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


Друзья, если не получается зарегистрироваться, напишите на почту 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 » 28 окт 2020, 12:54

Цитата:
Так вот задача сейчас состоит в том, чтобы написать лоухук(и) (или, если возможно, через WriteDword/WriteHexPatch), который эффект Радости и Удачи подымет до +3, а Печали и Неудачи опустит до -3 на Экспертном уровне.

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

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

bool __stdcall changeLMSpells(HiHook* hook)
{
    bool res = CALL_0(bool, __cdecl, hook->GetDefaultFunc());

    int LMEffects[] = {1, 1, 2, 3};
   
    for (int i = 0; i < 4; ++i)
    {
        o_Spell[SPL_MIRTH].effect[i] = LMEffects[i];
        o_Spell[SPL_SORROW].effect[i] = -LMEffects[i];
        o_Spell[SPL_FORTUNE].effect[i] = LMEffects[i];
        o_Spell[SPL_MISFORTUNE].effect[i] = -LMEffects[i];
    }

    // Здесь заодно можно поменять описания

    return res;
}

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((char*)"HD.Plugin.LMSpells");
            // HiHook on loading sptraits.txt
            _PI->WriteHiHook(0x4EDEAF, SPLICE_, EXTENDED_, THISCALL_, changeLMSpells);
        }
    }

    return TRUE;
}

Только учтите, что у этих заклинаний свой собственный кап (-3..+3) Морали и Удачи.

Насчёт возвращаемого типа bool vs char vs int. Считаю, что в исходниках был логический тип bool (false - файл sptraits.txt не удалось загрузить/файл загружен с ошибками, true - файл загружен успешно). Но здесь не будет ошибкой использовать char или даже int в качестве возвращаемого HiHook'ом типа. Насчёт соглашения о вызове __cdecl vs __stdcall. У функции нет аргументов, поэтому используем __cdecl, т.к. это соглашение о вызове в MVS используется по умолчанию.

* * *
Цитата:
Ускорение нужно увеличить с 5 до 7 на Эксперте. А вот Медлительность хотелось бы подправить на всех уровнях вместо 25%/25%/50%/50% ---> 20%/20%/40%/60%. Нужна ваша помощь.

Сделать это можно в том же хайхуке. Думаю, у Вас получится.

* * *
Замечание о TXT-файлах, загружаемых из LOD-архива. Для всех задач, которые требуют изменения данных в TXT-файлах ресурсов игры, можно использовать единый адрес для LoHook: 0x4EE006 (сразу после загрузки всех TXT-файлов), а не ставить хайхуки на каждую функцию загрузки текстовика по отдельности.

Пример.

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

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

int __stdcall changeLMSpells(LoHook* h, HookContext* c)
{
    int LMEffects[] = {1, 1, 2, 3};
   
    for (int i = 0; i < 4; ++i)
    {
        o_Spell[SPL_MIRTH].effect[i] = LMEffects[i];
        o_Spell[SPL_SORROW].effect[i] = -LMEffects[i];
        o_Spell[SPL_FORTUNE].effect[i] = LMEffects[i];
        o_Spell[SPL_MISFORTUNE].effect[i] = -LMEffects[i];
    }

    // Здесь заодно можно поменять описания

    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((char*)"HD.Plugin.LMSpells");
            // LoHook after loading all text files
            _PI->WriteLoHook(0x4EE006, changeLMSpells);
        }
    }

    return TRUE;
}

В этот лоухук можно поместить весь код, связанный с работой с текстовыми ресурсами LOD.

Так... Кроме camptext.txt :smile14: Тогда LoHook можно поставить ниже (например, здесь: 0x4EE1C1) или обернуть функцию 0x4EDCE0 HiHook'ом.
Вернуться к началу

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

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

Сообщение Rolex » 28 окт 2020, 18:29

Цитата:
Чтобы изменить эффект First Aid, Вам потребуется изменить базовый хил и коэффициенты. Базовый хил (25.0f) здесь: 0x63B76C, коэффициенты (0.0f, 1.0f, 2.0f, 3.0f) здесь: 0x63EA98. Базовый хил просто так менять нельзя (константа 25.0f используется в других алгоритмах), но мы уже обсуждали, что нужно делать в таких случаях. Базовый хил и коэффициенты - вещественные числа с плавающей точкой типа float (ссылку на конвертер float to hex я давал выше). Можно и без конвертера обойтись. Тоже пример выше был.

Да я в принципе всегда в тех навыках где идет повышение через %, использую проценты либо с гайда, либо конвертирую нужный через конвертер (для Интеллекта, Логистики, например). А вот для Разведки и Имущества итак все работает, там целые числа. Но здесь не совсем было очевидно, что нужно использовать вещественные числа с плавающей точкой типа float. Замудренно конечно с этой Палаткой все, но вроде как разобрался, заодно и математику немного вспомнил. :smile1:

В оригинале здоровье Палатки получается изменяется таким образом:

25.0f * (0.0f + 1)
25.0f * (1.0f + 1)
25.0f * (2.0f + 1)
25.0f * (3.0f + 1)

25.0f - базовый хил и коэффициенты (0.0f, 1.0f, 2.0f, 3.0f)

Подняв базовый хил до 75.0f я получил 75/150/225/300:

75.0f * (0.0f + 1) = 75.0f
75.0f * (1.0f + 1) = 150.0f
75.0f * (2.0f + 1) = 225.0f
75.0f * (3.0f + 1) = 300.0f

А мне нужно было 50/100/200/300, пришлось считать и править коэффициенты:

75.0f * (x.0f + 1) = 50.0f ===> -0.33 ===> 0xbea8f5c3
75.0f * (x.0f + 1) = 100.0f ===> 0.34 ===> 0x3eae147b
75.0f * (x.0f + 1) = 200.0f ===> 1.67 ===> 0x3fd5c28f
75.0f * (x.0f + 1) = 300.0f ===> 3 ===> 0x40400000

Итого, все работает, как нужно:

Код: Выделить всё
// dllmain.cpp: определяет точку входа для приложения DLL.
#define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
#include "HotA\homm3.h"

Patcher* _P; // required for every plugin
PatcherInstance* _PI;
static _bool_ plugin_On = 0;

struct SecSkillDesc
{
   char* Name;
   char* BasicDesc;
   char* AdvancedDesc;
   char* ExpertDesc;
};

SecSkillDesc FirstAidDesc =
{
   "Первая помощь",
   "{Первая помощь – \"Базовый\" уровень}\n\nВосстанавливает 100 единиц здоровья у всех отрядов в армии героя.",
   "{Первая помощь – \"Продвинутый\" уровень}\n\nВосстанавливает 200 единиц здоровья у всех отрядов в армии героя.",
   "{Первая помощь – \"Экспертный\" уровень}\n\nВосстанавливает 300 единиц здоровья у всех отрядов в армии героя."
};

int __stdcall changeFirstAidDesc(LoHook* h, HookContext* c)
{
   *(SecSkillDesc*)(*(int*)0x67DCF0 + 27 * 16) = FirstAidDesc;
   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.FirstAid");         

            _PI->WriteHexPatch(0x47852C, "EB 0A");   
             _PI->WriteDword(0x63B76C, 0x42960000);

            _PI->WriteDword(0x63EA98, 0xbea8f5c3);
            _PI->WriteDword(0x63EA98 + 4, 0x3eae147b);
            _PI->WriteDword(0x63EA98 + 8, 0x3fd5c28f);
            _PI->WriteDword(0x63EA98 + 12, 0x40400000);

            _PI->WriteLoHook(0x4E6D77, changeFirstAidDesc);
      }
   }
   return TRUE;
}


Осталось самое интересное. И вот здесь уж точно просто не будет. Без вашей помощи не обойтись.

1) Контроля Палатки нет. Игрок не управляет палаткой, все идет автоматически как и без навыка Первая помощь, только Палатка лечит не один отряд, а сразу все отряды героя. Но только с навыком Первая Помощь Базового уровня, без навыка оставить как есть - один отряд существ, который потерял больше всего здоровья.
2) Палатка восстанавливает здоровье всех орудий (Баллисты, Тележки, Катапульты), но пока кроме своего. В оригинале можно восстановить только здоровье существ. Этот бонус должен работать уже начиная с навыка Первая помощь Продвинутого уровня.
3) Палатка восстанавливает свое здоровье (в кол-ве, который соответствует развитию навыка - 300 ед, то есть полностью). Это уже с навыком Первая помощь Экспертного уровня.
4) Здоровье Палатки увеличить с 75 до 300.
5) Защиту Палатки увеличить с 0 до 10.
6) Стоимость Палатки увеличить с 750 до 1500.
Последний раз редактировалось Rolex 31 окт 2020, 13:34, всего редактировалось 10 раз(а).
Вернуться к началу

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

Базовый хил не нужно было трогать. Я уже писал, что эта константа используется не только для палатки. Вместо этого достаточно поменять коэффициенты:

Код: Выделить всё
// Меняем коэффициенты
float firstAidCoefs[] = {1.0f, 3.0f, 7.0f, 11.0f};

_PI->WriteDword(0x63EA98, (int&)firstAidCoefs[0]);
_PI->WriteDword(0x63EA98 + 4, (int&)firstAidCoefs[1]);
_PI->WriteDword(0x63EA98 + 8, (int&)firstAidCoefs[2]);
_PI->WriteDword(0x63EA98 + 12, (int&)firstAidCoefs[3]);


Цитата:
Осталось самое интересное.

Гляну попозже.
Вернуться к началу

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

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

Сообщение Rolex » 28 окт 2020, 19:04

AlexSpl писал(а):

Базовый хил не нужно было трогать. Я уже писал, что эта константа используется не только для палатки. Вместо этого достаточно поменять коэффициенты:

Видимо, я невнимательно прочел. Спасибо. Ваше решение конечно куда проще и не затрагивает константу. И никаких конвертеров ненужно.
Вернуться к началу

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 » 31 окт 2020, 02:52

Палатка с массхилом (требуется тестирование):

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

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

struct HealingInfo
{
    int stackID;
    int removedDamage;
} healingInfo[21 + 1];

int __stdcall afterInit(LoHook* h, HookContext* c)
{
    o_pCreatureInfo[CID_FIRST_AID_TENT].hit_points = 300;
    o_pCreatureInfo[CID_FIRST_AID_TENT].defence = 10;
    o_pCreatureInfo[CID_FIRST_AID_TENT].cost.gold = 1500;

    // Здесь можно также прописать все изменения текстовиков
   
    return EXEC_DEFAULT;
}

int __stdcall findTargetsToHeal(LoHook* h, HookContext* c)
{
    _Hero_* hero = o_BattleMgr->hero[o_BattleMgr->current_side];

    if ( hero && hero->second_skill[HSS_FIRST_AID] )
    {
        int n = 0;
        bool needHealing = false;
       
        for (int i = 0; i < o_BattleMgr->stacks_count[o_BattleMgr->current_side]; ++i)
        {
            _BattleStack_* stack = &o_BattleMgr->stack[o_BattleMgr->current_side][i];
       
            bool isSubjectToBeHealed = stack->lost_hp && !(stack->creature.flags & 0x200000);
            if ( hero->second_skill[HSS_FIRST_AID] == 2 && isSubjectToBeHealed )
                isSubjectToBeHealed = stack->creature_id != CID_FIRST_AID_TENT;

            if ( isSubjectToBeHealed )
            {
                needHealing = true;
                healingInfo[n].stackID = i;
                ++n;

                // Даём алгоритму игры валидную цель для хила
                *(int*)(c->ebp - 8) = i;
            }
        }
   
        healingInfo[n].stackID = -1;

        c->return_address = needHealing ? 0x4738C3 : 0x4738B3;
        return NO_EXEC_DEFAULT;
    }

    return EXEC_DEFAULT;
}

int __stdcall applyHealing(LoHook* h, HookContext* c)
{
    _Hero_* hero = o_BattleMgr->hero[o_BattleMgr->current_side];

    if ( hero && hero->second_skill[HSS_FIRST_AID] )
    {
        int i = 0;
        while ( healingInfo[i].stackID != -1 )
        {
            _BattleStack_* stack = &o_BattleMgr->stack[o_BattleMgr->current_side][healingInfo[i].stackID];
           
            if ( c->eax < stack->lost_hp ) {
                healingInfo[i].removedDamage = c->eax;
                stack->lost_hp -= c->eax;
            }
            else {
                healingInfo[i].removedDamage = stack->lost_hp;
                stack->lost_hp = 0;
            }
            ++i;
        }

        c->return_address = 0x478555;
        return NO_EXEC_DEFAULT;
    }

    return EXEC_DEFAULT;
}

int __stdcall playAnimation(LoHook* h, HookContext* c)
{
    _Hero_* hero = o_BattleMgr->hero[o_BattleMgr->current_side];

    if ( hero && hero->second_skill[HSS_FIRST_AID] )
    {
        memset(&o_BattleMgr->Field<int>(0x547C), 0, 40);
       
        // Пишем лог и проигрываем анимацию для всех вылеченных отрядов
        int i = 0;
        while ( healingInfo[i].stackID != -1 )
        {
            _BattleStack_* stack = &o_BattleMgr->stack[o_BattleMgr->current_side][healingInfo[i].stackID];

            sprintf(o_TextBuffer, o_GENRLTXT_TXT->GetString(415), GetCreatureName(CID_FIRST_AID_TENT, 1),
                GetCreatureName(stack->creature_id, stack->count_current), healingInfo[i].removedDamage);

            CALL_4(void, __thiscall, 0x4729D0, o_BattleMgr->dlg, o_TextBuffer, 1, 0);
           
            // Отмечаем отряды, для которых необходима анимация
            o_BattleMgr->Field<int>(0x547C + 20 * o_BattleMgr->current_side + healingInfo[i].stackID) = 1;

            ++i;
        }

        // Проигрываем массовую анимацию
        CALL_4(void, __thiscall, 0x5A6AD0, o_BattleMgr, &o_BattleMgr->Field<int>(0x547C), 79, 0);
       
        // Ждём, пока воспроизведётся звук
        CALL_3(void, __thiscall, 0x59A7C0, -1, c->eax, c->edx);
       
        c->return_address = 0x478692;
        return NO_EXEC_DEFAULT;
    }
       
    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((char*)"HD.Plugin.NewFirstAidTent");

            // Меняем параметры First Aid Tent
            _PI->WriteLoHook(0x4EE1C1, afterInit);

            // Меняем коэффициенты
            float firstAidCoefs[] = {1.0f, 3.0f, 7.0f, 11.0f};
            _PI->WriteDword(0x63EA98, (int&)firstAidCoefs[0]);
            _PI->WriteDword(0x63EA98 + 4, (int&)firstAidCoefs[1]);
            _PI->WriteDword(0x63EA98 + 8, (int&)firstAidCoefs[2]);
            _PI->WriteDword(0x63EA98 + 12, (int&)firstAidCoefs[3]);

            // Проверяем, нужен ли хил
            _PI->WriteLoHook(0x473865, findTargetsToHeal);

            // Убираем ручной контроль
            _PI->WriteCodePatch(0x4745FD, "%n", 10);

            // Делаем хил максимальным
            _PI->WriteCodePatch(0x47852C, "%n", 12);
                       
            // Хилим
            _PI->WriteLoHook(0x47852C, applyHealing);

            // Пишем лог и проигрываем анимацию
            _PI->WriteLoHook(0x478580, playAnimation);
        }
    }

    return TRUE;
}

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

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

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

Сообщение Rolex » 31 окт 2020, 07:14

AlexSpl писал(а):

Палатка с массхилом (требуется тестирование):

О, спасибо. Палатка с массхилом это конечно круто. Такого нет нигде, ни в AdFontes, ни в WoG, ни в HotA.

Ваша dll-ка из прикрепленного архива у меня работает, но на Базовом уровне навыка Палатка восстанавливает СВОЕ здоровье плюс здоровье всех других орудий (Тележки, Баллисты, Катапульты), то есть на Базовом уровне работает как на Эксперте, а нужно чтобы на Базовом уровне было восстановление здоровья только всех отрядов существ. На других уровнях, вроде, все ок.

Интересно, что если я сам собираю ваш код у себя, то у меня он не корректно работает. Убирается только ручной контроль, а сама Палатка восстанавливает здоровье только одного существа на любом уровне навыка, как будто его и нет. Собирал не на виртуалке, на Windows 7 x64, Visual Studio 2015 и в Release (x86). В чем может быть проблема не подскажите, почему один и тот же код собранный вами и мной работает по-разному?

AlexSpl писал(а):

// Здесь можно также прописать все изменения текстовиков

А можно пример. Если, допустим, нужно подправить описание не навыка, а, например, то описание, которое идет к Палатке по умолчанию (как артефакта), которое находится в файле ARTRAITS.TXT или то, которое можно увидеть в бою по правому клику по Палатке, которое находится в файле CRTRAITS.TXT.
Вернуться к началу

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

Цитата:
Ваша dll-ка из прикрепленного архива у меня работает, но на Базовом уровне навыка Палатка восстанавливает СВОЕ здоровье плюс здоровье всех других орудий (Тележки, Баллисты, Катапульты), то есть на Базовом уровне работает как на Эксперте, а нужно чтобы на Базовом уровне было восстановление здоровья только всех отрядов существ. На других уровнях, вроде, все ок.

Это из-за функции findTargetsToHeal(). Сначала было условие hero->second_skill[HSS_FIRST_AID] > 1, но потом я переделал логику. Короче, исправлю.

 Переписал функцию
Код: Выделить всё
int __stdcall findTargetsToHeal(LoHook* h, HookContext* c)
{
    _Hero_* hero = o_BattleMgr->hero[o_BattleMgr->current_side];

    if ( hero && hero->second_skill[HSS_FIRST_AID] )
    {
        int n = 0;
        bool needHealing = false;
       
        for (int i = 0; i < o_BattleMgr->stacks_count[o_BattleMgr->current_side]; ++i)
        {
            _BattleStack_* stack = &o_BattleMgr->stack[o_BattleMgr->current_side][i];
       
            bool isSubjectToBeHealed = false;
           
            if ( stack->lost_hp ) {
                switch ( hero->second_skill[HSS_FIRST_AID] ) {
                    case 1: isSubjectToBeHealed = !(stack->creature.flags & 0x200040); break;
                    case 2: isSubjectToBeHealed = !(stack->creature.flags & 0x200000) && stack->creature_id != CID_FIRST_AID_TENT; break;
                    case 3: isSubjectToBeHealed = !(stack->creature.flags & 0x200000); break;
                }
            }

            if ( isSubjectToBeHealed )
            {
                needHealing = true;
                healingInfo[n].stackID = i;
                ++n;

                // Даём алгоритму игры валидную цель для хила
                *(int*)(c->ebp - 8) = i;
            }
        }
   
        healingInfo[n].stackID = -1;

        c->return_address = needHealing ? 0x4738C3 : 0x4738B3;
        return NO_EXEC_DEFAULT;
    }

    return EXEC_DEFAULT;
}


Цитата:
Интересно, что если я сам собираю ваш код у себя, то у меня он не корректно работает. Убирается только ручной контроль, а сама Палатка восстанавливает здоровье только одного существа на любом уровне навыка, как будто его и нет. Собирал не на виртуалке, на Windows 7 x64, Visual Studio 2015 и в Release (x86). В чем может быть проблема не подскажите, почему один и тот же код собранный вами и мной работает по-разному?

Убедитесь в том, что выравнивание членов структур установлено в 1 байт, конфигурация решения - "Release", а также в том, что Вы используете homm3.h именно из первого сообщения этой темы. Если не помогает, отключите все другие плагины и подключите только этот (без правок, с текстом, скопированным из сообщения выше).

Цитата:
А можно пример. Если, допустим, нужно подправить описание не навыка, а, например, то описание, которое идет к Палатке по умолчанию (как артефакта), которое находится в файле ARTRAITS.TXT или то, которое можно увидеть в бою по правому клику по Палатке, которое находится в файле CRTRAITS.TXT.

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

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

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

Сообщение Rolex » 31 окт 2020, 14:49

AlexSpl писал(а):

Убедитесь в том, что выравнивание членов структур установлено в 1 байт, конфигурация решения - "Release", а также в том, что Вы используете homm3.h именно из первого сообщения этой темы. Если не помогает, отключите все другие плагины и подключите только этот (без правок, с текстом, скопированным из сообщения выше).

Я внимательно перечитывал ваше первое сообщение в теме и первым делом всегда ставлю выравнивание членов структур в 1 байт, а конфигурацию решения - "Release". homm3.h был взят из первого сообщения, он идет в папке HotA вместе с другими библиотеками. Отключал все другие плагины - не помогло. Результат тот же - нет массхила. Самое интересное, что ваш собранный плагин работает, как со всеми другими подключенными плагинами, так и без. А у меня никак не хочет. Такое впервые, уже целую кучу собрал плагинов. Может дело в среде разработки? У вас какая?

PS: Соответственно и переписанную функцию проверить не могу.
Последний раз редактировалось Rolex 31 окт 2020, 14:54, всего редактировалось 1 раз.
Вернуться к началу

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

Вероятно, дело в настройках компилятора по умолчанию. У меня в данный момент Express 2008.

Так, а посмотрите, какой у Вас размер bool: 1 или 4 байта?
Вернуться к началу

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

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

Сообщение Rolex » 31 окт 2020, 14:59

Цитата:
Так, а посмотрите, какой у Вас размер bool: 1 или 4 байта?

А где именно это смотреть? Свойства конфиг - C/C++ - Создание кода? Как этот пункт точно называется?
Вернуться к началу

Пред.След.

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

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

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