Объявления

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

Энциклопедия алгоритмов HoMM 3

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

Re: Энциклопедия алгоритмов HoMM 3

Сообщение Ben80 » 22 янв 2019, 18:28

Кусок кода, позволяющий создать массив miPassability[mapSize][mapSize], содержащий логические значения -
проходима ли данная клетка карты.

Возможно, где-то в игре есть уже готовая структура, ссылающаяся на уже готовый подобный массив
(например, структура 0x6992D4 AccessableSquaresStruct), но на данный момент это достоверно неизвестно.

Код: Выделить всё
int objectsNumber;
    int bitCounter;
    int impassNumber;
    int templateId;
    int x,y;
    bool passability;
    int mapSize = o_GameMgr->GetMapWidth();
    bool **miPassability = new bool*[mapSize];
    for (x = 0; x < mapSize; x++)
        miPassability[x] = new bool[mapSize];

    for(x = 0; x < mapSize; x++)
        for(y = 0; y < mapSize; y++)
            miPassability[x][y] = true;

    objectsNumber = ((int)o_GameMgr->Map.Objects.EndData - (int)o_GameMgr->Map.Objects.Data)/12;
    for(int n = 0; n < objectsNumber; n++)
    {
        templateId = o_GameMgr->Map.Objects[n].template_id;
        x = o_GameMgr->Map.Objects[n].x - 8;
        y = o_GameMgr->Map.Objects[n].y - 6;

        bitCounter = -1;
        impassNumber = (int)o_GameMgr->Map.Templates[templateId].ImpassBitMask.bits0;
        if(impassNumber != -1)
        {
            for(int i = 0; i < 4; i++)
            {
                y = y + 1;
                for(int j = 0; j < 8; j++)
                {
                    x = x + 1;
                    bitCounter = bitCounter + 1;
                    passability = (impassNumber >> bitCounter) & (int)1;
                    if(x>=0 && y>=0 && passability == false)
                        miPassability[x][y] = false;
                }
                x = x - 8;
            }
        }
        else
            y = y + 4;

        bitCounter = -1;
        impassNumber = (int)o_GameMgr->Map.Templates[templateId].ImpassBitMask.bits32;
        for(int i = 0; i < 2; i++)
        {
            y = y + 1;
            for(int j = 0; j < 8; j++)
            {
                x = x + 1;
                bitCounter = bitCounter + 1;
                passability = (impassNumber >> bitCounter) & (int)1;
                if(x>=0 && y>=0 && passability == false)
                    miPassability[x][y] = false;
            }
            x = x - 8;
        }
    }
Вернуться к началу

offlineАватара пользователя
AlexSpl  
имя: Александр
Эксперт
Эксперт
 
Сообщения: 5547
Зарегистрирован: 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)
Поблагодарили: 2162 раз.

Re: Энциклопедия алгоритмов HoMM 3

Сообщение AlexSpl » 22 янв 2019, 18:54

Я точно уже не помню, зачем мне было это нужно, но, кажется, для нахождения минимального расстояния между тайлами без учёта временно непроходимых объектов (таких, например, как кучки ресурсов, артефакты, герои и т.п.). Это очень полезная фича для оффлайн-турниров. Попробую поразбираться.
Вернуться к началу

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

Re: Энциклопедия алгоритмов HoMM 3

Сообщение Ben80 » 16 мар 2019, 04:52

RoseKavalier
Код: Выделить всё
INT32 move_type; // +0x132DC ~ 01 move, 03 ~ range, 05 ~ hover your allies, 07 ~ melee attack, 15 ~ half ranged damage

   Pointer Type
0   Null/Not Allowed
1   Move
2   Fly
3   Shooting (Arrow)
4   Hero (Helmet)
5   Question Mark
6   Arrow Pointer
7   Attack Northeast (Sword)
8   Attack East (Sword)
9   Attack Southeast (Sword)
10   Attack Southwest (Sword)
11   Attack West (Sword)
12   Attack Northwest (Sword)
13   Attack North (Sword)
14   Attack South (Sword)
15   Half Damage (Broken Arrow)
16   Attack Wall (Catapult)
17   Heal
18   Sacrifice
19   Teleport
Вернуться к началу

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

Re: Энциклопедия алгоритмов HoMM 3

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

_Player_*
field_30[4]

Содержит тип ИИ (Воин, Строитель, Исследователь).

Нашел на ДФ в посте MoP
Вернуться к началу

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

Re: Энциклопедия алгоритмов HoMM 3

Сообщение Ben80 » 16 мар 2019, 05:02

По поводу miPassability[mapSize][mapSize] в посте выше.

На самом деле все проще:

_MapItem_
attrib

01 - непроходимо (красная клетка)
10 - есть что-то, что надо настраивать (желтая клетка)
02 - граница к воде ???

(WoG sources) :smile1:
Вернуться к началу

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

Re: Энциклопедия алгоритмов HoMM 3

Сообщение Ben80 » 17 мар 2019, 20:00

Feanor

Цитата:
In TSW I made this like:
Код: Выделить всё
int __stdcall OnSpecBuildAIValueCalc(LoHook* h, HookContext* c)
{
_Town_* town = (_Town_*)c->ebx;
int building = c->edi;

if (town->type == 5 && building == 22)
{
int value = 1;
if(town->field_03)
{
value = -1;
}
else
{
//should be dynamic, but for now some big value is a fine too.
value = 9999;
}
c->return_address =  0x42B1CB;
*(int*)(c->ebp + c->edi * 4 - 0x114) = value;
return NO_EXEC_DEFAULT;
}
return EXEC_DEFAULT;
}

citrine->WriteLoHook(0x42B04D, (void*)OnSpecBuildAIValueCalc);

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

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

Re: Энциклопедия алгоритмов HoMM 3

Сообщение Ben80 » 17 мар 2019, 20:03

Sav, старый пост на Вог форуме

Sav_data.txt
(69.49 КБ) Скачиваний: 390
Вернуться к началу

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

Re: Энциклопедия алгоритмов HoMM 3

Сообщение Ben80 » 31 мар 2019, 19:03

RK
Код: Выделить всё
        int __thiscall RMG_CalculateMovementCost_00547D70(_RMGStruct_ *this, int x, int y, int z)
        {
          _RMGStruct_ *v4; // ebx
          _RMGMapItem_ *v5; // eax
          int z_; // esi
          _RMGMapItem_ *mitems; // edi
          int v8; // eax
          _RMGMapItem_ *mi; // eax
          unsigned int v10; // ecx
          _RMGObjectPrototype_ *v11; // ecx
          int objectType; // edx
          _ItemSettings_ *itemSet; // eax
          int v14; // eax
          unsigned int v15; // ecx
          _RMGObject_ **v16; // eax
          _RMGObject_ *v17; // eax
          int *v18; // eax
          int v19; // ecx
          int v20; // edi
          _RMGMapItem_ *v21; // eax
          int v22; // ecx
          int v23; // ST20_4
          int v24; // edx
          RMG_Point *v25; // eax
          int v26; // esi
          int v27; // ecx
          int v28; // ecx
          int v29; // ecx
          int v30; // edx
          int v31; // esi
          int subtype_; // edx
          unsigned int v33; // ecx
          _RMGObject_ **v34; // eax
          _RMGObject_ *v35; // eax
          RMG_Point *v36; // eax
          int x_2; // ecx
          int movCost; // edi
          _RMGMapItem_ *v39; // eax
          int v40; // ecx
          int v41; // edx
          RMG_Point *v42; // eax
          int cost_2; // esi
          int v44; // ecx
          int v45; // ecx
          int v46; // ecx
          int v47; // edx
          int v48; // esi
          int v49; // eax
          _RMGMapItem_ *v50; // edx
          _RMGMapItem_ *v51; // eax
          int v52; // edx
          int v53; // edi
          int *v54; // eax
          int v55; // ecx
          int v56; // esi
          int v57; // edx
          int v58; // edx
          int v59; // esi
          int v60; // eax
          _BOOL1 noDirectionAvailable; // zf
          POINT *offset; // ecx
          LONG xOffset; // eax
          LONG yOffset; // edx
          int _x; // ecx
          int _y; // edx
          int height; // eax
          _RMGMapItem_ *mi_offset; // eax
          int landType; // ecx
          unsigned int v70; // edx
          _ItemSettings_ *itSet; // ecx
          signed int costToMove; // edi
          int v73; // ecx
          unsigned __int16 prevMovementCost; // dx
          int xStart; // edx
          int v76; // edi
          RMG_Point *v77; // eax
          int newCostToMove_WORD; // esi
          int y_2; // ecx
          int zStart; // edx
          int v81; // ecx
          int currentPoint; // edx
          int v83; // esi
          int v84; // edx
          RMG_Point v86; // [esp+18h] [ebp-B0h]
          int v87; // [esp+24h] [ebp-A4h]
          int v88; // [esp+2Ch] [ebp-9Ch]
          RMG_Point a3; // [esp+30h] [ebp-98h]
          RMG_Point pt2; // [esp+3Ch] [ebp-8Ch]
          int yStart; // [esp+4Ch] [ebp-7Ch]
          int z_1; // [esp+50h] [ebp-78h]
          RMG_Point v93; // [esp+54h] [ebp-74h]
          int v94; // [esp+60h] [ebp-68h]
          int v95; // [esp+64h] [ebp-64h]
          int v96; // [esp+68h] [ebp-60h]
          RMG_Point pt1; // [esp+6Ch] [ebp-5Ch]
          int movementCost; // [esp+78h] [ebp-50h]
          _Memory_ minimumCost; // [esp+7Ch] [ebp-4Ch]
          int x_2_; // [esp+8Ch] [ebp-3Ch]
          int y_2_; // [esp+90h] [ebp-38h]
          int z_2; // [esp+94h] [ebp-34h]
          Vector_RMG_Point minimumPath; // [esp+98h] [ebp-30h]
          _BOOL1 hasRoad; // [esp+ABh] [ebp-1Dh]
          int direction; // [esp+ACh] [ebp-1Ch]
          int newCostToMove_2; // [esp+B0h] [ebp-18h]
          int subtype; // [esp+B4h] [ebp-14h]
          int newCostToMove; // [esp+B8h] [ebp-10h]
          int v109; // [esp+C4h] [ebp-4h]

          v4 = this;
          minimumPath.field_0 = HIBYTE(z);
          minimumPath.first = 0;
          minimumPath.end = 0;
          minimumPath.capacity = 0;
          v109 = 0;
          minimumCost.Ref = HIBYTE(z);
          minimumCost.First = 0;
          minimumCost.Last = 0;
          minimumCost.All = 0;
          LOBYTE(v109) = 1;
          Vector_Add_Size12_0054CAC0(&minimumPath, 0, (RMG_Point *)&x);
          subtype = 0;
          VectorCopy_0051B3A0((_Vector_ *)&minimumCost, 0, (int)&subtype);
          v5 = &v4->MapItems[x + v4->SizeX * (y + z * v4->SizeY)];
          v5->movementCost &= 0xFFFF0000;               // null out movement cost from starting point
          v5 = (_RMGMapItem_ *)((char *)v5 + 16);       // reference to coordinates of map item
          v5->objects.field_0 = -1;                     // x , previous tile = (-1, -1, -1)
          v5->objects.first = (_RMGObject_ **)-1;       // y
          v5->objects.end = (_RMGObject_ **)-1;         // z
          while ( minimumPath.first && minimumPath.end - minimumPath.first )
          {
            x = minimumPath.end[-1].x;
            y = minimumPath.end[-1].y;
            z = minimumPath.end[-1].z;
            DeleteEntry(&minimumCost, minimumCost.Last - 1);// remove last entry, cheapest
            VectorRemovePoint_0054CCE0(&minimumPath, minimumPath.end - 1);// remove last entry, cheapest
            z_ = z;
            mitems = v4->MapItems;
            v8 = x + v4->SizeX * (y + z * v4->SizeY);
            direction = 8;                              // no road?
            mi = &mitems[v8];                           // current tile
            movementCost = mi->movementCost & 0xFFFF;
            v10 = mi->PackedGroundData2;
            hasRoad = (mi->PackedGroundData & 0x3C000000) != 0;
            if ( (v10 >> 22) & 1 )                      // has object
            {
              v11 = (*mi->objects.first)->PrototypeRef->Prototype;
              objectType = v11->Type;
              itemSet = &MapObjectGlbSettings[v11->Type];
              if ( !itemSet->exitTop && !itemSet->mayBeGuarded )
                direction = 5;                          // try below, from botLeft
              switch ( objectType )
              {
                case MONOLITH_ONE_WAY_ENTRANCE:
                case MONOLITH_ONE_WAY_EXIT:
                  v14 = v11->Subtype;
                  v15 = 0;
                  subtype = v14;
                  while ( 1 )
                  {
                    v16 = v4->monolithsOneWay.first;
                    newCostToMove = v15;
                    if ( !v16 || v15 >= (_DWORD)((char *)v4->monolithsOneWay.end - (char *)v16) >> 2 )
                      break;
                    v17 = v16[v15];
                    if ( v17->PrototypeRef->Prototype->Subtype == subtype )
                    {
                      v18 = &v17->X;
                      v19 = *v18;
                      x_2_ = v19;
                      y_2_ = v18[1];
                      z_2 = v18[2];
                      v20 = movementCost + 50;
                      v21 = &v4->MapItems[v19 + v4->SizeX * (y_2_ + z_2 * v4->SizeY)];
                      v22 = v21->movementCost;
                      if ( (unsigned __int16)v21->movementCost > (unsigned int)(movementCost + 50) )
                      {
                        v23 = z_;
                        v24 = y;
                        v25 = &v21->prevTile;
                        v26 = v22 ^ (unsigned __int16)(v20 ^ v22);
                        v27 = x;
                        v25[1].x = v26;
                        v25->x = v27;
                        v28 = y_2_;
                        newCostToMove_2 = v20;
                        v25->y = v24;
                        a3.y = v28;
                        v29 = 0;
                        v25->z = v23;
                        a3.x = x_2_;
                        a3.z = z_2;
                        if ( minimumPath.first )
                          v30 = minimumPath.end - minimumPath.first;
                        else
                          v30 = 0;
                        while ( 1 )
                        {
                          v31 = (v30 + v29) >> 1;
                          if ( v29 >= v30 )
                            break;
                          if ( v20 >= minimumCost.First[v31] )
                            v30 = (v30 + v29) >> 1;
                          else
                            v29 = v31 + 1;
                        }
                        Vector_Add_Size12_0054CAC0(&minimumPath, &minimumPath.first[v31], &a3);
                        VectorCopy_0051B3A0((_Vector_ *)&minimumCost, (DWORD *)&minimumCost.First[v31], (int)&newCostToMove_2);
                        z_ = z;
                      }
                    }
                    v15 = newCostToMove + 1;
                  }
                  break;
                case MONOLITH_TWO_WAY:
                  subtype_ = v11->Subtype;
                  v33 = 0;
                  subtype = subtype_;
                  while ( 1 )
                  {
                    v34 = v4->monolithsTwoWay.first;
                    newCostToMove = v33;
                    if ( !v34 || v33 >= (_DWORD)((char *)v4->monolithsTwoWay.end - (char *)v34) >> 2 )
                      break;
                    v35 = v34[v33];
                    if ( v35->PrototypeRef->Prototype->Subtype == subtype )
                    {
                      v36 = (RMG_Point *)&v35->X;
                      x_2 = v36->x;
                      x_2_ = x_2;
                      y_2_ = v36->y;
                      z_2 = v36->z;
                      movCost = movementCost + 50;
                      v39 = &v4->MapItems[x_2 + v4->SizeX * (y_2_ + z_2 * v4->SizeY)];
                      v40 = v39->movementCost;
                      if ( (unsigned __int16)v39->movementCost > (unsigned int)(movementCost + 50) )
                      {
                        v88 = z_;
                        v87 = x;
                        v41 = y;
                        v42 = &v39->prevTile;
                        cost_2 = v40 ^ (unsigned __int16)(movCost ^ v40);
                        v44 = x;
                        v42[1].x = cost_2;              // movement cost
                        v42->x = v44;
                        v45 = y_2_;
                        newCostToMove_2 = movCost;
                        v42->y = v41;
                        v86.y = v45;
                        v46 = 0;
                        v42->z = v88;
                        v86.x = x_2_;
                        v86.z = z_2;
                        if ( minimumPath.first )
                          v47 = minimumPath.end - minimumPath.first;
                        else
                          v47 = 0;
                        while ( 1 )
                        {
                          v48 = (v47 + v46) >> 1;
                          if ( v46 >= v47 )
                            break;
                          if ( movCost >= minimumCost.First[v48] )
                            v47 = (v47 + v46) >> 1;
                          else
                            v46 = v48 + 1;
                        }
                        Vector_Add_Size12_0054CAC0(&minimumPath, &minimumPath.first[v48], &v86);
                        VectorCopy_0051B3A0((_Vector_ *)&minimumCost, (DWORD *)&minimumCost.First[v48], (int)&newCostToMove_2);
                        z_ = z;
                      }
                    }
                    v33 = newCostToMove + 1;
                  }
                  break;
                case SUBTERRANEAN_GATE:
                  v49 = x + v4->SizeX * (y + (1 - z) * v4->SizeY);
                  x_2_ = x;
                  v50 = v4->MapItems;
                  y_2_ = y;
                  z_2 = z;
                  v51 = &v50[v49];
                  newCostToMove = movementCost + 1;
                  v52 = v51->movementCost;
                  if ( movementCost + 1 < (unsigned int)(unsigned __int16)v51->movementCost )
                  {
                    v96 = z;
                    v94 = x;
                    v95 = y;
                    v53 = newCostToMove;
                    v54 = &v51->prevTile.x;
                    v93.z = 1 - z;
                    v55 = 0;
                    v56 = v52 ^ (unsigned __int16)(newCostToMove ^ v52);
                    v57 = x;
                    v54[3] = v56;
                    *v54 = v57;
                    newCostToMove_2 = v53;
                    v54[1] = v95;
                    v54[2] = v96;
                    v93.x = x_2_;
                    v93.y = y_2_;
                    if ( minimumPath.first )
                      v58 = minimumPath.end - minimumPath.first;
                    else
                      v58 = 0;
                    while ( 1 )
                    {
                      v59 = (v58 + v55) >> 1;
                      if ( v55 >= v58 )
                        break;
                      if ( v53 >= minimumCost.First[v59] )
                        v58 = (v58 + v55) >> 1;
                      else
                        v55 = v59 + 1;
                    }
                    Vector_Add_Size12_0054CAC0(&minimumPath, &minimumPath.first[v59], &v93);
                    VectorCopy_0051B3A0((_Vector_ *)&minimumCost, (DWORD *)&minimumCost.First[v59], (int)&newCostToMove_2);
                    z_ = z;
                  }
                  break;
                default:
                  break;
              }
            }
            v60 = direction - 1;
            noDirectionAvailable = direction-- == 0;
            if ( !noDirectionAvailable )
            {                                           //
                                                        // 0x69CE10 Order to check nearby tiles
                                                        //  Y\X  -1  0  1
                                                        //      ###########
                                                        //  -1  # 3  2  1 #
                                                        //   0  # 4  *  0 #
                                                        //   1  # 5  6  7 #
                                                        //      ###########


              offset = (POINT *)(8 * v60 + 0x69CE10);
              subtype = 8 * v60 + 0x69CE10;             // variable is reused, here is a POINT*
              do
              {
                xOffset = offset->x;
                yOffset = offset->y;
                pt1.z = z_;
                _x = xOffset + x;
                _y = y + yOffset;
                pt1.x = xOffset + x;
                pt1.y = _y;
                if ( xOffset + x >= 0 && _x < v4->SizeX && _y >= 0 )
                {
                  height = v4->SizeY;
                  if ( _y < height )
                  {
                    mi_offset = &v4->MapItems[_x + v4->SizeX * (_y + z_ * height)];
                    landType = mi_offset->PackedGroundData & 0x3F;
                    if ( landType != WATER_terrain )
                    {
                      v70 = mi_offset->PackedGroundData2;
                      if ( v70 & 0x2000000 )            // blocked access ?
                      {
                        if ( landType != ROCK_terrain )
                        {
                          if ( !((v70 >> 22) & 1)       // has object
                            || ((itSet = &MapObjectGlbSettings[(*mi_offset->objects.first)->PrototypeRef->Prototype->Type],
                                 !itSet->canEnter)
                             || itSet->mayBeGuarded)
                            && (itSet->exitTop || itSet->mayBeGuarded || direction <= 0 || direction >= 4) )
                          {
                            if ( !hasRoad || (costToMove = 2, !(mi_offset->PackedGroundData & 0x3C000000)) )// if road, cost is 2, 10% of no road
                              costToMove = 20;          // base cost
                            if ( direction & 1 )        // diagonal movement
                              costToMove *= 3;          // skewed against diagonal movement to draw nice looking roads
                            v73 = mi_offset->movementCost;
                            prevMovementCost = mi_offset->movementCost;
                            newCostToMove = movementCost + costToMove;
                            if ( movementCost + costToMove < (unsigned int)prevMovementCost )
                            {
                              xStart = x;
                              yStart = y;
                              v76 = newCostToMove;
                              z_1 = z_;
                              v77 = &mi_offset->prevTile;
                              newCostToMove_2 = newCostToMove;
                              newCostToMove_WORD = v73 ^ (unsigned __int16)(newCostToMove ^ v73);
                              y_2 = y;
                              v77[1].x = newCostToMove_WORD;// movement cost
                              v77->x = xStart;
                              zStart = z_1;
                              v77->y = y_2;
                              pt2.y = pt1.y;
                              v81 = 0;
                              v77->z = zStart;
                              pt2.x = pt1.x;
                              pt2.z = pt1.z;
                              if ( minimumPath.first )
                                currentPoint = minimumPath.end - minimumPath.first;
                              else
                                currentPoint = 0;
                              while ( 1 )
                              {
                                v83 = (currentPoint + v81) >> 1;// check if new cost calculated is cheaper than previous
                                if ( v81 >= currentPoint )
                                  break;
                                if ( v76 >= minimumCost.First[v83] )
                                  currentPoint = (currentPoint + v81) >> 1;
                                else
                                  v81 = v83 + 1;
                              }
                              AddVector_Size12(&minimumPath, &minimumPath.first[v83], 1u, &pt2);// update cheapest path
                              AddVector_Size4(&minimumCost, &minimumCost.First[v83], 1, &newCostToMove_2);// update cheapest cost
                              z_ = z;
                            }
                          }
                        }
                      }
                    }
                  }
                }
                v84 = direction;
                offset = (POINT *)(subtype - 8);
                --direction;
                subtype -= 8;
              }
              while ( v84 );
            }
          }
          delete(minimumCost.First);
          minimumCost.First = 0;
          minimumCost.Last = 0;
          minimumCost.All = 0;
          return delete(minimumPath.first);
        }
Вернуться к началу

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

Re: Энциклопедия алгоритмов HoMM 3

Сообщение Ben80 » 31 мар 2019, 19:08

RK: "sub_005328A0 writes the road type to a tile during RMG"
Код: Выделить всё
_RMGMapItem_ *__thiscall RMG_WriteRoad_005328A0(PtrToRMGStructOffset *this, POINT *a2, char roadType)
{
  _RMGMapItem_ *result; // eax

  result = &this->miOffset->mapItems[a2->x + a2->y * this->miOffset->sizeX];
  result->PackedGroundData = result->PackedGroundData & ~0x3C000000 | ((roadType & 0xF) << 26);
  return result;
}
Вернуться к началу

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

Re: Энциклопедия алгоритмов HoMM 3

Сообщение Ben80 » 31 мар 2019, 19:08

RK: "The format of PackedGroundData is bitfield as follows"
Код: Выделить всё
        struct RMG_GroundTile
        {
           unsigned landType   : 5; // bit 1~4
           unsigned _b6      : 1;
           unsigned landSprite : 7; // bit 7 ~ 13
           unsigned _b14      : 1;
           unsigned riverType   : 3; // bit 15, 16, 17
           unsigned _b18      : 1;
           unsigned riverSprite : 7;// bit 19, 20, 21, 22, 23, 24, 25
           unsigned _b26      : 1;
           unsigned roadType   : 3; // bit 27 28 29
           unsigned _b30      : 3;
        };
Вернуться к началу

След.

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

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

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

cron