Объявления

Форум о Героях Меча и Магии и King's Bounty. Если Вы любите эти игры, мы будем рады видеть Вас в наших рядах. :smile2:

Пользовательские плагины для HD мода

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 4844
Зарегистрирован: 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)
Поблагодарили: 1838 раз.

Re: Пользовательские плагины для HD мода

Сообщение AlexSpl » 02 ноя 2021, 21:28

It's OK. We can always build it. Try to upload .zip file next time, there're restrictions on extensions.
Вернуться к началу

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

Re: Пользовательские плагины для HD мода

Сообщение AlexSpl » 05 ноя 2021, 09:17

Авторы: AlexSpl, Rolex

Название: NewSpells

Описание: Добавляет в игру 16 новых заклинаний: 14 боевых и 2 походных.

Список новых заклинаний

Школа Магии Земли (5): Poison, Disease, Fear, Death Cloud, Drain Life.
Школа Магии Огня (7): Mobility (походное), Age, Death Blow, Behemoth's Claws, Incineration, Explosion, Summon Firebird.
Школа Магии Воды (1): Toughness.
Школа Магии Воздуха (2): Eye of the Magi (походное), Summon Sprite.
Все магические школы (1): Summon Magic Elemental.

NewSpells.zip
1.03 preview 4
(529.7 КБ) Скачиваний: 40

 Код
Код: Выделить всё
Код плагина находится в папке Source архива NewSpells.zip.
Вернуться к началу

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

Re: Пользовательские плагины для HD мода

Сообщение igrik » 31 дек 2021, 06:43

Так как я вижу никто плагин так и не скомпилировал...

Название: XXL-мод (SOD)

Автор: igrik

Описание: В дополнение к стандартному набору размеров, мод добавляет поддержку очень больших карт, но только при генерации случайных карт:
- H (180x180)
- XH (216x216)
- G (252x252)

Кнопки выбора случайной карты использованы из HoMM3 HotA.

 Скриншот
Изображение
Вложения
XXL.rar
(216.45 КБ) Скачиваний: 17
Последний раз редактировалось igrik 03 янв 2022, 08:17, всего редактировалось 2 раз(а).
Вернуться к началу

offlinevoid_17  
имя: DM
Мастер
Мастер
 
Сообщения: 310
Зарегистрирован: 25 апр 2021, 15:05
Откуда: Оттуда
Пол: Мужчина
Поблагодарили: 32 раз.

Re: Пользовательские плагины для HD мода

Сообщение void_17 » 31 дек 2021, 07:33

Хороший мод! И реализация его интересная, будет полезно всем, кто интерфейсом занимается.

Вы не против, что я в группе вк выложу и укажу вас как автора?
Вернуться к началу

offlineRolex  
имя: Alex
Ветеран
Ветеран
 
Сообщения: 880
Зарегистрирован: 22 сен 2020, 18:58
Пол: Мужчина
Поблагодарили: 47 раз.

Re: Пользовательские плагины для HD мода

Сообщение Rolex » 31 дек 2021, 10:06

igrik писал(а):

Так как я вижу никто плагин так и не скомпилировал...

Отлично. Хороший подарок фанатам Героев на НГ. :smile1:

Только вот не вижу сам плагин (*.dll) и его код. Вижу только описание плагина, ссылку на галерею с картинками HotA и скрин с кнопками. :smile5:
Вернуться к началу

offlinevoid_17  
имя: DM
Мастер
Мастер
 
Сообщения: 310
Зарегистрирован: 25 апр 2021, 15:05
Откуда: Оттуда
Пол: Мужчина
Поблагодарили: 32 раз.

Re: Пользовательские плагины для HD мода

Сообщение void_17 » 31 дек 2021, 12:12

Rolex писал(а):

igrik писал(а):

Так как я вижу никто плагин так и не скомпилировал...

Отлично. Хороший подарок фанатам Героев на НГ. :smile1:

Только вот не вижу сам плагин (*.dll) и его код. Вижу только описание плагина, ссылку на галерею с картинками HotA и скрин с кнопками. :smile5:


Код: Выделить всё
#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;
}
Вернуться к началу

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

Re: Пользовательские плагины для HD мода

Сообщение igrik » 03 янв 2022, 08:20

Простите, завтыкал я прикрепить dll :smile15:
Теперь прикрепил.

В идеале бы ещё нужно добавить шаблонов rmg.txt. Но в шаблонах я не шарю.

Для модераторов: думаю последние 4 сообщения нужно убрать из этой темы, чтобы не захламлять её.
Вернуться к началу

offlineRolex  
имя: Alex
Ветеран
Ветеран
 
Сообщения: 880
Зарегистрирован: 22 сен 2020, 18:58
Пол: Мужчина
Поблагодарили: 47 раз.

Re: Пользовательские плагины для HD мода

Сообщение Rolex » 03 янв 2022, 10:18

igrik писал(а):

В идеале бы ещё нужно добавить шаблонов rmg.txt. Но в шаблонах я не шарю.

Плюс к шаблонам было бы еще хорошо все файлы запаковать в lod и доработаь код так, чтобы этот lod подтягивался так, как это происходит в SoD_SP или NewSpells.

Да, последниие 5 сообщений включая мое здесь явно лишние. Плюс еще два сообщение перед постом с NewSpells.
Вернуться к началу

offlinemeo  
имя: Евгений
 
Сообщения: 1
Зарегистрирован: 14 янв 2022, 13:55
Пол: Мужчина
Поблагодарили: 0 раз.

Re: Пользовательские плагины для HD мода

Сообщение meo » 14 янв 2022, 14:08

Уважаемые магистры кода!
У меня обращение к Вам от части комьюнити тру-SoDовиков, в последнее время с завистью поглядывающей на фанатов мода HotA, балующихся многочисленными апгрейдами интерфейса и баланса. Кое-то хочется иметь и для классики.
Есть "фрэш-мод" - сборник твиков, по-видимому, авторства завсегдатая данного многоуважаемого форума. Но он ограничен в настройках - вкл\выкл, хотя не всем нравятся навязываемые родные ульеконсы и т.п.
Отсюда мольба и деловое предложение на создание сборника имеющихся и возможных к созданию модов с максимальным количеством галок в настройках создаваемой игры.
Вернуться к началу

offlinevoid_17  
имя: DM
Мастер
Мастер
 
Сообщения: 310
Зарегистрирован: 25 апр 2021, 15:05
Откуда: Оттуда
Пол: Мужчина
Поблагодарили: 32 раз.

Re: Пользовательские плагины для HD мода

Сообщение void_17 » 14 янв 2022, 15:52

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

Пред.

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

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

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