From 51fc3fbf833be0fac4652d1018a213fb03357048 Mon Sep 17 00:00:00 2001 From: DjWarmonger Date: Sun, 1 Jun 2014 16:31:15 +0200 Subject: [PATCH] - Zone guards will now match template settings. - Added guards for monoliths. --- lib/rmg/CMapGenerator.cpp | 60 ++++++++++++++++++++++++++++--- lib/rmg/CMapGenerator.h | 1 + lib/rmg/CRmgTemplateZone.cpp | 68 +++++------------------------------- lib/rmg/CRmgTemplateZone.h | 5 ++- 4 files changed, 68 insertions(+), 66 deletions(-) diff --git a/lib/rmg/CMapGenerator.cpp b/lib/rmg/CMapGenerator.cpp index 404a4d7a9..35d81373e 100644 --- a/lib/rmg/CMapGenerator.cpp +++ b/lib/rmg/CMapGenerator.cpp @@ -218,10 +218,7 @@ void CMapGenerator::fillZones() { logGlobal->infoStream() << "Started filling zones"; - for (auto it : zones) - { - it.second->createConnections(this); - } + createConnections(); for (auto it : zones) { //make sure all connections are passable before creating borders @@ -231,6 +228,61 @@ void CMapGenerator::fillZones() logGlobal->infoStream() << "Zones filled successfully"; } +void CMapGenerator::createConnections() +{ + for (auto connection : mapGenOptions->getMapTemplate()->getConnections()) + { + auto zoneA = connection.getZoneA(); + auto zoneB = connection.getZoneB(); + + //rearrange tiles in random order + auto tilesCopy = zoneA->getTileInfo(); + std::vector tiles(tilesCopy.begin(), tilesCopy.end()); + //TODO: hwo to use std::shuffle with our generator? + //std::random_shuffle (tiles.begin(), tiles.end(), &gen->rand.nextInt); + + int i, n; + n = (tiles.end() - tiles.begin()); + for (i=n-1; i>0; --i) + { + std::swap (tiles.begin()[i],tiles.begin()[rand.nextInt(i+1)]); + } + + int3 guardPos(-1,-1,-1); + + auto otherZoneTiles = zoneB->getTileInfo(); + auto otherZoneCenter = zoneB->getPos(); + + for (auto tile : tiles) + { + foreach_neighbour (tile, [&guardPos, tile, &otherZoneTiles](int3 &pos) + { + if (vstd::contains(otherZoneTiles, pos)) + guardPos = tile; + }); + if (guardPos.valid()) + { + zoneA->addMonster (this, guardPos, connection.getGuardStrength()); //TODO: set value according to template + //zones can make paths only in their own area + zoneA->crunchPath (this, guardPos, zoneA->getPos(), zoneA->getId()); //make connection towards our zone center + zoneB->crunchPath (this, guardPos, zoneB->getPos(), zoneB->getId()); //make connection towards other zone center + break; //we're done with this connection + } + } + if (!guardPos.valid()) + { + auto teleport1 = new CGTeleport; + teleport1->ID = Obj::MONOLITH_TWO_WAY; + teleport1->subID = getNextMonlithIndex(); + + auto teleport2 = new CGTeleport(*teleport1); + + zoneA->addRequiredObject (teleport1, connection.getGuardStrength()); + zoneB->addRequiredObject (teleport2, connection.getGuardStrength()); + } + } +} + void CMapGenerator::addHeaderInfo() { map->version = EMapFormat::SOD; diff --git a/lib/rmg/CMapGenerator.h b/lib/rmg/CMapGenerator.h index 98ba57d78..83b4d7e46 100644 --- a/lib/rmg/CMapGenerator.h +++ b/lib/rmg/CMapGenerator.h @@ -64,6 +64,7 @@ public: CMapEditManager * editManager; std::map getZones() const; + void createConnections(); void foreach_neighbour(const int3 &pos, std::function foo); bool isBlocked(const int3 &tile) const; diff --git a/lib/rmg/CRmgTemplateZone.cpp b/lib/rmg/CRmgTemplateZone.cpp index e680e4847..4259ea93a 100644 --- a/lib/rmg/CRmgTemplateZone.cpp +++ b/lib/rmg/CRmgTemplateZone.cpp @@ -317,60 +317,6 @@ std::set CRmgTemplateZone::getTileInfo () const return tileinfo; } -void CRmgTemplateZone::createConnections(CMapGenerator* gen) -{ - //rearrange tiles in random order - std::vector tiles(tileinfo.begin(), tileinfo.end()); - //TODO: hwo to use std::shuffle with our generator? - //std::random_shuffle (tiles.begin(), tiles.end(), &gen->rand.nextInt); - - int i, n; - n = (tiles.end() - tiles.begin()); - for (i=n-1; i>0; --i) - { - std::swap (tiles.begin()[i],tiles.begin()[gen->rand.nextInt(i+1)]); - } - - for (auto connection : connections) - { - if (getId() > connection) //only one connection between each pair - continue; - - int3 guardPos(-1,-1,-1); - - auto otherZoneTiles = gen->getZones()[connection]->getTileInfo(); - auto otherZoneCenter = gen->getZones()[connection]->getPos(); - - for (auto tile : tiles) - { - gen->foreach_neighbour (tile, [&guardPos, tile, &otherZoneTiles](int3 &pos) - { - if (vstd::contains(otherZoneTiles, pos)) - guardPos = tile; - }); - if (guardPos.valid()) - { - addMonster (gen, guardPos, 10000); //TODO: set value according to template - //zones can make paths only in their own area - this->crunchPath (gen, guardPos, this->getPos(), this->getId()); //make connection towards our zone center - gen->getZones()[connection]->crunchPath (gen, guardPos, otherZoneCenter, connection); //make connection towards other zone center - break; //we're done with this connection - } - } - if (!guardPos.valid()) - { - auto teleport1 = new CGTeleport; - teleport1->ID = Obj::MONOLITH_TWO_WAY; - teleport1->subID = gen->getNextMonlithIndex(); - - auto teleport2 = new CGTeleport(*teleport1); - - addRequiredObject (teleport1); - gen->getZones()[connection]->addRequiredObject(teleport2); - } - } -} - void CRmgTemplateZone::createBorder(CMapGenerator* gen) { for (auto tile : tileinfo) @@ -450,9 +396,9 @@ do not leave zone border return result; } -void CRmgTemplateZone::addRequiredObject(CGObjectInstance * obj) +void CRmgTemplateZone::addRequiredObject(CGObjectInstance * obj, si32 strength) { - requiredObjects.push_back(obj); + requiredObjects.push_back(std::make_pair(obj, strength)); } void CRmgTemplateZone::addMonster(CMapGenerator* gen, int3 &pos, si32 strength) @@ -527,7 +473,7 @@ bool CRmgTemplateZone::fill(CMapGenerator* gen) mine->subID = static_cast(res); mine->producedResource = res; mine->producedQuantity = mine->defaultResProduction(); - requiredObjects.push_back(mine); + addRequiredObject(mine); } } else @@ -555,7 +501,7 @@ bool CRmgTemplateZone::fill(CMapGenerator* gen) { int3 pos; logGlobal->traceStream() << "Looking for place"; - if ( ! findPlaceForObject(gen, obj, 3, pos)) + if ( ! findPlaceForObject(gen, obj.first, 3, pos)) { logGlobal->errorStream() << boost::format("Failed to fill zone %d due to lack of space") %id; //TODO CLEANUP! @@ -563,7 +509,11 @@ bool CRmgTemplateZone::fill(CMapGenerator* gen) } logGlobal->traceStream() << "Place found"; - placeObject(gen, obj, pos); + placeObject(gen, obj.first, pos); + if (obj.second) + { + guardObject (gen, obj.first, obj.second); //FIXME: set apriopriate guard strength + } } std::vector guarded_objects; static auto res_gen = gen->rand.getIntRange(Res::ERes::WOOD, Res::ERes::GOLD); diff --git a/lib/rmg/CRmgTemplateZone.h b/lib/rmg/CRmgTemplateZone.h index 657c6ccae..3163b432a 100644 --- a/lib/rmg/CRmgTemplateZone.h +++ b/lib/rmg/CRmgTemplateZone.h @@ -112,10 +112,9 @@ public: void addTile (const int3 &pos); std::set getTileInfo () const; - void addRequiredObject(CGObjectInstance * obj); + void addRequiredObject(CGObjectInstance * obj, si32 guardStrength=0); void addMonster(CMapGenerator* gen, int3 &pos, si32 strength); bool fill(CMapGenerator* gen); - void createConnections(CMapGenerator* gen); void createBorder(CMapGenerator* gen); bool crunchPath (CMapGenerator* gen, int3 &src, int3 &dst, TRmgTemplateZoneId zone); @@ -137,7 +136,7 @@ private: //content info std::vector shape; //TODO: remove - std::vector requiredObjects; + std::vector> requiredObjects; std::vector objects; //placement info