Объявления
Поздравляем
VDV_forever


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

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

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5540
Зарегистрирован: 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)
Поблагодарили: 2155 раз.

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

Сообщение AlexSpl » 17 авг 2021, 23:24

Техническая демка раздачи новых заклинаний в гильдию магов:

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

Patcher* _P;
PatcherInstance* _PI;

//char iniPath[MAX_PATH];

#define SPELLS_NUM 71
#define SPL_FEAR 70
_Spell_ spell[128];

int __stdcall afterInit(LoHook* h, HookContext* c)
{
    for (int i = 0; i < SPL_FEAR; ++i)
        spell[i] = o_Spell[i];

    spell[SPL_FEAR].type = -1;
    spell[SPL_FEAR].wav_name = "Fear.wav";
    spell[SPL_FEAR].animation_ix = 15;
    spell[SPL_FEAR].flags = 0x20415;
    spell[SPL_FEAR].name = "Fear";
    spell[SPL_FEAR].short_name = "Fear";
    spell[SPL_FEAR].level = 4;
    spell[SPL_FEAR].school_flags = 8;
    spell[SPL_FEAR].mana_cost[0] = 16;
    spell[SPL_FEAR].mana_cost[1] = 8;
    spell[SPL_FEAR].mana_cost[2] = 8;
    spell[SPL_FEAR].mana_cost[3] = 8;
    spell[SPL_FEAR].eff_power = 0;
    spell[SPL_FEAR].effect[0] = 75;
    spell[SPL_FEAR].effect[1] = 75;
    spell[SPL_FEAR].effect[2] = 50;
    spell[SPL_FEAR].effect[3] = 25;
    spell[SPL_FEAR].chance2get_var[0] = 10;
    spell[SPL_FEAR].chance2get_var[1] = 10;
    spell[SPL_FEAR].chance2get_var[2] = 10;
    spell[SPL_FEAR].chance2get_var[3] = 10;
    spell[SPL_FEAR].chance2get_var[4] = 10;
    spell[SPL_FEAR].chance2get_var[5] = 10;
    spell[SPL_FEAR].chance2get_var[6] = 10;
    spell[SPL_FEAR].chance2get_var[7] = 10;
    spell[SPL_FEAR].chance2get_var[8] = 10;
    spell[SPL_FEAR].ai_value[0] = 50;
    spell[SPL_FEAR].ai_value[1] = 50;
    spell[SPL_FEAR].ai_value[2] = 50;
    spell[SPL_FEAR].ai_value[3] = 50;
    spell[SPL_FEAR].description[0] =
        "{Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n";
    spell[SPL_FEAR].description[1] =
        "{Basic Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n\nSpell Point cost is half that of Normal Fear.\n";
    spell[SPL_FEAR].description[2] =
        "{Advanced Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n\nPenalty to movement is twice that of Basic Fear.\n";
    spell[SPL_FEAR].description[3] =
        "{Expert Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n\nPenalty to movement is three times that of Basic Fear.\n";

    for (int i = SPL_FEAR + 1; i < SPL_FEAR + 11; ++i)
        spell[i] = o_Spell[i];

    _PI->WriteDword(0x687FA8, (int)&spell);

    return EXEC_DEFAULT;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    static bool plugin_On = false;
    if ( DLL_PROCESS_ATTACH == ul_reason_for_call )
    {
        if ( !plugin_On )
        {
            plugin_On = true;
            _P = GetPatcher();
            _PI = _P->CreateInstance("HD.Plugin.H3.NewSpells");

            //GetCurrentDirectoryA(sizeof(iniPath), iniPath);
            //strcat(iniPath, "\\NewSpells.ini");

            _PI->WriteLoHook(0x4EE1C1, afterInit);

            // Mage Guild
            _PI->WriteByte(0x5BEA2C, SPELLS_NUM);
            _PI->WriteByte(0x5BEA70, SPELLS_NUM);
            _PI->WriteByte(0x5BEAAD, SPELLS_NUM);
            _PI->WriteByte(0x5BEB48, SPELLS_NUM);
            _PI->WriteByte(0x5BEB71, SPELLS_NUM);
            _PI->WriteByte(0x5BEBB2, SPELLS_NUM);
            _PI->WriteByte(0x5BEC1B, SPELLS_NUM);

            _PI->WriteDword(0x5BEAFE, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x5BEB2C, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x5BEC05, SPELLS_NUM * sizeof(_Spell_));

            _PI->WriteByte(0x4E67AC, SPELLS_NUM);
        }
    }

   return TRUE;
}

Примечание. Версия неиграбельна (сломаны спецабилки сущетсв из-за переноса). Просто полюбоваться картинкой.

SpellScr.zip
Распаковать в в _H3_Data\Common
(116.61 КБ) Скачиваний: 104

* * *
Второй этап - научить героев изучать новые заклинания. Здесь я решил не переносить структуры героев в код плагина и не увеличивать их размер, т.к. структура героя в коде используется повсеместно и получится слишком много патчей. Гораздо проще объединить поля

_byte_ spell[70]; // +1002
_byte_ spell_level[70]; // +1072

Это два булевых массива. В первом отмечаются заклинания, которые герой выучил, во втором - которые он может кастовать. Зачем два? Например, герой может получить заклинание из свитка или артефакта. В этом случае он может кастовать заклинание, но не знает его. Ничто не мешает использовать байт более благоразумно: 0 - герой не знает заклинание; 1 - герой знает заклинание; 2 (или -1) - герой не знает заклинание, но может его кастовать. С таким подходом мы расширяем список заклинаний до 140, что уже больше требуемых 128 (0 - 127 - положительные значения, которые может хранить char). Остаётся написать хуки, изменяющие способ работы с этими полями, а кода, который с ними работает гораздо меньше, чем того, который работает со структурой героя.

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

Patcher* _P;
PatcherInstance* _PI;

//char iniPath[MAX_PATH];

#define SPELLS_NUM 71
#define SPL_FEAR 70
_Spell_ spell[128];

int __stdcall afterInit(LoHook* h, HookContext* c)
{
   for (int i = 0; i < SPL_FEAR; ++i)
      spell[i] = o_Spell[i];

   spell[SPL_FEAR].type = -1;
   spell[SPL_FEAR].wav_name = "Fear.wav";
   spell[SPL_FEAR].animation_ix = 15;
   spell[SPL_FEAR].flags = 0x20415;
   spell[SPL_FEAR].name = "Fear";
   spell[SPL_FEAR].short_name = "Fear";
   spell[SPL_FEAR].level = 4;
   spell[SPL_FEAR].school_flags = 8;
   spell[SPL_FEAR].mana_cost[0] = 16;
   spell[SPL_FEAR].mana_cost[1] = 8;
   spell[SPL_FEAR].mana_cost[2] = 8;
   spell[SPL_FEAR].mana_cost[3] = 8;
   spell[SPL_FEAR].eff_power = 0;
   spell[SPL_FEAR].effect[0] = 75;
   spell[SPL_FEAR].effect[1] = 75;
   spell[SPL_FEAR].effect[2] = 50;
   spell[SPL_FEAR].effect[3] = 25;
   spell[SPL_FEAR].chance2get_var[0] = 10;
   spell[SPL_FEAR].chance2get_var[1] = 10;
   spell[SPL_FEAR].chance2get_var[2] = 10;
   spell[SPL_FEAR].chance2get_var[3] = 10;
   spell[SPL_FEAR].chance2get_var[4] = 10;
   spell[SPL_FEAR].chance2get_var[5] = 10;
   spell[SPL_FEAR].chance2get_var[6] = 10;
   spell[SPL_FEAR].chance2get_var[7] = 10;
   spell[SPL_FEAR].chance2get_var[8] = 10;
   spell[SPL_FEAR].ai_value[0] = 50;
   spell[SPL_FEAR].ai_value[1] = 50;
   spell[SPL_FEAR].ai_value[2] = 50;
   spell[SPL_FEAR].ai_value[3] = 50;
   spell[SPL_FEAR].description[0] =
      "{Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n";
   spell[SPL_FEAR].description[1] =
      "{Basic Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n\nSpell Point cost is half that of Normal Fear.\n";
   spell[SPL_FEAR].description[2] =
      "{Advanced Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n\nPenalty to movement is twice that of Basic Fear.\n";
   spell[SPL_FEAR].description[3] =
      "{Expert Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n\nPenalty to movement is three times that of Basic Fear.\n";

   for (int i = SPL_FEAR + 1; i < SPL_FEAR + 11; ++i)
      spell[i] = o_Spell[i];

   _PI->WriteDword(0x687FA8, (int)&spell);

   return EXEC_DEFAULT;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
   static bool plugin_On = false;
   if ( DLL_PROCESS_ATTACH == ul_reason_for_call )
   {
      if ( !plugin_On )
      {
         plugin_On = true;
         _P = GetPatcher();
         _PI = _P->CreateInstance("HD.Plugin.H3.NewSpells");

         //GetCurrentDirectoryA(sizeof(iniPath), iniPath);
         //strcat(iniPath, "\\NewSpells.ini");

         _PI->WriteLoHook(0x4EE1C1, afterInit);

         // Mage Guild
         _PI->WriteByte(0x5BEA2C, SPELLS_NUM);
         _PI->WriteByte(0x5BEA70, SPELLS_NUM);
         _PI->WriteByte(0x5BEAAD, SPELLS_NUM);
         _PI->WriteByte(0x5BEB48, SPELLS_NUM);
         _PI->WriteByte(0x5BEB71, SPELLS_NUM);
         _PI->WriteByte(0x5BEBB2, SPELLS_NUM);
         _PI->WriteByte(0x5BEC1B, SPELLS_NUM);

         _PI->WriteDword(0x5BEAFE, SPELLS_NUM * sizeof(_Spell_));
         _PI->WriteDword(0x5BEB2C, SPELLS_NUM * sizeof(_Spell_));
         _PI->WriteDword(0x5BEC05, SPELLS_NUM * sizeof(_Spell_));

         _PI->WriteByte(0x4E67AC, SPELLS_NUM);

         // Learning Spells
         _PI->WriteCodePatch(0x4D95AF, "%n", 7);
         _PI->WriteByte(0x402902, SPELLS_NUM); // Cheats
         _PI->WriteByte(0x471C57, SPELLS_NUM); // Cheats in battle
         _PI->WriteByte(0x427085, SPELLS_NUM);
         _PI->WriteByte(0x4864B0, SPELLS_NUM);
         _PI->WriteByte(0x48A34B, SPELLS_NUM);
         _PI->WriteByte(0x4F508B, SPELLS_NUM);
         _PI->WriteDword(0x4F50CE, SPELLS_NUM * sizeof(_Spell_));
         _PI->WriteDword(0x4F5114, SPELLS_NUM * sizeof(_Spell_));

         _PI->WriteDword(0x59CD5E, 0x3EA); // Spell Book
         _PI->WriteDword(0x59CDBF, SPELLS_NUM * sizeof(_Spell_)); // Spell Book

         _PI->WriteDword(0x5BE512, SPELLS_NUM * sizeof(_Spell_)); // Conflux Grail
         _PI->WriteDword(0x5BE56E, SPELLS_NUM * sizeof(_Spell_)); // Conflux Grail

      }
   }

   return TRUE;
}

Это не все патчи. Версия для демонстрации изучения новых заклинаний. О багах писать пока не стоит :smile1:

* * *
И версия для Rolex :smile1: Вот эту неплохо бы погонять со всем, что связано с магией (крэш-логи очень нужны; они помогут найти ещё не найденный код, который требуется изменить). Только абилки не тестируйте. Я их ещё не перемещал.

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

Patcher* _P;
PatcherInstance* _PI;

//char iniPath[MAX_PATH];

#define SPELLS_NUM 71
#define SPL_FEAR 70
_Spell_ spell[128];

int __stdcall afterInit(LoHook* h, HookContext* c)
{
    for (int i = 0; i < SPL_FEAR; ++i)
        spell[i] = o_Spell[i];

    spell[SPL_FEAR].type = -1;
    spell[SPL_FEAR].wav_name = "Fear.wav";
    spell[SPL_FEAR].animation_ix = 15;
    spell[SPL_FEAR].flags = 0x20415;
    spell[SPL_FEAR].name = "Fear";
    spell[SPL_FEAR].short_name = "Fear";
    spell[SPL_FEAR].level = 4;
    spell[SPL_FEAR].school_flags = 8;
    spell[SPL_FEAR].mana_cost[0] = 16;
    spell[SPL_FEAR].mana_cost[1] = 8;
    spell[SPL_FEAR].mana_cost[2] = 8;
    spell[SPL_FEAR].mana_cost[3] = 8;
    spell[SPL_FEAR].eff_power = 0;
    spell[SPL_FEAR].effect[0] = 75;
    spell[SPL_FEAR].effect[1] = 75;
    spell[SPL_FEAR].effect[2] = 50;
    spell[SPL_FEAR].effect[3] = 25;
    spell[SPL_FEAR].chance2get_var[0] = 10;
    spell[SPL_FEAR].chance2get_var[1] = 10;
    spell[SPL_FEAR].chance2get_var[2] = 10;
    spell[SPL_FEAR].chance2get_var[3] = 10;
    spell[SPL_FEAR].chance2get_var[4] = 10;
    spell[SPL_FEAR].chance2get_var[5] = 10;
    spell[SPL_FEAR].chance2get_var[6] = 10;
    spell[SPL_FEAR].chance2get_var[7] = 10;
    spell[SPL_FEAR].chance2get_var[8] = 10;
    spell[SPL_FEAR].ai_value[0] = 50;
    spell[SPL_FEAR].ai_value[1] = 50;
    spell[SPL_FEAR].ai_value[2] = 50;
    spell[SPL_FEAR].ai_value[3] = 50;
    spell[SPL_FEAR].description[0] =
        "{Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n";
    spell[SPL_FEAR].description[1] =
        "{Basic Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n\nSpell Point cost is half that of Normal Fear.\n";
    spell[SPL_FEAR].description[2] =
        "{Advanced Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n\nPenalty to movement is twice that of Basic Fear.\n";
    spell[SPL_FEAR].description[3] =
        "{Expert Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n\nPenalty to movement is three times that of Basic Fear.\n";

    for (int i = SPL_FEAR + 1; i < SPL_FEAR + 11; ++i)
        spell[i] = o_Spell[i];

    _PI->WriteDword(0x687FA8, (int)&spell);

    return EXEC_DEFAULT;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    static bool plugin_On = false;
    if ( DLL_PROCESS_ATTACH == ul_reason_for_call )
    {
        if ( !plugin_On )
        {
            plugin_On = true;
            _P = GetPatcher();
            _PI = _P->CreateInstance("HD.Plugin.H3.NewSpells");

            //GetCurrentDirectoryA(sizeof(iniPath), iniPath);
            //strcat(iniPath, "\\NewSpells.ini");

            _PI->WriteLoHook(0x4EE1C1, afterInit);

            // Mage Guild
            _PI->WriteByte(0x5BEA2C, SPELLS_NUM);
            _PI->WriteByte(0x5BEA70, SPELLS_NUM);
            _PI->WriteByte(0x5BEAAD, SPELLS_NUM);
            _PI->WriteByte(0x5BEB48, SPELLS_NUM);
            _PI->WriteByte(0x5BEB71, SPELLS_NUM);
            _PI->WriteByte(0x5BEBB2, SPELLS_NUM);
            _PI->WriteByte(0x5BEC1B, SPELLS_NUM);

            _PI->WriteDword(0x5BEAFE, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x5BEB2C, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x5BEC05, SPELLS_NUM * sizeof(_Spell_));

            _PI->WriteByte(0x4E67AC, SPELLS_NUM);

            // Learning Spells
            _PI->WriteCodePatch(0x4D95AF, "%n", 7);
            _PI->WriteByte(0x402902, SPELLS_NUM); // Cheats
            _PI->WriteByte(0x471C57, SPELLS_NUM); // Cheats in battle
            _PI->WriteByte(0x427085, SPELLS_NUM);
            _PI->WriteByte(0x4864B0, SPELLS_NUM);
            _PI->WriteByte(0x48A34B, SPELLS_NUM);
            _PI->WriteByte(0x4F508B, SPELLS_NUM);
            _PI->WriteDword(0x4F50CE, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4F5114, SPELLS_NUM * sizeof(_Spell_));
           
            _PI->WriteDword(0x59CD5E, 0x3EA); // Spell Book
            _PI->WriteDword(0x59CDBF, SPELLS_NUM * sizeof(_Spell_)); // Spell Book

            // Conflux Grail
            _PI->WriteDword(0x5BE512, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x5BE56E, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x5D7464, SPELLS_NUM);

            // WIP
            _PI->WriteDword(0x425E98, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4329C1, 0x3EA);
            _PI->WriteDword(0x432A43, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x432CDE, 0x3EA);
            _PI->WriteDword(0x432D1E, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x43C21B, SPELLS_NUM * sizeof(_Spell_)); // Master Genie AI
            _PI->WriteDword(0x43C6F2, SPELLS_NUM * sizeof(_Spell_)); // Battle AI
            _PI->WriteDword(0x447551, SPELLS_NUM * sizeof(_Spell_)); // Casters
            _PI->WriteDword(0x4C24C9, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteByte(0x4C250E, SPELLS_NUM);
            _PI->WriteDword(0x4C2557, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4C260D, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4C92C5, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4C9347, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4C93C0, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4D962D, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4D9681, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4D96D6, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4D972E, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4D9771, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x527ACB, 0x3EA);
            _PI->WriteDword(0x527B08, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x52A97A, 0x3EA); // AI
            _PI->WriteDword(0x52A9B6, SPELLS_NUM * sizeof(_Spell_)); // AI
            _PI->WriteDword(0x534C4B, SPELLS_NUM * sizeof(_Spell_)); // RMG
            _PI->WriteDword(0x5A1AD6, SPELLS_NUM * sizeof(_Spell_)); // Cast Spell

            _PI->WriteByte(0x4C244D, SPELLS_NUM);
            _PI->WriteByte(0x4C246F, SPELLS_NUM);
            _PI->WriteByte(0x4CEC4F, SPELLS_NUM);
        }
    }

   return TRUE;
}

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

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

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

Сообщение Rolex » 18 авг 2021, 04:57

AlexSpl писал(а):

И версия для Rolex :smile1: Вот эту неплохо бы погонять со всем, что связано с магией (крэш-логи очень нужны; они помогут найти ещё не найденный код, который требуется изменить).

Вижу что в этой версии больше всего патчей и она включает в себя те два других кода. Можно было только ее и выкладывать. Буду тестировать.
Вернуться к началу

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

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

Сообщение AlexSpl » 18 авг 2021, 04:59

Не забудьте скачать Common.zip (там картинки для книги заклинаний). Кстати, Вы не знаете, где хранятся картинки для свитков? И есть ли такая для Fear?
Вернуться к началу

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

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

Сообщение Rolex » 18 авг 2021, 05:26

AlexSpl писал(а):

Не забудьте скачать Common.zip (там картинки для книги заклинаний).

Да, скачал. В итоге увидел в книге красоту - Fear. Но я так понял анимацию самого закла вы еще не прикручивали. Наложить его пока что не получается. И, кстати, с анимацией определились? Какая более правильная будет - анимация абилки Могучих горгон или Лазурных драконов?

AlexSpl писал(а):

Кстати, Вы не знаете, где хранятся картинки для свитков? И есть ли такая для Fear?

Так сходу и не подскажу, нужно смотреть. Да и вряд ли есть Fear для свитка. Но из той, что есть, можно будет и для свитка сделать.
Вернуться к началу

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

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

Сообщение AlexSpl » 18 авг 2021, 05:46

Цитата:
Какая более правильная будет - анимация абилки Могучих горгон или Лазурных драконов?

Та, что в оригинале (RoE 1.0 - 1.2, AB 2.0). Анимацию Страха Лазурных драконов специально для них делали.

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

Patcher* _P;
PatcherInstance* _PI;

//char iniPath[MAX_PATH];

#define SPELLS_NUM 71
#define SPL_FEAR 70
_Spell_ spell[128];

int __stdcall afterInit(LoHook* h, HookContext* c)
{
    for (int i = 0; i < SPL_FEAR; ++i)
        spell[i] = o_Spell[i];

    spell[SPL_FEAR].type = -1;
    spell[SPL_FEAR].wav_name = "Fear.wav";
    spell[SPL_FEAR].animation_ix = 15;
    spell[SPL_FEAR].flags = 0x20415;
    spell[SPL_FEAR].name = "Fear";
    spell[SPL_FEAR].short_name = "Fear";
    spell[SPL_FEAR].level = 4;
    spell[SPL_FEAR].school_flags = 8;
    spell[SPL_FEAR].mana_cost[0] = 16;
    spell[SPL_FEAR].mana_cost[1] = 8;
    spell[SPL_FEAR].mana_cost[2] = 8;
    spell[SPL_FEAR].mana_cost[3] = 8;
    spell[SPL_FEAR].eff_power = 0;
    spell[SPL_FEAR].effect[0] = 75;
    spell[SPL_FEAR].effect[1] = 75;
    spell[SPL_FEAR].effect[2] = 50;
    spell[SPL_FEAR].effect[3] = 25;
    spell[SPL_FEAR].chance2get_var[0] = 10;
    spell[SPL_FEAR].chance2get_var[1] = 10;
    spell[SPL_FEAR].chance2get_var[2] = 10;
    spell[SPL_FEAR].chance2get_var[3] = 10;
    spell[SPL_FEAR].chance2get_var[4] = 10;
    spell[SPL_FEAR].chance2get_var[5] = 10;
    spell[SPL_FEAR].chance2get_var[6] = 10;
    spell[SPL_FEAR].chance2get_var[7] = 10;
    spell[SPL_FEAR].chance2get_var[8] = 10;
    spell[SPL_FEAR].ai_value[0] = 50;
    spell[SPL_FEAR].ai_value[1] = 50;
    spell[SPL_FEAR].ai_value[2] = 50;
    spell[SPL_FEAR].ai_value[3] = 50;
    spell[SPL_FEAR].description[0] =
        "{Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n";
    spell[SPL_FEAR].description[1] =
        "{Basic Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n\nSpell Point cost is half that of Normal Fear.\n";
    spell[SPL_FEAR].description[2] =
        "{Advanced Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n\nPenalty to movement is twice that of Basic Fear.\n";
    spell[SPL_FEAR].description[3] =
        "{Expert Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n\nPenalty to movement is three times that of Basic Fear.\n";

    for (int i = SPL_FEAR + 1; i < SPL_FEAR + 11; ++i)
        spell[i] = o_Spell[i];

    _PI->WriteDword(0x687FA8, (int)&spell);

    return EXEC_DEFAULT;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    static bool plugin_On = false;
    if ( DLL_PROCESS_ATTACH == ul_reason_for_call )
    {
        if ( !plugin_On )
        {
            plugin_On = true;
            _P = GetPatcher();
            _PI = _P->CreateInstance("HD.Plugin.H3.NewSpells");

            //GetCurrentDirectoryA(sizeof(iniPath), iniPath);
            //strcat(iniPath, "\\NewSpells.ini");

            // Moving and Expanding Spell Table
            _PI->WriteLoHook(0x4EE1C1, afterInit);

            // Mage Guild
            _PI->WriteByte(0x5BEA2C, SPELLS_NUM);
            _PI->WriteByte(0x5BEA70, SPELLS_NUM);
            _PI->WriteByte(0x5BEAAD, SPELLS_NUM);
            _PI->WriteByte(0x5BEB48, SPELLS_NUM);
            _PI->WriteByte(0x5BEB71, SPELLS_NUM);
            _PI->WriteByte(0x5BEBB2, SPELLS_NUM);
            _PI->WriteByte(0x5BEC1B, SPELLS_NUM);

            _PI->WriteDword(0x5BEAFE, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x5BEB2C, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x5BEC05, SPELLS_NUM * sizeof(_Spell_));

            _PI->WriteByte(0x4E67AC, SPELLS_NUM);

            // Learning Spells
            _PI->WriteCodePatch(0x4D8B72, "%n", 8);
            _PI->WriteCodePatch(0x4D8F7F, "%n", 8);
            _PI->WriteCodePatch(0x4D95AF, "%n", 7);
           
            _PI->WriteByte(0x402902, SPELLS_NUM); // Cheats
            _PI->WriteByte(0x471C57, SPELLS_NUM); // Cheats in battle
            _PI->WriteByte(0x4864B0, SPELLS_NUM);
            _PI->WriteByte(0x48A34B, SPELLS_NUM);
            _PI->WriteByte(0x4F508B, SPELLS_NUM);
            _PI->WriteDword(0x4F50CE, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4F5114, SPELLS_NUM * sizeof(_Spell_));
           
            _PI->WriteDword(0x59CDBF, SPELLS_NUM * sizeof(_Spell_)); // Spell Book

            // Conflux Grail
            _PI->WriteDword(0x5BE512, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x5BE56E, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x5D7464, SPELLS_NUM);

            _PI->WriteDword(0x425E98, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteByte(0x427085, SPELLS_NUM);
            _PI->WriteDword(0x432A43, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x432D1E, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x43C21B, SPELLS_NUM * sizeof(_Spell_)); // Master Genie AI
            _PI->WriteDword(0x43C6F2, SPELLS_NUM * sizeof(_Spell_)); // Battle AI
            _PI->WriteDword(0x447551, SPELLS_NUM * sizeof(_Spell_)); // Casters
            _PI->WriteDword(0x447C7D, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x447CC8, SPELLS_NUM * sizeof(_Spell_));

            _PI->WriteByte(0x4C244D, SPELLS_NUM);
            _PI->WriteByte(0x4C246F, SPELLS_NUM);
            _PI->WriteDword(0x4C24C9, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteByte(0x4C250E, SPELLS_NUM);
            _PI->WriteDword(0x4C2557, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4C260D, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4C92C5, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4C9347, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4C93C0, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteByte(0x4D8F53, SPELLS_NUM);
            _PI->WriteByte(0x4D8F8A, SPELLS_NUM);
            _PI->WriteDword(0x4D962D, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4D9681, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4D96D6, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4D972E, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4D9771, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteByte(0x4D98EA, SPELLS_NUM);
            _PI->WriteByte(0x4D99D6, SPELLS_NUM);
           
            _PI->WriteDword(0x527B08, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x52A9B6, SPELLS_NUM * sizeof(_Spell_)); // AI
            _PI->WriteDword(0x534C4B, SPELLS_NUM * sizeof(_Spell_)); // RMG
            _PI->WriteDword(0x5A1AD6, SPELLS_NUM * sizeof(_Spell_)); // Cast Spell
           
            _PI->WriteDword(0x5353D5, SPELLS_NUM);
            _PI->WriteByte(0x53542B, SPELLS_NUM);
           
            _PI->WriteByte(0x4CEC4F, SPELLS_NUM);

            // New _Hero_.spell[140] field
            _PI->WriteDword(0x40D97C, 0x3EA);
            _PI->WriteDword(0x41FBDF, 0x3EA);
            _PI->WriteDword(0x425C72, 0x3EA);
            _PI->WriteDword(0x427039, 0x3EA);
            _PI->WriteDword(0x427044, 0x3EA);
            _PI->WriteDword(0x4329C1, 0x3EA);
            _PI->WriteDword(0x432CDE, 0x3EA);
            _PI->WriteDword(0x433026, 0x3EA);
            _PI->WriteDword(0x4336C0, 0x3EA);
            _PI->WriteDword(0x439330, 0x3EA);
            _PI->WriteDword(0x43C561, 0x3EA);
            _PI->WriteDword(0x4E57CC, 0x3EA);
            _PI->WriteDword(0x527ACB, 0x3EA);
            _PI->WriteDword(0x52A97A, 0x3EA);
            _PI->WriteDword(0x52AE1C, 0x3EA);
            _PI->WriteDword(0x59CD5E, 0x3EA); // Spell Book
        }
    }

   return TRUE;
}

Адреса, которые всё ещё нужно найти, стремительно заканчиваются. Однако, чтобы всё работало, над многими из них придётся посидеть с дебаггером.
Последний раз редактировалось AlexSpl 18 авг 2021, 09:15, всего редактировалось 1 раз.
Вернуться к началу

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

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

Сообщение Rolex » 18 авг 2021, 08:30

Картинки для свитков по всей видимости хранятся здесь: SpellBon.def. Если в ресурсах RoE или AB нет картинки Fear для свитков, то можете взять мою.
Ах да, для наложенных заклов, они здесь - SpellInt.def, также нужно делать картинку Fear.

Все что у меня получилось прикрепил в архиве. Их осталось только запаковать в дефки вместе с остальными картинками для заклов.
Вложения
Fear.rar
(6.2 КБ) Скачиваний: 108
Вернуться к началу

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

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

Сообщение AlexSpl » 18 авг 2021, 14:02

Научил Учёных :smile1: делиться новыми заклинаниями. Нашёл ещё пару мест, требующих внимания.

Изображение

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

Patcher* _P;
PatcherInstance* _PI;

//char iniPath[MAX_PATH];

#define SPELLS_NUM 71
#define SPL_FEAR 70
_Spell_ spell[128];

int __stdcall afterInit(LoHook* h, HookContext* c)
{
    for (int i = 0; i < SPL_FEAR; ++i)
        spell[i] = o_Spell[i];

    spell[SPL_FEAR].type = -1;
    spell[SPL_FEAR].wav_name = "Fear.wav";
    spell[SPL_FEAR].animation_ix = 15;
    spell[SPL_FEAR].flags = 0x20415;
    spell[SPL_FEAR].name = "Fear";
    spell[SPL_FEAR].short_name = "Fear";
    spell[SPL_FEAR].level = 4;
    spell[SPL_FEAR].school_flags = 8;
    spell[SPL_FEAR].mana_cost[0] = 16;
    spell[SPL_FEAR].mana_cost[1] = 8;
    spell[SPL_FEAR].mana_cost[2] = 8;
    spell[SPL_FEAR].mana_cost[3] = 8;
    spell[SPL_FEAR].eff_power = 0;
    spell[SPL_FEAR].effect[0] = 75;
    spell[SPL_FEAR].effect[1] = 75;
    spell[SPL_FEAR].effect[2] = 50;
    spell[SPL_FEAR].effect[3] = 25;
    spell[SPL_FEAR].chance2get_var[0] = 10;
    spell[SPL_FEAR].chance2get_var[1] = 10;
    spell[SPL_FEAR].chance2get_var[2] = 10;
    spell[SPL_FEAR].chance2get_var[3] = 10;
    spell[SPL_FEAR].chance2get_var[4] = 10;
    spell[SPL_FEAR].chance2get_var[5] = 10;
    spell[SPL_FEAR].chance2get_var[6] = 10;
    spell[SPL_FEAR].chance2get_var[7] = 10;
    spell[SPL_FEAR].chance2get_var[8] = 10;
    spell[SPL_FEAR].ai_value[0] = 50;
    spell[SPL_FEAR].ai_value[1] = 50;
    spell[SPL_FEAR].ai_value[2] = 50;
    spell[SPL_FEAR].ai_value[3] = 50;
    spell[SPL_FEAR].description[0] =
        "{Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n";
    spell[SPL_FEAR].description[1] =
        "{Basic Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n\nSpell Point cost is half that of Normal Fear.\n";
    spell[SPL_FEAR].description[2] =
        "{Advanced Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n\nPenalty to movement is twice that of Basic Fear.\n";
    spell[SPL_FEAR].description[3] =
        "{Expert Fear}\n\nStrikes an enemy unit with such fear that it becomes unable to attack and nearly unable to move.\n\nPenalty to movement is three times that of Basic Fear.\n";

    for (int i = SPL_FEAR + 1; i < SPL_FEAR + 11; ++i)
        spell[i] = o_Spell[i];

    _PI->WriteDword(0x687FA8, (int)&spell);

    return EXEC_DEFAULT;
}

BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
    static bool plugin_On = false;
    if ( DLL_PROCESS_ATTACH == ul_reason_for_call )
    {
        if ( !plugin_On )
        {
            plugin_On = true;
            _P = GetPatcher();
            _PI = _P->CreateInstance("HD.Plugin.H3.NewSpells");

            //GetCurrentDirectoryA(sizeof(iniPath), iniPath);
            //strcat(iniPath, "\\NewSpells.ini");

            // Moving and Expanding Spell Table
            _PI->WriteLoHook(0x4EE1C1, afterInit);
                   
            // nwcthereisnospoon
            _PI->WriteByte (0x402902, SPELLS_NUM);
           
            _PI->WriteByte (0x41FC91, SPELLS_NUM);
            _PI->WriteDword(0x425E98, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteByte (0x427085, SPELLS_NUM);
            _PI->WriteDword(0x432A43, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x432D1E, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x43C21B, SPELLS_NUM * sizeof(_Spell_)); // Master Genie AI
            _PI->WriteDword(0x43C6F2, SPELLS_NUM * sizeof(_Spell_)); // Battle AI
            _PI->WriteDword(0x447551, SPELLS_NUM * sizeof(_Spell_)); // Casters
            _PI->WriteDword(0x447C7D, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x447CC8, SPELLS_NUM * sizeof(_Spell_));
           
            // Cheats in battle
            _PI->WriteByte (0x471C57, SPELLS_NUM);
           
            _PI->WriteByte (0x4864B0, SPELLS_NUM);
            _PI->WriteByte (0x48A34B, SPELLS_NUM);
            _PI->WriteByte (0x4C244D, SPELLS_NUM);
            _PI->WriteByte (0x4C246F, SPELLS_NUM);
            _PI->WriteDword(0x4C24C9, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteByte (0x4E67AC, SPELLS_NUM);
            _PI->WriteByte (0x4F508B, SPELLS_NUM);
            _PI->WriteDword(0x4F50CE, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4F5114, SPELLS_NUM * sizeof(_Spell_));
                       
            // _GameMgr_.disabled_spells[SPELLS_NUM]
            _PI->WriteByte (0x4C250E, SPELLS_NUM);
            _PI->WriteDword(0x4C2557, SPELLS_NUM * sizeof(_Spell_));
           
            _PI->WriteDword(0x4C260D, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4C92C5, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4C9347, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x4C93C0, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteByte (0x4CEC4F, SPELLS_NUM);
            _PI->WriteByte (0x4D8F53, SPELLS_NUM);
            _PI->WriteByte (0x4D8F8A, SPELLS_NUM);
           
            // Tome of Air Magic
            _PI->WriteDword(0x4D962D, SPELLS_NUM * sizeof(_Spell_));
            // Tome of Fire Magic
            _PI->WriteDword(0x4D9681, SPELLS_NUM * sizeof(_Spell_));
            // Tome of Water Magic
            _PI->WriteDword(0x4D96D6, SPELLS_NUM * sizeof(_Spell_));
            // Tome of Earth Magic
            _PI->WriteDword(0x4D972E, SPELLS_NUM * sizeof(_Spell_));
            // Spellbinder's Hat
            _PI->WriteDword(0x4D9771, SPELLS_NUM * sizeof(_Spell_));
           
            _PI->WriteByte (0x4D98EA, SPELLS_NUM);
            _PI->WriteByte (0x4D99D6, SPELLS_NUM);
           
            // Scholars
            _PI->WriteByte (0x5012B7, SPELLS_NUM);
            _PI->WriteDword(0x527B08, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x52A9B6, SPELLS_NUM * sizeof(_Spell_)); // AI
            _PI->WriteDword(0x534C4B, SPELLS_NUM * sizeof(_Spell_)); // RMG
            _PI->WriteDword(0x5353D5, SPELLS_NUM);
            _PI->WriteByte (0x53542B, SPELLS_NUM);
            _PI->WriteDword(0x59CDBF, SPELLS_NUM * sizeof(_Spell_)); // Spell Book
            _PI->WriteDword(0x5A1AD6, SPELLS_NUM * sizeof(_Spell_)); // Cast Spell

            // Mage Guild
            _PI->WriteByte (0x5BEA2C, SPELLS_NUM);
            _PI->WriteByte (0x5BEA70, SPELLS_NUM);
            _PI->WriteByte (0x5BEAAD, SPELLS_NUM);
            _PI->WriteDword(0x5BEAFE, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x5BEB2C, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteByte (0x5BEB48, SPELLS_NUM);
            _PI->WriteByte (0x5BEB71, SPELLS_NUM);
            _PI->WriteByte (0x5BEBB2, SPELLS_NUM);
            _PI->WriteDword(0x5BEC05, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteByte (0x5BEC1B, SPELLS_NUM);
                       
            // Conflux Grail
            _PI->WriteDword(0x5BE512, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x5BE56E, SPELLS_NUM * sizeof(_Spell_));
            _PI->WriteDword(0x5D7464, SPELLS_NUM);
           
            // ---------------------------
            // New _Hero_.spell[140] field
            // ---------------------------
            _PI->WriteCodePatch(0x4D8B72, "%n", 8);
            _PI->WriteCodePatch(0x4D8F7F, "%n", 8);
            _PI->WriteCodePatch(0x4D95AF, "%n", 7);

            _PI->WriteDword(0x40D97C, 0x3EA);
            _PI->WriteDword(0x41FBDF, 0x3EA);
            _PI->WriteDword(0x425C72, 0x3EA);
            _PI->WriteDword(0x427039, 0x3EA);
            _PI->WriteDword(0x427044, 0x3EA);
            _PI->WriteDword(0x4329C1, 0x3EA);
            _PI->WriteDword(0x432CDE, 0x3EA);
            _PI->WriteDword(0x433026, 0x3EA);
            _PI->WriteDword(0x4336C0, 0x3EA);
            _PI->WriteDword(0x439330, 0x3EA);
            _PI->WriteDword(0x43C561, 0x3EA);
           
            // Clear _Hero_.spell[140] (optional)
            _PI->WriteDword(0x48647A, 0x23);
            _PI->WriteJmp(0x486485, 0x486498);
           
            _PI->WriteDword(0x4E57CC, 0x3EA);
            _PI->WriteDword(0x527ACB, 0x3EA);
            _PI->WriteDword(0x52A97A, 0x3EA);
            _PI->WriteDword(0x52AE1C, 0x3EA);
            // Spell Book
            _PI->WriteDword(0x59CD5E, 0x3EA);
        }
    }

   return TRUE;
}

Следующий этап - чиним свитки заклинаний, поломанные из-за расширения поля _Hero_.spell[70] на поле _Hero_.spell_level[70].

Кстати, Вы можете помочь в тестировании объектов, дающих заклинания. Если есть ограничение по уровню заклинания, можно на время тестов снизить или повысить уровень заклинания Fear. Например, интересно, новые заклинания уже попадают в Пирамиду, а в свитки на рандомных картах?
Вернуться к началу

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

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

Сообщение Rolex » 18 авг 2021, 14:13

Кстати, а какой процент работы от всей запланированной уже сделан, примерно?
Вернуться к началу

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

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

Сообщение AlexSpl » 18 авг 2021, 14:16

Зависит от конечной цели. Будем считать, что добавляем только Fear (другие добавляются аналогично; кстати, если у Вас есть графика новых заклинаний, можете хоть сейчас начать добавлять). Сложно оценить процент, так как неизвестна трудоёмкость предпоследнего* этапа, когда нужен будет код для Fear. Но если навскидку, то процентов 40 уже готово.

* Последний этап - это сдвиг абилок (их 10). Думаю, не трогать их код, пока не будет готов код обычных заклинаний.

Каст Fear и Старения (Aging?) уже сейчас можно добавить. Думаю, после того, как починю свитки, займусь. Может быть, получится так, что Старение будет реализовано первым, т.к. для него есть готовый код.
Вернуться к началу

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

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

Сообщение Rolex » 18 авг 2021, 14:24

Ок. Тогда пока что сосредоточимся полностью на Fear, не отвлекаясь на другие.

Когда Fear будет полностью готов, тогда и будем думать за другие. Да и там всего-то 3 закла: Старение, Яд и Болезнь (я немного исправил свое сообщение: viewtopic.php?f=56&t=518&start=3060#p22995)

AlexSpl писал(а):

Например, интересно, новые заклинания уже попадают в Пирамиду, а в свитки на рандомных картах?

Вас интересует только на рандомных картах или на всех?
Вернуться к началу

Пред.След.

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

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

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