Browse Source

Disemboweling the system.
Things are broken now.

Michał W. Urbańczyk 15 years ago
parent
commit
9028684697

+ 2 - 1
client/CPlayerInterface.cpp

@@ -243,7 +243,8 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
 
 	bool directlyAttackingCreature =
 		CGI->mh->map->isInTheMap(details.attackedFrom)
-		&& adventureInt->terrain.currentPath->nodes.size() == 3;
+		&& adventureInt->terrain.currentPath					//in case if movement has been canceled in the meantime and path was already erased
+		&& adventureInt->terrain.currentPath->nodes.size() == 3;//FIXME should be 2 but works nevertheless...
 
 	if(makingTurn  &&  ho->tempOwner == playerID) //we are moving our hero - we may need to update assigned path
 	{

+ 9 - 9
hch/CArtHandler.cpp

@@ -171,15 +171,15 @@ int CArtifact::getArtClassSerial() const
 	return -1;
 }
 
-void CArtifact::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
-{
-	//combined artifact carries bonuses from its parts
-	if(constituents)
-	{
-		BOOST_FOREACH(ui32 id, *constituents)
-			out.insert(VLC->arth->artifacts[id]);
-	}
-}
+// void CArtifact::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
+// {
+// 	//combined artifact carries bonuses from its parts
+// 	if(constituents)
+// 	{
+// 		BOOST_FOREACH(ui32 id, *constituents)
+// 			out.insert(VLC->arth->artifacts[id]);
+// 	}
+// }
 
 void CScroll::Init()
 {

+ 1 - 1
hch/CArtHandler.h

@@ -54,7 +54,7 @@ public:
 	~CArtifact();
 
 	//override
-	void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const;
+	//void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const;
 };
 
 class DLL_EXPORT IModableArt : public CArtifact //artifact which can have different properties, such as scroll or banner

+ 4 - 4
hch/CCreatureHandler.cpp

@@ -129,10 +129,10 @@ void CCreature::addBonus(int val, int type, int subtype /*= -1*/)
 	Bonus added(Bonus::PERMANENT, type, Bonus::CREATURE_ABILITY, val, idNumber, subtype, Bonus::BASE_NUMBER);
 	bonuses.push_back(added);
 }
-void CCreature::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
-{
-	out.insert (VLC->creh->globalEffects);
-}
+// void CCreature::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
+// {
+// 	out.insert (VLC->creh->globalEffects);
+// }
 bool CCreature::isMyUpgrade(const CCreature *anotherCre) const
 {
 	//TODO upgrade of upgrade?

+ 1 - 1
hch/CCreatureHandler.h

@@ -62,7 +62,7 @@ public:
 	bool isMyUpgrade(const CCreature *anotherCre) const;
 
 	void addBonus(int val, int type, int subtype = -1);
-	void getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const;
+	//void getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const;
 
 	template<typename RanGen>
 	int getRandomAmount(RanGen &ranGen)

+ 158 - 158
hch/CObjectHandler.cpp

@@ -1488,79 +1488,79 @@ int CGHeroInstance::getSpellCost(const CSpell *sp) const
 	return sp->costs[getSpellSchoolLevel(sp)];
 }
 
-void CGHeroInstance::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
-{
-	CArmedInstance::getParents(out, root);
-
-	if((root == this || contains(static_cast<const CStackInstance *>(root))) &&  visitedTown && !dynamic_cast<const PlayerState*>(root))
-	{
-			out.insert(visitedTown);
-	}
-
-	for (std::map<ui16,CArtifact*>::const_iterator i = artifWorn.begin(); i != artifWorn.end(); i++)
-		out.insert(i->second);
-
-	out.insert(&speciality);
-}
+// void CGHeroInstance::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
+// {
+// 	CArmedInstance::getParents(out, root);
+// 
+// 	if((root == this || contains(static_cast<const CStackInstance *>(root))) &&  visitedTown && !dynamic_cast<const PlayerState*>(root))
+// 	{
+// 			out.insert(visitedTown);
+// 	}
+// 
+// 	for (std::map<ui16,CArtifact*>::const_iterator i = artifWorn.begin(); i != artifWorn.end(); i++)
+// 		out.insert(i->second);
+// 
+// 	out.insert(&speciality);
+// }
 
 void CGHeroInstance::pushPrimSkill(int which, int val)
 {
 	bonuses.push_back(Bonus(Bonus::PERMANENT, Bonus::PRIMARY_SKILL, Bonus::HERO_BASE_SKILL, val, id, which));
 }
 
-void CGHeroInstance::getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const
-{
-#define FOREACH_OWNER_TOWN(town) if(const PlayerState *p = cb->getPlayerState(tempOwner)) BOOST_FOREACH(const CGTownInstance *town, p->towns)
-
-	CArmedInstance::getBonuses(out, selector, root); ///that's not part of macro!
-
-	//TODO eliminate by moving secondary skills effects to bonus system
-	if(Selector::matchesType(selector, Bonus::LUCK))
-	{
-		//luck skill
-		if(int luckSkill = getSecSkillLevel(9)) 
-			out.push_back(Bonus(Bonus::PERMANENT, Bonus::LUCK, Bonus::SECONDARY_SKILL, luckSkill, 9, VLC->generaltexth->arraytxt[73+luckSkill]));
-
-		//guardian spirit
-		FOREACH_OWNER_TOWN(t)
-			if(t->subID ==1 && vstd::contains(t->builtBuildings,26)) //rampart with grail
-				out.push_back(Bonus(Bonus::PERMANENT, Bonus::LUCK, Bonus::TOWN_STRUCTURE, +2, 26, VLC->generaltexth->buildings[1][26].first + " +2"));
-	}
-
-	if(Selector::matchesType(selector, Bonus::SEA_MOVEMENT))
-	{
-		//lighthouses
-		FOREACH_OWNER_TOWN(t)
-			if(t->subID == 0 && vstd::contains(t->builtBuildings,17)) //castle
-				out.push_back(Bonus(Bonus::PERMANENT, Bonus::SEA_MOVEMENT, Bonus::TOWN_STRUCTURE, +500, 17, VLC->generaltexth->buildings[0][17].first + " +500"));
-	}
-
-	if(Selector::matchesType(selector, Bonus::MORALE))
-	{
-		//leadership
-		if(int moraleSkill = getSecSkillLevel(6)) 
-			out.push_back(Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::SECONDARY_SKILL, moraleSkill, 6, VLC->generaltexth->arraytxt[104+moraleSkill]));
-
-		//colossus
-		FOREACH_OWNER_TOWN(t)
-			if(t->subID == 0 && vstd::contains(t->builtBuildings,26)) //castle
-				out.push_back(Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::TOWN_STRUCTURE, +2, 26, VLC->generaltexth->buildings[0][26].first + " +2"));
-	}
-
-	if(Selector::matchesTypeSubtype(selector, Bonus::SECONDARY_SKILL_PREMY, 12)) //necromancy
-	{
-		FOREACH_OWNER_TOWN(t)
-		{
-			if(t->subID == 4) //necropolis
-			{
-				if(vstd::contains(t->builtBuildings,21)) //necromancy amplifier
-					out.push_back(Bonus(Bonus::PERMANENT, Bonus::SECONDARY_SKILL_PREMY, Bonus::TOWN_STRUCTURE, +10, 21, VLC->generaltexth->buildings[4][21].first + " +10%", 12));
-				if(vstd::contains(t->builtBuildings,26)) //grail - Soul prison
-					out.push_back(Bonus(Bonus::PERMANENT, Bonus::SECONDARY_SKILL_PREMY, Bonus::TOWN_STRUCTURE, +20, 26, VLC->generaltexth->buildings[4][26].first + " +20%", 12));
-			}
-		}
-	}
-}
+// void CGHeroInstance::getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const
+// {
+// #define FOREACH_OWNER_TOWN(town) if(const PlayerState *p = cb->getPlayerState(tempOwner)) BOOST_FOREACH(const CGTownInstance *town, p->towns)
+// 
+// 	CArmedInstance::getBonuses(out, selector, root); ///that's not part of macro!
+// 
+// 	//TODO eliminate by moving secondary skills effects to bonus system
+// 	if(Selector::matchesType(selector, Bonus::LUCK))
+// 	{
+// 		//luck skill
+// 		if(int luckSkill = getSecSkillLevel(9)) 
+// 			out.push_back(Bonus(Bonus::PERMANENT, Bonus::LUCK, Bonus::SECONDARY_SKILL, luckSkill, 9, VLC->generaltexth->arraytxt[73+luckSkill]));
+// 
+// 		//guardian spirit
+// 		FOREACH_OWNER_TOWN(t)
+// 			if(t->subID ==1 && vstd::contains(t->builtBuildings,26)) //rampart with grail
+// 				out.push_back(Bonus(Bonus::PERMANENT, Bonus::LUCK, Bonus::TOWN_STRUCTURE, +2, 26, VLC->generaltexth->buildings[1][26].first + " +2"));
+// 	}
+// 
+// 	if(Selector::matchesType(selector, Bonus::SEA_MOVEMENT))
+// 	{
+// 		//lighthouses
+// 		FOREACH_OWNER_TOWN(t)
+// 			if(t->subID == 0 && vstd::contains(t->builtBuildings,17)) //castle
+// 				out.push_back(Bonus(Bonus::PERMANENT, Bonus::SEA_MOVEMENT, Bonus::TOWN_STRUCTURE, +500, 17, VLC->generaltexth->buildings[0][17].first + " +500"));
+// 	}
+// 
+// 	if(Selector::matchesType(selector, Bonus::MORALE))
+// 	{
+// 		//leadership
+// 		if(int moraleSkill = getSecSkillLevel(6)) 
+// 			out.push_back(Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::SECONDARY_SKILL, moraleSkill, 6, VLC->generaltexth->arraytxt[104+moraleSkill]));
+// 
+// 		//colossus
+// 		FOREACH_OWNER_TOWN(t)
+// 			if(t->subID == 0 && vstd::contains(t->builtBuildings,26)) //castle
+// 				out.push_back(Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::TOWN_STRUCTURE, +2, 26, VLC->generaltexth->buildings[0][26].first + " +2"));
+// 	}
+// 
+// 	if(Selector::matchesTypeSubtype(selector, Bonus::SECONDARY_SKILL_PREMY, 12)) //necromancy
+// 	{
+// 		FOREACH_OWNER_TOWN(t)
+// 		{
+// 			if(t->subID == 4) //necropolis
+// 			{
+// 				if(vstd::contains(t->builtBuildings,21)) //necromancy amplifier
+// 					out.push_back(Bonus(Bonus::PERMANENT, Bonus::SECONDARY_SKILL_PREMY, Bonus::TOWN_STRUCTURE, +10, 21, VLC->generaltexth->buildings[4][21].first + " +10%", 12));
+// 				if(vstd::contains(t->builtBuildings,26)) //grail - Soul prison
+// 					out.push_back(Bonus(Bonus::PERMANENT, Bonus::SECONDARY_SKILL_PREMY, Bonus::TOWN_STRUCTURE, +20, 26, VLC->generaltexth->buildings[4][26].first + " +20%", 12));
+// 			}
+// 		}
+// 	}
+// }
 
 EAlignment CGHeroInstance::getAlignment() const
 {
@@ -2299,32 +2299,32 @@ int CGTownInstance::getBoatType() const
 		return 2;
 }
 
-void CGTownInstance::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
-{
-	CArmedInstance::getParents(out, root);
-	if(root == this  &&  visitingHero && visitingHero != root)
-		out.insert(visitingHero);
-}
-
-void CGTownInstance::getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const
-{
-	CArmedInstance::getBonuses(out, selector, root);
-	//TODO eliminate by moving structures effects to bonus system
-
-	if(Selector::matchesType(selector, Bonus::LUCK))
-	{
-		if(subID == 1  &&  vstd::contains(builtBuildings,21)) //rampart, fountain of fortune
-			out.push_back(Bonus(Bonus::PERMANENT, Bonus::LUCK, Bonus::TOWN_STRUCTURE, +2, 21, VLC->generaltexth->buildings[1][21].first + " +2"));
-	}
+// void CGTownInstance::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
+// {
+// 	CArmedInstance::getParents(out, root);
+// 	if(root == this  &&  visitingHero && visitingHero != root)
+// 		out.insert(visitingHero);
+// }
 
-	if(Selector::matchesType(selector, Bonus::MORALE))
-	{
-		if(subID == 0  &&  vstd::contains(builtBuildings,22)) //castle, brotherhood of sword built
-			out.push_back(Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::TOWN_STRUCTURE, +2, 22, VLC->generaltexth->buildings[0][22].first + " +2"));
-		else if(vstd::contains(builtBuildings,5)) //tavern is built
-			out.push_back(Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::TOWN_STRUCTURE, +1, 5, VLC->generaltexth->buildings[0][5].first + " +1"));
-	}
-}
+// void CGTownInstance::getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const
+// {
+// 	CArmedInstance::getBonuses(out, selector, root);
+// 	//TODO eliminate by moving structures effects to bonus system
+// 
+// 	if(Selector::matchesType(selector, Bonus::LUCK))
+// 	{
+// 		if(subID == 1  &&  vstd::contains(builtBuildings,21)) //rampart, fountain of fortune
+// 			out.push_back(Bonus(Bonus::PERMANENT, Bonus::LUCK, Bonus::TOWN_STRUCTURE, +2, 21, VLC->generaltexth->buildings[1][21].first + " +2"));
+// 	}
+// 
+// 	if(Selector::matchesType(selector, Bonus::MORALE))
+// 	{
+// 		if(subID == 0  &&  vstd::contains(builtBuildings,22)) //castle, brotherhood of sword built
+// 			out.push_back(Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::TOWN_STRUCTURE, +2, 22, VLC->generaltexth->buildings[0][22].first + " +2"));
+// 		else if(vstd::contains(builtBuildings,5)) //tavern is built
+// 			out.push_back(Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::TOWN_STRUCTURE, +1, 5, VLC->generaltexth->buildings[0][5].first + " +1"));
+// 	}
+// }
 
 int CGTownInstance::getMarketEfficiency() const
 {
@@ -6560,82 +6560,82 @@ void CArmedInstance::randomizeArmy(int type)
 	return;
 }
 
-void CArmedInstance::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
-{
-	/* //already given via PlayerState->getBonuses();
-	const PlayerState *p = cb->getPlayerState(tempOwner);
-	if (p && p != root) 
-		out.insert(p); 
-	*/
-	out.insert(&cb->gameState()->globalEffects); //global effects are always active I believe
-
-	if(battle)
-		out.insert(battle);
-}
+// void CArmedInstance::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
+// {
+// 	/* //already given via PlayerState->getBonuses();
+// 	const PlayerState *p = cb->getPlayerState(tempOwner);
+// 	if (p && p != root) 
+// 		out.insert(p); 
+// 	*/
+// 	out.insert(&cb->gameState()->globalEffects); //global effects are always active I believe
+// 
+// 	if(battle)
+// 		out.insert(battle);
+// }
 
 CArmedInstance::CArmedInstance()
 {
 	battle = NULL;
 }
 
-void CArmedInstance::getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const
-{
-	CBonusSystemNode::getBonuses(out, selector, root);
-
-	if(!battle)
-	{
-		//TODO do it clean, unify with BattleInfo version
-		if(Selector::matchesType(selector, Bonus::MORALE) || Selector::matchesType(selector, Bonus::LUCK))
-		{
-			for(TSlots::const_iterator i=Slots().begin(); i!=Slots().end(); i++)
-				i->second.getBonuses(out, selector, Selector::effectRange(Bonus::ONLY_ALLIED_ARMY), this);
-		}
-	}
-
-	if(Selector::matchesType(selector, Bonus::MORALE))
-	{
-		//number of alignments and presence of undead
-		if(contains(dynamic_cast<const CStackInstance*>(root)))
-		{
-			bool archangelInArmy = false;
-			bool canMix = hasBonusOfType(Bonus::NONEVIL_ALIGNMENT_MIX);
-			std::set<si8> factions;
-			for(TSlots::const_iterator i=Slots().begin(); i!=Slots().end(); i++)
-			{
-				// Take Angelic Alliance troop-mixing freedom of non-evil, non-Conflux units into account.
-				const si8 faction = i->second.type->faction;
-				if (canMix
-					&& ((faction >= 0 && faction <= 2) || faction == 6 || faction == 7))
-				{
-					factions.insert(0); // Insert a single faction of the affected group, Castle will do.
-				}
-				else
-				{
-					factions.insert(faction);
-				}
-
-				if(i->second.type->idNumber == 13)
-					archangelInArmy = true;
-			}
-
-			if(factions.size() == 1)
-				out.push_back(Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::ARMY, +1, id, VLC->generaltexth->arraytxt[115]));//All troops of one alignment +1
-			else
-			{
-				int fcountModifier = 2-factions.size();
-				out.push_back(Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::ARMY, fcountModifier, id, boost::str(boost::format(VLC->generaltexth->arraytxt[114]) % factions.size() % fcountModifier)));//Troops of %d alignments %d
-			}
-
-			if(vstd::contains(factions,4))
-				out.push_back(Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::ARMY, -1, id, VLC->generaltexth->arraytxt[116]));//Undead in group -1
-		}
-	}
-}
+// void CArmedInstance::getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const
+// {
+// 	CBonusSystemNode::getBonuses(out, selector, root);
+// 
+// 	if(!battle)
+// 	{
+// 		//TODO do it clean, unify with BattleInfo version
+// 		if(Selector::matchesType(selector, Bonus::MORALE) || Selector::matchesType(selector, Bonus::LUCK))
+// 		{
+// 			for(TSlots::const_iterator i=Slots().begin(); i!=Slots().end(); i++)
+// 				i->second.getBonuses(out, selector, Selector::effectRange(Bonus::ONLY_ALLIED_ARMY), this);
+// 		}
+// 	}
+// 
+// 	if(Selector::matchesType(selector, Bonus::MORALE))
+// 	{
+// 		//number of alignments and presence of undead
+// 		if(contains(dynamic_cast<const CStackInstance*>(root)))
+// 		{
+// 			bool archangelInArmy = false;
+// 			bool canMix = hasBonusOfType(Bonus::NONEVIL_ALIGNMENT_MIX);
+// 			std::set<si8> factions;
+// 			for(TSlots::const_iterator i=Slots().begin(); i!=Slots().end(); i++)
+// 			{
+// 				// Take Angelic Alliance troop-mixing freedom of non-evil, non-Conflux units into account.
+// 				const si8 faction = i->second.type->faction;
+// 				if (canMix
+// 					&& ((faction >= 0 && faction <= 2) || faction == 6 || faction == 7))
+// 				{
+// 					factions.insert(0); // Insert a single faction of the affected group, Castle will do.
+// 				}
+// 				else
+// 				{
+// 					factions.insert(faction);
+// 				}
+// 
+// 				if(i->second.type->idNumber == 13)
+// 					archangelInArmy = true;
+// 			}
+// 
+// 			if(factions.size() == 1)
+// 				out.push_back(Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::ARMY, +1, id, VLC->generaltexth->arraytxt[115]));//All troops of one alignment +1
+// 			else
+// 			{
+// 				int fcountModifier = 2-factions.size();
+// 				out.push_back(Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::ARMY, fcountModifier, id, boost::str(boost::format(VLC->generaltexth->arraytxt[114]) % factions.size() % fcountModifier)));//Troops of %d alignments %d
+// 			}
+// 
+// 			if(vstd::contains(factions,4))
+// 				out.push_back(Bonus(Bonus::PERMANENT, Bonus::MORALE, Bonus::ARMY, -1, id, VLC->generaltexth->arraytxt[116]));//Undead in group -1
+// 		}
+// 	}
+// }
 
 int CArmedInstance::valOfGlobalBonuses(CSelector selector) const
 {
 	//if (tempOwner != NEUTRAL_PLAYER)
-	return cb->gameState()->players[tempOwner].valOfBonuses(selector, this);
+	return cb->gameState()->players[tempOwner].valOfBonuses(selector);
 }
 
 bool IMarket::getOffer(int id1, int id2, int &val1, int &val2, EMarketMode mode) const

+ 7 - 7
hch/CObjectHandler.h

@@ -227,9 +227,9 @@ public:
 	void randomizeArmy(int type);
 
 	//////////////////////////////////////////////////////////////////////////
-	void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const;
-	void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const;
-	int valOfGlobalBonuses(CSelector selector) const; //used only for castle interface
+	//void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const;
+	//void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const;
+	int valOfGlobalBonuses(CSelector selector) const; //used only for castle interface								???
 	//////////////////////////////////////////////////////////////////////////
 
 	CArmedInstance();
@@ -305,8 +305,8 @@ public:
 		//visitied town pointer will be restored by map serialization method
 	}
 	//////////////////////////////////////////////////////////////////////////
-	void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const;
-	void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const;
+// 	void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const;
+// 	void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const;
 	//////////////////////////////////////////////////////////////////////////
 	int3 getSightCenter() const; //"center" tile from which the sight distance is calculated
 	int getSightRadious() const; //sight distance (should be used if player-owned structure)
@@ -528,8 +528,8 @@ public:
 		//garrison/visiting hero pointers will be restored in the map serialization
 	}
 	//////////////////////////////////////////////////////////////////////////
-	void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const;
-	void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const;
+// 	void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const;
+// 	void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const;
 	//////////////////////////////////////////////////////////////////////////
 
 	ui8 getPassableness() const; //bitmap - if the bit is set the corresponding player can pass through the visitable tiles of object, even if it's blockvis; if not set - default properties from definfo are used

+ 12 - 12
lib/CCreatureSet.cpp

@@ -265,18 +265,18 @@ void CStackInstance::setType(int creID)
 	type = VLC->creh->creatures[creID];
 }
 
-void CStackInstance::getParents(TCNodes &out, const CBonusSystemNode *source /*= NULL*/) const
-{
-	out.insert(type);
-
-	if(source && source != this) //we should be root, if not - do not inherit anything
-		return;
-
-	if(armyObj)
-		out.insert(armyObj);
-	else
-		out.insert(&IObjectInterface::cb->gameState()->globalEffects);
-}
+// void CStackInstance::getParents(TCNodes &out, const CBonusSystemNode *source /*= NULL*/) const
+// {
+// 	out.insert(type);
+// 
+// 	if(source && source != this) //we should be root, if not - do not inherit anything
+// 		return;
+// 
+// 	if(armyObj)
+// 		out.insert(armyObj);
+// 	else
+// 		out.insert(&IObjectInterface::cb->gameState()->globalEffects);
+// }
 
 std::string CStackInstance::getQuantityTXT(bool capitalized /*= true*/) const
 {

+ 1 - 1
lib/CCreatureSet.h

@@ -35,7 +35,7 @@ public:
 	}
 
 	//overrides CBonusSystemNode
-	void getParents(TCNodes &out, const CBonusSystemNode *source = NULL) const;  //retrieves list of parent nodes (nodes to inherit bonuses from), source is the prinary asker
+	//void getParents(TCNodes &out, const CBonusSystemNode *source = NULL) const;  //retrieves list of parent nodes (nodes to inherit bonuses from), source is the prinary asker
 
 	int getQuantityID() const;
 	std::string getQuantityTXT(bool capitalized = true) const;

+ 33 - 33
lib/CGameState.cpp

@@ -4305,26 +4305,26 @@ si8 BattleInfo::canTeleportTo(int stackID, int destHex, int telportLevel)
 
 }
 
-void BattleInfo::getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const
-{
-	CBonusSystemNode::getBonuses(out, selector, root);
-
-	const CStack *dest = dynamic_cast<const CStack*>(root);
-	if (!dest)
-		return;
-
-	//TODO: make it in clean way
-	if(Selector::matchesType(selector, Bonus::MORALE) || Selector::matchesType(selector, Bonus::LUCK))
-	{
-		BOOST_FOREACH(const CStack *s, stacks)
-		{
-			if(s->owner == dest->owner)
-				s->getBonuses(out, selector, Selector::effectRange(Bonus::ONLY_ALLIED_ARMY), this);
-			else
-				s->getBonuses(out, selector, Selector::effectRange(Bonus::ONLY_ENEMY_ARMY), this);
-		}
-	}
-}
+// void BattleInfo::getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const
+// {
+// 	CBonusSystemNode::getBonuses(out, selector, root);
+// 
+// 	const CStack *dest = dynamic_cast<const CStack*>(root);
+// 	if (!dest)
+// 		return;
+// 
+// 	//TODO: make it in clean way
+// 	if(Selector::matchesType(selector, Bonus::MORALE) || Selector::matchesType(selector, Bonus::LUCK))
+// 	{
+// 		BOOST_FOREACH(const CStack *s, stacks)
+// 		{
+// 			if(s->owner == dest->owner)
+// 				s->getBonuses(out, selector, Selector::effectRange(Bonus::ONLY_ALLIED_ARMY), this);
+// 			else
+// 				s->getBonuses(out, selector, Selector::effectRange(Bonus::ONLY_ENEMY_ARMY), this);
+// 		}
+// 	}
+// }
 
 si8 BattleInfo::getDistance( int hex1, int hex2 )
 {
@@ -4492,19 +4492,19 @@ PlayerState::PlayerState()
 
 }
 
-void PlayerState::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
-{
-	return; //no loops possible
-}
-
-void PlayerState::getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const
-{
-	for (std::vector<CGHeroInstance *>::const_iterator it = heroes.begin(); it != heroes.end(); it++)
-	{
-		if (*it != root)
-			(*it)->getBonuses(out, selector, this);
-	}
-}
+// void PlayerState::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const
+// {
+// 	return; //no loops possible
+// }
+// 
+// void PlayerState::getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const
+// {
+// 	for (std::vector<CGHeroInstance *>::const_iterator it = heroes.begin(); it != heroes.end(); it++)
+// 	{
+// 		if (*it != root)
+// 			(*it)->getBonuses(out, selector, this);
+// 	}
+// }
 
 InfoAboutHero::InfoAboutHero()
 {

+ 3 - 3
lib/CGameState.h

@@ -137,8 +137,8 @@ public:
 	PlayerState();
 
 	//override
-	void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const; 
-	void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const;
+	//void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const; 
+	//void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const;
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
@@ -212,7 +212,7 @@ struct DLL_EXPORT BattleInfo : public CBonusSystemNode
 	}
 
 	//////////////////////////////////////////////////////////////////////////
-	void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const;
+	//void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const;
 	//////////////////////////////////////////////////////////////////////////
 
 	const CStack * getNextStack() const; //which stack will have turn after current one

+ 34 - 39
lib/HeroBonus.cpp

@@ -9,8 +9,8 @@
 #include "CCreatureSet.h"
 #include <boost/algorithm/string/trim.hpp>
 
-#define FOREACH_CONST_PARENT(pname, source) 	TCNodes parents; getParents(parents, source); BOOST_FOREACH(const CBonusSystemNode *pname, parents)
-#define FOREACH_PARENT(pname, source) 	TNodes parents; getParents(parents, source); BOOST_FOREACH(CBonusSystemNode *pname, parents)
+#define FOREACH_CONST_PARENT(pname) 	TCNodes parents; getParents(parents); BOOST_FOREACH(const CBonusSystemNode *pname, parents)
+#define FOREACH_PARENT(pname) 	TNodes parents; getParents(parents); BOOST_FOREACH(CBonusSystemNode *pname, parents)
 
 #define BONUS_NAME(x) ( #x, Bonus::x )
 	DLL_EXPORT const std::map<std::string, int> bonusNameMap = boost::assign::map_list_of BONUS_LIST;
@@ -155,13 +155,13 @@ int CBonusSystemNode::valOfBonuses(Bonus::BonusType type, int subtype /*= -1*/)
 
 	return valOfBonuses(s);
 }
-int CBonusSystemNode::valOfBonuses(const CSelector &selector, const CBonusSystemNode *root/* = NULL*/) const
+int CBonusSystemNode::valOfBonuses(const CSelector &selector) const
 {
 	BonusList hlp;
-	getBonuses(hlp, selector, root);
+	getBonuses(hlp, selector);
 	return hlp.totalValue();
 }
-bool CBonusSystemNode::hasBonus(const CSelector &selector, const CBonusSystemNode *root/* = NULL*/) const
+bool CBonusSystemNode::hasBonus(const CSelector &selector) const
 {
 	return getBonuses(selector).size() > 0;
 }
@@ -181,10 +181,7 @@ Bonus * CBonusSystemNode::getBonus(const CSelector &selector)
 	if(ret)
 		return ret;
 
-	//FOREACH_PARENT(p, this)
-	TNodes parents;
-	getParents (parents, this);
-	BOOST_FOREACH (CBonusSystemNode *pname, parents)
+	FOREACH_PARENT(pname)
 	{
 		ret = pname->getBonus(selector);
 		if (ret)
@@ -199,7 +196,7 @@ void CBonusSystemNode::getModifiersWDescr(TModDescr &out, Bonus::BonusType type,
 	getModifiersWDescr(out, Selector::typeSybtype(type, subtype));
 }
 
-void CBonusSystemNode::getModifiersWDescr(TModDescr &out, const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const
+void CBonusSystemNode::getModifiersWDescr(TModDescr &out, const CSelector &selector) const
 {
 	getBonuses(selector).getModifiersWDescr(out);
 }
@@ -208,31 +205,26 @@ int CBonusSystemNode::getBonusesCount(int from, int id) const
 	return getBonusesCount(Selector::source(from, id));
 }
 
-int CBonusSystemNode::getBonusesCount(const CSelector &selector, const CBonusSystemNode *root/* = NULL*/) const
+int CBonusSystemNode::getBonusesCount(const CSelector &selector) const
 {
-	return getBonuses(selector, root).size();
+	return getBonuses(selector).size();
 }
 
-void CBonusSystemNode::getParents(TCNodes &out, const CBonusSystemNode *root) const /*retreives list of parent nodes (nodes to inherit bonuses from) */
+void CBonusSystemNode::getParents(TCNodes &out) const /*retreives list of parent nodes (nodes to inherit bonuses from) */
 {
-	return;
+	BOOST_FOREACH(const CBonusSystemNode *parent, parents)
+		out.insert(parent);
 }
 
-void CBonusSystemNode::getParents(TNodes &out, const CBonusSystemNode *root /*= NULL*/)
+void CBonusSystemNode::getParents(TNodes &out)
 {
-	//de-constify above
-	TCNodes hlp;
-	getParents(hlp, root);
-	BOOST_FOREACH(const CBonusSystemNode *pname, hlp)
-		out.insert(const_cast<CBonusSystemNode*>(pname));
+	BOOST_FOREACH(const CBonusSystemNode *parent, parents)
+		out.insert(const_cast<CBonusSystemNode*>(parent));
 }
 
 void CBonusSystemNode::getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const
 {
-	//FOREACH_CONST_PARENT(p, root ? root : this) //unwinded macro
-	TCNodes parents;
-	getParents(parents, root ? root : this);
-	BOOST_FOREACH(const CBonusSystemNode *p, parents)
+	FOREACH_CONST_PARENT(p) //unwinded macro
 		p->getBonuses(out, selector, root ? root : this);
 
 	bonuses.getBonuses(out, selector);
@@ -241,31 +233,24 @@ void CBonusSystemNode::getBonuses(BonusList &out, const CSelector &selector, con
 		out.limit(*this);
 }
 
-BonusList CBonusSystemNode::getBonuses(const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const
+BonusList CBonusSystemNode::getBonuses(const CSelector &selector) const
 {
 	BonusList ret;
-	getBonuses(ret, selector, root);
+	getBonuses(ret, selector);
 	return ret;
 }
 
-void CBonusSystemNode::getBonuses(BonusList &out, const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root /*= NULL*/) const
+void CBonusSystemNode::getBonuses(BonusList &out, const CSelector &selector, const CSelector &limit) const
 {
-	//FOREACH_CONST_PARENT(p, root ? root : this) //unwinded macro
-	TCNodes parents;
-	getParents(parents, root ? root : this);
-	BOOST_FOREACH(const CBonusSystemNode *p, parents)
-		p->getBonuses(out, selector, limit, root ? root : this);
-
-	bonuses.getBonuses(out, selector, limit);
-
-	if(!root)
-		out.limit(*this);
+	getBonuses(out, selector); //first get all the bonuses
+	out.remove_if(std::not1(limit)); //now remove the ones we don't like
+	out.limit(*this); //apply bonuses' limiters
 }
 
-BonusList CBonusSystemNode::getBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root /*= NULL*/) const
+BonusList CBonusSystemNode::getBonuses(const CSelector &selector, const CSelector &limit) const
 {
 	BonusList ret;
-	getBonuses(ret, selector, limit, root);
+	getBonuses(ret, selector, limit);
 	return ret;
 }
 
@@ -349,6 +334,16 @@ CBonusSystemNode::~CBonusSystemNode()
 
 }
 
+void CBonusSystemNode::attachTo(const CBonusSystemNode *parent)
+{
+
+}
+
+void CBonusSystemNode::detachFrom(const CBonusSystemNode *parent)
+{
+
+}
+
 int NBonus::valOf(const CBonusSystemNode *obj, Bonus::BonusType type, int subtype /*= -1*/)
 {
 	if(obj)

+ 21 - 11
lib/HeroBonus.h

@@ -345,7 +345,12 @@ public:
 class DLL_EXPORT CBonusSystemNode
 {
 public:
-	BonusList bonuses;
+	BonusList bonuses; //wielded bonuses (local and up-propagated here)
+	std::vector<Bonus*> exportedBonuses;
+
+	std::vector<const CBonusSystemNode *> parents, //parents -> we inherit bonuses from them, we may attach our bonuses to them
+									children;
+
 	ui8 nodeType;
 
 	CBonusSystemNode();
@@ -354,18 +359,20 @@ public:
 	//new bonusing node interface
 	// * selector is predicate that tests if HeroBonus matches our criteria
 	// * root is node on which call was made (NULL will be replaced with this)
-	virtual void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const;  //retrieves list of parent nodes (nodes to inherit bonuses from), source is the prinary asker
-	virtual void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const;
+	void getParents(TCNodes &out) const;  //retrieves list of parent nodes (nodes to inherit bonuses from), source is the prinary asker
+	void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const;
 
-	void getBonuses(BonusList &out, const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = NULL) const;
-	BonusList getBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = NULL) const;
-	BonusList getBonuses(const CSelector &selector, const CBonusSystemNode *root = NULL) const;
-	int getBonusesCount(const CSelector &selector, const CBonusSystemNode *root = NULL) const;
-	int valOfBonuses(const CSelector &selector, const CBonusSystemNode *root = NULL) const;
-	bool hasBonus(const CSelector &selector, const CBonusSystemNode *root = NULL) const;
-	void getModifiersWDescr(TModDescr &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const;  //out: pairs<modifier value, modifier description>
 
 	//////////////////////////////////////////////////////////////////////////
+	//interface
+	void getModifiersWDescr(TModDescr &out, const CSelector &selector) const;  //out: pairs<modifier value, modifier description>
+	int getBonusesCount(const CSelector &selector) const;
+	int valOfBonuses(const CSelector &selector) const;
+	bool hasBonus(const CSelector &selector) const;
+	BonusList getBonuses(const CSelector &selector, const CSelector &limit) const;
+	void getBonuses(BonusList &out, const CSelector &selector, const CSelector &limit) const;
+	BonusList getBonuses(const CSelector &selector) const;
+
 	//legacy interface 
 	int valOfBonuses(Bonus::BonusType type, const CSelector &selector) const;
 	int valOfBonuses(Bonus::BonusType type, int subtype = -1) const; //subtype -> subtype of bonus, if -1 then anyt;
@@ -384,9 +391,12 @@ public:
 
 
 	//non-const interface
-	void getParents(TNodes &out, const CBonusSystemNode *root = NULL);  //retrieves list of parent nodes (nodes to inherit bonuses from), source is the prinary asker
+	void getParents(TNodes &out);  //retrieves list of parent nodes (nodes to inherit bonuses from), source is the prinary asker
 	Bonus *getBonus(const CSelector &selector);
 
+	void attachTo(const CBonusSystemNode *parent);
+	void detachFrom(const CBonusSystemNode *parent);
+
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
 		h & bonuses & nodeType;