浏览代码

* Fixed a bug in gettick cache when compiling in Windows
- Changed "read_map_from_bitmap" to "read_map_from_cache" in map_athena, "map_bitmap_path" to "map_cache_file"
- Fixed item effects not showing when only one was used
- Fixed a bug in Safety Wall
- Allow only either Storm Gust or Lord of Vermillion to cause damage if stacked together
- Added path_search_long, map_find_skill_unit_oncell

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

(no author) 20 年之前
父节点
当前提交
85592f9a38
共有 12 个文件被更改,包括 315 次插入224 次删除
  1. 11 0
      Changelog.txt
  2. 10 6
      conf-tmpl/map_athena.conf
  3. 1 0
      src/common/timer.c
  4. 7 6
      src/map/atcommand.c
  5. 12 18
      src/map/battle.c
  6. 111 102
      src/map/map.c
  7. 21 33
      src/map/map.h
  8. 2 2
      src/map/npc.c
  9. 54 1
      src/map/path.c
  10. 4 5
      src/map/pc.c
  11. 78 48
      src/map/skill.c
  12. 4 3
      src/map/skill.h

+ 11 - 0
Changelog.txt

@@ -1,6 +1,17 @@
 Date	Added
 
 01/26
+        * Fixed a bug in gettick cache when compiling in Windows, thanks to Shinomori
+          (jA 1094) [celest]
+        * Added updates from jA 1092 [celest]
+          - Changed "read_map_from_bitmap" to "read_map_from_cache",
+            "map_bitmap_path" to "map_cache_file" in map_athena
+          - Fixed item effects not showing when only one was used
+          - Fixed a bug in Safety Wall
+          - Allow only either Storm Gust or Lord of Vermillion to cause damage if
+            stacked together
+          - Added path_search_long, map_find_skill_unit_oncell
+
         * Added status_get_sc_def for calculating resistance against status
           abnormalities [celest]
         * Added status.c and status.h of jA 1091 update and moved some functions into

+ 10 - 6
conf-tmpl/map_athena.conf

@@ -45,14 +45,18 @@ char_port: 6121
 map_port: 5121
 
 //Preferred map loading method
-//0: Read directly from grf, 1: Read from bitmap file (without compression)
-//2: Read from bitmap file (with compression). It is possible to reduce the map cache
-// to 1MB for 400+ maps with compression enabled. If all maps are already loaded in the
-// cache, Athena can boot without reading the grf files.
-read_map_from_bitmap: 1
+// 0: Read directly from grf
+// 1: Read from cache (without compression)
+// 2: Read from cache (with compression)
+// If the cache was not found it will read the maps from the GRF and copy
+// any necessary data into a newly created cache.
+// It is possible to reduce the map cache to 1MB for 400+ maps with compression
+// enabled. If all maps are already loaded in the cache, Athena can boot without
+// reading the grf files.
+read_map_from_cache: 1
 //
 //Where is the bitmap file stored?
-map_bitmap_path: db/map.info
+map_cache_file: db/map.info
 
 // Console Commands
 // Allow for console commands to be used on/off

+ 1 - 0
src/common/timer.c

@@ -91,6 +91,7 @@ static int gettick_count;
 unsigned int gettick_nocache(void)
 {
 #ifdef _WIN32
+	gettick_count = 256;	// [Shinomori]
 	return gettick_cache = GetTickCount();
 #else
 	struct timeval tval;

+ 7 - 6
src/map/atcommand.c

@@ -3674,12 +3674,13 @@ int atcommand_gat(
 
 	for (y = 2; y >= -2; y--) {
 		sprintf(output, "%s (x= %d, y= %d) %02X %02X %02X %02X %02X",
-		         map[sd->bl.m].name,   sd->bl.x - 2, sd->bl.y + y,
- 				map_getcell(sd->bl.m, sd->bl.x - 2, sd->bl.y + y,CELL_CHKTYPE),
- 				map_getcell(sd->bl.m, sd->bl.x - 1, sd->bl.y + y,CELL_CHKTYPE),
- 				map_getcell(sd->bl.m, sd->bl.x,     sd->bl.y + y,CELL_CHKTYPE),
- 				map_getcell(sd->bl.m, sd->bl.x + 1, sd->bl.y + y,CELL_CHKTYPE),
-	 			map_getcell(sd->bl.m, sd->bl.x + 2, sd->bl.y + y,CELL_CHKTYPE));
+			map[sd->bl.m].name,   sd->bl.x - 2, sd->bl.y + y,
+ 			map_getcell(sd->bl.m, sd->bl.x - 2, sd->bl.y + y, CELL_GETTYPE),
+ 			map_getcell(sd->bl.m, sd->bl.x - 1, sd->bl.y + y, CELL_GETTYPE),
+ 			map_getcell(sd->bl.m, sd->bl.x,     sd->bl.y + y, CELL_GETTYPE),
+ 			map_getcell(sd->bl.m, sd->bl.x + 1, sd->bl.y + y, CELL_GETTYPE),
+ 			map_getcell(sd->bl.m, sd->bl.x + 2, sd->bl.y + y, CELL_GETTYPE));
+
 		clif_displaymessage(fd, output);
 	}
 

+ 12 - 18
src/map/battle.c

@@ -252,14 +252,18 @@ int battle_calc_damage(struct block_list *src,struct block_list *bl,int damage,i
 	sc_count=status_get_sc_count(bl);
 
 	if(sc_count!=NULL && *sc_count>0){
-
-		if(sc_data[SC_SAFETYWALL].timer!=-1 && damage>0 && flag&BF_WEAPON && flag&BF_SHORT && skill_num != NPC_GUIDEDATTACK){
+		if (sc_data[SC_SAFETYWALL].timer!=-1 && damage>0 && flag&BF_WEAPON &&
+			flag&BF_SHORT && skill_num != NPC_GUIDEDATTACK) {
 			// セーフティウォール
-			struct skill_unit *unit=(struct skill_unit*)sc_data[SC_SAFETYWALL].val2;
-			if( unit && unit->alive && (--unit->group->val2)<=0 )
-				skill_delunit(unit);
-			skill_unit_move(bl,gettick(),1);	// 重ね掛けチェック
-			damage=0;
+			struct skill_unit *unit;
+			unit = map_find_skill_unit_oncell(bl->m,bl->x,bl->y,MG_SAFETYWALL);
+			if (unit) {
+				if ((--unit->group->val2)<=0)
+					skill_delunit(unit);
+				damage=0;
+			} else {
+				status_change_end(bl,SC_SAFETYWALL,-1);
+			}
 		}
 		if(sc_data[SC_PNEUMA].timer!=-1 && damage>0 && ((flag&BF_WEAPON && flag&BF_LONG && skill_num != NPC_GUIDEDATTACK) ||
 			(flag&BF_MISC && (skill_num ==  HT_BLITZBEAT || skill_num == SN_FALCONASSAULT)))){ // [DracoRPG]
@@ -3792,7 +3796,6 @@ int battle_check_range(struct block_list *src,struct block_list *bl,int range)
 {
 
 	int dx,dy;
-	struct walkpath_data wpd;
 	int arange;
 
 	nullpo_retr(0, src);
@@ -3815,16 +3818,7 @@ int battle_check_range(struct block_list *src,struct block_list *bl,int range)
 //		return 1;
 
 	// 障害物判定
-	wpd.path_len=0;
-	wpd.path_pos=0;
-	wpd.path_half=0;
-	if(path_search(&wpd,src->m,src->x,src->y,bl->x,bl->y,0x10001)!=-1)
-		return 1;
-
-	dx=(dx>0)?1:((dx<0)?-1:0);
-	dy=(dy>0)?1:((dy<0)?-1:0);
-	return (path_search(&wpd,src->m,src->x+dx,src->y+dy,
-		bl->x-dx,bl->y-dy,0x10001)!=-1)?1:0;
+	return path_search_long(src->m,src->x,src->y,bl->x,bl->y);
 }
 
 /*==========================================

+ 111 - 102
src/map/map.c

@@ -151,13 +151,10 @@ struct charid2nick {
 	int req_id;
 };
 
+// ォ゙ォテォラォュォ罩テォキォ袮ラ鯑ォユォ鬮ー(map_athana.conf?ェホread_map_from_cacheェヌ��)
+// 0:ララ鯑ェキェハェ、 1:゙ェ?�ワチ� 2:?�ワチ�
 int  map_read_flag = READ_FROM_GAT;
-// マップキャッシュ利用フラグ,どっちを使うかはmap_athana.conf内のread_map_from_bitmapで指定
-// 0ならば利用しない、1だと非圧縮保存、2だと圧縮して保存
-int map_getcell(int,int x,int y,CELL_CHK cellchk);
-int map_getcellp(struct map_data* m,int x,int y,CELL_CHK cellchk);
-
-char map_bitmap_filename[256]="db/map.info";//ビットマップファイルのデフォルトパス
+char map_cache_file[256]="db/map.info"; // ォ゙ォテォラォュォ罩テォキォ雖ユォ。ォ、ォ�」
 
 char motd_txt[256] = "conf/motd.txt";
 char help_txt[256] = "conf/help.txt";
@@ -398,7 +395,32 @@ int map_count_oncell(int m, int x, int y) {
 	if(!count) count = 1;
 	return count;
 }
+/*
+ * ォサォ�セェホ��ェヒフクェトェアェソォケォュォ�讚ヒォテォネェ��ケ
+ */
+struct skill_unit *map_find_skill_unit_oncell(int m,int x,int y,int skill_id)
+{
+	int bx,by;
+	struct block_list *bl;
+	int i,c;
+	struct skill_unit *unit;
+
+	if (x < 0 || y < 0 || (x >= map[m].xs) || (y >= map[m].ys))
+		return NULL;
+	bx = x/BLOCK_SIZE;
+	by = y/BLOCK_SIZE;
 
+	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->x != x || bl->y != y || bl->type != BL_SKILL)
+			continue;
+		unit = (struct skill_unit *) bl;
+		if (unit->alive && unit->group->skill_id == skill_id)
+			return unit;
+	}
+	return NULL;
+}
 
 /*==========================================
  * map m (x0,y0)-(x1,y1)?の全objに?して
@@ -1355,15 +1377,16 @@ int map_calc_dir( struct block_list *src,int x,int y) {
  *------------------------------------------
  */
 
-int map_getcell(int m,int x,int y,CELL_CHK cellchk)
+int map_getcell(int m,int x,int y,cell_t cellchk)
 {
 	return (m < 0 || m > MAX_MAP_PER_SERVER) ? 0 : map_getcellp(&map[m],x,y,cellchk);
 }
 
-int map_getcellp(struct map_data* m,int x,int y,CELL_CHK cellchk)
+int map_getcellp(struct map_data* m,int x,int y,cell_t cellchk)
 {
 	int j;
 	nullpo_ret(m);
+
 	if(x<0 || x>=m->xs-1 || y<0 || y>=m->ys-1)
 	{
 		if(cellchk==CELL_CHKNOPASS) return 1;
@@ -1373,55 +1396,40 @@ int map_getcellp(struct map_data* m,int x,int y,CELL_CHK cellchk)
 
 	switch(cellchk)
 	{
-		case CELL_CHKTOUCH:
-			if(m->gat[j]&0x80) return 1;return 0;
-		case CELL_CHKWATER:
-			if(m->gat[j]==3) return 1;return 0;
-		case CELL_CHKHIGH:
-			if(m->gat[j]==5) return 1;return 0;
 		case CELL_CHKPASS:
-			if(m->gat[j]!=1&&m->gat[j]!=5) return 1; return 0;
+			return (m->gat[j] != 1 && m->gat[j] != 5);
 		case CELL_CHKNOPASS:
-			if(m->gat[j]==1||m->gat[j]==5) return 1; return 0;
-		case CELL_CHKTYPE:
+			return (m->gat[j] == 1 || m->gat[j] == 5);
+		case CELL_CHKWALL:
+			return (m->gat[j] == 1);
+		case CELL_CHKNPC:
+			return (m->gat[j]&0x80);
+		case CELL_CHKWATER:
+			return (m->gat[j] == 3);
+		case CELL_CHKGROUND:
+			return (m->gat[j] == 5);
+		case CELL_GETTYPE:
 			return m->gat[j];
-		default: return 0;
-	}
-	return 0;
+		default:
+			return 0;
+	}	
 }
 
 /*==========================================
  * (m,x,y)の状態を設定する
  *------------------------------------------
  */
-int map_setcell(int m,int x,int y,CELL_SET cellset)
+void map_setcell(int m,int x,int y,int cell)
 {
-	int i,j;
-
+	int j;
 	if(x<0 || x>=map[m].xs || y<0 || y>=map[m].ys)
-		return 0;
+		return;
 	j=x+y*map[m].xs;
-	switch(cellset)
-	{
-	case CELL_SETTOUCH:
-		return map[m].gat[j]|=0x80;
-		break;
-	case CELL_SETWATER://3
-		i=3;break;
-	case CELL_SETPASS://0
-		i=0;break;
-	case CELL_SETNOPASS://gat_fileused[0](READ_FROM_BITMAP)か1(READ_FROM_GAT)
-		i=1;break;
-	case CELL_SETHIGH://5
-		i=5;break;
-	case CELL_SETNOHIGH://5
-		i=5;break;
-	default:
-		return 0;
-	}
-	map[m].gat[j]=i;
 
-	return 1;
+	if (cell == CELL_SETNPC)
+		map[m].gat[j] |= 0x80;
+	else
+		map[m].gat[j] = cell;
 }
 
 /*==========================================
@@ -1510,10 +1518,10 @@ static void map_readwater(char *watertxt) {
 *===========================================*/
 
 // マップキャッシュの最大値
-#define MAX_CAHCE_MAX 768
+#define MAX_MAP_CACHE 768
 
 //各マップごとの最小限情報を入れるもの、READ_FROM_BITMAP用
-struct MAP_CACHE_INFO {
+struct map_cache_info {
 	char fn[32];//ファイル名
 	int xs,ys; //幅と高さ
 	int water_height;
@@ -1522,17 +1530,15 @@ struct MAP_CACHE_INFO {
 	int compressed_len; // zilb通せるようにする為の予約
 }; // 56 byte
 
-struct MAP_CACHE_HEAD {
-	int sizeof_header;
-	int sizeof_map;
-	// 上の2つ改変不可
-	int nmaps; // マップの個数
-	int filesize;
-};
-
-struct map_cache_ {
-	struct MAP_CACHE_HEAD head;
-	struct MAP_CACHE_INFO *map;
+struct {
+	struct map_cache_head {
+		int sizeof_header;
+		int sizeof_map;
+		// 上の2つ改変不可
+		int nmaps; // マップの個数
+		int filesize;
+	} head;
+	struct map_cache_info *map;
 	FILE *fp;
 	int dirty;
 } map_cache;
@@ -1542,41 +1548,41 @@ static void map_cache_close(void);
 static int map_cache_read(struct map_data *m);
 static int map_cache_write(struct map_data *m);
 
-static int map_cache_open(char *fn) {
+static int map_cache_open(char *fn)
+{
 	atexit(map_cache_close);
 	if(map_cache.fp) {
 		map_cache_close();
 	}
 	map_cache.fp = fopen(fn,"r+b");
 	if(map_cache.fp) {
-		fread(&map_cache.head,1,sizeof(struct MAP_CACHE_HEAD),map_cache.fp);
+		fread(&map_cache.head,1,sizeof(struct map_cache_head),map_cache.fp);
 		fseek(map_cache.fp,0,SEEK_END);
 		if(
-			map_cache.head.sizeof_header == sizeof(struct MAP_CACHE_HEAD) &&
-			map_cache.head.sizeof_map    == sizeof(struct MAP_CACHE_INFO) &&
+			map_cache.head.sizeof_header == sizeof(struct map_cache_head) &&
+			map_cache.head.sizeof_map    == sizeof(struct map_cache_info) &&
+			map_cache.head.nmaps         == MAX_MAP_CACHE &&
 			map_cache.head.filesize      == ftell(map_cache.fp)
 		) {
 			// キャッシュ読み込み成功
-			map_cache.map = (struct MAP_CACHE_INFO*)aMallocA(sizeof(struct MAP_CACHE_INFO) * map_cache.head.nmaps);
-			fseek(map_cache.fp,sizeof(struct MAP_CACHE_HEAD),SEEK_SET);
-			fread(map_cache.map,sizeof(struct MAP_CACHE_INFO),map_cache.head.nmaps,map_cache.fp);
+			map_cache.map = aMalloc(sizeof(struct map_cache_info) * map_cache.head.nmaps);
+			fseek(map_cache.fp,sizeof(struct map_cache_head),SEEK_SET);
+			fread(map_cache.map,sizeof(struct map_cache_info),map_cache.head.nmaps,map_cache.fp);
 			return 1;
 		}
 		fclose(map_cache.fp);
-	} else if (map_read_flag == READ_FROM_BITMAP || map_read_flag == READ_FROM_BITMAP_COMPRESSED)
-		++map_read_flag;	// set to CREATE flag
-
+	}
 	// 読み込みに失敗したので新規に作成する
 	map_cache.fp = fopen(fn,"wb");
 	if(map_cache.fp) {
-		memset(&map_cache.head,0,sizeof(struct MAP_CACHE_HEAD));
-		map_cache.map = (struct MAP_CACHE_INFO*)aCallocA(sizeof(struct MAP_CACHE_INFO),MAX_CAHCE_MAX);
-		map_cache.head.nmaps         = MAX_CAHCE_MAX;
-		map_cache.head.sizeof_header = sizeof(struct MAP_CACHE_HEAD);
-		map_cache.head.sizeof_map    = sizeof(struct MAP_CACHE_INFO);
+		memset(&map_cache.head,0,sizeof(struct map_cache_head));
+		map_cache.map   = aCalloc(sizeof(struct map_cache_info),MAX_MAP_CACHE);
+		map_cache.head.nmaps         = MAX_MAP_CACHE;
+		map_cache.head.sizeof_header = sizeof(struct map_cache_head);
+		map_cache.head.sizeof_map    = sizeof(struct map_cache_info);
 
-		map_cache.head.filesize  = sizeof(struct MAP_CACHE_HEAD);
-		map_cache.head.filesize += sizeof(struct MAP_CACHE_INFO) * map_cache.head.nmaps;
+		map_cache.head.filesize  = sizeof(struct map_cache_head);
+		map_cache.head.filesize += sizeof(struct map_cache_info) * map_cache.head.nmaps;
 
 		map_cache.dirty = 1;
 		return 1;
@@ -1584,20 +1590,22 @@ static int map_cache_open(char *fn) {
 	return 0;
 }
 
-static void map_cache_close(void) {
+static void map_cache_close(void)
+{
 	if(!map_cache.fp) { return; }
 	if(map_cache.dirty) {
 		fseek(map_cache.fp,0,SEEK_SET);
-		fwrite(&map_cache.head,1,sizeof(struct MAP_CACHE_HEAD),map_cache.fp);
-		fwrite(map_cache.map,map_cache.head.nmaps,sizeof(struct MAP_CACHE_INFO),map_cache.fp);
+		fwrite(&map_cache.head,1,sizeof(struct map_cache_head),map_cache.fp);
+		fwrite(map_cache.map,map_cache.head.nmaps,sizeof(struct map_cache_info),map_cache.fp);
 	}
 	fclose(map_cache.fp);
-	aFree(map_cache.map);
+	free(map_cache.map);
 	map_cache.fp = NULL;
 	return;
 }
 
-int map_cache_read(struct map_data *m) {
+int map_cache_read(struct map_data *m)
+{
 	int i;
 	if(!map_cache.fp) { return 0; }
 	for(i = 0;i < map_cache.head.nmaps ; i++) {
@@ -1610,14 +1618,14 @@ int map_cache_read(struct map_data *m) {
 				int size = map_cache.map[i].xs * map_cache.map[i].ys;
 				m->xs = map_cache.map[i].xs;
 				m->ys = map_cache.map[i].ys;
-				m->gat = (unsigned char *)aCallocA(m->xs * m->ys,sizeof(unsigned char));
+				m->gat = (unsigned char *)aCalloc(m->xs * m->ys,sizeof(unsigned char));
 				fseek(map_cache.fp,map_cache.map[i].pos,SEEK_SET);
 				if(fread(m->gat,1,size,map_cache.fp) == size) {
 					// 成功
 					return 1;
 				} else {
 					// なぜかファイル後半が欠けてるので読み直し
-					m->xs = 0; m->ys = 0; m->gat = NULL; aFree(m->gat);
+					m->xs = 0; m->ys = 0; m->gat = NULL; free(m->gat);
 					return 0;
 				}
 			} else if(map_cache.map[i].compressed == 1) {
@@ -1627,14 +1635,14 @@ int map_cache_read(struct map_data *m) {
 				int size_compress = map_cache.map[i].compressed_len;
 				m->xs = map_cache.map[i].xs;
 				m->ys = map_cache.map[i].ys;
-				m->gat = (unsigned char *)aMallocA(m->xs * m->ys * sizeof(unsigned char));
-				buf = (unsigned char*)aMallocA(size_compress);
+				m->gat = (unsigned char *)aMalloc(m->xs * m->ys * sizeof(unsigned char));
+				buf = (unsigned char*)aMalloc(size_compress);
 				fseek(map_cache.fp,map_cache.map[i].pos,SEEK_SET);
 				if(fread(buf,1,size_compress,map_cache.fp) != size_compress) {
 					// なぜかファイル後半が欠けてるので読み直し
 					printf("fread error\n");
 					m->xs = 0; m->ys = 0; m->gat = NULL;
-					aFree(m->gat); aFree(buf);
+					free(m->gat); free(buf);
 					return 0;
 				}
 				dest_len = m->xs * m->ys;
@@ -1642,10 +1650,10 @@ int map_cache_read(struct map_data *m) {
 				if(dest_len != map_cache.map[i].xs * map_cache.map[i].ys) {
 					// 正常に解凍が出来てない
 					m->xs = 0; m->ys = 0; m->gat = NULL;
-					aFree(m->gat); aFree(buf);
+					free(m->gat); free(buf);
 					return 0;
 				}
-				aFree(buf);
+				free(buf);
 				return 1;
 			}
 		}
@@ -1653,10 +1661,11 @@ int map_cache_read(struct map_data *m) {
 	return 0;
 }
 
-static int map_cache_write(struct map_data *m) {
+static int map_cache_write(struct map_data *m)
+{
 	int i;
-	unsigned long len_new, len_old;
-	unsigned char *write_buf;
+	unsigned long len_new , len_old;
+	char *write_buf;
 	if(!map_cache.fp) { return 0; }
 	for(i = 0;i < map_cache.head.nmaps ; i++) {
 		if(!strcmp(m->name,map_cache.map[i].fn)) {
@@ -1669,10 +1678,10 @@ static int map_cache_write(struct map_data *m) {
 				// サポートされてない形式なので長さ0
 				len_old = 0;
 			}
-			if(map_read_flag >= READ_FROM_BITMAP_COMPRESSED) {
+			if(map_read_flag == 2) {
 				// 圧縮保存
 				// さすがに2倍に膨れる事はないという事で
-				write_buf = (unsigned char*)aMallocA(m->xs * m->ys * 2);
+				write_buf = aMalloc(m->xs * m->ys * 2);
 				len_new = m->xs * m->ys * 2;
 				encode_zip(write_buf,&len_new,m->gat,m->xs * m->ys);
 				map_cache.map[i].compressed     = 1;
@@ -1681,7 +1690,7 @@ static int map_cache_write(struct map_data *m) {
 				len_new = m->xs * m->ys;
 				write_buf = m->gat;
 				map_cache.map[i].compressed     = 0;
-				map_cache.map[i].compressed_len = 0;
+				map_cache.map[i].compressed_len = 0;	
 			}
 			if(len_new <= len_old) {
 				// サイズが同じか小さくなったので場所は変わらない
@@ -1698,8 +1707,8 @@ static int map_cache_write(struct map_data *m) {
 			map_cache.map[i].ys  = m->ys;
 			map_cache.map[i].water_height = map_waterheight(m->name);
 			map_cache.dirty = 1;
-			if(map_read_flag >= READ_FROM_BITMAP_COMPRESSED) {
-				aFree(write_buf);
+			if(map_read_flag == 2) {
+				free(write_buf);
 			}
 			return 0;
 		}
@@ -1708,8 +1717,8 @@ static int map_cache_write(struct map_data *m) {
 	for(i = 0;i < map_cache.head.nmaps ; i++) {
 		if(map_cache.map[i].fn[0] == 0) {
 			// 新しい場所に登録
-			if(map_read_flag >= READ_FROM_BITMAP_COMPRESSED) {
-				write_buf = (unsigned char*)aMallocA(m->xs * m->ys * 2);
+			if(map_read_flag == 2) {
+				write_buf = aMalloc(m->xs * m->ys * 2);
 				len_new = m->xs * m->ys * 2;
 				encode_zip(write_buf,&len_new,m->gat,m->xs * m->ys);
 				map_cache.map[i].compressed     = 1;
@@ -1729,8 +1738,8 @@ static int map_cache_write(struct map_data *m) {
 			map_cache.map[i].water_height = map_waterheight(m->name);
 			map_cache.head.filesize += len_new;
 			map_cache.dirty = 1;
-			if(map_read_flag >= READ_FROM_BITMAP_COMPRESSED) {
-				aFree(write_buf);
+			if(map_read_flag == 2) {
+				free(write_buf);
 			}
 			return 0;
 		}
@@ -1998,7 +2007,7 @@ int map_readallmap(void) {
 
 	// マップキャッシュを開く
 	if(map_read_flag >= READ_FROM_BITMAP) {
-		map_cache_open(map_bitmap_filename);
+		map_cache_open(map_cache_file);
 	}
 
 	sprintf(tmp_output, "Loading Maps%s...\n",
@@ -2270,15 +2279,15 @@ int map_config_read(char *cfgName) {
 				strcpy(help_txt, w2);
 			} else if (strcmpi(w1, "mapreg_txt") == 0) {
 				strcpy(mapreg_txt, w2);
-			}else if(strcmpi(w1,"read_map_from_bitmap")==0){
+			}else if(strcmpi(w1,"read_map_from_cache")==0){
 				if (atoi(w2) == 2)
 					map_read_flag = READ_FROM_BITMAP_COMPRESSED;
 				else if (atoi(w2) == 1)
 					map_read_flag = READ_FROM_BITMAP;
 				else
 					map_read_flag = READ_FROM_GAT;
-			}else if(strcmpi(w1,"map_bitmap_path")==0){
-				strncpy(map_bitmap_filename,w2,255);
+			}else if(strcmpi(w1,"map_cache_file")==0){
+				strncpy(map_cache_file,w2,255);
 			} else if (strcmpi(w1, "import") == 0) {
 				map_config_read(w2);
 			} else if (strcmpi(w1, "console") == 0) {

+ 21 - 33
src/map/map.h

@@ -100,7 +100,7 @@ struct skill_unit_group {
 };
 struct skill_unit_group_tickset {
 	unsigned int tick;
-	int group_id;
+	int id;
 };
 struct skill_timerskill {
 	int timer;
@@ -505,15 +505,10 @@ enum {
 	EQP_HELM		= 0x0100,		// 頭上段
 };
 
-#define MAX_CELL_TYPE 7 //今ではセルのタイプは数字的に6が最大なので7にした、
-			//MAX_CELL_TYPE+1はワープポイントなどのタッチ系に
-
 struct map_data {
 	char name[24];
 	unsigned char *gat;	// NULLなら下のmap_data_other_serverとして扱う
 	char *alias; // [MouseJstr]
-	int *gat_fileused[MAX_CELL_TYPE+1+1]; //もしビットマップを使うならこちらを使う、
-						//上のgatはキャストされてgat_fileused[0]に指す
 	struct block_list **block;
 	struct block_list **block_mob;
 	int *block_count,*block_mob_count;
@@ -567,8 +562,6 @@ struct map_data_other_server {
 	unsigned long ip;
 	unsigned int port;
 };
-#define read_gat(m,x,y) (map_getcell(m,x,y,CELL_CHKTYPE))  //ビットマップ使う場合結構CPUに負担かかるので、消極的に使おう
-#define read_gatp(m,x,y) (map_getcellp(m,x,y,CELL_CHKTYPE)) //同上
 
 struct flooritem_data {
 	struct block_list bl;
@@ -627,24 +620,20 @@ enum {
 	LOOK_BASE,LOOK_HAIR,LOOK_WEAPON,LOOK_HEAD_BOTTOM,LOOK_HEAD_TOP,LOOK_HEAD_MID,LOOK_HAIR_COLOR,LOOK_CLOTHES_COLOR,LOOK_SHIELD,LOOK_SHOES
 };
 
-/*-------CELL_CHK*----------------
- * CELL_CHKPASS: セルは0,3,6のどっちかの場合は1を返す、以外は0
- * CELL_CHKNOPASS: セルは1、5のどっちかの場合は1を返す、以外は0
- * CELL_CHKWATER: セルは3の場合は1を返す、以外は0
- * CELL_CHKHIGH: セルは5の場合は1を返す、以外は0
- * CHELL_CHKTOUCH:セルはタッチ系の場合は1を返す、以外は0
- * CELL_CHKTYPE: セルのタイプを知りたい場合は1を返す、以外は0
-*/
-typedef enum {
-	CELL_CHKPASS,CELL_CHKNOPASS,CELL_CHKWATER=3,CELL_CHKHIGH=5,CELL_CHKTOUCH,CELL_CHKTYPE
-} CELL_CHK;
-
-/*-------CELL_SET*---------------
- * ほとんどは上と対応、設定用
+/*
+ * map_getcell()ェヌ゙ナ鯑ェオェ��ユォ鬮ー
  */
-typedef enum {
-	CELL_SETPASS,CELL_SETNOPASS,CELL_SETWATER=3,CELL_SETHIGH=5,CELL_SETNOHIGH,CELL_SETTOUCH
-} CELL_SET;
+typedef enum { 
+	CELL_CHKWALL=1,		// ロ�(ォサォ�ソォ、ォラ1)
+	CELL_CHKWATER=3,	// 筰洄(ォサォ�ソォ、ォラ3)
+	CELL_CHKGROUND=5,	// �リ�。寬レェ(ォサォ�ソォ、ォラ5)
+	CELL_CHKNPC=0x80,	// ォソォテォチォソォ、ォラェホNPC(ォサォ�ソォ、ォラ0x80ォユォ鬮ー)
+	CELL_CHKPASS,		// �ホヲハヲメ�(ォサォ�ソォ、ォラ1,5�鞣)
+	CELL_CHKNOPASS,		// �ホヲワ�ヲ(ォサォ�ソォ、ォラ1,5)
+	CELL_GETTYPE		// ォサォ�ソォ、ォラェ��ケ
+} cell_t;
+// map_setcell()ェヌ゙ナ鯑ェオェ��ユォ鬮ー
+#define CELL_SETNPC	0x80	// ォソォテォチォソォ、ォラェホNPCェ�サォテォネ
 
 struct chat_data {
 	struct block_list bl;
@@ -667,11 +656,11 @@ extern int autosave_interval;
 extern int agit_flag;
 extern int night_flag; // 0=day, 1=night [Yor]
 
-//------bitmap使用とgrfファイル使用両方対応できるために追加、また、
-//セルの取得や設定は列挙型CELL_CHK*とCELL_SET*を使った方が意図がわかりやすいので変更してみた
-int map_getcell(int,int,int,CELL_CHK);
-int map_getcellp(struct map_data*,int,int,CELL_CHK);
-extern int map_read_flag;	//セル情報のソース判定フラグ、0ならgrfファイル、1ならビットマップファイル
+// gat?ヨァ
+int map_getcell(int,int,int,cell_t);
+int map_getcellp(struct map_data*,int,int,cell_t);
+void map_setcell(int,int,int,int);
+extern int map_read_flag; // 0: grfォユォ。ォ、ォ� 1: ォュォ罩テォキォ� 2: ォュォ罩テォキォ�(?�)
 enum {
 	READ_FROM_GAT, READ_FROM_AFM,
 	READ_FROM_BITMAP, CREATE_BITMAP,
@@ -702,6 +691,7 @@ void map_foreachinmovearea(int (*)(struct block_list*,va_list),int,int,int,int,i
 int map_countnearpc(int,int,int);
 //block関連に追加
 int map_count_oncell(int m,int x,int y);
+struct skill_unit *map_find_skill_unit_oncell(int m,int x,int y,int skill_id);
 // 一時的object関連
 int map_addobject(struct block_list *);
 int map_delobject(int);
@@ -737,15 +727,13 @@ void map_addnickdb(struct map_session_data *);
 struct map_session_data * map_nick2sd(char*);
 int compare_item(struct item *a, struct item *b);
 
-// gat関連
-int map_setcell(int,int,int,CELL_SET);
-
 // その他
 int map_check_dir(int s_dir,int t_dir);
 int map_calc_dir( struct block_list *src,int x,int y);
 
 // path.cより
 int path_search(struct walkpath_data*,int,int,int,int,int,int);
+int path_search_long(int m,int x0,int y0,int x1,int y1);
 int path_blownpos(int m,int x0,int y0,int dx,int dy,int count);
 
 int map_who(int fd);

+ 2 - 2
src/map/npc.c

@@ -1472,7 +1472,7 @@ int npc_parse_warp(char *w1,char *w2,char *w3,char *w4)
 		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_SETTOUCH);
+			map_setcell(m,x-xs/2+j,y-ys/2+i,CELL_SETNPC);
 		}
 	}
 
@@ -1700,7 +1700,7 @@ static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line
 				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_SETTOUCH);
+					map_setcell(m,x-xs/2+j,y-ys/2+i,CELL_SETNPC);
 				}
 			}
 		}

+ 54 - 1
src/map/path.c

@@ -172,7 +172,7 @@ static int can_place(struct map_data *m,int x,int y,int flag)
 
 	if(map_getcellp(m,x,y,CELL_CHKPASS))
 		return 1;
-	else if((flag&0x10000)&&map_getcellp(m,x,y,CELL_CHKHIGH))
+	else if((flag&0x10000)&&map_getcellp(m,x,y,CELL_CHKGROUND))
 		return 1;
 	return 0;
 }
@@ -241,6 +241,59 @@ int path_blownpos(int m,int x0,int y0,int dx,int dy,int count)
 	return (x0<<16)|y0;
 }
 
+/*==========================================
+ *  êÀËå×îÍô?ª¬Ê¦Òöª«ªÉª¦ª«ªòÚ÷ª¹
+ *------------------------------------------
+ */
+#define swap(x,y) { int t; t = x; x = y; y = t; }
+int path_search_long(int m,int x0,int y0,int x1,int y1)
+{
+	int dx, dy;
+	int wx = 0, wy = 0;
+	int weight;
+	struct map_data *md;
+
+	if (!map[m].gat)
+		return 0;
+	md = &map[m];
+
+	dx = (x1 - x0);
+	if (dx < 0) {
+		swap(x0, x1);
+		swap(y0, y1);
+		dx = -dx;
+	}
+	dy = (y1 - y0);
+
+	if (map_getcellp(md,x1,y1,CELL_CHKWALL))
+		return 0;
+
+	if (dx > abs(dy))
+		weight = dx;
+	else
+		weight = abs(y1 - y0);
+
+	while (x0 != x1 && y0 != y1) {
+		if (map_getcellp(md,x0,y0,CELL_CHKWALL))
+			return 0;
+		wx += dx;
+		wy += dy;
+		if (wx >= weight) {
+			wx -= weight;
+			x0 ++;
+		}
+		if (wy >= weight) {
+			wy -= weight;
+			y0 ++;
+		} else if (wy < 0) {
+			wy += weight;
+			y0 --;
+		}
+	}
+
+	return 1;
+}
+
 /*==========================================
  * path’T�õ (x0,y0)->(x1,y1)
  *------------------------------------------

+ 4 - 5
src/map/pc.c

@@ -2302,10 +2302,9 @@ int pc_useitem(struct map_session_data *sd,int n)
 		if(sd->inventory_data[n])
 			run_script(sd->inventory_data[n]->use_script,0,sd->bl.id,0);
 
-		pc_delitem(sd,n,1,1);
 		amount = sd->status.inventory[n].amount;
-
-		clif_useitemack(sd,n,amount,1);
+		clif_useitemack(sd,n,amount-1,1);
+		pc_delitem(sd,n,1,1);
 	}
 
 	return 0;
@@ -3131,7 +3130,7 @@ static int pc_walk(int tid,unsigned int tick,int id,int data)
 
 		skill_unit_move(&sd->bl,tick,1);	// スキルユニットの?査
 
-		if(map_getcell(sd->bl.m,x,y,CELL_CHKTOUCH))
+		if(map_getcell(sd->bl.m,x,y,CELL_CHKNPC))
 			npc_touch_areanpc(sd,sd->bl.m,x,y);
 		else
 			sd->areanpc_id=0;
@@ -3328,7 +3327,7 @@ int pc_movepos(struct map_session_data *sd,int dst_x,int dst_y)
 
 	skill_unit_move(&sd->bl,gettick(),dist+7);	// スキルユニットの?査
 
-	if(map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKTOUCH))
+	if(map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKNPC))
 		npc_touch_areanpc(sd,sd->bl.m,sd->bl.x,sd->bl.y);
 	else
 		sd->areanpc_id=0;

+ 78 - 48
src/map/skill.c

@@ -5795,11 +5795,11 @@ struct skill_unit_group *skill_unitsetting( struct block_list *src, int skillid,
 			map_foreachinarea(skill_landprotector,src->m,ux,uy,ux,uy,BL_SKILL,skillid,&alive);
 
 		if(skillid==WZ_ICEWALL && alive){
-			val2=map_getcell(src->m,ux,uy,CELL_CHKTYPE);
+			val2=map_getcell(src->m,ux,uy,CELL_GETTYPE);
 			if(val2==5 || val2==1)
 				alive=0;
 			else {
-				map_setcell(src->m,ux,uy,CELL_SETNOPASS);
+				map_setcell(src->m,ux,uy,5);
 				clif_changemapcell(src->m,ux,uy,5,0);
 			}
 		}
@@ -5865,9 +5865,11 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int
 	struct skill_unit_group_tickset *ts;
 	struct map_session_data *srcsd=NULL;
 	int diff,goflag,splash_count=0;
+	struct status_change *sc_data;
 
 	nullpo_retr(0, src);
 	nullpo_retr(0, bl);
+	sc_data = status_get_sc_data(bl);
 
 	if( bl->prev==NULL || !src->alive || (bl->type == BL_PC && pc_isdead((struct map_session_data *)bl) ) )
 		return 0;
@@ -5880,9 +5882,9 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int
 	if(srcsd && srcsd->chatID)
 		return 0;
 
-	if( bl->type!=BL_PC && bl->type!=BL_MOB )
+	if( bl->type != BL_PC && bl->type != BL_MOB )
 		return 0;
-	nullpo_retr(0, ts=skill_unitgrouptickset_search( bl, sg->group_id));
+	nullpo_retr(0, ts = skill_unitgrouptickset_search(bl, sg));
 	diff=DIFF_TICK(tick,ts->tick);
 	goflag=(diff>sg->interval || diff<0);
 	if (sg->skill_id == CR_GRANDCROSS && !battle_config.gx_allhit) // 重なっていたら3HITしない
@@ -5894,8 +5896,7 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int
 	if(!goflag)
 		return 0;
 	ts->tick=tick;
-	ts->group_id=sg->group_id;
-
+	
 	switch(sg->unit_id){
 	case 0x83:	/* サンクチュアリ */
 		{
@@ -5938,7 +5939,6 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int
 	case 0x85:	/* ニュ?マ */
 		{
 			struct skill_unit *unit2;
-			struct status_change *sc_data=status_get_sc_data(bl);
 			int type=SC_PNEUMA;
 			if(sc_data) {
 				if (sc_data[type].timer==-1)
@@ -5952,19 +5952,9 @@ int skill_unit_onplace(struct skill_unit *src,struct block_list *bl,unsigned int
 		}
 		break;
 	case 0x7e:	/* セイフティウォ?ル */
-		{
-			struct skill_unit *unit2;
-			struct status_change *sc_data=status_get_sc_data(bl);
-			int type=SC_SAFETYWALL;
-			if(sc_data) {
-				if (sc_data[type].timer==-1)
-					status_change_start(bl,type,sg->skill_lv,(int)src,0,0,0,0);
-				else if((unit2=(struct skill_unit *)sc_data[type].val2) && unit2 != src ){
-					if(sg->val1 < unit2->group->val1 )
-						status_change_start(bl,type,sg->skill_lv,(int)src,0,0,0,0);
-					ts->tick-=sg->interval;
-				}
-			}
+		if (sc_data) {
+			status_change_start(bl,SC_SAFETYWALL,sg->skill_lv,(int)src,0,0,0,0);
+			ts->tick-=sg->interval;
 		}
 		break;
 
@@ -6452,7 +6442,7 @@ int skill_unit_onout(struct skill_unit *src,struct block_list *bl,unsigned int t
 			printf("skill_unit_onout: Unknown skill unit id=%d block=%d\n",sg->unit_id,bl->id);
 		break;*/
 	}
-	skill_unitgrouptickset_delete(bl,sg->group_id);
+	skill_unitgrouptickset_delete(bl,sg);
 	return 0;
 }
 /*==========================================
@@ -6510,7 +6500,7 @@ int skill_unit_ondelete(struct skill_unit *src,struct block_list *bl,unsigned in
 			printf("skill_unit_ondelete: Unknown skill unit id=%d block=%d\n",sg->unit_id,bl->id);
 		break;*/
 	}
-	skill_unitgrouptickset_delete(bl,sg->group_id);
+	skill_unitgrouptickset_delete(bl,sg);
 	return 0;
 }
 /*==========================================
@@ -6543,8 +6533,6 @@ int skill_unit_onlimit(struct skill_unit *src,unsigned int tick)
 		break;
 
 	case 0x8d:	/* アイスウォ?ル */
-		if(map_read_flag == READ_FROM_BITMAP)
-			map_setcell(src->bl.m,src->bl.x,src->bl.y,CELL_SETPASS);
 		map_setcell(src->bl.m,src->bl.x,src->bl.y,src->val2);
 		clif_changemapcell(src->bl.m,src->bl.x,src->bl.y,src->val2,1);
 		break;
@@ -9059,31 +9047,63 @@ int skill_clear_unitgroup(struct block_list *src)
 	return 0;
 }
 
+/*
+ * 珞�ォケォュォ���ヘ�ェュェキェソ洄�ェホヤム曺
+ */
+int skill_unit_overlap_type(int skill_id)
+{
+	switch (skill_id) {
+		case WZ_STORMGUST:
+		case WZ_VERMILION:
+			return 1;	// ェノェチェ鬪ォ�ローェォェ鬮タォ�?ォクェ��アェ�
+		default:
+			return 0;	// ?ローェォェ鬮タォ�?ォクェ��アェ�
+	}
+}
+
 /*==========================================
  * スキルユニットグル?プの被影響tick?索
  *------------------------------------------
  */
 struct skill_unit_group_tickset *skill_unitgrouptickset_search(
-	struct block_list *bl,int group_id)
+	struct block_list *bl, struct skill_unit_group *sg)
 {
-	int i,j=0,k,s=group_id%MAX_SKILLUNITGROUPTICKSET;
-	struct skill_unit_group_tickset *set=NULL;
+	int i,j=-1,k,s,id;
+	struct skill_unit_group_tickset *set;
 
 	nullpo_retr(0, bl);
 
-	if(bl->type==BL_PC){
-		set=((struct map_session_data *)bl)->skillunittick;
-	}else{
-		set=((struct mob_data *)bl)->skillunittick;
-	}
-	if(set==NULL)
+	if (bl->type == BL_PC)
+		set = ((struct map_session_data *)bl)->skillunittick;
+	else if (bl->type == BL_MOB)
+		set = ((struct mob_data *)bl)->skillunittick;
+	else
 		return 0;
-	for(i=0;i<MAX_SKILLUNITGROUPTICKSET;i++)
-		if( set[(k=(i+s)%MAX_SKILLUNITGROUPTICKSET)].group_id == group_id )
+
+	if (skill_unit_overlap_type(sg->skill_id))
+		id = s = sg->skill_id;
+	else
+		id = s = sg->group_id;
+
+	for (i=0; i<MAX_SKILLUNITGROUPTICKSET; i++) {
+		k = (i+s) % MAX_SKILLUNITGROUPTICKSET;
+		if (set[k].id == id)
 			return &set[k];
-		else if( set[k].group_id==0 )
+		else if (j == -1 && set[k].id == 0)
 			j=k;
+	}
+
+	if (j == -1) {
+		if(battle_config.error_log) {
+			sprintf (tmp_output, "skill_unitgrouptickset_search: tickset is full\n");
+			ShowWarning (tmp_output);
+		}
+		for (i = 0; i<MAX_SKILLUNITGROUPTICKSET; i++)
+			set[k].id = 0;
+		j = id % MAX_SKILLUNITGROUPTICKSET;
+	}
 
+	set[j].id = id;
 	return &set[j];
 }
 
@@ -9091,26 +9111,36 @@ struct skill_unit_group_tickset *skill_unitgrouptickset_search(
  * スキルユニットグル?プの被影響tick削除
  *------------------------------------------
  */
-int skill_unitgrouptickset_delete(struct block_list *bl,int group_id)
+int skill_unitgrouptickset_delete(
+	struct block_list *bl, struct skill_unit_group *sg)
 {
-	int i,s=group_id%MAX_SKILLUNITGROUPTICKSET;
-	struct skill_unit_group_tickset *set=NULL,*ts;
+	int i, k, s, id;
+	struct skill_unit_group_tickset *set=NULL;
 
 	nullpo_retr(0, bl);
-
-	if(bl->type==BL_PC){
+	if (bl->type == BL_PC)
 		set=((struct map_session_data *)bl)->skillunittick;
-	}else{
+	else if (bl->type == BL_MOB)
 		set=((struct mob_data *)bl)->skillunittick;
-	}
-
-	if(set!=NULL){
+	else
+		return 0;
 
-		for(i=0;i<MAX_SKILLUNITGROUPTICKSET;i++)
-			if( (ts=&set[(i+s)%MAX_SKILLUNITGROUPTICKSET])->group_id == group_id )
-				ts->group_id=0;
+	if (skill_unit_overlap_type(sg->skill_id))
+		id = s = sg->skill_id;
+	else
+		id = s = sg->group_id;
 
+	for(i=0; i<MAX_SKILLUNITGROUPTICKSET; i++) {
+		k = (i+s) % MAX_SKILLUNITGROUPTICKSET;
+		if (set[k].id == id) {
+			set[k].id = 0;
+			break;
+		}
 	}
+//	if (i == MAX_SKILLUNITGROUPTICKSET && battle_config.error_log) {
+//		printf("skill_unitgrouptickset_delete: tickset not found\n");
+//	}
+
 	return 0;
 }
 

+ 4 - 3
src/map/skill.h

@@ -110,9 +110,10 @@ int skill_delunit(struct skill_unit *unit);
 struct skill_unit_group *skill_initunitgroup(struct block_list *src,
 	int count,int skillid,int skilllv,int unit_id);
 int skill_delunitgroup(struct skill_unit_group *group);
-struct skill_unit_group_tickset *skill_unitgrouptickset_search(
-	struct block_list *bl,int group_id);
-int skill_unitgrouptickset_delete(struct block_list *bl,int group_id);
+
+struct skill_unit_group_tickset *skill_unitgrouptickset_search(struct block_list *bl,struct skill_unit_group *sg);
+int skill_unitgrouptickset_delete(struct block_list *bl,struct skill_unit_group *sg);
+
 int skill_clear_unitgroup(struct block_list *src);
 
 int skill_unit_ondamaged(struct skill_unit *src,struct block_list *bl,