From ddfc677c9914780e8db93026f7dc6ec4d0e3d242 Mon Sep 17 00:00:00 2001 From: skotlex Date: Sun, 11 Mar 2007 20:02:42 +0000 Subject: [PATCH] - @storage/@gstorage will no longer work if you have a trade or a storage opened already. - Cleaned up a bit @gstorage - Added a bunch of npc functions required to properly handle moving the NPC cells when an npc is moved from it's previous location. - Added npc_setcells to handle setting down the NPC cells of ontouch npcs. git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@9990 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 4 ++ src/map/atcommand.c | 28 +++++++----- src/map/npc.c | 104 +++++++++++++++++++++++++++++++++++--------- src/map/npc.h | 2 + src/map/script.c | 13 +----- 5 files changed, 107 insertions(+), 44 deletions(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 9e60b44766..6c414e0afd 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -4,6 +4,10 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. 2007/03/12 + * @storage/@gstorage will no longer work if you have a trade or a storage + opened already. + * Corrected script command movenpc so it properly moves the ontouch npc + cells as well. * Changed the unit-walk packet to be 0x86 as pointed out by FlavioJS. This new packet is much smaller, and should greatly decrease bandwidth usage. The only drawback is that the character will not display at all if the diff --git a/src/map/atcommand.c b/src/map/atcommand.c index fbd7a28ff7..64396fa4bb 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -2163,6 +2163,9 @@ int atcommand_charspeed(const int fd, struct map_session_data* sd, const char* c int atcommand_storage(const int fd, struct map_session_data* sd, const char* command, const char* message) { nullpo_retr(-1, sd); + + if (sd->npc_id || sd->vender_id || sd->state.trading || sd->state.storage_flag) + return -1; if (storage_storageopen(sd) == 1) { //Already open. @@ -2182,21 +2185,24 @@ int atcommand_guildstorage(const int fd, struct map_session_data* sd, const char struct storage *stor; //changes from Freya/Yor nullpo_retr(-1, sd); - if (sd->status.guild_id > 0) { - if (sd->state.storage_flag) { - clif_displaymessage(fd, msg_txt(251)); - return -1; - } - if ((stor = account2storage2(sd->status.account_id)) != NULL && stor->storage_status == 1) { - clif_displaymessage(fd, msg_txt(251)); - return -1; - } - storage_guild_storageopen(sd); - } else { + if (!sd->status.guild_id) { clif_displaymessage(fd, msg_txt(252)); return -1; } + if (sd->npc_id || sd->vender_id || sd->state.trading || sd->state.storage_flag) + return -1; + + if (sd->state.storage_flag) { + clif_displaymessage(fd, msg_txt(251)); + return -1; + } + + if ((stor = account2storage2(sd->status.account_id)) != NULL && stor->storage_status == 1) { + clif_displaymessage(fd, msg_txt(251)); + return -1; + } + storage_guild_storageopen(sd); return 0; } diff --git a/src/map/npc.c b/src/map/npc.c index 3e8e519421..2538a1955b 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -1662,7 +1662,7 @@ void npc_delsrcfile (char *name) int npc_parse_warp (char *w1,char *w2,char *w3,char *w4) { int x, y, xs, ys, to_x, to_y, m; - int i, j; + int i; char mapname[MAP_NAME_LENGTH], to_mapname[MAP_NAME_LENGTH]; struct npc_data *nd; @@ -1704,18 +1704,10 @@ int npc_parse_warp (char *w1,char *w2,char *w3,char *w4) nd->u.warp.y = to_y; nd->u.warp.xs = xs; nd->u.warp.ys = ys; - - for (i = 0; i < ys; i++) { - for (j = 0; j < xs; j++) { - if (map_getcell(m, x-xs/2+j, y-ys/2+i, CELL_CHKNOPASS)) - continue; - map_setcell(m, x-xs/2+j, y-ys/2+i, CELL_SETNPC); - } - } - npc_warp++; nd->bl.type = BL_NPC; nd->bl.subtype = WARP; + npc_setcells(nd); map_addblock(&nd->bl); status_set_viewdata(&nd->bl, nd->class_); status_change_init(&nd->bl); @@ -2055,20 +2047,9 @@ static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line if (sscanf(w4, "%d,%d,%d", &class_, &xs, &ys) == 3) { // 接触型NPC - int i, j; if (xs >= 0) xs = xs * 2 + 1; if (ys >= 0) ys = ys * 2 + 1; - - if (m >= 0) { - for (i = 0; i < ys; i++) { - for (j = 0; j < xs; j++) { - if (map_getcell(m, x - xs/2 + j, y - ys/2 + i, CELL_CHKNOPASS)) - continue; - map_setcell(m, x - xs/2 + j, y - ys/2 + i, CELL_SETNPC); - } - } - } nd->u.scr.xs = xs; nd->u.scr.ys = ys; } else { @@ -2119,6 +2100,7 @@ static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line status_change_init(&nd->bl); unit_dataset(&nd->bl); nd->ud.dir = dir; + npc_setcells(nd); map_addblock(&nd->bl); // Unused. You can always use xxx::OnXXXX events. Have this removed to improve perfomance. /*if (evflag) { // イベント型 @@ -2217,6 +2199,86 @@ static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line return 0; } +void npc_setcells(struct npc_data *nd) +{ + int m = nd->bl.m, x = nd->bl.x, y = nd->bl.y, xs, ys; + int i,j; + + if (nd->bl.subtype == WARP) { + xs = nd->u.warp.xs; + ys = nd->u.warp.ys; + } else { + xs = nd->u.scr.xs; + ys = nd->u.scr.ys; + } + + if (m < 0 || xs < 1 || ys < 1) + return; + + for (i = 0; i < ys; i++) { + for (j = 0; j < xs; j++) { + if (map_getcell(m, x-xs/2+j, y-ys/2+i, CELL_CHKNOPASS)) + continue; + map_setcell(m, x-xs/2+j, y-ys/2+i, CELL_SETNPC); + } + } +} + +int npc_unsetcells_sub(struct block_list *bl, va_list ap) +{ + struct npc_data *nd = (struct npc_data*)bl; + int id = va_arg(ap,int); + if (nd->bl.id == id) return 0; + npc_setcells(nd); + return 1; +} + +void npc_unsetcells(struct npc_data *nd) +{ + int m = nd->bl.m, x = nd->bl.x, y = nd->bl.y, xs, ys; + int i,j, x0, x1, y0, y1; + + if (nd->bl.subtype == WARP) { + xs = nd->u.warp.xs; + ys = nd->u.warp.ys; + } else { + xs = nd->u.scr.xs; + ys = nd->u.scr.ys; + } + + if (m < 0 || xs < 1 || ys < 1) + return; + + //Locate max range on which we can localte npce cells + for(x0 = x-xs/2; x0 > 0 && map_getcell(m, x0, y, CELL_CHKNPC); x0--); + for(x1 = x+xs/2-1; x1 < map[m].xs && map_getcell(m, x1, y, CELL_CHKNPC); x1++); + for(y0 = y-ys/2; y0 > 0 && map_getcell(m, x, y0, CELL_CHKNPC); y0--); + for(y1 = y+ys/2-1; y1 < map[m].xs && map_getcell(m, x, y1, CELL_CHKNPC); y1++); + + for (i = 0; i < ys; i++) { + for (j = 0; j < xs; j++) + map_setcell(m, x-xs/2+j, y-ys/2+i, CELL_CLRNPC); + } + //Reset NPC cells for other nearby npcs. + map_foreachinarea( npc_unsetcells_sub, m, x0, y0, x1, y1, BL_NPC, nd->bl.id); +} + +void npc_movenpc(struct npc_data *nd, int x, int y) +{ + const int m = nd->bl.m; + if (m < 0 || nd->bl.prev == NULL) return; //Not on a map. + + if (x < 0) x = 0; + else if (x >= map[m].xs) x = map[m].xs-1; + if (y < 0) y = 0; + else if (y >= map[m].ys) y = map[m].ys-1; + + npc_unsetcells(nd); + map_foreachinrange(clif_outsight, &nd->bl, AREA_SIZE, BL_PC, &nd->bl); + map_moveblock(&nd->bl, x, y, gettick()); + map_foreachinrange(clif_insight, &nd->bl, AREA_SIZE, BL_PC, &nd->bl); + npc_setcells(nd); +} /*========================================== * function行解析 *------------------------------------------ diff --git a/src/map/npc.h b/src/map/npc.h index 0a1025040e..93b9b21d16 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -54,6 +54,8 @@ int npc_parse_mob2 (struct spawn_data*, int index); // [Wizputer] int npc_parse_warp(char *w1,char *w2,char *w3,char *w4); int npc_globalmessage(const char *name,const char *mes); +void npc_setcells(struct npc_data *nd); +void npc_movenpc(struct npc_data *nd, int x, int y); int npc_enable(const char *name,int flag); int npc_changename(const char *name, const char *newname, short look); // [Lance] struct npc_data* npc_name2id(const char *name); diff --git a/src/map/script.c b/src/map/script.c index eb1bc46092..9b15497bcc 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -10895,7 +10895,6 @@ BUILDIN_FUNC(movenpc) TBL_NPC *nd = NULL; const char *npc; int x,y; - short m; npc = conv_str(st,& (st->stack->stack_data[st->start+2])); x = conv_num(st,& (st->stack->stack_data[st->start+3])); @@ -10904,17 +10903,7 @@ BUILDIN_FUNC(movenpc) if ((nd = npc_name2id(npc)) == NULL) return -1; - if ((m=nd->bl.m) < 0 || nd->bl.prev == NULL) - return -1; //Not on a map. - - if (x < 0) x = 0; - else if (x >= map[m].xs) x = map[m].xs-1; - if (y < 0) y = 0; - else if (y >= map[m].ys) y = map[m].ys-1; - map_foreachinrange(clif_outsight, &nd->bl, AREA_SIZE, BL_PC, &nd->bl); - map_moveblock(&nd->bl, x, y, gettick()); - map_foreachinrange(clif_insight, &nd->bl, AREA_SIZE, BL_PC, &nd->bl); - + npc_movenpc(nd, x, y); return 0; }