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.
@@ -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
@@ -0,0 +1,73 @@
1
+ # <img src="https://v20.imgup.net/oakdex_logfbad.png" alt="fixer" width=282>
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/oakdex-pokemon.svg)](https://badge.fury.io/rb/oakdex-pokemon) [![Build Status](https://travis-ci.org/jalyna/oakdex-pokemon.svg?branch=master)](https://travis-ci.org/jalyna/oakdex-pokemon) [![Maintainability](https://api.codeclimate.com/v1/badges/9917f32f23833238aef9/maintainability)](https://codeclimate.com/github/jalyna/oakdex-pokemon/maintainability) [![Test Coverage](https://api.codeclimate.com/v1/badges/9917f32f23833238aef9/test_coverage)](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).
@@ -0,0 +1,3 @@
1
+ # Main Namespace Oakdex
2
+ module Oakdex
3
+ end
@@ -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
@@ -0,0 +1,5 @@
1
+ module Oakdex
2
+ class Pokemon
3
+ VERSION = '0.0.1'
4
+ end
5
+ 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: []