Compare commits

...

157 Commits

Author SHA1 Message Date
Akkadius 37e66b5c01 Swap quest debug for combat logging [skip ci] 2019-10-12 17:25:13 -05:00
Akkadius bf798c0561 Pet critical logging [skip ci] 2019-10-12 17:24:07 -05:00
Akkadius 6ec577f241 More logging [skip ci] 2019-10-08 02:25:02 -05:00
Akkadius 672e6766c7 More logging [skip ci] 2019-10-08 02:10:49 -05:00
Akkadius b3eb11d068 More logging changes [skip ci] 2019-10-08 01:56:08 -05:00
Akkadius 55c61ddc78 Update some of the logging [skip ci] 2019-10-06 04:56:19 -05:00
Akkadius c131eca57f More temp logging changes [skip ci] 2019-10-06 03:42:34 -05:00
Akkadius a6dbba5380 Revert message changes [skip ci] 2019-10-06 02:39:37 -05:00
Akkadius d2f1a3097b More log tweaks [skip ci] 2019-10-06 02:33:00 -05:00
Akkadius 6c522e0e76 Fix logging [skip ci] 2019-10-06 02:27:15 -05:00
Akkadius cba068bfe8 Lower logging status for GM 2019-10-06 02:22:43 -05:00
Akkadius 28c8af96e3 Logging Mob::TryCriticalHit [skip ci] 2019-10-06 02:12:15 -05:00
Akkadius c684709712 Logging to Mob::CommonOutgoingHitSuccess [skip ci[ 2019-10-06 02:05:39 -05:00
Akkadius 225b3fffbd Logging to Mob::ApplyMeleeDamageBonus [skip ci] 2019-10-06 01:57:48 -05:00
Akkadius 0b790342e7 Add logging to Mob::CheckHitChance [skip ci] 2019-10-06 01:53:03 -05:00
Akkadius 690621268b Change GetDamageTable to use e.self [skip ci] 2019-10-06 01:41:10 -05:00
Akkadius 725d080cac Damage Table logging [skip ci] 2019-10-06 01:31:28 -05:00
Akkadius a3ffa7e262 Logging to GetRawACNoShield [skip ci] 2019-10-06 00:54:46 -05:00
Akkadius 344682e6ff Add logging to Mob::GetMeleeMitDmg [skip ci] 2019-10-06 00:38:08 -05:00
Akkadius c927fec803 Logging to MeleeMitigation [skip ci] 2019-10-06 00:06:59 -05:00
Akkadius 3b23477139 Comment each method with source function calls [skip ci] 2019-10-05 22:36:00 -05:00
Akkadius ea49422ff7 Add legacy_combat.lua merely for logging reference 2019-10-05 22:09:48 -05:00
Akkadius 9ccd9b80bb Old combat code beginng in plus linux fixes 2019-10-05 19:50:11 -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
162 changed files with 10211 additions and 6966 deletions
+5
View File
@@ -35,3 +35,8 @@ Build_64/
build_64/
log/
logs/
submodules/
.idea/
cmake-build-debug
EQEmu.cbp
+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) |
***
+238 -134
View File
@@ -1,5 +1,109 @@
EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 12/03/2016 ==
Uleat: Added hack detection to trade code
- If illegal items are found in trade slots when the 'trade' button is clicked, the trade is cancelled and a message is sent to the offending player
- Future revisions will, at a minimum, log the player as a hacker once the quirks have been worked out
== 12/01/2016 ==
Uleat: Disabled RoF+ clients from augmenting items not in their possessions slots (0-29, 9999, 251-330) to abate an exploit in the current code
== 10/17/2016 ==
Uleat: Moved namespace ItemField from item_instance.h to shareddb.cpp - the only place it is used
Uleat: Separated class Inventory from item_instance files into inventory_profile files
Uleat: Renamed class Inventory to EQEmu::InventoryProfile
Uleat: Renamed enum class InventoryVersion to MobVersion
== 10/16/2016 ==
Uleat: Renamed struct EQEmu::ItemBase to EQEmu::ItemData and class ItemInst to EQEmu::ItemInstance
Uleat: Added class EQEmu::InventorySlot. Re-attached pertinent inventory token references to EQDictionary
== 10/15/2016 ==
Uleat: Changed filenames to facilitate future inventory naming conventions
== 10/09/2016 ==
Noudess: Rogue usage of merchants while utilizing sneak was limited to
temporary items, as the code that checked faction per item sold did not
take into account that rogue was sneaking. Now sneaking rogues can see full
inventory on merchants (well, unless an item requires a + faction value).
== 09/12/2016 ==
Akkadius: 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
== 09/10/2016 ==
noudess: Task system experience based on a % of a level did not take into
account the hell levels rule. Now it does.
== 09/04/2016 (Changes over past few months) ==
Akkadius: Fixed an issue where clients would crash with health marquee's
Akkadius: Fixed issues with NPC's "ghosting" when they path
Akkadius: Overhauled worldserver logging
Akkadius: Pets now don't actually spawn until the player has fully entered the zone (Live-like)
demonstar/KLS: Adjusted some background workings on how spell buff tics are synced with the client
Uleat: Optimizations to map loading and zone times
Uleat/Akkadius: Fixed bandolier exploit where you could equip a 2H and Shield
mackal: Re-worked spell re-use timer logic
mackal: Source optimizations all over, crash fixes
mackal: Fixed some issues with illusions on zoning
mackal: Fixed some client DOT stacking bugs
mackal: Invis will now break on AA spell casts and item cast
mackal: Changed how Loot response code works
mackal: Implemented 3 additional spell gems with (Mnemonic Retention)
mackal: Instant spells now have instrument mods
mackal: Rate limit character saves
mackal: Made it so items no longer do TGB (Live-like) Rule implemented to disable
mackal: Set pet buffs limit to 30
== 09/03/2016 ==
Uleat: Changed 'Bind Wound' behavior to match the best references that I could find for post-2004 era.
Note: If you wish to retain the old method, source in the optional '2016_09_03_old_bind_wound_rule.sql' script file.
@@ -412,10 +516,10 @@ mackal: Reworked the activated avoidace skills (riposte, dodge, etc) based on de
Also riposte immunity from the increase riposte chance spell effect.
== 7/2/2015 ==
KLS/Demonstar55: AA system has been rewritten fixing a ton of bugs and extending functionality while making it easier to create new AA points.
KLS/Demonstar55: New tables are needed and so older data will need to be migrated to the new system.
KLS/Demonstar55: The SQL saves the old aa points spent/avail/character_alt_abilities data if any server ops want to do something different than PEQ did with it.
KLS/Demonstar55: Will try to get a wiki entry written up next week some time explaining the system but it's really not hard to follow the db tables in the meantime.
KLS/mackal: AA system has been rewritten fixing a ton of bugs and extending functionality while making it easier to create new AA points.
KLS/mackal: New tables are needed and so older data will need to be migrated to the new system.
KLS/mackal: The SQL saves the old aa points spent/avail/character_alt_abilities data if any server ops want to do something different than PEQ did with it.
KLS/mackal: Will try to get a wiki entry written up next week some time explaining the system but it's really not hard to follow the db tables in the meantime.
== 7/1/2015 ==
Akkadius: Fix an issue where emote messages would overflow the buffer of 256 by increasing the size and changing some of the initialization
@@ -445,7 +549,7 @@ Akkadius: Added DB ver 9082 with update to add npc_types texture columns if tabl
Uleat: Added null-term declaration for character names in ENCODE(OP_CharInfo) - where appropriate
== 05/20/2015 ==
demonstar55: Bard instrument mods should be more consistent with live. Zoning will keep instrument mod for long duration buffs (selo's)
mackal: Bard instrument mods should be more consistent with live. Zoning will keep instrument mod for long duration buffs (selo's)
Still need to have procs/doom effects to inherit the instrument mods from their source buff/whatever
== 05/18/2015 ==
@@ -455,7 +559,7 @@ KLS: Changed how fishing locates water to hopefully be a bit more accurate at th
Uleat: Added check to EntityList::CheckSpawnQueue() to bypass dereference if returned iterator is npc_list.end() - should fix the debug assertion failure crash
== 04/30/2015 ==
demonstar55: Implement mob and client melee push
mackal: Implement mob and client melee push
You can set Combat:MeleePush to false to turn off or change Combat:MeleePushChance to increase the chance an NPC can be pushed
PCs are always pushed, need to do more testing to verify.
@@ -509,7 +613,7 @@ Uleat: Fix for RoF+ clients showing active 'Return Home' button when action is n
Noudess: Starting erudites that were supposed to start in paineel were landing in erudin on Titanium. Fixed to be paineel.
== 02/20/2015 ==
demonstar55: Implement claims for RoF/RoF2 (should no longer crash the client!)
mackal: Implement claims for RoF/RoF2 (should no longer crash the client!)
- fixed bugs related to claims for the rest of the clients (woo infinite loops)
== 02/18/2015 ==
@@ -528,7 +632,7 @@ Notes:
== 02/16/2015 ==
Trevius: (RoF2) Bazaar Trading (Buying/Selling) is now fully functional. Bazaar (/bazaar) search is not yet functional.
demonstar55: (RoF2) Send the bard focus effects, note custom servers will need to fix their items, server side we still use the old system, but RoF2 wasn't showing anything with not sending focus, so send them
mackal: (RoF2) Send the bard focus effects, note custom servers will need to fix their items, server side we still use the old system, but RoF2 wasn't showing anything with not sending focus, so send them
== 02/14/2015 ==
Trevius: (RoF2) Bazaar is now partially functional. RoF2 clients can start/end trader mode and other clients can purchase from them. No other functionality yet.
@@ -578,7 +682,7 @@ Akkadius: Implement Packet logs with dumps
See: http://wiki.eqemulator.org/p?Logging_System_Overhaul#packet-logging-levels
== 02/01/2015 ==
demonstar55: Add quest debugging to lua
mackal: Add quest debugging to lua
eq.debug("Test debug level implicit 1")
eq.debug("Test debug level explicit 1", 1)
eq.debug("Test debug level explicit 2", 2)
@@ -771,7 +875,7 @@ Trevius: Finished lining up the RoF2 Player Profile Struct. Zone times are now
Trevius: Fixed zoning after death for RoF2.
== 12/17/2014 ==
demonstar55: Use vectors for route stuff, should be more CPU cache friendly so faster
mackal: Use vectors for route stuff, should be more CPU cache friendly so faster
Secrets: EQStream changes as recommended by a community member in private.
== 12/15/2014 ==
@@ -781,7 +885,7 @@ Trevius: Player Corpses now saved attuned settings for Items.
Required SQL: utils/sql/git/required/2014_12_15_multiple_table_updates.sql
== 12/13/2014 ==
demonstar55: Fix guild rank spam on zone (needed to be in OP_PP).
mackal: Fix guild rank spam on zone (needed to be in OP_PP).
Trevius: (RoF+) Implemented Armor Ornamentation using Hero's Forge Armor Models. To use, create an ornamentation augment and set the herosforgemodel field in the items table.
Trevius: (RoF+) Added command #heromodel (#hm for short) - Usage: #heromodel [hero forge model] [ [slot] ] (example: #heromodel 63)
@@ -789,11 +893,11 @@ Be sure to run this or there will be item loss:
Required SQL: utils/sql/git/required/2014_12_13_inventory_table_update.sql
== 12/12/2014 ==
demonstar55: Add special attack 42, Ignore Root Aggro Rules. This allows you to root a mob and have them still use the normal aggro rules (so they will attack the one with most hate, not closest)
mackal: Add special attack 42, Ignore Root Aggro Rules. This allows you to root a mob and have them still use the normal aggro rules (so they will attack the one with most hate, not closest)
== 12/09/2014 ==
Trevius: (RoF+) Implemented Hero's Forge Armor Models for Items. To use, set herosforgemodel field in the item table to a model number such as 63 (for example).
demonstar55: SoF+ swarm pets will no longer be F8able (without a hack!)
mackal: SoF+ swarm pets will no longer be F8able (without a hack!)
== 12/08/2014 ==
Secrets: Added a feature that allows an EQ client to log in directly to World without having to enter the LoginServer, provided the 'password' field is set in WorldServer.
@@ -839,10 +943,10 @@ Trevius: Mercenaries now Dismiss, Suspend, Unsuspend, and Die correctly.
Trevius: Mercenaries can now zone once again.
== 11/17/2014 ==
demonstar55: Correct OP_AugmentInfo reply. This fixes RoF display issue with Adventurer's Stone. Still issues with UF/SoF/SoD though.
mackal: Correct OP_AugmentInfo reply. This fixes RoF display issue with Adventurer's Stone. Still issues with UF/SoF/SoD though.
== 11/16/2014 ==
demonstar55: fix size issue with ControlBoat_Struct and exploit fix in OP_BoardBoat
mackal: fix size issue with ControlBoat_Struct and exploit fix in OP_BoardBoat
Akkadius: Implemented Automatic Database update and versioning system
Akkadius: Created database revision define, this is located in version.h in common #define CURRENT_BINARY_DATABASE_VERSION 9057
@@ -919,12 +1023,12 @@ Optional SQL: utils/sql/git/optional/2014_11_15_SwarmPetTargetLock.sql
== 11/14/2014 ==
Secrets: Identified object size and solidtype as flags. Exported them as functions to Perl.
demonstar55: Don't use the hack for charms that doesn't work on RoF
demonstar55: UF too
demonstar55: Tit
demonstar55: SoF
demonstar55: SoD
demonstar55: 62 (untested)
mackal: Don't use the hack for charms that doesn't work on RoF
mackal: UF too
mackal: Tit
mackal: SoF
mackal: SoD
mackal: 62 (untested)
== 11/13/2014 ==
Kayen: Implemented target type (44) 'Beams' (which projects an AE infront of caster with a specified length and width).
@@ -950,7 +1054,7 @@ JJ: Implement new Live-like faction adjustment message using rule Client:UseLive
Optional SQL: utils/sql/git/optional/2014_11_09_LiveFactionMessages.sql
== 11/06/2014 ==
demonstar55: Tracking default sort will now be correct order
mackal: Tracking default sort will now be correct order
Trevius: Fixed dynamic merchant list loading. Allows any merchant to be used in any zone.
== 11/03/2014 ==
@@ -974,17 +1078,17 @@ Uleat: Added Client::InterrogateInventory(). Can be invoked by #interrogateinv a
Uleat: Fix for stacking items in a world object..added a new command option: #peekinv world - will show world container contents, if one is in use by target.
== 10/20/2014 ==
demonstar55: Inspect Buffs rank 1 will now show NPC buffs in target window (SoD+)
mackal: Inspect Buffs rank 1 will now show NPC buffs in target window (SoD+)
== 10/19/2014 ==
Uleat: Updated command #peekinv to display item links properly in RoF clients
demonstar55: Group Mentoring in raids
demonstar55: Inspect Buffs (text only version) works in raid groups
demonstar55: Make use of the Inspect Buffs op/packet. 62 SOL until someone finds its op
mackal: Group Mentoring in raids
mackal: Inspect Buffs (text only version) works in raid groups
mackal: Make use of the Inspect Buffs op/packet. 62 SOL until someone finds its op
== 10/18/2014==
demonstar55: Implement group mentor, sharing leadership exp (SoF+ only)
demonstar55: Add gaining of group leadership while in raids
mackal: Implement group mentor, sharing leadership exp (SoF+ only)
mackal: Add gaining of group leadership while in raids
== 10/16/2014 ==
Uleat: Fixed the auto-conversion view naming error and renamed the views in the script files. Added a fix sql for databases that auto-converted.
@@ -997,7 +1101,7 @@ Notes: I modifed the behavior of both load and drop bots to fail on the first op
a few altered tables back to their original state - as of the date in the file.
== 10/13/2014 ==
demonstar55: Partially implement leadership and raids
mackal: Partially implement leadership and raids
Currently working: client side only effects and stat bonuses.
Not working: Mark NPC, and other stuff that need extra server side support
Currently only UF tested (Tit and 62 may just work, others need packet work)
@@ -1006,7 +1110,7 @@ demonstar55: Partially implement leadership and raids
Akkadius: Fix for LDON Character Stat load
== 10/11/2014 ==
demonstar55: Implement Raid MOTD for UF
mackal: Implement Raid MOTD for UF
Don't forget 2014_10_11_RaidMOTD.sql!
== 10/09/2014 ==
@@ -1019,7 +1123,7 @@ previously and/or manually changed code, or just have a need for it to re-run, c
** This will only work if you haven't deleted your `character_old` table **
== 10/07/2014 ==
demonstar55: Identified tutorial flag in all charcreate packets, reworked logic to correctly set homes binds
mackal: Identified tutorial flag in all charcreate packets, reworked logic to correctly set homes binds
== 10/05/2014 ==
Uleat: Added Server<->Corpse slot translators needed for re-enumeration (inactive until phased in)
@@ -1037,13 +1141,13 @@ Uleat: First round of Ti/6.2 translators added - needed for re-enumeration
== 10/01/2014 ==
Kayen: Exported to PERL $client->SendColoredText(color, msg)
demonstar55: Exported SendColoredText to lua
mackal: Exported SendColoredText to lua
== 09/30/2014 ==
Uleat: Implemented click-casting from bag slots for clients that natively support it (RoF)
== 09/28/2014 ==
demonstar55: Add support for post June 18, 2014 Hundred Hands Effect spells (they changed the formula and stuff)
mackal: Add support for post June 18, 2014 Hundred Hands Effect spells (they changed the formula and stuff)
set Spells:Jun182014HundredHandsRevamp to true if you're using a spell file from June 18, 2014+
== 09/27/2014 ==
@@ -1052,15 +1156,15 @@ Note: identifier is the stat field in spells_new, slot is used for certain effec
Example $mob->GetSpellStat(121, "range"); //Returns spell range
Example $mob->GetSpellStat(121, "effectid", 1); //Returns the the value of effectid1
This will allow you to pull almost all the data for any spell in quest files.
demonstar55: Move the client's SetAttackTimer to the end of Client::CalcBonuses to keep the haste in sync
demonstar55: Correct haste/slow "stacking" rules
demonstar55: Correct SE_AttackSpeed4 to respect unslowable
demonstar55: Make the haste be between 1-225 like the client (<100 = slow, >100 = haste) to ...
demonstar55: Correct Hundred Hands effect and use formula provided by devs
mackal: Move the client's SetAttackTimer to the end of Client::CalcBonuses to keep the haste in sync
mackal: Correct haste/slow "stacking" rules
mackal: Correct SE_AttackSpeed4 to respect unslowable
mackal: Make the haste be between 1-225 like the client (<100 = slow, >100 = haste) to ...
mackal: Correct Hundred Hands effect and use formula provided by devs
== 09/24/2014 ==
Uleat: Re-ordered server opcodes and handlers to give them some predictability of location (I need this for the inventory re-enumeration.)
demonstar55: Added helper function bool EQEmu::IsTradeskill(uint32 skill)
mackal: Added helper function bool EQEmu::IsTradeskill(uint32 skill)
== 09/23/2014 ==
Kayen: Spell recourse effects will now be applied AFTER the base spells effects have been applied (consistent with live).
@@ -1169,46 +1273,46 @@ Akkadius: Player Profile Blob to Database Conversion
ORDER BY DATA DESC;
== 09/20/2014 ==
demonstar55: Fix crash in SendEnterWorld on illegally long names
demonstar55: The client only lets you enter 15 characters for your name (UF at least)
demonstar55: Add rule Spells:SHDProcIDOffByOne for pre-UF spell file, set to true, UF+ set to false
mackal: Fix crash in SendEnterWorld on illegally long names
mackal: The client only lets you enter 15 characters for your name (UF at least)
mackal: Add rule Spells:SHDProcIDOffByOne for pre-UF spell file, set to true, UF+ set to false
KLS: #suspend and #ban now have required messages to record the reason for the ban/suspension.
== 09/19/2014 ==
demonstar55: Added Client::Tell_StringID (used in tell queue messages)
demonstar55: Tell queues (and offline) messages now show correctly
demonstar55: Fix starting with capital check
mackal: Added Client::Tell_StringID (used in tell queue messages)
mackal: Tell queues (and offline) messages now show correctly
mackal: Fix starting with capital check
== 09/18/2014==
demonstar55: Implement tell queues
mackal: Implement tell queues
Currently set to a limit of 20 by default (World:TellQueueSize) I was unable to hit the limit on live though (100+)
The required SQL nukes the old tell queue table, which may or may not be in your DB
Optional SQL adds the rule to the DB to allow easy of change
Note: this does not play well with multiple sessions with the same name on (crash and relog and have multiple sessions) but normal tells don't play well either
== 09/16/2014 ==
demonstar55: Implement spell formula 137 (BER AA Desperation)
mackal: Implement spell formula 137 (BER AA Desperation)
Uleat (NateDog): Fix for LoadBuffs() crash when a spell with a non-persistent Illusion effect was loaded.
demonstar55: Fix some effect calcs + implement more (derived from the client)
mackal: Fix some effect calcs + implement more (derived from the client)
== 09/15/2014 ==
Kayen: Nimbus effects will now be reapplied after zoning and will be removed when associated buff fades.
== 09/13/2014 ==
demonstar55: Fix rogues not having Thieves' Cant
mackal: Fix rogues not having Thieves' Cant
== 09/09/2014 ==
demonstar55: Incrase Mob kick/bash timer by 3
mackal: Incrase Mob kick/bash timer by 3
see: http://www.eqemulator.org/forums/showthread.php?t=38734
demonstar55: Fix slow effect on NPC special attack reuse timers
mackal: Fix slow effect on NPC special attack reuse timers
see: http://www.eqemulator.org/forums/showthread.php?t=38734
demonstar55: Slow fixes to bots!
demonstar55: Revamped how NPC attack rate is set
mackal: Slow fixes to bots!
mackal: Revamped how NPC attack rate is set
SQL: 2014_09_09_attack_delay.sql
demonstar55: Added attackdelay to #npcedit
mackal: Added attackdelay to #npcedit
== 09/08/2014 ==
demonstar55: Fix slow calc
mackal: Fix slow calc
see: http://www.eqemulator.org/forums/showthread.php?t=38734
== 09/07/2014 ==
@@ -1219,18 +1323,18 @@ Uleat: Tweaked 'Smart' trading code to return main slots before sub slots in sta
== 09/05/2014 ==
Uleat: Fix for cursor item loss when zoning. (Thanks to the other devs who traced and fixed the 'macro' issue!)
demonstar55: Fix size getting nuked with lua's SendIllusionPacket
mackal: Fix size getting nuked with lua's SendIllusionPacket
== 09/03/2014 ==
Secrets: Identified the routines needed to augment items in RoF. Currently, only Insert and Remove are supported. Swap and Destroy do not work due to missing functions related to the cursor.
demonstar55: Added work around command to show numhits on your buffs (#shownumhits)
mackal: Added work around command to show numhits on your buffs (#shownumhits)
Uleat: Fix for timer issue introduced by Zone::ShutDown() fix.
== 09/02/2014 ==
Secrets: Identified OP_GuildPromote for RoF clients.
Secrets: Fixed promotion, demotion, transferring a leader and displaying of client ranks in the Rain of Fear client. The rain of fear client, as such, will only have 3 ranks like the other clients, but supports a theoretical 8 ranks later.
Secrets/Akkadius: Fixed an issue involving character name lookup in the new DB code.
demonstar55: crash fix checking DivineAura in hate_list.cpp
mackal: crash fix checking DivineAura in hate_list.cpp
Secrets: Reverted some code that got in the main branch that shouldn't have gotten there.
Uleat: Changed #loc to report the same precision as /loc for Cartesians
@@ -1241,7 +1345,7 @@ KLS: Fixed a few quest related inconsistencies.
KLS: Added Lua EntityList::ChannelMessage(from, type, msg, language)
== 08/30/2014 ==
demonstar55: (noudess) Merchants should be more descriptive of why they don't sell to you
mackal: (noudess) Merchants should be more descriptive of why they don't sell to you
== 08/26/2014 ==
Uleat: Implemented 'Smart' Player Trade transfers. Trades are processed by containers, stackables and then all remaining. QueryServ logs have been updated to match these transactions.
@@ -1619,7 +1723,7 @@ Optional SQL: utils/sql/git/optional/2014_04_03_SpellProjectileRules.sql
Note: The rules in this SQL are for setting the item id for the graphic used by the projectile on different clients.
== 04/01/2014 ==
demonstar55: Implemented ability for a merchant to open and close shop.
mackal: Implemented ability for a merchant to open and close shop.
Lua quest functions: e.self:MerchantOpenShop() and e.self:MerchantCloseShop()
GM Commands: #merchant_open_shop (short: #open_shop) and #merchant_close_shop (short: #close_shop)
default to status 100, just in case you need to force the merchants status
@@ -1685,7 +1789,7 @@ Kayen: Revision to lull/harmony/pacification code to be consistent with live bas
which if 'resisted' will cause the caster to gain aggro.
== 03/05/2014 ==
demonstar55: Corrected rogue's evade to be single target
mackal: Corrected rogue's evade to be single target
sorvani: fixed crash issue 119
== 03/04/2014 ==
@@ -1700,7 +1804,7 @@ Kayen: Revision to root code to be consistent with live based on extensive perso
Optional SQL: utils/sql/git/optional/2014_03_04_RootRule.sql
== 03/03/2014 ==
demonstar55: Implemented deadly strikes and gave rogues higher innate throwing crit chance
mackal: Implemented deadly strikes and gave rogues higher innate throwing crit chance
New rules: Combat:RogueCritThrowingChance, Combat:RogueDeadlyStrikeChance, Combat:RogueDeadlyStrikeMod
Defaults should give fairly close to live results
@@ -1712,7 +1816,7 @@ Kayen: Revision to charm code to be consistent with live based on extensive pers
Optional SQL: utils/sql/git/optional/2014_03_02_CharmRules.sql
demonstar55: Melee Crits, HoTs, DoTs messages should now be filtered correctly on all clients.
mackal: Melee Crits, HoTs, DoTs messages should now be filtered correctly on all clients.
Clients that also support seeing others DoTs will now see them if they don't filter them
note: some newer clients have a 'mine only' option for HoTs but it functions the same as show
@@ -1764,7 +1868,7 @@ Sorvani: Renamed the instance_lockout and instance_lockout_player tables to inst
Required SQL: utils/sql/git/2014_02_13_Rename_instance_lockout_tables.sql
== 02/10/2014 ==
demonstar55 (Secrets): Re-wrote the entity list to be a std::map. This should be used for direct entityID lookups and is noticably faster performance-wise. Also should result in less nil pointers potentially.
mackal (Secrets): Re-wrote the entity list to be a std::map. This should be used for direct entityID lookups and is noticably faster performance-wise. Also should result in less nil pointers potentially.
Secrets: Fixed a crash issue that could occur on #repop related to quest timers.
Kayen: Divine Arbiration and other similar spell effects will now utilize a spell range check.
Kayen: Revised how heal amount is calculated to properly incorporate all current focus effects/bonuses.
@@ -1795,14 +1899,14 @@ Kayen: Implemented SE_FfLimitUseType (focus limit to numhits type)
== 01/20/2014 ==
cavedude: Live-Like weather system (Thanks to robregen for figuring it out!)
demonstar55: Implemented not_extendable spell flag
demonstar55: Moved Spell Casting Reinforcement to DB
demonstar55: Moved Mez Mastery to DB
mackal: Implemented not_extendable spell flag
mackal: Moved Spell Casting Reinforcement to DB
mackal: Moved Mez Mastery to DB
Kayen: Complete revision of the numhits systems to utilize 'numhits type' field in spell file.
== 01/18/2014 ==
sorvani: Implemented for Lua eq.get_characters_in_instance(uint16 instance_id), return a Lua HashTable
demonstar55: NPCs will now cast their charms.
mackal: NPCs will now cast their charms.
== 01/13/2014 ==
Kayen: Numerous minor fixes to spell effects.
@@ -1822,19 +1926,19 @@ Kayen: Implemented SE_LimitRace (Limits to spells cast by a certain race)
Kayen: Implemented SE_FcMute (silences casting of spells that contain specific spell effects) ie silence only heals
== 01/09/2014 ==
demonstar55: Add pet size preservation like live (zone, camp, etc)
mackal: Add pet size preservation like live (zone, camp, etc)
== 01/07/2014 ==
demonstar55: Moved pet can attack check to before it tries to attack, which is more live like.
mackal: Moved pet can attack check to before it tries to attack, which is more live like.
== 01/03/2014 ==
demonstar55: Crash prevention for emote.
mackal: Crash prevention for emote.
== 01/02/2014 ==
demonstar55: Stuns from beneficial spells (Harvest) ignore immunity
mackal: Stuns from beneficial spells (Harvest) ignore immunity
== 12/26/2013 ==
demonstar55: Added classes_required to merchantlist (same bitmask as items)
mackal: Added classes_required to merchantlist (same bitmask as items)
== 12/24/2013 ==
Secrets (Akkadius): Perl $client->SilentMessage("Message"); addition, this is a pre-req for a Perl plugin I've shared with EQEmu. This function essentially mimics a player speaking with an NPC - which is used in popup window responses
@@ -1855,14 +1959,14 @@ Kayen: Implemented SE_TriggerOnAmountValue (Trigger spell if HP/Mana/End bellow
Kayen: Fix to SE_BlockNextSpellFocus to make it functional again.
== 12/15/2013 ==
demonstar55: Moved the blocked buff check down so we get spell effects like on live
mackal: Moved the blocked buff check down so we get spell effects like on live
Kayen: Implemented SE_ReduceHealing (Reduces amount of healing on target by X amount)
Kayen: Implemented SE_CastonFocusEffect (Triggers spell as part of a focus, when that focus effect is used)
Kayen: Implemented SE_IncreaseHitDmgTaken (Effect is triggered when X amount of damage is taken)
Kayen: More fixes for various spell triggers/procs to now properly use their resist modifier.
== 12/14/2013 ==
demonstar55: Blocked buffs shouldn't fail, they should just not be applied.
mackal: Blocked buffs shouldn't fail, they should just not be applied.
JJ: Changed enable/disable recipe to confirm change made.
== 12/13/2013 ==
@@ -1873,52 +1977,52 @@ Kayen: Fix for various spell triggers/procs to now properly use their resist mod
Kayen: Fix to mob->ModSkillDmgTaken(skill_num, value), setting value to -1 will now properly effect all skills.
== 12/11/2013 ==
demonstar55: Fixed issue with crippling blow from berserker frenzy not actually doing anything
demonstar55: Fix haste caps
mackal: Fixed issue with crippling blow from berserker frenzy not actually doing anything
mackal: Fix haste caps
== 12/04/2013 ==
demonstar55: Fixed SpellType_Charm case in AICastSpell
mackal: Fixed SpellType_Charm case in AICastSpell
== 12/03/2013 ==
demonstar55: Added #showspellslist to view a mobs spell list
demonstar55: Fix procing off of unattackable things
mackal: Added #showspellslist to view a mobs spell list
mackal: Fix procing off of unattackable things
== 12/02/2013 ==
JJ: Bandaid fix to CopyCharacter function.
== 11/29/2013 ==
demonstar55: Stacking issues should be resolved now, probably could be optimized more, but went from 3 loops that do stuff to 3 where only 2 really does stuff and one breaks early in most cases, so slightly better
mackal: Stacking issues should be resolved now, probably could be optimized more, but went from 3 loops that do stuff to 3 where only 2 really does stuff and one breaks early in most cases, so slightly better
== 11/23/2013 ==
Secrets: Fixed an issue related to a zone crash where the count of the abilities in an AA was 0, leading to a size 0 buffer issue.
== 11/19/2013 ==
Secrets: Fixed an issue with two zone crashes reported on PEQ related to the buff restrictions code and AAs.
demonstar55: Partially make use of dot_stacking_exempt (case when it's 1 is implemented, -1 case isn't)
mackal: Partially make use of dot_stacking_exempt (case when it's 1 is implemented, -1 case isn't)
== 11/18/2013 ==
demonstar55: Added assistradius to npc_types, defaults to aggroradius if set to 0 (old behaviour)
mackal: Added assistradius to npc_types, defaults to aggroradius if set to 0 (old behaviour)
== 11/17/2013 ==
Sorvani: fixed leash and tether special abilities to use the specified range correctly.
demonstar55: Rewrote the Mob::_GetMovementSpeed fix an issue that arose from the change on 11/11
mackal: Rewrote the Mob::_GetMovementSpeed fix an issue that arose from the change on 11/11
- Added the rule Character:BaseRunSpeedCap (default 158) so people can customize what their runspeed cap is. Hardcapped to 225 so stuff doesn't get too crazy.
== 11/16/2013 ==
Leere: Fixed the drinking message for auto-consume, it will again correctly show up for forced consumption instead.
demonstar55: Added Mob::DoCastingChecks() which will check for various fail conditions while the casting bar is up. This is called after Mob::DoCastSpell() starts the casting and before it returns.
mackal: Added Mob::DoCastingChecks() which will check for various fail conditions while the casting bar is up. This is called after Mob::DoCastSpell() starts the casting and before it returns.
== 11/15/2013 ==
demonstar55: Fixed Mob::CalcFocusEffect()'s SE_LimitEffect
mackal: Fixed Mob::CalcFocusEffect()'s SE_LimitEffect
Leere: Fixed a stacking issue for SE_StackingCommand_Block
== 11/13/2013 ==
demonstar55: Implemented bard song effect cap. You can set the base cap with the rule Character:BaseInstrumentSoftCap, defaults to 36 or "3.6" as it is sometimes referred to.
demonstar55: Fix Echo of Taelosia and Ayonae's Tutelage to increase the mod cap instead of further improving the instrument mod
demonstar55: Implemented Singing/Instrument Mastery as an AA bonus.
mackal: Implemented bard song effect cap. You can set the base cap with the rule Character:BaseInstrumentSoftCap, defaults to 36 or "3.6" as it is sometimes referred to.
mackal: Fix Echo of Taelosia and Ayonae's Tutelage to increase the mod cap instead of further improving the instrument mod
mackal: Implemented Singing/Instrument Mastery as an AA bonus.
== 11/11/2013 ==
demonstar55: Changed the way walk speed is calculated to allow mobs to have their walk speed equal a 100% movement reduction
mackal: Changed the way walk speed is calculated to allow mobs to have their walk speed equal a 100% movement reduction
== 11/09/2013 ==
Leere: Fixed Bard mana regen, they now only are affected by items and AA.
@@ -1968,50 +2072,50 @@ Uleat: Converted SkillType typedef enumeration to SkillUseTypes enumeration - So
Uleat: Prepped the client patch files for larger skill buffer size (not active)
== 10/24/2013 ==
demonstar55: Fix some memory leaks in Mob::SpellOnTarget
mackal: Fix some memory leaks in Mob::SpellOnTarget
== 10/21/2013 ==
demonstar55: Changed GetMinLevel return 0 for more cases that EQ uses for some reason ...
demonstar55: Added buff level restrictions, set the Spells:BuffLevelRestrictions to false to have the old behavior.
mackal: Changed GetMinLevel return 0 for more cases that EQ uses for some reason ...
mackal: Added buff level restrictions, set the Spells:BuffLevelRestrictions to false to have the old behavior.
== 10/18/2013 ==
Uleat: Expanded the 'Bag Type' enumeration to include all known values. Also, set in place additional 'Bag Type' to 'Skill Type' conversions. Some of these will need to be verified before activation.
Uleat: Cleaned up some unused enumerations to show a move towards standardization. More to come...
== 10/12/2013 ==
demonstar55: Allow Titanium and lower clients to enter Tutorial zone from character select
mackal: Allow Titanium and lower clients to enter Tutorial zone from character select
Bad_Captain: Fixed merc crash issue by updating special_abilities & vwMercNpcTypes (Sorvani).
Bad_Captain: Bots- added out of combat bard songs & #bot bardoutofcombat on|off command to turn them on/off.
== 10/11/2013 ==
JJ: (demonstar55) Allow use of Go Home button when Tutorial still selected in RoF.
JJ: (mackal) Allow use of Go Home button when Tutorial still selected in RoF.
== 10/10/2013 ==
Secrets: Fixed zone shutdown (or #reloadqst) reinitalization of Perl. This should allow for Perl 5.14 and later to work on Windows under the new quest system.
demonstar55: Beneficial single target buffs shouldn't have their mana/timers set if they fail to cast after the Mob::SpellOnTarget call in Mob::SpellFinished
mackal: Beneficial single target buffs shouldn't have their mana/timers set if they fail to cast after the Mob::SpellOnTarget call in Mob::SpellFinished
JJ: Revert change to EnterWorldPacket introduced on 22 April 2013 to fix inability to enter Tutorial or Go Home from character select screen.
== 10/09/2013 ==
demonstar55: Fixed some more instances of the AA timer being eaten
mackal: Fixed some more instances of the AA timer being eaten
== 10/08/2013 ==
demonstar55: Added IsBuffSpell(spell_id) that will return true if the spell has a duration, so would end up in effects/song/discs etc windows on the client
demonstar55: Replaced instances of using CalcBuffDuration to determine if a spell was a buff with IsBuffSpell
demonstar55: Removed Mob::HasBuffIcon since it was doing what IsBuffSpell does in a more convoluted way with a rather misleading name
demonstar55: Fixed issues that arose from the 10/03/2013 change
mackal: Added IsBuffSpell(spell_id) that will return true if the spell has a duration, so would end up in effects/song/discs etc windows on the client
mackal: Replaced instances of using CalcBuffDuration to determine if a spell was a buff with IsBuffSpell
mackal: Removed Mob::HasBuffIcon since it was doing what IsBuffSpell does in a more convoluted way with a rather misleading name
mackal: Fixed issues that arose from the 10/03/2013 change
== 10/05/2013 ==
Sorvani: fixed issue with stackable items being created with 0 charges cause by fix to SummonItems
== 10/03/2013 ==
demonstar55: Fix when the random +1 tick is added to nerf extension focus effects to where they should be
mackal: Fix when the random +1 tick is added to nerf extension focus effects to where they should be
== 09/30/2013 ==
Sorvani: Changed SummonItem to only summon an item with max charges when said default value is present and not on zero charges
demonstar55: Fixed issue with #showstats showing your level for a bunch of values
mackal: Fixed issue with #showstats showing your level for a bunch of values
== 09/13/2013 ==
demonstar55: Add support for /pet hold on and /pet hold off (UF and RoF)
mackal: Add support for /pet hold on and /pet hold off (UF and RoF)
== 08/29/2013 ==
KLS: Removed Common Profiler and Zone Profiler. They're well past outdated status and are just code bloat.
@@ -2157,8 +2261,8 @@ KLS: Perl now will (like lua) keep track of the values you return from EVENT_*.
KLS: Exported eq.follow(entity_id, [distance]) and eq.stop_follow() to lua.
== 07/01/2013 ==
demonstar55: Fix Monster Summoning related to giants/cyclops
demonstar55: Prevent Monster Summoning from summoning a portal in bothunder
mackal: Fix Monster Summoning related to giants/cyclops
mackal: Prevent Monster Summoning from summoning a portal in bothunder
KLS: Merge of lua branch to master
See: http://www.eqemulator.org/forums/showthread.php?t=37008 for more detailed information on what is added.
Upgrade notes:
@@ -2226,35 +2330,35 @@ JJ: Fixed rare case where heals from buffs could go negative.
Derision: Moved entity_list.Clear() prior to destruction of Perl objects in zone shutdown as I was seeing a segfault due to attempts to call EVENT_HATE_LIST as mobs were being destroyed.
== 04/09/2013 ==
demonstar55: Realized I was an idiot, changed salvage script to be better
mackal: Realized I was an idiot, changed salvage script to be better
optional SQL: 2013_04_09_SalvageCleanOld.sql - run if ran old script
== 04/08/2013 ==
demonstar55: Implemented Salvage AA
mackal: Implemented Salvage AA
required SQL: 2013_04_08_Salvage.sql
script: generate_salvage.py - will generate the entries for some exceptions for salvage returns.
== 04/04/2013 ==
demonstar55: Implemented SE_ForageAdditionalItems as a bonus
mackal: Implemented SE_ForageAdditionalItems as a bonus
required SQL: 2013_04_04_NaturesBounty.sql
== 04/03/2013 ==
demonstar55: Overloaded Mob::Say_StringID with the option to provide a message type
demonstar55: Switched rest of the Pet Messages to MT_PetResponse (Leader commands intentionally left the old way)
mackal: Overloaded Mob::Say_StringID with the option to provide a message type
mackal: Switched rest of the Pet Messages to MT_PetResponse (Leader commands intentionally left the old way)
== 04/2/2013 ==
Bad_Captain: Fixed Merc lack of use of heal over time spells (causing excessive healing).
Bad_Captain: Fixed pet mitigation/AC issues.
== 04/01/2013 ==
demonstar55: AA reuse timers now start when you hit the button and are reset upon failure
demonstar55: Instant Cast bard AAs can now be used while singing a song
mackal: AA reuse timers now start when you hit the button and are reset upon failure
mackal: Instant Cast bard AAs can now be used while singing a song
== 03/30/2013 ==
demonstar55: Fixed most of the pet talking, all use StringIDs now. Pet now informs you when it taunts.
mackal: Fixed most of the pet talking, all use StringIDs now. Pet now informs you when it taunts.
== 03/23/2013 ==
demonstar55: Fix issues with escape not always working and fixed SE_FadingMemories to have the message since the message isn't part of the spell data.
mackal: Fix issues with escape not always working and fixed SE_FadingMemories to have the message since the message isn't part of the spell data.
Escape now uses just the spell and not the AA Actoin
Fading Memories now only uses the AA Action to eat mana
@@ -2264,7 +2368,7 @@ Bad_Captain: Added checks before dismissing merc to prevent possible bugged merc
Bad_Captain: Merged in Secret's merc memory leak fixes.
== 03/20/2013 ==
demonstar55: Fixed stacking issues with SE_Limit* (ex. Unholy Aura Discipline and Aura of Reverence)
mackal: Fixed stacking issues with SE_Limit* (ex. Unholy Aura Discipline and Aura of Reverence)
== 03/18/2013 ==
Bad_Captain: Fixed zone crash due to merc focus effects & tribute.
@@ -2327,7 +2431,7 @@ KLS: Changed how shared memory works:
af4t: Add Touch of the Wicked AA redux to SK Improved Harm Touch and Leech Touch.
== 02/22/2013 ==
demonstar55: Mobs will now be removed from XTargets when they get back to their way point, should be last instance of XTarget mobs not clearing when they are not aggroed anymore
mackal: Mobs will now be removed from XTargets when they get back to their way point, should be last instance of XTarget mobs not clearing when they are not aggroed anymore
== 02/19/2013 ==
Derision: World should no longer crash if the start_zone query fails at character creation.
@@ -2336,7 +2440,7 @@ Derision: World should no longer crash if the start_zone query fails at characte
Bad_Captain: Moved merc save to merc table, save merc buffs, added cure and rez spells to healer merc.
JJ: Chat garbled for drunk characters.
Derision: Charmed pets should no longer be targettable with F8. Charmed pets no longer get a surname of Soandso's Pet.
demonstar55: Added potionbelt tool tip
mackal: Added potionbelt tool tip
KLS: Added EVENT_DEATH to Player Quests
REQUIRED SQL: 2013_02_18_Merc_Rules_and_Tables.sql
@@ -2348,8 +2452,8 @@ Derision: Client version is now returned by the stream proxy as a number.
Derision: Fixed bug where BecomeTrader packets were only being sent to the Trader, not all other clients in the bazaar.
== 02/16/2013 ==
demonstar55: Fix AA reuse timer calc
demonstar55: Remove old filters and change all remaining old to new (Also fix Auction filtering out OOC as well due to incorrect define)
mackal: Fix AA reuse timer calc
mackal: Remove old filters and change all remaining old to new (Also fix Auction filtering out OOC as well due to incorrect define)
== 02/12/2013 ==
Kayen: AA fix
@@ -2360,7 +2464,7 @@ REQUIRED SQL: utils/sql/svn/2504_required_aa_updates.sql
Derision: RoF: Added ENCODE for OP_BeginCast (fixes no sound during spell casting). Corrected OP_DeleteSpell.
== 02/10/2013 ==
JJ: (demonstar55) Language skill up should use proper function.
JJ: (mackal) Language skill up should use proper function.
JJ: SetLanguageSkill now updates client immediately. Both functions do proper limit checks.
Added two missing languages. Skill level 0 in a spoken language now shows 'in an unknown tongue'.
JJ: Initial implementation of a GarbleMessage function and implemented for languages. Can be shared with drunk speaking.
@@ -2396,7 +2500,7 @@ Trevius: RoF: Turning on Trader mode in bazaar now works, but no further trader
Akkadius: Fixed an issue where global_npc.pl was not initializing (initially)
== 01/31/2013 ==
cavedude00: (demonstar55) Rune aggro fix
cavedude00: (mackal) Rune aggro fix
cavedude00: (Drajor) Tradeskill skillneeded fix.
== 01/30/2013 ==
@@ -2430,7 +2534,7 @@ Bad_Captain: Mercs - Initial spell casting AI committed.
KLS: Added crash logging for Windows builds.
Trevius: Mercenaries now despawn when a player camps out or disconnects in any way.
Trevius: Players with a Mercenary spawned can now be invited to and join another group with their mercenary.
Sorvani: (Demonstar55): Moved stunproc rule implmentation to catch all cases
Sorvani: (mackal): Moved stunproc rule implmentation to catch all cases
OPTIONAL SQL: utils/sql/svn/mercs.sql -- rerun for updated merc stats & merc spell lists
@@ -2881,9 +2985,9 @@ references:
http://www.eqemulator.org/forums/showthread.php?t=35629 - CSD Bugged Corpse Patch
http://www.eqemulator.org/forums/showthread.php?t=35699 - CSD Bandolier Patch
cavedude: (demonstar55) Damage shields by default will no longer count towards EXP gain. (Rule also added to change this behaviour.)
cavedude: (demonstar55) Extended targets should now clear when aggro is lost using skills.
cavedude: (demonstar55) AAs with shorter reuse timers should now reset if the cast failed (interrupted.)
cavedude: (mackal) Damage shields by default will no longer count towards EXP gain. (Rule also added to change this behaviour.)
cavedude: (mackal) Extended targets should now clear when aggro is lost using skills.
cavedude: (mackal) AAs with shorter reuse timers should now reset if the cast failed (interrupted.)
KLS: Fixed a cause of raids disbanding on zoning.
OPTIONAL SQL: INSERT INTO `rule_values` VALUES (1, 'Combat:EXPFromDmgShield', 'false', 'Determine if damage from a damage shield counts for EXP gain.');
@@ -3260,7 +3364,7 @@ Kayen: Implemented Perl Mob Quest Object GetModVulnerability(resist type) - Retu
Optional SQL: utils/sql/svn/2154_optional_rule_spell_procs_resists_falloff.sql
==06/22/2012==
Secrets: (demonstar55) Spells now display to all clients and can be filtered as such.
Secrets: (mackal) Spells now display to all clients and can be filtered as such.
Secrets: Damage Shields now go to the proper filter, and do not show the non-melee damage to everyone.
==06/03/2012==
@@ -5415,10 +5519,10 @@ WildcardX: *BOTS* Bots can now be invited and disbanded from your group by simpl
WildcardX: *BOTS* Tweak to the bots total play time calculation to make it more accurate.
KLS: Added #path meshtest simple to do a faster search on errant path nodes.
KLS: Modified the accurate hazard code to make automatic path maps with more accurate info that requires less manual editing afterward.
cavedude: (demonstar55) Pets will now be amiable to their owners, indifferent to all else.
cavedude: (demonstar55) Added $client->KeyRingCheck() and $client->KeyRingAdd() to allow Perl to manipulate the keyring.
cavedude: (demonstar55) Casting an invis spell on a player that already has a similar type invis spell will no longer drop the existing buff.
cavedude: (demonstar55) Corrected message string for heal spells.
cavedude: (mackal) Pets will now be amiable to their owners, indifferent to all else.
cavedude: (mackal) Added $client->KeyRingCheck() and $client->KeyRingAdd() to allow Perl to manipulate the keyring.
cavedude: (mackal) Casting an invis spell on a player that already has a similar type invis spell will no longer drop the existing buff.
cavedude: (mackal) Corrected message string for heal spells.
cavedude: Added rule to determine at what HP a fleeing NPC will halt due to being snared.
==08/07/2009==
@@ -6054,7 +6158,7 @@ KLS: Fixed the /bug structure and updated the table to be more useful.
Required SQL: .\utils\sql\svn\503_bugs.sql
==05/11/2009==
demonstar55: Added a function to allow Perl to check augments within items.
mackal: Added a function to allow Perl to check augments within items.
cavedude: Increased bind wound skill up speed some.
KLS: Fix for potentially dangerous typo in spawn conditions code.
KLS: Removed some non-functioning but still taking up database resources database code.
@@ -6355,7 +6459,7 @@ cavedude: Removed the USE_RACE_CLASS_XP_MODS define as it was outdated and horri
cavedude: Added group XP bonus. The larger the group, the higher the XP gain.
cavedude: Added XP bonus for Warrior, Rogue, and Halfling.
cavedude: Corrected ZEM for AAs.
cavedude: (Thanks to demonstar55) Pet Affinity will no longer effect charmed pets.
cavedude: (Thanks to mackal) Pet Affinity will no longer effect charmed pets.
cavedude: (realityincarnate) Bard songs that require instruments will now require them.
Please note: XP gain has pretty much been overhauled. You may need tweak the multiplier rules for your server.
@@ -6489,7 +6593,7 @@ AndMetal: Augments are now visible when linking items.
Trevius: SoF - Adjusted the new Item Structure to align more fields
Trevius: SoF - Added OP_Consume and OP_LootRequest opcodes
cavedude00: (AndMetal) AAs now use skill_id instead of index for prereqs.
cavedude00: (demonstar55) Implemented Improved Instrument Mastery, Improved Singing Mastery, and Echo of Taelosia AAs.
cavedude00: (mackal) Implemented Improved Instrument Mastery, Improved Singing Mastery, and Echo of Taelosia AAs.
cavedude00: Created Combat:ChanceToHitDivideBy rule and increased default value to 1250.
Required and Optional SQL: utils/sql/svn/326_aas.sql
KLS: SoF - Fix for item slots in bags.
+8 -20
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
@@ -155,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
@@ -212,37 +216,29 @@ SET(common_headers
zone_numbers.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
@@ -266,37 +262,29 @@ SET(common_headers
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
+23 -4
View File
@@ -638,6 +638,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 +679,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 +708,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 +716,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 +2154,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;
}
+8 -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];
@@ -109,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 */
@@ -189,6 +193,8 @@ public:
int GetIPExemption(std::string account_ip);
int GetInstanceID(uint32 char_id, uint32 zone_id);
/* Groups */
+4 -4
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
@@ -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 */
+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*/
+21 -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];
};*/
@@ -3517,6 +3517,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;
+1 -1
View File
@@ -144,7 +144,7 @@ void EQEmuLogSys::ProcessGMSay(uint16 debug_level, uint16 log_category, const st
return;
/* Check to see if the process that actually ran this is zone */
if (EQEmuLogSys::log_platform == EQEmuExePlatform::ExePlatformZone)
if (GetExecutablePlatformInt() == EQEmuExePlatform::ExePlatformZone)
on_log_gmsay_hook(log_category, message);
}
+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 */
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);
// 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*/
@@ -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,32 @@ 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));
}
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);
}
+16 -36
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,15 @@ 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 { 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(); }
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;
};
} /*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*/
+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*/
+97 -99
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);
@@ -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);
@@ -5499,9 +5469,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 +5525,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 +5892,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 +5929,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 +5941,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 +5959,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 +5977,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 +5988,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 +5999,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 +6038,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 +6060,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 +6081,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 +6103,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 +6112,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 +6124,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 +6136,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 +6150,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 +6185,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 +6202,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 +6358,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)
+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];
};
};
@@ -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];
};*/
+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];
};*/
+11 -7
View File
@@ -55,6 +55,7 @@ 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, LightBlueModifier, 40)
RULE_INT(Character, BlueModifier, 90)
RULE_INT(Character, WhiteModifier, 100)
@@ -146,7 +147,7 @@ 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_CATEGORY_END()
RULE_CATEGORY(Mercs)
@@ -256,6 +257,7 @@ 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_CATEGORY_END()
RULE_CATEGORY(Map)
@@ -331,11 +333,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
@@ -489,6 +491,7 @@ 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_CATEGORY_END()
RULE_CATEGORY(NPC)
@@ -553,12 +556,13 @@ 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, 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;
+81 -69
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;
}
@@ -1250,18 +1261,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 +1290,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 +1315,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 +1326,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 +1700,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]);
+19 -19
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,24 +74,24 @@ 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);
@@ -99,9 +99,9 @@ class SharedDatabase : public Database
/*
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;
+13 -2
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;
}
+4 -4
View File
@@ -485,7 +485,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 +502,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 +519,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 +735,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*/
+1 -1
View File
@@ -30,7 +30,7 @@
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 9101
#ifdef BOTS
#define CURRENT_BINARY_BOTS_DATABASE_VERSION 9008
#else
+4 -4
View File
@@ -144,7 +144,7 @@ void Config::Parse(const char *file_name)
*/
void Config::Tokenize(FILE *input, std::list<std::string> &tokens)
{
char c = fgetc(input);
auto c = fgetc(input);
std::string lexeme;
while(c != EOF)
@@ -162,7 +162,7 @@ void Config::Tokenize(FILE *input, std::list<std::string> &tokens)
if(isalnum(c))
{
lexeme.append((const char *)&c, 1);
lexeme += c;
c = fgetc(input);
continue;
}
@@ -193,14 +193,14 @@ void Config::Tokenize(FILE *input, std::list<std::string> &tokens)
lexeme.clear();
}
lexeme.append((const char *)&c, 1);
lexeme += c;
tokens.push_back(lexeme);
lexeme.clear();
break;
}
default:
{
lexeme.append((const char *)&c, 1);
lexeme += c;
}
}
+2 -2
View File
@@ -22,7 +22,7 @@
#include "../common/ipc_mutex.h"
#include "../common/memory_mapped_file.h"
#include "../common/eqemu_exception.h"
#include "../common/item_base.h"
#include "../common/item_data.h"
void LoadItems(SharedDatabase *database, const std::string &prefix) {
EQEmu::IPCMutex mutex("items");
@@ -35,7 +35,7 @@ void LoadItems(SharedDatabase *database, const std::string &prefix) {
EQ_EXCEPT("Shared Memory", "Unable to get any items from the database.");
}
uint32 size = static_cast<uint32>(EQEmu::FixedMemoryHashSet<EQEmu::ItemBase>::estimated_size(items, max_item));
uint32 size = static_cast<uint32>(EQEmu::FixedMemoryHashSet<EQEmu::ItemData>::estimated_size(items, max_item));
auto Config = EQEmuConfig::get();
std::string file_name = Config->SharedMemDir + prefix + std::string("items");
+38
View File
@@ -36,6 +36,39 @@
EQEmuLogSys Log;
#ifdef _WINDOWS
#include <direct.h>
#else
#include <unistd.h>
#endif
#include <sys/stat.h>
inline bool MakeDirectory(const std::string &directory_name)
{
#ifdef _WINDOWS
struct _stat st;
if (_stat(directory_name.c_str(), &st) == 0) {
return false;
}
else {
_mkdir(directory_name.c_str());
return true;
}
#else
struct stat st;
if (stat(directory_name.c_str(), &st) == 0) {
return false;
}
else {
mkdir(directory_name.c_str(), 0755);
return true;
}
#endif
return false;
}
int main(int argc, char **argv) {
RegisterExecutablePlatform(ExePlatformSharedMemory);
Log.LoadLogSettingsDefaults();
@@ -62,6 +95,11 @@ int main(int argc, char **argv) {
database.LoadLogSettings(Log.log_settings);
Log.StartFileLogs();
std::string shared_mem_directory = Config->SharedMemDir;
if (MakeDirectory(shared_mem_directory)) {
Log.Out(Logs::General, Logs::Status, "Shared Memory folder doesn't exist, so we created it... '%s'", shared_mem_directory.c_str());
}
database.LoadVariables();
/* If we're running shared memory and hotfix has no custom name, we probably want to start from scratch... */
+24 -24
View File
@@ -21,13 +21,13 @@
#include "cppunit/cpptest.h"
#include "../common/fixed_memory_hash_set.h"
#include "../common/item.h"
#include "../common/item_instance.h"
class FixedMemoryHashTest : public Test::Suite {
typedef void(FixedMemoryHashTest::*TestFunction)(void);
public:
FixedMemoryHashTest() {
size_ = EQEmu::FixedMemoryHashSet<EQEmu::ItemBase>::estimated_size(72000, 190000);
size_ = EQEmu::FixedMemoryHashSet<EQEmu::ItemData>::estimated_size(72000, 190000);
data_ = new uint8[size_];
memset(data_, 0, size_);
TEST_ADD(FixedMemoryHashTest::InitTest);
@@ -49,7 +49,7 @@ public:
private:
void InitTest() {
EQEmu::FixedMemoryHashSet<EQEmu::ItemBase> hash(data_, size_, 72000, 190000);
EQEmu::FixedMemoryHashSet<EQEmu::ItemData> hash(data_, size_, 72000, 190000);
TEST_ASSERT(!hash.exists(1001));
TEST_ASSERT(hash.size() == 0);
TEST_ASSERT(hash.max_size() == 72000);
@@ -57,7 +57,7 @@ public:
}
void LoadTest() {
EQEmu::FixedMemoryHashSet<EQEmu::ItemBase> hash(data_, size_);
EQEmu::FixedMemoryHashSet<EQEmu::ItemData> hash(data_, size_);
TEST_ASSERT(!hash.exists(1001));
TEST_ASSERT(hash.size() == 0);
TEST_ASSERT(hash.max_size() == 72000);
@@ -65,8 +65,8 @@ public:
}
void InsertTest() {
EQEmu::FixedMemoryHashSet<EQEmu::ItemBase> hash(data_, size_);
EQEmu::ItemBase item;
EQEmu::FixedMemoryHashSet<EQEmu::ItemData> hash(data_, size_);
EQEmu::ItemData item;
memset(&item, 0, sizeof(item));
strcpy(item.Name, "Iron Sword");
item.ID = 1001;
@@ -79,20 +79,20 @@ public:
}
void RetrieveTest() {
EQEmu::FixedMemoryHashSet<EQEmu::ItemBase> hash(data_, size_);
EQEmu::FixedMemoryHashSet<EQEmu::ItemData> hash(data_, size_);
TEST_ASSERT(hash.exists(1001));
TEST_ASSERT(hash.size() == 1);
TEST_ASSERT(hash.max_size() == 72000);
TEST_ASSERT(!hash.empty());
EQEmu::ItemBase item = hash[1001];
EQEmu::ItemData item = hash[1001];
TEST_ASSERT(strcmp(item.Name, "Iron Sword") == 0);
TEST_ASSERT(item.ID == 1001);
}
void OverwriteTest() {
EQEmu::FixedMemoryHashSet<EQEmu::ItemBase> hash(data_, size_);
EQEmu::ItemBase item;
EQEmu::FixedMemoryHashSet<EQEmu::ItemData> hash(data_, size_);
EQEmu::ItemData item;
memset(&item, 0, sizeof(item));
strcpy(item.Name, "Steel Sword");
item.ID = 1001;
@@ -105,20 +105,20 @@ public:
}
void OverwriteRetrieveTest() {
EQEmu::FixedMemoryHashSet<EQEmu::ItemBase> hash(data_, size_);
EQEmu::FixedMemoryHashSet<EQEmu::ItemData> hash(data_, size_);
TEST_ASSERT(hash.exists(1001));
TEST_ASSERT(hash.size() == 1);
TEST_ASSERT((hash.max_size() == 72000));
TEST_ASSERT(!hash.empty());
EQEmu::ItemBase item = hash[1001];
EQEmu::ItemData item = hash[1001];
TEST_ASSERT(strcmp(item.Name, "Steel Sword") == 0);
TEST_ASSERT(item.ID == 1001);
}
void InsertAgainTest() {
EQEmu::FixedMemoryHashSet<EQEmu::ItemBase> hash(data_, size_);
EQEmu::ItemBase item;
EQEmu::FixedMemoryHashSet<EQEmu::ItemData> hash(data_, size_);
EQEmu::ItemData item;
memset(&item, 0, sizeof(item));
strcpy(item.Name, "Iron Sword");
item.ID = 1000;
@@ -132,14 +132,14 @@ public:
}
void RetrieveAgainTest() {
EQEmu::FixedMemoryHashSet<EQEmu::ItemBase> hash(data_, size_);
EQEmu::FixedMemoryHashSet<EQEmu::ItemData> hash(data_, size_);
TEST_ASSERT(hash.exists(1000));
TEST_ASSERT(hash.exists(1001));
TEST_ASSERT(hash.size() == 2);
TEST_ASSERT(hash.max_size() == 72000);
TEST_ASSERT(!hash.empty());
EQEmu::ItemBase item = hash[1000];
EQEmu::ItemData item = hash[1000];
TEST_ASSERT(strcmp(item.Name, "Iron Sword") == 0);
TEST_ASSERT(item.ID == 1000);
@@ -149,8 +149,8 @@ public:
}
void InsertBeginTest() {
EQEmu::FixedMemoryHashSet<EQEmu::ItemBase> hash(data_, size_);
EQEmu::ItemBase item;
EQEmu::FixedMemoryHashSet<EQEmu::ItemData> hash(data_, size_);
EQEmu::ItemData item;
memset(&item, 0, sizeof(item));
strcpy(item.Name, "Bronze Sword");
item.ID = 0;
@@ -165,7 +165,7 @@ public:
}
void RetrieveBeginTest() {
EQEmu::FixedMemoryHashSet<EQEmu::ItemBase> hash(data_, size_);
EQEmu::FixedMemoryHashSet<EQEmu::ItemData> hash(data_, size_);
TEST_ASSERT(hash.exists(1000));
TEST_ASSERT(hash.exists(1001));
TEST_ASSERT(hash.exists(0));
@@ -173,7 +173,7 @@ public:
TEST_ASSERT(hash.max_size() == 72000);
TEST_ASSERT(!hash.empty());
EQEmu::ItemBase item = hash[1000];
EQEmu::ItemData item = hash[1000];
TEST_ASSERT(strcmp(item.Name, "Iron Sword") == 0);
TEST_ASSERT(item.ID == 1000);
@@ -187,8 +187,8 @@ public:
}
void InsertEndTest() {
EQEmu::FixedMemoryHashSet<EQEmu::ItemBase> hash(data_, size_);
EQEmu::ItemBase item;
EQEmu::FixedMemoryHashSet<EQEmu::ItemData> hash(data_, size_);
EQEmu::ItemData item;
memset(&item, 0, sizeof(item));
strcpy(item.Name, "Jade Sword");
item.ID = 190000;
@@ -204,7 +204,7 @@ public:
}
void RetrieveEndTest() {
EQEmu::FixedMemoryHashSet<EQEmu::ItemBase> hash(data_, size_);
EQEmu::FixedMemoryHashSet<EQEmu::ItemData> hash(data_, size_);
TEST_ASSERT(hash.exists(1000));
TEST_ASSERT(hash.exists(1001));
TEST_ASSERT(hash.exists(0));
@@ -213,7 +213,7 @@ public:
TEST_ASSERT(hash.max_size() == 72000);
TEST_ASSERT(!hash.empty());
EQEmu::ItemBase item = hash[1000];
EQEmu::ItemData item = hash[1000];
TEST_ASSERT(strcmp(item.Name, "Iron Sword") == 0);
TEST_ASSERT(item.ID == 1000);
File diff suppressed because it is too large Load Diff
+83 -18
View File
@@ -43,8 +43,12 @@ if($Config{osname}=~/Win|MS/i){
$has_internet_connection = check_internet_connection();
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime();
if(-e "eqemu_server_skip_update.txt"){
$skip_self_update_check = 1;
}
#::: Check for script self update
do_self_update_check_routine();
do_self_update_check_routine() if !$skip_self_update_check;
get_perl_version();
read_eqemu_config_xml();
get_mysql_path();
@@ -488,11 +492,11 @@ sub check_internet_connection {
$count = "n";
}
if (`ping 8.8.8.8 -$count 1 -w 500`=~/Reply from|1 received/i) {
if (`ping 8.8.8.8 -$count 1 -w 500`=~/TTL|1 received/i) {
# print "[Update] We have a connection to the internet, continuing...\n";
return 1;
}
elsif (`ping 4.2.2.2 -$count 1 -w 500`=~/Reply from|1 received/i) {
elsif (`ping 4.2.2.2 -$count 1 -w 500`=~/TTL|1 received/i) {
# print "[Update] We have a connection to the internet, continuing...\n";
return 1;
}
@@ -558,6 +562,7 @@ sub do_self_update_check_routine {
}
unlink("updates_staged/eqemu_server.pl");
unlink("updates_staged");
}
}
@@ -720,13 +725,14 @@ sub show_menu_prompt {
print " [utility_scripts] Download utility scripts to run and operate the EQEmu Server\n";
if($OS eq "Windows"){
print ">>> Windows\n";
print " [windows_server_download] Updates server code from latest stable\n";
print " [windows_server_download_bots] Updates server code (bots enabled) from latest\n";
print " [windows_server_download] Updates server via latest 'stable' code\n";
print " [windows_server_latest] Updates server via latest commit 'unstable'\n";
print " [windows_server_download_bots] Updates server (bots) from latest 'stable'\n";
print " [fetch_dlls] Grabs dll's needed to run windows binaries\n";
print " [setup_loginserver] Sets up loginserver for Windows\n";
}
print " \n> main - go back to main menu\n";
print "Enter a command #> ";
print "Enter a command #> ";
$last_menu = trim($input);
}
elsif($input eq "backup_database"){ database_dump(); $dc = 1; }
@@ -741,6 +747,7 @@ sub show_menu_prompt {
elsif($input eq "quests"){ quest_files_fetch(); $dc = 1; }
elsif($input eq "lua_modules"){ lua_modules_fetch(); $dc = 1; }
elsif($input eq "windows_server_download"){ fetch_latest_windows_binaries(); $dc = 1; }
elsif($input eq "windows_server_latest"){ fetch_latest_windows_appveyor(); $dc = 1; }
elsif($input eq "windows_server_download_bots"){ fetch_latest_windows_binaries_bots(); $dc = 1; }
elsif($input eq "fetch_dlls"){ fetch_server_dlls(); $dc = 1; }
elsif($input eq "utility_scripts"){ fetch_utility_scripts(); $dc = 1; }
@@ -1063,17 +1070,50 @@ sub trim {
}
sub read_eqemu_config_xml {
my $confile = "eqemu_config.xml"; #default
open(F, "<$confile");
my $indb = 0;
while(<F>) {
s/\r//g;
if(/<host>(.*)<\/host>/i) { $host = $1; }
elsif(/<username>(.*)<\/username>/i) { $user = $1; }
elsif(/<password>(.*)<\/password>/i) { $pass = $1; }
elsif(/<db>(.*)<\/db>/i) { $db = $1; }
if(/<longname>(.*)<\/longname>/i) { $long_name = $1; }
}
open (CONFIG, "eqemu_config.xml");
while (<CONFIG>){
chomp;
$o = $_;
if($o=~/\<\!--/i){
next;
}
if($o=~/database/i && $o=~/\<\//i){
$in_database_tag = 0;
}
if($o=~/<database>/i){
print "IN DATABASE TAG\n" if $debug;
$in_database_tag = 1;
}
if($o=~/<longname>/i){
($long_name) = $o =~ /<longname>(.*)<\/longname>/;
print "Long Name: '" . $long_name . "'\n" if $debug;
}
if($in_database_tag == 1){
@left = split (">", $o);
@right = split("<", $left[1]);
$tag_data = trim($right[0]);
if($o=~/<username>/i && $in_database_tag){
$user = $tag_data;
print "Database User: '" . $user . "'\n" if $debug;
}
if($o=~/<password>/i && $in_database_tag){
$pass = $tag_data;
print "Database Pass: '" . $pass . "'\n" if $debug;
}
if($o=~/<db>/i){
$db = $tag_data;
print "Database Name: '" . $db . "'\n" if $debug;
}
if($o=~/<host>/i){
$host = $tag_data;
print "Database Host: '" . $host . "'\n" if $debug;
}
}
}
close(CONFIG);
}
#::: Fetch Latest PEQ AA's
@@ -1172,6 +1212,31 @@ sub copy_file {
copy $l_source_file, $l_destination_file;
}
sub fetch_latest_windows_appveyor {
print "[Update] Fetching Latest Windows Binaries (unstable) from Appveyor... \n";
get_remote_file("https://ci.appveyor.com/api/projects/KimLS/server/artifacts/build_x86_pdb.zip", "updates_staged/master_windows_build_pdb.zip", 1);
get_remote_file("https://ci.appveyor.com/api/projects/KimLS/server/artifacts/build_x86.zip", "updates_staged/master_windows_build.zip", 1);
print "[Update] Fetched Latest Windows Binaries (unstable) from Appveyor... \n";
print "[Update] Extracting... --- \n";
unzip('updates_staged/master_windows_build.zip', 'updates_staged/binaries/');
unzip('updates_staged/master_windows_build_pdb.zip', 'updates_staged/binaries/');
my @files;
my $start_dir = "updates_staged/binaries";
find(
sub { push @files, $File::Find::name unless -d; },
$start_dir
);
for my $file (@files) {
$destination_file = $file;
$destination_file =~s/updates_staged\/binaries\///g;
print "[Update] Installing :: " . $destination_file . "\n";
copy_file($file, $destination_file);
}
print "[Update] Done\n";
rmtree('updates_staged');
}
sub fetch_latest_windows_binaries {
print "[Update] Fetching Latest Windows Binaries... \n";
get_remote_file($install_repository_request_url . "master_windows_build.zip", "updates_staged/master_windows_build.zip", 1);
@@ -2154,4 +2219,4 @@ sub generate_random_password {
map $alphanumeric[rand @alphanumeric], 0..$passwordsize;
return $randpassword;
}
}
+1
View File
@@ -354,6 +354,7 @@
9098|2016_08_26_object_size_tilt.sql|SHOW COLUMNS FROM `object` LIKE 'size'|empty|
9099|2016_08_27_ip_exemptions.sql|SHOW TABLES LIKE 'ip_exemptions'|empty|
9100|2016_08_27_object_display_name.sql|SHOW COLUMNS FROM `object` LIKE 'display_name'|empty|
9101|2016_12_01_pcnpc_only.sql|SHOW COLUMNS FROM `spells_new` LIKE 'pcnpc_only_flag'|empty|
# Upgrade conditions:
# This won't be needed after this system is implemented, but it is used database that are not
@@ -1,4 +0,0 @@
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Bots:BotLevelsWithOwner', 'true', 'Auto-updates bots with ding.');
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (2, 'Bots:BotLevelsWithOwner', 'true', 'Auto-updates bots with ding.');
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (4, 'Bots:BotLevelsWithOwner', 'true', 'Auto-updates bots with ding.');
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (10, 'Bots:BotLevelsWithOwner', 'true', 'Auto-updates bots with ding.');
@@ -0,0 +1 @@
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Bots:BotLevelsWithOwner', 'true', 'Auto-updates bots with ding.');
@@ -0,0 +1,2 @@
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Bots:CasterStopMeleeLevel', '13', 'Level at which caster bots stop melee attacks');
@@ -0,0 +1 @@
UPDATE ground_spawns SET max_z = -99999 WHERE max_x != min_x OR max_y != min_y
@@ -0,0 +1 @@
INSERT INTO `rule_values` (`ruleset_id`, `rule_name`, `rule_value`, `notes`) VALUES (1, 'Character:GrantHoTTOnCreate', 'false', 'Grant Health of Target\'s Target leadership AA on character creation');
@@ -0,0 +1,2 @@
ALTER TABLE `spells_new` CHANGE `field183` `pcnpc_only_flag` INT(11) DEFAULT 0;
ALTER TABLE `spells_new` CHANGE `field184` `cast_not_standing` INT(11) DEFAULT 0;
+2 -2
View File
@@ -25,7 +25,7 @@
#include "../common/eq_packet_structs.h"
#include "../common/packet_dump.h"
#include "../common/eq_stream_intf.h"
#include "../common/item.h"
#include "../common/inventory_profile.h"
#include "../common/races.h"
#include "../common/classes.h"
#include "../common/languages.h"
@@ -1399,7 +1399,7 @@ bool Client::OPCharCreate(char *name, CharCreate_Struct *cc)
{
PlayerProfile_Struct pp;
ExtendedProfile_Struct ext;
Inventory inv;
EQEmu::InventoryProfile inv;
time_t bday = time(nullptr);
char startzone[50]={0};
uint32 i;
+13 -14
View File
@@ -17,10 +17,9 @@
*/
#include "worlddb.h"
//#include "../common/item.h"
#include "../common/string_util.h"
#include "../common/eq_packet_structs.h"
#include "../common/item.h"
#include "../common/inventory_profile.h"
#include "../common/rulesys.h"
#include <iostream>
#include <cstdlib>
@@ -97,7 +96,7 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou
for (auto row = results.begin(); row != results.end(); ++row) {
CharacterSelectEntry_Struct *cse = (CharacterSelectEntry_Struct *)buff_ptr;
PlayerProfile_Struct pp;
Inventory inv;
EQEmu::InventoryProfile inv;
uint32 character_id = (uint32)atoi(row[0]);
uint8 has_home = 0;
uint8 has_bind = 0;
@@ -117,12 +116,12 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou
cse->Gender = (uint8)atoi(row[2]);
cse->Face = (uint8)atoi(row[15]);
for (uint32 matslot = 0; matslot < EQEmu::textures::TextureCount; matslot++) { // Processed below
for (uint32 matslot = 0; matslot < EQEmu::textures::materialCount; matslot++) { // Processed below
cse->Equip[matslot].Material = 0;
cse->Equip[matslot].Unknown1 = 0;
cse->Equip[matslot].EliteMaterial = 0;
cse->Equip[matslot].HeroForgeModel = 0;
cse->Equip[matslot].Material2 = 0;
cse->Equip[matslot].EliteModel = 0;
cse->Equip[matslot].HerosForgeModel = 0;
cse->Equip[matslot].Unknown2 = 0;
cse->Equip[matslot].Color = 0;
}
@@ -245,12 +244,12 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou
/* Load Inventory */
// If we ensure that the material data is updated appropriately, we can do away with inventory loads
if (GetInventory(accountID, cse->Name, &inv)) {
const EQEmu::ItemBase* item = nullptr;
const ItemInst* inst = nullptr;
const EQEmu::ItemData* item = nullptr;
const EQEmu::ItemInstance* inst = nullptr;
int16 invslot = 0;
for (uint32 matslot = 0; matslot < EQEmu::textures::TextureCount; matslot++) {
invslot = Inventory::CalcSlotFromMaterial(matslot);
for (uint32 matslot = EQEmu::textures::textureBegin; matslot < EQEmu::textures::materialCount; matslot++) {
invslot = EQEmu::InventoryProfile::CalcSlotFromMaterial(matslot);
if (invslot == INVALID_INDEX) { continue; }
inst = inv.GetItem(invslot);
if (inst == nullptr) { continue; }
@@ -270,7 +269,7 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou
cse->Equip[matslot].Material = idfile;
}
}
if (matslot == EQEmu::textures::TexturePrimary) {
if (matslot == EQEmu::textures::weaponPrimary) {
cse->PrimaryIDFile = idfile;
}
else {
@@ -288,8 +287,8 @@ void WorldDatabase::GetCharSelectInfo(uint32 accountID, EQApplicationPacket **ou
// Armor Materials/Models
cse->Equip[matslot].Material = item->Material;
cse->Equip[matslot].EliteMaterial = item->EliteMaterial;
cse->Equip[matslot].HeroForgeModel = inst->GetOrnamentHeroModel(matslot);
cse->Equip[matslot].EliteModel = item->EliteMaterial;
cse->Equip[matslot].HerosForgeModel = inst->GetOrnamentHeroModel(matslot);
cse->Equip[matslot].Color = color;
}
}
+6 -1
View File
@@ -423,7 +423,7 @@ void Mob::WakeTheDead(uint16 spell_id, Mob *target, uint32 duration)
uint32 sitem = 0;
sitem = CorpseToUse->GetWornItem(x);
if(sitem){
const EQEmu::ItemBase * itm = database.GetItem(sitem);
const EQEmu::ItemData * itm = database.GetItem(sitem);
npca->AddLootDrop(itm, &npca->itemlist, 1, 1, 255, true, true);
}
}
@@ -1181,6 +1181,11 @@ void Client::ActivateAlternateAdvancementAbility(int rank_id, int target_id) {
if (!IsCastWhileInvis(rank->spell))
CommonBreakInvisible();
if (spells[rank->spell].sneak && (!hidden || (hidden && (Timer::GetCurrentTime() - tmHidden) < 4000))) {
Message_StringID(MT_SpellFailure, SNEAK_RESTRICT);
return;
}
// Bards can cast instant cast AAs while they are casting another song
if(spells[rank->spell].cast_time == 0 && GetClass() == BARD && IsBardSong(casting_spell_id)) {
if(!SpellFinished(rank->spell, entity_list.GetMob(target_id), EQEmu::CastingSlot::AltAbility, spells[rank->spell].mana, -1, spells[rank->spell].ResistDiff, false)) {
+2 -2
View File
@@ -1343,8 +1343,8 @@ bool Mob::PassCharismaCheck(Mob* caster, uint16 spell_id) {
void Mob::RogueEvade(Mob *other)
{
int amount = other->GetHateAmount(this) - (GetLevel() * 13);
other->SetHateAmountOnEnt(this, std::max(1, amount));
int amount = other->GetHateAmount(this) * zone->random.Int(40, 70) / 100;
other->SetHateAmountOnEnt(this, std::max(100, amount));
return;
}
+305 -89
View File
@@ -51,12 +51,12 @@ extern WorldServer worldserver;
extern EntityList entity_list;
extern Zone* zone;
bool Mob::AttackAnimation(EQEmu::skills::SkillType &skillinuse, int Hand, const ItemInst* weapon)
bool Mob::AttackAnimation(EQEmu::skills::SkillType &skillinuse, int Hand, const EQEmu::ItemInstance* weapon)
{
// Determine animation
int type = 0;
if (weapon && weapon->IsClassCommon()) {
const EQEmu::ItemBase* item = weapon->GetItem();
const EQEmu::ItemData* item = weapon->GetItem();
Log.Out(Logs::Detail, Logs::Attack, "Weapon skill : %i", item->ItemType);
@@ -132,7 +132,7 @@ bool Mob::AttackAnimation(EQEmu::skills::SkillType &skillinuse, int Hand, const
}
// If we're attacking with the secondary hand, play the dual wield anim
if (Hand == EQEmu::legacy::SlotSecondary) // DW anim
if (Hand == EQEmu::inventory::slotSecondary) // DW anim
type = animDualWield;
DoAnim(type);
@@ -305,6 +305,16 @@ bool Mob::CheckHitChance(Mob* other, EQEmu::skills::SkillType skillinuse, int Ha
float tohit_roll = zone->random.Real(0, 100);
Log.Out(
Logs::General,
Logs::Combat,
"[%s] [Mob::CheckHitChance] Chance [%.2f] ToHitRoll [%.2f] Hit? [%s]",
GetCleanName(),
chancetohit,
tohit_roll,
(tohit_roll <= chancetohit) ? "true" : "false"
);
Log.Out(Logs::Detail, Logs::Attack, "Final hit chance: %.2f%%. Hit roll %.2f", chancetohit, tohit_roll);
return(tohit_roll <= chancetohit);
@@ -373,7 +383,7 @@ bool Mob::AvoidDamage(Mob *other, int32 &damage, int hand)
// riposte -- it may seem crazy, but if the attacker has SPA 173 on them, they are immune to Ripo
bool ImmuneRipo = attacker->aabonuses.RiposteChance || attacker->spellbonuses.RiposteChance || attacker->itembonuses.RiposteChance;
// Need to check if we have something in MainHand to actually attack with (or fists)
if (hand != EQEmu::legacy::SlotRange && (CanThisClassRiposte() || IsEnraged()) && InFront && !ImmuneRipo) {
if (hand != EQEmu::inventory::slotRange && (CanThisClassRiposte() || IsEnraged()) && InFront && !ImmuneRipo) {
if (IsEnraged()) {
damage = -3;
Log.Out(Logs::Detail, Logs::Combat, "I am enraged, riposting frontal attack.");
@@ -395,7 +405,7 @@ bool Mob::AvoidDamage(Mob *other, int32 &damage, int hand)
chance -= chance * counter;
}
// AA Slippery Attacks
if (hand == EQEmu::legacy::SlotSecondary) {
if (hand == EQEmu::inventory::slotSecondary) {
int slip = aabonuses.OffhandRiposteFail + itembonuses.OffhandRiposteFail + spellbonuses.OffhandRiposteFail;
chance += chance * slip / 100;
}
@@ -440,7 +450,7 @@ bool Mob::AvoidDamage(Mob *other, int32 &damage, int hand)
}
// parry
if (CanThisClassParry() && InFront && hand != EQEmu::legacy::SlotRange) {
if (CanThisClassParry() && InFront && hand != EQEmu::inventory::slotRange) {
if (IsClient())
CastToClient()->CheckIncreaseSkill(EQEmu::skills::SkillParry, other, -10);
// check auto discs ... I guess aa/items too :P
@@ -522,6 +532,16 @@ void Mob::MeleeMitigation(Mob *attacker, int32 &damage, int32 minhit, ExtraAttac
float aa_mit = (aabonuses.CombatStability + itembonuses.CombatStability +
spellbonuses.CombatStability) / 100.0f;
Log.Out(
Logs::General,
Logs::Combat,
"[%s] [Mob::MeleeMitigation] Stability Bonuses | AA [%i] Item [%i] Spell [%i] ",
GetCleanName(),
aabonuses.CombatStability,
itembonuses.CombatStability,
spellbonuses.CombatStability
);
if (RuleB(Combat, UseIntervalAC)) {
float softcap = (GetSkill(EQEmu::skills::SkillDefense) + GetLevel()) *
RuleR(Combat, SoftcapFactor) * (1.0 + aa_mit);
@@ -534,6 +554,14 @@ void Mob::MeleeMitigation(Mob *attacker, int32 &damage, int32 minhit, ExtraAttac
float monkweight = RuleI(Combat, MonkACBonusWeight);
monkweight = mod_monk_weight(monkweight, attacker);
Log.Out(
Logs::General,
Logs::Combat,
"[%s] [Mob::MeleeMitigation] Soft Cap [%.2f]",
GetCleanName(),
softcap
);
if (IsClient()) {
armor = CastToClient()->GetRawACNoShield(shield_ac);
weight = (CastToClient()->CalcCurrentWeight() / 10.0);
@@ -637,6 +665,17 @@ void Mob::MeleeMitigation(Mob *attacker, int32 &damage, int32 minhit, ExtraAttac
attack_rating = attacker->mod_attack_rating(attack_rating, this);
Log.Out(
Logs::General,
Logs::Combat,
"[%s] [Mob::MeleeMitigation] Attack Rating [%.2f] Mitigation Rating [%.2f] Damage [%i] MinDmg [%i]",
GetCleanName(),
attack_rating,
mitigation_rating,
damage,
minhit
);
damage = GetMeleeMitDmg(attacker, damage, minhit, mitigation_rating, attack_rating);
} else {
////////////////////////////////////////////////////////
@@ -697,6 +736,14 @@ void Mob::MeleeMitigation(Mob *attacker, int32 &damage, int32 minhit, ExtraAttac
if (damage < 0)
damage = 0;
Log.Out(
Logs::General,
Logs::Combat,
"[%s] [Mob::MeleeMitigation] Final Damage [%i]",
GetCleanName(),
damage
);
}
// This is called when the Mob is the one being hit
@@ -707,6 +754,15 @@ int32 Mob::GetMeleeMitDmg(Mob *attacker, int32 damage, int32 minhit,
float mit_roll = zone->random.Real(0, mit_rating);
float atk_roll = zone->random.Real(0, atk_rating);
Log.Out(
Logs::General,
Logs::Combat,
"[%s] [Mob::GetMeleeMitDmg] MitigationRoll [%.2f] AtkRoll [%.2f]",
GetCleanName(),
mit_roll,
atk_roll
);
if (atk_roll > mit_roll) {
float a_diff = atk_roll - mit_roll;
float thac0 = atk_rating * RuleR(Combat, ACthac0Factor);
@@ -731,10 +787,50 @@ int32 Mob::GetMeleeMitDmg(Mob *attacker, int32 damage, int32 minhit,
d = 20.0;
float interval = (damage - minhit) / 20.0;
Log.Out(
Logs::General,
Logs::Combat,
"[%s] [Mob::GetMeleeMitDmg] Interval [%.2f] d [%.2f]",
GetCleanName(),
interval,
d
);
damage -= ((int)d * interval);
Log.Out(
Logs::General,
Logs::Combat,
"[%s] [Mob::GetMeleeMitDmg] Damage [%.2f] Post Interval",
GetCleanName(),
damage
);
damage -= (minhit * itembonuses.MeleeMitigation / 100);
damage -= (damage * (spellbonuses.MeleeMitigationEffect + itembonuses.MeleeMitigationEffect + aabonuses.MeleeMitigationEffect) / 100);
Log.Out(
Logs::General,
Logs::Combat,
"[%s] [Mob::GetMeleeMitDmg] Damage [%.2f] Mitigation [%i] Post Mitigation MinDmg",
GetCleanName(),
damage,
itembonuses.MeleeMitigation
);
damage -= (damage * (spellbonuses.MeleeMitigationEffect + itembonuses.MeleeMitigationEffect + aabonuses.MeleeMitigationEffect) / 100);
Log.Out(
Logs::General,
Logs::Combat,
"[%s] [Mob::GetMeleeMitDmg] Damage [%.2f] SpellMit [%i] ItemMit [%i] AAMit [%i] Post All Mit Bonuses",
GetCleanName(),
damage,
spellbonuses.MeleeMitigationEffect,
itembonuses.MeleeMitigationEffect,
aabonuses.MeleeMitigationEffect
);
return damage;
}
@@ -786,9 +882,9 @@ int32 Client::GetMeleeMitDmg(Mob *attacker, int32 damage, int32 minhit,
//Returns the weapon damage against the input mob
//if we cannot hit the mob with the current weapon we will get a value less than or equal to zero
//Else we know we can hit.
//GetWeaponDamage(mob*, const ItemBase*) is intended to be used for mobs or any other situation where we do not have a client inventory item
//GetWeaponDamage(mob*, const ItemInst*) is intended to be used for situations where we have a client inventory item
int Mob::GetWeaponDamage(Mob *against, const EQEmu::ItemBase *weapon_item) {
//GetWeaponDamage(mob*, const EQEmu::ItemData*) is intended to be used for mobs or any other situation where we do not have a client inventory item
//GetWeaponDamage(mob*, const EQEmu::ItemInstance*) is intended to be used for situations where we have a client inventory item
int Mob::GetWeaponDamage(Mob *against, const EQEmu::ItemData *weapon_item) {
int dmg = 0;
int banedmg = 0;
@@ -858,7 +954,7 @@ int Mob::GetWeaponDamage(Mob *against, const EQEmu::ItemBase *weapon_item) {
}
}
if(!eledmg && !banedmg){
if(!banedmg){
if(!GetSpecialAbility(SPECATK_BANE))
return 0;
else
@@ -888,7 +984,7 @@ int Mob::GetWeaponDamage(Mob *against, const EQEmu::ItemBase *weapon_item) {
return dmg;
}
int Mob::GetWeaponDamage(Mob *against, const ItemInst *weapon_item, uint32 *hate)
int Mob::GetWeaponDamage(Mob *against, const EQEmu::ItemInstance *weapon_item, uint32 *hate)
{
int dmg = 0;
int banedmg = 0;
@@ -927,7 +1023,7 @@ int Mob::GetWeaponDamage(Mob *against, const ItemInst *weapon_item, uint32 *hate
} else {
bool MagicGloves = false;
if (IsClient()) {
const ItemInst *gloves = CastToClient()->GetInv().GetItem(EQEmu::legacy::SlotHands);
const EQEmu::ItemInstance *gloves = CastToClient()->GetInv().GetItem(EQEmu::inventory::slotHands);
if (gloves)
MagicGloves = gloves->GetItemMagical(true);
}
@@ -979,7 +1075,7 @@ int Mob::GetWeaponDamage(Mob *against, const ItemInst *weapon_item, uint32 *hate
banedmg = against->CheckBaneDamage(weapon_item);
if (against->GetSpecialAbility(IMMUNE_MELEE_EXCEPT_BANE)) {
if (!eledmg && !banedmg) {
if (!banedmg) {
if (!GetSpecialAbility(SPECATK_BANE))
return 0;
else
@@ -1035,13 +1131,13 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
if (GetFeigned())
return false; // Rogean: How can you attack while feigned? Moved up from Aggro Code.
ItemInst* weapon;
if (Hand == EQEmu::legacy::SlotSecondary){ // Kaiyodo - Pick weapon from the attacking hand
weapon = GetInv().GetItem(EQEmu::legacy::SlotSecondary);
EQEmu::ItemInstance* weapon;
if (Hand == EQEmu::inventory::slotSecondary){ // Kaiyodo - Pick weapon from the attacking hand
weapon = GetInv().GetItem(EQEmu::inventory::slotSecondary);
OffHandAtk(true);
}
else{
weapon = GetInv().GetItem(EQEmu::legacy::SlotPrimary);
weapon = GetInv().GetItem(EQEmu::inventory::slotPrimary);
OffHandAtk(false);
}
@@ -1072,6 +1168,11 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
//if weapon damage > 0 then we know we can hit the target with this weapon
//otherwise we cannot and we set the damage to -5 later on
if(weapon_damage > 0){
auto shield_inc = spellbonuses.ShieldEquipDmgMod + itembonuses.ShieldEquipDmgMod + aabonuses.ShieldEquipDmgMod;
if (shield_inc > 0 && HasShieldEquiped() && Hand == EQEmu::inventory::slotPrimary) {
weapon_damage = weapon_damage * (100 + shield_inc) / 100;
hate = hate * (100 + shield_inc) / 100;
}
//Berserker Berserk damage bonus
if(IsBerserk() && GetClass() == BERSERKER){
@@ -1085,8 +1186,28 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
return (true);
int min_hit = 1;
Log.Out(
Logs::General,
Logs::Combat,
"[%s] [Client::Attack] Damage Table [%u] WeaponDMG [%i]",
GetCleanName(),
GetDamageTable(skillinuse),
weapon_damage
);
int max_hit = (2*weapon_damage*GetDamageTable(skillinuse)) / 100;
Log.Out(
Logs::General,
Logs::Combat,
"[%s] [ClientAttack] DamageDone [%i] BaseDamage [%i] HitSkill [%i]",
GetCleanName(),
max_hit,
weapon_damage,
skillinuse
);
if(GetLevel() < 10 && max_hit > RuleI(Combat, HitCapPre10))
max_hit = (RuleI(Combat, HitCapPre10));
else if(GetLevel() < 20 && max_hit > RuleI(Combat, HitCapPre20))
@@ -1109,12 +1230,12 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
int ucDamageBonus = 0;
if (Hand == EQEmu::legacy::SlotPrimary && GetLevel() >= 28 && IsWarriorClass())
if (Hand == EQEmu::inventory::slotPrimary && GetLevel() >= 28 && IsWarriorClass())
{
// Damage bonuses apply only to hits from the main hand (Hand == MainPrimary) by characters level 28 and above
// who belong to a melee class. If we're here, then all of these conditions apply.
ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const EQEmu::ItemBase*) nullptr);
ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const EQEmu::ItemData*) nullptr);
min_hit += (int) ucDamageBonus;
max_hit += (int) ucDamageBonus;
@@ -1122,10 +1243,10 @@ bool Client::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, b
}
#endif
//Live AA - Sinister Strikes *Adds weapon damage bonus to offhand weapon.
if (Hand == EQEmu::legacy::SlotSecondary) {
if (Hand == EQEmu::inventory::slotSecondary) {
if (aabonuses.SecondaryDmgInc || itembonuses.SecondaryDmgInc || spellbonuses.SecondaryDmgInc){
ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const EQEmu::ItemBase*) nullptr, true);
ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const EQEmu::ItemData*) nullptr, true);
min_hit += (int) ucDamageBonus;
max_hit += (int) ucDamageBonus;
@@ -1583,28 +1704,28 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
FaceTarget(GetTarget());
EQEmu::skills::SkillType skillinuse = EQEmu::skills::SkillHandtoHand;
if (Hand == EQEmu::legacy::SlotPrimary) {
if (Hand == EQEmu::inventory::slotPrimary) {
skillinuse = static_cast<EQEmu::skills::SkillType>(GetPrimSkill());
OffHandAtk(false);
}
if (Hand == EQEmu::legacy::SlotSecondary) {
if (Hand == EQEmu::inventory::slotSecondary) {
skillinuse = static_cast<EQEmu::skills::SkillType>(GetSecSkill());
OffHandAtk(true);
}
//figure out what weapon they are using, if any
const EQEmu::ItemBase* weapon = nullptr;
if (Hand == EQEmu::legacy::SlotPrimary && equipment[EQEmu::legacy::SlotPrimary] > 0)
weapon = database.GetItem(equipment[EQEmu::legacy::SlotPrimary]);
else if (equipment[EQEmu::legacy::SlotSecondary])
weapon = database.GetItem(equipment[EQEmu::legacy::SlotSecondary]);
const EQEmu::ItemData* weapon = nullptr;
if (Hand == EQEmu::inventory::slotPrimary && equipment[EQEmu::inventory::slotPrimary] > 0)
weapon = database.GetItem(equipment[EQEmu::inventory::slotPrimary]);
else if (equipment[EQEmu::inventory::slotSecondary])
weapon = database.GetItem(equipment[EQEmu::inventory::slotSecondary]);
//We dont factor much from the weapon into the attack.
//Just the skill type so it doesn't look silly using punching animations and stuff while wielding weapons
if(weapon) {
Log.Out(Logs::Detail, Logs::Combat, "Attacking with weapon: %s (%d) (too bad im not using it for much)", weapon->Name, weapon->ID);
if (Hand == EQEmu::legacy::SlotSecondary && weapon->ItemType == EQEmu::item::ItemTypeShield){
if (Hand == EQEmu::inventory::slotSecondary && weapon->ItemType == EQEmu::item::ItemTypeShield){
Log.Out(Logs::Detail, Logs::Combat, "Attack with shield canceled.");
return false;
}
@@ -1645,7 +1766,7 @@ bool NPC::Attack(Mob* other, int Hand, bool bRiposte, bool IsStrikethrough, bool
//do attack animation regardless of whether or not we can hit below
int16 charges = 0;
ItemInst weapon_inst(weapon, charges);
EQEmu::ItemInstance weapon_inst(weapon, charges);
AttackAnimation(skillinuse, Hand, &weapon_inst);
//basically "if not immune" then do the attack
@@ -2291,11 +2412,6 @@ void Mob::AddToHateList(Mob* other, uint32 hate /*= 0*/, int32 damage /*= 0*/, b
// Spell Casting Subtlety etc
int hatemod = 100 + other->spellbonuses.hatemod + other->itembonuses.hatemod + other->aabonuses.hatemod;
int32 shieldhatemod = other->spellbonuses.ShieldEquipHateMod + other->itembonuses.ShieldEquipHateMod + other->aabonuses.ShieldEquipHateMod;
if (shieldhatemod && other->HasShieldEquiped())
hatemod += shieldhatemod;
if(hatemod < 1)
hatemod = 1;
hate = ((hate * (hatemod))/100);
@@ -2515,7 +2631,7 @@ void Mob::DamageShield(Mob* attacker, bool spell_ds) {
}
}
uint8 Mob::GetWeaponDamageBonus(const EQEmu::ItemBase *weapon, bool offhand)
uint8 Mob::GetWeaponDamageBonus(const EQEmu::ItemData *weapon, bool offhand)
{
// dev quote with old and new formulas
// https://forums.daybreakgames.com/eq/index.php?threads/test-update-09-17-15.226618/page-5#post-3326194
@@ -3501,7 +3617,7 @@ void Mob::TryDefensiveProc(Mob *on, uint16 hand) {
float ProcChance, ProcBonus;
on->GetDefensiveProcChances(ProcBonus, ProcChance, hand , this);
if (hand != EQEmu::legacy::SlotPrimary)
if (hand != EQEmu::inventory::slotPrimary)
ProcChance /= 2;
int level_penalty = 0;
@@ -3526,7 +3642,7 @@ void Mob::TryDefensiveProc(Mob *on, uint16 hand) {
}
}
void Mob::TryWeaponProc(const ItemInst* weapon_g, Mob *on, uint16 hand) {
void Mob::TryWeaponProc(const EQEmu::ItemInstance* weapon_g, Mob *on, uint16 hand) {
if(!on) {
SetTarget(nullptr);
Log.Out(Logs::General, Logs::Error, "A null Mob object was passed to Mob::TryWeaponProc for evaluation!");
@@ -3544,12 +3660,12 @@ void Mob::TryWeaponProc(const ItemInst* weapon_g, Mob *on, uint16 hand) {
}
if(!weapon_g) {
TrySpellProc(nullptr, (const EQEmu::ItemBase*)nullptr, on);
TrySpellProc(nullptr, (const EQEmu::ItemData*)nullptr, on);
return;
}
if (!weapon_g->IsClassCommon()) {
TrySpellProc(nullptr, (const EQEmu::ItemBase*)nullptr, on);
TrySpellProc(nullptr, (const EQEmu::ItemData*)nullptr, on);
return;
}
@@ -3562,7 +3678,7 @@ void Mob::TryWeaponProc(const ItemInst* weapon_g, Mob *on, uint16 hand) {
return;
}
void Mob::TryWeaponProc(const ItemInst *inst, const EQEmu::ItemBase *weapon, Mob *on, uint16 hand)
void Mob::TryWeaponProc(const EQEmu::ItemInstance *inst, const EQEmu::ItemData *weapon, Mob *on, uint16 hand)
{
if (!weapon)
@@ -3574,7 +3690,7 @@ void Mob::TryWeaponProc(const ItemInst *inst, const EQEmu::ItemBase *weapon, Mob
ProcBonus += static_cast<float>(itembonuses.ProcChance) / 10.0f; // Combat Effects
float ProcChance = GetProcChances(ProcBonus, hand);
if (hand != EQEmu::legacy::SlotPrimary) //Is Archery intened to proc at 50% rate?
if (hand != EQEmu::inventory::slotPrimary) //Is Archery intened to proc at 50% rate?
ProcChance /= 2;
// Try innate proc on weapon
@@ -3611,11 +3727,11 @@ void Mob::TryWeaponProc(const ItemInst *inst, const EQEmu::ItemBase *weapon, Mob
proced = false;
if (!proced && inst) {
for (int r = 0; r < EQEmu::legacy::ITEM_COMMON_SIZE; r++) {
const ItemInst *aug_i = inst->GetAugment(r);
for (int r = EQEmu::inventory::socketBegin; r < EQEmu::inventory::SocketCount; r++) {
const EQEmu::ItemInstance *aug_i = inst->GetAugment(r);
if (!aug_i) // no aug, try next slot!
continue;
const EQEmu::ItemBase *aug = aug_i->GetItem();
const EQEmu::ItemData *aug = aug_i->GetItem();
if (!aug)
continue;
@@ -3645,18 +3761,18 @@ void Mob::TryWeaponProc(const ItemInst *inst, const EQEmu::ItemBase *weapon, Mob
return;
}
void Mob::TrySpellProc(const ItemInst *inst, const EQEmu::ItemBase *weapon, Mob *on, uint16 hand)
void Mob::TrySpellProc(const EQEmu::ItemInstance *inst, const EQEmu::ItemData *weapon, Mob *on, uint16 hand)
{
float ProcBonus = static_cast<float>(spellbonuses.SpellProcChance +
itembonuses.SpellProcChance + aabonuses.SpellProcChance);
float ProcChance = 0.0f;
ProcChance = GetProcChances(ProcBonus, hand);
if (hand != EQEmu::legacy::SlotPrimary) //Is Archery intened to proc at 50% rate?
if (hand != EQEmu::inventory::slotPrimary) //Is Archery intened to proc at 50% rate?
ProcChance /= 2;
bool rangedattk = false;
if (weapon && hand == EQEmu::legacy::SlotRange) {
if (weapon && hand == EQEmu::inventory::slotRange) {
if (weapon->ItemType == EQEmu::item::ItemTypeArrow ||
weapon->ItemType == EQEmu::item::ItemTypeLargeThrowing ||
weapon->ItemType == EQEmu::item::ItemTypeSmallThrowing ||
@@ -3665,11 +3781,11 @@ void Mob::TrySpellProc(const ItemInst *inst, const EQEmu::ItemBase *weapon, Mob
}
}
if (!weapon && hand == EQEmu::legacy::SlotRange && GetSpecialAbility(SPECATK_RANGED_ATK))
if (!weapon && hand == EQEmu::inventory::slotRange && GetSpecialAbility(SPECATK_RANGED_ATK))
rangedattk = true;
for (uint32 i = 0; i < MAX_PROCS; i++) {
if (IsPet() && hand != EQEmu::legacy::SlotPrimary) //Pets can only proc spell procs from their primay hand (ie; beastlord pets)
if (IsPet() && hand != EQEmu::inventory::slotPrimary) //Pets can only proc spell procs from their primay hand (ie; beastlord pets)
continue; // If pets ever can proc from off hand, this will need to change
// Not ranged
@@ -3732,7 +3848,7 @@ void Mob::TrySpellProc(const ItemInst *inst, const EQEmu::ItemBase *weapon, Mob
}
}
if (HasSkillProcs() && hand != EQEmu::legacy::SlotRange){ //We check ranged skill procs within the attack functions.
if (HasSkillProcs() && hand != EQEmu::inventory::slotRange){ //We check ranged skill procs within the attack functions.
uint16 skillinuse = 28;
if (weapon)
skillinuse = GetSkillByItemType(weapon->ItemType);
@@ -3773,12 +3889,32 @@ void Mob::TryPetCriticalHit(Mob *defender, uint16 skill, int32 &damage)
int32 CritPetChance = owner->aabonuses.PetCriticalHit + owner->itembonuses.PetCriticalHit + owner->spellbonuses.PetCriticalHit;
int32 CritChanceBonus = GetCriticalChanceBonus(skill);
Log.Out(
Logs::General,
Logs::Combat,
"[%s] [Mob::TryPetCriticalHit] CritPetChance [%i] CritChanceBonus [%i] | Bonuses AA [%i] Item [%i] Spell [%i]",
GetCleanName(),
CritPetChance,
CritChanceBonus,
owner->aabonuses.PetCriticalHit,
owner->itembonuses.PetCriticalHit,
owner->spellbonuses.PetCriticalHit
);
if (CritPetChance || critChance) {
//For pets use PetCriticalHit for base chance, pets do not innately critical with without it
//even if buffed with a CritChanceBonus effects.
critChance += CritPetChance;
critChance += critChance*CritChanceBonus/100.0f;
Log.Out(
Logs::General,
Logs::Combat,
"[%s] [Mob::TryPetCriticalHit] critChance [%.2f] PostCalcs",
GetCleanName(),
critChance
);
}
if(critChance > 0){
@@ -3789,9 +3925,27 @@ void Mob::TryPetCriticalHit(Mob *defender, uint16 skill, int32 &damage)
{
critMod += GetCritDmgMob(skill) * 2; // To account for base crit mod being 200 not 100
damage = (damage * critMod) / 100;
entity_list.FilteredMessageClose_StringID(this, false, 200,
MT_CritMelee, FilterMeleeCrits, CRITICAL_HIT,
GetCleanName(), itoa(damage));
Log.Out(
Logs::General,
Logs::Combat,
"[%s] [Mob::TryPetCriticalHit] critMod [%.2f] DmgMod [%i] DamageDone [%i]",
GetCleanName(),
critMod,
GetCritDmgMob(skill),
damage
);
entity_list.FilteredMessageClose_StringID(
this,
false,
200,
MT_CritMelee,
FilterMeleeCrits,
CRITICAL_HIT,
GetCleanName(),
itoa(damage)
);
}
}
}
@@ -3879,18 +4033,38 @@ void Mob::TryCriticalHit(Mob *defender, uint16 skill, int32 &damage, ExtraAttack
//Get Base CritChance from Dex. (200 = ~1.6%, 255 = ~2.0%, 355 = ~2.20%) Fall off rate > 255
//http://giline.versus.jp/shiden/su.htm , http://giline.versus.jp/shiden/damage_e.htm
if (GetDEX() <= 255)
if (GetDEX() <= 255) {
critChance += (float(GetDEX()) / 125.0f);
else if (GetDEX() > 255)
critChance += (float(GetDEX()-255)/ 500.0f) + 2.0f;
critChance += critChance*(float)CritChanceBonus /100.0f;
}
else if (GetDEX() > 255) {
critChance += (float(GetDEX() - 255) / 500.0f) + 2.0f;
}
critChance += critChance * (float) CritChanceBonus / 100.0f;
}
Log.Out(
Logs::General,
Logs::Combat,
"[%s] [Mob::TryCriticalHit] CritChance [%.2f] CritChanceBonus [%i] Dex [%i] Post-Dex-Block",
GetCleanName(),
critChance,
CritChanceBonus,
GetDEX()
);
if(opts) {
critChance *= opts->crit_percent;
critChance += opts->crit_flat;
}
Log.Out(
Logs::General,
Logs::Combat,
"[%s] [Mob::TryCriticalHit] CritChance [%.2f]",
GetCleanName(),
critChance
);
if(critChance > 0) {
critChance /= 100;
@@ -3915,6 +4089,18 @@ void Mob::TryCriticalHit(Mob *defender, uint16 skill, int32 &damage, ExtraAttack
}
critMod += GetCritDmgMob(skill) * 2; // To account for base crit mod being 200 not 100
Log.Out(
Logs::General,
Logs::Combat,
"[%s] [Mob::TryCriticalHit] CritChance [%.2f] CritMod [%u] GetCritDmgMod [%i] CripSuccess [%s]",
GetCleanName(),
critChance,
critMod,
GetCritDmgMob(skill),
crip_success ? "true" : "false"
);
damage = damage * critMod / 100;
bool deadlySuccess = false;
@@ -3980,7 +4166,7 @@ void Mob::DoRiposte(Mob *defender)
if (!defender)
return;
defender->Attack(this, EQEmu::legacy::SlotPrimary, true);
defender->Attack(this, EQEmu::inventory::slotPrimary, true);
if (HasDied())
return;
@@ -3991,7 +4177,7 @@ void Mob::DoRiposte(Mob *defender)
if (DoubleRipChance && zone->random.Roll(DoubleRipChance)) {
Log.Out(Logs::Detail, Logs::Combat,
"Preforming a double riposted from SE_DoubleRiposte (%d percent chance)", DoubleRipChance);
defender->Attack(this, EQEmu::legacy::SlotPrimary, true);
defender->Attack(this, EQEmu::inventory::slotPrimary, true);
if (HasDied())
return;
}
@@ -4004,7 +4190,7 @@ void Mob::DoRiposte(Mob *defender)
Log.Out(Logs::Detail, Logs::Combat,
"Preforming a double riposted from SE_GiveDoubleRiposte base1 == 0 (%d percent chance)",
DoubleRipChance);
defender->Attack(this, EQEmu::legacy::SlotPrimary, true);
defender->Attack(this, EQEmu::inventory::slotPrimary, true);
if (HasDied())
return;
}
@@ -4044,6 +4230,15 @@ void Mob::ApplyMeleeDamageBonus(uint16 skill, int32 &damage,ExtraAttackOptions *
if (opts)
dmgbonusmod += opts->melee_damage_bonus_flat;
Log.Out(
Logs::General,
Logs::Combat,
"[%s] [Mob::ApplyMeleeDamageBonus] DmgBonusMod [%i] Dmg [%i]",
GetCleanName(),
dmgbonusmod,
damage
);
damage += damage * dmgbonusmod / 100;
}
@@ -4288,7 +4483,7 @@ float Mob::GetSkillProcChances(uint16 ReuseTime, uint16 hand) {
if (!ReuseTime && hand) {
weapon_speed = GetWeaponSpeedbyHand(hand);
ProcChance = static_cast<float>(weapon_speed) * (RuleR(Combat, AvgProcsPerMinute) / 60000.0f);
if (hand != EQEmu::legacy::SlotPrimary)
if (hand != EQEmu::inventory::slotPrimary)
ProcChance /= 2;
}
@@ -4408,7 +4603,28 @@ void Mob::CommonOutgoingHitSuccess(Mob* defender, int32 &damage, EQEmu::skills::
return;
ApplyMeleeDamageBonus(skillInUse, damage, opts);
Log.Out(
Logs::General,
Logs::Combat,
"[%s] [Mob::CommonOutgoingHitSuccess] Dmg [%i] Post ApplyMeleeDamageBonus",
GetCleanName(),
damage
);
damage += (damage * defender->GetSkillDmgTaken(skillInUse, opts) / 100) + (GetSkillDmgAmt(skillInUse) + defender->GetFcDamageAmtIncoming(this, 0, true, skillInUse));
Log.Out(
Logs::General,
Logs::Combat,
"[%s] [Mob::CommonOutgoingHitSuccess] Dmg [%i] SkillDmgTaken [%i] SkillDmgtAmt [%i] FcDmgAmtIncoming [%i] Post DmgCalcs",
GetCleanName(),
damage,
defender->GetSkillDmgTaken(skillInUse, opts),
GetSkillDmgAmt(skillInUse),
defender->GetFcDamageAmtIncoming(this, 0, true, skillInUse)
);
TryCriticalHit(defender, skillInUse, damage,opts);
CheckNumHitsRemaining(NumHit::OutgoingHitSuccess);
}
@@ -4478,26 +4694,26 @@ void Client::SetAttackTimer()
Timer *TimerToUse = nullptr;
for (int i = EQEmu::legacy::SlotRange; i <= EQEmu::legacy::SlotSecondary; i++) {
for (int i = EQEmu::inventory::slotRange; i <= EQEmu::inventory::slotSecondary; i++) {
//pick a timer
if (i == EQEmu::legacy::SlotPrimary)
if (i == EQEmu::inventory::slotPrimary)
TimerToUse = &attack_timer;
else if (i == EQEmu::legacy::SlotRange)
else if (i == EQEmu::inventory::slotRange)
TimerToUse = &ranged_timer;
else if (i == EQEmu::legacy::SlotSecondary)
else if (i == EQEmu::inventory::slotSecondary)
TimerToUse = &attack_dw_timer;
else //invalid slot (hands will always hit this)
continue;
const EQEmu::ItemBase *ItemToUse = nullptr;
const EQEmu::ItemData *ItemToUse = nullptr;
//find our item
ItemInst *ci = GetInv().GetItem(i);
EQEmu::ItemInstance *ci = GetInv().GetItem(i);
if (ci)
ItemToUse = ci->GetItem();
//special offhand stuff
if (i == EQEmu::legacy::SlotSecondary) {
if (i == EQEmu::inventory::slotSecondary) {
//if we cant dual wield, skip it
if (!CanThisClassDualWield() || HasTwoHanderEquipped()) {
attack_dw_timer.Disable();
@@ -4571,19 +4787,19 @@ void NPC::SetAttackTimer()
else
speed = static_cast<int>(((attack_delay / haste_mod) + ((hhe / 100.0f) * attack_delay)) * 100);
for (int i = EQEmu::legacy::SlotRange; i <= EQEmu::legacy::SlotSecondary; i++) {
for (int i = EQEmu::inventory::slotRange; i <= EQEmu::inventory::slotSecondary; i++) {
//pick a timer
if (i == EQEmu::legacy::SlotPrimary)
if (i == EQEmu::inventory::slotPrimary)
TimerToUse = &attack_timer;
else if (i == EQEmu::legacy::SlotRange)
else if (i == EQEmu::inventory::slotRange)
TimerToUse = &ranged_timer;
else if (i == EQEmu::legacy::SlotSecondary)
else if (i == EQEmu::inventory::slotSecondary)
TimerToUse = &attack_dw_timer;
else //invalid slot (hands will always hit this)
continue;
//special offhand stuff
if (i == EQEmu::legacy::SlotSecondary) {
if (i == EQEmu::inventory::slotSecondary) {
// SPECATK_QUAD is uncheesable
if(!CanThisClassDualWield() || (HasTwoHanderEquipped() && !GetSpecialAbility(SPECATK_QUAD))) {
attack_dw_timer.Disable();
@@ -4605,7 +4821,7 @@ void Client::DoAttackRounds(Mob *target, int hand, bool IsFromSpell)
bool candouble = CanThisClassDoubleAttack();
// extra off hand non-sense, can only double with skill of 150 or above
// or you have any amount of GiveDoubleAttack
if (candouble && hand == EQEmu::legacy::SlotSecondary)
if (candouble && hand == EQEmu::inventory::slotSecondary)
candouble = GetSkill(EQEmu::skills::SkillDoubleAttack) > 149 || (aabonuses.GiveDoubleAttack + spellbonuses.GiveDoubleAttack + itembonuses.GiveDoubleAttack) > 0;
if (candouble) {
@@ -4613,7 +4829,7 @@ void Client::DoAttackRounds(Mob *target, int hand, bool IsFromSpell)
if (CheckDoubleAttack()) {
Attack(target, hand, false, false, IsFromSpell);
// you can only triple from the main hand
if (hand == EQEmu::legacy::SlotPrimary && CanThisClassTripleAttack()) {
if (hand == EQEmu::inventory::slotPrimary && CanThisClassTripleAttack()) {
CheckIncreaseSkill(EQEmu::skills::SkillTripleAttack, target, -10);
if (CheckTripleAttack())
Attack(target, hand, false, false, IsFromSpell);
@@ -4621,7 +4837,7 @@ void Client::DoAttackRounds(Mob *target, int hand, bool IsFromSpell)
}
}
if (hand == EQEmu::legacy::SlotPrimary) {
if (hand == EQEmu::inventory::slotPrimary) {
// According to http://www.monkly-business.net/forums/showpost.php?p=312095&postcount=168 a dev told them flurry isn't dependant on triple attack
// the parses kind of back that up and all of my parses seemed to be 4 or 5 attacks in the round which would work out to be
// doubles or triples with 2 from flurries or triple with 1 or 2 flurries ... Going with the "dev quote" I guess like we've always had it
@@ -4674,9 +4890,9 @@ void Mob::DoMainHandAttackRounds(Mob *target, ExtraAttackOptions *opts, int spec
if (RuleB(Combat, UseLiveCombatRounds)) {
// A "quad" on live really is just a successful dual wield where both double attack
// The mobs that could triple lost the ability to when the triple attack skill was added in
Attack(target, EQEmu::legacy::SlotPrimary, false, false, false, opts, special);
Attack(target, EQEmu::inventory::slotPrimary, false, false, false, opts, special);
if (CanThisClassDoubleAttack() && CheckDoubleAttack()){
Attack(target, EQEmu::legacy::SlotPrimary, false, false, false, opts, special);
Attack(target, EQEmu::inventory::slotPrimary, false, false, false, opts, special);
if ((IsPet() || IsTempPet()) && IsPetOwnerClient()){
int chance = spellbonuses.PC_Pet_Flurry + itembonuses.PC_Pet_Flurry + aabonuses.PC_Pet_Flurry;
@@ -4690,14 +4906,14 @@ void Mob::DoMainHandAttackRounds(Mob *target, ExtraAttackOptions *opts, int spec
if (IsNPC()) {
int16 n_atk = CastToNPC()->GetNumberOfAttacks();
if (n_atk <= 1) {
Attack(target, EQEmu::legacy::SlotPrimary, false, false, false, opts, special);
Attack(target, EQEmu::inventory::slotPrimary, false, false, false, opts, special);
} else {
for (int i = 0; i < n_atk; ++i) {
Attack(target, EQEmu::legacy::SlotPrimary, false, false, false, opts, special);
Attack(target, EQEmu::inventory::slotPrimary, false, false, false, opts, special);
}
}
} else {
Attack(target, EQEmu::legacy::SlotPrimary, false, false, false, opts, special);
Attack(target, EQEmu::inventory::slotPrimary, false, false, false, opts, special);
}
// we use this random value in three comparisons with different
@@ -4708,15 +4924,15 @@ void Mob::DoMainHandAttackRounds(Mob *target, ExtraAttackOptions *opts, int spec
// check double attack, this is NOT the same rules that clients use...
&&
RandRoll < (GetLevel() + NPCDualAttackModifier)) {
Attack(target, EQEmu::legacy::SlotPrimary, false, false, false, opts, special);
Attack(target, EQEmu::inventory::slotPrimary, false, false, false, opts, special);
// lets see if we can do a triple attack with the main hand
// pets are excluded from triple and quads...
if ((GetSpecialAbility(SPECATK_TRIPLE) || GetSpecialAbility(SPECATK_QUAD)) && !IsPet() &&
RandRoll < (GetLevel() + NPCTripleAttackModifier)) {
Attack(target, EQEmu::legacy::SlotPrimary, false, false, false, opts, special);
Attack(target, EQEmu::inventory::slotPrimary, false, false, false, opts, special);
// now lets check the quad attack
if (GetSpecialAbility(SPECATK_QUAD) && RandRoll < (GetLevel() + NPCQuadAttackModifier)) {
Attack(target, EQEmu::legacy::SlotPrimary, false, false, false, opts, special);
Attack(target, EQEmu::inventory::slotPrimary, false, false, false, opts, special);
}
}
}
@@ -4730,11 +4946,11 @@ void Mob::DoOffHandAttackRounds(Mob *target, ExtraAttackOptions *opts, int speci
// For now, SPECATK_QUAD means innate DW when Combat:UseLiveCombatRounds is true
if ((GetSpecialAbility(SPECATK_INNATE_DW) ||
(RuleB(Combat, UseLiveCombatRounds) && GetSpecialAbility(SPECATK_QUAD))) ||
GetEquipment(EQEmu::textures::TextureSecondary) != 0) {
GetEquipment(EQEmu::textures::weaponSecondary) != 0) {
if (CheckDualWield()) {
Attack(target, EQEmu::legacy::SlotSecondary, false, false, false, opts, special);
Attack(target, EQEmu::inventory::slotSecondary, false, false, false, opts, special);
if (CanThisClassDoubleAttack() && GetLevel() > 35 && CheckDoubleAttack()){
Attack(target, EQEmu::legacy::SlotSecondary, false, false, false, opts, special);
Attack(target, EQEmu::inventory::slotSecondary, false, false, false, opts, special);
if ((IsPet() || IsTempPet()) && IsPetOwnerClient()){
int chance = spellbonuses.PC_Pet_Flurry + itembonuses.PC_Pet_Flurry + aabonuses.PC_Pet_Flurry;
+1 -1
View File
@@ -36,7 +36,7 @@ public:
//abstract virtual function implementations requird by base abstract class
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill) { return true; }
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, int special = 0) { return; }
virtual bool Attack(Mob* other, int Hand = EQEmu::legacy::SlotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
virtual bool Attack(Mob* other, int Hand = EQEmu::inventory::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
ExtraAttackOptions *opts = nullptr, int special = 0) { return false; }
virtual bool HasRaid() { return false; }
virtual bool HasGroup() { return false; }
+42 -60
View File
@@ -17,7 +17,7 @@
*/
#include "../common/classes.h"
#include "../common/global_define.h"
#include "../common/item.h"
#include "../common/item_instance.h"
#include "../common/rulesys.h"
#include "../common/skills.h"
#include "../common/spdat.h"
@@ -145,35 +145,35 @@ void Client::CalcItemBonuses(StatBonuses* newbon) {
unsigned int i;
// Update: MainAmmo should only calc skill mods (TODO: Check for other cases)
for (i = EQEmu::legacy::SlotCharm; i <= EQEmu::legacy::SlotAmmo; i++) {
const ItemInst* inst = m_inv[i];
for (i = EQEmu::inventory::slotCharm; i <= EQEmu::inventory::slotAmmo; i++) {
const EQEmu::ItemInstance* inst = m_inv[i];
if(inst == 0)
continue;
AddItemBonuses(inst, newbon, false, false, 0, (i == EQEmu::legacy::SlotAmmo));
AddItemBonuses(inst, newbon, false, false, 0, (i == EQEmu::inventory::slotAmmo));
//These are given special flags due to how often they are checked for various spell effects.
const EQEmu::ItemBase *item = inst->GetItem();
if (i == EQEmu::legacy::SlotSecondary && (item && item->ItemType == EQEmu::item::ItemTypeShield))
const EQEmu::ItemData *item = inst->GetItem();
if (i == EQEmu::inventory::slotSecondary && (item && item->ItemType == EQEmu::item::ItemTypeShield))
SetShieldEquiped(true);
else if (i == EQEmu::legacy::SlotPrimary && (item && item->ItemType == EQEmu::item::ItemType2HBlunt)) {
else if (i == EQEmu::inventory::slotPrimary && (item && item->ItemType == EQEmu::item::ItemType2HBlunt)) {
SetTwoHandBluntEquiped(true);
SetTwoHanderEquipped(true);
}
else if (i == EQEmu::legacy::SlotPrimary && (item && (item->ItemType == EQEmu::item::ItemType2HSlash || item->ItemType == EQEmu::item::ItemType2HPiercing)))
else if (i == EQEmu::inventory::slotPrimary && (item && (item->ItemType == EQEmu::item::ItemType2HSlash || item->ItemType == EQEmu::item::ItemType2HPiercing)))
SetTwoHanderEquipped(true);
}
//Power Source Slot
if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF)
{
const ItemInst* inst = m_inv[EQEmu::legacy::SlotPowerSource];
const EQEmu::ItemInstance* inst = m_inv[EQEmu::inventory::slotPowerSource];
if(inst)
AddItemBonuses(inst, newbon);
}
//tribute items
for (i = 0; i < EQEmu::legacy::TRIBUTE_SIZE; i++) {
const ItemInst* inst = m_inv[EQEmu::legacy::TRIBUTE_BEGIN + i];
const EQEmu::ItemInstance* inst = m_inv[EQEmu::legacy::TRIBUTE_BEGIN + i];
if(inst == 0)
continue;
AddItemBonuses(inst, newbon, false, true);
@@ -181,8 +181,8 @@ void Client::CalcItemBonuses(StatBonuses* newbon) {
//Optional ability to have worn effects calculate as an addititive bonus instead of highest value
if (RuleI(Spells, AdditiveBonusWornType) && RuleI(Spells, AdditiveBonusWornType) != EQEmu::item::ItemEffectWorn){
for (i = EQEmu::legacy::SlotCharm; i < EQEmu::legacy::SlotAmmo; i++) {
const ItemInst* inst = m_inv[i];
for (i = EQEmu::inventory::slotCharm; i < EQEmu::inventory::slotAmmo; i++) {
const EQEmu::ItemInstance* inst = m_inv[i];
if(inst == 0)
continue;
AdditiveWornBonuses(inst, newbon);
@@ -208,7 +208,7 @@ void Client::ProcessItemCaps()
itembonuses.ATK = std::min(itembonuses.ATK, CalcItemATKCap());
}
void Client::AddItemBonuses(const ItemInst *inst, StatBonuses *newbon, bool isAug, bool isTribute, int rec_override, bool ammo_slot_item)
void Client::AddItemBonuses(const EQEmu::ItemInstance *inst, StatBonuses *newbon, bool isAug, bool isTribute, int rec_override, bool ammo_slot_item)
{
if (!inst || !inst->IsClassCommon()) {
return;
@@ -218,7 +218,7 @@ void Client::AddItemBonuses(const ItemInst *inst, StatBonuses *newbon, bool isAu
return;
}
const EQEmu::ItemBase *item = inst->GetItem();
const EQEmu::ItemData *item = inst->GetItem();
if (!isTribute && !inst->IsEquipable(GetBaseRace(), GetClass())) {
if (item->ItemType != EQEmu::item::ItemTypeFood && item->ItemType != EQEmu::item::ItemTypeDrink)
@@ -527,12 +527,12 @@ void Client::AddItemBonuses(const ItemInst *inst, StatBonuses *newbon, bool isAu
}
if (!isAug) {
for (int i = 0; i < EQEmu::legacy::ITEM_COMMON_SIZE; i++)
for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++)
AddItemBonuses(inst->GetAugment(i), newbon, true, false, rec_level, ammo_slot_item);
}
}
void Client::AdditiveWornBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug) {
void Client::AdditiveWornBonuses(const EQEmu::ItemInstance *inst, StatBonuses* newbon, bool isAug) {
/*
Powerful Non-live like option allows developers to add worn effects on items that
@@ -550,7 +550,7 @@ void Client::AdditiveWornBonuses(const ItemInst *inst, StatBonuses* newbon, bool
if(inst->GetAugmentType()==0 && isAug == true)
return;
const EQEmu::ItemBase *item = inst->GetItem();
const EQEmu::ItemData *item = inst->GetItem();
if(!inst->IsEquipable(GetBaseRace(),GetClass()))
return;
@@ -565,7 +565,7 @@ void Client::AdditiveWornBonuses(const ItemInst *inst, StatBonuses* newbon, bool
if (!isAug)
{
int i;
for (i = 0; i < EQEmu::legacy::ITEM_COMMON_SIZE; i++) {
for (i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) {
AdditiveWornBonuses(inst->GetAugment(i),newbon,true);
}
}
@@ -580,9 +580,9 @@ void Client::CalcEdibleBonuses(StatBonuses* newbon) {
{
if (food && drink)
break;
const ItemInst* inst = GetInv().GetItem(i);
const EQEmu::ItemInstance* inst = GetInv().GetItem(i);
if (inst && inst->GetItem() && inst->IsClassCommon()) {
const EQEmu::ItemBase *item = inst->GetItem();
const EQEmu::ItemData *item = inst->GetItem();
if (item->ItemType == EQEmu::item::ItemTypeFood && !food)
food = true;
else if (item->ItemType == EQEmu::item::ItemTypeDrink && !drink)
@@ -596,9 +596,9 @@ void Client::CalcEdibleBonuses(StatBonuses* newbon) {
{
if (food && drink)
break;
const ItemInst* inst = GetInv().GetItem(i);
const EQEmu::ItemInstance* inst = GetInv().GetItem(i);
if (inst && inst->GetItem() && inst->IsClassCommon()) {
const EQEmu::ItemBase *item = inst->GetItem();
const EQEmu::ItemData *item = inst->GetItem();
if (item->ItemType == EQEmu::item::ItemTypeFood && !food)
food = true;
else if (item->ItemType == EQEmu::item::ItemTypeDrink && !drink)
@@ -940,12 +940,8 @@ void Mob::ApplyAABonuses(const AA::Rank &rank, StatBonuses *newbon)
case SE_ShieldBlock:
newbon->ShieldBlock += base1;
break;
case SE_ShieldEquipHateMod:
newbon->ShieldEquipHateMod += base1;
break;
case SE_ShieldEquipDmgMod:
newbon->ShieldEquipDmgMod[0] += base1;
newbon->ShieldEquipDmgMod[1] += base2;
newbon->ShieldEquipDmgMod += base1;
break;
case SE_SecondaryDmgInc:
newbon->SecondaryDmgInc = true;
@@ -2655,13 +2651,8 @@ void Mob::ApplySpellsBonuses(uint16 spell_id, uint8 casterlevel, StatBonuses *ne
new_bonus->ShieldBlock += effect_value;
break;
case SE_ShieldEquipHateMod:
new_bonus->ShieldEquipHateMod += effect_value;
break;
case SE_ShieldEquipDmgMod:
new_bonus->ShieldEquipDmgMod[0] += effect_value;
new_bonus->ShieldEquipDmgMod[1] += base2;
new_bonus->ShieldEquipDmgMod += effect_value;
break;
case SE_BlockBehind:
@@ -3205,7 +3196,7 @@ void NPC::CalcItemBonuses(StatBonuses *newbon)
if(newbon){
for (int i = 0; i < EQEmu::legacy::EQUIPMENT_SIZE; i++){
const EQEmu::ItemBase *cur = database.GetItem(equipment[i]);
const EQEmu::ItemData *cur = database.GetItem(equipment[i]);
if(cur){
//basic stats
newbon->AC += cur->AC;
@@ -3299,7 +3290,7 @@ void Client::CalcItemScale() {
//Power Source Slot
if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF)
{
if (CalcItemScale(EQEmu::legacy::SlotPowerSource, EQEmu::legacy::SlotPowerSource))
if (CalcItemScale(EQEmu::inventory::slotPowerSource, EQEmu::inventory::slotPowerSource))
changed = true;
}
@@ -3314,10 +3305,10 @@ bool Client::CalcItemScale(uint32 slot_x, uint32 slot_y) {
bool changed = false;
uint32 i;
for (i = slot_x; i <= slot_y; i++) {
if (i == EQEmu::legacy::SlotAmmo) // moved here from calling procedure to facilitate future range changes where MainAmmo may not be the last slot
if (i == EQEmu::inventory::slotAmmo) // moved here from calling procedure to facilitate future range changes where MainAmmo may not be the last slot
continue;
ItemInst* inst = m_inv.GetItem(i);
EQEmu::ItemInstance* inst = m_inv.GetItem(i);
if(inst == nullptr)
continue;
@@ -3325,7 +3316,7 @@ bool Client::CalcItemScale(uint32 slot_x, uint32 slot_y) {
// TEST CODE: test for bazaar trader crashing with charm items
if (Trader)
if (i >= EQEmu::legacy::GENERAL_BAGS_BEGIN && i <= EQEmu::legacy::GENERAL_BAGS_END) {
ItemInst* parent_item = m_inv.GetItem(Inventory::CalcSlotId(i));
EQEmu::ItemInstance* parent_item = m_inv.GetItem(EQEmu::InventoryProfile::CalcSlotId(i));
if (parent_item && parent_item->GetItem()->ID == 17899) // trader satchel
continue;
}
@@ -3344,9 +3335,9 @@ bool Client::CalcItemScale(uint32 slot_x, uint32 slot_y) {
}
//iterate all augments
for (int x = AUG_INDEX_BEGIN; x < EQEmu::legacy::ITEM_COMMON_SIZE; ++x)
for (int x = EQEmu::inventory::socketBegin; x < EQEmu::inventory::SocketCount; ++x)
{
ItemInst * a_inst = inst->GetAugment(x);
EQEmu::ItemInstance * a_inst = inst->GetAugment(x);
if(!a_inst)
continue;
@@ -3393,7 +3384,7 @@ void Client::DoItemEnterZone() {
//Power Source Slot
if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF)
{
if (DoItemEnterZone(EQEmu::legacy::SlotPowerSource, EQEmu::legacy::SlotPowerSource))
if (DoItemEnterZone(EQEmu::inventory::slotPowerSource, EQEmu::inventory::slotPowerSource))
changed = true;
}
@@ -3407,10 +3398,10 @@ bool Client::DoItemEnterZone(uint32 slot_x, uint32 slot_y) {
// behavior change: 'slot_y' is now [RANGE]_END and not [RANGE]_END + 1
bool changed = false;
for(uint32 i = slot_x; i <= slot_y; i++) {
if (i == EQEmu::legacy::SlotAmmo) // moved here from calling procedure to facilitate future range changes where MainAmmo may not be the last slot
if (i == EQEmu::inventory::slotAmmo) // moved here from calling procedure to facilitate future range changes where MainAmmo may not be the last slot
continue;
ItemInst* inst = m_inv.GetItem(i);
EQEmu::ItemInstance* inst = m_inv.GetItem(i);
if(!inst)
continue;
@@ -3418,7 +3409,7 @@ bool Client::DoItemEnterZone(uint32 slot_x, uint32 slot_y) {
// TEST CODE: test for bazaar trader crashing with charm items
if (Trader)
if (i >= EQEmu::legacy::GENERAL_BAGS_BEGIN && i <= EQEmu::legacy::GENERAL_BAGS_END) {
ItemInst* parent_item = m_inv.GetItem(Inventory::CalcSlotId(i));
EQEmu::ItemInstance* parent_item = m_inv.GetItem(EQEmu::InventoryProfile::CalcSlotId(i));
if (parent_item && parent_item->GetItem()->ID == 17899) // trader satchel
continue;
}
@@ -3429,7 +3420,7 @@ bool Client::DoItemEnterZone(uint32 slot_x, uint32 slot_y) {
uint16 oldexp = inst->GetExp();
parse->EventItem(EVENT_ITEM_ENTER_ZONE, this, inst, nullptr, "", 0);
if (i <= EQEmu::legacy::SlotAmmo || i == EQEmu::legacy::SlotPowerSource) {
if (i <= EQEmu::inventory::slotAmmo || i == EQEmu::inventory::slotPowerSource) {
parse->EventItem(EVENT_EQUIP_ITEM, this, inst, nullptr, "", i);
}
@@ -3439,7 +3430,7 @@ bool Client::DoItemEnterZone(uint32 slot_x, uint32 slot_y) {
update_slot = true;
}
} else {
if (i <= EQEmu::legacy::SlotAmmo || i == EQEmu::legacy::SlotPowerSource) {
if (i <= EQEmu::inventory::slotAmmo || i == EQEmu::inventory::slotPowerSource) {
parse->EventItem(EVENT_EQUIP_ITEM, this, inst, nullptr, "", i);
}
@@ -3447,9 +3438,9 @@ bool Client::DoItemEnterZone(uint32 slot_x, uint32 slot_y) {
}
//iterate all augments
for (int x = AUG_INDEX_BEGIN; x < EQEmu::legacy::ITEM_COMMON_SIZE; ++x)
for (int x = EQEmu::inventory::socketBegin; x < EQEmu::inventory::SocketCount; ++x)
{
ItemInst *a_inst = inst->GetAugment(x);
EQEmu::ItemInstance *a_inst = inst->GetAugment(x);
if(!a_inst)
continue;
@@ -4555,19 +4546,10 @@ void Mob::NegateSpellsBonuses(uint16 spell_id)
itembonuses.DoubleRangedAttack = effect_value;
break;
case SE_ShieldEquipHateMod:
spellbonuses.ShieldEquipHateMod = effect_value;
aabonuses.ShieldEquipHateMod = effect_value;
itembonuses.ShieldEquipHateMod = effect_value;
break;
case SE_ShieldEquipDmgMod:
spellbonuses.ShieldEquipDmgMod[0] = effect_value;
spellbonuses.ShieldEquipDmgMod[1] = effect_value;
aabonuses.ShieldEquipDmgMod[0] = effect_value;
aabonuses.ShieldEquipDmgMod[1] = effect_value;
itembonuses.ShieldEquipDmgMod[0] = effect_value;
itembonuses.ShieldEquipDmgMod[1] = effect_value;
spellbonuses.ShieldEquipDmgMod = effect_value;
aabonuses.ShieldEquipDmgMod = effect_value;
itembonuses.ShieldEquipDmgMod = effect_value;
break;
case SE_TriggerMeleeThreshold:
+173 -173
View File
@@ -229,13 +229,13 @@ void Bot::SetBotSpellID(uint32 newSpellID) {
}
uint32 Bot::GetBotArcheryRange() {
const ItemInst *range_inst = GetBotItem(EQEmu::legacy::SlotRange);
const ItemInst *ammo_inst = GetBotItem(EQEmu::legacy::SlotAmmo);
const EQEmu::ItemInstance *range_inst = GetBotItem(EQEmu::inventory::slotRange);
const EQEmu::ItemInstance *ammo_inst = GetBotItem(EQEmu::inventory::slotAmmo);
if (!range_inst || !ammo_inst)
return 0;
const EQEmu::ItemBase *range_item = range_inst->GetItem();
const EQEmu::ItemBase *ammo_item = ammo_inst->GetItem();
const EQEmu::ItemData *range_item = range_inst->GetItem();
const EQEmu::ItemData *ammo_item = ammo_inst->GetItem();
if (!range_item || !ammo_item || range_item->ItemType != EQEmu::item::ItemTypeBow || ammo_item->ItemType != EQEmu::item::ItemTypeArrow)
return 0;
@@ -246,15 +246,15 @@ uint32 Bot::GetBotArcheryRange() {
void Bot::ChangeBotArcherWeapons(bool isArcher) {
if((GetClass()==WARRIOR) || (GetClass()==PALADIN) || (GetClass()==RANGER) || (GetClass()==SHADOWKNIGHT) || (GetClass()==ROGUE)) {
if(!isArcher) {
BotAddEquipItem(EQEmu::legacy::SlotPrimary, GetBotItemBySlot(EQEmu::legacy::SlotPrimary));
BotAddEquipItem(EQEmu::legacy::SlotSecondary, GetBotItemBySlot(EQEmu::legacy::SlotSecondary));
BotAddEquipItem(EQEmu::inventory::slotPrimary, GetBotItemBySlot(EQEmu::inventory::slotPrimary));
BotAddEquipItem(EQEmu::inventory::slotSecondary, GetBotItemBySlot(EQEmu::inventory::slotSecondary));
SetAttackTimer();
BotGroupSay(this, "My blade is ready");
} else {
BotRemoveEquipItem(EQEmu::legacy::SlotPrimary);
BotRemoveEquipItem(EQEmu::legacy::SlotSecondary);
BotAddEquipItem(EQEmu::legacy::SlotAmmo, GetBotItemBySlot(EQEmu::legacy::SlotAmmo));
BotAddEquipItem(EQEmu::legacy::SlotSecondary, GetBotItemBySlot(EQEmu::legacy::SlotRange));
BotRemoveEquipItem(EQEmu::inventory::slotPrimary);
BotRemoveEquipItem(EQEmu::inventory::slotSecondary);
BotAddEquipItem(EQEmu::inventory::slotAmmo, GetBotItemBySlot(EQEmu::inventory::slotAmmo));
BotAddEquipItem(EQEmu::inventory::slotSecondary, GetBotItemBySlot(EQEmu::inventory::slotRange));
SetAttackTimer();
BotGroupSay(this, "My bow is true and ready");
}
@@ -1175,11 +1175,11 @@ void Bot::GenerateArmorClass() {
uint16 Bot::GetPrimarySkillValue() {
EQEmu::skills::SkillType skill = EQEmu::skills::HIGHEST_SKILL; //because nullptr == 0, which is 1H Slashing, & we want it to return 0 from GetSkill
bool equiped = m_inv.GetItem(EQEmu::legacy::SlotPrimary);
bool equiped = m_inv.GetItem(EQEmu::inventory::slotPrimary);
if(!equiped)
skill = EQEmu::skills::SkillHandtoHand;
else {
uint8 type = m_inv.GetItem(EQEmu::legacy::SlotPrimary)->GetItem()->ItemType; //is this the best way to do this?
uint8 type = m_inv.GetItem(EQEmu::inventory::slotPrimary)->GetItem()->ItemType; //is this the best way to do this?
switch(type) {
case EQEmu::item::ItemType1HSlash:
skill = EQEmu::skills::Skill1HSlashing;
@@ -1900,13 +1900,13 @@ void Bot::BotRangedAttack(Mob* other) {
return;
}
ItemInst* rangedItem = GetBotItem(EQEmu::legacy::SlotRange);
const EQEmu::ItemBase* RangeWeapon = 0;
EQEmu::ItemInstance* rangedItem = GetBotItem(EQEmu::inventory::slotRange);
const EQEmu::ItemData* RangeWeapon = 0;
if(rangedItem)
RangeWeapon = rangedItem->GetItem();
ItemInst* ammoItem = GetBotItem(EQEmu::legacy::SlotAmmo);
const EQEmu::ItemBase* Ammo = 0;
EQEmu::ItemInstance* ammoItem = GetBotItem(EQEmu::inventory::slotAmmo);
const EQEmu::ItemData* Ammo = 0;
if(ammoItem)
Ammo = ammoItem->GetItem();
@@ -2002,7 +2002,7 @@ void Bot::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, EQEmu::skills:
int damage = 0;
uint32 hate = 0;
int Hand = EQEmu::legacy::SlotPrimary;
int Hand = EQEmu::inventory::slotPrimary;
if (hate == 0 && weapon_damage > 1)
hate = weapon_damage;
@@ -2015,7 +2015,7 @@ void Bot::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, EQEmu::skills:
int32 min_hit = 1;
int32 max_hit = ((2 * weapon_damage * GetDamageTable(skillinuse)) / 100);
if(GetLevel() >= 28 && IsWarriorClass()) {
int ucDamageBonus = GetWeaponDamageBonus((const EQEmu::ItemBase*) nullptr);
int ucDamageBonus = GetWeaponDamageBonus((const EQEmu::ItemData*) nullptr);
min_hit += (int) ucDamageBonus;
max_hit += (int) ucDamageBonus;
hate += ucDamageBonus;
@@ -2031,7 +2031,7 @@ void Bot::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, EQEmu::skills:
else
damage = zone->random.Int(min_hit, max_hit);
if (other->AvoidDamage(this, damage, CanRiposte ? EQEmu::legacy::SlotRange : EQEmu::legacy::SlotPrimary)) { // MainRange excludes ripo, primary doesn't have any extra behavior
if (other->AvoidDamage(this, damage, CanRiposte ? EQEmu::inventory::slotRange : EQEmu::inventory::slotPrimary)) { // MainRange excludes ripo, primary doesn't have any extra behavior
if (damage == -3) {
DoRiposte(other);
if (HasDied())
@@ -2056,8 +2056,8 @@ void Bot::DoMeleeSkillAttackDmg(Mob* other, uint16 weapon_damage, EQEmu::skills:
damage = -5;
if (skillinuse == EQEmu::skills::SkillBash){
const ItemInst* inst = GetBotItem(EQEmu::legacy::SlotSecondary);
const EQEmu::ItemBase* botweapon = 0;
const EQEmu::ItemInstance* inst = GetBotItem(EQEmu::inventory::slotSecondary);
const EQEmu::ItemData* botweapon = 0;
if(inst)
botweapon = inst->GetItem();
@@ -2103,21 +2103,21 @@ void Bot::ApplySpecialAttackMod(EQEmu::skills::SkillType skill, int32 &dmg, int3
case EQEmu::skills::SkillFlyingKick:
case EQEmu::skills::SkillRoundKick:
case EQEmu::skills::SkillKick:
item_slot = EQEmu::legacy::SlotFeet;
item_slot = EQEmu::inventory::slotFeet;
break;
case EQEmu::skills::SkillBash:
item_slot = EQEmu::legacy::SlotSecondary;
item_slot = EQEmu::inventory::slotSecondary;
break;
case EQEmu::skills::SkillDragonPunch:
case EQEmu::skills::SkillEagleStrike:
case EQEmu::skills::SkillTigerClaw:
item_slot = EQEmu::legacy::SlotHands;
item_slot = EQEmu::inventory::slotHands;
break;
}
if (item_slot >= EQEmu::legacy::EQUIPMENT_BEGIN){
const ItemInst* inst = GetBotItem(item_slot);
const EQEmu::ItemBase* botweapon = 0;
const EQEmu::ItemInstance* inst = GetBotItem(item_slot);
const EQEmu::ItemData* botweapon = 0;
if(inst)
botweapon = inst->GetItem();
@@ -2391,7 +2391,7 @@ void Bot::AI_Process() {
}
}
atCombatRange = true;
} else if(IsBotCaster() && GetLevel() > 12) {
} else if(IsBotCaster() && GetLevel() >= RuleI(Bots, CasterStopMeleeLevel)) {
if(IsBotCasterCombatRange(GetTarget()))
atCombatRange = true;
}
@@ -2440,7 +2440,7 @@ void Bot::AI_Process() {
if(GetTarget()->GetHPRatio() <= 99.0f)
BotRangedAttack(GetTarget());
}
else if(!IsBotArcher() && (!(IsBotCaster() && GetLevel() > 12)) && GetTarget() && !IsStunned() && !IsMezzed() && (GetAppearance() != eaDead)) {
else if(!IsBotArcher() && (!(IsBotCaster() && GetLevel() >= RuleI(Bots, CasterStopMeleeLevel))) && GetTarget() && !IsStunned() && !IsMezzed() && (GetAppearance() != eaDead)) {
// we can't fight if we don't have a target, are stun/mezzed or dead..
// Stop attacking if the target is enraged
if((IsEngaged() && !BehindMob(GetTarget(), GetX(), GetY()) && GetTarget()->IsEnraged()) || GetBotStance() == BotStancePassive)
@@ -2449,23 +2449,23 @@ void Bot::AI_Process() {
// First, special attack per class (kick, backstab etc..)
DoClassAttacks(GetTarget());
if(attack_timer.Check()) {
Attack(GetTarget(), EQEmu::legacy::SlotPrimary);
TriggerDefensiveProcs(GetTarget(), EQEmu::legacy::SlotPrimary, false);
ItemInst *wpn = GetBotItem(EQEmu::legacy::SlotPrimary);
TryWeaponProc(wpn, GetTarget(), EQEmu::legacy::SlotPrimary);
Attack(GetTarget(), EQEmu::inventory::slotPrimary);
TriggerDefensiveProcs(GetTarget(), EQEmu::inventory::slotPrimary, false);
EQEmu::ItemInstance *wpn = GetBotItem(EQEmu::inventory::slotPrimary);
TryWeaponProc(wpn, GetTarget(), EQEmu::inventory::slotPrimary);
bool tripleSuccess = false;
if(BotOwner && GetTarget() && CanThisClassDoubleAttack()) {
if(BotOwner && CheckBotDoubleAttack())
Attack(GetTarget(), EQEmu::legacy::SlotPrimary, true);
Attack(GetTarget(), EQEmu::inventory::slotPrimary, true);
if(BotOwner && GetTarget() && GetSpecialAbility(SPECATK_TRIPLE) && CheckBotDoubleAttack(true)) {
tripleSuccess = true;
Attack(GetTarget(), EQEmu::legacy::SlotPrimary, true);
Attack(GetTarget(), EQEmu::inventory::slotPrimary, true);
}
//quad attack, does this belong here??
if(BotOwner && GetTarget() && GetSpecialAbility(SPECATK_QUAD) && CheckBotDoubleAttack(true))
Attack(GetTarget(), EQEmu::legacy::SlotPrimary, true);
Attack(GetTarget(), EQEmu::inventory::slotPrimary, true);
}
//Live AA - Flurry, Rapid Strikes ect (Flurry does not require Triple Attack).
@@ -2473,18 +2473,18 @@ void Bot::AI_Process() {
if (GetTarget() && flurrychance) {
if(zone->random.Int(0, 100) < flurrychance) {
Message_StringID(MT_NPCFlurry, YOU_FLURRY);
Attack(GetTarget(), EQEmu::legacy::SlotPrimary, false);
Attack(GetTarget(), EQEmu::legacy::SlotPrimary, false);
Attack(GetTarget(), EQEmu::inventory::slotPrimary, false);
Attack(GetTarget(), EQEmu::inventory::slotPrimary, false);
}
}
int32 ExtraAttackChanceBonus = (spellbonuses.ExtraAttackChance + itembonuses.ExtraAttackChance + aabonuses.ExtraAttackChance);
if (GetTarget() && ExtraAttackChanceBonus) {
ItemInst *wpn = GetBotItem(EQEmu::legacy::SlotPrimary);
EQEmu::ItemInstance *wpn = GetBotItem(EQEmu::inventory::slotPrimary);
if(wpn) {
if (wpn->GetItem()->IsType2HWeapon()) {
if(zone->random.Int(0, 100) < ExtraAttackChanceBonus)
Attack(GetTarget(), EQEmu::legacy::SlotPrimary, false);
Attack(GetTarget(), EQEmu::inventory::slotPrimary, false);
}
}
}
@@ -2504,8 +2504,8 @@ void Bot::AI_Process() {
//now off hand
if(GetTarget() && attack_dw_timer.Check() && CanThisClassDualWield()) {
const ItemInst* instweapon = GetBotItem(EQEmu::legacy::SlotSecondary);
const EQEmu::ItemBase* weapon = 0;
const EQEmu::ItemInstance* instweapon = GetBotItem(EQEmu::inventory::slotSecondary);
const EQEmu::ItemData* weapon = 0;
//can only dual wield without a weapon if you're a monk
if(instweapon || (botClass == MONK)) {
if(instweapon)
@@ -2526,12 +2526,12 @@ void Bot::AI_Process() {
DualWieldProbability += (DualWieldProbability * float(DWBonus) / 100.0f);
float random = zone->random.Real(0, 1);
if (random < DualWieldProbability){ // Max 78% of DW
Attack(GetTarget(), EQEmu::legacy::SlotSecondary); // Single attack with offhand
ItemInst *wpn = GetBotItem(EQEmu::legacy::SlotSecondary);
TryWeaponProc(wpn, GetTarget(), EQEmu::legacy::SlotSecondary);
Attack(GetTarget(), EQEmu::inventory::slotSecondary); // Single attack with offhand
EQEmu::ItemInstance *wpn = GetBotItem(EQEmu::inventory::slotSecondary);
TryWeaponProc(wpn, GetTarget(), EQEmu::inventory::slotSecondary);
if( CanThisClassDoubleAttack() && CheckBotDoubleAttack()) {
if(GetTarget() && GetTarget()->GetHP() > -10)
Attack(GetTarget(), EQEmu::legacy::SlotSecondary); // Single attack with offhand
Attack(GetTarget(), EQEmu::inventory::slotSecondary); // Single attack with offhand
}
}
}
@@ -2702,12 +2702,12 @@ void Bot::PetAIProcess() {
if(!botPet->BehindMob(botPet->GetTarget(), botPet->GetX(), botPet->GetY()) && botPet->GetTarget()->IsEnraged())
return;
if (botPet->Attack(GetTarget(), EQEmu::legacy::SlotPrimary)) // try the main hand
if (botPet->Attack(GetTarget(), EQEmu::inventory::slotPrimary)) // try the main hand
if (botPet->GetTarget()) {
// We're a pet so we re able to dual attack
int32 RandRoll = zone->random.Int(0, 99);
if (botPet->CanThisClassDoubleAttack() && (RandRoll < (botPet->GetLevel() + NPCDualAttackModifier))) {
if (botPet->Attack(botPet->GetTarget(), EQEmu::legacy::SlotPrimary)) {}
if (botPet->Attack(botPet->GetTarget(), EQEmu::inventory::slotPrimary)) {}
}
}
@@ -2745,11 +2745,11 @@ void Bot::PetAIProcess() {
float DualWieldProbability = ((botPet->GetSkill(EQEmu::skills::SkillDualWield) + botPet->GetLevel()) / 400.0f);
DualWieldProbability -= zone->random.Real(0, 1);
if(DualWieldProbability < 0) {
botPet->Attack(botPet->GetTarget(), EQEmu::legacy::SlotSecondary);
botPet->Attack(botPet->GetTarget(), EQEmu::inventory::slotSecondary);
if (botPet->CanThisClassDoubleAttack()) {
int32 RandRoll = zone->random.Int(0, 99);
if (RandRoll < (botPet->GetLevel() + 20))
botPet->Attack(botPet->GetTarget(), EQEmu::legacy::SlotSecondary);
botPet->Attack(botPet->GetTarget(), EQEmu::inventory::slotSecondary);
}
}
}
@@ -2875,7 +2875,7 @@ void Bot::Spawn(Client* botCharacterOwner) {
for (int i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= EQEmu::legacy::EQUIPMENT_END; ++i) {
itemID = GetBotItemBySlot(i);
if(itemID != 0) {
materialFromSlot = Inventory::CalcMaterialFromSlot(i);
materialFromSlot = EQEmu::InventoryProfile::CalcMaterialFromSlot(i);
if(materialFromSlot != 0xFF)
this->SendWearChange(materialFromSlot);
}
@@ -2897,7 +2897,7 @@ void Bot::RemoveBotItemBySlot(uint32 slotID, std::string *errorMessage)
}
// Retrieves all the inventory records from the database for this bot.
void Bot::GetBotItems(Inventory &inv, std::string* errorMessage)
void Bot::GetBotItems(EQEmu::InventoryProfile &inv, std::string* errorMessage)
{
if(!GetBotID())
return;
@@ -2952,18 +2952,18 @@ void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
ns->spawn.light = m_Light.Type[EQEmu::lightsource::LightActive];
ns->spawn.helm = helmtexture; //(GetShowHelm() ? helmtexture : 0); //0xFF;
ns->spawn.equip_chest2 = texture; //0xFF;
const EQEmu::ItemBase* item = 0;
const ItemInst* inst = 0;
const EQEmu::ItemData* item = 0;
const EQEmu::ItemInstance* inst = 0;
uint32 spawnedbotid = 0;
spawnedbotid = this->GetBotID();
for (int i = 0; i < EQEmu::textures::TexturePrimary; i++) {
for (int i = EQEmu::textures::textureBegin; i < EQEmu::textures::weaponPrimary; i++) {
inst = GetBotItem(i);
if (inst) {
item = inst->GetItem();
if (item != 0) {
ns->spawn.equipment.Slot[i].Material = item->Material;
ns->spawn.equipment.Slot[i].EliteMaterial = item->EliteMaterial;
ns->spawn.equipment.Slot[i].HeroForgeModel = item->HerosForgeModel;
ns->spawn.equipment.Slot[i].EliteModel = item->EliteMaterial;
ns->spawn.equipment.Slot[i].HerosForgeModel = item->HerosForgeModel;
if (armor_tint.Slot[i].Color)
ns->spawn.equipment_tint.Slot[i].Color = armor_tint.Slot[i].Color;
else
@@ -2975,25 +2975,25 @@ void Bot::FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho) {
}
}
inst = GetBotItem(EQEmu::legacy::SlotPrimary);
inst = GetBotItem(EQEmu::inventory::slotPrimary);
if(inst) {
item = inst->GetItem();
if(item) {
if(strlen(item->IDFile) > 2)
ns->spawn.equipment.Primary.Material = atoi(&item->IDFile[2]);
ns->spawn.equipment_tint.Primary.Color = GetEquipmentColor(EQEmu::textures::TexturePrimary);
ns->spawn.equipment_tint.Primary.Color = GetEquipmentColor(EQEmu::textures::weaponPrimary);
}
}
inst = GetBotItem(EQEmu::legacy::SlotSecondary);
inst = GetBotItem(EQEmu::inventory::slotSecondary);
if(inst) {
item = inst->GetItem();
if(item) {
if(strlen(item->IDFile) > 2)
ns->spawn.equipment.Secondary.Material = atoi(&item->IDFile[2]);
ns->spawn.equipment_tint.Secondary.Color = GetEquipmentColor(EQEmu::textures::TextureSecondary);
ns->spawn.equipment_tint.Secondary.Color = GetEquipmentColor(EQEmu::textures::weaponSecondary);
}
}
}
@@ -3224,8 +3224,8 @@ void Bot::SendBotArcheryWearChange(uint8 material_slot, uint32 material, uint32
}
// Returns the item id that is in the bot inventory collection for the specified slot.
ItemInst* Bot::GetBotItem(uint32 slotID) {
ItemInst* item = m_inv.GetItem(slotID);
EQEmu::ItemInstance* Bot::GetBotItem(uint32 slotID) {
EQEmu::ItemInstance* item = m_inv.GetItem(slotID);
if(item)
return item;
@@ -3235,9 +3235,9 @@ ItemInst* Bot::GetBotItem(uint32 slotID) {
// Adds the specified item it bot to the NPC equipment array and to the bot inventory collection.
void Bot::BotAddEquipItem(int slot, uint32 id) {
if(slot > 0 && id > 0) {
uint8 materialFromSlot = Inventory::CalcMaterialFromSlot(slot);
uint8 materialFromSlot = EQEmu::InventoryProfile::CalcMaterialFromSlot(slot);
if (materialFromSlot != EQEmu::textures::TextureInvalid) {
if (materialFromSlot != EQEmu::textures::materialInvalid) {
equipment[slot] = id; // npc has more than just material slots. Valid material should mean valid inventory index
SendWearChange(materialFromSlot);
}
@@ -3251,13 +3251,13 @@ void Bot::BotAddEquipItem(int slot, uint32 id) {
// Erases the specified item from bot the NPC equipment array and from the bot inventory collection.
void Bot::BotRemoveEquipItem(int slot) {
if(slot > 0) {
uint8 materialFromSlot = Inventory::CalcMaterialFromSlot(slot);
uint8 materialFromSlot = EQEmu::InventoryProfile::CalcMaterialFromSlot(slot);
if (materialFromSlot != EQEmu::textures::TextureInvalid) {
if (materialFromSlot != EQEmu::textures::materialInvalid) {
equipment[slot] = 0; // npc has more than just material slots. Valid material should mean valid inventory index
SendWearChange(materialFromSlot);
if (materialFromSlot == EQEmu::textures::TextureChest)
SendWearChange(EQEmu::textures::TextureArms);
if (materialFromSlot == EQEmu::textures::armorChest)
SendWearChange(EQEmu::textures::armorArms);
}
UpdateEquipmentLight();
@@ -3266,7 +3266,7 @@ void Bot::BotRemoveEquipItem(int slot) {
}
}
void Bot::BotTradeSwapItem(Client* client, int16 lootSlot, const ItemInst* inst, const ItemInst* inst_swap, uint32 equipableSlots, std::string* errorMessage, bool swap) {
void Bot::BotTradeSwapItem(Client* client, int16 lootSlot, const EQEmu::ItemInstance* inst, const EQEmu::ItemInstance* inst_swap, uint32 equipableSlots, std::string* errorMessage, bool swap) {
if(!errorMessage->empty())
return;
@@ -3289,7 +3289,7 @@ void Bot::BotTradeSwapItem(Client* client, int16 lootSlot, const ItemInst* inst,
}
}
void Bot::BotTradeAddItem(uint32 id, const ItemInst* inst, int16 charges, uint32 equipableSlots, uint16 lootSlot, std::string* errorMessage, bool addToDb)
void Bot::BotTradeAddItem(uint32 id, const EQEmu::ItemInstance* inst, int16 charges, uint32 equipableSlots, uint16 lootSlot, std::string* errorMessage, bool addToDb)
{
if(addToDb) {
if (!botdb.SaveItemBySlot(this, lootSlot, inst)) {
@@ -3360,7 +3360,7 @@ void Bot::FinishTrade(Client* client, BotTradeType tradeType) {
else if(tradeType == BotTradeClientNoDropNoTrade) {
// Items being traded are found on the Client's cursor slot, slot id 30. This item can be either a single item or it can be a bag.
// If it is a bag, then we have to search for items in slots 331 thru 340
PerformTradeWithClient(EQEmu::legacy::SlotCursor, EQEmu::legacy::SlotCursor, client);
PerformTradeWithClient(EQEmu::inventory::slotCursor, EQEmu::inventory::slotCursor, client);
// TODO: Add logic here to test if the item in SLOT_CURSOR is a container type, if it is then we need to call the following:
// PerformTradeWithClient(331, 340, client);
@@ -3382,23 +3382,23 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
bool UpdateClient = false;
bool already_returned = false;
Inventory& clientInventory = client->GetInv();
const ItemInst* inst = clientInventory[i];
EQEmu::InventoryProfile& clientInventory = client->GetInv();
const EQEmu::ItemInstance* inst = clientInventory[i];
if(inst) {
items[i] = inst->GetItem()->ID;
charges[i] = inst->GetCharges();
}
if (i == EQEmu::legacy::SlotCursor)
if (i == EQEmu::inventory::slotCursor)
UpdateClient = true;
//EQoffline: will give the items to the bots and change the bot stats
if(inst && (GetBotOwner() == client->CastToMob()) && !IsEngaged()) {
std::string TempErrorMessage;
const EQEmu::ItemBase* mWeaponItem = inst->GetItem();
const EQEmu::ItemData* mWeaponItem = inst->GetItem();
bool failedLoreCheck = false;
for (int m = AUG_INDEX_BEGIN; m < EQEmu::legacy::ITEM_COMMON_SIZE; ++m) {
ItemInst *itm = inst->GetAugment(m);
for (int m = EQEmu::inventory::socketBegin; m < EQEmu::inventory::SocketCount; ++m) {
EQEmu::ItemInstance *itm = inst->GetAugment(m);
if(itm)
{
if(CheckLoreConflict(itm->GetItem())) {
@@ -3415,7 +3415,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
if(!failedLoreCheck && mWeaponItem && inst->IsEquipable(GetBaseRace(), GetClass()) && (GetLevel() >= mWeaponItem->ReqLevel)) {
BotCanWear = true;
botCanWear[i] = BotCanWear;
ItemInst* swap_item = nullptr;
EQEmu::ItemInstance* swap_item = nullptr;
const char* equipped[EQEmu::legacy::EQUIPMENT_SIZE + 1] = { "Charm", "Left Ear", "Head", "Face", "Right Ear", "Neck", "Shoulders", "Arms", "Back",
"Left Wrist", "Right Wrist", "Range", "Hands", "Primary Hand", "Secondary Hand",
@@ -3429,17 +3429,17 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
how_many_slots++;
if(!GetBotItem(j)) {
if (j == EQEmu::legacy::SlotPrimary) {
if (j == EQEmu::inventory::slotPrimary) {
if (mWeaponItem->IsType2HWeapon()) {
if (GetBotItem(EQEmu::legacy::SlotSecondary)) {
if (GetBotItem(EQEmu::inventory::slotSecondary)) {
if (mWeaponItem && mWeaponItem->IsType2HWeapon()) {
if (client->CheckLoreConflict(GetBotItem(EQEmu::legacy::SlotSecondary)->GetItem())) {
if (client->CheckLoreConflict(GetBotItem(EQEmu::inventory::slotSecondary)->GetItem())) {
failedLoreCheck = true;
}
}
else {
ItemInst* remove_item = GetBotItem(EQEmu::legacy::SlotSecondary);
BotTradeSwapItem(client, EQEmu::legacy::SlotSecondary, 0, remove_item, remove_item->GetItem()->Slots, &TempErrorMessage, false);
EQEmu::ItemInstance* remove_item = GetBotItem(EQEmu::inventory::slotSecondary);
BotTradeSwapItem(client, EQEmu::inventory::slotSecondary, 0, remove_item, remove_item->GetItem()->Slots, &TempErrorMessage, false);
}
}
}
@@ -3449,7 +3449,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
}
break;
}
else if (j == EQEmu::legacy::SlotSecondary) {
else if (j == EQEmu::inventory::slotSecondary) {
if(inst->IsWeapon()) {
if(CanThisClassDualWield()) {
BotTradeAddItem(mWeaponItem->ID, inst, inst->GetCharges(), mWeaponItem->Slots, j, &TempErrorMessage);
@@ -3465,10 +3465,10 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
success = true;
}
if(success) {
if (GetBotItem(EQEmu::legacy::SlotPrimary)) {
ItemInst* remove_item = GetBotItem(EQEmu::legacy::SlotPrimary);
if (GetBotItem(EQEmu::inventory::slotPrimary)) {
EQEmu::ItemInstance* remove_item = GetBotItem(EQEmu::inventory::slotPrimary);
if (remove_item->GetItem()->IsType2HWeapon()) {
BotTradeSwapItem(client, EQEmu::legacy::SlotPrimary, 0, remove_item, remove_item->GetItem()->Slots, &TempErrorMessage, false);
BotTradeSwapItem(client, EQEmu::inventory::slotPrimary, 0, remove_item, remove_item->GetItem()->Slots, &TempErrorMessage, false);
}
}
break;
@@ -3490,8 +3490,8 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
swap_item = GetBotItem(j);
failedLoreCheck = false;
for (int k = AUG_INDEX_BEGIN; k < EQEmu::legacy::ITEM_COMMON_SIZE; ++k) {
ItemInst *itm = swap_item->GetAugment(k);
for (int k = EQEmu::inventory::socketBegin; k < EQEmu::inventory::SocketCount; ++k) {
EQEmu::ItemInstance *itm = swap_item->GetAugment(k);
if(itm)
{
if(client->CheckLoreConflict(itm->GetItem())) {
@@ -3503,28 +3503,28 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
failedLoreCheck = true;
}
if(!failedLoreCheck) {
if (j == EQEmu::legacy::SlotPrimary) {
if (j == EQEmu::inventory::slotPrimary) {
if (mWeaponItem->IsType2HWeapon()) {
if (GetBotItem(EQEmu::legacy::SlotSecondary)) {
if (client->CheckLoreConflict(GetBotItem(EQEmu::legacy::SlotSecondary)->GetItem())) {
if (GetBotItem(EQEmu::inventory::slotSecondary)) {
if (client->CheckLoreConflict(GetBotItem(EQEmu::inventory::slotSecondary)->GetItem())) {
failedLoreCheck = true;
}
else {
ItemInst* remove_item = GetBotItem(EQEmu::legacy::SlotSecondary);
BotTradeSwapItem(client, EQEmu::legacy::SlotSecondary, 0, remove_item, remove_item->GetItem()->Slots, &TempErrorMessage, false);
EQEmu::ItemInstance* remove_item = GetBotItem(EQEmu::inventory::slotSecondary);
BotTradeSwapItem(client, EQEmu::inventory::slotSecondary, 0, remove_item, remove_item->GetItem()->Slots, &TempErrorMessage, false);
}
}
}
if(!failedLoreCheck) {
BotTradeSwapItem(client, EQEmu::legacy::SlotPrimary, inst, swap_item, mWeaponItem->Slots, &TempErrorMessage);
BotTradeSwapItem(client, EQEmu::inventory::slotPrimary, inst, swap_item, mWeaponItem->Slots, &TempErrorMessage);
success = true;
}
break;
}
else if (j == EQEmu::legacy::SlotSecondary) {
else if (j == EQEmu::inventory::slotSecondary) {
if(inst->IsWeapon()) {
if(CanThisClassDualWield()) {
BotTradeSwapItem(client, EQEmu::legacy::SlotSecondary, inst, swap_item, mWeaponItem->Slots, &TempErrorMessage);
BotTradeSwapItem(client, EQEmu::inventory::slotSecondary, inst, swap_item, mWeaponItem->Slots, &TempErrorMessage);
success = true;
}
else {
@@ -3533,13 +3533,13 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
}
}
else {
BotTradeSwapItem(client, EQEmu::legacy::SlotSecondary, inst, swap_item, mWeaponItem->Slots, &TempErrorMessage);
BotTradeSwapItem(client, EQEmu::inventory::slotSecondary, inst, swap_item, mWeaponItem->Slots, &TempErrorMessage);
success = true;
}
if (success && GetBotItem(EQEmu::legacy::SlotPrimary)) {
ItemInst* remove_item = GetBotItem(EQEmu::legacy::SlotPrimary);
if (success && GetBotItem(EQEmu::inventory::slotPrimary)) {
EQEmu::ItemInstance* remove_item = GetBotItem(EQEmu::inventory::slotPrimary);
if (remove_item->GetItem()->IsType2HWeapon()) {
BotTradeSwapItem(client, EQEmu::legacy::SlotPrimary, 0, remove_item, remove_item->GetItem()->Slots, &TempErrorMessage, false);
BotTradeSwapItem(client, EQEmu::inventory::slotPrimary, 0, remove_item, remove_item->GetItem()->Slots, &TempErrorMessage, false);
}
}
break;
@@ -3574,7 +3574,7 @@ void Bot::PerformTradeWithClient(int16 beginSlotID, int16 endSlotID, Client* cli
}
}
const EQEmu::ItemBase* item2 = 0;
const EQEmu::ItemData* item2 = 0;
for(int y = beginSlotID; y <= endSlotID; ++y) {
item2 = database.GetItem(items[y]);
if(item2) {
@@ -3738,14 +3738,14 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
}
FaceTarget(GetTarget());
ItemInst* weapon = nullptr;
if (Hand == EQEmu::legacy::SlotPrimary) {
weapon = GetBotItem(EQEmu::legacy::SlotPrimary);
EQEmu::ItemInstance* weapon = nullptr;
if (Hand == EQEmu::inventory::slotPrimary) {
weapon = GetBotItem(EQEmu::inventory::slotPrimary);
OffHandAtk(false);
}
if (Hand == EQEmu::legacy::SlotSecondary) {
weapon = GetBotItem(EQEmu::legacy::SlotSecondary);
if (Hand == EQEmu::inventory::slotSecondary) {
weapon = GetBotItem(EQEmu::inventory::slotSecondary);
OffHandAtk(true);
}
@@ -3810,19 +3810,19 @@ bool Bot::Attack(Mob* other, int Hand, bool FromRiposte, bool IsStrikethrough, b
// This is not recommended for normal usage, as the damage bonus represents a non-trivial component of the DPS output
// of weapons wielded by higher-level melee characters (especially for two-handed weapons).
int ucDamageBonus = 0;
if (Hand == EQEmu::legacy::SlotPrimary && GetLevel() >= 28 && IsWarriorClass()) {
if (Hand == EQEmu::inventory::slotPrimary && GetLevel() >= 28 && IsWarriorClass()) {
// Damage bonuses apply only to hits from the main hand (Hand == MainPrimary) by characters level 28 and above
// who belong to a melee class. If we're here, then all of these conditions apply.
ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const EQEmu::ItemBase*) nullptr);
ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const EQEmu::ItemData*) nullptr);
min_hit += (int) ucDamageBonus;
max_hit += (int) ucDamageBonus;
hate += ucDamageBonus;
}
#endif
//Live AA - Sinister Strikes *Adds weapon damage bonus to offhand weapon.
if (Hand == EQEmu::legacy::SlotSecondary) {
if (Hand == EQEmu::inventory::slotSecondary) {
if (aabonuses.SecondaryDmgInc || itembonuses.SecondaryDmgInc || spellbonuses.SecondaryDmgInc){
ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const EQEmu::ItemBase*) nullptr);
ucDamageBonus = GetWeaponDamageBonus(weapon ? weapon->GetItem() : (const EQEmu::ItemData*) nullptr);
min_hit += (int) ucDamageBonus;
max_hit += (int) ucDamageBonus;
hate += ucDamageBonus;
@@ -4280,9 +4280,9 @@ int32 Bot::GetBotFocusEffect(BotfocusType bottype, uint16 spell_id) {
//Check if item focus effect exists for the client.
if (itembonuses.FocusEffects[bottype]) {
const EQEmu::ItemBase* TempItem = 0;
const EQEmu::ItemBase* UsedItem = 0;
const ItemInst* TempInst = 0;
const EQEmu::ItemData* TempItem = 0;
const EQEmu::ItemData* UsedItem = 0;
const EQEmu::ItemInstance* TempInst = 0;
uint16 UsedFocusID = 0;
int32 Total = 0;
int32 focus_max = 0;
@@ -4290,7 +4290,7 @@ int32 Bot::GetBotFocusEffect(BotfocusType bottype, uint16 spell_id) {
//item focus
for (int x = EQEmu::legacy::EQUIPMENT_BEGIN; x <= EQEmu::legacy::EQUIPMENT_END; x++) {
TempItem = nullptr;
ItemInst* ins = GetBotItem(x);
EQEmu::ItemInstance* ins = GetBotItem(x);
if (!ins)
continue;
@@ -4313,11 +4313,11 @@ int32 Bot::GetBotFocusEffect(BotfocusType bottype, uint16 spell_id) {
}
}
for (int y = AUG_INDEX_BEGIN; y < EQEmu::legacy::ITEM_COMMON_SIZE; ++y) {
ItemInst *aug = nullptr;
for (int y = EQEmu::inventory::socketBegin; y < EQEmu::inventory::SocketCount; ++y) {
EQEmu::ItemInstance *aug = nullptr;
aug = ins->GetAugment(y);
if(aug) {
const EQEmu::ItemBase* TempItemAug = aug->GetItem();
const EQEmu::ItemData* TempItemAug = aug->GetItem();
if (TempItemAug && TempItemAug->Focus.Effect > 0 && TempItemAug->Focus.Effect != SPELL_UNKNOWN) {
if(rand_effectiveness) {
focus_max = CalcBotFocusEffect(bottype, TempItemAug->Focus.Effect, spell_id, true);
@@ -4749,13 +4749,13 @@ float Bot::GetProcChances(float ProcBonus, uint16 hand) {
float ProcChance = 0.0f;
uint32 weapon_speed = 0;
switch (hand) {
case EQEmu::legacy::SlotPrimary:
case EQEmu::inventory::slotPrimary:
weapon_speed = attack_timer.GetDuration();
break;
case EQEmu::legacy::SlotSecondary:
case EQEmu::inventory::slotSecondary:
weapon_speed = attack_dw_timer.GetDuration();
break;
case EQEmu::legacy::SlotRange:
case EQEmu::inventory::slotRange:
weapon_speed = ranged_timer.GetDuration();
break;
}
@@ -4781,7 +4781,7 @@ int Bot::GetHandToHandDamage(void) {
// everyone uses this in the revamp!
int skill = GetSkill(EQEmu::skills::SkillHandtoHand);
int epic = 0;
if (CastToNPC()->GetEquipment(EQEmu::textures::TextureHands) == 10652 && GetLevel() > 46)
if (CastToNPC()->GetEquipment(EQEmu::textures::armorHands) == 10652 && GetLevel() > 46)
epic = 280;
if (epic > skill)
skill = epic;
@@ -4803,7 +4803,7 @@ int Bot::GetHandToHandDamage(void) {
9, 9, 9, 9, 9, 10, 10, 10, 10, 10, // 31-40
10, 11, 11, 11, 11, 11, 11, 12, 12}; // 41-49
if (GetClass() == MONK) {
if (CastToNPC()->GetEquipment(EQEmu::textures::TextureHands) == 10652 && GetLevel() > 50)
if (CastToNPC()->GetEquipment(EQEmu::textures::armorHands) == 10652 && GetLevel() > 50)
return 9;
if (level > 62)
return 15;
@@ -4842,11 +4842,11 @@ void Bot::DoRiposte(Mob* defender) {
if (!defender)
return;
defender->Attack(this, EQEmu::legacy::SlotPrimary, true);
defender->Attack(this, EQEmu::inventory::slotPrimary, true);
int32 DoubleRipChance = (defender->GetAABonuses().GiveDoubleRiposte[0] + defender->GetSpellBonuses().GiveDoubleRiposte[0] + defender->GetItemBonuses().GiveDoubleRiposte[0]);
if(DoubleRipChance && (DoubleRipChance >= zone->random.Int(0, 100))) {
Log.Out(Logs::Detail, Logs::Combat, "Preforming a double riposte (%d percent chance)", DoubleRipChance);
defender->Attack(this, EQEmu::legacy::SlotPrimary, true);
defender->Attack(this, EQEmu::inventory::slotPrimary, true);
}
DoubleRipChance = defender->GetAABonuses().GiveDoubleRiposte[1];
@@ -4864,8 +4864,8 @@ void Bot::DoSpecialAttackDamage(Mob *who, EQEmu::skills::SkillType skill, int32
hate = hate_override;
if (skill == EQEmu::skills::SkillBash) {
const ItemInst* inst = GetBotItem(EQEmu::legacy::SlotSecondary);
const EQEmu::ItemBase* botweapon = 0;
const EQEmu::ItemInstance* inst = GetBotItem(EQEmu::inventory::slotSecondary);
const EQEmu::ItemData* botweapon = 0;
if(inst)
botweapon = inst->GetItem();
@@ -4878,14 +4878,14 @@ void Bot::DoSpecialAttackDamage(Mob *who, EQEmu::skills::SkillType skill, int32
}
min_damage += (min_damage * GetMeleeMinDamageMod_SE(skill) / 100);
int hand = EQEmu::legacy::SlotPrimary;
int hand = EQEmu::inventory::slotPrimary;
if (skill == EQEmu::skills::SkillThrowing || skill == EQEmu::skills::SkillArchery)
hand = EQEmu::legacy::SlotRange;
hand = EQEmu::inventory::slotRange;
if (who->AvoidDamage(this, max_damage, hand)) {
if (max_damage == -3)
DoRiposte(who);
} else {
if (HitChance || who->CheckHitChance(this, skill, EQEmu::legacy::SlotPrimary)) {
if (HitChance || who->CheckHitChance(this, skill, EQEmu::inventory::slotPrimary)) {
who->MeleeMitigation(this, max_damage, min_damage);
ApplyMeleeDamageBonus(skill, max_damage);
max_damage += who->GetFcDamageAmtIncoming(this, 0, true, skill);
@@ -4929,8 +4929,8 @@ void Bot::TryBackstab(Mob *other, int ReuseTime) {
bool bIsBehind = false;
bool bCanFrontalBS = false;
const ItemInst* inst = GetBotItem(EQEmu::legacy::SlotPrimary);
const EQEmu::ItemBase* botpiercer = nullptr;
const EQEmu::ItemInstance* inst = GetBotItem(EQEmu::inventory::slotPrimary);
const EQEmu::ItemData* botpiercer = nullptr;
if(inst)
botpiercer = inst->GetItem();
@@ -4979,7 +4979,7 @@ void Bot::TryBackstab(Mob *other, int ReuseTime) {
}
}
else
Attack(other, EQEmu::legacy::SlotPrimary);
Attack(other, EQEmu::inventory::slotPrimary);
}
void Bot::RogueBackstab(Mob* other, bool min_damage, int ReuseTime) {
@@ -4989,12 +4989,12 @@ void Bot::RogueBackstab(Mob* other, bool min_damage, int ReuseTime) {
int32 hate = 0;
int32 primaryweapondamage = 0;
int32 backstab_dmg = 0;
ItemInst* botweaponInst = GetBotItem(EQEmu::legacy::SlotPrimary);
EQEmu::ItemInstance* botweaponInst = GetBotItem(EQEmu::inventory::slotPrimary);
if(botweaponInst) {
primaryweapondamage = GetWeaponDamage(other, botweaponInst);
backstab_dmg = botweaponInst->GetItem()->BackstabDmg;
for (int i = AUG_INDEX_BEGIN; i < EQEmu::legacy::ITEM_COMMON_SIZE; ++i) {
ItemInst *aug = botweaponInst->GetAugment(i);
for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; ++i) {
EQEmu::ItemInstance *aug = botweaponInst->GetAugment(i);
if(aug)
backstab_dmg += aug->GetItem()->BackstabDmg;
}
@@ -5037,7 +5037,7 @@ void Bot::RogueBackstab(Mob* other, bool min_damage, int ReuseTime) {
}
void Bot::RogueAssassinate(Mob* other) {
ItemInst* botweaponInst = GetBotItem(EQEmu::legacy::SlotPrimary);
EQEmu::ItemInstance* botweaponInst = GetBotItem(EQEmu::inventory::slotPrimary);
if(botweaponInst) {
if(GetWeaponDamage(other, botweaponInst))
other->Damage(this, 32000, SPELL_UNKNOWN, EQEmu::skills::SkillBackstab);
@@ -5103,7 +5103,7 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) {
case WARRIOR:
if(level >= RuleI(Combat, NPCBashKickLevel)){
bool canBash = false;
if ((GetRace() == OGRE || GetRace() == TROLL || GetRace() == BARBARIAN) || (m_inv.GetItem(EQEmu::legacy::SlotSecondary) && m_inv.GetItem(EQEmu::legacy::SlotSecondary)->GetItem()->ItemType == EQEmu::item::ItemTypeShield) || (m_inv.GetItem(EQEmu::legacy::SlotPrimary) && m_inv.GetItem(EQEmu::legacy::SlotPrimary)->GetItem()->IsType2HWeapon() && GetAA(aa2HandBash) >= 1))
if ((GetRace() == OGRE || GetRace() == TROLL || GetRace() == BARBARIAN) || (m_inv.GetItem(EQEmu::inventory::slotSecondary) && m_inv.GetItem(EQEmu::inventory::slotSecondary)->GetItem()->ItemType == EQEmu::item::ItemTypeShield) || (m_inv.GetItem(EQEmu::inventory::slotPrimary) && m_inv.GetItem(EQEmu::inventory::slotPrimary)->GetItem()->IsType2HWeapon() && GetAA(aa2HandBash) >= 1))
canBash = true;
if(!canBash || zone->random.Int(0, 100) > 25)
@@ -5122,7 +5122,7 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) {
case SHADOWKNIGHT:
case PALADIN:
if(level >= RuleI(Combat, NPCBashKickLevel)){
if ((GetRace() == OGRE || GetRace() == TROLL || GetRace() == BARBARIAN) || (m_inv.GetItem(EQEmu::legacy::SlotSecondary) && m_inv.GetItem(EQEmu::legacy::SlotSecondary)->GetItem()->ItemType == EQEmu::item::ItemTypeShield) || (m_inv.GetItem(EQEmu::legacy::SlotPrimary) && m_inv.GetItem(EQEmu::legacy::SlotPrimary)->GetItem()->IsType2HWeapon() && GetAA(aa2HandBash) >= 1))
if ((GetRace() == OGRE || GetRace() == TROLL || GetRace() == BARBARIAN) || (m_inv.GetItem(EQEmu::inventory::slotSecondary) && m_inv.GetItem(EQEmu::inventory::slotSecondary)->GetItem()->ItemType == EQEmu::item::ItemTypeShield) || (m_inv.GetItem(EQEmu::inventory::slotPrimary) && m_inv.GetItem(EQEmu::inventory::slotPrimary)->GetItem()->IsType2HWeapon() && GetAA(aa2HandBash) >= 1))
skill_to_use = EQEmu::skills::SkillBash;
}
break;
@@ -5151,7 +5151,7 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) {
if (skill_to_use == EQEmu::skills::SkillBash) {
if (target != this) {
DoAnim(animTailRake);
if (GetWeaponDamage(target, GetBotItem(EQEmu::legacy::SlotSecondary)) <= 0 && GetWeaponDamage(target, GetBotItem(EQEmu::legacy::SlotShoulders)) <= 0)
if (GetWeaponDamage(target, GetBotItem(EQEmu::inventory::slotSecondary)) <= 0 && GetWeaponDamage(target, GetBotItem(EQEmu::inventory::slotShoulders)) <= 0)
dmg = -5;
else {
if (!target->CheckHitChance(this, EQEmu::skills::SkillBash, 0))
@@ -5201,7 +5201,7 @@ void Bot::DoClassAttacks(Mob *target, bool IsRiposte) {
if (skill_to_use == EQEmu::skills::SkillKick) {
if(target != this) {
DoAnim(animKick);
if (GetWeaponDamage(target, GetBotItem(EQEmu::legacy::SlotFeet)) <= 0)
if (GetWeaponDamage(target, GetBotItem(EQEmu::inventory::slotFeet)) <= 0)
dmg = -5;
else {
if (!target->CheckHitChance(this, EQEmu::skills::SkillKick, 0))
@@ -5366,8 +5366,8 @@ bool Bot::IsBotAttackAllowed(Mob* attacker, Mob* target, bool& hasRuleDefined) {
void Bot::EquipBot(std::string* errorMessage) {
GetBotItems(m_inv, errorMessage);
const ItemInst* inst = 0;
const EQEmu::ItemBase* item = 0;
const EQEmu::ItemInstance* inst = 0;
const EQEmu::ItemData* item = 0;
for (int i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= EQEmu::legacy::EQUIPMENT_END; ++i) {
inst = GetBotItem(i);
if(inst) {
@@ -5494,23 +5494,23 @@ void Bot::SetAttackTimer() {
float haste_mod = (GetHaste() * 0.01f);
attack_timer.SetAtTrigger(4000, true);
Timer* TimerToUse = nullptr;
const EQEmu::ItemBase* PrimaryWeapon = nullptr;
for (int i = EQEmu::legacy::SlotRange; i <= EQEmu::legacy::SlotSecondary; i++) {
if (i == EQEmu::legacy::SlotPrimary)
const EQEmu::ItemData* PrimaryWeapon = nullptr;
for (int i = EQEmu::inventory::slotRange; i <= EQEmu::inventory::slotSecondary; i++) {
if (i == EQEmu::inventory::slotPrimary)
TimerToUse = &attack_timer;
else if (i == EQEmu::legacy::SlotRange)
else if (i == EQEmu::inventory::slotRange)
TimerToUse = &ranged_timer;
else if (i == EQEmu::legacy::SlotSecondary)
else if (i == EQEmu::inventory::slotSecondary)
TimerToUse = &attack_dw_timer;
else
continue;
const EQEmu::ItemBase* ItemToUse = nullptr;
ItemInst* ci = GetBotItem(i);
const EQEmu::ItemData* ItemToUse = nullptr;
EQEmu::ItemInstance* ci = GetBotItem(i);
if (ci)
ItemToUse = ci->GetItem();
if (i == EQEmu::legacy::SlotSecondary) {
if (i == EQEmu::inventory::slotSecondary) {
if (PrimaryWeapon != nullptr) {
if (PrimaryWeapon->IsClassCommon() && PrimaryWeapon->IsType2HWeapon()) {
attack_dw_timer.Disable();
@@ -5541,7 +5541,7 @@ void Bot::SetAttackTimer() {
speed = (RuleB(Spells, Jun182014HundredHandsRevamp) ? static_cast<int>(((delay / haste_mod) + ((hhe / 1000.0f) * (delay / haste_mod))) * 100) : static_cast<int>(((delay / haste_mod) + ((hhe / 100.0f) * delay)) * 100));
TimerToUse->SetAtTrigger(std::max(RuleI(Combat, MinHastedDelay), speed), true);
if (i == EQEmu::legacy::SlotPrimary)
if (i == EQEmu::inventory::slotPrimary)
PrimaryWeapon = ItemToUse;
}
}
@@ -7180,13 +7180,13 @@ void Bot::ProcessBotInspectionRequest(Bot* inspectedBot, Client* client) {
insr->TargetID = inspectedBot->GetNPCTypeID();
insr->playerid = inspectedBot->GetID();
const EQEmu::ItemBase* item = 0;
const ItemInst* inst = 0;
const EQEmu::ItemData* item = 0;
const EQEmu::ItemInstance* inst = 0;
// Modded to display power source items (will only show up on SoF+ client inspect windows though.)
// I don't think bots are currently coded to use them..but, you'll have to use '#bot inventory list'
// to see them on a Titanium client when/if they are activated.
for (int16 L = EQEmu::legacy::EQUIPMENT_BEGIN; L <= EQEmu::legacy::SlotWaist; L++) {
for (int16 L = EQEmu::legacy::EQUIPMENT_BEGIN; L <= EQEmu::inventory::slotWaist; L++) {
inst = inspectedBot->GetBotItem(L);
if(inst) {
@@ -7200,7 +7200,7 @@ void Bot::ProcessBotInspectionRequest(Bot* inspectedBot, Client* client) {
}
}
inst = inspectedBot->GetBotItem(EQEmu::legacy::SlotPowerSource);
inst = inspectedBot->GetBotItem(EQEmu::inventory::slotPowerSource);
if(inst) {
item = inst->GetItem();
@@ -7212,7 +7212,7 @@ void Bot::ProcessBotInspectionRequest(Bot* inspectedBot, Client* client) {
insr->itemicons[SoF::invslot::PossessionsPowerSource] = 0xFFFFFFFF;
}
inst = inspectedBot->GetBotItem(EQEmu::legacy::SlotAmmo);
inst = inspectedBot->GetBotItem(EQEmu::inventory::slotAmmo);
if(inst) {
item = inst->GetItem();
@@ -7232,10 +7232,10 @@ void Bot::ProcessBotInspectionRequest(Bot* inspectedBot, Client* client) {
void Bot::CalcItemBonuses(StatBonuses* newbon)
{
const EQEmu::ItemBase* itemtmp = 0;
const EQEmu::ItemData* itemtmp = 0;
for (int i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= (EQEmu::legacy::EQUIPMENT_END + 1); ++i) {
const ItemInst* item = GetBotItem((i == 22 ? 9999 : i));
const EQEmu::ItemInstance* item = GetBotItem((i == 22 ? 9999 : i));
if(item) {
AddItemBonuses(item, newbon);
}
@@ -7252,7 +7252,7 @@ void Bot::CalcItemBonuses(StatBonuses* newbon)
newbon->EnduranceRegen = CalcEnduranceRegenCap();
}
void Bot::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug, bool isTribute, int rec_override) {
void Bot::AddItemBonuses(const EQEmu::ItemInstance *inst, StatBonuses* newbon, bool isAug, bool isTribute, int rec_override) {
if (!inst || !inst->IsClassCommon())
{
return;
@@ -7263,7 +7263,7 @@ void Bot::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug,
return;
}
const EQEmu::ItemBase *item = inst->GetItem();
const EQEmu::ItemData *item = inst->GetItem();
if(!isTribute && !inst->IsEquipable(GetBaseRace(),GetClass()))
{
@@ -7547,7 +7547,7 @@ void Bot::AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug,
if (!isAug)
{
for (int i = 0; i < EQEmu::legacy::ITEM_COMMON_SIZE; i++)
for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++)
AddItemBonuses(inst->GetAugment(i),newbon,true, false, rec_level);
}
@@ -7630,7 +7630,7 @@ void Bot::CalcBotStats(bool showtext) {
}
}
bool Bot::CheckLoreConflict(const EQEmu::ItemBase* item) {
bool Bot::CheckLoreConflict(const EQEmu::ItemData* item) {
if (!item || !(item->LoreFlag))
return false;
@@ -8036,12 +8036,12 @@ uint8 Bot::GetNumberNeedingHealedInGroup(uint8 hpr, bool includePets) {
int Bot::GetRawACNoShield(int &shield_ac) {
int ac = itembonuses.AC + spellbonuses.AC;
shield_ac = 0;
ItemInst* inst = GetBotItem(EQEmu::legacy::SlotSecondary);
EQEmu::ItemInstance* inst = GetBotItem(EQEmu::inventory::slotSecondary);
if(inst) {
if (inst->GetItem()->ItemType == EQEmu::item::ItemTypeShield) {
ac -= inst->GetItem()->AC;
shield_ac = inst->GetItem()->AC;
for (uint8 i = AUG_INDEX_BEGIN; i < EQEmu::legacy::ITEM_COMMON_SIZE; i++) {
for (uint8 i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) {
if(inst->GetAugment(i)) {
ac -= inst->GetAugment(i)->GetItem()->AC;
shield_ac += inst->GetAugment(i)->GetItem()->AC;
@@ -8053,8 +8053,8 @@ int Bot::GetRawACNoShield(int &shield_ac) {
}
uint32 Bot::CalcCurrentWeight() {
const EQEmu::ItemBase* TempItem = 0;
ItemInst* inst;
const EQEmu::ItemData* TempItem = 0;
EQEmu::ItemInstance* inst;
uint32 Total = 0;
for (int i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= EQEmu::legacy::EQUIPMENT_END; ++i) {
inst = GetBotItem(i);
@@ -8433,9 +8433,9 @@ bool Bot::DyeArmor(int16 slot_id, uint32 rgb, bool all_flag, bool save_flag)
if (slot_id != INVALID_INDEX)
return false;
for (uint8 i = 0; i < EQEmu::textures::TexturePrimary; ++i) {
uint8 inv_slot = Inventory::CalcSlotFromMaterial(i);
ItemInst* inst = m_inv.GetItem(inv_slot);
for (uint8 i = EQEmu::textures::textureBegin; i < EQEmu::textures::weaponPrimary; ++i) {
uint8 inv_slot = EQEmu::InventoryProfile::CalcSlotFromMaterial(i);
EQEmu::ItemInstance* inst = m_inv.GetItem(inv_slot);
if (!inst)
continue;
@@ -8444,11 +8444,11 @@ bool Bot::DyeArmor(int16 slot_id, uint32 rgb, bool all_flag, bool save_flag)
}
}
else {
uint8 mat_slot = Inventory::CalcMaterialFromSlot(slot_id);
if (mat_slot == EQEmu::textures::TextureInvalid || mat_slot >= EQEmu::textures::TexturePrimary)
uint8 mat_slot = EQEmu::InventoryProfile::CalcMaterialFromSlot(slot_id);
if (mat_slot == EQEmu::textures::materialInvalid || mat_slot >= EQEmu::textures::weaponPrimary)
return false;
ItemInst* inst = m_inv.GetItem(slot_id);
EQEmu::ItemInstance* inst = m_inv.GetItem(slot_id);
if (!inst)
return false;
+9 -9
View File
@@ -77,7 +77,7 @@ static const std::string bot_stance_name[BOT_STANCE_COUNT] = {
static const char* GetBotStanceName(int stance_id) { return bot_stance_name[VALIDBOTSTANCE(stance_id)].c_str(); }
#define VALIDBOTEQUIPSLOT(x) ((x >= EQEmu::legacy::EQUIPMENT_BEGIN && x <= EQEmu::legacy::EQUIPMENT_END) ? (x) : ((x == EQEmu::legacy::SlotPowerSource) ? (22) : (23)))
#define VALIDBOTEQUIPSLOT(x) ((x >= EQEmu::legacy::EQUIPMENT_BEGIN && x <= EQEmu::legacy::EQUIPMENT_END) ? (x) : ((x == EQEmu::inventory::slotPowerSource) ? (22) : (23)))
static std::string bot_equip_slot_name[EQEmu::legacy::EQUIPMENT_SIZE + 2] =
{
@@ -207,7 +207,7 @@ public:
//abstract virtual function implementations requird by base abstract class
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill);
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, int special = 0);
virtual bool Attack(Mob* other, int Hand = EQEmu::legacy::SlotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
virtual bool Attack(Mob* other, int Hand = EQEmu::inventory::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
ExtraAttackOptions *opts = nullptr, int special = 0);
virtual bool HasRaid() { return (GetRaid() ? true : false); }
virtual bool HasGroup() { return (GetGroup() ? true : false); }
@@ -260,7 +260,7 @@ public:
virtual int32 CheckAggroAmount(uint16 spellid);
virtual void CalcBonuses();
void CalcItemBonuses(StatBonuses* newbon);
void AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug = false, bool isTribute = false, int rec_override = 0);
void AddItemBonuses(const EQEmu::ItemInstance *inst, StatBonuses* newbon, bool isAug = false, bool isTribute = false, int rec_override = 0);
int CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat);
virtual void MakePet(uint16 spell_id, const char* pettype, const char *petname = nullptr);
virtual FACTION_VALUE GetReverseFactionCon(Mob* iOther);
@@ -382,10 +382,10 @@ public:
virtual bool DoCastSpell(uint16 spell_id, uint16 target_id, EQEmu::CastingSlot slot = EQEmu::CastingSlot::Item, int32 casttime = -1, int32 mana_cost = -1, uint32* oSpellWillFinish = 0, uint32 item_slot = 0xFFFFFFFF, uint32 aa_id = 0);
// Bot Equipment & Inventory Class Methods
void BotTradeSwapItem(Client* client, int16 lootSlot, const ItemInst* inst, const ItemInst* inst_swap, uint32 equipableSlots, std::string* errorMessage, bool swap = true);
void BotTradeAddItem(uint32 id, const ItemInst* inst, int16 charges, uint32 equipableSlots, uint16 lootSlot, std::string* errorMessage, bool addToDb = true);
void BotTradeSwapItem(Client* client, int16 lootSlot, const EQEmu::ItemInstance* inst, const EQEmu::ItemInstance* inst_swap, uint32 equipableSlots, std::string* errorMessage, bool swap = true);
void BotTradeAddItem(uint32 id, const EQEmu::ItemInstance* inst, int16 charges, uint32 equipableSlots, uint16 lootSlot, std::string* errorMessage, bool addToDb = true);
void EquipBot(std::string* errorMessage);
bool CheckLoreConflict(const EQEmu::ItemBase* item);
bool CheckLoreConflict(const EQEmu::ItemData* item);
virtual void UpdateEquipmentLight() { m_Light.Type[EQEmu::lightsource::LightEquipment] = m_inv.FindBrightestLightType(); m_Light.Level[EQEmu::lightsource::LightEquipment] = EQEmu::lightsource::TypeToLevel(m_Light.Type[EQEmu::lightsource::LightEquipment]); }
// Static Class Methods
@@ -457,7 +457,7 @@ public:
uint32 GetBotSpellID() { return npc_spells_id; }
Mob* GetBotOwner() { return this->_botOwner; }
uint32 GetBotArcheryRange();
ItemInst* GetBotItem(uint32 slotID);
EQEmu::ItemInstance* GetBotItem(uint32 slotID);
virtual bool GetSpawnStatus() { return _spawnStatus; }
uint8 GetPetChooserID() { return _petChooserID; }
bool IsPetChooser() { return _petChooser; }
@@ -647,7 +647,7 @@ private:
bool _petChooser;
uint8 _petChooserID;
bool berserk;
Inventory m_inv;
EQEmu::InventoryProfile m_inv;
double _lastTotalPlayTime;
time_t _startTotalPlayTime;
Mob* _previousTarget;
@@ -711,7 +711,7 @@ private:
void SetBotID(uint32 botID);
// Private "Inventory" Methods
void GetBotItems(Inventory &inv, std::string* errorMessage);
void GetBotItems(EQEmu::InventoryProfile &inv, std::string* errorMessage);
void BotAddEquipItem(int slot, uint32 id);
uint32 GetBotItemBySlot(uint32 slotID);
+53 -48
View File
@@ -2402,7 +2402,7 @@ namespace ActionableBots
mod_skill_value = base_skill_value;
for (int16 index = EQEmu::legacy::EQUIPMENT_BEGIN; index <= EQEmu::legacy::EQUIPMENT_END; ++index) {
const ItemInst* indexed_item = bot_iter->GetBotItem(index);
const EQEmu::ItemInstance* indexed_item = bot_iter->GetBotItem(index);
if (indexed_item && indexed_item->GetItem()->SkillModType == skill_type)
mod_skill_value += (base_skill_value * (((float)indexed_item->GetItem()->SkillModValue) / 100.0f));
}
@@ -3397,15 +3397,18 @@ void bot_command_movement_speed(Client *c, const Seperator *sep)
if (helper_spell_list_fail(c, local_list, BCEnum::SpT_MovementSpeed) || helper_command_alias_fail(c, "bot_command_movement_speed", sep->arg[0], "movementspeed"))
return;
if (helper_is_help_or_usage(sep->arg[1])) {
c->Message(m_usage, "usage: (<friendly_target>) %s ([group])", sep->arg[0]);
c->Message(m_usage, "usage: (<friendly_target>) %s ([group | sow])", sep->arg[0]);
helper_send_usage_required_bots(c, BCEnum::SpT_MovementSpeed);
return;
}
bool group = false;
std::string group_arg = sep->arg[1];
if (!group_arg.compare("group"))
bool sow = false;
std::string arg1 = sep->arg[1];
if (!arg1.compare("group"))
group = true;
else if (!arg1.compare("sow"))
sow = true;
ActionableTarget::Types actionable_targets;
Bot* my_bot = nullptr;
@@ -3417,7 +3420,9 @@ void bot_command_movement_speed(Client *c, const Seperator *sep)
auto local_entry = list_iter->SafeCastToMovementSpeed();
if (helper_spell_check_fail(local_entry))
continue;
if (local_entry->group != group)
if (!sow && (local_entry->group != group))
continue;
if (sow && (local_entry->spell_id != 278)) // '278' = single-target "Spirit of Wolf"
continue;
auto target_mob = actionable_targets.Select(c, local_entry->target_type, FRIENDLY);
@@ -4358,7 +4363,7 @@ void bot_subcommand_bot_dye_armor(Client *c, const Seperator *sep)
// TODO: Trouble-shoot model update issue
const std::string msg_matslot = StringFormat("mat_slot: %c(All), %i(Head), %i(Chest), %i(Arms), %i(Wrists), %i(Hands), %i(Legs), %i(Feet)",
'*', EQEmu::textures::TextureHead, EQEmu::textures::TextureChest, EQEmu::textures::TextureArms, EQEmu::textures::TextureWrist, EQEmu::textures::TextureHands, EQEmu::textures::TextureLegs, EQEmu::textures::TextureFeet);
'*', EQEmu::textures::armorHead, EQEmu::textures::armorChest, EQEmu::textures::armorArms, EQEmu::textures::armorWrist, EQEmu::textures::armorHands, EQEmu::textures::armorLegs, EQEmu::textures::armorFeet);
if (helper_command_alias_fail(c, "bot_subcommand_bot_dye_armor", sep->arg[0], "botdyearmor"))
return;
@@ -4369,15 +4374,15 @@ void bot_subcommand_bot_dye_armor(Client *c, const Seperator *sep)
}
const int ab_mask = ActionableBots::ABM_NoFilter;
uint8 material_slot = EQEmu::textures::TextureInvalid;
uint8 material_slot = EQEmu::textures::materialInvalid;
int16 slot_id = INVALID_INDEX;
bool dye_all = (sep->arg[1][0] == '*');
if (!dye_all) {
material_slot = atoi(sep->arg[1]);
slot_id = Inventory::CalcSlotFromMaterial(material_slot);
slot_id = EQEmu::InventoryProfile::CalcSlotFromMaterial(material_slot);
if (!sep->IsNumber(1) || slot_id == INVALID_INDEX || material_slot > EQEmu::textures::TextureFeet) {
if (!sep->IsNumber(1) || slot_id == INVALID_INDEX || material_slot > EQEmu::textures::LastTintableTexture) {
c->Message(m_fail, "Valid [mat_slot]s for this command are:");
c->Message(m_fail, msg_matslot.c_str());
return;
@@ -7062,8 +7067,8 @@ void bot_subcommand_inventory_list(Client *c, const Seperator *sep)
return;
}
const ItemInst* inst = nullptr;
const EQEmu::ItemBase* item = nullptr;
const EQEmu::ItemInstance* inst = nullptr;
const EQEmu::ItemData* item = nullptr;
bool is2Hweapon = false;
std::string item_link;
@@ -7072,23 +7077,23 @@ void bot_subcommand_inventory_list(Client *c, const Seperator *sep)
uint32 inventory_count = 0;
for (int i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= (EQEmu::legacy::EQUIPMENT_END + 1); ++i) {
if ((i == EQEmu::legacy::SlotSecondary) && is2Hweapon)
if ((i == EQEmu::inventory::slotSecondary) && is2Hweapon)
continue;
inst = my_bot->CastToBot()->GetBotItem(i == 22 ? EQEmu::legacy::SlotPowerSource : i);
inst = my_bot->CastToBot()->GetBotItem(i == 22 ? EQEmu::inventory::slotPowerSource : i);
if (!inst || !inst->GetItem()) {
c->Message(m_message, "I need something for my %s (slot %i)", GetBotEquipSlotName(i), (i == 22 ? EQEmu::legacy::SlotPowerSource : i));
c->Message(m_message, "I need something for my %s (slot %i)", GetBotEquipSlotName(i), (i == 22 ? EQEmu::inventory::slotPowerSource : i));
continue;
}
item = inst->GetItem();
if ((i == EQEmu::legacy::SlotPrimary) && item->IsType2HWeapon()) {
if ((i == EQEmu::inventory::slotPrimary) && item->IsType2HWeapon()) {
is2Hweapon = true;
}
linker.SetItemInst(inst);
item_link = linker.GenerateLink();
c->Message(m_message, "Using %s in my %s (slot %i)", item_link.c_str(), GetBotEquipSlotName(i), (i == 22 ? EQEmu::legacy::SlotPowerSource : i));
c->Message(m_message, "Using %s in my %s (slot %i)", item_link.c_str(), GetBotEquipSlotName(i), (i == 22 ? EQEmu::inventory::slotPowerSource : i));
++inventory_count;
}
@@ -7127,13 +7132,13 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep)
}
int slotId = atoi(sep->arg[1]);
if (!sep->IsNumber(1) || ((slotId > EQEmu::legacy::EQUIPMENT_END || slotId < EQEmu::legacy::EQUIPMENT_BEGIN) && slotId != EQEmu::legacy::SlotPowerSource)) {
if (!sep->IsNumber(1) || ((slotId > EQEmu::legacy::EQUIPMENT_END || slotId < EQEmu::legacy::EQUIPMENT_BEGIN) && slotId != EQEmu::inventory::slotPowerSource)) {
c->Message(m_fail, "Valid slots are 0-21 or 9999");
return;
}
const EQEmu::ItemBase* itm = nullptr;
const ItemInst* itminst = my_bot->GetBotItem(slotId);
const EQEmu::ItemData* itm = nullptr;
const EQEmu::ItemInstance* itminst = my_bot->GetBotItem(slotId);
if (itminst)
itm = itminst->GetItem();
@@ -7142,11 +7147,11 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep)
return;
}
for (int m = AUG_INDEX_BEGIN; m < EQEmu::legacy::ITEM_COMMON_SIZE; ++m) {
for (int m = EQEmu::inventory::socketBegin; m < EQEmu::inventory::SocketCount; ++m) {
if (!itminst)
break;
ItemInst *itma = itminst->GetAugment(m);
EQEmu::ItemInstance *itma = itminst->GetAugment(m);
if (!itma)
continue;
if (!c->CheckLoreConflict(itma->GetItem()))
@@ -7159,7 +7164,7 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep)
std::string error_message;
if (itm) {
c->PushItemOnCursor(*itminst, true);
if ((slotId == EQEmu::legacy::SlotRange) || (slotId == EQEmu::legacy::SlotAmmo) || (slotId == EQEmu::legacy::SlotPrimary) || (slotId == EQEmu::legacy::SlotSecondary))
if ((slotId == EQEmu::inventory::slotRange) || (slotId == EQEmu::inventory::slotAmmo) || (slotId == EQEmu::inventory::slotPrimary) || (slotId == EQEmu::inventory::slotSecondary))
my_bot->SetBotArcher(false);
my_bot->RemoveBotItemBySlot(slotId, &error_message);
@@ -7173,31 +7178,31 @@ void bot_subcommand_inventory_remove(Client *c, const Seperator *sep)
}
switch (slotId) {
case EQEmu::legacy::SlotCharm:
case EQEmu::legacy::SlotEar1:
case EQEmu::legacy::SlotHead:
case EQEmu::legacy::SlotFace:
case EQEmu::legacy::SlotEar2:
case EQEmu::legacy::SlotNeck:
case EQEmu::legacy::SlotBack:
case EQEmu::legacy::SlotWrist1:
case EQEmu::legacy::SlotWrist2:
case EQEmu::legacy::SlotRange:
case EQEmu::legacy::SlotPrimary:
case EQEmu::legacy::SlotSecondary:
case EQEmu::legacy::SlotFinger1:
case EQEmu::legacy::SlotFinger2:
case EQEmu::legacy::SlotChest:
case EQEmu::legacy::SlotWaist:
case EQEmu::legacy::SlotPowerSource:
case EQEmu::legacy::SlotAmmo:
case EQEmu::inventory::slotCharm:
case EQEmu::inventory::slotEar1:
case EQEmu::inventory::slotHead:
case EQEmu::inventory::slotFace:
case EQEmu::inventory::slotEar2:
case EQEmu::inventory::slotNeck:
case EQEmu::inventory::slotBack:
case EQEmu::inventory::slotWrist1:
case EQEmu::inventory::slotWrist2:
case EQEmu::inventory::slotRange:
case EQEmu::inventory::slotPrimary:
case EQEmu::inventory::slotSecondary:
case EQEmu::inventory::slotFinger1:
case EQEmu::inventory::slotFinger2:
case EQEmu::inventory::slotChest:
case EQEmu::inventory::slotWaist:
case EQEmu::inventory::slotPowerSource:
case EQEmu::inventory::slotAmmo:
c->Message(m_message, "My %s is %s unequipped", GetBotEquipSlotName(slotId), ((itm) ? ("now") : ("already")));
break;
case EQEmu::legacy::SlotShoulders:
case EQEmu::legacy::SlotArms:
case EQEmu::legacy::SlotHands:
case EQEmu::legacy::SlotLegs:
case EQEmu::legacy::SlotFeet:
case EQEmu::inventory::slotShoulders:
case EQEmu::inventory::slotArms:
case EQEmu::inventory::slotHands:
case EQEmu::inventory::slotLegs:
case EQEmu::inventory::slotFeet:
c->Message(m_message, "My %s are %s unequipped", GetBotEquipSlotName(slotId), ((itm) ? ("now") : ("already")));
break;
default:
@@ -7235,13 +7240,13 @@ void bot_subcommand_inventory_window(Client *c, const Seperator *sep)
//linker.SetLinkType(linker.linkItemInst);
for (int i = EQEmu::legacy::EQUIPMENT_BEGIN; i <= (EQEmu::legacy::EQUIPMENT_END + 1); ++i) {
const EQEmu::ItemBase* item = nullptr;
const ItemInst* inst = my_bot->CastToBot()->GetBotItem(i == 22 ? EQEmu::legacy::SlotPowerSource : i);
const EQEmu::ItemData* item = nullptr;
const EQEmu::ItemInstance* inst = my_bot->CastToBot()->GetBotItem(i == 22 ? EQEmu::inventory::slotPowerSource : i);
if (inst)
item = inst->GetItem();
window_text.append("<c \"#FFFFFF\">");
window_text.append(GetBotEquipSlotName(i == 22 ? EQEmu::legacy::SlotPowerSource : i));
window_text.append(GetBotEquipSlotName(i == 22 ? EQEmu::inventory::slotPowerSource : i));
window_text.append(": ");
if (item) {
//window_text.append("</c>");
+15 -15
View File
@@ -1023,7 +1023,7 @@ bool BotDatabase::QueryInventoryCount(const uint32 bot_id, uint32& item_count)
return true;
}
bool BotDatabase::LoadItems(const uint32 bot_id, Inventory& inventory_inst)
bool BotDatabase::LoadItems(const uint32 bot_id, EQEmu::InventoryProfile& inventory_inst)
{
if (!bot_id)
return false;
@@ -1058,13 +1058,13 @@ bool BotDatabase::LoadItems(const uint32 bot_id, Inventory& inventory_inst)
for (auto row = results.begin(); row != results.end(); ++row) {
int16 slot_id = atoi(row[0]);
if ((slot_id < EQEmu::legacy::EQUIPMENT_BEGIN || slot_id > EQEmu::legacy::EQUIPMENT_END) && slot_id != EQEmu::legacy::SlotPowerSource)
if ((slot_id < EQEmu::legacy::EQUIPMENT_BEGIN || slot_id > EQEmu::legacy::EQUIPMENT_END) && slot_id != EQEmu::inventory::slotPowerSource)
continue;
uint32 item_id = atoi(row[1]);
uint16 item_charges = (uint16)atoi(row[2]);
ItemInst* item_inst = database.CreateItem(
EQEmu::ItemInstance* item_inst = database.CreateItem(
item_id,
item_charges,
(uint32)atoul(row[9]),
@@ -1093,7 +1093,7 @@ bool BotDatabase::LoadItems(const uint32 bot_id, Inventory& inventory_inst)
if (item_inst->GetItem()->Attuneable) {
if (atoi(row[4]))
item_inst->SetAttuned(true);
else if (((slot_id >= EQEmu::legacy::EQUIPMENT_BEGIN) && (slot_id <= EQEmu::legacy::EQUIPMENT_END) || slot_id == EQEmu::legacy::SlotPowerSource))
else if (((slot_id >= EQEmu::legacy::EQUIPMENT_BEGIN) && (slot_id <= EQEmu::legacy::EQUIPMENT_END) || slot_id == EQEmu::inventory::slotPowerSource))
item_inst->SetAttuned(true);
}
@@ -1161,7 +1161,7 @@ bool BotDatabase::LoadItemBySlot(Bot* bot_inst)
bool BotDatabase::LoadItemBySlot(const uint32 bot_id, const uint32 slot_id, uint32& item_id)
{
if (!bot_id || (slot_id > EQEmu::legacy::EQUIPMENT_END && slot_id != EQEmu::legacy::SlotPowerSource))
if (!bot_id || (slot_id > EQEmu::legacy::EQUIPMENT_END && slot_id != EQEmu::inventory::slotPowerSource))
return false;
query = StringFormat("SELECT `item_id` FROM `bot_inventories` WHERE `bot_id` = '%i' AND `slot_id` = '%i' LIMIT 1", bot_id, slot_id);
@@ -1177,9 +1177,9 @@ bool BotDatabase::LoadItemBySlot(const uint32 bot_id, const uint32 slot_id, uint
return true;
}
bool BotDatabase::SaveItemBySlot(Bot* bot_inst, const uint32 slot_id, const ItemInst* item_inst)
bool BotDatabase::SaveItemBySlot(Bot* bot_inst, const uint32 slot_id, const EQEmu::ItemInstance* item_inst)
{
if (!bot_inst || !bot_inst->GetBotID() || (slot_id > EQEmu::legacy::EQUIPMENT_END && slot_id != EQEmu::legacy::SlotPowerSource))
if (!bot_inst || !bot_inst->GetBotID() || (slot_id > EQEmu::legacy::EQUIPMENT_END && slot_id != EQEmu::inventory::slotPowerSource))
return false;
if (!DeleteItemBySlot(bot_inst->GetBotID(), slot_id))
@@ -1188,8 +1188,8 @@ bool BotDatabase::SaveItemBySlot(Bot* bot_inst, const uint32 slot_id, const Item
if (!item_inst || !item_inst->GetID())
return true;
uint32 augment_id[] = { 0, 0, 0, 0, 0, 0 };
for (int augment_iter = 0; augment_iter < EQEmu::legacy::ITEM_COMMON_SIZE; ++augment_iter)
uint32 augment_id[EQEmu::inventory::SocketCount] = { 0, 0, 0, 0, 0, 0 };
for (int augment_iter = EQEmu::inventory::socketBegin; augment_iter < EQEmu::inventory::SocketCount; ++augment_iter)
augment_id[augment_iter] = item_inst->GetAugmentItemID(augment_iter);
uint16 item_charges = 0;
@@ -1263,7 +1263,7 @@ bool BotDatabase::SaveItemBySlot(Bot* bot_inst, const uint32 slot_id, const Item
bool BotDatabase::DeleteItemBySlot(const uint32 bot_id, const uint32 slot_id)
{
if (!bot_id || (slot_id > EQEmu::legacy::EQUIPMENT_END && slot_id != EQEmu::legacy::SlotPowerSource))
if (!bot_id || (slot_id > EQEmu::legacy::EQUIPMENT_END && slot_id != EQEmu::inventory::slotPowerSource))
return false;
query = StringFormat("DELETE FROM `bot_inventories` WHERE `bot_id` = '%u' AND `slot_id` = '%u'", bot_id, slot_id);
@@ -1279,7 +1279,7 @@ bool BotDatabase::LoadEquipmentColor(const uint32 bot_id, const uint8 material_s
if (!bot_id)
return false;
int16 slot_id = Inventory::CalcSlotFromMaterial(material_slot_id);
int16 slot_id = EQEmu::InventoryProfile::CalcSlotFromMaterial(material_slot_id);
if (slot_id == INVALID_INDEX)
return false;
@@ -1302,12 +1302,12 @@ bool BotDatabase::SaveEquipmentColor(const uint32 bot_id, const int16 slot_id, c
return false;
bool all_flag = (slot_id == -2);
if ((slot_id < EQEmu::legacy::EQUIPMENT_BEGIN || slot_id > EQEmu::legacy::EQUIPMENT_END) && slot_id != EQEmu::legacy::SlotPowerSource && !all_flag)
if ((slot_id < EQEmu::legacy::EQUIPMENT_BEGIN || slot_id > EQEmu::legacy::EQUIPMENT_END) && slot_id != EQEmu::inventory::slotPowerSource && !all_flag)
return false;
std::string where_clause;
if (all_flag)
where_clause = StringFormat(" AND `slot_id` IN ('%u', '%u', '%u', '%u', '%u', '%u', '%u')", EQEmu::legacy::SlotHead, EQEmu::legacy::SlotArms, EQEmu::legacy::SlotWrist1, EQEmu::legacy::SlotHands, EQEmu::legacy::SlotChest, EQEmu::legacy::SlotLegs, EQEmu::legacy::SlotFeet);
where_clause = StringFormat(" AND `slot_id` IN ('%u', '%u', '%u', '%u', '%u', '%u', '%u')", EQEmu::inventory::slotHead, EQEmu::inventory::slotArms, EQEmu::inventory::slotWrist1, EQEmu::inventory::slotHands, EQEmu::inventory::slotChest, EQEmu::inventory::slotLegs, EQEmu::inventory::slotFeet);
else
where_clause = StringFormat(" AND `slot_id` = '%u'", slot_id);
@@ -1752,7 +1752,7 @@ bool BotDatabase::SaveAllArmorColorBySlot(const uint32 owner_id, const int16 slo
" AND bi.`slot_id` = '%i'",
owner_id,
rgb_value,
EQEmu::legacy::SlotHead, EQEmu::legacy::SlotChest, EQEmu::legacy::SlotArms, EQEmu::legacy::SlotWrist1, EQEmu::legacy::SlotWrist2, EQEmu::legacy::SlotHands, EQEmu::legacy::SlotLegs, EQEmu::legacy::SlotFeet,
EQEmu::inventory::slotHead, EQEmu::inventory::slotChest, EQEmu::inventory::slotArms, EQEmu::inventory::slotWrist1, EQEmu::inventory::slotWrist2, EQEmu::inventory::slotHands, EQEmu::inventory::slotLegs, EQEmu::inventory::slotFeet,
slot_id
);
auto results = QueryDatabase(query);
@@ -1776,7 +1776,7 @@ bool BotDatabase::SaveAllArmorColors(const uint32 owner_id, const uint32 rgb_val
" AND bi.`slot_id` IN ('%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u')",
owner_id,
rgb_value,
EQEmu::legacy::SlotHead, EQEmu::legacy::SlotChest, EQEmu::legacy::SlotArms, EQEmu::legacy::SlotWrist1, EQEmu::legacy::SlotWrist2, EQEmu::legacy::SlotHands, EQEmu::legacy::SlotLegs, EQEmu::legacy::SlotFeet
EQEmu::inventory::slotHead, EQEmu::inventory::slotChest, EQEmu::inventory::slotArms, EQEmu::inventory::slotWrist1, EQEmu::inventory::slotWrist2, EQEmu::inventory::slotHands, EQEmu::inventory::slotLegs, EQEmu::inventory::slotFeet
);
auto results = QueryDatabase(query);
if (!results.Success())
+8 -4
View File
@@ -31,10 +31,14 @@
class Bot;
class ItemInst;
class Inventory;
struct BotsAvailableList;
namespace EQEmu
{
class ItemInstance;
class InventoryProfile;
}
class BotDatabase : public DBcore
{
@@ -85,13 +89,13 @@ public:
/* Bot inventory functions */
bool QueryInventoryCount(const uint32 bot_id, uint32& item_count);
bool LoadItems(const uint32 bot_id, Inventory &inventory_inst);
bool LoadItems(const uint32 bot_id, EQEmu::InventoryProfile &inventory_inst);
bool SaveItems(Bot* bot_inst);
bool DeleteItems(const uint32 bot_id);
bool LoadItemBySlot(Bot* bot_inst);
bool LoadItemBySlot(const uint32 bot_id, const uint32 slot_id, uint32& item_id);
bool SaveItemBySlot(Bot* bot_inst, const uint32 slot_id, const ItemInst* item_inst);
bool SaveItemBySlot(Bot* bot_inst, const uint32 slot_id, const EQEmu::ItemInstance* item_inst);
bool DeleteItemBySlot(const uint32 bot_id, const uint32 slot_id);
bool LoadEquipmentColor(const uint32 bot_id, const uint8 material_slot_id, uint32& rgb);
+74 -72
View File
@@ -424,6 +424,7 @@ Client::~Client() {
void Client::SendZoneInPackets()
{
//////////////////////////////////////////////////////
// Spawn Appearance Packet
auto outapp = new EQApplicationPacket(OP_SpawnAppearance, sizeof(SpawnAppearance_Struct));
@@ -2017,7 +2018,7 @@ void Client::ReadBook(BookRequest_Struct *book) {
out->window = book->window;
if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF)
{
const ItemInst *inst = m_inv[book->invslot];
const EQEmu::ItemInstance *inst = m_inv[book->invslot];
if(inst)
out->type = inst->GetItem()->Book;
else
@@ -2549,7 +2550,7 @@ void Client::SetFeigned(bool in_feigned) {
feigned=in_feigned;
}
void Client::LogMerchant(Client* player, Mob* merchant, uint32 quantity, uint32 price, const EQEmu::ItemBase* item, bool buying)
void Client::LogMerchant(Client* player, Mob* merchant, uint32 quantity, uint32 price, const EQEmu::ItemData* item, bool buying)
{
if(!player || !merchant || !item)
return;
@@ -2796,11 +2797,11 @@ bool Client::BindWound(Mob *bindmob, bool start, bool fail)
}
void Client::SetMaterial(int16 in_slot, uint32 item_id) {
const EQEmu::ItemBase* item = database.GetItem(item_id);
const EQEmu::ItemData* item = database.GetItem(item_id);
if (item && item->IsClassCommon())
{
uint8 matslot = Inventory::CalcMaterialFromSlot(in_slot);
if (matslot != EQEmu::textures::TextureInvalid)
uint8 matslot = EQEmu::InventoryProfile::CalcMaterialFromSlot(in_slot);
if (matslot != EQEmu::textures::materialInvalid)
{
m_pp.item_material.Slot[matslot].Material = GetEquipmentMaterial(matslot);
}
@@ -3132,17 +3133,17 @@ void Client::Tell_StringID(uint32 string_id, const char *who, const char *messag
}
void Client::SetTint(int16 in_slot, uint32 color) {
EQEmu::Tint_Struct new_color;
EQEmu::textures::Tint_Struct new_color;
new_color.Color = color;
SetTint(in_slot, new_color);
database.SaveCharacterMaterialColor(this->CharacterID(), in_slot, color);
}
// Still need to reconcile bracer01 versus bracer02
void Client::SetTint(int16 in_slot, EQEmu::Tint_Struct& color) {
void Client::SetTint(int16 in_slot, EQEmu::textures::Tint_Struct& color) {
uint8 matslot = Inventory::CalcMaterialFromSlot(in_slot);
if (matslot != EQEmu::textures::TextureInvalid)
uint8 matslot = EQEmu::InventoryProfile::CalcMaterialFromSlot(in_slot);
if (matslot != EQEmu::textures::materialInvalid)
{
m_pp.item_tint.Slot[matslot].Color = color.Color;
database.SaveCharacterMaterialColor(this->CharacterID(), in_slot, color.Color);
@@ -3219,28 +3220,28 @@ void Client::LinkDead()
uint8 Client::SlotConvert(uint8 slot,bool bracer){
uint8 slot2 = 0; // why are we returning MainCharm instead of INVALID_INDEX? (must be a pre-charm segment...)
if(bracer)
return EQEmu::legacy::SlotWrist2;
return EQEmu::inventory::slotWrist2;
switch(slot) {
case EQEmu::textures::TextureHead:
slot2 = EQEmu::legacy::SlotHead;
case EQEmu::textures::armorHead:
slot2 = EQEmu::inventory::slotHead;
break;
case EQEmu::textures::TextureChest:
slot2 = EQEmu::legacy::SlotChest;
case EQEmu::textures::armorChest:
slot2 = EQEmu::inventory::slotChest;
break;
case EQEmu::textures::TextureArms:
slot2 = EQEmu::legacy::SlotArms;
case EQEmu::textures::armorArms:
slot2 = EQEmu::inventory::slotArms;
break;
case EQEmu::textures::TextureWrist:
slot2 = EQEmu::legacy::SlotWrist1;
case EQEmu::textures::armorWrist:
slot2 = EQEmu::inventory::slotWrist1;
break;
case EQEmu::textures::TextureHands:
slot2 = EQEmu::legacy::SlotHands;
case EQEmu::textures::armorHands:
slot2 = EQEmu::inventory::slotHands;
break;
case EQEmu::textures::TextureLegs:
slot2 = EQEmu::legacy::SlotLegs;
case EQEmu::textures::armorLegs:
slot2 = EQEmu::inventory::slotLegs;
break;
case EQEmu::textures::TextureFeet:
slot2 = EQEmu::legacy::SlotFeet;
case EQEmu::textures::armorFeet:
slot2 = EQEmu::inventory::slotFeet;
break;
}
return slot2;
@@ -3249,26 +3250,26 @@ uint8 Client::SlotConvert(uint8 slot,bool bracer){
uint8 Client::SlotConvert2(uint8 slot){
uint8 slot2 = 0; // same as above...
switch(slot){
case EQEmu::legacy::SlotHead:
slot2 = EQEmu::textures::TextureHead;
case EQEmu::inventory::slotHead:
slot2 = EQEmu::textures::armorHead;
break;
case EQEmu::legacy::SlotChest:
slot2 = EQEmu::textures::TextureChest;
case EQEmu::inventory::slotChest:
slot2 = EQEmu::textures::armorChest;
break;
case EQEmu::legacy::SlotArms:
slot2 = EQEmu::textures::TextureArms;
case EQEmu::inventory::slotArms:
slot2 = EQEmu::textures::armorArms;
break;
case EQEmu::legacy::SlotWrist1:
slot2 = EQEmu::textures::TextureWrist;
case EQEmu::inventory::slotWrist1:
slot2 = EQEmu::textures::armorWrist;
break;
case EQEmu::legacy::SlotHands:
slot2 = EQEmu::textures::TextureHands;
case EQEmu::inventory::slotHands:
slot2 = EQEmu::textures::armorHands;
break;
case EQEmu::legacy::SlotLegs:
slot2 = EQEmu::textures::TextureLegs;
case EQEmu::inventory::slotLegs:
slot2 = EQEmu::textures::armorLegs;
break;
case EQEmu::legacy::SlotFeet:
slot2 = EQEmu::textures::TextureFeet;
case EQEmu::inventory::slotFeet:
slot2 = EQEmu::textures::armorFeet;
break;
}
return slot2;
@@ -3839,7 +3840,7 @@ void Client::SendOPTranslocateConfirm(Mob *Caster, uint16 SpellID) {
return;
}
void Client::SendPickPocketResponse(Mob *from, uint32 amt, int type, const EQEmu::ItemBase* item){
void Client::SendPickPocketResponse(Mob *from, uint32 amt, int type, const EQEmu::ItemData* item){
auto outapp = new EQApplicationPacket(OP_PickPocket, sizeof(sPickPocket_Struct));
sPickPocket_Struct *pick_out = (sPickPocket_Struct *)outapp->pBuffer;
pick_out->coin = amt;
@@ -4013,7 +4014,7 @@ bool Client::KeyRingCheck(uint32 item_id)
void Client::KeyRingList()
{
Message(4,"Keys on Keyring:");
const EQEmu::ItemBase *item = 0;
const EQEmu::ItemData *item = 0;
for (auto iter = keyring.begin(); iter != keyring.end(); ++iter) {
if ((item = database.GetItem(*iter))!=nullptr) {
Message(4,item->Name);
@@ -4268,14 +4269,14 @@ bool Client::GroupFollow(Client* inviter) {
uint16 Client::GetPrimarySkillValue()
{
EQEmu::skills::SkillType skill = EQEmu::skills::HIGHEST_SKILL; //because nullptr == 0, which is 1H Slashing, & we want it to return 0 from GetSkill
bool equiped = m_inv.GetItem(EQEmu::legacy::SlotPrimary);
bool equiped = m_inv.GetItem(EQEmu::inventory::slotPrimary);
if (!equiped)
skill = EQEmu::skills::SkillHandtoHand;
else {
uint8 type = m_inv.GetItem(EQEmu::legacy::SlotPrimary)->GetItem()->ItemType; //is this the best way to do this?
uint8 type = m_inv.GetItem(EQEmu::inventory::slotPrimary)->GetItem()->ItemType; //is this the best way to do this?
switch (type) {
case EQEmu::item::ItemType1HSlash: // 1H Slashing
@@ -5440,7 +5441,7 @@ bool Client::TryReward(uint32 claim_id)
uint32 free_slot = 0xFFFFFFFF;
for (int i = EQEmu::legacy::GENERAL_BEGIN; i <= EQEmu::legacy::GENERAL_END; ++i) {
ItemInst *item = GetInv().GetItem(i);
EQEmu::ItemInstance *item = GetInv().GetItem(i);
if (!item) {
free_slot = i;
break;
@@ -5486,7 +5487,7 @@ bool Client::TryReward(uint32 claim_id)
}
auto &ivr = (*iter);
ItemInst *claim = database.CreateItem(ivr.items[0].item_id, ivr.items[0].charges);
EQEmu::ItemInstance *claim = database.CreateItem(ivr.items[0].item_id, ivr.items[0].charges);
if (!claim) {
Save();
return true;
@@ -5496,7 +5497,7 @@ bool Client::TryReward(uint32 claim_id)
for (int y = 1; y < 8; y++)
if (ivr.items[y].item_id && claim->GetItem()->ItemClass == 1) {
ItemInst *item_temp = database.CreateItem(ivr.items[y].item_id, ivr.items[y].charges);
EQEmu::ItemInstance *item_temp = database.CreateItem(ivr.items[y].item_id, ivr.items[y].charges);
if (item_temp) {
if (CheckLoreConflict(item_temp->GetItem())) {
lore_conflict = true;
@@ -5756,8 +5757,8 @@ void Client::ProcessInspectRequest(Client* requestee, Client* requester) {
insr->TargetID = requester->GetID();
insr->playerid = requestee->GetID();
const EQEmu::ItemBase* item = nullptr;
const ItemInst* inst = nullptr;
const EQEmu::ItemData* item = nullptr;
const EQEmu::ItemInstance* inst = nullptr;
int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
for(int16 L = 0; L <= 20; L++) {
inst = requestee->GetInv().GetItem(L);
@@ -5768,7 +5769,7 @@ void Client::ProcessInspectRequest(Client* requestee, Client* requester) {
strcpy(insr->itemnames[L], item->Name);
if (inst && inst->GetOrnamentationAug(ornamentationAugtype))
{
const EQEmu::ItemBase *aug_item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
const EQEmu::ItemData *aug_item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
insr->itemicons[L] = aug_item->Icon;
}
else if (inst && inst->GetOrnamentationIcon())
@@ -5785,7 +5786,7 @@ void Client::ProcessInspectRequest(Client* requestee, Client* requester) {
}
}
inst = requestee->GetInv().GetItem(EQEmu::legacy::SlotPowerSource);
inst = requestee->GetInv().GetItem(EQEmu::inventory::slotPowerSource);
if(inst) {
item = inst->GetItem();
@@ -5799,7 +5800,7 @@ void Client::ProcessInspectRequest(Client* requestee, Client* requester) {
insr->itemicons[SoF::invslot::PossessionsPowerSource] = 0xFFFFFFFF;
}
inst = requestee->GetInv().GetItem(EQEmu::legacy::SlotAmmo);
inst = requestee->GetInv().GetItem(EQEmu::inventory::slotAmmo);
if(inst) {
item = inst->GetItem();
@@ -6341,8 +6342,8 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid
made_npc->Corrup = GetCorrup();
made_npc->PhR = GetPhR();
// looks
made_npc->texture = GetEquipmentMaterial(EQEmu::textures::TextureChest);
made_npc->helmtexture = GetEquipmentMaterial(EQEmu::textures::TextureHead);
made_npc->texture = GetEquipmentMaterial(EQEmu::textures::armorChest);
made_npc->helmtexture = GetEquipmentMaterial(EQEmu::textures::armorHead);
made_npc->haircolor = GetHairColor();
made_npc->beardcolor = GetBeardColor();
made_npc->eyecolor1 = GetEyeColor1();
@@ -6353,9 +6354,9 @@ void Client::Doppelganger(uint16 spell_id, Mob *target, const char *name_overrid
made_npc->drakkin_heritage = GetDrakkinHeritage();
made_npc->drakkin_tattoo = GetDrakkinTattoo();
made_npc->drakkin_details = GetDrakkinDetails();
made_npc->d_melee_texture1 = GetEquipmentMaterial(EQEmu::textures::TexturePrimary);
made_npc->d_melee_texture2 = GetEquipmentMaterial(EQEmu::textures::TextureSecondary);
for (int i = EQEmu::textures::TextureBegin; i <= EQEmu::textures::LastTexture; i++) {
made_npc->d_melee_texture1 = GetEquipmentMaterial(EQEmu::textures::weaponPrimary);
made_npc->d_melee_texture2 = GetEquipmentMaterial(EQEmu::textures::weaponSecondary);
for (int i = EQEmu::textures::textureBegin; i <= EQEmu::textures::LastTexture; i++) {
made_npc->armor_tint.Slot[i].Color = GetEquipmentColor(i);
}
made_npc->loottable_id = 0;
@@ -6949,7 +6950,7 @@ void Client::SendAltCurrencies() {
uint32 i = 0;
auto iter = zone->AlternateCurrencies.begin();
while(iter != zone->AlternateCurrencies.end()) {
const EQEmu::ItemBase* item = database.GetItem((*iter).item_id);
const EQEmu::ItemData* item = database.GetItem((*iter).item_id);
altc->entries[i].currency_number = (*iter).id;
altc->entries[i].unknown00 = 1;
altc->entries[i].currency_number2 = (*iter).id;
@@ -7272,7 +7273,8 @@ void Client::SendXTargetUpdates()
for (int i = 0; i < GetMaxXTargets(); ++i) {
if (XTargets[i].dirty) {
outapp->WriteUInt32(i);
outapp->WriteUInt8(0); // no idea what this is
// MQ2 checks this for valid mobs, so 0 is bad here at least ...
outapp->WriteUInt8(XTargets[i].ID ? 1 : 0);
outapp->WriteUInt32(XTargets[i].ID);
outapp->WriteString(XTargets[i].Name);
count++;
@@ -7604,7 +7606,7 @@ void Client::DuplicateLoreMessage(uint32 ItemID)
return;
}
const EQEmu::ItemBase *item = database.GetItem(ItemID);
const EQEmu::ItemData *item = database.GetItem(ItemID);
if(!item)
return;
@@ -8061,7 +8063,7 @@ void Client::TickItemCheck()
TryItemTick(i);
}
//Scan main inventory + cursor
for (i = EQEmu::legacy::GENERAL_BEGIN; i <= EQEmu::legacy::SlotCursor; i++)
for (i = EQEmu::legacy::GENERAL_BEGIN; i <= EQEmu::inventory::slotCursor; i++)
{
TryItemTick(i);
}
@@ -8075,7 +8077,7 @@ void Client::TickItemCheck()
void Client::TryItemTick(int slot)
{
int iid = 0;
const ItemInst* inst = m_inv[slot];
const EQEmu::ItemInstance* inst = m_inv[slot];
if(inst == 0) { return; }
iid = inst->GetID();
@@ -8084,7 +8086,7 @@ void Client::TryItemTick(int slot)
{
if (GetLevel() >= zone->tick_items[iid].level && zone->random.Int(0, 100) >= (100 - zone->tick_items[iid].chance) && (zone->tick_items[iid].bagslot || slot <= EQEmu::legacy::EQUIPMENT_END))
{
ItemInst* e_inst = (ItemInst*)inst;
EQEmu::ItemInstance* e_inst = (EQEmu::ItemInstance*)inst;
parse->EventItem(EVENT_ITEM_TICK, this, e_inst, nullptr, "", slot);
}
}
@@ -8092,9 +8094,9 @@ void Client::TryItemTick(int slot)
//Only look at augs in main inventory
if (slot > EQEmu::legacy::EQUIPMENT_END) { return; }
for (int x = AUG_INDEX_BEGIN; x < EQEmu::legacy::ITEM_COMMON_SIZE; ++x)
for (int x = EQEmu::inventory::socketBegin; x < EQEmu::inventory::SocketCount; ++x)
{
ItemInst * a_inst = inst->GetAugment(x);
EQEmu::ItemInstance * a_inst = inst->GetAugment(x);
if(!a_inst) { continue; }
iid = a_inst->GetID();
@@ -8103,7 +8105,7 @@ void Client::TryItemTick(int slot)
{
if( GetLevel() >= zone->tick_items[iid].level && zone->random.Int(0, 100) >= (100 - zone->tick_items[iid].chance) )
{
ItemInst* e_inst = (ItemInst*)a_inst;
EQEmu::ItemInstance* e_inst = (EQEmu::ItemInstance*)a_inst;
parse->EventItem(EVENT_ITEM_TICK, this, e_inst, nullptr, "", slot);
}
}
@@ -8118,7 +8120,7 @@ void Client::ItemTimerCheck()
TryItemTimer(i);
}
for (i = EQEmu::legacy::GENERAL_BEGIN; i <= EQEmu::legacy::SlotCursor; i++)
for (i = EQEmu::legacy::GENERAL_BEGIN; i <= EQEmu::inventory::slotCursor; i++)
{
TryItemTimer(i);
}
@@ -8131,7 +8133,7 @@ void Client::ItemTimerCheck()
void Client::TryItemTimer(int slot)
{
ItemInst* inst = m_inv.GetItem(slot);
EQEmu::ItemInstance* inst = m_inv.GetItem(slot);
if(!inst) {
return;
}
@@ -8149,9 +8151,9 @@ void Client::TryItemTimer(int slot)
return;
}
for (int x = AUG_INDEX_BEGIN; x < EQEmu::legacy::ITEM_COMMON_SIZE; ++x)
for (int x = EQEmu::inventory::socketBegin; x < EQEmu::inventory::SocketCount; ++x)
{
ItemInst * a_inst = inst->GetAugment(x);
EQEmu::ItemInstance * a_inst = inst->GetAugment(x);
if(!a_inst) {
continue;
}
@@ -8167,7 +8169,7 @@ void Client::TryItemTimer(int slot)
}
}
void Client::SendItemScale(ItemInst *inst) {
void Client::SendItemScale(EQEmu::ItemInstance *inst) {
int slot = m_inv.GetSlotByItemInst(inst);
if(slot != -1) {
inst->ScaleItem();
@@ -8321,7 +8323,7 @@ void Client::SetConsumption(int32 in_hunger, int32 in_thirst)
safe_delete(outapp);
}
void Client::Consume(const EQEmu::ItemBase *item, uint8 type, int16 slot, bool auto_consume)
void Client::Consume(const EQEmu::ItemData *item, uint8 type, int16 slot, bool auto_consume)
{
if(!item) { return; }
@@ -8436,7 +8438,7 @@ void Client::ShowNumHits()
int Client::GetQuiverHaste(int delay)
{
const ItemInst *pi = nullptr;
const EQEmu::ItemInstance *pi = nullptr;
for (int r = EQEmu::legacy::GENERAL_BEGIN; r <= EQEmu::legacy::GENERAL_END; r++) {
pi = GetInv().GetItem(r);
if (pi && pi->IsClassBag() && pi->GetItem()->BagType == EQEmu::item::BagTypeQuiver &&
@@ -8482,7 +8484,7 @@ void Client::QuestReward(Mob* target, uint32 copper, uint32 silver, uint32 gold,
AddMoneyToPP(copper, silver, gold, platinum, false);
if (itemid > 0)
SummonItem(itemid, 0, 0, 0, 0, 0, 0, false, EQEmu::legacy::SlotPowerSource);
SummonItem(itemid, 0, 0, 0, 0, 0, 0, false, EQEmu::inventory::slotPowerSource);
if (faction)
{
+44 -43
View File
@@ -31,7 +31,7 @@ enum WaterRegionType : int;
namespace EQEmu
{
struct ItemBase;
struct ItemData;
}
#include "../common/timer.h"
@@ -45,9 +45,9 @@ namespace EQEmu
#include "../common/extprofile.h"
#include "../common/races.h"
#include "../common/seperator.h"
#include "../common/item.h"
#include "../common/inventory_profile.h"
#include "../common/guilds.h"
#include "../common/item_base.h"
//#include "../common/item_data.h"
#include "common.h"
#include "merc.h"
@@ -222,7 +222,7 @@ public:
//abstract virtual function implementations required by base abstract class
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill);
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, int special = 0);
virtual bool Attack(Mob* other, int Hand = EQEmu::legacy::SlotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
virtual bool Attack(Mob* other, int Hand = EQEmu::inventory::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
ExtraAttackOptions *opts = nullptr, int special = 0);
virtual bool HasRaid() { return (GetRaid() ? true : false); }
virtual bool HasGroup() { return (GetGroup() ? true : false); }
@@ -250,7 +250,7 @@ public:
void KeyRingList();
virtual bool IsClient() const { return true; }
void CompleteConnect();
bool TryStacking(ItemInst* item, uint8 type = ItemPacketTrade, bool try_worn = true, bool try_cursor = true);
bool TryStacking(EQEmu::ItemInstance* item, uint8 type = ItemPacketTrade, bool try_worn = true, bool try_cursor = true);
void SendTraderPacket(Client* trader, uint32 Unknown72 = 51);
void SendBuyerPacket(Client* Buyer);
GetItems_Struct* GetTraderItems();
@@ -273,7 +273,7 @@ public:
void SendTraderItem(uint32 item_id,uint16 quantity);
uint16 FindTraderItem(int32 SerialNumber,uint16 Quantity);
uint32 FindTraderItemSerialNumber(int32 ItemID);
ItemInst* FindTraderItemBySerialNumber(int32 SerialNumber);
EQEmu::ItemInstance* FindTraderItemBySerialNumber(int32 SerialNumber);
void FindAndNukeTraderItem(int32 item_id,uint16 quantity,Client* customer,uint16 traderslot);
void NukeTraderItem(uint16 slot, int16 charges, uint16 quantity, Client* customer, uint16 traderslot, int32 uniqueid, int32 itemid = 0);
void ReturnTraderReq(const EQApplicationPacket* app,int16 traderitemcharges, uint32 itemid = 0);
@@ -294,7 +294,7 @@ public:
void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
virtual bool Process();
void LogMerchant(Client* player, Mob* merchant, uint32 quantity, uint32 price, const EQEmu::ItemBase* item, bool buying);
void LogMerchant(Client* player, Mob* merchant, uint32 quantity, uint32 price, const EQEmu::ItemData* item, bool buying);
void SendPacketQueue(bool Block = true);
void QueuePacket(const EQApplicationPacket* app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL, eqFilterType filter=FilterNone);
void FastQueuePacket(EQApplicationPacket** app, bool ack_req = true, CLIENT_CONN_STATUS = CLIENT_CONNECTINGALL);
@@ -308,7 +308,7 @@ public:
void LearnRecipe(uint32 recipeID);
bool CanIncreaseTradeskill(EQEmu::skills::SkillType tradeskill);
EQApplicationPacket* ReturnItemPacket(int16 slot_id, const ItemInst* inst, ItemPacketType packet_type);
EQApplicationPacket* ReturnItemPacket(int16 slot_id, const EQEmu::ItemInstance* inst, ItemPacketType packet_type);
bool GetRevoked() const { return revoked; }
void SetRevoked(bool rev) { revoked = rev; }
@@ -340,8 +340,8 @@ public:
inline uint8 GetAnon() const { return m_pp.anon; }
inline PlayerProfile_Struct& GetPP() { return m_pp; }
inline ExtendedProfile_Struct& GetEPP() { return m_epp; }
inline Inventory& GetInv() { return m_inv; }
inline const Inventory& GetInv() const { return m_inv; }
inline EQEmu::InventoryProfile& GetInv() { return m_inv; }
inline const EQEmu::InventoryProfile& GetInv() const { return m_inv; }
inline PetInfo* GetPetInfo(uint16 pet) { return (pet==1)?&m_suspendedminion:&m_petinfo; }
inline InspectMessage_Struct& GetInspectMessage() { return m_inspect_message; }
inline const InspectMessage_Struct& GetInspectMessage() const { return m_inspect_message; }
@@ -403,7 +403,7 @@ public:
inline uint8 GetLanguageSkill(uint16 n) const { return m_pp.languages[n]; }
void SendPickPocketResponse(Mob *from, uint32 amt, int type, const EQEmu::ItemBase* item = nullptr);
void SendPickPocketResponse(Mob *from, uint32 amt, int type, const EQEmu::ItemData* item = nullptr);
inline const char* GetLastName() const { return lastname; }
@@ -509,10 +509,10 @@ public:
virtual int GetCurrentBuffSlots() const;
virtual int GetCurrentSongSlots() const;
virtual int GetCurrentDiscSlots() const { return 1; }
virtual int GetMaxBuffSlots() const { return 25; }
virtual int GetMaxSongSlots() const { return 12; }
virtual int GetMaxDiscSlots() const { return 1; }
virtual int GetMaxTotalSlots() const { return 38; }
virtual int GetMaxBuffSlots() const { return EQEmu::constants::LongBuffs; }
virtual int GetMaxSongSlots() const { return EQEmu::constants::ShortBuffs; }
virtual int GetMaxDiscSlots() const { return EQEmu::constants::DiscBuffs; }
virtual int GetMaxTotalSlots() const { return EQEmu::constants::TotalBuffs; }
virtual uint32 GetFirstBuffSlot(bool disc, bool song);
virtual uint32 GetLastBuffSlot(bool disc, bool song);
virtual void InitializeBuffSlots();
@@ -601,7 +601,7 @@ public:
void AssignToInstance(uint16 instance_id);
void RemoveFromInstance(uint16 instance_id);
void WhoAll();
bool CheckLoreConflict(const EQEmu::ItemBase* item);
bool CheckLoreConflict(const EQEmu::ItemData* item);
void ChangeLastName(const char* in_lastname);
void GetGroupAAs(GroupLeadershipAA_Struct *into) const;
void GetRaidAAs(RaidLeadershipAA_Struct *into) const;
@@ -808,30 +808,30 @@ public:
uint32 NukeItem(uint32 itemnum, uint8 where_to_check =
(invWhereWorn | invWherePersonal | invWhereBank | invWhereSharedBank | invWhereTrading | invWhereCursor));
void SetTint(int16 slot_id, uint32 color);
void SetTint(int16 slot_id, EQEmu::Tint_Struct& color);
void SetTint(int16 slot_id, EQEmu::textures::Tint_Struct& color);
void SetMaterial(int16 slot_id, uint32 item_id);
void Undye();
int32 GetItemIDAt(int16 slot_id);
int32 GetAugmentIDAt(int16 slot_id, uint8 augslot);
bool PutItemInInventory(int16 slot_id, const ItemInst& inst, bool client_update = false);
bool PushItemOnCursor(const ItemInst& inst, bool client_update = false);
bool PutItemInInventory(int16 slot_id, const EQEmu::ItemInstance& inst, bool client_update = false);
bool PushItemOnCursor(const EQEmu::ItemInstance& inst, bool client_update = false);
void SendCursorBuffer();
void DeleteItemInInventory(int16 slot_id, int8 quantity = 0, bool client_update = false, bool update_db = true);
bool SwapItem(MoveItem_Struct* move_in);
void SwapItemResync(MoveItem_Struct* move_slots);
void QSSwapItemAuditor(MoveItem_Struct* move_in, bool postaction_call = false);
void PutLootInInventory(int16 slot_id, const ItemInst &inst, ServerLootItem_Struct** bag_item_data = 0);
bool AutoPutLootInInventory(ItemInst& inst, bool try_worn = false, bool try_cursor = true, ServerLootItem_Struct** bag_item_data = 0);
bool SummonItem(uint32 item_id, int16 charges = -1, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, bool attuned = false, uint16 to_slot = EQEmu::legacy::SlotCursor, uint32 ornament_icon = 0, uint32 ornament_idfile = 0, uint32 ornament_hero_model = 0);
void PutLootInInventory(int16 slot_id, const EQEmu::ItemInstance &inst, ServerLootItem_Struct** bag_item_data = 0);
bool AutoPutLootInInventory(EQEmu::ItemInstance& inst, bool try_worn = false, bool try_cursor = true, ServerLootItem_Struct** bag_item_data = 0);
bool SummonItem(uint32 item_id, int16 charges = -1, uint32 aug1 = 0, uint32 aug2 = 0, uint32 aug3 = 0, uint32 aug4 = 0, uint32 aug5 = 0, uint32 aug6 = 0, bool attuned = false, uint16 to_slot = EQEmu::inventory::slotCursor, uint32 ornament_icon = 0, uint32 ornament_idfile = 0, uint32 ornament_hero_model = 0);
void SetStats(uint8 type,int16 set_val);
void IncStats(uint8 type,int16 increase_val);
void DropItem(int16 slot_id);
void DropItem(int16 slot_id, bool recurse = true);
int GetItemLinkHash(const ItemInst* inst); // move to ItemBase..or make use of the pre-calculated database field
int GetItemLinkHash(const EQEmu::ItemInstance* inst); // move to ItemData..or make use of the pre-calculated database field
void SendItemLink(const ItemInst* inst, bool sendtoall=false);
void SendLootItemInPacket(const ItemInst* inst, int16 slot_id);
void SendItemPacket(int16 slot_id, const ItemInst* inst, ItemPacketType packet_type);
void SendItemLink(const EQEmu::ItemInstance* inst, bool sendtoall=false);
void SendLootItemInPacket(const EQEmu::ItemInstance* inst, int16 slot_id);
void SendItemPacket(int16 slot_id, const EQEmu::ItemInstance* inst, ItemPacketType packet_type);
bool IsValidSlot(uint32 slot);
bool IsBankSlot(uint32 slot);
@@ -855,6 +855,7 @@ public:
void SetConsumption(int32 in_hunger, int32 in_thirst);
bool CheckTradeLoreConflict(Client* other);
bool CheckTradeNonDroppable();
void LinkDead();
void Insight(uint32 t_id);
bool CheckDoubleAttack();
@@ -887,7 +888,7 @@ public:
//Calculate vendor price modifier based on CHA: (reverse==selling)
float CalcPriceMod(Mob* other = 0, bool reverse = false);
void ResetTrade();
void DropInst(const ItemInst* inst);
void DropInst(const EQEmu::ItemInstance* inst);
bool TrainDiscipline(uint32 itemid);
void TrainDiscBySpellID(int32 spell_id);
int GetDiscSlotBySpellID(int32 spellid);
@@ -965,7 +966,7 @@ public:
inline void UpdateTasksForItem(ActivityType Type, int ItemID, int Count=1) { if(taskstate) taskstate->UpdateTasksForItem(this, Type, ItemID, Count); }
inline void UpdateTasksOnExplore(int ExploreID) { if(taskstate) taskstate->UpdateTasksOnExplore(this, ExploreID); }
inline bool UpdateTasksOnSpeakWith(int NPCTypeID) { if(taskstate) return taskstate->UpdateTasksOnSpeakWith(this, NPCTypeID); else return false; }
inline bool UpdateTasksOnDeliver(std::list<ItemInst*>& Items, int Cash, int NPCTypeID) { if (taskstate) return taskstate->UpdateTasksOnDeliver(this, Items, Cash, NPCTypeID); else return false; }
inline bool UpdateTasksOnDeliver(std::list<EQEmu::ItemInstance*>& Items, int Cash, int NPCTypeID) { if (taskstate) return taskstate->UpdateTasksOnDeliver(this, Items, Cash, NPCTypeID); else return false; }
inline void TaskSetSelector(Mob *mob, int TaskSetID) { if(taskmanager) taskmanager->TaskSetSelector(this, taskstate, mob, TaskSetID); }
inline void EnableTask(int TaskCount, int *TaskList) { if(taskstate) taskstate->EnableTask(CharacterID(), TaskCount, TaskList); }
inline void DisableTask(int TaskCount, int *TaskList) { if(taskstate) taskstate->DisableTask(CharacterID(), TaskCount, TaskList); }
@@ -1080,7 +1081,7 @@ public:
inline bool GetPendingGuildInvitation() { return PendingGuildInvitation; }
void LocateCorpse();
void SendTargetCommand(uint32 EntityID);
bool MoveItemToInventory(ItemInst *BInst, bool UpdateClient = false);
bool MoveItemToInventory(EQEmu::ItemInstance *BInst, bool UpdateClient = false);
void HandleRespawnFromHover(uint32 Option);
bool IsHoveringForRespawn() { return RespawnFromHoverTimer.Enabled(); }
std::list<RespawnOption> respawn_options;
@@ -1173,7 +1174,7 @@ public:
void TryItemTick(int slot);
void ItemTimerCheck();
void TryItemTimer(int slot);
void SendItemScale(ItemInst *inst);
void SendItemScale(EQEmu::ItemInstance *inst);
int32 GetActSTR() { return( std::min(GetMaxSTR(), GetSTR()) ); }
int32 GetActSTA() { return( std::min(GetMaxSTA(), GetSTA()) ); }
@@ -1186,10 +1187,10 @@ public:
void SetAccountFlag(std::string flag, std::string val);
std::string GetAccountFlag(std::string flag);
float GetDamageMultiplier(EQEmu::skills::SkillType how_long_has_this_been_missing);
void Consume(const EQEmu::ItemBase *item, uint8 type, int16 slot, bool auto_consume);
void Consume(const EQEmu::ItemData *item, uint8 type, int16 slot, bool auto_consume);
void PlayMP3(const char* fname);
void ExpeditionSay(const char *str, int ExpID);
int mod_client_damage(int damage, EQEmu::skills::SkillType skillinuse, int hand, const ItemInst* weapon, Mob* other);
int mod_client_damage(int damage, EQEmu::skills::SkillType skillinuse, int hand, const EQEmu::ItemInstance* weapon, Mob* other);
bool mod_client_message(char* message, uint8 chan_num);
bool mod_can_increase_skill(EQEmu::skills::SkillType skillid, Mob* against_who);
int16 mod_increase_skill_chance(int16 chance, Mob* against_who);
@@ -1201,16 +1202,16 @@ public:
int16 mod_pet_power(int16 act_power, uint16 spell_id);
float mod_tradeskill_chance(float chance, DBTradeskillRecipe_Struct *spec);
float mod_tradeskill_skillup(float chance_stage2);
int32 mod_tribute_item_value(int32 pts, const ItemInst* item);
int32 mod_tribute_item_value(int32 pts, const EQEmu::ItemInstance* item);
void mod_client_death_npc(Mob* killerMob);
void mod_client_death_duel(Mob* killerMob);
void mod_client_death_env();
int32 mod_client_xp(int32 in_exp, NPC *npc);
uint32 mod_client_xp_for_level(uint32 xp, uint16 check_level);
int mod_client_haste_cap(int cap);
int mod_consume(EQEmu::ItemBase *item, EQEmu::item::ItemType type, int change);
int mod_food_value(const EQEmu::ItemBase *item, int change);
int mod_drink_value(const EQEmu::ItemBase *item, int change);
int mod_consume(EQEmu::ItemData *item, EQEmu::item::ItemType type, int change);
int mod_food_value(const EQEmu::ItemData *item, int change);
int mod_drink_value(const EQEmu::ItemData *item, int change);
void SetEngagedRaidTarget(bool value) { EngagedRaidTarget = value; }
bool GetEngagedRaidTarget() const { return EngagedRaidTarget; }
@@ -1244,8 +1245,8 @@ public:
protected:
friend class Mob;
void CalcItemBonuses(StatBonuses* newbon);
void AddItemBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug = false, bool isTribute = false, int rec_override = 0, bool ammo_slot_item = false);
void AdditiveWornBonuses(const ItemInst *inst, StatBonuses* newbon, bool isAug = false);
void AddItemBonuses(const EQEmu::ItemInstance *inst, StatBonuses* newbon, bool isAug = false, bool isTribute = false, int rec_override = 0, bool ammo_slot_item = false);
void AdditiveWornBonuses(const EQEmu::ItemInstance *inst, StatBonuses* newbon, bool isAug = false);
int CalcRecommendedLevelBonus(uint8 level, uint8 reclevel, int basestat);
void CalcEdibleBonuses(StatBonuses* newbon);
void ProcessItemCaps();
@@ -1286,7 +1287,7 @@ private:
void OPRezzAnswer(uint32 Action, uint32 SpellID, uint16 ZoneID, uint16 InstanceID, float x, float y, float z);
void OPMemorizeSpell(const EQApplicationPacket *app);
void OPMoveCoin(const EQApplicationPacket* app);
void MoveItemCharges(ItemInst &from, int16 to_slot, uint8 type);
void MoveItemCharges(EQEmu::ItemInstance &from, int16 to_slot, uint8 type);
void OPGMTraining(const EQApplicationPacket *app);
void OPGMEndTraining(const EQApplicationPacket *app);
void OPGMTrainSkill(const EQApplicationPacket *app);
@@ -1395,7 +1396,7 @@ private:
PlayerProfile_Struct m_pp;
ExtendedProfile_Struct m_epp;
Inventory m_inv;
EQEmu::InventoryProfile m_inv;
Object* m_tradeskill_object;
PetInfo m_petinfo; // current pet data, used while loading from and saving to DB
PetInfo m_suspendedminion; // pet data for our suspended minion.
@@ -1561,8 +1562,8 @@ private:
bool interrogateinv_flag; // used to minimize log spamming by players
void InterrogateInventory_(bool errorcheck, Client* requester, int16 head, int16 index, const ItemInst* inst, const ItemInst* parent, bool log, bool silent, bool &error, int depth);
bool InterrogateInventory_error(int16 head, int16 index, const ItemInst* inst, const ItemInst* parent, int depth);
void InterrogateInventory_(bool errorcheck, Client* requester, int16 head, int16 index, const EQEmu::ItemInstance* inst, const EQEmu::ItemInstance* parent, bool log, bool silent, bool &error, int depth);
bool InterrogateInventory_error(int16 head, int16 index, const EQEmu::ItemInstance* inst, const EQEmu::ItemInstance* parent, int depth);
};
#endif
+25 -13
View File
@@ -486,7 +486,7 @@ int32 Client::GetRawItemAC()
int32 Total = 0;
// this skips MainAmmo..add an '=' conditional if that slot is required (original behavior)
for (int16 slot_id = EQEmu::legacy::EQUIPMENT_BEGIN; slot_id < EQEmu::legacy::EQUIPMENT_END; slot_id++) {
const ItemInst* inst = m_inv[slot_id];
const EQEmu::ItemInstance* inst = m_inv[slot_id];
if (inst && inst->IsClassCommon()) {
Total += inst->GetItem()->AC;
}
@@ -1074,9 +1074,9 @@ int32 Client::CalcAC()
}
// Shield AC bonus for HeroicSTR
if (itembonuses.HeroicSTR) {
bool equiped = CastToClient()->m_inv.GetItem(EQEmu::legacy::SlotSecondary);
bool equiped = CastToClient()->m_inv.GetItem(EQEmu::inventory::slotSecondary);
if (equiped) {
uint8 shield = CastToClient()->m_inv.GetItem(EQEmu::legacy::SlotSecondary)->GetItem()->ItemType;
uint8 shield = CastToClient()->m_inv.GetItem(EQEmu::inventory::slotSecondary)->GetItem()->ItemType;
if (shield == EQEmu::item::ItemTypeShield) {
displayed += itembonuses.HeroicSTR / 2;
}
@@ -1103,9 +1103,9 @@ int32 Client::GetACMit()
}
// Shield AC bonus for HeroicSTR
if (itembonuses.HeroicSTR) {
bool equiped = CastToClient()->m_inv.GetItem(EQEmu::legacy::SlotSecondary);
bool equiped = CastToClient()->m_inv.GetItem(EQEmu::inventory::slotSecondary);
if (equiped) {
uint8 shield = CastToClient()->m_inv.GetItem(EQEmu::legacy::SlotSecondary)->GetItem()->ItemType;
uint8 shield = CastToClient()->m_inv.GetItem(EQEmu::inventory::slotSecondary)->GetItem()->ItemType;
if (shield == EQEmu::item::ItemTypeShield) {
mitigation += itembonuses.HeroicSTR / 2;
}
@@ -1316,11 +1316,11 @@ int32 Client::CalcManaRegenCap()
uint32 Client::CalcCurrentWeight()
{
const EQEmu::ItemBase* TempItem = 0;
ItemInst* ins;
const EQEmu::ItemData* TempItem = 0;
EQEmu::ItemInstance* ins;
uint32 Total = 0;
int x;
for (x = EQEmu::legacy::EQUIPMENT_BEGIN; x <= EQEmu::legacy::SlotCursor; x++) { // include cursor or not?
for (x = EQEmu::legacy::EQUIPMENT_BEGIN; x <= EQEmu::inventory::slotCursor; x++) { // include cursor or not?
TempItem = 0;
ins = GetInv().GetItem(x);
if (ins) {
@@ -1343,14 +1343,14 @@ uint32 Client::CalcCurrentWeight()
if (TmpWeight > 0) {
// this code indicates that weight redux bags can only be in the first general inventory slot to be effective...
// is this correct? or can we scan for the highest weight redux and use that? (need client verifications)
int bagslot = EQEmu::legacy::SlotGeneral1;
int bagslot = EQEmu::inventory::slotGeneral1;
int reduction = 0;
for (int m = EQEmu::legacy::GENERAL_BAGS_BEGIN + 10; m <= EQEmu::legacy::GENERAL_BAGS_END; m += 10) { // include cursor bags or not?
if (x >= m) {
bagslot += 1;
}
}
ItemInst* baginst = GetInv().GetItem(bagslot);
EQEmu::ItemInstance* baginst = GetInv().GetItem(bagslot);
if (baginst && baginst->GetItem() && baginst->IsClassBag()) {
reduction = baginst->GetItem()->BagWR;
}
@@ -1369,7 +1369,7 @@ uint32 Client::CalcCurrentWeight()
This is the ONLY instance I have seen where the client is hard coded to particular Item IDs to set a certain property for an item. It is very odd.
*/
// SoD+ client has no weight for coin
if (EQEmu::behavior::Lookup(EQEmu::versions::ConvertClientVersionToInventoryVersion(ClientVersion()))->CoinHasWeight) {
if (EQEmu::behavior::Lookup(EQEmu::versions::ConvertClientVersionToMobVersion(ClientVersion()))->CoinHasWeight) {
Total += (m_pp.platinum + m_pp.gold + m_pp.silver + m_pp.copper) / 4;
}
float Packrat = (float)spellbonuses.Packrat + (float)aabonuses.Packrat + (float)itembonuses.Packrat;
@@ -2219,12 +2219,12 @@ int Client::GetRawACNoShield(int &shield_ac) const
{
int ac = itembonuses.AC + spellbonuses.AC + aabonuses.AC;
shield_ac = 0;
const ItemInst *inst = m_inv.GetItem(EQEmu::legacy::SlotSecondary);
const EQEmu::ItemInstance *inst = m_inv.GetItem(EQEmu::inventory::slotSecondary);
if (inst) {
if (inst->GetItem()->ItemType == EQEmu::item::ItemTypeShield) {
ac -= inst->GetItem()->AC;
shield_ac = inst->GetItem()->AC;
for (uint8 i = AUG_INDEX_BEGIN; i < EQEmu::legacy::ITEM_COMMON_SIZE; i++) {
for (uint8 i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) {
if (inst->GetAugment(i)) {
ac -= inst->GetAugment(i)->GetItem()->AC;
shield_ac += inst->GetAugment(i)->GetItem()->AC;
@@ -2232,5 +2232,17 @@ int Client::GetRawACNoShield(int &shield_ac) const
}
}
}
Log.Out(
Logs::General,
Logs::Combat,
"[%s] [Client::GetRawACNoShield] AC [%i] ItemAC [%i] SpellAC [%i] AAAC [%i]",
GetName(),
ac,
itembonuses.AC,
spellbonuses.AC,
aabonuses.AC
);
return ac;
}
+151 -119
View File
@@ -493,6 +493,7 @@ int Client::HandlePacket(const EQApplicationPacket *app)
// Finish client connecting state
void Client::CompleteConnect()
{
UpdateWho();
client_state = CLIENT_CONNECTED;
SendAllPackets();
@@ -502,27 +503,6 @@ void Client::CompleteConnect()
SetDuelTarget(0);
SetDueling(false);
database.LoadPetInfo(this);
/*
This was moved before the spawn packets are sent
in hopes that it adds more consistency...
Remake pet
*/
if (m_petinfo.SpellID > 1 && !GetPet() && m_petinfo.SpellID <= SPDAT_RECORDS) {
MakePoweredPet(m_petinfo.SpellID, spells[m_petinfo.SpellID].teleport_zone, m_petinfo.petpower, m_petinfo.Name, m_petinfo.size);
if (GetPet() && GetPet()->IsNPC()) {
NPC *pet = GetPet()->CastToNPC();
pet->SetPetState(m_petinfo.Buffs, m_petinfo.Items);
pet->CalcBonuses();
pet->SetHP(m_petinfo.HP);
pet->SetMana(m_petinfo.Mana);
}
m_petinfo.SpellID = 0;
}
/* Moved here so it's after where we load the pet data. */
if (!GetAA(aaPersistentMinion))
memset(&m_suspendedminion, 0, sizeof(PetInfo));
EnteringMessages(this);
LoadZoneFlags();
@@ -1334,7 +1314,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
}
/* Set item material tint */
for (int i = EQEmu::textures::TextureBegin; i <= EQEmu::textures::LastTexture; i++)
for (int i = EQEmu::textures::textureBegin; i <= EQEmu::textures::LastTexture; i++)
{
if (m_pp.item_tint.Slot[i].UseTint == 1 || m_pp.item_tint.Slot[i].UseTint == 255)
{
@@ -1480,7 +1460,7 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
database.LoadBuffs(this);
uint32 max_slots = GetMaxBuffSlots();
for (int i = 0; i < max_slots; i++) {
for (int i = 0; i < BUFF_COUNT; i++) {
if (buffs[i].spellid != SPELL_UNKNOWN) {
m_pp.buffs[i].spellid = buffs[i].spellid;
m_pp.buffs[i].bard_modifier = buffs[i].instrument_mod;
@@ -1649,6 +1629,23 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
if (m_pp.RestTimer)
rest_timer.Start(m_pp.RestTimer * 1000);
/* Load Pet */
database.LoadPetInfo(this);
if (m_petinfo.SpellID > 1 && !GetPet() && m_petinfo.SpellID <= SPDAT_RECORDS) {
MakePoweredPet(m_petinfo.SpellID, spells[m_petinfo.SpellID].teleport_zone, m_petinfo.petpower, m_petinfo.Name, m_petinfo.size);
if (GetPet() && GetPet()->IsNPC()) {
NPC *pet = GetPet()->CastToNPC();
pet->SetPetState(m_petinfo.Buffs, m_petinfo.Items);
pet->CalcBonuses();
pet->SetHP(m_petinfo.HP);
pet->SetMana(m_petinfo.Mana);
}
m_petinfo.SpellID = 0;
}
/* Moved here so it's after where we load the pet data. */
if (!GetAA(aaPersistentMinion))
memset(&m_suspendedminion, 0, sizeof(PetInfo));
/* Server Zone Entry Packet */
outapp = new EQApplicationPacket(OP_ZoneEntry, sizeof(ServerZoneEntry_Struct));
ServerZoneEntry_Struct* sze = (ServerZoneEntry_Struct*)outapp->pBuffer;
@@ -1690,8 +1687,8 @@ void Client::Handle_Connect_OP_ZoneEntry(const EQApplicationPacket *app)
/* First item cursor is sent in bulk inventory packet */
if (iter == m_inv.cursor_cbegin())
continue;
const ItemInst *inst = *iter;
SendItemPacket(EQEmu::legacy::SlotCursor, inst, ItemPacketLimbo);
const EQEmu::ItemInstance *inst = *iter;
SendItemPacket(EQEmu::inventory::slotCursor, inst, ItemPacketLimbo);
}
}
@@ -1883,7 +1880,7 @@ void Client::Handle_OP_AdventureMerchantPurchase(const EQApplicationPacket *app)
merchantid = tmp->CastToNPC()->MerchantType;
const EQEmu::ItemBase* item = nullptr;
const EQEmu::ItemData* item = nullptr;
bool found = false;
std::list<MerchantList> merlist = zone->merchanttable[merchantid];
std::list<MerchantList>::const_iterator itr;
@@ -2026,10 +2023,10 @@ void Client::Handle_OP_AdventureMerchantPurchase(const EQApplicationPacket *app)
if (item->MaxCharges != 0)
charges = item->MaxCharges;
ItemInst *inst = database.CreateItem(item, charges);
EQEmu::ItemInstance *inst = database.CreateItem(item, charges);
if (!AutoPutLootInInventory(*inst, true, true))
{
PutLootInInventory(EQEmu::legacy::SlotCursor, *inst);
PutLootInInventory(EQEmu::inventory::slotCursor, *inst);
}
Save(1);
}
@@ -2059,7 +2056,7 @@ void Client::Handle_OP_AdventureMerchantRequest(const EQApplicationPacket *app)
merchantid = tmp->CastToNPC()->MerchantType;
tmp->CastToNPC()->FaceTarget(this->CastToMob());
const EQEmu::ItemBase *item = 0;
const EQEmu::ItemData *item = 0;
std::list<MerchantList> merlist = zone->merchanttable[merchantid];
std::list<MerchantList>::const_iterator itr;
for (itr = merlist.begin(); itr != merlist.end() && count<255; ++itr){
@@ -2158,8 +2155,8 @@ void Client::Handle_OP_AdventureMerchantSell(const EQApplicationPacket *app)
return;
}
const EQEmu::ItemBase* item = database.GetItem(itemid);
ItemInst* inst = GetInv().GetItem(ams_in->slot);
const EQEmu::ItemData* item = database.GetItem(itemid);
EQEmu::ItemInstance* inst = GetInv().GetItem(ams_in->slot);
if (!item || !inst){
Message(13, "You seemed to have misplaced that item...");
return;
@@ -2435,7 +2432,7 @@ void Client::Handle_OP_AltCurrencyMerchantRequest(const EQApplicationPacket *app
ss << alt_cur_id << "|1|" << alt_cur_id;
uint32 count = 0;
uint32 merchant_id = tar->MerchantType;
const EQEmu::ItemBase *item = nullptr;
const EQEmu::ItemData *item = nullptr;
std::list<MerchantList> merlist = zone->merchanttable[merchant_id];
std::list<MerchantList>::const_iterator itr;
@@ -2495,7 +2492,7 @@ void Client::Handle_OP_AltCurrencyPurchase(const EQApplicationPacket *app)
return;
}
const EQEmu::ItemBase* item = nullptr;
const EQEmu::ItemData* item = nullptr;
uint32 cost = 0;
uint32 current_currency = GetAlternateCurrencyValue(alt_cur_id);
uint32 merchant_id = tar->MerchantType;
@@ -2551,10 +2548,10 @@ void Client::Handle_OP_AltCurrencyPurchase(const EQApplicationPacket *app)
if (item->MaxCharges != 0)
charges = item->MaxCharges;
ItemInst *inst = database.CreateItem(item, charges);
EQEmu::ItemInstance *inst = database.CreateItem(item, charges);
if (!AutoPutLootInInventory(*inst, true, true))
{
PutLootInInventory(EQEmu::legacy::SlotCursor, *inst);
PutLootInInventory(EQEmu::inventory::slotCursor, *inst);
}
Save(1);
@@ -2604,7 +2601,7 @@ void Client::Handle_OP_AltCurrencyReclaim(const EQApplicationPacket *app)
SetAlternateCurrencyValue(reclaim->currency_id, 0);
}
else {
SummonItem(item_id, reclaim->count, 0, 0, 0, 0, 0, 0, false, EQEmu::legacy::SlotCursor);
SummonItem(item_id, reclaim->count, 0, 0, 0, 0, 0, 0, false, EQEmu::inventory::slotCursor);
AddAlternateCurrencyValue(reclaim->currency_id, -((int32)reclaim->count));
}
/* QS: PlayerLogAlternateCurrencyTransactions :: Cursor to Item Storage */
@@ -2635,7 +2632,7 @@ void Client::Handle_OP_AltCurrencySell(const EQApplicationPacket *app)
return;
}
ItemInst* inst = GetInv().GetItem(sell->slot_id);
EQEmu::ItemInstance* inst = GetInv().GetItem(sell->slot_id);
if (!inst) {
return;
}
@@ -2644,7 +2641,7 @@ void Client::Handle_OP_AltCurrencySell(const EQApplicationPacket *app)
return;
}
const EQEmu::ItemBase* item = nullptr;
const EQEmu::ItemData* item = nullptr;
uint32 cost = 0;
uint32 current_currency = GetAlternateCurrencyValue(alt_cur_id);
uint32 merchant_id = tar->MerchantType;
@@ -2732,12 +2729,12 @@ void Client::Handle_OP_AltCurrencySellSelection(const EQApplicationPacket *app)
return;
}
ItemInst *inst = m_inv.GetItem(select->slot_id);
EQEmu::ItemInstance *inst = m_inv.GetItem(select->slot_id);
if (!inst) {
return;
}
const EQEmu::ItemBase* item = nullptr;
const EQEmu::ItemData* item = nullptr;
uint32 cost = 0;
uint32 current_currency = GetAlternateCurrencyValue(alt_cur_id);
uint32 merchant_id = tar->MerchantType;
@@ -2816,9 +2813,9 @@ void Client::Handle_OP_ApplyPoison(const EQApplicationPacket *app)
}
uint32 ApplyPoisonSuccessResult = 0;
ApplyPoison_Struct* ApplyPoisonData = (ApplyPoison_Struct*)app->pBuffer;
const ItemInst* PrimaryWeapon = GetInv().GetItem(EQEmu::legacy::SlotPrimary);
const ItemInst* SecondaryWeapon = GetInv().GetItem(EQEmu::legacy::SlotSecondary);
const ItemInst* PoisonItemInstance = GetInv()[ApplyPoisonData->inventorySlot];
const EQEmu::ItemInstance* PrimaryWeapon = GetInv().GetItem(EQEmu::inventory::slotPrimary);
const EQEmu::ItemInstance* SecondaryWeapon = GetInv().GetItem(EQEmu::inventory::slotSecondary);
const EQEmu::ItemInstance* PoisonItemInstance = GetInv()[ApplyPoisonData->inventorySlot];
bool IsPoison = PoisonItemInstance && (PoisonItemInstance->GetItem()->ItemType == EQEmu::item::ItemTypePoison);
@@ -2912,7 +2909,7 @@ void Client::Handle_OP_AugmentInfo(const EQApplicationPacket *app)
}
AugmentInfo_Struct* AugInfo = (AugmentInfo_Struct*)app->pBuffer;
const EQEmu::ItemBase * item = database.GetItem(AugInfo->itemid);
const EQEmu::ItemData * item = database.GetItem(AugInfo->itemid);
if (item) {
strn0cpy(AugInfo->augment_info, item->Name, 64);
@@ -2933,17 +2930,30 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
bool deleteItems = false;
if (ClientVersion() >= EQEmu::versions::ClientVersion::RoF)
{
ItemInst *itemOneToPush = nullptr, *itemTwoToPush = nullptr;
if ((in_augment->container_slot < 0 || in_augment->container_slot >= EQEmu::legacy::SLOT_CURSOR) &&
in_augment->container_slot != EQEmu::legacy::SLOT_POWER_SOURCE &&
(in_augment->container_slot < EQEmu::legacy::SLOT_PERSONAL_BAGS_BEGIN || in_augment->container_slot > EQEmu::legacy::SLOT_PERSONAL_BAGS_END))
{
Message(13, "The server does not allow augmentation actions from this slot.");
auto cursor_item = m_inv[EQEmu::legacy::SLOT_CURSOR];
auto augmented_item = m_inv[in_augment->container_slot];
SendItemPacket(EQEmu::legacy::SLOT_CURSOR, cursor_item, ItemPacketCharInventory);
// this may crash clients on certain slots
SendItemPacket(in_augment->container_slot, augmented_item, ItemPacketCharInventory);
return;
}
EQEmu::ItemInstance *itemOneToPush = nullptr, *itemTwoToPush = nullptr;
//Log.Out(Logs::DebugLevel::Moderate, Logs::Debug, "cslot: %i aslot: %i cidx: %i aidx: %i act: %i dest: %i",
// in_augment->container_slot, in_augment->augment_slot, in_augment->container_index, in_augment->augment_index, in_augment->augment_action, in_augment->dest_inst_id);
ItemInst *tobe_auged = nullptr, *old_aug = nullptr, *new_aug = nullptr, *aug = nullptr, *solvent = nullptr;
Inventory& user_inv = GetInv();
EQEmu::ItemInstance *tobe_auged = nullptr, *old_aug = nullptr, *new_aug = nullptr, *aug = nullptr, *solvent = nullptr;
EQEmu::InventoryProfile& user_inv = GetInv();
uint16 item_slot = in_augment->container_slot;
uint16 solvent_slot = in_augment->augment_slot;
uint8 mat = Inventory::CalcMaterialFromSlot(item_slot); // for when player is augging a piece of equipment while they're wearing it
uint8 mat = EQEmu::InventoryProfile::CalcMaterialFromSlot(item_slot); // for when player is augging a piece of equipment while they're wearing it
if (item_slot == INVALID_INDEX || solvent_slot == INVALID_INDEX)
{
@@ -2999,7 +3009,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
{
case 0: // Adding an augment
case 2: // Swapping augment
new_aug = user_inv.GetItem(EQEmu::legacy::SlotCursor);
new_aug = user_inv.GetItem(EQEmu::inventory::slotCursor);
if (!new_aug) // Shouldn't get the OP code without the augment on the user's cursor, but maybe it's h4x.
{
@@ -3057,7 +3067,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
if (itemOneToPush)
{
DeleteItemInInventory(item_slot, 0, true);
DeleteItemInInventory(EQEmu::legacy::SlotCursor, new_aug->IsStackable() ? 1 : 0, true);
DeleteItemInInventory(EQEmu::inventory::slotCursor, new_aug->IsStackable() ? 1 : 0, true);
if (solvent)
{
@@ -3068,7 +3078,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
if (itemTwoToPush)
{
// This is a swap. Return the old aug to the player's cursor.
if (!PutItemInInventory(EQEmu::legacy::SlotCursor, *itemTwoToPush, true))
if (!PutItemInInventory(EQEmu::inventory::slotCursor, *itemTwoToPush, true))
{
Log.Out(Logs::General, Logs::Error, "Problem returning old augment to player's cursor after augmentation swap.");
Message(15, "Error: Failed to retrieve old augment after augmentation swap!");
@@ -3081,7 +3091,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
CalcBonuses();
if (mat != EQEmu::textures::TextureInvalid)
if (mat != EQEmu::textures::materialInvalid)
{
SendWearChange(mat); // Visible item augged while equipped. Send WC in case ornamentation changed.
}
@@ -3146,13 +3156,13 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
CalcBonuses();
if (mat != EQEmu::textures::TextureInvalid)
if (mat != EQEmu::textures::materialInvalid)
{
SendWearChange(mat); // Visible item augged while equipped. Send WC in case ornamentation changed.
}
// Drop the removed augment on the player's cursor
if (!PutItemInInventory(EQEmu::legacy::SlotCursor, *itemTwoToPush, true))
if (!PutItemInInventory(EQEmu::inventory::slotCursor, *itemTwoToPush, true))
{
Log.Out(Logs::General, Logs::Error, "Problem returning augment to player's cursor after safe removal.");
Message(15, "Error: Failed to return augment after removal from item!");
@@ -3201,7 +3211,7 @@ void Client::Handle_OP_AugmentItem(const EQApplicationPacket *app)
CalcBonuses();
if (mat != EQEmu::textures::TextureInvalid)
if (mat != EQEmu::textures::materialInvalid)
{
SendWearChange(mat);
}
@@ -3494,13 +3504,13 @@ void Client::Handle_OP_Barter(const EQApplicationPacket *app)
{
BarterItemSearchLinkRequest_Struct* bislr = (BarterItemSearchLinkRequest_Struct*)app->pBuffer;
const EQEmu::ItemBase* item = database.GetItem(bislr->ItemID);
const EQEmu::ItemData* item = database.GetItem(bislr->ItemID);
if (!item)
Message(13, "Error: This item does not exist!");
else
{
ItemInst* inst = database.CreateItem(item);
EQEmu::ItemInstance* inst = database.CreateItem(item);
if (inst)
{
SendItemPacket(0, inst, ItemPacketViewLink);
@@ -3527,13 +3537,13 @@ void Client::Handle_OP_Barter(const EQApplicationPacket *app)
{
BuyerItemSearchLinkRequest_Struct* bislr = (BuyerItemSearchLinkRequest_Struct*)app->pBuffer;
const EQEmu::ItemBase* item = database.GetItem(bislr->ItemID);
const EQEmu::ItemData* item = database.GetItem(bislr->ItemID);
if (!item)
Message(13, "Error: This item does not exist!");
else
{
ItemInst* inst = database.CreateItem(item);
EQEmu::ItemInstance* inst = database.CreateItem(item);
if (inst)
{
SendItemPacket(0, inst, ItemPacketViewLink);
@@ -3566,14 +3576,14 @@ void Client::Handle_OP_BazaarInspect(const EQApplicationPacket *app)
BazaarInspect_Struct* bis = (BazaarInspect_Struct*)app->pBuffer;
const EQEmu::ItemBase* item = database.GetItem(bis->ItemID);
const EQEmu::ItemData* item = database.GetItem(bis->ItemID);
if (!item) {
Message(13, "Error: This item does not exist!");
return;
}
ItemInst* inst = database.CreateItem(item);
EQEmu::ItemInstance* inst = database.CreateItem(item);
if (inst) {
SendItemPacket(0, inst, ItemPacketViewLink);
@@ -3606,7 +3616,7 @@ void Client::Handle_OP_BazaarSearch(const EQApplicationPacket *app)
Client *c = entity_list.GetClientByName(nbis->Name);
if (c) {
ItemInst* inst = c->FindTraderItemBySerialNumber(nbis->SerialNumber);
EQEmu::ItemInstance* inst = c->FindTraderItemBySerialNumber(nbis->SerialNumber);
if (inst)
SendItemPacket(0, inst, ItemPacketViewLink);
}
@@ -4007,11 +4017,11 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
if (m_inv.SupportsClickCasting(castspell->inventoryslot) || slot == CastingSlot::PotionBelt) // sanity check
{
// packet field types will be reviewed as packet transistions occur
const ItemInst* inst = m_inv[castspell->inventoryslot]; //slot values are int16, need to check packet on this field
const EQEmu::ItemInstance* inst = m_inv[castspell->inventoryslot]; //slot values are int16, need to check packet on this field
//bool cancast = true;
if (inst && inst->IsClassCommon())
{
const EQEmu::ItemBase* item = inst->GetItem();
const EQEmu::ItemData* item = inst->GetItem();
if (item->Click.Effect != (uint32)castspell->spell_id)
{
database.SetMQDetectionFlag(account_name, name, "OP_CastSpell with item, tried to cast a different spell.", zone->GetShortName());
@@ -4025,7 +4035,7 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
{
if (GetLevel() >= item->Click.Level2)
{
ItemInst* p_inst = (ItemInst*)inst;
EQEmu::ItemInstance* p_inst = (EQEmu::ItemInstance*)inst;
int i = parse->EventItem(EVENT_ITEM_CLICK_CAST, this, p_inst, nullptr, "", castspell->inventoryslot);
if (i == 0) {
@@ -4045,7 +4055,7 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
}
else
{
ItemInst* p_inst = (ItemInst*)inst;
EQEmu::ItemInstance* p_inst = (EQEmu::ItemInstance*)inst;
int i = parse->EventItem(EVENT_ITEM_CLICK_CAST, this, p_inst, nullptr, "", castspell->inventoryslot);
if (i == 0) {
@@ -4070,7 +4080,7 @@ void Client::Handle_OP_CastSpell(const EQApplicationPacket *app)
}
else
{
Message(0, "Error: castspell->inventoryslot >= %i (0x%04x)", EQEmu::legacy::SlotCursor, castspell->inventoryslot);
Message(0, "Error: castspell->inventoryslot >= %i (0x%04x)", EQEmu::inventory::slotCursor, castspell->inventoryslot);
InterruptSpell(castspell->spell_id);
}
}
@@ -4857,13 +4867,13 @@ void Client::Handle_OP_Consume(const EQApplicationPacket *app)
}
}
ItemInst *myitem = GetInv().GetItem(pcs->slot);
EQEmu::ItemInstance *myitem = GetInv().GetItem(pcs->slot);
if (myitem == nullptr) {
Log.Out(Logs::General, Logs::Error, "Consuming from empty slot %d", pcs->slot);
return;
}
const EQEmu::ItemBase* eat_item = myitem->GetItem();
const EQEmu::ItemData* eat_item = myitem->GetItem();
if (pcs->type == 0x01) {
Consume(eat_item, EQEmu::item::ItemTypeFood, pcs->slot, (pcs->auto_consumed == 0xffffffff));
}
@@ -4993,7 +5003,10 @@ void Client::Handle_OP_CrashDump(const EQApplicationPacket *app)
void Client::Handle_OP_CreateObject(const EQApplicationPacket *app)
{
DropItem(EQEmu::legacy::SlotCursor);
if (Log.log_settings[Logs::Inventory].is_category_enabled)
Log.Out(Logs::Detail, Logs::Inventory, "Handle_OP_CreateObject() [psize: %u] %s", app->size, DumpPacketToString(app).c_str());
DropItem(EQEmu::inventory::slotCursor);
return;
}
@@ -5146,7 +5159,7 @@ void Client::Handle_OP_DeleteItem(const EQApplicationPacket *app)
}
DeleteItem_Struct* alc = (DeleteItem_Struct*)app->pBuffer;
const ItemInst *inst = GetInv().GetItem(alc->from_slot);
const EQEmu::ItemInstance *inst = GetInv().GetItem(alc->from_slot);
if (inst && inst->GetItem()->ItemType == EQEmu::item::ItemTypeAlcohol) {
entity_list.MessageClose_StringID(this, true, 50, 0, DRINKING_MESSAGE, GetName(), inst->GetItem()->Name);
CheckIncreaseSkill(EQEmu::skills::SkillAlcoholTolerance, nullptr, 25);
@@ -6876,7 +6889,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
if (Slot >= 0)
{
ItemInst* inst = GuildBanks->GetItem(GuildID(), GuildBankMainArea, Slot, 1);
EQEmu::ItemInstance* inst = GuildBanks->GetItem(GuildID(), GuildBankMainArea, Slot, 1);
if (inst)
{
@@ -6896,7 +6909,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
{
GuildBankViewItem_Struct *gbvis = (GuildBankViewItem_Struct*)app->pBuffer;
ItemInst* inst = GuildBanks->GetItem(GuildID(), gbvis->Area, gbvis->SlotID, 1);
EQEmu::ItemInstance* inst = GuildBanks->GetItem(GuildID(), gbvis->Area, gbvis->SlotID, 1);
if (!inst)
break;
@@ -6919,7 +6932,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
return;
}
ItemInst *CursorItemInst = GetInv().GetItem(EQEmu::legacy::SlotCursor);
EQEmu::ItemInstance *CursorItemInst = GetInv().GetItem(EQEmu::inventory::slotCursor);
bool Allowed = true;
@@ -6932,7 +6945,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
return;
}
const EQEmu::ItemBase* CursorItem = CursorItemInst->GetItem();
const EQEmu::ItemData* CursorItem = CursorItemInst->GetItem();
if (!CursorItem->NoDrop || CursorItemInst->IsAttuned())
{
@@ -6967,7 +6980,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
{
GuildBankDepositAck(false, sentAction);
DeleteItemInInventory(EQEmu::legacy::SlotCursor, 0, false);
DeleteItemInInventory(EQEmu::inventory::slotCursor, 0, false);
}
break;
@@ -6988,7 +7001,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
case GuildBankWithdraw:
{
if (GetInv()[EQEmu::legacy::SlotCursor])
if (GetInv()[EQEmu::inventory::slotCursor])
{
Message_StringID(13, GUILD_BANK_EMPTY_HANDS);
@@ -6999,7 +7012,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
GuildBankWithdrawItem_Struct *gbwis = (GuildBankWithdrawItem_Struct*)app->pBuffer;
ItemInst* inst = GuildBanks->GetItem(GuildID(), gbwis->Area, gbwis->SlotID, gbwis->Quantity);
EQEmu::ItemInstance* inst = GuildBanks->GetItem(GuildID(), gbwis->Area, gbwis->SlotID, gbwis->Quantity);
if (!inst)
{
@@ -7034,7 +7047,7 @@ void Client::Handle_OP_GuildBank(const EQApplicationPacket *app)
{
PushItemOnCursor(*inst);
SendItemPacket(EQEmu::legacy::SlotCursor, inst, ItemPacketLimbo);
SendItemPacket(EQEmu::inventory::slotCursor, inst, ItemPacketLimbo);
GuildBanks->DeleteItem(GuildID(), gbwis->Area, gbwis->SlotID, gbwis->Quantity);
}
@@ -7911,6 +7924,7 @@ void Client::Handle_OP_Hide(const EQApplicationPacket *app)
}
else
hidden = true;
tmHidden = Timer::GetCurrentTime();
}
if (GetClass() == ROGUE){
auto outapp = new EQApplicationPacket(OP_SimpleMessage, sizeof(SimpleMessage_Struct));
@@ -8013,17 +8027,17 @@ void Client::Handle_OP_InspectAnswer(const EQApplicationPacket *app)
EQApplicationPacket* outapp = app->Copy();
InspectResponse_Struct* insr = (InspectResponse_Struct*)outapp->pBuffer;
Mob* tmp = entity_list.GetMob(insr->TargetID);
const EQEmu::ItemBase* item = nullptr;
const EQEmu::ItemData* item = nullptr;
int ornamentationAugtype = RuleI(Character, OrnamentationAugmentType);
for (int16 L = EQEmu::legacy::EQUIPMENT_BEGIN; L <= EQEmu::legacy::SlotWaist; L++) {
const ItemInst* inst = GetInv().GetItem(L);
for (int16 L = EQEmu::legacy::EQUIPMENT_BEGIN; L <= EQEmu::inventory::slotWaist; L++) {
const EQEmu::ItemInstance* inst = GetInv().GetItem(L);
item = inst ? inst->GetItem() : nullptr;
if (item) {
strcpy(insr->itemnames[L], item->Name);
if (inst && inst->GetOrnamentationAug(ornamentationAugtype)) {
const EQEmu::ItemBase *aug_item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
const EQEmu::ItemData *aug_item = inst->GetOrnamentationAug(ornamentationAugtype)->GetItem();
insr->itemicons[L] = aug_item->Icon;
}
else if (inst->GetOrnamentationIcon()) {
@@ -8036,7 +8050,7 @@ void Client::Handle_OP_InspectAnswer(const EQApplicationPacket *app)
else { insr->itemicons[L] = 0xFFFFFFFF; }
}
const ItemInst* inst = GetInv().GetItem(EQEmu::legacy::SlotAmmo);
const EQEmu::ItemInstance* inst = GetInv().GetItem(EQEmu::inventory::slotAmmo);
item = inst ? inst->GetItem() : nullptr;
if (item) {
@@ -8123,7 +8137,7 @@ void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app)
// todo: verify ivrs->link_hash based on a rule, in case we don't care about people being able to sniff data
// from the item DB
const EQEmu::ItemBase *item = database.GetItem(ivrs->item_id);
const EQEmu::ItemData *item = database.GetItem(ivrs->item_id);
if (!item) {
if (ivrs->item_id != SAYLINK_ITEM_ID) {
Message(13, "Error: The item for the link you have clicked on does not exist!");
@@ -8181,7 +8195,7 @@ void Client::Handle_OP_ItemLinkClick(const EQApplicationPacket *app)
}
}
ItemInst *inst =
EQEmu::ItemInstance *inst =
database.CreateItem(item, item->MaxCharges, ivrs->augments[0], ivrs->augments[1], ivrs->augments[2],
ivrs->augments[3], ivrs->augments[4], ivrs->augments[5]);
if (inst) {
@@ -8198,7 +8212,7 @@ void Client::Handle_OP_ItemLinkResponse(const EQApplicationPacket *app)
return;
}
LDONItemViewRequest_Struct* item = (LDONItemViewRequest_Struct*)app->pBuffer;
ItemInst* inst = database.CreateItem(item->item_id);
EQEmu::ItemInstance* inst = database.CreateItem(item->item_id);
if (inst) {
SendItemPacket(0, inst, ItemPacketViewLink);
safe_delete(inst);
@@ -8214,7 +8228,7 @@ void Client::Handle_OP_ItemName(const EQApplicationPacket *app)
return;
}
ItemNamePacket_Struct *p = (ItemNamePacket_Struct*)app->pBuffer;
const EQEmu::ItemBase *item = 0;
const EQEmu::ItemData *item = 0;
if ((item = database.GetItem(p->item_id)) != nullptr) {
auto outapp = new EQApplicationPacket(OP_ItemName, sizeof(ItemNamePacket_Struct));
p = (ItemNamePacket_Struct*)outapp->pBuffer;
@@ -8230,7 +8244,7 @@ void Client::Handle_OP_ItemPreview(const EQApplicationPacket *app)
VERIFY_PACKET_LENGTH(OP_ItemPreview, app, ItemPreview_Struct);
ItemPreview_Struct *ips = (ItemPreview_Struct *)app->pBuffer;
const EQEmu::ItemBase* item = database.GetItem(ips->itemid);
const EQEmu::ItemData* item = database.GetItem(ips->itemid);
if (item) {
auto outapp = new EQApplicationPacket(OP_ItemPreview, strlen(item->Name) + strlen(item->Lore) +
@@ -8441,14 +8455,14 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
return;
}
const ItemInst* inst = m_inv[slot_id];
const EQEmu::ItemInstance* inst = m_inv[slot_id];
if (!inst) {
Message(0, "Error: item not found in inventory slot #%i", slot_id);
DeleteItemInInventory(slot_id, 0, true);
return;
}
const EQEmu::ItemBase* item = inst->GetItem();
const EQEmu::ItemData* item = inst->GetItem();
if (!item) {
Message(0, "Error: item not found in inventory slot #%i", slot_id);
DeleteItemInInventory(slot_id, 0, true);
@@ -8484,7 +8498,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
if (m_inv.SupportsClickCasting(slot_id) || ((item->ItemType == EQEmu::item::ItemTypePotion || item->PotionBelt) && m_inv.SupportsPotionBeltCasting(slot_id))) // sanity check
{
ItemInst* p_inst = (ItemInst*)inst;
EQEmu::ItemInstance* p_inst = (EQEmu::ItemInstance*)inst;
parse->EventItem(EVENT_ITEM_CLICK, this, p_inst, nullptr, "", slot_id);
inst = m_inv[slot_id];
@@ -8495,22 +8509,22 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
int r;
bool tryaug = false;
ItemInst* clickaug = 0;
EQEmu::ItemBase* augitem = 0;
EQEmu::ItemInstance* clickaug = 0;
EQEmu::ItemData* augitem = 0;
for (r = 0; r < EQEmu::legacy::ITEM_COMMON_SIZE; r++) {
const ItemInst* aug_i = inst->GetAugment(r);
for (r = EQEmu::inventory::socketBegin; r < EQEmu::inventory::SocketCount; r++) {
const EQEmu::ItemInstance* aug_i = inst->GetAugment(r);
if (!aug_i)
continue;
const EQEmu::ItemBase* aug = aug_i->GetItem();
const EQEmu::ItemData* aug = aug_i->GetItem();
if (!aug)
continue;
if ((aug->Click.Type == EQEmu::item::ItemEffectClick) || (aug->Click.Type == EQEmu::item::ItemEffectExpendable) || (aug->Click.Type == EQEmu::item::ItemEffectEquipClick) || (aug->Click.Type == EQEmu::item::ItemEffectClick2))
{
tryaug = true;
clickaug = (ItemInst*)aug_i;
augitem = (EQEmu::ItemBase*)aug;
clickaug = (EQEmu::ItemInstance*)aug_i;
augitem = (EQEmu::ItemData*)aug;
spell_id = aug->Click.Effect;
break;
}
@@ -9678,8 +9692,8 @@ void Client::Handle_OP_MoveItem(const EQApplicationPacket *app)
if (mi->from_slot != mi->to_slot && (mi->from_slot <= EQEmu::legacy::GENERAL_END || mi->from_slot > 39) && IsValidSlot(mi->from_slot) && IsValidSlot(mi->to_slot))
{
char *detect = nullptr;
const ItemInst *itm_from = GetInv().GetItem(mi->from_slot);
const ItemInst *itm_to = GetInv().GetItem(mi->to_slot);
const EQEmu::ItemInstance *itm_from = GetInv().GetItem(mi->from_slot);
const EQEmu::ItemInstance *itm_to = GetInv().GetItem(mi->to_slot);
MakeAnyLenString(&detect, "Player issued a move item from %u(item id %u) to %u(item id %u) while casting %u.",
mi->from_slot,
itm_from ? itm_from->GetID() : 0,
@@ -10545,7 +10559,7 @@ void Client::Handle_OP_PotionBelt(const EQApplicationPacket *app)
}
if (mptbs->Action == 0) {
const EQEmu::ItemBase *BaseItem = database.GetItem(mptbs->ItemID);
const EQEmu::ItemData *BaseItem = database.GetItem(mptbs->ItemID);
if (BaseItem) {
m_pp.potionbelt.Items[mptbs->SlotNumber].ID = BaseItem->ID;
m_pp.potionbelt.Items[mptbs->SlotNumber].Icon = BaseItem->Icon;
@@ -12031,12 +12045,12 @@ void Client::Handle_OP_Shielding(const EQApplicationPacket *app)
Shielding_Struct* shield = (Shielding_Struct*)app->pBuffer;
shield_target = entity_list.GetMob(shield->target_id);
bool ack = false;
ItemInst* inst = GetInv().GetItem(EQEmu::legacy::SlotSecondary);
EQEmu::ItemInstance* inst = GetInv().GetItem(EQEmu::inventory::slotSecondary);
if (!shield_target)
return;
if (inst)
{
const EQEmu::ItemBase* shield = inst->GetItem();
const EQEmu::ItemData* shield = inst->GetItem();
if (shield && shield->ItemType == EQEmu::item::ItemTypeShield)
{
for (int x = 0; x < 2; x++)
@@ -12134,17 +12148,12 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app)
continue;
}
int32 fac = tmp->GetPrimaryFaction();
if (fac != 0 && GetModCharacterFactionLevel(fac) < ml.faction_required) {
continue;
}
if (mp->itemslot == ml.slot){
item_id = ml.item;
break;
}
}
const EQEmu::ItemBase* item = nullptr;
const EQEmu::ItemData* item = nullptr;
uint32 prevcharges = 0;
if (item_id == 0) { //check to see if its on the temporary table
std::list<TempMerchantList> tmp_merlist = zone->tmpmerchanttable[tmp->GetNPCTypeID()];
@@ -12205,7 +12214,7 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app)
else
charges = item->MaxCharges;
ItemInst* inst = database.CreateItem(item, charges);
EQEmu::ItemInstance* inst = database.CreateItem(item, charges);
int SinglePrice = 0;
if (RuleB(Merchant, UsePriceMod))
@@ -12248,8 +12257,8 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app)
// shouldn't we be reimbursing if these two fail?
//make sure we are not completely full...
if (freeslotid == EQEmu::legacy::SlotCursor) {
if (m_inv.GetItem(EQEmu::legacy::SlotCursor) != nullptr) {
if (freeslotid == EQEmu::inventory::slotCursor) {
if (m_inv.GetItem(EQEmu::inventory::slotCursor) != nullptr) {
Message(13, "You do not have room for any more items.");
safe_delete(outapp);
safe_delete(inst);
@@ -12326,7 +12335,7 @@ void Client::Handle_OP_ShopPlayerBuy(const EQApplicationPacket *app)
qsaudit->items[0].item_id = item->ID;
qsaudit->items[0].charges = mpo->quantity;
const ItemInst* audit_inst = m_inv[freeslotid];
const EQEmu::ItemInstance* audit_inst = m_inv[freeslotid];
if (audit_inst) {
qsaudit->items[0].aug_1 = audit_inst->GetAugmentItemID(0);
@@ -12392,8 +12401,8 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app)
uint32 itemid = GetItemIDAt(mp->itemslot);
if (itemid == 0)
return;
const EQEmu::ItemBase* item = database.GetItem(itemid);
ItemInst* inst = GetInv().GetItem(mp->itemslot);
const EQEmu::ItemData* item = database.GetItem(itemid);
EQEmu::ItemInstance* inst = GetInv().GetItem(mp->itemslot);
if (!item || !inst){
Message(13, "You seemed to have misplaced that item..");
return;
@@ -12438,7 +12447,7 @@ void Client::Handle_OP_ShopPlayerSell(const EQApplicationPacket *app)
int freeslot = 0;
if (charges > 0 && (freeslot = zone->SaveTempItem(vendor->CastToNPC()->MerchantType, vendor->GetNPCTypeID(), itemid, charges, true)) > 0){
ItemInst* inst2 = inst->Clone();
EQEmu::ItemInstance* inst2 = inst->Clone();
while (true) {
if (inst2 == nullptr)
@@ -13281,7 +13290,6 @@ void Client::Handle_OP_TradeAcceptClick(const EQApplicationPacket *app)
other->trade->state = TradeCompleting;
trade->state = TradeCompleting;
// should we do this for NoDrop items as well?
if (CheckTradeLoreConflict(other) || other->CheckTradeLoreConflict(this)) {
Message_StringID(13, TRADE_CANCEL_LORE);
other->Message_StringID(13, TRADE_CANCEL_LORE);
@@ -13290,6 +13298,26 @@ void Client::Handle_OP_TradeAcceptClick(const EQApplicationPacket *app)
other->trade->Reset();
trade->Reset();
}
else if (CheckTradeNonDroppable()) {
Message_StringID(13, TRADE_HAS_BEEN_CANCELLED);
other->Message_StringID(13, TRADE_HAS_BEEN_CANCELLED);
this->FinishTrade(this);
other->FinishTrade(other);
other->trade->Reset();
trade->Reset();
Message(15, "Hacking activity detected in trade transaction.");
// TODO: query (this) as a hacker
}
else if (other->CheckTradeNonDroppable()) {
Message_StringID(13, TRADE_HAS_BEEN_CANCELLED);
other->Message_StringID(13, TRADE_HAS_BEEN_CANCELLED);
this->FinishTrade(this);
other->FinishTrade(other);
other->trade->Reset();
trade->Reset();
other->Message(15, "Hacking activity detected in trade transaction.");
// TODO: query (other) as a hacker
}
else {
// Audit trade to database for both trade streams
other->trade->LogTrade();
@@ -13503,7 +13531,7 @@ void Client::Handle_OP_Trader(const EQApplicationPacket *app)
TradeItemsValid = false;
break;
}
const EQEmu::ItemBase *Item = database.GetItem(gis->Items[i]);
const EQEmu::ItemData *Item = database.GetItem(gis->Items[i]);
if (!Item) {
Message(13, "Unexpected error. Unable to start trader mode");
@@ -14024,6 +14052,10 @@ void Client::Handle_OP_WearChange(const EQApplicationPacket *app)
if (wc->spawn_id != GetID())
return;
// Hero Forge ID needs to be fixed here as RoF2 appears to send an incorrect value.
if (wc->hero_forge_model != 0 && wc->wear_slot_id >= 0 && wc->wear_slot_id < EQEmu::textures::weaponPrimary)
wc->hero_forge_model = GetHerosForgeModel(wc->wear_slot_id);
// we could maybe ignore this and just send our own from moveitem
entity_list.QueueClients(this, app, true);
return;
+38 -23
View File
@@ -296,7 +296,7 @@ bool Client::Process() {
}
if(AutoFireEnabled()){
ItemInst *ranged = GetInv().GetItem(EQEmu::legacy::SlotRange);
EQEmu::ItemInstance *ranged = GetInv().GetItem(EQEmu::inventory::slotRange);
if(ranged)
{
if (ranged->GetItem() && ranged->GetItem()->ItemType == EQEmu::item::ItemTypeBow){
@@ -391,10 +391,11 @@ bool Client::Process() {
}
else if (auto_attack_target->GetHP() > -10) // -10 so we can watch people bleed in PvP
{
ItemInst *wpn = GetInv().GetItem(EQEmu::legacy::SlotPrimary);
TryWeaponProc(wpn, auto_attack_target, EQEmu::legacy::SlotPrimary);
EQEmu::ItemInstance *wpn = GetInv().GetItem(EQEmu::inventory::slotPrimary);
TryWeaponProc(wpn, auto_attack_target, EQEmu::inventory::slotPrimary);
TriggerDefensiveProcs(auto_attack_target, EQEmu::inventory::slotPrimary, false);
DoAttackRounds(auto_attack_target, EQEmu::legacy::SlotPrimary);
DoAttackRounds(auto_attack_target, EQEmu::inventory::slotPrimary);
if (CheckAATimer(aaTimerRampage))
entity_list.AEAttack(this, 30);
}
@@ -430,10 +431,10 @@ bool Client::Process() {
else if(auto_attack_target->GetHP() > -10) {
CheckIncreaseSkill(EQEmu::skills::SkillDualWield, auto_attack_target, -10);
if (CheckDualWield()) {
ItemInst *wpn = GetInv().GetItem(EQEmu::legacy::SlotSecondary);
TryWeaponProc(wpn, auto_attack_target, EQEmu::legacy::SlotSecondary);
EQEmu::ItemInstance *wpn = GetInv().GetItem(EQEmu::inventory::slotSecondary);
TryWeaponProc(wpn, auto_attack_target, EQEmu::inventory::slotSecondary);
DoAttackRounds(auto_attack_target, EQEmu::legacy::SlotSecondary);
DoAttackRounds(auto_attack_target, EQEmu::inventory::slotSecondary);
}
}
}
@@ -738,7 +739,7 @@ void Client::BulkSendInventoryItems()
// LINKDEAD TRADE ITEMS
// Move trade slot items back into normal inventory..need them there now for the proceeding validity checks
for (int16 slot_id = EQEmu::legacy::TRADE_BEGIN; slot_id <= EQEmu::legacy::TRADE_END; slot_id++) {
ItemInst* inst = m_inv.PopItem(slot_id);
EQEmu::ItemInstance* inst = m_inv.PopItem(slot_id);
if(inst) {
bool is_arrow = (inst->GetItem()->ItemType == EQEmu::item::ItemTypeArrow) ? true : false;
int16 free_slot_id = m_inv.FindFreeSlot(inst->IsClassBag(), true, inst->GetItem()->Size, is_arrow);
@@ -763,8 +764,8 @@ void Client::BulkSendInventoryItems()
EQEmu::OutBuffer::pos_type last_pos = ob.tellp();
// Possessions items
for (int16 slot_id = SLOT_BEGIN; slot_id < EQEmu::legacy::TYPE_POSSESSIONS_SIZE; slot_id++) {
const ItemInst* inst = m_inv[slot_id];
for (int16 slot_id = EQEmu::inventory::slotBegin; slot_id < EQEmu::legacy::TYPE_POSSESSIONS_SIZE; slot_id++) {
const EQEmu::ItemInstance* inst = m_inv[slot_id];
if (!inst)
continue;
@@ -778,12 +779,12 @@ void Client::BulkSendInventoryItems()
// PowerSource item
if (ClientVersion() >= EQEmu::versions::ClientVersion::SoF) {
const ItemInst* inst = m_inv[EQEmu::legacy::SlotPowerSource];
const EQEmu::ItemInstance* inst = m_inv[EQEmu::inventory::slotPowerSource];
if (inst) {
inst->Serialize(ob, EQEmu::legacy::SlotPowerSource);
inst->Serialize(ob, EQEmu::inventory::slotPowerSource);
if (ob.tellp() == last_pos)
Log.Out(Logs::General, Logs::Inventory, "Serialization failed on item slot %d during BulkSendInventoryItems. Item skipped.", EQEmu::legacy::SlotPowerSource);
Log.Out(Logs::General, Logs::Inventory, "Serialization failed on item slot %d during BulkSendInventoryItems. Item skipped.", EQEmu::inventory::slotPowerSource);
last_pos = ob.tellp();
}
@@ -791,7 +792,7 @@ void Client::BulkSendInventoryItems()
// Bank items
for (int16 slot_id = EQEmu::legacy::BANK_BEGIN; slot_id <= EQEmu::legacy::BANK_END; slot_id++) {
const ItemInst* inst = m_inv[slot_id];
const EQEmu::ItemInstance* inst = m_inv[slot_id];
if (!inst)
continue;
@@ -805,7 +806,7 @@ void Client::BulkSendInventoryItems()
// SharedBank items
for (int16 slot_id = EQEmu::legacy::SHARED_BANK_BEGIN; slot_id <= EQEmu::legacy::SHARED_BANK_END; slot_id++) {
const ItemInst* inst = m_inv[slot_id];
const EQEmu::ItemInstance* inst = m_inv[slot_id];
if (!inst)
continue;
@@ -825,12 +826,12 @@ void Client::BulkSendInventoryItems()
}
void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
const EQEmu::ItemBase* handyitem = nullptr;
const EQEmu::ItemData* handyitem = nullptr;
uint32 numItemSlots = 80; //The max number of items passed in the transaction.
if (m_ClientVersionBit & EQEmu::versions::bit_RoFAndLater) { // RoF+ can send 200 items
numItemSlots = 200;
}
const EQEmu::ItemBase *item;
const EQEmu::ItemData *item;
std::list<MerchantList> merlist = zone->merchanttable[merchant_id];
std::list<MerchantList>::const_iterator itr;
Mob* merch = entity_list.GetMobByNpcTypeID(npcid);
@@ -857,7 +858,15 @@ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
continue;
int32 fac = merch ? merch->GetPrimaryFaction() : 0;
if (fac != 0 && GetModCharacterFactionLevel(fac) < ml.faction_required)
int32 cur_fac_level;
if (fac == 0 || sneaking) {
cur_fac_level = 0;
}
else {
cur_fac_level = GetModCharacterFactionLevel(fac);
}
if (cur_fac_level < ml.faction_required)
continue;
handychance = zone->random.Int(0, merlist.size() + tmp_merlist.size() - 1);
@@ -871,7 +880,7 @@ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
int charges = 1;
if (item->IsClassCommon())
charges = item->MaxCharges;
ItemInst* inst = database.CreateItem(item, charges);
EQEmu::ItemInstance* inst = database.CreateItem(item, charges);
if (inst) {
if (RuleB(Merchant, UsePriceMod)) {
inst->SetPrice((item->Price * (RuleR(Merchant, SellCostMod)) * item->SellRate * Client::CalcPriceMod(merch, false)));
@@ -912,7 +921,7 @@ void Client::BulkSendMerchantInventory(int merchant_id, int npcid) {
// charges=ml.charges;
//else
charges = item->MaxCharges;
ItemInst* inst = database.CreateItem(item, charges);
EQEmu::ItemInstance* inst = database.CreateItem(item, charges);
if (inst) {
if (RuleB(Merchant, UsePriceMod)) {
inst->SetPrice((item->Price * (RuleR(Merchant, SellCostMod)) * item->SellRate * Client::CalcPriceMod(merch, false)));
@@ -1087,11 +1096,11 @@ void Client::OPMemorizeSpell(const EQApplicationPacket* app)
switch(memspell->scribing)
{
case memSpellScribing: { // scribing spell to book
const ItemInst* inst = m_inv[EQEmu::legacy::SlotCursor];
const EQEmu::ItemInstance* inst = m_inv[EQEmu::inventory::slotCursor];
if (inst && inst->IsClassCommon())
{
const EQEmu::ItemBase* item = inst->GetItem();
const EQEmu::ItemData* item = inst->GetItem();
if (RuleB(Character, RestrictSpellScribing) && !item->IsEquipable(GetRace(), GetClass())) {
Message_StringID(13, CANNOT_USE_ITEM);
@@ -1101,7 +1110,7 @@ void Client::OPMemorizeSpell(const EQApplicationPacket* app)
if(item && item->Scroll.Effect == (int32)(memspell->spell_id))
{
ScribeSpell(memspell->spell_id, memspell->slot);
DeleteItemInInventory(EQEmu::legacy::SlotCursor, 1, true);
DeleteItemInInventory(EQEmu::inventory::slotCursor, 1, true);
}
else
Message(0,"Scribing spell: inst exists but item does not or spell ids do not match.");
@@ -1186,6 +1195,12 @@ void Client::OPMoveCoin(const EQApplicationPacket* app)
int32 *from_bucket = 0, *to_bucket = 0;
Mob* trader = trade->With();
// if amount < 0, client is sending a malicious packet
if (mc->amount < 0)
{
return;
}
// could just do a range, but this is clearer and explicit
if
(
+62 -57
View File
@@ -745,24 +745,15 @@ void command_wc(Client *c, const Seperator *sep)
uint32 hero_forge_model = 0;
uint32 wearslot = atoi(sep->arg[1]);
// Hero Forge
if (sep->argnum > 2)
{
hero_forge_model = atoi(sep->arg[3]);
if (hero_forge_model > 0)
{
// Conversion to simplify the command arguments
// Hero's Forge model is actually model * 1000 + texture * 100 + wearslot
hero_forge_model *= 1000;
hero_forge_model += (atoi(sep->arg[2]) * 100);
hero_forge_model += wearslot;
// For Hero's Forge, slot 7 is actually for Robes, but it still needs to use slot 1 in the packet
if (wearslot == 7)
{
wearslot = 1;
}
if (hero_forge_model != 0 && hero_forge_model < 1000) {
// Shorthand Hero Forge ID. Otherwise use the value the user entered.
hero_forge_model = (hero_forge_model * 100) + wearslot;
}
}
/*
// Leaving here to add color option to the #wc command eventually
@@ -1007,6 +998,7 @@ void command_summon(Client *c, const Seperator *sep)
szp->x_pos = c->GetX(); // May need to add a factor of 8 in here..
szp->y_pos = c->GetY();
szp->z_pos = c->GetZ();
szp->instance_id = zone->GetInstanceID();
worldserver.SendPacket(pack);
safe_delete(pack);
}
@@ -1470,16 +1462,29 @@ void command_npcstats(Client *c, const Seperator *sep)
else if (!c->GetTarget()->IsNPC())
c->Message(0, "ERROR: Target is not a NPC!");
else {
auto target_npc = c->GetTarget()->CastToNPC();
c->Message(0, "NPC Stats:");
c->Message(0, "Name: %s NpcID: %u", c->GetTarget()->GetName(), c->GetTarget()->GetNPCTypeID());
c->Message(0, "Race: %i Level: %i Class: %i Material: %i", c->GetTarget()->GetRace(), c->GetTarget()->GetLevel(), c->GetTarget()->GetClass(), c->GetTarget()->GetTexture());
c->Message(0, "Current HP: %i Max HP: %i", c->GetTarget()->GetHP(), c->GetTarget()->GetMaxHP());
//c->Message(0, "Weapon Item Number: %s", c->GetTarget()->GetWeapNo());
c->Message(0, "Gender: %i Size: %f Bodytype: %d", c->GetTarget()->GetGender(), c->GetTarget()->GetSize(), c->GetTarget()->GetBodyType());
c->Message(0, "Runspeed: %.3f Walkspeed: %.3f", static_cast<float>(0.025f * c->GetTarget()->GetRunspeed()), static_cast<float>(0.025f * c->GetTarget()->GetWalkspeed()));
c->Message(0, "Spawn Group: %i Grid: %i", c->GetTarget()->CastToNPC()->GetSp2(), c->GetTarget()->CastToNPC()->GetGrid());
c->Message(0, "EmoteID: %i", c->GetTarget()->CastToNPC()->GetEmoteID());
c->GetTarget()->CastToNPC()->QueryLoot(c);
c->Message(0, "Name: %s NpcID: %u", target_npc->GetName(), target_npc->GetNPCTypeID());
c->Message(0, "Race: %i Level: %i Class: %i Material: %i", target_npc->GetRace(), target_npc->GetLevel(), target_npc->GetClass(), target_npc->GetTexture());
c->Message(0, "Current HP: %i Max HP: %i", target_npc->GetHP(), target_npc->GetMaxHP());
//c->Message(0, "Weapon Item Number: %s", target_npc->GetWeapNo());
c->Message(0, "Gender: %i Size: %f Bodytype: %d", target_npc->GetGender(), target_npc->GetSize(), target_npc->GetBodyType());
c->Message(0, "Runspeed: %.3f Walkspeed: %.3f", static_cast<float>(0.025f * target_npc->GetRunspeed()), static_cast<float>(0.025f * target_npc->GetWalkspeed()));
c->Message(0, "Spawn Group: %i Grid: %i", target_npc->GetSp2(), target_npc->GetGrid());
if (target_npc->proximity) {
c->Message(0, "Proximity: Enabled");
c->Message(0, "Cur_X: %1.3f, Cur_Y: %1.3f, Cur_Z: %1.3f", target_npc->GetX(), target_npc->GetY(), target_npc->GetZ());
c->Message(0, "Min_X: %1.3f(%1.3f), Max_X: %1.3f(%1.3f), X_Range: %1.3f", target_npc->proximity->min_x, (target_npc->proximity->min_x - target_npc->GetX()), target_npc->proximity->max_x, (target_npc->proximity->max_x - target_npc->GetX()), (target_npc->proximity->max_x - target_npc->proximity->min_x));
c->Message(0, "Min_Y: %1.3f(%1.3f), Max_Y: %1.3f(%1.3f), Y_Range: %1.3f", target_npc->proximity->min_y, (target_npc->proximity->min_y - target_npc->GetY()), target_npc->proximity->max_y, (target_npc->proximity->max_y - target_npc->GetY()), (target_npc->proximity->max_y - target_npc->proximity->min_y));
c->Message(0, "Min_Z: %1.3f(%1.3f), Max_Z: %1.3f(%1.3f), Z_Range: %1.3f", target_npc->proximity->min_z, (target_npc->proximity->min_z - target_npc->GetZ()), target_npc->proximity->max_z, (target_npc->proximity->max_z - target_npc->GetZ()), (target_npc->proximity->max_z - target_npc->proximity->min_z));
c->Message(0, "Say: %s", (target_npc->proximity->say ? "Enabled" : "Disabled"));
}
else {
c->Message(0, "Proximity: Disabled");
}
c->Message(0, "");
c->Message(0, "EmoteID: %i", target_npc->GetEmoteID());
target_npc->QueryLoot(c);
}
}
@@ -2416,14 +2421,14 @@ void command_texture(Client *c, const Seperator *sep)
// Player Races Wear Armor, so Wearchange is sent instead
int i;
if (!c->GetTarget())
for (i = EQEmu::textures::TextureBegin; i <= EQEmu::textures::LastTintableTexture; i++)
for (i = EQEmu::textures::textureBegin; i <= EQEmu::textures::LastTintableTexture; i++)
{
c->SendTextureWC(i, texture);
}
else if ((c->GetTarget()->GetRace() > 0 && c->GetTarget()->GetRace() <= 12) ||
c->GetTarget()->GetRace() == 128 || c->GetTarget()->GetRace() == 130 ||
c->GetTarget()->GetRace() == 330 || c->GetTarget()->GetRace() == 522) {
for (i = EQEmu::textures::TextureBegin; i <= EQEmu::textures::LastTintableTexture; i++)
for (i = EQEmu::textures::textureBegin; i <= EQEmu::textures::LastTintableTexture; i++)
{
c->GetTarget()->SendTextureWC(i, texture);
}
@@ -2544,9 +2549,9 @@ void command_peekinv(Client *c, const Seperator *sep)
}
Client* targetClient = c->GetTarget()->CastToClient();
const ItemInst* inst_main = nullptr;
const ItemInst* inst_sub = nullptr;
const EQEmu::ItemBase* item_data = nullptr;
const EQEmu::ItemInstance* inst_main = nullptr;
const EQEmu::ItemInstance* inst_sub = nullptr;
const EQEmu::ItemData* item_data = nullptr;
std::string item_link;
EQEmu::SayLinkEngine linker;
linker.SetLinkType(EQEmu::saylink::SayLinkItemInst);
@@ -2566,14 +2571,14 @@ void command_peekinv(Client *c, const Seperator *sep)
}
if ((scopeWhere & peekWorn) && (targetClient->ClientVersion() >= EQEmu::versions::ClientVersion::SoF)) {
inst_main = targetClient->GetInv().GetItem(EQEmu::legacy::SlotPowerSource);
inst_main = targetClient->GetInv().GetItem(EQEmu::inventory::slotPowerSource);
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
linker.SetItemInst(inst_main);
item_link = linker.GenerateLink();
c->Message((item_data == nullptr), "WornSlot: %i, Item: %i (%s), Charges: %i",
EQEmu::legacy::SlotPowerSource, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
EQEmu::inventory::slotPowerSource, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
}
// inv
@@ -2587,7 +2592,7 @@ void command_peekinv(Client *c, const Seperator *sep)
c->Message((item_data == nullptr), "InvSlot: %i, Item: %i (%s), Charges: %i",
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
for (uint8 indexSub = SUB_INDEX_BEGIN; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::legacy::ITEM_CONTAINER_SIZE); ++indexSub) {
for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
inst_sub = inst_main->GetItem(indexSub);
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
linker.SetItemInst(inst_sub);
@@ -2595,7 +2600,7 @@ void command_peekinv(Client *c, const Seperator *sep)
item_link = linker.GenerateLink();
c->Message((item_data == nullptr), " InvBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
EQEmu::InventoryProfile::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
}
}
@@ -2607,7 +2612,7 @@ void command_peekinv(Client *c, const Seperator *sep)
item_link = linker.GenerateLink();
c->Message(1, "CursorSlot: %i, Item: %i (%s), Charges: %i",
EQEmu::legacy::SlotCursor, 0, item_link.c_str(), 0);
EQEmu::inventory::slotCursor, 0, item_link.c_str(), 0);
}
else {
int cursorDepth = 0;
@@ -2619,9 +2624,9 @@ void command_peekinv(Client *c, const Seperator *sep)
item_link = linker.GenerateLink();
c->Message((item_data == nullptr), "CursorSlot: %i, Depth: %i, Item: %i (%s), Charges: %i",
EQEmu::legacy::SlotCursor, cursorDepth, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
EQEmu::inventory::slotCursor, cursorDepth, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
for (uint8 indexSub = SUB_INDEX_BEGIN; (cursorDepth == 0) && inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::legacy::ITEM_CONTAINER_SIZE); ++indexSub) {
for (uint8 indexSub = EQEmu::inventory::containerBegin; (cursorDepth == 0) && inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
inst_sub = inst_main->GetItem(indexSub);
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
linker.SetItemInst(inst_sub);
@@ -2629,7 +2634,7 @@ void command_peekinv(Client *c, const Seperator *sep)
item_link = linker.GenerateLink();
c->Message((item_data == nullptr), " CursorBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
Inventory::CalcSlotId(EQEmu::legacy::SlotCursor, indexSub), EQEmu::legacy::SlotCursor, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
EQEmu::InventoryProfile::CalcSlotId(EQEmu::inventory::slotCursor, indexSub), EQEmu::inventory::slotCursor, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
}
}
}
@@ -2658,7 +2663,7 @@ void command_peekinv(Client *c, const Seperator *sep)
c->Message((item_data == nullptr), "BankSlot: %i, Item: %i (%s), Charges: %i",
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
for (uint8 indexSub = SUB_INDEX_BEGIN; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::legacy::ITEM_CONTAINER_SIZE); ++indexSub) {
for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
inst_sub = inst_main->GetItem(indexSub);
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
linker.SetItemInst(inst_sub);
@@ -2666,7 +2671,7 @@ void command_peekinv(Client *c, const Seperator *sep)
item_link = linker.GenerateLink();
c->Message((item_data == nullptr), " BankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
EQEmu::InventoryProfile::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
}
}
@@ -2680,7 +2685,7 @@ void command_peekinv(Client *c, const Seperator *sep)
c->Message((item_data == nullptr), "SharedBankSlot: %i, Item: %i (%s), Charges: %i",
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
for (uint8 indexSub = SUB_INDEX_BEGIN; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::legacy::ITEM_CONTAINER_SIZE); ++indexSub) {
for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
inst_sub = inst_main->GetItem(indexSub);
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
linker.SetItemInst(inst_sub);
@@ -2688,7 +2693,7 @@ void command_peekinv(Client *c, const Seperator *sep)
item_link = linker.GenerateLink();
c->Message((item_data == nullptr), " SharedBankBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
EQEmu::InventoryProfile::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
}
}
@@ -2703,7 +2708,7 @@ void command_peekinv(Client *c, const Seperator *sep)
c->Message((item_data == nullptr), "TradeSlot: %i, Item: %i (%s), Charges: %i",
indexMain, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
for (uint8 indexSub = SUB_INDEX_BEGIN; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::legacy::ITEM_CONTAINER_SIZE); ++indexSub) {
for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsClassBag() && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
inst_sub = inst_main->GetItem(indexSub);
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
linker.SetItemInst(inst_sub);
@@ -2711,7 +2716,7 @@ void command_peekinv(Client *c, const Seperator *sep)
item_link = linker.GenerateLink();
c->Message((item_data == nullptr), " TradeBagSlot: %i (Slot #%i, Bag #%i), Item: %i (%s), Charges: %i",
Inventory::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
EQEmu::InventoryProfile::CalcSlotId(indexMain, indexSub), indexMain, indexSub, ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_sub == nullptr) ? 0 : inst_sub->GetCharges()));
}
}
@@ -2725,7 +2730,7 @@ void command_peekinv(Client *c, const Seperator *sep)
else {
c->Message(0, "[WorldObject DBID: %i (entityid: %i)]", objectTradeskill->GetDBID(), objectTradeskill->GetID());
for (int16 indexMain = SLOT_BEGIN; indexMain < EQEmu::legacy::TYPE_WORLD_SIZE; ++indexMain) {
for (int16 indexMain = EQEmu::inventory::slotBegin; indexMain < EQEmu::legacy::TYPE_WORLD_SIZE; ++indexMain) {
inst_main = objectTradeskill->GetItem(indexMain);
item_data = (inst_main == nullptr) ? nullptr : inst_main->GetItem();
linker.SetItemInst(inst_main);
@@ -2735,7 +2740,7 @@ void command_peekinv(Client *c, const Seperator *sep)
c->Message((item_data == nullptr), "WorldSlot: %i, Item: %i (%s), Charges: %i",
(EQEmu::legacy::WORLD_BEGIN + indexMain), ((item_data == nullptr) ? 0 : item_data->ID), item_link.c_str(), ((inst_main == nullptr) ? 0 : inst_main->GetCharges()));
for (uint8 indexSub = SUB_INDEX_BEGIN; inst_main && inst_main->IsType(EQEmu::item::ItemClassBag) && (indexSub < EQEmu::legacy::ITEM_CONTAINER_SIZE); ++indexSub) {
for (uint8 indexSub = EQEmu::inventory::containerBegin; inst_main && inst_main->IsType(EQEmu::item::ItemClassBag) && (indexSub < EQEmu::inventory::ContainerCount); ++indexSub) {
inst_sub = inst_main->GetItem(indexSub);
item_data = (inst_sub == nullptr) ? nullptr : inst_sub->GetItem();
linker.SetItemInst(inst_sub);
@@ -2779,7 +2784,7 @@ void command_interrogateinv(Client *c, const Seperator *sep)
}
Client* target = nullptr;
std::map<int16, const ItemInst*> instmap;
std::map<int16, const EQEmu::ItemInstance*> instmap;
bool log = false;
bool silent = false;
bool error = false;
@@ -3144,16 +3149,16 @@ void command_listpetition(Client *c, const Seperator *sep)
void command_equipitem(Client *c, const Seperator *sep)
{
uint32 slot_id = atoi(sep->arg[1]);
if (sep->IsNumber(1) && ((slot_id >= EQEmu::legacy::EQUIPMENT_BEGIN) && (slot_id <= EQEmu::legacy::EQUIPMENT_END) || (slot_id == EQEmu::legacy::SlotPowerSource))) {
const ItemInst* from_inst = c->GetInv().GetItem(EQEmu::legacy::SlotCursor);
const ItemInst* to_inst = c->GetInv().GetItem(slot_id); // added (desync issue when forcing stack to stack)
if (sep->IsNumber(1) && ((slot_id >= EQEmu::legacy::EQUIPMENT_BEGIN) && (slot_id <= EQEmu::legacy::EQUIPMENT_END) || (slot_id == EQEmu::inventory::slotPowerSource))) {
const EQEmu::ItemInstance* from_inst = c->GetInv().GetItem(EQEmu::inventory::slotCursor);
const EQEmu::ItemInstance* to_inst = c->GetInv().GetItem(slot_id); // added (desync issue when forcing stack to stack)
bool partialmove = false;
int16 movecount;
if (from_inst && from_inst->IsClassCommon()) {
auto outapp = new EQApplicationPacket(OP_MoveItem, sizeof(MoveItem_Struct));
MoveItem_Struct* mi = (MoveItem_Struct*)outapp->pBuffer;
mi->from_slot = EQEmu::legacy::SlotCursor;
mi->from_slot = EQEmu::inventory::slotCursor;
mi->to_slot = slot_id;
// mi->number_in_stack = from_inst->GetCharges(); // replaced with con check for stacking
@@ -4338,7 +4343,7 @@ void command_goto(Client *c, const Seperator *sep)
void command_iteminfo(Client *c, const Seperator *sep)
{
auto inst = c->GetInv()[EQEmu::legacy::SlotCursor];
auto inst = c->GetInv()[EQEmu::inventory::slotCursor];
if (!inst) {
c->Message(13, "Error: You need an item on your cursor for this command");
return;
@@ -5518,7 +5523,7 @@ void command_summonitem(Client *c, const Seperator *sep)
}
int16 item_status = 0;
const EQEmu::ItemBase* item = database.GetItem(itemid);
const EQEmu::ItemData* item = database.GetItem(itemid);
if (item) {
item_status = static_cast<int16>(item->MinStatus);
}
@@ -5557,7 +5562,7 @@ void command_giveitem(Client *c, const Seperator *sep)
Client *t = c->GetTarget()->CastToClient();
uint32 itemid = atoi(sep->arg[1]);
int16 item_status = 0;
const EQEmu::ItemBase* item = database.GetItem(itemid);
const EQEmu::ItemData* item = database.GetItem(itemid);
if(item) {
item_status = static_cast<int16>(item->MinStatus);
}
@@ -5610,7 +5615,7 @@ void command_itemsearch(Client *c, const Seperator *sep)
{
const char *search_criteria=sep->argplus[1];
const EQEmu::ItemBase* item = nullptr;
const EQEmu::ItemData* item = nullptr;
std::string item_link;
EQEmu::SayLinkEngine linker;
linker.SetLinkType(EQEmu::saylink::SayLinkItemData);
@@ -7123,9 +7128,9 @@ void command_path(Client *c, const Seperator *sep)
}
void Client::Undye() {
for (int cur_slot = EQEmu::textures::TextureBegin; cur_slot <= EQEmu::textures::LastTexture; cur_slot++) {
for (int cur_slot = EQEmu::textures::textureBegin; cur_slot <= EQEmu::textures::LastTexture; cur_slot++) {
uint8 slot2=SlotConvert(cur_slot);
ItemInst* inst = m_inv.GetItem(slot2);
EQEmu::ItemInstance* inst = m_inv.GetItem(slot2);
if(inst != nullptr) {
inst->SetColor(inst->GetItem()->Color);
@@ -10234,7 +10239,7 @@ void command_zopp(Client *c, const Seperator *sep)
uint32 itemid = atoi(sep->arg[3]);
int16 charges = sep->argnum == 4 ? atoi(sep->arg[4]) : 1; // defaults to 1 charge if not specified
const EQEmu::ItemBase* FakeItem = database.GetItem(itemid);
const EQEmu::ItemData* FakeItem = database.GetItem(itemid);
if (!FakeItem) {
c->Message(13, "Error: Item [%u] is not a valid item id.", itemid);
@@ -10242,7 +10247,7 @@ void command_zopp(Client *c, const Seperator *sep)
}
int16 item_status = 0;
const EQEmu::ItemBase* item = database.GetItem(itemid);
const EQEmu::ItemData* item = database.GetItem(itemid);
if(item) {
item_status = static_cast<int16>(item->MinStatus);
}
@@ -10256,7 +10261,7 @@ void command_zopp(Client *c, const Seperator *sep)
c->Message(0, "Processing request..results may cause unpredictable behavior.");
}
ItemInst* FakeItemInst = database.CreateItem(FakeItem, charges);
EQEmu::ItemInstance* FakeItemInst = database.CreateItem(FakeItem, charges);
c->SendItemPacket(slotid, FakeItemInst, packettype);
c->Message(0, "Sending zephyr op packet to client - [%s] %s (%u) with %i %s to slot %i.",
packettype == ItemPacketTrade ? "Trade" : "Summon", FakeItem->Name, itemid, charges,
+7 -4
View File
@@ -457,8 +457,7 @@ struct StatBonuses {
int32 ItemATKCap; // Raise item attack cap
int32 FinishingBlow[2]; // Chance to do a finishing blow for specified damage amount.
uint32 FinishingBlowLvl[2]; // Sets max level an NPC can be affected by FB. (base1 = lv, base2= ???)
int32 ShieldEquipHateMod; // Hate mod when shield equiped.
int32 ShieldEquipDmgMod[2]; // Damage mod when shield equiped. 0 = damage modifier 1 = Unknown
int32 ShieldEquipDmgMod; // Increases weapon's base damage by base1 % when shield is equipped (indirectly increasing hate)
bool TriggerOnValueAmount; // Triggers off various different conditions, bool to check if client has effect.
int8 StunBashChance; // chance to stun with bash.
int8 IncreaseChanceMemwipe; // increases chance to memory wipe
@@ -568,7 +567,11 @@ struct MercData {
uint32 NPCID;
};
class ItemInst;
namespace EQEmu
{
class ItemInstance;
}
class Mob;
// All data associated with a single trade
class Trade
@@ -606,7 +609,7 @@ public:
private:
// Send item data for trade item to other person involved in trade
void SendItemData(const ItemInst* inst, int16 dest_slot_id);
void SendItemData(const EQEmu::ItemInstance* inst, int16 dest_slot_id);
uint32 with_id;
Mob* owner;
+121 -97
View File
@@ -36,7 +36,6 @@ Child of the Mob class.
#include "../common/string_util.h"
#include "../common/say_link.h"
#include "client.h"
#include "corpse.h"
#include "entity.h"
#include "groups.h"
@@ -268,7 +267,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
int i;
PlayerProfile_Struct *pp = &client->GetPP();
ItemInst *item;
EQEmu::ItemInstance *item;
/* Check if Zone has Graveyard First */
if(!zone->HasGraveyard()) {
@@ -323,12 +322,12 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
// to go into the regular slots on the player, out of bags
std::list<uint32> removed_list;
for (i = SLOT_BEGIN; i < EQEmu::legacy::TYPE_POSSESSIONS_SIZE; ++i) {
if (i == EQEmu::legacy::SlotAmmo && client->ClientVersion() >= EQEmu::versions::ClientVersion::SoF) {
item = client->GetInv().GetItem(EQEmu::legacy::SlotPowerSource);
for (i = EQEmu::inventory::slotBegin; i < EQEmu::legacy::TYPE_POSSESSIONS_SIZE; ++i) {
if (i == EQEmu::inventory::slotAmmo && client->ClientVersion() >= EQEmu::versions::ClientVersion::SoF) {
item = client->GetInv().GetItem(EQEmu::inventory::slotPowerSource);
if (item != nullptr) {
if (!client->IsBecomeNPC() || (client->IsBecomeNPC() && !item->GetItem()->NoRent))
MoveItemToCorpse(client, item, EQEmu::legacy::SlotPowerSource, removed_list);
MoveItemToCorpse(client, item, EQEmu::inventory::slotPowerSource, removed_list);
}
}
@@ -387,7 +386,7 @@ Corpse::Corpse(Client* client, int32 in_rezexp) : Mob (
Save();
}
void Corpse::MoveItemToCorpse(Client *client, ItemInst *inst, int16 equipSlot, std::list<uint32> &removedList)
void Corpse::MoveItemToCorpse(Client *client, EQEmu::ItemInstance *inst, int16 equipSlot, std::list<uint32> &removedList)
{
AddItem(
inst->GetItem()->ID,
@@ -405,10 +404,10 @@ void Corpse::MoveItemToCorpse(Client *client, ItemInst *inst, int16 equipSlot, s
while (true) {
if (!inst->IsClassBag()) { break; }
if (equipSlot < EQEmu::legacy::GENERAL_BEGIN || equipSlot > EQEmu::legacy::SlotCursor) { break; }
if (equipSlot < EQEmu::legacy::GENERAL_BEGIN || equipSlot > EQEmu::inventory::slotCursor) { break; }
for (auto sub_index = SUB_INDEX_BEGIN; sub_index < EQEmu::legacy::ITEM_CONTAINER_SIZE; ++sub_index) {
int16 real_bag_slot = Inventory::CalcSlotId(equipSlot, sub_index);
for (int16 sub_index = EQEmu::inventory::containerBegin; sub_index < EQEmu::inventory::ContainerCount; ++sub_index) {
int16 real_bag_slot = EQEmu::InventoryProfile::CalcSlotId(equipSlot, sub_index);
auto bag_inst = client->GetInv().GetItem(real_bag_slot);
if (bag_inst == nullptr) { continue; }
@@ -684,8 +683,8 @@ ServerLootItem_Struct* Corpse::GetItem(uint16 lootslot, ServerLootItem_Struct**
}
}
if (sitem && bag_item_data && Inventory::SupportsContainers(sitem->equip_slot)) {
int16 bagstart = Inventory::CalcSlotId(sitem->equip_slot, SUB_INDEX_BEGIN);
if (sitem && bag_item_data && EQEmu::InventoryProfile::SupportsContainers(sitem->equip_slot)) {
int16 bagstart = EQEmu::InventoryProfile::CalcSlotId(sitem->equip_slot, EQEmu::inventory::containerBegin);
cur = itemlist.begin();
end = itemlist.end();
@@ -739,8 +738,8 @@ void Corpse::RemoveItem(ServerLootItem_Struct* item_data)
is_corpse_changed = true;
itemlist.erase(iter);
uint8 material = Inventory::CalcMaterialFromSlot(sitem->equip_slot); // autos to unsigned char
if (material != EQEmu::textures::TextureInvalid)
uint8 material = EQEmu::InventoryProfile::CalcMaterialFromSlot(sitem->equip_slot); // autos to unsigned char
if (material != EQEmu::textures::materialInvalid)
SendWearChange(material);
UpdateEquipmentLight();
@@ -979,8 +978,8 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
safe_delete(outapp);
if(Loot_Request_Type == 5) {
int pkitem = GetPlayerKillItem();
const EQEmu::ItemBase* item = database.GetItem(pkitem);
ItemInst* inst = database.CreateItem(item, item->MaxCharges);
const EQEmu::ItemData* item = database.GetItem(pkitem);
EQEmu::ItemInstance* inst = database.CreateItem(item, item->MaxCharges);
if(inst) {
if (item->RecastDelay)
inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0);
@@ -994,12 +993,12 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
}
int i = 0;
const EQEmu::ItemBase* item = 0;
const EQEmu::ItemData* item = 0;
ItemList::iterator cur,end;
cur = itemlist.begin();
end = itemlist.end();
int corpselootlimit = EQEmu::inventory::Lookup(EQEmu::versions::ConvertClientVersionToInventoryVersion(client->ClientVersion()))->InventoryTypeSize[EQEmu::legacy::TypeCorpse];
int corpselootlimit = EQEmu::inventory::Lookup(EQEmu::versions::ConvertClientVersionToMobVersion(client->ClientVersion()))->InventoryTypeSize[EQEmu::inventory::typeCorpse];
for(; cur != end; ++cur) {
ServerLootItem_Struct* item_data = *cur;
@@ -1008,12 +1007,12 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
// Dont display the item if it's in a bag
// Added cursor queue slots to corpse item visibility list. Nothing else should be making it to corpse.
if (!IsPlayerCorpse() || item_data->equip_slot <= EQEmu::legacy::SlotCursor || item_data->equip_slot == EQEmu::legacy::SlotPowerSource || Loot_Request_Type >= 3 ||
if (!IsPlayerCorpse() || item_data->equip_slot <= EQEmu::inventory::slotCursor || item_data->equip_slot == EQEmu::inventory::slotPowerSource || Loot_Request_Type >= 3 ||
(item_data->equip_slot >= 8000 && item_data->equip_slot <= 8999)) {
if(i < corpselootlimit) {
item = database.GetItem(item_data->item_id);
if(client && item) {
ItemInst* inst = database.CreateItem(item, item_data->charges, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5, item_data->aug_6, item_data->attuned);
EQEmu::ItemInstance* inst = database.CreateItem(item, item_data->charges, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5, item_data->aug_6, item_data->attuned);
if(inst) {
if (item->RecastDelay)
inst->SetRecastTimestamp(timestamps.count(item->RecastType) ? timestamps.at(item->RecastType) : 0);
@@ -1063,77 +1062,86 @@ void Corpse::MakeLootRequestPackets(Client* client, const EQApplicationPacket* a
SendLootReqErrorPacket(client, LootResponse::LootAll);
}
void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
/* This gets sent no matter what as a sort of ACK */
client->QueuePacket(app);
void Corpse::LootItem(Client *client, const EQApplicationPacket *app)
{
auto lootitem = (LootingItem_Struct *)app->pBuffer;
if (!loot_cooldown_timer.Check()) {
client->QueuePacket(app);
SendEndLootErrorPacket(client);
//unlock corpse for others
if (this->being_looted_by = client->GetID()) {
being_looted_by = 0xFFFFFFFF;
}
// unlock corpse for others
if (IsBeingLootedBy(client))
ResetLooter();
return;
}
/* To prevent item loss for a player using 'Loot All' who doesn't have inventory space for all their items. */
if (RuleB(Character, CheckCursorEmptyWhenLooting) && !client->GetInv().CursorEmpty()) {
client->Message(13, "You may not loot an item while you have an item on your cursor.");
client->QueuePacket(app);
SendEndLootErrorPacket(client);
/* Unlock corpse for others */
if (this->being_looted_by = client->GetID()) {
being_looted_by = 0xFFFFFFFF;
}
if (IsBeingLootedBy(client))
ResetLooter();
return;
}
LootingItem_Struct* lootitem = (LootingItem_Struct*)app->pBuffer;
if (this->being_looted_by != client->GetID()) {
if (!IsBeingLootedBy(client)) {
client->Message(13, "Error: Corpse::LootItem: BeingLootedBy != client");
client->QueuePacket(app);
SendEndLootErrorPacket(client);
return;
}
if (IsPlayerCorpse() && !CanPlayerLoot(client->CharacterID()) && !become_npc && (char_id != client->CharacterID() && client->Admin() < 150)) {
if (IsPlayerCorpse() && !CanPlayerLoot(client->CharacterID()) && !become_npc &&
(char_id != client->CharacterID() && client->Admin() < 150)) {
client->Message(13, "Error: This is a player corpse and you dont own it.");
client->QueuePacket(app);
SendEndLootErrorPacket(client);
return;
}
if (is_locked && client->Admin() < 100) {
client->QueuePacket(app);
SendLootReqErrorPacket(client, LootResponse::SomeoneElse);
client->Message(13, "Error: Corpse locked by GM.");
return;
}
if (IsPlayerCorpse() && (char_id != client->CharacterID()) && CanPlayerLoot(client->CharacterID()) && GetPlayerKillItem() == 0){
if (IsPlayerCorpse() && (char_id != client->CharacterID()) && CanPlayerLoot(client->CharacterID()) &&
GetPlayerKillItem() == 0) {
client->Message(13, "Error: You cannot loot any more items from this corpse.");
client->QueuePacket(app);
SendEndLootErrorPacket(client);
being_looted_by = 0xFFFFFFFF;
ResetLooter();
return;
}
const EQEmu::ItemBase* item = 0;
ItemInst *inst = 0;
ServerLootItem_Struct* item_data = nullptr, *bag_item_data[10];
const EQEmu::ItemData *item = 0;
EQEmu::ItemInstance *inst = 0;
ServerLootItem_Struct *item_data = nullptr, *bag_item_data[10];
memset(bag_item_data, 0, sizeof(bag_item_data));
if (GetPlayerKillItem() > 1){
if (GetPlayerKillItem() > 1) {
item = database.GetItem(GetPlayerKillItem());
}
else if (GetPlayerKillItem() == -1 || GetPlayerKillItem() == 1){
item_data = GetItem(lootitem->slot_id - EQEmu::legacy::CORPSE_BEGIN); //dont allow them to loot entire bags of items as pvp reward
}
else{
} else if (GetPlayerKillItem() == -1 || GetPlayerKillItem() == 1) {
item_data =
GetItem(lootitem->slot_id -
EQEmu::legacy::CORPSE_BEGIN); // dont allow them to loot entire bags of items as pvp reward
} else {
item_data = GetItem(lootitem->slot_id - EQEmu::legacy::CORPSE_BEGIN, bag_item_data);
}
if (GetPlayerKillItem()<=1 && item_data != 0) {
if (GetPlayerKillItem() <= 1 && item_data != 0) {
item = database.GetItem(item_data->item_id);
}
if (item != 0) {
if (item_data){
inst = database.CreateItem(item, item_data ? item_data->charges : 0, item_data->aug_1, item_data->aug_2, item_data->aug_3, item_data->aug_4, item_data->aug_5, item_data->aug_6, item_data->attuned);
}
else {
if (item_data) {
inst = database.CreateItem(item, item_data ? item_data->charges : 0, item_data->aug_1,
item_data->aug_2, item_data->aug_3, item_data->aug_4,
item_data->aug_5, item_data->aug_6, item_data->attuned);
} else {
inst = database.CreateItem(item);
}
}
@@ -1141,20 +1149,22 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
if (client && inst) {
if (client->CheckLoreConflict(item)) {
client->Message_StringID(0, LOOT_LORE_ERROR);
client->QueuePacket(app);
SendEndLootErrorPacket(client);
being_looted_by = 0;
ResetLooter();
delete inst;
return;
}
if (inst->IsAugmented()) {
for (int i = AUG_INDEX_BEGIN; i < EQEmu::legacy::ITEM_COMMON_SIZE; i++) {
ItemInst *itm = inst->GetAugment(i);
for (int i = EQEmu::inventory::socketBegin; i < EQEmu::inventory::SocketCount; i++) {
EQEmu::ItemInstance *itm = inst->GetAugment(i);
if (itm) {
if (client->CheckLoreConflict(itm->GetItem())) {
client->Message_StringID(0, LOOT_LORE_ERROR);
client->QueuePacket(app);
SendEndLootErrorPacket(client);
being_looted_by = 0;
ResetLooter();
delete inst;
return;
}
@@ -1165,21 +1175,32 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
char buf[88];
char q_corpse_name[64];
strcpy(q_corpse_name, corpse_name);
snprintf(buf, 87, "%d %d %s", inst->GetItem()->ID, inst->GetCharges(), EntityList::RemoveNumbers(q_corpse_name));
snprintf(buf, 87, "%d %d %s", inst->GetItem()->ID, inst->GetCharges(),
EntityList::RemoveNumbers(q_corpse_name));
buf[87] = '\0';
std::vector<EQEmu::Any> args;
args.push_back(inst);
args.push_back(this);
parse->EventPlayer(EVENT_LOOT, client, buf, 0, &args);
if (parse->EventPlayer(EVENT_LOOT, client, buf, 0, &args) != 0) {
lootitem->auto_loot = -1;
client->Message_StringID(CC_Red, LOOT_NOT_ALLOWED, inst->GetItem()->Name);
client->QueuePacket(app);
delete inst;
return;
}
// do we want this to have a fail option too?
parse->EventItem(EVENT_LOOT, client, inst, this, buf, 0);
// safe to ACK now
client->QueuePacket(app);
if (!IsPlayerCorpse() && RuleB(Character, EnableDiscoveredItems)) {
if (client && !client->GetGM() && !client->IsDiscovered(inst->GetItem()->ID))
client->DiscoverItem(inst->GetItem()->ID);
}
if (zone->adv_data) {
ServerZoneAdventureDataReply_Struct *ad = (ServerZoneAdventureDataReply_Struct*)zone->adv_data;
ServerZoneAdventureDataReply_Struct *ad = (ServerZoneAdventureDataReply_Struct *)zone->adv_data;
if (ad->type == Adventure_Collect && !IsPlayerCorpse()) {
if (ad->data_id == inst->GetItem()->ID) {
zone->DoAdventureCountIncrease();
@@ -1188,12 +1209,11 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
}
/* First add it to the looter - this will do the bag contents too */
if (lootitem->auto_loot) {
if (lootitem->auto_loot > 0) {
if (!client->AutoPutLootInInventory(*inst, true, true, bag_item_data))
client->PutLootInInventory(EQEmu::legacy::SlotCursor, *inst, bag_item_data);
}
else {
client->PutLootInInventory(EQEmu::legacy::SlotCursor, *inst, bag_item_data);
client->PutLootInInventory(EQEmu::inventory::slotCursor, *inst, bag_item_data);
} else {
client->PutLootInInventory(EQEmu::inventory::slotCursor, *inst, bag_item_data);
}
/* Update any tasks that have an activity to loot this item */
@@ -1201,19 +1221,24 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
client->UpdateTasksForItem(ActivityLoot, item->ID);
/* Remove it from Corpse */
if (item_data){
/* Delete needs to be before RemoveItem because its deletes the pointer for item_data/bag_item_data */
database.DeleteItemOffCharacterCorpse(this->corpse_db_id, item_data->equip_slot, item_data->item_id);
if (item_data) {
/* Delete needs to be before RemoveItem because its deletes the pointer for
* item_data/bag_item_data */
database.DeleteItemOffCharacterCorpse(this->corpse_db_id, item_data->equip_slot,
item_data->item_id);
/* Delete Item Instance */
RemoveItem(item_data->lootslot);
}
/* Remove Bag Contents */
if (item->IsClassBag() && (GetPlayerKillItem() != -1 || GetPlayerKillItem() != 1)) {
for (int i = SUB_INDEX_BEGIN; i < EQEmu::legacy::ITEM_CONTAINER_SIZE; i++) {
for (int i = EQEmu::inventory::containerBegin; i < EQEmu::inventory::ContainerCount; i++) {
if (bag_item_data[i]) {
/* Delete needs to be before RemoveItem because its deletes the pointer for item_data/bag_item_data */
database.DeleteItemOffCharacterCorpse(this->corpse_db_id, bag_item_data[i]->equip_slot, bag_item_data[i]->item_id);
/* Delete needs to be before RemoveItem because its deletes the pointer for
* item_data/bag_item_data */
database.DeleteItemOffCharacterCorpse(this->corpse_db_id,
bag_item_data[i]->equip_slot,
bag_item_data[i]->item_id);
/* Delete Item Instance */
RemoveItem(bag_item_data[i]);
}
@@ -1224,38 +1249,37 @@ void Corpse::LootItem(Client* client, const EQApplicationPacket* app) {
SetPlayerKillItemID(0);
}
/* Send message with item link to groups and such */
EQEmu::SayLinkEngine linker;
linker.SetLinkType(EQEmu::saylink::SayLinkItemInst);
linker.SetItemInst(inst);
/* Send message with item link to groups and such */
EQEmu::SayLinkEngine linker;
linker.SetLinkType(EQEmu::saylink::SayLinkItemInst);
linker.SetItemInst(inst);
auto item_link = linker.GenerateLink();
auto item_link = linker.GenerateLink();
client->Message_StringID(MT_LootMessages, LOOTED_MESSAGE, item_link.c_str());
client->Message_StringID(MT_LootMessages, LOOTED_MESSAGE, item_link.c_str());
if (!IsPlayerCorpse()) {
if (!IsPlayerCorpse()) {
Group *g = client->GetGroup();
if(g != nullptr) {
g->GroupMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, client->GetName(), item_link.c_str());
}
else {
if (g != nullptr) {
g->GroupMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE,
client->GetName(), item_link.c_str());
} else {
Raid *r = client->GetRaid();
if(r != nullptr) {
r->RaidMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE, client->GetName(), item_link.c_str());
if (r != nullptr) {
r->RaidMessage_StringID(client, MT_LootMessages, OTHER_LOOTED_MESSAGE,
client->GetName(), item_link.c_str());
}
}
}
}
else {
} else {
SendEndLootErrorPacket(client);
safe_delete(inst);
return;
}
if (IsPlayerCorpse()){
if (IsPlayerCorpse()) {
client->SendItemLink(inst);
}
else{
} else {
client->SendItemLink(inst, true);
}
@@ -1294,7 +1318,7 @@ void Corpse::QueryLoot(Client* to) {
cur = itemlist.begin();
end = itemlist.end();
int corpselootlimit = EQEmu::inventory::Lookup(EQEmu::versions::ConvertClientVersionToInventoryVersion(to->ClientVersion()))->InventoryTypeSize[EQEmu::legacy::TypeCorpse];
int corpselootlimit = EQEmu::inventory::Lookup(EQEmu::versions::ConvertClientVersionToMobVersion(to->ClientVersion()))->InventoryTypeSize[EQEmu::inventory::typeCorpse];
for(; cur != end; ++cur) {
ServerLootItem_Struct* sitem = *cur;
@@ -1305,7 +1329,7 @@ void Corpse::QueryLoot(Client* to) {
else
x < corpselootlimit ? sitem->lootslot = x : sitem->lootslot = 0xFFFF;
const EQEmu::ItemBase* item = database.GetItem(sitem->item_id);
const EQEmu::ItemData* item = database.GetItem(sitem->item_id);
if (item)
to->Message((sitem->lootslot == 0xFFFF), "LootSlot: %i (EquipSlot: %i) Item: %s (%d), Count: %i", static_cast<int16>(sitem->lootslot), sitem->equip_slot, item->Name, item->ID, sitem->charges);
@@ -1319,7 +1343,7 @@ void Corpse::QueryLoot(Client* to) {
}
else {
sitem->lootslot=y;
const EQEmu::ItemBase* item = database.GetItem(sitem->item_id);
const EQEmu::ItemData* item = database.GetItem(sitem->item_id);
if (item)
to->Message(0, "LootSlot: %i Item: %s (%d), Count: %i", sitem->lootslot, item->Name, item->ID, sitem->charges);
@@ -1403,25 +1427,25 @@ uint32 Corpse::GetEquipment(uint8 material_slot) const {
int16 invslot;
if (material_slot > EQEmu::textures::LastTexture) {
return NO_ITEM;
return 0;
}
invslot = Inventory::CalcSlotFromMaterial(material_slot);
if(invslot == INVALID_INDEX) // GetWornItem() should be returning a NO_ITEM for any invalid index...
return NO_ITEM;
invslot = EQEmu::InventoryProfile::CalcSlotFromMaterial(material_slot);
if(invslot == INVALID_INDEX) // GetWornItem() should be returning a 0 for any invalid index...
return 0;
return GetWornItem(invslot);
}
uint32 Corpse::GetEquipmentColor(uint8 material_slot) const {
const EQEmu::ItemBase *item;
const EQEmu::ItemData *item;
if (material_slot > EQEmu::textures::LastTexture) {
return 0;
}
item = database.GetItem(GetEquipment(material_slot));
if(item != NO_ITEM) {
if(item != 0) {
return (item_tint.Slot[material_slot].UseTint ? item_tint.Slot[material_slot].Color : item->Color);
}
@@ -1434,8 +1458,8 @@ void Corpse::UpdateEquipmentLight()
m_Light.Level[EQEmu::lightsource::LightEquipment] = 0;
for (auto iter = itemlist.begin(); iter != itemlist.end(); ++iter) {
if (((*iter)->equip_slot < EQEmu::legacy::EQUIPMENT_BEGIN || (*iter)->equip_slot > EQEmu::legacy::EQUIPMENT_END) && (*iter)->equip_slot != EQEmu::legacy::SlotPowerSource) { continue; }
if ((*iter)->equip_slot == EQEmu::legacy::SlotAmmo) { continue; }
if (((*iter)->equip_slot < EQEmu::legacy::EQUIPMENT_BEGIN || (*iter)->equip_slot > EQEmu::legacy::EQUIPMENT_END) && (*iter)->equip_slot != EQEmu::inventory::slotPowerSource) { continue; }
if ((*iter)->equip_slot == EQEmu::inventory::slotAmmo) { continue; }
auto item = database.GetItem((*iter)->item_id);
if (item == nullptr) { continue; }
+9 -4
View File
@@ -20,17 +20,21 @@
#define CORPSE_H
#include "mob.h"
#include "client.h"
class Client;
class EQApplicationPacket;
class Group;
class ItemInst;
class NPC;
class Raid;
struct ExtraAttackOptions;
struct NPCType;
namespace EQEmu
{
class ItemInstance;
}
#define MAX_LOOTERS 72
class Corpse : public Mob {
@@ -49,7 +53,7 @@ class Corpse : public Mob {
/* Corpse: General */
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill) { return true; }
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, int special = 0) { return; }
virtual bool Attack(Mob* other, int Hand = EQEmu::legacy::SlotPrimary, bool FromRiposte = false, bool IsStrikethrough = true, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr, int special = 0) { return false; }
virtual bool Attack(Mob* other, int Hand = EQEmu::inventory::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = true, bool IsFromSpell = false, ExtraAttackOptions *opts = nullptr, int special = 0) { return false; }
virtual bool HasRaid() { return false; }
virtual bool HasGroup() { return false; }
virtual Raid* GetRaid() { return 0; }
@@ -114,6 +118,7 @@ class Corpse : public Mob {
inline bool IsLocked() { return is_locked; }
inline void ResetLooter() { being_looted_by = 0xFFFFFFFF; }
inline bool IsBeingLooted() { return (being_looted_by != 0xFFFFFFFF); }
inline bool IsBeingLootedBy(Client *c) { return being_looted_by == c->GetID(); }
/* Mob */
void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
@@ -128,7 +133,7 @@ class Corpse : public Mob {
virtual void UpdateEquipmentLight();
protected:
void MoveItemToCorpse(Client *client, ItemInst *inst, int16 equipSlot, std::list<uint32> &removedList);
void MoveItemToCorpse(Client *client, EQEmu::ItemInstance *inst, int16 equipSlot, std::list<uint32> &removedList);
private:
bool is_player_corpse; /* Determines if Player Corpse or not */
+1 -1
View File
@@ -188,7 +188,7 @@ void Doors::HandleClick(Client* sender, uint8 trigger)
uint8 keepoffkeyring = GetNoKeyring();
uint32 haskey = 0;
uint32 playerkey = 0;
const ItemInst *lockpicks = sender->GetInv().GetItem(EQEmu::legacy::SlotCursor);
const EQEmu::ItemInstance *lockpicks = sender->GetInv().GetItem(EQEmu::inventory::slotCursor);
haskey = sender->GetInv().HasItem(keyneeded, 1);
+23 -12
View File
@@ -481,7 +481,7 @@ int32 Client::GetActSpellCasttime(uint16 spell_id, int32 casttime)
bool Client::TrainDiscipline(uint32 itemid) {
//get the item info
const EQEmu::ItemBase *item = database.GetItem(itemid);
const EQEmu::ItemData *item = database.GetItem(itemid);
if(item == nullptr) {
Message(13, "Unable to find the tome you turned in!");
Log.Out(Logs::General, Logs::Error, "Unable to find turned in tome id %lu\n", (unsigned long)itemid);
@@ -630,17 +630,6 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) {
if(r == MAX_PP_DISCIPLINES)
return(false); //not found.
//Check the disc timer
pTimerType DiscTimer = pTimerDisciplineReuseStart + spells[spell_id].EndurTimerIndex;
if(!p_timers.Expired(&database, DiscTimer)) {
/*char val1[20]={0};*/ //unused
/*char val2[20]={0};*/ //unused
uint32 remain = p_timers.GetRemainingTime(DiscTimer);
//Message_StringID(0, DISCIPLINE_CANUSEIN, ConvertArray((remain)/60,val1), ConvertArray(remain%60,val2));
Message(0, "You can use this discipline in %d minutes %d seconds.", ((remain)/60), (remain%60));
return(false);
}
//make sure we can use it..
if(!IsValidSpell(spell_id)) {
Message(13, "This tome contains invalid knowledge.");
@@ -667,6 +656,23 @@ bool Client::UseDiscipline(uint32 spell_id, uint32 target) {
return(false);
}
// sneak attack discs require you to be hidden for 4 seconds before use
if (spell.sneak && (!hidden || (hidden && (Timer::GetCurrentTime() - tmHidden) < 4000))) {
Message_StringID(MT_SpellFailure, SNEAK_RESTRICT);
return false;
}
//Check the disc timer
pTimerType DiscTimer = pTimerDisciplineReuseStart + spell.EndurTimerIndex;
if(!p_timers.Expired(&database, DiscTimer)) {
/*char val1[20]={0};*/ //unused
/*char val2[20]={0};*/ //unused
uint32 remain = p_timers.GetRemainingTime(DiscTimer);
//Message_StringID(0, DISCIPLINE_CANUSEIN, ConvertArray((remain)/60,val1), ConvertArray(remain%60,val2));
Message(0, "You can use this discipline in %d minutes %d seconds.", ((remain)/60), (remain%60));
return(false);
}
if(spell.recast_time > 0)
{
uint32 reduced_recast = spell.recast_time / 1000;
@@ -772,6 +778,11 @@ void EntityList::AESpell(Mob *caster, Mob *center, uint16 spell_id, bool affect_
continue;
if (spells[spell_id].targettype == ST_AreaNPCOnly && !curmob->IsNPC())
continue;
// check PC/NPC only flag 1 = PCs, 2 = NPCs
if (spells[spell_id].pcnpc_only_flag == 1 && !curmob->IsClient() && !curmob->IsMerc())
continue;
if (spells[spell_id].pcnpc_only_flag == 2 && (curmob->IsClient() || curmob->IsMerc()))
continue;
if (spells[spell_id].targettype == ST_Ring) {
dist_targ = DistanceSquared(static_cast<glm::vec3>(curmob->GetPosition()), caster->GetTargetRingLocation());
+28 -28
View File
@@ -157,7 +157,7 @@ void PerlembParser::ReloadQuests() {
spell_quest_status_.clear();
}
int PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob,
int PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, EQEmu::ItemInstance* item_inst, Mob* mob,
uint32 extradata, bool global, std::vector<EQEmu::Any> *extra_pointers)
{
if(!perl)
@@ -174,9 +174,9 @@ int PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * da
std::string package_name;
GetQuestTypes(isPlayerQuest, isGlobalPlayerQuest, isGlobalNPC, isItemQuest, isSpellQuest,
event, npcmob, iteminst, mob, global);
event, npcmob, item_inst, mob, global);
GetQuestPackageName(isPlayerQuest, isGlobalPlayerQuest, isGlobalNPC, isItemQuest, isSpellQuest,
package_name, event, objid, data, npcmob, iteminst, global);
package_name, event, objid, data, npcmob, item_inst, global);
const char *sub_name = QuestEventSubroutines[event];
if(!perl->SubExists(package_name.c_str(), sub_name)) {
@@ -208,14 +208,14 @@ int PerlembParser::EventCommon(QuestEventID event, uint32 objid, const char * da
/* Check for Event export event enable */
if (parse->perl_event_export_settings[event].event_variables){
ExportEventVariables(package_name, event, objid, data, npcmob, iteminst, mob, extradata, extra_pointers);
ExportEventVariables(package_name, event, objid, data, npcmob, item_inst, mob, extradata, extra_pointers);
}
if(isPlayerQuest || isGlobalPlayerQuest){
return SendCommands(package_name.c_str(), sub_name, 0, mob, mob, nullptr);
}
else if(isItemQuest) {
return SendCommands(package_name.c_str(), sub_name, 0, mob, mob, iteminst);
return SendCommands(package_name.c_str(), sub_name, 0, mob, mob, item_inst);
}
else if(isSpellQuest){
if(mob) {
@@ -249,7 +249,7 @@ int PerlembParser::EventGlobalPlayer(QuestEventID evt, Client *client, std::stri
return EventCommon(evt, 0, data.c_str(), nullptr, nullptr, client, extra_data, true, extra_pointers);
}
int PerlembParser::EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
int PerlembParser::EventItem(QuestEventID evt, Client *client, EQEmu::ItemInstance *item, Mob *mob, std::string data, uint32 extra_data,
std::vector<EQEmu::Any> *extra_pointers) {
// needs pointer validation on 'item' argument
return EventCommon(evt, item->GetID(), nullptr, nullptr, item, client, extra_data, false, extra_pointers);
@@ -348,7 +348,7 @@ bool PerlembParser::SpellHasQuestSub(uint32 spell_id, QuestEventID evt) {
return(perl->SubExists(package_name.str().c_str(), subname));
}
bool PerlembParser::ItemHasQuestSub(ItemInst *itm, QuestEventID evt) {
bool PerlembParser::ItemHasQuestSub(EQEmu::ItemInstance *itm, QuestEventID evt) {
std::stringstream package_name;
package_name << "qst_item_" << itm->GetID();
@@ -471,7 +471,7 @@ void PerlembParser::LoadGlobalPlayerScript(std::string filename) {
global_player_quest_status_ = questLoaded;
}
void PerlembParser::LoadItemScript(std::string filename, ItemInst *item) {
void PerlembParser::LoadItemScript(std::string filename, EQEmu::ItemInstance *item) {
if (item == nullptr)
return;
@@ -642,13 +642,13 @@ void PerlembParser::ExportVar(const char *pkgprefix, const char *varname, const
}
}
int PerlembParser::SendCommands(const char *pkgprefix, const char *event, uint32 npcid, Mob* other, Mob* mob, ItemInst* iteminst) {
int PerlembParser::SendCommands(const char *pkgprefix, const char *event, uint32 npcid, Mob* other, Mob* mob, EQEmu::ItemInstance* item_inst) {
if(!perl)
return 0;
int ret_value = 0;
if(mob && mob->IsClient())
quest_manager.StartQuest(other, mob->CastToClient(), iteminst);
quest_manager.StartQuest(other, mob->CastToClient(), item_inst);
else
quest_manager.StartQuest(other, nullptr, nullptr);
@@ -711,8 +711,8 @@ int PerlembParser::SendCommands(const char *pkgprefix, const char *event, uint32
}
//only export QuestItem if it's an item quest
if(iteminst) {
ItemInst* curi = quest_manager.GetQuestItem();
if(item_inst) {
EQEmu::ItemInstance* curi = quest_manager.GetQuestItem();
snprintf(namebuf, 64, "%s::questitem", pkgprefix);
SV *questitem = get_sv(namebuf, true);
sv_setref_pv(questitem, "QuestItem", curi);
@@ -840,7 +840,7 @@ void PerlembParser::MapFunctions() {
}
void PerlembParser::GetQuestTypes(bool &isPlayerQuest, bool &isGlobalPlayerQuest, bool &isGlobalNPC, bool &isItemQuest,
bool &isSpellQuest, QuestEventID event, NPC* npcmob, ItemInst* iteminst, Mob* mob, bool global)
bool &isSpellQuest, QuestEventID event, NPC* npcmob, EQEmu::ItemInstance* item_inst, Mob* mob, bool global)
{
if(event == EVENT_SPELL_EFFECT_CLIENT ||
event == EVENT_SPELL_EFFECT_NPC ||
@@ -854,7 +854,7 @@ void PerlembParser::GetQuestTypes(bool &isPlayerQuest, bool &isGlobalPlayerQuest
else
{
if(!npcmob && mob) {
if(!iteminst) {
if(!item_inst) {
if(global) {
isGlobalPlayerQuest = true;
} else {
@@ -869,7 +869,7 @@ void PerlembParser::GetQuestTypes(bool &isPlayerQuest, bool &isGlobalPlayerQuest
void PerlembParser::GetQuestPackageName(bool &isPlayerQuest, bool &isGlobalPlayerQuest, bool &isGlobalNPC, bool &isItemQuest,
bool &isSpellQuest, std::string &package_name, QuestEventID event, uint32 objid, const char * data,
NPC* npcmob, ItemInst* iteminst, bool global)
NPC* npcmob, EQEmu::ItemInstance* item_inst, bool global)
{
if(!isPlayerQuest && !isGlobalPlayerQuest && !isItemQuest && !isSpellQuest) {
if(global) {
@@ -881,8 +881,8 @@ void PerlembParser::GetQuestPackageName(bool &isPlayerQuest, bool &isGlobalPlaye
}
}
else if(isItemQuest) {
// need a valid ItemInst pointer check here..unsure how to cancel this process
const EQEmu::ItemBase* item = iteminst->GetItem();
// need a valid EQEmu::ItemInstance pointer check here..unsure how to cancel this process
const EQEmu::ItemData* item = item_inst->GetItem();
package_name = "qst_item_";
package_name += itoa(item->ID);
}
@@ -1141,7 +1141,7 @@ void PerlembParser::ExportItemVariables(std::string &package_name, Mob *mob) {
#undef HASITEM_ISNULLITEM
void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID event, uint32 objid, const char * data,
NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata, std::vector<EQEmu::Any> *extra_pointers)
NPC* npcmob, EQEmu::ItemInstance* item_inst, Mob* mob, uint32 extradata, std::vector<EQEmu::Any> *extra_pointers)
{
switch (event) {
case EVENT_SAY: {
@@ -1159,7 +1159,7 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
if(extra_pointers) {
size_t sz = extra_pointers->size();
for(size_t i = 0; i < sz; ++i) {
ItemInst *inst = EQEmu::any_cast<ItemInst*>(extra_pointers->at(i));
EQEmu::ItemInstance *inst = EQEmu::any_cast<EQEmu::ItemInstance*>(extra_pointers->at(i));
std::string var_name = "item";
var_name += std::to_string(i + 1);
@@ -1327,19 +1327,19 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
case EVENT_SCALE_CALC:
case EVENT_ITEM_ENTER_ZONE: {
// need a valid ItemInst pointer check here..unsure how to cancel this process
// need a valid EQEmu::ItemInstance pointer check here..unsure how to cancel this process
ExportVar(package_name.c_str(), "itemid", objid);
ExportVar(package_name.c_str(), "itemname", iteminst->GetItem()->Name);
ExportVar(package_name.c_str(), "itemname", item_inst->GetItem()->Name);
break;
}
case EVENT_ITEM_CLICK_CAST:
case EVENT_ITEM_CLICK: {
// need a valid ItemInst pointer check here..unsure how to cancel this process
// need a valid EQEmu::ItemInstance pointer check here..unsure how to cancel this process
ExportVar(package_name.c_str(), "itemid", objid);
ExportVar(package_name.c_str(), "itemname", iteminst->GetItem()->Name);
ExportVar(package_name.c_str(), "itemname", item_inst->GetItem()->Name);
ExportVar(package_name.c_str(), "slotid", extradata);
ExportVar(package_name.c_str(), "spell_id", iteminst->GetItem()->Click.Effect);
ExportVar(package_name.c_str(), "spell_id", item_inst->GetItem()->Click.Effect);
break;
}
@@ -1419,10 +1419,10 @@ void PerlembParser::ExportEventVariables(std::string &package_name, QuestEventID
break;
}
case EVENT_DROP_ITEM: {
ExportVar(package_name.c_str(), "quantity", iteminst->IsStackable() ? iteminst->GetCharges() : 1);
ExportVar(package_name.c_str(), "itemname", iteminst->GetItem()->Name);
ExportVar(package_name.c_str(), "itemid", iteminst->GetItem()->ID);
ExportVar(package_name.c_str(), "spell_id", iteminst->GetItem()->Click.Effect);
ExportVar(package_name.c_str(), "quantity", item_inst->IsStackable() ? item_inst->GetCharges() : 1);
ExportVar(package_name.c_str(), "itemname", item_inst->GetItem()->Name);
ExportVar(package_name.c_str(), "itemid", item_inst->GetItem()->ID);
ExportVar(package_name.c_str(), "spell_id", item_inst->GetItem()->Click.Effect);
ExportVar(package_name.c_str(), "slotid", extradata);
break;
}
+14 -10
View File
@@ -17,7 +17,7 @@
*/
#ifndef EQEMU_EMBPARSER_H
#define EQMEU_EMBPARSER_H
#define EQEMU_EMBPARSER_H
#ifdef EMBPERL
#include "quest_parser_collection.h"
@@ -27,11 +27,15 @@
#include <map>
#include "embperl.h"
class ItemInst;
class Mob;
class Client;
class NPC;
namespace EQEmu
{
class ItemInstance;
}
typedef enum
{
questUnloaded,
@@ -52,7 +56,7 @@ public:
std::vector<EQEmu::Any> *extra_pointers);
virtual int EventGlobalPlayer(QuestEventID evt, Client *client, std::string data, uint32 extra_data,
std::vector<EQEmu::Any> *extra_pointers);
virtual int EventItem(QuestEventID evt, Client *client, ItemInst *item, Mob *mob, std::string data, uint32 extra_data,
virtual int EventItem(QuestEventID evt, Client *client, EQEmu::ItemInstance *item, Mob *mob, std::string data, uint32 extra_data,
std::vector<EQEmu::Any> *extra_pointers);
virtual int EventSpell(QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data,
std::vector<EQEmu::Any> *extra_pointers);
@@ -62,13 +66,13 @@ public:
virtual bool PlayerHasQuestSub(QuestEventID evt);
virtual bool GlobalPlayerHasQuestSub(QuestEventID evt);
virtual bool SpellHasQuestSub(uint32 spell_id, QuestEventID evt);
virtual bool ItemHasQuestSub(ItemInst *itm, QuestEventID evt);
virtual bool ItemHasQuestSub(EQEmu::ItemInstance *itm, QuestEventID evt);
virtual void LoadNPCScript(std::string filename, int npc_id);
virtual void LoadGlobalNPCScript(std::string filename);
virtual void LoadPlayerScript(std::string filename);
virtual void LoadGlobalPlayerScript(std::string filename);
virtual void LoadItemScript(std::string filename, ItemInst *item);
virtual void LoadItemScript(std::string filename, EQEmu::ItemInstance *item);
virtual void LoadSpellScript(std::string filename, uint32 spell_id);
virtual void AddVar(std::string name, std::string val);
@@ -86,16 +90,16 @@ private:
void ExportVar(const char *pkgprefix, const char *varname, float value);
void ExportVarComplex(const char *pkgprefix, const char *varname, const char *value);
int EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, ItemInst* iteminst, Mob* mob,
int EventCommon(QuestEventID event, uint32 objid, const char * data, NPC* npcmob, EQEmu::ItemInstance* item_inst, Mob* mob,
uint32 extradata, bool global, std::vector<EQEmu::Any> *extra_pointers);
int SendCommands(const char *pkgprefix, const char *event, uint32 npcid, Mob* other, Mob* mob, ItemInst *iteminst);
int SendCommands(const char *pkgprefix, const char *event, uint32 npcid, Mob* other, Mob* mob, EQEmu::ItemInstance *item_inst);
void MapFunctions();
void GetQuestTypes(bool &isPlayerQuest, bool &isGlobalPlayerQuest, bool &isGlobalNPC, bool &isItemQuest,
bool &isSpellQuest, QuestEventID event, NPC* npcmob, ItemInst* iteminst, Mob* mob, bool global);
bool &isSpellQuest, QuestEventID event, NPC* npcmob, EQEmu::ItemInstance* item_inst, Mob* mob, bool global);
void GetQuestPackageName(bool &isPlayerQuest, bool &isGlobalPlayerQuest, bool &isGlobalNPC, bool &isItemQuest,
bool &isSpellQuest, std::string &package_name, QuestEventID event, uint32 objid, const char * data,
NPC* npcmob, ItemInst* iteminst, bool global);
NPC* npcmob, EQEmu::ItemInstance* item_inst, bool global);
void ExportCharID(const std::string &package_name, int &char_id, NPC *npcmob, Mob *mob);
void ExportQGlobals(bool isPlayerQuest, bool isGlobalPlayerQuest, bool isGlobalNPC, bool isItemQuest,
bool isSpellQuest, std::string &package_name, NPC *npcmob, Mob *mob, int char_id);
@@ -104,7 +108,7 @@ private:
void ExportZoneVariables(std::string &package_name);
void ExportItemVariables(std::string &package_name, Mob *mob);
void ExportEventVariables(std::string &package_name, QuestEventID event, uint32 objid, const char * data,
NPC* npcmob, ItemInst* iteminst, Mob* mob, uint32 extradata, std::vector<EQEmu::Any> *extra_pointers);
NPC* npcmob, EQEmu::ItemInstance* item_inst, Mob* mob, uint32 extradata, std::vector<EQEmu::Any> *extra_pointers);
std::map<uint32, PerlQuestStatus> npc_quest_status_;
PerlQuestStatus global_npc_quest_status_;
+1 -1
View File
@@ -110,7 +110,7 @@ XS(XS_QuestItem_new)
if (items != 1)
Perl_croak(aTHX_ "Usage: QuestItem::new()");
ItemInst* RETVAL;
EQEmu::ItemInstance* RETVAL;
RETVAL = quest_manager.GetQuestItem();
ST(0) = sv_newmortal();
+2 -2
View File
@@ -247,8 +247,8 @@ void Embperl::init_eval_file(void)
" return;"
"} else {"
//we 'my' $filename,$mtime,$package,$sub to prevent them from changing our state up here.
" eval(\"package $package; my(\\$filename,\\$mtime,\\$package,\\$sub); \\$isloaded = 1; require '$filename'; \");"
/* "local *FH;open FH, $filename or die \"open '$filename' $!\";"
" eval(\"package $package; my(\\$filename,\\$mtime,\\$package,\\$sub); \\$isloaded = 1; require './$filename'; \");"
/* "local *FH;open FH, $filename or die \"open '$filename' $!\";"
"local($/) = undef;my $sub = <FH>;close FH;"
"my $eval = qq{package $package; sub handler { $sub; }};"
"{ my($filename,$mtime,$package,$sub); eval $eval; }"
+5 -1
View File
@@ -33,7 +33,7 @@
const char *getItemName(unsigned itemid)
{
const EQEmu::ItemBase* item = nullptr;
const EQEmu::ItemData* item = nullptr;
item = database.GetItem(itemid);
if (item)
@@ -99,6 +99,10 @@ XS(XS_EQEmuIO_PRINT)
/* Strip newlines from log message 'str' */
*std::remove(str, str + strlen(str), '\n') = '\0';
std::string log_string = str;
if (log_string.find("did not return a true") != std::string::npos)
return;
int i;
int pos = 0;
int len = 0;
+1 -1
View File
@@ -36,7 +36,7 @@ public:
//abstract virtual function implementations required by base abstract class
virtual bool Death(Mob* killerMob, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill) { return true; }
virtual void Damage(Mob* from, int32 damage, uint16 spell_id, EQEmu::skills::SkillType attack_skill, bool avoidable = true, int8 buffslot = -1, bool iBuffTic = false, int special = 0) { return; }
virtual bool Attack(Mob* other, int Hand = EQEmu::legacy::SlotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
virtual bool Attack(Mob* other, int Hand = EQEmu::inventory::slotPrimary, bool FromRiposte = false, bool IsStrikethrough = false, bool IsFromSpell = false,
ExtraAttackOptions *opts = nullptr, int special = 0) {
return false;
}
+12 -4
View File
@@ -2009,7 +2009,7 @@ void EntityList::QueueClientsGuildBankItemUpdate(const GuildBankItemUpdate_Struc
memcpy(outgbius, gbius, sizeof(GuildBankItemUpdate_Struct));
const EQEmu::ItemBase *Item = database.GetItem(gbius->ItemID);
const EQEmu::ItemData *Item = database.GetItem(gbius->ItemID);
auto it = client_list.begin();
while (it != client_list.end()) {
@@ -3878,11 +3878,11 @@ void EntityList::GroupMessage(uint32 gid, const char *from, const char *message)
uint16 EntityList::CreateGroundObject(uint32 itemid, const glm::vec4& position, uint32 decay_time)
{
const EQEmu::ItemBase *is = database.GetItem(itemid);
const EQEmu::ItemData *is = database.GetItem(itemid);
if (!is)
return 0;
auto i = new ItemInst(is, is->MaxCharges);
auto i = new EQEmu::ItemInstance(is, is->MaxCharges);
if (!i)
return 0;
@@ -4655,7 +4655,7 @@ Mob *EntityList::GetClosestMobByBodyType(Mob *sender, bodyType BodyType)
return ClosestMob;
}
void EntityList::GetTargetsForConeArea(Mob *start, float min_radius, float radius, float height, std::list<Mob*> &m_list)
void EntityList::GetTargetsForConeArea(Mob *start, float min_radius, float radius, float height, int pcnpc, std::list<Mob*> &m_list)
{
auto it = mob_list.begin();
while (it != mob_list.end()) {
@@ -4664,6 +4664,14 @@ void EntityList::GetTargetsForConeArea(Mob *start, float min_radius, float radiu
++it;
continue;
}
// check PC/NPC only flag 1 = PCs, 2 = NPCs
if (pcnpc == 1 && !ptr->IsClient() && !ptr->IsMerc()) {
++it;
continue;
} else if (pcnpc == 2 && (ptr->IsClient() || ptr->IsMerc())) {
++it;
continue;
}
float x_diff = ptr->GetX() - start->GetX();
float y_diff = ptr->GetY() - start->GetY();
float z_diff = ptr->GetZ() - start->GetZ();

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