| 181 | } |
| 182 | |
| 183 | int CalcNormalAttackEffect(const Game_Battler& source, |
| 184 | const Game_Battler& target, |
| 185 | Game_Battler::Weapon weapon, |
| 186 | bool is_critical_hit, |
| 187 | bool is_charged, |
| 188 | bool apply_variance, |
| 189 | lcf::rpg::System::BattleCondition cond, |
| 190 | bool emulate_2k3_enemy_row_bug) |
| 191 | { |
| 192 | const auto atk = source.GetAtk(weapon); |
| 193 | const auto def = target.GetDef(); |
| 194 | |
| 195 | // Base damage |
| 196 | auto dmg = std::max(0, atk / 2 - def / 4); |
| 197 | |
| 198 | // Attacker row adjustment |
| 199 | if (Feature::HasRow() && IsRowAdjusted(source, cond, true, false)) { |
| 200 | dmg = 125 * dmg / 100; |
| 201 | } |
| 202 | |
| 203 | // Attacker weapon attribute adjustment |
| 204 | dmg = Attribute::ApplyAttributeNormalAttackMultiplier(dmg, source, target, weapon); |
| 205 | |
| 206 | // Defender row adjustment |
| 207 | if (Feature::HasRow() && IsRowAdjusted(target, cond, false, emulate_2k3_enemy_row_bug)) { |
| 208 | dmg = 75 * dmg / 100; |
| 209 | } |
| 210 | |
| 211 | // Critical and charge adjustment |
| 212 | if (is_critical_hit) { |
| 213 | dmg *= 3; |
| 214 | } else if (is_charged) { |
| 215 | dmg *= 2; |
| 216 | } |
| 217 | |
| 218 | if (apply_variance) { |
| 219 | dmg = VarianceAdjustEffect(dmg, 4); |
| 220 | } |
| 221 | |
| 222 | return dmg; |
| 223 | } |
| 224 | |
| 225 | int CalcSkillEffect(const Game_Battler& source, |
| 226 | const Game_Battler& target, |