mirror of
https://github.com/liyunfan1223/mod-playerbots.git
synced 2026-02-20 18:10:02 +01:00
Compare commits
20 Commits
66c88d4815
...
eef2e8c1ef
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eef2e8c1ef | ||
|
|
a675e74d97 | ||
|
|
c6005449e0 | ||
|
|
2aca50c1c7 | ||
|
|
179e3bbf71 | ||
|
|
00b03bd29d | ||
|
|
e62da73706 | ||
|
|
5108f709c7 | ||
|
|
2beee4aec9 | ||
|
|
1e128ea24f | ||
|
|
e64da42f87 | ||
|
|
e0ef04e1b9 | ||
|
|
c5c1274d3c | ||
|
|
849b21f916 | ||
|
|
4c9e4e7b0f | ||
|
|
961629f4ce | ||
|
|
1801d7c314 | ||
|
|
55a37c48eb | ||
|
|
564bb198fb | ||
|
|
0b03b277c2 |
@ -1552,41 +1552,12 @@ AiPlayerbot.PremadeSpecLink.11.6.80 = 05320021--230033312031500531353013251
|
|||||||
|
|
||||||
# Applies a permanent buff to all bots simulating effects of spells, flasks, food, runes, etc.
|
# Applies a permanent buff to all bots simulating effects of spells, flasks, food, runes, etc.
|
||||||
# Requires sending the command "nc +worldbuff" in chat to a bot (or a group of bots) to enable
|
# Requires sending the command "nc +worldbuff" in chat to a bot (or a group of bots) to enable
|
||||||
# Numbers after the equal signs are spell IDs and may be customized
|
# Each entry in the matrix should be formatted as follows: Entry:FactionID,ClassID,SpecID,MinimumLevel,MaximumLevel:SpellID1,SpellID2,etc.;
|
||||||
# See Randombots Default Talent Specs for more info on each spec; they are listed in that section by the names in the parentheticals (e.g., arms pve, fury pve)
|
# Use 0 for any field to make it agnostic (e.g., 0 for FactionID means the entry will apply buffs to either faction)
|
||||||
|
# The default entries create a cross-faction list of level 80 buffs for each implemented pve spec from the "Premade Specs" section
|
||||||
|
# The default entries may be deleted or modified, and new custom entries may be added
|
||||||
|
|
||||||
AiPlayerbot.WorldBuff.0.1.0.80.80 = 53760,57358 #WARRIOR ARMS (arms pve)
|
AiPlayerbot.WorldBuffMatrix = # WARRIOR ARMS 1:0,1,0,80,80:53760,57358; # WARRIOR FURY 2:0,1,1,80,80:53760,57358; # WARRIOR PROTECTION 3:0,1,2,80,80:53758,57356; # PALADIN HOLY 4:0,2,0,80,80:53749,57332,60347; # PALADIN PROTECTION 5:0,2,1,80,80:53758,57356; # PALADIN RETRIBUTION 6:0,2,2,80,80:53760,57371; # HUNTER BEAST 7:0,3,0,80,80:53760,57325; # HUNTER MARKSMANSHIP 8:0,3,1,80,80:53760,57358; # HUNTER SURVIVAL 9:0,3,2,80,80:53760,57367; # ROGUE ASSASSINATION 10:0,4,0,80,80:53760,57325; # ROGUE COMBAT 11:0,4,1,80,80:53760,57358; # ROGUE SUBTLETY 12:0,4,2,80,80:53760,57367; # PRIEST DISCIPLINE 13:0,5,0,80,80:53755,57327; # PRIEST HOLY 14:0,5,1,80,80:53755,57327; # PRIEST SHADOW 15:0,5,2,80,80:53755,57327; # DEATH KNIGHT BLOOD 16:0,6,0,80,80:53758,57356; # DEATH KNIGHT FROST 17:0,6,1,80,80:53760,57358; # DEATH KNIGHT UNHOLY 18:0,6,2,80,80:53760,57358; # DEATH KNIGHT BLOOD DPS 19:0,6,3,80,80:53760,57371; # SHAMAN ELEMENTAL 20:0,7,0,80,80:53755,57327; # SHAMAN ENHANCEMENT 21:0,7,1,80,80:53760,57325; # SHAMAN RESTORATION 22:0,7,2,80,80:53755,57327; # MAGE ARCANE 23:0,8,0,80,80:53755,57327; # MAGE FIRE 24:0,8,1,80,80:53755,57327; # MAGE FROST 25:0,8,2,80,80:53755,57327; # WARLOCK AFFLICTION 26:0,9,0,80,80:53755,57327; # WARLOCK DEMONOLOGY 27:0,9,1,80,80:53755,57327; # WARLOCK DESTRUCTION 28:0,9,2,80,80:53755,57327; # DRUID BALANCE 29:0,11,0,80,80:53755,57327; # DRUID FERAL BEAR 30:0,11,1,80,80:53749,53763,57367; # DRUID RESTORATION 31:0,11,2,80,80:54212,57334; # DRUID FERAL CAT 32:0,11,3,80,80:53760,57358
|
||||||
AiPlayerbot.WorldBuff.0.1.1.80.80 = 53760,57358 #WARRIOR FURY (fury pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.1.2.80.80 = 53758,57356 #WARRIOR PROTECTION (prot pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.2.0.80.80 = 60347,53749,57332 #PALADIN HOLY (holy pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.2.1.80.80 = 53758,57356 #PALADIN PROTECTION (prot pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.2.2.80.80 = 53760,57371 #PALADIN RETRIBUTION (ret pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.3.0.80.80 = 53760,57325 #HUNTER BEAST (bm pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.3.1.80.80 = 53760,57358 #HUNTER MARKSMANSHIP (mm pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.3.2.80.80 = 53760,57367 #HUNTER SURVIVAL (surv pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.4.0.80.80 = 53760,57325 #ROGUE ASSASINATION (as pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.4.1.80.80 = 53760,57358 #ROGUE COMBAT (combat pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.4.2.80.80 = 53760,57367 #ROGUE SUBTLETY (subtlety pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.5.0.80.80 = 53755,57327 #PRIEST DISCIPLINE (disc pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.5.1.80.80 = 53755,57327 #PRIEST HOLY (holy pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.5.2.80.80 = 53755,57327 #PRIEST SHADOW (shadow pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.6.0.80.80 = 53758,57356 #DEATH KNIGHT BLOOD (blood pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.6.1.80.80 = 53760,57358 #DEATH KNIGHT FROST (frost pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.6.2.80.80 = 53760,57358 #DEATH KNIGHT UNHOLY (unholy pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.6.3.80.80 = 53760,57371 #DEATH KNIGHT BLOOD DPS (double aura blood pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.7.0.80.80 = 53755,57327 #SHAMAN ELEMENTAL (ele pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.7.1.80.80 = 53760,57325 #SHAMAN ENHANCEMENT (enh pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.7.2.80.80 = 53755,57327 #SHAMAN RESTORATION (resto pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.8.0.80.80 = 53755,57327 #MAGE ARCANE (arcane pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.8.1.80.80 = 53755,57327 #MAGE FIRE (fire pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.8.2.80.80 = 53755,57327 #MAGE FROST (frost pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.9.0.80.80 = 53755,57327 #WARLOCK AFFLICTION (affli pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.9.1.80.80 = 53755,57327 #WARLOCK DEMONOLOGY (demo pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.9.2.80.80 = 53755,57327 #WARLOCK DESTRUCTION (destro pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.11.0.80.80 = 53755,57327 #DRUID BALANCE (balance pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.11.1.80.80 = 53749,53763,57367 #DRUID FERAL BEAR (bear pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.11.2.80.80 = 54212,57334 #DRUID RESTORATION (resto pve)
|
|
||||||
AiPlayerbot.WorldBuff.0.11.3.80.80 = 53760,57358 #DRUID FERAL CAT (cat pve)
|
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|||||||
@ -471,25 +471,8 @@ bool PlayerbotAIConfig::Initialize()
|
|||||||
tradeActionExcludedPrefixes);
|
tradeActionExcludedPrefixes);
|
||||||
|
|
||||||
worldBuffs.clear();
|
worldBuffs.clear();
|
||||||
|
loadWorldBuff();
|
||||||
LOG_INFO("playerbots", "Loading Worldbuff...");
|
LOG_INFO("playerbots", "Loading World Buff Feature...");
|
||||||
for (uint32 factionId = 0; factionId < 3; factionId++)
|
|
||||||
{
|
|
||||||
for (uint32 classId = 0; classId < MAX_CLASSES; classId++)
|
|
||||||
{
|
|
||||||
for (uint32 specId = 0; specId <= MAX_WORLDBUFF_SPECNO; specId++)
|
|
||||||
{
|
|
||||||
for (uint32 minLevel = 0; minLevel <= randomBotMaxLevel; minLevel++)
|
|
||||||
{
|
|
||||||
for (uint32 maxLevel = minLevel; maxLevel <= randomBotMaxLevel; maxLevel++)
|
|
||||||
{
|
|
||||||
loadWorldBuff(factionId, classId, specId, minLevel, maxLevel);
|
|
||||||
}
|
|
||||||
loadWorldBuff(factionId, classId, specId, minLevel, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
randomBotAccountPrefix = sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotAccountPrefix", "rndbot");
|
randomBotAccountPrefix = sConfigMgr->GetOption<std::string>("AiPlayerbot.RandomBotAccountPrefix", "rndbot");
|
||||||
randomBotAccountCount = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAccountCount", 0);
|
randomBotAccountCount = sConfigMgr->GetOption<int32>("AiPlayerbot.RandomBotAccountCount", 0);
|
||||||
@ -742,88 +725,62 @@ void PlayerbotAIConfig::log(std::string const fileName, char const* str, ...)
|
|||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PlayerbotAIConfig::loadWorldBuff(uint32 factionId1, uint32 classId1, uint32 specId1, uint32 minLevel1, uint32 maxLevel1)
|
void PlayerbotAIConfig::loadWorldBuff()
|
||||||
{
|
{
|
||||||
std::vector<uint32> buffs;
|
std::string matrix = sConfigMgr->GetOption<std::string>("AiPlayerbot.WorldBuffMatrix", "", true);
|
||||||
|
if (matrix.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
std::ostringstream os;
|
std::istringstream entryStream(matrix);
|
||||||
os << "AiPlayerbot.WorldBuff." << factionId1 << "." << classId1 << "." << specId1 << "." << minLevel1 << "." << maxLevel1;
|
std::string entry;
|
||||||
|
|
||||||
LoadList<std::vector<uint32>>(sConfigMgr->GetOption<std::string>(os.str().c_str(), "", false), buffs);
|
while (std::getline(entryStream, entry, ';'))
|
||||||
|
|
||||||
for (auto buff : buffs)
|
|
||||||
{
|
{
|
||||||
worldBuff wb = {buff, factionId1, classId1, specId1, minLevel1, maxLevel1};
|
|
||||||
worldBuffs.push_back(wb);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (maxLevel1 == 0)
|
entry.erase(0, entry.find_first_not_of(" \t\r\n"));
|
||||||
{
|
entry.erase(entry.find_last_not_of(" \t\r\n") + 1);
|
||||||
std::ostringstream os;
|
|
||||||
os << "AiPlayerbot.WorldBuff." << factionId1 << "." << classId1 << "." << specId1 << "." << minLevel1;
|
|
||||||
|
|
||||||
LoadList<std::vector<uint32>>(sConfigMgr->GetOption<std::string>(os.str().c_str(), "", false), buffs);
|
size_t firstColon = entry.find(':');
|
||||||
|
size_t secondColon = entry.find(':', firstColon + 1);
|
||||||
|
|
||||||
for (auto buff : buffs)
|
if (firstColon == std::string::npos || secondColon == std::string::npos)
|
||||||
{
|
{
|
||||||
worldBuff wb = {buff, factionId1, classId1, specId1, minLevel1, maxLevel1};
|
LOG_ERROR("playerbots", "Malformed entry: [{}]", entry);
|
||||||
worldBuffs.push_back(wb);
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (maxLevel1 == 0 && minLevel1 == 0)
|
std::string metaPart = entry.substr(firstColon + 1, secondColon - firstColon - 1);
|
||||||
{
|
std::string spellPart = entry.substr(secondColon + 1);
|
||||||
std::ostringstream os;
|
|
||||||
os << "AiPlayerbot.WorldBuff." << factionId1 << "." << factionId1 << "." << classId1 << "." << specId1;
|
|
||||||
|
|
||||||
LoadList<std::vector<uint32>>(sConfigMgr->GetOption<std::string>(os.str().c_str(), "", false), buffs);
|
std::vector<uint32> ids;
|
||||||
|
std::istringstream metaStream(metaPart);
|
||||||
for (auto buff : buffs)
|
std::string token;
|
||||||
|
while (std::getline(metaStream, token, ','))
|
||||||
{
|
{
|
||||||
worldBuff wb = {buff, factionId1, classId1, specId1, minLevel1, maxLevel1};
|
try {
|
||||||
worldBuffs.push_back(wb);
|
ids.push_back(static_cast<uint32>(std::stoi(token)));
|
||||||
|
} catch (...) {
|
||||||
|
LOG_ERROR("playerbots", "Invalid meta token in [{}]", entry);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (maxLevel1 == 0 && minLevel1 == 0 && specId1 == 0)
|
if (ids.size() != 5)
|
||||||
{
|
|
||||||
std::ostringstream os;
|
|
||||||
os << "AiPlayerbot.WorldBuff." << factionId1 << "." << factionId1 << "." << classId1;
|
|
||||||
|
|
||||||
LoadList<std::vector<uint32>>(sConfigMgr->GetOption<std::string>(os.str().c_str(), "", false), buffs);
|
|
||||||
|
|
||||||
for (auto buff : buffs)
|
|
||||||
{
|
{
|
||||||
worldBuff wb = {buff, factionId1, classId1, specId1, minLevel1, maxLevel1};
|
LOG_ERROR("playerbots", "Entry [{}] has incomplete meta block", entry);
|
||||||
worldBuffs.push_back(wb);
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (classId1 == 0 && maxLevel1 == 0 && minLevel1 == 0 && specId1 == 0)
|
std::istringstream spellStream(spellPart);
|
||||||
{
|
while (std::getline(spellStream, token, ','))
|
||||||
std::ostringstream os;
|
|
||||||
os << "AiPlayerbot.WorldBuff." << factionId1;
|
|
||||||
|
|
||||||
LoadList<std::vector<uint32>>(sConfigMgr->GetOption<std::string>(os.str().c_str(), "", false), buffs);
|
|
||||||
|
|
||||||
for (auto buff : buffs)
|
|
||||||
{
|
{
|
||||||
worldBuff wb = {buff, factionId1, classId1, specId1, minLevel1, maxLevel1};
|
try {
|
||||||
worldBuffs.push_back(wb);
|
uint32 spellId = static_cast<uint32>(std::stoi(token));
|
||||||
}
|
worldBuff wb = { spellId, ids[0], ids[1], ids[2], ids[3], ids[4] };
|
||||||
}
|
worldBuffs.push_back(wb);
|
||||||
|
} catch (...) {
|
||||||
if (factionId1 == 0 && classId1 == 0 && maxLevel1 == 0 && minLevel1 == 0 && specId1 == 0)
|
LOG_ERROR("playerbots", "Invalid spell ID in [{}]", entry);
|
||||||
{
|
}
|
||||||
std::ostringstream os;
|
|
||||||
os << "AiPlayerbot.WorldBuff";
|
|
||||||
|
|
||||||
LoadList<std::vector<uint32>>(sConfigMgr->GetOption<std::string>(os.str().c_str(), "", false), buffs);
|
|
||||||
|
|
||||||
for (auto buff : buffs)
|
|
||||||
{
|
|
||||||
worldBuff wb = {buff, factionId1, classId1, specId1, minLevel1, maxLevel1};
|
|
||||||
worldBuffs.push_back(wb);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,7 +57,6 @@ enum NewRpgStatus : int
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_SPECNO 20
|
#define MAX_SPECNO 20
|
||||||
#define MAX_WORLDBUFF_SPECNO 3
|
|
||||||
|
|
||||||
class PlayerbotAIConfig
|
class PlayerbotAIConfig
|
||||||
{
|
{
|
||||||
@ -288,11 +287,11 @@ public:
|
|||||||
struct worldBuff
|
struct worldBuff
|
||||||
{
|
{
|
||||||
uint32 spellId;
|
uint32 spellId;
|
||||||
uint32 factionId = 0;
|
uint32 factionId;
|
||||||
uint32 classId = 0;
|
uint32 classId;
|
||||||
uint32 specId = 0;
|
uint32 specId;
|
||||||
uint32 minLevel = 0;
|
uint32 minLevel;
|
||||||
uint32 maxLevel = 0;
|
uint32 maxLevel;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<worldBuff> worldBuffs;
|
std::vector<worldBuff> worldBuffs;
|
||||||
@ -399,7 +398,8 @@ public:
|
|||||||
}
|
}
|
||||||
void log(std::string const fileName, const char* str, ...);
|
void log(std::string const fileName, const char* str, ...);
|
||||||
|
|
||||||
void loadWorldBuff(uint32 factionId, uint32 classId, uint32 specId, uint32 minLevel, uint32 maxLevel);
|
void loadWorldBuff();
|
||||||
|
|
||||||
static std::vector<std::vector<uint32>> ParseTempTalentsOrder(uint32 cls, std::string temp_talents_order);
|
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);
|
static std::vector<std::vector<uint32>> ParseTempPetTalentsOrder(uint32 spec, std::string temp_talents_order);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -39,6 +39,7 @@
|
|||||||
#include "SpellAuraDefines.h"
|
#include "SpellAuraDefines.h"
|
||||||
#include "StatsWeightCalculator.h"
|
#include "StatsWeightCalculator.h"
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
|
#include "AiObjectContext.h"
|
||||||
|
|
||||||
const uint64 diveMask = (1LL << 7) | (1LL << 44) | (1LL << 37) | (1LL << 38) | (1LL << 26) | (1LL << 30) | (1LL << 27) |
|
const uint64 diveMask = (1LL << 7) | (1LL << 44) | (1LL << 37) | (1LL << 38) | (1LL << 26) | (1LL << 30) | (1LL << 27) |
|
||||||
(1LL << 33) | (1LL << 24) | (1LL << 34);
|
(1LL << 33) | (1LL << 24) | (1LL << 34);
|
||||||
@ -3330,6 +3331,9 @@ void PlayerbotFactory::InitReagents()
|
|||||||
void PlayerbotFactory::InitGlyphs(bool increment)
|
void PlayerbotFactory::InitGlyphs(bool increment)
|
||||||
{
|
{
|
||||||
bot->InitGlyphsForLevel();
|
bot->InitGlyphsForLevel();
|
||||||
|
if (!increment &&
|
||||||
|
botAI->GetAiObjectContext()->GetValue<bool>("custom_glyphs")->Get())
|
||||||
|
return; // // Added for custom Glyphs - custom glyphs flag test
|
||||||
|
|
||||||
if (!increment)
|
if (!increment)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -27,6 +27,7 @@ typedef UntypedValue* (*ValueCreator)(PlayerbotAI* botAI);
|
|||||||
class AiObjectContext : public PlayerbotAIAware
|
class AiObjectContext : public PlayerbotAIAware
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
static BoolCalculatedValue* custom_glyphs(PlayerbotAI* ai); // Added for cutom glyphs
|
||||||
AiObjectContext(PlayerbotAI* botAI,
|
AiObjectContext(PlayerbotAI* botAI,
|
||||||
SharedNamedObjectContextList<Strategy>& sharedStrategyContext = sharedStrategyContexts,
|
SharedNamedObjectContextList<Strategy>& sharedStrategyContext = sharedStrategyContexts,
|
||||||
SharedNamedObjectContextList<Action>& sharedActionContext = sharedActionContexts,
|
SharedNamedObjectContextList<Action>& sharedActionContext = sharedActionContexts,
|
||||||
|
|||||||
@ -11,9 +11,18 @@
|
|||||||
#include "PlayerbotAIConfig.h"
|
#include "PlayerbotAIConfig.h"
|
||||||
#include "PlayerbotFactory.h"
|
#include "PlayerbotFactory.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
|
#include "AiObjectContext.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
bool ChangeTalentsAction::Execute(Event event)
|
bool ChangeTalentsAction::Execute(Event event)
|
||||||
{
|
{
|
||||||
|
auto* flag = botAI->GetAiObjectContext()->GetValue<bool>("custom_glyphs"); // Added for custom Glyphs
|
||||||
|
|
||||||
|
if (flag->Get()) // Added for custom Glyphs
|
||||||
|
{
|
||||||
|
flag->Set(false);
|
||||||
|
LOG_INFO("playerbots", "Custom Glyph Flag set to OFF");
|
||||||
|
}
|
||||||
std::string param = event.getParam();
|
std::string param = event.getParam();
|
||||||
|
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
|
|||||||
@ -79,6 +79,8 @@
|
|||||||
#include "UnlockItemAction.h"
|
#include "UnlockItemAction.h"
|
||||||
#include "UnlockTradedItemAction.h"
|
#include "UnlockTradedItemAction.h"
|
||||||
#include "PetAction.h"
|
#include "PetAction.h"
|
||||||
|
#include "TellGlyphsAction.h"
|
||||||
|
#include "EquipGlyphsAction.h"
|
||||||
|
|
||||||
class ChatActionContext : public NamedObjectContext<Action>
|
class ChatActionContext : public NamedObjectContext<Action>
|
||||||
{
|
{
|
||||||
@ -189,6 +191,8 @@ public:
|
|||||||
creators["calc"] = &ChatActionContext::calc;
|
creators["calc"] = &ChatActionContext::calc;
|
||||||
creators["wipe"] = &ChatActionContext::wipe;
|
creators["wipe"] = &ChatActionContext::wipe;
|
||||||
creators["pet"] = &ChatActionContext::pet;
|
creators["pet"] = &ChatActionContext::pet;
|
||||||
|
creators["glyphs"] = &ChatActionContext::glyphs; // Added for custom Glyphs
|
||||||
|
creators["glyph equip"] = &ChatActionContext::glyph_equip; // Added for custom Glyphs
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -296,6 +300,8 @@ private:
|
|||||||
static Action* calc(PlayerbotAI* ai) { return new TellCalculateItemAction(ai); }
|
static Action* calc(PlayerbotAI* ai) { return new TellCalculateItemAction(ai); }
|
||||||
static Action* wipe(PlayerbotAI* ai) { return new WipeAction(ai); }
|
static Action* wipe(PlayerbotAI* ai) { return new WipeAction(ai); }
|
||||||
static Action* pet(PlayerbotAI* botAI) { return new PetAction(botAI); }
|
static Action* pet(PlayerbotAI* botAI) { return new PetAction(botAI); }
|
||||||
|
static Action* glyphs(PlayerbotAI* botAI) { return new TellGlyphsAction(botAI); } // Added for custom Glyphs
|
||||||
|
static Action* glyph_equip(PlayerbotAI* ai) { return new EquipGlyphsAction(ai); } // Added for custom Glyphs
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
159
src/strategy/actions/EquipGlyphsAction.cpp
Normal file
159
src/strategy/actions/EquipGlyphsAction.cpp
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
|
||||||
|
* and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "EquipGlyphsAction.h"
|
||||||
|
|
||||||
|
#include "Playerbots.h"
|
||||||
|
#include "ObjectMgr.h"
|
||||||
|
#include "SpellMgr.h"
|
||||||
|
#include "DBCStores.h"
|
||||||
|
#include "AiObjectContext.h"
|
||||||
|
#include "Log.h"
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <sstream>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// itemId -> GlyphInfo
|
||||||
|
std::unordered_map<uint32, EquipGlyphsAction::GlyphInfo> s_GlyphCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EquipGlyphsAction::BuildGlyphCache()
|
||||||
|
{
|
||||||
|
if (!s_GlyphCache.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
ItemTemplateContainer const* store = sObjectMgr->GetItemTemplateStore();
|
||||||
|
|
||||||
|
for (auto const& kv : *store)
|
||||||
|
{
|
||||||
|
uint32 itemId = kv.first;
|
||||||
|
ItemTemplate const* proto = &kv.second;
|
||||||
|
if (!proto || proto->Class != ITEM_CLASS_GLYPH)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// inspect item spell
|
||||||
|
for (uint32 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
|
||||||
|
{
|
||||||
|
uint32 spellId = proto->Spells[i].SpellId;
|
||||||
|
if (!spellId) continue;
|
||||||
|
|
||||||
|
SpellInfo const* si = sSpellMgr->GetSpellInfo(spellId);
|
||||||
|
if (!si) continue;
|
||||||
|
|
||||||
|
for (uint8 eff = 0; eff <= EFFECT_2; ++eff)
|
||||||
|
{
|
||||||
|
if (si->Effects[eff].Effect != SPELL_EFFECT_APPLY_GLYPH)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
uint32 glyphId = si->Effects[eff].MiscValue;
|
||||||
|
if (!glyphId) continue;
|
||||||
|
|
||||||
|
if (auto const* gp = sGlyphPropertiesStore.LookupEntry(glyphId))
|
||||||
|
s_GlyphCache[itemId] = {gp, proto};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EquipGlyphsAction::GlyphInfo const* EquipGlyphsAction::GetGlyphInfo(uint32 itemId)
|
||||||
|
{
|
||||||
|
BuildGlyphCache();
|
||||||
|
auto it = s_GlyphCache.find(itemId);
|
||||||
|
return (it == s_GlyphCache.end()) ? nullptr : &it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// -----------------------------------------------------------------
|
||||||
|
/// Validation and collect
|
||||||
|
/// -----------------------------------------------------------------
|
||||||
|
bool EquipGlyphsAction::CollectGlyphs(std::vector<uint32> const& itemIds,
|
||||||
|
std::vector<GlyphInfo const*>& out) const
|
||||||
|
{
|
||||||
|
std::unordered_set<uint32> seen;
|
||||||
|
|
||||||
|
for (uint32 itemId : itemIds)
|
||||||
|
{
|
||||||
|
if (!seen.insert(itemId).second)
|
||||||
|
return false; // double
|
||||||
|
|
||||||
|
auto const* info = GetGlyphInfo(itemId);
|
||||||
|
if (!info) // no good glyph
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// check class by AllowableClass
|
||||||
|
if ((info->proto->AllowableClass & bot->getClassMask()) == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
out.push_back(info);
|
||||||
|
}
|
||||||
|
return out.size() <= 6 && !out.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// -----------------------------------------------------------------
|
||||||
|
/// Action
|
||||||
|
/// -----------------------------------------------------------------
|
||||||
|
bool EquipGlyphsAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
// 1) parse IDs
|
||||||
|
std::vector<uint32> itemIds;
|
||||||
|
std::istringstream iss(event.getParam());
|
||||||
|
for (uint32 id; iss >> id; ) itemIds.push_back(id);
|
||||||
|
|
||||||
|
std::vector<GlyphInfo const*> glyphs;
|
||||||
|
if (!CollectGlyphs(itemIds, glyphs))
|
||||||
|
{
|
||||||
|
botAI->TellMaster("Usage: glyph equip <6 glyph item IDs> (3 major, 3 minor).");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) prepare a empty slots table ?
|
||||||
|
bool used[6] = {false,false,false,false,false,false};
|
||||||
|
|
||||||
|
// 3) for each glyph, find the first available and compatible socket
|
||||||
|
for (auto const* g : glyphs)
|
||||||
|
{
|
||||||
|
bool placed = false;
|
||||||
|
|
||||||
|
for (uint8 i = 0; i < MAX_GLYPH_SLOT_INDEX; ++i)
|
||||||
|
{
|
||||||
|
if (used[i]) continue;
|
||||||
|
|
||||||
|
uint32 slotId = bot->GetGlyphSlot(i);
|
||||||
|
auto const* gs = sGlyphSlotStore.LookupEntry(slotId);
|
||||||
|
if (!gs || gs->TypeFlags != g->prop->TypeFlags)
|
||||||
|
continue; // major/minor don't match
|
||||||
|
|
||||||
|
// Remove aura if exist
|
||||||
|
uint32 cur = bot->GetGlyph(i);
|
||||||
|
if (cur)
|
||||||
|
if (auto* old = sGlyphPropertiesStore.LookupEntry(cur))
|
||||||
|
bot->RemoveAurasDueToSpell(old->SpellId);
|
||||||
|
|
||||||
|
// Apply new one
|
||||||
|
bot->CastSpell(bot, g->prop->SpellId, true);
|
||||||
|
bot->SetGlyph(i, g->prop->Id, true);
|
||||||
|
|
||||||
|
used[i] = true;
|
||||||
|
placed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!placed)
|
||||||
|
{
|
||||||
|
botAI->TellMaster("Not enought empty sockets for all glyphs.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
botAI->TellMaster("Glyphs updated.");
|
||||||
|
|
||||||
|
// Flag for custom glyphs
|
||||||
|
botAI->GetAiObjectContext()->GetValue<bool>("custom_glyphs")->Set(true);
|
||||||
|
LOG_INFO("playerbots", "Custom Glyph Flag set to ON");
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
37
src/strategy/actions/EquipGlyphsAction.h
Normal file
37
src/strategy/actions/EquipGlyphsAction.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
|
||||||
|
* and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PLAYERBOT_EQUIPGLYPHSACTION_H
|
||||||
|
#define _PLAYERBOT_EQUIPGLYPHSACTION_H
|
||||||
|
|
||||||
|
#include "Action.h"
|
||||||
|
|
||||||
|
// 1 = major, 2 = minor dans GlyphProperties.dbc
|
||||||
|
enum class GlyphKind : uint32 { MAJOR = 1, MINOR = 2 };
|
||||||
|
|
||||||
|
class EquipGlyphsAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EquipGlyphsAction(PlayerbotAI* ai) : Action(ai, "glyph equip") {}
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
|
||||||
|
/// ---- Rendu public pour être utilisable par le cache global ----
|
||||||
|
struct GlyphInfo
|
||||||
|
{
|
||||||
|
GlyphPropertiesEntry const* prop; ///< entrée GlyphProperties.dbc
|
||||||
|
ItemTemplate const* proto; ///< template de l’objet glyphe
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
/// Construit la cache {itemId -> GlyphInfo}
|
||||||
|
static void BuildGlyphCache();
|
||||||
|
static GlyphInfo const* GetGlyphInfo(uint32 itemId);
|
||||||
|
|
||||||
|
/// Parse & valide la liste d’items glyphes
|
||||||
|
bool CollectGlyphs(std::vector<uint32> const& itemIds,
|
||||||
|
std::vector<GlyphInfo const*>& out) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
113
src/strategy/actions/TellGlyphsAction.cpp
Normal file
113
src/strategy/actions/TellGlyphsAction.cpp
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
|
||||||
|
* and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "TellGlyphsAction.h"
|
||||||
|
|
||||||
|
#include "Event.h"
|
||||||
|
#include "Playerbots.h"
|
||||||
|
|
||||||
|
#include "ObjectMgr.h"
|
||||||
|
#include "SpellMgr.h"
|
||||||
|
#include "World.h"
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
// Cache : GlyphID (MiscValue) -> ItemTemplate*
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
std::unordered_map<uint32, ItemTemplate const*> s_GlyphItemCache;
|
||||||
|
|
||||||
|
void BuildGlyphItemCache()
|
||||||
|
{
|
||||||
|
if (!s_GlyphItemCache.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
ItemTemplateContainer const* store = sObjectMgr->GetItemTemplateStore();
|
||||||
|
|
||||||
|
for (auto const& kv : *store) // C++17 : range-for sur map
|
||||||
|
{
|
||||||
|
ItemTemplate const* proto = &kv.second;
|
||||||
|
|
||||||
|
if (!proto || proto->Class != ITEM_CLASS_GLYPH)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (uint32 i = 0; i < MAX_ITEM_PROTO_SPELLS; ++i)
|
||||||
|
{
|
||||||
|
uint32 spellId = proto->Spells[i].SpellId;
|
||||||
|
if (!spellId)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
SpellInfo const* spell = sSpellMgr->GetSpellInfo(spellId);
|
||||||
|
if (!spell)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (uint32 eff = 0; eff <= EFFECT_2; ++eff)
|
||||||
|
{
|
||||||
|
if (spell->Effects[eff].Effect != SPELL_EFFECT_APPLY_GLYPH)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
uint32 glyphId = spell->Effects[eff].MiscValue;
|
||||||
|
if (glyphId)
|
||||||
|
s_GlyphItemCache[glyphId] = proto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
// Action
|
||||||
|
// -----------------------------------------------------------------
|
||||||
|
bool TellGlyphsAction::Execute(Event event)
|
||||||
|
{
|
||||||
|
//-----------------------------------------------------------------
|
||||||
|
// 1. who sended the wisp ? (source of event)
|
||||||
|
//-----------------------------------------------------------------
|
||||||
|
Player* sender = event.getOwner(); // API Event
|
||||||
|
if (!sender)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------
|
||||||
|
// 2. Generate glyphId cache -> item
|
||||||
|
//-----------------------------------------------------------------
|
||||||
|
BuildGlyphItemCache();
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------
|
||||||
|
// 3. Look at the 6 glyphs sockets
|
||||||
|
//-----------------------------------------------------------------
|
||||||
|
std::ostringstream list;
|
||||||
|
bool first = true;
|
||||||
|
|
||||||
|
for (uint8 slot = 0; slot < MAX_GLYPH_SLOT_INDEX; ++slot)
|
||||||
|
{
|
||||||
|
uint32 glyphId = bot->GetGlyph(slot);
|
||||||
|
if (!glyphId)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto it = s_GlyphItemCache.find(glyphId);
|
||||||
|
if (it == s_GlyphItemCache.end())
|
||||||
|
continue; // No glyph found (rare)
|
||||||
|
|
||||||
|
if (!first)
|
||||||
|
list << ", ";
|
||||||
|
|
||||||
|
// chat->FormatItem
|
||||||
|
list << chat->FormatItem(it->second);
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------
|
||||||
|
// 4. Send chat messages
|
||||||
|
//-----------------------------------------------------------------
|
||||||
|
if (first) // no glyphs
|
||||||
|
botAI->TellMaster("No glyphs equipped");
|
||||||
|
else
|
||||||
|
botAI->TellMaster(std::string("Glyphs: ") + list.str());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
21
src/strategy/actions/TellGlyphsAction.h
Normal file
21
src/strategy/actions/TellGlyphsAction.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license, you may redistribute it
|
||||||
|
* and/or modify it under version 2 of the License, or (at your option), any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _PLAYERBOT_TELLGLYPHSACTION_H
|
||||||
|
#define _PLAYERBOT_TELLGLYPHSACTION_H
|
||||||
|
|
||||||
|
#include "Action.h"
|
||||||
|
|
||||||
|
class TellGlyphsAction : public Action
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TellGlyphsAction(PlayerbotAI* ai, std::string const name = "glyphs")
|
||||||
|
: Action(ai, name) {}
|
||||||
|
|
||||||
|
bool Execute(Event event) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
@ -4,7 +4,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "WorldBuffAction.h"
|
#include "WorldBuffAction.h"
|
||||||
|
|
||||||
#include "AiFactory.h"
|
#include "AiFactory.h"
|
||||||
#include "Event.h"
|
#include "Event.h"
|
||||||
#include "Playerbots.h"
|
#include "Playerbots.h"
|
||||||
@ -13,11 +12,12 @@ bool WorldBuffAction::Execute(Event event)
|
|||||||
{
|
{
|
||||||
std::string const text = event.getParam();
|
std::string const text = event.getParam();
|
||||||
|
|
||||||
for (auto& wb : NeedWorldBuffs(bot))
|
std::vector<uint32> buffs = NeedWorldBuffs(bot); // Get matching buffs
|
||||||
|
|
||||||
|
for (auto& wb : buffs)
|
||||||
{
|
{
|
||||||
bot->AddAura(wb, bot);
|
bot->AddAura(wb, bot);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +70,6 @@ std::vector<uint32> WorldBuffAction::NeedWorldBuffs(Unit* unit)
|
|||||||
// If tank, effectiveSpec remains unchanged
|
// If tank, effectiveSpec remains unchanged
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (auto const& wb : sPlayerbotAIConfig->worldBuffs)
|
for (auto const& wb : sPlayerbotAIConfig->worldBuffs)
|
||||||
{
|
{
|
||||||
// Faction check
|
// Faction check
|
||||||
|
|||||||
@ -103,6 +103,8 @@ void ChatCommandHandlerStrategy::InitTriggers(std::vector<TriggerNode*>& trigger
|
|||||||
triggers.push_back(
|
triggers.push_back(
|
||||||
new TriggerNode("wipe", NextAction::array(0, new NextAction("wipe", relevance), nullptr)));
|
new TriggerNode("wipe", NextAction::array(0, new NextAction("wipe", relevance), nullptr)));
|
||||||
triggers.push_back(new TriggerNode("pet", NextAction::array(0, new NextAction("pet", relevance), nullptr)));
|
triggers.push_back(new TriggerNode("pet", NextAction::array(0, new NextAction("pet", relevance), nullptr)));
|
||||||
|
triggers.push_back(new TriggerNode("glyphs", NextAction::array(0, new NextAction("glyphs", relevance), nullptr))); // Added for custom Glyphs
|
||||||
|
triggers.push_back(new TriggerNode("glyph equip", NextAction::array(0, new NextAction("glyph equip", relevance), nullptr))); // Added for custom Glyphs
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatCommandHandlerStrategy::ChatCommandHandlerStrategy(PlayerbotAI* botAI) : PassTroughStrategy(botAI)
|
ChatCommandHandlerStrategy::ChatCommandHandlerStrategy(PlayerbotAI* botAI) : PassTroughStrategy(botAI)
|
||||||
@ -183,4 +185,6 @@ ChatCommandHandlerStrategy::ChatCommandHandlerStrategy(PlayerbotAI* botAI) : Pas
|
|||||||
supported.push_back("unlock items");
|
supported.push_back("unlock items");
|
||||||
supported.push_back("unlock traded item");
|
supported.push_back("unlock traded item");
|
||||||
supported.push_back("pet");
|
supported.push_back("pet");
|
||||||
|
supported.push_back("glyphs"); // Added for custom Glyphs
|
||||||
|
supported.push_back("glyph equip"); // Added for custom Glyphs
|
||||||
}
|
}
|
||||||
|
|||||||
@ -134,6 +134,8 @@ public:
|
|||||||
creators["qi"] = &ChatTriggerContext::qi;
|
creators["qi"] = &ChatTriggerContext::qi;
|
||||||
creators["wipe"] = &ChatTriggerContext::wipe;
|
creators["wipe"] = &ChatTriggerContext::wipe;
|
||||||
creators["pet"] = &ChatTriggerContext::pet;
|
creators["pet"] = &ChatTriggerContext::pet;
|
||||||
|
creators["glyphs"] = &ChatTriggerContext::glyphs; // Added for custom Glyphs
|
||||||
|
creators["glyph equip"] = &ChatTriggerContext::glyph_equip; // Added for custom Glyphs
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -247,6 +249,8 @@ private:
|
|||||||
static Trigger* qi(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "qi"); }
|
static Trigger* qi(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "qi"); }
|
||||||
static Trigger* wipe(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "wipe"); }
|
static Trigger* wipe(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "wipe"); }
|
||||||
static Trigger* pet(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "pet"); }
|
static Trigger* pet(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "pet"); }
|
||||||
|
static Trigger* glyphs(PlayerbotAI* botAI) { return new ChatCommandTrigger(botAI, "glyphs"); } // Added for custom Glyphs
|
||||||
|
static Trigger* glyph_equip(PlayerbotAI* ai) { return new ChatCommandTrigger(ai, "glyph equip"); } // Added for custom Glyphs
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -160,6 +160,7 @@ public:
|
|||||||
creators["my attacker count"] = &ValueContext::my_attacker_count;
|
creators["my attacker count"] = &ValueContext::my_attacker_count;
|
||||||
creators["has aggro"] = &ValueContext::has_aggro;
|
creators["has aggro"] = &ValueContext::has_aggro;
|
||||||
creators["mounted"] = &ValueContext::mounted;
|
creators["mounted"] = &ValueContext::mounted;
|
||||||
|
creators["custom_glyphs"] = &ValueContext::custom_glyphs; // Added for custom glyphs
|
||||||
|
|
||||||
creators["can loot"] = &ValueContext::can_loot;
|
creators["can loot"] = &ValueContext::can_loot;
|
||||||
creators["loot target"] = &ValueContext::loot_target;
|
creators["loot target"] = &ValueContext::loot_target;
|
||||||
@ -554,6 +555,13 @@ private:
|
|||||||
static UntypedValue* last_flee_angle(PlayerbotAI* ai) { return new LastFleeAngleValue(ai); }
|
static UntypedValue* last_flee_angle(PlayerbotAI* ai) { return new LastFleeAngleValue(ai); }
|
||||||
static UntypedValue* last_flee_timestamp(PlayerbotAI* ai) { return new LastFleeTimestampValue(ai); }
|
static UntypedValue* last_flee_timestamp(PlayerbotAI* ai) { return new LastFleeTimestampValue(ai); }
|
||||||
static UntypedValue* recently_flee_info(PlayerbotAI* ai) { return new RecentlyFleeInfo(ai); }
|
static UntypedValue* recently_flee_info(PlayerbotAI* ai) { return new RecentlyFleeInfo(ai); }
|
||||||
|
// -------------------------------------------------------
|
||||||
|
// Flag for cutom glyphs : true when /w bot glyph equip …
|
||||||
|
// -------------------------------------------------------
|
||||||
|
static UntypedValue* custom_glyphs(PlayerbotAI* ai)
|
||||||
|
{
|
||||||
|
return new ManualSetValue<bool>(ai, false, "custom_glyphs");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user