Fix unique gem

This commit is contained in:
Yunfan Li
2024-03-30 00:38:05 +08:00
parent e6295e6260
commit fefb2b0037

View File

@@ -15,6 +15,7 @@
#include "LogCommon.h"
#include "LootMgr.h"
#include "MapMgr.h"
#include "ObjectMgr.h"
#include "PetDefines.h"
#include "Player.h"
#include "PlayerbotAI.h"
@@ -130,6 +131,9 @@ void PlayerbotFactory::Init()
if (gemId == 0) {
continue;
}
if (gemId == 1629) { // unique gem
continue;
}
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(gemId);
if (!proto || !sGemPropertiesStore.LookupEntry(proto->GemProperties)) {
continue;
@@ -2795,13 +2799,15 @@ void PlayerbotFactory::InitReagents()
}
}
void PlayerbotFactory::InitGlyphs()
void PlayerbotFactory::InitGlyphs(bool increment)
{
bot->InitGlyphsForLevel();
for (uint32 slotIndex = 0; slotIndex < MAX_GLYPH_SLOT_INDEX; ++slotIndex)
{
bot->SetGlyph(slotIndex, 0, true);
if (!increment) {
for (uint32 slotIndex = 0; slotIndex < MAX_GLYPH_SLOT_INDEX; ++slotIndex)
{
bot->SetGlyph(slotIndex, 0, true);
}
}
uint32 level = bot->getLevel();
@@ -2816,10 +2822,14 @@ void PlayerbotFactory::InitGlyphs()
maxSlot = 5;
if (level >= 80)
maxSlot = 6;
uint8 glyphOrder[6] = {0, 1, 3, 2, 4, 5};
if (!maxSlot)
return;
uint8 cls = bot->getClass();
uint8 tab = AiFactory::GetPlayerSpecTab(bot);
std::list<uint32> glyphs;
ItemTemplateContainer const* itemTemplates = sObjectMgr->GetItemTemplateStore();
for (ItemTemplateContainer::const_iterator i = itemTemplates->begin(); i != itemTemplates->end(); ++i)
@@ -2853,52 +2863,84 @@ void PlayerbotFactory::InitGlyphs()
}
}
if (glyphs.empty())
{
LOG_INFO("playerbots", "No glyphs found for bot {}", bot->GetName().c_str());
return;
}
std::unordered_set<uint32> chosen;
for (uint32 slotIndex = 0; slotIndex < maxSlot; ++slotIndex)
{
uint32 slot = bot->GetGlyphSlot(slotIndex);
GlyphSlotEntry const *gs = sGlyphSlotStore.LookupEntry(slot);
if (!gs)
uint8 realSlot = glyphOrder[slotIndex];
if (bot->GetGlyph(realSlot)) {
continue;
std::vector<uint32> ids;
for (std::list<uint32>::iterator i = glyphs.begin(); i != glyphs.end(); ++i)
{
uint32 id = *i;
GlyphPropertiesEntry const *gp = sGlyphPropertiesStore.LookupEntry(id);
if (!gp || gp->TypeFlags != gs->TypeFlags)
continue;
ids.push_back(id);
}
int maxCount = urand(0, 3);
int count = 0;
bool found = false;
for (int attempts = 0; attempts < 15; ++attempts)
{
uint32 index = urand(0, ids.size() - 1);
if (index >= ids.size())
// uint32 slot = bot->GetGlyphSlot(slotIndex);
// GlyphSlotEntry const *gs = sGlyphSlotStore.LookupEntry(slot);
// if (!gs)
// continue;
if (sPlayerbotAIConfig->parsedSpecGlyph[cls][tab].size() > slotIndex && sPlayerbotAIConfig->parsedSpecGlyph[cls][tab][slotIndex] != 0) {
uint32 itemId = sPlayerbotAIConfig->parsedSpecGlyph[cls][tab][slotIndex];
ItemTemplate const* proto = sObjectMgr->GetItemTemplate(itemId);
if (proto->Class != ITEM_CLASS_GLYPH)
continue;
uint32 id = ids[index];
if (chosen.find(id) != chosen.end())
if ((proto->AllowableClass & bot->getClassMask()) == 0 || (proto->AllowableRace & bot->getRaceMask()) == 0)
continue;
chosen.insert(id);
uint32 glyph = 0;
for (uint32 spell = 0; spell < MAX_ITEM_PROTO_SPELLS; spell++)
{
uint32 spellId = proto->Spells[spell].SpellId;
SpellInfo const *entry = sSpellMgr->GetSpellInfo(spellId);
if (!entry)
continue;
bot->SetGlyph(slotIndex, id, true);
found = true;
break;
for (uint32 effect = 0; effect <= EFFECT_2; ++effect)
{
if (entry->Effects[effect].Effect != SPELL_EFFECT_APPLY_GLYPH)
continue;
glyph = entry->Effects[effect].MiscValue;
}
}
if (!glyph) {
continue;
}
bot->SetGlyph(realSlot, glyph, true);
chosen.insert(glyph);
} else {
uint32 slot = bot->GetGlyphSlot(realSlot);
GlyphSlotEntry const *gs = sGlyphSlotStore.LookupEntry(slot);
if (!gs)
continue;
std::vector<uint32> ids;
for (std::list<uint32>::iterator i = glyphs.begin(); i != glyphs.end(); ++i)
{
uint32 id = *i;
GlyphPropertiesEntry const *gp = sGlyphPropertiesStore.LookupEntry(id);
if (!gp || gp->TypeFlags != gs->TypeFlags)
continue;
ids.push_back(id);
}
int maxCount = urand(0, 3);
int count = 0;
bool found = false;
for (int attempts = 0; attempts < 15; ++attempts)
{
uint32 index = urand(0, ids.size() - 1);
if (index >= ids.size())
continue;
uint32 id = ids[index];
if (chosen.find(id) != chosen.end())
continue;
chosen.insert(id);
bot->SetGlyph(realSlot, id, true);
found = true;
break;
}
}
if (!found)
LOG_INFO("playerbots", "No glyphs found for bot {} index {} slot {}", bot->GetName().c_str(), slotIndex, slot);
}
}
@@ -3360,7 +3402,7 @@ void PlayerbotFactory::ApplyEnchantAndGemsNew(bool destoryOld)
if (slot == EQUIPMENT_SLOT_TABARD || slot == EQUIPMENT_SLOT_BODY)
continue;
Item* item = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, slot);
if (!item) {
if (!item || !item->GetOwner()) {
continue;
}
int32 bestEnchantId = -1;
@@ -3544,7 +3586,12 @@ float PlayerbotFactory::CalculateItemScore(uint32 item_id, Player* bot)
int armor = 0;
int itemLevel = proto->ItemLevel;
int quality = proto->Quality;
int dps = (proto->Damage[0].DamageMin + proto->Damage[0].DamageMax) / 2 * proto->Delay / 1000;
int meleeDps = 0, rangeDps = 0;
if (proto->IsRangedWeapon()) {
rangeDps = (proto->Damage[0].DamageMin + proto->Damage[0].DamageMax) / 2 * proto->Delay / 1000;
} else if (proto->IsWeapon()) {
meleeDps = (proto->Damage[0].DamageMin + proto->Damage[0].DamageMax) / 2 * proto->Delay / 1000;
}
armor += proto->Armor;
block += proto->Block;
for (int i = 0; i < proto->StatsCount; i++) {
@@ -3609,6 +3656,7 @@ float PlayerbotFactory::CalculateItemScore(uint32 item_id, Player* bot)
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(proto->Spells[j].SpellId);
if (!spellInfo)
continue;
// spell category check?
for (uint8 i = 0 ; i < 3; i++)
{
@@ -3633,10 +3681,10 @@ float PlayerbotFactory::CalculateItemScore(uint32 item_id, Player* bot)
// Basic score
float score = (agility + strength + intellect + spirit + stamina + defense + dodge + parry + block +
resilience + hit + crit + haste + expertise + attack_power + mana_regeneration + spell_power + armor_penetration +
spell_penetration + armor + dps) * 0.001;
spell_penetration + armor + rangeDps + meleeDps) * 0.001;
if (cls == CLASS_HUNTER) {
// AGILITY only
score = agility * 2.5 + attack_power + armor_penetration * 2 + dps * 5 + hit * 2.5 + crit * 2 + haste * 2.5 + intellect;
score = agility * 2.5 + attack_power + armor_penetration * 2 + rangeDps * 5 + hit * 2.5 + crit * 2 + haste * 2.5 + intellect;
} else if (cls == CLASS_WARLOCK ||
cls == CLASS_MAGE ||
(cls == CLASS_PRIEST && tab == 2) || // shadow
@@ -3645,26 +3693,26 @@ float PlayerbotFactory::CalculateItemScore(uint32 item_id, Player* bot)
) {
// SPELL DPS
score = intellect * 0.5 + spirit * 0.5 + spell_power + spell_penetration
+ hit * 1.2 + crit * 0.7 + haste * 1;
+ hit * 1.2 + crit * 0.7 + haste * 1 + rangeDps;
} else if ((cls == CLASS_PALADIN && tab == 0) || // holy
(cls == CLASS_PRIEST && tab != 2) || // discipline / holy
(cls == CLASS_SHAMAN && tab == 2) || // heal
(cls == CLASS_DRUID && tab == 2)
) {
// HEALER
score = intellect * 0.5 + spirit * 0.5 + spell_power + mana_regeneration * 0.5 + crit * 0.5 + haste * 1;
score = intellect * 0.5 + spirit * 0.5 + spell_power + mana_regeneration * 0.5 + crit * 0.5 + haste * 1 + rangeDps;
} else if (cls == CLASS_ROGUE) {
// AGILITY mainly (STRENGTH also)
score = agility * 2 + strength + attack_power + armor_penetration * 1 + dps * 5 + hit * 2 + crit * 1.5 + haste * 1.5 + expertise * 2.5;
score = agility * 2 + strength + attack_power + armor_penetration * 1 + meleeDps * 5 + hit * 2 + crit * 1.5 + haste * 1.5 + expertise * 2.5;
} else if ((cls == CLASS_PALADIN && tab == 2) || // retribution
(cls == CLASS_WARRIOR && tab != 2) || // arm / fury
(cls == CLASS_DEATH_KNIGHT && tab != 0) // ice / unholy
) {
// STRENGTH mainly (AGILITY also)
score = strength * 2 + agility + attack_power + armor_penetration + dps * 5 + hit * 1.5 + crit * 1.5 + haste * 1.5 + expertise * 2;
score = strength * 2 + agility + attack_power + armor_penetration + meleeDps * 5 + hit * 1.5 + crit * 1.5 + haste * 1.5 + expertise * 2;
} else if ((cls == CLASS_SHAMAN && tab == 1)) { // enhancement
// STRENGTH mainly (AGILITY, INTELLECT also)
score = strength * 1 + agility * 1.5 + intellect * 1.5 + attack_power + spell_power * 1.5 + armor_penetration * 0.5 + dps * 5
score = strength * 1 + agility * 1.5 + intellect * 1.5 + attack_power + spell_power * 1.5 + armor_penetration * 0.5 + meleeDps * 5
+ hit * 2 + crit * 1.5 + haste * 1.5 + expertise * 2;
} else if ((cls == CLASS_WARRIOR && tab == 2) ||
(cls == CLASS_PALADIN && tab == 1)) {
@@ -3679,7 +3727,7 @@ float PlayerbotFactory::CalculateItemScore(uint32 item_id, Player* bot)
+ hit * 2 + crit * 0.5 + haste * 0.5 + expertise * 3.5;
} else {
// BEAR DRUID TANK (AND FERAL DRUID...?)
score = agility * 1.5 + strength * 1 + attack_power * 0.5 + armor_penetration * 0.5 + dps * 2
score = agility * 1.5 + strength * 1 + attack_power * 0.5 + armor_penetration * 0.5 + meleeDps * 2
+ defense * 0.25 + dodge * 0.25 + armor * 0.3 + stamina * 1.5
+ hit * 1 + crit * 1 + haste * 0.5 + expertise * 3;
}