diff options
author | Aqua Deus <95978183+aquadeus@users.noreply.github.com> | 2022-02-07 20:53:32 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-07 20:53:32 +0100 |
commit | d22d4616339a966ce5e5fe959dca622fc21b7988 (patch) | |
tree | b25cbc55d186373400e43f5cdbe15e795ecfb7e3 /src | |
parent | 2ae67de4c0f327edc60d5da9cc815016d48b7228 (diff) |
Core/Spells: Implement SPELL_ATTR7_NO_ATTACK_DODGE, SPELL_ATTR7_NO_ATTACK_PARRY and SPELL_ATTR7_NO_ATTACK_MISS (#27715)
Co-authored-by: Shauren <shauren.trinity@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Object/Object.cpp | 86 | ||||
-rw-r--r-- | src/server/game/Entities/Unit/Unit.cpp | 7 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/SharedDefines.h | 6 | ||||
-rw-r--r-- | src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp | 18 |
4 files changed, 64 insertions, 53 deletions
diff --git a/src/server/game/Entities/Object/Object.cpp b/src/server/game/Entities/Object/Object.cpp index be19025582d..07b73e66697 100644 --- a/src/server/game/Entities/Object/Object.cpp +++ b/src/server/game/Entities/Object/Object.cpp @@ -2366,54 +2366,62 @@ SpellMissInfo WorldObject::MagicSpellHitResult(Unit* victim, SpellInfo const* sp if (!victim->IsAlive() && victim->GetTypeId() != TYPEID_PLAYER) return SPELL_MISS_NONE; - SpellSchoolMask schoolMask = spellInfo->GetSchoolMask(); - // PvP - PvE spell misschances per leveldif > 2 - int32 lchance = victim->GetTypeId() == TYPEID_PLAYER ? 7 : 11; - int32 thisLevel = GetLevelForTarget(victim); - if (GetTypeId() == TYPEID_UNIT && ToCreature()->IsTrigger()) - thisLevel = std::max<int32>(thisLevel, spellInfo->SpellLevel); - int32 leveldif = int32(victim->GetLevelForTarget(this)) - thisLevel; - int32 levelBasedHitDiff = leveldif; - - // Base hit chance from attacker and victim levels - int32 modHitChance = 100; - if (levelBasedHitDiff >= 0) - { - if (victim->GetTypeId() != TYPEID_PLAYER) + float missChance = [&]() + { + if (spellInfo->HasAttribute(SPELL_ATTR7_NO_ATTACK_MISS)) + return 0.0f; + + SpellSchoolMask schoolMask = spellInfo->GetSchoolMask(); + // PvP - PvE spell misschances per leveldif > 2 + int32 lchance = victim->GetTypeId() == TYPEID_PLAYER ? 7 : 11; + int32 thisLevel = GetLevelForTarget(victim); + if (GetTypeId() == TYPEID_UNIT && ToCreature()->IsTrigger()) + thisLevel = std::max<int32>(thisLevel, spellInfo->SpellLevel); + int32 leveldif = int32(victim->GetLevelForTarget(this)) - thisLevel; + int32 levelBasedHitDiff = leveldif; + + // Base hit chance from attacker and victim levels + int32 modHitChance = 100; + if (levelBasedHitDiff >= 0) { - modHitChance = 94 - 3 * std::min(levelBasedHitDiff, 3); - levelBasedHitDiff -= 3; + if (victim->GetTypeId() != TYPEID_PLAYER) + { + modHitChance = 94 - 3 * std::min(levelBasedHitDiff, 3); + levelBasedHitDiff -= 3; + } + else + { + modHitChance = 96 - std::min(levelBasedHitDiff, 2); + levelBasedHitDiff -= 2; + } + if (levelBasedHitDiff > 0) + modHitChance -= lchance * std::min(levelBasedHitDiff, 7); } else + modHitChance = 97 - levelBasedHitDiff; + + // Spellmod from SpellModOp::HitChance + if (Player* modOwner = GetSpellModOwner()) + modOwner->ApplySpellMod(spellInfo, SpellModOp::HitChance, modHitChance); + + // Spells with SPELL_ATTR3_IGNORE_HIT_RESULT will ignore target's avoidance effects + if (!spellInfo->HasAttribute(SPELL_ATTR3_IGNORE_HIT_RESULT)) { - modHitChance = 96 - std::min(levelBasedHitDiff, 2); - levelBasedHitDiff -= 2; + // Chance hit from victim SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE auras + modHitChance += victim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE, schoolMask); } - if (levelBasedHitDiff > 0) - modHitChance -= lchance * std::min(levelBasedHitDiff, 7); - } - else - modHitChance = 97 - levelBasedHitDiff; - - // Spellmod from SpellModOp::HitChance - if (Player* modOwner = GetSpellModOwner()) - modOwner->ApplySpellMod(spellInfo, SpellModOp::HitChance, modHitChance); - // Spells with SPELL_ATTR3_IGNORE_HIT_RESULT will ignore target's avoidance effects - if (!spellInfo->HasAttribute(SPELL_ATTR3_IGNORE_HIT_RESULT)) - { - // Chance hit from victim SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE auras - modHitChance += victim->GetTotalAuraModifierByMiscMask(SPELL_AURA_MOD_ATTACKER_SPELL_HIT_CHANCE, schoolMask); - } + float HitChance = modHitChance; + // Increase hit chance from attacker SPELL_AURA_MOD_SPELL_HIT_CHANCE and attacker ratings + if (Unit const* unit = ToUnit()) + HitChance += unit->m_modSpellHitChance; - int32 HitChance = modHitChance * 100; - // Increase hit chance from attacker SPELL_AURA_MOD_SPELL_HIT_CHANCE and attacker ratings - if (Unit const* unit = ToUnit()) - HitChance += int32(unit->m_modSpellHitChance * 100.0f); + RoundToInterval(HitChance, 0.0f, 100.0f); - RoundToInterval(HitChance, 0, 10000); + return 100.0f - HitChance; + }(); - int32 tmp = 10000 - HitChance; + int32 tmp = int32(missChance * 100.0f); int32 rand = irand(0, 9999); if (tmp > 0 && rand < tmp) diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index f9e66caa44d..cfb20a015b8 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -2363,8 +2363,8 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo if (spellInfo->HasAttribute(SPELL_ATTR0_IMPOSSIBLE_DODGE_PARRY_BLOCK)) return SPELL_MISS_NONE; - bool canDodge = true; - bool canParry = true; + bool canDodge = !spellInfo->HasAttribute(SPELL_ATTR7_NO_ATTACK_DODGE); + bool canParry = !spellInfo->HasAttribute(SPELL_ATTR7_NO_ATTACK_PARRY); bool canBlock = spellInfo->HasAttribute(SPELL_ATTR3_BLOCKABLE_SPELL); // if victim is casting or cc'd it can't avoid attacks @@ -11559,6 +11559,9 @@ int32 Unit::CalculateAOEAvoidance(int32 damage, uint32 schoolMask, ObjectGuid co // Crit or block - determined on damage calculation phase! (and can be both in some time) float Unit::MeleeSpellMissChance(Unit const* victim, WeaponAttackType attType, SpellInfo const* spellInfo) const { + if (spellInfo && spellInfo->HasAttribute(SPELL_ATTR7_NO_ATTACK_MISS)) + return 0.f; + //calculate miss chance float missChance = victim->GetUnitMissChance(); diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 707668233b5..b62dbe68786 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -686,9 +686,9 @@ enum SpellAttr7 : uint32 SPELL_ATTR7_UNK20 = 0x00100000, // TITLE Unknown attribute 20@Attr7 DESCRIPTION Invulnerability related? SPELL_ATTR7_UNK21 = 0x00200000, // TITLE Unknown attribute 21@Attr7 SPELL_ATTR7_IGNORES_COLD_WEATHER_FLYING_REQUIREMENT = 0x00400000, // TITLE Ignores Cold Weather Flying Requirement - SPELL_ATTR7_UNK23 = 0x00800000, // TITLE Unknown attribute 23@Attr7 - SPELL_ATTR7_UNK24 = 0x01000000, // TITLE Unknown attribute 24@Attr7 - SPELL_ATTR7_UNK25 = 0x02000000, // TITLE Unknown attribute 25@Attr7 + SPELL_ATTR7_NO_ATTACK_DODGE = 0x00800000, // TITLE No Attack Dodge + SPELL_ATTR7_NO_ATTACK_PARRY = 0x01000000, // TITLE No Attack Parry + SPELL_ATTR7_NO_ATTACK_MISS = 0x02000000, // TITLE No Attack Miss SPELL_ATTR7_UNK26 = 0x04000000, // TITLE Unknown attribute 26@Attr7 SPELL_ATTR7_BYPASS_NO_RESURRECT_AURA = 0x08000000, // TITLE Bypass No Resurrect Aura SPELL_ATTR7_CONSOLIDATED_RAID_BUFF = 0x10000000, // TITLE Consolidate in raid buff frame (client only) diff --git a/src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp b/src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp index 4f90df03315..ab86d61c4e7 100644 --- a/src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp +++ b/src/server/game/Miscellaneous/enuminfo_SharedDefines.cpp @@ -1173,9 +1173,9 @@ TC_API_EXPORT EnumText EnumUtils<SpellAttr7>::ToString(SpellAttr7 value) case SPELL_ATTR7_UNK20: return { "SPELL_ATTR7_UNK20", "Unknown attribute 20@Attr7", "Invulnerability related?" }; case SPELL_ATTR7_UNK21: return { "SPELL_ATTR7_UNK21", "Unknown attribute 21@Attr7", "" }; case SPELL_ATTR7_IGNORES_COLD_WEATHER_FLYING_REQUIREMENT: return { "SPELL_ATTR7_IGNORES_COLD_WEATHER_FLYING_REQUIREMENT", "Ignores Cold Weather Flying Requirement", "" }; - case SPELL_ATTR7_UNK23: return { "SPELL_ATTR7_UNK23", "Unknown attribute 23@Attr7", "" }; - case SPELL_ATTR7_UNK24: return { "SPELL_ATTR7_UNK24", "Unknown attribute 24@Attr7", "" }; - case SPELL_ATTR7_UNK25: return { "SPELL_ATTR7_UNK25", "Unknown attribute 25@Attr7", "" }; + case SPELL_ATTR7_NO_ATTACK_DODGE: return { "SPELL_ATTR7_NO_ATTACK_DODGE", "No Attack Dodge", "" }; + case SPELL_ATTR7_NO_ATTACK_PARRY: return { "SPELL_ATTR7_NO_ATTACK_PARRY", "No Attack Parry", "" }; + case SPELL_ATTR7_NO_ATTACK_MISS: return { "SPELL_ATTR7_NO_ATTACK_MISS", "No Attack Miss", "" }; case SPELL_ATTR7_UNK26: return { "SPELL_ATTR7_UNK26", "Unknown attribute 26@Attr7", "" }; case SPELL_ATTR7_BYPASS_NO_RESURRECT_AURA: return { "SPELL_ATTR7_BYPASS_NO_RESURRECT_AURA", "Bypass No Resurrect Aura", "" }; case SPELL_ATTR7_CONSOLIDATED_RAID_BUFF: return { "SPELL_ATTR7_CONSOLIDATED_RAID_BUFF", "Consolidate in raid buff frame (client only)", "" }; @@ -1217,9 +1217,9 @@ TC_API_EXPORT SpellAttr7 EnumUtils<SpellAttr7>::FromIndex(size_t index) case 20: return SPELL_ATTR7_UNK20; case 21: return SPELL_ATTR7_UNK21; case 22: return SPELL_ATTR7_IGNORES_COLD_WEATHER_FLYING_REQUIREMENT; - case 23: return SPELL_ATTR7_UNK23; - case 24: return SPELL_ATTR7_UNK24; - case 25: return SPELL_ATTR7_UNK25; + case 23: return SPELL_ATTR7_NO_ATTACK_DODGE; + case 24: return SPELL_ATTR7_NO_ATTACK_PARRY; + case 25: return SPELL_ATTR7_NO_ATTACK_MISS; case 26: return SPELL_ATTR7_UNK26; case 27: return SPELL_ATTR7_BYPASS_NO_RESURRECT_AURA; case 28: return SPELL_ATTR7_CONSOLIDATED_RAID_BUFF; @@ -1258,9 +1258,9 @@ TC_API_EXPORT size_t EnumUtils<SpellAttr7>::ToIndex(SpellAttr7 value) case SPELL_ATTR7_UNK20: return 20; case SPELL_ATTR7_UNK21: return 21; case SPELL_ATTR7_IGNORES_COLD_WEATHER_FLYING_REQUIREMENT: return 22; - case SPELL_ATTR7_UNK23: return 23; - case SPELL_ATTR7_UNK24: return 24; - case SPELL_ATTR7_UNK25: return 25; + case SPELL_ATTR7_NO_ATTACK_DODGE: return 23; + case SPELL_ATTR7_NO_ATTACK_PARRY: return 24; + case SPELL_ATTR7_NO_ATTACK_MISS: return 25; case SPELL_ATTR7_UNK26: return 26; case SPELL_ATTR7_BYPASS_NO_RESURRECT_AURA: return 27; case SPELL_ATTR7_CONSOLIDATED_RAID_BUFF: return 28; |