Объявления

Форум о Героях Меча и Магии и King's Bounty. Если Вы любите эти игры, мы будем рады видеть Вас в наших рядах. :smile2:

RMG SOD

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

Re: RMG SOD

Сообщение as239 » 06 авг 2019, 06:29

Цитата:
I'm afraid I'm a bit too busy to look into RMG properly at the moment

Bad news for me, I'm stuck on getting a list of towns.
Вернуться к началу

offlineas239  
Мастер
Мастер
 
Сообщения: 323
Зарегистрирован: 29 дек 2018, 14:17
Пол: Не указан
Поблагодарили: 13 раз.

Re: RMG SOD

Сообщение as239 » 10 авг 2019, 09:00

Невозможность получения списка городов, обошел изменением алгоритма.
Теперь мучусь с ГО, как получить список координат охран проходов?
Создаются они здесь - RMG_MonsterGenerationZoneBlocks_00541630:
Код: Выделить всё
        v47 = v57;
        v45 = (_DWORD *)sub_00537DD0((int)&v6->MapItemsVMT, v34, v57, v58);
        v46 = v45[1];
        if ( !v46 || (signed int)((v45[2] - v46) & 0xFFFFFFFC) <= 0 )
        {
          v48 = RMG_00541010_MonsterGeneration(v6, a5, (int)v6->GenZones[v45[8] << 8 >> 24]);
          if ( v48 )
            (*(void (__thiscall **)(_RMGStruct_ *, _RMGObjMonster_ *, int, int, int))(v6->VMT + 4))(
              v6,
              v48,
              v34,
              v47,
              v58);
        }

Но проблема в том, что здесь v48 это созданный монстр, но у него пустые координаты x,y:
Код: Выделить всё
v48 = RMG_00541010_MonsterGeneration(v6, a5, (int)v6->GenZones[v45[8] << 8 >> 24]);


Ставил точку останову на изменение v48->x, попадаю сюда:
sub_00533700
Здесь есть координаты, но сюда попадают все монстры, а мне нужно только ГО.
Вернуться к началу

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

Re: RMG SOD

Сообщение RoseKavalier » 10 авг 2019, 13:04

As far as I could tell and remember, there is no distinction between generated monsters.
What you could do is hook RMG_MonsterGenerationZoneBlocks_00541630, and add the result to a global vector. Then at a later point you inspect the contents of the vector (remember to empty it afterwards).

In fact, same thing can be done for towns, look into RMG_PlaceTown_00545740.
Вернуться к началу

offlineas239  
Мастер
Мастер
 
Сообщения: 323
Зарегистрирован: 29 дек 2018, 14:17
Пол: Не указан
Поблагодарили: 13 раз.

Re: RMG SOD

Сообщение as239 » 11 авг 2019, 05:46

Thanks, it works:
Код: Выделить всё
vector<RMG_ObjectMonster*> GO;
_LHF_(GetMonsterBlock){
   RMG_ObjectMonster* Monster = (RMG_ObjectMonster*)c->eax;
   if (Monster)
   {
      GO.push_back(Monster);
   }
   
   return EXEC_DEFAULT;
}

   _PI->WriteLoHook(0x541BBE, GetMonsterBlock);
   _PI->WriteLoHook(0x541C1F, GetMonsterBlock);

But how to delete monster from the tile, it doesn't work:
Код: Выделить всё
   RMG_MapItem *xyz = rmg->map.GetMapItem(133, 100, 0);
   xyz->objects.RemoveAll();


And cann't find where is the town at RMG_ToPlaceTowns_00544F40.
Вернуться к началу

offlineas239  
Мастер
Мастер
 
Сообщения: 323
Зарегистрирован: 29 дек 2018, 14:17
Пол: Не указан
Поблагодарили: 13 раз.

Re: RMG SOD

Сообщение as239 » 12 авг 2019, 08:34

Если изменить координаты монстра за границы карты, то он естественно исчезает.
Например ставим x=200 и y=200.
Игра при этом запускается и все работает.
Могут ли быть побочные последствия у такого способа удаления монстров?
Вернуться к началу

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

Re: RMG SOD

Сообщение RoseKavalier » 13 авг 2019, 02:36

When the game loads adventure map objects from the h3m format, basic checks are performed for every single one of them, including whether they have at least 1 tile of presence on the map; if not, they're thrown out.

It's not only safe but also probably the easiest way to 'remove' these :smile20:

The RMG_MapItem::object vector doesn't "contain" objects itself, it's just a list of objects that show up here.
Вернуться к началу

offlineas239  
Мастер
Мастер
 
Сообщения: 323
Зарегистрирован: 29 дек 2018, 14:17
Пол: Не указан
Поблагодарили: 13 раз.

Re: RMG SOD

Сообщение as239 » 16 авг 2019, 19:06

Кто нибудь понимает как работает "RMGMapItems_00531D80_CantPlace"?
Я использую ее чтобы отодвинуть шахты и города от границы зон, это прекрасно работает и позволяет избежать проходов на смежные зоны.
Однако, иногда появляется абсолютно необъяснимый побочный эффект - на некоторых генерациях, центр становится более разряженным по объектам.
Вот пример:
Без HiHook на RMGMapItems_00531D80_CantPlace:
 
Изображение

С HiHook на RMGMapItems_00531D80_CantPlace:
 
Изображение


Вот код:
Код: Выделить всё
bool CantPlace(RMG_MapItem *xyz, int addX, int addY){
   if (addX >= MapSize || addY >= MapSize || addX < 0 || addY < 0) return false;
   RMG_MapItem *addxyz = rmg->map.GetMapItem(addX, addY, 0);
   if (addxyz->zone.zone1 != xyz->zone.zone1)
   {
      return true;
   }
   return false;
}

char __stdcall RMGMapItems_00531D80_CantPlace(HiHook* hook, int this1, RMG_ObjectPropsRef *a2, int x, int y, int z, int a6, char a7)
{
   char ret = THISCALL_7(char, hook->GetDefaultFunc(), this1, a2, x, y, z, a6, a7);
   if (ret == 1 || !ItsJC || MapSize == 0 || x >= MapSize || y >= MapSize || x < 0 || y < 0) return ret;
   bool ItsTown = (a2->prototype->type == 98);
   bool ItsMine = (a2->prototype->type == 53);

   RMG_MapItem *xyz = rmg->map.GetMapItem(x, y, 0);

   if (ItsTown) //&& xyz->GetLand() != 1
   {
      if (CantPlace(xyz,x, y + 4)) return 1;
      if (CantPlace(xyz,x + 6, y + 1)) return 1;
      if (CantPlace(xyz,x - 6, y + 1)) return 1;
   }
   else if (ItsMine)
   {
      if (CantPlace(xyz,x, y + 4)) return 1;
      if (CantPlace(xyz,x + 4, y)) return 1;
   }

   return ret;
}

Я так понимаю что RMGMapItems_00531D80_CantPlace, для каждого объекта строит маску размещения по всем клеткам карты.
Но как, код выше может влиять на размещение объектов в центре, вдалеке от смежных зон?
Вернуться к началу

offlineas239  
Мастер
Мастер
 
Сообщения: 323
Зарегистрирован: 29 дек 2018, 14:17
Пол: Не указан
Поблагодарили: 13 раз.

Re: RMG SOD

Сообщение as239 » 02 ноя 2019, 09:34

Поменял местами генерацию дорог и объектов.
И теперь при генерации объекта я всегда могу знать есть ли рядом дорога.
Т.о. появляется возможность красиво решить проблему блоков вдоль дорог.
Надо всего лишь найти функцию которая размещает объект на карту и в ней проверять есть ли рядом дорога и если есть то не размещать там объект.
Судя по всему эта функция "RMGMapItems_00531D80_CantPlace".
Использую ее и получаю нужный результат - блоков вдоль дорог нет! Однако, вылезает та же самая проблема, что постом выше - плотность объектов в центральной зоне значительно уменьшается.
Вот по сути весь код в HiHook на RMGMapItems_00531D80_CantPlace:
Код: Выделить всё
   for (int ix = -1; ix <= 1; ix++)
   {
      for (int iy = -1; iy <= 1; iy++)
      {
         int addx = x + ix;
         int addy = y + iy;

         if (MapSize == 0 || addx >= MapSize || addy >= MapSize || addx < 0 || addy < 0)  continue;
         RMG_MapItem *xyz = rmg->map.GetMapItem(addx, addy, z);
         if (xyz->GetRoad() != 0) {
            return 1;
         }
      }
   }


 
Вот центр без этого кода:
Изображение

А вот с ним:
Изображение


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

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

Re: RMG SOD

Сообщение RoseKavalier » 02 ноя 2019, 17:41

Swapping generation order is an interesting idea.
You could try to dump the information to a text file (std::ofstream) of failed items to double-check that road detection is correct.
Вернуться к началу

offlineas239  
Мастер
Мастер
 
Сообщения: 323
Зарегистрирован: 29 дек 2018, 14:17
Пол: Не указан
Поблагодарили: 13 раз.

Re: RMG SOD

Сообщение as239 » 02 ноя 2019, 18:42

The road detection is definitely correct. I checked it.
Вернуться к началу

Пред.След.

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

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

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

cron