I'm still here!
Rewrote fame ranking lists- changed MAP_NAME_LENGTH to 12, now there's MAP_NAME_LENGTH_EXT at 16 for uses where there is / may be the .gat extension, code adjusted accordingly - moved map_normalize_name to mapindex_normalize_name so that everything handling map names uses the same extension-removing function - greatly enhanced the map cache generator, complete documentation on the tool and the map cache format can be found in doc/ - the map cache format changed a bit as a consequence, but of course a new valid one is included (contains latest Nameless Island maps) - fixed a duplicate entry in map index git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@10167 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
a881931cb6
commit
7c8f12ccd5
@ -5,6 +5,17 @@ IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
|
||||
|
||||
|
||||
2007/04/07
|
||||
* Final touches to the whole map crap [DracoRPG]
|
||||
- changed MAP_NAME_LENGTH to 12, now there's MAP_NAME_LENGTH_EXT at 16 for
|
||||
uses where there is / may be the .gat extension, code adjusted accordingly
|
||||
- moved map_normalize_name to mapindex_normalize_name so that everything
|
||||
handling map names uses the same extension-removing function
|
||||
- greatly enhanced the map cache generator, complete documentation on the
|
||||
tool and the map cache format can be found in doc/
|
||||
- the map cache format changed a bit as a consequence, but of course a new
|
||||
valid one is included (contains latest Nameless Island maps)
|
||||
- and I'm sorry for the number of times I've moved around and renamed files,
|
||||
now the final structure should have been reached
|
||||
* Capped clif_heal's heal field (the argument received is int, but the
|
||||
packet field is short, meaning that if the heal is high enough, the client
|
||||
would receive a negative heal amount). [Skotlex]
|
||||
|
@ -744,7 +744,6 @@ map: ice_dun04
|
||||
|
||||
// --- Veins & Thor Dungeon ---
|
||||
// -- 2006-12-19sdata_k.gpf --
|
||||
|
||||
map: que_thor
|
||||
map: thor_camp
|
||||
map: thor_v01
|
||||
@ -760,6 +759,17 @@ map: ve_fild05
|
||||
map: ve_fild06
|
||||
map: ve_fild07
|
||||
|
||||
// --- Unknown Island & Abbey Dungeon ---
|
||||
// -- 2007-04-02sdata_k.gpf
|
||||
map: nameless_i
|
||||
map: nameless_n
|
||||
map: nameless_in
|
||||
map: abbey01
|
||||
map: abbey02
|
||||
map: abbey03
|
||||
map: poring_w01
|
||||
map: poring_w02
|
||||
|
||||
//------------------------- Clone Maps ---------------------------
|
||||
//------------------------- Extra Maps ---------------------------
|
||||
|
||||
|
@ -21,6 +21,8 @@
|
||||
========================
|
||||
|
||||
04/07
|
||||
* Updated map index and map cache with Nameless Island maps [DracoRPG]
|
||||
- also removed the duplicate g_room2 entry from map index, read the note
|
||||
* Corrected Aliza card's item_db line. [Skotlex]
|
||||
04/05
|
||||
* Fixed some items that should heal percentual hp/sp [Playtester]
|
||||
|
@ -1,15 +0,0 @@
|
||||
//-----------------------------------------
|
||||
// GRF List
|
||||
//-----------------------------------------
|
||||
|
||||
grf: C:\Program Files\Gravity\RO\data.grf
|
||||
grf: C:\Program Files\Gravity\RO\sdata.grf
|
||||
|
||||
// You may add more in this format
|
||||
// grf: <data file path>
|
||||
|
||||
//------ Others ---------------------------
|
||||
|
||||
//Path to directory that contains the data dir
|
||||
//NOTE: Path must include trailing backslash, only one data_dir entry is supported.
|
||||
//data_dir: C:\Program Files\Gravity\RO\
|
BIN
db/map_cache.dat
BIN
db/map_cache.dat
Binary file not shown.
@ -9,6 +9,11 @@
|
||||
//mapname <- map will use index of previous map +1
|
||||
//Note that map index 0 is special and reserved for "error" status.
|
||||
|
||||
// NOTE TO DEVELOPERS
|
||||
// Due to a removed duplicate, index 591 is free, if you have to add a single map,
|
||||
// please add it there instead of the end. Then remove the 592 on next line (rachel)
|
||||
// and remove all those comments. ~DracoRPG
|
||||
|
||||
alb_ship 1
|
||||
alb2trea
|
||||
alberta
|
||||
@ -599,8 +604,8 @@ job_hunter
|
||||
job_knight
|
||||
job_priest
|
||||
job_wizard
|
||||
g_room2
|
||||
rachel
|
||||
// INDEX 591 IS FREE, PLEASE USE IT
|
||||
rachel 592
|
||||
ra_in01
|
||||
ra_fild01
|
||||
ra_fild02
|
||||
@ -645,6 +650,14 @@ ve_fild07
|
||||
poring_c01
|
||||
poring_c02
|
||||
que_ng
|
||||
nameless_i
|
||||
nameless_n
|
||||
nameless_in
|
||||
abbey01
|
||||
abbey02
|
||||
abbey03
|
||||
poring_w01
|
||||
poring_w02
|
||||
|
||||
|
||||
// Only add maps under this line if they are not standard maps!
|
@ -1,18 +1,67 @@
|
||||
"How to use the mapcache builder"
|
||||
DracoRPG
|
||||
//===== Athena Doc ========================================
|
||||
//= Map Cache Builder and Format Documentation
|
||||
//===== By ================================================
|
||||
//= DracoRPG
|
||||
//===== Version ===========================================
|
||||
//= 1.0
|
||||
//=========================================================
|
||||
//= 0.1 - Short howto for the initial builder version
|
||||
//= 1.0 - Complete manual covering the improved version
|
||||
//===== Description =======================================
|
||||
//= A complete manual for eAthena's map cache generator
|
||||
//= as well as a reference on the map cache format used
|
||||
//=========================================================
|
||||
|
||||
Preface:
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Since SVN revision ~10000, the map-server does not know how to read RO client files anymore. It reads maps from a
|
||||
"map cache" file that contains all and only the useful data about the maps. A map cache containing every official
|
||||
kRO Sakray map currently supported by eAthena is provided as a default.
|
||||
If you have custom maps or want to minimize the size of your map cache because your server does not load all of them
|
||||
(multi-map-server or light test server), you can use the map cache builder to generate a new one fitting your needs.
|
||||
|
||||
Map cache builder manual:
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
The source code for the map cache builder is located in src/tool/. It can be built using "make tools" if you use the Makefile
|
||||
or using the "mapcache" project under Visual Studio. Named "mapcache", the executable will be in your eAthena main folder.
|
||||
The map cache builder needs 3 file paths : one is a list of GRFs and/or data directory containing the maps, the second
|
||||
is the list of maps to add to the map cache, and the last one is the path of the map cache to generate. Default values for
|
||||
those paths are "tools/mapcache/grf_files.txt", "db/map_index.txt" and "db/map_cache.dat".
|
||||
The list of GRF and/or data directory must follow the format and indication of the default file: as many "grf:" entries as
|
||||
you wish and optionally one only "data_dir:" entry with trailing backslash included. // comments are supported as usual.
|
||||
In fact, any file with one map name per line can be used as a map list, that's why the map index list is used as a default:
|
||||
we are sure it contains every map supported by the server. Anything after the map name is ignored, // comments are supported
|
||||
and if the first word on the line is "map:" then the second word is used as the map name instead: that allows using
|
||||
maps_athena.conf as your map list, which is handy if you want to generate a minimal map cache for each of your multiple
|
||||
map-servers.
|
||||
The map cache file path can point to an already existing file, as the builder adds a map only if it's not already cached.
|
||||
This way, you can add custom maps to the base map cache without even needing kRO Sakray maps. If you wish to rebuild the
|
||||
entire map cache, though, you can either provide a path to a non-existing file, or force the rebuild mode.
|
||||
|
||||
Here are the command-line arguments you can provide to the map cache builder to customize its behavior:
|
||||
-grf path/to/grf/list
|
||||
Allows to specify the file containing the list of GRFs and/or data directory
|
||||
-list path/to/map/list
|
||||
Allows to specify the file containing the list of maps to add to the map cache
|
||||
-cache path/to/map/cache
|
||||
Allows to specify the path to the generated map cache
|
||||
- rebuild
|
||||
Allows to force the rebuild mode (map cache will be overwritten even if it already exists)
|
||||
|
||||
|
||||
This is only useful if you have custom maps, as eAthena is provided with an updated mapcache containing every map
|
||||
from kRO Sakray's data.
|
||||
Map cache format reference:
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
1. First add the path to the directory / GRF containing your maps to db/grf_files.txt
|
||||
/!\ Please note you must also have the official maps as the whole mapcache will be rebuilt from scratch
|
||||
|
||||
2. Then add those custom maps at the end of db/map_list.txt, carefully chosing their index
|
||||
|
||||
3. Now just run the mapcache builder and it'll build a new one at db/map_cache.dat
|
||||
|
||||
|
||||
NOTE:
|
||||
You can override those default paths by providing your own ones as command-line arguments to the mapcache builder:
|
||||
$> mapcache [grf_files_path [map_list_path [map_cache_path]]]
|
||||
The file is written as little-endian, even on big-endian systems, for cross-compatibility reasons. Appropriate conversions
|
||||
are done when generating it, so don't worry about it.
|
||||
The first 6 bytes are a main header:
|
||||
<unsigned long> file size
|
||||
<unsigned short> number of maps
|
||||
Then maps are stored one right after another:
|
||||
<12-characters-long string> map name
|
||||
<short> X size
|
||||
<short> Y size
|
||||
<long> compressed cell data length
|
||||
<variable> compressed cell data
|
||||
|
@ -1605,10 +1605,6 @@ void create_online_files(void) {
|
||||
if (online_display_option & 24) { // 8 or 16
|
||||
// prepare map name
|
||||
memcpy(temp, mapindex_id2name(char_dat[j].status.last_point.map), MAP_NAME_LENGTH);
|
||||
temp[MAP_NAME_LENGTH] = '\0';
|
||||
if (strstr(temp, ".gat") != NULL) {
|
||||
temp[strstr(temp, ".gat") - temp] = 0; // suppress the '.gat'
|
||||
}
|
||||
// write map name
|
||||
if (online_display_option & 16) { // map-name AND coordinates
|
||||
fprintf(fp2, " <td>%s (%d, %d)</td>\n", temp, char_dat[j].status.last_point.x, char_dat[j].status.last_point.y);
|
||||
@ -3532,13 +3528,13 @@ int parse_char(int fd)
|
||||
{
|
||||
//Send player to map
|
||||
uint32 subnet_map_ip;
|
||||
char map_name[MAP_NAME_LENGTH];
|
||||
snprintf(map_name, MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(cd->last_point.map));
|
||||
char map_name[MAP_NAME_LENGTH_EXT];
|
||||
snprintf(map_name, MAP_NAME_LENGTH_EXT, "%s.gat", mapindex_id2name(cd->last_point.map));
|
||||
|
||||
WFIFOHEAD(fd,28);
|
||||
WFIFOW(fd,0) = 0x71;
|
||||
WFIFOL(fd,2) = cd->char_id;
|
||||
memcpy(WFIFOP(fd,6), map_name, MAP_NAME_LENGTH);
|
||||
memcpy(WFIFOP(fd,6), map_name, MAP_NAME_LENGTH_EXT);
|
||||
|
||||
// Advanced subnet check [LuzZza]
|
||||
subnet_map_ip = lan_subnetcheck(ipl);
|
||||
|
@ -3340,13 +3340,12 @@ int parse_char(int fd)
|
||||
{
|
||||
//Send player to map.
|
||||
uint32 subnet_map_ip;
|
||||
char map_name[MAP_NAME_LENGTH];
|
||||
snprintf(map_name, MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(char_dat.last_point.map));
|
||||
|
||||
char map_name[MAP_NAME_LENGTH_EXT];
|
||||
snprintf(map_name, MAP_NAME_LENGTH_EXT, "%s.gat", mapindex_id2name(char_dat.last_point.map));
|
||||
WFIFOHEAD(fd,28);
|
||||
WFIFOW(fd,0) = 0x71;
|
||||
WFIFOL(fd,2) = char_dat.char_id;
|
||||
memcpy(WFIFOP(fd,6), map_name, MAP_NAME_LENGTH);
|
||||
memcpy(WFIFOP(fd,6), map_name, MAP_NAME_LENGTH_EXT);
|
||||
|
||||
// Advanced subnet check [LuzZza]
|
||||
subnet_map_ip = lan_subnetcheck(ipl);
|
||||
@ -4024,17 +4023,15 @@ int char_config_read(const char *cfgName) {
|
||||
} else if (strcmpi(w1, "save_log") == 0) {
|
||||
save_log = config_switch(w2);
|
||||
} else if (strcmpi(w1, "start_point") == 0) {
|
||||
char map[MAP_NAME_LENGTH];
|
||||
char map[MAP_NAME_LENGTH_EXT];
|
||||
int x, y;
|
||||
if (sscanf(w2, "%16[^,],%d,%d", map, &x, &y) < 3)
|
||||
continue;
|
||||
if (strstr(map, ".gat") != NULL) { // Verify at least if '.gat' is in the map name
|
||||
start_point.map = mapindex_name2id(map);
|
||||
if (!start_point.map)
|
||||
ShowError("Specified start_point %s not found in map-index cache.\n", map);
|
||||
start_point.x = x;
|
||||
start_point.y = y;
|
||||
}
|
||||
start_point.map = mapindex_name2id(map);
|
||||
if (!start_point.map)
|
||||
ShowError("Specified start_point %s not found in map-index cache.\n", map);
|
||||
start_point.x = x;
|
||||
start_point.y = y;
|
||||
} else if (strcmpi(w1, "start_zeny") == 0) {
|
||||
start_zeny = atoi(w2);
|
||||
if (start_zeny < 0)
|
||||
|
@ -15,42 +15,53 @@
|
||||
//Leave an extra char of space to hold the terminator, in case for the strncpy(mapindex_id2name()) calls.
|
||||
struct indexes {
|
||||
char name[MAP_NAME_LENGTH+1]; //Stores map name
|
||||
int length; //Stores string length WITHOUT the extension for quick lookup.
|
||||
char exists; //Set to 1 if index exists
|
||||
} indexes[MAX_MAPINDEX];
|
||||
|
||||
static unsigned short max_index = 0;
|
||||
|
||||
char mapindex_cfgfile[80] = "db/map_list.txt";
|
||||
char mapindex_cfgfile[80] = "db/map_index.txt";
|
||||
|
||||
// Removes the extension from a map name
|
||||
char *mapindex_normalize_name(char *mapname)
|
||||
{
|
||||
char *ptr, *ptr2;
|
||||
ptr = strchr(mapname, '.');
|
||||
if (ptr) { //Check and remove extension.
|
||||
while (ptr[1] && (ptr2 = strchr(ptr+1, '.')))
|
||||
ptr = ptr2; //Skip to the last dot.
|
||||
if(stricmp(ptr,".gat") == 0 ||
|
||||
stricmp(ptr,".afm") == 0 ||
|
||||
stricmp(ptr,".af2") == 0)
|
||||
*ptr = '\0'; //Remove extension.
|
||||
}
|
||||
return mapname;
|
||||
}
|
||||
|
||||
/// Adds a map to the specified index
|
||||
/// Returns 1 if successful, 0 oherwise
|
||||
int mapindex_addmap(int index, const char *name)
|
||||
{
|
||||
char map_name[1024];
|
||||
char *ext;
|
||||
int length;
|
||||
|
||||
if (index < 0 || index >= MAX_MAPINDEX) {
|
||||
ShowError("(mapindex_add) Map index (%d) for \"%s\" out of range (max is %d)\n", index, name, MAX_MAPINDEX);
|
||||
return 0;
|
||||
}
|
||||
|
||||
snprintf(map_name, 1024, "%s", name);
|
||||
map_name[1023] = 0;
|
||||
length = strlen(map_name);
|
||||
if (length > MAP_NAME_LENGTH) {
|
||||
mapindex_normalize_name(map_name);
|
||||
|
||||
if (strlen(map_name) > MAP_NAME_LENGTH-1) {
|
||||
ShowError("(mapindex_add) Map name %s is too long. Maps are limited to %d characters.\n", map_name, MAP_NAME_LENGTH);
|
||||
return 0;
|
||||
}
|
||||
if ((ext = strstr(map_name, ".")) != NULL) { // Remove extension
|
||||
length = ext-map_name;
|
||||
*ext = '\0';
|
||||
}
|
||||
|
||||
if (indexes[index].length)
|
||||
if (indexes[index].exists)
|
||||
ShowWarning("(mapindex_add) Overriding index %d: map \"%s\" -> \"%s\"\n", index, indexes[index].name, map_name);
|
||||
|
||||
strncpy(indexes[index].name, map_name, MAP_NAME_LENGTH);
|
||||
indexes[index].length = length;
|
||||
indexes[index].exists = 1;
|
||||
if (max_index <= index)
|
||||
max_index = index+1;
|
||||
return 1;
|
||||
@ -59,17 +70,18 @@ int mapindex_addmap(int index, const char *name)
|
||||
unsigned short mapindex_name2id(const char* name) {
|
||||
//TODO: Perhaps use a db to speed this up? [Skotlex]
|
||||
int i;
|
||||
int length = strlen(name);
|
||||
char *ext = strstr(name, ".");
|
||||
if (ext)
|
||||
length = ext-name; //Base map-name length without the extension.
|
||||
char map_name[1024];
|
||||
|
||||
snprintf(map_name, 1024, "%s", name);
|
||||
mapindex_normalize_name(map_name);
|
||||
|
||||
for (i = 1; i < max_index; i++)
|
||||
{
|
||||
if (strncmp(indexes[i].name,name,length)==0)
|
||||
if (strcmp(indexes[i].name,map_name)==0)
|
||||
return i;
|
||||
}
|
||||
#ifdef MAPINDEX_AUTOADD
|
||||
if( mapindex_addmap(i,name) )
|
||||
if( mapindex_addmap(i,map_name) )
|
||||
{
|
||||
ShowDebug("mapindex_name2id: Auto-added map \"%s\" to position %d\n", indexes[i], i);
|
||||
return i;
|
||||
@ -83,7 +95,7 @@ unsigned short mapindex_name2id(const char* name) {
|
||||
}
|
||||
|
||||
const char* mapindex_id2name(unsigned short id) {
|
||||
if (id > MAX_MAPINDEX || !indexes[id].length) {
|
||||
if (id > MAX_MAPINDEX || !indexes[id].exists) {
|
||||
ShowDebug("mapindex_id2name: Requested name for non-existant map index [%d] in cache.\n", id);
|
||||
return indexes[0].name; //Theorically this should never happen, hence we return this string to prevent null pointer crashes.
|
||||
}
|
||||
|
@ -37,6 +37,7 @@ extern char mapindex_cfgfile[80];
|
||||
#define MAP_VEINS "veins"
|
||||
#define MAP_JAIL "sec_pri"
|
||||
#define MAP_NOVICE "new_zone01"
|
||||
char *mapindex_normalize_name(char *mapname);
|
||||
int mapindex_addmap(int index, const char *name);
|
||||
unsigned short mapindex_name2id(const char*);
|
||||
const char* mapindex_id2name(unsigned short);
|
||||
|
@ -77,8 +77,9 @@
|
||||
#define NAME_LENGTH 24
|
||||
//For item names, which tend to have much longer names.
|
||||
#define ITEM_NAME_LENGTH 50
|
||||
//For Map Names, which the client considers to be 16 in length
|
||||
#define MAP_NAME_LENGTH 16
|
||||
//For Map Names, which the client considers to be 16 in length including the .gat extension
|
||||
#define MAP_NAME_LENGTH 12
|
||||
#define MAP_NAME_LENGTH_EXT 16
|
||||
|
||||
#define MAX_FRIENDS 40
|
||||
#define MAX_MEMOPOINTS 10
|
||||
|
@ -1310,7 +1310,7 @@ int atcommand_send(const int fd, struct map_session_data* sd, const char* comman
|
||||
*/
|
||||
int atcommand_rura( const int fd, struct map_session_data* sd, const char* command, const char* message)
|
||||
{
|
||||
char map_name[MAP_NAME_LENGTH];
|
||||
char map_name[MAP_NAME_LENGTH_EXT];
|
||||
unsigned short mapindex;
|
||||
int x = 0, y = 0;
|
||||
int m = -1;
|
||||
@ -1698,7 +1698,7 @@ int atcommand_whomap3(const int fd, struct map_session_data* sd, const char* com
|
||||
int i, count, users;
|
||||
int pl_GM_level, GM_level;
|
||||
int map_id;
|
||||
char map_name[MAP_NAME_LENGTH];
|
||||
char map_name[MAP_NAME_LENGTH_EXT];
|
||||
|
||||
memset(atcmd_output, '\0', sizeof(atcmd_output));
|
||||
memset(map_name, '\0', sizeof(map_name));
|
||||
@ -1752,7 +1752,7 @@ int atcommand_whomap2(const int fd, struct map_session_data* sd, const char* com
|
||||
int i, count, users;
|
||||
int pl_GM_level, GM_level;
|
||||
int map_id = 0;
|
||||
char map_name[MAP_NAME_LENGTH];
|
||||
char map_name[MAP_NAME_LENGTH_EXT];
|
||||
|
||||
nullpo_retr(-1, sd);
|
||||
|
||||
@ -1810,7 +1810,7 @@ int atcommand_whomap(const int fd, struct map_session_data* sd, const char* comm
|
||||
int i, count, users;
|
||||
int pl_GM_level, GM_level;
|
||||
int map_id = 0;
|
||||
char map_name[MAP_NAME_LENGTH];
|
||||
char map_name[MAP_NAME_LENGTH_EXT];
|
||||
struct guild *g;
|
||||
struct party_data *p;
|
||||
|
||||
@ -3190,10 +3190,10 @@ int atcommand_go(const int fd, struct map_session_data* sd, const char* command,
|
||||
{
|
||||
int i;
|
||||
int town;
|
||||
char map_name[MAP_NAME_LENGTH];
|
||||
char map_name[MAP_NAME_LENGTH_EXT];
|
||||
int m;
|
||||
|
||||
const struct { char map[MAP_NAME_LENGTH]; int x, y; } data[] = {
|
||||
const struct { char map[MAP_NAME_LENGTH_EXT]; int x, y; } data[] = {
|
||||
{ MAP_PRONTERA, 156, 191 }, // 0=Prontera
|
||||
{ MAP_MORROC, 156, 93 }, // 1=Morroc
|
||||
{ MAP_GEFFEN, 119, 59 }, // 2=Geffen
|
||||
@ -3250,7 +3250,7 @@ int atcommand_go(const int fd, struct map_session_data* sd, const char* command,
|
||||
return -1;
|
||||
} else {
|
||||
// get possible name of the city
|
||||
map_name[MAP_NAME_LENGTH-1] = '\0';
|
||||
map_name[MAP_NAME_LENGTH_EXT-1] = '\0';
|
||||
for (i = 0; map_name[i]; i++)
|
||||
map_name[i] = TOLOWER(map_name[i]);
|
||||
// try to see if it's a name, and not a number (try a lot of possibilities, write errors and abbreviations too)
|
||||
@ -3636,7 +3636,7 @@ static int atkillmonster_sub(struct block_list *bl, va_list ap)
|
||||
void atcommand_killmonster_sub(const int fd, struct map_session_data* sd, const char* message, const int drop)
|
||||
{
|
||||
int map_id;
|
||||
char map_name[MAP_NAME_LENGTH];
|
||||
char map_name[MAP_NAME_LENGTH_EXT];
|
||||
|
||||
if (!sd) return;
|
||||
|
||||
@ -5432,8 +5432,8 @@ int atcommand_mapinfo(const int fd, struct map_session_data* sd, const char* com
|
||||
}
|
||||
|
||||
if (atcmd_player_name[0] == '\0') {
|
||||
memcpy(atcmd_player_name, mapindex_id2name(sd->mapindex), MAP_NAME_LENGTH);
|
||||
atcmd_player_name[MAP_NAME_LENGTH] = '\0';
|
||||
memcpy(atcmd_player_name, mapindex_id2name(sd->mapindex), MAP_NAME_LENGTH_EXT);
|
||||
atcmd_player_name[MAP_NAME_LENGTH_EXT] = '\0';
|
||||
m_id = map_mapindex2mapid(sd->mapindex);
|
||||
} else {
|
||||
m_id = map_mapname2mapid(atcmd_player_name);
|
||||
|
@ -617,7 +617,7 @@ int charcommand_save(
|
||||
const int fd, struct map_session_data* sd,
|
||||
const char* command, const char* message)
|
||||
{
|
||||
char map_name[MAP_NAME_LENGTH];
|
||||
char map_name[MAP_NAME_LENGTH_EXT];
|
||||
char character[NAME_LENGTH];
|
||||
struct map_session_data* pl_sd;
|
||||
int x = 0, y = 0;
|
||||
@ -1130,7 +1130,7 @@ int charcommand_warp(
|
||||
const int fd, struct map_session_data* sd,
|
||||
const char* command, const char* message)
|
||||
{
|
||||
char map_name[MAP_NAME_LENGTH];
|
||||
char map_name[MAP_NAME_LENGTH_EXT];
|
||||
char character[NAME_LENGTH];
|
||||
int x = 0, y = 0;
|
||||
struct map_session_data *pl_sd;
|
||||
|
@ -328,7 +328,7 @@ int chrif_changemapserver(struct map_session_data *sd, short map, int x, int y,
|
||||
int chrif_changemapserverack(int fd)
|
||||
{
|
||||
struct map_session_data *sd;
|
||||
char mapname[MAP_NAME_LENGTH+1];
|
||||
char mapname[MAP_NAME_LENGTH_EXT];
|
||||
RFIFOHEAD(fd);
|
||||
sd = map_id2sd(RFIFOL(fd,2));
|
||||
|
||||
|
@ -1208,12 +1208,16 @@ static void clif_spiritball_single(int fd, struct map_session_data *sd)
|
||||
*------------------------------------------
|
||||
*/
|
||||
static int clif_set0192(int fd, int m, int x, int y, int type) {
|
||||
char map_name[MAP_NAME_LENGTH_EXT];
|
||||
|
||||
sprintf(map_name, "%s.gat", map[m].name);
|
||||
|
||||
WFIFOHEAD(fd, packet_len(0x192));
|
||||
WFIFOW(fd,0) = 0x192;
|
||||
WFIFOW(fd,2) = x;
|
||||
WFIFOW(fd,4) = y;
|
||||
WFIFOW(fd,6) = type;
|
||||
memcpy(WFIFOP(fd,8),map[m].name,MAP_NAME_LENGTH);
|
||||
memcpy(WFIFOP(fd,8),map_name,MAP_NAME_LENGTH_EXT);
|
||||
WFIFOSET(fd,packet_len(0x192));
|
||||
|
||||
return 0;
|
||||
@ -1600,17 +1604,17 @@ void clif_setwaitclose(int fd) {
|
||||
*/
|
||||
int clif_changemap(struct map_session_data *sd, short map, int x, int y) {
|
||||
int fd;
|
||||
char map_name[MAP_NAME_LENGTH];
|
||||
|
||||
char map_name[MAP_NAME_LENGTH_EXT];
|
||||
|
||||
nullpo_retr(0, sd);
|
||||
|
||||
fd = sd->fd;
|
||||
|
||||
snprintf(map_name, MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(map));
|
||||
sprintf(map_name, "%s.gat", mapindex_id2name(map));
|
||||
|
||||
WFIFOHEAD(fd, packet_len(0x91));
|
||||
WFIFOW(fd,0) = 0x91;
|
||||
memcpy(WFIFOP(fd,2), map_name, MAP_NAME_LENGTH);
|
||||
memcpy(WFIFOP(fd,2), map_name, MAP_NAME_LENGTH_EXT);
|
||||
WFIFOW(fd,18) = x;
|
||||
WFIFOW(fd,20) = y;
|
||||
WFIFOSET(fd, packet_len(0x91));
|
||||
@ -1631,7 +1635,7 @@ int clif_changemapserver(struct map_session_data* sd, const char* mapname, int x
|
||||
WFIFOHEAD(fd, packet_len(0x92));
|
||||
WFIFOW(fd,0) = 0x92;
|
||||
//Better not trust the null-terminator is there. [Skotlex]
|
||||
memcpy(WFIFOP(fd,2), mapname, MAP_NAME_LENGTH);
|
||||
memcpy(WFIFOP(fd,2), mapname, MAP_NAME_LENGTH_EXT);
|
||||
WFIFOB(fd,17) = 0; //Null terminator for mapname
|
||||
WFIFOW(fd,18) = x;
|
||||
WFIFOW(fd,20) = y;
|
||||
@ -4661,10 +4665,10 @@ int clif_skill_warppoint(struct map_session_data *sd,int skill_num,int skill_lv,
|
||||
WFIFOHEAD(fd,packet_len(0x11c));
|
||||
WFIFOW(fd,0)=0x11c;
|
||||
WFIFOW(fd,2)=skill_num;
|
||||
strncpy((char*)WFIFOP(fd, 4),map1,MAP_NAME_LENGTH);
|
||||
strncpy((char*)WFIFOP(fd,20),map2,MAP_NAME_LENGTH);
|
||||
strncpy((char*)WFIFOP(fd,36),map3,MAP_NAME_LENGTH);
|
||||
strncpy((char*)WFIFOP(fd,52),map4,MAP_NAME_LENGTH);
|
||||
strncpy((char*)WFIFOP(fd, 4),map1,MAP_NAME_LENGTH_EXT);
|
||||
strncpy((char*)WFIFOP(fd,20),map2,MAP_NAME_LENGTH_EXT);
|
||||
strncpy((char*)WFIFOP(fd,36),map3,MAP_NAME_LENGTH_EXT);
|
||||
strncpy((char*)WFIFOP(fd,52),map4,MAP_NAME_LENGTH_EXT);
|
||||
WFIFOSET(fd,packet_len(0x11c));
|
||||
sd->menuskill_id = skill_num;
|
||||
if (skill_num == AL_WARP)
|
||||
@ -5660,7 +5664,7 @@ int clif_party_created(struct map_session_data *sd,int flag)
|
||||
int clif_party_member_info(struct party_data *p, struct map_session_data *sd)
|
||||
{
|
||||
unsigned char buf[96];
|
||||
char map_name[MAP_NAME_LENGTH];
|
||||
char map_name[MAP_NAME_LENGTH_EXT];
|
||||
|
||||
if (!sd) { //Pick any party member (this call is used when changing item share rules)
|
||||
int i;
|
||||
@ -5669,7 +5673,7 @@ int clif_party_member_info(struct party_data *p, struct map_session_data *sd)
|
||||
sd = p->data[i].sd;
|
||||
}
|
||||
|
||||
snprintf(map_name, MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(sd->mapindex));
|
||||
snprintf(map_name, MAP_NAME_LENGTH_EXT, "%s.gat", mapindex_id2name(sd->mapindex));
|
||||
|
||||
WBUFW(buf,0)=0x1e9;
|
||||
WBUFL(buf,2)= sd->status.account_id;
|
||||
@ -5679,7 +5683,7 @@ int clif_party_member_info(struct party_data *p, struct map_session_data *sd)
|
||||
WBUFB(buf,14)=0; //Unconfirmed byte, could be online/offline.
|
||||
memcpy(WBUFP(buf,15), p->party.name, NAME_LENGTH);
|
||||
memcpy(WBUFP(buf,39), sd->status.name, NAME_LENGTH);
|
||||
memcpy(WBUFP(buf,63), map_name, MAP_NAME_LENGTH);
|
||||
memcpy(WBUFP(buf,63), map_name, MAP_NAME_LENGTH_EXT);
|
||||
WBUFB(buf,79) = (p->party.item&1)?1:0;
|
||||
WBUFB(buf,80) = (p->party.item&2)?1:0;
|
||||
clif_send(buf,packet_len(0x1e9),&sd->bl,PARTY);
|
||||
@ -5693,7 +5697,7 @@ int clif_party_member_info(struct party_data *p, struct map_session_data *sd)
|
||||
*------------------------------------------*/
|
||||
int clif_party_info(struct party_data* p, struct map_session_data *sd)
|
||||
{
|
||||
unsigned char buf[2+2+NAME_LENGTH+(4+NAME_LENGTH+MAP_NAME_LENGTH+1+1)*MAX_PARTY];
|
||||
unsigned char buf[2+2+NAME_LENGTH+(4+NAME_LENGTH+MAP_NAME_LENGTH_EXT+1+1)*MAX_PARTY];
|
||||
struct map_session_data* party_sd = NULL;
|
||||
int i, c;
|
||||
|
||||
@ -5704,17 +5708,17 @@ int clif_party_info(struct party_data* p, struct map_session_data *sd)
|
||||
for(i = 0, c = 0; i < MAX_PARTY; i++)
|
||||
{
|
||||
struct party_member* m = &p->party.member[i];
|
||||
char map_name[MAP_NAME_LENGTH];
|
||||
char map_name[MAP_NAME_LENGTH_EXT];
|
||||
|
||||
if(!m->account_id) continue;
|
||||
|
||||
if(party_sd == NULL) party_sd = p->data[i].sd;
|
||||
|
||||
snprintf(map_name, MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(m->map));
|
||||
snprintf(map_name, MAP_NAME_LENGTH_EXT, "%s.gat", mapindex_id2name(m->map));
|
||||
|
||||
WBUFL(buf,28+c*46) = m->account_id;
|
||||
memcpy(WBUFP(buf,28+c*46+4), m->name, NAME_LENGTH);
|
||||
memcpy(WBUFP(buf,28+c*46+28), map_name, MAP_NAME_LENGTH);
|
||||
memcpy(WBUFP(buf,28+c*46+28), map_name, MAP_NAME_LENGTH_EXT);
|
||||
WBUFB(buf,28+c*46+44) = (m->leader) ? 0 : 1;
|
||||
WBUFB(buf,28+c*46+45) = (m->online) ? 0 : 1;
|
||||
c++;
|
||||
@ -5993,12 +5997,12 @@ int clif_hpmeter(struct map_session_data *sd)
|
||||
int clif_party_move(struct party *p,struct map_session_data *sd,int online)
|
||||
{
|
||||
unsigned char buf[128];
|
||||
char map_name[MAP_NAME_LENGTH];
|
||||
char map_name[MAP_NAME_LENGTH_EXT];
|
||||
|
||||
nullpo_retr(0, sd);
|
||||
nullpo_retr(0, p);
|
||||
|
||||
snprintf(map_name, MAP_NAME_LENGTH, "%s.gat", map[sd->bl.m].name);
|
||||
snprintf(map_name, MAP_NAME_LENGTH_EXT, "%s.gat", map[sd->bl.m].name);
|
||||
|
||||
WBUFW(buf, 0)=0x104;
|
||||
WBUFL(buf, 2)=sd->status.account_id;
|
||||
@ -6008,7 +6012,7 @@ int clif_party_move(struct party *p,struct map_session_data *sd,int online)
|
||||
WBUFB(buf,14)=!online;
|
||||
memcpy(WBUFP(buf,15),p->name, NAME_LENGTH);
|
||||
memcpy(WBUFP(buf,39),sd->status.name, NAME_LENGTH);
|
||||
memcpy(WBUFP(buf,63),map_name, MAP_NAME_LENGTH);
|
||||
memcpy(WBUFP(buf,63),map_name, MAP_NAME_LENGTH_EXT);
|
||||
clif_send(buf,packet_len(0x104),&sd->bl,PARTY);
|
||||
return 0;
|
||||
}
|
||||
@ -6415,6 +6419,9 @@ int clif_changemapcell(int m,int x,int y,int cell_type,int type)
|
||||
{
|
||||
struct block_list bl;
|
||||
unsigned char buf[32];
|
||||
char map_name[MAP_NAME_LENGTH_EXT];
|
||||
|
||||
snprintf(map_name, MAP_NAME_LENGTH_EXT, "%s.gat", map[m].name);
|
||||
|
||||
bl.type = BL_NUL;
|
||||
bl.m = m;
|
||||
@ -6424,7 +6431,7 @@ int clif_changemapcell(int m,int x,int y,int cell_type,int type)
|
||||
WBUFW(buf,2) = x;
|
||||
WBUFW(buf,4) = y;
|
||||
WBUFW(buf,6) = cell_type;
|
||||
memcpy(WBUFP(buf,8),map[m].name,MAP_NAME_LENGTH);
|
||||
memcpy(WBUFP(buf,8),map_name,MAP_NAME_LENGTH_EXT);
|
||||
if(!type)
|
||||
clif_send(buf,packet_len(0x192),&bl,AREA);
|
||||
else
|
||||
@ -7850,13 +7857,13 @@ void clif_gospel_info(struct map_session_data *sd, int type)
|
||||
void clif_feel_info(struct map_session_data *sd, unsigned char feel_level, unsigned char type)
|
||||
{
|
||||
int fd=sd->fd;
|
||||
char map_name[MAP_NAME_LENGTH];
|
||||
char map_name[MAP_NAME_LENGTH_EXT];
|
||||
|
||||
snprintf(map_name, MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(sd->feel_map[feel_level].index));
|
||||
snprintf(map_name, MAP_NAME_LENGTH_EXT, "%s.gat", mapindex_id2name(sd->feel_map[feel_level].index));
|
||||
|
||||
WFIFOHEAD(fd,packet_len(0x20e));
|
||||
WFIFOW(fd,0)=0x20e;
|
||||
memcpy(WFIFOP(fd,2),map_name, MAP_NAME_LENGTH);
|
||||
memcpy(WFIFOP(fd,2),map_name, MAP_NAME_LENGTH_EXT);
|
||||
WFIFOL(fd,26)=sd->bl.id;
|
||||
WFIFOB(fd,30)=feel_level;
|
||||
WFIFOB(fd,31)=type?1:0;
|
||||
@ -8636,8 +8643,8 @@ int clif_message(struct block_list *bl, const char* msg)
|
||||
*/
|
||||
void clif_parse_MapMove(int fd, struct map_session_data *sd) {
|
||||
// /m /mapmove (as @rura GM command)
|
||||
char output[MAP_NAME_LENGTH+15]; // Max length of a short: ' -6XXXX' -> 7 digits
|
||||
char message[MAP_NAME_LENGTH+15+5]; // "/mm "+output
|
||||
char output[MAP_NAME_LENGTH_EXT+15]; // Max length of a short: ' -6XXXX' -> 7 digits
|
||||
char message[MAP_NAME_LENGTH_EXT+15+5]; // "/mm "+output
|
||||
char *map_name;
|
||||
RFIFOHEAD(fd);
|
||||
|
||||
@ -8647,7 +8654,7 @@ void clif_parse_MapMove(int fd, struct map_session_data *sd) {
|
||||
return;
|
||||
|
||||
map_name = RFIFOP(fd,2);
|
||||
map_name[MAP_NAME_LENGTH-1]='\0';
|
||||
map_name[MAP_NAME_LENGTH_EXT-1]='\0';
|
||||
sprintf(output, "%s %d %d", map_name, RFIFOW(fd,18), RFIFOW(fd,20));
|
||||
atcommand_rura(fd, sd, "@rura", output);
|
||||
if(log_config.gm && get_atcommand_level(AtCommand_MapMove) >= log_config.gm)
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "../common/timer.h"
|
||||
#include "../common/nullpo.h"
|
||||
#include "../common/malloc.h"
|
||||
#include "../common/mapindex.h"
|
||||
#include "../common/showmsg.h"
|
||||
#include "../common/ers.h"
|
||||
|
||||
@ -183,7 +184,7 @@ static int guild_read_castledb(void)
|
||||
|
||||
gc=(struct guild_castle *)aCalloc(1,sizeof(struct guild_castle));
|
||||
gc->castle_id=atoi(str[0]);
|
||||
memcpy(gc->map_name,map_normalize_name(str[1]),MAP_NAME_LENGTH-1);
|
||||
memcpy(gc->map_name,mapindex_normalize_name(str[1]),MAP_NAME_LENGTH-1);
|
||||
memcpy(gc->castle_name,str[2],NAME_LENGTH-1);
|
||||
memcpy(gc->castle_event,str[3],NAME_LENGTH-1);
|
||||
|
||||
@ -254,7 +255,7 @@ struct guild_castle *guild_mapname2gc(char *mapname)
|
||||
int i;
|
||||
struct guild_castle *gc=NULL;
|
||||
|
||||
map_normalize_name(mapname);
|
||||
mapindex_normalize_name(mapname);
|
||||
|
||||
for(i=0;i<MAX_GUILDCASTLE;i++){
|
||||
gc=guild_castle_search(i);
|
||||
|
@ -145,6 +145,20 @@ struct charid2nick {
|
||||
int req_id;
|
||||
};
|
||||
|
||||
// This is the main header found at the very beginning of the map cache
|
||||
struct map_cache_main_header {
|
||||
unsigned long file_size;
|
||||
unsigned short map_count;
|
||||
};
|
||||
|
||||
// This is the header appended before every compressed map cells info in the map cache
|
||||
struct map_cache_map_info {
|
||||
char name[MAP_NAME_LENGTH];
|
||||
short xs;
|
||||
short ys;
|
||||
long len;
|
||||
};
|
||||
|
||||
char map_cache_file[256]="db/map_cache.dat";
|
||||
char db_path[256] = "db";
|
||||
char motd_txt[256] = "conf/motd.txt";
|
||||
@ -2410,61 +2424,34 @@ int map_eraseipport(unsigned short mapindex, uint32 ip, uint16 port)
|
||||
* Map cache reading
|
||||
*===========================================*/
|
||||
|
||||
// This is the header appended before every compressed map cells info
|
||||
struct map_cache_info {
|
||||
char name[MAP_NAME_LENGTH];
|
||||
unsigned short index;
|
||||
short xs;
|
||||
short ys;
|
||||
long len;
|
||||
};
|
||||
|
||||
FILE *map_cache_fp;
|
||||
|
||||
// Removes the extension from a map name
|
||||
char *map_normalize_name(char *mapname)
|
||||
{
|
||||
char *ptr, *ptr2;
|
||||
ptr = strchr(mapname, '.');
|
||||
if (ptr) { //Check and remove extension.
|
||||
while (ptr[1] && (ptr2 = strchr(ptr+1, '.')))
|
||||
ptr = ptr2; //Skip to the last dot.
|
||||
if(stricmp(ptr,".gat") == 0 ||
|
||||
stricmp(ptr,".afm") == 0 ||
|
||||
stricmp(ptr,".af2") == 0)
|
||||
*ptr = '\0'; //Remove extension.
|
||||
}
|
||||
return mapname;
|
||||
}
|
||||
|
||||
int map_readmap(struct map_data *m)
|
||||
int map_readfromcache(struct map_data *m, FILE *fp)
|
||||
{
|
||||
int i;
|
||||
unsigned short map_count;
|
||||
struct map_cache_info info;
|
||||
struct map_cache_main_header header;
|
||||
struct map_cache_map_info info;
|
||||
unsigned long size;
|
||||
unsigned char *buf;
|
||||
|
||||
if(!map_cache_fp)
|
||||
if(!fp)
|
||||
return 0;
|
||||
|
||||
fseek(map_cache_fp, 0, SEEK_SET);
|
||||
fread(&map_count, sizeof(map_count), 1, map_cache_fp);
|
||||
fseek(fp, 0, SEEK_SET);
|
||||
fread(&header, sizeof(struct map_cache_main_header), 1, fp);
|
||||
|
||||
for(i = 0; i < map_count; i++) {
|
||||
fread(&info, sizeof(info), 1, map_cache_fp);
|
||||
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, map_cache_fp);
|
||||
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(map_cache_fp, info.len, SEEK_CUR);
|
||||
fseek(fp, info.len, SEEK_CUR);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -2482,7 +2469,7 @@ int map_addmap(char *mapname) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
memcpy(map[map_num].name, map_normalize_name(mapname), MAP_NAME_LENGTH-1);
|
||||
memcpy(map[map_num].name, mapindex_normalize_name(mapname), MAP_NAME_LENGTH-1);
|
||||
map_num++;
|
||||
return 0;
|
||||
}
|
||||
@ -2520,8 +2507,9 @@ int map_readallmaps (void)
|
||||
{
|
||||
int i;
|
||||
int maps_removed = 0;
|
||||
FILE *fp;
|
||||
|
||||
if(!(map_cache_fp = fopen(map_cache_file, "rb")))
|
||||
if(!(fp = fopen(map_cache_file, "rb")))
|
||||
{
|
||||
ShowFatalError("Unable to open map cache file "CL_WHITE"%s"CL_RESET"\n", map_cache_file);
|
||||
exit(1); //No use launching server if maps can't be read.
|
||||
@ -2559,7 +2547,7 @@ int map_readallmaps (void)
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
if(!map_readmap(&map[i])) {
|
||||
if(!map_readfromcache(&map[i], fp)) {
|
||||
map_delmapid(i);
|
||||
maps_removed++;
|
||||
i--;
|
||||
@ -2609,6 +2597,8 @@ int map_readallmaps (void)
|
||||
map[i].block_mob_count = (int*)aCallocA(size, 1);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
// finished map loading
|
||||
printf("\r");
|
||||
ShowInfo("Successfully loaded '"CL_WHITE"%d"CL_RESET"' maps.%30s\n",map_num,"");
|
||||
|
@ -1030,7 +1030,7 @@ enum { ATK_LUCKY=1,ATK_FLEE,ATK_DEF}; //
|
||||
struct map_data {
|
||||
char name[MAP_NAME_LENGTH];
|
||||
unsigned short index; //Index is the map index used by the mapindex* functions.
|
||||
unsigned char *gat; // NULLなら下のmap_data_other_serverとして扱う
|
||||
unsigned char *gat; // If this is NULL‚ 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.
|
||||
@ -1350,7 +1350,6 @@ void map_foreachpc(int (*func)(DBKey,void*,va_list),...);
|
||||
int map_foreachiddb(int (*)(DBKey,void*,va_list),...);
|
||||
void map_addnickdb(struct map_session_data *);
|
||||
struct map_session_data * map_nick2sd(const char*);
|
||||
char *map_normalize_name(char *mapname);
|
||||
|
||||
// ‚»‚Ì‘¼
|
||||
int map_check_dir(int s_dir,int t_dir);
|
||||
|
@ -1659,7 +1659,7 @@ int npc_parse_warp (char *w1,char *w2,char *w3,char *w4)
|
||||
{
|
||||
int x, y, xs, ys, to_x, to_y, m;
|
||||
int i;
|
||||
char mapname[MAP_NAME_LENGTH], to_mapname[MAP_NAME_LENGTH];
|
||||
char mapname[MAP_NAME_LENGTH_EXT], to_mapname[MAP_NAME_LENGTH_EXT];
|
||||
struct npc_data *nd;
|
||||
|
||||
// 引数の個数チェック
|
||||
@ -1723,7 +1723,7 @@ static int npc_parse_shop (char *w1, char *w2, char *w3, char *w4)
|
||||
#define MAX_SHOPITEM 100
|
||||
char *p;
|
||||
int x, y, dir, m, pos = 0;
|
||||
char mapname[MAP_NAME_LENGTH];
|
||||
char mapname[MAP_NAME_LENGTH_EXT];
|
||||
struct npc_data *nd;
|
||||
|
||||
if (strcmp(w1, "-") == 0) {
|
||||
@ -1953,7 +1953,7 @@ static int npc_skip_script (char *w1,char *w2,char *w3,char *w4,char *first_line
|
||||
static int npc_parse_script(char *w1,char *w2,char *w3,char *w4,char *first_line,FILE *fp,int *lines,const char* file)
|
||||
{
|
||||
int x, y, dir = 0, m, xs = 0, ys = 0, class_ = 0; // [Valaris] thanks to fov
|
||||
char mapname[MAP_NAME_LENGTH];
|
||||
char mapname[MAP_NAME_LENGTH_EXT];
|
||||
unsigned char *srcbuf = NULL;
|
||||
struct script_code *script;
|
||||
int srcsize = 65536;
|
||||
@ -2380,7 +2380,7 @@ int npc_parse_mob2 (struct spawn_data *mob, int index)
|
||||
int npc_parse_mob (char *w1, char *w2, char *w3, char *w4)
|
||||
{
|
||||
int level, num, class_, mode, x,y,xs,ys;
|
||||
char mapname[MAP_NAME_LENGTH];
|
||||
char mapname[MAP_NAME_LENGTH_EXT];
|
||||
char mobname[NAME_LENGTH];
|
||||
struct spawn_data mob, *data;
|
||||
|
||||
@ -2515,7 +2515,7 @@ int npc_parse_mob (char *w1, char *w2, char *w3, char *w4)
|
||||
static int npc_parse_mapflag (char *w1, char *w2, char *w3, char *w4)
|
||||
{
|
||||
int m;
|
||||
char mapname[MAP_NAME_LENGTH];
|
||||
char mapname[MAP_NAME_LENGTH_EXT];
|
||||
int state = 1;
|
||||
|
||||
// 引数の個数チェック
|
||||
@ -2530,7 +2530,7 @@ static int npc_parse_mapflag (char *w1, char *w2, char *w3, char *w4)
|
||||
|
||||
//マップフラグ
|
||||
if (strcmpi(w3, "nosave") == 0) {
|
||||
char savemap[MAP_NAME_LENGTH];
|
||||
char savemap[MAP_NAME_LENGTH_EXT];
|
||||
int savex, savey;
|
||||
if (state == 0)
|
||||
; //Map flag disabled.
|
||||
@ -2764,7 +2764,7 @@ static int npc_parse_mapflag (char *w1, char *w2, char *w3, char *w4)
|
||||
static int npc_parse_mapcell (char *w1, char *w2, char *w3, char *w4)
|
||||
{
|
||||
int m, cell, x, y, x0, y0, x1, y1;
|
||||
char type[24], mapname[MAP_NAME_LENGTH];
|
||||
char type[24], mapname[MAP_NAME_LENGTH_EXT];
|
||||
|
||||
if (sscanf(w1, "%15[^,]", mapname) != 1)
|
||||
return 1;
|
||||
|
@ -9119,10 +9119,10 @@ BUILDIN_FUNC(flagemblem)
|
||||
|
||||
BUILDIN_FUNC(getcastlename)
|
||||
{
|
||||
char mapname[MAP_NAME_LENGTH];
|
||||
char mapname[MAP_NAME_LENGTH_EXT];
|
||||
struct guild_castle *gc;
|
||||
|
||||
strncpy(mapname, script_getstr(st,2), MAP_NAME_LENGTH);
|
||||
strncpy(mapname, script_getstr(st,2), MAP_NAME_LENGTH_EXT);
|
||||
gc = guild_mapname2gc(mapname);
|
||||
|
||||
if(gc)
|
||||
@ -9134,13 +9134,13 @@ BUILDIN_FUNC(getcastlename)
|
||||
|
||||
BUILDIN_FUNC(getcastledata)
|
||||
{
|
||||
char mapname[MAP_NAME_LENGTH];
|
||||
char mapname[MAP_NAME_LENGTH_EXT];
|
||||
int index=script_getnum(st,3);
|
||||
const char *event=NULL;
|
||||
struct guild_castle *gc;
|
||||
int i;
|
||||
|
||||
strncpy(mapname, script_getstr(st,2), MAP_NAME_LENGTH);
|
||||
strncpy(mapname, script_getstr(st,2), MAP_NAME_LENGTH_EXT);
|
||||
gc = guild_mapname2gc(mapname);
|
||||
|
||||
if(script_hasdata(st,4) && index==0 && gc) {
|
||||
@ -9202,12 +9202,12 @@ BUILDIN_FUNC(getcastledata)
|
||||
|
||||
BUILDIN_FUNC(setcastledata)
|
||||
{
|
||||
char mapname[MAP_NAME_LENGTH];
|
||||
char mapname[MAP_NAME_LENGTH_EXT];
|
||||
int index=script_getnum(st,3);
|
||||
int value=script_getnum(st,4);
|
||||
struct guild_castle *gc;
|
||||
|
||||
strncpy(mapname, script_getstr(st,2), MAP_NAME_LENGTH);
|
||||
strncpy(mapname, script_getstr(st,2), MAP_NAME_LENGTH_EXT);
|
||||
gc = guild_mapname2gc(mapname);
|
||||
|
||||
if(gc) {
|
||||
@ -11084,9 +11084,9 @@ BUILDIN_FUNC(getsavepoint)
|
||||
y=sd->status.save_point.y;
|
||||
switch(type){
|
||||
case 0:
|
||||
mapname=(char *) aMallocA((MAP_NAME_LENGTH+1)*sizeof(char));
|
||||
mapname=(char *) aMallocA((MAP_NAME_LENGTH)*sizeof(char));
|
||||
memcpy(mapname, mapindex_id2name(sd->status.save_point.map), MAP_NAME_LENGTH);
|
||||
mapname[MAP_NAME_LENGTH]='\0';
|
||||
mapname[MAP_NAME_LENGTH-1]='\0';
|
||||
script_pushstr(st,mapname);
|
||||
break;
|
||||
case 1:
|
||||
@ -11133,7 +11133,7 @@ BUILDIN_FUNC(getmapxy)
|
||||
char prefix;
|
||||
|
||||
int x,y,type;
|
||||
char mapname[MAP_NAME_LENGTH+1];
|
||||
char mapname[MAP_NAME_LENGTH];
|
||||
memset(mapname, 0, sizeof(mapname));
|
||||
|
||||
if( !data_isreference(script_getdata(st,2)) ){
|
||||
|
@ -4445,8 +4445,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
|
||||
} else {
|
||||
if (sd->skillitem != AL_TELEPORT)
|
||||
{
|
||||
char save_map[MAP_NAME_LENGTH];
|
||||
snprintf(save_map, MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(sd->status.save_point.map));
|
||||
char save_map[MAP_NAME_LENGTH_EXT];
|
||||
snprintf(save_map, MAP_NAME_LENGTH_EXT, "%s.gat", mapindex_id2name(sd->status.save_point.map));
|
||||
clif_skill_warppoint(sd,skillid,skilllv,"Random",save_map,"","");
|
||||
}
|
||||
else //Autocasted Teleport level 2??
|
||||
@ -6086,14 +6086,14 @@ int skill_castend_pos2 (struct block_list *src, int x, int y, int skillid, int s
|
||||
|
||||
case AL_WARP:
|
||||
if(sd) {
|
||||
char memo[4][MAP_NAME_LENGTH] = {"", "", "", ""};
|
||||
snprintf(memo[0], MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(sd->status.save_point.map));
|
||||
char memo[4][MAP_NAME_LENGTH_EXT] = {"", "", "", ""};
|
||||
snprintf(memo[0], MAP_NAME_LENGTH_EXT, "%s.gat", mapindex_id2name(sd->status.save_point.map));
|
||||
if (skilllv>1 && sd->status.memo_point[0].map)
|
||||
snprintf(memo[1], MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(sd->status.memo_point[0].map));
|
||||
snprintf(memo[1], MAP_NAME_LENGTH_EXT, "%s.gat", mapindex_id2name(sd->status.memo_point[0].map));
|
||||
if (skilllv>2 && sd->status.memo_point[1].map)
|
||||
snprintf(memo[2], MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(sd->status.memo_point[1].map));
|
||||
snprintf(memo[2], MAP_NAME_LENGTH_EXT, "%s.gat", mapindex_id2name(sd->status.memo_point[1].map));
|
||||
if (skilllv>3 && sd->status.memo_point[2].map)
|
||||
snprintf(memo[3], MAP_NAME_LENGTH, "%s.gat", mapindex_id2name(sd->status.memo_point[2].map));
|
||||
snprintf(memo[3], MAP_NAME_LENGTH_EXT, "%s.gat", mapindex_id2name(sd->status.memo_point[2].map));
|
||||
|
||||
clif_skill_warppoint(sd,skillid,skilllv,
|
||||
memo[0],memo[1],memo[2],memo[3]);
|
||||
|
@ -578,7 +578,6 @@ void* grfio_reads(char *fname, int *size)
|
||||
if (entry != NULL && entry->gentry < 0) {
|
||||
entry->gentry = -entry->gentry; // local file checked
|
||||
} else {
|
||||
printf("%s not found (grfio_reads - local file %s)\n", fname, lfname);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
@ -11,13 +12,19 @@
|
||||
|
||||
#include "grfio.h"
|
||||
|
||||
char grf_list_file[256] = "db/grf_files.txt";
|
||||
char map_list_file[256] = "db/map_list.txt";
|
||||
char map_cache_file[256] = "db/map_cache.dat";
|
||||
|
||||
#define MAP_NAME_LENGTH 16
|
||||
#define MAP_NAME_LENGTH 12
|
||||
#define MAP_NAME_LENGTH_EXT 16
|
||||
#define NO_WATER 1000000
|
||||
|
||||
char grf_list_file[256] = "tools/mapcache/grf_files.txt";
|
||||
char map_list_file[256] = "db/map_index.txt";
|
||||
char map_cache_file[256] = "db/map_cache.dat";
|
||||
int rebuild = 0;
|
||||
|
||||
FILE *map_cache_fp;
|
||||
|
||||
unsigned long file_size;
|
||||
|
||||
// Used internally, this structure contains the physical map cells
|
||||
struct map_data {
|
||||
short xs;
|
||||
@ -26,31 +33,25 @@ struct map_data {
|
||||
};
|
||||
|
||||
// This is the main header found at the very beginning of the file
|
||||
unsigned short map_count;
|
||||
struct main_header {
|
||||
unsigned long file_size;
|
||||
unsigned short map_count;
|
||||
} header;
|
||||
|
||||
// This is the header appended before every compressed map cells info
|
||||
struct map_cache_info {
|
||||
struct map_info {
|
||||
char name[MAP_NAME_LENGTH];
|
||||
unsigned short index;
|
||||
short xs;
|
||||
short ys;
|
||||
long len;
|
||||
};
|
||||
|
||||
FILE *map_cache_fp;
|
||||
|
||||
int filesize;
|
||||
/*************************************
|
||||
* Big-endian compatibility functions *
|
||||
*************************************/
|
||||
|
||||
/// Converts an unsigned short (16 bits) from current machine order to little-endian
|
||||
unsigned short MakeUShortLE(unsigned short val)
|
||||
{
|
||||
unsigned char buf[2];
|
||||
buf[0] = (unsigned char)( (val & 0x00FF) );
|
||||
buf[1] = (unsigned char)( (val & 0xFF00) >> 0x08 );
|
||||
return *((unsigned short*)buf);
|
||||
}
|
||||
|
||||
/// Converts a short (16 bits) from current machine order to little-endian
|
||||
// Converts a short (16 bits) from current machine order to little-endian
|
||||
short MakeShortLE(short val)
|
||||
{
|
||||
unsigned char buf[2];
|
||||
@ -59,7 +60,7 @@ short MakeShortLE(short val)
|
||||
return *((short*)buf);
|
||||
}
|
||||
|
||||
/// Converts a long (32 bits) from current machine order to little-endian
|
||||
// Converts a long (32 bits) from current machine order to little-endian
|
||||
long MakeLongLE(long val)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
@ -70,7 +71,23 @@ long MakeLongLE(long val)
|
||||
return *((long*)buf);
|
||||
}
|
||||
|
||||
/// Reads an unsigned long (32 bits) in little-endian from the buffer
|
||||
// Reads an unsigned short (16 bits) in little-endian from the buffer
|
||||
unsigned short GetUShort(const unsigned char *buf)
|
||||
{
|
||||
return ( ((unsigned short)(buf[0])) )
|
||||
|( ((unsigned short)(buf[1])) << 0x08 );
|
||||
}
|
||||
|
||||
// Reads a long (32 bits) in little-endian from the buffer
|
||||
long GetLong(const unsigned char *buf)
|
||||
{
|
||||
return ( ((long)(buf[0])) )
|
||||
|( ((long)(buf[1])) << 0x08 )
|
||||
|( ((long)(buf[2])) << 0x10 )
|
||||
|( ((long)(buf[3])) << 0x18 );
|
||||
}
|
||||
|
||||
// Reads an unsigned long (32 bits) in little-endian from the buffer
|
||||
unsigned long GetULong(const unsigned char *buf)
|
||||
{
|
||||
return ( ((unsigned long)(buf[0])) )
|
||||
@ -87,7 +104,7 @@ float GetFloat(const unsigned char *buf)
|
||||
}
|
||||
|
||||
|
||||
// Read map from GRF's GAT and RSW files
|
||||
// Reads a map from GRF's GAT and RSW files
|
||||
int read_map(char *name, struct map_data *m)
|
||||
{
|
||||
char filename[256];
|
||||
@ -143,31 +160,31 @@ int read_map(char *name, struct map_data *m)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void cache_map(char *name, unsigned short index, struct map_data *m)
|
||||
// Adds a map to the cache
|
||||
void cache_map(char *name, struct map_data *m)
|
||||
{
|
||||
struct map_cache_info info;
|
||||
unsigned long len;
|
||||
char *write_buf;
|
||||
struct map_info info;
|
||||
long len;
|
||||
unsigned char *write_buf;
|
||||
|
||||
// Create an output buffer twice as big as the uncompressed map... this way we're sure it fits
|
||||
len = m->xs*m->ys*2;
|
||||
write_buf = (char *)malloc(len);
|
||||
write_buf = (unsigned char *)malloc(len);
|
||||
// Compress the cells and get the compressed length
|
||||
encode_zip((unsigned char *)write_buf, &len, m->cells, m->xs*m->ys);
|
||||
encode_zip(write_buf, &len, m->cells, m->xs*m->ys);
|
||||
|
||||
// Fill the map header
|
||||
strncpy(info.name, name, MAP_NAME_LENGTH);
|
||||
info.index = MakeUShortLE(index);
|
||||
info.xs = MakeShortLE(m->xs);
|
||||
info.ys = MakeShortLE(m->ys);
|
||||
info.len = MakeLongLE((long)len);
|
||||
info.len = MakeLongLE(len);
|
||||
|
||||
// Append map header then compressed cells at the end of the file
|
||||
fseek(map_cache_fp, filesize, SEEK_SET);
|
||||
fwrite(&info, sizeof(struct map_cache_info), 1, map_cache_fp);
|
||||
fseek(map_cache_fp, header.file_size, SEEK_SET);
|
||||
fwrite(&info, sizeof(struct map_info), 1, map_cache_fp);
|
||||
fwrite(write_buf, 1, len, map_cache_fp);
|
||||
map_count++;
|
||||
filesize += sizeof(struct map_cache_info) + len;
|
||||
header.file_size += sizeof(struct map_info) + len;
|
||||
header.map_count++;
|
||||
|
||||
free(write_buf);
|
||||
free(m->cells);
|
||||
@ -175,41 +192,111 @@ void cache_map(char *name, unsigned short index, struct map_data *m)
|
||||
return;
|
||||
}
|
||||
|
||||
// Checks whether a map is already is the cache
|
||||
int find_map(char *name)
|
||||
{
|
||||
int i;
|
||||
struct map_info info;
|
||||
|
||||
fseek(map_cache_fp, sizeof(struct main_header), SEEK_SET);
|
||||
|
||||
for(i = 0; i < header.map_count; i++) {
|
||||
fread(&info, sizeof(info), 1, map_cache_fp);
|
||||
if(strcmp(name, info.name) == 0) // Map found
|
||||
return 1;
|
||||
else // Map not found, jump to the beginning of the next map info header
|
||||
fseek(map_cache_fp, GetLong((unsigned char *)&(info.len)), SEEK_CUR);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Cuts the extension from a map name
|
||||
char *remove_extension(char *mapname)
|
||||
{
|
||||
char *ptr, *ptr2;
|
||||
ptr = strchr(mapname, '.');
|
||||
if (ptr) { //Check and remove extension.
|
||||
while (ptr[1] && (ptr2 = strchr(ptr+1, '.')))
|
||||
ptr = ptr2; //Skip to the last dot.
|
||||
if(stricmp(ptr,".gat") == 0 ||
|
||||
stricmp(ptr,".afm") == 0 ||
|
||||
stricmp(ptr,".af2") == 0)
|
||||
*ptr = '\0'; //Remove extension.
|
||||
}
|
||||
return mapname;
|
||||
}
|
||||
|
||||
// Processes command-line arguments
|
||||
void process_args(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < argc; i++) {
|
||||
if(strcmp(argv[i], "-grf") == 0) {
|
||||
if(++i < argc)
|
||||
strcpy(grf_list_file, argv[i]);
|
||||
} else if(strcmp(argv[i], "-list") == 0) {
|
||||
if(++i < argc)
|
||||
strcpy(map_list_file, argv[i]);
|
||||
} else if(strcmp(argv[i], "-cache") == 0) {
|
||||
if(++i < argc)
|
||||
strcpy(map_cache_file, argv[i]);
|
||||
} else if(strcmp(argv[i], "-rebuild") == 0)
|
||||
rebuild = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
FILE *list;
|
||||
char line[1024];
|
||||
struct map_data map;
|
||||
char name[MAP_NAME_LENGTH];
|
||||
unsigned short index = 1;
|
||||
char name[MAP_NAME_LENGTH_EXT];
|
||||
|
||||
if(argc > 1)
|
||||
strcpy(grf_list_file, argv[1]);
|
||||
if(argc > 2)
|
||||
strcpy(map_list_file, argv[2]);
|
||||
if(argc > 3)
|
||||
strcpy(map_cache_file, argv[3]);
|
||||
// Process the command-line arguments
|
||||
process_args(argc, argv);
|
||||
|
||||
printf("Initializing grfio with %s\n", grf_list_file);
|
||||
grfio_init(grf_list_file);
|
||||
|
||||
// Attempt to open the map cache file and force rebuild if not found
|
||||
printf("Opening map cache: %s\n", map_cache_file);
|
||||
map_cache_fp = fopen(map_cache_file, "wb");
|
||||
if( map_cache_fp == NULL ) {
|
||||
if(!rebuild) {
|
||||
map_cache_fp = fopen(map_cache_file, "rb");
|
||||
if(map_cache_fp == NULL) {
|
||||
printf("Existing map cache not found, forcing rebuild mode\n");
|
||||
rebuild = 1;
|
||||
} else
|
||||
fclose(map_cache_fp);
|
||||
}
|
||||
if(rebuild)
|
||||
map_cache_fp = fopen(map_cache_file, "w+b");
|
||||
else
|
||||
map_cache_fp = fopen(map_cache_file, "r+b");
|
||||
if(map_cache_fp == NULL) {
|
||||
printf("Failure when opening map cache file %s\n", map_cache_file);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Open the map list
|
||||
printf("Opening map list: %s\n", map_list_file);
|
||||
list = fopen(map_list_file, "r");
|
||||
if( list == NULL ) {
|
||||
if(list == NULL) {
|
||||
printf("Failure when opening maps list file %s\n", map_list_file);
|
||||
exit(1);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
// Initialize the main header
|
||||
map_count = 0;
|
||||
filesize = sizeof(map_count);
|
||||
if(rebuild) {
|
||||
header.file_size = sizeof(struct main_header);
|
||||
header.map_count = 0;
|
||||
} else {
|
||||
fread(&header, sizeof(struct main_header), 1, map_cache_fp);
|
||||
header.file_size = GetULong((unsigned char *)&(header.file_size));
|
||||
header.map_count = GetUShort((unsigned char *)&(header.map_count));
|
||||
}
|
||||
|
||||
// Read and process the map list
|
||||
while(fgets(line, 1020, list)){
|
||||
@ -217,30 +304,37 @@ int main(int argc, char *argv[])
|
||||
if(line[0] == '/' && line[1] == '/')
|
||||
continue;
|
||||
|
||||
if(sscanf(line, "%16s %hu", name, &index) > 0) { // No defines in strings, 16 is hardcoded here
|
||||
printf("Index %d : %s\n", index, name);
|
||||
if(read_map(name, &map))
|
||||
cache_map(name, index, &map);
|
||||
else
|
||||
printf("Map file not found in GRF\n");
|
||||
// If the 2nd argument is omitted at next line, we'll keep last used index + 1
|
||||
index++;
|
||||
}
|
||||
if(sscanf(line, "%15s", name) < 1)
|
||||
continue;
|
||||
|
||||
if(strcmp("map:", name) == 0 && sscanf(line, "%*s %15s", name) < 1)
|
||||
continue;
|
||||
|
||||
remove_extension(name);
|
||||
printf("%s", name);
|
||||
if(find_map(name))
|
||||
printf(" already in cache!\n");
|
||||
else if(read_map(name, &map)) {
|
||||
cache_map(name, &map);
|
||||
printf(" successfully cached\n");
|
||||
} else
|
||||
printf(" not found in GRF!\n");
|
||||
|
||||
}
|
||||
|
||||
printf("Closing map list: %s\n", map_list_file);
|
||||
fclose(list);
|
||||
|
||||
printf("Closing map cache: %s\n", map_cache_file);
|
||||
// Write the main header and close the map cache
|
||||
printf("Closing map cache: %s\n", map_cache_file);
|
||||
fseek(map_cache_fp, 0, SEEK_SET);
|
||||
fwrite(&map_count, sizeof(map_count), 1, map_cache_fp);
|
||||
fwrite(&header, sizeof(struct main_header), 1, map_cache_fp);
|
||||
fclose(map_cache_fp);
|
||||
|
||||
printf("Finalizing grfio\n");
|
||||
grfio_final();
|
||||
|
||||
printf("%d maps cached\n", map_count);
|
||||
printf("%d maps now in cache\n", header.map_count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
15
tools/mapcache/grf_files.txt
Normal file
15
tools/mapcache/grf_files.txt
Normal file
@ -0,0 +1,15 @@
|
||||
//-----------------------------------------
|
||||
// GRF List
|
||||
// Add as many entries as you wish
|
||||
//-----------------------------------------
|
||||
|
||||
//grf: C:\Program Files\Gravity\RO\data.grf
|
||||
grf: C:\Program Files\Gravity\RO\sdata.grf
|
||||
|
||||
//-----------------------------------------
|
||||
// Data Directory
|
||||
// Path must include trailing backslash
|
||||
// Only one entry supported!
|
||||
//-----------------------------------------
|
||||
|
||||
//data_dir: C:\Program Files\Gravity\RO\
|
Loading…
x
Reference in New Issue
Block a user