From a6cd6538e4271ea08dc86803e8b7e8c8f235960b Mon Sep 17 00:00:00 2001 From: celest Date: Thu, 7 Apr 2005 15:14:35 +0000 Subject: * Readded @disablenpc * Fixed @reloadscript not removing old NPC's and monsters first * Some changes in mob and NPC unloading * Changed the original @disablenpc to @hidenpc git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/branches/stable@1429 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-SVN.txt | 9 ++ conf-tmpl/atcommand_athena.conf | 3 + npc/jobs/custom/jobchange.txt | 2 +- src/map/atcommand.c | 33 +++- src/map/atcommand.h | 1 + src/map/clif.c | 30 ++-- src/map/map.c | 4 +- src/map/mob.c | 40 +++-- src/map/mob.h | 4 +- src/map/npc.c | 329 +++++++++++++++++++++++----------------- src/map/npc.h | 4 +- src/map/pet.c | 3 +- 12 files changed, 290 insertions(+), 172 deletions(-) diff --git a/Changelog-SVN.txt b/Changelog-SVN.txt index d0c7228af..3c1ce0665 100644 --- a/Changelog-SVN.txt +++ b/Changelog-SVN.txt @@ -1,6 +1,15 @@ Date Added +04/07 + * Readded @disablenpc (not the same as @hidenpc) [celest] + * Fixed @reloadscript not removing old NPC's and monsters first [celest] + * Some changes in mob and NPC unloading [celest] + * Changed the original @disablenpc to @hidenpc [celest] + * Fixed HP Conversion to properly not reduce HP if SP is full [celest] + * Updated Defender -- should reduce walking speed, and does not reduce attack speed + at level 5 [celest] + 04/06 * Fixed a crash in clif_send when checking packet version, thanks to Alex14 * Fixed a crash in Deluge, Volcano and Violent Gale, thanks to Alex14 diff --git a/conf-tmpl/atcommand_athena.conf b/conf-tmpl/atcommand_athena.conf index 2d114a82c..4ba317603 100644 --- a/conf-tmpl/atcommand_athena.conf +++ b/conf-tmpl/atcommand_athena.conf @@ -567,6 +567,9 @@ enablenpc: 80 // Disables a NPC. disablenpc: 80 +// Hides a NPC. +hidenpc: 80 + // Move a NPC npcmove: 80 diff --git a/npc/jobs/custom/jobchange.txt b/npc/jobs/custom/jobchange.txt index 4f233ea0d..79e4de332 100644 --- a/npc/jobs/custom/jobchange.txt +++ b/npc/jobs/custom/jobchange.txt @@ -61,7 +61,7 @@ Llevelcheck: Ladvclasses: if(SkillPoint != 0) goto Lskillpt; //Lord Knight & Paladin - if(oldclass == 7 && readparam(19) == 4001 || oldclass == 14 && readparam(19) == 4001) goto Lswordsmanhigh; + if(oldclass == 7 && readparam(19) == 4001 || oldclass == 13 && readparam(19) == 4001 || oldclass == 14 && readparam(19) == 4001 || oldclass == 21 && readparam(19) == 4001) goto Lswordsmanhigh; if(readparam(19) == 4002 && oldclass == 7) goto Llordknight; if(readparam(19) == 4002 && oldclass == 14) goto Lpaladin; //Assassin Cross & Stalker diff --git a/src/map/atcommand.c b/src/map/atcommand.c index a420147bc..79e3ec675 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -167,6 +167,7 @@ ACMD_FUNC(guildrecall); // by Yor ACMD_FUNC(partyrecall); // by Yor ACMD_FUNC(nuke); // [Valaris] ACMD_FUNC(enablenpc); +ACMD_FUNC(hidenpc); ACMD_FUNC(disablenpc); ACMD_FUNC(servertime); // by Yor ACMD_FUNC(chardelitem); // by Yor @@ -433,6 +434,7 @@ static AtCommandInfo atcommand_info[] = { { AtCommand_PartyRecall, "@partyrecall", 60, atcommand_partyrecall }, // by Yor { AtCommand_Nuke, "@nuke", 60, atcommand_nuke }, // [Valaris] { AtCommand_Enablenpc, "@enablenpc", 80, atcommand_enablenpc }, // [] + { AtCommand_Hidenpc, "@hidenpc", 80, atcommand_hidenpc }, // [] { AtCommand_Disablenpc, "@disablenpc", 80, atcommand_disablenpc }, // [] { AtCommand_ServerTime, "@time", 0, atcommand_servertime }, // by Yor { AtCommand_ServerTime, "@date", 0, atcommand_servertime }, // by Yor @@ -5735,9 +5737,9 @@ int atcommand_reloadscript( rehash(); atcommand_broadcast( fd, sd, "@broadcast", "Reloading NPCs..." ); - do_init_npc(); + //do_init_npc(); do_init_script(); - + npc_reload(); npc_event_do_oninit(); clif_displaymessage(fd, msg_table[100]); // Scripts reloaded. @@ -6183,7 +6185,7 @@ int atcommand_enablenpc(const int fd, struct map_session_data* sd, * *------------------------------------------ */ -int atcommand_disablenpc(const int fd, struct map_session_data* sd, +int atcommand_hidenpc(const int fd, struct map_session_data* sd, const char* command, const char* message) { char NPCname[100]; @@ -6207,6 +6209,31 @@ int atcommand_disablenpc(const int fd, struct map_session_data* sd, return 0; } +int atcommand_disablenpc(const int fd, struct map_session_data* sd, + const char* command, const char* message) +{ + struct npc_data *nd; + char NPCname[100]; + nullpo_retr(-1, sd); + + memset(NPCname, '\0', sizeof(NPCname)); + + if (!message || !*message || sscanf(message, "%99[^\n]", NPCname) < 1) { + clif_displaymessage(fd, "Please, enter a NPC name (usage: @npcoff )."); + return -1; + } + + if ((nd = npc_name2id(NPCname)) != NULL) { + npc_unload(nd); + clif_displaymessage(fd, msg_table[112]); // Npc Disabled. + } else { + clif_displaymessage(fd, msg_table[111]); // This NPC doesn't exist. + return -1; + } + + return 0; +} + /*========================================== * time in txt for time command (by [Yor]) *------------------------------------------ diff --git a/src/map/atcommand.h b/src/map/atcommand.h index a9678d6a3..1160dccb7 100644 --- a/src/map/atcommand.h +++ b/src/map/atcommand.h @@ -145,6 +145,7 @@ enum AtCommandType { AtCommand_PartyRecall, // by Yor AtCommand_Nuke, // [Valaris] AtCommand_Enablenpc, + AtCommand_Hidenpc, AtCommand_Disablenpc, AtCommand_ServerTime, // by Yor AtCommand_CharDelItem, // by Yor diff --git a/src/map/clif.c b/src/map/clif.c index 50031a44f..c8f190c5a 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -242,12 +242,11 @@ int clif_foreachclient(int (*func)(struct map_session_data*, va_list),...) */ int clif_send_sub(struct block_list *bl, va_list ap) { - unsigned char *buf; - int len; struct block_list *src_bl; - int type; struct map_session_data *sd; - + unsigned char *buf; + int len, type; + nullpo_retr(0, bl); nullpo_retr(0, ap); nullpo_retr(0, sd = (struct map_session_data *)bl); @@ -259,20 +258,23 @@ int clif_send_sub(struct block_list *bl, va_list ap) switch(type) { case AREA_WOS: - if (bl && bl == src_bl) + if (bl == src_bl) return 0; break; case AREA_WOC: - if ((sd && sd->chatID) || (bl && bl == src_bl)) + if (sd->chatID || bl == src_bl) return 0; break; case AREA_WOSC: - if ((sd) && sd->chatID && sd->chatID == ((struct map_session_data*)src_bl)->chatID) - return 0; + { + struct map_session_data *ssd = (struct map_session_data *)src_bl; + if (ssd && sd->chatID && sd->chatID == ssd->chatID) + return 0; + } break; } - if ((sd != NULL) && (session[sd->fd] != NULL)) { + if (session[sd->fd] != NULL) { if (WFIFOP(sd->fd,0) == buf) { printf("WARNING: Invalid use of clif_send function\n"); printf(" Packet x%4x use a WFIFO of a player instead of to use a buffer.\n", WBUFW(buf,0)); @@ -10686,10 +10688,16 @@ static int clif_parse(int fd) { // get packet version before to parse packet_ver = 0; - if (sd) + if (sd) { packet_ver = sd->packet_ver; + if (packet_ver < 0 || packet_ver > MAX_PACKET_VER) { // unusual, but just in case + close(fd); + session[fd]->eof = 1; + printf("clif_parse: session #%d, bad packet version -> disconnected.\n", fd); + return 0; + } // check authentification packet to know packet version - else { + } else { // packet DB if (IS_PACKET_DB_VER (cmd)) { if (RFIFOREST(fd) >= packet_db[clif_config.packet_db_ver][cmd].len && diff --git a/src/map/map.c b/src/map/map.c index 14665fd54..386b38954 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -3131,10 +3131,10 @@ int cleanup_sub(struct block_list *bl, va_list ap) { map_quit((struct map_session_data *) bl); break; case BL_NPC: - npc_delete((struct npc_data *)bl); + npc_unload((struct npc_data *)bl); break; case BL_MOB: - mob_delete((struct mob_data *)bl); + mob_unload((struct mob_data *)bl); break; case BL_PET: pet_remove_map((struct map_session_data *)bl); diff --git a/src/map/mob.c b/src/map/mob.c index cd096cabd..f076b7530 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -914,7 +914,8 @@ int mob_spawn(int id) struct mob_data *md; struct block_list *bl; - nullpo_retr(-1, bl=map_id2bl(id)); + //nullpo_retr(-1, bl=map_id2bl(id)); + bl=map_id2bl(id); if(!bl || !bl->type || bl->type!=BL_MOB) return -1; @@ -2106,42 +2107,49 @@ static int mob_delay_item_drop2(int tid,unsigned int tick,int id,int data) * mob data is erased. *------------------------------------------ */ -int mob_delete(struct mob_data *md) +void mob_unload(struct mob_data *md) +{ + nullpo_retv(md); + mob_remove_map(md, 0); + map_deliddb(&md->bl); + aFree(md); + md = NULL; +} +int mob_remove_map(struct mob_data *md, int type) { nullpo_retr(1, md); if(md->bl.prev == NULL) return 1; mob_changestate(md,MS_DEAD,0); - clif_clearchar_area(&md->bl,1); + clif_clearchar_area(&md->bl,type); map_delblock(&md->bl); - if(mob_get_viewclass(md->class_) <= 1000) - clif_clearchar_delay(gettick()+3000,&md->bl,0); - mob_deleteslave(md); - mob_setdelayspawn(md->bl.id); + if (md->lootitem){ + aFree(md->lootitem); + md->lootitem = NULL; + } + return 0; } - -int mob_catch_delete(struct mob_data *md,int type) +int mob_delete(struct mob_data *md) { nullpo_retr(1, md); - if(md->bl.prev == NULL) - return 1; - mob_changestate(md,MS_DEAD,0); - clif_clearchar_area(&md->bl,type); - map_delblock(&md->bl); + mob_remove_map(md, 1); + if (mob_get_viewclass(md->class_) <= 1000) + clif_clearchar_delay(gettick()+3000,&md->bl,0); + mob_deleteslave(md); mob_setdelayspawn(md->bl.id); return 0; } - int mob_timer_delete(int tid, unsigned int tick, int id, int data) { struct mob_data *md=(struct mob_data *)map_id2bl(id); nullpo_retr(0, md); //for Alchemist CANNIBALIZE [Lupus] - mob_catch_delete(md,3); + mob_remove_map(md, 3); + mob_setdelayspawn(md->bl.id); return 0; } diff --git a/src/map/mob.h b/src/map/mob.h index e5e95879e..6613c5b6b 100644 --- a/src/map/mob.h +++ b/src/map/mob.h @@ -105,6 +105,7 @@ int mob_target(struct mob_data *md,struct block_list *bl,int dist); int mob_stop_walking(struct mob_data *md,int type); int mob_stopattack(struct mob_data *); int mob_spawn(int); +int mob_setdelayspawn(int); int mob_damage(struct block_list *,struct mob_data*,int,int); int mob_changestate(struct mob_data *md,int state,int type); int mob_heal(struct mob_data*,int); @@ -123,8 +124,9 @@ short mob_get_clothes_color(int); //player mob dye [Valaris] int mob_get_equip(int); // mob equip [Valaris] int do_init_mob(void); +void mob_unload(struct mob_data *md); +int mob_remove_map(struct mob_data *md, int type); int mob_delete(struct mob_data *md); -int mob_catch_delete(struct mob_data *md,int type); int mob_timer_delete(int tid, unsigned int tick, int id, int data); int mob_deleteslave(struct mob_data *md); 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"); diff --git a/src/map/npc.h b/src/map/npc.h index d4ee9997c..2f81345d7 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -52,7 +52,9 @@ int npc_timerevent_start(struct npc_data *nd, int rid); int npc_timerevent_stop(struct npc_data *nd); int npc_gettimerevent_tick(struct npc_data *nd); int npc_settimerevent_tick(struct npc_data *nd,int newtimer); -int npc_delete(struct npc_data *nd); +int npc_remove_map(struct npc_data *nd); +int npc_unload(struct npc_data *nd); +int npc_reload(void); extern char *current_file; diff --git a/src/map/pet.c b/src/map/pet.c index 351782e7f..6f4713d75 100644 --- a/src/map/pet.c +++ b/src/map/pet.c @@ -889,7 +889,8 @@ int pet_catch_process2(struct map_session_data *sd,int target_id) pet_catch_rate = (pet_catch_rate*battle_config.pet_catch_rate)/100; if(rand()%10000 < pet_catch_rate) { - mob_catch_delete(md,0); + mob_remove_map(md,0); + mob_setdelayspawn(md->bl.id); clif_pet_rulet(sd,1); // if(battle_config.etc_log) // printf("rulet success %d\n",target_id); -- cgit v1.2.3-70-g09d2