+/*
+ * 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::Wait(int ms) {
+ text.push_back(WAIT);
+ text.push_back(ms);
+}
+
+void AttackAnimation::WaitForAnimation() {
+ text.push_back(WAIT_ANIMATION);
+}
+
+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::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 WAIT:
+ return ExecuteWait();
+ case WAIT_ANIMATION:
+ return ExecuteWaitAnimation();
+ case ATTACK_ANIMATION:
+ return ExecuteAttackAnimation();
+ case SPELL_ANIMATION:
+ return ExecuteSpellAnimation();
+ case TARGET_ANIMATION:
+ return ExecuteTargetAnimation();
+ case FULLSCREEN_ANIMATION:
+ return ExecuteFullscreenAnimation();
+ }
+ ++cursor; // skip unknown command (which should never happen anyway)
+ return false;
+}
+
+bool AttackAnimation::ExecuteWait() {
+ if (timer.Started()) {
+ if (timer.Running()) {
+ return true;
+ } else {
+ cursor += 2;
+ return false;
+ }
+ } else {
+ timer = state->GraphicsTimers().StartCountdown(text[cursor + 1].number);
+ return true;
+ }
+}
+
+
+bool AttackAnimation::ExecuteWaitAnimation() {
+ 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::ExecuteAttackAnimation() {
+ foreignAnimations.push_back(battle->HeroAt(0).AttackAnimation());
+ battle->HeroAt(0).AttackAnimation()->Start(*state);
+ ++cursor;
+ return false;
+}
+
+bool AttackAnimation::ExecuteSpellAnimation() {
+ foreignAnimations.push_back(battle->HeroAt(0).SpellAnimation());
+ battle->HeroAt(0).SpellAnimation()->Start(*state);
+ ++cursor;
+ return false;
+}
+
+bool AttackAnimation::ExecuteTargetAnimation() {
+ 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 true;
+}
+
+bool AttackAnimation::ExecuteFullscreenAnimation() {
+ 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 true;
+}
+
+
+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);
+ }
+ }
+}
+
+}