-
void_17
имя: имя
- Ветеран
-
- Сообщения: 548
- Зарегистрирован: 25 апр 2021, 15:05
- Откуда: Оттуда
- Пол:
- Поблагодарили: 132 раз.
|
void_17 » 31 дек 2021, 12:12
Так как я вижу никто плагин так и не скомпилировал... Отлично. Хороший подарок фанатам Героев на НГ. Только вот не вижу сам плагин (*.dll) и его код. Вижу только описание плагина, ссылку на галерею с картинками HotA и скрин с кнопками. - Код: Выделить всё
#include "stdafx.h" #include "..\..\include\homm3.h"
char myString[1024]; #define MyString (char*)myString
Patcher* _P; PatcherInstance* _PI;
/////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////// КОНСТАНТЫ ///////////////////////////////////////////////
#define MAPSIZE_S 36 #define MAPSIZE_M 72 #define MAPSIZE_L 108 #define MAPSIZE_XL 144 #define MAPSIZE_H 180 #define MAPSIZE_XH 216 #define MAPSIZE_G 252
#define BTTNID_S 281 #define BTTNID_M 282 #define BTTNID_L 283 #define BTTNID_XL 284 #define BTTNID_U 285
#define BTTNID_PCX 1102 #define BTTNID_H 1103 #define BTTNID_XH 1104 #define BTTNID_G 1105
/////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////
#define SmallFont_FNT (*(char**)0x4EEAF8)
char* RanSizS_DEF = "RanSizS.def"; char* RanSizM_DEF = "RanSizM.def"; char* RanSizL_DEF = "RanSizL.def"; char* RanSizXL_DEF = "RanSizX.def"; char* RanSizHG_DEF = "RanSizHG.def"; char* RanSizXH_DEF = "RanSizXH.def"; char* RanSizGT_DEF = "RanSizGT.def"; char* RanSizU_DEF = "RanUndr.def";
// переменная для проверки стартовала ли игра (т.е. видима ли уже карта) // например диалог повышения уровня при старте карты пропускается из-за неё #define o_StartGame_SkipDialogs (*(_int_*)0x698450)
/////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////
int __stdcall Y_NewScenarioDlg_Proc(HiHook* hook, _NewScenarioDlg_* sDlg, _EventMsg_* msg) { // делаем ПКМ на кнопках размера карты при создании "случайной карты" if (msg->type == MT_MOUSEBUTTON) { if(msg->subtype == MST_RBUTTONDOWN) { if ( msg->item_id >= BTTNID_S && msg->item_id <= BTTNID_XL ) { int size = (msg->item_id -BTTNID_S +1) *MAPSIZE_S; sprintf(MyString, "{%s:} %d x %d", o_GENRLTXT_TXT->GetString(754), size, size); b_MsgBox(MyString, 4); return 1;
}
if (msg->item_id >= BTTNID_H && msg->item_id <= BTTNID_G ) { int size = (msg->item_id -BTTNID_H +5) *MAPSIZE_S; sprintf(MyString, "{%s:} %d x %d", o_GENRLTXT_TXT->GetString(754), size, size); b_MsgBox(MyString, 4); return 1; } //sprintf(MyString, "id: %d", msg->item_id); //b_MsgBox(MyString, 4); //return 1; } }
return CALL_2(int, __thiscall, hook->GetDefaultFunc(), sDlg, msg); }
/////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////
// вырезаем создание кнопок игрой и создаём их сами int __stdcall Y_NewScenarioDlg_RandomMap_CreateButtons(LoHook* h, HookContext* c) { // получаем структуру диалога _NewScenarioDlg_* dlg = (_NewScenarioDlg_*)c->ebx; // создаём текст (размер карты) dlg->AddItemToOwnArrayList(_DlgStaticText_::Create(58, 82, 99, 31, o_GENRLTXT_TXT->GetString(754), SmallFont_FNT, 1, 280, ALIGN_H_CENTER | ALIGN_V_CENTER, 0)); // перекрываем этот текс и его обводку голубым фоном dlg->AddItemToOwnArrayList(_DlgStaticPcx8_::Create(56, 78, 102, 38, BTTNID_PCX, "DiBoxBlu.pcx")); // координаты кнопок int x = 57; int xh = 44; int xd = 43; int y = 81; int yh = 33; // стандартные кнопки: S, M, L, XL dlg->AddItemToOwnArrayList(_DlgButton_::Create(x + xd*0, y, xh, yh, BTTNID_S, RanSizS_DEF, 0, 1, 0, 0, 2)); dlg->AddItemToOwnArrayList(_DlgButton_::Create(x + xd*1, y, xh, yh, BTTNID_M, RanSizM_DEF, 0, 1, 0, 0, 2)); dlg->AddItemToOwnArrayList(_DlgButton_::Create(x + xd*2, y, xh, yh, BTTNID_L, RanSizL_DEF, 0, 1, 0, 0, 2)); dlg->AddItemToOwnArrayList(_DlgButton_::Create(x + xd*3, y, xh, yh, BTTNID_XL, RanSizXL_DEF, 0, 1, 0, 0, 2)); // новые кнопки: H, XH, G dlg->AddItemToOwnArrayList(_DlgButton_::Create(x + xd*4, y, xh, yh, BTTNID_H, RanSizHG_DEF, 0, 1, 0, 0, 2)); dlg->AddItemToOwnArrayList(_DlgButton_::Create(x + xd*5, y, xh, yh, BTTNID_XH, RanSizXH_DEF, 0, 1, 0, 0, 2)); dlg->AddItemToOwnArrayList(_DlgButton_::Create(x + xd*6, y, xh, yh, BTTNID_G, RanSizGT_DEF, 0, 1, 0, 0, 2)); // кнопка подземелья dlg->AddItemToOwnArrayList(_DlgButton_::Create(x + xd*7, y, xh, yh, BTTNID_U, RanSizU_DEF, 0, 1, 0, 0, 2)); // пропускаем оригинальный код игры c->return_address = 0x57D6CC; return NO_EXEC_DEFAULT; }
int DlgItem_SendCommand(_Dlg_* dlg, int itemID, int enable) { if (enable) // DlgItem_Send5Cmd2Item return CALL_3(int, __thiscall, 0x5FF490, dlg, itemID, 16); else // DlgItem_Send6Cmd2Item return CALL_3(int, __thiscall, 0x5FF520, dlg, itemID, 16); }
/////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////
char Y_NewScenarioDlg_RandomMap_CALL_UpdateButtons(_NewScenarioDlg_* dlg, int mapSize) { *(int*)((int)dlg + 6304) = mapSize; CALL_1(char, __thiscall, 0x57F240, dlg); dlg->Redraw(0); CALL_1(signed int, __thiscall, 0x584820, dlg);
return 0; }
int __stdcall Y_NewScenarioDlg_RandomMap_UpdateButtons(LoHook* h, HookContext* c) { // получаем структуру диалога _NewScenarioDlg_* dlg = (_NewScenarioDlg_*)c->esi;
// отключаем все старые кнопки DlgItem_SendCommand(dlg, BTTNID_S, 0); DlgItem_SendCommand(dlg, BTTNID_M, 0); DlgItem_SendCommand(dlg, BTTNID_L, 0); DlgItem_SendCommand(dlg, BTTNID_XL, 0); // отключаем все новые кнопки DlgItem_SendCommand(dlg, BTTNID_H, 0); DlgItem_SendCommand(dlg, BTTNID_XH, 0); DlgItem_SendCommand(dlg, BTTNID_G, 0);
// тут код включения нужной кнопки // в зависимости от размера карты 0x57F270 int mapSize = *(int*)((int)dlg + 6304);
if (mapSize == MAPSIZE_S) DlgItem_SendCommand(dlg, BTTNID_S, 1);
if (mapSize == MAPSIZE_M) DlgItem_SendCommand(dlg, BTTNID_M, 1);
if (mapSize == MAPSIZE_L) DlgItem_SendCommand(dlg, BTTNID_L, 1);
if (mapSize == MAPSIZE_XL) DlgItem_SendCommand(dlg, BTTNID_XL, 1);
if (mapSize == MAPSIZE_H) DlgItem_SendCommand(dlg, BTTNID_H, 1);
if (mapSize == MAPSIZE_XH) DlgItem_SendCommand(dlg, BTTNID_XH, 1); if (mapSize == MAPSIZE_G) DlgItem_SendCommand(dlg, BTTNID_G, 1);
c->return_address = 0x57F2B6; return NO_EXEC_DEFAULT; }
int __stdcall Y_NewScenarioDlg_RandomMap_CallUpdateButtons(HiHook* hook, _NewScenarioDlg_* dlg, _EventMsg_* msg, int a3, int a4) { if (msg->item_id == BTTNID_H) return Y_NewScenarioDlg_RandomMap_CALL_UpdateButtons(dlg, MAPSIZE_H);
if (msg->item_id == BTTNID_XH) return Y_NewScenarioDlg_RandomMap_CALL_UpdateButtons(dlg, MAPSIZE_XH);
if (msg->item_id == BTTNID_G) return Y_NewScenarioDlg_RandomMap_CALL_UpdateButtons(dlg, MAPSIZE_G);
return CALL_4(int, __thiscall, hook->GetDefaultFunc(), dlg, msg, a3, a4); }
// показать кнопки int __stdcall Y_NewScenarioDlg_RandomMap_ShowButtons(LoHook* h, HookContext* c) { // получаем структуру диалога _NewScenarioDlg_* dlg = (_NewScenarioDlg_*)c->esi;
_DlgItem_* item;
item = dlg->GetItem(BTTNID_PCX); if (item) item->Show();
item = dlg->GetItem(BTTNID_H); if (item) item->Show();
item = dlg->GetItem(BTTNID_XH); if (item) item->Show();
item = dlg->GetItem(BTTNID_G); if (item) item->Show();
return EXEC_DEFAULT; }
// скрыть кнопки int __stdcall Y_NewScenarioDlg_RandomMap_HideButtons(LoHook* h, HookContext* c) { // получаем структуру диалога _NewScenarioDlg_* dlg = (_NewScenarioDlg_*)c->esi;
_DlgItem_* item;
item = dlg->GetItem(BTTNID_PCX); if (item) item->Hide();
item = dlg->GetItem(BTTNID_H); if (item) item->Hide();
item = dlg->GetItem(BTTNID_XH); if (item) item->Hide();
item = dlg->GetItem(BTTNID_G); if (item) item->Hide();
return EXEC_DEFAULT; }
// патч: фикс вылета при загрузке/старте карты int __stdcall Y_Fix_OpenArea(LoHook* h, HookContext* c) { if (o_StartGame_SkipDialogs) { c->return_address = 0x49D026; return NO_EXEC_DEFAULT; }
return EXEC_DEFAULT; }
/////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////
void StartPlugin() { _PI->WriteHiHook(0x587FD0, SPLICE_, EXTENDED_, THISCALL_, Y_NewScenarioDlg_Proc);
// вырезаем создание кнопок игрой и создаём их сами _PI->WriteCodePatch(0x57D49B, "%n", 2); _PI->WriteLoHook(0x57D4A6, Y_NewScenarioDlg_RandomMap_CreateButtons);
// показать кнопки _PI->WriteLoHook(0x5801E1, Y_NewScenarioDlg_RandomMap_ShowButtons);
// скрыть кнопки _PI->WriteLoHook(0x5820A6, Y_NewScenarioDlg_RandomMap_HideButtons);
// подсветка нужной кнопки случайной карты _PI->WriteLoHook(0x57F258, Y_NewScenarioDlg_RandomMap_UpdateButtons);
// нажатия кнопок обрабатывать тут 0x586938 -> 0x586FEB _PI->WriteHiHook(0x586880, SPLICE_, EXTENDED_, THISCALL_, Y_NewScenarioDlg_RandomMap_CallUpdateButtons);
// читы: радиус открытия/закрытия карты _PI->WriteDword(0x4026F9 +1, 356); _PI->WriteDword(0x402750 +1, 356); _PI->WriteDword(0x4F4B56 +1, 356);
// патч: фикс вылета при загрузке/старте карты _PI->WriteLoHook(0x49CFFA, Y_Fix_OpenArea);
// решение проблемы вылета игры при загрузке сохранения // суть: __int16 в __uint16 (делаем беззнаковое) _PI->WriteByte(0x49B96F +1, 0xB7); // загрузка (change MOVSX to MOVZX) _PI->WriteByte(0x49BAA2, 0x76); // сохранение (change JLE to JBE) _PI->WriteByte(0x49BAB4 +1, 0xB7); // сохранение (change MOVSX to MOVZX) _PI->WriteByte(0x49BABB, 0x72); // сохранение (change JL to JB)
/////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////
BOOL APIENTRY DllMain ( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { static _bool_ initialized = 0; switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: if (!initialized) { initialized = 1;
_P = GetPatcher(); _PI = _P->CreateInstance("igrik.XXL");
StartPlugin(); } break;
case DLL_PROCESS_DETACH: if (initialized) initialized = 0; break;
case DLL_THREAD_ATTACH: break;
case DLL_THREAD_DETACH: break; } return TRUE; }
|