Browse Source

Moved tower damage computation to town instance

Ivan Savenko 2 years ago
parent
commit
30d7bdc884
3 changed files with 61 additions and 36 deletions
  1. 19 36
      lib/battle/DamageCalculator.cpp
  2. 36 0
      lib/mapObjects/CGTownInstance.cpp
  3. 6 0
      lib/mapObjects/CGTownInstance.h

+ 19 - 36
lib/battle/DamageCalculator.cpp

@@ -20,38 +20,6 @@
 
 VCMI_LIB_NAMESPACE_BEGIN
 
-namespace SiegeStuffThatShouldBeMovedToHandlers // <=== TODO
-{
-
-static void retrieveTurretDamageRange(const CGTownInstance * town, const battle::Unit * turret, double & outMinDmg, double & outMaxDmg)
-{
-	// http://heroes.thelazy.net/wiki/Arrow_tower
-	assert(turret->creatureIndex() == CreatureID::ARROW_TOWERS);
-	assert(town);
-	assert(turret->getPosition() >= -4 && turret->getPosition() <= -2);
-
-	// base damage, irregardless of town level
-	static const int baseDamageKeep = 10;
-	static const int baseDamageTower = 6;
-
-	// extra damage, for each building in town
-	static const int extraDamage = 2;
-
-	const int townLevel = town->getTownLevel();
-
-	int minDamage;
-
-	if(turret->getPosition() == BattleHex::CASTLE_CENTRAL_TOWER)
-		minDamage = baseDamageKeep + townLevel * extraDamage;
-	else
-		minDamage = baseDamageTower + townLevel / 2 * extraDamage;
-
-	outMinDmg = minDamage;
-	outMaxDmg = minDamage * 2;
-}
-
-}
-
 TDmgRange DamageCalculator::getBaseDamageSingle() const
 {
 	double minDmg = 0.0;
@@ -61,19 +29,34 @@ TDmgRange DamageCalculator::getBaseDamageSingle() const
 	maxDmg = info.attacker->getMaxDamage(info.shooting);
 
 	if(info.attacker->creatureIndex() == CreatureID::ARROW_TOWERS)
-		SiegeStuffThatShouldBeMovedToHandlers::retrieveTurretDamageRange(callback.battleGetDefendedTown(), info.attacker, minDmg, maxDmg);
+	{
+		auto town = callback.battleGetDefendedTown();
+		assert(town);
+
+		switch(info.attacker->getPosition())
+		{
+		case BattleHex::CASTLE_CENTRAL_TOWER:
+			return town->getKeepDamageRange();
+		case BattleHex::CASTLE_BOTTOM_TOWER:
+		case BattleHex::CASTLE_UPPER_TOWER:
+			return town->getTowerDamageRange();
+		default:
+			assert(0);
+		}
+	}
 
 	const std::string cachingStrSiedgeWeapon = "type_SIEGE_WEAPON";
 	static const auto selectorSiedgeWeapon = Selector::type()(Bonus::SIEGE_WEAPON);
 
-	if(info.attacker->hasBonus(selectorSiedgeWeapon, cachingStrSiedgeWeapon) && info.attacker->creatureIndex() != CreatureID::ARROW_TOWERS) //any siege weapon, but only ballista can attack (second condition - not arrow turret)
-	{ //minDmg and maxDmg are multiplied by hero attack + 1
+	if(info.attacker->hasBonus(selectorSiedgeWeapon, cachingStrSiedgeWeapon) && info.attacker->creatureIndex() != CreatureID::ARROW_TOWERS)
+	{
 		auto retrieveHeroPrimSkill = [&](int skill) -> int
 		{
 			std::shared_ptr<const Bonus> b = info.attacker->getBonus(Selector::sourceTypeSel(Bonus::HERO_BASE_SKILL).And(Selector::typeSubtype(Bonus::PRIMARY_SKILL, skill)));
-			return b ? b->val : 0; //if there is no hero or no info on his primary skill, return 0
+			return b ? b->val : 0;
 		};
 
+		//minDmg and maxDmg are multiplied by hero attack + 1
 		minDmg *= retrieveHeroPrimSkill(PrimarySkill::ATTACK) + 1;
 		maxDmg *= retrieveHeroPrimSkill(PrimarySkill::ATTACK) + 1;
 	}

+ 36 - 0
lib/mapObjects/CGTownInstance.cpp

@@ -799,6 +799,42 @@ void CGTownInstance::addTownBonuses()
 	}
 }
 
+TDmgRange CGTownInstance::getTowerDamageRange() const
+{
+	assert(hasBuilt(BuildingID::CASTLE));
+
+	// http://heroes.thelazy.net/wiki/Arrow_tower
+	// base damage, irregardless of town level
+	static const int baseDamage = 6;
+	// extra damage, for each building in town
+	static const int extraDamage = 1;
+
+	const int minDamage = baseDamage + extraDamage * getTownLevel();
+
+	return {
+		minDamage,
+		minDamage * 2
+	};
+}
+
+TDmgRange CGTownInstance::getKeepDamageRange() const
+{
+	assert(hasBuilt(BuildingID::CITADEL));
+
+	// http://heroes.thelazy.net/wiki/Arrow_tower
+	// base damage, irregardless of town level
+	static const int baseDamage = 10;
+	// extra damage, for each building in town
+	static const int extraDamage = 2;
+
+	const int minDamage = baseDamage + extraDamage * getTownLevel();
+
+	return {
+		minDamage,
+		minDamage * 2
+	};
+}
+
 void CGTownInstance::deleteTownBonus(BuildingID::EBuildingID bid)
 {
 	size_t i = 0;

+ 6 - 0
lib/mapObjects/CGTownInstance.h

@@ -330,6 +330,12 @@ public:
 	void addHeroToStructureVisitors(const CGHeroInstance *h, si64 structureInstanceID) const; //hero must be visiting or garrisoned in town
 	void deleteTownBonus(BuildingID::EBuildingID bid);
 
+	/// Returns damage range for secondary towers of this town
+	TDmgRange getTowerDamageRange() const;
+
+	/// Returns damage range for central tower(keep) of this town
+	TDmgRange getKeepDamageRange() const;
+
 	const CTown * getTown() const ;
 
 	CGTownInstance();