summaryrefslogtreecommitdiff
path: root/src/map/map.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/map.cpp')
-rw-r--r--src/map/map.cpp1629
1 files changed, 638 insertions, 991 deletions
diff --git a/src/map/map.cpp b/src/map/map.cpp
index af49ad4..a3f600a 100644
--- a/src/map/map.cpp
+++ b/src/map/map.cpp
@@ -1,89 +1,103 @@
-// $Id: map.c,v 1.6 2004/09/25 17:37:01 MouseJstr Exp $
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#ifdef LCCWIN32
-#include <winsock.h>
-#else
+#include "map.hpp"
+
+#include <sys/time.h>
+#include <sys/wait.h>
+
#include <netdb.h>
-#endif
+#include <unistd.h>
+
+#include <cassert>
+#include <cstdlib>
+#include <cstring>
+
+#include <fstream>
#include "../common/core.hpp"
-#include "../common/timer.hpp"
+#include "../common/cxxstdio.hpp"
#include "../common/db.hpp"
-#include "../common/grfio.hpp"
-#include "../common/mt_rand.hpp"
-#include "map.hpp"
+#include "../common/random2.hpp"
+#include "../common/nullpo.hpp"
+#include "../common/socket.hpp"
+#include "../common/timer.hpp"
+
+#include "atcommand.hpp"
+#include "battle.hpp"
+#include "chat.hpp"
#include "chrif.hpp"
#include "clif.hpp"
-#include "intif.hpp"
+#include "grfio.hpp"
+#include "itemdb.hpp"
+#include "magic.hpp"
+#include "mob.hpp"
#include "npc.hpp"
+#include "party.hpp"
#include "pc.hpp"
-#include "mob.hpp"
-#include "chat.hpp"
-#include "itemdb.hpp"
-#include "storage.hpp"
+#include "script.hpp"
#include "skill.hpp"
+#include "storage.hpp"
#include "trade.hpp"
-#include "party.hpp"
-#include "battle.hpp"
-#include "script.hpp"
-#include "guild.hpp"
-#include "atcommand.hpp"
-#include "../common/nullpo.hpp"
-#include "../common/socket.hpp"
-#include "magic.hpp"
-
-#ifdef MEMWATCH
-#include "memwatch.hpp"
-#endif
-
-// 極力 staticでローカルに収める
-static struct dbt *id_db = NULL;
-static struct dbt *map_db = NULL;
-static struct dbt *nick_db = NULL;
-static struct dbt *charid_db = NULL;
-
-static int users = 0;
-static struct block_list *object[MAX_FLOORITEM];
-static int first_free_object_id = 0, last_object_id = 0;
-
-#define block_free_max 1048576
-static void *block_free[block_free_max];
-static int block_free_count = 0, block_free_lock = 0;
-#define BL_LIST_MAX 1048576
-static struct block_list *bl_list[BL_LIST_MAX];
-static int bl_list_count = 0;
+#include "../poison.hpp"
-struct map_data map[MAX_MAP_PER_SERVER];
-int map_num = 0;
+DMap<int, struct block_list *> id_db;
-int map_port = 0;
+static
+DMap<std::string, struct map_data *> map_db;
-int autosave_interval = DEFAULT_AUTOSAVE_INTERVAL;
-int save_settings = 0xFFFF;
-int agit_flag = 0;
-int night_flag = 0; // 0=day, 1=night [Yor]
+static
+DMap<std::string, struct map_session_data *> nick_db;
struct charid2nick
{
char nick[24];
- int req_id;
+ int req_id;
};
+static
+Map<int, struct charid2nick> charid_db;
+
+static
+int users = 0;
+static
+struct block_list *object[MAX_FLOORITEM];
+static
+int first_free_object_id = 0, last_object_id = 0;
+
+constexpr int block_free_max = 1048576;
+static
+void *block_free[block_free_max];
+static
+int block_free_count = 0, block_free_lock = 0;
+
+constexpr int BL_LIST_MAX = 1048576;
+static
+struct block_list *bl_list[BL_LIST_MAX];
+static
+int bl_list_count = 0;
+
+struct map_data map[MAX_MAP_PER_SERVER];
+int map_num = 0;
+
+static
+int map_port = 0;
+
+interval_t autosave_interval = DEFAULT_AUTOSAVE_INTERVAL;
+int save_settings = 0xFFFF;
+
char motd_txt[256] = "conf/motd.txt";
char help_txt[256] = "conf/help.txt";
char wisp_server_name[24] = "Server"; // can be modified in char-server configuration file
+static
+int map_delmap(const char *mapname);
+
/*==========================================
* 全map鯖総計での接続数設定
* (char鯖から送られてくる)
*------------------------------------------
*/
-void map_setusers (int n)
+void map_setusers(int n)
{
users = n;
}
@@ -92,7 +106,7 @@ void map_setusers (int n)
* 全map鯖総計での接続数取得 (/wへの応答用)
*------------------------------------------
*/
-int map_getusers (void)
+int map_getusers(void)
{
return users;
}
@@ -106,11 +120,11 @@ int map_getusers (void)
* ロックされているときはバッファにためる
*------------------------------------------
*/
-int map_freeblock (void *bl)
+int map_freeblock(void *bl)
{
if (block_free_lock == 0)
{
- free (bl);
+ free(bl);
bl = NULL;
}
else
@@ -118,8 +132,7 @@ int map_freeblock (void *bl)
if (block_free_count >= block_free_max)
{
if (battle_config.error_log)
- printf
- ("map_freeblock: *WARNING* too many free block! %d %d\n",
+ PRINTF("map_freeblock: *WARNING* too many free block! %d %d\n",
block_free_count, block_free_lock);
}
else
@@ -132,7 +145,7 @@ int map_freeblock (void *bl)
* blockのfreeを一時的に禁止する
*------------------------------------------
*/
-int map_freeblock_lock (void)
+int map_freeblock_lock(void)
{
return ++block_free_lock;
}
@@ -143,18 +156,18 @@ int map_freeblock_lock (void)
* バッファにたまっていたblockを全部削除
*------------------------------------------
*/
-int map_freeblock_unlock (void)
+int map_freeblock_unlock(void)
{
if ((--block_free_lock) == 0)
{
- int i;
+ int i;
// if(block_free_count>0) {
// if(battle_config.error_log)
-// printf("map_freeblock_unlock: free %d object\n",block_free_count);
+// PRINTF("map_freeblock_unlock: free %d object\n",block_free_count);
// }
for (i = 0; i < block_free_count; i++)
{
- free (block_free[i]);
+ free(block_free[i]);
block_free[i] = NULL;
}
block_free_count = 0;
@@ -162,20 +175,16 @@ int map_freeblock_unlock (void)
else if (block_free_lock < 0)
{
if (battle_config.error_log)
- printf ("map_freeblock_unlock: lock count < 0 !\n");
+ PRINTF("map_freeblock_unlock: lock count < 0 !\n");
}
return block_free_lock;
}
-//
-// block化処理
-//
-/*==========================================
- * map[]のblock_listから繋がっている場合に
- * bl->prevにbl_headのアドレスを入れておく
- *------------------------------------------
- */
-static struct block_list bl_head;
+/// This is a dummy entry that is shared by all the linked lists,
+/// so that any entry can unlink itself without worrying about
+/// whether it was the the head of the list.
+static
+struct block_list bl_head;
/*==========================================
* map[]のblock_listに追加
@@ -184,16 +193,16 @@ static struct block_list bl_head;
* 既にlink済みかの確認が無い。危険かも
*------------------------------------------
*/
-int map_addblock (struct block_list *bl)
+int map_addblock(struct block_list *bl)
{
- int m, x, y;
+ int m, x, y;
- nullpo_retr (0, bl);
+ nullpo_ret(bl);
if (bl->prev != NULL)
{
if (battle_config.error_log)
- printf ("map_addblock error : bl->prev!=NULL\n");
+ PRINTF("map_addblock error : bl->prev!=NULL\n");
return 0;
}
@@ -204,7 +213,7 @@ int map_addblock (struct block_list *bl)
x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys)
return 1;
- if (bl->type == BL_MOB)
+ if (bl->type == BL::MOB)
{
bl->next =
map[m].block_mob[x / BLOCK_SIZE + (y / BLOCK_SIZE) * map[m].bxs];
@@ -224,7 +233,7 @@ int map_addblock (struct block_list *bl)
bl->next->prev = bl;
map[m].block[x / BLOCK_SIZE + (y / BLOCK_SIZE) * map[m].bxs] = bl;
map[m].block_count[x / BLOCK_SIZE + (y / BLOCK_SIZE) * map[m].bxs]++;
- if (bl->type == BL_PC)
+ if (bl->type == BL::PC)
map[m].users++;
}
@@ -236,10 +245,10 @@ int map_addblock (struct block_list *bl)
* prevがNULLの場合listに繋がってない
*------------------------------------------
*/
-int map_delblock (struct block_list *bl)
+int map_delblock(struct block_list *bl)
{
- int b;
- nullpo_retr (0, bl);
+ int b;
+ nullpo_ret(bl);
// 既にblocklistから抜けている
if (bl->prev == NULL)
@@ -248,14 +257,14 @@ int map_delblock (struct block_list *bl)
{
// prevがNULLでnextがNULLでないのは有ってはならない
if (battle_config.error_log)
- printf ("map_delblock error : bl->next!=NULL\n");
+ PRINTF("map_delblock error : bl->next!=NULL\n");
}
return 0;
}
b = bl->x / BLOCK_SIZE + (bl->y / BLOCK_SIZE) * map[bl->m].bxs;
- if (bl->type == BL_PC)
+ if (bl->type == BL::PC)
map[bl->m].users--;
if (bl->next)
@@ -263,7 +272,7 @@ int map_delblock (struct block_list *bl)
if (bl->prev == &bl_head)
{
// リストの頭なので、map[]のblock_listを更新する
- if (bl->type == BL_MOB)
+ if (bl->type == BL::MOB)
{
map[bl->m].block_mob[b] = bl->next;
if ((map[bl->m].block_mob_count[b]--) < 0)
@@ -287,47 +296,15 @@ int map_delblock (struct block_list *bl)
}
/*==========================================
- * 周囲のPC人数を数える (現在未使用)
- *------------------------------------------
- */
-int map_countnearpc (int m, int x, int y)
-{
- int bx, by, c = 0;
- struct block_list *bl = NULL;
-
- if (map[m].users == 0)
- return 0;
- for (by = y / BLOCK_SIZE - AREA_SIZE / BLOCK_SIZE - 1;
- by <= y / BLOCK_SIZE + AREA_SIZE / BLOCK_SIZE + 1; by++)
- {
- if (by < 0 || by >= map[m].bys)
- continue;
- for (bx = x / BLOCK_SIZE - AREA_SIZE / BLOCK_SIZE - 1;
- bx <= x / BLOCK_SIZE + AREA_SIZE / BLOCK_SIZE + 1; bx++)
- {
- if (bx < 0 || bx >= map[m].bxs)
- continue;
- bl = map[m].block[bx + by * map[m].bxs];
- for (; bl; bl = bl->next)
- {
- if (bl->type == BL_PC)
- c++;
- }
- }
- }
- return c;
-}
-
-/*==========================================
* セル上のPCとMOBの数を数える (グランドクロス用)
*------------------------------------------
*/
-int map_count_oncell (int m, int x, int y)
+int map_count_oncell(int m, int x, int y)
{
- int bx, by;
+ int bx, by;
struct block_list *bl = NULL;
- int i, c;
- int count = 0;
+ int i, c;
+ int count = 0;
if (x < 0 || y < 0 || (x >= map[m].xs) || (y >= map[m].ys))
return 1;
@@ -338,7 +315,7 @@ int map_count_oncell (int m, int x, int y)
c = map[m].block_count[bx + by * map[m].bxs];
for (i = 0; i < c && bl; i++, bl = bl->next)
{
- if (bl->x == x && bl->y == y && bl->type == BL_PC)
+ if (bl->x == x && bl->y == y && bl->type == BL::PC)
count++;
}
bl = map[m].block_mob[bx + by * map[m].bxs];
@@ -359,17 +336,17 @@ int map_count_oncell (int m, int x, int y)
* type!=0 ならその種類のみ
*------------------------------------------
*/
-void map_foreachinarea (int (*func) (struct block_list *, va_list), int m,
- int x0, int y0, int x1, int y1, int type, ...)
+void map_foreachinarea(std::function<void(struct block_list *)> func,
+ int m,
+ int x0, int y0, int x1, int y1,
+ BL type)
{
- int bx, by;
+ int bx, by;
struct block_list *bl = NULL;
- va_list ap = NULL;
- int blockcount = bl_list_count, i, c;
+ int blockcount = bl_list_count, i, c;
if (m < 0)
return;
- va_start (ap, type);
if (x0 < 0)
x0 = 0;
if (y0 < 0)
@@ -378,7 +355,7 @@ void map_foreachinarea (int (*func) (struct block_list *, va_list), int m,
x1 = map[m].xs - 1;
if (y1 >= map[m].ys)
y1 = map[m].ys - 1;
- if (type == 0 || type != BL_MOB)
+ if (type == BL::NUL || type != BL::MOB)
for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++)
{
for (bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++)
@@ -387,7 +364,7 @@ void map_foreachinarea (int (*func) (struct block_list *, va_list), int m,
c = map[m].block_count[bx + by * map[m].bxs];
for (i = 0; i < c && bl; i++, bl = bl->next)
{
- if (bl && type && bl->type != type)
+ if (bl && type != BL::NUL && bl->type != type)
continue;
if (bl && bl->x >= x0 && bl->x <= x1 && bl->y >= y0
&& bl->y <= y1 && bl_list_count < BL_LIST_MAX)
@@ -395,7 +372,7 @@ void map_foreachinarea (int (*func) (struct block_list *, va_list), int m,
}
}
}
- if (type == 0 || type == BL_MOB)
+ if (type == BL::NUL || type == BL::MOB)
for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++)
{
for (bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++)
@@ -414,18 +391,17 @@ void map_foreachinarea (int (*func) (struct block_list *, va_list), int m,
if (bl_list_count >= BL_LIST_MAX)
{
if (battle_config.error_log)
- printf ("map_foreachinarea: *WARNING* block count too many!\n");
+ PRINTF("map_foreachinarea: *WARNING* block count too many!\n");
}
- map_freeblock_lock (); // メモリからの解放を禁止する
+ map_freeblock_lock(); // メモリからの解放を禁止する
for (i = blockcount; i < bl_list_count; i++)
if (bl_list[i]->prev) // 有効かどうかチェック
- func (bl_list[i], ap);
+ func(bl_list[i]);
- map_freeblock_unlock (); // 解放を許可する
+ map_freeblock_unlock(); // 解放を許可する
- va_end (ap);
bl_list_count = blockcount;
}
@@ -437,16 +413,16 @@ void map_foreachinarea (int (*func) (struct block_list *, va_list), int m,
* dx,dyは-1,0,1のみとする(どんな値でもいいっぽい?)
*------------------------------------------
*/
-void map_foreachinmovearea (int (*func) (struct block_list *, va_list), int m,
- int x0, int y0, int x1, int y1, int dx, int dy,
- int type, ...)
+void map_foreachinmovearea(std::function<void(struct block_list *)> func,
+ int m,
+ int x0, int y0, int x1, int y1,
+ int dx, int dy,
+ BL type)
{
- int bx, by;
+ int bx, by;
struct block_list *bl = NULL;
- va_list ap = NULL;
- int blockcount = bl_list_count, i, c;
+ int blockcount = bl_list_count, i, c;
- va_start (ap, type);
if (dx == 0 || dy == 0)
{
// 矩形領域の場合
@@ -488,7 +464,7 @@ void map_foreachinmovearea (int (*func) (struct block_list *, va_list), int m,
c = map[m].block_count[bx + by * map[m].bxs];
for (i = 0; i < c && bl; i++, bl = bl->next)
{
- if (bl && type && bl->type != type)
+ if (bl && type != BL::NUL && bl->type != type)
continue;
if (bl && bl->x >= x0 && bl->x <= x1 && bl->y >= y0
&& bl->y <= y1 && bl_list_count < BL_LIST_MAX)
@@ -498,7 +474,7 @@ void map_foreachinmovearea (int (*func) (struct block_list *, va_list), int m,
c = map[m].block_mob_count[bx + by * map[m].bxs];
for (i = 0; i < c && bl; i++, bl = bl->next)
{
- if (bl && type && bl->type != type)
+ if (bl && type != BL::NUL && bl->type != type)
continue;
if (bl && bl->x >= x0 && bl->x <= x1 && bl->y >= y0
&& bl->y <= y1 && bl_list_count < BL_LIST_MAX)
@@ -527,7 +503,7 @@ void map_foreachinmovearea (int (*func) (struct block_list *, va_list), int m,
c = map[m].block_count[bx + by * map[m].bxs];
for (i = 0; i < c && bl; i++, bl = bl->next)
{
- if (bl && type && bl->type != type)
+ if (bl && type != BL::NUL && bl->type != type)
continue;
if ((bl)
&& !(bl->x >= x0 && bl->x <= x1 && bl->y >= y0
@@ -546,7 +522,7 @@ void map_foreachinmovearea (int (*func) (struct block_list *, va_list), int m,
c = map[m].block_mob_count[bx + by * map[m].bxs];
for (i = 0; i < c && bl; i++, bl = bl->next)
{
- if (bl && type && bl->type != type)
+ if (bl && type != BL::NUL && bl->type != type)
continue;
if ((bl)
&& !(bl->x >= x0 && bl->x <= x1 && bl->y >= y0
@@ -569,18 +545,17 @@ void map_foreachinmovearea (int (*func) (struct block_list *, va_list), int m,
if (bl_list_count >= BL_LIST_MAX)
{
if (battle_config.error_log)
- printf ("map_foreachinarea: *WARNING* block count too many!\n");
+ PRINTF("map_foreachinarea: *WARNING* block count too many!\n");
}
- map_freeblock_lock (); // メモリからの解放を禁止する
+ map_freeblock_lock(); // メモリからの解放を禁止する
for (i = blockcount; i < bl_list_count; i++)
if (bl_list[i]->prev) // 有効かどうかチェック
- func (bl_list[i], ap);
+ func(bl_list[i]);
- map_freeblock_unlock (); // 解放を許可する
+ map_freeblock_unlock(); // 解放を許可する
- va_end (ap);
bl_list_count = blockcount;
}
@@ -588,33 +563,32 @@ void map_foreachinmovearea (int (*func) (struct block_list *, va_list), int m,
// which only checks the exact single x/y passed to it rather than an
// area radius - may be more useful in some instances)
//
-void map_foreachincell (int (*func) (struct block_list *, va_list), int m,
- int x, int y, int type, ...)
+void map_foreachincell(std::function<void(struct block_list *)> func,
+ int m,
+ int x, int y,
+ BL type)
{
- int bx, by;
+ int bx, by;
struct block_list *bl = NULL;
- va_list ap = NULL;
- int blockcount = bl_list_count, i, c;
-
- va_start (ap, type);
+ int blockcount = bl_list_count, i, c;
by = y / BLOCK_SIZE;
bx = x / BLOCK_SIZE;
- if (type == 0 || type != BL_MOB)
+ if (type == BL::NUL || type != BL::MOB)
{
bl = map[m].block[bx + by * map[m].bxs];
c = map[m].block_count[bx + by * map[m].bxs];
for (i = 0; i < c && bl; i++, bl = bl->next)
{
- if (type && bl && bl->type != type)
+ if (type != BL::NUL && bl && bl->type != type)
continue;
if (bl && bl->x == x && bl->y == y && bl_list_count < BL_LIST_MAX)
bl_list[bl_list_count++] = bl;
}
}
- if (type == 0 || type == BL_MOB)
+ if (type == BL::NUL || type == BL::MOB)
{
bl = map[m].block_mob[bx + by * map[m].bxs];
c = map[m].block_mob_count[bx + by * map[m].bxs];
@@ -628,18 +602,17 @@ void map_foreachincell (int (*func) (struct block_list *, va_list), int m,
if (bl_list_count >= BL_LIST_MAX)
{
if (battle_config.error_log)
- printf ("map_foreachincell: *WARNING* block count too many!\n");
+ PRINTF("map_foreachincell: *WARNING* block count too many!\n");
}
- map_freeblock_lock (); // メモリからの解放を禁止する
+ map_freeblock_lock(); // メモリからの解放を禁止する
for (i = blockcount; i < bl_list_count; i++)
if (bl_list[i]->prev) // 有効かどうかチェック
- func (bl_list[i], ap);
+ func(bl_list[i]);
- map_freeblock_unlock (); // 解放を許可する
+ map_freeblock_unlock(); // 解放を許可する
- va_end (ap);
bl_list_count = blockcount;
}
@@ -650,12 +623,12 @@ void map_foreachincell (int (*func) (struct block_list *, va_list), int m,
* bl->idもこの中で設定して問題無い?
*------------------------------------------
*/
-int map_addobject (struct block_list *bl)
+int map_addobject(struct block_list *bl)
{
- int i;
+ int i;
if (bl == NULL)
{
- printf ("map_addobject nullpo?\n");
+ PRINTF("map_addobject nullpo?\n");
return 0;
}
if (first_free_object_id < 2 || first_free_object_id >= MAX_FLOORITEM)
@@ -666,36 +639,37 @@ int map_addobject (struct block_list *bl)
if (i >= MAX_FLOORITEM)
{
if (battle_config.error_log)
- printf ("no free object id\n");
+ PRINTF("no free object id\n");
return 0;
}
first_free_object_id = i;
if (last_object_id < i)
last_object_id = i;
object[i] = bl;
- numdb_insert (id_db, i, bl);
+ id_db.put(i, bl);
return i;
}
/*==========================================
* 一時objectの解放
- * map_delobjectのfreeしないバージョン
+ * map_delobjectのfreeしないバージョン
*------------------------------------------
*/
-int map_delobjectnofree (int id, int type)
+int map_delobjectnofree(int id, BL type)
{
if (object[id] == NULL)
return 0;
if (object[id]->type != type)
{
- fprintf (stderr, "Incorrect type: expected %d, got %d\n", type,
- object[id]->type);
- *((char *) 0) = 0; // break for backtrace
+ FPRINTF(stderr, "Incorrect type: expected %d, got %d\n",
+ type,
+ object[id]->type);
+ abort();
}
- map_delblock (object[id]);
- numdb_erase (id_db, id);
+ map_delblock(object[id]);
+ id_db.put(id, nullptr);
// map_freeblock(object[id]);
object[id] = NULL;
@@ -716,18 +690,18 @@ int map_delobjectnofree (int id, int type)
* addとの対称性が無いのが気になる
*------------------------------------------
*/
-int map_delobject (int id, int type)
+int map_delobject(int id, BL type)
{
struct block_list *obj = object[id];
if (obj == NULL)
return 0;
- map_delobjectnofree (id, type);
- if (obj->type == BL_PC) // [Fate] Not sure where else to put this... I'm not sure where delobject for PCs is called from
- pc_cleanup ((struct map_session_data *) obj);
+ map_delobjectnofree(id, type);
+ if (obj->type == BL::PC) // [Fate] Not sure where else to put this... I'm not sure where delobject for PCs is called from
+ pc_cleanup((struct map_session_data *) obj);
- map_freeblock (obj);
+ map_freeblock(obj);
return 0;
}
@@ -737,40 +711,36 @@ int map_delobject (int id, int type)
*
*------------------------------------------
*/
-void map_foreachobject (int (*func) (struct block_list *, va_list), int type,
- ...)
+void map_foreachobject(std::function<void(struct block_list *)> func,
+ BL type)
{
- int i;
- int blockcount = bl_list_count;
- va_list ap = NULL;
-
- va_start (ap, type);
+ int i;
+ int blockcount = bl_list_count;
for (i = 2; i <= last_object_id; i++)
{
if (object[i])
{
- if (type && object[i]->type != type)
+ if (type != BL::NUL && object[i]->type != type)
continue;
if (bl_list_count >= BL_LIST_MAX)
{
if (battle_config.error_log)
- printf ("map_foreachobject: too many block !\n");
+ PRINTF("map_foreachobject: too many block !\n");
}
else
bl_list[bl_list_count++] = object[i];
}
}
- map_freeblock_lock ();
+ map_freeblock_lock();
for (i = blockcount; i < bl_list_count; i++)
if (bl_list[i]->prev || bl_list[i]->next)
- func (bl_list[i], ap);
+ func(bl_list[i]);
- map_freeblock_unlock ();
+ map_freeblock_unlock();
- va_end (ap);
bl_list_count = blockcount;
}
@@ -784,73 +754,41 @@ void map_foreachobject (int (*func) (struct block_list *, va_list), int type,
* map.h内で#defineしてある
*------------------------------------------
*/
-void map_clearflooritem_timer (timer_id tid, tick_t tick, custom_id_t id, custom_data_t data)
+void map_clearflooritem_timer(TimerData *tid, tick_t, int id)
{
struct flooritem_data *fitem = NULL;
fitem = (struct flooritem_data *) object[id];
- if (fitem == NULL || fitem->bl.type != BL_ITEM
- || (!data && fitem->cleartimer != tid))
+ if (fitem == NULL || fitem->bl.type != BL::ITEM)
{
if (battle_config.error_log)
- printf ("map_clearflooritem_timer : error\n");
+ PRINTF("map_clearflooritem_timer : error\n");
return;
}
- if (data)
- delete_timer (fitem->cleartimer, map_clearflooritem_timer);
- clif_clearflooritem (fitem, 0);
- map_delobject (fitem->bl.id, BL_ITEM);
+ if (!tid)
+ fitem->cleartimer.cancel();
+ clif_clearflooritem(fitem, 0);
+ map_delobject(fitem->bl.id, BL::ITEM);
}
-/*==========================================
- * (m,x,y)の周囲rangeマス内の空き(=侵入可能)cellの
- * 内から適当なマス目の座標をx+(y<<16)で返す
- *
- * 現状range=1でアイテムドロップ用途のみ
- *------------------------------------------
- */
-int map_searchrandfreecell (int m, int x, int y, int range)
+std::pair<uint16_t, uint16_t> map_randfreecell(int m, uint16_t x, uint16_t y, uint16_t w, uint16_t h)
{
- int free_cell, i, j, c;
-
- for (free_cell = 0, i = -range; i <= range; i++)
- {
- if (i + y < 0 || i + y >= map[m].ys)
- continue;
- for (j = -range; j <= range; j++)
- {
- if (j + x < 0 || j + x >= map[m].xs)
- continue;
- if ((c = read_gat (m, j + x, i + y)) == 1 || c == 5)
- continue;
- free_cell++;
- }
- }
- if (free_cell == 0)
- return -1;
- free_cell = MRAND (free_cell);
- for (i = -range; i <= range; i++)
+ for (int itr : random_::iterator(w * h))
{
- if (i + y < 0 || i + y >= map[m].ys)
- continue;
- for (j = -range; j <= range; j++)
- {
- if (j + x < 0 || j + x >= map[m].xs)
- continue;
- if ((c = read_gat (m, j + x, i + y)) == 1 || c == 5)
- continue;
- if (free_cell == 0)
- {
- x += j;
- y += i;
- i = range + 1;
- break;
- }
- free_cell--;
- }
+ int dx = itr % w;
+ int dy = itr / w;
+ 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)};
+}
- return x + (y << 16);
+/// Return a randomly selected passable cell within a given range.
+static
+std::pair<uint16_t, uint16_t> map_searchrandfreecell(int m, int x, int y, int range)
+{
+ int whole_range = 2 * range + 1;
+ return map_randfreecell(m, x - range, y - range, whole_range, whole_range);
}
/*==========================================
@@ -859,41 +797,39 @@ int map_searchrandfreecell (int m, int x, int y, int range)
* item_dataはamount以外をcopyする
*------------------------------------------
*/
-int map_addflooritem_any (struct item *item_data, int amount, int m, int x,
- int y, struct map_session_data **owners,
- int *owner_protection, int lifetime, int dispersal)
+int map_addflooritem_any(struct item *item_data, int amount,
+ int m, int x, int y,
+ struct map_session_data **owners, interval_t *owner_protection,
+ interval_t lifetime, int dispersal)
{
- int xy, r;
- unsigned int tick;
struct flooritem_data *fitem = NULL;
- nullpo_retr (0, item_data);
-
- if ((xy = map_searchrandfreecell (m, x, y, dispersal)) < 0)
+ nullpo_ret(item_data);
+ auto xy = map_searchrandfreecell(m, x, y, dispersal);
+ if (xy.first == 0 && xy.second == 0)
return 0;
- r = mt_random ();
- CREATE (fitem, struct flooritem_data, 1);
- fitem->bl.type = BL_ITEM;
+ CREATE(fitem, struct flooritem_data, 1);
+ fitem->bl.type = BL::ITEM;
fitem->bl.prev = fitem->bl.next = NULL;
fitem->bl.m = m;
- fitem->bl.x = xy & 0xffff;
- fitem->bl.y = (xy >> 16) & 0xffff;
+ fitem->bl.x = xy.first;
+ fitem->bl.y = xy.second;
fitem->first_get_id = 0;
- fitem->first_get_tick = 0;
+ fitem->first_get_tick = tick_t();
fitem->second_get_id = 0;
- fitem->second_get_tick = 0;
+ fitem->second_get_tick = tick_t();
fitem->third_get_id = 0;
- fitem->third_get_tick = 0;
+ fitem->third_get_tick = tick_t();
- fitem->bl.id = map_addobject (&fitem->bl);
+ fitem->bl.id = map_addobject(&fitem->bl);
if (fitem->bl.id == 0)
{
- free (fitem);
+ free(fitem);
return 0;
}
- tick = gettick ();
+ tick_t tick = gettick();
if (owners[0])
fitem->first_get_id = owners[0]->bl.id;
@@ -907,189 +843,90 @@ int map_addflooritem_any (struct item *item_data, int amount, int m, int x,
fitem->third_get_id = owners[2]->bl.id;
fitem->third_get_tick = tick + owner_protection[2];
- memcpy (&fitem->item_data, item_data, sizeof (*item_data));
+ memcpy(&fitem->item_data, item_data, sizeof(*item_data));
fitem->item_data.amount = amount;
- fitem->subx = (r & 3) * 3 + 3;
- fitem->suby = ((r >> 2) & 3) * 3 + 3;
- fitem->cleartimer =
- add_timer (gettick () + lifetime, map_clearflooritem_timer,
- fitem->bl.id, 0);
-
- map_addblock (&fitem->bl);
- clif_dropflooritem (fitem);
+ // TODO - talk to 4144 about maybe removing this.
+ // It has no effect on the server itself, it is visual only.
+ // If it is desirable to prevent items from visibly stacking
+ // on the ground, that can be done with client-side randomness.
+ // Currently, it yields the numbers {3 6 9 12}.
+ fitem->subx = random_::in(1, 4) * 3;
+ fitem->suby = random_::in(1, 4) * 3;
+ fitem->cleartimer = Timer(gettick() + lifetime,
+ std::bind(map_clearflooritem_timer, ph::_1, ph::_2,
+ fitem->bl.id));
+
+ map_addblock(&fitem->bl);
+ clif_dropflooritem(fitem);
return fitem->bl.id;
}
-int map_addflooritem (struct item *item_data, int amount, int m, int x, int y,
- struct map_session_data *first_sd,
- struct map_session_data *second_sd,
- struct map_session_data *third_sd, int type)
+int map_addflooritem(struct item *item_data, int amount,
+ int m, int x, int y,
+ struct map_session_data *first_sd,
+ struct map_session_data *second_sd,
+ struct map_session_data *third_sd)
{
struct map_session_data *owners[3] = { first_sd, second_sd, third_sd };
- int owner_protection[3];
+ interval_t owner_protection[3];
- if (type)
- {
- owner_protection[0] = battle_config.mvp_item_first_get_time;
- owner_protection[1] =
- owner_protection[0] + battle_config.mvp_item_second_get_time;
- owner_protection[2] =
- owner_protection[1] + battle_config.mvp_item_third_get_time;
- }
- else
{
- owner_protection[0] = battle_config.item_first_get_time;
- owner_protection[1] =
- owner_protection[0] + battle_config.item_second_get_time;
- owner_protection[2] =
- owner_protection[1] + battle_config.item_third_get_time;
+ owner_protection[0] = static_cast<interval_t>(battle_config.item_first_get_time);
+ owner_protection[1] = owner_protection[0] + static_cast<interval_t>(battle_config.item_second_get_time);
+ owner_protection[2] = owner_protection[1] + static_cast<interval_t>(battle_config.item_third_get_time);
}
- return map_addflooritem_any (item_data, amount, m, x, y,
- owners, owner_protection,
- battle_config.flooritem_lifetime, 1);
+ return map_addflooritem_any(item_data, amount, m, x, y,
+ owners, owner_protection,
+ static_cast<interval_t>(battle_config.flooritem_lifetime), 1);
}
-/* int xy,r; */
-/* unsigned int tick; */
-/* struct flooritem_data *fitem=NULL; */
-
-/* nullpo_retr(0, item_data); */
-
-/* if((xy=map_searchrandfreecell(m,x,y,1))<0) */
-/* return 0; */
-/* r=rand(); */
-
-/* fitem = (struct flooritem_data *)aCalloc(1,sizeof(*fitem)); */
-/* fitem->bl.type=BL_ITEM; */
-/* fitem->bl.prev = fitem->bl.next = NULL; */
-/* fitem->bl.m=m; */
-/* fitem->bl.x=xy&0xffff; */
-/* fitem->bl.y=(xy>>16)&0xffff; */
-/* fitem->first_get_id = 0; */
-/* fitem->first_get_tick = 0; */
-/* fitem->second_get_id = 0; */
-/* fitem->second_get_tick = 0; */
-/* fitem->third_get_id = 0; */
-/* fitem->third_get_tick = 0; */
-
-/* fitem->bl.id = map_addobject(&fitem->bl); */
-/* if(fitem->bl.id==0){ */
-/* free(fitem); */
-/* return 0; */
-/* } */
-
-/* tick = gettick(); */
-/* if(first_sd) { */
-/* fitem->first_get_id = first_sd->bl.id; */
-/* if(type) */
-/* fitem->first_get_tick = tick + battle_config.mvp_item_first_get_time; */
-/* else */
-/* fitem->first_get_tick = tick + battle_config.item_first_get_time; */
-/* } */
-/* if(second_sd) { */
-/* fitem->second_get_id = second_sd->bl.id; */
-/* if(type) */
-/* fitem->second_get_tick = tick + battle_config.mvp_item_first_get_time + battle_config.mvp_item_second_get_time; */
-/* else */
-/* fitem->second_get_tick = tick + battle_config.item_first_get_time + battle_config.item_second_get_time; */
-/* } */
-/* if(third_sd) { */
-/* fitem->third_get_id = third_sd->bl.id; */
-/* if(type) */
-/* fitem->third_get_tick = tick + battle_config.mvp_item_first_get_time + battle_config.mvp_item_second_get_time + battle_config.mvp_item_third_get_time; */
-/* else */
-/* fitem->third_get_tick = tick + battle_config.item_first_get_time + battle_config.item_second_get_time + battle_config.item_third_get_time; */
-/* } */
-
-/* memcpy(&fitem->item_data,item_data,sizeof(*item_data)); */
-/* fitem->item_data.amount=amount; */
-/* fitem->subx=(r&3)*3+3; */
-/* fitem->suby=((r>>2)&3)*3+3; */
-/* fitem->cleartimer=add_timer(gettick()+battle_config.flooritem_lifetime,map_clearflooritem_timer,fitem->bl.id,0); */
-
-/* map_addblock(&fitem->bl); */
-/* clif_dropflooritem(fitem); */
-
-/* return fitem->bl.id; */
-/* } */
-
/*==========================================
* charid_dbへ追加(返信待ちがあれば返信)
*------------------------------------------
*/
-void map_addchariddb (int charid, const char *name)
+void map_addchariddb(int charid, const char *name)
{
- struct charid2nick *p = (struct charid2nick *)numdb_search (charid_db, charid);
+ struct charid2nick *p = charid_db.search(charid);
if (p == NULL)
- { // データベースにない
- CREATE (p, struct charid2nick, 1);
- p->req_id = 0;
- }
- else
- numdb_erase (charid_db, charid);
+ p = charid_db.init(charid);
- int req = p->req_id;
- memcpy (p->nick, name, 24);
+ memcpy(p->nick, name, 24);
p->req_id = 0;
- numdb_insert (charid_db, charid, p);
- if (req)
- { // 返信待ちがあれば返信
- struct map_session_data *sd = map_id2sd (req);
- if (sd != NULL)
- clif_solved_charname (sd, charid);
- }
-}
-
-/*==========================================
- * charid_dbへ追加(返信要求のみ)
- *------------------------------------------
- */
-int map_reqchariddb (struct map_session_data *sd, int charid)
-{
- nullpo_retr (0, sd);
-
- struct charid2nick *p = (struct charid2nick *)numdb_search (charid_db, charid);
- if (p != NULL) // データベースにすでにある
- return 0;
- CREATE (p, struct charid2nick, 1);
- p->req_id = sd->bl.id;
- numdb_insert (charid_db, charid, p);
- return 0;
}
/*==========================================
* id_dbへblを追加
*------------------------------------------
*/
-void map_addiddb (struct block_list *bl)
+void map_addiddb(struct block_list *bl)
{
- nullpo_retv (bl);
+ nullpo_retv(bl);
- numdb_insert (id_db, bl->id, bl);
+ id_db.put(bl->id, bl);
}
/*==========================================
* id_dbからblを削除
*------------------------------------------
*/
-void map_deliddb (struct block_list *bl)
+void map_deliddb(struct block_list *bl)
{
- nullpo_retv (bl);
+ nullpo_retv(bl);
- numdb_erase (id_db, bl->id);
+ id_db.put(bl->id, nullptr);
}
/*==========================================
* nick_dbへsdを追加
*------------------------------------------
*/
-void map_addnickdb (struct map_session_data *sd)
+void map_addnickdb(struct map_session_data *sd)
{
- nullpo_retv (sd);
+ nullpo_retv(sd);
- strdb_insert (nick_db, sd->status.name, sd);
+ nick_db.put(sd->status.name, sd);
}
/*==========================================
@@ -1098,79 +935,62 @@ void map_addnickdb (struct map_session_data *sd)
* quit処理の主体が違うような気もしてきた
*------------------------------------------
*/
-int map_quit (struct map_session_data *sd)
+void map_quit(struct map_session_data *sd)
{
- nullpo_retr (0, sd);
+ nullpo_retv(sd);
if (sd->chatID) // チャットから出る
- chat_leavechat (sd);
+ chat_leavechat(sd);
if (sd->trade_partner) // 取引を中断する
- trade_tradecancel (sd);
+ trade_tradecancel(sd);
if (sd->party_invite > 0) // パーティ勧誘を拒否する
- party_reply_invite (sd, sd->party_invite_account, 0);
-
- if (sd->guild_invite > 0) // ギルド勧誘を拒否する
- guild_reply_invite (sd, sd->guild_invite, 0);
- if (sd->guild_alliance > 0) // ギルド同盟勧誘を拒否する
- guild_reply_reqalliance (sd, sd->guild_alliance_account, 0);
+ party_reply_invite(sd, sd->party_invite_account, 0);
- party_send_logout (sd); // パーティのログアウトメッセージ送信
+ party_send_logout(sd); // パーティのログアウトメッセージ送信
- guild_send_memberinfoshort (sd, 0); // ギルドのログアウトメッセージ送信
+ pc_cleareventtimer(sd); // イベントタイマを破棄する
- pc_cleareventtimer (sd); // イベントタイマを破棄する
+ skill_castcancel(&sd->bl, 0); // 詠唱を中断する
+ skill_stop_dancing(&sd->bl, 1); // ダンス/演奏中断
- skill_castcancel (&sd->bl, 0); // 詠唱を中断する
- skill_stop_dancing (&sd->bl, 1); // ダンス/演奏中断
+ skill_status_change_clear(&sd->bl, 1); // ステータス異常を解除する
+ pc_stop_walking(sd, 0);
+ pc_stopattack(sd);
+ pc_delinvincibletimer(sd);
+ skill_gangsterparadise(sd, 0);
- if (sd->sc_data && sd->sc_data[SC_BERSERK].timer != -1) //バーサーク中の終了はHPを100に
- sd->status.hp = 100;
+ pc_calcstatus(sd, 4);
- skill_status_change_clear (&sd->bl, 1); // ステータス異常を解除する
- skill_clear_unitgroup (&sd->bl); // スキルユニットグループの削除
- skill_cleartimerskill (&sd->bl);
- pc_stop_walking (sd, 0);
- pc_stopattack (sd);
- pc_delinvincibletimer (sd);
- pc_delspiritball (sd, sd->spiritball, 1);
- skill_gangsterparadise (sd, 0);
+ clif_clearchar(&sd->bl, BeingRemoveWhy::QUIT);
- pc_calcstatus (sd, 4);
-
- clif_clearchar_area (&sd->bl, 2);
-
- if (pc_isdead (sd))
- pc_setrestartvalue (sd, 2);
- pc_makesavestatus (sd);
+ if (pc_isdead(sd))
+ pc_setrestartvalue(sd, 2);
+ pc_makesavestatus(sd);
//クローンスキルで覚えたスキルは消す
//The storage closing routines will save the char if needed. [Skotlex]
- if (!sd->state.storage_flag)
- chrif_save (sd);
- else if (sd->state.storage_flag == 1)
- storage_storage_quit (sd);
- else if (sd->state.storage_flag == 2)
- storage_guild_storage_quit (sd, 1);
+ if (!sd->state.storage_open)
+ chrif_save(sd);
+ else if (sd->state.storage_open)
+ storage_storage_quit(sd);
if (sd->npc_stackbuf && sd->npc_stackbuf != NULL)
- free (sd->npc_stackbuf);
-
- map_delblock (&sd->bl);
+ free(sd->npc_stackbuf);
- numdb_erase (id_db, sd->bl.id);
- strdb_erase (nick_db, sd->status.name);
- numdb_erase (charid_db, sd->status.char_id);
+ map_delblock(&sd->bl);
- return 0;
+ id_db.put(sd->bl.id, nullptr);
+ nick_db.put(sd->status.name, nullptr);
+ charid_db.erase(sd->status.char_id);
}
/*==========================================
* id番号のPCを探す。居なければNULL
*------------------------------------------
*/
-struct map_session_data *map_id2sd (int id)
+struct map_session_data *map_id2sd(int id)
{
// remove search from db, because:
// 1 - all players, npc, items and mob are in this db (to search, it's not speed, and search in session is more sure)
@@ -1179,14 +999,14 @@ struct map_session_data *map_id2sd (int id)
// replaced by searching in all session.
// by searching in session, we are sure that fd, session, and account exist.
/*
- struct block_list *bl;
+ struct block_list *bl;
- bl=numdb_search(id_db,id);
- if(bl && bl->type==BL_PC)
- return (struct map_session_data*)bl;
- return NULL;
+ bl=numdb_search(id_db,id);
+ if (bl && bl->type==BL::PC)
+ return (struct map_session_data*)bl;
+ return NULL;
*/
- int i;
+ int i;
struct map_session_data *sd = NULL;
for (i = 0; i < fd_max; i++)
@@ -1200,9 +1020,9 @@ struct map_session_data *map_id2sd (int id)
* char_id番号の名前を探す
*------------------------------------------
*/
-char *map_charid2nick (int id)
+char *map_charid2nick(int id)
{
- struct charid2nick *p = (struct charid2nick *)numdb_search (charid_db, id);
+ struct charid2nick *p = charid_db.search(id);
if (p == NULL)
return NULL;
@@ -1214,7 +1034,8 @@ char *map_charid2nick (int id)
/*========================================*/
/* [Fate] Operations to iterate over active map sessions */
-static struct map_session_data *map_get_session (int i)
+static
+struct map_session_data *map_get_session(int i)
{
struct map_session_data *d;
@@ -1225,12 +1046,13 @@ static struct map_session_data *map_get_session (int i)
return NULL;
}
-static struct map_session_data *map_get_session_forward (int start)
+static
+struct map_session_data *map_get_session_forward(int start)
{
- int i;
+ int i;
for (i = start; i < fd_max; i++)
{
- struct map_session_data *d = map_get_session (i);
+ struct map_session_data *d = map_get_session(i);
if (d)
return d;
}
@@ -1238,12 +1060,13 @@ static struct map_session_data *map_get_session_forward (int start)
return NULL;
}
-static struct map_session_data *map_get_session_backward (int start)
+static
+struct map_session_data *map_get_session_backward(int start)
{
- int i;
+ int i;
for (i = start; i >= 0; i--)
{
- struct map_session_data *d = map_get_session (i);
+ struct map_session_data *d = map_get_session(i);
if (d)
return d;
}
@@ -1251,24 +1074,24 @@ static struct map_session_data *map_get_session_backward (int start)
return NULL;
}
-struct map_session_data *map_get_first_session (void)
+struct map_session_data *map_get_first_session(void)
{
- return map_get_session_forward (0);
+ return map_get_session_forward(0);
}
-struct map_session_data *map_get_next_session (struct map_session_data *d)
+struct map_session_data *map_get_next_session(struct map_session_data *d)
{
- return map_get_session_forward (d->fd + 1);
+ return map_get_session_forward(d->fd + 1);
}
-struct map_session_data *map_get_last_session (void)
+struct map_session_data *map_get_last_session(void)
{
- return map_get_session_backward (fd_max);
+ return map_get_session_backward(fd_max);
}
-struct map_session_data *map_get_prev_session (struct map_session_data *d)
+struct map_session_data *map_get_prev_session(struct map_session_data *d)
{
- return map_get_session_backward (d->fd - 1);
+ return map_get_session_backward(d->fd - 1);
}
/*==========================================
@@ -1277,16 +1100,16 @@ struct map_session_data *map_get_prev_session (struct map_session_data *d)
* return map_session_data pointer or NULL
*------------------------------------------
*/
-struct map_session_data *map_nick2sd (const char *nick)
+struct map_session_data *map_nick2sd(const char *nick)
{
- int i, quantity = 0, nicklen;
+ int i, quantity = 0, nicklen;
struct map_session_data *sd = NULL;
struct map_session_data *pl_sd = NULL;
if (nick == NULL)
return NULL;
- nicklen = strlen (nick);
+ nicklen = strlen(nick);
for (i = 0; i < fd_max; i++)
{
@@ -1294,10 +1117,10 @@ struct map_session_data *map_nick2sd (const char *nick)
&& pl_sd->state.auth)
{
// Without case sensitive check (increase the number of similar character names found)
- if (strncasecmp (pl_sd->status.name, nick, nicklen) == 0)
+ if (strncasecmp(pl_sd->status.name, nick, nicklen) == 0)
{
// Strict comparison (if found, we finish the function immediatly with correct value)
- if (strcmp (pl_sd->status.name, nick) == 0)
+ if (strcmp(pl_sd->status.name, nick) == 0)
return pl_sd;
quantity++;
sd = pl_sd;
@@ -1318,38 +1141,24 @@ struct map_session_data *map_nick2sd (const char *nick)
* 一時objectの場合は配列を引くのみ
*------------------------------------------
*/
-struct block_list *map_id2bl (int id)
+struct block_list *map_id2bl(int id)
{
struct block_list *bl = NULL;
- if (id < sizeof (object) / sizeof (object[0]))
+ if (id < sizeof(object) / sizeof(object[0]))
bl = object[id];
else
- bl = (struct block_list *)numdb_search (id_db, id);
+ bl = id_db.get(id);
return bl;
}
/*==========================================
- * id_db内の全てにfuncを実行
- *------------------------------------------
- */
-int map_foreachiddb (db_func_t func, ...)
-{
- va_list ap = NULL;
-
- va_start (ap, func);
- numdb_foreach (id_db, func, ap);
- va_end (ap);
- return 0;
-}
-
-/*==========================================
* map.npcへ追加 (warp等の領域持ちのみ)
*------------------------------------------
*/
-int map_addnpc (int m, struct npc_data *nd)
+int map_addnpc(int m, struct npc_data *nd)
{
- int i;
+ int i;
if (m < 0 || m >= map_num)
return -1;
for (i = 0; i < map[m].npc_num && i < MAX_NPC_PER_MAP; i++)
@@ -1358,7 +1167,7 @@ int map_addnpc (int m, struct npc_data *nd)
if (i == MAX_NPC_PER_MAP)
{
if (battle_config.error_log)
- printf ("too many NPCs in one map %s\n", map[m].name);
+ PRINTF("too many NPCs in one map %s\n", map[m].name);
return -1;
}
if (i == map[m].npc_num)
@@ -1366,19 +1175,19 @@ int map_addnpc (int m, struct npc_data *nd)
map[m].npc_num++;
}
- nullpo_retr (0, nd);
+ nullpo_ret(nd);
map[m].npc[i] = nd;
nd->n = i;
- numdb_insert (id_db, nd->bl.id, nd);
+ id_db.put(nd->bl.id, (struct block_list *)nd);
return i;
}
static
-void map_removenpc (void)
+void map_removenpc(void)
{
- int i, m, n = 0;
+ int i, m, n = 0;
for (m = 0; m < map_num; m++)
{
@@ -1386,30 +1195,30 @@ void map_removenpc (void)
{
if (map[m].npc[i] != NULL)
{
- clif_clearchar_area (&map[m].npc[i]->bl, 2);
- map_delblock (&map[m].npc[i]->bl);
- numdb_erase (id_db, map[m].npc[i]->bl.id);
- if (map[m].npc[i]->bl.subtype == SCRIPT)
+ clif_clearchar(&map[m].npc[i]->bl, BeingRemoveWhy::QUIT);
+ map_delblock(&map[m].npc[i]->bl);
+ id_db.put(map[m].npc[i]->bl.id, nullptr);
+ if (map[m].npc[i]->bl.subtype == NpcSubtype::SCRIPT)
{
// free(map[m].npc[i]->u.scr.script);
// free(map[m].npc[i]->u.scr.label_list);
}
- free (map[m].npc[i]);
+ free(map[m].npc[i]);
map[m].npc[i] = NULL;
n++;
}
}
}
- printf ("%d NPCs removed.\n", n);
+ PRINTF("%d NPCs removed.\n", n);
}
/*==========================================
* map名からmap番号へ変換
*------------------------------------------
*/
-int map_mapname2mapid (const char *name)
+int map_mapname2mapid(const char *name)
{
- struct map_data *md = (struct map_data *)strdb_search (map_db, name);
+ struct map_data *md = map_db.get(name);
if (md == NULL || md->gat == NULL)
return -1;
return md->m;
@@ -1419,9 +1228,9 @@ int map_mapname2mapid (const char *name)
* 他鯖map名からip,port変換
*------------------------------------------
*/
-int map_mapname2ipport (const char *name, struct in_addr *ip, int *port)
+int map_mapname2ipport(const char *name, struct in_addr *ip, int *port)
{
- struct map_data_other_server *mdos = (struct map_data_other_server *)strdb_search (map_db, name);
+ struct map_data_other_server *mdos = (struct map_data_other_server *)map_db.get(name);
if (mdos == NULL || mdos->gat)
return -1;
*ip = mdos->ip;
@@ -1429,100 +1238,73 @@ int map_mapname2ipport (const char *name, struct in_addr *ip, int *port)
return 0;
}
-/*==========================================
- *
- *------------------------------------------
- */
-int map_check_dir (int s_dir, int t_dir)
+/// Check compatibility of directions.
+/// Directions are compatible if they are at most 45° apart.
+///
+/// @return false if compatible, true if incompatible.
+bool map_check_dir(const DIR s_dir, const DIR t_dir)
{
if (s_dir == t_dir)
- return 0;
- switch (s_dir)
- {
- case 0:
- if (t_dir == 7 || t_dir == 1 || t_dir == 0)
- return 0;
- break;
- case 1:
- if (t_dir == 0 || t_dir == 2 || t_dir == 1)
- return 0;
- break;
- case 2:
- if (t_dir == 1 || t_dir == 3 || t_dir == 2)
- return 0;
- break;
- case 3:
- if (t_dir == 2 || t_dir == 4 || t_dir == 3)
- return 0;
- break;
- case 4:
- if (t_dir == 3 || t_dir == 5 || t_dir == 4)
- return 0;
- break;
- case 5:
- if (t_dir == 4 || t_dir == 6 || t_dir == 5)
- return 0;
- break;
- case 6:
- if (t_dir == 5 || t_dir == 7 || t_dir == 6)
- return 0;
- break;
- case 7:
- if (t_dir == 6 || t_dir == 0 || t_dir == 7)
- return 0;
- break;
- }
- return 1;
+ return false;
+
+ const uint8_t sdir = static_cast<uint8_t>(s_dir);
+ const uint8_t tdir = static_cast<uint8_t>(t_dir);
+ if ((sdir + 1) % 8 == tdir)
+ return false;
+ if (sdir == (tdir + 1) % 8)
+ return false;
+
+ return true;
}
/*==========================================
* 彼我の方向を計算
*------------------------------------------
*/
-int map_calc_dir (struct block_list *src, int x, int y)
+DIR map_calc_dir(struct block_list *src, int x, int y)
{
- int dir = 0;
- int dx, dy;
+ DIR dir = DIR::S;
+ int dx, dy;
- nullpo_retr (0, src);
+ nullpo_retr(DIR::S, src);
dx = x - src->x;
dy = y - src->y;
if (dx == 0 && dy == 0)
- { // 彼我の場所一致
- dir = 0; // 上
+ {
+ dir = DIR::S;
}
else if (dx >= 0 && dy >= 0)
- { // 方向的に右上
- dir = 7; // 右上
+ {
+ dir = DIR::SE;
if (dx * 3 - 1 < dy)
- dir = 0; // 上
+ dir = DIR::S;
if (dx > dy * 3)
- dir = 6; // 右
+ dir = DIR::E;
}
else if (dx >= 0 && dy <= 0)
- { // 方向的に右下
- dir = 5; // 右下
+ {
+ dir = DIR::NE;
if (dx * 3 - 1 < -dy)
- dir = 4; // 下
+ dir = DIR::N;
if (dx > -dy * 3)
- dir = 6; // 右
+ dir = DIR::E;
}
else if (dx <= 0 && dy <= 0)
- { // 方向的に左下
- dir = 3; // 左下
+ {
+ dir = DIR::NW;
if (dx * 3 + 1 > dy)
- dir = 4; // 下
+ dir = DIR::N;
if (dx < dy * 3)
- dir = 2; // 左
+ dir = DIR::W;
}
else
- { // 方向的に左上
- dir = 1; // 左上
+ {
+ dir = DIR::SW;
if (-dx * 3 - 1 < dy)
- dir = 0; // 上
+ dir = DIR::S;
if (-dx > dy * 3)
- dir = 2; // 左
+ dir = DIR::W;
}
return dir;
}
@@ -1532,10 +1314,10 @@ int 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];
}
@@ -1543,44 +1325,47 @@ 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;
}
/*==========================================
* 他鯖管理のマップをdbに追加
*------------------------------------------
*/
-int map_setipport (const char *name, struct in_addr ip, int port)
+int map_setipport(const char *name, struct in_addr ip, int port)
{
- struct map_data_other_server *mdos = NULL;
-
- struct map_data *md = (struct map_data *)strdb_search (map_db, name);
+ struct map_data *md = map_db.get(name);
if (md == NULL)
- { // not exist -> add new data
- CREATE (mdos, struct map_data_other_server, 1);
- memcpy (mdos->name, name, 24);
+ {
+ struct map_data_other_server *mdos = NULL;
+ // not exist -> add new data
+ CREATE(mdos, struct map_data_other_server, 1);
+ memcpy(mdos->name, name, 24);
mdos->gat = NULL;
mdos->ip = ip;
mdos->port = port;
- strdb_insert (map_db, mdos->name, mdos);
+ map_db.put(mdos->name, (struct map_data *)mdos);
}
else
{
if (md->gat)
- { // local -> check data
- if (ip.s_addr != clif_getip ().s_addr || port != clif_getport ())
+ {
+ // local -> check data
+ if (ip.s_addr != clif_getip().s_addr || port != clif_getport())
{
- printf ("from char server : %s -> %s:%d\n", name, ip2str(ip),
+ PRINTF("from char server : %s -> %s:%d\n", name, ip2str(ip),
port);
return 1;
}
}
else
- { // update
+ {
+ // update
+ struct map_data_other_server *mdos = NULL;
mdos = (struct map_data_other_server *) md;
mdos->ip = ip;
mdos->port = port;
@@ -1589,139 +1374,54 @@ int map_setipport (const char *name, struct in_addr ip, int port)
return 0;
}
-// 初期化周り
-/*==========================================
- * 水場高さ設定
- *------------------------------------------
- */
-static struct Waterlist
-{
- char mapname[24];
- int waterheight;
-} *waterlist = NULL;
-
-#define NO_WATER 1000000
-
-static int map_waterheight (char *mapname)
-{
- if (waterlist)
- {
- int i;
- for (i = 0; waterlist[i].mapname[0] && i < MAX_MAP_PER_SERVER; i++)
- if (strcmp (waterlist[i].mapname, mapname) == 0)
- return waterlist[i].waterheight;
- }
- return NO_WATER;
-}
-
-static void map_readwater (char *watertxt)
-{
- char line[1024], w1[1024];
- FILE *fp = NULL;
- int n = 0;
-
- fp = fopen_ (watertxt, "r");
- if (fp == NULL)
- {
- printf ("file not found: %s\n", watertxt);
- return;
- }
- if (waterlist == NULL)
- {
- CREATE (waterlist, struct Waterlist, MAX_MAP_PER_SERVER);
- }
- while (fgets (line, 1020, fp) && n < MAX_MAP_PER_SERVER)
- {
- int wh, count;
- if (line[0] == '/' && line[1] == '/')
- continue;
- if ((count = sscanf (line, "%s%d", w1, &wh)) < 1)
- {
- continue;
- }
- strcpy (waterlist[n].mapname, w1);
- if (count >= 2)
- waterlist[n].waterheight = wh;
- else
- waterlist[n].waterheight = 3;
- n++;
- }
- fclose_ (fp);
-}
-
/*==========================================
* マップ1枚読み込み
*------------------------------------------
*/
-static int map_readmap (int m, char *fn, char *alias)
+static
+bool map_readmap(int m, const_string fn)
{
- int s;
- int x, y, xs, ys;
- struct gat_1cell
- {
- char type;
- } *p;
- int wh;
- size_t size;
-
// read & convert fn
- uint8_t *gat = (uint8_t *)grfio_read (fn);
- if (gat == NULL)
- return -1;
-
- printf ("\rLoading Maps [%d/%d]: %-50s ", m, map_num, fn);
- fflush (stdout);
+ std::vector<uint8_t> gat_v = grfio_reads(fn);
+ if (gat_v.empty())
+ return false;
+ size_t s = gat_v.size() - 4;
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);
+ 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);
+
+ assert (s == xs * ys);
+ map[m].gat = make_unique<MapCell[]>(s);
if (map[m].gat == NULL)
{
- printf ("out of memory : map_readmap gat\n");
- exit (1);
+ PRINTF("out of memory : map_readmap gat\n");
+ exit(1);
}
map[m].npc_num = 0;
map[m].users = 0;
- memset (&map[m].flag, 0, sizeof (map[m].flag));
+ memset(&map[m].flag, 0, sizeof(map[m].flag));
if (battle_config.pk_mode)
map[m].flag.pvp = 1; // make all maps pvp for pk_mode [Valaris]
- wh = map_waterheight (map[m].name);
- for (y = 0; y < ys; y++)
- {
- p = (struct gat_1cell *) (gat + y * xs + 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;
-
- 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);
+ size_t size = map[m].bxs * map[m].bys;
- strdb_insert (map_db, map[m].name, &map[m]);
+ 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);
-// printf("%s read done\n",fn);
+ map_db.put(map[m].name, &map[m]);
- return 0;
+ return true;
}
/*==========================================
@@ -1729,57 +1429,26 @@ static int map_readmap (int m, char *fn, char *alias)
*------------------------------------------
*/
static
-int map_readallmap (void)
+int map_readallmap(void)
{
- int i, maps_removed = 0;
- char fn[256] = "";
+ int i, maps_removed = 0;
- // 先に全部のャbプの存在を確認
- for (i = 0; i < map_num; i++)
- {
- if (strstr (map[i].name, ".gat") == NULL)
- continue;
- sprintf (fn, "data\\%s", map[i].name);
- // TODO - remove this, it is the last call to grfio_size, which is deprecated
- if (!grfio_size (fn))
- {
- 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);
- sprintf (fn, "data\\%s", map[i].name);
- if (map_readmap (i, fn, alias) == -1)
+ if (!map_readmap(i, map[i].name))
{
- map_delmap (map[i].name);
- maps_removed++;
- }
- }
- else
- {
- sprintf (fn, "data\\%s", map[i].name);
- if (map_readmap (i, fn, NULL) == -1)
- {
- map_delmap (map[i].name);
+ map_delmap(map[i].name);
maps_removed++;
}
}
}
}
- free (waterlist);
- printf ("\rMaps Loaded: %d %60s\n", map_num, "");
- printf ("\rMaps Removed: %d \n", maps_removed);
+ PRINTF("\rMaps Loaded: %d %60s\n", map_num, "");
+ PRINTF("\rMaps Removed: %d \n", maps_removed);
return 0;
}
@@ -1788,9 +1457,9 @@ int map_readallmap (void)
*------------------------------------------
*/
static
-int map_addmap (char *mapname)
+int map_addmap(const char *mapname)
{
- if (strcasecmp (mapname, "clear") == 0)
+ if (strcasecmp(mapname, "clear") == 0)
{
map_num = 0;
return 0;
@@ -1798,10 +1467,10 @@ int map_addmap (char *mapname)
if (map_num >= MAX_MAP_PER_SERVER - 1)
{
- printf ("too many map\n");
+ PRINTF("too many map\n");
return 1;
}
- memcpy (map[map_num].name, mapname, 24);
+ memcpy(map[map_num].name, mapname, 24);
map_num++;
return 0;
}
@@ -1810,11 +1479,12 @@ int map_addmap (char *mapname)
* 読み込むmapを削除する
*------------------------------------------
*/
-int map_delmap (char *mapname)
+static
+int map_delmap(const char *mapname)
{
- int i;
+ int i;
- if (strcasecmp (mapname, "all") == 0)
+ if (strcasecmp(mapname, "all") == 0)
{
map_num = 0;
return 0;
@@ -1822,84 +1492,94 @@ int map_delmap (char *mapname)
for (i = 0; i < map_num; i++)
{
- if (strcmp (map[i].name, mapname) == 0)
+ if (strcmp(map[i].name, mapname) == 0)
{
- printf ("Removing map [ %s ] from maplist\n", map[i].name);
- memmove (map + i, map + i + 1,
- sizeof (map[0]) * (map_num - i - 1));
+ PRINTF("Removing map [ %s ] from maplist\n", map[i].name);
+ memmove(map + i, map + i + 1,
+ sizeof(map[0]) * (map_num - i - 1));
map_num--;
}
}
return 0;
}
-extern char *gm_logfile_name;
-
-#define LOGFILE_SECONDS_PER_CHUNK_SHIFT 10
+constexpr int LOGFILE_SECONDS_PER_CHUNK_SHIFT = 10;
+static
FILE *map_logfile = NULL;
+static
char *map_logfile_name = NULL;
-static long map_logfile_index;
+static
+long map_logfile_index;
-static void map_close_logfile (void)
+static
+void map_close_logfile(void)
{
if (map_logfile)
{
- char *filenameop_buf = (char*)malloc (strlen (map_logfile_name) + 50);
- sprintf (filenameop_buf, "gzip -f %s.%ld &", map_logfile_name,
- map_logfile_index);
-
- fclose (map_logfile);
+ std::string filename = STRPRINTF("%s.%ld", map_logfile_name, map_logfile_index);
+ const char *args[] =
+ {
+ "gzip",
+ "-f",
+ filename.c_str(),
+ NULL
+ };
+ char **argv = const_cast<char **>(args);
- if (!system (filenameop_buf))
- perror (filenameop_buf);
+ fclose(map_logfile);
- free (filenameop_buf);
+ if (!fork())
+ {
+ execvp("gzip", argv);
+ _exit(1);
+ }
+ wait(NULL);
}
}
-static void map_start_logfile (long suffix)
+static
+void map_start_logfile(long index)
{
- char *filename_buf = (char*)malloc (strlen (map_logfile_name) + 50);
- map_logfile_index = suffix >> LOGFILE_SECONDS_PER_CHUNK_SHIFT;
+ map_logfile_index = index;
- sprintf (filename_buf, "%s.%ld", map_logfile_name, map_logfile_index);
- map_logfile = fopen (filename_buf, "w+");
+ std::string filename_buf = STRPRINTF(
+ "%s.%ld",
+ map_logfile_name,
+ map_logfile_index);
+ map_logfile = fopen(filename_buf.c_str(), "w+");
if (!map_logfile)
- perror (map_logfile_name);
-
- free (filename_buf);
+ perror(map_logfile_name);
}
-static void map_set_logfile (const char *filename)
+static
+void map_set_logfile(const char *filename)
{
struct timeval tv;
- map_logfile_name = strdup (filename);
- gettimeofday (&tv, NULL);
+ map_logfile_name = strdup(filename);
+ gettimeofday(&tv, NULL);
- map_start_logfile (tv.tv_sec);
+ map_start_logfile(tv.tv_sec);
- MAP_LOG ("log-start v3");
+ MAP_LOG("log-start v4");
}
-void map_write_log (const char *format, ...)
+void map_log(const_string line)
{
- struct timeval tv;
- va_list args;
- va_start (args, format);
+ if (!map_logfile)
+ return;
- gettimeofday (&tv, NULL);
+ time_t t = TimeT::now();
+ long i = t >> LOGFILE_SECONDS_PER_CHUNK_SHIFT;
- if ((tv.tv_sec >> LOGFILE_SECONDS_PER_CHUNK_SHIFT) != map_logfile_index)
+ if (i != map_logfile_index)
{
- map_close_logfile ();
- map_start_logfile (tv.tv_sec);
+ map_close_logfile();
+ map_start_logfile(i);
}
- fprintf (map_logfile, "%ld.%06ld ", (long) tv.tv_sec, (long) tv.tv_usec);
- vfprintf (map_logfile, format, args);
- fputc ('\n', map_logfile);
+ log_with_timestamp(map_logfile, line);
}
/*==========================================
@@ -1907,216 +1587,198 @@ void map_write_log (const char *format, ...)
*------------------------------------------
*/
static
-int map_config_read (const char *cfgName)
+int map_config_read(const char *cfgName)
{
- char line[1024], w1[1024], w2[1024];
- FILE *fp;
struct hostent *h = NULL;
- fp = fopen_ (cfgName, "r");
- if (fp == NULL)
+ std::ifstream in(cfgName);
+ if (!in.is_open())
{
- printf ("Map configuration file not found at: %s\n", cfgName);
- exit (1);
+ PRINTF("Map configuration file not found at: %s\n", cfgName);
+ exit(1);
}
- while (fgets (line, sizeof (line) - 1, fp))
+
+ std::string line;
+ while (std::getline(in, line))
{
- if (line[0] == '/' && line[1] == '/')
+ std::string w1, w2;
+ if (!split_key_value(line, &w1, &w2))
continue;
- if (sscanf (line, "%[^:]: %[^\r\n]", w1, w2) == 2)
+ if (w1 == "userid")
{
- if (strcasecmp (w1, "userid") == 0)
- {
- chrif_setuserid (w2);
- }
- else if (strcasecmp (w1, "passwd") == 0)
- {
- chrif_setpasswd (w2);
- }
- else if (strcasecmp (w1, "char_ip") == 0)
+ chrif_setuserid(w2.c_str());
+ }
+ else if (w1 == "passwd")
+ {
+ chrif_setpasswd(w2.c_str());
+ }
+ else if (w1 == "char_ip")
+ {
+ h = gethostbyname(w2.c_str());
+ if (h != NULL)
{
- h = gethostbyname (w2);
- if (h != NULL)
- {
- printf
- ("Character server IP address : %s -> %d.%d.%d.%d\n",
- w2, (unsigned char) h->h_addr[0],
+ PRINTF("Character server IP address : %s -> %d.%d.%d.%d\n",
+ w2, (unsigned char) h->h_addr[0],
+ (unsigned char) h->h_addr[1],
+ (unsigned char) h->h_addr[2],
+ (unsigned char) h->h_addr[3]);
+ SPRINTF(w2, "%d.%d.%d.%d", (unsigned char) h->h_addr[0],
(unsigned char) h->h_addr[1],
(unsigned char) h->h_addr[2],
(unsigned char) h->h_addr[3]);
- sprintf (w2, "%d.%d.%d.%d", (unsigned char) h->h_addr[0],
- (unsigned char) h->h_addr[1],
- (unsigned char) h->h_addr[2],
- (unsigned char) h->h_addr[3]);
- }
- chrif_setip (w2);
- }
- else if (strcasecmp (w1, "char_port") == 0)
- {
- chrif_setport (atoi (w2));
- }
- else if (strcasecmp (w1, "map_ip") == 0)
- {
- h = gethostbyname (w2);
- if (h != NULL)
- {
- printf ("Map server IP address : %s -> %d.%d.%d.%d\n", w2,
- (unsigned char) h->h_addr[0],
- (unsigned char) h->h_addr[1],
- (unsigned char) h->h_addr[2],
- (unsigned char) h->h_addr[3]);
- sprintf (w2, "%d.%d.%d.%d", (unsigned char) h->h_addr[0],
- (unsigned char) h->h_addr[1],
- (unsigned char) h->h_addr[2],
- (unsigned char) h->h_addr[3]);
- }
- clif_setip (w2);
- }
- else if (strcasecmp (w1, "map_port") == 0)
- {
- clif_setport (atoi (w2));
- map_port = (atoi (w2));
- }
- else if (strcasecmp (w1, "water_height") == 0)
- {
- map_readwater (w2);
- }
- else if (strcasecmp (w1, "map") == 0)
- {
- map_addmap (w2);
- }
- else if (strcasecmp (w1, "delmap") == 0)
- {
- map_delmap (w2);
- }
- else if (strcasecmp (w1, "npc") == 0)
- {
- npc_addsrcfile (w2);
- }
- else if (strcasecmp (w1, "delnpc") == 0)
- {
- npc_delsrcfile (w2);
- }
- else if (strcasecmp (w1, "autosave_time") == 0)
- {
- autosave_interval = atoi (w2) * 1000;
- if (autosave_interval <= 0)
- autosave_interval = DEFAULT_AUTOSAVE_INTERVAL;
- }
- else if (strcasecmp (w1, "motd_txt") == 0)
- {
- strcpy (motd_txt, w2);
- }
- else if (strcasecmp (w1, "help_txt") == 0)
- {
- strcpy (help_txt, w2);
}
- else if (strcasecmp (w1, "mapreg_txt") == 0)
- {
- strcpy (mapreg_txt, w2);
- }
- else if (strcasecmp (w1, "gm_log") == 0)
- {
- gm_logfile_name = strdup (w2);
- }
- else if (strcasecmp (w1, "log_file") == 0)
- {
- map_set_logfile (w2);
- }
- else if (strcasecmp (w1, "import") == 0)
+ chrif_setip(w2.c_str());
+ }
+ else if (w1 == "char_port")
+ {
+ chrif_setport(atoi(w2.c_str()));
+ }
+ else if (w1 == "map_ip")
+ {
+ h = gethostbyname(w2.c_str());
+ if (h != NULL)
{
- map_config_read (w2);
+ PRINTF("Map server IP address : %s -> %d.%d.%d.%d\n", w2,
+ (unsigned char) h->h_addr[0],
+ (unsigned char) h->h_addr[1],
+ (unsigned char) h->h_addr[2],
+ (unsigned char) h->h_addr[3]);
+ SPRINTF(w2, "%d.%d.%d.%d", (unsigned char) h->h_addr[0],
+ (unsigned char) h->h_addr[1],
+ (unsigned char) h->h_addr[2],
+ (unsigned char) h->h_addr[3]);
}
+ clif_setip(w2.c_str());
+ }
+ else if (w1 == "map_port")
+ {
+ clif_setport(atoi(w2.c_str()));
+ }
+ else if (w1 == "map")
+ {
+ map_addmap(w2.c_str());
+ }
+ else if (w1 == "delmap")
+ {
+ map_delmap(w2.c_str());
+ }
+ else if (w1 == "npc")
+ {
+ npc_addsrcfile(w2.c_str());
+ }
+ else if (w1 == "delnpc")
+ {
+ npc_delsrcfile(w2.c_str());
+ }
+ else if (w1 == "autosave_time")
+ {
+ autosave_interval = std::chrono::seconds(atoi(w2.c_str()));
+ if (autosave_interval <= interval_t::zero())
+ autosave_interval = DEFAULT_AUTOSAVE_INTERVAL;
+ }
+ else if (w1 == "motd_txt")
+ {
+ strzcpy(motd_txt, w2.c_str(), sizeof(motd_txt));
+ }
+ else if (w1 == "help_txt")
+ {
+ strzcpy(help_txt, w2.c_str(), sizeof(help_txt));
+ }
+ else if (w1 == "mapreg_txt")
+ {
+ strzcpy(mapreg_txt, w2.c_str(), sizeof(mapreg_txt));
+ }
+ else if (w1 == "gm_log")
+ {
+ gm_logfile_name = strdup(w2.c_str());
+ }
+ else if (w1 == "log_file")
+ {
+ map_set_logfile(w2.c_str());
+ }
+ else if (w1 == "import")
+ {
+ map_config_read(w2.c_str());
}
}
- fclose_ (fp);
return 0;
}
-static int cleanup_sub (struct block_list *bl, va_list ap)
+static
+void cleanup_sub(struct block_list *bl)
{
- nullpo_retr (0, bl);
+ nullpo_retv(bl);
switch (bl->type)
{
- case BL_PC:
- map_delblock (bl); // There is something better...
+ case BL::PC:
+ map_delblock(bl); // There is something better...
break;
- case BL_NPC:
- npc_delete ((struct npc_data *) bl);
+ case BL::NPC:
+ npc_delete((struct npc_data *) bl);
break;
- case BL_MOB:
- mob_delete ((struct mob_data *) bl);
+ case BL::MOB:
+ mob_delete((struct mob_data *) bl);
break;
- case BL_ITEM:
- map_clearflooritem (bl->id);
+ case BL::ITEM:
+ map_clearflooritem(bl->id);
break;
- case BL_SKILL:
- skill_delunit ((struct skill_unit *) bl);
- break;
- case BL_SPELL:
- spell_free_invocation ((struct invocation *) bl);
+ case BL::SPELL:
+ spell_free_invocation((struct invocation *) bl);
break;
}
-
- return 0;
}
/*==========================================
* map鯖終了時処理
*------------------------------------------
*/
-void term_func (void)
+void term_func(void)
{
- map_close_logfile ();
+ map_close_logfile();
- int map_id, i;
+ int map_id, i;
for (map_id = 0; map_id < map_num; map_id++)
{
if (map[map_id].m)
- map_foreachinarea (cleanup_sub, map_id, 0, 0, map[map_id].xs,
- map[map_id].ys, 0, 0);
+ map_foreachinarea(cleanup_sub, map_id,
+ 0, 0, map[map_id].xs, map[map_id].ys,
+ BL::NUL);
}
for (i = 0; i < fd_max; i++)
- delete_session (i);
-
- map_removenpc ();
+ delete_session(i);
- numdb_final (id_db, NULL);
- strdb_final (map_db, NULL);
- strdb_final (nick_db, NULL);
- numdb_final (charid_db, NULL);
+ map_removenpc();
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);
+ free(map[i].block);
if (map[i].block_mob)
- free (map[i].block_mob);
+ free(map[i].block_mob);
if (map[i].block_count)
- free (map[i].block_count);
+ free(map[i].block_count);
if (map[i].block_mob_count)
- free (map[i].block_mob_count);
+ free(map[i].block_mob_count);
}
- do_final_script ();
- do_final_itemdb ();
- do_final_storage ();
- do_final_guild ();
+ do_final_script();
+ do_final_itemdb();
+ do_final_storage();
}
/// --help was passed
// FIXME this should produce output
-void map_helpscreen (void)
+static __attribute__((noreturn))
+void map_helpscreen(void)
{
- exit (1);
+ exit(1);
}
-int compare_item (struct item *a, struct item *b)
+int compare_item(struct item *a, struct item *b)
{
return ((a->nameid == b->nameid) &&
(a->identify == b->identify) &&
@@ -2131,86 +1793,71 @@ int compare_item (struct item *a, struct item *b)
* Map-Server Init and Command-line Arguments [Valaris]
*------------------------------------------------------
*/
-int do_init (int argc, char *argv[])
+int do_init(int argc, char *argv[])
{
- int i;
+ int i;
const char *MAP_CONF_NAME = "conf/map_athena.conf";
const char *BATTLE_CONF_FILENAME = "conf/battle_athena.conf";
const char *ATCOMMAND_CONF_FILENAME = "conf/atcommand_athena.conf";
- const char *SCRIPT_CONF_NAME = "conf/script_athena.conf";
- const char *MSG_CONF_NAME = "conf/msg_athena.conf";
for (i = 1; i < argc; i++)
{
- if (strcmp (argv[i], "--help") == 0 || strcmp (argv[i], "--h") == 0
- || strcmp (argv[i], "--?") == 0 || strcmp (argv[i], "/?") == 0)
- map_helpscreen ();
- else if (strcmp (argv[i], "--map_config") == 0)
+ if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "--h") == 0
+ || strcmp(argv[i], "--?") == 0 || strcmp(argv[i], "/?") == 0)
+ map_helpscreen();
+ else if (strcmp(argv[i], "--map_config") == 0)
MAP_CONF_NAME = argv[i + 1];
- else if (strcmp (argv[i], "--battle_config") == 0)
+ else if (strcmp(argv[i], "--battle_config") == 0)
BATTLE_CONF_FILENAME = argv[i + 1];
- else if (strcmp (argv[i], "--atcommand_config") == 0)
+ else if (strcmp(argv[i], "--atcommand_config") == 0)
ATCOMMAND_CONF_FILENAME = argv[i + 1];
- else if (strcmp (argv[i], "--script_config") == 0)
- SCRIPT_CONF_NAME = argv[i + 1];
- else if (strcmp (argv[i], "--msg_config") == 0)
- MSG_CONF_NAME = argv[i + 1];
}
- map_config_read (MAP_CONF_NAME);
- battle_config_read (BATTLE_CONF_FILENAME);
- atcommand_config_read (ATCOMMAND_CONF_FILENAME);
- script_config_read (SCRIPT_CONF_NAME);
-
- id_db = numdb_init ();
- map_db = strdb_init (16);
- nick_db = strdb_init (24);
- charid_db = numdb_init ();
-
- map_readallmap ();
+ map_config_read(MAP_CONF_NAME);
+ battle_config_read(BATTLE_CONF_FILENAME);
+ atcommand_config_read(ATCOMMAND_CONF_FILENAME);
+ script_config_read();
-// add_timer_func_list (map_clearflooritem_timer, "map_clearflooritem_timer");
+ map_readallmap();
do_init_chrif ();
do_init_clif ();
- do_init_itemdb ();
- do_init_mob (); // npcの初期化時内でmob_spawnして、mob_dbを参照するのでinit_npcより先
- do_init_script ();
- do_init_npc ();
- do_init_pc ();
- do_init_party ();
- do_init_guild ();
- do_init_storage ();
- do_init_skill ();
- do_init_magic ();
-
- npc_event_do_oninit (); // npcのOnInitイベント実行
+ do_init_itemdb();
+ do_init_mob(); // npcの初期化時内でmob_spawnして、mob_dbを参照するのでinit_npcより先
+ do_init_script();
+ do_init_npc();
+ do_init_pc();
+ do_init_party();
+ do_init_storage();
+ do_init_skill();
+ do_init_magic();
+
+ npc_event_do_oninit(); // npcのOnInitイベント実行
if (battle_config.pk_mode == 1)
- printf ("The server is running in \033[1;31mPK Mode\033[0m.\n");
+ PRINTF("The server is running in \033[1;31mPK Mode\033[0m.\n");
- printf
- ("The map-server is \033[1;32mready\033[0m (Server is listening on the port %d).\n\n",
+ PRINTF("The map-server is \033[1;32mready\033[0m (Server is listening on the port %d).\n\n",
map_port);
return 0;
}
-int map_scriptcont (struct map_session_data *sd, int id)
+int map_scriptcont(struct map_session_data *sd, int id)
{
- struct block_list *bl = map_id2bl (id);
+ struct block_list *bl = map_id2bl(id);
if (!bl)
return 0;
switch (bl->type)
{
- case BL_NPC:
- return npc_scriptcont (sd, id);
- case BL_SPELL:
- spell_execute_script ((struct invocation *) bl);
+ case BL::NPC:
+ return npc_scriptcont(sd, id);
+ case BL::SPELL:
+ spell_execute_script((struct invocation *) bl);
break;
}