浏览代码

Fix incorrect templates for mines in HoTA

Tomasz Zieliński 3 年之前
父节点
当前提交
8c481dff46

+ 7 - 9
lib/mapObjects/CObjectClassesHandler.cpp

@@ -116,13 +116,15 @@ std::vector<JsonNode> CObjectClassesHandler::loadLegacyData(size_t dataSize)
 	size_t totalNumber = static_cast<size_t>(parser.readNumber()); // first line contains number of objects to read and nothing else
 	parser.endLine();
 
-	for (size_t i=0; i<totalNumber; i++)
+	for (size_t i = 0; i < totalNumber; i++)
 	{
-		auto templ = new ObjectTemplate;
-		templ->readTxt(parser);
+		auto tmpl = new ObjectTemplate;
+
+		tmpl->readTxt(parser);
 		parser.endLine();
-		std::pair<si32, si32> key(templ->id.num, templ->subid);
-		legacyTemplates.insert(std::make_pair(key, std::shared_ptr<const ObjectTemplate>(templ)));
+
+		std::pair<si32, si32> key(tmpl->id.num, tmpl->subid);
+		legacyTemplates.insert(std::make_pair(key, std::shared_ptr<const ObjectTemplate>(tmpl)));
 	}
 
 	std::vector<JsonNode> ret(dataSize);// create storage for 256 objects
@@ -560,10 +562,6 @@ SObjectSounds AObjectTypeHandler::getSounds() const
 
 void AObjectTypeHandler::addTemplate(std::shared_ptr<const ObjectTemplate> templ)
 {
-	//Otherwise the template remains constant
-	auto ptr = const_cast<ObjectTemplate*>(templ.get());
-	ptr->id = Obj(type);
-	ptr->subid = subtype;
 	templates.push_back(templ);
 }
 

+ 1 - 9
lib/mapObjects/CommonConstructors.h

@@ -33,19 +33,11 @@ protected:
 		auto obj = new ObjectType();
 		preInitObject(obj);
 
+		//Set custom template or leave null
 		if (tmpl)
 		{
 			obj->appearance = tmpl;
 		}
-		else
-		{
-			auto templates = getTemplates();
-			if (templates.empty())
-			{
-				throw std::runtime_error("No handler for created object");
-			}
-			obj->appearance = templates.front(); //just any template for now, will be initialized later
-		}
 
 		return obj;
 	}

+ 1 - 0
lib/rmg/ObjectManager.cpp

@@ -490,6 +490,7 @@ bool ObjectManager::addGuard(rmg::Object & object, si32 strength, bool zoneGuard
 	
 	auto & instance = object.addInstance(*guard);
 	instance.setPosition(guardPos - object.getPosition());
+	instance.setAnyTemplate(); //terrain is irrelevant for monsters, but monsters need some template now
 		
 	return true;
 }

+ 31 - 21
lib/rmg/RmgObject.cpp

@@ -105,20 +105,26 @@ void Object::Instance::setPositionRaw(const int3 & position)
 	dObject.pos = dPosition + dParent.getPosition();
 }
 
-void Object::Instance::setTemplate(const TerrainId & terrain)
+void Object::Instance::setAnyTemplate()
 {
-	if(dObject.appearance->id == Obj::NO_OBJ)
+	auto templates = VLC->objtypeh->getHandlerFor(dObject.ID, dObject.subID)->getTemplates();
+	if(templates.empty())
+		throw rmgException(boost::to_string(boost::format("Did not find any graphics for object (%d,%d)") % dObject.ID % dObject.subID));
+
+	dObject.appearance = templates.front();
+	dAccessibleAreaCache.clear();
+	setPosition(getPosition(false));
+}
+
+void Object::Instance::setTemplate(TerrainId terrain)
+{
+	auto templates = VLC->objtypeh->getHandlerFor(dObject.ID, dObject.subID)->getTemplates(terrain);
+	if (templates.empty())
 	{
-		auto templates = VLC->objtypeh->getHandlerFor(dObject.ID, dObject.subID)->getTemplates(terrain);
 		auto terrainName = VLC->terrainTypeHandler->terrains()[terrain].name;
-		if (templates.empty())
-		{
-			throw rmgException(boost::to_string(boost::format("Did not find graphics for object (%d,%d) at %s") %
-				dObject.ID % dObject.subID % terrainName));
-		}
-		
-		dObject.appearance = templates.front();
+		throw rmgException(boost::to_string(boost::format("Did not find graphics for object (%d,%d) at %s") % dObject.ID % dObject.subID % terrainName));
 	}
+	dObject.appearance = templates.front();
 	dAccessibleAreaCache.clear();
 	setPosition(getPosition(false));
 }
@@ -283,6 +289,21 @@ void Object::Instance::finalize(RmgMap & map)
 	if(!map.isOnMap(getPosition(true)))
 		throw rmgException(boost::to_string(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)
+	{
+		auto terrainType = map.map().getTile(getPosition(true)).terType;
+		auto templates = VLC->objtypeh->getHandlerFor(dObject.ID, dObject.subID)->getTemplates(terrainType->id);
+		if (templates.empty())
+		{
+			throw rmgException(boost::to_string(boost::format("Did not find graphics for object (%d,%d) at %s (terrain %d)") % dObject.ID % dObject.subID % getPosition(true).toString() % terrainType));
+		}
+		else
+		{
+			setTemplate(terrainType->id);
+		}
+	}
+
 	if (dObject.isVisitable() && !map.isOnMap(dObject.visitablePos()))
 		throw rmgException(boost::to_string(boost::format("Visitable tile %s of object %d at %s is outside the map") % dObject.visitablePos().toString() % dObject.id % dObject.pos.toString()));
 	
@@ -292,17 +313,6 @@ void Object::Instance::finalize(RmgMap & map)
 			throw rmgException(boost::to_string(boost::format("Tile %s of object %d at %s is outside the map") % tile.toString() % dObject.id % dObject.pos.toString()));
 	}
 	
-	if (dObject.appearance->id == Obj::NO_OBJ)
-	{
-		auto terrainType = map.map().getTile(getPosition(true)).terType;
-		auto templates = VLC->objtypeh->getHandlerFor(dObject.ID, dObject.subID)->getTemplates(terrainType->id);
-		if (templates.empty())
-			throw rmgException(boost::to_string(boost::format("Did not find graphics for object (%d,%d) at %s (terrain %d)") %
-				dObject.ID % dObject.subID % getPosition(true).toString() % terrainType->name));
-		
-		setTemplate(terrainType->id);
-	}
-	
 	for(auto & tile : getBlockedArea().getTilesVector())
 	{
 		map.setOccupied(tile, ETileType::ETileType::USED);

+ 2 - 1
lib/rmg/RmgObject.h

@@ -35,7 +35,8 @@ public:
 		int3 getVisitablePosition() const;
 		bool isVisitableFrom(const int3 & tile) const;
 		const Area & getAccessibleArea() const;
-		void setTemplate(const TerrainId & terrain); //cache invalidation
+		void setTemplate(TerrainId terrain); //cache invalidation
+		void setAnyTemplate(); //cache invalidation
 		
 		int3 getPosition(bool isAbsolute = false) const;
 		void setPosition(const int3 & position); //cache invalidation

+ 6 - 45
lib/serializer/BinaryDeserializer.h

@@ -391,56 +391,17 @@ public:
 		else
 			data.reset();
 	}
+
 	template <typename T>
-	void load(std::shared_ptr<const T> &data) //version of the above for const ptr
+	void load(std::shared_ptr<const T> & data)
 	{
-		typedef typename std::remove_const<T>::type NonConstT;
-		NonConstT *internalPtr;
-		load(internalPtr);
+		std::shared_ptr<T> nonConstData;
 
-		void *internalPtrDerived = typeList.castToMostDerived(internalPtr);
+		load(nonConstData);
 
-		if(internalPtr)
-		{
-			auto itr = loadedSharedPointers.find(internalPtrDerived);
-			if(itr != loadedSharedPointers.end())
-			{
-				// This pointer is already loaded. The "data" needs to be pointed to it,
-				// so their shared state is actually shared.
-				try
-				{
-					auto actualType = typeList.getTypeInfo(internalPtr);
-					auto typeWeNeedToReturn = typeList.getTypeInfo<T>();
-					if(*actualType == *typeWeNeedToReturn)
-					{
-						// No casting needed, just unpack already stored shared_ptr and return it
-						data = boost::any_cast<std::shared_ptr<const T>>(itr->second);
-					}
-					else
-					{
-						// We need to perform series of casts
-						auto ret = typeList.castShared(itr->second, actualType, typeWeNeedToReturn);
-						data = boost::any_cast<std::shared_ptr<const T>>(ret);
-					}
-				}
-				catch(std::exception &e)
-				{
-					logGlobal->error(e.what());
-					logGlobal->error("Failed to cast stored shared ptr. Real type: %s. Needed type %s. FIXME FIXME FIXME", itr->second.type().name(), typeid(std::shared_ptr<T>).name());
-					//TODO scenario with inheritance -> we can have stored ptr to base and load ptr to derived (or vice versa)
-					throw;
-				}
-			}
-			else
-			{
-				auto hlp = std::shared_ptr<const T>(internalPtr);
-				data = hlp; //possibly adds const
-				loadedSharedPointers[internalPtrDerived] = typeList.castSharedToMostDerived(hlp);
-			}
-		}
-		else
-			data.reset();
+		data = nonConstData;
 	}
+
 	template <typename T>
 	void load(std::unique_ptr<T> &data)
 	{