| 290 | } |
| 291 | |
| 292 | bool IsSkillUsable(const lcf::rpg::Skill& skill, |
| 293 | bool require_states_persist) |
| 294 | { |
| 295 | const auto in_battle = Game_Battle::IsBattleRunning(); |
| 296 | |
| 297 | if (skill.type == lcf::rpg::Skill::Type_escape) { |
| 298 | return !in_battle && Main_Data::game_system->GetAllowEscape() && Main_Data::game_targets->HasEscapeTarget() && !Main_Data::game_player->IsFlying(); |
| 299 | } |
| 300 | |
| 301 | if (skill.type == lcf::rpg::Skill::Type_teleport) { |
| 302 | return !in_battle && Main_Data::game_system->GetAllowTeleport() && Main_Data::game_targets->HasTeleportTargets() && !Main_Data::game_player->IsFlying(); |
| 303 | } |
| 304 | |
| 305 | if (skill.type == lcf::rpg::Skill::Type_switch) { |
| 306 | return in_battle ? skill.occasion_battle : skill.occasion_field; |
| 307 | } |
| 308 | |
| 309 | if (in_battle) { |
| 310 | return true; |
| 311 | } |
| 312 | |
| 313 | if (SkillTargetsEnemies(skill)) { |
| 314 | return false; |
| 315 | } |
| 316 | |
| 317 | if (skill.affect_hp || skill.affect_sp) { |
| 318 | return true; |
| 319 | } |
| 320 | |
| 321 | bool affects_state = false; |
| 322 | for (int i = 0; i < static_cast<int>(skill.state_effects.size()); ++i) { |
| 323 | const bool inflict = skill.state_effects[i]; |
| 324 | if (inflict) { |
| 325 | const auto* state = lcf::ReaderUtil::GetElement(lcf::Data::states, i + 1); |
| 326 | if (state && (!require_states_persist || state->type == lcf::rpg::State::Persistence_persists)) { |
| 327 | affects_state = true; |
| 328 | break; |
| 329 | } |
| 330 | } |
| 331 | } |
| 332 | |
| 333 | return affects_state; |
| 334 | } |
| 335 | |
| 336 | int GetNumberOfAttacks(int actor_id, const lcf::rpg::Item& weapon) { |
| 337 | assert(weapon.type == lcf::rpg::Item::Type_weapon); |
no test coverage detected