summaryrefslogtreecommitdiff
path: root/src/map/npc.c
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/npc.c
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/npc.c')
-rw-r--r--src/map/npc.c174
1 files changed, 66 insertions, 108 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;
}