summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2008-01-03 21:36:40 +0000
committerultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec>2008-01-03 21:36:40 +0000
commit1b241817a93f892a24379866a06e046e7e6c5e86 (patch)
tree72e6e27d29b8eca173b32b64d3b31592de7208c6
parent50418d820226fbcdf7609fb619028e3b75a2fa9e (diff)
downloadhercules-1b241817a93f892a24379866a06e046e7e6c5e86.tar.gz
hercules-1b241817a93f892a24379866a06e046e7e6c5e86.tar.bz2
hercules-1b241817a93f892a24379866a06e046e7e6c5e86.tar.xz
hercules-1b241817a93f892a24379866a06e046e7e6c5e86.zip
Map cell mechanism rewrite
- defined a data structure for map cells (replaces 3 various cell arrays) - both terrain (gat) and dynamic (cell) information is now stored as C-style bit flags instead of #defines and bitmasks - added map_gat2cell() and map_cell2gat() for terrain type conversions - changing terrain information via 'setcell' is temporarily disabled - mapserver startup now takes longer, as it needs to adapt mapcache data to internal representation, cell by cell (new mapcache format anyone?) git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@12003 54d463be-8e91-2dee-dedb-b68131a5f0ec
-rw-r--r--Changelog-Trunk.txt10
-rw-r--r--src/map/map.c248
-rw-r--r--src/map/map.h205
-rw-r--r--src/map/npc.c6
-rw-r--r--src/map/path.c6
-rw-r--r--src/map/skill.c3
6 files changed, 280 insertions, 198 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt
index 6e372f5f4..8cb8e9def 100644
--- a/Changelog-Trunk.txt
+++ b/Changelog-Trunk.txt
@@ -4,11 +4,19 @@ 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.
2008/01/03
+ * Map cell mechanism rewrite
+ - defined a data structure for map cells (replaces 3 various cell arrays)
+ - both terrain (gat) and dynamic (cell) information is now stored as
+ C-style bit flags instead of #defines and bitmasks
+ - added map_gat2cell() and map_cell2gat() for terrain type conversions
+ - changing terrain information via 'setcell' is temporarily disabled
+ - mapserver startup now takes longer, as it needs to adapt mapcache data
+ to internal representation, cell by cell (new mapcache format anyone?)
* Moved extra junk from map_addblock/map_delblock to where it logically
belongs (loadendack/unit_remove_map), removed flags and _sub macros
* Removed map_data's block_count, as (quote Yor/ja2160),
"Perhaps useful for debug, but uses memory AND CPU for nothing."
- (block lists are linked lists, they don't need count tracking)
+ (block lists are linked lists, they don't need count tracking) [ultramage]
2007/12/31
* Fixed a crash in txt char-servers that the memory manager was hiding.
online_char_db being used after being destroyed (since r4026)
diff --git a/src/map/map.c b/src/map/map.c
index 0115bb02b..04ff50e23 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -178,6 +178,10 @@ int map_getusers(void)
return map_users;
}
+//
+// block削除の安全性確保?理
+//
+
/*==========================================
* blockをfreeするときfreeの?わりに呼ぶ
* ロックされているときはバッファにためる
@@ -1977,7 +1981,7 @@ int map_mapindex2mapid(unsigned short mapindex)
return -1;
md = (struct map_data*)uidb_get(map_db,(unsigned int)mapindex);
- if(md==NULL || md->gat==NULL)
+ if(md==NULL || md->cell==NULL)
return -1;
return md->m;
}
@@ -1990,7 +1994,7 @@ int map_mapname2ipport(unsigned short name, uint32* ip, uint16* port)
struct map_data_other_server *mdos=NULL;
mdos = (struct map_data_other_server*)uidb_get(map_db,(unsigned int)name);
- if(mdos==NULL || mdos->gat) //If gat isn't null, this is a local map.
+ if(mdos==NULL || mdos->cell) //If gat isn't null, this is a local map.
return -1;
*ip=mdos->ip;
*port=mdos->port;
@@ -2094,7 +2098,41 @@ int map_random_dir(struct block_list *bl, short *x, short *y)
}
return 0;
}
+
// gat系
+static struct mapcell map_gat2cell(int gat)
+{
+ struct mapcell cell;
+ memset(&cell, 0, sizeof(cell));
+
+ switch( gat )
+ {
+ case 0: cell.walkable = 1; cell.shootable = 1; cell.water = 0; break; // walkable ground
+ case 1: cell.walkable = 0; cell.shootable = 0; cell.water = 0; break; // non-walkable ground
+ case 2: cell.walkable = 1; cell.shootable = 1; cell.water = 0; break; // ???
+ case 3: cell.walkable = 1; cell.shootable = 1; cell.water = 1; break; // walkable water
+ case 4: cell.walkable = 1; cell.shootable = 1; cell.water = 0; break; // ???
+ case 5: cell.walkable = 0; cell.shootable = 1; cell.water = 0; break; // gap (snipable)
+ case 6: cell.walkable = 1; cell.shootable = 1; cell.water = 0; break; // ???
+ default:
+ ShowWarning("map_gat2cell: unrecognized gat type '%d'\n", gat);
+ break;
+ }
+
+ return cell;
+}
+
+static int map_cell2gat(struct mapcell cell)
+{
+ if( cell.walkable == 1 && cell.shootable == 1 && cell.water == 0 ) return 0;
+ if( cell.walkable == 0 && cell.shootable == 0 && cell.water == 0 ) return 1;
+ if( cell.walkable == 1 && cell.shootable == 1 && cell.water == 1 ) return 3;
+ if( cell.walkable == 0 && cell.shootable == 1 && cell.water == 0 ) return 5;
+
+ ShowWarning("map_cell2gat: cell has no matching gat type\n");
+ return 1; // default to 'wall'
+}
+
/*==========================================
* (m,x,y)の状態を調べる
*------------------------------------------*/
@@ -2105,70 +2143,76 @@ int map_getcell(int m,int x,int y,cell_t cellchk)
int map_getcellp(struct map_data* m,int x,int y,cell_t cellchk)
{
- int type, type2;
-#ifdef CELL_NOSTACK
- int type3;
-#endif
+ struct mapcell cell;
nullpo_ret(m);
+ //NOTE: this intentionally overrides the last row and column
if(x<0 || x>=m->xs-1 || y<0 || y>=m->ys-1)
{
if(cellchk==CELL_CHKNOPASS) return 1;
return 0;
}
- type = m->gat[x+y*m->xs];
- type2 = m->cell[x+y*m->xs];
-#ifdef CELL_NOSTACK
- type3 = m->cell_bl[x+y*m->xs];
-#endif
+
+ cell = m->cell[x + y*m->xs];
switch(cellchk)
{
+ // gat type retrieval
+ case CELL_GETTYPE:
+ return map_cell2gat(cell);
+
+ // base gat type checks
+ case CELL_CHKWALL:
+ return (!cell.walkable && !cell.shootable);
+ //return (map_cell2gat(cell) == 1);
+ case CELL_CHKWATER:
+ return (cell.water);
+ //return (map_cell2gat(cell) == 3);
+ case CELL_CHKCLIFF:
+ return (!cell.walkable && cell.shootable);
+ //return (map_cell2gat(cell) == 5);
+
+ // base cell type checks
+ case CELL_CHKNPC:
+ return (cell.npc);
+ case CELL_CHKPNEUMA:
+ return (cell.pneuma);
+ case CELL_CHKSAFETYWALL:
+ return (cell.safetywall);
+ case CELL_CHKBASILICA:
+ return (cell.basilica);
+ case CELL_CHKLANDPROTECTOR:
+ return (cell.landprotector);
+ case CELL_CHKREGEN:
+ return (cell.regen);
+ case CELL_CHKICEWALL:
+ return (cell.icewall);
+ case CELL_CHKNOVENDING:
+ return (cell.novending);
+
+ // special checks
case CELL_CHKPASS:
#ifdef CELL_NOSTACK
- if (type3 >= battle_config.cell_stack_limit) return 0;
+ if (cell.cell_bl >= battle_config.cell_stack_limit) return 0;
#endif
case CELL_CHKREACH:
- return (type!=1 && type!=5 && !(type2&CELL_ICEWALL));
+ return (cell.walkable && !cell.icewall);
+
case CELL_CHKNOPASS:
#ifdef CELL_NOSTACK
- if (type3 >= battle_config.cell_stack_limit) return 1;
+ if (cell.cell_bl >= battle_config.cell_stack_limit) return 1;
#endif
case CELL_CHKNOREACH:
- return (type==1 || type==5 || type2&CELL_ICEWALL);
+ return (!cell.walkable || cell.icewall);
+
case CELL_CHKSTACK:
#ifdef CELL_NOSTACK
- return (type3 >= battle_config.cell_stack_limit);
+ return (cell.cell_bl >= battle_config.cell_stack_limit);
#else
return 0;
#endif
- case CELL_CHKWALL:
- return (type==1/* || type2&CELL_ICEWALL*/); //Uncomment to prevent sniping/casting through the icewall. [Skotlex]
- case CELL_CHKWATER:
- return (type==3);
- case CELL_CHKGROUND:
- return (type==5 || type2&CELL_ICEWALL);
- case CELL_GETTYPE:
- return type;
- case CELL_GETCELLTYPE:
- return type2;
- case CELL_CHKNPC:
- return (type2&CELL_NPC);
- case CELL_CHKPNEUMA:
- return (type2&CELL_PNEUMA);
- case CELL_CHKSAFETYWALL:
- return (type2&CELL_SAFETYWALL);
- case CELL_CHKBASILICA:
- return (type2&CELL_BASILICA);
- case CELL_CHKLANDPROTECTOR:
- return (type2&CELL_LANDPROTECTOR);
- case CELL_CHKREGEN:
- return (type2&CELL_REGEN);
- case CELL_CHKICEWALL:
- return (type2&CELL_ICEWALL);
- case CELL_CHKNOVENDING:
- return (type2&CELL_NOVENDING);
+
default:
return 0;
}
@@ -2185,26 +2229,27 @@ void map_setcell(int m,int x,int y,int cell)
j=x+y*map[m].xs;
switch (cell) {
- case CELL_SETNPC: map[m].cell[j] |= CELL_NPC; break;
- case CELL_CLRNPC: map[m].cell[j] &= ~CELL_NPC; break;
- case CELL_SETICEWALL: map[m].cell[j] |= CELL_ICEWALL; break;
- case CELL_CLRICEWALL: map[m].cell[j] &= ~CELL_ICEWALL; break;
- case CELL_SETBASILICA: map[m].cell[j] |= CELL_BASILICA; break;
- case CELL_CLRBASILICA: map[m].cell[j] &= ~CELL_BASILICA; break;
- case CELL_SETPNEUMA: map[m].cell[j] |= CELL_PNEUMA; break;
- case CELL_CLRPNEUMA: map[m].cell[j] &= ~CELL_PNEUMA; break;
- case CELL_SETSAFETYWALL: map[m].cell[j] |= CELL_SAFETYWALL; break;
- case CELL_CLRSAFETYWALL: map[m].cell[j] &= ~CELL_SAFETYWALL; break;
- case CELL_SETLANDPROTECTOR: map[m].cell[j] |= CELL_LANDPROTECTOR; break;
- case CELL_CLRLANDPROTECTOR: map[m].cell[j] &= ~CELL_LANDPROTECTOR; break;
- case CELL_SETREGEN: map[m].cell[j] |= CELL_REGEN; break;
- case CELL_SETNOVENDING: map[m].cell[j] |= CELL_NOVENDING; break;
- case CELL_CLRNOVENDING: map[m].cell[j] &= ~CELL_NOVENDING; break;
+ case CELL_SETNPC: map[m].cell[j].npc = 1; break;
+ case CELL_CLRNPC: map[m].cell[j].npc = 0; break;
+ case CELL_SETICEWALL: map[m].cell[j].icewall = 1; break;
+ case CELL_CLRICEWALL: map[m].cell[j].icewall = 0; break;
+ case CELL_SETBASILICA: map[m].cell[j].basilica = 1; break;
+ case CELL_CLRBASILICA: map[m].cell[j].basilica = 0; break;
+ case CELL_SETPNEUMA: map[m].cell[j].pneuma = 1; break;
+ case CELL_CLRPNEUMA: map[m].cell[j].pneuma = 0; break;
+ case CELL_SETSAFETYWALL: map[m].cell[j].safetywall = 1; break;
+ case CELL_CLRSAFETYWALL: map[m].cell[j].safetywall = 0; break;
+ case CELL_SETLANDPROTECTOR: map[m].cell[j].landprotector = 1; break;
+ case CELL_CLRLANDPROTECTOR: map[m].cell[j].landprotector = 0; break;
+ case CELL_SETREGEN: map[m].cell[j].regen = 1; break;
+ case CELL_SETNOVENDING: map[m].cell[j].novending = 1; break;
+ case CELL_CLRNOVENDING: map[m].cell[j].novending = 0; break;
default:
- map[m].gat[j] = cell;
+ //map[m].gat[j] = cell; FIXME
break;
}
}
+
static void* create_map_data_other_server(DBKey key, va_list args)
{
struct map_data_other_server *mdos;
@@ -2224,7 +2269,7 @@ int map_setipport(unsigned short mapindex, uint32 ip, uint16 port)
mdos=(struct map_data_other_server *)uidb_ensure(map_db,(unsigned int)mapindex, create_map_data_other_server);
- if(mdos->gat) //Local map,Do nothing. Give priority to our own local maps over ones from another server. [Skotlex]
+ if(mdos->cell) //Local map,Do nothing. Give priority to our own local maps over ones from another server. [Skotlex]
return 0;
if(ip == clif_getip() && port == clif_getport()) {
//That's odd, we received info that we are the ones with this map, but... we don't have it.
@@ -2242,7 +2287,7 @@ int map_setipport(unsigned short mapindex, uint32 ip, uint16 port)
int map_eraseallipport_sub(DBKey key,void *data,va_list va)
{
struct map_data_other_server *mdos = (struct map_data_other_server*)data;
- if(mdos->gat == NULL) {
+ if(mdos->cell == NULL) {
db_remove(map_db,key);
aFree(mdos);
}
@@ -2263,7 +2308,7 @@ int map_eraseipport(unsigned short mapindex, uint32 ip, uint16 port)
struct map_data_other_server *mdos;
mdos = uidb_get(map_db,(unsigned int)mapindex);
- if(!mdos || mdos->gat) //Map either does not exists or is a local map.
+ if(!mdos || mdos->cell) //Map either does not exists or is a local map.
return 0;
if(mdos->ip==ip && mdos->port == port) {
@@ -2279,32 +2324,49 @@ int map_eraseipport(unsigned short mapindex, uint32 ip, uint16 port)
*===========================================*/
int map_readfromcache(struct map_data *m, FILE *fp)
{
- int i;
struct map_cache_main_header header;
struct map_cache_map_info info;
- unsigned long size;
- unsigned char *buf;
-
- if(!fp)
+ int i;
+
+ if( !fp )
return 0;
fseek(fp, 0, SEEK_SET);
fread(&header, sizeof(struct map_cache_main_header), 1, fp);
- for(i = 0; i < header.map_count; i++) {
+ for( i = 0; i < header.map_count; ++i )
+ {
fread(&info, sizeof(struct map_cache_map_info), 1, fp);
- if(strcmp(m->name, info.name) == 0) { // Map found
- m->xs = info.xs;
- m->ys = info.ys;
- m->gat = (unsigned char *)aMalloc(m->xs*m->ys); // Allocate room for map cells data
- buf = aMalloc(info.len); // Allocate a temp buffer to read the zipped map
- fread(buf, info.len, 1, fp);
- size = m->xs*m->ys;
- decode_zip(m->gat, &size, buf, info.len); // Unzip the map from the buffer
- aFree(buf);
- return 1;
- } else // Map not found, jump to the beginning of the next map info header
- fseek(fp, info.len, SEEK_CUR);
+
+ if( strcmp(m->name, info.name) == 0 )
+ break; // Map found
+
+ // Map not found, jump to the beginning of the next map info header
+ fseek(fp, info.len, SEEK_CUR);
+ }
+
+ if( i < header.map_count )
+ {
+ unsigned char *buf, *buf2;
+ unsigned int size, xy;
+
+ m->xs = info.xs;
+ m->ys = info.ys;
+ size = info.xs*info.ys;
+
+ buf = aMalloc(info.len); // temp buffer to read the zipped map
+ buf2 = aMalloc(size); // temp buffer to unpack the data
+ CREATE(m->cell, struct mapcell, size);
+
+ fread(buf, info.len, 1, fp);
+ decode_zip(buf2, &size, buf, info.len); // Unzip the map from the buffer
+
+ for( xy = 0; xy < size; ++xy )
+ m->cell[xy] = map_gat2cell(buf2[xy]);
+
+ aFree(buf);
+ aFree(buf2);
+ return 1;
}
return 0;
@@ -2329,7 +2391,7 @@ int map_addmap(char* mapname)
static void map_delmapid(int id)
{
- ShowNotice("Removing map [ %s ] from maplist\n"CL_CLL,map[id].name);
+ ShowNotice("Removing map [ %s ] from maplist"CL_CLL"\n",map[id].name);
memmove(map+id, map+id+1, sizeof(map[0])*(map_num-id-1));
map_num--;
}
@@ -2404,7 +2466,7 @@ int map_readgat (struct map_data* m)
m->xs = *(int32*)(gat+6);
m->ys = *(int32*)(gat+10);
num_cells = m->xs * m->ys;
- CREATE(m->gat, uint8, num_cells);
+ CREATE(m->cell, struct mapcell, num_cells);
water_height = map_waterheight(m->name);
@@ -2420,10 +2482,9 @@ int map_readgat (struct map_data* m)
if( type == 0 && water_height != NO_WATER && height > water_height )
type = 3; // Cell is 0 (walkable) but under water level, set to 3 (walkable water)
- m->gat[xy] = (uint8)type;
-
+ m->cell[xy] = map_gat2cell(type);
}
-
+
aFree(gat);
return 1;
@@ -2473,10 +2534,10 @@ int map_readallmaps (void)
if (uidb_get(map_db,(unsigned int)map[i].index) != NULL)
{
- ShowWarning("Map %s already loaded!\n"CL_CLL, map[i].name);
- if (map[i].gat) {
- aFree(map[i].gat);
- map[i].gat = NULL;
+ ShowWarning("Map %s already loaded!"CL_CLL"\n", map[i].name);
+ if (map[i].cell) {
+ aFree(map[i].cell);
+ map[i].cell = NULL;
}
map_delmapid(i);
maps_removed++;
@@ -2492,11 +2553,6 @@ int map_readallmaps (void)
if(battle_config.pk_mode)
map[i].flag.pvp = 1; // make all maps pvp for pk_mode [Valaris]
- map[i].cell = (unsigned char *)aCalloc(map[i].xs * map[i].ys, sizeof(unsigned char));
-#ifdef CELL_NOSTACK
- map[i].cell_bl = (unsigned char *)aCalloc(map[i].xs * map[i].ys, sizeof(unsigned char));
-#endif
-
map[i].bxs = (map[i].xs + BLOCK_SIZE - 1) / BLOCK_SIZE;
map[i].bys = (map[i].ys + BLOCK_SIZE - 1) / BLOCK_SIZE;
@@ -2859,7 +2915,7 @@ int sql_ping_init(void)
int map_db_final(DBKey k,void *d,va_list ap)
{
struct map_data_other_server *mdos = (struct map_data_other_server*)d;
- if(mdos && mdos->gat == NULL)
+ if(mdos && mdos->cell == NULL)
aFree(mdos);
return 0;
}
@@ -2977,11 +3033,7 @@ void do_final(void)
map_db->destroy(map_db, map_db_final);
for (i=0; i<map_num; i++) {
- if(map[i].gat) aFree(map[i].gat);
if(map[i].cell) aFree(map[i].cell);
-#ifdef CELL_NOSTACK
- if(map[i].cell_bl) aFree(map[i].cell_bl);
-#endif
if(map[i].block) aFree(map[i].block);
if(map[i].block_mob) aFree(map[i].block_mob);
if(battle_config.dynamic_mobs) { //Dynamic mobs flag by [random]
diff --git a/src/map/map.h b/src/map/map.h
index fa165609d..67e6d04fc 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -1014,93 +1014,6 @@ struct pet_data {
struct map_session_data *msd;
};
-struct map_data {
- char name[MAP_NAME_LENGTH];
- unsigned short index; // The map index used by the mapindex* functions.
- unsigned char *gat; // Holds the type of each map cell (NULL if the map is not on this map-server).
- unsigned char *cell; // Contains temporary cell data that is set/unset on tiles.
-#ifdef CELL_NOSTACK
- unsigned char *cell_bl; //Holds amount of bls in any given cell.
-#endif
- struct block_list **block;
- struct block_list **block_mob;
- int m;
- short xs,ys; // map dimensions (in cells)
- short bxs,bys; // map dimensions (in blocks)
- int npc_num;
- int users;
- struct map_flag {
- unsigned nomemo : 1;
- unsigned noteleport : 1;
- unsigned noreturn : 1;
- unsigned monster_noteleport : 1;
- unsigned nosave : 1;
- unsigned nobranch : 1;
- unsigned noexppenalty : 1;
- unsigned pvp : 1;
- unsigned pvp_noparty : 1;
- unsigned pvp_noguild : 1;
- unsigned pvp_nightmaredrop :1;
- unsigned pvp_nocalcrank : 1;
- unsigned gvg_castle : 1;
- unsigned gvg : 1; // Now it identifies gvg versus maps that are active 24/7
- unsigned gvg_dungeon : 1; // Celest
- unsigned gvg_noparty : 1;
- unsigned nozenypenalty : 1;
- unsigned notrade : 1;
- unsigned noskill : 1;
- unsigned nowarp : 1;
- unsigned nowarpto : 1;
- unsigned noicewall : 1; // [Valaris]
- unsigned snow : 1; // [Valaris]
- unsigned clouds : 1;
- unsigned clouds2 : 1; // [Valaris]
- unsigned fog : 1; // [Valaris]
- unsigned fireworks : 1;
- unsigned sakura : 1; // [Valaris]
- unsigned leaves : 1; // [Valaris]
- unsigned rain : 1; // [Valaris]
- unsigned indoors : 1; // celest
- unsigned nogo : 1; // [Valaris]
- unsigned nobaseexp : 1; // [Lorky] added by Lupus
- unsigned nojobexp : 1; // [Lorky]
- unsigned nomobloot : 1; // [Lorky]
- unsigned nomvploot : 1; // [Lorky]
- unsigned nightenabled :1; //For night display. [Skotlex]
- unsigned restricted : 1; // [Komurka]
- unsigned nodrop : 1;
- unsigned novending : 1;
- unsigned loadevent : 1;
- unsigned nochat :1;
- unsigned partylock :1;
- unsigned guildlock :1;
- } flag;
- struct point save;
- struct npc_data *npc[MAX_NPC_PER_MAP];
- struct {
- int drop_id;
- int drop_type;
- int drop_per;
- } drop_list[MAX_DROP_PER_MAP];
-
- struct spawn_data *moblist[MAX_MOB_LIST_PER_MAP]; // [Wizputer]
- int mob_delete_timer; // [Skotlex]
- int zone; // zone number (for item/skill restrictions)
- int jexp; // map experience multiplicator
- int bexp; // map experience multiplicator
- int nocommand; //Blocks @/# commands for non-gms. [Skotlex]
-};
-
-/// Stores information about a remote map (for multi-mapserver setups).
-/// Beginning of data structure matches 'map_data', to allow typecasting.
-struct map_data_other_server {
- char name[MAP_NAME_LENGTH];
- unsigned short index; //Index is the map index used by the mapindex* functions.
- unsigned char *gat; // If this is NULL, the map is not on this map-server
- uint32 ip;
- uint16 port;
-};
-
struct flooritem_data {
struct block_list bl;
unsigned char subx,suby;
@@ -1207,15 +1120,17 @@ enum _look {
* map_getcell()で使用されるフラグ
*/
typedef enum {
- CELL_CHKWALL=0, // 壁(セルタイプ1)
+ CELL_GETTYPE, // セルタイプを返す
+
+ CELL_CHKWALL, // 壁(セルタイプ1)
CELL_CHKWATER, // 水場(セルタイプ3)
- CELL_CHKGROUND, // 地面障害物(セルタイプ5)
+ CELL_CHKCLIFF, // 地面障害物(セルタイプ5)
+
CELL_CHKPASS, // 通過可能(セルタイプ1,5以外)
CELL_CHKREACH, // Same as PASS, but ignores the cell-stacking mod.
CELL_CHKNOPASS, // 通過不可(セルタイプ1,5)
CELL_CHKNOREACH, // Same as NOPASS, but ignores the cell-stacking mod.
- CELL_GETTYPE, // セルタイプを返す
- CELL_GETCELLTYPE,
+
CELL_CHKNPC=0x10, // タッチタイプのNPC(セルタイプ0x80フラグ)
CELL_CHKREGEN, // cells that improve regeneration
CELL_CHKPNEUMA,
@@ -1226,6 +1141,7 @@ typedef enum {
CELL_CHKSTACK,
CELL_CHKNOVENDING,
} cell_t;
+
// map_setcell()で使用されるフラグ
enum {
CELL_SETNPC=0x10, // タッチタイプのNPCをセット
@@ -1245,6 +1161,113 @@ enum {
CELL_CLRNOVENDING,
};
+struct mapcell
+{
+ // terrain flags
+ unsigned char
+ walkable : 1,
+ shootable : 1,
+ water : 1;
+
+ // dynamic flags
+ unsigned char
+ npc : 1,
+ regen : 1,
+ pneuma : 1,
+ safetywall : 1,
+ landprotector : 1,
+ basilica : 1,
+ icewall : 1,
+ novending : 1;
+
+#ifdef CELL_NOSTACK
+ unsigned char cell_bl; //Holds amount of bls in this cell.
+#endif
+};
+
+struct map_data {
+ char name[MAP_NAME_LENGTH];
+ unsigned short index; // The map index used by the mapindex* functions.
+ struct mapcell* cell; // Holds the information of each map cell (NULL if the map is not on this map-server).
+ struct block_list **block;
+ struct block_list **block_mob;
+ int m;
+ short xs,ys; // map dimensions (in cells)
+ short bxs,bys; // map dimensions (in blocks)
+ int npc_num;
+ int users;
+ struct map_flag {
+ unsigned nomemo : 1;
+ unsigned noteleport : 1;
+ unsigned noreturn : 1;
+ unsigned monster_noteleport : 1;
+ unsigned nosave : 1;
+ unsigned nobranch : 1;
+ unsigned noexppenalty : 1;
+ unsigned pvp : 1;
+ unsigned pvp_noparty : 1;
+ unsigned pvp_noguild : 1;
+ unsigned pvp_nightmaredrop :1;
+ unsigned pvp_nocalcrank : 1;
+ unsigned gvg_castle : 1;
+ unsigned gvg : 1; // Now it identifies gvg versus maps that are active 24/7
+ unsigned gvg_dungeon : 1; // Celest
+ unsigned gvg_noparty : 1;
+ unsigned nozenypenalty : 1;
+ unsigned notrade : 1;
+ unsigned noskill : 1;
+ unsigned nowarp : 1;
+ unsigned nowarpto : 1;
+ unsigned noicewall : 1; // [Valaris]
+ unsigned snow : 1; // [Valaris]
+ unsigned clouds : 1;
+ unsigned clouds2 : 1; // [Valaris]
+ unsigned fog : 1; // [Valaris]
+ unsigned fireworks : 1;
+ unsigned sakura : 1; // [Valaris]
+ unsigned leaves : 1; // [Valaris]
+ unsigned rain : 1; // [Valaris]
+ unsigned indoors : 1; // celest
+ unsigned nogo : 1; // [Valaris]
+ unsigned nobaseexp : 1; // [Lorky] added by Lupus
+ unsigned nojobexp : 1; // [Lorky]
+ unsigned nomobloot : 1; // [Lorky]
+ unsigned nomvploot : 1; // [Lorky]
+ unsigned nightenabled :1; //For night display. [Skotlex]
+ unsigned restricted : 1; // [Komurka]
+ unsigned nodrop : 1;
+ unsigned novending : 1;
+ unsigned loadevent : 1;
+ unsigned nochat :1;
+ unsigned partylock :1;
+ unsigned guildlock :1;
+ } flag;
+ struct point save;
+ struct npc_data *npc[MAX_NPC_PER_MAP];
+ struct {
+ int drop_id;
+ int drop_type;
+ int drop_per;
+ } drop_list[MAX_DROP_PER_MAP];
+
+ struct spawn_data *moblist[MAX_MOB_LIST_PER_MAP]; // [Wizputer]
+ int mob_delete_timer; // [Skotlex]
+ int zone; // zone number (for item/skill restrictions)
+ int jexp; // map experience multiplicator
+ int bexp; // map experience multiplicator
+ int nocommand; //Blocks @/# commands for non-gms. [Skotlex]
+};
+
+/// Stores information about a remote map (for multi-mapserver setups).
+/// Beginning of data structure matches 'map_data', to allow typecasting.
+struct map_data_other_server {
+ char name[MAP_NAME_LENGTH];
+ unsigned short index; //Index is the map index used by the mapindex* functions.
+ struct mapcell* cell; // If this is NULL, the map is not on this map-server
+ uint32 ip;
+ uint16 port;
+};
+
extern struct map_data map[];
extern int map_num;
extern int autosave_interval;
diff --git a/src/map/npc.c b/src/map/npc.c
index ca4201428..6514fbb6a 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -2555,9 +2555,9 @@ static const char* npc_parse_mapcell(char* w1, char* w2, char* w3, char* w4, con
swap(y0, y1);
for( x = x0; x <= x1; ++x )
- for( y = y0; y <= y1; ++y ) {
- int type = map_getcell(m, x, y, CELL_GETTYPE);
- if (type == 1 || type == 5) //TODO: use defines for the cell types.
+ for( y = y0; y <= y1; ++y )
+ {
+ if( map_getcell(m, x, y, CELL_CHKWALL) || map_getcell(m, x, y, CELL_CHKCLIFF) )
continue;
map_setcell(m, x, y, cell);
}
diff --git a/src/map/path.c b/src/map/path.c
index 440316131..d58adddd0 100644
--- a/src/map/path.c
+++ b/src/map/path.c
@@ -153,7 +153,7 @@ int path_blownpos(int m,int x0,int y0,int dx,int dy,int count)
{
struct map_data *md;
- if( !map[m].gat )
+ if( !map[m].cell )
return -1;
md = &map[m];
@@ -208,7 +208,7 @@ bool path_search_long(struct shootpath_data *spd,int m,int x0,int y0,int x1,int
if( spd == NULL )
spd = &s_spd; // use dummy output variable
- if (!map[m].gat)
+ if (!map[m].cell)
return false;
md = &map[m];
@@ -282,7 +282,7 @@ bool path_search(struct walkpath_data *wpd,int m,int x0,int y0,int x1,int y1,int
if( wpd == NULL )
wpd = &s_wpd; // use dummy output variable
- if( !map[m].gat )
+ if( !map[m].cell )
return false;
md = &map[m];
diff --git a/src/map/skill.c b/src/map/skill.c
index 31b919fd4..9a7fbada7 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -6408,8 +6408,7 @@ struct skill_unit_group* skill_unitsetting (struct block_list *src, short skilli
alive = 0; //no path between cell and center of casting.
if(alive && skillid == WZ_ICEWALL) {
- int celltype = map_getcell(src->m,ux,uy,CELL_GETTYPE);
- if(celltype==5 || celltype==1)
+ if( map_getcell(src->m,ux,uy,CELL_CHKWALL) || map_getcell(src->m,ux,uy,CELL_CHKCLIFF) )
alive=0;
else
{