diff options
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 | ||
