diff options
author | Inkfish <Inkfish@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2009-10-25 09:38:33 +0000 |
---|---|---|
committer | Inkfish <Inkfish@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2009-10-25 09:38:33 +0000 |
commit | 7da9ee0b5c0aad9425441bcddeeadb745aa4c0d5 (patch) | |
tree | 7207e15b81b7816156384b8f040ee5dda17de86a | |
parent | 9b4d9f29a8ab56f59cbac2cccbb685146f52faac (diff) | |
download | hercules-7da9ee0b5c0aad9425441bcddeeadb745aa4c0d5.tar.gz hercules-7da9ee0b5c0aad9425441bcddeeadb745aa4c0d5.tar.bz2 hercules-7da9ee0b5c0aad9425441bcddeeadb745aa4c0d5.tar.xz hercules-7da9ee0b5c0aad9425441bcddeeadb745aa4c0d5.zip |
* Implemented the official version of 'OnTouch' named as 'OnTouch_'.(it can be defined in script_athena.conf)
* Adapted 'map_foreachinarea' to 'map_forsomeinarea' so that it allows you to specify the number of bl you wanna operate on.
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@14097 54d463be-8e91-2dee-dedb-b68131a5f0ec
-rw-r--r-- | Changelog-Trunk.txt | 3 | ||||
-rw-r--r-- | conf/script_athena.conf | 11 | ||||
-rw-r--r-- | src/map/atcommand.c | 8 | ||||
-rw-r--r-- | src/map/clif.c | 8 | ||||
-rw-r--r-- | src/map/map.c | 8 | ||||
-rw-r--r-- | src/map/map.h | 2 | ||||
-rw-r--r-- | src/map/npc.c | 137 | ||||
-rw-r--r-- | src/map/npc.h | 2 | ||||
-rw-r--r-- | src/map/pc.h | 4 | ||||
-rw-r--r-- | src/map/script.c | 28 | ||||
-rw-r--r-- | src/map/script.h | 3 | ||||
-rw-r--r-- | src/map/skill.c | 52 | ||||
-rw-r--r-- | src/map/status.c | 7 | ||||
-rw-r--r-- | src/map/unit.c | 10 |
14 files changed, 210 insertions, 73 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 39f55ea9e..61c3d078d 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -3,6 +3,9 @@ Date Added AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK. IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. +09/10/25 + * Implemented the official version of 'OnTouch' named as 'OnTouch_' and it can be defined in script_athena.conf. [Inkfish] + * Adapted 'map_foreachinarea' to 'map_forsomeinarea' so that it allows you to specify the count of bl you wanna operate on. [Inkfish] 09/10/24 * Reverted the previous change to OnTouch not triggering for invisible chars [ultramage] * 'OnTouch' script shouldn't trigger when you are invisible.(same as warps) [Inkfish] diff --git a/conf/script_athena.conf b/conf/script_athena.conf index f45af4bad..67521740a 100644 --- a/conf/script_athena.conf +++ b/conf/script_athena.conf @@ -32,4 +32,15 @@ check_gotocount: 2048 //input_max_value: 2147483647 input_max_value: 10000000 +// Official Version of OnTouch +// Scripts run on the first visible character walks into the OnTouch area +// and before he walks out/hides, the scripts won't run ever again. +// This label takes the piority to OnTouch2_Label. +OnTouch_Label: OnTouch_ + +// Official Version of OnTouch2 +// Scripts run on every character walks into the OnTouch area +// This is the same as the "OnTouch" that eA has been using all along. +OnTouch2_Label: OnTouch + import: conf/import/script_conf.txt diff --git a/src/map/atcommand.c b/src/map/atcommand.c index e638d6513..ae5c3bea1 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -6367,9 +6367,9 @@ static int atcommand_cleanmap_sub(struct block_list *bl, va_list ap) int atcommand_cleanmap(const int fd, struct map_session_data* sd, const char* command, const char* message) { - map_foreachinarea(atcommand_cleanmap_sub, sd->bl.m, + map_forsomeinarea(atcommand_cleanmap_sub, sd->bl.m, sd->bl.x-AREA_SIZE*2, sd->bl.y-AREA_SIZE*2, - sd->bl.x+AREA_SIZE*2, sd->bl.y+AREA_SIZE*2, + sd->bl.x+AREA_SIZE*2, sd->bl.y+AREA_SIZE*2,0, BL_ITEM); clif_displaymessage(fd, "All dropped items have been cleaned up."); return 0; @@ -7593,9 +7593,9 @@ int atcommand_mutearea(const int fd, struct map_session_data* sd, const char* co time = atoi(message); - map_foreachinarea(atcommand_mutearea_sub,sd->bl.m, + map_forsomeinarea(atcommand_mutearea_sub,sd->bl.m, sd->bl.x-AREA_SIZE, sd->bl.y-AREA_SIZE, - sd->bl.x+AREA_SIZE, sd->bl.y+AREA_SIZE, BL_PC, sd->bl.id, time); + sd->bl.x+AREA_SIZE, sd->bl.y+AREA_SIZE, 0, BL_PC, sd->bl.id, time); return 0; } diff --git a/src/map/clif.c b/src/map/clif.c index ddda47612..a1c413398 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -278,12 +278,12 @@ int clif_send(const uint8* buf, int len, struct block_list* bl, enum send_target clif_send (buf, len, bl, SELF); case AREA_WOC: case AREA_WOS: - map_foreachinarea(clif_send_sub, bl->m, bl->x-AREA_SIZE, bl->y-AREA_SIZE, bl->x+AREA_SIZE, bl->y+AREA_SIZE, + map_forsomeinarea(clif_send_sub, bl->m, bl->x-AREA_SIZE, bl->y-AREA_SIZE, bl->x+AREA_SIZE, bl->y+AREA_SIZE, 0, BL_PC, buf, len, bl, type); break; case AREA_CHAT_WOC: - map_foreachinarea(clif_send_sub, bl->m, bl->x-(AREA_SIZE-5), bl->y-(AREA_SIZE-5), - bl->x+(AREA_SIZE-5), bl->y+(AREA_SIZE-5), BL_PC, buf, len, bl, AREA_WOC); + map_forsomeinarea(clif_send_sub, bl->m, bl->x-(AREA_SIZE-5), bl->y-(AREA_SIZE-5), + bl->x+(AREA_SIZE-5), bl->y+(AREA_SIZE-5), 0, BL_PC, buf, len, bl, AREA_WOC); break; case CHAT: @@ -8142,7 +8142,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) // info about nearby objects // must use foreachinarea (CIRCULAR_AREA interferes with foreachinrange) - map_foreachinarea(clif_getareachar, sd->bl.m, sd->bl.x-AREA_SIZE, sd->bl.y-AREA_SIZE, sd->bl.x+AREA_SIZE, sd->bl.y+AREA_SIZE, BL_ALL, sd); + map_forsomeinarea(clif_getareachar, sd->bl.m, sd->bl.x-AREA_SIZE, sd->bl.y-AREA_SIZE, sd->bl.x+AREA_SIZE, sd->bl.y+AREA_SIZE, 0, BL_ALL, sd); //TODO: merge it with the code below if (battle_config.pet_no_gvg && map_flag_gvg(sd->bl.m) && sd->pd) diff --git a/src/map/map.c b/src/map/map.c index 1215246b1..ed706bcdb 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -650,7 +650,7 @@ int map_foreachinshootrange(int (*func)(struct block_list*,va_list),struct block * funcを呼ぶ * type!=0 ならその種類のみ *------------------------------------------*/ -int map_foreachinarea(int (*func)(struct block_list*,va_list), int m, int x0, int y0, int x1, int y1, int type, ...) +int map_forsomeinarea(int (*func)(struct block_list*,va_list), int m, int x0, int y0, int x1, int y1, int count, int type, ...) { int bx,by; int returnCount =0; //total sum of returned values of func() [Skotlex] @@ -702,6 +702,8 @@ int map_foreachinarea(int (*func)(struct block_list*,va_list), int m, int x0, in va_start(ap, type); returnCount += func(bl_list[i], ap); va_end(ap); + if( count && returnCount >= count) + break; } map_freeblock_unlock(); // 解放を許可する @@ -1295,9 +1297,9 @@ int map_search_freecell(struct block_list *src, int m, short *x,short *y, int rx if(flag&4) { if (spawn >= 100) return 0; //Limit of retries reached. if (spawn++ < battle_config.no_spawn_on_player && - map_foreachinarea(map_count_sub, m, + map_forsomeinarea(map_count_sub, m, *x-AREA_SIZE, *y-AREA_SIZE, - *x+AREA_SIZE, *y+AREA_SIZE, BL_PC) + *x+AREA_SIZE, *y+AREA_SIZE, 0, BL_PC) ) continue; } diff --git a/src/map/map.h b/src/map/map.h index 101be46cf..98e15ab5a 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -530,7 +530,7 @@ int map_delblock(struct block_list* bl); int map_moveblock(struct block_list *, int, int, unsigned int); int map_foreachinrange(int (*func)(struct block_list*,va_list), struct block_list* center, int range, int type, ...); int map_foreachinshootrange(int (*func)(struct block_list*,va_list), struct block_list* center, int range, int type, ...); -int map_foreachinarea(int (*func)(struct block_list*,va_list), int m, int x0, int y0, int x1, int y1, int type, ...); +int map_forsomeinarea(int (*func)(struct block_list*,va_list), int m, int x0, int y0, int x1, int y1, int count, int type, ...); int map_foreachinmovearea(int (*func)(struct block_list*,va_list), struct block_list* center, int range, int dx, int dy, int type, ...); int map_foreachincell(int (*func)(struct block_list*,va_list), int m, int x, int y, int type, ...); int map_foreachinpath(int (*func)(struct block_list*,va_list), int m, int x0, int y0, int x1, int y1, int range, int length, int type, ...); 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) diff --git a/src/map/npc.h b/src/map/npc.h index dcb112966..5bbb29fa4 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -34,6 +34,7 @@ struct npc_data { char name[NAME_LENGTH+1];// display name char exname[NAME_LENGTH+1];// unique npc name int chat_id; + int touching_id; unsigned int next_walktime; unsigned size : 2; @@ -101,6 +102,7 @@ int npc_event(struct map_session_data* sd, const char* eventname, int mob_kill); int npc_touch_areanpc(struct map_session_data* sd, int m, int x, int y); int npc_touch_areanpc2(struct mob_data *md); // [Skotlex] int npc_check_areanpc(int flag, int m, int x, int y, int range); +int npc_touchnext_areanpc(struct map_session_data* sd,bool logout); int npc_click(struct map_session_data* sd, struct npc_data* nd); int npc_scriptcont(struct map_session_data* sd, int id); struct npc_data* npc_checknear(struct map_session_data* sd, struct block_list* bl); diff --git a/src/map/pc.h b/src/map/pc.h index 8695d78b2..6569b86c7 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -161,6 +161,10 @@ struct map_session_data { unsigned char head_dir; //0: Look forward. 1: Look right, 2: Look left. unsigned int client_tick; int npc_id,areanpc_id,npc_shopid; + struct { + int npc_id; + short x,y; + } ontouch; 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/script.c b/src/map/script.c index 0d781906c..6f34e3058 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -216,7 +216,9 @@ struct Script_Config script_config = { "OnPCLogoutEvent", //logout_event_name "OnPCLoadMapEvent", //loadmap_event_name "OnPCBaseLvUpEvent", //baselvup_event_name - "OnPCJobLvUpEvent" //joblvup_event_name + "OnPCJobLvUpEvent", //joblvup_event_name + "OnTouch", //Official version of OnTouch + "OnTouch2", //Official version of OnTouch2 }; static jmp_buf error_jump; @@ -3338,6 +3340,12 @@ int script_config_read(char *cfgName) else if(strcmpi(w1,"input_max_value")==0) { script_config.input_max_value = config_switch(w2); } + else if(strcmpi(w1, "OnTouch_Label") == 0) { + safestrncpy(script_config.ontouch_name, w2, NAME_LENGTH); + } + else if(strcmpi(w1, "OnTouch2_Label") == 0) { + safestrncpy(script_config.ontouch2_name, w2, NAME_LENGTH); + } else if(strcmpi(w1,"import")==0){ script_config_read(w2); } @@ -4110,7 +4118,7 @@ BUILDIN_FUNC(areawarp) else if(!(index=mapindex_name2id(str))) return 0; - map_foreachinarea(buildin_areawarp_sub, m,x0,y0,x1,y1,BL_PC, index,x,y); + map_forsomeinarea(buildin_areawarp_sub, m,x0,y0,x1,y1,0,BL_PC, index,x,y); return 0; } @@ -4142,7 +4150,7 @@ BUILDIN_FUNC(areapercentheal) if( (m=map_mapname2mapid(mapname))< 0) return 0; - map_foreachinarea(buildin_areapercentheal_sub,m,x0,y0,x1,y1,BL_PC,hp,sp); + map_forsomeinarea(buildin_areapercentheal_sub,m,x0,y0,x1,y1,0,BL_PC,hp,sp); return 0; } @@ -8170,8 +8178,8 @@ BUILDIN_FUNC(areaannounce) if( (m=map_mapname2mapid(map))<0 ) return 0; - map_foreachinarea(buildin_mapannounce_sub, - m,x0,y0,x1,y1,BL_PC, str,strlen(str)+1,flag&0x10, color); + map_forsomeinarea(buildin_mapannounce_sub, + m,x0,y0,x1,y1,0,BL_PC, str,strlen(str)+1,flag&0x10, color); return 0; } @@ -8281,8 +8289,8 @@ BUILDIN_FUNC(getareausers) script_pushint(st,-1); return 0; } - map_foreachinarea(buildin_getareausers_sub, - m,x0,y0,x1,y1,BL_PC,&users); + map_forsomeinarea(buildin_getareausers_sub, + m,x0,y0,x1,y1,0,BL_PC,&users); script_pushint(st,users); return 0; } @@ -8328,8 +8336,8 @@ BUILDIN_FUNC(getareadropitem) script_pushint(st,-1); return 0; } - map_foreachinarea(buildin_getareadropitem_sub, - m,x0,y0,x1,y1,BL_ITEM,item,&amount); + map_forsomeinarea(buildin_getareadropitem_sub, + m,x0,y0,x1,y1,0,BL_ITEM,item,&amount); script_pushint(st,amount); return 0; } @@ -10639,7 +10647,7 @@ BUILDIN_FUNC(soundeffectall) int y0 = script_getnum(st,6); int x1 = script_getnum(st,7); int y1 = script_getnum(st,8); - map_foreachinarea(soundeffect_sub, map_mapname2mapid(map), x0, y0, x1, y1, BL_PC, name, type); + map_forsomeinarea(soundeffect_sub, map_mapname2mapid(map), x0, y0, x1, y1, 0, BL_PC, name, type); } else { diff --git a/src/map/script.h b/src/map/script.h index 79822031c..fd329116e 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -25,6 +25,9 @@ extern struct Script_Config { const char *loadmap_event_name; const char *baselvup_event_name; const char *joblvup_event_name; + + char ontouch_name[NAME_LENGTH]; + char ontouch2_name[NAME_LENGTH]; } script_config; typedef enum c_op { diff --git a/src/map/skill.c b/src/map/skill.c index 36a83ee14..715c00558 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1539,8 +1539,14 @@ int skill_blown(struct block_list* src, struct block_list* target, int count, in if(!(flag&0x1)) clif_blown(target); - if(target->type == BL_PC && map_getcell(target->m, target->x, target->y, CELL_CHKNPC)) - npc_touch_areanpc((TBL_PC*)target, target->m, target->x, target->y); //Invoke area NPC + if( target->type == BL_PC ) + { + if( map_getcell(target->m, target->x, target->y, CELL_CHKNPC) ) + npc_touch_areanpc((TBL_PC*)target, target->m, target->x, target->y); //Invoke area NPC + + if( ((TBL_PC*)target)->ontouch.npc_id ) + npc_touchnext_areanpc(((TBL_PC*)target),false); + } return count; //Return amount of knocked back cells. } @@ -2067,7 +2073,7 @@ static int skill_check_unit_range (struct block_list *bl, int x, int y, int skil } range += layout_type; - return map_foreachinarea(skill_check_unit_range_sub,bl->m,x-range,y-range,x+range,y+range,BL_SKILL,skillid); + return map_forsomeinarea(skill_check_unit_range_sub,bl->m,x-range,y-range,x+range,y+range,0,BL_SKILL,skillid); } static int skill_check_unit_range2_sub (struct block_list *bl, va_list ap) @@ -2117,8 +2123,8 @@ static int skill_check_unit_range2 (struct block_list *bl, int x, int y, int ski else type = BL_PC; - return map_foreachinarea(skill_check_unit_range2_sub, bl->m, - x - range, y - range, x + range, y + range, + return map_forsomeinarea(skill_check_unit_range2_sub, bl->m, + x - range, y - range, x + range, y + range,0, type, skillid); } @@ -2328,8 +2334,8 @@ static int skill_timerskill(int tid, unsigned int tick, int id, intptr data) case BA_FROSTJOKER: case DC_SCREAM: range= skill_get_splash(skl->skill_id, skl->skill_lv); - map_foreachinarea(skill_frostjoke_scream,skl->map,skl->x-range,skl->y-range, - skl->x+range,skl->y+range,BL_CHAR,src,skl->skill_id,skl->skill_lv,tick); + map_forsomeinarea(skill_frostjoke_scream,skl->map,skl->x-range,skl->y-range, + skl->x+range,skl->y+range,0,BL_CHAR,src,skl->skill_id,skl->skill_lv,tick); break; case NPC_EARTHQUAKE: skill_area_temp[0] = map_foreachinrange(skill_area_sub, src, skill_get_splash(skl->skill_id, skl->skill_lv), BL_CHAR, src, skl->skill_id, skl->skill_lv, tick, BCT_ENEMY, skill_area_sub_count); @@ -6173,32 +6179,32 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk case PR_BENEDICTIO: skill_area_temp[1] = src->id; i = skill_get_splash(skillid, skilllv); - map_foreachinarea(skill_area_sub, - src->m, x-i, y-i, x+i, y+i, BL_PC, + map_forsomeinarea(skill_area_sub, + src->m, x-i, y-i, x+i, y+i, 0,BL_PC, src, skillid, skilllv, tick, flag|BCT_ALL|1, skill_castend_nodamage_id); - map_foreachinarea(skill_area_sub, - src->m, x-i, y-i, x+i, y+i, BL_CHAR, + map_forsomeinarea(skill_area_sub, + src->m, x-i, y-i, x+i, y+i, 0,BL_CHAR, src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_damage_id); break; case BS_HAMMERFALL: i = skill_get_splash(skillid, skilllv); - map_foreachinarea (skill_area_sub, - src->m, x-i, y-i, x+i, y+i, BL_CHAR, + map_forsomeinarea (skill_area_sub, + src->m, x-i, y-i, x+i, y+i, 0,BL_CHAR, src, skillid, skilllv, tick, flag|BCT_ENEMY|2, skill_castend_nodamage_id); break; case HT_DETECTING: i = skill_get_splash(skillid, skilllv); - map_foreachinarea( status_change_timer_sub, - src->m, x-i, y-i, x+i,y+i,BL_CHAR, + map_forsomeinarea( status_change_timer_sub, + src->m, x-i, y-i, x+i,y+i,0,BL_CHAR, src,NULL,SC_SIGHT,tick); if(battle_config.traps_setting&1) - map_foreachinarea( skill_reveal_trap, - src->m, x-i, y-i, x+i,y+i,BL_SKILL); + map_forsomeinarea( skill_reveal_trap, + src->m, x-i, y-i, x+i,y+i,0,BL_SKILL); break; case SA_VOLCANO: @@ -6313,7 +6319,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk break; case RG_CLEANER: // [Valaris] i = skill_get_splash(skillid, skilllv); - map_foreachinarea(skill_graffitiremover,src->m,x-i,y-i,x+i,y+i,BL_SKILL); + map_forsomeinarea(skill_graffitiremover,src->m,x-i,y-i,x+i,y+i,0,BL_SKILL); break; case WZ_METEOR: @@ -6418,8 +6424,8 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk if(potion_hp > 0 || potion_sp > 0) { i = skill_get_splash(skillid, skilllv); - map_foreachinarea(skill_area_sub, - src->m,x-i,y-i,x+i,y+i,BL_CHAR, + map_forsomeinarea(skill_area_sub, + src->m,x-i,y-i,x+i,y+i,0,BL_CHAR, src,skillid,skilllv,tick,flag|BCT_PARTY|BCT_GUILD|1, skill_castend_nodamage_id); } @@ -6440,8 +6446,8 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk if(potion_hp > 0 || potion_sp > 0) { i = skill_get_splash(skillid, skilllv); - map_foreachinarea(skill_area_sub, - src->m,x-i,y-i,x+i,y+i,BL_CHAR, + map_forsomeinarea(skill_area_sub, + src->m,x-i,y-i,x+i,y+i,0,BL_CHAR, src,skillid,skilllv,tick,flag|BCT_PARTY|BCT_GUILD|1, skill_castend_nodamage_id); } @@ -6453,7 +6459,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk int dummy = 1; clif_skill_poseffect(src,skillid,skilllv,x,y,tick); i = skill_get_splash(skillid, skilllv); - map_foreachinarea(skill_cell_overlap, src->m, x-i, y-i, x+i, y+i, BL_SKILL, HW_GANBANTEIN, &dummy, src); + map_forsomeinarea(skill_cell_overlap, src->m, x-i, y-i, x+i, y+i, BL_SKILL, HW_GANBANTEIN, &dummy, src); } else { if (sd) clif_skill_fail(sd,skillid,0,0); return 1; diff --git a/src/map/status.c b/src/map/status.c index 61b269ace..bd9bba811 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -6200,6 +6200,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val break; } + if( sd && sd->ontouch.npc_id ) + npc_touchnext_areanpc(sd,false); + return 1; } /*========================================== @@ -6495,8 +6498,8 @@ int status_change_end(struct block_list* bl, enum sc_type type, int tid) int range = 1 +skill_get_range2(bl, status_sc2skill(type), sce->val1) +skill_get_range2(bl, TF_BACKSLIDING, 1); //Since most people use this to escape the hold.... - map_foreachinarea(status_change_timer_sub, - bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,BL_CHAR,bl,sce,type,gettick()); + map_forsomeinarea(status_change_timer_sub, + bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,0,BL_CHAR,bl,sce,type,gettick()); } break; case SC_COMBO: //Clear last used skill when it is part of a combo. diff --git a/src/map/unit.c b/src/map/unit.c index 0ba48b32b..c75600180 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -171,6 +171,10 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr data) return 0; } else sd->areanpc_id=0; + + if( sd->ontouch.npc_id ) + npc_touchnext_areanpc(sd,false); + if (sd->state.gmaster_flag && (battle_config.guild_aura&((agit_flag || agit2_flag)?2:1)) && (battle_config.guild_aura&(map_flag_gvg2(bl->m)?8:4)) @@ -520,6 +524,10 @@ int unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, bool return 0; } else sd->areanpc_id=0; + + if( sd->ontouch.npc_id ) + npc_touchnext_areanpc(sd,false); + if( sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > 0 ) { // Check if pet needs to be teleported. [Skotlex] int flag = 0; @@ -1804,6 +1812,8 @@ int unit_remove_map_(struct block_list *bl, int clrtype, const char* file, int l guild_reply_reqalliance(sd,sd->guild_alliance_account,0); if(sd->menuskill_id) sd->menuskill_id = sd->menuskill_val = 0; + if( sd->ontouch.npc_id ) + npc_touchnext_areanpc(sd,true); sd->npc_shopid = 0; sd->adopt_invite = 0; |