📄 npc_pattern.cpp
字号:
#include "..\stdafx.h"
#include <mmsystem.h>
#include "DefaultHeader.h"
#include "Path.h"
#include "NPC_Pattern.h"
#include "CItem.h"
#include "OP_Magic.h"
#include "dr_network.h"
#include "RajaSystem.h"
#include "Map.h"
#include "SealStoneGameServer.h"
#include "AIDefine.h"
#include "LTSSupport.h" // LTS NEW LOCALWAR
#include "AIManager.h"
#include "UserManager.h"
#include "AdventManager.h"
#include "ArenaManager.h"
#include "RegenManager.h"
#define HOME_DIST_1AREA 245
#define HOME_DIST_2AREA 625
extern struct CItem_List Item_Ref ;
extern cLocalWarfield* g_pLocalWarfield; // LTS NEW LOCALWAR
extern void SendAttackNPCArea( t_connection c[], int npc );
extern void SendViewTypeChange( int cn, int viewtype );
extern inline int IsNKNation( LPCHARLIST ch );
extern inline int IsHeNK( LPCHARLIST ch, int nation );
extern void CalcResist(int tolerance, CHARLIST* target, int resist_Type);
extern int CheckActivedGroup(); // LTS AI2
extern int CheckEventAttack(); // CSD-031007
extern NPCName_by_Gender NPC_Name_Ref[Num_Of_NPC_Name];
extern NPCLev_to_Exp NPC_Lev_Ref[Num_Of_NPC_Lev] ;
extern NPC_Generation NPC_Gen_Ref[Num_Of_NPC_Generation] ;
extern int NPC_FemaleName_Count;
extern int NPC_MaleName_Count;
extern int NPC_LastName_Count;
int NpcPatternTable[20] =
{
NPC_PATTERN_HOSTILE_,
NPC_PATTERN_FIND_CLOSE_PC_,
NPC_PATTERN_ACCESS_PC_,
NPC_PATTERN_ATTACK_PC_,
NPC_PATTERN_BACKDRAW_,
NPC_PATTERN_RETURN_,
};
#define MAX_ANIMATION 24
#define MAX_PC_ANIMATION_FRAME 40
typedef struct tagPCANIMATIONTABLE
{
int nCount;
BYTE cFrame[ MAX_PC_ANIMATION_FRAME ];
char dx[ MAX_PC_ANIMATION_FRAME ];
char dy[ MAX_PC_ANIMATION_FRAME ];
char attackf[ MAX_PC_ANIMATION_FRAME ];
short wave[ MAX_PC_ANIMATION_FRAME ];
short height[ MAX_PC_ANIMATION_FRAME ];
short effect[ MAX_PC_ANIMATION_FRAME ];
} PCANIMATIONTABLE, *LPPCANIMATIONTABLE;
PCANIMATIONTABLE AnimationTable[ MAX_ANIMATION ];
#define MAX_CHARACTER_SPRITE_ 200 // CSD-030417
int WalkDelayTimeTable[ MAX_CHARACTER_SPRITE_];
int RunDelayTimeTable[ MAX_CHARACTER_SPRITE_];
int HorseDelayTimeTable[ MAX_CHARACTER_SPRITE_];
int movep;
sNPCgeneratePosition NPCgeneratePosition[ MAX_GENERATE_POSITION_];
int NPCgeneratePositionMax;
bool CharMovingThreadStart0;
bool CharMovingThreadStart1;
bool CharMovingThreadStart2;
inline int ran( int r )
{
if( r == 0 ) return 0;
return rand()%r;
}
#define FRAME_PER_SEC 15
// 府畔 : 0捞 酒囱 蔼捞搁 档馒抗惑矫埃.
DWORD ReturnDestTime( LPCHARLIST ch )
{
int dist = ch->MoveLength - ch->MovePathCount;
if( dist <= 0 ) {return 0;}
const DWORD timepertile = ::Get_MoveDelayTime( ch );
const DWORD desttime = global_time + timepertile * (DWORD )dist;
ch->desttime = desttime;
return desttime;
}
void SaveMoveDelayTable()
{ //< CSD-030806 : 1鸥老 捞悼窍绰单 吧府绰 矫埃阑 绵仿
FILE* pFile = fopen("./OutPut/Monster_WalkingTime_mSecPerTile.txt", "wt");
Dbg_Assert(pFile != NULL);
for (int i = 0; i < MAX_CHARACTER_SPRITE_; ++i)
{
fprintf(pFile, "[%03d]%s(%d msec/tile)\n", i, NPC_Gen_Ref[i].Name, WalkDelayTimeTable[i]);
}
fclose(pFile);
} //> CSD-030806
void InitMoveDelayTable( void )
{
int i,j;
double d = 0.;
double framepertile;
char temp[ FILENAME_MAX];
FILE *fp;
for( i = 0 ; i < MAX_CHARACTER_SPRITE_ ; i ++)
{
sprintf( temp, "%s/Char/%03dAniTable.bin", GameServerDataPath, i );
fp = fopen( temp, "rb" );
if( fp )
{
fseek( fp, 20, SEEK_SET );
fseek( fp, 1, SEEK_CUR );
fread( AnimationTable, sizeof( PCANIMATIONTABLE ), MAX_ANIMATION, fp );
fclose(fp);
for( d = 0, j = 0 ; j < AnimationTable[1].nCount ; j ++)
d += (double)AnimationTable[1].dx[j];
if( d )
{
framepertile = TILE_SIZE * (double)AnimationTable[1].nCount / d ;
WalkDelayTimeTable[ i] = (int)(1000 * framepertile / FRAME_PER_SEC);
}
if( i == 0 || i == 1 )
{
for( d = 0, j = 0 ; j < AnimationTable[12].nCount ; j ++) // 崔府扁..
d += (double)AnimationTable[12].dx[j];
if( d )
{
framepertile = TILE_SIZE * (double)AnimationTable[12].nCount / d ;
RunDelayTimeTable[ i] = (int)(1000 * framepertile / FRAME_PER_SEC);
}
for( d = 0, j = 0 ; j < AnimationTable[19].nCount ; j ++) // 富鸥扁....
d += (double)AnimationTable[19].dx[j];
if( d )
{
framepertile = TILE_SIZE * (double)AnimationTable[19].nCount / d ;
HorseDelayTimeTable[ i] = (int)(1000 * framepertile / FRAME_PER_SEC);
}
}
}
else
{
WalkDelayTimeTable[ i] = 700;
RunDelayTimeTable[ i] = 300;
HorseDelayTimeTable[i] = 300;
}
}
}
DWORD Get_MoveDelayTime( CHARLIST *ch )
{
const int movp= ch->CalcMovePower();
if(!movp){return 0;}
DWORD ret = 0;
switch( ch->SprNo )
{
case 0 :
case 1 :
{
switch( ch->MoveType )
{
// walking
case 0 :
{
if( ch->MoveLength <=4 )
{
ret = WalkDelayTimeTable[ ch->SprNo] * 50 / movp;
}
else
{
ret = RunDelayTimeTable[ ch->SprNo] * 50 / movp;
}
}break;
// running
case 1 :
{
ret = RunDelayTimeTable[ ch->SprNo] * 50 / movp;
}break;
// Horsing..
case 2 :
{
ret = HorseDelayTimeTable[ ch->SprNo] * 50 / movp;
}break;
default :
{
ret = 500;
}break;
}
}break;
default :
{
ret = WalkDelayTimeTable[ ch->SprNo] * 50 / movp;
}break;
}
return ret;
}
int InDistance( CHARLIST *s, CHARLIST *d, int dis )
{
if( s->bAlive != ALIVE_ ) return 0;
int sx = s->X;
int sy = s->Y;
int dx = d->X;
int dy = d->Y;
if( dis * dis > (dx-sx)*(dx-sx)+(dy-sy)*(dy-sy) ) return 1;
return 0;
}
bool NPC_CheckMustGoHome(CHARLIST *n,int tx,int ty)
{
DWORD area1, area2;
switch( n->patterntype )
{
case NPC_PATTERN_ACCESS :
case NPC_PATTERN_ATTACK :
case NPC_PATTERN_ATTACKED :
case NPC_PATTERN_BOSS_ACCESS :
case NPC_PATTERN_BOSS_ATTACK :
case NPC_PATTERN_BOSS_ATTACKED :
{
area1 = (n->X/TILE_SIZE - n->homex)*(n->X/TILE_SIZE - n->homex) + (n->Y/TILE_SIZE - n->homey)*(n->Y/TILE_SIZE - n->homey);
area2 = (tx - n->homex)*(tx - n->homex) + (ty - n->homey)*(ty - n->homey);
if( area1 > HOME_DIST_1AREA )
{
if( area2 > HOME_DIST_2AREA )
{
return true;
}
}
break;
}
}
return false;
}
bool NPC_CanReach(CHARLIST *n,int tx,int ty,int *x,int *y)
{
int d, i, j, tempdir;
int ttx, tty;
int dirt[ 5] = { 0,1,-1,-2,2 };
*x = n->X / TILE_SIZE; *y = n->Y / TILE_SIZE;
tempdir = NPC_GetDir( tx, ty, n->X / TILE_SIZE, n->Y / TILE_SIZE );
for( j = 1 ; j < 10 ; j ++)
{
for( i = 0 ; i < 5 ; i ++)
{
ttx = tx; tty = ty;
d = ( tempdir + 8 + dirt[i] ) %8;
switch( d )
{
case 0 : tty +=j; break;
case 1 : ttx -=j; tty +=j; break;
case 2 : ttx -=j; break;
case 3 : ttx -=j; tty -=j; break;
case 4 : tty -=j; break;
case 5 : ttx +=j; tty -=j; break;
case 6 : ttx +=j; break;
case 7 : ttx +=j; tty +=j; break;
}
if(FreeTile( n, n->MoveSx, n->MoveSy, ttx, tty ))
{
*x = ttx; *y = tty;
return true;
}
}
}
return false;
}
int NPC_NearCh( CHARLIST *n, CHARLIST *ch, int *x, int *y ) // LTS NPC MOVE
{
int dirt[ 5] = { 0,1,-1,-2,2 };
int tx = 0, ty = 0;
if( ch == NULL ){return 0;}
tx = ch->MoveSx;
ty = ch->MoveSy;
if (ch->SprNo==0||ch->SprNo==1)
{
tx = ch->MoveGox/TILE_SIZE;
ty = ch->MoveGoy/TILE_SIZE;
}
if (NPC_CheckMustGoHome(n,tx,ty))
{
if (!NPC_CanReach(n,n->homex,n->homey,x,y))
{
if (!NPC_CanReach(n,tx,ty,x,y))
{
return false;
}
}
}
else
{
if (!NPC_CanReach(n,tx,ty,x,y))
{
return false;
}
}
return true;
}
#define TILE_BLOCK_SIZE 11
BYTE TileBlock[ TILE_BLOCK_SIZE][ TILE_BLOCK_SIZE] =
{
{ 0,0,0,0,1,1,1,0,0,0,0 },
{ 0,0,1,1,1,1,1,1,1,0,0 },
{ 0,1,1,1,1,1,1,1,1,1,0 },
{ 0,1,1,1,1,1,1,1,1,1,0 },
{ 1,1,1,1,1,1,1,1,1,1,1 },
{ 1,1,1,1,1,1,1,1,1,1,1 },
{ 1,1,1,1,1,1,1,1,1,1,1 },
{ 0,1,1,1,1,1,1,1,1,1,0 },
{ 0,1,1,1,1,1,1,1,1,1,0 },
{ 0,0,1,1,1,1,1,1,1,0,0 },
{ 0,0,0,0,1,1,1,0,0,0,0 }
};
BYTE TileBlockBuf[ TILE_BLOCK_SIZE][ TILE_BLOCK_SIZE];
// 泅犁困摹俊辑 dist鸥老父怒 第肺 狐柳促.
int NPC_NearBackCh( CHARLIST *n, CHARLIST *ch, int *x, int *y, int dist )
{
int dirt[ 5] = { 0,1,-1,-2,2 };
int d, i, j, tempdir;
int tx, ty;
int ttx, tty;
if( n->targetid == -1 )
{
// n->targetid = NPC_IsWhoNearPC( n, 10 );
// if( n->targetid == -1 )
return 0;
}
// 傍拜 措惑捞 绝绢..
if( !connections[n->targetid].dwAgentConnectionIndex || connections[n->targetid].state < CONNECT_JOIN ) return 0;
if( connections[n->targetid].chrlst.bAlive >= DEAD_ ) return 0;
tx = connections[ n->targetid].chrlst.MoveSx;
ty = connections[ n->targetid].chrlst.MoveSy;
*x = n->MoveSx; *y = n->MoveSy;
tempdir = NPC_GetDir( tx, ty, n->MoveSx, n->MoveSy );
switch( tempdir )
{
case 0 : ty +=dist; break;
case 1 : tx -=dist; ty +=dist; break;
case 2 : tx -=dist; break;
case 3 : tx -=dist; ty -=dist; break;
case 4 : ty -=dist; break;
case 5 : tx +=dist; ty -=dist; break;
case 6 : tx +=dist; break;
case 7 : tx +=dist; ty +=dist; break;
}
for( j = 0 ; j < 10 ; j ++)
{
for( i = 0 ; i < 5 ; i ++)
{
ttx = tx; tty = ty;
d = ( tempdir + 8 + dirt[i] ) %8;
switch( d )
{
case 0 : tty +=j; break;
case 1 : ttx -=j; tty +=j; break;
case 2 : ttx -=j; break;
case 3 : ttx -=j; tty -=j; break;
case 4 : tty -=j; break;
case 5 : ttx +=j; tty -=j; break;
case 6 : ttx +=j; break;
case 7 : ttx +=j; tty +=j; break;
}
if( FreeTile( n, n->MoveSx, n->MoveSy, ttx, tty ) )
{
*x = ttx; *y = tty;
return 1;
}
}
}
return 0;
}
int NPC_GetDir( int sx, int sy, int ex, int ey )
{
if( sx > ex ) // 1/2/3
{
if( sy > ey ) return 3;
else if( sy < ey ) return 1;
else return 2;
}
else if( sx < ex ) // 5/6/7
{
if( sy > ey ) return 5;
else if( sy < ey ) return 7;
else return 6;
}
else
{
if( sy > ey ) return 4;
else if( sy < ey ) return 0;
}
return -1;
}
int NPC_MakePath( CHARLIST *n, int tx, int ty, int how = 0 )
{
int dir;
int c, i;
int nx, ny, px, py;
if( g_block_move )
{
return 0;
}
if (n->MoveP==0) return 0; // LTS AI
n->tx = tx;
n->ty = ty;
n->how = how;
if( n->MovePathCount < 2 )
{
if( PathBuild( n, tx, ty ) == false ) { return 0; }
int bOdd = 0;
if( n->pathcount )
{
px = n->path[ n->pathcount -1][0];
py = n->path[ n->pathcount -1][1];
c = 0;
for( i = n->pathcount -2 ; i >= 0 ; i -- )
{
nx = n->path[i][0];
ny = n->path[i][1];
if( nx > px )
{
if( ny > py ) { dir = 7; }
else if( ny < py ) { dir = 5; }
else { dir = 6; }
}
else if( nx < px )
{
if( ny > py ) { dir = 1; }
else if( ny < py ) { dir = 3; }
else { dir = 2; }
}
else
{
if( ny > py ) { dir = 0; }
else { dir = 4; }
}
if ( bOdd == 0){ n->MoveDirTbl[ (c/2) ] = dir << 4; }
else { n->MoveDirTbl[ (c/2) ] += dir; }
c++;
bOdd = !bOdd;
px = nx;
py = ny;
}
n->MoveLength = c;
n->MovePathCount = 0;
n->MoveGox = tx * TILE_SIZE + 16 -5 + ran(10); // 捞悼困摹啊 函版
n->MoveGoy = ty * TILE_SIZE + 16 -5 + ran(10); // 捞悼困摹啊 函版
n->WalkTime = global_time; // timeGetTime();
n->MoveType = 0;
return 1;
}
return 0;
}
return 0;
}
int NPC_MakePathBumn( CHARLIST *n, int tx, int ty, int how = 0 )
{
int dir;
int c, i;
int nx, ny, px, py;
n->tx = tx;
n->ty = ty;
n->how = how;
if( g_block_move ) return 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -