From cf5ce96aeb19ac8839902146d919625a3c2fd729 Mon Sep 17 00:00:00 2001 From: Dydzio Date: Mon, 23 Sep 2024 21:45:50 +0200 Subject: [PATCH] Backend implementation of object removal possibility by timed map events --- lib/mapping/CMap.cpp | 19 +++++++++++++++++++ lib/mapping/CMapDefines.h | 9 +++++++++ lib/serializer/ESerializationVersion.h | 3 ++- mapeditor/mapsettings/abstractsettings.h | 2 ++ mapeditor/mapsettings/eventsettings.cpp | 24 ++++++++++++++++++++++++ server/processors/NewTurnProcessor.cpp | 13 +++++++++++++ 6 files changed, 69 insertions(+), 1 deletion(-) diff --git a/lib/mapping/CMap.cpp b/lib/mapping/CMap.cpp index ee0948ee5..92a916f79 100644 --- a/lib/mapping/CMap.cpp +++ b/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(entry.x); + valueY.Float() = static_cast(entry.y); + valueZ.Float() = static_cast(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) diff --git a/lib/mapping/CMapDefines.h b/lib/mapping/CMapDefines.h index 36034db33..09787d198 100644 --- a/lib/mapping/CMapDefines.h +++ b/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 deletedObjectsCoordinates; + + std::vector unused; + template 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); diff --git a/lib/serializer/ESerializationVersion.h b/lib/serializer/ESerializationVersion.h index 3a835ef1e..f3b45d79a 100644 --- a/lib/serializer/ESerializationVersion.h +++ b/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 }; diff --git a/mapeditor/mapsettings/abstractsettings.h b/mapeditor/mapsettings/abstractsettings.h index 53ab653e5..bf729be06 100644 --- a/mapeditor/mapsettings/abstractsettings.h +++ b/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); diff --git a/mapeditor/mapsettings/eventsettings.cpp b/mapeditor/mapsettings/eventsettings.cpp index f7c2bbc76..9ec846659 100644 --- a/mapeditor/mapsettings/eventsettings.cpp +++ b/mapeditor/mapsettings/eventsettings.cpp @@ -55,6 +55,28 @@ TResources resourcesFromVariant(const QVariant & v) return TResources(vJson); } +QVariant toVariant(std::vector positions) +{ + QVariantList result; + for(int3 position : positions) + { + result.push_back(QVariant::fromValue(position)); + } + return result; +} + +std::vector deletedObjectsPositionsFromVariant(const QVariant & v) +{ + std::vector result; + for (auto positionAsVariant : v.toList()) + { + int3 position = positionAsVariant.value(); + 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; } diff --git a/server/processors/NewTurnProcessor.cpp b/server/processors/NewTurnProcessor.cpp index 4107720d5..888e9a399 100644 --- a/server/processors/NewTurnProcessor.cpp +++ b/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 } }