class Oakdex::Pokemon::UseItemService

Represents Item usage

Public Class Methods

new(pokemon, item_id, options = {}) click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 5
def initialize(pokemon, item_id, options = {})
  @pokemon = pokemon
  @item = Oakdex::Pokedex::Item.find!(item_id)
  @options = options
end

Public Instance Methods

usable?() click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 11
def usable?
  !evolution.nil? || effect_usable?
end
use() click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 15
def use
  return unless usable?
  unless evolution.nil?
    @pokemon.add_growth_event(GrowthEvents::Evolution,
                              evolution: evolution)
  end
  execute_effects
  true
end

Private Instance Methods

change_for_move(move, change) click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 183
def change_for_move(move, change)
  increase_by = if change['change_by_percent']
                  (move.move_type.pp.to_f *
                    (change['change_by_percent'].to_f / 100)).to_i
                else
                  change['change_by']
                end

  if change['change_by_max'] && increase_by > change['change_by_max']
    change['change_by_max']
  else
    increase_by
  end
end
condition_applies?(effect) click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 38
def condition_applies?(effect)
  condition = effect['condition']
  condition == 'Always' ||
    (in_battle? && condition == 'During Battle') ||
    (!in_battle? && condition == 'Outside of Battle')
end
effect_usable?() click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 31
def effect_usable?
  @item.effects.any? do |effect|
    condition_applies?(effect) && target_applies?(effect) &&
      pokemon_changes_apply?(effect) && move_changes_apply?(effect)
  end
end
evolution() click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 214
def evolution
  EvolutionMatcher.new(@pokemon, 'item', item_id: @item.name).evolution
end
execute_add_max_pp(change) click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 148
def execute_add_max_pp(change)
  moves = @pokemon.moves.map do |move|
    next if move.max_pp_at_max?
    [move.name, change_for_move(move, change)]
  end.compact.to_h
  @pokemon.add_growth_event(GrowthEvents::IncreaseMaxPp, moves: moves)
end
execute_add_pp(change, effect) click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 156
def execute_add_pp(change, effect)
  if effect['target'] == 'Single Pokemon > All Moves'
    @pokemon.moves.each do |move|
      next if move.pp_max?
      @pokemon.add_growth_event(
        GrowthEvents::IncreaseMovePp,
        move_id: move.name,
        change_by: pp_change_for_move(move, change)
      )
    end
  else
    moves = @pokemon.moves.map do |move|
      next if move.pp_max?
      [move.name, pp_change_for_move(move, change)]
    end.compact.to_h
    @pokemon.add_growth_event(GrowthEvents::IncreasePp, moves: moves)
  end
end
execute_current_hp_change(change) click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 198
def execute_current_hp_change(change)
  change_by = change['change_by']
  if change['change_by_percent']
    change_by = percent_calculation(:hp, change['change_by_percent'])
  end
  if change['revive']
    @pokemon.add_growth_event(GrowthEvents::Revive, hp: change_by)
  else
    @pokemon.add_growth_event(GrowthEvents::AddHp, hp: change_by)
  end
end
execute_effects() click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 100
def execute_effects
  @item.effects.each do |effect|
    execute_pokemon_changes(effect)
    execute_move_changes(effect)
  end
end
execute_ev_change(change) click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 139
def execute_ev_change(change)
  stat = change['field'].sub('ev_', '').to_sym
  @pokemon.add_ev(stat, change['change_by'])
end
execute_level_up(_change) click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 135
def execute_level_up(_change)
  @pokemon.increment_level
end
execute_move_change(change, effect) click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 128
def execute_move_change(change, effect)
  case change['field']
  when 'max_pp' then execute_add_max_pp(change)
  when 'pp' then execute_add_pp(change, effect)
  end
end
execute_move_changes(effect) click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 113
def execute_move_changes(effect)
  (effect['move_changes'] || []).each do |change|
    execute_move_change(change, effect) if move_change_applies?(change)
  end
end
execute_pokemon_change(change) click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 119
def execute_pokemon_change(change)
  case change['field']
  when 'current_hp' then execute_current_hp_change(change)
  when 'status_condition' then execute_remove_status_condition(change)
  when 'level' then execute_level_up(change)
  when /^ev_/ then execute_ev_change(change)
  end
end
execute_pokemon_changes(effect) click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 107
def execute_pokemon_changes(effect)
  (effect['pokemon_changes'] || []).each do |change|
    execute_pokemon_change(change) if pokemon_change_applies?(change)
  end
end
execute_remove_status_condition(_change) click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 144
def execute_remove_status_condition(_change)
  @pokemon.add_growth_event(GrowthEvents::RemoveStatusCondition)
end
in_battle?() click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 27
def in_battle?
  @options[:in_battle]
end
independent_fainted?(change) click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 95
def independent_fainted?(change)
  %w[level max_pp].include?(change['field']) ||
    change['field'].start_with?('ev_')
end
move_change_applies?(change) click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 74
def move_change_applies?(change)
  !move_field_max?(change)
end
move_changes_apply?(effect) click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 59
def move_changes_apply?(effect)
  move_changes = effect['move_changes'] || []
  return true if move_changes.empty?
  move_changes.any? do |change|
    move_change_applies?(change)
  end
end
move_field_max?(change) click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 78
def move_field_max?(change)
  case change['field']
  when 'max_pp' then @pokemon.moves.all?(&:max_pp_at_max?)
  when 'pp' then @pokemon.moves.all?(&:pp_max?)
  end
end
percent_calculation(field, percent) click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 210
def percent_calculation(field, percent)
  (@pokemon.public_send(field).to_f * (percent.to_f / 100)).to_i
end
pokemon_change_applies?(change) click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 67
def pokemon_change_applies?(change)
  !pokemon_field_max?(change) &&
    (independent_fainted?(change) ||
      !@pokemon.fainted? ||
      (@pokemon.fainted? && change['revive']))
end
pokemon_changes_apply?(effect) click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 51
def pokemon_changes_apply?(effect)
  pokemon_changes = effect['pokemon_changes'] || []
  return true if pokemon_changes.empty?
  pokemon_changes.any? do |change|
    pokemon_change_applies?(change)
  end
end
pokemon_field_max?(change) click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 85
def pokemon_field_max?(change)
  case change['field']
  when 'current_hp' then @pokemon.current_hp >= @pokemon.hp
  when 'level' then @pokemon.level >= 100
  when /^ev_/ then @pokemon.ev_max?(change['field'].sub('ev_', '').to_sym)
  when 'status_condition' then !change['conditions']
    .include?(@pokemon.primary_status_condition)
  end
end
pp_change_for_move(move, change) click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 175
def pp_change_for_move(move, change)
  if change['change_by_percent']
    (move.max_pp.to_f * (change['change_by_percent'].to_f / 100)).to_i
  else
    change['change_by']
  end
end
target_applies?(effect) click to toggle source
# File lib/oakdex/pokemon/use_item_service.rb, line 45
def target_applies?(effect)
  target = effect['target']
  ['Single Pokemon', 'Single Pokemon > Single Move',
   'Single Pokemon > All Moves', 'Team'].include?(target)
end