浏览代码

Fixed missing names for dwellings and creature banks

Ivan Savenko 11 年之前
父节点
当前提交
a1fff864e6

+ 4 - 6
lib/mapObjects/CBank.cpp

@@ -45,10 +45,8 @@ void CBank::initObj()
 
 std::string CBank::getHoverText(PlayerColor player) const
 {
-	// TODO: USE BANK_SPECIFIC NAMES
 	// TODO: record visited players
-	bool visited = (bc == nullptr);
-	return visitedTxt(visited);
+	return getObjectName() + " " + visitedTxt(bc == nullptr);
 }
 
 void CBank::setConfig(const BankConfig & config)
@@ -128,8 +126,8 @@ void CBank::onHeroVisit (const CGHeroInstance * h) const
 		bd.player = h->getOwner();
 		bd.soundID = soundID;
 		bd.text.addTxt(MetaString::ADVOB_TXT, banktext);
-		//if (ID == Obj::CREATURE_BANK)
-		//	bd.text.addReplacement(VLC->objh->creBanksNames[index]); // FIXME: USE BANK SPECIFIC NAMES
+		if (ID == Obj::CREATURE_BANK)
+			bd.text.addReplacement(getObjectName());
 		cb->showBlockingDialog (&bd);
 	}
 	else
@@ -149,7 +147,7 @@ void CBank::onHeroVisit (const CGHeroInstance * h) const
 		else
 		{
 			iw.text << VLC->generaltexth->advobtxt[33];// This was X, now is completely empty
-			//iw.text.addReplacement(VLC->objh->creBanksNames[index]); // FIXME: USE BANK SPECIFIC NAMES
+			iw.text.addReplacement(getObjectName());
 		}
 		cb->showInfoDialog(&iw);
 	}

+ 43 - 4
lib/mapObjects/CObjectClassesHandler.cpp

@@ -117,6 +117,17 @@ std::vector<JsonNode> CObjectClassesHandler::loadLegacyData(size_t dataSize)
 		ret[i]["name"].String() = namesParser.readString();
 		namesParser.endLine();
 	}
+
+	CLegacyConfigParser cregen1Parser("data/crgen1");
+	do
+		customNames[Obj::CREATURE_GENERATOR1].push_back(cregen1Parser.readString());
+	while(cregen1Parser.endLine());
+
+	CLegacyConfigParser cregen4Parser("data/crgen4");
+	do
+		customNames[Obj::CREATURE_GENERATOR4].push_back(cregen4Parser.readString());
+	while(cregen4Parser.endLine());
+
 	return ret;
 }
 
@@ -142,12 +153,16 @@ void CObjectClassesHandler::loadObjectEntry(const JsonNode & entry, ObjectContai
 		logGlobal->errorStream() << "Handler with name " << obj->handlerName << " was not found!";
 		return;
 	}
-	auto handler = handlerConstructors.at(obj->handlerName)();
-	handler->init(entry);
-
 	si32 id = selectNextID(entry["index"], obj->objects, 1000);
+
+	auto handler = handlerConstructors.at(obj->handlerName)();
 	handler->setType(obj->id, id);
 
+	if (customNames.count(obj->id) && customNames.at(obj->id).size() > id)
+		handler->init(entry, customNames.at(obj->id).at(id));
+	else
+		handler->init(entry);
+
 	if (handler->getTemplates().empty())
 	{
 		auto range = legacyTemplates.equal_range(std::make_pair(obj->id, id));
@@ -208,6 +223,7 @@ void CObjectClassesHandler::loadSubObject(std::string name, JsonNode config, si3
 	std::string oldMeta = config.meta; // FIXME: move into inheritNode?
 	JsonUtils::inherit(config, objects.at(ID)->base);
 	config.setMeta(oldMeta);
+
 	loadObjectEntry(config, objects[ID]);
 }
 
@@ -290,6 +306,17 @@ std::string CObjectClassesHandler::getObjectName(si32 type) const
 	return "";
 }
 
+std::string CObjectClassesHandler::getObjectName(si32 type, si32 subtype) const
+{
+	if (knownSubObjects(type).count(subtype))
+	{
+		auto name = getHandlerFor(type, subtype)->getCustomName();
+		if (name)
+			return name.get();
+	}
+	return getObjectName(type);
+}
+
 void AObjectTypeHandler::setType(si32 type, si32 subtype)
 {
 	this->type = type;
@@ -304,7 +331,7 @@ static ui32 loadJsonOrMax(const JsonNode & input)
 		return input.Float();
 }
 
-void AObjectTypeHandler::init(const JsonNode & input)
+void AObjectTypeHandler::init(const JsonNode & input, boost::optional<std::string> name)
 {
 	base = input["base"];
 
@@ -328,6 +355,12 @@ void AObjectTypeHandler::init(const JsonNode & input)
 		tmpl.readJson(entry.second);
 		templates.push_back(tmpl);
 	}
+
+	if (input["name"].isNull())
+		objectName = name;
+	else
+		objectName.reset(input["name"].String());
+
 	initTypeData(input);
 }
 
@@ -338,6 +371,12 @@ bool AObjectTypeHandler::objectFilter(const CGObjectInstance *, const ObjectTemp
 
 void AObjectTypeHandler::initTypeData(const JsonNode & input)
 {
+	// empty implementation for overrides
+}
+
+boost::optional<std::string> AObjectTypeHandler::getCustomName() const
+{
+	return objectName;
 }
 
 void AObjectTypeHandler::addTemplate(ObjectTemplate templ)

+ 14 - 4
lib/mapObjects/CObjectClassesHandler.h

@@ -98,6 +98,9 @@ class DLL_LINKAGE AObjectTypeHandler : public boost::noncopyable
 {
 	RandomMapInfo rmgInfo;
 
+	/// Human-readable name of this object, used for objects like banks and dwellings, if set
+	boost::optional<std::string> objectName;
+
 	si32 type;
 	si32 subtype;
 
@@ -116,7 +119,10 @@ public:
 	void setType(si32 type, si32 subtype);
 
 	/// loads generic data from Json structure and passes it towards type-specific constructors
-	void init(const JsonNode & input);
+	void init(const JsonNode & input, boost::optional<std::string> name = boost::optional<std::string>());
+
+	/// Returns object-specific name, if set
+	boost::optional<std::string> getCustomName() const;
 
 	void addTemplate(ObjectTemplate templ);
 	void addTemplate(JsonNode config);
@@ -148,7 +154,7 @@ public:
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
-		h & type & subtype & templates & rmgInfo;
+		h & type & subtype & templates & rmgInfo & objectName;
 	}
 };
 
@@ -174,8 +180,6 @@ class DLL_LINKAGE CObjectClassesHandler : public IHandlerBase
 		}
 	};
 
-	typedef std::multimap<std::pair<si32, si32>, ObjectTemplate> TTemplatesContainer;
-
 	/// list of object handlers, each of them handles only one type
 	std::map<si32, ObjectContainter * > objects;
 
@@ -183,8 +187,13 @@ class DLL_LINKAGE CObjectClassesHandler : public IHandlerBase
 	std::map<std::string, std::function<TObjectTypeHandler()> > handlerConstructors;
 
 	/// container with H3 templates, used only during loading, no need to serialize it
+	typedef std::multimap<std::pair<si32, si32>, ObjectTemplate> TTemplatesContainer;
 	TTemplatesContainer legacyTemplates;
 
+	/// contains list of custom names for H3 objects (e.g. Dwellings), used to load H3 data
+	/// format: customNames[primaryID][secondaryID] -> name
+	std::map<si32, std::vector<std::string>> customNames;
+
 	void loadObjectEntry(const JsonNode & entry, ObjectContainter * obj);
 	ObjectContainter * loadFromJson(const JsonNode & json);
 public:
@@ -211,6 +220,7 @@ public:
 	TObjectTypeHandler getHandlerFor(si32 type, si32 subtype) const;
 
 	std::string getObjectName(si32 type) const;
+	std::string getObjectName(si32 type, si32 subtype) const;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{

+ 1 - 1
lib/mapObjects/CObjectHandler.cpp

@@ -272,7 +272,7 @@ void CGObjectInstance::giveDummyBonus(ObjectInstanceID heroID, ui8 duration) con
 
 std::string CGObjectInstance::getObjectName() const
 {
-	return VLC->objtypeh->getObjectName(ID);
+	return VLC->objtypeh->getObjectName(ID, subID);
 }
 
 std::string CGObjectInstance::getHoverText(PlayerColor player) const

+ 1 - 2
lib/mapObjects/CRewardableObject.cpp

@@ -184,7 +184,6 @@ void CRewardableObject::blockingDialogAnswered(const CGHeroInstance *hero, ui32
 
 	if (answer > 0 && answer-1 < info.size())
 	{
-		//NOTE: this relies on assumption that there won't be any changes in player/hero during blocking dialog
 		auto list = getAvailableRewards(hero);
 		grantReward(list[answer - 1], hero);
 	}
@@ -470,7 +469,7 @@ void CGPickable::initObj()
 	blockVisit = true;
 	switch(ID)
 	{
-	case Obj::CAMPFIRE: //FIXME: campfire is not functioning correctly in game (no visible message)
+	case Obj::CAMPFIRE:
 		{
 			soundID = soundBase::experience;
 			int givenRes = cb->gameState()->getRandomGenerator().nextInt(5);

+ 5 - 2
lib/mapObjects/CommonConstructors.cpp

@@ -195,8 +195,11 @@ void CDwellingInstanceConstructor::configureObject(CGObjectInstance * object, CR
 
 	if (guards.getType() == JsonNode::DATA_BOOL)
 	{
-		const CCreature * crea = availableCreatures.at(0).at(0);
-		dwelling->putStack(SlotID(0), new CStackInstance(crea->idNumber, crea->growth * 3 ));
+		if (guards.Bool())
+		{
+			const CCreature * crea = availableCreatures.at(0).at(0);
+			dwelling->putStack(SlotID(0), new CStackInstance(crea->idNumber, crea->growth * 3 ));
+		}
 	}
 	else for (auto & stack : JsonRandom::loadCreatures(guards, rng))
 	{