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.c855
1 files changed, 566 insertions, 289 deletions
diff --git a/src/map/map.c b/src/map/map.c
index d920875ee..838a88f01 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -76,6 +76,22 @@ int map_getusers(void) {
return map->users;
}
+/**
+ * Expands map->bl_list on demand
+ **/
+static inline void map_bl_list_expand(void) {
+ map->bl_list_size += 250;
+ RECREATE(map->bl_list, struct block_list *, map->bl_list_size);
+}
+
+/**
+ * Expands map->block_free on demand
+ **/
+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);
+}
+
/*==========================================
* server player count (this mapserver only)
*------------------------------------------*/
@@ -88,13 +104,20 @@ int map_usercount(void) {
*------------------------------------------*/
int map_freeblock (struct block_list *bl) {
nullpo_retr(map->block_free_lock, bl);
- if (map->block_free_lock == 0 || map->block_free_count >= block_free_max) {
- aFree(bl);
+
+ if (map->block_free_lock == 0) {
+ if( bl->type == BL_ITEM )
+ ers_free(map->flooritem_ers, bl);
+ else
+ aFree(bl);
bl = NULL;
- if (map->block_free_count >= block_free_max)
- ShowWarning("map_freeblock: too many free block! %d %d\n", map->block_free_count, map->block_free_lock);
- } else
+ } else {
+
+ if( map->block_free_count >= map->block_free_list_size )
+ map_block_free_expand();
+
map->block_free[map->block_free_count++] = bl;
+ }
return map->block_free_lock;
}
@@ -109,11 +132,14 @@ int map_freeblock_lock (void) {
* Remove the lock on map_bl
*------------------------------------------*/
int map_freeblock_unlock (void) {
+
if ((--map->block_free_lock) == 0) {
int i;
- for (i = 0; i < map->block_free_count; i++)
- {
- aFree(map->block_free[i]);
+ for (i = 0; i < map->block_free_count; i++) {
+ if( map->block_free[i]->type == BL_ITEM )
+ ers_free(map->flooritem_ers, map->block_free[i]);
+ else
+ aFree(map->block_free[i]);
map->block_free[i] = NULL;
}
map->block_free_count = 0;
@@ -127,7 +153,7 @@ 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, unsigned int tick, int id, intptr_t data) {
+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;
@@ -259,8 +285,7 @@ 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, unsigned int tick)
-{
+int map_moveblock(struct block_list *bl, int x1, int y1, int64 tick) {
int x0 = bl->x, y0 = bl->y;
struct status_change *sc = NULL;
int moveblock = ( x0/BLOCK_SIZE != x1/BLOCK_SIZE || y0/BLOCK_SIZE != y1/BLOCK_SIZE);
@@ -477,23 +502,22 @@ static int map_vforeachinmap(int (*func)(struct block_list*, va_list), int16 m,
for (i = 0; i < bsize; i++) {
if (type&~BL_MOB) {
for (bl = map->list[m].block[i]; bl != NULL; bl = bl->next) {
- if (bl->type&type && map->bl_list_count < BL_LIST_MAX) {
+ if (bl->type&type) {
+ if( map->bl_list_count >= map->bl_list_size )
+ map_bl_list_expand();
map->bl_list[map->bl_list_count++] = bl;
}
}
}
if (type&BL_MOB) {
for (bl = map->list[m].block_mob[i]; bl != NULL; bl = bl->next) {
- if (map->bl_list_count < BL_LIST_MAX) {
- map->bl_list[map->bl_list_count++] = bl;
- }
+ if( map->bl_list_count >= map->bl_list_size )
+ map_bl_list_expand();
+ map->bl_list[map->bl_list_count++] = bl;
}
}
}
- if (map->bl_list_count >= BL_LIST_MAX)
- ShowError("map.c:map_vforeachinmap: bl_list size (%d) exceeded\n", BL_LIST_MAX);
-
va_copy(argscopy, args);
returnCount = bl_vforeach(func, blockcount, INT_MAX, argscopy);
va_end(argscopy);
@@ -601,52 +625,45 @@ static int bl_getall_area(int type, int m, int x0, int y0, int x1, int y1, int (
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 (map->bl_list_count < BL_LIST_MAX
- && bl->type&type
- && bl->x >= x0 && bl->x <= x1
- && bl->y >= y0 && bl->y <= y1) {
- if (func) {
- va_start(args, func);
- if (func(bl, args)) {
- map->bl_list[map->bl_list_count++] = bl;
- found++;
- }
- va_end(args);
- }
- else {
+ 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)) {
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 (map->bl_list_count < BL_LIST_MAX
- //&& bl->type&type // block_mob contains BL_MOBs only
- && bl->x >= x0 && bl->x <= x1
- && bl->y >= y0 && bl->y <= y1) {
- if (func) {
- va_start(args, func);
- if (func(bl, args)) {
- map->bl_list[map->bl_list_count++] = bl;
- found++;
- }
- va_end(args);
- }
- else {
+ 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)) {
map->bl_list[map->bl_list_count++] = bl;
found++;
}
+ va_end(args);
+ } else {
+ map->bl_list[map->bl_list_count++] = bl;
+ found++;
+ }
}
}
}
}
}
- if (map->bl_list_count >= BL_LIST_MAX)
- ShowError("map.c:bl_getall_area: bl_list size (%d) exceeded\n", BL_LIST_MAX);
-
return found;
}
@@ -689,7 +706,7 @@ int map_vforeachinrange(int (*func)(struct block_list*, va_list), struct block_l
va_copy(apcopy, ap);
returnCount = bl_vforeach(func, blockcount, INT_MAX, apcopy);
- va_end(ap);
+ va_end(apcopy);
return returnCount;
}
@@ -1305,7 +1322,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, unsigned int tick, int id, intptr_t data) {
+int map_clearflooritem_timer(int tid, int64 tick, int id, intptr_t data) {
struct flooritem_data* fitem = (struct flooritem_data*)idb_get(map->id_db, id);
if (fitem == NULL || fitem->bl.type != BL_ITEM || (fitem->cleartimer != tid)) {
@@ -1330,7 +1347,7 @@ int map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr_t data)
void map_clearflooritem(struct block_list *bl) {
struct flooritem_data* fitem = (struct flooritem_data*)bl;
- if( fitem->cleartimer )
+ if( fitem->cleartimer != INVALID_TIMER )
timer->delete(fitem->cleartimer,map->clearflooritem_timer);
clif->clearflooritem(fitem, 0);
@@ -1470,15 +1487,16 @@ int map_addflooritem(struct item *item_data,int amount,int16 m,int16 x,int16 y,i
return 0;
r=rnd();
- CREATE(fitem, struct flooritem_data, 1);
- fitem->bl.type=BL_ITEM;
+ fitem = ers_alloc(map->flooritem_ers, struct flooritem_data);
+
+ fitem->bl.type = BL_ITEM;
fitem->bl.prev = fitem->bl.next = NULL;
- fitem->bl.m=m;
- fitem->bl.x=x;
- fitem->bl.y=y;
+ fitem->bl.m = m;
+ fitem->bl.x = x;
+ fitem->bl.y = y;
fitem->bl.id = map->get_new_object_id();
if(fitem->bl.id==0){
- aFree(fitem);
+ ers_free(map->flooritem_ers, fitem);
return 0;
}
@@ -1656,6 +1674,9 @@ int map_quit(struct map_session_data *sd) {
//Non-active players should not have loaded any data yet (or it was cleared already) so no additional cleanups are needed.
return 0;
}
+
+ if( sd->expiration_tid != INVALID_TIMER )
+ timer->delete(sd->expiration_tid,pc->expiration_timer);
if (sd->npc_timer_id != INVALID_TIMER) //Cancel the event timer.
npc->timerevent_quit(sd);
@@ -1666,6 +1687,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,1);
+ if( sd->state.autotrade && runflag != MAPSERVER_ST_SHUTDOWN && !hChSys.closing )
+ pc->autotrade_update(sd,PAUC_REMOVE);
+
skill->cooldown_save(sd);
pc->itemcd_do(sd,false);
@@ -1715,8 +1739,6 @@ int map_quit(struct map_session_data *sd) {
if( sd->state.storage_flag == 1 ) sd->state.storage_flag = 0; // No need to Double Save Storage on Quit.
- if (sd->state.permanent_speed == 1) sd->state.permanent_speed = 0; // Remove lock so speed is set back to normal at login.
-
if( sd->ed ) {
elemental->clean_effect(sd->ed);
unit->remove_map(&sd->ed->bl,CLR_TELEPORT,ALC_MARK);
@@ -2087,9 +2109,7 @@ struct s_mapiterator
/// @param _bl_ block_list
/// @return true if it matches
#define MAPIT_MATCHES(_mapit_,_bl_) \
- ( \
- ( (_bl_)->type & (_mapit_)->types /* type matches */ ) \
- )
+ ( (_bl_)->type & (_mapit_)->types /* type matches */ )
/// Allocates a new iterator.
/// Returns the new iterator.
@@ -2233,7 +2253,7 @@ 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) {
- size_t i;
+ int i;
ARR_FIND( 0, MAX_MOB_LIST_PER_MAP, i, map->list[m].moblist[i] == NULL );
if( i < MAX_MOB_LIST_PER_MAP ) {
map->list[m].moblist[i] = spawn;
@@ -2288,8 +2308,7 @@ int map_removemobs_sub(struct block_list *bl, va_list ap)
return 1;
}
-int map_removemobs_timer(int tid, unsigned int tick, int id, intptr_t data)
-{
+int map_removemobs_timer(int tid, int64 tick, int id, intptr_t data) {
int count;
const int16 m = id;
@@ -2325,7 +2344,7 @@ void map_removemobs(int16 m) {
*------------------------------------------*/
int16 map_mapname2mapid(const char* name) {
unsigned short map_index;
- map_index = mapindex_name2id(name);
+ map_index = mapindex->name2id(name);
if (!map_index)
return -1;
return map->mapindex2mapid(map_index);
@@ -2334,12 +2353,12 @@ int16 map_mapname2mapid(const char* name) {
/*==========================================
* Returns the map of the given mapindex. [Skotlex]
*------------------------------------------*/
-int16 map_mapindex2mapid(unsigned short mapindex) {
+int16 map_mapindex2mapid(unsigned short map_index) {
- if (!mapindex || mapindex > MAX_MAPINDEX)
+ if (!map_index || map_index > MAX_MAPINDEX)
return -1;
- return map->index2mapid[mapindex];
+ return map->index2mapid[map_index];
}
/*==========================================
@@ -2555,8 +2574,6 @@ int map_getcellp(struct map_data* m,int16 x,int16 y,cell_chk cellchk) {
return (cell.novending);
case CELL_CHKNOCHAT:
return (cell.nochat);
- case CELL_CHKMAELSTROM:
- return (cell.maelstrom);
case CELL_CHKICEWALL:
return (cell.icewall);
@@ -2617,7 +2634,6 @@ void map_setcell(int16 m, int16 x, int16 y, cell_t cell, bool flag) {
case CELL_LANDPROTECTOR: map->list[m].cell[j].landprotector = flag; break;
case CELL_NOVENDING: map->list[m].cell[j].novending = flag; break;
case CELL_NOCHAT: map->list[m].cell[j].nochat = flag; break;
- case CELL_MAELSTROM: map->list[m].cell[j].maelstrom = flag; break;
case CELL_ICEWALL: map->list[m].cell[j].icewall = flag; break;
default:
ShowWarning("map_setcell: invalid cell type '%d'\n", (int)cell);
@@ -2761,27 +2777,27 @@ void map_iwall_remove(const char *wall_name)
DBData create_map_data_other_server(DBKey key, va_list args)
{
struct map_data_other_server *mdos;
- unsigned short mapindex = (unsigned short)key.ui;
+ unsigned short map_index = (unsigned short)key.ui;
mdos=(struct map_data_other_server *)aCalloc(1,sizeof(struct map_data_other_server));
- mdos->index = mapindex;
- memcpy(mdos->name, mapindex_id2name(mapindex), MAP_NAME_LENGTH);
+ mdos->index = map_index;
+ memcpy(mdos->name, mapindex_id2name(map_index), MAP_NAME_LENGTH);
return DB->ptr2data(mdos);
}
/*==========================================
* Add mapindex to db of another map server
*------------------------------------------*/
-int map_setipport(unsigned short mapindex, uint32 ip, uint16 port)
+int map_setipport(unsigned short map_index, uint32 ip, uint16 port)
{
struct map_data_other_server *mdos;
- mdos= uidb_ensure(map->map_db,(unsigned int)mapindex, map->create_map_data_other_server);
+ mdos= uidb_ensure(map->map_db,(unsigned int)map_index, map->create_map_data_other_server);
if(mdos->cell) //Local map,Do nothing. Give priority to our own local maps over ones from another server. [Skotlex]
return 0;
if(ip == clif->map_ip && port == clif->map_port) {
//That's odd, we received info that we are the ones with this map, but... we don't have it.
- ShowFatalError("map_setipport : received info that this map-server SHOULD have map '%s', but it is not loaded.\n",mapindex_id2name(mapindex));
+ ShowFatalError("map_setipport : received info that this map-server SHOULD have map '%s', but it is not loaded.\n",mapindex_id2name(map_index));
exit(EXIT_FAILURE);
}
mdos->ip = ip;
@@ -2811,15 +2827,15 @@ int map_eraseallipport(void) {
/*==========================================
* Delete mapindex from db of another map server
*------------------------------------------*/
-int map_eraseipport(unsigned short mapindex, uint32 ip, uint16 port) {
+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)mapindex);
+ mdos = (struct map_data_other_server*)uidb_get(map->map_db,(unsigned int)map_index);
if(!mdos || mdos->cell) //Map either does not exists or is a local map.
return 0;
if(mdos->ip==ip && mdos->port == port) {
- uidb_remove(map->map_db,(unsigned int)mapindex);
+ uidb_remove(map->map_db,(unsigned int)map_index);
aFree(mdos);
return 1;
}
@@ -2901,14 +2917,14 @@ int map_readfromcache(struct map_data *m, char *buffer) {
}
-int map_addmap(char* mapname) {
+int map_addmap(const char* mapname) {
map->list[map->count].instance_id = -1;
- mapindex_getmapname(mapname, map->list[map->count++].name);
+ mapindex->getmapname(mapname, map->list[map->count++].name);
return 0;
}
void map_delmapid(int id) {
- ShowNotice("Removing map [ %s ] from map->list"CL_CLL"\n",map->list[id].name);
+ 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--;
}
@@ -2922,7 +2938,7 @@ int map_delmap(char* mapname) {
return 0;
}
- mapindex_getmapname(mapname, map_name);
+ mapindex->getmapname(mapname, map_name);
for(i = 0; i < map->count; i++) {
if (strcmp(map->list[i].name, map_name) == 0) {
map->delmapid(i);
@@ -3104,6 +3120,18 @@ void do_final_maps(void) {
if( map->list[i].channel )
clif->chsys_delete(map->list[i].channel);
+
+ if( map->list[i].qi_data )
+ aFree(map->list[i].qi_data);
+
+ for( v = 0; v < map->list[i].hdatac; v++ ) {
+ if( map->list[i].hdata[v]->flag.free ) {
+ aFree(map->list[i].hdata[v]->data);
+ }
+ aFree(map->list[i].hdata[v]);
+ }
+ if( map->list[i].hdata )
+ aFree(map->list[i].hdata);
}
map->zone_db_clear();
@@ -3169,6 +3197,12 @@ void map_flags_init(void) {
map->list[i].misc_damage_rate = 100;
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;
}
}
@@ -3303,7 +3337,7 @@ int map_readallmaps (void) {
continue;
}
- map->list[i].index = mapindex_name2id(map->list[i].name);
+ map->list[i].index = mapindex->name2id(map->list[i].name);
if ( map->index2mapid[map_id2index(i)] != -1 ) {
ShowWarning("Map %s already loaded!"CL_CLL"\n", map->list[i].name);
@@ -3516,6 +3550,8 @@ void map_reloadnpc_sub(char *cfgName)
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);
}
@@ -3591,6 +3627,10 @@ int inter_config_read(char *cfgName) {
map->db_use_sql_mob_skill_db = config_switch(w2);
ShowStatus ("Using monster skill database as SQL: '%s'\n", w2);
}
+ else if(strcmpi(w1,"autotrade_merchants_db")==0)
+ strcpy(map->autotrade_merchants_db, w2);
+ else if(strcmpi(w1,"autotrade_data_db")==0)
+ strcpy(map->autotrade_data_db, w2);
/* sql log db */
else if(strcmpi(w1,"log_db_ip")==0)
strcpy(logs->db_ip, w2);
@@ -3645,14 +3685,115 @@ int map_sql_close(void)
return 0;
}
+/**
+ * Merges two zones into a new one
+ * @param main the zone whose data must override the others upon conflict,
+ * e.g. enabling pvp on a town means that main is the pvp zone, while "other" is the towns previous zone
+ *
+ * @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) {
+ char newzone[MAP_ZONE_NAME_LENGTH];
+ struct map_zone_data *zone = NULL;
+ int cursor, i;
+
+ sprintf(newzone, "%s+%s",main->name,other->name);
+
+ if( (zone = strdb_get(map->zone_db, newzone)) )
+ return zone;/* this zone has already been merged */
+
+ CREATE(zone, struct map_zone_data, 1);
+
+ safestrncpy(zone->name, newzone, MAP_ZONE_NAME_LENGTH);
+
+ zone->disabled_skills_count = main->disabled_skills_count + other->disabled_skills_count;
+ zone->disabled_items_count = main->disabled_items_count + other->disabled_items_count;
+ zone->mapflags_count = main->mapflags_count + other->mapflags_count;
+ zone->disabled_commands_count = main->disabled_commands_count + other->disabled_commands_count;
+ zone->capped_skills_count = main->capped_skills_count + other->capped_skills_count;
+
+ CREATE(zone->disabled_skills, struct map_zone_disabled_skill_entry *, zone->disabled_skills_count );
+
+ for(i = 0, cursor = 0; i < main->disabled_skills_count; i++, cursor++ ) {
+ CREATE(zone->disabled_skills[cursor], struct map_zone_disabled_skill_entry, 1 );
+ memcpy(zone->disabled_skills[cursor], main->disabled_skills[i], sizeof(struct map_zone_disabled_skill_entry));
+ }
+
+ for(i = 0; i < other->disabled_skills_count; i++, cursor++ ) {
+ CREATE(zone->disabled_skills[cursor], struct map_zone_disabled_skill_entry, 1 );
+ memcpy(zone->disabled_skills[cursor], other->disabled_skills[i], sizeof(struct map_zone_disabled_skill_entry));
+ }
+
+ CREATE(zone->disabled_items, int, zone->disabled_items_count );
+
+ for(i = 0, cursor = 0; i < main->disabled_items_count; i++, cursor++ ) {
+ zone->disabled_items[cursor] = main->disabled_items[i];
+ }
+
+ for(i = 0; i < other->disabled_items_count; i++, cursor++ ) {
+ zone->disabled_items[cursor] = other->disabled_items[i];
+ }
+
+ CREATE(zone->mapflags, char *, zone->mapflags_count );
+
+ for(i = 0, cursor = 0; i < main->mapflags_count; i++, cursor++ ) {
+ CREATE(zone->mapflags[cursor], char, MAP_ZONE_MAPFLAG_LENGTH );
+ safestrncpy(zone->mapflags[cursor], main->mapflags[i], MAP_ZONE_MAPFLAG_LENGTH);
+ }
+
+ for(i = 0; i < other->mapflags_count; i++, cursor++ ) {
+ CREATE(zone->mapflags[cursor], char, MAP_ZONE_MAPFLAG_LENGTH );
+ safestrncpy(zone->mapflags[cursor], other->mapflags[i], MAP_ZONE_MAPFLAG_LENGTH);
+ }
+
+ CREATE(zone->disabled_commands, struct map_zone_disabled_command_entry *, zone->disabled_commands_count);
+
+ for(i = 0, cursor = 0; i < main->disabled_commands_count; i++, cursor++ ) {
+ CREATE(zone->disabled_commands[cursor], struct map_zone_disabled_command_entry, 1);
+ memcpy(zone->disabled_commands[cursor], main->disabled_commands[i], sizeof(struct map_zone_disabled_command_entry));
+ }
+
+ for(i = 0; i < other->disabled_commands_count; i++, cursor++ ) {
+ CREATE(zone->disabled_commands[cursor], struct map_zone_disabled_command_entry, 1);
+ memcpy(zone->disabled_commands[cursor], other->disabled_commands[i], sizeof(struct map_zone_disabled_command_entry));
+ }
+
+ CREATE(zone->capped_skills, struct map_zone_skill_damage_cap_entry *, zone->capped_skills_count);
+
+
+ for(i = 0, cursor = 0; i < main->capped_skills_count; i++, cursor++ ) {
+ CREATE(zone->capped_skills[cursor], struct map_zone_skill_damage_cap_entry, 1);
+ memcpy(zone->capped_skills[cursor], main->disabled_commands[i], sizeof(struct map_zone_skill_damage_cap_entry));
+ }
+
+ for(i = 0; i < other->capped_skills_count; i++, cursor++ ) {
+ CREATE(zone->capped_skills[cursor], struct map_zone_skill_damage_cap_entry, 1);
+ memcpy(zone->capped_skills[cursor], other->capped_skills[i], sizeof(struct map_zone_skill_damage_cap_entry));
+ }
+
+ zone->info.special = 2;
+
+ strdb_put(map->zone_db, newzone, zone);
+
+ return zone;
+}
+
void map_zone_change2(int m, struct map_zone_data *zone) {
char empty[1] = "\0";
- map->list[m].prev_zone = map->list[m].zone;
-
+ if( map->list[m].zone == zone )
+ return;
+
+ if( map->list[m].zone->info.special != 2 ) /* we don't update it for merged zones! */
+ map->list[m].prev_zone = map->list[m].zone;
+
if( map->list[m].zone_mf_count )
map->zone_remove(m);
+ if( zone->info.special ) {
+ zone = map->merge_zone(zone,map->list[m].prev_zone);
+ }
+
map->zone_apply(m,zone,empty,empty,empty);
}
/* when changing from a mapflag to another during runtime */
@@ -3669,7 +3810,7 @@ void map_zone_remove(int m) {
unsigned short k;
char empty[1] = "\0";
for(k = 0; k < map->list[m].zone_mf_count; k++) {
- int len = strlen(map->list[m].zone_mf[k]),j;
+ size_t len = strlen(map->list[m].zone_mf[k]),j;
params[0] = '\0';
memcpy(flag, map->list[m].zone_mf[k], MAP_ZONE_MAPFLAG_LENGTH);
for(j = 0; j < len; j++) {
@@ -4221,7 +4362,7 @@ 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];
- int len = strlen(params);
+ size_t len = strlen(params);
modifier[0] = '\0';
memcpy(skill_name, params, MAP_ZONE_MAPFLAG_LENGTH);
@@ -4239,7 +4380,6 @@ bool map_zone_mf_cache(int m, char *flag, char *params) {
} else {
int idx = map->list[m].unit_count;
- k = 0;
ARR_FIND(0, idx, k, map->list[m].units[k]->skill_id == skill_id);
if( k < idx ) {
@@ -4255,7 +4395,7 @@ 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];
- int len = strlen(params);
+ size_t len = strlen(params);
modifier[0] = '\0';
memcpy(skill_name, params, MAP_ZONE_MAPFLAG_LENGTH);
@@ -4273,7 +4413,6 @@ bool map_zone_mf_cache(int m, char *flag, char *params) {
} else {
int idx = map->list[m].skill_count;
- k = 0;
ARR_FIND(0, idx, k, map->list[m].skills[k]->skill_id == skill_id);
if( k < idx ) {
@@ -4380,7 +4519,17 @@ bool map_zone_mf_cache(int m, char *flag, char *params) {
map_zone_mf_cache_add(m,rflag);
}
}
+ } else if (!strcmpi(flag,"nocashshop")) {
+ if( state && map->list[m].flag.nocashshop )
+ ;/* nothing to do */
+ else {
+ if( state )
+ map_zone_mf_cache_add(m,"nocashshop\toff");
+ else if( map->list[m].flag.nocashshop )
+ map_zone_mf_cache_add(m,"nocashshop");
+ }
}
+
return false;
}
void map_zone_apply(int m, struct map_zone_data *zone, const char* start, const char* buffer, const char* filepath) {
@@ -4389,7 +4538,7 @@ void map_zone_apply(int m, struct map_zone_data *zone, const char* start, const
char flag[MAP_ZONE_MAPFLAG_LENGTH], params[MAP_ZONE_MAPFLAG_LENGTH];
map->list[m].zone = zone;
for(i = 0; i < zone->mapflags_count; i++) {
- int len = strlen(zone->mapflags[i]);
+ size_t len = strlen(zone->mapflags[i]);
int k;
params[0] = '\0';
memcpy(flag, zone->mapflags[i], MAP_ZONE_MAPFLAG_LENGTH);
@@ -4417,7 +4566,7 @@ void map_zone_init(void) {
zone = &map->zone_all;
for(i = 0; i < zone->mapflags_count; i++) {
- int len = strlen(zone->mapflags[i]);
+ size_t len = strlen(zone->mapflags[i]);
params[0] = '\0';
memcpy(flag, zone->mapflags[i], MAP_ZONE_MAPFLAG_LENGTH);
for(k = 0; k < len; k++) {
@@ -4440,7 +4589,7 @@ void map_zone_init(void) {
if( battle_config.pk_mode ) {
zone = &map->zone_pk;
for(i = 0; i < zone->mapflags_count; i++) {
- int len = strlen(zone->mapflags[i]);
+ size_t len = strlen(zone->mapflags[i]);
params[0] = '\0';
memcpy(flag, zone->mapflags[i], MAP_ZONE_MAPFLAG_LENGTH);
for(k = 0; k < len; k++) {
@@ -4547,10 +4696,10 @@ void read_map_zone_db(void) {
#else
const char *config_filename = "db/pre-re/map_zone_db.conf"; // FIXME hardcoded name
#endif
- if (conf_read_file(&map_zone_db, config_filename))
+ if (libconfig->read_file(&map_zone_db, config_filename))
return;
- zones = config_lookup(&map_zone_db, "zones");
+ zones = libconfig->lookup(&map_zone_db, "zones");
if (zones != NULL) {
struct map_zone_data *zone;
@@ -4567,16 +4716,16 @@ void read_map_zone_db(void) {
disabled_commands_count = 0, capped_skills_count = 0;
enum map_zone_skill_subtype subtype;
- zone_count = config_setting_length(zones);
+ zone_count = libconfig->setting_length(zones);
for (i = 0; i < zone_count; ++i) {
bool is_all = false;
- zone_e = config_setting_get_elem(zones, i);
+ zone_e = libconfig->setting_get_elem(zones, i);
- if (!config_setting_lookup_string(zone_e, "name", &zonename)) {
+ if (!libconfig->setting_lookup_string(zone_e, "name", &zonename)) {
ShowError("map_zone_db: missing zone name, skipping... (%s:%d)\n",
config_setting_source_file(zone_e), config_setting_source_line(zone_e));
- config_setting_remove_elem(zones,i);/* remove from the tree */
+ libconfig->setting_remove_elem(zones,i);/* remove from the tree */
--zone_count;
--i;
continue;
@@ -4584,7 +4733,7 @@ void read_map_zone_db(void) {
if( strdb_exists(map->zone_db, zonename) ) {
ShowError("map_zone_db: duplicate zone name '%s', skipping...\n",zonename);
- config_setting_remove_elem(zones,i);/* remove from the tree */
+ libconfig->setting_remove_elem(zones,i);/* remove from the tree */
--zone_count;
--i;
continue;
@@ -4602,33 +4751,33 @@ void read_map_zone_db(void) {
zone->disabled_skills_count = 0;
zone->disabled_items_count = 0;
}
- safestrncpy(zone->name, zonename, MAP_ZONE_NAME_LENGTH);
+ safestrncpy(zone->name, zonename, MAP_ZONE_NAME_LENGTH/2);
- if( (skills = config_setting_get_member(zone_e, "disabled_skills")) != NULL ) {
- disabled_skills_count = config_setting_length(skills);
+ if( (skills = libconfig->setting_get_member(zone_e, "disabled_skills")) != NULL ) {
+ disabled_skills_count = libconfig->setting_length(skills);
/* validate */
- for(h = 0; h < config_setting_length(skills); h++) {
- config_setting_t *skillinfo = config_setting_get_elem(skills, h);
+ for(h = 0; h < libconfig->setting_length(skills); h++) {
+ config_setting_t *skillinfo = libconfig->setting_get_elem(skills, h);
name = config_setting_name(skillinfo);
if( !map->zone_str2skillid(name) ) {
ShowError("map_zone_db: unknown skill (%s) in disabled_skills for zone '%s', skipping skill...\n",name,zone->name);
- config_setting_remove_elem(skills,h);
+ libconfig->setting_remove_elem(skills,h);
--disabled_skills_count;
--h;
continue;
}
- if( !map->zone_bl_type(config_setting_get_string_elem(skills,h),&subtype) )/* we dont remove it from the three due to inheritance */
+ if( !map->zone_bl_type(libconfig->setting_get_string_elem(skills,h),&subtype) )/* we dont remove it from the three due to inheritance */
--disabled_skills_count;
}
/* all ok, process */
CREATE( zone->disabled_skills, struct map_zone_disabled_skill_entry *, disabled_skills_count );
- for(h = 0, v = 0; h < config_setting_length(skills); h++) {
- config_setting_t *skillinfo = config_setting_get_elem(skills, h);
+ for(h = 0, v = 0; h < libconfig->setting_length(skills); h++) {
+ config_setting_t *skillinfo = libconfig->setting_get_elem(skills, h);
struct map_zone_disabled_skill_entry * entry;
enum bl_type type;
name = config_setting_name(skillinfo);
- if( (type = map->zone_bl_type(config_setting_get_string_elem(skills,h),&subtype)) ) { /* only add if enabled */
+ if( (type = map->zone_bl_type(libconfig->setting_get_string_elem(skills,h),&subtype)) ) { /* only add if enabled */
CREATE( entry, struct map_zone_disabled_skill_entry, 1 );
entry->nameid = map->zone_str2skillid(name);
@@ -4642,28 +4791,28 @@ void read_map_zone_db(void) {
zone->disabled_skills_count = disabled_skills_count;
}
- if( (items = config_setting_get_member(zone_e, "disabled_items")) != NULL ) {
- disabled_items_count = config_setting_length(items);
+ if( (items = libconfig->setting_get_member(zone_e, "disabled_items")) != NULL ) {
+ disabled_items_count = libconfig->setting_length(items);
/* validate */
- for(h = 0; h < config_setting_length(items); h++) {
- config_setting_t *item = config_setting_get_elem(items, h);
+ for(h = 0; h < libconfig->setting_length(items); h++) {
+ config_setting_t *item = libconfig->setting_get_elem(items, h);
name = config_setting_name(item);
if( !map->zone_str2itemid(name) ) {
ShowError("map_zone_db: unknown item (%s) in disabled_items for zone '%s', skipping item...\n",name,zone->name);
- config_setting_remove_elem(items,h);
+ libconfig->setting_remove_elem(items,h);
--disabled_items_count;
--h;
continue;
}
- if( !config_setting_get_bool(item) )/* we dont remove it from the three due to inheritance */
+ if( !libconfig->setting_get_bool(item) )/* we dont remove it from the three due to inheritance */
--disabled_items_count;
}
/* all ok, process */
CREATE( zone->disabled_items, int, disabled_items_count );
- for(h = 0, v = 0; h < config_setting_length(items); h++) {
- config_setting_t *item = config_setting_get_elem(items, h);
+ for(h = 0, v = 0; h < libconfig->setting_length(items); h++) {
+ config_setting_t *item = libconfig->setting_get_elem(items, h);
- if( config_setting_get_bool(item) ) { /* only add if enabled */
+ if( libconfig->setting_get_bool(item) ) { /* only add if enabled */
name = config_setting_name(item);
zone->disabled_items[v++] = map->zone_str2itemid(name);
}
@@ -4672,14 +4821,14 @@ void read_map_zone_db(void) {
zone->disabled_items_count = disabled_items_count;
}
- if( (mapflags = config_setting_get_member(zone_e, "mapflags")) != NULL ) {
- mapflags_count = config_setting_length(mapflags);
+ if( (mapflags = libconfig->setting_get_member(zone_e, "mapflags")) != NULL ) {
+ mapflags_count = libconfig->setting_length(mapflags);
/* mapflags are not validated here, so we save all anyway */
CREATE( zone->mapflags, char *, mapflags_count );
for(h = 0; h < mapflags_count; h++) {
CREATE( zone->mapflags[h], char, MAP_ZONE_MAPFLAG_LENGTH );
- name = config_setting_get_string_elem(mapflags, h);
+ name = libconfig->setting_get_string_elem(mapflags, h);
safestrncpy(zone->mapflags[h], name, MAP_ZONE_MAPFLAG_LENGTH);
@@ -4687,31 +4836,31 @@ void read_map_zone_db(void) {
zone->mapflags_count = mapflags_count;
}
- if( (commands = config_setting_get_member(zone_e, "disabled_commands")) != NULL ) {
- disabled_commands_count = config_setting_length(commands);
+ if( (commands = libconfig->setting_get_member(zone_e, "disabled_commands")) != NULL ) {
+ disabled_commands_count = libconfig->setting_length(commands);
/* validate */
- for(h = 0; h < config_setting_length(commands); h++) {
- config_setting_t *command = config_setting_get_elem(commands, h);
+ for(h = 0; h < libconfig->setting_length(commands); h++) {
+ config_setting_t *command = libconfig->setting_get_elem(commands, h);
name = config_setting_name(command);
if( !atcommand->exists(name) ) {
ShowError("map_zone_db: unknown command '%s' in disabled_commands for zone '%s', skipping entry...\n",name,zone->name);
- config_setting_remove_elem(commands,h);
+ libconfig->setting_remove_elem(commands,h);
--disabled_commands_count;
--h;
continue;
}
- if( !config_setting_get_int(command) )/* we dont remove it from the three due to inheritance */
+ if( !libconfig->setting_get_int(command) )/* we dont remove it from the three due to inheritance */
--disabled_commands_count;
}
/* all ok, process */
CREATE( zone->disabled_commands, struct map_zone_disabled_command_entry *, disabled_commands_count );
- for(h = 0, v = 0; h < config_setting_length(commands); h++) {
- config_setting_t *command = config_setting_get_elem(commands, h);
+ for(h = 0, v = 0; h < libconfig->setting_length(commands); h++) {
+ config_setting_t *command = libconfig->setting_get_elem(commands, h);
struct map_zone_disabled_command_entry * entry;
int group_lv;
name = config_setting_name(command);
- if( (group_lv = config_setting_get_int(command)) ) { /* only add if enabled */
+ if( (group_lv = libconfig->setting_get_int(command)) ) { /* only add if enabled */
CREATE( entry, struct map_zone_disabled_command_entry, 1 );
entry->cmd = atcommand->exists(name)->func;
@@ -4723,35 +4872,35 @@ void read_map_zone_db(void) {
zone->disabled_commands_count = disabled_commands_count;
}
- if( (caps = config_setting_get_member(zone_e, "skill_damage_cap")) != NULL ) {
- capped_skills_count = config_setting_length(caps);
+ if( (caps = libconfig->setting_get_member(zone_e, "skill_damage_cap")) != NULL ) {
+ capped_skills_count = libconfig->setting_length(caps);
/* validate */
- for(h = 0; h < config_setting_length(caps); h++) {
- config_setting_t *cap = config_setting_get_elem(caps, h);
+ for(h = 0; h < libconfig->setting_length(caps); h++) {
+ config_setting_t *cap = libconfig->setting_get_elem(caps, h);
name = config_setting_name(cap);
if( !map->zone_str2skillid(name) ) {
ShowError("map_zone_db: unknown skill (%s) in skill_damage_cap for zone '%s', skipping skill...\n",name,zone->name);
- config_setting_remove_elem(caps,h);
+ libconfig->setting_remove_elem(caps,h);
--capped_skills_count;
--h;
continue;
}
- if( !map->zone_bl_type(config_setting_get_string_elem(cap,1),&subtype) )/* we dont remove it from the three due to inheritance */
+ if( !map->zone_bl_type(libconfig->setting_get_string_elem(cap,1),&subtype) )/* we dont remove it from the three due to inheritance */
--capped_skills_count;
}
/* all ok, process */
CREATE( zone->capped_skills, struct map_zone_skill_damage_cap_entry *, capped_skills_count );
- for(h = 0, v = 0; h < config_setting_length(caps); h++) {
- config_setting_t *cap = config_setting_get_elem(caps, h);
+ for(h = 0, v = 0; h < libconfig->setting_length(caps); h++) {
+ config_setting_t *cap = libconfig->setting_get_elem(caps, h);
struct map_zone_skill_damage_cap_entry * entry;
enum bl_type type;
name = config_setting_name(cap);
- if( (type = map->zone_bl_type(config_setting_get_string_elem(cap,1),&subtype)) ) { /* only add if enabled */
+ if( (type = map->zone_bl_type(libconfig->setting_get_string_elem(cap,1),&subtype)) ) { /* only add if enabled */
CREATE( entry, struct map_zone_skill_damage_cap_entry, 1 );
entry->nameid = map->zone_str2skillid(name);
- entry->cap = config_setting_get_int_elem(cap,0);
+ entry->cap = libconfig->setting_get_int_elem(cap,0);
entry->type = type;
entry->subtype = subtype;
zone->capped_skills[v++] = entry;
@@ -4771,24 +4920,24 @@ void read_map_zone_db(void) {
config_setting_t *new_entry = NULL;
int inherit_count;
- zone_e = config_setting_get_elem(zones, i);
- config_setting_lookup_string(zone_e, "name", &zonename);
+ zone_e = libconfig->setting_get_elem(zones, i);
+ libconfig->setting_lookup_string(zone_e, "name", &zonename);
if( strncmpi(zonename,MAP_ZONE_ALL_NAME,MAP_ZONE_NAME_LENGTH) == 0 ) {
continue;/* all zone doesn't inherit anything (if it did, everything would link to each other and boom endless loop) */
}
- if( (inherit_tree = config_setting_get_member(zone_e, "inherit")) != NULL ) {
+ if( (inherit_tree = libconfig->setting_get_member(zone_e, "inherit")) != NULL ) {
/* append global zone to this */
- new_entry = config_setting_add(inherit_tree,MAP_ZONE_ALL_NAME,CONFIG_TYPE_STRING);
- config_setting_set_string(new_entry,MAP_ZONE_ALL_NAME);
+ new_entry = libconfig->setting_add(inherit_tree,MAP_ZONE_ALL_NAME,CONFIG_TYPE_STRING);
+ libconfig->setting_set_string(new_entry,MAP_ZONE_ALL_NAME);
} else {
/* create inherit member and add global zone to it */
- inherit_tree = config_setting_add(zone_e, "inherit",CONFIG_TYPE_ARRAY);
- new_entry = config_setting_add(inherit_tree,MAP_ZONE_ALL_NAME,CONFIG_TYPE_STRING);
- config_setting_set_string(new_entry,MAP_ZONE_ALL_NAME);
+ inherit_tree = libconfig->setting_add(zone_e, "inherit",CONFIG_TYPE_ARRAY);
+ new_entry = libconfig->setting_add(inherit_tree,MAP_ZONE_ALL_NAME,CONFIG_TYPE_STRING);
+ libconfig->setting_set_string(new_entry,MAP_ZONE_ALL_NAME);
}
- inherit_count = config_setting_length(inherit_tree);
+ inherit_count = libconfig->setting_length(inherit_tree);
for(h = 0; h < inherit_count; h++) {
struct map_zone_data *izone; /* inherit zone */
int disabled_skills_count_i = 0; /* disabled skill count from inherit zone */
@@ -4798,8 +4947,8 @@ void read_map_zone_db(void) {
int capped_skills_count_i = 0; /* skill capped count from inherit zone */
int j;
- name = config_setting_get_string_elem(inherit_tree, h);
- config_setting_lookup_string(zone_e, "name", &zonename);/* will succeed for we validated it earlier */
+ name = libconfig->setting_get_string_elem(inherit_tree, h);
+ libconfig->setting_lookup_string(zone_e, "name", &zonename);/* will succeed for we validated it earlier */
if( !(izone = strdb_get(map->zone_db, name)) ) {
ShowError("map_zone_db: Unknown zone '%s' being inherit by zone '%s', skipping...\n",name,zonename);
@@ -4821,13 +4970,13 @@ void read_map_zone_db(void) {
/* process everything to override, paying attention to config_setting_get_bool */
if( disabled_skills_count_i ) {
- if( (skills = config_setting_get_member(zone_e, "disabled_skills")) == NULL )
- skills = config_setting_add(zone_e, "disabled_skills",CONFIG_TYPE_GROUP);
- disabled_skills_count = config_setting_length(skills);
+ if( (skills = libconfig->setting_get_member(zone_e, "disabled_skills")) == NULL )
+ skills = libconfig->setting_add(zone_e, "disabled_skills",CONFIG_TYPE_GROUP);
+ disabled_skills_count = libconfig->setting_length(skills);
for(j = 0; j < disabled_skills_count_i; j++) {
int k;
for(k = 0; k < disabled_skills_count; k++) {
- config_setting_t *skillinfo = config_setting_get_elem(skills, k);
+ config_setting_t *skillinfo = libconfig->setting_get_elem(skills, k);
if( map->zone_str2skillid(config_setting_name(skillinfo)) == izone->disabled_skills[j]->nameid ) {
break;
}
@@ -4844,18 +4993,18 @@ void read_map_zone_db(void) {
}
if( disabled_items_count_i ) {
- if( (items = config_setting_get_member(zone_e, "disabled_items")) == NULL )
- items = config_setting_add(zone_e, "disabled_items",CONFIG_TYPE_GROUP);
- disabled_items_count = config_setting_length(items);
+ if( (items = libconfig->setting_get_member(zone_e, "disabled_items")) == NULL )
+ items = libconfig->setting_add(zone_e, "disabled_items",CONFIG_TYPE_GROUP);
+ disabled_items_count = libconfig->setting_length(items);
for(j = 0; j < disabled_items_count_i; j++) {
int k;
for(k = 0; k < disabled_items_count; k++) {
- config_setting_t *item = config_setting_get_elem(items, k);
+ config_setting_t *item = libconfig->setting_get_elem(items, k);
name = config_setting_name(item);
if( map->zone_str2itemid(name) == izone->disabled_items[j] ) {
- if( config_setting_get_bool(item) )
+ if( libconfig->setting_get_bool(item) )
continue;
break;
}
@@ -4868,13 +5017,13 @@ void read_map_zone_db(void) {
}
if( mapflags_count_i ) {
- if( (mapflags = config_setting_get_member(zone_e, "mapflags")) == NULL )
- mapflags = config_setting_add(zone_e, "mapflags",CONFIG_TYPE_ARRAY);
- mapflags_count = config_setting_length(mapflags);
+ if( (mapflags = libconfig->setting_get_member(zone_e, "mapflags")) == NULL )
+ mapflags = libconfig->setting_add(zone_e, "mapflags",CONFIG_TYPE_ARRAY);
+ mapflags_count = libconfig->setting_length(mapflags);
for(j = 0; j < mapflags_count_i; j++) {
int k;
for(k = 0; k < mapflags_count; k++) {
- name = config_setting_get_string_elem(mapflags, k);
+ name = libconfig->setting_get_string_elem(mapflags, k);
if( strcmpi(name,izone->mapflags[j]) == 0 ) {
break;
@@ -4889,14 +5038,14 @@ void read_map_zone_db(void) {
}
if( disabled_commands_count_i ) {
- if( (commands = config_setting_get_member(zone_e, "disabled_commands")) == NULL )
- commands = config_setting_add(zone_e, "disabled_commands",CONFIG_TYPE_GROUP);
+ if( (commands = libconfig->setting_get_member(zone_e, "disabled_commands")) == NULL )
+ commands = libconfig->setting_add(zone_e, "disabled_commands",CONFIG_TYPE_GROUP);
- disabled_commands_count = config_setting_length(commands);
+ disabled_commands_count = libconfig->setting_length(commands);
for(j = 0; j < disabled_commands_count_i; j++) {
int k;
for(k = 0; k < disabled_commands_count; k++) {
- config_setting_t *command = config_setting_get_elem(commands, k);
+ config_setting_t *command = libconfig->setting_get_elem(commands, k);
if( atcommand->exists(config_setting_name(command))->func == izone->disabled_commands[j]->cmd ) {
break;
}
@@ -4913,14 +5062,14 @@ void read_map_zone_db(void) {
}
if( capped_skills_count_i ) {
- if( (caps = config_setting_get_member(zone_e, "skill_damage_cap")) == NULL )
- caps = config_setting_add(zone_e, "skill_damage_cap",CONFIG_TYPE_GROUP);
+ if( (caps = libconfig->setting_get_member(zone_e, "skill_damage_cap")) == NULL )
+ caps = libconfig->setting_add(zone_e, "skill_damage_cap",CONFIG_TYPE_GROUP);
- capped_skills_count = config_setting_length(caps);
+ capped_skills_count = libconfig->setting_length(caps);
for(j = 0; j < capped_skills_count_i; j++) {
int k;
for(k = 0; k < capped_skills_count; k++) {
- config_setting_t *cap = config_setting_get_elem(caps, k);
+ config_setting_t *cap = libconfig->setting_get_elem(caps, k);
if( map->zone_str2skillid(config_setting_name(cap)) == izone->capped_skills[j]->nameid ) {
break;
}
@@ -4942,8 +5091,52 @@ void read_map_zone_db(void) {
ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' zones in '"CL_WHITE"%s"CL_RESET"'.\n", zone_count, config_filename);
/* not supposed to go in here but in skill_final whatever */
- config_destroy(&map_zone_db);
+ libconfig->destroy(&map_zone_db);
+
+ /* post-load processing */
+ if( (zone = strdb_get(map->zone_db, MAP_ZONE_PVP_NAME)) )
+ zone->info.special = 1;
+ if( (zone = strdb_get(map->zone_db, MAP_ZONE_GVG_NAME)) )
+ zone->info.special = 1;
+ if( (zone = strdb_get(map->zone_db, MAP_ZONE_BG_NAME)) )
+ zone->info.special = 1;
+ }
+}
+
+int map_get_new_bonus_id (void) {
+ return map->bonus_id++;
+}
+
+void map_add_questinfo(int m, struct questinfo *qi) {
+ unsigned short i;
+
+ /* duplicate, override */
+ for(i = 0; i < map->list[m].qi_count; i++) {
+ if( map->list[m].qi_data[i].nd == qi->nd )
+ break;
+ }
+
+ if( i == map->list[m].qi_count )
+ RECREATE(map->list[m].qi_data, struct questinfo, ++map->list[m].qi_count);
+
+ memcpy(&map->list[m].qi_data[i], qi, sizeof(struct questinfo));
+}
+
+bool map_remove_questinfo(int m, struct npc_data *nd) {
+ unsigned short i;
+
+ 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;
+ }
}
+
+ return false;
}
/**
@@ -5047,7 +5240,7 @@ void do_final(void)
map->id_db->foreach(map->id_db,map->cleanup_db_sub);
chrif->char_reset_offline();
- chrif->flush_fifo();
+ chrif->flush();
atcommand->final();
battle->final();
@@ -5055,6 +5248,7 @@ void do_final(void)
ircbot->final();/* before clif. */
clif->final();
npc->final();
+ quest->final();
script->final();
itemdb->final();
instance->final();
@@ -5075,9 +5269,11 @@ void do_final(void)
map->list_final();
vending->final();
+ HPM_map_do_final();
+
map->map_db->destroy(map->map_db, map->db_final);
- mapindex_final();
+ mapindex->final();
if(map->enable_grf)
grfio_final();
@@ -5092,9 +5288,16 @@ void do_final(void)
map->sql_close();
ers_destroy(map->iterator_ers);
+ ers_destroy(map->flooritem_ers);
aFree(map->list);
+ if( map->block_free )
+ aFree(map->block_free);
+ if( map->bl_list )
+ aFree(map->bl_list);
+
+
if( !map->enable_grf )
aFree(map->cache_buffer);
@@ -5130,7 +5333,7 @@ void do_abort(void)
}
ShowError("Server received crash signal! Attempting to save all online characters!\n");
map->foreachpc(map->abort_sub);
- chrif->flush_fifo();
+ chrif->flush();
}
/*======================================================
@@ -5141,17 +5344,19 @@ void map_helpscreen(bool do_exit)
ShowInfo("Usage: %s [options]\n", SERVER_NAME);
ShowInfo("\n");
ShowInfo("Options:\n");
- ShowInfo(" -?, -h [--help]\t\tDisplays this help screen.\n");
- ShowInfo(" -v [--version]\t\tDisplays the server's version.\n");
- ShowInfo(" --run-once\t\t\tCloses server after loading (testing).\n");
- ShowInfo(" --map-config <file>\t\tAlternative map-server configuration.\n");
- ShowInfo(" --battle-config <file>\tAlternative battle configuration.\n");
- ShowInfo(" --atcommand-config <file>\tAlternative atcommand configuration.\n");
- ShowInfo(" --script-config <file>\tAlternative script configuration.\n");
- ShowInfo(" --msg-config <file>\t\tAlternative message configuration.\n");
- ShowInfo(" --grf-path <file>\t\tAlternative GRF path configuration.\n");
- ShowInfo(" --inter-config <file>\t\tAlternative inter-server configuration.\n");
- ShowInfo(" --log-config <file>\t\tAlternative logging configuration.\n");
+ ShowInfo(" -?, -h [--help] Displays this help screen.\n");
+ ShowInfo(" -v [--version] Displays the server's version.\n");
+ ShowInfo(" --run-once Closes server after loading (testing).\n");
+ ShowInfo(" --map-config <file> Alternative map-server configuration.\n");
+ ShowInfo(" --battle-config <file> Alternative battle configuration.\n");
+ ShowInfo(" --atcommand-config <file> Alternative atcommand configuration.\n");
+ ShowInfo(" --script-config <file> Alternative script configuration.\n");
+ ShowInfo(" --msg-config <file> Alternative message configuration.\n");
+ ShowInfo(" --grf-path <file> Alternative GRF path configuration.\n");
+ ShowInfo(" --inter-config <file> Alternative inter-server configuration.\n");
+ ShowInfo(" --log-config <file> Alternative logging configuration.\n");
+ ShowInfo(" --script-check <file> Tests a script for errors, without running the server.\n");
+ HPM->arg_help();/* display help for commands implemented thru HPM */
if( do_exit )
exit(EXIT_SUCCESS);
}
@@ -5194,10 +5399,11 @@ void do_shutdown(void)
}
}
-bool map_arg_next_value(const char* option, int i, int argc)
+bool map_arg_next_value(const char* option, int i, int argc, bool must)
{
if( i >= argc-1 ) {
- ShowWarning("Missing value for option '%s'.\n", option);
+ if( must )
+ ShowWarning("Missing value for option '%s'.\n", option);
return false;
}
@@ -5234,13 +5440,15 @@ CPCMD(gm_use) {
ShowError("gm:use invalid syntax. use '"CL_WHITE"gm:use @command <optional params>"CL_RESET"'\n");
return;
}
- map->cpsd->fd = -2;
- if( !atcommand->parse(map->cpsd->fd, map->cpsd, line, 0) )
+
+ map->cpsd_active = true;
+
+ if( !atcommand->exec(map->cpsd->fd, map->cpsd, line, false) )
ShowInfo("HCP: '"CL_WHITE"%s"CL_RESET"' failed\n",line);
else
ShowInfo("HCP: '"CL_WHITE"%s"CL_RESET"' was used\n",line);
- map->cpsd->fd = 0;
-
+
+ map->cpsd_active = false;
}
/* Hercules Console Parser */
void map_cp_defaults(void) {
@@ -5279,6 +5487,7 @@ void map_hp_symbols(void) {
HPM->share(skill,"skill");
HPM->share(vending,"vending");
HPM->share(pc,"pc");
+ HPM->share(pcg,"pc_groups");
HPM->share(party,"party");
HPM->share(storage,"storage");
HPM->share(trade,"trade");
@@ -5297,22 +5506,22 @@ void map_hp_symbols(void) {
HPM->share(quest,"quest");
#ifdef PCRE_SUPPORT
HPM->share(npc_chat,"npc_chat");
+ HPM->share(libpcre,"libpcre");
#endif
- /* partial */
HPM->share(mapit,"mapit");
+ HPM->share(mapindex,"mapindex");
/* sql link */
HPM->share(map->mysql_handle,"sql_handle");
/* specific */
HPM->share(atcommand->create,"addCommand");
HPM->share(script->addScript,"addScript");
- HPM->share(HPM_map_addToMSD,"addToMSD");
- HPM->share(HPM_map_getFromMSD,"getFromMSD");
- HPM->share(HPM_map_removeFromMSD,"removeFromMSD");
- /* vars */
- HPM->share(map->list,"map->list");
+ HPM->share(HPM_map_add_group_permission,"addGroupPermission");
}
void map_load_defaults(void) {
+ mapindex_defaults();
+ map_defaults();
+ /* */
atcommand_defaults();
battle_defaults();
battleground_defaults();
@@ -5333,6 +5542,7 @@ void map_load_defaults(void) {
skill_defaults();
vending_defaults();
pc_defaults();
+ pc_groups_defaults();
party_defaults();
storage_defaults();
trade_defaults();
@@ -5354,22 +5564,33 @@ void map_load_defaults(void) {
}
int do_init(int argc, char *argv[])
{
+ bool minimal = false;
+ char *scriptcheck = NULL;
int i;
#ifdef GCOLLECT
GC_enable_incremental();
#endif
+
+ map_load_defaults();
- map_defaults();
-
- rnd_init();
-
+ HPM_map_do_init();
+ HPM->DataCheck = HPM_map_DataCheck;
+ HPM->load_sub = HPM_map_plugin_load_sub;
+ HPM->symbol_defaults_sub = map_hp_symbols;
+ HPM->grabHPDataSub = HPM_map_grabHPData;
+ HPM->config_read();
+
+ HPM->event(HPET_PRE_INIT);
+
for( i = 1; i < argc ; i++ ) {
const char* arg = argv[i];
if( arg[0] != '-' && ( arg[0] != '/' || arg[1] == '-' ) ) {// -, -- and /
ShowError("Unknown option '%s'.\n", argv[i]);
exit(EXIT_FAILURE);
+ } else if ( HPM->parse_arg(arg,&i,argv,map->arg_next_value(arg, i, argc, false)) ) {
+ continue; /* HPM Triggered */
} else if( (++arg)[0] == '-' ) {// long option
arg++;
@@ -5378,31 +5599,36 @@ int do_init(int argc, char *argv[])
} else if( strcmp(arg, "version") == 0 ) {
map->versionscreen(true);
} else if( strcmp(arg, "map-config") == 0 ) {
- if( map->arg_next_value(arg, i, argc) )
+ if( map->arg_next_value(arg, i, argc, true) )
map->MAP_CONF_NAME = argv[++i];
} else if( strcmp(arg, "battle-config") == 0 ) {
- if( map->arg_next_value(arg, i, argc) )
+ if( map->arg_next_value(arg, i, argc, true) )
map->BATTLE_CONF_FILENAME = argv[++i];
} else if( strcmp(arg, "atcommand-config") == 0 ) {
- if( map->arg_next_value(arg, i, argc) )
+ if( map->arg_next_value(arg, i, argc, true) )
map->ATCOMMAND_CONF_FILENAME = argv[++i];
} else if( strcmp(arg, "script-config") == 0 ) {
- if( map->arg_next_value(arg, i, argc) )
+ if( map->arg_next_value(arg, i, argc, true) )
map->SCRIPT_CONF_NAME = argv[++i];
} else if( strcmp(arg, "msg-config") == 0 ) {
- if( map->arg_next_value(arg, i, argc) )
+ if( map->arg_next_value(arg, i, argc, true) )
map->MSG_CONF_NAME = argv[++i];
} else if( strcmp(arg, "grf-path-file") == 0 ) {
- if( map->arg_next_value(arg, i, argc) )
+ if( map->arg_next_value(arg, i, argc, true) )
map->GRF_PATH_FILENAME = argv[++i];
} else if( strcmp(arg, "inter-config") == 0 ) {
- if( map->arg_next_value(arg, i, argc) )
+ if( map->arg_next_value(arg, i, argc, true) )
map->INTER_CONF_NAME = argv[++i];
} else if( strcmp(arg, "log-config") == 0 ) {
- if( map->arg_next_value(arg, i, argc) )
+ if( map->arg_next_value(arg, i, argc, true) )
map->LOG_CONF_NAME = argv[++i];
} else if( strcmp(arg, "run-once") == 0 ) { // close the map-server as soon as its done.. for testing [Celest]
runflag = CORE_ST_STOP;
+ } else if( strcmp(arg, "script-check") == 0 ) {
+ map->minimal = true;
+ runflag = CORE_ST_STOP;
+ if( map->arg_next_value(arg, i, argc, true) )
+ scriptcheck = argv[++i];
} else {
ShowError("Unknown option '%s'.\n", argv[i]);
exit(EXIT_FAILURE);
@@ -5422,41 +5648,43 @@ int do_init(int argc, char *argv[])
}
}
}
+ 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_load_defaults();
- 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);
- // loads npcs
- map->reloadnpc(false);
+ // loads npcs
+ map->reloadnpc(false);
- chrif->checkdefaultlogin();
+ chrif->checkdefaultlogin();
- if (!map->ip_set || !map->char_ip_set) {
- char ip_str[16];
- ip2str(addr_[0], ip_str);
+ if (!map->ip_set || !map->char_ip_set) {
+ char ip_str[16];
+ ip2str(sockt->addr_[0], ip_str);
- ShowWarning("Not all IP addresses in /conf/map-server.conf configured, autodetecting...\n");
+ ShowWarning("Not all IP addresses in /conf/map-server.conf configured, autodetecting...\n");
- if (naddr_ == 0)
- ShowError("Unable to determine your IP address...\n");
- else if (naddr_ > 1)
- ShowNotice("Multiple interfaces detected...\n");
+ if (sockt->naddr_ == 0)
+ ShowError("Unable to determine your IP address...\n");
+ else if (sockt->naddr_ > 1)
+ ShowNotice("Multiple interfaces detected...\n");
- ShowInfo("Defaulting to %s as our IP address\n", ip_str);
+ ShowInfo("Defaulting to %s as our IP address\n", ip_str);
- if (!map->ip_set)
- clif->setip(ip_str);
- if (!map->char_ip_set)
- chrif->setip(ip_str);
- }
+ if (!map->ip_set)
+ clif->setip(ip_str);
+ if (!map->char_ip_set)
+ chrif->setip(ip_str);
+ }
- battle->config_read(map->BATTLE_CONF_FILENAME);
- atcommand->msg_read(map->MSG_CONF_NAME);
+ battle->config_read(map->BATTLE_CONF_FILENAME);
+ atcommand->msg_read(map->MSG_CONF_NAME);
+ map->inter_config_read(map->INTER_CONF_NAME);
+ logs->config_read(map->LOG_CONF_NAME);
+ }
script->config_read(map->SCRIPT_CONF_NAME);
- map->inter_config_read(map->INTER_CONF_NAME);
- logs->config_read(map->LOG_CONF_NAME);
map->id_db = idb_alloc(DB_OPT_BASE);
map->pc_db = idb_alloc(DB_OPT_BASE); //Added for reliable map->id2sd() use. [Skotlex]
@@ -5469,57 +5697,88 @@ int do_init(int argc, char *argv[])
map->iwall_db = strdb_alloc(DB_OPT_RELEASE_DATA,2*NAME_LENGTH+2+1); // [Zephyrus] Invisible Walls
map->zone_db = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, MAP_ZONE_NAME_LENGTH);
- map->iterator_ers = ers_new(sizeof(struct s_mapiterator),"map.c::map_iterator_ers",ERS_OPT_NONE);
+ map->iterator_ers = ers_new(sizeof(struct s_mapiterator),"map.c::map_iterator_ers",ERS_OPT_CLEAN|ERS_OPT_FLEX_CHUNK);
+ ers_chunk_size(map->iterator_ers, 25);
- map->sql_init();
- if (logs->config.sql_logs)
- logs->sql_init();
+ map->flooritem_ers = ers_new(sizeof(struct flooritem_data),"map.c::map_flooritem_ers",ERS_OPT_CLEAN|ERS_OPT_FLEX_CHUNK);
+ ers_chunk_size(map->flooritem_ers, 100);
+
+ if (!minimal) {
+ map->sql_init();
+ if (logs->config.sql_logs)
+ logs->sql_init();
+ }
+
+ i = mapindex->init();
+
+ if (minimal) {
+ // Pretend all maps from the mapindex are on this mapserver
+ CREATE(map->list,struct map_data,i);
+
+ for( i = 0; i < MAX_MAPINDEX; i++ ) {
+ if (mapindex_exists(i)) {
+ map->addmap(mapindex_id2name(i));
+ }
+ }
+ }
- mapindex_init();
if(map->enable_grf)
grfio_init(map->GRF_PATH_FILENAME);
map->readallmaps();
- timer->add_func_list(map->freeblock_timer, "map_freeblock_timer");
- timer->add_func_list(map->clearflooritem_timer, "map_clearflooritem_timer");
- timer->add_func_list(map->removemobs_timer, "map_removemobs_timer");
- timer->add_interval(timer->gettick()+1000, map->freeblock_timer, 0, 0, 60*1000);
- HPM->load_sub = HPM_map_plugin_load_sub;
- HPM->symbol_defaults_sub = map_hp_symbols;
- HPM->config_read();
- HPM->event(HPET_INIT);
-
- atcommand->init();
- battle->init();
- instance->init();
- chrif->init();
- clif->init();
- ircbot->init();
- script->init();
- itemdb->init();
- skill->init();
- map->read_zone_db();/* read after item and skill initalization */
- mob->init();
- pc->init();
- status->init();
- party->init();
- guild->init();
- gstorage->init();
- pet->init();
- homun->init();
- mercenary->init();
- elemental->init();
- quest->init();
- npc->init();
- unit->init();
- bg->init();
- duel->init();
- vending->init();
+ if (!minimal) {
+ timer->add_func_list(map->freeblock_timer, "map_freeblock_timer");
+ timer->add_func_list(map->clearflooritem_timer, "map_clearflooritem_timer");
+ timer->add_func_list(map->removemobs_timer, "map_removemobs_timer");
+ timer->add_interval(timer->gettick()+1000, map->freeblock_timer, 0, 0, 60*1000);
+
+ HPM->event(HPET_INIT);
+ }
+
+ atcommand->init(minimal);
+ battle->init(minimal);
+ instance->init(minimal);
+ chrif->init(minimal);
+ clif->init(minimal);
+ ircbot->init(minimal);
+ script->init(minimal);
+ itemdb->init(minimal);
+ skill->init(minimal);
+ if (!minimal)
+ map->read_zone_db();/* read after item and skill initalization */
+ mob->init(minimal);
+ pc->init(minimal);
+ status->init(minimal);
+ party->init(minimal);
+ guild->init(minimal);
+ gstorage->init(minimal);
+ pet->init(minimal);
+ homun->init(minimal);
+ mercenary->init(minimal);
+ elemental->init(minimal);
+ quest->init(minimal);
+ npc->init(minimal);
+ unit->init(minimal);
+ bg->init(minimal);
+ duel->init(minimal);
+ vending->init(minimal);
+
+ if (scriptcheck) {
+ if (npc->parsesrcfile(scriptcheck, false) == 0)
+ exit(EXIT_SUCCESS);
+ exit(EXIT_FAILURE);
+ }
+ if( minimal ) {
+ HPM->event(HPET_READY);
+ exit(EXIT_SUCCESS);
+ }
+
npc->event_do_oninit(); // Init npcs (OnInit)
-
+ npc->market_fromsql(); /* after OnInit */
+
if (battle_config.pk_mode)
ShowNotice("Server is running on '"CL_WHITE"PK Mode"CL_RESET"'.\n");
@@ -5552,6 +5811,7 @@ void map_defaults(void) {
map = &map_s;
/* */
+ map->minimal = false;
map->count = 0;
sprintf(map->db_path ,"db");
@@ -5599,6 +5859,8 @@ void map_defaults(void) {
sprintf(map->server_db,"ragnarok");
map->mysql_handle = NULL;
+ map->cpsd_active = false;
+
map->port = 0;
map->users = 0;
map->ip_set = 0;
@@ -5618,22 +5880,29 @@ void map_defaults(void) {
map->zone_db = NULL;
map->iwall_db = NULL;
+ map->block_free = NULL;
+ map->block_free_count = 0;
+ map->block_free_lock = 0;
+ map->block_free_list_size = 0;
+ map->bl_list = NULL;
+ map->bl_list_count = 0;
+ map->bl_list_size = 0;
+
//all in a big chunk, respects order
- memset(map->block_free,0,sizeof(map->block_free)
- + sizeof(map->block_free_count)
- + sizeof(map->block_free_lock)
- + sizeof(map->bl_list)
- + sizeof(map->bl_list_count)
- + sizeof(map->bl_head)
+ memset(&map->bl_head,0,sizeof(map->bl_head)
+ sizeof(map->zone_all)
+ sizeof(map->zone_pk)
);
-
+
map->cpsd = NULL;
map->list = NULL;
map->iterator_ers = NULL;
map->cache_buffer = NULL;
+
+ map->flooritem_ers = NULL;
+ /* */
+ map->bonus_id = SP_LAST_KNOWN;
/* funcs */
map->zone_init = map_zone_init;
map->zone_remove = map_zone_remove;
@@ -5800,7 +6069,14 @@ void map_defaults(void) {
map->addblcell = map_addblcell;
map->delblcell = map_delblcell;
-
+
+ map->get_new_bonus_id = map_get_new_bonus_id;
+
+ map->add_questinfo = map_add_questinfo;
+ map->remove_questinfo = map_remove_questinfo;
+
+ map->merge_zone = map_merge_zone;
+
/**
* mapit interface
**/
@@ -5814,4 +6090,5 @@ void map_defaults(void) {
mapit->next = mapit_next;
mapit->prev = mapit_prev;
mapit->exists = mapit_exists;
+
}