Browse Source

Fixes atcommands for PvP and GvG toggle
* Fixes atcommands pvpon, pvpoff, gvgon, and gvgoff to properly toggle the current map with the appropriate zone.
* Atcommand pvpon will assign the MAPTYPE_NOPENALTY_FREEPKZONE zone.
* Atcommand gvgon will assign the MAPTYPE_EVENT_GUILDWAR zone.
* Adds getMapZone() to return a map's zone.
* Adds setZone() to set a map's zone.
Thanks to @Atemo!

aleos 1 year ago
parent
commit
fc3cc3c1c2
3 changed files with 78 additions and 26 deletions
  1. 8 4
      src/map/atcommand.cpp
  2. 65 22
      src/map/map.cpp
  3. 5 0
      src/map/map.hpp

+ 8 - 4
src/map/atcommand.cpp

@@ -1786,7 +1786,8 @@ ACMD_FUNC(pvpoff)
 		return -1;
 	}
 
-	map_setmapflag(sd->bl.m, MF_PVP, false);
+	map_setmapflag(sd->bl.m, MF_PVP, false); // Needed to remove battle and client settings.
+	map_zone_db.setZone(sd->bl.m, map_zone_db.getMapZone(sd->bl.m));
 
 	clif_displaymessage(fd, msg_txt(sd,31)); // PvP: Off.
 	return 0;
@@ -1804,7 +1805,7 @@ ACMD_FUNC(pvpon)
 		return -1;
 	}
 
-	map_setmapflag(sd->bl.m, MF_PVP, true);
+	map_zone_db.setZone(sd->bl.m, MAPTYPE_NOPENALTY_FREEPKZONE);
 
 	clif_displaymessage(fd, msg_txt(sd,32)); // PvP: On.
 
@@ -1823,7 +1824,9 @@ ACMD_FUNC(gvgoff)
 		return -1;
 	}
 
-	map_setmapflag(sd->bl.m, MF_GVG, false);
+	map_setmapflag(sd->bl.m, MF_GVG, false); // Needed to remove battle and client settings.
+	map_zone_db.setZone(sd->bl.m, map_zone_db.getMapZone(sd->bl.m));
+
 	clif_displaymessage(fd, msg_txt(sd,33)); // GvG: Off.
 
 	return 0;
@@ -1841,7 +1844,8 @@ ACMD_FUNC(gvgon)
 		return -1;
 	}
 
-	map_setmapflag(sd->bl.m, MF_GVG, true);
+	map_zone_db.setZone(sd->bl.m, MAPTYPE_EVENT_GUILDWAR);
+
 	clif_displaymessage(fd, msg_txt(sd,34)); // GvG: On.
 
 	return 0;

+ 65 - 22
src/map/map.cpp

@@ -510,26 +510,8 @@ void MapZoneDatabase::loadingFinished() {
 	// This allows for live modifications to the map without affecting the Map Zone DB.
 	for (const auto &zone : map_zone_db) {
 		for (const auto &map : zone.second->maps) {
-			map_data *mapdata = map_getmapdata(map);
-
-			if (mapdata == nullptr)
+			if (map_zone_db.setZone(map, static_cast<e_map_type>(zone.second->id)))
 				continue;
-
-			mapdata->zone = std::make_shared<s_map_zone_data>();
-			mapdata->zone->id = zone.second->id;
-			mapdata->zone->disabled_commands = zone.second->disabled_commands;
-			mapdata->zone->disabled_items = zone.second->disabled_items;
-			mapdata->zone->disabled_skills = zone.second->disabled_skills;
-			mapdata->zone->disabled_statuses = zone.second->disabled_statuses;
-			mapdata->zone->restricted_jobs = zone.second->restricted_jobs;
-
-			// Apply mapflags from Map Zone DB
-			for (const auto &flag : zone.second->mapflags) {
-				char flag_name[50] = {}, empty[1] = {};
-
-				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::loadingFinished");
-			}
 		}
 	}
 
@@ -540,6 +522,70 @@ void MapZoneDatabase::loadingFinished() {
 	}
 }
 
+/**
+ * Get the zone to a map.
+ * @param map_id: Map ID
+ * @return e_map_type on success or MAPTYPE_UNUSED otherwise
+ */
+e_map_type MapZoneDatabase::getMapZone(int16 map_id) {
+	map_data *mapdata = map_getmapdata(map_id);
+
+	if (mapdata == nullptr) {
+		ShowError("MapZoneDatabase::getMapZone: Unknown map ID %d, skipping.\n", map_id);
+		return MAPTYPE_UNUSED;
+	}
+
+	for (const auto &zone : map_zone_db) {
+		if (util::vector_exists(zone.second->maps, map_id))
+			return static_cast<e_map_type>(zone.second->id);
+	}
+
+	return MAPTYPE_UNUSED;
+}
+
+/**
+ * Set the zone to a map.
+ * @param map_id: Map ID
+ * @param zone: Zone to set
+ * @return True on success or false otherwise
+ */
+bool MapZoneDatabase::setZone(int16 map_id, e_map_type zone) {
+	map_data *mapdata = map_getmapdata(map_id);
+
+	if (mapdata == nullptr) {
+		ShowError("MapZoneDatabase::setZone: Unknown map ID %d, skipping.\n", map_id);
+		return false;
+	}
+
+	auto zonedata = map_zone_db.find(zone);
+
+	if (zonedata == nullptr) {
+		ShowError("MapZoneDatabase::setZone: Unknown zone %d, skipping.\n", zone);
+		return false;
+	}
+
+	mapdata->zone = std::make_shared<s_map_zone_data>();
+	mapdata->zone->id = zonedata->id;
+	mapdata->zone->disabled_commands = zonedata->disabled_commands;
+	mapdata->zone->disabled_items = zonedata->disabled_items;
+	mapdata->zone->disabled_skills = zonedata->disabled_skills;
+	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] = {};
+
+		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");
+	}
+
+	return true;
+}
+
 MapZoneDatabase map_zone_db;
 
 /**
@@ -4292,9 +4338,6 @@ int map_readallmaps (void)
 		mapdata->channel = NULL;
 	}
 
-	// intialization and configuration-dependent adjustments of mapflags
-	map_flags_init();
-
 	if( !enable_grf ) {
 		// The cache isn't needed anymore, so free it. [Shinryo]
 		auto it = map_cache_buffer.begin();

+ 5 - 0
src/map/map.hpp

@@ -50,6 +50,7 @@ struct npc_data;
 struct item_data;
 struct Channel;
 enum sc_type : int16;
+enum e_map_type : uint8_t;
 
 struct map_data *map_getmapdata(int16 m);
 #define msg_config_read(cfgName,isnew) map_msg_config_read(cfgName,isnew)
@@ -900,6 +901,10 @@ public:
 	const std::string getDefaultLocation() override;
 	uint64 parseBodyNode(const ryml::NodeRef &node) override;
 	void loadingFinished() override;
+
+	// Others
+	e_map_type getMapZone(int16 map_id);
+	bool setZone(int16 map_id, e_map_type zone);
 };
 
 extern MapZoneDatabase map_zone_db;