Объявления

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

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

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

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

Сообщение Ben80 » 09 авг 2017, 19:18

Для Мелодии думаю сделать эффект специализации +25% (то есть для нее заклинание Удача +50/75/125%).
И измерять эффект для нее именно в процентах, а не в долях.
Наверно, вот по этому адресу бонус для Мелодии 004E62CD, видимо, нужно поменять "mov eax, 3" на "mov eax, 25".
И при этом "sub eax, ecx" заменить на NOPы.
Вернуться к началу

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

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

Сообщение AlexSpl » 10 авг 2017, 00:53

Цитата:
Есть и более заковыристая проблема - хотел бы, чтобы заклинание Радость действовало так -
на любом уровне магии +1 к Морали отрядов и вероятность выпадения повторного хода (птички) должна увеличиваться на 25% на осн. уровне, на 50% на продвинутом и на 100% на эксперте.


Цитата:
Уточнение для заклинания Радость - увеличение вероятности (+25/50/100%) происходит только если мораль положительна.
Для заклинания Удача планируется такой же принцип действия (+1 к удаче и увеличение вероятности выпадения +25/50/100%).


Код: Выделить всё
int __stdcall mirthSpell(LoHook* h, HookContext* c)
{
   c->edi = 1;
   return EXEC_DEFAULT;
}

int __stdcall mirthMoraleBonus(LoHook* h, HookContext* c)
{
   int cmAddr = *(int*)0x699420; // Получаем адрес Combat Manager
   int monSide = *(int*)(c->edi + 244); // Получаем сторону, на которой сражается монстр
   int heroOffset = *(int*)(cmAddr + monSide * 4 + 0x53CC); // Получаем адрес героя, наложившего Mirth

   if ( !heroOffset ) return EXEC_DEFAULT;

   char lvlWaterMagic = *(char*)(heroOffset + 201 + 16);

   if ( *(int*)(c->edi + 408 + 49 * 4) && lvlWaterMagic ) // Если "висит" Mirth (#49) и у героя есть Water Magic
   {
      int k[] = {5, 6, 8}; // 5/96 = 1/24 * 1.25 (Basic), 6/96 = 1/24 * 1.50 (Advanced), 8/96 = 1/24 * 2.00 (Expert)
      unsigned int dice;
      rand_s(&dice); // Пользуемся rand_s, чтобы не "сломать" ГПСЧ игры
      dice = (unsigned int)((double)dice / ((double)UINT_MAX + 1) * 96.0) + 1; // Случайное целое из диапазона [1, 96]

      if ( (int)dice <= k[lvlWaterMagic - 1] * *(int*)c->ebx ) // *(int*)c->ebx - Мораль отряда (-3..3)
      {
         c->return_address = 0x4645C0;
         return NO_EXEC_DEFAULT;
      }
   }
   
   return EXEC_DEFAULT;
}

...

_PI->WriteLoHook(0x444967, mirthSpell);
_PI->WriteLoHook(0x4645BA, mirthMoraleBonus);

Также добавьте
Код: Выделить всё
#define _CRT_RAND_S
перед самым первым инклудом (нужно для функции rand_s()).

Для Удачи делается по аналогии.
Последний раз редактировалось AlexSpl 10 авг 2017, 02:30, всего редактировалось 3 раз(а).
Вернуться к началу

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

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

Сообщение AlexSpl » 10 авг 2017, 01:52

Цитата:
Для Мелодии думаю сделать эффект специализации +25% (то есть для нее заклинание Удача +50/75/125%).
И измерять эффект для нее именно в процентах, а не в долях.
Наверно, вот по этому адресу бонус для Мелодии 004E62CD, видимо, нужно поменять "mov eax, 3" на "mov eax, 25".

Так Вы не добьётесь желаемого эффекта. Нужно писать хук по аналогии с mirthMoraleBonus и там проверять ID героя. Если герой - Мелодия, увеличивать процент выпадения.

Цитата:
Пока так и не понял, почему задается этот вопрос "Вы действительно хотите переместиться в ... ?"

Это фича HD мода, начиная с версии 3.809. Твика, чтобы отключить это окно, я не нашёл. Можно обойти так:

Код: Выделить всё
int __stdcall skipTownPortalConfirm(LoHook* h, HookContext* c)
{
   if ( c->eax == -1 ) {
      c->ecx = *(char*)(c->edi + 5); // Выполняем затёртую jmp-патчем команду
      c->return_address = 0x41D990; // Обходим jmp-патч
      return NO_EXEC_DEFAULT;
   }
   
   c->return_address = 0x41D939;
   return NO_EXEC_DEFAULT;
}

...

_PI->WriteLoHook(0x41D934, skipTownPortalConfirm);
Вернуться к началу

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

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

Сообщение AlexSpl » 10 авг 2017, 15:30

Сейчас пересмотрел код mirthMoraleBonus. Нужно изменить последнее условие. Кратко: игра бросает 24-гранную кость с гранями от 1 до 24. В хуке бросается 96-гранная кость с гранями от 1 до 96. Без else получается следующее: если бросок кости в хуке провалился, то мораль всё равно может выпасть, если бросок игры был успешным.

Код: Выделить всё
if ( (int)dice <= k[lvlWaterMagic - 1] * *(int*)c->ebx ) // *(int*)c->ebx - Мораль отряда (-3..3)
   c->return_address = 0x4645C0;
else
   c->return_address = 0x464708;

return NO_EXEC_DEFAULT;


Кстати, в данном случае можно явно не указывать адреса возврата, а менять регистр флагов (efl). Тогда вообще красиво получается:

Код: Выделить всё
(int)dice <= k[lvlWaterMagic - 1] * *(int*)c->ebx ? c->flags.ZF = 1 : c->flags.ZF = 0;


return NO_EXEC_DEFAULT убираем. Принимать решение о переходе будет оригинальный джамп.
Вернуться к началу

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

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

Сообщение Ben80 » 11 авг 2017, 04:10

А почему в ДедМорозовском плагине для изменения закла Slow пришлось 2 хука писать, а не один - на адреса 448A1A и 441E19 ?

Пытаюсь понять значение слова Melee :)
http://dictionary.cambridge.org/diction ... lish/melee

Если на юните одновременно Slow и Молитва - это требует специальной дополнительной процедуры ?
Вернуться к началу

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

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

Сообщение AlexSpl » 11 авг 2017, 05:32

Наверное, в двух местах скорость отряда на модификатор Slow умножается. Лучший способ найти все такие места в коде - поставить брейкпоинт на чтение значения модификатора Slow из памяти и провести тестовую битву, пробуя всякие варианты. Судя по названию (Melee), в рукопашной скорость считается отдельно.

 "Причёсанный" код mirthMoraleBonus
Код: Выделить всё
int __stdcall mirthMoraleBonus(LoHook* h, HookContext* c)
{
   int cmAddr = *(int*)0x699420;
   int monSide = *(int*)(c->edi + 244);
   int heroOffset = *(int*)(cmAddr + monSide * 4 + 0x53CC);

   char lvlWaterMagic = heroOffset ? *(char*)(heroOffset + 201 + 16) : 0;
     
   if ( *(int*)(c->edi + 408 + 49 * 4) )
   {
      int k[] = {4, 5, 6, 8};
      unsigned int dice;
      rand_s(&dice);
      dice = (unsigned int)((double)dice / ((double)UINT_MAX + 1) * 96.0) + 1;
      c->flags.ZF = (int)dice <= k[lvlWaterMagic] * *(int*)c->ebx ? 1 : 0;
   }
   
   return EXEC_DEFAULT;
}


С Удачей что-нибудь получается?
Последний раз редактировалось AlexSpl 12 авг 2017, 04:16, всего редактировалось 1 раз.
Вернуться к началу

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

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

Сообщение Ben80 » 11 авг 2017, 10:23

В воскресенье буду пробовать. Каждый новый шаг по модификации Героев 3 - это для меня событие, для которого нужно набраться духа :)

Для Slow у Деда-мороза, я так понял, используется округление до ближайшего целого.
У меня будет ceil, благодаря чему юниты с очень маленькой скоростью не будут попадать в такое катастрофическое положение. Например, у Людоеда на эксперте будет снижена скорость всего на 1, у гнома - тоже на 1.

А то при прохождении кампаний экспертный Slow оказывается едва ли не важнее, чем Городской портал - очень хорошие возможности для битв дает.
Вернуться к началу

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

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

Сообщение Ben80 » 15 авг 2017, 18:58

Однако, это ж еще нужно было додуматься до 96 :smile1:

Наверно, можно и так сделать - сгенерировать double число от 0.00 до 100.00
(https://msdn.microsoft.com/en-us/library/sxtz2fa8.aspx)

А массив объявить

double k[] = {5.20, 6.24, 8.32};

то есть числа в массиве - это
(4.16*(1+bonus))
Вернуться к началу

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

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

Сообщение AlexSpl » 16 авг 2017, 03:05

Да, можно и так. Но случайные целые числа лучше вписываются в стиль игры.
Вернуться к началу

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

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

Сообщение Ben80 » 16 авг 2017, 05:26

Код: Выделить всё
if ( *(int*)(c->edi + 408 + 49 * 4) && lvlWaterMagic )


Здесь видимо придется еще одно условие добавить:

Код: Выделить всё
if ( *(int*)(c->edi + 408 + 49 * 4) && lvlWaterMagic && *(int*)c->ebx >0)


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

Пред.След.

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

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

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