Compare commits

..

330 Commits

Author SHA1 Message Date
E Spause a3f21cc9ea Additional fixups. 2017-03-16 13:27:58 -04:00
E Spause 3c9e6d913a Merge remote-tracking branch 'refs/remotes/origin/master' into 2002_fixes 2017-03-16 13:23:56 -04:00
Michael Cook (mackal) 153e587cea Not sure how that happened 2017-03-16 12:56:21 -04:00
Michael Cook (mackal) fbb13ec416 bug found by clang 4 2017-03-16 12:52:58 -04:00
Michael Cook (mackal) e7785d5693 Bash dmg should return 0 with no item (slam) 2017-03-15 15:25:42 -04:00
Michael Cook (mackal) 23bc535e23 Tweaks to most likely wrong PVP damage reduction 2017-03-15 15:07:28 -04:00
Michael Cook (mackal) d04d6750a2 Allow base damage of 0 (ex slam) min damage done to 1 2017-03-15 13:22:45 -04:00
E Spause 9c08d6f25b Fix additional logic cases for merc disbanding. 2017-03-15 07:09:14 -04:00
E Spause f8d000d660 Don't allow disbanding mercs that have their owner in combat if the rule is set. 2017-03-15 06:52:16 -04:00
E Spause b2c6bb4df5 Set default, no-skill value for bash to 1. This is consistent with what demonstar was seeing on live with no skill and slam.
GetBaseDamage is now used for Bash/Slam additionally.
2017-03-15 06:39:57 -04:00
E Spause 542d0795c4 Add rule instead of define for IDLE_WHEN_EMPTY 2017-03-15 06:37:03 -04:00
E Spause c3b7f6d0bf Merge remote-tracking branch 'refs/remotes/origin/master' into 2002_fixes 2017-03-15 06:15:04 -04:00
E Spause 21e53a3cd0 Fix up slam some more 2017-03-15 06:15:01 -04:00
Uleat 2d24237aac Added los movement logic to combat and follow code (los is rule-based and can by disabled by applying the optional 2017_03_14_mercs_use_pathing_rule.sql) 2017-03-14 23:23:42 -04:00
Uleat 750e65f847 Merge branch 'master' of https://github.com/EQEmu/Server 2017-03-14 23:21:24 -04:00
E Spause 3ce99d9f00 Stupid sexy floats 2017-03-14 22:42:14 -04:00
E Spause 598196329d Bash min skill fix 2017-03-14 22:15:22 -04:00
Uleat 31cc6f63d6 Added evade code to rogue mercs 2017-03-14 16:32:10 -04:00
E Spause bbfacd902c Woops 2017-03-13 15:08:20 -04:00
E Spause 5cfb3111a6 SoF-era con system. New rule, UseOldConSystem to disable this functionality. 2017-03-13 15:07:56 -04:00
E Spause 5b674f23bd Merge remote-tracking branch 'refs/remotes/origin/master' into 2002_fixes 2017-03-13 15:05:26 -04:00
E Spause 81cadf3bb2 Merge pull request #593 from EQEmu/2002_fixes
MaxClientsSimplifiedLogic rule. See commit for description
2017-03-13 14:59:30 -04:00
E Spause 54c28117a8 Merge remote-tracking branch 'refs/remotes/origin/master' into 2002_fixes 2017-03-13 06:27:01 -04:00
E Spause 79f9433dfa Merc logic fix for heal spells - allows mercs to select fast healing spells as a 'standard' healing spell & new rule for unsuspend 2017-03-13 06:26:48 -04:00
E Spause 67a95b59a7 Merge remote-tracking branch 'refs/remotes/origin/master' into 2002_fixes 2017-03-12 23:20:55 -04:00
E Spause 09b9d398e2 Rule itself for MaxClientsSimplifiedLogic. Defaults to disabled (false) 2017-03-12 23:19:50 -04:00
E Spause 3dd0d43e96 Add a rule, MaxClientsSimplifiedLogic which allows for P99-style IP restrictions if enabled. Opcode handler for OP_WorldLogout in char sel.
Only uses ExemptAccountLimitStatus and MaxClientsPerIP. Also adds in an
opcode handler so CLEs are cleaned up at char select when ESC is
pressed.
2017-03-12 23:19:24 -04:00
E Spause 8d1fe63e77 Merge pull request #592 from EQEmu/2002_fixes
Remove delay death from Mercs so they function like normal NPCs at 0 health.
2017-03-12 23:17:08 -04:00
E Spause 3fa72218a4 Remove delay death from Mercs so they function like normal NPCs at 0 health. 2017-03-12 23:08:59 -04:00
Uleat f3f034d948 Fix for a combat ability targeting error 2017-03-12 21:46:16 -04:00
Michael Cook (mackal) bd364a4049 Merge pull request #591 from EQEmu/2002_fixes
Added an optional rule value that forces startzones to be the same as…
2017-03-12 19:21:05 -04:00
Akkadius 41b1634199 Update proper file name utils/sql/git/optional/2017_03_12_rule_values_range_update.sql [skip ci] 2017-03-12 17:19:42 -05:00
Akkadius 0159e1cc72 Fix some crapped out formatting [skip ci] 2017-03-12 16:42:26 -05:00
Akkadius ab372b0f6b - Implemented range rules for packets and other functions
RULE_INT ( Range, Say, 135 )
	RULE_INT ( Range, Emote, 135 )
	RULE_INT ( Range, BeginCast, 200)
	RULE_INT ( Range, Anims, 135)
	RULE_INT ( Range, SpellParticles, 135)
	RULE_INT ( Range, DamageMessages, 50)
	RULE_INT ( Range, SpellMessages, 75)
	RULE_INT ( Range, SongMessages, 75)
	RULE_INT ( Range, MobPositionUpdates, 600)
	RULE_INT ( Range, CriticalDamage, 80)

 - (Readability) Also cleaned up some formatting in messaging and packets so it is easier to understand what is going on with the code
2017-03-12 16:10:53 -05:00
Akkadius 14d09485eb Implement new rule based ranges for various range based packet operations (performance)
- the defaults are set in the code and can be tweaked by sourcing utils/sql/git/optional/rule_values_range_update.sql
- Thanks to mackal for gathering live ranges, thanks to takp for initial numbers
- We would send 200 for combat updates and the client will only display <= range 54 anyways, these should help a lot in spammy combat

RULE_CATEGORY( Range )
RULE_INT ( Range, Say, 135 )
RULE_INT ( Range, Emote, 135 )
RULE_INT ( Range, BeginCast, 200)
RULE_INT ( Range, Anims, 135)
RULE_INT ( Range, DamageMessages, 50)
RULE_INT ( Range, SpellMessages, 75)
RULE_INT ( Range, SongMessages, 75)
RULE_CATEGORY_END()
2017-03-12 14:38:14 -05:00
Uleat 8cd6416754 Added ItemData::CheckLoreConflict() 2017-03-12 14:20:22 -04:00
E Spause 4fad93824b Formatting fixes. 2017-03-12 03:49:41 -04:00
E Spause fe70834a6b Enabled a skill check bypass for OGRE, TROLL, and BARBARIAN races so the "Slam" skill works once more. 2017-03-12 03:49:07 -04:00
E Spause 17b5cc1fa5 Remove error message that has honestly bothered me since the dawn of time. Appears most often when doing loot all. EQLive does not have it. 2017-03-12 03:47:26 -04:00
E Spause 04ce4f66ed Added an optional rule value that forces startzones to be the same as the bind zone and enabled bind xyz once again. 2017-03-12 03:41:21 -04:00
Uleat 5b24cbde5d Merge branch 'master' of https://github.com/EQEmu/Server 2017-03-11 13:35:40 -05:00
Uleat 3555791e1f Multi-line remark statements wreck havoc on visual studio's parser (expensive) 2017-03-11 13:35:30 -05:00
Michael Cook (mackal) 262bcf5c29 Fix merc attack delay 2017-03-10 19:17:04 -05:00
Uleat 226a49cb42 Merge branch 'master' of https://github.com/EQEmu/Server 2017-03-10 18:41:14 -05:00
Uleat bf3d9b2d02 Couple of critical fixes for bot trade code 2017-03-10 18:41:04 -05:00
Michael Cook (mackal) 3d229e1da1 Aggro Meter on by default now (seemed fine on PEQ) 2017-03-10 18:15:08 -05:00
Michael Cook (mackal) df5d58f43d Temp pets shouldn't spawn when they're targeting a corpse 2017-03-10 13:00:22 -05:00
Uleat 37d22e17a3 First step of implementing inventory v2.0 2017-03-09 02:46:09 -05:00
Uleat 999650d368 Fixed a few glitches related to bot trading and other affected code 2017-03-09 01:55:01 -05:00
Uleat 09bbfbcc31 Complete rework of the bot trading system (see changelog.txt) 2017-03-08 08:12:04 -05:00
Drajor f26b7a4adc Hacky fix for quantity wrapping when stacked items are sold that have a quantity greater than 255. A better solution will need to implemented long term 2017-03-08 06:22:17 +10:00
Uleat becd7b5c24 This probably resolves a long-term bug with bots who are conscientious objectors to fighting... (Had a rash of reports concerning this -- obscure attack timer bug within inherited NPC class ctor) 2017-03-05 05:12:54 -05:00
Uleat d559e9da10 Fix for bot auto-combat damage (please post any abnormalities) 2017-03-04 14:50:32 -05:00
Uleat 2690d8fed8 Added inspect buff cases for bots (ZombieSoul) 2017-03-03 17:51:02 -05:00
Michael Cook (mackal) 7d13475bac Fix ClearAggro xtarget issue 2017-03-02 14:31:48 -05:00
Uleat 2ab280bef0 Merge branch 'master' of https://github.com/EQEmu/Server 2017-03-01 19:16:09 -05:00
Uleat 15af28720a Bad logic..not used anyways 2017-03-01 19:16:02 -05:00
Akkadius 5213e4c7d4 Remove table that doesn't exist anymore (PEQ Dumps) [skip ci] 2017-03-01 15:19:56 -06:00
Uleat 12d7f242b4 Tweaked bot caster combat range code a little (they shouldn't pile up unless there are los issues...) 2017-03-01 16:11:17 -05:00
Uleat 7ac597270b Merge branch 'master' of https://github.com/EQEmu/Server 2017-02-28 20:29:32 -05:00
Uleat 05ca4669a9 Fix for aberrant bot animations when using ^summon (i.e., swimming in air) 2017-02-28 10:39:26 -05:00
Uleat a7cbe2f60e Fix for npc corpse looting not updating appearance of looted items 2017-02-28 09:44:24 -05:00
Uleat 52d79f89a9 Bots should now /con correctly after a successful ^update 2017-02-28 08:49:25 -05:00
Michael Cook (mackal) a8a1c3f809 Better comment some group shit 2017-02-28 02:21:44 -05:00
Uleat 24bae49401 Merge branch 'master' of https://github.com/EQEmu/Server 2017-02-27 21:32:17 -05:00
Uleat bf239f9691 A 'hack' and a 'fix' (bot movement changes) 2017-02-27 21:32:07 -05:00
Michael Cook (mackal) 666513c4ab Better comment SendGroupCreatePacket 2017-02-27 15:21:50 -05:00
Uleat 1b2df18cea Merge branch 'master' of https://github.com/EQEmu/Server 2017-02-26 22:14:34 -05:00
Uleat b1be667884 Update bot spell casting chances table and implemented 'pre-combat' mode for all bots (only bard is actively coded atm) 2017-02-26 22:13:41 -05:00
Michael Cook (mackal) 91ae6a6613 Secondary aggro meter fix 2017-02-26 19:13:47 -05:00
Uleat 303f056075 Forgot loader... 2017-02-26 07:02:20 -05:00
Uleat ec9af74dc9 Update bot spells entries for new npc spells id values 2017-02-26 07:00:24 -05:00
Uleat a49e3d6471 Update for saved bot data to use new spells id values 2017-02-26 06:26:59 -05:00
Uleat 9ae585dd81 Moved bot npc spells entries to the 3000 + class id range 2017-02-26 05:47:10 -05:00
Uleat 0ee3168241 Merge branch 'master' of https://github.com/EQEmu/Server 2017-02-25 18:02:47 -05:00
Michael Cook (mackal) 3fd40e9449 Make ST_AreaNPCOnly skip faction check
The motivation for this is there a bunch of auras that use this target type
that all would require setting up faction for these NPCs so they would hate
everything.

Also allows Ward of Destruction to work.
2017-02-25 14:36:17 -05:00
Uleat c61c275221 Added position update packet in out-of-combat movement code when movement occurs (rule-based; default: false) - appears to help with rubber-banding effect 2017-02-25 09:02:20 -05:00
Uleat 7a6d5d46f4 Added node pathing to the bot movement dilemma... 2017-02-25 03:48:02 -05:00
Michael Cook (mackal) 14a5ff399a clear xtarget manager on death 2017-02-25 02:37:57 -05:00
Michael Cook (mackal) 31907382c8 Lets not aggro zonign clients 2017-02-25 02:21:48 -05:00
Uleat 5c6492bc0f Merge branch 'master' of https://github.com/EQEmu/Server 2017-02-24 20:09:53 -05:00
Michael Cook (mackal) 0968ce0d60 Add petnaming type 5 (`s ward) 2017-02-24 15:28:22 -05:00
Uleat 171474f1d2 Fix for bot combat line-of-sight issue (let me know if this causes zone training again) 2017-02-24 10:02:50 -05:00
Uleat 3383f65ff7 Updated bot casting roles to not refresh with every spell cast (oversight in recent casting chances commit) 2017-02-24 04:48:33 -05:00
Michael Cook (mackal) 7621bf47c8 Quick fix to resolve some serious group issues
Group leader swapping didn't work and left the client in a bad state
This just disbands the group if the leader leaves

Also prevents a group leader from disbanding other groups ...
Which also lead to bad states

Group leader swapping not working is better than these issues :P
2017-02-24 01:12:46 -05:00
Uleat 72ed770037 Merge branch 'master' of https://github.com/EQEmu/Server 2017-02-23 19:16:54 -05:00
Uleat 4e8a03f7b4 Migrated bot spell casting chance data to the database 2017-02-23 19:16:36 -05:00
Michael Cook (mackal) 602381ebec copy paste fail 2017-02-23 12:27:44 -05:00
Akkadius e098836934 Upload table lists that PEQ uses in daily database dump 2017-02-22 22:49:23 -06:00
Uleat ce3fc0f2c3 Merge branch 'master' of https://github.com/EQEmu/Server 2017-02-21 20:40:35 -05:00
Uleat 9adfe5b9ff Fix for bot wizard repeating familiar casting when pet is dead and buff is active 2017-02-21 20:40:04 -05:00
Michael Cook (mackal) b423ad0d80 Crash fix 2017-02-21 18:02:58 -05:00
Michael Cook (mackal) 9a157fa028 Turn aggro meter off by default until more tested
Reports of it being too spammy and causing DCs
2017-02-21 17:54:25 -05:00
Drajor 7db82a3b14 Fixes issue with calculating the value of items being sold. The loop was starting at 0 instead of 1. 2017-02-22 06:26:49 +10:00
Michael Cook (mackal) 056725b9bd Make timer for aggro meter not a magic number
you can edit AGGRO_METER_UPDATE_MS in common/features.h if you want to
see if a different number would work better
2017-02-21 13:38:00 -05:00
Akkadius 8bbf099636 Merge fix 2017-02-21 03:57:10 -06:00
Akkadius a884639534 Reduce the initial telnet console prompt timer 2017-02-21 03:55:21 -06:00
Uleat 8f67df1f4f Oops! (Won't affect any changes up to this point) [skip ci] 2017-02-20 22:50:43 -05:00
Uleat f851b1a3b4 Added combat-prep song buffing note [skip ci] 2017-02-20 21:47:47 -05:00
Uleat b41bb8e179 Merge branch 'master' of https://github.com/EQEmu/Server 2017-02-20 21:41:25 -05:00
Uleat d9633dfee4 Bard bot song twisting update 2017-02-20 21:41:15 -05:00
Michael Cook (mackal) 46b19e8e6f Disable the aggro meter timer if it's not enabled 2017-02-20 18:41:17 -05:00
Akkadius f0f5c41c30 Fixed an issue where clients would sell x1000 stacks of items where the price overflows data sizes, the code will now make sure not to sell too many items that go over this data size 2017-02-19 21:12:18 -06:00
Michael Cook (mackal) 08c2f73e37 Implement aggro meter for RoF2 (RoF wasn't tested)
I didn't test RoF, so it's disabled for now (change AggroMeterAvaliable if you want to test)

Group member meters probably buggy ... but do later

The "lock target" feature isn't working currently either
2017-02-18 22:27:34 -05:00
Michael Cook (mackal) 9f4604ec3e Rework how XTarget auto haters work
This should cause the auto haters to be shared with other toons who might be
interested (group/raid) like live.

There maybe some bugs since there is a lot of complex interactions here.
2017-02-17 21:04:48 -05:00
Uleat 8177f7d9bb Activation of bot_spells_entries table 2017-02-15 19:04:36 -05:00
Uleat 4ec3fda59d Merge branch 'master' of https://github.com/EQEmu/Server 2017-02-15 18:38:45 -05:00
Uleat e3c8b75259 Moved bot spell entries out of npc spell entries (easier to manage bot changes by committing to non-bot manifest) 2017-02-15 07:42:17 -05:00
Uleat d62a449f9c Missed an npc spells type (or two..) 2017-02-15 07:03:43 -05:00
Michael Cook (mackal) d043c38f71 Make it so enraged NPCs can't be riposted
This should prevent infinite loops
2017-02-14 16:47:22 -05:00
JJ 5b8ad902ce Add character_tasks to the list when deleting a character. 2017-02-13 16:00:39 -05:00
Akkadius ef16522473 Implement Rule Zone:GlobalLootMultiplier (Default 1) - Sets Global Loot drop multiplier for database based drops, useful for double, triple loot etc. 2017-02-13 02:16:40 -06:00
Akkadius fe21564659 Apply KLS' tweaks to Log.Out (CPU saves) https://github.com/EQEmu/Server/commit/1d055b5364a4183a327683dfa13cf33954874616 2017-02-13 01:38:23 -06:00
Akkadius e3173d04d4 Merge branch 'master' of https://github.com/EQEmu/Server 2017-02-13 01:26:44 -06:00
Akkadius 92d4468326 Put a category enabled filter on default switch case so we're not chewing up extra cpu cycles 2017-02-13 01:26:19 -06:00
Akkadius 0f32f780a9 Revert previous change to keep installation memory safe and independent [skip ci] 2017-02-12 23:31:25 -06:00
Akkadius 955514c20f eqemu_server.pl Linux make routine compile with the amount of cores available [skip ci] 2017-02-12 23:16:38 -06:00
Uleat ed717add29 Added a few more SpellType enumerations (uncoded) 2017-02-11 18:33:58 -05:00
Uleat a7b159fe65 Merge branch 'master' of https://github.com/EQEmu/Server 2017-02-09 17:58:08 -05:00
Uleat 38651258fc Updated npc spell types to 32-bit mask 2017-02-09 17:57:55 -05:00
Akkadius 4605540955 Update login_opcodes.conf 2017-02-09 01:33:41 -06:00
Akkadius c83bc038f3 Fix issue with installer pulling down the wrong opcodes for SOD+ clients on Linux Loginserver 2017-02-09 01:32:26 -06:00
Akkadius d3dff3760a Merge pull request #587 from N0ctrnl/patch-1
Update for Ubuntu 16.04
2017-02-08 19:04:29 -06:00
Kurt Gilpin 9e49b2ae0f Update for Ubuntu 16.04
This should be fully working with Ubuntu 16.04 Server.
2017-02-08 19:01:50 -06:00
Akkadius a81212e1b4 Allow admin telnet connections from localhost without requiring credentials to world 2017-02-08 18:00:38 -06:00
Akkadius 57d75572b2 Heavily reduce idle cpu footprint with many zone processes loaded simultaneously and not active 2017-02-08 17:28:54 -06:00
Uleat d1abe4a332 Added dev script for function to retrieve spell type description labels for spells from queries [skip ci] 2017-02-07 21:52:46 -05:00
Uleat cd11d7d1af Added dev script for function to retrieve spell category labels for spells from queries [skip ci] 2017-02-07 21:52:17 -05:00
Uleat 3d1bb6bd08 Updated SpellAffectIndex enumeration remarks [skip ci] 2017-02-06 17:48:44 -05:00
Uleat e9c1681e2c Merge branch 'master' of https://github.com/EQEmu/Server 2017-02-06 16:35:41 -05:00
Uleat 5dbbc5f21c Added some additional SpellAffectIndex declarations to the enumeration (no reference.) Added dev script for function to retrieve spell affect index id labels for spells from queries 2017-02-06 07:14:50 -05:00
Michael Cook (mackal) ef8b4754ea Fix min damage issue 2017-02-06 00:11:26 -05:00
Uleat a13694c859 Implemented cast restrictions in GetSpellTargetTypeToken() [skip ci] 2017-02-05 22:11:02 -05:00
Uleat 51eaf25ea0 Merge branch 'master' of https://github.com/EQEmu/Server 2017-02-05 16:18:16 -05:00
Michael Cook (mackal) 592f9a9cb9 Add rule to allow non-PC pet NPCs to crit
NPCs can't crit at all ever on live
2017-02-05 13:44:04 -05:00
Uleat 409dc3ad35 Added dev script for function to retrieve body type labels from queries [skip ci] 2017-02-05 07:56:37 -05:00
Uleat f8f783fa46 Added dev script for function to retrieve spell target type labels for spells from queries [skip ci] 2017-02-05 05:01:51 -05:00
Uleat 1d1382cb12 * Added dev script for function to retrieve race id labels from queries [skip ci] 2017-02-05 04:32:32 -05:00
Uleat 68680ac9d8 Created sub-d for database tools 2017-02-05 02:37:01 -05:00
Uleat df1d499da6 Imported RoF2 race names 2017-02-05 02:20:40 -05:00
Uleat a6a056ad0d Added rest of public spell effect list. Changed unimplemented effects to "NI_"##token format [skip ci] 2017-02-04 19:52:21 -05:00
Uleat b1f14e1e29 Added dev script for function to retrieve effect id labels for spells from queries [skip ci] 2017-02-04 05:55:10 -05:00
Uleat 1999982e6a Fix for bot load buffs instrument mod. More tweaks to bot movement hack 2017-02-02 19:10:10 -05:00
Uleat b0ad9524bc Bot movement behavior change..still in-work 2017-01-31 20:17:54 -05:00
Michael Cook (mackal) d8519bc270 Weapons allow NPCs to facestab 2017-01-31 17:25:05 -05:00
Uleat da9792160d Added Mob::HasTargetReflection() 2017-01-30 17:38:17 -05:00
Uleat dc308e2ecb Fix for null columns in books.language crash 2017-01-30 03:08:00 -05:00
Uleat 984a009fbb Temp fix for bot armor color issue - may break armor dying (not tested) 2017-01-29 04:35:03 -05:00
Michael Cook (mackal) 5d61cf5bcf Bots are dumb 2017-01-28 23:21:12 -05:00
Michael Cook (mackal) 2db6464d14 Fix last commit 2017-01-28 22:46:02 -05:00
Michael Cook (mackal) c17ac67296 Tweak #showstats so bots don't skip stuff 2017-01-28 22:43:07 -05:00
Michael Cook (mackal) 37e87e8cef Rework combat to make use of a struct to fix some bugs 2017-01-28 19:38:44 -05:00
Uleat e300f82c28 Added "rooted mob" conditional to rogue bot hate redux methods 2017-01-28 16:07:58 -05:00
Uleat 05cb9d56c2 Modded 2017_01_10_book_languages.sql to eliminate error message 2017-01-27 23:17:25 -05:00
Uleat ac0cba64f9 Merge pull request #585 from noudess/master
Use languages when reading books that are in a language other than common.
2017-01-27 22:48:43 -05:00
Uleat 0b3b3fdc88 Merge branch 'master' of https://github.com/EQEmu/Server 2017-01-27 21:28:32 -05:00
Uleat 104a0998ce Added rogue evade to bot combat (nothing is every really fixed until you do it a second time and add a timer...) 2017-01-27 21:28:25 -05:00
Michael Cook (mackal) cdf0d5deb0 Fix crash 2017-01-26 18:04:59 -05:00
Uleat 36300d6df1 Removed SE_NegateIfCombat movement spells from bot commands (i.e., Scale of Wolf) 2017-01-26 17:29:39 -05:00
Uleat 3d54a4edcb Eliminated Rogue Bot twirling combat behavior. 2017-01-26 14:37:51 -05:00
Michael Cook (mackal) 31de6a63cc Fix bot frenzy 2017-01-25 21:08:59 -05:00
Uleat ae81ab8a12 Fix for obscure crash related to bots and GetNeedsCured() 2017-01-21 21:38:32 -05:00
Michael Cook (mackal) 7033d9d919 memleak fix 2017-01-21 01:47:06 -05:00
Michael Cook (mackal) 905e3acab3 Fix bots? 2017-01-20 23:27:19 -05:00
Michael Cook (mackal) 2c6e11b464 Have modify NPC stat AC/AGI recache AC 2017-01-19 23:17:14 -05:00
Michael Cook (mackal) 9aba993888 Add optional rule SQL for combat update [skip ci] 2017-01-17 23:34:52 -05:00
Michael Cook (mackal) f614c35f6e Combat Revamp -- BREAKING CHANGES -- see changelog
Changelog updated for combat revamp
2017-01-17 23:30:50 -05:00
Michael Cook (mackal) 8f21b01b7e Tweak to accuracy based on newer clients 2017-01-17 02:52:16 -05:00
Michael Cook (mackal) 591fa003c6 Merge pull request #586 from huffin/patch-1
Update 2017_01_16_NPCCombatRebalance.sql
2017-01-16 21:00:52 -05:00
huffin f3e09abf22 Update 2017_01_16_NPCCombatRebalance.sql 2017-01-16 19:33:33 -06:00
Michael Cook (mackal) 18e6e5e5e2 Rename Defense to Mitigation on sim (since that's what it is) 2017-01-16 17:05:57 -05:00
Michael Cook (mackal) 698a814fc3 Add KLS' combat sim
This will show you the distribution of hits for a given offense and mitigation

DI 1 is the min hit and DI 20 is the max hit
2017-01-16 17:02:34 -05:00
Michael Cook (mackal) fb820f4fec Add Creamo's SQL to rebalance NPCs 2017-01-16 16:58:32 -05:00
Michael Cook (mackal) 0d84a73e9f Clean up MonkSpecialAttack too 2017-01-15 22:54:50 -05:00
Michael Cook (mackal) b92d6c57a1 Rework OPCombatAbiltiy a bit
This is done to help remove some code duplication in the future
2017-01-15 22:19:32 -05:00
Michael Cook (mackal) 8c6fefa33e Update #showstats 2017-01-15 16:32:15 -05:00
Michael Cook (mackal) e03a90b05d Refactor CheckHitChance
Pulled the accuracy/avoidance spell bonuses into their own functions so
we can show the total values in #showstats
2017-01-15 16:08:22 -05:00
Michael Cook (mackal) c030e1ce8d Add rule Combat:LevelToStopDamageCaps
Setting this to 1 will effectively disable damage caps
Setting this to 20 will give similar results to old incorrect default rules
2017-01-15 15:39:12 -05:00
Michael Cook (mackal) 7e49a21b3b Change NPC skill AC bonus
Basically, live doesn't have an NPC's skill at the max for their class like we
do. So for now, we'll just set their SkillDefense bonus to value / 5
2017-01-15 13:54:10 -05:00
Michael Cook (mackal) 9e824876ba Combat Revamp - MAJOR BREAKING CHANGE
This commit makes combat much more live like. This is based on a lot of parses
done by TAKP and myself. There are numerous things based on dev quotes and
hints. Pretty much all combat has changed, spell effects correct, stacking
correct, etc.

This is the fist stage of the revamp, I will be trying to remove some code
duplication and make things generally cleaner.

Server ops will have to rebalance their NPCs. AC actually means something now.
Rough recommendations?
Level 50 "classic" trash should be no more than 115.
Classic raid mobs should be more 200+ etc
Other "classic" NPCs should be a lot lower as well.
PoP trash probably shouldn't exceed 120 AC
PoP raids should be higher
Devs have said the vast majority of NPCs didn't exceed 600 AC until very
recently. The exceptions were mostly raid encounters.

There really isn't a good "default" for every server, so this will be up to
the devs to find where they want their server stats to be.
2017-01-15 00:03:02 -05:00
Michael Cook (mackal) 891fa0411c Revert "Update travis-ci to use newer VM"
This reverts commit 0a4ccb11aa.
2017-01-12 18:25:32 -05:00
Michael Cook (mackal) a4fda2a951 Revert "Try newer GCC versions?"
This reverts commit 50a67c76e7.
2017-01-12 18:25:25 -05:00
Michael Cook (mackal) ffdc933ce0 Revert "Gotta update env vars too I guess"
This reverts commit da08a622f1.
2017-01-12 18:25:16 -05:00
Michael Cook (mackal) e3f15de1f8 Revert "Gotta set them actually"
This reverts commit 6cef5c6beb.
2017-01-12 18:25:06 -05:00
Michael Cook (mackal) 6cef5c6beb Gotta set them actually 2017-01-12 18:19:04 -05:00
Michael Cook (mackal) da08a622f1 Gotta update env vars too I guess 2017-01-12 18:10:45 -05:00
Michael Cook (mackal) 50a67c76e7 Try newer GCC versions? 2017-01-12 18:06:13 -05:00
Michael Cook (mackal) 0a4ccb11aa Update travis-ci to use newer VM 2017-01-12 17:55:08 -05:00
Paul Coene af4a432745 Missed version.h in original commit 2017-01-10 20:33:01 -05:00
Paul Coene df86e644f4 Now the actual code changes - lol 2017-01-10 20:18:16 -05:00
Paul Coene 80ff535215 Added code so that books/scrolls read that are in a language other
than common get language skill applied.

Added code to support ReadBook slots above and beyond main inventory slots
by decoding additional bag slot field.
2017-01-10 20:15:03 -05:00
Akkadius 30157a37a2 Merge pull request #583 from noudess/master
Alliance spell line for chanters was not working.
2017-01-10 14:09:02 -06:00
Michael Cook (mackal) f5827174ee Make CheckHitChance much more live like
This should be fairly close to live-like.

Based on client decompiling, Torven's write up and parses and more parses.

It will probably break your server.
2016-12-25 21:11:10 -05:00
Michael Cook (mackal) 1d19bd11d0 Add Random::Roll0
This has the same interval ((0,N]) that the client function does
The devs have referenced this in a few posts talking about
mechanics.
2016-12-25 21:06:02 -05:00
Paul Coene 6a2be94282 Alliance spell line for chanters was not working. 2016-12-21 14:38:24 -05:00
Michael Cook (mackal) 630ea0d3c6 Fix RoF2 OP_GMHideMe 2016-12-21 13:45:18 -05:00
Drajor 55e78cd8e9 Fix for error in previous change. ItemInstance::GetOrnamentHeroModel will return zero again when parameter material_slot is the default -1. 2016-12-21 13:28:05 +10:00
Drajor a13e32498a Hero Forge robes are now visible at character select. Items using a robe HF ID need use the actual ID in the DB i.e. 11607-12107. WearChange command modified to allow both shorthand HF IDs and explicit IDs. 2016-12-21 13:03:19 +10:00
Uleat 18693998b9 Added logging code to DropItem() 2016-12-19 20:58:38 -05:00
Drajor 908a7061cf Hero forge ID in OP_WearChange originating from a client is now set to the correct value prior to being broadcast to other clients. 2016-12-19 21:00:55 +10:00
Uleat 648078d76c More NoDrop-related hack abatement 2016-12-18 20:20:27 -05:00
Akkadius 06279b18a3 Fix Hero Forge model not showing up at character select 2016-12-18 05:36:30 -06:00
Michael Cook (mackal) f53b95d141 Rework look acking a bit
We should no longer kick from corpse if the quest says to not loot an item
Need to investigate autoloot behavior with respect to everything still
So other cases will still kick you from the corpse (lore conflict etc)
2016-12-16 17:11:44 -05:00
Michael Cook (mackal) e680a0f704 Change LottingItem_Struct::auto_loot to signed 2016-12-16 16:09:31 -05:00
Michael Cook (mackal) 019586abbd Clang-format Corpse::LootItem 2016-12-16 16:03:44 -05:00
Michael Cook (mackal) 8f5ba05e75 Minor Corpse::LootItem refactoring 2016-12-16 16:02:42 -05:00
Michael Cook (mackal) 427fb08561 Merge pull request #582 from SCMcLaughlin/master
Additional LS config parser fixes:
2016-12-16 02:14:23 -05:00
SCMcLaughlin 343c23cc6c Additional LS config parser fixes:
* use auto
* fix some questionable uses of string.append() that were broken by the use of int/auto
2016-12-15 20:58:53 -08:00
Michael Cook (mackal) ac0332c020 Merge pull request #581 from SCMcLaughlin/master
Fix potential infinite loop in loginserver's config file reader
2016-12-15 20:55:43 -05:00
Michael Cook (mackal) c1fbfc0f44 Add support for kicking epic loot locks
Returning non-0 (no return in a lua/perl function = return 0 so this is best)
will prevent the client from looting the item

I still need to figure out how to make it so we don't have to kick
the player from the corpse, but maybe that's just a difference on live
2016-12-15 18:31:08 -05:00
SCMcLaughlin d305d67279 Fix potential infinite loop in loginserver's config file reader 2016-12-15 14:47:58 -08:00
Michael Cook (mackal) 3cc7d0db63 Fix fizzle message being the wrong color 2016-12-14 22:06:05 -05:00
Uleat 1b1d8700ae Merge branch 'master' of https://github.com/EQEmu/Server 2016-12-09 20:12:51 -05:00
Uleat 6994157184 Added optional bots rule 'CasterStopMeleeLevel' 2016-12-09 20:12:08 -05:00
Michael Cook (mackal) bf25c65868 Merge pull request #579 from noudess/master
Add check for mob spell based defensive procs.
2016-12-09 19:14:05 -05:00
Paul Coene 6311d82095 Add check for mob spell based defensive procs (as per DB entry) for attacking
clients.  Got coaching and testing from demonstar55.
2016-12-09 18:59:44 -05:00
Michael Cook (mackal) 491cabfe8b Fix SE_Destroy breaking respawns 2016-12-09 13:36:09 -05:00
Michael Cook (mackal) fddb6f67ab Update IsPartialCapableSpell based on Torven's findings 2016-12-09 13:29:46 -05:00
Michael Cook (mackal) 26985496d1 Fix Shield Specialist related SPAs 2016-12-08 22:36:47 -05:00
Michael Cook (mackal) ab0f883191 Merge pull request #578 from noudess/master
Add fish names to fishing messages as per live for non junk items,
2016-12-08 16:42:27 -05:00
Paul Coene 538ff873ee Fix alignment 2016-12-08 16:19:17 -05:00
Paul Coene d0e6bb6e07 more undos 2016-12-08 16:17:10 -05:00
Paul Coene 6cbb4bcf47 Remove defensive proc changes 2016-12-08 16:15:58 -05:00
Paul Coene d99df2540d Fix typo 2016-12-08 16:07:33 -05:00
Paul Coene f5a0b994dc Make message based on item type. Learned that non fish items can come from
both tables.
2016-12-08 16:07:33 -05:00
Paul Coene 246f770e8f Fix fishing messages so when actual fish are caught, name is in message. 2016-12-08 16:07:33 -05:00
Paul Coene 95efc3a66c Undo changes 2016-12-08 16:06:32 -05:00
Michael Cook (mackal) baf9336617 Fix RoF+ OP_InterruptCast 2016-12-06 14:12:11 -05:00
Uleat 0ab0c5c117 Added trade hack detection code 2016-12-03 18:17:10 -05:00
Akkadius c482738d79 Merge branch 'master' of https://github.com/EQEmu/Server 2016-12-01 22:42:35 -06:00
Akkadius a4c9fa6a65 eqemu_server.pl windws_server_latest - now grabs both pdb's and regular binaries [skip ci] 2016-12-01 22:42:22 -06:00
Michael Cook (mackal) bb8fc17189 Quick fix for PP buff issue
This may break buffs zoning, but I don't have time to look at
2016-12-01 22:57:50 -05:00
Uleat b61c7d0b14 Merge branch 'master' of https://github.com/EQEmu/Server 2016-12-01 22:34:51 -05:00
Uleat 0d9af27a03 Exploit abatement for item duplication involving augments 2016-12-01 22:34:43 -05:00
Akkadius 3e50491619 Update eqemu_server.pl to use new AppVeyor build link [skip ci] 2016-12-01 19:46:43 -06:00
Akkadius de92c277e0 Update eqemu_server.pl to use new AppVeyor build link
Adjust pet zoning to occur before zone spawns are sent in bulk
2016-12-01 19:41:12 -06:00
Michael Cook (mackal) ffbc913b9d Rename some spell fields 2016-12-01 13:35:19 -05:00
Michael Cook (mackal) 286bfa7af6 Implement the PC/NPC only flag 2016-11-30 20:53:39 -05:00
Akkadius b5e324af83 eqemu_server.pl windows_server_latest - Now pulls down latest unstable binaries built from AppVeyor (x86) [skip ci] 2016-11-28 16:46:38 -06:00
Michael Cook (mackal) d9e0708331 Merge pull request #576 from AthrogatePEQ/master
Add GetAppearance() to lua.
2016-11-28 16:53:56 -05:00
Athrogate a121675161 Add GetAppearance() to lua. 2016-11-28 13:50:24 -08:00
Michael Cook (mackal) bbd2796ea4 Add ParticlePoint enum for OP_LevelAppearance 2016-11-18 13:55:04 -05:00
Michael Cook (mackal) 5a08e0ffd9 Adjust Rogue Evade drop
Live seems to be inconsistent with how much hate is dropped, but I parsed
~69% drop on the highest and ~39% for the lowest. So round to 70 and 40.

It was also fairly obvious there was a min hate it could drop you to,
which parsed out to ~100 hate.
2016-11-16 02:36:20 -05:00
Michael Cook (mackal) 3dec02881a Revamp Buff slots
Server side we now have 63 total buff slots for clients
They match RoF/RoF2 and are mapped as 42 long, 20 short, 1 disc

The player is limited to what their clients supports, so
Tit players can have 25 buffs and 12 songs, while other can have more

When you log in, we only load up to the max your client supports,
the rest of the buffs are thrown away

Also changed is the default Max Buff slots for NPCs, they now match Tit (60)
If you are thinking about raising that, here are what some other clients support
Tit - SoF 60, SoD - UF 85, RoF - RoF2 97 (although UI only has 85 slots, you can
edit it if you want more)

Also SoD+ the pet limits match the NPC limits.

This will increase memory usage a bit, but I don't see a solution to that
Plus I think most people want this.
2016-11-15 01:37:58 -05:00
Akkadius 04c8fe7d2c Fix map loading paths for both platforms 2016-11-11 22:39:08 -06:00
Akkadius e8d80a436e Add map debugging [skip ci] 2016-11-11 22:31:54 -06:00
Uleat 3447c86562 Fix for windows compile (stat-use related) 2016-11-11 18:59:47 -05:00
Michael Cook (mackal) 71e641c882 Merge pull request #572 from KinglyKrab/master
Fixed #npcspawn update.
2016-11-10 15:57:31 -05:00
Kinglykrab cb1d0a0bef Fixed #npcspawn update. 2016-11-10 15:47:18 -05:00
Akkadius 34ffb5b908 Create shared_memory directory from the config file if it doesn't exist on launch of shared_memory.exe 2016-11-10 12:00:44 -06:00
Akkadius e7e379c71b Fix map loading logic so that case sensitive checks are made in the following order: maps, Maps, and if neither of those two exist, then <maps> value would take precedence.
- Added some log messages for what version of map is being loaded versus MMF
2016-11-10 11:28:06 -06:00
Michael Cook (mackal) b3842ba72a Fix indent 2016-11-09 12:14:24 -05:00
Michael Cook (mackal) a3c16ecdbe Merge pull request #571 from AthrogatePEQ/master
Expose GetLowestLevel() to Lua.
2016-11-09 12:13:15 -05:00
Athrogate 72e7465e16 Lua GetLowestLevel() 2016-11-09 04:41:09 -08:00
Athrogate 4af996e359 Adding GetLowestLevel() 2016-11-09 04:28:57 -08:00
Akkadius 462dea67e1 Merge pull request #566 from N0ctrnl/hott-test
Optional rule to grant HoTT to newly created characters
2016-11-06 16:11:02 -06:00
Akkadius e23fd269d5 Merge pull request #570 from zerosum0x0/potential_makeplat
fix potential plat creation exploit
2016-11-06 16:10:43 -06:00
Michael Cook (mackal) 06e2f76c05 Implement SE_SummonToCorpse 2016-11-05 14:08:00 -04:00
Michael Cook (mackal) b1f97712f1 Quick fix for bulk XTarget updates
This needs to be investigated more, but a 0 here for a valid mob
is bad.
2016-11-03 14:31:09 -04:00
Michael Cook (mackal) cbe53951f8 Add missing ITEMTransfig1HB 2016-11-02 13:36:04 -04:00
zerosum0x0 66f253553a Added an f like a dummy 2016-10-30 22:12:46 -06:00
zerosum0x0 7f4ce3faf5 fix potential plat creation exploit 2016-10-30 22:04:10 -06:00
Michael Cook (mackal) a29177de9e Fix zone/embparser.h header guard 2016-10-30 22:51:50 -04:00
Michael Cook (mackal) a15df2ec2c Switch Master Wu to modern live implementation
Classic Master Wu still exists setting Combat:ClassicMasterWu to true
2016-10-30 22:41:24 -04:00
Michael Cook (mackal) cbb7090615 Fix SNEAK_RESTRICT Message Type 2016-10-28 20:45:05 -04:00
Michael Cook (mackal) b9fefc95e8 Enforce 4 sec Sneak Attack rule fixes #569
Spells flagged with SNEAK_ATTACK requires you to be hidden for
about 4 seconds before you can cast them
2016-10-25 23:19:20 -04:00
Akkadius 60406ebcc1 Test build notification 2016-10-25 02:52:31 -05:00
Michael Cook (mackal) a6f5571750 Fix infinite loops 2016-10-24 13:29:07 -04:00
Uleat aabf7b9b5a Switched NPC::QueryLoot() from ItemData model to ServerLootItem model (allows saylinks with augments) 2016-10-23 20:51:07 -04:00
Uleat aa56e8aac4 Merge branch 'master' of https://github.com/EQEmu/Server 2016-10-23 15:28:27 -04:00
Uleat db7f0cc977 Fix for model glitches resulting from a recent patch 2016-10-23 15:28:20 -04:00
Michael Cook (mackal) 95064947b6 Hack to fix long recast bard songs 2016-10-21 20:48:18 -04:00
Uleat 714464481f Merge pull request #568 from KinglyKrab/master
Augment support for adding items to NPCs in quests.
2016-10-20 22:08:13 -04:00
Kinglykrab 6abed18eb9 Added augment support for NPC AddItem() and quest::addloot in Perl/Lua. This will allow you to add items to NPCs with scripts that already have augments in them. 2016-10-20 21:12:47 -04:00
Uleat 752821f22b Added proximity data report to npcstats command 2016-10-20 16:36:46 -04:00
Akkadius 409bad8108 Update eqemu_server.pl [skip ci] - not sure why formatting is getting thrown off 2016-10-18 16:52:51 -05:00
Akkadius 97999a63b7 Update eqemu_server.pl [skip ci] - Fix eqemu_config.xml tag parsing scenarios 2016-10-18 16:49:47 -05:00
Akkadius fe968f83a3 Update eqemu_server.pl [skip ci] - undo previous quote commit 2016-10-18 16:21:21 -05:00
Uleat 9545684883 Merge branch 'master' of https://github.com/EQEmu/Server 2016-10-18 17:09:14 -04:00
Uleat 6e0cba566f Added 'sow' argument to bot_command_movement_speed 2016-10-18 17:09:07 -04:00
Akkadius 16fa32e65b Update eqemu_server.pl [skip ci] 2016-10-18 14:16:53 -05:00
Kurt Gilpin e3e20a947b Create 2016_10_17_GrantHoTTOnCharacterCreate.sql 2016-10-17 19:00:08 -05:00
Kurt Gilpin d1f7448b25 Rule for HoTT grant. Defaults to false 2016-10-17 18:58:52 -05:00
Kurt Gilpin d62ceaefcc Rule to grant HoTT ability on character create 2016-10-17 18:57:35 -05:00
Uleat ec548874cc Another windows laxity... 2016-10-17 11:06:16 -04:00
Uleat 9a225bc396 Merge branch 'master' of https://github.com/EQEmu/Server 2016-10-17 10:59:45 -04:00
Uleat 101002d635 Renamed enum class InventoryVersion to MobVersion 2016-10-17 06:32:51 -04:00
Uleat 04f4fd652b Renamed class Inventory to EQEmu::InventoryProfile 2016-10-17 04:59:00 -04:00
Uleat 1cb79c8c1f Separated class Inventory from item_instance files into inventory_profile files 2016-10-17 02:41:09 -04:00
Akkadius 195bc03645 Update eqemu_server.pl [skip ci] - Make eqemu_config.xml parsing more strict to look inside the database section 2016-10-17 00:56:17 -05:00
Uleat 3438247904 Moved namespace ItemField from item_instance.h to shareddb.cpp 2016-10-17 01:03:40 -04:00
Uleat 9f01d14c64 Real fix for travis-ci build failure (thanks demonstar55!) 2016-10-16 23:18:12 -04:00
Uleat 7071b27183 Fix for travis-ci build failure 2016-10-16 21:59:35 -04:00
Uleat bfd07b1010 Added class EQEmu::InventorySlot 2016-10-16 21:36:39 -04:00
Uleat 8b5dd58e96 Renamed struct EQEmu::ItemBase to EQEmu::ItemData and class ItemInst to EQEmu::ItemInstance 2016-10-16 05:10:54 -04:00
Uleat decaadfe7d Merge branch 'master' of https://github.com/EQEmu/Server
# Conflicts:
#	changelog.txt
2016-10-15 22:27:14 -04:00
Uleat e29ec16759 Missed 2 reference changes 2016-10-15 22:23:50 -04:00
Uleat 16642b7c4c Filename changes to facilitate future updates 2016-10-15 22:14:03 -04:00
Akkadius 2188be24e4 Merge pull request #559 from TheGrandPackard/master
Fix Random Ground Spawn Z
2016-10-15 14:56:49 -05:00
Akkadius 70b9ff384c Merge pull request #562 from noudess/master
Fix rogue merchant usage under sneak.
2016-10-15 14:55:28 -05:00
Akkadius 56babc1801 Update client_process.cpp 2016-10-15 14:54:57 -05:00
Akkadius 3ba199e052 Merge pull request #558 from Xackery/master
Exp Raw Value / % Gain
2016-10-15 14:53:27 -05:00
Akkadius 8496bf16ff eqemu_server.pl [skip ci] Make the internet connection check more multi-lingual friendly 2016-10-14 14:37:25 -05:00
Michael Cook (mackal) e86fca3aff Add NPC NPC faction check to BeamDirectional 2016-10-14 13:59:45 -04:00
Michael Cook (mackal) 46cbd147b5 clang format BeamDirectional 2016-10-14 13:58:20 -04:00
Michael Cook (mackal) 05ed623056 Add NPC NPC faction check to ConeDirectional 2016-10-14 13:55:04 -04:00
Michael Cook (mackal) c90a436db3 Clang format ConeDirectional 2016-10-14 13:52:01 -04:00
Michael Cook (mackal) 1e865a5246 Take in elem/bane dmg in BS calc 2016-10-13 23:55:44 -04:00
Michael Cook (mackal) 343c41bb18 Elemental dmg shouldn't allow you to hit bane only 2016-10-13 23:54:56 -04:00
Joshua Packard a5b19d0c0d Added 0.1 to calculated Z so that objects show better above ground 2016-10-10 09:39:55 -07:00
Paul Coene c263c4ef07 2nd check for faction not needed - had to either check for sneaking again
or remove un-needed 2nd check.
2016-10-09 11:12:09 -04:00
Paul Coene 7b5ea9e99c Fix rogue merchant usage under sneak. 2016-10-09 10:22:55 -04:00
Michael Cook (mackal) 013f7cfd21 Set no_target_hotkey in Mob ctor
Fixes UBSan error
2016-10-03 01:35:11 -04:00
Joshua Packard 379ef7eed3 Added optional SQL to apply max z updates 2016-09-29 16:49:05 -07:00
Joshua Packard 329c9c8d98 Reordered zone initialization
Needed to reorder zone init so that the zonemap is loaded before ground spawns are made, otherwise the best Z won't calculate.
2016-09-28 19:26:44 -07:00
Joshua Packard 4fa8c89e5c Added Best Z Calculation to Ground Spawn Loc 2016-09-28 19:24:09 -07:00
Xackery 19b6a96063 Changed lost exp message to all be 15. 2016-09-26 02:11:50 -07:00
Xackery 6079b34a2a Added Ruleset AA:ShowExpValues. 2016-09-26 02:09:39 -07:00
Michael Cook (mackal) 4cb7d9a352 Remove ability for charmed NPCs from summoning
These rules do not appear to be true on live
They also don't look to have ever been true?
2016-09-22 00:32:01 -04:00
Michael Cook (mackal) b04844aa94 Fix merge [skip ci] 2016-09-21 23:54:51 -04:00
Akkadius b15ada974f Merge pull request #555 from noudess/master
Task experience based on % of level did not take into effect hell level rule
2016-09-18 20:38:08 -05:00
Paul Coene e2587b78f5 Merge remote-tracking branch 'upstream/master'
Conflicts:
	changelog.txt
2016-09-18 21:32:09 -04:00
Akkadius 06dfba3c81 Merge pull request #557 from KinglyKrab/master
Added quest global support for zone_controller.
2016-09-14 15:34:16 -05:00
Kinglykrab 8aa942cd27 Added quest global support for zone_controller. 2016-09-14 16:31:52 -04:00
Akkadius a9070b1327 Merge pull request #556 from KinglyKrab/master
#summon will now work when you are in an instance.
2016-09-12 01:42:53 -05:00
Akkadius 745510ea75 Massive overhaul of the update system and EQEmu Server management utility framework
(known as eqemu_update.pl) now known as eqemu_server.pl
	- eqemu_server.pl is now a general EQEmu Server management utiltiy framework that can be used
		to extend to many purposes. It's main purpose is to simplify server management
	- eqemu_server.pl changes:
		- Menu has been completely changed, instead of a number based (enter number and hit enter)
		you now type commands within the menu (Ex: 'database')
		- Handles last mile installation for Windows Servers (See Github Readme)
		- Handles last mile installation for Linux Servers (See Github Readme)
			- Ubuntu
			- Debian
			- Fedora
			- CentOS
		- Now checks for Internet connection before performing web requests
		- Database:
			- Regular schema updates now happen automatically, if new binaries present updated
				database schema changes, script will backup first, auto update database, and continue
				world bootup
			- Regular bots database schema changes now happen automatically similarily to the above
			- Database checks can also be ran manually via the script menu
		- CLI Arguments
			- Arguments passed to eqemu_server.pl can execute the same name-based operations that
				are present in the interactive menu
					- Example: "perl eqemu_server.pl opcodes" will download opcodes
					- Example: "perl eqemu_server.pl backup_player_tables" will backup and export player tables
		- Bots
			- Bots can now be automatically setup in Linux or Windows via the 'setup_bots' command
				- Windows will auto download binaries and install, along with installing bots db schema
				- Linxu will auto compile binaries and install, along with installings bots db schema
		- Utility scripts
			- Linux now has the following utility scripts for download, available via menu 'utility_scripts'
				and via Linux default install:
					- server_launcher.pl
					- server_start_dev.sh
					- server_start.sh
					- server_status.sh
					- server_stop.sh
		- Usage analytics
			- eqemu_server.pl now collects usage analytics, this is very helpful for our developers
				- Example: We can see how many installs have been performed:
					https://github.com/EQEmu/Server#server-installs
				- This helps us see how often certain utilities are used as well
		- Console Messages
			- All script messages have been prefixed with a bracket action Ex: [Update] [Database] [Info]
				to be more consistent with our log conventions
		- 'New Server' Utility
			- Running 'new_server' from the main menu or 'perl eqemu_server.pl new_server' while in
				a completely new folder with just the script present, will allow a server operator
				to initiate a full clean PEQ install in that folder. Pulling down all assets and
				installing a PEQ database with the name the server operator gives the prompts in the
				script
2016-09-12 01:31:35 -05:00
Kinglykrab f6d721dd72 #summon will now work when you are in an instance. 2016-09-11 19:25:41 -04:00
Paul Coene 0503e85fd3 Updated changelog 2016-09-10 14:26:47 -04:00
Paul Coene 0232f4f672 Merge remote-tracking branch 'upstream/master' 2016-09-10 14:21:59 -04:00
Paul Coene 56d355935b Fix task experience by level % to take into account hell level rule. 2016-09-10 14:21:19 -04:00
958 changed files with 34370 additions and 213472 deletions
+5 -10
View File
@@ -323,8 +323,7 @@ IF(EQEMU_BUILD_LUA)
SET(BOOST_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/dependencies/boost")
FIND_PACKAGE(Boost REQUIRED)
INCLUDE_DIRECTORIES(SYSTEM "${LUA_INCLUDE_DIR}" "${Boost_INCLUDE_DIRS}")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/luabind")
INCLUDE_DIRECTORIES(SYSTEM "${LUA_INCLUDE_DIR}" "${Boost_INCLUDE_DIRS}" "luabind")
OPTION(EQEMU_SANITIZE_LUA_LIBS "Sanitize Lua Libraries (Remove OS and IO standard libraries from being able to run)." ON)
IF(EQEMU_SANITIZE_LUA_LIBS)
@@ -332,18 +331,14 @@ IF(EQEMU_BUILD_LUA)
ENDIF(EQEMU_SANITIZE_LUA_LIBS)
ENDIF(EQEMU_BUILD_LUA)
INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_INCLUDE_DIRS}" "${MySQL_INCLUDE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/common/glm")
INCLUDE_DIRECTORIES(SYSTEM "${ZLIB_INCLUDE_DIRS}")
INCLUDE_DIRECTORIES(SYSTEM "${MySQL_INCLUDE_DIR}")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/common/glm")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/cereal")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/libuv/include" )
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/libuv/src")
INCLUDE_DIRECTORIES(SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/libs/format")
IF(EQEMU_BUILD_LUA)
ADD_SUBDIRECTORY(luabind)
ENDIF(EQEMU_BUILD_LUA)
IF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS)
ADD_SUBDIRECTORY(common)
ADD_SUBDIRECTORY(libs)
ENDIF(EQEMU_BUILD_SERVER OR EQEMU_BUILD_LOGIN OR EQEMU_BUILD_TESTS)
IF(EQEMU_BUILD_SERVER)
ADD_SUBDIRECTORY(shared_memory)
+1 -1
View File
@@ -1,6 +1,6 @@
# EQEmulator Core Server
|Travis CI (Linux)|Appveyor (Windows) |
|:---:|:---:|
|:---:|:---:|
|[![Linux CI](https://travis-ci.org/EQEmu/Server.svg?branch=master)](https://travis-ci.org/EQEmu/Server) |[![Windows CI](https://ci.appveyor.com/api/projects/status/d0cvokm7u732v8vl/branch/master?svg=true)](https://ci.appveyor.com/project/KimLS/server/branch/master) |
***
+391 -148
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -9,7 +9,7 @@ SET(export_headers
ADD_EXECUTABLE(export_client_files ${export_sources} ${export_headers})
INSTALL(TARGETS export_client_files RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
INSTALL(TARGETS export_client_files RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
TARGET_LINK_LIBRARIES(export_client_files common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
@@ -30,6 +30,7 @@ IF(UNIX)
TARGET_LINK_LIBRARIES(export_client_files "rt")
ENDIF(NOT DARWIN)
TARGET_LINK_LIBRARIES(export_client_files "pthread")
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
+2 -1
View File
@@ -9,7 +9,7 @@ SET(import_headers
ADD_EXECUTABLE(import_client_files ${import_sources} ${import_headers})
INSTALL(TARGETS import_client_files RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
INSTALL(TARGETS import_client_files RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
TARGET_LINK_LIBRARIES(import_client_files common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
@@ -30,6 +30,7 @@ IF(UNIX)
TARGET_LINK_LIBRARIES(import_client_files "rt")
ENDIF(NOT DARWIN)
TARGET_LINK_LIBRARIES(import_client_files "pthread")
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
+9 -76
View File
@@ -35,9 +35,11 @@ SET(common_sources
faction.cpp
guild_base.cpp
guilds.cpp
inventory_profile.cpp
inventory_slot.cpp
ipc_mutex.cpp
item.cpp
item_base.cpp
item_data.cpp
item_instance.cpp
light_source.cpp
md5.cpp
memory_buffer.cpp
@@ -75,14 +77,6 @@ SET(common_sources
worldconn.cpp
xml_parser.cpp
platform.cpp
net/crc32.cpp
net/daybreak_connection.cpp
net/eqstream.cpp
net/packet.cpp
patch/chat.cpp
patch/login_sod.cpp
patch/login_titanium.cpp
patch/patch.cpp
patches/patches.cpp
patches/sod.cpp
patches/sod_limits.cpp
@@ -163,10 +157,12 @@ SET(common_headers
global_define.h
guild_base.h
guilds.h
inventory_profile.h
inventory_slot.h
ipc_mutex.h
item.h
item_base.h
item_data.h
item_fieldlist.h
item_instance.h
languages.h
light_source.h
linked_list.h
@@ -218,52 +214,31 @@ SET(common_headers
worldconn.h
xml_parser.h
zone_numbers.h
event/background_task.h
event/event_loop.h
event/timer.h
net/crc32.h
net/daybreak_connection.h
net/daybreak_structs.h
net/endian.h
net/eqstream.h
net/packet.h
patch/chat.h
patch/login_sod.h
patch/login_titanium.h
patch/patch.h
patches/patches.h
patches/sod.h
# patches/sod_itemfields.h
patches/sod_limits.h
patches/sod_ops.h
patches/sod_structs.h
patches/sof.h
# patches/sof_itemfields.h
patches/sof_limits.h
# patches/sof_opcode_list.h
patches/sof_ops.h
patches/sof_structs.h
patches/ss_declare.h
patches/ss_define.h
patches/ss_register.h
patches/rof.h
# patches/rof_itemfields.h
patches/rof_limits.h
patches/rof_ops.h
patches/rof_structs.h
patches/rof2.h
# patches/rof2_itemfields.h
patches/rof2_limits.h
patches/rof2_ops.h
patches/rof2_structs.h
patches/titanium.h
# patches/titanium_itemfields_a.h
# patches/titanium_itemfields_b.h
patches/titanium_limits.h
patches/titanium_ops.h
patches/titanium_structs.h
patches/uf.h
# patches/uf_itemfields.h
patches/uf_limits.h
patches/uf_ops.h
patches/uf_structs.h
@@ -282,73 +257,34 @@ SET(common_headers
StackWalker/StackWalker.h
tinyxml/tinystr.h
tinyxml/tinyxml.h
util/memory_stream.h
)
SOURCE_GROUP(Event FILES
event/background_task.h
event/event_loop.h
event/timer.h
)
SOURCE_GROUP(Net FILES
net/crc32.cpp
net/crc32.h
net/daybreak_connection.cpp
net/daybreak_connection.h
net/daybreak_structs.h
net/endian.h
net/eqstream.h
net/eqstream.cpp
net/packet.cpp
net/packet.h
)
SOURCE_GROUP(Patch FILES
patch/chat.cpp
patch/chat.h
patch/login_sod.cpp
patch/login_sod.h
patch/login_titanium.cpp
patch/login_titanium.h
patch/patch.cpp
patch/patch.h
)
SOURCE_GROUP(Patches FILES
patches/patches.h
patches/sod.h
# patches/sod_itemfields.h
patches/sod_limits.h
patches/sod_ops.h
patches/sod_structs.h
patches/sof.h
# patches/sof_itemfields.h
patches/sof_limits.h
# patches/sof_opcode_list.h
patches/sof_ops.h
patches/sof_structs.h
patches/ss_declare.h
patches/ss_define.h
patches/ss_register.h
patches/rof.h
# patches/rof_itemfields.h
patches/rof_limits.h
patches/rof_ops.h
patches/rof_structs.h
patches/rof2.h
# patches/rof2_itemfields.h
patches/rof2_limits.h
patches/rof2_ops.h
patches/rof2_structs.h
patches/titanium.h
# patches/titanium_itemfields_a.h
# patches/titanium_itemfields_b.h
patches/titanium_limits.h
patches/titanium_ops.h
patches/titanium_structs.h
patches/uf.h
# patches/uf_itemfields.h
patches/uf_limits.h
patches/uf_ops.h
patches/uf_structs.h
@@ -407,15 +343,12 @@ SOURCE_GROUP(TinyXML FILES
tinyxml/tinyxmlparser.cpp
)
SOURCE_GROUP(Util FILES
util/memory_stream.h
)
INCLUDE_DIRECTORIES(Patches SocketLib StackWalker TinyXML)
ADD_LIBRARY(common ${common_sources} ${common_headers})
IF(UNIX)
ADD_DEFINITIONS(-fPIC)
SET_SOURCE_FILES_PROPERTIES("SocketLib/Mime.cpp" PROPERTY COMPILE_FLAGS -Wno-unused-result)
SET_SOURCE_FILES_PROPERTIES("patches/sod.cpp" "patches/sof.cpp" "patches/rof.cpp" "patches/rof2.cpp" "patches/uf.cpp" PROPERTIES COMPILE_FLAGS -O0)
ENDIF(UNIX)
+24 -4
View File
@@ -307,6 +307,7 @@ bool Database::DeleteCharacter(char *name) {
query = StringFormat("DELETE FROM `quest_globals` WHERE `charid` = '%d'", charid); QueryDatabase(query);
query = StringFormat("DELETE FROM `character_activities` WHERE `charid` = '%d'", charid); QueryDatabase(query);
query = StringFormat("DELETE FROM `character_enabledtasks` WHERE `charid` = '%d'", charid); QueryDatabase(query);
query = StringFormat("DELETE FROM `character_tasks` WHERE `charid` = '%d'", charid); QueryDatabase(query);
query = StringFormat("DELETE FROM `completed_tasks` WHERE `charid` = '%d'", charid); QueryDatabase(query);
query = StringFormat("DELETE FROM `friends` WHERE `charid` = '%d'", charid); QueryDatabase(query);
query = StringFormat("DELETE FROM `mail` WHERE `charid` = '%d'", charid); QueryDatabase(query);
@@ -638,6 +639,13 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
character_id, pp->binds[4].zoneId, 0, pp->binds[4].x, pp->binds[4].y, pp->binds[4].z, pp->binds[4].heading, 4
); results = QueryDatabase(query);
/* HoTT Ability */
if(RuleB(Character, GrantHoTTOnCreate))
{
query = StringFormat("INSERT INTO `character_leadership_abilities` (id, slot, rank) VALUES (%u, %i, %i)", character_id, 14, 1);
results = QueryDatabase(query);
}
/* Save Skills */
int firstquery = 0;
for (int i = 0; i < MAX_PP_SKILL; i++){
@@ -672,7 +680,7 @@ bool Database::SaveCharacterCreate(uint32 character_id, uint32 account_id, Playe
}
/* This only for new Character creation storing */
bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inventory* inv) {
bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, EQEmu::InventoryProfile* inv) {
uint32 charid = 0;
char zone[50];
float x, y, z;
@@ -701,7 +709,7 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inven
/* Insert starting inventory... */
std::string invquery;
for (int16 i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= EQEmu::legacy::BANK_BAGS_END;) {
const ItemInst* newinv = inv->GetItem(i);
const EQEmu::ItemInstance* newinv = inv->GetItem(i);
if (newinv) {
invquery = StringFormat("INSERT INTO `inventory` (charid, slotid, itemid, charges, color) VALUES (%u, %i, %u, %i, %u)",
charid, i, newinv->GetItem()->ID, newinv->GetCharges(), newinv->GetColor());
@@ -709,7 +717,7 @@ bool Database::StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inven
auto results = QueryDatabase(invquery);
}
if (i == EQEmu::legacy::SlotCursor) {
if (i == EQEmu::inventory::slotCursor) {
i = EQEmu::legacy::GENERAL_BAGS_BEGIN;
continue;
}
@@ -2147,4 +2155,16 @@ int Database::GetIPExemption(std::string account_ip) {
}
return RuleI(World, MaxClientsPerIP);
}
}
int Database::GetInstanceID(uint32 char_id, uint32 zone_id) {
std::string query = StringFormat("SELECT instance_list.id FROM instance_list INNER JOIN instance_list_player ON instance_list.id = instance_list_player.id WHERE instance_list.zone = '%i' AND instance_list_player.charid = '%i'", zone_id, char_id);
auto results = QueryDatabase(query);
if (results.Success() && results.RowCount() > 0) {
auto row = results.begin();
return atoi(row[0]);;
}
return 0;
}
+19 -2
View File
@@ -37,10 +37,14 @@
//atoi is not uint32 or uint32 safe!!!!
#define atoul(str) strtoul(str, nullptr, 10)
class Inventory;
class MySQLRequestResult;
class Client;
namespace EQEmu
{
class InventoryProfile;
}
struct EventLogDetails_Struct {
uint32 id;
char accountname[64];
@@ -79,6 +83,17 @@ struct VarCache_Struct {
class PTimerList;
#ifdef _WINDOWS
#if _MSC_VER > 1700 // greater than 2012 (2013+)
# define _ISNAN_(a) std::isnan(a)
#else
# include <float.h>
# define _ISNAN_(a) _isnan(a)
#endif
#else
# define _ISNAN_(a) std::isnan(a)
#endif
class Database : public DBcore {
public:
Database();
@@ -98,7 +113,7 @@ public:
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct* pp);
bool SetHackerFlag(const char* accountname, const char* charactername, const char* hacked);
bool SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone);
bool StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, Inventory* inv);
bool StoreCharacter(uint32 account_id, PlayerProfile_Struct* pp, EQEmu::InventoryProfile* inv);
bool UpdateName(const char* oldname, const char* newname);
/* General Information Queries */
@@ -178,6 +193,8 @@ public:
int GetIPExemption(std::string account_ip);
int GetInstanceID(uint32 char_id, uint32 zone_id);
/* Groups */
+6 -6
View File
@@ -186,7 +186,7 @@ namespace Convert {
/*002*/ uint32 HP;
/*006*/ uint32 Mana;
/*010*/ Convert::SpellBuff_Struct Buffs[BUFF_COUNT];
/*510*/ uint32 Items[EQEmu::textures::TextureCount];
/*510*/ uint32 Items[EQEmu::textures::materialCount];
/*546*/ char Name[64];
/*610*/
};
@@ -227,9 +227,9 @@ namespace Convert {
/*0304*/ uint8 ability_time_minutes;
/*0305*/ uint8 ability_time_hours; //place holder
/*0306*/ uint8 unknown0306[6]; // @bp Spacer/Flag?
/*0312*/ uint32 item_material[EQEmu::textures::TextureCount]; // Item texture/material of worn/held items
/*0312*/ uint32 item_material[EQEmu::textures::materialCount]; // Item texture/material of worn/held items
/*0348*/ uint8 unknown0348[44];
/*0392*/ Convert::Color_Struct item_tint[EQEmu::textures::TextureCount];
/*0392*/ Convert::Color_Struct item_tint[EQEmu::textures::materialCount];
/*0428*/ Convert::AA_Array aa_array[MAX_PP_AA_ARRAY];
/*2348*/ float unknown2384; //seen ~128, ~47
/*2352*/ char servername[32]; // length probably not right
@@ -1327,7 +1327,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
if (rquery != ""){ results = QueryDatabase(rquery); }
/* Run Bind Home Convert */
if (pp->binds[4].zoneId < 999 && !std::isnan(pp->binds[4].x) && !std::isnan(pp->binds[4].y) && !std::isnan(pp->binds[4].z) && !std::isnan(pp->binds[4].heading)) {
if (pp->binds[4].zoneId < 999 && !_ISNAN_(pp->binds[4].x) && !_ISNAN_(pp->binds[4].y) && !_ISNAN_(pp->binds[4].z) && !_ISNAN_(pp->binds[4].heading)) {
rquery = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)"
" VALUES (%u, %u, %u, %f, %f, %f, %f, 1)",
character_id, pp->binds[4].zoneId, 0, pp->binds[4].x, pp->binds[4].y, pp->binds[4].z, pp->binds[4].heading);
@@ -1335,7 +1335,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
}
/* Run Bind Convert */
if (pp->binds[0].zoneId < 999 && !std::isnan(pp->binds[0].x) && !std::isnan(pp->binds[0].y) && !std::isnan(pp->binds[0].z) && !std::isnan(pp->binds[0].heading)) {
if (pp->binds[0].zoneId < 999 && !_ISNAN_(pp->binds[0].x) && !_ISNAN_(pp->binds[0].y) && !_ISNAN_(pp->binds[0].z) && !_ISNAN_(pp->binds[0].heading)) {
rquery = StringFormat("REPLACE INTO `character_bind` (id, zone_id, instance_id, x, y, z, heading, is_home)"
" VALUES (%u, %u, %u, %f, %f, %f, %f, 0)",
character_id, pp->binds[0].zoneId, 0, pp->binds[0].x, pp->binds[0].y, pp->binds[0].z, pp->binds[0].heading);
@@ -1403,7 +1403,7 @@ bool Database::CheckDatabaseConvertPPDeblob(){
if (rquery != ""){ results = QueryDatabase(rquery); }
/* Run Material Color Convert */
first_entry = 0; rquery = "";
for (i = 0; i < EQEmu::textures::TextureCount; i++){
for (i = EQEmu::textures::textureBegin; i < EQEmu::textures::materialCount; i++){
if (pp->item_tint[i].color > 0){
if (first_entry != 1){
rquery = StringFormat("REPLACE INTO `character_material` (id, slot, blue, green, red, use_tint, color) VALUES (%u, %u, %u, %u, %u, %u, %u)", character_id, i, pp->item_tint[i].rgb.blue, pp->item_tint[i].rgb.green, pp->item_tint[i].rgb.red, pp->item_tint[i].rgb.use_tint, pp->item_tint[i].color);
+88
View File
@@ -35,6 +35,79 @@ namespace EQEmu
//using namespace RoF2::invbag;
//using namespace RoF2::invaug;
enum : int16 { typeInvalid = -1, slotInvalid = -1, containerInvalid = -1, socketInvalid = -1 }; // temporary
enum : int16 { typeBegin = 0, slotBegin = 0, containerBegin = 0, socketBegin = 0 }; // temporary
enum PossessionsSlots : int16 { // temporary
slotCharm = 0,
slotEar1,
slotHead,
slotFace,
slotEar2,
slotNeck, // 5
slotShoulders,
slotArms,
slotBack,
slotWrist1,
slotWrist2, // 10
slotRange,
slotHands,
slotPrimary,
slotSecondary,
slotFinger1, // 15
slotFinger2,
slotChest,
slotLegs,
slotFeet,
slotWaist, // 20
slotPowerSource = 9999,
slotAmmo = 21,
slotGeneral1,
slotGeneral2,
slotGeneral3,
slotGeneral4, // 25
slotGeneral5,
slotGeneral6,
slotGeneral7,
slotGeneral8,
slotCursor, // 30
slotCount
};
enum InventoryTypes : int16 { // temporary
typePossessions = 0,
typeBank,
typeSharedBank,
typeTrade,
typeWorld,
typeLimbo, // 5
typeTribute,
typeTrophyTribute,
typeGuildTribute,
typeMerchant,
typeDeleted, // 10
typeCorpse,
typeBazaar,
typeInspect,
typeRealEstate,
typeViewMODPC, // 15
typeViewMODBank,
typeViewMODSharedBank,
typeViewMODLimbo,
typeAltStorage,
typeArchived, // 20
typeMail,
typeGuildTrophyTribute,
typeKrono,
typeOther,
typeCount
};
static int16 SlotCount(int16 type_index) { return 0; } // temporary
const int16 ContainerCount = 10; // temporary
const int16 SocketCount = 6; // temporary
} /*inventory*/
namespace constants {
@@ -43,7 +116,16 @@ namespace EQEmu
const size_t SayLinkBodySize = RoF2::constants::SayLinkBodySize;
const int LongBuffs = RoF2::constants::LongBuffs;
const int ShortBuffs = RoF2::constants::ShortBuffs;
const int DiscBuffs = RoF2::constants::DiscBuffs;
const int TotalBuffs = RoF2::constants::TotalBuffs;
const int NPCBuffs = RoF2::constants::NPCBuffs;
const int PetBuffs = RoF2::constants::PetBuffs;
const int MercBuffs = RoF2::constants::MercBuffs;
} /*constants*/
enum class CastingSlot : uint32 {
Gem1 = 0,
Gem2 = 1,
@@ -68,3 +150,9 @@ namespace EQEmu
} /*EQEmu*/
#endif /*COMMON_EMU_CONSTANTS_H*/
/* hack list to prevent circular references
eq_limits.h:EQEmu::inventory::LookupEntry::InventoryTypeSize[n];
*/
+15 -89
View File
@@ -61,8 +61,6 @@ namespace EQEmu
SLOT_GENERAL_6 = 27,
SLOT_GENERAL_7 = 28,
SLOT_GENERAL_8 = 29,
//SLOT_GENERAL_9 = not supported
//SLOT_GENERAL_10 = not supported
SLOT_CURSOR = 30,
SLOT_CURSOR_END = (int16)0xFFFE, // I hope no one is using this...
SLOT_TRADESKILL = 1000,
@@ -96,75 +94,8 @@ namespace EQEmu
SLOT_WORLD_END = 4009
};
enum InventoryTypes : int16 {
TypePossessions = 0,
TypeBank,
TypeSharedBank,
TypeTrade,
TypeWorld,
TypeLimbo, // 5
TypeTribute,
TypeTrophyTribute,
TypeGuildTribute,
TypeMerchant,
TypeDeleted, // 10
TypeCorpse,
TypeBazaar,
TypeInspect,
TypeRealEstate,
TypeViewMODPC, // 15
TypeViewMODBank,
TypeViewMODSharedBank,
TypeViewMODLimbo,
TypeAltStorage,
TypeArchived, // 20
TypeMail,
TypeGuildTrophyTribute,
TypeKrono,
TypeOther,
TypeCount
};
enum PossessionsSlots : int16 {
SlotCharm = 0,
SlotEar1,
SlotHead,
SlotFace,
SlotEar2,
SlotNeck, // 5
SlotShoulders,
SlotArms,
SlotBack,
SlotWrist1,
SlotWrist2, // 10
SlotRange,
SlotHands,
SlotPrimary,
SlotSecondary,
SlotFinger1, // 15
SlotFinger2,
SlotChest,
SlotLegs,
SlotFeet,
SlotWaist, // 20
SlotPowerSource = 9999, // temp
SlotAmmo = 21, // temp
SlotGeneral1,
SlotGeneral2,
SlotGeneral3,
SlotGeneral4, // 25
SlotGeneral5,
SlotGeneral6,
SlotGeneral7,
SlotGeneral8,
//SlotGeneral9,
//SlotGeneral10,
SlotCursor, // 30
SlotCount
};
// these are currently hard-coded for existing inventory system..do not use in place of special client version handlers until ready
static const uint16 TYPE_POSSESSIONS_SIZE = SlotCount;
static const uint16 TYPE_POSSESSIONS_SIZE = 31;
static const uint16 TYPE_BANK_SIZE = 24;
static const uint16 TYPE_SHARED_BANK_SIZE = 2;
static const uint16 TYPE_TRADE_SIZE = 8;
@@ -175,14 +106,14 @@ namespace EQEmu
static const uint16 TYPE_GUILD_TRIBUTE_SIZE = 0;
static const uint16 TYPE_MERCHANT_SIZE = 0;
static const uint16 TYPE_DELETED_SIZE = 0;
static const uint16 TYPE_CORPSE_SIZE = SlotCount; // no bitmask use..limits to size of client corpse window (see EQLimits::InventoryMapSize(MapCorpse, <EQClientVersion))
static const uint16 TYPE_CORPSE_SIZE = 31; // no bitmask use..limits to size of client corpse window (see EQLimits::InventoryMapSize(MapCorpse, <EQClientVersion))
static const uint16 TYPE_BAZAAR_SIZE = 80;
static const uint16 TYPE_INSPECT_SIZE = 22;
static const uint16 TYPE_REAL_ESTATE_SIZE = 0;
static const uint16 TYPE_VIEW_MOD_PC_SIZE = 0;//NOT_USED;
static const uint16 TYPE_VIEW_MOD_BANK_SIZE = 0;//NOT_USED;
static const uint16 TYPE_VIEW_MOD_SHARED_BANK_SIZE = 0;//NOT_USED;
static const uint16 TYPE_VIEW_MOD_LIMBO_SIZE = 0;//NOT_USED;
static const uint16 TYPE_VIEW_MOD_PC_SIZE = 0;
static const uint16 TYPE_VIEW_MOD_BANK_SIZE = 0;
static const uint16 TYPE_VIEW_MOD_SHARED_BANK_SIZE = 0;
static const uint16 TYPE_VIEW_MOD_LIMBO_SIZE = 0;
static const uint16 TYPE_ALT_STORAGE_SIZE = 0;
static const uint16 TYPE_ARCHIVED_SIZE = 0;
static const uint16 TYPE_MAIL_SIZE = 0;
@@ -192,12 +123,12 @@ namespace EQEmu
// most of these definitions will go away with the structure-based system..this maintains compatibility for now
// (these are mainly to assign specific values to constants used in conversions and to identify per-client ranges/offsets)
static const int16 EQUIPMENT_BEGIN = SlotCharm;
static const int16 EQUIPMENT_END = SlotAmmo;
static const int16 EQUIPMENT_BEGIN = 0;
static const int16 EQUIPMENT_END = 21;
static const uint16 EQUIPMENT_SIZE = 22; // does not account for 'Power Source' - used mainly for npc equipment arrays
static const int16 GENERAL_BEGIN = SlotGeneral1;
static const int16 GENERAL_END = SlotGeneral8;
static const int16 GENERAL_BEGIN = 22;
static const int16 GENERAL_END = 29;
static const uint16 GENERAL_SIZE = 8;
static const int16 GENERAL_BAGS_BEGIN = 251;
static const int16 GENERAL_BAGS_END_OFFSET = 79;
@@ -235,22 +166,17 @@ namespace EQEmu
static const int16 TRIBUTE_SIZE = TYPE_TRIBUTE_SIZE;
static const int16 CORPSE_BEGIN = 22;
//static const int16 CORPSE_END = RoF::consts::CORPSE_END; // not ready for use
// items
// common and container sizes will not increase until the new 'location' struct is implemented
static const uint16 ITEM_COMMON_SIZE = 6;//RoF::consts::ITEM_COMMON_SIZE;
static const uint16 ITEM_CONTAINER_SIZE = 10;//Titanium::consts::ITEM_CONTAINER_SIZE;
// BANDOLIERS_SIZE sets maximum limit..active limit will need to be handled by the appropriate AA or spell (or item?)
static const size_t BANDOLIERS_SIZE = 20;//RoF2::consts::BANDOLIERS_SIZE; // number of bandolier instances
static const size_t BANDOLIER_ITEM_COUNT = 4;//RoF2::consts::BANDOLIER_ITEM_COUNT; // number of equipment slots in bandolier instance
static const size_t BANDOLIERS_SIZE = 20; // number of bandolier instances
static const size_t BANDOLIER_ITEM_COUNT = 4; // number of equipment slots in bandolier instance
// POTION_BELT_SIZE sets maximum limit..active limit will need to be handled by the appropriate AA or spell (or item?)
static const size_t POTION_BELT_ITEM_COUNT = 5;//RoF2::consts::POTION_BELT_ITEM_COUNT;
static const size_t POTION_BELT_ITEM_COUNT = 5;
static const size_t TEXT_LINK_BODY_LENGTH = 56;//RoF2::consts::TEXT_LINK_BODY_LENGTH;
static const size_t TEXT_LINK_BODY_LENGTH = 56;
}
}
#endif /* COMMON_EMU_LEGACY_H */
+3
View File
@@ -25,6 +25,9 @@ N(OP_AdventureRequest),
N(OP_AdventureStatsReply),
N(OP_AdventureStatsRequest),
N(OP_AdventureUpdate),
N(OP_AggroMeterLockTarget),
N(OP_AggroMeterTargetInfo),
N(OP_AggroMeterUpdate),
N(OP_AltCurrency),
N(OP_AltCurrencyMerchantReply),
N(OP_AltCurrencyMerchantRequest),
+113 -113
View File
@@ -127,244 +127,244 @@ uint32 EQEmu::versions::ConvertClientVersionToExpansion(ClientVersion client_ver
}
}
bool EQEmu::versions::IsValidInventoryVersion(InventoryVersion inventory_version)
bool EQEmu::versions::IsValidMobVersion(MobVersion mob_version)
{
if (inventory_version <= InventoryVersion::Unknown || inventory_version > LastInventoryVersion)
if (mob_version <= MobVersion::Unknown || mob_version > LastMobVersion)
return false;
return true;
}
bool EQEmu::versions::IsValidPCInventoryVersion(InventoryVersion inventory_version)
bool EQEmu::versions::IsValidPCMobVersion(MobVersion mob_version)
{
if (inventory_version <= InventoryVersion::Unknown || inventory_version > LastPCInventoryVersion)
if (mob_version <= MobVersion::Unknown || mob_version > LastPCMobVersion)
return false;
return true;
}
bool EQEmu::versions::IsValidNonPCInventoryVersion(InventoryVersion inventory_version)
bool EQEmu::versions::IsValidNonPCMobVersion(MobVersion mob_version)
{
if (inventory_version <= LastPCInventoryVersion || inventory_version > LastNonPCInventoryVersion)
if (mob_version <= LastPCMobVersion || mob_version > LastNonPCMobVersion)
return false;
return true;
}
bool EQEmu::versions::IsValidOfflinePCInventoryVersion(InventoryVersion inventory_version)
bool EQEmu::versions::IsValidOfflinePCMobVersion(MobVersion mob_version)
{
if (inventory_version <= LastNonPCInventoryVersion || inventory_version > LastOfflinePCInventoryVersion)
if (mob_version <= LastNonPCMobVersion || mob_version > LastOfflinePCMobVersion)
return false;
return true;
}
EQEmu::versions::InventoryVersion EQEmu::versions::ValidateInventoryVersion(InventoryVersion inventory_version)
EQEmu::versions::MobVersion EQEmu::versions::ValidateMobVersion(MobVersion mob_version)
{
if (inventory_version <= InventoryVersion::Unknown || inventory_version > LastInventoryVersion)
return InventoryVersion::Unknown;
if (mob_version <= MobVersion::Unknown || mob_version > LastMobVersion)
return MobVersion::Unknown;
return inventory_version;
return mob_version;
}
EQEmu::versions::InventoryVersion EQEmu::versions::ValidatePCInventoryVersion(InventoryVersion inventory_version)
EQEmu::versions::MobVersion EQEmu::versions::ValidatePCMobVersion(MobVersion mob_version)
{
if (inventory_version <= InventoryVersion::Unknown || inventory_version > LastPCInventoryVersion)
return InventoryVersion::Unknown;
if (mob_version <= MobVersion::Unknown || mob_version > LastPCMobVersion)
return MobVersion::Unknown;
return inventory_version;
return mob_version;
}
EQEmu::versions::InventoryVersion EQEmu::versions::ValidateNonPCInventoryVersion(InventoryVersion inventory_version)
EQEmu::versions::MobVersion EQEmu::versions::ValidateNonPCMobVersion(MobVersion mob_version)
{
if (inventory_version <= LastPCInventoryVersion || inventory_version > LastNonPCInventoryVersion)
return InventoryVersion::Unknown;
if (mob_version <= LastPCMobVersion || mob_version > LastNonPCMobVersion)
return MobVersion::Unknown;
return inventory_version;
return mob_version;
}
EQEmu::versions::InventoryVersion EQEmu::versions::ValidateOfflinePCInventoryVersion(InventoryVersion inventory_version)
EQEmu::versions::MobVersion EQEmu::versions::ValidateOfflinePCMobVersion(MobVersion mob_version)
{
if (inventory_version <= LastNonPCInventoryVersion || inventory_version > LastOfflinePCInventoryVersion)
return InventoryVersion::Unknown;
if (mob_version <= LastNonPCMobVersion || mob_version > LastOfflinePCMobVersion)
return MobVersion::Unknown;
return inventory_version;
return mob_version;
}
const char* EQEmu::versions::InventoryVersionName(InventoryVersion inventory_version)
const char* EQEmu::versions::MobVersionName(MobVersion mob_version)
{
switch (inventory_version) {
case InventoryVersion::Unknown:
switch (mob_version) {
case MobVersion::Unknown:
return "Unknown Version";
case InventoryVersion::Client62:
case MobVersion::Client62:
return "Client 6.2";
case InventoryVersion::Titanium:
case MobVersion::Titanium:
return "Titanium";
case InventoryVersion::SoF:
case MobVersion::SoF:
return "SoF";
case InventoryVersion::SoD:
case MobVersion::SoD:
return "SoD";
case InventoryVersion::UF:
case MobVersion::UF:
return "UF";
case InventoryVersion::RoF:
case MobVersion::RoF:
return "RoF";
case InventoryVersion::RoF2:
case MobVersion::RoF2:
return "RoF2";
case InventoryVersion::NPC:
case MobVersion::NPC:
return "NPC";
case InventoryVersion::NPCMerchant:
case MobVersion::NPCMerchant:
return "NPC Merchant";
case InventoryVersion::Merc:
case MobVersion::Merc:
return "Merc";
case InventoryVersion::Bot:
case MobVersion::Bot:
return "Bot";
case InventoryVersion::ClientPet:
case MobVersion::ClientPet:
return "Client Pet";
case InventoryVersion::NPCPet:
case MobVersion::NPCPet:
return "NPC Pet";
case InventoryVersion::MercPet:
case MobVersion::MercPet:
return "Merc Pet";
case InventoryVersion::BotPet:
case MobVersion::BotPet:
return "Bot Pet";
case InventoryVersion::OfflineTitanium:
case MobVersion::OfflineTitanium:
return "Offline Titanium";
case InventoryVersion::OfflineSoF:
case MobVersion::OfflineSoF:
return "Offline SoF";
case InventoryVersion::OfflineSoD:
case MobVersion::OfflineSoD:
return "Offline SoD";
case InventoryVersion::OfflineUF:
case MobVersion::OfflineUF:
return "Offline UF";
case InventoryVersion::OfflineRoF:
case MobVersion::OfflineRoF:
return "Offline RoF";
case InventoryVersion::OfflineRoF2:
case MobVersion::OfflineRoF2:
return "Offline RoF2";
default:
return "Invalid Version";
};
}
EQEmu::versions::ClientVersion EQEmu::versions::ConvertInventoryVersionToClientVersion(InventoryVersion inventory_version)
EQEmu::versions::ClientVersion EQEmu::versions::ConvertMobVersionToClientVersion(MobVersion mob_version)
{
switch (inventory_version) {
case InventoryVersion::Unknown:
case InventoryVersion::Client62:
switch (mob_version) {
case MobVersion::Unknown:
case MobVersion::Client62:
return ClientVersion::Unknown;
case InventoryVersion::Titanium:
case MobVersion::Titanium:
return ClientVersion::Titanium;
case InventoryVersion::SoF:
case MobVersion::SoF:
return ClientVersion::SoF;
case InventoryVersion::SoD:
case MobVersion::SoD:
return ClientVersion::SoD;
case InventoryVersion::UF:
case MobVersion::UF:
return ClientVersion::UF;
case InventoryVersion::RoF:
case MobVersion::RoF:
return ClientVersion::RoF;
case InventoryVersion::RoF2:
case MobVersion::RoF2:
return ClientVersion::RoF2;
default:
return ClientVersion::Unknown;
}
}
EQEmu::versions::InventoryVersion EQEmu::versions::ConvertClientVersionToInventoryVersion(ClientVersion client_version)
EQEmu::versions::MobVersion EQEmu::versions::ConvertClientVersionToMobVersion(ClientVersion client_version)
{
switch (client_version) {
case ClientVersion::Unknown:
case ClientVersion::Client62:
return InventoryVersion::Unknown;
return MobVersion::Unknown;
case ClientVersion::Titanium:
return InventoryVersion::Titanium;
return MobVersion::Titanium;
case ClientVersion::SoF:
return InventoryVersion::SoF;
return MobVersion::SoF;
case ClientVersion::SoD:
return InventoryVersion::SoD;
return MobVersion::SoD;
case ClientVersion::UF:
return InventoryVersion::UF;
return MobVersion::UF;
case ClientVersion::RoF:
return InventoryVersion::RoF;
return MobVersion::RoF;
case ClientVersion::RoF2:
return InventoryVersion::RoF2;
return MobVersion::RoF2;
default:
return InventoryVersion::Unknown;
return MobVersion::Unknown;
}
}
EQEmu::versions::InventoryVersion EQEmu::versions::ConvertPCInventoryVersionToOfflinePCInventoryVersion(InventoryVersion inventory_version)
EQEmu::versions::MobVersion EQEmu::versions::ConvertPCMobVersionToOfflinePCMobVersion(MobVersion mob_version)
{
switch (inventory_version) {
case InventoryVersion::Titanium:
return InventoryVersion::OfflineTitanium;
case InventoryVersion::SoF:
return InventoryVersion::OfflineSoF;
case InventoryVersion::SoD:
return InventoryVersion::OfflineSoD;
case InventoryVersion::UF:
return InventoryVersion::OfflineUF;
case InventoryVersion::RoF:
return InventoryVersion::OfflineRoF;
case InventoryVersion::RoF2:
return InventoryVersion::OfflineRoF2;
switch (mob_version) {
case MobVersion::Titanium:
return MobVersion::OfflineTitanium;
case MobVersion::SoF:
return MobVersion::OfflineSoF;
case MobVersion::SoD:
return MobVersion::OfflineSoD;
case MobVersion::UF:
return MobVersion::OfflineUF;
case MobVersion::RoF:
return MobVersion::OfflineRoF;
case MobVersion::RoF2:
return MobVersion::OfflineRoF2;
default:
return InventoryVersion::Unknown;
return MobVersion::Unknown;
}
}
EQEmu::versions::InventoryVersion EQEmu::versions::ConvertOfflinePCInventoryVersionToPCInventoryVersion(InventoryVersion inventory_version)
EQEmu::versions::MobVersion EQEmu::versions::ConvertOfflinePCMobVersionToPCMobVersion(MobVersion mob_version)
{
switch (inventory_version) {
case InventoryVersion::OfflineTitanium:
return InventoryVersion::Titanium;
case InventoryVersion::OfflineSoF:
return InventoryVersion::SoF;
case InventoryVersion::OfflineSoD:
return InventoryVersion::SoD;
case InventoryVersion::OfflineUF:
return InventoryVersion::UF;
case InventoryVersion::OfflineRoF:
return InventoryVersion::RoF;
case InventoryVersion::OfflineRoF2:
return InventoryVersion::RoF2;
switch (mob_version) {
case MobVersion::OfflineTitanium:
return MobVersion::Titanium;
case MobVersion::OfflineSoF:
return MobVersion::SoF;
case MobVersion::OfflineSoD:
return MobVersion::SoD;
case MobVersion::OfflineUF:
return MobVersion::UF;
case MobVersion::OfflineRoF:
return MobVersion::RoF;
case MobVersion::OfflineRoF2:
return MobVersion::RoF2;
default:
return InventoryVersion::Unknown;
return MobVersion::Unknown;
}
}
EQEmu::versions::ClientVersion EQEmu::versions::ConvertOfflinePCInventoryVersionToClientVersion(InventoryVersion inventory_version)
EQEmu::versions::ClientVersion EQEmu::versions::ConvertOfflinePCMobVersionToClientVersion(MobVersion mob_version)
{
switch (inventory_version) {
case InventoryVersion::OfflineTitanium:
switch (mob_version) {
case MobVersion::OfflineTitanium:
return ClientVersion::Titanium;
case InventoryVersion::OfflineSoF:
case MobVersion::OfflineSoF:
return ClientVersion::SoF;
case InventoryVersion::OfflineSoD:
case MobVersion::OfflineSoD:
return ClientVersion::SoD;
case InventoryVersion::OfflineUF:
case MobVersion::OfflineUF:
return ClientVersion::UF;
case InventoryVersion::OfflineRoF:
case MobVersion::OfflineRoF:
return ClientVersion::RoF;
case InventoryVersion::OfflineRoF2:
case MobVersion::OfflineRoF2:
return ClientVersion::RoF2;
default:
return ClientVersion::Unknown;
}
}
EQEmu::versions::InventoryVersion EQEmu::versions::ConvertClientVersionToOfflinePCInventoryVersion(ClientVersion client_version)
EQEmu::versions::MobVersion EQEmu::versions::ConvertClientVersionToOfflinePCMobVersion(ClientVersion client_version)
{
switch (client_version) {
case ClientVersion::Titanium:
return InventoryVersion::OfflineTitanium;
return MobVersion::OfflineTitanium;
case ClientVersion::SoF:
return InventoryVersion::OfflineSoF;
return MobVersion::OfflineSoF;
case ClientVersion::SoD:
return InventoryVersion::OfflineSoD;
return MobVersion::OfflineSoD;
case ClientVersion::UF:
return InventoryVersion::OfflineUF;
return MobVersion::OfflineUF;
case ClientVersion::RoF:
return InventoryVersion::OfflineRoF;
return MobVersion::OfflineRoF;
case ClientVersion::RoF2:
return InventoryVersion::OfflineRoF2;
return MobVersion::OfflineRoF2;
default:
return InventoryVersion::Unknown;
return MobVersion::Unknown;
}
}
+27 -29
View File
@@ -64,17 +64,15 @@ namespace EQEmu
const ClientVersion LastClientVersion = ClientVersion::RoF2;
const size_t ClientVersionCount = (static_cast<size_t>(LastClientVersion) + 1);
extern bool IsValidClientVersion(ClientVersion client_version);
extern ClientVersion ValidateClientVersion(ClientVersion client_version);
extern const char* ClientVersionName(ClientVersion client_version);
extern uint32 ConvertClientVersionToClientVersionBit(ClientVersion client_version);
extern ClientVersion ConvertClientVersionBitToClientVersion(uint32 client_version_bit);
extern uint32 ConvertClientVersionToExpansion(ClientVersion client_version);
bool IsValidClientVersion(ClientVersion client_version);
ClientVersion ValidateClientVersion(ClientVersion client_version);
const char* ClientVersionName(ClientVersion client_version);
uint32 ConvertClientVersionToClientVersionBit(ClientVersion client_version);
ClientVersion ConvertClientVersionBitToClientVersion(uint32 client_version_bit);
uint32 ConvertClientVersionToExpansion(ClientVersion client_version);
} /*versions*/
namespace versions {
enum class InventoryVersion {
enum class MobVersion {
Unknown = 0,
Client62,
Titanium,
@@ -99,29 +97,29 @@ namespace EQEmu
OfflineRoF2
};
const InventoryVersion LastInventoryVersion = InventoryVersion::OfflineRoF2;
const InventoryVersion LastPCInventoryVersion = InventoryVersion::RoF2;
const InventoryVersion LastNonPCInventoryVersion = InventoryVersion::BotPet;
const InventoryVersion LastOfflinePCInventoryVersion = InventoryVersion::OfflineRoF2;
const size_t InventoryVersionCount = (static_cast<size_t>(LastInventoryVersion) + 1);
const MobVersion LastMobVersion = MobVersion::OfflineRoF2;
const MobVersion LastPCMobVersion = MobVersion::RoF2;
const MobVersion LastNonPCMobVersion = MobVersion::BotPet;
const MobVersion LastOfflinePCMobVersion = MobVersion::OfflineRoF2;
const size_t MobVersionCount = (static_cast<size_t>(LastMobVersion) + 1);
extern bool IsValidInventoryVersion(InventoryVersion inventory_version);
extern bool IsValidPCInventoryVersion(InventoryVersion inventory_version);
extern bool IsValidNonPCInventoryVersion(InventoryVersion inventory_version);
extern bool IsValidOfflinePCInventoryVersion(InventoryVersion inventory_version);
bool IsValidMobVersion(MobVersion mob_version);
bool IsValidPCMobVersion(MobVersion mob_version);
bool IsValidNonPCMobVersion(MobVersion mob_version);
bool IsValidOfflinePCMobVersion(MobVersion mob_version);
extern InventoryVersion ValidateInventoryVersion(InventoryVersion inventory_version);
extern InventoryVersion ValidatePCInventoryVersion(InventoryVersion inventory_version);
extern InventoryVersion ValidateNonPCInventoryVersion(InventoryVersion inventory_version);
extern InventoryVersion ValidateOfflinePCInventoryVersion(InventoryVersion inventory_version);
MobVersion ValidateMobVersion(MobVersion mob_version);
MobVersion ValidatePCMobVersion(MobVersion mob_version);
MobVersion ValidateNonPCMobVersion(MobVersion mob_version);
MobVersion ValidateOfflinePCMobVersion(MobVersion mob_version);
extern const char* InventoryVersionName(InventoryVersion inventory_version);
extern ClientVersion ConvertInventoryVersionToClientVersion(InventoryVersion inventory_version);
extern InventoryVersion ConvertClientVersionToInventoryVersion(ClientVersion client_version);
extern InventoryVersion ConvertPCInventoryVersionToOfflinePCInventoryVersion(InventoryVersion inventory_version);
extern InventoryVersion ConvertOfflinePCInventoryVersionToPCInventoryVersion(InventoryVersion inventory_version);
extern ClientVersion ConvertOfflinePCInventoryVersionToClientVersion(InventoryVersion inventory_version);
extern InventoryVersion ConvertClientVersionToOfflinePCInventoryVersion(ClientVersion client_version);
const char* MobVersionName(MobVersion mob_version);
ClientVersion ConvertMobVersionToClientVersion(MobVersion mob_version);
MobVersion ConvertClientVersionToMobVersion(ClientVersion client_version);
MobVersion ConvertPCMobVersionToOfflinePCMobVersion(MobVersion mob_version);
MobVersion ConvertOfflinePCMobVersionToPCMobVersion(MobVersion mob_version);
ClientVersion ConvertOfflinePCMobVersionToClientVersion(MobVersion mob_version);
MobVersion ConvertClientVersionToOfflinePCMobVersion(ClientVersion client_version);
} /*versions*/
-8
View File
@@ -516,14 +516,6 @@ static const uint8 SkillDamageTypes[EQEmu::skills::HIGHEST_SKILL + 1] = // chang
*/
#define INVALID_INDEX -1
#define NO_ITEM 0
// yes..these are redundant... but, they help to identify and define what is actually being performed
// plus, since they're pre-op's, they don't affect the actual binary size
#define TYPE_BEGIN 0
#define SLOT_BEGIN 0
#define SUB_INDEX_BEGIN 0
#define AUG_INDEX_BEGIN 0
static const uint32 MAX_SPELL_DB_ID_VAL = 65535;
+791 -189
View File
File diff suppressed because it is too large Load Diff
+10 -3
View File
@@ -38,6 +38,13 @@ namespace EQEmu
class LookupEntry {
public:
size_t CharacterCreationLimit;
int LongBuffs;
int ShortBuffs;
int DiscBuffs;
int TotalBuffs;
int NPCBuffs;
int PetBuffs;
int MercBuffs;
};
const LookupEntry* Lookup(versions::ClientVersion client_version);
@@ -47,7 +54,7 @@ namespace EQEmu
namespace inventory {
class LookupEntry {
public:
size_t InventoryTypeSize[legacy::TypeCount];
size_t InventoryTypeSize[25]; // should reflect EQEmu::inventory::typeCount referenced in emu_constants.h
uint64 PossessionsBitmask;
size_t ItemBagSize;
@@ -59,7 +66,7 @@ namespace EQEmu
bool AllowOverLevelEquipment;
};
const LookupEntry* Lookup(versions::InventoryVersion inventory_version);
const LookupEntry* Lookup(versions::MobVersion mob_version);
} /*inventory*/
@@ -69,7 +76,7 @@ namespace EQEmu
bool CoinHasWeight;
};
const LookupEntry* Lookup(versions::InventoryVersion inventory_version);
const LookupEntry* Lookup(versions::MobVersion mob_version);
} /*behavior*/
+23 -7
View File
@@ -127,7 +127,7 @@ struct LDoNTrapTemplate
// All clients translate the character select information to some degree
struct CharSelectEquip : EQEmu::Texture_Struct, EQEmu::Tint_Struct {};
struct CharSelectEquip : EQEmu::textures::Texture_Struct, EQEmu::textures::Tint_Struct {};
// RoF2-based hybrid struct
struct CharacterSelectEntry_Struct
@@ -142,7 +142,7 @@ struct CharacterSelectEntry_Struct
uint16 Instance;
uint8 Gender;
uint8 Face;
CharSelectEquip Equip[EQEmu::textures::TextureCount];
CharSelectEquip Equip[EQEmu::textures::materialCount];
uint8 Unknown15; // Seen FF
uint8 Unknown19; // Seen FF
uint32 DrakkinTattoo;
@@ -834,7 +834,7 @@ struct SuspendedMinion_Struct
/*002*/ uint32 HP;
/*006*/ uint32 Mana;
/*010*/ SpellBuff_Struct Buffs[BUFF_COUNT];
/*510*/ EQEmu::TextureShortProfile Items;
/*510*/ EQEmu::TextureMaterialProfile Items;
/*546*/ char Name[64];
/*610*/
};
@@ -942,7 +942,7 @@ struct PlayerProfile_Struct
/*0304*/ uint8 ability_time_minutes;
/*0305*/ uint8 ability_time_hours; //place holder
/*0306*/ uint8 unknown0306[6]; // @bp Spacer/Flag?
/*0312*/ EQEmu::TextureShortProfile item_material; // Item texture/material of worn/held items
/*0312*/ EQEmu::TextureMaterialProfile item_material; // Item texture/material of worn/held items
/*0348*/ uint8 unknown0348[44];
/*0392*/ EQEmu::TintProfile item_tint;
/*0428*/ AA_Array aa_array[MAX_PP_AA_ARRAY];
@@ -1179,7 +1179,7 @@ struct WearChange_Struct{
/*010*/ uint32 elite_material; // 1 for Drakkin Elite Material
/*014*/ uint32 hero_forge_model; // New to VoA
/*018*/ uint32 unknown18; // New to RoF
/*022*/ EQEmu::Tint_Struct color;
/*022*/ EQEmu::textures::Tint_Struct color;
/*026*/ uint8 wear_slot_id;
/*027*/
};
@@ -1643,7 +1643,7 @@ struct LootingItem_Struct {
/*002*/ uint32 looter;
/*004*/ uint16 slot_id;
/*006*/ uint8 unknown3[2];
/*008*/ uint32 auto_loot;
/*008*/ int32 auto_loot;
};
struct GuildManageStatus_Struct{
@@ -2071,7 +2071,7 @@ struct AdventureLeaderboard_Struct
/*struct Item_Shop_Struct {
uint16 merchantid;
uint8 itemtype;
EQEmu::ItemBase item;
EQEmu::ItemData item;
uint8 iss_unknown001[6];
};*/
@@ -2243,6 +2243,7 @@ struct GroupFollow_Struct { // SoF Follow Struct
/*0132*/
};
// this is generic struct
struct GroupLeaderChange_Struct
{
/*000*/ char Unknown000[64];
@@ -2495,6 +2496,7 @@ struct BookRequest_Struct {
uint8 window; // where to display the text (0xFF means new window)
uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others.
uint32 invslot; // Only used in Sof and later clients;
int16 subslot; // The subslot inside of a bag if it is inside one.
char txtfile[20];
};
@@ -3517,6 +3519,20 @@ struct RecipeAutoCombine_Struct {
// f5 ff ff ff in 'you dont have all the stuff' reply
};
// this is the "value#a" data
enum EParticlePoint {
eDefault,
eChest,
eHead,
eLeftHand,
eRigthHand,
eLeftFoot,
eRightFood,
eLeftEye,
eRightEye,
eMouth
};
struct LevelAppearance_Struct { //Sends a little graphic on level up
uint32 spawn_id;
uint32 parm1;
+25 -32
View File
@@ -123,26 +123,21 @@ void EQEmuLogSys::LoadLogSettingsDefaults()
std::string EQEmuLogSys::FormatOutMessageString(uint16 log_category, const std::string &in_message)
{
std::string category_string;
if (log_category > 0 && Logs::LogCategoryName[log_category])
category_string = StringFormat("[%s] ", Logs::LogCategoryName[log_category]);
return StringFormat("%s%s", category_string.c_str(), in_message.c_str());
std::string ret;
ret.push_back('[');
ret.append(Logs::LogCategoryName[log_category]);
ret.push_back(']');
ret.push_back(' ');
ret.append(in_message);
return ret;
}
void EQEmuLogSys::ProcessGMSay(uint16 debug_level, uint16 log_category, const std::string &message)
{
/* Check if category enabled for process */
if (log_settings[log_category].log_to_gmsay == 0)
return;
/* Enabling Netcode based GMSay output creates a feedback loop that ultimately ends in a crash */
if (log_category == Logs::LogCategory::Netcode)
return;
/* Make sure the message inbound is at a debug level we're set at */
if (log_settings[log_category].log_to_gmsay < debug_level)
return;
/* Check to see if the process that actually ran this is zone */
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone)
on_log_gmsay_hook(log_category, message);
@@ -160,14 +155,6 @@ void EQEmuLogSys::ProcessLogWrite(uint16 debug_level, uint16 log_category, const
crash_log.close();
}
/* Check if category enabled for process */
if (log_settings[log_category].log_to_file == 0)
return;
/* Make sure the message inbound is at a debug level we're set at */
if (log_settings[log_category].log_to_file < debug_level)
return;
char time_stamp[80];
EQEmuLogSys::SetCurrentTimeStamp(time_stamp);
@@ -246,13 +233,6 @@ uint16 EQEmuLogSys::GetGMSayColorFromCategory(uint16 log_category) {
void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category, const std::string &message)
{
/* Check if category enabled for process */
if (log_settings[log_category].log_to_console == 0)
return;
/* Make sure the message inbound is at a debug level we're set at */
if (log_settings[log_category].log_to_console < debug_level)
return;
#ifdef _WINDOWS
HANDLE console_handle;
@@ -273,12 +253,25 @@ void EQEmuLogSys::ProcessConsoleMessage(uint16 debug_level, uint16 log_category,
void EQEmuLogSys::Out(Logs::DebugLevel debug_level, uint16 log_category, std::string message, ...)
{
const bool log_to_console = log_settings[log_category].log_to_console > 0;
const bool log_to_file = log_settings[log_category].log_to_file > 0;
const bool log_to_gmsay = log_settings[log_category].log_to_gmsay > 0;
const bool nothing_to_log = !log_to_console && !log_to_file && !log_to_gmsay;
if (nothing_to_log) return;
bool log_to_console = true;
if (log_settings[log_category].log_to_console < debug_level) {
log_to_console = false;
}
bool log_to_file = true;
if (log_settings[log_category].log_to_file < debug_level) {
log_to_file = false;
}
bool log_to_gmsay = true;
if (log_settings[log_category].log_to_gmsay < debug_level) {
log_to_gmsay = false;
}
const bool nothing_to_log = !log_to_console && !log_to_file && !log_to_gmsay;
if (nothing_to_log)
return;
va_list args;
va_start(args, message);
+1 -8
View File
@@ -19,11 +19,11 @@
#ifndef EQEMU_LOGSYS_H
#define EQEMU_LOGSYS_H
#include <fmt/format.h>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <functional>
#include "types.h"
namespace Logs {
@@ -158,13 +158,6 @@ public:
void SetCurrentTimeStamp(char* time_stamp); /* Used in file logs to prepend a timestamp entry for logs */
void StartFileLogs(const std::string &log_name = ""); /* Used to declare the processes file log and to keep it open for later use */
template <typename... Args>
void OutF(Logs::DebugLevel debug_level, uint16 log_category, const char *fmt, const Args&... args)
{
std::string log_str = fmt::format(fmt, args...);
Out(debug_level, log_category, log_str);
}
/*
LogSettings Struct
-39
View File
@@ -1,39 +0,0 @@
#pragma once
#include <functional>
#include "event_loop.h"
namespace EQ {
class BackgroundTask
{
public:
typedef std::function<void(void)> BackgroundTaskFunction;
struct BackgroundTaskBaton
{
BackgroundTaskFunction fn;
BackgroundTaskFunction on_finish;
};
BackgroundTask(BackgroundTaskFunction fn, BackgroundTaskFunction on_finish) {
uv_work_t *m_work = new uv_work_t;
memset(m_work, 0, sizeof(uv_work_t));
BackgroundTaskBaton *baton = new BackgroundTaskBaton();
baton->fn = fn;
baton->on_finish = on_finish;
m_work->data = baton;
uv_queue_work(EventLoop::Get().Handle(), m_work, [](uv_work_t* req) {
BackgroundTaskBaton *baton = (BackgroundTaskBaton*)req->data;
baton->fn();
}, [](uv_work_t* req, int status) {
BackgroundTaskBaton *baton = (BackgroundTaskBaton*)req->data;
baton->on_finish();
delete baton;
delete req;
});
}
~BackgroundTask() {
}
};
}
-36
View File
@@ -1,36 +0,0 @@
#pragma once
#include <functional>
#include <uv.h>
namespace EQ
{
class EventLoop
{
public:
static EventLoop &Get() {
static EventLoop inst;
return inst;
}
~EventLoop() {
uv_loop_close(&m_loop);
}
void Process() {
uv_run(&m_loop, UV_RUN_NOWAIT);
}
uv_loop_t* Handle() { return &m_loop; }
private:
EventLoop() {
memset(&m_loop, 0, sizeof(uv_loop_t));
uv_loop_init(&m_loop);
}
EventLoop(const EventLoop&);
EventLoop& operator=(const EventLoop&);
uv_loop_t m_loop;
};
}
-63
View File
@@ -1,63 +0,0 @@
#pragma once
#include <functional>
#include "event_loop.h"
namespace EQ {
class Timer
{
public:
Timer(uint64_t duration_ms, bool repeats, std::function<void(void)> cb)
{
memset(&m_timer, 0, sizeof(uv_timer_t));
m_cb = cb;
m_duration_ms = duration_ms;
m_repeats = repeats;
m_attached = nullptr;
Attach(EventLoop::Get().Handle());
}
~Timer()
{
Detach();
}
private:
void Execute() {
m_cb();
}
virtual void Attach(uv_loop_t *loop) {
if (!m_attached) {
uv_timer_init(loop, &m_timer);
m_timer.data = this;
if (m_repeats) {
uv_timer_start(&m_timer, [](uv_timer_t *handle) {
Timer *t = (Timer*)handle->data;
t->Execute();
}, m_duration_ms, m_duration_ms);
}
else {
uv_timer_start(&m_timer, [](uv_timer_t *handle) {
Timer *t = (Timer*)handle->data;
t->Execute();
}, m_duration_ms, 0);
}
m_attached = loop;
}
}
virtual void Detach() {
if (m_attached) {
uv_timer_stop(&m_timer);
m_attached = nullptr;
}
}
uv_timer_t m_timer;
std::function<void(void)> m_cb;
uint64_t m_duration_ms;
bool m_repeats;
uv_loop_t *m_attached;
};
}
+2 -2
View File
@@ -19,7 +19,7 @@
#define EXTENDED_PROFILE_H
#include "eq_packet_structs.h"
#include "item.h"
#include "inventory_profile.h"
#pragma pack(1)
@@ -40,7 +40,7 @@ struct ExtendedProfile_Struct {
uint16 old_pet_hp; /* Not Used */
uint16 old_pet_mana; /* Not Used */
SpellBuff_Struct pet_buffs[BUFF_COUNT]; /* Not Used */
EQEmu::TextureShortProfile pet_items; /* Not Used */
EQEmu::TextureMaterialProfile pet_items; /* Not Used */
char merc_name[64]; /* Used */
uint32 aa_effects; /* Used */
+3
View File
@@ -235,6 +235,9 @@ enum { //some random constants
#define ZONE_CONTROLLER_NPC_ID 10
// Timer to update aggrometer
#define AGGRO_METER_UPDATE_MS 1000
//Some hard coded statuses from commands and other places:
enum {
minStatusToBeGM = 40,
File diff suppressed because it is too large Load Diff
+230
View File
@@ -0,0 +1,230 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
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 04111-1307 USA
*/
// @merth notes:
// These classes could be optimized with database reads/writes by storing
// a status flag indicating how object needs to interact with database
#ifndef COMMON_INVENTORY_PROFILE_H
#define COMMON_INVENTORY_PROFILE_H
#include "item_instance.h"
#include <list>
//FatherNitwit: location bits for searching specific
//places with HasItem() and HasItemByUse()
enum {
invWhereWorn = 0x01,
invWherePersonal = 0x02, //in the character's inventory
invWhereBank = 0x04,
invWhereSharedBank = 0x08,
invWhereTrading = 0x10,
invWhereCursor = 0x20
};
// ########################################
// Class: Queue
// Queue that allows a read-only iterator
class ItemInstQueue
{
public:
~ItemInstQueue();
/////////////////////////
// Public Methods
/////////////////////////
inline std::list<EQEmu::ItemInstance*>::const_iterator cbegin() { return m_list.cbegin(); }
inline std::list<EQEmu::ItemInstance*>::const_iterator cend() { return m_list.cend(); }
inline int size() { return static_cast<int>(m_list.size()); } // TODO: change to size_t
inline bool empty() { return m_list.empty(); }
void push(EQEmu::ItemInstance* inst);
void push_front(EQEmu::ItemInstance* inst);
EQEmu::ItemInstance* pop();
EQEmu::ItemInstance* pop_back();
EQEmu::ItemInstance* peek_front() const;
protected:
/////////////////////////
// Protected Members
/////////////////////////
std::list<EQEmu::ItemInstance*> m_list;
};
// ########################################
// Class: EQEmu::InventoryProfile
// Character inventory
namespace EQEmu
{
class InventoryProfile
{
friend class ItemInstance;
public:
///////////////////////////////
// Public Methods
///////////////////////////////
InventoryProfile() { m_mob_version = versions::MobVersion::Unknown; m_mob_version_set = false; }
~InventoryProfile();
bool SetInventoryVersion(versions::MobVersion inventory_version) {
if (!m_mob_version_set) {
m_mob_version = versions::ValidateMobVersion(inventory_version);
return (m_mob_version_set = true);
}
else {
return false;
}
}
bool SetInventoryVersion(versions::ClientVersion client_version) { return SetInventoryVersion(versions::ConvertClientVersionToMobVersion(client_version)); }
versions::MobVersion InventoryVersion() { return m_mob_version; }
static void CleanDirty();
static void MarkDirty(ItemInstance *inst);
// Retrieve a writeable item at specified slot
ItemInstance* GetItem(int16 slot_id) const;
ItemInstance* GetItem(int16 slot_id, uint8 bagidx) const;
inline std::list<ItemInstance*>::const_iterator cursor_cbegin() { return m_cursor.cbegin(); }
inline std::list<ItemInstance*>::const_iterator cursor_cend() { return m_cursor.cend(); }
inline int CursorSize() { return m_cursor.size(); }
inline bool CursorEmpty() { return m_cursor.empty(); }
// Retrieve a read-only item from inventory
inline const ItemInstance* operator[](int16 slot_id) const { return GetItem(slot_id); }
// Add item to inventory
int16 PutItem(int16 slot_id, const ItemInstance& inst);
// Add item to cursor queue
int16 PushCursor(const ItemInstance& inst);
// Get cursor item in front of queue
ItemInstance* GetCursorItem();
// Swap items in inventory
bool SwapItem(int16 slot_a, int16 slot_b);
// Remove item from inventory
bool DeleteItem(int16 slot_id, uint8 quantity = 0);
// Checks All items in a bag for No Drop
bool CheckNoDrop(int16 slot_id, bool recurse = true);
// Remove item from inventory (and take control of memory)
ItemInstance* PopItem(int16 slot_id);
// Check whether there is space for the specified number of the specified item.
bool HasSpaceForItem(const ItemData *ItemToTry, int16 Quantity);
// Check whether item exists in inventory
// where argument specifies OR'd list of invWhere constants to look
int16 HasItem(uint32 item_id, uint8 quantity = 0, uint8 where = 0xFF);
// Check whether item exists in inventory
// where argument specifies OR'd list of invWhere constants to look
int16 HasItemByUse(uint8 use, uint8 quantity = 0, uint8 where = 0xFF);
// Check whether item exists in inventory
// where argument specifies OR'd list of invWhere constants to look
int16 HasItemByLoreGroup(uint32 loregroup, uint8 where = 0xFF);
// Locate an available inventory slot
int16 FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size = 0, bool is_arrow = false);
int16 FindFreeSlotForTradeItem(const ItemInstance* inst, int16 general_start = legacy::GENERAL_BEGIN, uint8 bag_start = inventory::containerBegin);
// Calculate slot_id for an item within a bag
static int16 CalcSlotId(int16 slot_id); // Calc parent bag's slot_id
static int16 CalcSlotId(int16 bagslot_id, uint8 bagidx); // Calc slot_id for item inside bag
static uint8 CalcBagIdx(int16 slot_id); // Calc bagidx for slot_id
static int16 CalcSlotFromMaterial(uint8 material);
static uint8 CalcMaterialFromSlot(int16 equipslot);
static bool CanItemFitInContainer(const ItemData *ItemToTry, const ItemData *Container);
// Test for valid inventory casting slot
bool SupportsClickCasting(int16 slot_id);
bool SupportsPotionBeltCasting(int16 slot_id);
// Test whether a given slot can support a container item
static bool SupportsContainers(int16 slot_id);
int GetSlotByItemInst(ItemInstance *inst);
uint8 FindBrightestLightType();
void dumpEntireInventory();
void dumpWornItems();
void dumpInventory();
void dumpBankItems();
void dumpSharedBankItems();
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, std::string value);
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, int value);
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, float value);
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, bool value);
std::string GetCustomItemData(int16 slot_id, std::string identifier);
protected:
///////////////////////////////
// Protected Methods
///////////////////////////////
int GetSlotByItemInstCollection(const std::map<int16, ItemInstance*> &collection, ItemInstance *inst);
void dumpItemCollection(const std::map<int16, ItemInstance*> &collection);
void dumpBagContents(ItemInstance *inst, std::map<int16, ItemInstance*>::const_iterator *it);
// Retrieves item within an inventory bucket
ItemInstance* _GetItem(const std::map<int16, ItemInstance*>& bucket, int16 slot_id) const;
// Private "put" item into bucket, without regard for what is currently in bucket
int16 _PutItem(int16 slot_id, ItemInstance* inst);
// Checks an inventory bucket for a particular item
int16 _HasItem(std::map<int16, ItemInstance*>& bucket, uint32 item_id, uint8 quantity);
int16 _HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity);
int16 _HasItemByUse(std::map<int16, ItemInstance*>& bucket, uint8 use, uint8 quantity);
int16 _HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity);
int16 _HasItemByLoreGroup(std::map<int16, ItemInstance*>& bucket, uint32 loregroup);
int16 _HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup);
// Player inventory
std::map<int16, ItemInstance*> m_worn; // Items worn by character
std::map<int16, ItemInstance*> m_inv; // Items in character personal inventory
std::map<int16, ItemInstance*> m_bank; // Items in character bank
std::map<int16, ItemInstance*> m_shbank; // Items in character shared bank
std::map<int16, ItemInstance*> m_trade; // Items in a trade session
::ItemInstQueue m_cursor; // Items on cursor: FIFO
private:
// Active mob version
versions::MobVersion m_mob_version;
bool m_mob_version_set;
};
}
#endif /*COMMON_INVENTORY_PROFILE_H*/
+397
View File
@@ -0,0 +1,397 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
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
*/
#include "inventory_slot.h"
#include "textures.h"
#include "string_util.h"
int8 EQEmu::inventory::ConvertEquipmentIndexToTextureIndex(int16 slot_index)
{
switch (slot_index) {
case slotHead:
return textures::armorHead;
case slotChest:
return textures::armorChest;
case slotArms:
return textures::armorArms;
case slotWrist1:
return textures::armorWrist;
case slotHands:
return textures::armorHands;
case slotLegs:
return textures::armorLegs;
case slotFeet:
return textures::armorFeet;
case slotPrimary:
return textures::weaponPrimary;
case slotSecondary:
return textures::weaponSecondary;
default:
return textures::textureInvalid;
}
}
int8 EQEmu::inventory::ConvertEquipmentSlotToTextureIndex(const InventorySlot& inventory_slot)
{
if ((!inventory_slot.Typeless() && !inventory_slot.IsTypeIndex(typePossessions)) || !inventory_slot.IsContainerIndex(containerInvalid) || !inventory_slot.IsSocketIndex(socketInvalid))
return textures::textureInvalid;
return ConvertEquipmentIndexToTextureIndex(inventory_slot.SlotIndex());
}
int16 EQEmu::inventory::ConvertTextureIndexToEquipmentIndex(int8 texture_index)
{
switch (texture_index) {
case textures::armorHead:
return slotHead;
case textures::armorChest:
return slotChest;
case textures::armorArms:
return slotArms;
case textures::armorWrist:
return slotWrist1;
case textures::armorHands:
return slotHands;
case textures::armorLegs:
return slotLegs;
case textures::armorFeet:
return slotFeet;
case textures::weaponPrimary:
return slotPrimary;
case textures::weaponSecondary:
return slotSecondary;
default:
return slotInvalid;
}
}
bool EQEmu::InventorySlot::IsValidSlot() const
{
if (_typeless)
return false;
int16 slot_count = inventory::SlotCount(_type_index);
if (!slot_count || _slot_index < inventory::slotBegin || _slot_index >= slot_count)
return false;
if (_container_index < inventory::containerInvalid || _container_index >= inventory::ContainerCount)
return false;
if (_socket_index < inventory::socketInvalid || _socket_index >= inventory::SocketCount)
return false;
return true;
}
bool EQEmu::InventorySlot::IsDeleteSlot() const
{
if (_typeless)
return (_slot_index == inventory::slotInvalid && _container_index == inventory::containerInvalid && _socket_index == inventory::socketInvalid);
else
return (_type_index == inventory::typeInvalid && _slot_index == inventory::slotInvalid && _container_index == inventory::containerInvalid && _socket_index == inventory::socketInvalid);
}
bool EQEmu::InventorySlot::IsEquipmentIndex(int16 slot_index)
{
/*if (slot_index < inventory::EquipmentBegin || slot_index > inventory::EquipmentEnd)
return false;*/
if ((slot_index < legacy::EQUIPMENT_BEGIN || slot_index > legacy::EQUIPMENT_END) && slot_index != legacy::SLOT_POWER_SOURCE)
return false;
return true;
}
bool EQEmu::InventorySlot::IsGeneralIndex(int16 slot_index)
{
/*if (slot_index < inventory::GeneralBegin || slot_index > inventory::GeneralEnd)
return false;*/
if (slot_index < legacy::GENERAL_BEGIN || slot_index > legacy::GENERAL_END)
return false;
return true;
}
bool EQEmu::InventorySlot::IsCursorIndex(int16 slot_index)
{
/*if (slot_index != inventory::slotCursor)
return false;*/
if (slot_index != legacy::SLOT_CURSOR)
return false;
return true;
}
bool EQEmu::InventorySlot::IsWeaponIndex(int16 slot_index)
{
/*if ((slot_index != inventory::slotRange) && (slot_index != inventory::slotPrimary) && (slot_index != inventory::slotSecondary))
return false;*/
if ((slot_index != legacy::SLOT_RANGE) && (slot_index != legacy::SLOT_PRIMARY) && (slot_index != legacy::SLOT_SECONDARY))
return false;
return true;
}
bool EQEmu::InventorySlot::IsTextureIndex(int16 slot_index)
{
switch (slot_index) {
case inventory::slotHead:
case inventory::slotChest:
case inventory::slotArms:
case inventory::slotWrist1:
case inventory::slotHands:
case inventory::slotLegs:
case inventory::slotFeet:
case inventory::slotPrimary:
case inventory::slotSecondary:
return true;
default:
return false;
}
}
bool EQEmu::InventorySlot::IsTintableIndex(int16 slot_index)
{
switch (slot_index) {
case inventory::slotHead:
case inventory::slotChest:
case inventory::slotArms:
case inventory::slotWrist1:
case inventory::slotHands:
case inventory::slotLegs:
case inventory::slotFeet:
return true;
default:
return false;
}
}
bool EQEmu::InventorySlot::IsEquipmentSlot() const
{
if (!_typeless && (_type_index != inventory::typePossessions))
return false;
if ((_container_index != inventory::containerInvalid) || (_socket_index != inventory::socketInvalid))
return false;
return IsEquipmentIndex(_slot_index);
}
bool EQEmu::InventorySlot::IsGeneralSlot() const
{
if (!_typeless && (_type_index != inventory::typePossessions))
return false;
if ((_container_index != inventory::containerInvalid) || (_socket_index != inventory::socketInvalid))
return false;
return IsGeneralIndex(_socket_index);
}
bool EQEmu::InventorySlot::IsCursorSlot() const
{
if (!_typeless && (_type_index != inventory::typePossessions))
return false;
if ((_container_index != inventory::containerInvalid) || (_socket_index != inventory::socketInvalid))
return false;
return IsCursorIndex(_slot_index);
}
bool EQEmu::InventorySlot::IsWeaponSlot() const
{
if (!_typeless && (_type_index != inventory::typePossessions))
return false;
if ((_container_index != inventory::containerInvalid) || (_socket_index != inventory::socketInvalid))
return false;
return IsWeaponIndex(_slot_index);
}
bool EQEmu::InventorySlot::IsTextureSlot() const
{
if (!_typeless && (_type_index != inventory::typePossessions))
return false;
if ((_container_index != inventory::containerInvalid) || (_socket_index != inventory::socketInvalid))
return false;
return IsTextureIndex(_slot_index);
}
bool EQEmu::InventorySlot::IsTintableSlot() const
{
if (!_typeless && (_type_index != inventory::typePossessions))
return false;
if ((_container_index != inventory::containerInvalid) || (_socket_index != inventory::socketInvalid))
return false;
return IsTintableIndex(_slot_index);
}
bool EQEmu::InventorySlot::IsSlot() const
{
if (!_typeless && (_type_index == inventory::typeInvalid))
return false;
if (_slot_index == inventory::slotInvalid)
return false;
if (_container_index != inventory::containerInvalid)
return false;
if (_socket_index != inventory::socketInvalid)
return false;
return true;
}
bool EQEmu::InventorySlot::IsSlotSocket() const
{
if (!_typeless && (_type_index == inventory::typeInvalid))
return false;
if (_slot_index == inventory::slotInvalid)
return false;
if (_container_index != inventory::containerInvalid)
return false;
if (_socket_index == inventory::socketInvalid)
return false;
return true;
}
bool EQEmu::InventorySlot::IsContainer() const
{
if (!_typeless && (_type_index == inventory::typeInvalid))
return false;
if (_slot_index == inventory::slotInvalid)
return false;
if (_container_index == inventory::containerInvalid)
return false;
if (_socket_index != inventory::socketInvalid)
return false;
return true;
}
bool EQEmu::InventorySlot::IsContainerSocket() const
{
if (!_typeless && (_type_index == inventory::typeInvalid))
return false;
if (_slot_index == inventory::slotInvalid)
return false;
if (_container_index == inventory::containerInvalid)
return false;
if (_socket_index == inventory::socketInvalid)
return false;
return true;
}
EQEmu::InventorySlot EQEmu::InventorySlot::ToTopOwner() const
{
return InventorySlot(_type_index, _slot_index);
}
EQEmu::InventorySlot EQEmu::InventorySlot::ToOwner() const
{
if (IsSlot() || IsSlotSocket() || IsContainer())
return InventorySlot(_type_index, _slot_index);
if (IsContainerSocket())
return InventorySlot(_type_index, _slot_index, _container_index);
return InventorySlot();
}
const std::string EQEmu::InventorySlot::ToString() const
{
return StringFormat("(%i%s, %i, %i, %i)", _type_index, (_typeless ? " [typeless]" : ""), _slot_index, _container_index, _socket_index);
}
const std::string EQEmu::InventorySlot::ToName() const
{
return StringFormat("InventorySlot - _type_index: %i%s, _slot_index: %i, _container_index: %i, _socket_index: %i", _type_index, (_typeless ? " [typeless]" : ""), _slot_index, _container_index, _socket_index);
}
void EQEmu::InventorySlot::SetInvalidSlot()
{
_type_index = inventory::typeInvalid;
_slot_index = inventory::slotInvalid;
_container_index = inventory::containerInvalid;
_socket_index = inventory::socketInvalid;
}
//bool EQEmu::InventorySlot::IsBonusIndex(int16 slot_index)
//{
// if ((slot_index >= inventory::EquipmentBegin) && (slot_index <= inventory::EquipmentEnd) && (slot_index != inventory::slotAmmo))
// return true;
//
// return false;
//}
//bool EQEmu::InventorySlot::IsBonusSlot() const
//{
// if ((_type_index != inventory::typePossessions) || (_container_index != inventory::containerInvalid) || (_socket_index != inventory::socketInvalid))
// return false;
//
// return IsBonusIndex(_slot_index);
//}
bool inventory_slot_typeless_lessthan(const EQEmu::InventorySlot& lhs, const EQEmu::InventorySlot& rhs)
{
if (lhs.SlotIndex() < rhs.SlotIndex())
return true;
if ((lhs.SlotIndex() == rhs.SlotIndex()) && (lhs.ContainerIndex() < rhs.ContainerIndex()))
return true;
if ((lhs.SlotIndex() == rhs.SlotIndex()) && (lhs.ContainerIndex() == rhs.ContainerIndex()) && (lhs.SocketIndex() < rhs.SocketIndex()))
return true;
return false;
}
bool EQEmu::InventorySlot::operator<(const InventorySlot& rhs) const
{
if (Typeless() || rhs.Typeless())
return inventory_slot_typeless_lessthan(*this, rhs);
if (TypeIndex() < rhs.TypeIndex())
return true;
if ((TypeIndex() == rhs.TypeIndex()) && (SlotIndex() < rhs.SlotIndex()))
return true;
if ((TypeIndex() == rhs.TypeIndex()) && (SlotIndex() == rhs.SlotIndex()) && (ContainerIndex() < rhs.ContainerIndex()))
return true;
if ((TypeIndex() == rhs.TypeIndex()) && (SlotIndex() == rhs.SlotIndex()) && (ContainerIndex() == rhs.ContainerIndex()) && (SocketIndex() < rhs.SocketIndex()))
return true;
return false;
}
bool EQEmu::operator==(const InventorySlot& lhs, const InventorySlot& rhs)
{
if (lhs.Typeless() || rhs.Typeless())
return ((lhs.SlotIndex() == rhs.SlotIndex()) && (lhs.ContainerIndex() == rhs.ContainerIndex()) && (lhs.SocketIndex() == rhs.SocketIndex()));
return ((lhs.TypeIndex() == rhs.TypeIndex()) && (lhs.SlotIndex() == rhs.SlotIndex()) && (lhs.ContainerIndex() == rhs.ContainerIndex()) && (lhs.SocketIndex() == rhs.SocketIndex()));
}
+133
View File
@@ -0,0 +1,133 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
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 COMMON_INVENTORY_SLOT
#define COMMON_INVENTORY_SLOT
#include "emu_constants.h"
namespace EQEmu
{
class InventorySlot;
namespace inventory {
int8 ConvertEquipmentIndexToTextureIndex(int16 slot_index);
int8 ConvertEquipmentSlotToTextureIndex(const InventorySlot& inventory_slot);
int16 ConvertTextureIndexToEquipmentIndex(int8 texture_index);
}
class InventorySlot {
public:
InventorySlot() : _type_index(inventory::typeInvalid), _slot_index(inventory::slotInvalid), _container_index(inventory::containerInvalid), _socket_index(inventory::socketInvalid), _typeless(false) { }
InventorySlot(int16 type_index) : _type_index(type_index), _slot_index(inventory::slotInvalid), _container_index(inventory::containerInvalid), _socket_index(inventory::socketInvalid), _typeless(false) { }
InventorySlot(int16 type_index, int16 parent_index) : _type_index(type_index), _slot_index(parent_index), _container_index(inventory::containerInvalid), _socket_index(inventory::socketInvalid), _typeless(false) { }
InventorySlot(int16 type_index, int16 parent_index, int16 bag_index) : _type_index(type_index), _slot_index(parent_index), _container_index(bag_index), _socket_index(inventory::socketInvalid), _typeless(false) { }
InventorySlot(int16 type_index, int16 parent_index, int16 bag_index, int16 aug_index) : _type_index(type_index), _slot_index(parent_index), _container_index(bag_index), _socket_index(aug_index), _typeless(false) { }
InventorySlot(const InventorySlot& r) : _type_index(r._type_index), _slot_index(r._slot_index), _container_index(r._container_index), _socket_index(r._socket_index), _typeless(r._typeless) { }
InventorySlot(int16 type_index, const InventorySlot& r) : _type_index(type_index), _slot_index(r._slot_index), _container_index(r._container_index), _socket_index(r._socket_index), _typeless(false) { }
inline int16 TypeIndex() const { return _type_index; }
inline int16 SlotIndex() const { return _slot_index; }
inline int16 ContainerIndex() const { return _container_index; }
inline int16 SocketIndex() const { return _socket_index; }
bool Typeless() const { return _typeless; }
bool IsValidSlot() const;
bool IsDeleteSlot() const;
static bool IsEquipmentIndex(int16 slot_index);
static bool IsGeneralIndex(int16 slot_index);
static bool IsCursorIndex(int16 slot_index);
static bool IsWeaponIndex(int16 slot_index);
static bool IsTextureIndex(int16 slot_index);
static bool IsTintableIndex(int16 slot_index);
bool IsEquipmentSlot() const;
bool IsGeneralSlot() const;
bool IsCursorSlot() const;
bool IsWeaponSlot() const;
bool IsTextureSlot() const;
bool IsTintableSlot() const;
bool IsSlot() const;
bool IsSlotSocket() const;
bool IsContainer() const;
bool IsContainerSocket() const;
InventorySlot ToTopOwner() const;
InventorySlot ToOwner() const;
const std::string ToString() const;
const std::string ToName() const;
bool IsTypeIndex(int16 type_index) const { return (_type_index == type_index); }
bool IsSlotIndex(int16 slot_index) const { return (_slot_index == slot_index); }
bool IsContainerIndex(int16 container_index) const { return (_container_index == container_index); }
bool IsSocketIndex(int16 socket_index) const { return (_socket_index == socket_index); }
void SetType(int16 type_index) { _type_index = type_index; }
void SetSlot(int16 slot_index) { _slot_index = slot_index; }
void SetContainer(int16 container_index) { _container_index = container_index; }
void SetSocket(int16 socket_index) { _socket_index = socket_index; }
void SetInvalidSlot();
void SetTypeInvalid() { _type_index = inventory::typeInvalid; }
void SetSlotInvalid() { _slot_index = inventory::slotInvalid; }
void SetContainerInvalid() { _container_index = inventory::containerInvalid; }
void SetSocketInvalid() { _socket_index = inventory::socketInvalid; }
void SetTypeBegin() { _type_index = inventory::typeBegin; }
void SetSlotBegin() { _slot_index = inventory::slotBegin; }
void SetContainerBegin() { _container_index = inventory::containerBegin; }
void SetSocketBegin() { _socket_index = inventory::socketBegin; }
void IncrementType() { ++_type_index; }
void IncrementSlot() { ++_slot_index; }
void IncrementContainer() { ++_container_index; }
void IncrementSocket() { ++_socket_index; }
void SetTypeless() { _typeless = true; }
void ClearTypeless() { _typeless = false; }
// these two methods should really check for all bonus-valid slots..currently checks for equipment only (rework needed)
//static bool IsBonusIndex(int16 slot_index);
//bool IsBonusSlot() const;
bool operator<(const InventorySlot& rhs) const;
private:
int16 _type_index;
//int16 _unknown2; // not implemented
int16 _slot_index;
int16 _container_index;
int16 _socket_index;
//int16 _unknown1; // not implemented
bool _typeless;
};
bool operator==(const InventorySlot& lhs, const InventorySlot& rhs);
bool operator!=(const InventorySlot& lhs, const InventorySlot& rhs) { return (!(lhs == rhs)); }
} /*EQEmu*/
#endif /*COMMON_INVENTORY_SLOT*/
-3073
View File
File diff suppressed because it is too large Load Diff
-544
View File
@@ -1,544 +0,0 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
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 04111-1307 USA
*/
// @merth notes:
// These classes could be optimized with database reads/writes by storing
// a status flag indicating how object needs to interact with database
#ifndef COMMON_ITEM_H
#define COMMON_ITEM_H
class ItemParse; // Parses item packets
class EvolveInfo; // Stores information about an evolving item family
#include "../common/eq_constants.h"
#include "../common/item_base.h"
#include "../common/timer.h"
#include "../common/bodytypes.h"
#include "../common/deity.h"
#include "../common/memory_buffer.h"
#include <list>
#include <map>
namespace ItemField
{
enum
{
source = 0,
#define F(x) x,
#include "item_fieldlist.h"
#undef F
updated
};
};
// Specifies usage type for item inside ItemInst
enum ItemInstTypes
{
ItemInstNormal = 0,
ItemInstWorldContainer
};
typedef enum {
byFlagIgnore, //do not consider this flag
byFlagSet, //apply action if the flag is set
byFlagNotSet //apply action if the flag is NOT set
} byFlagSetting;
//FatherNitwit: location bits for searching specific
//places with HasItem() and HasItemByUse()
enum {
invWhereWorn = 0x01,
invWherePersonal = 0x02, //in the character's inventory
invWhereBank = 0x04,
invWhereSharedBank = 0x08,
invWhereTrading = 0x10,
invWhereCursor = 0x20
};
class ItemInst;
// ########################################
// Class: Queue
// Queue that allows a read-only iterator
class ItemInstQueue
{
public:
~ItemInstQueue();
/////////////////////////
// Public Methods
/////////////////////////
inline std::list<ItemInst*>::const_iterator cbegin() { return m_list.cbegin(); }
inline std::list<ItemInst*>::const_iterator cend() { return m_list.cend(); }
inline int size() { return static_cast<int>(m_list.size()); } // TODO: change to size_t
inline bool empty() { return m_list.empty(); }
void push(ItemInst* inst);
void push_front(ItemInst* inst);
ItemInst* pop();
ItemInst* pop_back();
ItemInst* peek_front() const;
protected:
/////////////////////////
// Protected Members
/////////////////////////
std::list<ItemInst*> m_list;
};
// ########################################
// Class: Inventory
// Character inventory
class Inventory
{
friend class ItemInst;
public:
///////////////////////////////
// Public Methods
///////////////////////////////
Inventory() { m_inventory_version = EQEmu::versions::InventoryVersion::Unknown; m_inventory_version_set = false; }
~Inventory();
// inv2 creep
bool SetInventoryVersion(EQEmu::versions::InventoryVersion inventory_version) {
if (!m_inventory_version_set) {
m_inventory_version = EQEmu::versions::ValidateInventoryVersion(inventory_version);
return (m_inventory_version_set = true);
}
else {
return false;
}
}
bool SetInventoryVersion(EQEmu::versions::ClientVersion client_version) { return SetInventoryVersion(EQEmu::versions::ConvertClientVersionToInventoryVersion(client_version)); }
EQEmu::versions::InventoryVersion InventoryVersion() { return m_inventory_version; }
static void CleanDirty();
static void MarkDirty(ItemInst *inst);
// Retrieve a writeable item at specified slot
ItemInst* GetItem(int16 slot_id) const;
ItemInst* GetItem(int16 slot_id, uint8 bagidx) const;
inline std::list<ItemInst*>::const_iterator cursor_cbegin() { return m_cursor.cbegin(); }
inline std::list<ItemInst*>::const_iterator cursor_cend() { return m_cursor.cend(); }
inline int CursorSize() { return m_cursor.size(); }
inline bool CursorEmpty() { return m_cursor.empty(); }
// Retrieve a read-only item from inventory
inline const ItemInst* operator[](int16 slot_id) const { return GetItem(slot_id); }
// Add item to inventory
int16 PutItem(int16 slot_id, const ItemInst& inst);
// Add item to cursor queue
int16 PushCursor(const ItemInst& inst);
// Get cursor item in front of queue
ItemInst* GetCursorItem();
// Swap items in inventory
bool SwapItem(int16 slot_a, int16 slot_b);
// Remove item from inventory
bool DeleteItem(int16 slot_id, uint8 quantity=0);
// Checks All items in a bag for No Drop
bool CheckNoDrop(int16 slot_id);
// Remove item from inventory (and take control of memory)
ItemInst* PopItem(int16 slot_id);
// Check whether there is space for the specified number of the specified item.
bool HasSpaceForItem(const EQEmu::ItemBase *ItemToTry, int16 Quantity);
// Check whether item exists in inventory
// where argument specifies OR'd list of invWhere constants to look
int16 HasItem(uint32 item_id, uint8 quantity = 0, uint8 where = 0xFF);
// Check whether item exists in inventory
// where argument specifies OR'd list of invWhere constants to look
int16 HasItemByUse(uint8 use, uint8 quantity=0, uint8 where=0xFF);
// Check whether item exists in inventory
// where argument specifies OR'd list of invWhere constants to look
int16 HasItemByLoreGroup(uint32 loregroup, uint8 where=0xFF);
// Locate an available inventory slot
int16 FindFreeSlot(bool for_bag, bool try_cursor, uint8 min_size = 0, bool is_arrow = false);
int16 FindFreeSlotForTradeItem(const ItemInst* inst);
// Calculate slot_id for an item within a bag
static int16 CalcSlotId(int16 slot_id); // Calc parent bag's slot_id
static int16 CalcSlotId(int16 bagslot_id, uint8 bagidx); // Calc slot_id for item inside bag
static uint8 CalcBagIdx(int16 slot_id); // Calc bagidx for slot_id
static int16 CalcSlotFromMaterial(uint8 material);
static uint8 CalcMaterialFromSlot(int16 equipslot);
static bool CanItemFitInContainer(const EQEmu::ItemBase *ItemToTry, const EQEmu::ItemBase *Container);
// Test for valid inventory casting slot
bool SupportsClickCasting(int16 slot_id);
bool SupportsPotionBeltCasting(int16 slot_id);
// Test whether a given slot can support a container item
static bool SupportsContainers(int16 slot_id);
int GetSlotByItemInst(ItemInst *inst);
uint8 FindBrightestLightType();
void dumpEntireInventory();
void dumpWornItems();
void dumpInventory();
void dumpBankItems();
void dumpSharedBankItems();
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, std::string value);
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, int value);
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, float value);
void SetCustomItemData(uint32 character_id, int16 slot_id, std::string identifier, bool value);
std::string GetCustomItemData(int16 slot_id, std::string identifier);
protected:
///////////////////////////////
// Protected Methods
///////////////////////////////
int GetSlotByItemInstCollection(const std::map<int16, ItemInst*> &collection, ItemInst *inst);
void dumpItemCollection(const std::map<int16, ItemInst*> &collection);
void dumpBagContents(ItemInst *inst, std::map<int16, ItemInst*>::const_iterator *it);
// Retrieves item within an inventory bucket
ItemInst* _GetItem(const std::map<int16, ItemInst*>& bucket, int16 slot_id) const;
// Private "put" item into bucket, without regard for what is currently in bucket
int16 _PutItem(int16 slot_id, ItemInst* inst);
// Checks an inventory bucket for a particular item
int16 _HasItem(std::map<int16, ItemInst*>& bucket, uint32 item_id, uint8 quantity);
int16 _HasItem(ItemInstQueue& iqueue, uint32 item_id, uint8 quantity);
int16 _HasItemByUse(std::map<int16, ItemInst*>& bucket, uint8 use, uint8 quantity);
int16 _HasItemByUse(ItemInstQueue& iqueue, uint8 use, uint8 quantity);
int16 _HasItemByLoreGroup(std::map<int16, ItemInst*>& bucket, uint32 loregroup);
int16 _HasItemByLoreGroup(ItemInstQueue& iqueue, uint32 loregroup);
// Player inventory
std::map<int16, ItemInst*> m_worn; // Items worn by character
std::map<int16, ItemInst*> m_inv; // Items in character personal inventory
std::map<int16, ItemInst*> m_bank; // Items in character bank
std::map<int16, ItemInst*> m_shbank; // Items in character shared bank
std::map<int16, ItemInst*> m_trade; // Items in a trade session
ItemInstQueue m_cursor; // Items on cursor: FIFO
private:
// Active inventory version
EQEmu::versions::InventoryVersion m_inventory_version;
bool m_inventory_version_set;
};
class SharedDatabase;
// ########################################
// Class: ItemInst
// Base class for an instance of an item
// An item instance encapsulates item data + data specific
// to an item instance (includes dye, augments, charges, etc)
class ItemInst
{
public:
/////////////////////////
// Methods
/////////////////////////
// Constructors/Destructor
ItemInst(const EQEmu::ItemBase* item = nullptr, int16 charges = 0);
ItemInst(SharedDatabase *db, uint32 item_id, int16 charges = 0);
ItemInst(ItemInstTypes use_type);
ItemInst(const ItemInst& copy);
~ItemInst();
// Query item type
bool IsType(EQEmu::item::ItemClass item_class) const;
bool IsClassCommon();
bool IsClassBag();
bool IsClassBook();
bool IsClassCommon() const { return const_cast<ItemInst*>(this)->IsClassCommon(); }
bool IsClassBag() const { return const_cast<ItemInst*>(this)->IsClassBag(); }
bool IsClassBook() const { return const_cast<ItemInst*>(this)->IsClassBook(); }
// Can item be stacked?
bool IsStackable() const;
bool IsCharged() const;
// Can item be equipped by/at?
bool IsEquipable(uint16 race, uint16 class_) const;
bool IsEquipable(int16 slot_id) const;
//
// Augments
//
bool IsAugmentable() const;
bool AvailableWearSlot(uint32 aug_wear_slots) const;
int8 AvailableAugmentSlot(int32 augtype) const;
bool IsAugmentSlotAvailable(int32 augtype, uint8 slot) const;
inline int32 GetAugmentType() const { return ((m_item) ? m_item->AugType : NO_ITEM); }
inline bool IsExpendable() const { return ((m_item) ? ((m_item->Click.Type == EQEmu::item::ItemEffectExpendable) || (m_item->ItemType == EQEmu::item::ItemTypePotion)) : false); }
//
// Contents
//
ItemInst* GetItem(uint8 slot) const;
uint32 GetItemID(uint8 slot) const;
inline const ItemInst* operator[](uint8 slot) const { return GetItem(slot); }
void PutItem(uint8 slot, const ItemInst& inst);
void PutItem(SharedDatabase *db, uint8 slot, uint32 item_id) { return; } // not defined anywhere...
void DeleteItem(uint8 slot);
ItemInst* PopItem(uint8 index);
void Clear();
void ClearByFlags(byFlagSetting is_nodrop, byFlagSetting is_norent);
uint8 FirstOpenSlot() const;
uint8 GetTotalItemCount() const;
bool IsNoneEmptyContainer();
std::map<uint8, ItemInst*>* GetContents() { return &m_contents; }
//
// Augments
//
ItemInst* GetAugment(uint8 slot) const;
uint32 GetAugmentItemID(uint8 slot) const;
void PutAugment(uint8 slot, const ItemInst& inst);
void PutAugment(SharedDatabase *db, uint8 slot, uint32 item_id);
void DeleteAugment(uint8 slot);
ItemInst* RemoveAugment(uint8 index);
bool IsAugmented();
ItemInst* GetOrnamentationAug(int32 ornamentationAugtype) const;
bool UpdateOrnamentationInfo();
static bool CanTransform(const EQEmu::ItemBase *ItemToTry, const EQEmu::ItemBase *Container, bool AllowAll = false);
// Has attack/delay?
bool IsWeapon() const;
bool IsAmmo() const;
// Accessors
const uint32 GetID() const { return ((m_item) ? m_item->ID : NO_ITEM); }
const uint32 GetItemScriptID() const { return ((m_item) ? m_item->ScriptFileID : NO_ITEM); }
const EQEmu::ItemBase* GetItem() const;
const EQEmu::ItemBase* GetUnscaledItem() const;
int16 GetCharges() const { return m_charges; }
void SetCharges(int16 charges) { m_charges = charges; }
uint32 GetPrice() const { return m_price; }
void SetPrice(uint32 price) { m_price = price; }
void SetColor(uint32 color) { m_color = color; }
uint32 GetColor() const { return m_color; }
uint32 GetMerchantSlot() const { return m_merchantslot; }
void SetMerchantSlot(uint32 slot) { m_merchantslot = slot; }
int32 GetMerchantCount() const { return m_merchantcount; }
void SetMerchantCount(int32 count) { m_merchantcount = count; }
int16 GetCurrentSlot() const { return m_currentslot; }
void SetCurrentSlot(int16 curr_slot) { m_currentslot = curr_slot; }
// Is this item already attuned?
bool IsAttuned() const { return m_attuned; }
void SetAttuned(bool flag) { m_attuned=flag; }
std::string GetCustomDataString() const;
std::string GetCustomData(std::string identifier);
void SetCustomData(std::string identifier, std::string value);
void SetCustomData(std::string identifier, int value);
void SetCustomData(std::string identifier, float value);
void SetCustomData(std::string identifier, bool value);
void DeleteCustomData(std::string identifier);
// Allows treatment of this object as though it were a pointer to m_item
operator bool() const { return (m_item != nullptr); }
// Compare inner Item_Struct of two ItemInst objects
bool operator==(const ItemInst& right) const { return (this->m_item == right.m_item); }
bool operator!=(const ItemInst& right) const { return (this->m_item != right.m_item); }
// Clone current item
ItemInst* Clone() const;
bool IsSlotAllowed(int16 slot_id) const;
bool IsScaling() const { return m_scaling; }
bool IsEvolving() const { return (m_evolveLvl >= 1); }
uint32 GetExp() const { return m_exp; }
void SetExp(uint32 exp) { m_exp = exp; }
void AddExp(uint32 exp) { m_exp += exp; }
bool IsActivated() { return m_activated; }
void SetActivated(bool activated) { m_activated = activated; }
int8 GetEvolveLvl() const { return m_evolveLvl; }
void SetScaling(bool v) { m_scaling = v; }
uint32 GetOrnamentationIcon() const { return m_ornamenticon; }
void SetOrnamentIcon(uint32 ornament_icon) { m_ornamenticon = ornament_icon; }
uint32 GetOrnamentationIDFile() const { return m_ornamentidfile; }
void SetOrnamentationIDFile(uint32 ornament_idfile) { m_ornamentidfile = ornament_idfile; }
uint32 GetOrnamentHeroModel(int32 material_slot = -1) const;
void SetOrnamentHeroModel(uint32 ornament_hero_model) { m_ornament_hero_model = ornament_hero_model; }
uint32 GetRecastTimestamp() const { return m_recast_timestamp; }
void SetRecastTimestamp(uint32 in) { m_recast_timestamp = in; }
void Initialize(SharedDatabase *db = nullptr);
void ScaleItem();
bool EvolveOnAllKills() const;
int8 GetMaxEvolveLvl() const;
uint32 GetKillsNeeded(uint8 currentlevel);
std::string Serialize(int16 slot_id) const { EQEmu::InternalSerializedItem_Struct s; s.slot_id = slot_id; s.inst = (const void*)this; std::string ser; ser.assign((char*)&s, sizeof(EQEmu::InternalSerializedItem_Struct)); return ser; }
void Serialize(EQEmu::OutBuffer& ob, int16 slot_id) const { EQEmu::InternalSerializedItem_Struct isi; isi.slot_id = slot_id; isi.inst = (const void*)this; ob.write((const char*)&isi, sizeof(isi)); }
inline int32 GetSerialNumber() const { return m_SerialNumber; }
inline void SetSerialNumber(int32 id) { m_SerialNumber = id; }
std::map<std::string, Timer>& GetTimers() { return m_timers; }
void SetTimer(std::string name, uint32 time);
void StopTimer(std::string name);
void ClearTimers();
// Get a total of a stat, including augs
// These functions should be used in place of other code manually totaling
// to centralize where it is done to make future changes easier (ex. whenever powersources come around)
// and to minimize errors. CalcItemBonuses however doesn't use these in interest of performance
// by default these do not recurse into augs
int GetItemArmorClass(bool augments = false) const;
int GetItemElementalDamage(int &magic, int &fire, int &cold, int &poison, int &disease, int &chromatic, int &prismatic, int &physical, int &corruption, bool augments = false) const;
// These two differ in the fact that they're quick checks (they are checked BEFORE the one above
int GetItemElementalFlag(bool augments = false) const;
int GetItemElementalDamage(bool augments = false) const;
int GetItemRecommendedLevel(bool augments = false) const;
int GetItemRequiredLevel(bool augments = false) const;
int GetItemWeaponDamage(bool augments = false) const;
int GetItemBackstabDamage(bool augments = false) const;
// these two are just quick checks
int GetItemBaneDamageBody(bool augments = false) const;
int GetItemBaneDamageRace(bool augments = false) const;
int GetItemBaneDamageBody(bodyType against, bool augments = false) const;
int GetItemBaneDamageRace(uint16 against, bool augments = false) const;
int GetItemMagical(bool augments = false) const;
int GetItemHP(bool augments = false) const;
int GetItemMana(bool augments = false) const;
int GetItemEndur(bool augments = false) const;
int GetItemAttack(bool augments = false) const;
int GetItemStr(bool augments = false) const;
int GetItemSta(bool augments = false) const;
int GetItemDex(bool augments = false) const;
int GetItemAgi(bool augments = false) const;
int GetItemInt(bool augments = false) const;
int GetItemWis(bool augments = false) const;
int GetItemCha(bool augments = false) const;
int GetItemMR(bool augments = false) const;
int GetItemFR(bool augments = false) const;
int GetItemCR(bool augments = false) const;
int GetItemPR(bool augments = false) const;
int GetItemDR(bool augments = false) const;
int GetItemCorrup(bool augments = false) const;
int GetItemHeroicStr(bool augments = false) const;
int GetItemHeroicSta(bool augments = false) const;
int GetItemHeroicDex(bool augments = false) const;
int GetItemHeroicAgi(bool augments = false) const;
int GetItemHeroicInt(bool augments = false) const;
int GetItemHeroicWis(bool augments = false) const;
int GetItemHeroicCha(bool augments = false) const;
int GetItemHeroicMR(bool augments = false) const;
int GetItemHeroicFR(bool augments = false) const;
int GetItemHeroicCR(bool augments = false) const;
int GetItemHeroicPR(bool augments = false) const;
int GetItemHeroicDR(bool augments = false) const;
int GetItemHeroicCorrup(bool augments = false) const;
int GetItemHaste(bool augments = false) const;
protected:
//////////////////////////
// Protected Members
//////////////////////////
std::map<uint8, ItemInst*>::const_iterator _cbegin() { return m_contents.cbegin(); }
std::map<uint8, ItemInst*>::const_iterator _cend() { return m_contents.cend(); }
friend class Inventory;
void _PutItem(uint8 index, ItemInst* inst) { m_contents[index] = inst; }
ItemInstTypes m_use_type; // Usage type for item
const EQEmu::ItemBase* m_item; // Ptr to item data
int16 m_charges; // # of charges for chargeable items
uint32 m_price; // Bazaar /trader price
uint32 m_color;
uint32 m_merchantslot;
int16 m_currentslot;
bool m_attuned;
int32 m_merchantcount; //number avaliable on the merchant, -1=unlimited
int32 m_SerialNumber; // Unique identifier for this instance of an item. Needed for Bazaar.
uint32 m_exp;
int8 m_evolveLvl;
bool m_activated;
EQEmu::ItemBase* m_scaledItem;
EvolveInfo* m_evolveInfo;
bool m_scaling;
uint32 m_ornamenticon;
uint32 m_ornamentidfile;
uint32 m_ornament_hero_model;
uint32 m_recast_timestamp;
//
// Items inside of this item (augs or contents);
std::map<uint8, ItemInst*> m_contents; // Zero-based index: min=0, max=9
std::map<std::string, std::string> m_custom_data;
std::map<std::string, Timer> m_timers;
};
class EvolveInfo {
public:
friend class ItemInst;
//temporary
uint16 LvlKills[9];
uint32 FirstItem;
uint8 MaxLvl;
bool AllKills;
EvolveInfo();
EvolveInfo(uint32 first, uint8 max, bool allkills, uint32 L2, uint32 L3, uint32 L4, uint32 L5, uint32 L6, uint32 L7, uint32 L8, uint32 L9, uint32 L10);
~EvolveInfo();
};
#endif /*COMMON_ITEM_H*/
+27 -9
View File
@@ -17,7 +17,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "item_base.h"
#include "item_data.h"
#include "classes.h"
#include "races.h"
//#include "deity.h"
@@ -167,7 +167,7 @@ uint8 EQEmu::item::ConvertAugTypeBitToAugType(uint32 aug_type_bit)
}
}
bool EQEmu::ItemBase::IsEquipable(uint16 race_id, uint16 class_id)
bool EQEmu::ItemData::IsEquipable(uint16 race_id, uint16 class_id) const
{
if (!(Races & GetPlayerRaceBit(race_id)))
return false;
@@ -178,32 +178,50 @@ bool EQEmu::ItemBase::IsEquipable(uint16 race_id, uint16 class_id)
return true;
}
bool EQEmu::ItemBase::IsClassCommon()
bool EQEmu::ItemData::IsClassCommon() const
{
return (ItemClass == item::ItemClassCommon);
}
bool EQEmu::ItemBase::IsClassBag()
bool EQEmu::ItemData::IsClassBag() const
{
return (ItemClass == item::ItemClassBag);
}
bool EQEmu::ItemBase::IsClassBook()
bool EQEmu::ItemData::IsClassBook() const
{
return (ItemClass == item::ItemClassBook);
}
bool EQEmu::ItemBase::IsType1HWeapon()
bool EQEmu::ItemData::IsType1HWeapon() const
{
return ((ItemType == item::ItemType1HBlunt) || (ItemType == item::ItemType1HSlash) || (ItemType == item::ItemType1HPiercing));
return ((ItemType == item::ItemType1HBlunt) || (ItemType == item::ItemType1HSlash) || (ItemType == item::ItemType1HPiercing) || (ItemType == item::ItemTypeMartial));
}
bool EQEmu::ItemBase::IsType2HWeapon()
bool EQEmu::ItemData::IsType2HWeapon() const
{
return ((ItemType == item::ItemType2HBlunt) || (ItemType == item::ItemType2HSlash) || (ItemType == item::ItemType2HPiercing));
}
bool EQEmu::ItemBase::IsTypeShield()
bool EQEmu::ItemData::IsTypeShield() const
{
return (ItemType == item::ItemTypeShield);
}
bool EQEmu::ItemData::CheckLoreConflict(const ItemData* l_item, const ItemData* r_item)
{
if (!l_item || !r_item)
return false;
if (!l_item->LoreGroup || !r_item->LoreGroup)
return false;
if (l_item->LoreGroup == r_item->LoreGroup) {
if ((l_item->LoreGroup == -1) && (l_item->ID != r_item->ID))
return false;
return true;
}
return false;
}
+18 -35
View File
@@ -17,8 +17,8 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 04111-1307 USA
*/
#ifndef COMMON_ITEM_BASE_H
#define COMMON_ITEM_BASE_H
#ifndef COMMON_ITEM_DATA_H
#define COMMON_ITEM_DATA_H
/*
@@ -50,17 +50,6 @@
namespace EQEmu
{
namespace item {
enum ItemAttributeBit : uint32 {
bit_ItemAttributeNone = 0x00000000,
bit_ItemAttributeLore = 0x00000001,
bit_ItemAttributeArtifact = 0x00000002,
bit_ItemAttributeSummoned = 0x00000004,
bit_ItemAttributeMagic = 0x00000008,
bit_ItemAttributeAugment = 0x00000010,
bit_ItemAttributePendingLore = 0x00000020,
bit_ItemAttributeUnknown = 0xFFFFFFFF
};
enum ItemClass {
ItemClassCommon = 0,
ItemClassBag,
@@ -354,8 +343,8 @@ namespace EQEmu
//ProcRate
};
extern uint32 ConvertAugTypeToAugTypeBit(uint8 aug_type);
extern uint8 ConvertAugTypeBitToAugType(uint32 aug_type_bit);
uint32 ConvertAugTypeToAugTypeBit(uint8 aug_type);
uint8 ConvertAugTypeBitToAugType(uint32 aug_type_bit);
} /*item*/
@@ -364,10 +353,9 @@ namespace EQEmu
const void * inst;
};
struct ItemBase {
struct ItemData {
// Non packet based fields
uint8 MinStatus;
uint8 ItemDataType; // memset to item::ItemDataBase ('0') during mmf load
// Packet based fields
uint8 ItemClass; // Item Type: 0=common, 1=container, 2=book
@@ -476,9 +464,9 @@ namespace EQEmu
int32 FactionAmt4; // Faction Amt 4
char CharmFile[32]; // ?
uint32 AugType;
uint8 AugSlotType[EQEmu::legacy::ITEM_COMMON_SIZE]; // RoF: Augment Slot 1-6 Type
uint8 AugSlotVisible[EQEmu::legacy::ITEM_COMMON_SIZE]; // RoF: Augment Slot 1-6 Visible
uint8 AugSlotUnk2[EQEmu::legacy::ITEM_COMMON_SIZE]; // RoF: Augment Slot 1-6 Unknown Most likely Powersource related
uint8 AugSlotType[inventory::SocketCount]; // RoF: Augment Slot 1-6 Type
uint8 AugSlotVisible[inventory::SocketCount]; // RoF: Augment Slot 1-6 Visible
uint8 AugSlotUnk2[inventory::SocketCount]; // RoF: Augment Slot 1-6 Unknown Most likely Powersource related
uint32 LDoNTheme;
uint32 LDoNPrice;
uint32 LDoNSold;
@@ -543,23 +531,18 @@ namespace EQEmu
char ScrollName[65];
//BardName
bool IsEquipable(uint16 Race, uint16 Class);
bool IsClassCommon();
bool IsClassBag();
bool IsClassBook();
bool IsType1HWeapon();
bool IsType2HWeapon();
bool IsTypeShield();
bool IsEquipable(uint16 Race, uint16 Class) const;
bool IsClassCommon() const;
bool IsClassBag() const;
bool IsClassBook() const;
bool IsType1HWeapon() const;
bool IsType2HWeapon() const;
bool IsTypeShield() const;
bool IsEquipable(uint16 Race, uint16 Class) const { return const_cast<ItemBase*>(this)->IsEquipable(Race, Class); }
bool IsClassCommon() const { return const_cast<ItemBase*>(this)->IsClassCommon(); }
bool IsClassBag() const { return const_cast<ItemBase*>(this)->IsClassBag(); }
bool IsClassBook() const { return const_cast<ItemBase*>(this)->IsClassBook(); }
bool IsType1HWeapon() const { return const_cast<ItemBase*>(this)->IsType1HWeapon(); }
bool IsType2HWeapon() const { return const_cast<ItemBase*>(this)->IsType2HWeapon(); }
bool IsTypeShield() const { return const_cast<ItemBase*>(this)->IsTypeShield(); }
static bool CheckLoreConflict(const ItemData* l_item, const ItemData* r_item);
bool CheckLoreConflict(const ItemData* item) const { return CheckLoreConflict(this, item); }
};
} /*EQEmu*/
#endif /*COMMON_ITEM_BASE_H*/
#endif /*COMMON_ITEM_DATA_H*/
File diff suppressed because it is too large Load Diff
+334
View File
@@ -0,0 +1,334 @@
/* EQEMu: Everquest Server Emulator
Copyright (C) 2001-2016 EQEMu Development Team (http://eqemulator.net)
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 04111-1307 USA
*/
// @merth notes:
// These classes could be optimized with database reads/writes by storing
// a status flag indicating how object needs to interact with database
#ifndef COMMON_ITEM_INSTANCE_H
#define COMMON_ITEM_INSTANCE_H
class ItemParse; // Parses item packets
class EvolveInfo; // Stores information about an evolving item family
#include "../common/eq_constants.h"
#include "../common/item_data.h"
#include "../common/timer.h"
#include "../common/bodytypes.h"
#include "../common/deity.h"
#include "../common/memory_buffer.h"
#include <map>
// Specifies usage type for item inside EQEmu::ItemInstance
enum ItemInstTypes
{
ItemInstNormal = 0,
ItemInstWorldContainer
};
typedef enum {
byFlagIgnore, //do not consider this flag
byFlagSet, //apply action if the flag is set
byFlagNotSet //apply action if the flag is NOT set
} byFlagSetting;
class SharedDatabase;
// ########################################
// Class: EQEmu::ItemInstance
// Base class for an instance of an item
// An item instance encapsulates item data + data specific
// to an item instance (includes dye, augments, charges, etc)
namespace EQEmu
{
class InventoryProfile;
class ItemInstance {
public:
/////////////////////////
// Methods
/////////////////////////
// Constructors/Destructor
ItemInstance(const ItemData* item = nullptr, int16 charges = 0);
ItemInstance(SharedDatabase *db, uint32 item_id, int16 charges = 0);
ItemInstance(ItemInstTypes use_type);
ItemInstance(const ItemInstance& copy);
~ItemInstance();
// Query item type
bool IsType(item::ItemClass item_class) const;
bool IsClassCommon() const;
bool IsClassBag() const;
bool IsClassBook() const;
// Can item be stacked?
bool IsStackable() const;
bool IsCharged() const;
// Can item be equipped by/at?
bool IsEquipable(uint16 race, uint16 class_) const;
bool IsEquipable(int16 slot_id) const;
//
// Augments
//
bool IsAugmentable() const;
bool AvailableWearSlot(uint32 aug_wear_slots) const;
int8 AvailableAugmentSlot(int32 augtype) const;
bool IsAugmentSlotAvailable(int32 augtype, uint8 slot) const;
inline int32 GetAugmentType() const { return ((m_item) ? m_item->AugType : 0); }
inline bool IsExpendable() const { return ((m_item) ? ((m_item->Click.Type == item::ItemEffectExpendable) || (m_item->ItemType == item::ItemTypePotion)) : false); }
//
// Contents
//
ItemInstance* GetItem(uint8 slot) const;
uint32 GetItemID(uint8 slot) const;
inline const ItemInstance* operator[](uint8 slot) const { return GetItem(slot); }
void PutItem(uint8 slot, const ItemInstance& inst);
void PutItem(SharedDatabase *db, uint8 slot, uint32 item_id) { return; } // not defined anywhere...
void DeleteItem(uint8 slot);
ItemInstance* PopItem(uint8 index);
void Clear();
void ClearByFlags(byFlagSetting is_nodrop, byFlagSetting is_norent);
uint8 FirstOpenSlot() const;
uint8 GetTotalItemCount() const;
bool IsNoneEmptyContainer();
std::map<uint8, ItemInstance*>* GetContents() { return &m_contents; }
//
// Augments
//
ItemInstance* GetAugment(uint8 slot) const;
uint32 GetAugmentItemID(uint8 slot) const;
void PutAugment(uint8 slot, const ItemInstance& inst);
void PutAugment(SharedDatabase *db, uint8 slot, uint32 item_id);
void DeleteAugment(uint8 slot);
ItemInstance* RemoveAugment(uint8 index);
bool IsAugmented();
ItemInstance* GetOrnamentationAug(int32 ornamentationAugtype) const;
bool UpdateOrnamentationInfo();
static bool CanTransform(const ItemData *ItemToTry, const ItemData *Container, bool AllowAll = false);
// Has attack/delay?
bool IsWeapon() const;
bool IsAmmo() const;
// Accessors
const uint32 GetID() const { return ((m_item) ? m_item->ID : 0); }
const uint32 GetItemScriptID() const { return ((m_item) ? m_item->ScriptFileID : 0); }
const ItemData* GetItem() const;
const ItemData* GetUnscaledItem() const;
int16 GetCharges() const { return m_charges; }
void SetCharges(int16 charges) { m_charges = charges; }
uint32 GetPrice() const { return m_price; }
void SetPrice(uint32 price) { m_price = price; }
void SetColor(uint32 color) { m_color = color; }
uint32 GetColor() const { return m_color; }
uint32 GetMerchantSlot() const { return m_merchantslot; }
void SetMerchantSlot(uint32 slot) { m_merchantslot = slot; }
int32 GetMerchantCount() const { return m_merchantcount; }
void SetMerchantCount(int32 count) { m_merchantcount = count; }
int16 GetCurrentSlot() const { return m_currentslot; }
void SetCurrentSlot(int16 curr_slot) { m_currentslot = curr_slot; }
// Is this item already attuned?
bool IsAttuned() const { return m_attuned; }
void SetAttuned(bool flag) { m_attuned = flag; }
std::string GetCustomDataString() const;
std::string GetCustomData(std::string identifier);
void SetCustomData(std::string identifier, std::string value);
void SetCustomData(std::string identifier, int value);
void SetCustomData(std::string identifier, float value);
void SetCustomData(std::string identifier, bool value);
void DeleteCustomData(std::string identifier);
// Allows treatment of this object as though it were a pointer to m_item
operator bool() const { return (m_item != nullptr); }
// Compare inner Item_Struct of two ItemInstance objects
bool operator==(const ItemInstance& right) const { return (this->m_item == right.m_item); }
bool operator!=(const ItemInstance& right) const { return (this->m_item != right.m_item); }
// Clone current item
ItemInstance* Clone() const;
bool IsSlotAllowed(int16 slot_id) const;
bool IsDroppable(bool recurse = true) const;
bool IsScaling() const { return m_scaling; }
bool IsEvolving() const { return (m_evolveLvl >= 1); }
uint32 GetExp() const { return m_exp; }
void SetExp(uint32 exp) { m_exp = exp; }
void AddExp(uint32 exp) { m_exp += exp; }
bool IsActivated() { return m_activated; }
void SetActivated(bool activated) { m_activated = activated; }
int8 GetEvolveLvl() const { return m_evolveLvl; }
void SetScaling(bool v) { m_scaling = v; }
uint32 GetOrnamentationIcon() const { return m_ornamenticon; }
void SetOrnamentIcon(uint32 ornament_icon) { m_ornamenticon = ornament_icon; }
uint32 GetOrnamentationIDFile() const { return m_ornamentidfile; }
void SetOrnamentationIDFile(uint32 ornament_idfile) { m_ornamentidfile = ornament_idfile; }
uint32 GetOrnamentHeroModel(int32 material_slot = -1) const;
void SetOrnamentHeroModel(uint32 ornament_hero_model) { m_ornament_hero_model = ornament_hero_model; }
uint32 GetRecastTimestamp() const { return m_recast_timestamp; }
void SetRecastTimestamp(uint32 in) { m_recast_timestamp = in; }
void Initialize(SharedDatabase *db = nullptr);
void ScaleItem();
bool EvolveOnAllKills() const;
int8 GetMaxEvolveLvl() const;
uint32 GetKillsNeeded(uint8 currentlevel);
std::string Serialize(int16 slot_id) const { InternalSerializedItem_Struct s; s.slot_id = slot_id; s.inst = (const void*)this; std::string ser; ser.assign((char*)&s, sizeof(InternalSerializedItem_Struct)); return ser; }
void Serialize(OutBuffer& ob, int16 slot_id) const { InternalSerializedItem_Struct isi; isi.slot_id = slot_id; isi.inst = (const void*)this; ob.write((const char*)&isi, sizeof(isi)); }
inline int32 GetSerialNumber() const { return m_SerialNumber; }
inline void SetSerialNumber(int32 id) { m_SerialNumber = id; }
std::map<std::string, Timer>& GetTimers() { return m_timers; }
void SetTimer(std::string name, uint32 time);
void StopTimer(std::string name);
void ClearTimers();
// Get a total of a stat, including augs
// These functions should be used in place of other code manually totaling
// to centralize where it is done to make future changes easier (ex. whenever powersources come around)
// and to minimize errors. CalcItemBonuses however doesn't use these in interest of performance
// by default these do not recurse into augs
int GetItemArmorClass(bool augments = false) const;
int GetItemElementalDamage(int &magic, int &fire, int &cold, int &poison, int &disease, int &chromatic, int &prismatic, int &physical, int &corruption, bool augments = false) const;
// These two differ in the fact that they're quick checks (they are checked BEFORE the one above
int GetItemElementalFlag(bool augments = false) const;
int GetItemElementalDamage(bool augments = false) const;
int GetItemRecommendedLevel(bool augments = false) const;
int GetItemRequiredLevel(bool augments = false) const;
int GetItemWeaponDamage(bool augments = false) const;
int GetItemBackstabDamage(bool augments = false) const;
// these two are just quick checks
int GetItemBaneDamageBody(bool augments = false) const;
int GetItemBaneDamageRace(bool augments = false) const;
int GetItemBaneDamageBody(bodyType against, bool augments = false) const;
int GetItemBaneDamageRace(uint16 against, bool augments = false) const;
int GetItemMagical(bool augments = false) const;
int GetItemHP(bool augments = false) const;
int GetItemMana(bool augments = false) const;
int GetItemEndur(bool augments = false) const;
int GetItemAttack(bool augments = false) const;
int GetItemStr(bool augments = false) const;
int GetItemSta(bool augments = false) const;
int GetItemDex(bool augments = false) const;
int GetItemAgi(bool augments = false) const;
int GetItemInt(bool augments = false) const;
int GetItemWis(bool augments = false) const;
int GetItemCha(bool augments = false) const;
int GetItemMR(bool augments = false) const;
int GetItemFR(bool augments = false) const;
int GetItemCR(bool augments = false) const;
int GetItemPR(bool augments = false) const;
int GetItemDR(bool augments = false) const;
int GetItemCorrup(bool augments = false) const;
int GetItemHeroicStr(bool augments = false) const;
int GetItemHeroicSta(bool augments = false) const;
int GetItemHeroicDex(bool augments = false) const;
int GetItemHeroicAgi(bool augments = false) const;
int GetItemHeroicInt(bool augments = false) const;
int GetItemHeroicWis(bool augments = false) const;
int GetItemHeroicCha(bool augments = false) const;
int GetItemHeroicMR(bool augments = false) const;
int GetItemHeroicFR(bool augments = false) const;
int GetItemHeroicCR(bool augments = false) const;
int GetItemHeroicPR(bool augments = false) const;
int GetItemHeroicDR(bool augments = false) const;
int GetItemHeroicCorrup(bool augments = false) const;
int GetItemHaste(bool augments = false) const;
protected:
//////////////////////////
// Protected Members
//////////////////////////
friend class InventoryProfile;
std::map<uint8, ItemInstance*>::const_iterator _cbegin() { return m_contents.cbegin(); }
std::map<uint8, ItemInstance*>::const_iterator _cend() { return m_contents.cend(); }
void _PutItem(uint8 index, ItemInstance* inst) { m_contents[index] = inst; }
ItemInstTypes m_use_type; // Usage type for item
const ItemData* m_item; // Ptr to item data
int16 m_charges; // # of charges for chargeable items
uint32 m_price; // Bazaar /trader price
uint32 m_color;
uint32 m_merchantslot;
int16 m_currentslot;
bool m_attuned;
int32 m_merchantcount; //number avaliable on the merchant, -1=unlimited
int32 m_SerialNumber; // Unique identifier for this instance of an item. Needed for Bazaar.
uint32 m_exp;
int8 m_evolveLvl;
bool m_activated;
ItemData* m_scaledItem;
::EvolveInfo* m_evolveInfo;
bool m_scaling;
uint32 m_ornamenticon;
uint32 m_ornamentidfile;
uint32 m_ornament_hero_model;
uint32 m_recast_timestamp;
//
// Items inside of this item (augs or contents);
std::map<uint8, ItemInstance*> m_contents; // Zero-based index: min=0, max=9
std::map<std::string, std::string> m_custom_data;
std::map<std::string, Timer> m_timers;
};
}
class EvolveInfo {
public:
friend class EQEmu::ItemInstance;
//temporary
uint16 LvlKills[9];
uint32 FirstItem;
uint8 MaxLvl;
bool AllKills;
EvolveInfo();
EvolveInfo(uint32 first, uint8 max, bool allkills, uint32 L2, uint32 L3, uint32 L4, uint32 L5, uint32 L6, uint32 L7, uint32 L8, uint32 L9, uint32 L10);
~EvolveInfo();
};
#endif /*COMMON_ITEM_INSTANCE_H*/
-96
View File
@@ -1,96 +0,0 @@
#include "crc32.h"
#include <memory.h>
unsigned int CRC32EncodeTable[256] =
{
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
};
int EQ::Crc32(const void * data, int size)
{
int crc = 0xffffffff;
auto buffer = (const uint8_t *)data;
for (int i = 0; i < size; ++i) {
crc = ((crc >> 8) & 0x00FFFFFFL) ^ CRC32EncodeTable[(crc ^ *&buffer[i]) & 0x000000FFL];
}
return ~crc;
}
int EQ::Crc32(const void * data, int size, int key)
{
int crc = 0xffffffff;
for (int i = 0; i < 4; ++i) {
crc = ((crc >> 8) & 0x00FFFFFFL) ^ CRC32EncodeTable[(crc ^ ((key >> (i * 8)) & 0xff)) & 0x000000FFL];
}
auto buffer = (const uint8_t *)data;
for (int i = 0; i < size; ++i) {
crc = ((crc >> 8) & 0x00FFFFFFL) ^ CRC32EncodeTable[(crc ^ *&buffer[i]) & 0x000000FFL];
}
return ~crc;
}
-9
View File
@@ -1,9 +0,0 @@
#pragma once
#include <stdint.h>
namespace EQ
{
int Crc32(const void *data, int size);
int Crc32(const void *data, int size, int key);
}
File diff suppressed because it is too large Load Diff
-271
View File
@@ -1,271 +0,0 @@
#pragma once
#include "../random.h"
#include "packet.h"
#include "daybreak_structs.h"
#include <uv.h>
#include <chrono>
#include <functional>
#include <memory>
#include <map>
#include <queue>
#include <list>
namespace EQ
{
namespace Net
{
enum DaybreakProtocolOpcode
{
OP_Padding = 0x00,
OP_SessionRequest = 0x01,
OP_SessionResponse = 0x02,
OP_Combined = 0x03,
OP_SessionDisconnect = 0x05,
OP_KeepAlive = 0x06,
OP_SessionStatRequest = 0x07,
OP_SessionStatResponse = 0x08,
OP_Packet = 0x09,
OP_Packet2 = 0x0a,
OP_Packet3 = 0x0b,
OP_Packet4 = 0x0c,
OP_Fragment = 0x0d,
OP_Fragment2 = 0x0e,
OP_Fragment3 = 0x0f,
OP_Fragment4 = 0x10,
OP_OutOfOrderAck = 0x11,
OP_OutOfOrderAck2 = 0x12,
OP_OutOfOrderAck3 = 0x13,
OP_OutOfOrderAck4 = 0x14,
OP_Ack = 0x15,
OP_Ack2 = 0x16,
OP_Ack3 = 0x17,
OP_Ack4 = 0x18,
OP_AppCombined = 0x19,
OP_OutboundPing = 0x1c,
OP_OutOfSession = 0x1d
};
enum DbProtocolStatus
{
StatusConnecting,
StatusConnected,
StatusDisconnecting,
StatusDisconnected
};
enum DaybreakEncodeType
{
EncodeNone = 0,
EncodeCompression = 1,
EncodeXOR = 4,
};
enum SequenceOrder
{
SequenceCurrent,
SequenceFuture,
SequencePast
};
typedef std::chrono::system_clock::time_point Timestamp;
typedef std::chrono::system_clock Clock;
struct DaybreakConnectionStats
{
DaybreakConnectionStats() {
recv_bytes = 0;
sent_bytes = 0;
recv_packets = 0;
sent_packets = 0;
total_ping = 0;
total_acks = 0;
min_ping = 0xFFFFFFFFFFFFFFFFUL;
max_ping = 0;
created = Clock::now();
}
uint64_t recv_bytes;
uint64_t sent_bytes;
uint64_t recv_packets;
uint64_t sent_packets;
uint64_t total_ping;
uint64_t total_acks;
uint64_t min_ping;
uint64_t max_ping;
Timestamp created;
};
class DaybreakConnectionManager;
class DaybreakConnection;
class DaybreakConnection
{
public:
DaybreakConnection(DaybreakConnectionManager *owner, const DaybreakConnect &connect, const std::string &endpoint, int port);
DaybreakConnection(DaybreakConnectionManager *owner, const std::string &endpoint, int port);
~DaybreakConnection();
const std::string& RemoteEndpoint() const { return m_endpoint; }
int RemotePort() const { return m_port; }
void QueuePacket(Packet &p);
void QueuePacket(Packet &p, int stream);
void QueuePacket(Packet &p, int stream, bool reliable);
const DaybreakConnectionStats& GetStats() const { return m_stats; }
void ResetStats();
size_t GetRollingPing() const { return m_rolling_ping; }
private:
DaybreakConnectionManager *m_owner;
std::string m_endpoint;
int m_port;
uint32_t m_connect_code;
uint32_t m_encode_key;
uint32_t m_max_packet_size;
uint32_t m_crc_bytes;
DaybreakEncodeType m_encode_passes[2];
Timestamp m_last_send;
Timestamp m_last_recv;
DbProtocolStatus m_status;
Timestamp m_hold_time;
std::list<WritablePacket> m_buffered_packets;
size_t m_buffered_packets_length;
Timestamp m_last_stats;
DaybreakConnectionStats m_stats;
Timestamp m_last_session_stats;
uint64_t m_last_session_stats_ping;
size_t m_resend_delay;
size_t m_rolling_ping;
struct DaybreakSentPacket
{
WritablePacket packet;
Timestamp last_sent;
Timestamp first_sent;
size_t times_resent;
};
struct DaybreakStream
{
DaybreakStream() {
sequence_in = 0;
sequence_out = 0;
fragment_current_bytes = 0;
fragment_total_bytes = 0;
}
uint16_t sequence_in;
uint16_t sequence_out;
std::map<uint16_t, Packet*> packet_queue;
WritablePacket fragment_packet;
uint32_t fragment_current_bytes;
uint32_t fragment_total_bytes;
std::map<uint16_t, DaybreakSentPacket> sent_packets;
};
DaybreakStream m_streams[4];
std::weak_ptr<DaybreakConnection> m_self;
void Process();
void ProcessPacket(Packet &p);
void ProcessQueue();
void RemoveFromQueue(int stream, uint16_t seq);
void AddToQueue(int stream, uint16_t seq, const Packet &p);
void ProcessDecodedPacket(const Packet &p);
void ChangeStatus(DbProtocolStatus new_status);
bool ValidateCRC(Packet &p);
void AppendCRC(Packet &p);
bool PacketCanBeEncoded(Packet &p) const;
void Decode(Packet &p, size_t offset, size_t length);
void Encode(Packet &p, size_t offset, size_t length);
void Decompress(Packet &p, size_t offset, size_t length);
void Compress(Packet &p, size_t offset, size_t length);
void ProcessResend();
void ProcessResend(int stream);
void Ack(int stream, uint16_t seq);
void OutOfOrderAck(int stream, uint16_t seq);
void SendConnect();
void SendKeepAlive();
void SendAck(int stream, uint16_t seq);
void SendOutOfOrderAck(int stream, uint16_t seq);
void SendStatSync();
void InternalBufferedSend(Packet &p);
void InternalSend(Packet &p);
void InternalQueuePacket(Packet &p, int stream_id, bool reliable);
void FlushBuffer();
SequenceOrder CompareSequence(uint16_t expected, uint16_t actual) const;
friend class DaybreakConnectionManager;
};
struct DaybreakConnectionManagerOptions
{
DaybreakConnectionManagerOptions() {
max_connection_count = 0;
keepalive_delay_ms = 0;
resend_delay_ms = 1000;
stats_delay_ms = 10000;
connect_delay_ms = 1000;
stale_connection_ms = 60000;
crc_length = 2;
max_packet_size = 512;
encode_passes[0] = DaybreakEncodeType::EncodeNone;
encode_passes[1] = DaybreakEncodeType::EncodeNone;
port = 0;
hold_size = 384;
hold_length_ms = 50;
}
size_t max_packet_size;
size_t max_connection_count;
size_t keepalive_delay_ms;
size_t resend_delay_ms;
size_t stats_delay_ms;
size_t connect_delay_ms;
size_t stale_connection_ms;
size_t crc_length;
size_t hold_size;
size_t hold_length_ms;
DaybreakEncodeType encode_passes[2];
int port;
};
class DaybreakConnectionManager
{
public:
DaybreakConnectionManager();
DaybreakConnectionManager(const DaybreakConnectionManagerOptions &opts);
~DaybreakConnectionManager();
void Connect(const std::string &addr, int port);
void Process();
void ProcessResend();
void OnNewConnection(std::function<void(std::shared_ptr<DaybreakConnection>)> func) { m_on_new_connection = func; }
void OnConnectionStateChange(std::function<void(std::shared_ptr<DaybreakConnection>, DbProtocolStatus, DbProtocolStatus)> func) { m_on_connection_state_change = func; }
void OnPacketRecv(std::function<void(std::shared_ptr<DaybreakConnection>, const Packet &)> func) { m_on_packet_recv = func; }
private:
void Attach(uv_loop_t *loop);
void Detach();
EQEmu::Random m_rand;
uv_timer_t m_timer;
uv_timer_t m_resend_timer;
uv_udp_t m_socket;
uv_loop_t *m_attached;
DaybreakConnectionManagerOptions m_options;
std::function<void(std::shared_ptr<DaybreakConnection>)> m_on_new_connection;
std::function<void(std::shared_ptr<DaybreakConnection>, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change;
std::function<void(std::shared_ptr<DaybreakConnection>, const Packet&)> m_on_packet_recv;
std::map<std::pair<std::string, int>, std::shared_ptr<DaybreakConnection>> m_connections;
void ProcessPacket(const std::string &endpoint, int port, const char *data, size_t size);
std::shared_ptr<DaybreakConnection> FindConnectionByEndpoint(std::string addr, int port);
void SendSessionLost(const std::string &addr, int port);
friend class DaybreakConnection;
};
}
}
-175
View File
@@ -1,175 +0,0 @@
#pragma once
#include <cereal/cereal.hpp>
#include <cstdint>
#include "endian.h"
namespace EQ
{
namespace Net
{
struct DaybreakHeader
{
static size_t size() { return 2; }
uint8_t zero;
uint8_t opcode;
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(zero),
CEREAL_NVP(opcode));
}
};
struct DaybreakConnect
{
static size_t size() { return 14; }
uint8_t zero;
uint8_t opcode;
uint32_t protocol_version;
uint32_t connect_code;
uint32_t max_packet_size;
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(zero),
CEREAL_NVP(opcode),
CEREAL_NVP(protocol_version),
CEREAL_NVP(connect_code),
CEREAL_NVP(max_packet_size));
}
};
struct DaybreakConnectReply
{
static size_t size() { return 17; }
uint8_t zero;
uint8_t opcode;
uint32_t connect_code;
uint32_t encode_key;
uint8_t crc_bytes;
uint8_t encode_pass1;
uint8_t encode_pass2;
uint32_t max_packet_size;
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(zero),
CEREAL_NVP(opcode),
CEREAL_NVP(connect_code),
CEREAL_NVP(encode_key),
CEREAL_NVP(crc_bytes),
CEREAL_NVP(encode_pass1),
CEREAL_NVP(encode_pass2),
CEREAL_NVP(max_packet_size));
}
};
struct DaybreakDisconnect
{
static size_t size() { return 8; }
uint8_t zero;
uint8_t opcode;
uint32_t connect_code;
uint16_t disconnect_code;
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(zero),
CEREAL_NVP(opcode),
CEREAL_NVP(connect_code),
CEREAL_NVP(disconnect_code));
}
};
struct DaybreakReliableHeader
{
static size_t size() { return 4; }
uint8_t zero;
uint8_t opcode;
uint16_t sequence;
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(zero),
CEREAL_NVP(opcode),
CEREAL_NVP(sequence));
}
};
struct DaybreakReliableFragmentHeader
{
static size_t size() { return 4 + DaybreakReliableHeader::size(); }
DaybreakReliableHeader reliable;
uint32_t total_size;
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(reliable),
CEREAL_NVP(total_size));
}
};
struct DaybreakSessionStatRequestHeader
{
static size_t size() { return 40; }
uint8_t zero;
uint8_t opcode;
uint16_t timestamp;
uint32_t stat_ping;
uint32_t avg_ping;
uint32_t min_ping;
uint32_t max_ping;
uint32_t last_ping;
uint64_t packets_sent;
uint64_t packets_recv;
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(zero),
CEREAL_NVP(opcode),
CEREAL_NVP(timestamp),
CEREAL_NVP(stat_ping),
CEREAL_NVP(avg_ping),
CEREAL_NVP(min_ping),
CEREAL_NVP(max_ping),
CEREAL_NVP(last_ping),
CEREAL_NVP(packets_sent),
CEREAL_NVP(packets_recv));
}
};
struct DaybreakSessionStatResponseHeader
{
static size_t size() { return 40; }
uint8_t zero;
uint8_t opcode;
uint16_t timestamp;
uint32_t our_timestamp;
uint64_t client_sent;
uint64_t client_recv;
uint64_t server_sent;
uint64_t server_recv;
template <class Archive>
void serialize(Archive & archive)
{
archive(CEREAL_NVP(zero),
CEREAL_NVP(opcode),
CEREAL_NVP(timestamp),
CEREAL_NVP(our_timestamp),
CEREAL_NVP(client_sent),
CEREAL_NVP(client_recv),
CEREAL_NVP(server_sent),
CEREAL_NVP(server_recv));
}
};
}
}
-51
View File
@@ -1,51 +0,0 @@
#pragma once
#include <cstdint>
#include <algorithm>
#include <type_traits>
namespace EQ
{
namespace Net
{
inline bool IsLittleEndian() {
static int32_t v = 1;
return 1 == *(int8_t*)&v;
}
template<typename T>
T ByteSwap(T in) {
static_assert(std::is_integral<T>::value, "Byte swap only works on integer types.");
T ret;
char *first = (char*)&in;
char *last = (char*)&in + sizeof(in);
char *d_first = (char*)&ret;
while (first != last) {
*(d_first++) = *(--last);
}
return ret;
}
template<typename T>
T HostToNetwork(T in) {
if (IsLittleEndian()) {
return ByteSwap(in);
}
else {
return in;
}
}
template<typename T>
T NetworkToHost(T in) {
if (IsLittleEndian()) {
return ByteSwap(in);
}
else {
return in;
}
}
}
}
-115
View File
@@ -1,115 +0,0 @@
#include "eqstream.h"
#include "../eqemu_logsys.h"
EQ::Net::EQStreamManager::EQStreamManager(EQStreamManagerOptions &options) : m_daybreak(options.daybreak_options)
{
m_options = options;
m_daybreak.OnNewConnection(std::bind(&EQStreamManager::DaybreakNewConnection, this, std::placeholders::_1));
m_daybreak.OnConnectionStateChange(std::bind(&EQStreamManager::DaybreakConnectionStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
m_daybreak.OnPacketRecv(std::bind(&EQStreamManager::DaybreakPacketRecv, this, std::placeholders::_1, std::placeholders::_2));
}
EQ::Net::EQStreamManager::~EQStreamManager()
{
}
void EQ::Net::EQStreamManager::DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection)
{
std::shared_ptr<EQStream> stream(new EQStream(this, connection));
m_streams.insert(std::make_pair(connection, stream));
if (m_on_new_connection) {
m_on_new_connection(stream);
}
}
void EQ::Net::EQStreamManager::DaybreakConnectionStateChange(std::shared_ptr<DaybreakConnection> connection, DbProtocolStatus from, DbProtocolStatus to)
{
auto iter = m_streams.find(connection);
if (iter != m_streams.end()) {
if (m_on_connection_state_change) {
m_on_connection_state_change(iter->second, from, to);
}
if (to == EQ::Net::StatusDisconnected) {
m_streams.erase(iter);
}
}
}
void EQ::Net::EQStreamManager::DaybreakPacketRecv(std::shared_ptr<DaybreakConnection> connection, const Packet &p)
{
auto iter = m_streams.find(connection);
if (iter != m_streams.end()) {
auto patch = iter->second->GetRegisteredPatch();
if (patch == nullptr && m_possible_patches.size() > 0) {
for (auto &pt : m_possible_patches) {
auto match = pt->TryIdentityMatch(p);
if (match == EQ::Patches::IdentityMatchSuccess) {
iter->second->RegisterPatch(pt.get());
patch = pt.get();
Log.OutF(Logs::General, Logs::Debug, "Identified patch with name {0}", pt->GetName());
}
}
}
if (patch) {
EmuOpcode opcode;
EQ::Net::WritablePacket out;
patch->Decode(&p, opcode, out);
if (opcode == OP_Unknown) {
Log.OutF(Logs::General, Logs::Netcode, "Incoming packet was not handled because the opcode was not found.\n{0}", p.ToString());
}
else {
if (m_on_packet_recv) {
m_on_packet_recv(iter->second, opcode, out);
}
}
}
else {
Log.OutF(Logs::General, Logs::Netcode, "Incoming packet was not handled because we don't have a patch set.\n{0}", p.ToString());
}
}
}
EQ::Net::EQStream::EQStream(EQStreamManager *owner, std::shared_ptr<DaybreakConnection> connection)
{
m_owner = owner;
m_connection = connection;
m_patch = nullptr;
}
EQ::Net::EQStream::~EQStream()
{
}
void EQ::Net::EQStream::QueuePacket(EmuOpcode type, const Packet &p)
{
if (m_patch) {
EQ::Net::WritablePacket trans;
m_patch->Encode(m_connection, type, &p);
}
}
void EQ::Net::EQStream::ResetStats()
{
m_connection->ResetStats();
}
void EQ::Net::EQStream::Close()
{
}
void EQ::Net::EQStream::QueuePacket(const EQApplicationPacket *p)
{
EQ::Net::ReadOnlyPacket out(p->pBuffer, p->size);
QueuePacket(p->GetOpcode(), out);
}
void EQ::Net::EQStream::FastQueuePacket(const EQApplicationPacket **p)
{
QueuePacket(*p);
delete *p;
}
-89
View File
@@ -1,89 +0,0 @@
#pragma once
#include "../patch/patch.h"
#include "../eq_packet.h"
#include "daybreak_connection.h"
#include <vector>
namespace EQ
{
namespace Net
{
struct EQStreamManagerOptions
{
EQStreamManagerOptions() {
}
EQStreamManagerOptions(bool encoded, bool compressed) {
if (encoded) {
daybreak_options.encode_passes[0] = EncodeXOR;
if (compressed) {
daybreak_options.encode_passes[1] = EncodeCompression;
}
}
else {
if (compressed) {
daybreak_options.encode_passes[0] = EncodeCompression;
}
}
}
DaybreakConnectionManagerOptions daybreak_options;
};
class EQStream;
class EQStreamManager
{
public:
EQStreamManager(EQStreamManagerOptions &options);
~EQStreamManager();
void OnNewConnection(std::function<void(std::shared_ptr<EQStream>)> func) { m_on_new_connection = func; }
void OnConnectionStateChange(std::function<void(std::shared_ptr<EQStream>, DbProtocolStatus, DbProtocolStatus)> func) { m_on_connection_state_change = func; }
void OnPacketRecv(std::function<void(std::shared_ptr<EQStream>, EmuOpcode, const Packet &)> func) { m_on_packet_recv = func; }
void RegisterPotentialPatch(EQ::Patches::BasePatch *patch) { m_possible_patches.push_back(std::unique_ptr<EQ::Patches::BasePatch>(patch)); }
private:
EQStreamManagerOptions m_options;
DaybreakConnectionManager m_daybreak;
std::function<void(std::shared_ptr<EQStream>)> m_on_new_connection;
std::function<void(std::shared_ptr<EQStream>, DbProtocolStatus, DbProtocolStatus)> m_on_connection_state_change;
std::function<void(std::shared_ptr<EQStream>, EmuOpcode, const Packet &)> m_on_packet_recv;
std::map<std::shared_ptr<DaybreakConnection>, std::shared_ptr<EQStream>> m_streams;
std::vector<std::unique_ptr<EQ::Patches::BasePatch>> m_possible_patches;
void DaybreakNewConnection(std::shared_ptr<DaybreakConnection> connection);
void DaybreakConnectionStateChange(std::shared_ptr<DaybreakConnection> connection, DbProtocolStatus from, DbProtocolStatus to);
void DaybreakPacketRecv(std::shared_ptr<DaybreakConnection> connection, const Packet &p);
friend class EQStream;
};
class EQStream
{
public:
EQStream(EQStreamManager *parent, std::shared_ptr<DaybreakConnection> connection);
~EQStream();
const std::string& RemoteEndpoint() const { return m_connection->RemoteEndpoint(); }
int RemotePort() const { return m_connection->RemotePort(); }
void QueuePacket(EmuOpcode type, const Packet &p);
const DaybreakConnectionStats& GetStats() const { return m_connection->GetStats(); }
void ResetStats();
size_t GetRollingPing() const { return m_connection->GetRollingPing(); }
void Close();
void QueuePacket(const EQApplicationPacket *p);
void FastQueuePacket(const EQApplicationPacket **p);
void RegisterPatch(EQ::Patches::BasePatch *p) { m_patch = p; }
EQ::Patches::BasePatch *GetRegisteredPatch() { return m_patch; }
private:
EQStreamManager *m_owner;
std::shared_ptr<DaybreakConnection> m_connection;
EQ::Patches::BasePatch *m_patch;
friend class EQStreamManager;
};
}
}
-332
View File
@@ -1,332 +0,0 @@
#include "packet.h"
#include "endian.h"
#include <fmt/format.h>
#include <cctype>
void EQ::Net::Packet::PutInt8(size_t offset, int8_t value)
{
if (Length() < offset + 1) {
if (!Resize(offset + 1)) {
throw std::out_of_range("Packet::PutInt8(), could not resize packet and would of written past the end.");
}
}
*(int8_t*)((char*)Data() + offset) = value;
}
void EQ::Net::Packet::PutInt16(size_t offset, int16_t value)
{
if (Length() < offset + 2) {
if (!Resize(offset + 2)) {
throw std::out_of_range("Packet::PutInt16(), could not resize packet and would of written past the end.");
}
}
*(int16_t*)((char*)Data() + offset) = value;
}
void EQ::Net::Packet::PutInt32(size_t offset, int32_t value)
{
if (Length() < offset + 4) {
if (!Resize(offset + 4)) {
throw std::out_of_range("Packet::PutInt32(), could not resize packet and would of written past the end.");
}
}
*(int32_t*)((char*)Data() + offset) = value;
}
void EQ::Net::Packet::PutInt64(size_t offset, int64_t value)
{
if (Length() < offset + 8) {
if (!Resize(offset + 8)) {
throw std::out_of_range("Packet::PutInt64(), could not resize packet and would of written past the end.");
}
}
*(int64_t*)((char*)Data() + offset) = value;
}
void EQ::Net::Packet::PutUInt8(size_t offset, uint8_t value)
{
if (Length() < offset + 1) {
if (!Resize(offset + 1)) {
throw std::out_of_range("Packet::PutUInt8(), could not resize packet and would of written past the end.");
}
}
*(uint8_t*)((char*)Data() + offset) = value;
}
void EQ::Net::Packet::PutUInt16(size_t offset, uint16_t value)
{
if (Length() < offset + 2) {
if (!Resize(offset + 2)) {
throw std::out_of_range("Packet::PutUInt16(), could not resize packet and would of written past the end.");
}
}
*(uint16_t*)((char*)Data() + offset) = value;
}
void EQ::Net::Packet::PutUInt32(size_t offset, uint32_t value)
{
if (Length() < offset + 4) {
if (!Resize(offset + 4)) {
throw std::out_of_range("Packet::PutUInt32(), could not resize packet and would of written past the end.");
}
}
*(uint32_t*)((char*)Data() + offset) = value;
}
void EQ::Net::Packet::PutUInt64(size_t offset, uint64_t value)
{
if (Length() < offset + 8) {
if (!Resize(offset + 8)) {
throw std::out_of_range("Packet::PutUInt64(), could not resize packet and would of written past the end.");
}
}
*(uint64_t*)((char*)Data() + offset) = value;
}
void EQ::Net::Packet::PutFloat(size_t offset, float value)
{
if (Length() < offset + 4) {
if (!Resize(offset + 4)) {
throw std::out_of_range("Packet::PutFloat(), could not resize packet and would of written past the end.");
}
}
*(float*)((char*)Data() + offset) = value;
}
void EQ::Net::Packet::PutDouble(size_t offset, double value)
{
if (Length() < offset + 8) {
if (!Resize(offset + 8)) {
throw std::out_of_range("Packet::PutDouble(), could not resize packet and would of written past the end.");
}
}
*(double*)((char*)Data() + offset) = value;
}
void EQ::Net::Packet::PutString(size_t offset, const std::string &str)
{
if (Length() < offset + str.length()) {
if (!Resize(offset + str.length())) {
throw std::out_of_range("Packet::PutString(), could not resize packet and would of written past the end.");
}
}
memcpy(((char*)Data() + offset), str.c_str(), str.length());
}
void EQ::Net::Packet::PutCString(size_t offset, const char *str)
{
size_t sz = strlen(str);
if (Length() < offset + sz + 1) {
if (!Resize(offset + sz + 1)) {
throw std::out_of_range("Packet::PutCString(), could not resize packet and would of written past the end.");
}
}
memcpy(((char*)Data() + offset), str, sz);
*((char*)Data() + offset + sz) = 0;
}
void EQ::Net::Packet::PutPacket(size_t offset, const Packet &p)
{
if (Length() < offset + p.Length()) {
if (!Resize(offset + p.Length())) {
throw std::out_of_range("Packet::PutPacket(), could not resize packet and would of written past the end.");
}
}
memcpy(((char*)Data() + offset), p.Data(), p.Length());
}
void EQ::Net::Packet::PutData(size_t offset, void *data, size_t length)
{
if (Length() < offset + length) {
if (!Resize(offset + length)) {
throw std::out_of_range("Packet::PutData(), could not resize packet and would of written past the end.");
}
}
memcpy(((char*)Data() + offset), data, length);
}
int8_t EQ::Net::Packet::GetInt8(size_t offset) const
{
if (Length() < offset + 1) {
throw std::out_of_range("Packet read out of range.");
}
return *(int8_t*)((char*)Data() + offset);
}
int16_t EQ::Net::Packet::GetInt16(size_t offset) const
{
if (Length() < offset + 2) {
throw std::out_of_range("Packet read out of range.");
}
return *(int16_t*)((char*)Data() + offset);
}
int32_t EQ::Net::Packet::GetInt32(size_t offset) const
{
if (Length() < offset + 4) {
throw std::out_of_range("Packet read out of range.");
}
return *(int32_t*)((char*)Data() + offset);
}
int64_t EQ::Net::Packet::GetInt64(size_t offset) const
{
if (Length() < offset + 8) {
throw std::out_of_range("Packet read out of range.");
}
return *(int64_t*)((char*)Data() + offset);
}
uint8_t EQ::Net::Packet::GetUInt8(size_t offset) const
{
if (Length() < offset + 1) {
throw std::out_of_range("Packet read out of range.");
}
return *(uint8_t*)((char*)Data() + offset);
}
uint16_t EQ::Net::Packet::GetUInt16(size_t offset) const
{
if (Length() < offset + 2) {
throw std::out_of_range("Packet read out of range.");
}
return *(uint16_t*)((char*)Data() + offset);
}
uint32_t EQ::Net::Packet::GetUInt32(size_t offset) const
{
if (Length() < offset + 4) {
throw std::out_of_range("Packet read out of range.");
}
return *(uint32_t*)((char*)Data() + offset);
}
uint64_t EQ::Net::Packet::GetUInt64(size_t offset) const
{
if (Length() < offset + 8) {
throw std::out_of_range("Packet read out of range.");
}
return *(uint64_t*)((char*)Data() + offset);
}
float EQ::Net::Packet::GetFloat(size_t offset) const
{
if (Length() < offset + 4) {
throw std::out_of_range("Packet read out of range.");
}
return *(float*)((char*)Data() + offset);
}
double EQ::Net::Packet::GetDouble(size_t offset) const
{
if (Length() < offset + 8) {
throw std::out_of_range("Packet read out of range.");
}
return *(double*)((char*)Data() + offset);
}
std::string EQ::Net::Packet::GetString(size_t offset, size_t length) const
{
if (Length() < offset + length) {
throw std::out_of_range("Packet read out of range.");
}
return std::string((char*)Data(), (char*)Data() + length);
}
std::string EQ::Net::Packet::GetCString(size_t offset) const
{
if (Length() < offset + 1) {
throw std::out_of_range("Packet read out of range.");
}
char *str = ((char*)Data() + offset);
return std::string(str);
}
char ToSafePrint(unsigned char in) {
if (std::isprint(in)) {
return in;
}
return '.';
}
std::string EQ::Net::Packet::ToString() const
{
return ToString(16);
}
std::string EQ::Net::Packet::ToString(size_t line_length) const
{
std::string ret;
size_t lines = Length() / line_length;
size_t i;
char *data = (char*)Data();
for (i = 0; i < lines; ++i) {
ret += fmt::format("{:0>5x} |", i * line_length);
std::string hex;
std::string ascii;
for (size_t j = 0; j < line_length; ++j) {
hex += fmt::format(" {:0>2x}", (uint8_t)data[(i * line_length) + j]);
ascii += fmt::format("{}", ToSafePrint(data[(i * line_length) + j]));
}
ret += hex;
ret += " | ";
ret += ascii;
ret += "\n";
}
if (Length() % line_length > 0) {
ret += fmt::format("{:0>5x} |", i * line_length);
size_t non_blank_count = Length() % line_length;
size_t blank_count = line_length - non_blank_count;
std::string hex;
std::string ascii;
for (size_t j = 0; j < non_blank_count; ++j) {
hex += fmt::format(" {:0>2x}", (uint8_t)data[(i * line_length) + j]);
ascii += fmt::format("{}", ToSafePrint(data[(i * line_length) + j]));
}
for (size_t j = 0; j < blank_count; ++j) {
hex += " ";
ascii += " ";
}
ret += hex;
ret += " | ";
ret += ascii;
ret += "\n";
}
return ret;
}
-131
View File
@@ -1,131 +0,0 @@
#pragma once
#include <cstdint>
#include <string>
#include <stdexcept>
#include <cstring>
#include "../util/memory_stream.h"
#include <cereal/cereal.hpp>
#include <cereal/archives/binary.hpp>
namespace EQ {
namespace Net {
class Packet
{
public:
Packet() { }
virtual ~Packet() { }
virtual const void *Data() const = 0;
virtual void *Data() = 0;
virtual size_t Length() const = 0;
virtual size_t Length() = 0;
virtual bool Clear() = 0;
virtual bool Resize(size_t new_size) = 0;
virtual void Reserve(size_t new_size) = 0;
template<typename T>
T GetSerialize(size_t offset) const
{
if (T::size() > (Length() - offset)) {
throw std::out_of_range("Packet::GetSerialize(), packet not large enough to cast to type.");
}
T ret;
Util::MemoryStreamReader reader(((char*)Data() + offset), Length());
cereal::BinaryInputArchive input(reader);
input(ret);
return ret;
}
template<typename T>
void PutSerialize(size_t offset, const T &value) {
std::stringstream buffer(std::ios::in | std::ios::out | std::ios::binary);
cereal::BinaryOutputArchive output(buffer);
output(value);
auto str = buffer.str();
if (Length() < offset + str.length()) {
if (!Resize(offset + str.length())) {
throw std::out_of_range("Packet::PutSerialize(), could not resize packet and would of written past the end.");
}
}
memcpy((char*)Data() + offset, &str[0], str.length());
}
void PutInt8(size_t offset, int8_t value);
void PutInt16(size_t offset, int16_t value);
void PutInt32(size_t offset, int32_t value);
void PutInt64(size_t offset, int64_t value);
void PutUInt8(size_t offset, uint8_t value);
void PutUInt16(size_t offset, uint16_t value);
void PutUInt32(size_t offset, uint32_t value);
void PutUInt64(size_t offset, uint64_t value);
void PutFloat(size_t offset, float value);
void PutDouble(size_t offset, double value);
void PutString(size_t offset, const std::string &str);
void PutCString(size_t offset, const char *str);
void PutPacket(size_t offset, const Packet &p);
void PutData(size_t offset, void *data, size_t length);
int8_t GetInt8(size_t offset) const;
int16_t GetInt16(size_t offset) const;
int32_t GetInt32(size_t offset) const;
int64_t GetInt64(size_t offset) const;
uint8_t GetUInt8(size_t offset) const;
uint16_t GetUInt16(size_t offset) const;
uint32_t GetUInt32(size_t offset) const;
uint64_t GetUInt64(size_t offset) const;
float GetFloat(size_t offset) const;
double GetDouble(size_t offset) const;
std::string GetString(size_t offset, size_t length) const;
std::string GetCString(size_t offset) const;
std::string ToString() const;
std::string ToString(size_t line_length) const;
};
class ReadOnlyPacket : public Packet
{
public:
ReadOnlyPacket(void *data, size_t size) { m_data = data; m_data_length = size; }
virtual ~ReadOnlyPacket() { }
ReadOnlyPacket(const ReadOnlyPacket &o) { m_data = o.m_data; m_data_length = o.m_data_length; }
ReadOnlyPacket& operator=(const ReadOnlyPacket &o) { m_data = o.m_data; m_data_length = o.m_data_length; return *this; }
ReadOnlyPacket(ReadOnlyPacket &&o) { m_data = o.m_data; m_data_length = o.m_data_length; }
virtual const void *Data() const { return m_data; }
virtual void *Data() { return m_data; }
virtual size_t Length() const { return m_data_length; }
virtual size_t Length() { return m_data_length; }
virtual bool Clear() { return false; }
virtual bool Resize(size_t new_size) { return false; }
virtual void Reserve(size_t new_size) { }
protected:
void *m_data;
size_t m_data_length;
};
class WritablePacket : public Packet
{
public:
WritablePacket() { }
virtual ~WritablePacket() { }
WritablePacket(WritablePacket &&o) { m_data = std::move(o.m_data); }
WritablePacket(const WritablePacket &o) { m_data = o.m_data; }
WritablePacket& operator=(const WritablePacket &o) { m_data = o.m_data; return *this; }
virtual const void *Data() const { return &m_data[0]; }
virtual void *Data() { return &m_data[0]; }
virtual size_t Length() const { return m_data.size(); }
virtual size_t Length() { return m_data.size(); }
virtual bool Clear() { m_data.clear(); return true; }
virtual bool Resize(size_t new_size) { m_data.resize(new_size); return true; }
virtual void Reserve(size_t new_size) { m_data.reserve(new_size); }
protected:
std::vector<char> m_data;
};
}
}
-17
View File
@@ -1,17 +0,0 @@
#include "chat.h"
EQ::Patches::ChatPatch::ChatPatch()
{
m_opcode_manager.reset(new RegularOpcodeManager());
if (!m_opcode_manager->LoadOpcodes("mail_opcodes.conf")) {
m_opcode_manager.release();
}
m_signature.match_message_opcode = 0x0;
m_signature.match_message_size = 0;
m_message_size = 1;
}
EQ::Patches::ChatPatch::~ChatPatch()
{
}
-15
View File
@@ -1,15 +0,0 @@
#include "../patch/patch.h"
namespace EQ
{
namespace Patches
{
class ChatPatch : public BasePatch
{
public:
ChatPatch();
virtual ~ChatPatch();
virtual std::string GetName() const { return "Chat"; }
};
}
}
-17
View File
@@ -1,17 +0,0 @@
#include "login_sod.h"
EQ::Patches::LoginSoDPatch::LoginSoDPatch()
{
m_opcode_manager.reset(new RegularOpcodeManager());
if (!m_opcode_manager->LoadOpcodes("login_opcodes_sod.conf")) {
m_opcode_manager.release();
}
m_signature.match_message_opcode = 0x01;
m_signature.match_message_size = 0;
m_message_size = 2;
}
EQ::Patches::LoginSoDPatch::~LoginSoDPatch()
{
}
-15
View File
@@ -1,15 +0,0 @@
#include "../patch/patch.h"
namespace EQ
{
namespace Patches
{
class LoginSoDPatch : public BasePatch
{
public:
LoginSoDPatch();
virtual ~LoginSoDPatch();
virtual std::string GetName() const { return "Login SoD+"; }
};
}
}
-17
View File
@@ -1,17 +0,0 @@
#include "login_titanium.h"
EQ::Patches::LoginTitaniumPatch::LoginTitaniumPatch()
{
m_opcode_manager.reset(new RegularOpcodeManager());
if (!m_opcode_manager->LoadOpcodes("login_opcodes.conf")) {
m_opcode_manager.release();
}
m_signature.match_message_opcode = 0x01;
m_signature.match_message_size = 0;
m_message_size = 2;
}
EQ::Patches::LoginTitaniumPatch::~LoginTitaniumPatch()
{
}
-15
View File
@@ -1,15 +0,0 @@
#include "../patch/patch.h"
namespace EQ
{
namespace Patches
{
class LoginTitaniumPatch : public BasePatch
{
public:
LoginTitaniumPatch();
virtual ~LoginTitaniumPatch();
virtual std::string GetName() const { return "Login Titanium"; }
};
}
}
-107
View File
@@ -1,107 +0,0 @@
#include "patch.h"
#include "../eqemu_logsys.h"
EQ::Patches::IdentityMatchStatus EQ::Patches::BasePatch::TryIdentityMatch(const EQ::Net::Packet &p) const
{
if (p.Length() < m_message_size) {
return IdentityMatchFailure;
}
int raw_opcode = 0;
switch (m_message_size) {
case 1:
raw_opcode = *(uint8_t*)p.Data();
break;
case 2:
raw_opcode = *(uint16_t*)p.Data();
break;
default:
return IdentityMatchFailure;
}
if (m_signature.match_message_opcode != 0 && m_signature.match_message_opcode != raw_opcode) {
return IdentityMatchFailure;
}
if (m_signature.match_message_size > 0 && m_signature.match_message_size != p.Length() - m_message_size) {
return IdentityMatchFailure;
}
return IdentityMatchSuccess;
}
void EQ::Patches::BasePatch::Decode(const EQ::Net::Packet *in, EmuOpcode &opcode, EQ::Net::WritablePacket &out)
{
int raw_opcode = 0;
switch (m_message_size) {
case 1:
raw_opcode = *(uint8_t*)in->Data();
break;
case 2:
raw_opcode = *(uint16_t*)in->Data();
break;
default:
opcode = OP_Unknown;
return;
}
opcode = m_opcode_manager->EQToEmu(raw_opcode);
if (opcode == OP_Unknown) {
out.PutData(0, (uint8_t*)in->Data() + m_message_size, in->Length() - m_message_size);
return;
}
auto decode_iter = m_decode.find(opcode);
if (decode_iter != m_decode.end()) {
EQ::Net::ReadOnlyPacket p((uint8_t*)in->Data() + m_message_size, in->Length() - m_message_size);
decode_iter->second(&p, opcode, out);
}
else {
out.PutData(0, (uint8_t*)in->Data() + m_message_size, in->Length() - m_message_size);
}
}
void EQ::Patches::BasePatch::Encode(std::shared_ptr<EQ::Net::DaybreakConnection> connection, EmuOpcode opcode, const EQ::Net::Packet *in)
{
auto encode_iter = m_encode.find(opcode);
if (encode_iter != m_encode.end()) {
encode_iter->second(connection, opcode, in);
}
else {
SendPacket(connection, opcode, in);
}
}
void EQ::Patches::BasePatch::RegisterDecode(int protocol_number, DecodeStructFunction f)
{
m_decode.insert(std::make_pair(protocol_number, f));
}
void EQ::Patches::BasePatch::RegisterEncode(EmuOpcode opcode, EncodeStructFunction f)
{
m_encode.insert(std::make_pair(opcode, f));
}
void EQ::Patches::BasePatch::SendPacket(std::shared_ptr<EQ::Net::DaybreakConnection> connection, EmuOpcode opcode, const EQ::Net::Packet *p)
{
if (!m_opcode_manager) {
return;
}
auto raw_opcode = m_opcode_manager->EmuToEQ(opcode);
EQ::Net::WritablePacket out;
switch (m_message_size) {
case 1:
out.PutUInt8(0, (uint8_t)raw_opcode);
out.PutPacket(1, *p);
break;
case 2:
out.PutUInt16(0, raw_opcode);
out.PutPacket(2, *p);
break;
default:
return;
}
connection->QueuePacket(out);
}
-53
View File
@@ -1,53 +0,0 @@
#pragma once
#include "../opcodemgr.h"
#include "../net/packet.h"
#include "../net/daybreak_connection.h"
#include <functional>
#include <memory>
#include <map>
namespace EQ
{
namespace Patches
{
enum IdentityMatchStatus
{
IdentityMatchFailure,
IdentityMatchSuccess
};
struct Signature
{
int match_message_opcode;
size_t match_message_size;
};
class BasePatch
{
public:
typedef std::function<void(const EQ::Net::Packet*, EmuOpcode, EQ::Net::WritablePacket&)> DecodeStructFunction;
typedef std::function<void(std::shared_ptr<EQ::Net::DaybreakConnection>, EmuOpcode, const EQ::Net::Packet*)> EncodeStructFunction;
BasePatch() { }
virtual ~BasePatch() { }
virtual std::string GetName() const = 0;
IdentityMatchStatus TryIdentityMatch(const EQ::Net::Packet &p) const;
void Decode(const EQ::Net::Packet *in, EmuOpcode& opcode, EQ::Net::WritablePacket& out);
void Encode(std::shared_ptr<EQ::Net::DaybreakConnection> connection, EmuOpcode opcode, const EQ::Net::Packet *in);
void RegisterDecode(int protocol_number, DecodeStructFunction f);
void RegisterEncode(EmuOpcode opcode, EncodeStructFunction f);
protected:
void SendPacket(std::shared_ptr<EQ::Net::DaybreakConnection> connection, EmuOpcode opcode, const EQ::Net::Packet *p);
std::unique_ptr<OpcodeManager> m_opcode_manager;
std::map<int, DecodeStructFunction> m_decode;
std::map<EmuOpcode, EncodeStructFunction> m_encode;
Signature m_signature;
int m_message_size;
};
}
}
View File
View File
View File
File diff suppressed because it is too large Load Diff
+98 -94
View File
@@ -29,7 +29,7 @@
#include "../eq_packet_structs.h"
#include "../misc_functions.h"
#include "../string_util.h"
#include "../item.h"
#include "../inventory_profile.h"
#include "rof_structs.h"
#include "../rulesys.h"
@@ -45,7 +45,7 @@ namespace RoF
static OpcodeManager *opcodes = nullptr;
static Strategy struct_strategy;
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id, uint8 depth);
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id, uint8 depth);
// server to client inventory location converters
static inline structs::InventorySlot_Struct ServerToRoFSlot(uint32 serverSlot);
@@ -66,6 +66,9 @@ namespace RoF
static inline CastingSlot ServerToRoFCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot RoFToServerCastingSlot(CastingSlot slot);
static inline int ServerToRoFBuffSlot(int index);
static inline int RoFToServerBuffSlot(int index);
void Register(EQStreamIdentifier &into)
{
//create our opcode manager if we havent already
@@ -423,15 +426,8 @@ namespace RoF
OUT(buff.y);
OUT(buff.x);
OUT(buff.z);
uint16 buffslot = emu->slotid;
// Not sure if this is needs amending for RoF yet.
if (buffslot >= 25)
{
buffslot += 17;
}
// TODO: implement slot_data stuff
eq->slotid = buffslot;
eq->slotid = ServerToRoFBuffSlot(emu->slotid);
if (emu->bufffade == 1)
eq->bufffade = 1;
@@ -447,10 +443,10 @@ namespace RoF
outapp->WriteUInt32(0); // tic timer
outapp->WriteUInt8(0); // Type of OP_BuffCreate packet ?
outapp->WriteUInt16(1); // 1 buff in this packet
outapp->WriteUInt32(buffslot);
outapp->WriteUInt32(eq->slotid);
outapp->WriteUInt32(0xffffffff); // SpellID (0xffff to remove)
outapp->WriteUInt32(0); // Duration
outapp->WriteUInt32(0); // ?
outapp->WriteUInt32(0); // numhits
outapp->WriteUInt8(0); // Caster name
outapp->WriteUInt8(0); // Type
}
@@ -474,17 +470,9 @@ namespace RoF
__packet->WriteUInt8(emu->all_buffs); // 1 indicates all buffs on the player (0 to add or remove a single buff)
__packet->WriteUInt16(emu->count);
for (uint16 i = 0; i < emu->count; ++i)
for (int i = 0; i < emu->count; ++i)
{
uint16 buffslot = emu->entries[i].buff_slot;
if (emu->type == 0) { // only correct for self packets
if (emu->entries[i].buff_slot >= 25)
buffslot += 17;
if (buffslot == 54)
buffslot = 62;
}
__packet->WriteUInt32(buffslot);
__packet->WriteUInt32(emu->type == 0 ? ServerToRoFBuffSlot(emu->entries[i].buff_slot) : emu->entries[i].buff_slot);
__packet->WriteUInt32(emu->entries[i].spell_id);
__packet->WriteUInt32(emu->entries[i].tics_remaining);
__packet->WriteUInt32(emu->entries[i].num_hits); // Unknown
@@ -596,7 +584,7 @@ namespace RoF
ob.write((const char*)&item_count, sizeof(uint32));
for (int index = 0; index < item_count; ++index, ++eq) {
SerializeItem(ob, (const ItemInst*)eq->inst, eq->slot_id, 0);
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0);
if (ob.tellp() == last_pos)
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
@@ -1504,17 +1492,6 @@ namespace RoF
FINISH_ENCODE();
}
ENCODE(OP_InterruptCast)
{
ENCODE_LENGTH_EXACT(InterruptCast_Struct);
SETUP_DIRECT_ENCODE(InterruptCast_Struct, structs::InterruptCast_Struct);
OUT(spawnid);
OUT(messageid);
FINISH_ENCODE();
}
ENCODE(OP_ItemLinkResponse) { ENCODE_FORWARD(OP_ItemPacket); }
ENCODE(OP_ItemPacket)
@@ -1533,7 +1510,7 @@ namespace RoF
ob.write((const char*)__emu_buffer, 4);
SerializeItem(ob, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0);
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0);
if (ob.tellp() == last_pos) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
delete in;
@@ -2079,7 +2056,7 @@ namespace RoF
outapp->WriteUInt32(22); // Equipment count
for (int r = EQEmu::textures::TextureBegin; r < EQEmu::textures::TextureCount; r++)
for (int r = EQEmu::textures::textureBegin; r < EQEmu::textures::materialCount; r++)
{
outapp->WriteUInt32(emu->item_material.Slot[r].Material);
outapp->WriteUInt32(0);
@@ -2099,9 +2076,9 @@ namespace RoF
outapp->WriteUInt32(0);
}
outapp->WriteUInt32(EQEmu::textures::TextureCount); // Equipment2 count
outapp->WriteUInt32(EQEmu::textures::materialCount); // Equipment2 count
for (int r = EQEmu::textures::TextureBegin; r < EQEmu::textures::TextureCount; r++)
for (int r = EQEmu::textures::textureBegin; r < EQEmu::textures::materialCount; r++)
{
outapp->WriteUInt32(0);
outapp->WriteUInt32(0);
@@ -2110,7 +2087,7 @@ namespace RoF
outapp->WriteUInt32(0);
}
outapp->WriteUInt32(EQEmu::textures::TextureCount); // Tint Count
outapp->WriteUInt32(EQEmu::textures::materialCount); // Tint Count
for (int r = 0; r < 7; r++)
{
@@ -2120,7 +2097,7 @@ namespace RoF
outapp->WriteUInt32(0);
outapp->WriteUInt32(0);
outapp->WriteUInt32(EQEmu::textures::TextureCount); // Tint2 Count
outapp->WriteUInt32(EQEmu::textures::materialCount); // Tint2 Count
for (int r = 0; r < 7; r++)
{
@@ -3059,12 +3036,12 @@ namespace RoF
eq_cse->Gender = emu_cse->Gender;
eq_cse->Face = emu_cse->Face;
for (int equip_index = 0; equip_index < EQEmu::textures::TextureCount; equip_index++) {
for (int equip_index = 0; equip_index < EQEmu::textures::materialCount; equip_index++) {
eq_cse->Equip[equip_index].Material = emu_cse->Equip[equip_index].Material;
eq_cse->Equip[equip_index].Unknown1 = emu_cse->Equip[equip_index].Unknown1;
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteMaterial;
eq_cse->Equip[equip_index].HeroForgeModel = emu_cse->Equip[equip_index].HeroForgeModel;
eq_cse->Equip[equip_index].Material2 = emu_cse->Equip[equip_index].Material2;
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteModel;
eq_cse->Equip[equip_index].HeroForgeModel = emu_cse->Equip[equip_index].HerosForgeModel;
eq_cse->Equip[equip_index].Material2 = emu_cse->Equip[equip_index].Unknown2;
eq_cse->Equip[equip_index].Color = emu_cse->Equip[equip_index].Color;
}
@@ -4096,7 +4073,7 @@ namespace RoF
if ((emu->NPC == 0) || (emu->race <= 12) || (emu->race == 128) || (emu->race == 130) || (emu->race == 330) || (emu->race == 522))
{
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; ++k)
for (k = EQEmu::textures::textureBegin; k < EQEmu::textures::materialCount; ++k)
{
{
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment_tint.Slot[k].Color);
@@ -4105,15 +4082,15 @@ namespace RoF
structs::Texture_Struct *Equipment = (structs::Texture_Struct *)Buffer;
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; k++) {
for (k = EQEmu::textures::textureBegin; k < EQEmu::textures::materialCount; k++) {
Equipment[k].Material = emu->equipment.Slot[k].Material;
Equipment[k].Unknown1 = emu->equipment.Slot[k].Unknown1;
Equipment[k].EliteMaterial = emu->equipment.Slot[k].EliteMaterial;
Equipment[k].HeroForgeModel = emu->equipment.Slot[k].HeroForgeModel;
Equipment[k].Material2 = emu->equipment.Slot[k].Material2;
Equipment[k].EliteMaterial = emu->equipment.Slot[k].EliteModel;
Equipment[k].HeroForgeModel = emu->equipment.Slot[k].HerosForgeModel;
Equipment[k].Material2 = emu->equipment.Slot[k].Unknown2;
}
Buffer += (sizeof(structs::Texture_Struct) * EQEmu::textures::TextureCount);
Buffer += (sizeof(structs::Texture_Struct) * EQEmu::textures::materialCount);
}
else
{
@@ -4312,7 +4289,7 @@ namespace RoF
IN(buff.unknown003);
IN(buff.spellid);
IN(buff.duration);
IN(slotid);
emu->slotid = RoFToServerBuffSlot(eq->slotid);
IN(bufffade);
FINISH_DIRECT_DECODE();
@@ -4325,7 +4302,7 @@ namespace RoF
DECODE_LENGTH_EXACT(structs::BuffRemoveRequest_Struct);
SETUP_DIRECT_DECODE(BuffRemoveRequest_Struct, structs::BuffRemoveRequest_Struct);
emu->SlotID = (eq->SlotID < 42) ? eq->SlotID : (eq->SlotID - 17);
emu->SlotID = RoFToServerBuffSlot(eq->SlotID);
IN(EntityID);
@@ -4829,10 +4806,9 @@ namespace RoF
IN(item_id);
int r;
for (r = 0; r < EQEmu::legacy::ITEM_COMMON_SIZE; r++) {
for (r = EQEmu::inventory::socketBegin; r < EQEmu::inventory::SocketCount; r++) {
IN(augments[r]);
}
// Max Augs is now 6, but no code to support that many yet
IN(link_hash);
IN(icon);
@@ -5209,9 +5185,9 @@ namespace RoF
return NextItemInstSerialNumber;
}
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth)
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id_in, uint8 depth)
{
const EQEmu::ItemBase *item = inst->GetUnscaledItem();
const EQEmu::ItemData *item = inst->GetUnscaledItem();
RoF::structs::ItemSerializationHeader hdr;
@@ -5265,7 +5241,7 @@ namespace RoF
if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon()) {
ornaIcon = inst->GetOrnamentationIcon();
heroModel = inst->GetOrnamentHeroModel(Inventory::CalcMaterialFromSlot(slot_id_in));
heroModel = inst->GetOrnamentHeroModel(EQEmu::InventoryProfile::CalcMaterialFromSlot(slot_id_in));
char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile());
@@ -5622,18 +5598,18 @@ namespace RoF
ob.write((const char*)&subitem_count, sizeof(uint32));
for (uint32 index = SUB_INDEX_BEGIN; index < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++index) {
ItemInst* sub = inst->GetItem(index);
for (uint32 index = EQEmu::inventory::containerBegin; index < EQEmu::inventory::ContainerCount; ++index) {
EQEmu::ItemInstance* sub = inst->GetItem(index);
if (!sub)
continue;
int SubSlotNumber = INVALID_INDEX;
if (slot_id_in >= EQEmu::legacy::GENERAL_BEGIN && slot_id_in <= EQEmu::legacy::GENERAL_END)
SubSlotNumber = (((slot_id_in + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + index + 1);
SubSlotNumber = (((slot_id_in + 3) * EQEmu::inventory::ContainerCount) + index + 1);
else if (slot_id_in >= EQEmu::legacy::BANK_BEGIN && slot_id_in <= EQEmu::legacy::BANK_END)
SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::BANK_BAGS_BEGIN + index);
SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::BANK_BAGS_BEGIN + index);
else if (slot_id_in >= EQEmu::legacy::SHARED_BANK_BEGIN && slot_id_in <= EQEmu::legacy::SHARED_BANK_END)
SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index);
SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index);
else
SubSlotNumber = slot_id_in;
@@ -5659,17 +5635,17 @@ namespace RoF
uint32 TempSlot = 0;
if (serverSlot < 56 || serverSlot == EQEmu::legacy::SlotPowerSource) { // Main Inventory and Cursor
if (serverSlot < 56 || serverSlot == EQEmu::inventory::slotPowerSource) { // Main Inventory and Cursor
RoFSlot.Type = invtype::InvTypePossessions;
RoFSlot.Slot = serverSlot;
if (serverSlot == EQEmu::legacy::SlotPowerSource)
if (serverSlot == EQEmu::inventory::slotPowerSource)
RoFSlot.Slot = invslot::PossessionsPowerSource;
else if (serverSlot >= EQEmu::legacy::SlotCursor) // Cursor and Extended Corpse Inventory
else if (serverSlot >= EQEmu::inventory::slotCursor) // Cursor and Extended Corpse Inventory
RoFSlot.Slot += 3;
else if (serverSlot >= EQEmu::legacy::SlotAmmo) // (> 20)
else if (serverSlot >= EQEmu::inventory::slotAmmo) // (> 20)
RoFSlot.Slot += 1;
}
@@ -5681,8 +5657,8 @@ namespace RoF
else if (serverSlot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::legacy::CURSOR_BAG_END) { // (> 250 && < 341)
RoFSlot.Type = invtype::InvTypePossessions;
TempSlot = serverSlot - 1;
RoFSlot.Slot = int(TempSlot / EQEmu::legacy::ITEM_CONTAINER_SIZE) - 2;
RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 2) * EQEmu::legacy::ITEM_CONTAINER_SIZE);
RoFSlot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 2;
RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 2) * EQEmu::inventory::ContainerCount);
if (RoFSlot.Slot >= invslot::PossessionsGeneral9) // (> 30)
RoFSlot.Slot = invslot::PossessionsCursor;
@@ -5699,8 +5675,8 @@ namespace RoF
RoFSlot.Slot = TempSlot;
if (TempSlot > 30) { // (> 30)
RoFSlot.Slot = int(TempSlot / EQEmu::legacy::ITEM_CONTAINER_SIZE) - 3;
RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE);
RoFSlot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 3;
RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 3) * EQEmu::inventory::ContainerCount);
}
}
@@ -5710,8 +5686,8 @@ namespace RoF
RoFSlot.Slot = TempSlot;
if (TempSlot > 30) { // (> 30)
RoFSlot.Slot = int(TempSlot / EQEmu::legacy::ITEM_CONTAINER_SIZE) - 3;
RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE);
RoFSlot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 3;
RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 3) * EQEmu::inventory::ContainerCount);
}
}
@@ -5721,8 +5697,8 @@ namespace RoF
RoFSlot.Slot = TempSlot;
if (TempSlot > 30) {
RoFSlot.Slot = int(TempSlot / EQEmu::legacy::ITEM_CONTAINER_SIZE) - 3;
RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE);
RoFSlot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 3;
RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 3) * EQEmu::inventory::ContainerCount);
}
/*
@@ -5760,16 +5736,16 @@ namespace RoF
uint32 TempSlot = 0;
if (serverSlot < 56 || serverSlot == EQEmu::legacy::SlotPowerSource) { // (< 52)
if (serverSlot < 56 || serverSlot == EQEmu::inventory::slotPowerSource) { // (< 52)
RoFSlot.Slot = serverSlot;
if (serverSlot == EQEmu::legacy::SlotPowerSource)
if (serverSlot == EQEmu::inventory::slotPowerSource)
RoFSlot.Slot = invslot::PossessionsPowerSource;
else if (serverSlot >= EQEmu::legacy::SlotCursor) // Cursor and Extended Corpse Inventory
else if (serverSlot >= EQEmu::inventory::slotCursor) // Cursor and Extended Corpse Inventory
RoFSlot.Slot += 3;
else if (serverSlot >= EQEmu::legacy::SlotAmmo) // Ammo and Personl Inventory
else if (serverSlot >= EQEmu::inventory::slotAmmo) // Ammo and Personl Inventory
RoFSlot.Slot += 1;
/*else if (ServerSlot >= MainCursor) { // Cursor
@@ -5782,8 +5758,8 @@ namespace RoF
else if (serverSlot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::legacy::CURSOR_BAG_END) {
TempSlot = serverSlot - 1;
RoFSlot.Slot = int(TempSlot / EQEmu::legacy::ITEM_CONTAINER_SIZE) - 2;
RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 2) * EQEmu::legacy::ITEM_CONTAINER_SIZE);
RoFSlot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 2;
RoFSlot.SubIndex = TempSlot - ((RoFSlot.Slot + 2) * EQEmu::inventory::ContainerCount);
}
Log.Out(Logs::General, Logs::Netcode, "[ERROR] Convert Server Slot %i to RoF Slots: Main %i, Sub %i, Aug %i, Unk1 %i", serverSlot, RoFSlot.Slot, RoFSlot.SubIndex, RoFSlot.AugIndex, RoFSlot.Unknown01);
@@ -5803,7 +5779,7 @@ namespace RoF
if (rofSlot.Type == invtype::InvTypePossessions && rofSlot.Slot < 57) { // Worn/Personal Inventory and Cursor (< 51)
if (rofSlot.Slot == invslot::PossessionsPowerSource)
TempSlot = EQEmu::legacy::SlotPowerSource;
TempSlot = EQEmu::inventory::slotPowerSource;
else if (rofSlot.Slot >= invslot::PossessionsCursor) // Cursor and Extended Corpse Inventory
TempSlot = rofSlot.Slot - 3;
@@ -5825,8 +5801,8 @@ namespace RoF
else // Worn Slots
TempSlot = rofSlot.Slot;
if (rofSlot.SubIndex >= SUB_INDEX_BEGIN) // Bag Slots
TempSlot = ((TempSlot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + rofSlot.SubIndex + 1;
if (rofSlot.SubIndex >= EQEmu::inventory::containerBegin) // Bag Slots
TempSlot = ((TempSlot + 3) * EQEmu::inventory::ContainerCount) + rofSlot.SubIndex + 1;
ServerSlot = TempSlot;
}
@@ -5834,8 +5810,8 @@ namespace RoF
else if (rofSlot.Type == invtype::InvTypeBank) {
TempSlot = EQEmu::legacy::BANK_BEGIN;
if (rofSlot.SubIndex >= SUB_INDEX_BEGIN)
TempSlot += ((rofSlot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + rofSlot.SubIndex + 1;
if (rofSlot.SubIndex >= EQEmu::inventory::containerBegin)
TempSlot += ((rofSlot.Slot + 3) * EQEmu::inventory::ContainerCount) + rofSlot.SubIndex + 1;
else
TempSlot += rofSlot.Slot;
@@ -5846,8 +5822,8 @@ namespace RoF
else if (rofSlot.Type == invtype::InvTypeSharedBank) {
TempSlot = EQEmu::legacy::SHARED_BANK_BEGIN;
if (rofSlot.SubIndex >= SUB_INDEX_BEGIN)
TempSlot += ((rofSlot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + rofSlot.SubIndex + 1;
if (rofSlot.SubIndex >= EQEmu::inventory::containerBegin)
TempSlot += ((rofSlot.Slot + 3) * EQEmu::inventory::ContainerCount) + rofSlot.SubIndex + 1;
else
TempSlot += rofSlot.Slot;
@@ -5858,10 +5834,10 @@ namespace RoF
else if (rofSlot.Type == invtype::InvTypeTrade) {
TempSlot = EQEmu::legacy::TRADE_BEGIN;
if (rofSlot.SubIndex >= SUB_INDEX_BEGIN)
TempSlot += ((rofSlot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + rofSlot.SubIndex + 1;
if (rofSlot.SubIndex >= EQEmu::inventory::containerBegin)
TempSlot += ((rofSlot.Slot + 3) * EQEmu::inventory::ContainerCount) + rofSlot.SubIndex + 1;
// OLD CODE:
//TempSlot += 100 + (RoFSlot.MainSlot * EQEmu::legacy::ITEM_CONTAINER_SIZE) + RoFSlot.SubSlot;
//TempSlot += 100 + (RoFSlot.MainSlot * EQEmu::inventory::ContainerCount) + RoFSlot.SubSlot;
else
TempSlot += rofSlot.Slot;
@@ -5872,7 +5848,7 @@ namespace RoF
else if (rofSlot.Type == invtype::InvTypeWorld) {
TempSlot = EQEmu::legacy::WORLD_BEGIN;
if (rofSlot.Slot >= SUB_INDEX_BEGIN)
if (rofSlot.Slot >= EQEmu::inventory::containerBegin)
TempSlot += rofSlot.Slot;
ServerSlot = TempSlot;
@@ -5903,7 +5879,7 @@ namespace RoF
if (rofSlot.Slot < 57) { // Worn/Personal Inventory and Cursor (< 33)
if (rofSlot.Slot == invslot::PossessionsPowerSource)
TempSlot = EQEmu::legacy::SlotPowerSource;
TempSlot = EQEmu::inventory::slotPowerSource;
else if (rofSlot.Slot >= invslot::PossessionsCursor) // Cursor and Extended Corpse Inventory
TempSlot = rofSlot.Slot - 3;
@@ -5920,8 +5896,8 @@ namespace RoF
else
TempSlot = rofSlot.Slot;
if (rofSlot.SubIndex >= SUB_INDEX_BEGIN) // Bag Slots
TempSlot = ((TempSlot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + rofSlot.SubIndex + 1;
if (rofSlot.SubIndex >= EQEmu::inventory::containerBegin) // Bag Slots
TempSlot = ((TempSlot + 3) * EQEmu::inventory::ContainerCount) + rofSlot.SubIndex + 1;
ServerSlot = TempSlot;
}
@@ -6085,4 +6061,32 @@ namespace RoF
return EQEmu::CastingSlot::Discipline;
}
}
// these should be optimized out for RoF since they should all boil down to return index :P
// but lets leave it here for future proofing
static inline int ServerToRoFBuffSlot(int index)
{
// we're a disc
if (index >= EQEmu::constants::LongBuffs + EQEmu::constants::ShortBuffs)
return index - EQEmu::constants::LongBuffs - EQEmu::constants::ShortBuffs +
constants::LongBuffs + constants::ShortBuffs;
// we're a song
if (index >= EQEmu::constants::LongBuffs)
return index - EQEmu::constants::LongBuffs + constants::LongBuffs;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}
static inline int RoFToServerBuffSlot(int index)
{
// we're a disc
if (index >= constants::LongBuffs + constants::ShortBuffs)
return index - constants::LongBuffs - constants::ShortBuffs + EQEmu::constants::LongBuffs +
EQEmu::constants::ShortBuffs;
// we're a song
if (index >= constants::LongBuffs)
return index - constants::LongBuffs + EQEmu::constants::LongBuffs;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}
} /*RoF*/
+118 -119
View File
@@ -29,7 +29,7 @@
#include "../eq_packet_structs.h"
#include "../misc_functions.h"
#include "../string_util.h"
#include "../item.h"
#include "../inventory_profile.h"
#include "rof2_structs.h"
#include "../rulesys.h"
@@ -45,7 +45,7 @@ namespace RoF2
static OpcodeManager *opcodes = nullptr;
static Strategy struct_strategy;
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id, uint8 depth, ItemPacketType packet_type);
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id, uint8 depth, ItemPacketType packet_type);
// server to client inventory location converters
static inline structs::InventorySlot_Struct ServerToRoF2Slot(uint32 serverSlot, ItemPacketType PacketType = ItemPacketInvalid);
@@ -66,6 +66,9 @@ namespace RoF2
static inline CastingSlot ServerToRoF2CastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot RoF2ToServerCastingSlot(CastingSlot slot);
static inline int ServerToRoF2BuffSlot(int index);
static inline int RoF2ToServerBuffSlot(int index);
void Register(EQStreamIdentifier &into)
{
//create our opcode manager if we havent already
@@ -492,18 +495,7 @@ namespace RoF2
OUT(buff.y);
OUT(buff.x);
OUT(buff.z);
uint16 buffslot = emu->slotid;
// Not sure if this is needs amending for RoF2 yet.
if (buffslot >= 25)
{
buffslot += 17;
}
// TODO: We should really just deal with these "server side"
// so we can have clients not limited to other clients.
// This fixes discs, songs were changed to 20
if (buffslot == 54)
buffslot = 62;
eq->slotid = buffslot;
eq->slotid = ServerToRoF2BuffSlot(emu->slotid);
// TODO: implement slot_data stuff
if (emu->bufffade == 1)
eq->bufffade = 1;
@@ -519,10 +511,10 @@ namespace RoF2
outapp->WriteUInt32(0); // tic timer
outapp->WriteUInt8(0); // Type of OP_BuffCreate packet ?
outapp->WriteUInt16(1); // 1 buff in this packet
outapp->WriteUInt32(buffslot);
outapp->WriteUInt32(eq->slotid);
outapp->WriteUInt32(0xffffffff); // SpellID (0xffff to remove)
outapp->WriteUInt32(0); // Duration
outapp->WriteUInt32(0); // ?
outapp->WriteUInt32(0); // numhits
outapp->WriteUInt8(0); // Caster name
outapp->WriteUInt8(0); // Type
}
@@ -546,20 +538,9 @@ namespace RoF2
__packet->WriteUInt8(emu->all_buffs); // 1 indicates all buffs on the player (0 to add or remove a single buff)
__packet->WriteUInt16(emu->count);
for (uint16 i = 0; i < emu->count; ++i)
for (int i = 0; i < emu->count; ++i)
{
uint16 buffslot = emu->entries[i].buff_slot;
if (emu->type == 0) { // only correct for self packets
if (emu->entries[i].buff_slot >= 25)
buffslot += 17;
// TODO: We should really just deal with these "server side"
// so we can have clients not limited to other clients.
// This fixes discs, songs were changed to 20
if (buffslot == 54)
buffslot = 62;
}
__packet->WriteUInt32(buffslot);
__packet->WriteUInt32(emu->type == 0 ? ServerToRoF2BuffSlot(emu->entries[i].buff_slot) : emu->entries[i].buff_slot);
__packet->WriteUInt32(emu->entries[i].spell_id);
__packet->WriteUInt32(emu->entries[i].tics_remaining);
__packet->WriteUInt32(emu->entries[i].num_hits); // Unknown
@@ -671,7 +652,7 @@ namespace RoF2
ob.write((const char*)&item_count, sizeof(uint32));
for (int index = 0; index < item_count; ++index, ++eq) {
SerializeItem(ob, (const ItemInst*)eq->inst, eq->slot_id, 0, ItemPacketCharInventory);
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0, ItemPacketCharInventory);
if (ob.tellp() == last_pos)
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
@@ -1201,17 +1182,17 @@ namespace RoF2
// Leader
//
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_STRING(Buffer, gu2->yourname);
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // index
VARSTRUCT_ENCODE_STRING(Buffer, gu2->yourname); // name
VARSTRUCT_ENCODE_TYPE(uint16, Buffer, 0); // owner name of merc
//VARSTRUCT_ENCODE_STRING(Buffer, "");
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // This is a string
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0x46); // Observed 0x41 and 0x46 here
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint16, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // This is a string
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0x46); // level
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group tank flag
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group assist flag
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group puller flag
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // offline
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // timestamp
int MemberNumber = 1;
@@ -1220,17 +1201,17 @@ namespace RoF2
if (gu2->membername[i][0] == '\0')
continue;
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, MemberNumber++);
VARSTRUCT_ENCODE_STRING(Buffer, gu2->membername[i]);
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, MemberNumber++); // index
VARSTRUCT_ENCODE_STRING(Buffer, gu2->membername[i]); // name
VARSTRUCT_ENCODE_TYPE(uint16, Buffer, 0); // merc flag
//VARSTRUCT_ENCODE_STRING(Buffer, "");
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // This is a string
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0x41); // Observed 0x41 and 0x46 here
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // Low byte is Main Assist Flag
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint16, Buffer, 0);
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // owner name fo merc
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0x41); // level
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group tank flag
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group assist flag
VARSTRUCT_ENCODE_TYPE(uint8, Buffer, 0); // group puller flag
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // offline
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, 0); // timestamp
}
//Log.Hex(Logs::Netcode, outapp->pBuffer, outapp->size);
@@ -1579,17 +1560,6 @@ namespace RoF2
FINISH_ENCODE();
}
ENCODE(OP_InterruptCast)
{
ENCODE_LENGTH_EXACT(InterruptCast_Struct);
SETUP_DIRECT_ENCODE(InterruptCast_Struct, structs::InterruptCast_Struct);
OUT(spawnid);
OUT(messageid);
FINISH_ENCODE();
}
ENCODE(OP_ItemLinkResponse) { ENCODE_FORWARD(OP_ItemPacket); }
ENCODE(OP_ItemPacket)
@@ -1609,7 +1579,7 @@ namespace RoF2
ob.write((const char*)__emu_buffer, 4);
SerializeItem(ob, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0, old_item_pkt->PacketType);
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0, old_item_pkt->PacketType);
if (ob.tellp() == last_pos) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
delete in;
@@ -2164,7 +2134,7 @@ namespace RoF2
outapp->WriteUInt32(22); // Equipment count
for (int r = EQEmu::textures::TextureBegin; r < EQEmu::textures::TextureCount; r++)
for (int r = EQEmu::textures::textureBegin; r < EQEmu::textures::materialCount; r++)
{
outapp->WriteUInt32(emu->item_material.Slot[r].Material);
outapp->WriteUInt32(0);
@@ -2184,9 +2154,9 @@ namespace RoF2
outapp->WriteUInt32(0);
}
outapp->WriteUInt32(EQEmu::textures::TextureCount); // Equipment2 count
outapp->WriteUInt32(EQEmu::textures::materialCount); // Equipment2 count
for (int r = EQEmu::textures::TextureBegin; r < EQEmu::textures::TextureCount; r++)
for (int r = EQEmu::textures::textureBegin; r < EQEmu::textures::materialCount; r++)
{
outapp->WriteUInt32(0);
outapp->WriteUInt32(0);
@@ -2195,7 +2165,7 @@ namespace RoF2
outapp->WriteUInt32(0);
}
outapp->WriteUInt32(EQEmu::textures::TextureCount); // Tint Count
outapp->WriteUInt32(EQEmu::textures::materialCount); // Tint Count
for (int r = 0; r < 7; r++)
{
@@ -2205,7 +2175,7 @@ namespace RoF2
outapp->WriteUInt32(0);
outapp->WriteUInt32(0);
outapp->WriteUInt32(EQEmu::textures::TextureCount); // Tint2 Count
outapp->WriteUInt32(EQEmu::textures::materialCount); // Tint2 Count
for (int r = 0; r < 7; r++)
{
@@ -3154,12 +3124,12 @@ namespace RoF2
eq_cse->Gender = emu_cse->Gender;
eq_cse->Face = emu_cse->Face;
for (int equip_index = 0; equip_index < EQEmu::textures::TextureCount; equip_index++) {
for (int equip_index = 0; equip_index < EQEmu::textures::materialCount; equip_index++) {
eq_cse->Equip[equip_index].Material = emu_cse->Equip[equip_index].Material;
eq_cse->Equip[equip_index].Unknown1 = emu_cse->Equip[equip_index].Unknown1;
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteMaterial;
eq_cse->Equip[equip_index].HeroForgeModel = emu_cse->Equip[equip_index].HeroForgeModel;
eq_cse->Equip[equip_index].Material2 = emu_cse->Equip[equip_index].Material2;
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteModel;
eq_cse->Equip[equip_index].HeroForgeModel = emu_cse->Equip[equip_index].HerosForgeModel;
eq_cse->Equip[equip_index].Material2 = emu_cse->Equip[equip_index].Unknown2;
eq_cse->Equip[equip_index].Color = emu_cse->Equip[equip_index].Color;
}
@@ -4321,7 +4291,7 @@ namespace RoF2
if ((emu->NPC == 0) || (emu->race <= 12) || (emu->race == 128) || (emu->race == 130) || (emu->race == 330) || (emu->race == 522))
{
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; ++k)
for (k = EQEmu::textures::textureBegin; k < EQEmu::textures::materialCount; ++k)
{
{
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment_tint.Slot[k].Color);
@@ -4330,15 +4300,15 @@ namespace RoF2
structs::Texture_Struct *Equipment = (structs::Texture_Struct *)Buffer;
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; k++) {
for (k = EQEmu::textures::textureBegin; k < EQEmu::textures::materialCount; k++) {
Equipment[k].Material = emu->equipment.Slot[k].Material;
Equipment[k].Unknown1 = emu->equipment.Slot[k].Unknown1;
Equipment[k].EliteMaterial = emu->equipment.Slot[k].EliteMaterial;
Equipment[k].HeroForgeModel = emu->equipment.Slot[k].HeroForgeModel;
Equipment[k].Material2 = emu->equipment.Slot[k].Material2;
Equipment[k].EliteMaterial = emu->equipment.Slot[k].EliteModel;
Equipment[k].HeroForgeModel = emu->equipment.Slot[k].HerosForgeModel;
Equipment[k].Material2 = emu->equipment.Slot[k].Unknown2;
}
Buffer += (sizeof(structs::Texture_Struct) * EQEmu::textures::TextureCount);
Buffer += (sizeof(structs::Texture_Struct) * EQEmu::textures::materialCount);
}
else
{
@@ -4550,7 +4520,7 @@ namespace RoF2
IN(buff.unknown003);
IN(buff.spellid);
IN(buff.duration);
IN(slotid);
emu->slotid = RoF2ToServerBuffSlot(eq->slotid);
IN(bufffade);
FINISH_DIRECT_DECODE();
@@ -4563,7 +4533,7 @@ namespace RoF2
DECODE_LENGTH_EXACT(structs::BuffRemoveRequest_Struct);
SETUP_DIRECT_DECODE(BuffRemoveRequest_Struct, structs::BuffRemoveRequest_Struct);
emu->SlotID = (eq->SlotID < 42) ? eq->SlotID : (eq->SlotID - 17);
emu->SlotID = RoF2ToServerBuffSlot(eq->SlotID);
IN(EntityID);
@@ -5066,7 +5036,7 @@ namespace RoF2
IN(item_id);
int r;
for (r = 0; r < EQEmu::legacy::ITEM_COMMON_SIZE; r++) {
for (r = EQEmu::inventory::socketBegin; r < EQEmu::inventory::SocketCount; r++) {
IN(augments[r]);
}
IN(link_hash);
@@ -5184,6 +5154,7 @@ namespace RoF2
IN(type);
IN(invslot);
IN(subslot);
emu->window = (uint8)eq->window;
strn0cpy(emu->txtfile, eq->txtfile, sizeof(emu->txtfile));
@@ -5499,9 +5470,9 @@ namespace RoF2
return NextItemInstSerialNumber;
}
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth, ItemPacketType packet_type)
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id_in, uint8 depth, ItemPacketType packet_type)
{
const EQEmu::ItemBase *item = inst->GetUnscaledItem();
const EQEmu::ItemData *item = inst->GetUnscaledItem();
RoF2::structs::ItemSerializationHeader hdr;
@@ -5555,7 +5526,7 @@ namespace RoF2
if (inst->GetOrnamentationIDFile() && inst->GetOrnamentationIcon()) {
ornaIcon = inst->GetOrnamentationIcon();
heroModel = inst->GetOrnamentHeroModel(Inventory::CalcMaterialFromSlot(slot_id_in));
heroModel = inst->GetOrnamentHeroModel(EQEmu::InventoryProfile::CalcMaterialFromSlot(slot_id_in));
char tmp[30]; memset(tmp, 0x0, 30); sprintf(tmp, "IT%d", inst->GetOrnamentationIDFile());
@@ -5922,18 +5893,18 @@ namespace RoF2
ob.write((const char*)&subitem_count, sizeof(uint32));
for (uint32 index = SUB_INDEX_BEGIN; index < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++index) {
ItemInst* sub = inst->GetItem(index);
for (uint32 index = EQEmu::inventory::containerBegin; index < EQEmu::inventory::ContainerCount; ++index) {
EQEmu::ItemInstance* sub = inst->GetItem(index);
if (!sub)
continue;
int SubSlotNumber = INVALID_INDEX;
if (slot_id_in >= EQEmu::legacy::GENERAL_BEGIN && slot_id_in <= EQEmu::legacy::GENERAL_END)
SubSlotNumber = (((slot_id_in + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + index + 1);
SubSlotNumber = (((slot_id_in + 3) * EQEmu::inventory::ContainerCount) + index + 1);
else if (slot_id_in >= EQEmu::legacy::BANK_BEGIN && slot_id_in <= EQEmu::legacy::BANK_END)
SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::BANK_BAGS_BEGIN + index);
SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::BANK_BAGS_BEGIN + index);
else if (slot_id_in >= EQEmu::legacy::SHARED_BANK_BEGIN && slot_id_in <= EQEmu::legacy::SHARED_BANK_END)
SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index);
SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index);
else
SubSlotNumber = slot_id_in;
@@ -5959,7 +5930,7 @@ namespace RoF2
uint32 TempSlot = 0;
if (serverSlot < 56 || serverSlot == EQEmu::legacy::SlotPowerSource) { // Main Inventory and Cursor
if (serverSlot < 56 || serverSlot == EQEmu::inventory::slotPowerSource) { // Main Inventory and Cursor
if (PacketType == ItemPacketLoot)
{
RoF2Slot.Type = invtype::InvTypeCorpse;
@@ -5971,13 +5942,13 @@ namespace RoF2
RoF2Slot.Slot = serverSlot;
}
if (serverSlot == EQEmu::legacy::SlotPowerSource)
if (serverSlot == EQEmu::inventory::slotPowerSource)
RoF2Slot.Slot = invslot::PossessionsPowerSource;
else if (serverSlot >= EQEmu::legacy::SlotCursor && PacketType != ItemPacketLoot) // Cursor and Extended Corpse Inventory
else if (serverSlot >= EQEmu::inventory::slotCursor && PacketType != ItemPacketLoot) // Cursor and Extended Corpse Inventory
RoF2Slot.Slot += 3;
else if (serverSlot >= EQEmu::legacy::SlotAmmo) // (> 20)
else if (serverSlot >= EQEmu::inventory::slotAmmo) // (> 20)
RoF2Slot.Slot += 1;
}
@@ -5989,8 +5960,8 @@ namespace RoF2
else if (serverSlot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::legacy::CURSOR_BAG_END) { // (> 250 && < 341)
RoF2Slot.Type = invtype::InvTypePossessions;
TempSlot = serverSlot - 1;
RoF2Slot.Slot = int(TempSlot / EQEmu::legacy::ITEM_CONTAINER_SIZE) - 2;
RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 2) * EQEmu::legacy::ITEM_CONTAINER_SIZE);
RoF2Slot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 2;
RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 2) * EQEmu::inventory::ContainerCount);
if (RoF2Slot.Slot >= invslot::PossessionsGeneral9) // (> 30)
RoF2Slot.Slot = invslot::PossessionsCursor;
@@ -6007,8 +5978,8 @@ namespace RoF2
RoF2Slot.Slot = TempSlot;
if (TempSlot > 30) { // (> 30)
RoF2Slot.Slot = int(TempSlot / EQEmu::legacy::ITEM_CONTAINER_SIZE) - 3;
RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE);
RoF2Slot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 3;
RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 3) * EQEmu::inventory::ContainerCount);
}
}
@@ -6018,8 +5989,8 @@ namespace RoF2
RoF2Slot.Slot = TempSlot;
if (TempSlot > 30) { // (> 30)
RoF2Slot.Slot = int(TempSlot / EQEmu::legacy::ITEM_CONTAINER_SIZE) - 3;
RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE);
RoF2Slot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 3;
RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 3) * EQEmu::inventory::ContainerCount);
}
}
@@ -6029,8 +6000,8 @@ namespace RoF2
RoF2Slot.Slot = TempSlot;
if (TempSlot > 30) {
RoF2Slot.Slot = int(TempSlot / EQEmu::legacy::ITEM_CONTAINER_SIZE) - 3;
RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE);
RoF2Slot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 3;
RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 3) * EQEmu::inventory::ContainerCount);
}
/*
@@ -6068,16 +6039,16 @@ namespace RoF2
uint32 TempSlot = 0;
if (serverSlot < 56 || serverSlot == EQEmu::legacy::SlotPowerSource) { // (< 52)
if (serverSlot < 56 || serverSlot == EQEmu::inventory::slotPowerSource) { // (< 52)
RoF2Slot.Slot = serverSlot;
if (serverSlot == EQEmu::legacy::SlotPowerSource)
if (serverSlot == EQEmu::inventory::slotPowerSource)
RoF2Slot.Slot = invslot::PossessionsPowerSource;
else if (serverSlot >= EQEmu::legacy::SlotCursor) // Cursor and Extended Corpse Inventory
else if (serverSlot >= EQEmu::inventory::slotCursor) // Cursor and Extended Corpse Inventory
RoF2Slot.Slot += 3;
else if (serverSlot >= EQEmu::legacy::SlotAmmo) // Ammo and Personl Inventory
else if (serverSlot >= EQEmu::inventory::slotAmmo) // Ammo and Personl Inventory
RoF2Slot.Slot += 1;
/*else if (ServerSlot >= MainCursor) { // Cursor
@@ -6090,8 +6061,8 @@ namespace RoF2
else if (serverSlot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::legacy::CURSOR_BAG_END) {
TempSlot = serverSlot - 1;
RoF2Slot.Slot = int(TempSlot / EQEmu::legacy::ITEM_CONTAINER_SIZE) - 2;
RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 2) * EQEmu::legacy::ITEM_CONTAINER_SIZE);
RoF2Slot.Slot = int(TempSlot / EQEmu::inventory::ContainerCount) - 2;
RoF2Slot.SubIndex = TempSlot - ((RoF2Slot.Slot + 2) * EQEmu::inventory::ContainerCount);
}
Log.Out(Logs::General, Logs::Netcode, "[ERROR] Convert Server Slot %i to RoF2 Slots: Main %i, Sub %i, Aug %i, Unk1 %i", serverSlot, RoF2Slot.Slot, RoF2Slot.SubIndex, RoF2Slot.AugIndex, RoF2Slot.Unknown01);
@@ -6111,7 +6082,7 @@ namespace RoF2
if (rof2Slot.Type == invtype::InvTypePossessions && rof2Slot.Slot < 57) { // Worn/Personal Inventory and Cursor (< 51)
if (rof2Slot.Slot == invslot::PossessionsPowerSource)
TempSlot = EQEmu::legacy::SlotPowerSource;
TempSlot = EQEmu::inventory::slotPowerSource;
else if (rof2Slot.Slot >= invslot::PossessionsCursor) // Cursor and Extended Corpse Inventory
TempSlot = rof2Slot.Slot - 3;
@@ -6133,8 +6104,8 @@ namespace RoF2
else // Worn Slots
TempSlot = rof2Slot.Slot;
if (rof2Slot.SubIndex >= SUB_INDEX_BEGIN) // Bag Slots
TempSlot = ((TempSlot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + rof2Slot.SubIndex + 1;
if (rof2Slot.SubIndex >= EQEmu::inventory::containerBegin) // Bag Slots
TempSlot = ((TempSlot + 3) * EQEmu::inventory::ContainerCount) + rof2Slot.SubIndex + 1;
ServerSlot = TempSlot;
}
@@ -6142,8 +6113,8 @@ namespace RoF2
else if (rof2Slot.Type == invtype::InvTypeBank) {
TempSlot = EQEmu::legacy::BANK_BEGIN;
if (rof2Slot.SubIndex >= SUB_INDEX_BEGIN)
TempSlot += ((rof2Slot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + rof2Slot.SubIndex + 1;
if (rof2Slot.SubIndex >= EQEmu::inventory::containerBegin)
TempSlot += ((rof2Slot.Slot + 3) * EQEmu::inventory::ContainerCount) + rof2Slot.SubIndex + 1;
else
TempSlot += rof2Slot.Slot;
@@ -6154,8 +6125,8 @@ namespace RoF2
else if (rof2Slot.Type == invtype::InvTypeSharedBank) {
TempSlot = EQEmu::legacy::SHARED_BANK_BEGIN;
if (rof2Slot.SubIndex >= SUB_INDEX_BEGIN)
TempSlot += ((rof2Slot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + rof2Slot.SubIndex + 1;
if (rof2Slot.SubIndex >= EQEmu::inventory::containerBegin)
TempSlot += ((rof2Slot.Slot + 3) * EQEmu::inventory::ContainerCount) + rof2Slot.SubIndex + 1;
else
TempSlot += rof2Slot.Slot;
@@ -6166,8 +6137,8 @@ namespace RoF2
else if (rof2Slot.Type == invtype::InvTypeTrade) {
TempSlot = EQEmu::legacy::TRADE_BEGIN;
if (rof2Slot.SubIndex >= SUB_INDEX_BEGIN)
TempSlot += ((rof2Slot.Slot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + rof2Slot.SubIndex + 1;
if (rof2Slot.SubIndex >= EQEmu::inventory::containerBegin)
TempSlot += ((rof2Slot.Slot + 3) * EQEmu::inventory::ContainerCount) + rof2Slot.SubIndex + 1;
// OLD CODE:
//TempSlot += 100 + (RoF2Slot.MainSlot * EmuConstants::ITEM_CONTAINER_SIZE) + RoF2Slot.SubSlot;
@@ -6180,7 +6151,7 @@ namespace RoF2
else if (rof2Slot.Type == invtype::InvTypeWorld) {
TempSlot = EQEmu::legacy::WORLD_BEGIN;
if (rof2Slot.Slot >= SUB_INDEX_BEGIN)
if (rof2Slot.Slot >= EQEmu::inventory::containerBegin)
TempSlot += rof2Slot.Slot;
ServerSlot = TempSlot;
@@ -6215,7 +6186,7 @@ namespace RoF2
if (rof2Slot.Slot < 57) { // Worn/Personal Inventory and Cursor (< 33)
if (rof2Slot.Slot == invslot::PossessionsPowerSource)
TempSlot = EQEmu::legacy::SlotPowerSource;
TempSlot = EQEmu::inventory::slotPowerSource;
else if (rof2Slot.Slot >= invslot::PossessionsCursor) // Cursor and Extended Corpse Inventory
TempSlot = rof2Slot.Slot - 3;
@@ -6232,8 +6203,8 @@ namespace RoF2
else
TempSlot = rof2Slot.Slot;
if (rof2Slot.SubIndex >= SUB_INDEX_BEGIN) // Bag Slots
TempSlot = ((TempSlot + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + rof2Slot.SubIndex + 1;
if (rof2Slot.SubIndex >= EQEmu::inventory::containerBegin) // Bag Slots
TempSlot = ((TempSlot + 3) * EQEmu::inventory::ContainerCount) + rof2Slot.SubIndex + 1;
ServerSlot = TempSlot;
}
@@ -6388,4 +6359,32 @@ namespace RoF2
return EQEmu::CastingSlot::Discipline;
}
}
// these should be optimized out for RoF2 since they should all boil down to return index :P
// but lets leave it here for future proofing
static inline int ServerToRoF2BuffSlot(int index)
{
// we're a disc
if (index >= EQEmu::constants::LongBuffs + EQEmu::constants::ShortBuffs)
return index - EQEmu::constants::LongBuffs - EQEmu::constants::ShortBuffs +
constants::LongBuffs + constants::ShortBuffs;
// we're a song
if (index >= EQEmu::constants::LongBuffs)
return index - EQEmu::constants::LongBuffs + constants::LongBuffs;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}
static inline int RoF2ToServerBuffSlot(int index)
{
// we're a disc
if (index >= constants::LongBuffs + constants::ShortBuffs)
return index - constants::LongBuffs - constants::ShortBuffs + EQEmu::constants::LongBuffs +
EQEmu::constants::ShortBuffs;
// we're a song
if (index >= constants::LongBuffs)
return index - constants::LongBuffs + EQEmu::constants::LongBuffs;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}
} /*RoF2*/
+8
View File
@@ -277,6 +277,14 @@ namespace RoF2
const size_t SayLinkBodySize = 56;
const int LongBuffs = 42;
const int ShortBuffs = 20;
const int DiscBuffs = 1;
const int TotalBuffs = LongBuffs + ShortBuffs + DiscBuffs;
const int NPCBuffs = 97;
const int PetBuffs = NPCBuffs;
const int MercBuffs = LongBuffs;
} /*constants*/
namespace behavior {
-1
View File
@@ -85,7 +85,6 @@ E(OP_HPUpdate)
E(OP_Illusion)
E(OP_InspectBuffs)
E(OP_InspectRequest)
E(OP_InterruptCast)
E(OP_ItemLinkResponse)
E(OP_ItemPacket)
E(OP_ItemVerifyReply)
+10 -6
View File
@@ -190,7 +190,7 @@ struct TintProfile
Tint_Struct Primary;
Tint_Struct Secondary;
};
Tint_Struct Slot[EQEmu::textures::TextureCount];
Tint_Struct Slot[EQEmu::textures::materialCount];
};
};
@@ -1082,7 +1082,7 @@ union
/*00184*/ Texture_Struct equipment[22]; // Total Slots
};
/*00624*/ uint32 equip2_count; // Seen 9
/*00628*/ Texture_Struct equipment2[EQEmu::textures::TextureCount]; // Appears to be Visible slots, but all 0s
/*00628*/ Texture_Struct equipment2[EQEmu::textures::materialCount]; // Appears to be Visible slots, but all 0s
/*00808*/ uint32 tint_count; // Seen 9
/*00812*/ TintProfile item_tint; // RR GG BB 00
/*00848*/ uint32 tint_count2; // Seen 9
@@ -2423,7 +2423,7 @@ struct AdventureLeaderboard_Struct
/*struct Item_Shop_Struct {
uint16 merchantid;
uint8 itemtype;
ItemBase item;
ItemData item;
uint8 iss_unknown001[6];
};*/
@@ -2566,9 +2566,12 @@ struct GroupJoin_Struct_Live { // New for Live
};
struct GroupJoin_Struct {
/*000*/ char unknown000[64];
/*000*/ char owner_name[64]; // merc
/*064*/ char membername[64];
/*128*/ uint8 unknown128[20]; // Leadership AA ?
/*128*/ uint8 merc;
/*129*/ uint8 padding129[3];
/*132*/ uint32 level;
/*136*/ uint8 unknown136[12]; // group ID most likely in here judging from like captures (unused by client)
/*148*/
};
@@ -2826,7 +2829,8 @@ struct BookText_Struct {
struct BookRequest_Struct {
/*0000*/ uint32 window; // where to display the text (0xFFFFFFFF means new window).
/*0004*/ uint16 invslot; // Is the slot, but the RoF2 conversion causes it to fail. Turned to 0 since it isnt required anyway.
/*0008*/ uint32 unknown006; // Seen FFFFFFFF
/*0006*/ int16 subslot; // Inventory sub-slot (0-x)
/*0008*/ uint16 unknown006; // Seen FFFF
/*0010*/ uint16 unknown008; // seen 0000
/*0012*/ uint32 type; // 0 = Scroll, 1 = Book, 2 = Item Info. Possibly others
/*0016*/ uint32 unknown0012;
+8
View File
@@ -268,6 +268,14 @@ namespace RoF
const size_t SayLinkBodySize = 55;
const int LongBuffs = 42;
const int ShortBuffs = 20;
const int DiscBuffs = 1;
const int TotalBuffs = LongBuffs + ShortBuffs + DiscBuffs;
const int NPCBuffs = 97;
const int PetBuffs = NPCBuffs;
const int MercBuffs = LongBuffs;
} /*constants*/
namespace behavior {
-1
View File
@@ -70,7 +70,6 @@ E(OP_HPUpdate)
E(OP_Illusion)
E(OP_InspectBuffs)
E(OP_InspectRequest)
E(OP_InterruptCast)
E(OP_ItemLinkResponse)
E(OP_ItemPacket)
E(OP_ItemVerifyReply)
+3 -3
View File
@@ -190,7 +190,7 @@ struct TintProfile
Tint_Struct Primary;
Tint_Struct Secondary;
};
Tint_Struct Slot[EQEmu::textures::TextureCount];
Tint_Struct Slot[EQEmu::textures::materialCount];
};
};
@@ -2021,7 +2021,7 @@ struct LootingItem_Struct {
/*004*/ uint32 looter;
/*008*/ uint16 slot_id;
/*010*/ uint16 unknown10;
/*012*/ uint32 auto_loot;
/*012*/ int32 auto_loot;
/*016*/ uint32 unknown16;
/*020*/
};
@@ -2450,7 +2450,7 @@ struct AdventureLeaderboard_Struct
/*struct Item_Shop_Struct {
uint16 merchantid;
uint8 itemtype;
ItemBase item;
ItemData item;
uint8 iss_unknown001[6];
};*/
+54 -25
View File
@@ -29,7 +29,7 @@
#include "../eq_packet_structs.h"
#include "../misc_functions.h"
#include "../string_util.h"
#include "../item.h"
#include "../item_instance.h"
#include "sod_structs.h"
#include "../rulesys.h"
@@ -43,7 +43,7 @@ namespace SoD
static OpcodeManager *opcodes = nullptr;
static Strategy struct_strategy;
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id, uint8 depth);
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id, uint8 depth);
// server to client inventory location converters
static inline uint32 ServerToSoDSlot(uint32 ServerSlot);
@@ -62,6 +62,9 @@ namespace SoD
static inline CastingSlot ServerToSoDCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot SoDToServerCastingSlot(CastingSlot slot);
static inline int ServerToSoDBuffSlot(int index);
static inline int SoDToServerBuffSlot(int index);
void Register(EQStreamIdentifier &into)
{
//create our opcode manager if we havent already
@@ -315,7 +318,7 @@ namespace SoD
OUT(buff.duration);
OUT(buff.counters);
OUT(buff.player_id);
OUT(slotid);
eq->slotid = ServerToSoDBuffSlot(emu->slotid);
OUT(bufffade);
FINISH_ENCODE();
@@ -396,7 +399,7 @@ namespace SoD
ob.write((const char*)&item_count, sizeof(uint32));
for (int index = 0; index < item_count; ++index, ++eq) {
SerializeItem(ob, (const ItemInst*)eq->inst, eq->slot_id, 0);
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0);
if (ob.tellp() == last_pos)
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
@@ -1060,7 +1063,7 @@ namespace SoD
ob.write((const char*)__emu_buffer, 4);
SerializeItem(ob, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0);
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0);
if (ob.tellp() == last_pos) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
delete in;
@@ -1558,7 +1561,7 @@ namespace SoD
OUT(hairstyle);
OUT(beard);
// OUT(unknown00178[10]);
for (r = EQEmu::textures::TextureBegin; r < EQEmu::textures::TextureCount; r++) {
for (r = EQEmu::textures::textureBegin; r < EQEmu::textures::materialCount; r++) {
eq->equipment.Slot[r].Material = emu->item_material.Slot[r].Material;
eq->equipment.Slot[r].Unknown1 = 0;
eq->equipment.Slot[r].EliteMaterial = 0;
@@ -1998,10 +2001,10 @@ namespace SoD
eq_cse->HairColor = emu_cse->HairColor;
eq_cse->Face = emu_cse->Face;
for (int equip_index = 0; equip_index < EQEmu::textures::TextureCount; equip_index++) {
for (int equip_index = EQEmu::textures::textureBegin; equip_index < EQEmu::textures::materialCount; equip_index++) {
eq_cse->Equip[equip_index].Material = emu_cse->Equip[equip_index].Material;
eq_cse->Equip[equip_index].Unknown1 = emu_cse->Equip[equip_index].Unknown1;
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteMaterial;
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteModel;
eq_cse->Equip[equip_index].Color = emu_cse->Equip[equip_index].Color;
}
@@ -2568,7 +2571,7 @@ namespace SoD
float SpawnSize = emu->size;
if (!((emu->NPC == 0) || (emu->race <= 12) || (emu->race == 128) || (emu->race == 130) || (emu->race == 330) || (emu->race == 522)))
{
PacketSize -= (sizeof(structs::Texture_Struct) * EQEmu::textures::TextureCount);
PacketSize -= (sizeof(structs::Texture_Struct) * EQEmu::textures::materialCount);
if (emu->size == 0)
{
@@ -2765,7 +2768,7 @@ namespace SoD
if ((emu->NPC == 0) || (emu->race <= 12) || (emu->race == 128) || (emu->race == 130) || (emu->race == 330) || (emu->race == 522))
{
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; ++k)
for (k = EQEmu::textures::textureBegin; k < EQEmu::textures::materialCount; ++k)
{
{
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment_tint.Slot[k].Color);
@@ -2792,13 +2795,13 @@ namespace SoD
{
structs::Texture_Struct *Equipment = (structs::Texture_Struct *)Buffer;
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; k++) {
for (k = EQEmu::textures::textureBegin; k < EQEmu::textures::materialCount; k++) {
Equipment[k].Material = emu->equipment.Slot[k].Material;
Equipment[k].Unknown1 = emu->equipment.Slot[k].Unknown1;
Equipment[k].EliteMaterial = emu->equipment.Slot[k].EliteMaterial;
Equipment[k].EliteMaterial = emu->equipment.Slot[k].EliteModel;
}
Buffer += (sizeof(structs::Texture_Struct) * EQEmu::textures::TextureCount);
Buffer += (sizeof(structs::Texture_Struct) * EQEmu::textures::materialCount);
}
if (strlen(emu->title))
{
@@ -2921,8 +2924,8 @@ namespace SoD
IN(buff.bard_modifier);
IN(buff.spellid);
IN(buff.duration);
IN(buff.counters)
IN(slotid);
IN(buff.counters);
emu->slotid = SoDToServerBuffSlot(eq->slotid);
IN(bufffade);
FINISH_DIRECT_DECODE();
@@ -3553,9 +3556,9 @@ namespace SoD
return NextItemInstSerialNumber;
}
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth)
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id_in, uint8 depth)
{
const EQEmu::ItemBase *item = inst->GetUnscaledItem();
const EQEmu::ItemData *item = inst->GetUnscaledItem();
SoD::structs::ItemSerializationHeader hdr;
@@ -3869,18 +3872,18 @@ namespace SoD
ob.write((const char*)&subitem_count, sizeof(uint32));
for (uint32 index = SUB_INDEX_BEGIN; index < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++index) {
ItemInst* sub = inst->GetItem(index);
for (uint32 index = EQEmu::inventory::containerBegin; index < EQEmu::inventory::ContainerCount; ++index) {
EQEmu::ItemInstance* sub = inst->GetItem(index);
if (!sub)
continue;
int SubSlotNumber = INVALID_INDEX;
if (slot_id_in >= EQEmu::legacy::GENERAL_BEGIN && slot_id_in <= EQEmu::legacy::GENERAL_END)
SubSlotNumber = (((slot_id_in + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + index + 1);
SubSlotNumber = (((slot_id_in + 3) * EQEmu::inventory::ContainerCount) + index + 1);
else if (slot_id_in >= EQEmu::legacy::BANK_BEGIN && slot_id_in <= EQEmu::legacy::BANK_END)
SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::BANK_BAGS_BEGIN + index);
SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::BANK_BAGS_BEGIN + index);
else if (slot_id_in >= EQEmu::legacy::SHARED_BANK_BEGIN && slot_id_in <= EQEmu::legacy::SHARED_BANK_END)
SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index);
SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index);
else
SubSlotNumber = slot_id_in;
@@ -3898,7 +3901,7 @@ namespace SoD
{
uint32 SoDSlot = 0;
if (serverSlot >= EQEmu::legacy::SlotAmmo && serverSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots
if (serverSlot >= EQEmu::inventory::slotAmmo && serverSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots
SoDSlot = serverSlot + 1;
else if (serverSlot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::legacy::CURSOR_BAG_END)
SoDSlot = serverSlot + 11;
@@ -3906,7 +3909,7 @@ namespace SoD
SoDSlot = serverSlot + 1;
else if (serverSlot >= EQEmu::legacy::SHARED_BANK_BAGS_BEGIN && serverSlot <= EQEmu::legacy::SHARED_BANK_BAGS_END)
SoDSlot = serverSlot + 1;
else if (serverSlot == EQEmu::legacy::SlotPowerSource)
else if (serverSlot == EQEmu::inventory::slotPowerSource)
SoDSlot = invslot::PossessionsPowerSource;
else
SoDSlot = serverSlot;
@@ -3932,7 +3935,7 @@ namespace SoD
else if (sodSlot >= invbag::SharedBankBagsBegin && sodSlot <= invbag::SharedBankBagsEnd)
ServerSlot = sodSlot - 1;
else if (sodSlot == invslot::PossessionsPowerSource)
ServerSlot = EQEmu::legacy::SlotPowerSource;
ServerSlot = EQEmu::inventory::slotPowerSource;
else
ServerSlot = sodSlot;
return ServerSlot;
@@ -4088,4 +4091,30 @@ namespace SoD
return EQEmu::CastingSlot::Discipline;
}
}
static inline int ServerToSoDBuffSlot(int index)
{
// we're a disc
if (index >= EQEmu::constants::LongBuffs + EQEmu::constants::ShortBuffs)
return index - EQEmu::constants::LongBuffs - EQEmu::constants::ShortBuffs +
constants::LongBuffs + constants::ShortBuffs;
// we're a song
if (index >= EQEmu::constants::LongBuffs)
return index - EQEmu::constants::LongBuffs + constants::LongBuffs;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}
static inline int SoDToServerBuffSlot(int index)
{
// we're a disc
if (index >= constants::LongBuffs + constants::ShortBuffs)
return index - constants::LongBuffs - constants::ShortBuffs + EQEmu::constants::LongBuffs +
EQEmu::constants::ShortBuffs;
// we're a song
if (index >= constants::LongBuffs)
return index - constants::LongBuffs + EQEmu::constants::LongBuffs;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}
} /*SoD*/
+8
View File
@@ -295,6 +295,14 @@ namespace SoD
const size_t SayLinkBodySize = 50;
const int LongBuffs = 25;
const int ShortBuffs = 15;
const int DiscBuffs = 1;
const int TotalBuffs = LongBuffs + ShortBuffs + DiscBuffs;
const int NPCBuffs = 85;
const int PetBuffs = NPCBuffs;
const int MercBuffs = LongBuffs;
} /*constants*/
namespace behavior {
+5 -5
View File
@@ -149,7 +149,7 @@ struct TintProfile
Tint_Struct Primary;
Tint_Struct Secondary;
};
Tint_Struct Slot[EQEmu::textures::TextureCount];
Tint_Struct Slot[EQEmu::textures::materialCount];
};
};
@@ -178,7 +178,7 @@ struct TextureProfile
Texture_Struct Primary;
Texture_Struct Secondary;
};
Texture_Struct Slot[EQEmu::textures::TextureCount];
Texture_Struct Slot[EQEmu::textures::materialCount];
};
TextureProfile();
@@ -195,7 +195,7 @@ struct CharacterSelectEntry_Struct
/*0000*/ uint8 Beard; //
/*0001*/ uint8 HairColor; //
/*0000*/ uint8 Face; //
/*0000*/ CharSelectEquip Equip[EQEmu::textures::TextureCount];
/*0000*/ CharSelectEquip Equip[EQEmu::textures::materialCount];
/*0000*/ uint32 PrimaryIDFile; //
/*0000*/ uint32 SecondaryIDFile; //
/*0000*/ uint8 Unknown15; // 0xff
@@ -1666,7 +1666,7 @@ struct LootingItem_Struct {
/*000*/ uint32 lootee;
/*004*/ uint32 looter;
/*008*/ uint32 slot_id;
/*012*/ uint32 auto_loot;
/*012*/ int32 auto_loot;
/*016*/ uint32 unknown16;
/*020*/
};
@@ -1970,7 +1970,7 @@ struct AdventureLeaderboard_Struct
/*struct Item_Shop_Struct {
uint16 merchantid;
uint8 itemtype;
ItemBase item;
ItemData item;
uint8 iss_unknown001[6];
};*/
+51 -22
View File
@@ -29,7 +29,7 @@
#include "../eq_packet_structs.h"
#include "../misc_functions.h"
#include "../string_util.h"
#include "../item.h"
#include "../item_instance.h"
#include "sof_structs.h"
#include "../rulesys.h"
@@ -43,7 +43,7 @@ namespace SoF
static OpcodeManager *opcodes = nullptr;
static Strategy struct_strategy;
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id, uint8 depth);
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id, uint8 depth);
// server to client inventory location converters
static inline uint32 ServerToSoFSlot(uint32 serverSlot);
@@ -62,6 +62,9 @@ namespace SoF
static inline CastingSlot ServerToSoFCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot SoFToServerCastingSlot(CastingSlot slot, uint32 itemlocation);
static inline int ServerToSoFBuffSlot(int index);
static inline int SoFToServerBuffSlot(int index);
void Register(EQStreamIdentifier &into)
{
//create our opcode manager if we havent already
@@ -297,7 +300,7 @@ namespace SoF
OUT(buff.duration);
OUT(buff.counters);
OUT(buff.player_id);
OUT(slotid);
eq->slotid = ServerToSoFBuffSlot(emu->slotid);
OUT(bufffade);
FINISH_ENCODE();
@@ -378,7 +381,7 @@ namespace SoF
ob.write((const char*)&item_count, sizeof(uint32));
for (int index = 0; index < item_count; ++index, ++eq) {
SerializeItem(ob, (const ItemInst*)eq->inst, eq->slot_id, 0);
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0);
if (ob.tellp() == last_pos)
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
@@ -857,7 +860,7 @@ namespace SoF
ob.write((const char*)__emu_buffer, 4);
SerializeItem(ob, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0);
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0);
if (ob.tellp() == last_pos) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
delete in;
@@ -1230,7 +1233,7 @@ namespace SoF
OUT(hairstyle);
OUT(beard);
// OUT(unknown00178[10]);
for (r = EQEmu::textures::TextureBegin; r < EQEmu::textures::TextureCount; r++) {
for (r = EQEmu::textures::textureBegin; r < EQEmu::textures::materialCount; r++) {
eq->equipment.Slot[r].Material = emu->item_material.Slot[r].Material;
eq->equipment.Slot[r].Unknown1 = 0;
eq->equipment.Slot[r].EliteMaterial = 0;
@@ -1670,10 +1673,10 @@ namespace SoF
eq_cse->HairColor = emu_cse->HairColor;
eq_cse->Face = emu_cse->Face;
for (int equip_index = 0; equip_index < EQEmu::textures::TextureCount; equip_index++) {
for (int equip_index = EQEmu::textures::textureBegin; equip_index < EQEmu::textures::materialCount; equip_index++) {
eq_cse->Equip[equip_index].Material = emu_cse->Equip[equip_index].Material;
eq_cse->Equip[equip_index].Unknown1 = emu_cse->Equip[equip_index].Unknown1;
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteMaterial;
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteModel;
eq_cse->Equip[equip_index].Color = emu_cse->Equip[equip_index].Color;
}
@@ -2101,10 +2104,10 @@ namespace SoF
eq->deity = emu->deity;
eq->drakkin_heritage = emu->drakkin_heritage;
eq->gender = emu->gender;
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; k++) {
for (k = EQEmu::textures::textureBegin; k < EQEmu::textures::materialCount; k++) {
eq->equipment.Slot[k].Material = emu->equipment.Slot[k].Material;
eq->equipment.Slot[k].Unknown1 = emu->equipment.Slot[k].Unknown1;
eq->equipment.Slot[k].EliteMaterial = emu->equipment.Slot[k].EliteMaterial;
eq->equipment.Slot[k].EliteMaterial = emu->equipment.Slot[k].EliteModel;
eq->equipment_tint.Slot[k].Color = emu->equipment_tint.Slot[k].Color;
}
eq->StandState = emu->StandState;
@@ -2167,7 +2170,7 @@ namespace SoF
strcpy(eq->name, emu->name);
eq->petOwnerId = emu->petOwnerId;
eq->pvp = 0; // 0 = non-pvp colored name, 1 = red pvp name
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; k++) {
for (k = EQEmu::textures::textureBegin; k < EQEmu::textures::materialCount; k++) {
eq->equipment_tint.Slot[k].Color = emu->equipment_tint.Slot[k].Color;
}
eq->anon = emu->anon;
@@ -2375,7 +2378,7 @@ namespace SoF
IN(buff.duration);
IN(buff.counters);
IN(buff.player_id);
IN(slotid);
emu->slotid = SoFToServerBuffSlot(eq->slotid);
IN(bufffade);
FINISH_DIRECT_DECODE();
@@ -2923,9 +2926,9 @@ namespace SoF
return NextItemInstSerialNumber;
}
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth)
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id_in, uint8 depth)
{
const EQEmu::ItemBase *item = inst->GetUnscaledItem();
const EQEmu::ItemData *item = inst->GetUnscaledItem();
SoF::structs::ItemSerializationHeader hdr;
@@ -3237,18 +3240,18 @@ namespace SoF
ob.write((const char*)&subitem_count, sizeof(uint32));
for (uint32 index = SUB_INDEX_BEGIN; index < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++index) {
ItemInst* sub = inst->GetItem(index);
for (uint32 index = EQEmu::inventory::containerBegin; index < EQEmu::inventory::ContainerCount; ++index) {
EQEmu::ItemInstance* sub = inst->GetItem(index);
if (!sub)
continue;
int SubSlotNumber = INVALID_INDEX;
if (slot_id_in >= EQEmu::legacy::GENERAL_BEGIN && slot_id_in <= EQEmu::legacy::GENERAL_END)
SubSlotNumber = (((slot_id_in + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + index + 1);
SubSlotNumber = (((slot_id_in + 3) * EQEmu::inventory::ContainerCount) + index + 1);
else if (slot_id_in >= EQEmu::legacy::BANK_BEGIN && slot_id_in <= EQEmu::legacy::BANK_END)
SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::BANK_BAGS_BEGIN + index);
SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::BANK_BAGS_BEGIN + index);
else if (slot_id_in >= EQEmu::legacy::SHARED_BANK_BEGIN && slot_id_in <= EQEmu::legacy::SHARED_BANK_END)
SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index);
SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index);
else
SubSlotNumber = slot_id_in;
@@ -3266,7 +3269,7 @@ namespace SoF
{
uint32 SoFSlot = 0;
if (serverSlot >= EQEmu::legacy::SlotAmmo && serverSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots
if (serverSlot >= EQEmu::inventory::slotAmmo && serverSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots
SoFSlot = serverSlot + 1;
else if (serverSlot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::legacy::CURSOR_BAG_END)
SoFSlot = serverSlot + 11;
@@ -3274,7 +3277,7 @@ namespace SoF
SoFSlot = serverSlot + 1;
else if (serverSlot >= EQEmu::legacy::SHARED_BANK_BAGS_BEGIN && serverSlot <= EQEmu::legacy::SHARED_BANK_BAGS_END)
SoFSlot = serverSlot + 1;
else if (serverSlot == EQEmu::legacy::SlotPowerSource)
else if (serverSlot == EQEmu::inventory::slotPowerSource)
SoFSlot = invslot::PossessionsPowerSource;
else
SoFSlot = serverSlot;
@@ -3301,7 +3304,7 @@ namespace SoF
else if (sofSlot >= invbag::SharedBankBagsBegin && sofSlot <= invbag::SharedBankBagsEnd)
ServerSlot = sofSlot - 1;
else if (sofSlot == invslot::PossessionsPowerSource)
ServerSlot = EQEmu::legacy::SlotPowerSource;
ServerSlot = EQEmu::inventory::slotPowerSource;
else
ServerSlot = sofSlot;
@@ -3461,4 +3464,30 @@ namespace SoF
return EQEmu::CastingSlot::Discipline;
}
}
static inline int ServerToSoFBuffSlot(int index)
{
// we're a disc
if (index >= EQEmu::constants::LongBuffs + EQEmu::constants::ShortBuffs)
return index - EQEmu::constants::LongBuffs - EQEmu::constants::ShortBuffs +
constants::LongBuffs + constants::ShortBuffs;
// we're a song
if (index >= EQEmu::constants::LongBuffs)
return index - EQEmu::constants::LongBuffs + constants::LongBuffs;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}
static inline int SoFToServerBuffSlot(int index)
{
// we're a disc
if (index >= constants::LongBuffs + constants::ShortBuffs)
return index - constants::LongBuffs - constants::ShortBuffs + EQEmu::constants::LongBuffs +
EQEmu::constants::ShortBuffs;
// we're a song
if (index >= constants::LongBuffs)
return index - constants::LongBuffs + EQEmu::constants::LongBuffs;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}
} /*SoF*/
+8
View File
@@ -295,6 +295,14 @@ namespace SoF
const size_t SayLinkBodySize = 50;
const int LongBuffs = 25;
const int ShortBuffs = 15;
const int DiscBuffs = 1;
const int TotalBuffs = LongBuffs + ShortBuffs + DiscBuffs;
const int NPCBuffs = 60;
const int PetBuffs = 30;
const int MercBuffs = 0;
} /*constants*/
namespace behavior {
+4 -4
View File
@@ -149,7 +149,7 @@ struct TintProfile
Tint_Struct Primary;
Tint_Struct Secondary;
};
Tint_Struct Slot[EQEmu::textures::TextureCount];
Tint_Struct Slot[EQEmu::textures::materialCount];
};
};
@@ -178,7 +178,7 @@ struct TextureProfile
Texture_Struct Primary;
Texture_Struct Secondary;
};
Texture_Struct Slot[EQEmu::textures::TextureCount];
Texture_Struct Slot[EQEmu::textures::materialCount];
};
TextureProfile();
@@ -195,7 +195,7 @@ struct CharacterSelectEntry_Struct
/*0000*/ uint8 Beard; //
/*0001*/ uint8 HairColor; //
/*0000*/ uint8 Face; //
/*0000*/ CharSelectEquip Equip[EQEmu::textures::TextureCount];
/*0000*/ CharSelectEquip Equip[EQEmu::textures::materialCount];
/*0000*/ uint32 PrimaryIDFile; //
/*0000*/ uint32 SecondaryIDFile; //
/*0000*/ uint8 Unknown15; // 0xff
@@ -1648,7 +1648,7 @@ struct LootingItem_Struct {
/*002*/ uint32 looter;
/*004*/ uint16 slot_id;
/*006*/ uint8 unknown3[2];
/*008*/ uint32 auto_loot;
/*008*/ int32 auto_loot;
};
struct GuildManageStatus_Struct{
+45 -16
View File
@@ -30,7 +30,7 @@
#include "../eq_packet_structs.h"
#include "../misc_functions.h"
#include "../string_util.h"
#include "../item.h"
#include "../item_instance.h"
#include "titanium_structs.h"
#include <sstream>
@@ -42,7 +42,7 @@ namespace Titanium
static OpcodeManager *opcodes = nullptr;
static Strategy struct_strategy;
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth);
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id_in, uint8 depth);
// server to client inventory location converters
static inline int16 ServerToTitaniumSlot(uint32 serverSlot);
@@ -61,6 +61,9 @@ namespace Titanium
static inline CastingSlot ServerToTitaniumCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot TitaniumToServerCastingSlot(CastingSlot slot, uint32 itemlocation);
static inline int ServerToTitaniumBuffSlot(int index);
static inline int TitaniumToServerBuffSlot(int index);
void Register(EQStreamIdentifier &into)
{
auto Config = EQEmuConfig::get();
@@ -270,7 +273,7 @@ namespace Titanium
OUT(buff.duration);
OUT(buff.counters);
OUT(buff.player_id);
OUT(slotid);
eq->slotid = ServerToTitaniumBuffSlot(emu->slotid);
OUT(bufffade);
FINISH_ENCODE();
@@ -329,7 +332,7 @@ namespace Titanium
EQEmu::OutBuffer::pos_type last_pos = ob.tellp();
for (int r = 0; r < itemcount; r++, eq++) {
SerializeItem(ob, (const ItemInst*)eq->inst, eq->slot_id, 0);
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0);
if (ob.tellp() == last_pos)
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
@@ -815,7 +818,7 @@ namespace Titanium
ob.write((const char*)__emu_buffer, 4);
SerializeItem(ob, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0);
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0);
if (ob.tellp() == last_pos) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
delete in;
@@ -981,7 +984,7 @@ namespace Titanium
OUT(hairstyle);
OUT(beard);
// OUT(unknown00178[10]);
for (r = EQEmu::textures::TextureBegin; r < EQEmu::textures::TextureCount; r++) {
for (r = EQEmu::textures::textureBegin; r < EQEmu::textures::materialCount; r++) {
OUT(item_material.Slot[r].Material);
OUT(item_tint.Slot[r].Color);
}
@@ -1301,14 +1304,14 @@ namespace Titanium
if (eq->Race[char_index] > 473)
eq->Race[char_index] = 1;
for (int index = 0; index < EQEmu::textures::TextureCount; ++index) {
for (int index = 0; index < EQEmu::textures::materialCount; ++index) {
eq->CS_Colors[char_index].Slot[index].Color = emu_cse->Equip[index].Color;
}
eq->BeardColor[char_index] = emu_cse->BeardColor;
eq->HairStyle[char_index] = emu_cse->HairStyle;
for (int index = 0; index < EQEmu::textures::TextureCount; ++index) {
for (int index = 0; index < EQEmu::textures::materialCount; ++index) {
eq->Equip[char_index].Slot[index].Material = emu_cse->Equip[index].Material;
}
@@ -1338,14 +1341,14 @@ namespace Titanium
for (; char_index < 10; ++char_index) {
eq->Race[char_index] = 0;
for (int index = 0; index < EQEmu::textures::TextureCount; ++index) {
for (int index = 0; index < EQEmu::textures::materialCount; ++index) {
eq->CS_Colors[char_index].Slot[index].Color = 0;
}
eq->BeardColor[char_index] = 0;
eq->HairStyle[char_index] = 0;
for (int index = 0; index < EQEmu::textures::TextureCount; ++index) {
for (int index = 0; index < EQEmu::textures::materialCount; ++index) {
eq->Equip[char_index].Slot[index].Material = 0;
}
@@ -1677,7 +1680,7 @@ namespace Titanium
eq->petOwnerId = emu->petOwnerId;
eq->guildrank = emu->guildrank;
// eq->unknown0194[3] = emu->unknown0194[3];
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; k++) {
for (k = EQEmu::textures::textureBegin; k < EQEmu::textures::materialCount; k++) {
eq->equipment.Slot[k].Material = emu->equipment.Slot[k].Material;
eq->equipment_tint.Slot[k].Color = emu->equipment_tint.Slot[k].Color;
}
@@ -1779,7 +1782,7 @@ namespace Titanium
IN(buff.duration);
IN(buff.counters);
IN(buff.player_id);
IN(slotid);
emu->slotid = TitaniumToServerBuffSlot(eq->slotid);
IN(bufffade);
FINISH_DIRECT_DECODE();
@@ -2216,10 +2219,10 @@ namespace Titanium
}
// file scope helper methods
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth)
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id_in, uint8 depth)
{
const char* protection = "\\\\\\\\\\";
const EQEmu::ItemBase* item = inst->GetUnscaledItem();
const EQEmu::ItemData* item = inst->GetUnscaledItem();
ob << StringFormat("%.*s%s", (depth ? (depth - 1) : 0), protection, (depth ? "\"" : "")); // For leading quotes (and protection) if a subitem;
@@ -2437,10 +2440,10 @@ namespace Titanium
ob << StringFormat("%.*s\"", depth, protection); // Quotes (and protection, if needed) around static data
// Sub data
for (int index = SUB_INDEX_BEGIN; index < invbag::ItemBagSize; ++index) {
for (int index = EQEmu::inventory::containerBegin; index < invbag::ItemBagSize; ++index) {
ob << '|';
ItemInst* sub = inst->GetItem(index);
EQEmu::ItemInstance* sub = inst->GetItem(index);
if (!sub)
continue;
@@ -2632,4 +2635,30 @@ namespace Titanium
return EQEmu::CastingSlot::Discipline;
}
}
static inline int ServerToTitaniumBuffSlot(int index)
{
// we're a disc
if (index >= EQEmu::constants::LongBuffs + EQEmu::constants::ShortBuffs)
return index - EQEmu::constants::LongBuffs - EQEmu::constants::ShortBuffs +
constants::LongBuffs + constants::ShortBuffs;
// we're a song
if (index >= EQEmu::constants::LongBuffs)
return index - EQEmu::constants::LongBuffs + constants::LongBuffs;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}
static inline int TitaniumToServerBuffSlot(int index)
{
// we're a disc
if (index >= constants::LongBuffs + constants::ShortBuffs)
return index - constants::LongBuffs - constants::ShortBuffs + EQEmu::constants::LongBuffs +
EQEmu::constants::ShortBuffs;
// we're a song
if (index >= constants::LongBuffs)
return index - constants::LongBuffs + EQEmu::constants::LongBuffs;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}
} /*Titanium*/
+8
View File
@@ -294,6 +294,14 @@ namespace Titanium
const size_t SayLinkBodySize = 45;
const int LongBuffs = 25;
const int ShortBuffs = 12;
const int DiscBuffs = 1;
const int TotalBuffs = LongBuffs + ShortBuffs + DiscBuffs;
const int NPCBuffs = 60;
const int PetBuffs = 30;
const int MercBuffs = 0;
} /*constants*/
namespace behavior {
+3 -3
View File
@@ -144,7 +144,7 @@ struct TintProfile {
Tint_Struct Primary;
Tint_Struct Secondary;
};
Tint_Struct Slot[EQEmu::textures::TextureCount];
Tint_Struct Slot[EQEmu::textures::materialCount];
};
};
@@ -167,7 +167,7 @@ struct TextureProfile
Texture_Struct Primary;
Texture_Struct Secondary;
};
Texture_Struct Slot[EQEmu::textures::TextureCount];
Texture_Struct Slot[EQEmu::textures::materialCount];
};
TextureProfile();
@@ -1420,7 +1420,7 @@ struct LootingItem_Struct {
/*002*/ uint32 looter;
/*004*/ uint16 slot_id;
/*006*/ uint8 unknown3[2];
/*008*/ uint32 auto_loot;
/*008*/ int32 auto_loot;
};
struct GuildManageStatus_Struct{
+57 -44
View File
@@ -29,7 +29,7 @@
#include "../eq_packet_structs.h"
#include "../misc_functions.h"
#include "../string_util.h"
#include "../item.h"
#include "../item_instance.h"
#include "uf_structs.h"
#include "../rulesys.h"
@@ -43,7 +43,7 @@ namespace UF
static OpcodeManager *opcodes = nullptr;
static Strategy struct_strategy;
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id, uint8 depth);
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id, uint8 depth);
// server to client inventory location converters
static inline uint32 ServerToUFSlot(uint32 serverSlot);
@@ -62,6 +62,9 @@ namespace UF
static inline CastingSlot ServerToUFCastingSlot(EQEmu::CastingSlot slot);
static inline EQEmu::CastingSlot UFToServerCastingSlot(CastingSlot slot);
static inline int ServerToUFBuffSlot(int index);
static inline int UFToServerBuffSlot(int index);
void Register(EQStreamIdentifier &into)
{
//create our opcode manager if we havent already
@@ -377,17 +380,8 @@ namespace UF
OUT(buff.spellid);
OUT(buff.duration);
OUT(buff.num_hits);
uint16 buffslot = emu->slotid;
if (buffslot >= 25 && buffslot < 37)
{
buffslot += 5;
}
else if (buffslot >= 37)
{
buffslot += 14;
}
// TODO: implement slot_data stuff
eq->slotid = buffslot;
eq->slotid = ServerToUFBuffSlot(emu->slotid);
OUT(bufffade); // Live (October 2011) sends a 2 rather than 0 when a buff is created, but it doesn't seem to matter.
FINISH_ENCODE();
@@ -407,17 +401,9 @@ namespace UF
__packet->WriteUInt8(emu->all_buffs); // 1 = all buffs, 0 = 1 buff
__packet->WriteUInt16(emu->count);
for (uint16 i = 0; i < emu->count; ++i)
for (int i = 0; i < emu->count; ++i)
{
uint16 buffslot = emu->entries[i].buff_slot;
if (emu->type == 0) { // only correct for self packets
if (emu->entries[i].buff_slot >= 25 && emu->entries[i].buff_slot < 37)
buffslot += 5;
else if (emu->entries[i].buff_slot >= 37)
buffslot += 14;
}
__packet->WriteUInt32(buffslot);
__packet->WriteUInt32(emu->type == 0 ? ServerToUFBuffSlot(emu->entries[i].buff_slot) : emu->entries[i].buff_slot);
__packet->WriteUInt32(emu->entries[i].spell_id);
__packet->WriteUInt32(emu->entries[i].tics_remaining);
__packet->WriteUInt32(emu->entries[i].num_hits);
@@ -541,7 +527,7 @@ namespace UF
ob.write((const char*)&item_count, sizeof(uint32));
for (int index = 0; index < item_count; ++index, ++eq) {
SerializeItem(ob, (const ItemInst*)eq->inst, eq->slot_id, 0);
SerializeItem(ob, (const EQEmu::ItemInstance*)eq->inst, eq->slot_id, 0);
if (ob.tellp() == last_pos)
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d during OP_CharInventory. Item skipped.", eq->slot_id);
@@ -1293,7 +1279,7 @@ namespace UF
ob.write((const char*)__emu_buffer, 4);
SerializeItem(ob, (const ItemInst*)int_struct->inst, int_struct->slot_id, 0);
SerializeItem(ob, (const EQEmu::ItemInstance*)int_struct->inst, int_struct->slot_id, 0);
if (ob.tellp() == last_pos) {
Log.Out(Logs::General, Logs::Netcode, "[STRUCTS] Serialization failed on item slot %d.", int_struct->slot_id);
delete in;
@@ -1817,7 +1803,7 @@ namespace UF
OUT(hairstyle);
OUT(beard);
// OUT(unknown00178[10]);
for (r = EQEmu::textures::TextureBegin; r < EQEmu::textures::TextureCount; r++) {
for (r = EQEmu::textures::textureBegin; r < EQEmu::textures::materialCount; r++) {
eq->equipment.Slot[r].Material = emu->item_material.Slot[r].Material;
eq->equipment.Slot[r].Unknown1 = 0;
eq->equipment.Slot[r].EliteMaterial = 0;
@@ -2301,10 +2287,10 @@ namespace UF
eq_cse->HairColor = emu_cse->HairColor;
eq_cse->Face = emu_cse->Face;
for (int equip_index = 0; equip_index < EQEmu::textures::TextureCount; equip_index++) {
for (int equip_index = EQEmu::textures::textureBegin; equip_index < EQEmu::textures::materialCount; equip_index++) {
eq_cse->Equip[equip_index].Material = emu_cse->Equip[equip_index].Material;
eq_cse->Equip[equip_index].Unknown1 = emu_cse->Equip[equip_index].Unknown1;
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteMaterial;
eq_cse->Equip[equip_index].EliteMaterial = emu_cse->Equip[equip_index].EliteModel;
eq_cse->Equip[equip_index].Color = emu_cse->Equip[equip_index].Color;
}
@@ -2869,7 +2855,7 @@ namespace UF
float SpawnSize = emu->size;
if (!((emu->NPC == 0) || (emu->race <= 12) || (emu->race == 128) || (emu->race == 130) || (emu->race == 330) || (emu->race == 522)))
{
PacketSize -= (sizeof(structs::Texture_Struct) * EQEmu::textures::TextureCount);
PacketSize -= (sizeof(structs::Texture_Struct) * EQEmu::textures::materialCount);
if (emu->size == 0)
{
@@ -3068,7 +3054,7 @@ namespace UF
if ((emu->NPC == 0) || (emu->race <= 12) || (emu->race == 128) || (emu->race == 130) || (emu->race == 330) || (emu->race == 522))
{
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; ++k)
for (k = EQEmu::textures::textureBegin; k < EQEmu::textures::materialCount; ++k)
{
{
VARSTRUCT_ENCODE_TYPE(uint32, Buffer, emu->equipment_tint.Slot[k].Color);
@@ -3104,17 +3090,17 @@ namespace UF
{
structs::Texture_Struct *Equipment = (structs::Texture_Struct *)Buffer;
for (k = EQEmu::textures::TextureBegin; k < EQEmu::textures::TextureCount; k++) {
for (k = EQEmu::textures::textureBegin; k < EQEmu::textures::materialCount; k++) {
if (emu->equipment.Slot[k].Material > 99999) {
Equipment[k].Material = 63;
} else {
Equipment[k].Material = emu->equipment.Slot[k].Material;
}
Equipment[k].Unknown1 = emu->equipment.Slot[k].Unknown1;
Equipment[k].EliteMaterial = emu->equipment.Slot[k].EliteMaterial;
Equipment[k].EliteMaterial = emu->equipment.Slot[k].EliteModel;
}
Buffer += (sizeof(structs::Texture_Struct) * EQEmu::textures::TextureCount);
Buffer += (sizeof(structs::Texture_Struct) * EQEmu::textures::materialCount);
}
if (strlen(emu->title))
{
@@ -3236,6 +3222,7 @@ namespace UF
IN(buff.unknown003);
IN(buff.spellid);
IN(buff.duration);
emu->slotid = UFToServerBuffSlot(eq->slotid);
IN(slotid);
IN(bufffade);
@@ -3249,7 +3236,7 @@ namespace UF
DECODE_LENGTH_EXACT(structs::BuffRemoveRequest_Struct);
SETUP_DIRECT_DECODE(BuffRemoveRequest_Struct, structs::BuffRemoveRequest_Struct);
emu->SlotID = (eq->SlotID < 30) ? eq->SlotID : (eq->SlotID - 5);
emu->SlotID = UFToServerBuffSlot(eq->SlotID);
IN(EntityID);
@@ -3847,9 +3834,9 @@ namespace UF
return NextItemInstSerialNumber;
}
void SerializeItem(EQEmu::OutBuffer& ob, const ItemInst *inst, int16 slot_id_in, uint8 depth)
void SerializeItem(EQEmu::OutBuffer& ob, const EQEmu::ItemInstance *inst, int16 slot_id_in, uint8 depth)
{
const EQEmu::ItemBase *item = inst->GetUnscaledItem();
const EQEmu::ItemData *item = inst->GetUnscaledItem();
UF::structs::ItemSerializationHeader hdr;
@@ -3893,7 +3880,7 @@ namespace UF
int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
uint16 ornaIcon = 0;
if (inst->GetOrnamentationAug(ornamentationAugtype)) {
const EQEmu::ItemBase *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
const EQEmu::ItemData *aug_weap = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
ornaIcon = aug_weap->Icon;
ob.write(aug_weap->IDFile, strlen(aug_weap->IDFile));
@@ -4224,18 +4211,18 @@ namespace UF
ob.write((const char*)&subitem_count, sizeof(uint32));
for (uint32 index = SUB_INDEX_BEGIN; index < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++index) {
ItemInst* sub = inst->GetItem(index);
for (uint32 index = EQEmu::inventory::containerBegin; index < EQEmu::inventory::ContainerCount; ++index) {
EQEmu::ItemInstance* sub = inst->GetItem(index);
if (!sub)
continue;
int SubSlotNumber = INVALID_INDEX;
if (slot_id_in >= EQEmu::legacy::GENERAL_BEGIN && slot_id_in <= EQEmu::legacy::GENERAL_END)
SubSlotNumber = (((slot_id_in + 3) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + index + 1);
SubSlotNumber = (((slot_id_in + 3) * EQEmu::inventory::ContainerCount) + index + 1);
else if (slot_id_in >= EQEmu::legacy::BANK_BEGIN && slot_id_in <= EQEmu::legacy::BANK_END)
SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::BANK_BAGS_BEGIN + index);
SubSlotNumber = (((slot_id_in - EQEmu::legacy::BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::BANK_BAGS_BEGIN + index);
else if (slot_id_in >= EQEmu::legacy::SHARED_BANK_BEGIN && slot_id_in <= EQEmu::legacy::SHARED_BANK_END)
SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::legacy::ITEM_CONTAINER_SIZE) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index);
SubSlotNumber = (((slot_id_in - EQEmu::legacy::SHARED_BANK_BEGIN) * EQEmu::inventory::ContainerCount) + EQEmu::legacy::SHARED_BANK_BAGS_BEGIN + index);
else
SubSlotNumber = slot_id_in;
@@ -4253,7 +4240,7 @@ namespace UF
{
uint32 UnderfootSlot = 0;
if (serverSlot >= EQEmu::legacy::SlotAmmo && serverSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots
if (serverSlot >= EQEmu::inventory::slotAmmo && serverSlot <= 53) // Cursor/Ammo/Power Source and Normal Inventory Slots
UnderfootSlot = serverSlot + 1;
else if (serverSlot >= EQEmu::legacy::GENERAL_BAGS_BEGIN && serverSlot <= EQEmu::legacy::CURSOR_BAG_END)
UnderfootSlot = serverSlot + 11;
@@ -4261,7 +4248,7 @@ namespace UF
UnderfootSlot = serverSlot + 1;
else if (serverSlot >= EQEmu::legacy::SHARED_BANK_BAGS_BEGIN && serverSlot <= EQEmu::legacy::SHARED_BANK_BAGS_END)
UnderfootSlot = serverSlot + 1;
else if (serverSlot == EQEmu::legacy::SlotPowerSource)
else if (serverSlot == EQEmu::inventory::slotPowerSource)
UnderfootSlot = invslot::PossessionsPowerSource;
else
UnderfootSlot = serverSlot;
@@ -4288,7 +4275,7 @@ namespace UF
else if (ufSlot >= invbag::SharedBankBagsBegin && ufSlot <= invbag::SharedBankBagsEnd)
ServerSlot = ufSlot - 1;
else if (ufSlot == invslot::PossessionsPowerSource)
ServerSlot = EQEmu::legacy::SlotPowerSource;
ServerSlot = EQEmu::inventory::slotPowerSource;
else
ServerSlot = ufSlot;
@@ -4453,4 +4440,30 @@ namespace UF
return EQEmu::CastingSlot::Discipline;
}
}
static inline int ServerToUFBuffSlot(int index)
{
// we're a disc
if (index >= EQEmu::constants::LongBuffs + EQEmu::constants::ShortBuffs)
return index - EQEmu::constants::LongBuffs - EQEmu::constants::ShortBuffs +
constants::LongBuffs + constants::ShortBuffs;
// we're a song
if (index >= EQEmu::constants::LongBuffs)
return index - EQEmu::constants::LongBuffs + constants::LongBuffs;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}
static inline int UFToServerBuffSlot(int index)
{
// we're a disc
if (index >= constants::LongBuffs + constants::ShortBuffs)
return index - constants::LongBuffs - constants::ShortBuffs + EQEmu::constants::LongBuffs +
EQEmu::constants::ShortBuffs;
// we're a song
if (index >= constants::LongBuffs)
return index - constants::LongBuffs + EQEmu::constants::LongBuffs;
// we're a normal buff
return index; // as long as we guard against bad slots server side, we should be fine
}
} /*UF*/
+24 -16
View File
@@ -64,7 +64,7 @@ namespace UF
InvTypeOther,
InvTypeCount
};
} /*invtype*/
namespace invslot {
@@ -115,21 +115,21 @@ namespace UF
const int GeneralBegin = PossessionsGeneral1;
const int GeneralEnd = PossessionsGeneral8;
const int GeneralCount = (GeneralEnd - GeneralBegin + 1);
} /*invslot*/
namespace invbag {
inline EQEmu::versions::ClientVersion GetInvBagRef() { return EQEmu::versions::ClientVersion::UF; }
enum : int { InvBagInvalid = -1, InvBagBegin };
} /*invbag*/
namespace invaug {
inline EQEmu::versions::ClientVersion GetInvAugRef() { return EQEmu::versions::ClientVersion::UF; }
enum : int { InvAugInvalid = -1, InvAugBegin };
} /*invaug*/
namespace item {
@@ -148,27 +148,27 @@ namespace UF
ItemPacketCharmUpdate = 110,
ItemPacket11 = 111
};
} /*item*/
namespace profile {
inline EQEmu::versions::ClientVersion GetProfileRef() { return EQEmu::versions::ClientVersion::UF; }
} /*profile*/
namespace constants {
inline EQEmu::versions::ClientVersion GetConstantsRef() { return EQEmu::versions::ClientVersion::UF; }
} /*constants*/
namespace behavior {
inline EQEmu::versions::ClientVersion GetBehaviorRef() { return EQEmu::versions::ClientVersion::UF; }
} /*behavior*/
namespace skills {
inline EQEmu::versions::ClientVersion GetSkillsRef() { return EQEmu::versions::ClientVersion::UF; }
} /*skills*/
@@ -208,7 +208,7 @@ namespace UF
extern const char* GetInvTypeName(int inv_type);
extern bool IsInvTypePersistent(int inv_type);
} /*invtype*/
namespace invslot {
@@ -237,7 +237,7 @@ namespace UF
extern const char* GetInvPossessionsSlotName(int inv_slot);
extern const char* GetInvCorpseSlotName(int inv_slot);
extern const char* GetInvSlotName(int inv_type, int inv_slot);
} /*invslot*/
namespace invbag {
@@ -264,7 +264,7 @@ namespace UF
const int TradeBagsEnd = (TradeBagsBegin + TradeBagsSize) - 1;
extern const char* GetInvBagIndexName(int bag_index);
} /*invbag*/
namespace invaug {
@@ -288,24 +288,32 @@ namespace UF
const size_t PotionBeltSize = 5;
const size_t SkillArraySize = 100;
} /*profile*/
namespace constants {
const size_t CharacterCreationLimit = 12;
const size_t SayLinkBodySize = 50;
const int LongBuffs = 30;
const int ShortBuffs = 20;
const int DiscBuffs = 1;
const int TotalBuffs = LongBuffs + ShortBuffs + DiscBuffs;
const int NPCBuffs = 85;
const int PetBuffs = NPCBuffs;
const int MercBuffs = LongBuffs;
} /*constants*/
namespace behavior {
const bool CoinHasWeight = false;
} /*behavior*/
namespace skills {
const size_t LastUsableSkill = EQEmu::skills::SkillTripleAttack;
} /*skills*/
}; /*UF*/
+5 -5
View File
@@ -149,7 +149,7 @@ struct TintProfile
Tint_Struct Primary;
Tint_Struct Secondary;
};
Tint_Struct Slot[EQEmu::textures::TextureCount];
Tint_Struct Slot[EQEmu::textures::materialCount];
};
};
@@ -178,7 +178,7 @@ struct TextureProfile
Texture_Struct Primary;
Texture_Struct Secondary;
};
Texture_Struct Slot[EQEmu::textures::TextureCount];
Texture_Struct Slot[EQEmu::textures::materialCount];
};
TextureProfile();
@@ -195,7 +195,7 @@ struct CharacterSelectEntry_Struct
/*0000*/ uint8 Beard; //
/*0001*/ uint8 HairColor; //
/*0000*/ uint8 Face; //
/*0000*/ CharSelectEquip Equip[EQEmu::textures::TextureCount];
/*0000*/ CharSelectEquip Equip[EQEmu::textures::materialCount];
/*0000*/ uint32 PrimaryIDFile; //
/*0000*/ uint32 SecondaryIDFile; //
/*0000*/ uint8 Unknown15; // 0xff
@@ -1707,7 +1707,7 @@ struct LootingItem_Struct {
/*000*/ uint32 lootee;
/*004*/ uint32 looter;
/*008*/ uint32 slot_id;
/*012*/ uint32 auto_loot;
/*012*/ int32 auto_loot;
/*016*/ uint32 unknown16;
/*020*/
};
@@ -2011,7 +2011,7 @@ struct AdventureLeaderboard_Struct
/*struct Item_Shop_Struct {
uint16 merchantid;
uint8 itemtype;
ItemBase item;
ItemData item;
uint8 iss_unknown001[6];
};*/
+1316 -43
View File
File diff suppressed because it is too large Load Diff
+735
View File
@@ -113,6 +113,741 @@
#define PLAYER_RACE_ALL_MASK 65535
#define RT_ABHORRENT 193
#define RT_AIR_ELEMENTAL 210
#define RT_AIR_ELEMENTAL_2 475
#define RT_AIR_MEPHIT 291
#define RT_AKHEVA 230
#define RT_AKHEVA_2 722
#define RT_ALARAN 695
#define RT_ALARAN_GHOST 708
#define RT_ALARAN_SENTRY_STONE 703
#define RT_ALLIGATOR 91
#define RT_ALLIGATOR_2 479
#define RT_AMYGDALAN 99
#define RT_AMYGDALAN_2 663
#define RT_ANEUK 395
#define RT_ANIMATED_ARMOR 323
#define RT_ANIMATED_HAND 166
#define RT_ANIMATED_STATUE 442
#define RT_ANIMATED_STATUE_2 448
#define RT_APEXUS 637
#define RT_ARACHNID 326
#define RT_ARCANIST_OF_HATE 352
#define RT_ARMADILLO 87
#define RT_ARMOR_RACK 535
#define RT_AVIAK 13
#define RT_AVIAK_2 558
#define RT_AVIAK_PULL_ALONG 711
#define RT_AYONAE_RO 498
#define RT_BANNER 500
#define RT_BANNER_2 553
#define RT_BANNER_3 554
#define RT_BANNER_4 555
#define RT_BANNER_5 556
#define RT_BANNER_6 557
#define RT_BANNER_7 586
#define RT_BANNER_10TH_ANNIVERSARY 628
#define RT_BANSHEE 250
#define RT_BANSHEE_2 487
#define RT_BANSHEE_3 488
#define RT_BARBARIAN 2
#define RT_BARBARIAN_2 90
#define RT_BARREL 377
#define RT_BARREL_BARGE_SHIP 546
#define RT_BASILISK 436
#define RT_BAT 34
#define RT_BAT_2 260
#define RT_BAT_3 416
#define RT_BAZU 409
#define RT_BEAR 43
#define RT_BEAR_2 305
#define RT_BEAR_3 480
#define RT_BEAR_MOUNT 655
#define RT_BEAR_TRAP 503
#define RT_BEETLE 22
#define RT_BEETLE_2 559
#define RT_BEETLE_3 716
#define RT_BEGGAR 55
#define RT_BELLIKOS 638
#define RT_BERTOXXULOUS 152
#define RT_BERTOXXULOUS_2 255
#define RT_BIXIE 79
#define RT_BIXIE_2 520
#define RT_BLIMP_SHIP 693
#define RT_BLIND_DREAMER 669
#define RT_BLOOD_RAVEN 279
#define RT_BOAT 141
#define RT_BOAT_2 533
#define RT_BOLVIRK 486
#define RT_BONE_GOLEM 362
#define RT_BONE_GOLEM_2 491
#define RT_BONES 383
#define RT_BOOK_DERVISH 660
#define RT_BOT_PORTAL 329
#define RT_BOULDER 585
#define RT_BOX 376
#define RT_BRAXI 688
#define RT_BRAXI_MOUNT 676
#define RT_BRELL 640
#define RT_BRELLS_FIRST_CREATION 639
#define RT_BRISTLEBANE 153
#define RT_BROKEN_CLOCKWORK 274
#define RT_BRONTOTHERIUM 169
#define RT_BROWNIE 15
#define RT_BROWNIE_2 568
#define RT_BUBONIAN 268
#define RT_BUBONIAN_UNDERLING 269
#define RT_BURYNAI 144
#define RT_BURYNAI_2 602
#define RT_CAKE_10TH_ANNIVERSARY 629
#define RT_CAMPFIRE 567
#define RT_CARRIER_HAND 721
#define RT_CAT 713
#define RT_CAZIC_THULE 95
#define RT_CAZIC_THULE_2 670
#define RT_CENTAUR 16
#define RT_CENTAUR_2 521
#define RT_CHEST 378
#define RT_CHEST_2 589
#define RT_CHEST_3 590
#define RT_CHIMERA 412
#define RT_CHIMERA_2 582
#define RT_CHOKIDAI 356
#define RT_CLAM 115
#define RT_CLIKNAR_MOUNT 652
#define RT_CLIKNAR_QUEEN 642
#define RT_CLIKNAR_SOLDIER 643
#define RT_CLIKNAR_WORKER 644
#define RT_CLOCKWORK_BEETLE 276
#define RT_CLOCKWORK_BOAR 472
#define RT_CLOCKWORK_BOMB 504
#define RT_CLOCKWORK_BRAIN 249
#define RT_CLOCKWORK_GNOME 88
#define RT_CLOCKWORK_GOLEM 248
#define RT_CLOCKWORK_GUARDIAN 572
#define RT_COCKATRICE 96
#define RT_COFFIN 382
#define RT_COFFIN_2 592
#define RT_COIN_PURSE 427
#define RT_COLDAIN 183
#define RT_COLDAIN_2 645
#define RT_COLDAIN_3 646
#define RT_CORAL 460
#define RT_CORATHUS 459
#define RT_CRAB 302
#define RT_CRAGBEAST 390
#define RT_CRAGSLITHER 597
#define RT_CROCODILE 259
#define RT_CRYSTAL 591
#define RT_CRYSTAL_SHARD 425
#define RT_CRYSTAL_SPHERE 616
#define RT_CRYSTAL_SPIDER 327
#define RT_CRYSTALSKIN_AMBULOID 641
#define RT_CRYSTALSKIN_SESSILOID 647
#define RT_DAISY_MAN 97
#define RT_DARK_ELF 6
#define RT_DARK_ELF_2 77
#define RT_DARK_LORD 466
#define RT_DEMI_LICH 45
#define RT_DEMON_VULTURE 620
#define RT_DERVISH 100
#define RT_DERVISH_2 372
#define RT_DERVISH_3 431
#define RT_DERVISH_4 704
#define RT_DERVISH_VER_5 726
#define RT_DERVISH_VER_6 727
#define RT_DEVOURER 159
#define RT_DIRE_WOLF 171
#define RT_DISCORD_SHIP 404
#define RT_DISCORDLING 418
#define RT_DISEASED_FIEND 253
#define RT_DJINN 126
#define RT_DRACHNID 57
#define RT_DRACHNID_2 461
#define RT_DRACHNID_COCOON 462
#define RT_DRACOLICH 604
#define RT_DRAGLOCK 132
#define RT_DRAGON 49
#define RT_DRAGON_2 122
#define RT_DRAGON_3 165
#define RT_DRAGON_4 184
#define RT_DRAGON_5 192
#define RT_DRAGON_6 195
#define RT_DRAGON_7 196
#define RT_DRAGON_8 198
#define RT_DRAGON_9 304
#define RT_DRAGON_10 435
#define RT_DRAGON_11 437
#define RT_DRAGON_12 438
#define RT_DRAGON_13 452
#define RT_DRAGON_14 530
#define RT_DRAGON_15 531
#define RT_DRAGON_16 569
#define RT_DRAGON_BONES 423
#define RT_DRAGON_EGG 445
#define RT_DRAGON_STATUE 446
#define RT_DRAGORN 413
#define RT_DRAGORN_BOX 421
#define RT_DRAKE 89
#define RT_DRAKE_2 430
#define RT_DRAKE_3 432
#define RT_DRAKKIN 522
#define RT_DRIXIE 113
#define RT_DROGMORE 348
#define RT_DROLVARG 133
#define RT_DRYAD 243
#define RT_DWARF 8
#define RT_DWARF_2 94
#define RT_DYNAMITE_KEG 505
#define RT_DYNLETH 532
#define RT_EARTH_ELEMENTAL 209
#define RT_EARTH_ELEMENTAL_2 476
#define RT_EARTH_MEPHIT 292
#define RT_EEL 35
#define RT_EFREETI 101
#define RT_EFREETI_2 320
#define RT_ELDDAR 489
#define RT_ELEMENTAL 75
#define RT_ELK_HEAD 714
#define RT_ELVEN_BOAT 544
#define RT_ELVEN_GHOST 587
#define RT_ENCHANTED_ARMOR 175
#define RT_EROLLISI 150
#define RT_ERUDITE 3
#define RT_ERUDITE_2 78
#define RT_ERUDITE_3 678
#define RT_EVAN_TEST 204
#define RT_EVIL_EYE 21
#define RT_EVIL_EYE_2 375
#define RT_EVIL_EYE_3 469
#define RT_EXOSKELETON 570
#define RT_EXPLOSIVE_CART 692
#define RT_EYE 108
#define RT_FAIRY 25
#define RT_FAIRY_2 473
#define RT_FALLEN_KNIGHT 719
#define RT_FAUN 182
#define RT_FAY_DRAKE 154
#define RT_FENNIN_RO 284
#define RT_FERAN 410
#define RT_FERAN_MOUNT 623
#define RT_FIEND 300
#define RT_FIRE_ELEMENTAL 212
#define RT_FIRE_ELEMENTAL_2 477
#define RT_FIRE_MEPHIT 293
#define RT_FISH 24
#define RT_FISH_2 148
#define RT_FLAG 501
#define RT_FLOATING_ISLAND 596
#define RT_FLOATING_SKULL 512
#define RT_FLOATING_TOWER 691
#define RT_FLY 245
#define RT_FLYING_CARPET 720
#define RT_FOREST_GIANT 490
#define RT_FROG 343
#define RT_FROG_2 603
#define RT_FROGLOK 26
#define RT_FROGLOK_2 27
#define RT_FROGLOK_3 330
#define RT_FROGLOK_GHOST 371
#define RT_FROGLOK_SKELETON 349
#define RT_FUNGAL_FIEND 218
#define RT_FUNGUS_PATCH 463
#define RT_FUNGUSMAN 28
#define RT_GALORIAN 228
#define RT_GARGOYLE 29
#define RT_GARGOYLE_2 464
#define RT_GASBAG 30
#define RT_GELATINOUS_CUBE 31
#define RT_GELATINOUS_CUBE_2 712
#define RT_GELIDRAN 417
#define RT_GENARI 648
#define RT_GEONID 178
#define RT_GHOST 32
#define RT_GHOST_2 117
#define RT_GHOST_3 118
#define RT_GHOST_4 334
#define RT_GHOST_SHIP 114
#define RT_GHOST_SHIP_2 552
#define RT_GHOUL 33
#define RT_GHOUL_2 571
#define RT_GIANT 18
#define RT_GIANT_2 140
#define RT_GIANT_3 188
#define RT_GIANT_4 189
#define RT_GIANT_5 306
#define RT_GIANT_6 307
#define RT_GIANT_7 308
#define RT_GIANT_8 309
#define RT_GIANT_9 310
#define RT_GIANT_10 311
#define RT_GIANT_11 312
#define RT_GIANT_12 453
#define RT_GIANT_13 523
#define RT_GIANT_CLOCKWORK 275
#define RT_GIANT_RALLOSIAN_MATS 626
#define RT_GIANT_SHADE 526
#define RT_GIGYN 649
#define RT_GINGERBREAD_MAN 666
#define RT_GIRPLAN 419
#define RT_GNOLL 39
#define RT_GNOLL_2 524
#define RT_GNOLL_3 617
#define RT_GNOME 12
#define RT_GNOMEWORK 457
#define RT_GNOMISH_BALLOON 683
#define RT_GNOMISH_BOAT 545
#define RT_GNOMISH_HOVERING_TRANSPORT 685
#define RT_GNOMISH_ROCKET_PACK 684
#define RT_GOBLIN 40
#define RT_GOBLIN_2 59
#define RT_GOBLIN_3 137
#define RT_GOBLIN_4 369
#define RT_GOBLIN_5 433
#define RT_GOD_LUCLIN_VER_2 728
#define RT_GOD_LUCLIN_VER_3 729
#define RT_GOD_LUCLIN_VER_4 731
#define RT_GOD_OF_DISCORD 622
#define RT_GOLEM 17
#define RT_GOLEM_2 374
#define RT_GOO 145
#define RT_GOO_2 547
#define RT_GOO_3 548
#define RT_GOO_4 549
#define RT_GORAL 687
#define RT_GORAL_MOUNT 673
#define RT_GORGON 121
#define RT_GORILLA 41
#define RT_GORILLA_2 560
#define RT_GRANDFATHER_CLOCK 665
#define RT_GREKEN_YOUNG 651
#define RT_GREKEN_YOUNG_ADULT 650
#define RT_GRENDLAEN 701
#define RT_GRIEG_VENEFICUS 231
#define RT_GRIFFIN 47
#define RT_GRIFFIN_2 525
#define RT_GRIMLING 202
#define RT_GROUND_SHAKER 233
#define RT_GUARD 44
#define RT_GUARD_2 106
#define RT_GUARD_3 112
#define RT_GUARD_4 239
#define RT_GUARD_OF_JUSTICE 251
#define RT_GUARDIAN_CPU 593
#define RT_HADAL 698
#define RT_HAG 185
#define RT_HALF_ELF 7
#define RT_HALFLING 11
#define RT_HALFLING_2 81
#define RT_HARPY 111
#define RT_HARPY_2 527
#define RT_HIGH_ELF 5
#define RT_HIPPOGRIFF 186
#define RT_HOLGRESH 168
#define RT_HOLGRESH_2 715
#define RT_HONEY_POT 536
#define RT_HORSE 216
#define RT_HORSE_2 492
#define RT_HORSE_3 518
#define RT_HOVERING_PLATFORM 699
#define RT_HRAQUIS 261
#define RT_HUMAN 1
#define RT_HUMAN_2 67
#define RT_HUMAN_3 71
#define RT_HUMAN_4 566
#define RT_HUMAN_GHOST 588
#define RT_HUVUL 400
#define RT_HYDRA_CRYSTAL 615
#define RT_HYDRA_MOUNT 631
#define RT_HYDRA_NPC 632
#define RT_HYNID 388
#define RT_ICE_SPECTRE 174
#define RT_IKAAV 394
#define RT_IKSAR 128
#define RT_IKSAR_2 139
#define RT_IKSAR_GHOST 605
#define RT_IKSAR_GOLEM 160
#define RT_IKSAR_SKELETON 606
#define RT_IKSAR_SPIRIT 147
#define RT_IMP 46
#define RT_INNORUUK 123
#define RT_INSECT 370
#define RT_INTERACTIVE_OBJECT 2250
#define RT_INVISIBLE_MAN 127
#define RT_INVISIBLE_MAN_2 681
#define RT_INVISIBLE_MAN_3 690
#define RT_INVISIBLE_MAN_OF_ZOMM 600
#define RT_IXT 393
#define RT_JOKESTER 384
#define RT_JUM_JUM_BUCKET 537
#define RT_JUNK_BEAST 273
#define RT_KANGON 689
#define RT_KANGON_MOUNT 677
#define RT_KARANA 278
#define RT_KEDGE 103
#define RT_KEDGE_2 561
#define RT_KERRAN 23
#define RT_KERRAN_2 562
#define RT_KIRIN 434
#define RT_KIRIN_2 583
#define RT_KNIGHT_OF_HATE 351
#define RT_KNIGHT_OF_PESTILENCE 266
#define RT_KOBOLD 48
#define RT_KOBOLD_2 455
#define RT_KRAKEN 315
#define RT_KYV 396
#define RT_LAUNCH 73
#define RT_LAVA_ROCK 447
#define RT_LAVA_SPIDER 450
#define RT_LAVA_SPIDER_QUEEN 451
#define RT_LEECH 104
#define RT_LEPERTOLOTH 267
#define RT_LIGHTCRAWLER 223
#define RT_LIGHTNING_WARRIOR 407
#define RT_LION 50
#define RT_LIZARD_MAN 51
#define RT_LUCLIN 724
#define RT_LUGGALD 345
#define RT_LUGGALD_2 346
#define RT_LUGGALDS 347
#define RT_MALARIAN 265
#define RT_MAMMOTH 107
#define RT_MAMMOTH_2 528
#define RT_MAN_EATING_PLANT 162
#define RT_MANSION 595
#define RT_MANTICORE 172
#define RT_MANTRAP 573
#define RT_MARIONETTE 659
#define RT_MASTRUQ 402
#define RT_MATA_MURAM 406
#define RT_MEDIUM_PLANT 541
#define RT_MEPHIT 607
#define RT_MERCHANT_SHIP 550
#define RT_MERMAID 110
#define RT_MIMIC 52
#define RT_MINI_POM 252
#define RT_MINOTAUR 53
#define RT_MINOTAUR_2 420
#define RT_MINOTAUR_3 470
#define RT_MINOTAUR_4 574
#define RT_MITHANIEL_MARR 296
#define RT_MORELL_THULE 658
#define RT_MOSQUITO 134
#define RT_MOUTH_OF_INSANITY 281
#define RT_MUDDITE 608
#define RT_MUMMY 368
#define RT_MURAMITE_ARMOR_PILE 424
#define RT_MURKGLIDER 414
#define RT_MURKGLIDER_EGG_SAC 429
#define RT_MUTNA 401
#define RT_NEKHON 614
#define RT_NETHERBIAN 229
#define RT_NIGHTMARE 287
#define RT_NIGHTMARE_GARGOYLE 280
#define RT_NIGHTMARE_GOBLIN 277
#define RT_NIGHTMARE_MEPHIT 294
#define RT_NIGHTMARE_UNICORN 517
#define RT_NIGHTMARE_UNICORN_2 519
#define RT_NIGHTMARE_WRAITH 264
#define RT_NIHIL 385
#define RT_NILBORIEN 317
#define RT_NOC 397
#define RT_NYMPH 242
#define RT_OGRE 10
#define RT_OGRE_2 93
#define RT_OGRE_NPC_MALE 624
#define RT_ORB 730
#define RT_ORC 54
#define RT_ORC_2 458
#define RT_OTHMIR 190
#define RT_OWLBEAR 206
#define RT_PARASITIC_SCAVENGER 700
#define RT_PEGASUS 125
#define RT_PEGASUS_2 493
#define RT_PEGASUS_3 732
#define RT_PHOENIX 303
#define RT_PIRANHA 74
#define RT_PIRATE 335
#define RT_PIRATE_2 336
#define RT_PIRATE_3 337
#define RT_PIRATE_4 338
#define RT_PIRATE_5 339
#define RT_PIRATE_6 340
#define RT_PIRATE_7 341
#define RT_PIRATE_8 342
#define RT_PIRATE_SHIP 551
#define RT_PIXIE 56
#define RT_POISON_FROG 316
#define RT_PORTAL 426
#define RT_POWDER_KEG 636
#define RT_PRESSURE_PLATE 506
#define RT_PUFFER_SPORE 507
#define RT_PUMA 76
#define RT_PUMA_2 439
#define RT_PUMA_3 584
#define RT_PUSLING 270
#define RT_PYRILEN 411
#define RT_RA_TUK 398
#define RT_RABBIT 668
#define RT_RALLOS_ZEK 66
#define RT_RALLOS_ZEK_2 288
#define RT_RALLOS_ZEK_MINION 325
#define RT_RAPTOR 163
#define RT_RAPTOR_2 609
#define RT_RAPTOR_MOUNT 680
#define RT_RAT 36
#define RT_RAT_2 415
#define RT_RAT_MOUNT 656
#define RT_RATMAN 156
#define RT_RATMAN_2 718
#define RT_REANIMATED_HAND 80
#define RT_RECUSO 237
#define RT_REGENERATION_POOL 705
#define RT_RELIC_CASE 707
#define RT_RHINO_BEETLE 207
#define RT_RHINOCEROS 135
#define RT_ROBOCOPTER_OF_ZOMM 601
#define RT_ROCK_PILE 428
#define RT_ROCKHOPPER 200
#define RT_RONNIE_TEST 197
#define RT_ROOT_TENTACLE 509
#define RT_ROT_DOG_MOUNT 672
#define RT_ROTDOG 662
#define RT_ROTOCOPTER 577
#define RT_ROWBOAT 502
#define RT_ROYAL_GUARD 667
#define RT_RUJARKIAN_ORC 361
#define RT_RUJARKIAN_ORC_2 366
#define RT_RUNED_ORB 422
#define RT_RUNIC_SYMBOL 510
#define RT_SABER_TOOTHED_CAT 119
#define RT_SALTPETTER_BOMB 511
#define RT_SAND_ELF 364
#define RT_SANDMAN 664
#define RT_SARNAK 131
#define RT_SARNAK_2 610
#define RT_SARNAK_GOLEM 164
#define RT_SARNAK_SPIRIT 146
#define RT_SARYRN 283
#define RT_SATYR 529
#define RT_SCALED_WOLF 481
#define RT_SCARECROW 82
#define RT_SCARECROW_2 575
#define RT_SCARLET_CHEETAH 221
#define RT_SCLERA_MOUNT 675
#define RT_SCORPION 129
#define RT_SCORPION_2 149
#define RT_SCORPION_3 611
#define RT_SCRYKIN 495
#define RT_SEA_TURTLE 194
#define RT_SEAHORSE 116
#define RT_SELYRAH 686
#define RT_SELYRAH_MOUNT 674
#define RT_SERU 236
#define RT_SERVANT_OF_SHADOW 723
#define RT_SESSILOID_MOUNT 657
#define RT_SHADE 224
#define RT_SHADE_2 373
#define RT_SHADE_3 576
#define RT_SHADEL 205
#define RT_SHAMBLING_MOUND 494
#define RT_SHARK 61
#define RT_SHIKNAR 199
#define RT_SHILISKIN 467
#define RT_SHIP 72
#define RT_SHIP_IN_A_BOTTLE 702
#define RT_SHISSAR 217
#define RT_SHISSAR_2 563
#define RT_SHRIEKER 227
#define RT_SIREN 187
#define RT_SIREN_2 564
#define RT_SKELETAL_HORSE 282
#define RT_SKELETON 60
#define RT_SKELETON_2 367
#define RT_SKELETON_3 484
#define RT_SKUNK 83
#define RT_SKYSTRIDER 709
#define RT_SMALL_PLANT 540
#define RT_SNAKE 37
#define RT_SNAKE_2 468
#define RT_SNAKE_ELEMENTAL 84
#define RT_SNOW_DERVISH 170
#define RT_SNOW_RABBIT 176
#define RT_SOKOKAR 618
#define RT_SOKOKAR_MOUNT 625
#define RT_SOKOKAR_W_SADDLE 627
#define RT_SOLUSEK_RO 58
#define RT_SOLUSEK_RO_2 247
#define RT_SOLUSEK_RO_GUARD 254
#define RT_SONIC_WOLF 232
#define RT_SOUL_DEVOURER 286
#define RT_SPECTRE 85
#define RT_SPECTRE_2 485
#define RT_SPELL_PARTICLE_1 599
#define RT_SPHINX 86
#define RT_SPHINX_2 565
#define RT_SPIDER 38
#define RT_SPIDER_2 440
#define RT_SPIDER_EGG_SACK 449
#define RT_SPIDER_MOUNT 654
#define RT_SPIDER_QUEEN 441
#define RT_SPIKE_TRAP 513
#define RT_SPIRIT_WOLF 483
#define RT_SPORALI 456
#define RT_STONE_JUG 539
#define RT_STONE_PYLON 619
#define RT_STONE_RING 508
#define RT_STONE_WORKER 387
#define RT_STONE_WORKER_2 405
#define RT_STONEGRABBER 220
#define RT_STONEMITE 391
#define RT_STORMRIDER 272
#define RT_SUCCUBUS 408
#define RT_SUCCULENT 167
#define RT_SULLON_ZEK 499
#define RT_SUN_REVENANT 226
#define RT_SUNFLOWER 225
#define RT_SWINETOR 696
#define RT_SWORDFISH 105
#define RT_SYNARCANA 363
#define RT_TABLE 380
#define RT_TADPOLE 102
#define RT_TAELOSIAN 403
#define RT_TALL_PLANT 542
#define RT_TALLON_ZEK 290
#define RT_TANETH 399
#define RT_TAREW_MARR 246
#define RT_TEGI 215
#define RT_TELEPORT_MAN 240
#define RT_TELEPORTATION_STAND 706
#define RT_TELMIRA 653
#define RT_TENTACLE_TERROR 68
#define RT_TENTACLE_TERROR_2 578
#define RT_TERRIS_THULE 257
#define RT_TEST_OBJECT 301
#define RT_THE_RATHE 298
#define RT_THE_TRIBUNAL 256
#define RT_THOUGHT_HORROR 214
#define RT_TIGER 63
#define RT_TIN_SOLDIER 263
#define RT_TOOLBOX 538
#define RT_TOPIARY_LION 661
#define RT_TOPIARY_LION_MOUNT 671
#define RT_TORMENTOR 285
#define RT_TOTEM 173
#define RT_TOTEM_2 514
#define RT_TRAKANON 19
#define RT_TRANQUILION 262
#define RT_TREANT 64
#define RT_TREANT_2 244
#define RT_TREANT_3 496
#define RT_TRIBUNAL 151
#define RT_TRIUMVIRATE 697
#define RT_TROLL 9
#define RT_TROLL_2 92
#define RT_TROLL_3 331
#define RT_TROLL_4 332
#define RT_TROLL_5 333
#define RT_TROLL_ZOMBIE 344
#define RT_TRUSIK 386
#define RT_TSETSIAN 612
#define RT_TUMBLEWEED 694
#define RT_TUNARE 62
#define RT_TUREPTA 389
#define RT_UKUN 392
#define RT_ULTHORK 191
#define RT_UNDEAD_CHOKIDAI 357
#define RT_UNDEAD_FOOTMAN 324
#define RT_UNDEAD_FROGLOK 350
#define RT_UNDEAD_IKSAR 161
#define RT_UNDEAD_KNIGHT 297
#define RT_UNDEAD_SARNAK 155
#define RT_UNDEAD_VEKSAR 358
#define RT_UNDERBULK 201
#define RT_UNICORN 124
#define RT_UNKNOWN_RACE 0
#define RT_UNKNOWN_RACE_2 142
#define RT_UNKNOWN_RACE_3 143
#define RT_UNKNOWN_RACE_4 179
#define RT_UNKNOWN_RACE_5 180
#define RT_UNKNOWN_RACE_6 443
#define RT_UNKNOWN_RACE_7 444
#define RT_VAH_SHIR 130
#define RT_VAH_SHIR_2 238
#define RT_VAH_SHIR_SKELETON 234
#define RT_VALLON_ZEK 289
#define RT_VALORIAN 318
#define RT_VALORIAN_2 322
#define RT_VAMPIRE 65
#define RT_VAMPIRE_2 98
#define RT_VAMPIRE_3 208
#define RT_VAMPIRE_4 219
#define RT_VAMPIRE_5 359
#define RT_VAMPIRE_6 360
#define RT_VAMPIRE_7 365
#define RT_VAMPIRE_8 497
#define RT_VASE 379
#define RT_VEGEROG 258
#define RT_VEKSAR 353
#define RT_VEKSAR_2 354
#define RT_VEKSAR_3 355
#define RT_VENRIL_SATHIR 20
#define RT_VINE_MAW 717
#define RT_WAGON 621
#define RT_WALRUS 177
#define RT_WAR_BOAR 319
#define RT_WAR_BOAR_2 321
#define RT_WAR_WRAITH 313
#define RT_WASP 109
#define RT_WATER_ELEMENTAL 211
#define RT_WATER_ELEMENTAL_2 478
#define RT_WATER_MEPHIT 271
#define RT_WATER_SPOUT 710
#define RT_WEAPON_RACK 381
#define RT_WEAPON_RACK_2 534
#define RT_WEB 515
#define RT_WEDDING_ALTAR 635
#define RT_WEDDING_ARBOR 634
#define RT_WEDDING_FLOWERS 633
#define RT_WEREORC 579
#define RT_WEREWOLF 14
#define RT_WEREWOLF_2 241
#define RT_WEREWOLF_3 454
#define RT_WETFANG_MINNOW 213
#define RT_WHIRLIGIG 682
#define RT_WICKER_BASKET 516
#define RT_WILL_O_WISP 69
#define RT_WINE_CASK 543
#define RT_WINE_CASK_2 630
#define RT_WITHERAN 465
#define RT_WITHERAN_2 474
#define RT_WOLF 42
#define RT_WOLF_2 120
#define RT_WOLF_3 482
#define RT_WOOD_ELF 4
#define RT_WORG 580
#define RT_WORG_2 594
#define RT_WORM 203
#define RT_WRETCH 235
#define RT_WRULON 314
#define RT_WRULON_2 598
#define RT_WURM 158
#define RT_WURM_2 613
#define RT_WURM_MOUNT 679
#define RT_WYVERN 157
#define RT_WYVERN_2 581
#define RT_XALGOZ 136
#define RT_XARIC_THE_UNSPOKEN 725
#define RT_XEGONY 299
#define RT_YAKKAR 181
#define RT_YETI 138
#define RT_ZEBUXORUK 295
#define RT_ZEBUXORUKS_CAGE 328
#define RT_ZELNIAK 222
#define RT_ZOMBIE 70
#define RT_ZOMBIE_2 471
const char* GetRaceIDName(uint16 race_id);
const char* GetPlayerRaceName(uint32 player_race_value);
+9
View File
@@ -65,6 +65,15 @@ namespace EQEmu {
return Real(0.0, 1.0) <= required;
}
// same range as client's roll0
// This is their main high level RNG function
int Roll0(int max)
{
if (max - 1 > 0)
return Int(0, max - 1);
return 0;
}
// std::shuffle requires a RNG engine passed to it, so lets provide a wrapper to use our engine
template<typename RandomAccessIterator>
void Shuffle(RandomAccessIterator first, RandomAccessIterator last)
+42 -14
View File
@@ -55,6 +55,8 @@ RULE_REAL(Character, AAExpMultiplier, 0.5)
RULE_REAL(Character, GroupExpMultiplier, 0.5)
RULE_REAL(Character, RaidExpMultiplier, 0.2)
RULE_BOOL(Character, UseXPConScaling, true)
RULE_INT(Character, ShowExpValues, 0) //0 - normal, 1 - Show raw experience values, 2 - Show raw experience values AND percent.
RULE_INT(Character, GreenModifier, 20)
RULE_INT(Character, LightBlueModifier, 40)
RULE_INT(Character, BlueModifier, 90)
RULE_INT(Character, WhiteModifier, 100)
@@ -113,6 +115,7 @@ RULE_BOOL(Character, CheckCursorEmptyWhenLooting, true) // If true, a player can
RULE_BOOL(Character, MaintainIntoxicationAcrossZones, true) // If true, alcohol effects are maintained across zoning and logging out/in.
RULE_BOOL(Character, EnableDiscoveredItems, true) // If enabled, it enables EVENT_DISCOVER_ITEM and also saves character names and timestamps for the first time an item is discovered.
RULE_BOOL(Character, EnableXTargetting, true) // Enable Extended Targetting Window, for users with UF and later clients.
RULE_BOOL(Character, EnableAggroMeter, true) // Enable Aggro Meter, for users with RoF and later clients.
RULE_BOOL(Character, KeepLevelOverMax, false) // Don't delevel a character that has somehow gone over the level cap
RULE_INT(Character, FoodLossPerUpdate, 35) // How much food/water you lose per stamina update
RULE_INT(Character, BaseInstrumentSoftCap, 36) // Softcap for instrument mods, 36 commonly referred to as "3.6" as well.
@@ -146,7 +149,8 @@ RULE_BOOL(Character, EnableAvoidanceCap, false)
RULE_INT(Character, AvoidanceCap, 750) // 750 Is a pretty good value, seen people dodge all attacks beyond 1,000 Avoidance
RULE_BOOL(Character, AllowMQTarget, false) // Disables putting players in the 'hackers' list for targeting beyond the clip plane or attempting to target something untargetable
RULE_BOOL(Character, UseOldBindWound, false) // Uses the original bind wound behavior
RULE_BOOL(Character, GrantHoTTOnCreate, false) // Grant Health of Target's Target leadership AA on character creation
RULE_BOOL(Character, UseOldConSystem, false) // Grant Health of Target's Target leadership AA on character creation
RULE_CATEGORY_END()
RULE_CATEGORY(Mercs)
@@ -161,6 +165,8 @@ RULE_INT(Mercs, AggroRadius, 100) // Determines the distance from which a merc
RULE_INT(Mercs, AggroRadiusPuller, 25) // Determines the distance from which a merc will aggro group member's target, if they have the group role of puller (also used to determine the distance at which a healer merc will begin healing a group member, if they have the group role of puller)
RULE_INT(Mercs, ResurrectRadius, 50) // Determines the distance from which a healer merc will attempt to resurrect a group member's corpse
RULE_INT(Mercs, ScaleRate, 100)
RULE_BOOL(Mercs, MercsUsePathing, true) // Mercs will use node pathing when moving
RULE_BOOL(Mercs, AllowMercSuspendInCombat, true)
RULE_CATEGORY_END()
RULE_CATEGORY(Guild)
@@ -223,7 +229,9 @@ RULE_INT(World, PVPSettings, 0) // Sets the PVP settings for the server, 1 = Ral
RULE_BOOL (World, IsGMPetitionWindowEnabled, false)
RULE_INT (World, FVNoDropFlag, 0) // Sets the Firiona Vie settings on the client. If set to 2, the flag will be set for GMs only, allowing trading of no-drop items.
RULE_BOOL (World, IPLimitDisconnectAll, false)
RULE_BOOL(World, MaxClientsSimplifiedLogic, false) // New logic that only uses ExemptMaxClientsStatus and MaxClientsPerIP. Done on the loginserver. This mimics the P99-style special IP rules.
RULE_INT (World, TellQueueSize, 20)
RULE_BOOL(World, StartZoneSameAsBindOnCreation, true) //Should the start zone ALWAYS be the same location as your bind?
RULE_CATEGORY_END()
RULE_CATEGORY(Zone)
@@ -256,6 +264,9 @@ RULE_INT(Zone, WeatherTimer, 600) // Weather timer when no duration is available
RULE_BOOL(Zone, EnableLoggedOffReplenishments, true)
RULE_INT(Zone, MinOfflineTimeToReplenishments, 21600) // 21600 seconds is 6 Hours
RULE_BOOL(Zone, UseZoneController, true) // Enables the ability to use persistent quest based zone controllers (zone_controller.pl/lua)
RULE_BOOL(Zone, EnableZoneControllerGlobals, false) // Enables the ability to use quest globals with the zone controller NPC
RULE_INT(Zone, GlobalLootMultiplier, 1) // Sets Global Loot drop multiplier for database based drops, useful for double, triple loot etc.
RULE_BOOL(Zone, IdleWhenEmpty, true) // Don't process NPCs while zone is empty. Defaults to true.
RULE_CATEGORY_END()
RULE_CATEGORY(Map)
@@ -331,11 +342,11 @@ RULE_INT(Spells, SacrificeMinLevel, 46) //first level Sacrifice will work on
RULE_INT(Spells, SacrificeMaxLevel, 69) //last level Sacrifice will work on
RULE_INT(Spells, SacrificeItemID, 9963) //Item ID of the item Sacrifice will return (defaults to an EE)
RULE_BOOL(Spells, EnableSpellGlobals, false) // If Enabled, spells check the spell_globals table and compare character data from the quest globals before allowing that spell to scribe with scribespells
RULE_INT(Spells, MaxBuffSlotsNPC, 25)
RULE_INT(Spells, MaxSongSlotsNPC, 10)
RULE_INT(Spells, MaxDiscSlotsNPC, 1)
RULE_INT(Spells, MaxTotalSlotsNPC, 36)
RULE_INT(Spells, MaxTotalSlotsPET, 30) // do not set this higher than 25 until the player profile is removed from the blob
RULE_INT(Spells, MaxBuffSlotsNPC, 60) // default to Tit's limit
RULE_INT(Spells, MaxSongSlotsNPC, 0) // NPCs don't have songs ...
RULE_INT(Spells, MaxDiscSlotsNPC, 0) // NPCs don't have discs ...
RULE_INT(Spells, MaxTotalSlotsNPC, 60) // default to Tit's limit
RULE_INT(Spells, MaxTotalSlotsPET, 30) // default to Tit's limit
RULE_BOOL (Spells, EnableBlockedBuffs, true)
RULE_INT(Spells, ReflectType, 1) //0 = disabled, 1 = single target player spells only, 2 = all player spells, 3 = all single target spells, 4 = all spells
RULE_INT(Spells, VirusSpreadDistance, 30) // The distance a viral spell will jump to its next victim
@@ -390,15 +401,13 @@ RULE_BOOL(Spells, NPCInnateProcOverride, true) // NPC innate procs override the
RULE_CATEGORY_END()
RULE_CATEGORY(Combat)
RULE_INT(Combat, MeleeBaseCritChance, 0) //The base crit chance for non warriors, NOTE: This will apply to NPCs as well
RULE_INT(Combat, WarBerBaseCritChance, 3) //The base crit chance for warriors and berserkers, only applies to clients
RULE_INT(Combat, BerserkBaseCritChance, 6) //The bonus base crit chance you get when you're berserk
RULE_INT(Combat, PetBaseCritChance, 0) // Pet Base crit chance
RULE_INT(Combat, NPCBashKickLevel, 6) //The level that npcs can KICK/BASH
RULE_INT(Combat, NPCBashKickStunChance, 15) //Percent chance that a bash/kick will stun
RULE_INT(Combat, RogueCritThrowingChance, 25) //Rogue throwing crit bonus
RULE_INT(Combat, RogueDeadlyStrikeChance, 80) //Rogue chance throwing from behind crit becomes a deadly strike
RULE_INT(Combat, RogueDeadlyStrikeMod, 2) //Deadly strike modifier to crit damage
RULE_INT(Combat, ClientBaseCritChance, 0) //The base crit chance for all clients, this will stack with warrior's/zerker's crit chance.
RULE_INT(Combat, MeleeCritDifficulty, 8900) // lower is easier
RULE_INT(Combat, ArcheryCritDifficulty, 3400) // lower is easier
RULE_INT(Combat, ThrowingCritDifficulty, 1100) // lower is easier
RULE_BOOL(Combat, NPCCanCrit, false) // true allows non PC pet NPCs to crit
RULE_BOOL(Combat, UseIntervalAC, true)
RULE_INT(Combat, PetAttackMagicLevel, 30)
RULE_BOOL(Combat, EnableFearPathing, true)
@@ -489,6 +498,8 @@ RULE_BOOL(Combat, UseLiveCombatRounds, true) // turn this false if you don't wan
RULE_INT(Combat, NPCAssistCap, 5) // Maxiumium number of NPCs that will assist another NPC at once
RULE_INT(Combat, NPCAssistCapTimer, 6000) // Time in milliseconds a NPC will take to clear assist aggro cap space
RULE_BOOL(Combat, UseRevampHandToHand, false) // use h2h revamped dmg/delays I believe this was implemented during SoF
RULE_BOOL(Combat, ClassicMasterWu, false) // classic master wu uses a random special, modern doesn't
RULE_INT(Combat, LevelToStopDamageCaps, 0) // 1 will effectively disable them, 20 should give basically same results as old incorrect system
RULE_CATEGORY_END()
RULE_CATEGORY(NPC)
@@ -539,6 +550,20 @@ RULE_BOOL(TaskSystem, KeepOneRecordPerCompletedTask, true)
RULE_BOOL(TaskSystem, EnableTaskProximity, true)
RULE_CATEGORY_END()
RULE_CATEGORY(Range)
RULE_INT(Range, Say, 135)
RULE_INT(Range, Emote, 135)
RULE_INT(Range, BeginCast, 200)
RULE_INT(Range, Anims, 135)
RULE_INT(Range, SpellParticles, 135)
RULE_INT(Range, DamageMessages, 50)
RULE_INT(Range, SpellMessages, 75)
RULE_INT(Range, SongMessages, 75)
RULE_INT(Range, MobPositionUpdates, 600)
RULE_INT(Range, CriticalDamage, 80)
RULE_CATEGORY_END()
#ifdef BOTS
RULE_CATEGORY(Bots)
RULE_INT(Bots, AAExpansion, 8) // Bots get AAs through this expansion
@@ -553,12 +578,15 @@ RULE_REAL(Bots, ManaRegen, 2.0) // Adjust mana regen for bots, 1 is fast and hig
RULE_BOOL(Bots, PreferNoManaCommandSpells, true) // Give sorting priority to newer no-mana spells (i.e., 'Bind Affinity')
RULE_BOOL(Bots, QuestableSpawnLimit, false) // Optional quest method to manage bot spawn limits using the quest_globals name bot_spawn_limit, see: /bazaar/Aediles_Thrall.pl
RULE_BOOL(Bots, QuestableSpells, false) // Anita Thrall's (Anita_Thrall.pl) Bot Spell Scriber quests.
RULE_INT(Bots, SpawnLimit, 71) // Number of bots a character can have spawned at one time, You + 71 bots is a 12 group raid
RULE_INT(Bots, SpawnLimit, 71) // Number of bots a character can have spawned at one time, You + 71 bots is a 12 group pseudo-raid (bots are not raidable at this time)
RULE_BOOL(Bots, UpdatePositionWithTimer, false) // Sends a position update with every positive movement timer check
RULE_BOOL(Bots, UsePathing, true) // Bots will use node pathing when moving
RULE_BOOL(Bots, BotGroupXP, false) // Determines whether client gets xp for bots outside their group.
RULE_BOOL(Bots, BotBardUseOutOfCombatSongs, true) // Determines whether bard bots use additional out of combat songs (optional script)
RULE_BOOL(Bots, BotLevelsWithOwner, false) // Auto-updates spawned bots as owner levels/de-levels (false is original behavior)
RULE_BOOL(Bots, BotCharacterLevelEnabled, false) // Enables required level to spawn bots
RULE_INT(Bots, BotCharacterLevel, 0) // 0 as default (if level > this value you can spawn bots if BotCharacterLevelEnabled is true)
RULE_INT(Bots, CasterStopMeleeLevel, 13) // Level at which caster bots stop melee attacks
RULE_CATEGORY_END()
#endif
+4 -4
View File
@@ -21,8 +21,8 @@
#include "emu_constants.h"
#include "string_util.h"
#include "item.h"
#include "item_base.h"
#include "item_instance.h"
#include "item_data.h"
#include "../zone/zonedb.h"
@@ -147,7 +147,7 @@ void EQEmu::SayLinkEngine::generate_body()
memset(&m_LinkBodyStruct, 0, sizeof(SayLinkBody_Struct));
const EQEmu::ItemBase* item_data = nullptr;
const EQEmu::ItemData* item_data = nullptr;
switch (m_LinkType) {
case saylink::SayLinkBlank:
@@ -250,7 +250,7 @@ void EQEmu::SayLinkEngine::generate_text()
return;
}
const EQEmu::ItemBase* item_data = nullptr;
const EQEmu::ItemData* item_data = nullptr;
switch (m_LinkType) {
case saylink::SayLinkBlank:
+6 -6
View File
@@ -26,11 +26,11 @@
struct ServerLootItem_Struct;
class ItemInst;
namespace EQEmu
{
struct ItemBase;
struct ItemData;
class ItemInstance;
struct SayLinkBody_Struct;
namespace saylink {
@@ -67,9 +67,9 @@ namespace EQEmu
SayLinkEngine();
void SetLinkType(saylink::SayLinkType link_type) { m_LinkType = link_type; }
void SetItemData(const EQEmu::ItemBase* item_data) { m_ItemData = item_data; }
void SetItemData(const EQEmu::ItemData* item_data) { m_ItemData = item_data; }
void SetLootData(const ServerLootItem_Struct* loot_data) { m_LootData = loot_data; }
void SetItemInst(const ItemInst* item_inst) { m_ItemInst = item_inst; }
void SetItemInst(const ItemInstance* item_inst) { m_ItemInst = item_inst; }
// mainly for saylinks..but, not limited to
void SetProxyUnknown1(uint8 proxy_unknown_1) { m_Proxy_unknown_1 = proxy_unknown_1; }
@@ -103,9 +103,9 @@ namespace EQEmu
void generate_text();
int m_LinkType;
const ItemBase* m_ItemData;
const ItemData* m_ItemData;
const ServerLootItem_Struct* m_LootData;
const ItemInst* m_ItemInst;
const ItemInstance* m_ItemInst;
uint8 m_Proxy_unknown_1;
uint32 m_ProxyItemID;
+1
View File
@@ -663,6 +663,7 @@ struct UsertoWorldRequest_Struct {
uint32 worldid;
uint32 FromID;
uint32 ToID;
char IPAddr[64];
};
struct UsertoWorldResponse_Struct {
+84 -71
View File
@@ -29,7 +29,7 @@
#include "faction.h"
#include "features.h"
#include "ipc_mutex.h"
#include "item.h"
#include "inventory_profile.h"
#include "loottable.h"
#include "memory_mapped_file.h"
#include "mysql.h"
@@ -38,6 +38,17 @@
#include "string_util.h"
#include "eqemu_config.h"
namespace ItemField
{
enum {
source = 0,
#define F(x) x,
#include "item_fieldlist.h"
#undef F
updated
};
}
SharedDatabase::SharedDatabase()
: Database()
{
@@ -99,13 +110,13 @@ uint32 SharedDatabase::GetTotalTimeEntitledOnAccount(uint32 AccountID) {
return EntitledTime;
}
bool SharedDatabase::SaveCursor(uint32 char_id, std::list<ItemInst*>::const_iterator &start, std::list<ItemInst*>::const_iterator &end)
bool SharedDatabase::SaveCursor(uint32 char_id, std::list<EQEmu::ItemInstance*>::const_iterator &start, std::list<EQEmu::ItemInstance*>::const_iterator &end)
{
// Delete cursor items
std::string query = StringFormat("DELETE FROM inventory WHERE charid = %i "
"AND ((slotid >= 8000 AND slotid <= 8999) "
"OR slotid = %i OR (slotid >= %i AND slotid <= %i) )",
char_id, EQEmu::legacy::SlotCursor,
char_id, EQEmu::inventory::slotCursor,
EQEmu::legacy::CURSOR_BAG_BEGIN, EQEmu::legacy::CURSOR_BAG_END);
auto results = QueryDatabase(query);
if (!results.Success()) {
@@ -116,8 +127,8 @@ bool SharedDatabase::SaveCursor(uint32 char_id, std::list<ItemInst*>::const_iter
int i = 8000;
for(auto it = start; it != end; ++it, i++) {
if (i > 8999) { break; } // shouldn't be anything in the queue that indexes this high
ItemInst *inst = *it;
int16 use_slot = (i == 8000) ? EQEmu::legacy::SlotCursor : i;
EQEmu::ItemInstance *inst = *it;
int16 use_slot = (i == 8000) ? EQEmu::inventory::slotCursor : i;
if (!SaveInventory(char_id, inst, use_slot)) {
return false;
}
@@ -126,7 +137,7 @@ bool SharedDatabase::SaveCursor(uint32 char_id, std::list<ItemInst*>::const_iter
return true;
}
bool SharedDatabase::VerifyInventory(uint32 account_id, int16 slot_id, const ItemInst* inst)
bool SharedDatabase::VerifyInventory(uint32 account_id, int16 slot_id, const EQEmu::ItemInstance* inst)
{
// Delete cursor items
std::string query = StringFormat("SELECT itemid, charges FROM sharedbank "
@@ -159,7 +170,7 @@ bool SharedDatabase::VerifyInventory(uint32 account_id, int16 slot_id, const Ite
return true;
}
bool SharedDatabase::SaveInventory(uint32 char_id, const ItemInst* inst, int16 slot_id) {
bool SharedDatabase::SaveInventory(uint32 char_id, const EQEmu::ItemInstance* inst, int16 slot_id) {
//never save tribute slots:
if (slot_id >= EQEmu::legacy::TRIBUTE_BEGIN && slot_id <= EQEmu::legacy::TRIBUTE_END)
@@ -173,7 +184,7 @@ bool SharedDatabase::SaveInventory(uint32 char_id, const ItemInst* inst, int16 s
else {
// Needed to clear out bag slots that 'REPLACE' in UpdateSharedBankSlot does not overwrite..otherwise, duplication occurs
// (This requires that parent then child items be sent..which should be how they are currently passed)
if (Inventory::SupportsContainers(slot_id))
if (EQEmu::InventoryProfile::SupportsContainers(slot_id))
DeleteSharedBankSlot(char_id, slot_id);
return UpdateSharedBankSlot(char_id, inst, slot_id);
}
@@ -184,18 +195,18 @@ bool SharedDatabase::SaveInventory(uint32 char_id, const ItemInst* inst, int16 s
// Needed to clear out bag slots that 'REPLACE' in UpdateInventorySlot does not overwrite..otherwise, duplication occurs
// (This requires that parent then child items be sent..which should be how they are currently passed)
if (Inventory::SupportsContainers(slot_id))
if (EQEmu::InventoryProfile::SupportsContainers(slot_id))
DeleteInventorySlot(char_id, slot_id);
return UpdateInventorySlot(char_id, inst, slot_id);
}
bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const ItemInst* inst, int16 slot_id) {
bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const EQEmu::ItemInstance* inst, int16 slot_id) {
// need to check 'inst' argument for valid pointer
uint32 augslot[EQEmu::legacy::ITEM_COMMON_SIZE] = { 0, 0, 0, 0, 0, 0 };
uint32 augslot[EQEmu::inventory::SocketCount] = { 0, 0, 0, 0, 0, 0 };
if (inst->IsClassCommon()) {
for (int i = AUG_INDEX_BEGIN; i < EQEmu::legacy::ITEM_COMMON_SIZE; i++) {
ItemInst *auginst = inst->GetItem(i);
for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) {
EQEmu::ItemInstance *auginst = inst->GetItem(i);
augslot[i] = (auginst && auginst->GetItem()) ? auginst->GetItem()->ID : 0;
}
}
@@ -221,12 +232,12 @@ bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const ItemInst* inst, i
auto results = QueryDatabase(query);
// Save bag contents, if slot supports bag contents
if (inst->IsClassBag() && Inventory::SupportsContainers(slot_id))
if (inst->IsClassBag() && EQEmu::InventoryProfile::SupportsContainers(slot_id))
// Limiting to bag slot count will get rid of 'hidden' duplicated items and 'Invalid Slot ID'
// messages through attrition (and the modded code in SaveInventory)
for (uint8 idx = SUB_INDEX_BEGIN; idx < inst->GetItem()->BagSlots && idx < EQEmu::legacy::ITEM_CONTAINER_SIZE; idx++) {
const ItemInst* baginst = inst->GetItem(idx);
SaveInventory(char_id, baginst, Inventory::CalcSlotId(slot_id, idx));
for (uint8 idx = EQEmu::inventory::containerBegin; idx < inst->GetItem()->BagSlots && idx < EQEmu::inventory::ContainerCount; idx++) {
const EQEmu::ItemInstance* baginst = inst->GetItem(idx);
SaveInventory(char_id, baginst, EQEmu::InventoryProfile::CalcSlotId(slot_id, idx));
}
if (!results.Success()) {
@@ -236,13 +247,13 @@ bool SharedDatabase::UpdateInventorySlot(uint32 char_id, const ItemInst* inst, i
return true;
}
bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst, int16 slot_id) {
bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const EQEmu::ItemInstance* inst, int16 slot_id) {
// need to check 'inst' argument for valid pointer
uint32 augslot[EQEmu::legacy::ITEM_COMMON_SIZE] = { 0, 0, 0, 0, 0, 0 };
uint32 augslot[EQEmu::inventory::SocketCount] = { 0, 0, 0, 0, 0, 0 };
if (inst->IsClassCommon()) {
for (int i = AUG_INDEX_BEGIN; i < EQEmu::legacy::ITEM_COMMON_SIZE; i++) {
ItemInst *auginst = inst->GetItem(i);
for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) {
EQEmu::ItemInstance *auginst = inst->GetItem(i);
augslot[i] = (auginst && auginst->GetItem()) ? auginst->GetItem()->ID : 0;
}
}
@@ -267,12 +278,12 @@ bool SharedDatabase::UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst,
auto results = QueryDatabase(query);
// Save bag contents, if slot supports bag contents
if (inst->IsClassBag() && Inventory::SupportsContainers(slot_id)) {
if (inst->IsClassBag() && EQEmu::InventoryProfile::SupportsContainers(slot_id)) {
// Limiting to bag slot count will get rid of 'hidden' duplicated items and 'Invalid Slot ID'
// messages through attrition (and the modded code in SaveInventory)
for (uint8 idx = SUB_INDEX_BEGIN; idx < inst->GetItem()->BagSlots && idx < EQEmu::legacy::ITEM_CONTAINER_SIZE; idx++) {
const ItemInst* baginst = inst->GetItem(idx);
SaveInventory(char_id, baginst, Inventory::CalcSlotId(slot_id, idx));
for (uint8 idx = EQEmu::inventory::containerBegin; idx < inst->GetItem()->BagSlots && idx < EQEmu::inventory::ContainerCount; idx++) {
const EQEmu::ItemInstance* baginst = inst->GetItem(idx);
SaveInventory(char_id, baginst, EQEmu::InventoryProfile::CalcSlotId(slot_id, idx));
}
}
@@ -293,10 +304,10 @@ bool SharedDatabase::DeleteInventorySlot(uint32 char_id, int16 slot_id) {
}
// Delete bag slots, if need be
if (!Inventory::SupportsContainers(slot_id))
if (!EQEmu::InventoryProfile::SupportsContainers(slot_id))
return true;
int16 base_slot_id = Inventory::CalcSlotId(slot_id, SUB_INDEX_BEGIN);
int16 base_slot_id = EQEmu::InventoryProfile::CalcSlotId(slot_id, EQEmu::inventory::containerBegin);
query = StringFormat("DELETE FROM inventory WHERE charid = %i AND slotid >= %i AND slotid < %i",
char_id, base_slot_id, (base_slot_id+10));
results = QueryDatabase(query);
@@ -319,10 +330,10 @@ bool SharedDatabase::DeleteSharedBankSlot(uint32 char_id, int16 slot_id) {
}
// Delete bag slots, if need be
if (!Inventory::SupportsContainers(slot_id))
if (!EQEmu::InventoryProfile::SupportsContainers(slot_id))
return true;
int16 base_slot_id = Inventory::CalcSlotId(slot_id, SUB_INDEX_BEGIN);
int16 base_slot_id = EQEmu::InventoryProfile::CalcSlotId(slot_id, EQEmu::inventory::containerBegin);
query = StringFormat("DELETE FROM sharedbank WHERE acctid = %i "
"AND slotid >= %i AND slotid < %i",
account_id, base_slot_id, (base_slot_id+10));
@@ -362,9 +373,9 @@ bool SharedDatabase::SetSharedPlatinum(uint32 account_id, int32 amount_to_add) {
return true;
}
bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, Inventory* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin_level) {
bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, EQEmu::InventoryProfile* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin_level) {
const EQEmu::ItemBase* myitem;
const EQEmu::ItemData* myitem;
std::string query = StringFormat("SELECT itemid, item_charges, slot FROM starting_items "
"WHERE (race = %i or race = 0) AND (class = %i or class = 0) AND "
@@ -385,7 +396,7 @@ bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, Inventory* inv,
if(!myitem)
continue;
ItemInst* myinst = CreateBaseItem(myitem, charges);
EQEmu::ItemInstance* myinst = CreateBaseItem(myitem, charges);
if(slot < 0)
slot = inv->FindFreeSlot(0, 0);
@@ -399,7 +410,7 @@ bool SharedDatabase::SetStartingItems(PlayerProfile_Struct* pp, Inventory* inv,
// Retrieve shared bank inventory based on either account or character
bool SharedDatabase::GetSharedBank(uint32 id, Inventory *inv, bool is_charid)
bool SharedDatabase::GetSharedBank(uint32 id, EQEmu::InventoryProfile *inv, bool is_charid)
{
std::string query;
@@ -428,7 +439,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, Inventory *inv, bool is_charid)
uint32 item_id = (uint32)atoi(row[1]);
int8 charges = (int8)atoi(row[2]);
uint32 aug[EQEmu::legacy::ITEM_COMMON_SIZE];
uint32 aug[EQEmu::inventory::SocketCount];
aug[0] = (uint32)atoi(row[3]);
aug[1] = (uint32)atoi(row[4]);
aug[2] = (uint32)atoi(row[5]);
@@ -436,7 +447,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, Inventory *inv, bool is_charid)
aug[4] = (uint32)atoi(row[7]);
aug[5] = (uint32)atoi(row[8]);
const EQEmu::ItemBase *item = GetItem(item_id);
const EQEmu::ItemData *item = GetItem(item_id);
if (!item) {
Log.Out(Logs::General, Logs::Error,
@@ -447,9 +458,9 @@ bool SharedDatabase::GetSharedBank(uint32 id, Inventory *inv, bool is_charid)
int16 put_slot_id = INVALID_INDEX;
ItemInst *inst = CreateBaseItem(item, charges);
EQEmu::ItemInstance *inst = CreateBaseItem(item, charges);
if (inst && item->IsClassCommon()) {
for (int i = AUG_INDEX_BEGIN; i < EQEmu::legacy::ITEM_COMMON_SIZE; i++) {
for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) {
if (aug[i])
inst->PutAugment(this, i, aug[i]);
}
@@ -500,7 +511,7 @@ bool SharedDatabase::GetSharedBank(uint32 id, Inventory *inv, bool is_charid)
}
// Overloaded: Retrieve character inventory based on character id
bool SharedDatabase::GetInventory(uint32 char_id, Inventory *inv)
bool SharedDatabase::GetInventory(uint32 char_id, EQEmu::InventoryProfile *inv)
{
// Retrieve character inventory
std::string query =
@@ -524,7 +535,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory *inv)
uint16 charges = atoi(row[2]);
uint32 color = atoul(row[3]);
uint32 aug[EQEmu::legacy::ITEM_COMMON_SIZE];
uint32 aug[EQEmu::inventory::SocketCount];
aug[0] = (uint32)atoul(row[4]);
aug[1] = (uint32)atoul(row[5]);
@@ -539,7 +550,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory *inv)
uint32 ornament_idfile = (uint32)atoul(row[13]);
uint32 ornament_hero_model = (uint32)atoul(row[14]);
const EQEmu::ItemBase *item = GetItem(item_id);
const EQEmu::ItemData *item = GetItem(item_id);
if (!item) {
Log.Out(Logs::General, Logs::Error,
@@ -550,7 +561,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory *inv)
int16 put_slot_id = INVALID_INDEX;
ItemInst *inst = CreateBaseItem(item, charges);
EQEmu::ItemInstance *inst = CreateBaseItem(item, charges);
if (inst == nullptr)
continue;
@@ -583,11 +594,11 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory *inv)
inst->SetOrnamentIcon(ornament_icon);
inst->SetOrnamentationIDFile(ornament_idfile);
inst->SetOrnamentHeroModel(ornament_hero_model);
inst->SetOrnamentHeroModel(item->HerosForgeModel);
if (instnodrop ||
(((slot_id >= EQEmu::legacy::EQUIPMENT_BEGIN && slot_id <= EQEmu::legacy::EQUIPMENT_END) ||
slot_id == EQEmu::legacy::SlotPowerSource) &&
slot_id == EQEmu::inventory::slotPowerSource) &&
inst->GetItem()->Attuneable))
inst->SetAttuned(true);
@@ -609,7 +620,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory *inv)
}
if (item->IsClassCommon()) {
for (int i = AUG_INDEX_BEGIN; i < EQEmu::legacy::ITEM_COMMON_SIZE; i++) {
for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) {
if (aug[i])
inst->PutAugment(this, i, aug[i]);
}
@@ -642,7 +653,7 @@ bool SharedDatabase::GetInventory(uint32 char_id, Inventory *inv)
}
// Overloaded: Retrieve character inventory based on account_id and character name
bool SharedDatabase::GetInventory(uint32 account_id, char *name, Inventory *inv)
bool SharedDatabase::GetInventory(uint32 account_id, char *name, EQEmu::InventoryProfile *inv)
{
// Retrieve character inventory
std::string query =
@@ -666,7 +677,7 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, Inventory *inv)
int8 charges = atoi(row[2]);
uint32 color = atoul(row[3]);
uint32 aug[EQEmu::legacy::ITEM_COMMON_SIZE];
uint32 aug[EQEmu::inventory::SocketCount];
aug[0] = (uint32)atoi(row[4]);
aug[1] = (uint32)atoi(row[5]);
aug[2] = (uint32)atoi(row[6]);
@@ -679,12 +690,12 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, Inventory *inv)
uint32 ornament_idfile = (uint32)atoul(row[13]);
uint32 ornament_hero_model = (uint32)atoul(row[14]);
const EQEmu::ItemBase *item = GetItem(item_id);
const EQEmu::ItemData *item = GetItem(item_id);
int16 put_slot_id = INVALID_INDEX;
if (!item)
continue;
ItemInst *inst = CreateBaseItem(item, charges);
EQEmu::ItemInstance *inst = CreateBaseItem(item, charges);
if (inst == nullptr)
continue;
@@ -719,7 +730,7 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, Inventory *inv)
inst->SetOrnamentIcon(ornament_icon);
inst->SetOrnamentationIDFile(ornament_idfile);
inst->SetOrnamentHeroModel(ornament_hero_model);
inst->SetOrnamentHeroModel(item->HerosForgeModel);
if (color > 0)
inst->SetColor(color);
@@ -727,7 +738,7 @@ bool SharedDatabase::GetInventory(uint32 account_id, char *name, Inventory *inv)
inst->SetCharges(charges);
if (item->IsClassCommon()) {
for (int i = AUG_INDEX_BEGIN; i < EQEmu::legacy::ITEM_COMMON_SIZE; i++) {
for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) {
if (aug[i])
inst->PutAugment(this, i, aug[i]);
}
@@ -816,7 +827,7 @@ bool SharedDatabase::LoadItems(const std::string &prefix) {
mutex.Lock();
std::string file_name = Config->SharedMemDir + prefix + std::string("items");
items_mmf = std::unique_ptr<EQEmu::MemoryMappedFile>(new EQEmu::MemoryMappedFile(file_name));
items_hash = std::unique_ptr<EQEmu::FixedMemoryHashSet<EQEmu::ItemBase>>(new EQEmu::FixedMemoryHashSet<EQEmu::ItemBase>(reinterpret_cast<uint8*>(items_mmf->Get()), items_mmf->Size()));
items_hash = std::unique_ptr<EQEmu::FixedMemoryHashSet<EQEmu::ItemData>>(new EQEmu::FixedMemoryHashSet<EQEmu::ItemData>(reinterpret_cast<uint8*>(items_mmf->Get()), items_mmf->Size()));
mutex.Unlock();
} catch(std::exception& ex) {
Log.Out(Logs::General, Logs::Error, "Error Loading Items: %s", ex.what());
@@ -828,7 +839,7 @@ bool SharedDatabase::LoadItems(const std::string &prefix) {
void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id)
{
EQEmu::FixedMemoryHashSet<EQEmu::ItemBase> hash(reinterpret_cast<uint8 *>(data), size, items, max_item_id);
EQEmu::FixedMemoryHashSet<EQEmu::ItemData> hash(reinterpret_cast<uint8 *>(data), size, items, max_item_id);
std::string ndbuffer;
bool disableNoRent = false;
@@ -856,7 +867,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
}
}
EQEmu::ItemBase item;
EQEmu::ItemData item;
const std::string query = "SELECT source,"
#define F(x) "`"#x"`,"
@@ -869,7 +880,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
}
for (auto row = results.begin(); row != results.end(); ++row) {
memset(&item, 0, sizeof(EQEmu::ItemBase));
memset(&item, 0, sizeof(EQEmu::ItemData));
item.ItemClass = (uint8)atoi(row[ItemField::itemclass]);
strcpy(item.Name, row[ItemField::name]);
@@ -1086,7 +1097,7 @@ void SharedDatabase::LoadItems(void *data, uint32 size, int32 items, uint32 max_
}
}
const EQEmu::ItemBase* SharedDatabase::GetItem(uint32 id) {
const EQEmu::ItemData* SharedDatabase::GetItem(uint32 id) {
if (id == 0)
{
return nullptr;
@@ -1105,7 +1116,7 @@ const EQEmu::ItemBase* SharedDatabase::GetItem(uint32 id) {
return nullptr;
}
const EQEmu::ItemBase* SharedDatabase::IterateItems(uint32* id) {
const EQEmu::ItemData* SharedDatabase::IterateItems(uint32* id) {
if(!items_hash || !id) {
return nullptr;
}
@@ -1125,13 +1136,13 @@ const EQEmu::ItemBase* SharedDatabase::IterateItems(uint32* id) {
return nullptr;
}
std::string SharedDatabase::GetBook(const char *txtfile)
std::string SharedDatabase::GetBook(const char *txtfile, int16 *language)
{
char txtfile2[20];
std::string txtout;
strcpy(txtfile2, txtfile);
std::string query = StringFormat("SELECT txtfile FROM books WHERE name = '%s'", txtfile2);
std::string query = StringFormat("SELECT txtfile, language FROM books WHERE name = '%s'", txtfile2);
auto results = QueryDatabase(query);
if (!results.Success()) {
txtout.assign(" ",1);
@@ -1146,6 +1157,7 @@ std::string SharedDatabase::GetBook(const char *txtfile)
auto row = results.begin();
txtout.assign(row[0],strlen(row[0]));
*language = static_cast<int16>(atoi(row[1]));
return txtout;
}
@@ -1250,18 +1262,18 @@ bool SharedDatabase::LoadNPCFactionLists(const std::string &prefix) {
return true;
}
// Create appropriate ItemInst class
ItemInst* SharedDatabase::CreateItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned)
// Create appropriate EQEmu::ItemInstance class
EQEmu::ItemInstance* SharedDatabase::CreateItem(uint32 item_id, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned)
{
const EQEmu::ItemBase* item = nullptr;
ItemInst* inst = nullptr;
const EQEmu::ItemData* item = nullptr;
EQEmu::ItemInstance* inst = nullptr;
item = GetItem(item_id);
if (item) {
inst = CreateBaseItem(item, charges);
if (inst == nullptr) {
Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateItem()");
Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for EQEmu::ItemInstance creation in SharedDatabase::CreateItem()");
Log.Out(Logs::General, Logs::Error, "Item Data = ID: %u, Name: %s, Charges: %i", item->ID, item->Name, charges);
return nullptr;
}
@@ -1279,15 +1291,15 @@ ItemInst* SharedDatabase::CreateItem(uint32 item_id, int16 charges, uint32 aug1,
}
// Create appropriate ItemInst class
ItemInst* SharedDatabase::CreateItem(const EQEmu::ItemBase* item, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned)
// Create appropriate EQEmu::ItemInstance class
EQEmu::ItemInstance* SharedDatabase::CreateItem(const EQEmu::ItemData* item, int16 charges, uint32 aug1, uint32 aug2, uint32 aug3, uint32 aug4, uint32 aug5, uint32 aug6, uint8 attuned)
{
ItemInst* inst = nullptr;
EQEmu::ItemInstance* inst = nullptr;
if (item) {
inst = CreateBaseItem(item, charges);
if (inst == nullptr) {
Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateItem()");
Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for EQEmu::ItemInstance creation in SharedDatabase::CreateItem()");
Log.Out(Logs::General, Logs::Error, "Item Data = ID: %u, Name: %s, Charges: %i", item->ID, item->Name, charges);
return nullptr;
}
@@ -1304,8 +1316,8 @@ ItemInst* SharedDatabase::CreateItem(const EQEmu::ItemBase* item, int16 charges,
return inst;
}
ItemInst* SharedDatabase::CreateBaseItem(const EQEmu::ItemBase* item, int16 charges) {
ItemInst* inst = nullptr;
EQEmu::ItemInstance* SharedDatabase::CreateBaseItem(const EQEmu::ItemData* item, int16 charges) {
EQEmu::ItemInstance* inst = nullptr;
if (item) {
// if maxcharges is -1 that means it is an unlimited use item.
// set it to 1 charge so that it is usable on creation
@@ -1315,10 +1327,10 @@ ItemInst* SharedDatabase::CreateBaseItem(const EQEmu::ItemBase* item, int16 char
if(charges <= 0 && item->Stackable)
charges = 1;
inst = new ItemInst(item, charges);
inst = new EQEmu::ItemInstance(item, charges);
if (inst == nullptr) {
Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for ItemInst creation in SharedDatabase::CreateBaseItem()");
Log.Out(Logs::General, Logs::Error, "Error: valid item data returned a null reference for EQEmu::ItemInstance creation in SharedDatabase::CreateBaseItem()");
Log.Out(Logs::General, Logs::Error, "Item Data = ID: %u, Name: %s, Charges: %i", item->ID, item->Name, charges);
return nullptr;
}
@@ -1689,6 +1701,7 @@ void SharedDatabase::LoadSpells(void *data, int max_spells) {
sp[tempid].pvpresistcalc=atoi(row[178]);
sp[tempid].pvpresistcap=atoi(row[179]);
sp[tempid].spell_category=atoi(row[180]);
sp[tempid].pcnpc_only_flag=atoi(row[183]);
sp[tempid].cast_not_standing = atoi(row[184]) != 0;
sp[tempid].can_mgb=atoi(row[185]);
sp[tempid].dispel_flag = atoi(row[186]);
+20 -20
View File
@@ -33,8 +33,6 @@
#include <memory>
class EvolveInfo;
class Inventory;
class ItemInst;
struct BaseDataStruct;
struct InspectMessage_Struct;
struct PlayerProfile_Struct;
@@ -45,7 +43,9 @@ struct LootDrop_Struct;
namespace EQEmu
{
struct ItemBase;
struct ItemData;
class ItemInstance;
class InventoryProfile;
class MemoryMappedFile;
}
@@ -74,34 +74,34 @@ class SharedDatabase : public Database
uint32 GetTotalTimeEntitledOnAccount(uint32 AccountID);
/*
Character Inventory
Character InventoryProfile
*/
bool SaveCursor(uint32 char_id, std::list<ItemInst*>::const_iterator &start, std::list<ItemInst*>::const_iterator &end);
bool SaveInventory(uint32 char_id, const ItemInst* inst, int16 slot_id);
bool SaveCursor(uint32 char_id, std::list<EQEmu::ItemInstance*>::const_iterator &start, std::list<EQEmu::ItemInstance*>::const_iterator &end);
bool SaveInventory(uint32 char_id, const EQEmu::ItemInstance* inst, int16 slot_id);
bool DeleteSharedBankSlot(uint32 char_id, int16 slot_id);
bool DeleteInventorySlot(uint32 char_id, int16 slot_id);
bool UpdateInventorySlot(uint32 char_id, const ItemInst* inst, int16 slot_id);
bool UpdateSharedBankSlot(uint32 char_id, const ItemInst* inst, int16 slot_id);
bool VerifyInventory(uint32 account_id, int16 slot_id, const ItemInst* inst);
bool GetSharedBank(uint32 id, Inventory* inv, bool is_charid);
bool UpdateInventorySlot(uint32 char_id, const EQEmu::ItemInstance* inst, int16 slot_id);
bool UpdateSharedBankSlot(uint32 char_id, const EQEmu::ItemInstance* inst, int16 slot_id);
bool VerifyInventory(uint32 account_id, int16 slot_id, const EQEmu::ItemInstance* inst);
bool GetSharedBank(uint32 id, EQEmu::InventoryProfile* inv, bool is_charid);
int32 GetSharedPlatinum(uint32 account_id);
bool SetSharedPlatinum(uint32 account_id, int32 amount_to_add);
bool GetInventory(uint32 char_id, Inventory* inv);
bool GetInventory(uint32 account_id, char* name, Inventory* inv);
bool GetInventory(uint32 char_id, EQEmu::InventoryProfile* inv);
bool GetInventory(uint32 account_id, char* name, EQEmu::InventoryProfile* inv);
std::map<uint32, uint32> GetItemRecastTimestamps(uint32 char_id);
uint32 GetItemRecastTimestamp(uint32 char_id, uint32 recast_type);
void ClearOldRecastTimestamps(uint32 char_id);
bool SetStartingItems(PlayerProfile_Struct* pp, Inventory* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin);
bool SetStartingItems(PlayerProfile_Struct* pp, EQEmu::InventoryProfile* inv, uint32 si_race, uint32 si_class, uint32 si_deity, uint32 si_current_zone, char* si_name, int admin);
std::string GetBook(const char *txtfile);
std::string GetBook(const char *txtfile, int16 *language);
/*
Item Methods
*/
ItemInst* CreateItem(uint32 item_id, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0);
ItemInst* CreateItem(const EQEmu::ItemBase* item, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0);
ItemInst* CreateBaseItem(const EQEmu::ItemBase* item, int16 charges = 0);
EQEmu::ItemInstance* CreateItem(uint32 item_id, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0);
EQEmu::ItemInstance* CreateItem(const EQEmu::ItemData* item, int16 charges = 0, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, uint8 attuned = 0);
EQEmu::ItemInstance* CreateBaseItem(const EQEmu::ItemData* item, int16 charges = 0);
/*
Shared Memory crap
@@ -111,8 +111,8 @@ class SharedDatabase : public Database
void GetItemsCount(int32 &item_count, uint32 &max_id);
void LoadItems(void *data, uint32 size, int32 items, uint32 max_item_id);
bool LoadItems(const std::string &prefix);
const EQEmu::ItemBase* IterateItems(uint32* id);
const EQEmu::ItemBase* GetItem(uint32 id);
const EQEmu::ItemData* IterateItems(uint32* id);
const EQEmu::ItemData* GetItem(uint32 id);
const EvolveInfo* GetEvolveInfo(uint32 loregroup);
//faction lists
@@ -149,7 +149,7 @@ class SharedDatabase : public Database
std::unique_ptr<EQEmu::MemoryMappedFile> skill_caps_mmf;
std::unique_ptr<EQEmu::MemoryMappedFile> items_mmf;
std::unique_ptr<EQEmu::FixedMemoryHashSet<EQEmu::ItemBase>> items_hash;
std::unique_ptr<EQEmu::FixedMemoryHashSet<EQEmu::ItemData>> items_hash;
std::unique_ptr<EQEmu::MemoryMappedFile> faction_mmf;
std::unique_ptr<EQEmu::FixedMemoryHashSet<NPCFactionList>> faction_hash;
std::unique_ptr<EQEmu::MemoryMappedFile> loot_table_mmf;
+51
View File
@@ -124,6 +124,57 @@ bool EQEmu::skills::IsCastingSkill(SkillType skill)
}
}
int32 EQEmu::skills::GetBaseDamage(SkillType skill)
{
switch (skill) {
case SkillBash:
return 2;
case SkillDragonPunch:
return 12;
case SkillEagleStrike:
return 7;
case SkillFlyingKick:
return 25;
case SkillKick:
return 3;
case SkillRoundKick:
return 5;
case SkillTigerClaw:
return 4;
case SkillFrenzy:
return 10;
default:
return 0;
}
}
bool EQEmu::skills::IsMeleeDmg(SkillType skill)
{
switch (skill) {
case Skill1HBlunt:
case Skill1HSlashing:
case Skill2HBlunt:
case Skill2HSlashing:
case SkillBackstab:
case SkillBash:
case SkillDragonPunch:
case SkillEagleStrike:
case SkillFlyingKick:
case SkillHandtoHand:
case SkillKick:
case Skill1HPiercing:
case SkillRiposte:
case SkillRoundKick:
case SkillThrowing:
case SkillTigerClaw:
case SkillFrenzy:
case Skill2HPiercing:
return true;
default:
return false;
}
}
const std::map<EQEmu::skills::SkillType, std::string>& EQEmu::skills::GetSkillTypeMap()
{
/* VS2013 code
+2
View File
@@ -166,6 +166,8 @@ namespace EQEmu
float GetSkillMeleePushForce(SkillType skill);
bool IsBardInstrumentSkill(SkillType skill);
bool IsCastingSkill(SkillType skill);
int32 GetBaseDamage(SkillType skill);
bool IsMeleeDmg(SkillType skill);
extern const std::map<SkillType, std::string>& GetSkillTypeMap();
+14 -3
View File
@@ -409,8 +409,19 @@ bool IsPartialCapableSpell(uint16 spell_id)
if (spells[spell_id].no_partial_resist)
return false;
if (IsPureNukeSpell(spell_id))
return true;
// spell uses 600 (partial) scale if first effect is damage, else it uses 200 scale.
// this includes DoTs. no_partial_resist excludes spells like necro snares
for (int o = 0; o < EFFECT_COUNT; o++) {
auto tid = spells[spell_id].effectid[o];
if (IsBlankSpellEffect(spell_id, o))
continue;
if ((tid == SE_CurrentHPOnce || tid == SE_CurrentHP) && spells[spell_id].base[o] < 0)
return true;
return false;
}
return false;
}
@@ -929,7 +940,7 @@ bool IsRegularSingleTargetHealSpell(uint16 spell_id)
{
if(spells[spell_id].effectid[0] == 0 && spells[spell_id].base[0] > 0 &&
spells[spell_id].targettype == ST_Target && spells[spell_id].buffduration == 0 &&
!IsFastHealSpell(spell_id) && !IsCompleteHealSpell(spell_id) &&
!IsCompleteHealSpell(spell_id) &&
!IsHealOverTimeSpell(spell_id) && !IsGroupSpell(spell_id))
return true;
+87 -29
View File
@@ -43,35 +43,93 @@
const int Z_AGGRO=10;
const int MobAISpellRange=100; // max range of buffs
const int SpellType_Nuke=1;
const int SpellType_Heal=2;
const int SpellType_Root=4;
const int SpellType_Buff=8;
const int SpellType_Escape=16;
const int SpellType_Pet=32;
const int SpellType_Lifetap=64;
const int SpellType_Snare=128;
const int SpellType_DOT=256;
const int SpellType_Dispel=512;
const int SpellType_InCombatBuff=1024;
const int SpellType_Mez=2048;
const int SpellType_Charm=4096;
const int SpellType_Slow = 8192;
const int SpellType_Debuff = 16384;
const int SpellType_Cure = 32768;
const int SpellType_Resurrect = 65536;
const uint32 MobAISpellRange=100; // max range of buffs
const int SpellTypes_Detrimental = SpellType_Nuke|SpellType_Root|SpellType_Lifetap|SpellType_Snare|SpellType_DOT|SpellType_Dispel|SpellType_Mez|SpellType_Charm|SpellType_Debuff|SpellType_Slow;
const int SpellTypes_Beneficial = SpellType_Heal|SpellType_Buff|SpellType_Escape|SpellType_Pet|SpellType_InCombatBuff|SpellType_Cure;
enum SpellTypes : uint32
{
SpellType_Nuke = (1 << 0),
SpellType_Heal = (1 << 1),
SpellType_Root = (1 << 2),
SpellType_Buff = (1 << 3),
SpellType_Escape = (1 << 4),
SpellType_Pet = (1 << 5),
SpellType_Lifetap = (1 << 6),
SpellType_Snare = (1 << 7),
SpellType_DOT = (1 << 8),
SpellType_Dispel = (1 << 9),
SpellType_InCombatBuff = (1 << 10),
SpellType_Mez = (1 << 11),
SpellType_Charm = (1 << 12),
SpellType_Slow = (1 << 13),
SpellType_Debuff = (1 << 14),
SpellType_Cure = (1 << 15),
SpellType_Resurrect = (1 << 16),
SpellType_HateRedux = (1 << 17),
SpellType_InCombatBuffSong = (1 << 18), // bard in-combat group/ae buffs
SpellType_OutOfCombatBuffSong = (1 << 19), // bard out-of-combat group/ae buffs
SpellType_PreCombatBuff = (1 << 20),
SpellType_PreCombatBuffSong = (1 << 21),
#define SpellType_Any 0xFFFF
SpellTypes_Detrimental = (SpellType_Nuke | SpellType_Root | SpellType_Lifetap | SpellType_Snare | SpellType_DOT | SpellType_Dispel | SpellType_Mez | SpellType_Charm | SpellType_Debuff | SpellType_Slow),
SpellTypes_Beneficial = (SpellType_Heal | SpellType_Buff | SpellType_Escape | SpellType_Pet | SpellType_InCombatBuff | SpellType_Cure | SpellType_HateRedux | SpellType_InCombatBuffSong | SpellType_OutOfCombatBuffSong | SpellType_PreCombatBuff | SpellType_PreCombatBuffSong),
SpellType_Any = 0xFFFFFFFF
};
// These should not be used to determine spell category..
// They are a graphical affects (effects?) index only
// TODO: import sai list
enum SpellAffectIndex {
SAI_Calm = 12, // Lull and Alliance Spells
SAI_Dispell_Sight = 14, // Dispells and Spells like Bind Sight
SAI_Memory_Blur = 27,
SAI_Calm_Song = 43 // Lull and Alliance Songs
SAI_Summon_Mount_Unclass = -1,
SAI_Direct_Damage = 0,
SAI_Heal_Cure = 1,
SAI_AC_Buff = 2,
SAI_AE_Damage = 3,
SAI_Summon = 4, // Summoned Pets and Items
SAI_Sight = 5,
SAI_Mana_Regen_Resist_Song = 6,
SAI_Stat_Buff = 7,
SAI_Vanish = 9, // Invisibility and Gate/Port
SAI_Appearance = 10, // Illusion and Size
SAI_Enchanter_Pet = 11,
SAI_Calm = 12, // Lull and Alliance Spells
SAI_Fear = 13,
SAI_Dispell_Sight = 14, // Dispells and Spells like Bind Sight
SAI_Stun = 15,
SAI_Haste_Runspeed = 16, // Haste and SoW
SAI_Combat_Slow = 17,
SAI_Damage_Shield = 18,
SAI_Cannibalize_Weapon_Proc = 19,
SAI_Weaken = 20,
SAI_Banish = 21,
SAI_Blind_Poison = 22,
SAI_Cold_DD = 23,
SAI_Poison_Disease_DD = 24,
SAI_Fire_DD = 25,
SAI_Memory_Blur = 27,
SAI_Gravity_Fling = 28,
SAI_Suffocate = 29,
SAI_Lifetap_Over_Time = 30,
SAI_Fire_AE = 31,
SAI_Cold_AE = 33,
SAI_Poison_Disease_AE = 34,
SAI_Teleport = 40,
SAI_Direct_Damage_Song = 41,
SAI_Combat_Buff_Song = 42,
SAI_Calm_Song = 43, // Lull and Alliance Songs
SAI_Firework = 45,
SAI_Firework_AE = 46,
SAI_Weather_Rocket = 47,
SAI_Convert_Vitals = 50,
SAI_NPC_Special_60 = 60,
SAI_NPC_Special_61 = 61,
SAI_NPC_Special_62 = 62,
SAI_NPC_Special_63 = 63,
SAI_NPC_Special_70 = 70,
SAI_NPC_Special_71 = 71,
SAI_NPC_Special_80 = 80,
SAI_Trap_Lock = 88
};
enum RESISTTYPE
{
@@ -485,7 +543,7 @@ typedef enum {
#define SE_ManaAbsorbPercentDamage 329 // implemented
#define SE_CriticalDamageMob 330 // implemented
#define SE_Salvage 331 // implemented - chance to recover items that would be destroyed in failed tradeskill combine
//#define SE_SummonToCorpse 332 // *not implemented AA - Call of the Wild (Druid/Shaman Res spell with no exp)
#define SE_SummonToCorpse 332 // *not implemented AA - Call of the Wild (Druid/Shaman Res spell with no exp)
#define SE_CastOnRuneFadeEffect 333 // implemented
#define SE_BardAEDot 334 // implemented
#define SE_BlockNextSpellFocus 335 // implemented - base1 chance to block next spell ie Puratus (8494)
@@ -502,7 +560,7 @@ typedef enum {
#define SE_HeadShotLevel 346 // implemented[AA] - HeadShot max level to kill
#define SE_DoubleRangedAttack 347 // implemented - chance at an additional archery attack (consumes arrow)
#define SE_LimitManaMin 348 // implemented
#define SE_ShieldEquipHateMod 349 // implemented[AA] Increase melee hate when wearing a shield.
#define SE_ShieldEquipDmgMod 349 // implemented[AA] Increase melee base damage (indirectly increasing hate) when wearing a shield.
#define SE_ManaBurn 350 // implemented - Drains mana for damage/heal at a defined ratio up to a defined maximum amount of mana.
//#define SE_PersistentEffect 351 // *not implemented. creates a trap/totem that casts a spell (spell id + base1?) when anything comes near it. can probably make a beacon for this
//#define SE_IncreaseTrapCount 352 // *not implemented - looks to be some type of invulnerability? Test ITC (8755)
@@ -519,7 +577,7 @@ typedef enum {
#define SE_BandolierSlots 363 // *not implemented[AA] 'Battle Ready' expands the bandolier by one additional save slot per rank.
#define SE_TripleAttackChance 364 // implemented
#define SE_ProcOnSpellKillShot 365 // implemented - chance to trigger a spell on kill when the kill is caused by a specific spell with this effect in it (10470 Venin)
#define SE_ShieldEquipDmgMod 366 // implemented[AA] Damage modifier to melee if shield equiped. (base1 = dmg mod , base2 = ?) ie Shield Specialist AA
#define SE_GroupShielding 366 // *not implemented[AA] This gives you /shieldgroup
#define SE_SetBodyType 367 // implemented - set body type of base1 so it can be affected by spells that are limited to that type (Plant, Animal, Undead, etc)
//#define SE_FactionMod 368 // *not implemented - increases faction with base1 (faction id, live won't match up w/ ours) by base2
#define SE_CorruptionCounter 369 // implemented
@@ -735,7 +793,7 @@ struct SPDat_Spell_Struct
/* 180 */ int spell_category; // -- GLOBAL_GROUP
/* 181 */ //int pvp_duration; // buffdurationformula for PvP -- PVP_DURATION
/* 182 */ //int pvp_duration_cap; // buffduration for PvP -- PVP_DURATION_CAP
/* 183 */ //int pcnpc_only_flag; // valid values are 0, 1 = PCs (and mercs), and 2 = NPCs (and not mercs) -- PCNPC_ONLY_FLAG
/* 183 */ int pcnpc_only_flag; // valid values are 0, 1 = PCs (and mercs), and 2 = NPCs (and not mercs) -- PCNPC_ONLY_FLAG
/* 184 */ bool cast_not_standing; // this is checked in the client's EQ_Spell::IsCastWhileInvisSpell, this also blocks SE_InterruptCasting from affecting this spell -- CAST_NOT_STANDING
/* 185 */ bool can_mgb; // 0=no, -1 or 1 = yes -- CAN_MGB
/* 186 */ int dispel_flag; // -- NO_DISPELL
-79
View File
@@ -18,82 +18,3 @@
*/
#include "textures.h"
//#include "inventory_slot.h"
#include <string.h> // temp
//int EQEmu::textures::ConvertEquipmentSlotToTextureSlot(int equipment_slot)
//{
// switch (equipment_slot) {
// case inventory::PossessionsHead:
// return textures::TextureHead;
// case inventory::PossessionsChest:
// return textures::TextureChest;
// case inventory::PossessionsArms:
// return textures::TextureArms;
// case inventory::PossessionsWrist1:
// return textures::TextureWrist;
// case inventory::PossessionsHands:
// return textures::TextureHands;
// case inventory::PossessionsLegs:
// return textures::TextureLegs;
// case inventory::PossessionsFeet:
// return textures::TextureFeet;
// case inventory::PossessionsPrimary:
// return textures::TexturePrimary;
// case inventory::PossessionsSecondary:
// return textures::TextureSecondary;
// default:
// return textures::TextureInvalid;
// }
//}
//int EQEmu::textures::ConvertEquipmentSlotToTextureSlot(const InventorySlot &equipment_slot)
//{
// if (equipment_slot.Type() != inventory::InvTypePossessions || equipment_slot.Bag() != inventory::InvBagInvalid || equipment_slot.Aug() != inventory::InvAugInvalid)
// return textures::TextureInvalid;
//
// return ConvertEquipmentSlotToTextureSlot(equipment_slot.Slot());
//}
//EQEmu::InventorySlot EQEmu::textures::ConvertTextureSlotToEquipmentSlot(int texture_slot)
//{
// switch (texture_slot) {
// case textures::TextureHead:
// return EQEmu::InventorySlot(inventory::InvTypePossessions, inventory::PossessionsHead);
// case textures::TextureChest:
// return EQEmu::InventorySlot(inventory::InvTypePossessions, inventory::PossessionsChest);
// case textures::TextureArms:
// return EQEmu::InventorySlot(inventory::InvTypePossessions, inventory::PossessionsArms);
// case textures::TextureWrist:
// return EQEmu::InventorySlot(inventory::InvTypePossessions, inventory::PossessionsWrist1);
// case textures::TextureHands:
// return EQEmu::InventorySlot(inventory::InvTypePossessions, inventory::PossessionsHands);
// case textures::TextureLegs:
// return EQEmu::InventorySlot(inventory::InvTypePossessions, inventory::PossessionsLegs);
// case textures::TextureFeet:
// return EQEmu::InventorySlot(inventory::InvTypePossessions, inventory::PossessionsFeet);
// case textures::TexturePrimary:
// return EQEmu::InventorySlot(inventory::InvTypePossessions, inventory::PossessionsPrimary);
// case textures::TextureSecondary:
// return EQEmu::InventorySlot(inventory::InvTypePossessions, inventory::PossessionsSecondary);
// default:
// return EQEmu::InventorySlot();
// }
//}
EQEmu::TextureProfile::TextureProfile()
{
memset(&Slot, 0, (sizeof(Texture_Struct) * textures::TextureCount));
}
EQEmu::TextureShortProfile::TextureShortProfile()
{
memset(&Slot, 0, (sizeof(uint32) * textures::TextureCount));
}
EQEmu::TintProfile::TintProfile()
{
memset(&Slot, 0, (sizeof(uint32) * textures::TextureCount));
}
+81 -84
View File
@@ -25,116 +25,113 @@
namespace EQEmu
{
//class InventorySlot;
namespace textures {
//enum : int { TextureInvalid = -1, TextureBegin };
enum : uint8 { TextureInvalid = 255, TextureBegin = 0 };
enum : int8 { textureInvalid = -1, textureBegin };
//enum TextureSlot : int {
enum TextureSlot : uint8 {
TextureHead = TextureBegin,
TextureChest,
TextureArms,
TextureWrist,
TextureHands,
TextureLegs,
TextureFeet,
TexturePrimary,
TextureSecondary,
TextureCount
enum TextureSlot : int8 {
armorHead = textureBegin,
armorChest,
armorArms,
armorWrist,
armorHands,
armorLegs,
armorFeet,
weaponPrimary,
weaponSecondary,
materialCount,
materialInvalid = textureInvalid
};
const int LastTexture = TextureSecondary;
const int LastTintableTexture = TextureFeet;
enum TintSlot : int8 {
tintHead = textureBegin,
tintChest,
tintArms,
tintWrist,
tintHands,
tintLegs,
tintFeet,
tintCount,
tintInvalid = textureInvalid
};
//extern int ConvertEquipmentSlotToTextureSlot(int equipment_slot);
//extern int ConvertEquipmentSlotToTextureSlot(const InventorySlot &equipment_slot);
//extern InventorySlot ConvertTextureSlotToEquipmentSlot(int texture_slot);
const int8 LastTexture = weaponSecondary;
const int8 LastTintableTexture = tintFeet;
struct Texture_Struct {
uint32 Material;
uint32 Unknown1;
uint32 EliteModel;
uint32 HerosForgeModel;
uint32 Unknown2; // same as material?
};
struct TextureMaterial_Struct {
uint32 Material;
};
struct Tint_Struct {
union {
struct {
uint8 Blue;
uint8 Green;
uint8 Red;
uint8 UseTint; // if there's a tint, this is FF
};
uint32 Color;
};
};
} /*textures*/
struct Texture_Struct {
uint32 Material;
uint32 Unknown1;
uint32 EliteMaterial;
uint32 HeroForgeModel;
uint32 Material2; // Same as material?
};
struct TextureProfile {
union {
struct {
Texture_Struct Head;
Texture_Struct Chest;
Texture_Struct Arms;
Texture_Struct Wrist;
Texture_Struct Hands;
Texture_Struct Legs;
Texture_Struct Feet;
Texture_Struct Primary;
Texture_Struct Secondary;
textures::Texture_Struct Head;
textures::Texture_Struct Chest;
textures::Texture_Struct Arms;
textures::Texture_Struct Wrist;
textures::Texture_Struct Hands;
textures::Texture_Struct Legs;
textures::Texture_Struct Feet;
textures::Texture_Struct Primary;
textures::Texture_Struct Secondary;
};
Texture_Struct Slot[textures::TextureCount];
textures::Texture_Struct Slot[textures::materialCount];
};
TextureProfile();
};
struct TextureShort_Struct {
uint32 Material;
};
struct TextureShortProfile {
struct TextureMaterialProfile {
union {
struct {
TextureShort_Struct Head;
TextureShort_Struct Chest;
TextureShort_Struct Arms;
TextureShort_Struct Wrist;
TextureShort_Struct Hands;
TextureShort_Struct Legs;
TextureShort_Struct Feet;
TextureShort_Struct Primary;
TextureShort_Struct Secondary;
textures::TextureMaterial_Struct Head;
textures::TextureMaterial_Struct Chest;
textures::TextureMaterial_Struct Arms;
textures::TextureMaterial_Struct Wrist;
textures::TextureMaterial_Struct Hands;
textures::TextureMaterial_Struct Legs;
textures::TextureMaterial_Struct Feet;
textures::TextureMaterial_Struct Primary;
textures::TextureMaterial_Struct Secondary;
};
TextureShort_Struct Slot[textures::TextureCount];
textures::TextureMaterial_Struct Slot[textures::materialCount];
};
TextureShortProfile();
};
struct Tint_Struct {
union {
struct {
uint8 Blue;
uint8 Green;
uint8 Red;
uint8 UseTint; // if there's a tint this is FF
};
uint32 Color;
};
//Tint_Struct();
};
struct TintProfile {
union {
struct {
Tint_Struct Head;
Tint_Struct Chest;
Tint_Struct Arms;
Tint_Struct Wrist;
Tint_Struct Hands;
Tint_Struct Legs;
Tint_Struct Feet;
Tint_Struct Primary;
Tint_Struct Secondary;
textures::Tint_Struct Head;
textures::Tint_Struct Chest;
textures::Tint_Struct Arms;
textures::Tint_Struct Wrist;
textures::Tint_Struct Hands;
textures::Tint_Struct Legs;
textures::Tint_Struct Feet;
textures::Tint_Struct Primary;
textures::Tint_Struct Secondary;
};
Tint_Struct Slot[textures::TextureCount];
textures::Tint_Struct Slot[textures::materialCount]; // materialCount is correct..but, {[weaponPrimary],[weaponSecondary]} are not tintable...
};
TintProfile();
};
} /*EQEmu*/
-31
View File
@@ -1,31 +0,0 @@
#pragma once
#include <streambuf>
#include <istream>
#include <ostream>
namespace EQ
{
namespace Util {
class MemoryBuffer : public std::streambuf
{
public:
MemoryBuffer(char* base, size_t size) {
setg(base, base, base + size);
setp(base, base + size);
}
};
class MemoryStreamWriter : virtual MemoryBuffer, public std::ostream
{
public:
MemoryStreamWriter(char* base, size_t size) : MemoryBuffer(base, size), std::ostream(static_cast<std::streambuf*>(this)) { }
};
class MemoryStreamReader : virtual MemoryBuffer, public std::istream
{
public:
MemoryStreamReader(char* base, size_t size) : MemoryBuffer(base, size), std::istream(static_cast<std::streambuf*>(this)) { }
};
}
}
-189
View File
@@ -1,189 +0,0 @@
#include "uuid.h"
#include <core/logsys.h>
#ifdef _WIN32
#include <objbase.h>
#endif
#ifdef __linux__
#include <uuid/uuid.h>
#endif
#ifdef __APPLE__
#include <CoreFoundation/CFUUID.h>
#endif
unsigned char hexDigitToChar(char ch)
{
if (ch > 47 && ch < 58)
return ch - 48;
if (ch > 96 && ch < 103)
return ch - 87;
if (ch > 64 && ch < 71)
return ch - 55;
return 0;
}
unsigned char hexPairToChar(char a, char b)
{
return hexDigitToChar(a) * 16 + hexDigitToChar(b);
}
EQ::Util::UUID::UUID()
{
m_bytes = std::vector<char>(16, 0);
}
EQ::Util::UUID::UUID(const unsigned char *bytes)
{
m_bytes.assign(bytes, bytes + 16);
}
EQ::Util::UUID::UUID(const UUID &o)
{
m_bytes = o.m_bytes;
}
EQ::Util::UUID::UUID(UUID &&o)
{
std::swap(m_bytes, o.m_bytes);
}
EQ::Util::UUID& EQ::Util::UUID::operator=(const UUID &o)
{
m_bytes = o.m_bytes;
return *this;
}
EQ::Util::UUID::~UUID()
{
}
EQ::Util::UUID EQ::Util::UUID::Generate()
{
#ifdef _WIN32
GUID id;
CoCreateGuid(&id);
const unsigned char buffer[16] =
{
static_cast<unsigned char>((id.Data1 >> 24) & 0xFF),
static_cast<unsigned char>((id.Data1 >> 16) & 0xFF),
static_cast<unsigned char>((id.Data1 >> 8) & 0xFF),
static_cast<unsigned char>((id.Data1) & 0xff),
static_cast<unsigned char>((id.Data2 >> 8) & 0xFF),
static_cast<unsigned char>((id.Data2) & 0xff),
static_cast<unsigned char>((id.Data3 >> 8) & 0xFF),
static_cast<unsigned char>((id.Data3) & 0xFF),
id.Data4[0],
id.Data4[1],
id.Data4[2],
id.Data4[3],
id.Data4[4],
id.Data4[5],
id.Data4[6],
id.Data4[7]
};
return buffer;
#endif
#ifdef __linux__
uuid_t id;
uuid_generate(id);
return id;
#endif
#ifdef __APPLE__
auto id = CFUUIDCreate(nullptr);
auto bytes = CFUUIDGetUUIDBytes(id);
const unsigned char buffer[16] =
{
bytes.byte0,
bytes.byte1,
bytes.byte2,
bytes.byte3,
bytes.byte4,
bytes.byte5,
bytes.byte6,
bytes.byte7,
bytes.byte8,
bytes.byte9,
bytes.byte10,
bytes.byte11,
bytes.byte12,
bytes.byte13,
bytes.byte14,
bytes.byte15
};
CFRelease(id);
return buffer;
#endif
}
EQ::Util::UUID EQ::Util::UUID::FromString(const std::string &str)
{
UUID ret;
ret.m_bytes.clear();
size_t i = 0;
ret.m_bytes.push_back(hexPairToChar(str[i], str[i + 1])); ++i;
ret.m_bytes.push_back(hexPairToChar(str[i], str[i + 1])); ++i;
ret.m_bytes.push_back(hexPairToChar(str[i], str[i + 1])); ++i;
ret.m_bytes.push_back(hexPairToChar(str[i], str[i + 1])); ++i;
++i;
ret.m_bytes.push_back(hexPairToChar(str[i], str[i + 1])); ++i;
ret.m_bytes.push_back(hexPairToChar(str[i], str[i + 1])); ++i;
++i;
ret.m_bytes.push_back(hexPairToChar(str[i], str[i + 1])); ++i;
ret.m_bytes.push_back(hexPairToChar(str[i], str[i + 1])); ++i;
++i;
ret.m_bytes.push_back(hexPairToChar(str[i], str[i + 1])); ++i;
ret.m_bytes.push_back(hexPairToChar(str[i], str[i + 1])); ++i;
++i;
ret.m_bytes.push_back(hexPairToChar(str[i], str[i + 1])); ++i;
ret.m_bytes.push_back(hexPairToChar(str[i], str[i + 1])); ++i;
ret.m_bytes.push_back(hexPairToChar(str[i], str[i + 1])); ++i;
ret.m_bytes.push_back(hexPairToChar(str[i], str[i + 1])); ++i;
ret.m_bytes.push_back(hexPairToChar(str[i], str[i + 1])); ++i;
ret.m_bytes.push_back(hexPairToChar(str[i], str[i + 1])); ++i;
return ret;
}
EQ::Util::UUID EQ::Util::UUID::FromByteArray(const char *buffer)
{
return UUID((unsigned char*)buffer);
}
std::string EQ::Util::UUID::ToString() const
{
return fmt::format("{:0<2x}{:0<2x}{:0<2x}{:0<2x}-{:0<2x}{:0<2x}-{:0<2x}{:0<2x}-{:0<2x}{:0<2x}-{:0<2x}{:0<2x}{:0<2x}{:0<2x}{:0<2x}{:0<2x}",
(unsigned char)m_bytes[0],
(unsigned char)m_bytes[1],
(unsigned char)m_bytes[2],
(unsigned char)m_bytes[3],
(unsigned char)m_bytes[4],
(unsigned char)m_bytes[5],
(unsigned char)m_bytes[6],
(unsigned char)m_bytes[7],
(unsigned char)m_bytes[8],
(unsigned char)m_bytes[9],
(unsigned char)m_bytes[10],
(unsigned char)m_bytes[11],
(unsigned char)m_bytes[12],
(unsigned char)m_bytes[13],
(unsigned char)m_bytes[14],
(unsigned char)m_bytes[15]);
}
const std::vector<char>& EQ::Util::UUID::ToByteArray() const
{
return m_bytes;
}
-35
View File
@@ -1,35 +0,0 @@
#pragma once
#include <string>
#include <vector>
#include <ios>
namespace EQ
{
namespace Util
{
class UUID
{
public:
UUID(const UUID &o);
UUID(UUID &&o);
UUID& operator=(const UUID &o);
~UUID();
static UUID Generate();
static UUID FromString(const std::string &str);
static UUID FromByteArray(const char *buffer);
std::string ToString() const;
const std::vector<char>& ToByteArray() const;
friend std::ostream &operator<<(std::ostream &os, const UUID &id) {
return os << id.ToString();
}
private:
UUID();
UUID(const unsigned char *bytes);
std::vector<char> m_bytes;
};
}
}
+2 -2
View File
@@ -30,9 +30,9 @@
Manifest: https://github.com/EQEmu/Server/blob/master/utils/sql/db_update_manifest.txt
*/
#define CURRENT_BINARY_DATABASE_VERSION 9100
#define CURRENT_BINARY_DATABASE_VERSION 9107
#ifdef BOTS
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9008
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9015
#else
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 0 // must be 0
#endif
+2 -1
View File
@@ -13,7 +13,7 @@ SET(eqlaunch_headers
ADD_EXECUTABLE(eqlaunch ${eqlaunch_sources} ${eqlaunch_headers})
INSTALL(TARGETS eqlaunch RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
INSTALL(TARGETS eqlaunch RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
TARGET_LINK_LIBRARIES(eqlaunch common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY})
@@ -34,6 +34,7 @@ IF(UNIX)
TARGET_LINK_LIBRARIES(eqlaunch "rt")
ENDIF(NOT DARWIN)
TARGET_LINK_LIBRARIES(eqlaunch "pthread")
ADD_DEFINITIONS(-fPIC)
ENDIF(UNIX)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
-6
View File
@@ -1,6 +0,0 @@
IF(EQEMU_BUILD_LUA)
ADD_SUBDIRECTORY(luabind)
ENDIF(EQEMU_BUILD_LUA)
ADD_SUBDIRECTORY(libuv)
ADD_SUBDIRECTORY(format)
-427
View File
@@ -1,427 +0,0 @@
/*! \file access.hpp
\brief Access control, default construction, and serialization disambiguation */
/*
Copyright (c) 2014, Randolph Voorhies, Shane Grant
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of cereal nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL RANDOLPH VOORHIES OR SHANE GRANT BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CEREAL_ACCESS_HPP_
#define CEREAL_ACCESS_HPP_
#include <type_traits>
#include <iostream>
#include <cstdint>
#include <cereal/macros.hpp>
#include <cereal/details/helpers.hpp>
namespace cereal
{
// ######################################################################
//! A class that allows cereal to load smart pointers to types that have no default constructor
/*! If your class does not have a default constructor, cereal will not be able
to load any smart pointers to it unless you overload LoadAndConstruct
for your class, and provide an appropriate load_and_construct method. You can also
choose to define a member static function instead of specializing this class.
The specialization of LoadAndConstruct must be placed within the cereal namespace:
@code{.cpp}
struct MyType
{
MyType( int x ); // note: no default ctor
int myX;
// Define a serialize or load/save pair as you normally would
template <class Archive>
void serialize( Archive & ar )
{
ar( myX );
}
};
// Provide a specialization for LoadAndConstruct for your type
namespace cereal
{
template <> struct LoadAndConstruct<MyType>
{
// load_and_construct will be passed the archive that you will be loading
// from as well as a construct object which you can use as if it were the
// constructor for your type. cereal will handle all memory management for you.
template <class Archive>
static void load_and_construct( Archive & ar, cereal::construct<MyType> & construct )
{
int x;
ar( x );
construct( x );
}
};
} // end namespace cereal
@endcode
Please note that just as in using external serialization functions, you cannot get
access to non-public members of your class by befriending cereal::access. If you
have the ability to modify the class you wish to serialize, it is recommended that you
use member serialize functions and a static member load_and_construct function.
@tparam T The type to specialize for
@ingroup Access */
template <class T>
struct LoadAndConstruct
{
//! Called by cereal if no default constructor exists to load and construct data simultaneously
/*! Overloads of this should return a pointer to T and expect an archive as a parameter */
static std::false_type load_and_construct(...)
{ return std::false_type(); }
};
// forward decl for construct
//! @cond PRIVATE_NEVERDEFINED
namespace memory_detail{ template <class Ar, class T> struct LoadAndConstructLoadWrapper; }
//! @endcond
//! Used to construct types with no default constructor
/*! When serializing a type that has no default constructor, cereal
will attempt to call either the class static function load_and_construct
or the appropriate template specialization of LoadAndConstruct. cereal
will pass that function a reference to the archive as well as a reference
to a construct object which should be used to perform the allocation once
data has been appropriately loaded.
@code{.cpp}
struct MyType
{
// note the lack of default constructor
MyType( int xx, int yy );
int x, y;
double notInConstructor;
template <class Archive>
void serialize( Archive & ar )
{
ar( x, y );
ar( notInConstructor );
}
template <class Archive>
static void load_and_construct( Archive & ar, cereal::construct<MyType> & construct )
{
int x, y;
ar( x, y );
// use construct object to initialize with loaded data
construct( x, y );
// access to member variables and functions via -> operator
ar( construct->notInConstructor );
// could also do the above section by:
double z;
ar( z );
construct->notInConstructor = z;
}
};
@endcode
@tparam T The class type being serialized
*/
template <class T>
class construct
{
public:
//! Construct and initialize the type T with the given arguments
/*! This will forward all arguments to the underlying type T,
calling an appropriate constructor.
Calling this function more than once will result in an exception
being thrown.
@param args The arguments to the constructor for T
@throw Exception If called more than once */
template <class ... Args>
void operator()( Args && ... args );
// implementation deferred due to reliance on cereal::access
//! Get a reference to the initialized underlying object
/*! This must be called after the object has been initialized.
@return A reference to the initialized object
@throw Exception If called before initialization */
T * operator->()
{
if( !itsValid )
throw Exception("Object must be initialized prior to accessing members");
return itsPtr;
}
//! Returns a raw pointer to the initialized underlying object
/*! This is mainly intended for use with passing an instance of
a constructed object to cereal::base_class.
It is strongly recommended to avoid using this function in
any other circumstance.
@return A raw pointer to the initialized type */
T * ptr()
{
return operator->();
}
private:
template <class A, class B> friend struct ::cereal::memory_detail::LoadAndConstructLoadWrapper;
construct( T * p ) : itsPtr( p ), itsValid( false ) {}
construct( construct const & ) = delete;
construct & operator=( construct const & ) = delete;
T * itsPtr;
bool itsValid;
};
// ######################################################################
//! A class that can be made a friend to give cereal access to non public functions
/*! If you desire non-public serialization functions within a class, cereal can only
access these if you declare cereal::access a friend.
@code{.cpp}
class MyClass
{
private:
friend class cereal::access; // gives access to the private serialize
template <class Archive>
void serialize( Archive & ar )
{
// some code
}
};
@endcode
@ingroup Access */
class access
{
public:
// ####### Standard Serialization ########################################
template<class Archive, class T> inline
static auto member_serialize(Archive & ar, T & t) -> decltype(t.CEREAL_SERIALIZE_FUNCTION_NAME(ar))
{ return t.CEREAL_SERIALIZE_FUNCTION_NAME(ar); }
template<class Archive, class T> inline
static auto member_save(Archive & ar, T const & t) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar))
{ return t.CEREAL_SAVE_FUNCTION_NAME(ar); }
template<class Archive, class T> inline
static auto member_save_non_const(Archive & ar, T & t) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar))
{ return t.CEREAL_SAVE_FUNCTION_NAME(ar); }
template<class Archive, class T> inline
static auto member_load(Archive & ar, T & t) -> decltype(t.CEREAL_LOAD_FUNCTION_NAME(ar))
{ return t.CEREAL_LOAD_FUNCTION_NAME(ar); }
template<class Archive, class T> inline
static auto member_save_minimal(Archive const & ar, T const & t) -> decltype(t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar))
{ return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar); }
template<class Archive, class T> inline
static auto member_save_minimal_non_const(Archive const & ar, T & t) -> decltype(t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar))
{ return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar); }
template<class Archive, class T, class U> inline
static auto member_load_minimal(Archive const & ar, T & t, U && u) -> decltype(t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward<U>(u)))
{ return t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward<U>(u)); }
// ####### Versioned Serialization #######################################
template<class Archive, class T> inline
static auto member_serialize(Archive & ar, T & t, const std::uint32_t version ) -> decltype(t.CEREAL_SERIALIZE_FUNCTION_NAME(ar, version))
{ return t.CEREAL_SERIALIZE_FUNCTION_NAME(ar, version); }
template<class Archive, class T> inline
static auto member_save(Archive & ar, T const & t, const std::uint32_t version ) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar, version))
{ return t.CEREAL_SAVE_FUNCTION_NAME(ar, version); }
template<class Archive, class T> inline
static auto member_save_non_const(Archive & ar, T & t, const std::uint32_t version ) -> decltype(t.CEREAL_SAVE_FUNCTION_NAME(ar, version))
{ return t.CEREAL_SAVE_FUNCTION_NAME(ar, version); }
template<class Archive, class T> inline
static auto member_load(Archive & ar, T & t, const std::uint32_t version ) -> decltype(t.CEREAL_LOAD_FUNCTION_NAME(ar, version))
{ return t.CEREAL_LOAD_FUNCTION_NAME(ar, version); }
template<class Archive, class T> inline
static auto member_save_minimal(Archive const & ar, T const & t, const std::uint32_t version) -> decltype(t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar, version))
{ return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar, version); }
template<class Archive, class T> inline
static auto member_save_minimal_non_const(Archive const & ar, T & t, const std::uint32_t version) -> decltype(t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar, version))
{ return t.CEREAL_SAVE_MINIMAL_FUNCTION_NAME(ar, version); }
template<class Archive, class T, class U> inline
static auto member_load_minimal(Archive const & ar, T & t, U && u, const std::uint32_t version) -> decltype(t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward<U>(u), version))
{ return t.CEREAL_LOAD_MINIMAL_FUNCTION_NAME(ar, std::forward<U>(u), version); }
// ####### Other Functionality ##########################################
// for detecting inheritance from enable_shared_from_this
template <class T> inline
static auto shared_from_this(T & t) -> decltype(t.shared_from_this());
// for placement new
template <class T, class ... Args> inline
static void construct( T *& ptr, Args && ... args )
{
new (ptr) T( std::forward<Args>( args )... );
}
// for non-placement new with a default constructor
template <class T> inline
static T * construct()
{
return new T();
}
template <class T> inline
static std::false_type load_and_construct(...)
{ return std::false_type(); }
template<class T, class Archive> inline
static auto load_and_construct(Archive & ar, ::cereal::construct<T> & construct) -> decltype(T::load_and_construct(ar, construct))
{
T::load_and_construct( ar, construct );
}
}; // end class access
// ######################################################################
//! A specifier used in conjunction with cereal::specialize to disambiguate
//! serialization in special cases
/*! @relates specialize
@ingroup Access */
enum class specialization
{
member_serialize, //!< Force the use of a member serialize function
member_load_save, //!< Force the use of a member load/save pair
member_load_save_minimal, //!< Force the use of a member minimal load/save pair
non_member_serialize, //!< Force the use of a non-member serialize function
non_member_load_save, //!< Force the use of a non-member load/save pair
non_member_load_save_minimal //!< Force the use of a non-member minimal load/save pair
};
//! A class used to disambiguate cases where cereal cannot detect a unique way of serializing a class
/*! cereal attempts to figure out which method of serialization (member vs. non-member serialize
or load/save pair) at compile time. If for some reason cereal cannot find a non-ambiguous way
of serializing a type, it will produce a static assertion complaining about this.
This can happen because you have both a serialize and load/save pair, or even because a base
class has a serialize (public or private with friend access) and a derived class does not
overwrite this due to choosing some other serialization type.
Specializing this class will tell cereal to explicitly use the serialization type you specify
and it will not complain about ambiguity in its compile time selection. However, if cereal detects
an ambiguity in specializations, it will continue to issue a static assertion.
@code{.cpp}
class MyParent
{
friend class cereal::access;
template <class Archive>
void serialize( Archive & ar ) {}
};
// Although serialize is private in MyParent, to cereal::access it will look public,
// even through MyDerived
class MyDerived : public MyParent
{
public:
template <class Archive>
void load( Archive & ar ) {}
template <class Archive>
void save( Archive & ar ) {}
};
// The load/save pair in MyDerived is ambiguous because serialize in MyParent can
// be accessed from cereal::access. This looks the same as making serialize public
// in MyParent, making it seem as though MyDerived has both a serialize and a load/save pair.
// cereal will complain about this at compile time unless we disambiguate:
namespace cereal
{
// This struct specialization will tell cereal which is the right way to serialize the ambiguity
template <class Archive> struct specialize<Archive, MyDerived, cereal::specialization::member_load_save> {};
// If we only had a disambiguation for a specific archive type, it would look something like this
template <> struct specialize<cereal::BinaryOutputArchive, MyDerived, cereal::specialization::member_load_save> {};
}
@endcode
You can also choose to use the macros CEREAL_SPECIALIZE_FOR_ALL_ARCHIVES or
CEREAL_SPECIALIZE_FOR_ARCHIVE if you want to type a little bit less.
@tparam T The type to specialize the serialization for
@tparam S The specialization type to use for T
@ingroup Access */
template <class Archive, class T, specialization S>
struct specialize : public std::false_type {};
//! Convenient macro for performing specialization for all archive types
/*! This performs specialization for the specific type for all types of archives.
This macro should be placed at the global namespace.
@code{cpp}
struct MyType {};
CEREAL_SPECIALIZE_FOR_ALL_ARCHIVES( MyType, cereal::specialization::member_load_save );
@endcode
@relates specialize
@ingroup Access */
#define CEREAL_SPECIALIZE_FOR_ALL_ARCHIVES( Type, Specialization ) \
namespace cereal { template <class Archive> struct specialize<Archive, Type, Specialization> {}; }
//! Convenient macro for performing specialization for a single archive type
/*! This performs specialization for the specific type for a single type of archive.
This macro should be placed at the global namespace.
@code{cpp}
struct MyType {};
CEREAL_SPECIALIZE_FOR_ARCHIVE( cereal::XMLInputArchive, MyType, cereal::specialization::member_load_save );
@endcode
@relates specialize
@ingroup Access */
#define CEREAL_SPECIALIZE_FOR_ARCHIVE( Archive, Type, Specialization ) \
namespace cereal { template <> struct specialize<Archive, Type, Specialization> {}; }
// ######################################################################
// Deferred Implementation, see construct for more information
template <class T> template <class ... Args> inline
void construct<T>::operator()( Args && ... args )
{
if( itsValid )
throw Exception("Attempting to construct an already initialized object");
::cereal::access::construct( itsPtr, std::forward<Args>( args )... );
itsValid = true;
}
} // namespace cereal
#endif // CEREAL_ACCESS_HPP_
-163
View File
@@ -1,163 +0,0 @@
/*! \file adapters.hpp
\brief Archive adapters that provide additional functionality
on top of an existing archive */
/*
Copyright (c) 2014, Randolph Voorhies, Shane Grant
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of cereal nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL RANDOLPH VOORHIES OR SHANE GRANT BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef CEREAL_ARCHIVES_ADAPTERS_HPP_
#define CEREAL_ARCHIVES_ADAPTERS_HPP_
#include <cereal/details/helpers.hpp>
#include <utility>
namespace cereal
{
#ifdef CEREAL_FUTURE_EXPERIMENTAL
// Forward declaration for friend access
template <class U, class A> U & get_user_data( A & );
//! Wraps an archive and gives access to user data
/*! This adapter is useful if you require access to
either raw pointers or references within your
serialization functions.
While cereal does not directly support serialization
raw pointers or references, it is sometimes the case
that you may want to supply something such as a raw
pointer or global reference to some constructor.
In this situation this adapter would likely be used
with the construct class to allow for non-default
constructors.
@note This feature is experimental and may be altered or removed in a future release. See issue #46.
@code{.cpp}
struct MyUserData
{
int * myRawPointer;
std::reference_wrapper<MyOtherType> myReference;
};
struct MyClass
{
// Note the raw pointer parameter
MyClass( int xx, int * rawP );
int x;
template <class Archive>
void serialize( Archive & ar )
{ ar( x ); }
template <class Archive>
static void load_and_construct( Archive & ar, cereal::construct<MyClass> & construct )
{
int xx;
ar( xx );
// note the need to use get_user_data to retrieve user data from the archive
construct( xx, cereal::get_user_data<MyUserData>( ar ).myRawPointer );
}
};
int main()
{
{
MyUserData md;
md.myRawPointer = &something;
md.myReference = someInstanceOfType;
std::ifstream is( "data.xml" );
cereal::UserDataAdapter<MyUserData, cereal::XMLInputArchive> ar( md, is );
std::unique_ptr<MyClass> sc;
ar( sc ); // use as normal
}
return 0;
}
@endcode
@relates get_user_data
@tparam UserData The type to give the archive access to
@tparam Archive The archive to wrap */
template <class UserData, class Archive>
class UserDataAdapter : public Archive
{
public:
//! Construct the archive with some user data struct
/*! This will forward all arguments (other than the user
data) to the wrapped archive type. The UserDataAdapter
can then be used identically to the wrapped archive type
@tparam Args The arguments to pass to the constructor of
the archive. */
template <class ... Args>
UserDataAdapter( UserData & ud, Args && ... args ) :
Archive( std::forward<Args>( args )... ),
userdata( ud )
{ }
private:
//! Overload the rtti function to enable dynamic_cast
void rtti() {}
friend UserData & get_user_data<UserData>( Archive & ar );
UserData & userdata; //!< The actual user data
};
//! Retrieves user data from an archive wrapped by UserDataAdapter
/*! This will attempt to retrieve the user data associated with
some archive wrapped by UserDataAdapter. If this is used on
an archive that is not wrapped, a run-time exception will occur.
@note This feature is experimental and may be altered or removed in a future release. See issue #46.
@note The correct use of this function cannot be enforced at compile
time.
@relates UserDataAdapter
@tparam UserData The data struct contained in the archive
@tparam Archive The archive, which should be wrapped by UserDataAdapter
@param ar The archive
@throws Exception if the archive this is used upon is not wrapped with
UserDataAdapter. */
template <class UserData, class Archive>
UserData & get_user_data( Archive & ar )
{
try
{
return dynamic_cast<UserDataAdapter<UserData, Archive> &>( ar ).userdata;
}
catch( std::bad_cast const & )
{
throw ::cereal::Exception("Attempting to get user data from archive not wrapped in UserDataAdapter");
}
}
#endif // CEREAL_FUTURE_EXPERIMENTAL
} // namespace cereal
#endif // CEREAL_ARCHIVES_ADAPTERS_HPP_

Some files were not shown because too many files have changed in this diff Show More