Refactored unit damage to be cleaner

This commit is contained in:
2024-09-28 18:35:42 -04:00
parent 6356d975d8
commit ff5eb09faa
6 changed files with 135 additions and 117 deletions

View File

@@ -46,18 +46,21 @@ MythicPlus.EnableDeathLimits = 1
MythicPlus.Mythic.DungeonHealth = 1.25
MythicPlus.Mythic.DungeonMelee = 1.25
MythicPlus.Mythic.DungeonBaseDamage = 1.50
MythicPlus.Mythic.DungeonSpell = 1.15
MythicPlus.Mythic.DungeonArmor = 1.25
MythicPlus.Mythic.DungeonAvgLevel = 83
MythicPlus.Mythic.DungeonBossHealth = 1.50
MythicPlus.Mythic.DungeonBossMelee = 1.35
MythicPlus.Mythic.DungeonBossBaseDamage = 2.00
MythicPlus.Mythic.DungeonBossSpell = 1.25
MythicPlus.Mythic.DungeonBossArmor = 1.35
MythicPlus.Mythic.DungeonBossLevel = 85
MythicPlus.Legendary.DungeonHealth = 2.25
MythicPlus.Legendary.DungeonMelee = 2.25
MythicPlus.Legendary.DungeonBaseDamage = 2.75
MythicPlus.Legendary.DungeonSpell = 2.25
MythicPlus.Legendary.DungeonArmor = 2.25
MythicPlus.Legendary.DungeonAvgLevel = 85
@@ -65,11 +68,13 @@ MythicPlus.Legendary.DungeonAvgLevel = 85
MythicPlus.Legendary.DungeonBossHealth = 2.25
MythicPlus.Legendary.DungeonBossMelee = 2.25
MythicPlus.Legendary.DungeonBossSpell = 2.25
MythicPlus.Legendary.DungeonBossBaseDamage = 4.00
MythicPlus.Legendary.DungeonBossArmor = 3.25
MythicPlus.Legendary.DungeonBossLevel = 87
MythicPlus.Ascendant.DungeonHealth = 3.25
MythicPlus.Ascendant.DungeonMelee = 3.25
MythicPlus.Ascendant.DungeonBaseDamage = 4.75
MythicPlus.Ascendant.DungeonSpell = 3.25
MythicPlus.Ascendant.DungeonArmor = 3.25
MythicPlus.Ascendant.DungeonAvgLevel = 87
@@ -77,6 +82,7 @@ MythicPlus.Ascendant.DungeonAvgLevel = 87
MythicPlus.Ascendant.DungeonBossHealth = 3.25
MythicPlus.Ascendant.DungeonBossMelee = 3.25
MythicPlus.Ascendant.DungeonBossSpell = 3.25
MythicPlus.Ascendant.DungeonBossBaseDamage = 6.00
MythicPlus.Ascendant.DungeonBossArmor = 3.25
MythicPlus.Ascendant.DungeonBossLevel = 90
@@ -88,7 +94,7 @@ MythicPlus.Ascendant.DungeonBossLevel = 90
#
##########################################################
MythicPlus.Mythic.DeathAllowance = 1000
MythicPlus.Mythic.DeathAllowance = 100
MythicPlus.Legendary.DeathAllowance = 30
MythicPlus.Ascendant.DeathAllowance = 15

View File

@@ -64,7 +64,6 @@ public:
MpLogger::info("LootStoreItem is not valid after updating itemid to {} in OnBeforeDropAddItem()", newItemId);
return;
}
}
};

View File

@@ -8,27 +8,27 @@ class MpLogger
public:
template<typename... Args>
static void debug(const char* fmt, Args&&... args) {
LOG_DEBUG("module.MythicPlus", "[MythicPlus] " + std::string(fmt), std::forward<Args>(args)...);
LOG_DEBUG("module.MythicPlus", "[MythicPlus] DEBUG " + std::string(fmt), std::forward<Args>(args)...);
}
template<typename... Args>
static void error(const char* fmt, Args&&... args) {
LOG_ERROR("module.MythicPlus", "[MythicPlus] " + std::string(fmt), std::forward<Args>(args)...);
LOG_ERROR("module.MythicPlus", "[MythicPlus] ERROR " + std::string(fmt), std::forward<Args>(args)...);
}
template<typename... Args>
static void info(const char* fmt, Args&&... args) {
LOG_INFO("module.MythicPlus", "[MythicPlus] " + std::string(fmt), std::forward<Args>(args)...);
LOG_INFO("module.MythicPlus", "[MythicPlus] INFO " + std::string(fmt), std::forward<Args>(args)...);
}
template<typename... Args>
static void warn(const char* fmt, Args&&... args) {
LOG_WARN("module.MythicPlus", "[MythicPlus] " + std::string(fmt), std::forward<Args>(args)...);
LOG_WARN("module.MythicPlus", "[MythicPlus] WARN " + std::string(fmt), std::forward<Args>(args)...);
}
template<typename... Args>
static void trace(const char* fmt, Args&&... args) {
LOG_TRACE("module.MythicPlus", "[MythicPlus] " + std::string(fmt), std::forward<Args>(args)...);
LOG_TRACE("module.MythicPlus", "[MythicPlus] TRACE " + std::string(fmt), std::forward<Args>(args)...);
}
};

View File

@@ -43,7 +43,31 @@ bool MythicPlus::IsDungeonDisabled(uint32 dungeon)
return std::find(disabledDungeons.begin(), disabledDungeons.end(), dungeon) != disabledDungeons.end();
}
bool MythicPlus::EligibleTarget(Unit* target)
bool MythicPlus::EligibleHealTarget(Unit* target)
{
if (!target) {
return false;
}
if(sMythicPlus->EligibleDamageTarget(target)) {
return false;
}
if(sMythicPlus->IsCreatureEligible(target->ToCreature())) {
return true;
}
if (target->GetTypeId() == TYPEID_CORPSE || target->GetTypeId() == TYPEID_GAMEOBJECT) {
return false;
}
return true;
}
bool MythicPlus::EligibleDamageTarget(Unit* target)
{
if (!target) {
return false;
@@ -53,16 +77,7 @@ bool MythicPlus::EligibleTarget(Unit* target)
return true;
}
MpLogger::debug("EligibleTarget: target {} is not a player", target->GetName());
#if defined(NPCBots)
MpLogger::debug("MOD_PRESET_NPCBOTS: value {}", MOD_PRESENT_NPCBOTS);
#endif
#if defined(MOD_PRESENT_NPCBOTS)
MpLogger::debug("IN BOT DEFINED STUFF: target: {} BOT?{}", target->GetName(), target->IsNPCBot());
if (target->IsNPCBot()) {
MpLogger::debug("Target {} is an NPC eligible to be smacked hard", target->GetName());
return true;
@@ -237,6 +252,10 @@ void MythicPlus::ScaleCreature(uint8 level, Creature* creature, MpMultipliers* m
// Scale up the armor with some variance also to make some tougher enemies in the mix
uint32 armor = uint32(std::ceil(stats->BaseArmor * multipliers->armor));
creature->SetArmor(armor);
/**
* @TODO Explore scaling other variable stats based on the creature type at a later date.
*/
// creature->SetModifierValue(UNIT_MOD_ATTACK_POWER, BASE_VALUE, stats->AttackPower * multipliers->melee);
// creature->SetModifierValue(UNIT_MOD_ATTACK_POWER_RANGED, BASE_VALUE, stats->RangedAttackPower * multipliers->melee);

View File

@@ -49,6 +49,14 @@ public:
uint32 legendaryItemOffset;
uint32 ascendantItemOffset;
enum MP_UNIT_EVENT_TYPE
{
UNIT_EVENT_MELEE,
UNIT_EVENT_HEAL,
UNIT_EVENT_DOT,
UNIT_EVENT_SPELL
};
// Map is eligible for mythic+ scaling
bool IsMapEligible(Map* map);
@@ -61,8 +69,11 @@ public:
// if configuration has disabled the specific dungeon return false
bool IsDungeonDisabled(uint32 dungeonId);
// Is it a scaled creature that is being healed
bool EligibleHealTarget(Unit* target);
// Validates if the target of an attack should receive mythic+ damage/heal/dot scaling
bool EligibleTarget(Unit* target);
bool EligibleDamageTarget(Unit* target);
// The creature should be given Mythic+ scaling and powers check for pets, npcs, etc
bool IsCreatureEligible(Creature* creature);

View File

@@ -9,59 +9,6 @@ public:
MythicPlus_UnitScript() : UnitScript("MythicPlus_UnitScript", true) { }
void ModifyPeriodicDamageAurasTick(Unit* target, Unit* attacker, uint32& damage, SpellInfo const* /*spellInfo*/) override {
Map *map = target->GetMap();
if(!sMythicPlus->IsMapEligible(map)) {
return;
}
// If the target is the enemy then increase the amount of healing by the instance data modifier for spell output.
if(target->isType(TYPEID_PLAYER) && attacker->isType(TYPEID_UNIT)) {
Creature* creature = target->ToCreature();
if(!creature || !sMythicPlus->IsCreatureEligible(creature)) {
return;
}
MpInstanceData* instanceData = sMpDataStore->GetInstanceData(map->GetId(), map->GetInstanceId());
if(!instanceData) {
return;
}
if(creature->IsDungeonBoss()) {
damage = damage * (instanceData->boss.spell * 0.8);
} else {
damage = damage * (instanceData->creature.spell * 0.8);
}
}
}
void ModifySpellDamageTaken(Unit* target, Unit* attacker, int32& damage, SpellInfo const* /*spellInfo*/) override {
Map *map = target->GetMap();
if(!sMythicPlus->IsMapEligible(map)) {
return;
}
// If the target is the enemy then increase the amount of healing by the instance data modifier for spell output.
if(target->isType(TYPEID_PLAYER) && attacker->isType(TYPEID_UNIT)) {
Creature* creature = target->ToCreature();
if(!creature || !sMythicPlus->IsCreatureEligible(creature)) {
return;
}
MpInstanceData* instanceData = sMpDataStore->GetInstanceData(map->GetId(), map->GetInstanceId());
if(!instanceData) {
return;
}
if(creature->IsDungeonBoss()) {
damage = damage * instanceData->boss.spell;
} else {
damage = damage * instanceData->creature.spell;
}
}
}
void ModifyMeleeDamage(Unit* target, Unit* attacker, uint32& damage) override {
if (!target && !attacker) {
return;
}
@@ -71,74 +18,110 @@ public:
return;
}
// If the target is the enemy then increase the amount of healing by the instance data modifier for spell output.
if(sMythicPlus->EligibleTarget(target)) {
Creature* creature = attacker->ToCreature();
MpInstanceData* instanceData = sMpDataStore->GetInstanceData(map->GetId(), map->GetInstanceId());
if(!instanceData) {
return;
}
auto origDamage = damage;
if(creature->IsDungeonBoss()) {
damage = damage * instanceData->boss.melee * 5;
} else {
damage = damage * instanceData->creature.melee;
}
}
damage = modifyIncomingDmgHeal(MythicPlus::UNIT_EVENT_DOT, target, attacker, damage);
}
// When a healing spell hits a mythic+ enemy modify based on the modifiers for the difficulty
void ModifyHealReceived(Unit* target, Unit* healer, uint32& healing, SpellInfo const* /*spellInfo*/) override {
void ModifySpellDamageTaken(Unit* target, Unit* attacker, int32& damage, SpellInfo const* /*spellInfo*/) override {
if (!target && !attacker) {
return;
}
Map *map = target->GetMap();
if(!sMythicPlus->IsMapEligible(map)) {
return;
}
// If the target is the enemy then increase the amount of healing by the instance data modifier for spell output.
if(target->isType(TYPEID_UNIT)) {
Creature* creature = target->ToCreature();
if(!creature || !sMythicPlus->IsCreatureEligible(creature)) {
return;
}
damage = modifyIncomingDmgHeal(MythicPlus::UNIT_EVENT_SPELL, target, attacker, damage);
}
MpInstanceData* instanceData = sMpDataStore->GetInstanceData(map->GetId(), map->GetInstanceId());
if(!instanceData) {
return;
}
if(creature->IsDungeonBoss()) {
healing = healing * instanceData->boss.spell;
} else {
healing = healing * instanceData->creature.spell;
}
/**
* Directly Modify the melee damage characters and allied creatures will
* receive from mythic+ scaled enemies.
*/
void ModifyMeleeDamage(Unit* target, Unit* attacker, uint32& damage) override {
if (!target && !attacker) {
return;
}
Map *map = target->GetMap();
if(!sMythicPlus->IsMapEligible(map)) {
return;
}
damage = modifyIncomingDmgHeal(MythicPlus::UNIT_EVENT_MELEE, target, attacker, damage);
}
// void OnAuraApply(Unit* unit, Aura* aura) override {
// When a healing spell hits a mythic+ enemy modify based on the modifiers for the difficulty
void ModifyHealReceived(Unit* target, Unit* healer, uint32& healing, SpellInfo const* /*spellInfo*/) override {
if (!target && !healer) {
return;
}
// }
Map *map = target->GetMap();
if(!sMythicPlus->IsMapEligible(map)) {
return;
}
healing = modifyIncomingDmgHeal(MythicPlus::UNIT_EVENT_HEAL, target, healer, healing);
}
// void OnAuraApply(Unit* unit, Aura* aura) override {}
};
bool EligibleTarget(Unit* target, Unit* attacker) {
uint32 modifyIncomingDmgHeal(MythicPlus::MP_UNIT_EVENT_TYPE eventType,Unit* target, Unit* attacker, uint32 damageOrHeal) {
if (!target && !attacker) {
return false;
return damageOrHeal;
}
#define NPCBots
if (target->GetTypeId() == TYPEID_PLAYER && attacker->GetTypeId() == TYPEID_UNIT) {
return true;
Map *map = target->GetMap();
if(!sMythicPlus->IsMapEligible(map)) {
return damageOrHeal;
}
return false;
Creature* creature = attacker->ToCreature();
MpInstanceData* instanceData = sMpDataStore->GetInstanceData(map->GetId(), map->GetInstanceId());
if(!instanceData) {
return damageOrHeal;
}
// If the target is the enemy then increase the amount of healing by the instance data modifier for spell output.
if(sMythicPlus->EligibleDamageTarget(target)) {
/**
* @TODO: Allow more granular control over the scaling of DOT, HOT, and other spell effects
* in the future if needed
*/
switch (eventType) {
case MythicPlus::UNIT_EVENT_MELEE:
if(creature->IsDungeonBoss()) {
return damageOrHeal * instanceData->boss.melee;
} else {
return damageOrHeal * instanceData->creature.melee;
}
break;
case MythicPlus::UNIT_EVENT_DOT:
case MythicPlus::UNIT_EVENT_SPELL:
if(creature->IsDungeonBoss()) {
return damageOrHeal * instanceData->boss.spell;
} else {
return damageOrHeal * instanceData->creature.spell;
}
break;
}
}
/**
* @TODO: Add more granular control over the scaling of healing spells
*/
if(sMythicPlus->EligibleHealTarget(target)) {
if(creature->IsDungeonBoss()) {
return damageOrHeal * instanceData->boss.spell;
} else {
return damageOrHeal * instanceData->creature.spell;
}
}
return damageOrHeal;
}
void Add_MP_UnitScripts()