Explorar o código

Clean ups from review
Thanks to @Lemongrass3110!

aleos hai 1 ano
pai
achega
477c845027

+ 4 - 0
db/pre-re/map_zones.yml

@@ -860,6 +860,7 @@ Body:
         Value: 60
       - Flag: NoBranch
       - Flag: NoCostume
+      - Flag: NoKnockBack
       - Flag: NoLockOn
       - Flag: NoMemo
       - Flag: NoPenalty
@@ -968,6 +969,7 @@ Body:
       - Flag: Monster_NoTeleport
       - Flag: NoBranch
       - Flag: NoCostume
+      - Flag: NoKnockBack
       - Flag: NoLockOn
       - Flag: NoMemo
       - Flag: NoPenalty
@@ -1019,6 +1021,7 @@ Body:
     Mapflags:
       - Flag: GvG_Dungeon
       - Flag: NoCostume
+      - Flag: NoKnockBack
       - Flag: NoMemo
       - Flag: NoSave
         Value: SavePoint
@@ -1386,6 +1389,7 @@ Body:
       - Flag: Monster_NoTeleport
       - Flag: NoBranch
       - Flag: NoCostume
+      - Flag: NoKnockBack
       - Flag: NoLockOn
       - Flag: NoMemo
       - Flag: NoPenalty

+ 5 - 0
db/re/map_zones.yml

@@ -2107,6 +2107,7 @@ Body:
       - Flag: NoBranch
       - Flag: NoCostume
       - Flag: NoCostume
+      - Flag: NoKnockBack
       - Flag: NoLockOn
       - Flag: NoMemo
       - Flag: NoPenalty
@@ -2284,6 +2285,7 @@ Body:
       - Flag: Monster_NoTeleport
       - Flag: NoBranch
       - Flag: NoCostume
+      - Flag: NoKnockBack
       - Flag: NoLockOn
       - Flag: NoMemo
       - Flag: NoPenalty
@@ -3658,6 +3660,7 @@ Body:
       - Flag: Monster_NoTeleport
       - Flag: NoBranch
       - Flag: NoCostume
+      - Flag: NoKnockBack
       - Flag: NoLockOn
       - Flag: NoMemo
       - Flag: NoPenalty
@@ -3821,6 +3824,7 @@ Body:
         Value: 70
       - Flag: NoBranch
       - Flag: NoCostume
+      - Flag: NoKnockBack
       - Flag: NoLockOn
       - Flag: NoMemo
       - Flag: NoPenalty
@@ -5570,6 +5574,7 @@ Body:
       - Flag: GvG
       - Flag: GvG_NoParty
       - Flag: NoBranch
+      - Flag: NoKnockBack
       - Flag: PvP_NoGuild
       - Flag: PvP_NoParty
 

+ 5 - 0
src/map/atcommand.cpp

@@ -4423,6 +4423,11 @@ ACMD_FUNC(mapinfo) {
 
 	struct map_data *mapdata = map_getmapdata(m_id);
 
+	if (mapdata == nullptr) {
+		clif_displaymessage(fd, msg_txt(sd, 1)); // Map not found.
+		return -1;
+	}
+
 	sprintf(atcmd_output, msg_txt(sd,1040), mapname, script_get_constant_str("MAPTYPE_", mapdata->zone->id), mapdata->users, mapdata->npc_num, chat_num, vend_num); // Map: %s (Zone: %s) | Players: %d | NPCs: %d | Chats: %d | Vendings: %d
 	clif_displaymessage(fd, atcmd_output);
 	clif_displaymessage(fd, msg_txt(sd,1041)); // ------ Map Flags ------

+ 1 - 1
src/map/battle.cpp

@@ -9479,7 +9479,7 @@ int64 battle_calc_return_damage(struct block_list* tbl, struct block_list *src,
 	else if (mapdata->getMapFlag(MF_BATTLEGROUND))
 		rdamage = battle_calc_bg_damage(src, tbl, rdamage, skill_id, flag);
 	else if (battle_config.pk_mode > 0 && mapdata->getMapFlag(MF_PVP))
-			damage = battle_calc_pk_damage(*src, *tbl, damage, skill_id, flag);
+		rdamage = battle_calc_pk_damage(*src, *tbl, rdamage, skill_id, flag);
 
 	// Skill damage adjustment
 	int skill_damage = battle_skill_damage(src, tbl, skill_id);

+ 1 - 1
src/map/clif.cpp

@@ -11138,7 +11138,7 @@ void clif_parse_LoadEndAck(int fd,map_session_data *sd)
 			sd->state.hpmeter_visible = 1;
 		}
 
-		status_change_clear_onChangeMap(&sd->bl);
+		mapdata->zone->clear_all_disabled_status(sd->bl);
 		map_iwall_get(sd); // Updates Walls Info on this Map to Client
 		status_calc_pc(sd, sd->state.autotrade ? SCO_FIRST : SCO_NONE); // Some conditions are map-dependent so we must recalculate
 

+ 78 - 43
src/map/map.cpp

@@ -232,6 +232,7 @@ uint64 MapZoneDatabase::parseBodyNode(const ryml::NodeRef& node) {
 		for (const auto &it : commandNode) {
 			std::string command_name;
 			c4::from_chars(it.key(), &command_name);
+			util::tolower(command_name);
 
 			if (!atcommand_exists(command_name.c_str())) {
 				this->invalidWarning(commandNode, "Atcommand %s does not exist.\n", command_name.c_str());
@@ -248,9 +249,10 @@ uint64 MapZoneDatabase::parseBodyNode(const ryml::NodeRef& node) {
 				group_lv = 100;
 			}
 
-			if (group_lv == 0)
-				zone->disabled_commands.erase(command_name);
-			else
+			if (group_lv == 0) {
+				if (zone->disabled_commands.erase(command_name) == 0)
+					this->invalidWarning(commandNode, "Attempting to remove atcommand %s that is not part of the disabled list.\n", command_name.c_str());
+			} else
 				zone->disabled_commands[command_name] = group_lv;
 		}
 	}
@@ -275,9 +277,6 @@ uint64 MapZoneDatabase::parseBodyNode(const ryml::NodeRef& node) {
 				std::string bl_name;
 				c4::from_chars(subBl.key(), &bl_name);
 
-				if (bl_name.compare("Skill") == 0)
-					continue;
-
 				std::string bl_name_constant = "BL_" + bl_name;
 				int64 type_const;
 
@@ -293,6 +292,9 @@ uint64 MapZoneDatabase::parseBodyNode(const ryml::NodeRef& node) {
 					continue;
 				}
 
+				if (type & BL_SKILL)
+					continue;
+
 				uint16 group_lv;
 
 				if (!this->asUInt16(it, bl_name, group_lv))
@@ -303,17 +305,19 @@ uint64 MapZoneDatabase::parseBodyNode(const ryml::NodeRef& node) {
 					group_lv = 100;
 				}
 
-				if (util::umap_exists(zone->disabled_skills, skill_id)) {
-					if (group_lv > 0)
+				if (group_lv > 0) {
+					if (util::umap_exists(zone->disabled_skills, skill_id)) {
 						zone->disabled_skills[skill_id].first |= type;
-					else {
-						zone->disabled_skills[skill_id].first &= ~type;
+					} else
+						zone->disabled_skills.insert({ skill_id, std::pair<uint16, uint16>(type, group_lv) });
+				} else {
+					zone->disabled_skills[skill_id].first &= ~type;
 
-						if (zone->disabled_skills[skill_id].first == BL_NUL)
-							zone->disabled_skills.erase(skill_id);
+					if (zone->disabled_skills[skill_id].first == BL_NUL) {
+						if (zone->disabled_skills.erase(skill_id) == 0)
+							this->invalidWarning(it, "Attempting to remove skill %s that is not part of the disabled list.\n", skill_name.c_str());
 					}
-				} else if (group_lv > 0)
-					zone->disabled_skills.insert({ skill_id, std::pair<uint16, uint16>(type, group_lv) });
+				}
 			}
 		}
 	}
@@ -341,9 +345,10 @@ uint64 MapZoneDatabase::parseBodyNode(const ryml::NodeRef& node) {
 				group_lv = 100;
 			}
 
-			if (group_lv == 0)
-				zone->disabled_items.erase(item->nameid);
-			else
+			if (group_lv == 0) {
+				if (zone->disabled_items.erase(item->nameid) == 0)
+					this->invalidWarning(itemNode, "Attempting to remove item %s that is not part of the disabled list.\n", item_name.c_str());
+			} else
 				zone->disabled_items[item->nameid] = group_lv;
 		}
 	}
@@ -372,9 +377,10 @@ uint64 MapZoneDatabase::parseBodyNode(const ryml::NodeRef& node) {
 				group_lv = 100;
 			}
 
-			if (group_lv == 0)
-				zone->disabled_statuses.erase(static_cast<sc_type>(status));
-			else
+			if (group_lv == 0) {
+				if (zone->disabled_statuses.erase(static_cast<sc_type>(status)) == 0)
+					this->invalidWarning(statusNode, "Attempting to remove status %s that is not part of the disabled list.\n", status_name.c_str());
+			} else
 				zone->disabled_statuses[static_cast<sc_type>(status)] = group_lv;
 		}
 	}
@@ -403,9 +409,10 @@ uint64 MapZoneDatabase::parseBodyNode(const ryml::NodeRef& node) {
 				group_lv = 100;
 			}
 
-			if (group_lv == 0)
-				zone->restricted_jobs.erase(static_cast<uint32>(job_id));
-			else
+			if (group_lv == 0) {
+				if (zone->restricted_jobs.erase(static_cast<uint32>(job_id)) == 0)
+					this->invalidWarning(jobNode, "Attempting to remove job %s that is not part of the disabled list.\n", job_name.c_str());
+			} else
 				zone->restricted_jobs[static_cast<uint32>(job_id)] = group_lv;
 		}
 	}
@@ -485,10 +492,10 @@ uint64 MapZoneDatabase::parseBodyNode(const ryml::NodeRef& node) {
 				auto mapflagit = zone->mapflags.equal_range(static_cast<int16>(flag));
 
 				// Iterate over the mapflags to get their values
-				for (std::multimap<int16, std::string>::iterator it = mapflagit.first; it != mapflagit.second; ++it) {
+				for (auto flag_it = mapflagit.first; flag_it != mapflagit.second; ++flag_it) {
 					// Compare parse value with what's already in memory
-					if (it->second.find(value) == 0) {
-						zone->mapflags.erase(it);
+					if (flag_it->second.find(value) == 0) {
+						zone->mapflags.erase(flag_it);
 						break;
 					}
 				}
@@ -506,6 +513,9 @@ uint64 MapZoneDatabase::parseBodyNode(const ryml::NodeRef& node) {
  * Initialize Map Zone data
  */
 void MapZoneDatabase::loadingFinished() {
+	// Intialization and configuration-dependent adjustments of mapflags
+	map_flags_init();
+
 	// Copy Map Zone DB data to the map.
 	// This allows for live modifications to the map without affecting the Map Zone DB.
 	for (const auto &zone : map_zone_db) {
@@ -518,6 +528,7 @@ void MapZoneDatabase::loadingFinished() {
 	// Check for maps with no zones
 	for (int i = 0; i < map_num; i++) {
 		if (map[i].zone == nullptr)
+			// TODO: Change to ShowWarning as soon as possible.
 			ShowNotice("MapZoneDatabase::loadingFinished: Map %s has no zone. Assigning a zone is highly encouraged.\n", map[i].name);
 	}
 }
@@ -557,7 +568,7 @@ bool MapZoneDatabase::setZone(int16 map_id, e_map_type zone) {
 		return false;
 	}
 
-	auto zonedata = map_zone_db.find(zone);
+	auto zonedata = this->find(zone);
 
 	if (zonedata == nullptr) {
 		ShowError("MapZoneDatabase::setZone: Unknown zone %d, skipping.\n", zone);
@@ -572,12 +583,9 @@ bool MapZoneDatabase::setZone(int16 map_id, e_map_type zone) {
 	mapdata->zone->disabled_statuses = zonedata->disabled_statuses;
 	mapdata->zone->restricted_jobs = zonedata->restricted_jobs;
 
-	// Intialization and configuration-dependent adjustments of mapflags
-	map_flags_init();
-
 	// Apply mapflags from Map Zone DB
 	for (const auto &flag : zonedata->mapflags) {
-		char flag_name[50] = {}, empty[1] = {};
+		char flag_name[100], *empty = const_cast<char *>("");
 
 		if (map_getmapflag_name(static_cast<e_mapflag>(flag.first), flag_name))
 			npc_parse_mapflag(mapdata->name, empty, flag_name, const_cast<char *>(flag.second.c_str()), empty, empty, "MapZoneDatabase::setZone");
@@ -612,11 +620,10 @@ bool c_map_zone_data::isCommandDisabled(std::string name, map_session_data &sd)
 /**
  * Check if a skill is disabled on a map based on group level.
  * @param skill_id: Skill ID
- * @param type: Object type
- * @param sd: Player session data
+ * @param bl: Block list data
  * @return True when skill is disabled or false otherwise
  */
-bool c_map_zone_data::isSkillDisabled(uint16 skill_id, uint16 type, map_session_data &sd) {
+bool c_map_zone_data::isSkillDisabled(uint16 skill_id, block_list &bl) {
 	if (this->disabled_skills.empty())
 		return false;
 
@@ -625,7 +632,9 @@ bool c_map_zone_data::isSkillDisabled(uint16 skill_id, uint16 type, map_session_
 	if (skill_lv == nullptr)
 		return false;
 
-	if ((!(type & BL_PC) && skill_lv->second > 0) || (skill_lv->second < sd.group->level))
+	map_session_data *sd = BL_CAST(BL_PC, &bl);
+
+	if ((sd == nullptr && skill_lv->second > 0) || (sd != nullptr && skill_lv->second < sd->group->level))
 		return false;
 	else
 		return true;
@@ -655,11 +664,10 @@ bool c_map_zone_data::isItemDisabled(t_itemid nameid, map_session_data &sd) {
 /**
  * Check if a status is disabled on a map based on group level.
  * @param sc: Status type
- * @param type: Object type
- * @param sd: Player session data
+ * @param bl: Block list data
  * @return True when status is disabled or false otherwise
  */
-bool c_map_zone_data::isStatusDisabled(sc_type sc, uint16 type, map_session_data &sd) {
+bool c_map_zone_data::isStatusDisabled(sc_type sc, block_list &bl) {
 	if (this->disabled_statuses.empty())
 		return false;
 
@@ -668,7 +676,9 @@ bool c_map_zone_data::isStatusDisabled(sc_type sc, uint16 type, map_session_data
 	if (status_lv == nullptr)
 		return false;
 
-	if ((!(type & BL_PC) && *status_lv > 0) || (*status_lv < sd.group->level))
+	map_session_data *sd = BL_CAST(BL_PC, &bl);
+
+	if ((sd == nullptr && *status_lv > 0) || (sd != nullptr && *status_lv < sd->group->level))
 		return false;
 	else
 		return true;
@@ -695,6 +705,22 @@ bool c_map_zone_data::isJobRestricted(int32 job_id, uint16 group_lv) {
 		return true;
 }
 
+/**
+ * Clear all statuses that are disabled on a map.
+ * @param bl: Block list data
+ */
+void c_map_zone_data::clear_all_disabled_status(block_list &bl) {
+	if (this->disabled_statuses.empty())
+		return;
+
+	map_session_data *sd = BL_CAST(BL_PC, &bl);
+
+	for (const auto &sc : this->disabled_statuses) {
+		if (sd == nullptr || sd->group->level < sc.second)
+			status_change_end(&bl, sc.first);
+	}
+}
+
 /**
  * Get the map data
  * @param mapid: Map ID to lookup
@@ -4107,6 +4133,7 @@ void map_flags_init(void){
 		args.flag_val = 100;
 
 		// additional mapflag data
+		mapdata->zone = nullptr;
 		mapdata->setMapFlag(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
@@ -4119,10 +4146,6 @@ void map_flags_init(void){
 
 		if (instance_start && i >= instance_start)
 			continue;
-
-		// adjustments
-		//if( battle_config.pk_mode && !mapdata_flag_vs2(mapdata) ) // !TODO: Is this needed now that the PK zone exists?
-		//	mapdata->setMapFlag(MF_PVP, true); // make all maps pvp for pk_mode [Valaris]
 	}
 }
 
@@ -5021,6 +5044,12 @@ int map_getmapflag_sub(int16 m, enum e_mapflag mapflag, union u_mapflag_args *ar
 	}
 
 	switch(mapflag) {
+		case MF_TOWN:
+			ShowWarning("MF_TOWN is not supported anymore. Please utilize the 'Village' map_zone for this mapflag.\n");
+			return -1;
+		case MF_RESTRICTED:
+			ShowWarning("MF_RESTRICTED is not supported anymore. Please utilize the map_zone database for this mapflag.\n");
+			return -1;
 		case MF_NOLOOT:
 			return mapdata->getMapFlag(MF_NOMOBLOOT) && mapdata->getMapFlag(MF_NOMVPLOOT);
 		case MF_NOPENALTY:
@@ -5069,6 +5098,12 @@ bool map_setmapflag_sub(int16 m, enum e_mapflag mapflag, bool status, union u_ma
 	}
 
 	switch(mapflag) {
+		case MF_TOWN:
+			ShowWarning("MF_TOWN is not supported anymore. Please utilize the 'Village' map_zone for this mapflag.\n");
+			return false;
+		case MF_RESTRICTED:
+			ShowWarning("MF_RESTRICTED is not supported anymore. Please utilize the map_zone database for this mapflag.\n");
+			return false;
 		case MF_NOSAVE:
 			if (status) {
 				nullpo_retr(false, args);

+ 6 - 3
src/map/map.hpp

@@ -687,7 +687,9 @@ enum e_mapflag : int16 {
 	MF_NOBONUSITEMDROP,
 	MF_HIDEDAMAGE,
 	MF_FLEE_PENALTY,
-	MF_MAX
+	MF_MAX,
+	MF_RESTRICTED,
+	MF_TOWN,
 };
 
 /// Enum of damage types
@@ -818,10 +820,11 @@ public:
 	std::unordered_map<int32, uint16> restricted_jobs;
 
 	bool isCommandDisabled(std::string name, map_session_data &sd);
-	bool isSkillDisabled(uint16 skill_id, uint16 type, map_session_data &sd);
+	bool isSkillDisabled(uint16 skill_id, block_list &bl);
 	bool isItemDisabled(t_itemid nameid, map_session_data &sd);
-	bool isStatusDisabled(sc_type sc, uint16 type, map_session_data &sd);
+	bool isStatusDisabled(sc_type sc, block_list &bl);
 	bool isJobRestricted(int32 job_id, uint16 group_lv);
+	void clear_all_disabled_status(block_list &bl);
 };
 
 struct map_data {

+ 3 - 0
src/map/mob.cpp

@@ -2643,6 +2643,9 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
 
 	map_data *mapdata = map_getmapdata(m);
 
+	if (mapdata == nullptr)
+		return 3;
+
 	if(!(type&2) && //No exp
 		(!mapdata->getMapFlag(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]

+ 11 - 2
src/map/npc.cpp

@@ -5552,8 +5552,7 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char
 			break;
 		}
 
-		case MF_INVINCIBLE_TIME:
-		case MF_FLEE_PENALTY: {
+		case MF_INVINCIBLE_TIME: {
 				union u_mapflag_args args = {};
 
 				if (sscanf(w4, "%11d", &args.flag_val) < 1)
@@ -5563,6 +5562,16 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char
 			}
 			break;
 
+		case MF_FLEE_PENALTY: {
+				union u_mapflag_args args = {};
+
+				if (sscanf(w4, "%11d", &args.flag_val) < 1)
+					args.flag_val = 20;
+
+				map_setmapflag_sub(m, mapflag, state, &args);
+			}
+			break;
+
 		case MF_WEAPON_DAMAGE_RATE:
 		case MF_MAGIC_DAMAGE_RATE:
 		case MF_MISC_DAMAGE_RATE:

+ 0 - 5
src/map/pc.cpp

@@ -15145,11 +15145,6 @@ void pc_show_questinfo_reinit(map_session_data *sd) {
  * @return True if job is allowed, false otherwise
  **/
 bool pc_job_can_entermap(enum e_job jobid, int m, int group_lv) {
-	// Map is other map server.
-	// !FIXME: Currently, a map-server doesn't recognized map's attributes on other server, so we assume it's fine to warp.
-	if (m < 0)
-		return true;
-
 	if (!pcdb_checkid(jobid))
 		return false;
 

+ 2 - 0
src/map/script_constants.hpp

@@ -546,6 +546,8 @@
 	export_constant(MF_NOBONUSITEMDROP);
 	export_constant(MF_HIDEDAMAGE);
 	export_constant(MF_FLEE_PENALTY);
+	export_deprecated_constant(MF_RESTRICTED);
+	export_deprecated_constant(MF_TOWN);
 
 	/* setcell types */
 	export_constant(CELL_WALKABLE);

+ 1 - 1
src/map/skill.cpp

@@ -866,7 +866,7 @@ bool skill_isNotOk( uint16 skill_id, map_session_data& sd ){
 
 	uint32 skill_nocast = skill_get_nocast(skill_id);
 	// Check skill restrictions [Celest]
-	if (mapdata != nullptr && mapdata->zone->isSkillDisabled(skill_id, BL_PC, sd)) {
+	if (mapdata != nullptr && mapdata->zone->isSkillDisabled(skill_id, sd.bl)) {
 		clif_msg(&sd, SKILL_CANT_USE_AREA); // This skill cannot be used within this area
 		return true;
 	}

+ 3 - 35
src/map/status.cpp

@@ -1960,9 +1960,9 @@ bool status_check_skilluse(struct block_list *src, struct block_list *target, ui
 			return false;
 	} else {
 		map_data *mapdata = map_getmapdata(src->m);
-		map_session_data *sd = (TBL_PC *)src;
+		map_session_data *sd = BL_CAST(BL_PC, src);
 
-		if (mapdata != nullptr && mapdata->zone->isSkillDisabled(skill_id, src->type, *sd )) {
+		if (mapdata != nullptr && mapdata->zone->isSkillDisabled(skill_id, sd->bl)) {
 			if (sd != nullptr)
 				clif_msg(sd, SKILL_CANT_USE_AREA); // This skill cannot be used within this area
 			return false;
@@ -9993,9 +9993,8 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 		return 0;
 
 	map_data *mapdata = map_getmapdata(bl->m);
-	map_session_data *sd = BL_CAST(BL_PC, bl);
 
-	if (mapdata != nullptr && mapdata->zone->isStatusDisabled(type, bl->type, *sd))
+	if (mapdata != nullptr && mapdata->zone->isStatusDisabled(type, *bl))
 		return 0;
 
 	if (sc->getSCE(SC_GRAVITYCONTROL))
@@ -15384,37 +15383,6 @@ TIMER_FUNC(status_clear_lastEffect_timer) {
 	return 0;
 }
 
-/**
- * Clear a status if it is disabled on a map.
- * @param bl: Block list data
- * @param sc: Status Change data
- */
-void status_change_clear_onChangeMap(block_list *bl)
-{
-	nullpo_retv(bl);
-
-	status_change *sc = status_get_sc(bl);
-
-	if (sc && sc->count) {
-		map_data *mapdata = map_getmapdata(bl->m);
-
-		if (mapdata == nullptr)
-			return;
-
-		for (const auto &it : status_db) {
-			sc_type type = static_cast<sc_type>(it.first);
-
-			if (sc->getSCE(type) == nullptr)
-				continue;
-
-			map_session_data *sd = (TBL_PC *)bl;
-
-			if (mapdata->zone->isStatusDisabled(type, bl->type, *sd))
-				status_change_end(bl, type);
-		}
-	}
-}
-
 const std::string AttributeDatabase::getDefaultLocation() {
 	return std::string(db_path) + "/attr_fix.yml";
 }

+ 0 - 1
src/map/status.hpp

@@ -3449,7 +3449,6 @@ TIMER_FUNC(status_change_timer);
 int status_change_timer_sub(struct block_list* bl, va_list ap);
 int status_change_clear(struct block_list* bl, int type);
 void status_change_clear_buffs(struct block_list* bl, uint8 type);
-void status_change_clear_onChangeMap(block_list *bl);
 TIMER_FUNC(status_clear_lastEffect_timer);
 
 #define status_calc_mob(md, opt) status_calc_bl_(&(md)->bl, status_db.getSCB_ALL(), opt)

+ 4 - 5
src/map/unit.cpp

@@ -1232,7 +1232,7 @@ int unit_blown(struct block_list* bl, int dx, int dy, int count, enum e_skill_bl
  *		0x8 - Ignore target player 'special_state.no_knockback'
  * @return reason for immunity
  *		UB_KNOCKABLE - can be knocked back / stopped
- *		UB_NO_KNOCKBACK_MAP - at WOE/BG map
+ *		UB_NO_KNOCKBACK_MAP - on map with mapflag
  *		UB_MD_KNOCKBACK_IMMUNE - target is MD_KNOCKBACK_IMMUNE
  *		UB_TARGET_BASILICA - target is in Basilica area (Pre-Renewal)
  *		UB_TARGET_NO_KNOCKBACK - target has 'special_state.no_knockback'
@@ -1240,12 +1240,11 @@ 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) {
+	if (flag & 0x1 && (flag & 0x2 || !(battle_config.skill_trap_type & 0x1))) {
 		map_data *mapdata = map_getmapdata(bl->m);
 
-		if ((mapdata_flag_gvg2(mapdata) || mapdata->getMapFlag(MF_BATTLEGROUND) || mapdata->getMapFlag(MF_NOKNOCKBACK))
-			&& ((flag&0x2) || !(battle_config.skill_trap_type&0x1)))
-			return UB_NO_KNOCKBACK_MAP; // No knocking back in WoE / BG
+		if (mapdata != nullptr && mapdata->getMapFlag(MF_NOKNOCKBACK))
+			return UB_NO_KNOCKBACK_MAP; // No knocking back on this map.
 	}
 
 	switch (bl->type) {