mirror of
https://github.com/vcmi/vcmi.git
synced 2025-02-15 13:33:36 +02:00
Wood & ore mines will be placed close to zone center.
This commit is contained in:
parent
485b2ac688
commit
fee2184996
@ -605,6 +605,10 @@ void CRmgTemplateZone::addRequiredObject(CGObjectInstance * obj, si32 strength)
|
||||
{
|
||||
requiredObjects.push_back(std::make_pair(obj, strength));
|
||||
}
|
||||
void CRmgTemplateZone::addCloseObject(CGObjectInstance * obj, si32 strength)
|
||||
{
|
||||
closeObjects.push_back(std::make_pair(obj, strength));
|
||||
}
|
||||
|
||||
bool CRmgTemplateZone::addMonster(CMapGenerator* gen, int3 &pos, si32 strength, bool clearSurroundingTiles, bool zoneGuard)
|
||||
{
|
||||
@ -1109,11 +1113,8 @@ bool CRmgTemplateZone::placeMines (CMapGenerator* gen)
|
||||
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};
|
||||
|
||||
|
||||
//TODO: factory / copy constructor?
|
||||
for (const auto & res : woodOre)
|
||||
{
|
||||
//TODO: these 2 should be close to town (within 12 tiles radius)
|
||||
for (int i = 0; i < mines[res]; i++)
|
||||
{
|
||||
auto mine = new CGMine();
|
||||
@ -1121,7 +1122,7 @@ bool CRmgTemplateZone::placeMines (CMapGenerator* gen)
|
||||
mine->subID = static_cast<si32>(res);
|
||||
mine->producedResource = res;
|
||||
mine->producedQuantity = mine->defaultResProduction();
|
||||
addRequiredObject(mine, 1500);
|
||||
addCloseObject(mine, 1500);
|
||||
}
|
||||
}
|
||||
for (const auto & res : preciousResources)
|
||||
@ -1166,6 +1167,49 @@ bool CRmgTemplateZone::createRequiredObjects(CMapGenerator* gen)
|
||||
guardObject (gen, obj.first, obj.second, (obj.first->ID == Obj::MONOLITH_TWO_WAY), true);
|
||||
//paths to required objects constitute main paths of zone. otherwise they just may lead to middle and create dead zones
|
||||
}
|
||||
|
||||
for (const auto &obj : closeObjects)
|
||||
{
|
||||
std::vector<int3> tiles(possibleTiles.begin(), possibleTiles.end()); //new tiles vector after each object has been placed
|
||||
|
||||
// smallest distance to zone center, greatest distance to nearest object
|
||||
auto isCloser = [this, gen](const int3 & lhs, const int3 & rhs) -> bool
|
||||
{
|
||||
return (this->pos.dist2dSQ(lhs) * 0.5f - gen->getNearestObjectDistance(lhs)) < (this->pos.dist2dSQ(rhs) * 0.5f - gen->getNearestObjectDistance(rhs));
|
||||
};
|
||||
|
||||
boost::sort (tiles, isCloser);
|
||||
|
||||
setTemplateForObject(gen, obj.first);
|
||||
auto tilesBlockedByObject = obj.first->getBlockedOffsets();
|
||||
bool result = false;
|
||||
|
||||
for (auto tile : tiles)
|
||||
{
|
||||
//object must be accessible from at least one surounding tile
|
||||
if (!isAccessibleFromAnywhere(gen, obj.first->appearance, tile, tilesBlockedByObject))
|
||||
continue;
|
||||
|
||||
//avoid borders
|
||||
if (gen->isPossible(tile))
|
||||
{
|
||||
if (areAllTilesAvailable(gen, obj.first, tile, tilesBlockedByObject))
|
||||
{
|
||||
placeObject(gen, obj.first, tile);
|
||||
guardObject(gen, obj.first, obj.second, (obj.first->ID == Obj::MONOLITH_TWO_WAY), true);
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!result)
|
||||
{
|
||||
logGlobal->errorStream() << boost::format("Failed to fill zone %d due to lack of space") % id;
|
||||
//TODO CLEANUP!
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1441,17 +1485,36 @@ bool CRmgTemplateZone::isAccessibleFromAnywhere (CMapGenerator* gen, ObjectTempl
|
||||
return accessible;
|
||||
}
|
||||
|
||||
bool CRmgTemplateZone::findPlaceForObject(CMapGenerator* gen, CGObjectInstance* obj, si32 min_dist, int3 &pos)
|
||||
void CRmgTemplateZone::setTemplateForObject(CMapGenerator* gen, CGObjectInstance* obj)
|
||||
{
|
||||
//we need object apperance to deduce free tiles
|
||||
if (obj->appearance.id == Obj::NO_OBJ)
|
||||
{
|
||||
auto templates = VLC->objtypeh->getHandlerFor(obj->ID, obj->subID)->getTemplates(gen->map->getTile(getPos()).terType);
|
||||
if (templates.empty())
|
||||
throw rmgException(boost::to_string(boost::format("Did not find graphics for object (%d,%d) at %s") %obj->ID %obj->subID %pos));
|
||||
|
||||
throw rmgException(boost::to_string(boost::format("Did not find graphics for object (%d,%d) at %s") % obj->ID %obj->subID %pos));
|
||||
|
||||
obj->appearance = templates.front();
|
||||
}
|
||||
}
|
||||
|
||||
bool CRmgTemplateZone::areAllTilesAvailable(CMapGenerator* gen, CGObjectInstance* obj, int3& tile, std::set<int3>& tilesBlockedByObject) const
|
||||
{
|
||||
for (auto blockingTile : tilesBlockedByObject)
|
||||
{
|
||||
int3 t = tile + blockingTile;
|
||||
if (!gen->map->isInTheMap(t) || !gen->isPossible(t))
|
||||
{
|
||||
//if at least one tile is not possible, object can't be placed here
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CRmgTemplateZone::findPlaceForObject(CMapGenerator* gen, CGObjectInstance* obj, si32 min_dist, int3 &pos)
|
||||
{
|
||||
//we need object apperance to deduce free tile
|
||||
setTemplateForObject(gen, obj);
|
||||
|
||||
//si32 min_dist = sqrt(tileinfo.size()/density);
|
||||
int best_distance = 0;
|
||||
@ -1474,17 +1537,7 @@ bool CRmgTemplateZone::findPlaceForObject(CMapGenerator* gen, CGObjectInstance*
|
||||
//avoid borders
|
||||
if (gen->isPossible(tile) && (dist >= min_dist) && (dist > best_distance))
|
||||
{
|
||||
bool allTilesAvailable = true;
|
||||
for (auto blockingTile : tilesBlockedByObject)
|
||||
{
|
||||
int3 t = tile + blockingTile;
|
||||
if (!gen->map->isInTheMap(t) || !gen->isPossible(t))
|
||||
{
|
||||
allTilesAvailable = false; //if at least one tile is not possible, object can't be placed here
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (allTilesAvailable)
|
||||
if (areAllTilesAvailable(gen, obj, tile, tilesBlockedByObject))
|
||||
{
|
||||
best_distance = dist;
|
||||
pos = tile;
|
||||
|
@ -150,6 +150,7 @@ public:
|
||||
void discardDistantTiles (CMapGenerator* gen, float distance);
|
||||
|
||||
void addRequiredObject(CGObjectInstance * obj, si32 guardStrength=0);
|
||||
void addCloseObject(CGObjectInstance * obj, si32 guardStrength = 0);
|
||||
bool addMonster(CMapGenerator* gen, int3 &pos, si32 strength, bool clearSurroundingTiles = true, bool zoneGuard = false);
|
||||
bool createTreasurePile(CMapGenerator* gen, int3 &pos, float minDistance, const CTreasureInfo& treasureInfo);
|
||||
bool fill (CMapGenerator* gen);
|
||||
@ -198,6 +199,7 @@ private:
|
||||
|
||||
//content info
|
||||
std::vector<std::pair<CGObjectInstance*, ui32>> requiredObjects;
|
||||
std::vector<std::pair<CGObjectInstance*, ui32>> closeObjects;
|
||||
std::vector<CGObjectInstance*> objects;
|
||||
|
||||
//placement info
|
||||
@ -214,6 +216,8 @@ private:
|
||||
bool findPlaceForObject(CMapGenerator* gen, CGObjectInstance* obj, si32 min_dist, int3 &pos);
|
||||
bool findPlaceForTreasurePile(CMapGenerator* gen, float min_dist, int3 &pos);
|
||||
bool canObstacleBePlacedHere(CMapGenerator* gen, ObjectTemplate &temp, int3 &pos);
|
||||
void setTemplateForObject(CMapGenerator* gen, CGObjectInstance* obj);
|
||||
bool areAllTilesAvailable(CMapGenerator* gen, CGObjectInstance* obj, int3& tile, std::set<int3>& tilesBlockedByObject) const;
|
||||
void checkAndPlaceObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos);
|
||||
void placeObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos, bool updateDistance = true);
|
||||
bool guardObject(CMapGenerator* gen, CGObjectInstance* object, si32 str, bool zoneGuard = false, bool addToFreePaths = false);
|
||||
|
Loading…
x
Reference in New Issue
Block a user