diff options
-rw-r--r-- | sql/base/characters_database.sql | 4 | ||||
-rw-r--r-- | sql/updates/characters/master/2018_02_03_00_characters.sql | 3 | ||||
-rw-r--r-- | src/server/database/Database/Implementation/CharacterDatabase.cpp | 8 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateFieldFlags.cpp | 36 | ||||
-rw-r--r-- | src/server/game/Entities/Object/Updates/UpdateFields.h | 338 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 232 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 40 | ||||
-rw-r--r-- | src/server/game/Handlers/SpellHandler.cpp | 17 | ||||
-rw-r--r-- | src/server/game/Handlers/VoidStorageHandler.cpp | 3 | ||||
-rw-r--r-- | src/server/game/Server/Packets/SpellPackets.cpp | 5 | ||||
-rw-r--r-- | src/server/game/Server/Packets/SpellPackets.h | 4 | ||||
-rw-r--r-- | src/server/game/Server/WorldSession.h | 2 |
12 files changed, 382 insertions, 310 deletions
diff --git a/sql/base/characters_database.sql b/sql/base/characters_database.sql index 26e6da417c0..964dd61d6d0 100644 --- a/sql/base/characters_database.sql +++ b/sql/base/characters_database.sql @@ -1645,6 +1645,7 @@ CREATE TABLE `characters` ( `customDisplay1` tinyint(3) unsigned NOT NULL DEFAULT '0', `customDisplay2` tinyint(3) unsigned NOT NULL DEFAULT '0', `customDisplay3` tinyint(3) unsigned NOT NULL DEFAULT '0', + `inventorySlots` tinyint(3) unsigned NOT NULL DEFAULT '16', `bankSlots` tinyint(3) unsigned NOT NULL DEFAULT '0', `restState` tinyint(3) unsigned NOT NULL DEFAULT '0', `playerFlags` int(10) unsigned NOT NULL DEFAULT '0', @@ -3532,7 +3533,8 @@ INSERT INTO `updates` VALUES ('2017_06_04_00_characters.sql','BC80D2B7515CC6E01701070D2DA466727F36DB5E','ARCHIVED','2017-06-04 14:43:26',0), ('2017_08_20_00_characters.sql','8C5BBF6AEAA6C7DE2F40A7D3878C8187A4729F13','ARCHIVED','2017-08-20 17:00:00',0), ('2017_08_20_01_characters.sql','2F50D5E6BF3888B8C5270D79228A1D0601FAFF1D','ARCHIVED','2017-08-20 17:52:21',0), -('2017_10_29_00_characters.sql','8CFC473E7E87E58C317A72016BF69E9050D3BC83','ARCHIVED','2017-04-19 00:07:40',25); +('2017_10_29_00_characters.sql','8CFC473E7E87E58C317A72016BF69E9050D3BC83','ARCHIVED','2017-04-19 00:07:40',25), +('2018_02_03_00_characters.sql','73E9BFD848D7A22F2A7DD89CF64E30E3A8689512','RELEASED','2018-02-03 23:52:42', 0); /*!40000 ALTER TABLE `updates` ENABLE KEYS */; UNLOCK TABLES; diff --git a/sql/updates/characters/master/2018_02_03_00_characters.sql b/sql/updates/characters/master/2018_02_03_00_characters.sql new file mode 100644 index 00000000000..846a5978394 --- /dev/null +++ b/sql/updates/characters/master/2018_02_03_00_characters.sql @@ -0,0 +1,3 @@ +ALTER TABLE `characters` ADD `inventorySlots` tinyint(3) unsigned NOT NULL DEFAULT '16' AFTER `customDisplay3`; + +UPDATE `character_inventory` SET `slot`=`slot`+8 WHERE `slot`>=39 AND `bag`=0; diff --git a/src/server/database/Database/Implementation/CharacterDatabase.cpp b/src/server/database/Database/Implementation/CharacterDatabase.cpp index e639ffab506..ceeed6ac50f 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.cpp +++ b/src/server/database/Database/Implementation/CharacterDatabase.cpp @@ -79,7 +79,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_DEL_BATTLEGROUND_RANDOM, "DELETE FROM character_battleground_random WHERE guid = ?", CONNECTION_ASYNC); PrepareStatement(CHAR_INS_BATTLEGROUND_RANDOM, "INSERT INTO character_battleground_random (guid) VALUES (?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_SEL_CHARACTER, "SELECT c.guid, account, name, race, class, gender, level, xp, money, skin, face, hairStyle, hairColor, facialStyle, customDisplay1, customDisplay2, customDisplay3, bankSlots, restState, playerFlags, playerFlagsEx, " + PrepareStatement(CHAR_SEL_CHARACTER, "SELECT c.guid, account, name, race, class, gender, level, xp, money, skin, face, hairStyle, hairColor, facialStyle, customDisplay1, customDisplay2, customDisplay3, inventorySlots, bankSlots, restState, playerFlags, playerFlagsEx, " "position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, " "resettalents_time, primarySpecialization, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeonDifficulty, " "totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, " @@ -421,7 +421,7 @@ void CharacterDatabaseConnection::DoPrepareStatements() PrepareStatement(CHAR_DEL_LFG_DATA, "DELETE FROM lfg_data WHERE guid = ?", CONNECTION_ASYNC); // Player saving - PrepareStatement(CHAR_INS_CHARACTER, "INSERT INTO characters (guid, account, name, race, class, gender, level, xp, money, skin, face, hairStyle, hairColor, facialStyle, customDisplay1, customDisplay2, customDisplay3, bankSlots, restState, playerFlags, playerFlagsEx, " + PrepareStatement(CHAR_INS_CHARACTER, "INSERT INTO characters (guid, account, name, race, class, gender, level, xp, money, skin, face, hairStyle, hairColor, facialStyle, customDisplay1, customDisplay2, customDisplay3, inventorySlots, bankSlots, restState, playerFlags, playerFlagsEx, " "map, instance_id, dungeonDifficulty, raidDifficulty, legacyRaidDifficulty, position_x, position_y, position_z, orientation, trans_x, trans_y, trans_z, trans_o, transguid, " "taximask, cinematic, " "totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, resettalents_time, primarySpecialization, " @@ -429,8 +429,8 @@ void CharacterDatabaseConnection::DoPrepareStatements() "death_expire_time, taxi_path, totalKills, " "todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, health, power1, power2, power3, " "power4, power5, power6, latency, activeTalentGroup, lootSpecId, exploredZones, equipmentCache, knownTitles, actionBars, grantableLevels) VALUES " - "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC); - PrepareStatement(CHAR_UPD_CHARACTER, "UPDATE characters SET name=?,race=?,class=?,gender=?,level=?,xp=?,money=?,skin=?,face=?,hairStyle=?,hairColor=?,facialStyle=?,customDisplay1=?,customDisplay2=?,customDisplay3=?,bankSlots=?,restState=?,playerFlags=?,playerFlagsEx=?," + "(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", CONNECTION_ASYNC); + PrepareStatement(CHAR_UPD_CHARACTER, "UPDATE characters SET name=?,race=?,class=?,gender=?,level=?,xp=?,money=?,skin=?,face=?,hairStyle=?,hairColor=?,facialStyle=?,customDisplay1=?,customDisplay2=?,customDisplay3=?,inventorySlots=?,bankSlots=?,restState=?,playerFlags=?,playerFlagsEx=?," "map=?,instance_id=?,dungeonDifficulty=?,raidDifficulty=?,legacyRaidDifficulty=?,position_x=?,position_y=?,position_z=?,orientation=?,trans_x=?,trans_y=?,trans_z=?,trans_o=?,transguid=?,taximask=?,cinematic=?,totaltime=?,leveltime=?,rest_bonus=?," "logout_time=?,is_logout_resting=?,resettalents_cost=?,resettalents_time=?,primarySpecialization=?,extra_flags=?,stable_slots=?,at_login=?,zone=?,death_expire_time=?,taxi_path=?," "totalKills=?,todayKills=?,yesterdayKills=?,chosenTitle=?," diff --git a/src/server/game/Entities/Object/Updates/UpdateFieldFlags.cpp b/src/server/game/Entities/Object/Updates/UpdateFieldFlags.cpp index 1f2a7093d26..9a26e2a8c53 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFieldFlags.cpp +++ b/src/server/game/Entities/Object/Updates/UpdateFieldFlags.cpp @@ -348,6 +348,7 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] = UF_FLAG_PRIVATE | UF_FLAG_OWNER | UF_FLAG_UNIT_ALL, // UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER+5 UF_FLAG_PUBLIC, // UNIT_FIELD_LEVEL UF_FLAG_PUBLIC, // UNIT_FIELD_EFFECTIVE_LEVEL + UF_FLAG_PUBLIC, // UNIT_FIELD_SANDBOX_SCALING_ID UF_FLAG_PUBLIC, // UNIT_FIELD_SCALING_LEVEL_MIN UF_FLAG_PUBLIC, // UNIT_FIELD_SCALING_LEVEL_MAX UF_FLAG_PUBLIC, // UNIT_FIELD_SCALING_LEVEL_DELTA @@ -2095,6 +2096,38 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] = UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+745 UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+746 UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+747 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+748 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+749 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+750 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+751 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+752 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+753 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+754 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+755 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+756 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+757 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+758 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+759 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+760 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+761 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+762 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+763 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+764 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+765 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+766 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+767 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+768 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+769 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+770 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+771 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+772 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+773 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+774 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+775 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+776 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+777 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+778 + UF_FLAG_PRIVATE, // PLAYER_FIELD_INV_SLOT_HEAD+779 UF_FLAG_PRIVATE, // PLAYER_FARSIGHT UF_FLAG_PRIVATE, // PLAYER_FARSIGHT+1 UF_FLAG_PRIVATE, // PLAYER_FARSIGHT+2 @@ -2119,6 +2152,7 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] = UF_FLAG_PRIVATE, // PLAYER_FIELD_COINAGE+1 UF_FLAG_PRIVATE, // PLAYER_XP UF_FLAG_PRIVATE, // PLAYER_NEXT_LEVEL_XP + UF_FLAG_PRIVATE, // PLAYER_TRIAL_XP UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID+1 UF_FLAG_PRIVATE, // PLAYER_SKILL_LINEID+2 @@ -2958,7 +2992,6 @@ uint32 UnitUpdateFieldFlags[PLAYER_END] = UF_FLAG_PRIVATE, // PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE UF_FLAG_PRIVATE, // PLAYER_FIELD_LOCAL_FLAGS UF_FLAG_PRIVATE, // PLAYER_FIELD_BYTES - UF_FLAG_PRIVATE, // PLAYER_SELF_RES_SPELL UF_FLAG_PRIVATE, // PLAYER_FIELD_PVP_MEDALS UF_FLAG_PRIVATE, // PLAYER_FIELD_BUYBACK_PRICE_1 UF_FLAG_PRIVATE, // PLAYER_FIELD_BUYBACK_PRICE_1+1 @@ -4870,6 +4903,7 @@ uint32 UnitDynamicUpdateFieldFlags[PLAYER_DYNAMIC_END] = UF_FLAG_PRIVATE, // PLAYER_DYNAMIC_FIELD_TOYS UF_FLAG_PRIVATE, // PLAYER_DYNAMIC_FIELD_TRANSMOG UF_FLAG_PRIVATE, // PLAYER_DYNAMIC_FIELD_CONDITIONAL_TRANSMOG + UF_FLAG_PRIVATE, // PLAYER_DYNAMIC_FIELD_SELF_RES_SPELLS UF_FLAG_PRIVATE, // PLAYER_DYNAMIC_FIELD_CHARACTER_RESTRICTIONS UF_FLAG_PRIVATE, // PLAYER_DYNAMIC_FIELD_SPELL_PCT_MOD_BY_LABEL UF_FLAG_PRIVATE, // PLAYER_DYNAMIC_FIELD_SPELL_FLAT_MOD_BY_LABEL diff --git a/src/server/game/Entities/Object/Updates/UpdateFields.h b/src/server/game/Entities/Object/Updates/UpdateFields.h index fa1dff31f90..6fb0a5d952c 100644 --- a/src/server/game/Entities/Object/Updates/UpdateFields.h +++ b/src/server/game/Entities/Object/Updates/UpdateFields.h @@ -19,7 +19,7 @@ #ifndef _UPDATEFIELDS_H #define _UPDATEFIELDS_H -// Auto generated for version 7, 3, 2, 25383 +// Auto generated for version 7, 3, 5, 25928 enum ObjectFields { @@ -107,81 +107,82 @@ enum UnitFields UNIT_FIELD_POWER_REGEN_INTERRUPTED_FLAT_MODIFIER = OBJECT_END + 0x042, // Size: 6, Flags: PRIVATE, OWNER, UNIT_ALL UNIT_FIELD_LEVEL = OBJECT_END + 0x048, // Size: 1, Flags: PUBLIC UNIT_FIELD_EFFECTIVE_LEVEL = OBJECT_END + 0x049, // Size: 1, Flags: PUBLIC - UNIT_FIELD_SCALING_LEVEL_MIN = OBJECT_END + 0x04A, // Size: 1, Flags: PUBLIC - UNIT_FIELD_SCALING_LEVEL_MAX = OBJECT_END + 0x04B, // Size: 1, Flags: PUBLIC - UNIT_FIELD_SCALING_LEVEL_DELTA = OBJECT_END + 0x04C, // Size: 1, Flags: PUBLIC - UNIT_FIELD_FACTIONTEMPLATE = OBJECT_END + 0x04D, // Size: 1, Flags: PUBLIC - UNIT_VIRTUAL_ITEM_SLOT_ID = OBJECT_END + 0x04E, // Size: 6, Flags: PUBLIC - UNIT_FIELD_FLAGS = OBJECT_END + 0x054, // Size: 1, Flags: PUBLIC, URGENT - UNIT_FIELD_FLAGS_2 = OBJECT_END + 0x055, // Size: 1, Flags: PUBLIC, URGENT - UNIT_FIELD_FLAGS_3 = OBJECT_END + 0x056, // Size: 1, Flags: PUBLIC, URGENT - UNIT_FIELD_AURASTATE = OBJECT_END + 0x057, // Size: 1, Flags: PUBLIC - UNIT_FIELD_BASEATTACKTIME = OBJECT_END + 0x058, // Size: 2, Flags: PUBLIC - UNIT_FIELD_RANGEDATTACKTIME = OBJECT_END + 0x05A, // Size: 1, Flags: PRIVATE - UNIT_FIELD_BOUNDINGRADIUS = OBJECT_END + 0x05B, // Size: 1, Flags: PUBLIC - UNIT_FIELD_COMBATREACH = OBJECT_END + 0x05C, // Size: 1, Flags: PUBLIC - UNIT_FIELD_DISPLAYID = OBJECT_END + 0x05D, // Size: 1, Flags: DYNAMIC, URGENT - UNIT_FIELD_NATIVEDISPLAYID = OBJECT_END + 0x05E, // Size: 1, Flags: PUBLIC, URGENT - UNIT_FIELD_MOUNTDISPLAYID = OBJECT_END + 0x05F, // Size: 1, Flags: PUBLIC, URGENT - UNIT_FIELD_MINDAMAGE = OBJECT_END + 0x060, // Size: 1, Flags: PRIVATE, OWNER, SPECIAL_INFO - UNIT_FIELD_MAXDAMAGE = OBJECT_END + 0x061, // Size: 1, Flags: PRIVATE, OWNER, SPECIAL_INFO - UNIT_FIELD_MINOFFHANDDAMAGE = OBJECT_END + 0x062, // Size: 1, Flags: PRIVATE, OWNER, SPECIAL_INFO - UNIT_FIELD_MAXOFFHANDDAMAGE = OBJECT_END + 0x063, // Size: 1, Flags: PRIVATE, OWNER, SPECIAL_INFO - UNIT_FIELD_BYTES_1 = OBJECT_END + 0x064, // Size: 1, Flags: PUBLIC - UNIT_FIELD_PETNUMBER = OBJECT_END + 0x065, // Size: 1, Flags: PUBLIC - UNIT_FIELD_PET_NAME_TIMESTAMP = OBJECT_END + 0x066, // Size: 1, Flags: PUBLIC - UNIT_FIELD_PETEXPERIENCE = OBJECT_END + 0x067, // Size: 1, Flags: OWNER - UNIT_FIELD_PETNEXTLEVELEXP = OBJECT_END + 0x068, // Size: 1, Flags: OWNER - UNIT_MOD_CAST_SPEED = OBJECT_END + 0x069, // Size: 1, Flags: PUBLIC - UNIT_MOD_CAST_HASTE = OBJECT_END + 0x06A, // Size: 1, Flags: PUBLIC - UNIT_FIELD_MOD_HASTE = OBJECT_END + 0x06B, // Size: 1, Flags: PUBLIC - UNIT_FIELD_MOD_RANGED_HASTE = OBJECT_END + 0x06C, // Size: 1, Flags: PUBLIC - UNIT_FIELD_MOD_HASTE_REGEN = OBJECT_END + 0x06D, // Size: 1, Flags: PUBLIC - UNIT_FIELD_MOD_TIME_RATE = OBJECT_END + 0x06E, // Size: 1, Flags: PUBLIC - UNIT_CREATED_BY_SPELL = OBJECT_END + 0x06F, // Size: 1, Flags: PUBLIC - UNIT_NPC_FLAGS = OBJECT_END + 0x070, // Size: 2, Flags: PUBLIC, DYNAMIC - UNIT_NPC_EMOTESTATE = OBJECT_END + 0x072, // Size: 1, Flags: PUBLIC - UNIT_FIELD_STAT = OBJECT_END + 0x073, // Size: 4, Flags: PRIVATE, OWNER - UNIT_FIELD_POSSTAT = OBJECT_END + 0x077, // Size: 4, Flags: PRIVATE, OWNER - UNIT_FIELD_NEGSTAT = OBJECT_END + 0x07B, // Size: 4, Flags: PRIVATE, OWNER - UNIT_FIELD_RESISTANCES = OBJECT_END + 0x07F, // Size: 7, Flags: PRIVATE, OWNER, SPECIAL_INFO - UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE = OBJECT_END + 0x086, // Size: 7, Flags: PRIVATE, OWNER - UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE = OBJECT_END + 0x08D, // Size: 7, Flags: PRIVATE, OWNER - UNIT_FIELD_MOD_BONUS_ARMOR = OBJECT_END + 0x094, // Size: 1, Flags: PRIVATE, OWNER - UNIT_FIELD_BASE_MANA = OBJECT_END + 0x095, // Size: 1, Flags: PUBLIC - UNIT_FIELD_BASE_HEALTH = OBJECT_END + 0x096, // Size: 1, Flags: PRIVATE, OWNER - UNIT_FIELD_BYTES_2 = OBJECT_END + 0x097, // Size: 1, Flags: PUBLIC - UNIT_FIELD_ATTACK_POWER = OBJECT_END + 0x098, // Size: 1, Flags: PRIVATE, OWNER - UNIT_FIELD_ATTACK_POWER_MOD_POS = OBJECT_END + 0x099, // Size: 1, Flags: PRIVATE, OWNER - UNIT_FIELD_ATTACK_POWER_MOD_NEG = OBJECT_END + 0x09A, // Size: 1, Flags: PRIVATE, OWNER - UNIT_FIELD_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x09B, // Size: 1, Flags: PRIVATE, OWNER - UNIT_FIELD_RANGED_ATTACK_POWER = OBJECT_END + 0x09C, // Size: 1, Flags: PRIVATE, OWNER - UNIT_FIELD_RANGED_ATTACK_POWER_MOD_POS = OBJECT_END + 0x09D, // Size: 1, Flags: PRIVATE, OWNER - UNIT_FIELD_RANGED_ATTACK_POWER_MOD_NEG = OBJECT_END + 0x09E, // Size: 1, Flags: PRIVATE, OWNER - UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x09F, // Size: 1, Flags: PRIVATE, OWNER - UNIT_FIELD_ATTACK_SPEED_AURA = OBJECT_END + 0x0A0, // Size: 1, Flags: PRIVATE, OWNER - UNIT_FIELD_MINRANGEDDAMAGE = OBJECT_END + 0x0A1, // Size: 1, Flags: PRIVATE, OWNER - UNIT_FIELD_MAXRANGEDDAMAGE = OBJECT_END + 0x0A2, // Size: 1, Flags: PRIVATE, OWNER - UNIT_FIELD_POWER_COST_MODIFIER = OBJECT_END + 0x0A3, // Size: 7, Flags: PRIVATE, OWNER - UNIT_FIELD_POWER_COST_MULTIPLIER = OBJECT_END + 0x0AA, // Size: 7, Flags: PRIVATE, OWNER - UNIT_FIELD_MAXHEALTHMODIFIER = OBJECT_END + 0x0B1, // Size: 1, Flags: PRIVATE, OWNER - UNIT_FIELD_HOVERHEIGHT = OBJECT_END + 0x0B2, // Size: 1, Flags: PUBLIC - UNIT_FIELD_MIN_ITEM_LEVEL_CUTOFF = OBJECT_END + 0x0B3, // Size: 1, Flags: PUBLIC - UNIT_FIELD_MIN_ITEM_LEVEL = OBJECT_END + 0x0B4, // Size: 1, Flags: PUBLIC - UNIT_FIELD_MAXITEMLEVEL = OBJECT_END + 0x0B5, // Size: 1, Flags: PUBLIC - UNIT_FIELD_WILD_BATTLEPET_LEVEL = OBJECT_END + 0x0B6, // Size: 1, Flags: PUBLIC - UNIT_FIELD_BATTLEPET_COMPANION_NAME_TIMESTAMP = OBJECT_END + 0x0B7, // Size: 1, Flags: PUBLIC - UNIT_FIELD_INTERACT_SPELLID = OBJECT_END + 0x0B8, // Size: 1, Flags: PUBLIC - UNIT_FIELD_STATE_SPELL_VISUAL_ID = OBJECT_END + 0x0B9, // Size: 1, Flags: DYNAMIC, URGENT - UNIT_FIELD_STATE_ANIM_ID = OBJECT_END + 0x0BA, // Size: 1, Flags: DYNAMIC, URGENT - UNIT_FIELD_STATE_ANIM_KIT_ID = OBJECT_END + 0x0BB, // Size: 1, Flags: DYNAMIC, URGENT - UNIT_FIELD_STATE_WORLD_EFFECT_ID = OBJECT_END + 0x0BC, // Size: 4, Flags: DYNAMIC, URGENT - UNIT_FIELD_SCALE_DURATION = OBJECT_END + 0x0C0, // Size: 1, Flags: PUBLIC - UNIT_FIELD_LOOKS_LIKE_MOUNT_ID = OBJECT_END + 0x0C1, // Size: 1, Flags: PUBLIC - UNIT_FIELD_LOOKS_LIKE_CREATURE_ID = OBJECT_END + 0x0C2, // Size: 1, Flags: PUBLIC - UNIT_FIELD_LOOK_AT_CONTROLLER_ID = OBJECT_END + 0x0C3, // Size: 1, Flags: PUBLIC - UNIT_FIELD_LOOK_AT_CONTROLLER_TARGET = OBJECT_END + 0x0C4, // Size: 4, Flags: PUBLIC - UNIT_END = OBJECT_END + 0x0C8, + UNIT_FIELD_SANDBOX_SCALING_ID = OBJECT_END + 0x04A, // Size: 1, Flags: PUBLIC + UNIT_FIELD_SCALING_LEVEL_MIN = OBJECT_END + 0x04B, // Size: 1, Flags: PUBLIC + UNIT_FIELD_SCALING_LEVEL_MAX = OBJECT_END + 0x04C, // Size: 1, Flags: PUBLIC + UNIT_FIELD_SCALING_LEVEL_DELTA = OBJECT_END + 0x04D, // Size: 1, Flags: PUBLIC + UNIT_FIELD_FACTIONTEMPLATE = OBJECT_END + 0x04E, // Size: 1, Flags: PUBLIC + UNIT_VIRTUAL_ITEM_SLOT_ID = OBJECT_END + 0x04F, // Size: 6, Flags: PUBLIC + UNIT_FIELD_FLAGS = OBJECT_END + 0x055, // Size: 1, Flags: PUBLIC, URGENT + UNIT_FIELD_FLAGS_2 = OBJECT_END + 0x056, // Size: 1, Flags: PUBLIC, URGENT + UNIT_FIELD_FLAGS_3 = OBJECT_END + 0x057, // Size: 1, Flags: PUBLIC, URGENT + UNIT_FIELD_AURASTATE = OBJECT_END + 0x058, // Size: 1, Flags: PUBLIC + UNIT_FIELD_BASEATTACKTIME = OBJECT_END + 0x059, // Size: 2, Flags: PUBLIC + UNIT_FIELD_RANGEDATTACKTIME = OBJECT_END + 0x05B, // Size: 1, Flags: PRIVATE + UNIT_FIELD_BOUNDINGRADIUS = OBJECT_END + 0x05C, // Size: 1, Flags: PUBLIC + UNIT_FIELD_COMBATREACH = OBJECT_END + 0x05D, // Size: 1, Flags: PUBLIC + UNIT_FIELD_DISPLAYID = OBJECT_END + 0x05E, // Size: 1, Flags: DYNAMIC, URGENT + UNIT_FIELD_NATIVEDISPLAYID = OBJECT_END + 0x05F, // Size: 1, Flags: PUBLIC, URGENT + UNIT_FIELD_MOUNTDISPLAYID = OBJECT_END + 0x060, // Size: 1, Flags: PUBLIC, URGENT + UNIT_FIELD_MINDAMAGE = OBJECT_END + 0x061, // Size: 1, Flags: PRIVATE, OWNER, SPECIAL_INFO + UNIT_FIELD_MAXDAMAGE = OBJECT_END + 0x062, // Size: 1, Flags: PRIVATE, OWNER, SPECIAL_INFO + UNIT_FIELD_MINOFFHANDDAMAGE = OBJECT_END + 0x063, // Size: 1, Flags: PRIVATE, OWNER, SPECIAL_INFO + UNIT_FIELD_MAXOFFHANDDAMAGE = OBJECT_END + 0x064, // Size: 1, Flags: PRIVATE, OWNER, SPECIAL_INFO + UNIT_FIELD_BYTES_1 = OBJECT_END + 0x065, // Size: 1, Flags: PUBLIC + UNIT_FIELD_PETNUMBER = OBJECT_END + 0x066, // Size: 1, Flags: PUBLIC + UNIT_FIELD_PET_NAME_TIMESTAMP = OBJECT_END + 0x067, // Size: 1, Flags: PUBLIC + UNIT_FIELD_PETEXPERIENCE = OBJECT_END + 0x068, // Size: 1, Flags: OWNER + UNIT_FIELD_PETNEXTLEVELEXP = OBJECT_END + 0x069, // Size: 1, Flags: OWNER + UNIT_MOD_CAST_SPEED = OBJECT_END + 0x06A, // Size: 1, Flags: PUBLIC + UNIT_MOD_CAST_HASTE = OBJECT_END + 0x06B, // Size: 1, Flags: PUBLIC + UNIT_FIELD_MOD_HASTE = OBJECT_END + 0x06C, // Size: 1, Flags: PUBLIC + UNIT_FIELD_MOD_RANGED_HASTE = OBJECT_END + 0x06D, // Size: 1, Flags: PUBLIC + UNIT_FIELD_MOD_HASTE_REGEN = OBJECT_END + 0x06E, // Size: 1, Flags: PUBLIC + UNIT_FIELD_MOD_TIME_RATE = OBJECT_END + 0x06F, // Size: 1, Flags: PUBLIC + UNIT_CREATED_BY_SPELL = OBJECT_END + 0x070, // Size: 1, Flags: PUBLIC + UNIT_NPC_FLAGS = OBJECT_END + 0x071, // Size: 2, Flags: PUBLIC, DYNAMIC + UNIT_NPC_EMOTESTATE = OBJECT_END + 0x073, // Size: 1, Flags: PUBLIC + UNIT_FIELD_STAT = OBJECT_END + 0x074, // Size: 4, Flags: PRIVATE, OWNER + UNIT_FIELD_POSSTAT = OBJECT_END + 0x078, // Size: 4, Flags: PRIVATE, OWNER + UNIT_FIELD_NEGSTAT = OBJECT_END + 0x07C, // Size: 4, Flags: PRIVATE, OWNER + UNIT_FIELD_RESISTANCES = OBJECT_END + 0x080, // Size: 7, Flags: PRIVATE, OWNER, SPECIAL_INFO + UNIT_FIELD_RESISTANCEBUFFMODSPOSITIVE = OBJECT_END + 0x087, // Size: 7, Flags: PRIVATE, OWNER + UNIT_FIELD_RESISTANCEBUFFMODSNEGATIVE = OBJECT_END + 0x08E, // Size: 7, Flags: PRIVATE, OWNER + UNIT_FIELD_MOD_BONUS_ARMOR = OBJECT_END + 0x095, // Size: 1, Flags: PRIVATE, OWNER + UNIT_FIELD_BASE_MANA = OBJECT_END + 0x096, // Size: 1, Flags: PUBLIC + UNIT_FIELD_BASE_HEALTH = OBJECT_END + 0x097, // Size: 1, Flags: PRIVATE, OWNER + UNIT_FIELD_BYTES_2 = OBJECT_END + 0x098, // Size: 1, Flags: PUBLIC + UNIT_FIELD_ATTACK_POWER = OBJECT_END + 0x099, // Size: 1, Flags: PRIVATE, OWNER + UNIT_FIELD_ATTACK_POWER_MOD_POS = OBJECT_END + 0x09A, // Size: 1, Flags: PRIVATE, OWNER + UNIT_FIELD_ATTACK_POWER_MOD_NEG = OBJECT_END + 0x09B, // Size: 1, Flags: PRIVATE, OWNER + UNIT_FIELD_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x09C, // Size: 1, Flags: PRIVATE, OWNER + UNIT_FIELD_RANGED_ATTACK_POWER = OBJECT_END + 0x09D, // Size: 1, Flags: PRIVATE, OWNER + UNIT_FIELD_RANGED_ATTACK_POWER_MOD_POS = OBJECT_END + 0x09E, // Size: 1, Flags: PRIVATE, OWNER + UNIT_FIELD_RANGED_ATTACK_POWER_MOD_NEG = OBJECT_END + 0x09F, // Size: 1, Flags: PRIVATE, OWNER + UNIT_FIELD_RANGED_ATTACK_POWER_MULTIPLIER = OBJECT_END + 0x0A0, // Size: 1, Flags: PRIVATE, OWNER + UNIT_FIELD_ATTACK_SPEED_AURA = OBJECT_END + 0x0A1, // Size: 1, Flags: PRIVATE, OWNER + UNIT_FIELD_MINRANGEDDAMAGE = OBJECT_END + 0x0A2, // Size: 1, Flags: PRIVATE, OWNER + UNIT_FIELD_MAXRANGEDDAMAGE = OBJECT_END + 0x0A3, // Size: 1, Flags: PRIVATE, OWNER + UNIT_FIELD_POWER_COST_MODIFIER = OBJECT_END + 0x0A4, // Size: 7, Flags: PRIVATE, OWNER + UNIT_FIELD_POWER_COST_MULTIPLIER = OBJECT_END + 0x0AB, // Size: 7, Flags: PRIVATE, OWNER + UNIT_FIELD_MAXHEALTHMODIFIER = OBJECT_END + 0x0B2, // Size: 1, Flags: PRIVATE, OWNER + UNIT_FIELD_HOVERHEIGHT = OBJECT_END + 0x0B3, // Size: 1, Flags: PUBLIC + UNIT_FIELD_MIN_ITEM_LEVEL_CUTOFF = OBJECT_END + 0x0B4, // Size: 1, Flags: PUBLIC + UNIT_FIELD_MIN_ITEM_LEVEL = OBJECT_END + 0x0B5, // Size: 1, Flags: PUBLIC + UNIT_FIELD_MAXITEMLEVEL = OBJECT_END + 0x0B6, // Size: 1, Flags: PUBLIC + UNIT_FIELD_WILD_BATTLEPET_LEVEL = OBJECT_END + 0x0B7, // Size: 1, Flags: PUBLIC + UNIT_FIELD_BATTLEPET_COMPANION_NAME_TIMESTAMP = OBJECT_END + 0x0B8, // Size: 1, Flags: PUBLIC + UNIT_FIELD_INTERACT_SPELLID = OBJECT_END + 0x0B9, // Size: 1, Flags: PUBLIC + UNIT_FIELD_STATE_SPELL_VISUAL_ID = OBJECT_END + 0x0BA, // Size: 1, Flags: DYNAMIC, URGENT + UNIT_FIELD_STATE_ANIM_ID = OBJECT_END + 0x0BB, // Size: 1, Flags: DYNAMIC, URGENT + UNIT_FIELD_STATE_ANIM_KIT_ID = OBJECT_END + 0x0BC, // Size: 1, Flags: DYNAMIC, URGENT + UNIT_FIELD_STATE_WORLD_EFFECT_ID = OBJECT_END + 0x0BD, // Size: 4, Flags: DYNAMIC, URGENT + UNIT_FIELD_SCALE_DURATION = OBJECT_END + 0x0C1, // Size: 1, Flags: PUBLIC + UNIT_FIELD_LOOKS_LIKE_MOUNT_ID = OBJECT_END + 0x0C2, // Size: 1, Flags: PUBLIC + UNIT_FIELD_LOOKS_LIKE_CREATURE_ID = OBJECT_END + 0x0C3, // Size: 1, Flags: PUBLIC + UNIT_FIELD_LOOK_AT_CONTROLLER_ID = OBJECT_END + 0x0C4, // Size: 1, Flags: PUBLIC + UNIT_FIELD_LOOK_AT_CONTROLLER_TARGET = OBJECT_END + 0x0C5, // Size: 4, Flags: PUBLIC + UNIT_END = OBJECT_END + 0x0C9, }; enum UnitDynamicFields @@ -219,94 +220,94 @@ enum PlayerFields PLAYER_FIELD_CURRENT_BATTLE_PET_BREED_QUALITY = UNIT_END + 0x366, // Size: 1, Flags: PUBLIC PLAYER_FIELD_PRESTIGE = UNIT_END + 0x367, // Size: 1, Flags: PUBLIC PLAYER_FIELD_HONOR_LEVEL = UNIT_END + 0x368, // Size: 1, Flags: PUBLIC - PLAYER_FIELD_INV_SLOT_HEAD = UNIT_END + 0x369, // Size: 748, Flags: PRIVATE + PLAYER_FIELD_INV_SLOT_HEAD = UNIT_END + 0x369, // Size: 780, Flags: PRIVATE PLAYER_FIELD_END_NOT_SELF = UNIT_END + 0x369, - PLAYER_FARSIGHT = UNIT_END + 0x655, // Size: 4, Flags: PRIVATE - PLAYER_FIELD_SUMMONED_BATTLE_PET_ID = UNIT_END + 0x659, // Size: 4, Flags: PRIVATE - PLAYER__FIELD_KNOWN_TITLES = UNIT_END + 0x65D, // Size: 12, Flags: PRIVATE - PLAYER_FIELD_COINAGE = UNIT_END + 0x669, // Size: 2, Flags: PRIVATE - PLAYER_XP = UNIT_END + 0x66B, // Size: 1, Flags: PRIVATE - PLAYER_NEXT_LEVEL_XP = UNIT_END + 0x66C, // Size: 1, Flags: PRIVATE - PLAYER_SKILL_LINEID = UNIT_END + 0x66D, // Size: 448, Flags: PRIVATE - PLAYER_CHARACTER_POINTS = UNIT_END + 0x82D, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_MAX_TALENT_TIERS = UNIT_END + 0x82E, // Size: 1, Flags: PRIVATE - PLAYER_TRACK_CREATURES = UNIT_END + 0x82F, // Size: 1, Flags: PRIVATE - PLAYER_TRACK_RESOURCES = UNIT_END + 0x830, // Size: 1, Flags: PRIVATE - PLAYER_EXPERTISE = UNIT_END + 0x831, // Size: 1, Flags: PRIVATE - PLAYER_OFFHAND_EXPERTISE = UNIT_END + 0x832, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_RANGED_EXPERTISE = UNIT_END + 0x833, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_COMBAT_RATING_EXPERTISE = UNIT_END + 0x834, // Size: 1, Flags: PRIVATE - PLAYER_BLOCK_PERCENTAGE = UNIT_END + 0x835, // Size: 1, Flags: PRIVATE - PLAYER_DODGE_PERCENTAGE = UNIT_END + 0x836, // Size: 1, Flags: PRIVATE - PLAYER_DODGE_PERCENTAGE_FROM_ATTRIBUTE = UNIT_END + 0x837, // Size: 1, Flags: PRIVATE - PLAYER_PARRY_PERCENTAGE = UNIT_END + 0x838, // Size: 1, Flags: PRIVATE - PLAYER_PARRY_PERCENTAGE_FROM_ATTRIBUTE = UNIT_END + 0x839, // Size: 1, Flags: PRIVATE - PLAYER_CRIT_PERCENTAGE = UNIT_END + 0x83A, // Size: 1, Flags: PRIVATE - PLAYER_RANGED_CRIT_PERCENTAGE = UNIT_END + 0x83B, // Size: 1, Flags: PRIVATE - PLAYER_OFFHAND_CRIT_PERCENTAGE = UNIT_END + 0x83C, // Size: 1, Flags: PRIVATE - PLAYER_SPELL_CRIT_PERCENTAGE1 = UNIT_END + 0x83D, // Size: 1, Flags: PRIVATE - PLAYER_SHIELD_BLOCK = UNIT_END + 0x83E, // Size: 1, Flags: PRIVATE - PLAYER_SHIELD_BLOCK_CRIT_PERCENTAGE = UNIT_END + 0x83F, // Size: 1, Flags: PRIVATE - PLAYER_MASTERY = UNIT_END + 0x840, // Size: 1, Flags: PRIVATE - PLAYER_SPEED = UNIT_END + 0x841, // Size: 1, Flags: PRIVATE - PLAYER_LIFESTEAL = UNIT_END + 0x842, // Size: 1, Flags: PRIVATE - PLAYER_AVOIDANCE = UNIT_END + 0x843, // Size: 1, Flags: PRIVATE - PLAYER_STURDINESS = UNIT_END + 0x844, // Size: 1, Flags: PRIVATE - PLAYER_VERSATILITY = UNIT_END + 0x845, // Size: 1, Flags: PRIVATE - PLAYER_VERSATILITY_BONUS = UNIT_END + 0x846, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_PVP_POWER_DAMAGE = UNIT_END + 0x847, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_PVP_POWER_HEALING = UNIT_END + 0x848, // Size: 1, Flags: PRIVATE - PLAYER_EXPLORED_ZONES_1 = UNIT_END + 0x849, // Size: 320, Flags: PRIVATE - PLAYER_FIELD_REST_INFO = UNIT_END + 0x989, // Size: 4, Flags: PRIVATE - PLAYER_FIELD_MOD_DAMAGE_DONE_POS = UNIT_END + 0x98D, // Size: 7, Flags: PRIVATE - PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = UNIT_END + 0x994, // Size: 7, Flags: PRIVATE - PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = UNIT_END + 0x99B, // Size: 7, Flags: PRIVATE - PLAYER_FIELD_MOD_HEALING_DONE_POS = UNIT_END + 0x9A2, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_MOD_HEALING_PCT = UNIT_END + 0x9A3, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_MOD_HEALING_DONE_PCT = UNIT_END + 0x9A4, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_MOD_PERIODIC_HEALING_DONE_PERCENT = UNIT_END + 0x9A5, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_WEAPON_DMG_MULTIPLIERS = UNIT_END + 0x9A6, // Size: 3, Flags: PRIVATE - PLAYER_FIELD_WEAPON_ATK_SPEED_MULTIPLIERS = UNIT_END + 0x9A9, // Size: 3, Flags: PRIVATE - PLAYER_FIELD_MOD_SPELL_POWER_PCT = UNIT_END + 0x9AC, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_MOD_RESILIENCE_PERCENT = UNIT_END + 0x9AD, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_OVERRIDE_SPELL_POWER_BY_AP_PCT = UNIT_END + 0x9AE, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_OVERRIDE_AP_BY_SPELL_POWER_PERCENT = UNIT_END + 0x9AF, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x9B0, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x9B1, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_LOCAL_FLAGS = UNIT_END + 0x9B2, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_BYTES = UNIT_END + 0x9B3, // Size: 1, Flags: PRIVATE - PLAYER_SELF_RES_SPELL = UNIT_END + 0x9B4, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x9B5, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x9B6, // Size: 12, Flags: PRIVATE - PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x9C2, // Size: 12, Flags: PRIVATE - PLAYER_FIELD_KILLS = UNIT_END + 0x9CE, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_LIFETIME_HONORABLE_KILLS = UNIT_END + 0x9CF, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x9D0, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x9D1, // Size: 32, Flags: PRIVATE - PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0x9F1, // Size: 42, Flags: PRIVATE - PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0xA1B, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_SCALING_PLAYER_LEVEL_DELTA = UNIT_END + 0xA1C, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_MAX_CREATURE_SCALING_LEVEL = UNIT_END + 0xA1D, // Size: 1, Flags: PRIVATE - PLAYER_NO_REAGENT_COST_1 = UNIT_END + 0xA1E, // Size: 4, Flags: PRIVATE - PLAYER_PET_SPELL_POWER = UNIT_END + 0xA22, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_RESEARCHING_1 = UNIT_END + 0xA23, // Size: 10, Flags: PRIVATE - PLAYER_PROFESSION_SKILL_LINE_1 = UNIT_END + 0xA2D, // Size: 2, Flags: PRIVATE - PLAYER_FIELD_UI_HIT_MODIFIER = UNIT_END + 0xA2F, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_UI_SPELL_HIT_MODIFIER = UNIT_END + 0xA30, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_HOME_REALM_TIME_OFFSET = UNIT_END + 0xA31, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_MOD_PET_HASTE = UNIT_END + 0xA32, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_BYTES2 = UNIT_END + 0xA33, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_BYTES3 = UNIT_END + 0xA34, // Size: 1, Flags: PRIVATE, URGENT_SELF_ONLY - PLAYER_FIELD_LFG_BONUS_FACTION_ID = UNIT_END + 0xA35, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_LOOT_SPEC_ID = UNIT_END + 0xA36, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_OVERRIDE_ZONE_PVP_TYPE = UNIT_END + 0xA37, // Size: 1, Flags: PRIVATE, URGENT_SELF_ONLY - PLAYER_FIELD_BAG_SLOT_FLAGS = UNIT_END + 0xA38, // Size: 4, Flags: PRIVATE - PLAYER_FIELD_BANK_BAG_SLOT_FLAGS = UNIT_END + 0xA3C, // Size: 7, Flags: PRIVATE - PLAYER_FIELD_INSERT_ITEMS_LEFT_TO_RIGHT = UNIT_END + 0xA43, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_QUEST_COMPLETED = UNIT_END + 0xA44, // Size: 1750, Flags: PRIVATE - PLAYER_FIELD_HONOR = UNIT_END + 0x111A, // Size: 1, Flags: PRIVATE - PLAYER_FIELD_HONOR_NEXT_LEVEL = UNIT_END + 0x111B, // Size: 1, Flags: PRIVATE - PLAYER_END = UNIT_END + 0x111C, + PLAYER_FARSIGHT = UNIT_END + 0x675, // Size: 4, Flags: PRIVATE + PLAYER_FIELD_SUMMONED_BATTLE_PET_ID = UNIT_END + 0x679, // Size: 4, Flags: PRIVATE + PLAYER__FIELD_KNOWN_TITLES = UNIT_END + 0x67D, // Size: 12, Flags: PRIVATE + PLAYER_FIELD_COINAGE = UNIT_END + 0x689, // Size: 2, Flags: PRIVATE + PLAYER_XP = UNIT_END + 0x68B, // Size: 1, Flags: PRIVATE + PLAYER_NEXT_LEVEL_XP = UNIT_END + 0x68C, // Size: 1, Flags: PRIVATE + PLAYER_TRIAL_XP = UNIT_END + 0x68D, // Size: 1, Flags: PRIVATE + PLAYER_SKILL_LINEID = UNIT_END + 0x68E, // Size: 448, Flags: PRIVATE + PLAYER_CHARACTER_POINTS = UNIT_END + 0x84E, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_MAX_TALENT_TIERS = UNIT_END + 0x84F, // Size: 1, Flags: PRIVATE + PLAYER_TRACK_CREATURES = UNIT_END + 0x850, // Size: 1, Flags: PRIVATE + PLAYER_TRACK_RESOURCES = UNIT_END + 0x851, // Size: 1, Flags: PRIVATE + PLAYER_EXPERTISE = UNIT_END + 0x852, // Size: 1, Flags: PRIVATE + PLAYER_OFFHAND_EXPERTISE = UNIT_END + 0x853, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_RANGED_EXPERTISE = UNIT_END + 0x854, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_COMBAT_RATING_EXPERTISE = UNIT_END + 0x855, // Size: 1, Flags: PRIVATE + PLAYER_BLOCK_PERCENTAGE = UNIT_END + 0x856, // Size: 1, Flags: PRIVATE + PLAYER_DODGE_PERCENTAGE = UNIT_END + 0x857, // Size: 1, Flags: PRIVATE + PLAYER_DODGE_PERCENTAGE_FROM_ATTRIBUTE = UNIT_END + 0x858, // Size: 1, Flags: PRIVATE + PLAYER_PARRY_PERCENTAGE = UNIT_END + 0x859, // Size: 1, Flags: PRIVATE + PLAYER_PARRY_PERCENTAGE_FROM_ATTRIBUTE = UNIT_END + 0x85A, // Size: 1, Flags: PRIVATE + PLAYER_CRIT_PERCENTAGE = UNIT_END + 0x85B, // Size: 1, Flags: PRIVATE + PLAYER_RANGED_CRIT_PERCENTAGE = UNIT_END + 0x85C, // Size: 1, Flags: PRIVATE + PLAYER_OFFHAND_CRIT_PERCENTAGE = UNIT_END + 0x85D, // Size: 1, Flags: PRIVATE + PLAYER_SPELL_CRIT_PERCENTAGE1 = UNIT_END + 0x85E, // Size: 1, Flags: PRIVATE + PLAYER_SHIELD_BLOCK = UNIT_END + 0x85F, // Size: 1, Flags: PRIVATE + PLAYER_SHIELD_BLOCK_CRIT_PERCENTAGE = UNIT_END + 0x860, // Size: 1, Flags: PRIVATE + PLAYER_MASTERY = UNIT_END + 0x861, // Size: 1, Flags: PRIVATE + PLAYER_SPEED = UNIT_END + 0x862, // Size: 1, Flags: PRIVATE + PLAYER_LIFESTEAL = UNIT_END + 0x863, // Size: 1, Flags: PRIVATE + PLAYER_AVOIDANCE = UNIT_END + 0x864, // Size: 1, Flags: PRIVATE + PLAYER_STURDINESS = UNIT_END + 0x865, // Size: 1, Flags: PRIVATE + PLAYER_VERSATILITY = UNIT_END + 0x866, // Size: 1, Flags: PRIVATE + PLAYER_VERSATILITY_BONUS = UNIT_END + 0x867, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_PVP_POWER_DAMAGE = UNIT_END + 0x868, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_PVP_POWER_HEALING = UNIT_END + 0x869, // Size: 1, Flags: PRIVATE + PLAYER_EXPLORED_ZONES_1 = UNIT_END + 0x86A, // Size: 320, Flags: PRIVATE + PLAYER_FIELD_REST_INFO = UNIT_END + 0x9AA, // Size: 4, Flags: PRIVATE + PLAYER_FIELD_MOD_DAMAGE_DONE_POS = UNIT_END + 0x9AE, // Size: 7, Flags: PRIVATE + PLAYER_FIELD_MOD_DAMAGE_DONE_NEG = UNIT_END + 0x9B5, // Size: 7, Flags: PRIVATE + PLAYER_FIELD_MOD_DAMAGE_DONE_PCT = UNIT_END + 0x9BC, // Size: 7, Flags: PRIVATE + PLAYER_FIELD_MOD_HEALING_DONE_POS = UNIT_END + 0x9C3, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_MOD_HEALING_PCT = UNIT_END + 0x9C4, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_MOD_HEALING_DONE_PCT = UNIT_END + 0x9C5, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_MOD_PERIODIC_HEALING_DONE_PERCENT = UNIT_END + 0x9C6, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_WEAPON_DMG_MULTIPLIERS = UNIT_END + 0x9C7, // Size: 3, Flags: PRIVATE + PLAYER_FIELD_WEAPON_ATK_SPEED_MULTIPLIERS = UNIT_END + 0x9CA, // Size: 3, Flags: PRIVATE + PLAYER_FIELD_MOD_SPELL_POWER_PCT = UNIT_END + 0x9CD, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_MOD_RESILIENCE_PERCENT = UNIT_END + 0x9CE, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_OVERRIDE_SPELL_POWER_BY_AP_PCT = UNIT_END + 0x9CF, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_OVERRIDE_AP_BY_SPELL_POWER_PERCENT = UNIT_END + 0x9D0, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_MOD_TARGET_RESISTANCE = UNIT_END + 0x9D1, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_MOD_TARGET_PHYSICAL_RESISTANCE = UNIT_END + 0x9D2, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_LOCAL_FLAGS = UNIT_END + 0x9D3, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_BYTES = UNIT_END + 0x9D4, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_PVP_MEDALS = UNIT_END + 0x9D5, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_BUYBACK_PRICE_1 = UNIT_END + 0x9D6, // Size: 12, Flags: PRIVATE + PLAYER_FIELD_BUYBACK_TIMESTAMP_1 = UNIT_END + 0x9E2, // Size: 12, Flags: PRIVATE + PLAYER_FIELD_KILLS = UNIT_END + 0x9EE, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_LIFETIME_HONORABLE_KILLS = UNIT_END + 0x9EF, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_WATCHED_FACTION_INDEX = UNIT_END + 0x9F0, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_COMBAT_RATING_1 = UNIT_END + 0x9F1, // Size: 32, Flags: PRIVATE + PLAYER_FIELD_ARENA_TEAM_INFO_1_1 = UNIT_END + 0xA11, // Size: 42, Flags: PRIVATE + PLAYER_FIELD_MAX_LEVEL = UNIT_END + 0xA3B, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_SCALING_PLAYER_LEVEL_DELTA = UNIT_END + 0xA3C, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_MAX_CREATURE_SCALING_LEVEL = UNIT_END + 0xA3D, // Size: 1, Flags: PRIVATE + PLAYER_NO_REAGENT_COST_1 = UNIT_END + 0xA3E, // Size: 4, Flags: PRIVATE + PLAYER_PET_SPELL_POWER = UNIT_END + 0xA42, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_RESEARCHING_1 = UNIT_END + 0xA43, // Size: 10, Flags: PRIVATE + PLAYER_PROFESSION_SKILL_LINE_1 = UNIT_END + 0xA4D, // Size: 2, Flags: PRIVATE + PLAYER_FIELD_UI_HIT_MODIFIER = UNIT_END + 0xA4F, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_UI_SPELL_HIT_MODIFIER = UNIT_END + 0xA50, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_HOME_REALM_TIME_OFFSET = UNIT_END + 0xA51, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_MOD_PET_HASTE = UNIT_END + 0xA52, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_BYTES2 = UNIT_END + 0xA53, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_BYTES3 = UNIT_END + 0xA54, // Size: 1, Flags: PRIVATE, URGENT_SELF_ONLY + PLAYER_FIELD_LFG_BONUS_FACTION_ID = UNIT_END + 0xA55, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_LOOT_SPEC_ID = UNIT_END + 0xA56, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_OVERRIDE_ZONE_PVP_TYPE = UNIT_END + 0xA57, // Size: 1, Flags: PRIVATE, URGENT_SELF_ONLY + PLAYER_FIELD_BAG_SLOT_FLAGS = UNIT_END + 0xA58, // Size: 4, Flags: PRIVATE + PLAYER_FIELD_BANK_BAG_SLOT_FLAGS = UNIT_END + 0xA5C, // Size: 7, Flags: PRIVATE + PLAYER_FIELD_INSERT_ITEMS_LEFT_TO_RIGHT = UNIT_END + 0xA63, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_QUEST_COMPLETED = UNIT_END + 0xA64, // Size: 1750, Flags: PRIVATE + PLAYER_FIELD_HONOR = UNIT_END + 0x113A, // Size: 1, Flags: PRIVATE + PLAYER_FIELD_HONOR_NEXT_LEVEL = UNIT_END + 0x113B, // Size: 1, Flags: PRIVATE + PLAYER_END = UNIT_END + 0x113C, }; enum PlayerDynamicFields @@ -320,11 +321,12 @@ enum PlayerDynamicFields PLAYER_DYNAMIC_FIELD_TOYS = UNIT_DYNAMIC_END + 0x006, // Flags: PRIVATE PLAYER_DYNAMIC_FIELD_TRANSMOG = UNIT_DYNAMIC_END + 0x007, // Flags: PRIVATE PLAYER_DYNAMIC_FIELD_CONDITIONAL_TRANSMOG = UNIT_DYNAMIC_END + 0x008, // Flags: PRIVATE - PLAYER_DYNAMIC_FIELD_CHARACTER_RESTRICTIONS = UNIT_DYNAMIC_END + 0x009, // Flags: PRIVATE - PLAYER_DYNAMIC_FIELD_SPELL_PCT_MOD_BY_LABEL = UNIT_DYNAMIC_END + 0x00A, // Flags: PRIVATE - PLAYER_DYNAMIC_FIELD_SPELL_FLAT_MOD_BY_LABEL = UNIT_DYNAMIC_END + 0x00B, // Flags: PRIVATE - PLAYER_DYNAMIC_FIELD_ARENA_COOLDOWNS = UNIT_DYNAMIC_END + 0x00C, // Flags: PUBLIC - PLAYER_DYNAMIC_END = UNIT_DYNAMIC_END + 0x00D, + PLAYER_DYNAMIC_FIELD_SELF_RES_SPELLS = UNIT_DYNAMIC_END + 0x009, // Flags: PRIVATE + PLAYER_DYNAMIC_FIELD_CHARACTER_RESTRICTIONS = UNIT_DYNAMIC_END + 0x00A, // Flags: PRIVATE + PLAYER_DYNAMIC_FIELD_SPELL_PCT_MOD_BY_LABEL = UNIT_DYNAMIC_END + 0x00B, // Flags: PRIVATE + PLAYER_DYNAMIC_FIELD_SPELL_FLAT_MOD_BY_LABEL = UNIT_DYNAMIC_END + 0x00C, // Flags: PRIVATE + PLAYER_DYNAMIC_FIELD_ARENA_COOLDOWNS = UNIT_DYNAMIC_END + 0x00D, // Flags: PUBLIC + PLAYER_DYNAMIC_END = UNIT_DYNAMIC_END + 0x00E, }; enum GameObjectFields diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index ff0eaaf891f..fc29e464fbf 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -478,6 +478,7 @@ bool Player::Create(ObjectGuid::LowType guidlow, WorldPackets::Character::Charac SetUInt32Value(PLAYER_FIELD_REST_INFO + REST_STATE_HONOR, REST_STATE_NOT_RAF_LINKED); SetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER, createInfo->Sex); SetByteValue(PLAYER_BYTES_4, PLAYER_BYTES_4_OFFSET_ARENA_FACTION, 0); + SetInventorySlotCount(INVENTORY_DEFAULT_SIZE); SetGuidValue(OBJECT_FIELD_DATA, ObjectGuid::Empty); SetUInt32Value(PLAYER_GUILDRANK, 0); @@ -655,7 +656,8 @@ bool Player::Create(ObjectGuid::LowType guidlow, WorldPackets::Character::Charac // bags and main-hand weapon must equipped at this moment // now second pass for not equipped (offhand weapon/shield if it attempt equipped before main-hand weapon) // or ammo not equipped in special bag - for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) + uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); + for (uint8 i = INVENTORY_SLOT_ITEM_START; i < inventoryEnd; i++) { if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) { @@ -1349,13 +1351,11 @@ void Player::Update(uint32 p_time) void Player::setDeathState(DeathState s) { - uint32 ressSpellId = 0; - - bool cur = IsAlive(); + bool oldIsAlive = IsAlive(); if (s == JUST_DIED) { - if (!cur) + if (!oldIsAlive) { TC_LOG_ERROR("entities.player", "Player::setDeathState: Attempted to kill a dead player '%s' (%s)", GetName().c_str(), GetGUID().ToString().c_str()); return; @@ -1371,12 +1371,8 @@ void Player::setDeathState(DeathState s) //FIXME: is pet dismissed at dying or releasing spirit? if second, add setDeathState(DEAD) to HandleRepopRequestOpcode and define pet unsummon here with (s == DEAD) RemovePet(nullptr, PET_SAVE_NOT_IN_SLOT, true); - // save value before aura remove in Unit::setDeathState - ressSpellId = GetUInt32Value(PLAYER_SELF_RES_SPELL); + InitializeSelfResurrectionSpells(); - // passive spell - if (!ressSpellId) - ressSpellId = GetResurrectionSpellId(); UpdateCriteria(CRITERIA_TYPE_DEATH_AT_MAP, 1); UpdateCriteria(CRITERIA_TYPE_DEATH, 1); UpdateCriteria(CRITERIA_TYPE_DEATH_IN_DUNGEON, 1); @@ -1387,13 +1383,9 @@ void Player::setDeathState(DeathState s) Unit::setDeathState(s); - // restore resurrection spell id for player after aura remove - if (s == JUST_DIED && cur && ressSpellId) - SetUInt32Value(PLAYER_SELF_RES_SPELL, ressSpellId); - - if (IsAlive() && !cur) + if (IsAlive() && !oldIsAlive) //clear aura case after resurrection by another way (spells will be applied before next death) - SetUInt32Value(PLAYER_SELF_RES_SPELL, 0); + ClearDynamicValue(PLAYER_DYNAMIC_FIELD_SELF_RES_SPELLS); } void Player::ToggleAFK() @@ -2675,7 +2667,9 @@ void Player::InitStatsForLevel(bool reapplyMods) RemoveByteFlag(UNIT_FIELD_BYTES_2, UNIT_BYTES_2_OFFSET_PVP_FLAG, UNIT_BYTE2_FLAG_FFA_PVP | UNIT_BYTE2_FLAG_SANCTUARY); // restore if need some important flags - SetUInt32Value(PLAYER_FIELD_BYTES2, 0); // flags empty by default + SetByteValue(PLAYER_FIELD_BYTES2, PLAYER_FIELD_BYTES_2_OFFSET_IGNORE_POWER_REGEN_PREDICTION_MASK, 0); + SetByteValue(PLAYER_FIELD_BYTES2, PLAYER_FIELD_BYTES_2_OFFSET_AURA_VISION, 0); + SetByteValue(PLAYER_FIELD_BYTES2, 3, 0); if (reapplyMods) // reapply stats values only on .reset stats (level) command _ApplyAllStatBonuses(); @@ -4390,7 +4384,8 @@ void Player::DurabilityLossAll(double percent, bool inventory) // bags not have durability // for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) - for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) + uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); + for (uint8 i = INVENTORY_SLOT_ITEM_START; i < inventoryEnd; i++) if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) DurabilityLoss(pItem, percent); @@ -4433,7 +4428,8 @@ void Player::DurabilityPointsLossAll(int32 points, bool inventory) // bags not have durability // for (int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; i++) - for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) + uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); + for (uint8 i = INVENTORY_SLOT_ITEM_START; i < inventoryEnd; i++) if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) DurabilityPointsLoss(pItem, points); @@ -4488,7 +4484,8 @@ uint32 Player::DurabilityRepairAll(bool cost, float discountMod, bool guildBank) { uint32 TotalCost = 0; // equipped, backpack, bags itself - for (uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; i++) + uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); + for (uint8 i = EQUIPMENT_SLOT_START; i < inventoryEnd; i++) TotalCost += DurabilityRepair(((INVENTORY_SLOT_BAG_0 << 8) | i), cost, discountMod, guildBank); // bank, buyback and keys not repaired @@ -9443,7 +9440,8 @@ InventoryResult Player::CanUnequipItems(uint32 item, uint32 count) const res = ires; } - for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; ++i) + uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); + for (uint8 i = INVENTORY_SLOT_ITEM_START; i < inventoryEnd; ++i) if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) if (pItem->GetEntry() == item) { @@ -9489,7 +9487,8 @@ InventoryResult Player::CanUnequipItems(uint32 item, uint32 count) const uint32 Player::GetItemCount(uint32 item, bool inBankAlso, Item* skipItem) const { uint32 count = 0; - for (uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; i++) + uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); + for (uint8 i = EQUIPMENT_SLOT_START; i < inventoryEnd; i++) if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) if (pItem != skipItem && pItem->GetEntry() == item) count += pItem->GetCount(); @@ -9499,7 +9498,7 @@ uint32 Player::GetItemCount(uint32 item, bool inBankAlso, Item* skipItem) const count += pBag->GetItemCount(item, skipItem); if (skipItem && skipItem->GetTemplate()->GetGemProperties()) - for (uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; ++i) + for (uint8 i = EQUIPMENT_SLOT_START; i < inventoryEnd; ++i) if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) if (pItem != skipItem && pItem->GetSocketColor(0)) count += pItem->GetGemCountWithID(item); @@ -9551,7 +9550,8 @@ uint32 Player::GetItemCount(uint32 item, bool inBankAlso, Item* skipItem) const uint32 Player::GetItemCountWithLimitCategory(uint32 limitCategory, Item* skipItem) const { uint32 count = 0; - for (int i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; ++i) + uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); + for (uint8 i = EQUIPMENT_SLOT_START; i < inventoryEnd; ++i) if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) if (pItem != skipItem) if (ItemTemplate const* pProto = pItem->GetTemplate()) @@ -9592,7 +9592,8 @@ uint32 Player::GetItemCountWithLimitCategory(uint32 limitCategory, Item* skipIte Item* Player::GetItemByGuid(ObjectGuid guid) const { - for (uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; ++i) + uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); + for (uint8 i = EQUIPMENT_SLOT_START; i < inventoryEnd; ++i) if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) if (pItem->GetGUID() == guid) return pItem; @@ -9717,7 +9718,8 @@ Item* Player::GetShield(bool useable) const Item* Player::GetChildItemByGuid(ObjectGuid guid) const { - for (uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; ++i) + uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); + for (uint8 i = EQUIPMENT_SLOT_START; i < inventoryEnd; ++i) if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) if (pItem->GetGUID() == guid) return pItem; @@ -9812,7 +9814,7 @@ bool Player::IsValidPos(uint8 bag, uint8 slot, bool explicit_pos) const return true; // backpack slots - if (slot >= INVENTORY_SLOT_ITEM_START && slot < INVENTORY_SLOT_ITEM_END) + if (slot >= INVENTORY_SLOT_ITEM_START && slot < INVENTORY_SLOT_ITEM_START + GetInventorySlotCount()) return true; // bank main slots @@ -9841,10 +9843,17 @@ bool Player::IsValidPos(uint8 bag, uint8 slot, bool explicit_pos) const return false; } +void Player::SetInventorySlotCount(uint8 slots) +{ + ASSERT(slots <= (INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START)); + SetByteValue(PLAYER_FIELD_BYTES2, PLAYER_FIELD_BYTES_2_OFFSET_NUM_BACKPACK_SLOTS, slots); +} + bool Player::HasItemCount(uint32 item, uint32 count, bool inBankAlso) const { uint32 tempcount = 0; - for (uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; i++) + uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); + for (uint8 i = EQUIPMENT_SLOT_START; i < inventoryEnd; i++) { Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i); if (pItem && pItem->GetEntry() == item && !pItem->IsInTrade()) @@ -10096,7 +10105,8 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec& des bool Player::HasItemTotemCategory(uint32 TotemCategory) const { Item* item; - for (uint8 i = EQUIPMENT_SLOT_START; i < INVENTORY_SLOT_ITEM_END; ++i) + uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); + for (uint8 i = EQUIPMENT_SLOT_START; i < inventoryEnd; ++i) { item = GetUseableItemByPos(INVENTORY_SLOT_BAG_0, i); if (item && DB2Manager::IsTotemCategoryCompatibleWith(item->GetTemplate()->GetTotemCategory(), TotemCategory)) @@ -10402,6 +10412,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des } // not specific slot or have space for partly store only in specific slot + uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); // in specific bag if (bag != NULL_BAG) @@ -10447,7 +10458,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des return EQUIP_ERR_ITEM_MAX_COUNT; } - res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START, INVENTORY_SLOT_ITEM_END, dest, pProto, count, true, pItem, bag, slot); + res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START, inventoryEnd, dest, pProto, count, true, pItem, bag, slot); if (res != EQUIP_ERR_OK) { if (no_space_count) @@ -10535,7 +10546,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des } } - res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START, INVENTORY_SLOT_ITEM_END, dest, pProto, count, false, pItem, bag, slot); + res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START, inventoryEnd, dest, pProto, count, false, pItem, bag, slot); if (res != EQUIP_ERR_OK) { if (no_space_count) @@ -10619,7 +10630,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des return EQUIP_ERR_ITEM_MAX_COUNT; } - res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START, INVENTORY_SLOT_ITEM_END, dest, pProto, count, true, pItem, bag, slot); + res = CanStoreItem_InInventorySlots(INVENTORY_SLOT_ITEM_START, inventoryEnd, dest, pProto, count, true, pItem, bag, slot); if (res != EQUIP_ERR_OK) { if (no_space_count) @@ -10747,7 +10758,7 @@ InventoryResult Player::CanStoreItem(uint8 bag, uint8 slot, ItemPosCountVec &des (pProto->GetBonding() == BIND_NONE || pProto->GetBonding() == BIND_ON_ACQUIRE)) searchSlotStart = INVENTORY_SLOT_BAG_START; - res = CanStoreItem_InInventorySlots(searchSlotStart, INVENTORY_SLOT_ITEM_END, dest, pProto, count, false, pItem, bag, slot); + res = CanStoreItem_InInventorySlots(searchSlotStart, inventoryEnd, dest, pProto, count, false, pItem, bag, slot); if (res != EQUIP_ERR_OK) { if (no_space_count) @@ -10800,7 +10811,8 @@ InventoryResult Player::CanStoreItems(Item** items, int count, uint32* offending memset(inventoryCounts, 0, sizeof(uint32) * (INVENTORY_SLOT_ITEM_END - INVENTORY_SLOT_ITEM_START)); memset(bagCounts, 0, sizeof(uint32) * (INVENTORY_SLOT_BAG_END - INVENTORY_SLOT_BAG_START) * MAX_BAG_SIZE); - for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) + uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); + for (uint8 i = INVENTORY_SLOT_ITEM_START; i < inventoryEnd; i++) { item2 = GetItemByPos(INVENTORY_SLOT_BAG_0, i); if (item2 && !item2->IsInTrade()) @@ -10853,7 +10865,7 @@ InventoryResult Player::CanStoreItems(Item** items, int count, uint32* offending { bool b_found = false; - for (int t = INVENTORY_SLOT_ITEM_START; t < INVENTORY_SLOT_ITEM_END; ++t) + for (int t = INVENTORY_SLOT_ITEM_START; t < inventoryEnd; ++t) { item2 = GetItemByPos(INVENTORY_SLOT_BAG_0, t); if (item2 && item2->CanBeMergedPartlyWith(pProto) == EQUIP_ERR_OK && inventoryCounts[t-INVENTORY_SLOT_ITEM_START] + item->GetCount() <= pProto->GetMaxStackSize()) @@ -10922,7 +10934,7 @@ InventoryResult Player::CanStoreItems(Item** items, int count, uint32* offending // search free slot bool b_found = false; - for (int t = INVENTORY_SLOT_ITEM_START; t < INVENTORY_SLOT_ITEM_END; ++t) + for (int t = INVENTORY_SLOT_ITEM_START; t < inventoryEnd; ++t) { if (inventoryCounts[t-INVENTORY_SLOT_ITEM_START] == 0) { @@ -12328,7 +12340,8 @@ void Player::DestroyItemCount(uint32 itemEntry, uint32 count, bool update, bool uint32 remcount = 0; // in inventory - for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; ++i) + uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); + for (uint8 i = INVENTORY_SLOT_ITEM_START; i < inventoryEnd; ++i) { if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) { @@ -12548,7 +12561,8 @@ void Player::DestroyZoneLimitedItem(bool update, uint32 new_zone) GetMapId(), new_zone, GetName().c_str(), GetGUID().ToString().c_str()); // in inventory - for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) + uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); + for (uint8 i = INVENTORY_SLOT_ITEM_START; i < inventoryEnd; i++) if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) if (pItem->IsLimitedToAnotherMapOrZone(GetMapId(), new_zone)) DestroyItem(INVENTORY_SLOT_BAG_0, i, update); @@ -12576,7 +12590,8 @@ void Player::DestroyConjuredItems(bool update) GetName().c_str(), GetGUID().ToString().c_str()); // in inventory - for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) + uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); + for (uint8 i = INVENTORY_SLOT_ITEM_START; i < inventoryEnd; i++) if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) if (pItem->IsConjuredConsumable()) DestroyItem(INVENTORY_SLOT_BAG_0, i, update); @@ -12599,7 +12614,8 @@ void Player::DestroyConjuredItems(bool update) Item* Player::GetItemByEntry(uint32 entry) const { // in inventory - for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; ++i) + uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); + for (uint8 i = INVENTORY_SLOT_ITEM_START; i < inventoryEnd; ++i) if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) if (pItem->GetEntry() == entry) return pItem; @@ -12628,7 +12644,8 @@ std::vector<Item*> Player::GetItemListByEntry(uint32 entry, bool inBankAlso) con { std::vector<Item*> itemList = std::vector<Item*>(); - for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; ++i) + uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); + for (uint8 i = INVENTORY_SLOT_ITEM_START; i < inventoryEnd; ++i) if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) if (item->GetEntry() == entry) itemList.push_back(item); @@ -13541,7 +13558,8 @@ void Player::RemoveArenaEnchantments(EnchantmentSlot slot) // remove enchants from inventory items // NOTE: no need to remove these from stats, since these aren't equipped // in inventory - for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; ++i) + uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + GetInventorySlotCount(); + for (uint8 i = INVENTORY_SLOT_ITEM_START; i < inventoryEnd; ++i) if (Item* pItem = GetItemByPos(INVENTORY_SLOT_BAG_0, i)) if (pItem->GetEnchantmentId(slot)) pItem->ClearEnchantment(slot); @@ -17377,17 +17395,17 @@ bool Player::IsLoading() const bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) { - // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 - //"SELECT guid, account, name, race, class, gender, level, xp, money, skin, face, hairStyle, hairColor, facialStyle, customDisplay1, customDisplay2, customDisplay3, bankSlots, restState, playerFlags, playerFlagsEx, " - // 21 22 23 24 25 26 27 28 29 30 31 32 33 + // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 + //"SELECT guid, account, name, race, class, gender, level, xp, money, skin, face, hairStyle, hairColor, facialStyle, customDisplay1, customDisplay2, customDisplay3, inventorySlots, bankSlots, restState, playerFlags, playerFlagsEx, " + // 22 23 24 25 26 27 28 29 30 31 32 33 34 //"position_x, position_y, position_z, map, orientation, taximask, cinematic, totaltime, leveltime, rest_bonus, logout_time, is_logout_resting, resettalents_cost, " - // 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 + // 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 //"resettalents_time, primarySpecialization, trans_x, trans_y, trans_z, trans_o, transguid, extra_flags, stable_slots, at_login, zone, online, death_expire_time, taxi_path, dungeonDifficulty, " - // 49 50 51 52 53 54 + // 50 51 52 53 54 55 //"totalKills, todayKills, yesterdayKills, chosenTitle, watchedFaction, drunk, " - // 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 + // 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 //"health, power1, power2, power3, power4, power5, power6, instance_id, activeTalentGroup, lootSpecId, exploredZones, knownTitles, actionBars, grantableLevels, raidDifficulty, legacyRaidDifficulty, fishing_steps " - // 72 73 74 75 76 + // 73 74 75 76 77 //"honor, honorLevel, prestigeLevel, honor_rest_state, honor_rest_bonus " // //"FROM characters WHERE guid = ?", CONNECTION_ASYNC); @@ -17459,8 +17477,8 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) SetUInt32Value(UNIT_FIELD_LEVEL, fields[6].GetUInt8()); SetXP(fields[7].GetUInt32()); - _LoadIntoDataField(fields[65].GetString(), PLAYER_EXPLORED_ZONES_1, PLAYER_EXPLORED_ZONES_SIZE); - _LoadIntoDataField(fields[66].GetString(), PLAYER__FIELD_KNOWN_TITLES, KNOWN_TITLES_SIZE * 2); + _LoadIntoDataField(fields[66].GetString(), PLAYER_EXPLORED_ZONES_1, PLAYER_EXPLORED_ZONES_SIZE); + _LoadIntoDataField(fields[67].GetString(), PLAYER__FIELD_KNOWN_TITLES, KNOWN_TITLES_SIZE * 2); SetObjectScale(1.0f); SetFloatValue(UNIT_FIELD_HOVERHEIGHT, 1.0f); @@ -17486,12 +17504,13 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) SetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_FACIAL_STYLE, fields[13].GetUInt8()); for (uint32 i = 0; i < PLAYER_CUSTOM_DISPLAY_SIZE; ++i) SetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_CUSTOM_DISPLAY_OPTION + i, customDisplay[i]); - SetBankBagSlotCount(fields[17].GetUInt8()); + SetInventorySlotCount(fields[17].GetUInt8()); + SetBankBagSlotCount(fields[18].GetUInt8()); SetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_GENDER, gender); - SetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_INEBRIATION, fields[54].GetUInt8()); - SetUInt32Value(PLAYER_FLAGS, fields[19].GetUInt32()); - SetUInt32Value(PLAYER_FLAGS_EX, fields[20].GetUInt32()); - SetInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, fields[53].GetUInt32()); + SetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_INEBRIATION, fields[55].GetUInt8()); + SetUInt32Value(PLAYER_FLAGS, fields[20].GetUInt32()); + SetUInt32Value(PLAYER_FLAGS_EX, fields[21].GetUInt32()); + SetInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, fields[54].GetUInt32()); if (!ValidateAppearance( fields[3].GetUInt8(), // race @@ -17509,9 +17528,9 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) } // set which actionbars the client has active - DO NOT REMOVE EVER AGAIN (can be changed though, if it does change fieldwise) - SetByteValue(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTES_OFFSET_ACTION_BAR_TOGGLES, fields[67].GetUInt8()); + SetByteValue(PLAYER_FIELD_BYTES, PLAYER_FIELD_BYTES_OFFSET_ACTION_BAR_TOGGLES, fields[68].GetUInt8()); - m_fishingSteps = fields[71].GetUInt8(); + m_fishingSteps = fields[72].GetUInt8(); InitDisplayIds(); @@ -17539,18 +17558,18 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) InitPrimaryProfessions(); // to max set before any spell loaded // init saved position, and fix it later if problematic - ObjectGuid::LowType transLowGUID = fields[40].GetUInt64(); + ObjectGuid::LowType transLowGUID = fields[41].GetUInt64(); - Relocate(fields[21].GetFloat(), fields[22].GetFloat(), fields[23].GetFloat(), fields[25].GetFloat()); + Relocate(fields[22].GetFloat(), fields[23].GetFloat(), fields[24].GetFloat(), fields[26].GetFloat()); - uint32 mapId = fields[24].GetUInt16(); - uint32 instanceId = fields[62].GetUInt32(); + uint32 mapId = fields[25].GetUInt16(); + uint32 instanceId = fields[63].GetUInt32(); - SetDungeonDifficultyID(CheckLoadedDungeonDifficultyID(Difficulty(fields[48].GetUInt8()))); - SetRaidDifficultyID(CheckLoadedRaidDifficultyID(Difficulty(fields[69].GetUInt8()))); - SetLegacyRaidDifficultyID(CheckLoadedLegacyRaidDifficultyID(Difficulty(fields[70].GetUInt8()))); + SetDungeonDifficultyID(CheckLoadedDungeonDifficultyID(Difficulty(fields[49].GetUInt8()))); + SetRaidDifficultyID(CheckLoadedRaidDifficultyID(Difficulty(fields[70].GetUInt8()))); + SetLegacyRaidDifficultyID(CheckLoadedLegacyRaidDifficultyID(Difficulty(fields[71].GetUInt8()))); - std::string taxi_nodes = fields[47].GetString(); + std::string taxi_nodes = fields[48].GetString(); #define RelocateToHomebind(){ mapId = m_homebindMapId; instanceId = 0; Relocate(m_homebindX, m_homebindY, m_homebindZ); } @@ -17575,9 +17594,9 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) } _LoadCurrency(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_CURRENCY)); - SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, fields[49].GetUInt32()); - SetUInt16Value(PLAYER_FIELD_KILLS, PLAYER_FIELD_KILLS_OFFSET_TODAY_KILLS, fields[50].GetUInt16()); - SetUInt16Value(PLAYER_FIELD_KILLS, PLAYER_FIELD_KILLS_OFFSET_YESTERDAY_KILLS, fields[51].GetUInt16()); + SetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS, fields[50].GetUInt32()); + SetUInt16Value(PLAYER_FIELD_KILLS, PLAYER_FIELD_KILLS_OFFSET_TODAY_KILLS, fields[51].GetUInt16()); + SetUInt16Value(PLAYER_FIELD_KILLS, PLAYER_FIELD_KILLS_OFFSET_YESTERDAY_KILLS, fields[52].GetUInt16()); _LoadBoundInstances(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_BOUND_INSTANCES)); _LoadInstanceTimeRestrictions(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_INSTANCE_LOCK_TIMES)); @@ -17658,7 +17677,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) if (transport) { - float x = fields[36].GetFloat(), y = fields[37].GetFloat(), z = fields[38].GetFloat(), o = fields[39].GetFloat(); + float x = fields[37].GetFloat(), y = fields[38].GetFloat(), z = fields[39].GetFloat(), o = fields[40].GetFloat(); m_movementInfo.transport.pos.Relocate(x, y, z, o); transport->CalculatePassengerPosition(x, y, z, &o); @@ -17852,7 +17871,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) SaveRecallPosition(); time_t now = time(nullptr); - time_t logoutTime = time_t(fields[31].GetUInt32()); + time_t logoutTime = time_t(fields[32].GetUInt32()); // since last logout (in seconds) uint32 time_diff = uint32(now - logoutTime); //uint64 is excessive for a time_diff in seconds.. uint32 allows for 136~ year difference. @@ -17865,18 +17884,18 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) SetDrunkValue(newDrunkValue); - m_cinematic = fields[27].GetUInt8(); - m_Played_time[PLAYED_TIME_TOTAL] = fields[28].GetUInt32(); - m_Played_time[PLAYED_TIME_LEVEL] = fields[29].GetUInt32(); + m_cinematic = fields[28].GetUInt8(); + m_Played_time[PLAYED_TIME_TOTAL] = fields[29].GetUInt32(); + m_Played_time[PLAYED_TIME_LEVEL] = fields[30].GetUInt32(); - SetTalentResetCost(fields[33].GetUInt32()); - SetTalentResetTime(time_t(fields[34].GetUInt32())); + SetTalentResetCost(fields[34].GetUInt32()); + SetTalentResetTime(time_t(fields[35].GetUInt32())); - m_taxi.LoadTaxiMask(fields[26].GetString()); // must be before InitTaxiNodesForLevel + m_taxi.LoadTaxiMask(fields[27].GetString()); // must be before InitTaxiNodesForLevel - uint32 extraflags = fields[41].GetUInt16(); + uint32 extraflags = fields[42].GetUInt16(); - m_stableSlots = fields[42].GetUInt8(); + m_stableSlots = fields[43].GetUInt8(); if (m_stableSlots > MAX_PET_STABLES) { TC_LOG_ERROR("entities.player", "Player::LoadFromDB: Player (%s) can't have more stable slots than %u, but has %u in DB", @@ -17884,7 +17903,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) m_stableSlots = MAX_PET_STABLES; } - m_atLoginFlags = fields[43].GetUInt16(); + m_atLoginFlags = fields[44].GetUInt16(); if (HasAtLoginFlag(AT_LOGIN_RENAME)) { @@ -17897,7 +17916,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) m_lastHonorUpdateTime = logoutTime; UpdateHonorFields(); - m_deathExpireTime = time_t(fields[46].GetUInt32()); + m_deathExpireTime = time_t(fields[47].GetUInt32()); if (m_deathExpireTime > now + MAX_DEATH_COUNT * DEATH_EXPIRE_STEP) m_deathExpireTime = now + MAX_DEATH_COUNT * DEATH_EXPIRE_STEP - 1; @@ -17929,19 +17948,19 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) InitRunes(); // rest bonus can only be calculated after InitStatsForLevel() - _restMgr->LoadRestBonus(REST_TYPE_XP, PlayerRestState(fields[18].GetUInt8()), fields[30].GetFloat()); + _restMgr->LoadRestBonus(REST_TYPE_XP, PlayerRestState(fields[19].GetUInt8()), fields[31].GetFloat()); // load skills after InitStatsForLevel because it triggering aura apply also _LoadSkills(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_SKILLS)); UpdateSkillsForLevel(); //update skills after load, to make sure they are correctly update at player load - SetPrimarySpecialization(fields[35].GetUInt32()); - SetActiveTalentGroup(fields[63].GetUInt8()); + SetPrimarySpecialization(fields[36].GetUInt32()); + SetActiveTalentGroup(fields[64].GetUInt8()); ChrSpecializationEntry const* primarySpec = sChrSpecializationStore.LookupEntry(GetPrimarySpecialization()); if (!primarySpec || primarySpec->ClassID != getClass() || GetActiveTalentGroup() >= MAX_SPECIALIZATIONS) ResetTalentSpecialization(); - uint32 lootSpecId = fields[64].GetUInt32(); + uint32 lootSpecId = fields[65].GetUInt32(); if (ChrSpecializationEntry const* chrSpec = sChrSpecializationStore.LookupEntry(lootSpecId)) if (chrSpec->ClassID == getClass()) SetLootSpecId(lootSpecId); @@ -18001,7 +18020,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) // check PLAYER_CHOSEN_TITLE compatibility with PLAYER__FIELD_KNOWN_TITLES // note: PLAYER__FIELD_KNOWN_TITLES updated at quest status loaded - uint32 curTitle = fields[52].GetUInt32(); + uint32 curTitle = fields[53].GetUInt32(); if (curTitle && !HasTitle(curTitle)) curTitle = 0; @@ -18024,7 +18043,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) UpdateAllStats(); // restore remembered power/health values (but not more max values) - uint32 savedHealth = fields[55].GetUInt32(); + uint32 savedHealth = fields[56].GetUInt32(); SetHealth(savedHealth > GetMaxHealth() ? GetMaxHealth() : savedHealth); uint32 loadedPowers = 0; for (uint32 i = 0; i < MAX_POWERS; ++i) @@ -18108,7 +18127,7 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) } // RaF stuff. - m_grantableLevels = fields[68].GetUInt8(); + m_grantableLevels = fields[69].GetUInt8(); if (GetSession()->IsARecruiter() || (GetSession()->GetRecruiterId() != 0)) SetFlag(OBJECT_DYNAMIC_FLAGS, UNIT_DYNFLAG_REFER_A_FRIEND); @@ -18130,16 +18149,16 @@ bool Player::LoadFromDB(ObjectGuid guid, SQLQueryHolder *holder) holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOAD_GARRISON_FOLLOWER_ABILITIES))) _garrison = std::move(garrison); - _InitHonorLevelOnLoadFromDB(fields[72].GetUInt32(), fields[73].GetUInt32(), fields[74].GetUInt32()); + _InitHonorLevelOnLoadFromDB(fields[73].GetUInt32(), fields[74].GetUInt32(), fields[75].GetUInt32()); - _restMgr->LoadRestBonus(REST_TYPE_HONOR, PlayerRestState(fields[75].GetUInt8()), fields[76].GetFloat()); + _restMgr->LoadRestBonus(REST_TYPE_HONOR, PlayerRestState(fields[76].GetUInt8()), fields[77].GetFloat()); if (time_diff > 0) { //speed collect rest bonus in offline, in logout, far from tavern, city (section/in hour) float bubble0 = 0.031f; //speed collect rest bonus in offline, in logout, in tavern, city (section/in hour) float bubble1 = 0.125f; - float bubble = fields[31].GetUInt8() > 0 + float bubble = fields[32].GetUInt8() > 0 ? bubble1 * sWorld->getRate(RATE_REST_OFFLINE_IN_TAVERN_OR_CITY) : bubble0 * sWorld->getRate(RATE_REST_OFFLINE_IN_WILDERNESS); @@ -19767,6 +19786,7 @@ void Player::SaveToDB(bool create /*=false*/) stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_FACIAL_STYLE)); for (uint32 i = 0; i < PLAYER_CUSTOM_DISPLAY_SIZE; ++i) stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_CUSTOM_DISPLAY_OPTION + i)); + stmt->setUInt8(index++, GetInventorySlotCount()); stmt->setUInt8(index++, GetBankBagSlotCount()); stmt->setUInt8(index++, uint8(GetUInt32Value(PLAYER_FIELD_REST_INFO + REST_STATE_XP))); stmt->setUInt32(index++, GetUInt32Value(PLAYER_FLAGS)); @@ -19892,6 +19912,7 @@ void Player::SaveToDB(bool create /*=false*/) stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_FACIAL_STYLE)); for (uint32 i = 0; i < PLAYER_CUSTOM_DISPLAY_SIZE; ++i) stmt->setUInt8(index++, GetByteValue(PLAYER_BYTES_2, PLAYER_BYTES_2_OFFSET_CUSTOM_DISPLAY_OPTION + i)); + stmt->setUInt8(index++, GetInventorySlotCount()); stmt->setUInt8(index++, GetBankBagSlotCount()); stmt->setUInt8(index++, uint8(GetUInt32Value(PLAYER_FIELD_REST_INFO + REST_STATE_XP))); stmt->setUInt32(index++, GetUInt32Value(PLAYER_FLAGS)); @@ -24673,33 +24694,30 @@ void Player::RemoveItemDependentAurasAndCasts(Item* pItem) InterruptSpell(CurrentSpellTypes(i)); } -uint32 Player::GetResurrectionSpellId() const +void Player::InitializeSelfResurrectionSpells() { - // search priceless resurrection possibilities - uint32 prio = 0; - uint32 spell_id = 0; + ClearDynamicValue(PLAYER_DYNAMIC_FIELD_SELF_RES_SPELLS); + + uint32 spells[3] = { }; + AuraEffectList const& dummyAuras = GetAuraEffectsByType(SPELL_AURA_DUMMY); for (AuraEffectList::const_iterator itr = dummyAuras.begin(); itr != dummyAuras.end(); ++itr) { // Soulstone Resurrection // prio: 3 (max, non death persistent) - if (prio < 2 && (*itr)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_WARLOCK && (*itr)->GetSpellInfo()->SpellFamilyFlags[1] & 0x1000000) - { - spell_id = 3026; - prio = 3; - } + if ((*itr)->GetSpellInfo()->SpellFamilyName == SPELLFAMILY_WARLOCK && (*itr)->GetSpellInfo()->SpellFamilyFlags[1] & 0x1000000) + spells[0] = 3026; // Twisting Nether // prio: 2 (max) else if ((*itr)->GetId() == 23701 && roll_chance_i(10)) - { - prio = 2; - spell_id = 23700; - } + spells[1] = 23700; } // Reincarnation (passive spell) // prio: 1 - if (prio < 1 && HasSpell(20608) && !GetSpellHistory()->HasCooldown(21169)) - spell_id = 21169; + if (HasSpell(20608) && !GetSpellHistory()->HasCooldown(21169)) + spells[2] = 21169; - return spell_id; + for (uint32 selfResSpell : spells) + if (selfResSpell) + AddDynamicValue(PLAYER_DYNAMIC_FIELD_SELF_RES_SPELLS, selfResSpell); } // Used in triggers for check "Only to targets that grant experience or honor" req diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index bf60ebb1122..02f97985629 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -446,7 +446,7 @@ enum PlayerBytesOffsets enum PlayerBytes2Offsets { PLAYER_BYTES_2_OFFSET_CUSTOM_DISPLAY_OPTION = 0, // 3 bytes - PLAYER_BYTES_2_OFFSET_FACIAL_STYLE = 3, + PLAYER_BYTES_2_OFFSET_FACIAL_STYLE = 3 }; enum PlayerBytes3Offsets @@ -454,7 +454,7 @@ enum PlayerBytes3Offsets PLAYER_BYTES_3_OFFSET_PARTY_TYPE = 0, PLAYER_BYTES_3_OFFSET_BANK_BAG_SLOTS = 1, PLAYER_BYTES_3_OFFSET_GENDER = 2, - PLAYER_BYTES_3_OFFSET_INEBRIATION = 3, + PLAYER_BYTES_3_OFFSET_INEBRIATION = 3 }; enum PlayerBytes4Offsets @@ -468,13 +468,14 @@ enum PlayerFieldBytesOffsets PLAYER_FIELD_BYTES_OFFSET_RAF_GRANTABLE_LEVEL = 0, PLAYER_FIELD_BYTES_OFFSET_ACTION_BAR_TOGGLES = 1, PLAYER_FIELD_BYTES_OFFSET_LIFETIME_MAX_PVP_RANK = 2, - PLAYER_FIELD_BYTES_OFFSET_NUM_RESPECS = 3, + PLAYER_FIELD_BYTES_OFFSET_NUM_RESPECS = 3 }; enum PlayerFieldBytes2Offsets { PLAYER_FIELD_BYTES_2_OFFSET_IGNORE_POWER_REGEN_PREDICTION_MASK = 0, PLAYER_FIELD_BYTES_2_OFFSET_AURA_VISION = 1, + PLAYER_FIELD_BYTES_2_OFFSET_NUM_BACKPACK_SLOTS = 2 }; enum PlayerFieldBytes3Offsets @@ -604,11 +605,12 @@ enum PlayerSlots // first slot for item stored (in any way in player m_items data) PLAYER_SLOT_START = 0, // last+1 slot for item stored (in any way in player m_items data) - PLAYER_SLOT_END = 187, + PLAYER_SLOT_END = 195, PLAYER_SLOTS_COUNT = (PLAYER_SLOT_END - PLAYER_SLOT_START) }; #define INVENTORY_SLOT_BAG_0 255 +#define INVENTORY_DEFAULT_SIZE 16 enum EquipmentSlots : uint8 // 19 slots { @@ -644,41 +646,41 @@ enum InventorySlots : uint8 // 4 slots INVENTORY_SLOT_BAG_END = 23 }; -enum InventoryPackSlots : uint8 // 16 slots +enum InventoryPackSlots : uint8 // 24 slots { INVENTORY_SLOT_ITEM_START = 23, - INVENTORY_SLOT_ITEM_END = 39 + INVENTORY_SLOT_ITEM_END = 47 }; enum BankItemSlots // 28 slots { - BANK_SLOT_ITEM_START = 39, - BANK_SLOT_ITEM_END = 67 + BANK_SLOT_ITEM_START = 47, + BANK_SLOT_ITEM_END = 75 }; enum BankBagSlots // 7 slots { - BANK_SLOT_BAG_START = 67, - BANK_SLOT_BAG_END = 74 + BANK_SLOT_BAG_START = 75, + BANK_SLOT_BAG_END = 82 }; enum BuyBackSlots // 12 slots { // stored in m_buybackitems - BUYBACK_SLOT_START = 74, - BUYBACK_SLOT_END = 86 + BUYBACK_SLOT_START = 82, + BUYBACK_SLOT_END = 94 }; -enum ReagentSlots +enum ReagentSlots // 98 slots { - REAGENT_SLOT_START = 87, - REAGENT_SLOT_END = 184, + REAGENT_SLOT_START = 94, + REAGENT_SLOT_END = 192, }; enum ChildEquipmentSlots { - CHILD_EQUIPMENT_SLOT_START = 184, - CHILD_EQUIPMENT_SLOT_END = 187, + CHILD_EQUIPMENT_SLOT_START = 192, + CHILD_EQUIPMENT_SLOT_END = 195, }; struct ItemPosCount @@ -1178,6 +1180,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> static bool IsChildEquipmentPos(uint8 bag, uint8 slot); bool IsValidPos(uint16 pos, bool explicit_pos) const { return IsValidPos(pos >> 8, pos & 255, explicit_pos); } bool IsValidPos(uint8 bag, uint8 slot, bool explicit_pos) const; + uint8 GetInventorySlotCount() const { return GetByteValue(PLAYER_FIELD_BYTES2, PLAYER_FIELD_BYTES_2_OFFSET_NUM_BACKPACK_SLOTS); } + void SetInventorySlotCount(uint8 slots); uint8 GetBankBagSlotCount() const { return GetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_BANK_BAG_SLOTS); } void SetBankBagSlotCount(uint8 count) { SetByteValue(PLAYER_BYTES_3, PLAYER_BYTES_3_OFFSET_BANK_BAG_SLOTS, count); } bool HasItemCount(uint32 item, uint32 count = 1, bool inBankAlso = false) const; @@ -1858,7 +1862,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player> static void OfflineResurrect(ObjectGuid const& guid, SQLTransaction& trans); bool HasCorpse() const { return _corpseLocation.GetMapId() != MAPID_INVALID; } WorldLocation GetCorpseLocation() const { return _corpseLocation; } - uint32 GetResurrectionSpellId() const; + void InitializeSelfResurrectionSpells(); void ResurrectPlayer(float restore_percent, bool applySickness = false); void BuildPlayerRepop(); void RepopAtGraveyard(); diff --git a/src/server/game/Handlers/SpellHandler.cpp b/src/server/game/Handlers/SpellHandler.cpp index d3e8db0004a..ca011dfd61f 100644 --- a/src/server/game/Handlers/SpellHandler.cpp +++ b/src/server/game/Handlers/SpellHandler.cpp @@ -461,19 +461,20 @@ void WorldSession::HandleTotemDestroyed(WorldPackets::Totem::TotemDestroyed& tot totem->ToTotem()->UnSummon(); } -void WorldSession::HandleSelfResOpcode(WorldPackets::Spells::SelfRes& /*packet*/) +void WorldSession::HandleSelfResOpcode(WorldPackets::Spells::SelfRes& selfRes) { if (_player->HasAuraType(SPELL_AURA_PREVENT_RESURRECTION)) return; // silent return, client should display error by itself and not send this opcode - if (_player->GetUInt32Value(PLAYER_SELF_RES_SPELL)) - { - SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(_player->GetUInt32Value(PLAYER_SELF_RES_SPELL)); - if (spellInfo) - _player->CastSpell(_player, spellInfo, false, nullptr); + std::vector<uint32> const& selfResSpells = _player->GetDynamicValues(PLAYER_DYNAMIC_FIELD_SELF_RES_SPELLS); + if (std::find(selfResSpells.begin(), selfResSpells.end(), selfRes.SpellID) == selfResSpells.end()) + return; - _player->SetUInt32Value(PLAYER_SELF_RES_SPELL, 0); - } + SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(selfRes.SpellID); + if (spellInfo) + _player->CastSpell(_player, spellInfo, false, nullptr); + + _player->RemoveDynamicValue(PLAYER_DYNAMIC_FIELD_SELF_RES_SPELLS, selfRes.SpellID); } void WorldSession::HandleSpellClick(WorldPackets::Spells::SpellClick& spellClick) diff --git a/src/server/game/Handlers/VoidStorageHandler.cpp b/src/server/game/Handlers/VoidStorageHandler.cpp index a26592ca0e3..488eb7f911a 100644 --- a/src/server/game/Handlers/VoidStorageHandler.cpp +++ b/src/server/game/Handlers/VoidStorageHandler.cpp @@ -122,7 +122,8 @@ void WorldSession::HandleVoidStorageTransfer(WorldPackets::VoidStorage::VoidStor if (Bag* bag = _player->GetBagByPos(i)) freeBagSlots += bag->GetFreeSlots(); - for (uint8 i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; i++) + uint8 inventoryEnd = INVENTORY_SLOT_ITEM_START + _player->GetInventorySlotCount(); + for (uint8 i = INVENTORY_SLOT_ITEM_START; i < inventoryEnd; i++) if (!_player->GetItemByPos(INVENTORY_SLOT_BAG_0, i)) ++freeBagSlots; } diff --git a/src/server/game/Server/Packets/SpellPackets.cpp b/src/server/game/Server/Packets/SpellPackets.cpp index 72a2831881b..c0bee056145 100644 --- a/src/server/game/Server/Packets/SpellPackets.cpp +++ b/src/server/game/Server/Packets/SpellPackets.cpp @@ -821,6 +821,11 @@ void WorldPackets::Spells::UnlearnSkill::Read() _worldPacket >> SkillLine; } +void WorldPackets::Spells::SelfRes::Read() +{ + _worldPacket >> SpellID; +} + void WorldPackets::Spells::GetMirrorImageData::Read() { _worldPacket >> UnitGUID; diff --git a/src/server/game/Server/Packets/SpellPackets.h b/src/server/game/Server/Packets/SpellPackets.h index a5778e6faf8..80c40f5c715 100644 --- a/src/server/game/Server/Packets/SpellPackets.h +++ b/src/server/game/Server/Packets/SpellPackets.h @@ -823,7 +823,9 @@ namespace WorldPackets public: SelfRes(WorldPacket&& packet) : ClientPacket(CMSG_SELF_RES, std::move(packet)) { } - void Read() override { } + void Read() override; + + int32 SpellID = 0; }; class GetMirrorImageData final : public ClientPacket diff --git a/src/server/game/Server/WorldSession.h b/src/server/game/Server/WorldSession.h index 51f604a3e23..8e9ecabfded 100644 --- a/src/server/game/Server/WorldSession.h +++ b/src/server/game/Server/WorldSession.h @@ -1565,7 +1565,7 @@ class TC_GAME_API WorldSession void SendLfgOfferContinue(uint32 dungeonEntry); void SendLfgTeleportError(lfg::LfgTeleportResult err); - void HandleSelfResOpcode(WorldPackets::Spells::SelfRes& packet); + void HandleSelfResOpcode(WorldPackets::Spells::SelfRes& selfRes); void HandleRequestPetInfo(WorldPackets::Pet::RequestPetInfo& packet); // Socket gem |