From 476222257ace810a1e69d552c969f36c4687f4d9 Mon Sep 17 00:00:00 2001 From: Inkfish Date: Thu, 26 Nov 2009 12:01:19 +0000 Subject: * 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 --- src/map/npc.c | 174 ++++++++++++++++++++++------------------------------------ 1 file changed, 66 insertions(+), 108 deletions(-) (limited to 'src/map/npc.c') 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;iu.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; } -- cgit v1.2.3-60-g2f50