Объявления

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

Как создать плагин для HD мода

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1315
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

Re: Как создать плагин для HD мода

Сообщение Ben80 » 28 сен 2017, 16:37

Вроде нашел, в какой процедуре Disguise обнуляется - в 4D8990
Так, это не совсем то. Возможно, и впрямь придется брейкпойнты учиться ставить.
Вернуться к началу

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

Re: Как создать плагин для HD мода

Сообщение Ben80 » 28 сен 2017, 17:02

AlexSpl писал(а):

Цитата:
Не знаете, как Value объектов изменять ?

Они "зашиты" в инструкции. Легко находятся хекс-поиском по базе данных IDA. Точно не перепутаешь. Сами Values можно взять хотя бы из чейнджлога HotA.


В процедуре по адресу 539000 ?
Вернуться к началу

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

Re: Как создать плагин для HD мода

Сообщение Ben80 » 28 сен 2017, 17:36

Код: Выделить всё
    *(_DWORD *)v85 = &RMGObjGen_VTable;
    *(_DWORD *)(v85 + 4) = 57;
    *(_DWORD *)(v85 + 8) = 0;
    *(_DWORD *)(v85 + 12) = 3500;
    *(_DWORD *)(v85 + 16) = 200;


Обелиск

57 это id объекта
3500 это value

А 0 и 200 - что такое ?
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5547
Зарегистрирован: 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)
Поблагодарили: 2162 раз.

Re: Как создать плагин для HD мода

Сообщение AlexSpl » 28 сен 2017, 18:08

Судя по расширенному описанию, тип почвы и частота появления.
Вернуться к началу

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

Re: Как создать плагин для HD мода

Сообщение Ben80 » 28 сен 2017, 19:53

AlexSpl писал(а):

тип почвы


Увы, нет. Просто подтип.
Вернуться к началу

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

Re: Как создать плагин для HD мода

Сообщение Ben80 » 29 сен 2017, 04:46

Для Водоворота манны добавил ее зависимость от Гильдии магов 2 уровня.
Ну и стоимость - 2000 вместо 1000.

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

Patcher* _P;
PatcherInstance* _PI;

static _bool_ plugin_On = 0;

int BuildDepends_Dungeon[] =
{
7, -1,
8, 7, -1,
9, 8, -1,
22, -1,
23, -1,
5, -1,
16, -1,
14, -1,
15, 14, -1,
17, 14, -1,
0, -1,
1, 0, -1,
2, 1, -1,
21, 1, -1,
3, 2, -1,
4, 3, -1,
11, 5, -1,
12, 11, 16, 14, 0, -1,
13, 12, 9, -1,
30, 7, -1,
18, 30, -1,
37, 30, -1,
19, 37, -1,
32, 30, -1,
39, 32, -1,
31, 30, -1,
38, 31, -1,
33, 32, 31, -1,
40, 33, -1,
34, 33, -1,
41, 34, -1,
35, 33, -1,
42, 35, -1,
36, 34, 35, 1, -1,
2, -1,
26, -1,
-100
};


int __stdcall manaVortex(LoHook* h, HookContext* c)
{
    unsigned int dice;
    rand_s(&dice);
   
    // maxMana (c->eax) - максимальный запас маны: (int)(10 * knowledge * modifier)
    // curMana (c->ebx) - текущий запас маны: maxMana + rand(1, maxMana)
    c->ebx = c->eax + (unsigned int)((double)dice / ((double)UINT_MAX + 1) * c->eax) + 1;

    return EXEC_DEFAULT;
}

// Новое сообщение
int __stdcall manaVortexDlg(LoHook* h, HookContext* c)
{
    _Hero_* hero = (_Hero_*)c->edi;
    char Text[200];
    sprintf(Text, "{%s}, близ вихря маны ваше тело наполняется новой силой. " \
        "Количество маны увеличилось на {%d} ед. и теперь составляет {%d} ед.",
        hero->name, c->ebx - hero->spell_points, c->ebx);
    b_MsgBox(Text, MBX_OK);
   
    c->return_address = 0x5BDD92;
    return NO_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.NewManaVortex");
               
         _PI->WriteLoHook(0x5BDD4E, manaVortex);
         _PI->WriteLoHook(0x5BDD66, manaVortexDlg);

         *(int*)0x4EBA5C = (int)BuildDepends_Dungeon;

      }
   }
           
   return TRUE;
}
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5547
Зарегистрирован: 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)
Поблагодарили: 2162 раз.

Re: Как создать плагин для HD мода

Сообщение AlexSpl » 29 сен 2017, 13:43

Цитата:
Вроде нашел, в какой процедуре Disguise обнуляется - в 4D8990
Так, это не совсем то. Возможно, и впрямь придется брейкпойнты учиться ставить.


Пишем уровень школы магии в поле disguise здесь: 41C7C6h.

Сбрасываем (устанавливаем в -1) поля disguise в цикле для всех 178 героев здесь: 4C7DA5h.
В eax адрес поля temp_mod_flags (раз этот адрес используется в качестве базы, то в оригинальном коде temp_mod_flags, скорее всего, не обычное поле, а структура);
ecx - счётчик героев, ID текущего героя = 178 - ecx.

Написал хук, устанавливающий длительность "Маскировки", равной уровню Магии Воздуха + 1. В начале каждого дня сила заклинания слабеет, пока эффект совсем не исчезнет (Expert -> Advanced -> Basic -> None -> {заклинание пропадает}).

Код: Выделить всё
int __stdcall testDisguise(LoHook* h, HookContext* c)
{
   if ( *(int*)(c->eax + 9) > -1 ) --*(int*)(c->eax + 9);
   
   c->return_address = 0x4C7DA8;
   return NO_EXEC_DEFAULT;
}

...

_PI->WriteLoHook(0x4C7DA5, testDisguise);
Вернуться к началу

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

Re: Как создать плагин для HD мода

Сообщение Ben80 » 29 сен 2017, 16:58

У меня в экзешнике героев 156, как и в исходниках homm3.h

Вроде как для начала написал фикс бага Disguise к оригинальной игре, но пока не проверял :smile1:

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

Patcher* _P;
PatcherInstance* _PI;


int __stdcall makeDisguiseCounter(LoHook* h, HookContext* c)
{
   _GameMgr_* GM = (_GameMgr_*)c->ebx;
   _int_ id = GM->GetMeID();
   int addressTempModFlags = c->ebx + 0x21725;
   for(int i=0; i<156; i++)
   {
      if(*(_int8_*)(addressTempModFlags - 227) == id)
         *(_dword_*)(addressTempModFlags + 9) = -1;
      addressTempModFlags =+ 1170;
   }
       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.TestDisguise");

         _PI->WriteHexPatch(0x4C7DA5, "90 90 90");
         _PI->WriteLoHook(0x4C6CA0, makeDisguiseCounter);

        }
        break;

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

Последний раз редактировалось Ben80 29 сен 2017, 18:08, всего редактировалось 1 раз.
Вернуться к началу

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

Re: Как создать плагин для HD мода

Сообщение Ben80 » 29 сен 2017, 17:23

Или сюда, возможно, правильно - 4C75E0
Зависит от того, в каком месте уже точно происходит переход к следующему игроку.

Да, правильно в 4C75E0
Поскольку даже если id игрока = 8 то до выполнения 4C75E0 все равно дело дойдет.
Вернуться к началу

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

Re: Как создать плагин для HD мода

Сообщение Ben80 » 29 сен 2017, 18:33

Проверил для 2 игроков, работает.

Смешной момент -
Код: Выделить всё
addressTempModFlags =+ 1170;
пришлось исправить на
Код: Выделить всё
addressTempModFlags += 1170;

Иначе - нелепая ошибка.

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

Patcher* _P;
PatcherInstance* _PI;


int __stdcall makeDisguiseCounter(LoHook* h, HookContext* c)
{
   _GameMgr_* GM = (_GameMgr_*)c->ebx;
   _int_ id = GM->GetMeID();
   int addressTempModFlags = c->ebx + 0x21725;
   
   for(int i=0; i<156; i++)
   {
      if(*(_int8_*)(addressTempModFlags - 227) == id)
         *(_dword_*)(addressTempModFlags + 9) = -1;
      addressTempModFlags += 1170;
   }
   
   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.TestDisguise");

         _PI->WriteHexPatch(0x4C7DA5, "90 90 90");
         //_PI->WriteLoHook(0x4C6CA0, makeDisguiseCounter);
         _PI->WriteLoHook(0x4C75E0, makeDisguiseCounter);

        }
        break;

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

Вернуться к началу

Пред.След.

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

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

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