-
Ben80
имя: Сергей
- Эксперт
-
- Сообщения: 1318
- Зарегистрирован: 18 июн 2017, 06:49
- Пол:
- Поблагодарили: 336 раз.
|
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); }
|