From 5736970973fefa2a1e10a1847c9bb12bd2cb0719 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Thu, 4 Dec 2014 01:02:42 +0300 Subject: add npc area size field. --- src/map/npc.c | 19 +++++++++++++------ src/map/npc.h | 1 + 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/map/npc.c b/src/map/npc.c index 8c2f61d58..9731250f3 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -1086,22 +1086,28 @@ int npc_check_areanpc(int flag, int16 m, int16 x, int16 y, int16 range) { struct npc_data* npc_checknear(struct map_session_data* sd, struct block_list* bl) { struct npc_data *nd; + int distance = AREA_SIZE + 1; nullpo_retr(NULL, sd); - if(bl == NULL) return NULL; - if(bl->type != BL_NPC) return NULL; + if (bl == NULL) return NULL; + if (bl->type != BL_NPC) return NULL; nd = (TBL_NPC*)bl; - if(sd->state.using_fake_npc && sd->npc_id == bl->id) + if (sd->state.using_fake_npc && sd->npc_id == bl->id) return nd; if (nd->class_<0) //Class-less npc, enable click from anywhere. return nd; - if (bl->m!=sd->bl.m || - bl->xbl.x-AREA_SIZE-1 || bl->x>sd->bl.x+AREA_SIZE+1 || - bl->ybl.y-AREA_SIZE-1 || bl->y>sd->bl.y+AREA_SIZE+1) + if (distance > nd->area_size) + distance = nd->area_size; + + if (bl->m != sd->bl.m || + bl->x < sd->bl.x - distance || bl->x > sd->bl.x + distance || + bl->y < sd->bl.y - distance || bl->y > sd->bl.y + distance) + { return NULL; + } return nd; } @@ -2505,6 +2511,7 @@ struct npc_data* npc_create_npc(int m, int x, int y) nd->bl.m = m; nd->bl.x = x; nd->bl.y = y; + nd->area_size = AREA_SIZE + 1; return nd; } diff --git a/src/map/npc.h b/src/map/npc.h index fba14d485..0825faf10 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -61,6 +61,7 @@ struct npc_data { int touching_id; int64 next_walktime; uint8 dir; + uint8 area_size; unsigned size : 2; -- cgit v1.2.3-60-g2f50 From 058dabd69eb190f507e56747e5f25f68b935ec69 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Thu, 4 Dec 2014 01:18:28 +0300 Subject: Add script command to set npc click/activate instance. New script command: setnpcdistance N Where N is distance in tiles from where npc can be clicked. Add setnpcdistance into docs. --- doc/script_commands.txt | 11 +++++++++++ src/map/script.c | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 3467a5366..36b52988b 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -7558,6 +7558,17 @@ config, and will not work properly if the NPC has a mob sprite. --------------------------------------- +*setnpcdistance + +This command can reduce distance from where npc can be clicked. +Usefull to use from OnInit event. + + // Set distance to one tile on server load + OnInit: + setnpcdistance 1; + +--------------------------------------- + *day; *night; diff --git a/src/map/script.c b/src/map/script.c index a458bab49..5be4347ec 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -13311,6 +13311,16 @@ BUILDIN(npcstop) { return true; } +BUILDIN(setnpcdistance) { + struct npc_data *nd = (struct npc_data *) map->id2bl (st->oid); + if (!nd) + return false; + + nd->area_size = script_getnum(st, 2); + + return true; +} + /*========================================== * getlook char info. getlook(arg) @@ -19378,6 +19388,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(npcspeed,"i"), // [Valaris] BUILDIN_DEF(npcwalkto,"ii"), // [Valaris] BUILDIN_DEF(npcstop,""), // [Valaris] + BUILDIN_DEF(setnpcdistance,"i"), // [4144] BUILDIN_DEF(getmapxy,"rrri?"), //by Lorky [Lupus] BUILDIN_DEF(checkoption1,"i"), BUILDIN_DEF(checkoption2,"i"), -- cgit v1.2.3-60-g2f50 From 4ae220311093cb344a27052ebc90358748435be6 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Thu, 4 Dec 2014 02:14:35 +0300 Subject: Fix script error termination if already running script continue from very far npc. Note for Haruna: possible it may add side effects. Need check. --- src/map/npc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/map/npc.c b/src/map/npc.c index 9731250f3..c0e61e41f 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -1093,7 +1093,7 @@ struct npc_data* npc_checknear(struct map_session_data* sd, struct block_list* b if (bl->type != BL_NPC) return NULL; nd = (TBL_NPC*)bl; - if (sd->state.using_fake_npc && sd->npc_id == bl->id) + if (sd->npc_id == bl->id) return nd; if (nd->class_<0) //Class-less npc, enable click from anywhere. -- cgit v1.2.3-60-g2f50 From b681deae9fdee3a219ddf43b76a553c57733f237 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sat, 6 Dec 2014 20:51:57 +0300 Subject: Add getnpcdir and setnpcdir functions. --- doc/script_commands.txt | 19 ++++++++++++++ src/map/script.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 36b52988b..642b67fe3 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -7569,6 +7569,25 @@ Usefull to use from OnInit event. --------------------------------------- +*getnpcdir {}; + +Return current npc direction for parameter "name" or for attached npc +if it missing. If name missing and not attached npc, return -1. + +Example: + .@dir = getnpcdir(); + +--------------------------------------- + +*setnpcdir {,} ; + +Set npc direction. If npc name missing, will be used attached npc. + +Example: + setnpcdir 2; + +--------------------------------------- + *day; *night; diff --git a/src/map/script.c b/src/map/script.c index 5be4347ec..5d9220297 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -13311,6 +13311,7 @@ BUILDIN(npcstop) { return true; } +// set click npc distance [4144] BUILDIN(setnpcdistance) { struct npc_data *nd = (struct npc_data *) map->id2bl (st->oid); if (!nd) @@ -13321,6 +13322,72 @@ BUILDIN(setnpcdistance) { return true; } +// return current npc direction [4144] +BUILDIN(getnpcdir) +{ + struct npc_data *nd = 0; + + if (script_hasdata(st, 2)) + { + nd = npc->name2id (script_getstr(st, 2)); + } + if (!nd && !st->oid) + { + script_pushint(st, -1); + return true; + } + + if (!nd) + nd = (struct npc_data *) map->id2bl (st->oid); + + if (!nd) + { + script_pushint(st, -1); + return true; + } + + script_pushint(st, (int)nd->dir); + + return true; +} + +// set npc direction [4144] +BUILDIN(setnpcdir) +{ + int newdir; + struct npc_data *nd = 0; + + if (script_hasdata(st, 3)) + { + nd = npc->name2id (script_getstr(st, 2)); + newdir = script_getnum(st, 3); + } + else if (script_hasdata(st, 2)) + { + if (!st->oid) + return false; + + nd = (struct npc_data *) map->id2bl (st->oid); + newdir = script_getnum(st, 2); + } + if (!nd) + return false; + + if (newdir < 0) + newdir = 0; + else if (newdir > 7) + newdir = 7; + + nd->dir = newdir; + if (nd->ud) + nd->ud->dir = newdir; + + clif->clearunit_area(&nd->bl, CLR_OUTSIGHT); + clif->spawn(&nd->bl); + + return true; +} + /*========================================== * getlook char info. getlook(arg) @@ -19389,6 +19456,8 @@ void script_parse_builtin(void) { BUILDIN_DEF(npcwalkto,"ii"), // [Valaris] BUILDIN_DEF(npcstop,""), // [Valaris] BUILDIN_DEF(setnpcdistance,"i"), // [4144] + BUILDIN_DEF(getnpcdir,"?"), // [4144] + BUILDIN_DEF(setnpcdir,"*"), // [4144] BUILDIN_DEF(getmapxy,"rrri?"), //by Lorky [Lupus] BUILDIN_DEF(checkoption1,"i"), BUILDIN_DEF(checkoption2,"i"), -- cgit v1.2.3-60-g2f50 From ac4a461a4054eb814ff3df089d9caa96a4343a3d Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sat, 6 Dec 2014 21:09:27 +0300 Subject: Add script command getnpcclass. --- doc/script_commands.txt | 10 ++++++++++ src/map/script.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 642b67fe3..fb4c2530d 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -7588,6 +7588,16 @@ Example: --------------------------------------- +*getnpcclass {}; + +Return npc class/sprite id for npc with given name or for attached npc. +If name missing and no attached npc, return -1. + +Example: + .@class = getnpcclass(); + +--------------------------------------- + *day; *night; diff --git a/src/map/script.c b/src/map/script.c index 5d9220297..84179a64e 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -13388,6 +13388,35 @@ BUILDIN(setnpcdir) return true; } +// return npc class [4144] +BUILDIN(getnpcclass) +{ + struct npc_data *nd = 0; + + if (script_hasdata(st, 2)) + { + nd = npc->name2id (script_getstr(st, 2)); + } + if (!nd && !st->oid) + { + script_pushint(st, -1); + return false; + } + + if (!nd) + nd = (struct npc_data *) map->id2bl(st->oid); + + if (!nd) + { + script_pushint(st, -1); + return false; + } + + script_pushint(st, (int)nd->class_); + + return true; +} + /*========================================== * getlook char info. getlook(arg) @@ -19458,6 +19487,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(setnpcdistance,"i"), // [4144] BUILDIN_DEF(getnpcdir,"?"), // [4144] BUILDIN_DEF(setnpcdir,"*"), // [4144] + BUILDIN_DEF(getnpcclass,"?"), // [4144] BUILDIN_DEF(getmapxy,"rrri?"), //by Lorky [Lupus] BUILDIN_DEF(checkoption1,"i"), BUILDIN_DEF(checkoption2,"i"), -- cgit v1.2.3-60-g2f50 From 54b5a4d666eae9692ff06746c2ae68d9e1b49641 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sun, 7 Dec 2014 15:47:16 +0300 Subject: Fix incorrect memory access in script command getareausers. --- src/map/script.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/map/script.c b/src/map/script.c index 84179a64e..e59159586 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -10094,7 +10094,8 @@ int buildin_getareausers_sub(struct block_list *bl,va_list ap) BUILDIN(getareausers) { const char *str; - int16 m,x0,y0,x1,y1,users=0; //doubt we can have more then 32k users on + int16 m,x0,y0,x1,y1; + int users = 0; str=script_getstr(st,2); x0=script_getnum(st,3); y0=script_getnum(st,4); -- cgit v1.2.3-60-g2f50 From 625ed85b6a3d88587e8927f1f640f1fadd3dc642 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sun, 7 Dec 2014 17:18:45 +0300 Subject: Extend script command getareausers. --- doc/script_commands.txt | 13 +++++++--- src/map/script.c | 69 +++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 66 insertions(+), 16 deletions(-) diff --git a/doc/script_commands.txt b/doc/script_commands.txt index fb4c2530d..4909699c3 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -3226,15 +3226,22 @@ let you enter. --------------------------------------- -*getareausers("",,,,) +*getareausers({"",}{,,,}) +*getareausers({"",}{}) This function will return the count of connected characters which are -located within the specified area - an x1/y1-x2/y2 square - on the -specified map. +located within the specified area. Area can be x1/y1-x2/y2 square, +or radius from npc position. If map name missing, used attached player map. This is useful for maps that are split into many buildings, such as all the "*_in" maps, due to all the shops and houses. +Examples: + // return players in area npc area on current map. + .@num = getareausers(); + // return players in square (1, 1) - (10, 10) + .@num = "players: " + getareausers(1, 1, 10, 10); + --------------------------------------- *getusersname; diff --git a/src/map/script.c b/src/map/script.c index e59159586..fbfb88de2 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -10093,21 +10093,64 @@ int buildin_getareausers_sub(struct block_list *bl,va_list ap) } BUILDIN(getareausers) { - const char *str; - int16 m,x0,y0,x1,y1; + int16 m = -1, x0, y0, x1, y1; int users = 0; - str=script_getstr(st,2); - x0=script_getnum(st,3); - y0=script_getnum(st,4); - x1=script_getnum(st,5); - y1=script_getnum(st,6); - if( (m=map->mapname2mapid(str))< 0) { - script_pushint(st,-1); - return true; + int idx = 2; + struct npc_data *nd = NULL; + if (script_hasdata(st, 2) && script_isstringtype(st, 2)) { + const char *str = script_getstr(st, 2); + if ((m = map->mapname2mapid(str)) < 0) { + script_pushint(st, -1); + return true; + } + idx = 3; + } + if (m == -1) + { + TBL_PC *sd = NULL; + sd = script->rid2sd(st); + if (!sd) + { + script_pushint(st, -1); + return false; + } + m = sd->bl.m; + } + if (st->oid) + nd = map->id2nd(st->oid); + if (script_hasdata(st, idx + 3)) { + x0 = script_getnum(st, idx + 0); + y0 = script_getnum(st, idx + 1); + x1 = script_getnum(st, idx + 2); + y1 = script_getnum(st, idx + 3); + } else if (script_hasdata(st, idx)) { + if (!nd) + { + script_pushint(st, -1); + return true; + } + int sz = script_getnum(st, idx); + x0 = nd->bl.x - sz; + y0 = nd->bl.y - sz; + x1 = nd->bl.x + sz; + y1 = nd->bl.y + sz; + } else if (st->oid) { + if (!nd || nd->u.scr.xs == -1 || nd->u.scr.ys == -1) + { + script_pushint(st, -1); + return true; + } + x0 = nd->bl.x - nd->u.scr.xs; + y0 = nd->bl.y - nd->u.scr.ys; + x1 = nd->bl.x + nd->u.scr.xs; + y1 = nd->bl.y + nd->u.scr.ys; + } else { + script_pushint(st, -1); + return false; } map->foreachinarea(script->buildin_getareausers_sub, - m,x0,y0,x1,y1,BL_PC,&users); - script_pushint(st,users); + m, x0, y0, x1, y1, BL_PC, &users); + script_pushint(st, users); return true; } @@ -19382,7 +19425,7 @@ void script_parse_builtin(void) { BUILDIN_DEF(getusers,"i"), BUILDIN_DEF(getmapguildusers,"si"), BUILDIN_DEF(getmapusers,"s"), - BUILDIN_DEF(getareausers,"siiii"), + BUILDIN_DEF(getareausers,"*"), BUILDIN_DEF(getareadropitem,"siiiiv"), BUILDIN_DEF(enablenpc,"s"), BUILDIN_DEF(disablenpc,"s"), -- cgit v1.2.3-60-g2f50 From 61d6c958d5a753904d32ef2057b50f426bb0f3b9 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sun, 7 Dec 2014 18:19:57 +0300 Subject: Add function what call OnUntouch event. --- src/map/npc.c | 16 ++++++++++++++-- src/map/npc.h | 1 + src/map/script.c | 5 +++-- src/map/script.h | 1 + 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/map/npc.c b/src/map/npc.c index c0e61e41f..63514710f 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -139,11 +139,22 @@ int npc_ontouch2_event(struct map_session_data *sd, struct npc_data *nd) { char name[EVENT_NAME_LENGTH]; - if( sd->areanpc_id == nd->bl.id ) + 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); + return npc->event(sd, name, 2); +} + +int npc_onuntouch_event(struct map_session_data *sd, struct npc_data *nd) +{ + char name[EVENT_NAME_LENGTH]; + + if (sd->areanpc_id == nd->bl.id) + return 0; + + snprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script->config.onuntouch_name); + return npc->event(sd, name, 2); } /*========================================== @@ -4614,6 +4625,7 @@ void npc_defaults(void) { npc->isnear = npc_isnear; npc->ontouch_event = npc_ontouch_event; npc->ontouch2_event = npc_ontouch2_event; + npc->onuntouch_event = npc_onuntouch_event; npc->enable_sub = npc_enable_sub; npc->enable = npc_enable; npc->name2id = npc_name2id; diff --git a/src/map/npc.h b/src/map/npc.h index 0825faf10..cb8f09644 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -182,6 +182,7 @@ struct npc_interface { bool (*isnear) (struct block_list *bl); int (*ontouch_event) (struct map_session_data *sd, struct npc_data *nd); int (*ontouch2_event) (struct map_session_data *sd, struct npc_data *nd); + int (*onuntouch_event) (struct map_session_data *sd, struct npc_data *nd); int (*enable_sub) (struct block_list *bl, va_list ap); int (*enable) (const char *name, int flag); struct npc_data* (*name2id) (const char *name); diff --git a/src/map/script.c b/src/map/script.c index fbfb88de2..3ccb6a45a 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -20124,8 +20124,9 @@ void script_defaults(void) { script->config.loadmap_event_name = "OnPCLoadMapEvent"; script->config.baselvup_event_name = "OnPCBaseLvUpEvent"; script->config.joblvup_event_name = "OnPCJobLvUpEvent"; - script->config.ontouch_name = "OnTouch_";//ontouch_name (runs on first visible char to enter area, picks another char if the first char leaves) - script->config.ontouch2_name = "OnTouch";//ontouch2_name (run whenever a char walks into the OnTouch area) + script->config.ontouch_name = "OnTouch_"; //ontouch_name (runs on first visible char to enter area, picks another char if the first char leaves) + script->config.ontouch2_name = "OnTouch"; //ontouch2_name (run whenever a char walks into the OnTouch area) + script->config.onuntouch_name = "OnUnTouch"; //onuntouch_name (run whenever a char walks from the OnTouch area) // for ENABLE_CASE_CHECK script->calc_hash_ci = calc_hash_ci; diff --git a/src/map/script.h b/src/map/script.h index e28abf970..548c0f261 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -343,6 +343,7 @@ struct Script_Config { const char* ontouch_name; const char* ontouch2_name; + const char* onuntouch_name; }; /** -- cgit v1.2.3-60-g2f50 From 3a0bded54bcc5390bf6cd4be9e53206e1bc9e5c2 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sun, 7 Dec 2014 18:47:55 +0300 Subject: Add function what called if player leave npc area. --- src/map/clif.c | 2 +- src/map/npc.c | 11 +++++++++++ src/map/npc.h | 1 + src/map/status.c | 8 ++++++-- src/map/unit.c | 6 +++--- 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/map/clif.c b/src/map/clif.c index 173175260..3515bb806 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -9597,7 +9597,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; + npc->untouch_areanpc(sd, sd->bl.m, sd->bl.x, sd->bl.y); /* 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/npc.c b/src/map/npc.c index 63514710f..77e99ecc5 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -975,6 +975,16 @@ int npc_touch_areanpc(struct map_session_data* sd, int16 m, int16 x, int16 y) return 0; } +/*========================================== + * Exec OnUnTouch for player if out range of area event + *------------------------------------------*/ +int npc_untouch_areanpc(struct map_session_data* sd, int16 m, int16 x, int16 y) +{ + nullpo_retr(1, sd); + sd->areanpc_id = 0; + return 0; +} + // OnTouch NPC or Warp for Mobs // Return 1 if Warped int npc_touch_areanpc2(struct mob_data *md) @@ -4650,6 +4660,7 @@ void npc_defaults(void) { npc->touch_areanpc_sub = npc_touch_areanpc_sub; npc->touchnext_areanpc = npc_touchnext_areanpc; npc->touch_areanpc = npc_touch_areanpc; + npc->untouch_areanpc = npc_untouch_areanpc; npc->touch_areanpc2 = npc_touch_areanpc2; npc->check_areanpc = npc_check_areanpc; npc->checknear = npc_checknear; diff --git a/src/map/npc.h b/src/map/npc.h index cb8f09644..a5a2b4676 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -207,6 +207,7 @@ struct npc_interface { int (*touch_areanpc_sub) (struct block_list *bl, va_list ap); int (*touchnext_areanpc) (struct map_session_data *sd, bool leavemap); int (*touch_areanpc) (struct map_session_data *sd, int16 m, int16 x, int16 y); + int (*untouch_areanpc) (struct map_session_data *sd, int16 m, int16 x, int16 y); int (*touch_areanpc2) (struct mob_data *md); int (*check_areanpc) (int flag, int16 m, int16 x, int16 y, int16 range); struct npc_data* (*checknear) (struct map_session_data *sd, struct block_list *bl); diff --git a/src/map/status.c b/src/map/status.c index 54b4a4358..e0d8d4f9b 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -10466,8 +10466,12 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const if(opt_flag&4) //Out of hiding, invoke on place. skill->unit_move(bl,timer->gettick(),1); - if(opt_flag&2 && sd && map->getcell(bl->m,bl->x,bl->y,CELL_CHKNPC)) - npc->touch_areanpc(sd,bl->m,bl->x,bl->y); //Trigger on-touch event. + if (opt_flag & 2 && sd) { + if (map->getcell(bl->m,bl->x,bl->y,CELL_CHKNPC)) + npc->touch_areanpc(sd,bl->m,bl->x,bl->y); //Trigger on-touch event. + else + npc->untouch_areanpc(sd, bl->m, bl->x, bl->y); + } ers_free(status->data_ers, sce); return 1; diff --git a/src/map/unit.c b/src/map/unit.c index 64885541f..0924e6cf2 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -309,7 +309,7 @@ int unit_walktoxy_timer(int tid, int64 tick, int id, intptr_t data) { if (bl->prev == NULL) //Script could have warped char, abort remaining of the function. return 0; } else - sd->areanpc_id=0; + npc->untouch_areanpc(sd, bl->m, x, y); if( sd->md ) { // mercenary should be warped after being 3 seconds too far from the master [greenbox] if( !check_distance_bl(&sd->bl, &sd->md->bl, MAX_MER_DISTANCE) ) { @@ -767,7 +767,7 @@ int unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, bool if (bl->prev == NULL) //Script could have warped char, abort remaining of the function. return 0; } else - sd->areanpc_id=0; + npc->untouch_areanpc(sd, bl->m, bl->x, bl->y); if( sd->status.pet_id > 0 && sd->pd && sd->pd->pet.intimate > 0 ) { // Check if pet needs to be teleported. [Skotlex] @@ -867,7 +867,7 @@ int unit_blown(struct block_list* bl, int dx, int dy, int count, int flag) 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; + npc->untouch_areanpc(sd, bl->m, bl->x, bl->y);; } } } -- cgit v1.2.3-60-g2f50 From 3ea017f844af342a24b75c278e69b2821056c2a1 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sun, 7 Dec 2014 19:24:28 +0300 Subject: If player left npc, call onUnTouch event. --- src/map/npc.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/map/npc.c b/src/map/npc.c index 77e99ecc5..8b5bbc83e 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -150,7 +150,7 @@ int npc_onuntouch_event(struct map_session_data *sd, struct npc_data *nd) { char name[EVENT_NAME_LENGTH]; - if (sd->areanpc_id == nd->bl.id) + if (sd->areanpc_id != nd->bl.id) return 0; snprintf(name, ARRAYLENGTH(name), "%s::%s", nd->exname, script->config.onuntouch_name); @@ -980,7 +980,14 @@ int npc_touch_areanpc(struct map_session_data* sd, int16 m, int16 x, int16 y) *------------------------------------------*/ int npc_untouch_areanpc(struct map_session_data* sd, int16 m, int16 x, int16 y) { + struct npc_data *nd; nullpo_retr(1, sd); + + if (!sd->areanpc_id) + return 0; + + nd = (struct npc_data *) map->id2bl(sd->areanpc_id); + npc->onuntouch_event(sd, nd); sd->areanpc_id = 0; return 0; } -- cgit v1.2.3-60-g2f50 From 4e546bb97afdc3d4a0a29325b88942873ed676a3 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sun, 7 Dec 2014 19:42:37 +0300 Subject: Add OnUnTouch event/label into scripts documentation. --- doc/script_commands.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 4909699c3..3c99afcf1 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -259,7 +259,8 @@ direction across Y. Walking into that area will trigger the NPC. If no 'OnTouch:' special label is present in the NPC code, the execution will start from the beginning of the script, otherwise, it will start from the 'OnTouch:' label. Monsters can also trigger the NPC, though the label -'OnTouchNPC:' is used in this case. +'OnTouchNPC:' is used in this case. If player left area npc will called +if present label 'OnUnTouch'. The code part is the script code that will execute whenever the NPC is triggered. It may contain commands and function calls, descriptions of @@ -1040,6 +1041,12 @@ OnTouch_: Similar to OnTouch, but will only run one instance. Another character is chosen once the triggering character leaves the area. +OnUnTouch: + +This label will be executed if plater leave trigger area is defined for the NPC +object it's in. If it isn't present, nothing will happend. +The RID of the triggering character object will be attached. + OnPCLoginEvent: OnPCLogoutEvent: OnPCBaseLvUpEvent: -- cgit v1.2.3-60-g2f50 From 445bb7d0595832b3fed3ad3218073c4f6b6bb207 Mon Sep 17 00:00:00 2001 From: "Hercules.ws" Date: Tue, 16 Dec 2014 21:05:23 +0100 Subject: HPM Hooks Update Signed-off-by: HerculesWSAPI --- .../HPMHooking/HPMHooking_map.HPMHooksCore.inc | 8 ++++ .../HPMHooking/HPMHooking_map.HookingPoints.inc | 2 + src/plugins/HPMHooking/HPMHooking_map.Hooks.inc | 54 ++++++++++++++++++++++ 3 files changed, 64 insertions(+) diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc index 74e765cee..a68afc9ed 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc @@ -3205,6 +3205,8 @@ struct { struct HPMHookPoint *HP_npc_ontouch_event_post; struct HPMHookPoint *HP_npc_ontouch2_event_pre; struct HPMHookPoint *HP_npc_ontouch2_event_post; + struct HPMHookPoint *HP_npc_onuntouch_event_pre; + struct HPMHookPoint *HP_npc_onuntouch_event_post; struct HPMHookPoint *HP_npc_enable_sub_pre; struct HPMHookPoint *HP_npc_enable_sub_post; struct HPMHookPoint *HP_npc_enable_pre; @@ -3253,6 +3255,8 @@ struct { struct HPMHookPoint *HP_npc_touchnext_areanpc_post; struct HPMHookPoint *HP_npc_touch_areanpc_pre; struct HPMHookPoint *HP_npc_touch_areanpc_post; + struct HPMHookPoint *HP_npc_untouch_areanpc_pre; + struct HPMHookPoint *HP_npc_untouch_areanpc_post; struct HPMHookPoint *HP_npc_touch_areanpc2_pre; struct HPMHookPoint *HP_npc_touch_areanpc2_post; struct HPMHookPoint *HP_npc_check_areanpc_pre; @@ -8276,6 +8280,8 @@ struct { int HP_npc_ontouch_event_post; int HP_npc_ontouch2_event_pre; int HP_npc_ontouch2_event_post; + int HP_npc_onuntouch_event_pre; + int HP_npc_onuntouch_event_post; int HP_npc_enable_sub_pre; int HP_npc_enable_sub_post; int HP_npc_enable_pre; @@ -8324,6 +8330,8 @@ struct { int HP_npc_touchnext_areanpc_post; int HP_npc_touch_areanpc_pre; int HP_npc_touch_areanpc_post; + int HP_npc_untouch_areanpc_pre; + int HP_npc_untouch_areanpc_post; int HP_npc_touch_areanpc2_pre; int HP_npc_touch_areanpc2_post; int HP_npc_check_areanpc_pre; diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc index 5d0545f82..e615b9767 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc @@ -1629,6 +1629,7 @@ struct HookingPointData HookingPoints[] = { { HP_POP(npc->isnear, HP_npc_isnear) }, { HP_POP(npc->ontouch_event, HP_npc_ontouch_event) }, { HP_POP(npc->ontouch2_event, HP_npc_ontouch2_event) }, + { HP_POP(npc->onuntouch_event, HP_npc_onuntouch_event) }, { HP_POP(npc->enable_sub, HP_npc_enable_sub) }, { HP_POP(npc->enable, HP_npc_enable) }, { HP_POP(npc->name2id, HP_npc_name2id) }, @@ -1653,6 +1654,7 @@ struct HookingPointData HookingPoints[] = { { HP_POP(npc->touch_areanpc_sub, HP_npc_touch_areanpc_sub) }, { HP_POP(npc->touchnext_areanpc, HP_npc_touchnext_areanpc) }, { HP_POP(npc->touch_areanpc, HP_npc_touch_areanpc) }, + { HP_POP(npc->untouch_areanpc, HP_npc_untouch_areanpc) }, { HP_POP(npc->touch_areanpc2, HP_npc_touch_areanpc2) }, { HP_POP(npc->check_areanpc, HP_npc_check_areanpc) }, { HP_POP(npc->checknear, HP_npc_checknear) }, diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc index 0169d43c7..cf4e0e871 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc @@ -42784,6 +42784,33 @@ int HP_npc_ontouch2_event(struct map_session_data *sd, struct npc_data *nd) { } return retVal___; } +int HP_npc_onuntouch_event(struct map_session_data *sd, struct npc_data *nd) { + int hIndex = 0; + int retVal___ = 0; + if( HPMHooks.count.HP_npc_onuntouch_event_pre ) { + int (*preHookFunc) (struct map_session_data *sd, struct npc_data *nd); + *HPMforce_return = false; + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_onuntouch_event_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_npc_onuntouch_event_pre[hIndex].func; + retVal___ = preHookFunc(sd, nd); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.npc.onuntouch_event(sd, nd); + } + if( HPMHooks.count.HP_npc_onuntouch_event_post ) { + int (*postHookFunc) (int retVal___, struct map_session_data *sd, struct npc_data *nd); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_onuntouch_event_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_npc_onuntouch_event_post[hIndex].func; + retVal___ = postHookFunc(retVal___, sd, nd); + } + } + return retVal___; +} int HP_npc_enable_sub(struct block_list *bl, va_list ap) { int hIndex = 0; int retVal___ = 0; @@ -43454,6 +43481,33 @@ int HP_npc_touch_areanpc(struct map_session_data *sd, int16 m, int16 x, int16 y) } return retVal___; } +int HP_npc_untouch_areanpc(struct map_session_data *sd, int16 m, int16 x, int16 y) { + int hIndex = 0; + int retVal___ = 0; + if( HPMHooks.count.HP_npc_untouch_areanpc_pre ) { + int (*preHookFunc) (struct map_session_data *sd, int16 *m, int16 *x, int16 *y); + *HPMforce_return = false; + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_untouch_areanpc_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_npc_untouch_areanpc_pre[hIndex].func; + retVal___ = preHookFunc(sd, &m, &x, &y); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.npc.untouch_areanpc(sd, m, x, y); + } + if( HPMHooks.count.HP_npc_untouch_areanpc_post ) { + int (*postHookFunc) (int retVal___, struct map_session_data *sd, int16 *m, int16 *x, int16 *y); + for(hIndex = 0; hIndex < HPMHooks.count.HP_npc_untouch_areanpc_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_npc_untouch_areanpc_post[hIndex].func; + retVal___ = postHookFunc(retVal___, sd, &m, &x, &y); + } + } + return retVal___; +} int HP_npc_touch_areanpc2(struct mob_data *md) { int hIndex = 0; int retVal___ = 0; -- cgit v1.2.3-60-g2f50 From d48884f776c943b32bf432076ac28180a4410b06 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Mon, 15 Dec 2014 13:57:12 +0300 Subject: Move check is item usable or not to separate method. New method: itemdb_is_item_usable Can be used as: itemdb->is_item_usable(item) --- src/map/itemdb.c | 9 +++++++++ src/map/itemdb.h | 1 + src/map/pc.c | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/map/itemdb.c b/src/map/itemdb.c index 508a0ccec..545ce9ba0 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -2054,6 +2054,14 @@ struct item_combo * itemdb_id2combo( unsigned short id ) { return itemdb->combos[id]; } +/** + * check is item have usable type + **/ +bool itemdb_is_item_usable(struct item_data *item) +{ + return item->type == IT_HEALING || item->type == IT_USABLE || item->type == IT_CASH; +} + /*========================================== * Initialize / Finalize *------------------------------------------*/ @@ -2337,4 +2345,5 @@ void itemdb_defaults(void) { itemdb->final_sub = itemdb_final_sub; itemdb->clear = itemdb_clear; itemdb->id2combo = itemdb_id2combo; + itemdb->is_item_usable = itemdb_is_item_usable; } diff --git a/src/map/itemdb.h b/src/map/itemdb.h index 5504d72d9..23339790e 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -610,6 +610,7 @@ struct itemdb_interface { int (*final_sub) (DBKey key, DBData *data, va_list ap); void (*clear) (bool total); struct item_combo * (*id2combo) (unsigned short id); + bool (*is_item_usable) (struct item_data *item); }; struct itemdb_interface *itemdb; diff --git a/src/map/pc.c b/src/map/pc.c index 5c6cac6e9..6c3a32152 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -4238,7 +4238,7 @@ int pc_isUseitem(struct map_session_data *sd,int n) if( item == NULL ) return 0; //Not consumable item - if( item->type != IT_HEALING && item->type != IT_USABLE && item->type != IT_CASH ) + if (!itemdb->is_item_usable(item)) return 0; if( !item->script ) //if it has no script, you can't really consume it! return 0; -- cgit v1.2.3-60-g2f50 From dd6393551b6c93a9c6ebf9fcbe45c3eecf89dc81 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Wed, 17 Dec 2014 00:38:15 +0300 Subject: Update HPM hooks. --- .../HPMHooking/HPMHooking_map.HPMHooksCore.inc | 4 ++++ .../HPMHooking/HPMHooking_map.HookingPoints.inc | 1 + src/plugins/HPMHooking/HPMHooking_map.Hooks.inc | 27 ++++++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc index a68afc9ed..7b9eadb91 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc @@ -2587,6 +2587,8 @@ struct { struct HPMHookPoint *HP_itemdb_clear_post; struct HPMHookPoint *HP_itemdb_id2combo_pre; struct HPMHookPoint *HP_itemdb_id2combo_post; + struct HPMHookPoint *HP_itemdb_is_item_usable_pre; + struct HPMHookPoint *HP_itemdb_is_item_usable_post; struct HPMHookPoint *HP_logs_pick_pc_pre; struct HPMHookPoint *HP_logs_pick_pc_post; struct HPMHookPoint *HP_logs_pick_mob_pre; @@ -7662,6 +7664,8 @@ struct { int HP_itemdb_clear_post; int HP_itemdb_id2combo_pre; int HP_itemdb_id2combo_post; + int HP_itemdb_is_item_usable_pre; + int HP_itemdb_is_item_usable_post; int HP_logs_pick_pc_pre; int HP_logs_pick_pc_post; int HP_logs_pick_mob_pre; diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc index e615b9767..58af99107 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc @@ -1312,6 +1312,7 @@ struct HookingPointData HookingPoints[] = { { HP_POP(itemdb->final_sub, HP_itemdb_final_sub) }, { HP_POP(itemdb->clear, HP_itemdb_clear) }, { HP_POP(itemdb->id2combo, HP_itemdb_id2combo) }, + { HP_POP(itemdb->is_item_usable, HP_itemdb_is_item_usable) }, /* logs */ { HP_POP(logs->pick_pc, HP_logs_pick_pc) }, { HP_POP(logs->pick_mob, HP_logs_pick_mob) }, diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc index cf4e0e871..62b1be620 100644 --- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc +++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc @@ -34264,6 +34264,33 @@ struct item_combo* HP_itemdb_id2combo(unsigned short id) { } return retVal___; } +bool HP_itemdb_is_item_usable(struct item_data *item) { + int hIndex = 0; + bool retVal___ = false; + if( HPMHooks.count.HP_itemdb_is_item_usable_pre ) { + bool (*preHookFunc) (struct item_data *item); + *HPMforce_return = false; + for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_is_item_usable_pre; hIndex++ ) { + preHookFunc = HPMHooks.list.HP_itemdb_is_item_usable_pre[hIndex].func; + retVal___ = preHookFunc(item); + } + if( *HPMforce_return ) { + *HPMforce_return = false; + return retVal___; + } + } + { + retVal___ = HPMHooks.source.itemdb.is_item_usable(item); + } + if( HPMHooks.count.HP_itemdb_is_item_usable_post ) { + bool (*postHookFunc) (bool retVal___, struct item_data *item); + for(hIndex = 0; hIndex < HPMHooks.count.HP_itemdb_is_item_usable_post; hIndex++ ) { + postHookFunc = HPMHooks.list.HP_itemdb_is_item_usable_post[hIndex].func; + retVal___ = postHookFunc(retVal___, item); + } + } + return retVal___; +} /* logs */ void HP_logs_pick_pc(struct map_session_data *sd, e_log_pick_type type, int amount, struct item *itm, struct item_data *data) { int hIndex = 0; -- cgit v1.2.3-60-g2f50 From 251f5d933c49fc2dcb52cd76a2570cae4cb827fe Mon Sep 17 00:00:00 2001 From: Haru Date: Wed, 17 Dec 2014 02:04:11 +0100 Subject: Fixed a compile error on MSVC < 2013 Thanks to Ind, Michieru Signed-off-by: Haru --- src/map/script.c | 46 +++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 25 deletions(-) diff --git a/src/map/script.c b/src/map/script.c index 3ccb6a45a..be73fe5b2 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -10091,12 +10091,13 @@ int buildin_getareausers_sub(struct block_list *bl,va_list ap) (*users)++; return 0; } + BUILDIN(getareausers) { int16 m = -1, x0, y0, x1, y1; int users = 0; int idx = 2; - struct npc_data *nd = NULL; + if (script_hasdata(st, 2) && script_isstringtype(st, 2)) { const char *str = script_getstr(st, 2); if ((m = map->mapname2mapid(str)) < 0) { @@ -10104,46 +10105,41 @@ BUILDIN(getareausers) return true; } idx = 3; - } - if (m == -1) - { - TBL_PC *sd = NULL; - sd = script->rid2sd(st); - if (!sd) - { + } else { + TBL_PC *sd = script->rid2sd(st); + if (!sd) { script_pushint(st, -1); return false; } m = sd->bl.m; } - if (st->oid) - nd = map->id2nd(st->oid); + if (script_hasdata(st, idx + 3)) { x0 = script_getnum(st, idx + 0); y0 = script_getnum(st, idx + 1); x1 = script_getnum(st, idx + 2); y1 = script_getnum(st, idx + 3); - } else if (script_hasdata(st, idx)) { - if (!nd) - { + } else if (st->oid) { + struct npc_data *nd = map->id2nd(st->oid); + if (!nd) { script_pushint(st, -1); return true; } - int sz = script_getnum(st, idx); - x0 = nd->bl.x - sz; - y0 = nd->bl.y - sz; - x1 = nd->bl.x + sz; - y1 = nd->bl.y + sz; - } else if (st->oid) { - if (!nd || nd->u.scr.xs == -1 || nd->u.scr.ys == -1) - { + if (script_hasdata(st, idx)) { + int range = script_getnum(st, idx); + x0 = nd->bl.x - range; + y0 = nd->bl.y - range; + x1 = nd->bl.x + range; + y1 = nd->bl.y + range; + } else if (nd->u.scr.xs != -1 && nd->u.scr.ys != -1) { + x0 = nd->bl.x - nd->u.scr.xs; + y0 = nd->bl.y - nd->u.scr.ys; + x1 = nd->bl.x + nd->u.scr.xs; + y1 = nd->bl.y + nd->u.scr.ys; + } else { script_pushint(st, -1); return true; } - x0 = nd->bl.x - nd->u.scr.xs; - y0 = nd->bl.y - nd->u.scr.ys; - x1 = nd->bl.x + nd->u.scr.xs; - y1 = nd->bl.y + nd->u.scr.ys; } else { script_pushint(st, -1); return false; -- cgit v1.2.3-60-g2f50 From 68f0fee76a73612263984da5d9de1e32b7ffe7da Mon Sep 17 00:00:00 2001 From: Haru Date: Wed, 17 Dec 2014 02:09:33 +0100 Subject: Corrected a trivial null pointer case detected by Xcode Signed-off-by: Haru --- src/map/clif.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/map/clif.c b/src/map/clif.c index 3515bb806..eff41422c 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -17749,7 +17749,10 @@ void clif_parse_CashShopReqTab(int fd, struct map_session_data *sd) { void clif_maptypeproperty2(struct block_list *bl,enum send_target t) { #if PACKETVER >= 20121010 struct packet_maptypeproperty2 p; - struct map_session_data *sd = BL_CAST(BL_PC, bl); + struct map_session_data *sd = NULL; + nullpo_retv(bl); + + sd = BL_CAST(BL_PC, bl); p.PacketType = maptypeproperty2Type; p.type = 0x28; -- cgit v1.2.3-60-g2f50