Объявления

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

Нет.

Код: Выделить всё
int x = *(int*)(*(int*)(c->ebp + 8) + 0x10);
int y = *(int*)(*(int*)(c->ebp + 8) + 0x14);

Здесь мы получаем абсолютные координаты мышки.

Код: Выделить всё
_Dlg_* dlg = (_Dlg_*)c->ebx;
x - dlg->x, y - dlg->y

Так мы получаем относительные координаты мышки.

Т.е. условие будет: if (x - dlg->x >= ButtonLeftX && x - dlg->x <= ButtonRightX && y - dlg->y >= ButtonTopY && y - dlg->y <= ButtonBottomY), а неизвестные можно посмотреть плагином выше, либо в Paint. Просто не хочется искать кнопку. Даже в Paint проще посчитать координаты и размеры кнопки. Но и с помощью плагина выше можно посмотреть. Правда, от точности наведения курсора на границы кнопки результат будет зависеть. Но нам пока что важно? Чтобы работало. А точные числа потом подставим.
Вернуться к началу

offlineRoseKavalier  
Мастер
Мастер
 
Сообщения: 331
Зарегистрирован: 23 сен 2017, 17:00
Пол: Не указан
Поблагодарили: 234 раз.

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

Сообщение RoseKavalier » 05 авг 2021, 13:17

You could rewrite heroWindow::findWidgetPtr_5FF9A0 to ignore widget state so that it can find disabled ones, then simply compare the id if a widget is found at provided coordinates.

Код: Выделить всё
Widget *__thiscall heroWindow::findWidgetPtr_5FF9A0(HeroWindow* this, int abs_x, int abs_y)
{
  int relative_x; // edi
  Widget **last; // esi
  Widget *it; // eax
  int x; // ecx
  int y; // edx
  eWidgetState state; // cx
  Widget **first; // [esp+14h] [ebp+8h]
  int relative_y; // [esp+18h] [ebp+Ch]

  relative_x = abs_x - this->x;
  last = this->widgets.end;
  relative_y = abs_y - this->y;
  first = this->widgets.begin;
  if ( last == first )
    return 0;
  while ( 1 )
  {
    it = *(last - 1);
    x = it->x;
    if ( relative_x >= x )
    {
      y = it->y;
      if ( relative_y >= y && relative_x < x + it->width && relative_y < y + it->height )
      {
        state = it->state;
        if ( (state & ACTIVE) != 0 && (state & SHADED) == 0 && (state & UNKNOWN_1000) == 0 )
          break;
      }
    }
    if ( --last == first )
      return 0;
  }
  return it;
}
Вернуться к началу

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 » 05 авг 2021, 13:18

It's elegant, universal, but too complex :smile2:

(а ещё попробуй это через homm3.h написать, код вырастет раз в 10) :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 » 05 авг 2021, 19:08

Вот такое решение получается:

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

Patcher* _P;
PatcherInstance* _PI;

int __stdcall showUpgradeCost(LoHook* h, HookContext* c)
{
    int x = *(int*)(*(int*)(c->ebp + 8) + 0x10);
    int y = *(int*)(*(int*)(c->ebp + 8) + 0x14);

    _Dlg_* dlg = (_Dlg_*)c->ebx;
    _DlgItem_* button = dlg->GetItem(0x12C);
   
    if (x - dlg->x >= button->x && x - dlg->x <= button->x + button->width &&
        y - dlg->y >= button->y && y - dlg->y <= button->y + button->height)
    {
      char* str = *(char**)(0xD * 8 + 0x6A74C0); // Оригинальное сообщение

      sprintf(o_TextBuffer, "%s %s", str, "test");
      c->edi = (int)o_TextBuffer;
    }
   
    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((char*)"HD.Plugin.UpgradeInfo");

            _PI->WriteLoHook(0x5F5336, showUpgradeCost);
        }
    }

    return TRUE;
}

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

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 » 05 авг 2021, 20:03

Вот так всё красиво :smile11:

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

Patcher* _P;
PatcherInstance* _PI;

int __stdcall showUpgradeCost(LoHook* h, HookContext* c)
{
    _Dlg_* dlg = (_Dlg_*)c->ebx;
    _DlgItem_* button = dlg->GetItem(0x12C);

    int x, y;
    CALL_2(void, __stdcall, 0x50D700, &x, &y);
    if (x - dlg->x >= button->x && x - dlg->x <= button->x + button->width &&
        y - dlg->y >= button->y && y - dlg->y <= button->y + button->height)
    {
      char* str = *(char**)(0xD * 8 + 0x6A74C0); // Оригинальное сообщение

      sprintf(o_TextBuffer, "%s %s", str, "test");
      c->edi = (int)o_TextBuffer;
    }
   
    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((char*)"HD.Plugin.UpgradeInfo");

            _PI->WriteLoHook(0x5F5336, showUpgradeCost);
            _PI->WriteCodePatch(0x5F5201, "%n", 6);
        }
    }

    return TRUE;
}

Рано обрадовался. Краш диалога существ при отсутствии кнопки. А почему? А потому, что её нет :smile1:

С проверкой на button:
Код: Выделить всё
if (button)
{
    int x, y;
    CALL_2(void, __stdcall, 0x50D700, &x, &y);
    if (x - dlg->x >= button->x && x - dlg->x <= button->x + button->width &&
        y - dlg->y >= button->y && y - dlg->y <= button->y + button->height)
    {
      char* str = *(char**)(0xD * 8 + 0x6A74C0); // Оригинальное сообщение

      sprintf(o_TextBuffer, "%s %s", str, "test");
      c->edi = (int)o_TextBuffer;
    }
}
Последний раз редактировалось AlexSpl 05 авг 2021, 20:16, всего редактировалось 2 раз(а).
Вернуться к началу

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

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

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

Нашел кнопку, ее размеры и координаты. Кнопка находится в h3sprite.lod под именем iViewCr.def. Состоит из 4 bmp: ivc001d.bmp, ivc001h.bmp, ivc001n.bmp, ivc001s.bmp.

Изображение
Изображение
Изображение
Изображение

Размеры кнопки: 46 (ширина) x 32 (высота).

Но это без рамки. Каждая кнопка в игре обрамляется 1 пиксельной рамкой. Сама рамка в кнопку не входит. Если брать с рамкой, то это 48 x 34.

Изображение

Координаты кнопки:

По рамке:
X: 193
Y: 256
---
X: 240
Y: 289

По кнопке:
X: 194
Y: 257
---
X: 239
Y: 288
Последний раз редактировалось Rolex 05 авг 2021, 23:28, всего редактировалось 4 раз(а).
Вернуться к началу

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 » 05 авг 2021, 20:15

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

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

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

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

А что делает вот этот патч?
Код: Выделить всё
_PI->WriteCodePatch(0x5F5201, "%n", 6);
Вернуться к началу

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 » 05 авг 2021, 20:21

Позволяет выполняться хуку для неактивной кнопки. Это просто 6 нопов.
Вернуться к началу

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

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

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

В общем проверил ваш код. Все работает. Правда сравнивал по точности с кнопкой увольнения. Немного справа и снизу по рамке уже отображает. Точность может где-то 1-2 пикселя хромает, а так ок.

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

Пред.След.

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

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

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

cron