diff options
Diffstat (limited to 'src/map/npc.c')
-rw-r--r-- | src/map/npc.c | 329 |
1 files changed, 193 insertions, 136 deletions
diff --git a/src/map/npc.c b/src/map/npc.c index d6e219e48..069597f83 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -128,6 +128,15 @@ struct npc_data* npc_name2id(const char *name) { return (struct npc_data *) strdb_search(npcname_db,name); } + +void ev_release(struct dbn *db, int which) +{ + if (which & 0x1) + aFree(db->key); + if (which & 0x2) + aFree(db->data); +} + /*========================================== * イベントキューのイベント処理 *------------------------------------------ @@ -164,25 +173,6 @@ int npc_event_dequeue(struct map_session_data *sd) return 0; } - - - -int npc_delete(struct npc_data *nd) -{ - nullpo_retr(1, nd); - - if(nd->bl.prev == NULL) - return 1; - -#ifdef PCRE_SUPPORT - npc_chat_finalize(nd); -#endif - - clif_clearchar_area(&nd->bl,1); - map_delblock(&nd->bl); - return 0; -} - /*========================================== * イベントの遅延実行 *------------------------------------------ @@ -1366,6 +1356,56 @@ int npc_stop_walking(struct npc_data *nd,int type) return 0; } +int npc_remove_map (struct npc_data *nd) +{ + nullpo_retr(1, nd); + + if(nd->bl.prev == NULL) + return 1; + +#ifdef PCRE_SUPPORT + npc_chat_finalize(nd); +#endif + clif_clearchar_area(&nd->bl,2); + strdb_erase(npcname_db, nd->name); + map_delblock(&nd->bl); + map_deliddb(&nd->bl); + + return 0; +} + +int npc_unload(struct npc_data *nd) +{ + nullpo_retr (0, nd); + + if (nd->chat_id) { + struct chat_data *cd = (struct chat_data*)map_id2bl(nd->chat_id); + if (cd) aFree (cd); + cd = NULL; + } + if (nd->bl.subtype == SCRIPT) { + if (nd->u.scr.timerid != -1) + delete_timer(nd->u.scr.timerid, npc_timerevent); + npc_cleareventtimer (nd); + if (nd->u.scr.timer_event) + aFree(nd->u.scr.timer_event); + if (nd->u.scr.src_id == 0) { + if(nd->u.scr.script) { + aFree(nd->u.scr.script); + nd->u.scr.script = NULL; + } + if (nd->u.scr.label_list) { + aFree(nd->u.scr.label_list); + nd->u.scr.label_list = NULL; + } + } + } + npc_remove_map (nd); + aFree(nd); + nd = NULL; + + return 0; +} // // 初期化関係 @@ -1798,6 +1838,11 @@ static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line nd->n=map_addnpc(m,nd); map_addblock(&nd->bl); + // clear event timers upon initialise + memset(nd->eventqueue, 0, sizeof(nd->eventqueue)); + for(i = 0; i < MAX_EVENTTIMER; i++) + nd->eventtimer[i] = -1; + if (evflag) { // イベント型 struct event_data *ev=(struct event_data *)aCalloc(1,sizeof(struct event_data)); ev->nd=nd; @@ -2240,6 +2285,74 @@ static int npc_parse_mapflag(char *w1,char *w2,char *w3,char *w4) return 0; } +void npc_parsesrcfile(char *name) +{ + int m, lines = 0; + char line[1024]; + + FILE *fp = fopen (name,"r"); + if (fp == NULL) { + ShowError ("File not found : %s\n", name); + exit(1); + } + current_file = name; + + 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 && strcmpi(w1,"function") != 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) { + if (strcmpi(w1,"function") == 0) { + npc_parse_function(w1,w2,w3,w4,line+w4pos,fp,&lines); + } else { + 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); + + return; +} + static int npc_read_indoors(void) { char *buf,*p; @@ -2272,37 +2385,7 @@ static int npc_read_indoors(void) return 0; } -static int npc_unload(struct npc_data *nd) -{ - struct chat_data *cd; - - nullpo_retr (0, nd); - if (nd->chat_id && (cd=(struct chat_data*)map_id2bl(nd->chat_id))){ - aFree (cd); - cd = NULL; - } - if (nd->bl.subtype == SCRIPT) { - if (nd->u.scr.timer_event) - aFree(nd->u.scr.timer_event); - if (nd->u.scr.src_id==0) { - if(nd->u.scr.script) { - aFree(nd->u.scr.script); - nd->u.scr.script=NULL; - } - if (nd->u.scr.label_list) { - aFree(nd->u.scr.label_list); - nd->u.scr.label_list = NULL; - } - } - } - clif_clearchar_area(&nd->bl, 2); - map_delblock(&nd->bl); - map_deliddb(&nd->bl); - aFree(nd); - nd = NULL; - return 0; -} static int ev_db_final(void *key,void *data,va_list ap) { aFree(data); @@ -2318,25 +2401,70 @@ static int npcname_db_final(void *key,void *data,va_list ap) * *------------------------------------------ */ +int npc_cleanup_sub (struct block_list *bl, va_list ap) { + nullpo_retr(0, bl); + + switch(bl->type) { + case BL_NPC: + npc_unload((struct npc_data *)bl); + break; + case BL_MOB: + mob_unload((struct mob_data *)bl); + break; + } + + return 0; +} int npc_reload(void) { - struct npc_data *nd; - struct block_list *bl; - int i; + struct npc_src_list *nsl; + int m, last_npc_id; + time_t last_time = time(0); + int busy = 0; + char c = '-'; - if(ev_db) + for (m = 0; m < map_num; m++) { + map_foreachinarea(npc_cleanup_sub, m, 0, 0, map[m].xs, map[m].ys, 0); + map[m].npc_num = 0; + } + if(ev_db) strdb_final(ev_db,ev_db_final); if(npcname_db) strdb_final(npcname_db,npcname_db_final); - for (i = START_NPC_NUM; i < npc_id; i++) { - if((bl = map_id2bl(i)) && bl->type == BL_NPC && (nd = (struct npc_data *)bl)) - npc_unload(nd); + // anything else we should cleanup? + // Reloading npc's now + ev_db = strdb_init(51); + npcname_db = strdb_init(24); + ev_db->release = ev_release; + npc_warp = npc_shop = npc_script = npc_mob = 0; + last_npc_id = npc_id; + + for (nsl = npc_src_first; nsl; nsl = nsl->next) { + npc_parsesrcfile(nsl->name); + printf("\r"); + ShowStatus("Loading NPCs... Working: "); + if (last_time != time(0)) { + last_time = time(0); + switch(busy) { + case 0: c='\\'; busy++; break; + case 1: c='|'; busy++; break; + case 2: c='/'; busy++; break; + case 3: c='-'; busy=0; + } + } + printf("[%c]",c); + fflush(stdout); } + printf("\r"); + ShowInfo ("Done loading '"CL_WHITE"%d"CL_RESET"' NPCs:%30s\n\t-'" + CL_WHITE"%d"CL_RESET"' Warps\n\t-'" + CL_WHITE"%d"CL_RESET"' Shops\n\t-'" + CL_WHITE"%d"CL_RESET"' Scripts\n\t-'" + CL_WHITE"%d"CL_RESET"' Mobs\n", + npc_id - last_npc_id, "", npc_warp, npc_shop, npc_script, npc_mob); return 0; - - } /*========================================== * 終了 @@ -2378,15 +2506,6 @@ int do_final_npc(void) return 0; } - -void ev_release(struct dbn *db, int which) -{ - if (which & 0x1) - aFree(db->key); - if (which & 0x2) - aFree(db->data); -} - /*========================================== * npc初期化 *------------------------------------------ @@ -2394,9 +2513,6 @@ void ev_release(struct dbn *db, int which) int do_init_npc(void) { struct npc_src_list *nsl; - FILE *fp; - char line[1024]; - int m,lines; time_t last_time = time(0); int busy = 0; char c = '-'; @@ -2411,75 +2527,17 @@ int do_init_npc(void) //ev_db=strdb_init(24); ev_db = strdb_init(51); npcname_db = strdb_init(24); - ev_db->release = ev_release; - memset(&ev_tm_b,-1,sizeof(ev_tm_b)); + memset(&ev_tm_b, -1, sizeof(ev_tm_b)); - for(nsl=npc_src_first;nsl;nsl=nsl->next) { + for (nsl = npc_src_first; nsl; nsl = nsl->next) { /*if(nsl->prev){ // [Shinomori] aFree(nsl->prev); nsl->prev = NULL; }*/ - fp=fopen(nsl->name,"r"); - if (fp==NULL) { - printf("file not found : %s\n",nsl->name); - exit(1); - } - current_file=nsl->name; - 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 && strcmpi(w1,"function")!=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) { - if( strcmpi(w1,"function")==0 ){ - npc_parse_function(w1,w2,w3,w4,line+w4pos,fp,&lines); - }else{ - 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); + // + npc_parsesrcfile(nsl->name); current_file = NULL; printf("\r"); ShowStatus("Loading NPCs... Working: "); @@ -2498,14 +2556,13 @@ int do_init_npc(void) // fflush(stdout); } printf("\r"); - sprintf(tmp_output,"Done loading '"CL_WHITE"%d"CL_RESET"' NPCs:%30s\n\t-'" + ShowInfo ("Done loading '"CL_WHITE"%d"CL_RESET"' NPCs:%30s\n\t-'" CL_WHITE"%d"CL_RESET"' Warps\n\t-'" CL_WHITE"%d"CL_RESET"' Shops\n\t-'" CL_WHITE"%d"CL_RESET"' Scripts\n\t-'" CL_WHITE"%d"CL_RESET"' Mobs\n", - npc_id-START_NPC_NUM,"",npc_warp,npc_shop,npc_script,npc_mob); - ShowInfo(tmp_output); - + npc_id - START_NPC_NUM, "", npc_warp, npc_shop, npc_script, npc_mob); + add_timer_func_list(npc_walktimer,"npc_walktimer"); // [Valaris] add_timer_func_list(npc_event_timer,"npc_event_timer"); add_timer_func_list(npc_event_do_clock,"npc_event_do_clock"); |