diff options
Diffstat (limited to 'src/map/map.c')
-rw-r--r-- | src/map/map.c | 855 |
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; + } |