浏览代码

Use json configuration for special spell effect duration

AlexVinS 10 年之前
父节点
当前提交
3ed3f1fa13
共有 3 个文件被更改,包括 37 次插入27 次删除
  1. 4 2
      config/spells/timed.json
  2. 2 2
      lib/BattleState.cpp
  3. 31 23
      lib/spells/CDefaultSpellMechanics.cpp

+ 4 - 2
config/spells/timed.json

@@ -1022,7 +1022,8 @@
 					"inFrenzy" : {
 						"type" : "IN_FRENZY",
 						"val" : 100,
-						"duration" : "N_TURNS"//hardcoded to 1
+						"duration" : "N_TURNS",
+						"turns" : 1
 					}
 				}
 			},
@@ -1111,7 +1112,8 @@
 				"effects" : {
 					"attacksNearestCreature" : {
 						"type" : "ATTACKS_NEAREST_CREATURE",
-						"duration" : "N_TURNS" //hardcoded to 1
+						"duration" : "N_TURNS",
+						"turns" : 1
 					}
 				}
 			},

+ 2 - 2
lib/BattleState.cpp

@@ -848,10 +848,10 @@ void CStack::stackEffectToFeature(std::vector<Bonus> & sf, const Bonus & sse)
 
 	for(Bonus& b : tmp)
 	{
-		b.turnsRemain =  sse.turnsRemain;
+		if(b.turnsRemain == 0)
+			b.turnsRemain = sse.turnsRemain;
 		sf.push_back(b);
 	}
-
 }
 
 bool CStack::willMove(int turn /*= 0*/) const

+ 31 - 23
lib/spells/CDefaultSpellMechanics.cpp

@@ -488,22 +488,15 @@ void DefaultSpellMechanics::battleLogSingleTarget(std::vector<std::string> & log
 
 int DefaultSpellMechanics::calculateDuration(const CGHeroInstance * caster, int usedSpellPower) const
 {
-	switch(owner->id)
+	if(caster == nullptr)
 	{
-	case SpellID::FRENZY: 
-	case SpellID::BERSERK:
-		return 1;
-	default: //other spells		
-		if(caster == nullptr)
-		{
-			if (!usedSpellPower)
-				return 3; //default duration of all creature spells
-			else
-				return usedSpellPower; //use creature spell power			
-		}
+		if (!usedSpellPower)
+			return 3; //default duration of all creature spells
 		else
-			return caster->getPrimSkillLevel(PrimarySkill::SPELL_POWER) + caster->valOfBonuses(Bonus::SPELL_DURATION);
+			return usedSpellPower; //use creature spell power			
 	}
+	else
+		return caster->getPrimSkillLevel(PrimarySkill::SPELL_POWER) + caster->valOfBonuses(Bonus::SPELL_DURATION);
 }
 
 ui32 DefaultSpellMechanics::calculateHealedHP(const CGHeroInstance* caster, const CStack* stack, const CStack* sacrificedStack) const
@@ -577,18 +570,33 @@ void DefaultSpellMechanics::applyBattleEffects(const SpellCastEnvironment * env,
 			stackSpellPower =  parameters.casterStack->valOfBonuses(Bonus::CREATURE_ENCHANT_POWER);
 		}
 		SetStackEffect sse;
-		Bonus pseudoBonus;
-		pseudoBonus.sid = owner->id;
-		pseudoBonus.val = parameters.spellLvl;
-		pseudoBonus.turnsRemain = calculateDuration(parameters.casterHero, stackSpellPower ? stackSpellPower : parameters.usedSpellPower);
-		CStack::stackEffectToFeature(sse.effect, pseudoBonus);
+		//get default spell duration (spell power with bonuses for heroes)
+		int duration = calculateDuration(parameters.casterHero, stackSpellPower ? stackSpellPower : parameters.usedSpellPower);
+		//generate actual stack bonuses
+		{
+			int maxDuration = 0;
+			std::vector<Bonus> tmp;
+			owner->getEffects(tmp, parameters.spellLvl);
+			for(Bonus& b : tmp)
+			{
+				//use configured duration if present
+				if(b.turnsRemain == 0)
+					b.turnsRemain = duration;
+				vstd::amax(maxDuration, b.turnsRemain);
+				sse.effect.push_back(b);
+			}
+			//if all spell effects have special duration, use it 
+			duration = maxDuration;			
+		}
+		//fix to original config: shield should display damage reduction
 		if(owner->id == SpellID::SHIELD || owner->id == SpellID::AIR_SHIELD)
 		{
-			sse.effect.back().val = (100 - sse.effect.back().val); //fix to original config: shield should display damage reduction
+			sse.effect.back().val = (100 - sse.effect.back().val); 
 		}
-		if(owner->id == SpellID::BIND &&  parameters.casterStack)//bind
+		//we need to know who cast Bind
+		if(owner->id == SpellID::BIND && parameters.casterStack)
 		{
-			sse.effect.back().additionalInfo =  parameters.casterStack->ID; //we need to know who casted Bind
+			sse.effect.back().additionalInfo =  parameters.casterStack->ID;
 		}
 		const Bonus * bonus = nullptr;
 		if(parameters.casterHero)
@@ -628,7 +636,7 @@ void DefaultSpellMechanics::applyBattleEffects(const SpellCastEnvironment * env,
 					case 1: //only Coronius as yet
 					{
 						power = std::max(5 - tier, 0);
-						Bonus specialBonus = CStack::featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK, power, pseudoBonus.turnsRemain);
+						Bonus specialBonus = CStack::featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK, power, duration);
 						specialBonus.sid = owner->id;
 						sse.uniqueBonuses.push_back(std::pair<ui32,Bonus> (affected->ID, specialBonus)); //additional attack to Slayer effect
 					}
@@ -638,7 +646,7 @@ void DefaultSpellMechanics::applyBattleEffects(const SpellCastEnvironment * env,
 			if (parameters.casterHero && parameters.casterHero->hasBonusOfType(Bonus::SPECIAL_BLESS_DAMAGE, owner->id)) //TODO: better handling of bonus percentages
 			{
 				int damagePercent = parameters.casterHero->level * parameters.casterHero->valOfBonuses(Bonus::SPECIAL_BLESS_DAMAGE, owner->id.toEnum()) / tier;
-				Bonus specialBonus = CStack::featureGenerator(Bonus::CREATURE_DAMAGE, 0, damagePercent, pseudoBonus.turnsRemain);
+				Bonus specialBonus = CStack::featureGenerator(Bonus::CREATURE_DAMAGE, 0, damagePercent, duration);
 				specialBonus.valType = Bonus::PERCENT_TO_ALL;
 				specialBonus.sid = owner->id;
 				sse.uniqueBonuses.push_back (std::pair<ui32,Bonus> (affected->ID, specialBonus));