diff options
Diffstat (limited to 'src/map/map.c')
-rw-r--r-- | src/map/map.c | 314 |
1 files changed, 180 insertions, 134 deletions
diff --git a/src/map/map.c b/src/map/map.c index 343f219b8..9db868329 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -45,7 +45,6 @@ #include "map/mapreg.h" #include "map/mercenary.h" #include "map/mob.h" -#include "map/npc.h" #include "map/npc.h" // npc_setcells(), npc_unsetcells() #include "map/party.h" #include "map/path.h" @@ -56,7 +55,9 @@ #include "map/skill.h" #include "map/status.h" #include "map/storage.h" +#include "map/stylist.h" #include "map/rodex.h" +#include "map/refine.h" #include "map/trade.h" #include "map/unit.h" #include "map/achievement.h" @@ -635,6 +636,18 @@ static int map_foreachinmap(int (*func)(struct block_list*, va_list), int16 m, i return returnCount; } +static int map_forcountinmap(int (*func)(struct block_list*, va_list), int16 m, int count, int type, ...) +{ + int returnCount; + va_list ap; + + va_start(ap, type); + returnCount = map->vforcountinarea(func, m, 0, 0, map->list[m].xs, map->list[m].ys, count, type, ap); + va_end(ap); + + return returnCount; +} + /** * Applies func to every block_list object of bl_type type on all maps * of instance instance_id. @@ -2254,30 +2267,25 @@ static struct map_session_data *map_charid2sd(int charid) * (without sensitive case if necessary) * return map_session_data pointer or NULL *------------------------------------------*/ -static struct map_session_data *map_nick2sd(const char *nick) +static struct map_session_data *map_nick2sd(const char *nick, bool allow_partial) { - struct map_session_data* sd; - struct map_session_data* found_sd; - struct s_mapiterator* iter; - size_t nicklen; - int qty = 0; - - if( nick == NULL ) + if (nick == NULL) return NULL; - nicklen = strlen(nick); - iter = mapit_getallusers(); + struct s_mapiterator *iter = mapit_getallusers(); + struct map_session_data *found_sd = NULL; + + if (battle_config.partial_name_scan && allow_partial) { + int nicklen = (int)strlen(nick); + int qty = 0; - found_sd = NULL; - for (sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); sd = BL_UCAST(BL_PC, mapit->next(iter))) { - if( battle_config.partial_name_scan ) - {// partial name search - if( strnicmp(sd->status.name, nick, nicklen) == 0 ) - { + // partial name search + for (struct map_session_data *sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); sd = BL_UCAST(BL_PC, mapit->next(iter))) { + if (strnicmp(sd->status.name, nick, nicklen) == 0) { found_sd = sd; - if( strcmp(sd->status.name, nick) == 0 ) - {// Perfect Match + if (strcmp(sd->status.name, nick) == 0) { + // Perfect Match qty = 1; break; } @@ -2285,17 +2293,20 @@ static struct map_session_data *map_nick2sd(const char *nick) qty++; } } - else if( strcasecmp(sd->status.name, nick) == 0 ) - {// exact search only - found_sd = sd; - break; + + if (qty != 1) + found_sd = NULL; + } else { + // exact search only + for (struct map_session_data *sd = BL_UCAST(BL_PC, mapit->first(iter)); mapit->exists(iter); sd = BL_UCAST(BL_PC, mapit->next(iter))) { + if (strcasecmp(sd->status.name, nick) == 0) { + found_sd = sd; + break; + } } } mapit->free(iter); - if( battle_config.partial_name_scan && qty != 1 ) - found_sd = NULL; - return found_sd; } @@ -3572,23 +3583,27 @@ static void map_zone_db_clear(void) } static void map_clean(int i) { - int v; Assert_retv(i >= 0 && i < map->count); - if(map->list[i].cell && map->list[i].cell != (struct mapcell *)0xdeadbeaf) aFree(map->list[i].cell); - if(map->list[i].block) aFree(map->list[i].block); - if(map->list[i].block_mob) aFree(map->list[i].block_mob); - if(battle_config.dynamic_mobs) { //Dynamic mobs flag by [random] - int j; - if(map->list[i].mob_delete_timer != INVALID_TIMER) + if (map->list[i].cell && map->list[i].cell != (struct mapcell *)0xdeadbeaf) + aFree(map->list[i].cell); + if (map->list[i].block) + aFree(map->list[i].block); + if (map->list[i].block_mob) + aFree(map->list[i].block_mob); + + if (battle_config.dynamic_mobs != 0) { //Dynamic mobs flag by [random] + if (map->list[i].mob_delete_timer != INVALID_TIMER) timer->delete(map->list[i].mob_delete_timer, map->removemobs_timer); - for (j=0; j<MAX_MOB_LIST_PER_MAP; j++) - if (map->list[i].moblist[j]) aFree(map->list[i].moblist[j]); + for (int j = 0; j < MAX_MOB_LIST_PER_MAP; j++) { + if (map->list[i].moblist[j] != NULL) + aFree(map->list[i].moblist[j]); + } } - if( map->list[i].unit_count ) { - if( map->list[i].units ) { - for(v = 0; v < map->list[i].unit_count; v++) { + if (map->list[i].unit_count != 0) { + if (map->list[i].units != NULL) { + for (int v = 0; v < map->list[i].unit_count; v++) { aFree(map->list[i].units[v]); } aFree(map->list[i].units); @@ -3597,105 +3612,51 @@ static void map_clean(int i) map->list[i].unit_count = 0; } - if( map->list[i].skill_count ) { - if( map->list[i].skills ) { - for(v = 0; v < map->list[i].skill_count; v++) { - aFree(map->list[i].skills[v]); - } + if (map->list[i].skill_count != 0) { + if (map->list[i].skills != NULL) { + for (int v = 0; v < map->list[i].skill_count; v++) { + aFree(map->list[i].skills[v]); + } aFree(map->list[i].skills); map->list[i].skills = NULL; } map->list[i].skill_count = 0; } - if( map->list[i].zone_mf_count ) { - if( map->list[i].zone_mf ) { - for(v = 0; v < map->list[i].zone_mf_count; v++) { - aFree(map->list[i].zone_mf[v]); - } + if (map->list[i].zone_mf_count != 0) { + if (map->list[i].zone_mf != NULL) { + for (int v = 0; v < map->list[i].zone_mf_count; v++) { + aFree(map->list[i].zone_mf[v]); + } aFree(map->list[i].zone_mf); map->list[i].zone_mf = NULL; } map->list[i].zone_mf_count = 0; } - if( map->list[i].channel ) + if (map->list[i].drop_list_count != 0) + map->list[i].drop_list_count = 0; + if (map->list[i].drop_list != NULL) + aFree(map->list[i].drop_list); + + if (map->list[i].channel != NULL) channel->delete(map->list[i].channel); + + VECTOR_CLEAR(map->list[i].qi_list); + HPM->data_store_destroy(&map->list[i].hdata); } static void do_final_maps(void) { - int i, v = 0; - - for( i = 0; i < map->count; i++ ) { - - if(map->list[i].cell && map->list[i].cell != (struct mapcell *)0xdeadbeaf ) aFree(map->list[i].cell); - if(map->list[i].block) aFree(map->list[i].block); - if(map->list[i].block_mob) aFree(map->list[i].block_mob); - - if(battle_config.dynamic_mobs) { //Dynamic mobs flag by [random] - int j; - if(map->list[i].mob_delete_timer != INVALID_TIMER) - timer->delete(map->list[i].mob_delete_timer, map->removemobs_timer); - for (j=0; j<MAX_MOB_LIST_PER_MAP; j++) - if (map->list[i].moblist[j]) aFree(map->list[i].moblist[j]); - } - - if( map->list[i].unit_count ) { - if( map->list[i].units ) { - for(v = 0; v < map->list[i].unit_count; v++) { - aFree(map->list[i].units[v]); - } - aFree(map->list[i].units); - map->list[i].units = NULL; - } - map->list[i].unit_count = 0; - } - - if( map->list[i].skill_count ) { - if( map->list[i].skills ) { - for(v = 0; v < map->list[i].skill_count; v++) { - aFree(map->list[i].skills[v]); - } - aFree(map->list[i].skills); - map->list[i].skills = NULL; - } - map->list[i].skill_count = 0; - } - - if( map->list[i].zone_mf_count ) { - if( map->list[i].zone_mf ) { - for(v = 0; v < map->list[i].zone_mf_count; v++) { - aFree(map->list[i].zone_mf[v]); - } - aFree(map->list[i].zone_mf); - map->list[i].zone_mf = NULL; - } - map->list[i].zone_mf_count = 0; - } - - if( map->list[i].drop_list_count ) { - map->list[i].drop_list_count = 0; - } - if( map->list[i].drop_list != NULL ) - aFree(map->list[i].drop_list); - - if( map->list[i].channel ) - channel->delete(map->list[i].channel); - - quest->questinfo_vector_clear(i); - - HPM->data_store_destroy(&map->list[i].hdata); - } - + for (int i = 0; i < map->count; i++) + map->clean(i); map->zone_db_clear(); - } static void map_zonedb_reload(void) { // first, reset maps to their initial zones: for (int i = 0; i < map->count; i++) { - map->zone_remove(i); + map->zone_remove_all(i); if (battle_config.pk_mode) { map->list[i].flag.pvp = 1; @@ -3779,7 +3740,8 @@ static void map_flags_init(void) map->list[i].short_damage_rate = 100; map->list[i].long_damage_rate = 100; - VECTOR_INIT(map->list[i].qi_data); + VECTOR_CLEAR(map->list[i].qi_list); + VECTOR_INIT(map->list[i].qi_list); } } @@ -3807,8 +3769,29 @@ static int map_waterheight(char *mapname) // read & convert fn rsw = grfio_read(fn); if (rsw) { + if (memcmp(rsw, "GRSW", 4) != 0) { + ShowWarning("Failed to find water level for %s (%s)\n", mapname, fn); + aFree(rsw); + return NO_WATER; + } + int major_version = rsw[4]; + int minor_version = rsw[5]; + if (major_version > 2 || (major_version == 2 && minor_version > 2)) { + ShowWarning("Failed to find water level for %s (%s)\n", mapname, fn); + aFree(rsw); + return NO_WATER; + } + if (major_version < 1 || (major_version == 1 && minor_version <= 4)) { + ShowWarning("Failed to find water level for %s (%s)\n", mapname, fn); + aFree(rsw); + return NO_WATER; + } + int offset = 166; + if (major_version == 2 && minor_version >= 2) { + offset = 167; + } //Load water height from file - int wh = (int) *(float*)(rsw+166); + int wh = (int)*(float*)(rsw + offset); aFree(rsw); return wh; } @@ -4092,6 +4075,7 @@ static bool map_config_read_database(const char *filename, struct config_t *conf return false; } libconfig->setting_lookup_mutable_string(setting, "db_path", map->db_path, sizeof(map->db_path)); + libconfig->set_db_path(map->db_path); libconfig->setting_lookup_int(setting, "save_settings", &map->save_settings); if (libconfig->setting_lookup_int(setting, "autosave_time", &map->autosave_interval) == CONFIG_TRUE) { @@ -4467,6 +4451,7 @@ static bool inter_config_read_database_names(const char *filename, const struct libconfig->setting_lookup_mutable_string(setting, "autotrade_merchants_db", map->autotrade_merchants_db, sizeof(map->autotrade_merchants_db)); libconfig->setting_lookup_mutable_string(setting, "autotrade_data_db", map->autotrade_data_db, sizeof(map->autotrade_data_db)); libconfig->setting_lookup_mutable_string(setting, "npc_market_data_db", map->npc_market_data_db, sizeof(map->npc_market_data_db)); + libconfig->setting_lookup_mutable_string(setting, "npc_barter_data_db", map->npc_barter_data_db, sizeof(map->npc_barter_data_db)); if (!mapreg->config_read(filename, setting, imported)) retval = false; @@ -4676,6 +4661,27 @@ static void map_zone_remove(int m) map->list[m].zone_mf = NULL; map->list[m].zone_mf_count = 0; } +// this one removes every flag, even if they were previously turned on before +// the current zone was applied +static void map_zone_remove_all(int m) +{ + Assert_retv(m >= 0 && m < map->count); + + for (unsigned short k = 0; k < map->list[m].zone_mf_count; k++) { + char flag[MAP_ZONE_MAPFLAG_LENGTH]; + + memcpy(flag, map->list[m].zone_mf[k], MAP_ZONE_MAPFLAG_LENGTH); + strtok(flag, "\t"); + + npc->parse_mapflag(map->list[m].name, "", flag, "off", "", "", "", NULL); + aFree(map->list[m].zone_mf[k]); + map->list[m].zone_mf[k] = NULL; + } + + aFree(map->list[m].zone_mf); + map->list[m].zone_mf = NULL; + map->list[m].zone_mf_count = 0; +} static inline void map_zone_mf_cache_add(int m, char *rflag) { Assert_retv(m >= 0 && m < map->count); @@ -5392,6 +5398,32 @@ static bool map_zone_mf_cache(int m, char *flag, char *params) else if( map->list[m].flag.nocashshop ) map_zone_mf_cache_add(m,"nocashshop"); } + } else if (strcmpi(flag, "nostorage") == 0) { + if (!state) { + if (map->list[m].flag.nostorage != 0) { + sprintf(rflag, "nostorage\t%d", map->list[m].flag.nostorage); + map_zone_mf_cache_add(m, rflag); + } + } + if (sscanf(params, "%d", &state) == 1) { + if (state != map->list[m].flag.nostorage) { + sprintf(rflag, "nostorage\t%d", state); + map_zone_mf_cache_add(m, rflag); + } + } + } else if (strcmpi(flag, "nogstorage") == 0) { + if (!state) { + if (map->list[m].flag.nogstorage != 0) { + sprintf(rflag, "nogstorage\t%d", map->list[m].flag.nogstorage); + map_zone_mf_cache_add(m, rflag); + } + } + if (sscanf(params, "%d", &state) == 1) { + if (state != map->list[m].flag.nogstorage) { + sprintf(rflag, "nogstorage\t%d", state); + map_zone_mf_cache_add(m, rflag); + } + } } return false; @@ -5563,12 +5595,8 @@ static void read_map_zone_db(void) { struct config_t map_zone_db; struct config_setting_t *zones = NULL; - /* TODO: #ifndef required for re/pre-re */ -#ifdef RENEWAL - const char *config_filename = "db/re/map_zone_db.conf"; // FIXME hardcoded name -#else - const char *config_filename = "db/pre-re/map_zone_db.conf"; // FIXME hardcoded name -#endif + char config_filename[256]; + libconfig->format_db_path(DBPATH"map_zone_db.conf", config_filename, sizeof(config_filename)); if (!libconfig->load_file(&map_zone_db, config_filename)) return; @@ -5993,28 +6021,30 @@ static int map_get_new_bonus_id(void) return map->bonus_id++; } -static void map_add_questinfo(int m, struct questinfo *qi) +static bool map_add_questinfo(int m, struct npc_data *nd) { - nullpo_retv(qi); - Assert_retv(m >= 0 && m < map->count); + nullpo_retr(false, nd); + Assert_retr(false, m >= 0 && m < map->count); + + if (&VECTOR_LAST(map->list[m].qi_list) == nd) + return false; - VECTOR_ENSURE(map->list[m].qi_data, 1, 1); - VECTOR_PUSH(map->list[m].qi_data, *qi); + VECTOR_ENSURE(map->list[m].qi_list, 1, 1); + VECTOR_PUSH(map->list[m].qi_list, *nd); + return true; } static bool map_remove_questinfo(int m, struct npc_data *nd) { - unsigned short i; nullpo_retr(false, nd); Assert_retr(false, m >= 0 && m < map->count); - for (i = 0; i < VECTOR_LENGTH(map->list[m].qi_data); i++) { - struct questinfo *qi_data = &VECTOR_INDEX(map->list[m].qi_data, i); - if (qi_data->nd == nd) { - VECTOR_ERASE(map->list[m].qi_data, i); - return true; - } + int i; + ARR_FIND(0, VECTOR_LENGTH(map->list[m].qi_list), i, &VECTOR_INDEX(map->list[m].qi_list, i) == nd); + if (i != VECTOR_LENGTH(map->list[m].qi_list)) { + VECTOR_ERASE(map->list[m].qi_list, i); + return true; } return false; } @@ -6155,6 +6185,7 @@ int do_final(void) atcommand->final_msg(); skill->final(); status->final(); + refine->final(); unit->final(); bg->final(); duel->final(); @@ -6163,6 +6194,7 @@ int do_final(void) vending->final(); rodex->final(); achievement->final(); + stylist->final(); HPM_map_do_final(); @@ -6290,6 +6322,7 @@ static CPCMD(gm_position) map->cpsd->bl.x = x; map->cpsd->bl.y = y; map->cpsd->bl.m = m; + map->cpsd->mapindex = map_id2index(m); } static CPCMD(gm_use) { @@ -6318,6 +6351,8 @@ static void map_cp_defaults(void) map->cpsd->bl.x = mapindex->default_x; map->cpsd->bl.y = mapindex->default_y; map->cpsd->bl.m = map->mapname2mapid(mapindex->default_map); + Assert_retv(map->cpsd->bl.m >= 0); + map->cpsd->mapindex = map_id2index(map->cpsd->bl.m); console->input->addCommand("gm:info",CPCMD_A(gm_position)); console->input->addCommand("gm:use",CPCMD_A(gm_use)); @@ -6370,6 +6405,8 @@ static void map_load_defaults(void) achievement_defaults(); npc_chat_defaults(); rodex_defaults(); + stylist_defaults(); + refine_defaults(); } /** * --run-once handler @@ -6674,6 +6711,7 @@ int do_init(int argc, char *argv[]) map->read_zone_db();/* read after item and skill initialization */ mob->init(minimal); pc->init(minimal); + refine->init(minimal); status->init(minimal); party->init(minimal); guild->init(minimal); @@ -6684,6 +6722,7 @@ int do_init(int argc, char *argv[]) elemental->init(minimal); quest->init(minimal); achievement->init(minimal); + stylist->init(minimal); npc->init(minimal); unit->init(minimal); bg->init(minimal); @@ -6709,6 +6748,7 @@ int do_init(int argc, char *argv[]) npc->event_do_oninit( false ); // Init npcs (OnInit) npc->market_fromsql(); /* after OnInit */ + npc->barter_fromsql(); /* after OnInit */ if (battle_config.pk_mode) ShowNotice("Server is running on '"CL_WHITE"PK Mode"CL_RESET"'.\n"); @@ -6754,6 +6794,7 @@ void map_defaults(void) map->extra_scripts_count = 0; sprintf(map->db_path ,"db"); + libconfig->set_db_path(map->db_path); sprintf(map->help_txt ,"conf/help.txt"); sprintf(map->charhelp_txt ,"conf/charhelp.txt"); @@ -6815,7 +6856,10 @@ void map_defaults(void) map->bl_list_size = 0; //all in a big chunk, respects order +PRAGMA_GCC9(GCC diagnostic push) +PRAGMA_GCC9(GCC diagnostic ignored "-Warray-bounds") memset(ZEROED_BLOCK_POS(map), 0, ZEROED_BLOCK_SIZE(map)); +PRAGMA_GCC9(GCC diagnostic pop) map->cpsd = NULL; map->list = NULL; @@ -6828,6 +6872,7 @@ void map_defaults(void) /* funcs */ map->zone_init = map_zone_init; map->zone_remove = map_zone_remove; + map->zone_remove_all = map_zone_remove_all; map->zone_apply = map_zone_apply; map->zone_change = map_zone_change; map->zone_change2 = map_zone_change2; @@ -6901,6 +6946,7 @@ void map_defaults(void) map->foreachinpath = map_foreachinpath; map->vforeachinmap = map_vforeachinmap; map->foreachinmap = map_foreachinmap; + map->forcountinmap = map_forcountinmap; map->vforeachininstance = map_vforeachininstance; map->foreachininstance = map_foreachininstance; |