]> git.localhorst.tv Git - l2e.git/commitdiff
moved attack order to battle state
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 19 Aug 2012 17:50:18 +0000 (19:50 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Sun, 19 Aug 2012 17:50:18 +0000 (19:50 +0200)
src/app/Application.cpp
src/battle/BattleState.cpp
src/battle/BattleState.h
src/battle/TargetSelection.cpp
src/battle/TargetSelection.h
src/battle/states/PerformAttacks.cpp
src/battle/states/PerformAttacks.h

index 6e46203aa94184de00c55d90ff41025b7433d12d..ac95ed0a26f69287d24f69518acd3ef001f4cdaf 100644 (file)
@@ -159,7 +159,7 @@ void Application::HandleEvents() {
                                break;
                }
        }
-       CurrentState()->HandleEvents(input);
+       if (CurrentState()) CurrentState()->HandleEvents(input);
 }
 
 void Application::UpdateWorld(Uint32 deltaT) {
index 1a4f726de656c7a5c561ac01315d7472c898ace9..dcad8b2322d3c12197e3a308438da6556bddc294 100644 (file)
@@ -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) {
-       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<Monster>::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();
 }
 
 
index 3acc0b7699c79dd9ffeaef66c686d263c2a4d29e..5898a2d4aa93920ffc9a5a20a1d366240d46de5c 100644 (file)
@@ -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<Order> &);
+       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<int> CalculateScreenOffset(SDL_Surface *screen) const {
@@ -158,6 +164,8 @@ private:
        std::vector<geometry::Point<int> > monsterPositions;
        std::vector<geometry::Point<int> > heroesPositions;
        std::vector<Monster> monsters;
+       std::vector<AttackChoice> monsterAttacks;
+       std::vector<Order> attackOrder;
        Hero heroes[4];
        graphics::Menu<const common::Spell *> spellMenus[4];
        graphics::Menu<const common::Item *> itemMenu;
@@ -169,6 +177,7 @@ private:
        AttackChoice attackChoices[4];
        int numHeroes;
        int activeHero;
+       int attackCursor;
        bool ranAway;
 
 };
index c1aedf3ca7d8a253b05b368812801a8b3ce6cf67..2608e3976d6def49126654de419d21316cd7073f 100644 (file)
@@ -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)
index 664e9607e86caaf374f53d5f1f6d2a3151f59554..64500b0b02aca225a117e2005d60f881f63fae11 100644 (file)
@@ -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<bool> selected;
+       std::vector<State> selected;
        int selection;
        int cursor;
        bool multiple;
index 2a8f3a53b697a4aecb3e5270c4e7c65d4be69ff9..6baa1dae0fe700d64d70bab13141d7d857179a0c 100644 (file)
@@ -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<int> &offse
 
 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());
+       if (battle->CurrentAttack().isMonster) return; // no monsters for now
+       const TargetSelection &ts(battle->AttackChoiceAt(battle->CurrentAttack().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)) {
index 556ae43b5b0bb93b5210457ebb449afa9cc58d0c..e8a878d761e6b214820ba998407c7d98087dc617 100644 (file)
@@ -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<int> &offset) const;
@@ -58,7 +56,6 @@ private:
        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;
        int cursor;