diff options
Diffstat (limited to 'src/map/map.c')
-rw-r--r-- | src/map/map.c | 2009 |
1 files changed, 1745 insertions, 264 deletions
diff --git a/src/map/map.c b/src/map/map.c index a8521de7d..6f61375fe 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -1,9 +1,11 @@ -// Copyright (c) Athena Dev Teams - Licensed under GNU GPL -// For more information, see LICENCE in the main folder +// Copyright (c) Hercules Dev Team, licensed under GNU GPL. +// See the LICENSE file +// Portions Copyright (c) Athena Dev Teams #include "../common/cbasetypes.h" #include "../common/core.h" #include "../common/timer.h" +#include "../common/ers.h" #include "../common/grfio.h" #include "../common/malloc.h" #include "../common/socket.h" // WFIFO*() @@ -12,6 +14,9 @@ #include "../common/random.h" #include "../common/strlib.h" #include "../common/utils.h" +#include "../common/conf.h" +#include "../common/console.h" +#include "../common/HPM.h" #include "map.h" #include "path.h" @@ -45,6 +50,8 @@ #include "atcommand.h" #include "log.h" #include "mail.h" +#include "irc-bot.h" + #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -80,10 +87,6 @@ char log_db_pw[32] = "ragnarok"; char log_db_db[32] = "log"; Sql* logmysql_handle; -// This param using for sending mainchat -// messages like whispers to this nick. [LuzZza] -char main_chat_nick[16] = "Main"; - char *INTER_CONF_NAME; char *LOG_CONF_NAME; char *MAP_CONF_NAME; @@ -114,7 +117,6 @@ static int block_free_count = 0, block_free_lock = 0; static struct block_list *bl_list[BL_LIST_MAX]; static int bl_list_count = 0; -struct map_data map[MAX_MAP_PER_SERVER]; int map_num = 0; int map_port=0; @@ -156,10 +158,12 @@ char charhelp_txt[256] = "conf/charhelp.txt"; char wisp_server_name[NAME_LENGTH] = "Server"; // can be modified in char-server configuration file -int console = 0; int enable_spy = 0; //To enable/disable @spy commands, which consume too much cpu time when sending packets. [Skotlex] int enable_grf = 0; //To enable/disable reading maps from GRF files, bypassing mapcache [blackhole89] +/* [Ind/Hercules] */ +struct eri *map_iterator_ers; + /*========================================== * server player count (of all mapservers) *------------------------------------------*/ @@ -365,7 +369,7 @@ int map_delblock(struct block_list* bl) /*========================================== * Moves a block a x/y target position. [Skotlex] - * Pass flag as 1 to prevent doing skill_unit_move checks + * 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) @@ -385,14 +389,14 @@ int map_moveblock(struct block_list *bl, int x1, int y1, unsigned int tick) if (bl->type&BL_CHAR) { sc = status_get_sc(bl); - skill_unit_move(bl,tick,2); + skill->unit_move(bl,tick,2); status_change_end(bl, SC_CLOSECONFINE, INVALID_TIMER); status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER); // status_change_end(bl, SC_BLADESTOP, INVALID_TIMER); //Won't stop when you are knocked away, go figure... status_change_end(bl, SC_TATAMIGAESHI, INVALID_TIMER); status_change_end(bl, SC_MAGICROD, INVALID_TIMER); if (sc->data[SC_PROPERTYWALK] && - sc->data[SC_PROPERTYWALK]->val3 >= skill_get_maxcount(sc->data[SC_PROPERTYWALK]->val1,sc->data[SC_PROPERTYWALK]->val2) ) + 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); } else if (bl->type == BL_NPC) @@ -411,11 +415,11 @@ int map_moveblock(struct block_list *bl, int x1, int y1, unsigned int tick) if (bl->type&BL_CHAR) { - skill_unit_move(bl,tick,3); + skill->unit_move(bl,tick,3); if( bl->type == BL_PC && ((TBL_PC*)bl)->shadowform_id ) {//Shadow Form Target Moving struct block_list *d_bl; - if( (d_bl = map_id2bl(((TBL_PC*)bl)->shadowform_id)) == NULL || bl->m != d_bl->m || !check_distance_bl(bl,d_bl,10) ) { + if( (d_bl = map_id2bl(((TBL_PC*)bl)->shadowform_id)) == NULL || !check_distance_bl(bl,d_bl,10) ) { if( d_bl ) status_change_end(d_bl,SC__SHADOWFORM,INVALID_TIMER); ((TBL_PC*)bl)->shadowform_id = 0; @@ -424,31 +428,31 @@ int map_moveblock(struct block_list *bl, int x1, int y1, unsigned int tick) if (sc && sc->count) { if (sc->data[SC_DANCING]) - skill_unit_move_unit_group(skill_id2group(sc->data[SC_DANCING]->val2), bl->m, x1-x0, y1-y0); + skill->unit_move_unit_group(skill->id2group(sc->data[SC_DANCING]->val2), bl->m, x1-x0, y1-y0); else { if (sc->data[SC_CLOAKING]) - skill_check_cloaking(bl, sc->data[SC_CLOAKING]); + skill->check_cloaking(bl, sc->data[SC_CLOAKING]); if (sc->data[SC_WARM]) - skill_unit_move_unit_group(skill_id2group(sc->data[SC_WARM]->val4), bl->m, x1-x0, y1-y0); + skill->unit_move_unit_group(skill->id2group(sc->data[SC_WARM]->val4), bl->m, x1-x0, y1-y0); if (sc->data[SC_BANDING]) - skill_unit_move_unit_group(skill_id2group(sc->data[SC_BANDING]->val4), bl->m, x1-x0, y1-y0); + skill->unit_move_unit_group(skill->id2group(sc->data[SC_BANDING]->val4), bl->m, x1-x0, y1-y0); if (sc->data[SC_NEUTRALBARRIER_MASTER]) - skill_unit_move_unit_group(skill_id2group(sc->data[SC_NEUTRALBARRIER_MASTER]->val2), bl->m, x1-x0, y1-y0); + skill->unit_move_unit_group(skill->id2group(sc->data[SC_NEUTRALBARRIER_MASTER]->val2), bl->m, x1-x0, y1-y0); else if (sc->data[SC_STEALTHFIELD_MASTER]) - skill_unit_move_unit_group(skill_id2group(sc->data[SC_STEALTHFIELD_MASTER]->val2), bl->m, x1-x0, y1-y0); + skill->unit_move_unit_group(skill->id2group(sc->data[SC_STEALTHFIELD_MASTER]->val2), bl->m, x1-x0, y1-y0); if( sc->data[SC__SHADOWFORM] ) {//Shadow Form Caster Moving struct block_list *d_bl; - if( (d_bl = map_id2bl(sc->data[SC__SHADOWFORM]->val2)) == NULL || bl->m != d_bl->m || !check_distance_bl(bl,d_bl,10) ) + if( (d_bl = map_id2bl(sc->data[SC__SHADOWFORM]->val2)) == NULL || !check_distance_bl(bl,d_bl,10) ) status_change_end(bl,SC__SHADOWFORM,INVALID_TIMER); } if (sc->data[SC_PROPERTYWALK] - && sc->data[SC_PROPERTYWALK]->val3 < skill_get_maxcount(sc->data[SC_PROPERTYWALK]->val1,sc->data[SC_PROPERTYWALK]->val2) + && sc->data[SC_PROPERTYWALK]->val3 < skill->get_maxcount(sc->data[SC_PROPERTYWALK]->val1,sc->data[SC_PROPERTYWALK]->val2) && map_find_skill_unit_oncell(bl,bl->x,bl->y,SO_ELECTRICWALK,NULL,0) == NULL && map_find_skill_unit_oncell(bl,bl->x,bl->y,SO_FIREWALK,NULL,0) == NULL - && skill_unitsetting(bl,sc->data[SC_PROPERTYWALK]->val1,sc->data[SC_PROPERTYWALK]->val2,x0, y0,0)) { + && skill->unitsetting(bl,sc->data[SC_PROPERTYWALK]->val1,sc->data[SC_PROPERTYWALK]->val2,x0, y0,0)) { sc->data[SC_PROPERTYWALK]->val3++; } @@ -457,13 +461,13 @@ int map_moveblock(struct block_list *bl, int x1, int y1, unsigned int tick) /* Guild Aura Moving */ if( bl->type == BL_PC && ((TBL_PC*)bl)->state.gmaster_flag ) { if (sc->data[SC_LEADERSHIP]) - skill_unit_move_unit_group(skill_id2group(sc->data[SC_LEADERSHIP]->val4), bl->m, x1-x0, y1-y0); + skill->unit_move_unit_group(skill->id2group(sc->data[SC_LEADERSHIP]->val4), bl->m, x1-x0, y1-y0); if (sc->data[SC_GLORYWOUNDS]) - skill_unit_move_unit_group(skill_id2group(sc->data[SC_GLORYWOUNDS]->val4), bl->m, x1-x0, y1-y0); + skill->unit_move_unit_group(skill->id2group(sc->data[SC_GLORYWOUNDS]->val4), bl->m, x1-x0, y1-y0); if (sc->data[SC_SOULCOLD]) - skill_unit_move_unit_group(skill_id2group(sc->data[SC_SOULCOLD]->val4), bl->m, x1-x0, y1-y0); + skill->unit_move_unit_group(skill->id2group(sc->data[SC_SOULCOLD]->val4), bl->m, x1-x0, y1-y0); if (sc->data[SC_HAWKEYES]) - skill_unit_move_unit_group(skill_id2group(sc->data[SC_HAWKEYES]->val4), bl->m, x1-x0, y1-y0); + skill->unit_move_unit_group(skill->id2group(sc->data[SC_HAWKEYES]->val4), bl->m, x1-x0, y1-y0); } } } else @@ -524,7 +528,7 @@ struct skill_unit* map_find_skill_unit_oncell(struct block_list* target,int16 x, unit = (struct skill_unit *) bl; if( unit == out_unit || !unit->alive || !unit->group || unit->group->skill_id != skill_id ) continue; - if( !(flag&1) || battle_check_target(&unit->bl,target,unit->group->target_flag) > 0 ) + if( !(flag&1) || battle->check_target(&unit->bl,target,unit->group->target_flag) > 0 ) return unit; } return NULL; @@ -1280,7 +1284,7 @@ int map_clearflooritem_timer(int tid, unsigned int tick, int id, intptr_t data) if (search_petDB_index(fitem->item_data.nameid, PET_EGG) >= 0) intif_delete_petdata(MakeDWord(fitem->item_data.card[1], fitem->item_data.card[2])); - clif_clearflooritem(fitem, 0); + clif->clearflooritem(fitem, 0); map_deliddb(&fitem->bl); map_delblock(&fitem->bl); map_freeblock(&fitem->bl); @@ -1296,7 +1300,7 @@ void map_clearflooritem(struct block_list *bl) { if( fitem->cleartimer ) delete_timer(fitem->cleartimer,map_clearflooritem_timer); - clif_clearflooritem(fitem, 0); + clif->clearflooritem(fitem, 0); map_deliddb(&fitem->bl); map_delblock(&fitem->bl); map_freeblock(&fitem->bl); @@ -1463,7 +1467,7 @@ int map_addflooritem(struct item *item_data,int amount,int16 m,int16 x,int16 y,i map_addiddb(&fitem->bl); map_addblock(&fitem->bl); - clif_dropflooritem(fitem); + clif->dropflooritem(fitem); return fitem->bl.id; } @@ -1475,7 +1479,7 @@ static DBData create_charid2nick(DBKey key, va_list args) { struct charid2nick *p; CREATE(p, struct charid2nick, 1); - return db_ptr2data(p); + return DB->ptr2data(p); } /// Adds(or replaces) the nick of charid to nick_db and fullfils pending requests. @@ -1492,13 +1496,12 @@ void map_addnickdb(int charid, const char* nick) p = idb_ensure(nick_db, charid, create_charid2nick); safestrncpy(p->nick, nick, sizeof(p->nick)); - while( p->requests ) - { + while( p->requests ) { req = p->requests; p->requests = req->next; sd = map_charid2sd(req->charid); if( sd ) - clif_solved_charname(sd->fd, charid, p->nick); + clif->solved_charname(sd->fd, charid, p->nick); aFree(req); } } @@ -1512,16 +1515,15 @@ void map_delnickdb(int charid, const char* name) struct map_session_data* sd; DBData data; - if (!nick_db->remove(nick_db, db_i2key(charid), &data) || (p = db_data2ptr(&data)) == NULL) + if (!nick_db->remove(nick_db, DB->i2key(charid), &data) || (p = DB->data2ptr(&data)) == NULL) return; - while( p->requests ) - { + while( p->requests ) { req = p->requests; p->requests = req->next; sd = map_charid2sd(req->charid); if( sd ) - clif_solved_charname(sd->fd, charid, name); + clif->solved_charname(sd->fd, charid, name); aFree(req); } aFree(p); @@ -1539,16 +1541,14 @@ void map_reqnickdb(struct map_session_data * sd, int charid) nullpo_retv(sd); tsd = map_charid2sd(charid); - if( tsd ) - { - clif_solved_charname(sd->fd, charid, tsd->status.name); + if( tsd ) { + clif->solved_charname(sd->fd, charid, tsd->status.name); return; } p = idb_ensure(nick_db, charid, create_charid2nick); - if( *p->nick ) - { - clif_solved_charname(sd->fd, charid, p->nick); + if( *p->nick ) { + clif->solved_charname(sd->fd, charid, p->nick); return; } // not in cache, request it @@ -1698,15 +1698,22 @@ 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); } + if( hChSys.local && map[sd->bl.m].channel && idb_exists(map[sd->bl.m].channel->users, sd->status.char_id) ) { + clif->chsys_left(map[sd->bl.m].channel,sd); + } + + clif->chsys_quit(sd); + unit_remove_map_pc(sd,CLR_TELEPORT); - if( map[sd->bl.m].instance_id ) - { // Avoid map conflicts and warnings on next login + if( map[sd->bl.m].instance_id ) { // Avoid map conflicts and warnings on next login int16 m; struct point *pt; if( map[sd->bl.m].save.map ) @@ -1818,7 +1825,7 @@ struct map_session_data * map_nick2sd(const char *nick) iter = mapit_getallusers(); found_sd = NULL; - for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) ) + for( sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); sd = (TBL_PC*)mapit->next(iter) ) { if( battle_config.partial_name_scan ) {// partial name search @@ -1841,7 +1848,7 @@ struct map_session_data * map_nick2sd(const char *nick) break; } } - mapit_free(iter); + mapit->free(iter); if( battle_config.partial_name_scan && qty != 1 ) found_sd = NULL; @@ -1894,8 +1901,7 @@ struct mob_data * map_id2boss(int id) /// Applies func to all the players in the db. /// Stops iterating if func returns -1. -void map_foreachpc(int (*func)(struct map_session_data* sd, va_list args), ...) -{ +void map_map_foreachpc(int (*func)(struct map_session_data* sd, va_list args), ...) { DBIterator* iter; struct map_session_data* sd; @@ -1916,7 +1922,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_foreachmob(int (*func)(struct mob_data* md, va_list args), ...) +void map_map_foreachmob(int (*func)(struct mob_data* md, va_list args), ...) { DBIterator* iter; struct mob_data* md; @@ -1938,7 +1944,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_foreachnpc(int (*func)(struct npc_data* nd, va_list args), ...) +void map_map_foreachnpc(int (*func)(struct npc_data* nd, va_list args), ...) { DBIterator* iter; struct block_list* bl; @@ -1964,7 +1970,7 @@ void map_foreachnpc(int (*func)(struct npc_data* nd, va_list args), ...) /// Applies func to everything in the db. /// Stops iteratin gif func returns -1. -void map_foreachregen(int (*func)(struct block_list* bl, va_list args), ...) +void map_map_foreachregen(int (*func)(struct block_list* bl, va_list args), ...) { DBIterator* iter; struct block_list* bl; @@ -1986,7 +1992,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_foreachiddb(int (*func)(struct block_list* bl, va_list args), ...) +void map_map_foreachiddb(int (*func)(struct block_list* bl, va_list args), ...) { DBIterator* iter; struct block_list* bl; @@ -2037,7 +2043,7 @@ struct s_mapiterator* mapit_alloc(enum e_mapitflags flags, enum bl_type types) { struct s_mapiterator* mapit; - CREATE(mapit, struct s_mapiterator, 1); + mapit = ers_alloc(map_iterator_ers, struct s_mapiterator); mapit->flags = flags; mapit->types = types; if( types == BL_PC ) mapit->dbi = db_iterator(pc_db); @@ -2054,7 +2060,7 @@ void mapit_free(struct s_mapiterator* mapit) nullpo_retv(mapit); dbi_destroy(mapit->dbi); - aFree(mapit); + ers_free(map_iterator_ers, mapit); } /// Returns the first block_list that matches the description. @@ -2308,7 +2314,7 @@ int16 map_mapindex2mapid(unsigned short mapindex) *------------------------------------------*/ int map_mapname2ipport(unsigned short name, uint32* ip, uint16* port) { - struct map_data_other_server *mdos=NULL; + struct map_data_other_server *mdos; mdos = (struct map_data_other_server*)uidb_get(map_db,(unsigned int)name); if(mdos==NULL || mdos->cell) //If gat isn't null, this is a local map. @@ -2633,7 +2639,7 @@ bool map_iwall_set(int16 m, int16 x, int16 y, int size, int8 dir, bool shootable map_setcell(m, x1, y1, CELL_WALKABLE, false); map_setcell(m, x1, y1, CELL_SHOOTABLE, shootable); - clif_changemapcell(0, m, x1, y1, map_getcell(m, x1, y1, CELL_GETTYPE), ALL_SAMEMAP); + clif->changemapcell(0, m, x1, y1, map_getcell(m, x1, y1, CELL_GETTYPE), ALL_SAMEMAP); } iwall->size = i; @@ -2644,8 +2650,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) -{ +void map_iwall_get(struct map_session_data *sd) { struct iwall_data *iwall; DBIterator* iter; int16 x1, y1; @@ -2655,15 +2660,13 @@ void map_iwall_get(struct map_session_data *sd) return; iter = db_iterator(iwall_db); - for( iwall = dbi_first(iter); dbi_exists(iter); iwall = dbi_next(iter) ) - { + for( iwall = dbi_first(iter); dbi_exists(iter); iwall = dbi_next(iter) ) { if( iwall->m != sd->bl.m ) continue; - for( i = 0; i < iwall->size; i++ ) - { + for( i = 0; i < iwall->size; i++ ) { map_iwall_nextxy(iwall->x, iwall->y, iwall->dir, i, &x1, &y1); - clif_changemapcell(sd->fd, iwall->m, x1, y1, map_getcell(iwall->m, x1, y1, CELL_GETTYPE), SELF); + clif->changemapcell(sd->fd, iwall->m, x1, y1, map_getcell(iwall->m, x1, y1, CELL_GETTYPE), SELF); } } dbi_destroy(iter); @@ -2677,14 +2680,13 @@ void map_iwall_remove(const char *wall_name) if( (iwall = (struct iwall_data *)strdb_get(iwall_db, wall_name)) == NULL ) return; // Nothing to do - for( i = 0; i < iwall->size; i++ ) - { + for( i = 0; i < iwall->size; i++ ) { map_iwall_nextxy(iwall->x, iwall->y, iwall->dir, i, &x1, &y1); map_setcell(iwall->m, x1, y1, CELL_SHOOTABLE, true); map_setcell(iwall->m, x1, y1, CELL_WALKABLE, true); - clif_changemapcell(0, iwall->m, x1, y1, map_getcell(iwall->m, x1, y1, CELL_GETTYPE), ALL_SAMEMAP); + clif->changemapcell(0, iwall->m, x1, y1, map_getcell(iwall->m, x1, y1, CELL_GETTYPE), ALL_SAMEMAP); } map[iwall->m].iwall_num--; @@ -2701,7 +2703,7 @@ static DBData create_map_data_other_server(DBKey key, va_list args) 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); - return db_ptr2data(mdos); + return DB->ptr2data(mdos); } /*========================================== @@ -2709,13 +2711,13 @@ static DBData create_map_data_other_server(DBKey key, va_list args) *------------------------------------------*/ int map_setipport(unsigned short mapindex, uint32 ip, uint16 port) { - struct map_data_other_server *mdos=NULL; + struct map_data_other_server *mdos; mdos= uidb_ensure(map_db,(unsigned int)mapindex, 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_getip() && port == clif_getport()) { + 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)); exit(EXIT_FAILURE); @@ -2731,7 +2733,7 @@ int map_setipport(unsigned short mapindex, uint32 ip, uint16 port) */ int map_eraseallipport_sub(DBKey key, DBData *data, va_list va) { - struct map_data_other_server *mdos = db_data2ptr(data); + struct map_data_other_server *mdos = DB->data2ptr(data); if(mdos->cell == NULL) { db_remove(map_db,key); aFree(mdos); @@ -2892,27 +2894,186 @@ int map_delmap(char* mapname) } return 0; } +void map_zone_db_clear(void) { + struct map_zone_data *zone; + int i; + + DBIterator *iter = db_iterator(zone_db); + for(zone = dbi_first(iter); dbi_exists(iter); zone = dbi_next(iter)) { + for(i = 0; i < zone->disabled_skills_count; i++) { + aFree(zone->disabled_skills[i]); + } + aFree(zone->disabled_skills); + aFree(zone->disabled_items); + for(i = 0; i < zone->mapflags_count; i++) { + aFree(zone->mapflags[i]); + } + aFree(zone->mapflags); + for(i = 0; i < zone->disabled_commands_count; i++) { + aFree(zone->disabled_commands[i]); + } + aFree(zone->disabled_commands); + for(i = 0; i < zone->capped_skills_count; i++) { + aFree(zone->capped_skills[i]); + } + aFree(zone->capped_skills); + } + dbi_destroy(iter); + + db_destroy(zone_db);/* will aFree(zone) */ + + /* clear the pk zone stuff */ + for(i = 0; i < map_zone_pk.disabled_skills_count; i++) { + aFree(map_zone_pk.disabled_skills[i]); + } + aFree(map_zone_pk.disabled_skills); + aFree(map_zone_pk.disabled_items); + for(i = 0; i < map_zone_pk.mapflags_count; i++) { + aFree(map_zone_pk.mapflags[i]); + } + aFree(map_zone_pk.mapflags); + for(i = 0; i < map_zone_pk.disabled_commands_count; i++) { + aFree(map_zone_pk.disabled_commands[i]); + } + aFree(map_zone_pk.disabled_commands); + for(i = 0; i < map_zone_pk.capped_skills_count; i++) { + aFree(map_zone_pk.capped_skills[i]); + } + aFree(map_zone_pk.capped_skills); + /* clear the main zone stuff */ + for(i = 0; i < map_zone_all.disabled_skills_count; i++) { + aFree(map_zone_all.disabled_skills[i]); + } + aFree(map_zone_all.disabled_skills); + aFree(map_zone_all.disabled_items); + for(i = 0; i < map_zone_all.mapflags_count; i++) { + aFree(map_zone_all.mapflags[i]); + } + aFree(map_zone_all.mapflags); + for(i = 0; i < map_zone_all.disabled_commands_count; i++) { + aFree(map_zone_all.disabled_commands[i]); + } + aFree(map_zone_all.disabled_commands); + for(i = 0; i < map_zone_all.capped_skills_count; i++) { + aFree(map_zone_all.capped_skills[i]); + } + aFree(map_zone_all.capped_skills); +} + +void do_final_maps(void) { + int i, v = 0; + + for( i = 0; i < map_num; i++ ) { + + if(map[i].cell) aFree(map[i].cell); + if(map[i].block) aFree(map[i].block); + if(map[i].block_mob) aFree(map[i].block_mob); + + if(battle_config.dynamic_mobs) { //Dynamic mobs flag by [random] + int j; + if(map[i].mob_delete_timer != INVALID_TIMER) + delete_timer(map[i].mob_delete_timer, map_removemobs_timer); + for (j=0; j<MAX_MOB_LIST_PER_MAP; j++) + if (map[i].moblist[j]) aFree(map[i].moblist[j]); + } + if( map[i].unit_count ) { + for(v = 0; v < map[i].unit_count; v++) { + aFree(map[i].units[v]); + } + if( map[i].units ) { + aFree(map[i].units); + map[i].units = NULL; + } + map[i].unit_count = 0; + } + + if( map[i].skill_count ) { + for(v = 0; v < map[i].skill_count; v++) { + aFree(map[i].skills[v]); + } + if( map[i].skills ) { + aFree(map[i].skills); + map[i].skills = NULL; + } + map[i].skill_count = 0; + } + + if( map[i].zone_mf_count ) { + for(v = 0; v < map[i].zone_mf_count; v++) { + aFree(map[i].zone_mf[v]); + } + if( map[i].zone_mf ) { + aFree(map[i].zone_mf); + map[i].zone_mf = NULL; + } + map[i].zone_mf_count = 0; + } + + if( map[i].channel ) + clif->chsys_delete(map[i].channel); + } + + map_zone_db_clear(); + +} /// Initializes map flags and adjusts them depending on configuration. -void map_flags_init(void) -{ - int i; +void map_flags_init(void) { + int i, v = 0; - for( i = 0; i < map_num; i++ ) - { + for( i = 0; i < map_num; i++ ) { // mapflags memset(&map[i].flag, 0, sizeof(map[i].flag)); // additional mapflag data - map[i].zone = 0; // restricted mapflag zone map[i].nocommand = 0; // nocommand mapflag level map[i].bexp = 100; // per map base exp multiplicator map[i].jexp = 100; // per map job exp multiplicator memset(map[i].drop_list, 0, sizeof(map[i].drop_list)); // pvp nightmare drop list + if( map[i].unit_count ) { + for(v = 0; v < map[i].unit_count; v++) { + aFree(map[i].units[v]); + } + aFree(map[i].units); + } + map[i].units = NULL; + map[i].unit_count = 0; + + if( map[i].skill_count ) { + for(v = 0; v < map[i].skill_count; v++) { + aFree(map[i].skills[v]); + } + aFree(map[i].skills); + } + map[i].skills = NULL; + map[i].skill_count = 0; + // adjustments - if( battle_config.pk_mode ) + if( battle_config.pk_mode ) { map[i].flag.pvp = 1; // make all maps pvp for pk_mode [Valaris] + map[i].zone = &map_zone_pk; + } else /* align with 'All' zone */ + map[i].zone = &map_zone_all; + + if( map[i].zone_mf_count ) { + for(v = 0; v < map[i].zone_mf_count; v++) { + aFree(map[i].zone_mf[v]); + } + aFree(map[i].zone_mf); + } + + map[i].zone_mf = NULL; + map[i].zone_mf_count = 0; + map[i].prev_zone = map[i].zone; + + map[i].invincible_time_inc = 0; + + map[i].weapon_damage_rate = 100; + map[i].magic_damage_rate = 100; + map[i].misc_damage_rate = 100; + map[i].short_damage_rate = 100; + map[i].long_damage_rate = 100; } } @@ -3006,14 +3167,13 @@ void map_removemapdb(struct map_data *m) /*====================================== * Initiate maps loading stage *--------------------------------------*/ -int map_readallmaps (void) -{ +int map_readallmaps (void) { int i; FILE* fp=NULL; int maps_removed = 0; char *map_cache_buffer = NULL; // Has the uncompressed gat data of all maps, so just one allocation has to be made char map_cache_decode_buffer[MAX_MAP_SIZE]; - + if( enable_grf ) ShowStatus("Loading maps (using GRF files)...\n"); else { @@ -3106,84 +3266,6 @@ static int map_ip_set = 0; static int char_ip_set = 0; /*========================================== - * Console Command Parser [Wizputer] - *------------------------------------------*/ -int parse_console(const char* buf) -{ - char type[64]; - char command[64]; - char map[64]; - int16 x = 0; - int16 y = 0; - int16 m; - int n; - struct map_session_data sd; - - memset(&sd, 0, sizeof(struct map_session_data)); - strcpy(sd.status.name, "console"); - - if( ( n = sscanf(buf, "%63[^:]:%63[^:]:%63s %hd %hd[^\n]", type, command, map, &x, &y) ) < 5 ) - { - if( ( n = sscanf(buf, "%63[^:]:%63[^\n]", type, command) ) < 2 ) - { - n = sscanf(buf, "%63[^\n]", type); - } - } - - if( n == 5 ) - { - m = map_mapname2mapid(map); - if( m < 0 ) - { - ShowWarning("Console: Unknown map.\n"); - return 0; - } - sd.bl.m = m; - map_search_freecell(&sd.bl, m, &sd.bl.x, &sd.bl.y, -1, -1, 0); - if( x > 0 ) - sd.bl.x = x; - if( y > 0 ) - sd.bl.y = y; - } - else - { - map[0] = '\0'; - if( n < 2 ) - command[0] = '\0'; - if( n < 1 ) - type[0] = '\0'; - } - - ShowNotice("Type of command: '%s' || Command: '%s' || Map: '%s' Coords: %d %d\n", type, command, map, x, y); - - if( n == 5 && strcmpi("admin",type) == 0 ) - { - if( !is_atcommand(sd.fd, &sd, command, 0) ) - ShowInfo("Console: not atcommand\n"); - } - else if( n == 2 && strcmpi("server", type) == 0 ) - { - if( strcmpi("shutdown", command) == 0 || strcmpi("exit", command) == 0 || strcmpi("quit", command) == 0 ) - { - runflag = 0; - } - } - else if( strcmpi("help", type) == 0 ) - { - ShowInfo("To use GM commands:\n"); - ShowInfo(" admin:<gm command>:<map of \"gm\"> <x> <y>\n"); - ShowInfo("You can use any GM command that doesn't require the GM.\n"); - ShowInfo("No using @item or @warp however you can use @charwarp\n"); - ShowInfo("The <map of \"gm\"> <x> <y> is for commands that need coords of the GM\n"); - ShowInfo("IE: @spawn\n"); - ShowInfo("To shutdown the server:\n"); - ShowInfo(" server:shutdown\n"); - } - - return 0; -} - -/*========================================== * Read map server configuration files (conf/map_server.conf...) *------------------------------------------*/ int map_config_read(char *cfgName) @@ -3216,7 +3298,7 @@ int map_config_read(char *cfgName) *ptr = '\0'; if(strcmpi(w1,"timestamp_format")==0) - strncpy(timestamp_format, w2, 20); + safestrncpy(timestamp_format, w2, 20); else if(strcmpi(w1,"stdout_with_ansisequence")==0) stdout_with_ansisequence = config_switch(w2); else if(strcmpi(w1,"console_silent")==0) { @@ -3232,11 +3314,11 @@ int map_config_read(char *cfgName) else if (strcmpi(w1, "char_port") == 0) chrif_setport(atoi(w2)); else if (strcmpi(w1, "map_ip") == 0) - map_ip_set = clif_setip(w2); + map_ip_set = clif->setip(w2); else if (strcmpi(w1, "bind_ip") == 0) - clif_setbindip(w2); + clif->setbindip(w2); else if (strcmpi(w1, "map_port") == 0) { - clif_setport(atoi(w2)); + clif->setport(atoi(w2)); map_port = (atoi(w2)); } else if (strcmpi(w1, "map") == 0) map_addmap(w2); @@ -3267,12 +3349,8 @@ int map_config_read(char *cfgName) else if (strcmpi(w1, "charhelp_txt") == 0) strcpy(charhelp_txt, w2); else if(strcmpi(w1,"db_path") == 0) - strncpy(db_path,w2,255); - else if (strcmpi(w1, "console") == 0) { - console = config_switch(w2); - if (console) - ShowNotice("Console Commands are enabled.\n"); - } else if (strcmpi(w1, "enable_spy") == 0) + safestrncpy(db_path,w2,255); + else if (strcmpi(w1, "enable_spy") == 0) enable_spy = config_switch(w2); else if (strcmpi(w1, "use_grf") == 0) enable_grf = config_switch(w2); @@ -3357,9 +3435,6 @@ int inter_config_read(char *cfgName) if( sscanf(line,"%[^:]: %[^\r\n]",w1,w2) < 2 ) continue; - if(strcmpi(w1, "main_chat_nick")==0) - safestrncpy(main_chat_nick, w2, sizeof(main_chat_nick)); - else if(strcmpi(w1,"item_db_db")==0) strcpy(item_db_db,w2); else @@ -3431,15 +3506,15 @@ int inter_config_read(char *cfgName) int map_sql_init(void) { // main db connection - mmysql_handle = Sql_Malloc(); + mmysql_handle = SQL->Malloc(); ShowInfo("Connecting to the Map DB Server....\n"); - if( SQL_ERROR == Sql_Connect(mmysql_handle, map_server_id, map_server_pw, map_server_ip, map_server_port, map_server_db) ) + if( SQL_ERROR == SQL->Connect(mmysql_handle, map_server_id, map_server_pw, map_server_ip, map_server_port, map_server_db) ) exit(EXIT_FAILURE); ShowStatus("connect success! (Map Server Connection)\n"); if( strlen(default_codepage) > 0 ) - if ( SQL_ERROR == Sql_SetEncoding(mmysql_handle, default_codepage) ) + if ( SQL_ERROR == SQL->SetEncoding(mmysql_handle, default_codepage) ) Sql_ShowDebug(mmysql_handle); return 0; @@ -3448,43 +3523,1338 @@ int map_sql_init(void) int map_sql_close(void) { ShowStatus("Close Map DB Connection....\n"); - Sql_Free(mmysql_handle); + SQL->Free(mmysql_handle); mmysql_handle = NULL; -#ifndef BETA_THREAD_TEST - if (log_config.sql_logs) - { + if (logs->config.sql_logs) { ShowStatus("Close Log DB Connection....\n"); - Sql_Free(logmysql_handle); + SQL->Free(logmysql_handle); logmysql_handle = NULL; } -#endif return 0; } int log_sql_init(void) { -#ifndef BETA_THREAD_TEST // log db connection - logmysql_handle = Sql_Malloc(); + logmysql_handle = SQL->Malloc(); ShowInfo(""CL_WHITE"[SQL]"CL_RESET": Connecting to the Log Database "CL_WHITE"%s"CL_RESET" At "CL_WHITE"%s"CL_RESET"...\n",log_db_db,log_db_ip); - if ( SQL_ERROR == Sql_Connect(logmysql_handle, log_db_id, log_db_pw, log_db_ip, log_db_port, log_db_db) ) + if ( SQL_ERROR == SQL->Connect(logmysql_handle, log_db_id, log_db_pw, log_db_ip, log_db_port, log_db_db) ) exit(EXIT_FAILURE); ShowStatus(""CL_WHITE"[SQL]"CL_RESET": Successfully '"CL_GREEN"connected"CL_RESET"' to Database '"CL_WHITE"%s"CL_RESET"'.\n", log_db_db); if( strlen(default_codepage) > 0 ) - if ( SQL_ERROR == Sql_SetEncoding(logmysql_handle, default_codepage) ) + if ( SQL_ERROR == SQL->SetEncoding(logmysql_handle, default_codepage) ) Sql_ShowDebug(logmysql_handle); -#endif return 0; } +void map_zone_change2(int m, struct map_zone_data *zone) { + char empty[1] = "\0"; + + map[m].prev_zone = map[m].zone; + + if( map[m].zone_mf_count ) + map_zone_remove(m); + + 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) { + map[m].prev_zone = map[m].zone; + + if( map[m].zone_mf_count ) + map_zone_remove(m); + map_zone_apply(m,zone,start,buffer,filepath); +} +/* removes previous mapflags from this map */ +void map_zone_remove(int m) { + char flag[MAP_ZONE_MAPFLAG_LENGTH], params[MAP_ZONE_MAPFLAG_LENGTH]; + unsigned short k; + char empty[1] = "\0"; + for(k = 0; k < map[m].zone_mf_count; k++) { + int len = strlen(map[m].zone_mf[k]),j; + params[0] = '\0'; + memcpy(flag, map[m].zone_mf[k], MAP_ZONE_MAPFLAG_LENGTH); + for(j = 0; j < len; j++) { + if( flag[j] == '\t' ) { + memcpy(params, &flag[j+1], len - j); + flag[j] = '\0'; + break; + } + } + + npc_parse_mapflag(map[m].name,empty,flag,params,empty,empty,empty); + aFree(map[m].zone_mf[k]); + map[m].zone_mf[k] = NULL; + } + + aFree(map[m].zone_mf); + map[m].zone_mf = NULL; + map[m].zone_mf_count = 0; +} +static inline void map_zone_mf_cache_add(int m, char *rflag) { + RECREATE(map[m].zone_mf, char *, ++map[m].zone_mf_count); + CREATE(map[m].zone_mf[map[m].zone_mf_count - 1], char, MAP_ZONE_MAPFLAG_LENGTH); + safestrncpy(map[m].zone_mf[map[m].zone_mf_count - 1], rflag, MAP_ZONE_MAPFLAG_LENGTH); +} +/* 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) { + char rflag[MAP_ZONE_MAPFLAG_LENGTH]; + int state = 1; + + if (params[0] != '\0' && !strcmpi(params, "off")) + state = 0; + + if (!strcmpi(flag, "nosave")) { + ;/* not yet supported to be reversed */ + /* + char savemap[32]; + int savex, savey; + if (state == 0) { + if( map[m].flag.nosave ) { + sprintf(rflag, "nosave SavePoint"); + map_zone_mf_cache_add(m,nosave); + } + } else if (!strcmpi(params, "SavePoint")) { + if( map[m].save.map ) { + sprintf(rflag, "nosave %s,%d,%d",mapindex_id2name(map[m].save.map),map[m].save.x,map[m].save.y); + } else + sprintf(rflag, "nosave %s,%d,%d",mapindex_id2name(map[m].save.map),map[m].save.x,map[m].save.y); + map_zone_mf_cache_add(m,nosave); + } else if (sscanf(params, "%31[^,],%d,%d", savemap, &savex, &savey) == 3) { + if( map[m].save.map ) { + sprintf(rflag, "nosave %s,%d,%d",mapindex_id2name(map[m].save.map),map[m].save.x,map[m].save.y); + map_zone_mf_cache_add(m,nosave); + } + }*/ + } else if (!strcmpi(flag,"autotrade")) { + if( state && map[m].flag.autotrade ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"autotrade off"); + else if( !map[m].flag.autotrade ) + map_zone_mf_cache_add(m,"autotrade"); + } + } else if (!strcmpi(flag,"allowks")) { + if( state && map[m].flag.allowks ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"allowks off"); + else if( !map[m].flag.allowks ) + map_zone_mf_cache_add(m,"allowks"); + } + } else if (!strcmpi(flag,"town")) { + if( state && map[m].flag.town ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"town off"); + else if( !map[m].flag.town ) + map_zone_mf_cache_add(m,"town"); + } + } else if (!strcmpi(flag,"nomemo")) { + if( state && map[m].flag.nomemo ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"nomemo off"); + else if( !map[m].flag.nomemo ) + map_zone_mf_cache_add(m,"nomemo"); + } + } else if (!strcmpi(flag,"noteleport")) { + if( state && map[m].flag.noteleport ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"noteleport off"); + else if( !map[m].flag.noteleport ) + map_zone_mf_cache_add(m,"noteleport"); + } + } else if (!strcmpi(flag,"nowarp")) { + if( state && map[m].flag.nowarp ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"nowarp off"); + else if( !map[m].flag.nowarp ) + map_zone_mf_cache_add(m,"nowarp"); + } + } else if (!strcmpi(flag,"nowarpto")) { + if( state && map[m].flag.nowarpto ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"nowarpto off"); + else if( !map[m].flag.nowarpto ) + map_zone_mf_cache_add(m,"nowarpto"); + } + } else if (!strcmpi(flag,"noreturn")) { + if( state && map[m].flag.noreturn ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"noreturn off"); + else if( map[m].flag.noreturn ) + map_zone_mf_cache_add(m,"noreturn"); + } + } else if (!strcmpi(flag,"monster_noteleport")) { + if( state && map[m].flag.monster_noteleport ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"monster_noteleport off"); + else if( map[m].flag.monster_noteleport ) + map_zone_mf_cache_add(m,"monster_noteleport"); + } + } else if (!strcmpi(flag,"nobranch")) { + if( state && map[m].flag.nobranch ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"nobranch off"); + else if( map[m].flag.nobranch ) + map_zone_mf_cache_add(m,"nobranch"); + } + } else if (!strcmpi(flag,"nopenalty")) { + if( state && map[m].flag.noexppenalty ) /* they are applied together, no need to check both */ + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"nopenalty off"); + else if( map[m].flag.noexppenalty ) + map_zone_mf_cache_add(m,"nopenalty"); + } + } else if (!strcmpi(flag,"pvp")) { + if( state && map[m].flag.pvp ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"pvp off"); + else if( map[m].flag.pvp ) + map_zone_mf_cache_add(m,"pvp"); + } + } + else if (!strcmpi(flag,"pvp_noparty")) { + if( state && map[m].flag.pvp_noparty ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"pvp_noparty off"); + else if( map[m].flag.pvp_noparty ) + map_zone_mf_cache_add(m,"pvp_noparty"); + } + } else if (!strcmpi(flag,"pvp_noguild")) { + if( state && map[m].flag.pvp_noguild ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"pvp_noguild off"); + else if( map[m].flag.pvp_noguild ) + map_zone_mf_cache_add(m,"pvp_noguild"); + } + } else if (!strcmpi(flag, "pvp_nightmaredrop")) { + if( state && map[m].flag.pvp_nightmaredrop ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"pvp_nightmaredrop off"); + else if( map[m].flag.pvp_nightmaredrop ) + map_zone_mf_cache_add(m,"pvp_nightmaredrop"); + } + /* not yet fully supported */ + /*char drop_arg1[16], drop_arg2[16]; + int drop_per = 0; + if (sscanf(w4, "%[^,],%[^,],%d", drop_arg1, drop_arg2, &drop_per) == 3) { + int drop_id = 0, drop_type = 0; + if (!strcmpi(drop_arg1, "random")) + drop_id = -1; + else if (itemdb_exists((drop_id = atoi(drop_arg1))) == NULL) + drop_id = 0; + if (!strcmpi(drop_arg2, "inventory")) + drop_type = 1; + else if (!strcmpi(drop_arg2,"equip")) + drop_type = 2; + else if (!strcmpi(drop_arg2,"all")) + drop_type = 3; + + if (drop_id != 0){ + int i; + for (i = 0; i < MAX_DROP_PER_MAP; i++) { + if (map[m].drop_list[i].drop_id == 0){ + map[m].drop_list[i].drop_id = drop_id; + map[m].drop_list[i].drop_type = drop_type; + map[m].drop_list[i].drop_per = drop_per; + break; + } + } + map[m].flag.pvp_nightmaredrop = 1; + } + } else if (!state) //Disable + map[m].flag.pvp_nightmaredrop = 0; + */ + } else if (!strcmpi(flag,"pvp_nocalcrank")) { + if( state && map[m].flag.pvp_nocalcrank ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"pvp_nocalcrank off"); + else if( map[m].flag.pvp_nocalcrank ) + map_zone_mf_cache_add(m,"pvp_nocalcrank"); + } + } else if (!strcmpi(flag,"gvg")) { + if( state && map[m].flag.gvg ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"gvg off"); + else if( map[m].flag.gvg ) + map_zone_mf_cache_add(m,"gvg"); + } + } else if (!strcmpi(flag,"gvg_noparty")) { + if( state && map[m].flag.gvg_noparty ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"gvg_noparty off"); + else if( map[m].flag.gvg_noparty ) + map_zone_mf_cache_add(m,"gvg_noparty"); + } + } else if (!strcmpi(flag,"gvg_dungeon")) { + if( state && map[m].flag.gvg_dungeon ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"gvg_dungeon off"); + else if( map[m].flag.gvg_dungeon ) + map_zone_mf_cache_add(m,"gvg_dungeon"); + } + } + else if (!strcmpi(flag,"gvg_castle")) { + if( state && map[m].flag.gvg_castle ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"gvg_castle off"); + else if( map[m].flag.gvg_castle ) + map_zone_mf_cache_add(m,"gvg_castle"); + } + } + else if (!strcmpi(flag,"battleground")) { + if( state && map[m].flag.battleground ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"battleground off"); + else if( map[m].flag.battleground ) + map_zone_mf_cache_add(m,"battleground"); + } + } else if (!strcmpi(flag,"noexppenalty")) { + if( state && map[m].flag.noexppenalty ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"noexppenalty off"); + else if( map[m].flag.noexppenalty ) + map_zone_mf_cache_add(m,"noexppenalty"); + } + } else if (!strcmpi(flag,"nozenypenalty")) { + if( state && map[m].flag.nozenypenalty ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"nozenypenalty off"); + else if( map[m].flag.nozenypenalty ) + map_zone_mf_cache_add(m,"nozenypenalty"); + } + } else if (!strcmpi(flag,"notrade")) { + if( state && map[m].flag.notrade ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"notrade off"); + else if( map[m].flag.notrade ) + map_zone_mf_cache_add(m,"notrade"); + } + } else if (!strcmpi(flag,"novending")) { + if( state && map[m].flag.novending ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"novending off"); + else if( map[m].flag.novending ) + map_zone_mf_cache_add(m,"novending"); + } + } else if (!strcmpi(flag,"nodrop")) { + if( state && map[m].flag.nodrop ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"nodrop off"); + else if( map[m].flag.nodrop ) + map_zone_mf_cache_add(m,"nodrop"); + } + } else if (!strcmpi(flag,"noskill")) { + if( state && map[m].flag.noskill ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"noskill off"); + else if( map[m].flag.noskill ) + map_zone_mf_cache_add(m,"noskill"); + } + } else if (!strcmpi(flag,"noicewall")) { + if( state && map[m].flag.noicewall ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"noicewall off"); + else if( map[m].flag.noicewall ) + map_zone_mf_cache_add(m,"noicewall"); + } + } else if (!strcmpi(flag,"snow")) { + if( state && map[m].flag.snow ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"snow off"); + else if( map[m].flag.snow ) + map_zone_mf_cache_add(m,"snow"); + } + } else if (!strcmpi(flag,"clouds")) { + if( state && map[m].flag.clouds ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"clouds off"); + else if( map[m].flag.clouds ) + map_zone_mf_cache_add(m,"clouds"); + } + } else if (!strcmpi(flag,"clouds2")) { + if( state && map[m].flag.clouds2 ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"clouds2 off"); + else if( map[m].flag.clouds2 ) + map_zone_mf_cache_add(m,"clouds2"); + } + } else if (!strcmpi(flag,"fog")) { + if( state && map[m].flag.fog ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"fog off"); + else if( map[m].flag.fog ) + map_zone_mf_cache_add(m,"fog"); + } + } else if (!strcmpi(flag,"fireworks")) { + if( state && map[m].flag.fireworks ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"fireworks off"); + else if( map[m].flag.fireworks ) + map_zone_mf_cache_add(m,"fireworks"); + } + } else if (!strcmpi(flag,"sakura")) { + if( state && map[m].flag.sakura ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"sakura off"); + else if( map[m].flag.sakura ) + map_zone_mf_cache_add(m,"sakura"); + } + } else if (!strcmpi(flag,"leaves")) { + if( state && map[m].flag.leaves ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"leaves off"); + else if( map[m].flag.leaves ) + map_zone_mf_cache_add(m,"leaves"); + } + } else if (!strcmpi(flag,"nightenabled")) { + if( state && map[m].flag.nightenabled ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"nightenabled off"); + else if( map[m].flag.nightenabled ) + map_zone_mf_cache_add(m,"nightenabled"); + } + } else if (!strcmpi(flag,"noexp")) { + if( state && map[m].flag.nobaseexp ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"noexp off"); + else if( map[m].flag.nobaseexp ) + map_zone_mf_cache_add(m,"noexp"); + } + } + else if (!strcmpi(flag,"nobaseexp")) { + if( state && map[m].flag.nobaseexp ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"nobaseexp off"); + else if( map[m].flag.nobaseexp ) + map_zone_mf_cache_add(m,"nobaseexp"); + } + } else if (!strcmpi(flag,"nojobexp")) { + if( state && map[m].flag.nojobexp ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"nojobexp off"); + else if( map[m].flag.nojobexp ) + map_zone_mf_cache_add(m,"nojobexp"); + } + } else if (!strcmpi(flag,"noloot")) { + if( state && map[m].flag.nomobloot ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"noloot off"); + else if( map[m].flag.nomobloot ) + map_zone_mf_cache_add(m,"noloot"); + } + } else if (!strcmpi(flag,"nomobloot")) { + if( state && map[m].flag.nomobloot ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"nomobloot off"); + else if( map[m].flag.nomobloot ) + map_zone_mf_cache_add(m,"nomobloot"); + } + } else if (!strcmpi(flag,"nomvploot")) { + if( state && map[m].flag.nomvploot ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"nomvploot off"); + else if( map[m].flag.nomvploot ) + map_zone_mf_cache_add(m,"nomvploot"); + } + } else if (!strcmpi(flag,"nocommand")) { + /* implementation may be incomplete */ + if( state && sscanf(params, "%d", &state) == 1 ) { + sprintf(rflag, "nocommand %s",params); + map_zone_mf_cache_add(m,rflag); + } else if( !state && map[m].nocommand ) { + sprintf(rflag, "nocommand %d",map[m].nocommand); + map_zone_mf_cache_add(m,rflag); + } else if( map[m].nocommand ) { + map_zone_mf_cache_add(m,"nocommand off"); + } + } else if (!strcmpi(flag,"jexp")) { + if( !state ) { + if( map[m].jexp != 100 ) { + sprintf(rflag,"jexp %d",map[m].jexp); + map_zone_mf_cache_add(m,rflag); + } + } if( sscanf(params, "%d", &state) == 1 ) { + if( state != map[m].jexp ) { + sprintf(rflag,"jexp %s",params); + map_zone_mf_cache_add(m,rflag); + } + } + } else if (!strcmpi(flag,"bexp")) { + if( !state ) { + if( map[m].bexp != 100 ) { + sprintf(rflag,"bexp %d",map[m].jexp); + map_zone_mf_cache_add(m,rflag); + } + } if( sscanf(params, "%d", &state) == 1 ) { + if( state != map[m].bexp ) { + sprintf(rflag,"bexp %s",params); + map_zone_mf_cache_add(m,rflag); + } + } + } else if (!strcmpi(flag,"loadevent")) { + if( state && map[m].flag.loadevent ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"loadevent off"); + else if( map[m].flag.loadevent ) + map_zone_mf_cache_add(m,"loadevent"); + } + } else if (!strcmpi(flag,"nochat")) { + if( state && map[m].flag.nochat ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"nochat off"); + else if( map[m].flag.nochat ) + map_zone_mf_cache_add(m,"nochat"); + } + } else if (!strcmpi(flag,"partylock")) { + if( state && map[m].flag.partylock ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"partylock off"); + else if( map[m].flag.partylock ) + map_zone_mf_cache_add(m,"partylock"); + } + } else if (!strcmpi(flag,"guildlock")) { + if( state && map[m].flag.guildlock ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"guildlock off"); + else if( map[m].flag.guildlock ) + map_zone_mf_cache_add(m,"guildlock"); + } + } else if (!strcmpi(flag,"reset")) { + if( state && map[m].flag.reset ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"reset off"); + else if( map[m].flag.reset ) + map_zone_mf_cache_add(m,"reset"); + } + } 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); + + modifier[0] = '\0'; + memcpy(skill_name, params, MAP_ZONE_MAPFLAG_LENGTH); + + for(k = 0; k < len; k++) { + if( skill_name[k] == '\t' ) { + memcpy(modifier, &skill_name[k+1], len - k); + skill_name[k] = '\0'; + break; + } + } + + if( modifier[0] == '\0' || !( skill_id = skill->name2id(skill_name) ) || !skill->get_unit_id( skill->name2id(skill_name), 0) || atoi(modifier) < 1 || atoi(modifier) > USHRT_MAX ) { + ;/* we dont mind it, the server will take care of it next. */ + } else { + int idx = map[m].unit_count; + + k = 0; + ARR_FIND(0, idx, k, map[m].units[k]->skill_id == skill_id); + + if( k < idx ) { + if( atoi(modifier) != map[m].units[k]->modifier ) { + sprintf(rflag,"adjust_unit_duration %s %d",skill_name,map[m].units[k]->modifier); + map_zone_mf_cache_add(m,rflag); + } + } else { + sprintf(rflag,"adjust_unit_duration %s 100",skill_name); + map_zone_mf_cache_add(m,rflag); + } + } + } 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); + + modifier[0] = '\0'; + memcpy(skill_name, params, MAP_ZONE_MAPFLAG_LENGTH); + + for(k = 0; k < len; k++) { + if( skill_name[k] == '\t' ) { + memcpy(modifier, &skill_name[k+1], len - k); + skill_name[k] = '\0'; + break; + } + } + + if( modifier[0] == '\0' || !( skill_id = skill->name2id(skill_name) ) || atoi(modifier) < 1 || atoi(modifier) > USHRT_MAX ) { + ;/* we dont mind it, the server will take care of it next. */ + } else { + int idx = map[m].skill_count; + + k = 0; + ARR_FIND(0, idx, k, map[m].skills[k]->skill_id == skill_id); + + if( k < idx ) { + if( atoi(modifier) != map[m].skills[k]->modifier ) { + sprintf(rflag,"adjust_skill_damage %s %d",skill_name,map[m].skills[k]->modifier); + map_zone_mf_cache_add(m,rflag); + } + } else { + sprintf(rflag,"adjust_skill_damage %s 100",skill_name); + map_zone_mf_cache_add(m,rflag); + } + + } + } else if (!strcmpi(flag,"zone")) { + ShowWarning("You can't add a zone through a zone! ERROR, skipping for '%s'...\n",map[m].name); + return true; + } else if ( !strcmpi(flag,"nomapchannelautojoin") ) { + if( state && map[m].flag.chsysnolocalaj ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"nomapchannelautojoin off"); + else if( map[m].flag.chsysnolocalaj ) + map_zone_mf_cache_add(m,"nomapchannelautojoin"); + } + } else if ( !strcmpi(flag,"invincible_time_inc") ) { + if( !state ) { + if( map[m].invincible_time_inc != 0 ) { + sprintf(rflag,"invincible_time_inc %d",map[m].invincible_time_inc); + map_zone_mf_cache_add(m,rflag); + } + } if( sscanf(params, "%d", &state) == 1 ) { + if( state != map[m].invincible_time_inc ) { + sprintf(rflag,"invincible_time_inc %s",params); + map_zone_mf_cache_add(m,rflag); + } + } + } else if ( !strcmpi(flag,"noknockback") ) { + if( state && map[m].flag.noknockback ) + ;/* nothing to do */ + else { + if( state ) + map_zone_mf_cache_add(m,"noknockback off"); + else if( map[m].flag.noknockback ) + map_zone_mf_cache_add(m,"noknockback"); + } + } else if ( !strcmpi(flag,"weapon_damage_rate") ) { + if( !state ) { + if( map[m].weapon_damage_rate != 100 ) { + sprintf(rflag,"weapon_damage_rate %d",map[m].weapon_damage_rate); + map_zone_mf_cache_add(m,rflag); + } + } if( sscanf(params, "%d", &state) == 1 ) { + if( state != map[m].weapon_damage_rate ) { + sprintf(rflag,"weapon_damage_rate %s",params); + map_zone_mf_cache_add(m,rflag); + } + } + } else if ( !strcmpi(flag,"magic_damage_rate") ) { + if( !state ) { + if( map[m].magic_damage_rate != 100 ) { + sprintf(rflag,"magic_damage_rate %d",map[m].magic_damage_rate); + map_zone_mf_cache_add(m,rflag); + } + } if( sscanf(params, "%d", &state) == 1 ) { + if( state != map[m].magic_damage_rate ) { + sprintf(rflag,"magic_damage_rate %s",params); + map_zone_mf_cache_add(m,rflag); + } + } + } else if ( !strcmpi(flag,"misc_damage_rate") ) { + if( !state ) { + if( map[m].misc_damage_rate != 100 ) { + sprintf(rflag,"misc_damage_rate %d",map[m].misc_damage_rate); + map_zone_mf_cache_add(m,rflag); + } + } if( sscanf(params, "%d", &state) == 1 ) { + if( state != map[m].misc_damage_rate ) { + sprintf(rflag,"misc_damage_rate %s",params); + map_zone_mf_cache_add(m,rflag); + } + } + } else if ( !strcmpi(flag,"short_damage_rate") ) { + if( !state ) { + if( map[m].short_damage_rate != 100 ) { + sprintf(rflag,"short_damage_rate %d",map[m].short_damage_rate); + map_zone_mf_cache_add(m,rflag); + } + } if( sscanf(params, "%d", &state) == 1 ) { + if( state != map[m].short_damage_rate ) { + sprintf(rflag,"short_damage_rate %s",params); + map_zone_mf_cache_add(m,rflag); + } + } + } else if ( !strcmpi(flag,"long_damage_rate") ) { + if( !state ) { + if( map[m].long_damage_rate != 100 ) { + sprintf(rflag,"long_damage_rate %d",map[m].long_damage_rate); + map_zone_mf_cache_add(m,rflag); + } + } if( sscanf(params, "%d", &state) == 1 ) { + if( state != map[m].long_damage_rate ) { + sprintf(rflag,"long_damage_rate %s",params); + 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) { + int i; + char empty[1] = "\0"; + char flag[MAP_ZONE_MAPFLAG_LENGTH], params[MAP_ZONE_MAPFLAG_LENGTH]; + map[m].zone = zone; + for(i = 0; i < zone->mapflags_count; i++) { + int len = strlen(zone->mapflags[i]); + int k; + params[0] = '\0'; + memcpy(flag, zone->mapflags[i], MAP_ZONE_MAPFLAG_LENGTH); + for(k = 0; k < len; k++) { + if( flag[k] == '\t' ) { + memcpy(params, &flag[k+1], len - k); + flag[k] = '\0'; + break; + } + } + + if( map_zone_mf_cache(m,flag,params) ) + continue; + + npc_parse_mapflag(map[m].name,empty,flag,params,start,buffer,filepath); + } +} +/* used on npc load and reload to apply all "Normal" and "PK Mode" zones */ +void map_zone_init(void) { + char flag[MAP_ZONE_MAPFLAG_LENGTH], params[MAP_ZONE_MAPFLAG_LENGTH]; + struct map_zone_data *zone; + char empty[1] = "\0"; + int i,k,j; + + zone = &map_zone_all; + + for(i = 0; i < zone->mapflags_count; i++) { + int len = strlen(zone->mapflags[i]); + params[0] = '\0'; + memcpy(flag, zone->mapflags[i], MAP_ZONE_MAPFLAG_LENGTH); + for(k = 0; k < len; k++) { + if( flag[k] == '\t' ) { + memcpy(params, &flag[k+1], len - k); + flag[k] = '\0'; + break; + } + } + + for(j = 0; j < map_num; j++) { + if( map[j].zone == zone ) { + if( map_zone_mf_cache(j,flag,params) ) + break; + npc_parse_mapflag(map[j].name,empty,flag,params,empty,empty,empty); + } + } + } + + if( battle_config.pk_mode ) { + zone = &map_zone_pk; + for(i = 0; i < zone->mapflags_count; i++) { + int len = strlen(zone->mapflags[i]); + params[0] = '\0'; + memcpy(flag, zone->mapflags[i], MAP_ZONE_MAPFLAG_LENGTH); + for(k = 0; k < len; k++) { + if( flag[k] == '\t' ) { + memcpy(params, &flag[k+1], len - k); + flag[k] = '\0'; + break; + } + } + for(j = 0; j < map_num; j++) { + if( map[j].zone == zone ) { + if( map_zone_mf_cache(j,flag,params) ) + break; + npc_parse_mapflag(map[j].name,empty,flag,params,empty,empty,empty); + } + } + } + } + +} +unsigned short map_zone_str2itemid(const char *name) { + struct item_data *data; + + if( !name ) + return 0; + if( name[0] == 'I' && name[1] == 'D' && strlen(name) <= 7 ) { + if( !( data = itemdb_exists(atoi(name+2))) ) { + return 0; + } + } else { + if( !( data = itemdb_searchname(name) ) ) { + return 0; + } + } + return data->nameid; +} +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) <= 7 ) { + if( !skill->get_index((nameid = atoi(name+2))) ) + return 0; + } else { + if( !( nameid = strdb_iget(skilldb_name2id, name) ) ) { + return 0; + } + } + return nameid; +} +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; + *subtype = MZS_NONE; + + if( !entry ) + return BL_NUL; + + safestrncpy(temp, entry, 200); + + parse = strtok(temp,"|"); + + while (parse != NULL) { + normalize_name(parse," "); + if( strcmpi(parse,"player") == 0 ) + bl |= BL_PC; + else if( strcmpi(parse,"homun") == 0 ) + bl |= BL_HOM; + else if( strcmpi(parse,"mercenary") == 0 ) + bl |= BL_MER; + else if( strcmpi(parse,"monster") == 0 ) + bl |= BL_MOB; + else if( strcmpi(parse,"clone") == 0 ) { + bl |= BL_MOB; + *subtype |= MZS_CLONE; + } else if( strcmpi(parse,"mob_boss") == 0 ) { + bl |= BL_MOB; + *subtype |= MZS_BOSS; + } else if( strcmpi(parse,"elemental") == 0 ) + bl |= BL_ELEM; + else if( strcmpi(parse,"pet") == 0 ) + bl |= BL_PET; + else if( strcmpi(parse,"all") == 0 ) { + bl |= BL_ALL; + *subtype |= MZS_ALL; + } else if( strcmpi(parse,"none") == 0 ) { + bl = BL_NUL; + } else { + ShowError("map_zone_db: '%s' unknown type, skipping...\n",parse); + } + parse = strtok(NULL,"|"); + } + return bl; +} +/* [Ind/Hercules] */ +void read_map_zone_db(void) { + config_t map_zone_db; + 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 + if (conf_read_file(&map_zone_db, config_filename)) + return; + + zones = config_lookup(&map_zone_db, "zones"); + + if (zones != NULL) { + struct map_zone_data *zone; + config_setting_t *zone_e; + config_setting_t *skills; + config_setting_t *items; + config_setting_t *mapflags; + config_setting_t *commands; + config_setting_t *caps; + const char *name; + const char *zonename; + int i,h,v; + int zone_count = 0, disabled_skills_count = 0, disabled_items_count = 0, mapflags_count = 0, + disabled_commands_count = 0, capped_skills_count = 0; + enum map_zone_skill_subtype subtype; + + zone_count = config_setting_length(zones); + for (i = 0; i < zone_count; ++i) { + bool is_all = false; + + zone_e = config_setting_get_elem(zones, i); + + if (!config_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 */ + --zone_count; + --i; + continue; + } + + if( strdb_exists(zone_db, zonename) ) { + ShowError("map_zone_db: duplicate zone name '%s', skipping...\n",zonename); + config_setting_remove_elem(zones,i);/* remove from the tree */ + --zone_count; + --i; + continue; + } + + /* is this the global template? */ + if( strncmpi(zonename,MAP_ZONE_NORMAL_NAME,MAP_ZONE_NAME_LENGTH) == 0 ) { + zone = &map_zone_all; + is_all = true; + } else if( strncmpi(zonename,MAP_ZONE_PK_NAME,MAP_ZONE_NAME_LENGTH) == 0 ) { + zone = &map_zone_pk; + is_all = true; + } else { + CREATE( zone, struct map_zone_data, 1 ); + zone->disabled_skills_count = 0; + zone->disabled_items_count = 0; + } + safestrncpy(zone->name, zonename, MAP_ZONE_NAME_LENGTH); + + if( (skills = config_setting_get_member(zone_e, "disabled_skills")) != NULL ) { + disabled_skills_count = config_setting_length(skills); + /* validate */ + for(h = 0; h < config_setting_length(skills); h++) { + config_setting_t *skill = config_setting_get_elem(skills, h); + name = config_setting_name(skill); + 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); + --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 */ + --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 *skill = config_setting_get_elem(skills, h); + struct map_zone_disabled_skill_entry * entry; + enum bl_type type; + name = config_setting_name(skill); + + if( (type = map_zone_bl_type(config_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); + entry->type = type; + entry->subtype = subtype; + + zone->disabled_skills[v++] = entry; + } + + } + 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); + /* validate */ + for(h = 0; h < config_setting_length(items); h++) { + config_setting_t *item = config_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); + --disabled_items_count; + --h; + continue; + } + if( !config_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); + + if( config_setting_get_bool(item) ) { /* only add if enabled */ + name = config_setting_name(item); + zone->disabled_items[v++] = map_zone_str2itemid(name); + } + + } + zone->disabled_items_count = disabled_items_count; + } + + if( (mapflags = config_setting_get_member(zone_e, "mapflags")) != NULL ) { + mapflags_count = config_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); + + safestrncpy(zone->mapflags[h], name, MAP_ZONE_MAPFLAG_LENGTH); + + } + zone->mapflags_count = mapflags_count; + } + + if( (commands = config_setting_get_member(zone_e, "disabled_commands")) != NULL ) { + disabled_commands_count = config_setting_length(commands); + /* validate */ + for(h = 0; h < config_setting_length(commands); h++) { + config_setting_t *command = config_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); + --disabled_commands_count; + --h; + continue; + } + if( !config_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); + 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 */ + CREATE( entry, struct map_zone_disabled_command_entry, 1 ); + + entry->cmd = atcommand->exists(name)->func; + entry->group_lv = group_lv; + + zone->disabled_commands[v++] = entry; + } + } + 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); + /* validate */ + for(h = 0; h < config_setting_length(caps); h++) { + config_setting_t *cap = config_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); + --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 */ + --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); + 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 */ + 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->type = type; + entry->subtype = subtype; + zone->capped_skills[v++] = entry; + } + } + zone->capped_skills_count = capped_skills_count; + } + + if( !is_all ) /* global template doesn't go into db -- since it isn't a alloc'd piece of data */ + strdb_put(zone_db, zonename, zone); + + } + + /* process inheritance, aka loop through the whole thing again :P */ + for (i = 0; i < zone_count; ++i) { + config_setting_t *inherit_tree = NULL; + 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); + + 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 ) { + /* 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); + } 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_count = config_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 */ + int disabled_items_count_i = 0; /* disabled item count from inherit zone */ + int mapflags_count_i = 0; /* mapflag count from inherit zone */ + int disabled_commands_count_i = 0; /* commands count from inherit zone */ + 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 */ + + if( !(izone = strdb_get(zone_db, name)) ) { + ShowError("map_zone_db: Unknown zone '%s' being inherit by zone '%s', skipping...\n",name,zonename); + continue; + } + + if( strncmpi(zonename,MAP_ZONE_NORMAL_NAME,MAP_ZONE_NAME_LENGTH) == 0 ) { + zone = &map_zone_all; + } else if( strncmpi(zonename,MAP_ZONE_PK_NAME,MAP_ZONE_NAME_LENGTH) == 0 ) { + zone = &map_zone_pk; + } else + zone = strdb_get(zone_db, zonename);/* will succeed for we just put it in here */ + + disabled_skills_count_i = izone->disabled_skills_count; + disabled_items_count_i = izone->disabled_items_count; + mapflags_count_i = izone->mapflags_count; + disabled_commands_count_i = izone->disabled_commands_count; + capped_skills_count_i = izone->capped_skills_count; + + /* 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); + for(j = 0; j < disabled_skills_count_i; j++) { + int k; + for(k = 0; k < disabled_skills_count; k++) { + config_setting_t *skill = config_setting_get_elem(skills, k); + if( map_zone_str2skillid(config_setting_name(skill)) == izone->disabled_skills[j]->nameid ) { + break; + } + } + if( k == disabled_skills_count ) {/* we didn't find it */ + struct map_zone_disabled_skill_entry *entry; + RECREATE( zone->disabled_skills, struct map_zone_disabled_skill_entry *, ++zone->disabled_skills_count ); + CREATE( entry, struct map_zone_disabled_skill_entry, 1 ); + entry->nameid = izone->disabled_skills[j]->nameid; + entry->type = izone->disabled_skills[j]->type; + zone->disabled_skills[zone->disabled_skills_count-1] = entry; + } + } + } + + 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); + 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); + + name = config_setting_name(item); + + if( map_zone_str2itemid(name) == izone->disabled_items[j] ) { + if( config_setting_get_bool(item) ) + continue; + break; + } + } + if( k == disabled_items_count ) {/* we didn't find it */ + RECREATE( zone->disabled_items, int, ++zone->disabled_items_count ); + zone->disabled_items[zone->disabled_items_count-1] = izone->disabled_items[j]; + } + } + } + + 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); + 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); + + if( strcmpi(name,izone->mapflags[j]) == 0 ) { + break; + } + } + if( k == mapflags_count ) {/* we didn't find it */ + RECREATE( zone->mapflags, char*, ++zone->mapflags_count ); + CREATE( zone->mapflags[zone->mapflags_count-1], char, MAP_ZONE_MAPFLAG_LENGTH ); + safestrncpy(zone->mapflags[zone->mapflags_count-1], izone->mapflags[j], MAP_ZONE_MAPFLAG_LENGTH); + } + } + } + + 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); + + disabled_commands_count = config_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); + if( atcommand->exists(config_setting_name(command))->func == izone->disabled_commands[j]->cmd ) { + break; + } + } + if( k == disabled_commands_count ) {/* we didn't find it */ + struct map_zone_disabled_command_entry *entry; + RECREATE( zone->disabled_commands, struct map_zone_disabled_command_entry *, ++zone->disabled_commands_count ); + CREATE( entry, struct map_zone_disabled_command_entry, 1 ); + entry->cmd = izone->disabled_commands[j]->cmd; + entry->group_lv = izone->disabled_commands[j]->group_lv; + zone->disabled_commands[zone->disabled_commands_count-1] = entry; + } + } + } + + 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); + + capped_skills_count = config_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); + if( map_zone_str2skillid(config_setting_name(cap)) == izone->capped_skills[j]->nameid ) { + break; + } + } + if( k == capped_skills_count ) {/* we didn't find it */ + struct map_zone_skill_damage_cap_entry *entry; + RECREATE( zone->capped_skills, struct map_zone_skill_damage_cap_entry *, ++zone->capped_skills_count ); + CREATE( entry, struct map_zone_skill_damage_cap_entry, 1 ); + entry->nameid = izone->capped_skills[j]->nameid; + entry->cap = izone->capped_skills[j]->cap; + entry->type = izone->capped_skills[j]->type; + zone->capped_skills[zone->capped_skills_count-1] = entry; + } + } + } + + } + } + + 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); + } +} /** * @see DBApply */ int map_db_final(DBKey key, DBData *data, va_list ap) { - struct map_data_other_server *mdos = db_data2ptr(data); + struct map_data_other_server *mdos = DB->data2ptr(data); if(mdos && mdos->cell == NULL) aFree(mdos); return 0; @@ -3495,7 +4865,7 @@ int map_db_final(DBKey key, DBData *data, va_list ap) */ int nick_db_final(DBKey key, DBData *data, va_list args) { - struct charid2nick* p = db_data2ptr(data); + struct charid2nick* p = DB->data2ptr(data); struct charid_request* req; if( p == NULL ) @@ -3531,7 +4901,7 @@ int cleanup_sub(struct block_list *bl, va_list ap) map_clearflooritem(bl); break; case BL_SKILL: - skill_delunit((struct skill_unit *) bl); + skill->delunit((struct skill_unit *) bl); break; } @@ -3543,7 +4913,7 @@ int cleanup_sub(struct block_list *bl, va_list ap) */ static int cleanup_db_sub(DBKey key, DBData *data, va_list va) { - return cleanup_sub(db_data2ptr(data), va); + return cleanup_sub(DB->data2ptr(data), va); } /*========================================== @@ -3551,17 +4921,19 @@ static int cleanup_db_sub(DBKey key, DBData *data, va_list va) *------------------------------------------*/ void do_final(void) { - int i, j; + int i; struct map_session_data* sd; struct s_mapiterator* iter; ShowStatus("Terminating...\n"); + hChSys.closing = true; + HPM->event(HPET_FINAL); //Ladies and babies first. iter = mapit_getallusers(); - for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) ) + for( sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); sd = (TBL_PC*)mapit->next(iter) ) map_quit(sd); - mapit_free(iter); + mapit->free(iter); /* prepares npcs for a faster shutdown process */ do_clear_npc(); @@ -3577,43 +4949,35 @@ void do_final(void) id_db->foreach(id_db,cleanup_db_sub); chrif_char_reset_offline(); chrif_flush_fifo(); - - do_final_atcommand(); - do_final_battle(); + + atcommand->final(); + battle->final(); do_final_chrif(); - do_final_clif(); + ircbot->final();/* before clif. */ + clif->final(); do_final_npc(); - do_final_script(); + script->final(); do_final_instance(); do_final_itemdb(); do_final_storage(); - do_final_guild(); + guild->final(); do_final_party(); do_final_pc(); do_final_pet(); do_final_mob(); - do_final_msg(); - do_final_skill(); + homun->final(); + atcommand->final_msg(); + skill->final(); do_final_status(); do_final_unit(); do_final_battleground(); do_final_duel(); do_final_elemental(); - + do_final_maps(); + vending->final(); + map_db->destroy(map_db, map_db_final); - - for (i=0; i<map_num; i++) { - if(map[i].cell) aFree(map[i].cell); - if(map[i].block) aFree(map[i].block); - if(map[i].block_mob) aFree(map[i].block_mob); - if(battle_config.dynamic_mobs) { //Dynamic mobs flag by [random] - if(map[i].mob_delete_timer != INVALID_TIMER) - delete_timer(map[i].mob_delete_timer, map_removemobs_timer); - for (j=0; j<MAX_MOB_LIST_PER_MAP; j++) - if (map[i].moblist[j]) aFree(map[i].moblist[j]); - } - } - + mapindex_final(); if(enable_grf) grfio_final(); @@ -3628,6 +4992,9 @@ void do_final(void) regen_db->destroy(regen_db, NULL); map_sql_close(); + ers_destroy(map_iterator_ers); + + aFree(map); ShowStatus("Finished.\n"); } @@ -3689,22 +5056,19 @@ static void map_helpscreen(bool do_exit) /*====================================================== * Map-Server Version Screen [MC Cameri] *------------------------------------------------------*/ -static void map_versionscreen(bool do_exit) -{ - ShowInfo(CL_WHITE"rAthena SVN version: %s" CL_RESET"\n", get_svn_revision()); - ShowInfo(CL_GREEN"Website/Forum:"CL_RESET"\thttp://rathena.org/\n"); - ShowInfo(CL_GREEN"IRC Channel:"CL_RESET"\tirc://irc.rathena.net/#rathena\n"); +static void map_versionscreen(bool do_exit) { + const char *svn = get_svn_revision(); + const char *git = get_git_hash(); + ShowInfo(CL_WHITE"Hercules version: %s" CL_RESET"\n", git[0] != HERC_UNKNOWN_VER ? git : svn[0] != HERC_UNKNOWN_VER ? svn : "Unknown"); + ShowInfo(CL_GREEN"Website/Forum:"CL_RESET"\thttp://hercules.ws/\n"); + ShowInfo(CL_GREEN"IRC Channel:"CL_RESET"\tirc://irc.rizon.net/#Hercules\n"); ShowInfo("Open "CL_WHITE"readme.txt"CL_RESET" for more information.\n"); if( do_exit ) exit(EXIT_SUCCESS); } -/*====================================================== - * Map-Server Init and Command-line Arguments [Valaris] - *------------------------------------------------------*/ -void set_server_type(void) -{ - SERVER_TYPE = ATHENA_SERVER_MAP; +void set_server_type(void) { + SERVER_TYPE = SERVER_TYPE_MAP; } @@ -3718,9 +5082,9 @@ void do_shutdown(void) { struct map_session_data* sd; struct s_mapiterator* iter = mapit_getallusers(); - for( sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); sd = (TBL_PC*)mapit_next(iter) ) - clif_GM_kick(NULL, sd); - mapit_free(iter); + for( sd = (TBL_PC*)mapit->first(iter); mapit->exists(iter); sd = (TBL_PC*)mapit->next(iter) ) + clif->GM_kick(NULL, sd); + mapit->free(iter); flush_fifos(); } chrif_check_shutdown(); @@ -3729,15 +5093,124 @@ void do_shutdown(void) static bool map_arg_next_value(const char* option, int i, int argc) { - if( i >= argc-1 ) - { + if( i >= argc-1 ) { ShowWarning("Missing value for option '%s'.\n", option); return false; } return true; } +struct map_session_data cpsd; +CPCMD(gm_position) { + int x = 0, y = 0, m = 0; + char map_name[25]; + + if( line == NULL || sscanf(line, "%d %d %24s",&x,&y,map_name) < 3 ) { + ShowError("gm:info invalid syntax. use '"CL_WHITE"gm:info xCord yCord map_name"CL_RESET"'\n"); + return; + } + if ( (m = map_mapname2mapid(map_name) <= 0 ) ) { + ShowError("gm:info '"CL_WHITE"%s"CL_RESET"' is not a known map\n",map_name); + return; + } + + if( x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys ) { + ShowError("gm:info '"CL_WHITE"%d %d"CL_RESET"' is out of '"CL_WHITE"%s"CL_RESET"' map bounds!\n",x,y,map_name); + return; + } + + ShowInfo("HCP: updated console's game position to '"CL_WHITE"%d %d %s"CL_RESET"'\n",x,y,map_name); + cpsd.bl.x = x; + cpsd.bl.y = y; + cpsd.bl.m = m; +} +CPCMD(gm_use) { + + if( line == NULL ) { + ShowError("gm:use invalid syntax. use '"CL_WHITE"gm:use @command <optional params>"CL_RESET"'\n"); + return; + } + cpsd.fd = -2; + if( !atcommand->parse(cpsd.fd, &cpsd, line, 0) ) + ShowInfo("HCP: '"CL_WHITE"%s"CL_RESET"' failed\n",line); + else + ShowInfo("HCP: '"CL_WHITE"%s"CL_RESET"' was used\n",line); + cpsd.fd = 0; + +} +/* Hercules Console Parser */ +void map_cp_defaults(void) { + /* default HCP data */ + memset(&cpsd, 0, sizeof(struct map_session_data)); + strcpy(cpsd.status.name, "Hercules Console"); + cpsd.bl.x = 150; + cpsd.bl.y = 150; + cpsd.bl.m = map_mapname2mapid("prontera"); + + console->addCommand("gm:info",CPCMD_A(gm_position)); + console->addCommand("gm:use",CPCMD_A(gm_use)); +} +/* Hercules Plugin Mananger */ +void map_hp_symbols(void) { + /* full interfaces */ + HPM->share(atcommand,"atcommand"); + HPM->share(buyingstore,"buyingstore"); + HPM->share(clif,"clif"); + HPM->share(ircbot,"ircbot"); + HPM->share(logs,"logs"); + HPM->share(script,"script"); + HPM->share(searchstore,"searchstore"); + HPM->share(skill,"skill"); + HPM->share(vending,"vending"); + /* partial */ + HPM->share(mapit,"mapit"); + HPM->share(map_foreachpc,"map_foreachpc"); + HPM->share(map_foreachmob,"map_foreachmob"); + HPM->share(map_foreachnpc,"map_foreachnpc"); + HPM->share(map_foreachregen,"map_foreachregen"); + HPM->share(map_foreachiddb,"map_foreachiddb"); + /* sql link */ + HPM->share(mmysql_handle,"sql_handle"); + /* specific */ + HPM->share(atcommand->create,"addCommand"); + HPM->share(script->addScript,"addScript"); + /* vars */ + HPM->share(map,"map"); +} +/* temporary until the map.c "Hercules Renewal Phase One" design is complete. */ +void map_defaults(void) { + mapit = &mapit_s; + + mapit->alloc = mapit_alloc; + mapit->free = mapit_free; + mapit->first = mapit_first; + mapit->last = mapit_last; + mapit->next = mapit_next; + mapit->prev = mapit_prev; + mapit->exists = mapit_exists; + + map_foreachpc = map_map_foreachpc; + map_foreachmob = map_map_foreachmob; + map_foreachnpc = map_map_foreachnpc; + map_foreachregen = map_map_foreachregen; + map_foreachiddb = map_map_foreachiddb; +} +void load_defaults(void) { + atcommand_defaults(); + battle_defaults(); + buyingstore_defaults(); + clif_defaults(); + guild_defaults(); + homunculus_defaults(); + ircbot_defaults(); + log_defaults(); + map_defaults(); + script_defaults(); + searchstore_defaults(); + skill_defaults(); + vending_defaults(); +} int do_init(int argc, char *argv[]) { int i; @@ -3842,15 +5315,17 @@ int do_init(int argc, char *argv[]) exit(EXIT_FAILURE); } } - + + CREATE(map,struct map_data,MAX_MAP_PER_SERVER); + + load_defaults(); + map_config_read(MAP_CONF_NAME); - /* only temporary until sirius's datapack patch is complete */ - // loads npcs map_reloadnpc(false); chrif_checkdefaultlogin(); - + if (!map_ip_set || !char_ip_set) { char ip_str[16]; ip2str(addr_[0], ip_str); @@ -3865,16 +5340,16 @@ int do_init(int argc, char *argv[]) ShowInfo("Defaulting to %s as our IP address\n", ip_str); if (!map_ip_set) - clif_setip(ip_str); + clif->setip(ip_str); if (!char_ip_set) chrif_setip(ip_str); } - - battle_config_read(BATTLE_CONF_FILENAME); - msg_config_read(MSG_CONF_NAME); + + battle->config_read(BATTLE_CONF_FILENAME); + atcommand->msg_read(MSG_CONF_NAME); script_config_read(SCRIPT_CONF_NAME); inter_config_read(INTER_CONF_NAME); - log_config_read(LOG_CONF_NAME); + logs->config_read(LOG_CONF_NAME); id_db = idb_alloc(DB_OPT_BASE); pc_db = idb_alloc(DB_OPT_BASE); //Added for reliable map_id2sd() use. [Skotlex] @@ -3886,38 +5361,47 @@ int do_init(int argc, char *argv[]) regen_db = idb_alloc(DB_OPT_BASE); // efficient status_natural_heal processing iwall_db = strdb_alloc(DB_OPT_RELEASE_DATA,2*NAME_LENGTH+2+1); // [Zephyrus] Invisible Walls + 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_sql_init(); - if (log_config.sql_logs) + if (logs->config.sql_logs) log_sql_init(); mapindex_init(); if(enable_grf) grfio_init(GRF_PATH_FILENAME); - + map_readallmaps(); add_timer_func_list(map_freeblock_timer, "map_freeblock_timer"); add_timer_func_list(map_clearflooritem_timer, "map_clearflooritem_timer"); add_timer_func_list(map_removemobs_timer, "map_removemobs_timer"); add_timer_interval(gettick()+1000, map_freeblock_timer, 0, 0, 60*1000); - - do_init_atcommand(); - do_init_battle(); + + HPM->symbol_defaults_sub = map_hp_symbols; + HPM->config_read(); + HPM->event(HPET_INIT); + + atcommand->init(); + battle->init(); do_init_instance(); do_init_chrif(); - do_init_clif(); - do_init_script(); + clif->init(); + ircbot->init(); + script->init(); do_init_itemdb(); - do_init_skill(); + skill->init(); + read_map_zone_db();/* read after item and skill initalization */ do_init_mob(); do_init_pc(); do_init_status(); do_init_party(); - do_init_guild(); + guild->init(); do_init_storage(); do_init_pet(); - do_init_merc(); + homun->init(); do_init_mercenary(); do_init_elemental(); do_init_quest(); @@ -3925,28 +5409,25 @@ int do_init(int argc, char *argv[]) do_init_unit(); do_init_battleground(); do_init_duel(); + vending->init(); npc_event_do_oninit(); // Init npcs (OnInit) - if( console ) - { - //##TODO invoke a CONSOLE_START plugin event - } - if (battle_config.pk_mode) ShowNotice("Server is running on '"CL_WHITE"PK Mode"CL_RESET"'.\n"); + Sql_HerculesUpdateCheck(mmysql_handle); + ShowStatus("Server is '"CL_GREEN"ready"CL_RESET"' and listening on port '"CL_WHITE"%d"CL_RESET"'.\n\n", map_port); - - if( runflag != CORE_ST_STOP ) - { + + if( runflag != CORE_ST_STOP ) { shutdown_callback = do_shutdown; runflag = MAPSERVER_ST_RUNNING; } -#if defined(BUILDBOT) - if( buildbotflag ) - exit(EXIT_FAILURE); -#endif - + + map_cp_defaults(); + + HPM->event(HPET_READY); + return 0; } |