Explorar o código

vcmi: remove ONLY_ENEMY_ARMY range

It should be used directly instead of alias, propagation updater
also can be useful for any other updaters can be added.
Konstantin %!s(int64=2) %!d(string=hai) anos
pai
achega
b91d7418dd

+ 2 - 2
config/creatures/inferno.json

@@ -369,7 +369,7 @@
 				"val" : -1,
 				"stacking" : "Devils",
 				"propagator": "BATTLE_WIDE",
-				"updater" : "BONUS_OWNER_UPDATER",
+				"propagationUpdater" : "BONUS_OWNER_UPDATER",
 				"limiters" : [ "OPPOSITE_SIDE" ]
 			},
 			"blockRetaliation" :
@@ -423,7 +423,7 @@
 				"val" : -1,
 				"stacking" : "Devils",
 				"propagator": "BATTLE_WIDE",
-				"updater" : "BONUS_OWNER_UPDATER",
+				"propagationUpdater" : "BONUS_OWNER_UPDATER",
 				"limiters" : [ "OPPOSITE_SIDE" ]
 			},
 			"blockRetaliation" :

+ 2 - 2
config/creatures/necropolis.json

@@ -345,7 +345,7 @@
 				"val" : -1,
 				"stacking" : "Undead Dragons",
 				"propagator": "BATTLE_WIDE",
-				"updater" : "BONUS_OWNER_UPDATER",
+				"propagationUpdater" : "BONUS_OWNER_UPDATER",
 				"limiters" : [ "OPPOSITE_SIDE" ]
 			}
 		},
@@ -380,7 +380,7 @@
 				"val" : -1,
 				"stacking" : "Undead Dragons",
 				"propagator": "BATTLE_WIDE",
-				"updater" : "BONUS_OWNER_UPDATER",
+				"propagationUpdater" : "BONUS_OWNER_UPDATER",
 				"limiters" : [ "OPPOSITE_SIDE" ]
 			},
 			"age" :

+ 24 - 0
config/schemas/bonus.json

@@ -115,6 +115,30 @@
 				}
 			]
 		},
+		"propagationUpdater" : {
+			"anyOf" : [
+				{
+					"type" : "string"
+				},
+				{
+					"description" : "propagationUpdater",
+					"type" : "object",
+					"required" : ["type", "parameters"],
+					"additionalProperties" : false,
+					"properties" : {
+						"type" : {
+							"type" : "string",
+							"description" : "type"
+						},
+						"parameters": {
+							"type" : "array",
+							"description" : "parameters",
+							"additionalItems" : true
+						}
+					}
+				}
+			]
+		},
 		"sourceID": {
 			"type":"number",
 			"description": "sourceID"

+ 3 - 37
lib/HeroBonus.cpp

@@ -67,7 +67,6 @@ const std::map<std::string, Bonus::LimitEffect> bonusLimitEffect =
 	BONUS_ITEM(NO_LIMIT)
 	BONUS_ITEM(ONLY_DISTANCE_FIGHT)
 	BONUS_ITEM(ONLY_MELEE_FIGHT)
-	BONUS_ITEM(ONLY_ENEMY_ARMY)
 };
 
 const std::map<std::string, TLimiterPtr> bonusLimiterMap =
@@ -95,7 +94,8 @@ const std::map<std::string, TUpdaterPtr> bonusUpdaterMap =
 {
 	{"TIMES_HERO_LEVEL", std::make_shared<TimesHeroLevelUpdater>()},
 	{"TIMES_STACK_LEVEL", std::make_shared<TimesStackLevelUpdater>()},
-	{"ARMY_MOVEMENT", std::make_shared<ArmyMovementUpdater>()}
+	{"ARMY_MOVEMENT", std::make_shared<ArmyMovementUpdater>()},
+	{"BONUS_OWNER_UPDATER", std::make_shared<OwnerUpdater>()}
 };
 
 const std::set<std::string> deprecatedBonusSet = {
@@ -590,7 +590,7 @@ void BonusList::getBonuses(BonusList & out, const CSelector &selector, const CSe
 	for (auto & b : bonuses)
 	{
 		//add matching bonuses that matches limit predicate or have NO_LIMIT if no given predicate
-		auto noFightLimit = b->effectRange == Bonus::NO_LIMIT || b->effectRange == Bonus::ONLY_ENEMY_ARMY;
+		auto noFightLimit = b->effectRange == Bonus::NO_LIMIT;
 		if(selector(b.get()) && ((!limit && noFightLimit) || ((bool)limit && limit(b.get()))))
 			out.push_back(b);
 	}
@@ -2677,40 +2677,6 @@ std::shared_ptr<Bonus> Bonus::addUpdater(TUpdaterPtr Updater)
 	return this->shared_from_this();
 }
 
-// Update ONLY_ENEMY_ARMY bonuses from old saves to make them workable.
-// Also, we should foreseen possible errors in bonus configuration and fix them.
-void Bonus::updateOppositeBonuses()
-{
-	if(effectRange != Bonus::ONLY_ENEMY_ARMY)
-		return;
-
-	if(propagator)
-	{
-		if(propagator->getPropagatorType() != CBonusSystemNode::BATTLE)
-		{
-			logMod->error("Wrong Propagator will be ignored: The 'ONLY_ENEMY_ARMY' effectRange is only compatible with the 'BATTLE_WIDE' propagator.");
-			propagator.reset(new CPropagatorNodeType(CBonusSystemNode::BATTLE));
-		}
-	}
-	else
-	{
-		propagator = std::make_shared<CPropagatorNodeType>(CBonusSystemNode::BATTLE);
-	}
-	if(limiter)
-	{
-		if(!dynamic_cast<OppositeSideLimiter*>(limiter.get()))
-		{
-			logMod->error("Wrong Limiter will be ignored: The 'ONLY_ENEMY_ARMY' effectRange is only compatible with the 'OPPOSITE_SIDE' limiter.");
-			limiter.reset(new OppositeSideLimiter());
-		}
-	}
-	else
-	{
-		limiter = std::make_shared<OppositeSideLimiter>();
-	}
-	propagationUpdater = std::make_shared<OwnerUpdater>();
-}
-
 IUpdater::~IUpdater()
 {
 }

+ 0 - 2
lib/HeroBonus.h

@@ -406,7 +406,6 @@ struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>
 	{
 		NO_LIMIT = 0,
 		ONLY_DISTANCE_FIGHT=1, ONLY_MELEE_FIGHT, //used to mark bonuses for attack/defense primary skills from spells like Precision (distance only)
-		ONLY_ENEMY_ARMY
 	};
 
 	enum ValueType
@@ -529,7 +528,6 @@ struct DLL_LINKAGE Bonus : public std::enable_shared_from_this<Bonus>
 	std::shared_ptr<Bonus> addLimiter(TLimiterPtr Limiter); //returns this for convenient chain-calls
 	std::shared_ptr<Bonus> addPropagator(TPropagatorPtr Propagator); //returns this for convenient chain-calls
 	std::shared_ptr<Bonus> addUpdater(TUpdaterPtr Updater); //returns this for convenient chain-calls
-	void updateOppositeBonuses();
 };
 
 DLL_LINKAGE std::ostream & operator<<(std::ostream &out, const Bonus &bonus);

+ 28 - 23
lib/JsonNode.cpp

@@ -847,6 +847,30 @@ static BonusParams convertDeprecatedBonus(const JsonNode &ability)
 	return ret;
 }
 
+static TUpdaterPtr parseUpdater(const JsonNode & updaterJson)
+{
+	switch(updaterJson.getType())
+	{
+	case JsonNode::JsonType::DATA_STRING:
+		return parseByMap(bonusUpdaterMap, &updaterJson, "updater type ");
+		break;
+	case JsonNode::JsonType::DATA_STRUCT:
+		if(updaterJson["type"].String() == "GROWS_WITH_LEVEL")
+		{
+			std::shared_ptr<GrowsWithLevelUpdater> updater = std::make_shared<GrowsWithLevelUpdater>();
+			const JsonVector param = updaterJson["parameters"].Vector();
+			updater->valPer20 = static_cast<int>(param[0].Integer());
+			if(param.size() > 1)
+				updater->stepSize = static_cast<int>(param[1].Integer());
+			return updater;
+		}
+		else
+			logMod->warn("Unknown updater type \"%s\"", updaterJson["type"].String());
+		break;
+	}
+	return nullptr;
+}
+
 bool JsonUtils::parseBonus(const JsonNode &ability, Bonus *b)
 {
 	const JsonNode *value;
@@ -943,29 +967,10 @@ bool JsonUtils::parseBonus(const JsonNode &ability, Bonus *b)
 
 	value = &ability["updater"];
 	if(!value->isNull())
-	{
-		const JsonNode & updaterJson = *value;
-		switch(updaterJson.getType())
-		{
-		case JsonNode::JsonType::DATA_STRING:
-			b->addUpdater(parseByMap(bonusUpdaterMap, &updaterJson, "updater type "));
-			break;
-		case JsonNode::JsonType::DATA_STRUCT:
-			if(updaterJson["type"].String() == "GROWS_WITH_LEVEL")
-			{
-				std::shared_ptr<GrowsWithLevelUpdater> updater = std::make_shared<GrowsWithLevelUpdater>();
-				const JsonVector param = updaterJson["parameters"].Vector();
-				updater->valPer20 = static_cast<int>(param[0].Integer());
-				if(param.size() > 1)
-					updater->stepSize = static_cast<int>(param[1].Integer());
-				b->addUpdater(updater);
-			}
-			else
-				logMod->warn("Unknown updater type \"%s\"", updaterJson["type"].String());
-			break;
-		}
-	}
-	b->updateOppositeBonuses();
+		b->addUpdater(parseUpdater(*value));
+	value = &ability["propagationUpdater"];
+	if(!value->isNull())
+		b->propagationUpdater = parseUpdater(*value);
 	return true;
 }
 

+ 0 - 7
lib/mapObjects/CGTownInstance.cpp

@@ -1225,13 +1225,6 @@ void CGTownInstance::recreateBuildingsBonuses()
 
 		for(auto & bonus : building->buildingBonuses)
 		{
-			if(bonus->limiter && bonus->effectRange == Bonus::ONLY_ENEMY_ARMY) //ONLY_ENEMY_ARMY is only mark for OppositeSide limiter to avoid extra dynamic_cast.
-			{
-				auto bCopy = std::make_shared<Bonus>(*bonus); //just a copy of the shared_ptr has been changed and reassigned.
-				bCopy->limiter = std::make_shared<OppositeSideLimiter>(this->getOwner());
-				addNewBonus(bCopy);
-				continue;
-			}
 			if(bonus->propagator != nullptr && bonus->propagator->getPropagatorType() == ALL_CREATURES)
 				VLC->creh->addBonusForAllCreatures(bonus);
 			else