PDA

Просмотр полной версии : Каст заклинания на ходу


HuntsMan
18.06.2011, 16:48
В клизме добавили возможность кастовать некоторые заклинания на ходу. Наблюдая за клиентом я думаю, что нужно отправить какой-то флаг клиенту в SMSG_CAST_GO чтобы каст у него не прерывался при движении. Кто-нибудь в курсе что это за флаг?

MaxXx2021
18.06.2011, 17:05
В клизме добавили возможность кастовать некоторые заклинания на ходу. Наблюдая за клиентом я думаю, что нужно отправить какой-то флаг клиенту в SMSG_CAST_GO чтобы каст у него не прерывался при движении. Кто-нибудь в курсе что это за флаг?
Да уж открытие они и на вотлк есть. Lord Marrowgar. У него огонь движется по прямой и там идет каст с 0.2с каст таймером. все кастуется при движении. Причем я много встречал спеллов которые кастуются на ходу.

Vladimir
18.06.2011, 17:12
Можно подумать раньше таких спелов не было...

SeT
18.06.2011, 17:17
Некоторые гоблинкие мины всегда можно было кастовать на ходу.

Vladimir
18.06.2011, 20:18
Да у паладина половина спелов таких :)

Rave
18.06.2011, 20:39
К примеру?

HuntsMan
18.06.2011, 21:10
Да уж открытие они и на вотлк есть. Lord Marrowgar. У него огонь движется по прямой и там идет каст с 0.2с каст таймером. все кастуется при движении. Причем я много встречал спеллов которые кастуются на ходу.
Наш спелл посылает при попытке движения CMSG_CANCEL_CAST, поэтому нужно как-то заставить клиент не прерывать каст при движении. Что собственно я и хочу. На сервере продолжать каст 0 проблем, а вот как заставить клиент его не прерывать - это уже сложность.
Некоторые гоблинкие мины всегда можно было кастовать на ходу.
Не встречал таких. Можно конкретно пример?
Да у паладина половина спелов таких
Я не про инстант касты, а про реально кастующиеся спеллы при движении (вы двигаетесь, а полоска каста бежит)
Пример: http://ru.wowhead.com/spell=56641. http://ru.wowhead.com/spell=2948 + http://ru.wowhead.com/spell=86914

Den
18.06.2011, 21:18
К примеру вот, квесты бк:
http://www.wowhead.com/quest=11008
http://www.wowhead.com/quest=11023

Каст идет при движении.

HuntsMan
18.06.2011, 21:51
Как я понял, на ограничения по движению влияет Interrupt Flags (у спеллов предоставленных Den он равен 0, и поэтому клиент нормально кастует). Но например у того же 56641 Interrupt Flags: 0x0000000F. Поэтому клиент будет слать и шлет CMSG_CANCEL_CAST при движении. Я думаю, что нужно какой-то флаг указывать в SMSG_SPELL_GO (меняющий Interrupt Flags у клиента чтоли) чтобы все ок было, но вот вопрос какой?

Есть конечно вариант захакать Spell.dbc у клиента, или забивать на CMSG_CANCEL_CAST при определенных условиях, но сами понимаете что это не тру :)

LordJZ
19.06.2011, 01:35
Возможно это просто modifier? SMSG_SET_FLAT_SPELL_MODIFIER.

HuntsMan
19.06.2011, 02:02
Может быть. Просто смущает следующее:
Caster: (High: Zero (0x000), Counter: 175,292,137)
Target: (High: Zero (0x000), Counter: 175,292,137)
Pending Cast: 22
Spell Id: Автоматическая стрельба (75)
Cast Flags: 0x00040100 262400
TicksCount: 975712495
GO Hit Target 0: (High: Unit (0xF13), Entry: 47659, Counter: 391,911)
TargetFlags: 0x00000002 TARGET_FLAG_UNIT
ObjectTarget: 247

-- Read 42 bytes, have 49

Выделенное присутствует по большей части у нужных спеллов.

Если я правильно понял, SMSG_SET_FLAT_SPELL_MODIFIER позволяет менять только BasePoints, или ещё что-то?

Chameleon
19.06.2011, 04:55
Если вопрос про ауру 330, использующуюся например в Spiritwalker's Grace (http://www.wowhead.com/spell=79206), то я делал так (https://github.com/SkyFire/SkyFireEMU/commit/137caa1ab039d4fbf7a969ecbfd0653a32d271dd).

LordJZ
19.06.2011, 05:13
Если вопрос про ауру 330, использующуюся например в Spiritwalker's Grace (http://www.wowhead.com/spell=79206), то я делал так (https://github.com/SkyFire/SkyFireEMU/commit/137caa1ab039d4fbf7a969ecbfd0653a32d271dd).Т.е. клиент сам при движении под аурой не прерывает чтение заклинания?

Chameleon
19.06.2011, 05:54
Т.е. клиент сам при движении под аурой не прерывает чтение заклинания?
По-моему да, клиент не посылает CMSG_CANCEL_CAST, когда эта аура активна. Но т.к. дело было 3 месяца назад уже точно не помню.

LordJZ
19.06.2011, 08:03
По-моему да, клиент не посылает CMSG_CANCEL_CAST, когда эта аура активна.
...В таком случае тема не имеет смысла

MaS0n
19.06.2011, 09:50
В таком случае тема не имеет смысла
Вобщем-то да

По-моему да, клиент не посылает CMSG_CANCEL_CAST, когда эта аура активна. Но т.к. дело было 3 месяца назад уже точно не помню.

Не по-моему, а точно

void __cdecl Spell_C_CancelCastingSpellByMovement(C_Player * player)

if ( v7 >= v8
&& v7 <= *(&g_spellInterruptsDB + 2)
&& (v9 = *(_DWORD *)(*(&g_spellInterruptsDB + 6) + 4 * (v7 - v8))) != 0
&& *(_BYTE *)(v9 + 20) & 1
&& !(unsigned __int8)CGUnit_C__HasAuraMatchingSpellClass(a1, 330, v6) )
{
Spell_C_CancelSpell(v10, 0, 1, 42);
v1 = s_pendingCasts;
LABEL_4:
++v2;
v11 += 90;
if ( v2 >= v1 )
return;
}
else
{
LABEL_28:
v1 = s_pendingCasts;
++v2;
v11 += 90;
if ( v2 >= s_pendingCasts )
return;
}


Проверяются интерапт флаги, еще что-то в новой dbc, ну и выделено красным - аура 330

HuntsMan
19.06.2011, 10:06
Хм, тогда осталось выловить ауру, которая накладывается на персов для нужных заклинаний. Всем спасибо за помощь в изысканиях :)

Хм, странно, при наличии ауры на плеере (http://ru.wowhead.com/spell=86914 к примеру) клиент все равно шлет CMSG_CANCEL_CAST. Т.е. даже если дело было б в реализации на сервере, клиент поидее все равно не должен был его слать. Что за...

Add: А не, для Верного выстрела работает нормально, вот почему для таланта не хочет(

Easy
15.10.2011, 20:44
Не кто не решил проблему с http://ru.wowhead.com/spell=86914 ?
У этой ауры в отлии от других есть значение misc
Effect 0: Id 6 (SPELL_EFFECT_APPLY_AURA)
BasePoints = 5
Targets (1, 0) (TARGET_SELF, NO_TARGET)
Aura Id 330 (SPELL_AURA_ALLOW_CAST_WHILE_MOVING), value = 6, misc = 12 (12), miscB = 0, periodic = 0
SpellClassMask = 00000000 00000000 00000010
Возможно нужно слать клиенту какой то мод для спела, или ещё что то делать. У кого есть идеи?
Если просто игнорировать опкод отмены каста, то в клиенте визуально пропадает каст, а через время урон наносится жертве.

А может кто нибудь выложить код функции
CGUnit_C__HasAuraMatchingSpellClass
по идеи тут она должна истину вернуть, но возвращает лож.

MaS0n
16.10.2011, 09:30
Выложить можно, но понять его будет сложно, ибо там нет структур и названных переменных

Обычно это проверятся в отладчике напрямую, смотрится где и как идут переходы на выход из функции

Код вот :
База TOM_RUS, 4.2.2.14545


char __thiscall CGUnit_C::HasAuraMatchingSpellClass(void *this, signed int auraEffect, int a3)
{
void *v3; // esi@1
unsigned int v4; // ebx@2
int v5; // edi@3
unsigned int v6; // eax@4
int v7; // ebx@8
int v8; // eax@11
int v9; // edi@13
int v10; // esi@14
int v11; // eax@15
void *v13; // [sp+Ch] [bp-14h]@1
int v14; // [sp+10h] [bp-10h]@14
int v15; // [sp+14h] [bp-Ch]@3
unsigned int v16; // [sp+18h] [bp-8h]@2
unsigned int v17; // [sp+1Ch] [bp-4h]@14

v3 = this;
v13 = this;
if ( !((unsigned __int8)(1 << auraEffect % 8) & *((_BYTE *)this + auraEffect / 8 + 4064))
|| (v4 = 0, v16 = 0, !CGUnit_C::GetAuraCount(this)) )
return 0;
v5 = 0;
v15 = 0;
while ( 1 )
{
v6 = *((_DWORD *)v3 + 932);
if ( v6 == -1 )
v6 = *((_DWORD *)v3 + 773);
if ( v4 >= v6 )
{
v7 = 0;
}
else
{
if ( *((_DWORD *)v3 + 932) == -1 )
v7 = v5 + *((_DWORD *)v3 + 774);
else
v7 = (int)((char *)v3 + v5 + 3088);
}
v8 = *(_DWORD *)(v7 + 8);
if ( v8 < g_SpellDB.minIndex
|| v8 > g_SpellDB.maxIndex
|| (v9 = *((_DWORD *)g_SpellDB.Rows + v8 - g_SpellDB.minIndex)) == 0 )
goto LABEL_21;
v10 = 0;
v14 = SpellGetEffects(*(_DWORD *)v9, &v17);
if ( v17 )
break;
LABEL_20:
v3 = v13;
LABEL_21:
v5 = v15 + 40;
++v16;
v4 = v16;
v15 += 40;
if ( v16 >= CGUnit_C::GetAuraCount(v3) )
return 0;
}
while ( 1 )
{
v11 = *(_DWORD *)(v14 + 8) + 4 * v10;
if ( *(_DWORD *)v11 )
{
if ( *(_DWORD *)(*(_DWORD *)v11 + 12) == auraEffect
&& *(_WORD *)(v7 + 12) & (1 << v10)
&& SpellMatchesAuraSpellClass(a3, v9, v10) )
return 1;
}
++v10;
if ( v10 >= v17 )
goto LABEL_20;
}
}

Easy
16.10.2011, 13:02
мдя... наверное проще всего было бы, если бы кто нибудь смог снифнуть момент вкачивания таланта поджигатель, по любому что то отправляется клиенту, так как с талом этим на ходу клиент не позволяет даже начать каст, серверу не чего не шлётся при кликанье по кнопке. Но на сколько я слышал в данный момент нет возможности снифать офф :(

Lordronn
16.10.2011, 13:17
Нет, я сниффал. Там ничего не шлется как и при касте спелла 75

Easy
16.10.2011, 13:25
хм... ну не может же просто так не работать.
100% клиент блокирует, значит что то должно влиять. Мб аура несколько раз шлётся, мб бп меняются, мб в пакете ауры дополнительная инфа о которой мы не знаем прикреплена.

MaS0n
16.10.2011, 13:57
а другие талы под 330 аурой работают? как выглядит отмена каста? вы бежите, начинаете кастовать, прилетает CMSG_CANCEL_CAST, и все?

Есть 2 вида проверок, одна - срабатывающая при любом изменении движения, т.е хоть на миллиметр сдвинулись, чек идет, вторая проверка при касте

Так вот при первой CMSG_CANCEL_CAST шлется, при 2 пока не обнаружил, там если ауры нету, идут SpellFailed 34, SpellFailed 53

Отладка бы помогла - расставить бряки на Spell_C_CancelSpell и посмотреть call stack, откуда ноги растут

Easy
16.10.2011, 14:16
Вообщем всё что выяснил пока.
Есть аура 330 у ханта (http://pastebin.com/iPnAQLRn) и шамы (http://pastebin.com/Eu2RjZW3)
В сервере просто проверка на 330 ауру, и если она есть, то кастовать можно.
Собственно ссылка на функцию есть выше, на скайфаер.

А есть тал мага (http://pastebin.com/SPFBtkg9) (возможно и лока (http://pastebin.com/GRVMP7V2) тоже, пока не проверял)

Так вот, вкачиваем тал мага и на сервере видит что аура у него 330 и не блочит.

Дальше два варианта, которые говорят о том что клиент блочит:

1) Начинаем кастовать, и потом бежать, приходит опкод CMSG_CANCEL_CAST
Если мы его просто игнорируем, то на сервере каст продолжается, и урон будет нанесён, но визуально в клиенте всё равно обрыв каста.

2) Начинаем бежать, а потом пытаемся начать кастовать - не чего не происходит, в клиенте сообщение "вы не можете этого делать на ходу" а на сервер опкод старта каста даже не приходит.

То что сервер не блочит, легко проверить ещё так:
Начинаем бежать и пишем .cast 2948, и чар начнёт кастовать, так как сервер пошлёт команду старта каста. Но стоит остановится и опять попытаться побежать, как каст прервётся опкодом отмены каста.

Добавлено через 2 минуты

Отладка бы помогла - расставить бряки на Spell_C_CancelSpell и посмотреть call stack, откуда ноги растут

беда в том, что у меня клиент 4.0.6 и у меня нет базы где есть эти функции.

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

Ну что ещё видно, это то что у ханта и шамы бп = 0 для аур 330, а у мага и лока бп != 0

MaS0n
16.10.2011, 14:37
если глянуть на код проверки самой функции, там есть условие при котором возвращается 1


if ( *(_DWORD *)(*(_DWORD *)v11 + 12) == auraEffect
&& *(_WORD *)(v7 + 12) & (1 << v10)
&& SpellMatchesAuraSpellClass(a3, v9, v10) )
return 1;


Первая часть, сверка номера эффекта, вторая проверка какой-то маски, третья - функция SpellMatchesAuraSpellClass и вот там используется новая дбц - SpellClassOption.dbc как-то так, мб там что зарыто, мб value - номер связанный с этой дбц, отладку надо, я могу сказать адрес функции этой и других нужных, но сам проверить не могу увы

Поправка - не misc, а value = basepoints, он же бп

ПС : мб бредово звучит, я посмотрел что за дбц, мб 6 - это spellfamily, попробуйте дать тал и спелл тому классу, у кого спеллфэмили 6, в кате хз кто, в личе был прист

Easy
16.10.2011, 14:53
да, есть запись в дбц для этого спела
9749,0,0x0,0x0,0x0,3,"",

и вот в ядре структура
// SpellClassOptions.dbc
struct SpellClassOptionsEntry
{
uint32 Id; // 0 m_ID
//uint32 modalNextSpell; // 1 m_modalNextSpell not used
flag96 SpellFamilyFlags; // 2-4
uint32 SpellFamilyName; // 5 m_spellClassSet
//DBCString Description; // 6 4.0.0
};

Это видимо как раз строка
Family SPELLFAMILY_MAGE, flag 0x00000000 00000000 00000000

для ожога это
Family SPELLFAMILY_MAGE, flag 0x00000000 00000000 00000010

ну и условие для ауры
SpellClassMask = 00000000 00000000 00000010

То есть тут вроде бы всё в порядке.

Кто может проверить отладкой? Или кинуть ссылочку на мануал как вов отладить под вин 7 х64 :)

У приста тоже отмена каста идёт от клиента.

Кстати. Если нажать правую кнопку мышки, и во время каста влево или вправо, то под талом маг побежит и каст не собьётся, то есть это как раз говорит о том что сервер не блочит.
А клиент в таком случае не шлёт опкод. но если бежать так а потом попытаться кастануть то всё равно не разрешит клиент.

MaS0n
16.10.2011, 15:09
в ПМ загляни, чтоб не флудить тут)

HuntsMan
19.10.2011, 19:54
Распишите и тут что-ли :) Остальным тоже интересна эта проблема

MaS0n
19.10.2011, 21:58
да легко :)

Суть опущу, желающие могут взять и подебажить клиент :)

В функции идет проверка двух значений, одного, который считается из номера эффекта ауры и второго, значения по адресу в какой-то структуре, возможно это клиентская структура Aura. Соотвественно начат был поиск где же устанавливается значение в этот адрес.

Второе значение выставляется/изменяется только в одном месте - в функции, названной близами AuraEffectUpdateMask - внутри клиентской функции OnAuraUpdate, родителем которой является пакет хандлер SMSG_AURA_UPDATE. Там пишется значение в этот адрес, причем расчет аналогичен - по номеру эффекта ауры

Шама и хант, имеют активные эффекты, для них шлется пакет SMSG_AURA_UPDATE, а маг - не имеет, это талант, и пакет для него не шлется

По сути этот пакет для ауры/таланта мага служит активатором, который переводит состояние откл. в состояние вкл.

rsa
21.10.2011, 07:17
Шама и хант, имеют активные эффекты, для них шлется пакет SMSG_AURA_UPDATE, а маг - не имеет, это талант, и пакет для него не шлется

По сути этот пакет для ауры/таланта мага служит активатором, который переводит состояние откл. в состояние вкл.
общий вывод - для пассивных аур тоже необходимо отправлять SMSG_AURA_UPDATE, а текущий метод мангоса, когда обновляются только активные ауры, неверен в принципе?
кул =))) как меня, помнится, за подобное предположение на гетмангосе обо...ли...

HuntsMan
21.10.2011, 11:15
общий вывод - для пассивных аур тоже необходимо отправлять SMSG_AURA_UPDATE, а текущий метод мангоса, когда обновляются только активные ауры, неверен в принципе?
кул =))) как меня, помнится, за подобное предположение на гетмангосе обо...ли...
Там шлются не все, а только определенные. Иначе куева туча талантов была бы в снифах, чего я не наблюдаю.

rsa
21.10.2011, 12:25
Там шлются не все, а только определенные. Иначе куева туча талантов была бы в снифах, чего я не наблюдаю.
даже единственное исключение из правила говорит что это не правило, а д...мо.

SeT
21.10.2011, 13:58
даже единственное исключение из правила говорит что это не правило, а д...мо.
В каждом правиле есть исключение. Правило без исключений - это исключение из правил. :declare:

Laise
22.10.2011, 00:02
а текущий метод мангоса, когда обновляются только активные ауры, неверен в принципе?
в SpellAuraHolder::IsNeedVisibleSlot уже больше года как добавлены отловленные исключения (общего между спеллами пока не найдено, поэтому все и разом добавить не получилось).Ауры типа SPELL_AURA_ALLOW_CAST_WHILE_MOVING может туда же ?

rsa
22.10.2011, 13:52
в SpellAuraHolder::IsNeedVisibleSlot уже больше года как добавлены отловленные исключения
разговор как раз и был после этого добавления (впрочем, точно установить не выйдет, большая часть моих писем на гетмангосе вычищена). я предполагал тогда что ауры надо обновлять и без наличия/требования наличия слота.