IPB

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V  < 1 2  
Reply to this topicStart new topic
> Небольшие моды и плагины.
feanor
сообщение 03 Feb 2015, 19:06
Сообщение #21

laughed as one fey
Сообщений: 11 809
Спасибо сказали: 19673 раза




Вуду-гарпии.

Иногда гарпии-ведьмы будут атаковать с места, не приближаясь к противнику. Анимация этой атаки будет отличаться от обычной.

Автор: feanor
Язык: нет
Формат: erm-скрипт. Установка через копирование в data/s любого мода.

voodoo.erm (1 Кб)



--------------------
Go to the top of the pageAdd Nick
 
+Quote Post
feanor
сообщение 10 Feb 2015, 03:13
Сообщение #22

laughed as one fey
Сообщений: 11 809
Спасибо сказали: 19673 раза




Иной формат даты.

Дни недели и месяцы именуются, а не нумеруются.

Автор: feanor
Язык: русский
Формат: dll-плагин. Установка через копирование в /eraplugins любого мода.

human_month_names.dll (8,5 Кб)



--------------------


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
feanor
сообщение 10 Feb 2015, 20:56 (Сообщение отредактировал feanor - 10 Feb 2015, 21:04)
Сообщение #23

laughed as one fey
Сообщений: 11 809
Спасибо сказали: 19673 раза




Иные виды снарядов-лучей.

Архимаги стреляют молниеподобными лучами, бехолдеры - лучами разноцветными (семь цветов радуги).

Автор: feanor
Язык: нет
Формат: erm-скрипт. Установка через копирование в data/s любого мода.
Старая тема: http://forum.df2.ru/index.php?showtopic=22685

rays.erm (1 Кб)





--------------------
Go to the top of the pageAdd Nick
 
+Quote Post
hippocamus
сообщение 12 Feb 2015, 16:27
Сообщение #24

Мяў, наверное...
Сообщений: 21 685
Спасибо сказали: 10203 раза




Приручённые нейтралы

Большинство нейтралов теперь принадлежат фракциям, к которым они сродны.
Орки на кабанах - Цитадель
Мумии - Некрополис
Тролли - Крепость
Крестьне - Замок
Воры - Темница
Хоббиты - Башня

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

автор: hippocamus
формат: bin для SOD, HotA + HD (возможно Era)
язык: отсутствует
Скачать (76 байт)


Кампанейские герои доступны как стартовые

На случайных картах можно стартовать любым героем

автор: возможно, МоП (я взял из ExeBuilder и перебил адреса, адаптировал под ХД)
формат: bin для SoD+HD (под Хоту не работает)
язык: отсутствует
Скачать (301 байт)


--------------------


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
Iv
сообщение 19 Feb 2015, 23:46
Сообщение #25

Immortal
Сообщений: 6 158
Спасибо сказали: 12376 раз




Больше колодцев для бога колодцев

Маленький патчик для рандомок. На карте генерится больше колодцев. Иногда даже слишком много

Автор: Iv (инфа от Sav)
Формат: bin-файл для Era II. Класть в \EraPlugins\AfterWoG\ любого активного мода



--------------------


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
feanor
сообщение 13 Mar 2015, 23:57 (Сообщение отредактировал feanor - 14 Mar 2015, 00:00)
Сообщение #26

laughed as one fey
Сообщений: 11 809
Спасибо сказали: 19673 раза




В честь минувших праздников полового диморфизма..

Зависящие от пола имена классов.

Автор: feanor
Язык: русский
Формат: папка с модом.

gcn.zip (6 Кб)



--------------------
Go to the top of the pageAdd Nick
 
+Quote Post
feanor
сообщение 14 Aug 2016, 00:56
Сообщение #27

laughed as one fey
Сообщений: 11 809
Спасибо сказали: 19673 раза




Анимированные существа на поле боя (порт из WoG 3.59)

Автор: sergroj
Портировано: feanor в рамках проекта TSW; разрешение автора получено.
Формат: папка с модом.

InstantAnimation.zip, 7 Кб

Скорости анимаций настраиваются индивидуально для каждого типа существ в файле anims.ini; существующие параметры взяты из блока monanim0 хотовского HotA.dat (версия 1.3.4), для вог-монстров взято по подобию.
Помимо этого, есть глобальный множитель, позволяющий ускорить или замедлить анимацию для всех монстров без пересчета всех параметров.


--------------------
Go to the top of the pageAdd Nick
 
+Quote Post
igrik
сообщение 21 Oct 2016, 19:17 (Сообщение отредактировал igrik - 10 Aug 2017, 09:57)
Сообщение #28

Immortal
Сообщений: 568
Спасибо сказали: 810 раз




Цифровое отображение морали и удачи в окне стека.
Как в MOP

автор: igrik
язык: нет
формат: dll (плагин для HD-мода)
версии: SoD/WoG/ERA

NumMoralLuck.dll (8.50kb)
Код
/////////////////////////////////////////////////////////
// Расширение диалога монстров:                        //
//     - отображение единиц удачи и морали (igrik)     //
//     - отображение длительности заклинаний (из HotA) //
/////////////////////////////////////////////////////////

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

// Объекты patcher_x86.
Patcher* _P;
PatcherInstance* _PI;


int __stdcall Y_MoralLuckBonus(LoHook* h, HookContext* c)
{
    // цифровое отображение морали
    if (*(int*)(c->edi+1256) < 1)
        sprintf(o_TextBuffer, "%d", *(int*)(c->edi+1256));
    else
        sprintf(o_TextBuffer, "+%d", *(int*)(c->edi+1256));

    int bonMoralNew = CALL_1 (int, __cdecl, 6386834, 80);
    int bonMoral = CALL_12 (int, __thiscall, 6014624, bonMoralNew, 48, 209, 20, 20, o_TextBuffer, "tiny.fnt", 4, 3006, 10, 0, 8);

    CALL_4 (int, __thiscall, 0x5FE2D0, c->ebx, *(int*)(c->ebx+8), 1, &bonMoral);

    // цифровое отображение удачи
    if (*(int*)(c->edi+1260) < 1)
        sprintf(o_TextBuffer, "%d", *(int*)(c->edi+1260));
    else
        sprintf(o_TextBuffer, "+%d", *(int*)(c->edi+1260));

    int bonLuckNew = CALL_1 (int, __cdecl, 6386834, 80);
    int bonLuck = CALL_12 (int, __thiscall, 6014624, bonLuckNew, 101, 209, 20, 20, o_TextBuffer, "tiny.fnt", 4, 3007, 10, 0, 8);

    CALL_4 (int, __thiscall, 0x5FE2D0, c->ebx, *(int*)(c->ebx+8), 1, &bonLuck);

    return EXEC_DEFAULT;
}

int __stdcall Y_MoralLuckBonus2(LoHook* h, HookContext* c)
{
    if (*(int*)(c->ebx+104) < 1)
        sprintf(o_TextBuffer, "%d", *(int*)(c->ebx+104));
    else
        sprintf(o_TextBuffer, "+%d", *(int*)(c->ebx+104));    

    int bonMoralNew = CALL_1 (int, __cdecl, 6386834, 80);
    int bonMoral = CALL_12 (int, __thiscall, 6014624, bonMoralNew, 48, 209, 20, 20, o_TextBuffer, "tiny.fnt", 4, 3006, 10, 0, 8);
    CALL_4 (int, __thiscall, 0x5FE2D0, c->ebx+48, *(int*)(c->ebx+56), 1, &bonMoral);

    // отображение единиц удачи
    if (*(int*)(c->ebx+124) < 1)
        sprintf(o_TextBuffer, "%d", *(int*)(c->ebx+124));
    else
        sprintf(o_TextBuffer, "+%d", *(int*)(c->ebx+124));    

    int bonLuckNew = CALL_1 (int, __cdecl, 6386834, 80);
    int bonLuck = CALL_12 (int, __thiscall, 6014624, bonLuckNew, 101, 209, 20, 20, o_TextBuffer, "tiny.fnt", 4, 3007, 10, 0, 8);
    CALL_4 (int, __thiscall, 0x5FE2D0, c->ebx+48, *(int*)(c->ebx+56), 1, &bonLuck);

    return EXEC_DEFAULT;
}


int __stdcall Y_SpellShow(LoHook* h, HookContext* c)
{
    // цифровое отображение длительности заклинаний (вытащено из HotA.dll)
    int Spell = *(int*)(c->esi);
    int DlgShow = *(int*)(c->ebp-40);
    if (Spell >=0)
    {
        if (Spell == 47 || Spell == 59 || Spell == 72)
            int Spell = 47;
        else
        {
            sprintf(o_TextBuffer, "x%d", *(int*)(c->esi+12));
            int SpellNew = CALL_1 (int, __cdecl, 6386834, 80);
            int SpellShow = CALL_12 (int, __thiscall, 6014624, SpellNew, *(int*)(c->ebp-28), 202, 46, 20, o_TextBuffer, "tiny.fnt", 4, 3003 - *(int*)(c->ebp-32), 10, 0, 8);
            CALL_4 (int, __thiscall, 0x5FE2D0, DlgShow + 48, *(int*)(DlgShow +56), 1, &SpellShow);
        }    
    }
    return EXEC_DEFAULT;
}


int __stdcall Y_SpellInfo1(LoHook* h, HookContext* c)
{
    // в этой функции я не смог поставить HiHook
    // потому что в WoGе после её выполнения вылетает
    if( c->eax >= 3000 && c->eax <= 3007 )
    {    
        switch (c->eax){
            case 3000: c->eax = 11; break;    // спелл_1
            case 3001: c->eax = 11; break;    // спелл_2
            case 3002: c->eax = 11; break;    // спелл_3    
            case 3006: c->eax = 9; break;    // мораль    
            case 3007: c->eax = 10; break;    // удача
            default: c->eax = -1; break;    // на всякий
        }        
        c->return_address = 0x5F4B34;
        return NO_EXEC_DEFAULT;    
    }
    return EXEC_DEFAULT;
}


int __stdcall Y_SpellInfo2(LoHook* h, HookContext* c)
{
    // подсказка для циферных отображений спеллов, морали и удачи
    switch (c->esi){
        case 3000: c->esi = 221; break; // спелл_1
        case 3001: c->esi = 222; break; // спелл_2
        case 3002: c->esi = 223; break; // спелл_3    
        case 3006: c->esi = 219; break; // мораль    
        case 3007: c->esi = 220; break;    // удача
    }
    return EXEC_DEFAULT;
}


int __stdcall Y_SpellShow1(LoHook* h, HookContext* c)
{
    int New = CALL_1 (int, __cdecl, 0x617492, 80);
    int SpellShow = CALL_12 (int, __thiscall, 6014624, New, 15, c->ebx + 16, 46, 20, "", "tiny.fnt", 4, c->edi + 3003, 10, 0, 8);
    CALL_4 (int, __thiscall, 0x4230D0, c->esi, *(int*)(c->esi + 8), 1, &SpellShow);
    return EXEC_DEFAULT;
}

int __stdcall Y_SpellShow2(LoHook* h, HookContext* c)
{
    int New = CALL_1 (int, __cdecl, 0x617492, 80);
    int SpellShow = CALL_12 (int, __thiscall, 6014624, New, 15, *(int*)(c->ebp + 24) + 16, 46, 20, "", "tiny.fnt", 4, c->ebx + 3003, 10, 0, 8);
    CALL_4 (int, __thiscall, 0x4230D0, c->esi, *(int*)(c->esi + 8), 1, &SpellShow);
    return EXEC_DEFAULT;
}


int __stdcall Y_SpellShow3(LoHook* h, HookContext* c)
{
    _Dlg_* dlg = (_Dlg_*)(c->edi + 56);
    int item = 3006 - *(int*)(c->ebp + 8);
    int spell = *(int*)c->esp - 1;

    if (spell >= 0 && spell != 47 && spell != 59 && spell != 72)
        sprintf(o_TextBuffer, "x%d", *(int*)(c->esi + 4 * spell + 408));
    else
        sprintf(o_TextBuffer, "");

    ((_DlgStaticText_*)dlg->GetItem(item))->SetText(o_TextBuffer);

    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("MonDescription");           
         
            // Патч на tiny.fnt малые описания монстров (все в DEC)
            *(int*)6243434 = 6687924; // в бою
            *(int*)6244485 = 6687924; // при покупке
            *(int*)6241855 = 6687924; // не в бою
                
            _PI->WriteLoHook(0x5F3C43, Y_MoralLuckBonus);    // мораль и удача в бою
            _PI->WriteLoHook(0x5F439B, Y_MoralLuckBonus2);    // мораль и удача вне в боя

            // отображение длительности заклинаний в окне монстра (вытащено из HotA.dll)
            _PI->WriteLoHook(0x5F6BE2, Y_SpellShow);
            _PI->WriteLoHook(0x5F4B05, Y_SpellInfo1);  // тут WoG/ERA не дают поставить HiHook  
            _PI->WriteLoHook(0x5F522A, Y_SpellInfo2);
            // отображение длительности заклинаний в расширенной статистике (вытащено из HotA.dll)
            _PI->WriteLoHook(0x46D12B, Y_SpellShow1);    
            _PI->WriteLoHook(0x46D4CB, Y_SpellShow2);    
            _PI->WriteLoHook(0x46D9F0, Y_SpellShow3);

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



--------------------
Go to the top of the pageAdd Nick
 
+Quote Post
Ben
сообщение 08 Aug 2017, 21:11 (Сообщение отредактировал Ben - 15 Sep 2017, 13:18)
Сообщение #29

Member
Сообщений: 86
Спасибо сказали: 48 раз




Новая версия заклинания Городской портал

Авторы: AlexSpl, Ben
Dll плагин к HD моду.
Теперь на любом уровне магии Земли можно выбирать город. Существенно увеличились расходы MP - для основного уровня 1200 MP, для продвинутого 1000 MP, для эксперта 800 MP.
AI в курсе введенных изменений, применяет Городской портал для перемещения в нужный город, даже не имея навыка Магия Земли.

Код
#include "..\..\include\homm3.h"

// объекты patcher_x86.
Patcher* _P;
PatcherInstance* _PI;

int __stdcall tpCostForHuman(LoHook* h, HookContext* c)
{
   *(int*)(c->ebp - 0x40) = 1200;
   *(int*)(c->ebp - 0x3C) = 1200;
   *(int*)(c->ebp - 0x38) = 1000;
   *(int*)(c->ebp - 0x34) = 800;
  
   return EXEC_DEFAULT;
}

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


int __stdcall mpointsEarth_1(LoHook* h, HookContext* c) {
   int level = c->eax;
   int mpoints[] = {1200, 1200, 1000, 800};
   c->eax = mpoints[level];
  
   c->return_address = 0x56B5AA;
   return NO_EXEC_DEFAULT;
}

int __stdcall mpointsEarth_2(LoHook* h, HookContext* c) {
   int level = c->eax;
   int mpoints[] = {1200, 1200, 1000, 800};
   c->eax = mpoints[level];
   c->ecx = *(int*)(c->esi + 0x4D);
  
   c->return_address = 0x430532;
   return NO_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("HD.Plugin.TownPortal");
            
            _PI->WriteLoHook(0x41D538, tpCostForHuman); // меняем расходы MP c 300/300/200 на 1200/1000/800
            _PI->WriteHexPatch(0x41D6D1, "90 90 90 90 90 90 90 90 90 90"); // отменяем проверку на уровень Магии Земли в главной функции заклинания
            _PI->WriteLoHook(0x56B59B, mpointsEarth_1); // расходы MP во вспомогат. функции 1
            _PI->WriteHexPatch(0x56B3B4, "90 90 90 90 90 90"); // отменяем проверку на уровень Магии Земли во вспомогат. функции 1
            _PI->WriteLoHook(0x430520, mpointsEarth_2); // расходы MP во вспомогат. функции 2
            _PI->WriteLoHook(0x41D934, skipTownPortalConfirm); // обходим jmp патч HD мода (версии 3.809 и выше)
        }
        break;

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


Ссылка на DLL:
https://yadi.sk/d/BMehvHpF3MuoqR


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
igrik
сообщение 09 Aug 2017, 17:47 (Сообщение отредактировал igrik - 09 Aug 2017, 17:59)
Сообщение #30

Immortal
Сообщений: 568
Спасибо сказали: 810 раз




А где сама DLL?

Кстати забыл. Тестировал. Багов не обнаружил, поэтому включил и в мультиплеере.
Автоулучшение существ в городе.

автор: [igrik]
язык: нет
формат: dll (плагин для HD-мода)
версии: SoD/HotA/ERA

HD_Plugin.AutoGradeMonInTown (10.5kb)
Плагин позволяет улучшать существ в городе по комбинации клавиш [ЛКМ+A] (левая кнопка мыши + "A" в английской раскладке или "Ф" в русской раскладке):
- [ЛКМ+A] на иконке героя (или флаге): улучшение всех существ у данного героя/города. Исключения: Скелеты в Скелетов-Воинов, Корсары в Морских Волков (для HotA), специалисты по улучшению существ (например Джелу);
- [ЛКМ+A] на стеке: улучшение выбранного стека. Исключения: Корсары в Морских Волков (для HotA), специалисты по улучшению существ (например Джелу);

Поддерживаемые версии HoMM3: SoD, HotA, ERA/WoG.
Способ установки: это плагин для HD мода и его необходимо скопировать в "..[Ваша папка героев]\_HD3_Data\Packs\[Любое название]\.." и подключить это "Любое название" в лаунчере HD мода.
Код
//////////////////////////////////////////////////////////
// Плагин автоматического улучшения существ в городе    //
// Автор: [igrik]                                        //
/////////////////////////////////////////////////////////

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

// Объекты patcher_x86.
Patcher* _P;
PatcherInstance* _PI;


// улучшение всех стеков у героя или в городе
_bool_ Y_AutoGradeMonInTownFunc(_Town_* town, char type){

_Player_* me = o_GameMgr->GetMe();
int cost_res[7];

if (!me->IsActive()) return false;

    if (type != 0 ) // если не город
    {
        _Hero_* hero = 0;

        if (type == 1)
             hero = o_GameMgr->GetHero(town->up_hero_id);
        else hero = o_GameMgr->GetHero(town->down_hero_id);

        if (me->id != hero->owner_id) return false;

        for (char i = 0; i < 7; i++ )
        {
            if( hero->army.type[i] >= 0 )
            {
                if ( GetCreatureGrade(hero->army.type[i]) != -1 && hero->army.type[i] != 158 && hero->army.type[i] != 56)  
                {
                    if( town->IsBuildingBuilt(37 + o_pCreatureInfo[GetCreatureGrade(hero->army.type[i])].level, 1) && town->type == o_pCreatureInfo[hero->army.type[i]].town )    
                    {
                        cost_res[0] = (o_pCreatureInfo[GetCreatureGrade(hero->army.type[i])].cost.wood * hero->army.count[i]) - (o_pCreatureInfo[hero->army.type[i]].cost.wood * hero->army.count[i]);
                        cost_res[1] = (o_pCreatureInfo[GetCreatureGrade(hero->army.type[i])].cost.mercury * hero->army.count[i]) - (o_pCreatureInfo[hero->army.type[i]].cost.mercury * hero->army.count[i]);
                        cost_res[2] = (o_pCreatureInfo[GetCreatureGrade(hero->army.type[i])].cost.ore * hero->army.count[i]) - (o_pCreatureInfo[hero->army.type[i]].cost.ore * hero->army.count[i]);
                        cost_res[3] = (o_pCreatureInfo[GetCreatureGrade(hero->army.type[i])].cost.sulfur * hero->army.count[i]) - (o_pCreatureInfo[hero->army.type[i]].cost.sulfur * hero->army.count[i]);
                        cost_res[4] = (o_pCreatureInfo[GetCreatureGrade(hero->army.type[i])].cost.crystal * hero->army.count[i]) - (o_pCreatureInfo[hero->army.type[i]].cost.crystal * hero->army.count[i]);
                        cost_res[5] = (o_pCreatureInfo[GetCreatureGrade(hero->army.type[i])].cost.jems * hero->army.count[i]) - (o_pCreatureInfo[hero->army.type[i]].cost.jems * hero->army.count[i]);
                        cost_res[6] = (o_pCreatureInfo[GetCreatureGrade(hero->army.type[i])].cost.gold * hero->army.count[i]) - (o_pCreatureInfo[hero->army.type[i]].cost.gold * hero->army.count[i]);

                        if (me->resourses.wood >= cost_res[0] && me->resourses.mercury >= cost_res[1] && me->resourses.ore >= cost_res[2] && me->resourses.sulfur >= cost_res[3] && me->resourses.crystal >= cost_res[4] && me->resourses.jems >= cost_res[5] && me->resourses.gold >= cost_res[6])
                        {
                            me->resourses.wood    -= cost_res[0];
                            me->resourses.mercury -= cost_res[1];
                            me->resourses.ore     -= cost_res[2];
                            me->resourses.sulfur  -= cost_res[3];
                            me->resourses.crystal -= cost_res[4];
                            me->resourses.jems    -= cost_res[5];
                            me->resourses.gold    -= cost_res[6];
                            hero->army.type[i] = GetCreatureGrade(hero->army.type[i]);    
                        }
                    }                
                }
            }
        }
        return true;
    }
    else
    {
        if (me->id != town->owner_id) return false;

        for (char i = 0; i < 7; i++ )
        {
            if( town->guards.type[i] >= 0 )
            {
                if ( GetCreatureGrade(town->guards.type[i]) != -1 && town->guards.type[i] != 158 && town->guards.type[i] != 56)
                {
                    if( town->IsBuildingBuilt(37 + o_pCreatureInfo[GetCreatureGrade(town->guards.type[i])].level, 1) && town->type == o_pCreatureInfo[town->guards.type[i]].town )    
                    {
                        cost_res[0] = (o_pCreatureInfo[GetCreatureGrade(town->guards.type[i])].cost.wood * town->guards.count[i]) - (o_pCreatureInfo[town->guards.type[i]].cost.wood * town->guards.count[i]);
                        cost_res[1] = (o_pCreatureInfo[GetCreatureGrade(town->guards.type[i])].cost.mercury * town->guards.count[i]) - (o_pCreatureInfo[town->guards.type[i]].cost.mercury * town->guards.count[i]);
                        cost_res[2] = (o_pCreatureInfo[GetCreatureGrade(town->guards.type[i])].cost.ore * town->guards.count[i]) - (o_pCreatureInfo[town->guards.type[i]].cost.ore * town->guards.count[i]);
                        cost_res[3] = (o_pCreatureInfo[GetCreatureGrade(town->guards.type[i])].cost.sulfur * town->guards.count[i]) - (o_pCreatureInfo[town->guards.type[i]].cost.sulfur * town->guards.count[i]);
                        cost_res[4] = (o_pCreatureInfo[GetCreatureGrade(town->guards.type[i])].cost.crystal * town->guards.count[i]) - (o_pCreatureInfo[town->guards.type[i]].cost.crystal * town->guards.count[i]);
                        cost_res[5] = (o_pCreatureInfo[GetCreatureGrade(town->guards.type[i])].cost.jems * town->guards.count[i]) - (o_pCreatureInfo[town->guards.type[i]].cost.jems * town->guards.count[i]);
                        cost_res[6] = (o_pCreatureInfo[GetCreatureGrade(town->guards.type[i])].cost.gold * town->guards.count[i]) - (o_pCreatureInfo[town->guards.type[i]].cost.gold * town->guards.count[i]);

                        if (me->resourses.wood >= cost_res[0] && me->resourses.mercury >= cost_res[1] && me->resourses.ore >= cost_res[2] && me->resourses.sulfur >= cost_res[3] && me->resourses.crystal >= cost_res[4] && me->resourses.jems >= cost_res[5] && me->resourses.gold >= cost_res[6])
                        {
                            me->resourses.wood    -= cost_res[0];
                            me->resourses.mercury -= cost_res[1];
                            me->resourses.ore     -= cost_res[2];
                            me->resourses.sulfur  -= cost_res[3];
                            me->resourses.crystal -= cost_res[4];
                            me->resourses.jems    -= cost_res[5];
                            me->resourses.gold    -= cost_res[6];
                            town->guards.type[i] = GetCreatureGrade(town->guards.type[i]);    
                        }
                    }                
                }
            }
        }
        return true;
    }

return false;
}

// улучшение одного стека у героя
_bool_ Y_AutoGradeMonInTownOne_H(_Town_* town, char type, char i)
{
    _Player_* me = o_GameMgr->GetMe();
    if (!me->IsActive()) return false;

    int cost_res[7];
    _Hero_* hero = 0;

    if (type == 1)
            hero = o_GameMgr->GetHero(town->up_hero_id);
    else hero = o_GameMgr->GetHero(town->down_hero_id);

    if (me->id != hero->owner_id || hero->army.type[i] == -1 ) return false;

    if ( GetCreatureGrade(hero->army.type[i]) != -1 && hero->army.type[i] != 158 )  
    {
        if( town->IsBuildingBuilt(37 + o_pCreatureInfo[GetCreatureGrade(hero->army.type[i])].level, 1) && town->type == o_pCreatureInfo[hero->army.type[i]].town )    
        {
            cost_res[0] = (o_pCreatureInfo[GetCreatureGrade(hero->army.type[i])].cost.wood * hero->army.count[i]) - (o_pCreatureInfo[hero->army.type[i]].cost.wood * hero->army.count[i]);
            cost_res[1] = (o_pCreatureInfo[GetCreatureGrade(hero->army.type[i])].cost.mercury * hero->army.count[i]) - (o_pCreatureInfo[hero->army.type[i]].cost.mercury * hero->army.count[i]);
            cost_res[2] = (o_pCreatureInfo[GetCreatureGrade(hero->army.type[i])].cost.ore * hero->army.count[i]) - (o_pCreatureInfo[hero->army.type[i]].cost.ore * hero->army.count[i]);
            cost_res[3] = (o_pCreatureInfo[GetCreatureGrade(hero->army.type[i])].cost.sulfur * hero->army.count[i]) - (o_pCreatureInfo[hero->army.type[i]].cost.sulfur * hero->army.count[i]);
            cost_res[4] = (o_pCreatureInfo[GetCreatureGrade(hero->army.type[i])].cost.crystal * hero->army.count[i]) - (o_pCreatureInfo[hero->army.type[i]].cost.crystal * hero->army.count[i]);
            cost_res[5] = (o_pCreatureInfo[GetCreatureGrade(hero->army.type[i])].cost.jems * hero->army.count[i]) - (o_pCreatureInfo[hero->army.type[i]].cost.jems * hero->army.count[i]);
            cost_res[6] = (o_pCreatureInfo[GetCreatureGrade(hero->army.type[i])].cost.gold * hero->army.count[i]) - (o_pCreatureInfo[hero->army.type[i]].cost.gold * hero->army.count[i]);

            if (me->resourses.wood >= cost_res[0] && me->resourses.mercury >= cost_res[1] && me->resourses.ore >= cost_res[2] && me->resourses.sulfur >= cost_res[3] && me->resourses.crystal >= cost_res[4] && me->resourses.jems >= cost_res[5] && me->resourses.gold >= cost_res[6])
            {
                me->resourses.wood    -= cost_res[0];
                me->resourses.mercury -= cost_res[1];
                me->resourses.ore     -= cost_res[2];
                me->resourses.sulfur  -= cost_res[3];
                me->resourses.crystal -= cost_res[4];
                me->resourses.jems    -= cost_res[5];
                me->resourses.gold    -= cost_res[6];
                hero->army.type[i] = GetCreatureGrade(hero->army.type[i]);    
                return true;
            }
        }
    }
return false;
}

// улучшение одного стека в городе без героя
_bool_ Y_AutoGradeMonInTownOne_T(_Town_* town, char type, char i)
{
    _Player_* me = o_GameMgr->GetMe();
    if (!me->IsActive()) return false;

    int cost_res[7];

    if (me->id != town->owner_id || town->guards.type[i] == -1 ) return false;

    if ( GetCreatureGrade(town->guards.type[i]) != -1 && town->guards.type[i] != 158 )  
    {
        if( town->IsBuildingBuilt(37 + o_pCreatureInfo[GetCreatureGrade(town->guards.type[i])].level, 1) && town->type == o_pCreatureInfo[town->guards.type[i]].town )    
        {
            cost_res[0] = (o_pCreatureInfo[GetCreatureGrade(town->guards.type[i])].cost.wood * town->guards.count[i]) - (o_pCreatureInfo[town->guards.type[i]].cost.wood * town->guards.count[i]);
            cost_res[1] = (o_pCreatureInfo[GetCreatureGrade(town->guards.type[i])].cost.mercury * town->guards.count[i]) - (o_pCreatureInfo[town->guards.type[i]].cost.mercury * town->guards.count[i]);
            cost_res[2] = (o_pCreatureInfo[GetCreatureGrade(town->guards.type[i])].cost.ore * town->guards.count[i]) - (o_pCreatureInfo[town->guards.type[i]].cost.ore * town->guards.count[i]);
            cost_res[3] = (o_pCreatureInfo[GetCreatureGrade(town->guards.type[i])].cost.sulfur * town->guards.count[i]) - (o_pCreatureInfo[town->guards.type[i]].cost.sulfur * town->guards.count[i]);
            cost_res[4] = (o_pCreatureInfo[GetCreatureGrade(town->guards.type[i])].cost.crystal * town->guards.count[i]) - (o_pCreatureInfo[town->guards.type[i]].cost.crystal * town->guards.count[i]);
            cost_res[5] = (o_pCreatureInfo[GetCreatureGrade(town->guards.type[i])].cost.jems * town->guards.count[i]) - (o_pCreatureInfo[town->guards.type[i]].cost.jems * town->guards.count[i]);
            cost_res[6] = (o_pCreatureInfo[GetCreatureGrade(town->guards.type[i])].cost.gold * town->guards.count[i]) - (o_pCreatureInfo[town->guards.type[i]].cost.gold * town->guards.count[i]);

            if (me->resourses.wood >= cost_res[0] && me->resourses.mercury >= cost_res[1] && me->resourses.ore >= cost_res[2] && me->resourses.sulfur >= cost_res[3] && me->resourses.crystal >= cost_res[4] && me->resourses.jems >= cost_res[5] && me->resourses.gold >= cost_res[6])
            {
                me->resourses.wood    -= cost_res[0];
                me->resourses.mercury -= cost_res[1];
                me->resourses.ore     -= cost_res[2];
                me->resourses.sulfur  -= cost_res[3];
                me->resourses.crystal -= cost_res[4];
                me->resourses.jems    -= cost_res[5];
                me->resourses.gold    -= cost_res[6];
                town->guards.type[i] = GetCreatureGrade(town->guards.type[i]);    
                return true;
            }    
        }
    }
return false;
}

// автоулучшение существ в городе по ЛКМ+A
_int_ __stdcall Y_AutoGradeMonInTown(LoHook* h, HookContext* c)
{
    if (/* !o_IsOnlineGame && */ GetKeyState(65)<0 )
    {
        _bool_ done = 0;
        _Town_* town = o_TownMgr->town;
        int klick_id = c->edi;

        if(klick_id == 125 && town->down_hero_id != -1)
            done = Y_AutoGradeMonInTownFunc(town, 2);
        if(klick_id == 123 && town->up_hero_id != -1)
            done = Y_AutoGradeMonInTownFunc(town, 1);
        if(klick_id == 123 && town->up_hero_id == -1)
            done = Y_AutoGradeMonInTownFunc(town, 0);        

        if( klick_id >= 140 && klick_id <= 146 && town->down_hero_id != -1 )
            done = Y_AutoGradeMonInTownOne_H(town, 2, klick_id - 140);
        if( klick_id >= 115 && klick_id <= 121 && town->up_hero_id != -1 )
            done = Y_AutoGradeMonInTownOne_H(town, 1, klick_id - 115);
        if( klick_id >= 115 && klick_id <= 121 && town->up_hero_id == -1 )
            done = Y_AutoGradeMonInTownOne_T(town, 1, klick_id - 115);

        // обновить экран города
        if (done)
        {
            CALL_1(void, __thiscall, 0x5D5930, *(int*)0x69954C);     // отключить жёлтую обводку
            CALL_1(void, __thiscall, 0x5D5810, o_TownMgr);            // обновить экран города
            c->return_address = 0x5D460F;
            return NO_EXEC_DEFAULT;    
        }
    }
    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;    

            // Создаём объекты patcher_x86.
            _P = GetPatcher();
            _PI = _P->CreateInstance("HD_Plugin.AutoGradeMonInTown");

            _PI->WriteLoHook(0x5D45FD, Y_AutoGradeMonInTown);

        }
        break;

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


--------------------


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
Ben
сообщение 22 Aug 2017, 06:37 (Сообщение отредактировал Ben - 02 Oct 2017, 22:17)
Сообщение #31

Member
Сообщений: 86
Спасибо сказали: 48 раз




Цитата(fireman @ 21 Aug 2017, 23:09) *
Ben, закинь в гугл/яндекс диск в ближайшие лет 5 не умрёт точно


https://yadi.sk/d/Cgr-pvMX3NQmFW


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
Iv
сообщение 22 Aug 2017, 16:33
Сообщение #32

Immortal
Сообщений: 6 158
Спасибо сказали: 12376 раз




Напоминаю:

Цитата(feanor @ 25 Jul 2012, 11:30) *
Все обсуждения - в соседней теме.
..
Просьба здесь особо не обсуждать. Мне куда более доставляет складывать добро в чистую тему.


--------------------
Go to the top of the pageAdd Nick
 
+Quote Post
Ben
сообщение 02 Sep 2017, 17:46 (Сообщение отредактировал Ben - 02 Oct 2017, 22:21)
Сообщение #33

Member
Сообщений: 86
Спасибо сказали: 48 раз




Модификация Зыбучих песков и Мин

Dll плагин к HD моду.
Теперь количество этих объектов не 4/6/8, а 6/8/10.

С помощью SPTRAITS.txt это недостижимо.

Код
#include "..\..\include\homm3.h"

Patcher* _P;
PatcherInstance* _PI;


int __stdcall quicksandSpell(LoHook* h, HookContext* c)
{
    
    int peski[] = {6, 6, 8, 10};
    c->edi = peski[c->esi];
    
   return EXEC_DEFAULT;
}

int __stdcall minesSpell(LoHook* h, HookContext* c)
{
    
    int miny[] = {6, 6, 8, 10};
    c->edx = miny[c->esi];
    
   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("HD.Plugin.QuicksandMines");

_PI->WriteLoHook(0x5A066B, quicksandSpell);
_PI->WriteLoHook(0x5A0852, minesSpell);

}
break;

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



Сама Dll:
https://yadi.sk/d/5iwgKir_3NQmdY


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
Ben
сообщение 27 Sep 2017, 18:41 (Сообщение отредактировал Ben - 02 Oct 2017, 22:24)
Сообщение #34

Member
Сообщений: 86
Спасибо сказали: 48 раз




Улучшение вторичного навыка Обучение

Dll плагин к HD моду.
https://yadi.sk/d/MpGGkmG33NGbsE

UPD внес небольшое исправление по совету AlexSpl - поменял тип int на _word_ в строке с объявлением heroLevel.

https://yadi.sk/d/Tek6oZpq3NQmxA


Теперь герой с данным навыком с увеличением количества опыта увеличивает свой уровневый отрыв от героя без данного навыка.
Сравнительное движение героев по уровням:

Герой с навыком: 1->3->8->16->21->25->37->40->46
Герой без навыка: 1->3->7->11->14->17->27->30->34

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

Код
    #include "..\..\include\homm3.h"

    Patcher* _P;
    PatcherInstance* _PI;

    static _bool_ plugin_On = 0;


    int __stdcall changeLearningPower(LoHook* h, HookContext* c)
    {
        char learningSkill = *(char*)(c->ecx + 0xDE);
        _word_ heroLevel = *(_word_*)(c->ecx + 0x55);

        float multiplier = learningSkill * heroLevel / (float)15.0;
        *(float*)(c->ebp - 4) = (float)multiplier;

        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.LearningSkill");
            
             _PI->WriteLoHook(0x4E4ACD, changeLearningPower);
          }
       }
      
       return TRUE;
    }


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
Ben
сообщение 30 Sep 2017, 09:02 (Сообщение отредактировал Ben - 02 Oct 2017, 18:34)
Сообщение #35

Member
Сообщений: 86
Спасибо сказали: 48 раз




Улучшение навыка Орлиный глаз

Авторы: AlexSpl, Ben
Dll плагин к HD моду.
https://yadi.sk/d/8xAXgEpk3NLf8f

UPD Обновленная ссылка с версией в релизной конфигурации (предыдущая могла не работать на каких-то системах)
https://yadi.sk/d/RVqiFWfr3NQNWi


Теперь навык действует не после битвы, а до, в книгу заклинаний копируются
заклинания противника, с определенной вероятностью по схеме 30/35/40% для каждого заклинания
в зависимости от степени навыка (герою доступны заклинания 1-2/1-3/1-4 уровней в зависимости от
степени навыка, как в оригинальной игре). Влияние артефактов и специальности учитывается.
В сетевой игре работает.



Код
#define _CRT_RAND_S
#define _CRT_SECURE_NO_WARNINGS
#include "..\..\include\homm3.h"

Patcher* _P;
PatcherInstance* _PI;

static _bool_ plugin_On = 0;

struct PicStruc {
    int type;       // тип картинки (9 - заклинание)
    int id;         // ID картинки
};

// кастомный _List_
struct List {
    _ptr_ Creation;
    PicStruc* Data;
    PicStruc* EndData;
    _ptr_ EndMem;
};

int captionAddr;
bool dlgFirst[] = {true, true};

// Заголовок в каждом диалоге
int __stdcall saveCaption(LoHook* h, HookContext* c)
{
    captionAddr = c->ecx;
    return EXEC_DEFAULT;
}

int __stdcall captionFix(LoHook* h, HookContext* c)
{
    *(int*)(c->ebp - 0x14) = captionAddr;
    return EXEC_DEFAULT;
}

int showSpellDlg(_Hero_* hero, int spells[], int nPics)
{
    if ( !nPics ) return 0;

    List picList;

    // Динамический массив картинок
    // Первый и последний элемент резервируем для полей Creation и EndData/EndMem соответственно
    PicStruc* pic = new PicStruc[nPics + 2];

    for (int i = 0; i < nPics; ++i) {
        pic[i + 1].type = 9;
        pic[i + 1].id = spells[i];
    }

    picList.Creation = (_ptr_)pic + 4;
    picList.Data = pic + 1; // Адрес первого элемента в списке
    picList.EndData = picList.Data + nPics; // Адрес следующего за последним элементом в списке байта
    picList.EndMem = (_ptr_)picList.EndData;

    sprintf(o_TextBuffer, "Благодаря навыку {Орлиный глаз}, {%s} выучил%s следующ%s заклинан%s:",
        hero->name, hero->sex ? "а" : "", nPics > 1 ? "ие" : "ее", nPics > 1 ? "ия" : "ие");
    CALL_5(unsigned int, __fastcall, 0x4F7D20, o_TextBuffer, &picList, -1, -1, 0);

    delete [] pic;

    return 0;
}

int getEagleEyeSpells(_Hero_* hero, _Hero_* heroDonor, int spells[])
{
    int n = 0;
    unsigned int eagleEyeProb = (unsigned int)(CALL_1(float, __thiscall, 0x4E4690, hero) * 100.0);

    for (_Spell_* iSpell = o_Spell + SPL_QUICKSAND; iSpell <= o_Spell + SPL_AIR_ELEMENTAL; ++iSpell)
    {
        int i = iSpell - o_Spell;
        if ( heroDonor->spell_level[i] && !hero->spell[i] )
        {
            if ( iSpell->level <= hero->second_skill[HSS_EAGLE_EYE] + 1 )
            {
                unsigned int dice;
                rand_s(&dice);
                dice = (unsigned int)((double)dice / ((double)UINT_MAX + 1) * 100.0) + 1;
                if ( dice <= eagleEyeProb )
                {
                    spells[n++] = i;
                    hero->spell[i] = 1;
                    hero->spell_level[i] = 1;
                }
            }
        }
    }

    return n;
}

int __stdcall eagleEyeMain(LoHook* h, HookContext* c)
{
    _Hero_* hero[] = {o_BattleMgr->hero[ATTACKER], o_BattleMgr->hero[DEFENDER]};

    if ( hero[ATTACKER] && hero[DEFENDER] )
    {
        int spells[70];

        for (int i = ATTACKER; i <= DEFENDER; ++i)
        {
            if ( dlgFirst[i] && o_BattleMgr->current_side == i && hero[i]->second_skill[HSS_EAGLE_EYE] &&
                hero[i]->doll_art[AS_SPELL_BOOK].id == AID_SPELL_BOOK )
            {
                dlgFirst[i] = false;

                // Учим заклинания всегда.
                int n = getEagleEyeSpells(hero[i], hero[1 - i], spells);

                // Но диалог показываем только для игрока-человека:
                // в хотсите - диалог для обоих героев, в сетевой игре - только для своего героя.
                if ( o_GameMgr->GetPlayer(hero[i]->owner_id)->IsHuman() ) {
                    int id = o_GameMgr->GetMeID();
                    if ( !o_NetworkGame || hero[i]->owner_id == id ) {
                        o_ActivePlayerID = hero[i]->owner_id;
                        showSpellDlg(hero[i], spells, n);
                        o_ActivePlayerID = id;
                    }
                }
            }
        }
    }

    return EXEC_DEFAULT;
}

int __stdcall eagleEyeSetGlobalFlags(LoHook* h, HookContext* c)
{
    dlgFirst[ATTACKER] = true;
    dlgFirst[DEFENDER] = true;

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

            // Меняем коэффициенты
            float eagleEyeCoefs[] = {0.00f, 0.30f, 0.35f, 0.40f};

            _PI->WriteDword(0x63EA2C, (int&)eagleEyeCoefs[1]);
            _PI->WriteDword(0x63EA30, (int&)eagleEyeCoefs[2]);
            _PI->WriteDword(0x63EA34, (int&)eagleEyeCoefs[3]);

            // Убираем оригинальный эффект
            _PI->WriteHexPatch(0x469C23, "EB");
            _PI->WriteHexPatch(0x476996, "E9 DD 01 00 00");

            // Фиксим заголовок диалога
            _PI->WriteLoHook(0x4F7D49, saveCaption);
            _PI->WriteLoHook(0x4F7D54, captionFix);

            _PI->WriteLoHook(0x462C7D, eagleEyeSetGlobalFlags);
            _PI->WriteLoHook(0x477C00, eagleEyeMain);
        }
    }

    return TRUE;
}


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
igrik
сообщение 20 Sep 2018, 22:02 (Сообщение отредактировал igrik - 24 Dec 2018, 13:40)
Сообщение #36

Immortal
Сообщений: 568
Спасибо сказали: 810 раз




WoG Native Dialogs
(Вог диалоги в родном исполнении)
Основная цель: поддержка мастшабирования высоких разрешений при игре с HD-модом

Сделано:
()
()
()
()
()
()
()
()


Автор: igrik
Язык: Rus/Eng
Формат: самораспаковывающийся архив
Поддерживаемые версии: ERA
Способ установки: указать корневую папку ERA

Скачать


--------------------


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
igrik
сообщение 16 Nov 2018, 08:42
Сообщение #37

Immortal
Сообщений: 568
Спасибо сказали: 810 раз




Защита артефактов, пандор и свитков

Скачать (41.5kb)

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






--------------------


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post
Richter
сообщение 11 Feb 2019, 15:15 (Сообщение отредактировал Richter - 11 Feb 2019, 15:49)
Сообщение #38

collector of time
Сообщений: 149
Спасибо сказали: 51 раз




Небольшая модификация добавляющая статистику пройденного расстояния героя, просмотр по нажатию клавиши "X"
Автор:Richter

1 клетка карты равна 0,85714 км.
Содержимое архива положить в папку "Мods"
X_button_mod (950 байт)


--------------------


Спасибо сказали:
Go to the top of the pageAdd Nick
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 



Текстовая версия Сейчас: 25 August 2019 - 23:31
Copyright by Алексей Крючков
Strategy Gamez by GrayMage
Programming by Degtyarev Dmitry
  Яндекс.Метрика