Объявления

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

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

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

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

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

AlexSpl писал(а):

Попробуйте готовый плагин.

NewCrBanks.zip


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

Возможно, проблема с выравниваем полей структур. В любом случае, могу переделать, чтобы нужен был только patcher_x86.hpp


Тестирую сейчас вашу dll. Пока ничего не падает.
После тестирования мне нужно будет разобраться со своей dll.
Мне нужны исходники и своя рабочая dll т.к. планируется развитие и поддержка этого плагина будет "Fresh Mod".
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5538
Зарегистрирован: 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)
Поблагодарили: 2155 раз.

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

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

Перезалил патч вместо предыдущего. Там точно второй хук неправильный, в цикл залезает, а места там мало (есть только три байта). Пришлось вместо одного писать три.

Код: Выделить всё
_PI->WriteLoHook(0x4AC0EB, restoreOriginalReward);
_PI->WriteLoHook(0x4AC0FD, restoreOriginalReward);
_PI->WriteLoHook(0x4AC104, restoreOriginalReward);


Потестил, работает. По-хорошему, конечно, нужно HiHook писать, чтобы функция работала с нашей собственной структурой _CrBankState_, а не с оригинальной, которую приходится восстанавливать.

UPD: А нет, есть вылеты. Вот сейчас поймал после взятия улья. Так что пока сырой плагин.
Вернуться к началу

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

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

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

AlexSpl писал(а):

Перезалил патч вместо предыдущего. Там точно второй хук неправильный, в цикл залезает, а места там мало (есть только три байта). Пришлось вместо одного писать три.

Код: Выделить всё
_PI->WriteLoHook(0x4AC0EB, restoreOriginalReward);
_PI->WriteLoHook(0x4AC0FD, restoreOriginalReward);
_PI->WriteLoHook(0x4AC104, restoreOriginalReward);


Потестил, работает. По-хорошему, конечно, нужно HiHook писать, чтобы функция работала с нашей собственной структурой _CrBankState_, а не с оригинальной, которую приходится восстанавливать.

UPD: А нет, есть вылеты. Вот сейчас поймал после взятия улья. Так что пока сырой плагин.


Вылетаю те банки где дают артефакты - большие склепы и утопы.
А так все остальное супер, формулы все верные и существа тоже.

UPD: У сопряжения улучшенные элементали возвращаются, а должны обычные.
UPD2: Элементалей исправил:

Код: Выделить всё
const int Lvl6CreatureID = TownType == 8 ? CID_PSYCHIC_ELEMENTAL : 10 + TownType * 14;
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5538
Зарегистрирован: 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)
Поблагодарили: 2155 раз.

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

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

Перенёс хук. Теперь содержимое регистра ebx тоже сохраняется. Пробуйте.

Код: Выделить всё
#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 sEBX;
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;

    sEBX = c->ebx;
    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*)(sEBX + 0x54) = originalCreatureID;
    *(char*)(sEBX + 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(0x4AC168, restoreOriginalReward);
        }
    }

    return TRUE;
}

NewCrBanks.zip
(5.37 КБ) Скачиваний: 139
Вернуться к началу

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

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

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

AlexSpl писал(а):

Перенёс хук. Теперь содержимое регистра ebx тоже сохраняется. Пробуйте.

Код: Выделить всё
#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 sEBX;
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;

    sEBX = c->ebx;
    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*)(sEBX + 0x54) = originalCreatureID;
    *(char*)(sEBX + 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(0x4AC168, restoreOriginalReward);
        }
    }

    return TRUE;
}

NewCrBanks.zip


Супер! В одиночной у меня ничего не вылетает.
Сейчас сетевую буду проверять.

UPD: В сетевой тоже все работает.
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5538
Зарегистрирован: 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)
Поблагодарили: 2155 раз.

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

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

Да, теперь должно работать. Есть 4 состояния банка (разная охрана, награда, вероятность грейда и т.п.; см. структуру _CrBankState_ в homm3.h). Мы просто меняем после боя награду, если это существа (а таких банка два), остальные поля не трогаем, а потом возвращаем награду обратно, чтобы остальные объекты работали. Ошибка была в том, что я поставил хук, который требует 5 байтов, туда, где было доступно только 3, и джамп хука залез в цикл, который, походу, раздавал артефакты и ресурсы.
Вернуться к началу

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

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

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

AlexSpl писал(а):

Да, теперь должно работать. Есть 4 состояния банка (разная охрана, награда, вероятность грейда и т.п.; см. структуру _CrBankState_ в homm3.h). Мы просто меняем после боя награду, если это существа (а таких банка два), остальные поля не трогаем, а потом возвращаем награду обратно, чтобы остальные объекты работали. Ошибка была в том, что я поставил хук, который требует 5 байтов, туда, где было доступно только 3, и джамп хука залез в цикл, который, походу, раздавал артефакты и ресурсы.


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

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

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

Сообщение as239 » 08 янв 2019, 13:46

AlexSpl писал(а):

а потом возвращаем награду обратно, чтобы остальные объекты работали.

Никак не могу понять зачем возвращать значения.
Заремарил _PI->WriteLoHook(0x4AC168, restoreOriginalReward) , проверил все банки - все работает.

Также не понимаю что за 2-а магических числа: 0x54 и 0x58.
Вернуться к началу

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

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

Сообщение as239 » 08 янв 2019, 13:55

igrik писал(а):

Armageddets писал(а):

На счет помощи - я был бы очень признателен.

Вот, тестируй. Из несделанного только:
1. Таймер
2. Сбегание от нейтралов

Подключать как плагин к HD моду

Armageddets писал(а):

А еще было бы неплохо узнать твои реквизиты, чтобы фанаты имели возможность тебя отблагодарить

Я уже в который раз говорил, и буду говорить, что если вы желает меня как-то отблагодарить, то лучше перенаправте эти вложения на автора HD-мода baratorch (https://sites.google.com/site/heroes3hd/rus/donate)
Без него не было бы этих плагинов вообще. Да и труда в HoMM3 им вложено намного больше, чем мной. Плюс тем самым вы будете способстовать дальнейшему развитию HD-мода.


А можно ли получить исходники.
В практических целях интересует только дипломатия.
Все остальное нужно для обучения моддингу.
Вернуться к началу

offlineigrik  
Подмастерье
Подмастерье
 
Сообщения: 108
Зарегистрирован: 14 сен 2017, 12:35
Пол: Не указан
Поблагодарили: 84 раз.

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

Сообщение igrik » 08 янв 2019, 14:27

as239 писал(а):

А можно ли получить исходники.
В практических целях интересует только дипломатия.
Все остальное нужно для обучения моддингу.

Все эти плюхи написаны лично мной.
Поэтому держи (https://yadi.sk/i/MxpfqhF2_qBjDA).
Можешь использовать как хочешь (и все остальные тоже) :smile27:

PS: Так же читай эту тему. Там много чего разжевано:
http://forum.df2.ru/index.php?showtopic=36506
Вернуться к началу

Пред.След.

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

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

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