1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-06-15 00:05:02 +02:00

- Add new option for connection

- Store info about objects and roads in RequiredObjectInfo
This commit is contained in:
Tomasz Zieliński
2023-07-06 22:15:00 +02:00
parent fcf7a29f45
commit 0d3ac4a502
8 changed files with 139 additions and 59 deletions

View File

@ -57,22 +57,22 @@ void ObjectManager::createDistancesPriorityQueue()
}
}
void ObjectManager::addRequiredObject(CGObjectInstance * obj, si32 strength)
void ObjectManager::addRequiredObject(const RequiredObjectInfo & info)
{
RecursiveLock lock(externalAccessMutex);
requiredObjects.emplace_back(obj, strength);
requiredObjects.emplace_back(info);
}
void ObjectManager::addCloseObject(CGObjectInstance * obj, si32 strength)
void ObjectManager::addCloseObject(const RequiredObjectInfo & info)
{
RecursiveLock lock(externalAccessMutex);
closeObjects.emplace_back(obj, strength);
closeObjects.emplace_back(info);
}
void ObjectManager::addNearbyObject(CGObjectInstance * obj, CGObjectInstance * nearbyTarget)
void ObjectManager::addNearbyObject(const RequiredObjectInfo & info)
{
RecursiveLock lock(externalAccessMutex);
nearbyObjects.emplace_back(obj, nearbyTarget);
nearbyObjects.emplace_back(info);
}
void ObjectManager::updateDistances(const rmg::Object & obj)
@ -331,13 +331,11 @@ bool ObjectManager::createRequiredObjects()
logGlobal->trace("Creating required objects");
//RecursiveLock lock(externalAccessMutex); //Why could requiredObjects be modified during the loop?
for(const auto & object : requiredObjects)
for(const auto & objInfo : requiredObjects)
{
auto * obj = object.first;
//FIXME: Invalid dObject inside object?
rmg::Object rmgObject(*obj);
rmg::Object rmgObject(*objInfo.obj);
rmgObject.setTemplate(zone.getTerrainType());
bool guarded = addGuard(rmgObject, object.second, (obj->ID == Obj::MONOLITH_TWO_WAY));
bool guarded = addGuard(rmgObject, objInfo.guardStrength, (objInfo.obj->ID == Obj::MONOLITH_TWO_WAY));
Zone::Lock lock(zone.areaMutex);
auto path = placeAndConnectObject(zone.areaPossible(), rmgObject, 3, guarded, false, OptimizeType::DISTANCE);
@ -353,10 +351,10 @@ bool ObjectManager::createRequiredObjects()
for(const auto & nearby : nearbyObjects)
{
if(nearby.second != obj)
if(nearby.nearbyTarget != nearby.obj)
continue;
rmg::Object rmgNearObject(*nearby.first);
rmg::Object rmgNearObject(*nearby.obj);
rmg::Area possibleArea(rmgObject.instances().front()->getBlockedArea().getBorderOutside());
possibleArea.intersect(zone.areaPossible());
if(possibleArea.empty())
@ -370,17 +368,14 @@ bool ObjectManager::createRequiredObjects()
}
}
for(const auto & object : closeObjects)
for(const auto & objInfo : closeObjects)
{
auto * obj = object.first;
//TODO: Wrap into same area proxy?
Zone::Lock lock(zone.areaMutex);
auto possibleArea = zone.areaPossible();
rmg::Object rmgObject(*obj);
rmg::Object rmgObject(*objInfo.obj);
rmgObject.setTemplate(zone.getTerrainType());
bool guarded = addGuard(rmgObject, object.second, (obj->ID == Obj::MONOLITH_TWO_WAY));
bool guarded = addGuard(rmgObject, objInfo.guardStrength, (objInfo.obj->ID == Obj::MONOLITH_TWO_WAY));
auto path = placeAndConnectObject(zone.areaPossible(), rmgObject,
[this, &rmgObject](const int3 & tile)
{
@ -401,10 +396,10 @@ bool ObjectManager::createRequiredObjects()
for(const auto & nearby : nearbyObjects)
{
if(nearby.second != obj)
if(nearby.nearbyTarget != objInfo.obj)
continue;
rmg::Object rmgNearObject(*nearby.first);
rmg::Object rmgNearObject(*nearby.obj);
rmg::Area possibleArea(rmgObject.instances().front()->getBlockedArea().getBorderOutside());
possibleArea.intersect(zone.areaPossible());
if(possibleArea.empty())
@ -420,10 +415,10 @@ bool ObjectManager::createRequiredObjects()
//create object on specific positions
//TODO: implement guards
for (const auto &obj : instantObjects)
for (const auto &objInfo : instantObjects)
{
rmg::Object rmgObject(*obj.first);
rmgObject.setPosition(obj.second);
rmg::Object rmgObject(*objInfo.obj);
rmgObject.setPosition(objInfo.pos);
placeObject(rmgObject, false, false);
}
@ -435,7 +430,7 @@ bool ObjectManager::createRequiredObjects()
return true;
}
void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateDistance)
void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateDistance, bool allowRoad/* = true*/)
{
object.finalize(map);
@ -493,8 +488,10 @@ void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateD
}
}
switch(object.instances().front()->object().ID)
if (allowRoad)
{
switch (object.instances().front()->object().ID)
{
case Obj::TOWN:
case Obj::RANDOM_TOWN:
case Obj::MONOLITH_TWO_WAY:
@ -502,17 +499,18 @@ void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateD
case Obj::MONOLITH_ONE_WAY_EXIT:
case Obj::SUBTERRANEAN_GATE:
case Obj::SHIPYARD:
if(auto * m = zone.getModificator<RoadPlacer>())
if (auto* m = zone.getModificator<RoadPlacer>())
m->addRoadNode(object.instances().front()->getVisitablePosition());
break;
case Obj::WATER_WHEEL:
if(auto * m = zone.getModificator<RiverPlacer>())
if (auto* m = zone.getModificator<RiverPlacer>())
m->addRiverNode(object.instances().front()->getVisitablePosition());
break;
default:
break;
}
}
}
@ -614,3 +612,19 @@ bool ObjectManager::addGuard(rmg::Object & object, si32 strength, bool zoneGuard
}
VCMI_LIB_NAMESPACE_END
RequiredObjectInfo::RequiredObjectInfo():
obj(nullptr),
nearbyTarget(nullptr),
guardStrength(0),
allowRoad(true)
{}
RequiredObjectInfo::RequiredObjectInfo(CGObjectInstance* obj, ui32 guardStrength, bool allowRoad, CGObjectInstance* nearbyTarget):
obj(obj),
nearbyTarget(nearbyTarget),
guardStrength(guardStrength),
allowRoad(allowRoad)
{}