Объявления
Поздравляем
Roman2211


Друзья, если не получается зарегистрироваться, напишите на почту vdv_forever@bk.ru.
Я оторву свою задницу от всех дел и обязательно Вас активирую! :smile10:
Добро пожаловать на геройский форум! :smile25:

Как создать плагин для HD мода

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
offlineas239  
имя: Анатолий
Ветеран
Ветеран
 
Сообщения: 527
Зарегистрирован: 29 дек 2018, 14:17
Пол: Мужчина
Поблагодарили: 38 раз.

Re: Как создать плагин для HD мода

Сообщение as239 » 06 янв 2019, 13:25

AlexSpl писал(а):

Можно просто отредактировать экзешник: ангелы (0Сh) - по адресу 270384h, виверны (6Сh) - по адресу 270394h.

Если нужен плагин, то так:

Код: Выделить всё
#include "patcher_x86.hpp"

Patcher* _P;
PatcherInstance* _PI;
static _bool_ plugin_On = 0;

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    if ( DLL_PROCESS_ATTACH == ul_reason_for_call )
    {
        if ( !plugin_On )
        {
            plugin_On = 1;
            _P = GetPatcher();
            _PI = _P->CreateInstance("HD.Plugin.CreatureBanks");
           
            _PI->WriteDword(0x670384, 12);  // ID существа в Консерватории
            _PI->WriteDword(0x670394, 108); // ID существа в Улье
        }
    }

    return TRUE;
}


Огромное спасибо! То что нужно. А как получить количество возвращаемых существ?
Весь день вчера и сегодня пытался найти через IDA, даже близко не был.
Делаю патч, который возвращает из консерваторий и уликов, не ангелов и уток, а существа 7, 6 уровня, стартового замка текущего игрока, пропорционально ОЗ ангелов и уток.
Последний раз редактировалось as239 06 янв 2019, 14:13, всего редактировалось 1 раз.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2185 раз.

Re: Как создать плагин для HD мода

Сообщение AlexSpl » 06 янв 2019, 14:01

Кол-во и шансы можно изменить в CrBanks.txt (например, с помощью MMArchive). Если нужен плагин, то см. код по адресу 47A713h (в eax - адрес кол-ва существ; выше, в edx - порядковый номер шанса: 0-3).

Можно ещё перехватывать LoHook'ом загрузку из CrBanks.txt (функция по адресу 47A460h). Этот вариант хорош тогда, когда просто нужно изменить кол-во и проценты. В первом можно делать всё что угодно (например, давать разных существ в любом кол-ве по каким угодно правилам).

* * *
Цитата:
Делаю патч, который возвращает из консерваторий и уликов, не ангелов и уток, а существа 7, 6 уровня, стартового замка текущего игрока, пропорционально ОЗ ангелов и уток.

Тогда нужно делать по-другому. Начинку банки при загрузке карты получают. В Вашем случае нужно перехватывать получение героем армии из банка. Поставьте брейкпоинт на запись в слот армии. Так можно найти функцию, которая даёт существ после боя в банке, и переделать её в зависимости от текущей армии.
Последний раз редактировалось AlexSpl 06 янв 2019, 14:28, всего редактировалось 1 раз.
Вернуться к началу

offlineas239  
имя: Анатолий
Ветеран
Ветеран
 
Сообщения: 527
Зарегистрирован: 29 дек 2018, 14:17
Пол: Мужчина
Поблагодарили: 38 раз.

Re: Как создать плагин для HD мода

Сообщение as239 » 06 янв 2019, 14:28

Цитата:
Поставьте брейкпоинт на запись в слот армии

Вот это не понимаю как сделать.
Подключаюсь отладчиком в момент взятия улика(консерватории), когда появляется окно с количеством полученных существ и ничего не вижу, в регистрах ничего нет напоминающего тип существа и его количество.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2185 раз.

Re: Как создать плагин для HD мода

Сообщение AlexSpl » 06 янв 2019, 14:32

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

offlineas239  
имя: Анатолий
Ветеран
Ветеран
 
Сообщения: 527
Зарегистрирован: 29 дек 2018, 14:17
Пол: Мужчина
Поблагодарили: 38 раз.

Re: Как создать плагин для HD мода

Сообщение as239 » 06 янв 2019, 14:35

AlexSpl писал(а):

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


Консерватория дает не ангелов, а юнит 7-го уровня стартового замка игрока, взявшего консерваторию.
Согласно формуле: Кол. 7 уровень = Кол.Анг.*200/ОЗ , где:
Кол.Анг. = стандартное количество ангелов, даваемых в консерватории (1,2,3,4)
ОЗ = очки здоровья юнита 7-го уровня стартового замка игрока.

Улей дает не виверен, а юнит 6-го уровня стартового замка игрока, взявшего улей.
Согласно формуле: Кол. 6 уровень = Кол.Вив.*70/ОЗ , где:
Кол.Вив. = стандартное количество виверен, даваемых в улье (4,6,8,12)
ОЗ = очки здоровья юнита 6-го уровня стартового замка игрока.

Округление в меньшую сторону, ну или просто целочисленный остаток от деления.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2185 раз.

Re: Как создать плагин для HD мода

Сообщение AlexSpl » 06 янв 2019, 17:43

Вот такое временное решение (вместо стартового города берётся первый в списке; если города нет, не работает; потом поищу, как получить стартовый):

Код: Выделить всё
#define _CRT_SECURE_NO_WARNINGS
#include "HotA\homm3.h"

Patcher* _P;
PatcherInstance* _PI;
static _bool_ plugin_On = 0;

#define CREATURE_INFO_OFFSET (*(_ptr_*)0x47ADD1)
#define o_CreatureInfo ((_CreatureInfo_*)CREATURE_INFO_OFFSET)

int originalCreatureID;
char originalCreatureN;

int __stdcall setCreatureBankReward(LoHook* h, HookContext* c)
{
    // const char TownType = o_GameMgr->GetTown(o_ActivePlayer->towns_ids[0])->type;
    const int TownType = *(int*)o_GameMgr->Offset(0x1F6A0 + 0x10 + o_ActivePlayerID * 4);

    const int Lvl6CreatureID = TownType == 8 ? CID_MAGIC_ELEMENTAL : 10 + TownType * 14;
    const int Lvl7CreatureID = TownType == 8 ? CID_FIREBIRD : 12 + TownType * 14;

    originalCreatureID = *(int*)(c->ebx + 0x54);
    originalCreatureN = *(char*)(c->ebx + 0x58);

    switch ( originalCreatureID ) {
        // Меняем Ангелов
        case CID_ANGEL:
            *(int*)(c->ebx + 0x54) = Lvl7CreatureID;
            *(char*)(c->ebx + 0x58) = originalCreatureN * 200 / (o_CreatureInfo + Lvl7CreatureID)->hit_points; // N
            if ( *(char*)(c->ebx + 0x58) < 1 ) *(char*)(c->ebx + 0x58) = 1;
            break;

        // Меняем Виверн
        case CID_WYVERN:
            *(int*)(c->ebx + 0x54) = Lvl6CreatureID;
            *(char*)(c->ebx + 0x58) = originalCreatureN * 70 / (o_CreatureInfo + Lvl6CreatureID)->hit_points; // N
            if ( *(char*)(c->ebx + 0x58) < 1 ) *(char*)(c->ebx + 0x58) = 1;
            break;
    }
   
    return EXEC_DEFAULT;
}

int __stdcall restoreOriginalReward(LoHook* h, HookContext* c)
{
    *(int*)(c->ebx + 0x54) = originalCreatureID;
    *(char*)(c->ebx + 0x58) = originalCreatureN;

    return EXEC_DEFAULT;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    if ( DLL_PROCESS_ATTACH == ul_reason_for_call )
    {
        if ( !plugin_On )
        {
            plugin_On = 1;
            _P = GetPatcher();
            _PI = _P->CreateInstance("HD.Plugin.NewCreatureBanks");
           
            _PI->WriteLoHook(0x4ABBFA, setCreatureBankReward);
            _PI->WriteLoHook(0x4AC107, restoreOriginalReward);
        }
    }

    return TRUE;
}


UPD: Нашёл, где хранится стартовый город. Предыдущий вариант закомментил.
Последний раз редактировалось AlexSpl 07 янв 2019, 07:16, всего редактировалось 1 раз.
Вернуться к началу

offlineas239  
имя: Анатолий
Ветеран
Ветеран
 
Сообщения: 527
Зарегистрирован: 29 дек 2018, 14:17
Пол: Мужчина
Поблагодарили: 38 раз.

Re: Как создать плагин для HD мода

Сообщение as239 » 07 янв 2019, 07:15

AlexSpl писал(а):

Вот такое временное решение (вместо стартового города берётся первый в списке; если города нет, не работает; потом поищу, как получить стартовый):

Код: Выделить всё
#define _CRT_SECURE_NO_WARNINGS
#include "HotA\homm3.h"

Patcher* _P;
PatcherInstance* _PI;
static _bool_ plugin_On = 0;

#define CREATURE_INFO_OFFSET (*(_ptr_*)0x47ADD1)
#define o_CreatureInfo ((_CreatureInfo_*)CREATURE_INFO_OFFSET)

int originalCreatureID;
char originalCreatureN;

int __stdcall setCreatureBankReward(LoHook* h, HookContext* c)
{
    const char TownType = o_GameMgr->GetTown(o_ActivePlayer->towns_ids[0])->type;
    const int Lvl6CreatureID = TownType == 8 ? CID_MAGIC_ELEMENTAL : 10 + TownType * 14;
    const int Lvl7CreatureID = TownType == 8 ? CID_FIREBIRD : 12 + TownType * 14;

    originalCreatureID = *(int*)(c->ebx + 0x54);
    originalCreatureN = *(char*)(c->ebx + 0x58);

    switch ( originalCreatureID ) {
        // Меняем Ангелов
        case CID_ANGEL:
            *(int*)(c->ebx + 0x54) = Lvl7CreatureID;
            *(char*)(c->ebx + 0x58) = originalCreatureN * 200 / (o_CreatureInfo + Lvl7CreatureID)->hit_points; // N
            if ( *(char*)(c->ebx + 0x58) < 1 ) *(char*)(c->ebx + 0x58) = 1;
            break;

        // Меняем Виверн
        case CID_WYVERN:
            *(int*)(c->ebx + 0x54) = Lvl6CreatureID;
            *(char*)(c->ebx + 0x58) = originalCreatureN * 70 / (o_CreatureInfo + Lvl6CreatureID)->hit_points; // N
            if ( *(char*)(c->ebx + 0x58) < 1 ) *(char*)(c->ebx + 0x58) = 1;
            break;
    }
   
    return EXEC_DEFAULT;
}

int __stdcall restoreOriginalReward(LoHook* h, HookContext* c)
{
    *(int*)(c->ebx + 0x54) = originalCreatureID;
    *(char*)(c->ebx + 0x58) = originalCreatureN;

    return EXEC_DEFAULT;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    if ( DLL_PROCESS_ATTACH == ul_reason_for_call )
    {
        if ( !plugin_On )
        {
            plugin_On = 1;
            _P = GetPatcher();
            _PI = _P->CreateInstance("HD.Plugin.NewCreatureBanks");
           
            _PI->WriteLoHook(0x4ABBFA, setCreatureBankReward);
            _PI->WriteLoHook(0x4AC107, restoreOriginalReward);
        }
    }

    return TRUE;
}


Вопрос обязательно ли включать "HotA\homm3.h" или можно обычный "homm3.h" т.к. у меня есть только он и мод предназначен для сетевой игры в SOD. Работоспособность в HotA не нужна.
Вернуться к началу

offlineas239  
имя: Анатолий
Ветеран
Ветеран
 
Сообщения: 527
Зарегистрирован: 29 дек 2018, 14:17
Пол: Мужчина
Поблагодарили: 38 раз.

Re: Как создать плагин для HD мода

Сообщение as239 » 07 янв 2019, 07:17

AlexSpl писал(а):

Вот такое временное решение (вместо стартового города берётся первый в списке; если города нет, не работает; потом поищу, как получить стартовый):

Код: Выделить всё
#define _CRT_SECURE_NO_WARNINGS
#include "HotA\homm3.h"

Patcher* _P;
PatcherInstance* _PI;
static _bool_ plugin_On = 0;

#define CREATURE_INFO_OFFSET (*(_ptr_*)0x47ADD1)
#define o_CreatureInfo ((_CreatureInfo_*)CREATURE_INFO_OFFSET)

int originalCreatureID;
char originalCreatureN;

int __stdcall setCreatureBankReward(LoHook* h, HookContext* c)
{
    const char TownType = o_GameMgr->GetTown(o_ActivePlayer->towns_ids[0])->type;
    const int Lvl6CreatureID = TownType == 8 ? CID_MAGIC_ELEMENTAL : 10 + TownType * 14;
    const int Lvl7CreatureID = TownType == 8 ? CID_FIREBIRD : 12 + TownType * 14;

    originalCreatureID = *(int*)(c->ebx + 0x54);
    originalCreatureN = *(char*)(c->ebx + 0x58);

    switch ( originalCreatureID ) {
        // Меняем Ангелов
        case CID_ANGEL:
            *(int*)(c->ebx + 0x54) = Lvl7CreatureID;
            *(char*)(c->ebx + 0x58) = originalCreatureN * 200 / (o_CreatureInfo + Lvl7CreatureID)->hit_points; // N
            if ( *(char*)(c->ebx + 0x58) < 1 ) *(char*)(c->ebx + 0x58) = 1;
            break;

        // Меняем Виверн
        case CID_WYVERN:
            *(int*)(c->ebx + 0x54) = Lvl6CreatureID;
            *(char*)(c->ebx + 0x58) = originalCreatureN * 70 / (o_CreatureInfo + Lvl6CreatureID)->hit_points; // N
            if ( *(char*)(c->ebx + 0x58) < 1 ) *(char*)(c->ebx + 0x58) = 1;
            break;
    }
   
    return EXEC_DEFAULT;
}

int __stdcall restoreOriginalReward(LoHook* h, HookContext* c)
{
    *(int*)(c->ebx + 0x54) = originalCreatureID;
    *(char*)(c->ebx + 0x58) = originalCreatureN;

    return EXEC_DEFAULT;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    if ( DLL_PROCESS_ATTACH == ul_reason_for_call )
    {
        if ( !plugin_On )
        {
            plugin_On = 1;
            _P = GetPatcher();
            _PI = _P->CreateInstance("HD.Plugin.NewCreatureBanks");
           
            _PI->WriteLoHook(0x4ABBFA, setCreatureBankReward);
            _PI->WriteLoHook(0x4AC107, restoreOriginalReward);
        }
    }

    return TRUE;
}


Я скомпилировал с обычным "homm3.h"". При взятии макси склепа (хот-сит) игра падает.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2185 раз.

Re: Как создать плагин для HD мода

Сообщение AlexSpl » 07 янв 2019, 07:19

Цитата:
Я скомпилировал с обычным "homm3.h"". При взятии макси склепа (хот-сит) игра падает.

Возможно, проблема с выравниваем полей структур. В любом случае, могу переделать, чтобы нужен был только patcher_x86.hpp
Последний раз редактировалось AlexSpl 07 янв 2019, 08:05, всего редактировалось 2 раз(а).
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5587
Зарегистрирован: 17 сен 2010, 12:58
Пол: Мужчина
Награды: 14
Высшая медаль (1) Победителю турнира по HMM1_TE (2) Победителю этапа по HMM1 (1) Победителю этапа по HMM2 (1) Лучшему из лучших (1) 2 место 1 этапа по HMM1 (1)
3 место 1 этапа по HMM1 (1) 1 место 2 этапа по HMM2 (1) Победителю турнира по KB (2) Победителю турнира по KB (1) Грандмастер оффлайн-турниров (1) Боевой шлем (1)
Поблагодарили: 2185 раз.

Re: Как создать плагин для HD мода

Сообщение AlexSpl » 07 янв 2019, 07:29

Ага, Склеп я не проверял. Действительно падает после взятия. Посмотрю почему.

Понятно. Хук частично в цикл попал :smile1: Сейчас исправлю.
Вернуться к началу

Пред.След.

Вернуться в Общий раздел

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2