mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-28 23:06:24 +02:00
Introduced 3-value logic for free, blocked and possibly occupied tiles. Refactoring.
This commit is contained in:
parent
8ea175ce95
commit
8c24ea0bfb
@ -21,9 +21,6 @@
|
||||
#include "../../lib/NetPacks.h"
|
||||
#include "../../lib/CondSh.h"
|
||||
|
||||
static const int3 dirs[] = { int3(0,1,0),int3(0,-1,0),int3(-1,0,0),int3(+1,0,0),
|
||||
int3(1,1,0),int3(-1,1,0),int3(1,-1,0),int3(-1,-1,0) };
|
||||
|
||||
struct QuestInfo;
|
||||
|
||||
/*
|
||||
|
@ -450,6 +450,17 @@ namespace EWallState
|
||||
};
|
||||
}
|
||||
|
||||
namespace ETileType
|
||||
{
|
||||
enum ETileType
|
||||
{
|
||||
FREE,
|
||||
POSSIBLE,
|
||||
BLOCKED,
|
||||
USED
|
||||
};
|
||||
}
|
||||
|
||||
class Obj
|
||||
{
|
||||
public:
|
||||
|
@ -152,4 +152,7 @@ struct ShashInt3
|
||||
vstd::hash_combine(ret, pos.z);
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
static const int3 dirs[] = { int3(0,1,0),int3(0,-1,0),int3(-1,0,0),int3(+1,0,0),
|
||||
int3(1,1,0),int3(-1,1,0),int3(1,-1,0),int3(-1,-1,0) };
|
@ -16,12 +16,12 @@
|
||||
|
||||
void CMapGenerator::foreach_neighbour(const int3 &pos, std::function<void(const int3& pos)> foo)
|
||||
{
|
||||
//for(const int3 &dir : dirs)
|
||||
//{
|
||||
// const int3 n = pos + dir;
|
||||
// if(map->isInTheMap(n))
|
||||
// foo(pos+dir);
|
||||
//}
|
||||
for(const int3 &dir : dirs)
|
||||
{
|
||||
const int3 n = pos + dir;
|
||||
if(map->isInTheMap(n))
|
||||
foo(pos+dir);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -31,9 +31,40 @@ CMapGenerator::CMapGenerator(shared_ptr<CMapGenOptions> mapGenOptions, int rando
|
||||
rand.setSeed(randomSeed);
|
||||
}
|
||||
|
||||
void CMapGenerator::initTiles()
|
||||
{
|
||||
map->initTerrain();
|
||||
|
||||
int width = map->width;
|
||||
int height = map->height;
|
||||
|
||||
int level = map->twoLevel ? 2 : 1;
|
||||
tiles = new CTileInfo**[width];
|
||||
for (int i = 0; i < width; ++i)
|
||||
{
|
||||
tiles[i] = new CTileInfo*[height];
|
||||
for (int j = 0; j < height; ++j)
|
||||
{
|
||||
tiles[i][j] = new CTileInfo[level];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CMapGenerator::~CMapGenerator()
|
||||
{
|
||||
|
||||
//FIXME: what if map is not present anymore?
|
||||
if (tiles && map)
|
||||
{
|
||||
for (int i=0; i < map->width; i++)
|
||||
{
|
||||
for(int j=0; j < map->height; j++)
|
||||
{
|
||||
delete [] tiles[i][j];
|
||||
}
|
||||
delete [] tiles[i];
|
||||
}
|
||||
delete [] tiles;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<CMap> CMapGenerator::generate()
|
||||
@ -46,6 +77,7 @@ std::unique_ptr<CMap> CMapGenerator::generate()
|
||||
{
|
||||
editManager->getUndoManager().setUndoRedoLimit(0);
|
||||
addHeaderInfo();
|
||||
initTiles();
|
||||
|
||||
genZones();
|
||||
map->calculateGuardingGreaturePositions(); //clear map so that all tiles are unguarded
|
||||
@ -146,7 +178,6 @@ void CMapGenerator::addPlayerInfo()
|
||||
|
||||
void CMapGenerator::genZones()
|
||||
{
|
||||
map->initTerrain();
|
||||
editManager->clearTerrain(&rand);
|
||||
editManager->getTerrainSelection().selectRange(MapRect(int3(0, 0, 0), mapGenOptions->getWidth(), mapGenOptions->getHeight()));
|
||||
editManager->drawTerrain(ETerrainType::GRASS, &rand);
|
||||
@ -217,3 +248,39 @@ std::map<TRmgTemplateZoneId, CRmgTemplateZone*> CMapGenerator::getZones() const
|
||||
{
|
||||
return zones;
|
||||
}
|
||||
|
||||
bool CMapGenerator::isBlocked(int3 &tile) const
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z].isBlocked();
|
||||
}
|
||||
bool CMapGenerator::shouldBeBlocked(int3 &tile) const
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z].shouldBeBlocked();
|
||||
}
|
||||
bool CMapGenerator::isPossible(int3 &tile) const
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z].isPossible();
|
||||
}
|
||||
bool CMapGenerator::isFree(int3 &tile) const
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
|
||||
return tiles[tile.x][tile.y][tile.z].isFree();
|
||||
}
|
||||
void CMapGenerator::setOccupied(int3 &tile, ETileType::ETileType state)
|
||||
{
|
||||
if (!map->isInTheMap(tile))
|
||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||
|
||||
tiles[tile.x][tile.y][tile.z].setOccupied(state);
|
||||
}
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "../GameConstants.h"
|
||||
#include "../CRandomGenerator.h"
|
||||
#include "CMapGenOptions.h"
|
||||
#include "CRmgTemplateZone.h"
|
||||
#include "../CObjectHandler.h"
|
||||
#include "../int3.h"
|
||||
|
||||
@ -24,14 +25,11 @@ class CMapGenOptions;
|
||||
class CTerrainViewPatternConfig;
|
||||
class CMapEditManager;
|
||||
class JsonNode;
|
||||
class CMapGenerator;
|
||||
class CTileInfo;
|
||||
|
||||
typedef std::vector<JsonNode> JsonVector;
|
||||
|
||||
class CMapGenerator;
|
||||
|
||||
//static const int3 dirs[] = { int3(0,1,0),int3(0,-1,0),int3(-1,0,0),int3(+1,0,0),
|
||||
// int3(1,1,0),int3(-1,1,0),int3(1,-1,0),int3(-1,-1,0) };
|
||||
|
||||
class rmgException : std::exception
|
||||
{
|
||||
std::string msg;
|
||||
@ -68,19 +66,23 @@ public:
|
||||
std::map<TRmgTemplateZoneId, CRmgTemplateZone*> getZones() const;
|
||||
void foreach_neighbour(const int3 &pos, std::function<void(const int3& pos)> foo);
|
||||
|
||||
bool isBlocked(int3 &tile) const;
|
||||
bool shouldBeBlocked(int3 &tile) const;
|
||||
bool isPossible(int3 &tile) const;
|
||||
bool isFree(int3 &tile) const;
|
||||
void setOccupied(int3 &tile, ETileType::ETileType state);
|
||||
|
||||
private:
|
||||
std::map<TRmgTemplateZoneId, CRmgTemplateZone*> zones;
|
||||
|
||||
CTileInfo*** tiles;
|
||||
|
||||
/// Generation methods
|
||||
std::string getMapDescription() const;
|
||||
void addPlayerInfo();
|
||||
void addHeaderInfo();
|
||||
void initTiles();
|
||||
void genZones();
|
||||
void fillZones();
|
||||
|
||||
};
|
||||
|
||||
/* ---------------------------------------------------------------------------- */
|
||||
/* Implementation/Detail classes, Private API */
|
||||
/* ---------------------------------------------------------------------------- */
|
||||
|
||||
};
|
@ -73,47 +73,47 @@ void CRmgTemplateZone::CTownInfo::setCastleDensity(int value)
|
||||
castleDensity = value;
|
||||
}
|
||||
|
||||
CRmgTemplateZone::CTileInfo::CTileInfo():nearestObjectDistance(INT_MAX), obstacle(false), occupied(false), terrain(ETerrainType::WRONG)
|
||||
CTileInfo::CTileInfo():nearestObjectDistance(INT_MAX), terrain(ETerrainType::WRONG)
|
||||
{
|
||||
|
||||
occupied = ETileType::POSSIBLE; //all tiles are initially possible to place objects or passages
|
||||
}
|
||||
|
||||
int CRmgTemplateZone::CTileInfo::getNearestObjectDistance() const
|
||||
int CTileInfo::getNearestObjectDistance() const
|
||||
{
|
||||
return nearestObjectDistance;
|
||||
}
|
||||
|
||||
void CRmgTemplateZone::CTileInfo::setNearestObjectDistance(int value)
|
||||
void CTileInfo::setNearestObjectDistance(int value)
|
||||
{
|
||||
nearestObjectDistance = std::max(0, value); //never negative (or unitialized)
|
||||
}
|
||||
|
||||
bool CRmgTemplateZone::CTileInfo::isObstacle() const
|
||||
bool CTileInfo::shouldBeBlocked() const
|
||||
{
|
||||
return obstacle;
|
||||
return occupied == ETileType::BLOCKED;
|
||||
}
|
||||
|
||||
void CRmgTemplateZone::CTileInfo::setObstacle(bool value)
|
||||
bool CTileInfo::isBlocked() const
|
||||
{
|
||||
obstacle = value;
|
||||
return occupied == ETileType::BLOCKED || occupied == ETileType::USED;
|
||||
}
|
||||
|
||||
bool CRmgTemplateZone::CTileInfo::isOccupied() const
|
||||
bool CTileInfo::isPossible() const
|
||||
{
|
||||
return occupied;
|
||||
return occupied == ETileType::POSSIBLE;
|
||||
}
|
||||
|
||||
void CRmgTemplateZone::CTileInfo::setOccupied(bool value)
|
||||
bool CTileInfo::isFree() const
|
||||
{
|
||||
return occupied == ETileType::FREE;
|
||||
}
|
||||
void CTileInfo::setOccupied(ETileType::ETileType value)
|
||||
{
|
||||
occupied = value;
|
||||
}
|
||||
|
||||
ETerrainType CRmgTemplateZone::CTileInfo::getTerrainType() const
|
||||
ETerrainType CTileInfo::getTerrainType() const
|
||||
{
|
||||
return terrain;
|
||||
}
|
||||
|
||||
void CRmgTemplateZone::CTileInfo::setTerrainType(ETerrainType value)
|
||||
void CTileInfo::setTerrainType(ETerrainType value)
|
||||
{
|
||||
terrain = value;
|
||||
}
|
||||
@ -285,7 +285,7 @@ float3 CRmgTemplateZone::getCenter() const
|
||||
{
|
||||
return center;
|
||||
}
|
||||
void CRmgTemplateZone::setCenter(float3 f)
|
||||
void CRmgTemplateZone::setCenter(const float3 &f)
|
||||
{
|
||||
//limit boundaries to (0,1) square
|
||||
center = float3 (std::min(std::max(f.x, 0.f), 1.f), std::min(std::max(f.y, 0.f), 1.f), f.z);
|
||||
@ -302,7 +302,7 @@ void CRmgTemplateZone::setShape(std::vector<int3> shape)
|
||||
this->shape = shape;
|
||||
}
|
||||
|
||||
int3 CRmgTemplateZone::getPos()
|
||||
int3 CRmgTemplateZone::getPos() const
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
@ -441,7 +441,7 @@ bool CRmgTemplateZone::fill(CMapGenerator* gen)
|
||||
sel.clearSelection();
|
||||
for(auto it = tileinfo.begin(); it != tileinfo.end(); ++it)
|
||||
{
|
||||
if (it->second.isObstacle())
|
||||
if (it->second.shouldBeBlocked()) //fill tiles that should be blocked with obstacles
|
||||
{
|
||||
auto obj = new CGObjectInstance();
|
||||
obj->ID = static_cast<Obj>(130);
|
||||
@ -473,7 +473,7 @@ bool CRmgTemplateZone::findPlaceForObject(CMapGenerator* gen, CGObjectInstance*
|
||||
//avoid borders
|
||||
if ((p.x < 3) || (w - p.x < 3) || (p.y < 3) || (h - p.y < 3))
|
||||
continue;
|
||||
if (!ti.isOccupied() && !ti.isObstacle() && (dist >= min_dist) && (dist > best_distance))
|
||||
if (!ti.isBlocked() && (dist >= min_dist) && (dist > best_distance))
|
||||
{
|
||||
best_distance = dist;
|
||||
pos = p;
|
||||
@ -521,7 +521,7 @@ void CRmgTemplateZone::placeObject(CMapGenerator* gen, CGObjectInstance* object,
|
||||
{
|
||||
if (tileinfo.find(pos + p) != tileinfo.end())
|
||||
{
|
||||
tileinfo[pos + p].setOccupied(true);
|
||||
tileinfo[pos + p].setOccupied(ETileType::USED);
|
||||
}
|
||||
}
|
||||
for(auto it = tileinfo.begin(); it != tileinfo.end(); ++it)
|
||||
@ -547,10 +547,10 @@ bool CRmgTemplateZone::guardObject(CMapGenerator* gen, CGObjectInstance* object,
|
||||
if (it->first != visitable)
|
||||
{
|
||||
logGlobal->traceStream() << boost::format("Block at %d %d") % it->first.x % it->first.y;
|
||||
if (!it->second.isOccupied() && !it->second.isObstacle())
|
||||
if (it->second.isPossible())
|
||||
{
|
||||
tiles.push_back(it->first);
|
||||
it->second.setObstacle(true);
|
||||
it->second.setOccupied(ETileType::BLOCKED);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -562,7 +562,7 @@ bool CRmgTemplateZone::guardObject(CMapGenerator* gen, CGObjectInstance* object,
|
||||
return false;
|
||||
}
|
||||
auto guard_tile = *RandomGeneratorUtil::nextItem(tiles, gen->rand);
|
||||
tileinfo[guard_tile].setObstacle(false);
|
||||
tileinfo[guard_tile].setOccupied(ETileType::USED);
|
||||
auto guard = new CGCreature();
|
||||
guard->ID = Obj::RANDOM_MONSTER;
|
||||
guard->subID = 0;
|
||||
|
@ -14,19 +14,44 @@
|
||||
#include "../GameConstants.h"
|
||||
#include "CMapGenerator.h"
|
||||
#include "float3.h"
|
||||
#include "../int3.h"
|
||||
|
||||
class CMapgenerator;
|
||||
class CMapGenerator;
|
||||
class CTileInfo;
|
||||
class int3;
|
||||
class CGObjectInstance;
|
||||
|
||||
namespace ETemplateZoneType
|
||||
{
|
||||
enum ETemplateZoneType
|
||||
{
|
||||
PLAYER_START,
|
||||
CPU_START,
|
||||
TREASURE,
|
||||
JUNCTION
|
||||
};
|
||||
enum ETemplateZoneType
|
||||
{
|
||||
PLAYER_START,
|
||||
CPU_START,
|
||||
TREASURE,
|
||||
JUNCTION
|
||||
};
|
||||
}
|
||||
class DLL_LINKAGE CTileInfo
|
||||
{
|
||||
public:
|
||||
|
||||
CTileInfo();
|
||||
|
||||
int getNearestObjectDistance() const;
|
||||
void setNearestObjectDistance(int value);
|
||||
bool isBlocked() const;
|
||||
bool shouldBeBlocked() const;
|
||||
bool isPossible() const;
|
||||
bool isFree() const;
|
||||
void setOccupied(ETileType::ETileType value);
|
||||
ETerrainType getTerrainType() const;
|
||||
void setTerrainType(ETerrainType value);
|
||||
|
||||
private:
|
||||
int nearestObjectDistance;
|
||||
ETileType::ETileType occupied;
|
||||
ETerrainType terrain;
|
||||
};
|
||||
|
||||
/// The CRmgTemplateZone describes a zone in a template.
|
||||
class DLL_LINKAGE CRmgTemplateZone
|
||||
@ -49,27 +74,6 @@ public:
|
||||
private:
|
||||
int townCount, castleCount, townDensity, castleDensity;
|
||||
};
|
||||
|
||||
class DLL_LINKAGE CTileInfo
|
||||
{
|
||||
public:
|
||||
CTileInfo();
|
||||
|
||||
int getNearestObjectDistance() const;
|
||||
void setNearestObjectDistance(int value);
|
||||
bool isObstacle() const;
|
||||
void setObstacle(bool value);
|
||||
bool isOccupied() const;
|
||||
void setOccupied(bool value);
|
||||
ETerrainType getTerrainType() const;
|
||||
void setTerrainType(ETerrainType value);
|
||||
|
||||
private:
|
||||
int nearestObjectDistance;
|
||||
bool obstacle;
|
||||
bool occupied;
|
||||
ETerrainType terrain;
|
||||
};
|
||||
|
||||
CRmgTemplateZone();
|
||||
|
||||
@ -101,8 +105,8 @@ public:
|
||||
void setTownTypeLikeZone(boost::optional<TRmgTemplateZoneId> value);
|
||||
|
||||
float3 getCenter() const;
|
||||
void setCenter(float3 f);
|
||||
int3 getPos();
|
||||
void setCenter(const float3 &f);
|
||||
int3 getPos() const;
|
||||
void setPos(const int3 &pos);
|
||||
|
||||
void addTile (const int3 &pos);
|
||||
|
Loading…
Reference in New Issue
Block a user