Объявления

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

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

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

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

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

RoseKavalier писал(а):

Код: Выделить всё
struct RMG_Object
{
   // * +0
   h3func *vTable;
   // * +4
   RMG_ObjectPropsRef *properties;
   // * +8
   INT32 x;
   // * +C
   INT32 y;
   // * +10
   INT32 z;
   UINT8 _f_14[8];
};



А можно спросить, зачем каждому объекту аж целая отдельная функция h3func *vTable ?
И нельзя ли привести какие-то интересные декомпилированные фрагменты кода, отвечающие за наполнение зон объектами ?
И как примерно происходит внедрение шахт (mines) в зону ?

Ed.
Играет какую-то роль ли в наполнении зон объектами эта функция, h3func ?
Вернуться к началу

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

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

Сообщение RoseKavalier » 06 апр 2019, 16:12

@as239
or simply WriteByte(..., 0xEB) ; WriteWord(..., 0x9090)
Out of the two, I would try 0xEB patch, 0x9090 left more holes in the single seed I examined.

@Ben80
Virtual table is only different for some objects, in most cases they will all have the same virtual table and therefore same functions.

RMG_Object is the base case and looks like the structure you've written, but for example Monster and Towns inherit its properties and have some additional fields for data afterwards.
Код: Выделить всё
struct RMG_ObjectTown : public RMG_Object
{
   // * +1C
   INT32 indexOnMap;
   // * +20
   INT32 owner;
   // * +24
   BOOL8 hasFort;
   UINT8 _f_25[3];
};


Expanded, it reads like this:
Код: Выделить всё
struct RMG_ObjectTown
{
        struct RMG_Object
        {
           // * +0
           h3func *vTable;
           // * +4
           RMG_ObjectPropsRef *properties;
           // * +8
           INT32 x;
           // * +C
           INT32 y;
           // * +10
           INT32 z;
           UINT8 _f_14[8];
        }base;
   // * +1C
   INT32 indexOnMap;
   // * +20
   INT32 owner;
   // * +24
   BOOL8 hasFort;
   UINT8 _f_25[3];
};


For these special inheritance cases, a new virtual table exists as it could:
1) have different constructor / destructor or any other personal function that is normally used
2) more virtual functions

For example, HiHook is a public Patch and has the same base virtual functions, but it also has extra virtual functions. So the value of its vTable would be different even if the first 5 virtual functions are the same.
However LoHook is 100% a public Patch and should have the exact same vTable.

If you want to inspect which functions are responsible for doing what, I recommend skipping some function calls from RMG_ChooseTemplateAndGenerate_00549E20 to see their effects.
Also, fixed seed really helps!
e.g.
RMG_ToPlaceTowns_00544F40
RMG_ToPlaceMines_00546450
RMG_GenerateObjects_00547850
RMG_SetShoreMapItems_005317E0
RMG_PlaceObstacles_00537E60
RMG_PlaceRoads_00548780
RMG_WatermillRiver_00549D60

EDIT:
Another interesting one.
RMG_ClearSomePaths_00540AC0
Cancelled call at 0x54A100 vs allowed:
 
Изображение
Вернуться к началу

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

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

Сообщение Ben80 » 06 апр 2019, 17:22

RoseKavalier писал(а):

Also, fixed seed really helps!


Не могу не согласиться. (интересно, переводчик правильно переведет ? :smile1: )
Вот еще интересное - сможешь ли понять значение фразы "да нет, наверно" )))

Я сегодня наконец-то нашел время записать RMG структуры в SDK Бараторча (интересно было бы увидеть SDK RoseKavalier). Очень рад, что сделал это, не так уж много времени потратил, зато теперь не буду каждый раз мучиться с указателями и указателями на указатели и массивами, содержащими указатели на указатели. Это реально утомляет.

p.s. Обратил внимание на &RmgStructure + 52:
_List_ <_RMGObjectPrototypeRef_*> ObjectPrototypesByType[232];

Здесь именно _RMGObjectPrototypeRef_, а не _RMGObjectPrototype_

Правда, пока не знаю, где этот массив векторов можно использовать с пользой.

Также обратил внимание на большое расхождение в количестве объектов, полученном через разные методы/поля структур.
Вернуться к началу

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

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

Сообщение Ben80 » 06 апр 2019, 17:57

RoseKavalier писал(а):

EDIT:
Another interesting one.
RMG_ClearSomePaths_00540AC0


Possibly, this function makes unwanted additional paths between zones, trying to open mines.
Вернуться к началу

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

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

Сообщение Ben80 » 06 апр 2019, 18:44

RoseKavalier писал(а):

RMG_Object is the base case and looks like the structure you've written, but for example Monster and Towns inherit its properties and have some additional fields for data afterwards.
...
For example, HiHook is a public Patch and has the same base virtual functions, but it also has extra virtual functions. So the value of its vTable would be different even if the first 5 virtual functions are the same.


It seems it is one of very few examples of object-oriented programming using in Heroes 3. Actually I wonder. I just never thought about it before, that Heroes 3 code should use object-oriented programming more or less extensively (more extensively than we actually see).
Вернуться к началу

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 » 06 апр 2019, 20:55

Почему один из немногих примеров ООП? Классы были в Героях, начиная с первой части. И почти все основные структуры игры - это классы.
Вернуться к началу

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

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

Сообщение RoseKavalier » 06 апр 2019, 23:08

Alex is correct, OOP is all over the place.
Every function using __thiscall makes reference to a member function which is a sign of object.

Binary items (defined as such in WoG source, Def, pcx, wav, ...) all have virtual tables and behave the same way.
Also all managers ("GameMgr 0x695338" is not actually a manager, just an agglomerate of global variables) have virtual tables and all use the same base constructor before branching off.

да нет, наверно is translated to "yes, no, probably" ?

Цитата:
ps Drew attention to & RmgStructure + 52:
_List_ <_RMGObjectPrototypeRef _ *> ObjectPrototypesByType [232];

Here it is _RMGObjectPrototypeRef_, not _RMGObjectPrototype_

I will have to check, don't remember.
There is not much use for this data by itself in any case, it is a data copy of objects.txt in memory, the same as in _GameMap_. It could be useful if you need data about a given object on map but other than that I would use
Код: Выделить всё
// * +EC4
H3Vector<RMG_Object*> positions;

or if you know coordinates (x,y,z) then list of items at that tile is easily recoverable from RMG_MapItem.

There is still a lot of work to be done on my "H3 SDK" but it has all I need for SoD_SP and other mods... it should be available in not too long I hope.
Afterwards I plan on keeping it updated as new findings are done and as time is found to write in existing knowledge from IDA and such.
Вернуться к началу

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

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

Сообщение Ben80 » 09 апр 2019, 15:57

I have created hook at 0x5866F7 to make small cycle (3 map regenerations) with
Код: Выделить всё
c->return_address = 0x5866DE;

Several maps were created succesfully, however main game takes first generation, not last.

How it can be improved ? I suspect, there copying from Rmg_structure to Main_structure and further there is check filled Main_structure or not. And so - next generations are ignored.

Additional info - next generations do not overwrite existing random_map_1.h3m as it occurs for first generation. One can get next gen. maps only by explicit naming of maps.

ED.

Without explicit maps naming hook is following:
Код: Выделить всё
int __stdcall regenerateMapCycle(LoHook* h, HookContext* c)
{
   if(NRegen > 0)
   {
      char *mapName;
      _HStringF_* strF = new _HStringF_();
      CALL_1(_HStringF_*, __thiscall, 0x587C70, strF);
      mapName = strF->h_str.c_str;

      NRegen--;
      c->eax = (int)mapName;
      c->return_address = 0x5866DE;
      return NO_EXEC_DEFAULT;
   }
   else
      NRegen = 3;

   return EXEC_DEFAULT;
}
...
_PI->WriteLoHook(0x5866F7, regenerateMapCycle);
Вернуться к началу

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

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

Сообщение RoseKavalier » 09 апр 2019, 17:17

Why not simply call GenerateRandomMap_0054C580 3 times? You can give char* name directly I think and don't have to worry about deleting HStringF.
Вернуться к началу

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

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

Сообщение Ben80 » 09 апр 2019, 17:54

Probably because of I have expected problems and really I have got it. In both cases I can give char* name directly or use function 0x587C70 for naming.

I have got HD mod crash
Код: Выделить всё
   int params;
   char *mapName;
        int progress;

   params = *(int*)(c->ebp - 0xAC);
   mapName = "random_maps\\random_map_2.h3m";
   progress = *(int*)(c->ebp - 0x5C);
   NRegen--;
   //CALL_3(signed int, __thiscall, 0x54C580, params, mapName, progress);
   CALL_3(signed int, __thiscall, 0x54C580, progress, mapName, params);


Код: Выделить всё
Exception

{

   Module:    Heroes3 HD.exe

   Adress:      0x00536619

   Code:        EXCEPTION_ACCESS_VIOLATION

   Flags:       0x00000000

   Information: read of address: 0x00000005

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

Пред.След.

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

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

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