|
@@ -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;
|
|
|
}
|