mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-17 03:08:26 +00:00
Implement AIBot_spells_by_type to reduce looping when searching for spells
This commit is contained in:
+44
-2
@@ -6061,7 +6061,6 @@ bool Bot::DoFinishedSpellSingleTarget(uint16 spell_id, Mob* spellTarget, EQ::spe
|
||||
|
||||
bool Bot::DoFinishedSpellGroupTarget(uint16 spell_id, Mob* spellTarget, EQ::spells::CastingSlot slot, bool& stopLogic) {
|
||||
bool isMainGroupMGB = false;
|
||||
Raid* raid = GetStoredRaid();
|
||||
|
||||
if (isMainGroupMGB && (GetClass() != Class::Bard)) {
|
||||
BotGroupSay(
|
||||
@@ -9718,7 +9717,7 @@ bool Bot::BotHasEnoughMana(uint16 spell_id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Bot::IsTargetAlreadyReceivingSpell(Mob* tar, uint16 spell_id) { //TODO bot rewrite - add raid and spell targets
|
||||
bool Bot::IsTargetAlreadyReceivingSpell(Mob* tar, uint16 spell_id) {
|
||||
if (!tar || !spell_id) {
|
||||
return true;
|
||||
}
|
||||
@@ -11971,3 +11970,46 @@ void Bot::CleanBotBlockedBuffs()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<BotSpells_Struct_wIndex> Bot::BotGetSpellsByType(uint16 spellType) {
|
||||
if (!AIBot_spells_by_type[spellType].empty()) {
|
||||
return AIBot_spells_by_type[spellType];
|
||||
}
|
||||
else {
|
||||
spellType = GetParentSpellType(spellType);
|
||||
|
||||
return AIBot_spells_by_type[spellType];
|
||||
}
|
||||
}
|
||||
|
||||
void Bot::AssignBotSpellsToTypes(std::vector<BotSpells_Struct>& AIBot_spells, std::unordered_map<uint16, std::vector<BotSpells_Struct_wIndex>>& AIBot_spells_by_type) {
|
||||
AIBot_spells_by_type.clear();
|
||||
|
||||
for (size_t i = 0; i < AIBot_spells.size(); ++i) {
|
||||
const auto& spell = AIBot_spells[i];
|
||||
|
||||
if (spell.spellid <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BotSpells_Struct_wIndex spellWithIndex{
|
||||
static_cast<uint32>(i),
|
||||
spell.type,
|
||||
spell.spellid,
|
||||
spell.manacost,
|
||||
spell.time_cancast,
|
||||
spell.recast_delay,
|
||||
spell.priority,
|
||||
spell.resist_adjust,
|
||||
spell.minlevel,
|
||||
spell.maxlevel,
|
||||
spell.min_hp,
|
||||
spell.max_hp,
|
||||
spell.bucket_name,
|
||||
spell.bucket_value,
|
||||
spell.bucket_comparison
|
||||
};
|
||||
|
||||
AIBot_spells_by_type[spell.type].emplace_back(spellWithIndex);
|
||||
}
|
||||
}
|
||||
|
||||
+6
-3
@@ -236,6 +236,7 @@ public:
|
||||
uint16 BotGetSpells(int spellslot) { return AIBot_spells[spellslot].spellid; }
|
||||
uint32 BotGetSpellType(int spellslot) { return AIBot_spells[spellslot].type; }
|
||||
uint16 BotGetSpellPriority(int spellslot) { return AIBot_spells[spellslot].priority; }
|
||||
std::vector<BotSpells_Struct_wIndex> BotGetSpellsByType(uint16 spellType);
|
||||
float GetProcChances(float ProcBonus, uint16 hand) override;
|
||||
int GetHandToHandDamage(void) override;
|
||||
bool TryFinishingBlow(Mob *defender, int64 &damage) override;
|
||||
@@ -466,6 +467,7 @@ public:
|
||||
void SetGroupSpellTargetList(std::vector<Mob*> spellTargetList) { _groupSpellTargetList = spellTargetList; }
|
||||
Raid* GetStoredRaid() { return _storedRaid; }
|
||||
void SetStoredRaid(Raid* storedRaid) { _storedRaid = storedRaid; }
|
||||
void AssignBotSpellsToTypes(std::vector<BotSpells_Struct>& AIBot_spells, std::unordered_map<uint16, std::vector<BotSpells_Struct_wIndex>>& AIBot_spells_by_type);
|
||||
bool IsTargetAlreadyReceivingSpell(Mob* tar, uint16 spell_id);
|
||||
bool DoResistCheck(Mob* target, uint16 spell_id, int32 resist_limit);
|
||||
bool DoResistCheckBySpellType(Mob* tar, uint16 spell_id, uint16 spellType);
|
||||
@@ -622,9 +624,9 @@ public:
|
||||
static BotSpell GetBestBotSpellForNukeByTargetType(Bot* botCaster, SpellTargetType targetType, uint16 spellType, bool AE = false, Mob* tar = nullptr);
|
||||
static BotSpell GetBestBotSpellForStunByTargetType(Bot* botCaster, SpellTargetType targetType, uint16 spellType, bool AE = false, Mob* tar = nullptr);
|
||||
static BotSpell GetBestBotWizardNukeSpellByTargetResists(Bot* botCaster, Mob* target, uint16 spellType);
|
||||
static BotSpell GetDebuffBotSpell(Bot* botCaster, Mob* target);
|
||||
static BotSpell GetDebuffBotSpell(Bot* botCaster, Mob* target, uint16 spellType);
|
||||
static BotSpell GetBestBotSpellForCure(Bot* botCaster, Mob* target, uint16 spellType);
|
||||
static BotSpell GetBestBotSpellForResistDebuff(Bot* botCaster, Mob* target);
|
||||
static BotSpell GetBestBotSpellForResistDebuff(Bot* botCaster, Mob* target, uint16 spellType);
|
||||
static BotSpell GetBestBotSpellForNukeByBodyType(Bot* botCaster, uint8 bodyType, uint16 spellType, bool AE = false, Mob* tar = nullptr);
|
||||
static BotSpell GetBestBotSpellForRez(Bot* botCaster, Mob* target, uint16 spellType);
|
||||
static BotSpell GetBestBotSpellForCharm(Bot* botCaster, Mob* target, uint16 spellType);
|
||||
@@ -1020,6 +1022,7 @@ protected:
|
||||
|
||||
std::vector<BotSpells_Struct> AIBot_spells;
|
||||
std::vector<BotSpells_Struct> AIBot_spells_enforced;
|
||||
std::unordered_map<uint16, std::vector<BotSpells_Struct_wIndex>> AIBot_spells_by_type;
|
||||
std::vector<BotTimer_Struct> bot_timers;
|
||||
std::vector<BotBlockedBuffs_Struct> bot_blocked_buffs;
|
||||
|
||||
@@ -1099,7 +1102,7 @@ private:
|
||||
bool _commandedSpell;
|
||||
bool _pullingSpell;
|
||||
|
||||
std::vector<Mob*> _spellTargetList; // TODO bot rewrite - implement this and raid
|
||||
std::vector<Mob*> _spellTargetList;
|
||||
std::vector<Mob*> _groupSpellTargetList;
|
||||
Raid* _storedRaid;
|
||||
|
||||
|
||||
@@ -81,6 +81,24 @@ struct BotSpells_Struct {
|
||||
uint8 bucket_comparison;
|
||||
};
|
||||
|
||||
struct BotSpells_Struct_wIndex {
|
||||
uint32 index; //index of AIBot_spells
|
||||
uint32 type; // 0 = never, must be one (and only one) of the defined values
|
||||
int16 spellid; // <= 0 = no spell
|
||||
int16 manacost; // -1 = use spdat, -2 = no cast time
|
||||
uint32 time_cancast; // when we can cast this spell next
|
||||
int32 recast_delay;
|
||||
int16 priority;
|
||||
int16 resist_adjust;
|
||||
uint8 minlevel;
|
||||
uint8 maxlevel;
|
||||
int16 min_hp; // >0 won't cast if HP is below
|
||||
int16 max_hp; // >0 won't cast if HP is above
|
||||
std::string bucket_name;
|
||||
std::string bucket_value;
|
||||
uint8 bucket_comparison;
|
||||
};
|
||||
|
||||
struct BotTimer_Struct {
|
||||
uint32 timer_id;
|
||||
uint32 timer_value;
|
||||
|
||||
+35
-32
@@ -896,7 +896,7 @@ std::list<BotSpell> Bot::GetBotSpellsForSpellEffect(Bot* botCaster, uint16 spell
|
||||
}
|
||||
|
||||
if (botCaster->AI_HasSpells()) {
|
||||
std::vector<BotSpells_Struct> botSpellList = botCaster->AIBot_spells;
|
||||
std::vector<BotSpells_Struct_wIndex> botSpellList = botCaster->BotGetSpellsByType(spellType);
|
||||
|
||||
for (int i = botSpellList.size() - 1; i >= 0; i--) {
|
||||
if (!IsValidSpellAndLoS(botSpellList[i].spellid, botCaster->HasLoS())) {
|
||||
@@ -911,7 +911,7 @@ std::list<BotSpell> Bot::GetBotSpellsForSpellEffect(Bot* botCaster, uint16 spell
|
||||
) {
|
||||
BotSpell botSpell;
|
||||
botSpell.SpellId = botSpellList[i].spellid;
|
||||
botSpell.SpellIndex = i;
|
||||
botSpell.SpellIndex = botSpellList[i].index;
|
||||
botSpell.ManaCost = botSpellList[i].manacost;
|
||||
|
||||
result.push_back(botSpell);
|
||||
@@ -934,7 +934,7 @@ std::list<BotSpell> Bot::GetBotSpellsForSpellEffectAndTargetType(Bot* botCaster,
|
||||
}
|
||||
|
||||
if (botCaster->AI_HasSpells()) {
|
||||
std::vector<BotSpells_Struct> botSpellList = botCaster->AIBot_spells;
|
||||
std::vector<BotSpells_Struct_wIndex> botSpellList = botCaster->BotGetSpellsByType(spellType);
|
||||
|
||||
for (int i = botSpellList.size() - 1; i >= 0; i--) {
|
||||
if (!IsValidSpellAndLoS(botSpellList[i].spellid, botCaster->HasLoS())) {
|
||||
@@ -953,7 +953,7 @@ std::list<BotSpell> Bot::GetBotSpellsForSpellEffectAndTargetType(Bot* botCaster,
|
||||
) {
|
||||
BotSpell botSpell;
|
||||
botSpell.SpellId = botSpellList[i].spellid;
|
||||
botSpell.SpellIndex = i;
|
||||
botSpell.SpellIndex = botSpellList[i].index;
|
||||
botSpell.ManaCost = botSpellList[i].manacost;
|
||||
result.push_back(botSpell);
|
||||
}
|
||||
@@ -975,7 +975,7 @@ std::list<BotSpell> Bot::GetBotSpellsBySpellType(Bot* botCaster, uint16 spellTyp
|
||||
}
|
||||
|
||||
if (botCaster->AI_HasSpells()) {
|
||||
std::vector<BotSpells_Struct> botSpellList = botCaster->AIBot_spells;
|
||||
std::vector<BotSpells_Struct_wIndex> botSpellList = botCaster->BotGetSpellsByType(spellType);
|
||||
|
||||
for (int i = botSpellList.size() - 1; i >= 0; i--) {
|
||||
if (!IsValidSpellAndLoS(botSpellList[i].spellid, botCaster->HasLoS())) {
|
||||
@@ -989,7 +989,7 @@ std::list<BotSpell> Bot::GetBotSpellsBySpellType(Bot* botCaster, uint16 spellTyp
|
||||
) {
|
||||
BotSpell botSpell;
|
||||
botSpell.SpellId = botSpellList[i].spellid;
|
||||
botSpell.SpellIndex = i;
|
||||
botSpell.SpellIndex = botSpellList[i].index;
|
||||
botSpell.ManaCost = botSpellList[i].manacost;
|
||||
|
||||
result.push_back(botSpell);
|
||||
@@ -1004,7 +1004,7 @@ std::vector<BotSpell_wPriority> Bot::GetPrioritizedBotSpellsBySpellType(Bot* bot
|
||||
std::vector<BotSpell_wPriority> result;
|
||||
|
||||
if (botCaster && botCaster->AI_HasSpells()) {
|
||||
std::vector<BotSpells_Struct> botSpellList = botCaster->AIBot_spells;
|
||||
std::vector<BotSpells_Struct_wIndex> botSpellList = botCaster->BotGetSpellsByType(spellType);
|
||||
|
||||
for (int i = botSpellList.size() - 1; i >= 0; i--) {
|
||||
if (!IsValidSpellAndLoS(botSpellList[i].spellid, botCaster->HasLoS())) {
|
||||
@@ -1062,7 +1062,7 @@ std::vector<BotSpell_wPriority> Bot::GetPrioritizedBotSpellsBySpellType(Bot* bot
|
||||
) {
|
||||
BotSpell_wPriority botSpell;
|
||||
botSpell.SpellId = botSpellList[i].spellid;
|
||||
botSpell.SpellIndex = i;
|
||||
botSpell.SpellIndex = botSpellList[i].index;
|
||||
botSpell.ManaCost = botSpellList[i].manacost;
|
||||
botSpell.Priority = botSpellList[i].priority;
|
||||
|
||||
@@ -1089,7 +1089,7 @@ BotSpell Bot::GetFirstBotSpellBySpellType(Bot* botCaster, uint16 spellType) {
|
||||
result.ManaCost = 0;
|
||||
|
||||
if (botCaster && botCaster->AI_HasSpells()) {
|
||||
std::vector<BotSpells_Struct> botSpellList = botCaster->AIBot_spells;
|
||||
std::vector<BotSpells_Struct_wIndex> botSpellList = botCaster->BotGetSpellsByType(spellType);
|
||||
|
||||
for (int i = botSpellList.size() - 1; i >= 0; i--) {
|
||||
if (!IsValidSpellAndLoS(botSpellList[i].spellid, botCaster->HasLoS())) {
|
||||
@@ -1102,7 +1102,7 @@ BotSpell Bot::GetFirstBotSpellBySpellType(Bot* botCaster, uint16 spellType) {
|
||||
botCaster->IsValidSpellTypeBySpellID(spellType, botSpellList[i].spellid)
|
||||
) {
|
||||
result.SpellId = botSpellList[i].spellid;
|
||||
result.SpellIndex = i;
|
||||
result.SpellIndex = botSpellList[i].index;
|
||||
result.ManaCost = botSpellList[i].manacost;
|
||||
|
||||
break;
|
||||
@@ -1197,7 +1197,7 @@ BotSpell Bot::GetBestBotSpellForPercentageHeal(Bot *botCaster, Mob* tar, uint16
|
||||
result.ManaCost = 0;
|
||||
|
||||
if (botCaster && botCaster->AI_HasSpells()) {
|
||||
std::vector<BotSpells_Struct> botSpellList = botCaster->AIBot_spells;
|
||||
std::vector<BotSpells_Struct_wIndex> botSpellList = botCaster->BotGetSpellsByType(spellType);
|
||||
for (int i = botSpellList.size() - 1; i >= 0; i--) {
|
||||
if (!IsValidSpell(botSpellList[i].spellid)) {
|
||||
continue;
|
||||
@@ -1210,7 +1210,7 @@ BotSpell Bot::GetBestBotSpellForPercentageHeal(Bot *botCaster, Mob* tar, uint16
|
||||
botCaster->CastChecks(botSpellList[i].spellid, tar, spellType)
|
||||
) {
|
||||
result.SpellId = botSpellList[i].spellid;
|
||||
result.SpellIndex = i;
|
||||
result.SpellIndex = botSpellList[i].index;
|
||||
result.ManaCost = botSpellList[i].manacost;
|
||||
|
||||
break;
|
||||
@@ -1906,7 +1906,7 @@ BotSpell Bot::GetBestBotWizardNukeSpellByTargetResists(Bot* botCaster, Mob* targ
|
||||
return result;
|
||||
}
|
||||
|
||||
BotSpell Bot::GetDebuffBotSpell(Bot* botCaster, Mob *tar) {
|
||||
BotSpell Bot::GetDebuffBotSpell(Bot* botCaster, Mob *tar, uint16 spellType) {
|
||||
BotSpell result;
|
||||
|
||||
result.SpellId = 0;
|
||||
@@ -1917,7 +1917,7 @@ BotSpell Bot::GetDebuffBotSpell(Bot* botCaster, Mob *tar) {
|
||||
return result;
|
||||
|
||||
if (botCaster->AI_HasSpells()) {
|
||||
std::vector<BotSpells_Struct> botSpellList = botCaster->AIBot_spells;
|
||||
std::vector<BotSpells_Struct_wIndex> botSpellList = botCaster->BotGetSpellsByType(spellType);
|
||||
|
||||
for (int i = botSpellList.size() - 1; i >= 0; i--) {
|
||||
if (!IsValidSpellAndLoS(botSpellList[i].spellid, botCaster->HasLoS())) {
|
||||
@@ -1929,7 +1929,7 @@ BotSpell Bot::GetDebuffBotSpell(Bot* botCaster, Mob *tar) {
|
||||
&& tar->CanBuffStack(botSpellList[i].spellid, botCaster->GetLevel(), true) >= 0)
|
||||
&& botCaster->CheckSpellRecastTimer(botSpellList[i].spellid)) {
|
||||
result.SpellId = botSpellList[i].spellid;
|
||||
result.SpellIndex = i;
|
||||
result.SpellIndex = botSpellList[i].index;
|
||||
result.ManaCost = botSpellList[i].manacost;
|
||||
|
||||
break;
|
||||
@@ -1940,7 +1940,7 @@ BotSpell Bot::GetDebuffBotSpell(Bot* botCaster, Mob *tar) {
|
||||
return result;
|
||||
}
|
||||
|
||||
BotSpell Bot::GetBestBotSpellForResistDebuff(Bot* botCaster, Mob *tar) {
|
||||
BotSpell Bot::GetBestBotSpellForResistDebuff(Bot* botCaster, Mob *tar, uint16 spellType) {
|
||||
BotSpell result;
|
||||
|
||||
result.SpellId = 0;
|
||||
@@ -1963,7 +1963,7 @@ BotSpell Bot::GetBestBotSpellForResistDebuff(Bot* botCaster, Mob *tar) {
|
||||
bool needsDiseaseResistDebuff = (tar->GetDR() + level_mod) > 100;
|
||||
|
||||
if (botCaster->AI_HasSpells()) {
|
||||
std::vector<BotSpells_Struct> botSpellList = botCaster->AIBot_spells;
|
||||
std::vector<BotSpells_Struct_wIndex> botSpellList = botCaster->BotGetSpellsByType(spellType);
|
||||
|
||||
for (int i = botSpellList.size() - 1; i >= 0; i--) {
|
||||
if (!IsValidSpellAndLoS(botSpellList[i].spellid, botCaster->HasLoS())) {
|
||||
@@ -1980,7 +1980,7 @@ BotSpell Bot::GetBestBotSpellForResistDebuff(Bot* botCaster, Mob *tar) {
|
||||
&& tar->CanBuffStack(botSpellList[i].spellid, botCaster->GetLevel(), true) >= 0)
|
||||
&& botCaster->CheckSpellRecastTimer(botSpellList[i].spellid)) {
|
||||
result.SpellId = botSpellList[i].spellid;
|
||||
result.SpellIndex = i;
|
||||
result.SpellIndex = botSpellList[i].index;
|
||||
result.ManaCost = botSpellList[i].manacost;
|
||||
|
||||
break;
|
||||
@@ -2165,6 +2165,8 @@ bool Bot::AI_AddBotSpells(uint32 bot_spell_id) {
|
||||
npc_spells_id = bot_spell_id;
|
||||
AIBot_spells.clear();
|
||||
AIBot_spells_enforced.clear();
|
||||
AIBot_spells_by_type.clear();
|
||||
|
||||
if (!bot_spell_id) {
|
||||
AIautocastspell_timer->Disable();
|
||||
return false;
|
||||
@@ -2455,6 +2457,7 @@ bool Bot::AI_AddBotSpells(uint32 bot_spell_id) {
|
||||
AIautocastspell_timer->Disable();
|
||||
} else {
|
||||
AIautocastspell_timer->Trigger();
|
||||
AssignBotSpellsToTypes(AIBot_spells, AIBot_spells_by_type); // Assign AIBot_spells to AIBot_spells_by_type with an index
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -2630,20 +2633,20 @@ void Bot::AddSpellToBotEnforceList(
|
||||
HasAISpell = true;
|
||||
BotSpells_Struct t;
|
||||
|
||||
t.priority = iPriority;
|
||||
t.spellid = iSpellID;
|
||||
t.type = iType;
|
||||
t.manacost = iManaCost;
|
||||
t.recast_delay = iRecastDelay;
|
||||
t.time_cancast = 0;
|
||||
t.resist_adjust = iResistAdjust;
|
||||
t.minlevel = min_level;
|
||||
t.maxlevel = maxlevel;
|
||||
t.min_hp = min_hp;
|
||||
t.max_hp = max_hp;
|
||||
t.bucket_name = bucket_name;
|
||||
t.bucket_value = bucket_value;
|
||||
t.bucket_comparison = bucket_comparison;
|
||||
t.priority = iPriority;
|
||||
t.spellid = iSpellID;
|
||||
t.type = iType;
|
||||
t.manacost = iManaCost;
|
||||
t.recast_delay = iRecastDelay;
|
||||
t.time_cancast = 0;
|
||||
t.resist_adjust = iResistAdjust;
|
||||
t.minlevel = min_level;
|
||||
t.maxlevel = maxlevel;
|
||||
t.min_hp = min_hp;
|
||||
t.max_hp = max_hp;
|
||||
t.bucket_name = bucket_name;
|
||||
t.bucket_value = bucket_value;
|
||||
t.bucket_comparison = bucket_comparison;
|
||||
|
||||
AIBot_spells_enforced.push_back(t);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user