diff options
author | Star Rauchenberger <fefferburbia@gmail.com> | 2024-12-07 11:49:49 -0500 |
---|---|---|
committer | Star Rauchenberger <fefferburbia@gmail.com> | 2024-12-07 11:49:49 -0500 |
commit | 56f5841d4b9c12296cdfcaeff174b2627d59afc8 (patch) | |
tree | 4f7da4ebbe5ee15a1594b26466ed78e2cf10de35 /app/models | |
parent | c1b0443ba2aebdbd39291ddab0c189f3f4831320 (diff) | |
download | pokeviewer-56f5841d4b9c12296cdfcaeff174b2627d59afc8.tar.gz pokeviewer-56f5841d4b9c12296cdfcaeff174b2627d59afc8.tar.bz2 pokeviewer-56f5841d4b9c12296cdfcaeff174b2627d59afc8.zip |
Migrate to full rails app
Diffstat (limited to 'app/models')
-rw-r--r-- | app/models/ability.rb | 5 | ||||
-rw-r--r-- | app/models/application_record.rb | 3 | ||||
-rw-r--r-- | app/models/concerns/.keep | 0 | ||||
-rw-r--r-- | app/models/gift_ribbon.rb | 3 | ||||
-rw-r--r-- | app/models/item.rb | 41 | ||||
-rw-r--r-- | app/models/location.rb | 5 | ||||
-rw-r--r-- | app/models/move.rb | 31 | ||||
-rw-r--r-- | app/models/pokedex_entry.rb | 4 | ||||
-rw-r--r-- | app/models/pokemon.rb | 165 | ||||
-rw-r--r-- | app/models/pokeviewer/ability.rb | 7 | ||||
-rw-r--r-- | app/models/pokeviewer/application_record.rb | 5 | ||||
-rw-r--r-- | app/models/pokeviewer/gift_ribbon.rb | 5 | ||||
-rw-r--r-- | app/models/pokeviewer/item.rb | 43 | ||||
-rw-r--r-- | app/models/pokeviewer/location.rb | 7 | ||||
-rw-r--r-- | app/models/pokeviewer/move.rb | 33 | ||||
-rw-r--r-- | app/models/pokeviewer/pokedex_entry.rb | 6 | ||||
-rw-r--r-- | app/models/pokeviewer/pokemon.rb | 167 | ||||
-rw-r--r-- | app/models/pokeviewer/revision.rb | 496 | ||||
-rw-r--r-- | app/models/pokeviewer/species.rb | 26 | ||||
-rw-r--r-- | app/models/pokeviewer/trainer.rb | 95 | ||||
-rw-r--r-- | app/models/revision.rb | 494 | ||||
-rw-r--r-- | app/models/species.rb | 24 | ||||
-rw-r--r-- | app/models/trainer.rb | 93 |
23 files changed, 868 insertions, 890 deletions
diff --git a/app/models/ability.rb b/app/models/ability.rb new file mode 100644 index 0000000..5b7e8b4 --- /dev/null +++ b/app/models/ability.rb | |||
@@ -0,0 +1,5 @@ | |||
1 | class Ability < ApplicationRecord | ||
2 | validates :name, presence: true, uniqueness: true | ||
3 | |||
4 | validates :description, presence: true | ||
5 | end | ||
diff --git a/app/models/application_record.rb b/app/models/application_record.rb new file mode 100644 index 0000000..b63caeb --- /dev/null +++ b/app/models/application_record.rb | |||
@@ -0,0 +1,3 @@ | |||
1 | class ApplicationRecord < ActiveRecord::Base | ||
2 | primary_abstract_class | ||
3 | end | ||
diff --git a/app/models/concerns/.keep b/app/models/concerns/.keep new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/app/models/concerns/.keep | |||
diff --git a/app/models/gift_ribbon.rb b/app/models/gift_ribbon.rb new file mode 100644 index 0000000..dbf3c6f --- /dev/null +++ b/app/models/gift_ribbon.rb | |||
@@ -0,0 +1,3 @@ | |||
1 | class GiftRibbon < ApplicationRecord | ||
2 | validates :description, presence: true | ||
3 | end | ||
diff --git a/app/models/item.rb b/app/models/item.rb new file mode 100644 index 0000000..269cf97 --- /dev/null +++ b/app/models/item.rb | |||
@@ -0,0 +1,41 @@ | |||
1 | class Item < ApplicationRecord | ||
2 | validates :name, presence: true | ||
3 | |||
4 | belongs_to :move, optional: true | ||
5 | validates :move, presence: true, if: :tm? | ||
6 | |||
7 | validates :rs_description, presence: true, unless: :tm? | ||
8 | validates :frlg_description, presence: true, unless: :tm? | ||
9 | |||
10 | def description(game) | ||
11 | if game == :emerald | ||
12 | if not emerald_description.nil? | ||
13 | emerald_description | ||
14 | elsif not rs_description.nil? | ||
15 | rs_description | ||
16 | else | ||
17 | move.description game | ||
18 | end | ||
19 | elsif game == :firered or game == :leafgreen | ||
20 | if not frlg_description.nil? | ||
21 | frlg_description | ||
22 | else | ||
23 | move.description game | ||
24 | end | ||
25 | else | ||
26 | if not rs_description.nil? | ||
27 | rs_description | ||
28 | else | ||
29 | move.description game | ||
30 | end | ||
31 | end | ||
32 | end | ||
33 | |||
34 | def icon_path | ||
35 | if tm? | ||
36 | "items/tms/#{move.move_type}.png" | ||
37 | else | ||
38 | "items/#{id}.png" | ||
39 | end | ||
40 | end | ||
41 | end | ||
diff --git a/app/models/location.rb b/app/models/location.rb new file mode 100644 index 0000000..57e193f --- /dev/null +++ b/app/models/location.rb | |||
@@ -0,0 +1,5 @@ | |||
1 | class Location < ApplicationRecord | ||
2 | has_many :pokemon, dependent: :nullify | ||
3 | |||
4 | validates :name, presence: true | ||
5 | end | ||
diff --git a/app/models/move.rb b/app/models/move.rb new file mode 100644 index 0000000..cbc8422 --- /dev/null +++ b/app/models/move.rb | |||
@@ -0,0 +1,31 @@ | |||
1 | class Move < ApplicationRecord | ||
2 | extend Enumerize | ||
3 | |||
4 | has_many :revision_moves | ||
5 | has_many :revisions, through: :revision_moves | ||
6 | |||
7 | validates :name, presence: true, uniqueness: true | ||
8 | |||
9 | validates :pp, presence: true, | ||
10 | numericality: { greater_than_or_equal_to: 1, only_integer: true } | ||
11 | |||
12 | TYPES = [:normal, :fighting, :flying, :poison, :ground, | ||
13 | :rock, :bug, :ghost, :steel, :mystery, :fire, :water, :grass, :electric, | ||
14 | :psychic, :ice, :dragon, :dark] | ||
15 | |||
16 | validates :move_type, presence: true | ||
17 | enumerize :move_type, in: TYPES, predicates: true | ||
18 | |||
19 | validates :rs_description, presence: true | ||
20 | validates :frlg_description, presence: true | ||
21 | |||
22 | def description(game) | ||
23 | if game == :emerald and not emerald_description.nil? | ||
24 | emerald_description | ||
25 | elsif game == :firered or game == :leafgreen | ||
26 | frlg_description | ||
27 | else | ||
28 | rs_description | ||
29 | end | ||
30 | end | ||
31 | end | ||
diff --git a/app/models/pokedex_entry.rb b/app/models/pokedex_entry.rb new file mode 100644 index 0000000..9200896 --- /dev/null +++ b/app/models/pokedex_entry.rb | |||
@@ -0,0 +1,4 @@ | |||
1 | class PokedexEntry < ApplicationRecord | ||
2 | belongs_to :trainer | ||
3 | belongs_to :species | ||
4 | end | ||
diff --git a/app/models/pokemon.rb b/app/models/pokemon.rb new file mode 100644 index 0000000..7db74ee --- /dev/null +++ b/app/models/pokemon.rb | |||
@@ -0,0 +1,165 @@ | |||
1 | class Pokemon < ApplicationRecord | ||
2 | extend Enumerize | ||
3 | extend ActiveModel::Naming | ||
4 | |||
5 | has_many :revisions, -> { order "sequential_id ASC" }, dependent: :destroy | ||
6 | |||
7 | belongs_to :current, class_name: "Revision", optional: true | ||
8 | validate :current_is_cached | ||
9 | |||
10 | belongs_to :trainer, optional: true | ||
11 | |||
12 | validates :box, numericality: { | ||
13 | greater_than_or_equal_to: 1, | ||
14 | less_than_or_equal_to: 14, | ||
15 | only_integer: true }, | ||
16 | allow_nil: true | ||
17 | |||
18 | validates :slot, presence: true, | ||
19 | uniqueness: { scope: [:trainer_id, :box] }, | ||
20 | numericality: { | ||
21 | greater_than_or_equal_to: 0, | ||
22 | only_integer: true }, | ||
23 | unless: Proc.new { |a| a.trainer_id.nil? } | ||
24 | |||
25 | validates :slot, | ||
26 | numericality: { less_than: 30 }, | ||
27 | unless: Proc.new { |a| a.trainer_id.nil? or a.box.nil? } | ||
28 | |||
29 | validates :slot, | ||
30 | numericality: { less_than: 6 }, | ||
31 | unless: Proc.new { |a| a.trainer_id.nil? or not a.box.nil? } | ||
32 | |||
33 | scope :party, -> { where(box: nil) } | ||
34 | scope :box, ->(n) { where(box: n) } | ||
35 | scope :unaccounted, -> { where(trainer_id: nil) } | ||
36 | |||
37 | validate :uuid_is_constant, on: :update | ||
38 | before_create :set_uuid | ||
39 | |||
40 | validates :ot_name, presence: true | ||
41 | |||
42 | validates :ot_number, presence: true, | ||
43 | numericality: { greater_than_or_equal_to: 0, only_integer: true } | ||
44 | |||
45 | validates :ot_gender, presence: true | ||
46 | enumerize :ot_gender, in: [:female, :male] | ||
47 | |||
48 | validates :met_level, presence: true, | ||
49 | numericality: { greater_than_or_equal_to: 1, only_integer: true }, | ||
50 | if: Proc.new { |a| a.met_type == :normal } | ||
51 | |||
52 | validates :met_type, presence: true | ||
53 | enumerize :met_type, | ||
54 | in: [:normal, :hatched, :npc_trade, :fateful_encounter, :orre] | ||
55 | |||
56 | belongs_to :location, optional: true | ||
57 | validates :location, presence: true, | ||
58 | if: Proc.new { |c| c.met_type == :normal or c.met_type == :hatched} | ||
59 | |||
60 | validates :gender, presence: true | ||
61 | enumerize :gender, in: [:genderless, :female, :male] | ||
62 | |||
63 | validates :nature, presence: true | ||
64 | enumerize :nature, in: [:hardy, :lonely, :brave, :adamant, :naughty, :bold, | ||
65 | :docile, :relaxed, :impish, :lax, :timid, :hasty, :serious, :jolly, | ||
66 | :naive, :modest, :mild, :quiet, :bashful, :rash, :calm, :gentle, :sassy, | ||
67 | :careful, :quirky] | ||
68 | |||
69 | enumerize :unown_letter, in: [:a, :b, :c, :d, :e, :f, :g, :h, :i, :j, :k, | ||
70 | :l, :m, :n, :o, :p, :q, :r, :s, :t, :u, :v, :w, :x, :y, :z, | ||
71 | :question, :exclamation] | ||
72 | |||
73 | validates :pokeball, presence: true | ||
74 | enumerize :pokeball, in: [:master, :ultra, :great, :poke, :safari, :net, | ||
75 | :dive, :nest, :repeat, :timer, :luxury, :premier] | ||
76 | |||
77 | def to_param | ||
78 | uuid | ||
79 | end | ||
80 | |||
81 | def outsider? | ||
82 | (trainer.nil?) or (ot_name != trainer.name) or (ot_number != trainer.number) | ||
83 | end | ||
84 | |||
85 | def display_ot_number | ||
86 | ot_number.to_s.rjust(5, '0') | ||
87 | end | ||
88 | |||
89 | def nature_benefits?(stat) | ||
90 | if stat == :attack | ||
91 | [:lonely, :brave, :adamant, :naughty].include? nature.intern | ||
92 | elsif stat == :defense | ||
93 | [:bold, :relaxed, :impish, :lax].include? nature.intern | ||
94 | elsif stat == :speed | ||
95 | [:timid, :hasty, :jolly, :naive].include? nature.intern | ||
96 | elsif stat == :special_attack | ||
97 | [:modest, :mild, :quiet, :rash].include? nature.intern | ||
98 | elsif stat == :special_defense | ||
99 | [:calm, :gentle, :sassy, :careful].include? nature.intern | ||
100 | else | ||
101 | false | ||
102 | end | ||
103 | end | ||
104 | |||
105 | def nature_hinders?(stat) | ||
106 | if stat == :attack | ||
107 | [:bold, :timid, :modest, :calm].include? nature.intern | ||
108 | elsif stat == :defense | ||
109 | [:lonely, :hasty, :mild, :gentle].include? nature.intern | ||
110 | elsif stat == :speed | ||
111 | [:brave, :relaxed, :quiet, :sassy].include? nature.intern | ||
112 | elsif stat == :special_attack | ||
113 | [:adamant, :impish, :jolly, :careful].include? nature.intern | ||
114 | elsif stat == :special_defense | ||
115 | [:naughty, :lax, :naive, :rash].include? nature.intern | ||
116 | else | ||
117 | false | ||
118 | end | ||
119 | end | ||
120 | |||
121 | def pokeball_icon_path | ||
122 | "items/#{Pokemon.pokeball.values.find_index(pokeball) + 1}.png" | ||
123 | end | ||
124 | |||
125 | def gift_ribbon_description(ribbon) | ||
126 | if trainer.nil? | ||
127 | "" | ||
128 | else | ||
129 | trainer.gift_ribbon_description(ribbon) | ||
130 | end | ||
131 | end | ||
132 | |||
133 | def gender_symbol | ||
134 | case gender.intern | ||
135 | when :female | ||
136 | "♀" | ||
137 | when :male | ||
138 | "♂" | ||
139 | when :genderless | ||
140 | "" | ||
141 | end | ||
142 | end | ||
143 | |||
144 | private | ||
145 | |||
146 | def set_uuid | ||
147 | self.uuid = SecureRandom.uuid | ||
148 | end | ||
149 | |||
150 | def uuid_is_constant | ||
151 | errors.add(:uuid, "can't be changed") if self.uuid_changed? | ||
152 | end | ||
153 | |||
154 | def current_is_cached | ||
155 | if self.revisions.empty? | ||
156 | unless self.current_id.nil? | ||
157 | errors.add(:current, "must be null when there are no revisions") | ||
158 | end | ||
159 | else | ||
160 | unless self.current_id = self.revisions.last.id | ||
161 | errors.add(:current, "is not up-to-date") | ||
162 | end | ||
163 | end | ||
164 | end | ||
165 | end | ||
diff --git a/app/models/pokeviewer/ability.rb b/app/models/pokeviewer/ability.rb deleted file mode 100644 index 594b18c..0000000 --- a/app/models/pokeviewer/ability.rb +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | module Pokeviewer | ||
2 | class Ability < ApplicationRecord | ||
3 | validates :name, presence: true, uniqueness: true | ||
4 | |||
5 | validates :description, presence: true | ||
6 | end | ||
7 | end | ||
diff --git a/app/models/pokeviewer/application_record.rb b/app/models/pokeviewer/application_record.rb deleted file mode 100644 index 6d07f27..0000000 --- a/app/models/pokeviewer/application_record.rb +++ /dev/null | |||
@@ -1,5 +0,0 @@ | |||
1 | module Pokeviewer | ||
2 | class ApplicationRecord < ActiveRecord::Base | ||
3 | self.abstract_class = true | ||
4 | end | ||
5 | end | ||
diff --git a/app/models/pokeviewer/gift_ribbon.rb b/app/models/pokeviewer/gift_ribbon.rb deleted file mode 100644 index f8f4fa5..0000000 --- a/app/models/pokeviewer/gift_ribbon.rb +++ /dev/null | |||
@@ -1,5 +0,0 @@ | |||
1 | module Pokeviewer | ||
2 | class GiftRibbon < ApplicationRecord | ||
3 | validates :description, presence: true | ||
4 | end | ||
5 | end | ||
diff --git a/app/models/pokeviewer/item.rb b/app/models/pokeviewer/item.rb deleted file mode 100644 index d03c584..0000000 --- a/app/models/pokeviewer/item.rb +++ /dev/null | |||
@@ -1,43 +0,0 @@ | |||
1 | module Pokeviewer | ||
2 | class Item < ApplicationRecord | ||
3 | validates :name, presence: true | ||
4 | |||
5 | belongs_to :move, optional: true | ||
6 | validates :move, presence: true, if: :tm? | ||
7 | |||
8 | validates :rs_description, presence: true, unless: :tm? | ||
9 | validates :frlg_description, presence: true, unless: :tm? | ||
10 | |||
11 | def description(game) | ||
12 | if game == :emerald | ||
13 | if not emerald_description.nil? | ||
14 | emerald_description | ||
15 | elsif not rs_description.nil? | ||
16 | rs_description | ||
17 | else | ||
18 | move.description game | ||
19 | end | ||
20 | elsif game == :firered or game == :leafgreen | ||
21 | if not frlg_description.nil? | ||
22 | frlg_description | ||
23 | else | ||
24 | move.description game | ||
25 | end | ||
26 | else | ||
27 | if not rs_description.nil? | ||
28 | rs_description | ||
29 | else | ||
30 | move.description game | ||
31 | end | ||
32 | end | ||
33 | end | ||
34 | |||
35 | def icon_path | ||
36 | if tm? | ||
37 | "pokeviewer/items/tms/#{move.move_type}.png" | ||
38 | else | ||
39 | "pokeviewer/items/#{id}.png" | ||
40 | end | ||
41 | end | ||
42 | end | ||
43 | end | ||
diff --git a/app/models/pokeviewer/location.rb b/app/models/pokeviewer/location.rb deleted file mode 100644 index db37df2..0000000 --- a/app/models/pokeviewer/location.rb +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | module Pokeviewer | ||
2 | class Location < ApplicationRecord | ||
3 | has_many :pokemon, dependent: :nullify | ||
4 | |||
5 | validates :name, presence: true | ||
6 | end | ||
7 | end | ||
diff --git a/app/models/pokeviewer/move.rb b/app/models/pokeviewer/move.rb deleted file mode 100644 index c63493a..0000000 --- a/app/models/pokeviewer/move.rb +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
1 | module Pokeviewer | ||
2 | class Move < ApplicationRecord | ||
3 | extend Enumerize | ||
4 | |||
5 | has_many :revision_moves | ||
6 | has_many :revisions, through: :revision_moves | ||
7 | |||
8 | validates :name, presence: true, uniqueness: true | ||
9 | |||
10 | validates :pp, presence: true, | ||
11 | numericality: { greater_than_or_equal_to: 1, only_integer: true } | ||
12 | |||
13 | TYPES = [:normal, :fighting, :flying, :poison, :ground, | ||
14 | :rock, :bug, :ghost, :steel, :mystery, :fire, :water, :grass, :electric, | ||
15 | :psychic, :ice, :dragon, :dark] | ||
16 | |||
17 | validates :move_type, presence: true | ||
18 | enumerize :move_type, in: TYPES, predicates: true | ||
19 | |||
20 | validates :rs_description, presence: true | ||
21 | validates :frlg_description, presence: true | ||
22 | |||
23 | def description(game) | ||
24 | if game == :emerald and not emerald_description.nil? | ||
25 | emerald_description | ||
26 | elsif game == :firered or game == :leafgreen | ||
27 | frlg_description | ||
28 | else | ||
29 | rs_description | ||
30 | end | ||
31 | end | ||
32 | end | ||
33 | end | ||
diff --git a/app/models/pokeviewer/pokedex_entry.rb b/app/models/pokeviewer/pokedex_entry.rb deleted file mode 100644 index 9be6a6a..0000000 --- a/app/models/pokeviewer/pokedex_entry.rb +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | module Pokeviewer | ||
2 | class PokedexEntry < ApplicationRecord | ||
3 | belongs_to :trainer | ||
4 | belongs_to :species | ||
5 | end | ||
6 | end | ||
diff --git a/app/models/pokeviewer/pokemon.rb b/app/models/pokeviewer/pokemon.rb deleted file mode 100644 index 77ee89a..0000000 --- a/app/models/pokeviewer/pokemon.rb +++ /dev/null | |||
@@ -1,167 +0,0 @@ | |||
1 | module Pokeviewer | ||
2 | class Pokemon < ApplicationRecord | ||
3 | extend Enumerize | ||
4 | extend ActiveModel::Naming | ||
5 | |||
6 | has_many :revisions, -> { order "sequential_id ASC" }, dependent: :destroy | ||
7 | |||
8 | belongs_to :current, class_name: "Revision", optional: true | ||
9 | validate :current_is_cached | ||
10 | |||
11 | belongs_to :trainer, optional: true | ||
12 | |||
13 | validates :box, numericality: { | ||
14 | greater_than_or_equal_to: 1, | ||
15 | less_than_or_equal_to: 14, | ||
16 | only_integer: true }, | ||
17 | allow_nil: true | ||
18 | |||
19 | validates :slot, presence: true, | ||
20 | uniqueness: { scope: [:trainer_id, :box] }, | ||
21 | numericality: { | ||
22 | greater_than_or_equal_to: 0, | ||
23 | only_integer: true }, | ||
24 | unless: Proc.new { |a| a.trainer_id.nil? } | ||
25 | |||
26 | validates :slot, | ||
27 | numericality: { less_than: 30 }, | ||
28 | unless: Proc.new { |a| a.trainer_id.nil? or a.box.nil? } | ||
29 | |||
30 | validates :slot, | ||
31 | numericality: { less_than: 6 }, | ||
32 | unless: Proc.new { |a| a.trainer_id.nil? or not a.box.nil? } | ||
33 | |||
34 | scope :party, -> { where(box: nil) } | ||
35 | scope :box, ->(n) { where(box: n) } | ||
36 | scope :unaccounted, -> { where(trainer_id: nil) } | ||
37 | |||
38 | validate :uuid_is_constant, on: :update | ||
39 | before_create :set_uuid | ||
40 | |||
41 | validates :ot_name, presence: true | ||
42 | |||
43 | validates :ot_number, presence: true, | ||
44 | numericality: { greater_than_or_equal_to: 0, only_integer: true } | ||
45 | |||
46 | validates :ot_gender, presence: true | ||
47 | enumerize :ot_gender, in: [:female, :male] | ||
48 | |||
49 | validates :met_level, presence: true, | ||
50 | numericality: { greater_than_or_equal_to: 1, only_integer: true }, | ||
51 | if: Proc.new { |a| a.met_type == :normal } | ||
52 | |||
53 | validates :met_type, presence: true | ||
54 | enumerize :met_type, | ||
55 | in: [:normal, :hatched, :npc_trade, :fateful_encounter, :orre] | ||
56 | |||
57 | belongs_to :location, optional: true | ||
58 | validates :location, presence: true, | ||
59 | if: Proc.new { |c| c.met_type == :normal or c.met_type == :hatched} | ||
60 | |||
61 | validates :gender, presence: true | ||
62 | enumerize :gender, in: [:genderless, :female, :male] | ||
63 | |||
64 | validates :nature, presence: true | ||
65 | enumerize :nature, in: [:hardy, :lonely, :brave, :adamant, :naughty, :bold, | ||
66 | :docile, :relaxed, :impish, :lax, :timid, :hasty, :serious, :jolly, | ||
67 | :naive, :modest, :mild, :quiet, :bashful, :rash, :calm, :gentle, :sassy, | ||
68 | :careful, :quirky] | ||
69 | |||
70 | enumerize :unown_letter, in: [:a, :b, :c, :d, :e, :f, :g, :h, :i, :j, :k, | ||
71 | :l, :m, :n, :o, :p, :q, :r, :s, :t, :u, :v, :w, :x, :y, :z, | ||
72 | :question, :exclamation] | ||
73 | |||
74 | validates :pokeball, presence: true | ||
75 | enumerize :pokeball, in: [:master, :ultra, :great, :poke, :safari, :net, | ||
76 | :dive, :nest, :repeat, :timer, :luxury, :premier] | ||
77 | |||
78 | def to_param | ||
79 | uuid | ||
80 | end | ||
81 | |||
82 | def outsider? | ||
83 | (trainer.nil?) or (ot_name != trainer.name) or (ot_number != trainer.number) | ||
84 | end | ||
85 | |||
86 | def display_ot_number | ||
87 | ot_number.to_s.rjust(5, '0') | ||
88 | end | ||
89 | |||
90 | def nature_benefits?(stat) | ||
91 | if stat == :attack | ||
92 | [:lonely, :brave, :adamant, :naughty].include? nature.intern | ||
93 | elsif stat == :defense | ||
94 | [:bold, :relaxed, :impish, :lax].include? nature.intern | ||
95 | elsif stat == :speed | ||
96 | [:timid, :hasty, :jolly, :naive].include? nature.intern | ||
97 | elsif stat == :special_attack | ||
98 | [:modest, :mild, :quiet, :rash].include? nature.intern | ||
99 | elsif stat == :special_defense | ||
100 | [:calm, :gentle, :sassy, :careful].include? nature.intern | ||
101 | else | ||
102 | false | ||
103 | end | ||
104 | end | ||
105 | |||
106 | def nature_hinders?(stat) | ||
107 | if stat == :attack | ||
108 | [:bold, :timid, :modest, :calm].include? nature.intern | ||
109 | elsif stat == :defense | ||
110 | [:lonely, :hasty, :mild, :gentle].include? nature.intern | ||
111 | elsif stat == :speed | ||
112 | [:brave, :relaxed, :quiet, :sassy].include? nature.intern | ||
113 | elsif stat == :special_attack | ||
114 | [:adamant, :impish, :jolly, :careful].include? nature.intern | ||
115 | elsif stat == :special_defense | ||
116 | [:naughty, :lax, :naive, :rash].include? nature.intern | ||
117 | else | ||
118 | false | ||
119 | end | ||
120 | end | ||
121 | |||
122 | def pokeball_icon_path | ||
123 | "pokeviewer/items/#{Pokemon.pokeball.values.find_index(pokeball) + 1}.png" | ||
124 | end | ||
125 | |||
126 | def gift_ribbon_description(ribbon) | ||
127 | if trainer.nil? | ||
128 | "" | ||
129 | else | ||
130 | trainer.gift_ribbon_description(ribbon) | ||
131 | end | ||
132 | end | ||
133 | |||
134 | def gender_symbol | ||
135 | case gender.intern | ||
136 | when :female | ||
137 | "♀" | ||
138 | when :male | ||
139 | "♂" | ||
140 | when :genderless | ||
141 | "" | ||
142 | end | ||
143 | end | ||
144 | |||
145 | private | ||
146 | |||
147 | def set_uuid | ||
148 | self.uuid = SecureRandom.uuid | ||
149 | end | ||
150 | |||
151 | def uuid_is_constant | ||
152 | errors.add(:uuid, "can't be changed") if self.uuid_changed? | ||
153 | end | ||
154 | |||
155 | def current_is_cached | ||
156 | if self.revisions.empty? | ||
157 | unless self.current_id.nil? | ||
158 | errors.add(:current, "must be null when there are no revisions") | ||
159 | end | ||
160 | else | ||
161 | unless self.current_id = self.revisions.last.id | ||
162 | errors.add(:current, "is not up-to-date") | ||
163 | end | ||
164 | end | ||
165 | end | ||
166 | end | ||
167 | end | ||
diff --git a/app/models/pokeviewer/revision.rb b/app/models/pokeviewer/revision.rb deleted file mode 100644 index 05d2838..0000000 --- a/app/models/pokeviewer/revision.rb +++ /dev/null | |||
@@ -1,496 +0,0 @@ | |||
1 | require 'active_record/diff' | ||
2 | |||
3 | module Pokeviewer | ||
4 | class Revision < ApplicationRecord | ||
5 | include ActiveRecord::Diff | ||
6 | |||
7 | diff :species_id, :nickname, :level, :hp, :attack, :defense, | ||
8 | :special_attack, :special_defense, :speed, :coolness, :beauty, :cuteness, | ||
9 | :smartness, :toughness, :sheen, :item_id, :move_1_id, :move_2_id, | ||
10 | :move_3_id, :move_4_id, :move_1_pp_bonuses, :move_2_pp_bonuses, | ||
11 | :move_3_pp_bonuses, :move_4_pp_bonuses, :cool_ribbons, :beauty_ribbons, | ||
12 | :cute_ribbons, :smart_ribbons, :tough_ribbons, :champion_ribbon, | ||
13 | :winning_ribbon, :victory_ribbon, :artist_ribbon, :effort_ribbon, | ||
14 | :marine_ribbon, :land_ribbon, :sky_ribbon, :country_ribbon, | ||
15 | :national_ribbon, :earth_ribbon, :world_ribbon | ||
16 | |||
17 | belongs_to :pokemon | ||
18 | acts_as_sequenced scope: :pokemon_id | ||
19 | |||
20 | after_create :cache_pokemon_current | ||
21 | |||
22 | belongs_to :species | ||
23 | |||
24 | validates :nickname, presence: true | ||
25 | |||
26 | validates :experience, presence: true, | ||
27 | numericality: { greater_than_or_equal_to: 1, only_integer: true } | ||
28 | |||
29 | validates :level, presence: true, | ||
30 | numericality: { greater_than_or_equal_to: 1, only_integer: true } | ||
31 | |||
32 | validates :hp, presence: true, | ||
33 | numericality: { greater_than_or_equal_to: 1, only_integer: true } | ||
34 | |||
35 | validates :attack, presence: true, | ||
36 | numericality: { greater_than_or_equal_to: 1, only_integer: true } | ||
37 | |||
38 | validates :defense, presence: true, | ||
39 | numericality: { greater_than_or_equal_to: 1, only_integer: true } | ||
40 | |||
41 | validates :special_attack, presence: true, | ||
42 | numericality: { greater_than_or_equal_to: 1, only_integer: true } | ||
43 | |||
44 | validates :special_defense, presence: true, | ||
45 | numericality: { greater_than_or_equal_to: 1, only_integer: true } | ||
46 | |||
47 | validates :speed, presence: true, | ||
48 | numericality: { greater_than_or_equal_to: 1, only_integer: true } | ||
49 | |||
50 | validates :coolness, presence: true, | ||
51 | numericality: { | ||
52 | greater_than_or_equal_to: 0, | ||
53 | less_than_or_equal_to: 10, | ||
54 | only_integer: true } | ||
55 | |||
56 | validates :beauty, presence: true, | ||
57 | numericality: { | ||
58 | greater_than_or_equal_to: 0, | ||
59 | less_than_or_equal_to: 10, | ||
60 | only_integer: true } | ||
61 | |||
62 | validates :cuteness, presence: true, | ||
63 | numericality: { | ||
64 | greater_than_or_equal_to: 0, | ||
65 | less_than_or_equal_to: 10, | ||
66 | only_integer: true } | ||
67 | |||
68 | validates :smartness, presence: true, | ||
69 | numericality: { | ||
70 | greater_than_or_equal_to: 0, | ||
71 | less_than_or_equal_to: 10, | ||
72 | only_integer: true } | ||
73 | |||
74 | validates :toughness, presence: true, | ||
75 | numericality: { | ||
76 | greater_than_or_equal_to: 0, | ||
77 | less_than_or_equal_to: 10, | ||
78 | only_integer: true } | ||
79 | |||
80 | validates :sheen, presence: true, | ||
81 | numericality: { | ||
82 | greater_than_or_equal_to: 0, | ||
83 | less_than_or_equal_to: 10, | ||
84 | only_integer: true } | ||
85 | |||
86 | belongs_to :item, optional: true | ||
87 | |||
88 | belongs_to :move_1, class_name: "Move" | ||
89 | belongs_to :move_2, class_name: "Move", optional: true | ||
90 | belongs_to :move_3, class_name: "Move", optional: true | ||
91 | belongs_to :move_4, class_name: "Move", optional: true | ||
92 | |||
93 | validates :move_1_pp_bonuses, presence: true, | ||
94 | numericality: { | ||
95 | greater_than_or_equal_to: 0, | ||
96 | less_than_or_equal_to: 3, | ||
97 | only_integer: true} | ||
98 | |||
99 | validates :move_2_pp_bonuses, presence: true, | ||
100 | numericality: { | ||
101 | greater_than_or_equal_to: 0, | ||
102 | less_than_or_equal_to: 3, | ||
103 | only_integer: true} | ||
104 | |||
105 | validates :move_3_pp_bonuses, presence: true, | ||
106 | numericality: { | ||
107 | greater_than_or_equal_to: 0, | ||
108 | less_than_or_equal_to: 3, | ||
109 | only_integer: true} | ||
110 | |||
111 | validates :move_4_pp_bonuses, presence: true, | ||
112 | numericality: { | ||
113 | greater_than_or_equal_to: 0, | ||
114 | less_than_or_equal_to: 3, | ||
115 | only_integer: true} | ||
116 | |||
117 | validates :cool_ribbons, presence: true, | ||
118 | numericality: { | ||
119 | greater_than_or_equal_to: 0, | ||
120 | less_than_or_equal_to: 4, | ||
121 | only_integer: true} | ||
122 | |||
123 | validates :beauty_ribbons, presence: true, | ||
124 | numericality: { | ||
125 | greater_than_or_equal_to: 0, | ||
126 | less_than_or_equal_to: 4, | ||
127 | only_integer: true} | ||
128 | |||
129 | validates :cute_ribbons, presence: true, | ||
130 | numericality: { | ||
131 | greater_than_or_equal_to: 0, | ||
132 | less_than_or_equal_to: 4, | ||
133 | only_integer: true} | ||
134 | |||
135 | validates :smart_ribbons, presence: true, | ||
136 | numericality: { | ||
137 | greater_than_or_equal_to: 0, | ||
138 | less_than_or_equal_to: 4, | ||
139 | only_integer: true} | ||
140 | |||
141 | validates :tough_ribbons, presence: true, | ||
142 | numericality: { | ||
143 | greater_than_or_equal_to: 0, | ||
144 | less_than_or_equal_to: 4, | ||
145 | only_integer: true} | ||
146 | |||
147 | def icon_path | ||
148 | form = "" | ||
149 | if species_id == 201 | ||
150 | # Handle Unown form | ||
151 | form = "-#{pokemon.unown_letter}" | ||
152 | elsif species_id == 386 | ||
153 | # Handle Deoxys forms | ||
154 | if pokemon.trainer.firered? | ||
155 | form = "-attack" | ||
156 | elsif pokemon.trainer.leafgreen? | ||
157 | form = "-defense" | ||
158 | elsif pokemon.trainer.emerald? | ||
159 | form = "-speed" | ||
160 | end | ||
161 | end | ||
162 | |||
163 | "pokeviewer/icons/#{species_id}#{form}.png" | ||
164 | end | ||
165 | |||
166 | def sprite_path | ||
167 | shininess = "normal" | ||
168 | if pokemon.shiny | ||
169 | shininess = "shiny" | ||
170 | end | ||
171 | |||
172 | game = "ruby-sapphire" | ||
173 | unless pokemon.trainer.nil? | ||
174 | if (pokemon.trainer.firered? or pokemon.trainer.leafgreen?) and (species_id <= 151 or species_id == 216 or species_id == 386) | ||
175 | game = "firered-leafgreen" | ||
176 | elsif pokemon.trainer.emerald? | ||
177 | game = "emerald" | ||
178 | end | ||
179 | end | ||
180 | |||
181 | form = "" | ||
182 | if species_id == 201 | ||
183 | # Handle Unown forms | ||
184 | form = "-#{pokemon.unown_letter}" | ||
185 | elsif species_id == 386 | ||
186 | # Handle Deoxys forms | ||
187 | if pokemon.trainer.firered? | ||
188 | form = "-attack" | ||
189 | elsif pokemon.trainer.leafgreen? | ||
190 | form = "-defense" | ||
191 | elsif pokemon.trainer.emerald? | ||
192 | form = "-speed" | ||
193 | end | ||
194 | end | ||
195 | |||
196 | if game == "emerald" | ||
197 | "pokeviewer/sprites/emerald/#{shininess}/#{species_id}#{form}.gif" | ||
198 | else | ||
199 | "pokeviewer/sprites/#{game}/#{shininess}/#{species_id}#{form}.png" | ||
200 | end | ||
201 | end | ||
202 | |||
203 | def ability | ||
204 | if pokemon.second_ability | ||
205 | species.ability_2 | ||
206 | else | ||
207 | species.ability_1 | ||
208 | end | ||
209 | end | ||
210 | |||
211 | def move_1_pp | ||
212 | move_1.pp * (5 + move_1_pp_bonuses) / 5 | ||
213 | end | ||
214 | |||
215 | def move_2_pp | ||
216 | move_2.pp * (5 + move_2_pp_bonuses) / 5 | ||
217 | end | ||
218 | |||
219 | def move_3_pp | ||
220 | move_3.pp * (5 + move_3_pp_bonuses) / 5 | ||
221 | end | ||
222 | |||
223 | def move_4_pp | ||
224 | move_4.pp * (5 + move_4_pp_bonuses) / 5 | ||
225 | end | ||
226 | |||
227 | def ribbons | ||
228 | result = [] | ||
229 | |||
230 | if cool_ribbons >= 1 | ||
231 | result << { | ||
232 | filename: "cool-ribbon.png", | ||
233 | name: "Cool Ribbon", | ||
234 | description: "Cool Contest Normal Rank Winner!" | ||
235 | } | ||
236 | end | ||
237 | |||
238 | if cool_ribbons >= 2 | ||
239 | result << { | ||
240 | filename: "cool-ribbon-super.png", | ||
241 | name: "Cool Ribbon Super", | ||
242 | description: "Cool Contest Super Rank Winner!" | ||
243 | } | ||
244 | end | ||
245 | |||
246 | if cool_ribbons >= 3 | ||
247 | result << { | ||
248 | filename: "cool-ribbon-hyper.png", | ||
249 | name: "Cool Ribbon Hyper", | ||
250 | description: "Cool Contest Hyper Rank Winner!" | ||
251 | } | ||
252 | end | ||
253 | |||
254 | if cool_ribbons == 4 | ||
255 | result << { | ||
256 | filename: "cool-ribbon-master.png", | ||
257 | name: "Cool Ribbon Master", | ||
258 | description: "Cool Contest Master Rank Winner!" | ||
259 | } | ||
260 | end | ||
261 | |||
262 | if beauty_ribbons >= 1 | ||
263 | result << { | ||
264 | filename: "beauty-ribbon.png", | ||
265 | name: "Beauty Ribbon", | ||
266 | description: "Beauty Contest Normal Rank Winner!" | ||
267 | } | ||
268 | end | ||
269 | |||
270 | if beauty_ribbons >= 2 | ||
271 | result << { | ||
272 | filename: "beauty-ribbon-super.png", | ||
273 | name: "Beauty Ribbon Super", | ||
274 | description: "Beauty Contest Super Rank Winner!" | ||
275 | } | ||
276 | end | ||
277 | |||
278 | if beauty_ribbons >= 3 | ||
279 | result << { | ||
280 | filename: "beauty-ribbon-hyper.png", | ||
281 | name: "Beauty Ribbon Hyper", | ||
282 | description: "Beauty Contest Hyper Rank Winner!" | ||
283 | } | ||
284 | end | ||
285 | |||
286 | if beauty_ribbons == 4 | ||
287 | result << { | ||
288 | filename: "beauty-ribbon-master.png", | ||
289 | name: "Beauty Ribbon Master", | ||
290 | description: "Beauty Contest Master Rank Winner!" | ||
291 | } | ||
292 | end | ||
293 | |||
294 | if cute_ribbons >= 1 | ||
295 | result << { | ||
296 | filename: "cute-ribbon.png", | ||
297 | name: "Cute Ribbon", | ||
298 | description: "Cute Contest Normal Rank Winner!" | ||
299 | } | ||
300 | end | ||
301 | |||
302 | if cute_ribbons >= 2 | ||
303 | result << { | ||
304 | filename: "cute-ribbon-super.png", | ||
305 | name: "Cute Ribbon Super", | ||
306 | description: "Cute Contest Super Rank Winner!" | ||
307 | } | ||
308 | end | ||
309 | |||
310 | if cute_ribbons >= 3 | ||
311 | result << { | ||
312 | filename: "cute-ribbon-hyper.png", | ||
313 | name: "Cute Ribbon Hyper", | ||
314 | description: "Cute Contest Hyper Rank Winner!" | ||
315 | } | ||
316 | end | ||
317 | |||
318 | if cute_ribbons == 4 | ||
319 | result << { | ||
320 | filename: "cute-ribbon-master.png", | ||
321 | name: "Cute Ribbon Master", | ||
322 | description: "Cute Contest Master Rank Winner!" | ||
323 | } | ||
324 | end | ||
325 | |||
326 | if smart_ribbons >= 1 | ||
327 | result << { | ||
328 | filename: "smart-ribbon.png", | ||
329 | name: "Smart Ribbon", | ||
330 | description: "Smart Contest Normal Rank Winner!" | ||
331 | } | ||
332 | end | ||
333 | |||
334 | if smart_ribbons >= 2 | ||
335 | result << { | ||
336 | filename: "smart-ribbon-super.png", | ||
337 | name: "Smart Ribbon Super", | ||
338 | description: "Smart Contest Super Rank Winner!" | ||
339 | } | ||
340 | end | ||
341 | |||
342 | if smart_ribbons >= 3 | ||
343 | result << { | ||
344 | filename: "smart-ribbon-hyper.png", | ||
345 | name: "Smart Ribbon Hyper", | ||
346 | description: "Smart Contest Hyper Rank Winner!" | ||
347 | } | ||
348 | end | ||
349 | |||
350 | if smart_ribbons == 4 | ||
351 | result << { | ||
352 | filename: "smart-ribbon-master.png", | ||
353 | name: "Smart Ribbon Master", | ||
354 | description: "Smart Contest Master Rank Winner!" | ||
355 | } | ||
356 | end | ||
357 | |||
358 | if tough_ribbons >= 1 | ||
359 | result << { | ||
360 | filename: "tough-ribbon.png", | ||
361 | name: "Tough Ribbon", | ||
362 | description: "Tough Contest Normal Rank Winner!" | ||
363 | } | ||
364 | end | ||
365 | |||
366 | if tough_ribbons >= 2 | ||
367 | result << { | ||
368 | filename: "tough-ribbon-super.png", | ||
369 | name: "Tough Ribbon Super", | ||
370 | description: "Tough Contest Super Rank Winner!" | ||
371 | } | ||
372 | end | ||
373 | |||
374 | if tough_ribbons >= 3 | ||
375 | result << { | ||
376 | filename: "tough-ribbon-hyper.png", | ||
377 | name: "Tough Ribbon Hyper", | ||
378 | description: "Tough Contest Hyper Rank Winner!" | ||
379 | } | ||
380 | end | ||
381 | |||
382 | if tough_ribbons == 4 | ||
383 | result << { | ||
384 | filename: "tough-ribbon-master.png", | ||
385 | name: "Tough Ribbon Master", | ||
386 | description: "Tough Contest Master Rank Winner!" | ||
387 | } | ||
388 | end | ||
389 | |||
390 | if champion_ribbon | ||
391 | result << { | ||
392 | filename: "champion-ribbon.png", | ||
393 | name: "Champion Ribbon", | ||
394 | description: "Champion-beating, Hall of Fame Member Ribbon" | ||
395 | } | ||
396 | end | ||
397 | |||
398 | if winning_ribbon | ||
399 | result << { | ||
400 | filename: "winning-ribbon.png", | ||
401 | name: "Winning Ribbon", | ||
402 | description: "Ribbon for clearing LV50 at the Battle Tower." | ||
403 | } | ||
404 | end | ||
405 | |||
406 | if victory_ribbon | ||
407 | result << { | ||
408 | filename: "victory-ribbon.png", | ||
409 | name: "Victory Ribbon", | ||
410 | description: "Won for clearing LV100 at the Battle Tower." | ||
411 | } | ||
412 | end | ||
413 | |||
414 | if artist_ribbon | ||
415 | result << { | ||
416 | filename: "artist-ribbon.png", | ||
417 | name: "Artist Ribbon", | ||
418 | description: "Ribbon for being chosen as a super sketch model." | ||
419 | } | ||
420 | end | ||
421 | |||
422 | if effort_ribbon | ||
423 | result << { | ||
424 | filename: "effort-ribbon.png", | ||
425 | name: "Effort Ribbon", | ||
426 | description: "Ribbon awarded for being a hard worker." | ||
427 | } | ||
428 | end | ||
429 | |||
430 | if marine_ribbon | ||
431 | result << { | ||
432 | filename: "marine-ribbon.png", | ||
433 | name: "Marine Ribbon", | ||
434 | description: pokemon.gift_ribbon_description(:marine_ribbon) | ||
435 | } | ||
436 | end | ||
437 | |||
438 | if land_ribbon | ||
439 | result << { | ||
440 | filename: "land-ribbon.png", | ||
441 | name: "Land Ribbon", | ||
442 | description: pokemon.gift_ribbon_description(:land_ribbon) | ||
443 | } | ||
444 | end | ||
445 | |||
446 | if sky_ribbon | ||
447 | result << { | ||
448 | filename: "sky-ribbon.png", | ||
449 | name: "Sky Ribbon", | ||
450 | description: pokemon.gift_ribbon_description(:sky_ribbon) | ||
451 | } | ||
452 | end | ||
453 | |||
454 | if country_ribbon | ||
455 | result << { | ||
456 | filename: "country-ribbon.png", | ||
457 | name: "Country Ribbon", | ||
458 | description: pokemon.gift_ribbon_description(:country_ribbon) | ||
459 | } | ||
460 | end | ||
461 | |||
462 | if national_ribbon | ||
463 | result << { | ||
464 | filename: "national-ribbon.png", | ||
465 | name: "National Ribbon", | ||
466 | description: pokemon.gift_ribbon_description(:national_ribbon) | ||
467 | } | ||
468 | end | ||
469 | |||
470 | if earth_ribbon | ||
471 | result << { | ||
472 | filename: "earth-ribbon.png", | ||
473 | name: "Earth Ribbon", | ||
474 | description: pokemon.gift_ribbon_description(:earth_ribbon) | ||
475 | } | ||
476 | end | ||
477 | |||
478 | if world_ribbon | ||
479 | result << { | ||
480 | filename: "world-ribbon.png", | ||
481 | name: "World Ribbon", | ||
482 | description: pokemon.gift_ribbon_description(:world_ribbon) | ||
483 | } | ||
484 | end | ||
485 | |||
486 | result | ||
487 | end | ||
488 | |||
489 | private | ||
490 | |||
491 | def cache_pokemon_current | ||
492 | self.pokemon.current_id = self.id | ||
493 | self.pokemon.save! | ||
494 | end | ||
495 | end | ||
496 | end | ||
diff --git a/app/models/pokeviewer/species.rb b/app/models/pokeviewer/species.rb deleted file mode 100644 index 400d679..0000000 --- a/app/models/pokeviewer/species.rb +++ /dev/null | |||
@@ -1,26 +0,0 @@ | |||
1 | module Pokeviewer | ||
2 | class Species < ApplicationRecord | ||
3 | extend Enumerize | ||
4 | |||
5 | has_many :revisions, dependent: :restrict_with_exception | ||
6 | |||
7 | has_many :pokedex_entries, dependent: :destroy | ||
8 | |||
9 | validates :name, presence: true, uniqueness: true | ||
10 | |||
11 | validates :type_1, presence: true | ||
12 | |||
13 | enumerize :type_1, in: Move::TYPES | ||
14 | enumerize :type_2, in: Move::TYPES | ||
15 | |||
16 | belongs_to :ability_1, class_name: "Ability" | ||
17 | belongs_to :ability_2, class_name: "Ability", optional: true | ||
18 | |||
19 | def current_revisions | ||
20 | revisions. | ||
21 | where("pokeviewer_pokemon.current_id = pokeviewer_revisions.id"). | ||
22 | includes(:pokemon). | ||
23 | references(:pokemon) | ||
24 | end | ||
25 | end | ||
26 | end | ||
diff --git a/app/models/pokeviewer/trainer.rb b/app/models/pokeviewer/trainer.rb deleted file mode 100644 index 950dac0..0000000 --- a/app/models/pokeviewer/trainer.rb +++ /dev/null | |||
@@ -1,95 +0,0 @@ | |||
1 | module Pokeviewer | ||
2 | class Trainer < ApplicationRecord | ||
3 | extend Enumerize | ||
4 | |||
5 | has_many :pokemon, dependent: :nullify | ||
6 | |||
7 | has_many :pokedex_entries, dependent: :destroy | ||
8 | |||
9 | validates :number, presence: true, | ||
10 | numericality: { greater_than_or_equal_to: 0, only_integer: true } | ||
11 | |||
12 | validates :name, presence: true, uniqueness: { | ||
13 | scope: :number, | ||
14 | message: "and number should be pairwise unique" } | ||
15 | |||
16 | validates :game, presence: true | ||
17 | enumerize :game, in: [:ruby, :sapphire, :firered, :leafgreen, :emerald], | ||
18 | predicates: true | ||
19 | |||
20 | belongs_to :marine_ribbon, class_name: "GiftRibbon", optional: true | ||
21 | belongs_to :land_ribbon, class_name: "GiftRibbon", optional: true | ||
22 | belongs_to :sky_ribbon, class_name: "GiftRibbon", optional: true | ||
23 | belongs_to :country_ribbon, class_name: "GiftRibbon", optional: true | ||
24 | belongs_to :national_ribbon, class_name: "GiftRibbon", optional: true | ||
25 | belongs_to :earth_ribbon, class_name: "GiftRibbon", optional: true | ||
26 | belongs_to :world_ribbon, class_name: "GiftRibbon", optional: true | ||
27 | |||
28 | validates :box_1_name, presence: true | ||
29 | validates :box_2_name, presence: true | ||
30 | validates :box_3_name, presence: true | ||
31 | validates :box_4_name, presence: true | ||
32 | validates :box_5_name, presence: true | ||
33 | validates :box_6_name, presence: true | ||
34 | validates :box_7_name, presence: true | ||
35 | validates :box_8_name, presence: true | ||
36 | validates :box_9_name, presence: true | ||
37 | validates :box_10_name, presence: true | ||
38 | validates :box_11_name, presence: true | ||
39 | validates :box_12_name, presence: true | ||
40 | validates :box_13_name, presence: true | ||
41 | validates :box_14_name, presence: true | ||
42 | |||
43 | def party | ||
44 | pokemon.party.includes(current: [:species]) | ||
45 | end | ||
46 | |||
47 | def box(n) | ||
48 | pokemon.box(n).includes(current: [:species]) | ||
49 | end | ||
50 | |||
51 | def box_name(n) | ||
52 | if n > 0 and n <= 14 | ||
53 | send "box_#{n}_name".intern | ||
54 | else | ||
55 | nil | ||
56 | end | ||
57 | end | ||
58 | |||
59 | def box_contents(n) | ||
60 | pokes = box(n).to_a | ||
61 | |||
62 | result = [] | ||
63 | (0..29).each do |i| | ||
64 | if pokes.empty? or (pokes.first.slot == i) | ||
65 | result << pokes.shift | ||
66 | else | ||
67 | result << nil | ||
68 | end | ||
69 | end | ||
70 | |||
71 | result | ||
72 | end | ||
73 | |||
74 | def boxes | ||
75 | (1..14).map { |n| { | ||
76 | name: box_name(n), | ||
77 | pokemon: box_contents(n) | ||
78 | }} | ||
79 | end | ||
80 | |||
81 | def display_number | ||
82 | number.to_s.rjust(5, '0') | ||
83 | end | ||
84 | |||
85 | def gift_ribbon_description(ribbon) | ||
86 | gift_ribbon = send ribbon | ||
87 | |||
88 | if gift_ribbon.nil? | ||
89 | "" | ||
90 | else | ||
91 | gift_ribbon.description | ||
92 | end | ||
93 | end | ||
94 | end | ||
95 | end | ||
diff --git a/app/models/revision.rb b/app/models/revision.rb new file mode 100644 index 0000000..477a042 --- /dev/null +++ b/app/models/revision.rb | |||
@@ -0,0 +1,494 @@ | |||
1 | require 'active_record/diff' | ||
2 | |||
3 | class Revision < ApplicationRecord | ||
4 | include ActiveRecord::Diff | ||
5 | |||
6 | diff :species_id, :nickname, :level, :hp, :attack, :defense, | ||
7 | :special_attack, :special_defense, :speed, :coolness, :beauty, :cuteness, | ||
8 | :smartness, :toughness, :sheen, :item_id, :move_1_id, :move_2_id, | ||
9 | :move_3_id, :move_4_id, :move_1_pp_bonuses, :move_2_pp_bonuses, | ||
10 | :move_3_pp_bonuses, :move_4_pp_bonuses, :cool_ribbons, :beauty_ribbons, | ||
11 | :cute_ribbons, :smart_ribbons, :tough_ribbons, :champion_ribbon, | ||
12 | :winning_ribbon, :victory_ribbon, :artist_ribbon, :effort_ribbon, | ||
13 | :marine_ribbon, :land_ribbon, :sky_ribbon, :country_ribbon, | ||
14 | :national_ribbon, :earth_ribbon, :world_ribbon | ||
15 | |||
16 | belongs_to :pokemon | ||
17 | acts_as_sequenced scope: :pokemon_id | ||
18 | |||
19 | after_create :cache_pokemon_current | ||
20 | |||
21 | belongs_to :species | ||
22 | |||
23 | validates :nickname, presence: true | ||
24 | |||
25 | validates :experience, presence: true, | ||
26 | numericality: { greater_than_or_equal_to: 1, only_integer: true } | ||
27 | |||
28 | validates :level, presence: true, | ||
29 | numericality: { greater_than_or_equal_to: 1, only_integer: true } | ||
30 | |||
31 | validates :hp, presence: true, | ||
32 | numericality: { greater_than_or_equal_to: 1, only_integer: true } | ||
33 | |||
34 | validates :attack, presence: true, | ||
35 | numericality: { greater_than_or_equal_to: 1, only_integer: true } | ||
36 | |||
37 | validates :defense, presence: true, | ||
38 | numericality: { greater_than_or_equal_to: 1, only_integer: true } | ||
39 | |||
40 | validates :special_attack, presence: true, | ||
41 | numericality: { greater_than_or_equal_to: 1, only_integer: true } | ||
42 | |||
43 | validates :special_defense, presence: true, | ||
44 | numericality: { greater_than_or_equal_to: 1, only_integer: true } | ||
45 | |||
46 | validates :speed, presence: true, | ||
47 | numericality: { greater_than_or_equal_to: 1, only_integer: true } | ||
48 | |||
49 | validates :coolness, presence: true, | ||
50 | numericality: { | ||
51 | greater_than_or_equal_to: 0, | ||
52 | less_than_or_equal_to: 10, | ||
53 | only_integer: true } | ||
54 | |||
55 | validates :beauty, presence: true, | ||
56 | numericality: { | ||
57 | greater_than_or_equal_to: 0, | ||
58 | less_than_or_equal_to: 10, | ||
59 | only_integer: true } | ||
60 | |||
61 | validates :cuteness, presence: true, | ||
62 | numericality: { | ||
63 | greater_than_or_equal_to: 0, | ||
64 | less_than_or_equal_to: 10, | ||
65 | only_integer: true } | ||
66 | |||
67 | validates :smartness, presence: true, | ||
68 | numericality: { | ||
69 | greater_than_or_equal_to: 0, | ||
70 | less_than_or_equal_to: 10, | ||
71 | only_integer: true } | ||
72 | |||
73 | validates :toughness, presence: true, | ||
74 | numericality: { | ||
75 | greater_than_or_equal_to: 0, | ||
76 | less_than_or_equal_to: 10, | ||
77 | only_integer: true } | ||
78 | |||
79 | validates :sheen, presence: true, | ||
80 | numericality: { | ||
81 | greater_than_or_equal_to: 0, | ||
82 | less_than_or_equal_to: 10, | ||
83 | only_integer: true } | ||
84 | |||
85 | belongs_to :item, optional: true | ||
86 | |||
87 | belongs_to :move_1, class_name: "Move" | ||
88 | belongs_to :move_2, class_name: "Move", optional: true | ||
89 | belongs_to :move_3, class_name: "Move", optional: true | ||
90 | belongs_to :move_4, class_name: "Move", optional: true | ||
91 | |||
92 | validates :move_1_pp_bonuses, presence: true, | ||
93 | numericality: { | ||
94 | greater_than_or_equal_to: 0, | ||
95 | less_than_or_equal_to: 3, | ||
96 | only_integer: true} | ||
97 | |||
98 | validates :move_2_pp_bonuses, presence: true, | ||
99 | numericality: { | ||
100 | greater_than_or_equal_to: 0, | ||
101 | less_than_or_equal_to: 3, | ||
102 | only_integer: true} | ||
103 | |||
104 | validates :move_3_pp_bonuses, presence: true, | ||
105 | numericality: { | ||
106 | greater_than_or_equal_to: 0, | ||
107 | less_than_or_equal_to: 3, | ||
108 | only_integer: true} | ||
109 | |||
110 | validates :move_4_pp_bonuses, presence: true, | ||
111 | numericality: { | ||
112 | greater_than_or_equal_to: 0, | ||
113 | less_than_or_equal_to: 3, | ||
114 | only_integer: true} | ||
115 | |||
116 | validates :cool_ribbons, presence: true, | ||
117 | numericality: { | ||
118 | greater_than_or_equal_to: 0, | ||
119 | less_than_or_equal_to: 4, | ||
120 | only_integer: true} | ||
121 | |||
122 | validates :beauty_ribbons, presence: true, | ||
123 | numericality: { | ||
124 | greater_than_or_equal_to: 0, | ||
125 | less_than_or_equal_to: 4, | ||
126 | only_integer: true} | ||
127 | |||
128 | validates :cute_ribbons, presence: true, | ||
129 | numericality: { | ||
130 | greater_than_or_equal_to: 0, | ||
131 | less_than_or_equal_to: 4, | ||
132 | only_integer: true} | ||
133 | |||
134 | validates :smart_ribbons, presence: true, | ||
135 | numericality: { | ||
136 | greater_than_or_equal_to: 0, | ||
137 | less_than_or_equal_to: 4, | ||
138 | only_integer: true} | ||
139 | |||
140 | validates :tough_ribbons, presence: true, | ||
141 | numericality: { | ||
142 | greater_than_or_equal_to: 0, | ||
143 | less_than_or_equal_to: 4, | ||
144 | only_integer: true} | ||
145 | |||
146 | def icon_path | ||
147 | form = "" | ||
148 | if species_id == 201 | ||
149 | # Handle Unown form | ||
150 | form = "-#{pokemon.unown_letter}" | ||
151 | elsif species_id == 386 | ||
152 | # Handle Deoxys forms | ||
153 | if pokemon.trainer.firered? | ||
154 | form = "-attack" | ||
155 | elsif pokemon.trainer.leafgreen? | ||
156 | form = "-defense" | ||
157 | elsif pokemon.trainer.emerald? | ||
158 | form = "-speed" | ||
159 | end | ||
160 | end | ||
161 | |||
162 | "icons/#{species_id}#{form}.png" | ||
163 | end | ||
164 | |||
165 | def sprite_path | ||
166 | shininess = "normal" | ||
167 | if pokemon.shiny | ||
168 | shininess = "shiny" | ||
169 | end | ||
170 | |||
171 | game = "ruby-sapphire" | ||
172 | unless pokemon.trainer.nil? | ||
173 | if (pokemon.trainer.firered? or pokemon.trainer.leafgreen?) and (species_id <= 151 or species_id == 216 or species_id == 386) | ||
174 | game = "firered-leafgreen" | ||
175 | elsif pokemon.trainer.emerald? | ||
176 | game = "emerald" | ||
177 | end | ||
178 | end | ||
179 | |||
180 | form = "" | ||
181 | if species_id == 201 | ||
182 | # Handle Unown forms | ||
183 | form = "-#{pokemon.unown_letter}" | ||
184 | elsif species_id == 386 | ||
185 | # Handle Deoxys forms | ||
186 | if pokemon.trainer.firered? | ||
187 | form = "-attack" | ||
188 | elsif pokemon.trainer.leafgreen? | ||
189 | form = "-defense" | ||
190 | elsif pokemon.trainer.emerald? | ||
191 | form = "-speed" | ||
192 | end | ||
193 | end | ||
194 | |||
195 | if game == "emerald" | ||
196 | "sprites/emerald/#{shininess}/#{species_id}#{form}.gif" | ||
197 | else | ||
198 | "sprites/#{game}/#{shininess}/#{species_id}#{form}.png" | ||
199 | end | ||
200 | end | ||
201 | |||
202 | def ability | ||
203 | if pokemon.second_ability | ||
204 | species.ability_2 | ||
205 | else | ||
206 | species.ability_1 | ||
207 | end | ||
208 | end | ||
209 | |||
210 | def move_1_pp | ||
211 | move_1.pp * (5 + move_1_pp_bonuses) / 5 | ||
212 | end | ||
213 | |||
214 | def move_2_pp | ||
215 | move_2.pp * (5 + move_2_pp_bonuses) / 5 | ||
216 | end | ||
217 | |||
218 | def move_3_pp | ||
219 | move_3.pp * (5 + move_3_pp_bonuses) / 5 | ||
220 | end | ||
221 | |||
222 | def move_4_pp | ||
223 | move_4.pp * (5 + move_4_pp_bonuses) / 5 | ||
224 | end | ||
225 | |||
226 | def ribbons | ||
227 | result = [] | ||
228 | |||
229 | if cool_ribbons >= 1 | ||
230 | result << { | ||
231 | filename: "cool-ribbon.png", | ||
232 | name: "Cool Ribbon", | ||
233 | description: "Cool Contest Normal Rank Winner!" | ||
234 | } | ||
235 | end | ||
236 | |||
237 | if cool_ribbons >= 2 | ||
238 | result << { | ||
239 | filename: "cool-ribbon-super.png", | ||
240 | name: "Cool Ribbon Super", | ||
241 | description: "Cool Contest Super Rank Winner!" | ||
242 | } | ||
243 | end | ||
244 | |||
245 | if cool_ribbons >= 3 | ||
246 | result << { | ||
247 | filename: "cool-ribbon-hyper.png", | ||
248 | name: "Cool Ribbon Hyper", | ||
249 | description: "Cool Contest Hyper Rank Winner!" | ||
250 | } | ||
251 | end | ||
252 | |||
253 | if cool_ribbons == 4 | ||
254 | result << { | ||
255 | filename: "cool-ribbon-master.png", | ||
256 | name: "Cool Ribbon Master", | ||
257 | description: "Cool Contest Master Rank Winner!" | ||
258 | } | ||
259 | end | ||
260 | |||
261 | if beauty_ribbons >= 1 | ||
262 | result << { | ||
263 | filename: "beauty-ribbon.png", | ||
264 | name: "Beauty Ribbon", | ||
265 | description: "Beauty Contest Normal Rank Winner!" | ||
266 | } | ||
267 | end | ||
268 | |||
269 | if beauty_ribbons >= 2 | ||
270 | result << { | ||
271 | filename: "beauty-ribbon-super.png", | ||
272 | name: "Beauty Ribbon Super", | ||
273 | description: "Beauty Contest Super Rank Winner!" | ||
274 | } | ||
275 | end | ||
276 | |||
277 | if beauty_ribbons >= 3 | ||
278 | result << { | ||
279 | filename: "beauty-ribbon-hyper.png", | ||
280 | name: "Beauty Ribbon Hyper", | ||
281 | description: "Beauty Contest Hyper Rank Winner!" | ||
282 | } | ||
283 | end | ||
284 | |||
285 | if beauty_ribbons == 4 | ||
286 | result << { | ||
287 | filename: "beauty-ribbon-master.png", | ||
288 | name: "Beauty Ribbon Master", | ||
289 | description: "Beauty Contest Master Rank Winner!" | ||
290 | } | ||
291 | end | ||
292 | |||
293 | if cute_ribbons >= 1 | ||
294 | result << { | ||
295 | filename: "cute-ribbon.png", | ||
296 | name: "Cute Ribbon", | ||
297 | description: "Cute Contest Normal Rank Winner!" | ||
298 | } | ||
299 | end | ||
300 | |||
301 | if cute_ribbons >= 2 | ||
302 | result << { | ||
303 | filename: "cute-ribbon-super.png", | ||
304 | name: "Cute Ribbon Super", | ||
305 | description: "Cute Contest Super Rank Winner!" | ||
306 | } | ||
307 | end | ||
308 | |||
309 | if cute_ribbons >= 3 | ||
310 | result << { | ||
311 | filename: "cute-ribbon-hyper.png", | ||
312 | name: "Cute Ribbon Hyper", | ||
313 | description: "Cute Contest Hyper Rank Winner!" | ||
314 | } | ||
315 | end | ||
316 | |||
317 | if cute_ribbons == 4 | ||
318 | result << { | ||
319 | filename: "cute-ribbon-master.png", | ||
320 | name: "Cute Ribbon Master", | ||
321 | description: "Cute Contest Master Rank Winner!" | ||
322 | } | ||
323 | end | ||
324 | |||
325 | if smart_ribbons >= 1 | ||
326 | result << { | ||
327 | filename: "smart-ribbon.png", | ||
328 | name: "Smart Ribbon", | ||
329 | description: "Smart Contest Normal Rank Winner!" | ||
330 | } | ||
331 | end | ||
332 | |||
333 | if smart_ribbons >= 2 | ||
334 | result << { | ||
335 | filename: "smart-ribbon-super.png", | ||
336 | name: "Smart Ribbon Super", | ||
337 | description: "Smart Contest Super Rank Winner!" | ||
338 | } | ||
339 | end | ||
340 | |||
341 | if smart_ribbons >= 3 | ||
342 | result << { | ||
343 | filename: "smart-ribbon-hyper.png", | ||
344 | name: "Smart Ribbon Hyper", | ||
345 | description: "Smart Contest Hyper Rank Winner!" | ||
346 | } | ||
347 | end | ||
348 | |||
349 | if smart_ribbons == 4 | ||
350 | result << { | ||
351 | filename: "smart-ribbon-master.png", | ||
352 | name: "Smart Ribbon Master", | ||
353 | description: "Smart Contest Master Rank Winner!" | ||
354 | } | ||
355 | end | ||
356 | |||
357 | if tough_ribbons >= 1 | ||
358 | result << { | ||
359 | filename: "tough-ribbon.png", | ||
360 | name: "Tough Ribbon", | ||
361 | description: "Tough Contest Normal Rank Winner!" | ||
362 | } | ||
363 | end | ||
364 | |||
365 | if tough_ribbons >= 2 | ||
366 | result << { | ||
367 | filename: "tough-ribbon-super.png", | ||
368 | name: "Tough Ribbon Super", | ||
369 | description: "Tough Contest Super Rank Winner!" | ||
370 | } | ||
371 | end | ||
372 | |||
373 | if tough_ribbons >= 3 | ||
374 | result << { | ||
375 | filename: "tough-ribbon-hyper.png", | ||
376 | name: "Tough Ribbon Hyper", | ||
377 | description: "Tough Contest Hyper Rank Winner!" | ||
378 | } | ||
379 | end | ||
380 | |||
381 | if tough_ribbons == 4 | ||
382 | result << { | ||
383 | filename: "tough-ribbon-master.png", | ||
384 | name: "Tough Ribbon Master", | ||
385 | description: "Tough Contest Master Rank Winner!" | ||
386 | } | ||
387 | end | ||
388 | |||
389 | if champion_ribbon | ||
390 | result << { | ||
391 | filename: "champion-ribbon.png", | ||
392 | name: "Champion Ribbon", | ||
393 | description: "Champion-beating, Hall of Fame Member Ribbon" | ||
394 | } | ||
395 | end | ||
396 | |||
397 | if winning_ribbon | ||
398 | result << { | ||
399 | filename: "winning-ribbon.png", | ||
400 | name: "Winning Ribbon", | ||
401 | description: "Ribbon for clearing LV50 at the Battle Tower." | ||
402 | } | ||
403 | end | ||
404 | |||
405 | if victory_ribbon | ||
406 | result << { | ||
407 | filename: "victory-ribbon.png", | ||
408 | name: "Victory Ribbon", | ||
409 | description: "Won for clearing LV100 at the Battle Tower." | ||
410 | } | ||
411 | end | ||
412 | |||
413 | if artist_ribbon | ||
414 | result << { | ||
415 | filename: "artist-ribbon.png", | ||
416 | name: "Artist Ribbon", | ||
417 | description: "Ribbon for being chosen as a super sketch model." | ||
418 | } | ||
419 | end | ||
420 | |||
421 | if effort_ribbon | ||
422 | result << { | ||
423 | filename: "effort-ribbon.png", | ||
424 | name: "Effort Ribbon", | ||
425 | description: "Ribbon awarded for being a hard worker." | ||
426 | } | ||
427 | end | ||
428 | |||
429 | if marine_ribbon | ||
430 | result << { | ||
431 | filename: "marine-ribbon.png", | ||
432 | name: "Marine Ribbon", | ||
433 | description: pokemon.gift_ribbon_description(:marine_ribbon) | ||
434 | } | ||
435 | end | ||
436 | |||
437 | if land_ribbon | ||
438 | result << { | ||
439 | filename: "land-ribbon.png", | ||
440 | name: "Land Ribbon", | ||
441 | description: pokemon.gift_ribbon_description(:land_ribbon) | ||
442 | } | ||
443 | end | ||
444 | |||
445 | if sky_ribbon | ||
446 | result << { | ||
447 | filename: "sky-ribbon.png", | ||
448 | name: "Sky Ribbon", | ||
449 | description: pokemon.gift_ribbon_description(:sky_ribbon) | ||
450 | } | ||
451 | end | ||
452 | |||
453 | if country_ribbon | ||
454 | result << { | ||
455 | filename: "country-ribbon.png", | ||
456 | name: "Country Ribbon", | ||
457 | description: pokemon.gift_ribbon_description(:country_ribbon) | ||
458 | } | ||
459 | end | ||
460 | |||
461 | if national_ribbon | ||
462 | result << { | ||
463 | filename: "national-ribbon.png", | ||
464 | name: "National Ribbon", | ||
465 | description: pokemon.gift_ribbon_description(:national_ribbon) | ||
466 | } | ||
467 | end | ||
468 | |||
469 | if earth_ribbon | ||
470 | result << { | ||
471 | filename: "earth-ribbon.png", | ||
472 | name: "Earth Ribbon", | ||
473 | description: pokemon.gift_ribbon_description(:earth_ribbon) | ||
474 | } | ||
475 | end | ||
476 | |||
477 | if world_ribbon | ||
478 | result << { | ||
479 | filename: "world-ribbon.png", | ||
480 | name: "World Ribbon", | ||
481 | description: pokemon.gift_ribbon_description(:world_ribbon) | ||
482 | } | ||
483 | end | ||
484 | |||
485 | result | ||
486 | end | ||
487 | |||
488 | private | ||
489 | |||
490 | def cache_pokemon_current | ||
491 | self.pokemon.current_id = self.id | ||
492 | self.pokemon.save! | ||
493 | end | ||
494 | end | ||
diff --git a/app/models/species.rb b/app/models/species.rb new file mode 100644 index 0000000..0623f11 --- /dev/null +++ b/app/models/species.rb | |||
@@ -0,0 +1,24 @@ | |||
1 | class Species < ApplicationRecord | ||
2 | extend Enumerize | ||
3 | |||
4 | has_many :revisions, dependent: :restrict_with_exception | ||
5 | |||
6 | has_many :pokedex_entries, dependent: :destroy | ||
7 | |||
8 | validates :name, presence: true, uniqueness: true | ||
9 | |||
10 | validates :type_1, presence: true | ||
11 | |||
12 | enumerize :type_1, in: Move::TYPES | ||
13 | enumerize :type_2, in: Move::TYPES | ||
14 | |||
15 | belongs_to :ability_1, class_name: "Ability" | ||
16 | belongs_to :ability_2, class_name: "Ability", optional: true | ||
17 | |||
18 | def current_revisions | ||
19 | revisions. | ||
20 | where("pokemon.current_id = revisions.id"). | ||
21 | includes(:pokemon). | ||
22 | references(:pokemon) | ||
23 | end | ||
24 | end | ||
diff --git a/app/models/trainer.rb b/app/models/trainer.rb new file mode 100644 index 0000000..930dbaf --- /dev/null +++ b/app/models/trainer.rb | |||
@@ -0,0 +1,93 @@ | |||
1 | class Trainer < ApplicationRecord | ||
2 | extend Enumerize | ||
3 | |||
4 | has_many :pokemon, dependent: :nullify | ||
5 | |||
6 | has_many :pokedex_entries, dependent: :destroy | ||
7 | |||
8 | validates :number, presence: true, | ||
9 | numericality: { greater_than_or_equal_to: 0, only_integer: true } | ||
10 | |||
11 | validates :name, presence: true, uniqueness: { | ||
12 | scope: :number, | ||
13 | message: "and number should be pairwise unique" } | ||
14 | |||
15 | validates :game, presence: true | ||
16 | enumerize :game, in: [:ruby, :sapphire, :firered, :leafgreen, :emerald], | ||
17 | predicates: true | ||
18 | |||
19 | belongs_to :marine_ribbon, class_name: "GiftRibbon", optional: true | ||
20 | belongs_to :land_ribbon, class_name: "GiftRibbon", optional: true | ||
21 | belongs_to :sky_ribbon, class_name: "GiftRibbon", optional: true | ||
22 | belongs_to :country_ribbon, class_name: "GiftRibbon", optional: true | ||
23 | belongs_to :national_ribbon, class_name: "GiftRibbon", optional: true | ||
24 | belongs_to :earth_ribbon, class_name: "GiftRibbon", optional: true | ||
25 | belongs_to :world_ribbon, class_name: "GiftRibbon", optional: true | ||
26 | |||
27 | validates :box_1_name, presence: true | ||
28 | validates :box_2_name, presence: true | ||
29 | validates :box_3_name, presence: true | ||
30 | validates :box_4_name, presence: true | ||
31 | validates :box_5_name, presence: true | ||
32 | validates :box_6_name, presence: true | ||
33 | validates :box_7_name, presence: true | ||
34 | validates :box_8_name, presence: true | ||
35 | validates :box_9_name, presence: true | ||
36 | validates :box_10_name, presence: true | ||
37 | validates :box_11_name, presence: true | ||
38 | validates :box_12_name, presence: true | ||
39 | validates :box_13_name, presence: true | ||
40 | validates :box_14_name, presence: true | ||
41 | |||
42 | def party | ||
43 | pokemon.party.includes(current: [:species]) | ||
44 | end | ||
45 | |||
46 | def box(n) | ||
47 | pokemon.box(n).includes(current: [:species]) | ||
48 | end | ||
49 | |||
50 | def box_name(n) | ||
51 | if n > 0 and n <= 14 | ||
52 | send "box_#{n}_name".intern | ||
53 | else | ||
54 | nil | ||
55 | end | ||
56 | end | ||
57 | |||
58 | def box_contents(n) | ||
59 | pokes = box(n).to_a | ||
60 | |||
61 | result = [] | ||
62 | (0..29).each do |i| | ||
63 | if pokes.empty? or (pokes.first.slot == i) | ||
64 | result << pokes.shift | ||
65 | else | ||
66 | result << nil | ||
67 | end | ||
68 | end | ||
69 | |||
70 | result | ||
71 | end | ||
72 | |||
73 | def boxes | ||
74 | (1..14).map { |n| { | ||
75 | name: box_name(n), | ||
76 | pokemon: box_contents(n) | ||
77 | }} | ||
78 | end | ||
79 | |||
80 | def display_number | ||
81 | number.to_s.rjust(5, '0') | ||
82 | end | ||
83 | |||
84 | def gift_ribbon_description(ribbon) | ||
85 | gift_ribbon = send ribbon | ||
86 | |||
87 | if gift_ribbon.nil? | ||
88 | "" | ||
89 | else | ||
90 | gift_ribbon.description | ||
91 | end | ||
92 | end | ||
93 | end | ||