From 985a2682ae7e36f3ac63f8cf7a9304cb957b85fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Zieli=C5=84ski?= Date: Mon, 18 Dec 2023 11:12:52 +0100 Subject: [PATCH] Place Monoliths at max distance in Junction zone --- lib/rmg/Zone.cpp | 11 ++++++++ lib/rmg/modificators/ObjectManager.cpp | 35 ++++++++++++++++++++++++++ lib/rmg/modificators/ObjectManager.h | 1 + 3 files changed, 47 insertions(+) diff --git a/lib/rmg/Zone.cpp b/lib/rmg/Zone.cpp index 316d91a73..6c48ae3d4 100644 --- a/lib/rmg/Zone.cpp +++ b/lib/rmg/Zone.cpp @@ -15,6 +15,7 @@ #include "TileInfo.h" #include "CMapGenerator.h" #include "RmgPath.h" +#include "modificators/ObjectManager.h" VCMI_LIB_NAMESPACE_BEGIN @@ -307,6 +308,16 @@ void Zone::fractalize() tilesToIgnore.clear(); } } + else + { + // Handle special case - place Monoliths at the edge of a zone + auto objectManager = getModificator(); + if (objectManager) + { + objectManager->createMonoliths(); + } + } + Lock lock(areaMutex); //cut straight paths towards the center. A* is too slow for that. auto areas = connectedAreas(clearedTiles, false); diff --git a/lib/rmg/modificators/ObjectManager.cpp b/lib/rmg/modificators/ObjectManager.cpp index e48053a24..ccc836a91 100644 --- a/lib/rmg/modificators/ObjectManager.cpp +++ b/lib/rmg/modificators/ObjectManager.cpp @@ -356,6 +356,41 @@ rmg::Path ObjectManager::placeAndConnectObject(const rmg::Area & searchArea, rmg } } +bool ObjectManager::createMonoliths() +{ + // Special case for Junction zone only + logGlobal->trace("Creating Monoliths"); + for(const auto & objInfo : requiredObjects) + { + if (objInfo.obj->ID != Obj::MONOLITH_TWO_WAY) + { + continue; + } + + rmg::Object rmgObject(*objInfo.obj); + rmgObject.setTemplate(zone.getTerrainType(), zone.getRand()); + bool guarded = addGuard(rmgObject, objInfo.guardStrength, true); + + Zone::Lock lock(zone.areaMutex); + auto path = placeAndConnectObject(zone.areaPossible(), rmgObject, 3, guarded, false, OptimizeType::DISTANCE); + + if(!path.valid()) + { + logGlobal->error("Failed to fill zone %d due to lack of space", zone.getId()); + return false; + } + + zone.connectPath(path); + placeObject(rmgObject, guarded, true, objInfo.createRoad); + } + + vstd::erase_if(requiredObjects, [](const auto & objInfo) + { + return objInfo.obj->ID == Obj::MONOLITH_TWO_WAY; + }); + return true; +} + bool ObjectManager::createRequiredObjects() { logGlobal->trace("Creating required objects"); diff --git a/lib/rmg/modificators/ObjectManager.h b/lib/rmg/modificators/ObjectManager.h index 2e0ed7f71..0ce63238d 100644 --- a/lib/rmg/modificators/ObjectManager.h +++ b/lib/rmg/modificators/ObjectManager.h @@ -62,6 +62,7 @@ public: void addCloseObject(const RequiredObjectInfo & info); void addNearbyObject(const RequiredObjectInfo & info); + bool ObjectManager::createMonoliths(); bool createRequiredObjects(); int3 findPlaceForObject(const rmg::Area & searchArea, rmg::Object & obj, si32 min_dist, OptimizeType optimizer) const;