mirror of
https://github.com/araxiaonline/mod-mythic-plus.git
synced 2026-06-13 03:02:24 -04:00
Scaling updates for non creatures and fixes for elemental damage melee
This commit is contained in:
@@ -121,7 +121,7 @@ MythicPlus.Ascendant.ItemOffset = 22000000
|
|||||||
# - The diminishing returns are based on the difficulty of the dungeon and the amount of damage that has been done to the target.
|
# - The diminishing returns are based on the difficulty of the dungeon and the amount of damage that has been done to the target.
|
||||||
##########################################################
|
##########################################################
|
||||||
|
|
||||||
MythicPlus.DiminishingExponent = 0.98
|
MythicPlus.DiminishingExponent = 0.96
|
||||||
MythicPlus.DiminishingThreshold.Mythic = 10000
|
MythicPlus.DiminishingThreshold.Mythic = 10000
|
||||||
MythicPlus.DiminishingThreshold.Legendary = 20000
|
MythicPlus.DiminishingThreshold.Legendary = 20000
|
||||||
MythicPlus.DiminishingThreshold.Ascendant = 40000
|
MythicPlus.DiminishingThreshold.Ascendant = 40000
|
||||||
@@ -129,5 +129,6 @@ MythicPlus.DiminishingThreshold.Ascendant = 40000
|
|||||||
##############
|
##############
|
||||||
# Scaling Adjusters
|
# Scaling Adjusters
|
||||||
#############
|
#############
|
||||||
MythicPlus.MeleeAttackPowerDampener = 800
|
MythicPlus.ElementalMeleeReducer = 0.50
|
||||||
MythicPlus.MeleeAttackPowerStart = 3000
|
MythicPlus.NormalEnemyReducer = 0.50
|
||||||
|
MythicPlus.NonCreatureSpellReducer = 0.50
|
||||||
|
|||||||
@@ -243,7 +243,10 @@ void MythicPlus::ScaleAll(Player* player, MpInstanceData* instanceData)
|
|||||||
{
|
{
|
||||||
std::vector<MpCreatureData*> creatures = sMpDataStore->GetInstanceCreatures(player->GetMapId(), player->GetInstanceId());
|
std::vector<MpCreatureData*> creatures = sMpDataStore->GetInstanceCreatures(player->GetMapId(), player->GetInstanceId());
|
||||||
for (MpCreatureData* creatureData : creatures) {
|
for (MpCreatureData* creatureData : creatures) {
|
||||||
ScaleCreature(creatureData->creature->GetLevel(), creatureData->creature, &instanceData->creature, instanceData->difficulty);
|
// Only scale living creatures
|
||||||
|
if (creatureData->creature && creatureData->creature->IsAlive()) {
|
||||||
|
ScaleCreature(creatureData->creature->GetLevel(), creatureData->creature, &instanceData->creature, instanceData->difficulty);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,8 +324,8 @@ void MythicPlus::ScaleCreature(uint8 level, Creature* creature, MpMultipliers* m
|
|||||||
// Additionally need to add in a decrease in attack power for normal non elite enemies
|
// Additionally need to add in a decrease in attack power for normal non elite enemies
|
||||||
if (creature->GetCreatureTemplate()->rank == CREATURE_ELITE_NORMAL) {
|
if (creature->GetCreatureTemplate()->rank == CREATURE_ELITE_NORMAL) {
|
||||||
// Reduced scaling for elite/boss spells to prevent them from hitting too hard
|
// Reduced scaling for elite/boss spells to prevent them from hitting too hard
|
||||||
ap *= 0.5f;
|
ap *= normalEnemyReducer;
|
||||||
rangeAp *= 0.5f;
|
rangeAp *= normalEnemyReducer;
|
||||||
}
|
}
|
||||||
|
|
||||||
MpCreatureData* creatureData = sMpDataStore->GetCreatureData(creature->GetGUID());
|
MpCreatureData* creatureData = sMpDataStore->GetCreatureData(creature->GetGUID());
|
||||||
@@ -454,13 +457,13 @@ int32 MythicPlus::ScaleDamageSpell(SpellInfo const * spellInfo, uint32 damage, M
|
|||||||
int32 ownerOriginalLevel = ownerCreatureData->originalLevel;
|
int32 ownerOriginalLevel = ownerCreatureData->originalLevel;
|
||||||
|
|
||||||
if (ownerCreature->GetCreatureTemplate()->rank == CREATURE_ELITE_NORMAL) {
|
if (ownerCreature->GetCreatureTemplate()->rank == CREATURE_ELITE_NORMAL) {
|
||||||
totalModifier = totalModifier * 0.75f;
|
totalModifier = totalModifier * normalEnemyReducer;
|
||||||
}
|
}
|
||||||
newDamage = CalculateSpellDamage(damage, ownerOriginalLevel, ownerCreature->GetLevel());
|
newDamage = CalculateSpellDamage(damage, ownerOriginalLevel, ownerCreature->GetLevel());
|
||||||
} else {
|
} else {
|
||||||
// Fallback if no creature data found - use current level
|
// Fallback if no creature data found - use current level
|
||||||
if(ownerCreature->GetCreatureTemplate()->rank == CREATURE_ELITE_NORMAL) {
|
if(ownerCreature->GetCreatureTemplate()->rank == CREATURE_ELITE_NORMAL) {
|
||||||
totalModifier = totalModifier * 0.75f;
|
totalModifier = totalModifier * normalEnemyReducer;
|
||||||
}
|
}
|
||||||
newDamage = CalculateSpellDamage(damage, ownerCreature->GetLevel(), ownerCreature->GetLevel());
|
newDamage = CalculateSpellDamage(damage, ownerCreature->GetLevel(), ownerCreature->GetLevel());
|
||||||
MpLogger::debug("No creature data found for owner {}, using current level for scaling", ownerCreature->GetGUID().ToString());
|
MpLogger::debug("No creature data found for owner {}, using current level for scaling", ownerCreature->GetGUID().ToString());
|
||||||
@@ -564,7 +567,7 @@ int32 MythicPlus::ScaleHealSpell(SpellInfo const * spellInfo, uint32 heal, MpCre
|
|||||||
MpCreatureData* ownerCreatureData = sMpDataStore->GetCreatureData(ownerCreature->GetGUID());
|
MpCreatureData* ownerCreatureData = sMpDataStore->GetCreatureData(ownerCreature->GetGUID());
|
||||||
if (ownerCreatureData) {
|
if (ownerCreatureData) {
|
||||||
if (ownerCreature->GetCreatureTemplate()->rank == CREATURE_ELITE_NORMAL) {
|
if (ownerCreature->GetCreatureTemplate()->rank == CREATURE_ELITE_NORMAL) {
|
||||||
totalModifier = totalModifier * 0.7f; // Less reduction for heals than damage
|
totalModifier = totalModifier * normalEnemyReducer; // Less reduction for heals than damage
|
||||||
}
|
}
|
||||||
// Scale heal based on target's health, not caster's health
|
// Scale heal based on target's health, not caster's health
|
||||||
if (target) {
|
if (target) {
|
||||||
@@ -579,7 +582,7 @@ int32 MythicPlus::ScaleHealSpell(SpellInfo const * spellInfo, uint32 heal, MpCre
|
|||||||
} else {
|
} else {
|
||||||
// Fallback if no creature data found - use current level
|
// Fallback if no creature data found - use current level
|
||||||
if(ownerCreature->GetCreatureTemplate()->rank == CREATURE_ELITE_NORMAL) {
|
if(ownerCreature->GetCreatureTemplate()->rank == CREATURE_ELITE_NORMAL) {
|
||||||
totalModifier = totalModifier * 0.7f; // Less reduction for heals than damage
|
totalModifier = totalModifier * normalEnemyReducer; // Less reduction for heals than damage
|
||||||
}
|
}
|
||||||
// Scale heal based on target's health, not caster's health
|
// Scale heal based on target's health, not caster's health
|
||||||
if (target) {
|
if (target) {
|
||||||
@@ -854,7 +857,7 @@ uint32 CalculateNewHealth(Creature* creature, CreatureTemplate const* cInfo, uin
|
|||||||
|
|
||||||
// if it is a heroic instance give the enemy an additional 20% boost
|
// if it is a heroic instance give the enemy an additional 20% boost
|
||||||
InstanceMap* instanceMap = creature->GetMap()->ToInstanceMap();
|
InstanceMap* instanceMap = creature->GetMap()->ToInstanceMap();
|
||||||
if (instanceMap && (instanceMap->IsHeroic() || instanceMap->Is25ManRaid())) {
|
if (instanceMap && instanceMap->IsRaidOrHeroicDungeon()) {
|
||||||
basehp *= 1.25f;
|
basehp *= 1.25f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,6 +77,12 @@ public:
|
|||||||
float diminishingExponent;
|
float diminishingExponent;
|
||||||
std::unordered_map<MpDifficulty, uint32> diminishingThresholds;
|
std::unordered_map<MpDifficulty, uint32> diminishingThresholds;
|
||||||
|
|
||||||
|
// Specialized variables used in calculations
|
||||||
|
float elementalMeleeReducer;
|
||||||
|
float normalEnemyReducer;
|
||||||
|
float nonCreatureSpellReducer;
|
||||||
|
|
||||||
|
|
||||||
enum MP_UNIT_EVENT_TYPE
|
enum MP_UNIT_EVENT_TYPE
|
||||||
{
|
{
|
||||||
UNIT_EVENT_MELEE,
|
UNIT_EVENT_MELEE,
|
||||||
|
|||||||
@@ -14,6 +14,25 @@ public:
|
|||||||
// {
|
// {
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
void OnCreatureRespawn(Creature* creature) override
|
||||||
|
{
|
||||||
|
Map* map = creature->GetMap();
|
||||||
|
if (!sMythicPlus->IsMapEligible(map)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sMythicPlus->IsCreatureEligible(creature)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have instance data, scale the creature, otherwise add it to be scaled later
|
||||||
|
if (MpInstanceData* instanceData = sMpDataStore->GetInstanceData(map->GetId(), map->GetInstanceId())) {
|
||||||
|
sMythicPlus->AddScaledCreature(creature, instanceData);
|
||||||
|
} else {
|
||||||
|
sMythicPlus->AddCreatureForScaling(creature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// void OnAllCreatureUpdate(Creature* creature, uint32 diff) override
|
// void OnAllCreatureUpdate(Creature* creature, uint32 diff) override
|
||||||
// {
|
// {
|
||||||
// }
|
// }
|
||||||
|
|||||||
@@ -10,6 +10,83 @@ public:
|
|||||||
MythicPlus_UnitScript() : UnitScript("MythicPlus_UnitScript", true) { }
|
MythicPlus_UnitScript() : UnitScript("MythicPlus_UnitScript", true) { }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/**
|
||||||
|
* Handles damage from non-creature sources (GameObjects, Players, etc.)
|
||||||
|
* @tparam DamageType Type of damage (int32/float)
|
||||||
|
* @param target Target of the damage
|
||||||
|
* @param attacker The non-creature attacker (passed by reference and may be modified)
|
||||||
|
* @param damage Reference to damage value (will be modified)
|
||||||
|
* @param spellInfo The spell being cast
|
||||||
|
* @param eventType Type of event (spell/melee/etc)
|
||||||
|
*/
|
||||||
|
template<typename DamageType>
|
||||||
|
void HandleNonCreatureAttacker(Unit* target, Unit*& attacker, DamageType& damage,
|
||||||
|
SpellInfo const* spellInfo, MythicPlus::MP_UNIT_EVENT_TYPE eventType)
|
||||||
|
{
|
||||||
|
Map* map = target ? target->GetMap() : nullptr;
|
||||||
|
std::string attackerType = "nullptr";
|
||||||
|
std::string attackerName = "unknown";
|
||||||
|
uint32 entry = 0;
|
||||||
|
|
||||||
|
if (attacker) {
|
||||||
|
if (attacker->GetTypeId() == TYPEID_GAMEOBJECT) {
|
||||||
|
attackerType = "GameObject";
|
||||||
|
if (GameObject* go = attacker->ToGameObject()) {
|
||||||
|
entry = go->GetEntry();
|
||||||
|
if (GameObjectTemplate const* goInfo = go->GetGOInfo()) {
|
||||||
|
attackerName = goInfo->name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (attacker->GetTypeId() == TYPEID_PLAYER) {
|
||||||
|
attackerType = "Player";
|
||||||
|
attackerName = attacker->GetName();
|
||||||
|
} else if (attacker->GetTypeId() == TYPEID_UNIT) {
|
||||||
|
attackerType = "Unit (non-creature)";
|
||||||
|
attackerName = attacker->GetName();
|
||||||
|
} else {
|
||||||
|
attackerType = "Unknown Type";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to find a creature attacker from target's attackers list if we have one use it for scaling
|
||||||
|
Unit::AttackerSet const& attackers = target ? target->getAttackers() : Unit::AttackerSet();
|
||||||
|
if (!attackers.empty()) {
|
||||||
|
attacker = *attackers.begin();
|
||||||
|
if (Creature* creatureAttacker = attacker->ToCreature()) {
|
||||||
|
|
||||||
|
if (MpCreatureData* creatureData = sMpDataStore->GetCreatureData(creatureAttacker->GetGUID())) {
|
||||||
|
damage = static_cast<DamageType>(modifyIncomingDmgHeal(eventType, target, creatureAttacker,
|
||||||
|
static_cast<uint32>(damage), spellInfo)) * sMythicPlus->nonCreatureSpellReducer;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
MpLogger::debug("====== SPELL SCALING: Non-Creature attacker - Name: {}, Spell: {}({}), Damage: {}",
|
||||||
|
attackerName,
|
||||||
|
spellInfo ? spellInfo->SpellName[0] : "No Spell",
|
||||||
|
spellInfo ? spellInfo->Id : 0,
|
||||||
|
damage);
|
||||||
|
|
||||||
|
if (map) {
|
||||||
|
if (MpInstanceData* instanceData = sMpDataStore->GetInstanceData(map->GetId(), map->GetInstanceId())) {
|
||||||
|
damage = static_cast<DamageType>(damage * instanceData->creature.spell * sMythicPlus->nonCreatureSpellReducer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Fallback to instance-based scaling if we can't find a nearest creature
|
||||||
|
else if (map) {
|
||||||
|
if (MpInstanceData* instanceData = sMpDataStore->GetInstanceData(map->GetId(), map->GetInstanceId())) {
|
||||||
|
damage = static_cast<DamageType>(damage * instanceData->creature.spell * sMythicPlus->nonCreatureSpellReducer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Default scaling if no specific handler applied
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Helper function to determine if a spell scales with Attack Power
|
// Helper function to determine if a spell scales with Attack Power
|
||||||
bool IsAttackPowerScalingSpell(SpellInfo const* spellInfo) {
|
bool IsAttackPowerScalingSpell(SpellInfo const* spellInfo) {
|
||||||
if (!spellInfo || spellInfo->Effects.empty()) {
|
if (!spellInfo || spellInfo->Effects.empty()) {
|
||||||
@@ -63,37 +140,11 @@ private:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if attacker is a GameObject (traps, totems, environmental hazards)
|
// If this is a special case where the attacker is not a creature
|
||||||
if (!attacker || !attacker->ToCreature()) {
|
if (!attacker || !attacker->ToCreature()) {
|
||||||
MpLogger::debug("SPELL SCALING: Attacker is not a creature (likely GameObject or null), skipping CalcValue reversal");
|
return HandleNonCreatureAttacker(target, attacker, damage, spellInfo, eventType);
|
||||||
// Apply Mythic+ scaling to original damage without CalcValue reversal
|
|
||||||
damage = static_cast<DamageType>(modifyIncomingDmgHeal(eventType, target, attacker, static_cast<uint32>(damage), spellInfo));
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Debug: Log spell effects to understand what we're dealing with
|
|
||||||
// if (spellInfo->Effects.size() > 0) {
|
|
||||||
// auto mainEffect = spellInfo->Effects[0];
|
|
||||||
|
|
||||||
// MpLogger::debug("{}: Incoming Damage: {} Spell {} (ID: {}) Family: {} has RealPointsPerLevel: {} and BasePoints: {} and DieSides: {} and School: {}", logPrefix,
|
|
||||||
// damage,
|
|
||||||
// spellInfo->SpellName[0],
|
|
||||||
// spellInfo->Id,
|
|
||||||
|
|
||||||
// mainEffect.RealPointsPerLevel,
|
|
||||||
// mainEffect.BasePoints,
|
|
||||||
// mainEffect.DieSides,
|
|
||||||
// spellInfo->SchoolMask);
|
|
||||||
// } else {
|
|
||||||
// MpLogger::debug("{}: Incoming Damage: {} Spell {} (ID: {}) has no effects and School: {}", logPrefix,
|
|
||||||
// damage,
|
|
||||||
// spellInfo->SpellName[0],
|
|
||||||
// spellInfo->Id,
|
|
||||||
// spellInfo->SchoolMask);
|
|
||||||
|
|
||||||
// return;
|
|
||||||
// }
|
|
||||||
|
|
||||||
Creature* creatureCaster = attacker->ToCreature();
|
Creature* creatureCaster = attacker->ToCreature();
|
||||||
MpCreatureData* creatureData = sMpDataStore->GetCreatureData(creatureCaster->GetGUID());
|
MpCreatureData* creatureData = sMpDataStore->GetCreatureData(creatureCaster->GetGUID());
|
||||||
|
|
||||||
@@ -115,14 +166,14 @@ private:
|
|||||||
if (spellInfo && !spellInfo->Effects.empty()) {
|
if (spellInfo && !spellInfo->Effects.empty()) {
|
||||||
int32 baseEffect = spellInfo->Effects[0].CalcValue(attacker, nullptr, nullptr);
|
int32 baseEffect = spellInfo->Effects[0].CalcValue(attacker, nullptr, nullptr);
|
||||||
if (damage <= (baseEffect * 1.15f)) {
|
if (damage <= (baseEffect * 1.15f)) {
|
||||||
MpLogger::debug(">>>> MELEE SPELL SCALING: Spell {} (ID: {}) is not scaled by AP damage: {} vs originalEffect: {}",
|
// MpLogger::debug(">>>> MELEE SPELL SCALING: Spell {} (ID: {}) is not scaled by AP damage: {} vs originalEffect: {}",
|
||||||
spellInfo->SpellName[0], spellInfo->Id, damage, baseEffect);
|
// spellInfo->SpellName[0], spellInfo->Id, damage, baseEffect);
|
||||||
notScaledByAP = true;
|
notScaledByAP = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// If we can't determine the base effect, default to treating it as not AP-scaled
|
// If we can't determine the base effect, default to treating it as not AP-scaled
|
||||||
notScaledByAP = true;
|
notScaledByAP = true;
|
||||||
MpLogger::debug(">>>> MELEE SPELL SCALING: Could not determine base effect for spell, defaulting to spell scaling");
|
// MpLogger::debug(">>>> MELEE SPELL SCALING: Could not determine base effect for spell, defaulting to spell scaling");
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the effect type of the spell is not physical (aka not mitigated by armor/defense) then it needs to instead have the typical
|
// if the effect type of the spell is not physical (aka not mitigated by armor/defense) then it needs to instead have the typical
|
||||||
@@ -132,7 +183,7 @@ private:
|
|||||||
|
|
||||||
damage = modifyIncomingDmgHeal(MythicPlus::UNIT_EVENT_MELEE, target, attacker, meleeDamage);
|
damage = modifyIncomingDmgHeal(MythicPlus::UNIT_EVENT_MELEE, target, attacker, meleeDamage);
|
||||||
|
|
||||||
MpLogger::debug(">>MELEE SPELL SCALING: {} hits with spell: {} ID: {} meleeDamage: {} damage: {}", attacker->GetName(), spellInfo->SpellName[0], spellInfo->Id, meleeDamage, damage);
|
// MpLogger::debug(">>MELEE SPELL SCALING: {} hits with spell: {} ID: {} meleeDamage: {} damage: {}", attacker->GetName(), spellInfo->SpellName[0], spellInfo->Id, meleeDamage, damage);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// get the creatures original attack power
|
// get the creatures original attack power
|
||||||
@@ -143,7 +194,7 @@ private:
|
|||||||
uint32 apDmg = static_cast<uint32>(creatureData->originalStats->AttackPower * 0.10f);
|
uint32 apDmg = static_cast<uint32>(creatureData->originalStats->AttackPower * 0.10f);
|
||||||
uint32 finalDmg = spellDmg + apDmg;
|
uint32 finalDmg = spellDmg + apDmg;
|
||||||
|
|
||||||
MpLogger::debug(">> AP BASED DAMAGE Scaledown: origDamage: {} | spellDmg: {} | apDmg: {} | finalDmg: {}", static_cast<int32>(damage), spellDmg, apDmg, finalDmg);
|
// MpLogger::debug(">> AP BASED DAMAGE Scaledown: origDamage: {} | spellDmg: {} | apDmg: {} | finalDmg: {}", static_cast<int32>(damage), spellDmg, apDmg, finalDmg);
|
||||||
|
|
||||||
damage = modifyIncomingDmgHeal(MythicPlus::UNIT_EVENT_SPELL, target, attacker, finalDmg, spellInfo);
|
damage = modifyIncomingDmgHeal(MythicPlus::UNIT_EVENT_SPELL, target, attacker, finalDmg, spellInfo);
|
||||||
|
|
||||||
@@ -231,7 +282,7 @@ public:
|
|||||||
if (!target && !attacker) {
|
if (!target && !attacker) {
|
||||||
|
|
||||||
if(spellInfo) {
|
if(spellInfo) {
|
||||||
MpLogger::info("ModifySpellDamageTaken: Target and attacker are null for spell: {} ID: {}", spellInfo->SpellName[0], spellInfo->Id);
|
// MpLogger::info("ModifySpellDamageTaken: Target and attacker are null for spell: {} ID: {}", spellInfo->SpellName[0], spellInfo->Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -244,12 +295,12 @@ public:
|
|||||||
|
|
||||||
if(!sMythicPlus->EligibleDamageTarget(target)) {
|
if(!sMythicPlus->EligibleDamageTarget(target)) {
|
||||||
if(spellInfo) {
|
if(spellInfo) {
|
||||||
MpLogger::info("ModifySpellDamageTaken: Target is not eligible for spell: {} ID: {}", spellInfo->SpellName[0], spellInfo->Id);
|
// MpLogger::info("ModifySpellDamageTaken: Target is not eligible for spell: {} ID: {}", spellInfo->SpellName[0], spellInfo->Id);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MpLogger::debug("ModifySpellDamageTaken: {} hits {} with spell: {} ID: {}", attacker ? attacker->GetName() : "[null]", target ? target->GetName() : "[null]", spellInfo ? spellInfo->SpellName[0] : "[no spell]", spellInfo ? spellInfo->Id : 0);
|
// MpLogger::debug("ModifySpellDamageTaken: {} hits {} with spell: {} ID: {}", attacker ? attacker->GetName() : "[null]", target ? target->GetName() : "[null]", spellInfo ? spellInfo->SpellName[0] : "[no spell]", spellInfo ? spellInfo->Id : 0);
|
||||||
|
|
||||||
// Use the generic ProcessSpellDamage function
|
// Use the generic ProcessSpellDamage function
|
||||||
ProcessSpellDamage(target, attacker, damage, spellInfo, MythicPlus::UNIT_EVENT_SPELL, "SPELL DAMAGE");
|
ProcessSpellDamage(target, attacker, damage, spellInfo, MythicPlus::UNIT_EVENT_SPELL, "SPELL DAMAGE");
|
||||||
@@ -286,93 +337,9 @@ public:
|
|||||||
healing = modifyIncomingDmgHeal(MythicPlus::UNIT_EVENT_HEAL, target, healer, healing, spellInfo);
|
healing = modifyIncomingDmgHeal(MythicPlus::UNIT_EVENT_HEAL, target, healer, healing, spellInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnAuraApply(Unit* unit, Aura* aura) override {
|
|
||||||
if (!unit || !aura) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only scale auras for players
|
|
||||||
if (!unit->IsPlayer()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(MOD_PRESENT_NPCBOTS)
|
|
||||||
if (unit->IsNPCBotOrPet()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Map* map = unit->GetMap();
|
|
||||||
if (!sMythicPlus->IsMapEligible(map)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get instance data for scaling factors
|
|
||||||
MpInstanceData* instanceData = sMpDataStore->GetInstanceData(map->GetId(), map->GetInstanceId());
|
|
||||||
if (!instanceData) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
SpellInfo const* spellInfo = aura->GetSpellInfo();
|
|
||||||
if (!spellInfo) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Creature* creatureCaster = aura->GetCaster()->ToCreature();
|
|
||||||
if (!creatureCaster) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// MpLogger::debug("Aura Apply: {} applied to {} by {} Id: {}", spellInfo->SpellName[0], unit->GetName(), aura->GetCaster()->GetName(), aura->GetId());
|
|
||||||
|
|
||||||
// Scale aura effects based on creature type and instance difficulty
|
|
||||||
float scaleFactor = 1.0f;
|
|
||||||
|
|
||||||
if (creatureCaster->IsDungeonBoss() || creatureCaster->isWorldBoss()) {
|
|
||||||
scaleFactor = instanceData->boss.spell * 0.8f; // Reduce boss aura scaling slightly
|
|
||||||
} else {
|
|
||||||
scaleFactor = instanceData->creature.spell * 0.7f; // Reduce normal creature aura scaling
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply scaling to stat modifier effects only (damage auras handled elsewhere)
|
|
||||||
for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) {
|
|
||||||
AuraEffect* effect = aura->GetEffect(i);
|
|
||||||
if (!effect) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto amount = effect->GetAmount();
|
|
||||||
// MpLogger::debug("Aura Effect type: {} amount: {}", effect->GetAuraType(), amount);
|
|
||||||
|
|
||||||
// // Only scale stat modifiers and resistances (not damage/healing effects)
|
|
||||||
// if (effect->GetAuraType() == SPELL_AURA_MOD_STAT ||
|
|
||||||
// effect->GetAuraType() == SPELL_AURA_MOD_TOTAL_STAT_PERCENTAGE ||
|
|
||||||
// effect->GetAuraType() == SPELL_AURA_MOD_RESISTANCE ||
|
|
||||||
// effect->GetAuraType() == SPELL_AURA_MOD_RESISTANCE_PCT ||
|
|
||||||
// effect->GetAuraType() == SPELL_AURA_MOD_BASE_RESISTANCE_PCT ||
|
|
||||||
// effect->GetAuraType() == SPELL_AURA_MOD_DAMAGE_DONE ||
|
|
||||||
// effect->GetAuraType() == SPELL_AURA_MOD_DAMAGE_TAKEN ||
|
|
||||||
// effect->GetAuraType() == SPELL_AURA_MOD_HEALING_DONE ||
|
|
||||||
// effect->GetAuraType() == SPELL_AURA_MOD_HEALING_PCT ||
|
|
||||||
// effect->GetAuraType() == SPELL_AURA_MOD_HEALING_TAKEN_PCT ||
|
|
||||||
// effect->GetAuraType() == SPELL_AURA_MOD_ARMOR_PENETRATION_PCT ||
|
|
||||||
// effect->GetAuraType() == SPELL_AURA_MOD_ATTACK_POWER ||
|
|
||||||
// effect->GetAuraType() == SPELL_AURA_MOD_ATTACK_POWER_PCT ||
|
|
||||||
// effect->GetAuraType() == SPELL_AURA_MOD_SPELL_POWER_PCT) {
|
|
||||||
|
|
||||||
// int32 originalAmount = effect->GetAmount();
|
|
||||||
// int32 newAmount = int32(originalAmount * scaleFactor);
|
|
||||||
// effect->ChangeAmount(newAmount);
|
|
||||||
|
|
||||||
// MpLogger::debug("AURA SCALING: Scaled {} stat modifier effect {} from {} to {} (factor: {:.2f})",
|
|
||||||
// spellInfo->SpellName[0], i, originalAmount, newAmount, scaleFactor);
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32 modifyIncomingDmgHeal(MythicPlus::MP_UNIT_EVENT_TYPE eventType,Unit* target, Unit* attacker, uint32 damageOrHeal, SpellInfo const* spellInfo = nullptr) {
|
uint32 modifyIncomingDmgHeal(MythicPlus::MP_UNIT_EVENT_TYPE eventType,Unit* target, Unit* attacker, uint32 damageOrHeal, SpellInfo const* spellInfo = nullptr) {
|
||||||
if (!target && !attacker) {
|
if (!target && !attacker) {
|
||||||
MpLogger::info("modifyIncomingDmgHeal: Target and attacker are null for event {}", eventType);
|
// MpLogger::info("modifyIncomingDmgHeal: Target and attacker are null for event {}", eventType);
|
||||||
return damageOrHeal;
|
return damageOrHeal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,12 +398,20 @@ public:
|
|||||||
*/
|
*/
|
||||||
switch (eventType) {
|
switch (eventType) {
|
||||||
case MythicPlus::UNIT_EVENT_MELEE:
|
case MythicPlus::UNIT_EVENT_MELEE:
|
||||||
|
|
||||||
|
// Damage that is not mitigated by armor needs to be debuffed as it hits too hard and without resists
|
||||||
|
// it hits too hard give everyone a benefit of 30% armor reduction
|
||||||
|
MpLogger::debug(">>> Modify Melee Damage: Creature Name: {} alteredDmgHeal: {} School Mask: {}", creature->GetName(), alteredDmgHeal, creature->GetMeleeDamageSchoolMask());
|
||||||
|
if(creature->GetMeleeDamageSchoolMask() != SPELL_SCHOOL_MASK_NORMAL && creature->GetMeleeDamageSchoolMask() != SPELL_SCHOOL_MASK_NONE) {
|
||||||
|
damageOrHeal = damageOrHeal * 0.50f;
|
||||||
|
}
|
||||||
if(creature->IsDungeonBoss() || creature->isWorldBoss() || creature->GetEntry() == 23682) {
|
if(creature->IsDungeonBoss() || creature->isWorldBoss() || creature->GetEntry() == 23682) {
|
||||||
alteredDmgHeal = damageOrHeal * instanceData->boss.melee;
|
alteredDmgHeal = damageOrHeal * instanceData->boss.melee;
|
||||||
} else {
|
} else {
|
||||||
alteredDmgHeal = damageOrHeal * instanceData->creature.melee;
|
alteredDmgHeal = damageOrHeal * instanceData->creature.melee;
|
||||||
}
|
}
|
||||||
// MpLogger::debug("Incoming Melee New Damage: {}({}) {} hits {}", alteredDmgHeal, damageOrHeal, attacker->GetName(), target->GetName());
|
|
||||||
|
// MpLogger::debug(">>>>>>>>>>>> Incoming Melee New Damage: {}({}) {} hits {}", alteredDmgHeal, damageOrHeal, attacker->GetName(), target->GetName());
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case MythicPlus::UNIT_EVENT_DOT:
|
case MythicPlus::UNIT_EVENT_DOT:
|
||||||
|
|||||||
@@ -89,10 +89,6 @@ public:
|
|||||||
sMythicPlus->legendaryItemOffset = sConfigMgr->GetOption<uint32>("MythicPlus.Legendary.ItemOffset", 21000000);
|
sMythicPlus->legendaryItemOffset = sConfigMgr->GetOption<uint32>("MythicPlus.Legendary.ItemOffset", 21000000);
|
||||||
sMythicPlus->ascendantItemOffset = sConfigMgr->GetOption<uint32>("MythicPlus.Ascendant.ItemOffset", 22000000);
|
sMythicPlus->ascendantItemOffset = sConfigMgr->GetOption<uint32>("MythicPlus.Ascendant.ItemOffset", 22000000);
|
||||||
|
|
||||||
// Deprecated part of old attack power scaling
|
|
||||||
sMythicPlus->meleeAttackPowerDampener = sConfigMgr->GetOption<uint32>("MythicPlus.MeleeAttackPowerDampener", 2000);
|
|
||||||
sMythicPlus->meleeAttackPowerStart = sConfigMgr->GetOption<uint32>("MythicPlus.MeleeAttackPowerStart", 10000);
|
|
||||||
|
|
||||||
// Get diminishing returns from configuration
|
// Get diminishing returns from configuration
|
||||||
sMythicPlus->diminishingExponent = sConfigMgr->GetOption<float>("MythicPlus.DiminishingExponent", 0.975f);
|
sMythicPlus->diminishingExponent = sConfigMgr->GetOption<float>("MythicPlus.DiminishingExponent", 0.975f);
|
||||||
sMythicPlus->diminishingThresholds = {
|
sMythicPlus->diminishingThresholds = {
|
||||||
@@ -100,6 +96,10 @@ public:
|
|||||||
{MpDifficulty::MP_DIFFICULTY_LEGENDARY, sConfigMgr->GetOption<uint32>("MythicPlus.DiminishingThreshold.Legendary", 20000)},
|
{MpDifficulty::MP_DIFFICULTY_LEGENDARY, sConfigMgr->GetOption<uint32>("MythicPlus.DiminishingThreshold.Legendary", 20000)},
|
||||||
{MpDifficulty::MP_DIFFICULTY_ASCENDANT, sConfigMgr->GetOption<uint32>("MythicPlus.DiminishingThreshold.Ascendant", 40000)}
|
{MpDifficulty::MP_DIFFICULTY_ASCENDANT, sConfigMgr->GetOption<uint32>("MythicPlus.DiminishingThreshold.Ascendant", 40000)}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
sMythicPlus->elementalMeleeReducer = sConfigMgr->GetOption<float>("MythicPlus.ElementalMeleeReducer", 0.50f);
|
||||||
|
sMythicPlus->normalEnemyReducer = sConfigMgr->GetOption<float>("MythicPlus.NormalEnemyReducer", 0.50f);
|
||||||
|
sMythicPlus->nonCreatureSpellReducer = sConfigMgr->GetOption<float>("MythicPlus.NonCreatureSpellReducer", 0.50f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnStartup() override
|
void OnStartup() override
|
||||||
|
|||||||
Reference in New Issue
Block a user