# Add inputs and outputs from these tool invocations to the build variables
CPP_SRCS += \
-../src/battle/AttackAnimation.cpp \
../src/battle/AttackChoice.cpp \
../src/battle/AttackTypeMenu.cpp \
../src/battle/BattleState.cpp \
../src/battle/TargetSelection.cpp
OBJS += \
-./src/battle/AttackAnimation.o \
./src/battle/AttackChoice.o \
./src/battle/AttackTypeMenu.o \
./src/battle/BattleState.o \
./src/battle/TargetSelection.o
CPP_DEPS += \
-./src/battle/AttackAnimation.d \
./src/battle/AttackChoice.d \
./src/battle/AttackTypeMenu.d \
./src/battle/BattleState.d \
# Add inputs and outputs from these tool invocations to the build variables
CPP_SRCS += \
-../src/battle/AttackAnimation.cpp \
../src/battle/AttackChoice.cpp \
../src/battle/AttackTypeMenu.cpp \
../src/battle/BattleState.cpp \
../src/battle/TargetSelection.cpp
OBJS += \
-./src/battle/AttackAnimation.o \
./src/battle/AttackChoice.o \
./src/battle/AttackTypeMenu.o \
./src/battle/BattleState.o \
./src/battle/TargetSelection.o
CPP_DEPS += \
-./src/battle/AttackAnimation.d \
./src/battle/AttackChoice.d \
./src/battle/AttackTypeMenu.d \
./src/battle/BattleState.d \
+++ /dev/null
-/*
- * AttackAnimation.cpp
- *
- * Created on: Aug 13, 2012
- * Author: holy
- */
-
-#include "AttackAnimation.h"
-
-#include "BattleState.h"
-#include "../app/State.h"
-#include "../graphics/Animation.h"
-
-using geometry::Point;
-using graphics::Animation;
-using std::vector;
-
-namespace battle {
-
-AttackAnimation::~AttackAnimation() {
- for (vector<AnimationMemo>::const_iterator i(animations.begin()), end(animations.end()); i != end; ++i) {
- i->animation->Stop();
- }
- for (vector<Animation *>::const_iterator i(foreignAnimations.begin()), end(foreignAnimations.end()); i != end; ++i) {
- (*i)->Stop();
- }
-}
-
-
-void AttackAnimation::StartTimer(int ms) {
- text.push_back(START_TIMER);
- text.push_back(ms);
-}
-
-void AttackAnimation::PlayAttackAnimation() {
- text.push_back(ATTACK_ANIMATION);
-}
-
-void AttackAnimation::PlaySpellAnimation() {
- text.push_back(SPELL_ANIMATION);
-}
-
-void AttackAnimation::PlayTargetAnimation(graphics::Animation *a) {
- text.push_back(TARGET_ANIMATION);
- text.push_back(a);
-}
-
-void AttackAnimation::PlayFullscreenAnimation(graphics::Animation *a) {
- text.push_back(FULLSCREEN_ANIMATION);
- text.push_back(a);
-}
-
-void AttackAnimation::WaitForTimer() {
- text.push_back(WAIT_TIMER);
-}
-
-void AttackAnimation::WaitForAnimations() {
- text.push_back(WAIT_ANIMATIONS);
-}
-
-
-void AttackAnimation::Start(BattleState *b, app::State *s) {
- battle = b;
- state = s;
- cursor = 0;
- Update();
-}
-
-void AttackAnimation::Update() {
- while (!Finished()) {
- if (ExecuteCommand()) break;
- }
-}
-
-bool AttackAnimation::ExecuteCommand() {
- switch (text[cursor].command) {
- case NOOP:
- break;
- case START_TIMER:
- return ExecuteStartTimer();
- case ATTACK_ANIMATION:
- return ExecuteAttackAnimation();
- case SPELL_ANIMATION:
- return ExecuteSpellAnimation();
- case TARGET_ANIMATION:
- return ExecuteTargetAnimation();
- case FULLSCREEN_ANIMATION:
- return ExecuteFullscreenAnimation();
- case WAIT_TIMER:
- return ExecuteWaitTimer();
- case WAIT_ANIMATIONS:
- return ExecuteWaitAnimations();
- }
- ++cursor; // skip unknown command (which should never happen anyway)
- return false;
-}
-
-
-bool AttackAnimation::ExecuteStartTimer() {
- timer = state->GraphicsTimers().StartCountdown(text[cursor + 1].number);
- cursor += 2;
- return false;
-}
-
-bool AttackAnimation::ExecuteAttackAnimation() {
- // TODO: get real hero/monster
- foreignAnimations.push_back(battle->HeroAt(0).AttackAnimation());
- battle->HeroAt(0).AttackAnimation()->Start(*state);
- ++cursor;
- return false;
-}
-
-bool AttackAnimation::ExecuteSpellAnimation() {
- // TODO: get real hero/monster
- foreignAnimations.push_back(battle->HeroAt(0).SpellAnimation());
- battle->HeroAt(0).SpellAnimation()->Start(*state);
- ++cursor;
- return false;
-}
-
-bool AttackAnimation::ExecuteTargetAnimation() {
- // TODO: get real positions
- AnimationMemo am;
- am.animation = (Animation *) text[cursor + 1].ptr;
- am.animation->Start(*state);
- am.position = Point<int>(100, 100);
- animations.push_back(am);
- cursor += 2;
- return false;
-}
-
-bool AttackAnimation::ExecuteFullscreenAnimation() {
- AnimationMemo am;
- am.animation = (Animation *) text[cursor + 1].ptr;
- am.animation->Start(*state);
- am.position = Point<int>(0, 0);
- animations.push_back(am);
- cursor += 2;
- return false;
-}
-
-bool AttackAnimation::ExecuteWaitTimer() {
- if (timer.Running()) {
- return true;
- } else {
- ++cursor;
- return false;
- }
-}
-
-bool AttackAnimation::ExecuteWaitAnimations() {
- for (vector<AnimationMemo>::const_iterator i(animations.begin()), end(animations.end()); i != end; ++i) {
- if (i->animation->Running()) return true;
- }
- for (vector<Animation *>::const_iterator i(foreignAnimations.begin()), end(foreignAnimations.end()); i != end; ++i) {
- if ((*i)->Running()) return true;
- }
- ++cursor;
- return false;
-}
-
-
-bool AttackAnimation::Running() const {
- return cursor >= 0 && !Finished();
-}
-
-bool AttackAnimation::Finished() const {
- return cursor >= int(text.size());
-}
-
-void AttackAnimation::Render(SDL_Surface *screen, const geometry::Vector<int> &offset) const {
- for (vector<AnimationMemo>::const_iterator i(animations.begin()), end(animations.end()); i != end; ++i) {
- if (i->animation->Running()) {
- i->animation->Draw(screen, i->position + offset);
- }
- }
-}
-
-}
+++ /dev/null
-/*
- * AttackAnimation.h
- *
- * Created on: Aug 13, 2012
- * Author: holy
- */
-
-#ifndef BATTLE_ATTACKANIMATION_H_
-#define BATTLE_ATTACKANIMATION_H_
-
-#include "../app/Timer.h"
-#include "../geometry/Point.h"
-#include "../geometry/Vector.h"
-
-#include <vector>
-#include <SDL.h>
-
-namespace app { class State; }
-namespace graphics { class Animation; }
-
-namespace battle {
-
-class BattleState;
-
-class AttackAnimation {
-
-public:
- AttackAnimation() : battle(0), state(0), cursor(0) { }
- ~AttackAnimation();
-
-public:
- void StartTimer(int ms);
- void PlayAttackAnimation();
- void PlaySpellAnimation();
- void PlayTargetAnimation(graphics::Animation *);
- void PlayFullscreenAnimation(graphics::Animation *);
- void WaitForTimer();
- void WaitForAnimations();
-
-public:
- void Start(BattleState *, app::State *);
- void Update();
- bool Running() const;
- bool Finished() const;
- void Render(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
-
-private:
- bool ExecuteCommand();
- bool ExecuteStartTimer();
- bool ExecuteAttackAnimation();
- bool ExecuteSpellAnimation();
- bool ExecuteTargetAnimation();
- bool ExecuteFullscreenAnimation();
- bool ExecuteWaitTimer();
- bool ExecuteWaitAnimations();
-
-private:
- enum Command {
- NOOP,
- START_TIMER,
- ATTACK_ANIMATION,
- SPELL_ANIMATION,
- TARGET_ANIMATION,
- FULLSCREEN_ANIMATION,
- WAIT_TIMER,
- WAIT_ANIMATIONS,
- };
- union Code {
- Code(Command c) : command(c) { }
- Code(int n) : number(n) { }
- Code(void *p) : ptr(p) { }
- Command command;
- int number;
- void *ptr;
- };
- BattleState *battle;
- app::State *state;
- std::vector<Code> text;
- app::Timer<Uint32> timer;
- struct AnimationMemo {
- graphics::Animation *animation;
- geometry::Point<int> position;
- };
- std::vector<AnimationMemo> animations;
- std::vector<graphics::Animation *> foreignAnimations;
- int cursor;
-
-};
-
-}
-
-#endif /* BATTLE_ATTACKANIMATION_H_ */
namespace battle {
-class AttackAnimation;
-
class Hero {
public:
bool HasRing() const { return ring; }
bool HasJewel() const { return jewel; }
- class AttackAnimation *MeleeAnimation() { return meleeAnimation; }
- const class AttackAnimation *MeleeAnimation() const { return meleeAnimation; }
+ graphics::Animation *MeleeAnimation() { return meleeAnimation; }
+ const graphics::Animation *MeleeAnimation() const { return meleeAnimation; }
graphics::Animation *AttackAnimation() { return attackAnimation; }
const graphics::Animation *AttackAnimation() const { return attackAnimation; }
graphics::Animation *SpellAnimation() { return spellAnimation; }
void AddSpell(const common::Spell *s) { spells.push_back(s); }
- void SetMeleeAnimation(class AttackAnimation *a) { meleeAnimation = a; }
+ void SetMeleeAnimation(graphics::Animation *a) { meleeAnimation = a; }
void SetAttackAnimation(graphics::Animation *a) { attackAnimation = a; }
void SetSpellAnimation(graphics::Animation *a) { spellAnimation = a; }
const common::Item *ring;
const common::Item *jewel;
- class AttackAnimation *meleeAnimation;
+ graphics::Animation *meleeAnimation;
graphics::Animation *attackAnimation;
graphics::Animation *spellAnimation;
#include "PerformAttacks.h"
-#include "../AttackAnimation.h"
#include "../BattleState.h"
#include "../Hero.h"
#include "../Monster.h"
void PerformAttacks::HandleEvents(const Input &input) {
- if (attackAnimation) attackAnimation->Update();
- CheckNumberAnimation();
+ CheckAnimations();
if (HasAnimationsRunning()) return;
ResetAnimation();
AdvanceCursor();
case AttackChoice::SWORD:
if (hero.HasWeapon()) {
titleBarText = hero.Weapon()->Name();
- moveAnimation = hero.AttackAnimation();
} else {
titleBarText = "Melee attack!";
- if (hero.MeleeAnimation()) {
- moveAnimation = 0;
- attackAnimation = hero.MeleeAnimation();
- } else {
- moveAnimation = hero.AttackAnimation();
- attackAnimation = 0;
- }
}
+ moveAnimation = hero.AttackAnimation();
+ targetAnimation = hero.MeleeAnimation();
+
numberAnimation.push_back(NumberAnimation(15, battle->Res().numberAnimationPrototype, battle->Res().bigNumberSprite));
if (ac.Selection().TargetsEnemies()) {
numberPosition.push_back(
if (titleBarText) titleBarTimer = GraphicsTimers().StartCountdown(1500);
if (moveAnimation) moveAnimation->Start(*this);
- if (attackAnimation) attackAnimation->Start(battle, this);
+ if (targetAnimation) {
+ targetAnimationTimer = GraphicsTimers().StartCountdown(150);
+ } else {
+ targetAnimationTimer.Clear();
+ }
}
-void PerformAttacks::CheckNumberAnimation() {
- if (moveAnimation && moveAnimation->Running()) return;
- if (attackAnimation && !attackAnimation->Finished()) return;
- if (moveAnimation || attackAnimation) {
+void PerformAttacks::CheckAnimations() {
+ if (targetAnimation && targetAnimationTimer.JustHit()) {
+ targetAnimation->Start(*this);
+ }
+ if (moveAnimation && !moveAnimation->Finished()) return;
+ if (targetAnimation && !targetAnimation->Finished()) return;
+ if (moveAnimation || targetAnimation) {
moveAnimation = 0;
- attackAnimation = 0;
+ targetAnimation = 0;
for (vector<NumberAnimation>::iterator i(numberAnimation.begin()), end(numberAnimation.end()); i != end; ++i) {
i->Start(*this);
}
bool PerformAttacks::HasAnimationsRunning() const {
if (titleBarTimer.Running()) return true;
if (moveAnimation && moveAnimation->Running()) return true;
+ if (targetAnimation && targetAnimation->Running()) return true;
for (vector<NumberAnimation>::const_iterator i(numberAnimation.begin()), end(numberAnimation.end()); i != end; ++i) {
if (i->Running()) return true;
}
}
void PerformAttacks::ResetAnimation() {
- if (moveAnimation) moveAnimation->Stop();
- if (attackAnimation) attackAnimation = 0;
+ if (moveAnimation) {
+ moveAnimation->Stop();
+ moveAnimation = 0;
+ }
+ if (targetAnimation) {
+ targetAnimation->Stop();
+ targetAnimation = 0;
+ }
titleBarTimer.Clear();
numberAnimation.clear();
numberPosition.clear();
battle->RenderSmallHeroTags(screen, offset);
RenderTitleBar(screen, offset);
RenderNumbers(screen, offset);
- if (attackAnimation) attackAnimation->Render(screen, offset);
+ RenderTargetAnimation(screen, offset);
}
-void PerformAttacks::RenderTitleBar(SDL_Surface *screen, const Vector<int> &offset) {
+void PerformAttacks::RenderTitleBar(SDL_Surface *screen, const Vector<int> &offset) const {
if (!titleBarText || !titleBarTimer.Running()) return;
int height(battle->Res().titleFrame->BorderHeight() * 2 + battle->Res().titleFont->CharHeight());
battle->Res().titleFont->DrawString(titleBarText, screen, textPosition + offset);
}
-void PerformAttacks::RenderNumbers(SDL_Surface *screen, const Vector<int> &offset) {
+void PerformAttacks::RenderNumbers(SDL_Surface *screen, const Vector<int> &offset) const {
for (vector<NumberAnimation>::size_type i(0), end(numberAnimation.size()); i < end; ++i) {
if (numberAnimation[i].Running()) {
Vector<int> align(numberAnimation[i].Width() / -2, numberAnimation[i].Height() * -3 / 4);
}
}
+void PerformAttacks::RenderTargetAnimation(SDL_Surface *screen, const geometry::Vector<int> &offset) const {
+ if (!targetAnimation || !targetAnimation->Running()) return;
+ if (order[cursor].isMonster) return; // no monsters for now
+ const TargetSelection &ts(battle->AttackChoiceAt(order[cursor].index).Selection());
+ const vector<Point<int> > &positions(ts.TargetsHeroes() ? battle->HeroesPositions() : battle->MonsterPositions());
+ for (vector<Point<int> >::size_type i(0), end(positions.size()); i < end; ++i) {
+ if (ts.IsSelected(i)) {
+ targetAnimation->DrawCenter(screen, positions[i] + offset);
+ }
+ }
+}
+
}
namespace battle {
-class AttackAnimation;
-
class PerformAttacks
: public app::State {
public:
explicit PerformAttacks(BattleState *battle)
- : ctrl(0), battle(battle), moveAnimation(0), attackAnimation(0), titleBarText(0), cursor(-1) { }
+ : ctrl(0), battle(battle), moveAnimation(0), targetAnimation(0), titleBarText(0), cursor(-1) { }
public:
virtual void EnterState(app::Application &ctrl, SDL_Surface *screen);
virtual void Render(SDL_Surface *);
private:
- void CheckNumberAnimation();
+ void CheckAnimations();
bool HasAnimationsRunning() const;
void ResetAnimation();
void AdvanceCursor();
bool Finished() const { return cursor >= int(order.size()); }
private:
- void RenderTitleBar(SDL_Surface *screen, const geometry::Vector<int> &offset);
- void RenderNumbers(SDL_Surface *screen, const geometry::Vector<int> &offset);
+ void RenderTitleBar(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
+ void RenderNumbers(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
+ void RenderTargetAnimation(SDL_Surface *screen, const geometry::Vector<int> &offset) const;
private:
app::Application *ctrl;
BattleState *battle;
graphics::Animation *moveAnimation;
- AttackAnimation *attackAnimation;
+ graphics::Animation *targetAnimation;
const char *titleBarText;
app::Timer<Uint32> titleBarTimer;
+ app::Timer<Uint32> targetAnimationTimer;
std::vector<BattleState::Order> order;
std::vector<NumberAnimation> numberAnimation;
std::vector<geometry::Point<int> > numberPosition;
void Stop() {
timer = app::Timer<Uint32>();
}
+ bool Started() const {
+ return timer.Started();
+ }
bool Running() const {
return timer.Running() && (repeat || timer.Iteration() < NumFrames());
}
+ bool Finished() const {
+ return Started() && !Running();
+ }
bool JustFinished() const {
return timer.JustHit() && timer.Iteration() == NumFrames();
}
#include "app/Application.h"
#include "app/Input.h"
-#include "battle/AttackAnimation.h"
#include "battle/BattleState.h"
#include "battle/Hero.h"
#include "battle/Monster.h"
using app::Application;
using app::Input;
-using battle::AttackAnimation;
using battle::BattleState;
using battle::Hero;
using battle::Monster;
SDL_Surface *maximMeleeImg(IMG_Load("test-data/melee-maxim.png"));
Sprite maximMeleeSprite(maximMeleeImg, 96, 96);
SimpleAnimation maximMeleeAnimation(&maximMeleeSprite, 30, 4);
- AttackAnimation maximMeleeScript;
- maximMeleeScript.PlayAttackAnimation();
- maximMeleeScript.StartTimer(150);
- maximMeleeScript.WaitForTimer();
- maximMeleeScript.PlayTargetAnimation(&maximMeleeAnimation);
- maximMeleeScript.WaitForAnimations();
- maxim.SetMeleeAnimation(&maximMeleeScript);
+ maxim.SetMeleeAnimation(&maximMeleeAnimation);
SDL_Surface *selanImg(IMG_Load("test-data/selan.png"));
Sprite selanSprite(selanImg, 64, 64);