瀏覽代碼

vcmi: fix logistics specialist movement regression

There was incorrect calculations introduced earlier.
Konstantin 2 年之前
父節點
當前提交
580268bfd4
共有 6 個文件被更改,包括 21 次插入33 次删除
  1. 2 7
      config/defaultMods.json
  2. 6 3
      lib/CPathfinder.cpp
  3. 1 0
      lib/CPathfinder.h
  4. 8 20
      lib/HeroBonus.cpp
  5. 1 2
      lib/HeroBonus.h
  6. 3 1
      lib/mapObjects/CGHeroInstance.cpp

+ 2 - 7
config/defaultMods.json

@@ -83,15 +83,10 @@
 			"type" : "MOVEMENT", //Basic land movement
 			"type" : "MOVEMENT", //Basic land movement
 			"subtype" : 1,
 			"subtype" : 1,
 			"val" : 1300,
 			"val" : 1300,
-			"valueType" : "BASE_NUMBER"
-		},
-		{
-			"type" : "MOVEMENT", //Enable army movement bonus
-			"subtype" : 1,
 			"valueType" : "BASE_NUMBER",
 			"valueType" : "BASE_NUMBER",
 			"updater" : {
 			"updater" : {
-				"type" : "ARMY_MOVEMENT",
-				"parameters" : [ 20, 3, 10, 700]
+				"type" : "ARMY_MOVEMENT", //Enable army movement bonus
+				"parameters" : [20, 3, 10, 700]
 			}
 			}
 		},
 		},
 		{
 		{

+ 6 - 3
lib/CPathfinder.cpp

@@ -1014,8 +1014,11 @@ TurnInfo::BonusCache::BonusCache(TConstBonusListPtr bl)
 	pathfindingVal = bl->valOfBonuses(Selector::type()(Bonus::ROUGH_TERRAIN_DISCOUNT));
 	pathfindingVal = bl->valOfBonuses(Selector::type()(Bonus::ROUGH_TERRAIN_DISCOUNT));
 }
 }
 
 
-TurnInfo::TurnInfo(const CGHeroInstance * Hero, const int turn)
-	: hero(Hero), maxMovePointsLand(-1), maxMovePointsWater(-1)
+TurnInfo::TurnInfo(const CGHeroInstance * Hero, const int turn):
+	hero(Hero),
+	maxMovePointsLand(-1),
+	maxMovePointsWater(-1),
+	turn(turn)
 {
 {
 	bonuses = hero->getAllBonuses(Selector::days(turn), Selector::all, nullptr, "");
 	bonuses = hero->getAllBonuses(Selector::days(turn), Selector::all, nullptr, "");
 	bonusCache = std::make_unique<BonusCache>(bonuses);
 	bonusCache = std::make_unique<BonusCache>(bonuses);
@@ -1104,7 +1107,7 @@ void TurnInfo::updateHeroBonuses(Bonus::BonusType type, const CSelector& sel) co
 		bonusCache->pathfindingVal = bonuses->valOfBonuses(Selector::type()(Bonus::ROUGH_TERRAIN_DISCOUNT));
 		bonusCache->pathfindingVal = bonuses->valOfBonuses(Selector::type()(Bonus::ROUGH_TERRAIN_DISCOUNT));
 		break;
 		break;
 	default:
 	default:
-		bonuses = hero->getUpdatedBonusList(*bonuses, Selector::type()(type).And(sel));
+		bonuses = hero->getAllBonuses(Selector::days(turn), Selector::all, nullptr, "");
 	}
 	}
 }
 }
 
 

+ 1 - 0
lib/CPathfinder.h

@@ -529,6 +529,7 @@ struct DLL_LINKAGE TurnInfo
 	mutable int maxMovePointsLand;
 	mutable int maxMovePointsLand;
 	mutable int maxMovePointsWater;
 	mutable int maxMovePointsWater;
 	TerrainId nativeTerrain;
 	TerrainId nativeTerrain;
+	int turn;
 
 
 	TurnInfo(const CGHeroInstance * Hero, const int Turn = 0);
 	TurnInfo(const CGHeroInstance * Hero, const int Turn = 0);
 	bool isLayerAvailable(const EPathfindingLayer layer) const;
 	bool isLayerAvailable(const EPathfindingLayer layer) const;

+ 8 - 20
lib/HeroBonus.cpp

@@ -960,7 +960,7 @@ void CBonusSystemNode::getAllParents(TCNodes & out) const //retrieves list of pa
 	}
 	}
 }
 }
 
 
-void CBonusSystemNode::getAllBonusesRec(BonusList &out) const
+void CBonusSystemNode::getAllBonusesRec(BonusList &out, const CSelector & selector) const
 {
 {
 	//out has been reserved sufficient capacity at getAllBonuses() call
 	//out has been reserved sufficient capacity at getAllBonuses() call
 
 
@@ -980,13 +980,14 @@ void CBonusSystemNode::getAllBonusesRec(BonusList &out) const
 
 
 	for (auto parent : lparents)
 	for (auto parent : lparents)
 	{
 	{
-		parent->getAllBonusesRec(beforeUpdate);
+		parent->getAllBonusesRec(beforeUpdate, selector);
 	}
 	}
 	bonuses.getAllBonuses(beforeUpdate);
 	bonuses.getAllBonuses(beforeUpdate);
 
 
 	for(const auto & b : beforeUpdate)
 	for(const auto & b : beforeUpdate)
 	{
 	{
-		auto updated = b->updater
+		//We should not run updaters on non-selected bonuses
+		auto updated = selector(b.get()) && b->updater
 			? getUpdatedBonus(b, b->updater)
 			? getUpdatedBonus(b, b->updater)
 			: b;
 			: b;
 
 
@@ -1023,7 +1024,7 @@ TConstBonusListPtr CBonusSystemNode::getAllBonuses(const CSelector &selector, co
 			cachedBonuses.clear();
 			cachedBonuses.clear();
 			cachedRequests.clear();
 			cachedRequests.clear();
 
 
-			getAllBonusesRec(allBonuses);
+			getAllBonusesRec(allBonuses, Selector::all);
 			limitBonuses(allBonuses, cachedBonuses);
 			limitBonuses(allBonuses, cachedBonuses);
 			cachedBonuses.stackBonuses();
 			cachedBonuses.stackBonuses();
 
 
@@ -1065,7 +1066,7 @@ TConstBonusListPtr CBonusSystemNode::getAllBonusesWithoutCaching(const CSelector
 
 
 	// Get bonus results without caching enabled.
 	// Get bonus results without caching enabled.
 	BonusList beforeLimiting, afterLimiting;
 	BonusList beforeLimiting, afterLimiting;
-	getAllBonusesRec(beforeLimiting);
+	getAllBonusesRec(beforeLimiting, selector);
 
 
 	if(!root || root == this)
 	if(!root || root == this)
 	{
 	{
@@ -1076,7 +1077,7 @@ TConstBonusListPtr CBonusSystemNode::getAllBonusesWithoutCaching(const CSelector
 		//We want to limit our query against an external node. We get all its bonuses,
 		//We want to limit our query against an external node. We get all its bonuses,
 		// add the ones we're considering and see if they're cut out by limiters
 		// add the ones we're considering and see if they're cut out by limiters
 		BonusList rootBonuses, limitedRootBonuses;
 		BonusList rootBonuses, limitedRootBonuses;
-		getAllBonusesRec(rootBonuses);
+		getAllBonusesRec(rootBonuses, selector);
 
 
 		for(auto b : beforeLimiting)
 		for(auto b : beforeLimiting)
 			rootBonuses.push_back(b);
 			rootBonuses.push_back(b);
@@ -1099,19 +1100,6 @@ std::shared_ptr<Bonus> CBonusSystemNode::getUpdatedBonus(const std::shared_ptr<B
 	return updater->createUpdatedBonus(b, * this);
 	return updater->createUpdatedBonus(b, * this);
 }
 }
 
 
-TConstBonusListPtr CBonusSystemNode::getUpdatedBonusList(const BonusList & out, const CSelector & sel) const
-{
-	auto ret = std::make_shared<BonusList>();
-	for(const auto & b : out)
-	{
-		if(sel(b.get()) && b->updater)
-			ret->push_back(getUpdatedBonus(b, b->updater));
-		else
-			ret->push_back(b);
-	}
-	return ret;
-}
-
 CBonusSystemNode::CBonusSystemNode()
 CBonusSystemNode::CBonusSystemNode()
 	:CBonusSystemNode(false)
 	:CBonusSystemNode(false)
 {
 {
@@ -2788,7 +2776,7 @@ std::shared_ptr<Bonus> ArmyMovementUpdater::createUpdatedBonus(const std::shared
 		auto counted = armySpeed * multiplier;
 		auto counted = armySpeed * multiplier;
 		auto newBonus = std::make_shared<Bonus>(*b);
 		auto newBonus = std::make_shared<Bonus>(*b);
 		newBonus->source = Bonus::ARMY;
 		newBonus->source = Bonus::ARMY;
-		newBonus->val = vstd::amin(counted, max);
+		newBonus->val += vstd::amin(counted, max);
 		return newBonus;
 		return newBonus;
 	}
 	}
 	if(b->type != Bonus::MOVEMENT)
 	if(b->type != Bonus::MOVEMENT)

+ 1 - 2
lib/HeroBonus.h

@@ -789,7 +789,7 @@ private:
 	mutable std::map<std::string, TBonusListPtr > cachedRequests;
 	mutable std::map<std::string, TBonusListPtr > cachedRequests;
 	mutable boost::mutex sync;
 	mutable boost::mutex sync;
 
 
-	void getAllBonusesRec(BonusList &out) const;
+	void getAllBonusesRec(BonusList &out, const CSelector & selector) const;
 	TConstBonusListPtr getAllBonusesWithoutCaching(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = nullptr) const;
 	TConstBonusListPtr getAllBonusesWithoutCaching(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = nullptr) const;
 	std::shared_ptr<Bonus> getUpdatedBonus(const std::shared_ptr<Bonus> & b, const TUpdaterPtr updater) const;
 	std::shared_ptr<Bonus> getUpdatedBonus(const std::shared_ptr<Bonus> & b, const TUpdaterPtr updater) const;
 
 
@@ -805,7 +805,6 @@ public:
 	TConstBonusListPtr getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = nullptr, const std::string &cachingStr = "") const override;
 	TConstBonusListPtr getAllBonuses(const CSelector &selector, const CSelector &limit, const CBonusSystemNode *root = nullptr, const std::string &cachingStr = "") const override;
 	void getParents(TCNodes &out) const;  //retrieves list of parent nodes (nodes to inherit bonuses from),
 	void getParents(TCNodes &out) const;  //retrieves list of parent nodes (nodes to inherit bonuses from),
 	std::shared_ptr<const Bonus> getBonusLocalFirst(const CSelector & selector) const;
 	std::shared_ptr<const Bonus> getBonusLocalFirst(const CSelector & selector) const;
-	TConstBonusListPtr getUpdatedBonusList(const BonusList& out, const CSelector &sel) const; //update bonuses in list with builtin updaters, passes this as context
 
 
 	//non-const interface
 	//non-const interface
 	void getParents(TNodes &out);  //retrieves list of parent nodes (nodes to inherit bonuses from)
 	void getParents(TNodes &out);  //retrieves list of parent nodes (nodes to inherit bonuses from)

+ 3 - 1
lib/mapObjects/CGHeroInstance.cpp

@@ -199,7 +199,9 @@ void CGHeroInstance::updateArmyMovementBonus(bool onLand, const TurnInfo * ti) c
 	if(lowestCreatureSpeed != realLowestSpeed)
 	if(lowestCreatureSpeed != realLowestSpeed)
 	{
 	{
 		lowestCreatureSpeed = realLowestSpeed;
 		lowestCreatureSpeed = realLowestSpeed;
-		ti->updateHeroBonuses(Bonus::MOVEMENT, Selector::subtype()(!!onLand).And(Selector::sourceTypeSel(Bonus::ARMY)));
+		//Let updaters run again
+		treeHasChanged();
+		ti->updateHeroBonuses(Bonus::MOVEMENT, Selector::subtype()(!!onLand));
 	}
 	}
 }
 }