summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Longbons <b.r.longbons@gmail.com>2013-02-18 19:20:35 -0800
committerBen Longbons <b.r.longbons@gmail.com>2013-02-20 18:27:30 -0800
commit25823b36905a84d92f9299ba7f9f0c713141c8fb (patch)
treea335120de1c4618c9b41391e70bc621a4218010c
parenta5d231b6a60a4ab868918850be24640e88843825 (diff)
downloadtmwa-25823b36905a84d92f9299ba7f9f0c713141c8fb.tar.gz
tmwa-25823b36905a84d92f9299ba7f9f0c713141c8fb.tar.bz2
tmwa-25823b36905a84d92f9299ba7f9f0c713141c8fb.tar.xz
tmwa-25823b36905a84d92f9299ba7f9f0c713141c8fb.zip
Strictify map cells
Also fix a small but major bug in map_randfreecell.
-rw-r--r--GNUmakefile4
-rw-r--r--src/common/grfio.cpp226
-rw-r--r--src/common/grfio.hpp26
-rw-r--r--src/common/utils2.hpp19
-rw-r--r--src/map/grfio.cpp72
-rw-r--r--src/map/grfio.hpp15
-rw-r--r--src/map/magic-expr.cpp9
-rw-r--r--src/map/magic-expr.hpp2
-rw-r--r--src/map/magic-stmt.cpp2
-rw-r--r--src/map/map.cpp121
-rw-r--r--src/map/map.hpp11
-rw-r--r--src/map/map.t.hpp15
-rw-r--r--src/map/mob.cpp37
-rw-r--r--src/map/npc.cpp22
-rw-r--r--src/map/path.cpp44
-rw-r--r--src/map/pc.cpp24
16 files changed, 224 insertions, 425 deletions
diff --git a/GNUmakefile b/GNUmakefile
index 9accaab..a8fe0f0 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -44,7 +44,7 @@ all: ${PROGS}
most: ${MOSTPROGS}
clean:
rm -rf ${PROGS} ${BUILD_DIR}/
-common: ${BUILD_DIR}/common/core.o ${BUILD_DIR}/common/db.o ${BUILD_DIR}/common/grfio.o ${BUILD_DIR}/common/lock.o ${BUILD_DIR}/common/md5calc.o ${BUILD_DIR}/common/mt_rand.o ${BUILD_DIR}/common/nullpo.o ${BUILD_DIR}/common/socket.o ${BUILD_DIR}/common/timer.o ${BUILD_DIR}/common/utils.o ${BUILD_DIR}/common/cxxstdio.o ${BUILD_DIR}/common/extract.o
+common: ${BUILD_DIR}/common/core.o ${BUILD_DIR}/common/db.o ${BUILD_DIR}/common/lock.o ${BUILD_DIR}/common/md5calc.o ${BUILD_DIR}/common/random.o ${BUILD_DIR}/common/nullpo.o ${BUILD_DIR}/common/socket.o ${BUILD_DIR}/common/timer.o ${BUILD_DIR}/common/utils.o ${BUILD_DIR}/common/cxxstdio.o ${BUILD_DIR}/common/extract.o
# Top level programs
login-server: ${BUILD_DIR}/login/login
@@ -62,7 +62,7 @@ eathena-monitor: ${BUILD_DIR}/tool/eathena-monitor
${BUILD_DIR}/char/char: ${BUILD_DIR}/char/char.o ${BUILD_DIR}/char/inter.o ${BUILD_DIR}/char/int_party.o ${BUILD_DIR}/char/int_storage.o ${BUILD_DIR}/common/core.o ${BUILD_DIR}/common/socket.o ${BUILD_DIR}/common/timer.o ${BUILD_DIR}/common/db.o ${BUILD_DIR}/common/lock.o ${BUILD_DIR}/common/random.o ${BUILD_DIR}/common/utils.o ${BUILD_DIR}/common/cxxstdio.o ${BUILD_DIR}/common/extract.o
${BUILD_DIR}/ladmin/ladmin: ${BUILD_DIR}/ladmin/ladmin.o ${BUILD_DIR}/common/md5calc.o ${BUILD_DIR}/common/core.o ${BUILD_DIR}/common/socket.o ${BUILD_DIR}/common/timer.o ${BUILD_DIR}/common/db.o ${BUILD_DIR}/common/random.o ${BUILD_DIR}/common/utils.o ${BUILD_DIR}/common/cxxstdio.o
${BUILD_DIR}/login/login: ${BUILD_DIR}/login/login.o ${BUILD_DIR}/common/core.o ${BUILD_DIR}/common/socket.o ${BUILD_DIR}/common/timer.o ${BUILD_DIR}/common/db.o ${BUILD_DIR}/common/lock.o ${BUILD_DIR}/common/random.o ${BUILD_DIR}/common/md5calc.o ${BUILD_DIR}/common/utils.o ${BUILD_DIR}/common/cxxstdio.o ${BUILD_DIR}/common/extract.o
-${BUILD_DIR}/map/map: ${BUILD_DIR}/map/map.o ${BUILD_DIR}/map/tmw.o ${BUILD_DIR}/map/magic-interpreter-lexer.o ${BUILD_DIR}/map/magic-interpreter-parser.o ${BUILD_DIR}/map/magic-interpreter-base.o ${BUILD_DIR}/map/magic-expr.o ${BUILD_DIR}/map/magic-stmt.o ${BUILD_DIR}/map/magic.o ${BUILD_DIR}/map/map.o ${BUILD_DIR}/map/chrif.o ${BUILD_DIR}/map/clif.o ${BUILD_DIR}/map/pc.o ${BUILD_DIR}/map/npc.o ${BUILD_DIR}/map/chat.o ${BUILD_DIR}/map/path.o ${BUILD_DIR}/map/itemdb.o ${BUILD_DIR}/map/mob.o ${BUILD_DIR}/map/script.o ${BUILD_DIR}/map/storage.o ${BUILD_DIR}/map/skill.o ${BUILD_DIR}/map/skill-pools.o ${BUILD_DIR}/map/atcommand.o ${BUILD_DIR}/map/battle.o ${BUILD_DIR}/map/intif.o ${BUILD_DIR}/map/trade.o ${BUILD_DIR}/map/party.o ${BUILD_DIR}/common/core.o ${BUILD_DIR}/common/socket.o ${BUILD_DIR}/common/timer.o ${BUILD_DIR}/common/grfio.o ${BUILD_DIR}/common/db.o ${BUILD_DIR}/common/lock.o ${BUILD_DIR}/common/nullpo.o ${BUILD_DIR}/common/random.o ${BUILD_DIR}/common/md5calc.o ${BUILD_DIR}/common/utils.o ${BUILD_DIR}/common/cxxstdio.o ${BUILD_DIR}/common/extract.o
+${BUILD_DIR}/map/map: ${BUILD_DIR}/map/map.o ${BUILD_DIR}/map/tmw.o ${BUILD_DIR}/map/magic-interpreter-lexer.o ${BUILD_DIR}/map/magic-interpreter-parser.o ${BUILD_DIR}/map/magic-interpreter-base.o ${BUILD_DIR}/map/magic-expr.o ${BUILD_DIR}/map/magic-stmt.o ${BUILD_DIR}/map/magic.o ${BUILD_DIR}/map/map.o ${BUILD_DIR}/map/chrif.o ${BUILD_DIR}/map/clif.o ${BUILD_DIR}/map/pc.o ${BUILD_DIR}/map/npc.o ${BUILD_DIR}/map/chat.o ${BUILD_DIR}/map/path.o ${BUILD_DIR}/map/itemdb.o ${BUILD_DIR}/map/mob.o ${BUILD_DIR}/map/script.o ${BUILD_DIR}/map/storage.o ${BUILD_DIR}/map/skill.o ${BUILD_DIR}/map/skill-pools.o ${BUILD_DIR}/map/atcommand.o ${BUILD_DIR}/map/battle.o ${BUILD_DIR}/map/intif.o ${BUILD_DIR}/map/trade.o ${BUILD_DIR}/map/party.o ${BUILD_DIR}/common/core.o ${BUILD_DIR}/common/socket.o ${BUILD_DIR}/common/timer.o ${BUILD_DIR}/map/grfio.o ${BUILD_DIR}/common/db.o ${BUILD_DIR}/common/lock.o ${BUILD_DIR}/common/nullpo.o ${BUILD_DIR}/common/random.o ${BUILD_DIR}/common/md5calc.o ${BUILD_DIR}/common/utils.o ${BUILD_DIR}/common/cxxstdio.o ${BUILD_DIR}/common/extract.o
${BUILD_DIR}/tool/eathena-monitor: ${BUILD_DIR}/tool/eathena-monitor.o
# silence build warnings for code beyond my control
diff --git a/src/common/grfio.cpp b/src/common/grfio.cpp
deleted file mode 100644
index 1ed5c3e..0000000
--- a/src/common/grfio.cpp
+++ /dev/null
@@ -1,226 +0,0 @@
-// Reads .gat files by name-mapping .wlk files
-#include "grfio.hpp"
-
-#include <sys/stat.h>
-
-#include <cstdio>
-#include <cstring>
-
-#include "cxxstdio.hpp"
-#include "socket.hpp"
-#include "utils.hpp"
-
-#include "../poison.hpp"
-
-//----------------------------
-// file entry table struct
-//----------------------------
-typedef struct
-{
- size_t declen;
- int16_t next; // next index into the filelist[] array, or -1
- char fn[128 - 4 - 2]; // file name
-} FILELIST;
-
-#define FILELIST_LIMIT 32768 // limit to number of filelists - if you increase this, change all shorts to int
-#define FILELIST_ADDS 1024 // amount to increment when reallocing
-
-static
-FILELIST *filelist = NULL;
-/// Number of entries used
-static
-uint16_t filelist_entrys = 0;
-/// Number of FILELIST entries actually allocated
-static
-uint16_t filelist_maxentry = 0;
-
-/// First index of the given hash, into the filelist[] array
-#define l -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
-static
-int16_t filelist_hash[256] = {l,l,l,l,l,l,l,l,l,l,l,l,l,l,l,l};
-#undef l
-
-/// Hash a filename
-static
-uint8_t filehash(const char *fname)
-{
- // Larger than the return type - upper bits are used in the process
- uint32_t hash = 0;
- while (*fname)
- {
- hash = (hash << 1) + (hash >> 7) * 9 + (unsigned char)*fname;
- fname++;
- }
- return hash;
-}
-
-/// Find the filelist entry for the given filename, or NULL if it is not
-static
-FILELIST *filelist_find(const char *fname)
-{
- int16_t index = filelist_hash[filehash(fname)];
- while (index >= 0)
- {
- if (strcmp(filelist[index].fn, fname) == 0)
- return &filelist[index];
- index = filelist[index].next;
- }
- return NULL;
-}
-
-/// Copy a temporary entry into the hash map
-static
-FILELIST *filelist_add(FILELIST * entry)
-{
- if (filelist_entrys >= FILELIST_LIMIT)
- {
- FPRINTF(stderr, "filelist limit : filelist_add\n");
- exit(1);
- }
-
- if (filelist_entrys >= filelist_maxentry)
- {
- RECREATE(filelist, FILELIST, filelist_maxentry + FILELIST_ADDS);
- memset(filelist + filelist_maxentry, '\0',
- FILELIST_ADDS * sizeof(FILELIST));
- filelist_maxentry += FILELIST_ADDS;
- }
-
- uint16_t new_index = filelist_entrys++;
- uint8_t hash = filehash(entry->fn);
- entry->next = filelist_hash[hash];
- filelist_hash[hash] = new_index;
-
- filelist[new_index] = *entry;
-
- return &filelist[new_index];
-}
-
-static
-FILELIST *filelist_modify(FILELIST * entry)
-{
- FILELIST *fentry = filelist_find(entry->fn);
- if (fentry)
- {
- entry->next = fentry->next;
- *fentry = *entry;
- return fentry;
- }
- return filelist_add(entry);
-}
-
-/// Change fname data/*.gat to lfname data/*.wlk
-// TODO even if the file exists, don't keep reopening it every time one loads
-static
-void grfio_resnametable(const char *fname, char *lfname)
-{
- char restable[] = "data/resnametable.txt";
-
- FILE *fp = fopen_(restable, "rb");
- if (fp == NULL)
- {
- FPRINTF(stderr, "No resnametable, can't look for %s\n", fname);
- strcpy(lfname, fname);
- char* ext = lfname + strlen(lfname) - 4;
- if (!strcmp(ext, ".gat"))
- strcpy(ext, ".wlk");
- return;
- }
-
- char line[512];
- while (fgets(line, sizeof(line), fp))
- {
- char w1[256], w2[256];
- if (
- // line is of the form foo.gat#foo.wlk#
- (sscanf(line, "%[^#]#%[^#]#", w1, w2) == 2)
- // strip data/ from foo.gat before comparing
- && (!strcmp(w1, fname + 5)))
- {
- strcpy(lfname, "data/");
- strcpy(lfname + 5, w2);
- fclose_(fp);
- return;
- }
- }
- FPRINTF(stderr, "Unable to find resource: %s\n", fname);
- fclose_(fp);
-
- strcpy(lfname, fname);
- char* ext = lfname + strlen(lfname) - 4;
- if (!strcmp(ext, ".gat"))
- strcpy(ext, ".wlk");
- return;
-}
-
-/// Size of resource
-size_t grfio_size(const char *fname)
-{
- FILELIST *entry = filelist_find(fname);
- if (entry)
- return entry->declen;
-
- char lfname[256];
- FILELIST lentry;
- struct stat st;
-
- grfio_resnametable(fname, lfname);
-
- for (char *p = lfname; *p; p++)
- if (*p == '\\')
- *p = '/';
-
- if (stat(lfname, &st) == 0)
- {
- strncpy(lentry.fn, fname, sizeof(lentry.fn) - 1);
- lentry.declen = st.st_size;
- entry = filelist_modify(&lentry);
- }
- else
- {
- PRINTF("%s not found\n", fname);
- return 0;
- }
- return entry->declen;
-}
-
-void *grfio_reads(const char *fname, size_t *size)
-{
- char lfname[256];
- grfio_resnametable(fname, lfname);
-
- for (char *p = &lfname[0]; *p != 0; p++)
- if (*p == '\\')
- *p = '/'; // * At the time of Unix
-
- FILE *in = fopen_(lfname, "rb");
- if (!in)
- {
- FPRINTF(stderr, "%s not found\n", fname);
- return NULL;
- }
- FILELIST lentry;
- FILELIST *entry = filelist_find(fname);
- if (entry)
- {
- lentry.declen = entry->declen;
- }
- else
- {
- fseek(in, 0, SEEK_END);
- lentry.declen = ftell(in);
- fseek(in, 0, SEEK_SET);
- strncpy(lentry.fn, fname, sizeof(lentry.fn) - 1);
- entry = filelist_modify(&lentry);
- }
- uint8_t *buf2;
- CREATE(buf2, uint8_t, lentry.declen + 1024);
- if (fread(buf2, 1, lentry.declen, in) != lentry.declen)
- exit(1);
- fclose_(in);
- in = NULL;
-
- if (size)
- *size = entry->declen;
- return buf2;
-}
diff --git a/src/common/grfio.hpp b/src/common/grfio.hpp
deleted file mode 100644
index 7707b2b..0000000
--- a/src/common/grfio.hpp
+++ /dev/null
@@ -1,26 +0,0 @@
-#ifndef GRFIO_HPP
-#define GRFIO_HPP
-
-# include "sanity.hpp"
-
-/// Accessor to the .gat map virtual files
-// Note .gat files are mapped to .wlk files by data/resnametable.txt
-// Note that there currently is a 1-1 correlation between them,
-// but it is possible for a single .wlk to have multiple .gats reference it
-
-/// Load file into memory and possibly record length
-// For some reason, this allocates an extra 1024 bytes at the end
-void *grfio_reads(const char *resourcename, size_t *size);
-
-/// Load file into memory
-inline
-void *grfio_read(const char *resourcename)
-{
- return grfio_reads(resourcename, NULL);
-}
-
-/// Get size of file
-// This is only called once, and that is to check the existence of a file.
-size_t grfio_size(const char *resourcename) __attribute__((deprecated));
-
-#endif // GRFIO_HPP
diff --git a/src/common/utils2.hpp b/src/common/utils2.hpp
index cdf2069..5f02beb 100644
--- a/src/common/utils2.hpp
+++ b/src/common/utils2.hpp
@@ -5,6 +5,7 @@
#include <functional>
#include <iterator>
+#include <memory>
#include <type_traits>
#ifdef __clang__
@@ -208,4 +209,22 @@ typename std::common_type<A, B>::type max(A a, B b)
return b < a ? a : b;
}
+template<class T>
+struct is_array_of_unknown_bound
+: std::is_same<T, typename std::remove_extent<T>::type[]>
+{};
+
+template<class T, class... A>
+typename std::enable_if<!is_array_of_unknown_bound<T>::value, std::unique_ptr<T>>::type make_unique(A&&... a)
+{
+ return std::unique_ptr<T>(new T(a...));
+}
+
+template<class T>
+typename std::enable_if<is_array_of_unknown_bound<T>::value, std::unique_ptr<T>>::type make_unique(size_t sz)
+{
+ typedef typename std::remove_extent<T>::type E;
+ return std::unique_ptr<E[]>(new E[sz]);
+}
+
#endif // UTILS2_HPP
diff --git a/src/map/grfio.cpp b/src/map/grfio.cpp
new file mode 100644
index 0000000..a190d1b
--- /dev/null
+++ b/src/map/grfio.cpp
@@ -0,0 +1,72 @@
+// Reads .gat files by name-mapping .wlk files
+#include "grfio.hpp"
+
+#include <sys/stat.h>
+
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <cassert>
+#include <cstdio>
+#include <cstring>
+
+#include <fstream>
+#include <map>
+
+#include "../common/cxxstdio.hpp"
+#include "../common/extract.hpp"
+
+#include "../poison.hpp"
+
+static
+std::map<std::string, std::string> load_resnametable()
+{
+ std::ifstream in("data/resnametable.txt");
+ if (!in.is_open())
+ {
+ fprintf(stderr, "Missing data/resnametable.txt");
+ abort();
+ }
+ std::map<std::string, std::string> out;
+
+ std::string line;
+ while (std::getline(in, line))
+ {
+ std::string key, value;
+ if (!extract(line,
+ record<'#'>(&key, &value)))
+ continue;
+ out[key] = value;
+ }
+ return out;
+}
+
+/// Change *.gat to *.wlk
+static
+std::string grfio_resnametable(const_string rname)
+{
+ static
+ std::map<std::string, std::string> resnametable = load_resnametable();
+
+ return resnametable.at(std::string(rname.begin(), rname.end()));
+}
+
+std::vector<uint8_t> grfio_reads(const_string rname)
+{
+ std::string lfname = "data/" + grfio_resnametable(rname);
+
+ int fd = open(lfname.c_str(), O_RDONLY);
+ if (fd == -1)
+ {
+ FPRINTF(stderr, "Resource %s (file %s) not found\n",
+ std::string(rname.begin(), rname.end()), lfname);
+ return {};
+ }
+ off_t len = lseek(fd, 0, SEEK_END);
+ assert (len != -1);
+ std::vector<uint8_t> buffer(len);
+ int err = pread(fd, buffer.data(), len, 0);
+ assert (err == len);
+ close(fd);
+ return buffer;
+}
diff --git a/src/map/grfio.hpp b/src/map/grfio.hpp
new file mode 100644
index 0000000..fd7b871
--- /dev/null
+++ b/src/map/grfio.hpp
@@ -0,0 +1,15 @@
+#ifndef GRFIO_HPP
+#define GRFIO_HPP
+
+#include <cstdint>
+
+#include <vector>
+
+#include "../common/const_array.hpp"
+
+/// Load a resource into memory, subject to data/resnametable.txt.
+/// Normally, resourcename is xxx-y.gat and the file is xxx-y.wlk.
+/// Currently there is exactly one .wlk per .gat, but multiples are fine.
+std::vector<uint8_t> grfio_reads(const_string resourcename);
+
+#endif // GRFIO_HPP
diff --git a/src/map/magic-expr.cpp b/src/map/magic-expr.cpp
index ea853a1..a366cc0 100644
--- a/src/map/magic-expr.cpp
+++ b/src/map/magic-expr.cpp
@@ -14,11 +14,6 @@
#include "../poison.hpp"
-bool map_is_solid(int m, int x, int y)
-{
- return map_getcell(m, x, y) == 1;
-}
-
static
void free_area(area_t *area)
{
@@ -850,7 +845,9 @@ int fun_awayfrom(env_t *, int, val_t *result, val_t *args)
int dx = dirx[ARGDIR(1)];
int dy = diry[ARGDIR(1)];
int distance = ARGINT(2);
- while (distance-- && !map_is_solid(loc->m, loc->x + dx, loc->y + dy))
+ while (distance--
+ && !bool(read_gat(loc->m, loc->x + dx, loc->y + dy)
+ & MapCell::UNWALKABLE))
{
loc->x += dx;
loc->y += dy;
diff --git a/src/map/magic-expr.hpp b/src/map/magic-expr.hpp
index e7f27dc..419c833 100644
--- a/src/map/magic-expr.hpp
+++ b/src/map/magic-expr.hpp
@@ -60,8 +60,6 @@ int magic_eval_int(env_t *env, expr_t *expr);
*/
char *magic_eval_str(env_t *env, expr_t *expr);
-bool map_is_solid(int m, int x, int y);
-
expr_t *magic_new_expr(EXPR ty);
void magic_clear_var(val_t *v);
diff --git a/src/map/magic-stmt.cpp b/src/map/magic-stmt.cpp
index c729cfd..8058310 100644
--- a/src/map/magic-stmt.cpp
+++ b/src/map/magic-stmt.cpp
@@ -480,7 +480,7 @@ int op_move(env_t *, int, val_t *args)
int newx = subject->x + dirx[dir];
int newy = subject->y + diry[dir];
- if (!map_is_solid(subject->m, newx, newy))
+ if (!bool(map_getcell(subject->m, newx, newy) & MapCell::UNWALKABLE))
entity_warp(subject, subject->m, newx, newy);
return 0;
diff --git a/src/map/map.cpp b/src/map/map.cpp
index d7cf4f6..65fdc38 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -6,6 +6,7 @@
#include <netdb.h>
#include <unistd.h>
+#include <cassert>
#include <cstdlib>
#include <cstring>
@@ -14,7 +15,6 @@
#include "../common/core.hpp"
#include "../common/cxxstdio.hpp"
#include "../common/db.hpp"
-#include "../common/grfio.hpp"
#include "../common/random2.hpp"
#include "../common/nullpo.hpp"
#include "../common/socket.hpp"
@@ -25,6 +25,7 @@
#include "chat.hpp"
#include "chrif.hpp"
#include "clif.hpp"
+#include "grfio.hpp"
#include "itemdb.hpp"
#include "magic.hpp"
#include "mob.hpp"
@@ -776,7 +777,7 @@ std::pair<uint16_t, uint16_t> map_randfreecell(int m, uint16_t x, uint16_t y, ui
{
int dx = itr % w;
int dy = itr / w;
- if (read_gat(m, x + dx, y + dy) == 1)
+ if (!bool(read_gat(m, x + dx, y + dy) & MapCell::UNWALKABLE))
return {static_cast<uint16_t>(x + dx), static_cast<uint16_t>(y + dy)};
}
return {static_cast<uint16_t>(0), static_cast<uint16_t>(0)};
@@ -1347,10 +1348,10 @@ DIR map_calc_dir(struct block_list *src, int x, int y)
* (m,x,y)の状態を調べる
*------------------------------------------
*/
-int map_getcell(int m, int x, int y)
+MapCell map_getcell(int m, int x, int y)
{
if (x < 0 || x >= map[m].xs - 1 || y < 0 || y >= map[m].ys - 1)
- return 1;
+ return MapCell::UNWALKABLE;
return map[m].gat[x + y * map[m].xs];
}
@@ -1358,11 +1359,11 @@ int map_getcell(int m, int x, int y)
* (m,x,y)の状態をtにする
*------------------------------------------
*/
-int map_setcell(int m, int x, int y, int t)
+void map_setcell(int m, int x, int y, MapCell t)
{
if (x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys)
- return t;
- return map[m].gat[x + y * map[m].xs] = t;
+ return;
+ map[m].gat[x + y * map[m].xs] = t;
}
/*==========================================
@@ -1404,46 +1405,28 @@ int map_setipport(const char *name, struct in_addr ip, int port)
return 0;
}
-// 初期化周り
-/*==========================================
- * 水場高さ設定
- *------------------------------------------
- */
-static
-struct Waterlist
-{
- char mapname[24];
- int waterheight;
-} *waterlist = NULL;
-
/*==========================================
* マップ1枚読み込み
*------------------------------------------
*/
static
-int map_readmap(int m, const char *fn, char *)
+bool map_readmap(int m, const_string fn)
{
- int s;
- int x, y, xs, ys;
- struct gat_1cell
- {
- char type;
- } *p;
- size_t size;
-
// read & convert fn
- uint8_t *gat = (uint8_t *)grfio_read(fn);
- if (gat == NULL)
- return -1;
+ std::vector<uint8_t> gat_v = grfio_reads(fn);
+ if (gat_v.empty())
+ return false;
+ size_t s = gat_v.size() - 4;
- PRINTF("\rLoading Maps [%d/%d]: %-50s ", m, map_num, fn);
+ map[m].m = m;
+ int xs = map[m].xs = gat_v[0] | gat_v[1] << 8;
+ int ys = map[m].ys = gat_v[2] | gat_v[3] << 8;
+ PRINTF("\rLoading Maps [%d/%d]: %-30s (%i, %i)",
+ m, map_num, std::string(fn.begin(), fn.end()), xs, ys);
fflush(stdout);
- map[m].m = m;
- xs = map[m].xs = *(short *)(gat);
- ys = map[m].ys = *(short *)(gat + 2);
- PRINTF("\n%i %i\n", xs, ys);
- map[m].gat = (uint8_t *)calloc(s = map[m].xs * map[m].ys, 1);
+ assert (s == xs * ys);
+ map[m].gat = make_unique<MapCell[]>(s);
if (map[m].gat == NULL)
{
PRINTF("out of memory : map_readmap gat\n");
@@ -1455,39 +1438,21 @@ int map_readmap(int m, const char *fn, char *)
memset(&map[m].flag, 0, sizeof(map[m].flag));
if (battle_config.pk_mode)
map[m].flag.pvp = 1; // make all maps pvp for pk_mode [Valaris]
- for (y = 0; y < ys; y++)
- {
- p = (struct gat_1cell *)(gat + y * xs + 4);
- for (x = 0; x < xs; x++)
- {
- /*if (wh!=NO_WATER && p->type==0){
- * // 水場判定
- * map[m].gat[x+y*xs]= (p->high[0]>wh || p->high[1]>wh || p->high[2]>wh || p->high[3]>wh) ? 3 : 0;
- * } else { */
- map[m].gat[x + y * xs] = p->type;
- //}
- p++;
- }
- }
- free(gat);
+ MapCell *gat_m = reinterpret_cast<MapCell *>(&gat_v[4]);
+ std::copy(gat_m, gat_m + s, &map[m].gat[0]);
map[m].bxs = (xs + BLOCK_SIZE - 1) / BLOCK_SIZE;
map[m].bys = (ys + BLOCK_SIZE - 1) / BLOCK_SIZE;
- size = map[m].bxs * map[m].bys;
+ size_t size = map[m].bxs * map[m].bys;
CREATE(map[m].block, struct block_list *, size);
-
CREATE(map[m].block_mob, struct block_list *, size);
-
CREATE(map[m].block_count, int, size);
-
CREATE(map[m].block_mob_count, int, size);
strdb_insert(map_db, map[m].name, &map[m]);
-// PRINTF("%s read done\n",fn);
-
- return 0;
+ return true;
}
/*==========================================
@@ -1499,42 +1464,12 @@ int map_readallmap(void)
{
int i, maps_removed = 0;
- // 先に全部のャbプの存在を確認
- for (i = 0; i < map_num; i++)
- {
- if (strstr(map[i].name, ".gat") == NULL)
- continue;
- // TODO replace this
- std::string fn = STRPRINTF("data\\%s", map[i].name);
- // TODO - remove this, it is the last call to grfio_size, which is deprecated
- if (!grfio_size(fn.c_str()))
- {
- map_delmap(map[i].name);
- maps_removed++;
- }
- }
for (i = 0; i < map_num; i++)
{
- if (strstr(map[i].name, ".gat") != NULL)
+ assert (strstr(map[i].name, ".gat") != NULL);
{
- char *p = strstr(map[i].name, ">"); // [MouseJstr]
- if (p != NULL)
- {
- char alias[64];
- *p = '\0';
- strcpy(alias, map[i].name);
- strcpy(map[i].name, p + 1);
- std::string fn = STRPRINTF("data\\%s", map[i].name);
- if (map_readmap(i, fn.c_str(), alias) == -1)
- {
- map_delmap(map[i].name);
- maps_removed++;
- }
- }
- else
{
- std::string fn = STRPRINTF("data\\%s", map[i].name);
- if (map_readmap(i, fn.c_str(), NULL) == -1)
+ if (!map_readmap(i, map[i].name))
{
map_delmap(map[i].name);
maps_removed++;
@@ -1543,7 +1478,6 @@ int map_readallmap(void)
}
}
- free(waterlist);
PRINTF("\rMaps Loaded: %d %60s\n", map_num, "");
PRINTF("\rMaps Removed: %d \n", maps_removed);
return 0;
@@ -1856,8 +1790,7 @@ void term_func(void)
for (i = 0; i <= map_num; i++)
{
- if (map[i].gat)
- free(map[i].gat);
+ map[i].gat = nullptr;
if (map[i].block)
free(map[i].block);
if (map[i].block_mob)
diff --git a/src/map/map.hpp b/src/map/map.hpp
index 72ded63..29680a6 100644
--- a/src/map/map.hpp
+++ b/src/map/map.hpp
@@ -398,7 +398,8 @@ struct map_data
{
char name[24];
char alias[24]; // [MouseJstr]
- unsigned char *gat; // NULLなら下のmap_data_other_serverとして扱う
+ // if NULL, actually a map_data_other_server
+ std::unique_ptr<MapCell[]> gat;
struct block_list **block;
struct block_list **block_mob;
int *block_count, *block_mob_count;
@@ -455,12 +456,12 @@ extern struct map_data map[];
extern int map_num;
inline
-uint8_t read_gatp(struct map_data *m, int x, int y)
+MapCell read_gatp(struct map_data *m, int x, int y)
{
return m->gat[x + y * m->xs];
}
inline
-uint8_t read_gat(int m, int x, int y)
+MapCell read_gat(int m, int x, int y)
{
return read_gatp(&map[m], x, y);
}
@@ -584,8 +585,8 @@ struct map_session_data *map_get_prev_session(
struct map_session_data *current);
// gat関連
-int map_getcell(int, int, int);
-int map_setcell(int, int, int, int);
+MapCell map_getcell(int, int, int);
+void map_setcell(int, int, int, MapCell);
// その他
bool map_check_dir(DIR s_dir, DIR t_dir);
diff --git a/src/map/map.t.hpp b/src/map/map.t.hpp
index 09444fd..c57ea06 100644
--- a/src/map/map.t.hpp
+++ b/src/map/map.t.hpp
@@ -542,4 +542,19 @@ ENUM_BITWISE_OPERATORS(MobMode)
}
using e::MobMode;
+namespace e
+{
+enum class MapCell : uint8_t
+{
+ // the usual thing
+ UNWALKABLE = 0x01,
+ // not in tmwa data
+ _range = 0x04,
+ // set in code, not imported
+ NPC_NEAR = 0x80,
+};
+ENUM_BITWISE_OPERATORS(MapCell)
+}
+using e::MapCell;
+
#endif // MAP_T_HPP
diff --git a/src/map/mob.cpp b/src/map/mob.cpp
index 80671c2..79a21ea 100644
--- a/src/map/mob.cpp
+++ b/src/map/mob.cpp
@@ -435,7 +435,7 @@ int mob_once_spawn_area(struct map_session_data *sd, const char *mapname,
const char *mobname, int mob_class, int amount,
const char *event)
{
- int x, y, i, c, max, lx = -1, ly = -1, id = 0;
+ int x, y, i, max, lx = -1, ly = -1, id = 0;
int m;
if (strcmp(mapname, "this") == 0)
@@ -458,7 +458,8 @@ int mob_once_spawn_area(struct map_session_data *sd, const char *mapname,
x = random_::in(x0, x1);
y = random_::in(y0, y1);
}
- while (((c = map_getcell(m, x, y)) == 1 || c == 5) && (++j) < max);
+ while (bool(map_getcell(m, x, y) & MapCell::UNWALKABLE)
+ && (++j) < max);
if (j >= max)
{
if (lx >= 0)
@@ -570,7 +571,6 @@ static
int mob_walk(struct mob_data *md, tick_t tick, unsigned char data)
{
int moveblock;
- int ctype;
int x, y, dx, dy;
nullpo_ret(md);
@@ -597,8 +597,7 @@ int mob_walk(struct mob_data *md, tick_t tick, unsigned char data)
x = md->bl.x;
y = md->bl.y;
- ctype = map_getcell(md->bl.m, x, y);
- if (ctype == 1 || ctype == 5)
+ if (bool(map_getcell(md->bl.m, x, y) & MapCell::UNWALKABLE))
{
mob_stop_walking(md, 1);
return 0;
@@ -607,8 +606,8 @@ int mob_walk(struct mob_data *md, tick_t tick, unsigned char data)
dx = dirx[md->dir];
dy = diry[md->dir];
- ctype = map_getcell(md->bl.m, x + dx, y + dy);
- if (ctype == 1 || ctype == 5)
+ if (bool(map_getcell(md->bl.m, x + dx, y + dy)
+ & MapCell::UNWALKABLE))
{
mob_walktoxy_sub(md);
return 0;
@@ -1056,7 +1055,7 @@ int mob_setdelayspawn(int id)
*/
int mob_spawn(int id)
{
- int x = 0, y = 0, c;
+ int x = 0, y = 0;
tick_t tick = gettick();
struct mob_data *md;
struct block_list *bl;
@@ -1098,7 +1097,8 @@ int mob_spawn(int id)
}
i++;
}
- while (((c = map_getcell(md->bl.m, x, y)) == 1 || c == 5) && i < 50);
+ while (bool(map_getcell(md->bl.m, x, y) & MapCell::UNWALKABLE)
+ && i < 50);
if (i >= 50)
{
@@ -1698,8 +1698,7 @@ int mob_randomwalk(struct mob_data *md, tick_t tick)
// Search of a movable place
x = md->bl.x + random_::in(-d, d);
y = md->bl.y + random_::in(-d, d);
- uint8_t c = map_getcell(md->bl.m, x, y);
- if (c != 1 && c != 5
+ if (!bool(map_getcell(md->bl.m, x, y) & MapCell::UNWALKABLE)
&& mob_walktoxy(md, x, y, 1) == 0)
{
md->move_fail_count = 0;
@@ -2784,7 +2783,7 @@ int mob_warpslave(struct mob_data *md, int x, int y)
*/
int mob_warp(struct mob_data *md, int m, int x, int y, BeingRemoveWhy type)
{
- int i = 0, c, xs = 0, ys = 0, bx = x, by = y;
+ int i = 0, xs = 0, ys = 0, bx = x, by = y;
nullpo_ret(md);
@@ -2807,8 +2806,10 @@ int mob_warp(struct mob_data *md, int m, int x, int y, BeingRemoveWhy type)
xs = ys = 9;
}
- while ((x < 0 || y < 0 || ((c = read_gat(m, x, y)) == 1 || c == 5))
- && (i++) < 1000)
+ while ((x < 0
+ || y < 0
+ || bool(read_gat(m, x, y) & MapCell::UNWALKABLE))
+ && (i++) < 1000)
{
if (xs > 0 && ys > 0 && i < 250)
{
@@ -2924,7 +2925,7 @@ int mob_summonslave(struct mob_data *md2, int *value, int amount, int flag)
continue;
for (; amount > 0; amount--)
{
- int x = 0, y = 0, c = 0, i = 0;
+ int x = 0, y = 0, i = 0;
md = (struct mob_data *) calloc(1, sizeof(struct mob_data));
if (bool(mob_db[mob_class].mode & MobMode::LOOTER))
md->lootitem = (struct item *)
@@ -2932,8 +2933,10 @@ int mob_summonslave(struct mob_data *md2, int *value, int amount, int flag)
else
md->lootitem = NULL;
- while ((x <= 0 || y <= 0 || (c = map_getcell(m, x, y)) == 1
- || c == 5) && (i++) < 100)
+ while ((x <= 0
+ || y <= 0
+ || bool(map_getcell(m, x, y) & MapCell::UNWALKABLE))
+ && (i++) < 100)
{
x = bx + random_::in(-4, 4);
y = by + random_::in(-4, 4);
diff --git a/src/map/npc.cpp b/src/map/npc.cpp
index 610a274..b65c263 100644
--- a/src/map/npc.cpp
+++ b/src/map/npc.cpp
@@ -1014,11 +1014,14 @@ int npc_parse_warp(const char *w1, const char *, const char *w3, const char *w4)
{
for (j = 0; j < xs; j++)
{
- int t;
- t = map_getcell(m, x - xs / 2 + j, y - ys / 2 + i);
- if (t == 1 || t == 5)
+ int x_lo = x - xs / 2;
+ int y_lo = y - ys / 2;
+ int xc = x_lo + j;
+ int yc = y_lo + i;
+ MapCell t = map_getcell(m, xc, yc);
+ if (bool(t & MapCell::UNWALKABLE))
continue;
- map_setcell(m, x - xs / 2 + j, y - ys / 2 + i, t | 0x80);
+ map_setcell(m, xc, yc, t | MapCell::NPC_NEAR);
}
}
@@ -1317,11 +1320,14 @@ int npc_parse_script(char *w1, char *w2, char *w3, char *w4,
{
for (j = 0; j < xs; j++)
{
- int t;
- t = map_getcell(m, x - xs / 2 + j, y - ys / 2 + i);
- if (t == 1 || t == 5)
+ int x_lo = x - xs / 2;
+ int y_lo = y - ys / 2;
+ int xc = x_lo + j;
+ int yc = y_lo + i;
+ MapCell t = map_getcell(m, xc, yc);
+ if (bool(t & MapCell::UNWALKABLE))
continue;
- map_setcell(m, x - xs / 2 + j, y - ys / 2 + i, t | 0x80);
+ map_setcell(m, xc, yc, t | MapCell::NPC_NEAR);
}
}
}
diff --git a/src/map/path.cpp b/src/map/path.cpp
index 9c6ea28..7a8eb37 100644
--- a/src/map/path.cpp
+++ b/src/map/path.cpp
@@ -182,19 +182,11 @@ int add_path(int *heap, struct tmp_path *tp, int x, int y, int dist,
*------------------------------------------
*/
static
-int can_place(struct map_data *m, int x, int y, int flag)
+bool can_place(struct map_data *m, int x, int y)
{
- int c;
-
nullpo_ret(m);
- c = read_gatp(m, x, y);
-
- if (c == 1)
- return 0;
- if (!(flag & 0x10000) && c == 5)
- return 0;
- return 1;
+ return !bool(read_gatp(m, x, y) & MapCell::UNWALKABLE);
}
/*==========================================
@@ -202,7 +194,7 @@ int can_place(struct map_data *m, int x, int y, int flag)
*------------------------------------------
*/
static
-int can_move(struct map_data *m, int x0, int y0, int x1, int y1, int flag)
+int can_move(struct map_data *m, int x0, int y0, int x1, int y1)
{
nullpo_ret(m);
@@ -210,13 +202,13 @@ int can_move(struct map_data *m, int x0, int y0, int x1, int y1, int flag)
return 0;
if (x1 < 0 || y1 < 0 || x1 >= m->xs || y1 >= m->ys)
return 0;
- if (!can_place(m, x0, y0, flag))
+ if (!can_place(m, x0, y0))
return 0;
- if (!can_place(m, x1, y1, flag))
+ if (!can_place(m, x1, y1))
return 0;
if (x0 == x1 || y0 == y1)
return 1;
- if (!can_place(m, x0, y1, flag) || !can_place(m, x1, y0, flag))
+ if (!can_place(m, x0, y1) || !can_place(m, x1, y0))
return 0;
return 1;
}
@@ -239,7 +231,7 @@ int path_search(struct walkpath_data *wpd, int m, int x0, int y0, int x1, int y1
return -1;
md = &map[m];
if (x1 < 0 || x1 >= md->xs || y1 < 0 || y1 >= md->ys
- || (i = read_gatp(md, x1, y1)) == 1 || i == 5)
+ || bool(read_gatp(md, x1, y1) & MapCell::UNWALKABLE))
return -1;
// easy
@@ -251,7 +243,7 @@ int path_search(struct walkpath_data *wpd, int m, int x0, int y0, int x1, int y1
return -1;
if (x != x1 && y != y1)
{
- if (!can_move(md, x, y, x + dx, y + dy, flag))
+ if (!can_move(md, x, y, x + dx, y + dy))
break;
x += dx;
y += dy;
@@ -261,14 +253,14 @@ int path_search(struct walkpath_data *wpd, int m, int x0, int y0, int x1, int y1
}
else if (x != x1)
{
- if (!can_move(md, x, y, x + dx, y, flag))
+ if (!can_move(md, x, y, x + dx, y))
break;
x += dx;
wpd->path[i++] = (dx < 0) ? DIR::W : DIR::E;
}
else
{ // y!=y1
- if (!can_move(md, x, y, x, y + dy, flag))
+ if (!can_move(md, x, y, x, y + dy))
break;
y += dy;
wpd->path[i++] = (dy > 0) ? DIR::S : DIR::N;
@@ -321,21 +313,21 @@ int path_search(struct walkpath_data *wpd, int m, int x0, int y0, int x1, int y1
return 0;
}
- if (can_move(md, x, y, x + 1, y - 1, flag))
+ if (can_move(md, x, y, x + 1, y - 1))
e += add_path(heap, tp, x + 1, y - 1, tp[rp].dist + 14, DIR::NE, rp, x1, y1);
- if (can_move(md, x, y, x + 1, y, flag))
+ if (can_move(md, x, y, x + 1, y))
e += add_path(heap, tp, x + 1, y, tp[rp].dist + 10, DIR::E, rp, x1, y1);
- if (can_move(md, x, y, x + 1, y + 1, flag))
+ if (can_move(md, x, y, x + 1, y + 1))
e += add_path(heap, tp, x + 1, y + 1, tp[rp].dist + 14, DIR::SE, rp, x1, y1);
- if (can_move(md, x, y, x, y + 1, flag))
+ if (can_move(md, x, y, x, y + 1))
e += add_path(heap, tp, x, y + 1, tp[rp].dist + 10, DIR::S, rp, x1, y1);
- if (can_move(md, x, y, x - 1, y + 1, flag))
+ if (can_move(md, x, y, x - 1, y + 1))
e += add_path(heap, tp, x - 1, y + 1, tp[rp].dist + 14, DIR::SW, rp, x1, y1);
- if (can_move(md, x, y, x - 1, y, flag))
+ if (can_move(md, x, y, x - 1, y))
e += add_path(heap, tp, x - 1, y, tp[rp].dist + 10, DIR::W, rp, x1, y1);
- if (can_move(md, x, y, x - 1, y - 1, flag))
+ if (can_move(md, x, y, x - 1, y - 1))
e += add_path(heap, tp, x - 1, y - 1, tp[rp].dist + 14, DIR::NW, rp, x1, y1);
- if (can_move(md, x, y, x, y - 1, flag))
+ if (can_move(md, x, y, x, y - 1))
e += add_path(heap, tp, x, y - 1, tp[rp].dist + 10, DIR::N, rp, x1, y1);
tp[rp].flag = 1;
if (e || heap[0] >= MAX_HEAP - 5)
diff --git a/src/map/pc.cpp b/src/map/pc.cpp
index 4eb49e3..8a4a98f 100644
--- a/src/map/pc.cpp
+++ b/src/map/pc.cpp
@@ -2364,7 +2364,7 @@ int pc_setpos(struct map_session_data *sd, const char *mapname_org, int x, int y
BeingRemoveWhy clrtype)
{
char mapname[24];
- int m = 0, c = 0;
+ int m = 0;
nullpo_ret(sd);
@@ -2432,7 +2432,8 @@ int pc_setpos(struct map_session_data *sd, const char *mapname_org, int x, int y
if (x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys)
x = y = 0;
- if ((x == 0 && y == 0) || (c = read_gat(m, x, y)) == 1 || c == 5)
+ if ((x == 0 && y == 0)
+ || bool(read_gat(m, x, y) & MapCell::UNWALKABLE))
{
if (x || y)
{
@@ -2444,7 +2445,7 @@ int pc_setpos(struct map_session_data *sd, const char *mapname_org, int x, int y
x = random_::in(1, map[m].xs - 2);
y = random_::in(1, map[m].ys - 2);
}
- while ((c = read_gat(m, x, y)) == 1 || c == 5);
+ while (bool(read_gat(m, x, y) & MapCell::UNWALKABLE));
}
if (sd->mapname[0] && sd->bl.prev != NULL)
@@ -2477,7 +2478,7 @@ int pc_setpos(struct map_session_data *sd, const char *mapname_org, int x, int y
*/
int pc_randomwarp(struct map_session_data *sd, BeingRemoveWhy type)
{
- int x, y, c, i = 0;
+ int x, y, i = 0;
int m;
nullpo_ret(sd);
@@ -2492,7 +2493,8 @@ int pc_randomwarp(struct map_session_data *sd, BeingRemoveWhy type)
x = random_::in(1, map[m].xs - 2);
y = random_::in(1, map[m].ys - 2);
}
- while (((c = read_gat(m, x, y)) == 1 || c == 5) && (i++) < 1000);
+ while (bool(read_gat(m, x, y) & MapCell::UNWALKABLE)
+ && (i++) < 1000);
if (i < 1000)
pc_setpos(sd, map[m].name, x, y, type);
@@ -2550,7 +2552,6 @@ static
void pc_walk(TimerData *tid, tick_t tick, int id, unsigned char data)
{
struct map_session_data *sd;
- int ctype;
int moveblock;
int x, y, dx, dy;
@@ -2581,8 +2582,7 @@ void pc_walk(TimerData *tid, tick_t tick, int id, unsigned char data)
x = sd->bl.x;
y = sd->bl.y;
- ctype = map_getcell(sd->bl.m, x, y);
- if (ctype == 1 || ctype == 5)
+ if (bool(map_getcell(sd->bl.m, x, y) & MapCell::UNWALKABLE))
{
pc_stop_walking(sd, 1);
return;
@@ -2590,8 +2590,8 @@ void pc_walk(TimerData *tid, tick_t tick, int id, unsigned char data)
sd->dir = sd->head_dir = sd->walkpath.path[sd->walkpath.path_pos];
dx = dirx[sd->dir];
dy = diry[sd->dir];
- ctype = map_getcell(sd->bl.m, x + dx, y + dy);
- if (ctype == 1 || ctype == 5)
+ if (bool(map_getcell(sd->bl.m, x + dx, y + dy)
+ & MapCell::UNWALKABLE))
{
pc_walktoxy_sub(sd);
return;
@@ -2648,7 +2648,7 @@ void pc_walk(TimerData *tid, tick_t tick, int id, unsigned char data)
break;
}
- if (map_getcell(sd->bl.m, x, y) & 0x80)
+ if (bool(map_getcell(sd->bl.m, x, y) & MapCell::NPC_NEAR))
npc_touch_areanpc(sd, sd->bl.m, x, y);
else
sd->areanpc_id = 0;
@@ -2756,7 +2756,7 @@ int pc_stop_walking(struct map_session_data *sd, int type)
void pc_touch_all_relevant_npcs(struct map_session_data *sd)
{
- if (map_getcell(sd->bl.m, sd->bl.x, sd->bl.y) & 0x80)
+ if (bool(map_getcell(sd->bl.m, sd->bl.x, sd->bl.y) & MapCell::NPC_NEAR))
npc_touch_areanpc(sd, sd->bl.m, sd->bl.x, sd->bl.y);
else
sd->areanpc_id = 0;