1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Correct zone placement & sizing for underground maps.

This commit is contained in:
DjWarmonger 2014-07-03 12:28:51 +02:00
parent cc8d484775
commit 60a5c764b8
5 changed files with 38 additions and 78 deletions

View File

@ -1,66 +0,0 @@
{
"name" : "In The Wake of Gods",
"description" : "Unnofficial addon for Heroes of Might and Magic III",
"version" : "0.0.0",
"author" : "WoG Team",
"contact" : "http://forum.vcmi.eu/index.php",
"modType" : "Expansion",
"artifacts" :
[
"config/wog/artifacts.json"
],
"creatures" :
[
"config/wog/creatures.json"
],
"heroClasses" :
[
"config/wog/heroClasses.json"
],
"filesystem":
{
"" :
[
{ "type" : "map", "path" : "/Config/wogFileOverrides.json"}
],
"CONFIG/" :
[
{ "type" : "dir", "path" : "/Config"}
],
"DATA/" :
[
{"type" : "lod", "path" : "/Data/hmm35wog.pac"},
{"type" : "dir", "path" : "/Data"}
],
"SPRITES/":
[
{"type" : "lod", "path" : "/Data/hmm35wog.pac"},
{"type" : "lod", "path" : "/Data/wog - animated objects.pac"},
{"type" : "lod", "path" : "/Data/wog - animated trees.pac"},
{"type" : "lod", "path" : "/Data/wog - battle decorations.pac"}
],
"SOUNDS/":
[
{"type" : "snd", "path" : "/Data/wog - sounds.snd"},
{"type" : "snd", "path" : "/Data/wog.snd"}
],
"MUSIC/":
[
{"type" : "dir", "path" : "/Mp3"}
],
"VIDEO/":
[
{"type" : "vid", "path" : "/Data/wog - video.vid"},
{"type" : "vid", "path" : "/Data/wog.vid"}
],
"MAPS/":
[
{"type" : "dir", "path" : "/Maps"}
]
}
}

View File

@ -2,7 +2,7 @@
{ {
"Analogy" : "Analogy" :
{ {
"minSize" : "m", "maxSize" : "m", "minSize" : "m", "maxSize" : "m+u",
"players" : "4", "players" : "4",
"zones" : "zones" :
{ {
@ -63,13 +63,13 @@
}, },
"Upgrade" : "Upgrade" :
{ {
"minSize" : "s", "maxSize" : "m", "minSize" : "s+u", "maxSize" : "m",
"players" : "2", "players" : "2",
"zones" : "zones" :
{ {
"1" : "1" :
{ {
"type" : "playerStart", "size" : 1, "owner" : 1, "type" : "playerStart", "size" : 3, "owner" : 1,
"playerTowns" : { "castles" : 1 }, "playerTowns" : { "castles" : 1 },
"monsters" : "normal", "monsters" : "normal",
"mines" : {"wood" : 1, "ore" : 1}, "mines" : {"wood" : 1, "ore" : 1},
@ -80,7 +80,7 @@
}, },
"2" : "2" :
{ {
"type" : "playerStart", "size" : 1, "owner" : 2, "type" : "playerStart", "size" : 3, "owner" : 2,
"playerTowns" : { "castles" : 1 }, "playerTowns" : { "castles" : 1 },
"monsters" : "normal", "monsters" : "normal",
"minesLikeZone" : 1, "minesLikeZone" : 1,
@ -88,7 +88,7 @@
}, },
"3" : "3" :
{ {
"type" : "treasure", "size" : 2, "neutralTowns" : { "towns" : 1 }, "townTypeLikeZone" : 1, "type" : "treasure", "size" : 4, "neutralTowns" : { "towns" : 1 }, "townTypeLikeZone" : 1,
"monsters" : "weak", "monsters" : "weak",
"mines" : {"gems" : 1, "crystal" : 1, "sulfur" : 1, "mercury" : 1, "gold" : 1}, "mines" : {"gems" : 1, "crystal" : 1, "sulfur" : 1, "mercury" : 1, "gold" : 1},
"treasure" : [ "treasure" : [
@ -98,14 +98,14 @@
}, },
"4" : "4" :
{ {
"type" : "treasure", "size" : 2, "neutralTowns" : { "towns" : 1 }, "townTypeLikeZone" : 2, "type" : "treasure", "size" : 4, "neutralTowns" : { "towns" : 1 }, "townTypeLikeZone" : 2,
"monsters" : "weak", "monsters" : "weak",
"minesLikeZone" : 3, "minesLikeZone" : 3,
"treasureLikeZone" : 3 "treasureLikeZone" : 3
}, },
"5" : "5" :
{ {
"type" : "treasure", "size" : 3, "neutralTowns" : { "castles" : 1 }, "terrainTypes" : [ "sand" ], "type" : "treasure", "size" : 5, "neutralTowns" : { "castles" : 1 }, "terrainTypes" : [ "sand" ],
"monsters" : "strong", "monsters" : "strong",
"mines" : {"gold" : 2}, "mines" : {"gold" : 2},
"treasure" : [ "treasure" : [
@ -126,7 +126,7 @@
}, },
"Golden Ring" : "Golden Ring" :
{ {
"minSize" : "m", "maxSize" : "l", "minSize" : "m+u", "maxSize" : "l",
"players" : "3", "players" : "3",
"zones" : "zones" :
{ {
@ -243,7 +243,7 @@
}, },
"Jebus Cross": "Jebus Cross":
{ {
"minSize" : "l", "maxSize" : "xl", "minSize" : "l+u", "maxSize" : "xl+u",
"players" : "4", "players" : "4",
"zones": "zones":
{ {

View File

@ -354,6 +354,14 @@ std::set<int3> CRmgTemplateZone::getTileInfo () const
return tileinfo; return tileinfo;
} }
void CRmgTemplateZone::discardDistantTiles (int distance)
{
vstd::erase_if (tileinfo, [distance, this](const int3 &tile) -> bool
{
return tile.dist2d(this->pos) > distance;
});
}
void CRmgTemplateZone::createBorder(CMapGenerator* gen) void CRmgTemplateZone::createBorder(CMapGenerator* gen)
{ {
for (auto tile : tileinfo) for (auto tile : tileinfo)

View File

@ -128,6 +128,7 @@ public:
void addTile (const int3 &pos); void addTile (const int3 &pos);
std::set<int3> getTileInfo () const; std::set<int3> getTileInfo () const;
void discardDistantTiles (int distance);
void addRequiredObject(CGObjectInstance * obj, si32 guardStrength=0); void addRequiredObject(CGObjectInstance * obj, si32 guardStrength=0);
bool addMonster(CMapGenerator* gen, int3 &pos, si32 strength); bool addMonster(CMapGenerator* gen, int3 &pos, si32 strength);

View File

@ -52,6 +52,7 @@ void CZonePlacer::placeZones(shared_ptr<CMapGenOptions> mapGenOptions, CRandomGe
int height = mapGenOptions->getHeight(); int height = mapGenOptions->getHeight();
auto zones = gen->getZones(); auto zones = gen->getZones();
bool underground = mapGenOptions->getHasTwoLevels();
//TODO: consider underground zones //TODO: consider underground zones
@ -65,10 +66,16 @@ void CZonePlacer::placeZones(shared_ptr<CMapGenOptions> mapGenOptions, CRandomGe
float totalSize = 0; float totalSize = 0;
for (auto zone : zones) for (auto zone : zones)
{ {
int level = 0;
if (underground)
level = rand->nextInt(0, 1);
totalSize += (zone.second->getSize() * zone.second->getSize()); totalSize += (zone.second->getSize() * zone.second->getSize());
zone.second->setCenter (float3(rand->nextDouble(0.2,0.8), rand->nextDouble(0.2,0.8), 0)); //start away from borders zone.second->setCenter (float3(rand->nextDouble(0.2, 0.8), rand->nextDouble(0.2, 0.8), level)); //start away from borders
} }
//prescale zones //prescale zones
if (underground) //map is twice as big, so zones occupy only half of normal space
totalSize /= 2;
float prescaler = sqrt ((width * height) / (totalSize * 3.14f)); float prescaler = sqrt ((width * height) / (totalSize * 3.14f));
float mapSize = sqrt (width * height); float mapSize = sqrt (width * height);
for (auto zone : zones) for (auto zone : zones)
@ -105,7 +112,8 @@ void CZonePlacer::placeZones(shared_ptr<CMapGenOptions> mapGenOptions, CRandomGe
//separate overlaping zones //separate overlaping zones
for (auto otherZone : zones) for (auto otherZone : zones)
{ {
if (zone == otherZone) //zones on different levels don't push away
if (zone == otherZone || pos.z != otherZone.second->getCenter().z)
continue; continue;
float distance = pos.dist2d (otherZone.second->getCenter()); float distance = pos.dist2d (otherZone.second->getCenter());
@ -144,6 +152,7 @@ void CZonePlacer::placeZones(shared_ptr<CMapGenOptions> mapGenOptions, CRandomGe
forceVector -= (boundary - pos) / getDistance(distance); //negative value forceVector -= (boundary - pos) / getDistance(distance); //negative value
} }
forceVector.z = 0; //operator - doesn't preserve z coordinate :/
forces[zone.second] = forceVector; forces[zone.second] = forceVector;
} }
//update positions //update positions
@ -213,7 +222,10 @@ void CZonePlacer::assignZones(shared_ptr<CMapGenOptions> mapGenOptions)
int3 pos(i, j, k); int3 pos(i, j, k);
for (auto zone : zones) for (auto zone : zones)
{ {
distances.push_back (std::make_pair(zone.second, metric(pos, zone.second->getPos()))); if (zone.second->getPos().z == k)
distances.push_back (std::make_pair(zone.second, metric(pos, zone.second->getPos())));
else
distances.push_back (std::make_pair(zone.second, std::numeric_limits<float>::max()));
} }
boost::sort (distances, compareByDistance); boost::sort (distances, compareByDistance);
distances.front().first->addTile(pos); //closest tile belongs to zone distances.front().first->addTile(pos); //closest tile belongs to zone
@ -230,7 +242,12 @@ void CZonePlacer::assignZones(shared_ptr<CMapGenOptions> mapGenOptions)
total += tile; total += tile;
} }
int size = tiles.size(); int size = tiles.size();
assert (size);
zone.second->setPos (int3(total.x/size, total.y/size, total.z/size)); zone.second->setPos (int3(total.x/size, total.y/size, total.z/size));
//TODO: similiar for islands
if (zone.second->getPos().z)
zone.second->discardDistantTiles(zone.second->getSize());
} }
logGlobal->infoStream() << "Finished zone colouring"; logGlobal->infoStream() << "Finished zone colouring";
} }