Объявления

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

RMG SOD

Герои Меча и Магии 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: RMG SOD

Сообщение AlexSpl » 11 апр 2020, 08:28

Стоп. Так ставьте брейкпоинт на запись в память :smile2: И найдёте нужный Вам код.
Вернуться к началу

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

Re: RMG SOD

Сообщение as239 » 11 апр 2020, 08:28

AlexSpl писал(а):

Стоп. Так ставьте брейкпоинт на запись в память :smile2: И найдёте нужный Вам код.

Вот вот это я и не знаю как сделать.
Вернуться к началу

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: RMG SOD

Сообщение AlexSpl » 11 апр 2020, 08:30

Узнайте адрес RMG_MapItem.RMG_GroundTile.landType для начала. Он вычисляется.

Т.е. возьмите конкретный тайл конкретного объекта и поставьте брейкпоинт по этому адресу.

Другими словами, расшифруйте RMG_MapItem.RMG_GroundTile.landType. Получится что-то вроде сложения адресов. За адресами - в код H3API.
Вернуться к началу

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

Re: RMG SOD

Сообщение as239 » 11 апр 2020, 08:50

Не понимаю, как это сделать.
Формирую карту по одному сиду, получаю водный тайл(25,5,0).
В VS смотрю адрес типа земли:
 
Изображение

Но этот адрес при каждом переформировании карты разный.
Одновременно подключиться отладчиком VS и IDA не получается, выходит ошибка.
Не понимаю, как потом найти этот адрес в IDA.
Вернуться к началу

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: RMG SOD

Сообщение AlexSpl » 11 апр 2020, 09:00

Вам нужно понять, как вычисляется &((xyz)->tile.landType). Посмотрите H3API. Это будет сумма значений, записанных по другим адресам (например, GameMgr) и оффсета landType в структуре тайла. Адрес тайла находится по координатам. Т.е. получаете адрес карты, прибавляете к нему смещение конкретной структуры tile и оффсет поля landType внутри это структуры. 0x0f5e53c8 - это и есть такая сумма. Только она меняется каждый раз, когда Вы перезапускаете игру. Но этот адрес всё равно можно найти, т.к. адреса основных переменных фиксированны (тот же GameMgr).
Вернуться к началу

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: RMG SOD

Сообщение AlexSpl » 11 апр 2020, 09:13

Как вариант, попробуйте поиск по сигнатуре. Т.е. запишите последовательность байтов конкретной структуры тайла (адрес вы видите) и найдите такую же последовательность при следующей генерации (seed должен быть одинаковым).
Вернуться к началу

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

Re: RMG SOD

Сообщение as239 » 08 май 2020, 17:55

AlexSpl писал(а):

Там здоровая функция, и без теории - никак. Если бы кто статейку написал по объектам/структурам RMG :smile14: Причесать код можно, конечно, но для меня он слишком абстрактный.

Мне бы хоть вот этот, начальный кусок, скорее всего именно он делает проходы между зонами:
Код: Выделить всё
char __thiscall RMG_MonsterGenerationZoneBlocks_00541630(_RMGStruct_ *this, _RMGGenZone_ *GenZone1, unsigned int ZoneConnection, int a4, int a5)
 rmgMain = this;
  v7 = **(_DWORD **)ZoneConnection;
  ZoneId1 = GenZone1->ZoneInfo->Id;
  GenZone2 = this->GenZones[v7];
  GenZone2_ = GenZone2;
  ZoneId2 = GenZone2->ZoneInfo->Id;
  CentrX1 = GenZone1->X;
  CenterY1 = GenZone1->Y;
  CenterZ1 = GenZone1->Z;
  CentrX1 = GenZone2->X;
  CenterY1 = GenZone2->Y;
  if ( CenterZ1 != GenZone2->Z )
    return 0;
  if ( GenZone1->Ground == 8 )
    return 0;
  if ( GenZone2->Ground == 8 )
    return 0;
  v12 = 0;
  LOBYTE(Mon2Way.Ref) = HIBYTE(ZoneConnection);
  Mon2Way.First = 0;
  Mon2Way.Last = 0;
  Mon2Way.All = 0;
  v10 = a4;
  v11 = 0;
  v71 = 0;
  v67 = 0;
  v69 = 100;
  v65 = 0;
  for ( i = 0; ; i += 12 )
  {
    v13 = *(_DWORD *)(v10 + 4);
    if ( !v13 || v11 >= (*(_DWORD *)(v10 + 8) - v13) >> 2 )
      break;
    v14 = *(_DWORD **)(v13 + 4 * v11);
    if ( v14[8] << 8 >> 24 == ZoneId1 && v14[8] >> 24 == ZoneId2 )
    {
      v15 = v14[1];
      if ( !v15 || (signed int)((v14[2] - v15) & 0xFFFFFFFC) <= 0 )
      {
        v18 = (int *)(*(_DWORD *)(a5 + 4) + i);
        v19 = (v14[10] >> 12) & 7;
        CentrX1 = *v18;
        v20 = v18[1];
        v21 = dword_0069CE10[2 * v19];
        v22 = dword_0069CE14[2 * v19];
        v56 = v18[2];
        v16 = &rmgMain->MapItems[v21 + CentrX1 + rmgMain->SizeX * (v20 + v22 + v56 * rmgMain->SizeY)];
        v17 = v16->field_4;
        if ( !v17 || (signed int)((v16->field_8 - v17) & 0xFFFFFFFC) <= 0 )
        {
          ++v67;
          v23 = v14[7] >> 16;
          if ( v23 <= v69 )
          {
            if ( v23 < v69 )
            {
              sub_00506FD0((int)&Mon2Way, Mon2Way.First, Mon2Way.Last);
              v69 = v23;
            }
            sub_0054D4E0((int)&Mon2Way, Mon2Way.Last, 1u, i + *(_DWORD *)(a5 + 4));
          }
        }
      }
    }
    v10 = a4;
    v12 = (void *)Mon2Way.First;
    v11 = v65++ + 1;
  }
  if ( !v12 || (a4 = (Mon2Way.Last - (signed int)v12) / 12) == 0 )
  {
    delete(v12);
    return 0;
  }

Кстати sub_0054D4E0 одна из самых страшных функций, которые мне встречались.
Хоть бы примерно понимать что она делает.

По структурам, там все очень просто. Один из самых маленьких наборов в игре:
https://github.com/RoseKavalier/H3Plugi ... /H3RMG.hpp
Это все что есть и ничего более.

RMG_Main(_RMGStruct_) - Главная точка входа, в которой хранятся все основные параметры создаваемой карты. Основные атрибуты:
RMG_Map map; - структура всей создаваемой карты.
H3Vector<RMG_ObjectProps>(_RMGObjectPrototype_) objectsTxt; - свойства всех объектов из одноименного txt файла.
H3Vector<RMG_Object*>(_RMGObject_) positions; - все созданные на карте объекты.
H3Vector<RMG_ZoneGenerator*> zoneGenerators; - вектор создаваемых зон.

RMG_Map map(_RMGMapItems_) -вся карта состоит из:
RMG_MapItem(_RMGMapItem_) *mapItems; - одна клетка карты

RMG_ZoneGenerator(_RMGGenZone_) - создаваемая зона карты, ключевой атрибут:
RMG_Zone *zoneInfo; - содержит всю информацию по зоне, загруженную из шаблона rmg.txt

RMG_Zone(_RMGZone_)
H3Vector<RMG_ZoneConnection> connections; - по сути содержит вектор зон, с которыми должна соединяться текущая зона, эти данные также загружаются из rmg.txt и упакованы в отдельную структуру
 
Изображение
Вернуться к началу

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

Re: RMG SOD

Сообщение as239 » 16 май 2020, 13:34

А как можно по RMG_Object выйти на его RMG_ObjectGenerator?
Мне нужно получить value хижины провидца.
Вернуться к началу

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

Re: RMG SOD

Сообщение RoseKavalier » 16 май 2020, 16:16

Maybe by virtual table comparison?
I have this static-analysis of RMG_Object_Seer, really not certain it's accurate.
Код: Выделить всё
00000000 RMG_Obj_Seer        struc ; (sizeof=0x34, mappedto_483)
00000000 base                _RMGObject_ ?
0000001C art_id              dd ?
00000020 rewardType        dd ?
00000024 resourceId          dd ? (can be resources, experience)
00000028 resourceAmount      dd ?
0000002C creatureRewardType  dd ?
00000030 creatureRewardNumber dd ?
00000034 RMG_Obj_Seer        ends
Вернуться к началу

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

Re: RMG SOD

Сообщение as239 » 16 май 2020, 17:26

I don't know how to work with virtual tables.

RMG_Object_Seer - very useful, now i can get seer's reward.
And calculate it's values, there is a little problem, with army - i cant't repeat original formula cause it rather complicated.

Here is a little analyze of 6 Seer's Hut:
Код: Выделить всё
10 000 exp
      base   103   int
      art_id   10000   int
      rewardType   6   int
      resourceId   0   int
      resourceAmount   -1   int
      creatureRewardType   0   int
      creatureRewardNumber   42630688   int

20 000 exp
      base   105   int
      art_id   20000   int
      rewardType   6   int
      resourceId   0   int
      resourceAmount   -1   int
      creatureRewardType   0   int
      creatureRewardNumber   290750228   int

15 000 gold
      base   84   int
      art_id   0   int
      rewardType   6   int
      resourceId   15000   int
      resourceAmount   -1   int
      creatureRewardType   0   int
      creatureRewardNumber   293525376   int

20 fanatics
      base   97   int
      art_id   0   int
      rewardType   6   int
      resourceId   0   int
      resourceAmount   9   int
      creatureRewardType   20   int
      creatureRewardNumber   312757036   int


15 m.gorgons
      base   45   int
      art_id   0   int
      rewardType   6   int
      resourceId   0   int
      resourceAmount   103   int
      creatureRewardType   15   int
      creatureRewardNumber   293720848   int

20 k. griffons
      base   102   int
      art_id   0   int
      rewardType   6   int
      resourceId   0   int
      resourceAmount   5   int
      creatureRewardType   20   int
      creatureRewardNumber   8   int


So, here is the correct names:
Код: Выделить всё
art_id = expreward
resourceId = goldreward
resourceAmount = creatureRewardType
creatureRewardType =  creatureAmount


Question, what is "base"?
Вернуться к началу

Пред.След.

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

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

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