Объявления
Поздравляем
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 » 05 фев 2019, 20:50

Код для кол-ва потерь:

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

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

int MinKilled, MaxKilled;

int __stdcall getLosses(LoHook* h, HookContext* c)
{
    _BattleStack_* foeStack = *(_BattleStack_**)(c->ebp + 8);
   
    MinKilled = c->edi / foeStack->full_hp;
    if ( c->edi % foeStack->full_hp >= foeStack->full_hp - foeStack->lost_hp ) ++MinKilled;
    if ( MinKilled > foeStack->count_current ) MinKilled = foeStack->count_current;
   
    MaxKilled = c->eax / foeStack->full_hp;
    if ( c->eax % foeStack->full_hp >= foeStack->full_hp - foeStack->lost_hp ) ++MaxKilled;
    if ( MaxKilled > foeStack->count_current ) MaxKilled = foeStack->count_current;

    return EXEC_DEFAULT;
}

int __stdcall showLosses(LoHook* h, HookContext* c)
{
    sprintf(o_TextBuffer, "%s.  Losses: %d-%d", o_TextBuffer, MinKilled, MaxKilled);
    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.ShowLosses");

            _PI->WriteLoHook(0x493053, getLosses);
            _PI->WriteLoHook(0x492619, showLosses);
        }
    }

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

offlineas239  
имя: Анатолий
Ветеран
Ветеран
 
Сообщения: 527
Зарегистрирован: 29 дек 2018, 14:17
Пол: Мужчина
Поблагодарили: 38 раз.

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

Сообщение as239 » 06 фев 2019, 13:57

AlexSpl писал(а):

* * *
Со строкой ещё вот так попробуйте:
Код: Выделить всё
// Передаём адрес текстового буфера в качестве аргумента для диалога
sprintf(o_TextBuffer, "%s", str.c_str());
c->ecx = (int)o_TextBuffer;


Развернул все на ноутбуке с Windows.
Так вот на ноутбуке была та же самая проблема с отображением текста что и на маке.
Эта правка все исправила.
На маке с ней тоже все ок, даже не знаю может и не стоит переезжать :)
Последний раз редактировалось as239 06 фев 2019, 14:14, всего редактировалось 1 раз.
Вернуться к началу

offlineas239  
имя: Анатолий
Ветеран
Ветеран
 
Сообщения: 527
Зарегистрирован: 29 дек 2018, 14:17
Пол: Мужчина
Поблагодарили: 38 раз.

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

Сообщение as239 » 06 фев 2019, 13:59

AlexSpl писал(а):

Кстати, вышло обновление HD мода. Изменился код для перестройки:

 
Код: Выделить всё
int __stdcall patchDll(LoHook* h, HookContext* c)
{
   HMODULE hHW_SOD = GetModuleHandleA("HW_SOD.dll");

   if ( hHW_SOD ) _PI->WriteByte((int)hHW_SOD + 0xFCC7, 0xEB);
   
   return EXEC_DEFAULT;
}


А можно прям на пальцах объяснить как искать этот изменяющийся адрес.
Чтобы я сам мог править при выходе новой версии HD мода.
Вернуться к началу

offlineas239  
имя: Анатолий
Ветеран
Ветеран
 
Сообщения: 527
Зарегистрирован: 29 дек 2018, 14:17
Пол: Мужчина
Поблагодарили: 38 раз.

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

Сообщение as239 » 06 фев 2019, 14:00

AlexSpl писал(а):

Код для кол-ва потерь:

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

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

int MinKilled, MaxKilled;

int __stdcall getLosses(LoHook* h, HookContext* c)
{
    _BattleStack_* foeStack = *(_BattleStack_**)(c->ebp + 8);
   
    MinKilled = c->edi / foeStack->full_hp;
    if ( c->edi % foeStack->full_hp >= foeStack->full_hp - foeStack->lost_hp ) ++MinKilled;
    if ( MinKilled > foeStack->count_current ) MinKilled = foeStack->count_current;
   
    MaxKilled = c->eax / foeStack->full_hp;
    if ( c->eax % foeStack->full_hp >= foeStack->full_hp - foeStack->lost_hp ) ++MaxKilled;
    if ( MaxKilled > foeStack->count_current ) MaxKilled = foeStack->count_current;

    return EXEC_DEFAULT;
}

int __stdcall showLosses(LoHook* h, HookContext* c)
{
    sprintf(o_TextBuffer, "%s.  Losses: %d-%d", o_TextBuffer, MinKilled, MaxKilled);
    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.ShowLosses");

            _PI->WriteLoHook(0x493053, getLosses);
            _PI->WriteLoHook(0x492619, showLosses);
        }
    }

    return TRUE;
}


Шикарно, работает!
Единственное, сделал чтобы показывалась одна цифра при равных минимальном и максимальном значениях.
Последний раз редактировалось as239 06 фев 2019, 14:04, всего редактировалось 1 раз.
Вернуться к началу

offlineas239  
имя: Анатолий
Ветеран
Ветеран
 
Сообщения: 527
Зарегистрирован: 29 дек 2018, 14:17
Пол: Мужчина
Поблагодарили: 38 раз.

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

Сообщение as239 » 06 фев 2019, 14:04

Хотелось бы сделать еще 2-е интерфейсных мелочи:
1. В бою по ПКМ на отряде, в правом верхнем углу выводить порядок его хода.
2. При наведении на ученого, в строке состояния показывать что он даст - "skill, stat, cast"

Ну и ждем igrik, может он подскажет как все-таки сделать красивый обмен между героями в городе.
Вернуться к началу

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 » 06 фев 2019, 15:40

Цитата:
Так вот на ноутбуке была та же самая проблема с отображением текста что и на маке.
Эта правка все исправила.

Да, это корректный способ преобразования string в C-строку.

Цитата:
А можно прям на пальцах объяснить как искать этот изменяющийся адрес.

1-й способ: можно искать по "сигнатуре" (как предлагал Ben80). Записываете последовательность байтов, которые находятся в dll по текущему адресу, и ищете эту последовательность в новой версии;
2-й способ: поиск в IDA по строке "Для перестройки требуется".

Цитата:
Хотелось бы сделать еще 2-е интерфейсных мелочи:
1. В бою по ПКМ на отряде, в правом верхнем углу выводить порядок его хода.

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

Цитата:
2. При наведении на ученого, в строке состояния показывать что он даст - "skill, stat, cast"

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

offlineas239  
имя: Анатолий
Ветеран
Ветеран
 
Сообщения: 527
Зарегистрирован: 29 дек 2018, 14:17
Пол: Мужчина
Поблагодарили: 38 раз.

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

Сообщение as239 » 06 фев 2019, 16:06

Цитата:
Прямо так и писать, без уточнения что даст?

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

offlineas239  
имя: Анатолий
Ветеран
Ветеран
 
Сообщения: 527
Зарегистрирован: 29 дек 2018, 14:17
Пол: Мужчина
Поблагодарили: 38 раз.

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

Сообщение as239 » 06 фев 2019, 16:09

Цитата:
Взять бы из SoD_SP код очереди ходов, но отдельного плагина для очереди нет (а хотелось бы иметь), а исходники я не помню уже где видел.


Я тоже хотел оттуда вытащить, но не нашел исходники.
Ben80 давал ссылку:
https://github.com/RoseKavalier/h3_plug ... chorBugFix
Но там багофиксы и какие-то другие плагины.
Вернуться к началу

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

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

Сообщение Ben80 » 06 фев 2019, 16:12

AlexSpl писал(а):

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


Может, в VCMI видели ?
Вернуться к началу

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

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

Сообщение Ben80 » 06 фев 2019, 16:54

Так то алгоритм в ФизМиге описан:
Цитата:
Любая битва делится на раунды. В каждом раунде имеется своя последовательность ходящих существ, боевых машин и действий эффектов:
1.Тактическийрежимрасстановкивойск(толькопередпервымраундом).ЕслинавыкТактикиимеетсяуобоихсражающихсягероев,тоониподавляют друг друга в соответствии с уровнем развития.
2.Действие яда (снижает здоровье отравленных существ на 10%).
3.Центральная стрелковая башня (при осаде города).
4.Верхняя боковая башня (при осаде города).
5.Нижняя боковая башня (при осаде города).
6.Выстрел Катапульты (или 2 выстрела подряд при Экспертной Баллистике).
7.Ход всех существ по очереди в соответствии с их скоростью. У кого скорость выше - ходит первее.
7.1.Еслиудвухсуществодногоигрокаодинаковаяскорость,тораньшеходитто,котороерасположенолевеевокнегероя,т.е.вышевначальнойрасстановке(правилолевогослота).Вызванныесуществасчитаютсятак,какеслибыонинаходилисьввосьмом,девятомит.д.слотах героя, в порядке появления.
7.2.Если у двух существ разных игроков одинаковая скорость, то раньше ходит существо того игрока, который не ходил только что.
7.2.1.Если это первый ход в первом раунде, то раньше ходит существо напавшего игрока.
7.3.Существа у которых сработал Боевой дух сразу же получают право повторного хода.
8.Выстрел Баллисты (или 2 выстрела при Экспертной Артиллерии).
9.Лечение Палатки первой помощи.
10.Ход Стрелковых башен, если они Ждали в свой ход.
11.Ход Катапульты, если она Ждала в свой ход.
12.Ход Баллисты, если она Ждала в свой ход.
13.Ход Палатки первой помощи, если она Ждала в свой ход.
14.Ход всех существ, у которых сработал Боевой дух и они Ждали, в соответствии с очерёдностью срабатывания.
15.Ходсуществ,которыеЖдаливсвойход.Порядокобратныйскоростисуществ,т.е.укогоскоростьниже-ходитпервее.Действуетправилолевого слота и правило преимущества того, кто не ходил только что.
Вернуться к началу

Пред.След.

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

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

Сейчас этот форум просматривают: Yandex [bot] и гости: 10