From 8f8e2e42ba3ea1416b80190a3006c061ef4ed8b5 Mon Sep 17 00:00:00 2001 From: skotlex Date: Sun, 11 Mar 2007 20:02:42 +0000 Subject: - @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://rathena.svn.sourceforge.net/svnroot/rathena/trunk@9990 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/atcommand.c | 28 ++++++++------ src/map/npc.c | 104 +++++++++++++++++++++++++++++++++++++++++----------- src/map/npc.h | 2 + src/map/script.c | 13 +------ 4 files changed, 103 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/map/atcommand.c b/src/map/atcommand.c index fbd7a28ff..64396fa4b 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 3e8e51942..2538a1955 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 0a1025040..93b9b21d1 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 eb1bc4609..9b15497bc 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; } -- cgit v1.2.3-70-g09d2