summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
authorInkfish <Inkfish@54d463be-8e91-2dee-dedb-b68131a5f0ec>2009-11-26 12:01:19 +0000
committerInkfish <Inkfish@54d463be-8e91-2dee-dedb-b68131a5f0ec>2009-11-26 12:01:19 +0000
commit476222257ace810a1e69d552c969f36c4687f4d9 (patch)
tree4366787ac16e9f9d952b9cc1dee2c4e45d20e9f2 /src/map
parent07dee1fd6c710b78fc826679966dbb6c0c1a8d44 (diff)
downloadhercules-476222257ace810a1e69d552c969f36c4687f4d9.tar.gz
hercules-476222257ace810a1e69d552c969f36c4687f4d9.tar.bz2
hercules-476222257ace810a1e69d552c969f36c4687f4d9.tar.xz
hercules-476222257ace810a1e69d552c969f36c4687f4d9.zip
* NPC event code cleanups.
- removed the 'OnMyMobDead' dead code. It's never supported though documented. - removed the 'feature' that events only trigger when the player is in the OnTouch area IF it's specified. It's never documented and breaks official scripts. - some cleanups and bug fixes to OnTouch_. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@14173 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map')
-rw-r--r--src/map/npc.c174
-rw-r--r--src/map/npc.h4
-rw-r--r--src/map/pc.h8
-rw-r--r--src/map/skill.c12
-rw-r--r--src/map/status.c5
-rw-r--r--src/map/unit.c12
6 files changed, 86 insertions, 129 deletions
diff --git a/src/map/npc.c b/src/map/npc.c
index 6a3af6d40..8164054de 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -102,6 +102,29 @@ struct view_data* npc_get_viewdata(int class_)
return &npc_viewdb[class_];
return NULL;
}
+
+int npc_ontouch_event(struct map_session_data *sd, struct npc_data *nd)
+{
+ char name[NAME_LENGTH*2+3];
+
+ if( nd->touching_id || pc_ishiding(sd) )
+ return 0;
+
+ snprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script_config.ontouch_name);
+ return npc_event(sd,name,1);
+}
+
+int npc_ontouch2_event(struct map_session_data *sd, struct npc_data *nd)
+{
+ char name[NAME_LENGTH*2+3];
+
+ if( sd->areanpc_id == nd->bl.id )
+ return 0;
+
+ snprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script_config.ontouch2_name);
+ return npc_event(sd,name,2);
+}
+
/*==========================================
* NPCの無効化/有効化
* npc_enable
@@ -116,22 +139,16 @@ int npc_enable_sub(struct block_list *bl, va_list ap)
nullpo_retr(0, nd=va_arg(ap,struct npc_data *));
if(bl->type == BL_PC && (sd=(struct map_session_data *)bl))
{
- char name[NAME_LENGTH*2+3];
+ TBL_PC *sd = (TBL_PC*)bl;
if (nd->sc.option&OPTION_INVISIBLE)
return 1;
- if(sd->areanpc_id==nd->bl.id)
- return 1;
- sd->areanpc_id=nd->bl.id;
-
- snprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script_config.ontouch_name);
- if( npc_event(sd,name,0) > 0 )
- {
- snprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script_config.ontouch2_name); // exname to be specific. exname is the unique identifier for script events. [Lance]
- npc_event(sd,name,0);
+ if( npc_ontouch_event(sd,nd) > 0 && npc_ontouch2_event(sd,nd) > 0 )
+ { // failed to run OnTouch event, so just click the npc
+ pc_stop_walking(sd,1);
+ npc_click(sd,nd);
}
-
}
return 0;
}
@@ -699,10 +716,12 @@ int npc_event_sub(struct map_session_data* sd, struct event_data* ev, const char
int i;
ARR_FIND( 0, MAX_EVENTQUEUE, i, sd->eventqueue[i][0] == '\0' );
if( i < MAX_EVENTQUEUE )
+ {
safestrncpy(sd->eventqueue[i],eventname,50); //Event enqueued.
- else
- ShowWarning("npc_event: player's event queue is full, can't add event '%s' !\n", eventname);
-
+ return 0;
+ }
+
+ ShowWarning("npc_event: player's event queue is full, can't add event '%s' !\n", eventname);
return 1;
}
if( ev->nd->sc.option&OPTION_INVISIBLE )
@@ -718,80 +737,29 @@ int npc_event_sub(struct map_session_data* sd, struct event_data* ev, const char
/*==========================================
* イベント型のNPC処理
*------------------------------------------*/
-int npc_event(struct map_session_data* sd, const char* eventname, int mob_kill)
+int npc_event(struct map_session_data* sd, const char* eventname, int ontouch)
{
struct event_data* ev = (struct event_data*)strdb_get(ev_db, eventname);
struct npc_data *nd;
- int xs,ys;
- bool ontouch = false;
- char mobevent[100];
- char name[NAME_LENGTH*2+3];
- if( sd == NULL )
- {
- nullpo_info(NLP_MARK);
- return 0;
- }
-
- snprintf(name, ARRAYLENGTH(name), "::%s", script_config.ontouch_name);
- if( eventname && strcmp(((eventname)+strlen(eventname)-strlen(script_config.ontouch_name)-2),name) == 0 )
- {
- if( ev == NULL || !ev->nd )
- return 1;
- if( pc_ishiding(sd) )
- return 0;
- if( ev->nd->touching_id )
- return 0;
- ontouch = true;
- }
- else
- {
- snprintf(name, ARRAYLENGTH(name), "::%s", script_config.ontouch2_name);
- if( ev == NULL && eventname && strcmp(((eventname)+strlen(eventname)-strlen(script_config.ontouch2_name)-2),name) == 0 )
- return 1;
- }
+ nullpo_retr(0,sd);
if( ev == NULL || (nd = ev->nd) == NULL )
{
- if (mob_kill)
- {
- strcpy(mobevent, eventname);
- strcat(mobevent, "::OnMyMobDead");
- ev = (struct event_data*)strdb_get(ev_db, mobevent);
- if( ev == NULL || (nd = ev->nd) == NULL )
- {
- ShowError("npc_event: (mob_kill) event not found [%s]\n", mobevent);
- return 0;
- }
- }
- else
- {
+ if( !ontouch )
ShowError("npc_event: event not found [%s]\n", eventname);
- return 0;
- }
+ return ontouch;
}
- xs=nd->u.scr.xs;
- ys=nd->u.scr.ys;
- if( xs >= 0 && ys >= 0 && strcmp(((eventname)+strlen(eventname)-6),"Global") != 0 )
- {
- if( nd->bl.m >= 0 )
- {// Non-invisible npc
- if( nd->bl.m != sd->bl.m )
- return 1;
- if( sd->bl.x < nd->bl.x-xs || sd->bl.x > nd->bl.x+xs )
- return 1;
- if( sd->bl.y < nd->bl.y-ys || sd->bl.y > nd->bl.y+ys )
- return 1;
- }
- }
-
- if( ontouch )
+ switch(ontouch)
{
+ case 1:
nd->touching_id = sd->bl.id;
- sd->ontouch.npc_id = nd->bl.id;
- sd->ontouch.x = xs;
- sd->ontouch.y = ys;
+ sd->touching_id = nd->bl.id;
+ break;
+ case 2:
+ sd->areanpc_id = nd->bl.id;
+ break;
}
return npc_event_sub(sd,ev,eventname);
@@ -815,28 +783,30 @@ int npc_touch_areanpc_sub(struct block_list *bl, va_list ap)
if( pc_id == sd->bl.id )
return 0;
- sd->areanpc_id = npc_id;
- npc_event(sd,name,0);
+ npc_event(sd,name,1);
return 1;
}
-int npc_touchnext_areanpc(struct map_session_data* sd, bool logout)
+int npc_touchnext_areanpc(struct map_session_data* sd, bool leavemap)
{
- struct npc_data *nd = map_id2nd(sd->ontouch.npc_id);
- short xs = sd->ontouch.x ,ys = sd->ontouch.y;
+ struct npc_data *nd = map_id2nd(sd->touching_id);
+ short xs, ys;
if( !nd || nd->touching_id != sd->bl.id )
return 1;
+ xs = nd->u.scr.xs;
+ ys = nd->u.scr.ys;
+
if( sd->bl.m != nd->bl.m ||
sd->bl.x < nd->bl.x - xs || sd->bl.x > nd->bl.x + xs ||
sd->bl.y < nd->bl.y - ys || sd->bl.y > nd->bl.y + ys ||
- pc_ishiding(sd) || logout )
+ pc_ishiding(sd) || leavemap )
{
char name[NAME_LENGTH*2+3];
- memset(&sd->ontouch,0,sizeof(sd->ontouch));
- nd->touching_id = 0;
+
+ nd->touching_id = sd->touching_id = 0;
snprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script_config.ontouch_name);
map_forcountinarea(npc_touch_areanpc_sub,nd->bl.m,nd->bl.m - xs,nd->bl.y - ys,nd->bl.x + xs,nd->bl.y + ys,1,BL_PC,sd->bl.id,nd->bl.id,name);
}
@@ -854,8 +824,9 @@ int npc_touch_areanpc(struct map_session_data* sd, int m, int x, int y)
nullpo_retr(1, sd);
- if(sd->npc_id)
- return 1;
+ // Why not enqueue it? [Inkfish]
+ //if(sd->npc_id)
+ // return 1;
for(i=0;i<map[m].npc_num;i++)
{
@@ -893,31 +864,18 @@ int npc_touch_areanpc(struct map_session_data* sd, int m, int x, int y)
pc_setpos(sd,map[m].npc[i]->u.warp.mapindex,map[m].npc[i]->u.warp.x,map[m].npc[i]->u.warp.y,0);
break;
case SCRIPT:
- {
- char name[NAME_LENGTH*2+3];
-
- if(sd->areanpc_id == map[m].npc[i]->bl.id)
- return 1;
- sd->areanpc_id = map[m].npc[i]->bl.id;
-
- snprintf(name, ARRAYLENGTH(name), "%s::%s", map[m].npc[i]->exname, script_config.ontouch_name);
- if( npc_event(sd,name,0) > 0 )
- {
- snprintf(name, ARRAYLENGTH(name), "%s::%s", map[m].npc[i]->exname, script_config.ontouch2_name); // It goes here too. exname being the unique identifier. [Lance]
- if( npc_event(sd,name,0) > 0 )
- {// failed to run OnTouch event, so just click the npc
- struct unit_data *ud = unit_bl2ud(&sd->bl);
- if( ud && ud->walkpath.path_pos < ud->walkpath.path_len )
- { // Since walktimer always == -1 at this time, we stop walking manually. [Inkfish]
- clif_fixpos(&sd->bl);
- ud->walkpath.path_pos = ud->walkpath.path_len;
- }
- npc_click(sd,map[m].npc[i]);
+ if( npc_ontouch_event(sd,map[m].npc[i]) > 0 && npc_ontouch2_event(sd,map[m].npc[i]) > 0 )
+ { // failed to run OnTouch event, so just click the npc
+ struct unit_data *ud = unit_bl2ud(&sd->bl);
+ if( ud && ud->walkpath.path_pos < ud->walkpath.path_len )
+ { // Since walktimer always == -1 at this time, we stop walking manually. [Inkfish]
+ clif_fixpos(&sd->bl);
+ ud->walkpath.path_pos = ud->walkpath.path_len;
}
+ sd->areanpc_id = map[m].npc[i]->bl.id;
+ npc_click(sd,map[m].npc[i]);
}
-
break;
- }
}
return 0;
}
diff --git a/src/map/npc.h b/src/map/npc.h
index 5bbb29fa4..6f705a09c 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -98,11 +98,11 @@ enum npce_event {
struct view_data* npc_get_viewdata(int class_);
int npc_chat_sub(struct block_list* bl, va_list ap);
int npc_event_dequeue(struct map_session_data* sd);
-int npc_event(struct map_session_data* sd, const char* eventname, int mob_kill);
+int npc_event(struct map_session_data* sd, const char* eventname, int ontouch);
int npc_touch_areanpc(struct map_session_data* sd, int m, int x, int y);
int npc_touch_areanpc2(struct mob_data *md); // [Skotlex]
int npc_check_areanpc(int flag, int m, int x, int y, int range);
-int npc_touchnext_areanpc(struct map_session_data* sd,bool logout);
+int npc_touchnext_areanpc(struct map_session_data* sd,bool leavemap);
int npc_click(struct map_session_data* sd, struct npc_data* nd);
int npc_scriptcont(struct map_session_data* sd, int id);
struct npc_data* npc_checknear(struct map_session_data* sd, struct block_list* bl);
diff --git a/src/map/pc.h b/src/map/pc.h
index 19db45465..ab26721fd 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -161,11 +161,7 @@ struct map_session_data {
unsigned short mapindex;
unsigned char head_dir; //0: Look forward. 1: Look right, 2: Look left.
unsigned int client_tick;
- int npc_id,areanpc_id,npc_shopid;
- struct {
- int npc_id;
- short x,y;
- } ontouch;
+ int npc_id,areanpc_id,npc_shopid,touching_id;
int npc_item_flag; //Marks the npc_id with which you can use items during interactions with said npc (see script command enable_itemuse)
int npc_menu; // internal variable, used in npc menu handling
int npc_amount;
@@ -358,7 +354,7 @@ struct map_session_data {
unsigned short pvp_rank, pvp_lastusers;
unsigned short pvp_won, pvp_lost;
- char eventqueue[MAX_EVENTQUEUE][50];
+ char eventqueue[MAX_EVENTQUEUE][NAME_LENGTH*2+3];
int eventtimer[MAX_EVENTTIMER];
unsigned short eventcount; // [celest]
diff --git a/src/map/skill.c b/src/map/skill.c
index 8d0b1cda9..e4fad5ff8 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -1541,11 +1541,13 @@ int skill_blown(struct block_list* src, struct block_list* target, int count, in
if( target->type == BL_PC )
{
- if( map_getcell(target->m, target->x, target->y, CELL_CHKNPC) )
- npc_touch_areanpc((TBL_PC*)target, target->m, target->x, target->y); //Invoke area NPC
-
- if( ((TBL_PC*)target)->ontouch.npc_id )
- npc_touchnext_areanpc(((TBL_PC*)target),false);
+ TBL_PC *sd = (TBL_PC*)target;
+ if( sd->touching_id )
+ npc_touchnext_areanpc(sd,false);
+ if( map_getcell(target->m,target->x,target->y,CELL_CHKNPC) )
+ npc_touch_areanpc(sd,target->m,target->x,target->y);
+ else
+ sd->areanpc_id=0;
}
return count; //Return amount of knocked back cells.
diff --git a/src/map/status.c b/src/map/status.c
index 9b3482d83..479e77fd0 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -6093,12 +6093,15 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
//OPTION
case SC_HIDING:
sc->option |= OPTION_HIDE;
+ opt_flag = 2;
break;
case SC_CLOAKING:
sc->option |= OPTION_CLOAK;
+ opt_flag = 2;
break;
case SC_CHASEWALK:
sc->option |= OPTION_CHASEWALK|OPTION_CLOAK;
+ opt_flag = 2;
break;
case SC_SIGHT:
sc->option |= OPTION_SIGHT;
@@ -6198,7 +6201,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
}
- if( sd && sd->ontouch.npc_id )
+ if( opt_flag&2 && sd && sd->touching_id )
npc_touchnext_areanpc(sd,false);
return 1;
diff --git a/src/map/unit.c b/src/map/unit.c
index d828832c6..f739159fb 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -165,6 +165,8 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr data)
ud->walktimer = INVALID_TIMER;
if(sd) {
+ if( sd->touching_id )
+ npc_touchnext_areanpc(sd,false);
if(map_getcell(bl->m,x,y,CELL_CHKNPC)) {
npc_touch_areanpc(sd,bl->m,x,y);
if (bl->prev == NULL) //Script could have warped char, abort remaining of the function.
@@ -172,9 +174,6 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr data)
} else
sd->areanpc_id=0;
- if( sd->ontouch.npc_id )
- npc_touchnext_areanpc(sd,false);
-
if (sd->state.gmaster_flag &&
(battle_config.guild_aura&((agit_flag || agit2_flag)?2:1)) &&
(battle_config.guild_aura&(map_flag_gvg2(bl->m)?8:4))
@@ -518,6 +517,8 @@ int unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, bool
ud->walktimer = INVALID_TIMER;
if(sd) {
+ if( sd->touching_id )
+ npc_touchnext_areanpc(sd,false);
if(map_getcell(bl->m,bl->x,bl->y,CELL_CHKNPC)) {
npc_touch_areanpc(sd,bl->m,bl->x,bl->y);
if (bl->prev == NULL) //Script could have warped char, abort remaining of the function.
@@ -525,9 +526,6 @@ int unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, bool
} else
sd->areanpc_id=0;
- if( sd->ontouch.npc_id )
- npc_touchnext_areanpc(sd,false);
-
if( sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > 0 )
{ // Check if pet needs to be teleported. [Skotlex]
int flag = 0;
@@ -1816,7 +1814,7 @@ int unit_remove_map_(struct block_list *bl, int clrtype, const char* file, int l
guild_reply_reqalliance(sd,sd->guild_alliance_account,0);
if(sd->menuskill_id)
sd->menuskill_id = sd->menuskill_val = 0;
- if( sd->ontouch.npc_id )
+ if( sd->touching_id )
npc_touchnext_areanpc(sd,true);
sd->npc_shopid = 0;