Вроде получилось.
- Код: Выделить всё
#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.