From 3bb42dda4732f3288155725bd26da76822c10021 Mon Sep 17 00:00:00 2001 From: ultramage Date: Sat, 17 Nov 2007 20:03:29 +0000 Subject: Made OnTouch zone dimensions be stored as radius instead of diameter. Cleaned up some overly complicated area calculations. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@11750 54d463be-8e91-2dee-dedb-b68131a5f0ec --- src/map/atcommand.c | 2 +- src/map/map.h | 8 ++--- src/map/npc.c | 101 ++++++++++++++++++++++++++-------------------------- 3 files changed, 55 insertions(+), 56 deletions(-) (limited to 'src/map') diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 325177565..3cbe1f885 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -5512,7 +5512,7 @@ int atcommand_addwarp(const int fd, struct map_session_data* sd, const char* com return -1; } - nd = npc_add_warp(sd->bl.m, sd->bl.x, sd->bl.y, 1, 1, m, x, y); + nd = npc_add_warp(sd->bl.m, sd->bl.x, sd->bl.y, 2, 2, m, x, y); if( nd == NULL ) return -1; diff --git a/src/map/map.h b/src/map/map.h index f5fe6a4b6..b2660e124 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -838,7 +838,7 @@ struct npc_data { union { struct { struct script_code *script; - short xs,ys; + short xs,ys; // OnTouch area radius int guild_id; int timer,timerid,timeramount,rid; unsigned int timertick; @@ -849,9 +849,9 @@ struct npc_data { } scr; struct npc_item_list shop_item[1];// dynamic array, allocated with extra entries (last one has nameid 0) struct { - short xs,ys; - short x,y; - unsigned short mapindex; + short xs,ys; // OnTouch area radius + short x,y; // destination coords + unsigned short mapindex; // destination map } warp; } u; //Do NOT place anything afterwards... shop data NPC will override any variables from here and on! [Skotlex] diff --git a/src/map/npc.c b/src/map/npc.c index 5d98f761e..f1482df4d 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -133,8 +133,8 @@ 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)) - 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); + 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 ); return 0; } @@ -695,14 +695,15 @@ int npc_event(struct map_session_data* sd, const char* eventname, int mob_kill) xs=nd->u.scr.xs; ys=nd->u.scr.ys; - if (xs>=0 && ys>=0 && (strcmp(((eventname)+strlen(eventname)-6),"Global") != 0) ) + if( xs >= 0 && ys >= 0 && strcmp(((eventname)+strlen(eventname)-6),"Global") != 0 ) { - if (nd->bl.m >= 0) { //Non-invisible npc - if (nd->bl.m != sd->bl.m ) + if( nd->bl.m >= 0 ) + {// Non-invisible npc + if( nd->bl.m != sd->bl.m ) return 1; - if ( xs>0 && (sd->bl.xbl.x-xs/2 || nd->bl.x+xs/2bl.x) ) + if( sd->bl.x < nd->bl.x-xs || sd->bl.x > nd->bl.x+xs ) return 1; - if ( ys>0 && (sd->bl.ybl.y-ys/2 || nd->bl.y+ys/2bl.y) ) + if( sd->bl.y < nd->bl.y-ys || sd->bl.y > nd->bl.y+ys ) return 1; } } @@ -723,7 +724,8 @@ int npc_touch_areanpc(struct map_session_data* sd, int m, int x, int y) if(sd->npc_id) return 1; - for(i=0;isc.option&OPTION_INVISIBLE) { // 無効化されている f=0; continue; @@ -741,8 +743,8 @@ int npc_touch_areanpc(struct map_session_data* sd, int m, int x, int y) default: continue; } - if (x >= map[m].npc[i]->bl.x-xs/2 && x < map[m].npc[i]->bl.x-xs/2+xs && - y >= map[m].npc[i]->bl.y-ys/2 && y < map[m].npc[i]->bl.y-ys/2+ys) + if( x >= map[m].npc[i]->bl.x-xs && x <= map[m].npc[i]->bl.x+xs + && y >= map[m].npc[i]->bl.y-ys && y <= map[m].npc[i]->bl.y+ys ) break; } if (i==map[m].npc_num) { @@ -786,7 +788,8 @@ int npc_touch_areanpc2(struct block_list* bl) int i,m=bl->m; int xs,ys; - for(i=0;isc.option&OPTION_INVISIBLE) continue; @@ -796,8 +799,8 @@ int npc_touch_areanpc2(struct block_list* bl) xs=map[m].npc[i]->u.warp.xs; ys=map[m].npc[i]->u.warp.ys; - if (bl->x >= map[m].npc[i]->bl.x-xs/2 && bl->x < map[m].npc[i]->bl.x-xs/2+xs && - bl->y >= map[m].npc[i]->bl.y-ys/2 && bl->y < map[m].npc[i]->bl.y-ys/2+ys) + if( bl->x >= map[m].npc[i]->bl.x-xs && bl->x <= map[m].npc[i]->bl.x+xs + && bl->y >= map[m].npc[i]->bl.y-ys && bl->y <= map[m].npc[i]->bl.y+ys ) break; } if (i==map[m].npc_num) @@ -863,8 +866,8 @@ int npc_check_areanpc(int flag, int m, int x, int y, int range) continue; } - if (x1 >= map[m].npc[i]->bl.x-xs/2 && x0 < map[m].npc[i]->bl.x-xs/2+xs && - y1 >= map[m].npc[i]->bl.y-ys/2 && y0 < map[m].npc[i]->bl.y-ys/2+ys) + if( x1 >= map[m].npc[i]->bl.x-xs && x0 <= map[m].npc[i]->bl.x+xs + && y1 >= map[m].npc[i]->bl.y-ys && y0 <= map[m].npc[i]->bl.y+ys ) break; // found a npc } if (i==map[m].npc_num) @@ -1235,25 +1238,24 @@ int npc_remove_map(struct npc_data* nd) return 1; //Not assigned to a map. m = nd->bl.m; clif_clearunit_area(&nd->bl,2); - //Remove corresponding NPC CELLs - if (nd->bl.subtype == WARP) { + if (nd->bl.subtype == WARP) + {// Remove corresponding NPC CELLs int j, xs, ys, x, y; x = nd->bl.x; y = nd->bl.y; xs = nd->u.warp.xs; ys = nd->u.warp.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_CHKNPC)) - map_setcell(m, x-xs/2+j, y-ys/2+i, CELL_CLRNPC); - } - } + for( i = y-ys; i < y+ys; i++ ) + for( j = x-xs; j < x+xs; j++ ) + if( map_getcell(m, j, i, CELL_CHKNPC) ) + map_setcell(m, j, i, CELL_CLRNPC); + } map_delblock(&nd->bl); //Remove npc from map[].npc list. [Skotlex] - for(i=0;i= map[m].npc_num) return 2; //failed to find it? + ARR_FIND( 0, map[m].npc_num, i, map[m].npc[i] == nd ); + if( i >= map[m].npc_num ) return 2; //failed to find it? map[m].npc_num--; memmove(&map[m].npc[i], &map[m].npc[i+1], (map[m].npc_num-i)*sizeof(map[m].npc[0])); @@ -1507,8 +1509,8 @@ struct npc_data* npc_add_warp(short from_mapid, short from_x, short from_y, shor nd->u.warp.mapindex = to_mapindex; nd->u.warp.x = to_x; nd->u.warp.y = to_y; - nd->u.warp.xs = xs+2;// TODO why +2? [FlavioJS] - nd->u.warp.ys = xs+2; + nd->u.warp.xs = xs; + nd->u.warp.ys = xs; nd->bl.type = BL_NPC; nd->bl.subtype = WARP; npc_setcells(nd); @@ -1564,8 +1566,6 @@ static const char* npc_parse_warp(char* w1, char* w2, char* w3, char* w4, const nd->speed = 200; nd->u.warp.mapindex = i; - xs += 2; - ys += 2; nd->u.warp.x = to_x; nd->u.warp.y = to_y; nd->u.warp.xs = xs; @@ -1865,16 +1865,14 @@ static const char* npc_parse_script(char* w1, char* w2, char* w3, char* w4, cons if( sscanf(w4, "%d,%d,%d", &class_, &xs, &ys) == 3 ) {// OnTouch area defined - if (xs >= 0) xs = xs * 2 + 1; - if (ys >= 0) ys = ys * 2 + 1; nd->u.scr.xs = xs; nd->u.scr.ys = ys; } else - { + {// no OnTouch area class_ = atoi(w4); - nd->u.scr.xs = 0; - nd->u.scr.ys = 0; + nd->u.scr.xs = -1; + nd->u.scr.ys = -1; } nd->bl.prev = nd->bl.next = NULL; @@ -1981,14 +1979,14 @@ void npc_setcells(struct npc_data* nd) ys = nd->u.scr.ys; } - if (m < 0 || xs < 1 || ys < 1) + if (m < 0 || xs < 0 || ys < 0) 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)) + for (i = y-ys; i <= y+ys; i++) { + for (j = x-xs; j <= x+xs; j++) { + if (map_getcell(m, j, i, CELL_CHKNOPASS)) continue; - map_setcell(m, x-xs/2+j, y-ys/2+i, CELL_SETNPC); + map_setcell(m, j, i, CELL_SETNPC); } } } @@ -2015,21 +2013,22 @@ void npc_unsetcells(struct npc_data* nd) ys = nd->u.scr.ys; } - if (m < 0 || xs < 1 || ys < 1) + if (m < 0 || xs < 0 || ys < 0) return; //Locate max range on which we can locate npc 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); + for(x0 = x-xs; x0 > 0 && map_getcell(m, x0, y, CELL_CHKNPC); x0--); + for(x1 = x+xs; x1 < map[m].xs-1 && map_getcell(m, x1, y, CELL_CHKNPC); x1++); + for(y0 = y-ys; y0 > 0 && map_getcell(m, x, y0, CELL_CHKNPC); y0--); + for(y1 = y+ys; y1 < map[m].ys-1 && map_getcell(m, x, y1, CELL_CHKNPC); y1++); + + //Erase this npc's cells + for (i = y-ys; i <= y+ys; i++) + for (j = x-xs; j <= x+xs; j++) + map_setcell(m, j, i, CELL_CLRNPC); + + //Re-deploy 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) -- cgit v1.2.3-60-g2f50