Объявления

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

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

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
offlineSerp  
 
Сообщения: 8
Зарегистрирован: 05 окт 2017, 11:21
Пол: Не указан
Поблагодарили: 14 раз.

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

Сообщение Serp » 28 окт 2017, 14:25

Authors:
RoseKavalier, Serp

Titel:
SpritesMageGuild1Dependency_Serp

Description:
Upgrading the Conflux magic lantern (from Pixies to Sprites) has only Mage Guild 1 as dependency. No Magic University, like it is in HoTA 1.42.

Works also in Multiplayer. Every player should have this plugin installed/uninstalled, to not mess up the game.
Tested only with HoTA.
(I added _Serp to my mods to make sure they have a unique name, so there will be no conflicts)

Code and includes taken from RoseKavaliers example here:
https://github.com/RoseKavalier/homm3_p ... s/main.cpp

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

Patcher* _P; // required for every plugin
PatcherInstance* _PI;
static _bool_ plugin_On = 0;

int __stdcall new_town_dependencies(LoHook *h, HookContext *c)
{
   // IDs see town_dependencies.h file
   o_TownDependencies->ChangeDependency(TOWN_ID_CONFLUX, BLD_ID_DWELL1U, BLD_REQ_MAGE1); // town, building, dependencies seperated by |
   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.SpritesMageGuild1Dependency_Serp");
           
         _PI->WriteLoHook(0x4EEA79, new_town_dependencies); // right after big HotA DLL modifications
        }
    }
    return TRUE;
}
Вложения
SpritesMageGuild1Dependency_Serp.zip
(4.43 КБ) Скачиваний: 674
Последний раз редактировалось Serp 28 окт 2017, 21:10, всего редактировалось 1 раз.
Вернуться к началу

offlineSerp  
 
Сообщения: 8
Зарегистрирован: 05 окт 2017, 11:21
Пол: Не указан
Поблагодарили: 14 раз.

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

Сообщение Serp » 28 окт 2017, 14:52

Authors:
RoseKavalier, Serp

Titel:
FirebirdsImmuneFireMagic_Serp

Description:
Firebirds are again immune to fire magic (in HotA 1.42 they normally only have 50% damage reduction).
Does NOT change firebirds description, so it will still show the 50% damage reduction!
Also it does not change the AI value back to orignal.
Comment from phoenix4ever:
"don't forget to change Firebird AI Value, in crtraits.txt, from 4336 -> 4547 like in original game."
(If I find out how to do this in plugin, I may add a version 2 of the plugin to this post)

Works also in Multiplayer. Every player should have this plugin installed/uninstalled, to not mess up the game.
Tested only with HoTA.
(I added _Serp to my mods to make sure they have a unique name, so there will be no conflicts)

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

Patcher* _P; // required for every plugin
PatcherInstance* _PI;
static _bool_ plugin_On = 0;

int __stdcall firebirdsimmunefiremagic(LoHook *h, HookContext *c)
{
   o_pCreatureInfo[CID_FIREBIRD].flags = 0x409B;
   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.FirebirdsImmuneFireMagic_Serp");
           
         _PI->WriteLoHook(0x4EEA79, firebirdsimmunefiremagic); // right after big HotA DLL modifications
        }
    }
    return TRUE;
}
Вложения
FirebirdsImmuneFireMagic.zip
(4.29 КБ) Скачиваний: 586
Вернуться к началу

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

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

Сообщение Ben80 » 08 июл 2018, 05:35

Автор: Ben80, RoseKavalier, igrik

Название: Ben_BugFixes

Описание: Исправляет ряд багов оригинальной игры (Shadow of Death), не исправленных в HD моде:

- баг урона, получаемого от стрелковых башен при наличии вторичного навыка "Доспехи" или наложенного заклинания "Воздушный щит" или для окамененевшего существа (RoseKavalier)
- баг получения дополнительных очков перемещения по морю всем игрокам вместо владельца маяка (RoseKavalier)
- баг несрабатывания удачи в битве для существ без героя
- вылет игры при нападении ИИ на героя без существ (RoseKavalier)
- баги интерфейса для Сказочных Драконов (RoseKavalier, igrik)
- баг, связанный с нападением Гарпий на Дендроидов (igrik)
- баг заклинания "Маскировка" (заклинание действовало в течение одного игрового дня, а не одного цикла ходов игроков)
- баг получения бесконечного количества очков перемещения, используя Шляпу Адмирала
- баг получения бонусов Защиты и Атаки для Обелиска Крови и Знаков Страха (фракция "Крепость")
- баг уничтожения отрядов заклинанием "Землетрясение" (RoseKavalier)
- баг непересчета морских очков перемещения в сухопутные при побеге героя в битве на море


Совместимость: вряд ли будет совместимость с плагинами, которые также исправляют баги оригинальной игры (например, SoD_SP) или существенно изменяют геймплей. А вот с такими плагинами, как SuperPack_Rus, проблем совместимости быть не должно.

Версии игры: Дыхание смерти либо Полное Собрание с установленным HD модом (рекомендуется версия 3.811f)

Режим игры: любой - синглплеер, мультиплеер, сетевой, хотсит, кампании и тд.

Обновлено 08.06.2021:
Ben_BugFixes.zip
(4.53 КБ) Скачиваний: 411
Последний раз редактировалось Ben80 08 июн 2021, 10:35, всего редактировалось 3 раз(а).
Вернуться к началу

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

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

Сообщение Ben80 » 31 авг 2018, 14:16

Автор: Ben80

Название: AIManaSaving

Описание: Позволяет ИИ экономить ману в битвах с нейтралами, чтобы быть более боеготовым ко встрече с человеком, и для того, чтобы более успешно сражаться с сильными нейтралами.
Работает следующим образом: если армия нейтралов в 2 и более раз слабее героя и армии ИИ, то расходовать ману ИИ не дозволяется. При усилении армии нейтралов лимит расхода маны растет от 0 до полного запаса маны. Полный запас дозволяется расходовать в том случае, если армия нейтралов равна или сильнее героя ИИ и его армии.

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

Patcher* _P;
PatcherInstance* _PI;

static _bool_ plugin_On = 0;
int savedMana;

int __stdcall saveAIMana(LoHook* h, HookContext* c)
{
    _Hero_* hero = (_Hero_*)(*(int*)(c->ebp + 0xC));

    if(o_ActivePlayer->IsHuman() == false)
    {
        int heroSSkillSpec;
        int maxMana;
        int intelligenceLevel = (int)(*(_byte_*)((int)hero + 225));
        float intelligenceMultiplier = *(float*)(0x63EA88 + 4 * intelligenceLevel);
        int monsterID = (int)(*(unsigned short*)(c->edi + 34));
        int monsterNumber = (int)((*(int*)(c->edi)) & 0xFFF);
        int neutralsPower = monsterNumber * o_pCreatureInfo[monsterID].AI_value;
        int armyPower;
        __int64 yourLong;
        yourLong = CALL_1(__int64, __thiscall, 0x427650, hero);
        long tempLong = ((yourLong >> 32) << 32); //shift it right then left 32 bits, which zeroes the lower half of the long
        armyPower = (int)(yourLong - tempLong);
       
        // if Spec is SecSkill
        if(*(int*)(*(int*)0x679C80 + hero->id * 40) == 0)
            heroSSkillSpec = *(int*)(*(int*)0x679C80 + hero->id * 40 + 4);
        // if Spec is Intelligence
        if(heroSSkillSpec == 24)
            intelligenceMultiplier = (1.0 + 0.05 * hero->level) * intelligenceMultiplier;
       
        maxMana = hero->knowledge * 10 * (1.0 + intelligenceMultiplier);
        int minAllowedMana;
        if(neutralsPower >= armyPower)
            minAllowedMana = 0;
        else
            if((float)neutralsPower/(float)armyPower > 0.5)
                minAllowedMana = ((1.0 - (float)neutralsPower/(float)armyPower) * 2.0) * maxMana;
            else
                minAllowedMana = maxMana;

        if(minAllowedMana > maxMana)
            minAllowedMana = maxMana;

        if(hero->spell_points > minAllowedMana)
        {
            savedMana = minAllowedMana;
            hero->spell_points = hero->spell_points - savedMana;
        }
        else
        {
            savedMana = hero->spell_points;
            hero->spell_points = 0;
        }
    }
 
    return EXEC_DEFAULT;
}

int __stdcall restoreAIMana(LoHook* h, HookContext* c)
{
    _Hero_* hero = (_Hero_*)(*(int*)(c->ebp + 0xC));
    if(o_ActivePlayer->IsHuman() == false)
        hero->spell_points = hero->spell_points + savedMana;
 
    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.AIManaSaving");

            // Save AI mana to restore after battle
            _PI->WriteLoHook(0x4A768C, saveAIMana);
            _PI->WriteLoHook(0x4A7697, restoreAIMana);

        }
    }

   return TRUE;
}


Версия 1.2 (исправленная):
AIManaSaving.zip
(3.99 КБ) Скачиваний: 544
Последний раз редактировалось Ben80 23 ноя 2019, 14:49, всего редактировалось 2 раз(а).
Вернуться к началу

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

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

Сообщение Ben80 » 14 сен 2018, 22:33

Автор: Ben80

Название: SetRandomMines

Описание: Для игрового шаблона 4SM0d позволяет сделать случайным тип шахт для зон 1,2,3,4
(ртуть, сера, кристаллы, самоцветы).

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

Patcher* _P;
PatcherInstance* _PI;

static _bool_ plugin_On = 0;

int __stdcall setMines(LoHook* h, HookContext* c)
{
    int addrTempl = c->edx;
    _ZoneSettings_* zs;
    unsigned int dice;

    for(int j = 0; j<4; j++)
    {
        rand_s(&dice);
        dice = (unsigned int) ((double)dice /((double) UINT_MAX + 1 ) * 4.0) + 1;
        if(dice == 1)
            dice = 1;
        else
            dice++;
       
        zs = CALL_2(_ZoneSettings_*, __thiscall, 0x533570, addrTempl, j);
        zs->min_mines[1] = 0;
        zs->min_mines[3] = 0;
        zs->min_mines[4] = 0;
        zs->min_mines[5] = 0;
        zs->min_mines[dice] = 1;
        for(int i = 0; i<6; i++)
            zs->mines_density[i] = 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.SetRandomMines");

            _PI->WriteLoHook(0x549EA4, setMines);
        }
    }

   return TRUE;
}




Исправленная версия плагина (была небольшая ошибка, к сожалению):
SetRandomMines.zip
(3.56 КБ) Скачиваний: 523
Последний раз редактировалось Ben80 13 фев 2019, 14:04, всего редактировалось 4 раз(а).
Вернуться к началу

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 раз.
Вернуться к началу

Пред.След.

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

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

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