浏览代码

Fixes from code review

M 1 年之前
父节点
当前提交
9ee526d202

+ 1 - 1
Mods/vcmi/config/vcmi/english.json

@@ -185,7 +185,7 @@
 	"vcmi.battleWindow.damageEstimation.kills.1" : "%d will perish",
 	"vcmi.battleWindow.killed" : "Killed",
 	"vcmi.battleWindow.accurateShot.resultDescription.0" : "%d %s were killed by accurate shots!",
-	"vcmi.battleWindow.accurateShot.resultDescription.1" : "1 %s was killed with an accurate shot!",
+	"vcmi.battleWindow.accurateShot.resultDescription.1" : "%d %s was killed with an accurate shot!",
 	"vcmi.battleWindow.accurateShot.resultDescription.2" : "%d %s were killed by accurate shots!",
 
 	"vcmi.battleResultsWindow.applyResultsLabel" : "Apply battle result",

+ 6 - 12
lib/battle/DamageCalculator.cpp

@@ -10,8 +10,6 @@
 
 #include "StdInc.h"
 
-#include <cfenv>
-
 #include "DamageCalculator.h"
 #include "CBattleInfoCallback.h"
 #include "Unit.h"
@@ -462,7 +460,8 @@ std::vector<double> DamageCalculator::getAttackFactors() const
 		getAttackJoustingFactor(),
 		getAttackDeathBlowFactor(),
 		getAttackDoubleDamageFactor(),
-		getAttackHateFactor()
+		getAttackHateFactor(),
+		getAttackRevengeFactor()
 	};
 }
 
@@ -532,19 +531,14 @@ DamageEstimation DamageCalculator::calculateDmgRange() const
 	for (auto & factor : defenseFactors)
 	{
 		assert(factor >= 0.0);
-		defenseFactorTotal *= ( 1 - std::min(1.0, factor));
+		defenseFactorTotal *= (1 - std::min(1.0, factor));
 	}
 
-	double resultingFactor = std::min(8.0, attackFactorTotal) * std::max( 0.01, defenseFactorTotal);
-
-	//calculated separately since it bypasses cap on bonus damage
-	double revengeFactor = getAttackRevengeFactor();
-	double revengeAdditionalMinDamage = std::round(damageBase.min * revengeFactor);
-	double revengeAdditionalMaxDamage = std::round(damageBase.max * revengeFactor);
+	double resultingFactor = attackFactorTotal * defenseFactorTotal;
 
 	DamageRange damageDealt {
-		std::max<int64_t>( 1.0, std::floor(damageBase.min * resultingFactor + revengeAdditionalMinDamage)),
-		std::max<int64_t>( 1.0, std::floor(damageBase.max * resultingFactor + revengeAdditionalMaxDamage))
+		std::max<int64_t>( 1.0, std::floor(damageBase.min * resultingFactor)),
+		std::max<int64_t>( 1.0, std::floor(damageBase.max * resultingFactor))
 	};
 
 	DamageRange killsDealt = getCasualties(damageDealt);

+ 4 - 2
lib/spells/effects/Damage.cpp

@@ -20,10 +20,12 @@
 #include "../../battle/CBattleInfoCallback.h"
 #include "../../networkPacks/PacksForClientBattle.h"
 #include "../../CGeneralTextHandler.h"
+#include "../../Languages.h"
 #include "../../serializer/JsonSerializeFormat.h"
 
 #include <vcmi/spells/Spell.h>
 
+
 VCMI_LIB_NAMESPACE_BEGIN
 
 namespace spells
@@ -157,9 +159,9 @@ void Damage::describeEffect(std::vector<MetaString> & log, const Mechanics * m,
 		MetaString line;
 		std::string preferredLanguage = VLC->generaltexth->getPreferredLanguage();
 		std::string textID = "vcmi.battleWindow.accurateShot.resultDescription";
-		line.appendTextID(Languages::getPluralFormTextID( preferredLanguage, kills, text));
+		line.appendTextID(Languages::getPluralFormTextID( preferredLanguage, kills, textID));
 		line.replaceNumber(kills);
-		firstTarget->addNameReplacement(line, true);
+		firstTarget->addNameReplacement(line, kills != 1);
 		log.push_back(line);
 	}
 	else if(m->getSpellIndex() == SpellID::THUNDERBOLT && !multiple)

+ 10 - 15
server/battles/BattleActionProcessor.cpp

@@ -1258,9 +1258,13 @@ void BattleActionProcessor::HandleDeathStareAndPirateShot(const CBattleInfoCallb
 	if(bonus == nullptr)
 		bonus = attacker->getBonus(Selector::type()(BonusType::ACCURATE_SHOT));
 
-	if(bonus->type == BonusType::ACCURATE_SHOT && (!ranged || battle.battleHasWallPenalty(attacker, attacker->getPosition(), defender->getPosition())))
-		return; //should not work from behind walls, except being defender or under effect of golden bow etc.
-
+	if(bonus->type == BonusType::ACCURATE_SHOT) //should not work from behind walls, except when being defender or under effect of golden bow etc.
+	{
+		if(!ranged)
+			return;
+		if(battle.battleHasWallPenalty(attacker, attacker->getPosition(), defender->getPosition()))
+			return;
+	}
 
 	int singleCreatureKillChancePercent;
 	if(bonus->type == BonusType::ACCURATE_SHOT)
@@ -1277,20 +1281,11 @@ void BattleActionProcessor::HandleDeathStareAndPirateShot(const CBattleInfoCallb
 	std::binomial_distribution<> distribution(attacker->getCount(), chanceToKill);
 	int killedCreatures = distribution(gameHandler->getRandomGenerator().getStdGenerator());
 
-	if(bonus->type == BonusType::DEATH_STARE)
-	{
-		double cap = 1 / std::max(chanceToKill, (double)(0.01));//don't divide by 0
-		int maxToKill = static_cast<int>((attacker->getCount() + cap - 1) / cap); //not much more than chance * count
-		vstd::amin(killedCreatures, maxToKill);
+	int maxToKill = (attacker->getCount() * singleCreatureKillChancePercent + 99) / 100;
+	vstd::amin(killedCreatures, maxToKill);
 
+	if(bonus->type == BonusType::DEATH_STARE)
 		killedCreatures += (attacker->level() * attacker->valOfBonuses(BonusType::DEATH_STARE, BonusCustomSubtype::deathStareCommander)) / defender->level();
-	}
-	else //ACCURATE_SHOT
-	{
-		bool isMaxToKillRounded = attacker->getCount() * singleCreatureKillChancePercent % 100 == 0;
-		int maxToKill = attacker->getCount() * singleCreatureKillChancePercent / 100 + (isMaxToKillRounded ? 0 : 1);
-		vstd::amin(killedCreatures, maxToKill);
-	}
 
 	if(killedCreatures)
 	{