1
0
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:
DjWarmonger 2011-05-13 09:02:16 +00:00
parent 09a51acfc2
commit 515ab7e7c1
8 changed files with 90 additions and 42 deletions

View File

@ -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
}

View File

@ -239,11 +239,14 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
int printed=0; //how many effect pics have been printed
std::vector<si32> spells = battleStack->activeSpells();
BOOST_FOREACH(si32 effect, spells)
{
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))

View File

@ -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

View File

@ -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;
}
}

View File

@ -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
}

View File

@ -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;
}

View File

@ -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

View File

@ -3397,9 +3397,10 @@ 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;
if (spellID == 79)
amin(sc.dmgToDisplay, (*attackedCres.begin())->count); //stack is already reduced after attack
}
@ -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)