Объявления

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

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

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

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

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

Вы прям головоломками говорите. А как же тогда получить оригинальное сообщение. Значит если в esi ID элемента, то оригинальная строка где-то в другом месте? Получается esi мы не можем использовать, будем получать вылет.
Вернуться к началу

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 » 04 авг 2021, 14:33

Во-первых, никто не отменял NO_EXEC_DEFAULT. Во-вторых, нужно понимать, что значит запись mov reg, [value].

mov reg, [value] <=> c->reg = *(type*)value;

mov esi, dword_006A74C4[esi*8] <=> mov esi, [esi*8+6A74C4h] <=> c->esi = *(type*)(c->esi * 8 + 0x6A74C4);

Теперь должно быть понятнее, что происходит. А так как речь о строке, type - это char*. Пробуйте экспериментировать.
Вернуться к началу

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

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

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

Вот так сделал:
Код: Выделить всё
string str = (char*)(c->esi * 8 + 0x6A74C4);

Плюс вернул NO_EXEC_DEFAULT. Сумма грейда в золоте выводится, но при этом портится оригинальное сообщение и заменяется различными символами. Также если нажать по соседней кнопке удаления отряда ПКМ, то получаю вылет.
Вернуться к началу

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 » 04 авг 2021, 14:55

Пробуйте *(char**)(c->esi * 8 + 0x6A74C4); А NO_EXEC_DEFAULT используется с адресом возврата. Т.к. мы пропускаем только первую команду, то адресом возврата будет адрес следующей (той, на которую Вы ставили хук в самом начале).

Вылет при клике по кнопке удаления потому, что NO_EXEC_DEFAULT должен быть только при выполнении условия. А после условия напишите EXEC_DEFAULT.
Вернуться к началу

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

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

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

Есть, работает. :smile1:

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

using namespace std;

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


int __stdcall showGuardsRMB(LoHook* h, HookContext* c)
{
   if (c->esi == 0xD)
   {
      string str = *(char**)(c->esi * 8 + 0x6A74C4); // Оригинальное сообщение

      int id = *(int*)(c->ebx + 0x60);
      int number = *(int*)(c->ebx + 0x64);
      
      str = str + "\n" + to_string( ( o_CreatureInfo[id + 1].cost.gold - o_CreatureInfo[id].cost.gold ) * number );

      // Передаём адрес текстового буфера в качестве аргумента для диалога
      sprintf(o_TextBuffer, "%s", str.c_str());
      c->esi = (int)o_TextBuffer;

      c->return_address == 0x5F4CA0;
      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.UpgradeCost");

         // Сообщения по правому клику
         _PI->WriteLoHook(0x5F4C99, showGuardsRMB);
      }
   }

   return TRUE;
}


А как теперь узнать, требует ли улучшенное существо драгоценных ресурсов к золоту для грейда, чтобы не перечислять всех существ 7-го уровня через ифы? Или просто на уровень проверить?

Требования по золоту считаю так:
Код: Выделить всё
( o_CreatureInfo[id + 1].cost.gold - o_CreatureInfo[id].cost.gold ) * number

Хотя, наверное, id + 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 » 04 авг 2021, 15:20

Цитата:
Хотя, наверное, id + 1 для грейда не лучший варинт. Может быть можно иначе, там через функцию, но я не знаю как.

Да, не лучший. Например, есть Conflux :smile2: Функцию получения грейда можете посмотреть в недавних плагинах.

Цитата:
А как теперь узнать, требует ли улучшенное существо драгоценных ресурсов к золоту для грейда, чтобы не перечислять всех существ 7-го уровня через ифы? Или просто на уровень проверить?

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

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

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

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

AlexSpl писал(а):

Да, не лучший. Например, есть Conflux :smile2: Функцию получения грейда можете посмотреть в недавних плагинах.

Вроде, сделал:
Код: Выделить всё
( o_CreatureInfo[CALL_1(int, __fastcall, 0x47AAD0, id)].cost.gold - o_CreatureInfo[id].cost.gold ) * number


AlexSpl писал(а):

Никак по-другому. Нужно отнимать каждый ресурс и не выводить нулевую разность.

А как через o_CreatureInfo по id получить уровень существа?
Вернуться к началу

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

Цитата:
А как через o_CreatureInfo по id получить уровень существа?

Есть поле level. Остальные смотрите в структуре _CreatureInfo_.
Вернуться к началу

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

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

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

Может и не понадобится. Буду отнимать каждый ресурс и не выводить нулевую разность.

Такой вопрос. В нашей строке, которую мы дописываем к оригинальному сообщению можно прописывать Золото: столько-то; Кристаллов: столько-то. И вот под англ и рус язык нужно прописывать отдельно и проверять еще ресурсы на язык. Но можно сделать проще. В игре эти названия ресурсов уже есть и подтягиваються в игру из текстовика на нужном языке в зависмоти от языка текстовиков. Так вот вопрос: как получить вот эти общие названия ресурсов. Чтобы если плагин подключен под англ версию игры выводилось Gold:, а если под русскую Золото: ?

PS: Просто, например, в структуре _CreatureInfo_ есть _char_* name_single и _char_* name_plural, а в структуре _Resources_ только _int_, то есть кол-во (значения) ресурсов. Названий нет. Можно ли их все же как-то получить или нужно будет в любом случае тянуть их из RESTYPES.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 » 04 авг 2021, 18:22

Это уже обсуждалось в теме не один раз, только, конечно, не для ресурса RESTYPES.TXT :smile1: Определяем указатель по типу

Код: Выделить всё
#define o_GENRLTXT_TXT (*(_TXT_**)0x6A5DC4)
#define o_PLCOLORS_TXT (*(_TXT_**)0x6A7584)
#define o_TCOMMAND_TXT (*(_TXT_**)0x6A62F8)
// ..............

и получаем строчку через GetString() (например, o_GENRLTXT_TXT->GetString(45)). Вот уже если это не работает, получаем строку по указателю. Тоже были примеры в теме:

Код: Выделить всё
*(MonBattleDesc*)(0x6703CC + 116 * CID_PIKEMAN) = monBattleDesc[CID_PIKEMAN];
*(MonBattleDesc*)(0x6703CC + 116 * CID_MARKSMAN) = monBattleDesc[CID_MARKSMAN];
*(MonBattleDesc*)(0x6703CC + 116 * CID_FIRST_AID_TENT) = monBattleDesc[CID_FIRST_AID_TENT];

Но так для смешанных текстовиков со столбцами обычно. Если текстовик - набор строк, то, скорее всего, будет работать GetString().
Вернуться к началу

Пред.След.

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

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

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