mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
feat: track and display WotLK server-authoritative combat stats
Adds update field tracking for WotLK secondary combat statistics: - UNIT_FIELD_ATTACK_POWER / RANGED_ATTACK_POWER (fields 123, 126) - PLAYER_DODGE/PARRY/BLOCK/CRIT_PERCENTAGE (fields 1025-1029) - PLAYER_RANGED_CRIT_PERCENTAGE, PLAYER_SPELL_CRIT_PERCENTAGE1 (1030, 1032) - PLAYER_FIELD_COMBAT_RATING_1 (25 slots at 1231, hit/expertise/haste/etc.) Both CREATE_OBJECT and VALUES update paths now populate these fields. The Character screen Stats tab shows them when received from the server, with graceful fallback when not available (Classic/TBC expansions). Field indices verified against AzerothCore 3.3.5a UpdateFields.h.
This commit is contained in:
parent
ea7b276125
commit
c0ffca68f2
7 changed files with 166 additions and 3 deletions
|
|
@ -309,6 +309,31 @@ public:
|
|||
return playerStats_[idx];
|
||||
}
|
||||
|
||||
// Server-authoritative attack power (WotLK: UNIT_FIELD_ATTACK_POWER / RANGED).
|
||||
// Returns -1 if not yet received.
|
||||
int32_t getMeleeAttackPower() const { return playerMeleeAP_; }
|
||||
int32_t getRangedAttackPower() const { return playerRangedAP_; }
|
||||
|
||||
// Server-authoritative combat chance percentages (WotLK: PLAYER_* float fields).
|
||||
// Returns -1.0f if not yet received.
|
||||
float getDodgePct() const { return playerDodgePct_; }
|
||||
float getParryPct() const { return playerParryPct_; }
|
||||
float getBlockPct() const { return playerBlockPct_; }
|
||||
float getCritPct() const { return playerCritPct_; }
|
||||
float getRangedCritPct() const { return playerRangedCritPct_; }
|
||||
// Spell crit by school (0=Physical,1=Holy,2=Fire,3=Nature,4=Frost,5=Shadow,6=Arcane)
|
||||
float getSpellCritPct(int school = 1) const {
|
||||
if (school < 0 || school > 6) return -1.0f;
|
||||
return playerSpellCritPct_[school];
|
||||
}
|
||||
|
||||
// Server-authoritative combat ratings (WotLK: PLAYER_FIELD_COMBAT_RATING_1+idx).
|
||||
// Returns -1 if not yet received. Indices match AzerothCore CombatRating enum.
|
||||
int32_t getCombatRating(int cr) const {
|
||||
if (cr < 0 || cr > 24) return -1;
|
||||
return playerCombatRatings_[cr];
|
||||
}
|
||||
|
||||
// Inventory
|
||||
Inventory& getInventory() { return inventory; }
|
||||
const Inventory& getInventory() const { return inventory; }
|
||||
|
|
@ -2792,6 +2817,16 @@ private:
|
|||
int32_t playerResistances_[6] = {}; // [0]=Holy,[1]=Fire,[2]=Nature,[3]=Frost,[4]=Shadow,[5]=Arcane
|
||||
// Server-authoritative primary stats: [0]=STR [1]=AGI [2]=STA [3]=INT [4]=SPI; -1 = not received yet
|
||||
int32_t playerStats_[5] = {-1, -1, -1, -1, -1};
|
||||
// WotLK secondary combat stats (-1 = not yet received)
|
||||
int32_t playerMeleeAP_ = -1;
|
||||
int32_t playerRangedAP_ = -1;
|
||||
float playerDodgePct_ = -1.0f;
|
||||
float playerParryPct_ = -1.0f;
|
||||
float playerBlockPct_ = -1.0f;
|
||||
float playerCritPct_ = -1.0f;
|
||||
float playerRangedCritPct_ = -1.0f;
|
||||
float playerSpellCritPct_[7] = {-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,-1.0f,-1.0f};
|
||||
int32_t playerCombatRatings_[25] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
|
||||
// Some servers/custom clients shift update field indices. We can auto-detect coinage by correlating
|
||||
// money-notify deltas with update-field diffs and then overriding UF::PLAYER_FIELD_COINAGE at runtime.
|
||||
uint32_t pendingMoneyDelta_ = 0;
|
||||
|
|
|
|||
|
|
@ -42,6 +42,10 @@ enum class UF : uint16_t {
|
|||
UNIT_FIELD_STAT4, // Spirit
|
||||
UNIT_END,
|
||||
|
||||
// Unit combat fields (WotLK: PRIVATE+OWNER — only visible for the player character)
|
||||
UNIT_FIELD_ATTACK_POWER, // Melee attack power (int32)
|
||||
UNIT_FIELD_RANGED_ATTACK_POWER, // Ranged attack power (int32)
|
||||
|
||||
// Player fields
|
||||
PLAYER_FLAGS,
|
||||
PLAYER_BYTES,
|
||||
|
|
@ -59,6 +63,15 @@ enum class UF : uint16_t {
|
|||
PLAYER_EXPLORED_ZONES_START,
|
||||
PLAYER_CHOSEN_TITLE, // Active title index (-1 = no title)
|
||||
|
||||
// Player combat stats (WotLK: PRIVATE — float values)
|
||||
PLAYER_BLOCK_PERCENTAGE, // Block chance %
|
||||
PLAYER_DODGE_PERCENTAGE, // Dodge chance %
|
||||
PLAYER_PARRY_PERCENTAGE, // Parry chance %
|
||||
PLAYER_CRIT_PERCENTAGE, // Melee crit chance %
|
||||
PLAYER_RANGED_CRIT_PERCENTAGE, // Ranged crit chance %
|
||||
PLAYER_SPELL_CRIT_PERCENTAGE1, // Spell crit chance % (first school; 7 consecutive float fields)
|
||||
PLAYER_FIELD_COMBAT_RATING_1, // First of 25 int32 combat rating slots (CR_* indices)
|
||||
|
||||
// GameObject fields
|
||||
GAMEOBJECT_DISPLAYID,
|
||||
|
||||
|
|
|
|||
|
|
@ -149,7 +149,8 @@ private:
|
|||
void renderEquipmentPanel(game::Inventory& inventory);
|
||||
void renderBackpackPanel(game::Inventory& inventory, bool collapseEmptySections = false);
|
||||
void renderStatsPanel(game::Inventory& inventory, uint32_t playerLevel, int32_t serverArmor = 0,
|
||||
const int32_t* serverStats = nullptr, const int32_t* serverResists = nullptr);
|
||||
const int32_t* serverStats = nullptr, const int32_t* serverResists = nullptr,
|
||||
const game::GameHandler* gh = nullptr);
|
||||
void renderReputationPanel(game::GameHandler& gameHandler);
|
||||
|
||||
void renderItemSlot(game::Inventory& inventory, const game::ItemSlot& slot,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue