Browse Source

Merge pull request #4679 from dydzio0614/map-objects-removal-2

"Backend" part of map objects removal via timed events
Dydzio 1 year ago
parent
commit
6a7f58c3d1

+ 18 - 0
lib/gameState/CGameState.cpp

@@ -210,6 +210,7 @@ void CGameState::init(const IMapService * mapService, StartInfo * si, Load::Prog
 	buildBonusSystemTree();
 	initVisitingAndGarrisonedHeroes();
 	initFogOfWar();
+	initTimedEventsRemovableObjects();
 
 	for(auto & elem : teams)
 	{
@@ -951,6 +952,23 @@ void CGameState::initMapObjects()
 	map->calculateGuardingGreaturePositions(); //calculate once again when all the guards are placed and initialized
 }
 
+void CGameState::initTimedEventsRemovableObjects()
+{
+	for(auto & timedEvent : map->events)
+	{
+		for(int3 coordinate : timedEvent.deletedObjectsCoordinates)
+		{
+			if(isInTheMap(coordinate))
+			{
+				for(const CGObjectInstance * object : getBlockingObjs(coordinate))
+				{
+					timedEvent.deletedObjectsInstances.push_back(object);
+				}
+			}
+		}
+	}
+}
+
 void CGameState::placeHeroesInTowns()
 {
 	for(auto & player : players)

+ 1 - 0
lib/gameState/CGameState.h

@@ -196,6 +196,7 @@ private:
 	void initTowns();
 	void initTownNames();
 	void initMapObjects();
+	void initTimedEventsRemovableObjects();
 	void initVisitingAndGarrisonedHeroes();
 	void initCampaign();
 

+ 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)

+ 17 - 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,12 @@ 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<const CGObjectInstance*> deletedObjectsInstances;
+
+	std::vector<int3> unused;
+	std::set<const CGObjectInstance*> unused2;
+
 	template <typename Handler>
 	void serialize(Handler & h)
 	{
@@ -64,6 +71,16 @@ public:
 		h & computerAffected;
 		h & firstOccurrence;
 		h & nextOccurrence;
+		if(h.version >= Handler::Version::EVENT_OBJECTS_DELETION)
+		{
+			h & deletedObjectsCoordinates;
+			h & deletedObjectsInstances;
+		}
+		else
+		{
+			h & unused;
+			h & unused2;
+		}
 	}
 	
 	virtual void serializeJson(JsonSerializeFormat & handler);

+ 2 - 1
lib/serializer/ESerializationVersion.h

@@ -61,6 +61,7 @@ enum class ESerializationVersion : int32_t
 	CAMPAIGN_OUTRO_SUPPORT, // 862 - support for campaign outro video
 	REWARDABLE_BANKS, // 863 - team state contains list of scouted objects, coast visitable rewardable objects
 	REGION_LABEL, // 864 - labels for campaign regions
+	EVENT_OBJECTS_DELETION, //865 - allow events to remove map objects
 
-	CURRENT = REGION_LABEL
+	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;
 }
 

+ 6 - 0
server/processors/NewTurnProcessor.cpp

@@ -60,6 +60,12 @@ 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(const CGObjectInstance * objectToRemove : event.deletedObjectsInstances)
+		{
+			gameHandler->removeObject(objectToRemove, PlayerColor::NEUTRAL);
+		}
 		gameHandler->sendAndApply(&iw); //show dialog
 	}
 }