From cf5ce96aeb19ac8839902146d919625a3c2fd729 Mon Sep 17 00:00:00 2001 From: Dydzio Date: Mon, 23 Sep 2024 21:45:50 +0200 Subject: [PATCH 1/3] 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 } } From 9004b88c7e8b61f7771c4ec5ab63ec307d0d067f Mon Sep 17 00:00:00 2001 From: Dydzio Date: Thu, 26 Sep 2024 20:05:46 +0200 Subject: [PATCH 2/3] Mapping of deletable coordinates to objects on map start --- lib/gameState/CGameState.cpp | 23 +++++++++++++++++++++++ lib/gameState/CGameState.h | 1 + lib/mapping/CMapDefines.h | 8 ++++++++ server/processors/NewTurnProcessor.cpp | 11 ++--------- 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/lib/gameState/CGameState.cpp b/lib/gameState/CGameState.cpp index 31bd4e2de..524fb0e47 100644 --- a/lib/gameState/CGameState.cpp +++ b/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,28 @@ 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.insert(object); + } + + for(const CGObjectInstance * object : getVisitableObjs(coordinate)) + { + timedEvent.deletedObjectsInstances.insert(object); + } + } + } + } +} + void CGameState::placeHeroesInTowns() { for(auto & player : players) diff --git a/lib/gameState/CGameState.h b/lib/gameState/CGameState.h index d247eb47b..caa6df740 100644 --- a/lib/gameState/CGameState.h +++ b/lib/gameState/CGameState.h @@ -196,6 +196,7 @@ private: void initTowns(); void initTownNames(); void initMapObjects(); + void initTimedEventsRemovableObjects(); void initVisitingAndGarrisonedHeroes(); void initCampaign(); diff --git a/lib/mapping/CMapDefines.h b/lib/mapping/CMapDefines.h index 09787d198..9ba44b4c6 100644 --- a/lib/mapping/CMapDefines.h +++ b/lib/mapping/CMapDefines.h @@ -44,8 +44,10 @@ public: 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::set deletedObjectsInstances; std::vector unused; + std::set unused2; template void serialize(Handler & h) @@ -70,9 +72,15 @@ public: 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); diff --git a/server/processors/NewTurnProcessor.cpp b/server/processors/NewTurnProcessor.cpp index 888e9a399..91e48e8bb 100644 --- a/server/processors/NewTurnProcessor.cpp +++ b/server/processors/NewTurnProcessor.cpp @@ -62,16 +62,9 @@ void NewTurnProcessor::handleTimeEvents(PlayerColor color) } //remove objects specified by event - for(int3 coordinate : event.deletedObjectsCoordinates) + for(const CGObjectInstance * objectToRemove : event.deletedObjectsInstances) { - if(gameHandler->isInTheMap(coordinate)) - { - auto objects = gameHandler->getBlockingObjs(coordinate); - for(const CGObjectInstance * object : objects) - { - gameHandler->removeObject(object, PlayerColor::NEUTRAL); - } - } + gameHandler->removeObject(objectToRemove, PlayerColor::NEUTRAL); } gameHandler->sendAndApply(&iw); //show dialog } From e56b8e86e5ffa30cfe62e3e9f84f9597384a08fa Mon Sep 17 00:00:00 2001 From: Dydzio Date: Thu, 26 Sep 2024 21:25:02 +0200 Subject: [PATCH 3/3] Do not use VisitableObjects - BlockedObjects should suffice --- lib/gameState/CGameState.cpp | 7 +------ lib/mapping/CMapDefines.h | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/lib/gameState/CGameState.cpp b/lib/gameState/CGameState.cpp index 524fb0e47..feabbd077 100644 --- a/lib/gameState/CGameState.cpp +++ b/lib/gameState/CGameState.cpp @@ -962,12 +962,7 @@ void CGameState::initTimedEventsRemovableObjects() { for(const CGObjectInstance * object : getBlockingObjs(coordinate)) { - timedEvent.deletedObjectsInstances.insert(object); - } - - for(const CGObjectInstance * object : getVisitableObjs(coordinate)) - { - timedEvent.deletedObjectsInstances.insert(object); + timedEvent.deletedObjectsInstances.push_back(object); } } } diff --git a/lib/mapping/CMapDefines.h b/lib/mapping/CMapDefines.h index 9ba44b4c6..3cc19d74a 100644 --- a/lib/mapping/CMapDefines.h +++ b/lib/mapping/CMapDefines.h @@ -44,7 +44,7 @@ public: 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::set deletedObjectsInstances; + std::vector deletedObjectsInstances; std::vector unused; std::set unused2;