diff options
Diffstat (limited to 'app/models/pokemon.rb')
-rw-r--r-- | app/models/pokemon.rb | 165 |
1 files changed, 165 insertions, 0 deletions
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 | ||