Insider42
12.05.2010, 14:46
Достаточно давно роги (они же Разбойники) (и друиды тоже) стали жаловаться, что при уходе, например в "ванишу" (оно же Исчезновение), в них всё равно прилетает спел, если он наносит урон моментально. В итоге с помощью Чародейской вспышки или Чародейских стрел (особенно любимый магами спел для того чтобы мучать разбойников.
В данный момент стот ревизия 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.GetR awValue())));
}
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
В данный момент стот ревизия 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.GetR awValue())));
}
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