浏览代码

Tweaked CBonusTypeHandler

AlexVinS 8 年之前
父节点
当前提交
18b8e1c7ad
共有 2 个文件被更改,包括 187 次插入172 次删除
  1. 167 154
      lib/CBonusTypeHandler.cpp
  2. 20 18
      lib/CBonusTypeHandler.h

+ 167 - 154
lib/CBonusTypeHandler.cpp

@@ -8,6 +8,9 @@
  *
  */
 #include "StdInc.h"
+
+#define INSTANTIATE_CBonusTypeHandler_HERE
+
 #include "CBonusTypeHandler.h"
 
 #include "JsonNode.h"
@@ -17,31 +20,32 @@
 #include "CCreatureHandler.h"
 #include "spells/CSpellHandler.h"
 
+template class std::vector<CBonusType>;
+
 ///MacroString
 
-MacroString::MacroString(const std::string &format)
+MacroString::MacroString(const std::string & format)
 {
 	static const std::string MACRO_START = "${";
 	static const std::string MACRO_END = "}";
 	static const size_t MACRO_START_L = 2;
 	static const size_t MACRO_END_L = 1;
-	
-	size_t end_pos = 0;	
+
+	size_t end_pos = 0;
 	size_t start_pos = std::string::npos;
-	
 	do
 	{
 		start_pos = format.find(MACRO_START, end_pos);
-		
-		if (!(start_pos == std::string::npos))
+
+		if(!(start_pos == std::string::npos))
 		{
 			//chunk before macro
-			items.push_back(Item(Item::STRING,format.substr(end_pos, start_pos-end_pos)));
-			
+			items.push_back(Item(Item::STRING, format.substr(end_pos, start_pos - end_pos)));
+
 			start_pos += MACRO_START_L;
 			end_pos = format.find(MACRO_END, start_pos);
-			
-			if (end_pos == std::string::npos)
+
+			if(end_pos == std::string::npos)
 			{
 				logBonus->warnStream() << "Format error in: " << format;
 				end_pos = start_pos;
@@ -49,36 +53,36 @@ MacroString::MacroString(const std::string &format)
 			}
 			else
 			{
-				items.push_back(Item(Item::MACRO,format.substr(start_pos,end_pos-start_pos)));
+				items.push_back(Item(Item::MACRO, format.substr(start_pos, end_pos - start_pos)));
 				end_pos += MACRO_END_L;
 			}
-		}		
+		}
 	}
-	while (start_pos != std::string::npos);
-	
+	while(start_pos != std::string::npos);
+
 	//no more macros
-	items.push_back(Item(Item::STRING,format.substr(end_pos)));
+	items.push_back(Item(Item::STRING, format.substr(end_pos)));
 }
 
-std::string MacroString::build(const GetValue& getValue) const
+std::string MacroString::build(const GetValue & getValue) const
 {
 	std::string result;
-	
-	for(const Item &i : items)
+
+	for(const Item & i : items)
 	{
-		switch (i.type)
+		switch(i.type)
 		{
-			case Item::MACRO:
-			{
-				result += getValue(i.value);
-				break;
-			}			
-			case Item::STRING:
-			{
-				result += i.value;
-				break;
-			}			
-		}		
+		case Item::MACRO:
+		{
+			result += getValue(i.value);
+			break;
+		}
+		case Item::STRING:
+		{
+			result += i.value;
+			break;
+		}
+		}
 	}
 	return result;
 }
@@ -88,12 +92,12 @@ std::string MacroString::build(const GetValue& getValue) const
 CBonusType::CBonusType()
 {
 	hidden = true;
-	icon = nameTemplate = descriptionTemplate = ""; 
+	icon = nameTemplate = descriptionTemplate = "";
 }
 
 CBonusType::~CBonusType()
 {
-	
+
 }
 
 void CBonusType::buildMacros()
@@ -110,11 +114,11 @@ CBonusTypeHandler::CBonusTypeHandler()
 	//register predefined bonus types
 
 	#define BONUS_NAME(x) \
-		do{\
-			bonusTypes.push_back(CBonusType());\
-		}while (0);
-		
-	
+	do { \
+		bonusTypes.push_back(CBonusType()); \
+	} while(0);
+
+
 	BONUS_LIST;
 	#undef BONUS_NAME
 
@@ -126,190 +130,199 @@ CBonusTypeHandler::~CBonusTypeHandler()
 	//dtor
 }
 
-std::string CBonusTypeHandler::bonusToString(const std::shared_ptr<Bonus>& bonus, const IBonusBearer *bearer, bool description) const
-{	
-	auto getValue = [=](const std::string &name) -> std::string
+std::string CBonusTypeHandler::bonusToString(const std::shared_ptr<Bonus> & bonus, const IBonusBearer * bearer, bool description) const
+{
+	auto getValue = [=](const std::string & name) -> std::string
 	{
-		if (name == "val")
+		if(name == "val")
 		{
-			return boost::lexical_cast<std::string>(bearer->valOfBonuses(Selector::typeSubtype(bonus->type, bonus->subtype)));
+			 return boost::lexical_cast<std::string>(bearer->valOfBonuses(Selector::typeSubtype(bonus->type, bonus->subtype)));
 		}
-		else if (name == "subtype.creature")
+		else if(name == "subtype.creature")
 		{
-			const CreatureID cre(bonus->subtype);
-			return cre.toCreature()->namePl;
+			 const CreatureID cre(bonus->subtype);
+			 return cre.toCreature()->namePl;
 		}
-		else if (name == "subtype.spell")
+		else if(name == "subtype.spell")
 		{
-			const SpellID sp(bonus->subtype);
-			return sp.toSpell()->name;
-		}		
-		else if (name == "MR")
+			 const SpellID sp(bonus->subtype);
+			 return sp.toSpell()->name;
+		}
+		else if(name == "MR")
 		{
 			 return boost::lexical_cast<std::string>(bearer->magicResistance());
-		}			
+		}
 		else
 		{
-			logBonus->warnStream() << "Unknown macro in bonus config: " << name;
-			return "[error]";
+			 logBonus->warnStream() << "Unknown macro in bonus config: " << name;
+			 return "[error]";
 		}
 	};
-	
-	const CBonusType& bt = bonusTypes[bonus->type];	
+
+	const CBonusType & bt = bonusTypes[bonus->type];
 	if(bt.hidden)
 		return "";
-	const MacroString& macro = description ? bt.description : bt.name;
-	
-	return macro.build(getValue);	
+	const MacroString & macro = description ? bt.description : bt.name;
+
+	return macro.build(getValue);
 }
 
-std::string CBonusTypeHandler::bonusToGraphics(const std::shared_ptr<Bonus>& bonus) const
+std::string CBonusTypeHandler::bonusToGraphics(const std::shared_ptr<Bonus> & bonus) const
 {
 	std::string fileName;
 	bool fullPath = false;
 
-	switch (bonus->type)
+	switch(bonus->type)
 	{
-		case Bonus::SECONDARY_SKILL_PREMY:
-			if (bonus->subtype == SecondarySkill::RESISTANCE)
-			{
-				fileName = "E_DWARF.bmp";
-			}
-			break;
-		case Bonus::SPELL_IMMUNITY:
+	case Bonus::SECONDARY_SKILL_PREMY:
+		if(bonus->subtype == SecondarySkill::RESISTANCE)
 		{
-			fullPath = true;
-			const CSpell * sp = SpellID(bonus->subtype).toSpell();
-			fileName = sp->getIconImmune();
-			break;
+			fileName = "E_DWARF.bmp";
 		}
-		case Bonus::FIRE_IMMUNITY:
-			switch (bonus->subtype)
-			{
-				case 0:
-					fileName =  "E_SPFIRE.bmp"; break; //all
-				case 1:
-					fileName =  "E_SPFIRE1.bmp"; break; //not positive
-				case 2:
-					fileName =  "E_FIRE.bmp"; break; //direct damage
-			}
-			break;
-		case Bonus::WATER_IMMUNITY:
-			switch (bonus->subtype)
-			{
-				case 0:
-					fileName =  "E_SPWATER.bmp"; break; //all
-				case 1:
-					fileName =  "E_SPWATER1.bmp"; break; //not positive
-				case 2:
-					fileName =  "E_SPCOLD.bmp"; break; //direct damage
-			}
-			break;
-		case Bonus::AIR_IMMUNITY:
-			switch (bonus->subtype)
-			{
-				case 0:
-					fileName =  "E_SPAIR.bmp"; break; //all
-				case 1:
-					fileName =  "E_SPAIR1.bmp"; break; //not positive
-				case 2:
-					fileName = "E_LIGHT.bmp"; break;//direct damage
-			}
-			break;
-		case Bonus::EARTH_IMMUNITY:
-			switch (bonus->subtype)
-			{
-				case 0:
-					fileName =  "E_SPEATH.bmp"; break; //all
-				case 1:
-				case 2: //no specific icon for direct damage immunity
-					fileName =  "E_SPEATH1.bmp"; break; //not positive
-			}
-			break;
-		case Bonus::LEVEL_SPELL_IMMUNITY:
+		break;
+	case Bonus::SPELL_IMMUNITY:
+	{
+		fullPath = true;
+		const CSpell * sp = SpellID(bonus->subtype).toSpell();
+		fileName = sp->getIconImmune();
+		break;
+	}
+	case Bonus::FIRE_IMMUNITY:
+		switch(bonus->subtype)
 		{
-			if (vstd::iswithin(bonus->val, 1 , 5))
-			{
-				fileName = "E_SPLVL" + boost::lexical_cast<std::string>(bonus->val) + ".bmp";
-			}
-			break;
+		case 0:
+			fileName = "E_SPFIRE.bmp";
+			break;//all
+		case 1:
+			fileName = "E_SPFIRE1.bmp";
+			break;//not positive
+		case 2:
+			fileName = "E_FIRE.bmp";
+			break;//direct damage
 		}
-		case Bonus::GENERAL_DAMAGE_REDUCTION:
+		break;
+	case Bonus::WATER_IMMUNITY:
+		switch(bonus->subtype)
 		{
-			switch (bonus->subtype)
-			{
-				case 0:
-					fileName = "DamageReductionMelee.bmp"; break;
-				case 1:
-					fileName = "DamageReductionRanged.bmp"; break;
-			}
-			break;
+		case 0:
+			fileName = "E_SPWATER.bmp";
+			break;//all
+		case 1:
+			fileName = "E_SPWATER1.bmp";
+			break;//not positive
+		case 2:
+			fileName = "E_SPCOLD.bmp";
+			break;//direct damage
+		}
+		break;
+	case Bonus::AIR_IMMUNITY:
+		switch(bonus->subtype)
+		{
+		case 0:
+			fileName = "E_SPAIR.bmp";
+			break;//all
+		case 1:
+			fileName = "E_SPAIR1.bmp";
+			break;//not positive
+		case 2:
+			fileName = "E_LIGHT.bmp";
+			break;//direct damage
+		}
+		break;
+	case Bonus::EARTH_IMMUNITY:
+		switch(bonus->subtype)
+		{
+		case 0:
+			fileName = "E_SPEATH.bmp";
+			break;//all
+		case 1:
+		case 2://no specific icon for direct damage immunity
+			fileName = "E_SPEATH1.bmp";
+			break;//not positive
+		}
+		break;
+	case Bonus::LEVEL_SPELL_IMMUNITY:
+	{
+		if(vstd::iswithin(bonus->val, 1, 5))
+		{
+			fileName = "E_SPLVL" + boost::lexical_cast<std::string>(bonus->val) + ".bmp";
 		}
-		
-		default: 
+		break;
+	}
+	case Bonus::GENERAL_DAMAGE_REDUCTION:
+	{
+		switch(bonus->subtype)
 		{
+		case 0:
+			fileName = "DamageReductionMelee.bmp";
+			break;
+		case 1:
+			fileName = "DamageReductionRanged.bmp";
+			break;
+		}
+		break;
+	}
 
-			const CBonusType& bt = bonusTypes[bonus->type];
-			
+	default:
+		{
+			const CBonusType & bt = bonusTypes[bonus->type];
 			fileName = bt.icon;
 			fullPath = true;
-			break;
-		}		
+		}
+		break;
 	}
-	
+
 	if(!fileName.empty() && !fullPath)
 		fileName = "zvs/Lib1.res/" + fileName;
-	return fileName;	
+	return fileName;
 }
 
-
 void CBonusTypeHandler::load()
 {
 	const JsonNode gameConf(ResourceID("config/gameConfig.json"));
-	const JsonNode config(JsonUtils::assembleFromFiles(gameConf["bonuses"].convertTo<std::vector<std::string> >()));
+	const JsonNode config(JsonUtils::assembleFromFiles(gameConf["bonuses"].convertTo<std::vector<std::string>>()));
 	load(config);
 }
 
-void CBonusTypeHandler::load(const JsonNode& config)
+void CBonusTypeHandler::load(const JsonNode & config)
 {
 	for(auto & node : config.Struct())
 	{
 		auto it = bonusNameMap.find(node.first);
-		
+
 		if(it == bonusNameMap.end())
 		{
 			//TODO: new bonus
 //			CBonusType bt;
 //			loadItem(node.second, bt);
-//			
+//
 //			auto new_id = bonusTypes.size();
-//			
+//
 //			bonusTypes.push_back(bt);
-			
+
 			logBonus->warnStream() << "Adding new bonuses not implemented (" << node.first << ")";
 		}
 		else
 		{
-			CBonusType& bt = bonusTypes[it->second];
-			
+			CBonusType & bt = bonusTypes[it->second];
+
 			loadItem(node.second, bt);
 			logBonus->traceStream() << "Loaded bonus type " << node.first;
-		}	
-	}		
+		}
+	}
 }
 
-void CBonusTypeHandler::loadItem(const JsonNode& source, CBonusType& dest)
+void CBonusTypeHandler::loadItem(const JsonNode & source, CBonusType & dest)
 {
 	dest.nameTemplate = source["name"].String();
 	dest.descriptionTemplate = source["description"].String();
 	dest.hidden = source["hidden"].Bool(); //Null -> false
-	
-	const JsonNode& graphics = source["graphics"];
-	
+
+	const JsonNode & graphics = source["graphics"];
+
 	if(!graphics.isNull())
 	{
 		dest.icon = graphics["icon"].String();
-	}	
+	}
 	dest.buildMacros();
 }
-

+ 20 - 18
lib/CBonusTypeHandler.h

@@ -33,12 +33,13 @@ class MacroString
 	};
 	std::vector<Item> items;
 public:
-	typedef std::function <std::string(const std::string&)> GetValue;
+	typedef std::function<std::string(const std::string &)> GetValue;
 
-	MacroString(){};
-	MacroString(const std::string &format);
+	MacroString() = default;
+	~MacroString() = default;
+	explicit MacroString(const std::string & format);
 
-	std::string build(const GetValue& getValue) const;
+	std::string build(const GetValue & getValue) const;
 };
 
 class DLL_LINKAGE CBonusType
@@ -47,8 +48,7 @@ public:
 	CBonusType();
 	~CBonusType();
 
-
-	template <typename Handler> void serialize(Handler &h, const int version)
+	template <typename Handler> void serialize(Handler & h, const int version)
 	{
 		h & icon;
 		h & nameTemplate;
@@ -58,7 +58,6 @@ public:
 		if (!h.saving)
 			buildMacros();
 	}
-protected:
 
 private:
 	void buildMacros();
@@ -71,27 +70,30 @@ private:
 	bool hidden;
 };
 
-
 class DLL_LINKAGE CBonusTypeHandler : public IBonusTypeHandler
 {
 public:
 	CBonusTypeHandler();
 	virtual ~CBonusTypeHandler();
 
-	std::string bonusToString(const std::shared_ptr<Bonus>& bonus, const IBonusBearer *bearer, bool description) const override;
-	std::string bonusToGraphics(const std::shared_ptr<Bonus>& bonus) const override;
-
-	void load();
-	void load(const JsonNode& config);
+	std::string bonusToString(const std::shared_ptr<Bonus> & bonus, const IBonusBearer * bearer, bool description) const override;
+	std::string bonusToGraphics(const std::shared_ptr<Bonus> & bonus) const override;
 
-	template <typename Handler> void serialize(Handler &h, const int version)
+	template <typename Handler> void serialize(Handler & h, const int version)
 	{
-		h & bonusTypes;
+		//for now always use up to date configuration
+		//once modded bonus type will be implemented, serialize only them
+		std::vector<CBonusType> ignore;
+		h & ignore;
 	}
 private:
-
-	void loadItem(const JsonNode &source, CBonusType &dest);
+	void load();
+	void load(const JsonNode & config);
+	void loadItem(const JsonNode & source, CBonusType & dest);
 
 	std::vector<CBonusType> bonusTypes; //index = BonusTypeID
-
 };
+
+#ifndef INSTANTIATE_CBonusTypeHandler_HERE
+extern template class std::vector<CBonusType>;
+#endif