1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-07-05 00:49:09 +02:00

Map objects now use shared_ptr (rmg)

This commit is contained in:
Ivan Savenko
2025-03-13 20:13:27 +00:00
parent dda5c9f13a
commit 84cf7b052d
19 changed files with 145 additions and 145 deletions

View File

@ -370,7 +370,7 @@ void ObstacleProxy::placeObject(rmg::Object & object, std::set<std::shared_ptr<C
{ {
for (auto * instance : object.instances()) for (auto * instance : object.instances())
{ {
instances.insert(instance->object()); instances.insert(instance->pointer());
} }
} }

View File

@ -19,13 +19,13 @@ MapProxy::MapProxy(RmgMap & map):
{ {
} }
void MapProxy::insertObject(CGObjectInstance * obj) void MapProxy::insertObject(std::shared_ptr<CGObjectInstance> obj)
{ {
Lock lock(mx); Lock lock(mx);
map.getEditManager()->insertObject(obj); map.getEditManager()->insertObject(obj);
} }
void MapProxy::insertObjects(std::set<CGObjectInstance*>& objects) void MapProxy::insertObjects(std::set<std::shared_ptr<CGObjectInstance>>& objects)
{ {
Lock lock(mx); Lock lock(mx);
map.getEditManager()->insertObjects(objects); map.getEditManager()->insertObjects(objects);

View File

@ -24,8 +24,8 @@ class MapProxy
public: public:
MapProxy(RmgMap & map); MapProxy(RmgMap & map);
void insertObject(CGObjectInstance * obj); void insertObject(std::shared_ptr<CGObjectInstance> obj);
void insertObjects(std::set<CGObjectInstance*>& objects); void insertObjects(std::set<std::shared_ptr<CGObjectInstance>>& objects);
void removeObject(CGObjectInstance* obj); void removeObject(CGObjectInstance* obj);
void drawTerrain(vstd::RNG & generator, std::vector<int3> & tiles, TerrainId terrain); void drawTerrain(vstd::RNG & generator, std::vector<int3> & tiles, TerrainId terrain);

View File

@ -21,7 +21,7 @@ VCMI_LIB_NAMESPACE_BEGIN
ObjectInfo::ObjectInfo(si32 ID, si32 subID): ObjectInfo::ObjectInfo(si32 ID, si32 subID):
primaryID(ID), primaryID(ID),
secondaryID(subID), secondaryID(subID),
destroyObject([](CGObjectInstance * obj){}), destroyObject([](CGObjectInstance & obj){}),
maxPerZone(std::numeric_limits<ui32>::max()) maxPerZone(std::numeric_limits<ui32>::max())
{ {
} }
@ -82,4 +82,4 @@ CompoundMapObjectID ObjectInfo::getCompoundID() const
return CompoundMapObjectID(primaryID, secondaryID); return CompoundMapObjectID(primaryID, secondaryID);
} }
VCMI_LIB_NAMESPACE_END VCMI_LIB_NAMESPACE_END

View File

@ -32,8 +32,8 @@ struct DLL_LINKAGE ObjectInfo
ui16 probability = 0; ui16 probability = 0;
ui32 maxPerZone = 1; ui32 maxPerZone = 1;
//ui32 maxPerMap; //unused //ui32 maxPerMap; //unused
std::function<CGObjectInstance *()> generateObject; std::function<std::shared_ptr<CGObjectInstance>()> generateObject;
std::function<void(CGObjectInstance *)> destroyObject; std::function<void(CGObjectInstance &)> destroyObject;
void setAllTemplates(MapObjectID type, MapObjectSubID subtype); void setAllTemplates(MapObjectID type, MapObjectSubID subtype);
void setTemplates(MapObjectID type, MapObjectSubID subtype, TerrainId terrain); void setTemplates(MapObjectID type, MapObjectSubID subtype, TerrainId terrain);
@ -42,4 +42,4 @@ struct DLL_LINKAGE ObjectInfo
//bool matchesId(const CompoundMapObjectID & id) const; //bool matchesId(const CompoundMapObjectID & id) const;
}; };
VCMI_LIB_NAMESPACE_END VCMI_LIB_NAMESPACE_END

View File

@ -27,12 +27,12 @@ VCMI_LIB_NAMESPACE_BEGIN
using namespace rmg; using namespace rmg;
Object::Instance::Instance(const Object& parent, CGObjectInstance & object): dParent(parent), dObject(object) Object::Instance::Instance(const Object& parent, std::shared_ptr<CGObjectInstance> object): dParent(parent), dObject(object)
{ {
setPosition(dPosition); setPosition(dPosition);
} }
Object::Instance::Instance(const Object& parent, CGObjectInstance & object, const int3 & position): Instance(parent, object) Object::Instance::Instance(const Object& parent, std::shared_ptr<CGObjectInstance> object, const int3 & position): Instance(parent, object)
{ {
setPosition(position); setPosition(position);
} }
@ -41,10 +41,10 @@ const Area & Object::Instance::getBlockedArea() const
{ {
if(dBlockedAreaCache.empty()) if(dBlockedAreaCache.empty())
{ {
std::set<int3> blockedArea = dObject.getBlockedPos(); std::set<int3> blockedArea = dObject->getBlockedPos();
dBlockedAreaCache.assign(rmg::Tileset(blockedArea.begin(), blockedArea.end())); dBlockedAreaCache.assign(rmg::Tileset(blockedArea.begin(), blockedArea.end()));
if(dObject.isVisitable() || dBlockedAreaCache.empty()) if(dObject->isVisitable() || dBlockedAreaCache.empty())
dBlockedAreaCache.add(dObject.visitablePos()); dBlockedAreaCache.add(dObject->visitablePos());
} }
return dBlockedAreaCache; return dBlockedAreaCache;
} }
@ -64,7 +64,7 @@ int3 Object::Instance::getPosition(bool isAbsolute) const
int3 Object::Instance::getVisitablePosition() const int3 Object::Instance::getVisitablePosition() const
{ {
return dObject.visitablePos(); return dObject->visitablePos();
} }
const rmg::Area & Object::Instance::getAccessibleArea() const const rmg::Area & Object::Instance::getAccessibleArea() const
@ -87,7 +87,7 @@ const rmg::Area & Object::Instance::getAccessibleArea() const
void Object::Instance::setPosition(const int3 & position) void Object::Instance::setPosition(const int3 & position)
{ {
dPosition = position; dPosition = position;
dObject.setAnchorPos(dPosition + dParent.getPosition()); dObject->setAnchorPos(dPosition + dParent.getPosition());
dBlockedAreaCache.clear(); dBlockedAreaCache.clear();
dAccessibleAreaCache.clear(); dAccessibleAreaCache.clear();
@ -96,45 +96,45 @@ void Object::Instance::setPosition(const int3 & position)
void Object::Instance::setPositionRaw(const int3 & position) void Object::Instance::setPositionRaw(const int3 & position)
{ {
if(!dObject.anchorPos().isValid()) if(!dObject->anchorPos().isValid())
{ {
dObject.setAnchorPos(dPosition + dParent.getPosition()); dObject->setAnchorPos(dPosition + dParent.getPosition());
dBlockedAreaCache.clear(); dBlockedAreaCache.clear();
dAccessibleAreaCache.clear(); dAccessibleAreaCache.clear();
dParent.clearCachedArea(); dParent.clearCachedArea();
} }
auto shift = position + dParent.getPosition() - dObject.anchorPos(); auto shift = position + dParent.getPosition() - dObject->anchorPos();
dAccessibleAreaCache.translate(shift); dAccessibleAreaCache.translate(shift);
dBlockedAreaCache.translate(shift); dBlockedAreaCache.translate(shift);
dPosition = position; dPosition = position;
dObject.setAnchorPos(dPosition + dParent.getPosition()); dObject->setAnchorPos(dPosition + dParent.getPosition());
} }
void Object::Instance::setAnyTemplate(vstd::RNG & rng) void Object::Instance::setAnyTemplate(vstd::RNG & rng)
{ {
auto templates = dObject.getObjectHandler()->getTemplates(); auto templates = dObject->getObjectHandler()->getTemplates();
if(templates.empty()) if(templates.empty())
throw rmgException(boost::str(boost::format("Did not find any graphics for object (%d,%d)") % dObject.ID % dObject.getObjTypeIndex())); throw rmgException(boost::str(boost::format("Did not find any graphics for object (%d,%d)") % dObject->ID % dObject->getObjTypeIndex()));
dObject.appearance = *RandomGeneratorUtil::nextItem(templates, rng); dObject->appearance = *RandomGeneratorUtil::nextItem(templates, rng);
dAccessibleAreaCache.clear(); dAccessibleAreaCache.clear();
setPosition(getPosition(false)); setPosition(getPosition(false));
} }
void Object::Instance::setTemplate(TerrainId terrain, vstd::RNG & rng) void Object::Instance::setTemplate(TerrainId terrain, vstd::RNG & rng)
{ {
auto templates = dObject.getObjectHandler()->getMostSpecificTemplates(terrain); auto templates = dObject->getObjectHandler()->getMostSpecificTemplates(terrain);
if (templates.empty()) if (templates.empty())
{ {
auto terrainName = LIBRARY->terrainTypeHandler->getById(terrain)->getNameTranslated(); auto terrainName = LIBRARY->terrainTypeHandler->getById(terrain)->getNameTranslated();
throw rmgException(boost::str(boost::format("Did not find graphics for object (%d,%d) at %s") % dObject.ID % dObject.getObjTypeIndex() % terrainName)); throw rmgException(boost::str(boost::format("Did not find graphics for object (%d,%d) at %s") % dObject->ID % dObject->getObjTypeIndex() % terrainName));
} }
dObject.appearance = *RandomGeneratorUtil::nextItem(templates, rng); dObject->appearance = *RandomGeneratorUtil::nextItem(templates, rng);
dAccessibleAreaCache.clear(); dAccessibleAreaCache.clear();
setPosition(getPosition(false)); setPosition(getPosition(false));
} }
@ -142,9 +142,8 @@ void Object::Instance::setTemplate(TerrainId terrain, vstd::RNG & rng)
void Object::Instance::clear() void Object::Instance::clear()
{ {
if (onCleared) if (onCleared)
onCleared(&dObject); onCleared(*dObject);
delete &dObject;
dBlockedAreaCache.clear(); dBlockedAreaCache.clear();
dAccessibleAreaCache.clear(); dAccessibleAreaCache.clear();
dParent.clearCachedArea(); dParent.clearCachedArea();
@ -153,37 +152,42 @@ void Object::Instance::clear()
bool Object::Instance::isVisitableFrom(const int3 & position) const bool Object::Instance::isVisitableFrom(const int3 & position) const
{ {
auto relPosition = position - getPosition(true); auto relPosition = position - getPosition(true);
return dObject.appearance->isVisitableFrom(relPosition.x, relPosition.y); return dObject->appearance->isVisitableFrom(relPosition.x, relPosition.y);
} }
bool Object::Instance::isBlockedVisitable() const bool Object::Instance::isBlockedVisitable() const
{ {
return dObject.isBlockedVisitable(); return dObject->isBlockedVisitable();
} }
bool Object::Instance::isRemovable() const bool Object::Instance::isRemovable() const
{ {
return dObject.isRemovable(); return dObject->isRemovable();
} }
CGObjectInstance & Object::Instance::object() CGObjectInstance & Object::Instance::object()
{
return *dObject;
}
std::shared_ptr<CGObjectInstance> Object::Instance::pointer() const
{ {
return dObject; return dObject;
} }
const CGObjectInstance & Object::Instance::object() const const CGObjectInstance & Object::Instance::object() const
{ {
return dObject; return *dObject;
} }
Object::Object(CGObjectInstance & object, const int3 & position): Object::Object(std::shared_ptr<CGObjectInstance> object, const int3 & position):
guarded(false), guarded(false),
value(0) value(0)
{ {
addInstance(object, position); addInstance(object, position);
} }
Object::Object(CGObjectInstance & object): Object::Object(std::shared_ptr<CGObjectInstance> object):
guarded(false), guarded(false),
value(0) value(0)
{ {
@ -195,7 +199,7 @@ Object::Object(const Object & object):
value(object.value) value(object.value)
{ {
for(const auto & i : object.dInstances) for(const auto & i : object.dInstances)
addInstance(const_cast<CGObjectInstance &>(i.object()), i.getPosition()); addInstance(i.pointer(), i.getPosition());
setPosition(object.getPosition()); setPosition(object.getPosition());
} }
@ -231,7 +235,7 @@ void Object::addInstance(Instance & object)
visibleTopOffset.reset(); visibleTopOffset.reset();
} }
Object::Instance & Object::addInstance(CGObjectInstance & object) Object::Instance & Object::addInstance(std::shared_ptr<CGObjectInstance> object)
{ {
dInstances.emplace_back(*this, object); dInstances.emplace_back(*this, object);
setGuardedIfMonster(dInstances.back()); setGuardedIfMonster(dInstances.back());
@ -243,7 +247,7 @@ Object::Instance & Object::addInstance(CGObjectInstance & object)
return dInstances.back(); return dInstances.back();
} }
Object::Instance & Object::addInstance(CGObjectInstance & object, const int3 & position) Object::Instance & Object::addInstance(std::shared_ptr<CGObjectInstance> object, const int3 & position)
{ {
dInstances.emplace_back(*this, object, position); dInstances.emplace_back(*this, object, position);
setGuardedIfMonster(dInstances.back()); setGuardedIfMonster(dInstances.back());
@ -498,16 +502,16 @@ rmg::Area Object::Instance::getBorderAbove() const
void Object::Instance::finalize(RmgMap & map, vstd::RNG & rng) void Object::Instance::finalize(RmgMap & map, vstd::RNG & rng)
{ {
if(!map.isOnMap(getPosition(true))) if(!map.isOnMap(getPosition(true)))
throw rmgException(boost::str(boost::format("Position of object %d at %s is outside the map") % dObject.id % getPosition(true).toString())); throw rmgException(boost::str(boost::format("Position of object %d at %s is outside the map") % dObject->id % getPosition(true).toString()));
//If no specific template was defined for this object, select any matching //If no specific template was defined for this object, select any matching
if (!dObject.appearance) if (!dObject->appearance)
{ {
const auto * terrainType = map.getTile(getPosition(true)).getTerrain(); const auto * terrainType = map.getTile(getPosition(true)).getTerrain();
auto templates = dObject.getObjectHandler()->getTemplates(terrainType->getId()); auto templates = dObject->getObjectHandler()->getTemplates(terrainType->getId());
if (templates.empty()) if (templates.empty())
{ {
throw rmgException(boost::str(boost::format("Did not find graphics for object (%d,%d) at %s (terrain %d)") % dObject.ID % dObject.getObjTypeIndex() % getPosition(true).toString() % terrainType)); throw rmgException(boost::str(boost::format("Did not find graphics for object (%d,%d) at %s (terrain %d)") % dObject->ID % dObject->getObjTypeIndex() % getPosition(true).toString() % terrainType));
} }
else else
{ {
@ -515,13 +519,13 @@ void Object::Instance::finalize(RmgMap & map, vstd::RNG & rng)
} }
} }
if (dObject.isVisitable() && !map.isOnMap(dObject.visitablePos())) if (dObject->isVisitable() && !map.isOnMap(dObject->visitablePos()))
throw rmgException(boost::str(boost::format("Visitable tile %s of object %d at %s is outside the map") % dObject.visitablePos().toString() % dObject.id % dObject.anchorPos().toString())); throw rmgException(boost::str(boost::format("Visitable tile %s of object %d at %s is outside the map") % dObject->visitablePos().toString() % dObject->id % dObject->anchorPos().toString()));
for(const auto & tile : dObject.getBlockedPos()) for(const auto & tile : dObject->getBlockedPos())
{ {
if(!map.isOnMap(tile)) if(!map.isOnMap(tile))
throw rmgException(boost::str(boost::format("Tile %s of object %d at %s is outside the map") % tile.toString() % dObject.id % dObject.anchorPos().toString())); throw rmgException(boost::str(boost::format("Tile %s of object %d at %s is outside the map") % tile.toString() % dObject->id % dObject->anchorPos().toString()));
} }
for(const auto & tile : getBlockedArea().getTilesVector()) for(const auto & tile : getBlockedArea().getTilesVector())
@ -529,7 +533,7 @@ void Object::Instance::finalize(RmgMap & map, vstd::RNG & rng)
map.setOccupied(tile, ETileType::USED); map.setOccupied(tile, ETileType::USED);
} }
map.getMapProxy()->insertObject(&dObject); map.getMapProxy()->insertObject(dObject);
} }
void Object::finalize(RmgMap & map, vstd::RNG & rng) void Object::finalize(RmgMap & map, vstd::RNG & rng)

View File

@ -32,8 +32,8 @@ public:
class Instance class Instance
{ {
public: public:
Instance(const Object& parent, CGObjectInstance & object); Instance(const Object& parent, std::shared_ptr<CGObjectInstance> object);
Instance(const Object& parent, CGObjectInstance & object, const int3 & position); Instance(const Object& parent, std::shared_ptr<CGObjectInstance> object, const int3 & position);
const Area & getBlockedArea() const; const Area & getBlockedArea() const;
@ -52,27 +52,28 @@ public:
void setPositionRaw(const int3 & position); //no cache invalidation void setPositionRaw(const int3 & position); //no cache invalidation
const CGObjectInstance & object() const; const CGObjectInstance & object() const;
CGObjectInstance & object(); CGObjectInstance & object();
std::shared_ptr<CGObjectInstance> pointer() const;
void finalize(RmgMap & map, vstd::RNG &); //cache invalidation void finalize(RmgMap & map, vstd::RNG &); //cache invalidation
void clear(); void clear();
std::function<void(CGObjectInstance *)> onCleared; std::function<void(CGObjectInstance &)> onCleared;
private: private:
mutable Area dBlockedAreaCache; mutable Area dBlockedAreaCache;
int3 dPosition; int3 dPosition;
mutable Area dAccessibleAreaCache; mutable Area dAccessibleAreaCache;
CGObjectInstance & dObject; std::shared_ptr<CGObjectInstance> dObject;
const Object & dParent; const Object & dParent;
}; };
Object() = default; Object() = default;
Object(const Object & object); Object(const Object & object);
Object(CGObjectInstance & object); Object(std::shared_ptr<CGObjectInstance> object);
Object(CGObjectInstance & object, const int3 & position); Object(std::shared_ptr<CGObjectInstance> object, const int3 & position);
void addInstance(Instance & object); void addInstance(Instance & object);
Instance & addInstance(CGObjectInstance & object); Instance & addInstance(std::shared_ptr<CGObjectInstance> object);
Instance & addInstance(CGObjectInstance & object, const int3 & position); Instance & addInstance(std::shared_ptr<CGObjectInstance> object, const int3 & position);
std::list<Instance*> & instances(); std::list<Instance*> & instances();
std::list<const Instance*> & instances() const; std::list<const Instance*> & instances() const;

View File

@ -277,7 +277,7 @@ void ConnectionsPlacer::selfSideDirectConnection(const rmg::ZoneConnection & con
{ {
assert(zone.getModificator<ObjectManager>()); assert(zone.getModificator<ObjectManager>());
auto & manager = *zone.getModificator<ObjectManager>(); auto & manager = *zone.getModificator<ObjectManager>();
auto * monsterType = manager.chooseGuard(connection.getGuardStrength(), true); auto monsterType = manager.chooseGuard(connection.getGuardStrength(), true);
rmg::Area border(zone.area()->getBorder()); rmg::Area border(zone.area()->getBorder());
border.unite(otherZone->area()->getBorder()); border.unite(otherZone->area()->getBorder());
@ -302,7 +302,7 @@ void ConnectionsPlacer::selfSideDirectConnection(const rmg::ZoneConnection & con
if(monsterType) if(monsterType)
{ {
rmg::Object monster(*monsterType); rmg::Object monster(monsterType);
monster.setPosition(guardPos); monster.setPosition(guardPos);
manager.placeObject(monster, false, true); manager.placeObject(monster, false, true);
//Place objects away from the monster in the other zone, too //Place objects away from the monster in the other zone, too
@ -379,10 +379,10 @@ void ConnectionsPlacer::selfSideIndirectConnection(const rmg::ZoneConnection & c
auto & managerOther = *otherZone->getModificator<ObjectManager>(); auto & managerOther = *otherZone->getModificator<ObjectManager>();
auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::SUBTERRANEAN_GATE, 0); auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::SUBTERRANEAN_GATE, 0);
auto * gate1 = factory->create(map.mapInstance->cb, nullptr); auto gate1 = factory->create(map.mapInstance->cb, nullptr);
auto * gate2 = factory->create(map.mapInstance->cb, nullptr); auto gate2 = factory->create(map.mapInstance->cb, nullptr);
rmg::Object rmgGate1(*gate1); rmg::Object rmgGate1(gate1);
rmg::Object rmgGate2(*gate2); rmg::Object rmgGate2(gate2);
rmgGate1.setTemplate(zone.getTerrainType(), zone.getRand()); rmgGate1.setTemplate(zone.getTerrainType(), zone.getRand());
rmgGate2.setTemplate(otherZone->getTerrainType(), zone.getRand()); rmgGate2.setTemplate(otherZone->getTerrainType(), zone.getRand());
bool guarded1 = manager.addGuard(rmgGate1, connection.getGuardStrength(), true); bool guarded1 = manager.addGuard(rmgGate1, connection.getGuardStrength(), true);
@ -447,8 +447,8 @@ void ConnectionsPlacer::placeMonolithConnection(const rmg::ZoneConnection & conn
bool allowRoad = shouldGenerateRoad(connection); bool allowRoad = shouldGenerateRoad(connection);
auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::MONOLITH_TWO_WAY, generator.getNextMonlithIndex()); auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::MONOLITH_TWO_WAY, generator.getNextMonlithIndex());
auto * teleport1 = factory->create(map.mapInstance->cb, nullptr); auto teleport1 = factory->create(map.mapInstance->cb, nullptr);
auto * teleport2 = factory->create(map.mapInstance->cb, nullptr); auto teleport2 = factory->create(map.mapInstance->cb, nullptr);
RequiredObjectInfo obj1(teleport1, connection.getGuardStrength(), allowRoad); RequiredObjectInfo obj1(teleport1, connection.getGuardStrength(), allowRoad);
RequiredObjectInfo obj2(teleport2, connection.getGuardStrength(), allowRoad); RequiredObjectInfo obj2(teleport2, connection.getGuardStrength(), allowRoad);

View File

@ -49,9 +49,9 @@ void MinePlacer::init()
bool MinePlacer::placeMines(ObjectManager & manager) bool MinePlacer::placeMines(ObjectManager & manager)
{ {
std::vector<CGMine*> createdMines; std::vector<std::shared_ptr<CGMine>> createdMines;
std::vector<std::pair<CGObjectInstance*, ui32>> requiredObjects; std::vector<std::pair<std::shared_ptr<CGObjectInstance>, ui32>> requiredObjects;
for(const auto & mineInfo : zone.getMinesInfo()) for(const auto & mineInfo : zone.getMinesInfo())
{ {
@ -60,7 +60,7 @@ bool MinePlacer::placeMines(ObjectManager & manager)
{ {
auto mineHandler = LIBRARY->objtypeh->getHandlerFor(Obj::MINE, res); auto mineHandler = LIBRARY->objtypeh->getHandlerFor(Obj::MINE, res);
const auto & rmginfo = mineHandler->getRMGInfo(); const auto & rmginfo = mineHandler->getRMGInfo();
auto * mine = dynamic_cast<CGMine *>(mineHandler->create(map.mapInstance->cb, nullptr)); auto mine = std::dynamic_pointer_cast<CGMine>(mineHandler->create(map.mapInstance->cb, nullptr));
mine->producedResource = res; mine->producedResource = res;
mine->tempOwner = PlayerColor::NEUTRAL; mine->tempOwner = PlayerColor::NEUTRAL;
mine->producedQuantity = mine->defaultResProduction(); mine->producedQuantity = mine->defaultResProduction();
@ -73,7 +73,7 @@ bool MinePlacer::placeMines(ObjectManager & manager)
manager.addCloseObject(RequiredObjectInfo(mine, rmginfo.value)); manager.addCloseObject(RequiredObjectInfo(mine, rmginfo.value));
} }
else else
requiredObjects.push_back(std::pair<CGObjectInstance*, ui32>(mine, rmginfo.value)); requiredObjects.emplace_back(mine, rmginfo.value);
} }
} }
@ -87,15 +87,15 @@ bool MinePlacer::placeMines(ObjectManager & manager)
//create extra resources //create extra resources
if(int extraRes = generator.getConfig().mineExtraResources) if(int extraRes = generator.getConfig().mineExtraResources)
{ {
for(auto * mine : createdMines) for(auto mine : createdMines)
{ {
for(int rc = zone.getRand().nextInt(1, extraRes); rc > 0; --rc) for(int rc = zone.getRand().nextInt(1, extraRes); rc > 0; --rc)
{ {
auto * resource = dynamic_cast<CGResource *>(LIBRARY->objtypeh->getHandlerFor(Obj::RESOURCE, mine->producedResource)->create(map.mapInstance->cb, nullptr)); auto resource = std::dynamic_pointer_cast<CGResource>(LIBRARY->objtypeh->getHandlerFor(Obj::RESOURCE, mine->producedResource)->create(map.mapInstance->cb, nullptr));
RequiredObjectInfo roi; RequiredObjectInfo roi;
roi.obj = resource; roi.obj = resource;
roi.nearbyTarget = mine; roi.nearbyTarget = mine.get();
manager.addNearbyObject(roi); manager.addNearbyObject(roi);
} }
} }

View File

@ -82,7 +82,7 @@ void ObjectDistributor::distributeLimitedObjects()
{ {
ObjectInfo oi(primaryID, secondaryID); ObjectInfo oi(primaryID, secondaryID);
oi.generateObject = [cb=map.mapInstance->cb, primaryID, secondaryID]() -> CGObjectInstance * oi.generateObject = [cb=map.mapInstance->cb, primaryID, secondaryID]()
{ {
return LIBRARY->objtypeh->getHandlerFor(primaryID, secondaryID)->create(cb, nullptr); return LIBRARY->objtypeh->getHandlerFor(primaryID, secondaryID)->create(cb, nullptr);
}; };

View File

@ -406,7 +406,7 @@ bool ObjectManager::createMonoliths()
continue; continue;
} }
rmg::Object rmgObject(*objInfo.obj); rmg::Object rmgObject(objInfo.obj);
rmgObject.setTemplate(zone.getTerrainType(), zone.getRand()); rmgObject.setTemplate(zone.getTerrainType(), zone.getRand());
bool guarded = addGuard(rmgObject, objInfo.guardStrength, true); bool guarded = addGuard(rmgObject, objInfo.guardStrength, true);
@ -442,7 +442,7 @@ bool ObjectManager::createRequiredObjects()
RecursiveLock lock(externalAccessMutex); //In case someone adds more objects RecursiveLock lock(externalAccessMutex); //In case someone adds more objects
for(const auto & objInfo : requiredObjects) for(const auto & objInfo : requiredObjects)
{ {
rmg::Object rmgObject(*objInfo.obj); rmg::Object rmgObject(objInfo.obj);
rmgObject.setTemplate(zone.getTerrainType(), zone.getRand()); rmgObject.setTemplate(zone.getTerrainType(), zone.getRand());
bool guarded = addGuard(rmgObject, objInfo.guardStrength, (objInfo.obj->ID == Obj::MONOLITH_TWO_WAY)); bool guarded = addGuard(rmgObject, objInfo.guardStrength, (objInfo.obj->ID == Obj::MONOLITH_TWO_WAY));
@ -466,10 +466,10 @@ bool ObjectManager::createRequiredObjects()
for(const auto & nearby : nearbyObjects) for(const auto & nearby : nearbyObjects)
{ {
if(nearby.nearbyTarget != nearby.obj) if(nearby.nearbyTarget != nearby.obj.get())
continue; continue;
rmg::Object rmgNearObject(*nearby.obj); rmg::Object rmgNearObject(nearby.obj);
rmg::Area possibleArea(rmgObject.instances().front()->getBlockedArea().getBorderOutside()); rmg::Area possibleArea(rmgObject.instances().front()->getBlockedArea().getBorderOutside());
possibleArea.intersect(zone.areaPossible().get()); possibleArea.intersect(zone.areaPossible().get());
if(possibleArea.empty()) if(possibleArea.empty())
@ -487,7 +487,7 @@ bool ObjectManager::createRequiredObjects()
{ {
Zone::Lock lock(zone.areaMutex); Zone::Lock lock(zone.areaMutex);
rmg::Object rmgObject(*objInfo.obj); rmg::Object rmgObject(objInfo.obj);
rmgObject.setTemplate(zone.getTerrainType(), zone.getRand()); rmgObject.setTemplate(zone.getTerrainType(), zone.getRand());
bool guarded = addGuard(rmgObject, objInfo.guardStrength, (objInfo.obj->ID == Obj::MONOLITH_TWO_WAY)); bool guarded = addGuard(rmgObject, objInfo.guardStrength, (objInfo.obj->ID == Obj::MONOLITH_TWO_WAY));
auto path = placeAndConnectObject(zone.areaPossible().get(), rmgObject, auto path = placeAndConnectObject(zone.areaPossible().get(), rmgObject,
@ -517,7 +517,7 @@ bool ObjectManager::createRequiredObjects()
continue; continue;
} }
rmg::Object rmgNearObject(*nearby.obj); rmg::Object rmgNearObject(nearby.obj);
std::set<int3> blockedArea = targetObject->getBlockedPos(); std::set<int3> blockedArea = targetObject->getBlockedPos();
rmg::Area areaForObject(rmg::Area(rmg::Tileset(blockedArea.begin(), blockedArea.end())).getBorderOutside()); rmg::Area areaForObject(rmg::Area(rmg::Tileset(blockedArea.begin(), blockedArea.end())).getBorderOutside());
areaForObject.intersect(zone.areaPossible().get()); areaForObject.intersect(zone.areaPossible().get());
@ -549,7 +549,7 @@ bool ObjectManager::createRequiredObjects()
//TODO: implement guards //TODO: implement guards
for (const auto &objInfo : instantObjects) //Unused ATM for (const auto &objInfo : instantObjects) //Unused ATM
{ {
rmg::Object rmgObject(*objInfo.obj); rmg::Object rmgObject(objInfo.obj);
rmgObject.setPosition(objInfo.pos); rmgObject.setPosition(objInfo.pos);
placeObject(rmgObject, false, false); placeObject(rmgObject, false, false);
} }
@ -722,7 +722,7 @@ void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateD
} }
} }
CGCreature * ObjectManager::chooseGuard(si32 strength, bool zoneGuard) std::shared_ptr<CGCreature> ObjectManager::chooseGuard(si32 strength, bool zoneGuard)
{ {
//precalculate actual (randomized) monster strength based on this post //precalculate actual (randomized) monster strength based on this post
//http://forum.vcmi.eu/viewtopic.php?p=12426#12426 //http://forum.vcmi.eu/viewtopic.php?p=12426#12426
@ -775,7 +775,7 @@ CGCreature * ObjectManager::chooseGuard(si32 strength, bool zoneGuard)
auto guardFactory = LIBRARY->objtypeh->getHandlerFor(Obj::MONSTER, creId); auto guardFactory = LIBRARY->objtypeh->getHandlerFor(Obj::MONSTER, creId);
auto * guard = dynamic_cast<CGCreature *>(guardFactory->create(map.mapInstance->cb, nullptr)); auto guard = std::dynamic_pointer_cast<CGCreature>(guardFactory->create(map.mapInstance->cb, nullptr));
guard->character = CGCreature::HOSTILE; guard->character = CGCreature::HOSTILE;
auto * hlp = new CStackInstance(creId, amount); auto * hlp = new CStackInstance(creId, amount);
//will be set during initialization //will be set during initialization
@ -785,7 +785,7 @@ CGCreature * ObjectManager::chooseGuard(si32 strength, bool zoneGuard)
bool ObjectManager::addGuard(rmg::Object & object, si32 strength, bool zoneGuard) bool ObjectManager::addGuard(rmg::Object & object, si32 strength, bool zoneGuard)
{ {
auto * guard = chooseGuard(strength, zoneGuard); auto guard = chooseGuard(strength, zoneGuard);
if(!guard) if(!guard)
return false; return false;
@ -805,10 +805,8 @@ bool ObjectManager::addGuard(rmg::Object & object, si32 strength, bool zoneGuard
}); });
if(accessibleArea.empty()) if(accessibleArea.empty())
{
delete guard;
return false; return false;
}
auto guardTiles = accessibleArea.getTilesVector(); auto guardTiles = accessibleArea.getTilesVector();
auto guardPos = *std::min_element(guardTiles.begin(), guardTiles.end(), [&object](const int3 & l, const int3 & r) auto guardPos = *std::min_element(guardTiles.begin(), guardTiles.end(), [&object](const int3 & l, const int3 & r)
{ {
@ -822,7 +820,7 @@ bool ObjectManager::addGuard(rmg::Object & object, si32 strength, bool zoneGuard
return false; return false;
}); });
auto & instance = object.addInstance(*guard); auto & instance = object.addInstance(guard);
instance.setAnyTemplate(zone.getRand()); //terrain is irrelevant for monsters, but monsters need some template now instance.setAnyTemplate(zone.getRand()); //terrain is irrelevant for monsters, but monsters need some template now
//Fix HoTA monsters with offset template //Fix HoTA monsters with offset template
@ -840,7 +838,7 @@ RequiredObjectInfo::RequiredObjectInfo():
createRoad(true) createRoad(true)
{} {}
RequiredObjectInfo::RequiredObjectInfo(CGObjectInstance* obj, ui32 guardStrength, bool createRoad, CGObjectInstance* nearbyTarget): RequiredObjectInfo::RequiredObjectInfo(std::shared_ptr<CGObjectInstance> obj, ui32 guardStrength, bool createRoad, CGObjectInstance* nearbyTarget):
obj(obj), obj(obj),
nearbyTarget(nearbyTarget), nearbyTarget(nearbyTarget),
guardStrength(guardStrength), guardStrength(guardStrength),

View File

@ -32,9 +32,9 @@ struct DistanceMaximizeFunctor
struct RequiredObjectInfo struct RequiredObjectInfo
{ {
RequiredObjectInfo(); RequiredObjectInfo();
RequiredObjectInfo(CGObjectInstance* obj, ui32 guardStrength = 0, bool createRoad = false, CGObjectInstance* nearbyTarget = nullptr); RequiredObjectInfo(std::shared_ptr<CGObjectInstance> obj, ui32 guardStrength = 0, bool createRoad = false, CGObjectInstance* nearbyTarget = nullptr);
CGObjectInstance* obj; std::shared_ptr<CGObjectInstance> obj;
CGObjectInstance* nearbyTarget; CGObjectInstance* nearbyTarget;
int3 pos; int3 pos;
ui32 guardStrength; ui32 guardStrength;
@ -71,7 +71,7 @@ public:
rmg::Path placeAndConnectObject(const rmg::Area & searchArea, rmg::Object & obj, si32 min_dist, bool isGuarded, bool onlyStraight, OptimizeType optimizer) const; rmg::Path placeAndConnectObject(const rmg::Area & searchArea, rmg::Object & obj, si32 min_dist, bool isGuarded, bool onlyStraight, OptimizeType optimizer) const;
rmg::Path placeAndConnectObject(const rmg::Area & searchArea, rmg::Object & obj, const std::function<float(const int3)> & weightFunction, bool isGuarded, bool onlyStraight, OptimizeType optimizer) const; rmg::Path placeAndConnectObject(const rmg::Area & searchArea, rmg::Object & obj, const std::function<float(const int3)> & weightFunction, bool isGuarded, bool onlyStraight, OptimizeType optimizer) const;
CGCreature * chooseGuard(si32 strength, bool zoneGuard = false); std::shared_ptr<CGCreature> chooseGuard(si32 strength, bool zoneGuard = false);
bool addGuard(rmg::Object & object, si32 strength, bool zoneGuard = false); bool addGuard(rmg::Object & object, si32 strength, bool zoneGuard = false);
void placeObject(rmg::Object & object, bool guarded, bool updateDistance, bool createRoad = false); void placeObject(rmg::Object & object, bool guarded, bool updateDistance, bool createRoad = false);

View File

@ -137,7 +137,7 @@ bool ObstaclePlacer::isInTheMap(const int3& tile)
return map.isOnMap(tile); return map.isOnMap(tile);
} }
void ObstaclePlacer::placeObject(rmg::Object & object, std::set<CGObjectInstance*> &) void ObstaclePlacer::placeObject(rmg::Object & object, std::set<std::shared_ptr<CGObjectInstance>> &)
{ {
manager->placeObject(object, false, false); manager->placeObject(object, false, false);
} }

View File

@ -31,7 +31,7 @@ public:
std::pair<bool, bool> verifyCoverage(const int3 & t) const override; std::pair<bool, bool> verifyCoverage(const int3 & t) const override;
void placeObject(rmg::Object & object, std::set<CGObjectInstance*> & instances) override; void placeObject(rmg::Object & object, std::set<std::shared_ptr<CGObjectInstance>> & instances) override;
void postProcess(const rmg::Object & object) override; void postProcess(const rmg::Object & object) override;

View File

@ -403,8 +403,8 @@ void RiverPlacer::connectRiver(const int3 & tile)
{ {
if(templ->animationFile == targetTemplateName) if(templ->animationFile == targetTemplateName)
{ {
auto * obj = handler->create(map.mapInstance->cb, templ); auto obj = handler->create(map.mapInstance->cb, templ);
rmg::Object deltaObj(*obj, deltaPositions[pos]); rmg::Object deltaObj(obj, deltaPositions[pos]);
deltaObj.finalize(map, zone.getRand()); deltaObj.finalize(map, zone.getRand());
} }
} }

View File

@ -101,7 +101,7 @@ void TownPlacer::placeTowns(ObjectManager & manager)
auto townFactory = LIBRARY->objtypeh->getHandlerFor(Obj::TOWN, zone.getTownType()); auto townFactory = LIBRARY->objtypeh->getHandlerFor(Obj::TOWN, zone.getTownType());
CGTownInstance * town = dynamic_cast<CGTownInstance *>(townFactory->create(map.mapInstance->cb, nullptr)); auto town = std::dynamic_pointer_cast<CGTownInstance>(townFactory->create(map.mapInstance->cb, nullptr));
town->tempOwner = player; town->tempOwner = player;
town->addBuilding(BuildingID::FORT); town->addBuilding(BuildingID::FORT);
town->addBuilding(BuildingID::DEFAULT); town->addBuilding(BuildingID::DEFAULT);
@ -110,7 +110,7 @@ void TownPlacer::placeTowns(ObjectManager & manager)
for(auto spellID : LIBRARY->spellh->getDefaultAllowed()) //add all regular spells to town for(auto spellID : LIBRARY->spellh->getDefaultAllowed()) //add all regular spells to town
town->possibleSpells.push_back(spellID); town->possibleSpells.push_back(spellID);
auto position = placeMainTown(manager, *town); auto position = placeMainTown(manager, town);
totalTowns++; totalTowns++;
//register MAIN town of zone only //register MAIN town of zone only
@ -166,7 +166,7 @@ void TownPlacer::placeTowns(ObjectManager & manager)
} }
} }
int3 TownPlacer::placeMainTown(ObjectManager & manager, CGTownInstance & town) int3 TownPlacer::placeMainTown(ObjectManager & manager, std::shared_ptr<CGTownInstance> town)
{ {
//towns are big objects and should be centered around visitable position //towns are big objects and should be centered around visitable position
rmg::Object rmgObject(town); rmg::Object rmgObject(town);
@ -267,7 +267,7 @@ void TownPlacer::addNewTowns(int count, bool hasFort, const PlayerColor & player
} }
auto townFactory = LIBRARY->objtypeh->getHandlerFor(Obj::TOWN, subType); auto townFactory = LIBRARY->objtypeh->getHandlerFor(Obj::TOWN, subType);
auto * town = dynamic_cast<CGTownInstance *>(townFactory->create(map.mapInstance->cb, nullptr)); auto town = std::dynamic_pointer_cast<CGTownInstance>(townFactory->create(map.mapInstance->cb, nullptr));
town->ID = Obj::TOWN; town->ID = Obj::TOWN;
town->tempOwner = player; town->tempOwner = player;
@ -284,7 +284,7 @@ void TownPlacer::addNewTowns(int count, bool hasFort, const PlayerColor & player
//register MAIN town of zone //register MAIN town of zone
map.registerZone(town->getFactionID()); map.registerZone(town->getFactionID());
//first town in zone goes in the middle //first town in zone goes in the middle
placeMainTown(manager, *town); placeMainTown(manager, town);
} }
else else
{ {

View File

@ -32,7 +32,7 @@ protected:
FactionID getTownTypeFromHint(size_t hintIndex); FactionID getTownTypeFromHint(size_t hintIndex);
void placeTowns(ObjectManager & manager); void placeTowns(ObjectManager & manager);
bool placeMines(ObjectManager & manager); bool placeMines(ObjectManager & manager);
int3 placeMainTown(ObjectManager & manager, CGTownInstance & town); int3 placeMainTown(ObjectManager & manager, std::shared_ptr<CGTownInstance> town);
protected: protected:
int totalTowns = 0; int totalTowns = 0;

View File

@ -138,7 +138,7 @@ void TreasurePlacer::addCommonObjects()
void TreasurePlacer::setBasicProperties(ObjectInfo & oi, CompoundMapObjectID objid) const void TreasurePlacer::setBasicProperties(ObjectInfo & oi, CompoundMapObjectID objid) const
{ {
oi.generateObject = [this, objid]() -> CGObjectInstance * oi.generateObject = [this, objid]() -> std::shared_ptr<CGObjectInstance>
{ {
return LIBRARY->objtypeh->getHandlerFor(objid)->create(map.mapInstance->cb, nullptr); return LIBRARY->objtypeh->getHandlerFor(objid)->create(map.mapInstance->cb, nullptr);
}; };
@ -176,11 +176,11 @@ void TreasurePlacer::addPrisons()
continue; continue;
} }
oi.generateObject = [i, this, prisonHeroPlacer]() -> CGObjectInstance* oi.generateObject = [i, this, prisonHeroPlacer]() -> std::shared_ptr<CGObjectInstance>
{ {
HeroTypeID hid = prisonHeroPlacer->drawRandomHero(); HeroTypeID hid = prisonHeroPlacer->drawRandomHero();
auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::PRISON, 0); auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::PRISON, 0);
auto* obj = dynamic_cast<CGHeroInstance*>(factory->create(map.mapInstance->cb, nullptr)); auto obj = std::dynamic_pointer_cast<CGHeroInstance>(factory->create(map.mapInstance->cb, nullptr));
obj->setHeroType(hid); //will be initialized later obj->setHeroType(hid); //will be initialized later
obj->exp = generator.getConfig().prisonExperience[i]; obj->exp = generator.getConfig().prisonExperience[i];
@ -188,11 +188,11 @@ void TreasurePlacer::addPrisons()
return obj; return obj;
}; };
oi.destroyObject = [prisonHeroPlacer](CGObjectInstance* obj) oi.destroyObject = [prisonHeroPlacer](CGObjectInstance& obj)
{ {
// Hero can be used again // Hero can be used again
auto* hero = dynamic_cast<CGHeroInstance*>(obj); auto & hero = dynamic_cast<CGHeroInstance&>(obj);
prisonHeroPlacer->restoreDrawnHero(hero->getHeroTypeID()); prisonHeroPlacer->restoreDrawnHero(hero.getHeroTypeID());
}; };
oi.setTemplates(Obj::PRISON, 0, zone.getTerrainType()); oi.setTemplates(Obj::PRISON, 0, zone.getTerrainType());
@ -245,9 +245,9 @@ void TreasurePlacer::addDwellings()
oi.value = static_cast<ui32>(cre->getAIValue() * cre->getGrowth() * (1 + (nativeZonesCount / map.getTotalZoneCount()) + (nativeZonesCount / 2))); oi.value = static_cast<ui32>(cre->getAIValue() * cre->getGrowth() * (1 + (nativeZonesCount / map.getTotalZoneCount()) + (nativeZonesCount / 2)));
oi.probability = 40; oi.probability = 40;
oi.generateObject = [this, secondaryID, dwellingType]() -> CGObjectInstance * oi.generateObject = [this, secondaryID, dwellingType]() -> std::shared_ptr<CGObjectInstance>
{ {
auto * obj = LIBRARY->objtypeh->getHandlerFor(dwellingType, secondaryID)->create(map.mapInstance->cb, nullptr); auto obj = LIBRARY->objtypeh->getHandlerFor(dwellingType, secondaryID)->create(map.mapInstance->cb, nullptr);
obj->tempOwner = PlayerColor::NEUTRAL; obj->tempOwner = PlayerColor::NEUTRAL;
return obj; return obj;
}; };
@ -267,10 +267,10 @@ void TreasurePlacer::addScrolls()
for(int i = 0; i < generator.getConfig().scrollValues.size(); i++) for(int i = 0; i < generator.getConfig().scrollValues.size(); i++)
{ {
oi.generateObject = [i, this]() -> CGObjectInstance * oi.generateObject = [i, this]() -> std::shared_ptr<CGObjectInstance>
{ {
auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::SPELL_SCROLL, 0); auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::SPELL_SCROLL, 0);
auto * obj = dynamic_cast<CGArtifact *>(factory->create(map.mapInstance->cb, nullptr)); auto obj = std::dynamic_pointer_cast<CGArtifact>(factory->create(map.mapInstance->cb, nullptr));
std::vector<SpellID> out; std::vector<SpellID> out;
for(auto spellID : LIBRARY->spellh->getDefaultAllowed()) for(auto spellID : LIBRARY->spellh->getDefaultAllowed())
@ -307,10 +307,10 @@ void TreasurePlacer::addPandoraBoxesWithGold()
ObjectInfo oi(Obj::PANDORAS_BOX, 0); ObjectInfo oi(Obj::PANDORAS_BOX, 0);
for(int i = 1; i < 5; i++) for(int i = 1; i < 5; i++)
{ {
oi.generateObject = [this, i]() -> CGObjectInstance * oi.generateObject = [this, i]() -> std::shared_ptr<CGObjectInstance>
{ {
auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0); auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0);
auto * obj = dynamic_cast<CGPandoraBox *>(factory->create(map.mapInstance->cb, nullptr)); auto obj = std::dynamic_pointer_cast<CGPandoraBox>(factory->create(map.mapInstance->cb, nullptr));
Rewardable::VisitInfo reward; Rewardable::VisitInfo reward;
reward.reward.resources[EGameResID::GOLD] = i * 5000; reward.reward.resources[EGameResID::GOLD] = i * 5000;
@ -332,10 +332,10 @@ void TreasurePlacer::addPandoraBoxesWithExperience()
ObjectInfo oi(Obj::PANDORAS_BOX, 0); ObjectInfo oi(Obj::PANDORAS_BOX, 0);
for(int i = 1; i < 5; i++) for(int i = 1; i < 5; i++)
{ {
oi.generateObject = [this, i]() -> CGObjectInstance * oi.generateObject = [this, i]() -> std::shared_ptr<CGObjectInstance>
{ {
auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0); auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0);
auto * obj = dynamic_cast<CGPandoraBox *>(factory->create(map.mapInstance->cb, nullptr)); auto obj = std::dynamic_pointer_cast<CGPandoraBox>(factory->create(map.mapInstance->cb, nullptr));
Rewardable::VisitInfo reward; Rewardable::VisitInfo reward;
reward.reward.heroExperience = i * 5000; reward.reward.heroExperience = i * 5000;
@ -362,10 +362,10 @@ void TreasurePlacer::addPandoraBoxesWithCreatures()
ObjectInfo oi(Obj::PANDORAS_BOX, 0); ObjectInfo oi(Obj::PANDORAS_BOX, 0);
oi.generateObject = [this, creature, creaturesAmount]() -> CGObjectInstance * oi.generateObject = [this, creature, creaturesAmount]() -> std::shared_ptr<CGObjectInstance>
{ {
auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0); auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0);
auto * obj = dynamic_cast<CGPandoraBox *>(factory->create(map.mapInstance->cb, nullptr)); auto obj = std::dynamic_pointer_cast<CGPandoraBox>(factory->create(map.mapInstance->cb, nullptr));
Rewardable::VisitInfo reward; Rewardable::VisitInfo reward;
reward.reward.creatures.emplace_back(creature, creaturesAmount); reward.reward.creatures.emplace_back(creature, creaturesAmount);
@ -388,10 +388,10 @@ void TreasurePlacer::addPandoraBoxesWithSpells()
//Pandora with 12 spells of certain level //Pandora with 12 spells of certain level
for(int i = 1; i <= GameConstants::SPELL_LEVELS; i++) for(int i = 1; i <= GameConstants::SPELL_LEVELS; i++)
{ {
oi.generateObject = [i, this]() -> CGObjectInstance * oi.generateObject = [i, this]() -> std::shared_ptr<CGObjectInstance>
{ {
auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0); auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0);
auto * obj = dynamic_cast<CGPandoraBox *>(factory->create(map.mapInstance->cb, nullptr)); auto obj = std::dynamic_pointer_cast<CGPandoraBox>(factory->create(map.mapInstance->cb, nullptr));
std::vector <const CSpell *> spells; std::vector <const CSpell *> spells;
for(auto spellID : LIBRARY->spellh->getDefaultAllowed()) for(auto spellID : LIBRARY->spellh->getDefaultAllowed())
@ -421,10 +421,10 @@ void TreasurePlacer::addPandoraBoxesWithSpells()
//Pandora with 15 spells of certain school //Pandora with 15 spells of certain school
for(int i = 0; i < 4; i++) for(int i = 0; i < 4; i++)
{ {
oi.generateObject = [i, this]() -> CGObjectInstance * oi.generateObject = [i, this]() -> std::shared_ptr<CGObjectInstance>
{ {
auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0); auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0);
auto * obj = dynamic_cast<CGPandoraBox *>(factory->create(map.mapInstance->cb, nullptr)); auto obj = std::dynamic_pointer_cast<CGPandoraBox>(factory->create(map.mapInstance->cb, nullptr));
std::vector <const CSpell *> spells; std::vector <const CSpell *> spells;
for(auto spellID : LIBRARY->spellh->getDefaultAllowed()) for(auto spellID : LIBRARY->spellh->getDefaultAllowed())
@ -453,10 +453,10 @@ void TreasurePlacer::addPandoraBoxesWithSpells()
// Pandora box with 60 random spells // Pandora box with 60 random spells
oi.generateObject = [this]() -> CGObjectInstance * oi.generateObject = [this]() -> std::shared_ptr<CGObjectInstance>
{ {
auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0); auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0);
auto * obj = dynamic_cast<CGPandoraBox *>(factory->create(map.mapInstance->cb, nullptr)); auto obj = std::dynamic_pointer_cast<CGPandoraBox>(factory->create(map.mapInstance->cb, nullptr));
std::vector <const CSpell *> spells; std::vector <const CSpell *> spells;
for(auto spellID : LIBRARY->spellh->getDefaultAllowed()) for(auto spellID : LIBRARY->spellh->getDefaultAllowed())
@ -518,11 +518,11 @@ void TreasurePlacer::addSeerHuts()
obj->quest->mission.artifacts.push_back(artid); obj->quest->mission.artifacts.push_back(artid);
qap->addQuestArtifact(artid); qap->addQuestArtifact(artid);
}; };
auto destroyObject = [qap](CGObjectInstance * obj) auto destroyObject = [qap](CGObjectInstance & obj)
{ {
auto * seer = dynamic_cast<CGSeerHut *>(obj); auto & seer = dynamic_cast<CGSeerHut &>(obj);
// Artifact can be used again // Artifact can be used again
ArtifactID artid = seer->getQuest()->mission.artifacts.front(); ArtifactID artid = seer.getQuest()->mission.artifacts.front();
qap->addRandomArtifact(artid); qap->addRandomArtifact(artid);
qap->removeQuestArtifact(artid); qap->removeQuestArtifact(artid);
}; };
@ -538,17 +538,16 @@ void TreasurePlacer::addSeerHuts()
int randomAppearance = chooseRandomAppearance(zone.getRand(), Obj::SEER_HUT, zone.getTerrainType()); int randomAppearance = chooseRandomAppearance(zone.getRand(), Obj::SEER_HUT, zone.getTerrainType());
// FIXME: Remove duplicated code for gold, exp and creaure reward // FIXME: Remove duplicated code for gold, exp and creaure reward
oi.generateObject = [cb=map.mapInstance->cb, creature, creaturesAmount, randomAppearance, setRandomArtifact]() -> CGObjectInstance * oi.generateObject = [cb=map.mapInstance->cb, creature, creaturesAmount, randomAppearance, setRandomArtifact]() -> std::shared_ptr<CGObjectInstance>
{ {
auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::SEER_HUT, randomAppearance); auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::SEER_HUT, randomAppearance);
auto * obj = dynamic_cast<CGSeerHut *>(factory->create(cb, nullptr)); auto obj = std::dynamic_pointer_cast<CGSeerHut>(factory->create(cb, nullptr));
Rewardable::VisitInfo reward; Rewardable::VisitInfo reward;
reward.reward.creatures.emplace_back(creature->getId(), creaturesAmount); reward.reward.creatures.emplace_back(creature->getId(), creaturesAmount);
reward.visitType = Rewardable::EEventType::EVENT_FIRST_VISIT; reward.visitType = Rewardable::EEventType::EVENT_FIRST_VISIT;
obj->configuration.info.push_back(reward); obj->configuration.info.push_back(reward);
setRandomArtifact(obj.get());
setRandomArtifact(obj);
return obj; return obj;
}; };
@ -583,17 +582,16 @@ void TreasurePlacer::addSeerHuts()
oi.probability = 10; oi.probability = 10;
oi.maxPerZone = 1; oi.maxPerZone = 1;
oi.generateObject = [i, randomAppearance, this, setRandomArtifact]() -> CGObjectInstance * oi.generateObject = [i, randomAppearance, this, setRandomArtifact]() -> std::shared_ptr<CGObjectInstance>
{ {
auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::SEER_HUT, randomAppearance); auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::SEER_HUT, randomAppearance);
auto * obj = dynamic_cast<CGSeerHut *>(factory->create(map.mapInstance->cb, nullptr)); auto obj = std::dynamic_pointer_cast<CGSeerHut>(factory->create(map.mapInstance->cb, nullptr));
Rewardable::VisitInfo reward; Rewardable::VisitInfo reward;
reward.reward.heroExperience = generator.getConfig().questRewardValues[i]; reward.reward.heroExperience = generator.getConfig().questRewardValues[i];
reward.visitType = Rewardable::EEventType::EVENT_FIRST_VISIT; reward.visitType = Rewardable::EEventType::EVENT_FIRST_VISIT;
obj->configuration.info.push_back(reward); obj->configuration.info.push_back(reward);
setRandomArtifact(obj.get());
setRandomArtifact(obj);
return obj; return obj;
}; };
@ -602,17 +600,17 @@ void TreasurePlacer::addSeerHuts()
if(!oi.templates.empty()) if(!oi.templates.empty())
possibleSeerHuts.push_back(oi); possibleSeerHuts.push_back(oi);
oi.generateObject = [i, randomAppearance, this, setRandomArtifact]() -> CGObjectInstance * oi.generateObject = [i, randomAppearance, this, setRandomArtifact]() -> std::shared_ptr<CGObjectInstance>
{ {
auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::SEER_HUT, randomAppearance); auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::SEER_HUT, randomAppearance);
auto * obj = dynamic_cast<CGSeerHut *>(factory->create(map.mapInstance->cb, nullptr)); auto obj = std::dynamic_pointer_cast<CGSeerHut>(factory->create(map.mapInstance->cb, nullptr));
Rewardable::VisitInfo reward; Rewardable::VisitInfo reward;
reward.reward.resources[EGameResID::GOLD] = generator.getConfig().questRewardValues[i]; reward.reward.resources[EGameResID::GOLD] = generator.getConfig().questRewardValues[i];
reward.visitType = Rewardable::EEventType::EVENT_FIRST_VISIT; reward.visitType = Rewardable::EEventType::EVENT_FIRST_VISIT;
obj->configuration.info.push_back(reward); obj->configuration.info.push_back(reward);
setRandomArtifact(obj); setRandomArtifact(obj.get());
return obj; return obj;
}; };
@ -748,15 +746,14 @@ rmg::Object TreasurePlacer::constructTreasurePile(const std::vector<ObjectInfo*>
accessibleArea.add(int3()); accessibleArea.add(int3());
} }
CGObjectInstance * object = nullptr; std::shared_ptr<CGObjectInstance> object = nullptr;
if (oi->generateObject) if (oi->generateObject)
{ {
object = oi->generateObject(); object = oi->generateObject();
if(oi->templates.empty()) if(oi->templates.empty())
{ {
logGlobal->warn("Deleting randomized object with no templates: %s", object->getObjectName()); logGlobal->warn("Deleting randomized object with no templates: %s", object->getObjectName());
oi->destroyObject(object); oi->destroyObject(*object);
delete object;
continue; continue;
} }
} }
@ -785,7 +782,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); rmgObject.setValue(rmgObject.getValue() + oi->value);
instance.onCleared = oi->destroyObject; instance.onCleared = oi->destroyObject;

View File

@ -250,8 +250,8 @@ bool WaterProxy::placeBoat(Zone & land, const Lake & lake, bool createRoad, Rout
for(auto subObj : subObjects) for(auto subObj : subObjects)
{ {
//making a temporary object //making a temporary object
std::unique_ptr<CGObjectInstance> obj(LIBRARY->objtypeh->getHandlerFor(Obj::BOAT, subObj)->create(map.mapInstance->cb, nullptr)); auto obj(LIBRARY->objtypeh->getHandlerFor(Obj::BOAT, subObj)->create(map.mapInstance->cb, nullptr));
if(auto * testBoat = dynamic_cast<CGBoat *>(obj.get())) if(auto testBoat = dynamic_cast<CGBoat *>(obj.get()))
{ {
if(testBoat->layer == EPathfindingLayer::SAIL) if(testBoat->layer == EPathfindingLayer::SAIL)
sailingBoatTypes.insert(subObj); sailingBoatTypes.insert(subObj);
@ -261,9 +261,9 @@ bool WaterProxy::placeBoat(Zone & land, const Lake & lake, bool createRoad, Rout
if(sailingBoatTypes.empty()) if(sailingBoatTypes.empty())
return false; return false;
auto * boat = dynamic_cast<CGBoat *>(LIBRARY->objtypeh->getHandlerFor(Obj::BOAT, *RandomGeneratorUtil::nextItem(sailingBoatTypes, zone.getRand()))->create(map.mapInstance->cb, nullptr)); auto boat = std::dynamic_pointer_cast<CGBoat>(LIBRARY->objtypeh->getHandlerFor(Obj::BOAT, *RandomGeneratorUtil::nextItem(sailingBoatTypes, zone.getRand()))->create(map.mapInstance->cb, nullptr));
rmg::Object rmgObject(*boat); rmg::Object rmgObject(boat);
rmgObject.setTemplate(zone.getTerrainType(), zone.getRand()); rmgObject.setTemplate(zone.getTerrainType(), zone.getRand());
auto waterAvailable = zone.areaForRoads(); auto waterAvailable = zone.areaForRoads();
@ -325,10 +325,10 @@ bool WaterProxy::placeShipyard(Zone & land, const Lake & lake, si32 guard, bool
return false; return false;
int subtype = chooseRandomAppearance(zone.getRand(), Obj::SHIPYARD, land.getTerrainType()); int subtype = chooseRandomAppearance(zone.getRand(), Obj::SHIPYARD, land.getTerrainType());
auto * shipyard = dynamic_cast<CGShipyard *>(LIBRARY->objtypeh->getHandlerFor(Obj::SHIPYARD, subtype)->create(map.mapInstance->cb, nullptr)); auto shipyard = std::dynamic_pointer_cast<CGShipyard>(LIBRARY->objtypeh->getHandlerFor(Obj::SHIPYARD, subtype)->create(map.mapInstance->cb, nullptr));
shipyard->tempOwner = PlayerColor::NEUTRAL; shipyard->tempOwner = PlayerColor::NEUTRAL;
rmg::Object rmgObject(*shipyard); rmg::Object rmgObject(shipyard);
rmgObject.setTemplate(land.getTerrainType(), zone.getRand()); rmgObject.setTemplate(land.getTerrainType(), zone.getRand());
bool guarded = manager->addGuard(rmgObject, guard); bool guarded = manager->addGuard(rmgObject, guard);