mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Fixes mantis tickets 2899 and 2984 (bugged hero spell specialties)
- stoneskin/haste/prayer/weakness: didnt work because there were 2 bonus objects in buffer and they were filtered out as a possible duplicate (BattleInfo::addOrUpdateUnitBonus). it was fixed by making them a single bonus. - disrupting-ray and weakness: had opposite effect, because of missing negation - added a new specialty types: SPECIAL_ADD_VALUE_ENCHANT and SPECIAL_FIXED_VALUE_ENCHANT. this is to make possible specialties like Aenin (fixed specialty value added to spell value) and Melody (fixed value for spell regardless of anything). These specialties can be used in mods with any heroes. - slayer spell effect calculations was fixed to include hero Coronius-style specialty. - finally fixed description for Labetha Conflux hero, this is a OH3 bug described here https://heroes.thelazy.net/index.php/Labetha Changes were tested and work as intended. commit was made in cooperation with modder Misiokles
This commit is contained in:
parent
db1f9a15b0
commit
38efbb345e
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -265,8 +265,9 @@
|
||||
"specialty" : {
|
||||
"bonuses" : {
|
||||
"fortune" : {
|
||||
"addInfo" : 3,
|
||||
"subtype" : "spell.fortune",
|
||||
"type" : "MAXED_SPELL"
|
||||
"type" : "SPECIAL_FIXED_VALUE_ENCHANT"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1472,6 +1472,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:
|
||||
@ -1560,6 +1562,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]);
|
||||
|
@ -281,6 +281,8 @@ public:
|
||||
BONUS_NAME(SPECIAL_BLESS_DAMAGE) /*val = spell (bless), additionalInfo = value per level in percent*/\
|
||||
BONUS_NAME(MAXED_SPELL) /*val = id*/\
|
||||
BONUS_NAME(SPECIAL_PECULIAR_ENCHANT) /*blesses and curses with id = val dependent on unit's level, subtype = 0 or 1 for Coronius*/\
|
||||
BONUS_NAME(SPECIAL_ADD_VALUE_ENCHANT) /*specialty like Aenin, additionalInfo = value to add*/\
|
||||
BONUS_NAME(SPECIAL_FIXED_VALUE_ENCHANT) /*specialty like Melody constant 3 luck, additionalInfo = value to fix.*/\
|
||||
BONUS_NAME(SPECIAL_UPGRADE) /*subtype = base, additionalInfo = target */\
|
||||
BONUS_NAME(DRAGON_NATURE) \
|
||||
BONUS_NAME(CREATURE_DAMAGE)/*subtype 0 = both, 1 = min, 2 = max*/\
|
||||
|
@ -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
|
||||
|
@ -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,35 @@ 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;
|
||||
}
|
||||
}
|
||||
else if(addedValueBonus)
|
||||
{
|
||||
for(Bonus& b : buffer)
|
||||
{
|
||||
b.val += addedValueBonus->additionalInfo[0];
|
||||
}
|
||||
}
|
||||
else 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
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user