From 90f117f6b071c9c12bb8b521b6de46301639e75c Mon Sep 17 00:00:00 2001 From: shennetsind Date: Wed, 27 Mar 2013 13:22:55 -0300 Subject: Introducing Hercules' Map Zone Database Click the link for full info~! http://hercules.ws/board/topic/302-introducing-hercules-map-zone-database/ Signed-off-by: shennetsind --- src/map/atcommand.c | 32 ++--- src/map/clif.h | 4 + src/map/itemdb.c | 22 ---- src/map/itemdb.h | 3 +- src/map/map.c | 331 +++++++++++++++++++++++++++++++++++++++++++++++++++- src/map/map.h | 33 ++++-- src/map/mob.c | 3 +- src/map/npc.c | 66 ++++++----- src/map/npc.h | 1 + src/map/pc.c | 23 ++-- src/map/script.c | 56 ++++----- src/map/skill.c | 38 ++---- src/map/skill.h | 2 - src/map/status.c | 47 +++----- 14 files changed, 480 insertions(+), 181 deletions(-) (limited to 'src') diff --git a/src/map/atcommand.c b/src/map/atcommand.c index d563ba126..2e7c74b94 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -3795,16 +3795,16 @@ ACMD_FUNC(reloadscript) * 0 = no additional information * 1 = Show users in that map and their location * 2 = Shows NPCs in that map - * 3 = Shows the shops/chats in that map (not implemented) + * 3 = Shows the chats in that map + TODO# add the missing mapflags e.g. adjust_skill_damage to display *------------------------------------------*/ -ACMD_FUNC(mapinfo) -{ +ACMD_FUNC(mapinfo) { struct map_session_data* pl_sd; struct s_mapiterator* iter; struct npc_data *nd = NULL; struct chat_data *cd = NULL; char direction[12]; - int i, m_id, chat_num, list = 0; + int i, m_id, chat_num = 0, list = 0, vend_num = 0; unsigned short m_index; char mapname[24]; @@ -3839,12 +3839,17 @@ ACMD_FUNC(mapinfo) // count chats (for initial message) chat_num = 0; iter = mapit_getallusers(); - for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) ) - if( (cd = (struct chat_data*)map_id2bl(pl_sd->chatID)) != NULL && pl_sd->mapindex == m_index && cd->usersd[0] == pl_sd ) - chat_num++; + for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) ) { + if( pl_sd->mapindex == m_index ) { + if( sd->state.vending ) + vend_num++; + else if( (cd = (struct chat_data*)map_id2bl(pl_sd->chatID)) != NULL && cd->usersd[0] == pl_sd ) + chat_num++; + } + } mapit_free(iter); - sprintf(atcmd_output, msg_txt(1040), mapname, map[m_id].users, map[m_id].npc_num, chat_num); // Map Name: %s | Players In Map: %d | NPCs In Map: %d | Chats In Map: %d + sprintf(atcmd_output, msg_txt(1040), mapname, map[m_id].zone->name, map[m_id].users, map[m_id].npc_num, chat_num, vend_num); // Map: %s (Zone:%s) | Players: %d | NPCs: %d | Chats: %d | Vendings: %d clif_displaymessage(fd, atcmd_output); clif_displaymessage(fd, msg_txt(1041)); // ------ Map Flags ------ if (map[m_id].flag.town) @@ -3932,11 +3937,6 @@ ACMD_FUNC(mapinfo) strcat(atcmd_output, msg_txt(1077)); // Fireworks | if (map[m_id].flag.leaves) strcat(atcmd_output, msg_txt(1078)); // Leaves | - /** - * No longer available, keeping here just in case it's back someday. [Ind] - **/ - //if (map[m_id].flag.rain) - // strcat(atcmd_output, msg_txt(1079)); // Rain | if (map[m_id].flag.nightenabled) strcat(atcmd_output, msg_txt(1080)); // Displays Night | clif_displaymessage(fd, atcmd_output); @@ -7635,7 +7635,7 @@ ACMD_FUNC(mapflag) { checkflag(fog); checkflag(fireworks); checkflag(sakura); checkflag(leaves); checkflag(nogo); checkflag(nobaseexp); checkflag(nojobexp); checkflag(nomobloot); checkflag(nomvploot); checkflag(nightenabled); - checkflag(restricted); checkflag(nodrop); checkflag(novending); checkflag(loadevent); + checkflag(nodrop); checkflag(novending); checkflag(loadevent); checkflag(nochat); checkflag(partylock); checkflag(guildlock); checkflag(src4instance); clif_displaymessage(sd->fd," "); clif_displaymessage(sd->fd,msg_txt(1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On) @@ -7654,7 +7654,7 @@ ACMD_FUNC(mapflag) { setflag(fog); setflag(fireworks); setflag(sakura); setflag(leaves); setflag(nogo); setflag(nobaseexp); setflag(nojobexp); setflag(nomobloot); setflag(nomvploot); setflag(nightenabled); - setflag(restricted); setflag(nodrop); setflag(novending); setflag(loadevent); + setflag(nodrop); setflag(novending); setflag(loadevent); setflag(nochat); setflag(partylock); setflag(guildlock); setflag(src4instance); clif_displaymessage(sd->fd,msg_txt(1314)); // Invalid flag name or flag. @@ -7666,7 +7666,7 @@ ACMD_FUNC(mapflag) { clif_displaymessage(sd->fd,"pvp_nocalcrank, gvg_castle, gvg, gvg_dungeon, gvg_noparty, battleground,"); clif_displaymessage(sd->fd,"nozenypenalty, notrade, noskill, nowarp, nowarpto, noicewall, snow, clouds, clouds2,"); clif_displaymessage(sd->fd,"fog, fireworks, sakura, leaves, nogo, nobaseexp, nojobexp, nomobloot,"); - clif_displaymessage(sd->fd,"nomvploot, nightenabled, restricted, nodrop, novending, loadevent, nochat, partylock,"); + clif_displaymessage(sd->fd,"nomvploot, nightenabled, nodrop, novending, loadevent, nochat, partylock,"); clif_displaymessage(sd->fd,"guildlock, src4instance"); #undef checkflag diff --git a/src/map/clif.h b/src/map/clif.h index 8e0fc6629..1c04ae393 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -314,6 +314,10 @@ enum useskill_fail_cause USESKILL_FAIL_THERE_ARE_NPC_AROUND = 83, }; +enum clif_messages { + SKILL_CANT_USE_AREA = 0x536, +}; + int clif_setip(const char* ip); void clif_setbindip(const char* ip); void clif_setport(uint16 port); diff --git a/src/map/itemdb.c b/src/map/itemdb.c index 79d303085..a91946b2a 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -585,27 +585,6 @@ static void itemdb_read_itemgroup(void) return; } -/*========================================== - * Read item forbidden by mapflag (can't equip item) - *------------------------------------------*/ -static bool itemdb_read_noequip(char* str[], int columns, int current) -{// , - int nameid; - struct item_data *id; - - nameid = atoi(str[0]); - - if( ( id = itemdb_exists(nameid) ) == NULL ) - { - ShowWarning("itemdb_read_noequip: Invalid item id %d.\n", nameid); - return false; - } - - id->flag.no_equip |= atoi(str[1]); - - return true; -} - /*========================================== * Reads item trade restrictions [Skotlex] *------------------------------------------*/ @@ -1310,7 +1289,6 @@ static void itemdb_read(void) { itemdb_read_combos(); itemdb_read_itemgroup(); sv_readdb(db_path, "item_avail.txt", ',', 2, 2, -1, &itemdb_read_itemavail); - sv_readdb(db_path, DBPATH"item_noequip.txt", ',', 2, 2, -1, &itemdb_read_noequip); sv_readdb(db_path, DBPATH"item_trade.txt", ',', 3, 3, -1, &itemdb_read_itemtrade); sv_readdb(db_path, "item_delay.txt", ',', 2, 2, -1, &itemdb_read_itemdelay); sv_readdb(db_path, "item_stack.txt", ',', 3, 3, -1, &itemdb_read_stack); diff --git a/src/map/itemdb.h b/src/map/itemdb.h index e308b248b..06c95da8a 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -66,7 +66,7 @@ enum { ITEMID_CAMOUFLAGE_GENERATOR, ITEMID_HIGH_QUALITY_COOLER, ITEMID_SPECIAL_COOLER, - } mecha_item_list; +} mecha_item_list; //The only item group required by the code to be known. See const.txt for the full list. #define IG_FINDINGORE 6 @@ -123,7 +123,6 @@ struct item_data { struct script_code *unequip_script;//Script executed once when unequipping. struct { unsigned available : 1; - short no_equip; unsigned no_refine : 1; // [celest] unsigned delay_consume : 1; // Signifies items that are not consumed immediately upon double-click [Skotlex] unsigned trade_restriction : 9; //Item restrictions mask [Skotlex] diff --git a/src/map/map.c b/src/map/map.c index bd0d97ece..a7b8513f7 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -13,6 +13,7 @@ #include "../common/random.h" #include "../common/strlib.h" #include "../common/utils.h" +#include "../common/conf.h" #include "map.h" #include "path.h" @@ -2892,6 +2893,31 @@ 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)) { + aFree(zone->disabled_skills); + aFree(zone->disabled_items); + for(i = 0; i < zone->mapflags_count; i++) { + aFree(zone->mapflags[i]); + } + aFree(zone->mapflags); + } + dbi_destroy(iter); + + db_destroy(zone_db);/* will aFree(zone) */ + + /* clear the main zone stuff */ + 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); +} void do_final_maps(void) { int i, v = 0; @@ -2931,11 +2957,12 @@ void do_final_maps(void) { } map[i].skill_count = 0; } - + } + map_zone_db_clear(); + } - /// Initializes map flags and adjusts them depending on configuration. void map_flags_init(void) { int i, v = 0; @@ -2945,7 +2972,6 @@ void map_flags_init(void) { 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 @@ -2968,10 +2994,12 @@ void map_flags_init(void) { } map[i].skills = NULL; map[i].skill_count = 0; - + // adjustments if( battle_config.pk_mode ) map[i].flag.pvp = 1; // make all maps pvp for pk_mode [Valaris] + /* align with 'All' zone */ + map[i].zone = &map_zone_all; } } @@ -3533,6 +3561,296 @@ int log_sql_init(void) #endif return 0; } +void map_zone_apply(int m, struct map_zone_data *zone,char* w1, const char* start, const char* buffer, const char* filepath) { + int i; + char empty[1] = "\0"; + map[m].zone = zone; + for(i = 0; i < zone->mapflags_count; i++) { + char flag[MAP_ZONE_MAPFLAG_LENGTH], params[MAP_ZONE_MAPFLAG_LENGTH]; + 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; + } + } + npc_parse_mapflag(w1,empty,flag,params,start,buffer,filepath); + } +} +/* used on npc load and reload to apply all "Normal" zone */ +void map_zone_init(void) { + 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++) { + char flag[MAP_ZONE_MAPFLAG_LENGTH], params[MAP_ZONE_MAPFLAG_LENGTH]; + 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 == &map_zone_all ) { + npc_parse_mapflag(map[j].name,empty,flag,params,empty,empty,empty); + } + } + } + +} +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.txt"; // FIXME hardcoded name +#else + const char *config_filename = "db/pre-re/map_zone_db.txt"; // 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; + struct item_data *data; + config_setting_t *zone_e; + config_setting_t *skills; + config_setting_t *items; + config_setting_t *mapflags; + const char *name; + const char *zonename; + int i,h; + int zone_count = 0, disabled_skills_count = 0, disabled_items_count = 0, mapflags_count = 0; + + 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_ALL_NAME,MAP_ZONE_NAME_LENGTH) == 0 ) { + zone = &map_zone_all; + 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( !strdb_exists(skilldb_name2id,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( !config_setting_get_bool(skill) )/* we dont remove it from the three due to inheritance */ + --disabled_skills_count; + } + /* all ok, process */ + CREATE( zone->disabled_skills, int, disabled_skills_count ); + for(h = 0; h < disabled_skills_count; h++) { + config_setting_t *skill = config_setting_get_elem(skills, h); + + name = config_setting_name(skill); + + if( config_setting_get_bool(skill) )/* only add if enabled */ + zone->disabled_skills[h] = strdb_iget(skilldb_name2id, name); + + } + 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); + data = itemdb_searchname(name); + if( data == NULL ) { + 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; h < disabled_items_count; 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); + data = itemdb_searchname(name); + zone->disabled_items[h] = data->nameid; + } + + } + 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( !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; + + zone_e = config_setting_get_elem(zones, i); + + if( (inherit_tree = config_setting_get_member(zone_e, "inherit")) != NULL ) { + int 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 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; + } + + 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; + + /* process everything to override, paying attention to config_setting_get_bool */ + if( (skills = config_setting_get_member(zone_e, "disabled_skills")) != NULL ) { + 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( strdb_iget(skilldb_name2id, config_setting_name(skill)) == izone->disabled_skills[j] ) { + if( config_setting_get_bool(skill) ) + continue; + break; + } + } + if( k == disabled_skills_count ) {/* we didn't find it */ + RECREATE( zone->disabled_skills, int, ++zone->disabled_skills_count ); + zone->disabled_skills[zone->disabled_skills_count-1] = izone->disabled_skills[j]; + } + } + } + + if( (items = config_setting_get_member(zone_e, "disabled_items")) != NULL ) { + 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); + data = itemdb_searchname(name); + + if( data->nameid == 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 = config_setting_get_member(zone_e, "mapflags")) != NULL ) { + 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); + } + } + } + } + } + } + + 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 @@ -3632,7 +3950,7 @@ void do_final(void) id_db->foreach(id_db,cleanup_db_sub); chrif_char_reset_offline(); chrif_flush_fifo(); - + do_final_atcommand(); battle->final(); do_final_chrif(); @@ -3933,7 +4251,9 @@ 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_sql_init(); if (log_config.sql_logs) log_sql_init(); @@ -3957,6 +4277,7 @@ int do_init(int argc, char *argv[]) do_init_script(); do_init_itemdb(); skill->init(); + read_map_zone_db();/* read after item and skill initalization */ do_init_mob(); do_init_pc(); do_init_status(); diff --git a/src/map/map.h b/src/map/map.h index 38d9726cb..cd5983686 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -11,9 +11,6 @@ #include "../common/mapindex.h" #include "../common/db.h" -/** - * [rAthena.org] - **/ #include "../config/core.h" #include @@ -21,8 +18,7 @@ struct npc_data; struct item_data; -enum E_MAPSERVER_ST -{ +enum E_MAPSERVER_ST { MAPSERVER_ST_RUNNING = CORE_ST_LAST, MAPSERVER_ST_SHUTDOWN, MAPSERVER_ST_LAST @@ -501,6 +497,28 @@ struct mapflag_skill_adjust { unsigned short modifier; }; +#define MAP_ZONE_NAME_LENGTH 30 +#define MAP_ZONE_ALL_NAME "Normal" +#define MAP_ZONE_PVP_NAME "PvP" +#define MAP_ZONE_GVG_NAME "GvG" +#define MAP_ZONE_BG_NAME "Battlegrounds" +#define MAP_ZONE_MAPFLAG_LENGTH 50 +DBMap *zone_db;/* string => struct map_zone_data */ +struct map_zone_data { + char name[MAP_ZONE_NAME_LENGTH];/* 20'd */ + int *disabled_skills; + int disabled_skills_count; + int *disabled_items; + int disabled_items_count; + char **mapflags; + int mapflags_count; +}; +void map_zone_init(void); +void map_zone_apply(int m, struct map_zone_data *zone,char* w1, const char* start, const char* buffer, const char* filepath); + +struct map_zone_data map_zone_all;/* used as a base on all maps */ + + struct map_data { char name[MAP_NAME_LENGTH]; uint16 index; // The map index used by the mapindex* functions. @@ -559,7 +577,6 @@ struct map_data { unsigned nomobloot : 1; // [Lorky] unsigned nomvploot : 1; // [Lorky] unsigned nightenabled :1; //For night display. [Skotlex] - unsigned restricted : 1; // [Komurka] unsigned nodrop : 1; unsigned novending : 1; unsigned loadevent : 1; @@ -579,7 +596,6 @@ struct map_data { struct spawn_data *moblist[MAX_MOB_LIST_PER_MAP]; // [Wizputer] int mob_delete_timer; // [Skotlex] - int zone; // zone number (for item/skill restrictions) int jexp; // map experience multiplicator int bexp; // map experience multiplicator int nocommand; //Blocks @/# commands for non-gms. [Skotlex] @@ -600,6 +616,9 @@ struct map_data { /* adjust_skill_damage mapflag */ struct mapflag_skill_adjust **skills; unsigned short skill_count; + + /* Hercules nocast db overhaul */ + struct map_zone_data *zone; }; /// Stores information about a remote map (for multi-mapserver setups). diff --git a/src/map/mob.c b/src/map/mob.c index fa4bd5c7f..71b500491 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -3389,8 +3389,7 @@ int mob_clone_spawn(struct map_session_data *sd, int16 m, int16 x, int16 y, cons for (i=0,j = MAX_SKILL_TREE-1;j>=0 && i< MAX_MOBSKILL ;j--) { skill_id = skill_tree[pc_class2idx(sd->status.class_)][j].id; if (!skill_id || sd->status.skill[skill_id].lv < 1 || - (skill->get_inf2(skill_id)&(INF2_WEDDING_SKILL|INF2_GUILD_SKILL)) || - skill->get_nocast(skill_id)&16 + (skill->get_inf2(skill_id)&(INF2_WEDDING_SKILL|INF2_GUILD_SKILL)) ) continue; //Normal aggressive mob, disable skills that cannot help them fight diff --git a/src/map/npc.c b/src/map/npc.c index 0c9924d46..797fc7422 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -3157,14 +3157,12 @@ static const char* npc_parse_mob(char* w1, char* w2, char* w3, char* w4, const c return strchr(start,'\n');// continue } - /*========================================== * Set or disable mapflag on map * eg : bat_c01 mapflag battleground 2 * also chking if mapflag conflict with another *------------------------------------------*/ -static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath) -{ +const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath) { int16 m; char mapname[32]; int state = 1; @@ -3231,19 +3229,21 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con map[m].flag.nozenypenalty=state; } else if (!strcmpi(w3,"pvp")) { + struct map_zone_data *zone; map[m].flag.pvp = state; - if( state && (map[m].flag.gvg || map[m].flag.gvg_dungeon || map[m].flag.gvg_castle) ) - { + if( state && (map[m].flag.gvg || map[m].flag.gvg_dungeon || map[m].flag.gvg_castle) ) { map[m].flag.gvg = 0; map[m].flag.gvg_dungeon = 0; map[m].flag.gvg_castle = 0; ShowWarning("npc_parse_mapflag: You can't set PvP and GvG flags for the same map! Removing GvG flags from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer)); } - if( state && map[m].flag.battleground ) - { + if( state && map[m].flag.battleground ) { map[m].flag.battleground = 0; ShowWarning("npc_parse_mapflag: You can't set PvP and BattleGround flags for the same map! Removing BattleGround flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer)); } + if( (zone = strdb_get(zone_db, MAP_ZONE_GVG_NAME)) && map[m].zone != zone ) { + map_zone_apply(m,zone,w1,start,buffer,filepath); + } } else if (!strcmpi(w3,"pvp_noparty")) map[m].flag.pvp_noparty=state; @@ -3283,17 +3283,20 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con else if (!strcmpi(w3,"pvp_nocalcrank")) map[m].flag.pvp_nocalcrank=state; else if (!strcmpi(w3,"gvg")) { + struct map_zone_data *zone; + map[m].flag.gvg = state; - if( state && map[m].flag.pvp ) - { + if( state && map[m].flag.pvp ) { map[m].flag.pvp = 0; ShowWarning("npc_parse_mapflag: You can't set PvP and GvG flags for the same map! Removing PvP flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer)); } - if( state && map[m].flag.battleground ) - { + if( state && map[m].flag.battleground ) { map[m].flag.battleground = 0; ShowWarning("npc_parse_mapflag: You can't set GvG and BattleGround flags for the same map! Removing BattleGround flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer)); } + if( (zone = strdb_get(zone_db, MAP_ZONE_GVG_NAME)) && map[m].zone != zone ) { + map_zone_apply(m,zone,w1,start,buffer,filepath); + } } else if (!strcmpi(w3,"gvg_noparty")) map[m].flag.gvg_noparty=state; @@ -3306,28 +3309,29 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con if (state) map[m].flag.pvp=0; } else if (!strcmpi(w3,"battleground")) { - if( state ) - { + struct map_zone_data *zone; + if( state ) { if( sscanf(w4, "%d", &state) == 1 ) map[m].flag.battleground = state; else map[m].flag.battleground = 1; // Default value - } - else + } else map[m].flag.battleground = 0; - if( map[m].flag.battleground && map[m].flag.pvp ) - { + if( map[m].flag.battleground && map[m].flag.pvp ) { map[m].flag.pvp = 0; ShowWarning("npc_parse_mapflag: You can't set PvP and BattleGround flags for the same map! Removing PvP flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer)); } - if( map[m].flag.battleground && (map[m].flag.gvg || map[m].flag.gvg_dungeon || map[m].flag.gvg_castle) ) - { + if( map[m].flag.battleground && (map[m].flag.gvg || map[m].flag.gvg_dungeon || map[m].flag.gvg_castle) ) { map[m].flag.gvg = 0; map[m].flag.gvg_dungeon = 0; map[m].flag.gvg_castle = 0; ShowWarning("npc_parse_mapflag: You can't set GvG and BattleGround flags for the same map! Removing GvG flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer)); } + + if( (zone = strdb_get(zone_db, MAP_ZONE_BG_NAME)) && map[m].zone != zone ) { + map_zone_apply(m,zone,w1,start,buffer,filepath); + } } else if (!strcmpi(w3,"noexppenalty")) map[m].flag.noexppenalty=state; @@ -3391,16 +3395,6 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con } else map[m].nocommand=0; } - else if (!strcmpi(w3,"restricted")) { - if (state) { - map[m].flag.restricted=1; - sscanf(w4, "%d", &state); - map[m].zone |= 1<<(state+1); - } else { - map[m].flag.restricted=0; - map[m].zone = 0; - } - } else if (!strcmpi(w3,"jexp")) { map[m].jexp = (state) ? atoi(w4) : 100; if( map[m].jexp < 0 ) map[m].jexp = 100; @@ -3459,6 +3453,14 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con map[m].skills[idx]->skill_id = (unsigned short)skill_id; map[m].skills[idx]->modifier = (unsigned short)atoi(mod); } + } else if (!strcmpi(w3,"zone")) { + struct map_zone_data *zone; + + if( !(zone = strdb_get(zone_db, w4)) ) { + ShowWarning("npc_parse_mapflag: Invalid zone '%s'! removing flag from %s (file '%s', line '%d').\n", w4, map[m].name, filepath, strline(buffer,start-buffer)); + } else if( map[m].zone != zone ) { /* we do not override :P would mess everything */ + map_zone_apply(m,zone,w1,start,buffer,filepath); + } } else ShowError("npc_parse_mapflag: unrecognized mapflag '%s' (file '%s', line '%d').\n", w3, filepath, strline(buffer,start-buffer)); @@ -3792,12 +3794,14 @@ int npc_reload(void) { "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Cached\n" "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n", npc_id - npc_new_min, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob); - + do_final_instance(); for( i = 0; i < ARRAYLENGTH(instance); ++i ) instance_init(instance[i].instance_id); + map_zone_init(); + //Re-read the NPC Script Events cache. npc_read_event_script(); @@ -3926,6 +3930,8 @@ int do_init_npc(void) "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n", npc_id - START_NPC_NUM, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob); + map_zone_init(); + // set up the events cache memset(script_event, 0, sizeof(script_event)); npc_read_event_script(); diff --git a/src/map/npc.h b/src/map/npc.h index 20ce34459..424ff9312 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -124,6 +124,7 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type); int npc_buylist(struct map_session_data* sd,int n, unsigned short* item_list); int npc_selllist(struct map_session_data* sd, int n, unsigned short* item_list); void npc_parse_mob2(struct spawn_data* mob); +const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath); struct npc_data* npc_add_warp(char* name, short from_mapid, short from_x, short from_y, short xs, short ys, unsigned short to_mapindex, short to_x, short to_y); int npc_globalmessage(const char* name,const char* mes); diff --git a/src/map/pc.c b/src/map/pc.c index 4bd66a67c..840bf0c03 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -4227,12 +4227,13 @@ int pc_isUseitem(struct map_session_data *sd,int n) int pc_useitem(struct map_session_data *sd,int n) { unsigned int tick = gettick(); - int amount, nameid; + int amount, nameid, i; struct script_code *script; nullpo_ret(sd); if( sd->npc_id ){ + /* TODO: add to clif_messages enum */ #ifdef RENEWAL clif_msg(sd, 0x783); // TODO look for the client date that has this message. #endif @@ -4320,19 +4321,15 @@ int pc_useitem(struct map_session_data *sd,int n) } } - /* on restricted maps the item is consumed but the effect is not used */ - if ( - (!map_flag_vs(sd->bl.m) && sd->inventory_data[n]->flag.no_equip&1) || // Normal - (map[sd->bl.m].flag.pvp && sd->inventory_data[n]->flag.no_equip&2) || // PVP - (map_flag_gvg(sd->bl.m) && sd->inventory_data[n]->flag.no_equip&4) || // GVG - (map[sd->bl.m].flag.battleground && sd->inventory_data[n]->flag.no_equip&8) || // Battleground - (map[sd->bl.m].flag.restricted && sd->inventory_data[n]->flag.no_equip&(8*map[sd->bl.m].zone)) // Zone restriction - ) { - if( battle_config.item_restricted_consumption_type ) { - clif_useitemack(sd,n,sd->status.inventory[n].amount-1,true); - pc_delitem(sd,n,1,1,0,LOG_TYPE_CONSUME); + /* on restricted maps the item is consumed but the effect is not used */ + for(i = 0; i < map[sd->bl.m].zone->disabled_items_count; i++) { + if( map[sd->bl.m].zone->disabled_items[i] == nameid ) { + if( battle_config.item_restricted_consumption_type ) { + clif_useitemack(sd,n,sd->status.inventory[n].amount-1,true); + pc_delitem(sd,n,1,1,0,LOG_TYPE_CONSUME); + } + return 0; } - return 0;/* regardless, effect is not run */ } sd->itemid = sd->status.inventory[n].nameid; diff --git a/src/map/script.c b/src/map/script.c index 4c913651a..0e45f4821 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -384,7 +384,7 @@ enum { MF_NORETURN, MF_NOWARPTO, MF_NIGHTMAREDROP, - MF_RESTRICTED, + MF_ZONE, MF_NOCOMMAND, MF_NODROP, MF_JEXP, @@ -9558,8 +9558,8 @@ static int buildin_announce_sub(struct block_list *bl, va_list ap) return 0; } /* Runs item effect on attached character. - * consumeitem ; - * consumeitem ""; */ + * itemeffect ; + * itemeffect ""; */ BUILDIN_FUNC(itemeffect) { TBL_NPC *nd; TBL_PC *sd; @@ -9579,14 +9579,14 @@ BUILDIN_FUNC(itemeffect) { ShowError( "buildin_itemeffect: Nonexistant item %s requested.\n", name ); return 1; } - }else if( data_isint( data ) ){ + } else if( data_isint( data ) ){ int nameid = conv_num( st, data ); if( ( item_data = itemdb_exists( nameid ) ) == NULL ){ ShowError("buildin_itemeffect: Nonexistant item %d requested.\n", nameid ); return 1; } - }else{ + } else { ShowError("buildin_itemeffect: invalid data type for argument #1 (%d).", data->type ); return 1; } @@ -10707,10 +10707,6 @@ BUILDIN_FUNC(getmapflag) case MF_FOG: script_pushint(st,map[m].flag.fog); break; case MF_SAKURA: script_pushint(st,map[m].flag.sakura); break; case MF_LEAVES: script_pushint(st,map[m].flag.leaves); break; - /** - * No longer available, keeping here just in case it's back someday. [Ind] - **/ - //case MF_RAIN: script_pushint(st,map[m].flag.rain); break; case MF_NOGO: script_pushint(st,map[m].flag.nogo); break; case MF_CLOUDS: script_pushint(st,map[m].flag.clouds); break; case MF_CLOUDS2: script_pushint(st,map[m].flag.clouds2); break; @@ -10725,7 +10721,6 @@ BUILDIN_FUNC(getmapflag) case MF_NORETURN: script_pushint(st,map[m].flag.noreturn); break; case MF_NOWARPTO: script_pushint(st,map[m].flag.nowarpto); break; case MF_NIGHTMAREDROP: script_pushint(st,map[m].flag.pvp_nightmaredrop); break; - case MF_RESTRICTED: script_pushint(st,map[m].flag.restricted); break; case MF_NOCOMMAND: script_pushint(st,map[m].nocommand); break; case MF_NODROP: script_pushint(st,map[m].flag.nodrop); break; case MF_JEXP: script_pushint(st,map[m].jexp); break; @@ -10764,15 +10759,27 @@ static int script_mapflag_pvp_sub(struct block_list *bl,va_list ap) { BUILDIN_FUNC(setmapflag) { int16 m,i; - const char *str; + const char *str, *val2; + struct script_data* data; int val=0; str=script_getstr(st,2); - i=script_getnum(st,3); + + i = script_getnum(st, 3); + if(script_hasdata(st,4)){ - val=script_getnum(st,4); + data = script_getdata(st,4); + get_val(st, data); + + + if( data_isstring(data) ) + val2 = script_getstr(st, 4); + else + val = script_getnum(st, 4); + } m = map_mapname2mapid(str); + if(m >= 0) { switch(i) { case MF_NOMEMO: map[m].flag.nomemo = 1; break; @@ -10821,9 +10828,13 @@ BUILDIN_FUNC(setmapflag) case MF_NORETURN: map[m].flag.noreturn = 1; break; case MF_NOWARPTO: map[m].flag.nowarpto = 1; break; case MF_NIGHTMAREDROP: map[m].flag.pvp_nightmaredrop = 1; break; - case MF_RESTRICTED: - map[m].zone |= 1<<(val+1); - map[m].flag.restricted=1; + case MF_ZONE: { + char zone[6] = "zone\0"; + char empty[1] = "\0"; + char params[MAP_ZONE_MAPFLAG_LENGTH]; + memcpy(params, val2, MAP_ZONE_MAPFLAG_LENGTH); + npc_parse_mapflag(map[m].name, empty, zone, params, empty, empty, empty); + } break; case MF_NOCOMMAND: map[m].nocommand = (val <= 0) ? 100 : val; break; case MF_NODROP: map[m].flag.nodrop = 1; break; @@ -10887,10 +10898,6 @@ BUILDIN_FUNC(removemapflag) case MF_FOG: map[m].flag.fog = 0; break; case MF_SAKURA: map[m].flag.sakura = 0; break; case MF_LEAVES: map[m].flag.leaves = 0; break; - /** - * No longer available, keeping here just in case it's back someday. [Ind] - **/ - //case MF_RAIN: map[m].flag.rain = 0; break; case MF_NOGO: map[m].flag.nogo = 0; break; case MF_CLOUDS: map[m].flag.clouds = 0; break; case MF_CLOUDS2: map[m].flag.clouds2 = 0; break; @@ -10905,11 +10912,8 @@ BUILDIN_FUNC(removemapflag) case MF_NORETURN: map[m].flag.noreturn = 0; break; case MF_NOWARPTO: map[m].flag.nowarpto = 0; break; case MF_NIGHTMAREDROP: map[m].flag.pvp_nightmaredrop = 0; break; - case MF_RESTRICTED: - map[m].zone ^= 1<<(val+1); - if (map[m].zone == 0){ - map[m].flag.restricted=0; - } + case MF_ZONE:/* reset zone state, mapflags cant be removed however */ + map[m].zone = &map_zone_all; break; case MF_NOCOMMAND: map[m].nocommand = 0; break; case MF_NODROP: map[m].flag.nodrop = 0; break; @@ -17566,7 +17570,7 @@ struct script_function buildin_func[] = { BUILDIN_DEF(isloggedin,"i?"), BUILDIN_DEF(setmapflagnosave,"ssii"), BUILDIN_DEF(getmapflag,"si"), - BUILDIN_DEF(setmapflag,"si?"), + BUILDIN_DEF(setmapflag,"sv?"), BUILDIN_DEF(removemapflag,"si?"), BUILDIN_DEF(pvpon,"s"), BUILDIN_DEF(pvpoff,"s"), diff --git a/src/map/skill.c b/src/map/skill.c index 88111d898..3bd454357 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -212,7 +212,6 @@ int skill_get_blewcount( uint16 skill_id ,uint16 skill_lv ) { skill_get (skill_d int skill_get_mhp( uint16 skill_id ,uint16 skill_lv ) { skill_get (skill_db[skill_id].mhp[skill_lv-1], skill_id, skill_lv); } int skill_get_castnodex( uint16 skill_id ,uint16 skill_lv ) { skill_get (skill_db[skill_id].castnodex[skill_lv-1], skill_id, skill_lv); } int skill_get_delaynodex( uint16 skill_id ,uint16 skill_lv ){ skill_get (skill_db[skill_id].delaynodex[skill_lv-1], skill_id, skill_lv); } -int skill_get_nocast ( uint16 skill_id ) { skill_get (skill_db[skill_id].nocast, skill_id, 1); } int skill_get_type( uint16 skill_id ) { skill_get (skill_db[skill_id].skill_type, skill_id, 1); } int skill_get_unit_id ( uint16 skill_id, int flag ){ skill_get (skill_db[skill_id].unit_id[flag], skill_id, 1); } int skill_get_unit_interval( uint16 skill_id ) { skill_get (skill_db[skill_id].unit_interval, skill_id, 1); } @@ -478,6 +477,7 @@ int can_copy (struct map_session_data *sd, uint16 skill_id, struct block_list* b int skillnotok (uint16 skill_id, struct map_session_data *sd) { int16 idx,m; + int i; nullpo_retr (1, sd); m = sd->bl.m; idx = skill->get_index(skill_id); @@ -501,25 +501,23 @@ int skillnotok (uint16 skill_id, struct map_session_data *sd) return 1; } - if (sd->blockskill[idx] > 0){ + if (sd->blockskill[idx] > 0) { clif_skill_fail(sd, skill_id, USESKILL_FAIL_SKILLINTERVAL, 0); return 1; } + /** - * It has been confirmed on a official server (thanks to Yommy) that item-cast skills bypass all the restrictions above + * It has been confirmed on a official server (thanks to Yommy) that item-cast skills bypass all the restrictions below * Also, without this check, an exploit where an item casting + healing (or any other kind buff) isn't deleted after used on a restricted map **/ if( sd->skillitem == skill_id ) return 0; - /* TODO: these skill_get_nocast should be cached once instead of looking it up 5 times =_= */ - // Check skill restrictions [Celest] - if( (!map_flag_vs(m) && skill->get_nocast (skill_id) & 1) || - (map[m].flag.pvp && skill->get_nocast (skill_id) & 2) || - (map_flag_gvg(m) && skill->get_nocast (skill_id) & 4) || - (map[m].flag.battleground && skill->get_nocast (skill_id) & 8) || - (map[m].flag.restricted && map[m].zone && skill->get_nocast (skill_id) & (8*map[m].zone)) ){ - clif_msg(sd, 0x536); // This skill cannot be used within this area + + for(i = 0; i < map[m].zone->disabled_skills_count; i++) { + if( skill_id == map[m].zone->disabled_skills[i] ) { + clif_msg(sd, SKILL_CANT_USE_AREA); // This skill cannot be used within this area return 1; + } } if( sd->sc.option&OPTION_MOUNTING ) @@ -17476,18 +17474,6 @@ bool skill_parse_row_castnodexdb(char* split[], int columns, int current) { return true; } -bool skill_parse_row_nocastdb(char* split[], int columns, int current) { -// skill_id,Flag - uint16 skill_id = atoi(split[0]); - uint16 idx = skill->get_index(skill_id); - if( !idx ) // invalid skill id - return false; - - skill_db[idx].nocast |= atoi(split[1]); - - return true; -} - bool skill_parse_row_unitdb(char* split[], int columns, int current) { // ID,unit ID,unit ID 2,layout,range,interval,target,flag uint16 skill_id = atoi(split[0]); @@ -17734,8 +17720,6 @@ void skill_readdb(void) { sv_readdb(db_path, DBPATH"skill_castnodex_db.txt", ',', 2, 3, MAX_SKILL_DB, skill->parse_row_castnodexdb); sv_readdb(db_path, DBPATH"skill_unit_db.txt" , ',', 8, 8, MAX_SKILL_DB, skill->parse_row_unitdb); - sv_readdb(db_path, DBPATH"skill_nocast_db.txt" , ',', 2, 2, MAX_SKILL_DB, skill->parse_row_nocastdb); - skill->init_unit_layout(); sv_readdb(db_path, "produce_db.txt" , ',', 4, 4+2*MAX_PRODUCE_RESOURCE, MAX_SKILL_PRODUCE_DB, skill->parse_row_producedb); sv_readdb(db_path, "create_arrow_db.txt" , ',', 1+2, 1+2*MAX_ARROW_RESOURCE, MAX_SKILL_ARROW_DB, skill->parse_row_createarrowdb); @@ -17747,7 +17731,6 @@ void skill_readdb(void) { sv_readdb(db_path, "skill_reproduce_db.txt", ',', 1, 1, MAX_SKILL_DB, skill->parse_row_reproducedb); sv_readdb(db_path, "skill_improvise_db.txt" , ',', 2, 2, MAX_SKILL_IMPROVISE_DB, skill->parse_row_improvisedb); sv_readdb(db_path, "skill_changematerial_db.txt" , ',', 4, 4+2*5, MAX_SKILL_PRODUCE_DB, skill->parse_row_changematerialdb); - } void skill_reload (void) { @@ -17791,6 +17774,7 @@ int do_init_skill (void) int do_final_skill(void) { db_destroy(skilldb_name2id); + /* TODO: ZONE_DB IS NOT PROPERLY CLEARED */ db_destroy(group_db); db_destroy(skillunit_db); db_destroy(skillcd_db); @@ -17834,7 +17818,6 @@ void skill_defaults(void) { skill->get_weapontype = skill_get_weapontype; skill->get_ammotype = skill_get_ammotype; skill->get_ammo_qty = skill_get_ammo_qty; - skill->get_nocast = skill_get_nocast; skill->get_unit_id = skill_get_unit_id; skill->get_inf2 = skill_get_inf2; skill->get_castcancel = skill_get_castcancel; @@ -17967,7 +17950,6 @@ void skill_defaults(void) { skill->parse_row_castdb = skill_parse_row_castdb; skill->parse_row_castnodexdb = skill_parse_row_castnodexdb; skill->parse_row_unitdb = skill_parse_row_unitdb; - skill->parse_row_nocastdb = skill_parse_row_nocastdb; skill->parse_row_producedb = skill_parse_row_producedb; skill->parse_row_createarrowdb = skill_parse_row_createarrowdb; skill->parse_row_abradb = skill_parse_row_abradb; diff --git a/src/map/skill.h b/src/map/skill.h index be5f0a54f..3e2fc7936 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -1732,7 +1732,6 @@ struct skill_interface { int (*get_weapontype) ( uint16 skill_id ); int (*get_ammotype) ( uint16 skill_id ); int (*get_ammo_qty) ( uint16 skill_id, uint16 skill_lv ); - int (*get_nocast) ( uint16 skill_id ); int (*get_unit_id) (uint16 skill_id,int flag); int (*get_inf2) ( uint16 skill_id ); int (*get_castcancel) ( uint16 skill_id ); @@ -1866,7 +1865,6 @@ struct skill_interface { bool (*parse_row_castdb) (char* split[], int columns, int current); bool (*parse_row_castnodexdb) (char* split[], int columns, int current); bool (*parse_row_unitdb) (char* split[], int columns, int current); - bool (*parse_row_nocastdb) (char* split[], int columns, int current); bool (*parse_row_producedb) (char* split[], int columns, int current); bool (*parse_row_createarrowdb) (char* split[], int columns, int current); bool (*parse_row_abradb) (char* split[], int columns, int current); diff --git a/src/map/status.c b/src/map/status.c index 64f7f81af..f356e4aa5 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -2228,7 +2228,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first) const struct status_change *sc = &sd->sc; struct s_skill b_skill[MAX_SKILL]; // previous skill tree int b_weight, b_max_weight, b_cart_weight_max, // previous weight - i, index, skill,refinedef=0; + i, k, index, skill,refinedef=0; int64 i64; if (++calculating > 10) //Too many recursive calls! @@ -2392,19 +2392,14 @@ int status_calc_pc_(struct map_session_data* sd, bool first) if(!sd->inventory_data[index]) continue; - if(sd->inventory_data[index]->flag.no_equip) { // Items may be equipped, their effects however are nullified. - if(map[sd->bl.m].flag.restricted && sd->inventory_data[index]->flag.no_equip&(8*map[sd->bl.m].zone)) - continue; - if(!map_flag_vs(sd->bl.m) && sd->inventory_data[index]->flag.no_equip&1) - continue; - if(map[sd->bl.m].flag.pvp && sd->inventory_data[index]->flag.no_equip&2) - continue; - if(map_flag_gvg(sd->bl.m) && sd->inventory_data[index]->flag.no_equip&4) - continue; - if(map[sd->bl.m].flag.battleground && sd->inventory_data[index]->flag.no_equip&8) - continue; + for(k = 0; k < map[sd->bl.m].zone->disabled_items_count; k++) { + if( map[sd->bl.m].zone->disabled_items[k] == sd->inventory_data[index]->nameid ) { + break; + } } - + + if( k < map[sd->bl.m].zone->disabled_items_count ) + continue; status->def += sd->inventory_data[index]->def; @@ -2540,28 +2535,24 @@ int status_calc_pc_(struct map_session_data* sd, bool first) data = itemdb_exists(c); if(!data) continue; - if(first && data->equip_script) - { //Execute equip-script on login + if(first && data->equip_script) {//Execute equip-script on login run_script(data->equip_script,0,sd->bl.id,0); if (!calculating) return 1; } if(!data->script) continue; - if(data->flag.no_equip) { //Card restriction checks. - if(map[sd->bl.m].flag.restricted && data->flag.no_equip&(8*map[sd->bl.m].zone)) - continue; - if(!map_flag_vs(sd->bl.m) && data->flag.no_equip&1) - continue; - if(map[sd->bl.m].flag.pvp && data->flag.no_equip&2) - continue; - if(map_flag_gvg(sd->bl.m) && data->flag.no_equip&4) - continue; - if(map[sd->bl.m].flag.battleground && data->flag.no_equip&8) - continue; + + for(k = 0; k < map[sd->bl.m].zone->disabled_items_count; k++) { + if( map[sd->bl.m].zone->disabled_items[k] == sd->inventory_data[index]->nameid ) { + break; + } } - if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L) - { //Left hand status. + + if( k < map[sd->bl.m].zone->disabled_items_count ) + continue; + + if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L) { //Left hand status. sd->state.lr_flag = 1; run_script(data->script,0,sd->bl.id,0); sd->state.lr_flag = 0; -- cgit v1.2.3-60-g2f50