diff options
author | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2008-01-03 21:36:40 +0000 |
---|---|---|
committer | ultramage <ultramage@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2008-01-03 21:36:40 +0000 |
commit | 1b241817a93f892a24379866a06e046e7e6c5e86 (patch) | |
tree | 72e6e27d29b8eca173b32b64d3b31592de7208c6 | |
parent | 50418d820226fbcdf7609fb619028e3b75a2fa9e (diff) | |
download | hercules-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.txt | 10 | ||||
-rw-r--r-- | src/map/map.c | 248 | ||||
-rw-r--r-- | src/map/map.h | 205 | ||||
-rw-r--r-- | src/map/npc.c | 6 | ||||
-rw-r--r-- | src/map/path.c | 6 | ||||
-rw-r--r-- | src/map/skill.c | 3 |
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 { |