[Bots] Add Data Bucket support to Bot Spell Entries. (#2505)

* [Bots] Add Data Bucket support to Bot Spell Entries.

* Cleanup Formatting and Functions

* Consolidated "CheckDataBucket" Functions

* Remove unneeded CastToClient

* Add choice to format data buckets as either "character-id" or "bot-id" to Bot spells

* Fix Formatting

* Clean up.

* Update npc.h

* Fix Bot Casting issues

* Formatting

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
Co-authored-by: Kinglykrab <89047260+Kinglykrab@users.noreply.github.com>
This commit is contained in:
Aeadoin
2022-11-06 17:06:01 -05:00
committed by GitHub
parent de63eaa4b2
commit 7e7358e9b6
18 changed files with 623 additions and 367 deletions
+86 -11
View File
@@ -2188,7 +2188,6 @@ void Bot::AI_Bot_Start(uint32 iMoveDelay) {
}
if (NPCTypedata) {
AI_AddBotSpells(NPCTypedata->npc_spells_id);
ProcessSpecialAbilities(NPCTypedata->special_abilities);
AI_AddNPCSpellsEffects(NPCTypedata->npc_spells_effects_id);
}
@@ -3345,8 +3344,8 @@ void Bot::AI_Process()
TEST_COMBATANTS();
auto ExtraAttackChanceBonus =
(spellbonuses.ExtraAttackChance[0] + itembonuses.ExtraAttackChance[0] +
aabonuses.ExtraAttackChance[0]);
(spellbonuses.ExtraAttackChance[0] + itembonuses.ExtraAttackChance[0] +
aabonuses.ExtraAttackChance[0]);
if (ExtraAttackChanceBonus) {
if (p_item && p_item->GetItem()->IsType2HWeapon()) {
@@ -3951,14 +3950,14 @@ bool Bot::Spawn(Client* botCharacterOwner) {
void Bot::RemoveBotItemBySlot(uint16 slot_id, std::string *error_message)
{
if (!GetBotID()) {
return;
return;
}
if (!database.botdb.DeleteItemBySlot(GetBotID(), slot_id)) {
*error_message = BotDatabase::fail::DeleteItemBySlot();
if (!database.botdb.DeleteItemBySlot(GetBotID(), slot_id)) {
*error_message = BotDatabase::fail::DeleteItemBySlot();
}
m_inv.DeleteItem(slot_id);
m_inv.DeleteItem(slot_id);
UpdateEquipmentLight();
}
@@ -3982,7 +3981,7 @@ uint32 Bot::GetBotItemBySlot(uint16 slot_id)
{
uint32 item_id = 0;
if (!GetBotID()) {
return item_id;
return item_id;
}
if (!database.botdb.LoadItemBySlot(GetBotID(), slot_id, item_id)) {
@@ -7031,11 +7030,11 @@ int64 Bot::GetActSpellDamage(uint16 spell_id, int64 value, Mob* target) {
//Crtical Hit Calculation pathway
if (chance > 0 || (GetClass() == WIZARD && GetLevel() >= RuleI(Spells, WizCritLevel))) {
int32 ratio = RuleI(Spells, BaseCritRatio); //Critical modifier is applied from spell effects only. Keep at 100 for live like criticals.
int32 ratio = RuleI(Spells, BaseCritRatio); //Critical modifier is applied from spell effects only. Keep at 100 for live like criticals.
//Improved Harm Touch is a guaranteed crit if you have at least one level of SCF.
if (spell_id == SPELL_IMP_HARM_TOUCH && (GetAA(aaSpellCastingFury) > 0) && (GetAA(aaUnholyTouch) > 0))
chance = 100;
chance = 100;
if (spells[spell_id].override_crit_chance > 0 && chance > spells[spell_id].override_crit_chance)
chance = spells[spell_id].override_crit_chance;
@@ -7226,7 +7225,7 @@ int32 Bot::GetActSpellCasttime(uint16 spell_id, int32 casttime) {
uint8 botlevel = GetLevel();
uint8 botclass = GetClass();
if (botlevel >= 51 && casttime >= 3000 && !spells[spell_id].good_effect &&
(botclass == SHADOWKNIGHT || botclass == RANGER || botclass == PALADIN || botclass == BEASTLORD)) {
(botclass == SHADOWKNIGHT || botclass == RANGER || botclass == PALADIN || botclass == BEASTLORD)) {
int level_mod = std::min(15, botlevel - 50);
cast_reducer += level_mod * 3;
}
@@ -9235,6 +9234,8 @@ void Bot::CalcBotStats(bool showtext) {
CalcBonuses();
GetBotOwnerDataBuckets();
GetBotDataBuckets();
AI_AddBotSpells(GetBotSpellID());
if(showtext) {
@@ -10322,6 +10323,80 @@ void Bot::SpawnBotGroupByName(Client* c, std::string botgroup_name, uint32 leade
);
}
bool Bot::GetBotOwnerDataBuckets()
{
auto bot_owner = GetBotOwner();
if (!bot_owner) {
return false;
}
auto query = fmt::format(
"SELECT `key`, `value` FROM data_buckets WHERE `key` LIKE '{}-%'",
Strings::Escape(bot_owner->GetBucketKey())
);
auto results = database.QueryDatabase(query);
if (!results.Success() || !results.RowCount()) {
return false;
}
for (auto row : results) {
bot_data_buckets.insert(std::pair<std::string,std::string>(row[0], row[1]));
}
return true;
}
bool Bot::GetBotDataBuckets()
{
auto query = fmt::format(
"SELECT `key`, `value` FROM data_buckets WHERE `key` LIKE '{}-%'",
Strings::Escape(GetBucketKey())
);
auto results = database.QueryDatabase(query);
if (!results.Success() || !results.RowCount()) {
return false;
}
for (auto row : results) {
bot_data_buckets.insert(std::pair<std::string,std::string>(row[0], row[1]));
}
return true;
}
bool Bot::CheckDataBucket(std::string bucket_name, std::string bucket_value, uint8 bucket_comparison)
{
if (!bucket_name.empty() && !bucket_value.empty()) {
auto full_name = fmt::format(
"{}-{}",
GetBucketKey(),
bucket_name
);
auto player_value = bot_data_buckets[full_name];
if (player_value.empty() && GetBotOwner()) {
full_name = fmt::format(
"{}-{}",
GetBotOwner()->GetBucketKey(),
bucket_name
);
player_value = bot_data_buckets[full_name];
if (player_value.empty()) {
return false;
}
}
if (zone->CheckDataBucket(bucket_comparison, bucket_value, player_value)) {
return true;
}
}
return false;
}
uint8 Bot::spell_casting_chances[SPELL_TYPE_COUNT][PLAYER_CLASS_COUNT][EQ::constants::STANCE_TYPE_COUNT][cntHSND] = { 0 };
#endif