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

View File

@ -354,6 +354,14 @@ std::set<int3> CRmgTemplateZone::getTileInfo () const
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)
{
for (auto tile : tileinfo)

View File

@ -128,6 +128,7 @@ public:
void addTile (const int3 &pos);
std::set<int3> getTileInfo () const;
void discardDistantTiles (int distance);
void addRequiredObject(CGObjectInstance * obj, si32 guardStrength=0);
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();
auto zones = gen->getZones();
bool underground = mapGenOptions->getHasTwoLevels();
//TODO: consider underground zones
@ -65,10 +66,16 @@ void CZonePlacer::placeZones(shared_ptr<CMapGenOptions> mapGenOptions, CRandomGe
float totalSize = 0;
for (auto zone : zones)
{
int level = 0;
if (underground)
level = rand->nextInt(0, 1);
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
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 mapSize = sqrt (width * height);
for (auto zone : zones)
@ -105,7 +112,8 @@ void CZonePlacer::placeZones(shared_ptr<CMapGenOptions> mapGenOptions, CRandomGe
//separate overlaping 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;
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.z = 0; //operator - doesn't preserve z coordinate :/
forces[zone.second] = forceVector;
}
//update positions
@ -213,7 +222,10 @@ void CZonePlacer::assignZones(shared_ptr<CMapGenOptions> mapGenOptions)
int3 pos(i, j, k);
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);
distances.front().first->addTile(pos); //closest tile belongs to zone
@ -230,7 +242,12 @@ void CZonePlacer::assignZones(shared_ptr<CMapGenOptions> mapGenOptions)
total += tile;
}
int size = tiles.size();
assert (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";
}