📄 npc.c
字号:
while(1) {
for(i=strlen(srcbuf)-1;i>=0 && isspace(srcbuf[i]);i--);
if (i>=0 && srcbuf[i]=='}')
break;
fgets(line,1020,fp);
(*lines)++;
if (feof(fp))
break;
if (strlen(srcbuf)+strlen(line)+1>=srcsize) {
srcsize += 65536;
srcbuf = realloc(srcbuf, srcsize);
if (srcbuf==NULL) {
printf("out of memory : npc_parse_script srcbuf realloc\n");
exit(1);
}
memset(srcbuf + srcsize - 65536, '\0', 65536);
}
if (srcbuf[0]!='{') {
if (strchr(line,'{')) {
strcpy(srcbuf,strchr(line,'{'));
startline=*lines;
}
} else
strcat(srcbuf,line);
}
script=parse_script(srcbuf,startline);
if (script==NULL) {
// script parse error?
free(srcbuf);
return 1;
}
}else{
// duplicate偡傞
char srcname[128];
struct npc_data *nd2;
if( sscanf(w2,"duplicate(%[^)])",srcname)!=1 ){
printf("bad duplicate name! : %s",w2);
return 0;
}
if( (nd2=npc_name2id(srcname))==NULL ){
printf("bad duplicate name! (not exist) : %s\n",srcname);
return 0;
}
script=nd2->u.scr.script;
label_dup=nd2->u.scr.label_list;
label_dupnum=nd2->u.scr.label_list_num;
}// end of 僗僋儕僾僩夝愅
nd=calloc(sizeof(struct npc_data), 1);
if (nd==NULL) {
printf("out of memory : npc_parse_script nd\n");
exit(1);
}
memset(nd,0,sizeof(struct npc_data));
if(m==-1){
// 僗僋儕僾僩僐僺乕梡偺僟儈乕NPC
}else if( sscanf(w4,"%d,%d,%d",&class,&xs,&ys)==3) {
// 愙怗宆NPC
int i,j;
if (xs>=0)xs=xs*2+1;
if (ys>=0)ys=ys*2+1;
if (class>=0) {
for(i=0;i<ys;i++) {
for(j=0;j<xs;j++) {
int t;
t=map_getcell(m,x-xs/2+j,y-ys/2+i);
if (t==1 || t==5)
continue;
map_setcell(m,x-xs/2+j,y-ys/2+i,t|0x80);
}
}
}
nd->u.scr.xs=xs;
nd->u.scr.ys=ys;
} else { // 僋儕僢僋宆NPC
class=atoi(w4);
nd->u.scr.xs=0;
nd->u.scr.ys=0;
}
if (class<0 && m>=0) { // 僀儀儞僩宆NPC
evflag=1;
}
while((p=strchr(w3,':'))) {
if (p[1]==':') break;
}
if (p) {
*p=0;
memcpy(nd->name,w3,24);
memcpy(nd->exname,p+2,24);
}else{
memcpy(nd->name,w3,24);
memcpy(nd->exname,w3,24);
}
nd->bl.prev = nd->bl.next = NULL;
nd->bl.m = m;
nd->bl.x = x;
nd->bl.y = y;
nd->bl.id=npc_id++;
nd->dir = dir;
nd->flag=0;
nd->class=class;
nd->speed=200;
nd->u.scr.script=script;
nd->chat_id=0;
//printf("script npc %s %d %d read done\n",mapname,nd->bl.id,nd->class);
npc_script++;
nd->bl.type=BL_NPC;
nd->bl.subtype=SCRIPT;
if(m>=0){
nd->n=map_addnpc(m,nd);
map_addblock(&nd->bl);
if (evflag) { // 僀儀儞僩宆
struct event_data *ev=calloc(sizeof(struct event_data), 1);
if (ev==NULL) {
printf("npc_parse_script: out of memory !(event_data)\n");
exit(1);
}else{
ev->nd=nd;
ev->pos=0;
strdb_insert(ev_db,nd->exname,ev);
}
}else{
clif_spawnnpc(nd);
}
}
strdb_insert(npcname_db,nd->exname,nd);
//-----------------------------------------
// 儔儀儖僨乕僞偺弨旛
if(srcbuf){
// script杮懱偑偁傞応崌偺張棟
// 儔儀儖僨乕僞偺僐儞僶乕僩
label_db=script_get_label_db();
strdb_foreach(label_db,npc_convertlabel_db,nd);
// 傕偆巊傢側偄偺偱僶僢僼傽夝曻
free(srcbuf);
}else{
// duplicate
memcpy(nd->u.scr.label_list,label_dup,
sizeof(struct npc_label_list)*label_dupnum);
nd->u.scr.label_list_num=label_dupnum;
}
//-----------------------------------------
// 僀儀儞僩梡儔儀儖僨乕僞偺僄僋僗億乕僩
for(i=0;i<nd->u.scr.label_list_num;i++){
char *lname=nd->u.scr.label_list[i].name;
int pos=nd->u.scr.label_list[i].pos;
if ((lname[0]=='O' || lname[0]=='o')&&(lname[1]=='N' || lname[1]=='n')) {
struct event_data *ev;
char *buf;
// 僄僋僗億乕僩偝傟傞
ev=calloc(sizeof(struct event_data), 1);
buf=calloc(50, 1);
if (ev==NULL || buf==NULL) {
printf("npc_parse_script: out of memory !\n");
exit(1);
}else if (strlen(lname)>24) {
printf("npc_parse_script: label name error !\n");
exit(1);
}else{
ev->nd=nd;
ev->pos=pos;
sprintf(buf,"%s::%s",nd->exname,lname);
strdb_insert(ev_db,buf,ev);
}
}
}
//-----------------------------------------
// 儔儀儖僨乕僞偐傜僞僀儅乕僀儀儞僩庢傝崬傒
for(i=0;i<nd->u.scr.label_list_num;i++){
int t=0,k=0;
char *lname=nd->u.scr.label_list[i].name;
int pos=nd->u.scr.label_list[i].pos;
if(sscanf(lname,"OnTimer%d%n",&t,&k)==1 && lname[k]=='\0') {
// 僞僀儅乕僀儀儞僩
struct npc_timerevent_list *te=nd->u.scr.timer_event;
int j,k=nd->u.scr.timeramount;
if(te==NULL) te=malloc(sizeof(struct npc_timerevent_list));
else te=realloc( te, sizeof(struct npc_timerevent_list) * (k+1) );
if(te==NULL){
printf("npc_timerevent_import: out of memory !\n");
exit(1);
}
for(j=0;j<k;j++){
if(te[j].timer>t){
memmove(te+j+1,te+j,sizeof(struct npc_timerevent_list)*(k-j));
break;
}
}
te[j].timer=t;
te[j].pos=pos;
nd->u.scr.timer_event=te;
nd->u.scr.timeramount=k+1;
}
return 0;
}
nd->u.scr.nexttimer=-1;
nd->u.scr.timerid=-1;
return 0;
}
/*==========================================
* mob峴夝愅
*------------------------------------------
*/
int npc_parse_mob(char *w1,char *w2,char *w3,char *w4)
{
int m,x,y,xs,ys,class,num,delay1,delay2;
int i;
char mapname[24];
char eventname[24]="";
struct mob_data *md,*base;
xs=ys=0;
delay1=delay2=0;
// 堷悢偺屄悢僠僃僢僋
if (sscanf(w1,"%[^,],%d,%d,%d,%d",mapname,&x,&y,&xs,&ys) < 3 ||
sscanf(w4,"%d,%d,%d,%d,%s",&class,&num,&delay1,&delay2,eventname) < 2 ) {
printf("bad monster line : %s\n",w3);
return 1;
}
m=map_mapname2mapid(mapname);
if ( num>1 && battle_config.mob_count_rate!=100) {
if ( (num=num*battle_config.mob_count_rate/100)<1 )
num=1;
}
base=calloc(sizeof(struct mob_data)*num, 1);
if (base==NULL) {
printf("out of memory : npc_parse_mob\n");
exit(1);
}
for(i=0;i<num;i++) {
md=&base[i];
md->bl.prev=NULL;
md->bl.next=NULL;
md->bl.m=m;
md->bl.x=x;
md->bl.y=y;
memcpy(md->name,w3,24);
md->n = i;
md->base_class = md->class = class;
md->bl.id=npc_id++;
md->m =m;
md->x0=x;
md->y0=y;
md->xs=xs;
md->ys=ys;
md->spawndelay1=delay1;
md->spawndelay2=delay2;
memset(&md->state,0,sizeof(md->state));
md->timer = -1;
md->target_id=0;
md->attacked_id=0;
md->speed=mob_db[class].speed;
if (mob_db[class].mode&0x02) {
md->lootitem=calloc(sizeof(struct item)*LOOTITEM_SIZE, 1);
if (md->lootitem==NULL) {
printf("out of memory : npc_parse_mob\n");
exit(1);
}
memset(md->lootitem, 0, sizeof(struct item) * LOOTITEM_SIZE);
}
else
md->lootitem=NULL;
if (strlen(eventname)>=4) {
memcpy(md->npc_event,eventname,24);
}else
memset(md->npc_event,0,24);
md->bl.type=BL_MOB;
map_addiddb(&md->bl);
mob_spawn(md->bl.id);
npc_mob++;
}
//printf("warp npc %s %d read done\n",mapname,nd->bl.id);
return 0;
}
/*==========================================
* 儅僢僾僼儔僌峴偺夝愅
*------------------------------------------
*/
static int npc_parse_mapflag(char *w1,char *w2,char *w3,char *w4)
{
int m;
char mapname[24],savemap[16];
int savex,savey;
// 堷悢偺屄悢僠僃僢僋
// if ( sscanf(w1,"%[^,],%d,%d,%d",mapname,&x,&y,&dir) != 4 )
if ( sscanf(w1,"%[^,]",mapname) != 1 )
return 1;
m=map_mapname2mapid(mapname);
if (m<0)
return 1;
//儅僢僾僼儔僌
if ( strcmpi(w3,"nosave")==0) {
if (strcmp(w4,"SavePoint")==0) {
memcpy(map[m].save.map,"SavePoint",16);
map[m].save.x=-1;
map[m].save.y=-1;
}else if (sscanf(w4,"%[^,],%d,%d",savemap,&savex,&savey)==3) {
memcpy(map[m].save.map,savemap,16);
map[m].save.x=savex;
map[m].save.y=savey;
}
map[m].flag.nosave=1;
}
else if (strcmpi(w3,"nomemo")==0) {
map[m].flag.nomemo=1;
}
else if (strcmpi(w3,"noteleport")==0) {
map[m].flag.noteleport=1;
}
else if (strcmpi(w3,"noreturn")==0) {
map[m].flag.noreturn=1;
}
else if (strcmpi(w3,"monster_noteleport")==0) {
map[m].flag.monster_noteleport=1;
}
else if (strcmpi(w3,"nobranch")==0) {
map[m].flag.nobranch=1;
}
else if (strcmpi(w3,"nopenalty")==0) {
map[m].flag.nopenalty=1;
}
else if (strcmpi(w3,"pvp")==0) {
map[m].flag.pvp=1;
}
else if (strcmpi(w3,"pvp_noparty")==0) {
map[m].flag.pvp_noparty=1;
}
else if (strcmpi(w3,"pvp_noguild")==0) {
map[m].flag.pvp_noguild=1;
}
else if (strcmpi(w3,"gvg")==0) {
map[m].flag.gvg=1;
}
else if (strcmpi(w3,"gvg_noparty")==0) {
map[m].flag.gvg_noparty=1;
}
else if (strcmpi(w3,"nozenypenalty")==0) {
map[m].flag.nozenypenalty=1;
}
return 0;
}
/*==========================================
* npc弶婜壔
*------------------------------------------
*/
int do_init_npc(void)
{
struct npc_src_list *nsl;
FILE *fp;
char line[1024];
int m,lines;
ev_db=strdb_init(24);
npcname_db=strdb_init(24);
memset(&ev_tm_b,-1,sizeof(ev_tm_b));
for(nsl=npc_src_first;nsl;nsl=nsl->next) {
fp=fopen(nsl->name,"r");
if (fp==NULL) {
printf("file not found : %s\n",nsl->name);
exit(1);
}
lines=0;
while(fgets(line,1020,fp)) {
char w1[1024],w2[1024],w3[1024],w4[1024],mapname[1024];
int i,j,w4pos,count;
lines++;
if (line[0] == '/' && line[1] == '/')
continue;
// 晄梫側僗儁乕僗傗僞僽偺楢懕偼媗傔傞
for(i=j=0;line[i];i++) {
if (line[i]==' ') {
if (!((line[i+1] && (isspace(line[i+1]) || line[i+1]==',')) ||
(j && line[j-1]==',')))
line[j++]=' ';
} else if (line[i]=='\t') {
if (!(j && line[j-1]=='\t'))
line[j++]='\t';
} else
line[j++]=line[i];
}
// 嵟弶偼僞僽嬫愗傝偱僠僃僢僋偟偰傒偰丄僟儊側傜僗儁乕僗嬫愗傝偱妋擣
if ((count=sscanf(line,"%[^\t]\t%[^\t]\t%[^\t\r\n]\t%n%[^\t\r\n]",w1,w2,w3,&w4pos,w4)) < 3 &&
(count=sscanf(line,"%s%s%s%n%s",w1,w2,w3,&w4pos,w4)) < 3) {
continue;
}
// 儅僢僾偺懚嵼妋擣
if( strcmp(w1,"-")!=0 ){
sscanf(w1,"%[^,]",mapname);
m = map_mapname2mapid(mapname);
if (strlen(mapname)>16 || m<0) {
// "mapname" is not assigned to this server
continue;
}
}
if (strcmpi(w2,"warp")==0 && count > 3) {
npc_parse_warp(w1,w2,w3,w4);
} else if (strcmpi(w2,"shop")==0 && count > 3) {
npc_parse_shop(w1,w2,w3,w4);
} else if (strcmpi(w2,"script")==0 && count > 3) {
npc_parse_script(w1,w2,w3,w4,line+w4pos,fp,&lines);
} else if ((i=0,sscanf(w2,"duplicate%n",&i), (i>0 && w2[i]=='(')) && count > 3) {
npc_parse_script(w1,w2,w3,w4,line+w4pos,fp,&lines);
} else if (strcmpi(w2,"monster")==0 && count > 3) {
npc_parse_mob(w1,w2,w3,w4);
} else if (strcmpi(w2,"mapflag")==0 && count >= 3) {
npc_parse_mapflag(w1,w2,w3,w4);
}
}
fclose(fp);
printf("read npc %s done\n",nsl->name);
}
printf("total %d npcs (%d warp, %d shop, %d script, %d mob)\n",
npc_id-START_NPC_NUM,npc_warp,npc_shop,npc_script,npc_mob);
add_timer_func_list(npc_event_timer,"npc_event_timer");
add_timer_func_list(npc_event_do_clock,"npc_event_do_clock");
add_timer_func_list(npc_timerevent,"npc_timerevent");
//exit(1);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -