1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-17 11:56:46 +02:00

Allow guards not stronger than 1/3 max value next to roads

This commit is contained in:
Tomasz Zieliński 2024-05-01 10:24:21 +02:00
parent 67447acd0e
commit 7f3cf607a7
3 changed files with 27 additions and 8 deletions

View File

@ -175,19 +175,22 @@ const CGObjectInstance & Object::Instance::object() const
} }
Object::Object(CGObjectInstance & object, const int3 & position): Object::Object(CGObjectInstance & object, const int3 & position):
guarded(false) guarded(false),
value(0)
{ {
addInstance(object, position); addInstance(object, position);
} }
Object::Object(CGObjectInstance & object): Object::Object(CGObjectInstance & object):
guarded(false) guarded(false),
value(0)
{ {
addInstance(object); addInstance(object);
} }
Object::Object(const Object & object): Object::Object(const Object & object):
guarded(false) guarded(false),
value(0)
{ {
for(const auto & i : object.dInstances) for(const auto & i : object.dInstances)
addInstance(const_cast<CGObjectInstance &>(i.object()), i.getPosition()); addInstance(const_cast<CGObjectInstance &>(i.object()), i.getPosition());
@ -425,7 +428,7 @@ int3 rmg::Object::getGuardPos() const
{ {
if (instance.object().ID == Obj::MONSTER) if (instance.object().ID == Obj::MONSTER)
{ {
return instance.object().pos; return instance.getPosition(true);
} }
} }
} }
@ -435,6 +438,16 @@ int3 rmg::Object::getGuardPos() const
} }
} }
void rmg::Object::setValue(size_t newValue)
{
value = newValue;
}
size_t rmg::Object::getValue() const
{
return value;
}
void Object::Instance::finalize(RmgMap & map, CRandomGenerator & rng) void Object::Instance::finalize(RmgMap & map, CRandomGenerator & rng)
{ {
if(!map.isOnMap(getPosition(true))) if(!map.isOnMap(getPosition(true)))

View File

@ -89,6 +89,8 @@ public:
bool isGuarded() const; bool isGuarded() const;
int3 getGuardPos() const; int3 getGuardPos() const;
void setGuardedIfMonster(const Instance & object); void setGuardedIfMonster(const Instance & object);
void setValue(size_t value);
size_t getValue() const;
void finalize(RmgMap & map, CRandomGenerator &); void finalize(RmgMap & map, CRandomGenerator &);
void clearCachedArea() const; void clearCachedArea() const;
@ -107,6 +109,7 @@ private:
mutable std::list<Object::Instance*> cachedInstanceList; mutable std::list<Object::Instance*> cachedInstanceList;
mutable std::list<const Object::Instance*> cachedInstanceConstList; mutable std::list<const Object::Instance*> cachedInstanceConstList;
bool guarded; bool guarded;
size_t value;
}; };
} }

View File

@ -702,6 +702,7 @@ rmg::Object TreasurePlacer::constructTreasurePile(const std::vector<ObjectInfo*>
} }
auto & instance = rmgObject.addInstance(*object); auto & instance = rmgObject.addInstance(*object);
rmgObject.setValue(rmgObject.getValue() + oi->value);
instance.onCleared = oi->destroyObject; instance.onCleared = oi->destroyObject;
do do
@ -829,6 +830,7 @@ void TreasurePlacer::createTreasures(ObjectManager& manager)
int monsterStrength = (zone.monsterStrength == EMonsterStrength::ZONE_NONE ? 0 : zone.monsterStrength + mapMonsterStrength - 1); //array index from 0 to 4; pick any correct value for ZONE_NONE, minGuardedValue won't be used in this case anyway int monsterStrength = (zone.monsterStrength == EMonsterStrength::ZONE_NONE ? 0 : zone.monsterStrength + mapMonsterStrength - 1); //array index from 0 to 4; pick any correct value for ZONE_NONE, minGuardedValue won't be used in this case anyway
static const int minGuardedValues[] = { 6500, 4167, 3000, 1833, 1333 }; static const int minGuardedValues[] = { 6500, 4167, 3000, 1833, 1333 };
minGuardedValue = minGuardedValues[monsterStrength]; minGuardedValue = minGuardedValues[monsterStrength];
const auto blockingGuardMaxValue = zone.getMaxTreasureValue() / 3;
auto valueComparator = [](const CTreasureInfo& lhs, const CTreasureInfo& rhs) -> bool auto valueComparator = [](const CTreasureInfo& lhs, const CTreasureInfo& rhs) -> bool
{ {
@ -937,10 +939,9 @@ void TreasurePlacer::createTreasures(ObjectManager& manager)
if (guarded) if (guarded)
{ {
// Guard cannot be adjacent to road, but blocked side of an object could be
searchArea.subtract(roads); searchArea.subtract(roads);
path = manager.placeAndConnectObject(searchArea, rmgObject, [this, &rmgObject, &minDistance, &manager, &nextToRoad](const int3& tile) path = manager.placeAndConnectObject(searchArea, rmgObject, [this, &rmgObject, &minDistance, &manager, blockingGuardMaxValue, &roads, &nextToRoad](const int3& tile)
{ {
float bestDistance = 10e9; float bestDistance = 10e9;
for (const auto& t : rmgObject.getArea().getTilesVector()) for (const auto& t : rmgObject.getArea().getTilesVector())
@ -951,7 +952,9 @@ void TreasurePlacer::createTreasures(ObjectManager& manager)
else else
vstd::amin(bestDistance, distance); vstd::amin(bestDistance, distance);
} }
if (nextToRoad.contains(rmgObject.getGuardPos()))
// Guard cannot be adjacent to road, but blocked side of an object could be
if (rmgObject.getValue() > blockingGuardMaxValue && nextToRoad.contains(rmgObject.getGuardPos()))
{ {
return -1.f; return -1.f;
} }
@ -959,7 +962,7 @@ void TreasurePlacer::createTreasures(ObjectManager& manager)
const auto & guardedArea = rmgObject.instances().back()->getAccessibleArea(); const auto & guardedArea = rmgObject.instances().back()->getAccessibleArea();
const auto areaToBlock = rmgObject.getAccessibleArea(true) - guardedArea; const auto areaToBlock = rmgObject.getAccessibleArea(true) - guardedArea;
if (zone.freePaths()->overlap(areaToBlock) || manager.getVisitableArea().overlap(areaToBlock)) if (zone.freePaths()->overlap(areaToBlock) || roads.overlap(areaToBlock) || manager.getVisitableArea().overlap(areaToBlock))
return -1.f; return -1.f;
return bestDistance; return bestDistance;