Ver Fonte

Map objects now use shared_ptr (rmg)

Ivan Savenko há 7 meses atrás
pai
commit
84cf7b052d

+ 1 - 1
lib/mapping/ObstacleProxy.cpp

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

+ 2 - 2
lib/rmg/MapProxy.cpp

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

+ 2 - 2
lib/rmg/MapProxy.h

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

+ 2 - 2
lib/rmg/ObjectInfo.cpp

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

+ 3 - 3
lib/rmg/ObjectInfo.h

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

+ 41 - 37
lib/rmg/RmgObject.cpp

@@ -27,12 +27,12 @@ VCMI_LIB_NAMESPACE_BEGIN
 
 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);
 }
 
-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);
 }
@@ -41,10 +41,10 @@ const Area & Object::Instance::getBlockedArea() const
 {
 	if(dBlockedAreaCache.empty())
 	{
-		std::set<int3> blockedArea = dObject.getBlockedPos();
+		std::set<int3> blockedArea = dObject->getBlockedPos();
 		dBlockedAreaCache.assign(rmg::Tileset(blockedArea.begin(), blockedArea.end()));
-		if(dObject.isVisitable() || dBlockedAreaCache.empty())
-			dBlockedAreaCache.add(dObject.visitablePos());
+		if(dObject->isVisitable() || dBlockedAreaCache.empty())
+			dBlockedAreaCache.add(dObject->visitablePos());
 	}
 	return dBlockedAreaCache;
 }
@@ -64,7 +64,7 @@ int3 Object::Instance::getPosition(bool isAbsolute) const
 
 int3 Object::Instance::getVisitablePosition() const
 {
-	return dObject.visitablePos();
+	return dObject->visitablePos();
 }
 
 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)
 {
 	dPosition = position;
-	dObject.setAnchorPos(dPosition + dParent.getPosition());
+	dObject->setAnchorPos(dPosition + dParent.getPosition());
 	
 	dBlockedAreaCache.clear();
 	dAccessibleAreaCache.clear();
@@ -96,45 +96,45 @@ void Object::Instance::setPosition(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();
 		dAccessibleAreaCache.clear();
 		dParent.clearCachedArea();
 	}
 		
-	auto shift = position + dParent.getPosition() - dObject.anchorPos();
+	auto shift = position + dParent.getPosition() - dObject->anchorPos();
 	
 	dAccessibleAreaCache.translate(shift);
 	dBlockedAreaCache.translate(shift);
 	
 	dPosition = position;
-	dObject.setAnchorPos(dPosition + dParent.getPosition());
+	dObject->setAnchorPos(dPosition + dParent.getPosition());
 }
 
 void Object::Instance::setAnyTemplate(vstd::RNG & rng)
 {
-	auto templates = dObject.getObjectHandler()->getTemplates();
+	auto templates = dObject->getObjectHandler()->getTemplates();
 	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();
 	setPosition(getPosition(false));
 }
 
 void Object::Instance::setTemplate(TerrainId terrain, vstd::RNG & rng)
 {
-	auto templates = dObject.getObjectHandler()->getMostSpecificTemplates(terrain);
+	auto templates = dObject->getObjectHandler()->getMostSpecificTemplates(terrain);
 
 	if (templates.empty())
 	{
 		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();
 	setPosition(getPosition(false));
 }
@@ -142,9 +142,8 @@ void Object::Instance::setTemplate(TerrainId terrain, vstd::RNG & rng)
 void Object::Instance::clear()
 {
 	if (onCleared)
-		onCleared(&dObject);
+		onCleared(*dObject);
 
-	delete &dObject;
 	dBlockedAreaCache.clear();
 	dAccessibleAreaCache.clear();
 	dParent.clearCachedArea();
@@ -153,37 +152,42 @@ void Object::Instance::clear()
 bool Object::Instance::isVisitableFrom(const int3 & position) const
 {
 	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
 {
-	return dObject.isBlockedVisitable();
+	return dObject->isBlockedVisitable();
 }
 
 bool Object::Instance::isRemovable() const
 {
-	return dObject.isRemovable();
+	return dObject->isRemovable();
 }
 
 CGObjectInstance & Object::Instance::object()
+{
+	return *dObject;
+}
+
+std::shared_ptr<CGObjectInstance> Object::Instance::pointer() const
 {
 	return dObject;
 }
 
 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),
 	value(0)
 {
 	addInstance(object, position);
 }
 
-Object::Object(CGObjectInstance & object):
+Object::Object(std::shared_ptr<CGObjectInstance> object):
 	guarded(false),
 	value(0)
 {
@@ -195,7 +199,7 @@ Object::Object(const Object & object):
 	value(object.value)
 {
 	for(const auto & i : object.dInstances)
-		addInstance(const_cast<CGObjectInstance &>(i.object()), i.getPosition());
+		addInstance(i.pointer(), i.getPosition());
 	setPosition(object.getPosition());
 }
 
@@ -231,7 +235,7 @@ void Object::addInstance(Instance & object)
 	visibleTopOffset.reset();
 }
 
-Object::Instance & Object::addInstance(CGObjectInstance & object)
+Object::Instance & Object::addInstance(std::shared_ptr<CGObjectInstance> object)
 {
 	dInstances.emplace_back(*this, object);
 	setGuardedIfMonster(dInstances.back());
@@ -243,7 +247,7 @@ Object::Instance & Object::addInstance(CGObjectInstance & object)
 	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);
 	setGuardedIfMonster(dInstances.back());
@@ -498,16 +502,16 @@ rmg::Area Object::Instance::getBorderAbove() const
 void Object::Instance::finalize(RmgMap & map, vstd::RNG & rng)
 {
 	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 (!dObject.appearance)
+	if (!dObject->appearance)
 	{
 		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())
 		{
-			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
 		{
@@ -515,13 +519,13 @@ void Object::Instance::finalize(RmgMap & map, vstd::RNG & rng)
 		}
 	}
 
-	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()));
+	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()));
 
-	for(const auto & tile : dObject.getBlockedPos())
+	for(const auto & tile : dObject->getBlockedPos())
 	{
 		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())
@@ -529,7 +533,7 @@ void Object::Instance::finalize(RmgMap & map, vstd::RNG & rng)
 		map.setOccupied(tile, ETileType::USED);
 	}
 	
-	map.getMapProxy()->insertObject(&dObject);
+	map.getMapProxy()->insertObject(dObject);
 }
 
 void Object::finalize(RmgMap & map, vstd::RNG & rng)

+ 9 - 8
lib/rmg/RmgObject.h

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

+ 8 - 8
lib/rmg/modificators/ConnectionsPlacer.cpp

@@ -277,7 +277,7 @@ void ConnectionsPlacer::selfSideDirectConnection(const rmg::ZoneConnection & con
 		{
 			assert(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());
 			border.unite(otherZone->area()->getBorder());
@@ -302,7 +302,7 @@ void ConnectionsPlacer::selfSideDirectConnection(const rmg::ZoneConnection & con
 				
 				if(monsterType)
 				{
-					rmg::Object monster(*monsterType);
+					rmg::Object monster(monsterType);
 					monster.setPosition(guardPos);
 					manager.placeObject(monster, false, true);
 					//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 factory = LIBRARY->objtypeh->getHandlerFor(Obj::SUBTERRANEAN_GATE, 0);
-			auto * gate1 = factory->create(map.mapInstance->cb, nullptr);
-			auto * gate2 = factory->create(map.mapInstance->cb, nullptr);
-			rmg::Object rmgGate1(*gate1);
-			rmg::Object rmgGate2(*gate2);
+			auto gate1 = factory->create(map.mapInstance->cb, nullptr);
+			auto gate2 = factory->create(map.mapInstance->cb, nullptr);
+			rmg::Object rmgGate1(gate1);
+			rmg::Object rmgGate2(gate2);
 			rmgGate1.setTemplate(zone.getTerrainType(), zone.getRand());
 			rmgGate2.setTemplate(otherZone->getTerrainType(), zone.getRand());
 			bool guarded1 = manager.addGuard(rmgGate1, connection.getGuardStrength(), true);
@@ -447,8 +447,8 @@ void ConnectionsPlacer::placeMonolithConnection(const rmg::ZoneConnection & conn
 	bool allowRoad = shouldGenerateRoad(connection);
 
 	auto factory = LIBRARY->objtypeh->getHandlerFor(Obj::MONOLITH_TWO_WAY, generator.getNextMonlithIndex());
-	auto * teleport1 = factory->create(map.mapInstance->cb, nullptr);
-	auto * teleport2 = factory->create(map.mapInstance->cb, nullptr);
+	auto teleport1 = factory->create(map.mapInstance->cb, nullptr);
+	auto teleport2 = factory->create(map.mapInstance->cb, nullptr);
 
 	RequiredObjectInfo obj1(teleport1, connection.getGuardStrength(), allowRoad);
 	RequiredObjectInfo obj2(teleport2, connection.getGuardStrength(), allowRoad);

+ 7 - 7
lib/rmg/modificators/MinePlacer.cpp

@@ -49,9 +49,9 @@ void MinePlacer::init()
 
 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())
 	{
@@ -60,7 +60,7 @@ bool MinePlacer::placeMines(ObjectManager & manager)
 		{
 			auto mineHandler = LIBRARY->objtypeh->getHandlerFor(Obj::MINE, res);
 			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->tempOwner = PlayerColor::NEUTRAL;
 			mine->producedQuantity = mine->defaultResProduction();
@@ -73,7 +73,7 @@ bool MinePlacer::placeMines(ObjectManager & manager)
 				manager.addCloseObject(RequiredObjectInfo(mine, rmginfo.value));
 			}
 			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
 	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)
 			{
-				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;
 				roi.obj = resource;
-				roi.nearbyTarget = mine;
+				roi.nearbyTarget = mine.get();
 				manager.addNearbyObject(roi);
 			}
 		}

+ 1 - 1
lib/rmg/modificators/ObjectDistributor.cpp

@@ -82,7 +82,7 @@ void ObjectDistributor::distributeLimitedObjects()
 					{
 						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);
 						};

+ 13 - 15
lib/rmg/modificators/ObjectManager.cpp

@@ -406,7 +406,7 @@ bool ObjectManager::createMonoliths()
 			continue;
 		}
 
-		rmg::Object rmgObject(*objInfo.obj);
+		rmg::Object rmgObject(objInfo.obj);
 		rmgObject.setTemplate(zone.getTerrainType(), zone.getRand());
 		bool guarded = addGuard(rmgObject, objInfo.guardStrength, true);
 
@@ -442,7 +442,7 @@ bool ObjectManager::createRequiredObjects()
 	RecursiveLock lock(externalAccessMutex); //In case someone adds more objects
 	for(const auto & objInfo : requiredObjects)
 	{
-		rmg::Object rmgObject(*objInfo.obj);
+		rmg::Object rmgObject(objInfo.obj);
 		rmgObject.setTemplate(zone.getTerrainType(), zone.getRand());
 		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)
 		{
-			if(nearby.nearbyTarget != nearby.obj)
+			if(nearby.nearbyTarget != nearby.obj.get())
 				continue;
 			
-			rmg::Object rmgNearObject(*nearby.obj);
+			rmg::Object rmgNearObject(nearby.obj);
 			rmg::Area possibleArea(rmgObject.instances().front()->getBlockedArea().getBorderOutside());
 			possibleArea.intersect(zone.areaPossible().get());
 			if(possibleArea.empty())
@@ -487,7 +487,7 @@ bool ObjectManager::createRequiredObjects()
 	{
 		Zone::Lock lock(zone.areaMutex);
 
-		rmg::Object rmgObject(*objInfo.obj);
+		rmg::Object rmgObject(objInfo.obj);
 		rmgObject.setTemplate(zone.getTerrainType(), zone.getRand());
 		bool guarded = addGuard(rmgObject, objInfo.guardStrength, (objInfo.obj->ID == Obj::MONOLITH_TWO_WAY));
 		auto path = placeAndConnectObject(zone.areaPossible().get(), rmgObject,
@@ -517,7 +517,7 @@ bool ObjectManager::createRequiredObjects()
 			continue;
 		}
 
-		rmg::Object rmgNearObject(*nearby.obj);
+		rmg::Object rmgNearObject(nearby.obj);
 		std::set<int3> blockedArea = targetObject->getBlockedPos();
 		rmg::Area areaForObject(rmg::Area(rmg::Tileset(blockedArea.begin(), blockedArea.end())).getBorderOutside());
 		areaForObject.intersect(zone.areaPossible().get());
@@ -549,7 +549,7 @@ bool ObjectManager::createRequiredObjects()
 	//TODO: implement guards
 	for (const auto &objInfo : instantObjects) //Unused ATM
 	{
-		rmg::Object rmgObject(*objInfo.obj);
+		rmg::Object rmgObject(objInfo.obj);
 		rmgObject.setPosition(objInfo.pos);
 		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
 	//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 * 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;
 	auto * hlp = new CStackInstance(creId, amount);
 	//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)
 {
-	auto * guard = chooseGuard(strength, zoneGuard);
+	auto guard = chooseGuard(strength, zoneGuard);
 	if(!guard)
 		return false;
 	
@@ -805,10 +805,8 @@ bool ObjectManager::addGuard(rmg::Object & object, si32 strength, bool zoneGuard
 	});
 	
 	if(accessibleArea.empty())
-	{
-		delete guard;
 		return false;
-	}
+
 	auto guardTiles = accessibleArea.getTilesVector();
 	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;
 	});
 	
-	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
 
 	//Fix HoTA monsters with offset template
@@ -840,7 +838,7 @@ RequiredObjectInfo::RequiredObjectInfo():
 	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),
 	nearbyTarget(nearbyTarget),
 	guardStrength(guardStrength),

+ 3 - 3
lib/rmg/modificators/ObjectManager.h

@@ -32,9 +32,9 @@ struct DistanceMaximizeFunctor
 struct 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;
 	int3 pos;
 	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, 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);
 	void placeObject(rmg::Object & object, bool guarded, bool updateDistance, bool createRoad = false);
 

+ 1 - 1
lib/rmg/modificators/ObstaclePlacer.cpp

@@ -137,7 +137,7 @@ bool ObstaclePlacer::isInTheMap(const int3& 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);
 }

+ 1 - 1
lib/rmg/modificators/ObstaclePlacer.h

@@ -31,7 +31,7 @@ public:
 	
 	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;
 	

+ 2 - 2
lib/rmg/modificators/RiverPlacer.cpp

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

+ 5 - 5
lib/rmg/modificators/TownPlacer.cpp

@@ -101,7 +101,7 @@ void TownPlacer::placeTowns(ObjectManager & manager)
 		
 		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->addBuilding(BuildingID::FORT);
 		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
 			town->possibleSpells.push_back(spellID);
 		
-		auto position = placeMainTown(manager, *town);
+		auto position = placeMainTown(manager, town);
 		
 		totalTowns++;
 		//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
 	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 * 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->tempOwner = player;
@@ -284,7 +284,7 @@ void TownPlacer::addNewTowns(int count, bool hasFort, const PlayerColor & player
 			//register MAIN town of zone
 			map.registerZone(town->getFactionID());
 			//first town in zone goes in the middle
-			placeMainTown(manager, *town);
+			placeMainTown(manager, town);
 		}
 		else
 		{

+ 1 - 1
lib/rmg/modificators/TownPlacer.h

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

+ 37 - 40
lib/rmg/modificators/TreasurePlacer.cpp

@@ -138,7 +138,7 @@ void TreasurePlacer::addCommonObjects()
 
 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);
 	};
@@ -176,11 +176,11 @@ void TreasurePlacer::addPrisons()
 				continue;
 			}
 
-			oi.generateObject = [i, this, prisonHeroPlacer]() -> CGObjectInstance*
+			oi.generateObject = [i, this, prisonHeroPlacer]() -> std::shared_ptr<CGObjectInstance>
 			{
 				HeroTypeID hid = prisonHeroPlacer->drawRandomHero();
 				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->exp = generator.getConfig().prisonExperience[i];
@@ -188,11 +188,11 @@ void TreasurePlacer::addPrisons()
 
 				return obj;
 			};
-			oi.destroyObject = [prisonHeroPlacer](CGObjectInstance* obj)
+			oi.destroyObject = [prisonHeroPlacer](CGObjectInstance& obj)
 			{
 				// Hero can be used again
-				auto* hero = dynamic_cast<CGHeroInstance*>(obj);
-				prisonHeroPlacer->restoreDrawnHero(hero->getHeroTypeID());
+				auto & hero = dynamic_cast<CGHeroInstance&>(obj);
+				prisonHeroPlacer->restoreDrawnHero(hero.getHeroTypeID());
 			};
 
 			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.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;
 					return obj;
 				};
@@ -267,10 +267,10 @@ void TreasurePlacer::addScrolls()
 
 	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 * 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;
 			
 			for(auto spellID : LIBRARY->spellh->getDefaultAllowed())
@@ -307,10 +307,10 @@ void TreasurePlacer::addPandoraBoxesWithGold()
 	ObjectInfo oi(Obj::PANDORAS_BOX, 0);
 	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 * 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;
 			reward.reward.resources[EGameResID::GOLD] = i * 5000;
@@ -332,10 +332,10 @@ void TreasurePlacer::addPandoraBoxesWithExperience()
 	ObjectInfo oi(Obj::PANDORAS_BOX, 0);
 	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 * 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;
 			reward.reward.heroExperience = i * 5000;
@@ -362,10 +362,10 @@ void TreasurePlacer::addPandoraBoxesWithCreatures()
 
 		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 * 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;
 			reward.reward.creatures.emplace_back(creature, creaturesAmount);
@@ -388,10 +388,10 @@ void TreasurePlacer::addPandoraBoxesWithSpells()
 	//Pandora with 12 spells of certain level
 	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 * 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;
 			for(auto spellID : LIBRARY->spellh->getDefaultAllowed())
@@ -421,10 +421,10 @@ void TreasurePlacer::addPandoraBoxesWithSpells()
 	//Pandora with 15 spells of certain school
 	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 * 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;
 			for(auto spellID : LIBRARY->spellh->getDefaultAllowed())
@@ -453,10 +453,10 @@ void TreasurePlacer::addPandoraBoxesWithSpells()
 	
 	// 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 * 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;
 		for(auto spellID : LIBRARY->spellh->getDefaultAllowed())
@@ -518,11 +518,11 @@ void TreasurePlacer::addSeerHuts()
 			obj->quest->mission.artifacts.push_back(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
-			ArtifactID artid = seer->getQuest()->mission.artifacts.front();
+			ArtifactID artid = seer.getQuest()->mission.artifacts.front();
 			qap->addRandomArtifact(artid);
 			qap->removeQuestArtifact(artid);
 		};
@@ -538,17 +538,16 @@ void TreasurePlacer::addSeerHuts()
 			int randomAppearance = chooseRandomAppearance(zone.getRand(), Obj::SEER_HUT, zone.getTerrainType());
 			
 			// 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 * obj = dynamic_cast<CGSeerHut *>(factory->create(cb, nullptr));
+				auto obj = std::dynamic_pointer_cast<CGSeerHut>(factory->create(cb, nullptr));
 				
 				Rewardable::VisitInfo reward;
 				reward.reward.creatures.emplace_back(creature->getId(), creaturesAmount);
 				reward.visitType = Rewardable::EEventType::EVENT_FIRST_VISIT;
 				obj->configuration.info.push_back(reward);
-								
-				setRandomArtifact(obj);
+				setRandomArtifact(obj.get());
 				
 				return obj;
 			};
@@ -583,17 +582,16 @@ void TreasurePlacer::addSeerHuts()
 			oi.probability = 10;
 			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 * 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;
 				reward.reward.heroExperience = generator.getConfig().questRewardValues[i];
 				reward.visitType = Rewardable::EEventType::EVENT_FIRST_VISIT;
 				obj->configuration.info.push_back(reward);
-
-				setRandomArtifact(obj);
+				setRandomArtifact(obj.get());
 
 				return obj;
 			};
@@ -602,17 +600,17 @@ void TreasurePlacer::addSeerHuts()
 			if(!oi.templates.empty())
 				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 * 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;
 				reward.reward.resources[EGameResID::GOLD] = generator.getConfig().questRewardValues[i];
 				reward.visitType = Rewardable::EEventType::EVENT_FIRST_VISIT;
 				obj->configuration.info.push_back(reward);
 				
-				setRandomArtifact(obj);
+				setRandomArtifact(obj.get());
 				
 				return obj;
 			};
@@ -748,15 +746,14 @@ rmg::Object TreasurePlacer::constructTreasurePile(const std::vector<ObjectInfo*>
 			accessibleArea.add(int3());
 		}
 		
-		CGObjectInstance * object = nullptr;
+		std::shared_ptr<CGObjectInstance> object = nullptr;
 		if (oi->generateObject)
 		{
 			object = oi->generateObject();
 			if(oi->templates.empty())
 			{
 				logGlobal->warn("Deleting randomized object with no templates: %s", object->getObjectName());
-				oi->destroyObject(object);
-				delete object;
+				oi->destroyObject(*object);
 				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);
 		instance.onCleared = oi->destroyObject;
 

+ 6 - 6
lib/rmg/modificators/WaterProxy.cpp

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