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_ALGO_H
19 #define EP_ALGO_H
20 
21 #include <lcf/rpg/fwd.h>
22 #include <lcf/rpg/system.h>
23 #include <lcf/rpg/saveactor.h>
24 #include <lcf/rpg/skill.h>
25 #include "game_battler.h"
26 
27 class Game_Actor;
28 class Game_Enemy;
29 
30 namespace Algo {
31 
32 /**
33  * Compute whether a row adjustment should occur.
34  *
35  * @param row The row value to check
36  * @param cond The current battle condition
37  * @param offense Whether to adjust for an offensive action (true) or defensive action (false)
38  *
39  * @return Whether the row adjustment should apply or not.
40  */
41 bool IsRowAdjusted(lcf::rpg::SaveActor::RowType row, lcf::rpg::System::BattleCondition cond, bool offense);
42 
43 /**
44  * Compute whether a row adjustment should occur.
45  *
46  * @param actor The actor whose row to check
47  * @param cond The current battle condition
48  * @param offense Whether to adjust for an offensive action (true) or defensive action (false)
49  * @param allow_enemy Compute row adjustment for enemies also and treat them as always in front row.
50  *
51  * @return Whether the row adjustment should apply or not.
52  */
53 bool IsRowAdjusted(const Game_Battler& battler,
54 		lcf::rpg::System::BattleCondition cond,
55 		bool offense,
56 		bool allow_enemy);
57 
58 /**
59  * Uses RPG_RT algorithm for performing a variance adjument to damage/healing effects and returns the result.
60  *
61  * @param base - the base amount of the effect
62  * @param var - the variance level from 0 to 10
63  *
64  * @return the adjusted damage amount
65  */
66 int VarianceAdjustEffect(int base, int var);
67 
68 /**
69  * Compute the hit rate for a physical attack
70  *
71  * @param source The source of the action
72  * @param target The target of the action
73  * @param cond The current battle condition
74  * @param weapon Which weapon to use or kWeaponAll for combined
75  * @param emulate_2k3_enemy_row_bug Whether or not to emulate 2k3 bug where RPG_RT considers defending enemies in the front row
76  *
77  * @return Success hit rate
78  */
79 int CalcNormalAttackToHit(const Game_Battler& source,
80 		const Game_Battler& target,
81 		Game_Battler::Weapon weapon,
82 		lcf::rpg::System::BattleCondition cond,
83 		bool emulate_2k3_enemy_row_bug);
84 
85 /**
86  * Compute the hit rate for a skill
87  *
88  * @param source The source of the action
89  * @param target The target of the action
90  * @param skill Which skill to calculate hit rate for
91  *
92  * @return Success hit rate
93  */
94 int CalcSkillToHit(const Game_Battler& source, const Game_Battler& target, const lcf::rpg::Skill& skill);
95 
96 /**
97  * Compute the critical hit rate if source attacks target.
98  *
99  * @param source The attacker
100  * @param target The defender
101  * @param weapon Which weapon to use or kWeaponAll for combined
102  *
103  * @return Critical hit rate.
104  */
105 int CalcCriticalHitChance(const Game_Battler& source, const Game_Battler& target, Game_Battler::Weapon weapon);
106 
107 /**
108  * Check if target is defending and perform damage adjustment if so.
109  *
110  * @param dmg The base amount of damage.
111  * @param target who is to receive damage
112  *
113  * @return The adjusted damage.
114  */
115 int AdjustDamageForDefend(int dmg, const Game_Battler& target);
116 
117 /**
118  * Compute the base damage for a normal attack
119  * This includes: source atk, target def, source row, attributes, target row, critical, source charged, and variance
120  * It does not include: hit rate, critical hit rate, target defend adjustment, value clamping
121  *
122  * @param source The source of the action
123  * @param target The target of the action
124  * @param weapon Which weapon to use or kWeaponAll for combined
125  * @param is_critical_hit If true, apply critical hit bonus
126  * @param is_charged If true, the attacker was charged
127  * @param apply_variance If true, apply variance to the damage
128  * @param cond The current battle condition
129  * @param emulate_2k3_enemy_row_bug Whether or not to emulate 2k3 bug where RPG_RT considers defending enemies in the front row
130  *
131  * @return effect amount
132  */
133 int CalcNormalAttackEffect(const Game_Battler& source,
134 		const Game_Battler& target,
135 		Game_Battler::Weapon weapon,
136 		bool is_critical_hit,
137 		bool is_charged,
138 		bool apply_variance,
139 		lcf::rpg::System::BattleCondition cond,
140 		bool emulate_2k3_enemy_row_bug);
141 
142 /**
143  * Compute the base damage for a skill
144  * This includes: power, source atk/mag, target def/mag, attributes, variance
145  * It does not include: hit rate, target defend adjustment, value clamping
146  *
147  * @param source The source of the action
148  * @param target The target of the action
149  * @param skill The skill to use
150  * @param apply_variance If true, apply variance to the damage
151  *
152  * @return effect amount
153  */
154 int CalcSkillEffect(const Game_Battler& source,
155 		const Game_Battler& target,
156 		const lcf::rpg::Skill& skill,
157 		bool apply_variance);
158 
159 /**
160  * Compute the base damage for self-destruct
161  * This includes: power, source atk, target def, variance
162  * It does not include: hit rate, target defend adjustment, value clamping
163  *
164  * @param source The source of the action
165  * @param target The target of the action
166  * @param apply_variance If true, apply variance to the damage
167  *
168  * @return effect amount
169  */
170 int CalcSelfDestructEffect(const Game_Battler& source,
171 		const Game_Battler& target,
172 		bool apply_variance);
173 
174 /**
175  * Calculate the sp cost for a skill.
176  * This includes: power, source atk, target def, variance
177  * It does not include: hit rate, target defend adjustment, value clamping
178  *
179  * @param skill The skill to compute
180  * @param max_sp the max sp of the user
181  * @param half_sp_cost if user has half_sp_cost modifier
182  *
183  * @return sp cost
184  */
185 int CalcSkillCost(const lcf::rpg::Skill& skill, int max_sp, bool half_sp_cost);
186 
187 /*
188  * Determine whether a skill is usable.
189  *
190  * @param skill the skill to check
191  * @param require_states_persist If we should require persistent states for non-battle.
192  * @return Whether the skill can be used.
193  */
194 bool IsSkillUsable(const lcf::rpg::Skill& skill,
195 		bool require_states_persist);
196 
197 /**
198  * Checks if the skill is a normal or subskill type.
199  *
200  * @param skill the skill to check
201  * @return true if a normal skill or a 2k3 subskill.
202  */
IsNormalOrSubskill(const lcf::rpg::Skill & skill)203 inline bool IsNormalOrSubskill(const lcf::rpg::Skill& skill) {
204 	return skill.type == lcf::rpg::Skill::Type_normal
205 		|| skill.type >= lcf::rpg::Skill::Type_subskill;
206 }
207 
208 /**
209  * Checks if the skill targets the opposing party.
210  *
211  * @param skill the skill to check
212  * @return true if targets opposing party
213  */
SkillTargetsEnemies(const lcf::rpg::Skill & skill)214 inline bool SkillTargetsEnemies(const lcf::rpg::Skill& skill) {
215 	return skill.scope == lcf::rpg::Skill::Scope_enemy
216 		|| skill.scope == lcf::rpg::Skill::Scope_enemies;
217 }
218 
219 /**
220  * Checks if the skill targets the allied party.
221  *
222  * @param skill the skill to check
223  * @return true if targets allied party
224  */
SkillTargetsAllies(const lcf::rpg::Skill & skill)225 inline bool SkillTargetsAllies(const lcf::rpg::Skill& skill) {
226 	return !SkillTargetsEnemies(skill);
227 }
228 
229 /**
230  * Checks if the skill has a single target
231  *
232  * @param skill the skill to check
233  * @return true if targets a single battler
234  */
SkillTargetsOne(const lcf::rpg::Skill & skill)235 inline bool SkillTargetsOne(const lcf::rpg::Skill& skill) {
236 	return skill.scope == lcf::rpg::Skill::Scope_ally
237 				|| skill.scope == lcf::rpg::Skill::Scope_enemy
238 				|| skill.scope == lcf::rpg::Skill::Scope_self;
239 }
240 
241 /**
242  * Returns the number of attacks the weapon can do.
243  *
244  * @param the id of the actor to check
245  * @param weapon the item to check
246  * @pre If weapon is not a weapon type, the result is undefined.
247  * @return the number of attacks.
248  */
249 int GetNumberOfAttacks(int actor_id, const lcf::rpg::Item& weapon);
250 
251 } // namespace Algo
252 
253 
254 #endif
255