summaryrefslogtreecommitdiff
path: root/src/map/map.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/map.c')
-rw-r--r--src/map/map.c2098
1 files changed, 1341 insertions, 757 deletions
diff --git a/src/map/map.c b/src/map/map.c
index 3a7d752c3..40e66e4df 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -2,8 +2,8 @@
* This file is part of Hercules.
* http://herc.ws - http://github.com/HerculesWS/Hercules
*
- * Copyright (C) 2012-2015 Hercules Dev Team
- * Copyright (C) Athena Dev Teams
+ * Copyright (C) 2012-2020 Hercules Dev Team
+ * Copyright (C) Athena Dev Teams
*
* Hercules is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,6 +30,7 @@
#include "map/channel.h"
#include "map/chat.h"
#include "map/chrif.h"
+#include "map/clan.h"
#include "map/clif.h"
#include "map/duel.h"
#include "map/elemental.h"
@@ -44,7 +45,6 @@
#include "map/mapreg.h"
#include "map/mercenary.h"
#include "map/mob.h"
-#include "map/npc.h"
#include "map/npc.h" // npc_setcells(), npc_unsetcells()
#include "map/party.h"
#include "map/path.h"
@@ -55,8 +55,12 @@
#include "map/skill.h"
#include "map/status.h"
#include "map/storage.h"
+#include "map/stylist.h"
+#include "map/rodex.h"
+#include "map/refine.h"
#include "map/trade.h"
#include "map/unit.h"
+#include "map/achievement.h"
#include "common/HPM.h"
#include "common/cbasetypes.h"
#include "common/conf.h"
@@ -64,6 +68,7 @@
#include "common/core.h"
#include "common/ers.h"
#include "common/grfio.h"
+#include "common/md5calc.h"
#include "common/memmgr.h"
#include "common/nullpo.h"
#include "common/random.h"
@@ -79,12 +84,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/stat.h>
#ifndef _WIN32
#include <unistd.h>
#endif
-struct map_interface map_s;
-struct mapit_interface mapit_s;
+static struct map_interface map_s;
+static struct mapit_interface mapit_s;
struct map_interface *map;
struct mapit_interface *mapit;
@@ -92,18 +98,21 @@ struct mapit_interface *mapit;
/*==========================================
* server player count (of all mapservers)
*------------------------------------------*/
-void map_setusers(int users) {
+static void map_setusers(int users)
+{
map->users = users;
}
-int map_getusers(void) {
+static int map_getusers(void)
+{
return map->users;
}
/**
* Expands map->bl_list on demand
**/
-static inline void map_bl_list_expand(void) {
+static inline void map_bl_list_expand(void)
+{
map->bl_list_size += 250;
RECREATE(map->bl_list, struct block_list *, map->bl_list_size);
}
@@ -111,7 +120,8 @@ static inline void map_bl_list_expand(void) {
/**
* Expands map->block_free on demand
**/
-static inline void map_block_free_expand(void) {
+static inline void map_block_free_expand(void)
+{
map->block_free_list_size += 100;
RECREATE(map->block_free, struct block_list *, map->block_free_list_size);
}
@@ -119,14 +129,16 @@ static inline void map_block_free_expand(void) {
/*==========================================
* server player count (this mapserver only)
*------------------------------------------*/
-int map_usercount(void) {
+static int map_usercount(void)
+{
return db_size(map->pc_db);
}
/*==========================================
* Attempt to free a map blocklist
*------------------------------------------*/
-int map_freeblock (struct block_list *bl) {
+static int map_freeblock(struct block_list *bl)
+{
nullpo_retr(map->block_free_lock, bl);
if (map->block_free_lock == 0) {
@@ -147,14 +159,16 @@ int map_freeblock (struct block_list *bl) {
/*==========================================
* Lock blocklist, (prevent map->freeblock usage)
*------------------------------------------*/
-int map_freeblock_lock (void) {
+static int map_freeblock_lock(void)
+{
return ++map->block_free_lock;
}
/*==========================================
* Remove the lock on map_bl
*------------------------------------------*/
-int map_freeblock_unlock (void) {
+static int map_freeblock_unlock(void)
+{
if ((--map->block_free_lock) == 0) {
int i;
for (i = 0; i < map->block_free_count; i++) {
@@ -175,7 +189,8 @@ int map_freeblock_unlock (void) {
// Timer function to check if there some remaining lock and remove them if so.
// Called each 1s
-int map_freeblock_timer(int tid, int64 tick, int id, intptr_t data) {
+static int map_freeblock_timer(int tid, int64 tick, int id, intptr_t data)
+{
if (map->block_free_lock > 0) {
ShowError("map_freeblock_timer: block_free_lock(%d) is invalid.\n", map->block_free_lock);
map->block_free_lock = 1;
@@ -189,7 +204,8 @@ int map_freeblock_timer(int tid, int64 tick, int id, intptr_t data) {
* Updates the counter (cell.cell_bl) of how many objects are on a tile.
* @param add Whether the counter should be increased or decreased
**/
-void map_update_cell_bl( struct block_list *bl, bool increase ) {
+static void map_update_cell_bl(struct block_list *bl, bool increase)
+{
#ifdef CELL_NOSTACK
int pos;
@@ -218,7 +234,7 @@ void map_update_cell_bl( struct block_list *bl, bool increase ) {
* Adds a block to the map.
* Returns 0 on success, 1 on failure (illegal coordinates).
*------------------------------------------*/
-int map_addblock(struct block_list* bl)
+static int map_addblock(struct block_list *bl)
{
int16 m, x, y;
int pos;
@@ -266,7 +282,7 @@ int map_addblock(struct block_list* bl)
/*==========================================
* Removes a block from the map.
*------------------------------------------*/
-int map_delblock(struct block_list* bl)
+static int map_delblock(struct block_list *bl)
{
int pos;
nullpo_ret(bl);
@@ -309,7 +325,8 @@ int map_delblock(struct block_list* bl)
* Pass flag as 1 to prevent doing skill->unit_move checks
* (which are executed by default on BL_CHAR types)
*------------------------------------------*/
-int map_moveblock(struct block_list *bl, int x1, int y1, int64 tick) {
+static int map_moveblock(struct block_list *bl, int x1, int y1, int64 tick)
+{
struct status_change *sc = NULL;
int x0, y0;
int moveblock;
@@ -336,6 +353,7 @@ int map_moveblock(struct block_list *bl, int x1, int y1, int64 tick) {
//status_change_end(bl, SC_BLADESTOP, INVALID_TIMER); //Won't stop when you are knocked away, go figure...
status_change_end(bl, SC_NJ_TATAMIGAESHI, INVALID_TIMER);
status_change_end(bl, SC_MAGICROD, INVALID_TIMER);
+ status_change_end(bl, SC_SU_STOOP, INVALID_TIMER);
if (sc && sc->data[SC_PROPERTYWALK] &&
sc->data[SC_PROPERTYWALK]->val3 >= skill->get_maxcount(sc->data[SC_PROPERTYWALK]->val1,sc->data[SC_PROPERTYWALK]->val2) )
status_change_end(bl,SC_PROPERTYWALK,INVALID_TIMER);
@@ -426,7 +444,8 @@ int map_moveblock(struct block_list *bl, int x1, int y1, int64 tick) {
* 0x2 - don't count invinsible units
* TODO: merge with bl_getall_area
*------------------------------------------*/
-int map_count_oncell(int16 m, int16 x, int16 y, int type, int flag) {
+static int map_count_oncell(int16 m, int16 x, int16 y, int type, int flag)
+{
int bx,by;
struct block_list *bl;
int count = 0;
@@ -444,6 +463,11 @@ int map_count_oncell(int16 m, int16 x, int16 y, int type, int flag) {
struct status_change *sc = status->get_sc(bl);
if (sc && (sc->option&OPTION_INVISIBLE))
continue;
+ if (bl->type == BL_NPC) {
+ const struct npc_data *nd = BL_UCCAST(BL_NPC, bl);
+ if (nd->class_ == FAKE_NPC || nd->class_ == HIDDEN_WARP_CLASS)
+ continue;
+ }
}
if (flag&0x1) {
struct unit_data *ud = unit->bl2ud(bl);
@@ -479,7 +503,8 @@ int map_count_oncell(int16 m, int16 x, int16 y, int type, int flag) {
* Looks for a skill unit on a given cell
* flag&1: runs battle_check_target check based on unit->group->target_flag
*/
-struct skill_unit* map_find_skill_unit_oncell(struct block_list* target,int16 x,int16 y,uint16 skill_id,struct skill_unit* out_unit, int flag) {
+static struct skill_unit *map_find_skill_unit_oncell(struct block_list *target, int16 x, int16 y, uint16 skill_id, struct skill_unit *out_unit, int flag)
+{
int16 m,bx,by;
struct block_list *bl;
struct skill_unit *su;
@@ -506,10 +531,12 @@ struct skill_unit* map_find_skill_unit_oncell(struct block_list* target,int16 x,
return NULL;
}
-/** @name Functions for block_list search and manipulation
+/**
+ * @name Functions for block_list search and manipulation
+ *
+ * @{
*/
-/* @{ */
/**
* Applies func to every block_list in bl_list starting with bl_list[blockcount].
* Sets bl_list_count back to blockcount.
@@ -520,7 +547,8 @@ struct skill_unit* map_find_skill_unit_oncell(struct block_list* target,int16 x,
* @param args Extra arguments for func
* @return Sum of the values returned by func
*/
-static int bl_vforeach(int (*func)(struct block_list*, va_list), int blockcount, int max, va_list args) {
+static int bl_vforeach(int (*func)(struct block_list*, va_list), int blockcount, int max, va_list args)
+{
int i;
int returnCount = 0;
@@ -549,7 +577,8 @@ static int bl_vforeach(int (*func)(struct block_list*, va_list), int blockcount,
* @param args Extra arguments for func
* @return Sum of the values returned by func
*/
-static int map_vforeachinmap(int (*func)(struct block_list*, va_list), int16 m, int type, va_list args) {
+static int map_vforeachinmap(int (*func)(struct block_list*, va_list), int16 m, int type, va_list args)
+{
int i;
int returnCount = 0;
int bsize;
@@ -597,7 +626,8 @@ static int map_vforeachinmap(int (*func)(struct block_list*, va_list), int16 m,
* @param ... Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_foreachinmap(int (*func)(struct block_list*, va_list), int16 m, int type, ...) {
+static int map_foreachinmap(int (*func)(struct block_list*, va_list), int16 m, int type, ...)
+{
int returnCount;
va_list ap;
@@ -608,6 +638,21 @@ int map_foreachinmap(int (*func)(struct block_list*, va_list), int16 m, int type
return returnCount;
}
+static int map_forcountinmap(int (*func)(struct block_list*, va_list), int16 m, int count, int type, ...)
+{
+ int returnCount = 0;
+ va_list ap;
+
+ if (m < 0)
+ return returnCount;
+
+ va_start(ap, type);
+ returnCount = map->vforcountinarea(func, m, 0, 0, map->list[m].xs, map->list[m].ys, count, type, ap);
+ va_end(ap);
+
+ return returnCount;
+}
+
/**
* Applies func to every block_list object of bl_type type on all maps
* of instance instance_id.
@@ -619,7 +664,8 @@ int map_foreachinmap(int (*func)(struct block_list*, va_list), int16 m, int type
* @param ap Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_vforeachininstance(int (*func)(struct block_list*, va_list), int16 instance_id, int type, va_list ap) {
+static int map_vforeachininstance(int (*func)(struct block_list*, va_list), int16 instance_id, int type, va_list ap)
+{
int i;
int returnCount = 0;
@@ -645,7 +691,8 @@ int map_vforeachininstance(int (*func)(struct block_list*, va_list), int16 insta
* @param ... Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_foreachininstance(int (*func)(struct block_list*, va_list), int16 instance_id, int type, ...) {
+static int map_foreachininstance(int (*func)(struct block_list*, va_list), int16 instance_id, int type, ...)
+{
int returnCount;
va_list ap;
@@ -665,7 +712,8 @@ int map_foreachininstance(int (*func)(struct block_list*, va_list), int16 instan
* @param ... Extra arguments for func
* @return Number of found objects
*/
-static int bl_getall_area(int type, int m, int x0, int y0, int x1, int y1, int (*func)(struct block_list*, va_list), ...) {
+static int bl_getall_area(int type, int m, int x0, int y0, int x1, int y1, int (*func)(struct block_list*, va_list), ...)
+{
va_list args;
int bx, by;
struct block_list *bl;
@@ -683,49 +731,95 @@ static int bl_getall_area(int type, int m, int x0, int y0, int x1, int y1, int (
x1 = min(x1, map->list[m].xs - 1);
y1 = min(y1, map->list[m].ys - 1);
- for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++) {
- for (bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++) {
- if (type&~BL_MOB) {
- for (bl = map->list[m].block[bx + by * map->list[m].bxs]; bl != NULL; bl = bl->next) {
- if (bl->type&type && bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1) {
- if( map->bl_list_count >= map->bl_list_size )
- map_bl_list_expand();
- if (func) {
- va_start(args, func);
- if (func(bl, args)) {
+ {
+ const int x0b = x0 / BLOCK_SIZE;
+ const int x1b = x1 / BLOCK_SIZE;
+ const int y0b = y0 / BLOCK_SIZE;
+ const int y1b = y1 / BLOCK_SIZE;
+ const struct map_data *const listm = &map->list[m];
+ const int bxs0 = listm->bxs;
+
+ // duplication for better performance
+ if (func != NULL) {
+ if (type & ~BL_MOB) {
+ for (by = y0b; by <= y1b; by++) {
+ const int bxs = by * bxs0;
+ for (bx = x0b; bx <= x1b; bx++) {
+ for (bl = listm->block[bx + bxs]; bl != NULL; bl = bl->next) {
+ const int x = bl->x;
+ const int y = bl->y;
+ if (bl->type & type && x >= x0 && x <= x1 && y >= y0 && y <= y1) {
+ va_start(args, func);
+ if (func(bl, args)) {
+ if (map->bl_list_count >= map->bl_list_size)
+ map_bl_list_expand();
+ map->bl_list[map->bl_list_count++] = bl;
+ found++;
+ }
+ va_end(args);
+ }
+ }
+ }
+ }
+ }
+ if (type & BL_MOB) {
+ for (by = y0b; by <= y1b; by++) {
+ const int bxs = by * bxs0;
+ for (bx = x0b; bx <= x1b; bx++) {
+ for (bl = listm->block_mob[bx + bxs]; bl != NULL; bl = bl->next) {
+ const int x = bl->x;
+ const int y = bl->y;
+ if (x >= x0 && x <= x1 && y >= y0 && y <= y1) {
+ va_start(args, func);
+ if (func(bl, args)) {
+ if (map->bl_list_count >= map->bl_list_size)
+ map_bl_list_expand();
+ map->bl_list[map->bl_list_count++] = bl;
+ found++;
+ }
+ va_end(args);
+ }
+ }
+ }
+ }
+ }
+ } else { // func != NULL
+ if (type & ~BL_MOB) {
+ for (by = y0b; by <= y1b; by++) {
+ const int bxs = by * bxs0;
+ for (bx = x0b; bx <= x1b; bx++) {
+ for (bl = listm->block[bx + bxs]; bl != NULL; bl = bl->next) {
+ const int x = bl->x;
+ const int y = bl->y;
+ if (bl->type & type && x >= x0 && x <= x1 && y >= y0 && y <= y1) {
+ if (map->bl_list_count >= map->bl_list_size)
+ map_bl_list_expand();
map->bl_list[map->bl_list_count++] = bl;
found++;
}
- va_end(args);
- } else {
- map->bl_list[map->bl_list_count++] = bl;
- found++;
}
}
}
}
- if (type&BL_MOB) { // TODO: fix this code duplication
- for (bl = map->list[m].block_mob[bx + by * map->list[m].bxs]; bl != NULL; bl = bl->next) {
- if (bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1) {
- if( map->bl_list_count >= map->bl_list_size )
- map_bl_list_expand();
- if (func) {
- va_start(args, func);
- if (func(bl, args)) {
+ if (type & BL_MOB) {
+ for (by = y0b; by <= y1b; by++) {
+ const int bxs = by * bxs0;
+ for (bx = x0b; bx <= x1b; bx++) {
+ for (bl = listm->block_mob[bx + bxs]; bl != NULL; bl = bl->next) {
+ const int x = bl->x;
+ const int y = bl->y;
+ if (x >= x0 && x <= x1 && y >= y0 && y <= y1) {
+ if (map->bl_list_count >= map->bl_list_size)
+ map_bl_list_expand();
map->bl_list[map->bl_list_count++] = bl;
found++;
}
- va_end(args);
- } else {
- map->bl_list[map->bl_list_count++] = bl;
- found++;
}
}
}
}
}
}
-
return found;
}
@@ -757,7 +851,8 @@ static int bl_vgetall_inrange(struct block_list *bl, va_list args)
* @param ap Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_vforeachinrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int type, va_list ap) {
+static int map_vforeachinrange(int (*func)(struct block_list*, va_list), struct block_list *center, int16 range, int type, va_list ap)
+{
int returnCount = 0;
int blockcount = map->bl_list_count;
va_list apcopy;
@@ -785,7 +880,8 @@ int map_vforeachinrange(int (*func)(struct block_list*, va_list), struct block_l
* @param ... Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_foreachinrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int type, ...) {
+static int map_foreachinrange(int (*func)(struct block_list*, va_list), struct block_list *center, int16 range, int type, ...)
+{
int returnCount;
va_list ap;
@@ -809,7 +905,8 @@ int map_foreachinrange(int (*func)(struct block_list*, va_list), struct block_li
* @param ap Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_vforcountinrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int count, int type, va_list ap) {
+static int map_vforcountinrange(int (*func)(struct block_list*, va_list), struct block_list *center, int16 range, int count, int type, va_list ap)
+{
int returnCount = 0;
int blockcount = map->bl_list_count;
va_list apcopy;
@@ -839,7 +936,8 @@ int map_vforcountinrange(int (*func)(struct block_list*, va_list), struct block_
* @param ... Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_forcountinrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int count, int type, ...) {
+static int map_forcountinrange(int (*func)(struct block_list*, va_list), struct block_list *center, int16 range, int count, int type, ...)
+{
int returnCount;
va_list ap;
@@ -885,7 +983,8 @@ static int bl_vgetall_inshootrange(struct block_list *bl, va_list args)
* @param ap Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_vforeachinshootrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int type, va_list ap) {
+static int map_vforeachinshootrange(int (*func)(struct block_list*, va_list), struct block_list *center, int16 range, int type, va_list ap)
+{
int returnCount = 0;
int blockcount = map->bl_list_count;
va_list apcopy;
@@ -913,7 +1012,8 @@ int map_vforeachinshootrange(int (*func)(struct block_list*, va_list), struct bl
* @param ... Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_foreachinshootrange(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int type, ...) {
+static int map_foreachinshootrange(int (*func)(struct block_list*, va_list), struct block_list *center, int16 range, int type, ...)
+{
int returnCount;
va_list ap;
@@ -938,7 +1038,8 @@ int map_foreachinshootrange(int (*func)(struct block_list*, va_list), struct blo
* @param ap Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_vforeachinarea(int (*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int type, va_list ap) {
+static int map_vforeachinarea(int (*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int type, va_list ap)
+{
int returnCount = 0;
int blockcount = map->bl_list_count;
va_list apcopy;
@@ -967,7 +1068,8 @@ int map_vforeachinarea(int (*func)(struct block_list*, va_list), int16 m, int16
* @param ... Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_foreachinarea(int (*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int type, ...) {
+static int map_foreachinarea(int (*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int type, ...)
+{
int returnCount;
va_list ap;
@@ -994,7 +1096,8 @@ int map_foreachinarea(int (*func)(struct block_list*, va_list), int16 m, int16 x
* @param ap Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_vforcountinarea(int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int count, int type, va_list ap) {
+static int map_vforcountinarea(int (*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int count, int type, va_list ap)
+{
int returnCount = 0;
int blockcount = map->bl_list_count;
va_list apcopy;
@@ -1025,7 +1128,8 @@ int map_vforcountinarea(int (*func)(struct block_list*,va_list), int16 m, int16
* @param ... Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_forcountinarea(int (*func)(struct block_list*,va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int count, int type, ...) {
+static int map_forcountinarea(int (*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int count, int type, ...)
+{
int returnCount;
va_list ap;
@@ -1082,7 +1186,8 @@ static int bl_vgetall_inmovearea(struct block_list *bl, va_list args)
* @param ap Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_vforeachinmovearea(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int16 dx, int16 dy, int type, va_list ap) {
+static int map_vforeachinmovearea(int (*func)(struct block_list*, va_list), struct block_list *center, int16 range, int16 dx, int16 dy, int type, va_list ap)
+{
int returnCount = 0;
int blockcount = map->bl_list_count;
int m, x0, x1, y0, y1;
@@ -1140,7 +1245,8 @@ int map_vforeachinmovearea(int (*func)(struct block_list*, va_list), struct bloc
* @param ... Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_foreachinmovearea(int (*func)(struct block_list*, va_list), struct block_list* center, int16 range, int16 dx, int16 dy, int type, ...) {
+static int map_foreachinmovearea(int (*func)(struct block_list*, va_list), struct block_list *center, int16 range, int16 dx, int16 dy, int type, ...)
+{
int returnCount;
va_list ap;
@@ -1163,7 +1269,8 @@ int map_foreachinmovearea(int (*func)(struct block_list*, va_list), struct block
* @param ap Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_vforeachincell(int (*func)(struct block_list*, va_list), int16 m, int16 x, int16 y, int type, va_list ap) {
+static int map_vforeachincell(int (*func)(struct block_list*, va_list), int16 m, int16 x, int16 y, int type, va_list ap)
+{
int returnCount = 0;
int blockcount = map->bl_list_count;
va_list apcopy;
@@ -1189,7 +1296,8 @@ int map_vforeachincell(int (*func)(struct block_list*, va_list), int16 m, int16
* @param ... Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_foreachincell(int (*func)(struct block_list*, va_list), int16 m, int16 x, int16 y, int type, ...) {
+static int map_foreachincell(int (*func)(struct block_list*, va_list), int16 m, int16 x, int16 y, int type, ...)
+{
int returnCount;
va_list ap;
@@ -1268,7 +1376,8 @@ static int bl_vgetall_inpath(struct block_list *bl, va_list args)
* @param ap Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_vforeachinpath(int (*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int16 range, int length, int type, va_list ap) {
+static int map_vforeachinpath(int (*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int16 range, int length, int type, va_list ap)
+{
// [Skotlex]
// check for all targets in the square that
// contains the initial and final positions (area range increased to match the
@@ -1345,7 +1454,8 @@ int map_vforeachinpath(int (*func)(struct block_list*, va_list), int16 m, int16
* @param ... Extra arguments for func
* @return Sum of the values returned by func
*/
-int map_foreachinpath(int (*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int16 range, int length, int type, ...) {
+static int map_foreachinpath(int (*func)(struct block_list*, va_list), int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int16 range, int length, int type, ...)
+{
int returnCount;
va_list ap;
@@ -1361,7 +1471,7 @@ int map_foreachinpath(int (*func)(struct block_list*, va_list), int16 m, int16 x
/// Generates a new flooritem object id from the interval [MIN_FLOORITEM, MAX_FLOORITEM).
/// Used for floor items, skill units and chatroom objects.
/// @return The new object id
-int map_get_new_object_id(void)
+static int map_get_new_object_id(void)
{
static int last_object_id = MIN_FLOORITEM - 1;
int i;
@@ -1393,7 +1503,7 @@ int map_get_new_object_id(void)
* Timered function to clear the floor (remove remaining item)
* Called each flooritem_lifetime ms
*------------------------------------------*/
-int map_clearflooritem_timer(int tid, int64 tick, int id, intptr_t data)
+static int map_clearflooritem_timer(int tid, int64 tick, int id, intptr_t data)
{
struct block_list *bl = idb_get(map->id_db, id);
struct flooritem_data *fitem = BL_CAST(BL_ITEM, bl);
@@ -1416,7 +1526,7 @@ int map_clearflooritem_timer(int tid, int64 tick, int id, intptr_t data)
/*
* clears a single bl item out of the bazooonga.
*/
-void map_clearflooritem(struct block_list *bl)
+static void map_clearflooritem(struct block_list *bl)
{
struct flooritem_data *fitem = BL_CAST(BL_ITEM, bl);
@@ -1436,7 +1546,8 @@ void map_clearflooritem(struct block_list *bl)
* to place an BL_ITEM object. Scan area is 9x9, returns 1 on success.
* x and y are modified with the target cell when successful.
*------------------------------------------*/
-int map_searchrandfreecell(int16 m, const struct block_list *bl, int16 *x, int16 *y, int stack) {
+static int map_searchrandfreecell(int16 m, const struct block_list *bl, int16 *x, int16 *y, int stack)
+{
int free_cell,i,j;
int free_cells[9][2];
@@ -1466,7 +1577,8 @@ int map_searchrandfreecell(int16 m, const struct block_list *bl, int16 *x, int16
return 1;
}
-int map_count_sub(struct block_list *bl,va_list ap) {
+static int map_count_sub(struct block_list *bl, va_list ap)
+{
return 1;
}
@@ -1482,7 +1594,7 @@ int map_count_sub(struct block_list *bl,va_list ap) {
* &2 = the target should be able to walk to the target tile.
* &4 = there shouldn't be any players around the target tile (use the no_spawn_on_player setting)
*------------------------------------------*/
-int map_search_freecell(struct block_list *src, int16 m, int16 *x,int16 *y, int16 rx, int16 ry, int flag)
+static int map_search_freecell(struct block_list *src, int16 m, int16 *x, int16 *y, int16 rx, int16 ry, int flag)
{
int tries, spawn=0;
int bx, by;
@@ -1556,9 +1668,9 @@ int map_search_freecell(struct block_list *src, int16 m, int16 *x,int16 *y, int1
* flag:
* 0x1 - only count standing units
*------------------------------------------*/
-bool map_closest_freecell(int16 m, const struct block_list *bl, int16 *x, int16 *y, int type, int flag)
+static bool map_closest_freecell(int16 m, const struct block_list *bl, int16 *x, int16 *y, int type, int flag)
{
- uint8 dir = 6;
+ enum unit_dir dir = UNIT_DIR_EAST;
int16 tx;
int16 ty;
int costrange = 10;
@@ -1577,7 +1689,7 @@ bool map_closest_freecell(int16 m, const struct block_list *bl, int16 *x, int16
short dy = diry[dir];
//Linear search
- if(dir%2 == 0 && costrange%MOVE_COST == 0) {
+ if (!unit_is_diagonal_dir(dir) && (costrange % MOVE_COST) == 0) {
tx = *x+dx*(costrange/MOVE_COST);
ty = *y+dy*(costrange/MOVE_COST);
if (!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m, bl, tx, ty, CELL_CHKPASS)) {
@@ -1587,7 +1699,7 @@ bool map_closest_freecell(int16 m, const struct block_list *bl, int16 *x, int16
}
}
//Full diagonal search
- else if(dir%2 == 1 && costrange%MOVE_DIAGONAL_COST == 0) {
+ else if (unit_is_diagonal_dir(dir) && (costrange % MOVE_DIAGONAL_COST) == 0) {
tx = *x+dx*(costrange/MOVE_DIAGONAL_COST);
ty = *y+dy*(costrange/MOVE_DIAGONAL_COST);
if (!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m, bl, tx, ty, CELL_CHKPASS)) {
@@ -1597,16 +1709,24 @@ bool map_closest_freecell(int16 m, const struct block_list *bl, int16 *x, int16
}
}
//One cell diagonal, rest linear (TODO: Find a better algorithm for this)
- else if(dir%2 == 1 && costrange%MOVE_COST == 4) {
- tx = *x+dx*((dir%4==3)?(costrange/MOVE_COST):1);
- ty = *y+dy*((dir%4==1)?(costrange/MOVE_COST):1);
+ else if (unit_is_diagonal_dir(dir) && (costrange % MOVE_COST) == 4) {
+ tx = *x + dx;
+ ty = *y + dy;
+ if (unit_is_dir_or_opposite(dir, UNIT_DIR_SOUTHWEST))
+ tx = tx * costrange / MOVE_COST;
+ if (unit_is_dir_or_opposite(dir, UNIT_DIR_NORTHWEST))
+ ty = ty * costrange / MOVE_COST;
if (!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m, bl, tx, ty, CELL_CHKPASS)) {
*x = tx;
*y = ty;
return true;
}
- tx = *x+dx*((dir%4==1)?(costrange/MOVE_COST):1);
- ty = *y+dy*((dir%4==3)?(costrange/MOVE_COST):1);
+ tx = *x + dx;
+ ty = *y + dy;
+ if (unit_is_dir_or_opposite(dir, UNIT_DIR_NORTHWEST))
+ tx = tx * costrange / MOVE_COST;
+ if (unit_is_dir_or_opposite(dir, UNIT_DIR_SOUTHWEST))
+ ty = ty * costrange / MOVE_COST;
if (!map->count_oncell(m, tx, ty, type, flag) && map->getcell(m, bl, tx, ty, CELL_CHKPASS)) {
*x = tx;
*y = ty;
@@ -1615,17 +1735,17 @@ bool map_closest_freecell(int16 m, const struct block_list *bl, int16 *x, int16
}
//Get next direction
- if (dir == 5) {
+ if (dir == UNIT_DIR_SOUTHEAST) {
//Diagonal search complete, repeat with higher cost range
if(costrange == 14) costrange += 6;
else if(costrange == 28 || costrange >= 38) costrange += 2;
else costrange += 4;
- dir = 6;
- } else if (dir == 4) {
+ dir = UNIT_DIR_EAST;
+ } else if (dir == UNIT_DIR_SOUTH) {
//Linear search complete, switch to diagonal directions
- dir = 7;
+ dir = UNIT_DIR_NORTHEAST;
} else {
- dir = (dir+2)%8;
+ dir = unit_get_ccw90_dir(dir);
}
}
@@ -1640,8 +1760,9 @@ bool map_closest_freecell(int16 m, const struct block_list *bl, int16 *x, int16
* @m, @x, @y mapid,x,y
* @first_charid, @second_charid, @third_charid, looting priority
* @flag: &1 MVP item. &2 do stacking check.
+ * @showdropeffect: show effect when the item is dropped.
*------------------------------------------*/
-int map_addflooritem(const struct block_list *bl, struct item *item_data, int amount, int16 m, int16 x, int16 y, int first_charid, int second_charid, int third_charid, int flags)
+static int map_addflooritem(const struct block_list *bl, struct item *item_data, int amount, int16 m, int16 x, int16 y, int first_charid, int second_charid, int third_charid, int flags, bool showdropeffect)
{
int r;
struct flooritem_data *fitem=NULL;
@@ -1660,6 +1781,7 @@ int map_addflooritem(const struct block_list *bl, struct item *item_data, int am
fitem->bl.x = x;
fitem->bl.y = y;
fitem->bl.id = map->get_new_object_id();
+ fitem->showdropeffect = showdropeffect;
if(fitem->bl.id==0){
ers_free(map->flooritem_ers, fitem);
return 0;
@@ -1688,7 +1810,7 @@ int map_addflooritem(const struct block_list *bl, struct item *item_data, int am
/**
* @see DBCreateData
*/
-struct DBData create_charid2nick(union DBKey key, va_list args)
+static struct DBData create_charid2nick(union DBKey key, va_list args)
{
struct charid2nick *p;
CREATE(p, struct charid2nick, 1);
@@ -1697,7 +1819,7 @@ struct DBData create_charid2nick(union DBKey key, va_list args)
/// Adds(or replaces) the nick of charid to nick_db and fullfils pending requests.
/// Does nothing if the character is online.
-void map_addnickdb(int charid, const char* nick)
+static void map_addnickdb(int charid, const char *nick)
{
struct charid2nick* p;
struct charid_request* req;
@@ -1721,7 +1843,7 @@ void map_addnickdb(int charid, const char* nick)
/// Removes the nick of charid from nick_db.
/// Sends name to all pending requests on charid.
-void map_delnickdb(int charid, const char* name)
+static void map_delnickdb(int charid, const char *name)
{
struct charid2nick* p;
struct charid_request* req;
@@ -1745,7 +1867,7 @@ void map_delnickdb(int charid, const char* name)
/// Notifies sd of the nick of charid.
/// Uses the name in the character if online.
/// Uses the name in nick_db if offline.
-void map_reqnickdb(struct map_session_data * sd, int charid)
+static void map_reqnickdb(struct map_session_data *sd, int charid)
{
struct charid2nick* p;
struct charid_request* req;
@@ -1774,7 +1896,7 @@ void map_reqnickdb(struct map_session_data * sd, int charid)
/*==========================================
* add bl to id_db
*------------------------------------------*/
-void map_addiddb(struct block_list *bl)
+static void map_addiddb(struct block_list *bl)
{
nullpo_retv(bl);
@@ -1786,7 +1908,7 @@ void map_addiddb(struct block_list *bl)
struct mob_data *md = BL_UCAST(BL_MOB, bl);
idb_put(map->mobid_db,bl->id,bl);
- if( md->state.boss )
+ if (md->state.boss == BTYPE_MVP)
idb_put(map->bossid_db, bl->id, bl);
}
@@ -1799,7 +1921,7 @@ void map_addiddb(struct block_list *bl)
/*==========================================
* remove bl from id_db
*------------------------------------------*/
-void map_deliddb(struct block_list *bl)
+static void map_deliddb(struct block_list *bl)
{
nullpo_retv(bl);
@@ -1821,7 +1943,8 @@ void map_deliddb(struct block_list *bl)
/*==========================================
* Standard call when a player connection is closed.
*------------------------------------------*/
-int map_quit(struct map_session_data *sd) {
+static int map_quit(struct map_session_data *sd)
+{
int i;
nullpo_ret(sd);
@@ -1848,6 +1971,9 @@ int map_quit(struct map_session_data *sd) {
if( sd->bg_id && !sd->bg_queue.arena ) /* TODO: dump this chunk after bg_queue is fully enabled */
bg->team_leave(sd,BGTL_QUIT);
+ if (sd->status.clan_id)
+ clan->member_offline(sd);
+
if (sd->state.autotrade && core->runflag != MAPSERVER_ST_SHUTDOWN && !channel->config->closing)
pc->autotrade_update(sd,PAUC_REMOVE);
@@ -1867,6 +1993,7 @@ int map_quit(struct map_session_data *sd) {
}
npc->script_event(sd, NPCE_LOGOUT);
+ rodex->clean(sd, 0);
//Unit_free handles clearing the player related data,
//map->quit handles extra specific data which is related to quitting normally
@@ -1882,6 +2009,7 @@ int map_quit(struct map_session_data *sd) {
case SC_GDSKILL_REGENERATION:
if( !sd->sc.data[i]->val4 )
break;
+ FALLTHROUGH
default:
status_change_end(&sd->bl, (sc_type)i, INVALID_TIMER);
}
@@ -1946,7 +2074,7 @@ int map_quit(struct map_session_data *sd) {
* @return The searched map_session_data, if it exists.
* @retval NULL if the ID is invalid or doesn't belong to a player unit.
*/
-struct map_session_data *map_id2sd(int id)
+static struct map_session_data *map_id2sd(int id)
{
struct block_list *bl = NULL;
if (id <= 0)
@@ -1966,7 +2094,7 @@ struct map_session_data *map_id2sd(int id)
* @return The searched npc_data, if it exists.
* @retval NULL if the ID is invalid or doesn't belong to a NPC.
*/
-struct npc_data *map_id2nd(int id)
+static struct npc_data *map_id2nd(int id)
{
// just a id2bl lookup because there's no npc_db
struct block_list* bl = map->id2bl(id);
@@ -1983,7 +2111,7 @@ struct npc_data *map_id2nd(int id)
* @return The searched mob_data, if it exists.
* @retval NULL if the ID is invalid or doesn't belong to a mob unit.
*/
-struct mob_data *map_id2md(int id)
+static struct mob_data *map_id2md(int id)
{
struct block_list *bl = NULL;
if (id <= 0)
@@ -2003,7 +2131,7 @@ struct mob_data *map_id2md(int id)
* @return The searched flooritem_data, if it exists.
* @retval NULL if the ID is invalid or doesn't belong to a floor item.
*/
-struct flooritem_data *map_id2fi(int id)
+static struct flooritem_data *map_id2fi(int id)
{
struct block_list* bl = map->id2bl(id);
@@ -2017,7 +2145,7 @@ struct flooritem_data *map_id2fi(int id)
* @return The searched chat_data, if it exists.
* @retval NULL if the ID is invalid or doesn't belong to a chat.
*/
-struct chat_data *map_id2cd(int id)
+static struct chat_data *map_id2cd(int id)
{
struct block_list* bl = map->id2bl(id);
@@ -2031,7 +2159,7 @@ struct chat_data *map_id2cd(int id)
* @return The searched skill_unit data, if it exists.
* @retval NULL if the ID is invalid or doesn't belong to a skill unit.
*/
-struct skill_unit *map_id2su(int id)
+static struct skill_unit *map_id2su(int id)
{
struct block_list* bl = map->id2bl(id);
@@ -2045,7 +2173,7 @@ struct skill_unit *map_id2su(int id)
* @return The searched pet_data, if it exists.
* @retval NULL if the ID is invalid or doesn't belong to a pet.
*/
-struct pet_data *map_id2pd(int id)
+static struct pet_data *map_id2pd(int id)
{
struct block_list* bl = map->id2bl(id);
@@ -2059,7 +2187,7 @@ struct pet_data *map_id2pd(int id)
* @return The searched homun_data, if it exists.
* @retval NULL if the ID is invalid or doesn't belong to a homunculus.
*/
-struct homun_data *map_id2hd(int id)
+static struct homun_data *map_id2hd(int id)
{
struct block_list* bl = map->id2bl(id);
@@ -2073,7 +2201,7 @@ struct homun_data *map_id2hd(int id)
* @return The searched mercenary_data, if it exists.
* @retval NULL if the ID is invalid or doesn't belong to a mercenary.
*/
-struct mercenary_data *map_id2mc(int id)
+static struct mercenary_data *map_id2mc(int id)
{
struct block_list* bl = map->id2bl(id);
@@ -2087,7 +2215,7 @@ struct mercenary_data *map_id2mc(int id)
* @return The searched elemental_data, if it exists.
* @retval NULL if the ID is invalid or doesn't belong to an elemental.
*/
-struct elemental_data *map_id2ed(int id)
+static struct elemental_data *map_id2ed(int id)
{
struct block_list* bl = map->id2bl(id);
@@ -2103,7 +2231,7 @@ struct elemental_data *map_id2ed(int id)
* @return The searched block_list, if it exists.
* @retval NULL if the ID is invalid.
*/
-struct block_list *map_id2bl(int id)
+static struct block_list *map_id2bl(int id)
{
return idb_get(map->id_db, id);
}
@@ -2115,13 +2243,14 @@ struct block_list *map_id2bl(int id)
* @retval true if the ID exists and is valid.
* @retval false otherwise.
*/
-bool map_blid_exists(int id)
+static bool map_blid_exists(int id)
{
return (idb_exists(map->id_db,id));
}
/// Returns the nick of the target charid or NULL if unknown (requests the nick to the char server).
-const char *map_charid2nick(int charid) {
+static const char *map_charid2nick(int charid)
+{
struct charid2nick *p;
struct map_session_data* sd;
@@ -2138,7 +2267,7 @@ const char *map_charid2nick(int charid) {
}
/// Returns the struct map_session_data of the charid or NULL if the char is not online.
-struct map_session_data* map_charid2sd(int charid)
+static struct map_session_data *map_charid2sd(int charid)
{
struct block_list *bl = idb_get(map->charid_db, charid);
if (bl)
@@ -2151,30 +2280,25 @@ struct map_session_data* map_charid2sd(int charid)
* (without sensitive case if necessary)
* return map_session_data pointer or NULL
*------------------------------------------*/
-struct map_session_data * map_nick2sd(const char *nick)
+static struct map_session_data *map_nick2sd(const char *nick, bool allow_partial)
{
- struct map_session_data* sd;
- struct map_session_data* found_sd;
- struct s_mapiterator* iter;
- size_t nicklen;
- int qty = 0;
-
- if( nick == NULL )
+ if (nick == NULL)
return NULL;
- nicklen = strlen(nick);
- iter = mapit_getallusers();
+ struct s_mapiterator *iter = mapit_getallusers();
+ struct map_session_data *found_sd = NULL;
+
+ if (battle_config.partial_name_scan && allow_partial) {
+ int nicklen = (int)strlen(nick);
+ int qty = 0;
- found_sd = NULL;
- for (sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); sd = BL_UCAST(BL_PC, mapit->next(iter))) {
- if( battle_config.partial_name_scan )
- {// partial name search
- if( strnicmp(sd->status.name, nick, nicklen) == 0 )
- {
+ // partial name search
+ for (struct map_session_data *sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); sd = BL_UCAST(BL_PC, mapit->next(iter))) {
+ if (strnicmp(sd->status.name, nick, nicklen) == 0) {
found_sd = sd;
- if( strcmp(sd->status.name, nick) == 0 )
- {// Perfect Match
+ if (strcmp(sd->status.name, nick) == 0) {
+ // Perfect Match
qty = 1;
break;
}
@@ -2182,24 +2306,27 @@ struct map_session_data * map_nick2sd(const char *nick)
qty++;
}
}
- else if( strcasecmp(sd->status.name, nick) == 0 )
- {// exact search only
- found_sd = sd;
- break;
+
+ if (qty != 1)
+ found_sd = NULL;
+ } else {
+ // exact search only
+ for (struct map_session_data *sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); sd = BL_UCAST(BL_PC, mapit->next(iter))) {
+ if (strcasecmp(sd->status.name, nick) == 0) {
+ found_sd = sd;
+ break;
+ }
}
}
mapit->free(iter);
- if( battle_config.partial_name_scan && qty != 1 )
- found_sd = NULL;
-
return found_sd;
}
/*==========================================
* Convext Mirror
*------------------------------------------*/
-struct mob_data *map_getmob_boss(int16 m)
+static struct mob_data *map_getmob_boss(int16 m)
{
struct DBIterator *iter;
struct mob_data *md = NULL;
@@ -2217,7 +2344,7 @@ struct mob_data *map_getmob_boss(int16 m)
return (found)? md : NULL;
}
-struct mob_data *map_id2boss(int id)
+static struct mob_data *map_id2boss(int id)
{
struct block_list *bl = NULL;
if (id <= 0)
@@ -2235,7 +2362,7 @@ struct mob_data *map_id2boss(int id)
*
* @return The equivalent race bitmask.
*/
-uint32 map_race_id2mask(int race)
+static uint32 map_race_id2mask(int race)
{
if (race >= RC_FORMLESS && race < RC_MAX)
return 1 << race;
@@ -2263,7 +2390,7 @@ uint32 map_race_id2mask(int race)
/// Applies func to all the players in the db.
/// Stops iterating if func returns -1.
-void map_vforeachpc(int (*func)(struct map_session_data* sd, va_list args), va_list args)
+static void map_vforeachpc(int (*func)(struct map_session_data *sd, va_list args), va_list args)
{
struct DBIterator *iter = db_iterator(map->pc_db);
struct map_session_data *sd = NULL;
@@ -2285,7 +2412,8 @@ void map_vforeachpc(int (*func)(struct map_session_data* sd, va_list args), va_l
/// Applies func to all the players in the db.
/// Stops iterating if func returns -1.
/// @see map_vforeachpc
-void map_foreachpc(int (*func)(struct map_session_data* sd, va_list args), ...) {
+static void map_foreachpc(int (*func)(struct map_session_data *sd, va_list args), ...)
+{
va_list args;
va_start(args, func);
@@ -2295,7 +2423,7 @@ void map_foreachpc(int (*func)(struct map_session_data* sd, va_list args), ...)
/// Applies func to all the mobs in the db.
/// Stops iterating if func returns -1.
-void map_vforeachmob(int (*func)(struct mob_data* md, va_list args), va_list args)
+static void map_vforeachmob(int (*func)(struct mob_data *md, va_list args), va_list args)
{
struct DBIterator *iter = db_iterator(map->mobid_db);
struct mob_data *md = NULL;
@@ -2316,7 +2444,8 @@ void map_vforeachmob(int (*func)(struct mob_data* md, va_list args), va_list arg
/// Applies func to all the mobs in the db.
/// Stops iterating if func returns -1.
/// @see map_vforeachmob
-void map_foreachmob(int (*func)(struct mob_data* md, va_list args), ...) {
+static void map_foreachmob(int (*func)(struct mob_data *md, va_list args), ...)
+{
va_list args;
va_start(args, func);
@@ -2326,7 +2455,7 @@ void map_foreachmob(int (*func)(struct mob_data* md, va_list args), ...) {
/// Applies func to all the npcs in the db.
/// Stops iterating if func returns -1.
-void map_vforeachnpc(int (*func)(struct npc_data* nd, va_list args), va_list args)
+static void map_vforeachnpc(int (*func)(struct npc_data *nd, va_list args), va_list args)
{
struct DBIterator *iter = db_iterator(map->id_db);
struct block_list *bl = NULL;
@@ -2350,7 +2479,8 @@ void map_vforeachnpc(int (*func)(struct npc_data* nd, va_list args), va_list arg
/// Applies func to all the npcs in the db.
/// Stops iterating if func returns -1.
/// @see map_vforeachnpc
-void map_foreachnpc(int (*func)(struct npc_data* nd, va_list args), ...) {
+static void map_foreachnpc(int (*func)(struct npc_data *nd, va_list args), ...)
+{
va_list args;
va_start(args, func);
@@ -2360,7 +2490,7 @@ void map_foreachnpc(int (*func)(struct npc_data* nd, va_list args), ...) {
/// Applies func to everything in the db.
/// Stops iterating gif func returns -1.
-void map_vforeachregen(int (*func)(struct block_list* bl, va_list args), va_list args)
+static void map_vforeachregen(int (*func)(struct block_list *bl, va_list args), va_list args)
{
struct DBIterator *iter = db_iterator(map->regen_db);
struct block_list *bl = NULL;
@@ -2381,7 +2511,8 @@ void map_vforeachregen(int (*func)(struct block_list* bl, va_list args), va_list
/// Applies func to everything in the db.
/// Stops iterating gif func returns -1.
/// @see map_vforeachregen
-void map_foreachregen(int (*func)(struct block_list* bl, va_list args), ...) {
+static void map_foreachregen(int (*func)(struct block_list *bl, va_list args), ...)
+{
va_list args;
va_start(args, func);
@@ -2391,7 +2522,7 @@ void map_foreachregen(int (*func)(struct block_list* bl, va_list args), ...) {
/// Applies func to everything in the db.
/// Stops iterating if func returns -1.
-void map_vforeachiddb(int (*func)(struct block_list* bl, va_list args), va_list args)
+static void map_vforeachiddb(int (*func)(struct block_list *bl, va_list args), va_list args)
{
struct DBIterator *iter = db_iterator(map->id_db);
struct block_list *bl = NULL;
@@ -2412,7 +2543,8 @@ void map_vforeachiddb(int (*func)(struct block_list* bl, va_list args), va_list
/// Applies func to everything in the db.
/// Stops iterating if func returns -1.
/// @see map_vforeachiddb
-void map_foreachiddb(int (*func)(struct block_list* bl, va_list args), ...) {
+static void map_foreachiddb(int (*func)(struct block_list *bl, va_list args), ...)
+{
va_list args;
va_start(args, func);
@@ -2444,7 +2576,8 @@ struct s_mapiterator {
/// @param flags Flags of the iterator
/// @param type Target types
/// @return Iterator
-struct s_mapiterator* mapit_alloc(enum e_mapitflags flags, enum bl_type types) {
+static struct s_mapiterator *mapit_alloc(enum e_mapitflags flags, enum bl_type types)
+{
struct s_mapiterator* iter;
iter = ers_alloc(map->iterator_ers, struct s_mapiterator);
@@ -2459,7 +2592,8 @@ struct s_mapiterator* mapit_alloc(enum e_mapitflags flags, enum bl_type types) {
/// Frees the iterator.
///
/// @param iter Iterator
-void mapit_free(struct s_mapiterator* iter) {
+static void mapit_free(struct s_mapiterator *iter)
+{
nullpo_retv(iter);
dbi_destroy(iter->dbi);
@@ -2471,7 +2605,8 @@ void mapit_free(struct s_mapiterator* iter) {
///
/// @param iter Iterator
/// @return first block_list or NULL
-struct block_list* mapit_first(struct s_mapiterator* iter) {
+static struct block_list *mapit_first(struct s_mapiterator *iter)
+{
struct block_list* bl;
nullpo_retr(NULL,iter);
@@ -2488,7 +2623,8 @@ struct block_list* mapit_first(struct s_mapiterator* iter) {
///
/// @param iter Iterator
/// @return last block_list or NULL
-struct block_list* mapit_last(struct s_mapiterator* iter) {
+static struct block_list *mapit_last(struct s_mapiterator *iter)
+{
struct block_list* bl;
nullpo_retr(NULL,iter);
@@ -2505,7 +2641,8 @@ struct block_list* mapit_last(struct s_mapiterator* iter) {
///
/// @param iter Iterator
/// @return next block_list or NULL
-struct block_list* mapit_next(struct s_mapiterator* iter) {
+static struct block_list *mapit_next(struct s_mapiterator *iter)
+{
struct block_list* bl;
nullpo_retr(NULL,iter);
@@ -2526,7 +2663,8 @@ struct block_list* mapit_next(struct s_mapiterator* iter) {
///
/// @param iter Iterator
/// @return previous block_list or NULL
-struct block_list* mapit_prev(struct s_mapiterator* iter) {
+static struct block_list *mapit_prev(struct s_mapiterator *iter)
+{
struct block_list* bl;
nullpo_retr(NULL,iter);
@@ -2546,7 +2684,8 @@ struct block_list* mapit_prev(struct s_mapiterator* iter) {
///
/// @param iter Iterator
/// @return true if it exists
-bool mapit_exists(struct s_mapiterator* iter) {
+static bool mapit_exists(struct s_mapiterator *iter)
+{
nullpo_retr(false,iter);
return dbi_exists(iter->dbi);
@@ -2555,7 +2694,8 @@ bool mapit_exists(struct s_mapiterator* iter) {
/*==========================================
* Add npc-bl to id_db, basically register npc to map
*------------------------------------------*/
-bool map_addnpc(int16 m,struct npc_data *nd) {
+static bool map_addnpc(int16 m, struct npc_data *nd)
+{
nullpo_ret(nd);
if( m < 0 || m >= map->count )
@@ -2577,7 +2717,8 @@ bool map_addnpc(int16 m,struct npc_data *nd) {
*-----------------------------------------*/
// Stores the spawn data entry in the mob list.
// Returns the index of successful, or -1 if the list was full.
-int map_addmobtolist(unsigned short m, struct spawn_data *spawn) {
+static int map_addmobtolist(unsigned short m, struct spawn_data *spawn)
+{
int i;
nullpo_retr(-1, spawn);
ARR_FIND( 0, MAX_MOB_LIST_PER_MAP, i, map->list[m].moblist[i] == NULL );
@@ -2588,7 +2729,8 @@ int map_addmobtolist(unsigned short m, struct spawn_data *spawn) {
return -1;
}
-void map_spawnmobs(int16 m) {
+static void map_spawnmobs(int16 m)
+{
int i, k=0;
if (map->list[m].mob_delete_timer != INVALID_TIMER) {
//Mobs have not been removed yet [Skotlex]
@@ -2607,7 +2749,7 @@ void map_spawnmobs(int16 m) {
}
}
-int map_removemobs_sub(struct block_list *bl, va_list ap)
+static int map_removemobs_sub(struct block_list *bl, va_list ap)
{
struct mob_data *md = NULL;
nullpo_ret(bl);
@@ -2636,7 +2778,8 @@ int map_removemobs_sub(struct block_list *bl, va_list ap)
return 1;
}
-int map_removemobs_timer(int tid, int64 tick, int id, intptr_t data) {
+static int map_removemobs_timer(int tid, int64 tick, int id, intptr_t data)
+{
int count;
const int16 m = id;
@@ -2660,7 +2803,8 @@ int map_removemobs_timer(int tid, int64 tick, int id, intptr_t data) {
return 1;
}
-void map_removemobs(int16 m) {
+static void map_removemobs(int16 m)
+{
Assert_retv(m >= 0 && m < map->count);
if (map->list[m].mob_delete_timer != INVALID_TIMER) // should never happen
return; //Mobs are already scheduled for removal
@@ -2671,7 +2815,8 @@ void map_removemobs(int16 m) {
/*==========================================
* Hookup, get map_id from map_name
*------------------------------------------*/
-int16 map_mapname2mapid(const char* name) {
+static int16 map_mapname2mapid(const char *name)
+{
unsigned short map_index;
map_index = mapindex->name2id(name);
if (!map_index)
@@ -2682,7 +2827,8 @@ int16 map_mapname2mapid(const char* name) {
/*==========================================
* Returns the map of the given mapindex. [Skotlex]
*------------------------------------------*/
-int16 map_mapindex2mapid(unsigned short map_index) {
+static int16 map_mapindex2mapid(unsigned short map_index)
+{
if (!map_index || map_index >= MAX_MAPINDEX)
return -1;
@@ -2693,7 +2839,8 @@ int16 map_mapindex2mapid(unsigned short map_index) {
/*==========================================
* Switching Ip, port ? (like changing map_server) get ip/port from map_name
*------------------------------------------*/
-int map_mapname2ipport(unsigned short name, uint32* ip, uint16* port) {
+static int map_mapname2ipport(unsigned short name, uint32 *ip, uint16 *port)
+{
struct map_data_other_server *mdos;
nullpo_retr(-1, ip);
@@ -2706,63 +2853,70 @@ int map_mapname2ipport(unsigned short name, uint32* ip, uint16* port) {
return 0;
}
-/*==========================================
-* Checks if both dirs point in the same direction.
-*------------------------------------------*/
-int map_check_dir(int s_dir,int t_dir)
+/**
+ * Checks if both dirs point in the same direction.
+ * @param s_dir: direction source is facing
+ * @param t_dir: direction target is facing
+ * @return 0: success(both face the same direction), 1: failure
+ **/
+static int map_check_dir(enum unit_dir s_dir, enum unit_dir t_dir)
{
- if(s_dir == t_dir)
+ if (s_dir == t_dir || ((t_dir + UNIT_DIR_MAX - 1) % UNIT_DIR_MAX) == s_dir
+ || ((t_dir + UNIT_DIR_MAX + 1) % UNIT_DIR_MAX) == s_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;
}
-/*==========================================
+/**
* Returns the direction of the given cell, relative to 'src'
- *------------------------------------------*/
-uint8 map_calc_dir(struct block_list* src, int16 x, int16 y)
+ * @param src: object to put in relation between coordinates
+ * @param x: x-coordinate of cell
+ * @param y: y-coordinate of cell
+ * @return the direction of the given cell, relative to 'src'
+ **/
+static enum unit_dir map_calc_dir(const struct block_list *src, int16 x, int16 y)
{
- uint8 dir = 0;
- int dx, dy;
-
- nullpo_ret(src);
+ nullpo_retr(UNIT_DIR_NORTH, src);
+ enum unit_dir dir = UNIT_DIR_NORTH;
- dx = x-src->x;
- dy = y-src->y;
+ int dx = x - src->x;
+ int dy = y - src->y;
if (dx == 0 && dy == 0) {
// both are standing on the same spot.
// aegis-style, makes knockback default to the left.
// athena-style, makes knockback default to behind 'src'.
- dir = (battle_config.knockback_left ? 6 : unit->getdir(src));
- } else if (dx >= 0 && dy >=0) {
- // upper-right
- if( dx*2 < dy || dx == 0 ) dir = 0; // up
- else if( dx > dy*2+1 || dy == 0 ) dir = 6; // right
- else dir = 7; // up-right
+ if (battle_config.knockback_left != 0)
+ dir = UNIT_DIR_EAST;
+ else
+ dir = unit->getdir(src);
+ } else if (dx >= 0 && dy >= 0) {
+ if (dx * 2 < dy || dx == 0)
+ dir = UNIT_DIR_NORTH;
+ else if (dx > dy * 2 + 1 || dy == 0)
+ dir = UNIT_DIR_EAST;
+ else
+ dir = UNIT_DIR_NORTHEAST;
} else if (dx >= 0 && dy <= 0) {
- // lower-right
- if( dx*2 < -dy || dx == 0 ) dir = 4; // down
- else if( dx > -dy*2+1 || dy == 0 ) dir = 6; // right
- else dir = 5; // down-right
+ if (dx * 2 < -dy || dx == 0)
+ dir = UNIT_DIR_SOUTH;
+ else if (dx > -dy * 2 + 1 || dy == 0)
+ dir = UNIT_DIR_EAST;
+ else
+ dir = UNIT_DIR_SOUTHEAST;
} else if (dx <= 0 && dy <= 0) {
- // lower-left
- if( dx*2 > dy || dx == 0 ) dir = 4; // down
- else if( dx < dy*2-1 || dy == 0 ) dir = 2; // left
- else dir = 3; // down-left
+ if (dx * 2 > dy || dx == 0 )
+ dir = UNIT_DIR_SOUTH;
+ else if (dx < dy * 2 + 1 || dy == 0)
+ dir = UNIT_DIR_WEST;
+ else
+ dir = UNIT_DIR_SOUTHWEST;
} else {
- // upper-left
- if( -dx*2 < dy || dx == 0 ) dir = 0; // up
- else if( -dx > dy*2+1 || dy == 0) dir = 2; // left
- else dir = 1; // up-left
+ if (-dx * 2 < dy || dx == 0 )
+ dir = UNIT_DIR_NORTH;
+ else if (-dx > dy * 2 + 1 || dy == 0)
+ dir = UNIT_DIR_WEST;
+ else
+ dir = UNIT_DIR_NORTHWEST;
}
return dir;
}
@@ -2771,7 +2925,7 @@ uint8 map_calc_dir(struct block_list* src, int16 x, int16 y)
* Randomizes target cell x,y to a random walkable cell that
* has the same distance from object as given coordinates do. [Skotlex]
*------------------------------------------*/
-int map_random_dir(struct block_list *bl, int16 *x, int16 *y)
+static int map_random_dir(struct block_list *bl, int16 *x, int16 *y)
{
short xi;
short yi;
@@ -2790,11 +2944,11 @@ int map_random_dir(struct block_list *bl, int16 *x, int16 *y)
if (dist < 1) dist =1;
do {
- int j = 1 + 2*(rnd()%4); //Pick a random diagonal direction
+ enum unit_dir dir = unit_get_rnd_diagonal_dir();
short segment = 1+(rnd()%dist); //Pick a random interval from the whole vector in that direction
- xi = bl->x + segment*dirx[j];
+ xi = bl->x + segment * dirx[dir];
segment = (short)sqrt((float)(dist2 - segment*segment)); //The complement of the previously picked segment
- yi = bl->y + segment*diry[j];
+ yi = bl->y + segment * diry[dir];
} while ((map->getcell(bl->m, bl, xi, yi, CELL_CHKNOPASS) || !path->search(NULL, bl, bl->m, bl->x, bl->y, xi, yi, 1, CELL_CHKNOREACH))
&& (++i)<100);
@@ -2807,7 +2961,8 @@ int map_random_dir(struct block_list *bl, int16 *x, int16 *y)
}
// gat system
-struct mapcell map_gat2cell(int gat) {
+static struct mapcell map_gat2cell(int gat)
+{
struct mapcell cell;
memset(&cell,0,sizeof(struct mapcell));
@@ -2828,7 +2983,8 @@ struct mapcell map_gat2cell(int gat) {
return cell;
}
-int map_cell2gat(struct mapcell cell) {
+static int map_cell2gat(struct mapcell cell)
+{
if( cell.walkable == 1 && cell.shootable == 1 && cell.water == 0 ) return 0;
if( cell.walkable == 0 && cell.shootable == 0 && cell.water == 0 ) return 1;
if( cell.walkable == 1 && cell.shootable == 1 && cell.water == 1 ) return 3;
@@ -2837,21 +2993,26 @@ int map_cell2gat(struct mapcell cell) {
ShowWarning("map_cell2gat: cell has no matching gat type\n");
return 1; // default to 'wall'
}
-void map_cellfromcache(struct map_data *m) {
- struct map_cache_map_info *info;
+/**
+ * Extracts a map's cell data from its compressed mapcache.
+ *
+ * @param[in, out] m The target map.
+ */
+static void map_cellfromcache(struct map_data *m)
+{
nullpo_retv(m);
- info = (struct map_cache_map_info *)m->cellPos;
- if (info) {
+ if (m->cell_buf.data != NULL) {
char decode_buffer[MAX_MAP_SIZE];
unsigned long size, xy;
int i;
- size = (unsigned long)info->xs*(unsigned long)info->ys;
+ size = (unsigned long)m->xs * (unsigned long)m->ys;
// TO-DO: Maybe handle the scenario, if the decoded buffer isn't the same size as expected? [Shinryo]
- decode_zip(decode_buffer, &size, m->cellPos+sizeof(struct map_cache_map_info), info->len);
+ grfio->decode_zip(decode_buffer, &size, m->cell_buf.data, m->cell_buf.len);
+
CREATE(m->cell, struct mapcell, size);
// Set cell properties
@@ -2871,11 +3032,13 @@ void map_cellfromcache(struct map_data *m) {
/*==========================================
* Confirm if celltype in (m,x,y) match the one given in cellchk
*------------------------------------------*/
-int map_getcell(int16 m, const struct block_list *bl, int16 x, int16 y, cell_chk cellchk) {
+static int map_getcell(int16 m, const struct block_list *bl, int16 x, int16 y, cell_chk cellchk)
+{
return (m < 0 || m >= map->count) ? 0 : map->list[m].getcellp(&map->list[m], bl, x, y, cellchk);
}
-int map_getcellp(struct map_data* m, const struct block_list *bl, int16 x, int16 y, cell_chk cellchk) {
+static int map_getcellp(struct map_data *m, const struct block_list *bl, int16 x, int16 y, cell_chk cellchk)
+{
struct mapcell cell;
nullpo_ret(m);
@@ -2943,7 +3106,8 @@ int map_getcellp(struct map_data* m, const struct block_list *bl, int16 x, int16
}
/* [Ind/Hercules] */
-int map_sub_getcellp(struct map_data* m, const struct block_list *bl, int16 x, int16 y, cell_chk cellchk) {
+static int map_sub_getcellp(struct map_data *m, const struct block_list *bl, int16 x, int16 y, cell_chk cellchk)
+{
nullpo_ret(m);
map->cellfromcache(m);
m->getcellp = map->getcellp;
@@ -2956,7 +3120,8 @@ int map_sub_getcellp(struct map_data* m, const struct block_list *bl, int16 x, i
* 'cell' - which flag to modify
* 'flag' - true = on, false = off
*------------------------------------------*/
-void map_setcell(int16 m, int16 x, int16 y, cell_t cell, bool flag) {
+static void map_setcell(int16 m, int16 x, int16 y, cell_t cell, bool flag)
+{
int j;
if( m < 0 || m >= map->count || x < 0 || x >= map->list[m].xs || y < 0 || y >= map->list[m].ys )
@@ -2982,7 +3147,8 @@ void map_setcell(int16 m, int16 x, int16 y, cell_t cell, bool flag) {
break;
}
}
-void map_sub_setcell(int16 m, int16 x, int16 y, cell_t cell, bool flag) {
+static void map_sub_setcell(int16 m, int16 x, int16 y, cell_t cell, bool flag)
+{
if( m < 0 || m >= map->count || x < 0 || x >= map->list[m].xs || y < 0 || y >= map->list[m].ys )
return;
@@ -2991,7 +3157,8 @@ void map_sub_setcell(int16 m, int16 x, int16 y, cell_t cell, bool flag) {
map->list[m].getcellp = map->getcellp;
map->list[m].setcell(m,x,y,cell,flag);
}
-void map_setgatcell(int16 m, int16 x, int16 y, int gat) {
+static void map_setgatcell(int16 m, int16 x, int16 y, int gat)
+{
int j;
struct mapcell cell;
@@ -3007,9 +3174,9 @@ void map_setgatcell(int16 m, int16 x, int16 y, int gat) {
}
/*==========================================
-* Invisible Walls
-*------------------------------------------*/
-void map_iwall_nextxy(int16 x, int16 y, int8 dir, int pos, int16 *x1, int16 *y1)
+ * Invisible Walls
+ *------------------------------------------*/
+static void map_iwall_nextxy(int16 x, int16 y, int8 dir, int pos, int16 *x1, int16 *y1)
{
nullpo_retv(x1);
nullpo_retv(y1);
@@ -3029,7 +3196,7 @@ void map_iwall_nextxy(int16 x, int16 y, int8 dir, int pos, int16 *x1, int16 *y1)
*y1 = y + pos;
}
-bool map_iwall_set(int16 m, int16 x, int16 y, int size, int8 dir, bool shootable, const char* wall_name)
+static bool map_iwall_set(int16 m, int16 x, int16 y, int size, int8 dir, bool shootable, const char *wall_name)
{
struct iwall_data *iwall;
int i;
@@ -3073,7 +3240,7 @@ bool map_iwall_set(int16 m, int16 x, int16 y, int size, int8 dir, bool shootable
return true;
}
-void map_iwall_get(struct map_session_data *sd)
+static void map_iwall_get(struct map_session_data *sd)
{
struct iwall_data *iwall;
struct DBIterator *iter;
@@ -3098,13 +3265,13 @@ void map_iwall_get(struct map_session_data *sd)
dbi_destroy(iter);
}
-void map_iwall_remove(const char *wall_name)
+static bool map_iwall_remove(const char *wall_name)
{
struct iwall_data *iwall;
int16 i, x1, y1;
if( (iwall = (struct iwall_data *)strdb_get(map->iwall_db, wall_name)) == NULL )
- return; // Nothing to do
+ return false;
for( i = 0; i < iwall->size; i++ ) {
map->iwall_nextxy(iwall->x, iwall->y, iwall->dir, i, &x1, &y1);
@@ -3117,12 +3284,13 @@ void map_iwall_remove(const char *wall_name)
map->list[iwall->m].iwall_num--;
strdb_remove(map->iwall_db, iwall->wall_name);
+ return true;
}
/**
* @see DBCreateData
*/
-struct DBData create_map_data_other_server(union DBKey key, va_list args)
+static struct DBData create_map_data_other_server(union DBKey key, va_list args)
{
struct map_data_other_server *mdos;
unsigned short map_index = (unsigned short)key.ui;
@@ -3135,7 +3303,7 @@ struct DBData create_map_data_other_server(union DBKey key, va_list args)
/*==========================================
* Add mapindex to db of another map server
*------------------------------------------*/
-int map_setipport(unsigned short map_index, uint32 ip, uint16 port)
+static int map_setipport(unsigned short map_index, uint32 ip, uint16 port)
{
struct map_data_other_server *mdos;
@@ -3157,7 +3325,7 @@ int map_setipport(unsigned short map_index, uint32 ip, uint16 port)
* Delete all the other maps server management
* @see DBApply
*/
-int map_eraseallipport_sub(union DBKey key, struct DBData *data, va_list va)
+static int map_eraseallipport_sub(union DBKey key, struct DBData *data, va_list va)
{
struct map_data_other_server *mdos = DB->data2ptr(data);
nullpo_ret(mdos);
@@ -3168,7 +3336,8 @@ int map_eraseallipport_sub(union DBKey key, struct DBData *data, va_list va)
return 0;
}
-int map_eraseallipport(void) {
+static int map_eraseallipport(void)
+{
map->map_db->foreach(map->map_db,map->eraseallipport_sub);
return 1;
}
@@ -3176,7 +3345,8 @@ int map_eraseallipport(void) {
/*==========================================
* Delete mapindex from db of another map server
*------------------------------------------*/
-int map_eraseipport(unsigned short map_index, uint32 ip, uint16 port) {
+static int map_eraseipport(unsigned short map_index, uint32 ip, uint16 port)
+{
struct map_data_other_server *mdos;
mdos = (struct map_data_other_server*)uidb_get(map->map_db,(unsigned int)map_index);
@@ -3191,113 +3361,163 @@ int map_eraseipport(unsigned short map_index, uint32 ip, uint16 port) {
return 0;
}
-/*==========================================
- * [Shinryo]: Init the mapcache
- *------------------------------------------*/
-char *map_init_mapcache(FILE *fp) {
- struct map_cache_main_header header;
- size_t size = 0;
- char *buffer;
-
- // No file open? Return..
- nullpo_ret(fp);
+/**
+ * Reads a map's compressed cell data from its mapcache file.
+ *
+ * @param[in,out] m The target map.
+ * @return The loading success state.
+ * @retval false in case of errors.
+ */
+static bool map_readfromcache(struct map_data *m)
+{
+ unsigned int file_size;
+ char file_path[256];
+ FILE *fp = NULL;
+ bool retval = false;
+ int16 version;
- // Get file size
- fseek(fp, 0, SEEK_END);
- size = ftell(fp);
- fseek(fp, 0, SEEK_SET);
+ nullpo_retr(false, m);
- // Allocate enough space
- CREATE(buffer, char, size);
+ snprintf(file_path, sizeof(file_path), "%s%s%s.%s", "maps/", DBPATH, m->name, "mcache");
+ fp = fopen(file_path, "rb");
- // No memory? Return..
- nullpo_ret(buffer);
+ if (fp == NULL) {
+ ShowWarning("map_readfromcache: Could not open the mapcache file for map '%s' at path '%s'.\n", m->name, file_path);
+ return false;
+ }
- // Read file into buffer..
- if(fread(buffer, sizeof(char), size, fp) != size) {
- ShowError("map_init_mapcache: Could not read entire mapcache file\n");
- aFree(buffer);
- return NULL;
+ if (fread(&version, sizeof(version), 1, fp) < 1) {
+ ShowError("map_readfromcache: Could not read file version for map '%s'.\n", m->name);
+ fclose(fp);
+ return false;
}
- rewind(fp);
+ fseek(fp, 0, SEEK_END);
+ file_size = (unsigned int)ftell(fp);
+ fseek(fp, 0, SEEK_SET); // Rewind file pointer before passing it to the read function.
- // Get main header to verify if data is corrupted
- if( fread(&header, sizeof(header), 1, fp) != 1 ) {
- ShowError("map_init_mapcache: Error obtaining main header!\n");
- aFree(buffer);
- return NULL;
- }
- if( GetULong((unsigned char *)&(header.file_size)) != size ) {
- ShowError("map_init_mapcache: Map cache is corrupted!\n");
- aFree(buffer);
- return NULL;
+ switch(version) {
+ case 1:
+ retval = map->readfromcache_v1(fp, m, file_size);
+ break;
+ default:
+ ShowError("map_readfromcache: Mapcache file has unknown version '%d' for map '%s'.\n", version, m->name);
+ break;
}
- return buffer;
+ fclose(fp);
+ return retval;
}
-/*==========================================
- * Map cache reading
- * [Shinryo]: Optimized some behaviour to speed this up
- *==========================================*/
-int map_readfromcache(struct map_data *m, char *buffer) {
- int i;
- struct map_cache_main_header *header = (struct map_cache_main_header *)buffer;
- struct map_cache_map_info *info = NULL;
- char *p = buffer + sizeof(struct map_cache_main_header);
-
- nullpo_ret(m);
- nullpo_ret(buffer);
-
- for(i = 0; i < header->map_count; i++) {
- info = (struct map_cache_map_info *)p;
+/**
+ * Reads a map's compressed cell data from its mapcache file (file format
+ * version 1).
+ *
+ * @param[in] fp The file pointer to read from (opened and closed by
+ * the caller).
+ * @param[in,out] m The target map.
+ * @param[in] file_size The size of the file to load from.
+ * @return The loading success state.
+ * @retval false in case of errors.
+ */
+static bool map_readfromcache_v1(FILE *fp, struct map_data *m, unsigned int file_size)
+{
+ struct map_cache_header mheader = { 0 };
+ uint8 md5buf[16] = { 0 };
+ int map_size;
+ nullpo_retr(false, fp);
+ nullpo_retr(false, m);
+
+ if (file_size <= sizeof(mheader) || fread(&mheader, sizeof(mheader), 1, fp) < 1) {
+ ShowError("map_readfromcache: Failed to read cache header for map '%s'.\n", m->name);
+ return false;
+ }
- if( strcmp(m->name, info->name) == 0 )
- break; // Map found
+ if (mheader.len <= 0) {
+ ShowError("map_readfromcache: A file with negative or zero compressed length passed '%d'.\n", mheader.len);
+ return false;
+ }
- // Jump to next entry..
- p += sizeof(struct map_cache_map_info) + info->len;
+ if (file_size < sizeof(mheader) + mheader.len) {
+ ShowError("map_readfromcache: An incomplete file passed for map '%s'.\n", m->name);
+ return false;
}
- if( info && i < header->map_count ) {
- unsigned long size;
+ if (mheader.ys <= 0 || mheader.xs <= 0) {
+ ShowError("map_readfromcache: A map with invalid size passed '%s' xs: '%d' ys: '%d'.\n", m->name, mheader.xs, mheader.ys);
+ return false;
+ }
- if( info->xs <= 0 || info->ys <= 0 )
- return 0;// Invalid
+ m->xs = mheader.xs;
+ m->ys = mheader.ys;
+ map_size = (int)mheader.xs * (int)mheader.ys;
- m->xs = info->xs;
- m->ys = info->ys;
- size = (unsigned long)info->xs*(unsigned long)info->ys;
+ if (map_size > MAX_MAP_SIZE) {
+ ShowWarning("map_readfromcache: %s exceeded MAX_MAP_SIZE of %d.\n", m->name, MAX_MAP_SIZE);
+ return false;
+ }
- if(size > MAX_MAP_SIZE) {
- ShowWarning("map_readfromcache: %s exceeded MAX_MAP_SIZE of %d\n", info->name, MAX_MAP_SIZE);
- return 0; // Say not found to remove it from list.. [Shinryo]
- }
+ CREATE(m->cell_buf.data, uint8, mheader.len);
+ m->cell_buf.len = mheader.len;
+ if (fread(m->cell_buf.data, mheader.len, 1, fp) < 1) {
+ ShowError("mapreadfromcache: Could not load the compressed cell data for map '%s'.\n", m->name);
+ aFree(m->cell_buf.data);
+ m->cell_buf.data = NULL;
+ m->cell_buf.len = 0;
+ return false;
+ }
- m->cellPos = p;
- m->cell = (struct mapcell *)0xdeadbeaf;
+ md5->binary(m->cell_buf.data, m->cell_buf.len, md5buf);
- return 1;
+ if (memcmp(md5buf, mheader.md5_checksum, sizeof(md5buf)) != 0) {
+ ShowError("mapreadfromcache: md5 checksum check failed for map '%s'\n", m->name);
+ aFree(m->cell_buf.data);
+ m->cell_buf.data = NULL;
+ m->cell_buf.len = 0;
+ return false;
}
- return 0; // Not found
+ m->cell = (struct mapcell *)0xdeadbeaf;
+
+ return true;
}
-int map_addmap(const char* mapname) {
+/**
+ * Adds a new empty map to the map list.
+ *
+ * Assumes that there's enough space in the map list.
+ *
+ * @param mapname The new map's name.
+ * @return success state.
+ */
+static int map_addmap(const char *mapname)
+{
map->list[map->count].instance_id = -1;
mapindex->getmapname(mapname, map->list[map->count++].name);
return 0;
}
-void map_delmapid(int id) {
+/**
+ * Removes a map from the map list.
+ *
+ * @param id The map ID.
+ */
+static void map_delmapid(int id)
+{
Assert_retv(id >= 0 && id < map->count);
ShowNotice("Removing map [ %s ] from maplist"CL_CLL"\n",map->list[id].name);
memmove(map->list+id, map->list+id+1, sizeof(map->list[0])*(map->count-id-1));
map->count--;
}
-int map_delmap(char* mapname) {
+/**
+ * Removes a map fromt he map list.
+ *
+ * @param mapname The name of the map to remove.
+ * @return the number of removed maps.
+ */
+static int map_delmap(const char *mapname)
+{
int i;
char map_name[MAP_NAME_LENGTH];
@@ -3320,7 +3540,8 @@ int map_delmap(char* mapname) {
/**
*
**/
-void map_zone_clear_single(struct map_zone_data *zone) {
+static void map_zone_clear_single(struct map_zone_data *zone)
+{
int i;
nullpo_retv(zone);
@@ -3362,7 +3583,7 @@ void map_zone_clear_single(struct map_zone_data *zone) {
/**
*
**/
-void map_zone_db_clear(void)
+static void map_zone_db_clear(void)
{
struct DBIterator *iter = db_iterator(map->zone_db);
struct map_zone_data *zone = NULL;
@@ -3380,24 +3601,29 @@ void map_zone_db_clear(void)
/* clear the main zone stuff */
map->zone_clear_single(&map->zone_all);
}
-void map_clean(int i) {
- int v;
+static void map_clean(int i)
+{
Assert_retv(i >= 0 && i < map->count);
- if(map->list[i].cell && map->list[i].cell != (struct mapcell *)0xdeadbeaf) aFree(map->list[i].cell);
- if(map->list[i].block) aFree(map->list[i].block);
- if(map->list[i].block_mob) aFree(map->list[i].block_mob);
- if(battle_config.dynamic_mobs) { //Dynamic mobs flag by [random]
- int j;
- if(map->list[i].mob_delete_timer != INVALID_TIMER)
+ if (map->list[i].cell && map->list[i].cell != (struct mapcell *)0xdeadbeaf)
+ aFree(map->list[i].cell);
+ if (map->list[i].block)
+ aFree(map->list[i].block);
+ if (map->list[i].block_mob)
+ aFree(map->list[i].block_mob);
+
+ if (battle_config.dynamic_mobs != 0) { //Dynamic mobs flag by [random]
+ if (map->list[i].mob_delete_timer != INVALID_TIMER)
timer->delete(map->list[i].mob_delete_timer, map->removemobs_timer);
- for (j=0; j<MAX_MOB_LIST_PER_MAP; j++)
- if (map->list[i].moblist[j]) aFree(map->list[i].moblist[j]);
+ for (int j = 0; j < MAX_MOB_LIST_PER_MAP; j++) {
+ if (map->list[i].moblist[j] != NULL)
+ aFree(map->list[i].moblist[j]);
+ }
}
- if( map->list[i].unit_count ) {
- if( map->list[i].units ) {
- for(v = 0; v < map->list[i].unit_count; v++) {
+ if (map->list[i].unit_count != 0) {
+ if (map->list[i].units != NULL) {
+ for (int v = 0; v < map->list[i].unit_count; v++) {
aFree(map->list[i].units[v]);
}
aFree(map->list[i].units);
@@ -3406,101 +3632,75 @@ void map_clean(int i) {
map->list[i].unit_count = 0;
}
- if( map->list[i].skill_count ) {
- if( map->list[i].skills ) {
- for(v = 0; v < map->list[i].skill_count; v++) {
- aFree(map->list[i].skills[v]);
- }
+ if (map->list[i].skill_count != 0) {
+ if (map->list[i].skills != NULL) {
+ for (int v = 0; v < map->list[i].skill_count; v++) {
+ aFree(map->list[i].skills[v]);
+ }
aFree(map->list[i].skills);
map->list[i].skills = NULL;
}
map->list[i].skill_count = 0;
}
- if( map->list[i].zone_mf_count ) {
- if( map->list[i].zone_mf ) {
- for(v = 0; v < map->list[i].zone_mf_count; v++) {
- aFree(map->list[i].zone_mf[v]);
- }
+ if (map->list[i].zone_mf_count != 0) {
+ if (map->list[i].zone_mf != NULL) {
+ for (int v = 0; v < map->list[i].zone_mf_count; v++) {
+ aFree(map->list[i].zone_mf[v]);
+ }
aFree(map->list[i].zone_mf);
map->list[i].zone_mf = NULL;
}
map->list[i].zone_mf_count = 0;
}
- if( map->list[i].channel )
- channel->delete(map->list[i].channel);
-}
-void do_final_maps(void) {
- int i, v = 0;
-
- for( i = 0; i < map->count; i++ ) {
-
- if(map->list[i].cell && map->list[i].cell != (struct mapcell *)0xdeadbeaf ) aFree(map->list[i].cell);
- if(map->list[i].block) aFree(map->list[i].block);
- if(map->list[i].block_mob) aFree(map->list[i].block_mob);
+ if (map->list[i].drop_list_count != 0)
+ map->list[i].drop_list_count = 0;
+ if (map->list[i].drop_list != NULL)
+ aFree(map->list[i].drop_list);
- if(battle_config.dynamic_mobs) { //Dynamic mobs flag by [random]
- int j;
- if(map->list[i].mob_delete_timer != INVALID_TIMER)
- timer->delete(map->list[i].mob_delete_timer, map->removemobs_timer);
- for (j=0; j<MAX_MOB_LIST_PER_MAP; j++)
- if (map->list[i].moblist[j]) aFree(map->list[i].moblist[j]);
- }
+ if (map->list[i].channel != NULL)
+ channel->delete(map->list[i].channel);
- if( map->list[i].unit_count ) {
- if( map->list[i].units ) {
- for(v = 0; v < map->list[i].unit_count; v++) {
- aFree(map->list[i].units[v]);
- }
- aFree(map->list[i].units);
- map->list[i].units = NULL;
- }
- map->list[i].unit_count = 0;
- }
+ VECTOR_CLEAR(map->list[i].qi_list);
+ HPM->data_store_destroy(&map->list[i].hdata);
+}
+static void do_final_maps(void)
+{
+ for (int i = 0; i < map->count; i++)
+ map->clean(i);
+ map->zone_db_clear();
+}
- if( map->list[i].skill_count ) {
- if( map->list[i].skills ) {
- for(v = 0; v < map->list[i].skill_count; v++) {
- aFree(map->list[i].skills[v]);
- }
- aFree(map->list[i].skills);
- map->list[i].skills = NULL;
- }
- map->list[i].skill_count = 0;
- }
+static void map_zonedb_reload(void)
+{
+ // first, reset maps to their initial zones:
+ for (int i = 0; i < map->count; i++) {
+ map->zone_remove_all(i);
- if( map->list[i].zone_mf_count ) {
- if( map->list[i].zone_mf ) {
- for(v = 0; v < map->list[i].zone_mf_count; v++) {
- aFree(map->list[i].zone_mf[v]);
- }
- aFree(map->list[i].zone_mf);
- map->list[i].zone_mf = NULL;
- }
- map->list[i].zone_mf_count = 0;
+ if (battle_config.pk_mode) {
+ map->list[i].flag.pvp = 1;
+ map->list[i].zone = &map->zone_pk;
+ } else {
+ map->list[i].flag.pvp = 0;
+ map->list[i].zone = &map->zone_all;
}
- if( map->list[i].drop_list_count ) {
- map->list[i].drop_list_count = 0;
- }
- if( map->list[i].drop_list != NULL )
- aFree(map->list[i].drop_list);
-
- if( map->list[i].channel )
- channel->delete(map->list[i].channel);
-
- if( map->list[i].qi_data )
- aFree(map->list[i].qi_data);
-
- HPM->data_store_destroy(&map->list[i].hdata);
+ map->list[i].prev_zone = map->list[i].zone;
}
+ // now it's safe to remove the zones:
map->zone_db_clear();
+ // then reload everything from scratch:
+ map->zone_db = strdb_alloc(DB_OPT_DUP_KEY | DB_OPT_RELEASE_DATA, MAP_ZONE_NAME_LENGTH);
+ map->read_zone_db();
}
+
+
/// Initializes map flags and adjusts them depending on configuration.
-void map_flags_init(void) {
+static void map_flags_init(void)
+{
int i, v = 0;
for( i = 0; i < map->count; i++ ) {
@@ -3560,11 +3760,8 @@ void map_flags_init(void) {
map->list[i].short_damage_rate = 100;
map->list[i].long_damage_rate = 100;
- if( map->list[i].qi_data )
- aFree(map->list[i].qi_data);
-
- map->list[i].qi_data = NULL;
- map->list[i].qi_count = 0;
+ VECTOR_CLEAR(map->list[i].qi_list);
+ VECTOR_INIT(map->list[i].qi_list);
}
}
@@ -3576,23 +3773,45 @@ void map_flags_init(void) {
* Assumed path for file is data/mapname.rsw
* Credits to LittleWolf
*/
-int map_waterheight(char* mapname)
+static int map_waterheight(char *mapname)
{
char fn[256];
- char *rsw, *found;
+ char *rsw = NULL;
+ const char *found;
nullpo_retr(NO_WATER, mapname);
//Look up for the rsw
snprintf(fn, sizeof(fn), "data\\%s.rsw", mapname);
- if ( (found = grfio_find_file(fn)) )
+ if ((found = grfio->find_file(fn)))
safestrncpy(fn, found, sizeof(fn)); // replace with real name
// read & convert fn
- rsw = (char *) grfio_read (fn);
+ rsw = grfio_read(fn);
if (rsw) {
+ if (memcmp(rsw, "GRSW", 4) != 0) {
+ ShowWarning("Failed to find water level for %s (%s)\n", mapname, fn);
+ aFree(rsw);
+ return NO_WATER;
+ }
+ int major_version = rsw[4];
+ int minor_version = rsw[5];
+ if (major_version > 2 || (major_version == 2 && minor_version > 2)) {
+ ShowWarning("Failed to find water level for %s (%s)\n", mapname, fn);
+ aFree(rsw);
+ return NO_WATER;
+ }
+ if (major_version < 1 || (major_version == 1 && minor_version <= 4)) {
+ ShowWarning("Failed to find water level for %s (%s)\n", mapname, fn);
+ aFree(rsw);
+ return NO_WATER;
+ }
+ int offset = 166;
+ if (major_version == 2 && minor_version >= 2) {
+ offset = 167;
+ }
//Load water height from file
- int wh = (int) *(float*)(rsw+166);
+ int wh = (int)*(float*)(rsw + offset);
aFree(rsw);
return wh;
}
@@ -3603,7 +3822,7 @@ int map_waterheight(char* mapname)
/*==================================
* .GAT format
*----------------------------------*/
-int map_readgat (struct map_data* m)
+static int map_readgat(struct map_data *m)
{
char filename[256];
uint8* gat;
@@ -3613,7 +3832,7 @@ int map_readgat (struct map_data* m)
nullpo_ret(m);
sprintf(filename, "data\\%s.gat", m->name);
- gat = (uint8 *) grfio_read(filename);
+ gat = grfio_read(filename);
if (gat == NULL)
return 0;
@@ -3647,12 +3866,14 @@ int map_readgat (struct map_data* m)
/*======================================
* Add/Remove map to the map_db
*--------------------------------------*/
-void map_addmap2db(struct map_data *m) {
+static void map_addmap2db(struct map_data *m)
+{
nullpo_retv(m);
map->index2mapid[m->index] = m->m;
}
-void map_removemapdb(struct map_data *m) {
+static void map_removemapdb(struct map_data *m)
+{
nullpo_retv(m);
map->index2mapid[m->index] = -1;
}
@@ -3660,28 +3881,15 @@ void map_removemapdb(struct map_data *m) {
/*======================================
* Initiate maps loading stage
*--------------------------------------*/
-int map_readallmaps (void) {
+static int map_readallmaps(void)
+{
int i;
- FILE* fp=NULL;
int maps_removed = 0;
- if( map->enable_grf )
+ if (map->enable_grf) {
ShowStatus("Loading maps (using GRF files)...\n");
- else {
- char mapcachefilepath[254];
- sprintf(mapcachefilepath,"%s/%s%s",map->db_path,DBPATH,"map_cache.dat");
- ShowStatus("Loading maps (using %s as map cache)...\n", mapcachefilepath);
- if( (fp = fopen(mapcachefilepath, "rb")) == NULL ) {
- ShowFatalError("Unable to open map cache file "CL_WHITE"%s"CL_RESET"\n", mapcachefilepath);
- exit(EXIT_FAILURE); //No use launching server if maps can't be read.
- }
-
- // Init mapcache data.. [Shinryo]
- map->cache_buffer = map->init_mapcache(fp);
- if(!map->cache_buffer) {
- ShowFatalError("Failed to initialize mapcache data (%s)..\n", mapcachefilepath);
- exit(EXIT_FAILURE);
- }
+ } else {
+ ShowStatus("Loading maps using map cache files...\n");
}
for(i = 0; i < map->count; i++) {
@@ -3695,7 +3903,7 @@ int map_readallmaps (void) {
if( !
(map->enable_grf?
map->readgat(&map->list[i])
- :map->readfromcache(&map->list[i], map->cache_buffer))
+ :map->readfromcache(&map->list[i]))
) {
map->delmapid(i);
maps_removed++;
@@ -3737,10 +3945,6 @@ int map_readallmaps (void) {
// intialization and configuration-dependent adjustments of mapflags
map->flags_init();
- if( !map->enable_grf ) {
- fclose(fp);
- }
-
// finished map loading
ShowInfo("Successfully loaded '"CL_WHITE"%d"CL_RESET"' maps."CL_CLL"\n",map->count);
instance->start_id = map->count; // Next Map Index will be instances
@@ -3751,181 +3955,388 @@ int map_readallmaps (void) {
return 0;
}
-/*==========================================
- * Read map server configuration files (conf/map_server.conf...)
- *------------------------------------------*/
-int map_config_read(char *cfgName) {
- char line[1024], w1[1024], w2[1024];
- FILE *fp;
+/**
+ * Reads 'map_configuration/console' and initializes required variables.
+ *
+ * @param filename Path to configuration file (used in error and warning messages).
+ * @param config The current config being parsed.
+ * @param imported Whether the current config is imported from another file.
+ *
+ * @retval false in case of error.
+ */
+static bool map_config_read_console(const char *filename, struct config_t *config, bool imported)
+{
+ struct config_setting_t *setting = NULL;
- nullpo_retr(1, cfgName);
+ nullpo_retr(false, filename);
+ nullpo_retr(false, config);
- fp = fopen(cfgName,"r");
- if( fp == NULL ) {
- ShowError("Map configuration file not found at: %s\n", cfgName);
- return 1;
+ if ((setting = libconfig->lookup(config, "map_configuration/console")) == NULL) {
+ if (imported)
+ return true;
+ ShowError("map_config_read: map_configuration/console was not found in %s!\n", filename);
+ return false;
}
- while (fgets(line, sizeof(line), fp)) {
- char* ptr;
+ libconfig->setting_lookup_bool_real(setting, "stdout_with_ansisequence", &showmsg->stdout_with_ansisequence);
+ if (libconfig->setting_lookup_int(setting, "console_silent", &showmsg->silent) == CONFIG_TRUE) {
+ if (showmsg->silent) // only bother if its actually enabled
+ ShowInfo("Console Silent Setting: %d\n", showmsg->silent);
+ }
+ libconfig->setting_lookup_mutable_string(setting, "timestamp_format", showmsg->timestamp_format, sizeof(showmsg->timestamp_format));
+ libconfig->setting_lookup_int(setting, "console_msg_log", &showmsg->console_log);
- if (line[0] == '/' && line[1] == '/')
- continue;
- if ((ptr = strstr(line, "//")) != NULL)
- *ptr = '\n'; //Strip comments
- if (sscanf(line, "%1023[^:]: %1023[^\t\r\n]", w1, w2) < 2)
- continue;
+ return true;
+}
- //Strip trailing spaces
- ptr = w2 + strlen(w2);
- while (--ptr >= w2 && *ptr == ' ');
- ptr++;
- *ptr = '\0';
-
- if(strcmpi(w1,"timestamp_format")==0)
- safestrncpy(showmsg->timestamp_format, w2, 20);
- else if(strcmpi(w1,"stdout_with_ansisequence")==0)
- showmsg->stdout_with_ansisequence = config_switch(w2) ? true : false;
- else if(strcmpi(w1,"console_silent")==0) {
- showmsg->silent = atoi(w2);
- if (showmsg->silent) // only bother if its actually enabled
- ShowInfo("Console Silent Setting: %d\n", atoi(w2));
- } else if (strcmpi(w1, "userid")==0)
- chrif->setuserid(w2);
- else if (strcmpi(w1, "passwd") == 0)
- chrif->setpasswd(w2);
- else if (strcmpi(w1, "char_ip") == 0)
- map->char_ip_set = chrif->setip(w2);
- else if (strcmpi(w1, "char_port") == 0)
- chrif->setport(atoi(w2));
- else if (strcmpi(w1, "map_ip") == 0)
- map->ip_set = clif->setip(w2);
- else if (strcmpi(w1, "bind_ip") == 0)
- clif->setbindip(w2);
- else if (strcmpi(w1, "map_port") == 0) {
- clif->setport(atoi(w2));
- map->port = (atoi(w2));
- } else if (strcmpi(w1, "map") == 0)
- map->count++;
- else if (strcmpi(w1, "delmap") == 0)
- map->count--;
- else if (strcmpi(w1, "npc") == 0)
- npc->addsrcfile(w2);
- else if (strcmpi(w1, "delnpc") == 0)
- npc->delsrcfile(w2);
- else if (strcmpi(w1, "autosave_time") == 0) {
- map->autosave_interval = atoi(w2);
- if (map->autosave_interval < 1) //Revert to default saving.
- map->autosave_interval = DEFAULT_AUTOSAVE_INTERVAL;
- else
- map->autosave_interval *= 1000; //Pass from sec to ms
- } else if (strcmpi(w1, "minsave_time") == 0) {
- map->minsave_interval= atoi(w2);
- if (map->minsave_interval < 1)
- map->minsave_interval = 1;
- } else if (strcmpi(w1, "save_settings") == 0)
- map->save_settings = atoi(w2);
- else if (strcmpi(w1, "help_txt") == 0)
- strcpy(map->help_txt, w2);
- else if (strcmpi(w1, "help2_txt") == 0)
- strcpy(map->help2_txt, w2);
- else if (strcmpi(w1, "charhelp_txt") == 0)
- strcpy(map->charhelp_txt, w2);
- else if(strcmpi(w1,"db_path") == 0)
- safestrncpy(map->db_path,w2,255);
- else if (strcmpi(w1, "enable_spy") == 0)
- map->enable_spy = config_switch(w2);
- else if (strcmpi(w1, "use_grf") == 0)
- map->enable_grf = config_switch(w2);
- else if (strcmpi(w1, "console_msg_log") == 0)
- showmsg->console_log = atoi(w2);//[Ind]
- else if (strcmpi(w1, "default_language") == 0)
- safestrncpy(map->default_lang_str, w2, sizeof(map->default_lang_str));
- else if (strcmpi(w1, "import") == 0)
- map->config_read(w2);
+/**
+ * Reads 'map_configuration/sql_connection' and initializes required variables.
+ *
+ * @param filename Path to configuration file (used in error and warning messages).
+ * @param config The current config being parsed.
+ * @param imported Whether the current config is imported from another file.
+ *
+ * @retval false in case of error.
+ */
+static bool map_config_read_connection(const char *filename, struct config_t *config, bool imported)
+{
+ struct config_setting_t *setting = NULL;
+
+ nullpo_retr(false, filename);
+ nullpo_retr(false, config);
+
+ if ((setting = libconfig->lookup(config, "map_configuration/sql_connection")) == NULL) {
+ if (imported)
+ return true;
+ ShowError("map_config_read: map_configuration/sql_connection was not found in %s!\n", filename);
+ ShowWarning("map_config_read_connection: Defaulting sql_connection...\n");
+ return false;
+ }
+
+ libconfig->setting_lookup_int(setting, "db_port", &map->server_port);
+ libconfig->setting_lookup_mutable_string(setting, "db_hostname", map->server_ip, sizeof(map->server_ip));
+ libconfig->setting_lookup_mutable_string(setting, "db_username", map->server_id, sizeof(map->server_id));
+ libconfig->setting_lookup_mutable_string(setting, "db_password", map->server_pw, sizeof(map->server_pw));
+ libconfig->setting_lookup_mutable_string(setting, "db_database", map->server_db, sizeof(map->server_db));
+ libconfig->setting_lookup_mutable_string(setting, "default_codepage", map->default_codepage, sizeof(map->default_codepage));
+ return true;
+}
+
+/**
+ * Reads 'map_configuration/inter' and initializes required variables.
+ *
+ * @param filename Path to configuration file (used in error and warning messages).
+ * @param config The current config being parsed.
+ * @param imported Whether the current config is imported from another file.
+ *
+ * @retval false in case of error.
+ */
+static bool map_config_read_inter(const char *filename, struct config_t *config, bool imported)
+{
+ struct config_setting_t *setting = NULL;
+ const char *str = NULL;
+ char temp[24];
+ uint16 port;
+
+ nullpo_retr(false, filename);
+ nullpo_retr(false, config);
+
+ if ((setting = libconfig->lookup(config, "map_configuration/inter")) == NULL) {
+ if (imported)
+ return true;
+ ShowError("map_config_read: map_configuration/inter was not found in %s!\n", filename);
+ return false;
+ }
+
+ // Login information
+ if (libconfig->setting_lookup_mutable_string(setting, "userid", temp, sizeof(temp)) == CONFIG_TRUE)
+ chrif->setuserid(temp);
+ if (libconfig->setting_lookup_mutable_string(setting, "passwd", temp, sizeof(temp)) == CONFIG_TRUE)
+ chrif->setpasswd(temp);
+
+ // Char and map-server information
+ if (libconfig->setting_lookup_string(setting, "char_ip", &str) == CONFIG_TRUE)
+ map->char_ip_set = chrif->setip(str);
+ if (libconfig->setting_lookup_uint16(setting, "char_port", &port) == CONFIG_TRUE)
+ chrif->setport(port);
+
+ if (libconfig->setting_lookup_string(setting, "map_ip", &str) == CONFIG_TRUE)
+ map->ip_set = clif->setip(str);
+ if (libconfig->setting_lookup_uint16(setting, "map_port", &port) == CONFIG_TRUE) {
+ clif->setport(port);
+ map->port = port;
+ }
+ if (libconfig->setting_lookup_string(setting, "bind_ip", &str) == CONFIG_TRUE)
+ clif->setbindip(str);
+
+ return true;
+}
+
+/**
+ * Reads 'map_configuration/database' and initializes required variables
+ *
+ * @param filename Path to configuration file (used in error and warning messages).
+ * @param config The current config being parsed.
+ * @param imported Whether the current config is imported from another file.
+ *
+ * @retval false in case of error.
+ */
+static bool map_config_read_database(const char *filename, struct config_t *config, bool imported)
+{
+ struct config_setting_t *setting = NULL;
+
+ nullpo_retr(false, filename);
+ nullpo_retr(false, config);
+
+ if ((setting = libconfig->lookup(config, "map_configuration/database")) == NULL) {
+ if (imported)
+ return true;
+ ShowError("map_config_read: map_configuration/database was not found in %s!\n", filename);
+ return false;
+ }
+ libconfig->setting_lookup_mutable_string(setting, "db_path", map->db_path, sizeof(map->db_path));
+ libconfig->set_db_path(map->db_path);
+ libconfig->setting_lookup_int(setting, "save_settings", &map->save_settings);
+
+ if (libconfig->setting_lookup_int(setting, "autosave_time", &map->autosave_interval) == CONFIG_TRUE) {
+ if (map->autosave_interval < 1) // Revert to default saving
+ map->autosave_interval = DEFAULT_AUTOSAVE_INTERVAL;
else
- ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName);
+ map->autosave_interval *= 1000; // Pass from s to ms
+ }
+ if (libconfig->setting_lookup_int(setting, "minsave_time", &map->minsave_interval) == CONFIG_TRUE) {
+ if (map->minsave_interval < 1)
+ map->minsave_interval = 1;
}
- fclose(fp);
- return 0;
+ return true;
}
-int map_config_read_sub(char *cfgName) {
- char line[1024], w1[1024], w2[1024];
- FILE *fp;
- nullpo_retr(1, cfgName);
- fp = fopen(cfgName,"r");
- if (fp == NULL) {
- ShowError("Map configuration file not found at: %s\n", cfgName);
- return 1;
+/**
+ * Reads 'map_configuration/map_list'/'map_configuration/map_removed' and adds
+ * or removes maps from map-server.
+ *
+ * @param filename Path to configuration file (used in error and warning messages).
+ * @param config The current config being parsed.
+ * @param imported Whether the current config is imported from another file.
+ *
+ * @retval false in case of error.
+ */
+static bool map_config_read_map_list(const char *filename, struct config_t *config, bool imported)
+{
+ struct config_setting_t *setting = NULL;
+ int i, count = 0;
+ struct DBMap *deleted_maps;
+
+ nullpo_retr(false, filename);
+ nullpo_retr(false, config);
+
+ deleted_maps = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_ALLOW_NULL_DATA, MAP_NAME_LENGTH);
+
+ // Remove maps
+ if ((setting = libconfig->lookup(config, "map_configuration/map_removed")) != NULL) {
+ count = libconfig->setting_length(setting);
+ for (i = 0; i < count; i++) {
+ const char *mapname;
+
+ if ((mapname = libconfig->setting_get_string_elem(setting, i)) == NULL || mapname[0] == '\0')
+ continue;
+
+ strdb_put(deleted_maps, mapname, NULL);
+
+ if (imported) // Map list is empty on the first run, only do this for imported files.
+ map->delmap(mapname);
+ }
+ }
+
+ if ((setting = libconfig->lookup(config, "map_configuration/map_list")) == NULL) {
+ db_destroy(deleted_maps);
+ if (imported)
+ return true;
+ ShowError("map_config_read_map_list: map_configuration/map_list was not found in %s!\n", filename);
+ return false;
}
- while (fgets(line, sizeof(line), fp)) {
- char* ptr;
+ // Add maps to map->list
+ count = libconfig->setting_length(setting);
- if (line[0] == '/' && line[1] == '/')
+ if (count <= 0) {
+ db_destroy(deleted_maps);
+ if (imported)
+ return true;
+ ShowWarning("map_config_read_map_list: no maps found in %s!\n", filename);
+ return false;
+ }
+
+ RECREATE(map->list, struct map_data, map->count + count); // TODO: VECTOR candidate
+
+ for (i = 0; i < count; i++) {
+ const char *mapname;
+
+ if ((mapname = libconfig->setting_get_string_elem(setting, i)) == NULL || mapname[0] == '\0')
continue;
- if ((ptr = strstr(line, "//")) != NULL)
- *ptr = '\n'; //Strip comments
- if (sscanf(line, "%1023[^:]: %1023[^\t\r\n]", w1, w2) < 2)
+
+ if (strdb_exists(deleted_maps, mapname))
continue;
- //Strip trailing spaces
- ptr = w2 + strlen(w2);
- while (--ptr >= w2 && *ptr == ' ');
- ptr++;
- *ptr = '\0';
+ map->addmap(mapname);
+ }
+
+ RECREATE(map->list, struct map_data, map->count);
+
+ db_destroy(deleted_maps);
+ return true;
+}
+
+/**
+ * Reads map-server configuration files (map-server.conf) and initialises
+ * required variables.
+ *
+ * @param filename Path to configuration file.
+ * @param imported Whether the current config is imported from another file.
+ *
+ * @retval false in case of error.
+ */
+static bool map_config_read(const char *filename, bool imported)
+{
+ struct config_t config;
+ struct config_setting_t *setting = NULL;
+ const char *import = NULL;
+ bool retval = true;
+
+ nullpo_retr(false, filename);
- if (strcmpi(w1, "map") == 0)
- map->addmap(w2);
- else if (strcmpi(w1, "delmap") == 0)
- map->delmap(w2);
- else if (strcmpi(w1, "import") == 0)
- map->config_read_sub(w2);
+ if (!libconfig->load_file(&config, filename))
+ return false;
+
+ if ((setting = libconfig->lookup(&config, "map_configuration")) == NULL) {
+ libconfig->destroy(&config);
+ if (imported)
+ return true;
+ ShowError("map_config_read: map_configuration was not found in %s!\n", filename);
+ return false;
}
- fclose(fp);
- return 0;
+ libconfig->setting_lookup_mutable_string(setting, "help_txt", map->help_txt, sizeof(map->help_txt));
+ libconfig->setting_lookup_mutable_string(setting, "charhelp_txt", map->charhelp_txt, sizeof(map->charhelp_txt));
+ libconfig->setting_lookup_bool(setting, "enable_spy", &map->enable_spy);
+ libconfig->setting_lookup_bool(setting, "use_grf", &map->enable_grf);
+ libconfig->setting_lookup_mutable_string(setting, "default_language", map->default_lang_str, sizeof(map->default_lang_str));
+
+ if (!map_config_read_console(filename, &config, imported))
+ retval = false;
+ if (!map_config_read_connection(filename, &config, imported))
+ retval = false;
+ if (!map_config_read_inter(filename, &config, imported))
+ retval = false;
+ if (!map_config_read_database(filename, &config, imported))
+ retval = false;
+ if (!map_config_read_map_list(filename, &config, imported))
+ retval = false;
+
+ // import should overwrite any previous configuration, so it should be called last
+ if (libconfig->lookup_string(&config, "import", &import) == CONFIG_TRUE) {
+ if (strcmp(import, filename) == 0 || strcmp(import, map->MAP_CONF_NAME) == 0) {
+ ShowWarning("map_config_read: Loop detected! Skipping 'import'...\n");
+ } else {
+ if (!map->config_read(import, true))
+ retval = false;
+ }
+ }
+
+ libconfig->destroy(&config);
+ return retval;
}
-void map_reloadnpc_sub(char *cfgName) {
- char line[1024], w1[1024], w2[1024];
- FILE *fp;
- nullpo_retv(cfgName);
- fp = fopen(cfgName,"r");
- if (fp == NULL) {
- ShowError("Map configuration file not found at: %s\n", cfgName);
- return;
+/**
+ * Reads 'npc_global_list'/'npc_removed_list' and adds or removes NPC sources
+ * from map-server.
+ *
+ * @param filename Path to configuration file (used in error and warning messages).
+ * @param imported Whether the current config is imported from another file.
+ *
+ * @retval false in case of error.
+ */
+static bool map_read_npclist(const char *filename, bool imported)
+{
+ struct config_t config;
+ struct config_setting_t *setting = NULL;
+ const char *import = NULL;
+ bool retval = true;
+ bool remove_all = false;
+
+ struct DBMap *deleted_npcs;
+
+ nullpo_retr(false, filename);
+
+ if (!libconfig->load_file(&config, filename))
+ return false;
+
+ deleted_npcs = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_ALLOW_NULL_DATA, 0);
+
+ // Remove NPCs
+ if ((setting = libconfig->lookup(&config, "npc_removed_list")) != NULL) {
+ int i, del_count = libconfig->setting_length(setting);
+ for (i = 0; i < del_count; i++) {
+ const char *scriptname;
+
+ if ((scriptname = libconfig->setting_get_string_elem(setting, i)) == NULL || scriptname[0] == '\0')
+ continue;
+
+ if (strcmp(scriptname, "all") == 0) {
+ remove_all = true;
+ npc->clearsrcfile();
+ } else {
+ strdb_put(deleted_npcs, scriptname, NULL);
+ npc->delsrcfile(scriptname);
+ }
+ }
}
- while (fgets(line, sizeof(line), fp)) {
- char* ptr;
+ if ((setting = libconfig->lookup(&config, "npc_global_list")) != NULL) {
+ int i, count = libconfig->setting_length(setting);
+ if (count <= 0) {
+ if (!imported) {
+ ShowWarning("map_read_npclist: no NPCs found in %s!\n", filename);
+ retval = false;
+ }
+ }
+ for (i = 0; i < count; i++) {
+ const char *scriptname;
- if (line[0] == '/' && line[1] == '/')
- continue;
- if ((ptr = strstr(line, "//")) != NULL)
- *ptr = '\n'; //Strip comments
- if (sscanf(line, "%1023[^:]: %1023[^\t\r\n]", w1, w2) < 2)
- continue;
+ if ((scriptname = libconfig->setting_get_string_elem(setting, i)) == NULL || scriptname[0] == '\0')
+ continue;
- //Strip trailing spaces
- ptr = w2 + strlen(w2);
- while (--ptr >= w2 && *ptr == ' ');
- ptr++;
- *ptr = '\0';
-
- if (strcmpi(w1, "npc") == 0)
- npc->addsrcfile(w2);
- else if (strcmpi(w1, "import") == 0)
- map->reloadnpc_sub(w2);
- else if (strcmpi(w1, "delnpc") == 0)
- npc->delsrcfile(w2);
- else
- ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName);
+ if (remove_all || strdb_exists(deleted_npcs, scriptname))
+ continue;
+
+ npc->addsrcfile(scriptname);
+ }
+ } else {
+ ShowError("map_read_npclist: npc_global_list was not found in %s!\n", filename);
+ retval = false;
}
- fclose(fp);
+ db_destroy(deleted_npcs);
+
+ // import should overwrite any previous configuration, so it should be called last
+ if (libconfig->lookup_string(&config, "import", &import) == CONFIG_TRUE) {
+ const char *base_npclist = NULL;
+#ifdef RENEWAL
+ base_npclist = "npc/re/scripts_main.conf";
+#else
+ base_npclist = "npc/pre-re/scripts_main.conf";
+#endif
+ if (strcmp(import, filename) == 0 || strcmp(import, base_npclist) == 0) {
+ ShowWarning("map_read_npclist: Loop detected! Skipping 'import'...\n");
+ } else {
+ if (!map->read_npclist(import, true))
+ retval = false;
+ }
+ }
+
+ libconfig->destroy(&config);
+ return retval;
}
/**
@@ -3933,15 +4344,16 @@ void map_reloadnpc_sub(char *cfgName) {
*
* @param clear whether to clear the script list before reloading.
*/
-void map_reloadnpc(bool clear) {
+static void map_reloadnpc(bool clear)
+{
int i;
if (clear)
- npc->addsrcfile("clear"); // this will clear the current script list
+ npc->clearsrcfile();
#ifdef RENEWAL
- map->reloadnpc_sub("npc/re/scripts_main.conf");
+ map->read_npclist("npc/re/scripts_main.conf", false);
#else
- map->reloadnpc_sub("npc/pre-re/scripts_main.conf");
+ map->read_npclist("npc/pre-re/scripts_main.conf", false);
#endif
// Append extra scripts
@@ -3950,69 +4362,134 @@ void map_reloadnpc(bool clear) {
}
}
-int inter_config_read(char *cfgName) {
- char line[1024],w1[1024],w2[1024];
- FILE *fp;
+/**
+ * Reads inter-server.conf and initializes required variables.
+ *
+ * @param filename Path to configuration file
+ * @param imported Whether the current config is imported from another file.
+ *
+ * @retval false in case of error.
+ */
+static bool inter_config_read(const char *filename, bool imported)
+{
+ struct config_t config;
+ const struct config_setting_t *setting = NULL;
+ const char *import = NULL;
+ bool retval = true;
- nullpo_retr(1, cfgName);
- if (!(fp = fopen(cfgName,"r"))) {
- ShowError("File not found: %s\n",cfgName);
- return 1;
+ nullpo_retr(false, filename);
+
+ if (!libconfig->load_file(&config, filename))
+ return false;
+
+ if ((setting = libconfig->lookup(&config, "inter_configuration")) == NULL) {
+ libconfig->destroy(&config);
+ if (imported)
+ return true;
+ ShowError("inter_config_read: inter_configuration was not found in %s!\n", filename);
+ return false;
}
- while (fgets(line, sizeof(line), fp)) {
- if (line[0] == '/' && line[1] == '/')
- continue;
- if (sscanf(line,"%1023[^:]: %1023[^\r\n]", w1, w2) < 2)
- continue;
- /* map sql stuff */
- if(strcmpi(w1,"map_server_ip")==0)
- safestrncpy(map->server_ip, w2, sizeof(map->server_ip));
- else if(strcmpi(w1,"map_server_port")==0)
- map->server_port=atoi(w2);
- else if(strcmpi(w1,"map_server_id")==0)
- safestrncpy(map->server_id, w2, sizeof(map->server_id));
- else if(strcmpi(w1,"map_server_pw")==0)
- safestrncpy(map->server_pw, w2, sizeof(map->server_pw));
- else if(strcmpi(w1,"map_server_db")==0)
- safestrncpy(map->server_db, w2, sizeof(map->server_db));
- else if(strcmpi(w1,"default_codepage")==0)
- safestrncpy(map->default_codepage, w2, sizeof(map->default_codepage));
- else if(strcmpi(w1,"autotrade_merchants_db")==0)
- safestrncpy(map->autotrade_merchants_db, w2, sizeof(map->autotrade_merchants_db));
- else if(strcmpi(w1,"autotrade_data_db")==0)
- safestrncpy(map->autotrade_data_db, w2, sizeof(map->autotrade_data_db));
- else if(strcmpi(w1,"npc_market_data_db")==0)
- safestrncpy(map->npc_market_data_db, w2, sizeof(map->npc_market_data_db));
- /* sql log db */
- else if(strcmpi(w1,"log_db_ip")==0)
- safestrncpy(logs->db_ip, w2, sizeof(logs->db_ip));
- else if(strcmpi(w1,"log_db_id")==0)
- safestrncpy(logs->db_id, w2, sizeof(logs->db_id));
- else if(strcmpi(w1,"log_db_pw")==0)
- safestrncpy(logs->db_pw, w2, sizeof(logs->db_pw));
- else if(strcmpi(w1,"log_db_port")==0)
- logs->db_port = atoi(w2);
- else if(strcmpi(w1,"log_db_db")==0)
- safestrncpy(logs->db_name, w2, sizeof(logs->db_name));
- /* mapreg */
- else if( mapreg->config_read(w1,w2) )
- continue;
- /* import */
- else if(strcmpi(w1,"import")==0)
- map->inter_config_read(w2);
- else
- HPM->parseConf(w1, w2, HPCT_MAP_INTER);
+ if (!map->inter_config_read_database_names(filename, &config, imported))
+ retval = false;
+ if (!map->inter_config_read_connection(filename, &config, imported))
+ retval = false;
+
+ if (!HPM->parse_conf(&config, filename, HPCT_MAP_INTER, imported))
+ retval = false;
+
+ // import should overwrite any previous configuration, so it should be called last
+ if (libconfig->lookup_string(&config, "import", &import) == CONFIG_TRUE) {
+ if (strcmp(import, filename) == 0 || strcmp(import, map->INTER_CONF_NAME) == 0) {
+ ShowWarning("inter_config_read: Loop detected in %s! Skipping 'import'...\n", filename);
+ } else {
+ if (!map->inter_config_read(import, true))
+ retval = false;
+ }
}
- fclose(fp);
- return 0;
+ libconfig->destroy(&config);
+ return retval;
+}
+
+/**
+ * Reads the 'inter_configuration/log/sql_connection' config entry and initializes required variables.
+ *
+ * @param filename Path to configuration file (used in error and warning messages).
+ * @param config The current config being parsed.
+ * @param imported Whether the current config is imported from another file.
+ *
+ * @retval false in case of error.
+ */
+static bool inter_config_read_connection(const char *filename, const struct config_t *config, bool imported)
+{
+ const struct config_setting_t *setting = NULL;
+
+ nullpo_retr(false, filename);
+ nullpo_retr(false, config);
+
+ if ((setting = libconfig->lookup(config, "inter_configuration/log/sql_connection")) == NULL) {
+ if (imported)
+ return true;
+ ShowError("inter_config_read: inter_configuration/log/sql_connection was not found in %s!\n", filename);
+ return false;
+ }
+
+ libconfig->setting_lookup_int(setting, "db_port", &logs->db_port);
+ libconfig->setting_lookup_mutable_string(setting, "db_hostname", logs->db_ip, sizeof(logs->db_ip));
+ libconfig->setting_lookup_mutable_string(setting, "db_username", logs->db_id, sizeof(logs->db_id));
+ libconfig->setting_lookup_mutable_string(setting, "db_password", logs->db_pw, sizeof(logs->db_pw));
+ libconfig->setting_lookup_mutable_string(setting, "db_database", logs->db_name, sizeof(logs->db_name));
+
+ return true;
+}
+
+/**
+ * Reads the 'inter_configuration/database_names' config entry and initializes required variables.
+ *
+ * @param filename Path to configuration file (used in error and warning messages).
+ * @param config The current config being parsed.
+ * @param imported Whether the current config is imported from another file.
+ *
+ * @retval false in case of error.
+ */
+static bool inter_config_read_database_names(const char *filename, const struct config_t *config, bool imported)
+{
+ const struct config_setting_t *setting = NULL;
+ bool retval = true;
+
+ nullpo_retr(false, filename);
+ nullpo_retr(false, config);
+
+ if ((setting = libconfig->lookup(config, "inter_configuration/database_names")) == NULL) {
+ if (imported)
+ return true;
+ ShowError("inter_config_read: inter_configuration/database_names was not found in %s!\n", filename);
+ return false;
+ }
+
+ libconfig->setting_lookup_mutable_string(setting, "autotrade_merchants_db", map->autotrade_merchants_db, sizeof(map->autotrade_merchants_db));
+ libconfig->setting_lookup_mutable_string(setting, "autotrade_data_db", map->autotrade_data_db, sizeof(map->autotrade_data_db));
+ libconfig->setting_lookup_mutable_string(setting, "npc_market_data_db", map->npc_market_data_db, sizeof(map->npc_market_data_db));
+ libconfig->setting_lookup_mutable_string(setting, "npc_barter_data_db", map->npc_barter_data_db, sizeof(map->npc_barter_data_db));
+ libconfig->setting_lookup_mutable_string(setting, "npc_expanded_barter_data_db", map->npc_expanded_barter_data_db, sizeof(map->npc_expanded_barter_data_db));
+
+ if (!mapreg->config_read(filename, setting, imported))
+ retval = false;
+
+ if ((setting = libconfig->lookup(config, "inter_configuration/database_names/registry")) == NULL) {
+ if (imported)
+ return retval;
+ ShowError("inter_config_read: inter_configuration/database_names/registry was not found in %s!\n", filename);
+ return false;
+ }
+ return retval;
}
/*=======================================
* MySQL Init
*---------------------------------------*/
-int map_sql_init(void)
+static int map_sql_init(void)
{
// main db connection
map->mysql_handle = SQL->Malloc();
@@ -4029,7 +4506,7 @@ int map_sql_init(void)
return 0;
}
-int map_sql_close(void)
+static int map_sql_close(void)
{
ShowStatus("Close Map DB Connection....\n");
SQL->Free(map->mysql_handle);
@@ -4047,7 +4524,8 @@ int map_sql_close(void)
*
* @return the newly created zone from merging main and other
**/
-struct map_zone_data *map_merge_zone(struct map_zone_data *main, struct map_zone_data *other) {
+static struct map_zone_data *map_merge_zone(struct map_zone_data *main, struct map_zone_data *other)
+{
char newzone[MAP_ZONE_NAME_LENGTH];
struct map_zone_data *zone = NULL;
int cursor, i, j;
@@ -4055,7 +4533,7 @@ struct map_zone_data *map_merge_zone(struct map_zone_data *main, struct map_zone
nullpo_retr(NULL, main);
nullpo_retr(NULL, other);
- sprintf(newzone, "%s+%s",main->name,other->name);
+ safesnprintf(newzone, MAP_ZONE_NAME_LENGTH, "%s+%s", main->name, other->name);
if( (zone = strdb_get(map->zone_db, newzone)) )
return zone;/* this zone has already been merged */
@@ -4144,10 +4622,12 @@ struct map_zone_data *map_merge_zone(struct map_zone_data *main, struct map_zone
return zone;
}
-void map_zone_change2(int m, struct map_zone_data *zone)
+static void map_zone_change2(int m, struct map_zone_data *zone)
{
const char *empty = "";
+ if (zone == NULL)
+ return;
Assert_retv(m >= 0 && m < map->count);
if( map->list[m].zone == zone )
return;
@@ -4165,7 +4645,8 @@ void map_zone_change2(int m, struct map_zone_data *zone)
map->zone_apply(m,zone,empty,empty,empty);
}
/* when changing from a mapflag to another during runtime */
-void map_zone_change(int m, struct map_zone_data *zone, const char* start, const char* buffer, const char* filepath) {
+static void map_zone_change(int m, struct map_zone_data *zone, const char *start, const char *buffer, const char *filepath)
+{
Assert_retv(m >= 0 && m < map->count);
map->list[m].prev_zone = map->list[m].zone;
@@ -4174,7 +4655,7 @@ void map_zone_change(int m, struct map_zone_data *zone, const char* start, const
map->zone_apply(m,zone,start,buffer,filepath);
}
/* removes previous mapflags from this map */
-void map_zone_remove(int m)
+static void map_zone_remove(int m)
{
char flag[MAP_ZONE_MAPFLAG_LENGTH], params[MAP_ZONE_MAPFLAG_LENGTH];
unsigned short k;
@@ -4201,7 +4682,29 @@ void map_zone_remove(int m)
map->list[m].zone_mf = NULL;
map->list[m].zone_mf_count = 0;
}
-static inline void map_zone_mf_cache_add(int m, char *rflag) {
+// this one removes every flag, even if they were previously turned on before
+// the current zone was applied
+static void map_zone_remove_all(int m)
+{
+ Assert_retv(m >= 0 && m < map->count);
+
+ for (unsigned short k = 0; k < map->list[m].zone_mf_count; k++) {
+ char flag[MAP_ZONE_MAPFLAG_LENGTH];
+
+ memcpy(flag, map->list[m].zone_mf[k], MAP_ZONE_MAPFLAG_LENGTH);
+ strtok(flag, "\t");
+
+ npc->parse_mapflag(map->list[m].name, "", flag, "off", "", "", "", NULL);
+ aFree(map->list[m].zone_mf[k]);
+ map->list[m].zone_mf[k] = NULL;
+ }
+
+ aFree(map->list[m].zone_mf);
+ map->list[m].zone_mf = NULL;
+ map->list[m].zone_mf_count = 0;
+}
+static inline void map_zone_mf_cache_add(int m, char *rflag)
+{
Assert_retv(m >= 0 && m < map->count);
RECREATE(map->list[m].zone_mf, char *, ++map->list[m].zone_mf_count);
CREATE(map->list[m].zone_mf[map->list[m].zone_mf_count - 1], char, MAP_ZONE_MAPFLAG_LENGTH);
@@ -4209,7 +4712,8 @@ static inline void map_zone_mf_cache_add(int m, char *rflag) {
}
/* TODO: introduce enumerations to each mapflag so instead of reading the string a number of times we read it only once and use its value wherever we need */
/* cache previous values to revert */
-bool map_zone_mf_cache(int m, char *flag, char *params) {
+static bool map_zone_mf_cache(int m, char *flag, char *params)
+{
char rflag[MAP_ZONE_MAPFLAG_LENGTH];
int state = 1;
@@ -4465,6 +4969,15 @@ bool map_zone_mf_cache(int m, char *flag, char *params) {
else if( map->list[m].flag.battleground )
map_zone_mf_cache_add(m,"battleground");
}
+ } else if (!strcmpi(flag,"cvc")) {
+ if (state && map->list[m].flag.cvc) {
+ ;/* nothing to do */
+ } else {
+ if (state)
+ map_zone_mf_cache_add(m,"cvc\toff");
+ else if (map->list[m].flag.cvc)
+ map_zone_mf_cache_add(m,"cvc");
+ }
} else if (!strcmpi(flag,"noexppenalty")) {
if( state && map->list[m].flag.noexppenalty )
;/* nothing to do */
@@ -4737,11 +5250,12 @@ bool map_zone_mf_cache(int m, char *flag, char *params) {
}
} else if (!strcmpi(flag,"adjust_unit_duration")) {
int skill_id, k;
- char skill_name[MAP_ZONE_MAPFLAG_LENGTH], modifier[MAP_ZONE_MAPFLAG_LENGTH];
- size_t len = strlen(params);
+ char skill_name[MAX_SKILL_NAME_LENGTH], modifier[MAP_ZONE_MAPFLAG_LENGTH];
+ size_t len;
modifier[0] = '\0';
- memcpy(skill_name, params, MAP_ZONE_MAPFLAG_LENGTH);
+ safestrncpy(skill_name, params, MAX_SKILL_NAME_LENGTH);
+ len = strlen(skill_name);
for(k = 0; k < len; k++) {
if( skill_name[k] == '\t' ) {
@@ -4770,11 +5284,12 @@ bool map_zone_mf_cache(int m, char *flag, char *params) {
}
} else if (!strcmpi(flag,"adjust_skill_damage")) {
int skill_id, k;
- char skill_name[MAP_ZONE_MAPFLAG_LENGTH], modifier[MAP_ZONE_MAPFLAG_LENGTH];
- size_t len = strlen(params);
+ char skill_name[MAX_SKILL_NAME_LENGTH], modifier[MAP_ZONE_MAPFLAG_LENGTH];
+ size_t len;
modifier[0] = '\0';
- memcpy(skill_name, params, MAP_ZONE_MAPFLAG_LENGTH);
+ safestrncpy(skill_name, params, MAX_SKILL_NAME_LENGTH);
+ len = strlen(skill_name);
for(k = 0; k < len; k++) {
if( skill_name[k] == '\t' ) {
@@ -4904,11 +5419,37 @@ bool map_zone_mf_cache(int m, char *flag, char *params) {
else if( map->list[m].flag.nocashshop )
map_zone_mf_cache_add(m,"nocashshop");
}
+ } else if (strcmpi(flag, "nostorage") == 0) {
+ if (!state) {
+ if (map->list[m].flag.nostorage != 0) {
+ sprintf(rflag, "nostorage\t%d", map->list[m].flag.nostorage);
+ map_zone_mf_cache_add(m, rflag);
+ }
+ }
+ if (sscanf(params, "%d", &state) == 1) {
+ if (state != map->list[m].flag.nostorage) {
+ sprintf(rflag, "nostorage\t%d", state);
+ map_zone_mf_cache_add(m, rflag);
+ }
+ }
+ } else if (strcmpi(flag, "nogstorage") == 0) {
+ if (!state) {
+ if (map->list[m].flag.nogstorage != 0) {
+ sprintf(rflag, "nogstorage\t%d", map->list[m].flag.nogstorage);
+ map_zone_mf_cache_add(m, rflag);
+ }
+ }
+ if (sscanf(params, "%d", &state) == 1) {
+ if (state != map->list[m].flag.nogstorage) {
+ sprintf(rflag, "nogstorage\t%d", state);
+ map_zone_mf_cache_add(m, rflag);
+ }
+ }
}
return false;
}
-void map_zone_apply(int m, struct map_zone_data *zone, const char* start, const char* buffer, const char* filepath)
+static void map_zone_apply(int m, struct map_zone_data *zone, const char *start, const char *buffer, const char *filepath)
{
int i;
const char *empty = "";
@@ -4936,7 +5477,7 @@ void map_zone_apply(int m, struct map_zone_data *zone, const char* start, const
}
}
/* used on npc load and reload to apply all "Normal" and "PK Mode" zones */
-void map_zone_init(void)
+static void map_zone_init(void)
{
char flag[MAP_ZONE_MAPFLAG_LENGTH], params[MAP_ZONE_MAPFLAG_LENGTH];
struct map_zone_data *zone;
@@ -4990,12 +5531,13 @@ void map_zone_init(void)
}
}
-unsigned short map_zone_str2itemid(const char *name) {
+static int map_zone_str2itemid(const char *name)
+{
struct item_data *data;
if( !name )
return 0;
- if( name[0] == 'I' && name[1] == 'D' && strlen(name) < 8 ) {
+ if (name[0] == 'I' && name[1] == 'D' && strlen(name) <= 12) {
if( !( data = itemdb->exists(atoi(name+2))) ) {
return 0;
}
@@ -5006,13 +5548,14 @@ unsigned short map_zone_str2itemid(const char *name) {
}
return data->nameid;
}
-unsigned short map_zone_str2skillid(const char *name) {
+static unsigned short map_zone_str2skillid(const char *name)
+{
unsigned short nameid = 0;
if( !name )
return 0;
- if( name[0] == 'I' && name[1] == 'D' && strlen(name) < 8 ) {
+ if (name[0] == 'I' && name[1] == 'D' && strlen(name) <= 12) {
if( !skill->get_index((nameid = atoi(name+2))) )
return 0;
} else {
@@ -5022,7 +5565,8 @@ unsigned short map_zone_str2skillid(const char *name) {
}
return nameid;
}
-enum bl_type map_zone_bl_type(const char *entry, enum map_zone_skill_subtype *subtype) {
+static enum bl_type map_zone_bl_type(const char *entry, enum map_zone_skill_subtype *subtype)
+{
char temp[200], *parse;
enum bl_type bl = BL_NUL;
@@ -5068,15 +5612,12 @@ enum bl_type map_zone_bl_type(const char *entry, enum map_zone_skill_subtype *su
return bl;
}
/* [Ind/Hercules] */
-void read_map_zone_db(void) {
+static void read_map_zone_db(void)
+{
struct config_t map_zone_db;
struct config_setting_t *zones = NULL;
- /* TODO: #ifndef required for re/pre-re */
-#ifdef RENEWAL
- const char *config_filename = "db/re/map_zone_db.conf"; // FIXME hardcoded name
-#else
- const char *config_filename = "db/pre-re/map_zone_db.conf"; // FIXME hardcoded name
-#endif
+ char config_filename[256];
+ libconfig->format_db_path(DBPATH"map_zone_db.conf", config_filename, sizeof(config_filename));
if (!libconfig->load_file(&map_zone_db, config_filename))
return;
@@ -5489,45 +6030,46 @@ void read_map_zone_db(void) {
zone->merge_type = MZMT_MERGEABLE;
if( (zone = strdb_get(map->zone_db, MAP_ZONE_BG_NAME)) )
zone->merge_type = MZMT_MERGEABLE;
+ if ((zone = strdb_get(map->zone_db, MAP_ZONE_CVC_NAME)))
+ zone->merge_type = MZMT_MERGEABLE;
}
/* not supposed to go in here but in skill_final whatever */
libconfig->destroy(&map_zone_db);
}
-int map_get_new_bonus_id (void) {
+static int map_get_new_bonus_id(void)
+{
return map->bonus_id++;
}
-void map_add_questinfo(int m, struct questinfo *qi) {
- unsigned short i;
+static bool map_add_questinfo(int m, struct npc_data *nd)
+{
+ nullpo_retr(false, nd);
+ Assert_retr(false, m >= 0 && m < map->count);
- nullpo_retv(qi);
- Assert_retv(m >= 0 && m < map->count);
- /* duplicate, override */
- for(i = 0; i < map->list[m].qi_count; i++) {
- if( map->list[m].qi_data[i].nd == qi->nd )
- break;
- }
+ int i;
+ ARR_FIND(0, VECTOR_LENGTH(map->list[m].qi_list), i, VECTOR_INDEX(map->list[m].qi_list, i) == nd);
- if( i == map->list[m].qi_count )
- RECREATE(map->list[m].qi_data, struct questinfo, ++map->list[m].qi_count);
+ if (i < VECTOR_LENGTH(map->list[m].qi_list)) {
+ return false;
+ }
- memcpy(&map->list[m].qi_data[i], qi, sizeof(struct questinfo));
+ VECTOR_ENSURE(map->list[m].qi_list, 1, 1);
+ VECTOR_PUSH(map->list[m].qi_list, nd);
+ return true;
}
-bool map_remove_questinfo(int m, struct npc_data *nd) {
- unsigned short i;
+static bool map_remove_questinfo(int m, struct npc_data *nd)
+{
+ nullpo_retr(false, nd);
Assert_retr(false, m >= 0 && m < map->count);
- for(i = 0; i < map->list[m].qi_count; i++) {
- struct questinfo *qi = &map->list[m].qi_data[i];
- if( qi->nd == nd ) {
- memset(&map->list[m].qi_data[i], 0, sizeof(struct questinfo));
- if( i != --map->list[m].qi_count ) {
- memmove(&map->list[m].qi_data[i],&map->list[m].qi_data[i+1],sizeof(struct questinfo)*(map->list[m].qi_count-i));
- }
- return true;
- }
+
+ int i;
+ ARR_FIND(0, VECTOR_LENGTH(map->list[m].qi_list), i, VECTOR_INDEX(map->list[m].qi_list, i) == nd);
+ if (i != VECTOR_LENGTH(map->list[m].qi_list)) {
+ VECTOR_ERASE(map->list[m].qi_list, i);
+ return true;
}
return false;
}
@@ -5535,7 +6077,7 @@ bool map_remove_questinfo(int m, struct npc_data *nd) {
/**
* @see DBApply
*/
-int map_db_final(union DBKey key, struct DBData *data, va_list ap)
+static int map_db_final(union DBKey key, struct DBData *data, va_list ap)
{
struct map_data_other_server *mdos = DB->data2ptr(data);
@@ -5548,7 +6090,7 @@ int map_db_final(union DBKey key, struct DBData *data, va_list ap)
/**
* @see DBApply
*/
-int nick_db_final(union DBKey key, struct DBData *data, va_list args)
+static int nick_db_final(union DBKey key, struct DBData *data, va_list args)
{
struct charid2nick* p = DB->data2ptr(data);
struct charid_request* req;
@@ -5565,7 +6107,8 @@ int nick_db_final(union DBKey key, struct DBData *data, va_list args)
return 0;
}
-int cleanup_sub(struct block_list *bl, va_list ap) {
+static int cleanup_sub(struct block_list *bl, va_list ap)
+{
nullpo_ret(bl);
switch(bl->type) {
@@ -5573,7 +6116,7 @@ int cleanup_sub(struct block_list *bl, va_list ap) {
map->quit(BL_UCAST(BL_PC, bl));
break;
case BL_NPC:
- npc->unload(BL_UCAST(BL_NPC, bl), false);
+ npc->unload(BL_UCAST(BL_NPC, bl), false, true);
break;
case BL_MOB:
unit->free(bl,CLR_OUTSIGHT);
@@ -5595,7 +6138,7 @@ int cleanup_sub(struct block_list *bl, va_list ap) {
/**
* @see DBApply
*/
-int cleanup_db_sub(union DBKey key, struct DBData *data, va_list va)
+static int cleanup_db_sub(union DBKey key, struct DBData *data, va_list va)
{
return map->cleanup_sub(DB->data2ptr(data), va);
}
@@ -5603,7 +6146,8 @@ int cleanup_db_sub(union DBKey key, struct DBData *data, va_list va)
/*==========================================
* map destructor
*------------------------------------------*/
-int do_final(void) {
+int do_final(void)
+{
int i;
struct map_session_data* sd;
struct s_mapiterator* iter;
@@ -5649,6 +6193,7 @@ int do_final(void) {
ircbot->final();/* before channel. */
channel->final();
chrif->final();
+ clan->final();
clif->final();
npc->final();
quest->final();
@@ -5665,20 +6210,24 @@ int do_final(void) {
atcommand->final_msg();
skill->final();
status->final();
+ refine->final();
unit->final();
bg->final();
duel->final();
elemental->final();
map->list_final();
vending->final();
+ rodex->final();
+ achievement->final();
+ stylist->final();
HPM_map_do_final();
map->map_db->destroy(map->map_db, map->db_final);
mapindex->final();
- if(map->enable_grf)
- grfio_final();
+ if (map->enable_grf)
+ grfio->final();
db_destroy(map->id_db);
db_destroy(map->pc_db);
@@ -5693,6 +6242,11 @@ int do_final(void) {
ers_destroy(map->iterator_ers);
ers_destroy(map->flooritem_ers);
+ for (i = 0; i < map->count; ++i) {
+ if (map->list[i].cell_buf.data != NULL)
+ aFree(map->list[i].cell_buf.data);
+ map->list[i].cell_buf.len = 0;
+ }
aFree(map->list);
if( map->block_free )
@@ -5700,9 +6254,6 @@ int do_final(void) {
if( map->bl_list )
aFree(map->bl_list);
- if( !map->enable_grf )
- aFree(map->cache_buffer);
-
aFree(map->MAP_CONF_NAME);
aFree(map->BATTLE_CONF_FILENAME);
aFree(map->ATCOMMAND_CONF_FILENAME);
@@ -5718,7 +6269,8 @@ int do_final(void) {
return map->retval;
}
-int map_abort_sub(struct map_session_data* sd, va_list ap) {
+static int map_abort_sub(struct map_session_data *sd, va_list ap)
+{
chrif->save(sd,1);
return 1;
}
@@ -5747,12 +6299,13 @@ void do_abort(void)
chrif->flush();
}
-void set_server_type(void) {
+void set_server_type(void)
+{
SERVER_TYPE = SERVER_TYPE_MAP;
}
/// Called when a terminate signal is received.
-void do_shutdown(void)
+static void do_shutdown(void)
{
if( core->runflag != MAPSERVER_ST_SHUTDOWN )
{
@@ -5770,7 +6323,8 @@ void do_shutdown(void)
}
}
-CPCMD(gm_position) {
+static CPCMD(gm_position)
+{
int x = 0, y = 0, m = 0;
char map_name[25];
@@ -5793,8 +6347,10 @@ CPCMD(gm_position) {
map->cpsd->bl.x = x;
map->cpsd->bl.y = y;
map->cpsd->bl.m = m;
+ map->cpsd->mapindex = map_id2index(m);
}
-CPCMD(gm_use) {
+static CPCMD(gm_use)
+{
if( line == NULL ) {
ShowError("gm:use invalid syntax. use '"CL_WHITE"gm:use @command <optional params>"CL_RESET"'\n");
@@ -5811,7 +6367,8 @@ CPCMD(gm_use) {
map->cpsd_active = false;
}
/* Hercules Console Parser */
-void map_cp_defaults(void) {
+static void map_cp_defaults(void)
+{
#ifdef CONSOLE_INPUT
/* default HCP data */
map->cpsd = pc->get_dummy_sd();
@@ -5819,13 +6376,16 @@ void map_cp_defaults(void) {
map->cpsd->bl.x = mapindex->default_x;
map->cpsd->bl.y = mapindex->default_y;
map->cpsd->bl.m = map->mapname2mapid(mapindex->default_map);
+ Assert_retv(map->cpsd->bl.m >= 0);
+ map->cpsd->mapindex = map_id2index(map->cpsd->bl.m);
console->input->addCommand("gm:info",CPCMD_A(gm_position));
console->input->addCommand("gm:use",CPCMD_A(gm_use));
#endif
}
-void map_load_defaults(void) {
+static void map_load_defaults(void)
+{
mapindex_defaults();
map_defaults();
/* */
@@ -5834,6 +6394,7 @@ void map_load_defaults(void) {
battleground_defaults();
buyingstore_defaults();
channel_defaults();
+ clan_defaults();
clif_defaults();
chrif_defaults();
guild_defaults();
@@ -5866,7 +6427,11 @@ void map_load_defaults(void) {
pet_defaults();
path_defaults();
quest_defaults();
+ achievement_defaults();
npc_chat_defaults();
+ rodex_defaults();
+ stylist_defaults();
+ refine_defaults();
}
/**
* --run-once handler
@@ -6002,22 +6567,6 @@ static CMDLINEARG(loadscript)
}
/**
- * --generate-translations
- *
- * Creates "./generated_translations.pot"
- * @see cmdline->exec
- **/
-static CMDLINEARG(generatetranslations) {
- script->lang_export_file = aStrdup("./generated_translations.pot");
-
- if( !(script->lang_export_fp = fopen(script->lang_export_file,"wb")) ) {
- ShowError("export-dialog: failed to open '%s' for writing\n",script->lang_export_file);
- }
- core->runflag = CORE_ST_STOP;
- return true;
-}
-
-/**
* Defines the local command line arguments
*/
void cmdline_args_init_local(void)
@@ -6033,7 +6582,6 @@ void cmdline_args_init_local(void)
CMDLINEARG_DEF2(log-config, logconfig, "Alternative logging configuration.", CMDLINE_OPT_NORMAL|CMDLINE_OPT_PARAM);
CMDLINEARG_DEF2(script-check, scriptcheck, "Doesn't run the server, only tests the scripts passed through --load-script.", CMDLINE_OPT_SILENT);
CMDLINEARG_DEF2(load-script, loadscript, "Loads an additional script (can be repeated).", CMDLINE_OPT_NORMAL|CMDLINE_OPT_PARAM);
- CMDLINEARG_DEF2(generate-translations, generatetranslations, "Creates './generated_translations.pot' file with all translateable strings from scripts, server terminates afterwards.", CMDLINE_OPT_NORMAL);
}
int do_init(int argc, char *argv[])
@@ -6047,12 +6595,12 @@ int do_init(int argc, char *argv[])
map_load_defaults();
- map->INTER_CONF_NAME = aStrdup("conf/inter-server.conf");
- map->LOG_CONF_NAME = aStrdup("conf/logs.conf");
- map->MAP_CONF_NAME = aStrdup("conf/map-server.conf");
- map->BATTLE_CONF_FILENAME = aStrdup("conf/battle.conf");
+ map->INTER_CONF_NAME = aStrdup("conf/common/inter-server.conf");
+ map->LOG_CONF_NAME = aStrdup("conf/map/logs.conf");
+ map->MAP_CONF_NAME = aStrdup("conf/map/map-server.conf");
+ map->BATTLE_CONF_FILENAME = aStrdup("conf/map/battle.conf");
map->ATCOMMAND_CONF_FILENAME = aStrdup("conf/atcommand.conf");
- map->SCRIPT_CONF_NAME = aStrdup("conf/script.conf");
+ map->SCRIPT_CONF_NAME = aStrdup("conf/map/script.conf");
map->MSG_CONF_NAME = aStrdup("conf/messages.conf");
map->GRF_PATH_FILENAME = aStrdup("conf/grf-files.txt");
@@ -6065,10 +6613,30 @@ int do_init(int argc, char *argv[])
cmdline->exec(argc, argv, CMDLINE_OPT_NORMAL);
minimal = map->minimal;/* temp (perhaps make minimal a mask with options of what to load? e.g. plugin 1 does minimal |= mob_db; */
if (!minimal) {
- map->config_read(map->MAP_CONF_NAME);
- CREATE(map->list,struct map_data,map->count);
- map->count = 0;
- map->config_read_sub(map->MAP_CONF_NAME);
+ map->config_read(map->MAP_CONF_NAME, false);
+
+ {
+ // TODO: Remove this when no longer needed.
+#define CHECK_OLD_LOCAL_CONF(oldname, newname) do { \
+ if (stat((oldname), &fileinfo) == 0 && fileinfo.st_size > 0) { \
+ ShowWarning("An old configuration file \"%s\" was found.\n", (oldname)); \
+ ShowWarning("If it contains settings you wish to keep, please merge them into \"%s\".\n", (newname)); \
+ ShowWarning("Otherwise, just delete it.\n"); \
+ ShowInfo("Resuming in 10 seconds...\n"); \
+ HSleep(10); \
+ } \
+} while (0)
+ struct stat fileinfo;
+
+ CHECK_OLD_LOCAL_CONF("conf/import/map_conf.txt", "conf/import/map-server.conf");
+ CHECK_OLD_LOCAL_CONF("conf/import/inter_conf.txt", "conf/import/inter-server.conf");
+ CHECK_OLD_LOCAL_CONF("conf/import/log_conf.txt", "conf/import/logs.conf");
+ CHECK_OLD_LOCAL_CONF("conf/import/script_conf.txt", "conf/import/script.conf");
+ CHECK_OLD_LOCAL_CONF("conf/import/packet_conf.txt", "conf/import/socket.conf");
+ CHECK_OLD_LOCAL_CONF("conf/import/battle_conf.txt", "conf/import/battle.conf");
+
+#undef CHECK_OLD_LOCAL_CONF
+ }
// loads npcs
map->reloadnpc(false);
@@ -6079,7 +6647,9 @@ int do_init(int argc, char *argv[])
char ip_str[16];
sockt->ip2str(sockt->addr_[0], ip_str);
- ShowWarning("Not all IP addresses in /conf/map-server.conf configured, auto-detecting...\n");
+#ifndef BUILDBOT
+ ShowWarning("Not all IP addresses in /conf/map/map-server.conf configured, auto-detecting...\n");
+#endif
if (sockt->naddr_ == 0)
ShowError("Unable to determine your IP address...\n");
@@ -6094,12 +6664,12 @@ int do_init(int argc, char *argv[])
chrif->setip(ip_str);
}
- battle->config_read(map->BATTLE_CONF_FILENAME);
+ battle->config_read(map->BATTLE_CONF_FILENAME, false);
atcommand->msg_read(map->MSG_CONF_NAME, false);
- map->inter_config_read(map->INTER_CONF_NAME);
- logs->config_read(map->LOG_CONF_NAME);
+ map->inter_config_read(map->INTER_CONF_NAME, false);
+ logs->config_read(map->LOG_CONF_NAME, false);
}
- script->config_read(map->SCRIPT_CONF_NAME);
+ script->config_read(map->SCRIPT_CONF_NAME, false);
map->id_db = idb_alloc(DB_OPT_BASE);
map->pc_db = idb_alloc(DB_OPT_BASE); //Added for reliable map->id2sd() use. [Skotlex]
@@ -6137,8 +6707,8 @@ int do_init(int argc, char *argv[])
}
}
- if(map->enable_grf)
- grfio_init(map->GRF_PATH_FILENAME);
+ if (map->enable_grf)
+ grfio->init(map->GRF_PATH_FILENAME);
map->readallmaps();
@@ -6160,11 +6730,13 @@ int do_init(int argc, char *argv[])
ircbot->init(minimal);
script->init(minimal);
itemdb->init(minimal);
+ clan->init(minimal);
skill->init(minimal);
if (!minimal)
map->read_zone_db();/* read after item and skill initialization */
mob->init(minimal);
pc->init(minimal);
+ refine->init(minimal);
status->init(minimal);
party->init(minimal);
guild->init(minimal);
@@ -6174,11 +6746,14 @@ int do_init(int argc, char *argv[])
mercenary->init(minimal);
elemental->init(minimal);
quest->init(minimal);
+ achievement->init(minimal);
+ stylist->init(minimal);
npc->init(minimal);
unit->init(minimal);
bg->init(minimal);
duel->init(minimal);
vending->init(minimal);
+ rodex->init(minimal);
if (map->scriptcheck) {
bool failed = map->extra_scripts_count > 0 ? false : true;
@@ -6198,6 +6773,8 @@ int do_init(int argc, char *argv[])
npc->event_do_oninit( false ); // Init npcs (OnInit)
npc->market_fromsql(); /* after OnInit */
+ npc->barter_fromsql(); /* after OnInit */
+ npc->expanded_barter_fromsql(); /* after OnInit */
if (battle_config.pk_mode)
ShowNotice("Server is running on '"CL_WHITE"PK Mode"CL_RESET"'.\n");
@@ -6225,11 +6802,12 @@ int do_init(int argc, char *argv[])
}
/*=====================================
-* Default Functions : map.h
-* Generated by HerculesInterfaceMaker
-* created by Susu
-*-------------------------------------*/
-void map_defaults(void) {
+ * Default Functions : map.h
+ * Generated by HerculesInterfaceMaker
+ * created by Susu
+ *-------------------------------------*/
+void map_defaults(void)
+{
map = &map_s;
/* */
@@ -6242,8 +6820,8 @@ void map_defaults(void) {
map->extra_scripts_count = 0;
sprintf(map->db_path ,"db");
+ libconfig->set_db_path(map->db_path);
sprintf(map->help_txt ,"conf/help.txt");
- sprintf(map->help2_txt ,"conf/help2.txt");
sprintf(map->charhelp_txt ,"conf/charhelp.txt");
sprintf(map->wisp_server_name ,"Server"); // can be modified in char-server configuration file
@@ -6256,12 +6834,12 @@ void map_defaults(void) {
map->night_flag = 0; // 0=day, 1=night [Yor]
map->enable_spy = 0; //To enable/disable @spy commands, which consume too much cpu time when sending packets. [Skotlex]
- map->INTER_CONF_NAME="conf/inter-server.conf";
- map->LOG_CONF_NAME="conf/logs.conf";
- map->MAP_CONF_NAME = "conf/map-server.conf";
- map->BATTLE_CONF_FILENAME = "conf/battle.conf";
+ map->INTER_CONF_NAME="conf/common/inter-server.conf";
+ map->LOG_CONF_NAME="conf/map/logs.conf";
+ map->MAP_CONF_NAME = "conf/map/map-server.conf";
+ map->BATTLE_CONF_FILENAME = "conf/map/battle.conf";
map->ATCOMMAND_CONF_FILENAME = "conf/atcommand.conf";
- map->SCRIPT_CONF_NAME = "conf/script.conf";
+ map->SCRIPT_CONF_NAME = "conf/map/script.conf";
map->MSG_CONF_NAME = "conf/messages.conf";
map->GRF_PATH_FILENAME = "conf/grf-files.txt";
@@ -6304,13 +6882,15 @@ void map_defaults(void) {
map->bl_list_size = 0;
//all in a big chunk, respects order
+PRAGMA_GCC9(GCC diagnostic push)
+PRAGMA_GCC9(GCC diagnostic ignored "-Warray-bounds")
memset(ZEROED_BLOCK_POS(map), 0, ZEROED_BLOCK_SIZE(map));
+PRAGMA_GCC9(GCC diagnostic pop)
map->cpsd = NULL;
map->list = NULL;
map->iterator_ers = NULL;
- map->cache_buffer = NULL;
map->flooritem_ers = NULL;
/* */
@@ -6318,9 +6898,11 @@ void map_defaults(void) {
/* funcs */
map->zone_init = map_zone_init;
map->zone_remove = map_zone_remove;
+ map->zone_remove_all = map_zone_remove_all;
map->zone_apply = map_zone_apply;
map->zone_change = map_zone_change;
map->zone_change2 = map_zone_change2;
+ map->zone_reload = map_zonedb_reload;
map->getcell = map_getcell;
map->setgatcell = map_setgatcell;
@@ -6390,6 +6972,7 @@ void map_defaults(void) {
map->foreachinpath = map_foreachinpath;
map->vforeachinmap = map_vforeachinmap;
map->foreachinmap = map_foreachinmap;
+ map->forcountinmap = map_forcountinmap;
map->vforeachininstance = map_vforeachininstance;
map->foreachininstance = map_foreachininstance;
@@ -6457,8 +7040,8 @@ void map_defaults(void) {
map->iwall_nextxy = map_iwall_nextxy;
map->create_map_data_other_server = create_map_data_other_server;
map->eraseallipport_sub = map_eraseallipport_sub;
- map->init_mapcache = map_init_mapcache;
map->readfromcache = map_readfromcache;
+ map->readfromcache_v1 = map_readfromcache_v1;
map->addmap = map_addmap;
map->delmapid = map_delmapid;
map->zone_db_clear = map_zone_db_clear;
@@ -6467,9 +7050,10 @@ void map_defaults(void) {
map->readgat = map_readgat;
map->readallmaps = map_readallmaps;
map->config_read = map_config_read;
- map->config_read_sub = map_config_read_sub;
- map->reloadnpc_sub = map_reloadnpc_sub;
+ map->read_npclist = map_read_npclist;
map->inter_config_read = inter_config_read;
+ map->inter_config_read_database_names = inter_config_read_database_names;
+ map->inter_config_read_connection = inter_config_read_connection;
map->sql_init = map_sql_init;
map->sql_close = map_sql_close;
map->zone_mf_cache = map_zone_mf_cache;