mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
Zone shapes & terrains work nicely.
This commit is contained in:
parent
27dcf70b1a
commit
d2fd71d087
@ -98,6 +98,12 @@ void CTerrainSelection::deselectRange(const MapRect & rect)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CTerrainSelection::setSelection(std::vector<int3> & vec)
|
||||||
|
{
|
||||||
|
for (auto pos : vec)
|
||||||
|
this->select(pos);
|
||||||
|
}
|
||||||
|
|
||||||
void CTerrainSelection::selectAll()
|
void CTerrainSelection::selectAll()
|
||||||
{
|
{
|
||||||
selectRange(MapRect(int3(0, 0, 0), getMap()->width, getMap()->height));
|
selectRange(MapRect(int3(0, 0, 0), getMap()->width, getMap()->height));
|
||||||
|
@ -91,6 +91,7 @@ public:
|
|||||||
void deselectRange(const MapRect & rect) override;
|
void deselectRange(const MapRect & rect) override;
|
||||||
void selectAll() override;
|
void selectAll() override;
|
||||||
void clearSelection() override;
|
void clearSelection() override;
|
||||||
|
void setSelection(std::vector<int3> & vec);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Selection class to select objects.
|
/// Selection class to select objects.
|
||||||
|
@ -154,10 +154,13 @@ void CMapGenerator::genZones()
|
|||||||
|
|
||||||
CZonePlacer placer(this);
|
CZonePlacer placer(this);
|
||||||
placer.placeZones(mapGenOptions, &rand);
|
placer.placeZones(mapGenOptions, &rand);
|
||||||
|
placer.assignZones(mapGenOptions);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
int part_w = w/player_per_side;
|
int part_w = w/player_per_side;
|
||||||
int part_h = h/player_per_side;
|
int part_h = h/player_per_side;
|
||||||
|
|
||||||
|
|
||||||
for(auto const it : zones)
|
for(auto const it : zones)
|
||||||
{
|
{
|
||||||
CRmgTemplateZone * zone = it.second;
|
CRmgTemplateZone * zone = it.second;
|
||||||
|
@ -294,46 +294,46 @@ void CRmgTemplateZone::setCenter(float3 f)
|
|||||||
|
|
||||||
bool CRmgTemplateZone::pointIsIn(int x, int y)
|
bool CRmgTemplateZone::pointIsIn(int x, int y)
|
||||||
{
|
{
|
||||||
int i, j;
|
//int i, j;
|
||||||
bool c = false;
|
//bool c = false;
|
||||||
int nvert = shape.size();
|
//int nvert = shape.size();
|
||||||
for (i = 0, j = nvert-1; i < nvert; j = i++) {
|
//for (i = 0, j = nvert-1; i < nvert; j = i++) {
|
||||||
if ( ((shape[i].y>y) != (shape[j].y>y)) &&
|
// if ( ((shape[i].y>y) != (shape[j].y>y)) &&
|
||||||
(x < (shape[j].x-shape[i].x) * (y-shape[i].y) / (shape[j].y-shape[i].y) + shape[i].x) )
|
// (x < (shape[j].x-shape[i].x) * (y-shape[i].y) / (shape[j].y-shape[i].y) + shape[i].x) )
|
||||||
c = !c;
|
// c = !c;
|
||||||
}
|
//}
|
||||||
return c;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRmgTemplateZone::setShape(std::vector<int3> shape)
|
void CRmgTemplateZone::setShape(std::vector<int3> shape)
|
||||||
{
|
{
|
||||||
int z = -1;
|
//int z = -1;
|
||||||
si32 minx = INT_MAX;
|
//si32 minx = INT_MAX;
|
||||||
si32 maxx = -1;
|
//si32 maxx = -1;
|
||||||
si32 miny = INT_MAX;
|
//si32 miny = INT_MAX;
|
||||||
si32 maxy = -1;
|
//si32 maxy = -1;
|
||||||
for(auto &point : shape)
|
//for(auto &point : shape)
|
||||||
{
|
//{
|
||||||
if (z == -1)
|
// if (z == -1)
|
||||||
z = point.z;
|
// z = point.z;
|
||||||
if (point.z != z)
|
// if (point.z != z)
|
||||||
throw rmgException("Zone shape points should lie on same z.");
|
// throw rmgException("Zone shape points should lie on same z.");
|
||||||
minx = std::min(minx, point.x);
|
// minx = std::min(minx, point.x);
|
||||||
maxx = std::max(maxx, point.x);
|
// maxx = std::max(maxx, point.x);
|
||||||
miny = std::min(miny, point.y);
|
// miny = std::min(miny, point.y);
|
||||||
maxy = std::max(maxy, point.y);
|
// maxy = std::max(maxy, point.y);
|
||||||
}
|
//}
|
||||||
this->shape = shape;
|
this->shape = shape;
|
||||||
for(int x = minx; x <= maxx; ++x)
|
//for(int x = minx; x <= maxx; ++x)
|
||||||
{
|
//{
|
||||||
for(int y = miny; y <= maxy; ++y)
|
// for(int y = miny; y <= maxy; ++y)
|
||||||
{
|
// {
|
||||||
if (pointIsIn(x, y))
|
// if (pointIsIn(x, y))
|
||||||
{
|
// {
|
||||||
tileinfo[int3(x,y,z)] = CTileInfo();
|
// tileinfo[int3(x,y,z)] = CTileInfo();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
int3 CRmgTemplateZone::getPos()
|
int3 CRmgTemplateZone::getPos()
|
||||||
@ -353,11 +353,16 @@ int3 CRmgTemplateZone::getPos()
|
|||||||
//return int3(std::abs(cx/area/6), std::abs(cy/area/6), shape[0].z);
|
//return int3(std::abs(cx/area/6), std::abs(cy/area/6), shape[0].z);
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
void CRmgTemplateZone::setPos(int3 Pos)
|
void CRmgTemplateZone::setPos(int3 &Pos)
|
||||||
{
|
{
|
||||||
pos = Pos;
|
pos = Pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CRmgTemplateZone::addTile (int3 &pos)
|
||||||
|
{
|
||||||
|
tileinfo[pos] = CTileInfo();
|
||||||
|
}
|
||||||
|
|
||||||
bool CRmgTemplateZone::fill(CMapGenerator* gen)
|
bool CRmgTemplateZone::fill(CMapGenerator* gen)
|
||||||
{
|
{
|
||||||
std::vector<CGObjectInstance*> required_objects;
|
std::vector<CGObjectInstance*> required_objects;
|
||||||
@ -393,7 +398,13 @@ bool CRmgTemplateZone::fill(CMapGenerator* gen)
|
|||||||
playerInfo.posOfMainTown = town->pos - int3(2, 0, 0);
|
playerInfo.posOfMainTown = town->pos - int3(2, 0, 0);
|
||||||
playerInfo.generateHeroAtMainTown = true;
|
playerInfo.generateHeroAtMainTown = true;
|
||||||
|
|
||||||
gen->editManager->getTerrainSelection().selectRange(MapRect(shape[0], shape[2].y - shape[0].y, shape[2].x - shape[0].x));
|
//paint zone with matching terrain
|
||||||
|
std::vector<int3> tiles;
|
||||||
|
for (auto tile : tileinfo)
|
||||||
|
{
|
||||||
|
tiles.push_back (tile.first);
|
||||||
|
}
|
||||||
|
gen->editManager->getTerrainSelection().setSelection(tiles);
|
||||||
gen->editManager->drawTerrain(VLC->townh->factions[townId]->nativeTerrain, &gen->rand);
|
gen->editManager->drawTerrain(VLC->townh->factions[townId]->nativeTerrain, &gen->rand);
|
||||||
|
|
||||||
//required_objects.push_back(town);
|
//required_objects.push_back(town);
|
||||||
|
@ -103,8 +103,9 @@ public:
|
|||||||
float3 getCenter() const;
|
float3 getCenter() const;
|
||||||
void setCenter(float3 f);
|
void setCenter(float3 f);
|
||||||
int3 getPos();
|
int3 getPos();
|
||||||
void setPos(int3 pos);
|
void setPos(int3 &pos);
|
||||||
|
|
||||||
|
void addTile (int3 &pos);
|
||||||
void setShape(std::vector<int3> shape);
|
void setShape(std::vector<int3> shape);
|
||||||
bool fill(CMapGenerator* gen);
|
bool fill(CMapGenerator* gen);
|
||||||
|
|
||||||
|
@ -115,3 +115,63 @@ void CZonePlacer::placeZones(shared_ptr<CMapGenOptions> mapGenOptions, CRandomGe
|
|||||||
logGlobal->infoStream() << boost::format ("Placed zone %d at relative position %s and coordinates %s") % zone.first % zone.second->getCenter() % zone.second->getPos();
|
logGlobal->infoStream() << boost::format ("Placed zone %d at relative position %s and coordinates %s") % zone.first % zone.second->getCenter() % zone.second->getPos();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float CZonePlacer::metric (int3 &A, int3 &B) const
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
|
||||||
|
Matlab code
|
||||||
|
|
||||||
|
dx = abs(A(1) - B(1)); %distance must be symmetric
|
||||||
|
dy = abs(A(2) - B(2));
|
||||||
|
|
||||||
|
d = 0.01 * dx^3 + 0.1 * dx^2 + 1 * dx + ...
|
||||||
|
0.03 * dy^3 - 0.3 * dy^2 + 0.3 * dy;
|
||||||
|
*/
|
||||||
|
|
||||||
|
float dx = abs(A.x - B.x) * scaleX;
|
||||||
|
float dy = abs(A.y - B.y) * scaleY;
|
||||||
|
|
||||||
|
//Horner scheme
|
||||||
|
return dx * (1 + dx * (0.1 + dx * 0.01)) + dy * (0.3 + dy * (-0.3 + dy * 0.03));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CZonePlacer::assignZones(shared_ptr<CMapGenOptions> mapGenOptions)
|
||||||
|
{
|
||||||
|
auto width = mapGenOptions->getWidth();
|
||||||
|
auto height = mapGenOptions->getHeight();
|
||||||
|
|
||||||
|
//scale to Medium map to ensure smooth results
|
||||||
|
scaleX = 72.f / width;
|
||||||
|
scaleY = 72.f / height;
|
||||||
|
|
||||||
|
auto zones = gen->getZones();
|
||||||
|
|
||||||
|
typedef std::pair<CRmgTemplateZone *, float> Dpair;
|
||||||
|
std::vector <Dpair> distances;
|
||||||
|
distances.reserve(zones.size());
|
||||||
|
|
||||||
|
auto compareByDistance = [](const Dpair & lhs, const Dpair & rhs) -> bool
|
||||||
|
{
|
||||||
|
return lhs.second < rhs.second;
|
||||||
|
};
|
||||||
|
|
||||||
|
int levels = gen->map->twoLevel ? 2 : 1;
|
||||||
|
for (int i=0; i<width; i++)
|
||||||
|
{
|
||||||
|
for(int j=0; j<height; j++)
|
||||||
|
{
|
||||||
|
for (int k = 0; k < levels; k++)
|
||||||
|
{
|
||||||
|
distances.clear();
|
||||||
|
int3 pos(i, j, k);
|
||||||
|
for (auto zone : zones)
|
||||||
|
{
|
||||||
|
distances.push_back (std::make_pair(zone.second, metric(pos, zone.second->getPos())));
|
||||||
|
}
|
||||||
|
boost::sort (distances, compareByDistance);
|
||||||
|
distances.front().first->addTile(pos); //closest tile belongs to zone
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -40,11 +40,17 @@ class CZonePlacer
|
|||||||
public:
|
public:
|
||||||
explicit CZonePlacer(CMapGenerator * gen);
|
explicit CZonePlacer(CMapGenerator * gen);
|
||||||
int3 cords (float3 f) const;
|
int3 cords (float3 f) const;
|
||||||
|
float metric (int3 &a, int3 &b) const;
|
||||||
~CZonePlacer();
|
~CZonePlacer();
|
||||||
|
|
||||||
void placeZones(shared_ptr<CMapGenOptions> mapGenOptions, CRandomGenerator * rand);
|
void placeZones(shared_ptr<CMapGenOptions> mapGenOptions, CRandomGenerator * rand);
|
||||||
|
void assignZones(shared_ptr<CMapGenOptions> mapGenOptions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
//metric coefiicients
|
||||||
|
float scaleX;
|
||||||
|
float scaleY;
|
||||||
|
float a1, b1, c1, a2, b2, c2;
|
||||||
//CMap * map;
|
//CMap * map;
|
||||||
//unique_ptr<CZoneGraph> graph;
|
//unique_ptr<CZoneGraph> graph;
|
||||||
CMapGenerator * gen;
|
CMapGenerator * gen;
|
||||||
|
Loading…
Reference in New Issue
Block a user