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


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

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

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

Re: Пользовательские плагины для HD мода

Сообщение as239 » 27 мар 2019, 06:12

@igrik
Не могу скомпилировать ваш код - у меня нет этих атрибутов advMng:
advMng->monBattle_type
advMng->monBattle_num
advMng->monBattle_side
Смещение там написано, но я не знаю как его правильно применить.
Вернуться к началу

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

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

Сообщение as239 » 27 мар 2019, 06:15

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

offlineigrik  
Подмастерье
Подмастерье
 
Сообщения: 108
Зарегистрирован: 14 сен 2017, 12:35
Пол: Не указан
Поблагодарили: 84 раз.

Re: Пользовательские плагины для HD мода

Сообщение igrik » 27 мар 2019, 09:41

Укажи в заголовочнике homm3.h в описании класса _AdvMgr_ что это структура. Вот так:
Код: Выделить всё
struct _AdvMgr_: _Struct_


А потом используй метод Offset();
Код: Выделить всё
o_AdvMgr->Offset(536); // advMng->monBattle_type
Вернуться к началу

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

Re: Пользовательские плагины для HD мода

Сообщение as239 » 27 мар 2019, 10:07

Теперь пишет:
error C2106: '=' : left operand must be l-value

Код: Выделить всё
     _MapItem_* obj_54 = advMng->map->GetItem(b_unpack_x(xyz_54), b_unpack_y(xyz_54), b_unpack_z(xyz_54));
      o_AdvMgr->Offset(536) = (_word_)obj_54->os_type; // (advMng+<536>)
      o_AdvMgr->Offset(540) = (_word_)obj_54->draw_num; // (advMng+<540>)
      o_AdvMgr->Offset(544) = hero->x < (_word_)((_word_)(xyz_54 << 6) >> 6) ? 1 : 0; // поворот монстра при атаке (advMng+<544>)


И правильно ли я заменил код, с учетом правок RoseKavalier :

Код: Выделить всё
   //int xyz_54 = isGuardNearTheObject(advMng, xyz); // проверка клеток по кругу рядом с артефактом
   int xyz_54 = IsGuarded(b_unpack_x(xyz), b_unpack_y(xyz), b_unpack_z(xyz));
Вернуться к началу

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

Re: Пользовательские плагины для HD мода

Сообщение RoseKavalier » 27 мар 2019, 12:54

Offset() returns the address of a structure offset - not a pointer to this address and not the value at this address.
To change the memory at that point you have to use *(int*) or whatever data type you are looking to use.

Longest but easiest in long run is to fill in the structures to never have to use Offset() !
Вернуться к началу

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

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

Сообщение RoseKavalier » 27 мар 2019, 12:58

Indeed, swapping object locations on the map is not a great solution and is very limiting.
I will try to get you some sample code for passability.


Some background info...
 object passability bitmasks
Here is how all object bitfields work.
It starts top left.
Each byte represents one line, from left to right.
The next line is shown in the next byte, again starting left and heading right.
Изображение

Due to structure alignment, there are 2 extra padded bytes which are unused.
So in total you have 48 valid bits, numbered 0 ~ 47.
Изображение

When an object looks like this:
Изображение
Only bit 47 is used, which is 6th byte set as 0x80
Passability bitmask:
00 00 00 00 00 80 00 00

However, when your object looks like this:
Изображение

There are now 2 things involved.
First, bits 46 and 47 are used, which means 6th byte 0x40 + 0x80 = 0xC0
Passability bitmask:
00 00 00 00 00 C0 00 00

However, since there is an entrance shown here, there is also the entrance bitmask in use.
The only tile with an entrance is 47, which means 6th byte at 0x80
Entrability bitmask:
00 00 00 00 00 80 00 00

When an object gives you (x, y) position, this is actually the position of the bottom right of this rectangle.
So bit 47 is at offset (0, 0) from (x,y).
bit 46 is at offset (-1, 0) from (x,y).
bit 38 is at offset (-1, -1) from (x,y).


Getting bit values:
From _Template_ structure *temp,
Код: Выделить всё
_bool8_ On = temp->ImpassBitMask.GetBit(47);
Вернуться к началу

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

Re: Пользовательские плагины для HD мода

Сообщение as239 » 27 мар 2019, 13:18

Исправил:
Код: Выделить всё
      int xyz_54 = IsGuarded(b_unpack_x(xyz), b_unpack_y(xyz), b_unpack_z(xyz));
   if ( xyz_54 ) {
      _MapItem_* obj_54 = advMng->map->GetItem(b_unpack_x(xyz_54), b_unpack_y(xyz_54), b_unpack_z(xyz_54));
      *(_word_*)advMng->Offset(536) = (_word_)obj_54->os_type; // (advMng+<536>)
      *(_word_*)advMng->Offset(540) = (_word_)obj_54->draw_num; // (advMng+<540>)
       *(int*)advMng->Offset(544) = hero->x < (_word_)((_word_)(xyz_54 << 6) >> 6) ? 1 : 0; // поворот монстра при атаке (advMng+<544>)


     //Offset
      CALL_5(void, __thiscall, 0x4A73B0, advMng, obj_54, hero, xyz_54, isNotAI); // нападаем на монстра рядом с артом
       *(int*)advMng->Offset(536) = -1; // после битвы возвращаем параметры
       *(int*)advMng->Offset(540) = -1;  // после битвы возвращаем параметры
      if (hero->owner_id < 0) { // если герой убит или сбежал (т.е. номер хозяина героя стал == -1)
         return 0; // выйти из функции минуя функцию посещения артефакта
      }
   }


Теперь компилирует, но при взятии охраняемого объекта, пишет что существа хотят присоединиться, причем не те что охраняют и герой вообще без дипломатии.
Я так понимаю проблема здесь, как правильно вызывать эту функцию?
Код: Выделить всё
   int xyz_54 = IsGuarded(b_unpack_x(xyz), b_unpack_y(xyz), b_unpack_z(xyz));
Вернуться к началу

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

Re: Пользовательские плагины для HD мода

Сообщение Ben80 » 27 мар 2019, 13:55

Ребят, может не надо все-таки засорять эту тему ? Cогласно теме здесь выкладываются готовые протестированные плагины. Затрудняете поиск тем людям, кто заходит в эту тему, чтобы просто что-то скачать.
Есть же соседняя тема.
Вернуться к началу

offlineigrik  
Подмастерье
Подмастерье
 
Сообщения: 108
Зарегистрирован: 14 сен 2017, 12:35
Пол: Не указан
Поблагодарили: 84 раз.

Re: Пользовательские плагины для HD мода

Сообщение igrik » 27 мар 2019, 14:01

Для этого я и дал смещение, чтобы зная его можно было подправить заголовочник. RoseKavalier верно говорит.
Код: Выделить всё
NOALIGN struct _AdvMgr_ : _Struct_
{
 _byte_ field_0[68]; //+0
 _Dlg_* dlg; //+68
 _byte_ field_48[20]; //+72
 _GameMap_* map; //+92
 _byte_ field_60[136]; //+96
 _dword_ pack_xyz;     //+232
 _byte_ field_EC[300]; //+236
 _int32_ monBattle_num;  //+536
 _int32_ monBattle_type;   //+540
 _dword_ monBattle_side;   //+544
 _byte_ field_220[36]; //+548
 // Фоновые звуки (ссылка на звук или 0, если не проигрывается).
// и т.д.


as239 писал(а):

Теперь компилирует, но при взятии охраняемого объекта, пишет что существа хотят присоединиться, причем не те что охраняют и герой вообще без дипломатии.
Я так понимаю проблема здесь, как правильно вызывать эту функцию?
Код: Выделить всё
   int xyz_54 = IsGuarded(b_unpack_x(xyz), b_unpack_y(xyz), b_unpack_z(xyz));

Тут я хз...

upd: вообще, как я понимаю, это не ветка для обсуждений. Думаю, модерам необходимо перенести последние сообщения в тему "Как создать плагин для HD мода"
Вернуться к началу

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

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

Сообщение as239 » 27 мар 2019, 14:38

Вопрос к igrik по плагину "защита объектов".
На какие адреса нужно еще поставить хуки для защиты ресурсов, сундуков, костра и ученого?

@RoseKavalier
What is the correct call for that function:
Код: Выделить всё
#define IsGuarded(x,y,z) (0x0100 & CALL_3(WORD, __fastcall, 0x4F8040, x, y, z))


In the code:
Код: Выделить всё
_byte_ __stdcall Y_HeroGetObjWithGuard(HiHook* hook, _AdvMgr_* advMng, _Hero_* hero, _MapItem_* obj, _int_ xyz, _byte_ isNotAI)
{
   int xyz_54 = isGuardNearTheObject(advMng, xyz); // проверка клеток по кругу рядом с артефактом
//   int xyz_54 = IsGuarded(b_unpack_x(xyz), b_unpack_y(xyz), b_unpack_z(xyz));
   if ( xyz_54 ) {
      _MapItem_* obj_54 = advMng->map->GetItem(b_unpack_x(xyz_54), b_unpack_y(xyz_54), b_unpack_z(xyz_54));
      *(_word_*)advMng->Offset(536) = (_word_)obj_54->os_type; // (advMng+<536>)
      *(_word_*)advMng->Offset(540) = (_word_)obj_54->draw_num; // (advMng+<540>)
       *(int*)advMng->Offset(544) = hero->x < (_word_)((_word_)(xyz_54 << 6) >> 6) ? 1 : 0; // поворот монстра при атаке (advMng+<544>)


     //Offset
      CALL_5(void, __thiscall, 0x4A73B0, advMng, obj_54, hero, xyz_54, isNotAI); // нападаем на монстра рядом с артом
       *(int*)advMng->Offset(536) = -1; // после битвы возвращаем параметры
       *(int*)advMng->Offset(540) = -1;  // после битвы возвращаем параметры
      if (hero->owner_id < 0) { // если герой убит или сбежал (т.е. номер хозяина героя стал == -1)
         return 0; // выйти из функции минуя функцию посещения артефакта
      }
   }
   // всё норм (монстры повержены или присоединились) - подбираем артефакт
   return CALL_5(_byte_, __thiscall, hook->GetDefaultFunc(), advMng, hero, obj, xyz, isNotAI);
}
Вернуться к началу

Пред.След.

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

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

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

cron