Ru-MaNGOS

Ru-MaNGOS (http://mangos.ytdb.ru/index.php)
-   Патчи на рассмотрении (http://mangos.ytdb.ru/forumdisplay.php?f=49)
-   -   [patch/dev] Deterrence (http://mangos.ytdb.ru/showthread.php?t=801)

Insider42 22.04.2010 11:34

[patch/dev] Deterrence
 
Я уже как-то занимался данным спеллом, но старый вариант моего патча стал некорректен из-за изменений в механике работы этого спелла.
то что было реализовано:
1. deflect не должен срабатывать на дальние атаки, вместо этого используется SPELL_AURA_MOD_ATTACKER_RANGED_HIT_CHANCE
2. должен также триггерить 67801, который реализует п.1.
3. вражеские спеллы должны отражаться с любой стороны
4. спеллы не должны заменять друг друга
5. с этой способностью должны парироваться атаки с тыла
6. спелл должен отражать даже _уже_ выпущенные в охотника заклинания
Код:

diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 7ff69a9..888237f 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -1089,6 +1089,16 @@ void Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask)
        return;
    }
 
+    // Recheck deflection (only for delayed spells)
+    if (m_spellInfo->speed && unit->HasAura(19263))
+    {
+        if (realCaster)
+            realCaster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_DEFLECT);
+
+        ResetEffectDamageAndHeal();
+        return;
+    }
+
    if (unit->GetTypeId() == TYPEID_PLAYER)
    {
        ((Player*)unit)->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_BE_SPELL_TARGET, m_spellInfo->Id);
@@ -2784,6 +2794,13 @@ void Spell::cast(bool skipCheck)
                AddTriggeredSpell(60089);
            break;
        }
+        case SPELLFAMILY_HUNTER:
+        {
+            // Deterrence
+            if (m_spellInfo->Id == 19263)
+                AddTriggeredSpell(67801);
+            break;
+        }
        case SPELLFAMILY_ROGUE:
            // Fan of Knives (main hand)
            if (m_spellInfo->Id == 51723 && m_caster->GetTypeId() == TYPEID_PLAYER &&
diff --git a/src/game/SpellMgr.cpp b/src/game/SpellMgr.cpp
index 8a14904..62c76b7 100644
--- a/src/game/SpellMgr.cpp
+++ b/src/game/SpellMgr.cpp
@@ -1728,6 +1728,10 @@ bool SpellMgr::IsNoStackSpellDueToSpell(uint32 spellId_1, uint32 spellId_2) cons
                    (spellInfo_2->SpellFamilyFlags & UI64LIT(0x4)) && (spellInfo_1->SpellFamilyFlags & UI64LIT(0x00000004000)) )
                    return false;
 
+                // Deterrence
+                if( spellInfo_1->SpellIconID == 83 && spellInfo_2->SpellIconID == 83 )
+                    return false;
+
                // Bestial Wrath
                if( spellInfo_1->SpellIconID == 1680 && spellInfo_2->SpellIconID == 1680 )
                    return false;
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 1e34f88..1424a56 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -2562,7 +2562,7 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttack
    // parry & block chances
 
    // check if attack comes from behind, nobody can parry or block if attacker is behind
-    if (!pVictim->HasInArc(M_PI_F,this))
+    if (!pVictim->HasInArc(M_PI_F,this) && !pVictim->HasAura(19263))
    {
        DEBUG_LOG ("RollMeleeOutcomeAgainst: attack came from behind.");
    }
@@ -2866,23 +2866,13 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell,
    bool canDodge = true;
    bool canParry = true;
 
-    // Same spells cannot be parry/dodge
+    // Some spells cannot be parry/dodge
    if (spell->Attributes & SPELL_ATTR_IMPOSSIBLE_DODGE_PARRY_BLOCK)
        return SPELL_MISS_NONE;
 
-    // Ranged attack cannot be parry/dodge only deflect
+    // Ranged attack cannot be parry/dodge only miss
    if (attType == RANGED_ATTACK)
-    {
-        // only if in front
-        if (pVictim->HasInArc(M_PI_F,this))
-        {
-            int32 deflect_chance = pVictim->GetTotalAuraModifier(SPELL_AURA_DEFLECT_SPELLS)*100;
-            tmp+=deflect_chance;
-            if (roll < tmp)
-                return SPELL_MISS_DEFLECT;
-        }
        return SPELL_MISS_NONE;
-    }
 
    // Check for attack from behind
    if (!pVictim->HasInArc(M_PI_F,this))
@@ -2891,7 +2881,8 @@ SpellMissInfo Unit::MeleeSpellHitResult(Unit *pVictim, SpellEntry const *spell,
        if (GetTypeId() == TYPEID_PLAYER && pVictim->GetTypeId() == TYPEID_PLAYER)
            canDodge = false;
        // Can`t parry
-        canParry = false;
+        if (!pVictim->HasAura(19263))
+            canParry = false;
    }
    // Check creatures flags_extra for disable parry
    if(pVictim->GetTypeId()==TYPEID_UNIT)
@@ -3025,14 +3016,10 @@ SpellMissInfo Unit::MagicSpellHitResult(Unit *pVictim, SpellEntry const *spell)
    if (rand < tmp)
        return SPELL_MISS_MISS;
 
-    // cast by caster in front of victim
-    if (pVictim->HasInArc(M_PI_F,this))
-    {
-        int32 deflect_chance = pVictim->GetTotalAuraModifier(SPELL_AURA_DEFLECT_SPELLS)*100;
-        tmp+=deflect_chance;
-        if (rand < tmp)
-            return SPELL_MISS_DEFLECT;
-    }
+    int32 deflect_chance = pVictim->GetTotalAuraModifier(SPELL_AURA_DEFLECT_SPELLS)*100;
+    tmp+=deflect_chance;
+    if (rand < tmp)
+        return SPELL_MISS_DEFLECT;
 
    return SPELL_MISS_NONE;
 }

Из недостатков:
1. Необходимо разобраться для чего нужна aura_288. Мы её не используем
2. Возможно не во всех случаях выдаются верные сообщения (судя по словам некоторых игроков с оффа в некоторых случаях пишет Уворот, хотя у нас выдает Отражение)
3. Также в п.6. реализованной части не проверяется наличие экспертизы у атакующего (а нужно ли?). Т.е. если вы уже выстрелили и охотник после этого включает Сдерживание, то он 100% отклонит вашу атаку, сколько бы у вас ни было экспертизы или прочей фигни.
4. Возможно не все спеллы (например АОЕ) должны отражаться

LordJZ 22.04.2010 17:33

Последний чанк кода (умножение на 100) неправилен, в ауре и так умноженные на 100 значения. Если нет паррирования, то либо персонаж стоит спиной, либо не выучен скилл паррирования, либо не максимален параметр дефа.

Insider42 22.04.2010 18:20

Цитата:

Сообщение от LordJZ (Сообщение 4925)
Последний чанк кода (умножение на 100) неправилен, в ауре и так умноженные на 100 значения. Если нет паррирования, то либо персонаж стоит спиной, либо не выучен скилл паррирования, либо не максимален параметр дефа.

без патча (с патчем не проверял):
1) навык максимален
2) парирование изучено
3) оружие одето
4) не парирует как спереди так и сзади
тут уж я предусмотрел все возможные варианты, парирования нет и всё :(

Insider42 23.04.2010 15:07

Разобрался я с этим парированием, новая версия патча в первом посту

Insider42 23.04.2010 21:21

Как ни странно, но код для п.5. не выполняет то, что должен. Атаки всё также проходят с тыла :/ есть идеи?

wk23 23.04.2010 22:06

Код:

-        // only if in front
-        if (pVictim->HasInArc(M_PI_F,this))
-        {
-            int32 deflect_chance = pVictim->GetTotalAuraModifier(SPELL_AURA_DEFLECT_SPELLS)*100;
-            tmp+=deflect_chance;
-            if (roll < tmp)
-                return SPELL_MISS_DEFLECT;
-        }
        return SPELL_MISS_NONE;
-    }
 
    // Check for attack from behind
    if (!pVictim->HasInArc(M_PI_F,this))


Insider42 24.04.2010 12:50

Цитата:

Сообщение от wk23 (Сообщение 5001)

Вы хоть читали что обозначено под п.5. (Пункт 5)?
Я имею ввиду, что не получается заставить парировать атаки со спины (хотя это противоречит самому понятию парирования, но... близы...). Раньше (мой патч для 3.2.2 мангоса) с этим справлялся
Код:

-        canParry = false;
+        if (!pVictim->HasAura(19263))
+            canParry = false;

Но в данный момент не помагает.

Добавлено:

Судя по всему проблема в MeleeHitOutcome Unit::RollMeleeOutcomeAgainst
Код:

    // check if attack comes from behind, nobody can parry or block if attacker is behind
    if (!pVictim->HasInArc(M_PI_F,this))
    {
        DEBUG_LOG ("RollMeleeOutcomeAgainst: attack came from behind.");
    }
    else
    {
....

Исправляется так:
Код:

diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index dbb8f3e..1b4ede0 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -2579,7 +2579,7 @@ MeleeHitOutcome Unit::RollMeleeOutcomeAgainst (const Unit *pVictim, WeaponAttack
    // parry & block chances
 
    // check if attack comes from behind, nobody can parry or block if attacker is behind
-    if (!pVictim->HasInArc(M_PI_F,this))
+    if (!pVictim->HasInArc(M_PI_F,this) && !pVictim->HasAura(19263))
    {
        DEBUG_LOG ("RollMeleeOutcomeAgainst: attack came from behind.");
    }

Но, это немного нарушает логику работы. Т.е. мы позволяем также и блокировать атаки если имеем ауру 19263, но ведь этот спелл доступен только охотникам, у которых нет блока, собственно не критично.

Обновлен первый пост, теперь парироваться будут атаки со всех сторон

Insider42 12.05.2010 11:45

Обновил патч, теперь будет корректно работать отражение уже запущенных спеллов после изменений ревизии 9784 (написал по памяти, мог и промахнуться)


Текущее время: 19:15. Часовой пояс GMT +3.

ru-mangos.ru - Русское сообщество MaNGOS