📄 path.cpp
字号:
/*****************************************************************************\
* Copyright (c), Future Entertainment World / Seoul, Republic of Korea *
* All Rights Reserved. *
* *
* This document contains proprietary and confidential information. No *
* parts of this document or the computer program it embodies may be in *
* any way copied, duplicated, reproduced, translated into a different *
* programming language, or distributed to any person, company, or *
* corporation without the prior written consent of Future Entertainment World *
\*****************************************************************************/
#include "stdafx.h"
#include "path.h"
#include "map.h"
#include "Dragon.h"
#include "Hong_Sub.h"
#include "Item.h"
#include "CharDataTable.h"
extern int tool_Pathfind;
///////////////////////////////////////////////////////////////////////////////
//
int PATHCOUNT;
int SHORTPATH[ MAX_SHORTPATH ][ 2 ];
LPSP_NODE GLPSP_OPEN, GLPSP_CLOSED;
LPSP_STACK GLPSP_STACK;
///////////////////////////////////////////////////////////////////////////////
//
BOOL PathBuild( LPCHARACTER lpCharacter );
void PathDestroy( void );
LPSP_NODE PathFind( LPCHARACTER lpcharacter, int sx, int sy, int dx, int dy );
LPSP_NODE PathFind_Monster( LPCHARACTER lpcharacter, int sx, int sy, int dx, int dy );
void GenerateSucc( LPSP_NODE lpspNode, int x, int y, int dx, int dy, int dist );
void PropagateDown( LPSP_NODE lpspNode, int dist );
LPSP_NODE CheckOPEN( int tilenum );
LPSP_NODE CheckCLOSED( int tilenum );
void Insert( LPSP_NODE lpspNode );
void Push( LPSP_NODE lpspNode );
LPSP_NODE Pop( void );
///////////////////////////////////////////////////////////////////////////////
//
int PathCollisionLineCount; // 辨瘉扁俊 荤侩瞪 酒捞袍阑 葛酒 初绰促.
COLLISIONLINE PathCollisionLine[ MAX_ITEM_COLLISION ];
// 010724 KHS
BOOL PathBuild( LPCHARACTER lpCharacter )
{
LPSP_NODE lpspNode;
int sx, sy;
int dx, dy;
dx = lpCharacter->destx, dy = lpCharacter->desty;
if(lpCharacter->nCurrentAction == ACTION_MAGIC_BEFORE) return 0;
sx = lpCharacter->x / TILE_SIZE;
sy = lpCharacter->y / TILE_SIZE;
bool occupied_flag = false;
TILE *pT = &TileMap[ lpCharacter->position.x][lpCharacter->position.y];
if( pT->occupied )
{
pT->occupied = 0;
occupied_flag = true;
}
switch( lpCharacter->sprno )
{
case 0 :
case 1 : lpspNode = PathFind( lpCharacter, sx, sy, dx, dy );
break;
default : lpspNode = PathFind_Monster( lpCharacter, sx, sy, dx, dy );
break;
}
if( occupied_flag ) pT->occupied = 1;
if ( lpspNode == NULL )
{
PathDestroy( );
return FALSE;
}
lpCharacter->path[ 0 ][ 0 ] = dx;
lpCharacter->path[ 0 ][ 1 ] = dy;
lpCharacter->pathcount = 1;
while ( lpspNode->lpParent != NULL )
{
if ( lpCharacter->pathcount >= MAX_SHORTPATH )
{
break;
}
lpspNode = lpspNode->lpParent;
lpCharacter->path[ lpCharacter->pathcount ][ 0 ] = lpspNode->x;
lpCharacter->path[ lpCharacter->pathcount ][ 1 ] = lpspNode->y;
lpCharacter->pathcount++;
}
PathDestroy( );
if ( lpCharacter->pathcount > 1 )
{
return TRUE;
}
return FALSE;
}
void
PathDestroy( void )
{
LPSP_NODE lpspNode, lpspTemp;
if ( GLPSP_OPEN != NULL && GLPSP_CLOSED != NULL && GLPSP_STACK != NULL )
{
lpspNode = GLPSP_OPEN->lpNext;
while( lpspNode != NULL )
{
lpspTemp = lpspNode->lpNext;
GlobalFree( lpspNode );
lpspNode = lpspTemp;
}
lpspNode = GLPSP_CLOSED->lpNext;
while( lpspNode != NULL )
{
lpspTemp = lpspNode->lpNext;
GlobalFree( lpspNode );
lpspNode = lpspTemp;
}
GlobalFree( GLPSP_OPEN );
GlobalFree( GLPSP_CLOSED );
GlobalFree( GLPSP_STACK );
GLPSP_OPEN = NULL;
GLPSP_CLOSED = NULL;
GLPSP_STACK = NULL;
}
}
// 010724-1 KHS
int FreeTile( LPCHARACTER ch, int sx, int sy, int x, int y )
{
TILE *pT;
pT = &TileMap[ x ][ y ];
if( pT->attr_dont ) return 0;
if (!ch->JoinLocalWar && pT->occupied)
{ //< CSD-040322 : 惫瘤傈矫 鸥老阑 痢蜡窍瘤 臼档废 荐沥
return 0;
} //> CSD-040322
#define MAX_AREA_X_ 21 // Map Server狼 Area.h狼 REM_AREA_X客 鞍促.
#define MAX_AREA_Y_ 18
if( ch )
{
int tx, ty;
tx = ch->x / TILE_SIZE - MAX_AREA_X_;
ty = ch->y / TILE_SIZE - MAX_AREA_Y_;
if( x < tx ) return 0;
if( y < ty ) return 0;
if( x > tx + MAX_AREA_X_ + MAX_AREA_X_ ) return 0;
if( y > ty + MAX_AREA_Y_ + MAX_AREA_Y_ ) return 0;
if( ch->notcomeinside ) //甘加己吝 inside加己俊 甸绢坷瘤 给窍绰 某腐磐啊 疽促.
{
if( pT->attr_inside ) return 0;
}
}
if( x < 0 ) return 0;
if( y < 0 ) return 0;
if( x >= g_Map.file.wWidth ) return 0;
if( y >= g_Map.file.wHeight ) return 0;
// 林牢傍捞 Ghost啊 登搁 巩阑 凯鞘夸 绝捞 瘤唱促匆荐 乐促.
if( ch )
if( Hero )
{
if( ch == Hero && Hero->viewtype == VIEWTYPE_GHOST_ )
{
return 1;
}
}
LPITEMGROUND i = g_Item;
while( i != NULL )
{
switch( i->type )
{
case ITEMTYPE_BOX :
break;
case ITEMTYPE_DOOR :
if( i->Anitype == ITEMANIMATION_CLOSED )
{
if( CheckIntersect( i->ddx[ 0], i->ddy[ 0],
i->dsx[ 0], i->dsy[ 0], (sx<<5) + 16, (sy<<5) + 16, (x<<5) + 16, (y<<5) + 16 ) > 0)
{
return 0;
}
}
}
i = i->next;
}
return 1;
}
///////////////////////// 0812 yjs 荐沥 ///////////////////////////////////////////
//1鸥老究 啊搁辑 给哎锭 鳖瘤 眉农...
int Tile_Collision(LPCHARACTER ch, DIRECTION dir, int Power) //绵备傍, 规氢, 塞..
{
LPCHARACTER lpCharacter=Hero->lpNext;//公炼扒 hero啊 力老 菊俊 乐促..
int t_sx = ch->x/TILE_SIZE;// 鸥老 谅钎肺 父电促..
int t_sy = ch->y/TILE_SIZE;
int how_X=0, how_Y=0;
switch(dir)
{
case DIRECTION_DOWN: how_X=0; how_Y=1; break;
case DIRECTION_LEFTDOWN: how_X=-1; how_Y=1; break;
case DIRECTION_LEFT: how_X=-1; how_Y=0; break;
case DIRECTION_LEFTUP: how_X=-1; how_Y=-1; break;
case DIRECTION_UP: how_X=0; how_Y=-1; break;
case DIRECTION_RIGHTUP: how_X=1; how_Y=-1; break;
case DIRECTION_RIGHT: how_X=1; how_Y=0; break;
case DIRECTION_RIGHTDOWN: how_X=1; how_Y=1; break;
}
while ( lpCharacter != NULL ) ///////////////// 唱磊脚捞 傍俊 何碟摹搁 弊成 烹苞窍扼...
{
for(int i=1; i<Power; i++) ////////////// don't鸥老 牢啊? 眉农..///////////
{
t_sx += how_X;
t_sy += how_Y;
if( TileMap[ t_sx ][ t_sy ].attr_dont )
{
if(i == 1)
return -1; //傍苞 don't鸥老捞 嘿绢乐绰 版快......
else
return (i-1); ////////////// 傍捞 哎荐 乐绰 鸥老摆荐.......
}
if( lpCharacter != ch )
if( ch->x/TILE_SIZE + t_sx == lpCharacter->x/TILE_SIZE && ch->y/TILE_SIZE + t_sy == lpCharacter->y/TILE_SIZE)
return(i-1); //唱 捞寇狼 促弗 巴苞 何碟摹搁 给埃促..
}
lpCharacter = lpCharacter->lpNext;
}
return Power;
}
/////////////////////////// 0727 yjs 父惦 ///////////////////////////////
////////屁扁绰 窃荐..
/*void Reaction(LPCHARACTER ch, DIRECTION& old_dir, int& power) //绵备傍, 寒俊 嘎阑锭 规氢, 屁辨锭 规氢, 塞(鸥老窜困)
{
int t_power; // 颇老窜困..
int check;
// int t_X;
// int t_Y;
int count=0;
switch(old_dir)
{
case DIRECTION_DOWN:
do //do...while巩 鸥老窜困肺 眉农秦辑..
{
switch(rand()%3)
{
case 0: t_power = Tile_Collision(ch, DIRECTION_LEFTUP, power); //DIRECTION_LEFTUP
check = power - t_power;
break;
case 1: t_power = Tile_Collision(ch, DIRECTION_UP, power); //DIRECTION_UP:
check = power - t_power;
break;
case 2: t_power = Tile_Collision(ch, DIRECTION_RIGHTUP, power); //DIRECTION_RIGHTUP:
check = power - t_power;
break;
default : power = 0; break;
}
count++;
if(count == 6) power = 0;//3规氢促 给啊绰 荐啊 乐扁锭巩..
}while(check == 0 || count > 6);
break;
case DIRECTION_LEFTDOWN:
do
{
switch(rand()%2)
{
case 0: t_power = Tile_Collision(ch, DIRECTION_UP, power); //DIRECTION_UP:
check = power - t_power;
break;
case 1: t_power = Tile_Collision(ch, DIRECTION_RIGHTUP, power); //DIRECTION_RIGHTUP:
check = power - t_power;
break;
default : power = 0; break;
}
count++;
if(count == 6) power = 0;//2规氢促 给啊绰 荐啊 乐扁锭巩..
}while(check == 0 || count > 6);
break;
case DIRECTION_LEFT:
do
{
t_power = Tile_Collision(ch, DIRECTION_RIGHT, power);
check = power - t_power;
count++;
if(count == 6) power = 0;//给啊绰 荐啊 乐扁锭巩..
}while(check == 0 || count > 6);
break;
case DIRECTION_LEFTUP:
do
{
switch(rand()%2)
{
case 0: t_power = Tile_Collision(ch, DIRECTION_DOWN, power); //DIRECTION_DOWN:
check = power - t_power;
break;
case 1: t_power = Tile_Collision(ch, DIRECTION_RIGHTDOWN, power); //DIRECTION_RIGHTUP:
check = power - t_power;
break;
default : power = 0; break;
}
count++;
if(count == 6) power = 0;//2规氢促 给啊绰 荐啊 乐扁锭巩..
}while(check == 0 || count > 6);
break;
case DIRECTION_UP:
do
{
switch(rand()%2)
{
case 0: t_power = Tile_Collision(ch, DIRECTION_LEFT, power);
check = power - t_power;
case 1: t_power = Tile_Collision(ch, DIRECTION_DOWN, power); //DIRECTION_DOWN:
check = power - t_power;
break;
case 2: t_power = Tile_Collision(ch, DIRECTION_RIGHTDOWN, power); //DIRECTION_RIGHTUP:
check = power - t_power;
break;
default : power = 0; break;
}
count++;
if(count == 6) power = 0;//3规氢促 给啊绰 荐啊 乐扁锭巩..
}while(check == 0 || count > 6);
break;
case DIRECTION_RIGHTUP:
do
{
switch(rand()%2)
{
case 0: t_power = Tile_Collision(ch, DIRECTION_DOWN, power); //DIRECTION_DOWN:
check = power - t_power;
break;
case 1: t_power = Tile_Collision(ch, DIRECTION_LEFTDOWN, power); //DIRECTION_RIGHTUP:
check = power - t_power;
break;
default : power = 0; break;
}
count++;
if(count == 6) power = 0;//2规氢促 给啊绰 荐啊 乐扁锭巩..
}while(check == 0 || count > 6);
break;
case DIRECTION_RIGHT:
do
{
t_power = Tile_Collision(ch, DIRECTION_LEFT, power);
check = power - t_power;
count++;
if(count == 6) power = 0;//给啊绰 荐啊 乐扁锭巩..
}while(check == 0 || count > 6);
break;
case DIRECTION_RIGHTDOWN:
do
{
switch(rand()%2)
{
case 0: t_power = Tile_Collision(ch, DIRECTION_UP, power);
check = power - t_power;
break;
case 1: t_power = Tile_Collision(ch, DIRECTION_LEFTUP, power);
check = power - t_power;
break;
default : power = 0; break;
}
count++;
if(count == 6) power = 0;//2规氢促 给啊绰 荐啊 乐扁锭巩..
}while(check == 0 || count > 6);
break;
default : power = 0; break;
}
}
*//////////////////////////////////////////////////////////////////////////////////////////
int FreeTileLineCheck( LPCHARACTER ch, int sx, int sy, int x, int y )
{
if( TileMap[ x ][ y ].attr_dont ) return 0;
if( x < 0 ) return 0;
if( y < 0 ) return 0;
if( x >= g_Map.file.wWidth ) return 0;
if( y >= g_Map.file.wHeight ) return 0;
if( ch )
if( ch->notcomeinside ) //甘加己吝 inside加己俊 甸绢坷瘤 给窍绰 某腐磐啊 疽促.
{
if( TileMap[x][y].attr_inside ) return 0;
}
int mx = x * TILE_SIZE + 15;
int my = y * TILE_SIZE + 15;
LPITEMGROUND i = g_Item;
while( i != NULL )
{
switch( i->type )
{
case ITEMTYPE_DOOR :
if( i->Anitype == ITEMANIMATION_CLOSED )
{
if( CheckIntersect( i->ddx[ 0], i->ddy[ 0],
i->dsx[ 0], i->dsy[ 0], (sx<<5) + 16, (sy<<5) + 16, (x<<5) + 16, (y<<5) + 16 ) > 0)
{
return 0;
}
}
}
i = i->next;
}
return 1;
}
int FreeTileOther( LPCHARACTER ch, int x, int y )
{
LPCHARACTER lpCharacter = Hero;
DWORD iid;//, tid;
iid = ch->id;
if( iid >= 10000 ) iid -= 10000;
if( TileMap[ x ][ y ].attr_dont ) return 0;
int mx = x * TILE_SIZE + 15;
int my = y * TILE_SIZE + 15;
LPITEMGROUND i = g_Item;
while( i != NULL )
{
switch( i->type )
{
case ITEMTYPE_BOX :
if( i->Anitype == ITEMANIMATION_CLOSED )
{
if( IsInBox( i->dx[0], i->dy[0], i->dx[1], i->dy[1], i->dx[2], i->dy[2], i->dx[3], i->dy[3], mx, my ) > 0 )
return 0;
}
}
i = i->next;
}
return 1;
}
LPSP_NODE
PathFind_Monster( LPCHARACTER lpcharacter, int sx, int sy, int dx, int dy )
{
LPMAPFILE lpMapFile = &g_Map.file;
LPSP_NODE lpspNode, lpspTemp;
int nDestTile = dy * g_Map.file.wWidth + dx;
int x, y;
int c = 0;
int oldx, oldy;
GLPSP_OPEN = ( LPSP_NODE )GlobalAlloc( GPTR, sizeof( SP_NODE ) );
GLPSP_CLOSED = ( LPSP_NODE )GlobalAlloc( GPTR, sizeof( SP_NODE ));
GLPSP_STACK = ( LPSP_STACK )GlobalAlloc( GPTR, sizeof( SP_STACK ) );
lpspNode = ( LPSP_NODE )GlobalAlloc( GPTR, sizeof( SP_NODE ) );
if ( GLPSP_OPEN == NULL || GLPSP_CLOSED == NULL || GLPSP_STACK == NULL || lpspNode == NULL )
{
return NULL;
}
lpspNode->g = 0;
lpspNode->h = 1;//( sx - dx ) * ( sx - dx ) + ( sy - dy ) * ( sy - dy );
lpspNode->f = lpspNode->g + lpspNode->h;
lpspNode->number = sy * g_Map.file.wWidth + sx;
lpspNode->x = sx;
lpspNode->y = sy;
GLPSP_OPEN->lpNext = lpspNode;
while ( 1 )
{
if ( GLPSP_OPEN->lpNext == NULL )
{
return NULL;
}
c++;
if( c > 1000 )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -