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

Вот это

Код
if (*(short*)(c->esi + 85) < 10)

лишнее.
DedMorozzz
А вот так - завелось:
Код
char diplomacyLevelBonus = 0;
    if (*(char*)(c->esi + 201 + 4) > 0){
        diplomacyLevelBonus = *(char*)(c->esi + 201 + 4) * 2;
    }


Цитата(AlexSpl @ 27 Dec 2016, 21:05) *
Вот это

Код
if (*(short*)(c->esi + 85) < 10)

лишнее.


Что бы не заходить в проверки артов если есть 10й уровень. И так будет бонус
AlexSpl
Интересно, что не так в моём коде?

Цитата
Что бы не заходить в проверки артов если есть 10й уровень. И так будет бонус

Лишнее. Такая проверка будет после (cmp eax, 0Ah).
DedMorozzz
Цитата(AlexSpl @ 27 Dec 2016, 21:10) *
Интересно, что не так в моём коде?

Незнаю. У меня в коде со смещениями все значения. Мб в этом?

Цитата(AlexSpl @ 27 Dec 2016, 21:10) *
Цитата
Что бы не заходить в проверки артов если есть 10й уровень. И так будет бонус

Лишнее. Такая проверка будет после (cmp eax, 0Ah).

Так будет, но позже. Цель какую я преследовал была в том, что бы в целом не считать то, что не нужно.
Т.е. какой смысл учитывать бонусы от артов / дипломатии. Когда без этих бонусов левела хватает

------------------------------------

Итого на данный момент получился такой код, для учёта левела при посещении библиотеки, с учётом артов:

Код
int __stdcall setLibraryVisitLevel(LoHook* h, HookContext* c)
{
    int allLevelBonuses = 0;
    if (*(short*)(c->esi + 85) < 10) {
        
        for (int i = 0; i < 19; ++i) {
            switch ( *(int*)(c->esi + 301 + (i << 3)) ) {
                case 66:  allLevelBonuses += 1; break;
                case 67:  allLevelBonuses += 1; break;
                case 68:  allLevelBonuses += 1; break;
            }
        }

        if (*(char*)(c->esi + 201 + 4) > 0) {
            allLevelBonuses += *(char*)(c->esi + 201 + 4) * 2;
        }
    }

    int currentLevel = *(int*)(c->esi + 85);
    
    c->eax = currentLevel + allLevelBonuses;
    c->return_address = 0x4A2F55;

    return NO_EXEC_DEFAULT;
}


Код
_PI->WriteLoHook(0x4A2F47, setLibraryVisitLevel);


PS: итого переделывание навыка "дипломатия" закончено! smile.gif
Хотел ещё 5% бонусы сделать для откупа, от монстров для артов. Но думаю чёт с ними) И так уйму всяких мелочей учтено
Благодарю за всесильную помощь!
AlexSpl
Просто реально не понимаю. Есть же контекст. Зачем писать *(int*)(c->esi + 85), если можно просто c->edx?
DedMorozzz
Цитата(AlexSpl @ 27 Dec 2016, 21:28) *
Просто реально не понимаю. Есть же контекст. Зачем писать *(int*)(c->esi + 85), если можно просто c->edx?

ща перепроверю, но так не работало. 1 мин

да, не работает. А вот так - вообще вылетает:
Код
char currentLevel = *(char*)c->edx;


c char - вылетает тоже

PS: я абсолютно не против разобрать причину, есть есть варианты что проверить
AlexSpl
Не нужно приведение типов. См. мой код. c->edx - это уже уровень героя.

Просто вижу, что требуется дополнительное пояснение.

Итак, с->edx = 7 (уровень героя 7). Теперь вы делаете вот что *(char*)7; А именно пытаетесь прочитать память по адресу 7!
DedMorozzz
Цитата(AlexSpl @ 27 Dec 2016, 21:36) *
Не нужно приведение типов. См. мой код. c->edx - это уже уровень героя.

да, я пишу, что так не работает, т.е. уровень подходит уже по коду, а библиотека говорит "ты ещё не готов".
И далее 2 варианта с приведением типов, которые вообще вылетают

Проверил:
Код
c->eax = c->edx + allLevelBonuses;

Так тоже не работает. Не вылетает ничего, но считает что условия не выполнены
AlexSpl
Разберём вот этот код:

Код
.text:004A2F47 loc_4A2F47:
.text:004A2F47 movsx   ecx, byte ptr [esi+0CDh]
.text:004A2F4E movsx   edx, word ptr [esi+55h]
.text:004A2F52 lea     eax, [edx+ecx*2]
.text:004A2F55 cmp     eax, 0Ah


Вы ставите хук на 4A2F52h. Т.е. до выполнения этой инструкции. Соответственно, получаете контекст: в ecx - уровень дипломатии, потому что его туда интрукция movsx ecx, byte ptr [esi+0CDh] загрузила, в edx - уровень героя, потому что его туда инструкция movsx edx, word ptr [esi+55h] загрузила.

Поэтому c->ecx - это уровень дипломатии в контексте, а c->edx - уровень героя.
DedMorozzz
Цитата(AlexSpl @ 27 Dec 2016, 21:46) *
Разберём вот этот код:

Код
.text:004A2F47 loc_4A2F47:
.text:004A2F47 movsx   ecx, byte ptr [esi+0CDh]
.text:004A2F4E movsx   edx, word ptr [esi+55h]
.text:004A2F52 lea     eax, [edx+ecx*2]
.text:004A2F55 cmp     eax, 0Ah


Вы ставите хук на 4A2F52h. Т.е. до выполнения этой инструкции. Соответственно, получаете контекст: в ecx - уровень дипломатии, потому что его туда интрукция movsx ecx, byte ptr [esi+0CDh] загрузила, в edx - уровень героя, потому что его туда инструкция movsx edx, word ptr [esi+55h] загрузила.

Поэтому c->ecx - это уровень дипломатии в контексте, а c->edx - уровень героя.

На самом деле я и ранее это глянул вроде всё верно было. Но не работало... проверив "оригиналы" со смещением - завелось
Сейчас проверю чистый тест, без доп условий артов и прочего. Будет ли работать... 5мин

---------------------------------------

Итого:
Код
int __stdcall setLibraryVisitLevel2(LoHook* h, HookContext* c)
{
    c->eax = c->edx + c->ecx * 2;
    //c->eax = c->edx;
    c->return_address = 0x4A2F55;

    return NO_EXEC_DEFAULT;
}


Код
_PI->WriteLoHook(0x4A2F47, setLibraryVisitLevel2);


Вот так не работает. Даже на 11м уровне героя - говорит что не могу. Закоменченый вариант тоже попробовал. то же самое
AlexSpl
Млин! Да не на 0x4A2F47 хук ставить нужно. На 0x4A2F52.

Если хук на 0x4A2F47, естественно, Вы не получаете нужный контекст.
DedMorozzz
Цитата(AlexSpl @ 27 Dec 2016, 22:03) *
Млин! Да не на 0x4A2F47 хук ставить нужно. На 0x4A2F52.

Если хук на 0x4A2F47, естественно, Вы не получаете нужный контекст.


Код
int __stdcall setLibraryVisitLevel2(LoHook* h, HookContext* c)
{
    c->eax = c->edx + c->ecx * 2;
    c->return_address = 0x4A2F55;

    return NO_EXEC_DEFAULT;
}

Код
_PI->WriteLoHook(0x4A2F52, setLibraryVisitLevel2);


Вылетает при попытке захода в либу

-----------------------

Код
int __stdcall setLibraryVisitLevel2(LoHook* h, HookContext* c)
{
    //c->eax = c->edx + c->ecx * 2;
    c->eax = c->edx;
    c->return_address = 0x4A2F55;

    return NO_EXEC_DEFAULT;
}

Так тоже вылетает, т.е. не в дипломатии дело
AlexSpl
Этот код просто НЕ может вылетать. После сравнения
Код
cmp eax, 0Ah
регистр eax сразу же перезаписывается. Смотрите код внимательнее.

Просто бред же.

У вас всё работало. Проверьте так:

Код
int __stdcall setLibraryVisitLevel2(LoHook* h, HookContext* c)
{
    c->return_address = 0x4A2F55;
    return NO_EXEC_DEFAULT;
}
DedMorozzz
Цитата(AlexSpl @ 27 Dec 2016, 22:30) *
Этот код просто НЕ может вылетать. После сравнения
Код
cmp eax, 0Ah
регистр eax сразу же перезаписывается. Смотрите код внимательнее.

Просто бред же.

У вас всё работало. Проверьте так:

Код
int __stdcall setLibraryVisitLevel2(LoHook* h, HookContext* c)
{
    c->return_address = 0x4A2F55;
    return NO_EXEC_DEFAULT;
}

https://www.youtube.com/watch?v=RARS97b0VQA...eature=youtu.be
Пока проверяю код. Вот записал видео с экрана. Чуток лишнего обрезал ):
И в конце не дало статов потому что было

c->eax = c->edx + allLevelBonuses;
Вместо
c->eax = currentLevel + allLevelBonuses;

-----------------------

Проверил - вылетает и с этими 2мя строчками
AlexSpl
Напишите просто:

Код
int __stdcall setLibraryVisitLevel(LoHook* h, HookContext* c)
{
    int artBonus = 0;
    for (int i = 0; i < 19; ++i) {
        switch ( *(int*)(c->esi + 301 + (i << 3)) ) {
            case 66:
            case 67:
            case 68:  ++artBonus;
        }
    }

    c->eax = (c->edx + artBonus) + c->ecx * 2;
    c->return_address = 0x4A2F55;
    return NO_EXEC_DEFAULT;
}


LoHook на 0x4A2F52.

На всякий случай уберите другие хуки на библиотеку.
DedMorozzz
Цитата(AlexSpl @ 27 Dec 2016, 22:40) *
Напишите просто:

Код
int __stdcall setLibraryVisitLevel(LoHook* h, HookContext* c)
{
    int artBonus = 0;
    for (int i = 0; i < 19; ++i) {
        switch ( *(int*)(c->esi + 301 + (i << 3)) ) {
            case 66:
            case 67:
            case 68:  ++artBonus;
        }
    }

    c->eax = (c->edx + artBonus) + c->ecx * 2;
    c->return_address = 0x4A2F55;
    return NO_EXEC_DEFAULT;
}


LoHook на 0x4A2F52.

На всякий случай уберите другие хуки на библиотеку.


Закоментил вообще всё, даже изменение процентов некромантии. Голый код, только этот хук - вылетает
AlexSpl
Странно:

Тогда по минимуму:

Код
int __stdcall setLibraryVisitLevel(LoHook* h, HookContext* c)
{
    c->return_address = 0x4A2F55;
    return NO_EXEC_DEFAULT;
}


Это вылетает?

LoHook на 0x4A2F52 (!)
DedMorozzz
Цитата(AlexSpl @ 27 Dec 2016, 22:48) *
Это вылетает?

LoHook на 0x4A2F52 (!)


Да. И только при заходе в библиотеку. Герои просматриваются. Меняются... захожу в либу - вылетает
AlexSpl
Это я уже переварить не могу )) Мы просто передаём управление по адресу 4A2F55. Ваша ошибка. Если нет, то - патчера.
DedMorozzz
Цитата(AlexSpl @ 27 Dec 2016, 22:56) *
Это я уже переварить не могу )) Мы просто передаём управление по адресу 4A2F55. Ваша ошибка. Если нет, то - патчера.

Вот чесно, не лень было. раз уже поставил прогу для записи экрана smile.gif
https://youtu.be/3oLTBAOzovE

Может реально где ошибся... но я не вижу где

PS: пересмотрел видео.. я не показал в коде контент ф-ии. Но уверяю там 2 строчки тока)

----------------------------------

И если не слишком сильно утомил, то имеется желание "поиск пути" апнуть...
Сделать +1/2/3 к скорости юнита при подсчёте хода героя на начало дня
т.е. что бы с вампиром-лордом герой бегал на 2000 едениц, как и с ангелом

Как я понимаю базовая ф-я расчёта скорости героя - CalcHeroMovementsPoints
Далее, если я верно понимаю должно вызываться это - loc_004E4E22, для расчёта скорости по земле
Для воды - другая ф-я. Но вот что дальше делать - пока не понимаю
AlexSpl
Нет смысла в видео, всё равно ничего не видно. У вас хук работал (!). Почему он не работает сейчас?

Как бы вот это не поменялось:

Код
c->return_address = 0x4A2F55;
return NO_EXEC_DEFAULT;


Просто тестируйте, прежде чем постить.

Цитата
Вот так завелось:


Код
int __stdcall setLibraryVisitLevel(LoHook* h, HookContext* c)
{
    int tmpLevelBonus = 0;
    if (*(short*)(c->esi + 85) < 10) {
        
        for (int i = 0; i < 19; ++i) {
            switch ( *(int*)(c->esi + 301 + (i << 3)) ) {
                case 66:  tmpLevelBonus += 1; break;
                case 67:  tmpLevelBonus += 1; break;
                case 68:  tmpLevelBonus += 1; break;
            }
        }
    }
    

    int currentLevel = *(int*)(c->esi + 85);
    int diplomacyLevelBonus = *(int*)(c->esi + 201 + 4) * 2;
    
    c->eax = currentLevel + tmpLevelBonus + diplomacyLevelBonus;
        
    c->return_address = 0x4A2F55;
    return NO_EXEC_DEFAULT;
}


Ваш код, который работал.
DedMorozzz
работал только мой код. Тот который последнее время пробуем - нет
Если что у видео есть выбор качества, у меня норм отображается smile.gif Всё видно

Т.е. текущий рабочий код выглядит так:
Код
int __stdcall setLibraryVisitLevel(LoHook* h, HookContext* c)
{
    int allLevelBonuses = 0;
    if (*(short*)(c->esi + 85) < 10) {
        
        for (int i = 0; i < 19; ++i) {
            switch ( *(int*)(c->esi + 301 + (i << 3)) ) {
                case 66:  allLevelBonuses += 1; break;
                case 67:  allLevelBonuses += 1; break;
                case 68:  allLevelBonuses += 1; break;
            }
        }

        if (*(char*)(c->esi + 201 + 4) > 0) {
            allLevelBonuses += *(char*)(c->esi + 201 + 4) * 2;
        }
    }

    int currentLevel = *(int*)(c->esi + 85);
    
    c->eax = currentLevel + allLevelBonuses;
    c->return_address = 0x4A2F55;

    return NO_EXEC_DEFAULT;
}

Никакой другой не работал. Только который был со смещениями
AlexSpl
Я понимаю, что этот код работает. Но *(int*)(c->esi + 85) есть c->edx, а *(char*)(c->esi + 201 + 4) есть c->ecx.

Разницу между указателями и непосредственными значениями знаете?

* * *
Короче, просто задачка по теме:

Запарсите в уме

*(float*)&c->eax = 0.1f;

*Как* это работает, понимаете? Почему это работает? )
DedMorozzz
Цитата(AlexSpl @ 27 Dec 2016, 23:31) *
Я понимаю, что этот код работает. Но *(int*)(c->esi + 85) есть c->edx, а *(char*)(c->esi + 201 + 4) есть c->ecx.

Разницу между указателями и непосредственными значениями знаете?

* * *
Короче, просто задачка по теме:

Запарсите в уме

(*float*)&c->eax = 0.1f;

*Как* это работает, понимаете?

Да, то что должно быть одинаково я понимаю. Это по сути переменная, под каким видом пройдёт. Я в коде такое часто пишу.
Тот же baseHeroOffset то же самое, вот от сюда:
Код
int __stdcall setArmyValue(LoHook* h, HookContext* c)
{
    int baseHeroOffset = c->edi;
    float armyModifier = getArmyValueModifier(baseHeroOffset);
    (int)c->eax *= (1 + armyModifier);

    return EXEC_DEFAULT;
}


int __stdcall setArmyValuePreview(LoHook* h, HookContext* c)
{
    int baseHeroOffset = c->esi;
    float armyModifier = getArmyValueModifier(baseHeroOffset);
    (int)c->eax *= (1 + armyModifier);

    return EXEC_DEFAULT;
}

int __stdcall setArmyValueSplit(LoHook* h, HookContext* c)
{
    int baseHeroOffset = *(int*)(c->ebp + 8);
    float armyModifier = getArmyValueModifier(baseHeroOffset);
    (int)c->eax *= (1 + armyModifier);

    return EXEC_DEFAULT;
}


Насчёт (*float*)&c->eax = 0.1f;
Это не понятно, выглядит как странное приведение типа. Но в том случае когда c->eax это интеджер
Но это так, догадка что переписывается тип..
AlexSpl
Да нет тут высшей математики.

Лежит число по адресу A. Захотели его прочитать, пишете *(type*)A. Где type - это тип, который Вам нужен.

Хотите читайте его как целое, а хотите - как дробное.

Цитата
*(float*)&c->eax = 0.1f;

1. &c->eax - получаем адрес числа, а не его значение;
2. *(float*)&c->eax - интерпретируем число по адресу &c->eax, как float.

AlexSpl
Цитата
Но это так, догадка что переписывается тип..

Допустим, я компилятор и я заявляю, что тип pretty буду обрабатывать так: каждый нечётный бит, равный 1, будет добавлять 4 к значению.

0000 0000 = 0
1000 1000 = 0
0100 0000 = 4
0100 0100 = 8
и т.д.

Пусть в регистре eax находится адрес числа 1101 1101 = 0xDD = 221. Тогда *(int*)eax будет возвращать 221, а *(pretty*)eax - 16.
DedMorozzz
Цитата(AlexSpl @ 27 Dec 2016, 23:50) *
Цитата
*(float*)&c->eax = 0.1f;

1. &c->eax - получаем адрес числа, а не его значение;
2. *(float*)&c->eax - интерпретируем число по адресу &c->eax, как float.


Слегка не ясно. Зачем амперсант тогда. Если
Цитата
2. *(float*)&c->eax - интерпретируем число по адресу &c->eax, как float.

Т.е. значение адресса берём. Это не то же самое что и *(float*)c->eax ?

Как я понял. &c->eax == 0x4E480B (условно)
При этом c->eax = 12 (условно)
Соотв. если флоат интерпретирует значение по адрессу как флоат, это то же самое что и без амперсанта ...
(float) c->eax === *(float*)&c->eax ?
AlexSpl
Цитата
Т.е. значение адресса берём. Это не то же самое что и *(float*)c->eax ?

Например, если c->eax = 0, то *(float*)c->eax прочитает память по нулевому адресу. Типичная причина вылета.

Можно ещё так:
Код
*(float*)&c->eax = 1.1f;

Код
(float&)c->eax = 1.1f;
DedMorozzz
Какая ф-я(адрес) расчёт скорости героя на начало хода ведёт?
Имеется виду именно минимальная скорость монстра в войске героя. Хочу при определёных условиях мин скорость монстра увеличивать
feanor
004E4C00, DoCalcHeroMovementPoints
DedMorozzz
Цитата(feanor @ 28 Dec 2016, 11:37) *
004E4C00, DoCalcHeroMovementPoints


Цитата(DedMorozzz @ 27 Dec 2016, 23:14) *
Как я понимаю базовая ф-я расчёта скорости героя - CalcHeroMovementsPoints
Далее, если я верно понимаю должно вызываться это - loc_004E4E22, для расчёта скорости по земле
Для воды - другая ф-я. Но вот что дальше делать - пока не понимаю


Вот на этом подзастрял..
feanor
004E4ED9 - место где скорость минимального существа преобразуется в запас очков хода

наверное, так
Код
int __stdcall qwertyuiop(LoHook* h, HookContext* c)
{
    c->ecx += *(char*)(c->ebx + 201);
    return EXEC_DEFAULT;
}

h->WriteLoHook(0x4E4ED9, (void*)qwertyuiop);
DedMorozzz
Цитата(feanor @ 28 Dec 2016, 11:52) *
004E4ED9 - место где скорость минимального существа преобразуется в запас очков хода

наверное, так
Код
int __stdcall qwertyuiop(LoHook* h, HookContext* c)
{
    c->ecx += *(char*)(c->ebx + 201);
    return EXEC_DEFAULT;
}

h->WriteLoHook(0x4E4ED9, (void*)qwertyuiop);

да, оно. Спасибо!
DedMorozzz
чёт странное происходит:

Код
int __stdcall setBaseHeroSpeed(LoHook* h, HookContext* c)
{
    char speedBonus = 0;
    if (*(char*) (c->edx + 201 + 0) > 0) {
        speedBonus = 3;
    }

    char finalBonus = *(char*)(c->ebx + 201) + speedBonus;
    c->ecx += finalBonus;

    return EXEC_DEFAULT;
}


Код
_PI->WriteLoHook(0x4E4ED9, setBaseHeroSpeed);


Муха из болота. Скорость 9. Базовая скорость 1900.
Базовый поиск пути - скорость становится 1960
Улучшенный - 2000

Ожидаемо 2000 всегда ибо в коде прописано "при наличии поиска пути" делать +3 к скорости. Уровень навыка пока что не влияет...
В чём тут ошибка?
feanor
Цитата
Код
    if (*(char*) (c->edx + 201 + 0) > 0) {

ebx же
DedMorozzz
Цитата(feanor @ 28 Dec 2016, 12:40) *
Цитата
Код
    if (*(char*) (c->edx + 201 + 0) > 0) {

ebx же

вот жеж! Выше вообще готовое решение было smile.gif А я подумал что то выборка обычной скорости монстра была...
И пытался навесить условие с левелом навыка
А всё намного проще оказалось! Спасибо smile.gif
DedMorozzz
Пробую сделать +1/+2/+3 скорости на 1й ход, для тактики, во время боя во всех банках (т.е. там где войска по центру)

Иду от простого к сложному. Пробую для любого боя, без учёта тактики сделать бонус к ходу

.text:00475A37 loc_00475A37: ; CODE XREF: sub_00475800+255j
.text:00475A37 cmp dword ptr [ecx+34h], 0FFFFFFFFh ; Compare Two Operands
.text:00475A3B jz short loc_00475A45 ; Jump if Zero (ZF=1)
.text:00475A3D call combatMonster_SetUpNewRound ; Call Procedure
.text:00475A42 mov ecx, [ebp-4]

Сюда мы попадаем когда начинается новый ход.

Здесь я должен убрать бонус к скорости, если он есть. Но лучшее решение - взять номер раунда, если 1й, тогда давать бонус, но временно...
В общем, пробую хоть что-то сделать, что бы работало. Т.е. язнаю что попадаю в блок выше (475A37) после 1го раунда

Делаю:
Код
int __stdcall setTacticsUnitSpeed(LoHook* h, HookContext* c)
{
    //*(int*)(c->ecx +196) += 2;
    *(int*)(c->ecx + 1224) += 2;
    return EXEC_DEFAULT;
}


Код
_PI->WriteLoHook(0x475A37, setTacticsUnitSpeed);


Не работает. Итого вопрос - как более правильно задать скорость монстров, желательно на 1н ход. Какой адресс и edi/edx... юзать
И заодно, было бы здорово понять когда бой в банке, а когда обычный
DedMorozzz
Попробовал на ф-ю Battle
Код
_PI->WriteLoHook(0x4AD163, setTacticsUnitSpeed);

Судя по коду 2 переменные там:
Код
.text:004AD161                     mov     ebp, esp


Зная по примеру из магии замедления, есть 2 смещения монстров. 196 скорость и 1224 - модификатор скорости
В надежде что или ebp или esp будет монстр - пробовал им задать. При любом раскладе вылетает
Какой адрес верный? Должна же в ф-ии битвы присутствовать переменная с монстрами
AlexSpl
Что я могу сказать? ) Не решается эта задача так просто. Нужно ловить в коде инициализацию отрядов. Если бой в банке, всем союзным добавлять +1 к скорости. В начале второго раунда убирать этот бонус. Куча работы.
DedMorozzz
Цитата(AlexSpl @ 28 Dec 2016, 19:43) *
Что я могу сказать? ) Не решается эта задача так просто. Нужно ловить в коде инициализацию отрядов. Если бой в банке, всем союзным добавлять +1 к скорости. В начале второго раунда убирать этот бонус. Куча работы.


я понимаю ):
Нашел код боя. Нашел код нового раунда. Вроде знаю смещения модификаторов скорости
А вот совместить как - хз. Даже не то что совместить, а хотя бы реализовать частично кусок - хз как

Потому и пошел по частям - увеличить при любом бое союзным юнитам скорость на 1. Но не понял как
Нет цели всё сразу, пробую по частям

PS: т.е. на данный момент хочу решить задачу такую - при наличии тактики (смещение +19) всем союзным юнитам сделать +2 скорости
PPS: чуток подкопал по банкам/склепам
0040AB40 - адресс посещения банка. (.text:0040AB40 Enter2ObjectGuardText proc near) там диалог. Последний блокперед боем (004AC24E loc_004AC24E:) В нём вызывается (loc_004ABAB0) это уже сам бой
AlexSpl
Ну, для начала.

Есть гекс с координатами (x, y), на котором расположен отряд. Описания полей combatManager я не встречал, так что пишу только то, что знаю.

Код
int cmAddr = *(int*)0x699420;
int x = *(int*)(cmAddr + 0x132B8);
int y = *(int*)(cmAddr + 0x132BC); // или наоборот ))
int creatureAddr = cmAddr + 1352 * (x + 21 * y) + 21708;



Теперь находим, где в структуре отряда хранится его скорость, ставим hardware брейкпоинт на запись, начинаем бой и попадаем в то место кода, где скорость (пере)записывается.
DedMorozzz
Цитата(AlexSpl @ 28 Dec 2016, 20:05) *
Ну, для начала.

Есть гекс с координатами (x, y), на котором расположен отряд. Описания полей combatManager я не встречал, так что пишу только то, что знаю.

Код
int cmAddr = *(int*)0x699420;
int x = *(int*)(cmAddr + 0x132B8);
int y = *(int*)(cmAddr + 0x132BC); // или наоборот ))
int creatureAddr = cmAddr + 1356 * (x + 21 * y) + 21708;


Теперь находим, где в структуре отряда хранится его скорость, ставим hardware брейкпоинт на запись, начинаем бой и попадаем в то место кода, где скорость (пере)записывается.


Пытаюсь сопоставить инфу, по поводу цифр. Я так понял идея взять гексы и проверить войска. Если там есть, тем мобам увеличить скорость?
Открыл ЕРМ хелпер, там есть айдишники гексов - https://sc-cdn.scaleengine.net/i/893cd4bbe6...194fdf2d584.png их стоит брать?

Так же, что такое 1356/21/21708? Пока что даже не догадываюсь
AlexSpl
1352. Исправил. 1356 - для "Полного Собрания" от "Буки".
DedMorozzz
так а что это за цифры: 1352/21/21708?
igrik
21708 - смещение от комбат мэнеджера к стекам
1352 - размер структуры боевого стека
21 - количество стеков для одной стороны. Всего 41

В ерм-хелпе масса информации, которую можно применять и для хоты. Арты, объекты, герои, номера зданий и т.п. Но конечно же не всё. Гексы поля боя одни для всех версий героев.

Да и вообще. В посте feanora (я давал ссылку "как создать dll") там же инклуды есть. Чё вы ими то не пользуетесь?
AlexSpl
Короче, начал проверять. Всё, оказывается, не так, как мне казалось )

Код
int cmAddr = *(int*)0x699420;
int side = *(int*)(cmAddr + 0x132B8);
int unitNumber = *(int*)(cmAddr + 0x132BC);
int unitAddr = cmAddr + 1352 * (unitNumber + 21 * side) + 21708;


side - сторона (0 - левая, 1 - правая)
unitNumber - номер отряда в армии (начиная с 0).

Теперь, вроде, правильно )
DedMorozzz
Цитата(igrik @ 28 Dec 2016, 20:44) *
Да и вообще. В посте feanora (я давал ссылку "как создать dll") там же инклуды есть. Чё вы ими то не пользуетесь?


Я тогда не знал что это такое и как это готовить, да и сейчас не знаю ):
Вот полез, открыл... да, те же оффсет для бонуса морали нашел, который спрашивал, но явно не основной функционал
Т.е.что брать из инклудов - пока не понимаю...

----------------------------------------------

Цитата(AlexSpl @ 28 Dec 2016, 20:45) *
Короче, начал проверять. Всё, оказывается, не так, как мне казалось )

Код
int cmAddr = *(int*)0x699420;
int side = *(int*)(cmAddr + 0x132B8);
int unitNumber = *(int*)(cmAddr + 0x132BC);
int unitAddr = cmAddr + 1352 * (unitNumber + 21 * side) + 21708;


side - сторона (0 - левая, 1 - правая)
unitNumber - номер отряда в армии (начиная с 0).

Теперь, вроде, правильно )

Я правильно понимаю, что данный код получает всех юнитов за левую сторону. Без смещения?

Т.е. по логике вещей, если смещение модификатора скорости это 1224, то скорость юнита будет:
(unitAddr + 1224) ?


И я хук вешаю на адрес (0x4AD163) это ф-я Battle. Верный адрес? (забегая наперёд, так вылетает, если код выше поставить на этот адрес)
AlexSpl
Вроде нашёл. Как в базе IDA называется функция sub_43D450?
DedMorozzz
.text:0043D450 combatMonster_0043D450 proc near
оно?
AlexSpl
Значит, не обозвали. Она инициализирует отряды (43D490h). А вот здесь, похоже, бонусы к скорости добавляются: 4E666A.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Форум IP.Board © 2001-2025 IPS, Inc.