mirror of
https://github.com/araxiaonline/mod-mythic-plus.git
synced 2026-06-13 03:02:24 -04:00
updating spell damage mechanics
This commit is contained in:
@@ -297,31 +297,7 @@ void MythicPlus::ScaleCreature(uint8 level, Creature* creature, MpMultipliers* m
|
||||
creature->SetModifierValue(UNIT_MOD_MANA, BASE_VALUE, (float)mana * 3.0f);
|
||||
}
|
||||
|
||||
// Scale the creatures damage
|
||||
|
||||
MpInstanceData *instanceData = sMpDataStore->GetInstanceData(creature->GetMapId(), creature->GetInstanceId());
|
||||
// int32 meleeDamage = sMpDataStore->GetMeleeScaleFactor(creature->GetMapId(), instanceData->difficulty);
|
||||
|
||||
// Calculate the level difference
|
||||
// float levelDifference = creature->GetLevel() - origLevel;
|
||||
|
||||
// New formula with adjusted divisor for smoother scaling
|
||||
float scalingFactor;
|
||||
|
||||
// uint32 ap = uint32(sMythicPlus->meleeAttackPowerStart - sMythicPlus->meleeAttackPowerDampener);
|
||||
|
||||
// cInfo->DifficultyEntry
|
||||
|
||||
// Calculate base scaling first, then apply creature type modifier
|
||||
// float baseScaling = CalculateScaling(levelDifference, meleeDamage);
|
||||
|
||||
// if (creature->IsDungeonBoss() || creature->isElite() || cInfo->rank >= CREATURE_ELITE_ELITE) {
|
||||
// // Full scaling for bosses and elites
|
||||
// scalingFactor = baseScaling;
|
||||
// } else {
|
||||
// // Reduced scaling for normal creatures to achieve ~60% of elite damage
|
||||
// scalingFactor = baseScaling * 0.6f;
|
||||
// }
|
||||
|
||||
// Handle new melee/range scaling with simple formula (for simplicity range will just be 80% of melee bonus)
|
||||
float meleeMultiplier = sMpDataStore->GetMeleeScaleFactor(creature->GetMapId(), instanceData->difficulty);
|
||||
@@ -356,6 +332,17 @@ void MythicPlus::ScaleCreature(uint8 level, Creature* creature, MpMultipliers* m
|
||||
|
||||
}
|
||||
|
||||
int32 MythicPlus::CalculateSpellDamage(uint32 baseDamage, int originalLevel, int targetLevel) {
|
||||
float origHpPool = sMpDataStore->GetPlayerHealthAvg(originalLevel);
|
||||
float targetHpPool = sMpDataStore->GetPlayerHealthAvg(targetLevel);
|
||||
|
||||
// Using a % of expected damage of the average player pool creates a better consistent experience when scaling spells
|
||||
float percentDamage = baseDamage / origHpPool;
|
||||
int32 scaledDamage = static_cast<int32>(std::ceil(percentDamage * targetHpPool));
|
||||
|
||||
return scaledDamage;
|
||||
}
|
||||
|
||||
int32 MythicPlus::ScaleDamageSpell(SpellInfo const * spellInfo, uint32 damage, MpCreatureData* creatureData, Creature* creature, Unit* target, float damageMultiplier)
|
||||
{
|
||||
if (!spellInfo) {
|
||||
@@ -363,113 +350,74 @@ int32 MythicPlus::ScaleDamageSpell(SpellInfo const * spellInfo, uint32 damage, M
|
||||
return damage;
|
||||
}
|
||||
|
||||
if(!creatureData) {
|
||||
// this is probably a summoned object or totem so going to cheat here and just use the flat modifer
|
||||
MpInstanceData *instanceData = sMpDataStore->GetInstanceData(creature->GetMapId(), creature->GetInstanceId());
|
||||
if (!instanceData) {
|
||||
MpLogger::debug("No instance data found for spell scaling, using original damage");
|
||||
return damage;
|
||||
}
|
||||
|
||||
// Handle totems and summons - scale based on owner's elite status
|
||||
float scaleFactor = sMpDataStore->GetSpellScaleFactor(creature->GetMapId(), instanceData->difficulty);
|
||||
|
||||
// calculate the global modifier x instance modifier
|
||||
float totalModifier = damageMultiplier * scaleFactor;
|
||||
|
||||
// If for some reason there is not a creature, just use the global modifier x instance modifier
|
||||
if(!creature) {
|
||||
MpLogger::error("Invalid creature ScaleDamageSpell()");
|
||||
return damage * totalModifier;
|
||||
}
|
||||
|
||||
// Use the already calculated damage as the base for scaling
|
||||
int32 newDamage = damage;
|
||||
|
||||
// Handle Summoned unit modifiers as
|
||||
if(!creatureData) {
|
||||
|
||||
// handle if bot pets if NPCBot is installed.
|
||||
#ifdef NPCBOT
|
||||
if(creature->IsNPCBotOrPet()) {
|
||||
return damage;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Handle totems and summons - scale based on owner's details because they will not have creature data
|
||||
if(creature->IsTotem() || creature->IsSummon()) {
|
||||
Unit* owner = creature->GetOwner();
|
||||
if(owner && owner->IsCreature()) {
|
||||
Creature* ownerCreature = owner->ToCreature();
|
||||
MpInstanceData *instanceData = sMpDataStore->GetInstanceData(creature->GetMapId(), creature->GetInstanceId());
|
||||
int32 spellBonus = sMpDataStore->GetSpellScaleFactor(creature->GetMapId(), instanceData->difficulty);
|
||||
|
||||
// Calculate level difference (use owner's scaling)
|
||||
float levelDifference = ownerCreature->GetLevel() - 80; // Assume original level 80 for simplicity
|
||||
// Look up the owner creature's original level from MpDataStore
|
||||
MpCreatureData* ownerCreatureData = sMpDataStore->GetCreatureData(ownerCreature->GetGUID());
|
||||
if (ownerCreatureData) {
|
||||
int32 ownerOriginalLevel = ownerCreatureData->originalLevel;
|
||||
|
||||
// Apply same scaling rules as owner
|
||||
float baseTotemScaling = CalculateScaling(levelDifference, spellBonus);
|
||||
|
||||
float scalingFactor;
|
||||
if (ownerCreature->IsDungeonBoss() || ownerCreature->isElite() || ownerCreature->GetCreatureTemplate()->rank >= CREATURE_ELITE_ELITE) {
|
||||
// Elite owner - use elite spell scaling
|
||||
scalingFactor = baseTotemScaling * 0.85f;
|
||||
if (ownerCreature->GetCreatureTemplate()->rank == CREATURE_ELITE_NORMAL) {
|
||||
totalModifier = totalModifier * 0.5f;
|
||||
}
|
||||
newDamage = CalculateSpellDamage(damage, ownerOriginalLevel, ownerCreature->GetLevel());
|
||||
} else {
|
||||
// Normal owner - use normal creature spell scaling
|
||||
scalingFactor = baseTotemScaling * 0.5f;
|
||||
// Fallback if no creature data found - use current level
|
||||
if(ownerCreature->GetCreatureTemplate()->rank == CREATURE_ELITE_NORMAL) {
|
||||
totalModifier = totalModifier * 0.5f;
|
||||
}
|
||||
newDamage = CalculateSpellDamage(damage, ownerCreature->GetLevel(), ownerCreature->GetLevel());
|
||||
MpLogger::debug("No creature data found for owner {}, using current level for scaling", ownerCreature->GetGUID().ToString());
|
||||
}
|
||||
|
||||
return int32(damage * scalingFactor * damageMultiplier);
|
||||
} else {
|
||||
return damage * damageMultiplier;
|
||||
}
|
||||
}
|
||||
|
||||
MpLogger::error("Invalid creature data ScaleDamageSpell()");
|
||||
return damage * damageMultiplier;
|
||||
}
|
||||
|
||||
if(!creature) {
|
||||
MpLogger::error("Invalid creature ScaleDamageSpell()");
|
||||
return damage * damageMultiplier;
|
||||
}
|
||||
|
||||
int32 originalLevel = creatureData->originalLevel;
|
||||
|
||||
MpInstanceData *instanceData = sMpDataStore->GetInstanceData(creature->GetMapId(), creature->GetInstanceId());
|
||||
int32 spellBonus = sMpDataStore->GetSpellScaleFactor(creature->GetMapId(), instanceData->difficulty);
|
||||
|
||||
// Calculate the level difference
|
||||
float levelDifference = creature->GetLevel() - originalLevel;
|
||||
|
||||
// Calculate base spell scaling first, then apply creature type modifier
|
||||
float baseSpellScaling = CalculateScaling(levelDifference, spellBonus);
|
||||
|
||||
float scalingFactor;
|
||||
if (creature->IsDungeonBoss() || creature->isElite() || creature->GetCreatureTemplate()->rank >= CREATURE_ELITE_ELITE) {
|
||||
// Reduced scaling for elite/boss spells to prevent them from hitting too hard
|
||||
scalingFactor = baseSpellScaling * 0.85f;
|
||||
else {
|
||||
MpLogger::error("Invalid creature data ScaleDamageSpell()");
|
||||
return damage * totalModifier;
|
||||
}
|
||||
} else {
|
||||
// Much more reduced scaling for normal creature spells to achieve ~60% of elite damage
|
||||
scalingFactor = baseSpellScaling * 0.5f;
|
||||
}
|
||||
|
||||
int32 totalDamage = 0;
|
||||
auto effects = spellInfo->GetEffects();
|
||||
for (uint8 i = 0; i < effects.size(); ++i)
|
||||
{
|
||||
SpellEffectInfo effect = effects[i];
|
||||
if(effect.IsAura()) {
|
||||
switch(spellInfo->Effects[i].ApplyAuraName) {
|
||||
case SPELL_AURA_PERIODIC_DAMAGE:
|
||||
case SPELL_AURA_PERIODIC_DAMAGE_PERCENT:
|
||||
case SPELL_AURA_POWER_BURN:
|
||||
case SPELL_AURA_PERIODIC_LEECH:
|
||||
case SPELL_AURA_PERIODIC_TRIGGER_SPELL:
|
||||
case SPELL_AURA_PERIODIC_TRIGGER_SPELL_WITH_VALUE:
|
||||
case SPELL_AURA_PERIODIC_DUMMY:
|
||||
case SPELL_AURA_DUMMY:
|
||||
totalDamage += effect.CalcValue(creature, nullptr, target);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch(effect.Effect)
|
||||
{
|
||||
case SPELL_EFFECT_WEAPON_PERCENT_DAMAGE:
|
||||
case SPELL_EFFECT_WEAPON_DAMAGE:
|
||||
case SPELL_EFFECT_NORMALIZED_WEAPON_DMG:
|
||||
return damage;
|
||||
|
||||
case SPELL_EFFECT_SCHOOL_DAMAGE:
|
||||
case SPELL_EFFECT_ENVIRONMENTAL_DAMAGE:
|
||||
case SPELL_EFFECT_POWER_BURN:
|
||||
case SPELL_EFFECT_HEALTH_LEECH:
|
||||
case SPELL_EFFECT_TRIGGER_SPELL:
|
||||
case SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE:
|
||||
case SPELL_EFFECT_DUMMY:
|
||||
totalDamage += effect.CalcValue(creature, nullptr, target);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
newDamage = CalculateSpellDamage(damage, creatureData->originalLevel, creature->GetLevel());
|
||||
if (creature->GetCreatureTemplate()->rank == CREATURE_ELITE_NORMAL) {
|
||||
// Reduced scaling for elite/boss spells to prevent them from hitting too hard
|
||||
totalModifier = totalModifier * 0.5f;
|
||||
}
|
||||
}
|
||||
|
||||
if(totalDamage == 0) {
|
||||
return damage;
|
||||
}
|
||||
|
||||
|
||||
MpLogger::debug(" >>> Spell {} damage scaled from for spell New Damage: {} using: scaling Factor: {} and damage Multi: {}",spellInfo->SpellName[0], totalDamage, scalingFactor, damageMultiplier);
|
||||
|
||||
|
||||
@@ -132,6 +132,9 @@ public:
|
||||
// This scales a heal spell up based on the how much % the original heal spell was
|
||||
int32 ScaleHealSpell(SpellInfo const * spellInfo, uint32 heal, MpCreatureData* creatureData, Creature* creature, Creature* target, float healMultiplier);
|
||||
|
||||
// Calculate spell damage based on player health pools
|
||||
int32 CalculateSpellDamage(uint32 baseDamage, int originalLevel, int targetLevel);
|
||||
|
||||
static bool IsFinalBoss(Creature* creature);
|
||||
static void GroupReset(Group* group, Map* map);
|
||||
|
||||
@@ -146,6 +149,8 @@ float CalculateScaling(int levelDifference, float scaleFactor, float constant =
|
||||
uint32 CalculateNewHealth(Creature* creature, CreatureTemplate const* cInfo, uint32 mapId, MpDifficulty difficulty, uint32 origHealth, float confHPMod);
|
||||
float CalculateNewBaseDamage(CreatureTemplate const* cInfo, uint32 mapId, MpDifficulty difficulty, float origDamage);
|
||||
|
||||
|
||||
|
||||
#define sMythicPlus MythicPlus::instance()
|
||||
|
||||
#endif // MYTHICPLUS_H
|
||||
|
||||
Reference in New Issue
Block a user