1
0
Fork 0
devilution/Source/path.cpp

442 lines
9.4 KiB
C++
Raw Normal View History

2018-06-07 02:25:54 +00:00
/*
* UNPUBLISHED -- Rights reserved under the copyright laws of the
* United States. Use of a copyright notice is precautionary only and
* does not imply publication or disclosure.
*
* THIS DOCUMENTATION CONTAINS CONFIDENTIAL AND PROPRIETARY INFORMATION
* OF BLIZZARD ENTERTAINMENT. ANY DUPLICATION, MODIFICATION,
* DISTRIBUTION, OR DISCLOSURE IS STRICTLY PROHIBITED WITHOUT THE PRIOR
* EXPRESS WRITTEN PERMISSION OF BLIZZARD ENTERTAINMENT.
*/
#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;
}