Объявления

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

RMG SOD

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
offlineRoseKavalier  
Мастер
Мастер
 
Сообщения: 331
Зарегистрирован: 23 сен 2017, 17:00
Пол: Не указан
Поблагодарили: 234 раз.

Re: RMG SOD

Сообщение RoseKavalier » 17 май 2020, 02:21

See the description in second column _RMGObject_.
The first value (base) you wrote seems to be the artifact id needed to complete the quest.
Код: Выделить всё
00000000 RMG_Obj_Seer        struc ; (sizeof=0x34, mappedto_483)
00000000 base                _RMGObject_ ?
0000001C art_id              dd ?
00000020 experienceAmount    dd ?
00000024 resourceId          dd ?
00000028 resourceAmount      dd ?
0000002C creatureRewardType  dd ?
00000030 creatureRewardNumber dd ?
00000034 RMG_Obj_Seer        ends


Virtual table can be used to call specific functions tied to the current object (great for derived types), however in this context I meant to look at the address of the virtual table (PtrAt(this))
RMG_SeerHutMonsters_VTable_640C10
RMG_SeerHutExp_VTable_640C1C
RMG_SeerHutGold_VTable_640C28
Вернуться к началу

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

Re: RMG SOD

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

stupid me:
Код: Выделить всё
struct RMG_Obj_Seer : public RMG_Object{
   INT32 art_id;             
   INT32 experienceAmount;   
   INT32 resourceId;         
   INT32 resourceAmount;   
   INT32 creatureRewardType;
   INT32 creatureRewardNumber;
};
Вернуться к началу

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

Re: RMG SOD

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

Using RMG_LocalMap for getting RMG_Obj_Seer

Код: Выделить всё
#pragma pack(push, 1)
struct RMG_LocalMap : RMG_Map
{
   h3unk _f_18[16];
   H3Vector<RMG_Object*> localObjects;
};
#pragma pack(pop)


Код: Выделить всё
   RMG_Object *obj = *RMGMap->localObjects[0];
   RMG_Obj_Seer *objSeer = (RMG_Obj_Seer*)obj;


It works cause Seer Hut is always one.
But RMGMap->localObjects.Size() returns 4.
Maybe localObjects contains another structure, which 4X wide *RMG_Object, and contains it?
Вернуться к началу

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

Re: RMG SOD

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

Tried this:
Код: Выделить всё
struct RMG_LocalObject
{
   RMG_Object* object;
   INT32 x1;
   INT32 x2;
   INT32 x3;
};
#pragma pack(push, 1)
struct RMG_LocalMap : RMG_Map
{
   h3unk _f_18[16];
   H3Vector<RMG_LocalObject> localObjects;
};
#pragma pack(pop)


But its wrong, 1 object at treasury block:
Код: Выделить всё
object   0x111d7010     //first object at treasury block
x1   287145472   int  //Monster guard
x2   287145568   int  //idk
x3   287145472   int  //Monster guard again


2 objects at treasury block:
Код: Выделить всё
object   0x111d7dd0     //first object at treasury block
x1   287144944   int   //second object at treasury block
x2   287145360   int   //Monster guard
x3   287145472   int   //idk


3 objects at treasury block:
Код: Выделить всё
object   0x111d7dd0     //first object at treasury block
x1   287145376   int   //second object at treasury block
x2   287145328   int   //third object at treasury block
x3   287145264   int   //Monster guard


etc.
Looks like just usual vector with monster at the end:
Код: Выделить всё
#pragma pack(push, 1)
struct RMG_LocalMap : RMG_Map
{
   h3unk _f_18[16];
   H3Vector<RMG_Object*> localObjects;
};
#pragma pack(pop)


But why there are always four times more than the number of elements?
Код: Выделить всё
MiniMap->localObjects.Size()
Вернуться к началу

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

Re: RMG SOD

Сообщение RoseKavalier » 17 май 2020, 13:40

H3Vector::Size()
That's definitely my fault, I didn't write h3api initially with std:: names in mind.
Size() is actually RawSize() which is the number of bytes allocated; you want H3Vector::Count() for the number of items.
I'm making a lot of changes to h3api and this is part of things that need to be modified ~ providing better names that are more instinctive.

I don't think you can stipulate that localObjects[0] is a Seer Hut, although maybe I don't understand the inside-outs of RMG_LocalMap. This would be something to verify with virtual table

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

      h3func GetVTable() const { return h3func(vTable); }
   };


compare against addresses of the vtables you are seeking, RMGObject_SeerHut_VTable_640B14 to be certain this is what you are looking for.

Finally, depending on where you hook, the RMGObject might not be fully created.

If all else fails, give me some addresses to look at with debugger)
Вернуться к началу

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

Re: RMG SOD

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

I am getting seer hut at HiHook here:
Код: Выделить всё
A0_AdditionalObjectsForSpecObjs_Place_sub_54B7F0


It works fine:
Код: Выделить всё
   RMG_Object *obj = *RMGMap->localObjects[0];

   if (obj->properties->prototype->type != NH3Objects::SEER_HUT)
   {
      return THISCALL_3(char, h->GetDefaultFunc(), this1, RMGMap, GenZone);
   }

   RMG_Obj_Seer *objSeer = (RMG_Obj_Seer*)obj;
Вернуться к началу

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

Re: RMG SOD

Сообщение as239 » 18 май 2020, 12:02

Вот здесь 0054170E, происходит обход клеток карты и клетки-границы между двумя зонами добавляются в std::vector<H3Coordinates> &Mon2Way:

Код: Выделить всё
  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 )
            {
              A0_List_12_DeleteRange_sub_506FD0((_Vector_ *)&Mon2Way, Mon2Way.First, Mon2Way.Last);
              v69 = v23;
            }
            A0_List12_InsertRange_sub_54D4E0((int)&Mon2Way, Mon2Way.Last, 1u, i + *(_DWORD *)(a5 + 4));
          }
        }
      }
    }


Вот пример содержимого этого вектора:
Код: Выделить всё
[0]   {x=2 y=6 z=0 }
[1]   {x=2 y=7 z=0 }
[2]   {x=3 y=7 z=0 }
[3]   {x=3 y=8 z=0 }
[4]   {x=4 y=8 z=0 }
[5]   {x=4 y=9 z=0 }
[6]   {x=5 y=9 z=0 }
[7]   {x=5 y=10 z=0 }
[8]   {x=6 y=10 z=0 }
[9]   {x=10 y=12 z=0 }
[10]   {x=11 y=12 z=0 }
[11]   {x=11 y=13 z=0 }
[12]   {x=12 y=13 z=0 }
[13]   {x=12 y=14 z=0 }
[14]   {x=15 y=17 z=0 }
[15]   {x=17 y=17 z=0 }
[16]   {x=17 y=18 z=0 }
[17]   {x=18 y=18 z=0 }
[18]   {x=18 y=19 z=0 }
[19]   {x=19 y=19 z=0 }
[20]   {x=21 y=19 z=0 }
[21]   {x=21 y=20 z=0 }
[22]   {x=22 y=20 z=0 }
[23]   {x=25 y=23 z=0 }
[24]   {x=25 y=24 z=0 }
[25]   {x=26 y=24 z=0 }
[26]   {x=27 y=24 z=0 }


Мне нужно сократить этот вектор чтобы в нем был например каждый пятый элемент:
Код: Выделить всё
{x=2 y=6 z=0 }
{x=4 y=9 z=0 }
{x=11 y=12 z=0 }
{x=17 y=17 z=0 }
{x=21 y=19 z=0 }
{x=26 y=24 z=0 }


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

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

Re: RMG SOD

Сообщение as239 » 18 май 2020, 14:54

Я бы сделал через постобработку этого вектора, но проблема в том что я ничего не могу с ним делать:
Код: Выделить всё
   std::vector<H3Coordinates> *Borders = (std::vector<H3Coordinates>*)(c->ebp - 0x68);
   Borders->pop_back();


Вылет на второй строке:
Код: Выделить всё
std::vector<H3Coordinates,std::allocator<H3Coordinates> >::_Orphan_range
Вернуться к началу

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

Re: RMG SOD

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

I've not had time to look at RMG(

H3Vector has Pop(),Remove(INT), Remove(INT, INT) methods and upcoming Remove(_Elem*) and Remove(_Elem*, _Elem*) which work like erase()
Otherwise, you can convert between std::vector and h3::H3Vector and back.
Maybe something like...
Код: Выделить всё
std::vector stdVec = h3Vec->to_std_vector();
// perform manipulations...

// if you want to modify h3Vec, clear it first as I didn't do that in the code
h3Vec->RemoveAll();
*h3Vec = stdVec;


std::vector is different from H3Vector ~ you cannot guarantee it will work the same or that they are the same size. Plus you would need to specify H3Allocator because those are definitely not the same.
I briefly considered making H3Vector derived from std::vector with H3Allocator but simply switching to DEBUG would break compatibility...
Вернуться к началу

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

Re: RMG SOD

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

А как заменить вектор в памяти на свой?

Пробую так:

Код: Выделить всё
   std::vector<H3Coordinates> *vec = (std::vector<H3Coordinates>*)(c->ebp - 0x68);
   std::vector<H3Coordinates> vecNew;
   for (int i = 0; i < vec->size(); i++)
   {
      if (i % 4 == 0) vecNew.push_back(vec->at(i));
   }
   vec->clear();
   *vec = vecNew;

Вылет на:
Код: Выделить всё
vec->clear();

Либо на:
Код: Выделить всё
*vec = vecNew;


Я так и не понял, почему я ничего не могу делать с этим вектором, и чем мне может помочь H3Vector.
Так тоже вылет:
Код: Выделить всё
   H3Vector<H3Coordinates> *vec = (H3Vector<H3Coordinates>*)(c->ebp - 0x68);
   vec->RemoveAll();
Вернуться к началу

Пред.След.

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

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

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