mirror of
https://github.com/mangosfour/server.git
synced 2025-12-25 13:37:02 +00:00
[11831] Implement player gear score calculation
Signed-off-by: Laise <fenrisse@gmail.com>
This commit is contained in:
parent
fdc68c580d
commit
70a8a350d7
11 changed files with 246 additions and 4 deletions
|
|
@ -553,6 +553,8 @@ Player::Player (WorldSession *session): Unit(), m_mover(this), m_camera(this), m
|
|||
|
||||
m_lastFallTime = 0;
|
||||
m_lastFallZ = 0;
|
||||
|
||||
m_cachedGS = 0;
|
||||
}
|
||||
|
||||
Player::~Player ()
|
||||
|
|
@ -22938,3 +22940,193 @@ void Player::SetRestType( RestType n_r_type, uint32 areaTriggerId /*= 0*/)
|
|||
SetFFAPvP(false);
|
||||
}
|
||||
}
|
||||
|
||||
uint32 Player::GetEquipGearScore(bool withBags, bool withBank)
|
||||
{
|
||||
if (withBags && withBank && m_cachedGS > 0)
|
||||
return m_cachedGS;
|
||||
|
||||
GearScoreVec gearScore (EQUIPMENT_SLOT_END);
|
||||
uint32 twoHandScore = 0;
|
||||
|
||||
for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
|
||||
{
|
||||
gearScore[i] = 0;
|
||||
}
|
||||
|
||||
for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
|
||||
{
|
||||
if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
|
||||
_fillGearScoreData(item, &gearScore, twoHandScore);
|
||||
}
|
||||
|
||||
if (withBags)
|
||||
{
|
||||
// check inventory
|
||||
for(int i = INVENTORY_SLOT_ITEM_START; i < INVENTORY_SLOT_ITEM_END; ++i)
|
||||
{
|
||||
if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
|
||||
_fillGearScoreData(item, &gearScore, twoHandScore);
|
||||
}
|
||||
|
||||
// check bags
|
||||
for(int i = INVENTORY_SLOT_BAG_START; i < INVENTORY_SLOT_BAG_END; ++i)
|
||||
{
|
||||
if(Bag* pBag = (Bag*)GetItemByPos(INVENTORY_SLOT_BAG_0, i))
|
||||
{
|
||||
for(uint32 j = 0; j < pBag->GetBagSize(); ++j)
|
||||
{
|
||||
if (Item* item2 = pBag->GetItemByPos(j))
|
||||
_fillGearScoreData(item2, &gearScore, twoHandScore);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (withBank)
|
||||
{
|
||||
for (uint8 i = BANK_SLOT_ITEM_START; i < BANK_SLOT_ITEM_END; ++i)
|
||||
{
|
||||
if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
|
||||
_fillGearScoreData(item, &gearScore, twoHandScore);
|
||||
}
|
||||
|
||||
for (uint8 i = BANK_SLOT_BAG_START; i < BANK_SLOT_BAG_END; ++i)
|
||||
{
|
||||
if (Item* item = GetItemByPos(INVENTORY_SLOT_BAG_0, i))
|
||||
{
|
||||
if (item->IsBag())
|
||||
{
|
||||
Bag* bag = (Bag*)item;
|
||||
for (uint8 j = 0; j < bag->GetBagSize(); ++j)
|
||||
{
|
||||
if (Item* item2 = bag->GetItemByPos(j))
|
||||
_fillGearScoreData(item2, &gearScore, twoHandScore);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8 count = EQUIPMENT_SLOT_END - 2; // ignore body and tabard slots
|
||||
uint32 sum = 0;
|
||||
|
||||
// check if 2h hand is higher level than main hand + off hand
|
||||
if ((gearScore[EQUIPMENT_SLOT_MAINHAND] + gearScore[EQUIPMENT_SLOT_OFFHAND]) / 2 < twoHandScore)
|
||||
{
|
||||
gearScore[EQUIPMENT_SLOT_OFFHAND] = 0; // off hand is ignored in calculations if 2h weapon has higher score
|
||||
--count;
|
||||
gearScore[EQUIPMENT_SLOT_MAINHAND] = twoHandScore;
|
||||
}
|
||||
|
||||
for (uint8 i = EQUIPMENT_SLOT_START; i < EQUIPMENT_SLOT_END; ++i)
|
||||
{
|
||||
sum += gearScore[i];
|
||||
}
|
||||
|
||||
if (count)
|
||||
{
|
||||
uint32 res = uint32(sum / count);
|
||||
DEBUG_LOG("Player: calculating gear score for %u. Result is %u", GetObjectGuid().GetCounter(), res);
|
||||
|
||||
if (withBags && withBank)
|
||||
m_cachedGS = res;
|
||||
|
||||
return res;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Player::_fillGearScoreData(Item* item, GearScoreVec* gearScore, uint32& twoHandScore)
|
||||
{
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
if (CanUseItem(item->GetProto()) != EQUIP_ERR_OK)
|
||||
return;
|
||||
|
||||
uint8 type = item->GetProto()->InventoryType;
|
||||
uint32 level = item->GetProto()->ItemLevel;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case INVTYPE_2HWEAPON:
|
||||
twoHandScore = std::max(twoHandScore, level);
|
||||
break;
|
||||
case INVTYPE_WEAPON:
|
||||
case INVTYPE_WEAPONMAINHAND:
|
||||
(*gearScore)[SLOT_MAIN_HAND] = std::max((*gearScore)[SLOT_MAIN_HAND], level);
|
||||
break;
|
||||
case INVTYPE_SHIELD:
|
||||
case INVTYPE_WEAPONOFFHAND:
|
||||
(*gearScore)[EQUIPMENT_SLOT_OFFHAND] = std::max((*gearScore)[EQUIPMENT_SLOT_OFFHAND], level);
|
||||
break;
|
||||
case INVTYPE_THROWN:
|
||||
case INVTYPE_RANGEDRIGHT:
|
||||
case INVTYPE_RANGED:
|
||||
case INVTYPE_QUIVER:
|
||||
case INVTYPE_RELIC:
|
||||
(*gearScore)[EQUIPMENT_SLOT_RANGED] = std::max((*gearScore)[EQUIPMENT_SLOT_RANGED], level);
|
||||
break;
|
||||
case INVTYPE_HEAD:
|
||||
(*gearScore)[EQUIPMENT_SLOT_HEAD] = std::max((*gearScore)[EQUIPMENT_SLOT_HEAD], level);
|
||||
break;
|
||||
case INVTYPE_NECK:
|
||||
(*gearScore)[EQUIPMENT_SLOT_NECK] = std::max((*gearScore)[EQUIPMENT_SLOT_NECK], level);
|
||||
break;
|
||||
case INVTYPE_SHOULDERS:
|
||||
(*gearScore)[EQUIPMENT_SLOT_SHOULDERS] = std::max((*gearScore)[EQUIPMENT_SLOT_SHOULDERS], level);
|
||||
break;
|
||||
case INVTYPE_BODY:
|
||||
(*gearScore)[EQUIPMENT_SLOT_BODY] = std::max((*gearScore)[EQUIPMENT_SLOT_BODY], level);
|
||||
break;
|
||||
case INVTYPE_CHEST:
|
||||
(*gearScore)[EQUIPMENT_SLOT_CHEST] = std::max((*gearScore)[EQUIPMENT_SLOT_CHEST], level);
|
||||
break;
|
||||
case INVTYPE_WAIST:
|
||||
(*gearScore)[EQUIPMENT_SLOT_WAIST] = std::max((*gearScore)[EQUIPMENT_SLOT_WAIST], level);
|
||||
break;
|
||||
case INVTYPE_LEGS:
|
||||
(*gearScore)[EQUIPMENT_SLOT_LEGS] = std::max((*gearScore)[EQUIPMENT_SLOT_LEGS], level);
|
||||
break;
|
||||
case INVTYPE_FEET:
|
||||
(*gearScore)[EQUIPMENT_SLOT_FEET] = std::max((*gearScore)[EQUIPMENT_SLOT_FEET], level);
|
||||
break;
|
||||
case INVTYPE_WRISTS:
|
||||
(*gearScore)[EQUIPMENT_SLOT_WRISTS] = std::max((*gearScore)[EQUIPMENT_SLOT_WRISTS], level);
|
||||
break;
|
||||
case INVTYPE_HANDS:
|
||||
(*gearScore)[EQUIPMENT_SLOT_HEAD] = std::max((*gearScore)[EQUIPMENT_SLOT_HEAD], level);
|
||||
break;
|
||||
// equipped gear score check uses both rings and trinkets for calculation, assume that for bags/banks it is the same
|
||||
// with keeping second highest score at second slot
|
||||
case INVTYPE_FINGER:
|
||||
{
|
||||
if ((*gearScore)[EQUIPMENT_SLOT_FINGER1] < level)
|
||||
{
|
||||
(*gearScore)[EQUIPMENT_SLOT_FINGER2] = (*gearScore)[EQUIPMENT_SLOT_FINGER1];
|
||||
(*gearScore)[EQUIPMENT_SLOT_FINGER1] = level;
|
||||
}
|
||||
else if ((*gearScore)[EQUIPMENT_SLOT_FINGER2] < level)
|
||||
(*gearScore)[EQUIPMENT_SLOT_FINGER2] = level;
|
||||
break;
|
||||
}
|
||||
case INVTYPE_TRINKET:
|
||||
{
|
||||
if ((*gearScore)[EQUIPMENT_SLOT_TRINKET1] < level)
|
||||
{
|
||||
(*gearScore)[EQUIPMENT_SLOT_TRINKET2] = (*gearScore)[EQUIPMENT_SLOT_TRINKET1];
|
||||
(*gearScore)[EQUIPMENT_SLOT_TRINKET1] = level;
|
||||
}
|
||||
else if ((*gearScore)[EQUIPMENT_SLOT_TRINKET2] < level)
|
||||
(*gearScore)[EQUIPMENT_SLOT_TRINKET2] = level;
|
||||
break;
|
||||
}
|
||||
case INVTYPE_CLOAK:
|
||||
(*gearScore)[EQUIPMENT_SLOT_BACK] = std::max((*gearScore)[EQUIPMENT_SLOT_BACK], level);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue