oakdex-pokemon 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 +73 -0
- data/lib/oakdex.rb +3 -0
- data/lib/oakdex/pokemon.rb +122 -0
- data/lib/oakdex/pokemon/factory.rb +153 -0
- data/lib/oakdex/pokemon/move.rb +27 -0
- data/lib/oakdex/pokemon/stat.rb +70 -0
- data/lib/oakdex/pokemon/version.rb +5 -0
- metadata +64 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9e56029d18b8aa9b927c1f4c27516793cc715743
|
4
|
+
data.tar.gz: 167153d816542a894030ba366b252f43dec22f06
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1022ae90f08279c4b6d95fbaed0aba5cd0b24c94ac77ecc096118585697b761c98d37204bef1f1dc8900e9d2efd63b7d49a3d01d91122a70a92cecdd0ce95ba6
|
7
|
+
data.tar.gz: 14e9093e9c5095bedfa3addd8b7576566db1091cbd977c2a3c15139e7b9ce792d94a41dc1c3d823659189fbc100faf0cab78b8990a66633eb8384bae009f11bb
|
data/README.md
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# <img src="https://v20.imgup.net/oakdex_logfbad.png" alt="fixer" width=282>
|
2
|
+
|
3
|
+
[](https://badge.fury.io/rb/oakdex-pokemon) [](https://travis-ci.org/jalyna/oakdex-pokemon) [](https://codeclimate.com/github/jalyna/oakdex-pokemon/maintainability) [](https://codeclimate.com/github/jalyna/oakdex-pokemon/test_coverage)
|
4
|
+
|
5
|
+
Based on [oakdex-pokedex](https://github.com/jalyna/oakdex-pokedex).
|
6
|
+
|
7
|
+
Used as a representation for Pokémon across other Projects like [oakdex-battle](https://github.com/jalyna/oakdex-battle) and [oakdex-breeding](https://github.com/jalyna/oakdex-breeding).
|
8
|
+
|
9
|
+
## Getting Started
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
require 'oakdex/pokemon'
|
13
|
+
|
14
|
+
pikachu = Oakdex::Pokemon.create('Pikachu', level: 12)
|
15
|
+
bulbasaur = Oakdex::Pokemon.create('Bulbasaur', { # many options available
|
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
|
+
original_trainer: 'Cool trainer name',
|
43
|
+
item_id: 'Lucky Egg',
|
44
|
+
wild: true
|
45
|
+
})
|
46
|
+
|
47
|
+
pikachu.gender # => female
|
48
|
+
pikachu.name # => Pikachu
|
49
|
+
pikachu.level # => 12
|
50
|
+
pikachu.moves.map { |p| "#{p.name} #{p.pp}" } # => ["Quick Attack 30", "Tail Whip 30", "Growl 40", "Thunder Shock 30"]
|
51
|
+
pikachu.hp # => 34
|
52
|
+
pikachu.atk # => 18
|
53
|
+
pikachu.current_hp # => 34
|
54
|
+
pikachu.traded? # => false
|
55
|
+
pikachu.change_hp_by(38)
|
56
|
+
pikachu.current_hp # => 0
|
57
|
+
pikachu.change_pp_by('Thunder Shock', -1)
|
58
|
+
pikachu.moves.map { |p| "#{p.name} #{p.pp}" } # => ["Quick Attack 30", "Tail Whip 30", "Growl 40", "Thunder Shock 29"]
|
59
|
+
```
|
60
|
+
|
61
|
+
## Contributing
|
62
|
+
|
63
|
+
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.
|
64
|
+
|
65
|
+
Please respect the [Code of Conduct](//github.com/jalyna/oakdex-pokemon/blob/master/CODE_OF_CONDUCT.md).
|
66
|
+
|
67
|
+
## License
|
68
|
+
|
69
|
+
MIT License. See the included MIT-LICENSE file.
|
70
|
+
|
71
|
+
## Credits
|
72
|
+
|
73
|
+
Logo Icon by [Roundicons Freebies](http://www.flaticon.com/authors/roundicons-freebies).
|
data/lib/oakdex.rb
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'oakdex/pokedex'
|
3
|
+
|
4
|
+
require 'oakdex/pokemon/stat'
|
5
|
+
require 'oakdex/pokemon/move'
|
6
|
+
require 'oakdex/pokemon/factory'
|
7
|
+
|
8
|
+
module Oakdex
|
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
|
+
|
15
|
+
def_delegators :@species, :types
|
16
|
+
|
17
|
+
attr_accessor :trainer
|
18
|
+
attr_reader :species
|
19
|
+
|
20
|
+
def self.create(species_name, options = {})
|
21
|
+
species = Oakdex::Pokedex::Pokemon.find!(species_name)
|
22
|
+
Factory.create(species, options)
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(species, attributes = {})
|
26
|
+
@species = species
|
27
|
+
@attributes = attributes
|
28
|
+
end
|
29
|
+
|
30
|
+
def name
|
31
|
+
@species.names['en']
|
32
|
+
end
|
33
|
+
|
34
|
+
def gender
|
35
|
+
@attributes[:gender]
|
36
|
+
end
|
37
|
+
|
38
|
+
def moves
|
39
|
+
@attributes[:moves]
|
40
|
+
end
|
41
|
+
|
42
|
+
def current_hp
|
43
|
+
@attributes[:hp]
|
44
|
+
end
|
45
|
+
|
46
|
+
def moves_with_pp
|
47
|
+
moves.select { |m| m.pp > 0 }
|
48
|
+
end
|
49
|
+
|
50
|
+
def wild?
|
51
|
+
@attributes[:wild]
|
52
|
+
end
|
53
|
+
|
54
|
+
def original_trainer
|
55
|
+
@attributes[:original_trainer]
|
56
|
+
end
|
57
|
+
|
58
|
+
def item_id
|
59
|
+
@attributes[:item_id]
|
60
|
+
end
|
61
|
+
|
62
|
+
def amie
|
63
|
+
{
|
64
|
+
affection: 0,
|
65
|
+
fullness: 0,
|
66
|
+
enjoyment: 0
|
67
|
+
}.merge(@attributes[:amie] || {})
|
68
|
+
end
|
69
|
+
|
70
|
+
def amie_level(amie_stat)
|
71
|
+
5 - [255, 150, 100, 50, 1, 0].find_index do |treshold|
|
72
|
+
amie[amie_stat] >= treshold
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def traded?
|
77
|
+
return false if trainer.nil? || original_trainer.nil?
|
78
|
+
return false unless trainer.respond_to?(:name)
|
79
|
+
trainer.name != original_trainer
|
80
|
+
end
|
81
|
+
|
82
|
+
def change_hp_by(hp_change)
|
83
|
+
@attributes[:hp] = if hp_change < 0
|
84
|
+
[@attributes[:hp] + hp_change, 0].max
|
85
|
+
else
|
86
|
+
[@attributes[:hp] + hp_change, hp].min
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def change_pp_by(move_name, pp_change)
|
91
|
+
move = moves.find { |m| m.name == move_name }
|
92
|
+
return unless move
|
93
|
+
move.pp = if pp_change < 0
|
94
|
+
[move.pp + pp_change, 0].max
|
95
|
+
else
|
96
|
+
[move.pp + pp_change, move.max_pp].min
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def level
|
101
|
+
Stat.level_by_exp(@species.leveling_rate, @attributes[:exp])
|
102
|
+
end
|
103
|
+
|
104
|
+
BATTLE_STATS.each do |stat|
|
105
|
+
define_method stat do
|
106
|
+
initial_stat(stat)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def initial_stat(stat)
|
113
|
+
Stat.initial_stat(stat,
|
114
|
+
level: level,
|
115
|
+
nature: @attributes[:nature],
|
116
|
+
iv: @attributes[:iv],
|
117
|
+
ev: @attributes[:ev],
|
118
|
+
base_stats: @species.base_stats
|
119
|
+
)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,153 @@
|
|
1
|
+
module Oakdex
|
2
|
+
class Pokemon
|
3
|
+
# Creates Pokemon instance and prefills attributes
|
4
|
+
class Factory
|
5
|
+
REQUIRED_ATTRIBUTES = %i[exp gender ability nature hp iv ev moves]
|
6
|
+
OPTIONAL_ATTRIBUTES = %i[
|
7
|
+
original_trainer
|
8
|
+
wild
|
9
|
+
item_id
|
10
|
+
amie
|
11
|
+
]
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def create(species, options = {})
|
15
|
+
factory = new(species, options)
|
16
|
+
attributes = Hash[(REQUIRED_ATTRIBUTES +
|
17
|
+
OPTIONAL_ATTRIBUTES).map do |attr|
|
18
|
+
[attr, factory.send(attr)]
|
19
|
+
end]
|
20
|
+
Pokemon.new(species, attributes)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def initialize(species, options = {})
|
25
|
+
@species = species
|
26
|
+
@options = options
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def original_trainer
|
32
|
+
@options[:original_trainer]
|
33
|
+
end
|
34
|
+
|
35
|
+
def wild
|
36
|
+
@options[:wild]
|
37
|
+
end
|
38
|
+
|
39
|
+
def item_id
|
40
|
+
@options[:item_id]
|
41
|
+
end
|
42
|
+
|
43
|
+
def amie
|
44
|
+
@options[:amie]
|
45
|
+
end
|
46
|
+
|
47
|
+
def moves
|
48
|
+
if @options[:moves]
|
49
|
+
@options[:moves].map do |move_data|
|
50
|
+
Move.new(
|
51
|
+
Oakdex::Pokedex::Move.find!(move_data[0]),
|
52
|
+
move_data[1],
|
53
|
+
move_data[2]
|
54
|
+
)
|
55
|
+
end
|
56
|
+
else
|
57
|
+
(generate_available_moves + additional_moves).take(4)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def generate_available_moves
|
62
|
+
available_moves.sample(4).map do |move_name|
|
63
|
+
move_type = Oakdex::Pokedex::Move.find!(move_name)
|
64
|
+
Move.new(move_type, move_type.pp, move_type.pp)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def additional_moves
|
69
|
+
return [] unless @options[:additional_moves]
|
70
|
+
@options[:additional_moves].map do |move_name|
|
71
|
+
move_type = Oakdex::Pokedex::Move.find!(move_name)
|
72
|
+
Move.new(move_type, move_type.pp, move_type.pp)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def available_moves
|
77
|
+
@species.learnset.map do |m|
|
78
|
+
m['move'] if m['level'] && m['level'] <= level
|
79
|
+
end.compact
|
80
|
+
end
|
81
|
+
|
82
|
+
def ability
|
83
|
+
if @options['ability']
|
84
|
+
Oakdex::Pokedex::Ability.find!(@options['ability'])
|
85
|
+
else
|
86
|
+
Oakdex::Pokedex::Ability.find!(abilities.sample['name'])
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def abilities
|
91
|
+
@species.abilities.select { |a| !a['hidden'] && !a['mega'] }
|
92
|
+
end
|
93
|
+
|
94
|
+
def exp
|
95
|
+
@options[:exp] || Stat.exp_by_level(
|
96
|
+
@species.leveling_rate,
|
97
|
+
@options[:level]
|
98
|
+
)
|
99
|
+
end
|
100
|
+
|
101
|
+
def level
|
102
|
+
Stat.level_by_exp(@species.leveling_rate, exp)
|
103
|
+
end
|
104
|
+
|
105
|
+
def hp
|
106
|
+
return @options[:hp] if @options[:hp]
|
107
|
+
Stat.initial_stat(:hp,
|
108
|
+
level: level,
|
109
|
+
iv: iv,
|
110
|
+
ev: ev,
|
111
|
+
base_stats: @species.base_stats,
|
112
|
+
nature: nature
|
113
|
+
)
|
114
|
+
end
|
115
|
+
|
116
|
+
def iv
|
117
|
+
return @options[:iv] if @options[:iv]
|
118
|
+
@iv ||= Hash[Pokemon::BATTLE_STATS.map do |stat|
|
119
|
+
[stat, rand(0..31)]
|
120
|
+
end]
|
121
|
+
end
|
122
|
+
|
123
|
+
def ev
|
124
|
+
return @options[:ev] if @options[:ev]
|
125
|
+
@ev ||= Hash[Pokemon::BATTLE_STATS.map do |stat|
|
126
|
+
[stat, 0]
|
127
|
+
end]
|
128
|
+
end
|
129
|
+
|
130
|
+
def gender
|
131
|
+
return @options[:gender] if @options[:gender]
|
132
|
+
return 'neuter' unless @species.gender_ratios
|
133
|
+
calculate_gender
|
134
|
+
end
|
135
|
+
|
136
|
+
def calculate_gender
|
137
|
+
if rand(1..1000) <= @species.gender_ratios['male'] * 10
|
138
|
+
'male'
|
139
|
+
else
|
140
|
+
'female'
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def nature(options = {})
|
145
|
+
@nature ||= if options[:nature]
|
146
|
+
Oakdex::Pokedex::Nature.find!(options[:nature])
|
147
|
+
else
|
148
|
+
Oakdex::Pokedex::Nature.all.values.sample
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
module Oakdex
|
4
|
+
class Pokemon
|
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
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Oakdex
|
2
|
+
class Pokemon
|
3
|
+
# Calculates Pokemon Stats
|
4
|
+
class Stat
|
5
|
+
class << self
|
6
|
+
def initial_stat(stat, options = {})
|
7
|
+
first_part = initial_stat_first_part(stat, options)
|
8
|
+
(
|
9
|
+
if stat == :hp
|
10
|
+
first_part + options[:level] + 10
|
11
|
+
elsif stat.to_s == options[:nature].increased_stat
|
12
|
+
(first_part + 5) * 1.1
|
13
|
+
elsif stat.to_s == options[:nature].decreased_stat
|
14
|
+
(first_part + 5) * 0.9
|
15
|
+
else
|
16
|
+
first_part + 5
|
17
|
+
end
|
18
|
+
).to_i
|
19
|
+
end
|
20
|
+
|
21
|
+
def exp_by_level(leveling_rate, level)
|
22
|
+
case leveling_rate
|
23
|
+
when 'Fast' then ((4.0 * level**3) / 5).to_i
|
24
|
+
when 'Slow' then ((5.0 * level**3) / 4).to_i
|
25
|
+
when 'Medium Slow' then medium_slow_exp(level)
|
26
|
+
when 'Fluctuating' then fluctuating_exp(level)
|
27
|
+
else level**3
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def level_by_exp(leveling_rate, exp)
|
32
|
+
level = 2
|
33
|
+
level += 1 while exp_by_level(leveling_rate, level) <= exp
|
34
|
+
level - 1
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def medium_slow_exp(level)
|
40
|
+
(
|
41
|
+
((6.0 / 5) * level**3) - 15 * level**2 + (100 * level) - 140
|
42
|
+
).to_i
|
43
|
+
end
|
44
|
+
|
45
|
+
def fluctuating_exp(level)
|
46
|
+
(
|
47
|
+
if level <= 15
|
48
|
+
level**3 * ((((level + 1) / 3.0) + 24) / 50)
|
49
|
+
elsif level <= 36
|
50
|
+
level**3 * ((level + 14) / 50.0)
|
51
|
+
else
|
52
|
+
level**3 * (((level / 2.0) + 32) / 50)
|
53
|
+
end
|
54
|
+
).to_i
|
55
|
+
end
|
56
|
+
|
57
|
+
def initial_stat_first_part(stat, options = {})
|
58
|
+
(
|
59
|
+
(
|
60
|
+
2.0 *
|
61
|
+
options[:base_stats][stat.to_s] +
|
62
|
+
options[:iv][stat] +
|
63
|
+
(options[:ev][stat] / 4)
|
64
|
+
) * options[:level]
|
65
|
+
) / 100
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: oakdex-pokemon
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jalyna Schroeder
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-01-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: oakdex-pokedex
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.4.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.4.0
|
27
|
+
description: Pokémon Instance Representer, based on oakdex-pokedex
|
28
|
+
email: jalyna.schroeder@gmail.com
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- README.md
|
34
|
+
- lib/oakdex.rb
|
35
|
+
- lib/oakdex/pokemon.rb
|
36
|
+
- lib/oakdex/pokemon/factory.rb
|
37
|
+
- lib/oakdex/pokemon/move.rb
|
38
|
+
- lib/oakdex/pokemon/stat.rb
|
39
|
+
- lib/oakdex/pokemon/version.rb
|
40
|
+
homepage: http://github.com/jalyna/oakdex-pokemon
|
41
|
+
licenses:
|
42
|
+
- MIT
|
43
|
+
metadata: {}
|
44
|
+
post_install_message:
|
45
|
+
rdoc_options: []
|
46
|
+
require_paths:
|
47
|
+
- lib
|
48
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
requirements: []
|
59
|
+
rubyforge_project:
|
60
|
+
rubygems_version: 2.5.2
|
61
|
+
signing_key:
|
62
|
+
specification_version: 4
|
63
|
+
summary: Pokémon Instance Representer
|
64
|
+
test_files: []
|