From a942853d55dd0e96ff98e6c352e2c2a9e000ea86 Mon Sep 17 00:00:00 2001 From: Aleos Date: Wed, 18 Jul 2018 20:00:33 -0400 Subject: [PATCH] Cleaned up the mapflag system (#2943) * Created setter and getter functions. * Adjusted all calls to use these functions. * Converted mapflags to C++ map container. * Converted drop_list to vector. * Converted skill_damage ERS into vector and increased limit from UINT8 to UINT16. * Cleaned up several functions to be more dynamic to reduce redundancy that was all over the place. * Renamed nosumstarmiracle to nosunmoonstarmiracle. * Adjusted skill_damage mapflag to use proper defined constants. * Refactored map index into a vector. Thanks to @Lemongrass3110 for a lot of help and @secretdataz! --- db/skill_damage_db.txt | 18 +- doc/mapflags.txt | 29 +- doc/script_commands.txt | 8 - src/common/utilities.hpp | 22 ++ src/config/core.hpp | 2 +- src/map/atcommand.cpp | 402 +++++++++++++------------- src/map/battle.cpp | 129 +++------ src/map/buyingstore.cpp | 4 +- src/map/chat.cpp | 2 +- src/map/chrif.cpp | 4 +- src/map/clif.cpp | 118 ++++---- src/map/instance.cpp | 2 - src/map/instance.hpp | 1 - src/map/itemdb.cpp | 6 +- src/map/mail.cpp | 2 +- src/map/map.cpp | 535 +++++++++++++++++++++++++++-------- src/map/map.hpp | 257 +++++++++-------- src/map/mob.cpp | 26 +- src/map/npc.cpp | 453 ++++++++++------------------- src/map/party.cpp | 2 +- src/map/pc.cpp | 68 ++--- src/map/script.cpp | 514 +++++++++------------------------ src/map/script.hpp | 1 + src/map/script_constants.hpp | 20 +- src/map/skill.cpp | 72 +++-- src/map/skill.hpp | 13 - src/map/status.cpp | 18 +- src/map/trade.cpp | 2 +- src/map/unit.cpp | 10 +- 29 files changed, 1306 insertions(+), 1434 deletions(-) diff --git a/db/skill_damage_db.txt b/db/skill_damage_db.txt index db229ba23f..34a04fc53c 100644 --- a/db/skill_damage_db.txt +++ b/db/skill_damage_db.txt @@ -4,12 +4,12 @@ // SkillName,Caster,Map,Damage against Players{,Damage against Mobs{,Damage against Bosses{,Damage against Other}}} // // Caster: The groups for which the adjustment takes effect. (bitmask) -// 1 = Player -// 2 = Monster -// 4 = Pet -// 8 = Homunculus -// 16 = Mercenary -// 32 = Elemental +// BL_PC = Player +// BL_MOB = Monster +// BL_PET = Pet +// BL_HOM = Homunculus +// BL_MER = Mercenary +// BL_ELEM = Elemental // // Map: // 1 - Normal (the maps that aren't classified as these maps below) @@ -31,6 +31,6 @@ // Negative values decrease damage and positive values increase it (0 = no change). // // Examples: -// MC_MAMMONITE,1,1,50 // In normal maps, players deal +50% damage to other players with Mammonite. -// MO_EXTREMITYFIST,1,6,-50 // In PVP and GVG, players deal -50% (half) damage to other players with Asura Strike. -// AB_ADORAMUS,1,6,50,0,10,15 // In PVP and GVG, players deal +50% damage to other players, +0% to mobs, +10% to bosses, and +15% to other with Adoramus. +// MC_MAMMONITE,BL_PC,1,50 // In normal maps, players deal +50% damage to other players with Mammonite. +// MO_EXTREMITYFIST,BL_PC,6,-50 // In PVP and GVG, players deal -50% (half) damage to other players with Asura Strike. +// AB_ADORAMUS,BL_PC,6,50,0,10,15 // In PVP and GVG, players deal +50% damage to other players, +0% to mobs, +10% to bosses, and +15% to other with Adoramus. diff --git a/doc/mapflags.txt b/doc/mapflags.txt index 9606c33504..4b744fc41d 100644 --- a/doc/mapflags.txt +++ b/doc/mapflags.txt @@ -209,7 +209,7 @@ Disables skill WZ_ICEWALL on a map. --------------------------------------- -*nosumstarmiracle +*nosunmoonstarmiracle Disables Star Gladiator's "Solar, Lunar, and Stellar Miracle" from occurring on a map. @@ -297,7 +297,7 @@ Notes: --------------------------------------- -*skill_damage {,,,{,{,{}}}} +*skill_damage {,,,{,{,{}}}} Enables skill damage adjustment on a map. All adjustments in 'db/skill_damage_db.txt' for 'Map' type 16 will be applied. @@ -307,21 +307,21 @@ This mapflag can also be used to adjust the damage of one skill by a percentage: Name of the skill in 'db/(pre-)re/skill_db.txt' (ex. SM_BASH). To adjust all skill damage, write "all" (without quotes). - caster: the groups for which the adjustment takes effect. (bitmask) - 1 = Player - 2 = Monster - 4 = Pet - 8 = Homunculus - 16 = Mercenary - 32 = Elemental + BL_PC = Player + BL_MOB = Monster + BL_PET = Pet + BL_HOM = Homunculus + BL_MER = Mercenary + BL_ELEM = Elemental - damage: percent adjustment rate (between -100 and 100000). - 1 = against player - 2 = against normal monster - 3 = against boss monster - 4 = against other (homunculus, mercenary, pet, elemental) + SKILLDMG_PC = against player + SKILLDMG_MOB = against normal monster + SKILLDMG_BOSS = against boss monster + SKILLDMG_OTHER = against other (homunculus, mercenary, pet, elemental) Notes: - You MUST enable ADJUST_SKILL_DAMAGE in 'src/config/core.hpp' for this mapflag to take effect. - - Each map can contain up to 5 adjustments (MAX_MAP_SKILL_MODIFIER in 'src/map/map.h'). + - Each map can contain up to UINT16_MAX adjustments. --------------------------------------- @@ -368,7 +368,8 @@ Allows usage of item Neuralizer (ID 12213). *bexp *jexp -Changes the base and job experience rates on a map. +Changes the base and job experience rates on a map. Supports negative values to reduce EXP +rates as well. is given as a percentage (i.e. 100 = 1x EXP). This takes into account the modifiers 'base_exp_rate' and 'job_exp_rate' in '/conf/battle/exp.conf'. diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 779b0d7bc3..6a16747efa 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -7015,14 +7015,6 @@ mf_fireworks) and whether night will be in effect on this map (mf_nightenabled). The optional parameter 'zone' is used to set the zone for restricted mapflags. -For the 'skill_damage' mapflag, 'zone' functions as 'value' (-100 to 100000) and -'type' can be: - 1: damage against players - 2: damage against mobs - 3: damage against bosses - 4: damage against other - 5: caster type - --------------------------------------- *removemapflag "",{,}; diff --git a/src/common/utilities.hpp b/src/common/utilities.hpp index 18fa5cb646..7b04cff38f 100644 --- a/src/common/utilities.hpp +++ b/src/common/utilities.hpp @@ -26,6 +26,12 @@ namespace rathena { return map.find( key ) != map.end(); } + /** + * Find a key-value pair and return the key value + * @param map: Map to search through + * @param key: Key wanted + * @return Key value on success or nullptr on failure + */ template V* map_find( std::map& map, K key ){ auto it = map.find( key ); @@ -35,6 +41,22 @@ namespace rathena { return nullptr; } } + + /** + * Get a key-value pair and return the key value + * @param map: Map to search through + * @param key: Key wanted + * @param defaultValue: Value returned if key doesn't exist + * @return Key value on success or defaultValue on failure + */ + template V map_get(std::map& map, K key, V defaultValue) { + auto it = map.find(key); + + if (it != map.end()) + return it->second; + else + return defaultValue; + } } } diff --git a/src/config/core.hpp b/src/config/core.hpp index 154e0c2a39..5472bf488f 100644 --- a/src/config/core.hpp +++ b/src/config/core.hpp @@ -44,7 +44,7 @@ //#define SHOW_SERVER_STATS /// Uncomment to enable skills damage adjustments -/// By enabling this, db/skill_damage.txt and the skill_damage mapflag will adjust the +/// By enabling this, db/skill_damage_db.txt and the skill_damage mapflag will adjust the /// damage rate of specified skills. //#define ADJUST_SKILL_DAMAGE diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index a95e34b1d4..455c2d8fe8 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -488,11 +488,11 @@ ACMD_FUNC(mapmove) if (!map_search_freecell(NULL, m, &x, &y, 10, 10, 1)) x = y = 0; //Invalid cell, use random spot. } - if ((map[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) || !pc_job_can_entermap((enum e_job)sd->status.class_, m, sd->group_level)) { + if ((map_getmapflag(m, MF_NOWARPTO) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) || !pc_job_can_entermap((enum e_job)sd->status.class_, m, sd->group_level)) { clif_displaymessage(fd, msg_txt(sd,247)); // You are not authorized to warp to this map. return -1; } - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (sd->bl.m >= 0 && map_getmapflag(sd->bl.m, MF_NOWARP) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif_displaymessage(fd, msg_txt(sd,248)); // You are not authorized to warp from your current map. return -1; } @@ -557,13 +557,13 @@ ACMD_FUNC(jumpto) return -1; } - if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) + if (pl_sd->bl.m >= 0 && map_getmapflag(pl_sd->bl.m, MF_NOWARPTO) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif_displaymessage(fd, msg_txt(sd,247)); // You are not authorized to warp to this map. return -1; } - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) + if (sd->bl.m >= 0 && map_getmapflag(sd->bl.m, MF_NOWARP) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif_displaymessage(fd, msg_txt(sd,248)); // You are not authorized to warp from your current map. return -1; @@ -595,7 +595,7 @@ ACMD_FUNC(jump) sscanf(message, "%6hd %6hd", &x, &y); - if (map[sd->bl.m].flag.noteleport && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (map_getmapflag(sd->bl.m, MF_NOTELEPORT) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif_displaymessage(fd, msg_txt(sd,248)); // You are not authorized to warp from your current map. return -1; } @@ -840,11 +840,11 @@ ACMD_FUNC(load) nullpo_retr(-1, sd); m = map_mapindex2mapid(sd->status.save_point.map); - if (m >= 0 && map[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (m >= 0 && map_getmapflag(m, MF_NOWARPTO) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif_displaymessage(fd, msg_txt(sd,249)); // You are not authorized to warp to your save map. return -1; } - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (sd->bl.m >= 0 && map_getmapflag(sd->bl.m, MF_NOWARP) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif_displaymessage(fd, msg_txt(sd,248)); // You are not authorized to warp from your current map. return -1; } @@ -997,7 +997,7 @@ ACMD_FUNC(hide) // increment the number of pvp players on the map map[sd->bl.m].users_pvp++; - if( !battle_config.pk_mode && map[sd->bl.m].flag.pvp && !map[sd->bl.m].flag.pvp_nocalcrank ) + if( !battle_config.pk_mode && map_getmapflag(sd->bl.m, MF_PVP) && !map_getmapflag(sd->bl.m, MF_PVP_NOCALCRANK) ) {// register the player for ranking calculations sd->pvp_timer = add_timer( gettick() + 200, pc_calc_pvprank_timer, sd->bl.id, 0 ); } @@ -1011,7 +1011,7 @@ ACMD_FUNC(hide) // decrement the number of pvp players on the map map[sd->bl.m].users_pvp--; - if( map[sd->bl.m].flag.pvp && !map[sd->bl.m].flag.pvp_nocalcrank && sd->pvp_timer != INVALID_TIMER ) + if( map_getmapflag(sd->bl.m, MF_PVP) && !map_getmapflag(sd->bl.m, MF_PVP_NOCALCRANK) && sd->pvp_timer != INVALID_TIMER ) {// unregister the player for ranking delete_timer( sd->pvp_timer, pc_calc_pvprank_timer ); sd->pvp_timer = INVALID_TIMER; @@ -1632,12 +1632,12 @@ ACMD_FUNC(pvpoff) { nullpo_retr(-1, sd); - if (!map[sd->bl.m].flag.pvp) { + if (!map_getmapflag(sd->bl.m, MF_PVP)) { clif_displaymessage(fd, msg_txt(sd,160)); // PvP is already Off. return -1; } - map[sd->bl.m].flag.pvp = 0; + map_setmapflag(sd->bl.m, MF_PVP, false); if (!battle_config.pk_mode){ clif_map_property_mapall(sd->bl.m, MAPPROPERTY_NOTHING); @@ -1669,12 +1669,12 @@ ACMD_FUNC(pvpon) { nullpo_retr(-1, sd); - if (map[sd->bl.m].flag.pvp) { + if (map_getmapflag(sd->bl.m, MF_PVP)) { clif_displaymessage(fd, msg_txt(sd,161)); // PvP is already On. return -1; } - map[sd->bl.m].flag.pvp = 1; + map_setmapflag(sd->bl.m, MF_PVP, true); if (!battle_config.pk_mode) {// display pvp circle and rank clif_map_property_mapall(sd->bl.m, MAPPROPERTY_FREEPVPZONE); @@ -1693,12 +1693,12 @@ ACMD_FUNC(gvgoff) { nullpo_retr(-1, sd); - if (!map[sd->bl.m].flag.gvg) { + if (!map_getmapflag(sd->bl.m, MF_GVG)) { clif_displaymessage(fd, msg_txt(sd,162)); // GvG is already Off. return -1; } - map[sd->bl.m].flag.gvg = 0; + map_setmapflag(sd->bl.m, MF_GVG, false); clif_map_property_mapall(sd->bl.m, MAPPROPERTY_NOTHING); map_foreachinmap(atcommand_stopattack,sd->bl.m, BL_CHAR, 0); clif_displaymessage(fd, msg_txt(sd,33)); // GvG: Off. @@ -1713,12 +1713,12 @@ ACMD_FUNC(gvgon) { nullpo_retr(-1, sd); - if (map[sd->bl.m].flag.gvg) { + if (map_getmapflag(sd->bl.m, MF_GVG)) { clif_displaymessage(fd, msg_txt(sd,163)); // GvG is already On. return -1; } - map[sd->bl.m].flag.gvg = 1; + map_setmapflag(sd->bl.m, MF_GVG, true); clif_map_property_mapall(sd->bl.m, MAPPROPERTY_AGITZONE); clif_displaymessage(fd, msg_txt(sd,34)); // GvG: On. @@ -1932,7 +1932,7 @@ ACMD_FUNC(go) nullpo_retr(-1, sd); - if( map[sd->bl.m].flag.nogo && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE) ) { + if( map_getmapflag(sd->bl.m, MF_NOGO) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE) ) { clif_displaymessage(sd->fd,msg_txt(sd,995)); // You cannot use @go on this map. return 0; } @@ -2054,11 +2054,11 @@ ACMD_FUNC(go) if (town >= 0 && town < ARRAYLENGTH(data)) { int16 m = map_mapname2mapid(data[town].map); - if (m >= 0 && map[m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (m >= 0 && map_getmapflag(m, MF_NOWARPTO) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif_displaymessage(fd, msg_txt(sd,247)); // You are not authorized to warp to this map. return -1; } - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (sd->bl.m >= 0 && map_getmapflag(sd->bl.m, MF_NOWARP) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif_displaymessage(fd, msg_txt(sd,248)); // You are not authorized to warp from your current map. return -1; } @@ -2921,11 +2921,11 @@ ACMD_FUNC(recall) { return -1; } - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (sd->bl.m >= 0 && map_getmapflag(sd->bl.m, MF_NOWARPTO) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif_displaymessage(fd, msg_txt(sd,1019)); // You are not authorized to warp someone to this map. return -1; } - if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (pl_sd->bl.m >= 0 && map_getmapflag(pl_sd->bl.m, MF_NOWARP) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif_displaymessage(fd, msg_txt(sd,1020)); // You are not authorized to warp this player from their map. return -1; } @@ -3651,7 +3651,7 @@ ACMD_FUNC(recallall) memset(atcmd_output, '\0', sizeof(atcmd_output)); - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (sd->bl.m >= 0 && map_getmapflag(sd->bl.m, MF_NOWARPTO) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif_displaymessage(fd, msg_txt(sd,1032)); // You are not authorized to warp someone to your current map. return -1; } @@ -3664,7 +3664,7 @@ ACMD_FUNC(recallall) { if (pl_sd->bl.m == sd->bl.m && pl_sd->bl.x == sd->bl.x && pl_sd->bl.y == sd->bl.y) continue; // Don't waste time warping the character to the same place. - if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) + if (pl_sd->bl.m >= 0 && map_getmapflag(pl_sd->bl.m, MF_NOWARP) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) count++; else { if( pc_setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_RESPAWN) == SETPOS_AUTOTRADE ){ @@ -3704,7 +3704,7 @@ ACMD_FUNC(guildrecall) return -1; } - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (sd->bl.m >= 0 && map_getmapflag(sd->bl.m, MF_NOWARPTO) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif_displaymessage(fd, msg_txt(sd,1032)); // You are not authorized to warp someone to your current map. return -1; } @@ -3725,7 +3725,7 @@ ACMD_FUNC(guildrecall) { if (pc_get_group_level(pl_sd) > pc_get_group_level(sd) || (pl_sd->bl.m == sd->bl.m && pl_sd->bl.x == sd->bl.x && pl_sd->bl.y == sd->bl.y)) continue; // Skip GMs greater than you... or chars already on the cell - if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) + if (pl_sd->bl.m >= 0 && map_getmapflag(pl_sd->bl.m, MF_NOWARP) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) count++; else{ if( pc_setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_RESPAWN) == SETPOS_AUTOTRADE ){ @@ -3766,7 +3766,7 @@ ACMD_FUNC(partyrecall) return -1; } - if (sd->bl.m >= 0 && map[sd->bl.m].flag.nowarpto && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { + if (sd->bl.m >= 0 && map_getmapflag(sd->bl.m, MF_NOWARPTO) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) { clif_displaymessage(fd, msg_txt(sd,1032)); // You are not authorized to warp someone to your current map. return -1; } @@ -3787,7 +3787,7 @@ ACMD_FUNC(partyrecall) { if (pc_get_group_level(pl_sd) > pc_get_group_level(sd) || (pl_sd->bl.m == sd->bl.m && pl_sd->bl.x == sd->bl.x && pl_sd->bl.y == sd->bl.y)) continue; // Skip GMs greater than you... or chars already on the cell - if (pl_sd->bl.m >= 0 && map[pl_sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) + if (pl_sd->bl.m >= 0 && map_getmapflag(pl_sd->bl.m, MF_NOWARP) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) count++; else{ if( pc_setpos(pl_sd, sd->mapindex, sd->bl.x, sd->bl.y, CLR_RESPAWN) == SETPOS_AUTOTRADE ){ @@ -4036,46 +4036,45 @@ ACMD_FUNC(mapinfo) { sprintf(atcmd_output, msg_txt(sd,1040), mapname, map[m_id].users, map[m_id].npc_num, chat_num, vend_num); // Map: %s | Players: %d | NPCs: %d | Chats: %d | Vendings: %d clif_displaymessage(fd, atcmd_output); clif_displaymessage(fd, msg_txt(sd,1041)); // ------ Map Flags ------ - if (map[m_id].flag.town) + if (map_getmapflag(m_id, MF_TOWN)) clif_displaymessage(fd, msg_txt(sd,1042)); // Town Map - if (map[m_id].flag.restricted){ + if (map_getmapflag(m_id, MF_RESTRICTED)){ sprintf(atcmd_output, " Restricted (zone %d)",map[m_id].zone); clif_displaymessage(fd, atcmd_output); } - if (battle_config.autotrade_mapflag == map[m_id].flag.autotrade) + if (battle_config.autotrade_mapflag == map_getmapflag(m_id, MF_AUTOTRADE)) clif_displaymessage(fd, msg_txt(sd,1043)); // Autotrade Enabled else clif_displaymessage(fd, msg_txt(sd,1044)); // Autotrade Disabled - if (map[m_id].flag.battleground){ - sprintf(atcmd_output, msg_txt(sd,1045),map[m_id].flag.battleground); // Battlegrounds ON (type %d) + if (map_getmapflag(m_id, MF_BATTLEGROUND)){ + sprintf(atcmd_output, msg_txt(sd,1045),map_getmapflag(m_id, MF_BATTLEGROUND)); // Battlegrounds ON (type %d) clif_displaymessage(fd, atcmd_output); } /* Skill damage adjustment info [Cydh] */ #ifdef ADJUST_SKILL_DAMAGE - if (map[m_id].flag.skill_damage) { + if (map_getmapflag(m_id, MF_SKILL_DAMAGE)) { clif_displaymessage(fd,msg_txt(sd,1052)); // Skill Damage Adjustments: sprintf(atcmd_output," > [Map] %d%%, %d%%, %d%%, %d%% | Caster:%d" - ,map[m_id].adjust.damage.pc - ,map[m_id].adjust.damage.mob - ,map[m_id].adjust.damage.boss - ,map[m_id].adjust.damage.other - ,map[m_id].adjust.damage.caster); + ,map[m_id].damage_adjust.rate[SKILLDMG_PC] + ,map[m_id].damage_adjust.rate[SKILLDMG_MOB] + ,map[m_id].damage_adjust.rate[SKILLDMG_BOSS] + ,map[m_id].damage_adjust.rate[SKILLDMG_OTHER] + ,map[m_id].damage_adjust.caster); clif_displaymessage(fd, atcmd_output); - if (map[m_id].skill_damage.count) { - uint8 j; + if (map[m_id].skill_damage.size()) { clif_displaymessage(fd," > [Map Skill] Name : Player, Monster, Boss Monster, Other | Caster"); - for (j = 0; j < map[m_id].skill_damage.count; j++) { + for (int j = 0; j < map[m_id].skill_damage.size(); j++) { sprintf(atcmd_output," %d. %s : %d%%, %d%%, %d%%, %d%% | %d" ,j+1 - ,skill_get_name(map[m_id].skill_damage.entries[j]->skill_id) - ,map[m_id].skill_damage.entries[j]->pc - ,map[m_id].skill_damage.entries[j]->mob - ,map[m_id].skill_damage.entries[j]->boss - ,map[m_id].skill_damage.entries[j]->other - ,map[m_id].skill_damage.entries[j]->caster); + ,skill_get_name(map[m_id].skill_damage[j].skill_id) + ,map[m_id].skill_damage[j].rate[SKILLDMG_PC] + ,map[m_id].skill_damage[j].rate[SKILLDMG_MOB] + ,map[m_id].skill_damage[j].rate[SKILLDMG_BOSS] + ,map[m_id].skill_damage[j].rate[SKILLDMG_OTHER] + ,map[m_id].skill_damage[j].caster); clif_displaymessage(fd,atcmd_output); } } @@ -4083,55 +4082,55 @@ ACMD_FUNC(mapinfo) { #endif strcpy(atcmd_output,msg_txt(sd,1046)); // PvP Flags: - if (map[m_id].flag.pvp) + if (map_getmapflag(m_id, MF_PVP)) strcat(atcmd_output, " Pvp ON |"); - if (map[m_id].flag.pvp_noguild) + if (map_getmapflag(m_id, MF_PVP_NOGUILD)) strcat(atcmd_output, " NoGuild |"); - if (map[m_id].flag.pvp_noparty) + if (map_getmapflag(m_id, MF_PVP_NOPARTY)) strcat(atcmd_output, " NoParty |"); - if (map[m_id].flag.pvp_nightmaredrop) + if (map_getmapflag(m_id, MF_PVP_NIGHTMAREDROP)) strcat(atcmd_output, " NightmareDrop |"); - if (map[m_id].flag.pvp_nocalcrank) + if (map_getmapflag(m_id, MF_PVP_NOCALCRANK)) strcat(atcmd_output, " NoCalcRank |"); clif_displaymessage(fd, atcmd_output); strcpy(atcmd_output,msg_txt(sd,1047)); // GvG Flags: - if (map[m_id].flag.gvg) + if (map_getmapflag(m_id, MF_GVG)) strcat(atcmd_output, " GvG ON |"); - if (map[m_id].flag.gvg_dungeon) + if (map_getmapflag(m_id, MF_GVG_DUNGEON)) strcat(atcmd_output, " GvG Dungeon |"); - if (map[m_id].flag.gvg_castle) + if (map_getmapflag(m_id, MF_GVG_CASTLE)) strcat(atcmd_output, " GvG Castle |"); - if (map[m_id].flag.gvg_te) + if (map_getmapflag(m_id, MF_GVG_TE)) strcat(atcmd_output, " GvG TE |"); - if (map[m_id].flag.gvg_te_castle) + if (map_getmapflag(m_id, MF_GVG_TE_CASTLE)) strcat(atcmd_output, " GvG TE Castle |"); - if (map[m_id].flag.gvg_noparty) + if (map_getmapflag(m_id, MF_GVG_NOPARTY)) strcat(atcmd_output, " NoParty |"); clif_displaymessage(fd, atcmd_output); strcpy(atcmd_output,msg_txt(sd,1048)); // Teleport Flags: - if (map[m_id].flag.noteleport) + if (map_getmapflag(m_id, MF_NOTELEPORT)) strcat(atcmd_output, " NoTeleport |"); - if (map[m_id].flag.monster_noteleport) + if (map_getmapflag(m_id, MF_MONSTER_NOTELEPORT)) strcat(atcmd_output, " Monster NoTeleport |"); - if (map[m_id].flag.nowarp) + if (map_getmapflag(m_id, MF_NOWARP)) strcat(atcmd_output, " NoWarp |"); - if (map[m_id].flag.nowarpto) + if (map_getmapflag(m_id, MF_NOWARPTO)) strcat(atcmd_output, " NoWarpTo |"); - if (map[m_id].flag.noreturn) + if (map_getmapflag(m_id, MF_NORETURN)) strcat(atcmd_output, " NoReturn |"); - if (map[m_id].flag.nogo) + if (map_getmapflag(m_id, MF_NOGO)) strcat(atcmd_output, " NoGo |"); // - if (map[m_id].flag.nomemo) + if (map_getmapflag(m_id, MF_NOMEMO)) strcat(atcmd_output, " NoMemo |"); clif_displaymessage(fd, atcmd_output); sprintf(atcmd_output, msg_txt(sd,1065), // No Exp Penalty: %s | No Zeny Penalty: %s - (map[m_id].flag.noexppenalty) ? msg_txt(sd,1066) : msg_txt(sd,1067), (map[m_id].flag.nozenypenalty) ? msg_txt(sd,1066) : msg_txt(sd,1067)); // On / Off + (map_getmapflag(m_id, MF_NOEXPPENALTY)) ? msg_txt(sd,1066) : msg_txt(sd,1067), (map_getmapflag(m_id, MF_NOZENYPENALTY)) ? msg_txt(sd,1066) : msg_txt(sd,1067)); // On / Off clif_displaymessage(fd, atcmd_output); - if (map[m_id].flag.nosave) { + if (map_getmapflag(m_id, MF_NOSAVE)) { if (!map[m_id].save.map) clif_displaymessage(fd, msg_txt(sd,1068)); // No Save (Return to last Save Point) else if (map[m_id].save.x == -1 || map[m_id].save.y == -1 ) { @@ -4146,77 +4145,77 @@ ACMD_FUNC(mapinfo) { } strcpy(atcmd_output,msg_txt(sd,1049)); // Weather Flags: - if (map[m_id].flag.snow) + if (map_getmapflag(m_id, MF_SNOW)) strcat(atcmd_output, " Snow |"); - if (map[m_id].flag.fog) + if (map_getmapflag(m_id, MF_FOG)) strcat(atcmd_output, " Fog |"); - if (map[m_id].flag.sakura) + if (map_getmapflag(m_id, MF_SAKURA)) strcat(atcmd_output, " Sakura |"); - if (map[m_id].flag.clouds) + if (map_getmapflag(m_id, MF_CLOUDS)) strcat(atcmd_output, " Clouds |"); - if (map[m_id].flag.clouds2) + if (map_getmapflag(m_id, MF_CLOUDS2)) strcat(atcmd_output, " Clouds2 |"); - if (map[m_id].flag.fireworks) + if (map_getmapflag(m_id, MF_FIREWORKS)) strcat(atcmd_output, " Fireworks |"); - if (map[m_id].flag.leaves) + if (map_getmapflag(m_id, MF_LEAVES)) strcat(atcmd_output, " Leaves |"); - if (map[m_id].flag.nightenabled) + if (map_getmapflag(m_id, MF_NIGHTENABLED)) strcat(atcmd_output, " Displays Night |"); clif_displaymessage(fd, atcmd_output); strcpy(atcmd_output,msg_txt(sd,1050)); // Other Flags: - if (map[m_id].flag.nobranch) + if (map_getmapflag(m_id, MF_NOBRANCH)) strcat(atcmd_output, " NoBranch |"); - if (map[m_id].flag.notrade) + if (map_getmapflag(m_id, MF_NOTRADE)) strcat(atcmd_output, " NoTrade |"); - if (map[m_id].flag.novending) + if (map_getmapflag(m_id, MF_NOVENDING)) strcat(atcmd_output, " NoVending |"); - if (map[m_id].flag.nodrop) + if (map_getmapflag(m_id, MF_NODROP)) strcat(atcmd_output, " NoDrop |"); - if (map[m_id].flag.noskill) + if (map_getmapflag(m_id, MF_NOSKILL)) strcat(atcmd_output, " NoSkill |"); - if (map[m_id].flag.noicewall) + if (map_getmapflag(m_id, MF_NOICEWALL)) strcat(atcmd_output, " NoIcewall |"); - if (map[m_id].flag.allowks) + if (map_getmapflag(m_id, MF_ALLOWKS)) strcat(atcmd_output, " AllowKS |"); - if (map[m_id].flag.reset) + if (map_getmapflag(m_id, MF_RESET)) strcat(atcmd_output, " Reset |"); - if (map[m_id].flag.hidemobhpbar) + if (map_getmapflag(m_id, MF_HIDEMOBHPBAR)) strcat(atcmd_output, " HideMobHPBar |"); clif_displaymessage(fd, atcmd_output); strcpy(atcmd_output,msg_txt(sd,1051)); // Other Flags2: - if (map[m_id].nocommand) + if (map_getmapflag(m_id, MF_NOCOMMAND)) strcat(atcmd_output, " NoCommand |"); - if (map[m_id].flag.nobaseexp) + if (map_getmapflag(m_id, MF_NOBASEEXP)) strcat(atcmd_output, " NoBaseEXP |"); - if (map[m_id].flag.nojobexp) + if (map_getmapflag(m_id, MF_NOJOBEXP)) strcat(atcmd_output, " NoJobEXP |"); - if (map[m_id].flag.nomobloot) + if (map_getmapflag(m_id, MF_NOMOBLOOT)) strcat(atcmd_output, " NoMobLoot |"); - if (map[m_id].flag.nomvploot) + if (map_getmapflag(m_id, MF_NOMVPLOOT)) strcat(atcmd_output, " NoMVPLoot |"); - if (map[m_id].flag.partylock) + if (map_getmapflag(m_id, MF_PARTYLOCK)) strcat(atcmd_output, " PartyLock |"); - if (map[m_id].flag.guildlock) + if (map_getmapflag(m_id, MF_GUILDLOCK)) strcat(atcmd_output, " GuildLock |"); - if (map[m_id].flag.loadevent) + if (map_getmapflag(m_id, MF_LOADEVENT)) strcat(atcmd_output, " Loadevent |"); - if (map[m_id].flag.chmautojoin) - strcat(atcmd_output, " Chmautojoin |"); - if (map[m_id].flag.nousecart) + if (map_getmapflag(m_id, MF_NOMAPCHANNELAUTOJOIN)) + strcat(atcmd_output, " NoMapChannelAutoJoin |"); + if (map_getmapflag(m_id, MF_NOUSECART)) strcat(atcmd_output, " NoUsecart |"); - if (map[m_id].flag.noitemconsumption) + if (map_getmapflag(m_id, MF_NOITEMCONSUMPTION)) strcat(atcmd_output, " NoItemConsumption |"); - if (map[m_id].flag.nosumstarmiracle) - strcat(atcmd_output, " NoSumStarMiracle |"); - if (map[m_id].flag.nomineeffect) + if (map_getmapflag(m_id, MF_NOSUNMOONSTARMIRACLE)) + strcat(atcmd_output, " NoSunMoonStarMiracle |"); + if (map_getmapflag(m_id, MF_NOMINEEFFECT)) strcat(atcmd_output, " NoMineEffect |"); - if (map[m_id].flag.nolockon) + if (map_getmapflag(m_id, MF_NOLOCKON)) strcat(atcmd_output, " NoLockOn |"); - if (map[m_id].flag.notomb) + if (map_getmapflag(m_id, MF_NOTOMB)) strcat(atcmd_output, " NoTomb |"); - if (map[m_id].flag.nocostume) + if (map_getmapflag(m_id, MF_NOCOSTUME)) strcat(atcmd_output, " NoCostume |"); clif_displaymessage(fd, atcmd_output); @@ -5367,7 +5366,7 @@ ACMD_FUNC(killable) ACMD_FUNC(skillon) { nullpo_retr(-1, sd); - map[sd->bl.m].flag.noskill = 0; + map_setmapflag(sd->bl.m, MF_NOSKILL, false); clif_displaymessage(fd, msg_txt(sd,244)); // Skills have been enabled on this map. return 0; } @@ -5379,7 +5378,7 @@ ACMD_FUNC(skillon) ACMD_FUNC(skilloff) { nullpo_retr(-1, sd); - map[sd->bl.m].flag.noskill = 1; + map_setmapflag(sd->bl.m, MF_NOSKILL, true); clif_displaymessage(fd, msg_txt(sd,243)); // Skills have been disabled on this map. return 0; } @@ -5952,7 +5951,7 @@ ACMD_FUNC(changelook) ACMD_FUNC(autotrade) { nullpo_retr(-1, sd); - if( map[sd->bl.m].flag.autotrade != battle_config.autotrade_mapflag ) { + if( map_getmapflag(sd->bl.m, MF_AUTOTRADE) != battle_config.autotrade_mapflag ) { clif_displaymessage(fd, msg_txt(sd,1179)); // Autotrade is not allowed on this map. return -1; } @@ -6011,7 +6010,7 @@ ACMD_FUNC(changegm) return -1; } - if( map[sd->bl.m].flag.guildlock || map[sd->bl.m].flag.gvg_castle ) { + if( map_getmapflag(sd->bl.m, MF_GUILDLOCK) || map_getmapflag(sd->bl.m, MF_GVG_CASTLE) ) { clif_displaymessage(fd, msg_txt(sd,1182)); // You cannot change guild leaders on this map. return -1; } @@ -6331,21 +6330,19 @@ ACMD_FUNC(autoloottype) return 0; } -/** - * No longer available, keeping here just in case it's back someday. [Ind] - **/ /*========================================== * It is made to rain. + * No longer available, keeping here just in case it's back someday. [Ind] *------------------------------------------*/ //ACMD_FUNC(rain) //{ // nullpo_retr(-1, sd); -// if (map[sd->bl.m].flag.rain) { -// map[sd->bl.m].flag.rain=0; +// if (map_getmapflag(sd->bl.m, MF_RAIN)) { +// map_setmapflag(sd->bl.m, MF_RAIN, false); // clif_weather(sd->bl.m); // clif_displaymessage(fd, msg_txt(sd,1201)); // The rain has stopped. // } else { -// map[sd->bl.m].flag.rain=1; +// map_setmapflag(sd->bl.m, MF_RAIN, true); // clif_weather(sd->bl.m); // clif_displaymessage(fd, msg_txt(sd,1202)); // It has started to rain. // } @@ -6358,12 +6355,12 @@ ACMD_FUNC(autoloottype) ACMD_FUNC(snow) { nullpo_retr(-1, sd); - if (map[sd->bl.m].flag.snow) { - map[sd->bl.m].flag.snow=0; + if (map_getmapflag(sd->bl.m, MF_SNOW)) { + map_setmapflag(sd->bl.m, MF_SNOW, false); clif_weather(sd->bl.m); clif_displaymessage(fd, msg_txt(sd,1203)); // Snow has stopped falling. } else { - map[sd->bl.m].flag.snow=1; + map_setmapflag(sd->bl.m, MF_SNOW, true); clif_weather(sd->bl.m); clif_displaymessage(fd, msg_txt(sd,1204)); // It has started to snow. } @@ -6377,12 +6374,12 @@ ACMD_FUNC(snow) ACMD_FUNC(sakura) { nullpo_retr(-1, sd); - if (map[sd->bl.m].flag.sakura) { - map[sd->bl.m].flag.sakura=0; + if (map_getmapflag(sd->bl.m, MF_SAKURA)) { + map_setmapflag(sd->bl.m, MF_SAKURA, false); clif_weather(sd->bl.m); clif_displaymessage(fd, msg_txt(sd,1205)); // Cherry tree leaves no longer fall. } else { - map[sd->bl.m].flag.sakura=1; + map_setmapflag(sd->bl.m, MF_SAKURA, true); clif_weather(sd->bl.m); clif_displaymessage(fd, msg_txt(sd,1206)); // Cherry tree leaves have begun to fall. } @@ -6395,12 +6392,12 @@ ACMD_FUNC(sakura) ACMD_FUNC(clouds) { nullpo_retr(-1, sd); - if (map[sd->bl.m].flag.clouds) { - map[sd->bl.m].flag.clouds=0; + if (map_getmapflag(sd->bl.m, MF_CLOUDS)) { + map_setmapflag(sd->bl.m, MF_CLOUDS, false); clif_weather(sd->bl.m); clif_displaymessage(fd, msg_txt(sd,1207)); // The clouds has disappear. } else { - map[sd->bl.m].flag.clouds=1; + map_setmapflag(sd->bl.m, MF_CLOUDS, true); clif_weather(sd->bl.m); clif_displaymessage(fd, msg_txt(sd,1208)); // Clouds appear. } @@ -6414,12 +6411,12 @@ ACMD_FUNC(clouds) ACMD_FUNC(clouds2) { nullpo_retr(-1, sd); - if (map[sd->bl.m].flag.clouds2) { - map[sd->bl.m].flag.clouds2=0; + if (map_getmapflag(sd->bl.m, MF_CLOUDS2)) { + map_setmapflag(sd->bl.m, MF_CLOUDS2, false); clif_weather(sd->bl.m); clif_displaymessage(fd, msg_txt(sd,1209)); // The alternative clouds disappear. } else { - map[sd->bl.m].flag.clouds2=1; + map_setmapflag(sd->bl.m, MF_CLOUDS2, true); clif_weather(sd->bl.m); clif_displaymessage(fd, msg_txt(sd,1210)); // Alternative clouds appear. } @@ -6433,12 +6430,12 @@ ACMD_FUNC(clouds2) ACMD_FUNC(fog) { nullpo_retr(-1, sd); - if (map[sd->bl.m].flag.fog) { - map[sd->bl.m].flag.fog=0; + if (map_getmapflag(sd->bl.m, MF_FOG)) { + map_setmapflag(sd->bl.m, MF_FOG, false); clif_weather(sd->bl.m); clif_displaymessage(fd, msg_txt(sd,1211)); // The fog has gone. } else { - map[sd->bl.m].flag.fog=1; + map_setmapflag(sd->bl.m, MF_FOG, true); clif_weather(sd->bl.m); clif_displaymessage(fd, msg_txt(sd,1212)); // Fog hangs over. } @@ -6451,12 +6448,12 @@ ACMD_FUNC(fog) ACMD_FUNC(leaves) { nullpo_retr(-1, sd); - if (map[sd->bl.m].flag.leaves) { - map[sd->bl.m].flag.leaves=0; + if (map_getmapflag(sd->bl.m, MF_LEAVES)) { + map_setmapflag(sd->bl.m, MF_LEAVES, false); clif_weather(sd->bl.m); clif_displaymessage(fd, msg_txt(sd,1213)); // Leaves no longer fall. } else { - map[sd->bl.m].flag.leaves=1; + map_setmapflag(sd->bl.m, MF_LEAVES, true); clif_weather(sd->bl.m); clif_displaymessage(fd, msg_txt(sd,1214)); // Fallen leaves fall. } @@ -6470,12 +6467,12 @@ ACMD_FUNC(leaves) ACMD_FUNC(fireworks) { nullpo_retr(-1, sd); - if (map[sd->bl.m].flag.fireworks) { - map[sd->bl.m].flag.fireworks=0; + if (map_getmapflag(sd->bl.m, MF_FIREWORKS)) { + map_setmapflag(sd->bl.m, MF_FIREWORKS, false); clif_weather(sd->bl.m); clif_displaymessage(fd, msg_txt(sd,1215)); // Fireworks have ended. } else { - map[sd->bl.m].flag.fireworks=1; + map_setmapflag(sd->bl.m, MF_FIREWORKS, true); clif_weather(sd->bl.m); clif_displaymessage(fd, msg_txt(sd,1216)); // Fireworks have launched. } @@ -6489,17 +6486,15 @@ ACMD_FUNC(fireworks) ACMD_FUNC(clearweather) { nullpo_retr(-1, sd); - /** - * No longer available, keeping here just in case it's back someday. [Ind] - **/ - //map[sd->bl.m].flag.rain=0; - map[sd->bl.m].flag.snow=0; - map[sd->bl.m].flag.sakura=0; - map[sd->bl.m].flag.clouds=0; - map[sd->bl.m].flag.clouds2=0; - map[sd->bl.m].flag.fog=0; - map[sd->bl.m].flag.fireworks=0; - map[sd->bl.m].flag.leaves=0; + + //map_setmapflag(sd->bl.m, MF_RAIN, false); // No longer available, keeping here just in case it's back someday. [Ind] + map_setmapflag(sd->bl.m, MF_SNOW, false); + map_setmapflag(sd->bl.m, MF_SAKURA, false); + map_setmapflag(sd->bl.m, MF_CLOUDS, false); + map_setmapflag(sd->bl.m, MF_CLOUDS2, false); + map_setmapflag(sd->bl.m, MF_FOG, false); + map_setmapflag(sd->bl.m, MF_FIREWORKS, false); + map_setmapflag(sd->bl.m, MF_LEAVES, false); clif_weather(sd->bl.m); clif_displaymessage(fd, msg_txt(sd,291)); // Weather effects will dispell on warp/refresh @@ -8150,84 +8145,69 @@ ACMD_FUNC(fakename) * Ragnarok Resources *------------------------------------------*/ ACMD_FUNC(mapflag) { -#define checkflag( cmd ) if ( map[ sd->bl.m ].flag.cmd ) clif_displaymessage(sd->fd,#cmd) -#define setflag( cmd ) \ - if ( strcmp( flag_name , #cmd ) == 0 ){\ - map[ sd->bl.m ].flag.cmd = flag;\ - sprintf(atcmd_output,"[ @mapflag ] %s flag has been set to %s value = %hd",#cmd,flag?"On":"Off",flag);\ - clif_displaymessage(sd->fd,atcmd_output);\ - return 0;\ - } - char flag_name[100]; - short flag=0,i; + char flag_name[CHAT_SIZE_MAX]; + short flag = 0, i, j; + StringBuf buf; + nullpo_retr(-1, sd); + memset(flag_name, '\0', sizeof(flag_name)); if (!message || !*message || (sscanf(message, "%99s %6hd", flag_name, &flag) < 1)) { clif_displaymessage(sd->fd,msg_txt(sd,1311)); // Enabled Mapflags in this map: clif_displaymessage(sd->fd,"----------------------------------"); - checkflag(town); checkflag(autotrade); checkflag(allowks); checkflag(nomemo); - checkflag(noteleport); checkflag(noreturn); checkflag(monster_noteleport); checkflag(nosave); - checkflag(nobranch); checkflag(noexppenalty); checkflag(pvp); checkflag(pvp_noparty); - checkflag(pvp_noguild); checkflag(pvp_nightmaredrop); checkflag(pvp_nocalcrank); checkflag(gvg_castle); - checkflag(gvg); checkflag(gvg_dungeon); checkflag(gvg_noparty); checkflag(battleground); - checkflag(nozenypenalty); checkflag(notrade); checkflag(noskill); checkflag(nowarp); - checkflag(nowarpto); checkflag(noicewall); checkflag(snow); checkflag(clouds); - checkflag(clouds2); 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(nochat); - checkflag(partylock); checkflag(guildlock); checkflag(reset); checkflag(chmautojoin); - checkflag(nousecart); checkflag(noitemconsumption); checkflag(nosumstarmiracle); checkflag(nomineeffect); - checkflag(nolockon); checkflag(notomb); checkflag(nocostume); checkflag(gvg_te); - checkflag(gvg_te_castle); checkflag(hidemobhpbar); -#ifdef ADJUST_SKILL_DAMAGE - checkflag(skill_damage); -#endif + for( i = MF_MIN; i < MF_MAX; i++ ){ + if( map_getmapflag_name(static_cast(i), flag_name) && map_getmapflag( sd->bl.m, static_cast(i) ) ){ + clif_displaymessage(sd->fd, flag_name); + } + } + clif_displaymessage(sd->fd," "); clif_displaymessage(sd->fd,msg_txt(sd,1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On) clif_displaymessage(sd->fd,msg_txt(sd,1313)); // Type "@mapflag available" to list the available mapflags. return 1; } - for (i = 0; flag_name[i]; i++) flag_name[i] = (char)tolower(flag_name[i]); //lowercase - setflag(town); setflag(autotrade); setflag(allowks); setflag(nomemo); - setflag(noteleport); setflag(noreturn); setflag(monster_noteleport); setflag(nosave); - setflag(nobranch); setflag(noexppenalty); setflag(pvp); setflag(pvp_noparty); - setflag(pvp_noguild); setflag(pvp_nightmaredrop); setflag(pvp_nocalcrank); setflag(gvg_castle); - setflag(gvg); setflag(gvg_dungeon); setflag(gvg_noparty); setflag(battleground); - setflag(nozenypenalty); setflag(notrade); setflag(noskill); setflag(nowarp); - setflag(nowarpto); setflag(noicewall); setflag(snow); setflag(clouds); - setflag(clouds2); 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(nochat); - setflag(partylock); setflag(guildlock); setflag(reset); setflag(chmautojoin); - setflag(nousecart); setflag(noitemconsumption); setflag(nosumstarmiracle); setflag(nomineeffect); - setflag(nolockon); setflag(notomb); setflag(nocostume); setflag(gvg_te); - setflag(gvg_te_castle); setflag(hidemobhpbar); -#ifdef ADJUST_SKILL_DAMAGE - setflag(skill_damage); -#endif + // Check if the list of mapflags was requested + if( strcasecmp(flag_name,"available") ){ + for (i = 0; flag_name[i]; i++) flag_name[i] = (char)tolower(flag_name[i]); //lowercase + + enum e_mapflag mapflag = map_getmapflag_by_name(flag_name); + + if( mapflag != MF_INVALID ){ + map_setmapflag(sd->bl.m, static_cast(mapflag), flag != 0); + sprintf(atcmd_output,"[ @mapflag ] %s flag has been set to %s value = %hd",flag_name,flag?"On":"Off",flag); + clif_displaymessage(sd->fd,atcmd_output); + return 0; + }else{ + clif_displaymessage(sd->fd, msg_txt(sd, 1314)); // Invalid flag name or flag. + clif_displaymessage(sd->fd, msg_txt(sd, 1313)); // Type "@mapflag available" to list the available mapflags. + return 1; + } + } - clif_displaymessage(sd->fd,msg_txt(sd,1314)); // Invalid flag name or flag. - clif_displaymessage(sd->fd,msg_txt(sd,1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On) clif_displaymessage(sd->fd,msg_txt(sd,1315)); // Available Flags: clif_displaymessage(sd->fd,"----------------------------------"); - clif_displaymessage(sd->fd,"town, autotrade, allowks, nomemo, noteleport, noreturn, monster_noteleport, nosave,"); - clif_displaymessage(sd->fd,"nobranch, noexppenalty, pvp, pvp_noparty, pvp_noguild, pvp_nightmaredrop,"); - 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, nomvploot,"); - clif_displaymessage(sd->fd,"nightenabled, restricted, nodrop, novending, loadevent, nochat, partylock, guildlock,"); - clif_displaymessage(sd->fd,"reset, chmautojoin, nousecart, noitemconsumption, nosumstarmiracle, nolockon, notomb,"); - clif_displaymessage(sd->fd,"nocostume, gvg_te, gvg_te_castle, hidemobhpbar"); -#ifdef ADJUST_SKILL_DAMAGE - clif_displaymessage(sd->fd,"skill_damage"); -#endif + StringBuf_Init(&buf); + for( i = MF_MIN, j = 0; i < MF_MAX; i++ ){ + if( map_getmapflag_name( static_cast(i), flag_name ) ){ + StringBuf_AppendStr( &buf, flag_name ); -#undef checkflag -#undef setflag + if( (i + 1) < MF_MAX ){ + StringBuf_AppendStr( &buf, ", " ); + } + + j++; + } + + if( i > MF_MIN && ( j == 6 || ( i + 1 ) == MF_MAX ) ){ + clif_displaymessage(sd->fd, StringBuf_Value(&buf) ); + StringBuf_Clear(&buf); + j = 0; + } + } + StringBuf_Destroy(&buf); + clif_displaymessage(sd->fd, msg_txt(sd, 1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On) return 0; } @@ -8671,11 +8651,11 @@ ACMD_FUNC(allowks) { nullpo_retr(-1,sd); - if( map[sd->bl.m].flag.allowks ) { - map[sd->bl.m].flag.allowks = 0; + if( map_getmapflag(sd->bl.m, MF_ALLOWKS) ) { + map_setmapflag(sd->bl.m, MF_ALLOWKS, false); clif_displaymessage(fd, msg_txt(sd,1330)); // [ Map K.S Protection Active ] } else { - map[sd->bl.m].flag.allowks = 1; + map_setmapflag(sd->bl.m, MF_ALLOWKS, true); clif_displaymessage(fd, msg_txt(sd,1331)); // [ Map K.S Protection Inactive ] } return 0; @@ -10480,7 +10460,7 @@ bool is_atcommand(const int fd, struct map_session_data* sd, const char* message // type value 0|2 = script|console invoked: bypass restrictions if ( type == 1 || type == 3) { //Commands are disabled on maps flagged as 'nocommand' - if ( map[sd->bl.m].nocommand && pc_get_group_level(sd) < map[sd->bl.m].nocommand ) { + if ( pc_get_group_level(sd) < map_getmapflag(sd->bl.m, MF_NOCOMMAND) ) { clif_displaymessage(fd, msg_txt(sd,143)); // Commands are disabled on this map. return false; } diff --git a/src/map/battle.cpp b/src/map/battle.cpp index 7c367c27f6..b03f2c2ea8 100644 --- a/src/map/battle.cpp +++ b/src/map/battle.cpp @@ -1575,7 +1575,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam } //End of caster SC_ check //PK damage rates - if (battle_config.pk_mode && sd && bl->type == BL_PC && damage && map[bl->m].flag.pvp) { + if (battle_config.pk_mode && sd && bl->type == BL_PC && damage && map_getmapflag(bl->m, MF_PVP)) { if (flag & BF_SKILL) { //Skills get a different reduction than non-skills. [Skotlex] if (flag&BF_WEAPON) damage = damage * battle_config.pk_weapon_damage_rate / 100; @@ -2157,24 +2157,19 @@ static int battle_blewcount_bonus(struct map_session_data *sd, uint16 skill_id) } #ifdef ADJUST_SKILL_DAMAGE -/** - * Damage calculation for adjusting skill damage - * @param caster Applied caster type for damage skill - * @param type BL_Type of attacker - */ -static bool battle_skill_damage_iscaster(uint8 caster, enum bl_type src_type) { - if (caster == 0) - return false; - - switch (src_type) { - case BL_PC: if (caster&SDC_PC) return true; break; - case BL_MOB: if (caster&SDC_MOB) return true; break; - case BL_PET: if (caster&SDC_PET) return true; break; - case BL_HOM: if (caster&SDC_HOM) return true; break; - case BL_MER: if (caster&SDC_MER) return true; break; - case BL_ELEM: if (caster&SDC_ELEM) return true; break; +static enum e_skill_damage_type battle_skill_damage_type( struct block_list* bl ){ + switch( bl->type ){ + case BL_PC: + return SKILLDMG_PC; + case BL_MOB: + if( status_get_class_(bl) == CLASS_BOSS ){ + return SKILLDMG_BOSS; + }else{ + return SKILLDMG_MOB; + } + default: + return SKILLDMG_OTHER; } - return false; } /** @@ -2187,7 +2182,6 @@ static bool battle_skill_damage_iscaster(uint8 caster, enum bl_type src_type) { static int battle_skill_damage_skill(struct block_list *src, struct block_list *target, uint16 skill_id) { uint16 idx = skill_get_index(skill_id), m = src->m; struct s_skill_damage *damage = NULL; - struct map_data *mapd = &map[m]; if (!idx || !skill_db[idx]->damage.map) return 0; @@ -2195,27 +2189,17 @@ static int battle_skill_damage_skill(struct block_list *src, struct block_list * damage = &skill_db[idx]->damage; //check the adjustment works for specified type - if (!battle_skill_damage_iscaster(damage->caster, src->type)) + if (!(damage->caster&src->type)) return 0; - if ((damage->map&1 && (!mapd->flag.pvp && !map_flag_gvg2(m) && !mapd->flag.battleground && !mapd->flag.skill_damage && !mapd->flag.restricted)) || - (damage->map&2 && mapd->flag.pvp) || + if ((damage->map&1 && (!map_getmapflag(m, MF_PVP) && !map_flag_gvg2(m) && !map_getmapflag(m, MF_BATTLEGROUND) && !map_getmapflag(m, MF_SKILL_DAMAGE) && !map_getmapflag(m, MF_RESTRICTED))) || + (damage->map&2 && map_getmapflag(m, MF_PVP)) || (damage->map&4 && map_flag_gvg2(m)) || - (damage->map&8 && mapd->flag.battleground) || - (damage->map&16 && mapd->flag.skill_damage) || - (mapd->flag.restricted && damage->map&(8*mapd->zone))) + (damage->map&8 && map_getmapflag(m, MF_BATTLEGROUND)) || + (damage->map&16 && map_getmapflag(m, MF_SKILL_DAMAGE)) || + (map_getmapflag(m, MF_RESTRICTED) && damage->map&(8*map[m].zone))) { - switch (target->type) { - case BL_PC: - return damage->pc; - case BL_MOB: - if (status_get_class_(target) == CLASS_BOSS) - return damage->boss; - else - return damage->mob; - default: - return damage->other; - } + return damage->rate[battle_skill_damage_type(target)]; } return 0; @@ -2230,55 +2214,22 @@ static int battle_skill_damage_skill(struct block_list *src, struct block_list * */ static int battle_skill_damage_map(struct block_list *src, struct block_list *target, uint16 skill_id) { int rate = 0; - uint8 i = 0; - struct map_data *mapd = NULL; + struct map_data *mapd = &map[src->m]; - mapd = &map[src->m]; - - if (!mapd || !mapd->flag.skill_damage) + if (!mapd || !map_getmapflag(src->m, MF_SKILL_DAMAGE)) return 0; // Damage rate for all skills at this map - if (battle_skill_damage_iscaster(mapd->adjust.damage.caster, src->type)) { - switch (target->type) { - case BL_PC: - rate = mapd->adjust.damage.pc; - break; - case BL_MOB: - if (status_get_class_(target) == CLASS_BOSS) - rate = mapd->adjust.damage.boss; - else - rate = mapd->adjust.damage.mob; - break; - default: - rate = mapd->adjust.damage.other; - break; - } - } + if (mapd->damage_adjust.caster&src->type) + rate = mapd->damage_adjust.rate[battle_skill_damage_type(target)]; - if (!mapd->skill_damage.count) + if (mapd->skill_damage.empty()) return rate; // Damage rate for specified skill at this map - for (i = 0; i < mapd->skill_damage.count; i++) { - if (mapd->skill_damage.entries[i]->skill_id == skill_id && - battle_skill_damage_iscaster(mapd->skill_damage.entries[i]->caster, src->type)) - { - switch (target->type) { - case BL_PC: - rate += mapd->skill_damage.entries[i]->pc; - break; - case BL_MOB: - if (status_get_class_(target) == CLASS_BOSS) - rate += mapd->skill_damage.entries[i]->boss; - else - rate += mapd->skill_damage.entries[i]->mob; - break; - default: - rate += mapd->skill_damage.entries[i]->other; - break; - } - } + for (int i = 0; i < mapd->skill_damage.size(); i++) { + if (mapd->skill_damage[i].skill_id == skill_id && mapd->skill_damage[i].caster&src->type) + rate += mapd->skill_damage[i].rate[battle_skill_damage_type(target)]; } return rate; } @@ -5111,14 +5062,14 @@ struct Damage battle_calc_attack_gvg_bg(struct Damage wd, struct block_list *src wd.damage = battle_calc_damage(src,target,&wd,wd.damage,skill_id,skill_lv); if( map_flag_gvg2(target->m) ) wd.damage=battle_calc_gvg_damage(src,target,wd.damage,skill_id,wd.flag); - else if( map[target->m].flag.battleground ) + else if( map_getmapflag(target->m, MF_BATTLEGROUND) ) wd.damage=battle_calc_bg_damage(src,target,wd.damage,skill_id,wd.flag); } else if(!wd.damage) { wd.damage2 = battle_calc_damage(src,target,&wd,wd.damage2,skill_id,skill_lv); if( map_flag_gvg2(target->m) ) wd.damage2 = battle_calc_gvg_damage(src,target,wd.damage2,skill_id,wd.flag); - else if( map[target->m].flag.battleground ) + else if( map_getmapflag(target->m, MF_BATTLEGROUND) ) wd.damage2 = battle_calc_bg_damage(src,target,wd.damage2,skill_id,wd.flag); } else { @@ -5126,7 +5077,7 @@ struct Damage battle_calc_attack_gvg_bg(struct Damage wd, struct block_list *src wd.damage = battle_calc_damage(src,target,&wd,d1,skill_id,skill_lv); if( map_flag_gvg2(target->m) ) wd.damage = battle_calc_gvg_damage(src,target,wd.damage,skill_id,wd.flag); - else if( map[target->m].flag.battleground ) + else if( map_getmapflag(target->m, MF_BATTLEGROUND) ) wd.damage = battle_calc_bg_damage(src,target,wd.damage,skill_id,wd.flag); wd.damage2 = (int64)d2*100/d1 * wd.damage/100; if(wd.damage > 1 && wd.damage2 < 1) wd.damage2 = 1; @@ -6441,7 +6392,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list ad.damage = battle_calc_damage(src,target,&ad,ad.damage,skill_id,skill_lv); if (map_flag_gvg2(target->m)) ad.damage = battle_calc_gvg_damage(src,target,ad.damage,skill_id,ad.flag); - else if (map[target->m].flag.battleground) + else if (map_getmapflag(target->m, MF_BATTLEGROUND)) ad.damage = battle_calc_bg_damage(src,target,ad.damage,skill_id,ad.flag); // Skill damage adjustment @@ -6837,7 +6788,7 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list * md.damage = battle_calc_damage(src,target,&md,md.damage,skill_id,skill_lv); if(map_flag_gvg2(target->m)) md.damage = battle_calc_gvg_damage(src,target,md.damage,skill_id,md.flag); - else if(map[target->m].flag.battleground) + else if(map_getmapflag(target->m, MF_BATTLEGROUND)) md.damage = battle_calc_bg_damage(src,target,md.damage,skill_id,md.flag); // Skill damage adjustment @@ -7756,7 +7707,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f case NC_AXETORNADO: case SR_SKYNETBLOW: // Can only hit traps in PVP/GVG maps - if (!map[m].flag.pvp && !map[m].flag.gvg) + if (!map_getmapflag(m, MF_PVP) && !map_getmapflag(m, MF_GVG)) return 0; break; } @@ -7773,7 +7724,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f case NC_AXETORNADO: case SR_SKYNETBLOW: // Can only hit icewall in PVP/GVG maps - if (!map[m].flag.pvp && !map[m].flag.gvg) + if (!map_getmapflag(m, MF_PVP) && !map_getmapflag(m, MF_GVG)) return 0; break; case HT_CLAYMORETRAP: @@ -7877,7 +7828,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f state |= BCT_ENEMY; // Can kill anything strip_enemy = 0; } - else if( sd->duel_group && !((!battle_config.duel_allow_pvp && map[m].flag.pvp) || (!battle_config.duel_allow_gvg && map_flag_gvg(m))) ) + else if( sd->duel_group && !((!battle_config.duel_allow_pvp && map_getmapflag(m, MF_PVP)) || (!battle_config.duel_allow_gvg && map_flag_gvg(m))) ) { if( t_bl->type == BL_PC && (sd->duel_group == ((TBL_PC*)t_bl)->duel_group) ) return (BCT_ENEMY&flag)?1:-1; // Duel targets can ONLY be your enemy, nothing else. @@ -7942,7 +7893,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f if( map_flag_vs(m) ) { //Check rivalry settings. int sbg_id = 0, tbg_id = 0; - if( map[m].flag.battleground ) + if( map_getmapflag(m, MF_BATTLEGROUND) ) { sbg_id = bg_team_get_id(s_bl); tbg_id = bg_team_get_id(t_bl); @@ -7950,7 +7901,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f if( flag&(BCT_PARTY|BCT_ENEMY) ) { int s_party = status_get_party_id(s_bl); - if( s_party && s_party == status_get_party_id(t_bl) && !(map[m].flag.pvp && map[m].flag.pvp_noparty) && !(map_flag_gvg(m) && map[m].flag.gvg_noparty) && (!map[m].flag.battleground || sbg_id == tbg_id) ) + if( s_party && s_party == status_get_party_id(t_bl) && !(map_getmapflag(m, MF_PVP) && map_getmapflag(m, MF_PVP_NOPARTY)) && !(map_flag_gvg(m) && map_getmapflag(m, MF_GVG_NOPARTY)) && (!map_getmapflag(m, MF_BATTLEGROUND) || sbg_id == tbg_id) ) state |= BCT_PARTY; else state |= BCT_ENEMY; @@ -7959,12 +7910,12 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f { int s_guild = status_get_guild_id(s_bl); int t_guild = status_get_guild_id(t_bl); - if( !(map[m].flag.pvp && map[m].flag.pvp_noguild) && s_guild && t_guild && (s_guild == t_guild || (!(flag&BCT_SAMEGUILD) && guild_isallied(s_guild, t_guild))) && (!map[m].flag.battleground || sbg_id == tbg_id) ) + if( !(map_getmapflag(m, MF_PVP) && map_getmapflag(m, MF_PVP_NOGUILD)) && s_guild && t_guild && (s_guild == t_guild || (!(flag&BCT_SAMEGUILD) && guild_isallied(s_guild, t_guild))) && (!map_getmapflag(m, MF_BATTLEGROUND) || sbg_id == tbg_id) ) state |= BCT_GUILD; else state |= BCT_ENEMY; } - if( state&BCT_ENEMY && map[m].flag.battleground && sbg_id && sbg_id == tbg_id ) + if( state&BCT_ENEMY && map_getmapflag(m, MF_BATTLEGROUND) && sbg_id && sbg_id == tbg_id ) state &= ~BCT_ENEMY; if( state&BCT_ENEMY && battle_config.pk_mode && !map_flag_gvg(m) && s_bl->type == BL_PC && t_bl->type == BL_PC ) diff --git a/src/map/buyingstore.cpp b/src/map/buyingstore.cpp index dcaa14f2bf..173997a80c 100644 --- a/src/map/buyingstore.cpp +++ b/src/map/buyingstore.cpp @@ -78,7 +78,7 @@ int8 buyingstore_setup(struct map_session_data* sd, unsigned char slots){ return 2; } - if( map[sd->bl.m].flag.novending ) + if( map_getmapflag(sd->bl.m, MF_NOVENDING) ) {// custom: no vending maps clif_displaymessage(sd->fd, msg_txt(sd,276)); // "You can't open a shop on this map" return 3; @@ -146,7 +146,7 @@ int8 buyingstore_create(struct map_session_data* sd, int zenylimit, unsigned cha return 2; } - if( map[sd->bl.m].flag.novending ) + if( map_getmapflag(sd->bl.m, MF_NOVENDING) ) {// custom: no vending maps clif_displaymessage(sd->fd, msg_txt(sd,276)); // "You can't open a shop on this map" return 3; diff --git a/src/map/chat.cpp b/src/map/chat.cpp index c8a29c63a9..6bd616096f 100644 --- a/src/map/chat.cpp +++ b/src/map/chat.cpp @@ -86,7 +86,7 @@ int chat_createpcchat(struct map_session_data* sd, const char* title, const char if( sd->state.vending || sd->state.buyingstore ) // not chat, when you already have a store open return 0; - if( map[sd->bl.m].flag.nochat ) { + if( map_getmapflag(sd->bl.m, MF_NOCHAT) ) { clif_displaymessage(sd->fd, msg_txt(sd,281)); return 0; //Can't create chatrooms on this map. } diff --git a/src/map/chrif.cpp b/src/map/chrif.cpp index c4afd45eb1..6bd913fe26 100644 --- a/src/map/chrif.cpp +++ b/src/map/chrif.cpp @@ -400,9 +400,9 @@ int chrif_sendmap(int fd) { ShowStatus("Sending maps to char server...\n"); // Sending normal maps, not instances - WFIFOHEAD(fd, 4 + instance_start * 4); + WFIFOHEAD(fd, 4 + map.size() * 4); WFIFOW(fd,0) = 0x2afa; - for(i = 0; i < instance_start; i++) + for(i = 0; i < map.size(); i++) WFIFOW(fd,4+i*4) = map[i].index; WFIFOW(fd,2) = 4 + i * 4; WFIFOSET(fd,WFIFOW(fd,2)); diff --git a/src/map/clif.cpp b/src/map/clif.cpp index 76c10324be..1b1d639b94 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -1120,7 +1120,7 @@ static int clif_set_unit_idle(struct block_list* bl, unsigned char* buffer, bool WBUFW(buf,53) = (sd ? sd->status.font : 0); #endif #if PACKETVER >= 20120221 - if ( battle_config.monster_hp_bars_info && !map[bl->m].flag.hidemobhpbar && bl->type == BL_MOB && (status_get_hp(bl) < status_get_max_hp(bl)) ) { + if ( battle_config.monster_hp_bars_info && !map_getmapflag(bl->m, MF_HIDEMOBHPBAR) && bl->type == BL_MOB && (status_get_hp(bl) < status_get_max_hp(bl)) ) { WBUFL(buf,55) = status_get_max_hp(bl); // maxHP WBUFL(buf,59) = status_get_hp(bl); // HP } else { @@ -1263,7 +1263,7 @@ static int clif_set_unit_walking(struct block_list* bl, struct unit_data* ud, un WBUFW(buf,60) = (sd ? sd->status.font : 0); #endif #if PACKETVER >= 20120221 - if ( battle_config.monster_hp_bars_info && !map[bl->m].flag.hidemobhpbar && bl->type == BL_MOB && (status_get_hp(bl) < status_get_max_hp(bl)) ) { + if ( battle_config.monster_hp_bars_info && !map_getmapflag(bl->m, MF_HIDEMOBHPBAR) && bl->type == BL_MOB && (status_get_hp(bl) < status_get_max_hp(bl)) ) { WBUFL(buf,62) = status_get_max_hp(bl); // maxHP WBUFL(buf,66) = status_get_hp(bl); // HP } else { @@ -1361,30 +1361,30 @@ static void clif_weather_check(struct map_session_data *sd) int16 m = sd->bl.m; int fd = sd->fd; - if (map[m].flag.snow - || map[m].flag.clouds - || map[m].flag.fog - || map[m].flag.fireworks - || map[m].flag.sakura - || map[m].flag.leaves - || map[m].flag.clouds2) + if (map_getmapflag(m, MF_SNOW) + || map_getmapflag(m, MF_CLOUDS) + || map_getmapflag(m, MF_FOG) + || map_getmapflag(m, MF_FIREWORKS) + || map_getmapflag(m, MF_SAKURA) + || map_getmapflag(m, MF_LEAVES) + || map_getmapflag(m, MF_CLOUDS2)) { - if (map[m].flag.snow) + if (map_getmapflag(m, MF_SNOW)) clif_specialeffect_single(&sd->bl, EF_SNOW, fd); - if (map[m].flag.clouds) + if (map_getmapflag(m, MF_CLOUDS)) clif_specialeffect_single(&sd->bl, EF_CLOUD3, fd); - if (map[m].flag.clouds2) + if (map_getmapflag(m, MF_CLOUDS2)) clif_specialeffect_single(&sd->bl, EF_CLOUD5, fd); - if (map[m].flag.fog) + if (map_getmapflag(m, MF_FOG)) clif_specialeffect_single(&sd->bl, EF_CLOUD4, fd); - if (map[m].flag.fireworks) { + if (map_getmapflag(m, MF_FIREWORKS)) { clif_specialeffect_single(&sd->bl, EF_POKJUK, fd); clif_specialeffect_single(&sd->bl, EF_THROWITEM2, fd); clif_specialeffect_single(&sd->bl, EF_POKJUK_SOUND, fd); } - if (map[m].flag.sakura) + if (map_getmapflag(m, MF_SAKURA)) clif_specialeffect_single(&sd->bl, EF_SAKURA, fd); - if (map[m].flag.leaves) + if (map_getmapflag(m, MF_LEAVES)) clif_specialeffect_single(&sd->bl, EF_MAPLE, fd); } } @@ -1445,7 +1445,7 @@ int clif_spawn(struct block_list *bl) clif_specialeffect(bl,EF_GIANTBODY2,AREA); else if(sd->state.size==SZ_MEDIUM) clif_specialeffect(bl,EF_BABYBODY2,AREA); - if( sd->bg_id && map[sd->bl.m].flag.battleground ) + if( sd->bg_id && map_getmapflag(sd->bl.m, MF_BATTLEGROUND) ) clif_sendbgemblem_area(sd); if (sd->spiritcharm_type != CHARM_TYPE_NONE && sd->spiritcharm > 0) clif_spiritcharm(sd); @@ -4642,7 +4642,7 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl) clif_specialeffect_single(bl,EF_GIANTBODY2,sd->fd); else if(tsd->state.size==SZ_MEDIUM) clif_specialeffect_single(bl,EF_BABYBODY2,sd->fd); - if( tsd->bg_id && map[tsd->bl.m].flag.battleground ) + if( tsd->bg_id && map_getmapflag(tsd->bl.m, MF_BATTLEGROUND) ) clif_sendbgemblem_single(sd->fd,tsd); if ( tsd->status.robe ) clif_refreshlook(&sd->bl,bl->id,LOOK_ROBE,tsd->status.robe,SELF); @@ -4675,7 +4675,7 @@ void clif_getareachar_unit(struct map_session_data* sd,struct block_list *bl) else if(md->special_state.size==SZ_MEDIUM) clif_specialeffect_single(bl,EF_BABYBODY2,sd->fd); #if PACKETVER >= 20120404 - if (battle_config.monster_hp_bars_info && !map[bl->m].flag.hidemobhpbar) { + if (battle_config.monster_hp_bars_info && !map_getmapflag(bl->m, MF_HIDEMOBHPBAR)) { int i; for(i = 0; i < DAMAGELOG_SIZE; i++)// must show hp bar to all char who already hit the mob. if( md->dmglog[i].id == sd->status.char_id ) @@ -6343,17 +6343,17 @@ void clif_map_property(struct block_list *bl, enum map_property property, enum s WBUFW(buf,2)=property; #if PACKETVER >= 20121010 - WBUFL(buf,4) = ((map[bl->m].flag.pvp?1:0)<<0)| // PARTY - Show attack cursor on non-party members (PvP) - ((map[bl->m].flag.battleground || map_flag_gvg2(bl->m)?1:0)<<1)|// GUILD - Show attack cursor on non-guild members (GvG) - ((map[bl->m].flag.battleground || map_flag_gvg2(bl->m)?1:0)<<2)|// SIEGE - Show emblem over characters heads when in GvG (WoE castle) - ((map[bl->m].flag.nomineeffect || !map_flag_gvg2(bl->m)?0:1)<<3)| // USE_SIMPLE_EFFECT - Automatically enable /mineffect - ((map[bl->m].flag.nolockon || map_flag_vs(bl->m)?1:0)<<4)| // DISABLE_LOCKON - Only allow attacks on other players with shift key or /ns active - ((map[bl->m].flag.pvp?1:0)<<5)| // COUNT_PK - Show the PvP counter - ((map[bl->m].flag.partylock?1:0)<<6)| // NO_PARTY_FORMATION - Prevents party creation/modification (Might be used for instance dungeons) - ((map[bl->m].flag.battleground?1:0)<<7)| // BATTLEFIELD - Unknown (Does something for battlegrounds areas) - ((map[bl->m].flag.nocostume?1:0)<<8)| // DISABLE_COSTUMEITEM - Disable costume sprites - ((map[bl->m].flag.nousecart?0:1)<<9)| // USECART - Allow opening cart inventory (Well force it to always allow it) - ((map[bl->m].flag.nosumstarmiracle?0:1)<<10); // SUNMOONSTAR_MIRACLE - Unknown - (Guessing it blocks Star Gladiator's Miracle from activating) + WBUFL(buf,4) = ((map_getmapflag(bl->m, MF_PVP)?1:0)<<0)| // PARTY - Show attack cursor on non-party members (PvP) + ((map_getmapflag(bl->m, MF_BATTLEGROUND) || map_flag_gvg2(bl->m)?1:0)<<1)|// GUILD - Show attack cursor on non-guild members (GvG) + ((map_getmapflag(bl->m, MF_BATTLEGROUND) || map_flag_gvg2(bl->m)?1:0)<<2)|// SIEGE - Show emblem over characters heads when in GvG (WoE castle) + ((map_getmapflag(bl->m, MF_NOMINEEFFECT) || !map_flag_gvg2(bl->m)?0:1)<<3)| // USE_SIMPLE_EFFECT - Automatically enable /mineffect + ((map_getmapflag(bl->m, MF_NOLOCKON) || map_flag_vs(bl->m)?1:0)<<4)| // DISABLE_LOCKON - Only allow attacks on other players with shift key or /ns active + ((map_getmapflag(bl->m, MF_PVP)?1:0)<<5)| // COUNT_PK - Show the PvP counter + ((map_getmapflag(bl->m, MF_PARTYLOCK)?1:0)<<6)| // NO_PARTY_FORMATION - Prevents party creation/modification (Might be used for instance dungeons) + ((map_getmapflag(bl->m, MF_BATTLEGROUND)?1:0)<<7)| // BATTLEFIELD - Unknown (Does something for battlegrounds areas) + ((map_getmapflag(bl->m, MF_NOCOSTUME)?1:0)<<8)| // DISABLE_COSTUMEITEM - Disable costume sprites + ((map_getmapflag(bl->m, MF_NOUSECART)?0:1)<<9)| // USECART - Allow opening cart inventory (Well force it to always allow it) + ((map_getmapflag(bl->m, MF_NOSUNMOONSTARMIRACLE)?0:1)<<10); // SUNMOONSTAR_MIRACLE - Blocks Star Gladiator's Miracle from activating //(1<<11); // Unused bits. 1 - 10 is 0x1 length and 11 is 0x15 length. May be used for future settings. #endif @@ -10088,7 +10088,7 @@ static bool clif_process_message(struct map_session_data* sd, bool whisperFormat inline void clif_pk_mode_message(struct map_session_data * sd) { if (battle_config.pk_mode && battle_config.pk_mode_mes && - sd && map[sd->bl.m].flag.pvp) { + sd && map_getmapflag(sd->bl.m, MF_PVP)) { if( (int)sd->status.base_level < battle_config.pk_min_level ) { char output[CHAT_SIZE_MAX]; // 1504: You've entered a PK Zone (safe until level %d). @@ -10331,9 +10331,9 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) if( sd->bg_id ) clif_bg_hp(sd); // BattleGround System - if(map[sd->bl.m].flag.pvp && !pc_isinvisible(sd)) { + if(map_getmapflag(sd->bl.m, MF_PVP) && !pc_isinvisible(sd)) { if(!battle_config.pk_mode) { // remove pvp stuff for pk_mode [Valaris] - if (!map[sd->bl.m].flag.pvp_nocalcrank) + if (!map_getmapflag(sd->bl.m, MF_PVP_NOCALCRANK)) sd->pvp_timer = add_timer(gettick()+200, pc_calc_pvprank_timer, sd->bl.id, 0); sd->pvp_rank = 0; sd->pvp_lastusers = 0; @@ -10344,7 +10344,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) clif_map_property(&sd->bl, MAPPROPERTY_FREEPVPZONE, SELF); } else if(sd->duel_group) // set flag, if it's a duel [LuzZza] clif_map_property(&sd->bl, MAPPROPERTY_FREEPVPZONE, SELF); - else if (map[sd->bl.m].flag.gvg_dungeon) + else if (map_getmapflag(sd->bl.m, MF_GVG_DUNGEON)) clif_map_property(&sd->bl, MAPPROPERTY_FREEPVPZONE, SELF); //TODO: Figure out the real packet to send here. else if( map_flag_gvg(sd->bl.m) ) clif_map_property(&sd->bl, MAPPROPERTY_AGITZONE, SELF); @@ -10443,7 +10443,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) if(hom_is_active(sd->hd)) hom_init_timers(sd->hd); - if (night_flag && map[sd->bl.m].flag.nightenabled) { + if (night_flag && map_getmapflag(sd->bl.m, MF_NIGHTENABLED)) { sd->state.night = 1; clif_status_load(&sd->bl, EFST_SKE, 1); } @@ -10500,10 +10500,10 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) } if( (battle_config.bg_flee_penalty != 100 || battle_config.gvg_flee_penalty != 100) && - (map_flag_gvg(sd->state.pmap) || map_flag_gvg(sd->bl.m) || map[sd->state.pmap].flag.battleground || map[sd->bl.m].flag.battleground) ) + (map_flag_gvg(sd->state.pmap) || map_flag_gvg(sd->bl.m) || map_getmapflag(sd->state.pmap, MF_BATTLEGROUND) || map_getmapflag(sd->bl.m, MF_BATTLEGROUND)) ) status_calc_bl(&sd->bl, SCB_FLEE); //Refresh flee penalty - if( night_flag && map[sd->bl.m].flag.nightenabled ) + if( night_flag && map_getmapflag(sd->bl.m, MF_NIGHTENABLED) ) { //Display night. if( !sd->state.night ) { @@ -10517,14 +10517,14 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) clif_status_load(&sd->bl, EFST_SKE, 0); } - if( map[sd->bl.m].flag.battleground ) + if( map_getmapflag(sd->bl.m, MF_BATTLEGROUND) ) { clif_map_type(sd, MAPTYPE_BATTLEFIELD); // Battleground Mode - if( map[sd->bl.m].flag.battleground == 2 ) + if( map_getmapflag(sd->bl.m, MF_BATTLEGROUND) == 2 ) clif_bg_updatescore_single(sd); } - if( map[sd->bl.m].flag.allowks && !map_flag_ks(sd->bl.m) ) + if( map_getmapflag(sd->bl.m, MF_ALLOWKS) && !map_flag_ks(sd->bl.m) ) { char output[128]; sprintf(output, "[ Kill Steal Protection Disable. KS is allowed in this map ]"); @@ -10544,7 +10544,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) if (!sd->state.connect_new && !sd->vip.disableshowrate && sd->state.pmap != sd->bl.m && - map[sd->state.pmap].adjust.bexp != map[sd->bl.m].adjust.bexp + map_getmapflag(sd->state.pmap, MF_BEXP) != map_getmapflag(sd->bl.m, MF_BEXP) ) { clif_display_pinfo(sd,ZC_PERSONAL_INFOMATION); @@ -10553,7 +10553,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) #endif // Instances do not need their own channels - if( channel_config.map_tmpl.name[0] && (channel_config.map_tmpl.opt&CHAN_OPT_AUTOJOIN) && !map[sd->bl.m].flag.chmautojoin && !map[sd->bl.m].instance_id ) + if( channel_config.map_tmpl.name[0] && (channel_config.map_tmpl.opt&CHAN_OPT_AUTOJOIN) && !map_getmapflag(sd->bl.m,MF_NOMAPCHANNELAUTOJOIN) && !map[sd->bl.m].instance_id ) channel_mjoin(sd); //join new map clif_pk_mode_message(sd); @@ -10579,7 +10579,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) } // Don't trigger NPC event or opening vending/buyingstore will be failed - if(!sd->state.autotrade && map[sd->bl.m].flag.loadevent) // Lance + if(!sd->state.autotrade && map_getmapflag(sd->bl.m, MF_LOADEVENT)) // Lance npc_script_event(sd, NPCE_LOADMAP); if (pc_checkskill(sd, SG_DEVIL) && pc_is_maxjoblv(sd)) @@ -12908,7 +12908,7 @@ void clif_parse_CreateParty(int fd, struct map_session_data *sd){ char* name = RFIFOCP(fd,packet_db[RFIFOW(fd,0)].pos[0]); name[NAME_LENGTH-1] = '\0'; - if( map[sd->bl.m].flag.partylock ) {// Party locked. + if( map_getmapflag(sd->bl.m, MF_PARTYLOCK) ) {// Party locked. clif_displaymessage(fd, msg_txt(sd,227)); return; } @@ -12928,7 +12928,7 @@ void clif_parse_CreateParty2(int fd, struct map_session_data *sd){ int item2 = RFIFOB(fd,info->pos[2]); name[NAME_LENGTH-1] = '\0'; - if( map[sd->bl.m].flag.partylock ) {// Party locked. + if( map_getmapflag(sd->bl.m, MF_PARTYLOCK) ) {// Party locked. clif_displaymessage(fd, msg_txt(sd,227)); return; } @@ -12947,7 +12947,7 @@ void clif_parse_PartyInvite(int fd, struct map_session_data *sd) { struct map_session_data *t_sd; - if(map[sd->bl.m].flag.partylock) {// Party locked. + if(map_getmapflag(sd->bl.m, MF_PARTYLOCK)) {// Party locked. clif_displaymessage(fd, msg_txt(sd,227)); return; } @@ -12968,7 +12968,7 @@ void clif_parse_PartyInvite2(int fd, struct map_session_data *sd){ char *name = RFIFOCP(fd,packet_db[RFIFOW(fd,0)].pos[0]); name[NAME_LENGTH-1] = '\0'; - if(map[sd->bl.m].flag.partylock) {// Party locked. + if(map_getmapflag(sd->bl.m, MF_PARTYLOCK)) {// Party locked. clif_displaymessage(fd, msg_txt(sd,227)); return; } @@ -13009,7 +13009,7 @@ void clif_parse_ReplyPartyInvite2(int fd,struct map_session_data *sd) /// 0100 void clif_parse_LeaveParty(int fd, struct map_session_data *sd) { - if(map[sd->bl.m].flag.partylock) {// Party locked. + if(map_getmapflag(sd->bl.m, MF_PARTYLOCK)) {// Party locked. clif_displaymessage(fd, msg_txt(sd,227)); return; } @@ -13022,7 +13022,7 @@ void clif_parse_LeaveParty(int fd, struct map_session_data *sd) void clif_parse_RemovePartyMember(int fd, struct map_session_data *sd) { struct s_packet_db* info = &packet_db[RFIFOW(fd,0)]; - if(map[sd->bl.m].flag.partylock) {// Party locked. + if(map_getmapflag(sd->bl.m, MF_PARTYLOCK)) {// Party locked. clif_displaymessage(fd, msg_txt(sd,227)); return; } @@ -13337,7 +13337,7 @@ void clif_parse_OpenVending(int fd, struct map_session_data* sd){ if( sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOROOM ) return; - if( map[sd->bl.m].flag.novending ) { + if( map_getmapflag(sd->bl.m, MF_NOVENDING) ) { clif_displaymessage (sd->fd, msg_txt(sd,276)); // "You can't open a shop on this map" return; } @@ -13360,7 +13360,7 @@ void clif_parse_CreateGuild(int fd,struct map_session_data *sd){ char* name = RFIFOCP(fd,packet_db[RFIFOW(fd,0)].pos[1]); name[NAME_LENGTH-1] = '\0'; - if(map[sd->bl.m].flag.guildlock) { //Guild locked. + if(map_getmapflag(sd->bl.m, MF_GUILDLOCK)) { //Guild locked. clif_displaymessage(fd, msg_txt(sd,228)); return; } @@ -13586,7 +13586,7 @@ int clif_sub_guild_invite(int fd, struct map_session_data *sd, struct map_sessio if (t_sd == NULL) // not online or does not exist return 1; - if (map[sd->bl.m].flag.guildlock) {//Guild locked. + if (map_getmapflag(sd->bl.m, MF_GUILDLOCK)) {//Guild locked. clif_displaymessage(fd, msg_txt(sd,228)); return 1; } @@ -13644,7 +13644,7 @@ void clif_parse_GuildReplyInvite(int fd,struct map_session_data *sd){ /// 0159 .L .L .L .40B void clif_parse_GuildLeave(int fd,struct map_session_data *sd){ struct s_packet_db* info = &packet_db[RFIFOW(fd,0)]; - if(map[sd->bl.m].flag.guildlock) { //Guild locked. + if(map_getmapflag(sd->bl.m, MF_GUILDLOCK)) { //Guild locked. clif_displaymessage(fd, msg_txt(sd,228)); return; } @@ -13664,7 +13664,7 @@ void clif_parse_GuildLeave(int fd,struct map_session_data *sd){ /// 015b .L .L .L .40B void clif_parse_GuildExpulsion(int fd,struct map_session_data *sd){ struct s_packet_db* info = &packet_db[RFIFOW(fd,0)]; - if( map[sd->bl.m].flag.guildlock || sd->bg_id ) + if( map_getmapflag(sd->bl.m, MF_GUILDLOCK) || sd->bg_id ) { // Guild locked. clif_displaymessage(fd, msg_txt(sd,228)); return; @@ -13701,7 +13701,7 @@ void clif_parse_GuildRequestAlliance(int fd, struct map_session_data *sd) if(!sd->state.gmaster_flag) return; - if(map[sd->bl.m].flag.guildlock) { //Guild locked. + if(map_getmapflag(sd->bl.m, MF_GUILDLOCK)) { //Guild locked. clif_displaymessage(fd, msg_txt(sd,228)); return; } @@ -13743,7 +13743,7 @@ void clif_parse_GuildDelAlliance(int fd, struct map_session_data *sd){ if(!sd->state.gmaster_flag) return; - if(map[sd->bl.m].flag.guildlock) { //Guild locked. + if(map_getmapflag(sd->bl.m, MF_GUILDLOCK)) { //Guild locked. clif_displaymessage(fd, msg_txt(sd,228)); return; } @@ -13762,7 +13762,7 @@ void clif_parse_GuildOpposition(int fd, struct map_session_data *sd) if(!sd->state.gmaster_flag) return; - if(map[sd->bl.m].flag.guildlock) { //Guild locked. + if(map_getmapflag(sd->bl.m, MF_GUILDLOCK)) { //Guild locked. clif_displaymessage(fd, msg_txt(sd,228)); return; } @@ -13786,7 +13786,7 @@ void clif_parse_GuildOpposition(int fd, struct map_session_data *sd) /// field name and size is same as the one in CH_DELETE_CHAR. void clif_parse_GuildBreak(int fd, struct map_session_data *sd) { - if( map[sd->bl.m].flag.guildlock ) { //Guild locked. + if( map_getmapflag(sd->bl.m, MF_GUILDLOCK) ) { //Guild locked. clif_displaymessage(fd, msg_txt(sd,228)); return; } @@ -18787,7 +18787,7 @@ void clif_display_pinfo(struct map_session_data *sd, int cmdtype) { * Set for EXP */ //0:PCRoom - details_bexp[0] = map[sd->bl.m].adjust.bexp; + details_bexp[0] = map_getmapflag(sd->bl.m, MF_BEXP); if (details_bexp[0] == 100 || !details_bexp[0]) details_bexp[0] = 0; else { diff --git a/src/map/instance.cpp b/src/map/instance.cpp index 809741d665..85885378f6 100644 --- a/src/map/instance.cpp +++ b/src/map/instance.cpp @@ -25,8 +25,6 @@ #define INSTANCE_INTERVAL 60000 // Interval used to check when an instance is to be destroyed (ms) -int instance_start = 0; // To keep the last index + 1 of normal map inserted in the map[ARRAY] - struct instance_data instance_data[MAX_INSTANCE_DATA]; struct eri *instance_maps_ers = NULL; ///< Array of maps per instance diff --git a/src/map/instance.hpp b/src/map/instance.hpp index 27f5639733..c299091ac6 100644 --- a/src/map/instance.hpp +++ b/src/map/instance.hpp @@ -72,7 +72,6 @@ struct instance_db { uint8 maplist_count; ///< Number of used maps }; -extern int instance_start; extern struct instance_data instance_data[MAX_INSTANCE_DATA]; struct instance_db *instance_searchtype_db(unsigned short instance_id); diff --git a/src/map/itemdb.cpp b/src/map/itemdb.cpp index 2f69a937b4..61ba8f4267 100644 --- a/src/map/itemdb.cpp +++ b/src/map/itemdb.cpp @@ -1582,11 +1582,11 @@ bool itemdb_isNoEquip(struct item_data *id, uint16 m) { if (!id->flag.no_equip) return false; if ((!map_flag_vs2(m) && id->flag.no_equip&1) || // Normal - (map[m].flag.pvp && id->flag.no_equip&2) || // PVP + (map_getmapflag(m, MF_PVP) && id->flag.no_equip&2) || // PVP (map_flag_gvg2_no_te(m) && id->flag.no_equip&4) || // GVG - (map[m].flag.battleground && id->flag.no_equip&8) || // Battleground + (map_getmapflag(m, MF_BATTLEGROUND) && id->flag.no_equip&8) || // Battleground (map_flag_gvg2_te(m) && id->flag.no_equip&16) || // WOE:TE - (map[m].flag.restricted && id->flag.no_equip&(8*map[m].zone)) // Zone restriction + (map_getmapflag(m, MF_RESTRICTED) && id->flag.no_equip&(8*map[m].zone)) // Zone restriction ) return true; return false; diff --git a/src/map/mail.cpp b/src/map/mail.cpp index 94bf1650e8..f2c551cfca 100644 --- a/src/map/mail.cpp +++ b/src/map/mail.cpp @@ -326,7 +326,7 @@ void mail_deliveryfail(struct map_session_data *sd, struct mail_message *msg){ bool mail_invalid_operation(struct map_session_data *sd) { #if PACKETVER < 20150513 - if( !map[sd->bl.m].flag.town && !pc_can_use_command(sd, "mail", COMMAND_ATCOMMAND) ) + if( !map_getmapflag(sd->bl.m, MF_TOWN) && !pc_can_use_command(sd, "mail", COMMAND_ATCOMMAND) ) { ShowWarning("clif_parse_Mail: char '%s' trying to do invalid mail operations.\n", sd->status.name); return true; diff --git a/src/map/map.cpp b/src/map/map.cpp index 91a26f4388..7d5f0fea88 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -18,6 +18,7 @@ #include "../common/socket.hpp" // WFIFO*() #include "../common/strlib.hpp" #include "../common/timer.hpp" +#include "../common/utilities.hpp" #include "../common/utils.hpp" #include "achievement.hpp" @@ -49,6 +50,8 @@ #include "storage.hpp" #include "trade.hpp" +using namespace rathena; + char default_codepage[32] = ""; int map_server_port = 3306; @@ -119,8 +122,7 @@ static int bl_list_count = 0; #define MAP_MAX_MSG 1550 #endif -struct map_data map[MAX_MAP_PER_SERVER]; -int map_num = 0; +std::vector map; int map_port=0; int autosave_interval = DEFAULT_AUTOSAVE_INTERVAL; @@ -131,10 +133,6 @@ bool agit2_flag = false; bool agit3_flag = false; int night_flag = 0; // 0=day, 1=night [Yor] -#ifdef ADJUST_SKILL_DAMAGE -struct eri *map_skill_damage_ers = NULL; -#endif - struct charid_request { struct charid_request* next; int charid;// who want to be notified of the nick @@ -311,9 +309,9 @@ int map_addblock(struct block_list* bl) m = bl->m; x = bl->x; y = bl->y; - if( m < 0 || m >= map_num ) + if( m < 0 || m >= map.size() ) { - ShowError("map_addblock: invalid map id (%d), only %d are loaded.\n", m, map_num); + ShowError("map_addblock: invalid map id (%d), only %d are loaded.\n", m, map.size()); return 1; } if( x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys ) @@ -707,7 +705,7 @@ int map_foreachinareaV(int(*func)(struct block_list*, va_list), int16 m, int16 x int blockcount = bl_list_count, i; va_list ap_copy; - if (m < 0 || m >= map_num) + if (m < 0 || m >= map.size()) return 0; if (x1 < x0) @@ -2542,7 +2540,7 @@ bool map_addnpc(int16 m,struct npc_data *nd) { nullpo_ret(nd); - if( m < 0 || m >= map_num ) + if( m < 0 || m >= map.size() ) return false; if( map[m].npc_num == MAX_NPC_PER_MAP ) @@ -2563,7 +2561,6 @@ bool map_addnpc(int16 m,struct npc_data *nd) int map_addinstancemap(const char *name, unsigned short instance_id) { int src_m = map_mapname2mapid(name); - int dst_m = -1, i; char iname[MAP_NAME_LENGTH]; size_t num_cell, size; @@ -2576,24 +2573,15 @@ int map_addinstancemap(const char *name, unsigned short instance_id) return -2; } - for(i = instance_start; i < MAX_MAP_PER_SERVER; i++) { - if(!map[i].name[0]) - break; - } - if(i < map_num) // Destination map value overwrites another - dst_m = i; - else if(i < MAX_MAP_PER_SERVER) // Destination map value increments to new map - dst_m = map_num++; - else { - // Out of bounds - ShowError("map_addinstancemap failed. map_num(%d) > map_max(%d)\n",map_num, MAX_MAP_PER_SERVER); + if(map.size() >= MAX_MAP_PER_SERVER) { // Out of bounds + ShowError("map_addinstancemap: Failed to add map. Map size (%d) > max maps (%d)\n", map.size(), MAX_MAP_PER_SERVER); return -3; } // Copy the map - memcpy(&map[dst_m], &map[src_m], sizeof(struct map_data)); - - strcpy(iname,name); + int dst_m = map.size(); + map.push_back(map[src_m]); + strcpy(iname, name); // Alter the name // Due to this being custom we only worry about preserving as many characters as necessary for accurate map distinguishing @@ -3114,7 +3102,7 @@ void map_setcell(int16 m, int16 x, int16 y, cell_t cell, bool flag) { int j; - if( m < 0 || m >= map_num || x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys ) + if( m < 0 || m >= map.size() || x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys ) return; j = x + y*map[m].xs; @@ -3142,7 +3130,7 @@ void map_setgatcell(int16 m, int16 x, int16 y, int gat) int j; struct mapcell cell; - if( m < 0 || m >= map_num || x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys ) + if( m < 0 || m >= map.size() || x < 0 || x >= map[m].xs || y < 0 || y >= map[m].ys ) return; j = x + y*map[m].xs; @@ -3423,27 +3411,27 @@ int map_addmap(char* mapname) { if( strcmpi(mapname,"clear")==0 ) { - map_num = 0; - instance_start = 0; + map.clear(); return 0; } - if( map_num >= MAX_MAP_PER_SERVER - 1 ) + if( map.size() >= MAX_MAP_PER_SERVER ) { ShowError("Could not add map '" CL_WHITE "%s" CL_RESET "', the limit of maps has been reached.\n",mapname); return 1; } - mapindex_getmapname(mapname, map[map_num].name); - map_num++; + struct map_data entry = {}; + + mapindex_getmapname(mapname, entry.name); + map.push_back(entry); return 0; } static void map_delmapid(int id) { ShowNotice("Removing map [ %s ] from maplist" CL_CLL "\n",map[id].name); - memmove(map+id, map+id+1, sizeof(map[0])*(map_num-id-1)); - map_num--; + map.erase(map.begin() + id); } int map_delmap(char* mapname) @@ -3452,12 +3440,12 @@ int map_delmap(char* mapname) char map_name[MAP_NAME_LENGTH]; if (strcmpi(mapname, "all") == 0) { - map_num = 0; + map.clear(); return 0; } mapindex_getmapname(mapname, map_name); - for(i = 0; i < map_num; i++) { + for(i = 0; i < map.size(); i++) { if (strcmp(map[i].name, map_name) == 0) { map_delmapid(i); return 1; @@ -3469,30 +3457,26 @@ int map_delmap(char* mapname) /// Initializes map flags and adjusts them depending on configuration. void map_flags_init(void) { - int i; - - for( i = 0; i < map_num; i++ ) + for( int i = 0; i < map.size(); i++ ) { - // mapflags - memset(&map[i].flag, 0, sizeof(map[i].flag)); + union u_mapflag_args args = {}; + + args.flag_val = 100; // additional mapflag data - map[i].zone = 0; // restricted mapflag zone - map[i].nocommand = 0; // nocommand mapflag level - map[i].adjust.bexp = 100; // per map base exp multiplicator - map[i].adjust.jexp = 100; // per map job exp multiplicator - memset(map[i].drop_list, 0, sizeof(map[i].drop_list)); // pvp nightmare drop list + map[i].zone = 0; // restricted mapflag zone + map_setmapflag(i, MF_NOCOMMAND, false); // nocommand mapflag level + map_setmapflag_sub(i, MF_BEXP, true, &args); // per map base exp multiplicator + map_setmapflag_sub(i, MF_JEXP, true, &args); // per map job exp multiplicator // skill damage #ifdef ADJUST_SKILL_DAMAGE - memset(&map[i].adjust.damage, 0, sizeof(map[i].adjust.damage)); - if (map[i].skill_damage.count) - map_skill_damage_free(&map[i]); + memset(&map[i].damage_adjust, 0, sizeof(map[i].damage_adjust)); #endif // adjustments if( battle_config.pk_mode ) - map[i].flag.pvp = 1; // make all maps pvp for pk_mode [Valaris] + map_setmapflag(i, MF_PVP, true); // make all maps pvp for pk_mode [Valaris] map_free_questinfo(i); } @@ -3633,14 +3617,14 @@ int map_readallmaps (void) } } - for(i = 0; i < map_num; i++) { + for(i = 0; i < map.size(); i++) { size_t size; bool success = false; unsigned short idx = 0; if( enable_grf ){ // show progress - ShowStatus("Loading maps [%i/%i]: %s" CL_CLL "\r", i, map_num, map[i].name); + ShowStatus("Loading maps [%i/%i]: %s" CL_CLL "\r", i, map.size(), map[i].name); // try to load the map success = map_readgat(&map[i]) != 0; @@ -3706,8 +3690,7 @@ int map_readallmaps (void) } // finished map loading - ShowInfo("Successfully loaded '" CL_WHITE "%d" CL_RESET "' maps." CL_CLL "\n",map_num); - instance_start = map_num; // Next Map Index will be instances + ShowInfo("Successfully loaded '" CL_WHITE "%d" CL_RESET "' maps." CL_CLL "\n",map.size()); if (maps_removed) ShowNotice("Maps removed: '" CL_WHITE "%d" CL_RESET "'\n",maps_removed); @@ -4297,64 +4280,395 @@ int cleanup_sub(struct block_list *bl, va_list ap) } #ifdef ADJUST_SKILL_DAMAGE -/** - * Free all skill damage entries for a map - * @param m Map data - **/ -void map_skill_damage_free(struct map_data *m) { - uint8 i; - - for (i = 0; i < m->skill_damage.count; i++) { - ers_free(map_skill_damage_ers, m->skill_damage.entries[i]); - m->skill_damage.entries[i] = NULL; - } - - aFree(m->skill_damage.entries); - m->skill_damage.entries = NULL; - m->skill_damage.count = 0; -} - /** * Add new skill damage adjustment entry for a map - * @param m Map data - * @param skill_id Skill - * @param pc Rate to PC - * @param mobs Rate to Monster - * @param boss Rate to Boss-monster - * @param other Rate to Other target - * @param caster Caster type - **/ -void map_skill_damage_add(struct map_data *m, uint16 skill_id, int pc, int mob, int boss, int other, uint8 caster) { - struct s_skill_damage *entry; - int i = 0; - - if (m->skill_damage.count >= UINT8_MAX) + * @param m: Map data + * @param skill_id: Skill ID + * @param pc: Rate to PC + * @param mobs: Rate to Monster + * @param boss: Rate to Boss-monster + * @param other: Rate to Other target + * @param caster: Caster type + */ +void map_skill_damage_add(struct map_data *m, uint16 skill_id, int rate[SKILLDMG_MAX], uint16 caster) { + if (m->skill_damage.size() > UINT16_MAX) return; - for (i = 0; i < m->skill_damage.count; i++) { - if (m->skill_damage.entries[i]->skill_id == skill_id) { - m->skill_damage.entries[i]->pc = pc; - m->skill_damage.entries[i]->mob = mob; - m->skill_damage.entries[i]->boss = boss; - m->skill_damage.entries[i]->other = other; - m->skill_damage.entries[i]->caster = caster; + for (int i = 0; i < m->skill_damage.size(); i++) { + if (m->skill_damage[i].skill_id == skill_id) { + for (int j = 0; j < SKILLDMG_MAX; j++) { + m->skill_damage[i].rate[j] = rate[j]; + } + m->skill_damage[i].caster = caster; return; } } - entry = ers_alloc(map_skill_damage_ers, struct s_skill_damage); - entry->skill_id = skill_id; - entry->pc = pc; - entry->mob = mob; - entry->boss = boss; - entry->other = other; - entry->caster = caster; + struct s_skill_damage entry = {}; - RECREATE(m->skill_damage.entries, struct s_skill_damage *, m->skill_damage.count+1); - m->skill_damage.entries[m->skill_damage.count++] = entry; + entry.skill_id = skill_id; + for (int i = 0; i < SKILLDMG_MAX; i++) + entry.rate[i] = rate[i]; + entry.caster = caster; + m->skill_damage.push_back(entry); } #endif +/** + * PvP timer handling + * @param bl: Player block object + * @param ap: func* with va_list values + * @return 0 + */ +static int map_mapflag_pvp_sub(struct block_list *bl, va_list ap) +{ + struct map_session_data *sd = map_id2sd(bl->id); + + nullpo_retr(0, sd); + + if (sd->pvp_timer == INVALID_TIMER) { + sd->pvp_timer = add_timer(gettick() + 200, pc_calc_pvprank_timer, sd->bl.id, 0); + sd->pvp_rank = 0; + sd->pvp_lastusers = 0; + sd->pvp_point = 5; + sd->pvp_won = 0; + sd->pvp_lost = 0; + } + + clif_map_property(&sd->bl, MAPPROPERTY_FREEPVPZONE, SELF); + return 0; +} + +/** + * Return the mapflag enum from the given name. + * @param name: Mapflag name + * @return Mapflag enum value + */ +enum e_mapflag map_getmapflag_by_name(char* name) +{ + char flag_constant[255]; + int mapflag; + + safesnprintf(flag_constant, sizeof(flag_constant), "mf_%s", name); + + if (!script_get_constant(flag_constant, &mapflag)) + return MF_INVALID; + else + return (enum e_mapflag)mapflag; +} + +/** + * Return the mapflag name from the given enum. + * @param mapflag: Mapflag enum + * @param output: Stores the mapflag name + * @return True on success otherwise false + */ +bool map_getmapflag_name( enum e_mapflag mapflag, char* output ){ + const char* constant; + const char* prefix = "mf_"; + int i, len = strlen(prefix); + + // Look it up + constant = script_get_constant_str( prefix, mapflag ); + + // Should never happen + if (constant == NULL) + return false; + + // Begin copy after the prefix + for(i = len; constant[i]; i++) + output[i-len] = (char)tolower(constant[i]); // Force lowercase + output[i - len] = 0; // Terminate it + + return true; +} + +/** + * Get a mapflag value + * @param m: Map ID + * @param mapflag: Mapflag ID + * @param args: Arguments for special flags + * @return Mapflag value on success or -1 on failure + */ +int map_getmapflag_sub(int16 m, enum e_mapflag mapflag, union u_mapflag_args *args) +{ + if (m < 0 || m >= map.size()) { + ShowWarning("map_getmapflag: Invalid map ID %d.\n", m); + return -1; + } + + if (mapflag < MF_MIN || mapflag >= MF_MAX) { + ShowWarning("map_getmapflag: Invalid mapflag %d on map %s.\n", mapflag, map[m].name); + return -1; + } + + switch(mapflag) { + case MF_NOLOOT: + return util::map_get(map[m].flag, MF_NOMOBLOOT, 0) && util::map_get(map[m].flag, MF_NOMVPLOOT, 0); + case MF_NOPENALTY: + return util::map_get(map[m].flag, MF_NOEXPPENALTY, 0) && util::map_get(map[m].flag, MF_NOZENYPENALTY, 0); + case MF_NOEXP: + return util::map_get(map[m].flag, MF_NOBASEEXP, 0) && util::map_get(map[m].flag, MF_NOJOBEXP, 0); + case MF_SKILL_DAMAGE: +#ifdef ADJUST_SKILL_DAMAGE + nullpo_retr(-1, args); + + switch (args->flag_val) { + case SKILLDMG_PC: + case SKILLDMG_MOB: + case SKILLDMG_BOSS: + case SKILLDMG_OTHER: + return map[m].damage_adjust.rate[args->flag_val]; + default: + return util::map_get(map[m].flag, mapflag, 0); + } +#else + return 0; +#endif + default: + return util::map_get(map[m].flag, mapflag, 0); + } +} + +/** + * Set a mapflag + * @param m: Map ID + * @param mapflag: Mapflag ID + * @param status: true - Set mapflag, false - Remove mapflag + * @param args: Arguments for special flags + * @return True on success or false on failure + */ +bool map_setmapflag_sub(int16 m, enum e_mapflag mapflag, bool status, union u_mapflag_args *args) +{ + if (m < 0 || m >= map.size()) { + ShowWarning("map_setmapflag: Invalid map ID %d.\n", m); + return false; + } + + if (mapflag < MF_MIN || mapflag >= MF_MAX) { + ShowWarning("map_setmapflag: Invalid mapflag %d on map %s.\n", mapflag, map[m].name); + return false; + } + + switch(mapflag) { + case MF_NOSAVE: + if (status) { + nullpo_retr(false, args); + + map[m].save.map = args->nosave.map; + map[m].save.x = args->nosave.x; + map[m].save.y = args->nosave.y; + } + map[m].flag[mapflag] = status; + break; + case MF_PVP: + if (!status) + clif_map_property_mapall(m, MAPPROPERTY_NOTHING); + else { + if (!battle_config.pk_mode) + map_foreachinmap(map_mapflag_pvp_sub, m, BL_PC); + if (map_getmapflag(m, MF_GVG)) { + map_setmapflag(m, MF_GVG, false); + ShowWarning("map_setmapflag: Unable to set GvG and PvP flags for the same map! Removing GvG flag from %s.\n", map[m].name); + } + if (map_getmapflag(m, MF_GVG_TE)) { + map_setmapflag(m, MF_GVG_TE, false); + ShowWarning("map_setmapflag: Unable to set GvG TE and PvP flags for the same map! Removing GvG TE flag from %s.\n", map[m].name); + } + if (map_getmapflag(m, MF_GVG_DUNGEON)) { + map_setmapflag(m, MF_GVG_DUNGEON, false); + ShowWarning("map_setmapflag: Unable to set GvG Dungeon and PvP flags for the same map! Removing GvG Dungeon flag from %s.\n", map[m].name); + } + if (map_getmapflag(m, MF_GVG_CASTLE)) { + map_setmapflag(m, MF_GVG_CASTLE, false); + ShowWarning("map_setmapflag: Unable to set GvG Castle and PvP flags for the same map! Removing GvG Castle flag from %s.\n", map[m].name); + } + if (map_getmapflag(m, MF_GVG_TE_CASTLE)) { + map_setmapflag(m, MF_GVG_TE_CASTLE, false); + ShowWarning("map_setmapflag: Unable to set GvG TE Castle and PvP flags for the same map! Removing GvG TE Castle flag from %s.\n", map[m].name); + } + if (map_getmapflag(m, MF_BATTLEGROUND)) { + map_setmapflag(m, MF_BATTLEGROUND, false); + ShowWarning("map_setmapflag: Unable to set Battleground and PvP flags for the same map! Removing Battleground flag from %s.\n", map[m].name); + } + } + map[m].flag[mapflag] = status; + break; + case MF_GVG: + case MF_GVG_TE: + if (!status) + clif_map_property_mapall(m, MAPPROPERTY_NOTHING); + else { + clif_map_property_mapall(m, MAPPROPERTY_AGITZONE); + if (map_getmapflag(m, MF_PVP)) { + map_setmapflag(m, MF_PVP, false); + ShowWarning("map_setmapflag: Unable to set PvP and GvG flags for the same map! Removing PvP flag from %s.\n", map[m].name); + } + if (map_getmapflag(m, MF_BATTLEGROUND)) { + map_setmapflag(m, MF_BATTLEGROUND, false); + ShowWarning("map_setmapflag: Unable to set Battleground and GvG flags for the same map! Removing Battleground flag from %s.\n", map[m].name); + } + } + map[m].flag[mapflag] = status; + break; + case MF_GVG_CASTLE: + case MF_GVG_TE_CASTLE: + if (status) { + if (mapflag == MF_GVG_CASTLE && map_getmapflag(m, MF_GVG_TE_CASTLE)) { + map_setmapflag(m, MF_GVG_TE_CASTLE, false); + ShowWarning("map_setmapflag: Unable to set GvG TE Castle and GvG Castle flags for the same map! Removing GvG TE Castle flag from %s.\n", map[m].name); + } + if (mapflag == MF_GVG_TE_CASTLE && map_getmapflag(m, MF_GVG_CASTLE)) { + map_setmapflag(m, MF_GVG_CASTLE, false); + ShowWarning("map_setmapflag: Unable to set GvG Castle and GvG TE Castle flags for the same map! Removing GvG Castle flag from %s.\n", map[m].name); + } + if (map_getmapflag(m, MF_PVP)) { + map_setmapflag(m, MF_PVP, false); + ShowWarning("npc_parse_mapflag: Unable to set PvP and GvG%s Castle flags for the same map! Removing PvP flag from %s.\n", (mapflag == MF_GVG_CASTLE ? NULL : " TE"), map[m].name); + } + } + map[m].flag[mapflag] = status; + break; + case MF_GVG_DUNGEON: + if (status && map_getmapflag(m, MF_PVP)) { + map_setmapflag(m, MF_PVP, false); + ShowWarning("map_setmapflag: Unable to set PvP and GvG Dungeon flags for the same map! Removing PvP flag from %s.\n", map[m].name); + } + map[m].flag[mapflag] = status; + break; + case MF_NOBASEEXP: + case MF_NOJOBEXP: + if (status) { + if (mapflag == MF_NOBASEEXP && map_getmapflag(m, MF_BEXP) != 100) { + map_setmapflag(m, MF_BEXP, false); + ShowWarning("map_setmapflag: Unable to set BEXP and No Base EXP flags for the same map! Removing BEXP flag from %s.\n", map[m].name); + } + if (mapflag == MF_NOJOBEXP && map_getmapflag(m, MF_JEXP) != 100) { + map_setmapflag(m, MF_JEXP, false); + ShowWarning("map_setmapflag: Unable to set JEXP and No Job EXP flags for the same map! Removing JEXP flag from %s.\n", map[m].name); + } + } + map[m].flag[mapflag] = status; + break; + case MF_PVP_NIGHTMAREDROP: + if (status) { + nullpo_retr(false, args); + + if (map[m].drop_list.size() == MAX_DROP_PER_MAP) { + ShowWarning("map_setmapflag: Reached the maximum number of drop list items for mapflag pvp_nightmaredrop on %s. Skipping.\n", map[m].name); + break; + } + + struct s_drop_list entry; + + entry.drop_id = args->nightmaredrop.drop_id; + entry.drop_type = args->nightmaredrop.drop_type; + entry.drop_per = args->nightmaredrop.drop_per; + map[m].drop_list.push_back(entry); + } + map[m].flag[mapflag] = status; + break; + case MF_RESTRICTED: + nullpo_retr(false, args); + + map[m].flag[mapflag] = status; + if (!status) + map[m].zone ^= 1 << (args->flag_val + 1); + else + map[m].zone |= 1 << (args->flag_val + 1); + break; + case MF_NOCOMMAND: + if (status) { + nullpo_retr(false, args); + + map[m].flag[mapflag] = ((args->flag_val <= 0) ? 100 : args->flag_val); + } else + map[m].flag[mapflag] = false; + break; + case MF_JEXP: + case MF_BEXP: + if (status) { + nullpo_retr(false, args); + + if (mapflag == MF_JEXP && map_getmapflag(m, MF_NOJOBEXP)) { + map_setmapflag(m, MF_NOJOBEXP, false); + ShowWarning("map_setmapflag: Unable to set No Job EXP and JEXP flags for the same map! Removing No Job EXP flag from %s.\n", map[m].name); + } + if (mapflag == MF_BEXP && map_getmapflag(m, MF_NOBASEEXP)) { + map_setmapflag(m, MF_NOBASEEXP, false); + ShowWarning("map_setmapflag: Unable to set No Base EXP and BEXP flags for the same map! Removing No Base EXP flag from %s.\n", map[m].name); + } + map[m].flag[mapflag] = args->flag_val; + } else + map[m].flag[mapflag] = false; + break; + case MF_BATTLEGROUND: + if (status) { + nullpo_retr(false, args); + + if (map_getmapflag(m, MF_PVP)) { + map_setmapflag(m, MF_PVP, false); + ShowWarning("map_setmapflag: Unable to set PvP and Battleground flags for the same map! Removing PvP flag from %s.\n", map[m].name); + } + if (map_getmapflag(m, MF_GVG)) { + map_setmapflag(m, MF_GVG, false); + ShowWarning("map_setmapflag: Unable to set GvG and Battleground flags for the same map! Removing GvG flag from %s.\n", map[m].name); + } + if (map_getmapflag(m, MF_GVG_DUNGEON)) { + map_setmapflag(m, MF_GVG_DUNGEON, false); + ShowWarning("map_setmapflag: Unable to set GvG Dungeon and Battleground flags for the same map! Removing GvG Dungeon flag from %s.\n", map[m].name); + } + if (map_getmapflag(m, MF_GVG_CASTLE)) { + map_setmapflag(m, MF_GVG_CASTLE, false); + ShowWarning("map_setmapflag: Unable to set GvG Castle and Battleground flags for the same map! Removing GvG Castle flag from %s.\n", map[m].name); + } + map[m].flag[mapflag] = ((args->flag_val <= 0 || args->flag_val > 2) ? 1 : args->flag_val); + } else + map[m].flag[mapflag] = false; + break; + case MF_NOLOOT: + map[m].flag[MF_NOMOBLOOT] = status; + map[m].flag[MF_NOMVPLOOT] = status; + break; + case MF_NOPENALTY: + map[m].flag[MF_NOEXPPENALTY] = status; + map[m].flag[MF_NOZENYPENALTY] = status; + break; + case MF_NOEXP: + map[m].flag[MF_NOBASEEXP] = status; + map[m].flag[MF_NOJOBEXP] = status; + break; +#ifdef ADJUST_SKILL_DAMAGE + case MF_SKILL_DAMAGE: + if (!status) { + memset(&map[m].damage_adjust, 0, sizeof(map[m].damage_adjust)); + map[m].skill_damage.clear(); + } else { + nullpo_retr(false, args); + + if (!args->skill_damage.caster) { + ShowError("map_setmapflag: Skill damage adjustment without casting type for map %s.\n", map[m].name); + return false; + } + + for (int i = 0; i < SKILLDMG_MAX; i++) { + map[m].damage_adjust.rate[i] = cap_value(args->skill_damage.rate[i], -100, 100000); + + if (map[m].flag.find(mapflag) != map[m].flag.end() && map[m].damage_adjust.rate[i]) + map[m].damage_adjust.caster = args->skill_damage.caster; + } + } + map[m].flag[mapflag] = status; + break; +#endif + default: + map[m].flag[mapflag] = status; + break; + } + + return true; +} + /** * @see DBApply */ @@ -4385,14 +4699,14 @@ void do_final(void) do_clear_npc(); // remove all objects on maps - for (i = 0; i < map_num; i++) { - ShowStatus("Cleaning up maps [%d/%d]: %s..." CL_CLL "\r", i+1, map_num, map[i].name); + for (i = 0; i < map.size(); i++) { + ShowStatus("Cleaning up maps [%d/%d]: %s..." CL_CLL "\r", i+1, map.size(), map[i].name); if (map[i].m >= 0) { map_foreachinmap(cleanup_sub, i, BL_ALL); channel_delete(map[i].channel,false); } } - ShowStatus("Cleaned up %d maps." CL_CLL "\n", map_num); + ShowStatus("Cleaned up %d maps." CL_CLL "\n", map.size()); id_db->foreach(id_db,cleanup_db_sub); chrif_char_reset_offline(); @@ -4432,7 +4746,7 @@ void do_final(void) map_db->destroy(map_db, map_db_final); - for (i=0; idestroy(iwall_db, NULL); regen_db->destroy(regen_db, NULL); -#ifdef ADJUST_SKILL_DAMAGE - ers_destroy(map_skill_damage_ers); -#endif - map_sql_close(); ShowStatus("Finished.\n"); @@ -4717,10 +5028,6 @@ 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 -#ifdef ADJUST_SKILL_DAMAGE - map_skill_damage_ers = ers_new(sizeof(struct s_skill_damage), "map.cpp:map_skill_damage_ers", ERS_OPT_NONE); -#endif - map_sql_init(); if (log_config.sql_logs) log_sql_init(); diff --git a/src/map/map.hpp b/src/map/map.hpp index 444b265da5..8fee021f09 100644 --- a/src/map/map.hpp +++ b/src/map/map.hpp @@ -4,7 +4,10 @@ #ifndef _MAP_HPP_ #define _MAP_HPP_ +#include +#include #include +#include #include "../common/cbasetypes.hpp" #include "../common/core.hpp" // CORE_ST_LAST @@ -228,20 +231,20 @@ enum e_mapid { #define DEFAULT_AUTOSAVE_INTERVAL 5*60*1000 /// Specifies maps where players may hit each other -#define map_flag_vs(m) (map[m].flag.pvp || map[m].flag.gvg_dungeon || map[m].flag.gvg || ((agit_flag || agit2_flag) && map[m].flag.gvg_castle) || map[m].flag.gvg_te || (agit3_flag && map[m].flag.gvg_te_castle) || map[m].flag.battleground) +#define map_flag_vs(m) (map_getmapflag(m, MF_PVP) || map_getmapflag(m, MF_GVG_DUNGEON) ||map_getmapflag(m, MF_GVG) || ((agit_flag || agit2_flag) && map_getmapflag(m, MF_GVG_CASTLE)) || map_getmapflag(m, MF_GVG_TE) || (agit3_flag && map_getmapflag(m, MF_GVG_TE_CASTLE)) || map_getmapflag(m, MF_BATTLEGROUND)) /// Versus map: PVP, BG, GVG, GVG Dungeons, and GVG Castles (regardless of agit_flag status) -#define map_flag_vs2(m) (map[m].flag.pvp || map[m].flag.gvg_dungeon || map[m].flag.gvg || map[m].flag.gvg_castle || map[m].flag.gvg_te || map[m].flag.gvg_te_castle || map[m].flag.battleground) +#define map_flag_vs2(m) (map_getmapflag(m, MF_PVP) || map_getmapflag(m, MF_GVG_DUNGEON) || map_getmapflag(m, MF_GVG) || map_getmapflag(m, MF_GVG_CASTLE) || map_getmapflag(m, MF_GVG_TE) || map_getmapflag(m, MF_GVG_TE_CASTLE) || map_getmapflag(m, MF_BATTLEGROUND)) /// Specifies maps that have special GvG/WoE restrictions -#define map_flag_gvg(m) (map[m].flag.gvg || ((agit_flag || agit2_flag) && map[m].flag.gvg_castle) || map[m].flag.gvg_te || (agit3_flag && map[m].flag.gvg_te_castle)) +#define map_flag_gvg(m) (map_getmapflag(m, MF_GVG) || ((agit_flag || agit2_flag) && map_getmapflag(m, MF_GVG_CASTLE)) || map_getmapflag(m, MF_GVG_TE) || (agit3_flag && map_getmapflag(m, MF_GVG_TE_CASTLE))) /// Specifies if the map is tagged as GvG/WoE (regardless of agit_flag status) -#define map_flag_gvg2(m) (map[m].flag.gvg || map[m].flag.gvg_te || map[m].flag.gvg_castle || map[m].flag.gvg_te_castle) +#define map_flag_gvg2(m) (map_getmapflag(m, MF_GVG) || map_getmapflag(m, MF_GVG_TE) || map_getmapflag(m, MF_GVG_CASTLE) || map_getmapflag(m, MF_GVG_TE_CASTLE)) /// No Kill Steal Protection -#define map_flag_ks(m) (map[m].flag.town || map[m].flag.pvp || map[m].flag.gvg || map[m].flag.gvg_te || map[m].flag.battleground) +#define map_flag_ks(m) (map_getmapflag(m, MF_TOWN) || map_getmapflag(m, MF_PVP) || map_getmapflag(m, MF_GVG) || map_getmapflag(m, MF_GVG_TE) || map_getmapflag(m, MF_BATTLEGROUND)) /// WOE:TE Maps (regardless of agit_flag status) [Cydh] -#define map_flag_gvg2_te(m) (map[m].flag.gvg_te || map[m].flag.gvg_te_castle) +#define map_flag_gvg2_te(m) (map_getmapflag(m, MF_GVG_TE) || map_getmapflag(m, MF_GVG_TE_CASTLE)) /// Check if map is GVG maps exclusion for item, skill, and status restriction check (regardless of agit_flag status) [Cydh] -#define map_flag_gvg2_no_te(m) (map[m].flag.gvg || map[m].flag.gvg_castle) +#define map_flag_gvg2_no_te(m) (map_getmapflag(m, MF_GVG) || map_getmapflag(m, MF_GVG_CASTLE)) //This stackable implementation does not means a BL can be more than one type at a time, but it's //meant to make it easier to check for multiple types at a time on invocations such as map_foreach* calls [Skotlex] @@ -513,6 +516,122 @@ enum _look { LOOK_BODY2 }; +enum e_mapflag : int16 { + MF_INVALID = -1, + MF_MIN = 0, + MF_NOMEMO = 0, + MF_NOTELEPORT, + MF_NOSAVE, + MF_NOBRANCH, + MF_NOPENALTY, + MF_NOZENYPENALTY, + MF_PVP, + MF_PVP_NOPARTY, + MF_PVP_NOGUILD, + MF_GVG, + MF_GVG_NOPARTY, //10 + MF_NOTRADE, + MF_NOSKILL, + MF_NOWARP, + MF_PARTYLOCK, + MF_NOICEWALL, + MF_SNOW, + MF_FOG, + MF_SAKURA, + MF_LEAVES, + //MF_RAIN, //20 - No longer available, keeping here just in case it's back someday. [Ind] + // 21 free + MF_NOGO = 22, + MF_CLOUDS, + MF_CLOUDS2, + MF_FIREWORKS, + MF_GVG_CASTLE, + MF_GVG_DUNGEON, + MF_NIGHTENABLED, + MF_NOBASEEXP, + MF_NOJOBEXP, //30 + MF_NOMOBLOOT, + MF_NOMVPLOOT, + MF_NORETURN, + MF_NOWARPTO, + MF_PVP_NIGHTMAREDROP, + MF_RESTRICTED, + MF_NOCOMMAND, + MF_NODROP, + MF_JEXP, + MF_BEXP, //40 + MF_NOVENDING, + MF_LOADEVENT, + MF_NOCHAT, + MF_NOEXPPENALTY, + MF_GUILDLOCK, + MF_TOWN, + MF_AUTOTRADE, + MF_ALLOWKS, + MF_MONSTER_NOTELEPORT, + MF_PVP_NOCALCRANK, //50 + MF_BATTLEGROUND, + MF_RESET, + MF_NOMAPCHANNELAUTOJOIN, + MF_NOUSECART, + MF_NOITEMCONSUMPTION, + MF_NOSUNMOONSTARMIRACLE, + MF_NOMINEEFFECT, + MF_NOLOCKON, + MF_NOTOMB, + MF_SKILL_DAMAGE, //60 + MF_NOCOSTUME, + MF_GVG_TE_CASTLE, + MF_GVG_TE, + MF_HIDEMOBHPBAR, + MF_NOLOOT, + MF_NOEXP, + MF_MAX +}; + +/// Enum of damage types +enum e_skill_damage_type : uint8 { + SKILLDMG_PC, + SKILLDMG_MOB, + SKILLDMG_BOSS, + SKILLDMG_OTHER, + SKILLDMG_MAX +}; + +#ifdef ADJUST_SKILL_DAMAGE +/// Struct for MF_SKILLDAMAGE +struct s_skill_damage { + unsigned int map; ///< Maps (used for skill_damage_db.txt) + uint16 skill_id; ///< Skill ID (used for mapflag) + uint16 caster; ///< Caster type + int rate[SKILLDMG_MAX]; ///< Used for when all skills are adjusted +}; +#endif + +/// Enum for item drop type for MF_PVP_NIGHTMAREDROP +enum e_nightmare_drop_type : uint8 { + NMDT_INVENTORY = 0x1, + NMDT_EQUIP = 0x2, + NMDT_ALL = (NMDT_INVENTORY|NMDT_EQUIP) +}; + +/// Struct for MF_PVP_NIGHTMAREDROP +struct s_drop_list { + int drop_id; + int drop_per; + enum e_nightmare_drop_type drop_type; +}; + +/// Union for mapflag values +union u_mapflag_args { + struct point nosave; + struct s_drop_list nightmaredrop; +#ifdef ADJUST_SKILL_DAMAGE + struct s_skill_damage skill_damage; +#endif + int flag_val; +}; + // used by map_setcell() enum cell_t{ CELL_WALKABLE, @@ -583,21 +702,6 @@ struct iwall_data { bool shootable; }; -#ifdef ADJUST_SKILL_DAMAGE -/// Struct of skill damage adjustment -struct s_skill_damage { - unsigned int map; ///< Maps (used for skill_damage_db.txt) - uint16 skill_id; ///< Skill ID (used for mapflag) - // Additional rates - int pc, ///< Rate to Player - mob, ///< Rate to Monster - boss, ///< Rate to Boss-Monster - other; ///< Rate to Other target - uint8 caster; ///< Caster type -}; -extern struct eri *map_skill_damage_ers; -#endif - struct questinfo_req { unsigned int quest_id; unsigned state : 2; // 0: Doesn't have, 1: Inactive, 2: Active, 3: Complete //! TODO: CONFIRM ME!! @@ -630,94 +734,20 @@ struct map_data { int users; int users_pvp; int iwall_num; // Total of invisible walls in this map - struct map_flag { - unsigned town : 1; // [Suggestion to protect Mail System] - unsigned autotrade : 1; - unsigned allowks : 1; // [Kill Steal Protection] - unsigned nomemo : 1; - unsigned noteleport : 1; - unsigned noreturn : 1; - unsigned monster_noteleport : 1; - unsigned nosave : 1; - unsigned nobranch : 1; - unsigned noexppenalty : 1; - unsigned pvp : 1; - unsigned pvp_noparty : 1; - unsigned pvp_noguild : 1; - unsigned pvp_nightmaredrop :1; - unsigned pvp_nocalcrank : 1; - unsigned gvg_castle : 1; - unsigned gvg : 1; // Now it identifies gvg versus maps that are active 24/7 - unsigned gvg_dungeon : 1; // Celest - unsigned gvg_noparty : 1; - unsigned battleground : 2; // [BattleGround System] - unsigned nozenypenalty : 1; - unsigned notrade : 1; - unsigned noskill : 1; - unsigned nowarp : 1; - unsigned nowarpto : 1; - unsigned noicewall : 1; // [Valaris] - unsigned snow : 1; // [Valaris] - unsigned clouds : 1; - unsigned clouds2 : 1; // [Valaris] - unsigned fog : 1; // [Valaris] - unsigned fireworks : 1; - unsigned sakura : 1; // [Valaris] - unsigned leaves : 1; // [Valaris] - unsigned nogo : 1; // [Valaris] - unsigned nobaseexp : 1; // [Lorky] added by Lupus - unsigned nojobexp : 1; // [Lorky] - 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; - unsigned nochat :1; - unsigned partylock :1; - unsigned guildlock :1; - unsigned reset :1; // [Daegaladh] - unsigned chmautojoin : 1; //prevent to auto join map channel - unsigned nousecart : 1; //prevent open up cart @FIXME client side only atm - unsigned noitemconsumption : 1; //prevent item usage - unsigned nosumstarmiracle : 1; //allow SG miracle to happen ? - unsigned nomineeffect : 1; //allow /mineeffect - unsigned nolockon : 1; - unsigned notomb : 1; - unsigned nocostume : 1; // Disable costume sprites [Cydh] - unsigned gvg_te : 1; // GVG WOE:TE. This was added as purpose to change 'gvg' for GVG TE, so item_noequp, skill_nocast exlude GVG TE maps from 'gvg' (flag &4) - unsigned gvg_te_castle : 1; // GVG WOE:TE Castle - unsigned hidemobhpbar : 1; -#ifdef ADJUST_SKILL_DAMAGE - unsigned skill_damage : 1; -#endif - } flag; - struct point save; - struct npc_data *npc[MAX_NPC_PER_MAP]; - struct { - int drop_id; - int drop_type; - int drop_per; - } drop_list[MAX_DROP_PER_MAP]; + std::map flag; + struct point save; + std::vector drop_list; + uint32 zone; // zone number (for item/skill restrictions) +#ifdef ADJUST_SKILL_DAMAGE + struct s_skill_damage damage_adjust; // Used for overall skill damage adjustment + std::vector skill_damage; // Used for single skill damage adjustment +#endif + + struct npc_data *npc[MAX_NPC_PER_MAP]; struct spawn_data *moblist[MAX_MOB_LIST_PER_MAP]; // [Wizputer] int mob_delete_timer; // Timer ID for map_removemobs_timer [Skotlex] - uint32 zone; // zone number (for item/skill restrictions) - int nocommand; //Blocks @/# commands for non-gms. [Skotlex] - struct { - int jexp; // map experience multiplicator - int bexp; // map experience multiplicator -#ifdef ADJUST_SKILL_DAMAGE - struct s_skill_damage damage; -#endif - } adjust; -#ifdef ADJUST_SKILL_DAMAGE - struct { - struct s_skill_damage **entries; - uint8 count; - } skill_damage; -#endif + // Instance Variables unsigned short instance_id; int instance_src_map; @@ -748,8 +778,7 @@ int map_getcellp(struct map_data* m,int16 x,int16 y,cell_chk cellchk); void map_setcell(int16 m, int16 x, int16 y, cell_t cell, bool flag); void map_setgatcell(int16 m, int16 x, int16 y, int gat); -extern struct map_data map[]; -extern int map_num; +extern std::vector map; extern int autosave_interval; extern int minsave_interval; @@ -926,10 +955,16 @@ void map_addmap2db(struct map_data *m); void map_removemapdb(struct map_data *m); #ifdef ADJUST_SKILL_DAMAGE -void map_skill_damage_free(struct map_data *m); -void map_skill_damage_add(struct map_data *m, uint16 skill_id, int pc, int mob, int boss, int other, uint8 caster); +void map_skill_damage_add(struct map_data *m, uint16 skill_id, int rate[SKILLDMG_MAX], uint16 caster); #endif +enum e_mapflag map_getmapflag_by_name(char* name); +bool map_getmapflag_name(enum e_mapflag mapflag, char* output); +int map_getmapflag_sub(int16 m, enum e_mapflag mapflag, union u_mapflag_args *args); +bool map_setmapflag_sub(int16 m, enum e_mapflag mapflag, bool status, union u_mapflag_args *args); +#define map_getmapflag(m, mapflag) map_getmapflag_sub(m, mapflag, NULL) +#define map_setmapflag(m, mapflag, status) map_setmapflag_sub(m, mapflag, status, NULL) + #define CHK_ELEMENT(ele) ((ele) > ELE_NONE && (ele) < ELE_MAX) /// Check valid Element #define CHK_ELEMENT_LEVEL(lv) ((lv) >= 1 && (lv) <= MAX_ELE_LEVEL) /// Check valid element level #define CHK_RACE(race) ((race) > RC_NONE_ && (race) < RC_MAX) /// Check valid Race diff --git a/src/map/mob.cpp b/src/map/mob.cpp index 8d14597d10..429edd8a3c 100644 --- a/src/map/mob.cpp +++ b/src/map/mob.cpp @@ -568,7 +568,7 @@ bool mob_ksprotected (struct block_list *src, struct block_list *target) struct map_session_data *pl_sd; // Owner char output[128]; - if( map[md->bl.m].flag.allowks || map_flag_ks(md->bl.m) ) + if( map_getmapflag(md->bl.m, MF_ALLOWKS) || map_flag_ks(md->bl.m) ) return false; // Ignores GVG, PVP and AllowKS map flags if( md->db->mexp || md->master_id ) @@ -2402,7 +2402,7 @@ void mob_damage(struct mob_data *md, struct block_list *src, int damage) clif_name_area(&md->bl); #if PACKETVER >= 20120404 - if (battle_config.monster_hp_bars_info && !map[md->bl.m].flag.hidemobhpbar) { + if (battle_config.monster_hp_bars_info && !map_getmapflag(md->bl.m, MF_HIDEMOBHPBAR)) { int i; for(i = 0; i < DAMAGELOG_SIZE; i++){ // must show hp bar to all char who already hit the mob. struct map_session_data *sd = map_charid2sd(md->dmglog[i].id); @@ -2518,9 +2518,9 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) } if(!(type&2) && //No exp - (!map[m].flag.pvp || battle_config.pvp_exp) && //Pvp no exp rule [MouseJstr] + (!map_getmapflag(m, MF_PVP) || battle_config.pvp_exp) && //Pvp no exp rule [MouseJstr] (!md->master_id || !md->special_state.ai) && //Only player-summoned mobs do not give exp. [Skotlex] - (!map[m].flag.nobaseexp || !map[m].flag.nojobexp) //Gives Exp + (!map_getmapflag(m, MF_NOBASEEXP) || !map_getmapflag(m, MF_NOJOBEXP)) //Gives Exp ) { //Experience calculation. int bonus = 100; //Bonus on top of your share (common to all attackers). int pnum = 0; @@ -2583,21 +2583,21 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) zeny*=rnd()%250; } - if (map[m].flag.nobaseexp || !md->db->base_exp) + if (map_getmapflag(m, MF_NOBASEEXP) || !md->db->base_exp) base_exp = 0; else { double exp = apply_rate2(md->db->base_exp, per, 1); exp = apply_rate(exp, bonus); - exp = apply_rate(exp, map[m].adjust.bexp); + exp = apply_rate(exp, map_getmapflag(m, MF_BEXP)); base_exp = (unsigned int)cap_value(exp, 1, UINT_MAX); } - if (map[m].flag.nojobexp || !md->db->job_exp || md->dmglog[i].flag == MDLF_HOMUN) //Homun earned job-exp is always lost. + if (map_getmapflag(m, MF_NOJOBEXP) || !md->db->job_exp || md->dmglog[i].flag == MDLF_HOMUN) //Homun earned job-exp is always lost. job_exp = 0; else { double exp = apply_rate2(md->db->job_exp, per, 1); exp = apply_rate(exp, bonus); - exp = apply_rate(exp, map[m].adjust.jexp); + exp = apply_rate(exp, map_getmapflag(m, MF_JEXP)); job_exp = (unsigned int)cap_value(exp, 1, UINT_MAX); } @@ -2660,7 +2660,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) } //End EXP giving. - if( !(type&1) && !map[m].flag.nomobloot && !md->state.rebirth && ( + if( !(type&1) && !map_getmapflag(m, MF_NOMOBLOOT) && !md->state.rebirth && ( !md->special_state.ai || //Non special mob battle_config.alchemist_summon_reward == 2 || //All summoned give drops (md->special_state.ai==AI_SPHERE && battle_config.alchemist_summon_reward == 1) //Marine Sphere Drops items. @@ -2849,7 +2849,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) double exp; //mapflag: noexp check [Lorky] - if (map[m].flag.nobaseexp || type&2) + if (map_getmapflag(m, MF_NOBASEEXP) || type&2) exp =1; else { exp = md->db->mexp; @@ -2864,7 +2864,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) pc_gainexp(mvp_sd, &md->bl, mexp,0, 0); log_mvp[1] = mexp; - if( !(map[m].flag.nomvploot || type&1) ) { + if( !(map_getmapflag(m, MF_NOMVPLOOT) || type&1) ) { //Order might be random depending on item_drop_mvp_mode config setting struct s_mob_drop mdrop[MAX_MVP_DROP_TOTAL]; @@ -3039,7 +3039,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type) } // MvP tomb [GreenBox] - if (battle_config.mvp_tomb_enabled && md->spawn->state.boss && map[md->bl.m].flag.notomb != 1) + if (battle_config.mvp_tomb_enabled && md->spawn->state.boss && map_getmapflag(md->bl.m, MF_NOTOMB) != 1) mvptomb_create(md, mvp_sd ? mvp_sd->status.name : NULL, time(NULL)); if( !rebirth ) @@ -3271,7 +3271,7 @@ void mob_heal(struct mob_data *md,unsigned int heal) if (battle_config.show_mob_info&3) clif_name_area(&md->bl); #if PACKETVER >= 20120404 - if (battle_config.monster_hp_bars_info && !map[md->bl.m].flag.hidemobhpbar) { + if (battle_config.monster_hp_bars_info && !map_getmapflag(md->bl.m, MF_HIDEMOBHPBAR)) { int i; for(i = 0; i < DAMAGELOG_SIZE; i++)// must show hp bar to all char who already hit the mob. if( md->dmglog[i].id ) { diff --git a/src/map/npc.cpp b/src/map/npc.cpp index 23f7017331..f32a814c3d 100644 --- a/src/map/npc.cpp +++ b/src/map/npc.cpp @@ -3934,327 +3934,176 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con { int16 m; char mapname[MAP_NAME_LENGTH_EXT]; - int state = 1; + bool state = true; + enum e_mapflag mapflag; // w1= - if( sscanf(w1, "%15[^,]", mapname) != 1 ) - { + if (sscanf(w1, "%15[^,]", mapname) != 1) { ShowError("npc_parse_mapflag: Invalid mapflag definition in file '%s', line '%d'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", filepath, strline(buffer,start-buffer), w1, w2, w3, w4); return strchr(start,'\n');// skip and continue } m = map_mapname2mapid(mapname); - if( m < 0 ) - { + if (m < 0) { ShowWarning("npc_parse_mapflag: Unknown map in file '%s', line '%d' : %s\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", mapname, filepath, strline(buffer,start-buffer), w1, w2, w3, w4); return strchr(start,'\n');// skip and continue } if (w4 && !strcmpi(w4, "off")) - state = 0; //Disable mapflag rather than enable it. [Skotlex] + state = false; //Disable mapflag rather than enable it. [Skotlex] - if (!strcmpi(w3, "nosave")) { - char savemap[MAP_NAME_LENGTH_EXT]; - short savex, savey; - if (state == 0) - ; //Map flag disabled. - else if (!strcmpi(w4, "SavePoint")) { - map[m].save.map = 0; - map[m].save.x = -1; - map[m].save.y = -1; - } else if (sscanf(w4, "%15[^,],%6hd,%6hd", savemap, &savex, &savey) == 3) { - map[m].save.map = mapindex_name2id(savemap); - map[m].save.x = savex; - map[m].save.y = savey; - if (!map[m].save.map) { - ShowWarning("npc_parse_mapflag: Specified save point map '%s' for mapflag 'nosave' not found (file '%s', line '%d'), using 'SavePoint'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", savemap, filepath, strline(buffer,start-buffer), w1, w2, w3, w4); - map[m].save.x = -1; - map[m].save.y = -1; + mapflag = map_getmapflag_by_name(w3); + + switch( mapflag ){ + case MF_INVALID: + ShowError("npc_parse_mapflag: unrecognized mapflag '%s' (file '%s', line '%d').\n", w3, filepath, strline(buffer,start-buffer)); + break; + case MF_NOSAVE: { + char savemap[MAP_NAME_LENGTH_EXT]; + union u_mapflag_args args = {}; + + if (state && !strcmpi(w4, "SavePoint")) { + args.nosave.map = 0; + args.nosave.x = -1; + args.nosave.y = -1; + } else if (state && sscanf(w4, "%15[^,],%6hd,%6hd", savemap, &args.nosave.x, &args.nosave.y) == 3) { + args.nosave.map = mapindex_name2id(savemap); + if (!args.nosave.map) { + ShowWarning("npc_parse_mapflag: Specified save point map '%s' for mapflag 'nosave' not found (file '%s', line '%d'), using 'SavePoint'.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", savemap, filepath, strline(buffer,start-buffer), w1, w2, w3, w4); + args.nosave.x = -1; + args.nosave.y = -1; + } } + map_setmapflag_sub(m, MF_NOSAVE, state, &args); + break; } - map[m].flag.nosave = state; - } - else if (!strcmpi(w3,"autotrade")) - map[m].flag.autotrade=state; - else if (!strcmpi(w3,"allowks")) - map[m].flag.allowks=state; // [Kill Steal Protection] - else if (!strcmpi(w3,"town")) - map[m].flag.town=state; - else if (!strcmpi(w3,"nomemo")) - map[m].flag.nomemo=state; - else if (!strcmpi(w3,"noteleport")) - map[m].flag.noteleport=state; - else if (!strcmpi(w3,"nowarp")) - map[m].flag.nowarp=state; - else if (!strcmpi(w3,"nowarpto")) - map[m].flag.nowarpto=state; - else if (!strcmpi(w3,"noreturn")) - map[m].flag.noreturn=state; - else if (!strcmpi(w3,"monster_noteleport")) - map[m].flag.monster_noteleport=state; - else if (!strcmpi(w3,"nobranch")) - map[m].flag.nobranch=state; - else if (!strcmpi(w3,"nopenalty")) { - map[m].flag.noexppenalty=state; - map[m].flag.nozenypenalty=state; - } - else if (!strcmpi(w3,"pvp")) { - map[m].flag.pvp = state; - 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 ) { - 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)); - } - } - else if (!strcmpi(w3,"pvp_noparty")) - map[m].flag.pvp_noparty=state; - else if (!strcmpi(w3,"pvp_noguild")) - map[m].flag.pvp_noguild=state; - else if (!strcmpi(w3, "pvp_nightmaredrop")) { - char drop_arg1[16], drop_arg2[16]; - int drop_per = 0; - if (sscanf(w4, "%15[^,],%15[^,],%11d", drop_arg1, drop_arg2, &drop_per) == 3) { - int drop_id = 0, drop_type = 0; - if (!strcmpi(drop_arg1, "random")) - drop_id = -1; - else if (itemdb_exists((drop_id = atoi(drop_arg1))) == NULL) - drop_id = 0; - if (!strcmpi(drop_arg2, "inventory")) - drop_type = 1; - else if (!strcmpi(drop_arg2,"equip")) - drop_type = 2; - else if (!strcmpi(drop_arg2,"all")) - drop_type = 3; - if (drop_id != 0){ - int i; - for (i = 0; i < MAX_DROP_PER_MAP; i++) { - if (map[m].drop_list[i].drop_id == 0){ - map[m].drop_list[i].drop_id = drop_id; - map[m].drop_list[i].drop_type = drop_type; - map[m].drop_list[i].drop_per = drop_per; - break; + case MF_PVP_NIGHTMAREDROP: { + char drop_arg1[16], drop_arg2[16]; + union u_mapflag_args args = {}; + + if (sscanf(w4, "%15[^,],%15[^,],%11d", drop_arg1, drop_arg2, &args.nightmaredrop.drop_per) == 3) { + + if (!strcmpi(drop_arg1, "random")) + args.nightmaredrop.drop_id = -1; + else if (itemdb_exists((args.nightmaredrop.drop_id = atoi(drop_arg1))) == NULL) { + args.nightmaredrop.drop_id = 0; + ShowWarning("npc_parse_mapflag: Invalid item ID '%d' supplied for mapflag 'pvp_nightmaredrop' (file '%s', line '%d'), removing.\n * w1=%s\n * w2=%s\n * w3=%s\n * w4=%s\n", args.nightmaredrop.drop_id, filepath, strline(buffer, start - buffer), w1, w2, w3, w4); + break; + } + if (!strcmpi(drop_arg2, "inventory")) + args.nightmaredrop.drop_type = NMDT_INVENTORY; + else if (!strcmpi(drop_arg2, "equip")) + args.nightmaredrop.drop_type = NMDT_EQUIP; + else if (!strcmpi(drop_arg2, "all")) + args.nightmaredrop.drop_type = NMDT_ALL; + + if (args.nightmaredrop.drop_id != 0) + map_setmapflag_sub(m, MF_PVP_NIGHTMAREDROP, true, &args); + } else if (!state) + map_setmapflag(m, MF_PVP_NIGHTMAREDROP, false); + break; + } + + case MF_BATTLEGROUND: + if (state) { + union u_mapflag_args args = {}; + + if (sscanf(w4, "%11d", &args.flag_val) < 1) + args.flag_val = 1; // Default value + + map_setmapflag_sub(m, MF_BATTLEGROUND, true, &args); + } else + map_setmapflag(m, MF_BATTLEGROUND, false); + break; + + case MF_NOCOMMAND: + if (state) { + union u_mapflag_args args = {}; + + if (sscanf(w4, "%11d", &args.flag_val) < 1) + args.flag_val = 100; // No level specified, block everyone. + + map_setmapflag_sub(m, MF_NOCOMMAND, true, &args); + } else + map_setmapflag(m, MF_NOCOMMAND, false); + break; + + case MF_RESTRICTED: + if (state) { + union u_mapflag_args args = {}; + + if (sscanf(w4, "%11d", &args.flag_val) == 1) + map_setmapflag_sub(m, MF_RESTRICTED, true, &args); + else // Could not be read, no value defined; don't remove as other restrictions may be set on the map + ShowWarning("npc_parse_mapflag: Zone value not set for the restricted mapflag! Skipped flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer)); + } else + map_setmapflag(m, MF_RESTRICTED, false); + break; + + case MF_JEXP: + case MF_BEXP: { + union u_mapflag_args args = {}; + + if (sscanf(w4, "%11d", &args.flag_val) < 1) + args.flag_val = 0; + + map_setmapflag_sub(m, mapflag, state, &args); + } + break; + + case MF_SKILL_DAMAGE: { +#ifdef ADJUST_SKILL_DAMAGE + char skill_name[SKILL_NAME_LENGTH]; + char caster_constant[NAME_LENGTH]; + + memset(skill_name, 0, sizeof(skill_name)); + + if (!state) + map_setmapflag(m, MF_SKILL_DAMAGE, false); + else { + union u_mapflag_args args = {}; + + if (sscanf(w4, "%30[^,],%23[^,],%11d,%11d,%11d,%11d[^\n]", skill_name, caster_constant, &args.skill_damage.rate[SKILLDMG_PC], &args.skill_damage.rate[SKILLDMG_MOB], &args.skill_damage.rate[SKILLDMG_BOSS], &args.skill_damage.rate[SKILLDMG_OTHER]) >= 3) { + if (ISDIGIT(caster_constant[0])) + args.skill_damage.caster = atoi(caster_constant); + else { + int val; + + if (!script_get_constant(caster_constant, &val)) { + ShowError( "npc_parse_mapflag: Unknown constant '%s'. Skipping (file '%s', line '%d').\n", caster_constant, filepath, strline(buffer, start - buffer) ); + break; + } + + args.skill_damage.caster = val; + } + + if (!args.skill_damage.caster) + args.skill_damage.caster = BL_ALL; + + for (int i = 0; i < SKILLDMG_MAX; i++) + args.skill_damage.rate[i] = cap_value(args.skill_damage.rate[i], -100, INT_MAX); + + if (strcmp(skill_name, "all") == 0) // Adjust damage for all skills + map_setmapflag_sub(m, MF_SKILL_DAMAGE, true, &args); + else if (skill_name2id(skill_name) <= 0) + ShowWarning("npc_parse_mapflag: Invalid skill name '%s' for Skill Damage mapflag. Skipping (file '%s', line '%d').\n", skill_name, filepath, strline(buffer, start - buffer)); + else { // Adjusted damage for specified skill + map_setmapflag(m, MF_SKILL_DAMAGE, true); + map_skill_damage_add(&map[m], skill_name2id(skill_name), args.skill_damage.rate, args.skill_damage.caster); } } - map[m].flag.pvp_nightmaredrop = 1; } - } else if (!state) //Disable - map[m].flag.pvp_nightmaredrop = 0; - } - else if (!strcmpi(w3,"pvp_nocalcrank")) - map[m].flag.pvp_nocalcrank=state; - else if (!strcmpi(w3,"gvg")) { - map[m].flag.gvg = state; - 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 ) { - 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)); - } - } - else if (!strcmpi(w3,"gvg_noparty")) - map[m].flag.gvg_noparty=state; - else if (!strcmpi(w3,"gvg_dungeon")) { - map[m].flag.gvg_dungeon=state; - if (state) map[m].flag.pvp=0; - } - else if (!strcmpi(w3,"gvg_castle")) { - map[m].flag.gvg_castle=state; - if (state) map[m].flag.pvp=0; - } - else if (!strcmpi(w3,"gvg_te")) { - map[m].flag.gvg_te = state; - 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 ) { - 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)); - } - } - else if (!strcmpi(w3,"gvg_te_castle")) { - map[m].flag.gvg_te_castle = state; - if (state) { - map[m].flag.gvg_castle = 0; - map[m].flag.pvp = 0; - } - } - else if (!strcmpi(w3,"battleground")) { - if( state ) { - if( sscanf(w4, "%11d", &state) == 1 ) - map[m].flag.battleground = state; - else - map[m].flag.battleground = 1; // Default value - } else - map[m].flag.battleground = 0; - - 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) ) { - 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)); - } - } - else if (!strcmpi(w3,"noexppenalty")) - map[m].flag.noexppenalty=state; - else if (!strcmpi(w3,"nozenypenalty")) - map[m].flag.nozenypenalty=state; - else if (!strcmpi(w3,"notrade")) - map[m].flag.notrade=state; - else if (!strcmpi(w3,"novending")) - map[m].flag.novending=state; - else if (!strcmpi(w3,"nodrop")) - map[m].flag.nodrop=state; - else if (!strcmpi(w3,"noskill")) - map[m].flag.noskill=state; - else if (!strcmpi(w3,"noicewall")) - map[m].flag.noicewall=state; - else if (!strcmpi(w3,"snow")) - map[m].flag.snow=state; - else if (!strcmpi(w3,"clouds")) - map[m].flag.clouds=state; - else if (!strcmpi(w3,"clouds2")) - map[m].flag.clouds2=state; - else if (!strcmpi(w3,"fog")) - map[m].flag.fog=state; - else if (!strcmpi(w3,"fireworks")) - map[m].flag.fireworks=state; - else if (!strcmpi(w3,"sakura")) - map[m].flag.sakura=state; - else if (!strcmpi(w3,"leaves")) - map[m].flag.leaves=state; - else if (!strcmpi(w3,"nightenabled")) - map[m].flag.nightenabled=state; - else if (!strcmpi(w3,"nogo")) - map[m].flag.nogo=state; - else if (!strcmpi(w3,"noexp")) { - map[m].flag.nobaseexp=state; - map[m].flag.nojobexp=state; - } - else if (!strcmpi(w3,"nobaseexp")) - map[m].flag.nobaseexp=state; - else if (!strcmpi(w3,"nojobexp")) - map[m].flag.nojobexp=state; - else if (!strcmpi(w3,"noloot")) { - map[m].flag.nomobloot=state; - map[m].flag.nomvploot=state; - } - else if (!strcmpi(w3,"nomobloot")) - map[m].flag.nomobloot=state; - else if (!strcmpi(w3,"nomvploot")) - map[m].flag.nomvploot=state; - else if (!strcmpi(w3,"nocommand")) { - if (state) { - if (sscanf(w4, "%11d", &state) == 1) - map[m].nocommand =state; - else //No level specified, block everyone. - map[m].nocommand =100; - } else - map[m].nocommand=0; - } - else if (!strcmpi(w3,"restricted")) { - if (state) { - if (sscanf(w4, "%11d", &state) == 1) { - map[m].flag.restricted = 1; - map[m].zone |= 1<<(state+1); - } else { // Could not be read, no value defined - //we don't remove has other restricted may be set on the map - ShowWarning("npc_parse_mapflag: You did not set a zone value for the restricted mapflag! Skipped flag from %s (file '%s', line '%d').\n", map[m].name, filepath, strline(buffer,start-buffer)); - } - } else { - map[m].flag.restricted=0; - map[m].zone = 0; - } - } - else if (!strcmpi(w3,"jexp")) { - map[m].adjust.jexp = (state) ? atoi(w4) : 100; - if( map[m].adjust.jexp < 0 ) map[m].adjust.jexp = 100; - map[m].flag.nojobexp = (map[m].adjust.jexp==0)?1:0; - } - else if (!strcmpi(w3,"bexp")) { - map[m].adjust.bexp = (state) ? atoi(w4) : 100; - if( map[m].adjust.bexp < 0 ) map[m].adjust.bexp = 100; - map[m].flag.nobaseexp = (map[m].adjust.bexp==0)?1:0; - } - else if (!strcmpi(w3,"loadevent")) - map[m].flag.loadevent=state; - else if (!strcmpi(w3,"nochat")) - map[m].flag.nochat=state; - else if (!strcmpi(w3,"partylock")) - map[m].flag.partylock=state; - else if (!strcmpi(w3,"guildlock")) - map[m].flag.guildlock=state; - else if (!strcmpi(w3,"reset")) - map[m].flag.reset=state; - else if (!strcmpi(w3,"nomapchannelautojoin")) - map[m].flag.chmautojoin = state; - else if (!strcmpi(w3,"nousecart")) - map[m].flag.nousecart = state; - else if (!strcmpi(w3,"noitemconsumption")) - map[m].flag.noitemconsumption = state; - else if (!strcmpi(w3,"summonstarmiracle")) - map[m].flag.nosumstarmiracle = state; - else if (!strcmpi(w3,"nomineeffect")) - map[m].flag.nomineeffect = state; - else if (!strcmpi(w3,"nolockon")) - map[m].flag.nolockon = state; - else if (!strcmpi(w3,"notomb")) - map[m].flag.notomb = state; - else if (!strcmpi(w3,"nocostume")) - map[m].flag.nocostume = state; - else if (!strcmpi(w3,"hidemobhpbar")) - map[m].flag.hidemobhpbar = state; - else if (!strcmpi(w3,"skill_damage")) { -#ifdef ADJUST_SKILL_DAMAGE - char skill[SKILL_NAME_LENGTH]; - int pc = 0, mob = 0, boss = 0, other = 0, caster = 0; - - memset(skill, 0, sizeof(skill)); - map[m].flag.skill_damage = state; // Set the mapflag - - if (!state) { - memset(&map[m].adjust.damage, 0, sizeof(map[m].adjust.damage)); - if (map[m].skill_damage.count) - map_skill_damage_free(&map[m]); - } - else { - if (sscanf(w4, "%30[^,],%11d,%11d,%11d,%11d,%11d[^\n]", skill, &caster, &pc, &mob, &boss, &other) >= 3) { - caster = (!caster) ? SDC_ALL : caster; - pc = cap_value(pc, -100, INT_MAX); - mob = cap_value(mob, -100, INT_MAX); - boss = cap_value(boss, -100, INT_MAX); - other = cap_value(other, -100, INT_MAX); - - if (strcmp(skill,"all") == 0) { // Adjust damages for all skills - map[m].adjust.damage.caster = caster; - map[m].adjust.damage.pc = pc; - map[m].adjust.damage.mob = mob; - map[m].adjust.damage.boss = boss; - map[m].adjust.damage.other = other; - } - else if (skill_name2id(skill) <= 0) - ShowWarning("npc_parse_mapflag: skill_damage: Invalid skill name '%s'. Skipping (file '%s', line '%d')\n", skill, filepath, strline(buffer,start-buffer)); - else //Damages for specified skill - map_skill_damage_add(&map[m], skill_name2id(skill), pc, mob, boss, other, caster); - } - } #else - ShowInfo("npc_parse_mapflag: skill_damage: ADJUST_SKILL_DAMAGE is inactive (core.hpp). Skipping this mapflag..\n"); + ShowWarning("npc_parse_mapflag: skill_damage: ADJUST_SKILL_DAMAGE is inactive (src/config/core.hpp). Skipping this mapflag..\n"); #endif + break; + } + + // All others do not need special treatment + default: + map_setmapflag(m, mapflag, state); + break; } - else - ShowError("npc_parse_mapflag: unrecognized mapflag '%s' (file '%s', line '%d').\n", w3, filepath, strline(buffer,start-buffer)); return strchr(start,'\n');// continue } @@ -4586,7 +4435,7 @@ int npc_reload(void) { if(battle_config.dynamic_mobs) {// dynamic check by [random] int16 m; - for (m = 0; m < map_num; m++) { + for (m = 0; m < map.size(); m++) { int16 i; for (i = 0; i < MAX_MOB_LIST_PER_MAP; i++) { if (map[m].moblist[i] != NULL) { @@ -4727,7 +4576,7 @@ static void npc_debug_warps_sub(struct npc_data* nd) static void npc_debug_warps(void) { int16 m, i; - for (m = 0; m < map_num; m++) + for (m = 0; m < map.size(); m++) for (i = 0; i < map[m].npc_num; i++) npc_debug_warps_sub(map[m].npc[i]); } diff --git a/src/map/party.cpp b/src/map/party.cpp index 1db73f45db..8660ea8b6b 100644 --- a/src/map/party.cpp +++ b/src/map/party.cpp @@ -791,7 +791,7 @@ int party_changeleader(struct map_session_data *sd, struct map_session_data *tsd return -3; } - if ( map[sd->bl.m].flag.partylock ) { + if ( map_getmapflag(sd->bl.m, MF_PARTYLOCK) ) { clif_displaymessage(sd->fd, msg_txt(sd,287)); return 0; } diff --git a/src/map/pc.cpp b/src/map/pc.cpp index 617824cc59..2f4a99c6fe 100755 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -712,7 +712,7 @@ void pc_makesavestatus(struct map_session_data *sd) { sd->status.last_point.y = sd->bl.y; } - if(map[sd->bl.m].flag.nosave) { + if(map_getmapflag(sd->bl.m, MF_NOSAVE)) { struct map_data *m=&map[sd->bl.m]; if(m->save.map) memcpy(&sd->status.last_point,&m->save,sizeof(sd->status.last_point)); @@ -1570,7 +1570,7 @@ void pc_reg_received(struct map_session_data *sd) // decrement the number of pvp players on the map map[sd->bl.m].users_pvp--; - if( map[sd->bl.m].flag.pvp && !map[sd->bl.m].flag.pvp_nocalcrank && sd->pvp_timer != INVALID_TIMER ){ + if( map_getmapflag(sd->bl.m, MF_PVP) && !map_getmapflag(sd->bl.m, MF_PVP_NOCALCRANK) && sd->pvp_timer != INVALID_TIMER ){ // unregister the player for ranking delete_timer( sd->pvp_timer, pc_calc_pvprank_timer ); sd->pvp_timer = INVALID_TIMER; @@ -4764,7 +4764,7 @@ bool pc_dropitem(struct map_session_data *sd,int n,int amount) ) return false; - if( map[sd->bl.m].flag.nodrop ) + if( map_getmapflag(sd->bl.m, MF_NODROP) ) { clif_displaymessage (sd->fd, msg_txt(sd,271)); return false; //Can't drop items in nodrop mapflag maps. @@ -4882,7 +4882,7 @@ bool pc_isUseitem(struct map_session_data *sd,int n) return false; if (pc_has_permission(sd,PC_PERM_ITEM_UNCONDITIONAL)) return true; - if(map[sd->bl.m].flag.noitemconsumption) //consumable but mapflag prevent it + if(map_getmapflag(sd->bl.m, MF_NOITEMCONSUMPTION)) //consumable but mapflag prevent it return false; //Prevent mass item usage. [Skotlex] if( DIFF_TICK(sd->canuseitem_tick,gettick()) > 0 || @@ -4900,14 +4900,14 @@ bool pc_isUseitem(struct map_session_data *sd,int n) return false; // You cannot use this item while storage is open. } - if (item->flag.dead_branch && (map[sd->bl.m].flag.nobranch || map_flag_gvg2(sd->bl.m))) + if (item->flag.dead_branch && (map_getmapflag(sd->bl.m, MF_NOBRANCH) || map_flag_gvg2(sd->bl.m))) return false; switch( nameid ) { case ITEMID_WING_OF_FLY: case ITEMID_GIANT_FLY_WING: case ITEMID_N_FLY_WING: - if( map[sd->bl.m].flag.noteleport || map_flag_gvg2(sd->bl.m) ) { + if( map_getmapflag(sd->bl.m, MF_NOTELEPORT) || map_flag_gvg2(sd->bl.m) ) { clif_skill_teleportmessage(sd,0); return false; } @@ -4948,7 +4948,7 @@ bool pc_isUseitem(struct map_session_data *sd,int n) clif_displaymessage(sd->fd, msg_txt(sd,663)); return false; } - if( map[sd->bl.m].flag.noreturn && nameid != ITEMID_WING_OF_FLY && nameid != ITEMID_GIANT_FLY_WING && nameid != ITEMID_N_FLY_WING ) + if( map_getmapflag(sd->bl.m, MF_NORETURN) && nameid != ITEMID_WING_OF_FLY && nameid != ITEMID_GIANT_FLY_WING && nameid != ITEMID_N_FLY_WING ) return false; break; case ITEMID_MERCENARY_RED_POTION: @@ -4967,7 +4967,7 @@ bool pc_isUseitem(struct map_session_data *sd,int n) break; case ITEMID_NEURALIZER: - if( !map[sd->bl.m].flag.reset ) + if( !map_getmapflag(sd->bl.m, MF_RESET) ) return false; break; } @@ -5375,7 +5375,7 @@ int pc_steal_item(struct map_session_data *sd,struct block_list *bl, uint16 skil md_status= status_get_status_data(bl); if (md->master_id || status_has_mode(md_status, MD_STATUS_IMMUNE) || status_get_race2(&md->bl) == RC2_TREASURE || - map[bl->m].flag.nomobloot || // check noloot map flag [Lorky] + map_getmapflag(bl->m, MF_NOMOBLOOT) || // check noloot map flag [Lorky] (battle_config.skill_steal_max_tries && //Reached limit of steal attempts. [Lupus] md->state.steal_flag++ >= battle_config.skill_steal_max_tries) ) { //Can't steal from @@ -5555,7 +5555,7 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in if (sd->regen.state.gc) sd->regen.state.gc = 0; // make sure vending is allowed here - if (sd->state.vending && map[m].flag.novending) { + if (sd->state.vending && map_getmapflag(m, MF_NOVENDING)) { clif_displaymessage (sd->fd, msg_txt(sd,276)); // "You can't open a shop on this map" vending_closevending(sd); } @@ -5638,7 +5638,7 @@ enum e_setpos pc_setpos(struct map_session_data* sd, unsigned short mapindex, in sd->bl.x = sd->ud.to_x = x; sd->bl.y = sd->ud.to_y = y; - if( sd->status.guild_id > 0 && map[m].flag.gvg_castle ) + if( sd->status.guild_id > 0 && map_getmapflag(m, MF_GVG_CASTLE) ) { // Increased guild castle regen [Valaris] struct guild_castle *gc = guild_mapindex2gc(sd->mapindex); if(gc && gc->guild_id == sd->status.guild_id) @@ -5704,7 +5704,7 @@ char pc_randomwarp(struct map_session_data *sd, clr_type type) m=sd->bl.m; - if (map[sd->bl.m].flag.noteleport) //Teleport forbidden + if (map_getmapflag(sd->bl.m, MF_NOTELEPORT)) //Teleport forbidden return 3; do { @@ -5729,7 +5729,7 @@ bool pc_memo(struct map_session_data* sd, int pos) nullpo_ret(sd); // check mapflags - if( sd->bl.m >= 0 && (map[sd->bl.m].flag.nomemo || map[sd->bl.m].flag.nowarpto) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE) ) { + if( sd->bl.m >= 0 && (map_getmapflag(sd->bl.m, MF_NOMEMO) || map_getmapflag(sd->bl.m, MF_NOWARPTO)) && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE) ) { clif_skill_teleportmessage(sd, 1); // "Saved point cannot be memorized." return false; } @@ -6769,7 +6769,7 @@ void pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned in if (!(exp_flag&2)) { - if (!battle_config.pvp_exp && map[sd->bl.m].flag.pvp) // [MouseJstr] + if (!battle_config.pvp_exp && map_getmapflag(sd->bl.m, MF_PVP)) // [MouseJstr] return; // no exp on pvp maps if (sd->status.guild_id>0) @@ -7776,7 +7776,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) if(sd->status.pet_id > 0 && sd->pd) { struct pet_data *pd = sd->pd; - if( !map[sd->bl.m].flag.noexppenalty ) { + if( !map_getmapflag(sd->bl.m, MF_NOEXPPENALTY) ) { pet_set_intimate(pd, pd->pet.intimate - pd->get_pet_db()->die); if( pd->pet.intimate < 0 ) pd->pet.intimate = 0; @@ -7896,7 +7896,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) } if(battle_config.bone_drop==2 - || (battle_config.bone_drop==1 && map[sd->bl.m].flag.pvp)) + || (battle_config.bone_drop==1 && map_getmapflag(sd->bl.m, MF_PVP))) { struct item item_tmp; memset(&item_tmp,0,sizeof(item_tmp)); @@ -7915,7 +7915,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) // changed penalty options, added death by player if pk_mode [Valaris] if(battle_config.death_penalty_type && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE // only novices will receive no penalty - && !map[sd->bl.m].flag.noexppenalty && !map_flag_gvg2(sd->bl.m) + && !map_getmapflag(sd->bl.m, MF_NOEXPPENALTY) && !map_flag_gvg2(sd->bl.m) && !sd->sc.data[SC_BABY] && !sd->sc.data[SC_LIFEINSURANCE]) { uint32 base_penalty = 0; @@ -7963,28 +7963,28 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) if (base_penalty || job_penalty) pc_lostexp(sd, base_penalty, job_penalty); - if( zeny_penalty > 0 && !map[sd->bl.m].flag.nozenypenalty) { + if( zeny_penalty > 0 && !map_getmapflag(sd->bl.m, MF_NOZENYPENALTY)) { zeny_penalty = (uint32)( sd->status.zeny * ( zeny_penalty / 10000. ) ); if(zeny_penalty) pc_payzeny(sd, zeny_penalty, LOG_TYPE_PICKDROP_PLAYER, NULL); } } - if(map[sd->bl.m].flag.pvp_nightmaredrop) { // Moved this outside so it works when PVP isn't enabled and during pk mode [Ancyker] - int j; - for(j=0;jbl.m, MF_PVP_NIGHTMAREDROP ) ) { // Moved this outside so it works when PVP isn't enabled and during pk mode [Ancyker] + for(int j=0;jbl.m].drop_list[j].drop_id; - int type = map[sd->bl.m].drop_list[j].drop_type; int per = map[sd->bl.m].drop_list[j].drop_per; + enum e_nightmare_drop_type type = map[sd->bl.m].drop_list[j].drop_type; + if(id == 0) continue; if(id == -1){ int eq_num=0,eq_n[MAX_INVENTORY]; memset(eq_n,0,sizeof(eq_n)); for(i=0;iinventory.u.items_inventory[i].equip) - || (type == 2 && sd->inventory.u.items_inventory[i].equip) - || type == 3) + if( (type&NMDT_INVENTORY && !sd->inventory.u.items_inventory[i].equip) + || (type&NMDT_EQUIP && sd->inventory.u.items_inventory[i].equip) + || type&NMDT_ALL) { int l; ARR_FIND( 0, MAX_INVENTORY, l, eq_n[l] <= 0 ); @@ -8007,9 +8007,9 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) for(i=0;iinventory.u.items_inventory[i].nameid == id && rnd()%10000 < per - && ((type == 1 && !sd->inventory.u.items_inventory[i].equip) - || (type == 2 && sd->inventory.u.items_inventory[i].equip) - || type == 3) ){ + && ((type&NMDT_INVENTORY && !sd->inventory.u.items_inventory[i].equip) + || (type&NMDT_EQUIP && sd->inventory.u.items_inventory[i].equip) + || type&NMDT_ALL) ){ if(sd->inventory.u.items_inventory[i].equip) pc_unequipitem(sd,i,3); pc_dropitem(sd,i,1); @@ -8021,7 +8021,7 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) } // pvp // disable certain pvp functions on pk_mode [Valaris] - if( map[sd->bl.m].flag.pvp && !battle_config.pk_mode && !map[sd->bl.m].flag.pvp_nocalcrank ) { + if( map_getmapflag(sd->bl.m, MF_PVP) && !battle_config.pk_mode && !map_getmapflag(sd->bl.m, MF_PVP_NOCALCRANK) ) { sd->pvp_point -= 5; sd->pvp_lost++; if( src && src->type == BL_PC ) { @@ -10584,7 +10584,7 @@ static TIMER_FUNC(pc_autosave){ static int pc_daynight_timer_sub(struct map_session_data *sd,va_list ap) { - if (sd->state.night != night_flag && map[sd->bl.m].flag.nightenabled) + if (sd->state.night != night_flag && map_getmapflag(sd->bl.m, MF_NIGHTENABLED)) { //Night/day state does not match. clif_status_load(&sd->bl, EFST_SKE, night_flag); //New night effect by dynamix [Skotlex] sd->state.night = night_flag; @@ -12476,11 +12476,11 @@ bool pc_job_can_entermap(enum e_job jobid, int m, int group_lv) { return true; if ((!map_flag_vs2(m) && job_info[idx].noenter_map.zone&1) || // Normal - (map[m].flag.pvp && job_info[idx].noenter_map.zone&2) || // PVP + (map_getmapflag(m, MF_PVP) && job_info[idx].noenter_map.zone&2) || // PVP (map_flag_gvg2_no_te(m) && job_info[idx].noenter_map.zone&4) || // GVG - (map[m].flag.battleground && job_info[idx].noenter_map.zone&8) || // Battleground + (map_getmapflag(m, MF_BATTLEGROUND) && job_info[idx].noenter_map.zone&8) || // Battleground (map_flag_gvg2_te(m) && job_info[idx].noenter_map.zone&16) || // WOE:TE - (map[m].flag.restricted && job_info[idx].noenter_map.zone&(8*map[m].zone)) // Zone restriction + (map_getmapflag(m, MF_RESTRICTED) && job_info[idx].noenter_map.zone&(8*map[m].zone)) // Zone restriction ) return false; @@ -12525,7 +12525,7 @@ void pc_set_costume_view(struct map_session_data *sd) { sd->status.robe = id->look; // Costumes check - if (!map[sd->bl.m].flag.nocostume) { + if (!map_getmapflag(sd->bl.m, MF_NOCOSTUME)) { if ((i = sd->equip_index[EQI_COSTUME_HEAD_LOW]) != -1 && (id = sd->inventory_data[i])) { if (!(id->equip&(EQP_COSTUME_HEAD_MID|EQP_COSTUME_HEAD_TOP))) sd->status.head_bottom = id->look; diff --git a/src/map/script.cpp b/src/map/script.cpp index faf8617b61..aa05b45d4e 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -380,77 +380,6 @@ const char* parse_subexpr(const char* p,int limit); int run_func(struct script_state *st); unsigned short script_instancegetid(struct script_state *st); -enum { - MF_NOMEMO, //0 - MF_NOTELEPORT, - MF_NOSAVE, - MF_NOBRANCH, - MF_NOPENALTY, - MF_NOZENYPENALTY, - MF_PVP, - MF_PVP_NOPARTY, - MF_PVP_NOGUILD, - MF_GVG, - MF_GVG_NOPARTY, //10 - MF_NOTRADE, - MF_NOSKILL, - MF_NOWARP, - MF_PARTYLOCK, - MF_NOICEWALL, - MF_SNOW, - MF_FOG, - MF_SAKURA, - MF_LEAVES, - /** - * No longer available, keeping here just in case it's back someday. [Ind] - **/ - //MF_RAIN, //20 - // 21 free - MF_NOGO = 22, - MF_CLOUDS, - MF_CLOUDS2, - MF_FIREWORKS, - MF_GVG_CASTLE, - MF_GVG_DUNGEON, - MF_NIGHTENABLED, - MF_NOBASEEXP, - MF_NOJOBEXP, //30 - MF_NOMOBLOOT, - MF_NOMVPLOOT, - MF_NORETURN, - MF_NOWARPTO, - MF_NIGHTMAREDROP, - MF_RESTRICTED, - MF_NOCOMMAND, - MF_NODROP, - MF_JEXP, - MF_BEXP, //40 - MF_NOVENDING, - MF_LOADEVENT, - MF_NOCHAT, - MF_NOEXPPENALTY, - MF_GUILDLOCK, - MF_TOWN, - MF_AUTOTRADE, - MF_ALLOWKS, - MF_MONSTER_NOTELEPORT, - MF_PVP_NOCALCRANK, //50 - MF_BATTLEGROUND, - MF_RESET, - MF_CHANNELAUTOJOIN, - MF_NOUSECART, - MF_NOITEMCONSUMPTION, - MF_SUMSTARTMIRACLE, - MF_NOMINEEFFECT, - MF_NOLOCKON, - MF_NOTOMB, - MF_SKILL_DAMAGE, //60 - MF_NOCOSTUME, - MF_GVG_TE_CASTLE, - MF_GVG_TE, - MF_HIDEMOBHPBAR, -}; - const char* script_op2name(int op) { #define RETURN_OP_NAME(type) case type: return #type @@ -2291,6 +2220,39 @@ static void add_buildin_func(void) } } +/** + * String comparison with a char array to a script constant + * @param prefix: Char array to compare + * @param value: Script constant + * @return Constant name as char array or NULL otherwise + */ +const char* script_get_constant_str( const char* prefix, int64 value ){ + const char* name; + + for(int i = 0; i < str_data_size; i++ ){ + // Check if it is a constant + if( str_data[i].type != C_INT ){ + continue; + } + + // Check if the value matches + if( str_data[i].val != value ){ + continue; + } + + // Look up the actual string + name = get_str(i); + + // Compare the prefix + if( !strncasecmp( name, prefix, strlen(prefix) ) ){ + // We found a match + return name; + } + } + + return NULL; +} + /// Retrieves the value of a constant parameter. bool script_get_parameter(const char* name, int* value) { @@ -5652,15 +5614,15 @@ BUILDIN_FUNC(warpparty) switch( type ) { case 0: // Random - if(!map[pl_sd->bl.m].flag.nowarp) + if(!map_getmapflag(pl_sd->bl.m, MF_NOWARP)) pc_randomwarp(pl_sd,CLR_TELEPORT); break; case 1: // SavePointAll - if(!map[pl_sd->bl.m].flag.noreturn) + if(!map_getmapflag(pl_sd->bl.m, MF_NORETURN)) pc_setpos(pl_sd,pl_sd->status.save_point.map,pl_sd->status.save_point.x,pl_sd->status.save_point.y,CLR_TELEPORT); break; case 2: // SavePoint - if(!map[pl_sd->bl.m].flag.noreturn) + if(!map_getmapflag(pl_sd->bl.m, MF_NORETURN)) pc_setpos(pl_sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT); break; case 3: // Leader @@ -5678,7 +5640,7 @@ BUILDIN_FUNC(warpparty) } while ((--attempts) > 0 && !map_getcell(m, x, y, CELL_CHKPASS)); } - if(!map[pl_sd->bl.m].flag.noreturn && !map[pl_sd->bl.m].flag.nowarp && pc_job_can_entermap((enum e_job)pl_sd->status.class_, m, pl_sd->group_level)) + if(!map_getmapflag(pl_sd->bl.m, MF_NORETURN) && !map_getmapflag(pl_sd->bl.m, MF_NOWARP) && pc_job_can_entermap((enum e_job)pl_sd->status.class_, m, pl_sd->group_level)) pc_setpos(pl_sd,mapindex,x,y,CLR_TELEPORT); break; } @@ -5736,19 +5698,19 @@ BUILDIN_FUNC(warpguild) switch( type ) { case 0: // Random - if(!map[pl_sd->bl.m].flag.nowarp) + if(!map_getmapflag(pl_sd->bl.m, MF_NOWARP)) pc_randomwarp(pl_sd,CLR_TELEPORT); break; case 1: // SavePointAll - if(!map[pl_sd->bl.m].flag.noreturn) + if(!map_getmapflag(pl_sd->bl.m, MF_NORETURN)) pc_setpos(pl_sd,pl_sd->status.save_point.map,pl_sd->status.save_point.x,pl_sd->status.save_point.y,CLR_TELEPORT); break; case 2: // SavePoint - if(!map[pl_sd->bl.m].flag.noreturn) + if(!map_getmapflag(pl_sd->bl.m, MF_NORETURN)) pc_setpos(pl_sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT); break; case 3: // m,x,y - if(!map[pl_sd->bl.m].flag.noreturn && !map[pl_sd->bl.m].flag.nowarp && pc_job_can_entermap((enum e_job)pl_sd->status.class_, m, pl_sd->group_level)) + if(!map_getmapflag(pl_sd->bl.m, MF_NORETURN) && !map_getmapflag(pl_sd->bl.m, MF_NOWARP) && pc_job_can_entermap((enum e_job)pl_sd->status.class_, m, pl_sd->group_level)) pc_setpos(pl_sd,mapindex,x,y,CLR_TELEPORT); break; } @@ -12044,7 +12006,7 @@ BUILDIN_FUNC(warpwaitingpc) { TBL_PC* sd = cd->usersd[0]; - if( strcmp(map_name,"SavePoint") == 0 && map[sd->bl.m].flag.noteleport ) + if( strcmp(map_name,"SavePoint") == 0 && map_getmapflag(sd->bl.m, MF_NOTELEPORT) ) {// can't teleport on this map break; } @@ -12261,6 +12223,7 @@ BUILDIN_FUNC(setmapflagnosave) int16 m,x,y; unsigned short mapindex; const char *str,*str2; + union u_mapflag_args args = {}; str=script_getstr(st,2); str2=script_getstr(st,3); @@ -12269,331 +12232,110 @@ BUILDIN_FUNC(setmapflagnosave) m = map_mapname2mapid(str); mapindex = mapindex_name2id(str2); - if(m >= 0 && mapindex) { - map[m].flag.nosave=1; - map[m].save.map=mapindex; - map[m].save.x=x; - map[m].save.y=y; + if(m < 0) { + ShowWarning("buildin_setmapflagnosave: Invalid map name %s.\n", str); + return SCRIPT_CMD_FAILURE; } + + args.nosave.map = mapindex; + args.nosave.x = x; + args.nosave.y = y; + + map_setmapflag_sub(m, MF_NOSAVE, true, &args); return SCRIPT_CMD_SUCCESS; } BUILDIN_FUNC(getmapflag) { - int16 m,i; + int16 m; + int mf; const char *str; + union u_mapflag_args args = {}; str=script_getstr(st,2); - i=script_getnum(st,3); m = map_mapname2mapid(str); - if(m >= 0) { - switch(i) { - case MF_NOMEMO: script_pushint(st,map[m].flag.nomemo); break; - case MF_NOTELEPORT: script_pushint(st,map[m].flag.noteleport); break; - case MF_NOSAVE: script_pushint(st,map[m].flag.nosave); break; - case MF_NOBRANCH: script_pushint(st,map[m].flag.nobranch); break; - case MF_NOPENALTY: script_pushint(st,map[m].flag.noexppenalty); break; - case MF_NOZENYPENALTY: script_pushint(st,map[m].flag.nozenypenalty); break; - case MF_PVP: script_pushint(st,map[m].flag.pvp); break; - case MF_PVP_NOPARTY: script_pushint(st,map[m].flag.pvp_noparty); break; - case MF_PVP_NOGUILD: script_pushint(st,map[m].flag.pvp_noguild); break; - case MF_GVG: script_pushint(st,map[m].flag.gvg); break; - case MF_GVG_NOPARTY: script_pushint(st,map[m].flag.gvg_noparty); break; - case MF_NOTRADE: script_pushint(st,map[m].flag.notrade); break; - case MF_NOSKILL: script_pushint(st,map[m].flag.noskill); break; - case MF_NOWARP: script_pushint(st,map[m].flag.nowarp); break; - case MF_PARTYLOCK: script_pushint(st,map[m].flag.partylock); break; - case MF_NOICEWALL: script_pushint(st,map[m].flag.noicewall); break; - case MF_SNOW: script_pushint(st,map[m].flag.snow); break; - 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; - 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; - case MF_FIREWORKS: script_pushint(st,map[m].flag.fireworks); break; - case MF_GVG_CASTLE: script_pushint(st,map[m].flag.gvg_castle); break; - case MF_GVG_DUNGEON: script_pushint(st,map[m].flag.gvg_dungeon); break; - case MF_NIGHTENABLED: script_pushint(st,map[m].flag.nightenabled); break; - case MF_NOBASEEXP: script_pushint(st,map[m].flag.nobaseexp); break; - case MF_NOJOBEXP: script_pushint(st,map[m].flag.nojobexp); break; - case MF_NOMOBLOOT: script_pushint(st,map[m].flag.nomobloot); break; - case MF_NOMVPLOOT: script_pushint(st,map[m].flag.nomvploot); break; - 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].adjust.jexp); break; - case MF_BEXP: script_pushint(st,map[m].adjust.bexp); break; - case MF_NOVENDING: script_pushint(st,map[m].flag.novending); break; - case MF_LOADEVENT: script_pushint(st,map[m].flag.loadevent); break; - case MF_NOCHAT: script_pushint(st,map[m].flag.nochat); break; - case MF_NOEXPPENALTY: script_pushint(st,map[m].flag.noexppenalty ); break; - case MF_GUILDLOCK: script_pushint(st,map[m].flag.guildlock); break; - case MF_TOWN: script_pushint(st,map[m].flag.town); break; - case MF_AUTOTRADE: script_pushint(st,map[m].flag.autotrade); break; - case MF_ALLOWKS: script_pushint(st,map[m].flag.allowks); break; - case MF_MONSTER_NOTELEPORT: script_pushint(st,map[m].flag.monster_noteleport); break; - case MF_PVP_NOCALCRANK: script_pushint(st,map[m].flag.pvp_nocalcrank); break; - case MF_BATTLEGROUND: script_pushint(st,map[m].flag.battleground); break; - case MF_RESET: script_pushint(st,map[m].flag.reset); break; - case MF_CHANNELAUTOJOIN: script_pushint(st,map[m].flag.chmautojoin); break; - case MF_NOUSECART: script_pushint(st,map[m].flag.nousecart); break; - case MF_NOITEMCONSUMPTION: script_pushint(st,map[m].flag.noitemconsumption); break; - case MF_SUMSTARTMIRACLE: script_pushint(st,map[m].flag.nosumstarmiracle); break; - case MF_NOMINEEFFECT: script_pushint(st,map[m].flag.nomineeffect); break; - case MF_NOLOCKON: script_pushint(st,map[m].flag.nolockon); break; - case MF_NOTOMB: script_pushint(st,map[m].flag.notomb); break; - case MF_NOCOSTUME: script_pushint(st,map[m].flag.nocostume); break; - case MF_GVG_TE_CASTLE: script_pushint(st,map[m].flag.gvg_te_castle); break; - case MF_GVG_TE: script_pushint(st,map[m].flag.gvg_te); break; - case MF_HIDEMOBHPBAR: script_pushint(st,map[m].flag.hidemobhpbar); break; -#ifdef ADJUST_SKILL_DAMAGE - case MF_SKILL_DAMAGE: - { - int ret_val=0, type=0; - FETCH(4,type); - switch (type) { - case 1: ret_val = map[m].adjust.damage.pc; break; - case 2: ret_val = map[m].adjust.damage.mob; break; - case 3: ret_val = map[m].adjust.damage.boss; break; - case 4: ret_val = map[m].adjust.damage.other; break; - case 5: ret_val = map[m].adjust.damage.caster; break; - default: ret_val = map[m].flag.skill_damage; break; - } - script_pushint(st,ret_val); break; - } break; -#endif - } + if (m < 0) { + ShowWarning("buildin_getmapflag: Invalid map name %s.\n", str); + return SCRIPT_CMD_FAILURE; } - return SCRIPT_CMD_SUCCESS; -} -/* pvp timer handling */ -static int script_mapflag_pvp_sub(struct block_list *bl,va_list ap) { - TBL_PC* sd = (TBL_PC*)bl; - if (sd->pvp_timer == INVALID_TIMER) { - sd->pvp_timer = add_timer(gettick() + 200, pc_calc_pvprank_timer, sd->bl.id, 0); - sd->pvp_rank = 0; - sd->pvp_lastusers = 0; - sd->pvp_point = 5; - sd->pvp_won = 0; - sd->pvp_lost = 0; + mf = script_getnum(st, 3); + + if( mf < MF_MIN || mf > MF_MAX ){ + ShowError( "buildin_getmapflag: Unsupported mapflag '%d'.\n", mf ); + return SCRIPT_CMD_FAILURE; } - clif_map_property(&sd->bl, MAPPROPERTY_FREEPVPZONE,SELF); - return 0; + +#ifdef ADJUST_SKILL_DAMAGE + FETCH(4, args.flag_val); +#endif + + script_pushint(st, map_getmapflag_sub(m, static_cast(mf), &args)); + + return SCRIPT_CMD_SUCCESS; } BUILDIN_FUNC(setmapflag) { - int16 m,i; + int16 m; + int mf; const char *str; - int val=0; + union u_mapflag_args args = {}; + + str = script_getstr(st,2); - str=script_getstr(st,2); - i=script_getnum(st,3); - FETCH(4,val); m = map_mapname2mapid(str); - if(m >= 0) { - switch(i) { - case MF_NOMEMO: map[m].flag.nomemo = 1; break; - case MF_NOTELEPORT: map[m].flag.noteleport = 1; break; - case MF_NOSAVE: map[m].flag.nosave = 1; break; - case MF_NOBRANCH: map[m].flag.nobranch = 1; break; - case MF_NOPENALTY: map[m].flag.noexppenalty = 1; map[m].flag.nozenypenalty = 1; break; - case MF_NOZENYPENALTY: map[m].flag.nozenypenalty = 1; break; - case MF_PVP: - map[m].flag.pvp = 1; - if( !battle_config.pk_mode ) { - map_foreachinmap(script_mapflag_pvp_sub,m,BL_PC); - } - break; - case MF_PVP_NOPARTY: map[m].flag.pvp_noparty = 1; break; - case MF_PVP_NOGUILD: map[m].flag.pvp_noguild = 1; break; - case MF_GVG: - map[m].flag.gvg = 1; - clif_map_property_mapall(m, MAPPROPERTY_AGITZONE); - break; - case MF_GVG_NOPARTY: map[m].flag.gvg_noparty = 1; break; - case MF_NOTRADE: map[m].flag.notrade = 1; break; - case MF_NOSKILL: map[m].flag.noskill = 1; break; - case MF_NOWARP: map[m].flag.nowarp = 1; break; - case MF_PARTYLOCK: map[m].flag.partylock = 1; break; - case MF_NOICEWALL: map[m].flag.noicewall = 1; break; - case MF_SNOW: map[m].flag.snow = 1; break; - case MF_FOG: map[m].flag.fog = 1; break; - case MF_SAKURA: map[m].flag.sakura = 1; break; - case MF_LEAVES: map[m].flag.leaves = 1; break; - case MF_NOGO: map[m].flag.nogo = 1; break; - case MF_CLOUDS: map[m].flag.clouds = 1; break; - case MF_CLOUDS2: map[m].flag.clouds2 = 1; break; - case MF_FIREWORKS: map[m].flag.fireworks = 1; break; - case MF_GVG_CASTLE: map[m].flag.gvg_castle = 1; break; - case MF_GVG_DUNGEON: map[m].flag.gvg_dungeon = 1; break; - case MF_NIGHTENABLED: map[m].flag.nightenabled = 1; break; - case MF_NOBASEEXP: map[m].flag.nobaseexp = 1; break; - case MF_NOJOBEXP: map[m].flag.nojobexp = 1; break; - case MF_NOMOBLOOT: map[m].flag.nomobloot = 1; break; - case MF_NOMVPLOOT: map[m].flag.nomvploot = 1; break; - 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; - break; - case MF_NOCOMMAND: map[m].nocommand = (val <= 0) ? 100 : val; break; - case MF_NODROP: map[m].flag.nodrop = 1; break; - case MF_JEXP: map[m].adjust.jexp = (val <= 0) ? 100 : val; break; - case MF_BEXP: map[m].adjust.bexp = (val <= 0) ? 100 : val; break; - case MF_NOVENDING: map[m].flag.novending = 1; break; - case MF_LOADEVENT: map[m].flag.loadevent = 1; break; - case MF_NOCHAT: map[m].flag.nochat = 1; break; - case MF_NOEXPPENALTY: map[m].flag.noexppenalty = 1; break; - case MF_GUILDLOCK: map[m].flag.guildlock = 1; break; - case MF_TOWN: map[m].flag.town = 1; break; - case MF_AUTOTRADE: map[m].flag.autotrade = 1; break; - case MF_ALLOWKS: map[m].flag.allowks = 1; break; - case MF_MONSTER_NOTELEPORT: map[m].flag.monster_noteleport = 1; break; - case MF_PVP_NOCALCRANK: map[m].flag.pvp_nocalcrank = 1; break; - case MF_BATTLEGROUND: map[m].flag.battleground = (val <= 0 || val > 2) ? 1 : val; break; - case MF_RESET: map[m].flag.reset = 1; break; - case MF_CHANNELAUTOJOIN: map[m].flag.chmautojoin = 1 ; break; - case MF_NOUSECART: map[m].flag.nousecart = 1 ; break; - case MF_NOITEMCONSUMPTION: map[m].flag.noitemconsumption = 1 ; break; - case MF_SUMSTARTMIRACLE: map[m].flag.nosumstarmiracle = 1 ; break; - case MF_NOMINEEFFECT: map[m].flag.nomineeffect = 1 ; break; - case MF_NOLOCKON: map[m].flag.nolockon = 1 ; break; - case MF_NOTOMB: map[m].flag.notomb = 1; break; - case MF_NOCOSTUME: map[m].flag.nocostume = 1; break; - case MF_GVG_TE_CASTLE: map[m].flag.gvg_te_castle = 1; break; - case MF_GVG_TE: - map[m].flag.gvg_te = 1; - clif_map_property_mapall(m, MAPPROPERTY_AGITZONE); - break; - case MF_HIDEMOBHPBAR: map[m].flag.hidemobhpbar = 1; break; -#ifdef ADJUST_SKILL_DAMAGE - case MF_SKILL_DAMAGE: - { - int type=0; - FETCH(5,type); - switch (type) { - case 1: map[m].adjust.damage.pc = val; break; - case 2: map[m].adjust.damage.mob = val; break; - case 3: map[m].adjust.damage.boss = val; break; - case 4: map[m].adjust.damage.other = val; break; - case 5: map[m].adjust.damage.caster = val; break; - } - map[m].flag.skill_damage = 1; - } break; -#endif - } + if (m < 0) { + ShowWarning("buildin_setmapflag: Invalid map name %s.\n", str); + return SCRIPT_CMD_FAILURE; } + + mf = script_getnum(st, 3); + + if( mf < MF_MIN || mf > MF_MAX ){ + ShowError( "buildin_setmapflag: Unsupported mapflag '%d'.\n", mf ); + return SCRIPT_CMD_FAILURE; + } + + if( mf == MF_SKILL_DAMAGE ){ + ShowError( "buildin_setmapflag: Skill damage adjust is not supported. Please use setmapflagskilldmg.\n" ); + return SCRIPT_CMD_FAILURE; + } + + FETCH(4, args.flag_val); + + map_setmapflag_sub(m, static_cast(mf), true, &args); + return SCRIPT_CMD_SUCCESS; } BUILDIN_FUNC(removemapflag) { - int16 m,i; + int16 m; + int mf; const char *str; - int val=0; + union u_mapflag_args args = {}; + + str = script_getstr(st, 2); - str=script_getstr(st,2); - i=script_getnum(st,3); - FETCH(4,val); m = map_mapname2mapid(str); - if(m >= 0) { - switch(i) { - case MF_NOMEMO: map[m].flag.nomemo = 0; break; - case MF_NOTELEPORT: map[m].flag.noteleport = 0; break; - case MF_NOSAVE: map[m].flag.nosave = 0; break; - case MF_NOBRANCH: map[m].flag.nobranch = 0; break; - case MF_NOPENALTY: map[m].flag.noexppenalty = 0; map[m].flag.nozenypenalty = 0; break; - case MF_NOZENYPENALTY: map[m].flag.nozenypenalty = 0; break; - case MF_PVP: - map[m].flag.pvp = 0; - clif_map_property_mapall(m, MAPPROPERTY_NOTHING); - break; - case MF_PVP_NOPARTY: map[m].flag.pvp_noparty = 0; break; - case MF_PVP_NOGUILD: map[m].flag.pvp_noguild = 0; break; - case MF_GVG: - map[m].flag.gvg = 0; - clif_map_property_mapall(m, MAPPROPERTY_NOTHING); - break; - case MF_GVG_NOPARTY: map[m].flag.gvg_noparty = 0; break; - case MF_NOTRADE: map[m].flag.notrade = 0; break; - case MF_NOSKILL: map[m].flag.noskill = 0; break; - case MF_NOWARP: map[m].flag.nowarp = 0; break; - case MF_PARTYLOCK: map[m].flag.partylock = 0; break; - case MF_NOICEWALL: map[m].flag.noicewall = 0; break; - case MF_SNOW: map[m].flag.snow = 0; break; - 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; - 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; - case MF_FIREWORKS: map[m].flag.fireworks = 0; break; - case MF_GVG_CASTLE: map[m].flag.gvg_castle = 0; break; - case MF_GVG_DUNGEON: map[m].flag.gvg_dungeon = 0; break; - case MF_NIGHTENABLED: map[m].flag.nightenabled = 0; break; - case MF_NOBASEEXP: map[m].flag.nobaseexp = 0; break; - case MF_NOJOBEXP: map[m].flag.nojobexp = 0; break; - case MF_NOMOBLOOT: map[m].flag.nomobloot = 0; break; - case MF_NOMVPLOOT: map[m].flag.nomvploot = 0; break; - 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; - } - break; - case MF_NOCOMMAND: map[m].nocommand = 0; break; - case MF_NODROP: map[m].flag.nodrop = 0; break; - case MF_JEXP: map[m].adjust.jexp = 0; break; - case MF_BEXP: map[m].adjust.bexp = 0; break; - case MF_NOVENDING: map[m].flag.novending = 0; break; - case MF_LOADEVENT: map[m].flag.loadevent = 0; break; - case MF_NOCHAT: map[m].flag.nochat = 0; break; - case MF_NOEXPPENALTY: map[m].flag.noexppenalty = 0; break; - case MF_GUILDLOCK: map[m].flag.guildlock = 0; break; - case MF_TOWN: map[m].flag.town = 0; break; - case MF_AUTOTRADE: map[m].flag.autotrade = 0; break; - case MF_ALLOWKS: map[m].flag.allowks = 0; break; - case MF_MONSTER_NOTELEPORT: map[m].flag.monster_noteleport = 0; break; - case MF_PVP_NOCALCRANK: map[m].flag.pvp_nocalcrank = 0; break; - case MF_BATTLEGROUND: map[m].flag.battleground = 0; break; - case MF_RESET: map[m].flag.reset = 0; break; - case MF_CHANNELAUTOJOIN: map[m].flag.chmautojoin = 0 ; break; - case MF_NOUSECART: map[m].flag.nousecart = 0 ; break; - case MF_NOITEMCONSUMPTION: map[m].flag.noitemconsumption = 0 ; break; - case MF_SUMSTARTMIRACLE: map[m].flag.nosumstarmiracle = 0 ; break; - case MF_NOMINEEFFECT: map[m].flag.nomineeffect = 0 ; break; - case MF_NOLOCKON: map[m].flag.nolockon = 0 ; break; - case MF_NOTOMB: map[m].flag.notomb = 0; break; - case MF_NOCOSTUME: map[m].flag.nocostume = 0; break; - case MF_GVG_TE_CASTLE: map[m].flag.gvg_te_castle = 0; break; - case MF_GVG_TE: - map[m].flag.gvg_te = 0; - clif_map_property_mapall(m, MAPPROPERTY_NOTHING); - break; - case MF_HIDEMOBHPBAR: map[m].flag.hidemobhpbar = 0; break; -#ifdef ADJUST_SKILL_DAMAGE - case MF_SKILL_DAMAGE: - { - map[m].flag.skill_damage = 0; - memset(&map[m].adjust.damage, 0, sizeof(map[m].adjust.damage)); - if (map[m].skill_damage.count) - map_skill_damage_free(&map[m]); - } break; -#endif - } + if (m < 0) { + ShowWarning("buildin_removemapflag: Invalid map name %s.\n", str); + return SCRIPT_CMD_FAILURE; } + + mf = script_getnum(st, 3); + + if( mf < MF_MIN || mf > MF_MAX ){ + ShowError( "buildin_removemapflag: Unsupported mapflag '%d'.\n", mf ); + return SCRIPT_CMD_FAILURE; + } + + FETCH(4, args.flag_val); + + map_setmapflag_sub(m, static_cast(mf), false, &args); + return SCRIPT_CMD_SUCCESS; } @@ -12606,10 +12348,10 @@ BUILDIN_FUNC(pvpon) str = script_getstr(st,2); m = map_mapname2mapid(str); - if( m < 0 || map[m].flag.pvp ) + if( m < 0 || map_getmapflag(m, MF_PVP) ) return SCRIPT_CMD_SUCCESS; // nothing to do - map[m].flag.pvp = 1; + map_setmapflag(m, MF_PVP, true); clif_map_property_mapall(m, MAPPROPERTY_FREEPVPZONE); if(battle_config.pk_mode) // disable ranking functions if pk_mode is on [Valaris] @@ -12650,10 +12392,10 @@ BUILDIN_FUNC(pvpoff) str=script_getstr(st,2); m = map_mapname2mapid(str); - if(m < 0 || !map[m].flag.pvp) + if(m < 0 || !map_getmapflag(m, MF_PVP)) return SCRIPT_CMD_SUCCESS; //fixed Lupus - map[m].flag.pvp = 0; + map_setmapflag(m, MF_PVP, false); clif_map_property_mapall(m, MAPPROPERTY_NOTHING); if(battle_config.pk_mode) // disable ranking options if pk_mode is on [Valaris] @@ -12670,8 +12412,8 @@ BUILDIN_FUNC(gvgon) str=script_getstr(st,2); m = map_mapname2mapid(str); - if(m >= 0 && !map[m].flag.gvg) { - map[m].flag.gvg = 1; + if(m >= 0 && !map_getmapflag(m, MF_GVG)) { + map_setmapflag(m, MF_GVG, true); clif_map_property_mapall(m, MAPPROPERTY_AGITZONE); } return SCRIPT_CMD_SUCCESS; @@ -12684,8 +12426,8 @@ BUILDIN_FUNC(gvgoff) str=script_getstr(st,2); m = map_mapname2mapid(str); - if(m >= 0 && map[m].flag.gvg) { - map[m].flag.gvg = 0; + if(m >= 0 && map_getmapflag(m, MF_GVG)) { + map_setmapflag(m, MF_GVG, false); clif_map_property_mapall(m, MAPPROPERTY_NOTHING); } return SCRIPT_CMD_SUCCESS; @@ -12698,8 +12440,8 @@ BUILDIN_FUNC(gvgon3) str = script_getstr(st,2); m = map_mapname2mapid(str); - if (m >= 0 && !map[m].flag.gvg_te) { - map[m].flag.gvg_te = 1; + if (m >= 0 && !map_getmapflag(m, MF_GVG_TE)) { + map_setmapflag(m, MF_GVG_TE, true); clif_map_property_mapall(m, MAPPROPERTY_AGITZONE); } return SCRIPT_CMD_SUCCESS; @@ -12712,8 +12454,8 @@ BUILDIN_FUNC(gvgoff3) str = script_getstr(st,2); m = map_mapname2mapid(str); - if (m >= 0 && map[m].flag.gvg_te) { - map[m].flag.gvg_te = 0; + if (m >= 0 && map_getmapflag(m, MF_GVG_TE)) { + map_setmapflag(m, MF_GVG_TE, false); clif_map_property_mapall(m, MAPPROPERTY_NOTHING); } return SCRIPT_CMD_SUCCESS; diff --git a/src/map/script.hpp b/src/map/script.hpp index dee1c32457..b204738a93 100644 --- a/src/map/script.hpp +++ b/src/map/script.hpp @@ -1942,6 +1942,7 @@ struct DBMap* script_get_label_db(void); struct DBMap* script_get_userfunc_db(void); void script_run_autobonus(const char *autobonus, struct map_session_data *sd, unsigned int pos); +const char* script_get_constant_str(const char* prefix, int64 value); bool script_get_parameter(const char* name, int* value); bool script_get_constant(const char* name, int* value); void script_set_constant(const char* name, int value, bool isparameter, bool deprecated); diff --git a/src/map/script_constants.hpp b/src/map/script_constants.hpp index d91b939e30..939aea5fe4 100644 --- a/src/map/script_constants.hpp +++ b/src/map/script_constants.hpp @@ -419,7 +419,8 @@ export_constant(MF_NOMVPLOOT); export_constant(MF_NORETURN); export_constant(MF_NOWARPTO); - export_constant(MF_NIGHTMAREDROP); + export_constant(MF_PVP_NIGHTMAREDROP); + script_set_constant("mf_nightmaredrop",MF_PVP_NIGHTMAREDROP,false,true); export_constant(MF_RESTRICTED); export_constant(MF_NOCOMMAND); export_constant(MF_NODROP); @@ -437,12 +438,11 @@ export_constant(MF_PVP_NOCALCRANK); export_constant(MF_BATTLEGROUND); export_constant(MF_RESET); - // TODO: Check why it is called differently on source and const - //export_constant(MF_CHANNELAUTOJOIN); - export_constant2("mf_nomapchannelautojoin",MF_CHANNELAUTOJOIN); + export_constant(MF_NOMAPCHANNELAUTOJOIN); export_constant(MF_NOUSECART); export_constant(MF_NOITEMCONSUMPTION); - export_constant(MF_SUMSTARTMIRACLE); + export_constant(MF_NOSUNMOONSTARMIRACLE); + script_set_constant("mf_sumstarmiracle",MF_NOSUNMOONSTARMIRACLE,false,true); export_constant(MF_NOMINEEFFECT); export_constant(MF_NOLOCKON); export_constant(MF_NOTOMB); @@ -451,6 +451,8 @@ export_constant(MF_GVG_TE_CASTLE); export_constant(MF_GVG_TE); export_constant(MF_HIDEMOBHPBAR); + export_constant(MF_NOLOOT); + export_constant(MF_NOEXP); /* setcell types */ export_constant(CELL_WALKABLE); @@ -7259,6 +7261,14 @@ export_constant(GSTORAGE_NO_STORAGE); export_constant(GSTORAGE_NO_PERMISSION); + /* block list types */ + export_constant(BL_PC); + export_constant(BL_MOB); + export_constant(BL_PET); + export_constant(BL_HOM); + export_constant(BL_MER); + export_constant(BL_ELEM); + #undef export_constant #undef export_constant2 #undef export_parameter diff --git a/src/map/skill.cpp b/src/map/skill.cpp index e22b2f7301..8c0595d070 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -668,7 +668,7 @@ bool skill_isNotOk(uint16 skill_id, struct map_session_data *sd) if (skill_id == AL_TELEPORT && sd->skillitem == skill_id && sd->skillitemlv > 2) return false; // Teleport lv 3 bypasses this check.[Inkfish] - if (map[m].flag.noskill) + if (map_getmapflag(m, MF_NOSKILL)) return true; // Epoque: @@ -696,11 +696,11 @@ bool skill_isNotOk(uint16 skill_id, struct map_session_data *sd) skill_nocast = skill_get_nocast(skill_id); // Check skill restrictions [Celest] if( (!map_flag_vs2(m) && skill_nocast&1) || - (map[m].flag.pvp && skill_nocast&2) || + (map_getmapflag(m, MF_PVP) && skill_nocast&2) || (map_flag_gvg2_no_te(m) && skill_nocast&4) || - (map[m].flag.battleground && skill_nocast&8) || + (map_getmapflag(m, MF_BATTLEGROUND) && skill_nocast&8) || (map_flag_gvg2_te(m) && skill_nocast&16) || // WOE:TE - (map[m].flag.restricted && map[m].zone && skill_nocast&(8*map[m].zone)) ){ + (map_getmapflag(m, MF_RESTRICTED) && map[m].zone && skill_nocast&(8*map[m].zone)) ){ clif_msg(sd, SKILL_CANT_USE_AREA); // This skill cannot be used within this area return true; } @@ -713,7 +713,7 @@ bool skill_isNotOk(uint16 skill_id, struct map_session_data *sd) case RETURN_TO_ELDICASTES: case ALL_GUARDIAN_RECALL: case ECLAGE_RECALL: - if(map[m].flag.nowarp) { + if(map_getmapflag(m, MF_NOWARP)) { clif_skill_teleportmessage(sd,0); return true; } @@ -723,7 +723,7 @@ bool skill_isNotOk(uint16 skill_id, struct map_session_data *sd) case SC_DIMENSIONDOOR: case ALL_ODINS_RECALL: case WE_CALLALLFAMILY: - if(map[m].flag.noteleport) { + if(map_getmapflag(m, MF_NOTELEPORT)) { clif_skill_teleportmessage(sd,0); return true; } @@ -731,14 +731,14 @@ bool skill_isNotOk(uint16 skill_id, struct map_session_data *sd) case WE_CALLPARTNER: case WE_CALLPARENT: case WE_CALLBABY: - if (map[m].flag.nomemo) { + if (map_getmapflag(m, MF_NOMEMO)) { clif_skill_teleportmessage(sd,1); return true; } break; case MC_VENDING: case ALL_BUYING_STORE: - if( map[sd->bl.m].flag.novending ) { + if( map_getmapflag(sd->bl.m, MF_NOVENDING) ) { clif_displaymessage (sd->fd, msg_txt(sd,276)); // "You can't open a shop on this map" clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return true; @@ -760,7 +760,7 @@ bool skill_isNotOk(uint16 skill_id, struct map_session_data *sd) return false; // always allowed case WZ_ICEWALL: // noicewall flag [Valaris] - if (map[m].flag.noicewall) { + if (map_getmapflag(m, MF_NOICEWALL)) { clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return true; } @@ -776,7 +776,7 @@ bool skill_isNotOk(uint16 skill_id, struct map_session_data *sd) if ( !(battle_config.emergency_call&((is_agit_start())?2:1)) || !(battle_config.emergency_call&(map_flag_gvg2(m)?8:4)) || - (battle_config.emergency_call&16 && map[m].flag.nowarpto && !(map[m].flag.gvg_castle || map[m].flag.gvg_te_castle)) + (battle_config.emergency_call&16 && map_getmapflag(m, MF_NOWARPTO) && !(map_getmapflag(m, MF_GVG_CASTLE) || map_getmapflag(m, MF_GVG_TE_CASTLE))) ) { clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); return true; @@ -2371,7 +2371,7 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list * } if(sd && (sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR && - map[sd->bl.m].flag.nosumstarmiracle == 0) //SG_MIRACLE [Komurka] + map_getmapflag(sd->bl.m, MF_NOSUNMOONSTARMIRACLE) == 0) //SG_MIRACLE [Komurka] status_change_start(src,src,SC_MIRACLE,battle_config.sg_miracle_skill_ratio,1,0,0,0,battle_config.sg_miracle_skill_duration,SCSTART_NONE); if(sd && skill_id && attack_type&BF_MAGIC && status_isdead(bl) && @@ -4857,7 +4857,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint else y = 0; // Ashura Strike still has slide effect in GVG - if ((mbl == src || (!map_flag_gvg2(src->m) && !map[src->m].flag.battleground)) && + if ((mbl == src || (!map_flag_gvg2(src->m) && !map_getmapflag(src->m, MF_BATTLEGROUND))) && unit_movepos(src, mbl->x + x, mbl->y + y, 1, 1)) { clif_blown(src); clif_spiritball(src); @@ -5354,7 +5354,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint sc_start(src,src,SC_HIDING,100,skill_lv,skill_get_time(skill_id,skill_lv)); break; case NJ_KIRIKAGE: - if( !map_flag_gvg2(src->m) && !map[src->m].flag.battleground ) + if( !map_flag_gvg2(src->m) && !map_getmapflag(src->m, MF_BATTLEGROUND) ) { //You don't move on GVG grounds. short x, y; map_search_freecell(bl, 0, &x, &y, 1, 1, 0); @@ -6209,7 +6209,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; } skill_area_temp[0] = battle_config.exp_cost_redemptio_limit - skill_area_temp[0]; // The actual penalty... - if (skill_area_temp[0] > 0 && !map[src->m].flag.noexppenalty && battle_config.exp_cost_redemptio) { //Apply penalty + if (skill_area_temp[0] > 0 && !map_getmapflag(src->m, MF_NOEXPPENALTY) && battle_config.exp_cost_redemptio) { //Apply penalty //If total penalty is 1% => reduced 0.2% penalty per each revived player pc_lostexp(sd, u32min(sd->status.base_exp, (pc_nextbaseexp(sd) * skill_area_temp[0] * battle_config.exp_cost_redemptio / battle_config.exp_cost_redemptio_limit) / 100), 0); } @@ -6223,7 +6223,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; case ALL_RESURRECTION: - if(sd && (map_flag_gvg2(bl->m) || map[bl->m].flag.battleground)) + if(sd && (map_flag_gvg2(bl->m) || map_getmapflag(bl->m, MF_BATTLEGROUND))) { //No reviving in WoE grounds! clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0); break; @@ -6237,7 +6237,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; } - if (map[bl->m].flag.pvp && dstsd && dstsd->pvp_point < 0) + if (map_getmapflag(bl->m, MF_PVP) && dstsd && dstsd->pvp_point < 0) break; switch(skill_lv){ @@ -7505,7 +7505,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case ALL_ODINS_RECALL: if(sd) { - if (map[bl->m].flag.noteleport && skill_lv <= 2) { + if (map_getmapflag(bl->m, MF_NOTELEPORT) && skill_lv <= 2) { clif_skill_teleportmessage(sd,0); break; } @@ -7974,8 +7974,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui int x,y, dir = unit_getdir(src); //Fails on noteleport maps, except for GvG and BG maps [Skotlex] - if( map[src->m].flag.noteleport && - !(map[src->m].flag.battleground || map_flag_gvg2(src->m) ) + if( map_getmapflag(src->m, MF_NOTELEPORT) && + !(map_getmapflag(src->m, MF_BATTLEGROUND) || map_flag_gvg2(src->m) ) ) { x = src->x; y = src->y; @@ -8359,7 +8359,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui map_freeblock_unlock(); return 1; } - if ((map_flag_gvg2(bl->m) || map[bl->m].flag.battleground)) { // No reviving in WoE grounds! + if (map_flag_gvg2(bl->m) || map_getmapflag(bl->m, MF_BATTLEGROUND)) { // No reviving in WoE grounds! clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0); break; } @@ -8370,7 +8370,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; if (tsc && tsc->data[SC_HELLPOWER]) break; - if (map[bl->m].flag.pvp && dstsd->pvp_point < 0) + if (map_getmapflag(bl->m, MF_PVP) && dstsd->pvp_point < 0) break; if (dstsd->special_state.restart_full_recover) per = sper = 100; @@ -8812,7 +8812,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui if (j > 8) j = 0; if ((dstsd = g->member[i].sd) != NULL && sd != dstsd && !dstsd->state.autotrade && !pc_isdead(dstsd)) { - if (map[dstsd->bl.m].flag.nowarp && !map_flag_gvg2(dstsd->bl.m)) + if (map_getmapflag(dstsd->bl.m, MF_NOWARP) && !map_flag_gvg2(dstsd->bl.m)) continue; if (!pc_job_can_entermap((enum e_job)dstsd->status.class_, src->m, dstsd->group_level)) continue; @@ -9916,7 +9916,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui break; case LG_INSPIRATION: - if( sd && !map[sd->bl.m].flag.noexppenalty && battle_config.exp_cost_inspiration ) + if( sd && !map_getmapflag(sd->bl.m, MF_NOEXPPENALTY) && battle_config.exp_cost_inspiration ) pc_lostexp(sd, u32min(sd->status.base_exp, pc_nextbaseexp(sd) * battle_config.exp_cost_inspiration / 100), 0); // 1% penalty. clif_skill_nodamage(bl,src,skill_id,skill_lv, sc_start(src,bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv))); break; @@ -12368,7 +12368,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui uint8 dir = map_calc_dir(src, x, y); // Fails on noteleport maps, except for GvG and BG maps - if (map[src->m].flag.noteleport && !(map[src->m].flag.battleground || map_flag_gvg2(src->m))) { + if (map_getmapflag(src->m, MF_NOTELEPORT) && !(map_getmapflag(src->m, MF_BATTLEGROUND) || map_flag_gvg2(src->m))) { x = src->x; y = src->y; } else if (dir%2) { // Diagonal @@ -14078,7 +14078,7 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, uns break; case UNT_DIMENSIONDOOR: - if( tsd && !map[bl->m].flag.noteleport ) + if( tsd && !map_getmapflag(bl->m, MF_NOTELEPORT) ) pc_randomwarp(tsd,CLR_TELEPORT); else if( bl->type == BL_MOB && battle_config.mob_warp&8 ) unit_warp(bl,-1,-1,-1,CLR_TELEPORT); @@ -16681,7 +16681,7 @@ int skill_delayfix(struct block_list *bl, uint16 skill_id, uint16 skill_lv) time /= 2; break; case AS_SONICBLOW: - if (!map_flag_gvg2(bl->m) && !map[bl->m].flag.battleground && sc->data[SC_SPIRIT]->val2 == SL_ASSASIN) + if (!map_flag_gvg2(bl->m) && !map_getmapflag(bl->m, MF_BATTLEGROUND) && sc->data[SC_SPIRIT]->val2 == SL_ASSASIN) time /= 2; break; } @@ -18407,13 +18407,13 @@ static int skill_unit_timer_sub(DBKey key, DBData *data, va_list ap) if(group->val1) { sd = map_charid2sd(group->val1); group->val1 = 0; - if (sd && !map[sd->bl.m].flag.nowarp && pc_job_can_entermap((enum e_job)sd->status.class_, unit->bl.m, sd->group_level)) + if (sd && !map_getmapflag(sd->bl.m, MF_NOWARP) && pc_job_can_entermap((enum e_job)sd->status.class_, unit->bl.m, sd->group_level)) pc_setpos(sd,map_id2index(unit->bl.m),unit->bl.x,unit->bl.y,CLR_TELEPORT); } if(group->val2) { sd = map_charid2sd(group->val2); group->val2 = 0; - if (sd && !map[sd->bl.m].flag.nowarp && pc_job_can_entermap((enum e_job)sd->status.class_, unit->bl.m, sd->group_level)) + if (sd && !map_getmapflag(sd->bl.m, MF_NOWARP) && pc_job_can_entermap((enum e_job)sd->status.class_, unit->bl.m, sd->group_level)) pc_setpos(sd,map_id2index(unit->bl.m),unit->bl.x,unit->bl.y,CLR_TELEPORT); } skill_delunit(unit); @@ -20791,7 +20791,7 @@ static bool skill_check_unit_movepos(uint8 check_flag, struct block_list *bl, sh nullpo_retr(false, bl); - if (check_flag&1 && map[bl->m].flag.battleground) + if (check_flag&1 && map_getmapflag(bl->m, MF_BATTLEGROUND)) return false; if (check_flag&2 && map_flag_gvg(bl->m)) return false; @@ -21475,13 +21475,11 @@ static bool skill_parse_row_skilldamage(char* split[], int columns, int current) memset(&skill_db[id]->damage,0,sizeof(struct s_skill_damage)); skill_db[id]->damage.caster |= atoi(split[1]); skill_db[id]->damage.map |= atoi(split[2]); - skill_db[id]->damage.pc = cap_value(atoi(split[3]),-100,INT_MAX); - if (split[3]) - skill_db[id]->damage.mob = cap_value(atoi(split[4]),-100,INT_MAX); - if (split[4]) - skill_db[id]->damage.boss = cap_value(atoi(split[5]),-100,INT_MAX); - if (split[5]) - skill_db[id]->damage.other = cap_value(atoi(split[6]),-100,INT_MAX); + + for(int offset = 3, int i = 0; i < SKILLDMG_MAX && offset < columns; i++, offset++ ){ + skill_db[id]->damage.rate[i] = cap_value(atoi(split[offset]), -100, INT_MAX); + } + return true; } #endif @@ -21593,7 +21591,7 @@ static void skill_readdb(void) sv_readdb(dbsubpath1, "skill_changematerial_db.txt" , ',', 5, 5+2*MAX_SKILL_CHANGEMATERIAL_SET, MAX_SKILL_CHANGEMATERIAL_DB, skill_parse_row_changematerialdb, i > 0); sv_readdb(dbsubpath1, "skill_nonearnpc_db.txt" , ',', 2, 3, -1, skill_parse_row_nonearnpcrangedb, i > 0); #ifdef ADJUST_SKILL_DAMAGE - sv_readdb(dbsubpath1, "skill_damage_db.txt" , ',', 4, 7, -1, skill_parse_row_skilldamage, i > 0); + sv_readdb(dbsubpath1, "skill_damage_db.txt" , ',', 4, 3+SKILLDMG_MAX, -1, skill_parse_row_skilldamage, i > 0); #endif aFree(dbsubpath1); aFree(dbsubpath2); diff --git a/src/map/skill.hpp b/src/map/skill.hpp index 5af14137dc..7f8a0c3bca 100644 --- a/src/map/skill.hpp +++ b/src/map/skill.hpp @@ -2213,19 +2213,6 @@ void skill_combo(struct block_list* src,struct block_list *dsrc, struct block_li void skill_reveal_trap_inarea(struct block_list *src, int range, int x, int y); -#ifdef ADJUST_SKILL_DAMAGE -/// Skill Damage target -enum e_skill_damage_caster { - SDC_PC = 0x01, - SDC_MOB = 0x02, - SDC_PET = 0x04, - SDC_HOM = 0x08, - SDC_MER = 0x10, - SDC_ELEM = 0x20, - SDC_ALL = SDC_PC|SDC_MOB|SDC_PET|SDC_HOM|SDC_MER|SDC_ELEM, -}; -#endif - /// Variable name of copied skill by Plagiarism #define SKILL_VAR_PLAGIARISM "CLONE_SKILL" /// Variable name of copied skill level by Plagiarism diff --git a/src/map/status.cpp b/src/map/status.cpp index 5b59f0ef2e..9aec61e6bd 100644 --- a/src/map/status.cpp +++ b/src/map/status.cpp @@ -113,7 +113,7 @@ static unsigned int status_calc_maxhpsp_pc(struct map_session_data* sd, unsigned static int status_get_sc_interval(enum sc_type type); static bool status_change_isDisabledOnMap_(sc_type type, bool mapIsVS, bool mapIsPVP, bool mapIsGVG, bool mapIsBG, unsigned int mapZone, bool mapIsTE); -#define status_change_isDisabledOnMap(type, m) ( status_change_isDisabledOnMap_((type), map_flag_vs2((m)), map[(m)].flag.pvp != 0, map_flag_gvg2_no_te((m)), map[(m)].flag.battleground != 0, (map[(m)].zone << 3) != 0, map_flag_gvg2_te((m))) ) +#define status_change_isDisabledOnMap(type, m) ( status_change_isDisabledOnMap_((type), map_flag_vs2((m)), map_getmapflag((m), MF_PVP) != 0, map_flag_gvg2_no_te((m)), map_getmapflag((m), MF_BATTLEGROUND) != 0, (map[(m)].zone << 3) != 0, map_flag_gvg2_te((m))) ) /** * Returns the status change associated with a skill. @@ -1716,7 +1716,7 @@ int status_damage(struct block_list *src,struct block_list *target,int64 dhp, in * Endure count is only reduced by non-players on non-gvg maps. * val4 signals infinite endure. **/ - if (src && src->type != BL_PC && !map_flag_gvg2(target->m) && !map[target->m].flag.battleground && --(sce->val2) <= 0) + if (src && src->type != BL_PC && !map_flag_gvg2(target->m) && !map_getmapflag(target->m, MF_BATTLEGROUND) && --(sce->val2) <= 0) status_change_end(target, SC_ENDURE, INVALID_TIMER); } if ((sce=sc->data[SC_GRAVITATION]) && sce->val3 == BCT_SELF) { @@ -6265,7 +6265,7 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change if( bl->type == BL_PC ) { if( map_flag_gvg(bl->m) ) flee -= flee * battle_config.gvg_flee_penalty/100; - else if( map[bl->m].flag.battleground ) + else if( map_getmapflag(bl->m, MF_BATTLEGROUND) ) flee -= flee * battle_config.bg_flee_penalty/100; } @@ -7153,7 +7153,7 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change * */ static unsigned short status_calc_dmotion(struct block_list *bl, struct status_change *sc, int dmotion) { - if( !sc || !sc->count || map_flag_gvg2(bl->m) || map[bl->m].flag.battleground ) + if( !sc || !sc->count || map_flag_gvg2(bl->m) || map_getmapflag(bl->m, MF_BATTLEGROUND) ) return cap_value(dmotion,0,USHRT_MAX); /// It has been confirmed on official servers that MvP mobs have no dmotion even without endure @@ -9445,7 +9445,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty break; case SC_ENDURE: val2 = 7; // Hit-count [Celest] - if( !(flag&SCSTART_NOAVOID) && (bl->type&(BL_PC|BL_MER)) && !map_flag_gvg2(bl->m) && !map[bl->m].flag.battleground && !val4 ) { + if( !(flag&SCSTART_NOAVOID) && (bl->type&(BL_PC|BL_MER)) && !map_flag_gvg2(bl->m) && !map_getmapflag(bl->m, MF_BATTLEGROUND) && !val4 ) { struct map_session_data *tsd; if( sd ) { int i; @@ -9757,7 +9757,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty if (sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_ROGUE) val3 -= 40; val4 = 10+val1*2; // SP cost. - if (map_flag_gvg2(bl->m) || map[bl->m].flag.battleground) val4 *= 5; + if (map_flag_gvg2(bl->m) || map_getmapflag(bl->m, MF_BATTLEGROUND)) val4 *= 5; break; case SC_CLOAKING: if (!sd) // Monsters should be able to walk with no penalties. [Skotlex] @@ -9952,7 +9952,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty if( (d_bl = map_id2bl(val1)) && (d_sc = status_get_sc(d_bl)) && d_sc->count ) { // Inherits Status From Source const enum sc_type types[] = { SC_AUTOGUARD, SC_DEFENDER, SC_REFLECTSHIELD, SC_ENDURE }; - int i = (map_flag_gvg2(bl->m) || map[bl->m].flag.battleground)?2:3; + int i = (map_flag_gvg2(bl->m) || map_getmapflag(bl->m, MF_BATTLEGROUND))?2:3; while( i >= 0 ) { enum sc_type type2 = types[i]; if( d_sc->data[type2] ) @@ -14351,9 +14351,9 @@ void status_change_clear_onChangeMap(struct block_list *bl, struct status_change if (sc && sc->count) { unsigned short i; bool mapIsVS = map_flag_vs2(bl->m); - bool mapIsPVP = map[bl->m].flag.pvp != 0; + bool mapIsPVP = map_getmapflag(bl->m, MF_PVP) != 0; bool mapIsGVG = map_flag_gvg2_no_te(bl->m); - bool mapIsBG = map[bl->m].flag.battleground != 0; + bool mapIsBG = map_getmapflag(bl->m, MF_BATTLEGROUND) != 0; bool mapIsTE = map_flag_gvg2_te(bl->m); unsigned int mapZone = map[bl->m].zone << 3; diff --git a/src/map/trade.cpp b/src/map/trade.cpp index 2e3e39dd3c..05bc7320d6 100644 --- a/src/map/trade.cpp +++ b/src/map/trade.cpp @@ -32,7 +32,7 @@ void trade_traderequest(struct map_session_data *sd, struct map_session_data *ta { nullpo_retv(sd); - if (map[sd->bl.m].flag.notrade) { + if (map_getmapflag(sd->bl.m, MF_NOTRADE)) { clif_displaymessage (sd->fd, msg_txt(sd,272)); return; //Can't trade in notrade mapflag maps. } diff --git a/src/map/unit.cpp b/src/map/unit.cpp index 9cd9789b36..80b09d5ce0 100644 --- a/src/map/unit.cpp +++ b/src/map/unit.cpp @@ -1138,7 +1138,7 @@ int unit_blown(struct block_list* bl, int dx, int dy, int count, enum e_skill_bl enum e_unit_blown unit_blown_immune(struct block_list* bl, uint8 flag) { if ((flag&0x1) - && (map_flag_gvg2(bl->m) || map[bl->m].flag.battleground) + && (map_flag_gvg2(bl->m) || map_getmapflag(bl->m, MF_BATTLEGROUND)) && ((flag&0x2) || !(battle_config.skill_trap_type&0x1))) return UB_NO_KNOCKBACK_MAP; // No knocking back in WoE / BG @@ -1204,14 +1204,14 @@ int unit_warp(struct block_list *bl,short m,short x,short y,clr_type type) switch (bl->type) { case BL_MOB: - if (map[bl->m].flag.monster_noteleport && ((TBL_MOB*)bl)->master_id == 0) + if (map_getmapflag(bl->m, MF_MONSTER_NOTELEPORT) && ((TBL_MOB*)bl)->master_id == 0) return 1; - if (m != bl->m && map[m].flag.nobranch && battle_config.mob_warp&4 && !(((TBL_MOB *)bl)->master_id)) + if (m != bl->m && map_getmapflag(m, MF_NOBRANCH) && battle_config.mob_warp&4 && !(((TBL_MOB *)bl)->master_id)) return 1; break; case BL_PC: - if (map[bl->m].flag.noteleport) + if (map_getmapflag(bl->m, MF_NOTELEPORT)) return 1; break; } @@ -2706,7 +2706,7 @@ int unit_skillcastcancel(struct block_list *bl, char type) return 0; if (sd && (sd->special_state.no_castcancel2 || - ((sd->sc.data[SC_UNLIMITEDHUMMINGVOICE] || sd->special_state.no_castcancel) && !map_flag_gvg2(bl->m) && !map[bl->m].flag.battleground))) // fixed flags being read the wrong way around [blackhole89] + ((sd->sc.data[SC_UNLIMITEDHUMMINGVOICE] || sd->special_state.no_castcancel) && !map_flag_gvg2(bl->m) && !map_getmapflag(bl->m, MF_BATTLEGROUND)))) // fixed flags being read the wrong way around [blackhole89] return 0; }