Объявления

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

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

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
offlineRoseKavalier  
Мастер
Мастер
 
Сообщения: 331
Зарегистрирован: 23 сен 2017, 17:00
Пол: Не указан
Поблагодарили: 234 раз.

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

Сообщение RoseKavalier » 15 июл 2019, 20:37

Get rid of _HH_DestroyDialog, it's the wrong place to hook.
Код: Выделить всё
HDDlg* __stdcall _HH_CloseDialog(HiHook *h, HDDlg *This, H3Msg *msg)
{
   if (P_NewGameDlg)
   {
      auto hw = This->GetH3DlgItem(1001);
      if (hw)
      {
         auto but = This->ItemAtPosition(msg);
         if (but && but->GetID() == 1) // cancel button is id #2
         {
            sprintf(h3_TextBuffer, "At close time, state was %d", hw->CastDef()->GetFrame());
            F_MessageBox();
         }
      }
   }

   return THISCALL_2(HDDlg*, h->GetDefaultFunc(), This, msg);
}



void GetHWproc()
{
...
_PI->WriteHiHook((h3func)&vt->closeDlg, FUNCPTR_, THISCALL_, _HH_CloseDialog); // only hook run dialog from HW mod
}


Also the text doesn't show up if you don't use the HDmod fonts, make its height greater or reduce font size.
 
Изображение


To get rid of toggling state - semi-press state is not used and do NOT use disable.
Код: Выделить всё
int __stdcall _HH_RunDialog(HiHook *h, HDDlg *dlg, int a2)
{
   auto ItemHWRules = dlg->GetH3DlgItem(1001);
   if (P_NewGameDlg && ItemHWRules) // if we're in lobby
   {
      HWRulesOn = ItemHWRules->CastDef()->GetFrame();
      int CheckBoxX = ItemHWRules->GetX() + 145;
      if (!HWRulesOn)
         GamePlayChangesOn = FALSE;
      H3DlgCustomButton *FlagCheckBox = dlg->CreateCustomButton(CheckBoxX, ItemHWRules->GetY(), CheckBoxID, "ChkBlue.def", MyButtonProc, GamePlayChangesOn, GamePlayChangesOn);
      if (ItemHWRules->IsEnabled()) {
         sprintf(h3_TextBuffer, "{Gameplay changes (FreshMod %s)}", VerInfo);
         IsHost = true;
      }
      else {
         sprintf(h3_TextBuffer, "{Gameplay changes (FreshMod %s)}", VerInfo);
         IsHost = false;
      }
      dlg->CreateText(CheckBoxX + 41, ItemHWRules->GetY() + 6, 200, 25, h3_TextBuffer, MEDIUM_TEXT, TEXT_REGULAR, 0, 0);
   }
   return THISCALL_2(int, h->GetDefaultFunc(), dlg, a2); // run dialog
}

int __fastcall MyButtonProc(H3MsgCustom *msg)
{
   if (msg->IsLeftClick())
   {
      H3DlgCustomButton *b = (H3DlgCustomButton*)msg->GetDlg()->GetH3DlgItem(CheckBoxID);

      auto ItemHWRules = (H3DlgCustomButton*)msg->GetDlg()->GetH3DlgItem(1001);
      if (!ItemHWRules->CastDef()->GetFrame()) {

         return 1;
      }
      else
      {
         if (b) {
            b->ToggleFlag(GamePlayChangesOn);
            SendFlag();
         }
      }
   }
   else if (msg->IsRightClick())
   {
      sprintf(h3_TextBuffer, "Flag state is %d", GamePlayChangesOn);
      F_MessageBoxRMB();
   }

   return 1;
}
Вернуться к началу

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

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

Сообщение as239 » 16 июл 2019, 05:13

Thanks a lot! Now everything works fine!
Вернуться к началу

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

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

Сообщение Ben80 » 07 авг 2019, 13:30

Catastrophe писал(а):

Скопирую сюда, пожалуй, свои наработки из темы "как создать плагин для HD-мода".
Только исходный код, без готовых плагинов. Но лучше так, чем наоборот, не правда ли?


Catastrophe, тема "Пользовательские плагины" - именно для готовых плагинов, не для кода (код можно, но по желанию). Код в свободном формате как раз уместен в данной теме, либо в дополнительных частных (например, "Энциклопедия").

Те наработки, которые у меня были в этой теме, в принципе уже все перенесены в четком законченном виде в "Пользовательские плагины", либо в "Энциклопедию".

Я так понял, все продвинутые люди давно уже на гитхабе все держат, но меня и так устраивает.

Catastrophe писал(а):

Ben80 писал(а):

_Player_*
field_30[4]

Содержит тип ИИ (Воин, Строитель, Исследователь).

0 - случайный, 1 - воин, 2 - строитель, 3 - исследователь?


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

offlineАватара пользователя
Catastrophe  
имя: Alex
Посвященный
Посвященный
 
Сообщения: 88
Зарегистрирован: 07 мар 2019, 11:50
Пол: Мужчина
Поблагодарили: 22 раз.

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

Сообщение Catastrophe » 10 авг 2019, 04:47

Фикс нежелания отображаться и давать бонусы в подземелье всех ландшафтов, кроме подземного:
Код: Выделить всё
_PI->WriteByte(0x464044, 0xEB);
Быстрее всего смогу ответить вам в Telegram: @PleaseAndThankYou
Вернуться к началу

offlineАватара пользователя
Catastrophe  
имя: Alex
Посвященный
Посвященный
 
Сообщения: 88
Зарегистрирован: 07 мар 2019, 11:50
Пол: Мужчина
Поблагодарили: 22 раз.

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

Сообщение Catastrophe » 10 авг 2019, 09:04

Делаем костяных и призрачных драконов более страшными :)
 
Изображение

Поскольку в оригинальном коде используется декремент и нет места на низкий хук, я затер оригинальную проверку и повесил на ее место свою.
Код: Выделить всё
int __stdcall c_bonedragons(LoHook* h, HookContext* c)
{
   if ( *(_dword_*)(c->edx) == 68 )
   {
      c->ebx -= 2;
   }
   return EXEC_DEFAULT;
}

int __stdcall c_ghostdragons(LoHook* h, HookContext* c)
{
   if ( *(_dword_*)(c->ecx) == 69 )
   {
      c->ebx -= 3;
   }
   return EXEC_DEFAULT;
}

         _PI->WriteByte(0x44AD2D, 0x90); // nop
         _PI->WriteLoHook(0x44AD0D, c_bonedragons);
         _PI->WriteLoHook(0x44AD1D, c_ghostdragons);


Только такая проблема: количество морали отображается правильно, но в обосновании пишет по прежнему -1, как можно поправить?
 
Изображение
Последний раз редактировалось Catastrophe 10 авг 2019, 09:32, всего редактировалось 3 раз(а).
Быстрее всего смогу ответить вам в Telegram: @PleaseAndThankYou
Вернуться к началу

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

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

Сообщение as239 » 10 авг 2019, 09:10

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

offlineАватара пользователя
Catastrophe  
имя: Alex
Посвященный
Посвященный
 
Сообщения: 88
Зарегистрирован: 07 мар 2019, 11:50
Пол: Мужчина
Поблагодарили: 22 раз.

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

Сообщение Catastrophe » 10 авг 2019, 10:23

Удваиваем штраф за несколько мировоззрений в армии.
Код: Выделить всё
int __stdcall c_morale_penalty(LoHook* h, HookContext* c)
{
   c->edi <<= 1;
   return EXEC_DEFAULT;
}

         _PI->WriteDword(0x44AC96, 3); // offset, default is 2
         _PI->WriteLoHook(0x44AC95, c_morale_penalty);

 
Изображение

Либо утраиваем. Чисто лишний пример, чтобы легко понять принцип.
Код: Выделить всё
int __stdcall c_morale_penalty(LoHook* h, HookContext* c)
{
   c->edi *= 3;
   return EXEC_DEFAULT;
}

         _PI->WriteDword(0x44AC96, 4); // offset, default is 2
         _PI->WriteLoHook(0x44AC95, c_morale_penalty);

Оффсет увеличиваем для того, чтобы не получить отрицательную мораль даже с одним мировозррением в армии.

Данный метод действует и на нейтралов, то есть, например, мораль драконов в утопиях будет ниже 0. Продолжаем исследования, хочу дать бонусы нейтралам.
Быстрее всего смогу ответить вам в Telegram: @PleaseAndThankYou
Вернуться к началу

offlineАватара пользователя
Catastrophe  
имя: Alex
Посвященный
Посвященный
 
Сообщения: 88
Зарегистрирован: 07 мар 2019, 11:50
Пол: Мужчина
Поблагодарили: 22 раз.

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

Сообщение Catastrophe » 10 авг 2019, 12:13

Доделал бонусы и штрафы к морали и удаче от существ - хорошие: +1/+2, плохие: -2/-3

Код: Выделить всё
int __stdcall c_bonedragons(LoHook* h, HookContext* c)
{
   if ( *(_dword_*)(c->edx) == 68 )
   {
      c->ebx -= 2;
   }
   return EXEC_DEFAULT;
}

int __stdcall c_ghostdragons(LoHook* h, HookContext* c)
{
   if ( *(_dword_*)(c->ecx) == 69 )
   {
      c->ebx -= 3;
   }
   return EXEC_DEFAULT;
}

int __stdcall c_angels(LoHook* h, HookContext* c)
{
   if ( *(_dword_*)(c->ecx) == 12 )
   {
      c->ebx++;
   }
   return EXEC_DEFAULT;
}

int __stdcall c_archangels(LoHook* h, HookContext* c)
{
   if ( *(_dword_*)(c->ecx) == 13 )
   {
      c->ebx += 2;
   }
   return EXEC_DEFAULT;
}

int __stdcall c_devils(LoHook* h, HookContext* c)
{
   if ( *(_dword_*)(c->esi) == 54 )
   {
      c->eax -= 2;
   }
   return EXEC_DEFAULT;
}

int __stdcall c_archdevils(LoHook* h, HookContext* c)
{
   if ( *(_dword_*)(c->edx) == 55 )
   {
      c->eax -= 3;
   }
   return EXEC_DEFAULT;
}

         // remove original bonuses
         _PI->WriteByte(0x44AD01, 0x90);
         _PI->WriteByte(0x44AD2D, 0x90);
         _PI->WriteByte(0x44B01F, 0x90);

         // morale and luck creature bonuses
         _PI->WriteLoHook(0x44ACDF, c_angels);
         _PI->WriteLoHook(0x44ACF1, c_archangels);
         _PI->WriteLoHook(0x44AD0D, c_bonedragons);
         _PI->WriteLoHook(0x44AD1D, c_ghostdragons);
         _PI->WriteLoHook(0x44AFFF, c_devils);
         _PI->WriteLoHook(0x44B00F, c_archdevils);
Быстрее всего смогу ответить вам в Telegram: @PleaseAndThankYou
Вернуться к началу

offlineАватара пользователя
Catastrophe  
имя: Alex
Посвященный
Посвященный
 
Сообщения: 88
Зарегистрирован: 07 мар 2019, 11:50
Пол: Мужчина
Поблагодарили: 22 раз.

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

Сообщение Catastrophe » 10 авг 2019, 13:26

Может, уже постил, просто щас буду дополнять это. Убираем рандом из случайных карт.

Герои всегда получают второй и третий стек существ. Жилище 2 уровня появляется с 100% шансом.
Код: Выделить всё
         // heroes always get 2nd stack
         _PI->WriteDword(0x4C948F +1, 2);
         // heroes always get 3rd stack
         _PI->WriteDword(0x4C950F +1, 2);
         // towns always get level 2 dwelling
         _PI->WriteDword(0x5C1051 +1, 2);

А вот код для строительства вообще любого здания по вашему желанию.
 
Изображение

Шанс его появления по идее равен жилищу 2 лвла, то есть, если используете код выше, оно точно будет появляться всегда.
Код: Выделить всё
int __stdcall c_rmg_build(LoHook* h, HookContext* c)
{
   CALL_2(_int_, __thiscall, 0x5BED30, c->esi, 0); // lvl 1 mage guild
   CALL_2(_int_, __thiscall, 0x5BED30, c->esi, 32); // lvl 3 dwelling
   CALL_2(_int_, __thiscall, 0x5BED30, c->esi, 11); // prefecture

   return EXEC_DEFAULT;
}

         _PI->WriteLoHook(0x5C106E, c_rmg_build);

Все id зданий (не для каждого замка, а именно для случайных)
 
0 Гильдия магов уровня 1
1 Гильдия магов уровня 2
2 Гильдия магов уровня 3
3 Гильдия магов уровня 4
4 Гильдия магов уровня 5
5 Таверна
6 Верфь (0,4,7,8); ??? (1,2,3,5,6)
7 Форт
8 Цитадель
9 Замок
10 Сельская управа
11 Префектура
12 Муниципалитет
13 Капитолий
14 Рынок
15 Хранилище ресурсов
16 Кузница
17 Маяк (0), Таинственный пруд (1), Торговцы артефактами (2,5,8), ??? (3), Вуаль Тьмы (4), Черный ход (6), Клетка богов Войны (7)
18 Строение орды для неулучшенных существ: Грифонов, Гномов, Каменных Горгулий, Бесов, Скелетов, Троглодитов, Гоблинов, Гноллов, Маленьких Фей
19 Строение орды для улучшенных существ: Королевские Грифоны, Боевые Гномы, Обсидиановые Горгульи, Прилипалы, Скелеты-Воины, Адские Троглодиты, Хобгоблины, Гноллы-Мародеры, Феи
20 ??? (0,1,2,3,4,5,6,7,8)
21 Конюшни (0), Фонтан Удачи (1), Смотровая башня (2), Серные Тучи (3), Усилитель Некромантии (4), Водоворот Маны (5), Гильдия наемников (6), Знаки страха (7), Университет магии (8)
22 Братство Меча (0), Сокровищница гномов (1), Библиотека (2), Врата замка (3), Трансформатор Скелетов (4), Портал Вызова (5), Двор Баллист (6), Кровавый Обелиск (7), ??? (8)
23 ??? (0,1,4,7,8), Стена Знаний (2), Орден Огня (3), Академия боевых искусств (5), Храм Валгаллы (6)
24 ??? (0,2,4,5,6,7,8), Строение орды для неулучшенных существ: Дендроиды-стражники, Адские гончие
25 ??? (0,2,4,5,6,7,8), Строение орды для улучшенных существ: Дендроиды-солдаты, Церберы
26 Грааль
27 ??? (все)
28 ??? (все)
29 ??? (все)
30 Жилище 1го уровня
31 Жилище 2го уровня
32 Жилище 3го уровня
33 Жилище 4го уровня
34 Жилище 5го уровня
35 Жилище 6го уровня
36 Жилище 7го уровня
37 Улучшенное жилище 1го уровня
38 Улучшенное жилище 2го уровня
39 Улучшенное жилище 3го уровня
40 Улучшенное жилище 4го уровня
41 Улучшенное жилище 5го уровня
42 Улучшенное жилище 6го уровня
43 Улучшенное жилище 7го уровня

Аналог XXL-патча из Era. Генератор всегда будет создавать карты указанного размера прямо в игре. Может потребоваться кастомный шаблон.
Код: Выделить всё
int __stdcall c_rmg_size(LoHook* h, HookContext* c)
{
   c->eax = 252; // x
   c->edx = 252; // y

   return EXEC_DEFAULT;
}

         _PI->WriteLoHook(0x54C4CD, c_rmg_size);

Поскольку чит на открытие карты работает как обсерватории, нужно увеличить его радиус для подобных карт:
Код: Выделить всё
         _PI->WriteDword(0x4026FA, 0x200);
Быстрее всего смогу ответить вам в Telegram: @PleaseAndThankYou
Вернуться к началу

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

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

Сообщение as239 » 11 авг 2019, 08:05

Хочу чтобы при нажатии на мой флаг "Gameplay changes", флаг "Всегда 2 стек у героя" устанавливался.
А при отжатии сбрасывался.
Этот код при нажатии работает верно. А вот когда отжимаешь флаг "Gameplay changes", флаг "Всегда 2 стек у героя" не сбрасывается, что не так?
Код: Выделить всё
int __fastcall MyButtonProc(H3MsgCustom *msg)
{
   if (msg->IsLeftClick())
   {
      H3DlgCustomButton *b = (H3DlgCustomButton*)msg->GetDlg()->GetH3DlgItem(CheckBoxID);
      auto ItemHWRules = (H3DlgCustomButton*)msg->GetDlg()->GetH3DlgItem(HWRulesID);
      if (!ItemHWRules->IsEnabled()){
         return 1;
      }

      if (b) {

         auto Item2Stack = (H3DlgCustomButton*)msg->GetDlg()->GetH3DlgItem(101);
         Item2Stack->ToggleFlag(GamePlayChangesOn);

         b->ToggleFlag(GamePlayChangesOn);

      }
   }

   return 1;
}
Вернуться к началу

Пред.След.

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

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

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

cron