From a01c2f05b5a6493d7fe097eb15e5337a095992ae Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Sun, 19 Aug 2012 19:50:18 +0200 Subject: [PATCH] moved attack order to battle state --- src/app/Application.cpp | 2 +- src/battle/BattleState.cpp | 67 ++++++++++++++++++++++------ src/battle/BattleState.h | 13 +++++- src/battle/TargetSelection.cpp | 2 +- src/battle/TargetSelection.h | 30 ++++++++++--- src/battle/states/PerformAttacks.cpp | 51 +++++++++++---------- src/battle/states/PerformAttacks.h | 3 -- 7 files changed, 116 insertions(+), 52 deletions(-) diff --git a/src/app/Application.cpp b/src/app/Application.cpp index 6e46203..ac95ed0 100644 --- a/src/app/Application.cpp +++ b/src/app/Application.cpp @@ -159,7 +159,7 @@ void Application::HandleEvents() { break; } } - CurrentState()->HandleEvents(input); + if (CurrentState()) CurrentState()->HandleEvents(input); } void Application::UpdateWorld(Uint32 deltaT) { diff --git a/src/battle/BattleState.cpp b/src/battle/BattleState.cpp index 1a4f726..dcad8b2 100644 --- a/src/battle/BattleState.cpp +++ b/src/battle/BattleState.cpp @@ -225,14 +225,6 @@ void BattleState::PauseState(Application &ctrl, SDL_Surface *screen) { } -void BattleState::ClearAllAttacks() { - activeHero = -1; - for (int i(0); i < numHeroes; ++i) { - attackChoices[i] = AttackChoice(this); - } -} - - class OrderCompare { public: OrderCompare(BattleState *battle) : battle(battle) { } @@ -245,15 +237,64 @@ class OrderCompare { BattleState *battle; }; -void BattleState::WriteOrder(std::vector &order) { - order.reserve(monsters.size() + NumHeroes()); +void BattleState::CalculateAttackOrder() { + attackOrder.reserve(monsters.size() + NumHeroes()); for (int i(0); i < numHeroes; ++i) { - order.push_back(Order(i, false)); + attackOrder.push_back(Order(i, false)); } for (vector::size_type i(0), end(monsters.size()); i < end; ++i) { - order.push_back(Order(i, true)); + attackOrder.push_back(Order(i, true)); + } + std::sort(attackOrder.begin(), attackOrder.end(), OrderCompare(this)); + + monsterAttacks.resize(monsters.size(), AttackChoice(this)); +} + +void BattleState::NextAttack() { + ++attackCursor; + while (attackCursor < int(attackOrder.size())) { + if (attackOrder[attackCursor].isMonster) { + if (MonsterAt(attackOrder[attackCursor].index).Health() > 0) break; + } else { + if (HeroAt(attackOrder[attackCursor].index).Health() > 0) break; + } + ++attackCursor; + } +} + +void BattleState::CalculateDamage() { + if (CurrentAttack().isMonster) { + // TODO: run monster's attack script + monsterAttacks[CurrentAttack().index].SetType(AttackChoice::SWORD); + monsterAttacks[CurrentAttack().index].Selection().SelectSingle(); + monsterAttacks[CurrentAttack().index].Selection().SelectHeroes(); + monsterAttacks[CurrentAttack().index].Selection().SetBad(0, 15); + } else { + TargetSelection &ts(AttackChoiceAt(CurrentAttack().index).Selection()); + if (ts.TargetsEnemies()) { + for (int i(0); i < NumHeroes(); ++i) { + if (ts.IsSelected(i)) { + ts.SetBad(i, 15); + } + } + } else { + for (int i(0); i < MaxMonsters(); ++i) { + if (ts.IsSelected(i) && MonsterAt(i).Health() > 0) { + ts.SetBad(i, 15); + } + } + } + } +} + +void BattleState::ClearAllAttacks() { + attackCursor = -1; + activeHero = -1; + for (int i(0); i < numHeroes; ++i) { + attackChoices[i] = AttackChoice(this); } - std::sort(order.begin(), order.end(), OrderCompare(this)); + attackOrder.clear(); + monsterAttacks.clear(); } diff --git a/src/battle/BattleState.h b/src/battle/BattleState.h index 3acc0b7..5898a2d 100644 --- a/src/battle/BattleState.h +++ b/src/battle/BattleState.h @@ -55,6 +55,7 @@ public: , moveMenu(res->moveIcons) , numHeroes(0) , activeHero(-1) + , attackCursor(-1) , ranAway(false) { } public: @@ -103,6 +104,7 @@ public: 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 AttackSelectionDone() const { return activeHero >= numHeroes; } @@ -116,7 +118,6 @@ public: bool HeroPositionOccupied(int index) const { return index >= 0 && index < numHeroes; } void SetRunaway() { ranAway = true; } - void ClearAllAttacks(); struct Order { Order(int index, bool isMonster) @@ -125,7 +126,12 @@ public: bool isMonster; }; - void WriteOrder(std::vector &); + void CalculateAttackOrder(); + void NextAttack(); + bool AttacksFinished() const { return attackCursor >= int(attackOrder.size()); } + void CalculateDamage(); + const Order &CurrentAttack() const { return attackOrder[attackCursor]; }; + void ClearAllAttacks(); public: geometry::Vector CalculateScreenOffset(SDL_Surface *screen) const { @@ -158,6 +164,8 @@ private: std::vector > monsterPositions; std::vector > heroesPositions; std::vector monsters; + std::vector monsterAttacks; + std::vector attackOrder; Hero heroes[4]; graphics::Menu spellMenus[4]; graphics::Menu itemMenu; @@ -169,6 +177,7 @@ private: AttackChoice attackChoices[4]; int numHeroes; int activeHero; + int attackCursor; bool ranAway; }; diff --git a/src/battle/TargetSelection.cpp b/src/battle/TargetSelection.cpp index c1aedf3..2608e39 100644 --- a/src/battle/TargetSelection.cpp +++ b/src/battle/TargetSelection.cpp @@ -13,7 +13,7 @@ namespace battle { TargetSelection::TargetSelection(BattleState *battle, bool multiple, bool atEnemy) : battle(battle) -, selected(battle ? ((int)battle->MonsterPositions().size() > battle->NumHeroes() ? (int)battle->MonsterPositions().size() : battle->NumHeroes()) : 0, false) +, selected(battle ? ((int)battle->MonsterPositions().size() > battle->NumHeroes() ? (int)battle->MonsterPositions().size() : battle->NumHeroes()) : 0, State()) , selection(-1) , cursor(0) , multiple(multiple) diff --git a/src/battle/TargetSelection.h b/src/battle/TargetSelection.h index 664e960..64500b0 100644 --- a/src/battle/TargetSelection.h +++ b/src/battle/TargetSelection.h @@ -22,7 +22,7 @@ public: public: bool TargetsEnemies() const { return enemy; } bool TargetsHeroes() const { return !TargetsEnemies(); } - bool IsSelected(int index) const { return index >= 0 && index < int(selected.size()) && selected[index]; } + bool IsSelected(int index) const { return index >= 0 && index < int(selected.size()) && selected[index].type != State::IGNORE; } bool HasSelected() const { return selection >= 0; } int SingleSelection() const { return selection; } @@ -33,12 +33,12 @@ public: void SelectEnemies(); void SelectHeroes(); - void Select(int index) { selected[index] = true; selection = index; } - void Unselect(int index) { selected[index] = false; } - void UnselectAll() { selected.assign(selected.size(), false); selection = -1; } + void Select(int index) { selected[index].type = State::SELECTED; selection = index; } + void Unselect(int index) { selected[index].type = State::IGNORE; } + void UnselectAll() { selected.assign(selected.size(), State()); selection = -1; } void Reset(); - void Resize(int num) { selected.resize(num, false); } + void Resize(int num) { selected.resize(num); } void MoveUp(); void MoveRight(); @@ -49,12 +49,30 @@ public: int Current() const { return cursor; } bool CurrentIsSelected() { return IsSelected(cursor); } + void SetMiss(int index) { selected[index].type = State::MISS; } + void SetFull(int index) { selected[index].type = State::FULL; } + void SetGood(int index, int amount) { selected[index].type = State::GOOD; selected[index].number = amount; } + void SetBad(int index, int amount) { selected[index].type = State::BAD; selected[index].number = amount; } + int GetAmount(int index) const { return selected[index].number; } + private: void FindNextEnemy(); private: + struct State { + enum Type { + IGNORE, + SELECTED, + MISS, + FULL, + GOOD, + BAD, + } type; + int number; + explicit State(Type type = IGNORE, int num = 0) : type(type), number(num) { } + }; BattleState *battle; - std::vector selected; + std::vector selected; int selection; int cursor; bool multiple; diff --git a/src/battle/states/PerformAttacks.cpp b/src/battle/states/PerformAttacks.cpp index 2a8f3a5..6baa1da 100644 --- a/src/battle/states/PerformAttacks.cpp +++ b/src/battle/states/PerformAttacks.cpp @@ -33,7 +33,7 @@ namespace battle { void PerformAttacks::EnterState(Application &c, SDL_Surface *screen) { ctrl = &c; - battle->WriteOrder(order); + battle->CalculateAttackOrder(); numberAnimation.reserve(battle->MaxMonsters() > battle->NumHeroes() + 1 ? battle->MaxMonsters() : battle->NumHeroes() + 1); numberPosition.reserve(numberAnimation.size()); } @@ -60,20 +60,22 @@ void PerformAttacks::HandleEvents(const Input &input) { CheckAnimations(); if (HasAnimationsRunning()) return; ResetAnimation(); - AdvanceCursor(); - if (Finished()) { + battle->NextAttack(); + if (battle->AttacksFinished()) { battle->ClearAllAttacks(); ctrl->PopState(); return; } - if (order[cursor].isMonster) { - const Monster &monster(battle->MonsterAt(order[cursor].index)); + battle->CalculateDamage(); + + if (battle->CurrentAttack().isMonster) { + const Monster &monster(battle->MonsterAt(battle->CurrentAttack().index)); titleBarText = monster.Name(); moveAnimation = 0; } else { - Hero &hero(battle->HeroAt(order[cursor].index)); - const AttackChoice &ac(battle->AttackChoiceAt(order[cursor].index)); + Hero &hero(battle->HeroAt(battle->CurrentAttack().index)); + const AttackChoice &ac(battle->AttackChoiceAt(battle->CurrentAttack().index)); switch (ac.GetType()) { case AttackChoice::SWORD: @@ -86,13 +88,22 @@ void PerformAttacks::HandleEvents(const Input &input) { } moveAnimation = hero.AttackAnimation(); - numberAnimation.push_back(NumberAnimation(15, battle->Res().numberAnimationPrototype, battle->Res().bigNumberSprite)); if (ac.Selection().TargetsEnemies()) { - numberPosition.push_back( - battle->MonsterPositions()[ac.Selection().SingleSelection()]); + for (int i(0); i < battle->MaxMonsters(); ++i) { + if (ac.Selection().IsSelected(i)) { + numberAnimation.push_back(NumberAnimation(ac.Selection().GetAmount(i), battle->Res().numberAnimationPrototype, battle->Res().bigNumberSprite)); + numberPosition.push_back( + battle->MonsterPositions()[i]); + } + } } else { - numberPosition.push_back( - battle->HeroesPositions()[ac.Selection().SingleSelection()]); + for (int i(0); i < battle->NumHeroes(); ++i) { + if (ac.Selection().IsSelected(i)) { + numberAnimation.push_back(NumberAnimation(ac.Selection().GetAmount(i), battle->Res().numberAnimationPrototype, battle->Res().bigNumberSprite)); + numberPosition.push_back( + battle->HeroesPositions()[i]); + } + } } break; case AttackChoice::MAGIC: @@ -176,18 +187,6 @@ void PerformAttacks::ResetAnimation() { numberPosition.clear(); } -void PerformAttacks::AdvanceCursor() { - ++cursor; - while (cursor < int(order.size())) { - if (order[cursor].isMonster) { - if (battle->MonsterAt(order[cursor].index).Health() > 0) break; - } else { - if (battle->HeroAt(order[cursor].index).Health() > 0) break; - } - ++cursor; - } -} - void PerformAttacks::UpdateWorld(float deltaT) { @@ -227,8 +226,8 @@ void PerformAttacks::RenderNumbers(SDL_Surface *screen, const Vector &offse void PerformAttacks::RenderTargetAnimation(SDL_Surface *screen, const geometry::Vector &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()); + if (battle->CurrentAttack().isMonster) return; // no monsters for now + const TargetSelection &ts(battle->AttackChoiceAt(battle->CurrentAttack().index).Selection()); const vector > &positions(ts.TargetsHeroes() ? battle->HeroesPositions() : battle->MonsterPositions()); for (vector >::size_type i(0), end(positions.size()); i < end; ++i) { if (ts.IsSelected(i)) { diff --git a/src/battle/states/PerformAttacks.h b/src/battle/states/PerformAttacks.h index 556ae43..e8a878d 100644 --- a/src/battle/states/PerformAttacks.h +++ b/src/battle/states/PerformAttacks.h @@ -42,8 +42,6 @@ private: 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 &offset) const; @@ -58,7 +56,6 @@ private: const char *titleBarText; app::Timer titleBarTimer; app::Timer targetAnimationTimer; - std::vector order; std::vector numberAnimation; std::vector > numberPosition; int cursor; -- 2.39.2