* 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://svn.code.sf.net/p/rathena/svn/branches/stable@1429 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
ad4fcfbe12
commit
171609d4a2
@ -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
|
||||
|
@ -567,6 +567,9 @@ enablenpc: 80
|
||||
// Disables a NPC.
|
||||
disablenpc: 80
|
||||
|
||||
// Hides a NPC.
|
||||
hidenpc: 80
|
||||
|
||||
// Move a NPC
|
||||
npcmove: 80
|
||||
|
||||
|
@ -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
|
||||
|
@ -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])
|
||||
*------------------------------------------
|
||||
|
@ -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
|
||||
|
@ -242,11 +242,10 @@ 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);
|
||||
@ -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 &&
|
||||
|
@ -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);
|
||||
|
@ -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,23 +2107,15 @@ 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_retr(1, md);
|
||||
|
||||
if(md->bl.prev == NULL)
|
||||
return 1;
|
||||
mob_changestate(md,MS_DEAD,0);
|
||||
clif_clearchar_area(&md->bl,1);
|
||||
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);
|
||||
return 0;
|
||||
nullpo_retv(md);
|
||||
mob_remove_map(md, 0);
|
||||
map_deliddb(&md->bl);
|
||||
aFree(md);
|
||||
md = NULL;
|
||||
}
|
||||
|
||||
int mob_catch_delete(struct mob_data *md,int type)
|
||||
int mob_remove_map(struct mob_data *md, int type)
|
||||
{
|
||||
nullpo_retr(1, md);
|
||||
|
||||
@ -2131,17 +2124,32 @@ int mob_catch_delete(struct mob_data *md,int type)
|
||||
mob_changestate(md,MS_DEAD,0);
|
||||
clif_clearchar_area(&md->bl,type);
|
||||
map_delblock(&md->bl);
|
||||
if (md->lootitem){
|
||||
aFree(md->lootitem);
|
||||
md->lootitem = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int mob_delete(struct mob_data *md)
|
||||
{
|
||||
nullpo_retr(1, md);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
325
src/map/npc.c
325
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 = '-';
|
||||
|
||||
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,13 +2556,12 @@ 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");
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user