#include "version.h" #include #include "common.h" #include "npccreate.h" #include "npctemplate.h" #include "char.h" #include "char_data.h" #include "buf.h" #include "object.h" #include "readmap.h" #include "item.h" #include "handletime.h" #include "map_deal.h" typedef struct tagNPC_searchPoint { int floor; int x; int y; }NPC_searchPoint; /* 窒荚NPC毛综月井 */ #define NPC_CREATECHALLENGETIME 1 int all_nosee = 0; /* ㄠ及凛{蝈化及衬毛 no_see 卞 */ int all_nobody = 0; /* ㄠ及凛{蝈化及衬毛 no_body 卞 */ int one_loop_born = 1; /* ㄠ伙□皿匹 嫖戏心请允醒 oneloop_born */ /*------------------------------------------------------------ * 衬毛丹心分允桦赭毛瑁烂允月 * 娄醒 * nobody int 1 及凛反簿手中卅中凛卞勾仁月 * (簿井中化手综月) * (簿井中凶凛及心综月) * 毛仄卅仁卅月 * 忒曰袄 * 综木月凛反 TRUE * 综木卅中凛反 FALSE ------------------------------------------------------------*/ static BOOL NPC_searchCreatePoint( NPC_Create* cr,int nobody,int nosee, NPC_searchPoint* point, BOOL isflying ) { int floor=cr->intdata[NPC_CREATEFLOORID]; int x = cr->intdata[NPC_CREATEBORNLEFTUPX]; int y = cr->intdata[NPC_CREATEBORNLEFTUPY]; int width; int height; int area; int loop; BOOL ret = FALSE; int i, j; width = cr->intdata[NPC_CREATEBORNRIGHTDOWNX] - cr->intdata[NPC_CREATEBORNLEFTUPX] + 1; height = cr->intdata[NPC_CREATEBORNRIGHTDOWNY] - cr->intdata[NPC_CREATEBORNLEFTUPY] + 1; area = width * height; if( nobody == 0 && all_nobody == 0 ) { BOOL found = FALSE; for( i = x ; i <= x +width && found == FALSE; i ++ ) { for( j = y; j <= y + height && found == FALSE; j ++ ) { OBJECT object; for( object = MAP_getTopObj( floor, i,j); object; object = NEXT_OBJECT(object) ) { int objindex = GET_OBJINDEX( object); if( OBJECT_getType(objindex) == OBJTYPE_CHARA ){ if( CHAR_getInt( OBJECT_getIndex(objindex), CHAR_WHICHTYPE ) == CHAR_TYPEPLAYER ) { found = TRUE; break; } } } } } if( found == FALSE ) { return( FALSE); } } for( loop=0 ; loopintdata[NPC_CREATEIGNOREINVINCIBLE] == 0 && CHAR_isInvincibleArea( floor,crx,cry ) ){ continue; } if( nosee == 0 && all_nosee == 0 ) { BOOL found = FALSE; for( i = crx - CHAR_DEFAULTSEESIZ/2 ; i <= crx +CHAR_DEFAULTSEESIZ/2 && found == FALSE ; i ++ ) { for( j = cry - CHAR_DEFAULTSEESIZ/2; j <= cry + CHAR_DEFAULTSEESIZ/2 && found == FALSE; j ++ ) { OBJECT object; for( object = MAP_getTopObj( floor, i,j); object; object = NEXT_OBJECT(object) ) { int objindex = GET_OBJINDEX( object); if( OBJECT_getType(objindex) == OBJTYPE_CHARA ){ if( CHAR_getInt( OBJECT_getIndex(objindex), CHAR_WHICHTYPE ) == CHAR_TYPEPLAYER ) { found = TRUE; break; } } } } } if( found == TRUE ){ return FALSE; } } if( MAP_walkAbleFromPoint( floor,crx,cry,isflying ) == TRUE ){ point->floor = cr->intdata[NPC_CREATEFLOORID]; point->x = crx; point->y = cry; ret = TRUE; break; }else{ } } return( ret ); } typedef struct tagNPC_Correspondfunction { int template; int ch; }NPC_Correspondfunction; static NPC_Correspondfunction correspondfunction[]={ { NPC_TEMPLATEINITFUNC, CHAR_INITFUNC }, { NPC_TEMPLATEWALKPREFUNC, CHAR_WALKPREFUNC }, { NPC_TEMPLATEWALKPOSTFUNC, CHAR_WALKPOSTFUNC }, { NPC_TEMPLATEPREOVERFUNC, CHAR_PREOVERFUNC }, { NPC_TEMPLATEPOSTOVERFUNC, CHAR_POSTOVERFUNC }, { NPC_TEMPLATEWATCHFUNC, CHAR_WATCHFUNC }, { NPC_TEMPLATELOOPFUNC, CHAR_LOOPFUNC }, { NPC_TEMPLATETALKEDFUNC, CHAR_TALKEDFUNC }, { NPC_TEMPLATEDYINGFUNC, CHAR_DYINGFUNC }, { NPC_TEMPLATEPREATTACKEDFUNC,CHAR_PREATTACKEDFUNC }, { NPC_TEMPLATEPOSTATTACKEDFUNC, CHAR_POSTATTACKEDFUNC }, { NPC_TEMPLATEOFFFUNC, CHAR_OFFFUNC }, { NPC_TEMPLATELOOKEDFUNC, CHAR_LOOKEDFUNC }, { NPC_TEMPLATEITEMPUTFUNC, CHAR_ITEMPUTFUNC }, { NPC_TEMPLATESPECIALTALKEDFUNC, CHAR_SPECIALTALKEDFUNC}, { NPC_TEMPLATEWINDOWTALKEDFUNC, CHAR_WINDOWTALKEDFUNC}, #ifdef _USER_CHARLOOPS { NPC_TEMPLATELOOPFUNCTEMP1, CHAR_LOOPFUNCTEMP1}, { NPC_TEMPLATELOOPFUNCTEMP2, CHAR_LOOPFUNCTEMP2}, { NPC_TEMPLATEBATTLEPROPERTY, CHAR_BATTLEPROPERTY}, #endif }; /*------------------------------------------------------------ * 楮醒戊疋□允月 * 娄醒 * ch Char* 平乓仿犯□正 * 忒曰袄 * 卅仄 ------------------------------------------------------------*/ static void NPC_copyFunction( Char* ch, NPC_Template* temp ) { int i; for( i=0 ; ichardata[correspondfunction[i].template].string[0] != '\0' ) strcpysafe( ch->charfunctable[correspondfunction[i].ch].string, sizeof(ch->charfunctable[correspondfunction[i].ch].string), temp->chardata[correspondfunction[i].template].string); } static BOOL NPC_generateNPC( int createindex, int createtemplateindex ) { Char one; NPC_searchPoint sp; int i; NPC_Template* template; NPC_Create* cr; if( NPC_CHECKCREATEINDEX(createindex) && 0 <= createtemplateindex && createtemplateindex < arraysizeof(NPC_create[createindex].templateindex ) && NPC_CHECKTEMPLATEINDEX( NPC_create[createindex].templateindex[createtemplateindex])){ cr = &NPC_create[createindex]; template = &NPC_template[NPC_create[createindex]. templateindex[createtemplateindex]]; }else{ return FALSE; } if( NPC_searchCreatePoint( cr, template->intdata[NPC_TEMPLATEMAKEATNOBODY], template->intdata[NPC_TEMPLATEMAKEATNOSEE], &sp, template->intdata[NPC_TEMPLATEISFLYING]) == FALSE ){ return FALSE; } if( CHAR_getDefaultChar( &one, template->intdata[NPC_TEMPLATETYPE] ) == FALSE ){ return FALSE; } one.data[CHAR_FLOOR] = sp.floor; one.data[CHAR_X] = sp.x; one.data[CHAR_Y] = sp.y; one.data[CHAR_DIR] = cr->intdata[NPC_CREATEDIR]; #ifdef _ADD_ACTION one.data[CHAR_ACTIONSTYLE] = cr->intdata[NPC_CREATEACTION]; #endif one.data[CHAR_BASEBASEIMAGENUMBER] = one.data[CHAR_BASEIMAGENUMBER] = template->intdata[NPC_TEMPLATEIMAGENUMBER]; if( cr->intdata[NPC_CREATEBASEIMAGENUMBER] != -1 ) one.data[CHAR_BASEBASEIMAGENUMBER] = one.data[CHAR_BASEIMAGENUMBER] = cr->intdata[NPC_CREATEBASEIMAGENUMBER]; strcpysafe(one.string[CHAR_NAME].string, sizeof(one.string[CHAR_NAME].string), template->chardata[NPC_TEMPLATECHARNAME].string); if( cr->chardata[NPC_CREATENAME].string[0] != '\0' ){ strcpysafe(one.string[CHAR_NAME].string, sizeof(one.string[CHAR_NAME].string), cr->chardata[NPC_CREATENAME].string); } // Robin 0731 one.data[CHAR_FMINDEX] = cr->intdata[NPC_CREATEFAMILY]; NPC_copyFunctionSetToChar( template-> intdata[NPC_TEMPLATEFUNCTIONINDEX], &one ); NPC_copyFunction( &one, template ); one.data[CHAR_LOOPINTERVAL] = template-> intdata[NPC_TEMPLATELOOPFUNCTIME]; if( cr->arg[createtemplateindex].string[0] != '\0' ){ strcpysafe( one.string[CHAR_NPCARGUMENT].string, sizeof(one.string[CHAR_NPCARGUMENT].string), cr->arg[createtemplateindex].string ); }else{ one.string[CHAR_NPCARGUMENT].string[0] = '\0'; } one.data[CHAR_WHICHTYPE] = CHAR_TYPEENEMY; one.data[CHAR_NPCCREATEINDEX] = createindex; { static struct NPC_Paramtable { int templateindex; int charadataindex; }paramtbl[]={ { NPC_TEMPLATEMINMP, CHAR_MAXMP }, { NPC_TEMPLATEMINSTR, CHAR_STR }, { NPC_TEMPLATEMINTOUGH, CHAR_TOUGH }, }; for( i=0 ; irandomdata[ paramtbl[i].templateindex] ); one.data[paramtbl[i].charadataindex] = one.data[paramtbl[i].charadataindex] + template->intdata[paramtbl[i].templateindex] + randomvalue; } one.data[CHAR_MP] = one.data[CHAR_MAXMP]; } { int itemindex=CHAR_STARTITEMARRAY; for( i = 0 ; i < template->intdata[NPC_TEMPLATEITEMNUM] ; i ++ ){ if( RAND(0,32767) <= template->haveitem[i].haverate ){ if( template->haveitem[i].itemnumber == -1 && template->haveitem[i].havenum > 0 ){ int randomvalue = template->haveitem[i].havenum; randomvalue *= (RAND(90,110))/100.0; one.data[CHAR_GOLD] = min( CHAR_MAXGOLDHAVE, randomvalue ); }else if( itemindex+i < CHAR_MAXITEMHAVE ){ one.indexOfExistItems[itemindex+i] = ITEM_makeItemAndRegist(template->haveitem[i] .itemnumber); } } } } { int charaindex; int objindex; Object obj; charaindex = CHAR_initCharOneArray( &one ); if( charaindex == -1 ){ CHAR_endCharData( &one ); return FALSE; } if( template->intdata[NPC_TEMPLATEISFLYING] ) CHAR_setFlg(charaindex, CHAR_ISFLYING, 1 ); obj.type = OBJTYPE_CHARA; obj.index= charaindex; obj.x = CHAR_getInt(charaindex,CHAR_X); obj.y = CHAR_getInt(charaindex,CHAR_Y); obj.floor = CHAR_getInt(charaindex,CHAR_FLOOR); objindex = initObjectOne( &obj ); if( objindex == -1 ){ CHAR_endCharOneArray( charaindex ); return FALSE; }else{ } CHAR_setWorkInt( charaindex,CHAR_WORKOBJINDEX,objindex ); CHAR_setWorkInt( charaindex,CHAR_WORKNPCTYPE,1); #ifdef _ADD_ACTION //CHAR_WORKACTION CHAR_setWorkInt( charaindex, CHAR_WORKACTION, CHAR_getInt( charaindex, CHAR_ACTIONSTYLE ) ); CHAR_sendWatchEvent( objindex, CHAR_getWorkInt( charaindex, CHAR_WORKACTION) ,NULL,0,TRUE); #else CHAR_sendWatchEvent(objindex,CHAR_ACTSTAND,NULL,0,TRUE); #endif CHAR_complianceParameter( charaindex ); } return TRUE; } void NPC_generateLoop( BOOL checkall ) { int i,j; int CreateOk=0; int enemynum ; static int createcount = 0; /* create及窒 井日蔺爵允月井 */ static struct timeval _store_npc_generateloop_time; if( checkall == FALSE) { if( time_diff_us( NowTime, _store_npc_generateloop_time ) < (1000*1000)){ return; } else { _store_npc_generateloop_time = NowTime; } } for( i=0 ; i < NPC_createnum ; i++ ){ if( createcount >= NPC_createnum ) createcount = 0; enemynum = NPC_getCreateInt( createcount, NPC_CREATEENEMYNUM ); for( j = 0 ; j < enemynum ; j ++ ){ if( NPC_createCheckGenerateFromTime(createcount) == TRUE ){ CreateOk ++; NPC_createInitTime(createcount); if( NPC_generateNPC(createcount,j) == TRUE ){ NPC_createIncreaseEnemynum(createcount); }else{ } } } createcount ++; if( checkall == FALSE && CreateOk >= one_loop_born ){ break; } } }