You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
432 lines
9.0 KiB
432 lines
9.0 KiB
//HEADER_GOES_HERE |
|
|
|
#include "../types.h" |
|
|
|
PATHNODE path_nodes[300]; |
|
int gdwCurPathStep; |
|
int pnode_vals[26]; |
|
PATHNODE *pnode_ptr; |
|
PATHNODE *pnode_tblptr[300]; |
|
PATHNODE path_2_nodes[300]; |
|
|
|
char pathxdir[8] = { -1, -1, 1, 1, -1, 0, 1, 0 }; |
|
char pathydir[8] = { -1, 1, -1, 1, 0, -1, 0, 1 }; |
|
|
|
/* rdata */ |
|
char path_directions[9] = { 5, 1, 6, 2, 0, 3, 8, 4, 7 }; |
|
|
|
//----- (004493D4) -------------------------------------------------------- |
|
int __fastcall FindPath(bool (__fastcall *PosOk)(int, int, int), int PosOkArg, int sx, int sy, int dx, int dy, char *path) |
|
{ |
|
PATHNODE *v8; // esi |
|
char v9; // al |
|
PATHNODE *v11; // eax |
|
int result; // eax |
|
PATHNODE *v13; // edx |
|
int v14; // eax |
|
int v15; // edi |
|
bool v16; // zf |
|
int *v17; // ecx |
|
char v18; // dl |
|
|
|
pnode_vals[0] = 0; |
|
*(_DWORD *)&path_2_nodes[0].f = (unsigned int)path_new_step(); |
|
gdwCurPathStep = 0; |
|
pnode_ptr = path_new_step(); |
|
v8 = path_new_step(); |
|
v8->g = 0; |
|
v9 = path_get_h_cost(sx, sy, dx, dy); |
|
v8->h = v9; |
|
v8->x = sx; |
|
v8->f = v9 + v8->g; |
|
v8->y = sy; |
|
*(_DWORD *)(*(_DWORD *)&path_2_nodes[0].f + 48) = (unsigned int)v8; |
|
while ( 1 ) |
|
{ |
|
v11 = GetNextPath(); |
|
if ( !v11 ) |
|
return 0; |
|
if ( v11->x == dx && v11->y == dy ) |
|
break; |
|
if ( !path_get_path(PosOk, PosOkArg, v11, dx, dy) ) |
|
return 0; |
|
} |
|
v13 = v11; |
|
v14 = (int)&v11->Parent; |
|
v15 = 0; |
|
if ( *(_DWORD *)v14 ) |
|
{ |
|
while ( 1 ) |
|
{ |
|
v16 = v15 == 25; |
|
if ( v15 >= 25 ) |
|
break; |
|
pnode_vals[++v15] = path_directions[3 * (v13->y - *(_DWORD *)(*(_DWORD *)v14 + 8)) |
|
- *(_DWORD *)(*(_DWORD *)v14 + 4) |
|
+ 4 |
|
+ v13->x]; |
|
v13 = *(PATHNODE **)v14; |
|
v14 = *(_DWORD *)v14 + 12; |
|
if ( !*(_DWORD *)v14 ) |
|
{ |
|
v16 = v15 == 25; |
|
break; |
|
} |
|
} |
|
if ( v16 ) |
|
return 0; |
|
} |
|
result = 0; |
|
if ( v15 > 0 ) |
|
{ |
|
v17 = &pnode_vals[v15]; |
|
do |
|
{ |
|
v18 = *(_BYTE *)v17; |
|
--v17; |
|
path[result++] = v18; |
|
} |
|
while ( result < v15 ); |
|
} |
|
return result; |
|
} |
|
|
|
//----- (004494D3) -------------------------------------------------------- |
|
int __fastcall path_get_h_cost(int sx, int sy, int dx, int dy) |
|
{ |
|
int v4; // esi |
|
int v5; // edi |
|
int v6; // eax |
|
int v7; // ecx |
|
|
|
v4 = sy; |
|
v5 = abs(sx - dx); |
|
v6 = abs(v4 - dy); |
|
v7 = v5; |
|
if ( v5 >= v6 ) |
|
{ |
|
v7 = v6; |
|
if ( v5 > v6 ) |
|
v6 = v5; |
|
} |
|
return 2 * (v7 + v6); |
|
} |
|
|
|
//----- (00449504) -------------------------------------------------------- |
|
int __fastcall path_check_equal(PATHNODE *pPath, int dx, int dy) |
|
{ |
|
int v4; // [esp-4h] [ebp-4h] |
|
|
|
if ( pPath->x == dx || pPath->y == dy ) |
|
v4 = 2; |
|
else |
|
v4 = 3; |
|
return v4; |
|
} |
|
|
|
//----- (0044951C) -------------------------------------------------------- |
|
PATHNODE *__cdecl GetNextPath() |
|
{ |
|
PATHNODE *result; // eax |
|
|
|
result = *(PATHNODE **)(*(_DWORD *)&path_2_nodes[0].f + 48); |
|
if ( result ) |
|
{ |
|
*(_DWORD *)(*(_DWORD *)&path_2_nodes[0].f + 48) = (unsigned int)result->NextNode; |
|
result->NextNode = pnode_ptr->NextNode; |
|
pnode_ptr->NextNode = result; |
|
} |
|
return result; |
|
} |
|
|
|
//----- (00449546) -------------------------------------------------------- |
|
bool __fastcall path_solid_pieces(PATHNODE *pPath, int dx, int dy) |
|
{ |
|
bool result; // eax |
|
int dir; // ecx |
|
int v8; // ecx |
|
int v10; // edx |
|
|
|
result = 1; |
|
dir = path_directions[3 * (dy - pPath->y) - pPath->x + 4 + dx] - 5; |
|
if ( !dir ) |
|
{ |
|
result = 0; |
|
if ( nSolidTable[dPiece[dx][dy + 1]] ) |
|
return result; |
|
v8 = dPiece[dx + 1][dy]; |
|
goto LABEL_13; |
|
} |
|
dir--; |
|
if ( !dir ) |
|
{ |
|
v10 = dPiece[dx][dy + 1]; |
|
goto LABEL_9; |
|
} |
|
dir--; |
|
if ( !dir ) |
|
{ |
|
v10 = dPiece[dx][dy-1]; /* check */ |
|
LABEL_9: |
|
result = 0; |
|
if ( nSolidTable[v10] ) |
|
return result; |
|
v8 = dPiece[dx-4][dy]; /* check */ |
|
goto LABEL_13; |
|
} |
|
if ( dir == 1 ) |
|
{ |
|
result = 0; |
|
if ( !nSolidTable[dPiece[dx + 1][dy]] ) |
|
{ |
|
v8 = dPiece[dx][dy-1]; /* check */ |
|
LABEL_13: |
|
if ( nSolidTable[v8] == result ) |
|
result = 1; |
|
return result; |
|
} |
|
} |
|
return result; |
|
} |
|
|
|
//----- (004495ED) -------------------------------------------------------- |
|
int __fastcall path_get_path(bool (__fastcall *PosOk)(int, int, int), int PosOkArg, PATHNODE *pPath, int x, int y) |
|
{ |
|
int v5; // eax |
|
int dx; // esi |
|
int dy; // edi |
|
int i; // [esp+14h] [ebp-4h] |
|
|
|
v5 = 0; |
|
for ( i = 0; ; v5 = i ) |
|
{ |
|
dx = pPath->x + pathxdir[v5]; |
|
dy = pPath->y + pathydir[v5]; |
|
if ( !PosOk(PosOkArg, dx, dy) ) |
|
break; |
|
if ( path_solid_pieces(pPath, dx, dy) ) |
|
goto LABEL_8; |
|
LABEL_9: |
|
if ( ++i >= 8 ) |
|
return 1; |
|
} |
|
if ( dx != x || dy != y ) |
|
goto LABEL_9; |
|
LABEL_8: |
|
if ( path_parent_path(pPath, dx, dy, x, y) ) |
|
goto LABEL_9; |
|
return 0; |
|
} |
|
|
|
//----- (0044966F) -------------------------------------------------------- |
|
int __fastcall path_parent_path(PATHNODE *pPath, int dx, int dy, int sx, int sy) |
|
{ |
|
PATHNODE *v5; // edi |
|
int v6; // ebx |
|
PATHNODE *v7; // esi |
|
signed int v8; // eax |
|
struct PATHNODE **v9; // ecx |
|
char v10; // al |
|
PATHNODE *v11; // esi |
|
signed int v12; // eax |
|
struct PATHNODE **v13; // ecx |
|
char v14; // al |
|
PATHNODE *result; // eax |
|
PATHNODE *v16; // esi |
|
char v17; // al |
|
signed int v18; // ecx |
|
struct PATHNODE **v19; // eax |
|
int a1; // [esp+Ch] [ebp-4h] |
|
|
|
a1 = dx; |
|
v5 = pPath; |
|
v6 = pPath->g + path_check_equal(pPath, dx, dy); |
|
v7 = path_get_node1(a1, dy); |
|
if ( v7 ) |
|
{ |
|
v8 = 0; |
|
v9 = v5->Child; |
|
do |
|
{ |
|
if ( !*v9 ) |
|
break; |
|
++v8; |
|
++v9; |
|
} |
|
while ( v8 < 8 ); |
|
v5->Child[v8] = v7; |
|
if ( v6 < v7->g ) |
|
{ |
|
if ( path_solid_pieces(v5, a1, dy) ) |
|
{ |
|
v10 = v7->h; |
|
v7->Parent = v5; |
|
v7->g = v6; |
|
v7->f = v6 + v10; |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
v11 = path_get_node2(a1, dy); |
|
if ( v11 ) |
|
{ |
|
v12 = 0; |
|
v13 = v5->Child; |
|
do |
|
{ |
|
if ( !*v13 ) |
|
break; |
|
++v12; |
|
++v13; |
|
} |
|
while ( v12 < 8 ); |
|
v5->Child[v12] = v11; |
|
if ( v6 < v11->g && path_solid_pieces(v5, a1, dy) ) |
|
{ |
|
v14 = v6 + v11->h; |
|
v11->Parent = v5; |
|
v11->g = v6; |
|
v11->f = v14; |
|
path_set_coords(v11); |
|
} |
|
} |
|
else |
|
{ |
|
result = path_new_step(); |
|
v16 = result; |
|
if ( !result ) |
|
return 0; |
|
result->Parent = v5; |
|
result->g = v6; |
|
v17 = path_get_h_cost(a1, dy, sx, sy); |
|
v16->h = v17; |
|
v16->f = v6 + v17; |
|
v16->x = a1; |
|
v16->y = dy; |
|
path_next_node(v16); |
|
v18 = 0; |
|
v19 = v5->Child; |
|
do |
|
{ |
|
if ( !*v19 ) |
|
break; |
|
++v18; |
|
++v19; |
|
} |
|
while ( v18 < 8 ); |
|
v5->Child[v18] = v16; |
|
} |
|
} |
|
return 1; |
|
} |
|
|
|
//----- (0044979A) -------------------------------------------------------- |
|
PATHNODE *__fastcall path_get_node1(int dx, int dy) |
|
{ |
|
PATHNODE *result; // eax |
|
|
|
result = *(PATHNODE **)&path_2_nodes[0].f; |
|
do |
|
result = result->NextNode; |
|
while ( result && (result->x != dx || result->y != dy) ); |
|
return result; |
|
} |
|
|
|
//----- (004497B3) -------------------------------------------------------- |
|
PATHNODE *__fastcall path_get_node2(int dx, int dy) |
|
{ |
|
PATHNODE *result; // eax |
|
|
|
result = pnode_ptr; |
|
do |
|
result = result->NextNode; |
|
while ( result && (result->x != dx || result->y != dy) ); |
|
return result; |
|
} |
|
|
|
//----- (004497CC) -------------------------------------------------------- |
|
void __fastcall path_next_node(PATHNODE *pPath) |
|
{ |
|
PATHNODE *v1; // edx |
|
PATHNODE *v2; // eax |
|
|
|
v1 = *(PATHNODE **)&path_2_nodes[0].f; |
|
v2 = *(PATHNODE **)(*(_DWORD *)&path_2_nodes[0].f + 48); |
|
if ( v2 ) |
|
{ |
|
do |
|
{ |
|
if ( v2->f >= pPath->f ) |
|
break; |
|
v1 = v2; |
|
v2 = v2->NextNode; |
|
} |
|
while ( v2 ); |
|
pPath->NextNode = v2; |
|
} |
|
v1->NextNode = pPath; |
|
} |
|
|
|
//----- (004497F7) -------------------------------------------------------- |
|
void __fastcall path_set_coords(PATHNODE *pPath) |
|
{ |
|
PATHNODE *PathOld; // edi |
|
PATHNODE *PathAct; // esi |
|
char v6; // al |
|
int i; // [esp+0h] [ebp-8h] |
|
PATHNODE **v9; // [esp+4h] [ebp-4h] |
|
|
|
path_push_active_step(pPath); |
|
while ( gdwCurPathStep ) |
|
{ |
|
PathOld = path_pop_active_step(); |
|
v9 = PathOld->Child; |
|
for(i = 0; i < 8; i++) |
|
{ |
|
PathAct = *v9; |
|
if ( !*v9 ) |
|
break; |
|
|
|
if ( PathOld->g + path_check_equal(PathOld, PathAct->x, PathAct->y) < PathAct->g ) |
|
{ |
|
if ( path_solid_pieces(PathOld, PathAct->x, PathAct->y) ) |
|
{ |
|
PathAct->Parent = PathOld; |
|
v6 = PathOld->g + path_check_equal(PathOld, PathAct->x, PathAct->y); |
|
PathAct->g = v6; |
|
PathAct->f = v6 + PathAct->h; |
|
path_push_active_step(PathAct); |
|
} |
|
} |
|
++v9; |
|
} |
|
} |
|
} |
|
|
|
//----- (00449890) -------------------------------------------------------- |
|
void __fastcall path_push_active_step(PATHNODE *pPath) |
|
{ |
|
int v1; // eax |
|
|
|
v1 = gdwCurPathStep++; |
|
pnode_tblptr[v1] = pPath; |
|
} |
|
|
|
//----- (004498A3) -------------------------------------------------------- |
|
PATHNODE *__cdecl path_pop_active_step() |
|
{ |
|
return pnode_tblptr[--gdwCurPathStep]; |
|
} |
|
|
|
//----- (004498B6) -------------------------------------------------------- |
|
PATHNODE *__cdecl path_new_step() |
|
{ |
|
PATHNODE *v1; // esi |
|
|
|
if ( pnode_vals[0] == 300 ) |
|
return 0; |
|
v1 = &path_nodes[pnode_vals[0]++]; |
|
memset(v1, 0, 0x34u); |
|
return v1; |
|
}
|
|
|