mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Create random obstacles that match terrain.
This commit is contained in:
parent
7aa8213cd5
commit
920f56969b
@ -15,7 +15,7 @@ SPELLS:
|
||||
* New configuration format: http://wiki.vcmi.eu/index.php?title=Spell_Format
|
||||
|
||||
RANDOM MAP GENERATOR
|
||||
* Towns form mods cna be used
|
||||
* Towns from mods can be used
|
||||
* Reading connections, terrains, towns and mines from template
|
||||
* Zone placement
|
||||
* Zone borders and connections, fractalized paths inside zones
|
||||
|
@ -178,16 +178,7 @@ std::set<int3> CGObjectInstance::getBlockedPos() const
|
||||
|
||||
std::set<int3> CGObjectInstance::getBlockedOffsets() const
|
||||
{
|
||||
std::set<int3> ret;
|
||||
for(int w=0; w<getWidth(); ++w)
|
||||
{
|
||||
for(int h=0; h<getHeight(); ++h)
|
||||
{
|
||||
if (appearance.isBlockedAt(w, h))
|
||||
ret.insert(int3(-w, -h, 0));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
return appearance.getBlockedOffsets();
|
||||
}
|
||||
|
||||
void CGObjectInstance::setType(si32 ID, si32 subID)
|
||||
|
@ -308,6 +308,33 @@ bool ObjectTemplate::isBlockedAt(si32 X, si32 Y) const
|
||||
return false;
|
||||
}
|
||||
|
||||
std::set<int3> ObjectTemplate::getBlockedOffsets() const
|
||||
{
|
||||
std::set<int3> ret;
|
||||
for(int w = 0; w < getWidth(); ++w)
|
||||
{
|
||||
for(int h = 0; h < getHeight(); ++h)
|
||||
{
|
||||
if (isBlockedAt(w, h))
|
||||
ret.insert(int3(-w, -h, 0));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int3 ObjectTemplate::getBlockMapOffset() const
|
||||
{
|
||||
for(int w = 0; w < getWidth(); ++w)
|
||||
{
|
||||
for(int h = 0; h < getHeight(); ++h)
|
||||
{
|
||||
if (isBlockedAt(w, h))
|
||||
return int3(-w, -h, 0);
|
||||
}
|
||||
}
|
||||
return int3(-1,-1,-1);
|
||||
}
|
||||
|
||||
bool ObjectTemplate::isVisitableFrom(si8 X, si8 Y) const
|
||||
{
|
||||
// visitDir uses format
|
||||
|
@ -15,6 +15,7 @@
|
||||
class CBinaryReader;
|
||||
class CLegacyConfigParser;
|
||||
class JsonNode;
|
||||
class int3;
|
||||
|
||||
class DLL_LINKAGE ObjectTemplate
|
||||
{
|
||||
@ -56,6 +57,8 @@ public:
|
||||
bool isVisitableAt(si32 X, si32 Y) const;
|
||||
bool isVisibleAt(si32 X, si32 Y) const;
|
||||
bool isBlockedAt(si32 X, si32 Y) const;
|
||||
std::set<int3> getBlockedOffsets() const;
|
||||
int3 getBlockMapOffset() const; //bottom-right corner when firts blocked tile is
|
||||
|
||||
// Checks if object is visitable from certain direction. X and Y must be between -1..+1
|
||||
bool isVisitableFrom(si8 X, si8 Y) const;
|
||||
|
@ -962,20 +962,49 @@ void CRmgTemplateZone::createTreasures(CMapGenerator* gen)
|
||||
|
||||
void CRmgTemplateZone::createObstacles(CMapGenerator* gen)
|
||||
{
|
||||
//get all possible obstacles for this terrain
|
||||
for (auto primaryID : VLC->objtypeh->knownObjects())
|
||||
{
|
||||
for (auto secondaryID : VLC->objtypeh->knownSubObjects(primaryID))
|
||||
{
|
||||
auto handler = VLC->objtypeh->getHandlerFor(primaryID, secondaryID);
|
||||
if (handler->isStaticObject())
|
||||
{
|
||||
for (auto temp : handler->getTemplates())
|
||||
{
|
||||
if (temp.canBePlacedAt(terrainType) && temp.getBlockMapOffset().valid())
|
||||
possibleObstacles.push_back(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto sel = gen->editManager->getTerrainSelection();
|
||||
sel.clearSelection();
|
||||
|
||||
auto tryToPlaceObstacleHere = [this, gen](int3& tile)-> bool
|
||||
{
|
||||
auto temp = *RandomGeneratorUtil::nextItem(possibleObstacles, gen->rand);
|
||||
int3 obstaclePos = tile + temp.getBlockMapOffset();
|
||||
if (canObstacleBePlacedHere(gen, temp, obstaclePos)) //can be placed here
|
||||
{
|
||||
auto obj = VLC->objtypeh->getHandlerFor(temp.id, temp.subid)->create(temp);
|
||||
placeObject(gen, obj, obstaclePos);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
for (auto tile : tileinfo)
|
||||
{
|
||||
//test code - block all the map to show paths clearly
|
||||
//if (gen->isPossible(tile))
|
||||
// gen->setOccupied(tile, ETileType::BLOCKED);
|
||||
|
||||
if (gen->shouldBeBlocked(tile)) //fill tiles that should be blocked with obstacles
|
||||
{
|
||||
auto obj = new CGObjectInstance();
|
||||
obj->ID = static_cast<Obj>(57);
|
||||
obj->subID = 0;
|
||||
placeObject(gen, obj, tile);
|
||||
while (!tryToPlaceObstacleHere(tile));
|
||||
}
|
||||
else if (gen->isPossible(tile))
|
||||
{
|
||||
//try to place random obstacle once - if not possible, leave it clear
|
||||
tryToPlaceObstacleHere(tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1031,6 +1060,23 @@ bool CRmgTemplateZone::findPlaceForTreasurePile(CMapGenerator* gen, si32 min_dis
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CRmgTemplateZone::canObstacleBePlacedHere(CMapGenerator* gen, ObjectTemplate &temp, int3 &pos)
|
||||
{
|
||||
auto tilesBlockedByObject = temp.getBlockedOffsets();
|
||||
|
||||
bool allTilesAvailable = true;
|
||||
for (auto blockingTile : tilesBlockedByObject)
|
||||
{
|
||||
int3 t = pos + blockingTile;
|
||||
if (!gen->map->isInTheMap(t) || !(gen->isPossible(t) || gen->shouldBeBlocked(t)))
|
||||
{
|
||||
allTilesAvailable = false; //if at least one tile is not possible, object can't be placed here
|
||||
break;
|
||||
}
|
||||
}
|
||||
return allTilesAvailable;
|
||||
}
|
||||
|
||||
bool CRmgTemplateZone::findPlaceForObject(CMapGenerator* gen, CGObjectInstance* obj, si32 min_dist, int3 &pos)
|
||||
{
|
||||
//we need object apperance to deduce free tiles
|
||||
|
@ -21,6 +21,7 @@ class CMapGenerator;
|
||||
class CTileInfo;
|
||||
class int3;
|
||||
class CGObjectInstance;
|
||||
class ObjectTemplate;
|
||||
|
||||
namespace ETemplateZoneType
|
||||
{
|
||||
@ -173,6 +174,7 @@ private:
|
||||
ui16 totalDensity;
|
||||
std::vector<CTreasureInfo> treasureInfo;
|
||||
std::vector<ObjectInfo> possibleObjects;
|
||||
std::vector<ObjectTemplate> possibleObstacles;
|
||||
|
||||
//content info
|
||||
std::vector<std::pair<CGObjectInstance*, ui32>> requiredObjects;
|
||||
@ -189,6 +191,7 @@ private:
|
||||
void addAllPossibleObjects (CMapGenerator* gen); //add objects, including zone-specific, to possibleObjects
|
||||
bool findPlaceForObject(CMapGenerator* gen, CGObjectInstance* obj, si32 min_dist, int3 &pos);
|
||||
bool findPlaceForTreasurePile(CMapGenerator* gen, si32 min_dist, int3 &pos);
|
||||
bool canObstacleBePlacedHere(CMapGenerator* gen, ObjectTemplate &temp, int3 &pos);
|
||||
void checkAndPlaceObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos);
|
||||
void placeObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos);
|
||||
bool guardObject(CMapGenerator* gen, CGObjectInstance* object, si32 str);
|
||||
|
Loading…
Reference in New Issue
Block a user