class Oakdex::Battle::ValidActionService
Generates all valid actions within the battle
Public Class Methods
new(battle)
click to toggle source
# File lib/oakdex/battle/valid_action_service.rb, line 11 def initialize(battle) @battle = battle end
Public Instance Methods
valid_actions_for(trainer)
click to toggle source
# File lib/oakdex/battle/valid_action_service.rb, line 15 def valid_actions_for(trainer) return [] if no_actions_for?(trainer) growth_events = growth_event_actions(trainer) return growth_events unless growth_events.empty? valid_move_actions_for(trainer) + valid_recall_actions_for(trainer) + valid_item_actions_for(trainer) end
Private Instance Methods
actions_for_trainer(trainer)
click to toggle source
# File lib/oakdex/battle/valid_action_service.rb, line 26 def actions_for_trainer(trainer) actions.select { |a| a.trainer == trainer } end
added_growth_action_already?(trainer)
click to toggle source
# File lib/oakdex/battle/valid_action_service.rb, line 38 def added_growth_action_already?(trainer) growth_events = growth_event_actions(trainer) !growth_events.empty? && !actions_for_trainer(trainer).empty? end
growth_event_actions(trainer)
click to toggle source
# File lib/oakdex/battle/valid_action_service.rb, line 44 def growth_event_actions(trainer) while trainer.growth_event? && trainer.growth_event.read_only? @battle.add_to_log(trainer.growth_event.message) trainer.growth_event.execute end if trainer.growth_event? trainer.growth_event.possible_actions.map do |option| { 'action' => 'growth_event', 'option' => option } end else [] end end
no_actions_for?(trainer)
click to toggle source
# File lib/oakdex/battle/valid_action_service.rb, line 30 def no_actions_for?(trainer) growth_events = growth_event_actions(trainer) sides.empty? || (no_battle_pokemon?(trainer) && growth_events.empty?) || (other_is_growing?(trainer) && growth_events.empty?) || added_growth_action_already?(trainer) end
no_battle_pokemon?(trainer)
click to toggle source
# File lib/oakdex/battle/valid_action_service.rb, line 152 def no_battle_pokemon?(trainer) other_sides(trainer).all? { |s| s.active_in_battle_pokemon.empty? } && own_battle_pokemon?(trainer) end
other_is_growing?(trainer)
click to toggle source
# File lib/oakdex/battle/valid_action_service.rb, line 62 def other_is_growing?(trainer) other_trainers = sides.flat_map(&:trainers) - [trainer] other_trainers.any? do |t| t.growth_event? && !t.growth_event.read_only? end end
other_sides(trainer)
click to toggle source
# File lib/oakdex/battle/valid_action_service.rb, line 161 def other_sides(trainer) sides.select { |s| !s.trainer_on_side?(trainer) } end
own_battle_pokemon?(trainer)
click to toggle source
# File lib/oakdex/battle/valid_action_service.rb, line 157 def own_battle_pokemon?(trainer) !side(trainer).active_in_battle_pokemon.empty? end
pokemon_per_trainer()
click to toggle source
# File lib/oakdex/battle/valid_action_service.rb, line 136 def pokemon_per_trainer sides.first.trainers.size end
possible_item_actions(battle_pokemon, item_id, prevActions = [])
click to toggle source
# File lib/oakdex/battle/valid_action_service.rb, line 91 def possible_item_actions(battle_pokemon, item_id, prevActions = []) dup_pokemon = battle_pokemon.pokemon.dup dup_pokemon.use_item(item_id, in_battle: true) e = dup_pokemon.growth_event return [[]] if !e || e.read_only? prevActions.each do |a| e.execute(a) e = dup_pokemon.growth_event end return [prevActions] if e.read_only? e.possible_actions.flat_map do |a| r = possible_item_actions(battle_pokemon, item_id, prevActions + [a]) r end end
recall_action(trainer, active_ibp, target)
click to toggle source
# File lib/oakdex/battle/valid_action_service.rb, line 117 def recall_action(trainer, active_ibp, target) return if !recall_action_valid?(trainer, active_ibp, target) || recall_action_for?(target) { 'action' => 'recall', 'pokemon' => active_ibp&.position || side(trainer).next_position, 'target' => target.id } end
recall_action_for?(target)
click to toggle source
# File lib/oakdex/battle/valid_action_service.rb, line 140 def recall_action_for?(target) actions.any? do |action| action.type == 'recall' && action.target_id == target.id end end
recall_action_for_position?(position)
click to toggle source
# File lib/oakdex/battle/valid_action_service.rb, line 146 def recall_action_for_position?(position) actions.any? do |action| action.type == 'recall' && action.pokemon_position == position end end
recall_action_valid?(trainer, active_in_battle_pokemon, _target)
click to toggle source
# File lib/oakdex/battle/valid_action_service.rb, line 127 def recall_action_valid?(trainer, active_in_battle_pokemon, _target) if active_in_battle_pokemon !active_in_battle_pokemon.action_added? else next_position = side(trainer).next_position next_position && !recall_action_for_position?(next_position) end end
side(trainer)
click to toggle source
# File lib/oakdex/battle/valid_action_service.rb, line 165 def side(trainer) sides.find { |s| s.trainer_on_side?(trainer) } end
valid_item_actions_for(trainer)
click to toggle source
# File lib/oakdex/battle/valid_action_service.rb, line 73 def valid_item_actions_for(trainer) return [] if actions.select { |a| a.trainer == trainer }.size >= pokemon_per_trainer trainer.items.flat_map do |item_id| trainer.team.flat_map.with_index do |pokemon, i| next if actions.any? { |a| a.item_id == item_id } next unless pokemon.usable_item?(item_id, in_battle: true) possible_item_actions(pokemon, item_id).map do |item_actions| { 'action' => 'use_item_on_pokemon', 'pokemon_team_pos' => i, 'item_id' => item_id, 'item_actions' => item_actions } end end.compact end - actions end
valid_move_actions_for(trainer)
click to toggle source
# File lib/oakdex/battle/valid_action_service.rb, line 69 def valid_move_actions_for(trainer) trainer.active_in_battle_pokemon.flat_map(&:valid_move_actions) end
valid_recall_actions_for(trainer)
click to toggle source
# File lib/oakdex/battle/valid_action_service.rb, line 107 def valid_recall_actions_for(trainer) trainer.left_pokemon_in_team.flat_map do |pokemon| pokemon_per_trainer.times.map do |position| recall_action(trainer, trainer.active_in_battle_pokemon[position], pokemon) end.compact end end