Объявления

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

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

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
offlineigrik  
Подмастерье
Подмастерье
 
Сообщения: 108
Зарегистрирован: 14 сен 2017, 12:35
Пол: Не указан
Поблагодарили: 84 раз.

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

Сообщение igrik » 12 ноя 2018, 09:21

Автор: igrik

Название: защита артефактов, пандор и свитков
Описание: теперь артефакты, ящики пандор и свитки защищены рядом стоящими монстрами
(монстр защищает объекты согласно красной рамки):
Совместимость: SoD, ERA

Изображение

 код
Код: Выделить всё
// ////////////////////////////////////////
// Нейтралы охраняют объекты вокруг себя //
//          автор:     igrik             //
//          дата:    09/11/2018          //
///////////////////////////////////////////

#include "..\..\include\homm3.h"

Patcher* _P;
PatcherInstance* _PI;

//   ФУНКЦИЯ: есть ли стража рядом с объектом (возвращает координаты клетки с монстрами)
_int_ isGuardNearTheObject(_AdvMgr_* advMng, _int_ xyz)
{
   int xd = b_unpack_x(xyz);
   int yd = b_unpack_y(xyz);
   int z = b_unpack_z(xyz);

   if (!(0x0100 & CALL_3(WORD, __fastcall, 0x4F8040, xd, yd, z)) ) {
      return 0; // монстров вокруг клетки нет
   }

   int x, y;
   int size = advMng->map->size;
   // ряд на уровне арта --------------------------------------------------------------------------------------
   x = xd -1; y = yd;
   if ( x >= 0 && x < size && y >= 0 && y < size) {
      if (advMng->map->GetItem(x,y,z)->object_type == 54) {
            return b_pack_xyz(x,y,z); } }

   x = xd +1; y = yd;
   if ( x >= 0 && x < size && y >= 0 && y < size) {
      if (advMng->map->GetItem(x,y,z)->object_type == 54) {
            return b_pack_xyz(x,y,z); } }
   // ряд ниже арта --------------------------------------------------------------------------------------------
   x = xd -1; y = yd +1;
   if ( x >= 0 && x < size && y >= 0 && y < size) {
      if (advMng->map->GetItem(x,y,z)->object_type == 54) {
            return b_pack_xyz(x,y,z); } }

   x = xd;   y = yd +1;
   if ( x >= 0 && x < size && y >= 0 && y < size) {
      if (advMng->map->GetItem(x,y,z)->object_type == 54) {
            return b_pack_xyz(x,y,z); } }

   x = xd +1; y = yd +1;
   if ( x >= 0 && x < size && y >= 0 && y < size) {
      if (advMng->map->GetItem(x,y,z)->object_type == 54) {
            return b_pack_xyz(x,y,z); } }

   // ряд выше арта --------------------------------------------------------------------------------------------     
   x = xd -1; y = yd -1;
   if ( x >= 0 && x < size && y >= 0 && y < size) {
      if (advMng->map->GetItem(x,y,z)->object_type == 54) {
            return b_pack_xyz(x,y,z); } }

   x = xd; y = yd -1;
   if ( x >= 0 && x < size && y >= 0 && y < size) {
      if (advMng->map->GetItem(x,y,z)->object_type == 54) {
            return b_pack_xyz(x,y,z); } }

   x = xd +1; y = yd -1;
   if ( x >= 0 && x < size && y >= 0 && y < size) {
      if (advMng->map->GetItem(x,y,z)->object_type == 54) {
            return b_pack_xyz(x,y,z); } }
   // -----------------------------------------------------------------------------------------------------
   return 0; // монстров вокруг клетки нет
}

// при движении мыши на КП
_int_ __stdcall Y_GetCursorFrameOnAdvMap(HiHook* hook, _AdvMgr_* advMng, _MapItem_* obj)
{
   switch (obj->object_type) {
      case 5: case 6: case 81: case 93: // типы защищаемых объектов
         if ( isGuardNearTheObject(advMng, advMng->pack_xyz) ) {
            return 5; // возвращаем боевой курсор
         }   break;

      default: break;
   }
   return CALL_2(_int_, __thiscall, hook->GetDefaultFunc(), advMng, obj);
}

void __stdcall Y_Hero_Enter_To_Object(HiHook* hook, _AdvMgr_* advMng, _Hero_* hero, _MapItem_* obj, _int_ xyz, _int_ isPlayer)
{
   int xyz_54 = 0; // инициализации переменной (возврат пакованных координат охраны)
   // Edit: кстати, возможнен недочёт с охраной в точке 0/0/0 (мне влом уже)

   switch (obj->object_type) {
      case 5:      // артефакт
      case 6:      // ящик пондоры
      case 81:   // ученый
      case 93:   // свиток с заклинаниями
         xyz_54 = isGuardNearTheObject(advMng, xyz); // проверка стражи объекта в соседних клетках
         if ( xyz_54 ){  // если стража есть
            _MapItem_* obj_54 = advMng->map->GetItem(b_unpack_x(xyz_54), b_unpack_y(xyz_54), b_unpack_z(xyz_54)); // получаем структуру объекта "стража"
            CALL_5(void, __thiscall, hook->GetDefaultFunc(), advMng, hero, obj_54, xyz_54, isPlayer);

            if (hero->owner_id < 0) {    // если герой убит или сбежал (т.е. номер хозяина героя стал == -1)
               return; // выйти из функции ПОСЕЩЕНИЕ ОБЪЕКТА
            }
         }   break;

      default: break;
   }
   // вызываем стандартную функцию
   CALL_5(void, __thiscall, hook->GetDefaultFunc(), advMng, hero, obj, xyz, isPlayer);
   return;
}


BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
{
    static _bool_ enable = false;
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        if (!enable)
        {
         enable = true;   

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

         _PI->WriteHiHook(0x40E97F, CALL_, EXTENDED_, THISCALL_, Y_GetCursorFrameOnAdvMap);
         _PI->WriteHiHook(0x4A8160, SPLICE_, EXTENDED_, THISCALL_, Y_Hero_Enter_To_Object);

        }
        break;

    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}


Скачать
https://dl.dropboxusercontent.com/s/95j ... tGuard.dll
Последний раз редактировалось igrik 19 июн 2019, 07:52, всего редактировалось 2 раз(а).
Вернуться к началу

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

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

Сообщение igrik » 23 ноя 2018, 17:33

Исправление бага с исчезновением улучшенного отряда нейтральных монстров после боя

Автор: igrik
Совместимость: SoD, ERA
 код
Код: Выделить всё
_int_ __stdcall Y_FixBagCreatureGredeOfNeutrals(HiHook* hook, _Army_* army, _int_ creature_id)
{
   _int_ count = 0;
   _int_ i = 0;
   _int_ crGrade_id = GetCreatureGrade(creature_id);
   do {
      if (army->type[i] == creature_id || army->type[i] == crGrade_id) {
         count += army->count[i];
      }
      i++;
   } while ( i<7 );

   return count;
}

// --------------------------------------------------------------------------------------
_PI->WriteHiHook(0x4AC5F5, CALL_, EXTENDED_, THISCALL_, Y_FixBagCreatureGredeOfNeutrals);
Вложения
FixBagCreatureGredeOfNeutrals.zip
(41.16 КБ) Скачиваний: 827
Вернуться к началу

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

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

Сообщение Ben80 » 31 янв 2019, 15:43

Автор: Ben80

Название: BukaSoD_RusFonts

Описание:

Альтернатива плагину SuperPack_Rus.

Позволяет использовать шрифты буковских версий Героев 3 ("Дыхание Смерти" и "Клинок Армагеддона") в HD моде, установленном на буковское "Дыхание Смерти", корректируя некоторые несоответствия сочетания буковской локализации и шрифтов, с одной стороны, и размеров для надписей, характерных для английского EXE файла (который используется в HD моде).
Кроме того, устранен небольшой графический изъян работы HD мода при параметре HiRezCore = 0.
Перенос нужных пользователю шрифтов возложен на самого пользователя.

Для буковского Полного Собрания также будет работать.

Рекомендую шрифты из Клинка Армагеддона (такие же в Хрониках). Хорошие.
Плагин, поддерживающий шрифты из Клинка Армагеддона, также будет
поддерживать шрифты по умолчанию из HD мода версий 5+.


Изображение

Изображение

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

Patcher *_P;
PatcherInstance *_PI;


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("HD.BukaSoD_RusFontsSoD");

            // Hero Pop-up fix для шрифтов Рус. СоД
            _PI->WriteByte(0x46C502, 0x23);
            _PI->WriteByte(0x46C506, 0xA2);

            // Hero Pop-up fix для шрифтов Рус. AB
            //_PI->WriteByte(0x46C502, 0x2D);
            //_PI->WriteByte(0x46C506, 0x9F);

            // fix Hero right-click (monster's number) для шрифтов Рус. AB
            //_PI->WriteByte(0x52F73A, 12);
            //_PI->WriteByte(0x52F7CA, 12);

            // Extend part of screen for animation
            _PI->WriteDataPatch(0x45724E, "08 25 00 00");
            _PI->WriteDataPatch(0x457253, "40 01 00 00");
            _PI->WriteDataPatch(0x457258, "00");
            _PI->WriteDataPatch(0x45725A, "E0 01 00 00");

            _PI->WriteDataPatch(0x4D5CEE, "08 25 00 00");
            _PI->WriteDataPatch(0x4D5CF3, "40 01 00 00");
            _PI->WriteDataPatch(0x4D5CF8, "00");
            _PI->WriteDataPatch(0x4D5CFA, "E0 01 00 00");

            _PI->WriteDataPatch(0x4FC185, "08 25 00 00");
            _PI->WriteDataPatch(0x4FC18A, "40 01 00 00");
            _PI->WriteDataPatch(0x4FC18F, "00");
            _PI->WriteDataPatch(0x4FC191, "E0 01 00 00");

           
            // Spell book correction ля шрифтов Рус. СоД
            _PI->WriteByte(0x59C4F4, 0x2D);
            _PI->WriteByte(0x59C4F6, 0x69);
            _PI->WriteByte(0x59C4C5, 0x5D);
            _PI->WriteByte(0x59C51F, 0x69);
            _PI->WriteByte(0x59C522, 0x2F);

            _PI->WriteByte(0x59C574, 0x2D);
            _PI->WriteByte(0x59C576, 0x69);
            _PI->WriteByte(0x59C545, 0x32);
            _PI->WriteByte(0x59C59F, 0x69);
            _PI->WriteByte(0x59C5A2, 0x04);
            _PI->WriteByte(0x59C5A3, 0x02);
           
            /*
            // Spell book correction ля шрифтов Рус. AB
            _PI->WriteByte(0x59C4F4, 0x36);
            _PI->WriteByte(0x59C4F6, 0x60);
            _PI->WriteByte(0x59C574, 0x36);
            _PI->WriteByte(0x59C576, 0x60);

            _PI->WriteByte(0x59C4C5, 0x67);
            _PI->WriteByte(0x59C51F, 0x60);
            _PI->WriteByte(0x59C522, 0x27);

            _PI->WriteByte(0x59C545, 0x3F);
            _PI->WriteByte(0x59C59F, 0x60);
            _PI->WriteByte(0x59C5A2, 0xFF);
            _PI->WriteByte(0x59C5A3, 0x01);
            */

            // Hero level-up для шрифтов Рус. СоД
            _PI->WriteByte(0x4F9383, 0x44);
            _PI->WriteByte(0x4F938A, 0x04);
            _PI->WriteByte(0x4F938B, 0x01);

            // Hero level-up для шрифтов Рус. AB
            //_PI->WriteByte(0x4F9383, 0x61);
            //_PI->WriteByte(0x4F9385, 0x61);
            //_PI->WriteByte(0x4F9386, 0x01);
            //_PI->WriteByte(0x4F938A, 0xF0);
            //_PI->WriteByte(0x4F938B, 0x00);
            //_PI->WriteByte(0x4F938F, 0x10);   

        }
        break;
       

    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}


Новые версии с исправленными ошибками:
Верcия для использования шрифтов из буковского "Дыхания Смерти":
BukaSoD_RusFontsSoD.zip
(3.73 КБ) Скачиваний: 641


Верcия для использования шрифтов из буковского "Клинка Армагеддона":
BukaSoD_RusFontsAB.zip
(3.76 КБ) Скачиваний: 640
Последний раз редактировалось Ben80 01 мар 2019, 14:52, всего редактировалось 9 раз(а).
Вернуться к началу

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:05

Авторы: AlexSpl, as239

Название: Fresh Mod 1.0

Описание: Меняет награду Ульев и Консерваторий на существ 6-го и 7-го уровня стартового замка игрока соответственно. Кол-во получаемых существ 6-го и 7-го уровня зависит от начинки банка (пропорционально общему здоровью Виверн и Ангелов) и вычисляется по формулам:

N_Lvl6Creatures = [N_Wyverns * HP_Wyvern / HP_Lvl6Creature] и
N_Lvl7Creatures = [N_Angels * HP_Angel / HP_Lvl7Creature] соответственно.

 Код
Код: Выделить всё
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"

#include "..\HotA\homm3.h"

Patcher* _P;
PatcherInstance* _PI;
static _bool_ plugin_On = 0;

#define CREATURE_INFO_OFFSET (*(_ptr_*)0x47ADD1)
#define o_CreatureInfo ((_CreatureInfo_*)CREATURE_INFO_OFFSET)

int sEBX;
int originalCreatureID;
char originalCreatureN;

int __stdcall setCreatureBankReward(LoHook* h, HookContext* c)
{
    // Тип стартового замка
    const int TownType = *(int*)o_GameMgr->Offset(0x1F6A0 + 0x10 + o_ActivePlayerID * 4);
   
    const int Lvl6CreatureID = TownType == 8 ? CID_PSYCHIC_ELEMENTAL : 10 + TownType * 14;
    const int Lvl7CreatureID = TownType == 8 ? CID_FIREBIRD : 12 + TownType * 14;

    sEBX = c->ebx;
    originalCreatureID = *(int*)(c->ebx + 0x54);
    originalCreatureN = *(char*)(c->ebx + 0x58);

    if ( originalCreatureID == CID_WYVERN || originalCreatureID == CID_ANGEL ) {
        int CreatureID = originalCreatureID == CID_WYVERN ? Lvl6CreatureID : Lvl7CreatureID;
       
        // ID
        *(int*)(c->ebx + 0x54) = CreatureID;
        // N
        *(char*)(c->ebx + 0x58) =
            originalCreatureN * o_CreatureInfo[originalCreatureID].hit_points / o_CreatureInfo[CreatureID].hit_points;
        if ( *(char*)(c->ebx + 0x58) < 1 ) *(char*)(c->ebx + 0x58) = 1;
    }

    return EXEC_DEFAULT;
}

int __stdcall restoreOriginalReward(LoHook * h, HookContext * c)
{
    *(int*)(sEBX + 0x54) = originalCreatureID;
    *(char*)(sEBX + 0x58) = originalCreatureN;

    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((char*)"HD.Plugin.NewCreatureBanks");

            _PI->WriteLoHook(0x4ABBFA, setCreatureBankReward);
            _PI->WriteLoHook(0x4AC168, restoreOriginalReward);
        }
    }

    return TRUE;
}

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

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

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

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

Автор: Ben80

Название: RmgLesserBones

Описание: При генерации случайных карт создают монстров с меньшей численностью, но более высоким уровнем. В ГСК по умолчанию численность монстров ограничена числом 100, данный фикс заменяет его на 50.
Зачем это нужно ? Это очередной дополнительный момент, который помогает сделать игру более сбалансированной, более приближенной к игре на фикс картах NWC.
Простейшие следствия (если быть конкретным): ослабление некромантов, усиление магов/ослабление воинов, уменьшение среднего кол-ва получаемого опыта (вообще, играть при таком раскладе будет потяжелее).

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

        Patcher* _P;
        PatcherInstance* _PI;

        static _bool_ plugin_On = 0;


        int __stdcall rmgLesserBones(LoHook* h, HookContext* c)
        {
           c->eax = c->eax / 2;

           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.RmgLesserBones");

                 _PI->WriteLoHook(0x54111C, rmgLesserBones);

                }
            }

           return TRUE;
        }



RmgLesserBones.zip
(3.38 КБ) Скачиваний: 674
Последний раз редактировалось Ben80 13 авг 2019, 21:20, всего редактировалось 1 раз.
Вернуться к началу

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  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 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 КБ) Скачиваний: 484
Последний раз редактировалось Ben80 07 авг 2019, 13:59, всего редактировалось 1 раз.
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 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 КБ) Скачиваний: 495
Вернуться к началу

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 КБ) Скачиваний: 505
Быстрее всего смогу ответить вам в 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 МБ) Скачиваний: 510
Быстрее всего смогу ответить вам в Telegram: @PleaseAndThankYou
Вернуться к началу

Пред.След.

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

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

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