Sfoglia il codice sorgente

Made OnTouch zone dimensions be stored as radius instead of diameter.
Cleaned up some overly complicated area calculations.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@11750 54d463be-8e91-2dee-dedb-b68131a5f0ec

ultramage 17 anni fa
parent
commit
90b75ed816
4 ha cambiato i file con 60 aggiunte e 58 eliminazioni
  1. 5 2
      Changelog-Trunk.txt
  2. 1 1
      src/map/atcommand.c
  3. 4 4
      src/map/map.h
  4. 50 51
      src/map/npc.c

+ 5 - 2
Changelog-Trunk.txt

@@ -3,12 +3,15 @@ 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.
 
+2007/11/17
+	* Made OnTouch zone dimensions be stored as radius instead of diameter
+	- cleaned up some overly complicated area calculations [ultramage]
 2007/11/16
-	* Added error messages when trying to place objects on invalid map coords
-	* Fixed Divine Protection working against players (bugreport:410)
 	* Added 2 new status changes for Life and Regeneration Potions [Zephyrus]
 	- Fixed some items boxes giving wrong tamings.
 	- Fixed another item giving 48 gladius[3]
+	* Added error messages when trying to place objects on invalid map coords
+	* Fixed Divine Protection working against players (bugreport:410)
 2007/11/15
 	* Fixed some homunculus skill offset calculation mistakes (bugreport:363)
 2007/11/14

+ 1 - 1
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;
 

+ 4 - 4
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]

+ 50 - 51
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.x<nd->bl.x-xs/2 || nd->bl.x+xs/2<sd->bl.x) )
+			if( sd->bl.x < nd->bl.x-xs || sd->bl.x > nd->bl.x+xs )
 				return 1;
-			if ( ys>0 && (sd->bl.y<nd->bl.y-ys/2 || nd->bl.y+ys/2<sd->bl.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;i<map[m].npc_num;i++) {
+	for(i=0;i<map[m].npc_num;i++)
+	{
 		if (map[m].npc[i]->sc.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;i<map[m].npc_num;i++) {
+	for(i=0;i<map[m].npc_num;i++)
+	{
 		if (map[m].npc[i]->sc.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 && map[m].npc[i] != nd;i++);
-	if (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)