#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::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;
for (int i(0); i < MaxMonsters(); ++i) {
if (ts.IsBad(i)) {
MonsterAt(i).SubtractHealth(ts.GetAmount(i));
+ // TODO: collect reward if dead
}
}
} else {
}
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)) {
// TODO: better solution for running animations
}
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);
#include "../graphics/Animation.h"
#include "../graphics/Menu.h"
+#include <cassert>
#include <vector>
#include <SDL.h>
, numHeroes(0)
, activeHero(-1)
, attackCursor(-1)
- , ranAway(false) { }
+ , ranAway(false) { assert(background && res); }
public:
void AddMonster(const Monster &);
Hero &ActiveHero() { return heroes[activeHero]; }
const Hero &ActiveHero() const { return heroes[activeHero]; }
- Hero &HeroAt(int index) { return heroes[index]; }
- const Hero &HeroAt(int index) const { return heroes[index]; }
- Monster &MonsterAt(int index) { return monsters[index]; }
- const Monster &MonsterAt(int index) const { return monsters[index]; }
+ Hero &HeroAt(int index) { assert(index >= 0 && index < NumHeroes()); return heroes[index]; }
+ const Hero &HeroAt(int index) const { assert(index >= 0 && index < NumHeroes()); return heroes[index]; }
+ Monster &MonsterAt(int index) { assert(index >= 0 && index < NumHeroes()); return monsters[index]; }
+ const Monster &MonsterAt(int index) const { assert(index >= 0 && index < NumHeroes()); return monsters[index]; }
- const HeroTag &HeroTagAt(int index) const { return heroTags[index]; }
- const geometry::Point<int> &HeroTagPositionAt(int index) const { return heroTagPositions[index]; }
+ const HeroTag &HeroTagAt(int index) const { assert(index >= 0 && index < NumHeroes()); return heroTags[index]; }
+ const geometry::Point<int> &HeroTagPositionAt(int index) const { assert(index >= 0 && index < NumHeroes()); return heroTagPositions[index]; }
- bool HasChosenAttackType() const { return attackChoices[activeHero].GetType() != AttackChoice::UNDECIDED; }
- AttackChoice &ActiveHeroAttackChoice() { return attackChoices[activeHero]; }
- const AttackChoice &ActiveHeroAttackChoice() const { return attackChoices[activeHero]; }
- AttackChoice &AttackChoiceAt(int index) { return attackChoices[index]; }
- const AttackChoice &AttackChoiceAt(int index) const { return attackChoices[index]; }
+ bool HasChosenAttackType() const { return ActiveHeroAttackChoice().GetType() != AttackChoice::UNDECIDED; }
+ AttackChoice &ActiveHeroAttackChoice() { return AttackChoiceAt(activeHero); }
+ const AttackChoice &ActiveHeroAttackChoice() const { return AttackChoiceAt(activeHero); }
+ AttackChoice &AttackChoiceAt(int index) { assert(index >= 0 && index < NumHeroes()); return attackChoices[index]; }
+ const AttackChoice &AttackChoiceAt(int index) const { assert(index >= 0 && index < NumHeroes()); return attackChoices[index]; }
bool AttackSelectionDone() const { return activeHero >= numHeroes; }
int NumHeroes() const { return numHeroes; }
void CalculateAttackOrder();
void NextAttack();
- bool AttacksFinished() const { return attackCursor >= int(attackOrder.size()); }
+ bool AttacksFinished() const;
void CalculateDamage();
void ApplyDamage();
- const Order &CurrentAttack() const { return attackOrder[attackCursor]; };
+ const Order &CurrentAttack() const { assert(attackCursor >= 0 && attackCursor < int(attackOrder.size())); return attackOrder[attackCursor]; };
void ClearAllAttacks();
bool Victory() const;
}
void PerformAttacks::ExitState(Application &c, SDL_Surface *screen) {
+ battle->ClearAllAttacks();
ctrl = 0;
}
battle->ApplyDamage();
battle->NextAttack();
if (battle->AttacksFinished()) {
- battle->ClearAllAttacks();
ctrl->PopState();
return;
}
monster.SetHealth(8);
monster.SetStats(Stats(14, 6, 6, 6, 6, 6, 6));
monster.SetReward(3, 5);
- ComplexAnimation monsterAttackAnimation(&monsterSprite, 120);
+ ComplexAnimation monsterAttackAnimation(&monsterSprite, 4 * framerate);
monsterAttackAnimation.AddFrame(0, 1, Vector<int>(16, 0));
monsterAttackAnimation.AddFrame(0, 0, Vector<int>(16, 0));
monsterAttackAnimation.AddFrame(0, 1, Vector<int>(16, 0));