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


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

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

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

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

Сообщение Ben80 » 22 июн 2019, 05:19

Спасибо.
Я, Ben80, не видел его, иначе бы не написал так. Проглядел, может быть.
Вернуться к началу

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

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

Сообщение as239 » 23 июн 2019, 09:42

@Ben80
Не знаю как я тестировал раньше, но сейчас я вижу что сообщение в сетевой чат отправляет только один, последний игрок:
Код: Выделить всё
int __stdcall send2Chat(LoHook* h, HookContext* c) {
   char* mes = "Plugin <Fresh Mod 3.0> is used";
   if( o_NetworkGame && o_GameMgr->curr_day_ix == 2 &&
      o_GameMgr->curr_week_ix == 1 && o_GameMgr->curr_month_ix == 1 && o_GameMgr->GetPlayer(o_ActivePlayerID)->IsHuman() )
      CALL_2(char, __fastcall, 0x554BB0, mes, 127);
   return EXEC_DEFAULT;
}
_PI->WriteLoHook(0x4C7207, send2Chat);
Вернуться к началу

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

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

Сообщение Ben80 » 23 июн 2019, 10:52

Вот правильная реализация данной задумки - сообщение появляется при загрузке окна приключений - сразу при начале игры, и каждый раз при загрузке игры - тоже сразу.

Код: Выделить всё
bool gChat;
...
int __stdcall send2Chat(LoHook* h, HookContext* c)
{
   char* mes = "Fresh";

   if(o_NetworkGame && gChat == 1)
   {
      gChat = false;
      CALL_2(char, __fastcall, 0x554BB0, mes, 127);
   }

   return EXEC_DEFAULT;
}

int __stdcall setChatTrigger(LoHook* h, HookContext* c)
{
   gChat = true;

   return EXEC_DEFAULT;
}
...
// Chat message - info about Mod and options used
_PI->WriteLoHook(0x406F60, send2Chat);

// Для Загрузить игру
_PI->WriteLoHook(0x4BEFF0, setChatTrigger);
         
// Для Новой игры
_PI->WriteLoHook(0x4C018D, setChatTrigger);

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

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

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

Сообщение Catastrophe » 23 июн 2019, 22:57

igrik писал(а):

Если кому интересно, то вот код, запрещающий генерироваться тюрмам с героями выше 1-го уровня только на случайных картах.

Мне интересно )) всегда рад таким подаркам
Быстрее всего смогу ответить вам в Telegram: @PleaseAndThankYou
Вернуться к началу

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

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

Сообщение as239 » 24 июн 2019, 05:07

Цитата:
Вот правильная реализация данной задумки - сообщение появляется при загрузке окна приключений - сразу при начале игры, и каждый раз при загрузке игры - тоже сразу.

Большое спасибо! Так действительно правильнее и работает как нужно.
Вернуться к началу

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

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

Сообщение Catastrophe » 24 июн 2019, 06:28

Делюсь нововведением в Ad Fontes v1.2 - новые типы специализации по спеллам. Бонус тем больше, чем больше уровень существа. (1/2/3 и 3/6/9)
Заменяют типы специализации по удаче и разрушающему лучу. По умолчанию используется для Печали, Неудачи, Слабости и Разрушающего Луча.
 
Изображение

Код: Выделить всё
int c_spec_spell_array[7] = {0, 3, 3, 6, 6, 9, 9};

int __stdcall c_spec_spell_reverse(LoHook* h, HookContext* c)
{
   int jedn = IntAt(c->ebp+0xC); // just in case
   c->eax = c_spec_spell_array[jedn];

   return EXEC_DEFAULT;
}

int c_spec_spell_aray[7] = {0, 1, 1, 2, 2, 3, 3};

int __stdcall c_spec_spell_ray(LoHook* h, HookContext* c)
{
   int jedn = IntAt(c->ebp+0xC); // just in case
   c->eax = c_spec_spell_aray[jedn];

   return EXEC_DEFAULT;
}

// bool apientry dllmain

         _PI->WriteHexPatch(0x4E6291, "8D 46 E5"); // lea eax, [esi-13] -> lea eax, [esi-27]
         // spell spec table is limited to 43 entries + it skips first 13 entries (non-battle ones)
         // spells which are not included in this table will use id 06 (default damage formula)
         // this change makes the game skip first 27 entries instead of 13, to include ALL spells
         _PI->WriteByte(0x4E6296, 69); // spells with id more than 42 -> 69 are not included

         // spell specialty table
         _PI->WriteHexPatch(0x4E6358, "00 00 00 00 00 00 00 00 00 01 00 01 01 01 01 01 02 02 03 02 04 02 02 03 02 03 02 00 05 01 00 00 00 01 00 00 00 00 00 01 01 01 01");
         // 00 = +100% fixed bonus
         // 01 = +50% fixed bonus
         // 02 = 3/3/2/2/1/1/0 bonus per creature level
         // 03 = 0/3/3/6/6/9/9 bonus per creature level
         // 04 = 0/1/1/2/2/3/3 bonus per creature level
         // 05 = 9/9/6/6/3/3/0 bonus per creature level
         _PI->WriteJmp(0x4E62FD, 0x4E62F1); // redirect all 06 (default) to 01

         // replacing luck spell specialty
         _PI->WriteHexPatch(0x4E62E5, "8B 45 0C 90 90"); // mov eax, 2 -> mov eax, [ebp+0xC]
         _PI->WriteLoHook(0x4E62EB, c_spec_spell_reverse);

         // replacing disrupting ray specialty
         _PI->WriteHexPatch(0x4E62CA, "8B 45 0C 90 90 90 90 90 90 90"); // mov eax, [ebp+0xC]
         _PI->WriteLoHook(0x4E62D5, c_spec_spell_ray);
Последний раз редактировалось Catastrophe 24 июн 2019, 08:13, всего редактировалось 2 раз(а).
Быстрее всего смогу ответить вам в Telegram: @PleaseAndThankYou
Вернуться к началу

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

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

Сообщение as239 » 24 июн 2019, 06:57

@RoseKavalier
Found that after completing a simultaneous turns, the calculation of move points does not work for an inactive player.
Is it possible to fix this?
Код: Выделить всё
int __stdcall MapHintCoordinates(LoHook* h, HookContext* c)
{
   if ( (GetAsyncKeyState(VK_LMENU) & 0x8000) || (GetAsyncKeyState(VK_RMENU) & 0x8000) ) {
      H3AdventureManager *adv = P_AdventureMgr;
      UINT32 mixedDestination = adv->mousePosition.Mixed();
      adv->MovementCalculations(mixedDestination);
      H3TileMovement *mvmt = P_MovementMgr->GetMovementInfo(mixedDestination);
      if (!mvmt) return EXEC_DEFAULT;
      if (mvmt->access.accessible) {
         sprintf(h3_TextBuffer, "Movements: %d - %d = {%d}", P_MovementMgr->available_movement, mvmt->movementCost, P_MovementMgr->available_movement-mvmt->movementCost );
      }
   }
   return EXEC_DEFAULT;
}
Вернуться к началу

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 » 24 июн 2019, 15:14

Сегодня поигрался немного с курсорами. Почти всё получилось, кроме:

1) при зажатии шифта, когда курсор находится прямо над героем, курсор приобретает форму шлема, только если чуть сдвинуть мышку;
2) если герой центрирован (только что был активирован и теперь находится по центру карты), то курсор не изменяется.

По первому пункту: кто-нибудь знает, как обновить курсор прямо здесь и сейчас? :smile1: Сейчас он обновляется либо при его перемещении на другой тайл (моя первая попытка), либо просто при изменении координат. По второму: в Героях 1 у тайла с центрированным героем устанавливается специальный бит (если даже хоть немного проскроллить карту, он сбрасывается). Есть ли что-то аналогичное в Героях 3?

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

* * *
Хуки ставлю на функцию sub_0040E2C0. Если установить ecx = -1 здесь: 40E495h, проблема курсоров частично решается (кроме упомянутых выше проблем).
Вернуться к началу

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

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

Сообщение igrik » 24 июн 2019, 15:58

AlexSpl писал(а):

кто-нибудь знает, как обновить курсор прямо здесь и сейчас? :smile1:
По-хорошему, конечно, нужно писать свой алгоритм, который будет проверять, что находится под курсором, когда зажат шифт, и вызывать функцию SetMouseCursor().

Вроде так:
Код: Выделить всё
   // установить курсор(0,0)
   CALL_3 (void, __thiscall, 0x50CEA0, o_MouseMgr, 0, 0);
   CALL_2 (void, __thiscall, 0x50D7B0, o_MouseMgr, 0);


Вообще, обновление курсора на КП происходит в районе этого адреса 0x40E676 (в нескольких местах, смотря над чем курсор)
Вернуться к началу

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 » 24 июн 2019, 16:05

Код: Выделить всё
// установить курсор(0,0)
CALL_3 (void, __thiscall, 0x50CEA0, o_MouseMgr, 0, 0);
CALL_2 (void, __thiscall, 0x50D7B0, o_MouseMgr, 0);

Спасибо. Буду пробовать.

Цитата:
Вообще, обновление курсора на КП происходит в районе этого адреса 0x40E676 (в нескольких местах, смотря над чем курсор)

Я их все нашёл и разобрался, но у меня подозрение, что функция sub_0040E2C0 вызывается только при смене координат курсора, что нас не устраивает. Хотя смена тайла проверяется здесь же :smile5:

Ещё после большинства вызовов SetMouseCursor() следует инструкция типа

Код: Выделить всё
mov     dword ptr [esi+40h], 2

Интересно, что она делает?

* * *
Так и есть, функция sub_0040E2C0 вызывается при изменении координат курсора. При неподвижном курсоре она не вызывается. Нужно искать другой способ.
Последний раз редактировалось AlexSpl 24 июн 2019, 16:36, всего редактировалось 2 раз(а).
Вернуться к началу

Пред.След.

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

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

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