Compare commits

..

4 Commits

Author SHA1 Message Date
bashermens
965d300203 [HOTFIX] Revert "Fix/Feat: Stop bots in party from PVP when master isn't, and … (#2003)
…PVP probablity system (#1914)"

This reverts commit 02e8465a3b.


[worldserver_gdb_20260111_000520.log](https://github.com/user-attachments/files/24547263/worldserver_gdb_20260111_000520.log)


Noticed the server kept crashing all the sudden, first thought it was
local issue but see dump.
2026-01-11 01:52:25 +01:00
privatecore
dc55ecfd9c Fix wrong logic when processing quest reward spells during maintenance level-up action (#2001)
The previous behavior failed cuz if a spell has no
`SPELL_EFFECT_LEARN_SPELL`, bots learned the original spell from
`quest_template` rewards w/o any checks, when they should never learn
any spells specified in the `RewardSpell` and/or `RewardDisplaySpell`.

PR: https://github.com/mod-playerbots/mod-playerbots/pull/1996 Thx
@Wishmaster117 for the collaboration!

Fix issue https://github.com/mod-playerbots/mod-playerbots/issues/1759
2026-01-10 01:31:54 +01:00
Crow
59d6eb139e Exclude additional test enchants from bots (#1952)
Added two test enchants to exclude from the list of enchants that bots
can apply: 19927 and 44119. I also reordered the list to be in
alphanumeric order.

The important exclusion to add is 44119:
https://www.wowhead.com/wotlk/spell=44119/enchant-bracer-template

It is a test enchant that gives 34 AP on bracers; this is stronger than
any other bracer enchant for level 70 physical attackers so bots are
applying it.
2026-01-09 22:16:33 +01:00
Crow
00171a8c82 Minor fixes to .dist descriptions (#1945)
Clarified that MinEnchantingBotLevel also determines whether maintenance
will socket gems, in addition to applying enchants.

Fixed max iLevel for ZA gear in RandomGearScoreLimit description (iLevel
138 is the max that drops from the final boss, but the 3rd timed chest
gives iLevel 141 equipment).
2026-01-09 19:57:29 +01:00
5 changed files with 85 additions and 198 deletions

View File

@@ -21,7 +21,7 @@
# THRESHOLDS
# QUESTS
# COMBAT
# PALADIN BUFFS STRATEGIES
# GREATER BUFFS STRATEGIES
# CHEATS
# SPELLS
# FLIGHTPATH
@@ -91,17 +91,20 @@ AiPlayerbot.MinRandomBots = 500
AiPlayerbot.MaxRandomBots = 500
# Randombot accounts
# If you are not using any expansion at all, you may have to set this manually, in which case please ensure that RandomBotAccountCount is at least greater than (MaxRandomBots / 10 + AddClassAccountPoolSize)
# If you are not using any expansion at all, you may have to set this manually, in which case please
# ensure that RandomBotAccountCount is at least greater than (MaxRandomBots / 10 + AddClassAccountPoolSize)
# Default: 0 (automatic)
AiPlayerbot.RandomBotAccountCount = 0
# Delete all randombot accounts
# To apply this, set the number to 1 and run the Worldserver. Once deletion is complete, if you would like to recreate randombots, set the number back to 0 and rerun the Worldserver.
# To apply this, set the number to 1 and run the Worldserver. Once deletion is complete, if you would
# like to recreate randombots, set the number back to 0 and rerun the Worldserver.
AiPlayerbot.DeleteRandomBotAccounts = 0
# Disable randombots when no real players are logged in
# Default: 0 (randombots will login when server starts)
# If enabled, randombots will only log in 30 seconds (default) after a real player logs in, and will log out 300 seconds (default) after all real players log out
# If enabled, randombots will only log in 30 seconds (default) after a real player logs in, and will
# log out 300 seconds (default) after all real players log out
AiPlayerbot.DisabledWithoutRealPlayer = 0
AiPlayerbot.DisabledWithoutRealPlayerLoginDelay = 30
AiPlayerbot.DisabledWithoutRealPlayerLogoutDelay = 300
@@ -153,7 +156,8 @@ AiPlayerbot.AllowGuildBots = 1
AiPlayerbot.AllowTrustedAccountBots = 1
# Randombots will create guilds with nearby randombots
# Note: currently, randombots will not invite more bots after a guild is created (i.e., randombot guilds will have only the 10 initial randombots needed to sign the charter)
# Note: currently, randombots will not invite more bots after a guild is created,
# meaning randombot guilds will have only the 10 initial randombots needed to sign the charter
# Default: 0 (disabled)
AiPlayerbot.RandomBotGuildNearby = 0
@@ -187,7 +191,8 @@ AiPlayerbot.AutoInitOnly = 0
# Default: 1.0 (same with the player)
AiPlayerbot.AutoInitEquipLevelLimitRatio = 1.0
# Bot automatically trains spells when talking to trainer (yes = train all available spells as long as the bot has the money, free = auto trains with no money cost, no = only list spells)
# Bot automatically trains spells when talking to trainer
# yes = train all available spells as long as the bot has the money, free = auto trains with no money cost, no = only list spells
AiPlayerbot.AutoTrainSpells = yes
#
@@ -264,7 +269,7 @@ AiPlayerbot.UseFastFlyMountAtMinLevel = 70
AiPlayerbot.RandomBotShowHelmet = 1
AiPlayerbot.RandomBotShowCloak = 1
# Randombots and altbots automatically equip upgrades (bots will equip any item obtained from looting or a quest if they are sufficient upgrades)
# Randombots and altbots automatically equip any items in their inventory that are sufficient upgrades
# Default: 1 (enabled)
AiPlayerbot.AutoEquipUpgradeLoot = 1
@@ -312,7 +317,8 @@ AiPlayerbot.GlobalCooldown = 500
# Max wait time when moving
AiPlayerbot.MaxWaitForMove = 5000
# Disable use of MoveSplinePath for bot movement, will result in more erratic bot movement but means stun/snare/root/etc will work on bots (they wont reliably work when MoveSplinePath is enabled, though slowing effects still work ok)
# Enable/disable use of MoveSplinePath for bot movement
# Disabling will result in more erratic movement but is required for stuns, snares, and roots to work on bots
# Default: 0 - MoveSplinePath enabled
# 1 - MoveSplinePath disabled in BG/Arena only
# 2 - MoveSplinePath disabled everywhere
@@ -406,10 +412,11 @@ AiPlayerbot.HighMana = 65
#
#
# Bots pick their quest rewards (yes = picks the most useful item, no = list all rewards, ask = pick useful item and lists if multiple)
# Bots pick their quest rewards
# yes = picks the most useful item, no = list all rewards, ask = pick useful item and lists if multiple
AiPlayerbot.AutoPickReward = yes
# Sync quests with player (Bots will complete quests the moment you hand them in and will not loot quest items.)
# Sync quests with player (bots will complete quests the moment you hand them in and will not loot quest items.)
# Default: 1 (enabled)
AiPlayerbot.SyncQuestWithPlayer = 1
@@ -434,7 +441,7 @@ AiPlayerbot.DropObsoleteQuests = 1
# Auto add dungeon/raid strategies when entering the instance if implemented
AiPlayerbot.ApplyInstanceStrategies = 1
# Enable auto avoid aoe strategy (experimental)
# Enable auto avoid aoe strategy
# Default: 1 (enabled)
AiPlayerbot.AutoAvoidAoe = 1
@@ -461,7 +468,7 @@ AiPlayerbot.FleeingEnabled = 1
####################################################################################################
####################################################################################################
# PALADIN BUFFS STRATEGIES
# GREATER BUFFS STRATEGIES
#
#
@@ -484,12 +491,13 @@ AiPlayerbot.RPWarningCooldown = 30
#
# Enable/Disable maintenance command
# Learn all available spells and skills, refresh consumables, repair, enchant equipment and socket gems if bot's level is above AiPlayerbot.MinEnchantingBotLevel
# Learn all available spells and skills, assign talent points, refresh consumables, repair, enchant equipment, socket gems, etc.
# Applies if bot's level is above AiPlayerbot.MinEnchantingBotLevel
# Default: 1 (enabled)
AiPlayerbot.MaintenanceCommand = 1
# Enable/Disable specific maintenance command functionality for alt bots
# Disable to prevent players from giving free bags, spells, skill levels etc to their alt bots
# Disable to prevent players from giving free bags, spells, skill levels, etc. to their alt bots
# Default: 1 (enabled)
AiPlayerbot.AltMaintenanceAmmo = 1
AiPlayerbot.AltMaintenanceFood = 1
@@ -501,6 +509,7 @@ AiPlayerbot.AltMaintenanceBags = 1
AiPlayerbot.AltMaintenanceMounts = 1
AiPlayerbot.AltMaintenanceSkills = 1
# "Special Spells" consist of any spells listed in AiPlayerbot.RandomBotSpellIds and Death Gate for Death Knights
AiPlayerbot.AltMaintenanceClassSpells = 1
AiPlayerbot.AltMaintenanceAvailableSpells = 1
AiPlayerbot.AltMaintenanceSpecialSpells = 1
@@ -515,8 +524,8 @@ AiPlayerbot.AltMaintenanceReputation = 1
AiPlayerbot.AltMaintenanceAttunementQuests = 1
AiPlayerbot.AltMaintenanceKeyring = 1
# Enable/Disable autogear command, which automatically upgrades bots' gear; the quality is limited by AutoGearQualityLimit and AutoGearScoreLimit
# Enable/Disable autogear command, which automatically upgrades bots' gear
# The quality is limited by AutoGearQualityLimit and AutoGearScoreLimit
# Default: 1 (enabled)
AiPlayerbot.AutoGearCommand = 1
@@ -582,15 +591,21 @@ AiPlayerbot.BotTaxiGapJitterMs = 100
####################################################################################################
# PROFESSIONS
# Random bots currently do not get professions.
# Note: Random bots currently do not get professions
#
# EnableFishingWithMaster automatically adds the 'master fishing' strategy to bots that can fish that can.
# Automatically adds the 'master fishing' strategy to bots that have the fishing skill when the bots master fishes.
# Default: 1 (Enabled)
AiPlayerbot.EnableFishingWithMaster = 1
#FishingDistance sets how far a bot without a master will search for water, while FishingDistanceFromMaster limits it to a closer range, and overrides the following distance to the same value. EndFishingWithMaster sets the distance from water a bot needs to have to automatically drop the 'master fishing' strategy.
# Distance from itself (in yards) that a bot with a master will search for water to fish
AiPlayerbot.FishingDistanceFromMaster = 10.0
# Distance from itself (in yards) that a bot without a master will search for water to fish
# Currently not relevant since masterless bots will not fish
AiPlayerbot.FishingDistance = 40.0
# Distance from water (in yards) beyond which a bot will remove the 'master fishing' strategy
AiPlayerbot.EndFishingWithMaster = 30.0
#
@@ -719,7 +734,7 @@ AiPlayerbot.RandomGearQualityLimit = 3
# Max iLVL Phase 1(MC, Ony, ZG) = 78 | Phase 2(BWL) = 83 | Phase 2.5(AQ40) = 88 | Phase 3(Naxx40) = 92
# TBC
# Max iLVL Tier 4 = 120 | Tier 5 = 133 | Tier 6 = 164
# Max iLVL Phase 1(Kara, Gruul, Mag) = 125 | Phase 1.5(ZA) = 138 | Phase 2(SC, TK) = 141 | Phase 3(Hyjal, BT) = 156 | Phase 4(Sunwell) = 164
# Max iLVL Phase 1(Kara, Gruul, Mag) = 125 | Phase 2(SSC, TK, ZA) = 141 | Phase 3(Hyjal, BT) = 156 | Phase 4(Sunwell) = 164
# Wotlk
# Max iLVL Tier 7(10/25) = 200/213 | Tier 8(10/25) = 225/232 | Tier 9(10/25) = 232/245 | Tier 10(10/25/HC) = 251/264/290
# Max iLVL Phase 1(Naxx) = 224 | Phase 2(Ulduar) = 245 | Phase 3(ToC) = 258 | Phase 4(ICC) = 290
@@ -730,7 +745,8 @@ AiPlayerbot.RandomGearScoreLimit = 0
# Default: 1 (enabled)
AiPlayerbot.IncrementalGearInit = 1
# Set minimum level of bots that will enchant their equipment (if greater than RandomBotMaxlevel, bots will not enchant equipment)
# Set minimum level of bots that will enchant and socket gems into their equipment with maintenance
# If greater than RandomBotMaxlevel, bots will not automatically enchant equipment or socket gems
# Default: 60
AiPlayerbot.MinEnchantingBotLevel = 60
@@ -882,13 +898,15 @@ AiPlayerbot.OpenGoSpell = 6477
#
# Additional randombot strategies
# Strategies added here are applied to all randombots, in addition (or subtraction) to spec/role-based default strategies. These rules are processed after the defaults.
# Strategies added here are applied to all randombots, in addition (or subtraction) to spec/role-based default strategies.
# These rules are processed after the defaults.
# Example: "+threat,-potions"
AiPlayerbot.RandomBotCombatStrategies = ""
AiPlayerbot.RandomBotNonCombatStrategies = ""
# Additional altbot strategies
# Strategies added here are applied to all altbots, in addition (or subtraction) to spec/role-based default strategies. These rules are processed after the defaults.
# Strategies added here are applied to all altbots, in addition (or subtraction) to spec/role-based default strategies.
# These rules are processed after the defaults.
AiPlayerbot.CombatStrategies = ""
AiPlayerbot.NonCombatStrategies = ""

View File

@@ -122,7 +122,11 @@ void PlayerbotFactory::Init()
uint32 maxStoreSize = sSpellMgr->GetSpellInfoStoreSize();
for (uint32 id = 1; id < maxStoreSize; ++id)
{
if (id == 47181 || id == 50358 || id == 47242 || id == 52639 || id == 47147 || id == 7218) // Test Enchant
if (id == 7218 || id == 19927 || id == 44119 || id == 47147 || id == 47181 ||
id == 47242 || id == 50358 || id == 52639) // Test Enchants
continue;
if (id == 35791 || id == 39405) // Grandfathered TBC Enchants
continue;
if (id == 15463 || id == 15490) // Legendary Arcane Amalgamation

View File

@@ -90,18 +90,25 @@ void AutoMaintenanceOnLevelupAction::LearnQuestSpells(std::ostringstream* out)
//uint32 questId = i->first; //not used, line marked for removal.
Quest const* quest = i->second;
if (!quest->GetRequiredClasses() || quest->IsRepeatable() || quest->GetMinLevel() < 10)
// only process class-specific quests to learn class-related spells, cuz
// we don't want all these bunch of entries to be handled!
if (!quest->GetRequiredClasses())
continue;
if (!bot->SatisfyQuestClass(quest, false) || quest->GetMinLevel() > bot->GetLevel() ||
!bot->SatisfyQuestRace(quest, false))
// skip quests that are repeatable, too low level, or above bots' level
if (quest->IsRepeatable() || quest->GetMinLevel() < 10 || quest->GetMinLevel() > bot->GetLevel())
continue;
if (quest->GetRewSpellCast() > 0)
// skip if bot doesnt satisfy class, race, or skill requirements
if (!bot->SatisfyQuestClass(quest, false) || !bot->SatisfyQuestRace(quest, false) ||
!bot->SatisfyQuestSkill(quest, false))
continue;
if (quest->GetRewSpellCast() > 0) // RewardSpell - expected route
{
LearnSpell(quest->GetRewSpellCast(), out);
}
else if (quest->GetRewSpell() > 0)
else if (quest->GetRewSpell() > 0) // RewardDisplaySpell - fallback
{
LearnSpell(quest->GetRewSpell(), out);
}
@@ -123,35 +130,37 @@ std::string const AutoMaintenanceOnLevelupAction::FormatSpell(SpellInfo const* s
void AutoMaintenanceOnLevelupAction::LearnSpell(uint32 spellId, std::ostringstream* out)
{
SpellInfo const* proto = sSpellMgr->GetSpellInfo(spellId);
if (!proto)
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo)
return;
bool learned = false;
for (uint8 j = 0; j < 3; ++j)
SpellInfo const* triggeredInfo;
// find effect with learn spell and check if we have this spell
bool found = false;
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i)
{
if (proto->Effects[j].Effect == SPELL_EFFECT_LEARN_SPELL)
if (spellInfo->Effects[i].Effect == SPELL_EFFECT_LEARN_SPELL && spellInfo->Effects[i].TriggerSpell &&
!bot->HasSpell(spellInfo->Effects[i].TriggerSpell))
{
uint32 learnedSpell = proto->Effects[j].TriggerSpell;
triggeredInfo = sSpellMgr->GetSpellInfo(spellInfo->Effects[i].TriggerSpell);
if (!bot->HasSpell(learnedSpell))
{
bot->learnSpell(learnedSpell);
*out << FormatSpell(sSpellMgr->GetSpellInfo(learnedSpell)) << ", ";
}
// do not learn profession specialties!
if (!triggeredInfo || triggeredInfo->Effects[0].Effect == SPELL_EFFECT_TRADE_SKILL)
break;
learned = true;
found = true;
break;
}
}
if (!learned)
{
if (!bot->HasSpell(spellId))
{
bot->learnSpell(spellId);
*out << FormatSpell(proto) << ", ";
}
}
if (!found)
return;
// NOTE: When rewarding quests, core casts spells instead of learning them,
// but we sacrifice safe cast checks here in favor of performance/speed
bot->learnSpell(triggeredInfo->Id);
*out << FormatSpell(triggeredInfo) << ", ";
}
void AutoMaintenanceOnLevelupAction::AutoUpgradeEquip()

View File

@@ -11,10 +11,6 @@
bool NearestEnemyPlayersValue::AcceptUnit(Unit* unit)
{
// Apply parent's filtering first (includes level difference checks)
if (!PossibleTargetsValue::AcceptUnit(unit))
return false;
bool inCannon = botAI->IsInVehicle(false, true);
Player* enemy = dynamic_cast<Player*>(unit);
if (enemy && botAI->IsOpposing(enemy) && enemy->IsPvP() &&
@@ -23,14 +19,7 @@ bool NearestEnemyPlayersValue::AcceptUnit(Unit* unit)
((inCannon || !enemy->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE))) &&
/*!enemy->HasStealthAura() && !enemy->HasInvisibilityAura()*/ enemy->CanSeeOrDetect(bot) &&
!(enemy->HasSpiritOfRedemptionAura()))
{
// If with master, only attack if master is PvP flagged
Player* master = botAI->GetMaster();
if (master && !master->IsPvP() && !master->IsFFAPvP())
return false;
return true;
}
return false;
}

View File

@@ -16,32 +16,6 @@
#include "SpellAuraEffects.h"
#include "SpellMgr.h"
#include "Unit.h"
#include "AreaDefines.h"
#include <unordered_map>
// Level difference thresholds for attack probability
constexpr int32 EXTREME_LEVEL_DIFF = 5; // Don't attack if enemy is this much higher
constexpr int32 HIGH_LEVEL_DIFF = 4; // 25% chance at +/- this difference
constexpr int32 MID_LEVEL_DIFF = 3; // 50% chance at +/- this difference
constexpr int32 LOW_LEVEL_DIFF = 2; // 75% chance at +/- this difference
// Cache duration before reconsidering attack decision, and old cache cleanup interval
constexpr uint32 ATTACK_DECISION_CACHE_DURATION = 2 * MINUTE;
constexpr uint32 ATTACK_DECISION_CACHE_CLEANUP_INTERVAL = 10 * MINUTE;
// Custom hash function for (botGUID, targetGUID) pairs
struct PairGuidHash
{
std::size_t operator()(const std::pair<ObjectGuid, ObjectGuid>& pair) const
{
return std::hash<uint64>()(pair.first.GetRawValue()) ^
(std::hash<uint64>()(pair.second.GetRawValue()) << 1);
}
};
// Cache for probability-based attack decisions (Per-bot: non-global)
// Map: (botGUID, targetGUID) -> (should attack decision, timestamp)
static std::unordered_map<std::pair<ObjectGuid, ObjectGuid>, std::pair<bool, time_t>, PairGuidHash> attackDecisionCache;
void PossibleTargetsValue::FindUnits(std::list<Unit*>& targets)
{
@@ -50,117 +24,7 @@ void PossibleTargetsValue::FindUnits(std::list<Unit*>& targets)
Cell::VisitObjects(bot, searcher, range);
}
static void CleanupAttackDecisionCache()
{
time_t currentTime = time(nullptr);
for (auto it = attackDecisionCache.begin(); it != attackDecisionCache.end();)
{
if (currentTime - it->second.second >= ATTACK_DECISION_CACHE_DURATION)
it = attackDecisionCache.erase(it);
else
++it;
}
}
bool PossibleTargetsValue::AcceptUnit(Unit* unit)
{
// attackDecisionCache cleanup
static time_t lastCleanup = 0;
time_t currentTime = time(nullptr);
if (currentTime - lastCleanup > ATTACK_DECISION_CACHE_CLEANUP_INTERVAL)
{
CleanupAttackDecisionCache();
lastCleanup = currentTime;
}
if (!AttackersValue::IsPossibleTarget(unit, bot, range))
return false;
// Level-based PvP restrictions
if (unit->IsPlayer())
{
// Self-defense - always allow fighting back
if (bot->IsInCombat() && bot->GetVictim() == unit)
return true; // Already fighting
Unit* botAttacker = bot->getAttackerForHelper();
if (botAttacker)
{
if (botAttacker == unit)
return true; // Enemy attacking
if (botAttacker->IsPet())
{
Unit* petOwner = botAttacker->GetOwner();
if (petOwner && petOwner == unit)
return true; // Enemy's pet attacking
}
}
// Skip restrictions in BG/Arena
if (bot->InBattleground() || bot->InArena())
return true;
// Skip restrictions if in duel with this player
if (bot->duel && bot->duel->Opponent == unit)
return true;
// Capital cities - no restrictions
uint32 zoneId = bot->GetZoneId();
bool inCapitalCity = (zoneId == AREA_STORMWIND_CITY ||
zoneId == AREA_IRONFORGE ||
zoneId == AREA_DARNASSUS ||
zoneId == AREA_THE_EXODAR ||
zoneId == AREA_ORGRIMMAR ||
zoneId == AREA_THUNDER_BLUFF ||
zoneId == AREA_UNDERCITY ||
zoneId == AREA_SILVERMOON_CITY);
if (inCapitalCity)
return true;
// Level difference check
int32 levelDifference = unit->GetLevel() - bot->GetLevel();
int32 absLevelDifference = std::abs(levelDifference);
// Extreme difference - do not attack
if (levelDifference >= EXTREME_LEVEL_DIFF)
return false;
// Calculate attack chance based on level difference
uint32 attackChance = 100; // Default 100%: Bot and target's levels are very close
// There's a chance a bot might gank on an extremly low target
if ((absLevelDifference < EXTREME_LEVEL_DIFF && absLevelDifference >= HIGH_LEVEL_DIFF) ||
levelDifference <= -EXTREME_LEVEL_DIFF)
attackChance = 25;
else if (absLevelDifference < HIGH_LEVEL_DIFF && absLevelDifference >= MID_LEVEL_DIFF)
attackChance = 50;
else if (absLevelDifference < MID_LEVEL_DIFF && absLevelDifference >= LOW_LEVEL_DIFF)
attackChance = 75;
// If probability check needed, use cache
if (attackChance < 100)
{
std::pair<ObjectGuid, ObjectGuid> cacheKey = std::make_pair(bot->GetGUID(), unit->GetGUID());
auto it = attackDecisionCache.find(cacheKey);
if (it != attackDecisionCache.end())
{
if (currentTime - it->second.second < ATTACK_DECISION_CACHE_DURATION)
return it->second.first;
}
bool shouldAttack = (urand(1, 100) <= attackChance);
attackDecisionCache[cacheKey] = std::make_pair(shouldAttack, currentTime);
return shouldAttack;
}
}
return true;
}
bool PossibleTargetsValue::AcceptUnit(Unit* unit) { return AttackersValue::IsPossibleTarget(unit, bot, range); }
void PossibleTriggersValue::FindUnits(std::list<Unit*>& targets)
{
@@ -172,8 +36,9 @@ void PossibleTriggersValue::FindUnits(std::list<Unit*>& targets)
bool PossibleTriggersValue::AcceptUnit(Unit* unit)
{
if (!unit->HasUnitFlag(UNIT_FLAG_NOT_SELECTABLE))
{
return false;
}
Unit::AuraEffectList const& aurasPeriodicTriggerSpell =
unit->GetAuraEffectsByType(SPELL_AURA_PERIODIC_TRIGGER_SPELL);
Unit::AuraEffectList const& aurasPeriodicTriggerWithValueSpell =
@@ -193,7 +58,9 @@ bool PossibleTriggersValue::AcceptUnit(Unit* unit)
for (int j = 0; j < MAX_SPELL_EFFECTS; j++)
{
if (triggerSpellInfo->Effects[j].Effect == SPELL_EFFECT_SCHOOL_DAMAGE)
{
return true;
}
}
}
}