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


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

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

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
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 » 09 сен 2017, 20:37

Это локальная переменная (экземпляр struc?) и расположена в стеке. Например, в функции, которая реализует логику Eagle Eye после боя (sub_476910), происходит заполнение полей данной структуры: см. 47695Ch, 4769AAh (это поле всегда инициализируется числом 9, без понятия, что оно означает), 4769B3h и далее. В последнем случае (инструкция по адресу 4769B3h) в одно из полей структуры пишется ID заклинания, чья картинка будет показана в диалоге: mov [ebp+var_18], esi.

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

CALL_5 (unsigned int, __fastcall, 0x4F7D20, Text, &unknown_struc, 0, -1, -1);

По-моему, легче кастомный диалог запилить.
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

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

Сообщение Ben80 » 09 сен 2017, 20:40

Да, я уже понимаю, что стандартный не получится использовать.

Но если уж дать волю фантазии, можно создать кастомную функцию, переделку
Код: Выделить всё
//----- (005A0140) --------------------------------------------------------
void *__thiscall CombatMan_CastSpell(_CombatMan_ *this, int spell, signed int pos, int casterKind, int pos2, int skillLevel, int spellPower)


подредактировать и обрезать примерно после
Код: Выделить всё
if ( DHp )
    {
      v15 = DHp->SSkill[11];
      if ( v15 > 0 )
      {
        if ( !DHp->Spell[spell] )
        {
          if ( v15 + 1 >= vSpell->Level )
          {
            v83 = GetEagleEyePower((int)DHp);
            __asm { fmul ds:flt_0063AC68                    ; Multiply Real }
            v17 = _ftol(v16);
            if ( Random(1, 100) > v17 )
            {
              v10 = v252;
            }
            else
            {
              v10 = v252;
              sub_005A9760((int)&vThis->gap_545c[16 * v252], (int)v263, (int)&spell);
            }
          }
        }
      }
    }


:smile1:
Вернуться к началу

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 » 09 сен 2017, 20:53

Попробую всё-таки разобраться, что это за unknown_struc. В homm3.h пока такую не нашёл.
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

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

Сообщение Ben80 » 09 сен 2017, 21:27

Этот же диалог ведь используется в
//----- (004069B0) --------------------------------------------------------
char __stdcall AskGiftResource(int a1)

и других процедурах (изучение заклинаний из пандорок и тд).

Эти процедуры тоже работают с неизвестной структурой ?
Или же можно выбрать среди этих процедур, которые вызывают DisplayComplexDialog
какую-то наиболее подходящую (которая работает с простыми структурами) ?
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

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

Сообщение Ben80 » 09 сен 2017, 21:41

char __thiscall sub_0056DCB0(void *this, int a2)

Тут вот Mon2Way некий имеется. Не знаете, что это такое ?
DisplayComplexDialog(v10, (int)&Mon2Way, -1, -1, 0);
Вернуться к началу

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 » 09 сен 2017, 22:21

Получилось вызвать, но пока без картинки, т.к. info наполовину нулями забил :smile1:

Код: Выделить всё
char Text[200] = "Герой кастует";
СALL_5 (unsigned int, __fastcall, 0x4F7D20, Text, &info, -1, -1, 0);


-1, -1 - координаты (диалог по центру).

Цитата:
Mon2Way

Кажется, то, что нужно. Посмотрите тип Mon2Way.
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

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

Сообщение Ben80 » 09 сен 2017, 22:30

AlexSpl писал(а):

Посмотрите тип Mon2Way.


Посмотрю :smile1:
Вернуться к началу

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 » 10 сен 2017, 02:03

Вроде получилось.

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

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

struct complexDlgStruc {
    int* field_00;
    int* field_04;
    int* field_08;
};

struct auxStruc {
    int field_00;
    int type;       // тип картинки (9 - заклинание)
    int id;         // ID картинки
    int field_0C;
};

int __stdcall showSpellDlg(LoHook* h, HookContext* c)
{
    complexDlgStruc info;
    auxStruc aux;
   
    aux.field_00 = 0;
    aux.type = 9;
    aux.id = c->ebx;
    aux.field_0C = 0x11;

    info.field_00 = &aux.field_00;
    info.field_04 = &aux.type;
    info.field_08 = &aux.field_0C;
   
    char Text[200] = "Hero casts";
    CALL_5 (unsigned int, __fastcall, 0x4F7D20, Text, &info, -1, -1, 0);
   
    return EXEC_DEFAULT;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    switch ( ul_reason_for_call )
    {
        case DLL_PROCESS_ATTACH:
            if ( !plugin_On )
            {
                plugin_On = 1;
                _P = GetPatcher();
                _PI = _P->CreateInstance("HD.Plugin.TestComplexDialog");
                _PI->WriteLoHook(0x44467E, showSpellDlg);
            }
            break;

        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
    }
    return TRUE;
}


При касте заклинаний, у которых продолжительность раунд/сила магии, показывается диалог:

Изображение

* * *
Этот диалог также может показывать несколько картинок (если я правильно понял код, максимум 8):

Изображение

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

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

struct picStruc {
    int type;       // тип картинки (9 - заклинание)
    int id;         // ID картинки
};

struct complexDlgStruc {
    int* field_00;
    void* field_04;
    int* field_08;
};

struct auxStruc {
    int field_00;
    picStruc pic[8];   
    int field_unk;
};

int __stdcall showSpellDlg(LoHook* h, HookContext* c)
{
    complexDlgStruc info;
    auxStruc aux;
   
    aux.field_00 = 0;
   
    for (int i = 0; i < 8; ++i) {
        aux.pic[i].type = -1;
        aux.pic[i].id = -1;
    }

    aux.pic[0].type = 9;
    aux.pic[0].id = 62;
    aux.pic[1].type = 9;
    aux.pic[1].id = 63;
    aux.pic[2].type = 9;
    aux.pic[2].id = 64;

    aux.field_unk = 0x11;

    info.field_00 = &aux.field_00;
    info.field_04 = &aux.pic;
    info.field_08 = &aux.field_unk;
   
    char Text[200] = "Покажем три картинки:";
    CALL_5 (unsigned int, __fastcall, 0x4F7D20, Text, &info, -1, -1, 0);
   
    return EXEC_DEFAULT;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    switch ( ul_reason_for_call )
    {
        case DLL_PROCESS_ATTACH:
            if ( !plugin_On )
            {
                plugin_On = 1;
                _P = GetPatcher();
                _PI = _P->CreateInstance("HD.Plugin.TestComplexDialog");
                _PI->WriteLoHook(0x44467E, showSpellDlg);
            }
            break;

        case DLL_THREAD_ATTACH:
        case DLL_THREAD_DETACH:
        case DLL_PROCESS_DETACH:
            break;
    }
    return TRUE;
}


Если попытаться показать больше 8 картинок, лишние попадут в дополнительный диалог без текста, который появится сразу же за первым после нажатия на кнопку OK.

P.S. Не знаю, есть ли какой-то смысл в значениях aux.field_00 и aux.field_unk. Похоже, это список. Например, игра использует адрес последнего поля, чтобы определить кол-во картинок, которые необходимо показать:
(&aux.field_unk - &aux.pic) / 8.
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

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

Сообщение Ben80 » 10 сен 2017, 05:09

Впечатляет. Лично я не смог догадаться, что Mon2Way.First и Mon2Way.Last - это тип картинки и id. Mon2Way.Ref и Mon2Way.All оказались избыточной информацией.
Сперва подумалось, что Mon2Way - это что-то вроде связанного списка.
Вернуться к началу

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 » 10 сен 2017, 05:17

Так и есть, это список (только не связанный, а обычный):

Код: Выделить всё
// Структура заголовка списка.
#pragma pack(push, 1)
template <typename _type_> struct _List_
{
public:
  // При первой инициализации-очистке памяти для структуры сюда помещается значение из неинициализированной переменной.
  _byte_ Creation; // +0h;
  // Результат выравнивания, не используется.
  _byte_ Dummy_f1[3]; // +1h;
  // Адрес начала данных списка.
  _type_* Data; // +4h;
  // Адрес конца списка.
  _type_* EndData; // +8h;
  // Конец выделенной на список памяти.
  _ptr_ EndMem; // +Ch;
  ...


Хотелось бы использовать _List_, но он

Цитата:
// Работает для типов размером в 4.


А у нас размер структуры picStruc 8 байтов.
Вернуться к началу

Пред.След.

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

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

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