diff options
Diffstat (limited to 'src/map/map.c')
-rw-r--r-- | src/map/map.c | 274 |
1 files changed, 148 insertions, 126 deletions
diff --git a/src/map/map.c b/src/map/map.c index 343f219b8..332bbe75f 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -56,7 +56,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 +637,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 +2268,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 +2294,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 +3584,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 +3613,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 +3741,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); } } @@ -4467,6 +4430,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 +4640,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 +5377,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; @@ -5993,28 +6004,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 +6168,7 @@ int do_final(void) atcommand->final_msg(); skill->final(); status->final(); + refine->final(); unit->final(); bg->final(); duel->final(); @@ -6163,6 +6177,7 @@ int do_final(void) vending->final(); rodex->final(); achievement->final(); + stylist->final(); HPM_map_do_final(); @@ -6370,6 +6385,8 @@ static void map_load_defaults(void) achievement_defaults(); npc_chat_defaults(); rodex_defaults(); + stylist_defaults(); + refine_defaults(); } /** * --run-once handler @@ -6674,6 +6691,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); @@ -6690,6 +6708,7 @@ int do_init(int argc, char *argv[]) duel->init(minimal); vending->init(minimal); rodex->init(minimal); + stylist->init(minimal); if (map->scriptcheck) { bool failed = map->extra_scripts_count > 0 ? false : true; @@ -6709,6 +6728,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"); @@ -6828,6 +6848,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 +6922,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; |