2
0
Эх сурвалжийг харах

Merge pull request #678 from MikeLodz/develop

Fixes mantis tickets 2899 and 2984 (bugged hero spell specialties)
Alexander Shishkin 4 жил өмнө
parent
commit
11bb46780a

+ 7 - 2
config/heroes/conflux.json

@@ -325,6 +325,11 @@
 		"class" : "elementalist",
 		"female": true,
 		"spellbook": [ "stoneSkin" ],
+		"texts" : {
+			"specialty" : {
+				"description" : "{Stone Skin}\r\n\r\nCasts Stone Skin with increased effect, based on the level of the target unit. (The bonus is greater when used on weaker units)"
+			}
+		},
 		"skills":
 		[
 			{ "skill" : "wisdom", "level": "basic" },
@@ -375,9 +380,9 @@
 		"specialty" : {
 			"bonuses" : {
 				"disruptingRay" : {
-					"addInfo" : 0,
+					"addInfo" : -2,
 					"subtype" : "spell.disruptingRay",
-					"type" : "SPECIAL_PECULIAR_ENCHANT"
+					"type" : "SPECIAL_ADD_VALUE_ENCHANT"
 				}
 			}
 		}

+ 2 - 1
config/heroes/rampart.json

@@ -265,8 +265,9 @@
 		"specialty" : {
 			"bonuses" : {
 				"fortune" : {
+					"addInfo" : 3,
 					"subtype" : "spell.fortune",
-					"type" : "MAXED_SPELL"
+					"type" : "SPECIAL_FIXED_VALUE_ENCHANT"
 				}
 			}
 		}

+ 4 - 0
lib/HeroBonus.cpp

@@ -1468,6 +1468,8 @@ JsonNode subtypeToJson(Bonus::BonusType type, int subtype)
 	case Bonus::SPECIAL_BLESS_DAMAGE:
 	case Bonus::MAXED_SPELL:
 	case Bonus::SPECIAL_PECULIAR_ENCHANT:
+	case Bonus::SPECIAL_ADD_VALUE_ENCHANT:
+	case Bonus::SPECIAL_FIXED_VALUE_ENCHANT:
 		return JsonUtils::stringNode("spell." + (*VLC->spellh)[SpellID::ESpellID(subtype)]->identifier);
 	case Bonus::IMPROVED_NECROMANCY:
 	case Bonus::SPECIAL_UPGRADE:
@@ -1556,6 +1558,8 @@ std::string Bonus::nameForBonus() const
 	case Bonus::SPECIAL_BLESS_DAMAGE:
 	case Bonus::MAXED_SPELL:
 	case Bonus::SPECIAL_PECULIAR_ENCHANT:
+	case Bonus::SPECIAL_ADD_VALUE_ENCHANT:
+	case Bonus::SPECIAL_FIXED_VALUE_ENCHANT:
 		return (*VLC->spellh)[SpellID::ESpellID(subtype)]->identifier;
 	case Bonus::SPECIAL_UPGRADE:
 		return CreatureID::encode(subtype) + "2" + CreatureID::encode(additionalInfo[0]);

+ 2 - 0
lib/HeroBonus.h

@@ -321,6 +321,8 @@ public:
 	BONUS_NAME(SPECIAL_CRYSTAL_GENERATION) /*crystal dragon crystal generation*/ \
 	BONUS_NAME(NO_SPELLCAST_BY_DEFAULT) /*spellcast will not be default attack option for this creature*/ \
 	BONUS_NAME(GARGOYLE) /* gargoyle is special than NON_LIVING, cannot be rised or healed */ \
+	BONUS_NAME(SPECIAL_ADD_VALUE_ENCHANT) /*specialty spell like Aenin has, increased effect of spell, additionalInfo = value to add*/\
+	BONUS_NAME(SPECIAL_FIXED_VALUE_ENCHANT) /*specialty spell like Melody has, constant spell effect (i.e. 3 luck), additionalInfo = value to fix.*/\
 
 	/* end of list */
 

+ 8 - 0
lib/battle/CBattleInfoCallback.cpp

@@ -791,7 +791,15 @@ TDmgRange CBattleInfoCallback::calculateDmgRange(const BattleAttackInfo & info)
 		}
 
 		if(isAffected)
+		{ 
 			attackDefenceDifference += SpellID(SpellID::SLAYER).toSpell()->getPower(spLevel);
+			if(info.attacker->hasBonusOfType(Bonus::SPECIAL_PECULIAR_ENCHANT, SpellID::SLAYER))
+			{
+				ui8 attackerTier = info.attacker->unitType()->level;
+				ui8 specialtyBonus = std::max(5 - attackerTier, 0);
+				attackDefenceDifference += specialtyBonus;
+			}
+		}
 	}
 
 	//bonus from attack/defense skills

+ 40 - 20
lib/spells/effects/Timed.cpp

@@ -151,10 +151,16 @@ void Timed::prepareEffects(SetStackEffect & sse, const Mechanics * m, const Effe
 	std::vector<Bonus> converted;
     convertBonus(m, duration, converted);
 
-	std::shared_ptr<const Bonus> bonus = nullptr;
+	std::shared_ptr<const Bonus> peculiarBonus = nullptr;
+	std::shared_ptr<const Bonus> addedValueBonus = nullptr;
+	std::shared_ptr<const Bonus> fixedValueBonus = nullptr; 
 	auto casterHero = dynamic_cast<const CGHeroInstance *>(m->caster);
 	if(casterHero)
-		bonus = casterHero->getBonusLocalFirst(Selector::typeSubtype(Bonus::SPECIAL_PECULIAR_ENCHANT, m->getSpellIndex()));
+	{ 
+		peculiarBonus = casterHero->getBonusLocalFirst(Selector::typeSubtype(Bonus::SPECIAL_PECULIAR_ENCHANT, m->getSpellIndex()));
+		addedValueBonus = casterHero->getBonusLocalFirst(Selector::typeSubtype(Bonus::SPECIAL_ADD_VALUE_ENCHANT, m->getSpellIndex()));
+		fixedValueBonus = casterHero->getBonusLocalFirst(Selector::typeSubtype(Bonus::SPECIAL_FIXED_VALUE_ENCHANT, m->getSpellIndex()));
+	}
 	//TODO: does hero specialty should affects his stack casting spells?
 
 	for(auto & t : target)
@@ -175,16 +181,17 @@ void Timed::prepareEffects(SetStackEffect & sse, const Mechanics * m, const Effe
 		if(describe)
 			describeEffect(sse.battleLog, m, converted, affected);
 
-		si32 power = 0;
+		const auto tier = std::max(affected->creatureLevel(), 1); //don't divide by 0 for certain creatures (commanders, war machines)
 
 		//Apply hero specials - peculiar enchants
-		const auto tier = std::max(affected->creatureLevel(), 1); //don't divide by 0 for certain creatures (commanders, war machines)
-		if(bonus)
+		if(peculiarBonus)
 		{
-			switch(bonus->additionalInfo[0])
+
+			si32 power = 0;
+			switch (peculiarBonus->additionalInfo[0])
 			{
 			case 0: //normal
-				switch(tier)
+				switch (tier)
 				{
 				case 1:
 				case 2:
@@ -199,23 +206,36 @@ void Timed::prepareEffects(SetStackEffect & sse, const Mechanics * m, const Effe
 					power = 1;
 					break;
 				}
-				for(const Bonus & b : converted)
-				{
-					Bonus specialBonus(b);
-					specialBonus.val = power; //it doesn't necessarily make sense for some spells, use it wisely
-					specialBonus.turnsRemain = duration;
-
-					//additional premy to given effect
-					buffer.push_back(specialBonus);
-				}
 				break;
-			case 1: //only Coronius as yet
+			case 1: 
+				//Coronius style specialty bonus.
+				//Please note that actual Coronius isnt here, because Slayer is a spell that doesnt affect monster stats and is used only in calculateDmgRange
 				power = std::max(5 - tier, 0);
-				Bonus specialBonus(Bonus::N_TURNS, Bonus::PRIMARY_SKILL, Bonus::SPELL_EFFECT, power, m->getSpellIndex(), PrimarySkill::ATTACK);
-				specialBonus.turnsRemain = duration;
-				buffer.push_back(specialBonus);
 				break;
 			}
+			if(m->isNegativeSpell())
+			{
+				//negative spells like weakness are defined in json with negative numbers, so we need do same here
+				power = -1 * power;
+			}
+			for(Bonus& b : buffer)
+			{
+				b.val += power;
+			}
+		}
+		if(addedValueBonus)
+		{
+			for(Bonus& b : buffer)
+			{
+				b.val += addedValueBonus->additionalInfo[0];
+			}
+		}
+		if(fixedValueBonus)
+		{
+			for(Bonus& b : buffer)
+			{
+				b.val = fixedValueBonus->additionalInfo[0];
+			}
 		}
 		if(casterHero && casterHero->hasBonusOfType(Bonus::SPECIAL_BLESS_DAMAGE, m->getSpellIndex())) //TODO: better handling of bonus percentages
 		{