mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Fix unique gem
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user