#include "../graphics/Sprite.h"
#include <algorithm>
+#include <cassert>
#include <stdexcept>
using app::Application;
}
void BattleState::LoadSpellMenu(vector<Hero>::size_type index) {
+ assert(index >= 0 && index < 4);
spellMenus[index].Clear();
spellMenus[index].Reserve(HeroAt(index).Spells().size());
for (vector<const Spell *>::const_iterator i(HeroAt(index).Spells().begin()), end(HeroAt(index).Spells().end()); i != end; ++i) {
}
void BattleState::LoadIkariMenu(vector<Hero>::size_type index) {
+ assert(index >= 0 && index < 4);
ikariMenus[index].Clear();
ikariMenus[index].Reserve(6);
}
void BattleState::ResumeState(Application &ctrl, SDL_Surface *screen) {
- // TODO: check for victory or defeat
if (ranAway) {
ctrl.PopState(); // quit the battle scene
return;
void BattleState::CalculateAttackOrder() {
attackOrder.reserve(monsters.size() + NumHeroes());
- for (int i(0); i < numHeroes; ++i) {
+ for (int i(0); i < NumHeroes(); ++i) {
attackOrder.push_back(Order(i, false));
}
for (vector<Monster>::size_type i(0), end(monsters.size()); i < end; ++i) {
}
}
+bool BattleState::AttacksFinished() const {
+ return attackCursor >= int(attackOrder.size())
+ || Victory() || Defeat();
+}
+
void BattleState::CalculateDamage() {
AttackChoice &ac(CurrentAttack().isMonster ? monsterAttacks[CurrentAttack().index] : AttackChoiceAt(CurrentAttack().index));
if (ac.GetType() == AttackChoice::DEFEND) return;
TargetSelection &ts(ac.Selection());
if (ts.TargetsEnemies()) {
for (int i(0); i < MaxMonsters(); ++i) {
+ Monster &monster(MonsterAt(i));
if (ts.IsBad(i)) {
- MonsterAt(i).SubtractHealth(ts.GetAmount(i));
+ monster.SubtractHealth(ts.GetAmount(i));
+ if (monster.Health() == 0) {
+ expReward += monster.ExpReward();
+ goldReward += monster.GoldReward();
+ }
}
}
} else {
}
}
+AttackChoice &BattleState::CurrentAttackAttackChoice() {
+ if (CurrentAttack().isMonster) {
+ return monsterAttacks[CurrentAttack().index];
+ } else {
+ return AttackChoiceAt(CurrentAttack().index);
+ }
+}
+
void BattleState::ClearAllAttacks() {
attackCursor = -1;
activeHero = -1;
}
void BattleState::Render(SDL_Surface *screen) {
+ assert(screen);
Vector<int> offset(CalculateScreenOffset(screen));
RenderBackground(screen, offset);
RenderMonsters(screen, offset);
}
void BattleState::RenderBackground(SDL_Surface *screen, const Vector<int> &offset) {
+ assert(screen);
// black for now
SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));
SDL_Rect destRect;
}
void BattleState::RenderMonsters(SDL_Surface *screen, const Vector<int> &offset) {
+ assert(screen);
for (vector<Monster>::size_type i(0), end(monsters.size()); i < end; ++i) {
if (MonsterPositionOccupied(i)) {
- monsters[i].Sprite()->DrawCenter(screen, monsterPositions[i] + offset);
+ // TODO: better solution for running animations
+ if (monsters[i].AttackAnimation() && monsters[i].AttackAnimation()->Running()) {
+ monsters[i].AttackAnimation()->DrawCenter(screen, monsterPositions[i] + offset);
+ } else if (monsters[i].SpellAnimation() && monsters[i].SpellAnimation()->Running()) {
+ monsters[i].SpellAnimation()->DrawCenter(screen, monsterPositions[i] + offset);
+ } else {
+ monsters[i].Sprite()->DrawCenter(screen, monsterPositions[i] + offset);
+ }
}
}
}
void BattleState::RenderHeroes(SDL_Surface *screen, const Vector<int> &offset) {
+ assert(screen);
for (int i(0); i < numHeroes; ++i) {
if (heroes[i].AttackAnimation() && heroes[i].AttackAnimation()->Running()) {
heroes[i].AttackAnimation()->DrawCenter(screen, heroesPositions[i] + offset);
}
void BattleState::RenderHeroTags(SDL_Surface *screen, const Vector<int> &offset) {
+ assert(screen);
int tagHeight(attackTypeMenu.Height());
int tagWidth(attackTypeMenu.Width() * 2 + attackTypeMenu.Width() / 2);
}
void BattleState::RenderSmallHeroTags(SDL_Surface *screen, const Vector<int> &offset) {
+ assert(screen);
int tagHeight(res->normalFont->CharHeight() * 4 + res->smallHeroTagFrame->BorderHeight() * 2);
int tagWidth(res->normalFont->CharWidth() * 6 + res->smallHeroTagFrame->BorderWidth() * 2);