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


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

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

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

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

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

Ben80 писал(а):

c->eax = c->eax / 2;

Можно еще так делить:
Код: Выделить всё
с->eax /= 2
c->eax >>= 1


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




Монстры и игроки-компьютеры на любой сложности мыслят как на максимальной. Автор - igrik, я немного дополнил его код.
Принцип работы - после выдачи ресурсов сложность выставляется на 200% и возвращается на оригинальную перед расчетом очков на экране победы
Недочеты - при загрузке сохраненной игры изначально выставленная сложность не отображается. Но игра все равно ее помнит и посчитает очки на экране победы правильно!
Код: Выделить всё
#include homm3.h

_int_ __stdcall Hook_StartNewGame(LoHook* h, HookContext* c)
{
   c_chosen_difficulty = o_GameMgr->Field<_byte_>(0x1F6D8); // get initial difficulty
   o_GameMgr->Field<_byte_>(0x1F6D8) = 4; // set difficulty to 200%

   return EXEC_DEFAULT;
}

_int_ __stdcall c_score_calc1(LoHook* h, HookContext* c)
{
   c->ecx = c_chosen_difficulty; // return initial difficulty
   return EXEC_DEFAULT;
}

_int_ __stdcall c_score_calc2(LoHook* h, HookContext* c)
{
   c->eax = c_chosen_difficulty; // return initial difficulty
   return EXEC_DEFAULT;
}

...

         _PI->WriteLoHook(0x4C0107, Hook_StartNewGame);
         _PI->WriteLoHook(0x4F46E2, c_score_calc1);
         _PI->WriteLoHook(0x4F4723, c_score_calc2);





ПКМ по монстрам на карте дает расширенную информацию о них. Инфа от видений и дипломатии немного сместилась вниз.
Плагин двуязычный, знает русский и английский, определяет язык игры сам и отображает текст соответствующе
 ru
Изображение

 en
Изображение

За основу брался плагин игрика для показа AI value нейтралов. Конечный результат зависит от используемых шрифтов.

Код: Выделить всё
#include homm3.h

_bool_ isRusLng;

int __stdcall Y_LoadAllTXTinGames(LoHook* h, HookContext* c)
{
   if ( o_CreatureInfo[0].name_single[0] != 'P' ) {
      isRusLng = 1;
   } else {
      isRusLng = 0;
   }
   return EXEC_DEFAULT;
}

int c_neu_rmb_id;

int __stdcall c_get_neu_rmb(LoHook* h, HookContext* c)
{   
   c_neu_rmb_id = c->esi;

   return EXEC_DEFAULT;
}

int __stdcall c_neu_rmb_public(LoHook* h, HookContext* c)

   int c_neu_lv = o_pCreatureInfo[c_neu_rmb_id].level + 1;
   int c_neu_at = o_pCreatureInfo[c_neu_rmb_id].attack;
   int c_neu_df = o_pCreatureInfo[c_neu_rmb_id].defence;
   int c_neu_sp = o_pCreatureInfo[c_neu_rmb_id].speed;
   int c_neu_hp = o_pCreatureInfo[c_neu_rmb_id].hit_points;
   int c_neu_d1 = o_pCreatureInfo[c_neu_rmb_id].damage_min;
   int c_neu_d2 = o_pCreatureInfo[c_neu_rmb_id].damage_max;
   char* c_neu_ds = o_pCreatureInfo[c_neu_rmb_id].specification_description;

   if ( isRusLng == 1 )
   {
   sprintf(o_TextBuffer, "%s\n\nУровень: {%d}, Атака: {%d}, Защита: {%d},\nЗдоровье: {%d}, Урон: {%d}-{%d}, Скорость: {%d}.\n\n%s", o_TextBuffer, c_neu_lv, c_neu_at, c_neu_df, c_neu_hp, c_neu_d1, c_neu_d2, c_neu_sp, c_neu_ds);
   }
   else
   {
   sprintf(o_TextBuffer, "%s\n\nLevel: {%d}, Attack: {%d}, Defense: {%d},\nHealth: {%d}, Damage: {%d}-{%d}, Speed: {%d}.\n\n%s", o_TextBuffer, c_neu_lv, c_neu_at, c_neu_df, c_neu_hp, c_neu_d1, c_neu_d2, c_neu_sp, c_neu_ds);
   }
   return EXEC_DEFAULT;
}

...

         // check language after loading all txt files
         _PI->WriteLoHook(0x4EDFFD, Y_LoadAllTXTinGames);

         // advanced rmb on neutrals
         _PI->WriteLoHook(0x52FFEC, c_get_neu_rmb);
         _PI->WriteLoHook(0x530020, c_neu_rmb_public);
         _PI->WriteByte(0x530026, 120); // public y size
         _PI->WriteByte(0x53002D, 100); // public y pos
         _PI->WriteByte(0x530170, 217); // private y pos
Быстрее всего смогу ответить вам в Telegram: @PleaseAndThankYou
Вернуться к началу

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

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

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

Автор: Ben80

Название: MullichStartList

Описание: При создании игры в списке выбора героев Замка появляется сэр Мюллич вместо лорда Хаарта (там, где это возможно - то есть во всяком случае не в RoE).
Наличие Хаарта вместо Мюллича при создании случайной карты, даже играя в "Клинок Армагеддона" (к этому времени Хаарт уже стал личем) - по сути, баг.

Код: Выделить всё
#include "..\..\include\homm3.h"

Patcher* _P;
PatcherInstance* _PI;

static _bool_ plugin_On = 0;


int __stdcall startListChanges(LoHook* h, HookContext* c)
{
   if(c->edx == 4)
   {
      c->return_address = 0x583DAD;
      return NO_EXEC_DEFAULT;
   }

   return EXEC_DEFAULT;

}


BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
{
    if ( DLL_PROCESS_ATTACH == ul_reason_for_call)
    {
        if (!plugin_On)
        {
         plugin_On = 1;       
         _P = GetPatcher();

         _PI = _P->CreateInstance("HD.Plugin.MullichStartList");

         _PI->WriteLoHook(0x583CE8, startListChanges);

        }
    }

   return TRUE;
}


MullichStartList.zip
(3.39 КБ) Скачиваний: 359
Последний раз редактировалось Ben80 07 авг 2019, 13:59, всего редактировалось 1 раз.
Вернуться к началу

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

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

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

Автор: Ben80

Название: HaartMullich

Описание: Замещение читерного сэра Мюллича лордом Хаартом - при создании игры в списке выбора героев, в таверне, в тюрьмах на случайных картах.
Согласно хронологии, во время "Дыхания Смерти" лорд Хаарт личем еще не был, так что данная замена вполне "законна". Не вполне правильна такая замена будет только для "Клинка Армагеддона".

Код: Выделить всё
#include "..\..\include\homm3.h"

Patcher* _P;
PatcherInstance* _PI;
PatcherInstance* _PI_Test;

static _bool_ plugin_On = 0;


int __stdcall startListChanges(LoHook* h, HookContext* c)
{
   // Если не Клинок Армагеддона
   //if((*(int*)0x69928C) != 1 && o_GameMgr->map_header.f0[3] != 1)
   {
      if(c->edx == 4)
      {
         c->return_address = 0x583CF6;
         return NO_EXEC_DEFAULT;
      }

      if(c->edx == 144)
      {
         c->return_address = 0x583DAD;
         return NO_EXEC_DEFAULT;
      }
   }

   return EXEC_DEFAULT;

}

int __stdcall tavernChanges(LoHook* h, HookContext* c)
{   
   // Если не Клинок Армагеддона
   //if(*(int*)(0x69928C) != 1 && o_GameMgr->map_header.f0[3] != 1)
   {
      o_GameMgr->heroes_aval_abyte4DF18[4] = 0xFF;
      o_GameMgr->heroes_aval_abyte4DF18[144] = 0x40;
   }

   return EXEC_DEFAULT;
}

int __stdcall prisonChanges(LoHook* h, HookContext* c)
{
   // Если не Клинок Армагеддона
   //if(*(int*)(0x69928C) != 1 && o_GameMgr->map_header.f0[3] != 1)
   {
      *(_byte_*)(c->esi + 0xF88 + 4) = 0;
      *(_byte_*)(c->esi + 0xF88 + 144) = 1;
   }

   return EXEC_DEFAULT;
}

BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
{
    if ( DLL_PROCESS_ATTACH == ul_reason_for_call)
    {
        if (!plugin_On)
        {
         plugin_On = 1;       
         _P = GetPatcher();

         _PI = _P->CreateInstance("HD.Plugin.HaartMullich");

         _PI->WriteLoHook(0x583CE8, startListChanges);
         _PI->WriteLoHook(0x4C4B46, tavernChanges);
         _PI->WriteLoHook(0x534DCA, prisonChanges);

        }
    }

   return TRUE;
}



HaartMullich.zip
(3.48 КБ) Скачиваний: 361
Вернуться к началу

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

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

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

Аналог XXL-патча из Era. Генератор всегда будет создавать карты максимального размера прямо в игре. Может потребоваться кастомный шаблон.
Код: Выделить всё
#include <windows.h>
#include <stdio.h>
#include "..\..\include\HotA\HoMM3.h"
#include "..\..\include\patcher_x86_commented.hpp"
#include "..\..\include\heroes.h"

Patcher* _P;
PatcherInstance* _PI;

int __stdcall c_rmg_xxl(LoHook* h, HookContext* c)
{
   c->eax = 252; // x
   c->edx = 252; // y

   return EXEC_DEFAULT;
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                )
{
    static _bool_ plugin_On = 0;
   switch (ul_reason_for_call)
   {
   case DLL_PROCESS_ATTACH:
        if (!plugin_On)
        {
         plugin_On = 1;

         _P = GetPatcher();
         _PI = _P->CreateInstance("afpXXL");

         _PI->WriteLoHook(0x54C4CD, c_rmg_xxl);
        }
        break;
   case DLL_THREAD_ATTACH:
   case DLL_THREAD_DETACH:
   case DLL_PROCESS_DETACH:
      break;
   }
   return TRUE;
}
Вложения
XXL.zip
(3.37 КБ) Скачиваний: 374
Быстрее всего смогу ответить вам в Telegram: @PleaseAndThankYou
Вернуться к началу

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

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

Сообщение Catastrophe » 11 авг 2019, 18:17

Альтернативная русификация интерфейса Полного Собрания (на Дыхании Смерти не тестировал). За основу взяты пиратские переводы AB и SoD от XXI век, они же 8 Bit, они же Эликтан.

 
Изображение Изображение




Изображение Изображение




Изображение Изображение




Изображение Изображение
Вложения
rus.zip
(4.18 МБ) Скачиваний: 363
Быстрее всего смогу ответить вам в Telegram: @PleaseAndThankYou
Вернуться к началу

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

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

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

Еще один плагин без кода, только с графикой. Чистые фоны в меню существ на ПКМ или экране замка. В оригинале там еще находятся замки крайне низкого качества. В хоте их перерисовали, я предпочел удалить.
Старался пихать по минимуму отсебятины, новые фоны, как и старые, сняты с полей боев и экранов городов. Исключение составляет сопряжение, там было снято с того же фона, что и замок, я снял с магических равнин.
Почему для нейтралов фон снят с пустынь, а не с грязи? Потому что, как и прошлый плагин, этот делался под хотелки для моего (ха-ха) мода, где в нейтралах остались только кочевники и элементали из возрождения эрафии.
 
Изображение
Вложения
backgrounds.zip
(138.94 КБ) Скачиваний: 359
Быстрее всего смогу ответить вам в Telegram: @PleaseAndThankYou
Вернуться к началу

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

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

Сообщение igrik » 12 авг 2019, 14:20

Площадные замедление и ускорение
FUN плагин, который преобразует заклинания замедление и ускорение из массовых в площадные заклинания.
Радиус действия заклинаний как у заклинания берсерк (радиус: нет, базов = 0 клеток, продв = 1 клетка, эксперт = 2 клетки)
Действие заклинания накладывается и на дружественные и на вражеские стеки (так и задумано), которые попадают в зону действия заклинания
Важно! ИИ неверно оценивает как пользоваться такими заклинаниями (для этого нужно писать свой алгоритм с нуля)

https://dl.dropboxusercontent.com/s/m8nqrl1rgwrphw4/NewHastAndSlow.dll


 код
Код: Выделить всё
#define SPL_SLOW 54
#define SPL_HASTE 53
#define SPL_BERSERK 59

// функция ведения мыши по площади
int __stdcall Y_Haste_MouseMoove(LoHook* h, HookContext* c)
{
   if (c->esi == SPL_HASTE || c->esi == SPL_SLOW || c->esi == SPL_BERSERK) {
      c->return_address = 0x59FA88;
   } else c->return_address = 0x59FA8C;

   return NO_EXEC_DEFAULT;
}

// радиус затемнения гексов
int __stdcall Y_Haste_RadiusGex(LoHook* h, HookContext* c)
{
   if (c->ecx == SPL_HASTE || c->ecx == SPL_SLOW || c->ecx == SPL_BERSERK) {
      c->return_address = 0x59FD09;
   } else c->return_address = 0x59FD1E;

   return NO_EXEC_DEFAULT;
}

// подсветка существ = на кого может дейстовать (проверка на сторону действия и на гипноз (в данном случае)
int __stdcall Y_Haste_WhoCanBeAffected(LoHook* h, HookContext* c)
{

   int spell_id = *(int*)(c->ebp +12);
   if (spell_id == SPL_HASTE || spell_id == SPL_SLOW )
   {
      c->return_address = 0x5A6A2D;
      return NO_EXEC_DEFAULT;
   }

   return EXEC_DEFAULT;
}

// подсветка курсора (широкого затемнения) при ведении мыши
int __stdcall Y_Haste_SetCursorShadow(LoHook* h, HookContext* c)
{
   // восстанавливаем пропущенные параметры
   *(char*)(c->ebp -0x4) = c->edi;
   *(char*)(c->ebp -0xD) = 0;

   if (c->eax == SPL_HASTE || c->eax == SPL_SLOW || c->eax == SPL_BERSERK) {
      c->return_address = 0x59FBF7;
   } else c->return_address = 0x59FC09;

   return NO_EXEC_DEFAULT;
}

// функция накладывания спеллов (код берсерка)
int __stdcall Y_Haste_PlayDefAnim(LoHook* h, HookContext* c)
{
   int anim_id;
   int spell_id = *(int*)(c->ebp +8);
   switch (spell_id){
      case SPL_HASTE:      anim_id = 31; break;   
      case SPL_SLOW:      anim_id = 19; break;   
      case SPL_BERSERK:   anim_id = 35; break;   
      default:         anim_id = 35; break;
   }
   _BattleMgr_* bm = (_BattleMgr_*)c->ebx;
   int caster = *(int*)(c->ebp +0x10); // 0 - герой, 1 - монстр, 2 - артефакт, 3 - герой без вычета маны

   if ( caster == 1 ) {
      if ( bm->stack[bm->current_stack_ix]->creature_id == 136 ) { // если Чародей
         o_Spell[SPL_HASTE].type = 1;
         o_Spell[SPL_SLOW].type = -1;
         CALL_7(void, __thiscall, 0x5A69E0, bm, *(int*)(c->ebp -0x14), *(int*)(c->ebp +0x8), c->esi, *(int*)(c->ebp +0x1C), bm->current_side, caster );
         o_Spell[SPL_HASTE].type = 0;
         o_Spell[SPL_SLOW].type = 0;
      }
   } 
   CALL_5(char, __fastcall, 0x5A6AD0, bm, (int)c->ebx +0x547C, (int)c->ebx +0x547C, anim_id, 0);

   c->return_address = 0x5A2168;
   return NO_EXEC_DEFAULT;
}


// запрет колодовства своими монстрами на врагов (актуально для WOG/ERA)
_byte_ __stdcall Y_Haste_SetCursor(HiHook* hook, _BattleStack_* stack, _int_ gex)
{
   _byte_ ret = 0;

   ret = CALL_2(_byte_, __thiscall, hook->GetDefaultFunc(), stack, gex);

   if (ret == 1) {
      if ( stack->creature_id >= 174 && stack->creature_id <= 191 ) {
         // проверить на сторону существа в gex и сравнить с кастующим
         int side_target = o_BattleMgr->hex[gex].GetCreature()->side;
         if ( stack->side != side_target) {
            ret = 0;
         }
      }
   }

   return ret;
}

// оценка спелла для ИИ
int __stdcall Y_Haste_AI1(LoHook* h, HookContext* c)
{
   if (c->eax == SPL_HASTE || c->eax == SPL_SLOW || c->eax == SPL_BERSERK) {
      c->return_address = 0x5A4C3B;
   } else c->return_address = 0x5A4C50;

   return NO_EXEC_DEFAULT;
}

// оценка спелла для ИИ
int __stdcall Y_Haste_AI2(LoHook* h, HookContext* c)
{
   *(char*)(c->ebp -0x4) = c->eax;
   if (c->esi == SPL_HASTE || c->esi == SPL_SLOW || c->esi == SPL_BERSERK) {
      c->return_address = 0x5A4CE6;
   } else c->return_address = 0x5A4CF8;

   return NO_EXEC_DEFAULT;
}


void New_Haste_and_Slow()
{
   // настариваем параметры закл."Ускорение"
   o_Spell[SPL_HASTE].flags = 266373;
   o_Spell[SPL_HASTE].type = 0;
   o_Spell[SPL_HASTE].effect[0] = 2;
   o_Spell[SPL_HASTE].effect[1] = 3;
   o_Spell[SPL_HASTE].effect[2] = 4;
   o_Spell[SPL_HASTE].effect[3] = 5;
   o_Spell[SPL_HASTE].eff_power = 10;
   // настариваем параметры закл."Медлительность"
   o_Spell[SPL_SLOW].flags = 266373;
   o_Spell[SPL_SLOW].type = 0;
   o_Spell[SPL_SLOW].effect[0] = 80;
   o_Spell[SPL_SLOW].effect[1] = 70;
   o_Spell[SPL_SLOW].effect[2] = 60;
   o_Spell[SPL_SLOW].effect[3] = 50;
   o_Spell[SPL_SLOW].eff_power = 5;
   // убираем эффект молитвы (бонусы скорости)
   _PI->WriteHexPatch(0x444956, "90 E9");   // при касте молитвы
   _PI->WriteHexPatch(0x44440D, "90 E9");   // при снятии заклинания
   // усиливаем берсерк
   o_Spell[SPL_BERSERK].eff_power = 100;
   o_Spell[SPL_BERSERK].ai_value[0] = 37;
   o_Spell[SPL_BERSERK].ai_value[1] = 37;
   o_Spell[SPL_BERSERK].ai_value[2] = 37;
   o_Spell[SPL_BERSERK].ai_value[3] = 37;

   // патчим свитчи заклинаний
   _PI->WriteByte(0x59F9BC +SPL_HASTE -10, 5);
   _PI->WriteByte(0x59F9BC +SPL_SLOW -10, 5);
   _PI->WriteByte(0x5A2B48 +SPL_HASTE -10, 24);
   _PI->WriteByte(0x5A2B48 +SPL_SLOW -10, 24);

   // патчим свитч ИИ (переносим в площадные (но ударные) заклинания)
   // по хорошему нужно писать свой алгоритм с нуля
   _PI->WriteByte(0x43BB34 +SPL_HASTE -14, 2);
   _PI->WriteByte(0x43BB34 +SPL_SLOW -14, 2);
   _PI->WriteByte(0x43BB34 +SPL_BERSERK -14, 2);

   // ставим хуки
   _PI->WriteLoHook(0x59FA83, Y_Haste_MouseMoove);
   _PI->WriteLoHook(0x59FD04, Y_Haste_RadiusGex);
   _PI->WriteLoHook(0x5A6A23, Y_Haste_WhoCanBeAffected);
   _PI->WriteLoHook(0x59FBED, Y_Haste_SetCursorShadow);   
   _PI->WriteLoHook(0x5A2156, Y_Haste_PlayDefAnim);

   _PI->WriteHiHook(0x4473E0, SPLICE_, EXTENDED_, THISCALL_, Y_Haste_SetCursor);

   // оценка спелла для ИИ
   // по хорошему нужно писать свой алгоритм с нуля
   _PI->WriteLoHook(0x5A4C36, Y_Haste_AI1);
   _PI->WriteLoHook(0x5A4CDE, Y_Haste_AI2);

   return;
}


 Скрин
Изображение
Вернуться к началу

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

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

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

Автор: Ben80

Название: RmgMoreSavageMonsters

Описание: Продолжаем заниматься балансировкой игры, не изменяя базовые механики. Данный плагин при создании случайных карт часть монстров (одну треть) делает "дикими" (неспособными к присоединению даже посредством Дипломатии).
Цель плагина - балансировка вторичного навыка Дипломатия.

Код: Выделить всё
#define _CRT_RAND_S
#define _CRT_SECURE_NO_WARNINGS
#include "..\..\include\homm3.h"

Patcher* _P;
PatcherInstance* _PI;

static _bool_ plugin_On = 0;

int __stdcall setMonsterAgression(LoHook* h, HookContext* c)
{
    unsigned int dice;
    rand_s(&dice);
    dice = (unsigned int)((double)dice / ((double)UINT_MAX + 1) * 100.0) + 1;
   if ( dice <= 33 )
      *(int*)(c->eax + 0x24) = 4;

   return EXEC_DEFAULT;

}

BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
{
    if ( DLL_PROCESS_ATTACH == ul_reason_for_call)
    {
        if (!plugin_On)
        {
         plugin_On = 1;       
         _P = GetPatcher();

         _PI = _P->CreateInstance("HD.Plugin.RmgMoreSavageMonsters");
         //_PI->WriteByte(0x541237, 4);
         _PI->WriteLoHook(0x054123B, setMonsterAgression);

        }
    }

   return TRUE;
}



RmgMoreSavageMonsters.zip
(3.51 КБ) Скачиваний: 482
Вернуться к началу

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

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

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

Автор: Ben80

Название: AI_MeleeBugFix

Описание: Фикс бага расчета ИИ ценности движения к цели во время боя. В оригинале имел место лишний делитель, равный числу ходов до цели. Это приводило к тому, что крайний правый стек противника получал сильно завышенную ценность.

Код: Выделить всё
#include "..\..\include\homm3.h"

Patcher* _P;
PatcherInstance* _PI;

static _bool_ plugin_On = 0;

int __stdcall AI_MeleeBugFix(LoHook* h, HookContext* c)
{
   c->eax = c->eax * *(int*)(c->ebp - 0x24);

   return EXEC_DEFAULT;
}

BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
{
    if ( DLL_PROCESS_ATTACH == ul_reason_for_call)
    {
        if (!plugin_On)
        {
         plugin_On = 1;       
         _P = GetPatcher();
         _PI = _P->CreateInstance("HD.Plugin.AI_MeleeBugFix");

         _PI->WriteLoHook(0x421D3F, AI_MeleeBugFix);

        }
    }

   return TRUE;
}



AI_MeleeBugFix.zip
(3.38 КБ) Скачиваний: 370
Вернуться к началу

offlinewenwell  
имя: Roman
Новичок
Новичок
 
Сообщения: 15
Зарегистрирован: 29 мар 2019, 09:31
Пол: Мужчина
Поблагодарили: 16 раз.

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

Сообщение wenwell » 31 авг 2019, 14:08

Цитата:
Это приводило к тому, что крайний правый стек противника получал сильно завышенную ценность.


Баг любопытный, интересно узнать подробнее =) На примере боя:

 
Изображение


AI (коричневый) нападает на игрока (красный), получается, что стеком с багованной ценностью будет гном? (крайний справа). Что если у нас не семь стеков, а два, баг тоже будет работать? Работает ли баг если нападаем мы?
Вернуться к началу

Пред.След.

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

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

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