From c977558cfdc170be51e86a39d6b3426b8b3f677c Mon Sep 17 00:00:00 2001 From: Aleos Date: Wed, 3 Apr 2019 19:25:47 -0400 Subject: [PATCH] Adjusted OnTouch overlap behavior (#2382) * Fixes #1939 and fixes #2274. * OnTouch NPC are now able to overlap one another and properly trigger as they do on official servers. * When entering an overlap area it should trigger both NPC. * Walking from overlap area to either NPC should trigger neither. * Walking from one NPC to the other (skipping the overlap area) should trigger the NPC area you enter. * Entering an OnTouch area will no longer stop the player from walking unless a message or menu window opens (or other events that should stop the player). * Resolves OnTouch_ overlapping issues. * Dead players don't trigger OnTouch_ anymore. * Hidden players don't trigger NPC clicks when OnTouch_ label is defined. Thanks to @Tokeiburu, @Lemongrass3110, @Atemo, and @Normynator! --- src/map/clif.cpp | 2 +- src/map/map.cpp | 40 +++++++- src/map/map.hpp | 4 +- src/map/npc.cpp | 233 +++++++++++++++++++++++++-------------------- src/map/pc.hpp | 3 +- src/map/status.cpp | 2 +- src/map/unit.cpp | 14 +-- 7 files changed, 185 insertions(+), 113 deletions(-) diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 8ea1ba4d27..c059dd709c 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -10655,7 +10655,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) if (map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKNPC)) npc_touch_areanpc(sd,sd->bl.m,sd->bl.x,sd->bl.y); else - sd->areanpc_id = 0; + sd->areanpc.clear(); /* it broke at some point (e.g. during a crash), so we make it visibly dead again. */ if( !sd->status.hp && !pc_isdead(sd) && status_isdead(&sd->bl) ) diff --git a/src/map/map.cpp b/src/map/map.cpp index 2eb219df06..78b268e2b8 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -2642,7 +2642,43 @@ bool map_addnpc(int16 m,struct npc_data *nd) return false; } - mapdata->npc[mapdata->npc_num]=nd; + int xs = -1, ys = -1; + + switch (nd->subtype) { + case NPCTYPE_WARP: + xs = nd->u.warp.xs; + ys = nd->u.warp.ys; + break; + case NPCTYPE_SCRIPT: + xs = nd->u.scr.xs; + ys = nd->u.scr.ys; + break; + default: + break; + } + // npcs with trigger area are grouped + // 0 < npc_num_warp < npc_num_area < npc_num + if (xs < 0 && ys < 0) + mapdata->npc[ mapdata->npc_num ] = nd; + else { + switch (nd->subtype) { + case NPCTYPE_WARP: + mapdata->npc[ mapdata->npc_num ] = mapdata->npc[ mapdata->npc_num_area ]; + mapdata->npc[ mapdata->npc_num_area ] = mapdata->npc[ mapdata->npc_num_warp ]; + mapdata->npc[ mapdata->npc_num_warp ] = nd; + mapdata->npc_num_warp++; + mapdata->npc_num_area++; + break; + case NPCTYPE_SCRIPT: + mapdata->npc[ mapdata->npc_num ] = mapdata->npc[ mapdata->npc_num_area ]; + mapdata->npc[ mapdata->npc_num_area ] = nd; + mapdata->npc_num_area++; + break; + default: + mapdata->npc[ mapdata->npc_num ] = nd; + break; + } + } mapdata->npc_num++; idb_put(id_db,nd->bl.id,nd); return true; @@ -2709,6 +2745,8 @@ int map_addinstancemap(const char *name, unsigned short instance_id) memset(dst_map->npc, 0, sizeof(dst_map->npc)); dst_map->npc_num = 0; + dst_map->npc_num_area = 0; + dst_map->npc_num_warp = 0; // Reallocate cells num_cell = dst_map->xs * dst_map->ys; diff --git a/src/map/map.hpp b/src/map/map.hpp index 2d9b8db1c6..8c301a05f8 100644 --- a/src/map/map.hpp +++ b/src/map/map.hpp @@ -726,7 +726,9 @@ struct map_data { int16 xs,ys; // map dimensions (in cells) int16 bxs,bys; // map dimensions (in blocks) int16 bgscore_lion, bgscore_eagle; // Battleground ScoreBoard - int npc_num; + int npc_num; // number total of npc on the map + int npc_num_area; // number of npc with a trigger area on the map + int npc_num_warp; // number of warp npc on the map int users; int users_pvp; int iwall_num; // Total of invisible walls in this map diff --git a/src/map/npc.cpp b/src/map/npc.cpp index 6c8f4b5a55..f88625ffb7 100644 --- a/src/map/npc.cpp +++ b/src/map/npc.cpp @@ -169,11 +169,21 @@ int npc_ontouch_event(struct map_session_data *sd, struct npc_data *nd) { char name[EVENT_NAME_LENGTH]; + if (pc_isdead(sd)) // Dead player don't trigger 'OnTouch_' + return 0; + if( nd->touching_id ) return 0; // Attached a player already. Can't trigger on anyone else. - if( pc_ishiding(sd) ) - return 1; // Can't trigger 'OnTouch_'. try 'OnTouch' later. + // pc_ishiding moved in npc_event for now. + // If OnTouch_ event exists hiding player doesn't click the npc. + // if( pc_ishiding(sd) ) + // return 1; // Can't trigger 'OnTouch_'. + + auto it = std::find(sd->npc_ontouch_.begin(), sd->npc_ontouch_.end(), nd->bl.id); + + if (it != sd->npc_ontouch_.end()) + return 0; safesnprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script_config.ontouch_event_name); return npc_event(sd,name,1); @@ -182,8 +192,9 @@ int npc_ontouch_event(struct map_session_data *sd, struct npc_data *nd) int npc_ontouch2_event(struct map_session_data *sd, struct npc_data *nd) { char name[EVENT_NAME_LENGTH]; + auto it = std::find(sd->areanpc.begin(), sd->areanpc.end(), nd->bl.id); - if( sd->areanpc_id == nd->bl.id ) + if (it != sd->areanpc.end()) return 0; safesnprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script_config.ontouch2_event_name); @@ -206,6 +217,7 @@ int npc_enable_sub(struct block_list *bl, va_list ap) if (nd->sc.option&OPTION_INVISIBLE) return 1; + // note : disablenpc doesn't reset the previous trigger status on official if( npc_ontouch_event(sd,nd) > 0 && npc_ontouch2_event(sd,nd) > 0 ) { // failed to run OnTouch event, so just click the npc if (sd->npc_id != 0) @@ -252,7 +264,7 @@ int npc_enable(const char* name, int flag) } else clif_changeoption(&nd->bl); - if( flag&3 && (nd->u.scr.xs >= 0 || nd->u.scr.ys >= 0) ) //check if player standing on a OnTouchArea + if( flag&3 && (nd->u.scr.xs >= 0 || nd->u.scr.ys >= 0) )// check if player standing on a OnTouchArea map_foreachinallarea( 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 ); return 0; @@ -898,18 +910,25 @@ int npc_event(struct map_session_data* sd, const char* eventname, int ontouch) return ontouch; } - switch(ontouch) - { - case 1: + if (ontouch == 1) { // OnTouch_ + if (pc_ishiding(sd)) + return 0; + nd->touching_id = sd->bl.id; - sd->touching_id = nd->bl.id; - break; - case 2: - sd->areanpc_id = nd->bl.id; - break; + + auto it = std::find(sd->npc_ontouch_.begin(), sd->npc_ontouch_.end(), nd->bl.id); + + if (it == sd->npc_ontouch_.end()) + sd->npc_ontouch_.push_back(nd->bl.id); + } else if (ontouch == 2) { // OnTouch + auto it = std::find(sd->areanpc.begin(), sd->areanpc.end(), nd->bl.id); + + if (it == sd->areanpc.end()) + sd->areanpc.push_back(nd->bl.id); } - return npc_event_sub(sd,ev,eventname); + npc_event_sub(sd,ev,eventname); // Don't return this value so npc_enable_sub doesn't attempt to "click" the NPC if OnTouch fails. + return 0; } /*========================================== @@ -931,6 +950,8 @@ int npc_touch_areanpc_sub(struct block_list *bl, va_list ap) return 0; if( pc_ishiding(sd) ) return 0; + if( pc_isdead(sd) ) + return 0; if( pc_id == sd->bl.id ) return 0; @@ -945,27 +966,40 @@ int npc_touch_areanpc_sub(struct block_list *bl, va_list ap) *------------------------------------------*/ int npc_touchnext_areanpc(struct map_session_data* sd, bool leavemap) { - struct npc_data *nd = map_id2nd(sd->touching_id); - short xs, ys; + if (sd->npc_ontouch_.empty()) + return 0; - if( !nd || nd->touching_id != sd->bl.id ) - return 1; + bool found = false; - xs = nd->u.scr.xs; - ys = nd->u.scr.ys; + sd->npc_ontouch_.erase(std::remove_if(sd->npc_ontouch_.begin(), sd->npc_ontouch_.end(), [&] (const int ¤t_npc_id) { + struct npc_data *nd = map_id2nd(current_npc_id); - 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) || leavemap ) - { - char name[EVENT_NAME_LENGTH]; + if (!nd) { + return true; + } else { + int16 xs = nd->u.scr.xs; + int16 ys = nd->u.scr.ys; - nd->touching_id = sd->touching_id = 0; - safesnprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script_config.ontouch_event_name); - map_forcountinarea(npc_touch_areanpc_sub,nd->bl.m,nd->bl.x - xs,nd->bl.y - ys,nd->bl.x + xs,nd->bl.y + ys,1,BL_PC,sd->bl.id,name); - } - return 0; + // note : hiding doesn't reset the previous trigger status + // player must leave the area to reset nd->touching_id on official + 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 || leavemap) { + char name[EVENT_NAME_LENGTH]; + + if (nd->touching_id && nd->touching_id == sd->bl.id) {// empty when reload script + found = true; + nd->touching_id = 0; + safesnprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script_config.ontouch_event_name); + map_forcountinarea(npc_touch_areanpc_sub,nd->bl.m,nd->bl.x - xs,nd->bl.y - ys,nd->bl.x + xs,nd->bl.y + ys,1,BL_PC,sd->bl.id,name); + } + + return true; + } + } + + return false; + }), sd->npc_ontouch_.end()); + + return found; } /*========================================== @@ -973,97 +1007,81 @@ int npc_touchnext_areanpc(struct map_session_data* sd, bool leavemap) *------------------------------------------*/ int npc_touch_areanpc(struct map_session_data* sd, int16 m, int16 x, int16 y) { - int xs,ys; - int f = 1; - int i; - int j, found_warp = 0; + int xs, ys, i, f = 1; nullpo_retr(1, sd); - // Why not enqueue it? [Inkfish] - //if(sd->npc_id) - // return 1; + // Remove NPCs that are no longer within the OnTouch area + for (i = 0; i < sd->areanpc.size(); i++) { + struct npc_data *nd = map_id2nd(sd->areanpc[i]); + + if (!nd || nd->subtype != NPCTYPE_SCRIPT || + !(x >= nd->bl.x - nd->u.scr.xs && x <= nd->bl.x + nd->u.scr.xs && y >= nd->bl.y - nd->u.scr.ys && y <= nd->bl.y + nd->u.scr.ys)) + sd->areanpc.erase(sd->areanpc.begin() + i); + } if (sd->state.block_action & PCBLOCK_NPCCLICK) return 0; struct map_data *mapdata = map_getmapdata(m); - for(i=0;inpc_num;i++) - { + for (i = 0; i < mapdata->npc_num_area; i++) { if (mapdata->npc[i]->sc.option&OPTION_INVISIBLE) { - f=0; // a npc was found, but it is disabled; don't print warning + f = 0; // a npc was found, but it is disabled; don't print warning continue; } switch(mapdata->npc[i]->subtype) { case NPCTYPE_WARP: - xs=mapdata->npc[i]->u.warp.xs; - ys=mapdata->npc[i]->u.warp.ys; + xs = mapdata->npc[i]->u.warp.xs; + ys = mapdata->npc[i]->u.warp.ys; break; case NPCTYPE_SCRIPT: - xs=mapdata->npc[i]->u.scr.xs; - ys=mapdata->npc[i]->u.scr.ys; + xs = mapdata->npc[i]->u.scr.xs; + ys = mapdata->npc[i]->u.scr.ys; break; default: continue; } - if( x >= mapdata->npc[i]->bl.x-xs && x <= mapdata->npc[i]->bl.x+xs - && y >= mapdata->npc[i]->bl.y-ys && y <= mapdata->npc[i]->bl.y+ys ) - break; - } - if( i == mapdata->npc_num ) - { - if( f == 1 ) // no npc found - ShowError("npc_touch_areanpc : stray NPC cell/NPC not found in the block on coordinates '%s',%d,%d\n", mapdata->name, x, y); - return 1; - } - switch(mapdata->npc[i]->subtype) { - case NPCTYPE_WARP: - if ((!mapdata->npc[i]->trigger_on_hidden && (pc_ishiding(sd) || (sd->sc.count && sd->sc.data[SC_CAMOUFLAGE]))) || pc_isdead(sd)) - break; // hidden or dead chars cannot use warps - if (!pc_job_can_entermap((enum e_job)sd->status.class_, map_mapindex2mapid(mapdata->npc[i]->u.warp.mapindex), sd->group_level)) - break; - if(sd->count_rewarp > 10){ - ShowWarning("Prevented infinite warp loop for player (%d:%d). Please fix NPC: '%s', path: '%s'\n", sd->status.account_id, sd->status.char_id, mapdata->npc[i]->exname, mapdata->npc[i]->path); - sd->count_rewarp=0; - break; - } - pc_setpos(sd,mapdata->npc[i]->u.warp.mapindex,mapdata->npc[i]->u.warp.x,mapdata->npc[i]->u.warp.y,CLR_OUTSIGHT); - break; - case NPCTYPE_SCRIPT: - for (j = i; j < mapdata->npc_num; j++) { - if (mapdata->npc[j]->subtype != NPCTYPE_WARP) { - continue; - } - if ((sd->bl.x >= (mapdata->npc[j]->bl.x - mapdata->npc[j]->u.warp.xs) && sd->bl.x <= (mapdata->npc[j]->bl.x + mapdata->npc[j]->u.warp.xs)) && - (sd->bl.y >= (mapdata->npc[j]->bl.y - mapdata->npc[j]->u.warp.ys) && sd->bl.y <= (mapdata->npc[j]->bl.y + mapdata->npc[j]->u.warp.ys))) { - if ((!mapdata->npc[i]->trigger_on_hidden && (pc_ishiding(sd) || (sd->sc.count && sd->sc.data[SC_CAMOUFLAGE]))) || pc_isdead(sd)) - break; // hidden or dead chars cannot use warps - pc_setpos(sd,mapdata->npc[j]->u.warp.mapindex,mapdata->npc[j]->u.warp.x,mapdata->npc[j]->u.warp.y,CLR_OUTSIGHT); - found_warp = 1; + if (x >= mapdata->npc[i]->bl.x - xs && x <= mapdata->npc[i]->bl.x + xs && y >= mapdata->npc[i]->bl.y - ys && y <= mapdata->npc[i]->bl.y + ys) { + f = 0; + + switch (mapdata->npc[i]->subtype) { + case NPCTYPE_WARP: + if ((!mapdata->npc[i]->trigger_on_hidden && (pc_ishiding(sd) || (sd->sc.count && sd->sc.data[SC_CAMOUFLAGE]))) || pc_isdead(sd)) + break; // hidden or dead chars cannot use warps + if (!pc_job_can_entermap((enum e_job)sd->status.class_, map_mapindex2mapid(mapdata->npc[i]->u.warp.mapindex), sd->group_level)) + break; + if (sd->count_rewarp > 10) { + ShowWarning("Prevented infinite warp loop for player (%d:%d). Please fix NPC: '%s', path: '%s'\n", sd->status.account_id, sd->status.char_id, mapdata->npc[i]->exname, mapdata->npc[i]->path); + sd->count_rewarp = 0; break; } - } + pc_setpos(sd, mapdata->npc[i]->u.warp.mapindex, mapdata->npc[i]->u.warp.x, mapdata->npc[i]->u.warp.y, CLR_OUTSIGHT); + return 0; + case NPCTYPE_SCRIPT: + // warp type sorted first, no need to check if they override any other OnTouch areas. + + if (npc_ontouch_event(sd, mapdata->npc[i]) > 0 && npc_ontouch2_event(sd, mapdata->npc[i]) > 0) { // failed to run OnTouch event, so just click the npc + auto it = std::find(sd->areanpc.begin(), sd->areanpc.end(), mapdata->npc[i]->bl.id); + + if (it == sd->areanpc.end()) + sd->areanpc.push_back(mapdata->npc[i]->bl.id); + + npc_click(sd, mapdata->npc[i]); + } - if (found_warp > 0) { break; } - - if( npc_ontouch_event(sd,mapdata->npc[i]) > 0 && npc_ontouch2_event(sd,mapdata->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 == INVALID_TIMER at this time, we stop walking manually. [Inkfish] - clif_fixpos(&sd->bl); - ud->walkpath.path_pos = ud->walkpath.path_len; - } - sd->areanpc_id = mapdata->npc[i]->bl.id; - npc_click(sd,mapdata->npc[i]); - } - break; + } } + + if (f == 1) { + ShowError("npc_touch_areanpc : stray NPC cell/NPC not found in the block on coordinates '%s',%d,%d\n", mapdata->name, x, y); + return 1; + } + return 0; } @@ -1077,7 +1095,7 @@ int npc_touch_areanpc2(struct mob_data *md) int xs, ys; struct map_data *mapdata = map_getmapdata(md->bl.m); - for( i = 0; i < mapdata->npc_num; i++ ) + for( i = 0; i < mapdata->npc_num_area; i++ ) { if( mapdata->npc[i]->sc.option&OPTION_INVISIBLE ) continue; @@ -1166,7 +1184,7 @@ int npc_check_areanpc(int flag, int16 m, int16 x, int16 y, int16 range) if (!i) return 0; //No NPC_CELLs. //Now check for the actual NPC on said range. - for(i=0;inpc_num;i++) + for (i = 0; i < mapdata->npc_num_area; i++) { if (mapdata->npc[i]->sc.option&OPTION_INVISIBLE) continue; @@ -1193,7 +1211,7 @@ int npc_check_areanpc(int flag, int16 m, int16 x, int16 y, int16 range) && y1 >= mapdata->npc[i]->bl.y-ys && y0 <= mapdata->npc[i]->bl.y+ys ) break; // found a npc } - if (i==mapdata->npc_num) + if (i == mapdata->npc_num_area) return 0; return (mapdata->npc[i]->bl.id); @@ -2164,8 +2182,21 @@ int npc_remove_map(struct npc_data* nd) if( i == mapdata->npc_num ) return 2; //failed to find it? mapdata->npc_num--; - mapdata->npc[i] = mapdata->npc[mapdata->npc_num]; - mapdata->npc[mapdata->npc_num] = NULL; + if (i >= mapdata->npc_num_area) + mapdata->npc[i] = mapdata->npc[ mapdata->npc_num ]; + else if (i >= mapdata->npc_num_warp) { + mapdata->npc_num_area--; + mapdata->npc[i] = mapdata->npc[ mapdata->npc_num_area ]; + mapdata->npc[ mapdata->npc_num_area ] = mapdata->npc[ mapdata->npc_num ]; + } + else { + mapdata->npc_num_warp--; + mapdata->npc_num_area--; + mapdata->npc[i] = mapdata->npc[ mapdata->npc_num_warp ]; + mapdata->npc[ mapdata->npc_num_warp ] = mapdata->npc[ mapdata->npc_num_area ]; + mapdata->npc[ mapdata->npc_num_area ] = mapdata->npc[ mapdata->npc_num ]; + } + mapdata->npc[ mapdata->npc_num ] = NULL; return 0; } @@ -2570,7 +2601,6 @@ struct npc_data* npc_add_warp(char* name, short from_mapid, short from_x, short struct npc_data *nd; nd = npc_create_npc(from_mapid, from_x, from_y); - map_addnpc(from_mapid, nd); safestrncpy(nd->exname, name, ARRAYLENGTH(nd->exname)); if (npc_name2id(nd->exname) != NULL) @@ -2597,6 +2627,7 @@ struct npc_data* npc_add_warp(char* name, short from_mapid, short from_x, short nd->bl.type = BL_NPC; nd->subtype = NPCTYPE_WARP; nd->trigger_on_hidden = false; + map_addnpc(from_mapid, nd); npc_setcells(nd); if(map_addblock(&nd->bl)) return NULL; @@ -2654,7 +2685,6 @@ static const char* npc_parse_warp(char* w1, char* w2, char* w3, char* w4, const } nd = npc_create_npc(m, x, y); - map_addnpc(m, nd); npc_parsename(nd, w3, start, buffer, filepath); if (!battle_config.warp_point_debug) @@ -2675,6 +2705,7 @@ static const char* npc_parse_warp(char* w1, char* w2, char* w3, char* w4, const nd->trigger_on_hidden = true; else nd->trigger_on_hidden = false; + map_addnpc(m, nd); npc_setcells(nd); if(map_addblock(&nd->bl)) //couldn't add on map return strchr(start,'\n'); @@ -3376,7 +3407,6 @@ int npc_duplicate4instance(struct npc_data *snd, int16 m) { } wnd = npc_create_npc(m, snd->bl.x, snd->bl.y); - map_addnpc(m, wnd); safestrncpy(wnd->name, "", ARRAYLENGTH(wnd->name)); safestrncpy(wnd->exname, newname, ARRAYLENGTH(wnd->exname)); wnd->class_ = JT_WARPNPC; @@ -3390,6 +3420,7 @@ int npc_duplicate4instance(struct npc_data *snd, int16 m) { wnd->subtype = NPCTYPE_WARP; wnd->trigger_on_hidden = snd->trigger_on_hidden; wnd->src_id = snd->src_id ? snd->src_id : snd->bl.id; + map_addnpc(m, wnd); npc_setcells(wnd); if(map_addblock(&wnd->bl)) return 1; diff --git a/src/map/pc.hpp b/src/map/pc.hpp index 238ad04e6a..10eff2c55f 100644 --- a/src/map/pc.hpp +++ b/src/map/pc.hpp @@ -333,7 +333,8 @@ struct map_session_data { unsigned short mapindex; unsigned char head_dir; //0: Look forward. 1: Look right, 2: Look left. t_tick client_tick; - int npc_id,areanpc_id,npc_shopid,touching_id; //for script follow scriptoid; ,npcid + int npc_id,npc_shopid; //for script follow scriptoid; ,npcid + std::vector areanpc, npc_ontouch_; ///< Array of OnTouch and OnTouch_ NPC 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; diff --git a/src/map/status.cpp b/src/map/status.cpp index 36b84c22c1..f5961489e7 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -11851,7 +11851,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty break; } - if( opt_flag&2 && sd && sd->touching_id ) + if( opt_flag&2 && sd && !sd->npc_ontouch_.empty() ) npc_touchnext_areanpc(sd,false); // Run OnTouch_ on next char in range return 1; diff --git a/src/map/unit.cpp b/src/map/unit.cpp index b6183e51ce..93a3c15648 100644 --- a/src/map/unit.cpp +++ b/src/map/unit.cpp @@ -444,14 +444,14 @@ static TIMER_FUNC(unit_walktoxy_timer){ switch(bl->type) { case BL_PC: - if( sd->touching_id ) + if( !sd->npc_ontouch_.empty() ) 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. return 0; } else - sd->areanpc_id=0; + sd->areanpc.clear(); pc_cell_basilica(sd); break; case BL_MOB: @@ -971,7 +971,7 @@ bool unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, boo ud->walktimer = INVALID_TIMER; if(sd) { - if( sd->touching_id ) + if( !sd->npc_ontouch_.empty() ) npc_touchnext_areanpc(sd,false); if(map_getcell(bl->m,bl->x,bl->y,CELL_CHKNPC)) { @@ -980,7 +980,7 @@ bool unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, boo if (bl->prev == NULL) // Script could have warped char, abort remaining of the function. return false; } else - sd->areanpc_id=0; + sd->areanpc.clear(); if( sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > PET_INTIMATE_NONE ) { // Check if pet needs to be teleported. [Skotlex] @@ -1102,13 +1102,13 @@ int unit_blown(struct block_list* bl, int dx, int dy, int count, enum e_skill_bl clif_blown(bl); if(sd) { - if(sd->touching_id) + if(!sd->npc_ontouch_.empty()) 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); else - sd->areanpc_id = 0; + sd->areanpc.clear(); } } @@ -2955,7 +2955,7 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file, if(sd->menuskill_id) sd->menuskill_id = sd->menuskill_val = 0; - if( sd->touching_id ) + if( !sd->npc_ontouch_.empty() ) npc_touchnext_areanpc(sd,true); // Check if warping and not changing the map.