mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Support for Acid Breath (both effects are now separate).
Minor fixes.
This commit is contained in:
parent
09a51acfc2
commit
515ab7e7c1
@ -2935,6 +2935,8 @@ void CBattleInterface::spellCast( const BattleSpellCast * sc )
|
||||
else
|
||||
text = "";
|
||||
break;
|
||||
case 81:
|
||||
break; //handled as hero spell - display damage
|
||||
default:
|
||||
boost::algorithm::replace_first(text, "%s", "Creature"); //TODO: better fix
|
||||
}
|
||||
|
@ -240,9 +240,12 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
|
||||
std::vector<si32> spells = battleStack->activeSpells();
|
||||
BOOST_FOREACH(si32 effect, spells)
|
||||
{
|
||||
blitAt(graphics->spellEffectsPics->ourImages[effect + 1].bitmap, 20 + 52 * printed, 184, *bitmap);
|
||||
if (++printed >= 10) //we can fit only 10 effects
|
||||
break;
|
||||
if (effect < graphics->spellEffectsPics->ourImages.size()) //not all effects have graphics (for eg. Acid Breath)
|
||||
{
|
||||
blitAt(graphics->spellEffectsPics->ourImages[effect + 1].bitmap, 20 + 52 * printed, 184, *bitmap);
|
||||
if (++printed >= 10) //we can fit only 10 effects
|
||||
break;
|
||||
}
|
||||
}
|
||||
//print current health
|
||||
printLine (5, CGI->generaltexth->allTexts[200], battleStack->firstHPleft);
|
||||
@ -314,8 +317,8 @@ void CCreatureWindow::showAll(SDL_Surface * to)
|
||||
printTo(count, 117, 174, FONT_SMALL, tytulowy,*bitmap);
|
||||
printAtMiddle(c->namePl, 180, 30, FONT_SMALL, tytulowy,*bitmap); //creature name
|
||||
|
||||
printLine(0, CGI->generaltexth->primarySkillNames[0], c->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK), stackNode->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK));
|
||||
printLine(1, CGI->generaltexth->primarySkillNames[1], c->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE), stackNode->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE));
|
||||
printLine(0, CGI->generaltexth->primarySkillNames[0], c->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK), stackNode->Attack());
|
||||
printLine(1, CGI->generaltexth->primarySkillNames[1], c->valOfBonuses(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE), stackNode->Defense());
|
||||
//if(c->shots)
|
||||
// printLine(2, CGI->generaltexth->allTexts[198], c->shots);
|
||||
if(stackNode->valOfBonuses(Bonus::SHOTS))
|
||||
|
@ -179,22 +179,24 @@
|
||||
+ 133 DRAGON_NATURE 0 0 0 //crystal dragon is a dragon
|
||||
+ 134 DRAGON_NATURE 0 0 0 //faerie dragon is a dragon
|
||||
+ 135 DRAGON_NATURE 0 0 0 //rust dragon is a dragon
|
||||
+ 135 ACID_BREATH 25 0 20 //20% chance to do 25 damage
|
||||
+ 135 SPELL_AFTER_ATTACK 100 80 0 //always reduce defense
|
||||
+ 136 NO_OBSTACLES_PENALTY 0 0 0 //Enchanter
|
||||
+ 137 NO_DISTANCE_PENALTY 0 0 0 //Sharpshooter
|
||||
+ 137 NO_OBSTACLES_PENALTY 0 0 0
|
||||
+ 140 DOUBLE_WIDE 0 0 0 //boar should be treated as double-wide
|
||||
+ 142 DOUBLE_WIDE 0 0 0 //nomads should be treated as double-wide
|
||||
+ 144 FULL_HP_REGENERATION 0 0 0 //troll
|
||||
+ 147 HEALER 0 0 0 //first aid tent can heal
|
||||
+ 148 NOT_ACTIVE 0 0 0 //Ammo Cart
|
||||
+ 149 SHOOTER 0 0 0 //arrow turret
|
||||
+ 142 DOUBLE_WIDE 0 0 0 //nomads should be treated as double-wide //first aid tent can heal
|
||||
+ 144 FULL_HP_REGENERATION 0 0 0 //troll //Ammo Cart
|
||||
+ 147 HEALER 0 0 0 //arrow turret
|
||||
+ 148 NOT_ACTIVE 0 0 0
|
||||
+ 149 SHOOTER 0 0 0
|
||||
+ 151 DRAGON_NATURE 0 0 0 //diamond dragon is a dragon
|
||||
+ 154 DRAGON_NATURE 0 0 0 //blood dragon is a dragon
|
||||
+ 155 DRAGON_NATURE 0 0 0 //darkness dragon is a dragon
|
||||
+ 168 FLYING 0 0 0 //Gorynyches fly
|
||||
- 46 FLYING //hell hound doesn't fly
|
||||
- 47 FLYING //cerberus doesn't fly
|
||||
- 120 DOUBLE_WIDE //psychic elemental
|
||||
- 121 DOUBLE_WIDE //magic elemental
|
||||
+ 154 DRAGON_NATURE 0 0 0 //blood dragon is a dragon //Gorynyches fly
|
||||
+ 155 DRAGON_NATURE 0 0 0 //darkness dragon is a dragon //hell hound doesn't fly
|
||||
+ 168 FLYING 0 0 0 //cerberus doesn't fly
|
||||
- 46 FLYING //psychic elemental
|
||||
- 47 FLYING //magic elemental
|
||||
- 120 DOUBLE_WIDE
|
||||
- 121 DOUBLE_WIDE
|
||||
- 157 SHOOTER //Hell Hydra certainly does not shoot
|
||||
0
|
||||
|
@ -1792,7 +1792,7 @@ SpellCasting::ESpellCastProblem BattleInfo::battleIsImmune(const CGHeroInstance
|
||||
}
|
||||
|
||||
if(subject->hasBonusOfType(Bonus::SPELL_IMMUNITY, spell->id) ||
|
||||
( immunities.size() > 0 && immunities.totalValue() >= spell->level)) //many creature abilities have level equal to 0 by default, fixed in config\spell_levels
|
||||
( immunities.size() > 0 && immunities.totalValue() >= spell->level && spell->level))
|
||||
{
|
||||
return SpellCasting::STACK_IMMUNE_TO_SPELL;
|
||||
}
|
||||
@ -2167,6 +2167,12 @@ void CStack::stackEffectToFeature(std::vector<Bonus> & sf, const Bonus & sse)
|
||||
sf.push_back(featureGeneratorVT(Bonus::STACK_HEALTH, 0, -50, 3, Bonus::PERCENT_TO_ALL));
|
||||
sf.back().sid = sse.sid;
|
||||
break;
|
||||
case 80: //Acid Breath
|
||||
sf.push_back(featureGenerator(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE, -3, 1));
|
||||
sf.back().sid = sse.sid;
|
||||
sf.back().duration = Bonus::PERMANENT;
|
||||
sf.back().valType = Bonus::ADDITIVE_VALUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -322,23 +322,24 @@ void CSpellHandler::loadSpells()
|
||||
}
|
||||
}
|
||||
ast.close();
|
||||
ast.open(DATA_DIR "/config/spell_levels.txt", std::ios::binary);
|
||||
if(!ast.is_open())
|
||||
{
|
||||
tlog1<<"lack of config/spell_levels.txt file!"<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
//custom levels of spells. Level 0 seems to not be supported correctly, but we can replace it it something else
|
||||
int spellID;
|
||||
ast>>spellID;
|
||||
int buf;
|
||||
while(spellID != -1)
|
||||
{
|
||||
ast >> buf;
|
||||
spells[spellID]->level = buf;
|
||||
ast>>spellID;
|
||||
}
|
||||
}
|
||||
ast.close();
|
||||
//ast.open(DATA_DIR "/config/spell_levels.txt", std::ios::binary);
|
||||
//if(!ast.is_open())
|
||||
//{
|
||||
// tlog1<<"lack of config/spell_levels.txt file!"<<std::endl;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// //custom levels of spells. Level 0 seems to not be supported correctly, but we can replace it it something else
|
||||
// int spellID;
|
||||
// ast>>spellID;
|
||||
// int buf;
|
||||
// while(spellID != -1)
|
||||
// {
|
||||
// ast >> buf;
|
||||
// spells[spellID]->level = buf;
|
||||
// ast>>spellID;
|
||||
// }
|
||||
//}
|
||||
//ast.close();
|
||||
spells.push_back(spells[80]); //clone Acid Breath attributes for Acid Breath damage effect
|
||||
}
|
||||
|
@ -269,6 +269,7 @@ si32 IBonusBearer::Attack() const
|
||||
{
|
||||
ret += frenzyPower * Defense(false);
|
||||
}
|
||||
amax(ret, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -281,6 +282,7 @@ si32 IBonusBearer::Defense(bool withFrenzy /*= true*/) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
amax(ret, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -159,7 +159,8 @@ namespace PrimarySkill
|
||||
BONUS_NAME(SHOTS)\
|
||||
BONUS_NAME(DEATH_STARE) /*subtype 0 - gorgon, 1 - commander*/\
|
||||
BONUS_NAME(POISON) /*val - max health penalty from poison possible*/\
|
||||
BONUS_NAME(BIND_EFFECT) /*doesn't do anything particular, works as a marker)*/
|
||||
BONUS_NAME(BIND_EFFECT) /*doesn't do anything particular, works as a marker)*/\
|
||||
BONUS_NAME(ACID_BREATH) /*additional val damage per creature after attack, additional info - chance in percent*/
|
||||
|
||||
/// Struct for handling bonuses of several types. Can be transfered to any hero
|
||||
struct DLL_EXPORT Bonus
|
||||
|
@ -3397,10 +3397,11 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, int destinatio
|
||||
continue;
|
||||
sc.dmgToDisplay += gs->curB->calculateSpellDmg(spell, caster, *it, spellLvl, usedSpellPower);
|
||||
}
|
||||
if (spellID == 79) // Death stare
|
||||
if (spellID == 79 || spellID == 81) // Death stare or Acid Breath
|
||||
{
|
||||
sc.dmgToDisplay = usedSpellPower;
|
||||
amin(sc.dmgToDisplay, (*attackedCres.begin())->count); //stack is already reduced after attack
|
||||
if (spellID == 79)
|
||||
amin(sc.dmgToDisplay, (*attackedCres.begin())->count); //stack is already reduced after attack
|
||||
}
|
||||
|
||||
//applying effects
|
||||
@ -3474,6 +3475,7 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, int destinatio
|
||||
case 73: //Disease
|
||||
case 74: //Paralyze
|
||||
case 75: //Aging
|
||||
case 80: //Acid Breath defense reduction
|
||||
{
|
||||
SetStackEffect sse;
|
||||
Bonus pseudoBonus;
|
||||
@ -3529,7 +3531,7 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, int destinatio
|
||||
}
|
||||
if (caster && caster->hasBonusOfType(Bonus::SPECIAL_BLESS_DAMAGE, spellID)) //TODO: better handling of bonus percentages
|
||||
{
|
||||
int damagePercent = caster->level * caster->valOfBonuses(Bonus::SPECIAL_BLESS_DAMAGE, 41) / tier;
|
||||
int damagePercent = caster->level * caster->valOfBonuses(Bonus::SPECIAL_BLESS_DAMAGE, spellID) / tier;
|
||||
Bonus specialBonus = CStack::featureGenerator(Bonus::CREATURE_DAMAGE, 0, damagePercent, pseudoBonus.turnsRemain);
|
||||
specialBonus.valType = Bonus::PERCENT_TO_ALL;
|
||||
specialBonus.sid = spellID;
|
||||
@ -3617,10 +3619,27 @@ void CGameHandler::handleSpellCasting( int spellID, int spellLvl, int destinatio
|
||||
sendAndApply(&si);
|
||||
}
|
||||
break;
|
||||
case 81: //Acid breath damage - new effect, separate from acid breath defense reduction
|
||||
{
|
||||
StacksInjured si;
|
||||
for(std::set<CStack*>::iterator it = attackedCres.begin(); it != attackedCres.end(); ++it) //no immunities
|
||||
{
|
||||
BattleStackAttacked bsa;
|
||||
bsa.flags |= BattleStackAttacked::EFFECT;
|
||||
bsa.effect = VLC->spellh->spells[80]->mainEffectAnim; //use acid breath
|
||||
bsa.damageAmount = usedSpellPower; //damage times the number of attackers
|
||||
bsa.stackAttacked = (*it)->ID;
|
||||
bsa.attackerID = -1;
|
||||
(*it)->prepareAttacked(bsa);
|
||||
si.stacks.push_back(bsa);
|
||||
}
|
||||
if(!si.stacks.empty())
|
||||
sendAndApply(&si);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
sendAndApply(&sc);
|
||||
|
||||
}
|
||||
|
||||
bool CGameHandler::makeCustomAction( BattleAction &ba )
|
||||
@ -4286,6 +4305,18 @@ void CGameHandler::handleAfterAttackCasting( const BattleAttack & bat )
|
||||
!attacker->attackerOwned, attacker->owner, NULL, NULL, staredCreatures, SpellCasting::AFTER_ATTACK_CASTING);
|
||||
}
|
||||
}
|
||||
int acidDamage = 0;
|
||||
BOOST_FOREACH(const Bonus *b, attacker->getBonuses(Selector::type(Bonus::ACID_BREATH)))
|
||||
{
|
||||
if (b->additionalInfo > rand()%100)
|
||||
acidDamage += b->val;
|
||||
}
|
||||
if (acidDamage)
|
||||
{
|
||||
handleSpellCasting(81, 0, gs->curB->getStack(bat.bsa[0].stackAttacked)->position,
|
||||
!attacker->attackerOwned, attacker->owner, NULL, NULL,
|
||||
acidDamage * attacker->count, SpellCasting::AFTER_ATTACK_CASTING);
|
||||
}
|
||||
}
|
||||
|
||||
bool CGameHandler::castSpell(const CGHeroInstance *h, int spellID, const int3 &pos)
|
||||
|
Loading…
Reference in New Issue
Block a user