|
@@ -790,6 +790,10 @@ void CRmgTemplateZone::addCloseObject(CGObjectInstance * obj, si32 strength)
|
|
|
{
|
|
|
closeObjects.push_back(std::make_pair(obj, strength));
|
|
|
}
|
|
|
+void CRmgTemplateZone::addNearbyObject(CGObjectInstance * obj, CGObjectInstance * nearbyTarget)
|
|
|
+{
|
|
|
+ nearbyObjects.push_back(std::make_pair(obj, nearbyTarget));
|
|
|
+}
|
|
|
|
|
|
void CRmgTemplateZone::addToConnectLater(const int3& src)
|
|
|
{
|
|
@@ -1106,14 +1110,17 @@ void CRmgTemplateZone::initTownType ()
|
|
|
//cut a ring around town to ensure crunchPath always hits it.
|
|
|
auto cutPathAroundTown = [this](const CGTownInstance * town)
|
|
|
{
|
|
|
+ auto clearPos = [this](const int3 & pos)
|
|
|
+ {
|
|
|
+ if (gen->isPossible(pos))
|
|
|
+ gen->setOccupied(pos, ETileType::FREE);
|
|
|
+ };
|
|
|
for (auto blockedTile : town->getBlockedPos())
|
|
|
{
|
|
|
- gen->foreach_neighbour(blockedTile, [this](const int3 & pos)
|
|
|
- {
|
|
|
- if (gen->isPossible(pos))
|
|
|
- gen->setOccupied(pos, ETileType::FREE);
|
|
|
- });
|
|
|
+ gen->foreach_neighbour(blockedTile, clearPos);
|
|
|
}
|
|
|
+ //clear town entry
|
|
|
+ gen->foreach_neighbour(town->visitablePos()+int3{0,1,0}, clearPos);
|
|
|
};
|
|
|
|
|
|
auto addNewTowns = [&totalTowns, this, &cutPathAroundTown](int count, bool hasFort, PlayerColor player)
|
|
@@ -1294,53 +1301,39 @@ void CRmgTemplateZone::paintZoneTerrain (ETerrainType terrainType)
|
|
|
|
|
|
bool CRmgTemplateZone::placeMines ()
|
|
|
{
|
|
|
- static const Res::ERes woodOre[] = {Res::ERes::WOOD, Res::ERes::ORE};
|
|
|
- static const Res::ERes preciousResources[] = {Res::ERes::GEMS, Res::ERes::CRYSTAL, Res::ERes::MERCURY, Res::ERes::SULFUR};
|
|
|
-
|
|
|
- std::array<TObjectTypeHandler, 7> factory =
|
|
|
+ using namespace Res;
|
|
|
+ static const std::map<ERes, int> mineValue{{ERes::WOOD, 1500}, {ERes::ORE, 1500}, {ERes::GEMS, 3500}, {ERes::CRYSTAL, 3500}, {ERes::MERCURY, 3500}, {ERes::SULFUR, 3500}, {ERes::GOLD, 7000}};
|
|
|
+
|
|
|
+ std::vector<CGMine*> createdMines;
|
|
|
+
|
|
|
+ for(const auto & mineInfo : mines)
|
|
|
{
|
|
|
- VLC->objtypeh->getHandlerFor(Obj::MINE, 0),
|
|
|
- VLC->objtypeh->getHandlerFor(Obj::MINE, 1),
|
|
|
- VLC->objtypeh->getHandlerFor(Obj::MINE, 2),
|
|
|
- VLC->objtypeh->getHandlerFor(Obj::MINE, 3),
|
|
|
- VLC->objtypeh->getHandlerFor(Obj::MINE, 4),
|
|
|
- VLC->objtypeh->getHandlerFor(Obj::MINE, 5),
|
|
|
- VLC->objtypeh->getHandlerFor(Obj::MINE, 6)
|
|
|
- };
|
|
|
-
|
|
|
- for (const auto & res : woodOre)
|
|
|
- {
|
|
|
- for (int i = 0; i < mines[res]; i++)
|
|
|
+ ERes res = (ERes)mineInfo.first;
|
|
|
+ for(int i = 0; i < mineInfo.second; ++i)
|
|
|
{
|
|
|
- auto mine = (CGMine *) factory.at(static_cast<si32>(res))->create(ObjectTemplate());
|
|
|
+ auto mine = (CGMine*) VLC->objtypeh->getHandlerFor(Obj::MINE, res)->create(ObjectTemplate());
|
|
|
mine->producedResource = res;
|
|
|
mine->tempOwner = PlayerColor::NEUTRAL;
|
|
|
mine->producedQuantity = mine->defaultResProduction();
|
|
|
- if (!i)
|
|
|
- addCloseObject(mine, 1500); //only firts one is close
|
|
|
+ createdMines.push_back(mine);
|
|
|
+
|
|
|
+ if(!i && (res == ERes::WOOD || res == ERes::ORE))
|
|
|
+ addCloseObject(mine, mineValue.at(res)); //only first woor&ore mines are close
|
|
|
else
|
|
|
- addRequiredObject(mine, 1500);
|
|
|
+ addRequiredObject(mine, mineValue.at(res));
|
|
|
}
|
|
|
}
|
|
|
- for (const auto & res : preciousResources)
|
|
|
+
|
|
|
+ //create extra resources
|
|
|
+ for(auto * mine : createdMines)
|
|
|
{
|
|
|
- for (int i = 0; i < mines[res]; i++)
|
|
|
+ for(int rc = gen->rand.nextInt(1, 3); rc > 0; --rc)
|
|
|
{
|
|
|
- auto mine = (CGMine *) factory.at(static_cast<si32>(res))->create(ObjectTemplate());
|
|
|
- mine->producedResource = res;
|
|
|
- mine->tempOwner = PlayerColor::NEUTRAL;
|
|
|
- mine->producedQuantity = mine->defaultResProduction();
|
|
|
- addRequiredObject(mine, 3500);
|
|
|
+ auto resourse = (CGResource*) VLC->objtypeh->getHandlerFor(Obj::RESOURCE, mine->producedResource)->create(ObjectTemplate());
|
|
|
+ resourse->amount = CGResource::RANDOM_AMOUNT;
|
|
|
+ addNearbyObject(resourse, mine);
|
|
|
}
|
|
|
}
|
|
|
- for (int i = 0; i < mines[Res::GOLD]; i++)
|
|
|
- {
|
|
|
- auto mine = (CGMine *) factory.at(Res::GOLD)->create(ObjectTemplate());
|
|
|
- mine->producedResource = Res::GOLD;
|
|
|
- mine->tempOwner = PlayerColor::NEUTRAL;
|
|
|
- mine->producedQuantity = mine->defaultResProduction();
|
|
|
- addRequiredObject(mine, 7000);
|
|
|
- }
|
|
|
|
|
|
return true;
|
|
|
}
|
|
@@ -1463,6 +1456,38 @@ bool CRmgTemplateZone::createRequiredObjects()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ //create nearby objects (e.g. extra resources close to mines)
|
|
|
+ for(const auto & object : nearbyObjects)
|
|
|
+ {
|
|
|
+ auto obj = object.first;
|
|
|
+ std::set<int3> possiblePositions;
|
|
|
+ for (auto blockedTile : object.second->getBlockedPos())
|
|
|
+ {
|
|
|
+ gen->foreachDirectNeighbour(blockedTile, [this, &possiblePositions](int3 pos)
|
|
|
+ {
|
|
|
+ if (!gen->isBlocked(pos))
|
|
|
+ {
|
|
|
+ //some resources still could be unaccessible, at least one free cell shall be
|
|
|
+ gen->foreach_neighbour(pos, [this, &possiblePositions, &pos](int3 p)
|
|
|
+ {
|
|
|
+ if(gen->isFree(p))
|
|
|
+ possiblePositions.insert(pos);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ if(possiblePositions.empty())
|
|
|
+ {
|
|
|
+ delete obj; //is it correct way to prevent leak?
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ auto pos = *RandomGeneratorUtil::nextItem(possiblePositions, gen->rand);
|
|
|
+ placeObject(obj, pos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
return true;
|
|
|
}
|
|
|
|