Полная версия этой страницы:
Мод на ХотА
DedMorozzz
30 Dec 2016, 21:18
Честно говоря пока что не понял про определение левела школы. Но массовая версия работает верно.
Вот кстати код отвечающий за снятие бонусов:
Код
.text:004443DF loc_004443DF: ; CODE XREF: combatMonster_ResetSpellFromStack+4Ej
.text:004443DF ; DATA XREF: .text:off_004445C4o
.text:004443DF mov eax, [esi+478h] ; jumptable 0044427E case 3
.text:004443E5 mov ecx, [esi+0C8h]
.text:004443EB mov ebx, [esi+0CCh]
.text:004443F1 sub ecx, eax ; Integer Subtraction
.text:004443F3 mov [esi+0C8h], ecx
.text:004443F9 mov ecx, [esi+84h]
.text:004443FF shr ecx, 6 ; Shift Logical Right
.text:00444402 sub ebx, eax ; Integer Subtraction
.text:00444404 test cl, 1 ; Logical Compare
.text:00444407 mov [esi+0CCh], ebx
.text:0044440D jnz loc_004444E1 ; default
.text:0044440D ; jumptable 0044427E cases 2,4-7,10-14,16-26,29
.text:00444413 sub [esi+0C4h], eax ; Integer Subtraction
.text:00444419 jmp loc_004444E1 ; default
Но я не до конца разобрался на какие адресса лоу хуки ставить... этот - 004443F1? Т.е. адерес после всех переменных
AlexSpl
30 Dec 2016, 21:30
* * *
LoHook на 44490Ah.
В контексте хука c->ecx - указатель (адрес) на героя. Соответственно, скиллы доступны. с->edi - бонус Молитвы.
Т.е. задаём бонусы Молитвы:
Код
{
if ( *(char*)(c->ecx + 201 + оффсет_школы_воды) == _уровень_ ) bonus = _такой-то_; // здесь идея, а не реализация )
c->edi = bonus;
return EXEC_DEFAULT;
}
LoHook на 44490Ah.
DedMorozzz
30 Dec 2016, 21:32
Цитата(AlexSpl @ 30 Dec 2016, 20:30)

* * *
LoHook на 44490Ah.
В контексте хука c->ecx - указатель (адрес) на героя. Соответственно, скиллы доступны. с->edi - бонус Молитвы.
Т.е. задаём бонусы Молитвы:
Код
{
if ( *(char*)(c->ecx + 201 + оффсет_школы_воды) == _уровень_ ) bonus = _такой-то_; // здесь идея, а не реализация )
c->edi = bonus;
return EXEC_DEFAULT;
}
LoHook на 44490Ah.
ну... если герой есть, тогда да, не вопрос как взять школу, то я уже поспешил. Даже из комбат менеджера можно было бы взять
AlexSpl
30 Dec 2016, 21:38
Но c->edi - это бонус сразу к атаке, защите и скорости. Если нужно дифференцировать бонусы, то придётся повозиться немного.
В любом случае, весь код, который добавляет бонусы Молитвы здесь:
Код
.text:00444907 loc_444907:
.text:00444907
.text:00444907 mov ecx, [ebp+arg_C]
.text:0044490A mov [esi+478h], edi
.text:00444910 test ecx, ecx
.text:00444912 jz short loc_444928
.text:00444914 mov edx, [esi+78h]
.text:00444917 mov eax, [ebp+arg_0]
.text:0044491A push edi
.text:0044491B push edx
.text:0044491C push eax
.text:0044491D call sub_4E6260
.text:00444922 add [esi+478h], eax
.text:00444928
.text:00444928 loc_444928:
.text:00444928 mov eax, [esi+478h]
.text:0044492E mov ecx, [esi+0C8h]
.text:00444934 mov ebx, [esi+0CCh]
.text:0044493A add ecx, eax
.text:0044493C mov [esi+0C8h], ecx
.text:00444942 mov ecx, [esi+84h]
.text:00444948 shr ecx, 6
.text:0044494B add ebx, eax
.text:0044494D test cl, 1
.text:00444950 mov [esi+0CCh], ebx
.text:00444956 jnz loc_444D5C
.text:0044495C add [esi+0C4h], eax
.text:00444962 jmp loc_444D5C
DedMorozzz
30 Dec 2016, 21:53
Пока что так получилось:
Код
int __stdcall spellPray(LoHook* h, HookContext* c)
{
c->ecx += 2;
c->ebx += 2;
return EXEC_DEFAULT;
}
int __stdcall spellPrayEnd(LoHook* h, HookContext* c)
{
c->ecx -= 2;
c->ebx -= 2;
return EXEC_DEFAULT;
}
Код
_PI->WriteLoHook(0x44493C, spellPray);
_PI->WriteLoHook(0x4443F1, spellPrayEnd);
Вроде работает
PS:
А вот и смещения для благо:
//_int_ damage_min; //+208 0xD0
//_int_ damage_max; //+212 0xD4
-----------
хм... не пойму пока как сделать благо
Как оно работает- все атаки наносят максимальный урон. Если улучшеное и выше, то макс. урон +1.
т.е. урон 4-7, после улучшеного блага всегда 8
Соотв. Как сделать благо - понятно, а как вернуть?)
AlexSpl
30 Dec 2016, 21:59
Да, так должно работать. Метод есть. Дерзайте )
Цитата
хм... не пойму пока как сделать благо
У отряда есть поле, где хранится инфа о всех висящих на нём заклах. Попробуйте найти его и в коде для Молитвы добавить Bless. Хотя тогда в инфе об отряде Bless видно будет.
Есть ещё поля мин. урон и макс. урон - их изменить будет проще и правильнее. Если, конечно, не нужны фишки Bless типа +1 урону. Но и это реализовать можно, если проверять навык воды.
DedMorozzz
30 Dec 2016, 22:06
Цитата(AlexSpl @ 30 Dec 2016, 20:59)

Цитата
хм... не пойму пока как сделать благо
У отряда есть поле, где хранится инфа о всех висящих на нём заклах. Попробуйте найти его и в коде для Молитвы добавить Bless. Хотя тогда в инфе об отряде Bless видно будет.
Есть ещё поля мин. урон и макс. урон - их изменить будет проще и правильнее. Если, конечно, не нужны фишки Bless типа +1 урону.
Я ж выше написал. Даже +1 сделать не проблема
Вопрос в том как это вернуть после окончания действия
Ибо значения переписаны, я не знаю на сколько изменилось оно. Ибо может и не изменится вовсе (аля ангел). А может сильно (гидра 25-45 урон)
После блесса получится "46" и минимальный и максимальный. Максимальный какой понятно. Если улучшеный и выше - тогда текущий максимальный -1
А вот как минимальный получить?
AlexSpl
30 Dec 2016, 22:11
На отряде и другие модификаторы атаки/защиты висеть могут. Тогда либо вешать одновременно с Mолитвой Блесс. Либо искать код, который считает урон и изменять условие:
if ( spell == Bless ) на if ( (spell == Bless) || (spell == Prayer) )
По опыту исследования кода Героев 2 скажу, что, вероятнее всего, игра так и делает. Т.е. не модифицирует мин. и макс. урон, а именно проверяет, висит ли Bless, и просто использует изменённые значения при расчёте урона или если требуется в окошке урон показать.
DedMorozzz
30 Dec 2016, 22:32
Цитата(AlexSpl @ 30 Dec 2016, 21:11)

На отряде и другие модификаторы атаки/защиты висеть могут. Тогда либо вешать одновременно с Mолитвой Блесс. Либо искать код, который считает урон и изменять условие:
if ( spell == Bless ) на if ( (spell == Bless) || (spell == Prayer) )
По опыту исследования кода Героев 2 скажу, что, вероятнее всего, игра так и делает. Т.е. не модифицирует мин. и макс. урон, а именно проверяет, висит ли Bless, и просто использует изменённые значения при расчёте урона или если требуется в окошке урон показать.
попробую найти где ставится статус заклинаний. И добавить туда благо
Есть ещё, на крайняк идея - найти пустое место и туда записать минимальный урон каждого юнита. Всего надо 42 значения. По 21 на каждую сторону
Во время каста молитвы - это поля предварительно очищать. А когда отрабатывает код завершение бонусов молитвы - из этого места брать оригиналы минимального урона
Но это слишком сложное и муторное решение
Или вариант 3: по анналогии со скоростью. Есть скорость а есть модификатор скорости.
Может так же существует минимальный урон и модификатор миниального урона. Но в базе Феанора этого не нашел. Да и модификатора скорости тоже

Его как-то Игрик писал
AlexSpl
30 Dec 2016, 22:34
А хедерах нет описания структуры стека? Счас посмотрю.
Не, куда-то я их засунул, теперь не помню куда. Можно скачать на WoG-форуме.
DedMorozzz
30 Dec 2016, 22:44
Кого скачать? Хедеры к монстрам?
AlexSpl
30 Dec 2016, 22:55
Короче, вот тут раздают минимальные и максимальные уроны: loc_442EC7.
DedMorozzz
30 Dec 2016, 23:09
Цитата(AlexSpl @ 30 Dec 2016, 21:55)

Короче, вот тут раздают минимальные и максимальные уроны: loc_442EC7.
Код
.text:00442EC7 loc_00442EC7: ; CODE XREF: combatMonster_RandomizeBasicDamage+3Fj
.text:00442EC7 mov eax, [ecx+34h]
.text:00442ECA push ebx
.text:00442ECB push esi
.text:00442ECC cmp eax, 92h ; Compare Two Operands
.text:00442ED1 push edi
.text:00442ED2 jnz loc_00442F58 ; Jump if Not Zero (ZF=0)
.text:00442ED8 mov eax, [ecx+288h]
.text:00442EDE test eax, eax ; Logical Compare
.text:00442EE0 jz short loc_00442EF1 ; Jump if Zero (ZF=1)
.text:00442EE2 mov esi, [ecx+0F4h]
.text:00442EE8 mov eax, 1
.text:00442EED sub eax, esi ; Integer Subtraction
.text:00442EEF jmp short loc_00442EF7 ; Jump
Делаю так:
Код
int __stdcall spellPrayBonus(LoHook* h, HookContext* c)
{
//c->ebx += 300;
c->eax += 300;
return EXEC_DEFAULT;
}
Хуку сюда
Код
_PI->WriteLoHook(0x442ED8, spellPrayBonus);
Не меняется урон
AlexSpl
30 Dec 2016, 23:10
442F64h - проверка на Bless.
Код
.text:00442F6C jz short loc_442F84
.text:00442F6E mov ecx, [ecx+458h]
.text:00442F74 pop edi
.text:00442F75 add ecx, ebx
.text:00442F77 pop esi
.text:00442F78 imul ecx, edx; здесь максимальный урон умножается на кол-во
.text:00442F7B mov eax, ecx
.text:00442F7D pop ebx
.text:00442F7E mov esp, ebp
.text:00442F80 pop ebp
.text:00442F81 retn 4
DedMorozzz
30 Dec 2016, 23:18
Мне кажется всё равно надо будет найти статус у моба. Какие спелы висят. Ибо если по ним логика считается, то это будет проще
более того я в дальнейшем планирую "волшебное зеркало" вешать на эксперте воздуха на всех. Я думаю там так же, провесить всем своим юнитам статус и всё...
PS: а не, всё равно... даже найду условный адрес АААА для где вешается статус. ИХ же несколько может быть. Соотв. это какой-то массив. В общем пока не понятно как этим управлять
AlexSpl
30 Dec 2016, 23:58
Походу, c->ecx - указатель на стек, а *(int*)(c->ecx + 0x23C) - флаг заклинания (висит = 1, нет = 0).
Тогда хук на 442F6Ah.
Код
{
c->eax = 0; // наличие закла: 0 - нет, 1 есть; нужно для test eax, eax
if ( *(int*)(c->ecx + 0x23C) != 0 ) c->eax = 1; // проверяем Bless
if ( *(int*)(c->ecx + offset_prayer) != 0 ) c->eax = 1; // проверяем Prayer
return EXEC_DEFAULT;
}
UPD Обновил. Осталось подставить offset_prayer.
Можно проще, т.к. Bless уже проверили до хука:
Код
{
if ( *(int*)(c->ecx + offset_prayer) != 0 ) c->eax = 1; // проверяем Prayer
return EXEC_DEFAULT;
}
Если тупо взять:
41 Bless
48 Prayer
То offset_prayer = 0x23C + (48 - 41) = 0x243.
Попробуйте )
* * *
Хотя ведь и длительность закла должна где-то храниться. В любом случае, нужен оффсет Prayer, если идея верная.
* * *
UPD2 Вроде как разобрался.
*(int*)(c->ecx + 0x23C) - это не флаг, а длительность заклинания, во-первых.
Во-вторых, оффсет Prayer = 0x23C + (48 - 41) * 4 (инт же) =
0x258.
Финальный код:
Код
{
if ( *(int*)(c->ecx + 0x258) != 0 ) c->eax = 1; // проверяем Prayer
return EXEC_DEFAULT;
LoHook на 442F6Ah.
DedMorozzz
31 Dec 2016, 00:08
Работает! Пишется что урон с разбросом. Но по факту наносит всегда максимальный
AlexSpl
31 Dec 2016, 00:11
В окне стека так и должно ведь быть? Нет?
А что в статусной строке при включённой опции "Показывать всё" или как-то так.
Ещё неплохо бы проверить зависимость от уровня школы воды. Возможно, ещё бонус +458h учесть нужно, если он автоматом не учёлся.
DedMorozzz
31 Dec 2016, 00:15
Цитата(AlexSpl @ 30 Dec 2016, 23:11)

В окне стека так и должно ведь быть? Нет?
А что в статусной строке при включённой опции "Показывать всё" или как-то так.
Ещё неплохо бы проверить зависимость от уровня школы воды. Возможно, ещё бонус +458h учесть нужно, если он автоматом не учёлся.
В статусе стека блага нету. И +1 урона с улучшенной водой не наносится
Так же если кастануть благо, то снизу будет писаться урон без разброса. Сейчас он по факту без разброса, но пишется с ним
AlexSpl
31 Dec 2016, 00:21
Цитата
В статусе стека блага нету.
Ну блага и не будет, мы же не вешаем Благо. А разброс уронов - так и должно быть. Счас кастанул Bless с экпертной водой на горгулий. Урон пишется 2-3.
В статусной строке тоже писаться должен урон фиксированный при наведении курсора на отряд противника.
Цитата
И +1 урона с улучшенной водой не наносится
А это, видимо, и есть универсальный бонус +458h )
DedMorozzz
31 Dec 2016, 00:25
Цитата(AlexSpl @ 30 Dec 2016, 23:21)

Цитата
В статусе стека блага нету.
Ну блага и не будет, мы же не вешаем Благо. А разброс уронов - так и должно быть. Счас кастанул Bless с экпертной водой на горгулий. Урон пишется 2-3.
В статусной строке тоже писаться должен урон фиксированный при наведении курсора на отряд противника.
Цитата
И +1 урона с улучшенной водой не наносится
А это, видимо, и есть универсальный бонус +458h )
Вот с низу урон пишется с разбросом (в статусной строке, там где лог боя)
Как бонус добавить +458h?
Если я правильно понимаю, то сейчас просто включаем благо, если есть молитва. Куда бонус приписать?
И ещё момент - как получить тип юнита? Т.е. сейчас андеды получают бонус блага, хотя не должны
AlexSpl
31 Dec 2016, 00:35
Есть два пути: вешать Bless в дополнение к Prayer, но это неправильно, т.к. один закл будет вешать сразу два. Другой - полностью переделать логику. Тип юнита там же, в c-ecx: *(int*)(c->ecx+ 0x34). Но есть более правильный способ: маска. С помощью неё андедов сразу отличить можно.
Цитата
Как бонус добавить +458h?
Да просто прописать его в касте. Там где бонусы Молитвы меняли.
* * *
Хотя +1 макс. урону может и не он добавляет. Так что сначала с андедами разобраться нужно.
Ан нет, он родимый ) вот тут:
Код
.text:00442F6E mov ecx, [ecx+458h]
.text:00442F74 pop edi
.text:00442F75 add ecx, ebx
.text:00442F77 pop esi
.text:00442F78 imul ecx, edx
.text:00442F7B mov eax, ecx
.text:00442F7D pop ebx
.text:00442F7E mov esp, ebp
.text:00442F80 pop ebp
.text:00442F81 retn 4
Так что в касте при наличии у героя экспертной воды, ставим этот бонус в 1. Только осторожно: для Молитвы свой бонус.
DedMorozzz
31 Dec 2016, 00:45
Для молитвы добавил так:
Код
c->eax = 1;
Ибо код вот:
Код
.text:00444928 mov eax, [esi+478h]
.text:0044492E mov ecx, [esi+0C8h]
.text:00444934 mov ebx, [esi+0CCh]
Не завелось. Я так понимаю что универсальный бонус как раз для молитвы дал
AlexSpl
31 Dec 2016, 00:49
Нужно в этом хуке добавлять для Bless, так как бонус для Молитвы уже не нужен.
Например, так:
Код
int __stdcall spellPray(LoHook* h, HookContext* c)
{
c->ecx += 2;
c->ebx += 2;
int heroOffset = *(int*)(c->ebp + 20);
if ( *(char*)(heroOffset + 201 + 16) > 1 ) *(int*)(c->esi + 0x458) = 1;
return EXEC_DEFAULT;
}
DedMorozzz
31 Dec 2016, 01:03
Да, работает. Тестовый код такой:
Код
int __stdcall spellPray(LoHook* h, HookContext* c)
{
int cmAddr = *(int*)0x699420;
char waterLevel = *(char*)(*(int*)(cmAddr + 0x53CC) + 201 + 16);
if (waterLevel > 1) {
c->ecx -= 4;
c->ebx -= 4;
*(int*)(c->esi + 0x458) = 1;
} else {
c->ecx -= 2;
c->ebx -= 2;
}
return EXEC_DEFAULT;
}
Фактический такой:
Код
int __stdcall spellPray(LoHook* h, HookContext* c)
{
c->ecx += 2;
c->ebx += 2;
int cmAddr = *(int*)0x699420;
char waterLevel = *(char*)(*(int*)(cmAddr + 0x53CC) + 201 + 16);
if (waterLevel > 1) {
*(int*)(c->esi + 0x458) = 1;
}
return EXEC_DEFAULT;
}
Тестовый нужен для того, что бы понять что наносится не усиленный урон. Для этого убираю бонус к статам для молитвы
AlexSpl
31 Dec 2016, 01:05
Опередили ) Можно героя и через combatManager получать, конечно.
DedMorozzz
31 Dec 2016, 01:07
Через комбат менеджер более универсально получается. Всегда одинаково и не надо гадать "как же в этом случае получить героя..."
Да и вообще в дальнейшем сделаю ф-ю "getHeroOffset" которая по комбат менеджеру всегда оффсет героя вернёт
AlexSpl
31 Dec 2016, 01:11
Ага, поправил уровень Water Magic.
Идеально, когда с оффсетами разберётесь, ибо это очень полезный скилл - находить их и понимать, подключайте хедер homm3.h и работайте прямо со структурами.
DedMorozzz
31 Dec 2016, 01:12
Цитата
Тип юнита там же, в c-ecx: *(int*)(c->ecx+ 0x34). Но есть более правильный способ: маска. С помощью неё андедов сразу отличить можно.
Я так понимаю как-то так:
Код
if (*(int*)(c->ecx+ 0x34) == 262144) {//не вешаем благо
Где 262144 взял из "флаги существ", в erm-helper
AlexSpl
31 Dec 2016, 01:16
Не, не то. Почему благо не работает на андедах в первую очередь? Потому что при касте не устанавливается *(int*)(c->ecx + 0x23C). Нужно посмотреть, как работает каст Bless. Оттуда уже можно взять правильный код.
DedMorozzz
31 Dec 2016, 01:20
А смысл пытаться сделать так же, как и при касте блесса, когда можно просто в проверку активации блага (наличие молитвы) добавить и проверку на тип существа
AlexSpl
31 Dec 2016, 01:21
А проще посмотреть в хедерах: должно быть поле, по которому сразу можно определить: undead или нет.
DedMorozzz
31 Dec 2016, 01:23
в смысле есть отдельное поле "isUndead"? И где эти хедеры смотреть?
AlexSpl
31 Dec 2016, 01:25
homm3.h. Там, по идее, должна быть описана структура стека.
DedMorozzz
31 Dec 2016, 01:31
такое есть:
NOALIGN struct _BattleStack_ : _Struct_ // размер 0x548
{
....
_int32_ creature_id; // +52 0x34 // тип монстра
AlexSpl
31 Dec 2016, 01:34
Попробуйте так проверять:
Код
if ( *(int*)(c->reg + 0x105) & 0x40000 )
c->reg - указатель на стек.
Цитата
такое есть:
NOALIGN struct _BattleStack_ : _Struct_ // размер 0x548
{
....
_int32_ creature_id; // +52 0x34 // тип монстра
Вот. А что там по смещению 0x105?
Поправил. Это ж битовое поле.
DedMorozzz
31 Dec 2016, 01:40
Цитата(AlexSpl @ 31 Dec 2016, 00:34)

Вот. А что там по смещению 0x105?
0x105 не нашло. А +261 (dec) только для героя инфа
AlexSpl
31 Dec 2016, 01:49
Странно. В erm точно про undead шла речь? Если да, то см. мой пост выше. Проверка такая
if ( *(int*)(c->reg + 0x105) & 0x40000 ) {
_значит_undead_
}
c->reg - это c->esi в нашем случае.
Сорри, контекст )
Код
{
if ( (*(int*)(c->ecx + 0x258) != 0) && (!(*(int*)(c->ecx + 0x105) & 0x40000)) ) c->eax = 1; // проверяем Prayer и андедов
return EXEC_DEFAULT;
}
DedMorozzz
31 Dec 2016, 01:50
Цитата(AlexSpl @ 31 Dec 2016, 00:49)

Странно. В erm точно про undead шла речь? Если да, то см. мой пост выше. Проверка такая
if ( *(int*)(c->reg + 0x105) & 0x40000 ) {
_значит_undead_
}
c->reg - это c->esi в нашем случае.
Сорри, контекст )
Код
{
if ( (*(int*)(c->ecx + 0x258) != 0) && ( !(*(int*)(c->reg + 0x105) & 0x40000) ) c->eax = 1; // проверяем Prayer и андедов
return EXEC_DEFAULT;
}
ecx только, а не esi
Код
if ( *(int*)(c->ecx + 0x105) & 0x40000 ) {
c->eax = 1;
}
Вот так завелось
Вот из ERM:
Цитата
262144 Нежить (все существа Некрополиса, существо с этим флагом не имеет морали, получает урон от заклинания Уничтожить нежить и не несет урона от Волны смерти)
AlexSpl
31 Dec 2016, 01:56
Ага. Лучше на два if разбить. Я запарился со скобками )
*(int*)(c->ecx + 0x105) & 0x40000, похоже возвращает, живой ли стек. Но это не важно. Если работает, значит, правильно.
DedMorozzz
31 Dec 2016, 01:58
Цитата(AlexSpl @ 31 Dec 2016, 00:56)

Ага. Лучше на два if разбить. Я запарился со скобками )
*(int*)(c->ecx + 0x105) & 0x40000, похоже возвращает, живой ли стек. Но это не важно. Если работает, значит, правильно.
не, не работает))
Не работает не на ком. Т.е. андеды не получают блага. Живые тоже)
AlexSpl
31 Dec 2016, 02:01
А так?
Код
{
if ( ( *(int*)(c->ecx + 0x258) != 0 ) && !( *(int*)(c->ecx + 0x105) & 0x40000 ) ) c->eax = 1; // проверяем Prayer и андедов
return EXEC_DEFAULT;
}
DedMorozzz
31 Dec 2016, 02:09
Цитата(AlexSpl @ 31 Dec 2016, 01:01)

А так?
Код
{
if ( ( *(int*)(c->ecx + 0x258) != 0 ) && !( *(int*)(c->ecx + 0x105) & 0x40000 ) ) c->eax = 1; // проверяем Prayer и андедов
return EXEC_DEFAULT;
}
так на всех работает. И на андедов тоже
PS: ладно, завтра уже поковыряю ещё

Жена ругается
AlexSpl
31 Dec 2016, 02:16
Реально ничего нет в структуре стека по смещению 0x105 = 261? Наверное, не тот оффсет. Или не та маска.
AlexSpl
31 Dec 2016, 04:15
Короче, перехватил наведение курсора на отряд при касте Bless. Маска правильная - 40000h, смещение - нет.
Правильный код (ввёл дополнительные переменные, чтобы было понятнее):
Код
{
// Работает независимо от Bless
int spellDuration = *(int*)(c->ecx + 0x258); // Prayer
bool isUndead = *(int*)(c->ecx + 0x84) & 0x40000;
if ( ( spellDuration != 0 ) && !isUndead ) c->eax = 1; // проверяем Prayer и бит Undead
return EXEC_DEFAULT;
}
AlexSpl
31 Dec 2016, 04:48
Технические подробности:
loc_44A333 - проверка бита Undead при касте Bless.
sub_5A83A0 - функция, которая решает, разрешён ли каст: 1.0 - да, 0.0 - нет
DedMorozzz
31 Dec 2016, 14:04
Спасибо, работает
Что такое 0x40000 я понял, это проверка на андеда
Код
.text:0044A333 test edx, 40000h ; Undead ?
А что такое 0x258 и 0x84 нет. По логике это смещение для каста молитвы и благо, но открыв код молитвы там таких значений нету
Более того в файлах *.h таких смещений тоже не нашел
Вот кстати и +1 урона для благо:
_int32_ bless_value; // +1112 0x458 Bless добавка к Max. Damage
PS: а вот это походу нужно для правильного предварительного расчёта урона, но не уверен:
Код
.text:00443C60; int __thiscall combatMonster_CalculateDamageToMonster
PPS: да, эта функа отвечает за возвращаемые цифры урона при наведении. Проверил дебагом
AlexSpl
31 Dec 2016, 14:47
Цитата
Вот кстати и +1 урона для благо:
_int32_ bless_value; // +1112 0x458 Bless добавка к Max. Damage
Не только для Bless. Это универсальный бонус для заклинаний.
Цитата
А что такое 0x258 и 0x84 нет. По логике это смещение для каста молитвы и благо, но открыв код молитвы там таких значений нету
Более того в файлах *.h таких смещений тоже не нашел
258h - смещение поля (int), где хранится длительность заклинания (оставшаяся). 84h - это флаги существа в структуре отряда на поле боя (стека).
DedMorozzz
31 Dec 2016, 14:51
Цитата(AlexSpl @ 31 Dec 2016, 13:47)

84h - это флаги существа в структуре отряда на поле боя (стека).
Т.е. грубо говоря эта запись:
Код
bool isUndead = *(int*)(c->ecx + 0x84) & 0x40000;
эквивалентна этой:
Код
bool isUndead = if(*(int*)(c->ecx + 0x84) == 0x40000);
?
AlexSpl
31 Dec 2016, 15:06
Нет, не эквивалентна. У существа есть свойства: летает, двухгексовый, undead и т.п. Флаги - это битовое поле int (32 бита) по смещению 0x84, где каждое свойство отряда хранится в одном бите: 0 - отсутствие свойства, 1 - присутствие свойства (обычно).
*(int*)(c->ecx + 0x84) = xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxxb (32 бита)
40000h (маска) = 1000000000000000000b = 00000000 00000
100 00000000 00000000 (1 в этой позиции - свойство undead).
Для проверки используется битовое И (&):
Код
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx // флаги
&&&&&&&& &&&&&&&& &&&&&&&& &&&&&&&&
00000000 00000100 00000000 00000000 // маска
======== ======== ======== ========
00000000 00000y00 00000000 00000000
Где y = x & 1 = 1 в том и только в том случае, если x = 1.
Вот пример флагов для чёрного рыцаря:
00000000 00000110 00000100 00000001
Код
00000000 00000110 00000100 00000001 // флаги *(int*)(c->ecx + 0x84)
&&&&&&&& &&&&&&&& &&&&&&&& &&&&&&&&
00000000 00000100 00000000 00000000 // маска 40000h
======== ======== ======== ========
00000000 00000100 00000000 00000000 // результат: *(int*)(c->ecx + 0x84) & 0x40000
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.