Browse Source

template editor fixes

Laserlicht 2 weeks ago
parent
commit
3690a032e3

+ 180 - 74
lib/rmg/ObjectConfig.cpp

@@ -61,113 +61,219 @@ void ObjectConfig::serializeJson(JsonSerializeFormat & handler)
 		{ "seerHut", EObjectCategory::SEER_HUT}
 	};
 
-	const JsonNode & config = handler.getCurrent();
-	const JsonNode & configBannedCategories = config["bannedCategories"];
-	const JsonNode & configBannedObjects = config["bannedObjects"];
-	const JsonNode & configCommonObjects = config["commonObjects"];
-
-	for(const auto & node : configBannedCategories.Vector())
+	// Serialize banned categories
+	if (handler.saving)
 	{
-		auto it = OBJECT_CATEGORY_STRINGS.find(node.String());
-		if(it != OBJECT_CATEGORY_STRINGS.end())
-			bannedObjectCategories.push_back(it->second);
+		auto categoriesArray = handler.enterArray("bannedCategories");
+		categoriesArray.syncSize(bannedObjectCategories, JsonNode::JsonType::DATA_STRING);
+		
+		for(size_t i = 0; i < bannedObjectCategories.size(); ++i)
+		{
+			for(const auto & [key, value] : OBJECT_CATEGORY_STRINGS)
+			{
+				if(value == bannedObjectCategories[i])
+				{
+					std::string categoryName = key;
+					categoriesArray.serializeString(i, categoryName);
+					break;
+				}
+			}
+		}
 	}
-
-	if(configBannedObjects.isVector())
+	else
 	{
-		// MOD COMPATIBILITY - 1.6 format
+		const JsonNode & config = handler.getCurrent();
+		const JsonNode & configBannedCategories = config["bannedCategories"];
 
-		for(const auto & node : configBannedObjects.Vector())
+		for(const auto & node : configBannedCategories.Vector())
 		{
-			LIBRARY->objtypeh->resolveObjectCompoundId(node.String(),
-				[this](CompoundMapObjectID objid)
+			auto it = OBJECT_CATEGORY_STRINGS.find(node.String());
+			if(it != OBJECT_CATEGORY_STRINGS.end())
+				bannedObjectCategories.push_back(it->second);
+		}
+	}
+
+	// Serialize banned objects
+	if (handler.saving)
+	{
+		// Group banned objects by primary ID
+		std::map<int, std::set<int>> groupedBanned;
+		for(const auto & objid : bannedObjects)
+		{
+			groupedBanned[objid.primaryID].insert(objid.secondaryID);
+		}
+		
+		auto bannedObjectsStruct = handler.enterStruct("bannedObjects");
+		
+		for(const auto & [primaryID, secondaryIDs] : groupedBanned)
+		{
+			const std::string jsonKey = LIBRARY->objtypeh->getJsonKey(primaryID);
+			
+			if(secondaryIDs.size() == 1 && *secondaryIDs.begin() == -1)
+			{
+				// Ban entire object type - write as boolean true
+				bool allBanned = true;
+				bannedObjectsStruct->serializeBool(jsonKey, allBanned);
+			}
+			else
+			{
+				// Ban specific subtypes
+				auto objStruct = bannedObjectsStruct->enterStruct(jsonKey);
+				for(int secondaryID : secondaryIDs)
 				{
-					addBannedObject(objid);
+					if(secondaryID != -1)
+					{
+						auto handler = LIBRARY->objtypeh->getHandlerFor(MapObjectID(primaryID), MapObjectSubID(secondaryID));
+						const std::string subtypeKey = handler->getSubTypeName();
+						bool banned = true;
+						objStruct->serializeBool(subtypeKey, banned);
+					}
 				}
-			);
+			}
 		}
 	}
 	else
 	{
-		for(const auto & node : configBannedObjects.Struct())
+		const JsonNode & config = handler.getCurrent();
+		const JsonNode & configBannedObjects = config["bannedObjects"];
+
+		if(configBannedObjects.isVector())
 		{
-			LIBRARY->identifiers()->requestIdentifierIfFound(node.second.getModScope(), "object", node.first, [this, node](int primaryID)
+			// MOD COMPATIBILITY - 1.6 format
+
+			for(const auto & node : configBannedObjects.Vector())
 			{
-				if (node.second.isBool())
-				{
-					if (node.second.Bool())
-						addBannedObject(CompoundMapObjectID(primaryID, -1));
-				}
-				else
+				LIBRARY->objtypeh->resolveObjectCompoundId(node.String(),
+					[this](CompoundMapObjectID objid)
+					{
+						addBannedObject(objid);
+					}
+				);
+			}
+		}
+		else
+		{
+			for(const auto & node : configBannedObjects.Struct())
+			{
+				LIBRARY->identifiers()->requestIdentifierIfFound(node.second.getModScope(), "object", node.first, [this, node](int primaryID)
 				{
-					for (const auto & subNode : node.second.Struct())
+					if (node.second.isBool())
 					{
-						const std::string jsonKey = LIBRARY->objtypeh->getJsonKey(primaryID);
-
-						LIBRARY->identifiers()->requestIdentifierIfFound(node.second.getModScope(), jsonKey, subNode.first, [this, primaryID](int secondaryID)
+						if (node.second.Bool())
+							addBannedObject(CompoundMapObjectID(primaryID, -1));
+					}
+					else
+					{
+						for (const auto & subNode : node.second.Struct())
 						{
-							addBannedObject(CompoundMapObjectID(primaryID, secondaryID));
-						});
+							const std::string jsonKey = LIBRARY->objtypeh->getJsonKey(primaryID);
+
+							LIBRARY->identifiers()->requestIdentifierIfFound(node.second.getModScope(), jsonKey, subNode.first, [this, primaryID](int secondaryID)
+							{
+								addBannedObject(CompoundMapObjectID(primaryID, secondaryID));
+							});
+						}
 					}
-				}
-			});
+				});
+			}
 		}
 	}
 
-	for (const auto & objectConfig : configCommonObjects.Vector())
+	// Serialize common objects
+	if (handler.saving)
 	{
-		auto rmg = objectConfig["rmg"].Struct();
+		auto commonObjectsArray = handler.enterArray("commonObjects");
+		commonObjectsArray.syncSize(customObjects, JsonNode::JsonType::DATA_STRUCT);
+		
+		for(size_t i = 0; i < customObjects.size(); ++i)
+		{
+			auto objectStruct = commonObjectsArray.enterStruct(i);
+			const auto & object = customObjects[i];
+			
+			// Serialize object type/subtype
+			std::string objectType = LIBRARY->objtypeh->getJsonKey(object.primaryID);
+			objectStruct->serializeString("type", objectType);
+			
+			if(object.secondaryID != 0)
+			{
+				auto handler = LIBRARY->objtypeh->getHandlerFor(MapObjectID(object.primaryID), MapObjectSubID(object.secondaryID));
+				std::string subtypeName = handler->getSubTypeName();
+				objectStruct->serializeString("subtype", subtypeName);
+			}
+			
+			// Serialize RMG properties
+			{
+				auto rmgStruct = objectStruct->enterStruct("rmg");
+				int value = object.value;
+				int rarity = object.probability;
+				int zoneLimit = (object.maxPerZone == std::numeric_limits<int>::max()) ? 0 : object.maxPerZone;
+				
+				rmgStruct->serializeInt("value", value);
+				rmgStruct->serializeInt("rarity", rarity);
+				rmgStruct->serializeInt("zoneLimit", zoneLimit);
+			}
+		}
+	}
+	else
+	{
+		const JsonNode & config = handler.getCurrent();
+		const JsonNode & configCommonObjects = config["commonObjects"];
+
+		for (const auto & objectConfig : configCommonObjects.Vector())
+		{
+			auto rmg = objectConfig["rmg"].Struct();
 
-		// TODO: Use common code with default rmg config
+			// TODO: Use common code with default rmg config
 
-		ObjectInfo object;
+			ObjectInfo object;
 
-		// TODO: Configure basic generateObject function
-		object.value = rmg["value"].Integer();
-		object.probability = rmg["rarity"].Integer();
-		object.maxPerZone = rmg["zoneLimit"].Integer();
-		if (object.maxPerZone == 0)
-			object.maxPerZone = std::numeric_limits<int>::max();
+			// TODO: Configure basic generateObject function
+			object.value = rmg["value"].Integer();
+			object.probability = rmg["rarity"].Integer();
+			object.maxPerZone = rmg["zoneLimit"].Integer();
+			if (object.maxPerZone == 0)
+				object.maxPerZone = std::numeric_limits<int>::max();
 
-		if (objectConfig["id"].isNull())
-		{
-			LIBRARY->identifiers()->requestIdentifierIfFound("object", objectConfig["type"], [this, object, objectConfig](int primaryID)
+			if (objectConfig["id"].isNull())
 			{
-				if (objectConfig["subtype"].isNull())
-				{
-					auto objectWithID = object;
-					objectWithID.primaryID = primaryID;
-					objectWithID.secondaryID = 0;
-					addCustomObject(objectWithID);
-				}
-				else
+				LIBRARY->identifiers()->requestIdentifierIfFound("object", objectConfig["type"], [this, object, objectConfig](int primaryID)
 				{
-					const std::string jsonKey = LIBRARY->objtypeh->getJsonKey(primaryID);
-
-					LIBRARY->identifiers()->requestIdentifierIfFound(jsonKey, objectConfig["subtype"], [this, primaryID, object](int secondaryID)
+					if (objectConfig["subtype"].isNull())
 					{
 						auto objectWithID = object;
 						objectWithID.primaryID = primaryID;
-						objectWithID.secondaryID = secondaryID;
+						objectWithID.secondaryID = 0;
 						addCustomObject(objectWithID);
-					});
-				}
-			});
-		}
-		else
-		{
-			// MOD COMPATIBILITY - 1.6 format
-			auto objectName = objectConfig["id"].String();
+					}
+					else
+					{
+						const std::string jsonKey = LIBRARY->objtypeh->getJsonKey(primaryID);
 
-			LIBRARY->objtypeh->resolveObjectCompoundId(objectName, [this, object](CompoundMapObjectID objid)
+						LIBRARY->identifiers()->requestIdentifierIfFound(jsonKey, objectConfig["subtype"], [this, primaryID, object](int secondaryID)
+						{
+							auto objectWithID = object;
+							objectWithID.primaryID = primaryID;
+							objectWithID.secondaryID = secondaryID;
+							addCustomObject(objectWithID);
+						});
+					}
+				});
+			}
+			else
 			{
-				auto objectWithID = object;
-				objectWithID.primaryID = objid.primaryID;
-				objectWithID.secondaryID = objid.secondaryID;
-				if (objectWithID.secondaryID == -1)
-					objectWithID.secondaryID = 0;
-				addCustomObject(objectWithID);
-			});
+				// MOD COMPATIBILITY - 1.6 format
+				auto objectName = objectConfig["id"].String();
+
+				LIBRARY->objtypeh->resolveObjectCompoundId(objectName, [this, object](CompoundMapObjectID objid)
+				{
+					auto objectWithID = object;
+					objectWithID.primaryID = objid.primaryID;
+					objectWithID.secondaryID = objid.secondaryID;
+					if (objectWithID.secondaryID == -1)
+						objectWithID.secondaryID = 0;
+					addCustomObject(objectWithID);
+				});
+			}
 		}
 	}
 }

+ 4 - 5
mapeditor/templateeditor/objectselector.cpp

@@ -135,7 +135,7 @@ void ObjectSelector::fillBannedObjectCategories()
 	for (int row = 0; row < obj.bannedObjectCategories.size(); ++row)
 		addRow(obj.bannedObjectCategories[row], row);
 
-	auto addButton = new QPushButton("Add");
+	auto addButton = new QPushButton(tr("Add"));
 	ui->tableWidgetBannedObjectCategories->setCellWidget(ui->tableWidgetBannedObjectCategories->rowCount() - 1, 1, addButton);
 	connect(addButton, &QPushButton::clicked, this, [this, addRow]() {
 		ui->tableWidgetBannedObjectCategories->insertRow(ui->tableWidgetBannedObjectCategories->rowCount() - 1);
@@ -152,8 +152,7 @@ void ObjectSelector::getBannedObjectCategories()
 	for (int row = 0; row < ui->tableWidgetBannedObjectCategories->rowCount() - 1; ++row)
 	{
 		auto val = static_cast<ObjectConfig::EObjectCategory>(static_cast<QComboBox *>(ui->tableWidgetBannedObjectCategories->cellWidget(row, 0))->currentData().toInt());
-		if(vstd::contains(obj.bannedObjectCategories, val))
-			obj.bannedObjectCategories.push_back(val);
+		obj.bannedObjectCategories.push_back(val);
 	}
 }
 
@@ -196,7 +195,7 @@ void ObjectSelector::fillBannedObjects()
 	for (int row = 0; row < obj.bannedObjects.size(); ++row)
 		addRow(obj.bannedObjects[row], row);
 
-	auto addButton = new QPushButton("Add");
+	auto addButton = new QPushButton(tr("Add"));
 	ui->tableWidgetBannedObjects->setCellWidget(ui->tableWidgetBannedObjects->rowCount() - 1, 1, addButton);
 	connect(addButton, &QPushButton::clicked, this, [this, addRow]() {
 		ui->tableWidgetBannedObjects->insertRow(ui->tableWidgetBannedObjects->rowCount() - 1);
@@ -271,7 +270,7 @@ void ObjectSelector::fillCustomObjects()
 	for (int row = 0; row < obj.customObjects.size(); ++row)
 		addRow(obj.customObjects[row].getCompoundID(), obj.customObjects[row].value, obj.customObjects[row].probability, obj.customObjects[row].maxPerZone, row);
 
-	auto addButton = new QPushButton("Add");
+	auto addButton = new QPushButton(tr("Add"));
 	ui->tableWidgetObjects->setCellWidget(ui->tableWidgetObjects->rowCount() - 1, 4, addButton);
 	connect(addButton, &QPushButton::clicked, this, [this, addRow]() {
 		ui->tableWidgetObjects->insertRow(ui->tableWidgetObjects->rowCount() - 1);

+ 1 - 1
mapeditor/templateeditor/townhintselector.cpp

@@ -96,7 +96,7 @@ TownHintSelector::TownHintSelector(std::vector<rmg::ZoneOptions::CTownHints> & t
 		addRow(mode, zones, row);
 	}
 
-	auto addButton = new QPushButton("Add");
+	auto addButton = new QPushButton(tr("Add"));
 	ui->tableWidgetTownHints->setCellWidget(ui->tableWidgetTownHints->rowCount() - 1, 2, addButton);
 	connect(addButton, &QPushButton::clicked, this, [this, addRow]() {
 		ui->tableWidgetTownHints->insertRow(ui->tableWidgetTownHints->rowCount() - 1);

+ 1 - 1
mapeditor/templateeditor/treasureselector.cpp

@@ -62,7 +62,7 @@ TreasureSelector::TreasureSelector(std::vector<CTreasureInfo> & treasures) :
 	for (int row = 0; row < treasures.size(); ++row)
 		addRow(treasures[row].min, treasures[row].max, treasures[row].density, row);
 
-	auto addButton = new QPushButton("Add");
+	auto addButton = new QPushButton(tr("Add"));
 	ui->tableWidgetTreasures->setCellWidget(ui->tableWidgetTreasures->rowCount() - 1, 3, addButton);
 	connect(addButton, &QPushButton::clicked, this, [this, addRow, treasures]() {
 		ui->tableWidgetTreasures->insertRow(ui->tableWidgetTreasures->rowCount() - 1);