mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Merge pull request #678 from MikeLodz/develop
Fixes mantis tickets 2899 and 2984 (bugged hero spell specialties)
This commit is contained in:
commit
11bb46780a
@ -325,6 +325,11 @@
|
|||||||
"class" : "elementalist",
|
"class" : "elementalist",
|
||||||
"female": true,
|
"female": true,
|
||||||
"spellbook": [ "stoneSkin" ],
|
"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":
|
"skills":
|
||||||
[
|
[
|
||||||
{ "skill" : "wisdom", "level": "basic" },
|
{ "skill" : "wisdom", "level": "basic" },
|
||||||
@ -375,9 +380,9 @@
|
|||||||
"specialty" : {
|
"specialty" : {
|
||||||
"bonuses" : {
|
"bonuses" : {
|
||||||
"disruptingRay" : {
|
"disruptingRay" : {
|
||||||
"addInfo" : 0,
|
"addInfo" : -2,
|
||||||
"subtype" : "spell.disruptingRay",
|
"subtype" : "spell.disruptingRay",
|
||||||
"type" : "SPECIAL_PECULIAR_ENCHANT"
|
"type" : "SPECIAL_ADD_VALUE_ENCHANT"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -265,8 +265,9 @@
|
|||||||
"specialty" : {
|
"specialty" : {
|
||||||
"bonuses" : {
|
"bonuses" : {
|
||||||
"fortune" : {
|
"fortune" : {
|
||||||
|
"addInfo" : 3,
|
||||||
"subtype" : "spell.fortune",
|
"subtype" : "spell.fortune",
|
||||||
"type" : "MAXED_SPELL"
|
"type" : "SPECIAL_FIXED_VALUE_ENCHANT"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1468,6 +1468,8 @@ JsonNode subtypeToJson(Bonus::BonusType type, int subtype)
|
|||||||
case Bonus::SPECIAL_BLESS_DAMAGE:
|
case Bonus::SPECIAL_BLESS_DAMAGE:
|
||||||
case Bonus::MAXED_SPELL:
|
case Bonus::MAXED_SPELL:
|
||||||
case Bonus::SPECIAL_PECULIAR_ENCHANT:
|
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);
|
return JsonUtils::stringNode("spell." + (*VLC->spellh)[SpellID::ESpellID(subtype)]->identifier);
|
||||||
case Bonus::IMPROVED_NECROMANCY:
|
case Bonus::IMPROVED_NECROMANCY:
|
||||||
case Bonus::SPECIAL_UPGRADE:
|
case Bonus::SPECIAL_UPGRADE:
|
||||||
@ -1556,6 +1558,8 @@ std::string Bonus::nameForBonus() const
|
|||||||
case Bonus::SPECIAL_BLESS_DAMAGE:
|
case Bonus::SPECIAL_BLESS_DAMAGE:
|
||||||
case Bonus::MAXED_SPELL:
|
case Bonus::MAXED_SPELL:
|
||||||
case Bonus::SPECIAL_PECULIAR_ENCHANT:
|
case Bonus::SPECIAL_PECULIAR_ENCHANT:
|
||||||
|
case Bonus::SPECIAL_ADD_VALUE_ENCHANT:
|
||||||
|
case Bonus::SPECIAL_FIXED_VALUE_ENCHANT:
|
||||||
return (*VLC->spellh)[SpellID::ESpellID(subtype)]->identifier;
|
return (*VLC->spellh)[SpellID::ESpellID(subtype)]->identifier;
|
||||||
case Bonus::SPECIAL_UPGRADE:
|
case Bonus::SPECIAL_UPGRADE:
|
||||||
return CreatureID::encode(subtype) + "2" + CreatureID::encode(additionalInfo[0]);
|
return CreatureID::encode(subtype) + "2" + CreatureID::encode(additionalInfo[0]);
|
||||||
|
@ -321,6 +321,8 @@ public:
|
|||||||
BONUS_NAME(SPECIAL_CRYSTAL_GENERATION) /*crystal dragon crystal generation*/ \
|
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(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(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 */
|
/* end of list */
|
||||||
|
|
||||||
|
@ -791,7 +791,15 @@ TDmgRange CBattleInfoCallback::calculateDmgRange(const BattleAttackInfo & info)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(isAffected)
|
if(isAffected)
|
||||||
|
{
|
||||||
attackDefenceDifference += SpellID(SpellID::SLAYER).toSpell()->getPower(spLevel);
|
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
|
//bonus from attack/defense skills
|
||||||
|
@ -151,10 +151,16 @@ void Timed::prepareEffects(SetStackEffect & sse, const Mechanics * m, const Effe
|
|||||||
std::vector<Bonus> converted;
|
std::vector<Bonus> converted;
|
||||||
convertBonus(m, duration, 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);
|
auto casterHero = dynamic_cast<const CGHeroInstance *>(m->caster);
|
||||||
if(casterHero)
|
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?
|
//TODO: does hero specialty should affects his stack casting spells?
|
||||||
|
|
||||||
for(auto & t : target)
|
for(auto & t : target)
|
||||||
@ -175,13 +181,14 @@ void Timed::prepareEffects(SetStackEffect & sse, const Mechanics * m, const Effe
|
|||||||
if(describe)
|
if(describe)
|
||||||
describeEffect(sse.battleLog, m, converted, affected);
|
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
|
//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(peculiarBonus)
|
||||||
if(bonus)
|
|
||||||
{
|
{
|
||||||
switch(bonus->additionalInfo[0])
|
|
||||||
|
si32 power = 0;
|
||||||
|
switch (peculiarBonus->additionalInfo[0])
|
||||||
{
|
{
|
||||||
case 0: //normal
|
case 0: //normal
|
||||||
switch (tier)
|
switch (tier)
|
||||||
@ -199,23 +206,36 @@ void Timed::prepareEffects(SetStackEffect & sse, const Mechanics * m, const Effe
|
|||||||
power = 1;
|
power = 1;
|
||||||
break;
|
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;
|
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);
|
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;
|
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
|
if(casterHero && casterHero->hasBonusOfType(Bonus::SPECIAL_BLESS_DAMAGE, m->getSpellIndex())) //TODO: better handling of bonus percentages
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user