Browse Source

Players affected by event is now stored as std::set instead of bitmask

Ivan Savenko 1 năm trước cách đây
mục cha
commit
5523e08cb7

+ 14 - 3
lib/mapping/CMap.cpp

@@ -44,8 +44,7 @@ DisposedHero::DisposedHero() : heroId(0), portrait(255)
 }
 
 CMapEvent::CMapEvent()
-	: players(0)
-	, humanAffected(false)
+	: humanAffected(false)
 	, computerAffected(false)
 	, firstOccurrence(0)
 	, nextOccurrence(0)
@@ -67,7 +66,19 @@ void CMapEvent::serializeJson(JsonSerializeFormat & handler)
 {
 	handler.serializeString("name", name);
 	handler.serializeStruct("message", message);
-	handler.serializeInt("players", players);
+	if (!handler.saving && handler.getCurrent()["players"].isNumber())
+	{
+		// compatibility for old maps
+		int playersMask = 0;
+		handler.serializeInt("players", playersMask);
+		for (int i = 0; i < 8; ++i)
+			if ((playersMask & (1 << i)) != 0)
+				players.insert(PlayerColor(i));
+	}
+	else
+	{
+		handler.serializeIdArray("players", players);
+	}
 	handler.serializeInt("humanAffected", humanAffected);
 	handler.serializeInt("computerAffected", computerAffected);
 	handler.serializeInt("firstOccurrence", firstOccurrence);

+ 13 - 2
lib/mapping/CMapDefines.h

@@ -36,7 +36,7 @@ public:
 	std::string name;
 	MetaString message;
 	TResources resources;
-	ui8 players; // affected players, bit field?
+	std::set<PlayerColor> players;
 	bool humanAffected;
 	bool computerAffected;
 	ui32 firstOccurrence;
@@ -48,7 +48,18 @@ public:
 		h & name;
 		h & message;
 		h & resources;
-		h & players;
+		if (h.version >= Handler::Version::EVENTS_PLAYER_SET)
+		{
+			h & players;
+		}
+		else
+		{
+			ui8 playersMask = 0;
+			h & playersMask;
+			for (int i = 0; i < 8; ++i)
+				if ((playersMask & (1 << i)) != 0)
+					players.insert(PlayerColor(i));
+		}
 		h & humanAffected;
 		h & computerAffected;
 		h & firstOccurrence;

+ 2 - 2
lib/mapping/MapFormatH3M.cpp

@@ -2244,7 +2244,7 @@ CGObjectInstance * CMapLoaderH3M::readTown(const int3 & position, std::shared_pt
 
 		reader->readResources(event.resources);
 
-		event.players = reader->readUInt8();
+		reader->readBitmaskPlayers(event.players, false);
 		if(features.levelSOD)
 			event.humanAffected = reader->readBool();
 		else
@@ -2313,7 +2313,7 @@ void CMapLoaderH3M::readEvents()
 		event.message.appendTextID(readLocalizedString(TextIdentifier("event", eventID, "description")));
 
 		reader->readResources(event.resources);
-		event.players = reader->readUInt8();
+		reader->readBitmaskPlayers(event.players, false);
 		if(features.levelSOD)
 		{
 			event.humanAffected = reader->readBool();

+ 3 - 1
lib/serializer/ESerializationVersion.h

@@ -50,6 +50,7 @@ enum class ESerializationVersion : int32_t
 	BANK_UNIT_PLACEMENT, // 843 Banks have unit placement flag
 
 	RELEASE_152 = BANK_UNIT_PLACEMENT,
+	RELEASE_156 = BANK_UNIT_PLACEMENT,
 
 	COMPACT_STRING_SERIALIZATION, // 844 - optimized serialization of previously encountered strings
 	COMPACT_INTEGER_SERIALIZATION, // 845 - serialize integers in forms similar to protobuf
@@ -61,6 +62,7 @@ enum class ESerializationVersion : int32_t
 	PLAYER_HANDICAP, // 851 - player handicap selection at game start
 	STATISTICS, // 852 - removed random number generators from library classes
 	CAMPAIGN_REGIONS, // 853 - configurable campaign regions
+	EVENTS_PLAYER_SET, // 854 - map & town events use std::set instead of bitmask to store player list
 
-	CURRENT = CAMPAIGN_REGIONS
+	CURRENT = EVENTS_PLAYER_SET
 };

+ 2 - 2
mapeditor/inspector/towneventswidget.cpp

@@ -69,7 +69,7 @@ QVariant toVariant(const CCastleEvent& event)
 	QVariantMap result;
 	result["name"] = QString::fromStdString(event.name);
 	result["message"] = QString::fromStdString(event.message.toString());
-	result["players"] = QVariant::fromValue(event.players);
+	result["players"] = toVariant(event.players);
 	result["humanAffected"] = QVariant::fromValue(event.humanAffected);
 	result["computerAffected"] = QVariant::fromValue(event.computerAffected);
 	result["firstOccurrence"] = QVariant::fromValue(event.firstOccurrence);
@@ -87,7 +87,7 @@ CCastleEvent eventFromVariant(CMapHeader& map, const CGTownInstance& town, const
 	auto v = variant.toMap();
 	result.name = v.value("name").toString().toStdString();
 	result.message.appendTextID(mapRegisterLocalizedString("map", map, TextIdentifier("town", town.instanceName, "event", result.name, "message"), v.value("message").toString().toStdString()));
-	result.players = v.value("players").toInt();
+	result.players = playersFromVariant(v.value("players"));
 	result.humanAffected = v.value("humanAffected").toInt();
 	result.computerAffected = v.value("computerAffected").toInt();
 	result.firstOccurrence = v.value("firstOccurrence").toInt();

+ 20 - 3
mapeditor/mapsettings/eventsettings.cpp

@@ -16,6 +16,24 @@
 #include "../../lib/constants/NumericConstants.h"
 #include "../../lib/constants/StringConstants.h"
 
+QVariant toVariant(const std::set<PlayerColor> & players)
+{
+	QVariantList result;
+	for(auto const id : players)
+		result.push_back(QString::fromStdString(id.toString()));
+	return result;
+}
+
+std::set<PlayerColor> playersFromVariant(const QVariant & v)
+{
+	std::set<PlayerColor> result;
+
+	for(auto const & id : v.toList())
+		result.insert(PlayerColor(PlayerColor::decode(id.toString().toStdString())));
+
+	return result;
+}
+
 QVariant toVariant(const TResources & resources)
 {
 	QVariantMap result;
@@ -30,7 +48,6 @@ TResources resourcesFromVariant(const QVariant & v)
 	for(auto r : v.toMap().keys())
 		vJson[r.toStdString()].Integer() = v.toMap().value(r).toInt();
 	return TResources(vJson);
-
 }
 
 QVariant toVariant(const CMapEvent & event)
@@ -38,7 +55,7 @@ QVariant toVariant(const CMapEvent & event)
 	QVariantMap result;
 	result["name"] = QString::fromStdString(event.name);
 	result["message"] = QString::fromStdString(event.message.toString());
-	result["players"] = QVariant::fromValue(event.players);
+	result["players"] = toVariant(event.players);
 	result["humanAffected"] = QVariant::fromValue(event.humanAffected);
 	result["computerAffected"] = QVariant::fromValue(event.computerAffected);
 	result["firstOccurrence"] = QVariant::fromValue(event.firstOccurrence);
@@ -53,7 +70,7 @@ CMapEvent eventFromVariant(CMapHeader & mapHeader, const QVariant & variant)
 	auto v = variant.toMap();
 	result.name = v.value("name").toString().toStdString();
 	result.message.appendTextID(mapRegisterLocalizedString("map", mapHeader, TextIdentifier("header", "event", result.name, "message"), v.value("message").toString().toStdString()));
-	result.players = v.value("players").toInt();
+	result.players = playersFromVariant(v.value("players"));
 	result.humanAffected = v.value("humanAffected").toInt();
 	result.computerAffected = v.value("computerAffected").toInt();
 	result.firstOccurrence = v.value("firstOccurrence").toInt();

+ 3 - 0
mapeditor/mapsettings/eventsettings.h

@@ -16,7 +16,10 @@ class EventSettings;
 }
 
 QVariant toVariant(const TResources & resources);
+QVariant toVariant(const std::set<PlayerColor> & players);
+
 TResources resourcesFromVariant(const QVariant & v);
+std::set<PlayerColor> playersFromVariant(const QVariant & v);
 
 class EventSettings : public AbstractSettings
 {