Explorar o código

* Added Bitmap File system
* Added --run_once flag

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

celest %!s(int64=20) %!d(string=hai) anos
pai
achega
94fae3e32b
Modificáronse 12 ficheiros con 462 adicións e 143 borrados
  1. 6 0
      Changelog.txt
  2. 7 0
      conf-tmpl/map_athena.conf
  3. 3 3
      src/common/grfio.c
  4. 6 8
      src/map/atcommand.c
  5. 348 55
      src/map/map.c
  6. 35 5
      src/map/map.h
  7. 16 17
      src/map/mob.c
  8. 7 13
      src/map/npc.c
  9. 6 10
      src/map/path.c
  10. 12 15
      src/map/pc.c
  11. 3 4
      src/map/pet.c
  12. 13 13
      src/map/skill.c

+ 6 - 0
Changelog.txt

@@ -1,5 +1,11 @@
 Date	Added
 12/26
+        * Added Bitmap File system from jA 1086 - automatically generates a cache
+          from maps in the GRF to speed up loading. You can enable/disable it with
+          read_map_from_bitmap in map_athena.conf. Note: AFM maps will override this
+          cache [celest]
+        * Added --run_once flag for the map server for testing purposes - closes itself
+          when everything is done loading [celest]
         * Added some code for Moonlit Petals and Basilica [celest]
 
 12/24

+ 7 - 0
conf-tmpl/map_athena.conf

@@ -44,6 +44,13 @@ char_port: 6121
 // Map Server Port
 map_port: 5121
 
+//Preferred map loading method
+//0: Read directly from grf, 1: Read from bitmap file
+read_map_from_bitmap: 1
+//
+//Where is the bitmap file stored?
+map_bitmap_path: db/map.info
+
 // Console Commands
 // Allow for console commands to be used on/off
 // This prevents usage of >& log.file

+ 3 - 3
src/common/grfio.c

@@ -586,7 +586,7 @@ errret:
 	if (buf!=NULL) free(buf);
 	if (buf2!=NULL) free(buf2);
 	if (in!=NULL) fclose(in);
-	exit(1);	//return NULL;
+	return NULL;
 }
 
 /*==========================================
@@ -964,9 +964,9 @@ void grfio_init(char *fname)
 
 	if (strcmp(data_dir, "") == 0)		    // Id data_dir doesn't exist
 		result4 = 1;	                    // Data directory
-
+/*
 	if (result != 0 && result2 != 0 && result3 != 0 && result4 != 0) {
 		printf("not grf file readed exit!!\n");
 		exit(1);	// It ends, if a resource cannot read one.
-	}
+	}*/
 }

+ 6 - 8
src/map/atcommand.c

@@ -953,9 +953,7 @@ int atcommand_send(
 			WBUFW(buf,0)=0x18f;
 		case 4:
 			WBUFW(buf,0)=0x190;
-		}
-		
-		
+		}		
 	}
 	return 0;
 }
@@ -3604,11 +3602,11 @@ 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),
-		         map_getcell(sd->bl.m, sd->bl.x - 1, sd->bl.y + y),
-		         map_getcell(sd->bl.m, sd->bl.x,     sd->bl.y + y),
-		         map_getcell(sd->bl.m, sd->bl.x + 1, sd->bl.y + y),
-		         map_getcell(sd->bl.m, 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));
 		clif_displaymessage(fd, output);
 	}
 

+ 348 - 55
src/map/map.c

@@ -150,6 +150,25 @@ struct charid2nick {
 	int req_id;
 };
 
+//各マップごとの最小限情報を入れるもの、READ_FROM_BITMAP用
+/*typedef struct{
+	char fn[32];//ファイル名
+	int xs,ys; //幅と高さ
+	int sizeinint;//intでの大きさ、1intに32セルの情報が入てる
+	int celltype[MAX_CELL_TYPE];//マップごとにそのタイプのセルがあれば対応する数字が入る、なければ1
+						//(タイプ1そのものは0と同じ配列gat_fileused[0]に
+	long pos[MAX_CELL_TYPE];//ビットマップファイルでの場所、読み出す時に使う
+} CELL_INFO;*/
+
+//#define READ_FROM_GAT 0 //gatファイルから
+//#define READ_FROM_BITMAP 1 //ビットマップファイルから
+int  map_read_flag = READ_FROM_GAT;//上の判定フラグ,どっちを使うかはmap_athana.conf内のread_map_from_bitmapで指定
+					//0ならばREAD_FROM_GAT,1ならばREAD_FROM_BITMAP
+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 motd_txt[256] = "conf/motd.txt";
 char help_txt[256] = "conf/help.txt";
 
@@ -769,7 +788,7 @@ int map_clearflooritem_timer(int tid,unsigned int tick,int id,int data) {
  *------------------------------------------
  */
 int map_searchrandfreecell(int m,int x,int y,int range) {
-	int free_cell,i,j,c;
+	int free_cell,i,j;
 
 	for(free_cell=0,i=-range;i<=range;i++){
 		if(i+y<0 || i+y>=map[m].ys)
@@ -777,7 +796,7 @@ int map_searchrandfreecell(int m,int x,int y,int range) {
 		for(j=-range;j<=range;j++){
 			if(j+x<0 || j+x>=map[m].xs)
 				continue;
-			if((c=read_gat(m,j+x,i+y))==1 || c==5)
+			if(map_getcell(m,j+x,i+y,CELL_CHKNOPASS))
 				continue;
 			free_cell++;
 		}
@@ -791,7 +810,7 @@ int map_searchrandfreecell(int m,int x,int y,int range) {
 		for(j=-range;j<=range;j++){
 			if(j+x<0 || j+x>=map[m].xs)
 				continue;
-			if((c=read_gat(m,j+x,i+y))==1 || c==5)
+			if(map_getcell(m,j+x,i+y,CELL_CHKNOPASS))
 				continue;
 			if(free_cell==0){
 				x+=j;
@@ -1340,23 +1359,77 @@ int map_calc_dir( struct block_list *src,int x,int y) {
 
 // gat系
 /*==========================================
- * (m,x,y)の?態を調べる
+ * (m,x,y)の態を調べる
  *------------------------------------------
  */
-int map_getcell(int m,int x,int y) {
-	if(x<0 || x>=map[m].xs-1 || y<0 || y>=map[m].ys-1)
-		return 1;
-	return map[m].gat[x+y*map[m].xs];
+
+int map_getcell(int m,int x,int y,CELL_CHK 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 j;
+	nullpo_ret(m);
+	if(x<0 || x>=m->xs-1 || y<0 || y>=m->ys-1)
+	{
+		if(cellchk==CELL_CHKNOPASS) return 1;
+		return 0;
+	}
+	j=x+y*m->xs;
+
+	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;
+		case CELL_CHKNOPASS:
+			if(m->gat[j]==1||m->gat[j]==5) return 1; return 0;
+		case CELL_CHKTYPE:
+			return m->gat[j];
+		default: return 0;
+	}	
+	return 0;
 }
 
 /*==========================================
- * (m,x,y)の?態をtにする
+ * (m,x,y)の状態を設定する
  *------------------------------------------
  */
-int map_setcell(int m,int x,int y,int t) {
+int map_setcell(int m,int x,int y,CELL_SET cellset)
+{
+	int i,j;
+		
 	if(x<0 || x>=map[m].xs || y<0 || y>=map[m].ys)
-		return t;
-	return map[m].gat[x+y*map[m].xs]=t;
+		return 0;
+	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;
 }
 
 /*==========================================
@@ -1440,6 +1513,178 @@ static void map_readwater(char *watertxt) {
 	}
 	fclose(fp);
 }
+/*==========================================
+* マップキャッシュに追加する
+*===========================================*/
+
+// マップキャッシュの最大値
+#define MAX_CAHCE_MAX 768
+
+//各マップごとの最小限情報を入れるもの、READ_FROM_BITMAP用
+struct MAP_CACHE_INFO {
+	char fn[32];//ファイル名
+	int xs,ys; //幅と高さ
+	int water_height;
+	int pos;  // データが入れてある場所
+	int compressed;     // zilb通せるようにする為の予約
+	int compressed_len; // zilb通せるようにする為の予約
+}; // 56 byte
+
+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;
+
+static int map_cache_open(char *fn);
+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) {
+	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);
+		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.filesize      == ftell(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 {
+		map_read_flag = CREATE_BITMAP;		
+	}		
+	// 読み込みに失敗したので新規に作成する
+	map_cache.fp = fopen(fn,"wb");
+	if(map_cache.fp) {
+		memset(&map_cache.head,0,sizeof(struct MAP_CACHE_HEAD));
+		map_cache.map   = aCalloc(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);
+
+		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;
+	}
+	return 0;
+}
+
+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);
+	}
+	fclose(map_cache.fp);
+	free(map_cache.map);
+	map_cache.fp = NULL;
+	return;
+}
+
+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++) {
+		if(!strcmp(m->name,map_cache.map[i].fn)) {
+			if(map_cache.map[i].water_height != map_waterheight(m->name)) {
+				// 水場の高さが違うので読み直し
+				return 0;
+			} else if(map_cache.map[i].compressed) {
+				// 圧縮ファイルは未対応
+				return 0;
+			} else {
+				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 *)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;
+					free(m->gat);
+					m->gat = NULL;
+					return 0;
+				}
+			}
+		}
+	}
+	return 0;
+}
+
+static int map_cache_write(struct map_data *m) {
+	int i;
+	if(!map_cache.fp) { return 0; }
+	for(i = 0;i < map_cache.head.nmaps ; i++) {
+		if(!strcmp(m->name,map_cache.map[i].fn)) {
+			// 同じエントリーがあれば上書き
+			if(
+				map_cache.map[i].xs == m->xs && map_cache.map[i].ys == m->ys &&
+				!map_cache.map[i].compressed
+			) {
+				// 幅と高さ同じで圧縮してないなら場所は変わらない
+				fseek(map_cache.fp,map_cache.map[i].pos,SEEK_SET);
+				fwrite(m->gat,m->xs,m->ys,map_cache.fp);
+			} else {
+				// 幅と高さが違うなら新しい場所に登録
+				int size = m->xs * m->ys;
+				fseek(map_cache.fp,map_cache.head.filesize,SEEK_SET);
+				fwrite(m->gat,1,size,map_cache.fp);
+				map_cache.map[i].pos = map_cache.head.filesize;
+				map_cache.map[i].xs  = m->xs;
+				map_cache.map[i].ys  = m->ys;
+				map_cache.head.filesize += size;
+			}
+			map_cache.map[i].water_height = map_waterheight(m->name);
+			map_cache.dirty = 1;
+			return 0;
+		}
+	}
+	// 同じエントリが無ければ書き込める場所を探す
+	for(i = 0;i < map_cache.head.nmaps ; i++) {
+		if(map_cache.map[i].fn[0] == 0) {
+			// 新しい場所に登録
+			int size = m->xs * m->ys;
+			strncpy(map_cache.map[i].fn,m->name,sizeof(map_cache.map[0].fn));
+			fseek(map_cache.fp,map_cache.head.filesize,SEEK_SET);
+			fwrite(m->gat,1,size,map_cache.fp);
+			map_cache.map[i].pos = map_cache.head.filesize;
+			map_cache.map[i].xs  = m->xs;
+			map_cache.map[i].ys  = m->ys;
+			map_cache.map[i].water_height = map_waterheight(m->name);
+			map_cache.head.filesize += size;
+			map_cache.dirty = 1;
+			return 0;
+		}
+	}
+	// 書き込めなかった
+	return 1;
+}
 
 #ifdef USE_AFM
 static int map_readafm(int m,char *fn) {
@@ -1587,28 +1832,20 @@ static int map_readafm(int m,char *fn) {
 #endif
 
 /*==========================================
- * マップ1枚?み?み
- *------------------------------------------
- */
-static int map_readmap(int m,char *fn, char *alias) {
+ * マップ1枚読み込み
+ * ===================================================*/
+static int map_readmap(int m,char *fn, char *alias, int *map_cache) {
 	unsigned char *gat="";
-	int s;
-	int x,y,xs,ys;
-	struct gat_1cell {float high[4]; int type;} *p=NULL;
-	int wh;
+	size_t size;
+	
 	int i;
 	int e = 0;
-
-	size_t size;
 	char progress[21] = "                    ";
-	// read & convert fn
-	gat=grfio_read(fn);
-	if(gat==NULL)
-		return -1;
+
 	//printf("\rLoading Maps [%d/%d]: %-50s  ",m,map_num,fn);
 	if (map_num) { //avoid map-server crashing if there are 0 maps
-	printf("\r");
-	ShowStatus("Progress: ");
+		printf("\r");
+		ShowStatus("Progress: ");
 		i=m*20/420;
 		printf("[");
 		for (e=0;e<i;e++) progress[e] = '#';
@@ -1616,32 +1853,52 @@ static int map_readmap(int m,char *fn, char *alias) {
 		printf("] Working: [");
 		fflush(stdout);
 	}
+
+	if(map_cache_read(&map[m])) {
+		// キャッシュから読み込めた
+		(*map_cache)++;
+	} else {
+		int s;
+		int wh;
+		int x,y,xs,ys;
+		struct gat_1cell {float high[4]; int type;} *p=NULL;	
+		// read & convert fn
+		gat=grfio_read(fn);
+		if(gat==NULL) {
+			return -1;
+			// さすがにマップが読めないのはまずいので終了する
+			//printf("Can't load map %s\n",fn);
+			//exit(1);
+		}
+	
+		xs=map[m].xs=*(int*)(gat+6);
+		ys=map[m].ys=*(int*)(gat+10);
+		map[m].gat = (unsigned char *)aCalloc(s = map[m].xs * map[m].ys,sizeof(unsigned char));
+		wh=map_waterheight(map[m].name);
+		for(y=0;y<ys;y++){
+			p=(struct gat_1cell*)(gat+y*xs*20+14);
+			for(x=0;x<xs;x++){
+				if(wh!=NO_WATER && p->type==0){
+					// 水場判定
+					map[m].gat[x+y*xs]=(p->high[0]>wh || p->high[1]>wh || p->high[2]>wh || p->high[3]>wh) ? 3 : 0;
+				} else {
+					map[m].gat[x+y*xs]=p->type;
+				}
+				p++;
+			}
+		}
+		map_cache_write(&map[m]);
+		free(gat);
+	}
+
 	map[m].m=m;
-	xs=map[m].xs=*(int*)(gat+6);
-	ys=map[m].ys=*(int*)(gat+10);
-	map[m].gat = (unsigned char *)aCalloc(s = map[m].xs * map[m].ys,sizeof(unsigned char));
 	map[m].npc_num=0;
 	map[m].users=0;
 	memset(&map[m].flag,0,sizeof(map[m].flag));
 	if(battle_config.pk_mode)
 		map[m].flag.pvp = 1; // make all maps pvp for pk_mode [Valaris]
-	wh=map_waterheight(map[m].name);
-	for(y=0;y<ys;y++){
-		p=(struct gat_1cell*)(gat+y*xs*20+14);
-		for(x=0;x<xs;x++){
-			if(wh!=NO_WATER && p->type==0){
-				// 水場判定
-				map[m].gat[x+y*xs]=(p->high[0]>wh || p->high[1]>wh || p->high[2]>wh || p->high[3]>wh) ? 3 : 0;
-			} else {
-				map[m].gat[x+y*xs]=p->type;
-			}
-			p++;
-		}
-	}
-	free(gat);
-
-	map[m].bxs=(xs+BLOCK_SIZE-1)/BLOCK_SIZE;
-	map[m].bys=(ys+BLOCK_SIZE-1)/BLOCK_SIZE;
+	map[m].bxs=(map[m].xs+BLOCK_SIZE-1)/BLOCK_SIZE;
+	map[m].bys=(map[m].ys+BLOCK_SIZE-1)/BLOCK_SIZE;
 	size = map[m].bxs * map[m].bys * sizeof(struct block_list*);
 	map[m].block = (struct block_list **)aCalloc(1,size);
 	map[m].block_mob = (struct block_list **)aCalloc(1,size);
@@ -1671,18 +1928,31 @@ int map_readallmap(void) {
 #ifdef USE_AFM
 	FILE *afm_file;
 #endif
+	int map_cache = 0;
+	
+	// マップキャッシュを開く
+	if(map_read_flag == READ_FROM_BITMAP) {
+		map_cache_open(map_bitmap_filename);
+	}
 
-	ShowStatus("Loading Maps...\n");
+	sprintf(tmp_output, "Loading Maps%s...\n",
+		(map_read_flag == CREATE_BITMAP ? " (Generating Map Cache)" :
+		map_read_flag == READ_FROM_BITMAP ? " (w/ Map Cache)" :
+		map_read_flag == READ_FROM_AFM ? " (w/ AFM)" : ""));
+	ShowStatus(tmp_output);
 
 	// 先に全部のャbプの存在を確認
 	for(i=0;i<map_num;i++){
+
 #ifdef USE_AFM
 		char afm_name[256] = "";
 		char *p;
-		strncpy(afm_name, map[i].name, strlen(map[i].name) - 4);
-		strcat(afm_name, ".afm");
+		if(!strstr(map[i].name,".afm")) {
+		// check if it's necessary to replace the extension - speeds up loading abit
+			strncpy(afm_name, map[i].name, strlen(map[i].name) - 4);
+			strcat(afm_name, ".afm");
+		}
 		map[i].alias = NULL;
-
 		sprintf(fn,"%s\\%s",afm_dir,afm_name);
 		for(p=&fn[0];*p!=0;p++) if (*p=='\\') *p = '/';	// * At the time of Unix
 
@@ -1705,7 +1975,7 @@ int map_readallmap(void) {
 				map[i].alias = NULL;
 
 			sprintf(fn,"data\\%s",map[i].name);
-			if(map_readmap(i,fn, p) == -1) {
+			if(map_readmap(i,fn, p, &map_cache) == -1) {
 				map_delmap(map[i].name);
 				maps_removed++;
 				i--;
@@ -1729,6 +1999,12 @@ int map_readallmap(void) {
 	printf("\r");
 	snprintf(tmp_output,sizeof(tmp_output),"Successfully loaded '"CL_WHITE"%d"CL_RESET"' maps.%30s\n",map_num,"");
 	ShowInfo(tmp_output);
+	
+	map_cache_close();
+	if(map_read_flag == CREATE_BITMAP) {
+		map_read_flag = READ_FROM_BITMAP;
+	}
+	
 	if (maps_removed) {
 		snprintf(tmp_output,sizeof(tmp_output),"Maps Removed: '"CL_WHITE"%d"CL_RESET"'\n",maps_removed);
 		ShowNotice(tmp_output);
@@ -1937,6 +2213,11 @@ 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){
+				if (atoi(w2) == 1)
+					map_read_flag = READ_FROM_BITMAP;
+				else
+					map_read_flag = READ_FROM_GAT;
 			} else if (strcmpi(w1, "import") == 0) {
 				map_config_read(w2);
 			} else if (strcmpi(w1, "console") == 0) {
@@ -2125,6 +2406,13 @@ int sql_config_read(char *cfgName)
 			strcpy(log_db_pw, w2);
 		} else if(strcmpi(w1,"log_db_port")==0) {
 			log_db_port = atoi(w2);
+		}else if(strcmpi(w1,"read_map_from_bitmap")==0){
+			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);
 		//support the import command, just like any other config
 		} else if(strcmpi(w1,"import")==0){
 			sql_config_read(w2);
@@ -2250,7 +2538,10 @@ void do_final(void) {
     numdb_final(charid_db, charid_db_final);
 
 	for(i=0;i<=map_num;i++){
-		if(map[i].gat) free(map[i].gat);
+		if(map[i].gat) {	
+			free(map[i].gat);
+			map[i].gat=NULL;
+		}
 		if(map[i].block) free(map[i].block);
 		if(map[i].block_mob) free(map[i].block_mob);
 		if(map[i].block_count) free(map[i].block_count);
@@ -2350,8 +2641,10 @@ int do_init(int argc, char *argv[]) {
 		else if (strcmp(argv[i],"--sql_config") == 0 || strcmp(argv[i],"--sql-config") == 0)
 		    SQL_CONF_NAME = argv[i+1];
 		else if (strcmp(argv[i],"--log_config") == 0 || strcmp(argv[i],"--log-config") == 0)
-		    LOG_CONF_NAME = argv[i+1];
+		    LOG_CONF_NAME = argv[i+1];		
 #endif /* not TXT_ONLY */
+		else if (strcmp(argv[i],"--run_once") == 0)	// close the map-server as soon as its done.. for testing [Celest]
+			runflag = 0;
 	}
 
 	map_config_read(MAP_CONF_NAME);

+ 35 - 5
src/map/map.h

@@ -500,10 +500,15 @@ 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]	
+	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;
@@ -557,8 +562,8 @@ struct map_data_other_server {
 	unsigned long ip;
 	unsigned int port;
 };
-#define read_gat(m,x,y) (map[m].gat[(x)+(y)*map[m].xs])
-#define read_gatp(m,x,y) (m->gat[(x)+(y)*m->xs])
+#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;
@@ -617,6 +622,25 @@ 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*---------------
+ * ほとんどは上と対応、設定用
+ */
+typedef enum {
+	CELL_SETPASS,CELL_SETNOPASS,CELL_SETWATER=3,CELL_SETHIGH=5,CELL_SETNOHIGH,CELL_SETTOUCH
+} CELL_SET;
+
 struct chat_data {
 	struct block_list bl;
 
@@ -638,6 +662,13 @@ 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ならビットマップファイル
+enum { READ_FROM_GAT, READ_FROM_AFM, READ_FROM_BITMAP, CREATE_BITMAP };
+
 extern char motd_txt[];
 extern char help_txt[];
 
@@ -698,8 +729,7 @@ struct map_session_data * map_nick2sd(char*);
 int compare_item(struct item *a, struct item *b);
 
 // gat関連
-int map_getcell(int,int,int);
-int map_setcell(int,int,int,int);
+int map_setcell(int,int,int,CELL_SET);
 
 // その他
 int map_check_dir(int s_dir,int t_dir);

+ 16 - 17
src/map/mob.c

@@ -216,7 +216,7 @@ int mob_once_spawn_area(struct map_session_data *sd,char *mapname,
 	int x0,int y0,int x1,int y1,
 	const char *mobname,int class,int amount,const char *event)
 {
-	int x,y,i,c,max,lx=-1,ly=-1,id=0;
+	int x,y,i,max,lx=-1,ly=-1,id=0;
 	int m;
 
 	if(strcmp(mapname,"this")==0)
@@ -235,7 +235,7 @@ int mob_once_spawn_area(struct map_session_data *sd,char *mapname,
 		do{
 			x=rand()%(x1-x0+1)+x0;
 			y=rand()%(y1-y0+1)+y0;
-		}while( ( (c=map_getcell(m,x,y))==1 || c==5)&& (++j)<max );
+		} while (map_getcell(m,x,y,CELL_CHKNOPASS) && (++j)<max);
 		if(j>=max){
 			if(lx>=0){	// 検索に失敗したので以前に沸いた場所を使う
 				x=lx;
@@ -243,6 +243,7 @@ int mob_once_spawn_area(struct map_session_data *sd,char *mapname,
 			}else
 				return 0;	// 最初に沸く場所の検索を失敗したのでやめる
 		}
+		if(x==0||y==0) printf("xory=0, x=%d,y=%d,x0=%d,y0=%d\n",x,y,x0,y0);
 		id=mob_once_spawn(sd,mapname,x,y,mobname,class,1,event);
 		lx=x;
 		ly=y;
@@ -461,7 +462,7 @@ static int mob_walktoxy_sub(struct mob_data *md);
 static int mob_walk(struct mob_data *md,unsigned int tick,int data)
 {
 	int moveblock;
-	int i,ctype;
+	int i;
 	static int dirx[8]={0,-1,-1,-1,0,1,1,1};
 	static int diry[8]={1,1,0,-1,-1,-1,0,1};
 	int x,y,dx,dy;
@@ -486,8 +487,7 @@ static int mob_walk(struct mob_data *md,unsigned int tick,int data)
 
 		x = md->bl.x;
 		y = md->bl.y;
-		ctype = map_getcell(md->bl.m,x,y);
-		if(ctype == 1 || ctype == 5) {
+		if(map_getcell(md->bl.m,x,y,CELL_CHKNOPASS)) {
 			mob_stop_walking(md,1);
 			return 0;
 		}
@@ -495,8 +495,7 @@ static int mob_walk(struct mob_data *md,unsigned int tick,int data)
 		dx = dirx[md->dir];
 		dy = diry[md->dir];
 
-		ctype = map_getcell(md->bl.m,x+dx,y+dy);
-		if(ctype == 1 || ctype == 5) {
+		if(map_getcell(md->bl.m,x+dx,y+dy,CELL_CHKNOPASS)) {
 			mob_walktoxy_sub(md);
 			return 0;
 		}
@@ -925,7 +924,7 @@ int mob_spawn(int id)
 			y=md->y0+rand()%(md->ys+1)-md->ys/2;
 		}
 		i++;
-	} while(((c=map_getcell(md->bl.m,x,y))==1 || c==5) && i<50);
+	} while(map_getcell(md->bl.m,x,y,CELL_CHKNOPASS) && i<50);
 
 	if(i>=50){
 //		if(battle_config.error_log==1)
@@ -1517,7 +1516,7 @@ static int mob_randomwalk(struct mob_data *md,int tick)
 			x+=md->bl.x;
 			y+=md->bl.y;
 
-			if((c=map_getcell(md->bl.m,x,y))!=1 && c!=5 && mob_walktoxy(md,x,y,1)==0){
+			if((map_getcell(md->bl.m,x,y,CELL_CHKPASS)) && mob_walktoxy(md,x,y,1)==0){
 				md->move_fail_count=0;
 				break;
 			}
@@ -2782,7 +2781,7 @@ int mob_warpslave(struct mob_data *md,int x, int y)
  */
 int mob_warp(struct mob_data *md,int m,int x,int y,int type)
 {
-	int i=0,c,xs=0,ys=0,bx=x,by=y;
+	int i=0,xs=0,ys=0,bx=x,by=y;
 
 	nullpo_retr(0, md);
 
@@ -2803,7 +2802,7 @@ int mob_warp(struct mob_data *md,int m,int x,int y,int type)
 		xs=ys=9;
 	}
 
-	while( ( x<0 || y<0 || ((c=read_gat(m,x,y))==1 || c==5) ) && (i++)<1000 ){
+	while( ( x<0 || y<0 || map_getcell(m,x,y,CELL_CHKNOPASS)) && (i++)<1000 ){
 		if( xs>0 && ys>0 && i<250 ){	// 指定位置付近の探索
 			x=bx+rand()%xs-xs/2;
 			y=by+rand()%ys-ys/2;
@@ -2906,14 +2905,14 @@ int mob_summonslave(struct mob_data *md2,int *value,int amount,int flag)
 		class = value[k];
 		if(class<=1000 || class>MAX_MOB_DB) continue;
 		for(;amount>0;amount--){
-			int x=0,y=0,c=0,i=0;
+			int x=0,y=0,i=0;
 			md=(struct mob_data *)aCalloc(1,sizeof(struct mob_data));
 			if(mob_db[class].mode&0x02)
 				md->lootitem=(struct item *)aCalloc(LOOTITEM_SIZE,sizeof(struct item));
 			else
 				md->lootitem=NULL;
 
-			while((x<=0 || y<=0 || (c=map_getcell(m,x,y))==1 || c==5 ) && (i++)<100){
+			while((x<=0 || y<=0 || map_getcell(m,x,y,CELL_CHKNOPASS)) && (i++)<100){
 				x=rand()%9-4+bx;
 				y=rand()%9-4+by;
 			}
@@ -3611,24 +3610,24 @@ int mobskill_use(struct mob_data *md,unsigned int tick,int event)
 					continue;
 				// 自分の周囲
 				if( ms[i].target>=MST_AROUND1 ){
-					int bx=x, by=y, i=0, c, m=bl->m, r=ms[i].target-MST_AROUND1;
+					int bx=x, by=y, i=0, m=bl->m, r=ms[i].target-MST_AROUND1;
 					do{
 						bx=x + rand()%(r*2+3) - r;
 						by=y + rand()%(r*2+3) - r;
 					}while( ( bx<=0 || by<=0 || bx>=map[m].xs || by>=map[m].ys ||
-						((c=read_gat(m,bx,by))==1 || c==5) ) && (i++)<1000);
+						map_getcell(m,bx,by,CELL_CHKNOPASS)) && (i++)<1000);
 					if(i<1000){
 						x=bx; y=by;
 					}
 				}
 				// 相手の周囲
 				if( ms[i].target>=MST_AROUND5 ){
-					int bx=x, by=y, i=0, c, m=bl->m, r=(ms[i].target-MST_AROUND5)+1;
+					int bx=x, by=y, i=0,m=bl->m, r=(ms[i].target-MST_AROUND5)+1;
 					do{
 						bx=x + rand()%(r*2+1) - r;
 						by=y + rand()%(r*2+1) - r;
 					}while( ( bx<=0 || by<=0 || bx>=map[m].xs || by>=map[m].ys ||
-						((c=read_gat(m,bx,by))==1 || c==5) ) && (i++)<1000);
+						map_getcell(m,bx,by,CELL_CHKNOPASS)) && (i++)<1000);
 					if(i<1000){
 						x=bx; y=by;
 					}

+ 7 - 13
src/map/npc.c

@@ -1126,7 +1126,7 @@ static int calc_next_walk_step(struct npc_data *nd)
 static int npc_walk(struct npc_data *nd,unsigned int tick,int data)
 {
 	int moveblock;
-	int i,ctype;
+	int i;
 	static int dirx[8]={0,-1,-1,-1,0,1,1,1};
 	static int diry[8]={1,1,0,-1,-1,-1,0,1};
 	int x,y,dx,dy;
@@ -1151,8 +1151,7 @@ static int npc_walk(struct npc_data *nd,unsigned int tick,int data)
 
 		x = nd->bl.x;
 		y = nd->bl.y;
-		ctype = map_getcell(nd->bl.m,x,y);
-		if(ctype == 1 || ctype == 5) {
+		if(map_getcell(nd->bl.m,x,y,CELL_CHKNOPASS)) {
 			npc_stop_walking(nd,1);
 			return 0;
 		}
@@ -1160,8 +1159,7 @@ static int npc_walk(struct npc_data *nd,unsigned int tick,int data)
 		dx = dirx[nd->dir];
 		dy = diry[nd->dir];
 
-		ctype = map_getcell(nd->bl.m,x+dx,y+dy);
-		if(ctype == 1 || ctype == 5) {
+		if(map_getcell(nd->bl.m,x+dx,y+dy,CELL_CHKNOPASS)) {
 			npc_walktoxy_sub(nd);
 			return 0;
 		}
@@ -1468,11 +1466,9 @@ int npc_parse_warp(char *w1,char *w2,char *w3,char *w4)
 
 	for(i=0;i<ys;i++) {
 		for(j=0;j<xs;j++) {
-			int t;
-			t=map_getcell(m,x-xs/2+j,y-ys/2+i);
-			if (t==1 || t==5)
+			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,t|0x80);
+			map_setcell(m,x-xs/2+j,y-ys/2+i,CELL_SETTOUCH);
 		}
 	}
 
@@ -1698,11 +1694,9 @@ static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line
 
 			for(i=0;i<ys;i++) {
 				for(j=0;j<xs;j++) {
-					int t;
-					t=map_getcell(m,x-xs/2+j,y-ys/2+i);
-					if (t==1 || t==5)
+					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,t|0x80);
+					map_setcell(m,x-xs/2+j,y-ys/2+i,CELL_SETTOUCH);
 				}
 			}
 		}

+ 6 - 10
src/map/path.c

@@ -168,17 +168,13 @@ static int add_path(int *heap,struct tmp_path *tp,int x,int y,int dist,int dir,i
  */
 static int can_place(struct map_data *m,int x,int y,int flag)
 {
-	int c;
-
 	nullpo_retr(0, m);
 
-	c=read_gatp(m,x,y);
-
-	if(c==1)
-		return 0;
-	if(!(flag&0x10000) && c==5)
-		return 0;
-	return 1;
+	if(map_getcellp(m,x,y,CELL_CHKPASS))
+		return 1;
+	else if((flag&0x10000)&&map_getcellp(m,x,y,CELL_CHKHIGH))
+		return 1;
+	return 0;
 }
 
 /*==========================================
@@ -262,7 +258,7 @@ int path_search(struct walkpath_data *wpd,int m,int x0,int y0,int x1,int y1,int
 	if(!map[m].gat)
 		return -1;
 	md=&map[m];
-	if(x1<0 || x1>=md->xs || y1<0 || y1>=md->ys || (i=read_gatp(md,x1,y1))==1 || i==5)
+	if(x1<0 || x1>=md->xs || y1<0 || y1>=md->ys || map_getcellp(md,x1,y1,CELL_CHKNOPASS))
 		return -1;
 
 	// easy

+ 12 - 15
src/map/pc.c

@@ -3822,7 +3822,7 @@ int pc_steal_coin(struct map_session_data *sd,struct block_list *bl)
 int pc_setpos(struct map_session_data *sd,char *mapname_org,int x,int y,int clrtype)
 {
 	char mapname[24];
-	int m=0,c=0,disguise=0;
+	int m=0,disguise=0;
 
 	nullpo_retr(0, sd);
 
@@ -3935,7 +3935,7 @@ int pc_setpos(struct map_session_data *sd,char *mapname_org,int x,int y,int clrt
 
 	if(x <0 || x >= map[m].xs || y <0 || y >= map[m].ys)
 		x=y=0;
-	if((x==0 && y==0) || (c=read_gat(m,x,y))==1 || c==5){
+	if((x==0 && y==0) || map_getcell(m,x,y,CELL_CHKNOPASS)){
 		if(x||y) {
 			if(battle_config.error_log)
 				printf("stacked (%d,%d)\n",x,y);
@@ -3943,7 +3943,7 @@ int pc_setpos(struct map_session_data *sd,char *mapname_org,int x,int y,int clrt
 		do {
 			x=rand()%(map[m].xs-2)+1;
 			y=rand()%(map[m].ys-2)+1;
-		} while((c=read_gat(m,x,y))==1 || c==5);
+		} while(map_getcell(m,x,y,CELL_CHKNOPASS));
 	}
 
 	if(sd->mapname[0] && sd->bl.prev != NULL){
@@ -4011,7 +4011,7 @@ int pc_setpos(struct map_session_data *sd,char *mapname_org,int x,int y,int clrt
  *------------------------------------------
  */
 int pc_randomwarp(struct map_session_data *sd, int type) {
-	int x,y,c,i=0;
+	int x,y,i=0;
 	int m;
 
 	nullpo_retr(0, sd);
@@ -4024,7 +4024,7 @@ int pc_randomwarp(struct map_session_data *sd, int type) {
 	do{
 		x=rand()%(map[m].xs-2)+1;
 		y=rand()%(map[m].ys-2)+1;
-	} while (((c=read_gat(m,x,y)) == 1 || c == 5) && (i++) < 1000);
+	}while(map_getcell(m,x,y,CELL_CHKNOPASS) && (i++)<1000 );
 
 	if (i < 1000)
 		pc_setpos(sd,map[m].name,x,y,type);
@@ -4129,7 +4129,7 @@ static int calc_next_walk_step(struct map_session_data *sd)
 static int pc_walk(int tid,unsigned int tick,int id,int data)
 {
 	struct map_session_data *sd;
-	int i,ctype;
+	int i;
 	int moveblock;
 	int x,y,dx,dy;
 
@@ -4162,16 +4162,14 @@ static int pc_walk(int tid,unsigned int tick,int id,int data)
 
 		x = sd->bl.x;
 		y = sd->bl.y;
-		ctype = map_getcell(sd->bl.m,x,y);
-		if(ctype == 1 || ctype == 5) {
+		if(map_getcell(sd->bl.m,x,y,CELL_CHKNOPASS)) {
 			pc_stop_walking(sd,1);
 			return 0;
 		}
 		sd->dir=sd->head_dir=sd->walkpath.path[sd->walkpath.path_pos];
 		dx = dirx[(int)sd->dir];
 		dy = diry[(int)sd->dir];
-		ctype = map_getcell(sd->bl.m,x+dx,y+dy);
-		if(ctype == 1 || ctype == 5) {
+		if(map_getcell(sd->bl.m,x,y,CELL_CHKNOPASS)) {
 			pc_walktoxy_sub(sd);
 			return 0;
 		}
@@ -4252,7 +4250,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)&0x80)
+		if(map_getcell(sd->bl.m,x,y,CELL_CHKTOUCH))
 			npc_touch_areanpc(sd,sd->bl.m,x,y);
 		else
 			sd->areanpc_id=0;
@@ -4378,15 +4376,14 @@ int pc_randomwalk(struct map_session_data *sd,int tick)
 	nullpo_retr(0, sd);
 	
 	if(DIFF_TICK(sd->next_walktime,tick)<0){
-		int i,x,y,c,d;
+		int i,x,y,d;
 		d = rand()%7+5;
 		for(i=0;i<retrycount;i++){	// Search of a movable place
 			int r=rand();
 			x=sd->bl.x+r%(d*2+1)-d;
 			y=sd->bl.y+r/(d*2+1)%(d*2+1)-d;
-			if((c=map_getcell(sd->bl.m,x,y))!=1 && c!=5 && pc_walktoxy(sd,x,y)==0){
+			if((map_getcell(sd->bl.m,x,y,CELL_CHKPASS)) && pc_walktoxy(sd,x,y)==0)
 				break;
-			}
 		}
 		// Working on this part later [celest]
 		/*for(i=c=0;i<sd->walkpath.path_len;i++){	// The next walk start time is calculated.
@@ -4450,7 +4447,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)&0x80)
+	if(map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKTOUCH))
 		npc_touch_areanpc(sd,sd->bl.m,sd->bl.x,sd->bl.y);
 	else
 		sd->areanpc_id=0;

+ 3 - 4
src/map/pet.c

@@ -203,7 +203,7 @@ static int pet_attack(struct pet_data *pd,unsigned int tick,int data)
 static int pet_walk(struct pet_data *pd,unsigned int tick,int data)
 {
 	int moveblock;
-	int i,ctype;
+	int i;
 	int x,y,dx,dy;
 
 	nullpo_retr(0, pd);
@@ -235,8 +235,7 @@ static int pet_walk(struct pet_data *pd,unsigned int tick,int data)
 		dx = dirx[pd->dir];
 		dy = diry[pd->dir];
 
-		ctype = map_getcell(pd->bl.m,x+dx,y+dy);
-		if(ctype == 1 || ctype == 5) {
+		if(map_getcell(pd->bl.m,x+dx,y+dy,CELL_CHKNOPASS)){
 			pet_walktoxy_sub(pd);
 			return 0;
 		}
@@ -1058,7 +1057,7 @@ static int pet_randomwalk(struct pet_data *pd,int tick)
 			int r=rand();
 			x=pd->bl.x+r%(d*2+1)-d;
 			y=pd->bl.y+r/(d*2+1)%(d*2+1)-d;
-			if((c=map_getcell(pd->bl.m,x,y))!=1 && c!=5 && pet_walktoxy(pd,x,y)==0){
+			if((map_getcell(pd->bl.m,x,y,CELL_CHKPASS))&&( pet_walktoxy(pd,x,y)==0)){
 				pd->move_fail_count=0;
 				break;
 			}

+ 13 - 13
src/map/skill.c

@@ -2069,13 +2069,13 @@ static int skill_timerskill(int tid, unsigned int tick, int id,int data )
 				break;
 			case RG_INTIMIDATE:
 				if(sd && !map[src->m].flag.noteleport) {
-					int x,y,i,j,c;
+					int x,y,i,j;
 					pc_randomwarp(sd,3);
 					for(i=0;i<16;i++) {
 						j = rand()%8;
 						x = sd->bl.x + dirx[j];
 						y = sd->bl.y + diry[j];
-						if((c=map_getcell(sd->bl.m,x,y)) != 1 && c != 5)
+						if(map_getcell(sd->bl.m,x,y,CELL_CHKPASS))
 							break;
 					}
 					if(i >= 16) {
@@ -2090,13 +2090,13 @@ static int skill_timerskill(int tid, unsigned int tick, int id,int data )
 					}
 				}
 				else if(md && !map[src->m].flag.monster_noteleport) {
-					int x,y,i,j,c;
+					int x,y,i,j;
 					mob_warp(md,-1,-1,-1,3);
 					for(i=0;i<16;i++) {
 						j = rand()%8;
 						x = md->bl.x + dirx[j];
 						y = md->bl.y + diry[j];
-						if((c=map_getcell(md->bl.m,x,y)) != 1 && c != 5)
+						if(map_getcell(md->bl.m,x,y,CELL_CHKPASS))
 							break;
 					}
 					if(i >= 16) {
@@ -5002,7 +5002,7 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil
 		{
 			int flag=0;
 			for(i=0;i<2+(skilllv>>1);i++) {
-				int j=0, c;
+				int j=0;
 				do {
 					tmpx = x + (rand()%7 - 3);
 					tmpy = y + (rand()%7 - 3);
@@ -5015,7 +5015,7 @@ int skill_castend_pos2( struct block_list *src, int x,int y,int skillid,int skil
 					else if(tmpy >= map[src->m].ys)
 						tmpy = map[src->m].ys - 1;
 					j++;
-				} while(((c=map_getcell(src->m,tmpx,tmpy))==1 || c==5) && j<100);
+				} while((map_getcell(src->m,tmpx,tmpy,CELL_CHKNOPASS)) && j<100);
 				if(j >= 100)
 					continue;
 				if(flag==0){
@@ -5810,11 +5810,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);
+			val2=map_getcell(src->m,ux,uy,CELL_CHKTYPE);
 			if(val2==5 || val2==1)
 				alive=0;
 			else {
-				map_setcell(src->m,ux,uy,5);
+				map_setcell(src->m,ux,uy,CELL_SETNOPASS);
 				clif_changemapcell(src->m,ux,uy,5,0);
 			}
 		}
@@ -6558,6 +6558,8 @@ 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;
@@ -7290,7 +7292,7 @@ int skill_check_condition(struct map_session_data *sd,int type)
 		}
 		break;
 	case ST_WATER:
-		if(map_getcell(sd->bl.m,sd->bl.x,sd->bl.y) != 3 && (sd->sc_data[SC_DELUGE].timer==-1)){	//水場判定
+		if((!map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKWATER))&& (sd->sc_data[SC_DELUGE].timer==-1)){	//水場判定
 			clif_skill_fail(sd,skill,0,0);
 			return 0;
 		}
@@ -10422,8 +10424,7 @@ int skill_check_cloaking(struct block_list *bl)
 	else if(bl->type == BL_MOB && !battle_config.monster_cloak_check_type)
 		return 0;
 	for(i=0;i<sizeof(dx)/sizeof(dx[0]);i++){
-		int c=map_getcell(bl->m,bl->x+dx[i],bl->y+dy[i]);
-		if(c==1 || c==5) {
+		if(map_getcell(bl->m,bl->x+dx[i],bl->y+dy[i],CELL_CHKNOPASS)) {
 			end=0;
 			break;
 		}
@@ -10460,8 +10461,7 @@ int skill_type_cloaking(struct block_list *bl)
 		return 0;
 	for(i=0; i<sizeof(dx)/sizeof(dx[0]); i++)
 	{
-		int c=map_getcell(bl->m,bl->x+dx[i],bl->y+dy[i]);
-		if(c==1 || c==5)
+		if(map_getcell(bl->m,bl->x+dx[i],bl->y+dy[i],CELL_CHKNOPASS))
 			return 0;
 	}
 	return 1;