浏览代码

Backend implementation of object removal possibility by timed map events

Dydzio 1 年之前
父节点
当前提交
cf5ce96aeb

+ 19 - 0
lib/mapping/CMap.cpp

@@ -103,6 +103,25 @@ void CMapEvent::serializeJson(JsonSerializeFormat & handler)
 	handler.serializeInt("firstOccurrence", firstOccurrence);
 	handler.serializeInt("nextOccurrence", nextOccurrence);
 	resources.serializeJson(handler, "resources");
+
+	JsonNode deletedObjectsJson;
+
+	for (const auto & entry : deletedObjectsCoordinates)
+	{
+		JsonNode values;
+		JsonNode valueX;
+		JsonNode valueY;
+		JsonNode valueZ;
+		valueX.Float() = static_cast<int>(entry.x);
+		valueY.Float() = static_cast<int>(entry.y);
+		valueZ.Float() = static_cast<int>(entry.z);
+		values.Vector().push_back(valueX);
+		values.Vector().push_back(valueY);
+		values.Vector().push_back(valueZ);
+		deletedObjectsJson.Vector().push_back(values);
+	}
+
+	handler.serializeRaw("deletedObjectsCoordinates", deletedObjectsJson, std::nullopt);
 }
 
 void CCastleEvent::serializeJson(JsonSerializeFormat & handler)

+ 9 - 0
lib/mapping/CMapDefines.h

@@ -12,6 +12,7 @@
 
 #include "../ResourceSet.h"
 #include "../texts/MetaString.h"
+#include "../int3.h"
 
 VCMI_LIB_NAMESPACE_BEGIN
 
@@ -42,6 +43,10 @@ public:
 	ui32 firstOccurrence;
 	ui32 nextOccurrence; /// specifies after how many days the event will occur the next time; 0 if event occurs only one time
 
+	std::vector<int3> deletedObjectsCoordinates;
+
+	std::vector<int3> unused;
+
 	template <typename Handler>
 	void serialize(Handler & h)
 	{
@@ -64,6 +69,10 @@ public:
 		h & computerAffected;
 		h & firstOccurrence;
 		h & nextOccurrence;
+		if(h.version >= Handler::Version::EVENT_OBJECTS_DELETION)
+			h & deletedObjectsCoordinates;
+		else
+			h & unused;
 	}
 	
 	virtual void serializeJson(JsonSerializeFormat & handler);

+ 2 - 1
lib/serializer/ESerializationVersion.h

@@ -60,6 +60,7 @@ enum class ESerializationVersion : int32_t
 	PER_MAP_GAME_SETTINGS, // 861 - game settings are now stored per-map
 	CAMPAIGN_OUTRO_SUPPORT, // 862 - support for campaign outro video
 	REWARDABLE_BANKS, // 863 - team state contains list of scouted objects, coast visitable rewardable objects
+	EVENT_OBJECTS_DELETION, //864 - allow events to remove map objects
 
-	CURRENT = REWARDABLE_BANKS
+	CURRENT = EVENT_OBJECTS_DELETION
 };

+ 2 - 0
mapeditor/mapsettings/abstractsettings.h

@@ -14,6 +14,8 @@
 #include "../../lib/mapObjects/CGTownInstance.h"
 #include "../../lib/mapObjects/CGHeroInstance.h"
 
+Q_DECLARE_METATYPE(int3)
+
 //parses date for lose condition (1m 1w 1d)
 int expiredDate(const QString & date);
 QString expiredDate(int date);

+ 24 - 0
mapeditor/mapsettings/eventsettings.cpp

@@ -55,6 +55,28 @@ TResources resourcesFromVariant(const QVariant & v)
 	return TResources(vJson);
 }
 
+QVariant toVariant(std::vector<int3> positions)
+{
+	QVariantList result;
+	for(int3 position : positions)
+	{
+		result.push_back(QVariant::fromValue<int3>(position));
+	}
+	return result;
+}
+
+std::vector<int3> deletedObjectsPositionsFromVariant(const QVariant & v)
+{
+	std::vector<int3> result;
+	for (auto positionAsVariant : v.toList())
+	{
+		int3 position = positionAsVariant.value<int3>();
+		result.push_back(position);
+	}
+
+	return result;
+}
+
 QVariant toVariant(const CMapEvent & event)
 {
 	QVariantMap result;
@@ -66,6 +88,7 @@ QVariant toVariant(const CMapEvent & event)
 	result["firstOccurrence"] = QVariant::fromValue(event.firstOccurrence);
 	result["nextOccurrence"] = QVariant::fromValue(event.nextOccurrence);
 	result["resources"] = toVariant(event.resources);
+	result["deletedObjectsPositions"] = toVariant(event.deletedObjectsCoordinates);
 	return QVariant(result);
 }
 
@@ -81,6 +104,7 @@ CMapEvent eventFromVariant(CMapHeader & mapHeader, const QVariant & variant)
 	result.firstOccurrence = v.value("firstOccurrence").toInt();
 	result.nextOccurrence = v.value("nextOccurrence").toInt();
 	result.resources = resourcesFromVariant(v.value("resources"));
+	result.deletedObjectsCoordinates = deletedObjectsPositionsFromVariant(v.value("deletedObjectsPositions"));
 	return result;
 }
 

+ 13 - 0
server/processors/NewTurnProcessor.cpp

@@ -60,6 +60,19 @@ void NewTurnProcessor::handleTimeEvents(PlayerColor color)
 				if (event.resources[i])
 					iw.components.emplace_back(ComponentType::RESOURCE, i, event.resources[i]);
 		}
+
+		//remove objects specified by event
+		for(int3 coordinate : event.deletedObjectsCoordinates)
+		{
+			if(gameHandler->isInTheMap(coordinate))
+			{
+				auto objects = gameHandler->getBlockingObjs(coordinate);
+				for(const CGObjectInstance * object : objects)
+				{
+					gameHandler->removeObject(object, PlayerColor::NEUTRAL);
+				}
+			}
+		}
 		gameHandler->sendAndApply(&iw); //show dialog
 	}
 }