mirror of
https://github.com/mod-playerbots/mod-playerbots
synced 2025-11-29 15:58:20 +08:00
Hunter pet talents init
This commit is contained in:
@@ -821,13 +821,25 @@ AiPlayerbot.PremadeSpecGlyph.3.0 = 42912,43350,42902,43351,43338,45732
|
||||
AiPlayerbot.PremadeSpecLink.3.0.60 = 51200201505112243100511351
|
||||
AiPlayerbot.PremadeSpecLink.3.0.80 = 51200201505112253100531351-015305021
|
||||
AiPlayerbot.PremadeSpecName.3.1 = mm pve
|
||||
AiPlayerbot.PremadeSpecGlyph.3.1 = 42912,43350,42915,43351,43338,45732
|
||||
AiPlayerbot.PremadeSpecLink.3.1.60 = -015305101230013233135030051
|
||||
AiPlayerbot.PremadeSpecLink.3.1.80 = 502-035305101230013233135031351-5000002
|
||||
AiPlayerbot.PremadeSpecGlyph.3.1 = 42912,43350,42914,43351,43338,45732
|
||||
AiPlayerbot.PremadeSpecLink.3.1.60 = -005305111230013233125030151-5
|
||||
AiPlayerbot.PremadeSpecLink.3.1.80 = 502-005305131230013233135031351-5000002
|
||||
AiPlayerbot.PremadeSpecName.3.2 = surv pve
|
||||
AiPlayerbot.PremadeSpecGlyph.3.2 = 42912,43350,45731,43351,43338,45732
|
||||
AiPlayerbot.PremadeSpecLink.3.2.60 = --5000032500033330502135001331
|
||||
AiPlayerbot.PremadeSpecLink.3.2.80 = -005305101-5000032500033330522135301331
|
||||
AiPlayerbot.PremadeSpecLink.3.2.60 = --5000032500033330502135201311
|
||||
AiPlayerbot.PremadeSpecLink.3.2.80 = -005305101-5000032500033330532135301321
|
||||
|
||||
# HUNTER PET
|
||||
#
|
||||
# Ferocity
|
||||
AiPlayerbot.PremadeHunterPetLink.0.16 = 2100003030103010101
|
||||
AiPlayerbot.PremadeHunterPetLink.0.20 = 2100013030103010122
|
||||
# Tenacity
|
||||
AiPlayerbot.PremadeHunterPetLink.1.16 = 21103000300120101001
|
||||
AiPlayerbot.PremadeHunterPetLink.1.20 = 21303010300120101002
|
||||
# Cunning
|
||||
AiPlayerbot.PremadeHunterPetLink.2.16 = 2100020330000211001
|
||||
AiPlayerbot.PremadeHunterPetLink.2.20 = 21000203300002110221
|
||||
|
||||
#
|
||||
#
|
||||
|
||||
@@ -331,6 +331,17 @@ bool PlayerbotAIConfig::Initialize()
|
||||
parsedSpecLinkOrder[cls][spec][level] = ParseTempTalentsOrder(cls, premadeSpecLink[cls][spec][level]);
|
||||
}
|
||||
}
|
||||
for (uint32 spec = 0; spec < 3; ++spec)
|
||||
{
|
||||
for (uint32 points = 0; points < 21; ++points)
|
||||
{
|
||||
std::ostringstream os;
|
||||
os << "AiPlayerbot.PremadeHunterPetLink." << spec << "." << points;
|
||||
premadeHunterPetLink[spec][points] = sConfigMgr->GetOption<std::string>(os.str().c_str(), "", false);
|
||||
parsedHunterPetLinkOrder[spec][points] =
|
||||
ParseTempPetTalentsOrder(spec, premadeHunterPetLink[spec][points]);
|
||||
}
|
||||
}
|
||||
for (uint32 spec = 0; spec < MAX_SPECNO; ++spec)
|
||||
{
|
||||
std::ostringstream os;
|
||||
@@ -760,3 +771,47 @@ std::vector<std::vector<uint32>> PlayerbotAIConfig::ParseTempTalentsOrder(uint32
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<std::vector<uint32>> PlayerbotAIConfig::ParseTempPetTalentsOrder(uint32 spec, std::string tab_link)
|
||||
{
|
||||
// check bad link
|
||||
// uint32 classMask = 1 << (cls - 1);
|
||||
std::vector<TalentEntry const*> spells;
|
||||
std::vector<std::vector<uint32>> orders;
|
||||
for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
|
||||
{
|
||||
TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
|
||||
if (!talentInfo)
|
||||
continue;
|
||||
|
||||
TalentTabEntry const* talentTabInfo = sTalentTabStore.LookupEntry(talentInfo->TalentTab);
|
||||
if (!talentTabInfo)
|
||||
continue;
|
||||
|
||||
if (!((1 << spec) & talentTabInfo->petTalentMask))
|
||||
continue;
|
||||
// skip some duplicate spells like dash/dive
|
||||
if (talentInfo->TalentID == 2201 || talentInfo->TalentID == 2208 || talentInfo->TalentID == 2219 || talentInfo->TalentID == 2203)
|
||||
continue;
|
||||
|
||||
spells.push_back(talentInfo);
|
||||
}
|
||||
std::sort(spells.begin(), spells.end(),
|
||||
[&](TalentEntry const* lhs, TalentEntry const* rhs)
|
||||
{ return lhs->Row != rhs->Row ? lhs->Row < rhs->Row : lhs->Col < rhs->Col; });
|
||||
for (int i = 0; i < tab_link.size(); i++)
|
||||
{
|
||||
if (i >= spells.size())
|
||||
{
|
||||
break;
|
||||
}
|
||||
int lvl = tab_link[i] - '0';
|
||||
if (lvl == 0)
|
||||
continue;
|
||||
orders.push_back({spells[i]->Row, spells[i]->Col, (uint32)lvl});
|
||||
}
|
||||
// sort by talent tab size
|
||||
std::sort(orders.begin(), orders.end(), [&](auto& lhs, auto& rhs) { return lhs.size() > rhs.size(); });
|
||||
|
||||
return orders;
|
||||
}
|
||||
|
||||
@@ -195,7 +195,9 @@ public:
|
||||
std::string premadeSpecGlyph[MAX_CLASSES][MAX_SPECNO];
|
||||
std::vector<uint32> parsedSpecGlyph[MAX_CLASSES][MAX_SPECNO];
|
||||
std::string premadeSpecLink[MAX_CLASSES][MAX_SPECNO][MAX_LEVEL];
|
||||
std::string premadeHunterPetLink[3][21];
|
||||
std::vector<std::vector<uint32>> parsedSpecLinkOrder[MAX_CLASSES][MAX_SPECNO][MAX_LEVEL];
|
||||
std::vector<std::vector<uint32>> parsedHunterPetLinkOrder[3][21];
|
||||
uint32 randomClassSpecProb[MAX_CLASSES][MAX_SPECNO];
|
||||
uint32 randomClassSpecIndex[MAX_CLASSES][MAX_SPECNO];
|
||||
|
||||
@@ -325,6 +327,7 @@ public:
|
||||
|
||||
void loadWorldBuf(uint32 factionId, uint32 classId, uint32 minLevel, uint32 maxLevel);
|
||||
static std::vector<std::vector<uint32>> ParseTempTalentsOrder(uint32 cls, std::string temp_talents_order);
|
||||
static std::vector<std::vector<uint32>> ParseTempPetTalentsOrder(uint32 spec, std::string temp_talents_order);
|
||||
};
|
||||
|
||||
#define sPlayerbotAIConfig PlayerbotAIConfig::instance()
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
#define PLAYER_SKILL_INDEX(x) (PLAYER_SKILL_INFO_1_1 + ((x)*3))
|
||||
|
||||
const uint64 diveMask = (1LL << 7) | (1LL << 44) | (1LL << 37) | (1LL << 38) | (1LL << 26) | (1LL << 30) | (1LL << 27) | (1LL << 33) | (1LL << 24) | (1LL << 34);
|
||||
uint32 PlayerbotFactory::tradeSkills[] = {SKILL_ALCHEMY, SKILL_ENCHANTING, SKILL_SKINNING, SKILL_TAILORING,
|
||||
SKILL_LEATHERWORKING, SKILL_ENGINEERING, SKILL_HERBALISM, SKILL_MINING,
|
||||
SKILL_BLACKSMITHING, SKILL_COOKING, SKILL_FIRST_AID, SKILL_FISHING,
|
||||
@@ -611,8 +612,10 @@ void PlayerbotFactory::InitPetTalents()
|
||||
// pet_family->petTalentType);
|
||||
return;
|
||||
}
|
||||
// pet->resetTalents();
|
||||
std::unordered_map<uint32, std::vector<TalentEntry const*>> spells;
|
||||
bool diveTypePet = (1LL << ci->family) & diveMask;
|
||||
LOG_INFO("playerbots", "DIVEMASK:{}", diveMask);
|
||||
|
||||
for (uint32 i = 0; i < sTalentStore.GetNumRows(); ++i)
|
||||
{
|
||||
TalentEntry const* talentInfo = sTalentStore.LookupEntry(i);
|
||||
@@ -624,15 +627,21 @@ void PlayerbotFactory::InitPetTalents()
|
||||
// prevent learn talent for different family (cheating)
|
||||
if (!((1 << pet_family->petTalentType) & talentTabInfo->petTalentMask))
|
||||
continue;
|
||||
|
||||
bool diveClass = talentInfo->TalentID == 2201 || talentInfo->TalentID == 2208 || talentInfo->TalentID == 2219 || talentInfo->TalentID == 2203;
|
||||
if (diveClass && !diveTypePet)
|
||||
continue;
|
||||
bool dashClass = talentInfo->TalentID == 2119 || talentInfo->TalentID == 2207 || talentInfo->TalentID == 2111 || talentInfo->TalentID == 2109;
|
||||
if (dashClass && diveTypePet)
|
||||
continue;
|
||||
spells[talentInfo->Row].push_back(talentInfo);
|
||||
}
|
||||
|
||||
uint32 curTalentPoints = pet->GetFreeTalentPoints();
|
||||
std::vector<std::vector<uint32>> order = sPlayerbotAIConfig->parsedHunterPetLinkOrder[pet_family->petTalentType][20];
|
||||
uint32 maxTalentPoints = pet->GetMaxTalentPointsForLevel(pet->GetLevel());
|
||||
|
||||
if (order.empty())
|
||||
{
|
||||
int row = 0;
|
||||
// LOG_INFO("playerbots", "{} learning, max talent points: {}, cur: {}", bot->GetName().c_str(), maxTalentPoints,
|
||||
// curTalentPoints);
|
||||
for (auto i = spells.begin(); i != spells.end(); ++i, ++row)
|
||||
{
|
||||
std::vector<TalentEntry const*>& spells_row = i->second;
|
||||
@@ -669,6 +678,63 @@ void PlayerbotFactory::InitPetTalents()
|
||||
spells_row.erase(spells_row.begin() + index);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32 spec = pet_family->petTalentType;
|
||||
uint32 startPoints = pet->GetMaxTalentPointsForLevel(pet->GetLevel());
|
||||
while (startPoints > 1 && startPoints < 20 &&
|
||||
sPlayerbotAIConfig->parsedHunterPetLinkOrder[spec][startPoints].size() == 0)
|
||||
{
|
||||
startPoints--;
|
||||
}
|
||||
|
||||
for (uint32 points = startPoints; points <= 20; points++)
|
||||
{
|
||||
if (sPlayerbotAIConfig->parsedHunterPetLinkOrder[spec][points].size() == 0)
|
||||
continue;
|
||||
for (std::vector<uint32>& p : sPlayerbotAIConfig->parsedHunterPetLinkOrder[spec][points])
|
||||
{
|
||||
uint32 row = p[0], col = p[1], lvl = p[2];
|
||||
uint32 talentID = 0;
|
||||
uint32 learnLevel = 0;
|
||||
std::vector<TalentEntry const*>& spell = spells[row];
|
||||
for (TalentEntry const* talentInfo : spell)
|
||||
{
|
||||
if (talentInfo->Col != col)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (talentInfo->DependsOn)
|
||||
{
|
||||
bot->LearnPetTalent(pet->GetGUID(),talentInfo->DependsOn,
|
||||
std::min(talentInfo->DependsOnRank, bot->GetFreeTalentPoints() - 1));
|
||||
}
|
||||
talentID = talentInfo->TalentID;
|
||||
|
||||
uint32 currentTalentRank = 0;
|
||||
for (uint8 rank = 0; rank < MAX_TALENT_RANK; ++rank)
|
||||
{
|
||||
if (talentInfo->RankID[rank] && pet->HasSpell(talentInfo->RankID[rank]))
|
||||
{
|
||||
currentTalentRank = rank + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
learnLevel = std::min(lvl, pet->GetFreeTalentPoints() + currentTalentRank) - 1;
|
||||
}
|
||||
bot->LearnPetTalent(pet->GetGUID(), talentID, learnLevel);
|
||||
if (pet->GetFreeTalentPoints() == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (pet->GetFreeTalentPoints() == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
bot->SendTalentsInfoData(true);
|
||||
}
|
||||
|
||||
@@ -1467,6 +1533,7 @@ void PlayerbotFactory::InitEquipment(bool incremental)
|
||||
else if (blevel == 80)
|
||||
delta = 9;
|
||||
|
||||
StatsWeightCalculator calculator(bot);
|
||||
for (uint8 slot = 0; slot < EQUIPMENT_SLOT_END; ++slot)
|
||||
{
|
||||
if (slot == EQUIPMENT_SLOT_TABARD || slot == EQUIPMENT_SLOT_BODY)
|
||||
@@ -1484,6 +1551,18 @@ void PlayerbotFactory::InitEquipment(bool incremental)
|
||||
if (level < 20 && (slot == EQUIPMENT_SLOT_FINGER1 || slot == EQUIPMENT_SLOT_FINGER2))
|
||||
continue;
|
||||
|
||||
Item* oldItem = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, slot);
|
||||
|
||||
if (!incremental && oldItem)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (oldItem)
|
||||
{
|
||||
bot->DestroyItem(INVENTORY_SLOT_BAG_0, slot, true);
|
||||
}
|
||||
|
||||
uint32 desiredQuality = itemQuality;
|
||||
if (urand(0, 100) < 100 * sPlayerbotAIConfig->randomGearLoweringChance && desiredQuality > ITEM_QUALITY_NORMAL)
|
||||
{
|
||||
@@ -1555,41 +1634,19 @@ void PlayerbotFactory::InitEquipment(bool incremental)
|
||||
break;
|
||||
}
|
||||
} while (items[slot].size() < 25 && desiredQuality-- > ITEM_QUALITY_NORMAL);
|
||||
}
|
||||
|
||||
StatsWeightCalculator calculator(bot);
|
||||
for (uint8 slot = 0; slot < EQUIPMENT_SLOT_END; ++slot)
|
||||
{
|
||||
if (slot == EQUIPMENT_SLOT_TABARD || slot == EQUIPMENT_SLOT_BODY)
|
||||
continue;
|
||||
|
||||
if (level < 40 && (slot == EQUIPMENT_SLOT_TRINKET1 || slot == EQUIPMENT_SLOT_TRINKET2))
|
||||
continue;
|
||||
|
||||
if (level < 25 && slot == EQUIPMENT_SLOT_NECK)
|
||||
continue;
|
||||
|
||||
if (level < 25 && slot == EQUIPMENT_SLOT_HEAD)
|
||||
continue;
|
||||
|
||||
std::vector<uint32>& ids = items[slot];
|
||||
if (ids.empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Item* oldItem = bot->GetItemByPos(INVENTORY_SLOT_BAG_0, slot);
|
||||
|
||||
if (incremental && !IsDesiredReplacement(oldItem))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
float bestScoreForSlot = -1;
|
||||
uint32 bestItemForSlot = 0;
|
||||
for (int index = 0; index < ids.size(); index++)
|
||||
{
|
||||
uint32 skipProb = 25;
|
||||
if (urand(0, 100) <= skipProb)
|
||||
if (urand(1, 100) <= skipProb)
|
||||
continue;
|
||||
|
||||
uint32 newItemId = ids[index];
|
||||
@@ -1601,9 +1658,6 @@ void PlayerbotFactory::InitEquipment(bool incremental)
|
||||
if (!CanEquipItem(proto))
|
||||
continue;
|
||||
|
||||
if (oldItem && oldItem->GetTemplate()->ItemId == newItemId)
|
||||
continue;
|
||||
|
||||
if (!CanEquipUnseenItem(slot, dest, newItemId))
|
||||
continue;
|
||||
|
||||
@@ -1618,10 +1672,7 @@ void PlayerbotFactory::InitEquipment(bool incremental)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (oldItem)
|
||||
{
|
||||
bot->DestroyItem(INVENTORY_SLOT_BAG_0, slot, true);
|
||||
}
|
||||
|
||||
uint16 dest;
|
||||
if (!CanEquipUnseenItem(slot, dest, bestItemForSlot))
|
||||
{
|
||||
@@ -1632,10 +1683,28 @@ void PlayerbotFactory::InitEquipment(bool incremental)
|
||||
{
|
||||
newItem->AddToWorld();
|
||||
newItem->AddToUpdateQueueOf(bot);
|
||||
// bot->AutoUnequipOffhandIfNeed();
|
||||
// EnchantItem(newItem);
|
||||
}
|
||||
}
|
||||
// secondary init for better equips
|
||||
if (!incremental)
|
||||
InitEquipment(true);
|
||||
|
||||
// for (uint8 slot = 0; slot < EQUIPMENT_SLOT_END; ++slot)
|
||||
// {
|
||||
// if (slot == EQUIPMENT_SLOT_TABARD || slot == EQUIPMENT_SLOT_BODY)
|
||||
// continue;
|
||||
|
||||
// if (level < 40 && (slot == EQUIPMENT_SLOT_TRINKET1 || slot == EQUIPMENT_SLOT_TRINKET2))
|
||||
// continue;
|
||||
|
||||
// if (level < 25 && slot == EQUIPMENT_SLOT_NECK)
|
||||
// continue;
|
||||
|
||||
// if (level < 25 && slot == EQUIPMENT_SLOT_HEAD)
|
||||
// continue;
|
||||
|
||||
|
||||
// }
|
||||
}
|
||||
|
||||
bool PlayerbotFactory::IsDesiredReplacement(Item* item)
|
||||
@@ -3818,7 +3887,7 @@ void PlayerbotFactory::ApplyEnchantAndGemsNew(bool destoryOld)
|
||||
if (!gemProperties)
|
||||
continue;
|
||||
|
||||
if ((socketColor & gemProperties->color) == 0)
|
||||
if ((socketColor & gemProperties->color) == 0 && gemProperties->color == 1) // meta socket
|
||||
continue;
|
||||
|
||||
uint32 enchant_id = gemProperties->spellitemenchantement;
|
||||
@@ -3829,6 +3898,7 @@ void PlayerbotFactory::ApplyEnchantAndGemsNew(bool destoryOld)
|
||||
StatsWeightCalculator calculator(bot);
|
||||
float score = calculator.CalculateEnchant(enchant_id);
|
||||
if (curCount[0] != 0)
|
||||
{
|
||||
// Ensure meta gem activation
|
||||
for (int i = 1; i < curCount.size(); i++)
|
||||
{
|
||||
@@ -3838,6 +3908,9 @@ void PlayerbotFactory::ApplyEnchantAndGemsNew(bool destoryOld)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (socketColor & gemProperties->color)
|
||||
score *= 1.2;
|
||||
if (score > bestGemScore)
|
||||
{
|
||||
enchantIdChosen = enchant_id;
|
||||
|
||||
Reference in New Issue
Block a user