mirror of
https://github.com/EQEmu/Server.git
synced 2026-06-25 06:18:21 +00:00
Compare commits
112 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7d194083aa | |||
| dd41fc5fcd | |||
| 6bf36f3e77 | |||
| dfb06db17b | |||
| 3e958c575b | |||
| e5db19965f | |||
| ce73f6bfe1 | |||
| 700f4645e2 | |||
| 5a7d544c5b | |||
| 0f7f71334a | |||
| c731f3f560 | |||
| b30fbc70a3 | |||
| 195cb80d56 | |||
| b2d5007466 | |||
| 47e2eb0acf | |||
| c36b3f030b | |||
| 2b821e50ff | |||
| 0aa07e9529 | |||
| 7ddafd9ed8 | |||
| 5488e9bf22 | |||
| 6db6d7dca9 | |||
| 066b762e73 | |||
| cd85a8524a | |||
| 4490a53ba0 | |||
| 00eb462d47 | |||
| 2df7d19f97 | |||
| 48c6db3a9c | |||
| cce368d94c | |||
| 84b8bdd2b4 | |||
| fc8ace91cb | |||
| 2d6c9f881a | |||
| 9b72c07a54 | |||
| 9d5d13fbd0 | |||
| bc3e9e8fba | |||
| d9cfc3a858 | |||
| 51dc62dfb1 | |||
| e52e4d5b3f | |||
| 0c3149a6e5 | |||
| 611122833d | |||
| b83373491e | |||
| dfa349492c | |||
| c08200188f | |||
| 41d9a15c74 | |||
| 2ed4effbe3 | |||
| 6ec09f300a | |||
| 079f612730 | |||
| 2c971fb2de | |||
| 20e9a8b2d2 | |||
| 8fa6a0b496 | |||
| d6e1c3f187 | |||
| 70a4b6a2b1 | |||
| 7923d7bc6c | |||
| 6007ba454c | |||
| d4a78f4799 | |||
| 0ada53aa96 | |||
| 7803170d6b | |||
| 20778ad7d9 | |||
| 44d63c47d9 | |||
| b288202c96 | |||
| a724e92638 | |||
| 0ea825e9a4 | |||
| 2ca50b339d | |||
| 164fe31fa8 | |||
| f3de3e8c31 | |||
| 1227f35382 | |||
| c0769a9c29 | |||
| 2dd0e51936 | |||
| fd787af53a | |||
| aa39ac8023 | |||
| 397096996c | |||
| f8de9b9167 | |||
| 9d48cbcd29 | |||
| eb5eb0ca30 | |||
| bc4bebb4a9 | |||
| 05f09b56e6 | |||
| 411fe3d95d | |||
| c1e984dfc1 | |||
| a5d9a8596a | |||
| 7e23d798d5 | |||
| 47ab8910a3 | |||
| 259add68f5 | |||
| d2f5dc43a6 | |||
| 99d2e3a8b1 | |||
| 122fe398b4 | |||
| 43c4b13978 | |||
| a3a707adae | |||
| c4da9766a4 | |||
| a8eb2832ce | |||
| 076aab50e8 | |||
| 1e8889a9fc | |||
| 7c3481daf9 | |||
| b93dec357f | |||
| 2f4af4f0c2 | |||
| a0f2a8a743 | |||
| 4c7016bd7b | |||
| 6c18cd0bee | |||
| 87e63e1e36 | |||
| a771882cff | |||
| b3f6a8c55f | |||
| 605502cd9d | |||
| 4712ca471b | |||
| 836c3d6596 | |||
| 53169ae217 | |||
| fd31915fae | |||
| 52763b6dd2 | |||
| 51cd43b4ea | |||
| 2db84f5a4f | |||
| 79cc2d5351 | |||
| d31cb09214 | |||
| 8bedcd8751 | |||
| 473c5096f6 | |||
| 0b181d5048 |
+208
@@ -1,3 +1,211 @@
|
|||||||
|
## [22.41.0] - 1/8/2024
|
||||||
|
|
||||||
|
### Bug
|
||||||
|
|
||||||
|
* DI Buff Fade ([#3919](https://github.com/EQEmu/Server/pull/3919)) @fryguy503 2024-01-08
|
||||||
|
* NPCs will now only proc on hit ([#3913](https://github.com/EQEmu/Server/pull/3913)) @fryguy503 2024-01-08
|
||||||
|
* Pets should not ignore Z axis ([#3912](https://github.com/EQEmu/Server/pull/3912)) @fryguy503 2024-01-08
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Disciplines should show when someone casts them. ([#3901](https://github.com/EQEmu/Server/pull/3901)) @fryguy503 2024-01-08
|
||||||
|
* Fix Typo in Character Skills loading ([#3937](https://github.com/EQEmu/Server/pull/3937)) @Kinglykrab 2024-01-09
|
||||||
|
* Fix for HasLockoutByCharacterID ([#3927](https://github.com/EQEmu/Server/pull/3927)) @fryguy503 2024-01-08
|
||||||
|
* Harm Touch, Improved Harm Touch, and Unholy Touch ([#3904](https://github.com/EQEmu/Server/pull/3904)) @fryguy503 2024-01-08
|
||||||
|
* Legacy Manaburn should have hard cap. ([#3905](https://github.com/EQEmu/Server/pull/3905)) @fryguy503 2024-01-08
|
||||||
|
* TGB - Added logic to stop bard errors on group songs. ([#3906](https://github.com/EQEmu/Server/pull/3906)) @fryguy503 2024-01-08
|
||||||
|
* World Shutdown Filter ([#3930](https://github.com/EQEmu/Server/pull/3930)) @fryguy503 2024-01-08
|
||||||
|
|
||||||
|
### Info
|
||||||
|
|
||||||
|
* Adding textual feedback when trying to sell alt items back to … ([#3917](https://github.com/EQEmu/Server/pull/3917)) @fryguy503 2024-01-08
|
||||||
|
|
||||||
|
### Rules
|
||||||
|
|
||||||
|
* Backstab Damage Modifier ([#3908](https://github.com/EQEmu/Server/pull/3908)) @fryguy503 2024-01-08
|
||||||
|
* Classic Tradeskill Skill Clamp ([#3914](https://github.com/EQEmu/Server/pull/3914)) @fryguy503 2024-01-08
|
||||||
|
* Classic Triple Attack ([#3903](https://github.com/EQEmu/Server/pull/3903)) @fryguy503 2024-01-08
|
||||||
|
* Ensure mana taps only effect NPC's that have mana. ([#3907](https://github.com/EQEmu/Server/pull/3907)) @fryguy503 2024-01-08
|
||||||
|
* Over Taunt Hate ([#3900](https://github.com/EQEmu/Server/pull/3900)) @fryguy503 2024-01-08
|
||||||
|
* Stun Chance Percent Rule ([#3922](https://github.com/EQEmu/Server/pull/3922)) @fryguy503 2024-01-08
|
||||||
|
|
||||||
|
## [22.40.0] - 1/7/2024
|
||||||
|
|
||||||
|
### Account
|
||||||
|
|
||||||
|
* Convert Get/Update Account Karma to Repositories ([#3858](https://github.com/EQEmu/Server/pull/3858)) @Kinglykrab 2024-01-07
|
||||||
|
* Convert UpdateGMStatus to Repositories ([#3859](https://github.com/EQEmu/Server/pull/3859)) @Kinglykrab 2024-01-07
|
||||||
|
|
||||||
|
### Bots
|
||||||
|
|
||||||
|
* Resist Spell Fix ([#3840](https://github.com/EQEmu/Server/pull/3840)) @dariusuknuis 2024-01-07
|
||||||
|
|
||||||
|
### Bugfix
|
||||||
|
|
||||||
|
* Negative Aggro Fix ([#3866](https://github.com/EQEmu/Server/pull/3866)) @fryguy503 2024-01-07
|
||||||
|
|
||||||
|
### Character
|
||||||
|
|
||||||
|
* Convert Clear/Delete/Get/Update of Character Item Recast to Repositories ([#3857](https://github.com/EQEmu/Server/pull/3857)) @Kinglykrab 2024-01-07
|
||||||
|
* Convert Delete/Load/Remove/Save of Character AA to Repositories ([#3849](https://github.com/EQEmu/Server/pull/3849)) @Kinglykrab 2024-01-07
|
||||||
|
* Convert Delete/Load/Save of Character Bandolier to Repositories ([#3845](https://github.com/EQEmu/Server/pull/3845)) @Kinglykrab 2024-01-07
|
||||||
|
* Convert Delete/Load/Save of Character Disciplines to Repositories ([#3850](https://github.com/EQEmu/Server/pull/3850)) @Kinglykrab 2024-01-07
|
||||||
|
* Convert Delete/Load/Save of Character Leadership Abilities to Repositories ([#3847](https://github.com/EQEmu/Server/pull/3847)) @Kinglykrab 2024-01-07
|
||||||
|
* Convert Delete/Load/Save of Character Material to Repositories ([#3846](https://github.com/EQEmu/Server/pull/3846)) @Kinglykrab 2024-01-07
|
||||||
|
* Convert Delete/Load/Save of Character Spells to Repositories ([#3842](https://github.com/EQEmu/Server/pull/3842)) @Kinglykrab 2024-01-07
|
||||||
|
* Convert Delete/Save of Character Memmed Spells to Repositories ([#3841](https://github.com/EQEmu/Server/pull/3841)) @Kinglykrab 2024-01-07
|
||||||
|
* Convert Load/Save of Character Bind to Repositories ([#3851](https://github.com/EQEmu/Server/pull/3851)) @Kinglykrab 2024-01-07
|
||||||
|
* Convert Load/Save of Character Buffs to Repositories ([#3855](https://github.com/EQEmu/Server/pull/3855)) @Kinglykrab 2024-01-07
|
||||||
|
* Convert Load/Save of Character Currency to Repositories ([#3848](https://github.com/EQEmu/Server/pull/3848)) @Kinglykrab 2024-01-07
|
||||||
|
* Convert Load/Save of Character Data to Repositories ([#3839](https://github.com/EQEmu/Server/pull/3839)) @Kinglykrab 2024-01-07
|
||||||
|
* Convert Load/Save of Character Potion Belt to Repositories ([#3844](https://github.com/EQEmu/Server/pull/3844)) @Kinglykrab 2024-01-07
|
||||||
|
* Convert Load/Save of Character Skills to Repositories ([#3843](https://github.com/EQEmu/Server/pull/3843)) @Kinglykrab 2024-01-07
|
||||||
|
* Convert Load/Update of Character Alternate Currencies to Repositories ([#3856](https://github.com/EQEmu/Server/pull/3856)) @Kinglykrab 2024-01-07
|
||||||
|
* Convert NoRentExpired to Repositories ([#3860](https://github.com/EQEmu/Server/pull/3860)) @Kinglykrab 2024-01-07
|
||||||
|
|
||||||
|
### Characters
|
||||||
|
|
||||||
|
* Convert Load/Save of Character Auras to Repositories ([#3854](https://github.com/EQEmu/Server/pull/3854)) @Kinglykrab 2024-01-07
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* Remove bot-based saylink method ([#3852](https://github.com/EQEmu/Server/pull/3852)) @Kinglykrab 2024-01-07
|
||||||
|
|
||||||
|
### Commands
|
||||||
|
|
||||||
|
* Add #clearxtargets Command ([#3833](https://github.com/EQEmu/Server/pull/3833)) @Kinglykrab 2024-01-07
|
||||||
|
* Add scoped buckets and editing to #databuckets ([#3826](https://github.com/EQEmu/Server/pull/3826)) @Kinglykrab 2024-01-07
|
||||||
|
* Cleanup #appearance Command ([#3827](https://github.com/EQEmu/Server/pull/3827)) @Kinglykrab 2024-01-07
|
||||||
|
* Cleanup #fixmob Command ([#3828](https://github.com/EQEmu/Server/pull/3828)) @Kinglykrab 2024-01-07
|
||||||
|
* Cleanup #petname Command ([#3829](https://github.com/EQEmu/Server/pull/3829)) @Kinglykrab 2024-01-07
|
||||||
|
* Cleanup #shutdown Command ([#3830](https://github.com/EQEmu/Server/pull/3830)) @Kinglykrab 2024-01-07
|
||||||
|
* Remove #zopp Command ([#3831](https://github.com/EQEmu/Server/pull/3831)) @Kinglykrab 2024-01-07
|
||||||
|
|
||||||
|
### Crash
|
||||||
|
|
||||||
|
* Fix crash where Raid invite could be accepted after forming group with the Raid invitor. ([#3837](https://github.com/EQEmu/Server/pull/3837)) @Aeadoin 2024-01-06
|
||||||
|
|
||||||
|
### Feature
|
||||||
|
|
||||||
|
* Break Trader if moved ([#3862](https://github.com/EQEmu/Server/pull/3862)) @fryguy503 2024-01-07
|
||||||
|
* Formula Addition (40+ Harm Touch) ([#3870](https://github.com/EQEmu/Server/pull/3870)) @fryguy503 2024-01-07
|
||||||
|
* Legacy Fizzle Code ([#3868](https://github.com/EQEmu/Server/pull/3868)) @fryguy503 2024-01-07
|
||||||
|
* Legacy Manaburn Rule ([#3872](https://github.com/EQEmu/Server/pull/3872)) @fryguy503 2024-01-07
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Add locations where melee can be bound outside of a city. ([#3887](https://github.com/EQEmu/Server/pull/3887)) @fryguy503 2024-01-07
|
||||||
|
* Amplification should not benefit from instrument mods ([#3898](https://github.com/EQEmu/Server/pull/3898)) @fryguy503 2024-01-07
|
||||||
|
* Bard Caster Level Fixes ([#3883](https://github.com/EQEmu/Server/pull/3883)) @fryguy503 2024-01-07
|
||||||
|
* Buff Sync ([#3896](https://github.com/EQEmu/Server/pull/3896)) @fryguy503 2024-01-07
|
||||||
|
* Cancel Magic SE fix ([#3890](https://github.com/EQEmu/Server/pull/3890)) @fryguy503 2024-01-07
|
||||||
|
* Class Trainers dont steal your money! ([#3864](https://github.com/EQEmu/Server/pull/3864)) @fryguy503 2024-01-07
|
||||||
|
* Clear Ramp when Clearing hate ([#3892](https://github.com/EQEmu/Server/pull/3892)) @fryguy503 2024-01-07
|
||||||
|
* DI/Death Pact Fix ([#3867](https://github.com/EQEmu/Server/pull/3867)) @fryguy503 2024-01-07
|
||||||
|
* Depop Charm Pet and Detach Debuffs on Evacuate ([#3888](https://github.com/EQEmu/Server/pull/3888)) @fryguy503 2024-01-07
|
||||||
|
* Dire Charm Reset ([#3875](https://github.com/EQEmu/Server/pull/3875)) @fryguy503 2024-01-07
|
||||||
|
* Disciplines Getting Focuses Fix ([#3884](https://github.com/EQEmu/Server/pull/3884)) @fryguy503 2024-01-07
|
||||||
|
* Fix issue with 9th/10th inventory slot ([#3835](https://github.com/EQEmu/Server/pull/3835)) @Kinglykrab 2024-01-03
|
||||||
|
* Fix typo on ZoneDatabase::LoadPetInfo ([#3871](https://github.com/EQEmu/Server/pull/3871)) @Kinglykrab 2024-01-07
|
||||||
|
* Harm Touch Unholy Disc Type ([#3874](https://github.com/EQEmu/Server/pull/3874)) @fryguy503 2024-01-07
|
||||||
|
* Prevent QS Crashes ([#3877](https://github.com/EQEmu/Server/pull/3877)) @fryguy503 2024-01-07
|
||||||
|
* Rez Effects Stacking ([#3882](https://github.com/EQEmu/Server/pull/3882)) @fryguy503 2024-01-07
|
||||||
|
* Rez in zone clear aggro ([#3895](https://github.com/EQEmu/Server/pull/3895)) @fryguy503 2024-01-07
|
||||||
|
* Rune Invis Break ([#3893](https://github.com/EQEmu/Server/pull/3893)) @fryguy503 2024-01-07
|
||||||
|
* Snare and DOT Stacking ([#3897](https://github.com/EQEmu/Server/pull/3897)) @fryguy503 2024-01-07
|
||||||
|
* Swim Skillup and Underwater Fall Damage Fix ([#3885](https://github.com/EQEmu/Server/pull/3885)) @fryguy503 2024-01-07
|
||||||
|
* Swimming Rules Adjustment and Racial ([#3889](https://github.com/EQEmu/Server/pull/3889)) @fryguy503 2024-01-07
|
||||||
|
* Target Locked Pet Taunt ([#3894](https://github.com/EQEmu/Server/pull/3894)) @fryguy503 2024-01-07
|
||||||
|
* Vampiric Embrace Fixes ([#3873](https://github.com/EQEmu/Server/pull/3873)) @fryguy503 2024-01-07
|
||||||
|
|
||||||
|
### Languages
|
||||||
|
|
||||||
|
* Cleanup language constants, use repositories ([#3838](https://github.com/EQEmu/Server/pull/3838)) @Kinglykrab 2024-01-07
|
||||||
|
|
||||||
|
### Pets
|
||||||
|
|
||||||
|
* Convert Load/Save of Pet Info to Repositories ([#3853](https://github.com/EQEmu/Server/pull/3853)) @Kinglykrab 2024-01-07
|
||||||
|
|
||||||
|
### Rules
|
||||||
|
|
||||||
|
* Casting Charm on over level = Aggro ([#3886](https://github.com/EQEmu/Server/pull/3886)) @fryguy503 2024-01-07
|
||||||
|
* Classic Invite Requires Target ([#3878](https://github.com/EQEmu/Server/pull/3878)) @fryguy503 2024-01-07
|
||||||
|
* Evac Aggro Wipe ([#3880](https://github.com/EQEmu/Server/pull/3880)) @fryguy503 2024-01-07
|
||||||
|
* Mounts will wear off on zone ([#3865](https://github.com/EQEmu/Server/pull/3865)) @fryguy503 2024-01-07
|
||||||
|
* PC Push and NPCtoNPC Push ([#3879](https://github.com/EQEmu/Server/pull/3879)) @fryguy503 2024-01-07
|
||||||
|
* RequireMnemonicRetention for Spells 9-12 Rule ([#3876](https://github.com/EQEmu/Server/pull/3876)) @fryguy503 2024-01-07
|
||||||
|
* Resist Softcap rules ([#3863](https://github.com/EQEmu/Server/pull/3863)) @fryguy503 2024-01-07
|
||||||
|
* Restrict Finishing Blow to only Fleeing NPC's. ([#3869](https://github.com/EQEmu/Server/pull/3869)) @fryguy503 2024-01-07
|
||||||
|
* Undead Aggro ([#3881](https://github.com/EQEmu/Server/pull/3881)) @fryguy503 2024-01-07
|
||||||
|
|
||||||
|
### Tuning
|
||||||
|
|
||||||
|
* FD and Sneak break when cast on adjustments. ([#3861](https://github.com/EQEmu/Server/pull/3861)) @fryguy503 2024-01-07
|
||||||
|
|
||||||
|
### UCS
|
||||||
|
|
||||||
|
* Consolidate configuration block ([#3768](https://github.com/EQEmu/Server/pull/3768)) @Akkadius 2024-01-07
|
||||||
|
|
||||||
|
## [22.39.1] - 12/31/2023
|
||||||
|
|
||||||
|
### Code
|
||||||
|
|
||||||
|
* Appearance not appearence ([#3819](https://github.com/EQEmu/Server/pull/3819)) @Kinglykrab 2023-12-30
|
||||||
|
* Delete errmsg.h in common and zone ([#3821](https://github.com/EQEmu/Server/pull/3821)) @Kinglykrab 2023-12-30
|
||||||
|
* Gender constants cleanup ([#3817](https://github.com/EQEmu/Server/pull/3817)) @Kinglykrab 2023-12-30
|
||||||
|
* Remove MakeSpawnUpdateNoDelta from mob.cpp/mob.h ([#3816](https://github.com/EQEmu/Server/pull/3816)) @Kinglykrab 2023-12-31
|
||||||
|
* Remove SendStunAppearance from mob.cpp/mob.h ([#3818](https://github.com/EQEmu/Server/pull/3818)) @Kinglykrab 2023-12-31
|
||||||
|
* Remove unused PlotPosition methods from mob.cpp/mob.h ([#3820](https://github.com/EQEmu/Server/pull/3820)) @Kinglykrab 2023-12-31
|
||||||
|
|
||||||
|
### Database
|
||||||
|
|
||||||
|
* Database update improvements, content db and terminal checks ([#3814](https://github.com/EQEmu/Server/pull/3814)) @Akkadius 2023-12-31
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
|
||||||
|
* Client:SetBucket Overload Incorrectly Named ([#3825](https://github.com/EQEmu/Server/pull/3825)) @fryguy503 2023-12-30
|
||||||
|
* Fix crash in Client::Handle_OP_GMGoto ([#3832](https://github.com/EQEmu/Server/pull/3832)) @Kinglykrab 2023-12-31
|
||||||
|
|
||||||
|
### Quest API
|
||||||
|
|
||||||
|
* Add HasItemOnCorpse() to Perl/Lua ([#3824](https://github.com/EQEmu/Server/pull/3824)) @Kinglykrab 2023-12-31
|
||||||
|
* Fix issue with death events. ([#3823](https://github.com/EQEmu/Server/pull/3823)) @Kinglykrab 2023-12-31
|
||||||
|
|
||||||
|
### Repositories
|
||||||
|
|
||||||
|
* Protected extended repositories from being overwritten if exists ([#3815](https://github.com/EQEmu/Server/pull/3815)) @Akkadius 2023-12-31
|
||||||
|
|
||||||
|
## [22.39.0] - 12/27/2023
|
||||||
|
|
||||||
|
### Character
|
||||||
|
|
||||||
|
* Fix character copier due to schema change ([#3805](https://github.com/EQEmu/Server/pull/3805)) @Akkadius 2023-12-28
|
||||||
|
|
||||||
|
### Combat
|
||||||
|
|
||||||
|
* Disarm was not dropping item to ground due to bug ([#3811](https://github.com/EQEmu/Server/pull/3811)) @noudess 2023-12-27
|
||||||
|
|
||||||
|
### Logs
|
||||||
|
|
||||||
|
* Bulk insert new log settings ([#3810](https://github.com/EQEmu/Server/pull/3810)) @Akkadius 2023-12-28
|
||||||
|
* Reclassify unhelpful Info message ([#3809](https://github.com/EQEmu/Server/pull/3809)) @Akkadius 2023-12-28
|
||||||
|
|
||||||
|
### MySQL
|
||||||
|
|
||||||
|
* Fix MySQL Query error formatting ([#3808](https://github.com/EQEmu/Server/pull/3808)) @Akkadius 2023-12-28
|
||||||
|
|
||||||
|
### Objects
|
||||||
|
|
||||||
|
* Remove "No objects to load for zone" error message ([#3807](https://github.com/EQEmu/Server/pull/3807)) @Akkadius 2023-12-28
|
||||||
|
|
||||||
|
### Player Events
|
||||||
|
|
||||||
|
* Bulk replace settings on boot ([#3806](https://github.com/EQEmu/Server/pull/3806)) @Akkadius 2023-12-28
|
||||||
|
|
||||||
|
### Tasks
|
||||||
|
|
||||||
|
* Add enabled column ([#3804](https://github.com/EQEmu/Server/pull/3804)) @Akkadius 2023-12-28
|
||||||
|
|
||||||
## [22.38.0] - 12/26/2023
|
## [22.38.0] - 12/26/2023
|
||||||
|
|
||||||
### Bots
|
### Bots
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ SET(common_sources
|
|||||||
crc32.cpp
|
crc32.cpp
|
||||||
database/database_dump_service.cpp
|
database/database_dump_service.cpp
|
||||||
database.cpp
|
database.cpp
|
||||||
database_conversions.cpp
|
|
||||||
database_instances.cpp
|
database_instances.cpp
|
||||||
database/database_update_manifest.cpp
|
database/database_update_manifest.cpp
|
||||||
database/database_update_manifest_bots.cpp
|
database/database_update_manifest_bots.cpp
|
||||||
@@ -541,7 +540,6 @@ SET(common_headers
|
|||||||
events/player_event_logs.h
|
events/player_event_logs.h
|
||||||
events/player_event_discord_formatter.h
|
events/player_event_discord_formatter.h
|
||||||
events/player_events.h
|
events/player_events.h
|
||||||
errmsg.h
|
|
||||||
event_sub.h
|
event_sub.h
|
||||||
expedition_lockout_timer.h
|
expedition_lockout_timer.h
|
||||||
extprofile.h
|
extprofile.h
|
||||||
@@ -563,7 +561,6 @@ SET(common_headers
|
|||||||
item_fieldlist.h
|
item_fieldlist.h
|
||||||
item_instance.h
|
item_instance.h
|
||||||
json_config.h
|
json_config.h
|
||||||
languages.h
|
|
||||||
light_source.h
|
light_source.h
|
||||||
linked_list.h
|
linked_list.h
|
||||||
loottable.h
|
loottable.h
|
||||||
|
|||||||
+9
-1
@@ -2246,6 +2246,11 @@ bool Database::CopyCharacter(
|
|||||||
row = results.begin();
|
row = results.begin();
|
||||||
std::string new_character_id = row[0];
|
std::string new_character_id = row[0];
|
||||||
|
|
||||||
|
std::vector<std::string> tables_to_zero_id = {
|
||||||
|
"keyring",
|
||||||
|
"data_buckets",
|
||||||
|
};
|
||||||
|
|
||||||
TransactionBegin();
|
TransactionBegin();
|
||||||
for (const auto &iter : DatabaseSchema::GetCharacterTables()) {
|
for (const auto &iter : DatabaseSchema::GetCharacterTables()) {
|
||||||
std::string table_name = iter.first;
|
std::string table_name = iter.first;
|
||||||
@@ -2279,6 +2284,10 @@ bool Database::CopyCharacter(
|
|||||||
std::string column = columns[column_index];
|
std::string column = columns[column_index];
|
||||||
std::string value = row[column_index] ? row[column_index] : "null";
|
std::string value = row[column_index] ? row[column_index] : "null";
|
||||||
|
|
||||||
|
if (column == "id" && Strings::Contains(tables_to_zero_id, table_name)) {
|
||||||
|
value = "0";
|
||||||
|
}
|
||||||
|
|
||||||
if (column == character_id_column_name) {
|
if (column == character_id_column_name) {
|
||||||
value = new_character_id;
|
value = new_character_id;
|
||||||
}
|
}
|
||||||
@@ -2326,7 +2335,6 @@ bool Database::CopyCharacter(
|
|||||||
if (!insert.ErrorMessage().empty()) {
|
if (!insert.ErrorMessage().empty()) {
|
||||||
TransactionRollback();
|
TransactionRollback();
|
||||||
return false;
|
return false;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -226,11 +226,6 @@ public:
|
|||||||
|
|
||||||
void PurgeAllDeletedDataBuckets();
|
void PurgeAllDeletedDataBuckets();
|
||||||
|
|
||||||
/* Database Conversions 'database_conversions.cpp' */
|
|
||||||
|
|
||||||
bool CheckDatabaseConversions();
|
|
||||||
bool CheckDatabaseConvertCorpseDeblob();
|
|
||||||
bool CheckDatabaseConvertPPDeblob();
|
|
||||||
|
|
||||||
/* Database Variables */
|
/* Database Variables */
|
||||||
|
|
||||||
|
|||||||
@@ -76,9 +76,9 @@ void DatabaseUpdate::CheckDbUpdates()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DatabaseUpdate::GetQueryResult(std::string query)
|
std::string DatabaseUpdate::GetQueryResult(const ManifestEntry& e)
|
||||||
{
|
{
|
||||||
auto results = m_database->QueryDatabase(query);
|
auto results = (e.content_schema_update ? m_content_database : m_database)->QueryDatabase(e.check);
|
||||||
|
|
||||||
std::vector<std::string> result_lines = {};
|
std::vector<std::string> result_lines = {};
|
||||||
|
|
||||||
@@ -121,6 +121,16 @@ bool DatabaseUpdate::ShouldRunMigration(ManifestEntry &e, std::string query_resu
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check if we are running in a terminal
|
||||||
|
bool is_atty()
|
||||||
|
{
|
||||||
|
#ifdef _WINDOWS
|
||||||
|
return ::_isatty(_fileno(stdin));
|
||||||
|
#else
|
||||||
|
return isatty(fileno(stdin));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// return true if we ran updates
|
// return true if we ran updates
|
||||||
bool DatabaseUpdate::UpdateManifest(
|
bool DatabaseUpdate::UpdateManifest(
|
||||||
std::vector<ManifestEntry> entries,
|
std::vector<ManifestEntry> entries,
|
||||||
@@ -136,7 +146,7 @@ bool DatabaseUpdate::UpdateManifest(
|
|||||||
for (auto &e: entries) {
|
for (auto &e: entries) {
|
||||||
if (e.version == version) {
|
if (e.version == version) {
|
||||||
bool has_migration = true;
|
bool has_migration = true;
|
||||||
std::string r = GetQueryResult(e.check);
|
std::string r = GetQueryResult(e);
|
||||||
if (ShouldRunMigration(e, r)) {
|
if (ShouldRunMigration(e, r)) {
|
||||||
has_migration = false;
|
has_migration = false;
|
||||||
missing_migrations.emplace_back(e.version);
|
missing_migrations.emplace_back(e.version);
|
||||||
@@ -179,7 +189,7 @@ bool DatabaseUpdate::UpdateManifest(
|
|||||||
if (e.version == m) {
|
if (e.version == m) {
|
||||||
bool errored_migration = false;
|
bool errored_migration = false;
|
||||||
|
|
||||||
auto r = m_database->QueryDatabaseMulti(e.sql);
|
auto r = (e.content_schema_update ? m_content_database : m_database)->QueryDatabaseMulti(e.sql);
|
||||||
|
|
||||||
// ignore empty query result "errors"
|
// ignore empty query result "errors"
|
||||||
if (r.ErrorNumber() != 1065 && !r.ErrorMessage().empty()) {
|
if (r.ErrorNumber() != 1065 && !r.ErrorMessage().empty()) {
|
||||||
@@ -187,6 +197,9 @@ bool DatabaseUpdate::UpdateManifest(
|
|||||||
errored_migration = true;
|
errored_migration = true;
|
||||||
|
|
||||||
LogInfo("Required database update failed. This could be a problem");
|
LogInfo("Required database update failed. This could be a problem");
|
||||||
|
|
||||||
|
// if terminal attached then prompt for skip
|
||||||
|
if (is_atty()) {
|
||||||
LogInfo("Would you like to skip this update? [y/n] (Timeout 60s)");
|
LogInfo("Would you like to skip this update? [y/n] (Timeout 60s)");
|
||||||
|
|
||||||
// user input
|
// user input
|
||||||
@@ -214,6 +227,10 @@ bool DatabaseUpdate::UpdateManifest(
|
|||||||
errored_migration = false;
|
errored_migration = false;
|
||||||
LogInfo("Skipping update [{}] [{}]", e.version, e.description);
|
LogInfo("Skipping update [{}] [{}]", e.version, e.description);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
errored_migration = true;
|
||||||
|
LogInfo("Skipping update [{}] [{}]", e.version, e.description);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogInfo(
|
LogInfo(
|
||||||
@@ -247,6 +264,13 @@ DatabaseUpdate *DatabaseUpdate::SetDatabase(Database *db)
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DatabaseUpdate *DatabaseUpdate::SetContentDatabase(Database *db)
|
||||||
|
{
|
||||||
|
m_content_database = db;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
bool DatabaseUpdate::CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b)
|
bool DatabaseUpdate::CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b)
|
||||||
{
|
{
|
||||||
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
LogInfo("{}", Strings::Repeat("-", BREAK_LENGTH));
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ struct ManifestEntry {
|
|||||||
std::string condition{}; // condition or "match_type" - Possible values [contains|match|missing|empty|not_empty]
|
std::string condition{}; // condition or "match_type" - Possible values [contains|match|missing|empty|not_empty]
|
||||||
std::string match{}; // match field that is not always used, but works in conjunction with "condition" values [missing|match|contains]
|
std::string match{}; // match field that is not always used, but works in conjunction with "condition" values [missing|match|contains]
|
||||||
std::string sql{}; // the SQL DDL that gets ran when the condition is true
|
std::string sql{}; // the SQL DDL that gets ran when the condition is true
|
||||||
|
bool content_schema_update{}; // if true, this migration is a content schema update and should be ran against the content database
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DatabaseVersion {
|
struct DatabaseVersion {
|
||||||
@@ -22,14 +23,16 @@ public:
|
|||||||
DatabaseVersion GetDatabaseVersions();
|
DatabaseVersion GetDatabaseVersions();
|
||||||
DatabaseVersion GetBinaryDatabaseVersions();
|
DatabaseVersion GetBinaryDatabaseVersions();
|
||||||
void CheckDbUpdates();
|
void CheckDbUpdates();
|
||||||
std::string GetQueryResult(std::string query);
|
std::string GetQueryResult(const ManifestEntry& e);
|
||||||
static bool ShouldRunMigration(ManifestEntry &e, std::string query_result);
|
static bool ShouldRunMigration(ManifestEntry &e, std::string query_result);
|
||||||
bool UpdateManifest(std::vector<ManifestEntry> entries, int version_low, int version_high);
|
bool UpdateManifest(std::vector<ManifestEntry> entries, int version_low, int version_high);
|
||||||
|
|
||||||
DatabaseUpdate *SetDatabase(Database *db);
|
DatabaseUpdate *SetDatabase(Database *db);
|
||||||
|
DatabaseUpdate *SetContentDatabase(Database *db);
|
||||||
bool HasPendingUpdates();
|
bool HasPendingUpdates();
|
||||||
private:
|
private:
|
||||||
Database *m_database;
|
Database *m_database;
|
||||||
|
Database *m_content_database;
|
||||||
static bool CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b);
|
static bool CheckVersionsUpToDate(DatabaseVersion v, DatabaseVersion b);
|
||||||
void InjectBotsVersionColumn();
|
void InjectBotsVersionColumn();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5016,7 +5016,7 @@ CREATE TABLE `spawn2_disabled` (
|
|||||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
|
||||||
INSERT INTO spawn2_disabled (spawn2_id, disabled) SELECT id, 1 FROM spawn2 WHERE enabled = 0;
|
INSERT INTO spawn2_disabled (spawn2_id, disabled) SELECT id, 1 FROM spawn2 WHERE enabled = 0;
|
||||||
ALTER TABLE `spawn2` DROP COLUMN `enabled`;
|
ALTER TABLE `spawn2` DROP COLUMN `enabled`;
|
||||||
)"
|
)",
|
||||||
},
|
},
|
||||||
ManifestEntry{
|
ManifestEntry{
|
||||||
.version = 9242,
|
.version = 9242,
|
||||||
@@ -5028,7 +5028,8 @@ ALTER TABLE `spawn2` DROP COLUMN `enabled`;
|
|||||||
ALTER TABLE `spawnentry`
|
ALTER TABLE `spawnentry`
|
||||||
ADD COLUMN `min_time` smallint(4) NOT NULL DEFAULT 0 AFTER `condition_value_filter`,
|
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`;
|
ADD COLUMN `max_time` smallint(4) NOT NULL DEFAULT 0 AFTER `min_time`;
|
||||||
)"
|
)",
|
||||||
|
.content_schema_update = true
|
||||||
},
|
},
|
||||||
ManifestEntry{
|
ManifestEntry{
|
||||||
.version = 9243,
|
.version = 9243,
|
||||||
@@ -5082,7 +5083,8 @@ INSERT INTO
|
|||||||
|
|
||||||
DROP TABLE `starting_items`;
|
DROP TABLE `starting_items`;
|
||||||
RENAME TABLE `starting_items_new` TO `starting_items`;
|
RENAME TABLE `starting_items_new` TO `starting_items`;
|
||||||
)"
|
)",
|
||||||
|
.content_schema_update = true
|
||||||
},
|
},
|
||||||
ManifestEntry{
|
ManifestEntry{
|
||||||
.version = 9244,
|
.version = 9244,
|
||||||
@@ -5092,7 +5094,8 @@ RENAME TABLE `starting_items_new` TO `starting_items`;
|
|||||||
.match = "0000-00-00 00:00:00",
|
.match = "0000-00-00 00:00:00",
|
||||||
.sql = R"(
|
.sql = R"(
|
||||||
ALTER TABLE `items` MODIFY COLUMN `updated` datetime NULL DEFAULT NULL;
|
ALTER TABLE `items` MODIFY COLUMN `updated` datetime NULL DEFAULT NULL;
|
||||||
)"
|
)",
|
||||||
|
.content_schema_update = true
|
||||||
},
|
},
|
||||||
ManifestEntry{
|
ManifestEntry{
|
||||||
.version = 9245,
|
.version = 9245,
|
||||||
@@ -5104,7 +5107,8 @@ ALTER TABLE `items` MODIFY COLUMN `updated` datetime NULL DEFAULT NULL;
|
|||||||
ALTER TABLE `object` CHANGE COLUMN `unknown08` `size_percentage` float NOT NULL DEFAULT 0 AFTER `icon`;
|
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 `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`;
|
ALTER TABLE `object` CHANGE COLUMN `unknown20` `incline` int(11) NOT NULL DEFAULT 0 AFTER `solid_type`;
|
||||||
)"
|
)",
|
||||||
|
.content_schema_update = true
|
||||||
},
|
},
|
||||||
ManifestEntry{
|
ManifestEntry{
|
||||||
.version = 9246,
|
.version = 9246,
|
||||||
@@ -5133,7 +5137,8 @@ CHANGE COLUMN `slot` `inventory_slot` mediumint(9) NOT NULL DEFAULT -1 AFTER `st
|
|||||||
|
|
||||||
ALTER TABLE `starting_items`
|
ALTER TABLE `starting_items`
|
||||||
CHANGE COLUMN `temporary` `class_list` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `id`;
|
CHANGE COLUMN `temporary` `class_list` text CHARACTER SET latin1 COLLATE latin1_swedish_ci NULL DEFAULT NULL AFTER `id`;
|
||||||
)"
|
)",
|
||||||
|
.content_schema_update = true
|
||||||
},
|
},
|
||||||
ManifestEntry{
|
ManifestEntry{
|
||||||
.version = 9248,
|
.version = 9248,
|
||||||
@@ -5143,7 +5148,20 @@ CHANGE COLUMN `temporary` `class_list` text CHARACTER SET latin1 COLLATE latin1_
|
|||||||
.match = "",
|
.match = "",
|
||||||
.sql = R"(
|
.sql = R"(
|
||||||
ALTER TABLE `npc_emotes` DROP INDEX `emoteid`;
|
ALTER TABLE `npc_emotes` DROP INDEX `emoteid`;
|
||||||
)"
|
)",
|
||||||
|
.content_schema_update = true
|
||||||
|
},
|
||||||
|
ManifestEntry{
|
||||||
|
.version = 9249,
|
||||||
|
.description = "2023_12_26_add_tasks_enabled_column.sql",
|
||||||
|
.check = "SHOW COLUMNS FROM `tasks` LIKE 'enabled'",
|
||||||
|
.condition = "empty",
|
||||||
|
.match = "",
|
||||||
|
.sql = R"(
|
||||||
|
ALTER TABLE `tasks`
|
||||||
|
ADD COLUMN `enabled` smallint NULL DEFAULT 1 AFTER `faction_amount`
|
||||||
|
)",
|
||||||
|
.content_schema_update = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- template; copy/paste this when you need to create a new entry
|
// -- template; copy/paste this when you need to create a new entry
|
||||||
|
|||||||
@@ -1,39 +0,0 @@
|
|||||||
#include "../common/global_define.h"
|
|
||||||
#include "../common/rulesys.h"
|
|
||||||
#include "../common/strings.h"
|
|
||||||
|
|
||||||
#include "database.h"
|
|
||||||
#include "database/database_update.h"
|
|
||||||
|
|
||||||
|
|
||||||
// Disgrace: for windows compile
|
|
||||||
#ifdef _WINDOWS
|
|
||||||
#include <windows.h>
|
|
||||||
#define snprintf _snprintf
|
|
||||||
#define strncasecmp _strnicmp
|
|
||||||
#define strcasecmp _stricmp
|
|
||||||
#else
|
|
||||||
|
|
||||||
#include "unix.h"
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#pragma pack(1)
|
|
||||||
|
|
||||||
DatabaseUpdate database_update;
|
|
||||||
|
|
||||||
bool Database::CheckDatabaseConversions()
|
|
||||||
{
|
|
||||||
auto *r = RuleManager::Instance();
|
|
||||||
r->LoadRules(this, "default", false);
|
|
||||||
if (!RuleB(Bots, Enabled) && DoesTableExist("bot_data")) {
|
|
||||||
LogInfo("Bot tables found but rule not enabled, enabling");
|
|
||||||
r->SetRule("Bots:Enabled", "true", this, true, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
database_update.SetDatabase(this)->CheckDbUpdates();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
@@ -71,7 +71,7 @@ namespace DatabaseSchema {
|
|||||||
{"character_tasks", "charid"},
|
{"character_tasks", "charid"},
|
||||||
{"character_tribute", "character_id"},
|
{"character_tribute", "character_id"},
|
||||||
{"completed_tasks", "charid"},
|
{"completed_tasks", "charid"},
|
||||||
{"data_buckets", "id"},
|
{"data_buckets", "character_id"},
|
||||||
{"faction_values", "char_id"},
|
{"faction_values", "char_id"},
|
||||||
{"friends", "charid"},
|
{"friends", "charid"},
|
||||||
{"guild_members", "char_id"},
|
{"guild_members", "char_id"},
|
||||||
|
|||||||
+1
-2
@@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
#include "dbcore.h"
|
#include "dbcore.h"
|
||||||
|
|
||||||
#include <errmsg.h>
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <mysqld_error.h>
|
#include <mysqld_error.h>
|
||||||
@@ -138,7 +137,7 @@ MySQLRequestResult DBcore::QueryDatabase(const char *query, uint32 querylen, boo
|
|||||||
* Error logging
|
* Error logging
|
||||||
*/
|
*/
|
||||||
if (mysql_errno(mysql) > 0 && query[0] != '\0') {
|
if (mysql_errno(mysql) > 0 && query[0] != '\0') {
|
||||||
LogMySQLError("[{}] [{}]\n[{}]", mysql_errno(mysql), mysql_error(mysql), query);
|
LogMySQLError("MySQL Error ({}) [{}] Query [{}]", mysql_errno(mysql), mysql_error(mysql), query);
|
||||||
}
|
}
|
||||||
|
|
||||||
return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(mysql), errorBuffer);
|
return MySQLRequestResult(nullptr, 0, 0, 0, 0, mysql_errno(mysql), errorBuffer);
|
||||||
|
|||||||
@@ -14,6 +14,9 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
|
#define CR_SERVER_GONE_ERROR 2006
|
||||||
|
#define CR_SERVER_LOST 2013
|
||||||
|
|
||||||
class DBcore {
|
class DBcore {
|
||||||
public:
|
public:
|
||||||
enum eStatus {
|
enum eStatus {
|
||||||
|
|||||||
+92
-34
@@ -22,7 +22,6 @@
|
|||||||
#include "data_verification.h"
|
#include "data_verification.h"
|
||||||
#include "eqemu_logsys.h"
|
#include "eqemu_logsys.h"
|
||||||
#include "eqemu_logsys_log_aliases.h"
|
#include "eqemu_logsys_log_aliases.h"
|
||||||
#include "languages.h"
|
|
||||||
#include "rulesys.h"
|
#include "rulesys.h"
|
||||||
|
|
||||||
int16 EQ::invtype::GetInvTypeSize(int16 inv_type) {
|
int16 EQ::invtype::GetInvTypeSize(int16 inv_type) {
|
||||||
@@ -159,45 +158,45 @@ int EQ::constants::ConvertStanceTypeToIndex(StanceType stance_type) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::map<int, std::string>& EQ::constants::GetLanguageMap()
|
const std::map<uint8, std::string>& EQ::constants::GetLanguageMap()
|
||||||
{
|
{
|
||||||
static const std::map<int, std::string> language_map = {
|
static const std::map<uint8, std::string> language_map = {
|
||||||
{ LANG_COMMON_TONGUE, "Common Tongue" },
|
{ Language::CommonTongue, "Common Tongue" },
|
||||||
{ LANG_BARBARIAN, "Barbarian" },
|
{ Language::Barbarian, "Barbarian" },
|
||||||
{ LANG_ERUDIAN, "Erudian" },
|
{ Language::Erudian, "Erudian" },
|
||||||
{ LANG_ELVISH, "Elvish" },
|
{ Language::Elvish, "Elvish" },
|
||||||
{ LANG_DARK_ELVISH, "Dark Elvish" },
|
{ Language::DarkElvish, "Dark Elvish" },
|
||||||
{ LANG_DWARVISH, "Dwarvish" },
|
{ Language::Dwarvish, "Dwarvish" },
|
||||||
{ LANG_TROLL, "Troll" },
|
{ Language::Troll, "Troll" },
|
||||||
{ LANG_OGRE, "Ogre" },
|
{ Language::Ogre, "Ogre" },
|
||||||
{ LANG_GNOMISH, "Gnomish" },
|
{ Language::Gnomish, "Gnomish" },
|
||||||
{ LANG_HALFLING, "Halfling" },
|
{ Language::Halfling, "Halfling" },
|
||||||
{ LANG_THIEVES_CANT, "Thieves Cant" },
|
{ Language::ThievesCant, "Thieves Cant" },
|
||||||
{ LANG_OLD_ERUDIAN, "Old Erudian" },
|
{ Language::OldErudian, "Old Erudian" },
|
||||||
{ LANG_ELDER_ELVISH, "Elder Elvish" },
|
{ Language::ElderElvish, "Elder Elvish" },
|
||||||
{ LANG_FROGLOK, "Froglok" },
|
{ Language::Froglok, "Froglok" },
|
||||||
{ LANG_GOBLIN, "Goblin" },
|
{ Language::Goblin, "Goblin" },
|
||||||
{ LANG_GNOLL, "Gnoll" },
|
{ Language::Gnoll, "Gnoll" },
|
||||||
{ LANG_COMBINE_TONGUE, "Combine Tongue" },
|
{ Language::CombineTongue, "Combine Tongue" },
|
||||||
{ LANG_ELDER_TEIRDAL, "Elder Teirdal" },
|
{ Language::ElderTeirDal, "Elder Teir'Dal" },
|
||||||
{ LANG_LIZARDMAN, "Lizardman" },
|
{ Language::Lizardman, "Lizardman" },
|
||||||
{ LANG_ORCISH, "Orcish" },
|
{ Language::Orcish, "Orcish" },
|
||||||
{ LANG_FAERIE, "Faerie" },
|
{ Language::Faerie, "Faerie" },
|
||||||
{ LANG_DRAGON, "Dragon" },
|
{ Language::Dragon, "Dragon" },
|
||||||
{ LANG_ELDER_DRAGON, "Elder Dragon" },
|
{ Language::ElderDragon, "Elder Dragon" },
|
||||||
{ LANG_DARK_SPEECH, "Dark Speech" },
|
{ Language::DarkSpeech, "Dark Speech" },
|
||||||
{ LANG_VAH_SHIR, "Vah Shir" },
|
{ Language::VahShir, "Vah Shir" },
|
||||||
{ LANG_ALARAN, "Alaran" },
|
{ Language::Alaran, "Alaran" },
|
||||||
{ LANG_HADAL, "Hadal" },
|
{ Language::Hadal, "Hadal" },
|
||||||
{ LANG_UNKNOWN, "Unknown" }
|
{ Language::Unknown27, "Unknown" }
|
||||||
};
|
};
|
||||||
|
|
||||||
return language_map;
|
return language_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string EQ::constants::GetLanguageName(int language_id)
|
std::string EQ::constants::GetLanguageName(uint8 language_id)
|
||||||
{
|
{
|
||||||
if (!EQ::ValueWithin(language_id, LANG_COMMON_TONGUE, LANG_UNKNOWN)) {
|
if (!EQ::ValueWithin(language_id, Language::CommonTongue, Language::Unknown27)) {
|
||||||
return std::string();
|
return std::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -509,7 +508,6 @@ std::string EQ::constants::GetObjectTypeName(int object_type)
|
|||||||
{
|
{
|
||||||
if (!EQ::ValueWithin(object_type, ObjectTypes::SmallBag, ObjectTypes::NoDeposit)) {
|
if (!EQ::ValueWithin(object_type, ObjectTypes::SmallBag, ObjectTypes::NoDeposit)) {
|
||||||
return std::string();
|
return std::string();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return EQ::constants::GetObjectTypeMap().find(object_type)->second;
|
return EQ::constants::GetObjectTypeMap().find(object_type)->second;
|
||||||
@@ -580,3 +578,63 @@ std::string EQ::constants::GetEmoteTypeName(uint8 emote_type)
|
|||||||
|
|
||||||
return EQ::constants::GetEmoteTypeMap().find(emote_type)->second;
|
return EQ::constants::GetEmoteTypeMap().find(emote_type)->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::map<uint32, std::string>& EQ::constants::GetAppearanceTypeMap()
|
||||||
|
{
|
||||||
|
static const std::map<uint32, std::string> appearance_type_map = {
|
||||||
|
{ AppearanceType::Die, "Die" },
|
||||||
|
{ AppearanceType::WhoLevel, "Who Level" },
|
||||||
|
{ AppearanceType::MaxHealth, "Max Health" },
|
||||||
|
{ AppearanceType::Invisibility, "Invisibility" },
|
||||||
|
{ AppearanceType::PVP, "PVP" },
|
||||||
|
{ AppearanceType::Light, "Light" },
|
||||||
|
{ AppearanceType::Animation, "Animation" },
|
||||||
|
{ AppearanceType::Sneak, "Sneak" },
|
||||||
|
{ AppearanceType::SpawnID, "Spawn ID" },
|
||||||
|
{ AppearanceType::Health, "Health" },
|
||||||
|
{ AppearanceType::Linkdead, "Linkdead" },
|
||||||
|
{ AppearanceType::FlyMode, "Fly Mode" },
|
||||||
|
{ AppearanceType::GM, "GM" },
|
||||||
|
{ AppearanceType::Anonymous, "Anonymous" },
|
||||||
|
{ AppearanceType::GuildID, "Guild ID" },
|
||||||
|
{ AppearanceType::GuildRank, "Guild Rank" },
|
||||||
|
{ AppearanceType::AFK, "AFK" },
|
||||||
|
{ AppearanceType::Pet, "Pet" },
|
||||||
|
{ AppearanceType::Summoned, "Summoned" },
|
||||||
|
{ AppearanceType::Split, "Split" },
|
||||||
|
{ AppearanceType::Size, "Size" },
|
||||||
|
{ AppearanceType::SetType, "Set Type" },
|
||||||
|
{ AppearanceType::NPCName, "NPCName" },
|
||||||
|
{ AppearanceType::AARank, "AARank" },
|
||||||
|
{ AppearanceType::CancelSneakHide, "Cancel Sneak Hide" },
|
||||||
|
{ AppearanceType::AreaHealthRegen, "Area Health Regeneration" },
|
||||||
|
{ AppearanceType::AreaManaRegen, "Area Mana Regeneration" },
|
||||||
|
{ AppearanceType::AreaEnduranceRegen, "Area Endurance Regeneration" },
|
||||||
|
{ AppearanceType::FreezeBeneficialBuffs, "Freeze Beneficial Buffs" },
|
||||||
|
{ AppearanceType::NPCTintIndex, "NPC Tint Index" },
|
||||||
|
{ AppearanceType::GroupAutoConsent, "Group Auto Consent" },
|
||||||
|
{ AppearanceType::RaidAutoConsent, "Raid Auto Consent" },
|
||||||
|
{ AppearanceType::GuildAutoConsent, "Guild Auto Consent" },
|
||||||
|
{ AppearanceType::ShowHelm, "Show Helm" },
|
||||||
|
{ AppearanceType::DamageState, "Damage State" },
|
||||||
|
{ AppearanceType::EQPlayers, "EQ Players" },
|
||||||
|
{ AppearanceType::FindBits, "Find Bits" },
|
||||||
|
{ AppearanceType::TextureType, "Texture Type" },
|
||||||
|
{ AppearanceType::FacePick, "Face Pick" },
|
||||||
|
{ AppearanceType::AntiCheat, "Anti Cheat" },
|
||||||
|
{ AppearanceType::GuildShow, "Guild Show" },
|
||||||
|
{ AppearanceType::OfflineMode, "Offline Mode" }
|
||||||
|
};
|
||||||
|
|
||||||
|
return appearance_type_map;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string EQ::constants::GetAppearanceTypeName(uint32 appearance_type)
|
||||||
|
{
|
||||||
|
const auto& a = EQ::constants::GetAppearanceTypeMap().find(appearance_type);
|
||||||
|
if (a != EQ::constants::GetAppearanceTypeMap().end()) {
|
||||||
|
return a->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|||||||
@@ -358,8 +358,8 @@ namespace EQ
|
|||||||
const char *GetStanceName(StanceType stance_type);
|
const char *GetStanceName(StanceType stance_type);
|
||||||
int ConvertStanceTypeToIndex(StanceType stance_type);
|
int ConvertStanceTypeToIndex(StanceType stance_type);
|
||||||
|
|
||||||
extern const std::map<int, std::string>& GetLanguageMap();
|
extern const std::map<uint8, std::string>& GetLanguageMap();
|
||||||
std::string GetLanguageName(int language_id);
|
std::string GetLanguageName(uint8 language_id);
|
||||||
|
|
||||||
extern const std::map<uint32, std::string>& GetLDoNThemeMap();
|
extern const std::map<uint32, std::string>& GetLDoNThemeMap();
|
||||||
std::string GetLDoNThemeName(uint32 theme_id);
|
std::string GetLDoNThemeName(uint32 theme_id);
|
||||||
@@ -397,6 +397,9 @@ namespace EQ
|
|||||||
extern const std::map<uint8, std::string>& GetEmoteTypeMap();
|
extern const std::map<uint8, std::string>& GetEmoteTypeMap();
|
||||||
std::string GetEmoteTypeName(uint8 emote_type);
|
std::string GetEmoteTypeName(uint8 emote_type);
|
||||||
|
|
||||||
|
extern const std::map<uint32, std::string>& GetAppearanceTypeMap();
|
||||||
|
std::string GetAppearanceTypeName(uint32 animation_type);
|
||||||
|
|
||||||
const int STANCE_TYPE_FIRST = stancePassive;
|
const int STANCE_TYPE_FIRST = stancePassive;
|
||||||
const int STANCE_TYPE_LAST = stanceBurnAE;
|
const int STANCE_TYPE_LAST = stanceBurnAE;
|
||||||
const int STANCE_TYPE_COUNT = stanceBurnAE;
|
const int STANCE_TYPE_COUNT = stanceBurnAE;
|
||||||
|
|||||||
+99
-54
@@ -23,61 +23,59 @@
|
|||||||
#include "skills.h"
|
#include "skills.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
|
namespace AppearanceType {
|
||||||
|
constexpr uint32 Die = 0; // Causes the client to keel over and zone to bind point (default action)
|
||||||
|
constexpr uint32 WhoLevel = 1; // Level that shows up on /who
|
||||||
|
constexpr uint32 MaxHealth = 2;
|
||||||
|
constexpr uint32 Invisibility = 3; // 0 = Visible, 1 = Invisible
|
||||||
|
constexpr uint32 PVP = 4; // 0 = Non-PVP, 1 = PVP
|
||||||
|
constexpr uint32 Light = 5; // Light type emitted by player (lightstone, shiny shield)
|
||||||
|
constexpr uint32 Animation = 14; // 100 = Standing, 102 = Freeze, 105 = Looting, 110 = Sitting, 111 = Crouching, 115 = Lying
|
||||||
|
constexpr uint32 Sneak = 15; // 0 = Normal, 1 = Sneaking
|
||||||
|
constexpr uint32 SpawnID = 16; // Server -> Client, sets player spawn ID
|
||||||
|
constexpr uint32 Health = 17; // Client->Server, my HP has changed (like regen tic)
|
||||||
|
constexpr uint32 Linkdead = 18; // 0 = Normal, 1 = Linkdead
|
||||||
|
constexpr uint32 FlyMode = 19; // 0 = Off, 1 = Flying, 2 = Levitating, 3 = Water, 4 = Floating, 5 = Levitating while Running
|
||||||
|
constexpr uint32 GM = 20; // 0 = Non-GM, 1 = GM
|
||||||
|
constexpr uint32 Anonymous = 21; // 0 = Non-Anonymous, 1 = Anonymous, 2 = Roleplaying
|
||||||
|
constexpr uint32 GuildID = 22;
|
||||||
|
constexpr uint32 GuildRank = 23;
|
||||||
|
constexpr uint32 AFK = 24; // 0 = Non-AFK, 1 = AFK
|
||||||
|
constexpr uint32 Pet = 25; // Parameter is Entity ID of owner, or 0 for when charm breaks
|
||||||
|
constexpr uint32 Summoned = 27;
|
||||||
|
constexpr uint32 Split = 28; // 0 = No Split, 1 = Auto Split
|
||||||
|
constexpr uint32 Size = 29; // Spawn's Size
|
||||||
|
constexpr uint32 SetType = 30; // 0 = PC, 1 = NPC, 2 = Corpse
|
||||||
|
constexpr uint32 NPCName = 31; // Change PC name color to NPC name color
|
||||||
|
constexpr uint32 AARank = 32; // AA Rank Title ID, title in /who?
|
||||||
|
constexpr uint32 CancelSneakHide = 33; // Turns off Hide and Sneak
|
||||||
|
constexpr uint32 AreaHealthRegen = 35; // Guild Hall Regeneration Pool sets to value * 0.001
|
||||||
|
constexpr uint32 AreaManaRegen = 36; // Guild Hall Regeneration Pool sets to value * 0.001
|
||||||
|
constexpr uint32 AreaEnduranceRegen = 37; // Guild Hall Regeneration Pool sets to value * 0.001
|
||||||
|
constexpr uint32 FreezeBeneficialBuffs = 38; // Freezes beneficial buff timers for PCs
|
||||||
|
constexpr uint32 NPCTintIndex = 39;
|
||||||
|
constexpr uint32 GroupAutoConsent = 40; // Auto Consent Group
|
||||||
|
constexpr uint32 RaidAutoConsent = 41; // Auto Consent Raid
|
||||||
|
constexpr uint32 GuildAutoConsent = 42; // Auto Consent Guild
|
||||||
|
constexpr uint32 ShowHelm = 43; // 0 = Hide, 1 = Show
|
||||||
|
constexpr uint32 DamageState = 44; // The damage state of a destructible object (0 through 10) plays sound IDs, most only have 2 or 4 states though
|
||||||
|
constexpr uint32 EQPlayers = 45; // EQ Players Update
|
||||||
|
constexpr uint32 FindBits = 46; // Set Find Bits?
|
||||||
|
constexpr uint32 TextureType = 48; // Texture Type?
|
||||||
|
constexpr uint32 FacePick = 49; // Turns off face pick window?
|
||||||
|
constexpr uint32 AntiCheat = 51; // Sent by the client randomly telling the server how long since last action has occurred
|
||||||
|
constexpr uint32 GuildShow = 52;
|
||||||
|
constexpr uint32 OfflineMode = 53; // Offline Mode
|
||||||
|
}
|
||||||
|
|
||||||
//SpawnAppearance types: (compared two clients for server-originating types: SoF & RoF2)
|
namespace Animation {
|
||||||
#define AT_Die 0 // this causes the client to keel over and zone to bind point (default action)
|
constexpr uint32 Standing = 100;
|
||||||
#define AT_WhoLevel 1 // the level that shows up on /who
|
constexpr uint32 Freeze = 102;
|
||||||
#define AT_HPMax 2 // idk
|
constexpr uint32 Looting = 105;
|
||||||
#define AT_Invis 3 // 0 = visible, 1 = invisible
|
constexpr uint32 Sitting = 110;
|
||||||
#define AT_PVP 4 // 0 = blue, 1 = pvp (red)
|
constexpr uint32 Crouching = 111;
|
||||||
#define AT_Light 5 // light type emitted by player (lightstone, shiny shield)
|
constexpr uint32 Lying = 115;
|
||||||
#define AT_Anim 14 // 100=standing, 110=sitting, 111=ducking, 115=feigned, 105=looting
|
}
|
||||||
#define AT_Sneak 15 // 0 = normal, 1 = sneaking
|
|
||||||
#define AT_SpawnID 16 // server to client, sets player spawn id
|
|
||||||
#define AT_HP 17 // Client->Server, my HP has changed (like regen tic)
|
|
||||||
#define AT_Linkdead 18 // 0 = normal, 1 = linkdead
|
|
||||||
#define AT_Levitate 19 // 0=off, 1=flymode, 2=levitate max 5, see GravityBehavior enum
|
|
||||||
#define AT_GM 20 // 0 = normal, 1 = GM - all odd numbers seem to make it GM
|
|
||||||
#define AT_Anon 21 // 0 = normal, 1 = anon, 2 = roleplay
|
|
||||||
#define AT_GuildID 22
|
|
||||||
#define AT_GuildRank 23 // 0=member, 1=officer, 2=leader
|
|
||||||
#define AT_AFK 24 // 0 = normal, 1 = afk
|
|
||||||
#define AT_Pet 25 // Param is EntityID of owner, or 0 for when charm breaks
|
|
||||||
#define AT_Summoned 27 // Unsure
|
|
||||||
#define AT_Split 28 // 0 = normal, 1 = autosplit on (not showing in SoF+) (client-to-server only)
|
|
||||||
#define AT_Size 29 // spawn's size (present: SoF, absent: RoF2)
|
|
||||||
#define AT_SetType 30 // 0 = PC, 1 = NPC, 2 <= = corpse
|
|
||||||
#define AT_NPCName 31 // change PC's name's color to NPC color 0 = normal, 1 = npc name, Trader on RoF2?
|
|
||||||
#define AT_AARank 32 // AA Rank Title ID thingy, does is this the title in /who?
|
|
||||||
#define AT_CancelSneakHide 33 // Turns off Hide and Sneak
|
|
||||||
//#define AT_34 34 // unknown (present: SoF, absent: RoF2)
|
|
||||||
#define AT_AreaHPRegen 35 // guild hall regen pool sets to value * 0.001
|
|
||||||
#define AT_AreaManaRegen 36 // guild hall regen pool sets to value * 0.001
|
|
||||||
#define AT_AreaEndRegen 37 // guild hall regen pool sets to value * 0.001
|
|
||||||
#define AT_FreezeBuffs 38 // Freezes beneficial buff timers
|
|
||||||
#define AT_NpcTintIndex 39 // not 100% sure
|
|
||||||
#define AT_GroupConsent 40 // auto consent group
|
|
||||||
#define AT_RaidConsent 41 // auto consent raid
|
|
||||||
#define AT_GuildConsent 42 // auto consent guild
|
|
||||||
#define AT_ShowHelm 43 // 0 = hide graphic, 1 = show graphic
|
|
||||||
#define AT_DamageState 44 // The damage state of a destructible object (0 through 10) plays soundids most only have 2 or 4 states though
|
|
||||||
#define AT_EQPlayers 45 // /eqplayersupdate
|
|
||||||
#define AT_FindBits 46 // set FindBits, whatever those are!
|
|
||||||
#define AT_TextureType 48 // TextureType
|
|
||||||
#define AT_FacePick 49 // Turns off face pick window? maybe ...
|
|
||||||
#define AT_AntiCheat 51 // sent by the client randomly telling the server how long since last action has occured
|
|
||||||
#define AT_GuildShow 52 // this is what MQ2 call sit, not sure
|
|
||||||
#define AT_Offline 53 // Offline mode
|
|
||||||
|
|
||||||
//#define AT_Trader 300 // Bazaar Trader Mode (not present in SoF or RoF2)
|
|
||||||
|
|
||||||
// animations for AT_Anim
|
|
||||||
#define ANIM_FREEZE 102
|
|
||||||
#define ANIM_STAND 0x64
|
|
||||||
#define ANIM_SIT 0x6e
|
|
||||||
#define ANIM_CROUCH 0x6f
|
|
||||||
#define ANIM_DEATH 0x73
|
|
||||||
#define ANIM_LOOT 0x69
|
|
||||||
|
|
||||||
constexpr int16 RECAST_TYPE_UNLINKED_ITEM = -1;
|
constexpr int16 RECAST_TYPE_UNLINKED_ITEM = -1;
|
||||||
|
|
||||||
@@ -686,6 +684,53 @@ namespace Zones {
|
|||||||
constexpr uint16 APPRENTICE = 999; // Designer Apprentice
|
constexpr uint16 APPRENTICE = 999; // Designer Apprentice
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Language {
|
||||||
|
constexpr uint8 CommonTongue = 0;
|
||||||
|
constexpr uint8 Barbarian = 1;
|
||||||
|
constexpr uint8 Erudian = 2;
|
||||||
|
constexpr uint8 Elvish = 3;
|
||||||
|
constexpr uint8 DarkElvish = 4;
|
||||||
|
constexpr uint8 Dwarvish = 5;
|
||||||
|
constexpr uint8 Troll = 6;
|
||||||
|
constexpr uint8 Ogre = 7;
|
||||||
|
constexpr uint8 Gnomish = 8;
|
||||||
|
constexpr uint8 Halfling = 9;
|
||||||
|
constexpr uint8 ThievesCant = 10;
|
||||||
|
constexpr uint8 OldErudian = 11;
|
||||||
|
constexpr uint8 ElderElvish = 12;
|
||||||
|
constexpr uint8 Froglok = 13;
|
||||||
|
constexpr uint8 Goblin = 14;
|
||||||
|
constexpr uint8 Gnoll = 15;
|
||||||
|
constexpr uint8 CombineTongue = 16;
|
||||||
|
constexpr uint8 ElderTeirDal = 17;
|
||||||
|
constexpr uint8 Lizardman = 18;
|
||||||
|
constexpr uint8 Orcish = 19;
|
||||||
|
constexpr uint8 Faerie = 20;
|
||||||
|
constexpr uint8 Dragon = 21;
|
||||||
|
constexpr uint8 ElderDragon = 22;
|
||||||
|
constexpr uint8 DarkSpeech = 23;
|
||||||
|
constexpr uint8 VahShir = 24;
|
||||||
|
constexpr uint8 Alaran = 25;
|
||||||
|
constexpr uint8 Hadal = 26;
|
||||||
|
constexpr uint8 Unknown27 = 27;
|
||||||
|
|
||||||
|
constexpr uint8 MaxValue = 100;
|
||||||
|
}
|
||||||
|
namespace PetInfoType {
|
||||||
|
constexpr int Current = 0;
|
||||||
|
constexpr int Suspended = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace BuffEffectType {
|
||||||
|
constexpr uint8 None = 0;
|
||||||
|
constexpr uint8 Buff = 2;
|
||||||
|
constexpr uint8 InverseBuff = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace AlternateCurrencyMode {
|
||||||
|
constexpr uint32 Update = 7;
|
||||||
|
constexpr uint32 Populate = 8;
|
||||||
|
}
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FilterNone = 0,
|
FilterNone = 0,
|
||||||
|
|||||||
@@ -5134,8 +5134,6 @@ struct GroupMakeLeader_Struct
|
|||||||
//ex for a blank crowns window you would send:
|
//ex for a blank crowns window you would send:
|
||||||
//999999|1|999999|0
|
//999999|1|999999|0
|
||||||
//any items come after in much the same way adventure merchant items do except there is no theme included
|
//any items come after in much the same way adventure merchant items do except there is no theme included
|
||||||
#define ALT_CURRENCY_OP_POPULATE 8
|
|
||||||
#define ALT_CURRENCY_OP_UPDATE 7
|
|
||||||
|
|
||||||
//Server -> Client
|
//Server -> Client
|
||||||
//Populates the initial Alternate Currency Window
|
//Populates the initial Alternate Currency Window
|
||||||
|
|||||||
+110
-15
@@ -20,9 +20,12 @@
|
|||||||
#include "eqemu_config.h"
|
#include "eqemu_config.h"
|
||||||
#include "misc_functions.h"
|
#include "misc_functions.h"
|
||||||
#include "strings.h"
|
#include "strings.h"
|
||||||
|
#include "eqemu_logsys.h"
|
||||||
|
#include "json/json.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
std::string EQEmuConfig::ConfigFile = "eqemu_config.json";
|
std::string EQEmuConfig::ConfigFile = "eqemu_config.json";
|
||||||
EQEmuConfig *EQEmuConfig::_config = nullptr;
|
EQEmuConfig *EQEmuConfig::_config = nullptr;
|
||||||
@@ -111,13 +114,12 @@ void EQEmuConfig::parse_config()
|
|||||||
DisableConfigChecks = true;
|
DisableConfigChecks = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* UCS
|
|
||||||
*/
|
CheckUcsConfigConversion();
|
||||||
ChatHost = _root["server"]["chatserver"].get("host", "eqchat.eqemulator.net").asString();
|
|
||||||
ChatPort = Strings::ToUnsignedInt(_root["server"]["chatserver"].get("port", "7778").asString());
|
m_ucs_host = _root["server"]["ucs"].get("host", "eqchat.eqemulator.net").asString();
|
||||||
MailHost = _root["server"]["mailserver"].get("host", "eqmail.eqemulator.net").asString();
|
m_ucs_port = Strings::ToUnsignedInt(_root["server"]["ucs"].get("port", "7778").asString());
|
||||||
MailPort = Strings::ToUnsignedInt(_root["server"]["mailserver"].get("port", "7778").asString());
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Database
|
* Database
|
||||||
@@ -246,16 +248,16 @@ std::string EQEmuConfig::GetByName(const std::string &var_name) const
|
|||||||
return (WorldHTTPEnabled ? "true" : "false");
|
return (WorldHTTPEnabled ? "true" : "false");
|
||||||
}
|
}
|
||||||
if (var_name == "ChatHost") {
|
if (var_name == "ChatHost") {
|
||||||
return (ChatHost);
|
return (m_ucs_host);
|
||||||
}
|
}
|
||||||
if (var_name == "ChatPort") {
|
if (var_name == "ChatPort") {
|
||||||
return (itoa(ChatPort));
|
return (itoa(m_ucs_port));
|
||||||
}
|
}
|
||||||
if (var_name == "MailHost") {
|
if (var_name == "MailHost") {
|
||||||
return (MailHost);
|
return (m_ucs_host);
|
||||||
}
|
}
|
||||||
if (var_name == "MailPort") {
|
if (var_name == "MailPort") {
|
||||||
return (itoa(MailPort));
|
return (itoa(m_ucs_port));
|
||||||
}
|
}
|
||||||
if (var_name == "DatabaseHost") {
|
if (var_name == "DatabaseHost") {
|
||||||
return (DatabaseHost);
|
return (DatabaseHost);
|
||||||
@@ -362,10 +364,8 @@ void EQEmuConfig::Dump() const
|
|||||||
std::cout << "WorldHTTPPort = " << WorldHTTPPort << std::endl;
|
std::cout << "WorldHTTPPort = " << WorldHTTPPort << std::endl;
|
||||||
std::cout << "WorldHTTPMimeFile = " << WorldHTTPMimeFile << std::endl;
|
std::cout << "WorldHTTPMimeFile = " << WorldHTTPMimeFile << std::endl;
|
||||||
std::cout << "WorldHTTPEnabled = " << WorldHTTPEnabled << std::endl;
|
std::cout << "WorldHTTPEnabled = " << WorldHTTPEnabled << std::endl;
|
||||||
std::cout << "ChatHost = " << ChatHost << std::endl;
|
std::cout << "UCSHost = " << m_ucs_host << std::endl;
|
||||||
std::cout << "ChatPort = " << ChatPort << std::endl;
|
std::cout << "UCSPort = " << m_ucs_port << std::endl;
|
||||||
std::cout << "MailHost = " << MailHost << std::endl;
|
|
||||||
std::cout << "MailPort = " << MailPort << std::endl;
|
|
||||||
std::cout << "DatabaseHost = " << DatabaseHost << std::endl;
|
std::cout << "DatabaseHost = " << DatabaseHost << std::endl;
|
||||||
std::cout << "DatabaseUsername = " << DatabaseUsername << std::endl;
|
std::cout << "DatabaseUsername = " << DatabaseUsername << std::endl;
|
||||||
std::cout << "DatabasePassword = " << DatabasePassword << std::endl;
|
std::cout << "DatabasePassword = " << DatabasePassword << std::endl;
|
||||||
@@ -392,3 +392,98 @@ void EQEmuConfig::Dump() const
|
|||||||
std::cout << "DefaultStatus = " << (int) DefaultStatus << std::endl;
|
std::cout << "DefaultStatus = " << (int) DefaultStatus << std::endl;
|
||||||
// std::cout << "DynamicCount = " << DynamicCount << std::endl;
|
// std::cout << "DynamicCount = " << DynamicCount << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::string &EQEmuConfig::GetUCSHost() const
|
||||||
|
{
|
||||||
|
return m_ucs_host;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16 EQEmuConfig::GetUCSPort() const
|
||||||
|
{
|
||||||
|
return m_ucs_port;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EQEmuConfig::CheckUcsConfigConversion()
|
||||||
|
{
|
||||||
|
std::string chat_host = _root["server"]["chatserver"].get("host", "").asString();
|
||||||
|
uint32 chat_port = Strings::ToUnsignedInt(_root["server"]["chatserver"].get("port", "0").asString());
|
||||||
|
std::string mail_host = _root["server"]["mailserver"].get("host", "").asString();
|
||||||
|
uint32 mail_port = Strings::ToUnsignedInt(_root["server"]["mailserver"].get("port", "0").asString());
|
||||||
|
std::string ucs_host = _root["server"]["ucs"].get("host", "").asString();
|
||||||
|
|
||||||
|
// automatic ucs legacy configuration migration
|
||||||
|
// if old configuration values are set, let's backup the existing configuration
|
||||||
|
// and migrate to to use the new fields and write the new config
|
||||||
|
if ((!chat_host.empty() || !mail_host.empty()) && ucs_host.empty()) {
|
||||||
|
LogInfo("Migrating old [eqemu_config] UCS configuration to new configuration");
|
||||||
|
|
||||||
|
std::string config_file_path = std::filesystem::path{
|
||||||
|
path.GetServerPath() + "/eqemu_config.json"
|
||||||
|
}.string();
|
||||||
|
|
||||||
|
std::string config_file_bak_path = std::filesystem::path{
|
||||||
|
path.GetServerPath() + "/eqemu_config.ucs-migrate-json.bak"
|
||||||
|
}.string();
|
||||||
|
|
||||||
|
// copy eqemu_config.json to eqemu_config.json.bak
|
||||||
|
std::ifstream src(config_file_path, std::ios::binary);
|
||||||
|
std::ofstream dst(config_file_bak_path, std::ios::binary);
|
||||||
|
dst << src.rdbuf();
|
||||||
|
src.close();
|
||||||
|
|
||||||
|
LogInfo("Old configuration backed up to [{}]", config_file_bak_path);
|
||||||
|
|
||||||
|
// read eqemu_config.json, transplant new fields and write to eqemu_config.json
|
||||||
|
Json::Value root;
|
||||||
|
Json::Reader reader;
|
||||||
|
std::ifstream file(config_file_path);
|
||||||
|
if (!reader.parse(file, root)) {
|
||||||
|
LogError("Failed to parse configuration file");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
// get old fields
|
||||||
|
std::string host = !chat_host.empty() ? chat_host : mail_host;
|
||||||
|
if (host.empty()) {
|
||||||
|
host = "eqchat.eqemulator.net";
|
||||||
|
}
|
||||||
|
std::string port = chat_port > 0 ? std::to_string(chat_port) : std::to_string(mail_port);
|
||||||
|
if (port.empty()) {
|
||||||
|
port = "7778";
|
||||||
|
}
|
||||||
|
|
||||||
|
// set new fields
|
||||||
|
root["server"]["ucs"]["host"] = host;
|
||||||
|
root["server"]["ucs"]["port"] = port;
|
||||||
|
|
||||||
|
// unset old fields
|
||||||
|
root["server"].removeMember("chatserver");
|
||||||
|
root["server"].removeMember("mailserver");
|
||||||
|
|
||||||
|
// get Json::Value raw string
|
||||||
|
std::string config = root.toStyledString();
|
||||||
|
|
||||||
|
// format using more modern json library
|
||||||
|
nlohmann::json data = nlohmann::json::parse(config);
|
||||||
|
|
||||||
|
// write to file
|
||||||
|
std::ofstream o(config_file_path);
|
||||||
|
o << std::setw(1) << data << std::endl;
|
||||||
|
o.close();
|
||||||
|
|
||||||
|
// write new config
|
||||||
|
LogInfo("New configuration written to [{}]", config_file_path);
|
||||||
|
LogInfo("Migration complete, please review the new configuration file");
|
||||||
|
|
||||||
|
// reload config internally
|
||||||
|
try {
|
||||||
|
std::ifstream fconfig(config_file_path, std::ifstream::binary);
|
||||||
|
fconfig >> _config->_root;
|
||||||
|
_config->parse_config();
|
||||||
|
}
|
||||||
|
catch (std::exception &) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -62,14 +62,6 @@ class EQEmuConfig
|
|||||||
std::string SharedKey;
|
std::string SharedKey;
|
||||||
bool DisableConfigChecks;
|
bool DisableConfigChecks;
|
||||||
|
|
||||||
// From <chatserver/>
|
|
||||||
std::string ChatHost;
|
|
||||||
uint16 ChatPort;
|
|
||||||
|
|
||||||
// From <mailserver/>
|
|
||||||
std::string MailHost;
|
|
||||||
uint16 MailPort;
|
|
||||||
|
|
||||||
// From <database/>
|
// From <database/>
|
||||||
std::string DatabaseHost;
|
std::string DatabaseHost;
|
||||||
std::string DatabaseUsername;
|
std::string DatabaseUsername;
|
||||||
@@ -122,12 +114,18 @@ class EQEmuConfig
|
|||||||
|
|
||||||
bool auto_database_updates;
|
bool auto_database_updates;
|
||||||
|
|
||||||
|
const std::string &GetUCSHost() const;
|
||||||
|
uint16 GetUCSPort() const;
|
||||||
|
|
||||||
// uint16 DynamicCount;
|
// uint16 DynamicCount;
|
||||||
|
|
||||||
// map<string,uint16> StaticZones;
|
// map<string,uint16> StaticZones;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
std::string m_ucs_host;
|
||||||
|
uint16 m_ucs_port;
|
||||||
|
|
||||||
static EQEmuConfig *_config;
|
static EQEmuConfig *_config;
|
||||||
Json::Value _root;
|
Json::Value _root;
|
||||||
static std::string ConfigFile;
|
static std::string ConfigFile;
|
||||||
@@ -186,6 +184,7 @@ class EQEmuConfig
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Dump() const;
|
void Dump() const;
|
||||||
|
void CheckUcsConfigConversion();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+11
-7
@@ -651,6 +651,9 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Auto inject categories that don't exist in the database...
|
// Auto inject categories that don't exist in the database...
|
||||||
|
|
||||||
|
std::vector<LogsysCategoriesRepository::LogsysCategories> db_categories_to_add{};
|
||||||
|
|
||||||
for (int i = Logs::AA; i != Logs::MaxCategoryID; i++) {
|
for (int i = Logs::AA; i != Logs::MaxCategoryID; i++) {
|
||||||
|
|
||||||
bool is_missing_in_database = std::find(db_categories.begin(), db_categories.end(), i) == db_categories.end();
|
bool is_missing_in_database = std::find(db_categories.begin(), db_categories.end(), i) == db_categories.end();
|
||||||
@@ -665,11 +668,7 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_missing_in_database && !is_deprecated_category) {
|
if (is_missing_in_database && !is_deprecated_category) {
|
||||||
LogInfo(
|
LogInfo("Automatically adding new log category [{}] ({})", Logs::LogCategoryName[i], i);
|
||||||
"Automatically adding new log category [{}] ({})",
|
|
||||||
Logs::LogCategoryName[i],
|
|
||||||
i
|
|
||||||
);
|
|
||||||
|
|
||||||
auto new_category = LogsysCategoriesRepository::NewEntity();
|
auto new_category = LogsysCategoriesRepository::NewEntity();
|
||||||
new_category.log_category_id = i;
|
new_category.log_category_id = i;
|
||||||
@@ -678,11 +677,16 @@ EQEmuLogSys *EQEmuLogSys::LoadLogDatabaseSettings()
|
|||||||
new_category.log_to_gmsay = log_settings[i].log_to_gmsay;
|
new_category.log_to_gmsay = log_settings[i].log_to_gmsay;
|
||||||
new_category.log_to_file = log_settings[i].log_to_file;
|
new_category.log_to_file = log_settings[i].log_to_file;
|
||||||
new_category.log_to_discord = log_settings[i].log_to_discord;
|
new_category.log_to_discord = log_settings[i].log_to_discord;
|
||||||
|
db_categories_to_add.emplace_back(new_category);
|
||||||
LogsysCategoriesRepository::InsertOne(*m_database, new_category);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!db_categories_to_add.empty()) {
|
||||||
|
LogsysCategoriesRepository::ReplaceMany(*m_database, db_categories_to_add);
|
||||||
|
LoadLogDatabaseSettings();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
LogInfo("Loaded [{}] log categories", categories.size());
|
LogInfo("Loaded [{}] log categories", categories.size());
|
||||||
|
|
||||||
auto webhooks = DiscordWebhooksRepository::GetWhere(*m_database, fmt::format("id < {}", MAX_DISCORD_WEBHOOK_ID));
|
auto webhooks = DiscordWebhooksRepository::GetWhere(*m_database, fmt::format("id < {}", MAX_DISCORD_WEBHOOK_ID));
|
||||||
|
|||||||
@@ -1,59 +0,0 @@
|
|||||||
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
|
||||||
MA 02111-1307, USA */
|
|
||||||
|
|
||||||
/* Error messages for mysql clients */
|
|
||||||
/* error messages for the demon is in share/language/errmsg.sys */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
void init_client_errs(void);
|
|
||||||
extern const char *client_errors[]; /* Error messages */
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CR_MIN_ERROR 2000 /* For easier client code */
|
|
||||||
#define CR_MAX_ERROR 2999
|
|
||||||
#if defined(OS2) && defined( MYSQL_SERVER)
|
|
||||||
#define CER(X) client_errors[(X)-CR_MIN_ERROR]
|
|
||||||
#else
|
|
||||||
#define ER(X) client_errors[(X)-CR_MIN_ERROR]
|
|
||||||
#endif
|
|
||||||
#define CLIENT_ERRMAP 2 /* Errormap used by my_error() */
|
|
||||||
|
|
||||||
#define CR_UNKNOWN_ERROR 2000
|
|
||||||
#define CR_SOCKET_CREATE_ERROR 2001
|
|
||||||
#define CR_CONNECTION_ERROR 2002
|
|
||||||
#define CR_CONN_HOST_ERROR 2003
|
|
||||||
#define CR_IPSOCK_ERROR 2004
|
|
||||||
#define CR_UNKNOWN_HOST 2005
|
|
||||||
#define CR_SERVER_GONE_ERROR 2006
|
|
||||||
#define CR_VERSION_ERROR 2007
|
|
||||||
#define CR_OUT_OF_MEMORY 2008
|
|
||||||
#define CR_WRONG_HOST_INFO 2009
|
|
||||||
#define CR_LOCALHOST_CONNECTION 2010
|
|
||||||
#define CR_TCP_CONNECTION 2011
|
|
||||||
#define CR_SERVER_HANDSHAKE_ERR 2012
|
|
||||||
#define CR_SERVER_LOST 2013
|
|
||||||
#define CR_COMMANDS_OUT_OF_SYNC 2014
|
|
||||||
#define CR_NAMEDPIPE_CONNECTION 2015
|
|
||||||
#define CR_NAMEDPIPEWAIT_ERROR 2016
|
|
||||||
#define CR_NAMEDPIPEOPEN_ERROR 2017
|
|
||||||
#define CR_NAMEDPIPESETSTATE_ERROR 2018
|
|
||||||
#define CR_CANT_READ_CHARSET 2019
|
|
||||||
#define CR_NET_PACKET_TOO_LARGE 2020
|
|
||||||
@@ -37,6 +37,8 @@ void PlayerEventLogs::Init()
|
|||||||
db.emplace_back(e.id);
|
db.emplace_back(e.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<PlayerEventLogSettingsRepository::PlayerEventLogSettings> settings_to_insert{};
|
||||||
|
|
||||||
// insert entries that don't exist in database
|
// insert entries that don't exist in database
|
||||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
||||||
bool is_in_database = std::find(db.begin(), db.end(), i) != db.end();
|
bool is_in_database = std::find(db.begin(), db.end(), i) != db.end();
|
||||||
@@ -56,21 +58,21 @@ void PlayerEventLogs::Init()
|
|||||||
|
|
||||||
bool is_missing_in_database = std::find(db.begin(), db.end(), i) == db.end();
|
bool is_missing_in_database = std::find(db.begin(), db.end(), i) == db.end();
|
||||||
if (is_missing_in_database && is_implemented && !is_deprecated) {
|
if (is_missing_in_database && is_implemented && !is_deprecated) {
|
||||||
LogInfo(
|
LogInfo("[New] PlayerEvent [{}] ({})", PlayerEvent::EventName[i], i);
|
||||||
"[New] PlayerEvent [{}] ({})",
|
|
||||||
PlayerEvent::EventName[i],
|
|
||||||
i
|
|
||||||
);
|
|
||||||
|
|
||||||
auto c = PlayerEventLogSettingsRepository::NewEntity();
|
auto c = PlayerEventLogSettingsRepository::NewEntity();
|
||||||
c.id = i;
|
c.id = i;
|
||||||
c.event_name = PlayerEvent::EventName[i];
|
c.event_name = PlayerEvent::EventName[i];
|
||||||
c.event_enabled = m_settings[i].event_enabled;
|
c.event_enabled = m_settings[i].event_enabled;
|
||||||
c.retention_days = m_settings[i].retention_days;
|
c.retention_days = m_settings[i].retention_days;
|
||||||
PlayerEventLogSettingsRepository::InsertOne(*m_database, c);
|
settings_to_insert.emplace_back(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!settings_to_insert.empty()) {
|
||||||
|
PlayerEventLogSettingsRepository::ReplaceMany(*m_database, settings_to_insert);
|
||||||
|
}
|
||||||
|
|
||||||
bool processing_in_world = !RuleB(Logging, PlayerEventsQSProcess) && IsWorld();
|
bool processing_in_world = !RuleB(Logging, PlayerEventsQSProcess) && IsWorld();
|
||||||
bool processing_in_qs = RuleB(Logging, PlayerEventsQSProcess) && IsQueryServ();
|
bool processing_in_qs = RuleB(Logging, PlayerEventsQSProcess) && IsQueryServ();
|
||||||
|
|
||||||
@@ -611,7 +613,7 @@ void PlayerEventLogs::Process()
|
|||||||
|
|
||||||
void PlayerEventLogs::ProcessRetentionTruncation()
|
void PlayerEventLogs::ProcessRetentionTruncation()
|
||||||
{
|
{
|
||||||
LogInfo("Running truncation");
|
LogPlayerEvents("Running truncation");
|
||||||
|
|
||||||
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
for (int i = PlayerEvent::GM_COMMAND; i != PlayerEvent::MAX; i++) {
|
||||||
if (m_settings[i].retention_days > 0) {
|
if (m_settings[i].retention_days > 0) {
|
||||||
|
|||||||
@@ -801,7 +801,7 @@ int16 EQ::InventoryProfile::HasItemByLoreGroup(uint32 loregroup, uint8 where)
|
|||||||
// Returns slot_id when there's one available, else SLOT_INVALID
|
// Returns slot_id when there's one available, else SLOT_INVALID
|
||||||
int16 EQ::InventoryProfile::FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size, bool is_arrow)
|
int16 EQ::InventoryProfile::FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size, bool is_arrow)
|
||||||
{
|
{
|
||||||
const int16 last_bag_slot = RuleI(World, ExpansionSettings) & EQ::expansions::bitHoT ? EQ::invslot::slotGeneral10 : EQ::invslot::slotGeneral8;
|
const int16 last_bag_slot = (RuleI(World, ExpansionSettings) == -1 || RuleI(World, ExpansionSettings) & EQ::expansions::bitHoT) ? EQ::invslot::slotGeneral10 : EQ::invslot::slotGeneral8;
|
||||||
|
|
||||||
for (int16 i = invslot::GENERAL_BEGIN; i <= last_bag_slot; i++) { // Check basic inventory
|
for (int16 i = invslot::GENERAL_BEGIN; i <= last_bag_slot; i++) { // Check basic inventory
|
||||||
if ((((uint64) 1 << i) & m_lookup->PossessionsBitmask) == 0) {
|
if ((((uint64) 1 << i) & m_lookup->PossessionsBitmask) == 0) {
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
/* EQEMu: Everquest Server Emulator
|
|
||||||
Copyright (C) 2001-2002 EQEMu Development Team (http://eqemulator.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 LANGUAGES_H
|
|
||||||
#define LANGUAGES_H
|
|
||||||
#include "../common/types.h"
|
|
||||||
|
|
||||||
#define LANG_COMMON_TONGUE 0
|
|
||||||
#define LANG_BARBARIAN 1
|
|
||||||
#define LANG_ERUDIAN 2
|
|
||||||
#define LANG_ELVISH 3
|
|
||||||
#define LANG_DARK_ELVISH 4
|
|
||||||
#define LANG_DWARVISH 5
|
|
||||||
#define LANG_TROLL 6
|
|
||||||
#define LANG_OGRE 7
|
|
||||||
#define LANG_GNOMISH 8
|
|
||||||
#define LANG_HALFLING 9
|
|
||||||
#define LANG_THIEVES_CANT 10
|
|
||||||
#define LANG_OLD_ERUDIAN 11
|
|
||||||
#define LANG_ELDER_ELVISH 12
|
|
||||||
#define LANG_FROGLOK 13
|
|
||||||
#define LANG_GOBLIN 14
|
|
||||||
#define LANG_GNOLL 15
|
|
||||||
#define LANG_COMBINE_TONGUE 16
|
|
||||||
#define LANG_ELDER_TEIRDAL 17
|
|
||||||
#define LANG_LIZARDMAN 18
|
|
||||||
#define LANG_ORCISH 19
|
|
||||||
#define LANG_FAERIE 20
|
|
||||||
#define LANG_DRAGON 21
|
|
||||||
#define LANG_ELDER_DRAGON 22
|
|
||||||
#define LANG_DARK_SPEECH 23
|
|
||||||
#define LANG_VAH_SHIR 24
|
|
||||||
#define LANG_ALARAN 25
|
|
||||||
#define LANG_HADAL 26
|
|
||||||
#define LANG_UNKNOWN 27
|
|
||||||
|
|
||||||
#define MAX_LANGUAGE_SKILL 100
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -202,7 +202,7 @@ namespace RoF
|
|||||||
unsigned char *emu_buffer = in->pBuffer;
|
unsigned char *emu_buffer = in->pBuffer;
|
||||||
uint32 opcode = *((uint32*)emu_buffer);
|
uint32 opcode = *((uint32*)emu_buffer);
|
||||||
|
|
||||||
if (opcode == 8) {
|
if (opcode == AlternateCurrencyMode::Populate) {
|
||||||
AltCurrencyPopulate_Struct *populate = (AltCurrencyPopulate_Struct*)emu_buffer;
|
AltCurrencyPopulate_Struct *populate = (AltCurrencyPopulate_Struct*)emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(
|
auto outapp = new EQApplicationPacket(
|
||||||
@@ -3165,7 +3165,7 @@ namespace RoF
|
|||||||
|
|
||||||
SpawnAppearance_Struct *sas = (SpawnAppearance_Struct *)emu_buffer;
|
SpawnAppearance_Struct *sas = (SpawnAppearance_Struct *)emu_buffer;
|
||||||
|
|
||||||
if (sas->type != AT_Size)
|
if (sas->type != AppearanceType::Size)
|
||||||
{
|
{
|
||||||
dest->FastQueuePacket(&in, ack_req);
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -274,7 +274,7 @@ namespace RoF2
|
|||||||
unsigned char *emu_buffer = in->pBuffer;
|
unsigned char *emu_buffer = in->pBuffer;
|
||||||
uint32 opcode = *((uint32*)emu_buffer);
|
uint32 opcode = *((uint32*)emu_buffer);
|
||||||
|
|
||||||
if (opcode == 8) {
|
if (opcode == AlternateCurrencyMode::Populate) {
|
||||||
AltCurrencyPopulate_Struct *populate = (AltCurrencyPopulate_Struct*)emu_buffer;
|
AltCurrencyPopulate_Struct *populate = (AltCurrencyPopulate_Struct*)emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(
|
auto outapp = new EQApplicationPacket(
|
||||||
@@ -3218,7 +3218,7 @@ namespace RoF2
|
|||||||
|
|
||||||
SpawnAppearance_Struct *sas = (SpawnAppearance_Struct *)emu_buffer;
|
SpawnAppearance_Struct *sas = (SpawnAppearance_Struct *)emu_buffer;
|
||||||
|
|
||||||
if (sas->type != AT_Size)
|
if (sas->type != AppearanceType::Size)
|
||||||
{
|
{
|
||||||
dest->FastQueuePacket(&in, ack_req);
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ namespace UF
|
|||||||
unsigned char *emu_buffer = in->pBuffer;
|
unsigned char *emu_buffer = in->pBuffer;
|
||||||
uint32 opcode = *((uint32*)emu_buffer);
|
uint32 opcode = *((uint32*)emu_buffer);
|
||||||
|
|
||||||
if (opcode == 8) {
|
if (opcode == AlternateCurrencyMode::Populate) {
|
||||||
AltCurrencyPopulate_Struct *populate = (AltCurrencyPopulate_Struct*)emu_buffer;
|
AltCurrencyPopulate_Struct *populate = (AltCurrencyPopulate_Struct*)emu_buffer;
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(
|
auto outapp = new EQApplicationPacket(
|
||||||
@@ -2339,7 +2339,7 @@ namespace UF
|
|||||||
|
|
||||||
SpawnAppearance_Struct *sas = (SpawnAppearance_Struct *)emu_buffer;
|
SpawnAppearance_Struct *sas = (SpawnAppearance_Struct *)emu_buffer;
|
||||||
|
|
||||||
if (sas->type != AT_Size)
|
if (sas->type != AppearanceType::Size)
|
||||||
{
|
{
|
||||||
dest->FastQueuePacket(&in, ack_req);
|
dest->FastQueuePacket(&in, ack_req);
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ enum : int { //values for pTimerType
|
|||||||
pTimerBeggingPickPocket = 27,
|
pTimerBeggingPickPocket = 27,
|
||||||
pTimerLinkedSpellReuseStart = 28,
|
pTimerLinkedSpellReuseStart = 28,
|
||||||
pTimerLinkedSpellReuseEnd = 48,
|
pTimerLinkedSpellReuseEnd = 48,
|
||||||
|
pTimerClearXTarget = 50,
|
||||||
|
|
||||||
pTimerShieldAbility = 86,
|
pTimerShieldAbility = 86,
|
||||||
|
|
||||||
|
|||||||
+36
-36
@@ -1598,7 +1598,7 @@ float GetRaceGenderDefaultHeight(int race, int gender)
|
|||||||
return 6.0f;
|
return 6.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gender == FEMALE) {
|
if (gender == Gender::Female) {
|
||||||
return female_height[race];
|
return female_height[race];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1606,38 +1606,38 @@ float GetRaceGenderDefaultHeight(int race, int gender)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PlayerAppearance prep
|
// PlayerAppearance prep
|
||||||
#define HUMAN_MALE ((HUMAN << 8) | MALE)
|
#define HUMAN_MALE ((HUMAN << 8) | Gender::Male)
|
||||||
#define HUMAN_FEMALE ((HUMAN << 8) | FEMALE)
|
#define HUMAN_FEMALE ((HUMAN << 8) | Gender::Female)
|
||||||
#define BARBARIAN_MALE ((BARBARIAN << 8) | MALE)
|
#define BARBARIAN_MALE ((BARBARIAN << 8) | Gender::Male)
|
||||||
#define BARBARIAN_FEMALE ((BARBARIAN << 8) | FEMALE)
|
#define BARBARIAN_FEMALE ((BARBARIAN << 8) | Gender::Female)
|
||||||
#define ERUDITE_MALE ((ERUDITE << 8) | MALE)
|
#define ERUDITE_MALE ((ERUDITE << 8) | Gender::Male)
|
||||||
#define ERUDITE_FEMALE ((ERUDITE << 8) | FEMALE)
|
#define ERUDITE_FEMALE ((ERUDITE << 8) | Gender::Female)
|
||||||
#define WOOD_ELF_MALE ((WOOD_ELF << 8) | MALE)
|
#define WOOD_ELF_MALE ((WOOD_ELF << 8) | Gender::Male)
|
||||||
#define WOOD_ELF_FEMALE ((WOOD_ELF << 8) | FEMALE)
|
#define WOOD_ELF_FEMALE ((WOOD_ELF << 8) | Gender::Female)
|
||||||
#define HIGH_ELF_MALE ((HIGH_ELF << 8) | MALE)
|
#define HIGH_ELF_MALE ((HIGH_ELF << 8) | Gender::Male)
|
||||||
#define HIGH_ELF_FEMALE ((HIGH_ELF << 8) | FEMALE)
|
#define HIGH_ELF_FEMALE ((HIGH_ELF << 8) | Gender::Female)
|
||||||
#define DARK_ELF_MALE ((DARK_ELF << 8) | MALE)
|
#define DARK_ELF_MALE ((DARK_ELF << 8) | Gender::Male)
|
||||||
#define DARK_ELF_FEMALE ((DARK_ELF << 8) | FEMALE)
|
#define DARK_ELF_FEMALE ((DARK_ELF << 8) | Gender::Female)
|
||||||
#define HALF_ELF_MALE ((HALF_ELF << 8) | MALE)
|
#define HALF_ELF_MALE ((HALF_ELF << 8) | Gender::Male)
|
||||||
#define HALF_ELF_FEMALE ((HALF_ELF << 8) | FEMALE)
|
#define HALF_ELF_FEMALE ((HALF_ELF << 8) | Gender::Female)
|
||||||
#define DWARF_MALE ((DWARF << 8) | MALE)
|
#define DWARF_MALE ((DWARF << 8) | Gender::Male)
|
||||||
#define DWARF_FEMALE ((DWARF << 8) | FEMALE)
|
#define DWARF_FEMALE ((DWARF << 8) | Gender::Female)
|
||||||
#define TROLL_MALE ((TROLL << 8) | MALE)
|
#define TROLL_MALE ((TROLL << 8) | Gender::Male)
|
||||||
#define TROLL_FEMALE ((TROLL << 8) | FEMALE)
|
#define TROLL_FEMALE ((TROLL << 8) | Gender::Female)
|
||||||
#define OGRE_MALE ((OGRE << 8) | MALE)
|
#define OGRE_MALE ((OGRE << 8) | Gender::Male)
|
||||||
#define OGRE_FEMALE ((OGRE << 8) | FEMALE)
|
#define OGRE_FEMALE ((OGRE << 8) | Gender::Female)
|
||||||
#define HALFLING_MALE ((HALFLING << 8) | MALE)
|
#define HALFLING_MALE ((HALFLING << 8) | Gender::Male)
|
||||||
#define HALFLING_FEMALE ((HALFLING << 8) | FEMALE)
|
#define HALFLING_FEMALE ((HALFLING << 8) | Gender::Female)
|
||||||
#define GNOME_MALE ((GNOME << 8) | MALE)
|
#define GNOME_MALE ((GNOME << 8) | Gender::Male)
|
||||||
#define GNOME_FEMALE ((GNOME << 8) | FEMALE)
|
#define GNOME_FEMALE ((GNOME << 8) | Gender::Female)
|
||||||
#define IKSAR_MALE ((IKSAR << 8) | MALE)
|
#define IKSAR_MALE ((IKSAR << 8) | Gender::Male)
|
||||||
#define IKSAR_FEMALE ((IKSAR << 8) | FEMALE)
|
#define IKSAR_FEMALE ((IKSAR << 8) | Gender::Female)
|
||||||
#define VAHSHIR_MALE ((VAHSHIR << 8) | MALE)
|
#define VAHSHIR_MALE ((VAHSHIR << 8) | Gender::Male)
|
||||||
#define VAHSHIR_FEMALE ((VAHSHIR << 8) | FEMALE)
|
#define VAHSHIR_FEMALE ((VAHSHIR << 8) | Gender::Female)
|
||||||
#define FROGLOK_MALE ((FROGLOK << 8) | MALE)
|
#define FROGLOK_MALE ((FROGLOK << 8) | Gender::Male)
|
||||||
#define FROGLOK_FEMALE ((FROGLOK << 8) | FEMALE)
|
#define FROGLOK_FEMALE ((FROGLOK << 8) | Gender::Female)
|
||||||
#define DRAKKIN_MALE ((DRAKKIN << 8) | MALE)
|
#define DRAKKIN_MALE ((DRAKKIN << 8) | Gender::Male)
|
||||||
#define DRAKKIN_FEMALE ((DRAKKIN << 8) | FEMALE)
|
#define DRAKKIN_FEMALE ((DRAKKIN << 8) | Gender::Female)
|
||||||
|
|
||||||
#define BINDRG(r, g) (((int)r << 8) | g)
|
#define BINDRG(r, g) (((int)r << 8) | g)
|
||||||
|
|
||||||
@@ -2238,11 +2238,11 @@ bool PlayerAppearance::IsValidWoad(uint16 race_id, uint8 gender_id, uint8 woad_v
|
|||||||
|
|
||||||
const char* GetGenderName(uint32 gender_id) {
|
const char* GetGenderName(uint32 gender_id) {
|
||||||
const char* gender_name = "Unknown";
|
const char* gender_name = "Unknown";
|
||||||
if (gender_id == MALE) {
|
if (gender_id == Gender::Male) {
|
||||||
gender_name = "Male";
|
gender_name = "Male";
|
||||||
} else if (gender_id == FEMALE) {
|
} else if (gender_id == Gender::Female) {
|
||||||
gender_name = "Female";
|
gender_name = "Female";
|
||||||
} else if (gender_id == NEUTER) {
|
} else if (gender_id == Gender::Neuter) {
|
||||||
gender_name = "Neuter";
|
gender_name = "Neuter";
|
||||||
}
|
}
|
||||||
return gender_name;
|
return gender_name;
|
||||||
|
|||||||
+5
-3
@@ -21,9 +21,11 @@
|
|||||||
#include "../common/types.h"
|
#include "../common/types.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#define MALE 0
|
namespace Gender {
|
||||||
#define FEMALE 1
|
constexpr uint8 Male = 0;
|
||||||
#define NEUTER 2
|
constexpr uint8 Female = 1;
|
||||||
|
constexpr uint8 Neuter = 2;
|
||||||
|
}
|
||||||
|
|
||||||
//theres a big list straight from the client below.
|
//theres a big list straight from the client below.
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_ACCOUNT_REPOSITORY_H
|
#ifndef EQEMU_BASE_ACCOUNT_REPOSITORY_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseAccountRepository {
|
class BaseAccountRepository {
|
||||||
public:
|
public:
|
||||||
struct Account {
|
struct Account {
|
||||||
@@ -196,8 +197,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
account_id
|
account_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -547,6 +549,108 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const Account &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back("'" + Strings::Escape(e.name) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.charname) + "'");
|
||||||
|
v.push_back(std::to_string(e.sharedplat));
|
||||||
|
v.push_back("'" + Strings::Escape(e.password) + "'");
|
||||||
|
v.push_back(std::to_string(e.status));
|
||||||
|
v.push_back("'" + Strings::Escape(e.ls_id) + "'");
|
||||||
|
v.push_back(std::to_string(e.lsaccount_id));
|
||||||
|
v.push_back(std::to_string(e.gmspeed));
|
||||||
|
v.push_back(std::to_string(e.invulnerable));
|
||||||
|
v.push_back(std::to_string(e.flymode));
|
||||||
|
v.push_back(std::to_string(e.ignore_tells));
|
||||||
|
v.push_back(std::to_string(e.revoked));
|
||||||
|
v.push_back(std::to_string(e.karma));
|
||||||
|
v.push_back("'" + Strings::Escape(e.minilogin_ip) + "'");
|
||||||
|
v.push_back(std::to_string(e.hideme));
|
||||||
|
v.push_back(std::to_string(e.rulesflag));
|
||||||
|
v.push_back("FROM_UNIXTIME(" + (e.suspendeduntil > 0 ? std::to_string(e.suspendeduntil) : "null") + ")");
|
||||||
|
v.push_back(std::to_string(e.time_creation));
|
||||||
|
v.push_back("'" + Strings::Escape(e.ban_reason) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.suspend_reason) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.crc_eqgame) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.crc_skillcaps) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.crc_basedata) + "'");
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<Account> &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("'" + Strings::Escape(e.name) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.charname) + "'");
|
||||||
|
v.push_back(std::to_string(e.sharedplat));
|
||||||
|
v.push_back("'" + Strings::Escape(e.password) + "'");
|
||||||
|
v.push_back(std::to_string(e.status));
|
||||||
|
v.push_back("'" + Strings::Escape(e.ls_id) + "'");
|
||||||
|
v.push_back(std::to_string(e.lsaccount_id));
|
||||||
|
v.push_back(std::to_string(e.gmspeed));
|
||||||
|
v.push_back(std::to_string(e.invulnerable));
|
||||||
|
v.push_back(std::to_string(e.flymode));
|
||||||
|
v.push_back(std::to_string(e.ignore_tells));
|
||||||
|
v.push_back(std::to_string(e.revoked));
|
||||||
|
v.push_back(std::to_string(e.karma));
|
||||||
|
v.push_back("'" + Strings::Escape(e.minilogin_ip) + "'");
|
||||||
|
v.push_back(std::to_string(e.hideme));
|
||||||
|
v.push_back(std::to_string(e.rulesflag));
|
||||||
|
v.push_back("FROM_UNIXTIME(" + (e.suspendeduntil > 0 ? std::to_string(e.suspendeduntil) : "null") + ")");
|
||||||
|
v.push_back(std::to_string(e.time_creation));
|
||||||
|
v.push_back("'" + Strings::Escape(e.ban_reason) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.suspend_reason) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.crc_eqgame) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.crc_skillcaps) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.crc_basedata) + "'");
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_ACCOUNT_REPOSITORY_H
|
#endif //EQEMU_BASE_ACCOUNT_REPOSITORY_H
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_CHARACTER_ALT_CURRENCY_REPOSITORY_H
|
#ifndef EQEMU_BASE_CHARACTER_ALT_CURRENCY_REPOSITORY_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseCharacterAltCurrencyRepository {
|
class BaseCharacterAltCurrencyRepository {
|
||||||
public:
|
public:
|
||||||
struct CharacterAltCurrency {
|
struct CharacterAltCurrency {
|
||||||
@@ -112,8 +113,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
character_alt_currency_id
|
character_alt_currency_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -338,6 +340,66 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterAltCurrency &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.char_id));
|
||||||
|
v.push_back(std::to_string(e.currency_id));
|
||||||
|
v.push_back(std::to_string(e.amount));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterAltCurrency> &entries
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> insert_chunks;
|
||||||
|
|
||||||
|
for (auto &e: entries) {
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.char_id));
|
||||||
|
v.push_back(std::to_string(e.currency_id));
|
||||||
|
v.push_back(std::to_string(e.amount));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_CHARACTER_ALT_CURRENCY_REPOSITORY_H
|
#endif //EQEMU_BASE_CHARACTER_ALT_CURRENCY_REPOSITORY_H
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_CHARACTER_ALTERNATE_ABILITIES_REPOSITORY_H
|
#ifndef EQEMU_BASE_CHARACTER_ALTERNATE_ABILITIES_REPOSITORY_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseCharacterAlternateAbilitiesRepository {
|
class BaseCharacterAlternateAbilitiesRepository {
|
||||||
public:
|
public:
|
||||||
struct CharacterAlternateAbilities {
|
struct CharacterAlternateAbilities {
|
||||||
@@ -116,8 +117,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
character_alternate_abilities_id
|
character_alternate_abilities_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -348,6 +350,68 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterAlternateAbilities &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.aa_id));
|
||||||
|
v.push_back(std::to_string(e.aa_value));
|
||||||
|
v.push_back(std::to_string(e.charges));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterAlternateAbilities> &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.aa_id));
|
||||||
|
v.push_back(std::to_string(e.aa_value));
|
||||||
|
v.push_back(std::to_string(e.charges));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_CHARACTER_ALTERNATE_ABILITIES_REPOSITORY_H
|
#endif //EQEMU_BASE_CHARACTER_ALTERNATE_ABILITIES_REPOSITORY_H
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_CHARACTER_AURAS_REPOSITORY_H
|
#ifndef EQEMU_BASE_CHARACTER_AURAS_REPOSITORY_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseCharacterAurasRepository {
|
class BaseCharacterAurasRepository {
|
||||||
public:
|
public:
|
||||||
struct CharacterAuras {
|
struct CharacterAuras {
|
||||||
@@ -112,8 +113,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
character_auras_id
|
character_auras_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -338,6 +340,66 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterAuras &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.slot));
|
||||||
|
v.push_back(std::to_string(e.spell_id));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterAuras> &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.slot));
|
||||||
|
v.push_back(std::to_string(e.spell_id));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_CHARACTER_AURAS_REPOSITORY_H
|
#endif //EQEMU_BASE_CHARACTER_AURAS_REPOSITORY_H
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_CHARACTER_BANDOLIER_REPOSITORY_H
|
#ifndef EQEMU_BASE_CHARACTER_BANDOLIER_REPOSITORY_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseCharacterBandolierRepository {
|
class BaseCharacterBandolierRepository {
|
||||||
public:
|
public:
|
||||||
struct CharacterBandolier {
|
struct CharacterBandolier {
|
||||||
@@ -124,8 +125,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
character_bandolier_id
|
character_bandolier_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -368,6 +370,72 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterBandolier &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.bandolier_id));
|
||||||
|
v.push_back(std::to_string(e.bandolier_slot));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
v.push_back(std::to_string(e.icon));
|
||||||
|
v.push_back("'" + Strings::Escape(e.bandolier_name) + "'");
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterBandolier> &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.bandolier_id));
|
||||||
|
v.push_back(std::to_string(e.bandolier_slot));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
v.push_back(std::to_string(e.icon));
|
||||||
|
v.push_back("'" + Strings::Escape(e.bandolier_name) + "'");
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_CHARACTER_BANDOLIER_REPOSITORY_H
|
#endif //EQEMU_BASE_CHARACTER_BANDOLIER_REPOSITORY_H
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_CHARACTER_BIND_REPOSITORY_H
|
#ifndef EQEMU_BASE_CHARACTER_BIND_REPOSITORY_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseCharacterBindRepository {
|
class BaseCharacterBindRepository {
|
||||||
public:
|
public:
|
||||||
struct CharacterBind {
|
struct CharacterBind {
|
||||||
@@ -132,8 +133,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
character_bind_id
|
character_bind_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -387,6 +389,76 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterBind &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.slot));
|
||||||
|
v.push_back(std::to_string(e.zone_id));
|
||||||
|
v.push_back(std::to_string(e.instance_id));
|
||||||
|
v.push_back(std::to_string(e.x));
|
||||||
|
v.push_back(std::to_string(e.y));
|
||||||
|
v.push_back(std::to_string(e.z));
|
||||||
|
v.push_back(std::to_string(e.heading));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterBind> &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.slot));
|
||||||
|
v.push_back(std::to_string(e.zone_id));
|
||||||
|
v.push_back(std::to_string(e.instance_id));
|
||||||
|
v.push_back(std::to_string(e.x));
|
||||||
|
v.push_back(std::to_string(e.y));
|
||||||
|
v.push_back(std::to_string(e.z));
|
||||||
|
v.push_back(std::to_string(e.heading));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_CHARACTER_BIND_REPOSITORY_H
|
#endif //EQEMU_BASE_CHARACTER_BIND_REPOSITORY_H
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_CHARACTER_BUFFS_REPOSITORY_H
|
#ifndef EQEMU_BASE_CHARACTER_BUFFS_REPOSITORY_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseCharacterBuffsRepository {
|
class BaseCharacterBuffsRepository {
|
||||||
public:
|
public:
|
||||||
struct CharacterBuffs {
|
struct CharacterBuffs {
|
||||||
@@ -168,8 +169,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
character_buffs_id
|
character_buffs_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -478,6 +480,94 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterBuffs &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.character_id));
|
||||||
|
v.push_back(std::to_string(e.slot_id));
|
||||||
|
v.push_back(std::to_string(e.spell_id));
|
||||||
|
v.push_back(std::to_string(e.caster_level));
|
||||||
|
v.push_back("'" + Strings::Escape(e.caster_name) + "'");
|
||||||
|
v.push_back(std::to_string(e.ticsremaining));
|
||||||
|
v.push_back(std::to_string(e.counters));
|
||||||
|
v.push_back(std::to_string(e.numhits));
|
||||||
|
v.push_back(std::to_string(e.melee_rune));
|
||||||
|
v.push_back(std::to_string(e.magic_rune));
|
||||||
|
v.push_back(std::to_string(e.persistent));
|
||||||
|
v.push_back(std::to_string(e.dot_rune));
|
||||||
|
v.push_back(std::to_string(e.caston_x));
|
||||||
|
v.push_back(std::to_string(e.caston_y));
|
||||||
|
v.push_back(std::to_string(e.caston_z));
|
||||||
|
v.push_back(std::to_string(e.ExtraDIChance));
|
||||||
|
v.push_back(std::to_string(e.instrument_mod));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterBuffs> &entries
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> insert_chunks;
|
||||||
|
|
||||||
|
for (auto &e: entries) {
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.character_id));
|
||||||
|
v.push_back(std::to_string(e.slot_id));
|
||||||
|
v.push_back(std::to_string(e.spell_id));
|
||||||
|
v.push_back(std::to_string(e.caster_level));
|
||||||
|
v.push_back("'" + Strings::Escape(e.caster_name) + "'");
|
||||||
|
v.push_back(std::to_string(e.ticsremaining));
|
||||||
|
v.push_back(std::to_string(e.counters));
|
||||||
|
v.push_back(std::to_string(e.numhits));
|
||||||
|
v.push_back(std::to_string(e.melee_rune));
|
||||||
|
v.push_back(std::to_string(e.magic_rune));
|
||||||
|
v.push_back(std::to_string(e.persistent));
|
||||||
|
v.push_back(std::to_string(e.dot_rune));
|
||||||
|
v.push_back(std::to_string(e.caston_x));
|
||||||
|
v.push_back(std::to_string(e.caston_y));
|
||||||
|
v.push_back(std::to_string(e.caston_z));
|
||||||
|
v.push_back(std::to_string(e.ExtraDIChance));
|
||||||
|
v.push_back(std::to_string(e.instrument_mod));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_CHARACTER_BUFFS_REPOSITORY_H
|
#endif //EQEMU_BASE_CHARACTER_BUFFS_REPOSITORY_H
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_CHARACTER_CURRENCY_REPOSITORY_H
|
#ifndef EQEMU_BASE_CHARACTER_CURRENCY_REPOSITORY_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseCharacterCurrencyRepository {
|
class BaseCharacterCurrencyRepository {
|
||||||
public:
|
public:
|
||||||
struct CharacterCurrency {
|
struct CharacterCurrency {
|
||||||
@@ -168,8 +169,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
character_currency_id
|
character_currency_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -478,6 +480,94 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterCurrency &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.platinum));
|
||||||
|
v.push_back(std::to_string(e.gold));
|
||||||
|
v.push_back(std::to_string(e.silver));
|
||||||
|
v.push_back(std::to_string(e.copper));
|
||||||
|
v.push_back(std::to_string(e.platinum_bank));
|
||||||
|
v.push_back(std::to_string(e.gold_bank));
|
||||||
|
v.push_back(std::to_string(e.silver_bank));
|
||||||
|
v.push_back(std::to_string(e.copper_bank));
|
||||||
|
v.push_back(std::to_string(e.platinum_cursor));
|
||||||
|
v.push_back(std::to_string(e.gold_cursor));
|
||||||
|
v.push_back(std::to_string(e.silver_cursor));
|
||||||
|
v.push_back(std::to_string(e.copper_cursor));
|
||||||
|
v.push_back(std::to_string(e.radiant_crystals));
|
||||||
|
v.push_back(std::to_string(e.career_radiant_crystals));
|
||||||
|
v.push_back(std::to_string(e.ebon_crystals));
|
||||||
|
v.push_back(std::to_string(e.career_ebon_crystals));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterCurrency> &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.platinum));
|
||||||
|
v.push_back(std::to_string(e.gold));
|
||||||
|
v.push_back(std::to_string(e.silver));
|
||||||
|
v.push_back(std::to_string(e.copper));
|
||||||
|
v.push_back(std::to_string(e.platinum_bank));
|
||||||
|
v.push_back(std::to_string(e.gold_bank));
|
||||||
|
v.push_back(std::to_string(e.silver_bank));
|
||||||
|
v.push_back(std::to_string(e.copper_bank));
|
||||||
|
v.push_back(std::to_string(e.platinum_cursor));
|
||||||
|
v.push_back(std::to_string(e.gold_cursor));
|
||||||
|
v.push_back(std::to_string(e.silver_cursor));
|
||||||
|
v.push_back(std::to_string(e.copper_cursor));
|
||||||
|
v.push_back(std::to_string(e.radiant_crystals));
|
||||||
|
v.push_back(std::to_string(e.career_radiant_crystals));
|
||||||
|
v.push_back(std::to_string(e.ebon_crystals));
|
||||||
|
v.push_back(std::to_string(e.career_ebon_crystals));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_CHARACTER_CURRENCY_REPOSITORY_H
|
#endif //EQEMU_BASE_CHARACTER_CURRENCY_REPOSITORY_H
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_CHARACTER_DATA_REPOSITORY_H
|
#ifndef EQEMU_BASE_CHARACTER_DATA_REPOSITORY_H
|
||||||
@@ -1339,6 +1339,266 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterData &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.account_id));
|
||||||
|
v.push_back("'" + Strings::Escape(e.name) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.last_name) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.title) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.suffix) + "'");
|
||||||
|
v.push_back(std::to_string(e.zone_id));
|
||||||
|
v.push_back(std::to_string(e.zone_instance));
|
||||||
|
v.push_back(std::to_string(e.y));
|
||||||
|
v.push_back(std::to_string(e.x));
|
||||||
|
v.push_back(std::to_string(e.z));
|
||||||
|
v.push_back(std::to_string(e.heading));
|
||||||
|
v.push_back(std::to_string(e.gender));
|
||||||
|
v.push_back(std::to_string(e.race));
|
||||||
|
v.push_back(std::to_string(e.class_));
|
||||||
|
v.push_back(std::to_string(e.level));
|
||||||
|
v.push_back(std::to_string(e.deity));
|
||||||
|
v.push_back(std::to_string(e.birthday));
|
||||||
|
v.push_back(std::to_string(e.last_login));
|
||||||
|
v.push_back(std::to_string(e.time_played));
|
||||||
|
v.push_back(std::to_string(e.level2));
|
||||||
|
v.push_back(std::to_string(e.anon));
|
||||||
|
v.push_back(std::to_string(e.gm));
|
||||||
|
v.push_back(std::to_string(e.face));
|
||||||
|
v.push_back(std::to_string(e.hair_color));
|
||||||
|
v.push_back(std::to_string(e.hair_style));
|
||||||
|
v.push_back(std::to_string(e.beard));
|
||||||
|
v.push_back(std::to_string(e.beard_color));
|
||||||
|
v.push_back(std::to_string(e.eye_color_1));
|
||||||
|
v.push_back(std::to_string(e.eye_color_2));
|
||||||
|
v.push_back(std::to_string(e.drakkin_heritage));
|
||||||
|
v.push_back(std::to_string(e.drakkin_tattoo));
|
||||||
|
v.push_back(std::to_string(e.drakkin_details));
|
||||||
|
v.push_back(std::to_string(e.ability_time_seconds));
|
||||||
|
v.push_back(std::to_string(e.ability_number));
|
||||||
|
v.push_back(std::to_string(e.ability_time_minutes));
|
||||||
|
v.push_back(std::to_string(e.ability_time_hours));
|
||||||
|
v.push_back(std::to_string(e.exp));
|
||||||
|
v.push_back(std::to_string(e.exp_enabled));
|
||||||
|
v.push_back(std::to_string(e.aa_points_spent));
|
||||||
|
v.push_back(std::to_string(e.aa_exp));
|
||||||
|
v.push_back(std::to_string(e.aa_points));
|
||||||
|
v.push_back(std::to_string(e.group_leadership_exp));
|
||||||
|
v.push_back(std::to_string(e.raid_leadership_exp));
|
||||||
|
v.push_back(std::to_string(e.group_leadership_points));
|
||||||
|
v.push_back(std::to_string(e.raid_leadership_points));
|
||||||
|
v.push_back(std::to_string(e.points));
|
||||||
|
v.push_back(std::to_string(e.cur_hp));
|
||||||
|
v.push_back(std::to_string(e.mana));
|
||||||
|
v.push_back(std::to_string(e.endurance));
|
||||||
|
v.push_back(std::to_string(e.intoxication));
|
||||||
|
v.push_back(std::to_string(e.str));
|
||||||
|
v.push_back(std::to_string(e.sta));
|
||||||
|
v.push_back(std::to_string(e.cha));
|
||||||
|
v.push_back(std::to_string(e.dex));
|
||||||
|
v.push_back(std::to_string(e.int_));
|
||||||
|
v.push_back(std::to_string(e.agi));
|
||||||
|
v.push_back(std::to_string(e.wis));
|
||||||
|
v.push_back(std::to_string(e.zone_change_count));
|
||||||
|
v.push_back(std::to_string(e.toxicity));
|
||||||
|
v.push_back(std::to_string(e.hunger_level));
|
||||||
|
v.push_back(std::to_string(e.thirst_level));
|
||||||
|
v.push_back(std::to_string(e.ability_up));
|
||||||
|
v.push_back(std::to_string(e.ldon_points_guk));
|
||||||
|
v.push_back(std::to_string(e.ldon_points_mir));
|
||||||
|
v.push_back(std::to_string(e.ldon_points_mmc));
|
||||||
|
v.push_back(std::to_string(e.ldon_points_ruj));
|
||||||
|
v.push_back(std::to_string(e.ldon_points_tak));
|
||||||
|
v.push_back(std::to_string(e.ldon_points_available));
|
||||||
|
v.push_back(std::to_string(e.tribute_time_remaining));
|
||||||
|
v.push_back(std::to_string(e.career_tribute_points));
|
||||||
|
v.push_back(std::to_string(e.tribute_points));
|
||||||
|
v.push_back(std::to_string(e.tribute_active));
|
||||||
|
v.push_back(std::to_string(e.pvp_status));
|
||||||
|
v.push_back(std::to_string(e.pvp_kills));
|
||||||
|
v.push_back(std::to_string(e.pvp_deaths));
|
||||||
|
v.push_back(std::to_string(e.pvp_current_points));
|
||||||
|
v.push_back(std::to_string(e.pvp_career_points));
|
||||||
|
v.push_back(std::to_string(e.pvp_best_kill_streak));
|
||||||
|
v.push_back(std::to_string(e.pvp_worst_death_streak));
|
||||||
|
v.push_back(std::to_string(e.pvp_current_kill_streak));
|
||||||
|
v.push_back(std::to_string(e.pvp2));
|
||||||
|
v.push_back(std::to_string(e.pvp_type));
|
||||||
|
v.push_back(std::to_string(e.show_helm));
|
||||||
|
v.push_back(std::to_string(e.group_auto_consent));
|
||||||
|
v.push_back(std::to_string(e.raid_auto_consent));
|
||||||
|
v.push_back(std::to_string(e.guild_auto_consent));
|
||||||
|
v.push_back(std::to_string(e.leadership_exp_on));
|
||||||
|
v.push_back(std::to_string(e.RestTimer));
|
||||||
|
v.push_back(std::to_string(e.air_remaining));
|
||||||
|
v.push_back(std::to_string(e.autosplit_enabled));
|
||||||
|
v.push_back(std::to_string(e.lfp));
|
||||||
|
v.push_back(std::to_string(e.lfg));
|
||||||
|
v.push_back("'" + Strings::Escape(e.mailkey) + "'");
|
||||||
|
v.push_back(std::to_string(e.xtargets));
|
||||||
|
v.push_back(std::to_string(e.firstlogon));
|
||||||
|
v.push_back(std::to_string(e.e_aa_effects));
|
||||||
|
v.push_back(std::to_string(e.e_percent_to_aa));
|
||||||
|
v.push_back(std::to_string(e.e_expended_aa_spent));
|
||||||
|
v.push_back(std::to_string(e.aa_points_spent_old));
|
||||||
|
v.push_back(std::to_string(e.aa_points_old));
|
||||||
|
v.push_back(std::to_string(e.e_last_invsnapshot));
|
||||||
|
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterData> &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.account_id));
|
||||||
|
v.push_back("'" + Strings::Escape(e.name) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.last_name) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.title) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.suffix) + "'");
|
||||||
|
v.push_back(std::to_string(e.zone_id));
|
||||||
|
v.push_back(std::to_string(e.zone_instance));
|
||||||
|
v.push_back(std::to_string(e.y));
|
||||||
|
v.push_back(std::to_string(e.x));
|
||||||
|
v.push_back(std::to_string(e.z));
|
||||||
|
v.push_back(std::to_string(e.heading));
|
||||||
|
v.push_back(std::to_string(e.gender));
|
||||||
|
v.push_back(std::to_string(e.race));
|
||||||
|
v.push_back(std::to_string(e.class_));
|
||||||
|
v.push_back(std::to_string(e.level));
|
||||||
|
v.push_back(std::to_string(e.deity));
|
||||||
|
v.push_back(std::to_string(e.birthday));
|
||||||
|
v.push_back(std::to_string(e.last_login));
|
||||||
|
v.push_back(std::to_string(e.time_played));
|
||||||
|
v.push_back(std::to_string(e.level2));
|
||||||
|
v.push_back(std::to_string(e.anon));
|
||||||
|
v.push_back(std::to_string(e.gm));
|
||||||
|
v.push_back(std::to_string(e.face));
|
||||||
|
v.push_back(std::to_string(e.hair_color));
|
||||||
|
v.push_back(std::to_string(e.hair_style));
|
||||||
|
v.push_back(std::to_string(e.beard));
|
||||||
|
v.push_back(std::to_string(e.beard_color));
|
||||||
|
v.push_back(std::to_string(e.eye_color_1));
|
||||||
|
v.push_back(std::to_string(e.eye_color_2));
|
||||||
|
v.push_back(std::to_string(e.drakkin_heritage));
|
||||||
|
v.push_back(std::to_string(e.drakkin_tattoo));
|
||||||
|
v.push_back(std::to_string(e.drakkin_details));
|
||||||
|
v.push_back(std::to_string(e.ability_time_seconds));
|
||||||
|
v.push_back(std::to_string(e.ability_number));
|
||||||
|
v.push_back(std::to_string(e.ability_time_minutes));
|
||||||
|
v.push_back(std::to_string(e.ability_time_hours));
|
||||||
|
v.push_back(std::to_string(e.exp));
|
||||||
|
v.push_back(std::to_string(e.exp_enabled));
|
||||||
|
v.push_back(std::to_string(e.aa_points_spent));
|
||||||
|
v.push_back(std::to_string(e.aa_exp));
|
||||||
|
v.push_back(std::to_string(e.aa_points));
|
||||||
|
v.push_back(std::to_string(e.group_leadership_exp));
|
||||||
|
v.push_back(std::to_string(e.raid_leadership_exp));
|
||||||
|
v.push_back(std::to_string(e.group_leadership_points));
|
||||||
|
v.push_back(std::to_string(e.raid_leadership_points));
|
||||||
|
v.push_back(std::to_string(e.points));
|
||||||
|
v.push_back(std::to_string(e.cur_hp));
|
||||||
|
v.push_back(std::to_string(e.mana));
|
||||||
|
v.push_back(std::to_string(e.endurance));
|
||||||
|
v.push_back(std::to_string(e.intoxication));
|
||||||
|
v.push_back(std::to_string(e.str));
|
||||||
|
v.push_back(std::to_string(e.sta));
|
||||||
|
v.push_back(std::to_string(e.cha));
|
||||||
|
v.push_back(std::to_string(e.dex));
|
||||||
|
v.push_back(std::to_string(e.int_));
|
||||||
|
v.push_back(std::to_string(e.agi));
|
||||||
|
v.push_back(std::to_string(e.wis));
|
||||||
|
v.push_back(std::to_string(e.zone_change_count));
|
||||||
|
v.push_back(std::to_string(e.toxicity));
|
||||||
|
v.push_back(std::to_string(e.hunger_level));
|
||||||
|
v.push_back(std::to_string(e.thirst_level));
|
||||||
|
v.push_back(std::to_string(e.ability_up));
|
||||||
|
v.push_back(std::to_string(e.ldon_points_guk));
|
||||||
|
v.push_back(std::to_string(e.ldon_points_mir));
|
||||||
|
v.push_back(std::to_string(e.ldon_points_mmc));
|
||||||
|
v.push_back(std::to_string(e.ldon_points_ruj));
|
||||||
|
v.push_back(std::to_string(e.ldon_points_tak));
|
||||||
|
v.push_back(std::to_string(e.ldon_points_available));
|
||||||
|
v.push_back(std::to_string(e.tribute_time_remaining));
|
||||||
|
v.push_back(std::to_string(e.career_tribute_points));
|
||||||
|
v.push_back(std::to_string(e.tribute_points));
|
||||||
|
v.push_back(std::to_string(e.tribute_active));
|
||||||
|
v.push_back(std::to_string(e.pvp_status));
|
||||||
|
v.push_back(std::to_string(e.pvp_kills));
|
||||||
|
v.push_back(std::to_string(e.pvp_deaths));
|
||||||
|
v.push_back(std::to_string(e.pvp_current_points));
|
||||||
|
v.push_back(std::to_string(e.pvp_career_points));
|
||||||
|
v.push_back(std::to_string(e.pvp_best_kill_streak));
|
||||||
|
v.push_back(std::to_string(e.pvp_worst_death_streak));
|
||||||
|
v.push_back(std::to_string(e.pvp_current_kill_streak));
|
||||||
|
v.push_back(std::to_string(e.pvp2));
|
||||||
|
v.push_back(std::to_string(e.pvp_type));
|
||||||
|
v.push_back(std::to_string(e.show_helm));
|
||||||
|
v.push_back(std::to_string(e.group_auto_consent));
|
||||||
|
v.push_back(std::to_string(e.raid_auto_consent));
|
||||||
|
v.push_back(std::to_string(e.guild_auto_consent));
|
||||||
|
v.push_back(std::to_string(e.leadership_exp_on));
|
||||||
|
v.push_back(std::to_string(e.RestTimer));
|
||||||
|
v.push_back(std::to_string(e.air_remaining));
|
||||||
|
v.push_back(std::to_string(e.autosplit_enabled));
|
||||||
|
v.push_back(std::to_string(e.lfp));
|
||||||
|
v.push_back(std::to_string(e.lfg));
|
||||||
|
v.push_back("'" + Strings::Escape(e.mailkey) + "'");
|
||||||
|
v.push_back(std::to_string(e.xtargets));
|
||||||
|
v.push_back(std::to_string(e.firstlogon));
|
||||||
|
v.push_back(std::to_string(e.e_aa_effects));
|
||||||
|
v.push_back(std::to_string(e.e_percent_to_aa));
|
||||||
|
v.push_back(std::to_string(e.e_expended_aa_spent));
|
||||||
|
v.push_back(std::to_string(e.aa_points_spent_old));
|
||||||
|
v.push_back(std::to_string(e.aa_points_old));
|
||||||
|
v.push_back(std::to_string(e.e_last_invsnapshot));
|
||||||
|
v.push_back("FROM_UNIXTIME(" + (e.deleted_at > 0 ? std::to_string(e.deleted_at) : "null") + ")");
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_CHARACTER_DATA_REPOSITORY_H
|
#endif //EQEMU_BASE_CHARACTER_DATA_REPOSITORY_H
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_CHARACTER_DISCIPLINES_REPOSITORY_H
|
#ifndef EQEMU_BASE_CHARACTER_DISCIPLINES_REPOSITORY_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseCharacterDisciplinesRepository {
|
class BaseCharacterDisciplinesRepository {
|
||||||
public:
|
public:
|
||||||
struct CharacterDisciplines {
|
struct CharacterDisciplines {
|
||||||
@@ -112,8 +113,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
character_disciplines_id
|
character_disciplines_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -338,6 +340,66 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterDisciplines &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.slot_id));
|
||||||
|
v.push_back(std::to_string(e.disc_id));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterDisciplines> &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.slot_id));
|
||||||
|
v.push_back(std::to_string(e.disc_id));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_CHARACTER_DISCIPLINES_REPOSITORY_H
|
#endif //EQEMU_BASE_CHARACTER_DISCIPLINES_REPOSITORY_H
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_CHARACTER_ITEM_RECAST_REPOSITORY_H
|
#ifndef EQEMU_BASE_CHARACTER_ITEM_RECAST_REPOSITORY_H
|
||||||
@@ -16,11 +16,12 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseCharacterItemRecastRepository {
|
class BaseCharacterItemRecastRepository {
|
||||||
public:
|
public:
|
||||||
struct CharacterItemRecast {
|
struct CharacterItemRecast {
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
uint16_t recast_type;
|
uint32_t recast_type;
|
||||||
uint32_t timestamp;
|
uint32_t timestamp;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -112,8 +113,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
character_item_recast_id
|
character_item_recast_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -123,7 +125,7 @@ public:
|
|||||||
CharacterItemRecast e{};
|
CharacterItemRecast e{};
|
||||||
|
|
||||||
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||||
e.recast_type = static_cast<uint16_t>(strtoul(row[1], nullptr, 10));
|
e.recast_type = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
|
||||||
e.timestamp = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
e.timestamp = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
@@ -251,7 +253,7 @@ public:
|
|||||||
CharacterItemRecast e{};
|
CharacterItemRecast e{};
|
||||||
|
|
||||||
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||||
e.recast_type = static_cast<uint16_t>(strtoul(row[1], nullptr, 10));
|
e.recast_type = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
|
||||||
e.timestamp = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
e.timestamp = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
@@ -278,7 +280,7 @@ public:
|
|||||||
CharacterItemRecast e{};
|
CharacterItemRecast e{};
|
||||||
|
|
||||||
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
e.id = static_cast<uint32_t>(strtoul(row[0], nullptr, 10));
|
||||||
e.recast_type = static_cast<uint16_t>(strtoul(row[1], nullptr, 10));
|
e.recast_type = static_cast<uint32_t>(strtoul(row[1], nullptr, 10));
|
||||||
e.timestamp = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
e.timestamp = static_cast<uint32_t>(strtoul(row[2], nullptr, 10));
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
@@ -338,6 +340,66 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterItemRecast &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.recast_type));
|
||||||
|
v.push_back(std::to_string(e.timestamp));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterItemRecast> &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.recast_type));
|
||||||
|
v.push_back(std::to_string(e.timestamp));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_CHARACTER_ITEM_RECAST_REPOSITORY_H
|
#endif //EQEMU_BASE_CHARACTER_ITEM_RECAST_REPOSITORY_H
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_CHARACTER_LEADERSHIP_ABILITIES_REPOSITORY_H
|
#ifndef EQEMU_BASE_CHARACTER_LEADERSHIP_ABILITIES_REPOSITORY_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseCharacterLeadershipAbilitiesRepository {
|
class BaseCharacterLeadershipAbilitiesRepository {
|
||||||
public:
|
public:
|
||||||
struct CharacterLeadershipAbilities {
|
struct CharacterLeadershipAbilities {
|
||||||
@@ -112,8 +113,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
character_leadership_abilities_id
|
character_leadership_abilities_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -338,6 +340,66 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterLeadershipAbilities &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.slot));
|
||||||
|
v.push_back(std::to_string(e.rank));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterLeadershipAbilities> &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.slot));
|
||||||
|
v.push_back(std::to_string(e.rank));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_CHARACTER_LEADERSHIP_ABILITIES_REPOSITORY_H
|
#endif //EQEMU_BASE_CHARACTER_LEADERSHIP_ABILITIES_REPOSITORY_H
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_CHARACTER_MATERIAL_REPOSITORY_H
|
#ifndef EQEMU_BASE_CHARACTER_MATERIAL_REPOSITORY_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseCharacterMaterialRepository {
|
class BaseCharacterMaterialRepository {
|
||||||
public:
|
public:
|
||||||
struct CharacterMaterial {
|
struct CharacterMaterial {
|
||||||
@@ -128,8 +129,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
character_material_id
|
character_material_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -377,6 +379,74 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterMaterial &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.slot));
|
||||||
|
v.push_back(std::to_string(e.blue));
|
||||||
|
v.push_back(std::to_string(e.green));
|
||||||
|
v.push_back(std::to_string(e.red));
|
||||||
|
v.push_back(std::to_string(e.use_tint));
|
||||||
|
v.push_back(std::to_string(e.color));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterMaterial> &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.slot));
|
||||||
|
v.push_back(std::to_string(e.blue));
|
||||||
|
v.push_back(std::to_string(e.green));
|
||||||
|
v.push_back(std::to_string(e.red));
|
||||||
|
v.push_back(std::to_string(e.use_tint));
|
||||||
|
v.push_back(std::to_string(e.color));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_CHARACTER_MATERIAL_REPOSITORY_H
|
#endif //EQEMU_BASE_CHARACTER_MATERIAL_REPOSITORY_H
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_CHARACTER_MEMMED_SPELLS_REPOSITORY_H
|
#ifndef EQEMU_BASE_CHARACTER_MEMMED_SPELLS_REPOSITORY_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseCharacterMemmedSpellsRepository {
|
class BaseCharacterMemmedSpellsRepository {
|
||||||
public:
|
public:
|
||||||
struct CharacterMemmedSpells {
|
struct CharacterMemmedSpells {
|
||||||
@@ -112,8 +113,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
character_memmed_spells_id
|
character_memmed_spells_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -338,6 +340,66 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterMemmedSpells &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.slot_id));
|
||||||
|
v.push_back(std::to_string(e.spell_id));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterMemmedSpells> &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.slot_id));
|
||||||
|
v.push_back(std::to_string(e.spell_id));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_CHARACTER_MEMMED_SPELLS_REPOSITORY_H
|
#endif //EQEMU_BASE_CHARACTER_MEMMED_SPELLS_REPOSITORY_H
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_CHARACTER_PET_BUFFS_REPOSITORY_H
|
#ifndef EQEMU_BASE_CHARACTER_PET_BUFFS_REPOSITORY_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseCharacterPetBuffsRepository {
|
class BaseCharacterPetBuffsRepository {
|
||||||
public:
|
public:
|
||||||
struct CharacterPetBuffs {
|
struct CharacterPetBuffs {
|
||||||
@@ -144,8 +145,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
character_pet_buffs_id
|
character_pet_buffs_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -418,6 +420,82 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterPetBuffs &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.char_id));
|
||||||
|
v.push_back(std::to_string(e.pet));
|
||||||
|
v.push_back(std::to_string(e.slot));
|
||||||
|
v.push_back(std::to_string(e.spell_id));
|
||||||
|
v.push_back(std::to_string(e.caster_level));
|
||||||
|
v.push_back("'" + Strings::Escape(e.castername) + "'");
|
||||||
|
v.push_back(std::to_string(e.ticsremaining));
|
||||||
|
v.push_back(std::to_string(e.counters));
|
||||||
|
v.push_back(std::to_string(e.numhits));
|
||||||
|
v.push_back(std::to_string(e.rune));
|
||||||
|
v.push_back(std::to_string(e.instrument_mod));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterPetBuffs> &entries
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> insert_chunks;
|
||||||
|
|
||||||
|
for (auto &e: entries) {
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.char_id));
|
||||||
|
v.push_back(std::to_string(e.pet));
|
||||||
|
v.push_back(std::to_string(e.slot));
|
||||||
|
v.push_back(std::to_string(e.spell_id));
|
||||||
|
v.push_back(std::to_string(e.caster_level));
|
||||||
|
v.push_back("'" + Strings::Escape(e.castername) + "'");
|
||||||
|
v.push_back(std::to_string(e.ticsremaining));
|
||||||
|
v.push_back(std::to_string(e.counters));
|
||||||
|
v.push_back(std::to_string(e.numhits));
|
||||||
|
v.push_back(std::to_string(e.rune));
|
||||||
|
v.push_back(std::to_string(e.instrument_mod));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_CHARACTER_PET_BUFFS_REPOSITORY_H
|
#endif //EQEMU_BASE_CHARACTER_PET_BUFFS_REPOSITORY_H
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_CHARACTER_PET_INFO_REPOSITORY_H
|
#ifndef EQEMU_BASE_CHARACTER_PET_INFO_REPOSITORY_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseCharacterPetInfoRepository {
|
class BaseCharacterPetInfoRepository {
|
||||||
public:
|
public:
|
||||||
struct CharacterPetInfo {
|
struct CharacterPetInfo {
|
||||||
@@ -136,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(),
|
||||||
character_pet_info_id
|
character_pet_info_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -398,6 +400,78 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterPetInfo &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.char_id));
|
||||||
|
v.push_back(std::to_string(e.pet));
|
||||||
|
v.push_back("'" + Strings::Escape(e.petname) + "'");
|
||||||
|
v.push_back(std::to_string(e.petpower));
|
||||||
|
v.push_back(std::to_string(e.spell_id));
|
||||||
|
v.push_back(std::to_string(e.hp));
|
||||||
|
v.push_back(std::to_string(e.mana));
|
||||||
|
v.push_back(std::to_string(e.size));
|
||||||
|
v.push_back(std::to_string(e.taunting));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterPetInfo> &entries
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> insert_chunks;
|
||||||
|
|
||||||
|
for (auto &e: entries) {
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.char_id));
|
||||||
|
v.push_back(std::to_string(e.pet));
|
||||||
|
v.push_back("'" + Strings::Escape(e.petname) + "'");
|
||||||
|
v.push_back(std::to_string(e.petpower));
|
||||||
|
v.push_back(std::to_string(e.spell_id));
|
||||||
|
v.push_back(std::to_string(e.hp));
|
||||||
|
v.push_back(std::to_string(e.mana));
|
||||||
|
v.push_back(std::to_string(e.size));
|
||||||
|
v.push_back(std::to_string(e.taunting));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_CHARACTER_PET_INFO_REPOSITORY_H
|
#endif //EQEMU_BASE_CHARACTER_PET_INFO_REPOSITORY_H
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_CHARACTER_PET_INVENTORY_REPOSITORY_H
|
#ifndef EQEMU_BASE_CHARACTER_PET_INVENTORY_REPOSITORY_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseCharacterPetInventoryRepository {
|
class BaseCharacterPetInventoryRepository {
|
||||||
public:
|
public:
|
||||||
struct CharacterPetInventory {
|
struct CharacterPetInventory {
|
||||||
@@ -116,8 +117,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
character_pet_inventory_id
|
character_pet_inventory_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -348,6 +350,68 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterPetInventory &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.char_id));
|
||||||
|
v.push_back(std::to_string(e.pet));
|
||||||
|
v.push_back(std::to_string(e.slot));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterPetInventory> &entries
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> insert_chunks;
|
||||||
|
|
||||||
|
for (auto &e: entries) {
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.char_id));
|
||||||
|
v.push_back(std::to_string(e.pet));
|
||||||
|
v.push_back(std::to_string(e.slot));
|
||||||
|
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 {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_CHARACTER_PET_INVENTORY_REPOSITORY_H
|
#endif //EQEMU_BASE_CHARACTER_PET_INVENTORY_REPOSITORY_H
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_CHARACTER_POTIONBELT_REPOSITORY_H
|
#ifndef EQEMU_BASE_CHARACTER_POTIONBELT_REPOSITORY_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseCharacterPotionbeltRepository {
|
class BaseCharacterPotionbeltRepository {
|
||||||
public:
|
public:
|
||||||
struct CharacterPotionbelt {
|
struct CharacterPotionbelt {
|
||||||
@@ -116,8 +117,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
character_potionbelt_id
|
character_potionbelt_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -348,6 +350,68 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterPotionbelt &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.potion_id));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
v.push_back(std::to_string(e.icon));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterPotionbelt> &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.potion_id));
|
||||||
|
v.push_back(std::to_string(e.item_id));
|
||||||
|
v.push_back(std::to_string(e.icon));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_CHARACTER_POTIONBELT_REPOSITORY_H
|
#endif //EQEMU_BASE_CHARACTER_POTIONBELT_REPOSITORY_H
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_CHARACTER_SKILLS_REPOSITORY_H
|
#ifndef EQEMU_BASE_CHARACTER_SKILLS_REPOSITORY_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseCharacterSkillsRepository {
|
class BaseCharacterSkillsRepository {
|
||||||
public:
|
public:
|
||||||
struct CharacterSkills {
|
struct CharacterSkills {
|
||||||
@@ -112,8 +113,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
character_skills_id
|
character_skills_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -337,6 +339,66 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterSkills &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.skill_id));
|
||||||
|
v.push_back(std::to_string(e.value));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterSkills> &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.skill_id));
|
||||||
|
v.push_back(std::to_string(e.value));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_CHARACTER_SKILLS_REPOSITORY_H
|
#endif //EQEMU_BASE_CHARACTER_SKILLS_REPOSITORY_H
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_CHARACTER_SPELLS_REPOSITORY_H
|
#ifndef EQEMU_BASE_CHARACTER_SPELLS_REPOSITORY_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseCharacterSpellsRepository {
|
class BaseCharacterSpellsRepository {
|
||||||
public:
|
public:
|
||||||
struct CharacterSpells {
|
struct CharacterSpells {
|
||||||
@@ -112,8 +113,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
character_spells_id
|
character_spells_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -337,6 +339,66 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const CharacterSpells &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.slot_id));
|
||||||
|
v.push_back(std::to_string(e.spell_id));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<CharacterSpells> &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.slot_id));
|
||||||
|
v.push_back(std::to_string(e.spell_id));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_CHARACTER_SPELLS_REPOSITORY_H
|
#endif //EQEMU_BASE_CHARACTER_SPELLS_REPOSITORY_H
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_LOGSYS_CATEGORIES_REPOSITORY_H
|
#ifndef EQEMU_BASE_LOGSYS_CATEGORIES_REPOSITORY_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseLogsysCategoriesRepository {
|
class BaseLogsysCategoriesRepository {
|
||||||
public:
|
public:
|
||||||
struct LogsysCategories {
|
struct LogsysCategories {
|
||||||
@@ -128,8 +129,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
logsys_categories_id
|
logsys_categories_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -378,6 +380,74 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const LogsysCategories &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.log_category_id));
|
||||||
|
v.push_back("'" + Strings::Escape(e.log_category_description) + "'");
|
||||||
|
v.push_back(std::to_string(e.log_to_console));
|
||||||
|
v.push_back(std::to_string(e.log_to_file));
|
||||||
|
v.push_back(std::to_string(e.log_to_gmsay));
|
||||||
|
v.push_back(std::to_string(e.log_to_discord));
|
||||||
|
v.push_back(std::to_string(e.discord_webhook_id));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<LogsysCategories> &entries
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> insert_chunks;
|
||||||
|
|
||||||
|
for (auto &e: entries) {
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.log_category_id));
|
||||||
|
v.push_back("'" + Strings::Escape(e.log_category_description) + "'");
|
||||||
|
v.push_back(std::to_string(e.log_to_console));
|
||||||
|
v.push_back(std::to_string(e.log_to_file));
|
||||||
|
v.push_back(std::to_string(e.log_to_gmsay));
|
||||||
|
v.push_back(std::to_string(e.log_to_discord));
|
||||||
|
v.push_back(std::to_string(e.discord_webhook_id));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_LOGSYS_CATEGORIES_REPOSITORY_H
|
#endif //EQEMU_BASE_LOGSYS_CATEGORIES_REPOSITORY_H
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_PLAYER_EVENT_LOG_SETTINGS_REPOSITORY_H
|
#ifndef EQEMU_BASE_PLAYER_EVENT_LOG_SETTINGS_REPOSITORY_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BasePlayerEventLogSettingsRepository {
|
class BasePlayerEventLogSettingsRepository {
|
||||||
public:
|
public:
|
||||||
struct PlayerEventLogSettings {
|
struct PlayerEventLogSettings {
|
||||||
@@ -359,6 +360,70 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const PlayerEventLogSettings &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back("'" + Strings::Escape(e.event_name) + "'");
|
||||||
|
v.push_back(std::to_string(e.event_enabled));
|
||||||
|
v.push_back(std::to_string(e.retention_days));
|
||||||
|
v.push_back(std::to_string(e.discord_webhook_id));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<PlayerEventLogSettings> &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("'" + Strings::Escape(e.event_name) + "'");
|
||||||
|
v.push_back(std::to_string(e.event_enabled));
|
||||||
|
v.push_back(std::to_string(e.retention_days));
|
||||||
|
v.push_back(std::to_string(e.discord_webhook_id));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_PLAYER_EVENT_LOG_SETTINGS_REPOSITORY_H
|
#endif //EQEMU_BASE_PLAYER_EVENT_LOG_SETTINGS_REPOSITORY_H
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_PLAYER_EVENT_LOGS_REPOSITORY_H
|
#ifndef EQEMU_BASE_PLAYER_EVENT_LOGS_REPOSITORY_H
|
||||||
@@ -240,8 +240,8 @@ public:
|
|||||||
v.push_back(columns[7] + " = " + std::to_string(e.z));
|
v.push_back(columns[7] + " = " + std::to_string(e.z));
|
||||||
v.push_back(columns[8] + " = " + std::to_string(e.heading));
|
v.push_back(columns[8] + " = " + std::to_string(e.heading));
|
||||||
v.push_back(columns[9] + " = " + std::to_string(e.event_type_id));
|
v.push_back(columns[9] + " = " + std::to_string(e.event_type_id));
|
||||||
v.push_back(columns[10] + " = '" + db.Escape(e.event_type_name) + "'");
|
v.push_back(columns[10] + " = '" + Strings::Escape(e.event_type_name) + "'");
|
||||||
v.push_back(columns[11] + " = '" + db.Escape(e.event_data) + "'");
|
v.push_back(columns[11] + " = '" + Strings::Escape(e.event_data) + "'");
|
||||||
v.push_back(columns[12] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
|
v.push_back(columns[12] + " = FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
@@ -274,8 +274,8 @@ public:
|
|||||||
v.push_back(std::to_string(e.z));
|
v.push_back(std::to_string(e.z));
|
||||||
v.push_back(std::to_string(e.heading));
|
v.push_back(std::to_string(e.heading));
|
||||||
v.push_back(std::to_string(e.event_type_id));
|
v.push_back(std::to_string(e.event_type_id));
|
||||||
v.push_back("'" + db.Escape(e.event_type_name) + "'");
|
v.push_back("'" + Strings::Escape(e.event_type_name) + "'");
|
||||||
v.push_back("'" + db.Escape(e.event_data) + "'");
|
v.push_back("'" + Strings::Escape(e.event_data) + "'");
|
||||||
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
|
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
@@ -316,8 +316,8 @@ public:
|
|||||||
v.push_back(std::to_string(e.z));
|
v.push_back(std::to_string(e.z));
|
||||||
v.push_back(std::to_string(e.heading));
|
v.push_back(std::to_string(e.heading));
|
||||||
v.push_back(std::to_string(e.event_type_id));
|
v.push_back(std::to_string(e.event_type_id));
|
||||||
v.push_back("'" + db.Escape(e.event_type_name) + "'");
|
v.push_back("'" + Strings::Escape(e.event_type_name) + "'");
|
||||||
v.push_back("'" + db.Escape(e.event_data) + "'");
|
v.push_back("'" + Strings::Escape(e.event_data) + "'");
|
||||||
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
|
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
@@ -460,6 +460,86 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const PlayerEventLogs &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.account_id));
|
||||||
|
v.push_back(std::to_string(e.character_id));
|
||||||
|
v.push_back(std::to_string(e.zone_id));
|
||||||
|
v.push_back(std::to_string(e.instance_id));
|
||||||
|
v.push_back(std::to_string(e.x));
|
||||||
|
v.push_back(std::to_string(e.y));
|
||||||
|
v.push_back(std::to_string(e.z));
|
||||||
|
v.push_back(std::to_string(e.heading));
|
||||||
|
v.push_back(std::to_string(e.event_type_id));
|
||||||
|
v.push_back("'" + Strings::Escape(e.event_type_name) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.event_data) + "'");
|
||||||
|
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<PlayerEventLogs> &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.account_id));
|
||||||
|
v.push_back(std::to_string(e.character_id));
|
||||||
|
v.push_back(std::to_string(e.zone_id));
|
||||||
|
v.push_back(std::to_string(e.instance_id));
|
||||||
|
v.push_back(std::to_string(e.x));
|
||||||
|
v.push_back(std::to_string(e.y));
|
||||||
|
v.push_back(std::to_string(e.z));
|
||||||
|
v.push_back(std::to_string(e.heading));
|
||||||
|
v.push_back(std::to_string(e.event_type_id));
|
||||||
|
v.push_back("'" + Strings::Escape(e.event_type_name) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.event_data) + "'");
|
||||||
|
v.push_back("FROM_UNIXTIME(" + (e.created_at > 0 ? std::to_string(e.created_at) : "null") + ")");
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_PLAYER_EVENT_LOGS_REPOSITORY_H
|
#endif //EQEMU_BASE_PLAYER_EVENT_LOGS_REPOSITORY_H
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* Any modifications to base repositories are to be made by the generator only
|
* Any modifications to base repositories are to be made by the generator only
|
||||||
*
|
*
|
||||||
* @generator ./utils/scripts/generators/repository-generator.pl
|
* @generator ./utils/scripts/generators/repository-generator.pl
|
||||||
* @docs https://eqemu.gitbook.io/server/in-development/developer-area/repositories
|
* @docs https://docs.eqemu.io/developer/repositories
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef EQEMU_BASE_TASKS_REPOSITORY_H
|
#ifndef EQEMU_BASE_TASKS_REPOSITORY_H
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
#include "../../strings.h"
|
#include "../../strings.h"
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
|
||||||
class BaseTasksRepository {
|
class BaseTasksRepository {
|
||||||
public:
|
public:
|
||||||
struct Tasks {
|
struct Tasks {
|
||||||
@@ -47,6 +48,7 @@ public:
|
|||||||
uint32_t dz_template_id;
|
uint32_t dz_template_id;
|
||||||
int32_t lock_activity_id;
|
int32_t lock_activity_id;
|
||||||
int32_t faction_amount;
|
int32_t faction_amount;
|
||||||
|
int16_t enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::string PrimaryKey()
|
static std::string PrimaryKey()
|
||||||
@@ -85,6 +87,7 @@ public:
|
|||||||
"dz_template_id",
|
"dz_template_id",
|
||||||
"lock_activity_id",
|
"lock_activity_id",
|
||||||
"faction_amount",
|
"faction_amount",
|
||||||
|
"enabled",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,6 +122,7 @@ public:
|
|||||||
"dz_template_id",
|
"dz_template_id",
|
||||||
"lock_activity_id",
|
"lock_activity_id",
|
||||||
"faction_amount",
|
"faction_amount",
|
||||||
|
"enabled",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,6 +191,7 @@ public:
|
|||||||
e.dz_template_id = 0;
|
e.dz_template_id = 0;
|
||||||
e.lock_activity_id = -1;
|
e.lock_activity_id = -1;
|
||||||
e.faction_amount = 0;
|
e.faction_amount = 0;
|
||||||
|
e.enabled = 1;
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -212,8 +217,9 @@ public:
|
|||||||
{
|
{
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} WHERE id = {} LIMIT 1",
|
"{} WHERE {} = {} LIMIT 1",
|
||||||
BaseSelect(),
|
BaseSelect(),
|
||||||
|
PrimaryKey(),
|
||||||
tasks_id
|
tasks_id
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -250,6 +256,7 @@ public:
|
|||||||
e.dz_template_id = static_cast<uint32_t>(strtoul(row[25], nullptr, 10));
|
e.dz_template_id = static_cast<uint32_t>(strtoul(row[25], nullptr, 10));
|
||||||
e.lock_activity_id = static_cast<int32_t>(atoi(row[26]));
|
e.lock_activity_id = static_cast<int32_t>(atoi(row[26]));
|
||||||
e.faction_amount = static_cast<int32_t>(atoi(row[27]));
|
e.faction_amount = static_cast<int32_t>(atoi(row[27]));
|
||||||
|
e.enabled = static_cast<int16_t>(atoi(row[28]));
|
||||||
|
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -311,6 +318,7 @@ public:
|
|||||||
v.push_back(columns[25] + " = " + std::to_string(e.dz_template_id));
|
v.push_back(columns[25] + " = " + std::to_string(e.dz_template_id));
|
||||||
v.push_back(columns[26] + " = " + std::to_string(e.lock_activity_id));
|
v.push_back(columns[26] + " = " + std::to_string(e.lock_activity_id));
|
||||||
v.push_back(columns[27] + " = " + std::to_string(e.faction_amount));
|
v.push_back(columns[27] + " = " + std::to_string(e.faction_amount));
|
||||||
|
v.push_back(columns[28] + " = " + std::to_string(e.enabled));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -360,6 +368,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.dz_template_id));
|
v.push_back(std::to_string(e.dz_template_id));
|
||||||
v.push_back(std::to_string(e.lock_activity_id));
|
v.push_back(std::to_string(e.lock_activity_id));
|
||||||
v.push_back(std::to_string(e.faction_amount));
|
v.push_back(std::to_string(e.faction_amount));
|
||||||
|
v.push_back(std::to_string(e.enabled));
|
||||||
|
|
||||||
auto results = db.QueryDatabase(
|
auto results = db.QueryDatabase(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -417,6 +426,7 @@ public:
|
|||||||
v.push_back(std::to_string(e.dz_template_id));
|
v.push_back(std::to_string(e.dz_template_id));
|
||||||
v.push_back(std::to_string(e.lock_activity_id));
|
v.push_back(std::to_string(e.lock_activity_id));
|
||||||
v.push_back(std::to_string(e.faction_amount));
|
v.push_back(std::to_string(e.faction_amount));
|
||||||
|
v.push_back(std::to_string(e.enabled));
|
||||||
|
|
||||||
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
}
|
}
|
||||||
@@ -478,6 +488,7 @@ public:
|
|||||||
e.dz_template_id = static_cast<uint32_t>(strtoul(row[25], nullptr, 10));
|
e.dz_template_id = static_cast<uint32_t>(strtoul(row[25], nullptr, 10));
|
||||||
e.lock_activity_id = static_cast<int32_t>(atoi(row[26]));
|
e.lock_activity_id = static_cast<int32_t>(atoi(row[26]));
|
||||||
e.faction_amount = static_cast<int32_t>(atoi(row[27]));
|
e.faction_amount = static_cast<int32_t>(atoi(row[27]));
|
||||||
|
e.enabled = static_cast<int16_t>(atoi(row[28]));
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -530,6 +541,7 @@ public:
|
|||||||
e.dz_template_id = static_cast<uint32_t>(strtoul(row[25], nullptr, 10));
|
e.dz_template_id = static_cast<uint32_t>(strtoul(row[25], nullptr, 10));
|
||||||
e.lock_activity_id = static_cast<int32_t>(atoi(row[26]));
|
e.lock_activity_id = static_cast<int32_t>(atoi(row[26]));
|
||||||
e.faction_amount = static_cast<int32_t>(atoi(row[27]));
|
e.faction_amount = static_cast<int32_t>(atoi(row[27]));
|
||||||
|
e.enabled = static_cast<int16_t>(atoi(row[28]));
|
||||||
|
|
||||||
all_entries.push_back(e);
|
all_entries.push_back(e);
|
||||||
}
|
}
|
||||||
@@ -588,6 +600,118 @@ public:
|
|||||||
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
return (results.Success() && results.begin()[0] ? strtoll(results.begin()[0], nullptr, 10) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string BaseReplace()
|
||||||
|
{
|
||||||
|
return fmt::format(
|
||||||
|
"REPLACE INTO {} ({}) ",
|
||||||
|
TableName(),
|
||||||
|
ColumnsRaw()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceOne(
|
||||||
|
Database& db,
|
||||||
|
const Tasks &e
|
||||||
|
)
|
||||||
|
{
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
v.push_back(std::to_string(e.id));
|
||||||
|
v.push_back(std::to_string(e.type));
|
||||||
|
v.push_back(std::to_string(e.duration));
|
||||||
|
v.push_back(std::to_string(e.duration_code));
|
||||||
|
v.push_back("'" + Strings::Escape(e.title) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.description) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.reward_text) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.reward_id_list) + "'");
|
||||||
|
v.push_back(std::to_string(e.cash_reward));
|
||||||
|
v.push_back(std::to_string(e.exp_reward));
|
||||||
|
v.push_back(std::to_string(e.reward_method));
|
||||||
|
v.push_back(std::to_string(e.reward_points));
|
||||||
|
v.push_back(std::to_string(e.reward_point_type));
|
||||||
|
v.push_back(std::to_string(e.min_level));
|
||||||
|
v.push_back(std::to_string(e.max_level));
|
||||||
|
v.push_back(std::to_string(e.level_spread));
|
||||||
|
v.push_back(std::to_string(e.min_players));
|
||||||
|
v.push_back(std::to_string(e.max_players));
|
||||||
|
v.push_back(std::to_string(e.repeatable));
|
||||||
|
v.push_back(std::to_string(e.faction_reward));
|
||||||
|
v.push_back("'" + Strings::Escape(e.completion_emote) + "'");
|
||||||
|
v.push_back(std::to_string(e.replay_timer_group));
|
||||||
|
v.push_back(std::to_string(e.replay_timer_seconds));
|
||||||
|
v.push_back(std::to_string(e.request_timer_group));
|
||||||
|
v.push_back(std::to_string(e.request_timer_seconds));
|
||||||
|
v.push_back(std::to_string(e.dz_template_id));
|
||||||
|
v.push_back(std::to_string(e.lock_activity_id));
|
||||||
|
v.push_back(std::to_string(e.faction_amount));
|
||||||
|
v.push_back(std::to_string(e.enabled));
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES ({})",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", v)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ReplaceMany(
|
||||||
|
Database& db,
|
||||||
|
const std::vector<Tasks> &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.type));
|
||||||
|
v.push_back(std::to_string(e.duration));
|
||||||
|
v.push_back(std::to_string(e.duration_code));
|
||||||
|
v.push_back("'" + Strings::Escape(e.title) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.description) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.reward_text) + "'");
|
||||||
|
v.push_back("'" + Strings::Escape(e.reward_id_list) + "'");
|
||||||
|
v.push_back(std::to_string(e.cash_reward));
|
||||||
|
v.push_back(std::to_string(e.exp_reward));
|
||||||
|
v.push_back(std::to_string(e.reward_method));
|
||||||
|
v.push_back(std::to_string(e.reward_points));
|
||||||
|
v.push_back(std::to_string(e.reward_point_type));
|
||||||
|
v.push_back(std::to_string(e.min_level));
|
||||||
|
v.push_back(std::to_string(e.max_level));
|
||||||
|
v.push_back(std::to_string(e.level_spread));
|
||||||
|
v.push_back(std::to_string(e.min_players));
|
||||||
|
v.push_back(std::to_string(e.max_players));
|
||||||
|
v.push_back(std::to_string(e.repeatable));
|
||||||
|
v.push_back(std::to_string(e.faction_reward));
|
||||||
|
v.push_back("'" + Strings::Escape(e.completion_emote) + "'");
|
||||||
|
v.push_back(std::to_string(e.replay_timer_group));
|
||||||
|
v.push_back(std::to_string(e.replay_timer_seconds));
|
||||||
|
v.push_back(std::to_string(e.request_timer_group));
|
||||||
|
v.push_back(std::to_string(e.request_timer_seconds));
|
||||||
|
v.push_back(std::to_string(e.dz_template_id));
|
||||||
|
v.push_back(std::to_string(e.lock_activity_id));
|
||||||
|
v.push_back(std::to_string(e.faction_amount));
|
||||||
|
v.push_back(std::to_string(e.enabled));
|
||||||
|
|
||||||
|
insert_chunks.push_back("(" + Strings::Implode(",", v) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> v;
|
||||||
|
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"{} VALUES {}",
|
||||||
|
BaseReplace(),
|
||||||
|
Strings::Implode(",", insert_chunks)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (results.Success() ? results.RowsAffected() : 0);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_BASE_TASKS_REPOSITORY_H
|
#endif //EQEMU_BASE_TASKS_REPOSITORY_H
|
||||||
|
|||||||
@@ -46,6 +46,24 @@ public:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Custom extended repository methods here
|
// Custom extended repository methods here
|
||||||
|
static uint32 GetSecondsSinceLastLogin(Database &db, const std::string& name)
|
||||||
|
{
|
||||||
|
auto results = db.QueryDatabase(
|
||||||
|
fmt::format(
|
||||||
|
"SELECT (UNIX_TIMESTAMP(NOW()) - last_login) FROM {} WHERE name = '{}'",
|
||||||
|
TableName(),
|
||||||
|
Strings::Escape(name)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!results.RowCount() || !results.Success()) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto row = results.begin();
|
||||||
|
|
||||||
|
return Strings::ToUnsignedInt(row[0]);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //EQEMU_CHARACTER_DATA_REPOSITORY_H
|
#endif //EQEMU_CHARACTER_DATA_REPOSITORY_H
|
||||||
|
|||||||
@@ -216,6 +216,9 @@ RULE_BOOL(Character, EnableRaidMemberEXPModifier, true, "Enable or disable the r
|
|||||||
RULE_BOOL(Character, LeaveCursorMoneyOnCorpse, false, "Enable or disable leaving cursor money on player corpses")
|
RULE_BOOL(Character, LeaveCursorMoneyOnCorpse, false, "Enable or disable leaving cursor money on player corpses")
|
||||||
RULE_BOOL(Character, ItemExtraSkillDamageCalcAsPercent, false, "If enabled, apply Item Extra Skill Damage as Percentage-based modifiers")
|
RULE_BOOL(Character, ItemExtraSkillDamageCalcAsPercent, false, "If enabled, apply Item Extra Skill Damage as Percentage-based modifiers")
|
||||||
RULE_BOOL(Character, UseForageCommonFood, true, "If enabled, use the common foods specified in the code.")
|
RULE_BOOL(Character, UseForageCommonFood, true, "If enabled, use the common foods specified in the code.")
|
||||||
|
RULE_INT(Character, ClearXTargetDelay, 10, "Seconds between uses of the #clearxtargets command (Set to 0 to disable)")
|
||||||
|
RULE_BOOL(Character, PreventMountsFromZoning, false, "Enable to prevent mounts from zoning - Prior to December 15, 2004 this is enabled.")
|
||||||
|
RULE_BOOL(Character, GroupInvitesRequireTarget, false, "Enable to require players to have invitee on target (Disables /invite name) - Classic Style")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Mercs)
|
RULE_CATEGORY(Mercs)
|
||||||
@@ -251,6 +254,7 @@ RULE_BOOL(Skills, TrainSenseHeading, false, "Switch whether SenseHeading is trai
|
|||||||
RULE_INT(Skills, SenseHeadingStartValue, 200, "Start value of sense heading skill")
|
RULE_INT(Skills, SenseHeadingStartValue, 200, "Start value of sense heading skill")
|
||||||
RULE_BOOL(Skills, SelfLanguageLearning, true, "Enabling self-learning of languages")
|
RULE_BOOL(Skills, SelfLanguageLearning, true, "Enabling self-learning of languages")
|
||||||
RULE_BOOL(Skills, RequireTomeHandin, false, "Disable click-to-learn and force hand in to Guild Master")
|
RULE_BOOL(Skills, RequireTomeHandin, false, "Disable click-to-learn and force hand in to Guild Master")
|
||||||
|
RULE_INT(Skills, TradeSkillClamp, 0, "Legacy tradeskills would clamp at 252 regardless of item modifiers and skill combination. DEFAULT: 0 will bypass clamp. Legacy value 252")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Pets)
|
RULE_CATEGORY(Pets)
|
||||||
@@ -430,6 +434,10 @@ RULE_BOOL(Spells, AlwaysSendTargetsBuffs, false, "Ignore Leadership Alternate Ab
|
|||||||
RULE_BOOL(Spells, FlatItemExtraSpellAmt, false, "Allow SpellDmg stat to affect all spells, regardless of cast time/cooldown/etc")
|
RULE_BOOL(Spells, FlatItemExtraSpellAmt, false, "Allow SpellDmg stat to affect all spells, regardless of cast time/cooldown/etc")
|
||||||
RULE_BOOL(Spells, IgnoreSpellDmgLvlRestriction, false, "Ignore the 5 level spread on applying SpellDmg")
|
RULE_BOOL(Spells, IgnoreSpellDmgLvlRestriction, false, "Ignore the 5 level spread on applying SpellDmg")
|
||||||
RULE_BOOL(Spells, ItemExtraSpellAmtCalcAsPercent, false, "Apply the Item stats Spell Dmg and Heal Amount as Percentage-based modifiers instead of flat additions")
|
RULE_BOOL(Spells, ItemExtraSpellAmtCalcAsPercent, false, "Apply the Item stats Spell Dmg and Heal Amount as Percentage-based modifiers instead of flat additions")
|
||||||
|
RULE_REAL(Spells, BreakFeignDeathWhenCastOn, 2.0, "Percentage that Feign Death will break when you resist a spell")
|
||||||
|
RULE_REAL(Spells, BreakSneakWhenCastOn, 2.0, "Percentage that Sneak will break when you resist a spell")
|
||||||
|
RULE_BOOL(Spells, EnableResistSoftCap, false, "Enabled resist softcap and can be adjusted by rule, SpellResistSoftCap")
|
||||||
|
RULE_INT(Spells, SpellResistSoftCap, 255, "Softcap for spell resists.")
|
||||||
RULE_BOOL(Spells, AllowItemTGB, false, "Target group buff (/tgb) doesn't work with items on live, custom servers want it though")
|
RULE_BOOL(Spells, AllowItemTGB, false, "Target group buff (/tgb) doesn't work with items on live, custom servers want it though")
|
||||||
RULE_BOOL(Spells, NPCInnateProcOverride, true, "NPC innate procs override the target type to single target")
|
RULE_BOOL(Spells, NPCInnateProcOverride, true, "NPC innate procs override the target type to single target")
|
||||||
RULE_BOOL(Spells, OldRainTargets, false, "Use old incorrectly implemented maximum targets for rains")
|
RULE_BOOL(Spells, OldRainTargets, false, "Use old incorrectly implemented maximum targets for rains")
|
||||||
@@ -462,6 +470,14 @@ RULE_INT(Spells, DefensiveProcPenaltyLevelGap, 6, "Defensive Proc Penalty Level
|
|||||||
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, 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_BOOL(Spells, HOTBonusHealingSplitOverDuration, true, "Disable to have Heal Over Time total bonus healing added to each tick instead of divided across duration")
|
||||||
|
RULE_BOOL(Spells, UseLegacyFizzleCode, false, "Enable will turn on the legacy fizzle code which is far stricter and more accurate to 2001/2002 testing.")
|
||||||
|
RULE_BOOL(Spells, LegacyManaburn, false, "Enable to have the legacy manaburn system from 2003 and earlier.")
|
||||||
|
RULE_INT(Spells, LegacyManaburnCap, 9492, "Adjusted the hard cap (Normal or Crit) for the Legacy Manaburn system. DEFAULT: 9492")
|
||||||
|
RULE_BOOL(Spells, EvacClearAggroInSameZone, false, "Enable to clear aggro on clients when evacing in same zone.")
|
||||||
|
RULE_BOOL(Spells, CharmAggroOverLevel, false, "Enabling this rule will cause Charm casts over level to show resisted and cause aggro. Early EQ style.")
|
||||||
|
RULE_BOOL(Spells, RequireMnemonicRetention, true, "Enabling will require spell slots 9-12 to have the appropriate Mnemonic Retention AA learned.")
|
||||||
|
RULE_BOOL(Spells, EvacClearCharmPet, false, "Enable to have evac in zone clear charm from charm pets and detach buffs.")
|
||||||
|
RULE_BOOL(Spells, ManaTapsRequireNPCMana, false, "Enabling will require target to have mana to tap. Default off as many npc's are caster class with 0 mana and need fixed.")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(Combat)
|
RULE_CATEGORY(Combat)
|
||||||
@@ -499,6 +515,7 @@ RULE_REAL(Combat, AvgDefProcsPerMinute, 2.0, "Average defense procs per minute")
|
|||||||
RULE_REAL(Combat, DefProcPerMinAgiContrib, 0.075, "How much agility contributes to defensive proc rate")
|
RULE_REAL(Combat, DefProcPerMinAgiContrib, 0.075, "How much agility contributes to defensive proc rate")
|
||||||
RULE_INT(Combat, NPCFlurryChance, 20, "Chance for NPC to flurry")
|
RULE_INT(Combat, NPCFlurryChance, 20, "Chance for NPC to flurry")
|
||||||
RULE_BOOL(Combat, TauntOverLevel, 1, "Allows you to taunt NPC's over warriors level")
|
RULE_BOOL(Combat, TauntOverLevel, 1, "Allows you to taunt NPC's over warriors level")
|
||||||
|
RULE_INT(Combat, TauntOverAggro, 0, "+ amount over hate_top it will add before any bonus hate.")
|
||||||
RULE_REAL(Combat, TauntSkillFalloff, 0.33, "For every taunt skill point that's not maxed you lose this percentage chance to taunt")
|
RULE_REAL(Combat, TauntSkillFalloff, 0.33, "For every taunt skill point that's not maxed you lose this percentage chance to taunt")
|
||||||
RULE_BOOL(Combat, EXPFromDmgShield, false, "Determine if damage from a damage shield counts for experience gain")
|
RULE_BOOL(Combat, EXPFromDmgShield, false, "Determine if damage from a damage shield counts for experience gain")
|
||||||
RULE_INT(Combat, QuiverHasteCap, 1000, "Quiver haste cap 1000 on live for a while, currently 700 on live")
|
RULE_INT(Combat, QuiverHasteCap, 1000, "Quiver haste cap 1000 on live for a while, currently 700 on live")
|
||||||
@@ -508,6 +525,9 @@ RULE_BOOL(Combat, OneProcPerWeapon, true, "If enabled, One proc per weapon per r
|
|||||||
RULE_BOOL(Combat, ProjectileDmgOnImpact, true, "If enabled, projectiles (i.e. arrows) will hit on impact, instead of instantly")
|
RULE_BOOL(Combat, ProjectileDmgOnImpact, true, "If enabled, projectiles (i.e. arrows) will hit on impact, instead of instantly")
|
||||||
RULE_BOOL(Combat, MeleePush, true, "Enable melee push")
|
RULE_BOOL(Combat, MeleePush, true, "Enable melee push")
|
||||||
RULE_INT(Combat, MeleePushChance, 50, "NPC chance the target will be pushed. Made up, 100 actually isn't that bad")
|
RULE_INT(Combat, MeleePushChance, 50, "NPC chance the target will be pushed. Made up, 100 actually isn't that bad")
|
||||||
|
RULE_REAL(Combat, MeleePushForceClientPercent, 0.00, "Percent to add or remove from push for players")
|
||||||
|
RULE_REAL(Combat, MeleePushForcePetPercent, 0.00, "Percent to add or remove from push for pets")
|
||||||
|
RULE_BOOL(Combat, NPCtoNPCPush, false, "Disabled prevents NPC to NPC pushing per the 2013+ patch.")
|
||||||
RULE_BOOL(Combat, UseLiveCombatRounds, true, "Turn this false if you don't want to worry about fixing up combat rounds for NPCs")
|
RULE_BOOL(Combat, UseLiveCombatRounds, true, "Turn this false if you don't want to worry about fixing up combat rounds for NPCs")
|
||||||
RULE_INT(Combat, NPCAssistCap, 5, "Maximum number of NPC that will assist another NPC at once")
|
RULE_INT(Combat, NPCAssistCap, 5, "Maximum number of NPC that will assist another NPC at once")
|
||||||
RULE_INT(Combat, NPCAssistCapTimer, 6000, "Time a NPC will take to clear assist aggro cap space (milliseconds)")
|
RULE_INT(Combat, NPCAssistCapTimer, 6000, "Time a NPC will take to clear assist aggro cap space (milliseconds)")
|
||||||
@@ -538,6 +558,13 @@ RULE_BOOL(Combat, SummonMeleeRange, true, "Enable or disable summoning of a play
|
|||||||
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, 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_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_BOOL(Combat, FinishingBlowOnlyWhenFleeing, false, "Enable to only allow Finishing Blow when fleeing (Original Style Finishing Blow)")
|
||||||
|
RULE_BOOL(Combat, ClassicTripleAttack, false, "enable to use non-skill based classic triple attack. Originally it was Warrior Only but was expanded, can use the TripleAttackChance to tune the classes out.")
|
||||||
|
RULE_INT(Combat, ClassicTripleAttackChanceWarrior, 100, "Innate Chance for Warrior to Triple Attack after a Double Attack (125 = 12.5%). DEFAULT: 100")
|
||||||
|
RULE_INT(Combat, ClassicTripleAttackChanceMonk, 100, "Innate Chance for Monk to Triple Attack after a Double Attack (200 = 20%). DEFAULT: 100")
|
||||||
|
RULE_INT(Combat, ClassicTripleAttackChanceBerserker, 100, "Innate Chance for Berserker to Triple Attack after a Double Attack (200 = 20%). DEFAULT: 100")
|
||||||
|
RULE_INT(Combat, ClassicTripleAttackChanceRanger, 100, "Innate Chance for Ranger to Triple Attack after a Double Attack (200 = 20%). DEFAULT: 100")
|
||||||
|
RULE_INT(Combat, StunChance, 12, "Percent chance that client will be stunned when mob is behind player. DEFAULT: 12")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(NPC)
|
RULE_CATEGORY(NPC)
|
||||||
@@ -563,6 +590,7 @@ RULE_INT(NPC, NPCToNPCAggroTimerMin, 500, "Minimum time span after which one NPC
|
|||||||
RULE_INT(NPC, NPCToNPCAggroTimerMax, 6000, "Maximum time span after which one NPC aggro another NPC (milliseconds)")
|
RULE_INT(NPC, NPCToNPCAggroTimerMax, 6000, "Maximum time span after which one NPC aggro another NPC (milliseconds)")
|
||||||
RULE_BOOL(NPC, UseClassAsLastName, true, "Uses class archetype as LastName for NPC with none")
|
RULE_BOOL(NPC, UseClassAsLastName, true, "Uses class archetype as LastName for NPC with none")
|
||||||
RULE_BOOL(NPC, NewLevelScaling, true, "Better level scaling, use old if new formulas would break your server")
|
RULE_BOOL(NPC, NewLevelScaling, true, "Better level scaling, use old if new formulas would break your server")
|
||||||
|
RULE_REAL(NPC,NPCBackstabMod, 1.9, "Multiplier for NPC Backstab, Higher = Lower backstab amount")
|
||||||
RULE_INT(NPC, NPCGatePercent, 20, " Percentage at which the NPC Will attempt to gate at")
|
RULE_INT(NPC, NPCGatePercent, 20, " Percentage at which the NPC Will attempt to gate at")
|
||||||
RULE_BOOL(NPC, NPCGateNearBind, false, "Will NPC attempt to gate when near bind location?")
|
RULE_BOOL(NPC, NPCGateNearBind, false, "Will NPC attempt to gate when near bind location?")
|
||||||
RULE_INT(NPC, NPCGateDistanceBind, 75, "Distance from bind before NPC will attempt to gate")
|
RULE_INT(NPC, NPCGateDistanceBind, 75, "Distance from bind before NPC will attempt to gate")
|
||||||
@@ -593,6 +621,7 @@ RULE_INT(Aggro, ClientAggroCheckIdleInterval, 6000, "Interval in which clients a
|
|||||||
RULE_REAL(Aggro, PetAttackRange, 40000.0, "Maximum squared range /pet attack works at default is 200")
|
RULE_REAL(Aggro, PetAttackRange, 40000.0, "Maximum squared range /pet attack works at default is 200")
|
||||||
RULE_BOOL(Aggro, NPCAggroMaxDistanceEnabled, true, "If enabled, NPC's will drop aggro beyond 600 units or what is defined at the zone level")
|
RULE_BOOL(Aggro, NPCAggroMaxDistanceEnabled, true, "If enabled, NPC's will drop aggro beyond 600 units or what is defined at the zone level")
|
||||||
RULE_BOOL(Aggro, AggroPlayerPets, false, "If enabled, NPCs will aggro player pets")
|
RULE_BOOL(Aggro, AggroPlayerPets, false, "If enabled, NPCs will aggro player pets")
|
||||||
|
RULE_BOOL(Aggro, UndeadAlwaysAggro, true, "should undead always aggro?")
|
||||||
RULE_CATEGORY_END()
|
RULE_CATEGORY_END()
|
||||||
|
|
||||||
RULE_CATEGORY(TaskSystem)
|
RULE_CATEGORY(TaskSystem)
|
||||||
|
|||||||
+34
-18
@@ -44,6 +44,7 @@
|
|||||||
#include "repositories/starting_items_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"
|
||||||
|
#include "repositories/character_item_recast_repository.h"
|
||||||
|
|
||||||
namespace ItemField
|
namespace ItemField
|
||||||
{
|
{
|
||||||
@@ -882,34 +883,49 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, EQ::InventoryPr
|
|||||||
std::map<uint32, uint32> SharedDatabase::GetItemRecastTimestamps(uint32 char_id)
|
std::map<uint32, uint32> SharedDatabase::GetItemRecastTimestamps(uint32 char_id)
|
||||||
{
|
{
|
||||||
std::map<uint32, uint32> timers;
|
std::map<uint32, uint32> timers;
|
||||||
const std::string query = StringFormat("SELECT recast_type,timestamp FROM character_item_recast WHERE id=%u", char_id);
|
|
||||||
auto results = QueryDatabase(query);
|
|
||||||
if (!results.Success() || results.RowCount() == 0)
|
|
||||||
return timers;
|
|
||||||
|
|
||||||
for (auto& row = results.begin(); row != results.end(); ++row)
|
const auto& l = CharacterItemRecastRepository::GetWhere(
|
||||||
timers[Strings::ToUnsignedInt(row[0])] = Strings::ToUnsignedInt(row[1]);
|
*this,
|
||||||
return timers; // RVO or move assigned
|
fmt::format(
|
||||||
|
"`id` = {}",
|
||||||
|
char_id
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (l.empty()) {
|
||||||
|
return timers;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& e : l) {
|
||||||
|
timers[e.recast_type] = e.timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return timers;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 SharedDatabase::GetItemRecastTimestamp(uint32 char_id, uint32 recast_type)
|
uint32 SharedDatabase::GetItemRecastTimestamp(uint32 char_id, uint32 recast_type)
|
||||||
{
|
{
|
||||||
const std::string query = StringFormat("SELECT timestamp FROM character_item_recast WHERE id=%u AND recast_type=%u",
|
const auto& l = CharacterItemRecastRepository::GetWhere(
|
||||||
char_id, recast_type);
|
*this,
|
||||||
auto results = QueryDatabase(query);
|
fmt::format(
|
||||||
if (!results.Success() || results.RowCount() == 0)
|
"`id` = {} AND `recast_type` = {}",
|
||||||
return 0;
|
char_id,
|
||||||
|
recast_type
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
auto& row = results.begin();
|
return l.empty() ? 0 : l[0].timestamp;
|
||||||
return Strings::ToUnsignedInt(row[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SharedDatabase::ClearOldRecastTimestamps(uint32 char_id)
|
void SharedDatabase::ClearOldRecastTimestamps(uint32 char_id)
|
||||||
{
|
{
|
||||||
// This actually isn't strictly live-like. Live your recast timestamps are forever
|
CharacterItemRecastRepository::DeleteWhere(
|
||||||
const std::string query =
|
*this,
|
||||||
StringFormat("DELETE FROM character_item_recast WHERE id = %u and timestamp < UNIX_TIMESTAMP()", char_id);
|
fmt::format(
|
||||||
QueryDatabase(query);
|
"`id` = {} AND `timestamp` < UNIX_TIMESTAMP()",
|
||||||
|
char_id
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SharedDatabase::GetItemsCount(int32 &item_count, uint32 &max_id)
|
void SharedDatabase::GetItemsCount(int32 &item_count, uint32 &max_id)
|
||||||
|
|||||||
@@ -202,6 +202,19 @@
|
|||||||
#define SPELL_GUIDE_LEVITATION 39852
|
#define SPELL_GUIDE_LEVITATION 39852
|
||||||
#define SPELL_GUIDE_SPELL_HASTE 39853
|
#define SPELL_GUIDE_SPELL_HASTE 39853
|
||||||
#define SPELL_GUIDE_HASTE 39854
|
#define SPELL_GUIDE_HASTE 39854
|
||||||
|
#define SPELL_VAMPIRIC_EMBRACE 821
|
||||||
|
#define SPELL_VAMPIRIC_EMBRACE_OF_SHADOW 822
|
||||||
|
#define SPELL_BATTLE_CRY 5027
|
||||||
|
#define SPELL_WAR_CRY 5028
|
||||||
|
#define SPELL_BATTLE_CRY_OF_DRAVEL 5029
|
||||||
|
#define SPELL_WAR_CRY_OF_DRAVEL 5030
|
||||||
|
#define SPELL_BATTLE_CRY_OF_THE_MASTRUQ 5031
|
||||||
|
#define SPELL_ANCIENT_CRY_OF_CHAOS 5032
|
||||||
|
#define SPELL_BLOODTHIRST 8476
|
||||||
|
#define SPELL_AMPLIFICATION 2603
|
||||||
|
|
||||||
|
// discipline IDs.
|
||||||
|
#define DISC_UNHOLY_AURA 4520
|
||||||
|
|
||||||
//spellgroup ids
|
//spellgroup ids
|
||||||
#define SPELLGROUP_FRENZIED_BURNOUT 2754
|
#define SPELLGROUP_FRENZIED_BURNOUT 2754
|
||||||
|
|||||||
+3
-1
@@ -359,9 +359,11 @@ namespace Tasks {
|
|||||||
if (activity_states[i].activity_state != ActivityCompleted)
|
if (activity_states[i].activity_state != ActivityCompleted)
|
||||||
{
|
{
|
||||||
completed_ids[i] = false;
|
completed_ids[i] = false;
|
||||||
current_step = std::min(current_step, el.step);
|
|
||||||
|
// step system advances to next step if only optionals active
|
||||||
if (!el.optional)
|
if (!el.optional)
|
||||||
{
|
{
|
||||||
|
current_step = std::min(current_step, el.step);
|
||||||
result.is_task_complete = false;
|
result.is_task_complete = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -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.38.0-dev" // always append -dev to the current version for custom-builds
|
#define CURRENT_VERSION "22.41.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,7 +42,7 @@
|
|||||||
* 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 9248
|
#define CURRENT_BINARY_DATABASE_VERSION 9249
|
||||||
|
|
||||||
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9041
|
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9041
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "eqemu-server",
|
"name": "eqemu-server",
|
||||||
"version": "22.38.0",
|
"version": "22.41.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/EQEmu/Server.git"
|
"url": "https://github.com/EQEmu/Server.git"
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errmsg.h>
|
|
||||||
#include <mysqld_error.h>
|
#include <mysqld_error.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -399,5 +398,6 @@ void QSDatabase::GeneralQueryReceive(ServerPacket *pack)
|
|||||||
LogInfo("[{}]", query.c_str());
|
LogInfo("[{}]", query.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
safe_delete(pack);
|
||||||
safe_delete_array(queryBuffer);
|
safe_delete_array(queryBuffer);
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-8
@@ -463,15 +463,17 @@ void TaskStateTest::TestOptionalSteps()
|
|||||||
// activity_id | step | state
|
// activity_id | step | state
|
||||||
// 0 | 0 | complete
|
// 0 | 0 | complete
|
||||||
// 1 | 1 | hidden | optional (active)
|
// 1 | 1 | hidden | optional (active)
|
||||||
// 2 | 2 | hidden | optional
|
// 2 | 2 | hidden | optional (active)
|
||||||
// 3 | 2 | hidden
|
// 3 | 2 | hidden (active)
|
||||||
|
|
||||||
auto res = Tasks::GetActiveElements(data, state, activity_count);
|
auto res = Tasks::GetActiveElements(data, state, activity_count);
|
||||||
|
|
||||||
// since optional is on its own step it's effectively non-optional to open next step
|
// steps that only contain optionals should not need to be completed to open next step
|
||||||
TEST_ASSERT(res.is_task_complete == false);
|
TEST_ASSERT(res.is_task_complete == false);
|
||||||
TEST_ASSERT(res.active.size() == 1);
|
TEST_ASSERT(res.active.size() == 3);
|
||||||
TEST_ASSERT(std::find(res.active.begin(), res.active.end(), 1) != res.active.end());
|
TEST_ASSERT(std::find(res.active.begin(), res.active.end(), 1) != res.active.end());
|
||||||
|
TEST_ASSERT(std::find(res.active.begin(), res.active.end(), 2) != res.active.end());
|
||||||
|
TEST_ASSERT(std::find(res.active.begin(), res.active.end(), 3) != res.active.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -530,9 +532,9 @@ void TaskStateTest::TestOptionalLastSteps()
|
|||||||
auto state = GetMockWorldState(activity_count);
|
auto state = GetMockWorldState(activity_count);
|
||||||
data[0].step = 0;
|
data[0].step = 0;
|
||||||
data[1].optional = true;
|
data[1].optional = true;
|
||||||
data[1].step = 2;
|
data[1].step = 1;
|
||||||
data[2].optional = true;
|
data[2].optional = true;
|
||||||
data[2].step = 3;
|
data[2].step = 2;
|
||||||
|
|
||||||
{
|
{
|
||||||
// activity_id | step | state
|
// activity_id | step | state
|
||||||
@@ -553,13 +555,15 @@ void TaskStateTest::TestOptionalLastSteps()
|
|||||||
// activity_id | step | state
|
// activity_id | step | state
|
||||||
// 0 | 0 | complete
|
// 0 | 0 | complete
|
||||||
// 1 | 1 | hidden | optional (active)
|
// 1 | 1 | hidden | optional (active)
|
||||||
// 2 | 2 | hidden | optional
|
// 2 | 2 | hidden | optional (active)
|
||||||
|
|
||||||
|
// step with only an optional should not prevent next step being active
|
||||||
auto res = Tasks::GetActiveElements(data, state, activity_count);
|
auto res = Tasks::GetActiveElements(data, state, activity_count);
|
||||||
|
|
||||||
TEST_ASSERT(res.is_task_complete == true);
|
TEST_ASSERT(res.is_task_complete == true);
|
||||||
TEST_ASSERT(res.active.size() == 1);
|
TEST_ASSERT(res.active.size() == 2);
|
||||||
TEST_ASSERT(std::find(res.active.begin(), res.active.end(), 1) != res.active.end());
|
TEST_ASSERT(std::find(res.active.begin(), res.active.end(), 1) != res.active.end());
|
||||||
|
TEST_ASSERT(std::find(res.active.begin(), res.active.end(), 2) != res.active.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errmsg.h>
|
|
||||||
#include <mysqld_error.h>
|
#include <mysqld_error.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|||||||
+1
-7
@@ -164,13 +164,7 @@ int main() {
|
|||||||
|
|
||||||
database.ExpireMail();
|
database.ExpireMail();
|
||||||
|
|
||||||
if(Config->ChatPort != Config->MailPort)
|
g_Clientlist = new Clientlist(Config->GetUCSPort());
|
||||||
{
|
|
||||||
LogInfo("MailPort and CharPort must be the same in eqemu_config.json for UCS");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_Clientlist = new Clientlist(Config->ChatPort);
|
|
||||||
|
|
||||||
ChannelList = new ChatChannelList();
|
ChannelList = new ChatChannelList();
|
||||||
|
|
||||||
|
|||||||
@@ -513,6 +513,13 @@ foreach my $table_to_generate (@tables) {
|
|||||||
#############################################
|
#############################################
|
||||||
if ($repository_generation_option eq "all" || $repository_generation_option eq "extended") {
|
if ($repository_generation_option eq "all" || $repository_generation_option eq "extended") {
|
||||||
my $generated_repository = './common/repositories/' . $table_to_generate . '_repository.h';
|
my $generated_repository = './common/repositories/' . $table_to_generate . '_repository.h';
|
||||||
|
|
||||||
|
# check if file exists firsts
|
||||||
|
if (-e $generated_repository) {
|
||||||
|
print "File [$generated_repository] already exists! Can't overwrite extended once created!\n";
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
my $cmake_generated_reference = $generated_repository;
|
my $cmake_generated_reference = $generated_repository;
|
||||||
$cmake_generated_reference =~ s/.\/common\///g;
|
$cmake_generated_reference =~ s/.\/common\///g;
|
||||||
$generated_repository_files .= $cmake_generated_reference . "\n";
|
$generated_repository_files .= $cmake_generated_reference . "\n";
|
||||||
|
|||||||
@@ -9,5 +9,7 @@ void WorldserverCLI::DatabaseUpdates(int argc, char **argv, argh::parser &cmd, s
|
|||||||
}
|
}
|
||||||
|
|
||||||
DatabaseUpdate update;
|
DatabaseUpdate update;
|
||||||
update.SetDatabase(&database)->CheckDbUpdates();
|
update.SetDatabase(&database)
|
||||||
|
->SetContentDatabase(&content_db)
|
||||||
|
->CheckDbUpdates();
|
||||||
}
|
}
|
||||||
|
|||||||
+78
-88
@@ -28,7 +28,6 @@
|
|||||||
#include "../common/inventory_profile.h"
|
#include "../common/inventory_profile.h"
|
||||||
#include "../common/races.h"
|
#include "../common/races.h"
|
||||||
#include "../common/classes.h"
|
#include "../common/classes.h"
|
||||||
#include "../common/languages.h"
|
|
||||||
#include "../common/skills.h"
|
#include "../common/skills.h"
|
||||||
#include "../common/extprofile.h"
|
#include "../common/extprofile.h"
|
||||||
#include "../common/strings.h"
|
#include "../common/strings.h"
|
||||||
@@ -945,8 +944,8 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buffer = fmt::format("{},{},{}.{},{}{:08X}",
|
buffer = fmt::format("{},{},{}.{},{}{:08X}",
|
||||||
config->ChatHost,
|
config->GetUCSHost(),
|
||||||
config->ChatPort,
|
config->GetUCSPort(),
|
||||||
config->ShortName,
|
config->ShortName,
|
||||||
GetCharName(),
|
GetCharName(),
|
||||||
static_cast<char>(connection_type),
|
static_cast<char>(connection_type),
|
||||||
@@ -971,8 +970,8 @@ bool Client::HandleEnterWorldPacket(const EQApplicationPacket *app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buffer = fmt::format("{},{},{}.{},{}{:08X}",
|
buffer = fmt::format("{},{},{}.{},{}{:08X}",
|
||||||
config->MailHost,
|
config->GetUCSHost(),
|
||||||
config->MailPort,
|
config->GetUCSPort(),
|
||||||
config->ShortName,
|
config->ShortName,
|
||||||
GetCharName(),
|
GetCharName(),
|
||||||
static_cast<char>(connection_type),
|
static_cast<char>(connection_type),
|
||||||
@@ -1692,15 +1691,16 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
|
|||||||
pp.hunger_level = 6000;
|
pp.hunger_level = 6000;
|
||||||
pp.thirst_level = 6000;
|
pp.thirst_level = 6000;
|
||||||
|
|
||||||
|
/* Set default skills for everybody */
|
||||||
|
pp.skills[EQ::skills::SkillSwimming] = RuleI(Skills, SwimmingStartValue);
|
||||||
|
pp.skills[EQ::skills::SkillSenseHeading] = RuleI(Skills, SenseHeadingStartValue);
|
||||||
|
|
||||||
/* Set Racial and Class specific language and skills */
|
/* Set Racial and Class specific language and skills */
|
||||||
SetRacialLanguages(&pp);
|
SetRacialLanguages(&pp);
|
||||||
SetRaceStartingSkills(&pp);
|
SetRaceStartingSkills(&pp);
|
||||||
SetClassStartingSkills(&pp);
|
SetClassStartingSkills(&pp);
|
||||||
SetClassLanguages(&pp);
|
SetClassLanguages(&pp);
|
||||||
|
|
||||||
pp.skills[EQ::skills::SkillSwimming] = RuleI(Skills, SwimmingStartValue);
|
|
||||||
pp.skills[EQ::skills::SkillSenseHeading] = RuleI(Skills, SenseHeadingStartValue);
|
|
||||||
|
|
||||||
// strcpy(pp.servername, WorldConfig::get()->ShortName.c_str());
|
// strcpy(pp.servername, WorldConfig::get()->ShortName.c_str());
|
||||||
|
|
||||||
memset(pp.spell_book, 0xFF, (sizeof(uint32) * EQ::spells::SPELLBOOK_SIZE));
|
memset(pp.spell_book, 0xFF, (sizeof(uint32) * EQ::spells::SPELLBOOK_SIZE));
|
||||||
@@ -2144,7 +2144,9 @@ void Client::SetRaceStartingSkills( PlayerProfile_Struct *pp )
|
|||||||
}
|
}
|
||||||
case FROGLOK:
|
case FROGLOK:
|
||||||
{
|
{
|
||||||
|
if (RuleI(Skills, SwimmingStartValue) < 125) {
|
||||||
pp->skills[EQ::skills::SkillSwimming] = 125;
|
pp->skills[EQ::skills::SkillSwimming] = 125;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GNOME:
|
case GNOME:
|
||||||
@@ -2161,7 +2163,9 @@ void Client::SetRaceStartingSkills( PlayerProfile_Struct *pp )
|
|||||||
case IKSAR:
|
case IKSAR:
|
||||||
{
|
{
|
||||||
pp->skills[EQ::skills::SkillForage] = 50;
|
pp->skills[EQ::skills::SkillForage] = 50;
|
||||||
|
if (RuleI(Skills, SwimmingStartValue) < 100) {
|
||||||
pp->skills[EQ::skills::SkillSwimming] = 100;
|
pp->skills[EQ::skills::SkillSwimming] = 100;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WOOD_ELF:
|
case WOOD_ELF:
|
||||||
@@ -2181,115 +2185,101 @@ void Client::SetRaceStartingSkills( PlayerProfile_Struct *pp )
|
|||||||
|
|
||||||
void Client::SetRacialLanguages( PlayerProfile_Struct *pp )
|
void Client::SetRacialLanguages( PlayerProfile_Struct *pp )
|
||||||
{
|
{
|
||||||
switch( pp->race )
|
switch (pp->race) {
|
||||||
{
|
case Race::Human: {
|
||||||
case BARBARIAN:
|
pp->languages[Language::CommonTongue] = Language::MaxValue;
|
||||||
{
|
|
||||||
pp->languages[LANG_COMMON_TONGUE] = 100;
|
|
||||||
pp->languages[LANG_BARBARIAN] = 100;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DARK_ELF:
|
case Race::Barbarian: {
|
||||||
{
|
pp->languages[Language::CommonTongue] = Language::MaxValue;
|
||||||
pp->languages[LANG_COMMON_TONGUE] = 100;
|
pp->languages[Language::Barbarian] = Language::MaxValue;
|
||||||
pp->languages[LANG_DARK_ELVISH] = 100;
|
|
||||||
pp->languages[LANG_DARK_SPEECH] = 100;
|
|
||||||
pp->languages[LANG_ELDER_ELVISH] = 100;
|
|
||||||
pp->languages[LANG_ELVISH] = 25;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DWARF:
|
case Race::Erudite: {
|
||||||
{
|
pp->languages[Language::CommonTongue] = Language::MaxValue;
|
||||||
pp->languages[LANG_COMMON_TONGUE] = 100;
|
pp->languages[Language::Erudian] = Language::MaxValue;
|
||||||
pp->languages[LANG_DWARVISH] = 100;
|
|
||||||
pp->languages[LANG_GNOMISH] = 25;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ERUDITE:
|
case Race::WoodElf: {
|
||||||
{
|
pp->languages[Language::CommonTongue] = Language::MaxValue;
|
||||||
pp->languages[LANG_COMMON_TONGUE] = 100;
|
pp->languages[Language::Elvish] = Language::MaxValue;
|
||||||
pp->languages[LANG_ERUDIAN] = 100;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FROGLOK:
|
case Race::HighElf: {
|
||||||
{
|
pp->languages[Language::CommonTongue] = Language::MaxValue;
|
||||||
pp->languages[LANG_COMMON_TONGUE] = 100;
|
pp->languages[Language::DarkElvish] = 25;
|
||||||
pp->languages[LANG_FROGLOK] = 100;
|
pp->languages[Language::ElderElvish] = 25;
|
||||||
pp->languages[LANG_TROLL] = 25;
|
pp->languages[Language::Elvish] = Language::MaxValue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case GNOME:
|
case Race::DarkElf: {
|
||||||
{
|
pp->languages[Language::CommonTongue] = Language::MaxValue;
|
||||||
pp->languages[LANG_COMMON_TONGUE] = 100;
|
pp->languages[Language::DarkElvish] = Language::MaxValue;
|
||||||
pp->languages[LANG_DWARVISH] = 25;
|
pp->languages[Language::DarkSpeech] = Language::MaxValue;
|
||||||
pp->languages[LANG_GNOMISH] = 100;
|
pp->languages[Language::ElderElvish] = Language::MaxValue;
|
||||||
|
pp->languages[Language::Elvish] = 25;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case HALF_ELF:
|
case Race::HalfElf: {
|
||||||
{
|
pp->languages[Language::CommonTongue] = Language::MaxValue;
|
||||||
pp->languages[LANG_COMMON_TONGUE] = 100;
|
pp->languages[Language::Elvish] = Language::MaxValue;
|
||||||
pp->languages[LANG_ELVISH] = 100;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case HALFLING:
|
case Race::Dwarf: {
|
||||||
{
|
pp->languages[Language::CommonTongue] = Language::MaxValue;
|
||||||
pp->languages[LANG_COMMON_TONGUE] = 100;
|
pp->languages[Language::Dwarvish] = Language::MaxValue;
|
||||||
pp->languages[LANG_HALFLING] = 100;
|
pp->languages[Language::Gnomish] = 25;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case HIGH_ELF:
|
case Race::Troll: {
|
||||||
{
|
pp->languages[Language::CommonTongue] = RuleI(Character, TrollCommonTongue);
|
||||||
pp->languages[LANG_COMMON_TONGUE] = 100;
|
pp->languages[Language::DarkSpeech] = Language::MaxValue;
|
||||||
pp->languages[LANG_DARK_ELVISH] = 25;
|
pp->languages[Language::Troll] = Language::MaxValue;
|
||||||
pp->languages[LANG_ELDER_ELVISH] = 25;
|
|
||||||
pp->languages[LANG_ELVISH] = 100;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case HUMAN:
|
case Race::Ogre: {
|
||||||
{
|
pp->languages[Language::CommonTongue] = RuleI(Character, OgreCommonTongue);
|
||||||
pp->languages[LANG_COMMON_TONGUE] = 100;
|
pp->languages[Language::DarkSpeech] = Language::MaxValue;
|
||||||
|
pp->languages[Language::Ogre] = Language::MaxValue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IKSAR:
|
case Race::Halfling: {
|
||||||
{
|
pp->languages[Language::CommonTongue] = Language::MaxValue;
|
||||||
pp->languages[LANG_COMMON_TONGUE] = RuleI(Character, IksarCommonTongue);
|
pp->languages[Language::Halfling] = Language::MaxValue;
|
||||||
pp->languages[LANG_DARK_SPEECH] = 100;
|
|
||||||
pp->languages[LANG_LIZARDMAN] = 100;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case OGRE:
|
case Race::Gnome: {
|
||||||
{
|
pp->languages[Language::CommonTongue] = Language::MaxValue;
|
||||||
pp->languages[LANG_COMMON_TONGUE] = RuleI(Character, OgreCommonTongue);
|
pp->languages[Language::Dwarvish] = 25;
|
||||||
pp->languages[LANG_DARK_SPEECH] = 100;
|
pp->languages[Language::Gnomish] = Language::MaxValue;
|
||||||
pp->languages[LANG_OGRE] = 100;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TROLL:
|
case Race::Iksar: {
|
||||||
{
|
pp->languages[Language::CommonTongue] = RuleI(Character, IksarCommonTongue);
|
||||||
pp->languages[LANG_COMMON_TONGUE] = RuleI(Character, TrollCommonTongue);
|
pp->languages[Language::DarkSpeech] = Language::MaxValue;
|
||||||
pp->languages[LANG_DARK_SPEECH] = 100;
|
pp->languages[Language::Lizardman] = Language::MaxValue;
|
||||||
pp->languages[LANG_TROLL] = 100;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WOOD_ELF:
|
case Race::VahShir: {
|
||||||
{
|
pp->languages[Language::CommonTongue] = Language::MaxValue;
|
||||||
pp->languages[LANG_COMMON_TONGUE] = 100;
|
pp->languages[Language::CombineTongue] = Language::MaxValue;
|
||||||
pp->languages[LANG_ELVISH] = 100;
|
pp->languages[Language::Erudian] = 25;
|
||||||
|
pp->languages[Language::VahShir] = Language::MaxValue;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VAHSHIR:
|
case Race::Froglok: {
|
||||||
{
|
pp->languages[Language::CommonTongue] = Language::MaxValue;
|
||||||
pp->languages[LANG_COMMON_TONGUE] = 100;
|
pp->languages[Language::Froglok] = Language::MaxValue;
|
||||||
pp->languages[LANG_COMBINE_TONGUE] = 100;
|
pp->languages[Language::Troll] = 25;
|
||||||
pp->languages[LANG_ERUDIAN] = 25;
|
|
||||||
pp->languages[LANG_VAH_SHIR] = 100;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DRAKKIN:
|
case Race::Drakkin: {
|
||||||
{
|
pp->languages[Language::CommonTongue] = Language::MaxValue;
|
||||||
pp->languages[LANG_COMMON_TONGUE] = 100;
|
pp->languages[Language::ElderDragon] = Language::MaxValue;
|
||||||
pp->languages[LANG_ELDER_DRAGON] = 100;
|
pp->languages[Language::Dragon] = Language::MaxValue;
|
||||||
pp->languages[LANG_DRAGON] = 100;
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2300,7 +2290,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 Class::Rogue:
|
case Class::Rogue:
|
||||||
pp->languages[LANG_THIEVES_CANT] = 100;
|
pp->languages[Language::ThievesCant] = Language::MaxValue;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -460,7 +460,7 @@ void SharedTaskManager::LoadSharedTaskState()
|
|||||||
|
|
||||||
SharedTaskManager *SharedTaskManager::LoadTaskData()
|
SharedTaskManager *SharedTaskManager::LoadTaskData()
|
||||||
{
|
{
|
||||||
m_task_data = TasksRepository::All(*m_content_database);
|
m_task_data = TasksRepository::GetWhere(*m_content_database, "enabled = 1");
|
||||||
m_task_activity_data = TaskActivitiesRepository::All(*m_content_database);
|
m_task_activity_data = TaskActivitiesRepository::All(*m_content_database);
|
||||||
|
|
||||||
LogTasks("Loaded tasks [{}] activities [{}]", m_task_data.size(), m_task_activity_data.size());
|
LogTasks("Loaded tasks [{}] activities [{}]", m_task_data.size(), m_task_activity_data.size());
|
||||||
|
|||||||
+16
-10
@@ -26,6 +26,7 @@
|
|||||||
#include "../common/ip_util.h"
|
#include "../common/ip_util.h"
|
||||||
#include "../common/zone_store.h"
|
#include "../common/zone_store.h"
|
||||||
#include "../common/path_manager.h"
|
#include "../common/path_manager.h"
|
||||||
|
#include "../common/database/database_update.h"
|
||||||
|
|
||||||
extern ZSList zoneserver_list;
|
extern ZSList zoneserver_list;
|
||||||
extern WorldConfig Config;
|
extern WorldConfig Config;
|
||||||
@@ -293,7 +294,18 @@ bool WorldBoot::DatabaseLoadRoutines(int argc, char **argv)
|
|||||||
const auto c = EQEmuConfig::get();
|
const auto c = EQEmuConfig::get();
|
||||||
if (c->auto_database_updates) {
|
if (c->auto_database_updates) {
|
||||||
LogInfo("Checking Database Conversions");
|
LogInfo("Checking Database Conversions");
|
||||||
database.CheckDatabaseConversions();
|
|
||||||
|
auto *r = RuleManager::Instance();
|
||||||
|
r->LoadRules(&database, "default", false);
|
||||||
|
if (!RuleB(Bots, Enabled) && database.DoesTableExist("bot_data")) {
|
||||||
|
LogInfo("Bot tables found but rule not enabled, enabling");
|
||||||
|
r->SetRule("Bots:Enabled", "true", &database, true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
DatabaseUpdate update{};
|
||||||
|
update.SetDatabase(&database)
|
||||||
|
->SetContentDatabase(&content_db)
|
||||||
|
->CheckDbUpdates();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RuleB(Logging, WorldGMSayLogging)) {
|
if (RuleB(Logging, WorldGMSayLogging)) {
|
||||||
@@ -622,8 +634,7 @@ void WorldBoot::CheckForPossibleConfigurationIssues()
|
|||||||
|
|
||||||
// ucs (public)
|
// ucs (public)
|
||||||
if (
|
if (
|
||||||
(!config_address.empty() && c->MailHost != config_address) ||
|
(!config_address.empty() && c->GetUCSHost() != config_address)
|
||||||
(!config_address.empty() && c->ChatHost != config_address)
|
|
||||||
) {
|
) {
|
||||||
LogWarning("# UCS Address Mailhost (Configuration)");
|
LogWarning("# UCS Address Mailhost (Configuration)");
|
||||||
LogWarning("");
|
LogWarning("");
|
||||||
@@ -635,14 +646,9 @@ void WorldBoot::CheckForPossibleConfigurationIssues()
|
|||||||
LogWarning("Docs [https://docs.eqemu.io/server/installation/configure-your-eqemu_config/#mailserver]");
|
LogWarning("Docs [https://docs.eqemu.io/server/installation/configure-your-eqemu_config/#mailserver]");
|
||||||
LogWarning("");
|
LogWarning("");
|
||||||
LogWarning(
|
LogWarning(
|
||||||
"[server.world.address] value [{}] [server.chatserver.host] [{}]",
|
"[server.world.address] value [{}] [server.ucs.host] [{}]",
|
||||||
config_address,
|
config_address,
|
||||||
c->ChatHost
|
c->GetUCSHost()
|
||||||
);
|
|
||||||
LogWarning(
|
|
||||||
"[server.world.address] value [{}] [server.mailserver.host] [{}]",
|
|
||||||
config_address,
|
|
||||||
c->MailHost
|
|
||||||
);
|
);
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -111,7 +111,7 @@ void ZSList::Process() {
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
AccountStatus::Player,
|
AccountStatus::Player,
|
||||||
Chat::Yellow,
|
Chat::System,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"[SYSTEM] World will be shutting down in {} minutes.",
|
"[SYSTEM] World will be shutting down in {} minutes.",
|
||||||
((shutdowntimer->GetRemainingTime() / 1000) / 60)
|
((shutdowntimer->GetRemainingTime() / 1000) / 60)
|
||||||
@@ -759,7 +759,7 @@ void ZSList::WorldShutDown(uint32 time, uint32 interval)
|
|||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
AccountStatus::Player,
|
AccountStatus::Player,
|
||||||
Chat::Yellow,
|
Chat::System,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"[SYSTEM] World will be shutting down in {} minutes.",
|
"[SYSTEM] World will be shutting down in {} minutes.",
|
||||||
(time / 60)
|
(time / 60)
|
||||||
|
|||||||
@@ -191,7 +191,6 @@ SET(zone_headers
|
|||||||
embperl.h
|
embperl.h
|
||||||
encounter.h
|
encounter.h
|
||||||
entity.h
|
entity.h
|
||||||
errmsg.h
|
|
||||||
event_codes.h
|
event_codes.h
|
||||||
expedition.h
|
expedition.h
|
||||||
expedition_database.h
|
expedition_database.h
|
||||||
|
|||||||
+79
-67
@@ -39,6 +39,8 @@ Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
|
|||||||
|
|
||||||
#include "bot.h"
|
#include "bot.h"
|
||||||
|
|
||||||
|
#include "../common/repositories/character_alternate_abilities_repository.h"
|
||||||
|
|
||||||
extern WorldServer worldserver;
|
extern WorldServer worldserver;
|
||||||
extern QueryServ* QServ;
|
extern QueryServ* QServ;
|
||||||
|
|
||||||
@@ -510,13 +512,15 @@ void Mob::WakeTheDead(uint16 spell_id, Corpse *corpse_to_use, Mob *tar, uint32 d
|
|||||||
delete made_npc;
|
delete made_npc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::ResetAA() {
|
void Client::ResetAA()
|
||||||
|
{
|
||||||
SendClearAA();
|
SendClearAA();
|
||||||
RefundAA();
|
RefundAA();
|
||||||
|
|
||||||
memset(&m_pp.aa_array[0], 0, sizeof(AA_Array) * MAX_PP_AA_ARRAY);
|
memset(&m_pp.aa_array[0], 0, sizeof(AA_Array) * MAX_PP_AA_ARRAY);
|
||||||
|
|
||||||
int i = 0;
|
int slot_id = 0;
|
||||||
|
|
||||||
for (auto& rank_value: aa_ranks) {
|
for (auto& rank_value: aa_ranks) {
|
||||||
auto ability_rank = zone->GetAlternateAdvancementAbilityAndRank(rank_value.first, rank_value.second.first);
|
auto ability_rank = zone->GetAlternateAdvancementAbilityAndRank(rank_value.first, rank_value.second.first);
|
||||||
auto ability = ability_rank.first;
|
auto ability = ability_rank.first;
|
||||||
@@ -526,14 +530,15 @@ void Client::ResetAA() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pp.aa_array[i].AA = rank_value.first;
|
m_pp.aa_array[slot_id].AA = rank_value.first;
|
||||||
m_pp.aa_array[i].value = rank_value.second.first;
|
m_pp.aa_array[slot_id].value = rank_value.second.first;
|
||||||
m_pp.aa_array[i].charges = rank_value.second.second;
|
m_pp.aa_array[slot_id].charges = rank_value.second.second;
|
||||||
++i;
|
++slot_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < _maxLeaderAA; ++i)
|
for (int slot_id = 0; slot_id < _maxLeaderAA; ++slot_id) {
|
||||||
m_pp.leader_abilities.ranks[i] = 0;
|
m_pp.leader_abilities.ranks[slot_id] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
m_pp.group_leadership_points = 0;
|
m_pp.group_leadership_points = 0;
|
||||||
m_pp.raid_leadership_points = 0;
|
m_pp.raid_leadership_points = 0;
|
||||||
@@ -541,7 +546,7 @@ void Client::ResetAA() {
|
|||||||
m_pp.raid_leadership_exp = 0;
|
m_pp.raid_leadership_exp = 0;
|
||||||
|
|
||||||
database.DeleteCharacterAAs(CharacterID());
|
database.DeleteCharacterAAs(CharacterID());
|
||||||
database.DeleteCharacterLeadershipAAs(CharacterID());
|
database.DeleteCharacterLeadershipAbilities(CharacterID());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::SendClearAA()
|
void Client::SendClearAA()
|
||||||
@@ -1438,23 +1443,23 @@ void Mob::ExpendAlternateAdvancementCharge(uint32 aa_id) {
|
|||||||
|
|
||||||
bool ZoneDatabase::LoadAlternateAdvancement(Client *c) {
|
bool ZoneDatabase::LoadAlternateAdvancement(Client *c) {
|
||||||
c->ClearAAs();
|
c->ClearAAs();
|
||||||
std::string query = StringFormat(
|
|
||||||
"SELECT "
|
|
||||||
"aa_id, "
|
|
||||||
"aa_value, "
|
|
||||||
"charges "
|
|
||||||
"FROM "
|
|
||||||
"`character_alternate_abilities` "
|
|
||||||
"WHERE `id` = %u", c->CharacterID());
|
|
||||||
MySQLRequestResult results = database.QueryDatabase(query);
|
|
||||||
|
|
||||||
int i = 0;
|
const auto& l = CharacterAlternateAbilitiesRepository::GetWhere(
|
||||||
for(auto row = results.begin(); row != results.end(); ++row) {
|
database,
|
||||||
uint32 aa = Strings::ToUnsignedInt(row[0]);
|
fmt::format(
|
||||||
uint32 value = Strings::ToUnsignedInt(row[1]);
|
"`id` = {}",
|
||||||
uint32 charges = Strings::ToUnsignedInt(row[2]);
|
c->CharacterID()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
auto rank = zone->GetAlternateAdvancementRank(aa);
|
uint32 slot_id = 0;
|
||||||
|
|
||||||
|
for (const auto& e : l) {
|
||||||
|
const uint16 aa_id = e.aa_id;
|
||||||
|
const uint16 aa_value = e.aa_value;
|
||||||
|
const uint16 charges = e.charges;
|
||||||
|
|
||||||
|
auto rank = zone->GetAlternateAdvancementRank(aa_id);
|
||||||
if (!rank) {
|
if (!rank) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1464,14 +1469,16 @@ bool ZoneDatabase::LoadAlternateAdvancement(Client *c) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
rank = ability->GetRankByPointsSpent(value);
|
rank = ability->GetRankByPointsSpent(aa_value);
|
||||||
|
|
||||||
if (c->CanUseAlternateAdvancementRank(rank)) {
|
if (c->CanUseAlternateAdvancementRank(rank)) {
|
||||||
c->GetPP().aa_array[i].AA = aa;
|
c->GetPP().aa_array[slot_id].AA = aa_id;
|
||||||
c->GetPP().aa_array[i].value = value;
|
c->GetPP().aa_array[slot_id].value = aa_value;
|
||||||
c->GetPP().aa_array[i].charges = charges;
|
c->GetPP().aa_array[slot_id].charges = charges;
|
||||||
c->SetAA(aa, value, charges);
|
|
||||||
i++;
|
c->SetAA(aa_id, aa_value, charges);
|
||||||
|
|
||||||
|
slot_id++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1556,42 +1563,47 @@ uint32 Mob::GetAAByAAID(uint32 aa_id, uint32 *charges) const {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mob::SetAA(uint32 rank_id, uint32 new_value, uint32 charges) {
|
bool Mob::SetAA(uint32 rank_id, uint32 new_value, uint32 charges)
|
||||||
|
{
|
||||||
if (zone) {
|
if (zone) {
|
||||||
AA::Ability *ability = zone->GetAlternateAdvancementAbilityByRank(rank_id);
|
auto a = zone->GetAlternateAdvancementAbilityByRank(rank_id);
|
||||||
|
|
||||||
if(!ability) {
|
if (!a) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(new_value > ability->GetMaxLevel(this)) {
|
if(new_value > a->GetMaxLevel(this)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
aa_ranks[ability->id] = std::make_pair(new_value, charges);
|
aa_ranks[a->id] = std::make_pair(new_value, charges);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Mob::CanUseAlternateAdvancementRank(AA::Rank *rank) {
|
bool Mob::CanUseAlternateAdvancementRank(AA::Rank *rank)
|
||||||
|
{
|
||||||
if (!rank) {
|
if (!rank) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AA::Ability *ability = rank->base_ability;
|
const auto a = rank->base_ability;
|
||||||
|
|
||||||
if(!ability)
|
if (!a) {
|
||||||
return false;
|
|
||||||
|
|
||||||
if(!(ability->classes & (1 << GetClass()))) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Passive and Active Shroud AAs
|
if (!(a->classes & (1 << GetClass()))) {
|
||||||
// For now we skip them
|
return false;
|
||||||
if(ability->category == 3 || ability->category == 4) {
|
}
|
||||||
|
|
||||||
|
// Passive and Active Shroud AAs, skip for now
|
||||||
|
if (
|
||||||
|
a->category == AACategory::ShroudPassive ||
|
||||||
|
a->category == AACategory::ShroudActive
|
||||||
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1599,13 +1611,13 @@ bool Mob::CanUseAlternateAdvancementRank(AA::Rank *rank) {
|
|||||||
//just to make sure we dont crash the client with newer aas
|
//just to make sure we dont crash the client with newer aas
|
||||||
//we'll exclude any expendable ones
|
//we'll exclude any expendable ones
|
||||||
if (IsClient() && CastToClient()->ClientVersionBit() & EQ::versions::maskTitaniumAndEarlier) {
|
if (IsClient() && CastToClient()->ClientVersionBit() & EQ::versions::maskTitaniumAndEarlier) {
|
||||||
if(ability->charges > 0) {
|
if (a->charges > 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int expansion = RuleI(Expansion, CurrentExpansion);
|
const int expansion = RuleI(Expansion, CurrentExpansion);
|
||||||
bool use_expansion_aa = RuleB(Expansion, UseCurrentExpansionAAOnly);
|
const bool use_expansion_aa = RuleB(Expansion, UseCurrentExpansionAAOnly);
|
||||||
if (use_expansion_aa && expansion >= 0) {
|
if (use_expansion_aa && expansion >= 0) {
|
||||||
if (rank->expansion > expansion) {
|
if (rank->expansion > expansion) {
|
||||||
return false;
|
return false;
|
||||||
@@ -1617,36 +1629,35 @@ bool Mob::CanUseAlternateAdvancementRank(AA::Rank *rank) {
|
|||||||
if (rank->expansion && !(CastToClient()->GetPP().expansions & (1 << (rank->expansion - 1)))) {
|
if (rank->expansion && !(CastToClient()->GetPP().expansions & (1 << (rank->expansion - 1)))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} else if (IsBot()) {
|
||||||
else if (IsBot()) {
|
|
||||||
if (rank->expansion && !(CastToBot()->GetExpansionBitmask() & (1 << (rank->expansion - 1)))) {
|
if (rank->expansion && !(CastToBot()->GetExpansionBitmask() & (1 << (rank->expansion - 1)))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (rank->expansion && !(RuleI(World, ExpansionSettings) & (1 << (rank->expansion - 1)))) {
|
if (rank->expansion && !(RuleI(World, ExpansionSettings) & (1 << (rank->expansion - 1)))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto race = GetPlayerRaceValue(GetBaseRace());
|
auto race = GetPlayerRaceValue(GetBaseRace());
|
||||||
race = race > 16 ? 1 : race;
|
|
||||||
if(!(ability->races & (1 << (race - 1)))) {
|
race = race > PLAYER_RACE_COUNT ? Race::Human : race;
|
||||||
|
|
||||||
|
if (!(a->races & (1 << (race - 1)))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto deity = GetDeityBit();
|
const auto deity = GetDeityBit();
|
||||||
if(!(ability->deities & deity)) {
|
if (!(a->deities & deity)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(IsClient() && CastToClient()->Admin() < ability->status) {
|
if (IsClient() && CastToClient()->Admin() < a->status) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GetBaseRace() == 522) {
|
if (GetBaseRace() == Race::Drakkin) {
|
||||||
//drakkin_heritage
|
if (!(a->drakkin_heritage & (1 << GetDrakkinHeritage()))) {
|
||||||
if(!(ability->drakkin_heritage & (1 << GetDrakkinHeritage()))) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1654,11 +1665,13 @@ bool Mob::CanUseAlternateAdvancementRank(AA::Rank *rank) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Mob::CanPurchaseAlternateAdvancementRank(AA::Rank *rank, bool check_price, bool check_grant) {
|
bool Mob::CanPurchaseAlternateAdvancementRank(AA::Rank *rank, bool check_price, bool check_grant)
|
||||||
AA::Ability *ability = rank->base_ability;
|
{
|
||||||
|
auto a = rank->base_ability;
|
||||||
|
|
||||||
if(!ability)
|
if (!a) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!CanUseAlternateAdvancementRank(rank)) {
|
if (!CanUseAlternateAdvancementRank(rank)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -1668,18 +1681,17 @@ bool Mob::CanPurchaseAlternateAdvancementRank(AA::Rank *rank, bool check_price,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//You can't purchase grant only AAs they can only be assigned
|
// You cannot purchase grant only AAs they can only be assigned
|
||||||
if(check_grant && ability->grant_only) {
|
if (check_grant && a->grant_only) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//check level req
|
|
||||||
if (rank->level_req > GetLevel()) {
|
if (rank->level_req > GetLevel()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 current_charges = 0;
|
uint32 current_charges = 0;
|
||||||
auto points = GetAA(rank->id, ¤t_charges);
|
const uint32 points = GetAA(rank->id, ¤t_charges);
|
||||||
|
|
||||||
//check that we are on previous rank already (if exists)
|
//check that we are on previous rank already (if exists)
|
||||||
//grant ignores the req to own the previous rank.
|
//grant ignores the req to own the previous rank.
|
||||||
@@ -1697,7 +1709,7 @@ bool Mob::CanPurchaseAlternateAdvancementRank(AA::Rank *rank, bool check_price,
|
|||||||
//if expendable only let us purchase if we have no charges already
|
//if expendable only let us purchase if we have no charges already
|
||||||
//not quite sure on how this functions client side atm
|
//not quite sure on how this functions client side atm
|
||||||
//I intend to look into it later to make sure the behavior is right
|
//I intend to look into it later to make sure the behavior is right
|
||||||
if(ability->charges > 0 && current_charges > 0) {
|
if (a->charges > 0 && current_charges > 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1525,6 +1525,19 @@ enum { //values of AA_Action.action
|
|||||||
aaActionBuy = 3
|
aaActionBuy = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
|
namespace AACategory {
|
||||||
|
constexpr int None = -1;
|
||||||
|
constexpr int Passive = 1;
|
||||||
|
constexpr int Progression = 2;
|
||||||
|
constexpr int ShroudPassive = 3;
|
||||||
|
constexpr int ShroudActive = 4;
|
||||||
|
constexpr int VeteranReward = 5;
|
||||||
|
constexpr int Tradeskill = 6;
|
||||||
|
constexpr int Expendable = 7;
|
||||||
|
constexpr int RacialInnate = 8;
|
||||||
|
constexpr int EverQuest = 9;
|
||||||
|
}
|
||||||
|
|
||||||
class Timer;
|
class Timer;
|
||||||
class Mob;
|
class Mob;
|
||||||
class SwarmPet {
|
class SwarmPet {
|
||||||
|
|||||||
+2
-1
@@ -524,7 +524,8 @@ bool Mob::CheckWillAggro(Mob *mob) {
|
|||||||
} else {
|
} else {
|
||||||
if (
|
if (
|
||||||
(
|
(
|
||||||
GetINT() <= RuleI(Aggro, IntAggroThreshold) ||
|
(RuleB(Aggro, UndeadAlwaysAggro) && GetBodyType() == BT_Undead) ||
|
||||||
|
(GetINT() <= RuleI(Aggro, IntAggroThreshold)) ||
|
||||||
AlwaysAggro() ||
|
AlwaysAggro() ||
|
||||||
(
|
(
|
||||||
mob->IsClient() &&
|
mob->IsClient() &&
|
||||||
|
|||||||
+192
-117
@@ -1419,7 +1419,7 @@ void Mob::DoAttack(Mob *other, DamageHitInfo &hit, ExtraAttackOptions *opts, boo
|
|||||||
if (other->CheckHitChance(this, hit)) {
|
if (other->CheckHitChance(this, hit)) {
|
||||||
if (IsNPC() && other->IsClient() && other->animation > 0 && GetLevel() >= 5 && BehindMob(other, GetX(), GetY())) {
|
if (IsNPC() && other->IsClient() && other->animation > 0 && GetLevel() >= 5 && BehindMob(other, GetX(), GetY())) {
|
||||||
// ~ 12% chance
|
// ~ 12% chance
|
||||||
if (zone->random.Roll(12)) {
|
if (zone->random.Roll(RuleI(Combat, StunChance))) {
|
||||||
int stun_resist2 = other->spellbonuses.FrontalStunResist + other->itembonuses.FrontalStunResist + other->aabonuses.FrontalStunResist;
|
int stun_resist2 = other->spellbonuses.FrontalStunResist + other->itembonuses.FrontalStunResist + other->aabonuses.FrontalStunResist;
|
||||||
int stun_resist = other->spellbonuses.StunResist + other->itembonuses.StunResist + other->aabonuses.StunResist;
|
int stun_resist = other->spellbonuses.StunResist + other->itembonuses.StunResist + other->aabonuses.StunResist;
|
||||||
if (zone->random.Roll(stun_resist2)) {
|
if (zone->random.Roll(stun_resist2)) {
|
||||||
@@ -2119,6 +2119,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
|||||||
}
|
}
|
||||||
|
|
||||||
RemoveFromHateList(other);
|
RemoveFromHateList(other);
|
||||||
|
RemoveFromRampageList(other);
|
||||||
LogCombat("I am not allowed to attack [{}]", other->GetName());
|
LogCombat("I am not allowed to attack [{}]", other->GetName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -2280,49 +2281,51 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
|
|||||||
if (other->IsClient() && IsPet() && GetOwner()->IsClient()) {
|
if (other->IsClient() && IsPet() && GetOwner()->IsClient()) {
|
||||||
//pets do half damage to clients in pvp
|
//pets do half damage to clients in pvp
|
||||||
my_hit.damage_done /= 2;
|
my_hit.damage_done /= 2;
|
||||||
if (my_hit.damage_done < 1)
|
if (my_hit.damage_done < 1) {
|
||||||
my_hit.damage_done = 1;
|
my_hit.damage_done = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
} else {
|
||||||
my_hit.damage_done = DMG_INVULNERABLE;
|
my_hit.damage_done = DMG_INVULNERABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetHP() > 0 && !other->HasDied()) {
|
if (GetHP() > 0 && !other->HasDied()) {
|
||||||
other->Damage(this, my_hit.damage_done, SPELL_UNKNOWN, my_hit.skill, true, -1, false, m_specialattacks); // Not avoidable client already had thier chance to Avoid
|
other->Damage(this, my_hit.damage_done, SPELL_UNKNOWN, my_hit.skill, true, -1, false, m_specialattacks); // Not avoidable client already had thier chance to Avoid
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (HasDied()) //killed by damage shield ect
|
if (HasDied()) { //killed by damage shield ect
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
MeleeLifeTap(my_hit.damage_done);
|
MeleeLifeTap(my_hit.damage_done);
|
||||||
|
|
||||||
CommonBreakInvisibleFromCombat();
|
CommonBreakInvisibleFromCombat();
|
||||||
|
|
||||||
//I doubt this works...
|
//I doubt this works...
|
||||||
if (!GetTarget())
|
if (!GetTarget()) {
|
||||||
return true; //We killed them
|
return true; //We killed them
|
||||||
|
|
||||||
if (!bRiposte && !other->HasDied()) {
|
|
||||||
TryWeaponProc(nullptr, weapon, other, Hand); //no weapon
|
|
||||||
|
|
||||||
if (!other->HasDied())
|
|
||||||
TrySpellProc(nullptr, weapon, other, Hand);
|
|
||||||
|
|
||||||
if (my_hit.damage_done > 0 && HasSkillProcSuccess() && !other->HasDied())
|
|
||||||
TrySkillProc(other, my_hit.skill, 0, true, Hand);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetHP() > 0 && !other->HasDied())
|
bool has_hit = my_hit.damage_done > 0;
|
||||||
|
if (has_hit && !bRiposte && !other->HasDied()) {
|
||||||
|
TryWeaponProc(nullptr, weapon, other, Hand);
|
||||||
|
|
||||||
|
if (!other->HasDied()) {
|
||||||
|
TrySpellProc(nullptr, weapon, other, Hand);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HasSkillProcSuccess() && !other->HasDied()) {
|
||||||
|
TrySkillProc(other, my_hit.skill, 0, true, Hand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GetHP() > 0 && !other->HasDied()) {
|
||||||
TriggerDefensiveProcs(other, Hand, true, my_hit.damage_done);
|
TriggerDefensiveProcs(other, Hand, true, my_hit.damage_done);
|
||||||
|
}
|
||||||
|
|
||||||
if (my_hit.damage_done > 0)
|
return has_hit;
|
||||||
return true;
|
|
||||||
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NPC::Damage(Mob* other, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill, bool avoidable, int8 buffslot, bool iBuffTic, eSpecialAttacks special) {
|
void NPC::Damage(Mob* other, int64 damage, uint16 spell_id, EQ::skills::SkillType attack_skill, bool avoidable, int8 buffslot, bool iBuffTic, eSpecialAttacks special) {
|
||||||
@@ -2705,68 +2708,7 @@ bool NPC::Death(Mob* killer_mob, int64 damage, uint16 spell, EQ::skills::SkillTy
|
|||||||
|
|
||||||
Corpse* corpse = nullptr;
|
Corpse* corpse = nullptr;
|
||||||
|
|
||||||
// Parse quests even if we're killed by an NPC
|
const uint16 entity_id = GetID();
|
||||||
if (oos) {
|
|
||||||
if (IsNPC()) {
|
|
||||||
auto emote_id = GetEmoteID();
|
|
||||||
if (emote_id) {
|
|
||||||
DoNPCEmote(EQ::constants::EmoteEventTypes::OnDeath, emoteid, killer_mob);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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, this);
|
|
||||||
}
|
|
||||||
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()) ||
|
||||||
@@ -2877,6 +2819,39 @@ 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, killer_mob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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, this);
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
|
||||||
@@ -2885,6 +2860,39 @@ 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),
|
||||||
|
entity_id
|
||||||
|
);
|
||||||
|
|
||||||
|
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),
|
||||||
|
entity_id
|
||||||
|
);
|
||||||
|
|
||||||
|
std::vector<std::any> args = { corpse, this };
|
||||||
|
|
||||||
|
DispatchZoneControllerEvent(EVENT_DEATH_ZONE, oos, export_string, 0, &args);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3718,9 +3726,43 @@ bool Client::CheckDoubleAttack()
|
|||||||
// with varying triple attack skill (1-3% error at least)
|
// with varying triple attack skill (1-3% error at least)
|
||||||
bool Client::CheckTripleAttack()
|
bool Client::CheckTripleAttack()
|
||||||
{
|
{
|
||||||
int chance = GetSkill(EQ::skills::SkillTripleAttack);
|
int chance;
|
||||||
if (chance < 1)
|
|
||||||
|
if (RuleB(Combat, ClassicTripleAttack)) {
|
||||||
|
if (
|
||||||
|
IsClient() &&
|
||||||
|
GetLevel() >= 60 &&
|
||||||
|
(
|
||||||
|
GetClass() == Class::Warrior ||
|
||||||
|
GetClass() == Class::Ranger ||
|
||||||
|
GetClass() == Class::Monk ||
|
||||||
|
GetClass() == Class::Berserker
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
switch (GetClass()) {
|
||||||
|
case Class::Warrior:
|
||||||
|
chance = RuleI(Combat, ClassicTripleAttackChanceWarrior);
|
||||||
|
break;
|
||||||
|
case Class::Ranger:
|
||||||
|
chance = RuleI(Combat, ClassicTripleAttackChanceRanger);
|
||||||
|
break;
|
||||||
|
case Class::Monk:
|
||||||
|
chance = RuleI(Combat, ClassicTripleAttackChanceMonk);
|
||||||
|
break;
|
||||||
|
case Class::Berserker:
|
||||||
|
chance = RuleI(Combat, ClassicTripleAttackChanceBerserker);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
chance = GetSkill(EQ::skills::SkillTripleAttack);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chance < 1) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int inc = aabonuses.TripleAttackChance + spellbonuses.TripleAttackChance + itembonuses.TripleAttackChance;
|
int inc = aabonuses.TripleAttackChance + spellbonuses.TripleAttackChance + itembonuses.TripleAttackChance;
|
||||||
chance = static_cast<int>(chance * (1 + inc / 100.0f));
|
chance = static_cast<int>(chance * (1 + inc / 100.0f));
|
||||||
@@ -3805,6 +3847,8 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
|
|||||||
|
|
||||||
if (damage > 0) {
|
if (damage > 0) {
|
||||||
//if there is some damage being done and theres an attacker involved
|
//if there is some damage being done and theres an attacker involved
|
||||||
|
int previous_hp_ratio = GetHPRatio();
|
||||||
|
|
||||||
if (attacker) {
|
if (attacker) {
|
||||||
// if spell is lifetap add hp to the caster
|
// if spell is lifetap add hp to the caster
|
||||||
if (IsValidSpell(spell_id) && IsLifetapSpell(spell_id)) {
|
if (IsValidSpell(spell_id) && IsLifetapSpell(spell_id)) {
|
||||||
@@ -3909,13 +3953,13 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
|
|||||||
TryTriggerThreshHold(damage, SE_TriggerSpellThreshold, attacker);
|
TryTriggerThreshHold(damage, SE_TriggerSpellThreshold, attacker);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsClient() && CastToClient()->sneaking) {
|
if (IsClient()) {
|
||||||
CastToClient()->sneaking = false;
|
CommonBreakInvisible();
|
||||||
SendAppearancePacket(AT_Sneak, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attacker && attacker->IsClient() && attacker->CastToClient()->sneaking) {
|
if (attacker && attacker->IsClient() && attacker->CastToClient()->sneaking) {
|
||||||
attacker->CastToClient()->sneaking = false;
|
attacker->CastToClient()->sneaking = false;
|
||||||
attacker->SendAppearancePacket(AT_Sneak, 0);
|
attacker->SendAppearancePacket(AppearanceType::Sneak, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//final damage has been determined.
|
//final damage has been determined.
|
||||||
@@ -4030,9 +4074,10 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (GetHPRatio() < 16)
|
if (GetHPRatio() < 16 && previous_hp_ratio >= 16) {
|
||||||
TryDeathSave();
|
TryDeathSave();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TryTriggerOnCastRequirement();
|
TryTriggerOnCastRequirement();
|
||||||
|
|
||||||
@@ -4179,8 +4224,9 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
//send an HP update if we are hurt
|
//send an HP update if we are hurt
|
||||||
if (GetHP() < GetMaxHP())
|
if (GetHP() < GetMaxHP()) {
|
||||||
SendHPUpdate(); // the OP_Damage actually updates the client in these cases, so we skip the HP update for them
|
SendHPUpdate(); // the OP_Damage actually updates the client in these cases, so we skip the HP update for them
|
||||||
|
}
|
||||||
} //end `if damage was done`
|
} //end `if damage was done`
|
||||||
|
|
||||||
//send damage packet...
|
//send damage packet...
|
||||||
@@ -4188,32 +4234,48 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons
|
|||||||
auto outapp = new EQApplicationPacket(OP_Damage, sizeof(CombatDamage_Struct));
|
auto outapp = new EQApplicationPacket(OP_Damage, sizeof(CombatDamage_Struct));
|
||||||
CombatDamage_Struct* a = (CombatDamage_Struct*)outapp->pBuffer;
|
CombatDamage_Struct* a = (CombatDamage_Struct*)outapp->pBuffer;
|
||||||
a->target = GetID();
|
a->target = GetID();
|
||||||
if (attacker == nullptr)
|
|
||||||
|
if (!attacker) {
|
||||||
a->source = 0;
|
a->source = 0;
|
||||||
else if (attacker->IsClient() && attacker->CastToClient()->GMHideMe())
|
} else if (attacker->IsClient() && attacker->CastToClient()->GMHideMe()) {
|
||||||
a->source = 0;
|
a->source = 0;
|
||||||
else
|
} else {
|
||||||
a->source = attacker->GetID();
|
a->source = attacker->GetID();
|
||||||
|
}
|
||||||
|
|
||||||
a->type = (EQ::ValueWithin(skill_used, EQ::skills::Skill1HBlunt, EQ::skills::Skill2HPiercing)) ?
|
a->type = (EQ::ValueWithin(skill_used, EQ::skills::Skill1HBlunt, EQ::skills::Skill2HPiercing)) ?
|
||||||
SkillDamageTypes[skill_used] : SkillDamageTypes[EQ::skills::SkillHandtoHand]; // was 0x1c
|
SkillDamageTypes[skill_used] : SkillDamageTypes[EQ::skills::SkillHandtoHand]; // was 0x1c
|
||||||
a->damage = damage;
|
a->damage = damage;
|
||||||
a->spellid = spell_id;
|
a->spellid = spell_id;
|
||||||
if (special == eSpecialAttacks::AERampage)
|
|
||||||
|
if (special == eSpecialAttacks::AERampage) {
|
||||||
a->special = 1;
|
a->special = 1;
|
||||||
else if (special == eSpecialAttacks::Rampage)
|
} else if (special == eSpecialAttacks::Rampage) {
|
||||||
a->special = 2;
|
a->special = 2;
|
||||||
else
|
} else {
|
||||||
a->special = 0;
|
a->special = 0;
|
||||||
|
}
|
||||||
|
|
||||||
a->hit_heading = attacker ? attacker->GetHeading() : 0.0f;
|
a->hit_heading = attacker ? attacker->GetHeading() : 0.0f;
|
||||||
if (RuleB(Combat, MeleePush) && damage > 0 && !IsRooted() &&
|
if (RuleB(Combat, MeleePush) && damage > 0 && !IsRooted() &&
|
||||||
(IsClient() || zone->random.Roll(RuleI(Combat, MeleePushChance)))) {
|
(IsClient() || zone->random.Roll(RuleI(Combat, MeleePushChance)))) {
|
||||||
a->force = EQ::skills::GetSkillMeleePushForce(skill_used);
|
a->force = EQ::skills::GetSkillMeleePushForce(skill_used);
|
||||||
|
|
||||||
|
if (RuleR(Combat, MeleePushForceClientPercent) && IsClient()) {
|
||||||
|
a->force += a->force * RuleR(Combat, MeleePushForceClientPercent);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RuleR(Combat, MeleePushForcePetPercent) && IsPet()) {
|
||||||
|
a->force += a->force * RuleR(Combat, MeleePushForcePetPercent);
|
||||||
|
}
|
||||||
|
|
||||||
if (IsNPC()) {
|
if (IsNPC()) {
|
||||||
if (attacker && attacker->IsNPC()) {
|
if (!RuleB(Combat, NPCtoNPCPush) && attacker && attacker->IsNPC()) {
|
||||||
a->force = 0.0f; // 2013 change that disabled NPC vs NPC push
|
a->force = 0.0f; // 2013 change that disabled NPC vs NPC push
|
||||||
} else {
|
} else {
|
||||||
a->force *= 0.10f; // force against NPCs is divided by 10 I guess? ex bash is 0.3, parsed 0.03 against an NPC
|
a->force *= 0.10f; // force against NPCs is divided by 10 I guess? ex bash is 0.3, parsed 0.03 against an NPC
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ForcedMovement == 0 && a->force != 0.0f && position_update_melee_push_timer.Check()) {
|
if (ForcedMovement == 0 && a->force != 0.0f && position_update_melee_push_timer.Check()) {
|
||||||
m_Delta.x += a->force * g_Math.FastSin(a->hit_heading);
|
m_Delta.x += a->force * g_Math.FastSin(a->hit_heading);
|
||||||
m_Delta.y += a->force * g_Math.FastCos(a->hit_heading);
|
m_Delta.y += a->force * g_Math.FastCos(a->hit_heading);
|
||||||
@@ -5015,7 +5077,7 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *
|
|||||||
hit.damage_done = (hit.damage_done * SlayDmgBonus) / 100;
|
hit.damage_done = (hit.damage_done * SlayDmgBonus) / 100;
|
||||||
|
|
||||||
/* Female */
|
/* Female */
|
||||||
if (GetGender() == 1) {
|
if (GetGender() == Gender::Female) {
|
||||||
entity_list.FilteredMessageCloseString(
|
entity_list.FilteredMessageCloseString(
|
||||||
this, /* Sender */
|
this, /* Sender */
|
||||||
false, /* Skip Sender */
|
false, /* Skip Sender */
|
||||||
@@ -5183,7 +5245,6 @@ void Mob::TryCriticalHit(Mob *defender, DamageHitInfo &hit, ExtraAttackOptions *
|
|||||||
bool Mob::TryFinishingBlow(Mob *defender, int64 &damage)
|
bool Mob::TryFinishingBlow(Mob *defender, int64 &damage)
|
||||||
{
|
{
|
||||||
float hp_limit = 10.0f;
|
float hp_limit = 10.0f;
|
||||||
|
|
||||||
auto fb_hp_limit = std::max(
|
auto fb_hp_limit = std::max(
|
||||||
{
|
{
|
||||||
aabonuses.FinishingBlowLvl[SBIndex::FINISHING_BLOW_LEVEL_HP_RATIO],
|
aabonuses.FinishingBlowLvl[SBIndex::FINISHING_BLOW_LEVEL_HP_RATIO],
|
||||||
@@ -5195,28 +5256,36 @@ bool Mob::TryFinishingBlow(Mob *defender, int64 &damage)
|
|||||||
if (fb_hp_limit) {
|
if (fb_hp_limit) {
|
||||||
hp_limit = fb_hp_limit/10.0f;
|
hp_limit = fb_hp_limit/10.0f;
|
||||||
}
|
}
|
||||||
if (defender && !defender->IsClient() && defender->GetHPRatio() < hp_limit) {
|
|
||||||
|
|
||||||
uint32 FB_Dmg =
|
if (defender && !defender->IsClient() && defender->GetHPRatio() < hp_limit) {
|
||||||
|
uint32 finishing_blow_damage =
|
||||||
aabonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_DMG] + spellbonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_DMG] + itembonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_DMG];
|
aabonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_DMG] + spellbonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_DMG] + itembonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_DMG];
|
||||||
|
|
||||||
uint32 FB_Level = 0;
|
uint32 finishing_blow_level = 0;
|
||||||
FB_Level = aabonuses.FinishingBlowLvl[SBIndex::FINISHING_EFFECT_LEVEL_MAX];
|
finishing_blow_level = aabonuses.FinishingBlowLvl[SBIndex::FINISHING_EFFECT_LEVEL_MAX];
|
||||||
if (FB_Level < spellbonuses.FinishingBlowLvl[SBIndex::FINISHING_EFFECT_LEVEL_MAX])
|
if (finishing_blow_level < spellbonuses.FinishingBlowLvl[SBIndex::FINISHING_EFFECT_LEVEL_MAX]) {
|
||||||
FB_Level = spellbonuses.FinishingBlowLvl[SBIndex::FINISHING_EFFECT_LEVEL_MAX];
|
finishing_blow_level = spellbonuses.FinishingBlowLvl[SBIndex::FINISHING_EFFECT_LEVEL_MAX];
|
||||||
else if (FB_Level < itembonuses.FinishingBlowLvl[SBIndex::FINISHING_EFFECT_LEVEL_MAX])
|
} else if (finishing_blow_level < itembonuses.FinishingBlowLvl[SBIndex::FINISHING_EFFECT_LEVEL_MAX]) {
|
||||||
FB_Level = itembonuses.FinishingBlowLvl[SBIndex::FINISHING_EFFECT_LEVEL_MAX];
|
finishing_blow_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 proc_chance = (
|
||||||
aabonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE] +
|
aabonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE] +
|
||||||
itembonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE] +
|
itembonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE] +
|
||||||
spellbonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE]
|
spellbonuses.FinishingBlow[SBIndex::FINISHING_EFFECT_PROC_CHANCE]
|
||||||
);
|
);
|
||||||
|
|
||||||
if (FB_Level && FB_Dmg && (defender->GetLevel() <= FB_Level) &&
|
if (
|
||||||
(ProcChance >= zone->random.Int(1, 1000))) {
|
(
|
||||||
|
(RuleB(Combat, FinishingBlowOnlyWhenFleeing) && !defender->currently_fleeing) ||
|
||||||
|
!RuleB(Combat, FinishingBlowOnlyWhenFleeing)
|
||||||
|
) &&
|
||||||
|
finishing_blow_level &&
|
||||||
|
finishing_blow_damage &&
|
||||||
|
defender->GetLevel() <= finishing_blow_level &&
|
||||||
|
proc_chance >= zone->random.Int(1, 1000)
|
||||||
|
) {
|
||||||
/* Finishing Blow Critical Message */
|
/* Finishing Blow Critical Message */
|
||||||
entity_list.FilteredMessageCloseString(
|
entity_list.FilteredMessageCloseString(
|
||||||
this, /* Sender */
|
this, /* Sender */
|
||||||
@@ -5229,7 +5298,7 @@ bool Mob::TryFinishingBlow(Mob *defender, int64 &damage)
|
|||||||
GetCleanName() /* Message1 */
|
GetCleanName() /* Message1 */
|
||||||
);
|
);
|
||||||
|
|
||||||
damage = FB_Dmg;
|
damage = finishing_blow_damage;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6287,15 +6356,21 @@ void Client::DoAttackRounds(Mob *target, int hand, bool IsFromSpell)
|
|||||||
|
|
||||||
// you can only triple from the main hand
|
// you can only triple from the main hand
|
||||||
if (hand == EQ::invslot::slotPrimary && CanThisClassTripleAttack()) {
|
if (hand == EQ::invslot::slotPrimary && CanThisClassTripleAttack()) {
|
||||||
|
if (!RuleB(Combat, ClassicTripleAttack)) {
|
||||||
CheckIncreaseSkill(EQ::skills::SkillTripleAttack, target, -10);
|
CheckIncreaseSkill(EQ::skills::SkillTripleAttack, target, -10);
|
||||||
|
}
|
||||||
|
|
||||||
if (CheckTripleAttack()) {
|
if (CheckTripleAttack()) {
|
||||||
Attack(target, hand, false, false, IsFromSpell);
|
Attack(target, hand, false, false, IsFromSpell);
|
||||||
auto flurrychance = aabonuses.FlurryChance + spellbonuses.FlurryChance +
|
int flurry_chance = aabonuses.FlurryChance + spellbonuses.FlurryChance +
|
||||||
itembonuses.FlurryChance;
|
itembonuses.FlurryChance;
|
||||||
if (flurrychance && zone->random.Roll(flurrychance)) {
|
|
||||||
|
if (flurry_chance && zone->random.Roll(flurry_chance)) {
|
||||||
Attack(target, hand, false, false, IsFromSpell);
|
Attack(target, hand, false, false, IsFromSpell);
|
||||||
if (zone->random.Roll(flurrychance))
|
|
||||||
|
if (zone->random.Roll(flurry_chance)) {
|
||||||
Attack(target, hand, false, false, IsFromSpell);
|
Attack(target, hand, false, false, IsFromSpell);
|
||||||
|
}
|
||||||
MessageString(Chat::NPCFlurry, YOU_FLURRY);
|
MessageString(Chat::NPCFlurry, YOU_FLURRY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -49,9 +49,9 @@ Beacon::Beacon(const glm::vec4 &in_pos, int lifetime) : Mob(
|
|||||||
nullptr, // in_lastname
|
nullptr, // in_lastname
|
||||||
0, // in_cur_hp
|
0, // in_cur_hp
|
||||||
0, // in_max_hp
|
0, // in_max_hp
|
||||||
MALE, // in_gender
|
Gender::Male, // in_gender
|
||||||
INVISIBLE_MAN, // in_race
|
Race::InvisibleMan, // in_race
|
||||||
0, // in_class
|
Class::None, // in_class
|
||||||
BT_NoTarget, // in_bodytype
|
BT_NoTarget, // in_bodytype
|
||||||
0, // in_deity
|
0, // in_deity
|
||||||
0, // in_level
|
0, // in_level
|
||||||
|
|||||||
+20
-40
@@ -281,10 +281,10 @@ Bot::Bot(
|
|||||||
case SE_IllusionCopy:
|
case SE_IllusionCopy:
|
||||||
case SE_Illusion: {
|
case SE_Illusion: {
|
||||||
if (spell.base_value[x1] == -1) {
|
if (spell.base_value[x1] == -1) {
|
||||||
if (gender == FEMALE) {
|
if (gender == Gender::Female) {
|
||||||
gender = MALE;
|
gender = Gender::Male;
|
||||||
} else if (gender == MALE) {
|
} else if (gender == Gender::Male) {
|
||||||
gender = FEMALE;
|
gender = Gender::Female;
|
||||||
}
|
}
|
||||||
|
|
||||||
SendIllusionPacket(
|
SendIllusionPacket(
|
||||||
@@ -325,30 +325,30 @@ Bot::Bot(
|
|||||||
|
|
||||||
switch (spell.base_value[x1]) {
|
switch (spell.base_value[x1]) {
|
||||||
case OGRE:
|
case OGRE:
|
||||||
SendAppearancePacket(AT_Size, 9);
|
SendAppearancePacket(AppearanceType::Size, 9);
|
||||||
break;
|
break;
|
||||||
case TROLL:
|
case TROLL:
|
||||||
SendAppearancePacket(AT_Size, 8);
|
SendAppearancePacket(AppearanceType::Size, 8);
|
||||||
break;
|
break;
|
||||||
case VAHSHIR:
|
case VAHSHIR:
|
||||||
case BARBARIAN:
|
case BARBARIAN:
|
||||||
SendAppearancePacket(AT_Size, 7);
|
SendAppearancePacket(AppearanceType::Size, 7);
|
||||||
break;
|
break;
|
||||||
case HALF_ELF:
|
case HALF_ELF:
|
||||||
case WOOD_ELF:
|
case WOOD_ELF:
|
||||||
case DARK_ELF:
|
case DARK_ELF:
|
||||||
case FROGLOK:
|
case FROGLOK:
|
||||||
SendAppearancePacket(AT_Size, 5);
|
SendAppearancePacket(AppearanceType::Size, 5);
|
||||||
break;
|
break;
|
||||||
case DWARF:
|
case DWARF:
|
||||||
SendAppearancePacket(AT_Size, 4);
|
SendAppearancePacket(AppearanceType::Size, 4);
|
||||||
break;
|
break;
|
||||||
case HALFLING:
|
case HALFLING:
|
||||||
case GNOME:
|
case GNOME:
|
||||||
SendAppearancePacket(AT_Size, 3);
|
SendAppearancePacket(AppearanceType::Size, 3);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
SendAppearancePacket(AT_Size, 6);
|
SendAppearancePacket(AppearanceType::Size, 6);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -372,18 +372,18 @@ Bot::Bot(
|
|||||||
case SE_Invisibility:
|
case SE_Invisibility:
|
||||||
{
|
{
|
||||||
invisible = true;
|
invisible = true;
|
||||||
SendAppearancePacket(AT_Invis, 1);
|
SendAppearancePacket(AppearanceType::Invisibility, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SE_Levitate:
|
case SE_Levitate:
|
||||||
{
|
{
|
||||||
if (!zone->CanLevitate())
|
if (!zone->CanLevitate())
|
||||||
{
|
{
|
||||||
SendAppearancePacket(AT_Levitate, 0);
|
SendAppearancePacket(AppearanceType::FlyMode, 0);
|
||||||
BuffFadeByEffect(SE_Levitate);
|
BuffFadeByEffect(SE_Levitate);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SendAppearancePacket(AT_Levitate, 2);
|
SendAppearancePacket(AppearanceType::FlyMode, 2);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2783,10 +2783,12 @@ bool Bot::IsValidTarget(Client* bot_owner, Client* leash_owner, float lo_distanc
|
|||||||
// Normally, we wouldn't want to do this without class checks..but, too many issues can arise if we let enchanter animation pets run rampant
|
// Normally, we wouldn't want to do this without class checks..but, too many issues can arise if we let enchanter animation pets run rampant
|
||||||
if (HasPet()) {
|
if (HasPet()) {
|
||||||
GetPet()->RemoveFromHateList(tar);
|
GetPet()->RemoveFromHateList(tar);
|
||||||
|
GetPet()->RemoveFromRampageList(tar);
|
||||||
GetPet()->SetTarget(nullptr);
|
GetPet()->SetTarget(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
RemoveFromHateList(tar);
|
RemoveFromHateList(tar);
|
||||||
|
RemoveFromRampageList(tar);
|
||||||
SetTarget(nullptr);
|
SetTarget(nullptr);
|
||||||
|
|
||||||
SetAttackFlag(false);
|
SetAttackFlag(false);
|
||||||
@@ -3674,7 +3676,7 @@ void Bot::LevelBotWithClient(Client* c, uint8 new_level, bool send_appearance) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
e->SendHPUpdate();
|
e->SendHPUpdate();
|
||||||
e->SendAppearancePacket(AT_WhoLevel, new_level, true, true); // who level change
|
e->SendAppearancePacket(AppearanceType::WhoLevel, new_level, true, true); // who level change
|
||||||
e->AI_AddBotSpells(e->GetBotSpellID());
|
e->AI_AddBotSpells(e->GetBotSpellID());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3706,7 +3708,7 @@ void Bot::BotAddEquipItem(uint16 slot_id, uint32 item_id) {
|
|||||||
|
|
||||||
UpdateEquipmentLight();
|
UpdateEquipmentLight();
|
||||||
if (UpdateActiveLight() && GetID()) { // temp hack fix
|
if (UpdateActiveLight() && GetID()) { // temp hack fix
|
||||||
SendAppearancePacket(AT_Light, GetActiveLightType());
|
SendAppearancePacket(AppearanceType::Light, GetActiveLightType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3726,7 +3728,7 @@ void Bot::BotRemoveEquipItem(uint16 slot_id)
|
|||||||
|
|
||||||
UpdateEquipmentLight();
|
UpdateEquipmentLight();
|
||||||
if (UpdateActiveLight()) {
|
if (UpdateActiveLight()) {
|
||||||
SendAppearancePacket(AT_Light, GetActiveLightType());
|
SendAppearancePacket(AppearanceType::Light, GetActiveLightType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7894,7 +7896,7 @@ void Bot::BotGroupSay(Mob *speaker, const char *msg, ...) {
|
|||||||
if (speaker->HasGroup()) {
|
if (speaker->HasGroup()) {
|
||||||
Group *g = speaker->GetGroup();
|
Group *g = speaker->GetGroup();
|
||||||
if (g)
|
if (g)
|
||||||
g->GroupMessage(speaker->CastToMob(), 0, 100, buf);
|
g->GroupMessage(speaker->CastToMob(), Language::CommonTongue, Language::MaxValue, buf);
|
||||||
} else
|
} else
|
||||||
speaker->Say("%s", buf);
|
speaker->Say("%s", buf);
|
||||||
}
|
}
|
||||||
@@ -8138,28 +8140,6 @@ bool Bot::DyeArmor(int16 slot_id, uint32 rgb, bool all_flag, bool save_flag)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Bot::CreateSayLink(Client* c, const char* message, const char* name)
|
|
||||||
{
|
|
||||||
// TODO: review
|
|
||||||
|
|
||||||
int saylink_size = strlen(message);
|
|
||||||
char* escaped_string = new char[saylink_size * 2];
|
|
||||||
|
|
||||||
database.DoEscapeString(escaped_string, message, saylink_size);
|
|
||||||
|
|
||||||
uint32 saylink_id = database.LoadSaylinkID(escaped_string);
|
|
||||||
safe_delete_array(escaped_string);
|
|
||||||
|
|
||||||
EQ::SayLinkEngine linker;
|
|
||||||
linker.SetLinkType(EQ::saylink::SayLinkItemData);
|
|
||||||
linker.SetProxyItemID(SAYLINK_ITEM_ID);
|
|
||||||
linker.SetProxyAugment1ID(saylink_id);
|
|
||||||
linker.SetProxyText(name);
|
|
||||||
|
|
||||||
auto saylink = linker.GenerateLink();
|
|
||||||
return saylink;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Bot::Signal(int signal_id)
|
void Bot::Signal(int signal_id)
|
||||||
{
|
{
|
||||||
if (parse->BotHasQuestSub(EVENT_SIGNAL)) {
|
if (parse->BotHasQuestSub(EVENT_SIGNAL)) {
|
||||||
|
|||||||
@@ -659,8 +659,6 @@ public:
|
|||||||
void SetBotEnforceSpellSetting(bool enforcespellsettings, bool save = false);
|
void SetBotEnforceSpellSetting(bool enforcespellsettings, bool save = false);
|
||||||
bool GetBotEnforceSpellSetting() const { return m_enforce_spell_settings; }
|
bool GetBotEnforceSpellSetting() const { return m_enforce_spell_settings; }
|
||||||
|
|
||||||
std::string CreateSayLink(Client* botOwner, const char* message, const char* name);
|
|
||||||
|
|
||||||
// Class Destructors
|
// Class Destructors
|
||||||
~Bot() override;
|
~Bot() override;
|
||||||
|
|
||||||
|
|||||||
+58
-71
@@ -404,38 +404,38 @@ public:
|
|||||||
|
|
||||||
for (int i = EffectIDFirst; i <= EffectIDLast; ++i) {
|
for (int i = EffectIDFirst; i <= EffectIDLast; ++i) {
|
||||||
int effect_index = EFFECTIDTOINDEX(i);
|
int effect_index = EFFECTIDTOINDEX(i);
|
||||||
if (spells[spell_id].base_value[effect_index] <= 0)
|
if (spells[spell_id].max_value[effect_index] <= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
switch (spells[spell_id].effect_id[effect_index]) {
|
switch (spells[spell_id].effect_id[effect_index]) {
|
||||||
case SE_ResistFire:
|
case SE_ResistFire:
|
||||||
entry_prototype->SafeCastToResistance()->resist_value[RESISTANCEIDTOINDEX(
|
entry_prototype->SafeCastToResistance()->resist_value[RESISTANCEIDTOINDEX(
|
||||||
BCEnum::RT_Fire)] += spells[spell_id].base_value[effect_index];
|
BCEnum::RT_Fire)] += spells[spell_id].max_value[effect_index];
|
||||||
break;
|
break;
|
||||||
case SE_ResistCold:
|
case SE_ResistCold:
|
||||||
entry_prototype->SafeCastToResistance()->resist_value[RESISTANCEIDTOINDEX(
|
entry_prototype->SafeCastToResistance()->resist_value[RESISTANCEIDTOINDEX(
|
||||||
BCEnum::RT_Cold)] += spells[spell_id].base_value[effect_index];
|
BCEnum::RT_Cold)] += spells[spell_id].max_value[effect_index];
|
||||||
break;
|
break;
|
||||||
case SE_ResistPoison:
|
case SE_ResistPoison:
|
||||||
entry_prototype->SafeCastToResistance()->resist_value[RESISTANCEIDTOINDEX(
|
entry_prototype->SafeCastToResistance()->resist_value[RESISTANCEIDTOINDEX(
|
||||||
BCEnum::RT_Poison)] += spells[spell_id].base_value[effect_index];
|
BCEnum::RT_Poison)] += spells[spell_id].max_value[effect_index];
|
||||||
break;
|
break;
|
||||||
case SE_ResistDisease:
|
case SE_ResistDisease:
|
||||||
entry_prototype->SafeCastToResistance()->resist_value[RESISTANCEIDTOINDEX(
|
entry_prototype->SafeCastToResistance()->resist_value[RESISTANCEIDTOINDEX(
|
||||||
BCEnum::RT_Disease)] += spells[spell_id].base_value[effect_index];
|
BCEnum::RT_Disease)] += spells[spell_id].max_value[effect_index];
|
||||||
break;
|
break;
|
||||||
case SE_ResistMagic:
|
case SE_ResistMagic:
|
||||||
entry_prototype->SafeCastToResistance()->resist_value[RESISTANCEIDTOINDEX(
|
entry_prototype->SafeCastToResistance()->resist_value[RESISTANCEIDTOINDEX(
|
||||||
BCEnum::RT_Magic)] += spells[spell_id].base_value[effect_index];
|
BCEnum::RT_Magic)] += spells[spell_id].max_value[effect_index];
|
||||||
break;
|
break;
|
||||||
case SE_ResistCorruption:
|
case SE_ResistCorruption:
|
||||||
entry_prototype->SafeCastToResistance()->resist_value[RESISTANCEIDTOINDEX(
|
entry_prototype->SafeCastToResistance()->resist_value[RESISTANCEIDTOINDEX(
|
||||||
BCEnum::RT_Corruption)] += spells[spell_id].base_value[effect_index];
|
BCEnum::RT_Corruption)] += spells[spell_id].max_value[effect_index];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
entry_prototype->SafeCastToResistance()->resist_total += spells[spell_id].base_value[effect_index];
|
entry_prototype->SafeCastToResistance()->resist_total += spells[spell_id].max_value[effect_index];
|
||||||
valid_spell = true;
|
valid_spell = true;
|
||||||
}
|
}
|
||||||
if (!valid_spell) {
|
if (!valid_spell) {
|
||||||
@@ -2870,7 +2870,7 @@ void bot_command_apply_poison(Client *c, const Seperator *sep)
|
|||||||
}
|
}
|
||||||
if (my_rogue_bot->GetLevel() < 18) {
|
if (my_rogue_bot->GetLevel() < 18) {
|
||||||
|
|
||||||
c->Message(Chat::White, "Your rogue bot must be level 18 before %s can apply poison!", (my_rogue_bot->GetGender() == 1 ? "she" : "he"));
|
c->Message(Chat::White, "Your rogue bot must be level 18 before %s can apply poison!", (my_rogue_bot->GetGender() == Gender::Female ? "she" : "he"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4003,8 +4003,6 @@ void bot_command_item_use(Client* c, const Seperator* sep)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string text_link;
|
|
||||||
|
|
||||||
EQ::SayLinkEngine linker;
|
EQ::SayLinkEngine linker;
|
||||||
linker.SetLinkType(EQ::saylink::SayLinkItemInst);
|
linker.SetLinkType(EQ::saylink::SayLinkItemInst);
|
||||||
|
|
||||||
@@ -4050,15 +4048,6 @@ void bot_command_item_use(Client* c, const Seperator* sep)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
text_link = bot_iter->CreateSayLink(
|
|
||||||
c,
|
|
||||||
fmt::format(
|
|
||||||
"^inventorygive byname {}",
|
|
||||||
bot_iter->GetCleanName()
|
|
||||||
).c_str(),
|
|
||||||
bot_iter->GetCleanName()
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const auto& slot_iter : equipable_slot_list) {
|
for (const auto& slot_iter : equipable_slot_list) {
|
||||||
// needs more failure criteria - this should cover the bulk for now
|
// needs more failure criteria - this should cover the bulk for now
|
||||||
if (slot_iter == EQ::invslot::slotSecondary && item_data->Damage && !bot_iter->CanThisClassDualWield()) {
|
if (slot_iter == EQ::invslot::slotSecondary && item_data->Damage && !bot_iter->CanThisClassDualWield()) {
|
||||||
@@ -4074,7 +4063,13 @@ void bot_command_item_use(Client* c, const Seperator* sep)
|
|||||||
Chat::Say,
|
Chat::Say,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} says, 'I can use that for my {} instead of my {}! Would you like to {} my {}?'",
|
"{} says, 'I can use that for my {} instead of my {}! Would you like to {} my {}?'",
|
||||||
text_link,
|
Saylink::Silent(
|
||||||
|
fmt::format(
|
||||||
|
"^inventorygive byname {}",
|
||||||
|
bot_iter->GetCleanName()
|
||||||
|
),
|
||||||
|
bot_iter->GetCleanName()
|
||||||
|
),
|
||||||
EQ::invslot::GetInvPossessionsSlotName(slot_iter),
|
EQ::invslot::GetInvPossessionsSlotName(slot_iter),
|
||||||
linker.GenerateLink(),
|
linker.GenerateLink(),
|
||||||
Saylink::Silent(
|
Saylink::Silent(
|
||||||
@@ -4096,7 +4091,13 @@ void bot_command_item_use(Client* c, const Seperator* sep)
|
|||||||
Chat::Say,
|
Chat::Say,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"{} says, 'I can use that for my {}! Would you like to {} it to me?'",
|
"{} says, 'I can use that for my {}! Would you like to {} it to me?'",
|
||||||
text_link,
|
Saylink::Silent(
|
||||||
|
fmt::format(
|
||||||
|
"^inventorygive byname {}",
|
||||||
|
bot_iter->GetCleanName()
|
||||||
|
),
|
||||||
|
bot_iter->GetCleanName()
|
||||||
|
),
|
||||||
EQ::invslot::GetInvPossessionsSlotName(slot_iter),
|
EQ::invslot::GetInvPossessionsSlotName(slot_iter),
|
||||||
Saylink::Silent(
|
Saylink::Silent(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
@@ -5633,7 +5634,7 @@ void bot_subcommand_bot_beard_color(Client *c, const Seperator *sep)
|
|||||||
uint8 uvalue = Strings::ToInt(sep->arg[1]);
|
uint8 uvalue = Strings::ToInt(sep->arg[1]);
|
||||||
|
|
||||||
auto fail_type = BCEnum::AFT_None;
|
auto fail_type = BCEnum::AFT_None;
|
||||||
if (my_bot->GetGender() != MALE && my_bot->GetRace() != DWARF)
|
if (my_bot->GetGender() != Gender::Male && my_bot->GetRace() != DWARF)
|
||||||
fail_type = BCEnum::AFT_GenderRace;
|
fail_type = BCEnum::AFT_GenderRace;
|
||||||
else if (!PlayerAppearance::IsValidBeardColor(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
else if (!PlayerAppearance::IsValidBeardColor(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
||||||
fail_type = BCEnum::AFT_Value;
|
fail_type = BCEnum::AFT_Value;
|
||||||
@@ -5670,7 +5671,7 @@ void bot_subcommand_bot_beard_style(Client *c, const Seperator *sep)
|
|||||||
uint8 uvalue = Strings::ToInt(sep->arg[1]);
|
uint8 uvalue = Strings::ToInt(sep->arg[1]);
|
||||||
|
|
||||||
auto fail_type = BCEnum::AFT_None;
|
auto fail_type = BCEnum::AFT_None;
|
||||||
if (my_bot->GetGender() != MALE && my_bot->GetRace() != DWARF)
|
if (my_bot->GetGender() != Gender::Male && my_bot->GetRace() != DWARF)
|
||||||
fail_type = BCEnum::AFT_GenderRace;
|
fail_type = BCEnum::AFT_GenderRace;
|
||||||
else if (!PlayerAppearance::IsValidBeard(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
else if (!PlayerAppearance::IsValidBeard(my_bot->GetRace(), my_bot->GetGender(), uvalue))
|
||||||
fail_type = BCEnum::AFT_Value;
|
fail_type = BCEnum::AFT_Value;
|
||||||
@@ -6171,18 +6172,18 @@ void bot_subcommand_bot_create(Client *c, const Seperator *sep)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto bot_gender = MALE;
|
auto bot_gender = Gender::Male;
|
||||||
|
|
||||||
if (sep->IsNumber(4)) {
|
if (sep->IsNumber(4)) {
|
||||||
bot_gender = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[4]));
|
bot_gender = static_cast<uint8>(Strings::ToUnsignedInt(sep->arg[4]));
|
||||||
if (bot_gender == NEUTER) {
|
if (bot_gender == Gender::Neuter) {
|
||||||
bot_gender = MALE;
|
bot_gender = Gender::Male;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!strcasecmp(sep->arg[4], "m") || !strcasecmp(sep->arg[4], "male")) {
|
if (!strcasecmp(sep->arg[4], "m") || !strcasecmp(sep->arg[4], "male")) {
|
||||||
bot_gender = MALE;
|
bot_gender = Gender::Male;
|
||||||
} else if (!strcasecmp(sep->arg[4], "f") || !strcasecmp(sep->arg[4], "female")) {
|
} else if (!strcasecmp(sep->arg[4], "f") || !strcasecmp(sep->arg[4], "female")) {
|
||||||
bot_gender = FEMALE;
|
bot_gender = Gender::Female;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7594,7 +7595,7 @@ void bot_subcommand_bot_toggle_helm(Client *c, const Seperator *sep)
|
|||||||
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
|
EQApplicationPacket* outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
|
||||||
SpawnAppearance_Struct* saptr = (SpawnAppearance_Struct*)outapp->pBuffer;
|
SpawnAppearance_Struct* saptr = (SpawnAppearance_Struct*)outapp->pBuffer;
|
||||||
saptr->spawn_id = bot_iter->GetID();
|
saptr->spawn_id = bot_iter->GetID();
|
||||||
saptr->type = AT_ShowHelm;
|
saptr->type = AppearanceType::ShowHelm;
|
||||||
saptr->parameter = bot_iter->GetShowHelm();
|
saptr->parameter = bot_iter->GetShowHelm();
|
||||||
|
|
||||||
entity_list.QueueClients(bot_iter, outapp);
|
entity_list.QueueClients(bot_iter, outapp);
|
||||||
@@ -7667,7 +7668,7 @@ void bot_subcommand_bot_toggle_helm(Client *c, const Seperator *sep)
|
|||||||
[10-16-2015 :: 22:15:40] [Packet :: Server -> Client (Dump)] [OP_SpawnAppearance - 0x01d1] [Size: 10]
|
[10-16-2015 :: 22:15:40] [Packet :: Server -> Client (Dump)] [OP_SpawnAppearance - 0x01d1] [Size: 10]
|
||||||
0: A2 02 2B 00 00 00 00 00 - showhelm = false
|
0: A2 02 2B 00 00 00 00 00 - showhelm = false
|
||||||
|
|
||||||
*** Bot did not update using the OP_SpawnAppearance packet with AT_ShowHelm appearance type ***
|
*** Bot did not update using the OP_SpawnAppearance packet with AppearanceType::ShowHelm appearance type ***
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7694,7 +7695,7 @@ void bot_subcommand_bot_update(Client *c, const Seperator *sep)
|
|||||||
|
|
||||||
bot_iter->SetPetChooser(false);
|
bot_iter->SetPetChooser(false);
|
||||||
bot_iter->CalcBotStats(c->GetBotOption(Client::booStatsUpdate));
|
bot_iter->CalcBotStats(c->GetBotOption(Client::booStatsUpdate));
|
||||||
bot_iter->SendAppearancePacket(AT_WhoLevel, bot_iter->GetLevel(), true, true);
|
bot_iter->SendAppearancePacket(AppearanceType::WhoLevel, bot_iter->GetLevel(), true, true);
|
||||||
++bot_count;
|
++bot_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -9542,10 +9543,6 @@ uint32 helper_bot_create(Client *bot_owner, std::string bot_name, uint8 bot_clas
|
|||||||
if (!Bot::IsValidRaceClassCombo(bot_race, bot_class)) {
|
if (!Bot::IsValidRaceClassCombo(bot_race, bot_class)) {
|
||||||
const std::string bot_race_name = GetRaceIDName(bot_race);
|
const std::string bot_race_name = GetRaceIDName(bot_race);
|
||||||
const std::string bot_class_name = GetClassIDName(bot_class);
|
const std::string bot_class_name = GetClassIDName(bot_class);
|
||||||
const auto view_saylink = Saylink::Silent(
|
|
||||||
fmt::format("^viewcombos {}", bot_race),
|
|
||||||
"view"
|
|
||||||
);
|
|
||||||
|
|
||||||
bot_owner->Message(
|
bot_owner->Message(
|
||||||
Chat::White,
|
Chat::White,
|
||||||
@@ -9553,7 +9550,10 @@ uint32 helper_bot_create(Client *bot_owner, std::string bot_name, uint8 bot_clas
|
|||||||
"{} {} is an invalid race-class combination, would you like to {} proper combinations for {}?",
|
"{} {} is an invalid race-class combination, would you like to {} proper combinations for {}?",
|
||||||
bot_race_name,
|
bot_race_name,
|
||||||
bot_class_name,
|
bot_class_name,
|
||||||
view_saylink,
|
Saylink::Silent(
|
||||||
|
fmt::format("^viewcombos {}", bot_race),
|
||||||
|
"view"
|
||||||
|
),
|
||||||
bot_race_name
|
bot_race_name
|
||||||
).c_str()
|
).c_str()
|
||||||
);
|
);
|
||||||
@@ -9561,15 +9561,15 @@ uint32 helper_bot_create(Client *bot_owner, std::string bot_name, uint8 bot_clas
|
|||||||
return bot_id;
|
return bot_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!EQ::ValueWithin(bot_gender, MALE, FEMALE)) {
|
if (!EQ::ValueWithin(bot_gender, Gender::Male, Gender::Female)) {
|
||||||
bot_owner->Message(
|
bot_owner->Message(
|
||||||
Chat::White,
|
Chat::White,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"Gender: {} ({}) or {} ({})",
|
"Gender: {} ({}) or {} ({})",
|
||||||
GetGenderName(MALE),
|
GetGenderName(Gender::Male),
|
||||||
MALE,
|
Gender::Male,
|
||||||
GetGenderName(FEMALE),
|
GetGenderName(Gender::Female),
|
||||||
FEMALE
|
Gender::Female
|
||||||
).c_str()
|
).c_str()
|
||||||
);
|
);
|
||||||
return bot_id;
|
return bot_id;
|
||||||
@@ -9871,9 +9871,6 @@ void helper_command_depart_list(Client* bot_owner, Bot* druid_bot, Bot* wizard_b
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string msg;
|
|
||||||
std::string text_link;
|
|
||||||
|
|
||||||
auto destination_count = 0;
|
auto destination_count = 0;
|
||||||
auto destination_number = 1;
|
auto destination_number = 1;
|
||||||
for (auto list_iter : *local_list) {
|
for (auto list_iter : *local_list) {
|
||||||
@@ -9891,24 +9888,19 @@ void helper_command_depart_list(Client* bot_owner, Bot* druid_bot, Bot* wizard_b
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = fmt::format(
|
|
||||||
"^circle {}{}",
|
|
||||||
spells[local_entry->spell_id].teleport_zone,
|
|
||||||
single_flag ? " single" : ""
|
|
||||||
);
|
|
||||||
|
|
||||||
text_link = druid_bot->CreateSayLink(
|
|
||||||
bot_owner,
|
|
||||||
msg.c_str(),
|
|
||||||
"Goto"
|
|
||||||
);
|
|
||||||
|
|
||||||
druid_bot->OwnerMessage(
|
druid_bot->OwnerMessage(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"Destination {} | {} | {}",
|
"Destination {} | {} | {}",
|
||||||
destination_number,
|
destination_number,
|
||||||
local_entry->long_name,
|
local_entry->long_name,
|
||||||
text_link
|
Saylink::Silent(
|
||||||
|
fmt::format(
|
||||||
|
"^circle {}{}",
|
||||||
|
spells[local_entry->spell_id].teleport_zone,
|
||||||
|
single_flag ? " single" : ""
|
||||||
|
),
|
||||||
|
"Goto"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -9926,24 +9918,19 @@ void helper_command_depart_list(Client* bot_owner, Bot* druid_bot, Bot* wizard_b
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = fmt::format(
|
|
||||||
"^portal {}{}",
|
|
||||||
spells[local_entry->spell_id].teleport_zone,
|
|
||||||
single_flag ? " single" : ""
|
|
||||||
);
|
|
||||||
|
|
||||||
text_link = wizard_bot->CreateSayLink(
|
|
||||||
bot_owner,
|
|
||||||
msg.c_str(),
|
|
||||||
"Goto"
|
|
||||||
);
|
|
||||||
|
|
||||||
wizard_bot->OwnerMessage(
|
wizard_bot->OwnerMessage(
|
||||||
fmt::format(
|
fmt::format(
|
||||||
"Destination {} | {} | {}",
|
"Destination {} | {} | {}",
|
||||||
destination_number,
|
destination_number,
|
||||||
local_entry->long_name,
|
local_entry->long_name,
|
||||||
text_link
|
Saylink::Silent(
|
||||||
|
fmt::format(
|
||||||
|
"^portal {}{}",
|
||||||
|
spells[local_entry->spell_id].teleport_zone,
|
||||||
|
single_flag ? " single" : ""
|
||||||
|
),
|
||||||
|
"Goto"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -367,7 +367,7 @@ bool Bot::BotCastSlow(Mob* tar, uint8 botLevel, uint8 botClass, BotSpell& botSpe
|
|||||||
if (casted_spell && GetClass() != Class::Bard) {
|
if (casted_spell && GetClass() != Class::Bard) {
|
||||||
if (raid) {
|
if (raid) {
|
||||||
const auto msg = fmt::format("Attempting to slow {}.", tar->GetCleanName());
|
const auto msg = fmt::format("Attempting to slow {}.", tar->GetCleanName());
|
||||||
raid->RaidSay(msg.c_str(), GetCleanName(), 0, 100);
|
raid->RaidSay(msg.c_str(), GetCleanName(), Language::CommonTongue, Language::MaxValue);
|
||||||
} else {
|
} else {
|
||||||
BotGroupSay(
|
BotGroupSay(
|
||||||
this,
|
this,
|
||||||
@@ -1159,7 +1159,7 @@ bool Bot::BotCastHeal(Mob* tar, uint8 botLevel, uint8 botClass, BotSpell& botSpe
|
|||||||
} else if (IsRaidGrouped()) {
|
} else if (IsRaidGrouped()) {
|
||||||
uint32 r_group = raid->GetGroup(GetName());
|
uint32 r_group = raid->GetGroup(GetName());
|
||||||
const auto msg = fmt::format("Casting {}.", spells[botSpell.SpellId].name);
|
const auto msg = fmt::format("Casting {}.", spells[botSpell.SpellId].name);
|
||||||
raid->RaidGroupSay(msg.c_str(), GetCleanName(), 0, 100);
|
raid->RaidGroupSay(msg.c_str(), GetCleanName(), Language::CommonTongue, Language::MaxValue);
|
||||||
std::vector<RaidMember> raid_group_members = raid->GetRaidGroupMembers(r_group);
|
std::vector<RaidMember> raid_group_members = raid->GetRaidGroupMembers(r_group);
|
||||||
for (const auto& rgm : raid_group_members) {
|
for (const auto& rgm : raid_group_members) {
|
||||||
if (rgm.member && !rgm.member->qglobal) {
|
if (rgm.member && !rgm.member->qglobal) {
|
||||||
|
|||||||
@@ -349,10 +349,10 @@ void CheatManager::ProcessMovementHistory(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
void CheatManager::ProcessSpawnApperance(uint16 spawn_id, uint16 type, uint32 parameter)
|
void CheatManager::ProcessSpawnApperance(uint16 spawn_id, uint16 type, uint32 parameter)
|
||||||
{
|
{
|
||||||
if (type == AT_Anim && parameter == ANIM_SIT) {
|
if (type == AppearanceType::Animation && parameter == Animation::Sitting) {
|
||||||
m_time_since_last_memorization = Timer::GetCurrentTime();
|
m_time_since_last_memorization = Timer::GetCurrentTime();
|
||||||
}
|
}
|
||||||
else if (spawn_id == 0 && type == AT_AntiCheat) {
|
else if (spawn_id == 0 && type == AppearanceType::AntiCheat) {
|
||||||
m_time_since_last_action = parameter;
|
m_time_since_last_action = parameter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+238
-167
@@ -58,6 +58,7 @@ extern volatile bool RunLoops;
|
|||||||
#include "mob_movement_manager.h"
|
#include "mob_movement_manager.h"
|
||||||
#include "cheat_manager.h"
|
#include "cheat_manager.h"
|
||||||
|
|
||||||
|
#include "../common/repositories/character_alternate_abilities_repository.h"
|
||||||
#include "../common/repositories/account_flags_repository.h"
|
#include "../common/repositories/account_flags_repository.h"
|
||||||
#include "../common/repositories/bug_reports_repository.h"
|
#include "../common/repositories/bug_reports_repository.h"
|
||||||
#include "../common/repositories/char_recipe_list_repository.h"
|
#include "../common/repositories/char_recipe_list_repository.h"
|
||||||
@@ -86,9 +87,9 @@ Client::Client(EQStreamInterface *ieqs) : Mob(
|
|||||||
"", // in_lastname
|
"", // in_lastname
|
||||||
0, // in_cur_hp
|
0, // in_cur_hp
|
||||||
0, // in_max_hp
|
0, // in_max_hp
|
||||||
0, // in_gender
|
Gender::Male, // in_gender
|
||||||
0, // in_race
|
Race::Doug, // in_race
|
||||||
0, // in_class
|
Class::None, // in_class
|
||||||
BT_Humanoid, // in_bodytype
|
BT_Humanoid, // in_bodytype
|
||||||
0, // in_deity
|
0, // in_deity
|
||||||
0, // in_level
|
0, // in_level
|
||||||
@@ -483,7 +484,7 @@ void Client::SendZoneInPackets()
|
|||||||
// Spawn Appearance Packet
|
// Spawn Appearance Packet
|
||||||
auto outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
|
auto outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
|
||||||
SpawnAppearance_Struct* sa = (SpawnAppearance_Struct*)outapp->pBuffer;
|
SpawnAppearance_Struct* sa = (SpawnAppearance_Struct*)outapp->pBuffer;
|
||||||
sa->type = AT_SpawnID; // Is 0x10 used to set the player id?
|
sa->type = AppearanceType::SpawnID; // Is 0x10 used to set the player id?
|
||||||
sa->parameter = GetID(); // Four bytes for this parameter...
|
sa->parameter = GetID(); // Four bytes for this parameter...
|
||||||
outapp->priority = 6;
|
outapp->priority = 6;
|
||||||
QueuePacket(outapp);
|
QueuePacket(outapp);
|
||||||
@@ -498,7 +499,7 @@ void Client::SendZoneInPackets()
|
|||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
SetSpawned();
|
SetSpawned();
|
||||||
if (GetPVP(false)) //force a PVP update until we fix the spawn struct
|
if (GetPVP(false)) //force a PVP update until we fix the spawn struct
|
||||||
SendAppearancePacket(AT_PVP, GetPVP(false), true, false);
|
SendAppearancePacket(AppearanceType::PVP, GetPVP(false), true, false);
|
||||||
|
|
||||||
//Send AA Exp packet:
|
//Send AA Exp packet:
|
||||||
if (GetLevel() >= 51)
|
if (GetLevel() >= 51)
|
||||||
@@ -586,45 +587,52 @@ void Client::ReportConnectingState() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Client::SaveAA() {
|
bool Client::SaveAA()
|
||||||
std::string iquery;
|
{
|
||||||
int spentpoints = 0;
|
std::vector<CharacterAlternateAbilitiesRepository::CharacterAlternateAbilities> v;
|
||||||
int i = 0;
|
|
||||||
|
uint32 aa_points_spent = 0;
|
||||||
|
|
||||||
|
auto e = CharacterAlternateAbilitiesRepository::NewEntity();
|
||||||
|
|
||||||
for (auto &rank : aa_ranks) {
|
for (auto &rank : aa_ranks) {
|
||||||
AA::Ability *ability = zone->GetAlternateAdvancementAbility(rank.first);
|
auto a = zone->GetAlternateAdvancementAbility(rank.first);
|
||||||
if(!ability)
|
if (!a) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (rank.second.first > 0) {
|
if (rank.second.first > 0) {
|
||||||
AA::Rank *r = ability->GetRankByPointsSpent(rank.second.first);
|
auto r = a->GetRankByPointsSpent(rank.second.first);
|
||||||
|
if (!r) {
|
||||||
if(!r)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
spentpoints += r->total_cost;
|
|
||||||
|
|
||||||
if(i == 0) {
|
|
||||||
iquery = StringFormat("REPLACE INTO `character_alternate_abilities` (id, aa_id, aa_value, charges)"
|
|
||||||
" VALUES (%u, %u, %u, %u)", character_id, ability->first_rank_id, rank.second.first, rank.second.second);
|
|
||||||
} else {
|
|
||||||
iquery += StringFormat(", (%u, %u, %u, %u)", character_id, ability->first_rank_id, rank.second.first, rank.second.second);
|
|
||||||
}
|
}
|
||||||
i++;
|
|
||||||
|
aa_points_spent += r->total_cost;
|
||||||
|
|
||||||
|
e.id = character_id;
|
||||||
|
e.aa_id = a->first_rank_id;
|
||||||
|
e.aa_value = rank.second.first;
|
||||||
|
e.charges = rank.second.second;
|
||||||
|
|
||||||
|
v.emplace_back(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pp.aapoints_spent = spentpoints + m_epp.expended_aa;
|
m_pp.aapoints_spent = aa_points_spent + m_epp.expended_aa;
|
||||||
|
|
||||||
if(iquery.length() > 0) {
|
return CharacterAlternateAbilitiesRepository::ReplaceMany(database, v);
|
||||||
database.QueryDatabase(iquery);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::RemoveExpendedAA(int aa_id)
|
void Client::RemoveExpendedAA(int aa_id)
|
||||||
{
|
{
|
||||||
database.QueryDatabase(StringFormat("DELETE from `character_alternate_abilities` WHERE `id` = %d and `aa_id` = %d", character_id, aa_id));
|
CharacterAlternateAbilitiesRepository::DeleteWhere(
|
||||||
|
database,
|
||||||
|
fmt::format(
|
||||||
|
"`id` = {} AND `aa_id` = {}",
|
||||||
|
CharacterID(),
|
||||||
|
aa_id
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Client::Save(uint8 iCommitNow) {
|
bool Client::Save(uint8 iCommitNow) {
|
||||||
@@ -915,15 +923,19 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
|||||||
// Garble the message based on drunkness
|
// Garble the message based on drunkness
|
||||||
if (GetIntoxication() > 0 && !(RuleB(Chat, ServerWideOOC) && chan_num == ChatChannel_OOC) && !GetGM()) {
|
if (GetIntoxication() > 0 && !(RuleB(Chat, ServerWideOOC) && chan_num == ChatChannel_OOC) && !GetGM()) {
|
||||||
GarbleMessage(message, (int)(GetIntoxication() / 3));
|
GarbleMessage(message, (int)(GetIntoxication() / 3));
|
||||||
language = 0; // No need for language when drunk
|
language = Language::CommonTongue; // No need for language when drunk
|
||||||
lang_skill = 100;
|
lang_skill = Language::MaxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// some channels don't use languages
|
// some channels don't use languages
|
||||||
if (chan_num == ChatChannel_OOC || chan_num == ChatChannel_GMSAY || chan_num == ChatChannel_Broadcast || chan_num == ChatChannel_Petition)
|
if (
|
||||||
{
|
chan_num == ChatChannel_OOC ||
|
||||||
language = 0;
|
chan_num == ChatChannel_GMSAY ||
|
||||||
lang_skill = 100;
|
chan_num == ChatChannel_Broadcast ||
|
||||||
|
chan_num == ChatChannel_Petition
|
||||||
|
) {
|
||||||
|
language = Language::CommonTongue;
|
||||||
|
lang_skill = Language::MaxValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Censor the message
|
// Censor the message
|
||||||
@@ -1274,9 +1286,23 @@ void Client::ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::ChannelMessageSend(const char* from, const char* to, uint8 chan_num, uint8 language, uint8 lang_skill, const char* message, ...) {
|
void Client::ChannelMessageSend(
|
||||||
if ((chan_num==11 && !(GetGM())) || (chan_num==10 && Admin() < AccountStatus::QuestTroupe)) // dont need to send /pr & /petition to everybody
|
const char *from,
|
||||||
|
const char *to,
|
||||||
|
uint8 channel_id,
|
||||||
|
uint8 language_id,
|
||||||
|
uint8 language_skill,
|
||||||
|
const char *message,
|
||||||
|
...
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (
|
||||||
|
(channel_id == ChatChannel_Petition && Admin() < AccountStatus::QuestTroupe) ||
|
||||||
|
(channel_id == ChatChannel_GMSAY && !GetGM())
|
||||||
|
) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
char buffer[4096];
|
char buffer[4096];
|
||||||
char message_sender[64];
|
char message_sender[64];
|
||||||
@@ -1286,57 +1312,62 @@ void Client::ChannelMessageSend(const char* from, const char* to, uint8 chan_num
|
|||||||
va_end(argptr);
|
va_end(argptr);
|
||||||
|
|
||||||
EQApplicationPacket app(OP_ChannelMessage, sizeof(ChannelMessage_Struct) + strlen(buffer) + 1);
|
EQApplicationPacket app(OP_ChannelMessage, sizeof(ChannelMessage_Struct) + strlen(buffer) + 1);
|
||||||
ChannelMessage_Struct* cm = (ChannelMessage_Struct*)app.pBuffer;
|
|
||||||
|
|
||||||
if (from == 0)
|
auto* cm = (ChannelMessage_Struct *) app.pBuffer;
|
||||||
|
|
||||||
|
if (from == 0) {
|
||||||
strcpy(cm->sender, "ZServer");
|
strcpy(cm->sender, "ZServer");
|
||||||
else if (from[0] == 0)
|
} else if (from[0] == 0) {
|
||||||
strcpy(cm->sender, "ZServer");
|
strcpy(cm->sender, "ZServer");
|
||||||
else {
|
} else {
|
||||||
CleanMobName(from, message_sender);
|
CleanMobName(from, message_sender);
|
||||||
strcpy(cm->sender, message_sender);
|
strcpy(cm->sender, message_sender);
|
||||||
}
|
}
|
||||||
if (to != 0)
|
|
||||||
|
if (to != 0) {
|
||||||
strcpy((char *) cm->targetname, to);
|
strcpy((char *) cm->targetname, to);
|
||||||
else if (chan_num == ChatChannel_Tell)
|
} else if (channel_id == ChatChannel_Tell) {
|
||||||
strcpy(cm->targetname, m_pp.name);
|
strcpy(cm->targetname, m_pp.name);
|
||||||
else
|
} else {
|
||||||
cm->targetname[0] = 0;
|
cm->targetname[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint8 ListenerSkill;
|
uint8 listener_skill;
|
||||||
|
|
||||||
if (language < MAX_PP_LANGUAGE) {
|
const bool is_valid_language = EQ::ValueWithin(language_id, Language::CommonTongue, Language::Unknown27);
|
||||||
ListenerSkill = m_pp.languages[language];
|
|
||||||
if (ListenerSkill < 24) {
|
if (is_valid_language) {
|
||||||
cm->language = (MAX_PP_LANGUAGE - 1); // in an unknown tongue
|
listener_skill = m_pp.languages[language_id];
|
||||||
}
|
cm->language = listener_skill < 24 ? Language::Unknown27 : language_id;
|
||||||
else {
|
} else {
|
||||||
cm->language = language;
|
listener_skill = m_pp.languages[Language::CommonTongue];
|
||||||
}
|
cm->language = Language::CommonTongue;
|
||||||
}
|
|
||||||
else {
|
|
||||||
ListenerSkill = m_pp.languages[0];
|
|
||||||
cm->language = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set effective language skill = lower of sender and receiver skills
|
// set effective language skill = lower of sender and receiver skills
|
||||||
int32 EffSkill = (lang_skill < ListenerSkill ? lang_skill : ListenerSkill);
|
uint8 effective_skill = (language_skill < listener_skill ? language_skill : listener_skill);
|
||||||
if (EffSkill > 100) // maximum language skill is 100
|
if (effective_skill > Language::MaxValue) {
|
||||||
EffSkill = 100;
|
effective_skill = Language::MaxValue;
|
||||||
cm->skill_in_language = EffSkill;
|
}
|
||||||
|
|
||||||
cm->chan_num = chan_num;
|
cm->skill_in_language = effective_skill;
|
||||||
|
|
||||||
|
cm->chan_num = channel_id;
|
||||||
strcpy(&cm->message[0], buffer);
|
strcpy(&cm->message[0], buffer);
|
||||||
|
|
||||||
QueuePacket(&app);
|
QueuePacket(&app);
|
||||||
|
|
||||||
bool senderCanTrainSelf = RuleB(Client, SelfLanguageLearning);
|
const bool can_train_self = RuleB(Client, SelfLanguageLearning);
|
||||||
bool weAreNotSender = strcmp(GetCleanName(), cm->sender);
|
const bool is_not_sender = strcmp(GetCleanName(), cm->sender);
|
||||||
|
|
||||||
if (senderCanTrainSelf || weAreNotSender) {
|
if (can_train_self || is_not_sender) {
|
||||||
if ((chan_num == ChatChannel_Group) && (ListenerSkill < 100)) { // group message in unmastered language, check for skill up
|
if (
|
||||||
if (language < MAX_PP_LANGUAGE && m_pp.languages[language] <= lang_skill)
|
channel_id == ChatChannel_Group &&
|
||||||
CheckLanguageSkillIncrease(language, lang_skill);
|
listener_skill < Language::MaxValue
|
||||||
|
) { // group message in non-mastered language, check for skill up
|
||||||
|
if (is_valid_language && m_pp.languages[language_id] <= language_skill) {
|
||||||
|
CheckLanguageSkillIncrease(language_id, language_skill);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1637,26 +1668,30 @@ void Client::SetSkill(EQ::skills::SkillType skillid, uint16 value) {
|
|||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::IncreaseLanguageSkill(int skill_id, int value) {
|
void Client::IncreaseLanguageSkill(uint8 language_id, uint8 increase)
|
||||||
|
{
|
||||||
|
if (!EQ::ValueWithin(language_id, Language::CommonTongue, Language::Unknown27)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (skill_id >= MAX_PP_LANGUAGE)
|
m_pp.languages[language_id] += increase;
|
||||||
return; //Invalid lang id
|
|
||||||
|
|
||||||
m_pp.languages[skill_id] += value;
|
if (m_pp.languages[language_id] > Language::MaxValue) {
|
||||||
|
m_pp.languages[language_id] = Language::MaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
if (m_pp.languages[skill_id] > 100) //Lang skill above max
|
database.SaveCharacterLanguage(CharacterID(), language_id, m_pp.languages[language_id]);
|
||||||
m_pp.languages[skill_id] = 100;
|
|
||||||
|
|
||||||
database.SaveCharacterLanguage(CharacterID(), skill_id, m_pp.languages[skill_id]);
|
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_SkillUpdate, sizeof(SkillUpdate_Struct));
|
auto outapp = new EQApplicationPacket(OP_SkillUpdate, sizeof(SkillUpdate_Struct));
|
||||||
SkillUpdate_Struct* skill = (SkillUpdate_Struct*)outapp->pBuffer;
|
auto* s = (SkillUpdate_Struct*) outapp->pBuffer;
|
||||||
skill->skillId = 100 + skill_id;
|
|
||||||
skill->value = m_pp.languages[skill_id];
|
s->skillId = 100 + language_id;
|
||||||
|
s->value = m_pp.languages[language_id];
|
||||||
|
|
||||||
QueuePacket(outapp);
|
QueuePacket(outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
|
|
||||||
MessageString( Chat::Skills, LANG_SKILL_IMPROVED ); //Notify client
|
MessageString(Chat::Skills, LANG_SKILL_IMPROVED);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::AddSkill(EQ::skills::SkillType skillid, uint16 value) {
|
void Client::AddSkill(EQ::skills::SkillType skillid, uint16 value) {
|
||||||
@@ -2221,7 +2256,7 @@ void Client::SetGM(bool toggle) {
|
|||||||
m_pp.gm ? "now" : "no longer"
|
m_pp.gm ? "now" : "no longer"
|
||||||
).c_str()
|
).c_str()
|
||||||
);
|
);
|
||||||
SendAppearancePacket(AT_GM, m_pp.gm);
|
SendAppearancePacket(AppearanceType::GM, m_pp.gm);
|
||||||
Save();
|
Save();
|
||||||
UpdateWho();
|
UpdateWho();
|
||||||
}
|
}
|
||||||
@@ -2272,9 +2307,9 @@ void Client::ReadBook(BookRequest_Struct *book) {
|
|||||||
|
|
||||||
memcpy(out->booktext, booktxt2.c_str(), length);
|
memcpy(out->booktext, booktxt2.c_str(), length);
|
||||||
|
|
||||||
if (book_language > 0 && book_language < MAX_PP_LANGUAGE) {
|
if (EQ::ValueWithin(book_language, Language::CommonTongue, Language::Unknown27)) {
|
||||||
if (m_pp.languages[book_language] < 100) {
|
if (m_pp.languages[book_language] < Language::MaxValue) {
|
||||||
GarbleMessage(out->booktext, (100 - m_pp.languages[book_language]));
|
GarbleMessage(out->booktext, (Language::MaxValue - m_pp.languages[book_language]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2673,38 +2708,43 @@ bool Client::CheckIncreaseSkill(EQ::skills::SkillType skillid, Mob *against_who,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::CheckLanguageSkillIncrease(uint8 langid, uint8 TeacherSkill) {
|
void Client::CheckLanguageSkillIncrease(uint8 language_id, uint8 teacher_skill) {
|
||||||
if (IsDead() || IsUnconscious())
|
if (IsDead() || IsUnconscious()) {
|
||||||
return;
|
return;
|
||||||
if (IsAIControlled())
|
}
|
||||||
|
|
||||||
|
if (IsAIControlled()) {
|
||||||
return;
|
return;
|
||||||
if (langid >= MAX_PP_LANGUAGE)
|
}
|
||||||
return; // do nothing if langid is an invalid language
|
|
||||||
|
|
||||||
int LangSkill = m_pp.languages[langid]; // get current language skill
|
if (!EQ::ValueWithin(language_id, Language::CommonTongue, Language::Unknown27)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (LangSkill < 100) { // if the language isn't already maxed
|
const uint8 language_skill = m_pp.languages[language_id]; // get current language skill
|
||||||
int32 Chance = 5 + ((TeacherSkill - LangSkill)/10); // greater chance to learn if teacher's skill is much higher than yours
|
|
||||||
Chance = (Chance * RuleI(Character, SkillUpModifier)/100);
|
|
||||||
|
|
||||||
if(zone->random.Real(0,100) < Chance) { // if they make the roll
|
if (language_skill < Language::MaxValue) { // if the language isn't already maxed
|
||||||
IncreaseLanguageSkill(langid); // increase the language skill by 1
|
int chance = 5 + ((teacher_skill - language_skill) / 10); // greater chance to learn if teacher's skill is much higher than yours
|
||||||
|
chance = (chance * RuleI(Character, SkillUpModifier) / 100);
|
||||||
|
|
||||||
|
if (zone->random.Real(0, 100) < chance) { // if they make the roll
|
||||||
|
IncreaseLanguageSkill(language_id);
|
||||||
|
|
||||||
if (parse->PlayerHasQuestSub(EVENT_LANGUAGE_SKILL_UP)) {
|
if (parse->PlayerHasQuestSub(EVENT_LANGUAGE_SKILL_UP)) {
|
||||||
const auto &export_string = fmt::format(
|
const auto &export_string = fmt::format(
|
||||||
"{} {} {}",
|
"{} {} {}",
|
||||||
langid,
|
language_id,
|
||||||
LangSkill + 1,
|
language_skill + 1,
|
||||||
100
|
Language::MaxValue
|
||||||
);
|
);
|
||||||
|
|
||||||
parse->EventPlayer(EVENT_LANGUAGE_SKILL_UP, this, export_string, 0);
|
parse->EventPlayer(EVENT_LANGUAGE_SKILL_UP, this, export_string, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogSkills("Language [{}] at value [{}] successfully gain with [{}] % chance", langid, LangSkill, Chance);
|
LogSkills("Language [{}] at value [{}] successfully gain with [{}] % chance", language_id, language_skill, chance);
|
||||||
|
} else {
|
||||||
|
LogSkills("Language [{}] at value [{}] failed to gain with [{}] % chance", language_id, language_skill, chance);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
LogSkills("Language [{}] at value [{}] failed to gain with [{}] % chance", langid, LangSkill, Chance);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2839,7 +2879,7 @@ void Client::SetPVP(bool toggle, bool message) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SendAppearancePacket(AT_PVP, GetPVP());
|
SendAppearancePacket(AppearanceType::PVP, GetPVP());
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3566,25 +3606,30 @@ void Client::SetHideMe(bool flag)
|
|||||||
UpdateWho();
|
UpdateWho();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::SetLanguageSkill(int langid, int value)
|
void Client::SetLanguageSkill(uint8 language_id, uint8 language_skill)
|
||||||
{
|
{
|
||||||
if (langid >= MAX_PP_LANGUAGE)
|
if (!EQ::ValueWithin(language_id, Language::CommonTongue, Language::Unknown27)) {
|
||||||
return; //Invalid Language
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (value > 100)
|
if (language_skill > Language::MaxValue) {
|
||||||
value = 100; //Max lang value
|
language_skill = Language::MaxValue;
|
||||||
|
}
|
||||||
|
|
||||||
m_pp.languages[langid] = value;
|
m_pp.languages[language_id] = language_skill;
|
||||||
database.SaveCharacterLanguage(CharacterID(), langid, value);
|
|
||||||
|
database.SaveCharacterLanguage(CharacterID(), language_id, language_skill);
|
||||||
|
|
||||||
auto outapp = new EQApplicationPacket(OP_SkillUpdate, sizeof(SkillUpdate_Struct));
|
auto outapp = new EQApplicationPacket(OP_SkillUpdate, sizeof(SkillUpdate_Struct));
|
||||||
SkillUpdate_Struct* skill = (SkillUpdate_Struct*)outapp->pBuffer;
|
auto* s = (SkillUpdate_Struct*) outapp->pBuffer;
|
||||||
skill->skillId = 100 + langid;
|
|
||||||
skill->value = m_pp.languages[langid];
|
s->skillId = 100 + language_id;
|
||||||
|
s->value = m_pp.languages[language_id];
|
||||||
|
|
||||||
QueuePacket(outapp);
|
QueuePacket(outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
|
|
||||||
MessageString( Chat::Skills, LANG_SKILL_IMPROVED ); //Notify the client
|
MessageString(Chat::Skills, LANG_SKILL_IMPROVED);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::LinkDead()
|
void Client::LinkDead()
|
||||||
@@ -3607,7 +3652,7 @@ void Client::LinkDead()
|
|||||||
|
|
||||||
// save_timer.Start(2500);
|
// save_timer.Start(2500);
|
||||||
linkdead_timer.Start(RuleI(Zone,ClientLinkdeadMS));
|
linkdead_timer.Start(RuleI(Zone,ClientLinkdeadMS));
|
||||||
SendAppearancePacket(AT_Linkdead, 1);
|
SendAppearancePacket(AppearanceType::Linkdead, 1);
|
||||||
client_state = CLIENT_LINKDEAD;
|
client_state = CLIENT_LINKDEAD;
|
||||||
AI_Start(CLIENT_LD_TIMEOUT);
|
AI_Start(CLIENT_LD_TIMEOUT);
|
||||||
}
|
}
|
||||||
@@ -3750,7 +3795,7 @@ void Client::EnteringMessages(Client* client)
|
|||||||
).c_str()
|
).c_str()
|
||||||
);
|
);
|
||||||
|
|
||||||
client->SendAppearancePacket(AT_Anim, ANIM_FREEZE);
|
client->SendAppearancePacket(AppearanceType::Animation, Animation::Freeze);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4599,7 +4644,7 @@ void Client::ClearGroupAAs() {
|
|||||||
m_pp.raid_leadership_exp = 0;
|
m_pp.raid_leadership_exp = 0;
|
||||||
|
|
||||||
Save();
|
Save();
|
||||||
database.SaveCharacterLeadershipAA(CharacterID(), &m_pp);
|
database.SaveCharacterLeadershipAbilities(CharacterID(), &m_pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::UpdateGroupAAs(int32 points, uint32 type) {
|
void Client::UpdateGroupAAs(int32 points, uint32 type) {
|
||||||
@@ -6519,27 +6564,33 @@ void Client::RemoveFromInstance(uint16 instance_id)
|
|||||||
|
|
||||||
void Client::SendAltCurrencies() {
|
void Client::SendAltCurrencies() {
|
||||||
if (ClientVersion() >= EQ::versions::ClientVersion::SoF) {
|
if (ClientVersion() >= EQ::versions::ClientVersion::SoF) {
|
||||||
uint32 count = zone->AlternateCurrencies.size();
|
const uint32 currency_count = zone->AlternateCurrencies.size();
|
||||||
if(count == 0) {
|
if (!currency_count) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto outapp =
|
auto outapp = new EQApplicationPacket(
|
||||||
new EQApplicationPacket(OP_AltCurrency, sizeof(AltCurrencyPopulate_Struct) +
|
OP_AltCurrency,
|
||||||
sizeof(AltCurrencyPopulateEntry_Struct) * count);
|
sizeof(AltCurrencyPopulate_Struct) +
|
||||||
AltCurrencyPopulate_Struct *altc = (AltCurrencyPopulate_Struct*)outapp->pBuffer;
|
sizeof(AltCurrencyPopulateEntry_Struct) * currency_count
|
||||||
altc->opcode = ALT_CURRENCY_OP_POPULATE;
|
);
|
||||||
altc->count = count;
|
|
||||||
|
auto a = (AltCurrencyPopulate_Struct*) outapp->pBuffer;
|
||||||
|
|
||||||
|
a->opcode = AlternateCurrencyMode::Populate;
|
||||||
|
a->count = currency_count;
|
||||||
|
|
||||||
uint32 currency_id = 0;
|
uint32 currency_id = 0;
|
||||||
for (const auto& alternate_currency : zone->AlternateCurrencies) {
|
for (const auto& c : zone->AlternateCurrencies) {
|
||||||
const EQ::ItemData* item = database.GetItem(alternate_currency.item_id);
|
const auto* item = database.GetItem(c.item_id);
|
||||||
altc->entries[currency_id].currency_number = alternate_currency.id;
|
|
||||||
altc->entries[currency_id].unknown00 = 1;
|
a->entries[currency_id].currency_number = c.id;
|
||||||
altc->entries[currency_id].currency_number2 = alternate_currency.id;
|
a->entries[currency_id].unknown00 = 1;
|
||||||
altc->entries[currency_id].item_id = alternate_currency.item_id;
|
a->entries[currency_id].currency_number2 = c.id;
|
||||||
altc->entries[currency_id].item_icon = item ? item->Icon : 1000;
|
a->entries[currency_id].item_id = c.item_id;
|
||||||
altc->entries[currency_id].stack_size = item ? item->StackSize : 1000;
|
a->entries[currency_id].item_icon = item ? item->Icon : 1000;
|
||||||
|
a->entries[currency_id].stack_size = item ? item->StackSize : 1000;
|
||||||
|
|
||||||
currency_id++;
|
currency_id++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6636,11 +6687,8 @@ void Client::SendAlternateCurrencyValue(uint32 currency_id, bool send_if_null)
|
|||||||
uint32 Client::GetAlternateCurrencyValue(uint32 currency_id) const
|
uint32 Client::GetAlternateCurrencyValue(uint32 currency_id) const
|
||||||
{
|
{
|
||||||
auto iter = alternate_currency.find(currency_id);
|
auto iter = alternate_currency.find(currency_id);
|
||||||
if(iter == alternate_currency.end()) {
|
|
||||||
return 0;
|
return iter == alternate_currency.end() ? 0 : (*iter).second;
|
||||||
} else {
|
|
||||||
return (*iter).second;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::ProcessAlternateCurrencyQueue() {
|
void Client::ProcessAlternateCurrencyQueue() {
|
||||||
@@ -8565,37 +8613,37 @@ bool Client::CanMedOnHorse()
|
|||||||
void Client::EnableAreaHPRegen(int value)
|
void Client::EnableAreaHPRegen(int value)
|
||||||
{
|
{
|
||||||
AreaHPRegen = value * 0.001f;
|
AreaHPRegen = value * 0.001f;
|
||||||
SendAppearancePacket(AT_AreaHPRegen, value, false);
|
SendAppearancePacket(AppearanceType::AreaHealthRegen, value, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::DisableAreaHPRegen()
|
void Client::DisableAreaHPRegen()
|
||||||
{
|
{
|
||||||
AreaHPRegen = 1.0f;
|
AreaHPRegen = 1.0f;
|
||||||
SendAppearancePacket(AT_AreaHPRegen, 1000, false);
|
SendAppearancePacket(AppearanceType::AreaHealthRegen, 1000, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::EnableAreaManaRegen(int value)
|
void Client::EnableAreaManaRegen(int value)
|
||||||
{
|
{
|
||||||
AreaManaRegen = value * 0.001f;
|
AreaManaRegen = value * 0.001f;
|
||||||
SendAppearancePacket(AT_AreaManaRegen, value, false);
|
SendAppearancePacket(AppearanceType::AreaManaRegen, value, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::DisableAreaManaRegen()
|
void Client::DisableAreaManaRegen()
|
||||||
{
|
{
|
||||||
AreaManaRegen = 1.0f;
|
AreaManaRegen = 1.0f;
|
||||||
SendAppearancePacket(AT_AreaManaRegen, 1000, false);
|
SendAppearancePacket(AppearanceType::AreaManaRegen, 1000, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::EnableAreaEndRegen(int value)
|
void Client::EnableAreaEndRegen(int value)
|
||||||
{
|
{
|
||||||
AreaEndRegen = value * 0.001f;
|
AreaEndRegen = value * 0.001f;
|
||||||
SendAppearancePacket(AT_AreaEndRegen, value, false);
|
SendAppearancePacket(AppearanceType::AreaEnduranceRegen, value, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::DisableAreaEndRegen()
|
void Client::DisableAreaEndRegen()
|
||||||
{
|
{
|
||||||
AreaEndRegen = 1.0f;
|
AreaEndRegen = 1.0f;
|
||||||
SendAppearancePacket(AT_AreaEndRegen, 1000, false);
|
SendAppearancePacket(AppearanceType::AreaEnduranceRegen, 1000, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::EnableAreaRegens(int value)
|
void Client::EnableAreaRegens(int value)
|
||||||
@@ -10011,7 +10059,7 @@ void Client::SetAnon(uint8 anon_flag) {
|
|||||||
auto outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
|
auto outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
|
||||||
SpawnAppearance_Struct* spawn_appearance = (SpawnAppearance_Struct*)outapp->pBuffer;
|
SpawnAppearance_Struct* spawn_appearance = (SpawnAppearance_Struct*)outapp->pBuffer;
|
||||||
spawn_appearance->spawn_id = GetID();
|
spawn_appearance->spawn_id = GetID();
|
||||||
spawn_appearance->type = AT_Anon;
|
spawn_appearance->type = AppearanceType::Anonymous;
|
||||||
spawn_appearance->parameter = anon_flag;
|
spawn_appearance->parameter = anon_flag;
|
||||||
entity_list.QueueClients(this, outapp);
|
entity_list.QueueClients(this, outapp);
|
||||||
Save();
|
Save();
|
||||||
@@ -10024,7 +10072,7 @@ void Client::SetAFK(uint8 afk_flag) {
|
|||||||
auto outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
|
auto outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
|
||||||
SpawnAppearance_Struct* spawn_appearance = (SpawnAppearance_Struct*)outapp->pBuffer;
|
SpawnAppearance_Struct* spawn_appearance = (SpawnAppearance_Struct*)outapp->pBuffer;
|
||||||
spawn_appearance->spawn_id = GetID();
|
spawn_appearance->spawn_id = GetID();
|
||||||
spawn_appearance->type = AT_AFK;
|
spawn_appearance->type = AppearanceType::AFK;
|
||||||
spawn_appearance->parameter = afk_flag;
|
spawn_appearance->parameter = afk_flag;
|
||||||
entity_list.QueueClients(this, outapp);
|
entity_list.QueueClients(this, outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
@@ -10269,7 +10317,7 @@ void Client::RemoveItem(uint32 item_id, uint32 quantity)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::SetGMStatus(int16 new_status) {
|
void Client::SetGMStatus(int new_status) {
|
||||||
if (Admin() != new_status) {
|
if (Admin() != new_status) {
|
||||||
database.UpdateGMStatus(AccountID(), new_status);
|
database.UpdateGMStatus(AccountID(), new_status);
|
||||||
UpdateAdmin();
|
UpdateAdmin();
|
||||||
@@ -10546,9 +10594,9 @@ void Client::ReadBookByName(std::string book_name, uint8 book_type)
|
|||||||
|
|
||||||
memcpy(out->booktext, book_text.c_str(), length);
|
memcpy(out->booktext, book_text.c_str(), length);
|
||||||
|
|
||||||
if (book_language > 0 && book_language < MAX_PP_LANGUAGE) {
|
if (EQ::ValueWithin(book_language, Language::CommonTongue, Language::Unknown27)) {
|
||||||
if (m_pp.languages[book_language] < 100) {
|
if (m_pp.languages[book_language] < Language::MaxValue) {
|
||||||
GarbleMessage(out->booktext, (100 - m_pp.languages[book_language]));
|
GarbleMessage(out->booktext, (Language::MaxValue - m_pp.languages[book_language]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10697,22 +10745,22 @@ void Client::SaveSpells()
|
|||||||
|
|
||||||
void Client::SaveDisciplines()
|
void Client::SaveDisciplines()
|
||||||
{
|
{
|
||||||
std::vector<CharacterDisciplinesRepository::CharacterDisciplines> character_discs = {};
|
std::vector<CharacterDisciplinesRepository::CharacterDisciplines> v;
|
||||||
|
|
||||||
for (int index = 0; index < MAX_PP_DISCIPLINES; index++) {
|
for (int slot_id = 0; slot_id < MAX_PP_DISCIPLINES; slot_id++) {
|
||||||
if (IsValidSpell(m_pp.disciplines.values[index])) {
|
if (IsValidSpell(m_pp.disciplines.values[slot_id])) {
|
||||||
auto discipline = CharacterDisciplinesRepository::NewEntity();
|
auto e = CharacterDisciplinesRepository::NewEntity();
|
||||||
discipline.id = CharacterID();
|
|
||||||
discipline.slot_id = index;
|
e.id = CharacterID();
|
||||||
discipline.disc_id = m_pp.disciplines.values[index];
|
e.slot_id = slot_id;
|
||||||
character_discs.emplace_back(discipline);
|
e.disc_id = m_pp.disciplines.values[slot_id];
|
||||||
|
|
||||||
|
v.emplace_back(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CharacterDisciplinesRepository::DeleteWhere(database, fmt::format("id = {}", CharacterID()));
|
if (!v.empty()) {
|
||||||
|
CharacterDisciplinesRepository::ReplaceMany(database, v);
|
||||||
if (!character_discs.empty()) {
|
|
||||||
CharacterDisciplinesRepository::InsertMany(database, character_discs);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10883,8 +10931,8 @@ void Client::ReconnectUCS()
|
|||||||
|
|
||||||
buffer = StringFormat(
|
buffer = StringFormat(
|
||||||
"%s,%i,%s.%s,%c%s",
|
"%s,%i,%s.%s,%c%s",
|
||||||
Config->ChatHost.c_str(),
|
Config->GetUCSHost().c_str(),
|
||||||
Config->ChatPort,
|
Config->GetUCSPort(),
|
||||||
Config->ShortName.c_str(),
|
Config->ShortName.c_str(),
|
||||||
GetName(),
|
GetName(),
|
||||||
connection_type,
|
connection_type,
|
||||||
@@ -10910,8 +10958,8 @@ void Client::ReconnectUCS()
|
|||||||
|
|
||||||
buffer = StringFormat(
|
buffer = StringFormat(
|
||||||
"%s,%i,%s.%s,%c%s",
|
"%s,%i,%s.%s,%c%s",
|
||||||
Config->MailHost.c_str(),
|
Config->GetUCSHost().c_str(),
|
||||||
Config->MailPort,
|
Config->GetUCSPort(),
|
||||||
Config->ShortName.c_str(),
|
Config->ShortName.c_str(),
|
||||||
GetName(),
|
GetName(),
|
||||||
connection_type,
|
connection_type,
|
||||||
@@ -11224,7 +11272,7 @@ void Client::Undye()
|
|||||||
SendWearChange(slot);
|
SendWearChange(slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
database.DeleteCharacterDye(CharacterID());
|
database.DeleteCharacterMaterialColor(CharacterID());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Client::SetTrackingID(uint32 entity_id)
|
void Client::SetTrackingID(uint32 entity_id)
|
||||||
@@ -11944,3 +11992,26 @@ std::string GetZoneModeString(ZoneMode mode)
|
|||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::ClearXTargets()
|
||||||
|
{
|
||||||
|
if (!XTargettingAvailable()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < GetMaxXTargets(); ++i) {
|
||||||
|
if (XTargets[i].ID) {
|
||||||
|
Mob* m = entity_list.GetMob(XTargets[i].ID);
|
||||||
|
|
||||||
|
if (m) {
|
||||||
|
RemoveXTarget(m, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
XTargets[i].ID = 0;
|
||||||
|
XTargets[i].Name[0] = 0;
|
||||||
|
XTargets[i].dirty = false;
|
||||||
|
|
||||||
|
SendXTargetPacket(i, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+9
-7
@@ -335,7 +335,7 @@ public:
|
|||||||
void QueuePacket(const EQApplicationPacket* app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL, eqFilterType filter=FilterNone);
|
void QueuePacket(const EQApplicationPacket* app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL, eqFilterType filter=FilterNone);
|
||||||
void FastQueuePacket(EQApplicationPacket** app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL);
|
void FastQueuePacket(EQApplicationPacket** app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL);
|
||||||
void ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_skill, const char* orig_message, const char* targetname = nullptr, bool is_silent = false);
|
void ChannelMessageReceived(uint8 chan_num, uint8 language, uint8 lang_skill, const char* orig_message, const char* targetname = nullptr, bool is_silent = false);
|
||||||
void ChannelMessageSend(const char* from, const char* to, uint8 chan_num, uint8 language, uint8 lang_skill, const char* message, ...);
|
void ChannelMessageSend(const char* from, const char* to, uint8 channel_id, uint8 language_id, uint8 language_skill, const char* message, ...);
|
||||||
void Message(uint32 type, const char* message, ...);
|
void Message(uint32 type, const char* message, ...);
|
||||||
void FilteredMessage(Mob *sender, uint32 type, eqFilterType filter, const char* message, ...);
|
void FilteredMessage(Mob *sender, uint32 type, eqFilterType filter, const char* message, ...);
|
||||||
void VoiceMacroReceived(uint32 Type, char *Target, uint32 MacroNumber);
|
void VoiceMacroReceived(uint32 Type, char *Target, uint32 MacroNumber);
|
||||||
@@ -382,7 +382,7 @@ public:
|
|||||||
inline ExtendedProfile_Struct& GetEPP() { return m_epp; }
|
inline ExtendedProfile_Struct& GetEPP() { return m_epp; }
|
||||||
inline EQ::InventoryProfile& GetInv() { return m_inv; }
|
inline EQ::InventoryProfile& GetInv() { return m_inv; }
|
||||||
inline const EQ::InventoryProfile& GetInv() const { return m_inv; }
|
inline const EQ::InventoryProfile& GetInv() const { return m_inv; }
|
||||||
inline PetInfo* GetPetInfo(uint16 pet) { return (pet==1)?&m_suspendedminion:&m_petinfo; }
|
inline PetInfo* GetPetInfo(int pet_info_type) { return pet_info_type == PetInfoType::Suspended ? &m_suspendedminion : &m_petinfo; }
|
||||||
inline InspectMessage_Struct& GetInspectMessage() { return m_inspect_message; }
|
inline InspectMessage_Struct& GetInspectMessage() { return m_inspect_message; }
|
||||||
inline const InspectMessage_Struct& GetInspectMessage() const { return m_inspect_message; }
|
inline const InspectMessage_Struct& GetInspectMessage() const { return m_inspect_message; }
|
||||||
void ReloadExpansionProfileSetting();
|
void ReloadExpansionProfileSetting();
|
||||||
@@ -452,7 +452,7 @@ public:
|
|||||||
void SendSingleTraderItem(uint32 char_id, int uniqueid);
|
void SendSingleTraderItem(uint32 char_id, int uniqueid);
|
||||||
void BulkSendMerchantInventory(int merchant_id, int npcid);
|
void BulkSendMerchantInventory(int merchant_id, int npcid);
|
||||||
|
|
||||||
inline uint8 GetLanguageSkill(uint16 n) const { return m_pp.languages[n]; }
|
inline uint8 GetLanguageSkill(uint8 language_id) const { return m_pp.languages[language_id]; }
|
||||||
|
|
||||||
void SendPickPocketResponse(Mob *from, uint32 amt, int type, const EQ::ItemData* item = nullptr);
|
void SendPickPocketResponse(Mob *from, uint32 amt, int type, const EQ::ItemData* item = nullptr);
|
||||||
|
|
||||||
@@ -767,7 +767,7 @@ public:
|
|||||||
void SetSkillPoints(int inp) { m_pp.points = inp;}
|
void SetSkillPoints(int inp) { m_pp.points = inp;}
|
||||||
|
|
||||||
void IncreaseSkill(int skill_id, int value = 1) { if (skill_id <= EQ::skills::HIGHEST_SKILL) { m_pp.skills[skill_id] += value; } }
|
void IncreaseSkill(int skill_id, int value = 1) { if (skill_id <= EQ::skills::HIGHEST_SKILL) { m_pp.skills[skill_id] += value; } }
|
||||||
void IncreaseLanguageSkill(int skill_id, int value = 1);
|
void IncreaseLanguageSkill(uint8 language_id, uint8 increase = 1);
|
||||||
virtual uint16 GetSkill(EQ::skills::SkillType skill_id) const { if (skill_id <= EQ::skills::HIGHEST_SKILL) { return(itembonuses.skillmod[skill_id] > 0 ? (itembonuses.skillmodmax[skill_id] > 0 ? std::min(m_pp.skills[skill_id] + itembonuses.skillmodmax[skill_id], m_pp.skills[skill_id] * (100 + itembonuses.skillmod[skill_id]) / 100) : m_pp.skills[skill_id] * (100 + itembonuses.skillmod[skill_id]) / 100) : m_pp.skills[skill_id]); } return 0; }
|
virtual uint16 GetSkill(EQ::skills::SkillType skill_id) const { if (skill_id <= EQ::skills::HIGHEST_SKILL) { return(itembonuses.skillmod[skill_id] > 0 ? (itembonuses.skillmodmax[skill_id] > 0 ? std::min(m_pp.skills[skill_id] + itembonuses.skillmodmax[skill_id], m_pp.skills[skill_id] * (100 + itembonuses.skillmod[skill_id]) / 100) : m_pp.skills[skill_id] * (100 + itembonuses.skillmod[skill_id]) / 100) : m_pp.skills[skill_id]); } return 0; }
|
||||||
uint32 GetRawSkill(EQ::skills::SkillType skill_id) const { if (skill_id <= EQ::skills::HIGHEST_SKILL) { return(m_pp.skills[skill_id]); } return 0; }
|
uint32 GetRawSkill(EQ::skills::SkillType skill_id) const { if (skill_id <= EQ::skills::HIGHEST_SKILL) { return(m_pp.skills[skill_id]); } return 0; }
|
||||||
bool HasSkill(EQ::skills::SkillType skill_id) const;
|
bool HasSkill(EQ::skills::SkillType skill_id) const;
|
||||||
@@ -777,8 +777,8 @@ public:
|
|||||||
void CheckSpecializeIncrease(uint16 spell_id);
|
void CheckSpecializeIncrease(uint16 spell_id);
|
||||||
void CheckSongSkillIncrease(uint16 spell_id);
|
void CheckSongSkillIncrease(uint16 spell_id);
|
||||||
bool CheckIncreaseSkill(EQ::skills::SkillType skillid, Mob *against_who, int chancemodi = 0);
|
bool CheckIncreaseSkill(EQ::skills::SkillType skillid, Mob *against_who, int chancemodi = 0);
|
||||||
void CheckLanguageSkillIncrease(uint8 langid, uint8 TeacherSkill);
|
void CheckLanguageSkillIncrease(uint8 language_id, uint8 teacher_skill);
|
||||||
void SetLanguageSkill(int langid, int value);
|
void SetLanguageSkill(uint8 language_id, uint8 language_skill);
|
||||||
void SetHoTT(uint32 mobid);
|
void SetHoTT(uint32 mobid);
|
||||||
void ShowSkillsWindow();
|
void ShowSkillsWindow();
|
||||||
|
|
||||||
@@ -988,6 +988,7 @@ public:
|
|||||||
void IncStats(uint8 type,int16 increase_val);
|
void IncStats(uint8 type,int16 increase_val);
|
||||||
void DropItem(int16 slot_id, bool recurse = true);
|
void DropItem(int16 slot_id, bool recurse = true);
|
||||||
void DropItemQS(EQ::ItemInstance* inst, bool pickup);
|
void DropItemQS(EQ::ItemInstance* inst, bool pickup);
|
||||||
|
bool HasItemOnCorpse(uint32 item_id);
|
||||||
|
|
||||||
bool IsAugmentRestricted(uint8 item_type, uint32 augment_restriction);
|
bool IsAugmentRestricted(uint8 item_type, uint32 augment_restriction);
|
||||||
|
|
||||||
@@ -1527,6 +1528,7 @@ public:
|
|||||||
void JoinGroupXTargets(Group *g);
|
void JoinGroupXTargets(Group *g);
|
||||||
void LeaveGroupXTargets(Group *g);
|
void LeaveGroupXTargets(Group *g);
|
||||||
void LeaveRaidXTargets(Raid *r);
|
void LeaveRaidXTargets(Raid *r);
|
||||||
|
void ClearXTargets();
|
||||||
bool GroupFollow(Client* inviter);
|
bool GroupFollow(Client* inviter);
|
||||||
inline bool GetRunMode() const { return runmode; }
|
inline bool GetRunMode() const { return runmode; }
|
||||||
|
|
||||||
@@ -1605,7 +1607,7 @@ public:
|
|||||||
void SetAccountFlag(const std::string& flag, const std::string& value);
|
void SetAccountFlag(const std::string& flag, const std::string& value);
|
||||||
std::string GetAccountFlag(const std::string& flag);
|
std::string GetAccountFlag(const std::string& flag);
|
||||||
std::vector<std::string> GetAccountFlags();
|
std::vector<std::string> GetAccountFlags();
|
||||||
void SetGMStatus(int16 new_status);
|
void SetGMStatus(int new_status);
|
||||||
void Consume(const EQ::ItemData *item, uint8 type, int16 slot, bool auto_consume);
|
void Consume(const EQ::ItemData *item, uint8 type, int16 slot, bool auto_consume);
|
||||||
void PlayMP3(const char* fname);
|
void PlayMP3(const char* fname);
|
||||||
void ExpeditionSay(const char *str, int ExpID);
|
void ExpeditionSay(const char *str, int ExpID);
|
||||||
|
|||||||
@@ -1455,7 +1455,7 @@ int32 Client::CalcATK()
|
|||||||
|
|
||||||
uint32 Mob::GetInstrumentMod(uint16 spell_id)
|
uint32 Mob::GetInstrumentMod(uint16 spell_id)
|
||||||
{
|
{
|
||||||
if (GetClass() != Class::Bard) {
|
if (GetClass() != Class::Bard || spells[spell_id].is_discipline || spell_id == SPELL_AMPLIFICATION) {
|
||||||
//Other classes can get a base effects mod using SPA 413
|
//Other classes can get a base effects mod using SPA 413
|
||||||
if (HasBaseEffectFocus()) {
|
if (HasBaseEffectFocus()) {
|
||||||
return (10 + (GetFocusEffect(focusFcBaseEffects, spell_id) / 10));//TODO: change action->instrument mod to float to support < 10% focus values
|
return (10 + (GetFocusEffect(focusFcBaseEffects, spell_id) / 10));//TODO: change action->instrument mod to float to support < 10% focus values
|
||||||
|
|||||||
+171
-111
@@ -547,8 +547,8 @@ void Client::CompleteConnect()
|
|||||||
default: { break; } // GUILD_NONE
|
default: { break; } // GUILD_NONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SendAppearancePacket(AT_GuildID, GuildID(), false);
|
SendAppearancePacket(AppearanceType::GuildID, GuildID(), false);
|
||||||
SendAppearancePacket(AT_GuildRank, rank, false);
|
SendAppearancePacket(AppearanceType::GuildRank, rank, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// moved to dbload and translators since we iterate there also .. keep m_pp values whatever they are when they get here
|
// moved to dbload and translators since we iterate there also .. keep m_pp values whatever they are when they get here
|
||||||
@@ -681,8 +681,11 @@ void Client::CompleteConnect()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SE_SummonHorse: {
|
case SE_SummonHorse: {
|
||||||
|
if (RuleB(Character, PreventMountsFromZoning)) {
|
||||||
|
BuffFadeByEffect(SE_SummonHorse);
|
||||||
|
} else {
|
||||||
SummonHorse(buffs[j1].spellid);
|
SummonHorse(buffs[j1].spellid);
|
||||||
//hasmount = true; //this was false, is that the correct thing?
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SE_Silence:
|
case SE_Silence:
|
||||||
@@ -703,7 +706,7 @@ void Client::CompleteConnect()
|
|||||||
case SE_Invisibility2:
|
case SE_Invisibility2:
|
||||||
case SE_Invisibility:
|
case SE_Invisibility:
|
||||||
{
|
{
|
||||||
SendAppearancePacket(AT_Invis, Invisibility::Invisible);
|
SendAppearancePacket(AppearanceType::Invisibility, Invisibility::Invisible);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SE_Levitate:
|
case SE_Levitate:
|
||||||
@@ -712,17 +715,17 @@ void Client::CompleteConnect()
|
|||||||
{
|
{
|
||||||
if (!GetGM())
|
if (!GetGM())
|
||||||
{
|
{
|
||||||
SendAppearancePacket(AT_Levitate, 0);
|
SendAppearancePacket(AppearanceType::FlyMode, 0);
|
||||||
BuffFadeByEffect(SE_Levitate);
|
BuffFadeByEffect(SE_Levitate);
|
||||||
Message(Chat::Red, "You can't levitate in this zone.");
|
Message(Chat::Red, "You can't levitate in this zone.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (spell.limit_value[x1] == 1) {
|
if (spell.limit_value[x1] == 1) {
|
||||||
SendAppearancePacket(AT_Levitate, EQ::constants::GravityBehavior::LevitateWhileRunning, true, true);
|
SendAppearancePacket(AppearanceType::FlyMode, EQ::constants::GravityBehavior::LevitateWhileRunning, true, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SendAppearancePacket(AT_Levitate, EQ::constants::GravityBehavior::Levitating, true, true);
|
SendAppearancePacket(AppearanceType::FlyMode, EQ::constants::GravityBehavior::Levitating, true, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -747,7 +750,7 @@ void Client::CompleteConnect()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sends appearances for all mobs not doing anim_stand aka sitting, looting, playing dead */
|
/* Sends appearances for all mobs not doing Animation::Standing aka sitting, looting, playing dead */
|
||||||
entity_list.SendZoneAppearance(this);
|
entity_list.SendZoneAppearance(this);
|
||||||
/* Sends the Nimbus particle effects (up to 3) for any mob using them */
|
/* Sends the Nimbus particle effects (up to 3) for any mob using them */
|
||||||
entity_list.SendNimbusEffects(this);
|
entity_list.SendNimbusEffects(this);
|
||||||
@@ -1268,7 +1271,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
|||||||
database.LoadCharacterBandolier(cid, &m_pp); /* Load Character Bandolier */
|
database.LoadCharacterBandolier(cid, &m_pp); /* Load Character Bandolier */
|
||||||
database.LoadCharacterBindPoint(cid, &m_pp); /* Load Character Bind */
|
database.LoadCharacterBindPoint(cid, &m_pp); /* Load Character Bind */
|
||||||
database.LoadCharacterMaterialColor(cid, &m_pp); /* Load Character Material */
|
database.LoadCharacterMaterialColor(cid, &m_pp); /* Load Character Material */
|
||||||
database.LoadCharacterPotions(cid, &m_pp); /* Load Character Potion Belt */
|
database.LoadCharacterPotionBelt(cid, &m_pp); /* Load Character Potion Belt */
|
||||||
database.LoadCharacterCurrency(cid, &m_pp); /* Load Character Currency into PP */
|
database.LoadCharacterCurrency(cid, &m_pp); /* Load Character Currency into PP */
|
||||||
database.LoadCharacterData(cid, &m_pp, &m_epp); /* Load Character Data from DB into PP as well as E_PP */
|
database.LoadCharacterData(cid, &m_pp, &m_epp); /* Load Character Data from DB into PP as well as E_PP */
|
||||||
database.LoadCharacterSkills(cid, &m_pp); /* Load Character Skills */
|
database.LoadCharacterSkills(cid, &m_pp); /* Load Character Skills */
|
||||||
@@ -1277,7 +1280,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
|||||||
database.LoadCharacterMemmedSpells(cid, &m_pp); /* Load Character Memorized Spells */
|
database.LoadCharacterMemmedSpells(cid, &m_pp); /* Load Character Memorized Spells */
|
||||||
database.LoadCharacterDisciplines(cid, &m_pp); /* Load Character Disciplines */
|
database.LoadCharacterDisciplines(cid, &m_pp); /* Load Character Disciplines */
|
||||||
database.LoadCharacterLanguages(cid, &m_pp); /* Load Character Languages */
|
database.LoadCharacterLanguages(cid, &m_pp); /* Load Character Languages */
|
||||||
database.LoadCharacterLeadershipAA(cid, &m_pp); /* Load Character Leadership AA's */
|
database.LoadCharacterLeadershipAbilities(cid, &m_pp); /* Load Character Leadership AA's */
|
||||||
database.LoadCharacterTribute(this); /* Load CharacterTribute */
|
database.LoadCharacterTribute(this); /* Load CharacterTribute */
|
||||||
|
|
||||||
// this pattern is strange
|
// this pattern is strange
|
||||||
@@ -1316,7 +1319,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
|
|||||||
/* If GM, not trackable */
|
/* If GM, not trackable */
|
||||||
if (gm_hide_me) { trackable = false; }
|
if (gm_hide_me) { trackable = false; }
|
||||||
if (gminvul) { invulnerable = true; }
|
if (gminvul) { invulnerable = true; }
|
||||||
if (flymode > 0) { SendAppearancePacket(AT_Levitate, flymode); }
|
if (flymode > 0) { SendAppearancePacket(AppearanceType::FlyMode, flymode); }
|
||||||
/* Set Con State for Reporting */
|
/* Set Con State for Reporting */
|
||||||
conn_state = PlayerProfileLoaded;
|
conn_state = PlayerProfileLoaded;
|
||||||
|
|
||||||
@@ -2737,6 +2740,7 @@ void Client::Handle_OP_AltCurrencySell(const EQApplicationPacket *app)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!RuleB(Merchant, EnableAltCurrencySell)) {
|
if (!RuleB(Merchant, EnableAltCurrencySell)) {
|
||||||
|
Message(Chat::Red, "Selling alternate currency items is disabled.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4326,6 +4330,14 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
|
|||||||
LogSpells("OP CastSpell: slot [{}] spell [{}] target [{}] inv [{}]", castspell->slot, castspell->spell_id, castspell->target_id, (unsigned long)castspell->inventoryslot);
|
LogSpells("OP CastSpell: slot [{}] spell [{}] target [{}] inv [{}]", castspell->slot, castspell->spell_id, castspell->target_id, (unsigned long)castspell->inventoryslot);
|
||||||
CastingSlot slot = static_cast<CastingSlot>(castspell->slot);
|
CastingSlot slot = static_cast<CastingSlot>(castspell->slot);
|
||||||
|
|
||||||
|
if (RuleB(Spells, RequireMnemonicRetention)) {
|
||||||
|
if (EQ::ValueWithin(castspell->slot, 8, 11) && GetAA(aaMnemonicRetention) < (castspell->slot - 7)) {
|
||||||
|
InterruptSpell(castspell->spell_id);
|
||||||
|
Message(Chat::Red, "You do not have the required AA to use this spell slot.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Memorized Spell */
|
/* Memorized Spell */
|
||||||
if (m_pp.mem_spells[castspell->slot] && m_pp.mem_spells[castspell->slot] == castspell->spell_id) {
|
if (m_pp.mem_spells[castspell->slot] && m_pp.mem_spells[castspell->slot] == castspell->spell_id) {
|
||||||
uint16 spell_to_cast = 0;
|
uint16 spell_to_cast = 0;
|
||||||
@@ -4505,23 +4517,24 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
void Client::Handle_OP_ChannelMessage(const EQApplicationPacket *app)
|
void Client::Handle_OP_ChannelMessage(const EQApplicationPacket *app)
|
||||||
{
|
{
|
||||||
ChannelMessage_Struct* cm = (ChannelMessage_Struct*)app->pBuffer;
|
auto* cm = (ChannelMessage_Struct*) app->pBuffer;
|
||||||
|
|
||||||
if (app->size < sizeof(ChannelMessage_Struct)) {
|
if (app->size < sizeof(ChannelMessage_Struct)) {
|
||||||
std::cout << "Wrong size " << app->size << ", should be " << sizeof(ChannelMessage_Struct) << "+ on 0x" << std::hex << std::setfill('0') << std::setw(4) << app->GetOpcode() << std::dec << std::endl;
|
LogDebug("Size mismatch in OP_ChannelMessage expected [{}] got [{}]", sizeof(ChannelMessage_Struct), app->size);
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (IsAIControlled() && !GetGM()) {
|
|
||||||
Message(Chat::Red, "You try to speak but cant move your mouth!");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 skill_in_language = 100;
|
if (IsAIControlled() && !GetGM()) {
|
||||||
if (cm->language < MAX_PP_LANGUAGE)
|
Message(Chat::Red, "You try to speak but can't move your mouth!");
|
||||||
{
|
return;
|
||||||
skill_in_language = m_pp.languages[cm->language];
|
|
||||||
}
|
}
|
||||||
ChannelMessageReceived(cm->chan_num, cm->language, skill_in_language, cm->message, cm->targetname);
|
|
||||||
|
uint8 language_skill = Language::MaxValue;
|
||||||
|
if (EQ::ValueWithin(cm->language, Language::CommonTongue, Language::Unknown27)) {
|
||||||
|
language_skill = m_pp.languages[cm->language];
|
||||||
|
}
|
||||||
|
|
||||||
|
ChannelMessageReceived(cm->chan_num, cm->language, language_skill, cm->message, cm->targetname);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4887,8 +4900,13 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
|
|||||||
CheckIncreaseSkill(EQ::skills::SkillTracking, nullptr, -20);
|
CheckIncreaseSkill(EQ::skills::SkillTracking, nullptr, -20);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Break Hide if moving without sneaking and set rewind timer if moved */
|
|
||||||
if (cy != m_Position.y || cx != m_Position.x) {
|
if (cy != m_Position.y || cx != m_Position.x) {
|
||||||
|
// End trader mode if we move
|
||||||
|
if (Trader) {
|
||||||
|
Trader_EndTrader();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Break Hide if moving without sneaking and set rewind timer if moved */
|
||||||
if ((hidden || improved_hidden) && !sneaking) {
|
if ((hidden || improved_hidden) && !sneaking) {
|
||||||
hidden = false;
|
hidden = false;
|
||||||
improved_hidden = false;
|
improved_hidden = false;
|
||||||
@@ -5053,7 +5071,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (zone->watermap) {
|
if (zone->watermap) {
|
||||||
if (zone->watermap->InLiquid(glm::vec3(m_Position))) {
|
if (zone->watermap->InLiquid(glm::vec3(m_Position)) && IsMoving()) {
|
||||||
CheckIncreaseSkill(EQ::skills::SkillSwimming, nullptr, -17);
|
CheckIncreaseSkill(EQ::skills::SkillSwimming, nullptr, -17);
|
||||||
|
|
||||||
// Dismount horses when entering water
|
// Dismount horses when entering water
|
||||||
@@ -5770,7 +5788,7 @@ void Client::Handle_OP_DeleteSpell(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
if (m_pp.spell_book[dss->spell_slot] != SPELLBOOK_UNKNOWN) {
|
if (m_pp.spell_book[dss->spell_slot] != SPELLBOOK_UNKNOWN) {
|
||||||
m_pp.spell_book[dss->spell_slot] = SPELLBOOK_UNKNOWN;
|
m_pp.spell_book[dss->spell_slot] = SPELLBOOK_UNKNOWN;
|
||||||
database.DeleteCharacterSpell(CharacterID(), m_pp.spell_book[dss->spell_slot], dss->spell_slot);
|
database.DeleteCharacterSpell(CharacterID(), dss->spell_slot);
|
||||||
dss->success = 1;
|
dss->success = 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -6233,6 +6251,13 @@ void Client::Handle_OP_EnvDamage(const EQApplicationPacket *app)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ed->dmgtype == EQ::constants::EnvironmentalDamage::Falling) {
|
if (ed->dmgtype == EQ::constants::EnvironmentalDamage::Falling) {
|
||||||
|
if (zone->HasWaterMap()) {
|
||||||
|
auto target_position = glm::vec3(GetX(), GetY(), GetZ());
|
||||||
|
if (!zone->watermap->InLiquid(target_position)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
uint32 mod = spellbonuses.ReduceFallDamage + itembonuses.ReduceFallDamage + aabonuses.ReduceFallDamage;
|
uint32 mod = spellbonuses.ReduceFallDamage + itembonuses.ReduceFallDamage + aabonuses.ReduceFallDamage;
|
||||||
damage -= damage * mod / 100;
|
damage -= damage * mod / 100;
|
||||||
}
|
}
|
||||||
@@ -6481,7 +6506,7 @@ void Client::Handle_OP_GMBecomeNPC(const EQApplicationPacket *app)
|
|||||||
t->SetGM(false);
|
t->SetGM(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
m->SendAppearancePacket(AT_NPCName, 1, true);
|
m->SendAppearancePacket(AppearanceType::NPCName, 1, true);
|
||||||
t->SetBecomeNPC(true);
|
t->SetBecomeNPC(true);
|
||||||
t->SetBecomeNPCLevel(b->maxlevel);
|
t->SetBecomeNPCLevel(b->maxlevel);
|
||||||
m->MessageString(Chat::White, TOGGLE_OFF);
|
m->MessageString(Chat::White, TOGGLE_OFF);
|
||||||
@@ -6598,17 +6623,26 @@ void Client::Handle_OP_GMGoto(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
auto *gmg = (GMSummon_Struct *) app->pBuffer;
|
auto *gmg = (GMSummon_Struct *) app->pBuffer;
|
||||||
Mob *gt = entity_list.GetMob(gmg->charname);
|
Mob *gt = entity_list.GetMob(gmg->charname);
|
||||||
if (!gt) {
|
if (gt) {
|
||||||
MovePC(zone->GetZoneID(), zone->GetInstanceID(), gt->GetX(), gt->GetY(), gt->GetZ(), gt->GetHeading());
|
MovePC(
|
||||||
|
zone->GetZoneID(),
|
||||||
|
zone->GetInstanceID(),
|
||||||
|
gt->GetX(),
|
||||||
|
gt->GetY(),
|
||||||
|
gt->GetZ(),
|
||||||
|
gt->GetHeading()
|
||||||
|
);
|
||||||
} else if (!worldserver.Connected()) {
|
} else if (!worldserver.Connected()) {
|
||||||
Message(Chat::Red, "Error: World server disconnected.");
|
Message(Chat::Red, "Error: World server disconnected.");
|
||||||
} else {
|
} else {
|
||||||
auto pack = new ServerPacket(ServerOP_GMGoto, sizeof(ServerGMGoto_Struct));
|
auto pack = new ServerPacket(ServerOP_GMGoto, sizeof(ServerGMGoto_Struct));
|
||||||
memset(pack->pBuffer, 0, pack->size);
|
memset(pack->pBuffer, 0, pack->size);
|
||||||
ServerGMGoto_Struct *wsgmg = (ServerGMGoto_Struct *) pack->pBuffer;
|
|
||||||
strcpy(wsgmg->myname, GetName());
|
auto* g = (ServerGMGoto_Struct *) pack->pBuffer;
|
||||||
strcpy(wsgmg->gotoname, gmg->charname);
|
strcpy(g->myname, GetName());
|
||||||
wsgmg->admin = admin;
|
strcpy(g->gotoname, gmg->charname);
|
||||||
|
g->admin = admin;
|
||||||
|
|
||||||
worldserver.SendPacket(pack);
|
worldserver.SendPacket(pack);
|
||||||
safe_delete(pack);
|
safe_delete(pack);
|
||||||
}
|
}
|
||||||
@@ -7304,64 +7338,81 @@ void Client::Handle_OP_GroupInvite2(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
GroupInvite_Struct* gis = (GroupInvite_Struct*)app->pBuffer;
|
GroupInvite_Struct* gis = (GroupInvite_Struct*)app->pBuffer;
|
||||||
|
|
||||||
Mob *Invitee = entity_list.GetMob(gis->invitee_name);
|
Mob* invitee = nullptr;
|
||||||
|
|
||||||
if (Invitee == this)
|
if (RuleB(Character, GroupInvitesRequireTarget)) {
|
||||||
{
|
// We can only invite the current target.
|
||||||
|
invitee = GetTarget();
|
||||||
|
} else {
|
||||||
|
invitee = entity_list.GetMob(gis->invitee_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (invitee == this) {
|
||||||
MessageString(Chat::LightGray, GROUP_INVITEE_SELF);
|
MessageString(Chat::LightGray, GROUP_INVITEE_SELF);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Invitee)
|
if (invitee) {
|
||||||
{
|
if (invitee->IsClient()) {
|
||||||
if (Invitee->IsClient())
|
if (invitee->CastToClient()->MercOnlyOrNoGroup() && !invitee->IsRaidGrouped()) {
|
||||||
{
|
if (app->GetOpcode() == OP_GroupInvite2) {
|
||||||
if (Invitee->CastToClient()->MercOnlyOrNoGroup() && !Invitee->IsRaidGrouped())
|
|
||||||
{
|
|
||||||
if (app->GetOpcode() == OP_GroupInvite2)
|
|
||||||
{
|
|
||||||
//Make a new packet using all the same information but make sure it's a fixed GroupInvite opcode so we
|
//Make a new packet using all the same information but make sure it's a fixed GroupInvite opcode so we
|
||||||
//Don't have to deal with GroupFollow2 crap.
|
//Don't have to deal with GroupFollow2 crap.
|
||||||
auto outapp =
|
auto outapp =
|
||||||
new EQApplicationPacket(OP_GroupInvite, sizeof(GroupInvite_Struct));
|
new EQApplicationPacket(OP_GroupInvite, sizeof(GroupInvite_Struct));
|
||||||
memcpy(outapp->pBuffer, app->pBuffer, outapp->size);
|
memcpy(outapp->pBuffer, app->pBuffer, outapp->size);
|
||||||
Invitee->CastToClient()->QueuePacket(outapp);
|
invitee->CastToClient()->QueuePacket(outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//The correct opcode, no reason to bother wasting time reconstructing the packet
|
|
||||||
Invitee->CastToClient()->QueuePacket(app);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (RuleB(Character, OnInviteReceiveAlreadyinGroupMessage)) {
|
|
||||||
if (!Invitee->CastToClient()->MercOnlyOrNoGroup()) {
|
|
||||||
Message(Chat::LightGray, "%s is already in another group.", Invitee->GetCleanName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Invitee->IsBot()) {
|
|
||||||
Client* inviter = entity_list.GetClientByName(gis->inviter_name);
|
|
||||||
if (inviter && inviter->IsRaidGrouped() && !Invitee->HasRaid()) {
|
|
||||||
Bot::ProcessRaidInvite(Invitee->CastToBot(), inviter, true);
|
|
||||||
}
|
|
||||||
else if (!Invitee->HasRaid()) {
|
|
||||||
Bot::ProcessBotGroupInvite(this, std::string(Invitee->GetName()));
|
|
||||||
} else {
|
} else {
|
||||||
MessageString(Chat::LightGray, ALREADY_IN_RAID, Invitee->GetCleanName());
|
//The correct opcode, no reason to bother wasting time reconstructing the packet
|
||||||
|
invitee->CastToClient()->QueuePacket(app);
|
||||||
|
}
|
||||||
|
} else if (invitee->IsRaidGrouped()) {
|
||||||
|
Raid* inviter_raid = GetRaid();
|
||||||
|
Raid* invitee_raid = invitee->CastToClient()->GetRaid();
|
||||||
|
|
||||||
|
bool leader = false;
|
||||||
|
|
||||||
|
if (invitee_raid) {
|
||||||
|
leader = invitee_raid->IsGroupLeader(invitee->GetName());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inviter_raid != invitee_raid || leader) {
|
||||||
|
MessageString(Chat::Default, ALREADY_IN_GRP_RAID, invitee->GetCleanName());
|
||||||
|
} else {
|
||||||
|
MessageString(Chat::Default, TARGET_ALREADY_IN_GROUP, invitee->GetCleanName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (RuleB(Character, OnInviteReceiveAlreadyinGroupMessage)) {
|
||||||
|
if (!invitee->CastToClient()->MercOnlyOrNoGroup()) {
|
||||||
|
MessageString(Chat::Default, TARGET_ALREADY_IN_GROUP, invitee->GetCleanName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
} else if (invitee->IsBot()) {
|
||||||
{
|
Client* inviter = entity_list.GetClientByName(gis->inviter_name);
|
||||||
|
if (inviter && inviter->IsRaidGrouped() && !invitee->HasRaid()) {
|
||||||
|
Bot::ProcessRaidInvite(invitee->CastToBot(), inviter, true);
|
||||||
|
} else if (!invitee->HasRaid()) {
|
||||||
|
Bot::ProcessBotGroupInvite(this, std::string(invitee->GetName()));
|
||||||
|
} else {
|
||||||
|
MessageString(Chat::LightGray, ALREADY_IN_RAID, invitee->GetCleanName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (RuleB(Character, GroupInvitesRequireTarget)) {
|
||||||
|
Message(Chat::White, "You must target a player first to invite to join your group.");
|
||||||
|
} else {
|
||||||
auto pack = new ServerPacket(ServerOP_GroupInvite, sizeof(GroupInvite_Struct));
|
auto pack = new ServerPacket(ServerOP_GroupInvite, sizeof(GroupInvite_Struct));
|
||||||
memcpy(pack->pBuffer, gis, sizeof(GroupInvite_Struct));
|
memcpy(pack->pBuffer, gis, sizeof(GroupInvite_Struct));
|
||||||
worldserver.SendPacket(pack);
|
worldserver.SendPacket(pack);
|
||||||
safe_delete(pack);
|
safe_delete(pack);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8853,7 +8904,7 @@ void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app)
|
|||||||
Message(Chat::LightGray, "You say, '%s'", response.c_str());
|
Message(Chat::LightGray, "You say, '%s'", response.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
ChannelMessageReceived(ChatChannel_Say, 0, 100, response.c_str(), nullptr, true);
|
ChannelMessageReceived(ChatChannel_Say, Language::CommonTongue, Language::MaxValue, response.c_str(), nullptr, true);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -10716,7 +10767,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) {
|
if ((mypet->GetPetType() == petAnimation && aabonuses.PetCommands[PetCommand]) || mypet->GetPetType() != petAnimation) {
|
||||||
if (target != this && DistanceSquaredNoZ(mypet->GetPosition(), target->GetPosition()) <= (RuleR(Pets, AttackCommandRange)*RuleR(Pets, AttackCommandRange))) {
|
if (target != this && DistanceSquared(mypet->GetPosition(), target->GetPosition()) <= (RuleR(Pets, AttackCommandRange)*RuleR(Pets, AttackCommandRange))) {
|
||||||
mypet->SetFeigned(false);
|
mypet->SetFeigned(false);
|
||||||
if (mypet->IsPetStop()) {
|
if (mypet->IsPetStop()) {
|
||||||
mypet->SetPetStop(false);
|
mypet->SetPetStop(false);
|
||||||
@@ -10842,7 +10893,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
|||||||
// Set Sit button to unpressed - send stand anim/end hpregen
|
// Set Sit button to unpressed - send stand anim/end hpregen
|
||||||
mypet->SetFeigned(false);
|
mypet->SetFeigned(false);
|
||||||
SetPetCommandState(PET_BUTTON_SIT, 0);
|
SetPetCommandState(PET_BUTTON_SIT, 0);
|
||||||
mypet->SendAppearancePacket(AT_Anim, ANIM_STAND);
|
mypet->SendAppearancePacket(AppearanceType::Animation, Animation::Standing);
|
||||||
|
|
||||||
mypet->SayString(this, Chat::PetResponse, PET_GUARDINGLIFE);
|
mypet->SayString(this, Chat::PetResponse, PET_GUARDINGLIFE);
|
||||||
mypet->SetPetOrder(SPO_Guard);
|
mypet->SetPetOrder(SPO_Guard);
|
||||||
@@ -10867,7 +10918,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
// fix GUI sit button to be unpressed - send stand anim/end hpregen
|
// fix GUI sit button to be unpressed - send stand anim/end hpregen
|
||||||
SetPetCommandState(PET_BUTTON_SIT, 0);
|
SetPetCommandState(PET_BUTTON_SIT, 0);
|
||||||
mypet->SendAppearancePacket(AT_Anim, ANIM_STAND);
|
mypet->SendAppearancePacket(AppearanceType::Animation, Animation::Standing);
|
||||||
|
|
||||||
if (mypet->IsPetStop()) {
|
if (mypet->IsPetStop()) {
|
||||||
mypet->SetPetStop(false);
|
mypet->SetPetStop(false);
|
||||||
@@ -10915,7 +10966,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
// Set Sit button to unpressed - send stand anim/end hpregen
|
// Set Sit button to unpressed - send stand anim/end hpregen
|
||||||
SetPetCommandState(PET_BUTTON_SIT, 0);
|
SetPetCommandState(PET_BUTTON_SIT, 0);
|
||||||
mypet->SendAppearancePacket(AT_Anim, ANIM_STAND);
|
mypet->SendAppearancePacket(AppearanceType::Animation, Animation::Standing);
|
||||||
|
|
||||||
if (mypet->IsPetStop()) {
|
if (mypet->IsPetStop()) {
|
||||||
mypet->SetPetStop(false);
|
mypet->SetPetStop(false);
|
||||||
@@ -10933,7 +10984,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
|||||||
mypet->SetFeigned(false);
|
mypet->SetFeigned(false);
|
||||||
mypet->SayString(this, Chat::PetResponse, PET_SIT_STRING);
|
mypet->SayString(this, Chat::PetResponse, PET_SIT_STRING);
|
||||||
mypet->SetPetOrder(SPO_Follow);
|
mypet->SetPetOrder(SPO_Follow);
|
||||||
mypet->SendAppearancePacket(AT_Anim, ANIM_STAND);
|
mypet->SendAppearancePacket(AppearanceType::Animation, Animation::Standing);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -10943,7 +10994,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
|||||||
mypet->SetRunAnimSpeed(0);
|
mypet->SetRunAnimSpeed(0);
|
||||||
if (!mypet->UseBardSpellLogic()) //maybe we can have a bard pet
|
if (!mypet->UseBardSpellLogic()) //maybe we can have a bard pet
|
||||||
mypet->InterruptSpell(); //No cast 4 u. //i guess the pet should start casting
|
mypet->InterruptSpell(); //No cast 4 u. //i guess the pet should start casting
|
||||||
mypet->SendAppearancePacket(AT_Anim, ANIM_SIT);
|
mypet->SendAppearancePacket(AppearanceType::Animation, Animation::Sitting);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -10956,7 +11007,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
|||||||
mypet->SayString(this, Chat::PetResponse, PET_SIT_STRING);
|
mypet->SayString(this, Chat::PetResponse, PET_SIT_STRING);
|
||||||
SetPetCommandState(PET_BUTTON_SIT, 0);
|
SetPetCommandState(PET_BUTTON_SIT, 0);
|
||||||
mypet->SetPetOrder(SPO_Follow);
|
mypet->SetPetOrder(SPO_Follow);
|
||||||
mypet->SendAppearancePacket(AT_Anim, ANIM_STAND);
|
mypet->SendAppearancePacket(AppearanceType::Animation, Animation::Standing);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -10971,7 +11022,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
|||||||
mypet->SetRunAnimSpeed(0);
|
mypet->SetRunAnimSpeed(0);
|
||||||
if (!mypet->UseBardSpellLogic()) //maybe we can have a bard pet
|
if (!mypet->UseBardSpellLogic()) //maybe we can have a bard pet
|
||||||
mypet->InterruptSpell(); //No cast 4 u. //i guess the pet should start casting
|
mypet->InterruptSpell(); //No cast 4 u. //i guess the pet should start casting
|
||||||
mypet->SendAppearancePacket(AT_Anim, ANIM_SIT);
|
mypet->SendAppearancePacket(AppearanceType::Animation, Animation::Sitting);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -11176,7 +11227,7 @@ void Client::Handle_OP_PetCommands(const EQApplicationPacket *app)
|
|||||||
mypet->SetPetOrder(SPO_FeignDeath);
|
mypet->SetPetOrder(SPO_FeignDeath);
|
||||||
mypet->SetRunAnimSpeed(0);
|
mypet->SetRunAnimSpeed(0);
|
||||||
mypet->StopNavigation();
|
mypet->StopNavigation();
|
||||||
mypet->SendAppearancePacket(AT_Anim, ANIM_DEATH);
|
mypet->SendAppearancePacket(AppearanceType::Animation, Animation::Lying);
|
||||||
mypet->SetFeigned(true);
|
mypet->SetFeigned(true);
|
||||||
mypet->SetTarget(nullptr);
|
mypet->SetTarget(nullptr);
|
||||||
if (!mypet->UseBardSpellLogic()) {
|
if (!mypet->UseBardSpellLogic()) {
|
||||||
@@ -11564,7 +11615,7 @@ void Client::Handle_OP_PopupResponse(const EQApplicationPacket *app)
|
|||||||
if (EntityVariableExists(DIAWIND_RESPONSE_ONE_KEY)) {
|
if (EntityVariableExists(DIAWIND_RESPONSE_ONE_KEY)) {
|
||||||
response = GetEntityVariable(DIAWIND_RESPONSE_ONE_KEY);
|
response = GetEntityVariable(DIAWIND_RESPONSE_ONE_KEY);
|
||||||
if (!response.empty()) {
|
if (!response.empty()) {
|
||||||
ChannelMessageReceived(ChatChannel_Say, 0, 100, response.c_str(), nullptr, true);
|
ChannelMessageReceived(ChatChannel_Say, Language::CommonTongue, Language::MaxValue, response.c_str(), nullptr, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -11573,7 +11624,7 @@ void Client::Handle_OP_PopupResponse(const EQApplicationPacket *app)
|
|||||||
if (EntityVariableExists(DIAWIND_RESPONSE_TWO_KEY)) {
|
if (EntityVariableExists(DIAWIND_RESPONSE_TWO_KEY)) {
|
||||||
response = GetEntityVariable(DIAWIND_RESPONSE_TWO_KEY);
|
response = GetEntityVariable(DIAWIND_RESPONSE_TWO_KEY);
|
||||||
if (!response.empty()) {
|
if (!response.empty()) {
|
||||||
ChannelMessageReceived(ChatChannel_Say, 0, 100, response.c_str(), nullptr, true);
|
ChannelMessageReceived(ChatChannel_Say, Language::CommonTongue, Language::MaxValue, response.c_str(), nullptr, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -11671,7 +11722,7 @@ void Client::Handle_OP_PurchaseLeadershipAA(const EQApplicationPacket *app)
|
|||||||
m_pp.raid_leadership_points -= cost;
|
m_pp.raid_leadership_points -= cost;
|
||||||
m_pp.leader_abilities.ranks[aaid]++;
|
m_pp.leader_abilities.ranks[aaid]++;
|
||||||
|
|
||||||
database.SaveCharacterLeadershipAA(CharacterID(), &m_pp);
|
database.SaveCharacterLeadershipAbilities(CharacterID(), &m_pp);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//it is a group ability.
|
//it is a group ability.
|
||||||
@@ -11684,7 +11735,7 @@ void Client::Handle_OP_PurchaseLeadershipAA(const EQApplicationPacket *app)
|
|||||||
m_pp.group_leadership_points -= cost;
|
m_pp.group_leadership_points -= cost;
|
||||||
m_pp.leader_abilities.ranks[aaid]++;
|
m_pp.leader_abilities.ranks[aaid]++;
|
||||||
|
|
||||||
database.SaveCharacterLeadershipAA(CharacterID(), &m_pp);
|
database.SaveCharacterLeadershipAbilities(CharacterID(), &m_pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
//success, send them an update
|
//success, send them an update
|
||||||
@@ -11808,8 +11859,8 @@ void Client::Handle_OP_QueryUCSServerStatus(const EQApplicationPacket *app)
|
|||||||
}
|
}
|
||||||
|
|
||||||
buffer = StringFormat("%s,%i,%s.%s,%c%s",
|
buffer = StringFormat("%s,%i,%s.%s,%c%s",
|
||||||
Config->ChatHost.c_str(),
|
Config->GetUCSHost().c_str(),
|
||||||
Config->ChatPort,
|
Config->GetUCSPort(),
|
||||||
Config->ShortName.c_str(),
|
Config->ShortName.c_str(),
|
||||||
GetName(),
|
GetName(),
|
||||||
ConnectionType,
|
ConnectionType,
|
||||||
@@ -11834,8 +11885,8 @@ void Client::Handle_OP_QueryUCSServerStatus(const EQApplicationPacket *app)
|
|||||||
}
|
}
|
||||||
|
|
||||||
buffer = StringFormat("%s,%i,%s.%s,%c%s",
|
buffer = StringFormat("%s,%i,%s.%s,%c%s",
|
||||||
Config->MailHost.c_str(),
|
Config->GetUCSHost().c_str(),
|
||||||
Config->MailPort,
|
Config->GetUCSPort(),
|
||||||
Config->ShortName.c_str(),
|
Config->ShortName.c_str(),
|
||||||
GetName(),
|
GetName(),
|
||||||
ConnectionType,
|
ConnectionType,
|
||||||
@@ -12044,6 +12095,13 @@ void Client::Handle_OP_RaidCommand(const EQApplicationPacket* app)
|
|||||||
{
|
{
|
||||||
auto player_sending_invite_group = player_sending_invite->GetGroup();
|
auto player_sending_invite_group = player_sending_invite->GetGroup();
|
||||||
Group* group = GetGroup();
|
Group* group = GetGroup();
|
||||||
|
|
||||||
|
/* Prevent scenario where player had joined group with Raid invitor before accepting Raid invite */
|
||||||
|
if (group && group == player_sending_invite_group) {
|
||||||
|
player_sending_invite->MessageString(Chat::Red, INVITE_GROUP_LEADER);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (group) //if our target has a group
|
if (group) //if our target has a group
|
||||||
{
|
{
|
||||||
raid = new Raid(player_sending_invite);
|
raid = new Raid(player_sending_invite);
|
||||||
@@ -14247,14 +14305,14 @@ void Client::Handle_OP_SpawnAppearance(const EQApplicationPacket *app)
|
|||||||
if (sa->spawn_id != GetID())
|
if (sa->spawn_id != GetID())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (sa->type == AT_Invis) {
|
if (sa->type == AppearanceType::Invisibility) {
|
||||||
if (sa->parameter != 0)
|
if (sa->parameter != 0)
|
||||||
{
|
{
|
||||||
if (!HasSkill(EQ::skills::SkillHide) && GetSkill(EQ::skills::SkillHide) == 0)
|
if (!HasSkill(EQ::skills::SkillHide) && GetSkill(EQ::skills::SkillHide) == 0)
|
||||||
{
|
{
|
||||||
if (ClientVersion() < EQ::versions::ClientVersion::SoF)
|
if (ClientVersion() < EQ::versions::ClientVersion::SoF)
|
||||||
{
|
{
|
||||||
auto message = fmt::format("Player sent OP_SpawnAppearance with AT_Invis [{}]", sa->parameter);
|
auto message = fmt::format("Player sent OP_SpawnAppearance with AppearanceType::Invisibility [{}]", sa->parameter);
|
||||||
RecordPlayerEventLog(PlayerEvent::POSSIBLE_HACK, PlayerEvent::PossibleHackEvent{.message = message});
|
RecordPlayerEventLog(PlayerEvent::POSSIBLE_HACK, PlayerEvent::PossibleHackEvent{.message = message});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -14266,18 +14324,18 @@ void Client::Handle_OP_SpawnAppearance(const EQApplicationPacket *app)
|
|||||||
entity_list.QueueClients(this, app, true);
|
entity_list.QueueClients(this, app, true);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (sa->type == AT_Anim) {
|
else if (sa->type == AppearanceType::Animation) {
|
||||||
if (IsAIControlled())
|
if (IsAIControlled())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (sa->parameter == ANIM_STAND) {
|
if (sa->parameter == Animation::Standing) {
|
||||||
SetAppearance(eaStanding);
|
SetAppearance(eaStanding);
|
||||||
playeraction = 0;
|
playeraction = 0;
|
||||||
SetFeigned(false);
|
SetFeigned(false);
|
||||||
BindWound(this, false, true);
|
BindWound(this, false, true);
|
||||||
camp_timer.Disable();
|
camp_timer.Disable();
|
||||||
}
|
}
|
||||||
else if (sa->parameter == ANIM_SIT) {
|
else if (sa->parameter == Animation::Sitting) {
|
||||||
SetAppearance(eaSitting);
|
SetAppearance(eaSitting);
|
||||||
playeraction = 1;
|
playeraction = 1;
|
||||||
if (!UseBardSpellLogic())
|
if (!UseBardSpellLogic())
|
||||||
@@ -14287,19 +14345,19 @@ void Client::Handle_OP_SpawnAppearance(const EQApplicationPacket *app)
|
|||||||
tmSitting = Timer::GetCurrentTime();
|
tmSitting = Timer::GetCurrentTime();
|
||||||
BuffFadeBySitModifier();
|
BuffFadeBySitModifier();
|
||||||
}
|
}
|
||||||
else if (sa->parameter == ANIM_CROUCH) {
|
else if (sa->parameter == Animation::Crouching) {
|
||||||
if (!UseBardSpellLogic())
|
if (!UseBardSpellLogic())
|
||||||
InterruptSpell();
|
InterruptSpell();
|
||||||
SetAppearance(eaCrouching);
|
SetAppearance(eaCrouching);
|
||||||
playeraction = 2;
|
playeraction = 2;
|
||||||
SetFeigned(false);
|
SetFeigned(false);
|
||||||
}
|
}
|
||||||
else if (sa->parameter == ANIM_DEATH) { // feign death too
|
else if (sa->parameter == Animation::Lying) { // feign death too
|
||||||
SetAppearance(eaDead);
|
SetAppearance(eaDead);
|
||||||
playeraction = 3;
|
playeraction = 3;
|
||||||
InterruptSpell();
|
InterruptSpell();
|
||||||
}
|
}
|
||||||
else if (sa->parameter == ANIM_LOOT) {
|
else if (sa->parameter == Animation::Looting) {
|
||||||
SetAppearance(eaLooting);
|
SetAppearance(eaLooting);
|
||||||
playeraction = 4;
|
playeraction = 4;
|
||||||
SetFeigned(false);
|
SetFeigned(false);
|
||||||
@@ -14312,7 +14370,7 @@ void Client::Handle_OP_SpawnAppearance(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
entity_list.QueueClients(this, app, true);
|
entity_list.QueueClients(this, app, true);
|
||||||
}
|
}
|
||||||
else if (sa->type == AT_Anon) {
|
else if (sa->type == AppearanceType::Anonymous) {
|
||||||
if (!anon_toggle_timer.Check()) {
|
if (!anon_toggle_timer.Check()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -14334,19 +14392,19 @@ void Client::Handle_OP_SpawnAppearance(const EQApplicationPacket *app)
|
|||||||
entity_list.QueueClients(this, app, true);
|
entity_list.QueueClients(this, app, true);
|
||||||
UpdateWho();
|
UpdateWho();
|
||||||
}
|
}
|
||||||
else if ((sa->type == AT_HP) && (dead == 0)) {
|
else if ((sa->type == AppearanceType::Health) && (dead == 0)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (sa->type == AT_AFK) {
|
else if (sa->type == AppearanceType::AFK) {
|
||||||
if (afk_toggle_timer.Check()) {
|
if (afk_toggle_timer.Check()) {
|
||||||
AFK = (sa->parameter == 1);
|
AFK = (sa->parameter == 1);
|
||||||
entity_list.QueueClients(this, app, true);
|
entity_list.QueueClients(this, app, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (sa->type == AT_Split) {
|
else if (sa->type == AppearanceType::Split) {
|
||||||
m_pp.autosplit = (sa->parameter == 1);
|
m_pp.autosplit = (sa->parameter == 1);
|
||||||
}
|
}
|
||||||
else if (sa->type == AT_Sneak) {
|
else if (sa->type == AppearanceType::Sneak) {
|
||||||
if (sneaking == 0)
|
if (sneaking == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -14354,7 +14412,7 @@ void Client::Handle_OP_SpawnAppearance(const EQApplicationPacket *app)
|
|||||||
{
|
{
|
||||||
if (!HasSkill(EQ::skills::SkillSneak))
|
if (!HasSkill(EQ::skills::SkillSneak))
|
||||||
{
|
{
|
||||||
auto message = fmt::format("Player sent OP_SpawnAppearance with AT_Sneak [{}]", sa->parameter);
|
auto message = fmt::format("Player sent OP_SpawnAppearance with AppearanceType::Sneak [{}]", sa->parameter);
|
||||||
RecordPlayerEventLog(PlayerEvent::POSSIBLE_HACK, PlayerEvent::PossibleHackEvent{.message = message});
|
RecordPlayerEventLog(PlayerEvent::POSSIBLE_HACK, PlayerEvent::PossibleHackEvent{.message = message});
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -14362,38 +14420,38 @@ void Client::Handle_OP_SpawnAppearance(const EQApplicationPacket *app)
|
|||||||
sneaking = 0;
|
sneaking = 0;
|
||||||
entity_list.QueueClients(this, app, true);
|
entity_list.QueueClients(this, app, true);
|
||||||
}
|
}
|
||||||
else if (sa->type == AT_Size)
|
else if (sa->type == AppearanceType::Size)
|
||||||
{
|
{
|
||||||
auto message = fmt::format("Player sent OP_SpawnAppearance with AT_Size [{}]", sa->parameter);
|
auto message = fmt::format("Player sent OP_SpawnAppearance with AppearanceType::Size [{}]", sa->parameter);
|
||||||
RecordPlayerEventLog(PlayerEvent::POSSIBLE_HACK, PlayerEvent::PossibleHackEvent{.message = message});
|
RecordPlayerEventLog(PlayerEvent::POSSIBLE_HACK, PlayerEvent::PossibleHackEvent{.message = message});
|
||||||
}
|
}
|
||||||
else if (sa->type == AT_Light) // client emitting light (lightstone, shiny shield)
|
else if (sa->type == AppearanceType::Light) // client emitting light (lightstone, shiny shield)
|
||||||
{
|
{
|
||||||
//don't do anything with this
|
//don't do anything with this
|
||||||
}
|
}
|
||||||
else if (sa->type == AT_Levitate)
|
else if (sa->type == AppearanceType::FlyMode)
|
||||||
{
|
{
|
||||||
// don't do anything with this, we tell the client when it's
|
// don't do anything with this, we tell the client when it's
|
||||||
// levitating, not the other way around
|
// levitating, not the other way around
|
||||||
}
|
}
|
||||||
else if (sa->type == AT_ShowHelm)
|
else if (sa->type == AppearanceType::ShowHelm)
|
||||||
{
|
{
|
||||||
if (helm_toggle_timer.Check()) {
|
if (helm_toggle_timer.Check()) {
|
||||||
m_pp.showhelm = (sa->parameter == 1);
|
m_pp.showhelm = (sa->parameter == 1);
|
||||||
entity_list.QueueClients(this, app, true);
|
entity_list.QueueClients(this, app, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (sa->type == AT_GroupConsent)
|
else if (sa->type == AppearanceType::GroupAutoConsent)
|
||||||
{
|
{
|
||||||
m_pp.groupAutoconsent = (sa->parameter == 1);
|
m_pp.groupAutoconsent = (sa->parameter == 1);
|
||||||
ConsentCorpses("Group", (sa->parameter != 1));
|
ConsentCorpses("Group", (sa->parameter != 1));
|
||||||
}
|
}
|
||||||
else if (sa->type == AT_RaidConsent)
|
else if (sa->type == AppearanceType::RaidAutoConsent)
|
||||||
{
|
{
|
||||||
m_pp.raidAutoconsent = (sa->parameter == 1);
|
m_pp.raidAutoconsent = (sa->parameter == 1);
|
||||||
ConsentCorpses("Raid", (sa->parameter != 1));
|
ConsentCorpses("Raid", (sa->parameter != 1));
|
||||||
}
|
}
|
||||||
else if (sa->type == AT_GuildConsent)
|
else if (sa->type == AppearanceType::GuildAutoConsent)
|
||||||
{
|
{
|
||||||
m_pp.guildAutoconsent = (sa->parameter == 1);
|
m_pp.guildAutoconsent = (sa->parameter == 1);
|
||||||
ConsentCorpses("Guild", (sa->parameter != 1));
|
ConsentCorpses("Guild", (sa->parameter != 1));
|
||||||
@@ -14533,10 +14591,10 @@ void Client::Handle_OP_SwapSpell(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
/* Save Spell Swaps */
|
/* Save Spell Swaps */
|
||||||
if (!database.SaveCharacterSpell(CharacterID(), m_pp.spell_book[swapspell->from_slot], swapspell->from_slot)) {
|
if (!database.SaveCharacterSpell(CharacterID(), m_pp.spell_book[swapspell->from_slot], swapspell->from_slot)) {
|
||||||
database.DeleteCharacterSpell(CharacterID(), m_pp.spell_book[swapspell->from_slot], swapspell->from_slot);
|
database.DeleteCharacterSpell(CharacterID(), swapspell->from_slot);
|
||||||
}
|
}
|
||||||
if (!database.SaveCharacterSpell(CharacterID(), swapspelltemp, swapspell->to_slot)) {
|
if (!database.SaveCharacterSpell(CharacterID(), swapspelltemp, swapspell->to_slot)) {
|
||||||
database.DeleteCharacterSpell(CharacterID(), swapspelltemp, swapspell->to_slot);
|
database.DeleteCharacterSpell(CharacterID(), swapspell->to_slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
QueuePacket(app);
|
QueuePacket(app);
|
||||||
@@ -15504,6 +15562,8 @@ void Client::Handle_OP_Translocate(const EQApplicationPacket *app)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entity_list.ClearAggro(this);
|
||||||
|
|
||||||
////Was sending the packet back to initiate client zone...
|
////Was sending the packet back to initiate client zone...
|
||||||
////but that could be abusable, so lets go through proper channels
|
////but that could be abusable, so lets go through proper channels
|
||||||
MovePC(
|
MovePC(
|
||||||
|
|||||||
+25
-13
@@ -572,7 +572,7 @@ bool Client::Process() {
|
|||||||
linkdead_timer.Start(RuleI(Zone, ClientLinkdeadMS));
|
linkdead_timer.Start(RuleI(Zone, ClientLinkdeadMS));
|
||||||
client_state = CLIENT_LINKDEAD;
|
client_state = CLIENT_LINKDEAD;
|
||||||
AI_Start(CLIENT_LD_TIMEOUT);
|
AI_Start(CLIENT_LD_TIMEOUT);
|
||||||
SendAppearancePacket(AT_Linkdead, 1);
|
SendAppearancePacket(AppearanceType::Linkdead, 1);
|
||||||
|
|
||||||
SetDynamicZoneMemberStatus(DynamicZoneMemberStatus::LinkDead);
|
SetDynamicZoneMemberStatus(DynamicZoneMemberStatus::LinkDead);
|
||||||
}
|
}
|
||||||
@@ -763,10 +763,12 @@ void Client::BulkSendInventoryItems()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool deletenorent = database.NoRentExpired(GetName());
|
const bool delete_no_rent = database.NoRentExpired(GetName());
|
||||||
if (deletenorent) { //client was offline for more than 30 minutes, delete no rent items
|
if (delete_no_rent) { //client was offline for more than 30 minutes, delete no rent items
|
||||||
if (RuleB(Inventory, TransformSummonedBags))
|
if (RuleB(Inventory, TransformSummonedBags)) {
|
||||||
DisenchantSummonedBags(false);
|
DisenchantSummonedBags(false);
|
||||||
|
}
|
||||||
|
|
||||||
RemoveNoRent(false);
|
RemoveNoRent(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1184,10 +1186,10 @@ void Client::CancelSneakHide()
|
|||||||
if (hidden || improved_hidden) {
|
if (hidden || improved_hidden) {
|
||||||
auto app = new EQApplicationPacket(OP_CancelSneakHide, 0);
|
auto app = new EQApplicationPacket(OP_CancelSneakHide, 0);
|
||||||
FastQueuePacket(&app);
|
FastQueuePacket(&app);
|
||||||
// SoF and Tit send back a OP_SpawnAppearance turning off AT_Invis
|
// SoF and Tit send back a OP_SpawnAppearance turning off AppearanceType::Invisibility
|
||||||
// so we need to handle our sneaking flag only
|
// so we need to handle our sneaking flag only
|
||||||
// The later clients send back a OP_Hide (this has a size but data is 0)
|
// The later clients send back a OP_Hide (this has a size but data is 0)
|
||||||
// as well as OP_SpawnAppearance with AT_Invis and one with AT_Sneak
|
// as well as OP_SpawnAppearance with AppearanceType::Invisibility and one with AppearanceType::Sneak
|
||||||
// So we don't have to handle any of those flags
|
// So we don't have to handle any of those flags
|
||||||
if (ClientVersionBit() & EQ::versions::maskSoFAndEarlier)
|
if (ClientVersionBit() & EQ::versions::maskSoFAndEarlier)
|
||||||
sneaking = false;
|
sneaking = false;
|
||||||
@@ -1552,19 +1554,24 @@ void Client::OPGMTraining(const EQApplicationPacket *app)
|
|||||||
|
|
||||||
Mob* pTrainer = entity_list.GetMob(gmtrain->npcid);
|
Mob* pTrainer = entity_list.GetMob(gmtrain->npcid);
|
||||||
|
|
||||||
if(!pTrainer || !pTrainer->IsNPC() || pTrainer->GetClass() < Class::WarriorGM || pTrainer->GetClass() > Class::BerserkerGM)
|
if (!pTrainer || !pTrainer->IsNPC() || pTrainer->GetClass() < Class::WarriorGM || pTrainer->GetClass() > Class::BerserkerGM) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//you can only use your own trainer, client enforces this, but why trust it
|
//you can only use your own trainer, client enforces this, but why trust it
|
||||||
if (!RuleB(Character, AllowCrossClassTrainers)) {
|
if (!RuleB(Character, AllowCrossClassTrainers)) {
|
||||||
int trains_class = pTrainer->GetClass() - (Class::WarriorGM - Class::Warrior);
|
int trains_class = pTrainer->GetClass() - (Class::WarriorGM - Class::Warrior);
|
||||||
if (GetClass() != trains_class)
|
if (GetClass() != trains_class) {
|
||||||
|
safe_delete(outapp);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//you have to be somewhat close to a trainer to be properly using them
|
//you have to be somewhat close to a trainer to be properly using them
|
||||||
if(DistanceSquared(m_Position,pTrainer->GetPosition()) > USE_NPC_RANGE2)
|
if (DistanceSquared(m_Position,pTrainer->GetPosition()) > USE_NPC_RANGE2) {
|
||||||
|
safe_delete(outapp);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// if this for-loop acts up again (crashes linux), try enabling the before and after #pragmas
|
// if this for-loop acts up again (crashes linux), try enabling the before and after #pragmas
|
||||||
//#pragma GCC push_options
|
//#pragma GCC push_options
|
||||||
@@ -1657,7 +1664,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app)
|
|||||||
// languages go here
|
// languages go here
|
||||||
if (gmskill->skill_id > 25)
|
if (gmskill->skill_id > 25)
|
||||||
{
|
{
|
||||||
std::cout << "Wrong Training Skill (languages)" << std::endl;
|
LogSkills("Wrong Training Skill (languages)");
|
||||||
DumpPacket(app);
|
DumpPacket(app);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1672,7 +1679,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app)
|
|||||||
// normal skills go here
|
// normal skills go here
|
||||||
if (gmskill->skill_id > EQ::skills::HIGHEST_SKILL)
|
if (gmskill->skill_id > EQ::skills::HIGHEST_SKILL)
|
||||||
{
|
{
|
||||||
std::cout << "Wrong Training Skill (abilities)" << std::endl;
|
LogSkills("Wrong Training Skill (abilities)");
|
||||||
DumpPacket(app);
|
DumpPacket(app);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1694,8 +1701,9 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app)
|
|||||||
if (skilllevel == 0) {
|
if (skilllevel == 0) {
|
||||||
//this is a new skill..
|
//this is a new skill..
|
||||||
uint16 t_level = SkillTrainLevel(skill, GetClass());
|
uint16 t_level = SkillTrainLevel(skill, GetClass());
|
||||||
if (t_level == 0)
|
|
||||||
{
|
if (t_level == 0) {
|
||||||
|
LogSkills("Tried to train a new skill [{}] which is invalid for this race/class.", skill);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1715,6 +1723,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app)
|
|||||||
case EQ::skills::SkillPottery:
|
case EQ::skills::SkillPottery:
|
||||||
if(skilllevel >= RuleI(Skills, MaxTrainTradeskills)) {
|
if(skilllevel >= RuleI(Skills, MaxTrainTradeskills)) {
|
||||||
MessageString(Chat::Red, MORE_SKILLED_THAN_I, pTrainer->GetCleanName());
|
MessageString(Chat::Red, MORE_SKILLED_THAN_I, pTrainer->GetCleanName());
|
||||||
|
SetSkill(skill, skilllevel);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -1725,6 +1734,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app)
|
|||||||
case EQ::skills::SkillSpecializeEvocation:
|
case EQ::skills::SkillSpecializeEvocation:
|
||||||
if(skilllevel >= RuleI(Skills, MaxTrainSpecializations)) {
|
if(skilllevel >= RuleI(Skills, MaxTrainSpecializations)) {
|
||||||
MessageString(Chat::Red, MORE_SKILLED_THAN_I, pTrainer->GetCleanName());
|
MessageString(Chat::Red, MORE_SKILLED_THAN_I, pTrainer->GetCleanName());
|
||||||
|
SetSkill(skill, skilllevel);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -1736,6 +1746,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app)
|
|||||||
{
|
{
|
||||||
// Don't allow training over max skill level
|
// Don't allow training over max skill level
|
||||||
MessageString(Chat::Red, MORE_SKILLED_THAN_I, pTrainer->GetCleanName());
|
MessageString(Chat::Red, MORE_SKILLED_THAN_I, pTrainer->GetCleanName());
|
||||||
|
SetSkill(skill, skilllevel);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1746,6 +1757,7 @@ void Client::OPGMTrainSkill(const EQApplicationPacket *app)
|
|||||||
{
|
{
|
||||||
// Restrict specialization training to follow the rules
|
// Restrict specialization training to follow the rules
|
||||||
MessageString(Chat::Red, MORE_SKILLED_THAN_I, pTrainer->GetCleanName());
|
MessageString(Chat::Red, MORE_SKILLED_THAN_I, pTrainer->GetCleanName());
|
||||||
|
SetSkill(skill, skilllevel);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -100,6 +100,7 @@ int command_init(void)
|
|||||||
command_add("camerashake", "[Duration (Milliseconds)] [Intensity (1-10)] - Shakes the camera on everyone's screen globally.", AccountStatus::QuestTroupe, command_camerashake) ||
|
command_add("camerashake", "[Duration (Milliseconds)] [Intensity (1-10)] - Shakes the camera on everyone's screen globally.", AccountStatus::QuestTroupe, command_camerashake) ||
|
||||||
command_add("castspell", "[Spell ID] [Instant (0 = False, 1 = True, Default is 1 if Unused)] - Cast a spell", AccountStatus::Guide, command_castspell) ||
|
command_add("castspell", "[Spell ID] [Instant (0 = False, 1 = True, Default is 1 if Unused)] - Cast a spell", AccountStatus::Guide, command_castspell) ||
|
||||||
command_add("chat", "[Channel ID] [Message] - Send a channel message to all zones", AccountStatus::GMMgmt, command_chat) ||
|
command_add("chat", "[Channel ID] [Message] - Send a channel message to all zones", AccountStatus::GMMgmt, command_chat) ||
|
||||||
|
command_add("clearxtargets", "Clears XTargets", AccountStatus::Player, command_clearxtargets) ||
|
||||||
command_add("copycharacter", "[source_char_name] [dest_char_name] [dest_account_name] - Copies character to destination account", AccountStatus::GMImpossible, command_copycharacter) ||
|
command_add("copycharacter", "[source_char_name] [dest_char_name] [dest_account_name] - Copies character to destination account", AccountStatus::GMImpossible, command_copycharacter) ||
|
||||||
command_add("corpse", "Manipulate corpses, use with no arguments for help", AccountStatus::Guide, command_corpse) ||
|
command_add("corpse", "Manipulate corpses, use with no arguments for help", AccountStatus::Guide, command_corpse) ||
|
||||||
command_add("corpsefix", "Attempts to bring corpses from underneath the ground within close proximity of the player", AccountStatus::Player, command_corpsefix) ||
|
command_add("corpsefix", "Attempts to bring corpses from underneath the ground within close proximity of the player", AccountStatus::Player, command_corpsefix) ||
|
||||||
@@ -238,7 +239,6 @@ int command_init(void)
|
|||||||
command_add("zonebootup", "[ZoneServerID] [shortname] - Make a zone server boot a specific zone", AccountStatus::GMLeadAdmin, command_zonebootup) ||
|
command_add("zonebootup", "[ZoneServerID] [shortname] - Make a zone server boot a specific zone", AccountStatus::GMLeadAdmin, command_zonebootup) ||
|
||||||
command_add("zoneinstance", "[Instance ID] [X] [Y] [Z] - Teleport to specified Instance by ID (coordinates are optional)", AccountStatus::Guide, command_zone_instance) ||
|
command_add("zoneinstance", "[Instance ID] [X] [Y] [Z] - Teleport to specified Instance by ID (coordinates are optional)", AccountStatus::Guide, command_zone_instance) ||
|
||||||
command_add("zoneshutdown", "[shortname] - Shut down a zone server", AccountStatus::GMLeadAdmin, command_zoneshutdown) ||
|
command_add("zoneshutdown", "[shortname] - Shut down a zone server", AccountStatus::GMLeadAdmin, command_zoneshutdown) ||
|
||||||
command_add("zopp", "Troubleshooting command - Sends a fake item packet to you. No server reference is created.", AccountStatus::GMImpossible, command_zopp) ||
|
|
||||||
command_add("zsave", " Saves zheader to the database", AccountStatus::QuestTroupe, command_zsave)
|
command_add("zsave", " Saves zheader to the database", AccountStatus::QuestTroupe, command_zsave)
|
||||||
) {
|
) {
|
||||||
command_deinit();
|
command_deinit();
|
||||||
@@ -792,6 +792,7 @@ void command_bot(Client *c, const Seperator *sep)
|
|||||||
#include "gm_commands/camerashake.cpp"
|
#include "gm_commands/camerashake.cpp"
|
||||||
#include "gm_commands/castspell.cpp"
|
#include "gm_commands/castspell.cpp"
|
||||||
#include "gm_commands/chat.cpp"
|
#include "gm_commands/chat.cpp"
|
||||||
|
#include "gm_commands/clearxtargets.cpp"
|
||||||
#include "gm_commands/copycharacter.cpp"
|
#include "gm_commands/copycharacter.cpp"
|
||||||
#include "gm_commands/corpse.cpp"
|
#include "gm_commands/corpse.cpp"
|
||||||
#include "gm_commands/corpsefix.cpp"
|
#include "gm_commands/corpsefix.cpp"
|
||||||
@@ -925,5 +926,4 @@ void command_bot(Client *c, const Seperator *sep)
|
|||||||
#include "gm_commands/zonebootup.cpp"
|
#include "gm_commands/zonebootup.cpp"
|
||||||
#include "gm_commands/zoneshutdown.cpp"
|
#include "gm_commands/zoneshutdown.cpp"
|
||||||
#include "gm_commands/zone_instance.cpp"
|
#include "gm_commands/zone_instance.cpp"
|
||||||
#include "gm_commands/zopp.cpp"
|
|
||||||
#include "gm_commands/zsave.cpp"
|
#include "gm_commands/zsave.cpp"
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ void SendNPCEditSubCommands(Client *c);
|
|||||||
void SendRuleSubCommands(Client *c);
|
void SendRuleSubCommands(Client *c);
|
||||||
void SendGuildSubCommands(Client *c);
|
void SendGuildSubCommands(Client *c);
|
||||||
void SendShowInventorySubCommands(Client *c);
|
void SendShowInventorySubCommands(Client *c);
|
||||||
|
void SendFixMobSubCommands(Client *c);
|
||||||
|
void SendDataBucketsSubCommands(Client *c);
|
||||||
|
|
||||||
// Commands
|
// Commands
|
||||||
void command_acceptrules(Client *c, const Seperator *sep);
|
void command_acceptrules(Client *c, const Seperator *sep);
|
||||||
@@ -51,6 +53,7 @@ void command_bugs(Client *c, const Seperator *sep);
|
|||||||
void command_camerashake(Client *c, const Seperator *sep);
|
void command_camerashake(Client *c, const Seperator *sep);
|
||||||
void command_castspell(Client *c, const Seperator *sep);
|
void command_castspell(Client *c, const Seperator *sep);
|
||||||
void command_chat(Client *c, const Seperator *sep);
|
void command_chat(Client *c, const Seperator *sep);
|
||||||
|
void command_clearxtargets(Client *c, const Seperator *sep);
|
||||||
void command_copycharacter(Client *c, const Seperator *sep);
|
void command_copycharacter(Client *c, const Seperator *sep);
|
||||||
void command_corpse(Client *c, const Seperator *sep);
|
void command_corpse(Client *c, const Seperator *sep);
|
||||||
void command_corpsefix(Client *c, const Seperator *sep);
|
void command_corpsefix(Client *c, const Seperator *sep);
|
||||||
|
|||||||
+1
-1
@@ -927,7 +927,7 @@ void Corpse::RemoveItem(ServerLootItem_Struct* item_data)
|
|||||||
|
|
||||||
UpdateEquipmentLight();
|
UpdateEquipmentLight();
|
||||||
if (UpdateActiveLight())
|
if (UpdateActiveLight())
|
||||||
SendAppearancePacket(AT_Light, GetActiveLightType());
|
SendAppearancePacket(AppearanceType::Light, GetActiveLightType());
|
||||||
|
|
||||||
safe_delete(sitem);
|
safe_delete(sitem);
|
||||||
return;
|
return;
|
||||||
|
|||||||
+45
-12
@@ -60,15 +60,7 @@ int64 Mob::GetActSpellDamage(uint16 spell_id, int64 value, Mob* target) {
|
|||||||
bool Critical = false;
|
bool Critical = false;
|
||||||
int64 base_value = value;
|
int64 base_value = value;
|
||||||
int chance = 0;
|
int chance = 0;
|
||||||
|
int legacy_manaburn_cap = RuleI(Spells, LegacyManaburnCap);
|
||||||
// Need to scale HT damage differently after level 40! It no longer scales by the constant value in the spell file. It scales differently, instead of 10 more damage per level, it does 30 more damage per level. So we multiply the level minus 40 times 20 if they are over level 40.
|
|
||||||
if ((spell_id == SPELL_HARM_TOUCH || spell_id == SPELL_HARM_TOUCH2 || spell_id == SPELL_IMP_HARM_TOUCH ) && GetLevel() > 40)
|
|
||||||
value -= (GetLevel() - 40) * 20;
|
|
||||||
|
|
||||||
//This adds the extra damage from the AA Unholy Touch, 450 per level to the AA Improved Harm TOuch.
|
|
||||||
if (spell_id == SPELL_IMP_HARM_TOUCH && IsOfClientBot()) { //Improved Harm Touch
|
|
||||||
value -= GetAA(aaUnholyTouch) * 450; //Unholy Touch
|
|
||||||
}
|
|
||||||
|
|
||||||
chance = RuleI(Spells, BaseCritChance); //Wizard base critical chance is 2% (Does not scale with level)
|
chance = RuleI(Spells, BaseCritChance); //Wizard base critical chance is 2% (Does not scale with level)
|
||||||
chance += itembonuses.CriticalSpellChance + spellbonuses.CriticalSpellChance + aabonuses.CriticalSpellChance;
|
chance += itembonuses.CriticalSpellChance + spellbonuses.CriticalSpellChance + aabonuses.CriticalSpellChance;
|
||||||
@@ -138,12 +130,30 @@ int64 Mob::GetActSpellDamage(uint16 spell_id, int64 value, Mob* target) {
|
|||||||
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, base_value) * ratio / 100;
|
value -= GetExtraSpellAmt(spell_id, itembonuses.SpellDmg, base_value) * ratio / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// legacy manaburn can crit, but is still held to the same cap
|
||||||
|
if (RuleB(Spells, LegacyManaburn) && spell_id == SPELL_MANA_BURN) {
|
||||||
|
if (value < -legacy_manaburn_cap) {
|
||||||
|
value = -legacy_manaburn_cap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
entity_list.FilteredMessageCloseString(
|
entity_list.FilteredMessageCloseString(
|
||||||
this, true, 100, Chat::SpellCrit, FilterSpellCrits,
|
this, true, 100, Chat::SpellCrit, FilterSpellCrits,
|
||||||
OTHER_CRIT_BLAST, nullptr, GetName(), itoa(-value));
|
OTHER_CRIT_BLAST, nullptr, GetName(), itoa(-value));
|
||||||
|
|
||||||
if (IsClient())
|
if (IsClient()) {
|
||||||
MessageString(Chat::SpellCrit, YOU_CRIT_BLAST, itoa(-value));
|
MessageString(Chat::SpellCrit, YOU_CRIT_BLAST, itoa(-value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Need to scale HT damage differently after level 40! It no longer scales by the constant value in the spell file. It scales differently, instead of 10 more damage per level, it does 30 more damage per level. So we multiply the level minus 40 times 20 if they are over level 40.
|
||||||
|
if ((spell_id == SPELL_HARM_TOUCH || spell_id == SPELL_HARM_TOUCH2 || spell_id == SPELL_IMP_HARM_TOUCH) && GetLevel() > 40) {
|
||||||
|
value -= (GetLevel() - 40) * 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
//This adds the extra damage from the AA Unholy Touch, 450 per level to the AA Improved Harm Touch.
|
||||||
|
if (spell_id == SPELL_IMP_HARM_TOUCH && IsOfClientBot()) { //Improved Harm Touch
|
||||||
|
value -= GetAA(aaUnholyTouch) * 450; //Unholy Touch
|
||||||
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@@ -183,6 +193,13 @@ int64 Mob::GetActSpellDamage(uint16 spell_id, int64 value, Mob* target) {
|
|||||||
value -= GetExtraSpellAmt(spell_id, GetSpellDmg(), base_value);
|
value -= GetExtraSpellAmt(spell_id, GetSpellDmg(), base_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply Manaburn Damage Cap
|
||||||
|
if (RuleB(Spells, LegacyManaburn) && spell_id == SPELL_MANA_BURN) {
|
||||||
|
if (value < -legacy_manaburn_cap) {
|
||||||
|
value = -legacy_manaburn_cap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -592,6 +609,22 @@ int32 Mob::GetActSpellCost(uint16 spell_id, int32 cost)
|
|||||||
|
|
||||||
int32 Mob::GetActSpellDuration(uint16 spell_id, int32 duration)
|
int32 Mob::GetActSpellDuration(uint16 spell_id, int32 duration)
|
||||||
{
|
{
|
||||||
|
// focuses don't affect discipline duration (Except War Cries)
|
||||||
|
if (
|
||||||
|
IsDiscipline(spell_id) &&
|
||||||
|
(
|
||||||
|
spell_id != SPELL_BATTLE_CRY &&
|
||||||
|
spell_id != SPELL_WAR_CRY &&
|
||||||
|
spell_id != SPELL_BATTLE_CRY_OF_DRAVEL &&
|
||||||
|
spell_id != SPELL_WAR_CRY_OF_DRAVEL &&
|
||||||
|
spell_id != SPELL_BATTLE_CRY_OF_THE_MASTRUQ &&
|
||||||
|
spell_id != SPELL_ANCIENT_CRY_OF_CHAOS &&
|
||||||
|
spell_id != SPELL_BLOODTHIRST
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return duration;
|
||||||
|
}
|
||||||
|
|
||||||
int increase = 100;
|
int increase = 100;
|
||||||
increase += GetFocusEffect(focusSpellDuration, spell_id);
|
increase += GetFocusEffect(focusSpellDuration, spell_id);
|
||||||
int tic_inc = 0;
|
int tic_inc = 0;
|
||||||
@@ -690,7 +723,7 @@ bool Client::TrainDiscipline(uint32 itemid) {
|
|||||||
return false;
|
return false;
|
||||||
} else if (m_pp.disciplines.values[r] == 0) {
|
} else if (m_pp.disciplines.values[r] == 0) {
|
||||||
m_pp.disciplines.values[r] = spell_id;
|
m_pp.disciplines.values[r] = spell_id;
|
||||||
database.SaveCharacterDisc(CharacterID(), r, spell_id);
|
database.SaveCharacterDiscipline(CharacterID(), r, spell_id);
|
||||||
SendDisciplineUpdate();
|
SendDisciplineUpdate();
|
||||||
Message(Chat::White, "You have learned a new discipline!");
|
Message(Chat::White, "You have learned a new discipline!");
|
||||||
return true;
|
return true;
|
||||||
@@ -789,7 +822,7 @@ void Client::TrainDiscBySpellID(int32 spell_id)
|
|||||||
for(i = 0; i < MAX_PP_DISCIPLINES; i++) {
|
for(i = 0; i < MAX_PP_DISCIPLINES; i++) {
|
||||||
if(m_pp.disciplines.values[i] == 0) {
|
if(m_pp.disciplines.values[i] == 0) {
|
||||||
m_pp.disciplines.values[i] = spell_id;
|
m_pp.disciplines.values[i] = spell_id;
|
||||||
database.SaveCharacterDisc(CharacterID(), i, spell_id);
|
database.SaveCharacterDiscipline(CharacterID(), i, spell_id);
|
||||||
SendDisciplineUpdate();
|
SendDisciplineUpdate();
|
||||||
Message(Chat::Yellow, "You have learned a new combat ability!");
|
Message(Chat::Yellow, "You have learned a new combat ability!");
|
||||||
return;
|
return;
|
||||||
|
|||||||
+1
-1
@@ -1891,6 +1891,7 @@ void PerlembParser::ExportEventVariables(
|
|||||||
ExportVar(package_name.c_str(), "killer_damage", sep.arg[1]);
|
ExportVar(package_name.c_str(), "killer_damage", sep.arg[1]);
|
||||||
ExportVar(package_name.c_str(), "killer_spell", sep.arg[2]);
|
ExportVar(package_name.c_str(), "killer_spell", sep.arg[2]);
|
||||||
ExportVar(package_name.c_str(), "killer_skill", sep.arg[3]);
|
ExportVar(package_name.c_str(), "killer_skill", sep.arg[3]);
|
||||||
|
ExportVar(package_name.c_str(), "killed_entity_id", sep.arg[4]);
|
||||||
|
|
||||||
if (extra_pointers && extra_pointers->size() >= 1) {
|
if (extra_pointers && extra_pointers->size() >= 1) {
|
||||||
Corpse *corpse = std::any_cast<Corpse *>(extra_pointers->at(0));
|
Corpse *corpse = std::any_cast<Corpse *>(extra_pointers->at(0));
|
||||||
@@ -1902,7 +1903,6 @@ void PerlembParser::ExportEventVariables(
|
|||||||
if (extra_pointers && extra_pointers->size() >= 2) {
|
if (extra_pointers && extra_pointers->size() >= 2) {
|
||||||
NPC *killed = std::any_cast<NPC *>(extra_pointers->at(1));
|
NPC *killed = std::any_cast<NPC *>(extra_pointers->at(1));
|
||||||
if (killed) {
|
if (killed) {
|
||||||
ExportVar(package_name.c_str(), "killed_entity_id", killed->GetID());
|
|
||||||
ExportVar(package_name.c_str(), "killed_bot_id", killed->IsBot() ? killed->CastToBot()->GetBotID() : 0);
|
ExportVar(package_name.c_str(), "killed_bot_id", killed->IsBot() ? killed->CastToBot()->GetBotID() : 0);
|
||||||
ExportVar(package_name.c_str(), "killed_npc_id", killed->IsNPC() ? killed->GetNPCTypeID() : 0);
|
ExportVar(package_name.c_str(), "killed_npc_id", killed->IsNPC() ? killed->GetNPCTypeID() : 0);
|
||||||
ExportVar(package_name.c_str(), "killed_x", killed->GetX());
|
ExportVar(package_name.c_str(), "killed_x", killed->GetX());
|
||||||
|
|||||||
+12
-12
@@ -93,13 +93,13 @@ void Perl__say(const char* message)
|
|||||||
// we currently default to these
|
// we currently default to these
|
||||||
opts.speak_mode = Journal::SpeakMode::Say;
|
opts.speak_mode = Journal::SpeakMode::Say;
|
||||||
opts.journal_mode = Journal::Mode::Log2;
|
opts.journal_mode = Journal::Mode::Log2;
|
||||||
opts.language = 0;
|
opts.language = Language::CommonTongue;
|
||||||
opts.message_type = Chat::NPCQuestSay;
|
opts.message_type = Chat::NPCQuestSay;
|
||||||
|
|
||||||
quest_manager.say(message, opts);
|
quest_manager.say(message, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perl__say(const char* message, int language_id)
|
void Perl__say(const char* message, uint8 language_id)
|
||||||
{
|
{
|
||||||
Journal::Options opts;
|
Journal::Options opts;
|
||||||
opts.speak_mode = Journal::SpeakMode::Say;
|
opts.speak_mode = Journal::SpeakMode::Say;
|
||||||
@@ -110,7 +110,7 @@ void Perl__say(const char* message, int language_id)
|
|||||||
quest_manager.say(message, opts);
|
quest_manager.say(message, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perl__say(const char* message, int language_id, int message_type)
|
void Perl__say(const char* message, uint8 language_id, int message_type)
|
||||||
{
|
{
|
||||||
Journal::Options opts;
|
Journal::Options opts;
|
||||||
opts.speak_mode = Journal::SpeakMode::Say;
|
opts.speak_mode = Journal::SpeakMode::Say;
|
||||||
@@ -121,7 +121,7 @@ void Perl__say(const char* message, int language_id, int message_type)
|
|||||||
quest_manager.say(message, opts);
|
quest_manager.say(message, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perl__say(const char* message, int language_id, int message_type, int speak_mode)
|
void Perl__say(const char* message, uint8 language_id, int message_type, int speak_mode)
|
||||||
{
|
{
|
||||||
Journal::Options opts;
|
Journal::Options opts;
|
||||||
opts.speak_mode = static_cast<Journal::SpeakMode>(speak_mode);
|
opts.speak_mode = static_cast<Journal::SpeakMode>(speak_mode);
|
||||||
@@ -132,7 +132,7 @@ void Perl__say(const char* message, int language_id, int message_type, int speak
|
|||||||
quest_manager.say(message, opts);
|
quest_manager.say(message, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perl__say(const char* message, int language_id, int message_type, int speak_mode, int journal_mode)
|
void Perl__say(const char* message, uint8 language_id, int message_type, int speak_mode, int journal_mode)
|
||||||
{
|
{
|
||||||
Journal::Options opts;
|
Journal::Options opts;
|
||||||
opts.speak_mode = static_cast<Journal::SpeakMode>(speak_mode);
|
opts.speak_mode = static_cast<Journal::SpeakMode>(speak_mode);
|
||||||
@@ -674,9 +674,9 @@ void Perl__addskill(int skill_id, int value)
|
|||||||
quest_manager.addskill(skill_id, value);
|
quest_manager.addskill(skill_id, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perl__setlanguage(int skill_id, int value)
|
void Perl__setlanguage(uint8 language_id, uint8 language_skill)
|
||||||
{
|
{
|
||||||
quest_manager.setlanguage(skill_id, value);
|
quest_manager.setlanguage(language_id, language_skill);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Perl__setskill(int skill_id, int value)
|
void Perl__setskill(int skill_id, int value)
|
||||||
@@ -4713,7 +4713,7 @@ std::string Perl__getfactionname(int faction_id)
|
|||||||
return quest_manager.getfactionname(faction_id);
|
return quest_manager.getfactionname(faction_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Perl__getlanguagename(int language_id)
|
std::string Perl__getlanguagename(uint8 language_id)
|
||||||
{
|
{
|
||||||
return quest_manager.getlanguagename(language_id);
|
return quest_manager.getlanguagename(language_id);
|
||||||
}
|
}
|
||||||
@@ -6532,10 +6532,10 @@ void perl_register_quest()
|
|||||||
package.add("safemove", &Perl__safemove);
|
package.add("safemove", &Perl__safemove);
|
||||||
package.add("save", &Perl__save);
|
package.add("save", &Perl__save);
|
||||||
package.add("say", (void(*)(const char*))&Perl__say);
|
package.add("say", (void(*)(const char*))&Perl__say);
|
||||||
package.add("say", (void(*)(const char*, int))&Perl__say);
|
package.add("say", (void(*)(const char*, uint8))&Perl__say);
|
||||||
package.add("say", (void(*)(const char*, int, int))&Perl__say);
|
package.add("say", (void(*)(const char*, uint8, int))&Perl__say);
|
||||||
package.add("say", (void(*)(const char*, int, int, int))&Perl__say);
|
package.add("say", (void(*)(const char*, uint8, int, int))&Perl__say);
|
||||||
package.add("say", (void(*)(const char*, int, int, int, int))&Perl__say);
|
package.add("say", (void(*)(const char*, uint8, int, int, int))&Perl__say);
|
||||||
package.add("saylink", (std::string(*)(const char*))&Perl__saylink);
|
package.add("saylink", (std::string(*)(const char*))&Perl__saylink);
|
||||||
package.add("saylink", (std::string(*)(const char*, bool))&Perl__saylink);
|
package.add("saylink", (std::string(*)(const char*, bool))&Perl__saylink);
|
||||||
package.add("saylink", (std::string(*)(const char*, bool, const char*))&Perl__saylink);
|
package.add("saylink", (std::string(*)(const char*, bool, const char*))&Perl__saylink);
|
||||||
|
|||||||
+3
-3
@@ -37,9 +37,9 @@ Encounter::Encounter(const char *enc_name) : Mob(
|
|||||||
nullptr, // in_lastname
|
nullptr, // in_lastname
|
||||||
0, // in_cur_hp
|
0, // in_cur_hp
|
||||||
0, // in_max_hp
|
0, // in_max_hp
|
||||||
MALE, // in_gender
|
Gender::Male, // in_gender
|
||||||
INVISIBLE_MAN, // in_race
|
Race::InvisibleMan, // in_race
|
||||||
0, // in_class
|
Class::None, // in_class
|
||||||
BT_NoTarget, // in_bodytype
|
BT_NoTarget, // in_bodytype
|
||||||
0, // in_deity
|
0, // in_deity
|
||||||
0, // in_level
|
0, // in_level
|
||||||
|
|||||||
+45
-21
@@ -1282,7 +1282,7 @@ uint16 EntityList::GetFreeID()
|
|||||||
// if no language skill is specified, sent with 100 skill
|
// if no language skill is specified, sent with 100 skill
|
||||||
void EntityList::ChannelMessage(Mob *from, uint8 chan_num, uint8 language, const char *message, ...)
|
void EntityList::ChannelMessage(Mob *from, uint8 chan_num, uint8 language, const char *message, ...)
|
||||||
{
|
{
|
||||||
ChannelMessage(from, chan_num, language, 100, message);
|
ChannelMessage(from, chan_num, language, Language::MaxValue, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EntityList::ChannelMessage(Mob *from, uint8 chan_num, uint8 language,
|
void EntityList::ChannelMessage(Mob *from, uint8 chan_num, uint8 language,
|
||||||
@@ -1411,7 +1411,7 @@ void EntityList::SendZonePVPUpdates(Client *to)
|
|||||||
while (it != client_list.end()) {
|
while (it != client_list.end()) {
|
||||||
Client *c = it->second;
|
Client *c = it->second;
|
||||||
if(c->GetPVP())
|
if(c->GetPVP())
|
||||||
c->SendAppearancePacket(AT_PVP, c->GetPVP(), true, false, to);
|
c->SendAppearancePacket(AppearanceType::PVP, c->GetPVP(), true, false, to);
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1491,18 +1491,21 @@ void EntityList::RemoveFromTargets(Mob *mob, bool RemoveFromXTargets)
|
|||||||
Mob *m = it->second;
|
Mob *m = it->second;
|
||||||
++it;
|
++it;
|
||||||
|
|
||||||
if (!m)
|
if (!m) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (RemoveFromXTargets && mob) {
|
if (RemoveFromXTargets && mob) {
|
||||||
if (m->IsClient() && (mob->CheckAggro(m) || mob->IsOnFeignMemory(m)))
|
if (m->IsClient() && (mob->CheckAggro(m) || mob->IsOnFeignMemory(m))) {
|
||||||
m->CastToClient()->RemoveXTarget(mob, false);
|
m->CastToClient()->RemoveXTarget(mob, false);
|
||||||
// FadingMemories calls this function passing the client.
|
// FadingMemories calls this function passing the client.
|
||||||
else if (mob->IsClient() && (m->CheckAggro(mob) || m->IsOnFeignMemory(mob)))
|
} else if (mob->IsClient() && (m->CheckAggro(mob) || m->IsOnFeignMemory(mob))) {
|
||||||
mob->CastToClient()->RemoveXTarget(m, false);
|
mob->CastToClient()->RemoveXTarget(m, false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m->RemoveFromHateList(mob);
|
m->RemoveFromHateList(mob);
|
||||||
|
m->RemoveFromRampageList(mob);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1515,20 +1518,24 @@ void EntityList::RemoveFromTargetsFadingMemories(Mob *spell_target, bool RemoveF
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (max_level && mob->GetLevel() > max_level)
|
if (max_level && mob->GetLevel() > max_level) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (mob->GetSpecialAbility(IMMUNE_FADING_MEMORIES))
|
if (mob->GetSpecialAbility(IMMUNE_FADING_MEMORIES)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (RemoveFromXTargets && spell_target) {
|
if (RemoveFromXTargets && spell_target) {
|
||||||
if (mob->IsClient() && (spell_target->CheckAggro(mob) || spell_target->IsOnFeignMemory(mob)))
|
if (mob->IsClient() && (spell_target->CheckAggro(mob) || spell_target->IsOnFeignMemory(mob))) {
|
||||||
mob->CastToClient()->RemoveXTarget(spell_target, false);
|
mob->CastToClient()->RemoveXTarget(spell_target, false);
|
||||||
else if (spell_target->IsClient() && (mob->CheckAggro(spell_target) || mob->IsOnFeignMemory(spell_target)))
|
} else if (spell_target->IsClient() && (mob->CheckAggro(spell_target) || mob->IsOnFeignMemory(spell_target))) {
|
||||||
spell_target->CastToClient()->RemoveXTarget(mob, false);
|
spell_target->CastToClient()->RemoveXTarget(mob, false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mob->RemoveFromHateList(spell_target);
|
mob->RemoveFromHateList(spell_target);
|
||||||
|
mob->RemoveFromRampageList(spell_target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1814,14 +1821,14 @@ void EntityList::DuelMessage(Mob *winner, Mob *loser, bool flee)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Client *EntityList::GetClientByName(const char *checkname)
|
Client *EntityList::GetClientByName(const char* name)
|
||||||
{
|
{
|
||||||
auto it = client_list.begin();
|
for (const auto& e : client_list) {
|
||||||
while (it != client_list.end()) {
|
if (e.second && Strings::EqualFold(e.second->GetName(), name)) {
|
||||||
if (strcasecmp(it->second->GetName(), checkname) == 0)
|
return e.second;
|
||||||
return it->second;
|
|
||||||
++it;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3188,8 +3195,10 @@ void EntityList::RemoveFromHateLists(Mob *mob, bool settoone)
|
|||||||
if (it->second->CheckAggro(mob)) {
|
if (it->second->CheckAggro(mob)) {
|
||||||
if (!settoone) {
|
if (!settoone) {
|
||||||
it->second->RemoveFromHateList(mob);
|
it->second->RemoveFromHateList(mob);
|
||||||
if (mob->IsClient())
|
it->second->RemoveFromRampageList(mob);
|
||||||
|
if (mob->IsClient()) {
|
||||||
mob->CastToClient()->RemoveXTarget(it->second, false); // gotta do book keeping
|
mob->CastToClient()->RemoveXTarget(it->second, false); // gotta do book keeping
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
it->second->SetHateAmountOnEnt(mob, 1);
|
it->second->SetHateAmountOnEnt(mob, 1);
|
||||||
}
|
}
|
||||||
@@ -3536,20 +3545,29 @@ void EntityList::HalveAggro(Mob *who)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//removes "targ" from all hate lists, including feigned, in the zone
|
//removes "targ" from all hate lists, including feigned, in the zone
|
||||||
void EntityList::ClearAggro(Mob* targ)
|
void EntityList::ClearAggro(Mob* targ, bool clear_caster_id)
|
||||||
{
|
{
|
||||||
Client *c = nullptr;
|
Client *c = nullptr;
|
||||||
|
|
||||||
if (targ->IsClient()) {
|
if (targ->IsClient()) {
|
||||||
c = targ->CastToClient();
|
c = targ->CastToClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto it = npc_list.begin();
|
auto it = npc_list.begin();
|
||||||
while (it != npc_list.end()) {
|
while (it != npc_list.end()) {
|
||||||
|
if (clear_caster_id) {
|
||||||
|
it->second->BuffDetachCaster(targ);
|
||||||
|
}
|
||||||
|
|
||||||
if (it->second->CheckAggro(targ)) {
|
if (it->second->CheckAggro(targ)) {
|
||||||
if (c) {
|
if (c) {
|
||||||
c->RemoveXTarget(it->second, false);
|
c->RemoveXTarget(it->second, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
it->second->RemoveFromHateList(targ);
|
it->second->RemoveFromHateList(targ);
|
||||||
|
it->second->RemoveFromRampageList(targ, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c && it->second->IsOnFeignMemory(c)) {
|
if (c && it->second->IsOnFeignMemory(c)) {
|
||||||
it->second->RemoveFromFeignMemory(c); //just in case we feigned
|
it->second->RemoveFromFeignMemory(c); //just in case we feigned
|
||||||
c->RemoveXTarget(it->second, false);
|
c->RemoveXTarget(it->second, false);
|
||||||
@@ -3573,6 +3591,7 @@ void EntityList::ClearWaterAggro(Mob* targ)
|
|||||||
c->RemoveXTarget(it->second, false);
|
c->RemoveXTarget(it->second, false);
|
||||||
}
|
}
|
||||||
it->second->RemoveFromHateList(targ);
|
it->second->RemoveFromHateList(targ);
|
||||||
|
it->second->RemoveFromRampageList(targ);
|
||||||
}
|
}
|
||||||
if (c && it->second->IsOnFeignMemory(c)) {
|
if (c && it->second->IsOnFeignMemory(c)) {
|
||||||
it->second->RemoveFromFeignMemory(c); //just in case we feigned
|
it->second->RemoveFromFeignMemory(c); //just in case we feigned
|
||||||
@@ -3618,6 +3637,11 @@ void EntityList::ClearFeignAggro(Mob *targ)
|
|||||||
}
|
}
|
||||||
|
|
||||||
it->second->RemoveFromHateList(targ);
|
it->second->RemoveFromHateList(targ);
|
||||||
|
|
||||||
|
if (it->second->GetSpecialAbility(SPECATK_RAMPAGE)) {
|
||||||
|
it->second->RemoveFromRampageList(targ, true);
|
||||||
|
}
|
||||||
|
|
||||||
if (targ->IsClient()) {
|
if (targ->IsClient()) {
|
||||||
if (it->second->GetLevel() >= 35 && zone->random.Roll(60)) {
|
if (it->second->GetLevel() >= 35 && zone->random.Roll(60)) {
|
||||||
it->second->AddFeignMemory(targ);
|
it->second->AddFeignMemory(targ);
|
||||||
@@ -4588,7 +4612,7 @@ void EntityList::GroupMessage(uint32 gid, const char *from, const char *message)
|
|||||||
g = it->second->GetGroup();
|
g = it->second->GetGroup();
|
||||||
if (g) {
|
if (g) {
|
||||||
if (g->GetID() == gid)
|
if (g->GetID() == gid)
|
||||||
it->second->ChannelMessageSend(from, it->second->GetName(), ChatChannel_Group, 0, 100, message);
|
it->second->ChannelMessageSend(from, it->second->GetName(), ChatChannel_Group, Language::CommonTongue, Language::MaxValue, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++it;
|
++it;
|
||||||
@@ -4704,10 +4728,10 @@ void EntityList::SendZoneAppearance(Client *c)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (cur->GetAppearance() != eaStanding) {
|
if (cur->GetAppearance() != eaStanding) {
|
||||||
cur->SendAppearancePacket(AT_Anim, cur->GetAppearanceValue(cur->GetAppearance()), false, true, c);
|
cur->SendAppearancePacket(AppearanceType::Animation, cur->GetAppearanceValue(cur->GetAppearance()), false, true, c);
|
||||||
}
|
}
|
||||||
if (cur->GetSize() != cur->GetBaseSize()) {
|
if (cur->GetSize() != cur->GetBaseSize()) {
|
||||||
cur->SendAppearancePacket(AT_Size, (uint32) cur->GetSize(), false, true, c);
|
cur->SendAppearancePacket(AppearanceType::Size, (uint32) cur->GetSize(), false, true, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++it;
|
++it;
|
||||||
@@ -4781,7 +4805,7 @@ void EntityList::SendAppearanceEffects(Client *c)
|
|||||||
++it;
|
++it;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
cur->SendSavedAppearenceEffects(c);
|
cur->SendSavedAppearanceEffects(c);
|
||||||
}
|
}
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -463,7 +463,7 @@ public:
|
|||||||
void UpdateHoTT(Mob* target);
|
void UpdateHoTT(Mob* target);
|
||||||
|
|
||||||
void Process();
|
void Process();
|
||||||
void ClearAggro(Mob* targ);
|
void ClearAggro(Mob* targ, bool clear_caster_id = false);
|
||||||
void ClearWaterAggro(Mob* targ);
|
void ClearWaterAggro(Mob* targ);
|
||||||
void ClearFeignAggro(Mob* targ);
|
void ClearFeignAggro(Mob* targ);
|
||||||
void ClearZoneFeignAggro(Mob* targ);
|
void ClearZoneFeignAggro(Mob* targ);
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
|
|
||||||
|
|
||||||
This library is free software; you can redistribute it and/or
|
|
||||||
modify it under the terms of the GNU Library General Public
|
|
||||||
License as published by the Free Software Foundation; either
|
|
||||||
version 2 of the License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This library is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
Library General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Library General Public
|
|
||||||
License along with this library; if not, write to the Free
|
|
||||||
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
|
|
||||||
MA 02111-1307, USA */
|
|
||||||
|
|
||||||
/* Error messages for mysql clients */
|
|
||||||
/* error messages for the demon is in share/language/errmsg.sys */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
void init_client_errs(void);
|
|
||||||
extern const char *client_errors[]; /* Error messages */
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CR_MIN_ERROR 2000 /* For easier client code */
|
|
||||||
#define CR_MAX_ERROR 2999
|
|
||||||
#if defined(OS2) && defined( MYSQL_SERVER)
|
|
||||||
#define CER(X) client_errors[(X)-CR_MIN_ERROR]
|
|
||||||
#else
|
|
||||||
#define ER(X) client_errors[(X)-CR_MIN_ERROR]
|
|
||||||
#endif
|
|
||||||
#define CLIENT_ERRMAP 2 /* Errormap used by my_error() */
|
|
||||||
|
|
||||||
#define CR_UNKNOWN_ERROR 2000
|
|
||||||
#define CR_SOCKET_CREATE_ERROR 2001
|
|
||||||
#define CR_CONNECTION_ERROR 2002
|
|
||||||
#define CR_CONN_HOST_ERROR 2003
|
|
||||||
#define CR_IPSOCK_ERROR 2004
|
|
||||||
#define CR_UNKNOWN_HOST 2005
|
|
||||||
#define CR_SERVER_GONE_ERROR 2006
|
|
||||||
#define CR_VERSION_ERROR 2007
|
|
||||||
#define CR_OUT_OF_MEMORY 2008
|
|
||||||
#define CR_WRONG_HOST_INFO 2009
|
|
||||||
#define CR_LOCALHOST_CONNECTION 2010
|
|
||||||
#define CR_TCP_CONNECTION 2011
|
|
||||||
#define CR_SERVER_HANDSHAKE_ERR 2012
|
|
||||||
#define CR_SERVER_LOST 2013
|
|
||||||
#define CR_COMMANDS_OUT_OF_SYNC 2014
|
|
||||||
#define CR_NAMEDPIPE_CONNECTION 2015
|
|
||||||
#define CR_NAMEDPIPEWAIT_ERROR 2016
|
|
||||||
#define CR_NAMEDPIPEOPEN_ERROR 2017
|
|
||||||
#define CR_NAMEDPIPESETSTATE_ERROR 2018
|
|
||||||
#define CR_CANT_READ_CHARSET 2019
|
|
||||||
#define CR_NET_PACKET_TOO_LARGE 2020
|
|
||||||
|
|
||||||
+1
-1
@@ -950,7 +950,7 @@ void Client::SetLevel(uint8 set_level, bool command)
|
|||||||
|
|
||||||
QueuePacket(outapp);
|
QueuePacket(outapp);
|
||||||
safe_delete(outapp);
|
safe_delete(outapp);
|
||||||
SendAppearancePacket(AT_WhoLevel, set_level); // who level change
|
SendAppearancePacket(AppearanceType::WhoLevel, set_level); // who level change
|
||||||
|
|
||||||
LogInfo("Setting Level for [{}] to [{}]", GetName(), set_level);
|
LogInfo("Setting Level for [{}] to [{}]", GetName(), set_level);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1171,7 +1171,7 @@ bool Expedition::HasLockoutByCharacterID(
|
|||||||
{
|
{
|
||||||
auto lockouts = Expedition::GetExpeditionLockoutsByCharacterID(character_id);
|
auto lockouts = Expedition::GetExpeditionLockoutsByCharacterID(character_id);
|
||||||
return std::any_of(lockouts.begin(), lockouts.end(), [&](const ExpeditionLockoutTimer& lockout) {
|
return std::any_of(lockouts.begin(), lockouts.end(), [&](const ExpeditionLockoutTimer& lockout) {
|
||||||
return lockout.IsSameLockout(expedition_name, event_name);
|
return !lockout.IsExpired() && lockout.IsSameLockout(expedition_name, event_name);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,6 @@ void command_acceptrules(Client *c, const Seperator *sep)
|
|||||||
}
|
}
|
||||||
|
|
||||||
database.SetAgreementFlag(c->AccountID());
|
database.SetAgreementFlag(c->AccountID());
|
||||||
c->SendAppearancePacket(AT_Anim, ANIM_STAND);
|
c->SendAppearancePacket(AppearanceType::Animation, Animation::Standing);
|
||||||
c->Message(Chat::White, "It is recorded you have agreed to the rules.");
|
c->Message(Chat::White, "It is recorded you have agreed to the rules.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,25 +2,43 @@
|
|||||||
|
|
||||||
void command_appearance(Client *c, const Seperator *sep)
|
void command_appearance(Client *c, const Seperator *sep)
|
||||||
{
|
{
|
||||||
Mob *t = c->CastToMob();
|
const int arguments = sep->argnum;
|
||||||
|
if (!arguments || !sep->IsNumber(1) || !sep->IsNumber(2)) {
|
||||||
|
c->Message(Chat::White, "Usage: #appearance [Type] [Value]");
|
||||||
|
c->Message(Chat::White, "Note: Types are as follows:");
|
||||||
|
|
||||||
// sends any appearance packet
|
for (const auto& a : EQ::constants::GetAppearanceTypeMap()) {
|
||||||
// Dev debug command, for appearance types
|
|
||||||
if (sep->arg[2][0] == 0) {
|
|
||||||
c->Message(Chat::White, "Usage: #appearance type value");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ((c->GetTarget())) {
|
|
||||||
t = c->GetTarget();
|
|
||||||
}
|
|
||||||
t->SendAppearancePacket(Strings::ToInt(sep->arg[1]), Strings::ToInt(sep->arg[2]));
|
|
||||||
c->Message(
|
c->Message(
|
||||||
Chat::White,
|
Chat::White,
|
||||||
"Sending appearance packet: target=%s, type=%s, value=%s",
|
fmt::format(
|
||||||
t->GetName(),
|
"Appearance Type {} | {}",
|
||||||
sep->arg[1],
|
a.first,
|
||||||
sep->arg[2]
|
a.second
|
||||||
|
).c_str()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Mob *t = c;
|
||||||
|
if (c->GetTarget()) {
|
||||||
|
t = c->GetTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32 type = Strings::ToUnsignedInt(sep->arg[1]);
|
||||||
|
const uint32 value = Strings::ToUnsignedInt(sep->arg[2]);
|
||||||
|
|
||||||
|
t->SendAppearancePacket(type, value);
|
||||||
|
|
||||||
|
c->Message(
|
||||||
|
Chat::White,
|
||||||
|
fmt::format(
|
||||||
|
"Appearance Sent to {} | Type: {} ({}) Value: {}",
|
||||||
|
c->GetTargetDescription(t, TargetDescriptionType::UCSelf),
|
||||||
|
EQ::constants::GetAppearanceTypeName(type),
|
||||||
|
type,
|
||||||
|
value
|
||||||
|
).c_str()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ void command_appearanceeffects(Client *c, const Seperator *sep)
|
|||||||
.texture = t->GetTexture(),
|
.texture = t->GetTexture(),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
t->ClearAppearenceEffects();
|
t->ClearAppearanceEffects();
|
||||||
c->Message(
|
c->Message(
|
||||||
Chat::White,
|
Chat::White,
|
||||||
fmt::format(
|
fmt::format(
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user