summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog-SVN.txt9
-rw-r--r--conf-tmpl/atcommand_athena.conf3
-rw-r--r--npc/jobs/custom/jobchange.txt2
-rw-r--r--src/map/atcommand.c33
-rw-r--r--src/map/atcommand.h1
-rw-r--r--src/map/clif.c30
-rw-r--r--src/map/map.c4
-rw-r--r--src/map/mob.c40
-rw-r--r--src/map/mob.h4
-rw-r--r--src/map/npc.c329
-rw-r--r--src/map/npc.h4
-rw-r--r--src/map/pet.c3
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 <NPC_name>).");
+ 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);