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 #ifndef EP_AUTOBATTLE_H
18 #define EP_AUTOBATTLE_H
19 
20 #include <lcf/rpg/fwd.h>
21 #include <lcf/rpg/system.h>
22 #include <lcf/rpg/saveactor.h>
23 #include <game_battler.h>
24 #include <memory>
25 
26 class Game_Actor;
27 class Game_Enemy;
28 
29 namespace AutoBattle {
30 class AlgorithmBase;
31 
32 /**
33  * Auto battle algorithm factory function which creates auto battle algorithm from the given name
34  *
35  * @param name of the algo.
36  * @return An auto battle algorithm to be used in battles.
37  */
38 std::unique_ptr<AlgorithmBase> CreateAlgorithm(StringView name);
39 
40 /**
41  * Base class for auto battle algorithm implementations.
42  */
43 class AlgorithmBase {
44 public:
~AlgorithmBase()45 	virtual ~AlgorithmBase() {}
46 
47 	/** @return the name of this algorithm */
48 	virtual StringView GetName() const = 0;
49 
50 	/**
51 	 * Calculates the auto battle algorithm and sets the algorithm on source.
52 	 * This computation ignores states on the actor, it is  the resposibility of the caller
53 	 * to handle death, confuse, provoke, etc..
54 	 *
55 	 * @param source The source actor to set the action for.
56 	 * @post source will have a BattleAlgorithm set.
57 	 */
58 	void SetAutoBattleAction(Game_Actor& source);
59 private:
60 	virtual void vSetAutoBattleAction(Game_Actor& source) = 0;
61 };
62 
63 /**
64  * The default autobattle algorithm which is strictly compatible with RPG_RT, bugs included.
65  */
66 class RpgRtCompat: public AlgorithmBase {
67 public:
68 	static constexpr auto name = "RPG_RT";
69 
GetName()70 	StringView GetName() const override { return name; }
71 private:
72 	void vSetAutoBattleAction(Game_Actor& source) override;
73 };
74 
75 /**
76  * An autobattle algorithm which only does physical attacks.
77  */
78 class AttackOnly: public AlgorithmBase {
79 public:
80 	static constexpr auto name = "ATTACK";
81 
GetName()82 	StringView GetName() const override { return name; }
83 private:
84 	void vSetAutoBattleAction(Game_Actor& source) override;
85 };
86 
87 /**
88  * A custom autobattle algorithm which is similar to RPG_RT but fixes bugs and has improved logic.
89  */
90 class RpgRtImproved: public AlgorithmBase {
91 public:
92 	static constexpr auto name = "RPG_RT+";
93 
GetName()94 	StringView GetName() const override { return name; }
95 private:
96 	void vSetAutoBattleAction(Game_Actor& source) override;
97 };
98 
99 /**
100  * Calculate the auto battle effectiveness rank of source using healing skill on target.
101  *
102  * @param source the user of the skill
103  * @param target the target of the skill
104  * @param skill the skill
105  * @param apply_variance If true, apply variance to the damage
106  * @param emulate_bugs Emulate all RPG_RT bugs for accuracy
107  *
108  * @pre skill Must be a normal or subskill or the result is undefined.
109  * @pre skill must target self, ally, or ally party or the result is undefined.
110  */
111 double CalcSkillHealAutoBattleTargetRank(const Game_Actor& source, const Game_Battler& target, const lcf::rpg::Skill& skill, bool apply_variance, bool emulate_bugs);
112 
113 /**
114  * Calculate the auto battle effectiveness rank of source using damage skill on target.
115  *
116  * @param source the user of the skill
117  * @param target the target of the skill
118  * @param skill the skill
119  * @param apply_variance If true, apply variance to the damage
120  * @param emulate_bugs Emulate all RPG_RT bugs for accuracy
121  *
122  * @pre skill Must be a normal or subskill or the result is undefined.
123  * @pre skill must target enemy, or enemy party or the result is undefined.
124  */
125 double CalcSkillDmgAutoBattleTargetRank(const Game_Actor& source, const Game_Battler& target, const lcf::rpg::Skill& skill, bool apply_variance, bool emulate_bugs);
126 
127 /**
128  * Calculate the auto battle total effectiveness rank of using a skill.
129  *
130  * @param source the user of the skill
131  * @param skill the skill
132  * @param apply_variance If true, apply variance to the damage
133  * @param emulate_bugs Emulate all RPG_RT bugs for accuracy
134  */
135 double CalcSkillAutoBattleRank(const Game_Actor& source, const lcf::rpg::Skill& skill, bool apply_variance, bool emulate_bugs);
136 
137 /**
138  * Calculate the auto battle effectiveness rank of source attacking target.
139  *
140  * @param source the user of the skill
141  * @param target the target of the skill
142  * @param cond the battle condition
143  * @param apply_variance If true, apply variance to the damage
144  * @param emulate_bugs Emulate all RPG_RT bugs for accuracy
145  */
146 double CalcNormalAttackAutoBattleTargetRank(const Game_Actor& source, const Game_Battler& target, Game_Battler::Weapon weapon, lcf::rpg::System::BattleCondition cond, bool apply_variance, bool emulate_bugs);
147 
148 /**
149  * Calculate the auto battle total effectiveness rank of using a normal attack.
150  *
151  * @param source the user of the skill
152  * @param weapon Which weapon to use in the calculation
153  * @param cond the battle condition
154  * @param apply_variance If true, apply variance to the damage
155  * @param emulate_bugs Emulate all RPG_RT bugs for accuracy
156  */
157 double CalcNormalAttackAutoBattleRank(const Game_Actor& source, Game_Battler::Weapon weapon, lcf::rpg::System::BattleCondition cond, bool apply_variance, bool emulate_bugs);
158 
159 /**
160  * Runs the RPG_RT auto battle algorithm and sets a Game_BattlerAlgorithm on the source.
161  *
162  * @param actor Which actor to select auto battle action for
163  * @param weapon Which weapon to use in the calculation
164  * @param cond the battle condition
165  * @param do_skills Whether to include skills or not
166  * @param attack_variance Whether to include variance in normal attack ranking
167  * @param skill_variance Whether to include variance in skill ranking
168  * @param emulate_bugs Emulate all RPG_RT bugs for accuracy
169  * @post actor may have a battle algorithm set, unless an error occured.
170  */
171 void SelectAutoBattleAction(Game_Actor& source,
172 		Game_Battler::Weapon weapon,
173 		lcf::rpg::System::BattleCondition cond,
174 		bool do_skills,
175 		bool attack_variance,
176 		bool skill_variance,
177 		bool emulate_bugs);
178 
179 /**
180  * Calls SelectAutoBattleAction() with RPG_RT strictly compatible flags.
181  *
182  * @param actor Which actor to select auto battle action for
183  * @param cond the battle condition
184  * @post actor may have a battle algorithm set, unless an error occured.
185  */
SelectAutoBattleActionRpgRtCompat(Game_Actor & source,lcf::rpg::System::BattleCondition cond)186 inline void SelectAutoBattleActionRpgRtCompat(Game_Actor& source, lcf::rpg::System::BattleCondition cond) {
187 	SelectAutoBattleAction(source, Game_Battler::WeaponAll, cond, true, false, true, true);
188 }
189 
190 } // namespace AutoBattle
191 
192 #endif
193