Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Мод на ХотА
DF2 :: ФОРУМЫ > Игровые форумы > Heroes of Might & Magic III > Моды
Страницы: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
DedMorozzz
Честно говоря пока что не понял про определение левела школы. Но массовая версия работает верно.

Вот кстати код отвечающий за снятие бонусов:
Код
.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
* * *
LoHook на 44490Ah.

В контексте хука c->ecx - указатель (адрес) на героя. Соответственно, скиллы доступны. с->edi - бонус Молитвы.

Т.е. задаём бонусы Молитвы:

Код
{
    if ( *(char*)(c->ecx + 201 + оффсет_школы_воды) == _уровень_ ) bonus = _такой-то_; // здесь идея, а не реализация )
    c->edi =  bonus;
    return EXEC_DEFAULT;
}


LoHook на 44490Ah.
DedMorozzz
Цитата(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
Но c->edi - это бонус сразу к атаке, защите и скорости. Если нужно дифференцировать бонусы, то придётся повозиться немного.

В любом случае, весь код, который добавляет бонусы Молитвы здесь:

DedMorozzz
Пока что так получилось:
Код
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
Да, так должно работать. Метод есть. Дерзайте )

Цитата
хм... не пойму пока как сделать благо

У отряда есть поле, где хранится инфа о всех висящих на нём заклах. Попробуйте найти его и в коде для Молитвы добавить Bless. Хотя тогда в инфе об отряде Bless видно будет.

Есть ещё поля мин. урон и макс. урон - их изменить будет проще и правильнее. Если, конечно, не нужны фишки Bless типа +1 урону. Но и это реализовать можно, если проверять навык воды.
DedMorozzz
Цитата(AlexSpl @ 30 Dec 2016, 20:59) *
Цитата
хм... не пойму пока как сделать благо

У отряда есть поле, где хранится инфа о всех висящих на нём заклах. Попробуйте найти его и в коде для Молитвы добавить Bless. Хотя тогда в инфе об отряде Bless видно будет.

Есть ещё поля мин. урон и макс. урон - их изменить будет проще и правильнее. Если, конечно, не нужны фишки Bless типа +1 урону.

Я ж выше написал. Даже +1 сделать не проблема
Вопрос в том как это вернуть после окончания действия
Ибо значения переписаны, я не знаю на сколько изменилось оно. Ибо может и не изменится вовсе (аля ангел). А может сильно (гидра 25-45 урон)

После блесса получится "46" и минимальный и максимальный. Максимальный какой понятно. Если улучшеный и выше - тогда текущий максимальный -1
А вот как минимальный получить?
AlexSpl
На отряде и другие модификаторы атаки/защиты висеть могут. Тогда либо вешать одновременно с Mолитвой Блесс. Либо искать код, который считает урон и изменять условие:

if ( spell == Bless ) на if ( (spell == Bless) || (spell == Prayer) )

По опыту исследования кода Героев 2 скажу, что, вероятнее всего, игра так и делает. Т.е. не модифицирует мин. и макс. урон, а именно проверяет, висит ли Bless, и просто использует изменённые значения при расчёте урона или если требуется в окошке урон показать.
DedMorozzz
Цитата(AlexSpl @ 30 Dec 2016, 21:11) *
На отряде и другие модификаторы атаки/защиты висеть могут. Тогда либо вешать одновременно с Mолитвой Блесс. Либо искать код, который считает урон и изменять условие:

if ( spell == Bless ) на if ( (spell == Bless) || (spell == Prayer) )

По опыту исследования кода Героев 2 скажу, что, вероятнее всего, игра так и делает. Т.е. не модифицирует мин. и макс. урон, а именно проверяет, висит ли Bless, и просто использует изменённые значения при расчёте урона или если требуется в окошке урон показать.

попробую найти где ставится статус заклинаний. И добавить туда благо

Есть ещё, на крайняк идея - найти пустое место и туда записать минимальный урон каждого юнита. Всего надо 42 значения. По 21 на каждую сторону
Во время каста молитвы - это поля предварительно очищать. А когда отрабатывает код завершение бонусов молитвы - из этого места брать оригиналы минимального урона
Но это слишком сложное и муторное решение

Или вариант 3: по анналогии со скоростью. Есть скорость а есть модификатор скорости.
Может так же существует минимальный урон и модификатор миниального урона. Но в базе Феанора этого не нашел. Да и модификатора скорости тоже smile.gif Его как-то Игрик писал
AlexSpl
А хедерах нет описания структуры стека? Счас посмотрю.

Не, куда-то я их засунул, теперь не помню куда. Можно скачать на WoG-форуме.
DedMorozzz
Кого скачать? Хедеры к монстрам?
AlexSpl
Короче, вот тут раздают минимальные и максимальные уроны: loc_442EC7.
DedMorozzz
Цитата(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
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
Мне кажется всё равно надо будет найти статус у моба. Какие спелы висят. Ибо если по ним логика считается, то это будет проще
более того я в дальнейшем планирую "волшебное зеркало" вешать на эксперте воздуха на всех. Я думаю там так же, провесить всем своим юнитам статус и всё...

PS: а не, всё равно... даже найду условный адрес АААА для где вешается статус. ИХ же несколько может быть. Соотв. это какой-то массив. В общем пока не понятно как этим управлять smile.gif
AlexSpl
Походу, 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
Работает! Пишется что урон с разбросом. Но по факту наносит всегда максимальный
AlexSpl
В окне стека так и должно ведь быть? Нет?

А что в статусной строке при включённой опции "Показывать всё" или как-то так.

Ещё неплохо бы проверить зависимость от уровня школы воды. Возможно, ещё бонус +458h учесть нужно, если он автоматом не учёлся.
DedMorozzz
Цитата(AlexSpl @ 30 Dec 2016, 23:11) *
В окне стека так и должно ведь быть? Нет?

А что в статусной строке при включённой опции "Показывать всё" или как-то так.

Ещё неплохо бы проверить зависимость от уровня школы воды. Возможно, ещё бонус +458h учесть нужно, если он автоматом не учёлся.

В статусе стека блага нету. И +1 урона с улучшенной водой не наносится

Так же если кастануть благо, то снизу будет писаться урон без разброса. Сейчас он по факту без разброса, но пишется с ним
AlexSpl
Цитата
В статусе стека блага нету.

Ну блага и не будет, мы же не вешаем Благо. А разброс уронов - так и должно быть. Счас кастанул Bless с экпертной водой на горгулий. Урон пишется 2-3.

В статусной строке тоже писаться должен урон фиксированный при наведении курсора на отряд противника.

Цитата
И +1 урона с улучшенной водой не наносится

А это, видимо, и есть универсальный бонус +458h )
DedMorozzz
Цитата(AlexSpl @ 30 Dec 2016, 23:21) *
Цитата
В статусе стека блага нету.

Ну блага и не будет, мы же не вешаем Благо. А разброс уронов - так и должно быть. Счас кастанул Bless с экпертной водой на горгулий. Урон пишется 2-3.

В статусной строке тоже писаться должен урон фиксированный при наведении курсора на отряд противника.

Цитата
И +1 урона с улучшенной водой не наносится

А это, видимо, и есть универсальный бонус +458h )

Вот с низу урон пишется с разбросом (в статусной строке, там где лог боя)
Как бонус добавить +458h?
Если я правильно понимаю, то сейчас просто включаем благо, если есть молитва. Куда бонус приписать?

И ещё момент - как получить тип юнита? Т.е. сейчас андеды получают бонус блага, хотя не должны
AlexSpl
Есть два пути: вешать 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
Для молитвы добавил так:
Код
c->eax = 1;


Ибо код вот:
Код
.text:00444928                     mov     eax, [esi+478h]
.text:0044492E                     mov     ecx, [esi+0C8h]
.text:00444934                     mov     ebx, [esi+0CCh]

Не завелось. Я так понимаю что универсальный бонус как раз для молитвы дал
AlexSpl
Нужно в этом хуке добавлять для 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
Да, работает. Тестовый код такой:
Код
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
Опередили ) Можно героя и через combatManager получать, конечно.
DedMorozzz
Через комбат менеджер более универсально получается. Всегда одинаково и не надо гадать "как же в этом случае получить героя..."
Да и вообще в дальнейшем сделаю ф-ю "getHeroOffset" которая по комбат менеджеру всегда оффсет героя вернёт
AlexSpl
Ага, поправил уровень Water Magic.

Идеально, когда с оффсетами разберётесь, ибо это очень полезный скилл - находить их и понимать, подключайте хедер homm3.h и работайте прямо со структурами.
DedMorozzz
Цитата
Тип юнита там же, в c-ecx: *(int*)(c->ecx+ 0x34). Но есть более правильный способ: маска. С помощью неё андедов сразу отличить можно.


Я так понимаю как-то так:
Код
if (*(int*)(c->ecx+ 0x34) == 262144) {//не вешаем благо

Где 262144 взял из "флаги существ", в erm-helper
AlexSpl
Не, не то. Почему благо не работает на андедах в первую очередь? Потому что при касте не устанавливается *(int*)(c->ecx + 0x23C). Нужно посмотреть, как работает каст Bless. Оттуда уже можно взять правильный код.
DedMorozzz
А смысл пытаться сделать так же, как и при касте блесса, когда можно просто в проверку активации блага (наличие молитвы) добавить и проверку на тип существа
AlexSpl
А проще посмотреть в хедерах: должно быть поле, по которому сразу можно определить: undead или нет.
DedMorozzz
в смысле есть отдельное поле "isUndead"? И где эти хедеры смотреть?
AlexSpl
homm3.h. Там, по идее, должна быть описана структура стека.
DedMorozzz
такое есть:
NOALIGN struct _BattleStack_ : _Struct_ // размер 0x548
{
....
_int32_ creature_id; // +52 0x34 // тип монстра

AlexSpl
Попробуйте так проверять:

Код
if ( *(int*)(c->reg + 0x105) & 0x40000 )


c->reg - указатель на стек.

Цитата
такое есть:
NOALIGN struct _BattleStack_ : _Struct_ // размер 0x548
{
....
_int32_ creature_id; // +52 0x34 // тип монстра

Вот. А что там по смещению 0x105?

Поправил. Это ж битовое поле.
DedMorozzz
Цитата(AlexSpl @ 31 Dec 2016, 00:34) *
Вот. А что там по смещению 0x105?

0x105 не нашло. А +261 (dec) только для героя инфа
AlexSpl
Странно. В 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
Цитата(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
Ага. Лучше на два if разбить. Я запарился со скобками )

*(int*)(c->ecx + 0x105) & 0x40000, похоже возвращает, живой ли стек. Но это не важно. Если работает, значит, правильно.

DedMorozzz
Цитата(AlexSpl @ 31 Dec 2016, 00:56) *
Ага. Лучше на два if разбить. Я запарился со скобками )

*(int*)(c->ecx + 0x105) & 0x40000, похоже возвращает, живой ли стек. Но это не важно. Если работает, значит, правильно.

не, не работает))
Не работает не на ком. Т.е. андеды не получают блага. Живые тоже)
AlexSpl
А так?
Код
{
    if (  ( *(int*)(c->ecx + 0x258) != 0 ) &&  !( *(int*)(c->ecx + 0x105) & 0x40000 )  ) c->eax = 1; // проверяем Prayer и андедов

    return EXEC_DEFAULT;
}
DedMorozzz
Цитата(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: ладно, завтра уже поковыряю ещё smile.gif Жена ругается smile.gif
AlexSpl
Реально ничего нет в структуре стека по смещению 0x105 = 261? Наверное, не тот оффсет. Или не та маска.
AlexSpl
Короче, перехватил наведение курсора на отряд при касте 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
DedMorozzz
Спасибо, работает
Что такое 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
Цитата
Вот кстати и +1 урона для благо:
_int32_ bless_value; // +1112 0x458 Bless добавка к Max. Damage

Не только для Bless. Это универсальный бонус для заклинаний.

Цитата
А что такое 0x258 и 0x84 нет. По логике это смещение для каста молитвы и благо, но открыв код молитвы там таких значений нету
Более того в файлах *.h таких смещений тоже не нашел

258h - смещение поля (int), где хранится длительность заклинания (оставшаяся). 84h - это флаги существа в структуре отряда на поле боя (стека).
DedMorozzz
Цитата(AlexSpl @ 31 Dec 2016, 13:47) *
84h - это флаги существа в структуре отряда на поле боя (стека).

Т.е. грубо говоря эта запись:
Код
bool isUndead = *(int*)(c->ecx + 0x84) & 0x40000;

эквивалентна этой:
Код
bool isUndead = if(*(int*)(c->ecx + 0x84) == 0x40000);

?
AlexSpl
Нет, не эквивалентна. У существа есть свойства: летает, двухгексовый, undead и т.п. Флаги - это битовое поле int (32 бита) по смещению 0x84, где каждое свойство отряда хранится в одном бите: 0 - отсутствие свойства, 1 - присутствие свойства (обычно).

*(int*)(c->ecx + 0x84) = xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxxb (32 бита)
40000h (маска) = 1000000000000000000b = 00000000 00000100 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
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2025 IPS, Inc.