oakdex-battle 0.0.1
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.
- checksums.yaml +7 -0
- data/README.md +103 -0
- data/lib/oakdex.rb +3 -0
- data/lib/oakdex/battle.rb +111 -0
- data/lib/oakdex/battle/action.rb +115 -0
- data/lib/oakdex/battle/damage.rb +99 -0
- data/lib/oakdex/battle/in_battle_pokemon.rb +159 -0
- data/lib/oakdex/battle/move.rb +27 -0
- data/lib/oakdex/battle/move_execution.rb +148 -0
- data/lib/oakdex/battle/pokemon.rb +168 -0
- data/lib/oakdex/battle/pokemon_factory.rb +118 -0
- data/lib/oakdex/battle/pokemon_stat.rb +109 -0
- data/lib/oakdex/battle/side.rb +76 -0
- data/lib/oakdex/battle/status_conditions.rb +16 -0
- data/lib/oakdex/battle/status_conditions/badly_poisoned.rb +36 -0
- data/lib/oakdex/battle/status_conditions/base.rb +36 -0
- data/lib/oakdex/battle/status_conditions/burn.rb +26 -0
- data/lib/oakdex/battle/status_conditions/freeze.rb +36 -0
- data/lib/oakdex/battle/status_conditions/non_volatile.rb +12 -0
- data/lib/oakdex/battle/status_conditions/paralysis.rb +26 -0
- data/lib/oakdex/battle/status_conditions/poison.rb +22 -0
- data/lib/oakdex/battle/status_conditions/sleep.rb +37 -0
- data/lib/oakdex/battle/trainer.rb +50 -0
- data/lib/oakdex/battle/turn.rb +70 -0
- data/lib/oakdex/battle/valid_action_service.rb +89 -0
- data/lib/oakdex/battle/version.rb +5 -0
- metadata +82 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ecd31f627a41112b511d36b3f229b4f39f16c50db2f30d2152d6d8be6c2a4084
|
4
|
+
data.tar.gz: c4d2ff60f0bc64a148b278f8dc9493a71191298672d0f365fa0a5ce2a3e8ab61
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: eae5231ca258390c2d3b3f2af6979b34f66c9615ed6e55c7c636d96267cdae3f76a8a86475f19a819aa0bdda1746f6b3efb8f84c0547cbb7290099efd6889ba4
|
7
|
+
data.tar.gz: 5a22eb518390c80e4eb7d5ab086ef744588a11de5260043050958a2930286dca62a88efe27f957bd6fccdc2c47c397325a11f5fa143fc5ff6d04399d4f11a2b5
|
data/README.md
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
# <img src="https://v20.imgup.net/oakdex_logfbad.png" alt="fixer" width=282>
|
2
|
+
|
3
|
+
[](https://travis-ci.org/jalyna/oakdex-battle) [](https://codeclimate.com/github/jalyna/oakdex-battle/maintainability) [](https://codeclimate.com/github/jalyna/oakdex-battle/test_coverage)
|
4
|
+
|
5
|
+
Based on [oakdex-pokedex](https://github.com/jalyna/oakdex-pokedex).
|
6
|
+
|
7
|
+
## Getting Started
|
8
|
+
|
9
|
+
### 1 vs. 1
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
require 'oakdex/battle'
|
13
|
+
|
14
|
+
pok1 = Oakdex::Battle::Pokemon.create('Pikachu', level: 10)
|
15
|
+
pok2 = Oakdex::Battle::Pokemon.create('Bulbasaur', {
|
16
|
+
exp: 120,
|
17
|
+
gender: 'female',
|
18
|
+
ability: 'Soundproof',
|
19
|
+
nature: 'Bashful',
|
20
|
+
item: 'Earth Plate',
|
21
|
+
hp: 2,
|
22
|
+
iv: {
|
23
|
+
hp: 8,
|
24
|
+
atk: 12,
|
25
|
+
def: 31,
|
26
|
+
sp_atk: 12,
|
27
|
+
sp_def: 5,
|
28
|
+
speed: 14
|
29
|
+
},
|
30
|
+
ev: {
|
31
|
+
hp: 8,
|
32
|
+
atk: 12,
|
33
|
+
def: 99,
|
34
|
+
sp_atk: 4,
|
35
|
+
sp_def: 12,
|
36
|
+
speed: 14
|
37
|
+
},
|
38
|
+
moves: [
|
39
|
+
['Swords Dance', 12, 30],
|
40
|
+
['Cut', 40, 44]
|
41
|
+
]
|
42
|
+
})
|
43
|
+
|
44
|
+
trainer1 = Oakdex::Battle::Trainer.new('Ash', [pok1])
|
45
|
+
trainer2 = Oakdex::Battle::Trainer.new('Misty', [pok2])
|
46
|
+
|
47
|
+
battle = Oakdex::Battle.new(trainer1, trainer2)
|
48
|
+
battle.continue # => true
|
49
|
+
battle.log.size # => 1
|
50
|
+
battle.log.last # => [['sends_to_battle', 'Ash', 'Pikachu'], ['sends_to_battle', 'Misty', 'Bulbasaur']]
|
51
|
+
battle.arena # => Snapshot of current state as Hash
|
52
|
+
battle.finished? # => false
|
53
|
+
battle.valid_actions_for(trainer1) # => [{ action: 'move', pokemon: pok1, move: <Move>, target: pok2 }, ...]
|
54
|
+
|
55
|
+
battle.add_action(trainer1, { action: 'move', pokemon: pok1, move: <Move>, target: pok2 }) # => false
|
56
|
+
|
57
|
+
battle.add_action(trainer1, { action: 'move', pokemon: pok1, move: <Move>, target: pok2 }) # => true
|
58
|
+
|
59
|
+
battle.valid_actions_for(trainer1) # => []
|
60
|
+
battle.continue # => false
|
61
|
+
battle.simulate_action(trainer2) # => true
|
62
|
+
battle.valid_actions_for(trainer2) # => []
|
63
|
+
battle.continue # => true
|
64
|
+
|
65
|
+
battle.log.size # => 2
|
66
|
+
battle.log.last # => [['uses_move', 'Ash', 'Pikachu', 'Thunder Shock'], ['received_damage', 'Misty', 'Bulbasaur', 'Thunder Shock'], ['uses_move', 'Misty', 'Bulbasaur', 'Leech Seed'], ['move_failed', 'Misty', 'Bulbasaur', 'Leech Seed']]
|
67
|
+
|
68
|
+
# ...
|
69
|
+
|
70
|
+
battle.finished? # => true
|
71
|
+
battle.winner # => trainer1
|
72
|
+
```
|
73
|
+
|
74
|
+
|
75
|
+
### Other Battle types
|
76
|
+
|
77
|
+
```ruby
|
78
|
+
pok3 = Oakdex::Battle::Pokemon.create('Altaria', level: 20)
|
79
|
+
pok4 = Oakdex::Battle::Pokemon.create('Elekid', level: 14)
|
80
|
+
trainer1 = Oakdex::Battle::Trainer.new('Ash', [pok1, pok3, pok9])
|
81
|
+
trainer2 = Oakdex::Battle::Trainer.new('Misty', [pok2, pok4, pok10])
|
82
|
+
trainer3 = Oakdex::Battle::Trainer.new('Brock', [pok5, pok6])
|
83
|
+
trainer4 = Oakdex::Battle::Trainer.new('Erika', [pok7, pok8])
|
84
|
+
|
85
|
+
# 2 vs. 2
|
86
|
+
battle = Oakdex::Battle.new([trainer1], [trainer2], pokemon_per_side: 2)
|
87
|
+
# 3 vs. 3
|
88
|
+
battle = Oakdex::Battle.new([trainer1], [trainer2], pokemon_per_side: 3)
|
89
|
+
# 2 vs. 2 (1 pokemon each trainer)
|
90
|
+
battle = Oakdex::Battle.new([trainer1, trainer3], [trainer2, trainer4])
|
91
|
+
```
|
92
|
+
|
93
|
+
## Contributing
|
94
|
+
|
95
|
+
I would be happy if you want to add your contribution to the project. In order to contribute, you just have to fork this repository.
|
96
|
+
|
97
|
+
## License
|
98
|
+
|
99
|
+
MIT License. See the included MIT-LICENSE file.
|
100
|
+
|
101
|
+
## Credits
|
102
|
+
|
103
|
+
Logo Icon by [Roundicons Freebies](http://www.flaticon.com/authors/roundicons-freebies).
|
data/lib/oakdex.rb
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'oakdex/pokedex'
|
2
|
+
|
3
|
+
require 'oakdex/battle/pokemon'
|
4
|
+
require 'oakdex/battle/trainer'
|
5
|
+
require 'oakdex/battle/move_execution'
|
6
|
+
require 'oakdex/battle/action'
|
7
|
+
require 'oakdex/battle/damage'
|
8
|
+
require 'oakdex/battle/turn'
|
9
|
+
require 'oakdex/battle/valid_action_service'
|
10
|
+
require 'oakdex/battle/side'
|
11
|
+
require 'oakdex/battle/in_battle_pokemon'
|
12
|
+
|
13
|
+
module Oakdex
|
14
|
+
# Represents battle, with has n turns and m sides
|
15
|
+
class Battle
|
16
|
+
attr_reader :log, :actions, :team1, :team2,
|
17
|
+
:sides, :current_log
|
18
|
+
|
19
|
+
def initialize(team1, team2, options = {})
|
20
|
+
@team1 = team1.is_a?(Array) ? team1 : [team1]
|
21
|
+
@team2 = team2.is_a?(Array) ? team2 : [team2]
|
22
|
+
@options = options
|
23
|
+
@sides = []
|
24
|
+
@log = []
|
25
|
+
@current_log = []
|
26
|
+
@actions = []
|
27
|
+
@turns = []
|
28
|
+
end
|
29
|
+
|
30
|
+
def pokemon_per_side
|
31
|
+
@options[:pokemon_per_side] || @team1.size
|
32
|
+
end
|
33
|
+
|
34
|
+
def arena
|
35
|
+
{ sides: sides }
|
36
|
+
end
|
37
|
+
|
38
|
+
def valid_actions_for(trainer)
|
39
|
+
valid_action_service.valid_actions_for(trainer)
|
40
|
+
end
|
41
|
+
|
42
|
+
def add_action(trainer, action)
|
43
|
+
return false unless valid_actions_for(trainer).include?(action)
|
44
|
+
@actions << Action.new(trainer, action)
|
45
|
+
true
|
46
|
+
end
|
47
|
+
|
48
|
+
def simulate_action(trainer)
|
49
|
+
valid_actions = valid_actions_for(trainer)
|
50
|
+
return false if valid_actions.empty?
|
51
|
+
add_action(trainer, valid_actions.sample)
|
52
|
+
end
|
53
|
+
|
54
|
+
def continue
|
55
|
+
return start if sides.empty?
|
56
|
+
return false unless trainers.all? { |t| valid_actions_for(t).empty? }
|
57
|
+
execute_actions
|
58
|
+
true
|
59
|
+
end
|
60
|
+
|
61
|
+
def finished?
|
62
|
+
!fainted_sides.empty?
|
63
|
+
end
|
64
|
+
|
65
|
+
def winner
|
66
|
+
return if fainted_sides.empty?
|
67
|
+
(sides - fainted_sides).flat_map(&:trainers)
|
68
|
+
end
|
69
|
+
|
70
|
+
def add_to_log(*args)
|
71
|
+
@current_log << args.to_a
|
72
|
+
end
|
73
|
+
|
74
|
+
def remove_fainted
|
75
|
+
sides.each(&:remove_fainted)
|
76
|
+
end
|
77
|
+
|
78
|
+
private
|
79
|
+
|
80
|
+
def valid_action_service
|
81
|
+
@valid_action_service ||= ValidActionService.new(self)
|
82
|
+
end
|
83
|
+
|
84
|
+
def fainted_sides
|
85
|
+
sides.select(&:fainted?)
|
86
|
+
end
|
87
|
+
|
88
|
+
def start
|
89
|
+
@sides = [@team1, @team2].map do |team|
|
90
|
+
Side.new(self, team).tap(&:send_to_battle)
|
91
|
+
end
|
92
|
+
finish_turn
|
93
|
+
true
|
94
|
+
end
|
95
|
+
|
96
|
+
def execute_actions
|
97
|
+
@turns << Turn.new(self, @actions).tap(&:execute)
|
98
|
+
finish_turn
|
99
|
+
end
|
100
|
+
|
101
|
+
def trainers
|
102
|
+
sides.flat_map(&:trainers)
|
103
|
+
end
|
104
|
+
|
105
|
+
def finish_turn
|
106
|
+
@log << @current_log
|
107
|
+
@current_log = []
|
108
|
+
@actions = []
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Oakdex
|
4
|
+
class Battle
|
5
|
+
# Represents one Action. One turn has many actions.
|
6
|
+
class Action
|
7
|
+
RECALL_PRIORITY = 6
|
8
|
+
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
def_delegators :@turn, :battle
|
12
|
+
|
13
|
+
attr_reader :trainer, :damage, :turn
|
14
|
+
|
15
|
+
def initialize(trainer, attributes)
|
16
|
+
@trainer = trainer
|
17
|
+
@attributes = attributes
|
18
|
+
end
|
19
|
+
|
20
|
+
def priority
|
21
|
+
move&.priority || RECALL_PRIORITY
|
22
|
+
end
|
23
|
+
|
24
|
+
def pokemon
|
25
|
+
recall? ? pokemon_by_position : @attributes[:pokemon]
|
26
|
+
end
|
27
|
+
|
28
|
+
def pokemon_position
|
29
|
+
recall? ? @attributes[:pokemon] : nil
|
30
|
+
end
|
31
|
+
|
32
|
+
def target
|
33
|
+
recall? ? @attributes[:target] : targets
|
34
|
+
end
|
35
|
+
|
36
|
+
def type
|
37
|
+
@attributes[:action]
|
38
|
+
end
|
39
|
+
|
40
|
+
def move
|
41
|
+
@attributes[:move]
|
42
|
+
end
|
43
|
+
|
44
|
+
def hitting_probability
|
45
|
+
((move.accuracy / 100.0) * (pokemon.accuracy / target.evasion)) * 1000
|
46
|
+
end
|
47
|
+
|
48
|
+
def hitting?
|
49
|
+
@hitting = rand(1..1000) <= hitting_probability ? 1 : 0
|
50
|
+
@hitting == 1
|
51
|
+
end
|
52
|
+
|
53
|
+
def execute(turn)
|
54
|
+
@turn = turn
|
55
|
+
return execute_recall if type == 'recall'
|
56
|
+
targets.each { |t| MoveExecution.new(self, t).execute }
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def targets
|
62
|
+
target_list.map do |target|
|
63
|
+
target_by_position(target[0], target[1])
|
64
|
+
end.compact
|
65
|
+
end
|
66
|
+
|
67
|
+
def target_list
|
68
|
+
list = @attributes[:target]
|
69
|
+
reutrn [] if list.empty?
|
70
|
+
list = [list] unless list[0].is_a?(Array)
|
71
|
+
list
|
72
|
+
end
|
73
|
+
|
74
|
+
def recall?
|
75
|
+
type == 'recall'
|
76
|
+
end
|
77
|
+
|
78
|
+
def pokemon_by_position
|
79
|
+
trainer.in_battle_pokemon
|
80
|
+
.find { |ibp| ibp.position == @attributes[:pokemon] }&.pokemon
|
81
|
+
end
|
82
|
+
|
83
|
+
def target_by_position(side, position)
|
84
|
+
side.in_battle_pokemon
|
85
|
+
.find { |ibp| ibp.position == position }&.pokemon
|
86
|
+
end
|
87
|
+
|
88
|
+
def side
|
89
|
+
battle.sides.find { |s| s.trainer_on_side?(trainer) }
|
90
|
+
end
|
91
|
+
|
92
|
+
def execute_recall
|
93
|
+
add_recalls_log
|
94
|
+
if pokemon
|
95
|
+
trainer.remove_from_battle(pokemon, side)
|
96
|
+
trainer.send_to_battle(target, side)
|
97
|
+
else
|
98
|
+
trainer.send_to_battle(target, side)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def add_log(*args)
|
103
|
+
battle.add_to_log(*args)
|
104
|
+
end
|
105
|
+
|
106
|
+
def add_recalls_log
|
107
|
+
if pokemon
|
108
|
+
add_log 'recalls', trainer.name, pokemon.name, target.name
|
109
|
+
else
|
110
|
+
add_log 'recalls_for_fainted', trainer.name, target.name
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Oakdex
|
4
|
+
class Battle
|
5
|
+
# Calculates damage
|
6
|
+
class Damage
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
def_delegators :@action, :move, :pokemon, :target
|
10
|
+
|
11
|
+
def initialize(turn, action)
|
12
|
+
@turn = turn
|
13
|
+
@action = action
|
14
|
+
end
|
15
|
+
|
16
|
+
def damage
|
17
|
+
(simple_damage * modifier).to_i
|
18
|
+
end
|
19
|
+
|
20
|
+
def critical?
|
21
|
+
@critical ||= rand(1..1000) <= pokemon.critical_hit_prob * 1000 ? 1 : 0
|
22
|
+
@critical == 1
|
23
|
+
end
|
24
|
+
|
25
|
+
def effective?
|
26
|
+
type_modifier > 1.0
|
27
|
+
end
|
28
|
+
|
29
|
+
def ineffective?
|
30
|
+
type_modifier < 1.0
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def modifier
|
36
|
+
target_modifier * weather_modifier * critical_hit_modifier *
|
37
|
+
random_modifier * stab_modifier * type_modifier *
|
38
|
+
burn_modifier * status_condition_modifier * other_modifiers
|
39
|
+
end
|
40
|
+
|
41
|
+
def status_condition_modifier
|
42
|
+
pokemon.status_conditions.reduce(1.0) do |modifier, condition|
|
43
|
+
modifier * condition.damage_modifier(@action)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def target_modifier
|
48
|
+
1.0 # TODO: 0.75 if move has more than one target
|
49
|
+
end
|
50
|
+
|
51
|
+
def weather_modifier
|
52
|
+
1.0 # TODO: 1.5 water at rain or fire at harsh sunlight, 0.5 vice versa
|
53
|
+
end
|
54
|
+
|
55
|
+
def critical_hit_modifier
|
56
|
+
if critical?
|
57
|
+
1.5
|
58
|
+
else
|
59
|
+
1.0
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def random_modifier
|
64
|
+
@random_modifier ||= rand(850..1000) / 1000.0
|
65
|
+
end
|
66
|
+
|
67
|
+
def stab_modifier
|
68
|
+
pokemon.types.include?(move.type) ? 1.5 : 1.0
|
69
|
+
end
|
70
|
+
|
71
|
+
def type_modifier
|
72
|
+
type_data = Oakdex::Pokedex::Type.find!(move.type)
|
73
|
+
target.types.reduce(1.0) do |factor, type|
|
74
|
+
factor * type_data.effectivness[type]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def burn_modifier
|
79
|
+
1.0 # TODO: 0.5 if attack is burning and physical move
|
80
|
+
end
|
81
|
+
|
82
|
+
def other_modifiers
|
83
|
+
1.0 # TODO: See other https://bulbapedia.bulbagarden.net/wiki/Damage
|
84
|
+
end
|
85
|
+
|
86
|
+
def def_and_atk
|
87
|
+
if move.category == 'special'
|
88
|
+
(pokemon.sp_atk.to_f / target.sp_def.to_f)
|
89
|
+
else
|
90
|
+
(pokemon.atk.to_f / target.def.to_f)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def simple_damage
|
95
|
+
(((2 * pokemon.level) / 5.0 + 2) * move.power * def_and_atk) / 50 + 2
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Oakdex
|
4
|
+
class Battle
|
5
|
+
# Represents a pokemon that is in battle
|
6
|
+
class InBattlePokemon
|
7
|
+
extend Forwardable
|
8
|
+
|
9
|
+
def_delegators :@pokemon, :current_hp, :moves_with_pp
|
10
|
+
def_delegators :@side, :battle
|
11
|
+
|
12
|
+
attr_reader :pokemon, :position, :side
|
13
|
+
|
14
|
+
def initialize(pokemon, side, position = 0)
|
15
|
+
@pokemon = pokemon
|
16
|
+
@side = side
|
17
|
+
@position = position
|
18
|
+
end
|
19
|
+
|
20
|
+
def fainted?
|
21
|
+
current_hp.zero?
|
22
|
+
end
|
23
|
+
|
24
|
+
def action_added?
|
25
|
+
actions.any? { |a| a.pokemon == pokemon }
|
26
|
+
end
|
27
|
+
|
28
|
+
def valid_move_actions
|
29
|
+
return [] if action_added?
|
30
|
+
moves = moves_with_pp
|
31
|
+
moves = [struggle_move] if moves_with_pp.empty?
|
32
|
+
moves.flat_map do |move|
|
33
|
+
targets_in_battle(move).map do |target|
|
34
|
+
{
|
35
|
+
action: 'move',
|
36
|
+
pokemon: pokemon,
|
37
|
+
move: move,
|
38
|
+
target: target
|
39
|
+
}
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def targets_in_battle(move)
|
47
|
+
available_targets(move).map do |targets|
|
48
|
+
if targets.last.is_a?(Array)
|
49
|
+
targets if targets_in_battle?(targets)
|
50
|
+
elsif target_in_battle?(targets)
|
51
|
+
targets
|
52
|
+
end
|
53
|
+
end.compact.reject(&:empty?)
|
54
|
+
end
|
55
|
+
|
56
|
+
def targets_in_battle?(targets)
|
57
|
+
targets.any? { |target| target[0].pokemon_in_battle?(target[1]) }
|
58
|
+
end
|
59
|
+
|
60
|
+
def target_in_battle?(target)
|
61
|
+
target[0].pokemon_in_battle?(target[1]) ||
|
62
|
+
(!target[0].pokemon_left? && target[1] == 0)
|
63
|
+
end
|
64
|
+
|
65
|
+
def struggle_move
|
66
|
+
@struggle_move ||= begin
|
67
|
+
move_type = Oakdex::Pokedex::Move.find('Struggle')
|
68
|
+
Oakdex::Battle::Move.new(move_type, move_type.pp, move_type.pp)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def available_targets(move)
|
73
|
+
with_target(move) || multiple_targets_adjacent(move) ||
|
74
|
+
multiple_targets(move) || []
|
75
|
+
end
|
76
|
+
|
77
|
+
def multiple_targets(move)
|
78
|
+
case move.target
|
79
|
+
when 'all_users' then [all_users]
|
80
|
+
when 'all_except_user' then [all_targets - [self_target]]
|
81
|
+
when 'all' then [all_targets]
|
82
|
+
when 'all_foes' then [all_foes]
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def multiple_targets_adjacent(move)
|
87
|
+
case move.target
|
88
|
+
when 'all_adjacent' then [adjacent]
|
89
|
+
when 'adjacent_foes_all' then [adjacent_foes]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def with_target(move)
|
94
|
+
case move.target
|
95
|
+
when 'user', 'user_and_random_adjacent_foe' then [self_target]
|
96
|
+
when 'target_adjacent_user_single' then adjacent_users
|
97
|
+
when 'target_adjacent_single' then adjacent
|
98
|
+
when 'target_user_or_adjacent_user'
|
99
|
+
[self_target] + adjacent_users
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def all_targets
|
104
|
+
all_foes + all_users
|
105
|
+
end
|
106
|
+
|
107
|
+
def target_adjacent_single
|
108
|
+
adjacent_foes + adjacent_users
|
109
|
+
end
|
110
|
+
|
111
|
+
def adjacent
|
112
|
+
adjacent_foes + adjacent_users
|
113
|
+
end
|
114
|
+
|
115
|
+
def self_target
|
116
|
+
[@side, position]
|
117
|
+
end
|
118
|
+
|
119
|
+
def adjacent_foes
|
120
|
+
[
|
121
|
+
[other_side, position - 1],
|
122
|
+
[other_side, position],
|
123
|
+
[other_side, position + 1]
|
124
|
+
].select { |t| t[1] >= 0 && t[1] < pokemon_per_side }
|
125
|
+
end
|
126
|
+
|
127
|
+
def adjacent_users
|
128
|
+
[
|
129
|
+
[@side, position - 1],
|
130
|
+
[@side, position + 1]
|
131
|
+
].select { |t| t[1] >= 0 && t[1] < pokemon_per_side }
|
132
|
+
end
|
133
|
+
|
134
|
+
def all_users
|
135
|
+
pokemon_per_side.times.map { |i| [@side, i] }
|
136
|
+
end
|
137
|
+
|
138
|
+
def all_foes
|
139
|
+
pokemon_per_side.times.map { |i| [other_side, i] }
|
140
|
+
end
|
141
|
+
|
142
|
+
def pokemon_per_side
|
143
|
+
battle.pokemon_per_side
|
144
|
+
end
|
145
|
+
|
146
|
+
def other_side
|
147
|
+
other_sides.first
|
148
|
+
end
|
149
|
+
|
150
|
+
def other_sides
|
151
|
+
battle.sides - [@side]
|
152
|
+
end
|
153
|
+
|
154
|
+
def actions
|
155
|
+
battle.actions
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|