1 /*
2  * This file is part of EasyRPG Player.
3  *
4  * EasyRPG Player is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * EasyRPG Player is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with EasyRPG Player. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef EP_SCENE_BATTLE_H
19 #define EP_SCENE_BATTLE_H
20 
21 // Headers
22 #include <deque>
23 #include <lcf/rpg/troopmember.h>
24 #include <lcf/rpg/actor.h>
25 #include <lcf/rpg/enemy.h>
26 
27 #include "battle_animation.h"
28 #include "drawable.h"
29 #include "game_actor.h"
30 #include "game_enemy.h"
31 #include "scene.h"
32 #include "spriteset_battle.h"
33 #include "window_help.h"
34 #include "window_item.h"
35 #include "window_skill.h"
36 #include "window_command.h"
37 #include "window_battlecommand.h"
38 #include "window_battlestatus.h"
39 #include "window_message.h"
40 #include "game_battle.h"
41 
42 namespace AutoBattle {
43 class AlgorithmBase;
44 }
45 
46 namespace EnemyAi {
47 class AlgorithmBase;
48 }
49 
50 class Game_Battler;
51 
52 using BattleContinuation = std::function<void(BattleResult)>;
53 
54 struct BattleArgs {
55 	BattleContinuation on_battle_end;
56 	std::string background;
57 	int troop_id = 0;
58 	int terrain_id = 0;
59 	lcf::rpg::System::BattleFormation formation = lcf::rpg::System::BattleFormation_terrain;
60 	lcf::rpg::System::BattleCondition condition = lcf::rpg::System::BattleCondition_none;
61 	bool first_strike = false;
62 	bool allow_escape = true;
63 };
64 
65 constexpr int option_command_mov = 76;
66 constexpr int option_command_time = 8;
67 
68 /**
69  * Scene_Battle class.
70  * Manages the battles.
71  */
72 class Scene_Battle : public Scene {
73 
74 public:
75 	static std::shared_ptr<Scene_Battle> Create(const BattleArgs& args);
76 
77 	~Scene_Battle() override;
78 
79 	void Start() override;
80 
81 	void UpdateScreen();
82 	void UpdateBattlers();
83 	void UpdateUi();
84 	bool UpdateEvents();
85 	bool UpdateTimers();
86 	void UpdateGraphics() override;
87 
88 	void Continue(SceneType prev_scene) override;
89 	void TransitionIn(SceneType prev_scene) override;
90 	void TransitionOut(SceneType next_scene) override;
91 	void DrawBackground(Bitmap& dst) override;
92 
93 	enum State {
94 		/** Battle has started (Display encounter message) */
95 		State_Start,
96 		/** Menu with Battle, Auto Battle and Escape Options */
97 		State_SelectOption,
98 		/** Selects next actor who has to move */
99 		State_SelectActor,
100 		/** Auto battle command selected */
101 		State_AutoBattle,
102 		/** Menu with abilities of current Actor (e.g. Command, Item, Skill and Defend) */
103 		State_SelectCommand,
104 		/** Item selection is active */
105 		State_SelectItem,
106 		/** Skill selection menu is active */
107 		State_SelectSkill,
108 		/** Player selects enemy target */
109 		State_SelectEnemyTarget,
110 		/** Player selects allied target */
111 		State_SelectAllyTarget,
112 		/** Battle Running */
113 		State_Battle,
114 		/** Battle ended with a victory */
115 		State_Victory,
116 		/** Battle ended with a defeat */
117 		State_Defeat,
118 		/** Escape command selected */
119 		State_Escape
120 	};
121 
122 	/** Options available in a battle option menu. */
123 	enum BattleOptionType {
124 		Battle,
125 		AutoBattle,
126 		Escape
127 	};
128 
129 	static void SelectionFlash(Game_Battler* battler);
130 
131 protected:
132 	explicit Scene_Battle(const BattleArgs& args);
133 
134 	virtual void CreateUi();
135 
136 	virtual void SetState(Scene_Battle::State new_state) = 0;
137 
138 	bool IsWindowMoving();
139 	bool IsEscapeAllowed() const;
140 
141 	virtual Game_Enemy* EnemySelected();
142 	virtual Game_Actor* AllySelected();
143 	virtual void AttackSelected();
144 	virtual void DefendSelected();
145 	virtual void ItemSelected();
146 	virtual void SkillSelected();
147 
148 	virtual void AssignSkill(const lcf::rpg::Skill* skill, const lcf::rpg::Item* item);
149 
150 	/**
151 	 * Executed when selection an action (normal, skill, item, ...) and
152 	 * (if needed) choosing an attack target was finished.
153 	 *
154 	 * @param for_battler Battler whose action was selected.
155 	 */
156 	virtual void ActionSelectedCallback(Game_Battler* for_battler);
157 
158 	void PrepareBattleAction(Game_Battler* battler);
159 
160 	void RemoveCurrentAction();
161 
162 	bool CallDebug();
163 
164 	void EndBattle(BattleResult result);
165 
166 	void InitEscapeChance();
167 	bool TryEscape();
168 
169 	// Variables
170 	State state = State_Start;
171 	State previous_state = State_Start;
172 	int cycle = 0;
173 	int troop_id = 0;
174 	int escape_chance = 0;
175 	bool allow_escape = false;
176 	bool first_strike = false;
177 
178 	Game_Actor* active_actor = nullptr;
179 
180 	/** Displays Fight, Autobattle, Flee */
181 	std::unique_ptr<Window_Command> options_window;
182 	/** Displays list of enemies */
183 	std::unique_ptr<Window_Command> target_window;
184 	/** Displays Attack, Defense, Magic, Item */
185 	std::unique_ptr<Window_Command> command_window;
186 	std::unique_ptr<Window_Item> item_window;
187 	std::unique_ptr<Window_BattleSkill> skill_window;
188 	std::unique_ptr<Window_Help> help_window;
189 	/** Displays allies status */
190 	std::unique_ptr<Window_BattleStatus> status_window;
191 	std::unique_ptr<Window_Message> message_window;
192 
193 	std::deque<Game_Battler*> battle_actions;
194 	std::unique_ptr<AutoBattle::AlgorithmBase> autobattle_algo;
195 	std::unique_ptr<EnemyAi::AlgorithmBase> enemyai_algo;
196 
197 	BattleContinuation on_battle_end;
198 
199 	/** Options available in the menu. */
200 	std::vector<BattleOptionType> battle_options;
201 };
202 
IsEscapeAllowed()203 inline bool Scene_Battle::IsEscapeAllowed() const {
204 	return allow_escape;
205 }
206 
207 #endif
208