ソースを参照

- Added function map_foreachinshootrange, behaves the same way as map_foreachinrange, but it also performs a "shoot-path" check before invoking the function. Used in the skill subtimer function if skill_wall_check is defined.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@6436 54d463be-8e91-2dee-dedb-b68131a5f0ec
skotlex 19 年 前
コミット
14413f8ec6
4 ファイル変更84 行追加3 行削除
  1. 4 0
      Changelog-Trunk.txt
  2. 73 1
      src/map/map.c
  3. 1 0
      src/map/map.h
  4. 6 2
      src/map/skill.c

+ 4 - 0
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.
 
 2006/05/01
+	* Added function map_foreachinshootrange, behaves the same way as
+	  map_foreachinrange, but it also performs a "shoot-path" check before
+	  invoking the function. Used in the skill subtimer function if
+	  skill_wall_check is defined. [Skotlex]
 	* Fixed AL_WARP displaying "Unknown Area" selections when you don't have
 	  all memo points used up. [Skotlex]
 	* Fixed alive_count not being reset on skill unitsetting, which leads to

+ 73 - 1
src/map/map.c

@@ -673,7 +673,79 @@ int map_foreachinrange(int (*func)(struct block_list*,va_list),struct block_list
 				for(i=0;i<c && bl;i++,bl=bl->next){
 					if(bl
 						&& bl->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1
-						&& check_distance_bl(center, bl, range)
+//						&& check_distance_bl(center, bl, range)
+						&& bl_list_count<BL_LIST_MAX)
+						bl_list[bl_list_count++]=bl;
+				}
+			}
+		}
+
+	if(bl_list_count>=BL_LIST_MAX) {
+		if(battle_config.error_log)
+			ShowWarning("map_foreachinrange: block count too many!\n");
+	}
+
+	map_freeblock_lock();	// メモリからの解放を禁止する
+
+	for(i=blockcount;i<bl_list_count;i++)
+		if(bl_list[i]->prev)	// 有?かどうかチェック
+			returnCount += func(bl_list[i],ap);
+
+	map_freeblock_unlock();	// 解放を許可する
+
+	va_end(ap);
+	bl_list_count = blockcount;
+	return returnCount;	//[Skotlex]
+}
+
+/*==========================================
+ * Same as foreachinrange, but there must be a shoot-able range between center and target to be counted in. [Skotlex]
+ *------------------------------------------
+ */
+int map_foreachinshootrange(int (*func)(struct block_list*,va_list),struct block_list *center, int range,int type,...) {
+	va_list ap;
+	int bx,by,m;
+	int returnCount =0;	//total sum of returned values of func() [Skotlex]
+	struct block_list *bl=NULL;
+	int blockcount=bl_list_count,i,c;
+	int x0,x1,y0,y1;
+	m = center->m;
+	if (m < 0)
+		return 0;
+	va_start(ap,type);
+	x0 = center->x-range;
+	x1 = center->x+range;
+	y0 = center->y-range;
+	y1 = center->y+range;
+	
+	if (x0 < 0) x0 = 0;
+	if (y0 < 0) y0 = 0;
+	if (x1 >= map[m].xs) x1 = map[m].xs-1;
+	if (y1 >= map[m].ys) y1 = map[m].ys-1;
+	
+	if (type&~BL_MOB)
+		for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++) {
+			for(bx=x0/BLOCK_SIZE;bx<=x1/BLOCK_SIZE;bx++){
+				bl = map[m].block[bx+by*map[m].bxs];
+				c = map[m].block_count[bx+by*map[m].bxs];
+				for(i=0;i<c && bl;i++,bl=bl->next){
+					if(bl && bl->type&type
+						&& bl->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1
+						&& path_search_long(NULL,center->m,center->x,center->y,bl->x,bl->y)
+					  	&& bl_list_count<BL_LIST_MAX)
+						bl_list[bl_list_count++]=bl;
+				}
+			}
+		}
+	if(type&BL_MOB)
+		for(by=y0/BLOCK_SIZE;by<=y1/BLOCK_SIZE;by++){
+			for(bx=x0/BLOCK_SIZE;bx<=x1/BLOCK_SIZE;bx++){
+				bl = map[m].block_mob[bx+by*map[m].bxs];
+				c = map[m].block_mob_count[bx+by*map[m].bxs];
+				for(i=0;i<c && bl;i++,bl=bl->next){
+					if(bl
+						&& bl->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1
+						&& path_search_long(NULL,center->m,center->x,center->y,bl->x,bl->y)
 						&& bl_list_count<BL_LIST_MAX)
 						bl_list[bl_list_count++]=bl;
 				}

+ 1 - 0
src/map/map.h

@@ -1254,6 +1254,7 @@ int map_delblock_sub(struct block_list *, int);
 #define map_delblock(bl) map_delblock_sub(bl,1)
 int map_moveblock(struct block_list *, int, int, unsigned int);
 int map_foreachinrange(int (*)(struct block_list*,va_list),struct block_list *,int,int,...);
+int map_foreachinshootrange(int (*)(struct block_list*,va_list),struct block_list *,int,int,...);
 int map_foreachinarea(int (*)(struct block_list*,va_list),int,int,int,int,int,int,...);
 // -- moonsoul (added map_foreachincell)
 int map_foreachincell(int (*)(struct block_list*,va_list),int,int,int,int,...);

+ 6 - 2
src/map/skill.c

@@ -9639,8 +9639,12 @@ int skill_unit_timer_sub( struct block_list *bl, va_list ap )
 
 	/* onplace_timerƒCƒxƒ“ƒgŒÄ‚Ñ?o‚µ */
 	if (unit->range>=0 && group->interval!=-1) {
-		map_foreachinrange(skill_unit_timer_sub_onplace, bl, unit->range,
-			group->bl_flag,bl,tick);
+		if (battle_config.skill_wall_check)
+			map_foreachinshootrange(skill_unit_timer_sub_onplace, bl, unit->range,
+				group->bl_flag,bl,tick);
+		else
+			map_foreachinrange(skill_unit_timer_sub_onplace, bl, unit->range,
+				group->bl_flag,bl,tick);
 		if (!unit->alive)
 			return 0;
 	}