浏览代码

fix mantiss 1967 + some refactoring
* remove TModDescr and realted APIs - they were only used in one place

AlexVinS 10 年之前
父节点
当前提交
8f2da66a18

+ 14 - 19
client/widgets/MiscWidgets.cpp

@@ -361,40 +361,35 @@ void MoraleLuckBox::set(const IBonusBearer *node)
 	const int hoverTextBase[] = {7, 4};
 	const Bonus::BonusType bonusType[] = {Bonus::LUCK, Bonus::MORALE};
 	int (IBonusBearer::*getValue[])() const = {&IBonusBearer::LuckVal, &IBonusBearer::MoraleVal};
-
-	int mrlt = -9;
-	TModDescr mrl;
+	TBonusListPtr modifierList(new BonusList());
 
 	if (node)
 	{
-		node->getModifiersWDescr(mrl, bonusType[morale]);
+		modifierList = node->getBonuses(Selector::type(bonusType[morale]));
 		bonusValue = (node->*getValue[morale])();
 	}
 	else
 		bonusValue = 0;
 
-	mrlt = (bonusValue>0)-(bonusValue<0); //signum: -1 - bad luck / morale, 0 - neutral, 1 - good
+	int mrlt = (bonusValue>0)-(bonusValue<0); //signum: -1 - bad luck / morale, 0 - neutral, 1 - good
 	hoverText = CGI->generaltexth->heroscrn[hoverTextBase[morale] - mrlt];
 	baseType = componentType[morale];
 	text = CGI->generaltexth->arraytxt[textId[morale]];
 	boost::algorithm::replace_first(text,"%s",CGI->generaltexth->arraytxt[neutralDescr[morale]-mrlt]);
-	if (!mrl.size())
-		text += CGI->generaltexth->arraytxt[noneTxtId];
+	
+	if (morale && node && (node->hasBonusOfType(Bonus::UNDEAD) 
+			|| node->hasBonusOfType(Bonus::BLOCK_MORALE) 
+			|| node->hasBonusOfType(Bonus::NON_LIVING)))
+		text += CGI->generaltexth->arraytxt[113]; //unaffected by morale		
+	else if(modifierList->empty())
+		text += CGI->generaltexth->arraytxt[noneTxtId];//no modifiers
 	else
 	{
-		//it's a creature window
-		if ((morale && node && node->hasBonusOfType(Bonus::UNDEAD)) ||
-			node->hasBonusOfType(Bonus::BLOCK_MORALE) || node->hasBonusOfType(Bonus::NON_LIVING))
-		{
-			text += CGI->generaltexth->arraytxt[113]; //unaffected by morale
-		}
-		else
+		for(const Bonus * elem : *modifierList)
 		{
-			for(auto & elem : mrl)
-			{
-				if (elem.first) //no bonuses with value 0
-					text += "\n" + elem.second;
-			}
+			if(elem->val != 0)
+				//no bonuses with value 0
+				text += "\n" + elem->Description();
 		}
 	}
 

+ 27 - 51
lib/HeroBonus.cpp

@@ -211,21 +211,8 @@ Bonus * BonusList::getFirst(const CSelector &select)
 	return nullptr;
 }
 
-void BonusList::getModifiersWDescr(TModDescr &out) const
-{
-	for (auto & elem : bonuses)
-	{
-		Bonus *b = elem;
-		out.push_back(std::make_pair(b->val, b->Description()));
-	}
-}
-
 void BonusList::getBonuses(BonusList & out, const CSelector &selector) const
 {
-// 	for(Bonus *i : *this)
-// 		if(selector(i) && i->effectRange == Bonus::NO_LIMIT)
-// 			out.push_back(i);
-
 	getBonuses(out, selector, nullptr);
 }
 
@@ -359,17 +346,6 @@ bool IBonusBearer::hasBonusOfType(Bonus::BonusType type, int subtype /*= -1*/) c
 	return hasBonus(s, cachingStr.str());
 }
 
-void IBonusBearer::getModifiersWDescr(TModDescr &out, Bonus::BonusType type, int subtype /*= -1 */) const
-{
-	std::stringstream cachingStr;
-	cachingStr << "type_" << type << "s_" << subtype;
-	getModifiersWDescr(out, subtype != -1 ? Selector::typeSubtype(type, subtype) : Selector::type(type), cachingStr.str());
-}
-
-void IBonusBearer::getModifiersWDescr(TModDescr &out, const CSelector &selector, const std::string &cachingStr /* =""*/) const
-{
-	getBonuses(selector, cachingStr)->getModifiersWDescr(out);
-}
 int IBonusBearer::getBonusesCount(Bonus::BonusSource from, int id) const
 {
 	std::stringstream cachingStr;
@@ -1105,12 +1081,6 @@ bool NBonus::hasOfType(const CBonusSystemNode *obj, Bonus::BonusType type, int s
 	return false;
 }
 
-void NBonus::getModifiersWDescr(const CBonusSystemNode *obj, TModDescr &out, Bonus::BonusType type, int subtype /*= -1 */)
-{
-	if(obj)
-		return obj->getModifiersWDescr(out, type, subtype);
-}
-
 int NBonus::getCount(const CBonusSystemNode *obj, Bonus::BonusSource from, int id)
 {
 	if(obj)
@@ -1127,28 +1097,34 @@ const CSpell * Bonus::sourceSpell() const
 
 std::string Bonus::Description() const
 {
-	if(description.size())
-		return description;
-
 	std::ostringstream str;
-	str << std::showpos << val << " ";
-
-	switch(source)
-	{
-	case ARTIFACT:
-		str << VLC->arth->artifacts[sid]->Name();
-		break;;
-	case SPELL_EFFECT:
-		str << SpellID(sid).toSpell()->name;
-		break;
-	case CREATURE_ABILITY:
-		str << VLC->creh->creatures[sid]->namePl;
-		break;
-	case SECONDARY_SKILL:
-		str << VLC->generaltexth->skillName[sid]/* << " secondary skill"*/;
-		break;
-	}
-
+	
+	if(description.empty())
+		switch(source)
+		{
+		case ARTIFACT:
+			str << VLC->arth->artifacts[sid]->Name();
+			break;;
+		case SPELL_EFFECT:
+			str << SpellID(sid).toSpell()->name;
+			break;
+		case CREATURE_ABILITY:
+			str << VLC->creh->creatures[sid]->namePl;
+			break;
+		case SECONDARY_SKILL:
+			str << VLC->generaltexth->skillName[sid]/* << " secondary skill"*/;
+			break;
+		default:
+			//todo: handle all possible sources
+			str << "Unknown"; 
+			break;
+		}
+	else
+		str << description;
+		
+	if(val != 0)
+		str << " " << std::showpos << val;
+	
 	return str.str();
 }
 

+ 0 - 6
lib/HeroBonus.h

@@ -23,7 +23,6 @@ class BonusList;
 typedef shared_ptr<BonusList> TBonusListPtr;
 typedef shared_ptr<ILimiter> TLimiterPtr;
 typedef shared_ptr<IPropagator> TPropagatorPtr;
-typedef std::vector<std::pair<int,std::string> > TModDescr; //modifiers values and their descriptions
 typedef std::set<CBonusSystemNode*> TNodes;
 typedef std::set<const CBonusSystemNode*> TCNodes;
 typedef std::vector<CBonusSystemNode *> TNodesVector;
@@ -448,7 +447,6 @@ public:
 	int totalValue() const; //subtype -> subtype of bonus, if -1 then any
 	void getBonuses(BonusList &out, const CSelector &selector, const CSelector &limit) const;
 	void getAllBonuses(BonusList &out) const;
-	void getModifiersWDescr(TModDescr &out) const;
 
 	void getBonuses(BonusList & out, const CSelector &selector) const;
 
@@ -579,7 +577,6 @@ public:
 	// * root is node on which call was made (nullptr will be replaced with this)
 	//interface
 	virtual const TBonusListPtr getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = nullptr, const std::string &cachingStr = "") const = 0;
-	void getModifiersWDescr(TModDescr &out, const CSelector &selector, const std::string &cachingStr = "") const;  //out: pairs<modifier value, modifier description>
 	int getBonusesCount(const CSelector &selector, const std::string &cachingStr = "") const;
 	int valOfBonuses(const CSelector &selector, const std::string &cachingStr = "") const;
 	bool hasBonus(const CSelector &selector, const std::string &cachingStr = "") const;
@@ -594,7 +591,6 @@ public:
 	int valOfBonuses(Bonus::BonusType type, int subtype = -1) const; //subtype -> subtype of bonus, if -1 then anyt;
 	bool hasBonusOfType(Bonus::BonusType type, int subtype = -1) const;//determines if hero has a bonus of given type (and optionally subtype)
 	bool hasBonusFrom(Bonus::BonusSource source, ui32 sourceID) const;
-	void getModifiersWDescr( TModDescr &out, Bonus::BonusType type, int subtype = -1 ) const;  //out: pairs<modifier value, modifier description>
 	int getBonusesCount(Bonus::BonusSource from, int id) const;
 
 	//various hlp functions for non-trivial values
@@ -722,8 +718,6 @@ namespace NBonus
 	//set of methods that may be safely called with nullptr objs
 	DLL_LINKAGE int valOf(const CBonusSystemNode *obj, Bonus::BonusType type, int subtype = -1); //subtype -> subtype of bonus, if -1 then any
 	DLL_LINKAGE bool hasOfType(const CBonusSystemNode *obj, Bonus::BonusType type, int subtype = -1);//determines if hero has a bonus of given type (and optionally subtype)
-	//DLL_LINKAGE const HeroBonus * get(const CBonusSystemNode *obj, int from, int id );
-	DLL_LINKAGE void getModifiersWDescr(const CBonusSystemNode *obj, TModDescr &out, Bonus::BonusType type, int subtype = -1 );  //out: pairs<modifier value, modifier description>
 	DLL_LINKAGE int getCount(const CBonusSystemNode *obj, Bonus::BonusSource from, int id);
 }
 

+ 7 - 1
lib/mapObjects/CArmedInstance.cpp

@@ -86,11 +86,13 @@ void CArmedInstance::updateMoraleBonusFromArmy()
 	{
 		b->val = +1;
 		b->description = VLC->generaltexth->arraytxt[115]; //All troops of one alignment +1
+		b->description = b->description.substr(0, b->description.size()-3);//trim "+1"
 	}
 	else if (!factions.empty()) // no bonus from empty garrison
 	{
 	 	b->val = 2 - factionsInArmy;
 		b->description = boost::str(boost::format(VLC->generaltexth->arraytxt[114]) % factionsInArmy % b->val); //Troops of %d alignments %d
+		b->description = b->description.substr(0, b->description.size()-2);//trim value
 	}
 	boost::algorithm::trim(b->description);
 
@@ -100,7 +102,11 @@ void CArmedInstance::updateMoraleBonusFromArmy()
  	if(hasUndead)
 	{
 		if(!undeadModifier)
-			addNewBonus(new Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::ARMY, -1, UNDEAD_MODIFIER_ID, VLC->generaltexth->arraytxt[116]));
+		{
+			undeadModifier = new Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::ARMY, -1, UNDEAD_MODIFIER_ID, VLC->generaltexth->arraytxt[116]);
+			undeadModifier->description = undeadModifier->description.substr(0, undeadModifier->description.size()-2);//trim value
+			addNewBonus(undeadModifier);
+		}			
 	}
 	else if(undeadModifier)
 		removeBonus(undeadModifier);

+ 8 - 2
lib/mapObjects/CGTownInstance.cpp

@@ -436,12 +436,12 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const
 	//other *-of-legion-like bonuses (%d to growth cumulative with grail)
 	TBonusListPtr bonuses = getBonuses(Selector::type(Bonus::CREATURE_GROWTH).And(Selector::subtype(level)));
 	for(const Bonus *b : *bonuses)
-		ret.entries.push_back(GrowthInfo::Entry(b->Description() + " %+d", b->val));
+		ret.entries.push_back(GrowthInfo::Entry(b->val, b->Description()));
 
 	//statue-of-legion-like bonus: % to base+castle
 	TBonusListPtr bonuses2 = getBonuses(Selector::type(Bonus::CREATURE_GROWTH_PERCENT));
 	for(const Bonus *b : *bonuses2)
-		ret.entries.push_back(GrowthInfo::Entry(b->Description() + " %+d", b->val * (base + castleBonus) / 100));
+		ret.entries.push_back(GrowthInfo::Entry(b->val * (base + castleBonus) / 100, b->Description()));
 
 	if(hasBuilt(BuildingID::GRAIL)) //grail - +50% to ALL (so far added) growth
 		ret.entries.push_back(GrowthInfo::Entry(subID, BuildingID::GRAIL, ret.totalGrowth() / 2));
@@ -1244,6 +1244,12 @@ GrowthInfo::Entry::Entry(int subID, BuildingID building, int _count)
 	description = boost::str(boost::format("%s %+d") % VLC->townh->factions[subID]->town->buildings.at(building)->Name() % count);
 }
 
+GrowthInfo::Entry::Entry(int _count, const std::string &fullDescription)
+	: count(_count)
+{
+	description = fullDescription;
+}
+
 CTownAndVisitingHero::CTownAndVisitingHero()
 {
 	setNodeType(TOWN_AND_VISITOR);

+ 1 - 0
lib/mapObjects/CGTownInstance.h

@@ -130,6 +130,7 @@ struct DLL_LINKAGE GrowthInfo
 		std::string description;
 		Entry(const std::string &format, int _count);
 		Entry(int subID, BuildingID building, int _count);
+		Entry(int _count, const std::string &fullDescription);
 	};
 
 	std::vector<Entry> entries;