1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-02-03 13:01:33 +02:00

Merge pull request #3596 from vcmi/fixes_for_water

Fixes for RMG water
This commit is contained in:
Ivan Savenko 2024-02-11 17:53:46 +02:00 committed by GitHub
commit f1a8e78f0b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 34 additions and 19 deletions

View File

@ -3,8 +3,9 @@
{
"treasure" :
[
{ "min" : 2000, "max" : 6000, "density" : 1 },
{ "min" : 100, "max" : 1000, "density" : 5 }
{ "min" : 4000, "max" : 12000, "density" : 1 },
{ "min" : 1000, "max" : 4000, "density" : 3 },
{ "min" : 100, "max" : 1000, "density" : 6 }
],
"shipyard" :
{

View File

@ -908,7 +908,7 @@ void CZonePlacer::assignZones(CRandomGenerator * rand)
vertexMapping[closestZone].insert(int3(vertex.x() * width, vertex.y() * height, closestZone->getPos().z)); //Closest vertex belongs to zone
}
//Assign actual tiles to each zone using nonlinear norm for fine edges
//Assign actual tiles to each zone
for (pos.z = 0; pos.z < levels; pos.z++)
{
for (pos.x = 0; pos.x < width; pos.x++)
@ -918,7 +918,6 @@ void CZonePlacer::assignZones(CRandomGenerator * rand)
distances.clear();
for(const auto & zoneVertex : vertexMapping)
{
// FIXME: Find closest vertex, not closest zone
auto zone = zoneVertex.first;
for (const auto & vertex : zoneVertex.second)
{
@ -929,7 +928,8 @@ void CZonePlacer::assignZones(CRandomGenerator * rand)
}
}
auto closestZone = boost::min_element(distances, simpleCompareByDistance)->first; //closest tile belongs to zone
//Tile closes to vertex belongs to zone
auto closestZone = boost::min_element(distances, simpleCompareByDistance)->first;
closestZone->area().add(pos);
map.setZoneID(pos, closestZone->getId());
}

View File

@ -116,6 +116,7 @@ void Zone::initFreeTiles()
if(dAreaFree.empty())
{
// Fixme: This might fail fot water zone, which doesn't need to have a tile in its center of the mass
dAreaPossible.erase(pos);
dAreaFree.add(pos); //zone must have at least one free tile where other paths go - for instance in the center
}
@ -250,6 +251,13 @@ void Zone::fractalize()
treasureDensity += t.density;
}
if (getType() == ETemplateZoneType::WATER)
{
// Set very little obstacles on water
spanFactor = 0.2;
}
else //Scale with treasure density
{
if (treasureValue > 400)
{
// A quater at max density
@ -265,6 +273,8 @@ void Zone::fractalize()
{
vstd::amin(spanFactor, 0.1f + 0.01f * treasureDensity); //Add extra obstacles to fill up space
}
}
float blockDistance = minDistance * spanFactor; //More obstacles in the Underground
freeDistance = freeDistance * marginFactor;
vstd::amax(freeDistance, 4 * 4);

View File

@ -579,14 +579,18 @@ void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateD
for (auto id : adjacentZones)
{
auto manager = map.getZones().at(id)->getModificator<ObjectManager>();
auto otherZone = map.getZones().at(id);
if ((otherZone->getType() == ETemplateZoneType::WATER) == (zone.getType() == ETemplateZoneType::WATER))
{
// Do not update other zone if only one is water
auto manager = otherZone->getModificator<ObjectManager>();
if (manager)
{
// TODO: Update distances for perimeter of guarded object, not just treasures
manager->updateDistances(object);
}
}
}
}
// TODO: Add multiple tiles in one operation to avoid multiple invalidation
for(auto * instance : object.instances())