Показать сообщение отдельно
Старый 12.05.2010, 14:46   #1
Insider42
Ученый
 
Регистрация: 15.03.2010
Сообщений: 261
Сказал(а) спасибо: 84
Поблагодарили 257 раз(а) в 96 сообщениях
Insider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранитаInsider42 Как самоцвет среди гранита
По умолчанию [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

Последний раз редактировалось Insider42; 12.05.2010 в 16:44.
Insider42 вне форума   Ответить с цитированием