Skip to content

Commit

Permalink
NPCBots: Implement saving per-bot settings: Rogue poisons, Shaman enc…
Browse files Browse the repository at this point in the history
…hants, Paladin aura, Hunter pet type, Warlock pet type. Fix weapon enchants set by player disappearing on Rogues / Shamans after server restart

(cherry picked from commit 8dc82c25e2203d2272ff7aa6e57564ee1686732f)

# Conflicts:
#	data/sql/custom/db_characters/2024_11_21_00_characters_npcbot.sql
  • Loading branch information
trickerer committed Nov 21, 2024
1 parent 1d9f8b3 commit 3fbdf3b
Show file tree
Hide file tree
Showing 14 changed files with 308 additions and 168 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
--
ALTER TABLE `characters_npcbot` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
ALTER TABLE `characters_npcbot` ADD `miscvalues` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL AFTER `spells_disabled`;
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,7 @@ void CharacterDatabaseConnection::DoPrepareStatements()
PrepareStatement(CHAR_UPD_NPCBOT_FACTION, "UPDATE characters_npcbot SET faction = ? WHERE entry = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_NPCBOT_SPEC, "UPDATE characters_npcbot SET spec = ? WHERE entry = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_NPCBOT_DISABLED_SPELLS, "UPDATE characters_npcbot SET spells_disabled = ? WHERE entry = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_UPD_NPCBOT_MISCVALUES, "UPDATE characters_npcbot SET miscvalues = ? WHERE entry = ?", CONNECTION_ASYNC);
PrepareStatement(CHAR_REP_NPCBOT_STATS, "REPLACE INTO characters_npcbot_stats "
"(entry, maxhealth, maxpower, strength, agility, stamina, intellect, spirit, armor, defense, resHoly, resFire, resNature, resFrost, resShadow, resArcane, blockPct, dodgePct, parryPct, critPct, attackPower, spellPower, spellPen, hastePct, hitBonusPct, expertise, armorPenPct) VALUES "
"(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,7 @@ enum CharacterDatabaseStatements : uint32
CHAR_UPD_NPCBOT_FACTION,
CHAR_UPD_NPCBOT_SPEC,
CHAR_UPD_NPCBOT_DISABLED_SPELLS,
CHAR_UPD_NPCBOT_MISCVALUES,
CHAR_REP_NPCBOT_STATS,
CHAR_REP_NPCBOT_TRANSMOG,
CHAR_DEL_NPCBOT_TRANSMOG,
Expand Down
77 changes: 74 additions & 3 deletions src/server/game/AI/NpcBots/bot_ai.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ bot_ai::bot_ai(Creature* creature) : CreatureAI(creature)

_saveDisabledSpellsTimer = 0;
_saveDisabledSpells = false;
_saveMiscValuesTimer = 0;
_saveMiscValues = false;

_deathsCount = 0;
_killsCount = 0;
Expand Down Expand Up @@ -615,6 +617,8 @@ void bot_ai::ResetBotAI(uint8 resetType)

if ((resetType == BOTAI_RESET_DISMISS || resetType == BOTAI_RESET_LOGOUT) && !IsTempBot())
{
if (resetType == BOTAI_RESET_DISMISS)
ResetAllMiscValues();
EnableAllSpells(resetType == BOTAI_RESET_DISMISS);
InitRoles();
}
Expand Down Expand Up @@ -13137,13 +13141,13 @@ BotEquipResult bot_ai::_equip(uint8 slot, Item* newItem, ObjectGuid receiver, bo
if (slot == BOT_SLOT_MAINHAND)
{
SetAIMiscValue(BOTAI_MISC_DAGGER_MAINHAND, proto->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER);
SetAIMiscValue(BOTAI_MISC_ENCHANT_CAN_EXPIRE_MH, newItem->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT));
SetAIMiscValue(BOTAI_MISC_ENCHANT_TIMER_MH, uint32(newItem->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT) ? 0 : 1));
SetAIMiscValue(BOTAI_MISC_WEAPON_SPEC, proto->SubClass);
}
if (slot == BOT_SLOT_OFFHAND)
{
SetAIMiscValue(BOTAI_MISC_DAGGER_OFFHAND, proto->SubClass == ITEM_SUBCLASS_WEAPON_DAGGER);
SetAIMiscValue(BOTAI_MISC_ENCHANT_CAN_EXPIRE_OH, newItem->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT));
SetAIMiscValue(BOTAI_MISC_ENCHANT_TIMER_OH, uint32(newItem->GetEnchantmentId(TEMP_ENCHANTMENT_SLOT) ? 0 : 1));
}
}

Expand Down Expand Up @@ -13547,7 +13551,7 @@ void bot_ai::RemoveItemClassEnchantment(uint8 slot)
{
uint8 eslot = TEMP_ENCHANTMENT_SLOT;

if (!GetAIMiscValue(slot == BOT_SLOT_MAINHAND ? BOTAI_MISC_ENCHANT_CAN_EXPIRE_MH : BOTAI_MISC_ENCHANT_CAN_EXPIRE_OH))
if (!GetAIMiscValue(slot == BOT_SLOT_MAINHAND ? BOTAI_MISC_ENCHANT_TIMER_MH : BOTAI_MISC_ENCHANT_TIMER_OH))
return;

Item* weap = _equips[slot];
Expand Down Expand Up @@ -14806,6 +14810,7 @@ void bot_ai::DefaultInit()
InitFaction();
InitOwner();
InitEquips();
InitMiscValues();
}

firstspawn = false;
Expand Down Expand Up @@ -17834,6 +17839,18 @@ bool bot_ai::GlobalUpdate(uint32 diff)
BotDataMgr::UpdateNpcBotData(me->GetEntry(), NPCBOT_UPDATE_DISABLED_SPELLS, &npcBotData->disabled_spells);
}
}
// 2) miscavalues
if (_saveMiscValues && _saveMiscValuesTimer <= diff)
{
_saveMiscValues = false;
_saveMiscValuesTimer = 5000;

if (!IsTempBot())
{
NpcBotData* npcBotData = const_cast<NpcBotData*>(BotDataMgr::SelectNpcBotData(me->GetEntry()));
BotDataMgr::UpdateNpcBotData(me->GetEntry(), NPCBOT_UPDATE_MISCVALUES, &npcBotData->miscvalues);
}
}

if (_updateTimerEx2 <= diff)
{
Expand Down Expand Up @@ -18628,6 +18645,7 @@ void bot_ai::CommonTimers(uint32 diff)
if (_updateTimerEx2 > diff) _updateTimerEx2 -= diff;

if (_saveDisabledSpellsTimer > diff) _saveDisabledSpellsTimer -= diff;
if (_saveMiscValuesTimer > diff) _saveMiscValuesTimer -= diff;
}

void bot_ai::UpdateReviveTimer(uint32 diff)
Expand Down Expand Up @@ -20996,6 +21014,59 @@ uint8 bot_ai::GetBotComboPoints() const
return me->GetVehicle() ? vehcomboPoints : uint8(GetAIMiscValue(BOTAI_MISC_COMBO_POINTS));
}

void bot_ai::SetAIMiscValue(uint32 data, uint32 value)
{
if (data >= BOT_MISCVALUE_SAVED_FIRST && data <= BOT_MISCVALUE_SAVED_LAST)
{
NpcBotData* npcBotData = const_cast<NpcBotData*>(BotDataMgr::SelectNpcBotData(me->GetEntry()));
if (auto it = npcBotData->miscvalues.find(data); it == npcBotData->miscvalues.end() || it->second != value)
{
npcBotData->miscvalues[data] = value;
_saveMiscValues = true;
}
}
}

void bot_ai::ResetAllMiscValues()
{
NpcBotData* npcBotData = const_cast<NpcBotData*>(BotDataMgr::SelectNpcBotData(me->GetEntry()));

for (uint32 miscval = BOT_MISCVALUE_SAVED_FIRST; miscval <= BOT_MISCVALUE_SAVED_LAST; ++miscval)
{
switch (miscval)
{
case BOTAI_MISC_ENCHANT_IS_AUTO_MH:
case BOTAI_MISC_ENCHANT_IS_AUTO_OH:
SetAIMiscValue(miscval, uint32(true));
break;
case BOTAI_MISC_ENCHANT_TIMER_MH:
case BOTAI_MISC_ENCHANT_TIMER_OH:
SetAIMiscValue(miscval, uint32(1));
break;
case BOTAI_MISC_ENCHANT_CURRENT_MH:
case BOTAI_MISC_ENCHANT_CURRENT_OH:
case BOTAI_MISC_PET_TYPE:
case BOTAI_MISC_AURA_TYPE:
SetAIMiscValue(miscval, uint32(0));
break;
default:
BOT_LOG_ERROR("npcbots", "ResetMiscValues: unknown saved miscvalue {} reset for bot {} (current: {})!", miscval, me->GetEntry(), GetAIMiscValue(miscval));
SetAIMiscValue(miscval, uint32(0));
break;
}
}

npcBotData->miscvalues.clear();
_saveMiscValues = true;
}

void bot_ai::InitMiscValues()
{
NpcBotData const* npcBotData = BotDataMgr::SelectNpcBotData(me->GetEntry());
for (auto const& p : npcBotData->miscvalues)
SetAIMiscValue(p.first, p.second);
}

float bot_ai::GetBotAmmoDPS() const
{
if (CanUseAmmo())
Expand Down
6 changes: 5 additions & 1 deletion src/server/game/AI/NpcBots/bot_ai.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,8 +263,10 @@ class bot_ai : public CreatureAI
bool CanChangeEquip(uint8 slot) const;
virtual bool CanSeeEveryone() const { return false; }
virtual float GetBotArmorPenetrationCoef() const { return armor_pen; }
void InitMiscValues();
void ResetAllMiscValues();
virtual uint32 GetAIMiscValue(uint32 /*data*/) const { return 0; }
virtual void SetAIMiscValue(uint32 /*data*/, uint32 /*value*/) {}
virtual void SetAIMiscValue(uint32 data, uint32 value);
uint8 GetBotComboPoints() const;
float GetBotAmmoDPS() const;

Expand Down Expand Up @@ -714,6 +716,7 @@ class bot_ai : public CreatureAI
uint32 _groupUpdateTimer;
//save timers
uint32 _saveDisabledSpellsTimer;
uint32 _saveMiscValuesTimer;

uint32 _lastZoneId, _lastAreaId, _lastWMOAreaId;
uint32 _selfrez_spell_id;
Expand Down Expand Up @@ -755,6 +758,7 @@ class bot_ai : public CreatureAI

//save flags
bool _saveDisabledSpells;
bool _saveMiscValues;

TeleportHomeEvent* teleHomeEvent;
TeleportFinishEvent* teleFinishEvent;
Expand Down
Loading

0 comments on commit 3fbdf3b

Please sign in to comment.