558 lines
25 KiB
C++
558 lines
25 KiB
C++
#include "ABUnitScript.h"
|
|
|
|
#include "ABConfig.h"
|
|
#include "ABCreatureInfo.h"
|
|
#include "ABMapInfo.h"
|
|
#include "ABUtils.h"
|
|
|
|
void AutoBalance_UnitScript::ModifyPeriodicDamageAurasTick(Unit* target, Unit* source, uint32& amount, SpellInfo const* spellInfo)
|
|
{
|
|
// if the spell is negative (damage), we need to flip the sign
|
|
// if the spell is positive (healing or other) we keep it the same
|
|
int32 adjustedAmount = !spellInfo->IsPositive() ? amount * -1 : amount;
|
|
|
|
// only debug if the source or target is a player
|
|
bool _debug_damage_and_healing = ((source && (source->GetTypeId() == TYPEID_PLAYER || source->IsControlledByPlayer())) || (target && target->GetTypeId() == TYPEID_PLAYER));
|
|
_debug_damage_and_healing = (source && source->GetMap()->GetInstanceId());
|
|
|
|
if (_debug_damage_and_healing)
|
|
_Debug_Output("ModifyPeriodicDamageAurasTick", target, source, adjustedAmount, AUTOBALANCE_DAMAGE_HEALING_DEBUG_PHASE_BEFORE, spellInfo->SpellName[0], spellInfo->Id);
|
|
|
|
// set amount to the absolute value of the function call
|
|
// the provided amount doesn't indicate whether it's a positive or negative value
|
|
adjustedAmount = _Modify_Damage_Healing(target, source, adjustedAmount, spellInfo);
|
|
amount = abs(adjustedAmount);
|
|
|
|
if (_debug_damage_and_healing)
|
|
_Debug_Output("ModifyPeriodicDamageAurasTick", target, source, adjustedAmount, AUTOBALANCE_DAMAGE_HEALING_DEBUG_PHASE_AFTER, spellInfo->SpellName[0], spellInfo->Id);
|
|
}
|
|
|
|
void AutoBalance_UnitScript::ModifySpellDamageTaken(Unit* target, Unit* source, int32& amount, SpellInfo const* spellInfo)
|
|
{
|
|
// if the spell is negative (damage), we need to flip the sign to negative
|
|
// if the spell is positive (healing or other) we keep it the same (positive)
|
|
int32 adjustedAmount = !spellInfo->IsPositive() ? amount * -1 : amount;
|
|
|
|
// only debug if the source or target is a player
|
|
bool _debug_damage_and_healing = ((source && (source->GetTypeId() == TYPEID_PLAYER || source->IsControlledByPlayer())) || (target && target->GetTypeId() == TYPEID_PLAYER));
|
|
_debug_damage_and_healing = (source && source->GetMap()->GetInstanceId());
|
|
|
|
if (_debug_damage_and_healing)
|
|
_Debug_Output("ModifySpellDamageTaken", target, source, adjustedAmount, AUTOBALANCE_DAMAGE_HEALING_DEBUG_PHASE_BEFORE, spellInfo->SpellName[0], spellInfo->Id);
|
|
|
|
// set amount to the absolute value of the function call
|
|
// the provided amount doesn't indicate whether it's a positive or negative value
|
|
adjustedAmount = _Modify_Damage_Healing(target, source, adjustedAmount, spellInfo);
|
|
amount = abs(adjustedAmount);
|
|
|
|
if (_debug_damage_and_healing)
|
|
_Debug_Output("ModifySpellDamageTaken", target, source, adjustedAmount, AUTOBALANCE_DAMAGE_HEALING_DEBUG_PHASE_AFTER, spellInfo->SpellName[0], spellInfo->Id);
|
|
}
|
|
|
|
void AutoBalance_UnitScript::ModifyMeleeDamage(Unit* target, Unit* source, uint32& amount)
|
|
{
|
|
// melee damage is always negative, so we need to flip the sign to negative
|
|
int32 adjustedAmount = amount * -1;
|
|
|
|
// only debug if the source or target is a player
|
|
bool _debug_damage_and_healing = ((source && (source->GetTypeId() == TYPEID_PLAYER || source->IsControlledByPlayer())) || (target && target->GetTypeId() == TYPEID_PLAYER));
|
|
_debug_damage_and_healing = (source && source->GetMap()->GetInstanceId());
|
|
|
|
if (_debug_damage_and_healing)
|
|
_Debug_Output("ModifyMeleeDamage", target, source, adjustedAmount, AUTOBALANCE_DAMAGE_HEALING_DEBUG_PHASE_BEFORE, "Melee");
|
|
|
|
// set amount to the absolute value of the function call
|
|
adjustedAmount = _Modify_Damage_Healing(target, source, adjustedAmount);
|
|
amount = abs(adjustedAmount);
|
|
|
|
if (_debug_damage_and_healing)
|
|
_Debug_Output("ModifyMeleeDamage", target, source, adjustedAmount, AUTOBALANCE_DAMAGE_HEALING_DEBUG_PHASE_AFTER, "Melee");
|
|
}
|
|
|
|
void AutoBalance_UnitScript::ModifyHealReceived(Unit* target, Unit* source, uint32& amount, SpellInfo const* spellInfo)
|
|
{
|
|
// healing is always positive, no need for any sign flip
|
|
|
|
// only debug if the source or target is a player
|
|
bool _debug_damage_and_healing = ((source && (source->GetTypeId() == TYPEID_PLAYER || source->IsControlledByPlayer())) || (target && target->GetTypeId() == TYPEID_PLAYER));
|
|
_debug_damage_and_healing = (source && source->GetMap()->GetInstanceId());
|
|
|
|
if (_debug_damage_and_healing)
|
|
_Debug_Output("ModifyHealReceived", target, source, amount, AUTOBALANCE_DAMAGE_HEALING_DEBUG_PHASE_BEFORE, spellInfo->SpellName[0], spellInfo->Id);
|
|
|
|
amount = _Modify_Damage_Healing(target, source, amount, spellInfo);
|
|
|
|
if (_debug_damage_and_healing)
|
|
_Debug_Output("ModifyHealReceived", target, source, amount, AUTOBALANCE_DAMAGE_HEALING_DEBUG_PHASE_AFTER, spellInfo->SpellName[0], spellInfo->Id);
|
|
}
|
|
|
|
void AutoBalance_UnitScript::OnAuraApply(Unit* unit, Aura* aura)
|
|
{
|
|
// only debug if the source or target is a player
|
|
bool _debug_damage_and_healing = (unit && unit->GetTypeId() == TYPEID_PLAYER);
|
|
_debug_damage_and_healing = (unit && unit->GetMap()->GetInstanceId());
|
|
|
|
// Only if this aura has a duration
|
|
if (aura && (aura->GetDuration() > 0 || aura->GetMaxDuration() > 0))
|
|
{
|
|
uint32 auraDuration = _Modifier_CCDuration(unit, aura->GetCaster(), aura);
|
|
|
|
// only update if we decided to change it
|
|
if (auraDuration != (float)aura->GetDuration())
|
|
{
|
|
if (_debug_damage_and_healing)
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::OnAuraApply(): Spell '{}' had it's duration adjusted ({}->{}).",
|
|
aura->GetSpellInfo()->SpellName[0],
|
|
aura->GetMaxDuration() / 1000,
|
|
auraDuration / 1000
|
|
);
|
|
|
|
aura->SetMaxDuration(auraDuration);
|
|
aura->SetDuration(auraDuration);
|
|
}
|
|
}
|
|
}
|
|
|
|
void AutoBalance_UnitScript::_Debug_Output(std::string function_name, Unit* target, Unit* source, int32 amount, Damage_Healing_Debug_Phase phase, std::string spell_name, uint32 spell_id)
|
|
{
|
|
if (phase == AUTOBALANCE_DAMAGE_HEALING_DEBUG_PHASE_BEFORE)
|
|
{
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance:: ------------------------------------------------");
|
|
}
|
|
|
|
if (target && source && amount)
|
|
{
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::{}: {}: {}{} {} {}{} with {}{} for ({})",
|
|
function_name,
|
|
phase ? "AFTER" : "BEFORE",
|
|
source->GetName(),
|
|
source->GetEntry() ? " (" + std::to_string(source->GetEntry()) + ")" : "",
|
|
amount > 0 ? "heals" : "damages",
|
|
target->GetName(),
|
|
target->GetEntry() ? " (" + std::to_string(target->GetEntry()) + ")" : "",
|
|
spell_name,
|
|
spell_id ? " (" + std::to_string(spell_id) + ")" : "",
|
|
amount
|
|
);
|
|
}
|
|
else if (target && source)
|
|
{
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::{}: {}: {}{} damages {}{} with {}{} for (0)",
|
|
function_name,
|
|
phase ? "AFTER" : "BEFORE",
|
|
source->GetName(),
|
|
source->GetEntry() ? " (" + std::to_string(source->GetEntry()) + ")" : "",
|
|
target->GetName(),
|
|
target->GetEntry() ? " (" + std::to_string(target->GetEntry()) + ")" : "",
|
|
spell_name,
|
|
spell_id ? " (" + std::to_string(spell_id) + ")" : ""
|
|
);
|
|
}
|
|
else if (target && amount)
|
|
{
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::{}: {}: ?? {} {}{} with {}{} for ({})",
|
|
function_name,
|
|
phase ? "AFTER" : "BEFORE",
|
|
amount > 0 ? "heals" : "damages",
|
|
target->GetName(),
|
|
target->GetEntry() ? " (" + std::to_string(target->GetEntry()) + ")" : "",
|
|
spell_name,
|
|
spell_id ? " (" + std::to_string(spell_id) + ")" : "",
|
|
amount
|
|
);
|
|
}
|
|
else if (target)
|
|
{
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::{}: {}: ?? affects {}{} with {}{}",
|
|
function_name,
|
|
phase ? "AFTER" : "BEFORE",
|
|
target->GetName(),
|
|
target->GetEntry() ? " (" + std::to_string(target->GetEntry()) + ")" : "",
|
|
spell_name,
|
|
spell_id ? " (" + std::to_string(spell_id) + ")" : ""
|
|
);
|
|
}
|
|
else
|
|
{
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::{}: {}: W? T? F? with {}{}",
|
|
function_name,
|
|
phase ? "AFTER" : "BEFORE",
|
|
spell_name,
|
|
spell_id ? " (" + std::to_string(spell_id) + ")" : ""
|
|
);
|
|
}
|
|
}
|
|
|
|
int32 AutoBalance_UnitScript::_Modify_Damage_Healing(Unit* target, Unit* source, int32 amount, SpellInfo const* spellInfo)
|
|
{
|
|
//
|
|
// Pre-flight Checks
|
|
//
|
|
|
|
// only debug if the source or target is a player
|
|
bool _debug_damage_and_healing = ((source && (source->GetTypeId() == TYPEID_PLAYER || source->IsControlledByPlayer())) || (target && target->GetTypeId() == TYPEID_PLAYER));
|
|
_debug_damage_and_healing = (source && source->GetMap()->GetInstanceId());
|
|
|
|
// check that we're enabled globally, else return the original value
|
|
if (!EnableGlobal)
|
|
{
|
|
if (_debug_damage_and_healing)
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: EnableGlobal is false, returning original value of ({}).", amount);
|
|
|
|
return amount;
|
|
}
|
|
|
|
// if the source is gone (logged off? despawned?), use the same target and source.
|
|
// hacky, but better than crashing or having the damage go to 1.0x
|
|
if (!source)
|
|
{
|
|
if (_debug_damage_and_healing)
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Source is null, using target as source.");
|
|
|
|
source = target;
|
|
}
|
|
|
|
// make sure the source and target are in an instance, else return the original damage
|
|
if (!(source->GetMap()->IsDungeon() && target->GetMap()->IsDungeon()))
|
|
{
|
|
//if (_debug_damage_and_healing)
|
|
// LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Not in an instance, returning original value of ({}).", amount);
|
|
|
|
return amount;
|
|
}
|
|
|
|
// make sure that the source is in the world, else return the original value
|
|
if (!source->IsInWorld())
|
|
{
|
|
if (_debug_damage_and_healing)
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Source does not exist in the world, returning original value of ({}).", amount);
|
|
|
|
return amount;
|
|
}
|
|
|
|
// if the spell ID is in our "never modify" list, return the original value
|
|
if
|
|
(
|
|
spellInfo &&
|
|
spellInfo->Id &&
|
|
std::find
|
|
(
|
|
spellIdsToNeverModify.begin(),
|
|
spellIdsToNeverModify.end(),
|
|
spellInfo->Id
|
|
) != spellIdsToNeverModify.end()
|
|
)
|
|
{
|
|
if (_debug_damage_and_healing)
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Spell {}({}) is in the never modify list, returning original value of ({}).",
|
|
spellInfo->SpellName[0],
|
|
spellInfo->Id,
|
|
amount
|
|
);
|
|
|
|
return amount;
|
|
}
|
|
|
|
// get the maps' info
|
|
AutoBalanceMapInfo* sourceMapABInfo = GetMapInfo(source->GetMap());
|
|
AutoBalanceMapInfo* targetMapABInfo = GetMapInfo(target->GetMap());
|
|
|
|
// if either the target or the source's maps are not enabled, return the original damage
|
|
if (!sourceMapABInfo->enabled || !targetMapABInfo->enabled)
|
|
{
|
|
if (_debug_damage_and_healing)
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Source or Target's map is not enabled, returning original value of ({}).", amount);
|
|
|
|
return amount;
|
|
}
|
|
|
|
//
|
|
// Source and Target Checking
|
|
//
|
|
|
|
// if the source is a player and they are healing themselves, return the original value
|
|
if (source->GetTypeId() == TYPEID_PLAYER && source->GetGUID() == target->GetGUID() && amount >= 0)
|
|
{
|
|
if (_debug_damage_and_healing)
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Source is a player that is self-healing, returning original value of ({}).", amount);
|
|
|
|
return amount;
|
|
}
|
|
// if the source is a player and they are damaging themselves, log to debug but continue
|
|
else if (source->GetTypeId() == TYPEID_PLAYER && source->GetGUID() == target->GetGUID() && amount < 0)
|
|
{
|
|
// if the spell used is in our list of spells to ignore, return the original value
|
|
if
|
|
(
|
|
spellInfo &&
|
|
spellInfo->Id &&
|
|
std::find
|
|
(
|
|
spellIdsThatSpendPlayerHealth.begin(),
|
|
spellIdsThatSpendPlayerHealth.end(),
|
|
spellInfo->Id
|
|
) != spellIdsThatSpendPlayerHealth.end()
|
|
)
|
|
{
|
|
if (_debug_damage_and_healing)
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Source is a player that is self-damaging with a spell that is ignored, returning original value of ({}).", amount);
|
|
|
|
return amount;
|
|
}
|
|
|
|
if (_debug_damage_and_healing)
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Source is a player that is self-damaging, continuing.");
|
|
}
|
|
// if the source is a player and they are damaging unit that is friendly, log to debug but continue
|
|
else if (source->GetTypeId() == TYPEID_PLAYER && target->IsFriendlyTo(source) && amount < 0)
|
|
{
|
|
if (_debug_damage_and_healing)
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Source is a player that is damaging a friendly unit, continuing.");
|
|
}
|
|
// if the source is a player under any other condition, return the original value
|
|
else if (source->GetTypeId() == TYPEID_PLAYER)
|
|
{
|
|
if (_debug_damage_and_healing)
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Source is an enemy player, returning original value of ({}).", amount);
|
|
|
|
return amount;
|
|
}
|
|
// if the creature is attacking itself with an aura with effect type SPELL_AURA_SHARE_DAMAGE_PCT, return the orginal damage
|
|
else if
|
|
(
|
|
source->GetTypeId() == TYPEID_UNIT &&
|
|
source->GetTypeId() != TYPEID_PLAYER &&
|
|
source->GetGUID() == target->GetGUID() &&
|
|
_isAuraWithEffectType(spellInfo, SPELL_AURA_SHARE_DAMAGE_PCT)
|
|
)
|
|
{
|
|
if (_debug_damage_and_healing)
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Source is a creature that is self-damaging with an aura that shares damage, returning original value of ({}).", amount);
|
|
|
|
return amount;
|
|
}
|
|
|
|
// if the source is under the control of the player, return the original damage
|
|
// noteably, this should NOT include mind control targets
|
|
if ((source->IsHunterPet() || source->IsPet() || source->IsSummon()) && source->IsControlledByPlayer())
|
|
{
|
|
if (_debug_damage_and_healing)
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Source is a player-controlled pet or summon, returning original value of ({}).", amount);
|
|
|
|
return amount;
|
|
}
|
|
|
|
//
|
|
// Multiplier calculation
|
|
//
|
|
float damageMultiplier = 1.0f;
|
|
|
|
// if the source is a player AND the target is that same player AND the value is damage (negative), use the map's multiplier
|
|
if (source->GetTypeId() == TYPEID_PLAYER && source->GetGUID() == target->GetGUID() && amount < 0)
|
|
{
|
|
// if this aura damages based on a percent of the player's max health, use the un-level-scaled multiplier
|
|
if (_isAuraWithEffectType(spellInfo, SPELL_AURA_PERIODIC_DAMAGE_PERCENT))
|
|
{
|
|
damageMultiplier = sourceMapABInfo->worldDamageHealingMultiplier;
|
|
if (_debug_damage_and_healing)
|
|
{
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Spell damage based on percent of max health. Ignore level scaling.");
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC",
|
|
"AutoBalance_UnitScript::_Modify_Damage_Healing: Source is a player and the target is that same player, using the map's (level-scaling ignored) multiplier: ({})",
|
|
damageMultiplier
|
|
);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
damageMultiplier = sourceMapABInfo->scaledWorldDamageHealingMultiplier;
|
|
if (_debug_damage_and_healing)
|
|
{
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC",
|
|
"AutoBalance_UnitScript::_Modify_Damage_Healing: Source is a player and the target is that same player, using the map's multiplier: ({})",
|
|
damageMultiplier
|
|
);
|
|
}
|
|
}
|
|
}
|
|
// if the target is a player AND the value is healing (positive), use the map's damage multiplier
|
|
// (player to player healing was already eliminated in the Source and Target Checking section)
|
|
else if (target->GetTypeId() == TYPEID_PLAYER && amount >= 0)
|
|
{
|
|
damageMultiplier = targetMapABInfo->scaledWorldDamageHealingMultiplier;
|
|
if (_debug_damage_and_healing)
|
|
{
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC",
|
|
"AutoBalance_UnitScript::_Modify_Damage_Healing: A non-player is healing a player, using the map's multiplier: ({})",
|
|
damageMultiplier
|
|
);
|
|
}
|
|
}
|
|
// if the target is a player AND the source is not a creature, use the map's multiplier
|
|
else if (target->GetTypeId() == TYPEID_PLAYER && source->GetTypeId() != TYPEID_UNIT && amount < 0)
|
|
{
|
|
// if this aura damages based on a percent of the player's max health, use the un-level-scaled multiplier
|
|
if (_isAuraWithEffectType(spellInfo, SPELL_AURA_PERIODIC_DAMAGE_PERCENT))
|
|
{
|
|
damageMultiplier = targetMapABInfo->worldDamageHealingMultiplier;
|
|
if (_debug_damage_and_healing)
|
|
{
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Spell damage based on percent of max health. Ignore level scaling.");
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC",
|
|
"AutoBalance_UnitScript::_Modify_Damage_Healing: Target is a player and the source is not a creature, using the map's (level-scaling-ignored) multiplier: ({})",
|
|
damageMultiplier
|
|
);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
damageMultiplier = targetMapABInfo->scaledWorldDamageHealingMultiplier;
|
|
if (_debug_damage_and_healing)
|
|
{
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC",
|
|
"AutoBalance_UnitScript::_Modify_Damage_Healing: Target is a player and the source is not a creature, using the map's multiplier: ({})",
|
|
damageMultiplier
|
|
);
|
|
}
|
|
}
|
|
}
|
|
// otherwise, use the source creature's damage multiplier
|
|
else
|
|
{
|
|
// if this aura damages based on a percent of the player's max health, use the un-level-scaled multiplier
|
|
if (_isAuraWithEffectType(spellInfo, SPELL_AURA_PERIODIC_DAMAGE_PERCENT))
|
|
{
|
|
damageMultiplier = source->CustomData.GetDefault<AutoBalanceCreatureInfo>("AutoBalanceCreatureInfo")->DamageMultiplier;
|
|
if (_debug_damage_and_healing)
|
|
{
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Spell damage based on percent of max health. Ignore level scaling.");
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC",
|
|
"AutoBalance_UnitScript::_Modify_Damage_Healing: Using the source creature's (level-scaling ignored) damage multiplier: ({})",
|
|
damageMultiplier
|
|
);
|
|
}
|
|
}
|
|
// non percent-based, used the normal multiplier
|
|
else
|
|
{
|
|
damageMultiplier = source->CustomData.GetDefault<AutoBalanceCreatureInfo>("AutoBalanceCreatureInfo")->ScaledDamageMultiplier;
|
|
if (_debug_damage_and_healing)
|
|
{
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC",
|
|
"AutoBalance_UnitScript::_Modify_Damage_Healing: Using the source creature's damage multiplier: ({})",
|
|
damageMultiplier
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
// we are good to go, return the original damage times the multiplier
|
|
if (_debug_damage_and_healing)
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_Modify_Damage_Healing: Returning modified {}: ({}) * ({}) = ({})",
|
|
amount <= 0 ? "damage" : "healing",
|
|
amount,
|
|
damageMultiplier,
|
|
amount * damageMultiplier
|
|
);
|
|
|
|
return amount * damageMultiplier;
|
|
}
|
|
|
|
uint32 AutoBalance_UnitScript::_Modifier_CCDuration(Unit* target, Unit* caster, Aura* aura)
|
|
{
|
|
// store the original duration of the aura
|
|
float originalDuration = (float)aura->GetDuration();
|
|
|
|
// check that we're enabled globally, else return the original duration
|
|
if (!EnableGlobal)
|
|
return originalDuration;
|
|
|
|
// ensure that both the target and the caster are defined
|
|
if (!target || !caster)
|
|
return originalDuration;
|
|
|
|
// if the aura wasn't cast just now, don't change it
|
|
if (aura->GetDuration() != aura->GetMaxDuration())
|
|
return originalDuration;
|
|
|
|
// if the target isn't a player or the caster is a player, return the original duration
|
|
if (!target->IsPlayer() || caster->IsPlayer())
|
|
return originalDuration;
|
|
|
|
// make sure we're in an instance, else return the original duration
|
|
if (!(target->GetMap()->IsDungeon() && caster->GetMap()->IsDungeon()))
|
|
return originalDuration;
|
|
|
|
// get the current creature's CC duration multiplier
|
|
float ccDurationMultiplier = caster->CustomData.GetDefault<AutoBalanceCreatureInfo>("AutoBalanceCreatureInfo")->CCDurationMultiplier;
|
|
|
|
// if it's the default of 1.0, return the original damage
|
|
if (ccDurationMultiplier == 1)
|
|
return originalDuration;
|
|
|
|
// if the aura was cast by a pet or summon, return the original duration
|
|
if ((caster->IsHunterPet() || caster->IsPet() || caster->IsSummon()) && caster->IsControlledByPlayer())
|
|
return originalDuration;
|
|
|
|
// only if this aura is a CC
|
|
if (
|
|
aura->HasEffectType(SPELL_AURA_MOD_CHARM) ||
|
|
aura->HasEffectType(SPELL_AURA_MOD_CONFUSE) ||
|
|
aura->HasEffectType(SPELL_AURA_MOD_DISARM) ||
|
|
aura->HasEffectType(SPELL_AURA_MOD_FEAR) ||
|
|
aura->HasEffectType(SPELL_AURA_MOD_PACIFY) ||
|
|
aura->HasEffectType(SPELL_AURA_MOD_POSSESS) ||
|
|
aura->HasEffectType(SPELL_AURA_MOD_SILENCE) ||
|
|
aura->HasEffectType(SPELL_AURA_MOD_STUN) ||
|
|
aura->HasEffectType(SPELL_AURA_MOD_SPEED_SLOW_ALL)
|
|
)
|
|
{
|
|
return originalDuration * ccDurationMultiplier;
|
|
}
|
|
else
|
|
return originalDuration;
|
|
}
|
|
|
|
bool AutoBalance_UnitScript::_isAuraWithEffectType(SpellInfo const* spellInfo, AuraType auraType, bool log)
|
|
{
|
|
// if the spell is not defined, return false
|
|
if (!spellInfo)
|
|
{
|
|
if (log)
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_isAuraWithEffectType: SpellInfo is null, returning false.");
|
|
return false;
|
|
}
|
|
|
|
// if the spell doesn't have any effects, return false
|
|
if (!spellInfo->GetEffects().size())
|
|
{
|
|
if (log)
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_isAuraWithEffectType: SpellInfo has no effects, returning false.");
|
|
return false;
|
|
}
|
|
|
|
// iterate through the spell effects
|
|
for (SpellEffectInfo effect : spellInfo->GetEffects())
|
|
{
|
|
// if the effect is not an aura, continue to next effect
|
|
if (!effect.IsAura())
|
|
{
|
|
if (log)
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_isAuraWithEffectType: SpellInfo has an effect that is not an aura, continuing to next effect.");
|
|
continue;
|
|
}
|
|
|
|
if (effect.ApplyAuraName == auraType)
|
|
{
|
|
// if the effect is an aura of the target type, return true
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_isAuraWithEffectType: SpellInfo has an aura of the target type, returning true.");
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// if no aura effect of type auraType was found, return false
|
|
if (log)
|
|
LOG_DEBUG("module.AutoBalance_DamageHealingCC", "AutoBalance_UnitScript::_isAuraWithEffectType: SpellInfo has no aura of the target type, returning false.");
|
|
return false;
|
|
}
|