From f78b524731b25d28f609d4d68c47b0071e6d1e0e Mon Sep 17 00:00:00 2001 From: DjWarmonger Date: Tue, 20 Dec 2016 15:23:47 +0100 Subject: [PATCH] - Remove obstacle in front of player-owned towns - Allow obstacles to touch town object --- lib/rmg/CMapGenerator.cpp | 25 +++++++++++++++---------- lib/rmg/CRmgTemplateZone.cpp | 26 ++++++++++---------------- lib/rmg/CRmgTemplateZone.h | 2 +- 3 files changed, 26 insertions(+), 27 deletions(-) diff --git a/lib/rmg/CMapGenerator.cpp b/lib/rmg/CMapGenerator.cpp index 3f6ba4cbb..bf7d83243 100644 --- a/lib/rmg/CMapGenerator.cpp +++ b/lib/rmg/CMapGenerator.cpp @@ -283,7 +283,12 @@ void CMapGenerator::fillZones() logGlobal->infoStream() << "Started filling zones"; - //initialize possible tiles before any object is actually placed + //we need info about all town types to evaluate dwellings and pandoras with creatures properly + //place main town in the middle + for (auto it : zones) + it.second->initTownType(this); + + //make sure there are some free tiles in the zone for (auto it : zones) it.second->initFreeTiles(this); @@ -294,10 +299,6 @@ void CMapGenerator::fillZones() createConnections2(); //subterranean gates and monoliths - //we need info about all town types to evaluate dwellings and pandoras with creatures properly - for (auto it : zones) - it.second->initTownType(this); - std::vector treasureZones; for (auto it : zones) { @@ -532,12 +533,16 @@ void CMapGenerator::createDirectConnections() guardPos = tile; if (guardPos.valid()) { - setOccupied(guardPos, ETileType::FREE); //just in case monster is too weak to spawn - zoneA->addMonster(this, guardPos, connection.getGuardStrength(), false, true); - zoneB->updateDistances(this, guardPos); //place next objects away from guard in both zones //zones can make paths only in their own area - zoneA->crunchPath(this, guardPos, posA, true, zoneA->getFreePaths()); //make connection towards our zone center - zoneB->crunchPath(this, guardPos, posB, true, zoneB->getFreePaths()); //make connection towards other zone center + zoneA->connectWithCenter(this, guardPos, true); + zoneB->connectWithCenter(this, guardPos, true); + + bool monsterPresent = zoneA->addMonster(this, guardPos, connection.getGuardStrength(), false, true); + zoneB->updateDistances(this, guardPos); //place next objects away from guard in both zones + + //set free tile only after connection is made to the center of the zone + if (!monsterPresent) + setOccupied(guardPos, ETileType::FREE); //just in case monster is too weak to spawn zoneA->addRoadNode(guardPos); zoneB->addRoadNode(guardPos); diff --git a/lib/rmg/CRmgTemplateZone.cpp b/lib/rmg/CRmgTemplateZone.cpp index 94d53188d..68fe20ef4 100644 --- a/lib/rmg/CRmgTemplateZone.cpp +++ b/lib/rmg/CRmgTemplateZone.cpp @@ -1319,17 +1319,11 @@ void CRmgTemplateZone::initTownType (CMapGenerator* gen) auto cutPathAroundTown = [gen, this](const CGTownInstance * town) { - //cut contour around town in case it was placed in a middle of path. TODO: find better solution - for (auto tile : town->getBlockedPos()) + //cut contour around town entrance + for (auto pos: getAccessibleOffsets(gen, town)) { - gen->foreach_neighbour(tile, [gen, &tile](int3& pos) - { - if (gen->isPossible(pos)) - { - gen->setOccupied(pos, ETileType::FREE); - } - }); - } + gen->setOccupied(pos, ETileType::FREE); + }; }; auto addNewTowns = [&totalTowns, gen, this, &cutPathAroundTown](int count, bool hasFort, PlayerColor player) @@ -1369,9 +1363,9 @@ void CRmgTemplateZone::initTownType (CMapGenerator* gen) //register MAIN town of zone gen->registerZone(town->subID); //first town in zone goes in the middle - placeAndGuardObject(gen, town, getPos() + town->getVisitableOffset(), 0); + placeObject(gen, town, getPos() + town->getVisitableOffset(), true); cutPathAroundTown(town); - setPos(town->visitablePos() + int3(0, 1, 0)); //new center of zone that paths connect to + setPos(town->pos + int3(0, 1, 0)); //roads lead to tile below the town } else addRequiredObject (town); @@ -1414,9 +1408,9 @@ void CRmgTemplateZone::initTownType (CMapGenerator* gen) town->possibleSpells.push_back(spell->id); } //towns are big objects and should be centered around visitable position - placeAndGuardObject(gen, town, getPos() + town->getVisitableOffset(), 0); //generate no guards, but free path to entrance + placeObject(gen, town, getPos() + town->getVisitableOffset(), true); cutPathAroundTown(town); - setPos(town->visitablePos() + int3(0, 1, 0)); //new center of zone that paths connect to + setPos(town->pos + int3(0, 1, 0)); //roads lead to tile below the town totalTowns++; //register MAIN town of zone only @@ -1902,7 +1896,7 @@ bool CRmgTemplateZone::fill(CMapGenerator* gen) initTerrainType(gen); //zone center should be always clear to allow other tiles to connect - gen->setOccupied(this->getPos(), ETileType::FREE); + gen->setOccupied(pos, ETileType::FREE); freePaths.insert(pos); addAllPossibleObjects (gen); @@ -2156,7 +2150,7 @@ void CRmgTemplateZone::placeSubterraneanGate(CMapGenerator* gen, int3 pos, si32 guardObject (gen, gate, guardStrength, true); } -std::vector CRmgTemplateZone::getAccessibleOffsets (CMapGenerator* gen, CGObjectInstance* object) +std::vector CRmgTemplateZone::getAccessibleOffsets (CMapGenerator* gen, const CGObjectInstance* object) { //get all tiles from which this object can be accessed int3 visitable = object->visitablePos(); diff --git a/lib/rmg/CRmgTemplateZone.h b/lib/rmg/CRmgTemplateZone.h index f35a3fc5a..686d9794f 100644 --- a/lib/rmg/CRmgTemplateZone.h +++ b/lib/rmg/CRmgTemplateZone.h @@ -194,7 +194,7 @@ public: bool connectWithCenter(CMapGenerator* gen, const int3& src, bool onlyStraight); void updateDistances(CMapGenerator* gen, const int3 & pos); - std::vector getAccessibleOffsets (CMapGenerator* gen, CGObjectInstance* object); + std::vector getAccessibleOffsets (CMapGenerator* gen, const CGObjectInstance* object); bool areAllTilesAvailable(CMapGenerator* gen, CGObjectInstance* obj, int3& tile, std::set& tilesBlockedByObject) const; void addConnection(TRmgTemplateZoneId otherZone);