Ru-MaNGOS

Ru-MaNGOS (http://mangos.ytdb.ru/index.php)
-   Патчи (http://mangos.ytdb.ru/forumdisplay.php?f=6)
-   -   [patch/dev] Невидимость vs магия (http://mangos.ytdb.ru/showthread.php?t=1046)

Insider42 12.05.2010 14:46

[patch/dev] Невидимость vs магия
 
Достаточно давно роги (они же Разбойники) (и друиды тоже) стали жаловаться, что при уходе, например в "ванишу" (оно же Исчезновение), в них всё равно прилетает спел, если он наносит урон моментально. В итоге с помощью Чародейской вспышки или Чародейских стрел (особенно любимый магами спел для того чтобы мучать разбойников.
В данный момент стот ревизия 9880 и проблема всё ещё есть.

По-моему вот этот участок кода в spell.cpp должен отвечать за это дело
Код:

    // update pointers base at GUIDs to prevent access to non-existed already object
    UpdatePointers();

    // cancel at lost main target unit
    if(!m_targets.getUnitTarget() && m_targets.getUnitTargetGUID() && m_targets.getUnitTargetGUID() != m_caster->GetGUID())
    {
        cancel();
        m_caster->DecreaseCastCounter();
        SetExecutedCurrently(false);
        return;
    }

И нужно добавить проверку на IsVisibleForOrDetect()

У кого-то есть другие идеи по реализации? Пишите, пока я не начал реализацию того, что задумал :)

Ещё есть вариант поработать с этой функцией
Код:

void SpellCastTargets::Update(Unit* caster)
{
    m_GOTarget  = !m_GOTargetGUID.IsEmpty() ? caster->GetMap()->GetGameObject(m_GOTargetGUID) : NULL;
    m_unitTarget = !m_unitTargetGUID.IsEmpty() ?
        ( m_unitTargetGUID == caster->GetObjectGuid() ? caster : ObjectAccessor::GetUnit(*caster, m_unitTargetGUID) ) :
    NULL;

    m_itemTarget = NULL;
    if(caster->GetTypeId() == TYPEID_PLAYER)
    {
        if(m_targetMask & TARGET_FLAG_ITEM)
            m_itemTarget = ((Player*)caster)->GetItemByGuid(m_itemTargetGUID);
        else if(m_targetMask & TARGET_FLAG_TRADE_ITEM)
        {
            Player* pTrader = ((Player*)caster)->GetTrader();
            if(pTrader && m_itemTargetGUID.GetRawValue() < TRADE_SLOT_COUNT)
                m_itemTarget = pTrader->GetItemByPos(pTrader->GetItemPosByTradeSlot(uint32(m_itemTargetGUID.GetRawValue())));
        }
        if(m_itemTarget)
            m_itemTargetEntry = m_itemTarget->GetEntry();
    }
}

патч V1
Код:

diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index fd69f8d..cba440c 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -188,6 +188,10 @@ void SpellCastTargets::Update(Unit* caster)
        ( m_unitTargetGUID == caster->GetObjectGuid() ? caster : ObjectAccessor::GetUnit(*caster, m_unitTargetGUID) ) :
    NULL;
 
+    if (m_unitTarget && m_unitTargetGUID != caster->GetObjectGuid() &&
+        !m_unitTarget->isVisibleForOrDetect(caster, caster, false))
+            m_unitTarget = NULL;
+
    m_itemTarget = NULL;
    if(caster->GetTypeId() == TYPEID_PLAYER)
    {

Сразу возникла проблема - патч выполяет то, для чего он писался, НО не выводит никаких сообщений и обрабатывается даже раньше чем
Код:

            // for delayed spells ignore not visible explicit target
            if (m_spellInfo->speed > 0.0f && unit == m_targets.getUnitTarget() &&
                !unit->isVisibleForOrDetect(m_caster, m_caster, false))
            {
                realCaster->SendSpellMiss(unit, m_spellInfo->Id, SPELL_MISS_EVADE);
                ResetEffectDamageAndHeal();
                return;
            }

в том же spell.cpp, следовательно последний кусок тупо отпадает.

Поставлю на игровой сервер, посмотрим что ещё найдут :P

Laise 12.05.2010 18:06

SpellCastTargets::Update - может зря туда? Update в нескольких местах используется..
if(!m_targets.getUnitTarget() && m_targets.getUnitTargetGUID() && m_targets.getUnitTargetGUID() != m_caster->GetGUID()) может туда уже добавить как еще одно условие ? а не просто обнулять unitTarget?

Insider42 12.05.2010 18:56

Цитата:

Сообщение от Laise (Сообщение 6283)
SpellCastTargets::Update - может зря туда? Update в нескольких местах используется..

Но ведь не логично стрелять в цель которую мы не видим... где бы оно ни происходило и не использовалось

Цитата:

Сообщение от Laise (Сообщение 6283)
if(!m_targets.getUnitTarget() && m_targets.getUnitTargetGUID() && m_targets.getUnitTargetGUID() != m_caster->GetGUID()) может туда уже добавить как еще одно условие ? а не просто обнулять unitTarget?

Тогда каст будет срываться только в самом конце, т.е. полоска дойдёт до конца, а эффект не произойдёт.
Нам же нужно прервать заклинание именно в тот момент когда цель стала недоступна

Everheit 13.05.2010 04:25

логично то логично, но этот баг есть и на офе. близы пытались его фиксить во времена траев ик-ивк, но безуспешно

Deamon 13.05.2010 20:31

Цитата:

Сообщение от Everheit (Сообщение 6309)
логично то логично, но этот баг есть и на офе. близы пытались его фиксить во времена траев ик-ивк, но безуспешно

Там другие глюки. Глюки связанные с петами. И этот глюк таки пофиксили тогда, но бляззы посчитали, что это слишком круто для рог, и вернули все обратно =)))

Insider42 15.05.2010 22:59

С патчем в первом посте проблема:
Ловушки охотников при попадании в них невидимых разбойников - прерываются, в прямом смысле слова.

Загвоздка в том, что m_spellinfo нельзя (или я незнаю как) вызвать из функции, которую меняет патч, так возможно бы сделал исключение...

Новая версия патча в более корректном месте
Код:

diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 16fd1f4..8a59d86 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -3109,6 +3105,9 @@ void Spell::update(uint32 difftime)
        {
            if(m_timer)
            {
+                if (m_targets.getUnitTarget() && !m_targets.getUnitTarget()->isVisibleForOrDetect(m_caster, m_caster, false))
+                    cancel();
+
                if(difftime >= m_timer)
                    m_timer = 0;
                else

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

Insider42 15.06.2010 09:16

Нашёл баг в предыдущей версии патча, из-за которого некоторые невидимые НПС, такие как Хранители душ на БГ, иногда не воскрешали игроков
Новая версия патча не должна иметь данной проблемы, там всего лишь нехватало проверки на IsAlive, ведь мертвый по определению невидим.
Код:

diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 16fd1f4..8a59d86 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -3109,6 +3105,9 @@ void Spell::update(uint32 difftime)
        {
            if(m_timer)
            {
+                if (m_targets.getUnitTarget() && m_targets.getUnitTarget()->isAlive() && !m_targets.getUnitTarget()->isVisibleForOrDetect(m_caster, m_caster, false))
+                    cancel();
+
                if(difftime >= m_timer)
                    m_timer = 0;
                else

Пока не тестировал, о проблеме доложил Wowka321.


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

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