Объявления

Форум о Героях Меча и Магии и King's Bounty. Если Вы любите эти игры, мы будем рады видеть Вас в наших рядах. :smile2:
Для активации Вашей учетной записи необходимо написать письмо на почтовый ящик dumai-spb@mail.ru или vdv_forever@bk.ru с указанием зарегистрированного Вами ника

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

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

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 КБ) Скачиваний: 167
Последний раз редактировалось Serp 28 окт 2017, 21:10, всего редактировалось 1 раз.
Вернуться к началу

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

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 КБ) Скачиваний: 43
Вернуться к началу

offlineBen80
Мастер
Мастер
 
Сообщения: 455
Зарегистрирован: 18 июн 2017, 06:49
Поблагодарили: 74 раз.

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

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

Автор: Ben80, RoseKavalier, igrik

Название: Ben_BugFixes

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

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

Дополнительно отменено спорное решение HD мода (при опции HD+), приводящее к получению в Нага банке драг. камней как бонуса вместо серы.

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

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

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

Ben_BugFixes_v1.0.zip
(4.39 КБ) Скачиваний: 114
Вернуться к началу

offlineBen80
Мастер
Мастер
 
Сообщения: 455
Зарегистрирован: 18 июн 2017, 06:49
Поблагодарили: 74 раз.

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;
}


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

offlineBen80
Мастер
Мастер
 
Сообщения: 455
Зарегистрирован: 18 июн 2017, 06:49
Поблагодарили: 74 раз.

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 = 1; 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.73 КБ) Скачиваний: 24
Вернуться к началу

offlineigrik
Новичок
Новичок
 
Сообщения: 20
Зарегистрирован: 14 сен 2017, 12:35
Поблагодарили: 16 раз.

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

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

Автор: igrik

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

Изображение

 код
Код: Выделить всё
// есть ли стража рядом с объектом (возвращает координаты клетки с монстрами)
_int_ isGuardNearTheObject(_AdvMgr_* advMng, _int_ xyz)
{
   int xd = b_unpack_x(xyz);
   int yd = b_unpack_y(xyz);
   int z = b_unpack_z(xyz);
   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)
{
   if ( obj->object_type == 5 || obj->object_type == 6 || obj->object_type == 93 ) { // если объект под мышью артефакт(5), пандора (6) или свиток (93)
      if ( isGuardNearTheObject(advMng, advMng->pack_xyz) ) {
         return 5; // возвратить тип курсора (атакующий меч)
      }
   }
   // если монстров вокруг артефакта нет выполняем стандартную функцию
   return CALL_2(_int_, __thiscall, hook->GetDefaultFunc(), advMng, obj);
}

// при взятии артефакта, пандоры или свитка
_byte_ __stdcall Y_HeroGetObjWithGuard(HiHook* hook, _AdvMgr_* advMng, _Hero_* hero, _MapItem_* obj, _int_ xyz, _byte_ isNotAI)
{
   int 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));
      advMng->monBattle_type = (_word_)obj_54->os_type; // (advMng+<536>)
      advMng->monBattle_num = (_word_)obj_54->draw_num; // (advMng+<540>)
      advMng->monBattle_side = hero->x < (_word_)((_word_)(xyz_54 << 6) >> 6) ? 1 : 0; // поворот монстра при атаке (advMng+<544>)
      CALL_5(void, __thiscall, 0x4A73B0, advMng, obj_54, hero, xyz_54, isNotAI); // нападаем на монстра рядом с артом
      advMng->monBattle_type = -1; // после битвы возвращаем параметры
      advMng->monBattle_num = -1;  // после битвы возвращаем параметры
      if (hero->owner_id < 0) { // если герой убит или сбежал (т.е. номер хозяина героя стал == -1)
         return 0; // выйти из функции минуя функцию посещения артефакта
      }
   }
   // всё норм (монстры повержены или присоединились) - подбираем артефакт
   return CALL_5(_byte_, __thiscall, hook->GetDefaultFunc(), advMng, hero, obj, xyz, isNotAI);
}

// --------------------------------------------------------------------------------------
_PI->WriteHiHook(0x40E97F, CALL_, EXTENDED_, THISCALL_, Y_GetCursorFrameOnAdvMap);
_PI->WriteHiHook(0x4A82DE, CALL_, EXTENDED_, THISCALL_, Y_HeroGetObjWithGuard);
_PI->WriteHiHook(0x4A8305, CALL_, EXTENDED_, THISCALL_, Y_HeroGetObjWithGuard);
_PI->WriteHiHook(0x4A9D1C, CALL_, EXTENDED_, THISCALL_, Y_HeroGetObjWithGuard);
// --------------------------------------------------------------------------------------


upd (19.11.2018): обновленно из-за найденной ошибки (опечатки)
upd (21.11.2018): обновленно из-за серьезного недочета (была возможна передача отрицательных координат: например когда артефакт находился на границе карты (y=0) велся поиск на y=-1 что приводило к вылету)

Скачать
https://dl.dropboxusercontent.com/s/95j ... tGuard.dll
Вернуться к началу

offlineigrik
Новичок
Новичок
 
Сообщения: 20
Зарегистрирован: 14 сен 2017, 12:35
Поблагодарили: 16 раз.

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 КБ) Скачиваний: 16
Вернуться к началу

Пред.

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

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

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

cron