summaryrefslogtreecommitdiff
path: root/src/map/npc.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/npc.c')
-rw-r--r--src/map/npc.c137
1 files changed, 111 insertions, 26 deletions
diff --git a/src/map/npc.c b/src/map/npc.c
index d87619382..2e3ca2c63 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -118,17 +118,21 @@ int npc_enable_sub(struct block_list *bl, va_list ap)
{
char name[NAME_LENGTH*2+3];
- if (nd->sc.option&OPTION_INVISIBLE) // 無効化されている
+ 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::OnTouch", nd->exname); // exname to be specific. exname is the unique identifier for script events. [Lance]
- npc_event(sd,name,0);
+ 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);
+ }
+
}
- //aFree(name);
return 0;
}
@@ -157,7 +161,7 @@ int npc_enable(const char* name, int flag)
clif_changeoption(&nd->bl);
if( flag&3 && (nd->u.scr.xs >= 0 || nd->u.scr.ys >= 0) )
- map_foreachinarea( npc_enable_sub, nd->bl.m, nd->bl.x-nd->u.scr.xs, nd->bl.y-nd->u.scr.ys, nd->bl.x+nd->u.scr.xs, nd->bl.y+nd->u.scr.ys, BL_PC, nd );
+ map_forsomeinarea( npc_enable_sub, nd->bl.m, nd->bl.x-nd->u.scr.xs, nd->bl.y-nd->u.scr.ys, nd->bl.x+nd->u.scr.xs, nd->bl.y+nd->u.scr.ys, 0, BL_PC, nd );
return 0;
}
@@ -719,26 +723,49 @@ int npc_event(struct map_session_data* sd, const char* eventname, int mob_kill)
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) {
+ if( sd == NULL )
+ {
nullpo_info(NLP_MARK);
return 0;
}
- if (ev == NULL && eventname && strcmp(((eventname)+strlen(eventname)-9),"::OnTouch") == 0)
- return 1;
+ 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;
+ }
- if (ev == NULL || (nd = ev->nd) == NULL) {
- if (mob_kill) {
- strcpy( mobevent, eventname);
- strcat( mobevent, "::OnMyMobDead");
+ 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) {
+ if( ev == NULL || (nd = ev->nd) == NULL )
+ {
ShowError("npc_event: (mob_kill) event not found [%s]\n", mobevent);
return 0;
}
- } else {
+ }
+ else
+ {
ShowError("npc_event: event not found [%s]\n", eventname);
return 0;
}
@@ -758,10 +785,64 @@ int npc_event(struct map_session_data* sd, const char* eventname, int mob_kill)
return 1;
}
}
-
+
+ if( ontouch )
+ {
+ nd->touching_id = sd->bl.id;
+ sd->ontouch.npc_id = nd->bl.id;
+ sd->ontouch.x = xs;
+ sd->ontouch.y = ys;
+ }
+
return npc_event_sub(sd,ev,eventname);
}
+int npc_touch_areanpc_sub(struct block_list *bl, va_list ap)
+{
+ struct map_session_data *sd;
+ int pc_id,npc_id;
+ char *name;
+
+ nullpo_retr(0,bl);
+ nullpo_retr(0,(sd = map_id2sd(bl->id)));
+
+ pc_id = va_arg(ap,int);
+ npc_id = va_arg(ap,int);
+ name = va_arg(ap,char*);
+
+ if( pc_ishiding(sd) )
+ return 0;
+ if( pc_id == sd->bl.id )
+ return 0;
+
+ sd->areanpc_id = npc_id;
+ npc_event(sd,name,0);
+
+ return 1;
+}
+
+int npc_touchnext_areanpc(struct map_session_data* sd, bool logout)
+{
+ struct npc_data *nd = map_id2nd(sd->ontouch.npc_id);
+ short xs = sd->ontouch.x ,ys = sd->ontouch.y;
+
+ if( !nd || nd->touching_id != sd->bl.id )
+ return 1;
+
+ 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 )
+ {
+ char name[NAME_LENGTH*2+3];
+ memset(&sd->ontouch,0,sizeof(sd->ontouch));
+ nd->touching_id = 0;
+ snprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script_config.ontouch_name);
+ map_forsomeinarea(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);
+ }
+ return 0;
+}
+
/*==========================================
* 接触型のNPC処理
*------------------------------------------*/
@@ -807,7 +888,7 @@ int npc_touch_areanpc(struct map_session_data* sd, int m, int x, int y)
}
switch(map[m].npc[i]->subtype) {
case WARP:
- if (sd->sc.option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK))
+ if( pc_ishiding(sd) )
break; // hidden chars cannot use warps
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;
@@ -819,18 +900,22 @@ int npc_touch_areanpc(struct map_session_data* sd, int m, int x, int y)
return 1;
sd->areanpc_id = map[m].npc[i]->bl.id;
- snprintf(name, ARRAYLENGTH(name), "%s::OnTouch", map[m].npc[i]->exname); // It goes here too. exname being the unique identifier. [Lance]
-
+ snprintf(name, ARRAYLENGTH(name), "%s::%s", map[m].npc[i]->exname, script_config.ontouch_name);
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;
+ {
+ 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]);
}
- npc_click(sd,map[m].npc[i]);
}
+
break;
}
}
@@ -2450,7 +2535,7 @@ void npc_unsetcells(struct npc_data* nd)
map_setcell(m, j, i, CELL_NPC, false);
//Re-deploy NPC cells for other nearby npcs.
- map_foreachinarea( npc_unsetcells_sub, m, x0, y0, x1, y1, BL_NPC, nd->bl.id );
+ map_forsomeinarea( npc_unsetcells_sub, m, x0, y0, x1, y1, 0, BL_NPC, nd->bl.id );
}
void npc_movenpc(struct npc_data* nd, int x, int y)