oakdex-battle 0.0.2 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -104,7 +104,7 @@ module Oakdex
104
104
  end
105
105
 
106
106
  def random_stat
107
- (Pokemon::BATTLE_STATS + Pokemon::OTHER_STATS).sample
107
+ (Oakdex::Pokemon::BATTLE_STATS + InBattlePokemon::OTHER_STATS).sample
108
108
  end
109
109
 
110
110
  def add_log(*args)
@@ -37,17 +37,17 @@ module Oakdex
37
37
  end
38
38
 
39
39
  def pokemon_in_battle?(position)
40
- in_battle_pokemon.any? do |ibp|
40
+ active_in_battle_pokemon.any? do |ibp|
41
41
  ibp.position == position
42
42
  end
43
43
  end
44
44
 
45
45
  def pokemon_left?
46
- !in_battle_pokemon.empty?
46
+ !active_in_battle_pokemon.empty?
47
47
  end
48
48
 
49
- def in_battle_pokemon
50
- @trainers.map(&:in_battle_pokemon).flatten(1)
49
+ def active_in_battle_pokemon
50
+ @trainers.map(&:active_in_battle_pokemon).flatten(1)
51
51
  end
52
52
 
53
53
  def fainted?
@@ -65,7 +65,7 @@ module Oakdex
65
65
  end
66
66
 
67
67
  def taken_positions
68
- in_battle_pokemon.map(&:position).sort
68
+ active_in_battle_pokemon.map(&:position).sort
69
69
  end
70
70
 
71
71
  def all_position
@@ -9,7 +9,7 @@ module Oakdex
9
9
  end
10
10
 
11
11
  def after_turn(turn)
12
- return if pokemon.current_hp.zero?
12
+ return if pokemon.fainted?
13
13
  turn.battle.add_to_log('damage_by_badly_poisoned',
14
14
  pokemon.trainer.name,
15
15
  pokemon.name, hp_by_turn)
@@ -4,7 +4,7 @@ module Oakdex
4
4
  # Represents Burn status condition
5
5
  class Burn < NonVolatile
6
6
  def after_turn(turn)
7
- return if pokemon.current_hp.zero?
7
+ return if pokemon.fainted?
8
8
  turn.battle.add_to_log('damage_by_burn',
9
9
  pokemon.trainer.name,
10
10
  pokemon.name, hp_by_turn)
@@ -13,7 +13,7 @@ module Oakdex
13
13
  end
14
14
 
15
15
  def after_received_damage(move_execution)
16
- return unless move_execution.move.type == 'fire'
16
+ return unless move_execution.move.type_id == 'fire'
17
17
  defrost(move_execution.battle)
18
18
  end
19
19
 
@@ -4,7 +4,7 @@ module Oakdex
4
4
  # Represents Poison status condition
5
5
  class Poison < NonVolatile
6
6
  def after_turn(turn)
7
- return if pokemon.current_hp.zero?
7
+ return if pokemon.fainted?
8
8
  turn.battle.add_to_log('damage_by_poison',
9
9
  pokemon.trainer.name,
10
10
  pokemon.name, hp_by_turn)
@@ -2,48 +2,50 @@ module Oakdex
2
2
  class Battle
3
3
  # Represents a Pokemon Trainer. Owns Pokemon and has a name
4
4
  class Trainer
5
- attr_reader :name, :team, :in_battle_pokemon
5
+ attr_reader :name, :team, :active_in_battle_pokemon
6
6
 
7
- def initialize(name, team)
7
+ def initialize(name, pokemon)
8
8
  @name = name
9
- team.each { |p| p.trainer = self }
10
- @team = team
11
- @in_battle_pokemon = []
9
+ pokemon.each { |p| p.trainer = self }
10
+ @team = pokemon.map { |p| Oakdex::Battle::InBattlePokemon.new(p) }
11
+ @active_in_battle_pokemon = []
12
12
  end
13
13
 
14
14
  def fainted?
15
- @team.all? { |p| p.current_hp.zero? }
15
+ @team.all?(&:fainted?)
16
16
  end
17
17
 
18
18
  def send_to_battle(pokemon, side)
19
- @in_battle_pokemon << InBattlePokemon.new(pokemon,
20
- side, side.next_position)
19
+ @active_in_battle_pokemon << ActiveInBattlePokemon.new(
20
+ pokemon,
21
+ side, side.next_position)
21
22
  side.add_to_log 'sends_to_battle', name, pokemon.name
22
23
  end
23
24
 
24
25
  def remove_from_battle(pokemon, side)
25
- ibp_to_remove = @in_battle_pokemon.find { |ibp| ibp.pokemon == pokemon }
26
+ ibp_to_remove = @active_in_battle_pokemon
27
+ .find { |ibp| ibp.pokemon == pokemon }
26
28
  pokemon.reset_stats
27
29
  pokemon.status_conditions.each do |s|
28
30
  s.after_switched_out(ibp_to_remove.battle)
29
31
  end
30
- @in_battle_pokemon -= [ibp_to_remove]
32
+ @active_in_battle_pokemon -= [ibp_to_remove]
31
33
  side.add_to_log 'removes_from_battle', name, pokemon.name
32
34
  end
33
35
 
34
36
  def remove_fainted
35
- @in_battle_pokemon.each do |ibp|
37
+ @active_in_battle_pokemon.each do |ibp|
36
38
  next unless ibp.fainted?
37
39
  ibp.battle.add_to_log('pokemon_fainted', name, ibp.pokemon.name)
38
40
  ibp.pokemon.status_conditions
39
41
  .each { |s| s.after_fainted(ibp.battle) }
40
42
  end
41
- @in_battle_pokemon = @in_battle_pokemon.reject(&:fainted?)
43
+ @active_in_battle_pokemon = @active_in_battle_pokemon.reject(&:fainted?)
42
44
  end
43
45
 
44
46
  def left_pokemon_in_team
45
- @team.select { |p| !p.current_hp.zero? } -
46
- @in_battle_pokemon.map(&:pokemon)
47
+ @team.select { |p| !p.fainted? } -
48
+ @active_in_battle_pokemon.map(&:pokemon)
47
49
  end
48
50
  end
49
51
  end
@@ -19,7 +19,7 @@ module Oakdex
19
19
 
20
20
  ordered_actions.each do |action|
21
21
  next unless valid_target?(action)
22
- next if action.pokemon && action.pokemon.current_hp.zero?
22
+ next if action.pokemon && action.pokemon.fainted?
23
23
  action.execute(self)
24
24
  end
25
25
 
@@ -36,7 +36,7 @@ module Oakdex
36
36
  end
37
37
 
38
38
  def status_conditions
39
- sides.flat_map(&:in_battle_pokemon)
39
+ sides.flat_map(&:active_in_battle_pokemon)
40
40
  .map(&:pokemon)
41
41
  .flat_map(&:status_conditions)
42
42
  end
@@ -44,7 +44,7 @@ module Oakdex
44
44
  def valid_target?(action)
45
45
  targets = action.target.is_a?(Array) ? action.target : [action.target]
46
46
  targets.all? do |target|
47
- !target.nil? && !target.current_hp.zero?
47
+ !target.nil? && !target.fainted?
48
48
  end
49
49
  end
50
50
 
@@ -21,32 +21,32 @@ module Oakdex
21
21
  private
22
22
 
23
23
  def valid_move_actions_for(trainer)
24
- trainer.in_battle_pokemon.flat_map(&:valid_move_actions)
24
+ trainer.active_in_battle_pokemon.flat_map(&:valid_move_actions)
25
25
  end
26
26
 
27
27
  def valid_recall_actions_for(trainer)
28
28
  trainer.left_pokemon_in_team.flat_map do |pokemon|
29
29
  pokemon_per_trainer.times.map do |position|
30
30
  recall_action(trainer,
31
- trainer.in_battle_pokemon[position],
31
+ trainer.active_in_battle_pokemon[position],
32
32
  pokemon)
33
33
  end.compact
34
34
  end
35
35
  end
36
36
 
37
- def recall_action(trainer, in_battle_pokemon, target)
38
- return if !recall_action_valid?(trainer, in_battle_pokemon, target) ||
37
+ def recall_action(trainer, active_ibp, target)
38
+ return if !recall_action_valid?(trainer, active_ibp, target) ||
39
39
  recall_action_for?(target)
40
40
  {
41
41
  action: 'recall',
42
- pokemon: in_battle_pokemon&.position || side(trainer).next_position,
42
+ pokemon: active_ibp&.position || side(trainer).next_position,
43
43
  target: target
44
44
  }
45
45
  end
46
46
 
47
- def recall_action_valid?(trainer, in_battle_pokemon, _target)
48
- if in_battle_pokemon
49
- !in_battle_pokemon.action_added?
47
+ def recall_action_valid?(trainer, active_in_battle_pokemon, _target)
48
+ if active_in_battle_pokemon
49
+ !active_in_battle_pokemon.action_added?
50
50
  else
51
51
  next_position = side(trainer).next_position
52
52
  next_position && !recall_action_for_position?(next_position)
@@ -70,11 +70,11 @@ module Oakdex
70
70
  end
71
71
 
72
72
  def no_battle_pokemon?(trainer)
73
- other_sides(trainer).all? { |s| s.in_battle_pokemon.empty? }
73
+ other_sides(trainer).all? { |s| s.active_in_battle_pokemon.empty? }
74
74
  end
75
75
 
76
76
  def own_battle_pokemon?(trainer)
77
- !side(trainer).in_battle_pokemon.empty?
77
+ !side(trainer).active_in_battle_pokemon.empty?
78
78
  end
79
79
 
80
80
  def other_sides(trainer)
@@ -1,5 +1,5 @@
1
1
  module Oakdex
2
2
  class Battle
3
- VERSION = '0.0.2'
3
+ VERSION = '0.1.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oakdex-battle
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jalyna Schroeder
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-13 00:00:00.000000000 Z
11
+ date: 2019-01-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: oakdex-pokedex
14
+ name: oakdex-pokemon
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 0.2.2
19
+ version: 0.0.4
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 0.2.2
26
+ version: 0.0.4
27
27
  description: Pokémon Battle Engine Gen 7 Gem, based on oakdex-pokedex
28
28
  email: jalyna.schroeder@gmail.com
29
29
  executables: []
@@ -34,14 +34,10 @@ files:
34
34
  - lib/oakdex.rb
35
35
  - lib/oakdex/battle.rb
36
36
  - lib/oakdex/battle/action.rb
37
- - lib/oakdex/battle/breeding.rb
37
+ - lib/oakdex/battle/active_in_battle_pokemon.rb
38
38
  - lib/oakdex/battle/damage.rb
39
39
  - lib/oakdex/battle/in_battle_pokemon.rb
40
- - lib/oakdex/battle/move.rb
41
40
  - lib/oakdex/battle/move_execution.rb
42
- - lib/oakdex/battle/pokemon.rb
43
- - lib/oakdex/battle/pokemon_factory.rb
44
- - lib/oakdex/battle/pokemon_stat.rb
45
41
  - lib/oakdex/battle/side.rb
46
42
  - lib/oakdex/battle/status_conditions.rb
47
43
  - lib/oakdex/battle/status_conditions/badly_poisoned.rb
@@ -1,109 +0,0 @@
1
- module Oakdex
2
- class Battle
3
- # Pokemon Breeding
4
- class Breeding
5
- class << self
6
- def compatible?(pokemon1, pokemon2)
7
- new(pokemon1, pokemon2).compatible?
8
- end
9
-
10
- def chance_in_percentage(pokemon1, pokemon2)
11
- new(pokemon1, pokemon2).chance_in_percentage
12
- end
13
-
14
- def breed(pokemon1, pokemon2)
15
- new(pokemon1, pokemon2).child
16
- end
17
- end
18
-
19
- def initialize(pokemon1, pokemon2)
20
- @female = pokemon1.gender == 'female' ? pokemon1 : pokemon2
21
- @male = ([pokemon1, pokemon2] - [@female]).first
22
- end
23
-
24
- def compatible?
25
- (opposite_gender? && same_egg_group? && !any_undiscovered?) ||
26
- (exactly_one_is_ditto? && non_ditto_is_discovered?)
27
- end
28
-
29
- def chance_in_percentage
30
- return 0 unless compatible?
31
- return 50 if same_species?
32
- 20
33
- end
34
-
35
- def child
36
- return unless compatible?
37
- Oakdex::Battle::Pokemon.create(child_species.name,
38
- level: 1,
39
- additional_moves: enabled_egg_moves
40
- )
41
- end
42
-
43
- private
44
-
45
- def child_species
46
- @child_species ||=
47
- lowest_in_evolutionary_chain(non_ditto_or_female.species)
48
- end
49
-
50
- def enabled_egg_moves
51
- egg_moves & parent_moves
52
- end
53
-
54
- def parent_moves
55
- @female.moves.map(&:name) + @male.moves.map(&:name)
56
- end
57
-
58
- def egg_moves
59
- child_species.learnset
60
- .map { |l| l['egg_move'] ? l['move'] : nil }
61
- .compact
62
- end
63
-
64
- def lowest_in_evolutionary_chain(species)
65
- # TODO: take incenses into account
66
- lowest_species = species
67
- while lowest_species.evolution_from
68
- lowest_species = Oakdex::Pokedex::Pokemon
69
- .find!(lowest_species.evolution_from)
70
- end
71
- lowest_species
72
- end
73
-
74
- def exactly_one_is_ditto?
75
- (@female.name == 'Ditto') ^ (@male.name == 'Ditto')
76
- end
77
-
78
- def non_ditto_is_discovered?
79
- !non_ditto.species.egg_groups.include?('Undiscovered')
80
- end
81
-
82
- def non_ditto
83
- return unless exactly_one_is_ditto?
84
- @female.name == 'Ditto' ? @male : @female
85
- end
86
-
87
- def non_ditto_or_female
88
- non_ditto || @female
89
- end
90
-
91
- def opposite_gender?
92
- @female.gender == 'female' && @male.gender == 'male'
93
- end
94
-
95
- def same_egg_group?
96
- !(@female.species.egg_groups & @male.species.egg_groups).empty?
97
- end
98
-
99
- def any_undiscovered?
100
- (@female.species.egg_groups + @male.species.egg_groups)
101
- .include?('Undiscovered')
102
- end
103
-
104
- def same_species?
105
- @female.name == @male.name
106
- end
107
- end
108
- end
109
- end
@@ -1,27 +0,0 @@
1
- require 'forwardable'
2
-
3
- module Oakdex
4
- class Battle
5
- # Represents Pokemon Move with PP
6
- class Move
7
- extend Forwardable
8
-
9
- attr_reader :max_pp
10
- attr_accessor :pp
11
-
12
- def_delegators :@move_type, :target, :priority, :accuracy,
13
- :category, :power, :type, :stat_modifiers,
14
- :in_battle_properties
15
-
16
- def initialize(move_type, pp, max_pp)
17
- @move_type = move_type
18
- @pp = pp
19
- @max_pp = max_pp
20
- end
21
-
22
- def name
23
- @move_type.names['en']
24
- end
25
- end
26
- end
27
- end
@@ -1,173 +0,0 @@
1
- require 'forwardable'
2
- require 'oakdex/battle/pokemon_stat'
3
- require 'oakdex/battle/move'
4
- require 'oakdex/battle/pokemon_factory'
5
- require 'oakdex/battle/status_conditions'
6
-
7
- module Oakdex
8
- class Battle
9
- # Represents detailed pokemon instance
10
- class Pokemon
11
- extend Forwardable
12
-
13
- BATTLE_STATS = %i[hp atk def sp_atk sp_def speed]
14
- OTHER_STATS = %i[accuracy evasion critical_hit]
15
- STATUS_CONDITIONS = {
16
- 'poison' => StatusConditions::Poison,
17
- 'burn' => StatusConditions::Burn,
18
- 'freeze' => StatusConditions::Freeze,
19
- 'paralysis' => StatusConditions::Paralysis,
20
- 'badly_poisoned' => StatusConditions::BadlyPoisoned,
21
- 'sleep' => StatusConditions::Sleep
22
- }
23
-
24
- def_delegators :@species, :types
25
-
26
- attr_accessor :trainer
27
- attr_reader :species
28
-
29
- def self.create(species_name, options = {})
30
- species = Oakdex::Pokedex::Pokemon.find!(species_name)
31
- Oakdex::Battle::PokemonFactory.create(species, options)
32
- end
33
-
34
- def initialize(species, attributes = {})
35
- @species = species
36
- @attributes = attributes
37
- @attributes[:status_conditions] ||= []
38
- reset_stats
39
- end
40
-
41
- def name
42
- @species.names['en']
43
- end
44
-
45
- def gender
46
- @attributes[:gender]
47
- end
48
-
49
- def moves
50
- @attributes[:moves]
51
- end
52
-
53
- def current_hp
54
- @attributes[:hp]
55
- end
56
-
57
- def status_conditions
58
- @attributes[:status_conditions]
59
- end
60
-
61
- def moves_with_pp
62
- moves.select { |m| m.pp > 0 }
63
- end
64
-
65
- def change_hp_by(hp_change)
66
- @attributes[:hp] = if hp_change < 0
67
- [@attributes[:hp] + hp_change, 0].max
68
- else
69
- [@attributes[:hp] + hp_change, hp].min
70
- end
71
- end
72
-
73
- def change_pp_by(move_name, pp_change)
74
- move = moves.find { |m| m.name == move_name }
75
- return unless move
76
- move.pp = if pp_change < 0
77
- [move.pp + pp_change, 0].max
78
- else
79
- [move.pp + pp_change, move.max_pp].min
80
- end
81
- end
82
-
83
- def change_stat_by(stat, change_by)
84
- modifiers = stage_multipliers(stat)
85
- stat_before = @stat_modifiers[stat]
86
- min_value = modifiers.keys.first
87
- max_value = modifiers.keys.last
88
- @stat_modifiers[stat] = if change_by < 0
89
- [stat_before + change_by, min_value].max
90
- else
91
- [stat_before + change_by, max_value].min
92
- end
93
- stat_before != @stat_modifiers[stat]
94
- end
95
-
96
- def add_status_condition(condition_name)
97
- @attributes[:status_conditions] << status_condition(condition_name)
98
- end
99
-
100
- def remove_status_condition(condition)
101
- @attributes[:status_conditions] = @attributes[:status_conditions]
102
- .reject { |s| s == condition }
103
- end
104
-
105
- def reset_stats
106
- @stat_modifiers = (BATTLE_STATS + OTHER_STATS - %i[hp]).map do |stat|
107
- [stat, 0]
108
- end.to_h
109
- end
110
-
111
- def level
112
- PokemonStat.level_by_exp(@species.leveling_rate, @attributes[:exp])
113
- end
114
-
115
- def accuracy
116
- stage(:accuracy)
117
- end
118
-
119
- def evasion
120
- stage(:evasion)
121
- end
122
-
123
- def critical_hit_prob
124
- stage(:critical_hit)
125
- end
126
-
127
- BATTLE_STATS.each do |stat|
128
- define_method stat do
129
- (initial_stat(stat) * stage(stat) *
130
- status_condition_modifier(stat)).to_i
131
- end
132
- end
133
-
134
- private
135
-
136
- def status_condition_modifier(stat)
137
- status_conditions.reduce(1.0) do |modifier, condition|
138
- condition.stat_modifier(stat) * modifier
139
- end
140
- end
141
-
142
- def status_condition(condition_name)
143
- STATUS_CONDITIONS[condition_name].new(self)
144
- end
145
-
146
- def stage(stat)
147
- multipliers = stage_multipliers(stat)
148
- multipliers[@stat_modifiers[stat] || 0]
149
- end
150
-
151
- def initial_stat(stat)
152
- PokemonStat.initial_stat(stat,
153
- level: level,
154
- nature: @attributes[:nature],
155
- iv: @attributes[:iv],
156
- ev: @attributes[:ev],
157
- base_stats: @species.base_stats
158
- )
159
- end
160
-
161
- def stage_multipliers(stat)
162
- case stat
163
- when :evasion, :accuracy
164
- PokemonStat::STAGE_MULTIPLIERS_ACC_EVA
165
- when :critical_hit
166
- PokemonStat::STAGE_MULTIPLIERS_CRITICAL_HIT
167
- else
168
- PokemonStat::STAGE_MULTIPLIERS
169
- end
170
- end
171
- end
172
- end
173
- end