Объявления

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

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

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
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 » 06 окт 2020, 16:58

Цитата:
Осталось найти адрес с таблицей описания артефактов.

С названиями и описаниями артефактов немножко сложнее, чем со вторичными навыками. Нашёл код, но сегодня уже вряд ли буду разбираться (структура _ArtInfo_).

Цитата:
А для сборного арта, все аналогично или есть нюансы?

Аналогично. Добавьте ещё одну глобальную переменную float Cloak_of_the_Undead_King_Bonus = 0.30f; и строчку _PI->WriteDword(0x4E4175 + 2, (int)&Cloak_of_the_Undead_King_Bonus);
Да, чтобы каждый раз не менять, лучше так: float Cloak_of_the_Undead_King_Bonus = первый_бонус + второй_бонус + третий_бонус;
Вернуться к началу

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 » 07 окт 2020, 09:54

С описаниями:

Код: Выделить всё
#define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
#include "patcher_x86.hpp"

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

float Amulet_of_the_Undertaker_Bonus = 0.05f;
float Vampires_Cowl_Bonus = 0.10f;
float Dead_Mans_Boots_Bonus = 0.15f;

float Necromancy_Amplifier_Bonus = 0.10f;
float Soul_Prison_Bonus = 0.20f;

struct ArtInfo {
    char* Name;
    char* Desc;
};

ArtInfo Amulet_of_the_Undertaker = {
    "Amulet of the Undertaker",
    "{Amulet of the Undertaker}\n\nYour description here"
};

ArtInfo Vampires_Cowl = {
    "Vampire's Cowl",
    "{Vampire's Cowl}\n\nYour description here"
};

ArtInfo Dead_Mans_Boots = {
    "Dead Man's Boots",
    "{Dead Man's Boots}\n\nYour description here"
};

ArtInfo Cloak_of_the_Undead_King = {
    "Cloak of the Undead King",
    "{Cloak of the Undead King}\n\nYour description here"
};

char* Necromancy_Amplifier_Desc = "Your description here";
char* Soul_Prison_Desc = "Your description here";

int __stdcall changeArtDesc(LoHook* h, HookContext* c)
{
   
    int ArtAddr = *(int*)0x660B68;

    *(int*)(ArtAddr + 54 * 32) = (int)Amulet_of_the_Undertaker.Name;
    *(int*)(ArtAddr + 55 * 32) = (int)Vampires_Cowl.Name;
    *(int*)(ArtAddr + 56 * 32) = (int)Dead_Mans_Boots.Name;
    *(int*)(ArtAddr + 130 * 32) = (int)Cloak_of_the_Undead_King.Name;

    *(int*)(ArtAddr + 54 * 32 + 0x10) = (int)Amulet_of_the_Undertaker.Desc;
    *(int*)(ArtAddr + 55 * 32 + 0x10) = (int)Vampires_Cowl.Desc;
    *(int*)(ArtAddr + 56 * 32 + 0x10) = (int)Dead_Mans_Boots.Desc;
    *(int*)(ArtAddr + 130 * 32 + 0x10) = (int)Cloak_of_the_Undead_King.Desc;
       
    return EXEC_DEFAULT;
}

int __stdcall changeBldgSpecDesc(LoHook* h, HookContext* c)
{
    *(int*)(0x6A7830 + 0x41 * 4) = (int)Necromancy_Amplifier_Desc;
    *(int*)(0x6A7830 + 0x46 * 4) = (int)Soul_Prison_Desc;

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

            _PI->WriteDword(0x4E3FE5 + 2, (int)&Amulet_of_the_Undertaker_Bonus);
            _PI->WriteDword(0x4E402B + 2, (int)&Vampires_Cowl_Bonus);
            _PI->WriteDword(0x4E4072 + 2, (int)&Dead_Mans_Boots_Bonus);

            _PI->WriteDword(0x4E40FE + 2, (int)&Necromancy_Amplifier_Bonus);
            _PI->WriteDword(0x4E411D + 2, (int)&Soul_Prison_Bonus);
           
            _PI->WriteLoHook(0x44CCB5, changeArtDesc);
            _PI->WriteLoHook(0x5B996A, changeBldgSpecDesc);
        }
    }

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

offlineRolex  
имя: Alex
Ветеран
Ветеран
 
Сообщения: 898
Зарегистрирован: 22 сен 2020, 18:58
Откуда: УКРАИНА
Пол: Мужчина
Поблагодарили: 53 раз.

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

Сообщение Rolex » 07 окт 2020, 12:28

Отлично. Огромное спасибо. Вы 2 и 3 пункты вместе склеили и еще бонус для Темницы душ я вижу добавили. Я разобрался, разделю. Почему-то вы не включили свое предпоследнее сообщение в итоговый код. Наверное, вы так хотели:

Код: Выделить всё
#define _CRT_SECURE_NO_WARNINGS

#include "stdafx.h"
#include "patcher_x86.hpp"

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

float Amulet_of_the_Undertaker_Bonus = 0.05f;
float Vampires_Cowl_Bonus = 0.10f;
float Dead_Mans_Boots_Bonus = 0.15f;
float Cloak_of_the_Undead_King_Bonus = Amulet_of_the_Undertaker_Bonus + Vampires_Cowl_Bonus + Dead_Mans_Boots_Bonus;

float Necromancy_Amplifier_Bonus = 0.10f;
float Soul_Prison_Bonus = 0.20f;

struct ArtInfo {
   char* Name;
   char* Desc;
};

ArtInfo Amulet_of_the_Undertaker = {
   "Amulet of the Undertaker",
   "{Amulet of the Undertaker}\n\nYour description here"
};

ArtInfo Vampires_Cowl = {
   "Vampire's Cowl",
   "{Vampire's Cowl}\n\nYour description here"
};

ArtInfo Dead_Mans_Boots = {
   "Dead Man's Boots",
   "{Dead Man's Boots}\n\nYour description here"
};

ArtInfo Cloak_of_the_Undead_King = {
   "Cloak of the Undead King",
   "{Cloak of the Undead King}\n\nYour description here"
};

char* Necromancy_Amplifier_Desc = "Your description here";
char* Soul_Prison_Desc = "Your description here";

int __stdcall changeArtDesc(LoHook* h, HookContext* c)
{

   int ArtAddr = *(int*)0x660B68;

   *(int*)(ArtAddr + 54 * 32) = (int)Amulet_of_the_Undertaker.Name;
   *(int*)(ArtAddr + 55 * 32) = (int)Vampires_Cowl.Name;
   *(int*)(ArtAddr + 56 * 32) = (int)Dead_Mans_Boots.Name;
   *(int*)(ArtAddr + 130 * 32) = (int)Cloak_of_the_Undead_King.Name;

   *(int*)(ArtAddr + 54 * 32 + 0x10) = (int)Amulet_of_the_Undertaker.Desc;
   *(int*)(ArtAddr + 55 * 32 + 0x10) = (int)Vampires_Cowl.Desc;
   *(int*)(ArtAddr + 56 * 32 + 0x10) = (int)Dead_Mans_Boots.Desc;
   *(int*)(ArtAddr + 130 * 32 + 0x10) = (int)Cloak_of_the_Undead_King.Desc;

   return EXEC_DEFAULT;
}

int __stdcall changeBldgSpecDesc(LoHook* h, HookContext* c)
{
   *(int*)(0x6A7830 + 0x41 * 4) = (int)Necromancy_Amplifier_Desc;
   *(int*)(0x6A7830 + 0x46 * 4) = (int)Soul_Prison_Desc;

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

         _PI->WriteDword(0x4E3FE5 + 2, (int)&Amulet_of_the_Undertaker_Bonus);
         _PI->WriteDword(0x4E402B + 2, (int)&Vampires_Cowl_Bonus);
         _PI->WriteDword(0x4E4072 + 2, (int)&Dead_Mans_Boots_Bonus);
         _PI->WriteDword(0x4E4175 + 2, (int)&Cloak_of_the_Undead_King_Bonus);

         _PI->WriteDword(0x4E40FE + 2, (int)&Necromancy_Amplifier_Bonus);
         _PI->WriteDword(0x4E411D + 2, (int)&Soul_Prison_Bonus);

         _PI->WriteLoHook(0x44CCB5, changeArtDesc);
         _PI->WriteLoHook(0x5B996A, changeBldgSpecDesc);
      }
   }

   return TRUE;
}

Идем дальше. :smile1:
Я сейчас как раз разбираюсь с Огненными птицами и Фениксами.
Вернуться к началу

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 » 07 окт 2020, 14:51

Вот, кстати, нашёлся код, позволяющий существам накапливаться во внешних жилищах: https://handbookhmm.ru/forum/viewtopic.php?f=39&p=19794#p19794

* * *
Тема про капы Морали/Удачи - http://heroescommunity.com/viewthread.php3?TID=46237&pagenumber=2. Просто замените подчёркнутые числа на свои с помощью WriteByte/WriteDword. К адресам на картинке следует прибавить 0x400000 (это я обрезал специально, потому что на HC редактируют файл игры на диске).
Вернуться к началу

offlineRolex  
имя: Alex
Ветеран
Ветеран
 
Сообщения: 898
Зарегистрирован: 22 сен 2020, 18:58
Откуда: УКРАИНА
Пол: Мужчина
Поблагодарили: 53 раз.

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

Сообщение Rolex » 07 окт 2020, 15:38

AlexSpl писал(а):

Вот, кстати, нашёлся код, позволяющий существам накапливаться во внешних жилищах: [url=https://handbookhmm.ru/forum/viewtopic.php?f=39&p=19794#p19794]https://handbookhmm.ru/forum/viewtopic.php?f=39&p=19794#p19794.

Благодарю. Нашел еще такой код по накоплению:
http://heroescommunity.com/viewthread.p ... 0277#focus
Решение в одну строчку без хуков:
Код: Выделить всё
_PI->WriteByte(0x004B87A1, 0x01);

Это просто накопление во внешних жилищах.
Какое из них надежней?

Правда через WriteDword что-то не работает только через WriteByte.

А с охраной, хоть так:
Код: Выделить всё
_PI->WriteByte(0x004B8771, 0x9090909090);

Хоть так:
Код: Выделить всё
_PI->WriteDword(0x004B8771, 0x9090909090);

Не работает. Падает при создании игры.
Вернуться к началу

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 » 07 окт 2020, 16:07

Цитата:
Какое из них надежней?

Я не тестировал, но первое проще. Замена mov [edi], cx на add [edi], cx.

Цитата:
Не работает. Падает при создании игры.

А так и не получится. Нужно WriteHexPatch(0x4B8771, "90 90 90 90 90");

* * *
Отличия WriteByte, WriteWord, WriteDword и WriteHexPatch in nutshell:

WriteByte(0xАдрес, один байт - 0xAB для примера); - эквивалент WriteHexPatch(0xАдрес, "AB");
WriteWord(0xАдрес, два байта - 0xABСD для примера); - эквивалент WriteHexPatch(0xАдрес, "СD AB");
WriteDword(0xАдрес, четыре байта - 0xABСDEF01 для примера); - эквивалент WriteHexPatch(0xАдрес, "01 EF CD AB");
Если нужно пропатчить три или более 4-х байт, всегда используйте WriteHexPatch: WriteHexPatch(0xАдрес, "00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F");
Вернуться к началу

offlineRolex  
имя: Alex
Ветеран
Ветеран
 
Сообщения: 898
Зарегистрирован: 22 сен 2020, 18:58
Откуда: УКРАИНА
Пол: Мужчина
Поблагодарили: 53 раз.

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

Сообщение Rolex » 08 окт 2020, 16:30

Вот все что нашел в гайде по Огненным Птицам и Фениксам.
 Птицы/Фениксы
CREATURES
CONFLUX CREATURE DATA RES.A RES.B ATK.A ATK.B SPELL ANIMATE
Firebird 273EA0 04A6CA ------ 04131B 0406C8 0484FD 03DC24
Phoenix 273F14 04A6CB ------ 04131C 0406C9 0484FE 03DC25

CONFLUX BUILDINGS
Lv.7 Dwelling 23FBA0 28B2B8 Lv.7 Upgrade 23FBAC 28B2BE

CREATURE DWELLINGS
Lv.7 = 27498C Upg.7 = 2749A8


1) Ничего не получается, как не пытался по последним адресам. А как реально сделать так, чтобы базовый прирост Огненных птиц и Фениксов все же уменьшился с 2 до 1, а после постройки Замка с 4 до 2, как в самом городе, так и во внешних жилищах?

AlexSpl писал(а):

Тема про капы Морали/Удачи - http://heroescommunity.com/viewthread.php3?TID=46237&pagenumber=2. Просто замените подчёркнутые числа на свои с помощью WriteByte/WriteDword. К адресам на картинке следует прибавить 0x400000 (это я обрезал специально, потому что на HC редактируют файл игры на диске).


Цитата:
Changing Morale cap -
Изображение

Changing Luck cap -
Изображение
Изображение
(FD, FD FF FF FF = -3)


Цитата:
For Morale you have to change 4 commands (+/- 24 cap):

C7 45 0C 03 00 00 00 -> C7 45 0C 18 00 00 00
83 F8 FD -> 83 F8 E8
C7 45 08 FD FF FF FF -> C7 45 08 E8 FF FF FF
83 F8 03 -> 83 F8 18


Цитата:
For Bad Morale -
Изображение
Just like in the previous example change underlined 03 and FD. For Bad Morale, the cap, of course, -12 (or F4 in hex).


2) Для положительной Морали так пойдет?

Код: Выделить всё
#define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
#include "patcher_x86.hpp"

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

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

         _PI->WriteHexPatch(0x000000030C45C7 + 0x400000, "C7 45 0C 18 00 00 00");
         _PI->WriteHexPatch(0xFDF883 + 0x400000, "83 F8 E8");
         _PI->WriteHexPatch(0xFFFFFFFD0845C7 + 0x400000, "C7 45 08 E8 FF FF FF");
         _PI->WriteHexPatch(0x03F883 + 0x400000, "83 F8 18");
      }
   }

   return TRUE;
}


Или же к тому, на что меняем, добавить "00 00 04" ?
Вернуться к началу

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 » 08 окт 2020, 17:30

На первой картинке первая строка начинается с адреса 0x64580 (в файле Героев на диске), в памяти она начинается с адреса 0x64580 + 0x400000 = 0x464580. Т.е. первый байт (04) имеет адрес 0x464580, второй байт (00) - 0x464580 + 1, третий байт (00) - 0x464580 + 2, четвёртый байт (С7) - 0x464580 + 3 и т.д. Нетрудно посчитать, что подчёркнутые байты начинаются с адреса 0x464580 + 6 и их четыре (03 00 00 00). 03 00 00 00 = 0x00000003, ведущие нули можно убрать, получится 0х3, или просто 3. Это и есть кап положительной Морали. Если Вы хотите изменить его, скажем, на 6, запишите по адресу 0x464580 + 6 число 6 = 06 00 00 00. Через WriteHexPatch это будет выглядеть так: _PI->WriteHexPatch(0x464580 + 6, "06 00 00 00");

Далее, если диапазон у нас симметричный, то следует также поменять 0xFD = -3 на -6 = FA, а FD FF FF FF - на FA FF FF FF. Попробуйте посчитать адреса этих чисел и у Вас всё получится.
Вернуться к началу

offlineRolex  
имя: Alex
Ветеран
Ветеран
 
Сообщения: 898
Зарегистрирован: 22 сен 2020, 18:58
Откуда: УКРАИНА
Пол: Мужчина
Поблагодарили: 53 раз.

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

Сообщение Rolex » 08 окт 2020, 18:00

AlexSpl писал(а):

На первой картинке первая строка начинается с адреса 0x64580 (в файле Героев на диске), в памяти она начинается с адреса 0x64580 + 0x400000 = 0x464580. Т.е. первый байт (04) имеет адрес 0x464580, второй байт (00) - 0x464580 + 1, третий байт (00) - 0x464580 + 2, четвёртый байт (С7) - 0x464580 + 3 и т.д. Нетрудно посчитать, что подчёркнутые байты начинаются с адреса 0x464580 + 6 и их четыре (03 00 00 00). 03 00 00 00 = 0x00000003, ведущие нули можно убрать, получится 0х3, или просто 3. Это и есть кап положительной Морали. Если Вы хотите изменить его, скажем, на 6, запишите по адресу 0x464580 + 6 число 6 = 06 00 00 00. Через WriteHexPatch это будет выглядеть так: _PI->WriteHexPatch(0x464580 + 6, "06 00 00 00");

Далее, если диапазон у нас симметричный, то следует также поменять 0xFD = -3 на -6 = FA, а FD FF FF FF - на FA FF FF FF. Попробуйте посчитать адреса этих чисел и у Вас всё получится.

О, спасибо, теперь понятно. Я как все посчитаю опубликую код для проверки.

AlexSpl писал(а):

Далее, если диапазон у нас симметричный, то следует также поменять 0xFD = -3 на -6 = FA, а FD FF FF FF - на FA FF FF FF. Попробуйте посчитать адреса этих чисел и у Вас всё получится.

А если допустим нужно -12, то указываем F4? Логика следующая:
FD - 253 (-3)
FA - 250 (-6)
F7 - 247 (-9)
F4 - 244 (-12)
Вернуться к началу

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 » 08 окт 2020, 18:03

Для перевода чисел в Hex вы можете использовать как обычный инженерный калькулятор, так и встроенный в ОС.

Как менять прирост существ, я покажу позже.
Вернуться к началу

Пред.След.

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

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

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