From 56f5841d4b9c12296cdfcaeff174b2627d59afc8 Mon Sep 17 00:00:00 2001 From: Star Rauchenberger Date: Sat, 7 Dec 2024 11:49:49 -0500 Subject: Migrate to full rails app --- app/models/ability.rb | 5 + app/models/application_record.rb | 3 + app/models/concerns/.keep | 0 app/models/gift_ribbon.rb | 3 + app/models/item.rb | 41 +++ app/models/location.rb | 5 + app/models/move.rb | 31 ++ app/models/pokedex_entry.rb | 4 + app/models/pokemon.rb | 165 +++++++++ app/models/pokeviewer/ability.rb | 7 - app/models/pokeviewer/application_record.rb | 5 - app/models/pokeviewer/gift_ribbon.rb | 5 - app/models/pokeviewer/item.rb | 43 --- app/models/pokeviewer/location.rb | 7 - app/models/pokeviewer/move.rb | 33 -- app/models/pokeviewer/pokedex_entry.rb | 6 - app/models/pokeviewer/pokemon.rb | 167 ---------- app/models/pokeviewer/revision.rb | 496 ---------------------------- app/models/pokeviewer/species.rb | 26 -- app/models/pokeviewer/trainer.rb | 95 ------ app/models/revision.rb | 494 +++++++++++++++++++++++++++ app/models/species.rb | 24 ++ app/models/trainer.rb | 93 ++++++ 23 files changed, 868 insertions(+), 890 deletions(-) create mode 100644 app/models/ability.rb create mode 100644 app/models/application_record.rb create mode 100644 app/models/concerns/.keep create mode 100644 app/models/gift_ribbon.rb create mode 100644 app/models/item.rb create mode 100644 app/models/location.rb create mode 100644 app/models/move.rb create mode 100644 app/models/pokedex_entry.rb create mode 100644 app/models/pokemon.rb delete mode 100644 app/models/pokeviewer/ability.rb delete mode 100644 app/models/pokeviewer/application_record.rb delete mode 100644 app/models/pokeviewer/gift_ribbon.rb delete mode 100644 app/models/pokeviewer/item.rb delete mode 100644 app/models/pokeviewer/location.rb delete mode 100644 app/models/pokeviewer/move.rb delete mode 100644 app/models/pokeviewer/pokedex_entry.rb delete mode 100644 app/models/pokeviewer/pokemon.rb delete mode 100644 app/models/pokeviewer/revision.rb delete mode 100644 app/models/pokeviewer/species.rb delete mode 100644 app/models/pokeviewer/trainer.rb create mode 100644 app/models/revision.rb create mode 100644 app/models/species.rb create mode 100644 app/models/trainer.rb (limited to 'app/models') 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 @@ +class Ability < ApplicationRecord + validates :name, presence: true, uniqueness: true + + validates :description, presence: true +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 @@ +class ApplicationRecord < ActiveRecord::Base + primary_abstract_class +end diff --git a/app/models/concerns/.keep b/app/models/concerns/.keep new file mode 100644 index 0000000..e69de29 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 @@ +class GiftRibbon < ApplicationRecord + validates :description, presence: true +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 @@ +class Item < ApplicationRecord + validates :name, presence: true + + belongs_to :move, optional: true + validates :move, presence: true, if: :tm? + + validates :rs_description, presence: true, unless: :tm? + validates :frlg_description, presence: true, unless: :tm? + + def description(game) + if game == :emerald + if not emerald_description.nil? + emerald_description + elsif not rs_description.nil? + rs_description + else + move.description game + end + elsif game == :firered or game == :leafgreen + if not frlg_description.nil? + frlg_description + else + move.description game + end + else + if not rs_description.nil? + rs_description + else + move.description game + end + end + end + + def icon_path + if tm? + "items/tms/#{move.move_type}.png" + else + "items/#{id}.png" + end + end +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 @@ +class Location < ApplicationRecord + has_many :pokemon, dependent: :nullify + + validates :name, presence: true +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 @@ +class Move < ApplicationRecord + extend Enumerize + + has_many :revision_moves + has_many :revisions, through: :revision_moves + + validates :name, presence: true, uniqueness: true + + validates :pp, presence: true, + numericality: { greater_than_or_equal_to: 1, only_integer: true } + + TYPES = [:normal, :fighting, :flying, :poison, :ground, + :rock, :bug, :ghost, :steel, :mystery, :fire, :water, :grass, :electric, + :psychic, :ice, :dragon, :dark] + + validates :move_type, presence: true + enumerize :move_type, in: TYPES, predicates: true + + validates :rs_description, presence: true + validates :frlg_description, presence: true + + def description(game) + if game == :emerald and not emerald_description.nil? + emerald_description + elsif game == :firered or game == :leafgreen + frlg_description + else + rs_description + end + end +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 @@ +class PokedexEntry < ApplicationRecord + belongs_to :trainer + belongs_to :species +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 @@ +class Pokemon < ApplicationRecord + extend Enumerize + extend ActiveModel::Naming + + has_many :revisions, -> { order "sequential_id ASC" }, dependent: :destroy + + belongs_to :current, class_name: "Revision", optional: true + validate :current_is_cached + + belongs_to :trainer, optional: true + + validates :box, numericality: { + greater_than_or_equal_to: 1, + less_than_or_equal_to: 14, + only_integer: true }, + allow_nil: true + + validates :slot, presence: true, + uniqueness: { scope: [:trainer_id, :box] }, + numericality: { + greater_than_or_equal_to: 0, + only_integer: true }, + unless: Proc.new { |a| a.trainer_id.nil? } + + validates :slot, + numericality: { less_than: 30 }, + unless: Proc.new { |a| a.trainer_id.nil? or a.box.nil? } + + validates :slot, + numericality: { less_than: 6 }, + unless: Proc.new { |a| a.trainer_id.nil? or not a.box.nil? } + + scope :party, -> { where(box: nil) } + scope :box, ->(n) { where(box: n) } + scope :unaccounted, -> { where(trainer_id: nil) } + + validate :uuid_is_constant, on: :update + before_create :set_uuid + + validates :ot_name, presence: true + + validates :ot_number, presence: true, + numericality: { greater_than_or_equal_to: 0, only_integer: true } + + validates :ot_gender, presence: true + enumerize :ot_gender, in: [:female, :male] + + validates :met_level, presence: true, + numericality: { greater_than_or_equal_to: 1, only_integer: true }, + if: Proc.new { |a| a.met_type == :normal } + + validates :met_type, presence: true + enumerize :met_type, + in: [:normal, :hatched, :npc_trade, :fateful_encounter, :orre] + + belongs_to :location, optional: true + validates :location, presence: true, + if: Proc.new { |c| c.met_type == :normal or c.met_type == :hatched} + + validates :gender, presence: true + enumerize :gender, in: [:genderless, :female, :male] + + validates :nature, presence: true + enumerize :nature, in: [:hardy, :lonely, :brave, :adamant, :naughty, :bold, + :docile, :relaxed, :impish, :lax, :timid, :hasty, :serious, :jolly, + :naive, :modest, :mild, :quiet, :bashful, :rash, :calm, :gentle, :sassy, + :careful, :quirky] + + enumerize :unown_letter, in: [:a, :b, :c, :d, :e, :f, :g, :h, :i, :j, :k, + :l, :m, :n, :o, :p, :q, :r, :s, :t, :u, :v, :w, :x, :y, :z, + :question, :exclamation] + + validates :pokeball, presence: true + enumerize :pokeball, in: [:master, :ultra, :great, :poke, :safari, :net, + :dive, :nest, :repeat, :timer, :luxury, :premier] + + def to_param + uuid + end + + def outsider? + (trainer.nil?) or (ot_name != trainer.name) or (ot_number != trainer.number) + end + + def display_ot_number + ot_number.to_s.rjust(5, '0') + end + + def nature_benefits?(stat) + if stat == :attack + [:lonely, :brave, :adamant, :naughty].include? nature.intern + elsif stat == :defense + [:bold, :relaxed, :impish, :lax].include? nature.intern + elsif stat == :speed + [:timid, :hasty, :jolly, :naive].include? nature.intern + elsif stat == :special_attack + [:modest, :mild, :quiet, :rash].include? nature.intern + elsif stat == :special_defense + [:calm, :gentle, :sassy, :careful].include? nature.intern + else + false + end + end + + def nature_hinders?(stat) + if stat == :attack + [:bold, :timid, :modest, :calm].include? nature.intern + elsif stat == :defense + [:lonely, :hasty, :mild, :gentle].include? nature.intern + elsif stat == :speed + [:brave, :relaxed, :quiet, :sassy].include? nature.intern + elsif stat == :special_attack + [:adamant, :impish, :jolly, :careful].include? nature.intern + elsif stat == :special_defense + [:naughty, :lax, :naive, :rash].include? nature.intern + else + false + end + end + + def pokeball_icon_path + "items/#{Pokemon.pokeball.values.find_index(pokeball) + 1}.png" + end + + def gift_ribbon_description(ribbon) + if trainer.nil? + "" + else + trainer.gift_ribbon_description(ribbon) + end + end + + def gender_symbol + case gender.intern + when :female + "♀" + when :male + "♂" + when :genderless + "" + end + end + + private + + def set_uuid + self.uuid = SecureRandom.uuid + end + + def uuid_is_constant + errors.add(:uuid, "can't be changed") if self.uuid_changed? + end + + def current_is_cached + if self.revisions.empty? + unless self.current_id.nil? + errors.add(:current, "must be null when there are no revisions") + end + else + unless self.current_id = self.revisions.last.id + errors.add(:current, "is not up-to-date") + end + end + end +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 @@ -module Pokeviewer - class Ability < ApplicationRecord - validates :name, presence: true, uniqueness: true - - validates :description, presence: true - end -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 @@ -module Pokeviewer - class ApplicationRecord < ActiveRecord::Base - self.abstract_class = true - end -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 @@ -module Pokeviewer - class GiftRibbon < ApplicationRecord - validates :description, presence: true - end -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 @@ -module Pokeviewer - class Item < ApplicationRecord - validates :name, presence: true - - belongs_to :move, optional: true - validates :move, presence: true, if: :tm? - - validates :rs_description, presence: true, unless: :tm? - validates :frlg_description, presence: true, unless: :tm? - - def description(game) - if game == :emerald - if not emerald_description.nil? - emerald_description - elsif not rs_description.nil? - rs_description - else - move.description game - end - elsif game == :firered or game == :leafgreen - if not frlg_description.nil? - frlg_description - else - move.description game - end - else - if not rs_description.nil? - rs_description - else - move.description game - end - end - end - - def icon_path - if tm? - "pokeviewer/items/tms/#{move.move_type}.png" - else - "pokeviewer/items/#{id}.png" - end - end - end -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 @@ -module Pokeviewer - class Location < ApplicationRecord - has_many :pokemon, dependent: :nullify - - validates :name, presence: true - end -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 @@ -module Pokeviewer - class Move < ApplicationRecord - extend Enumerize - - has_many :revision_moves - has_many :revisions, through: :revision_moves - - validates :name, presence: true, uniqueness: true - - validates :pp, presence: true, - numericality: { greater_than_or_equal_to: 1, only_integer: true } - - TYPES = [:normal, :fighting, :flying, :poison, :ground, - :rock, :bug, :ghost, :steel, :mystery, :fire, :water, :grass, :electric, - :psychic, :ice, :dragon, :dark] - - validates :move_type, presence: true - enumerize :move_type, in: TYPES, predicates: true - - validates :rs_description, presence: true - validates :frlg_description, presence: true - - def description(game) - if game == :emerald and not emerald_description.nil? - emerald_description - elsif game == :firered or game == :leafgreen - frlg_description - else - rs_description - end - end - end -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 @@ -module Pokeviewer - class PokedexEntry < ApplicationRecord - belongs_to :trainer - belongs_to :species - end -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 @@ -module Pokeviewer - class Pokemon < ApplicationRecord - extend Enumerize - extend ActiveModel::Naming - - has_many :revisions, -> { order "sequential_id ASC" }, dependent: :destroy - - belongs_to :current, class_name: "Revision", optional: true - validate :current_is_cached - - belongs_to :trainer, optional: true - - validates :box, numericality: { - greater_than_or_equal_to: 1, - less_than_or_equal_to: 14, - only_integer: true }, - allow_nil: true - - validates :slot, presence: true, - uniqueness: { scope: [:trainer_id, :box] }, - numericality: { - greater_than_or_equal_to: 0, - only_integer: true }, - unless: Proc.new { |a| a.trainer_id.nil? } - - validates :slot, - numericality: { less_than: 30 }, - unless: Proc.new { |a| a.trainer_id.nil? or a.box.nil? } - - validates :slot, - numericality: { less_than: 6 }, - unless: Proc.new { |a| a.trainer_id.nil? or not a.box.nil? } - - scope :party, -> { where(box: nil) } - scope :box, ->(n) { where(box: n) } - scope :unaccounted, -> { where(trainer_id: nil) } - - validate :uuid_is_constant, on: :update - before_create :set_uuid - - validates :ot_name, presence: true - - validates :ot_number, presence: true, - numericality: { greater_than_or_equal_to: 0, only_integer: true } - - validates :ot_gender, presence: true - enumerize :ot_gender, in: [:female, :male] - - validates :met_level, presence: true, - numericality: { greater_than_or_equal_to: 1, only_integer: true }, - if: Proc.new { |a| a.met_type == :normal } - - validates :met_type, presence: true - enumerize :met_type, - in: [:normal, :hatched, :npc_trade, :fateful_encounter, :orre] - - belongs_to :location, optional: true - validates :location, presence: true, - if: Proc.new { |c| c.met_type == :normal or c.met_type == :hatched} - - validates :gender, presence: true - enumerize :gender, in: [:genderless, :female, :male] - - validates :nature, presence: true - enumerize :nature, in: [:hardy, :lonely, :brave, :adamant, :naughty, :bold, - :docile, :relaxed, :impish, :lax, :timid, :hasty, :serious, :jolly, - :naive, :modest, :mild, :quiet, :bashful, :rash, :calm, :gentle, :sassy, - :careful, :quirky] - - enumerize :unown_letter, in: [:a, :b, :c, :d, :e, :f, :g, :h, :i, :j, :k, - :l, :m, :n, :o, :p, :q, :r, :s, :t, :u, :v, :w, :x, :y, :z, - :question, :exclamation] - - validates :pokeball, presence: true - enumerize :pokeball, in: [:master, :ultra, :great, :poke, :safari, :net, - :dive, :nest, :repeat, :timer, :luxury, :premier] - - def to_param - uuid - end - - def outsider? - (trainer.nil?) or (ot_name != trainer.name) or (ot_number != trainer.number) - end - - def display_ot_number - ot_number.to_s.rjust(5, '0') - end - - def nature_benefits?(stat) - if stat == :attack - [:lonely, :brave, :adamant, :naughty].include? nature.intern - elsif stat == :defense - [:bold, :relaxed, :impish, :lax].include? nature.intern - elsif stat == :speed - [:timid, :hasty, :jolly, :naive].include? nature.intern - elsif stat == :special_attack - [:modest, :mild, :quiet, :rash].include? nature.intern - elsif stat == :special_defense - [:calm, :gentle, :sassy, :careful].include? nature.intern - else - false - end - end - - def nature_hinders?(stat) - if stat == :attack - [:bold, :timid, :modest, :calm].include? nature.intern - elsif stat == :defense - [:lonely, :hasty, :mild, :gentle].include? nature.intern - elsif stat == :speed - [:brave, :relaxed, :quiet, :sassy].include? nature.intern - elsif stat == :special_attack - [:adamant, :impish, :jolly, :careful].include? nature.intern - elsif stat == :special_defense - [:naughty, :lax, :naive, :rash].include? nature.intern - else - false - end - end - - def pokeball_icon_path - "pokeviewer/items/#{Pokemon.pokeball.values.find_index(pokeball) + 1}.png" - end - - def gift_ribbon_description(ribbon) - if trainer.nil? - "" - else - trainer.gift_ribbon_description(ribbon) - end - end - - def gender_symbol - case gender.intern - when :female - "♀" - when :male - "♂" - when :genderless - "" - end - end - - private - - def set_uuid - self.uuid = SecureRandom.uuid - end - - def uuid_is_constant - errors.add(:uuid, "can't be changed") if self.uuid_changed? - end - - def current_is_cached - if self.revisions.empty? - unless self.current_id.nil? - errors.add(:current, "must be null when there are no revisions") - end - else - unless self.current_id = self.revisions.last.id - errors.add(:current, "is not up-to-date") - end - end - end - end -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 @@ -require 'active_record/diff' - -module Pokeviewer - class Revision < ApplicationRecord - include ActiveRecord::Diff - - diff :species_id, :nickname, :level, :hp, :attack, :defense, - :special_attack, :special_defense, :speed, :coolness, :beauty, :cuteness, - :smartness, :toughness, :sheen, :item_id, :move_1_id, :move_2_id, - :move_3_id, :move_4_id, :move_1_pp_bonuses, :move_2_pp_bonuses, - :move_3_pp_bonuses, :move_4_pp_bonuses, :cool_ribbons, :beauty_ribbons, - :cute_ribbons, :smart_ribbons, :tough_ribbons, :champion_ribbon, - :winning_ribbon, :victory_ribbon, :artist_ribbon, :effort_ribbon, - :marine_ribbon, :land_ribbon, :sky_ribbon, :country_ribbon, - :national_ribbon, :earth_ribbon, :world_ribbon - - belongs_to :pokemon - acts_as_sequenced scope: :pokemon_id - - after_create :cache_pokemon_current - - belongs_to :species - - validates :nickname, presence: true - - validates :experience, presence: true, - numericality: { greater_than_or_equal_to: 1, only_integer: true } - - validates :level, presence: true, - numericality: { greater_than_or_equal_to: 1, only_integer: true } - - validates :hp, presence: true, - numericality: { greater_than_or_equal_to: 1, only_integer: true } - - validates :attack, presence: true, - numericality: { greater_than_or_equal_to: 1, only_integer: true } - - validates :defense, presence: true, - numericality: { greater_than_or_equal_to: 1, only_integer: true } - - validates :special_attack, presence: true, - numericality: { greater_than_or_equal_to: 1, only_integer: true } - - validates :special_defense, presence: true, - numericality: { greater_than_or_equal_to: 1, only_integer: true } - - validates :speed, presence: true, - numericality: { greater_than_or_equal_to: 1, only_integer: true } - - validates :coolness, presence: true, - numericality: { - greater_than_or_equal_to: 0, - less_than_or_equal_to: 10, - only_integer: true } - - validates :beauty, presence: true, - numericality: { - greater_than_or_equal_to: 0, - less_than_or_equal_to: 10, - only_integer: true } - - validates :cuteness, presence: true, - numericality: { - greater_than_or_equal_to: 0, - less_than_or_equal_to: 10, - only_integer: true } - - validates :smartness, presence: true, - numericality: { - greater_than_or_equal_to: 0, - less_than_or_equal_to: 10, - only_integer: true } - - validates :toughness, presence: true, - numericality: { - greater_than_or_equal_to: 0, - less_than_or_equal_to: 10, - only_integer: true } - - validates :sheen, presence: true, - numericality: { - greater_than_or_equal_to: 0, - less_than_or_equal_to: 10, - only_integer: true } - - belongs_to :item, optional: true - - belongs_to :move_1, class_name: "Move" - belongs_to :move_2, class_name: "Move", optional: true - belongs_to :move_3, class_name: "Move", optional: true - belongs_to :move_4, class_name: "Move", optional: true - - validates :move_1_pp_bonuses, presence: true, - numericality: { - greater_than_or_equal_to: 0, - less_than_or_equal_to: 3, - only_integer: true} - - validates :move_2_pp_bonuses, presence: true, - numericality: { - greater_than_or_equal_to: 0, - less_than_or_equal_to: 3, - only_integer: true} - - validates :move_3_pp_bonuses, presence: true, - numericality: { - greater_than_or_equal_to: 0, - less_than_or_equal_to: 3, - only_integer: true} - - validates :move_4_pp_bonuses, presence: true, - numericality: { - greater_than_or_equal_to: 0, - less_than_or_equal_to: 3, - only_integer: true} - - validates :cool_ribbons, presence: true, - numericality: { - greater_than_or_equal_to: 0, - less_than_or_equal_to: 4, - only_integer: true} - - validates :beauty_ribbons, presence: true, - numericality: { - greater_than_or_equal_to: 0, - less_than_or_equal_to: 4, - only_integer: true} - - validates :cute_ribbons, presence: true, - numericality: { - greater_than_or_equal_to: 0, - less_than_or_equal_to: 4, - only_integer: true} - - validates :smart_ribbons, presence: true, - numericality: { - greater_than_or_equal_to: 0, - less_than_or_equal_to: 4, - only_integer: true} - - validates :tough_ribbons, presence: true, - numericality: { - greater_than_or_equal_to: 0, - less_than_or_equal_to: 4, - only_integer: true} - - def icon_path - form = "" - if species_id == 201 - # Handle Unown form - form = "-#{pokemon.unown_letter}" - elsif species_id == 386 - # Handle Deoxys forms - if pokemon.trainer.firered? - form = "-attack" - elsif pokemon.trainer.leafgreen? - form = "-defense" - elsif pokemon.trainer.emerald? - form = "-speed" - end - end - - "pokeviewer/icons/#{species_id}#{form}.png" - end - - def sprite_path - shininess = "normal" - if pokemon.shiny - shininess = "shiny" - end - - game = "ruby-sapphire" - unless pokemon.trainer.nil? - if (pokemon.trainer.firered? or pokemon.trainer.leafgreen?) and (species_id <= 151 or species_id == 216 or species_id == 386) - game = "firered-leafgreen" - elsif pokemon.trainer.emerald? - game = "emerald" - end - end - - form = "" - if species_id == 201 - # Handle Unown forms - form = "-#{pokemon.unown_letter}" - elsif species_id == 386 - # Handle Deoxys forms - if pokemon.trainer.firered? - form = "-attack" - elsif pokemon.trainer.leafgreen? - form = "-defense" - elsif pokemon.trainer.emerald? - form = "-speed" - end - end - - if game == "emerald" - "pokeviewer/sprites/emerald/#{shininess}/#{species_id}#{form}.gif" - else - "pokeviewer/sprites/#{game}/#{shininess}/#{species_id}#{form}.png" - end - end - - def ability - if pokemon.second_ability - species.ability_2 - else - species.ability_1 - end - end - - def move_1_pp - move_1.pp * (5 + move_1_pp_bonuses) / 5 - end - - def move_2_pp - move_2.pp * (5 + move_2_pp_bonuses) / 5 - end - - def move_3_pp - move_3.pp * (5 + move_3_pp_bonuses) / 5 - end - - def move_4_pp - move_4.pp * (5 + move_4_pp_bonuses) / 5 - end - - def ribbons - result = [] - - if cool_ribbons >= 1 - result << { - filename: "cool-ribbon.png", - name: "Cool Ribbon", - description: "Cool Contest Normal Rank Winner!" - } - end - - if cool_ribbons >= 2 - result << { - filename: "cool-ribbon-super.png", - name: "Cool Ribbon Super", - description: "Cool Contest Super Rank Winner!" - } - end - - if cool_ribbons >= 3 - result << { - filename: "cool-ribbon-hyper.png", - name: "Cool Ribbon Hyper", - description: "Cool Contest Hyper Rank Winner!" - } - end - - if cool_ribbons == 4 - result << { - filename: "cool-ribbon-master.png", - name: "Cool Ribbon Master", - description: "Cool Contest Master Rank Winner!" - } - end - - if beauty_ribbons >= 1 - result << { - filename: "beauty-ribbon.png", - name: "Beauty Ribbon", - description: "Beauty Contest Normal Rank Winner!" - } - end - - if beauty_ribbons >= 2 - result << { - filename: "beauty-ribbon-super.png", - name: "Beauty Ribbon Super", - description: "Beauty Contest Super Rank Winner!" - } - end - - if beauty_ribbons >= 3 - result << { - filename: "beauty-ribbon-hyper.png", - name: "Beauty Ribbon Hyper", - description: "Beauty Contest Hyper Rank Winner!" - } - end - - if beauty_ribbons == 4 - result << { - filename: "beauty-ribbon-master.png", - name: "Beauty Ribbon Master", - description: "Beauty Contest Master Rank Winner!" - } - end - - if cute_ribbons >= 1 - result << { - filename: "cute-ribbon.png", - name: "Cute Ribbon", - description: "Cute Contest Normal Rank Winner!" - } - end - - if cute_ribbons >= 2 - result << { - filename: "cute-ribbon-super.png", - name: "Cute Ribbon Super", - description: "Cute Contest Super Rank Winner!" - } - end - - if cute_ribbons >= 3 - result << { - filename: "cute-ribbon-hyper.png", - name: "Cute Ribbon Hyper", - description: "Cute Contest Hyper Rank Winner!" - } - end - - if cute_ribbons == 4 - result << { - filename: "cute-ribbon-master.png", - name: "Cute Ribbon Master", - description: "Cute Contest Master Rank Winner!" - } - end - - if smart_ribbons >= 1 - result << { - filename: "smart-ribbon.png", - name: "Smart Ribbon", - description: "Smart Contest Normal Rank Winner!" - } - end - - if smart_ribbons >= 2 - result << { - filename: "smart-ribbon-super.png", - name: "Smart Ribbon Super", - description: "Smart Contest Super Rank Winner!" - } - end - - if smart_ribbons >= 3 - result << { - filename: "smart-ribbon-hyper.png", - name: "Smart Ribbon Hyper", - description: "Smart Contest Hyper Rank Winner!" - } - end - - if smart_ribbons == 4 - result << { - filename: "smart-ribbon-master.png", - name: "Smart Ribbon Master", - description: "Smart Contest Master Rank Winner!" - } - end - - if tough_ribbons >= 1 - result << { - filename: "tough-ribbon.png", - name: "Tough Ribbon", - description: "Tough Contest Normal Rank Winner!" - } - end - - if tough_ribbons >= 2 - result << { - filename: "tough-ribbon-super.png", - name: "Tough Ribbon Super", - description: "Tough Contest Super Rank Winner!" - } - end - - if tough_ribbons >= 3 - result << { - filename: "tough-ribbon-hyper.png", - name: "Tough Ribbon Hyper", - description: "Tough Contest Hyper Rank Winner!" - } - end - - if tough_ribbons == 4 - result << { - filename: "tough-ribbon-master.png", - name: "Tough Ribbon Master", - description: "Tough Contest Master Rank Winner!" - } - end - - if champion_ribbon - result << { - filename: "champion-ribbon.png", - name: "Champion Ribbon", - description: "Champion-beating, Hall of Fame Member Ribbon" - } - end - - if winning_ribbon - result << { - filename: "winning-ribbon.png", - name: "Winning Ribbon", - description: "Ribbon for clearing LV50 at the Battle Tower." - } - end - - if victory_ribbon - result << { - filename: "victory-ribbon.png", - name: "Victory Ribbon", - description: "Won for clearing LV100 at the Battle Tower." - } - end - - if artist_ribbon - result << { - filename: "artist-ribbon.png", - name: "Artist Ribbon", - description: "Ribbon for being chosen as a super sketch model." - } - end - - if effort_ribbon - result << { - filename: "effort-ribbon.png", - name: "Effort Ribbon", - description: "Ribbon awarded for being a hard worker." - } - end - - if marine_ribbon - result << { - filename: "marine-ribbon.png", - name: "Marine Ribbon", - description: pokemon.gift_ribbon_description(:marine_ribbon) - } - end - - if land_ribbon - result << { - filename: "land-ribbon.png", - name: "Land Ribbon", - description: pokemon.gift_ribbon_description(:land_ribbon) - } - end - - if sky_ribbon - result << { - filename: "sky-ribbon.png", - name: "Sky Ribbon", - description: pokemon.gift_ribbon_description(:sky_ribbon) - } - end - - if country_ribbon - result << { - filename: "country-ribbon.png", - name: "Country Ribbon", - description: pokemon.gift_ribbon_description(:country_ribbon) - } - end - - if national_ribbon - result << { - filename: "national-ribbon.png", - name: "National Ribbon", - description: pokemon.gift_ribbon_description(:national_ribbon) - } - end - - if earth_ribbon - result << { - filename: "earth-ribbon.png", - name: "Earth Ribbon", - description: pokemon.gift_ribbon_description(:earth_ribbon) - } - end - - if world_ribbon - result << { - filename: "world-ribbon.png", - name: "World Ribbon", - description: pokemon.gift_ribbon_description(:world_ribbon) - } - end - - result - end - - private - - def cache_pokemon_current - self.pokemon.current_id = self.id - self.pokemon.save! - end - end -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 @@ -module Pokeviewer - class Species < ApplicationRecord - extend Enumerize - - has_many :revisions, dependent: :restrict_with_exception - - has_many :pokedex_entries, dependent: :destroy - - validates :name, presence: true, uniqueness: true - - validates :type_1, presence: true - - enumerize :type_1, in: Move::TYPES - enumerize :type_2, in: Move::TYPES - - belongs_to :ability_1, class_name: "Ability" - belongs_to :ability_2, class_name: "Ability", optional: true - - def current_revisions - revisions. - where("pokeviewer_pokemon.current_id = pokeviewer_revisions.id"). - includes(:pokemon). - references(:pokemon) - end - end -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 @@ -module Pokeviewer - class Trainer < ApplicationRecord - extend Enumerize - - has_many :pokemon, dependent: :nullify - - has_many :pokedex_entries, dependent: :destroy - - validates :number, presence: true, - numericality: { greater_than_or_equal_to: 0, only_integer: true } - - validates :name, presence: true, uniqueness: { - scope: :number, - message: "and number should be pairwise unique" } - - validates :game, presence: true - enumerize :game, in: [:ruby, :sapphire, :firered, :leafgreen, :emerald], - predicates: true - - belongs_to :marine_ribbon, class_name: "GiftRibbon", optional: true - belongs_to :land_ribbon, class_name: "GiftRibbon", optional: true - belongs_to :sky_ribbon, class_name: "GiftRibbon", optional: true - belongs_to :country_ribbon, class_name: "GiftRibbon", optional: true - belongs_to :national_ribbon, class_name: "GiftRibbon", optional: true - belongs_to :earth_ribbon, class_name: "GiftRibbon", optional: true - belongs_to :world_ribbon, class_name: "GiftRibbon", optional: true - - validates :box_1_name, presence: true - validates :box_2_name, presence: true - validates :box_3_name, presence: true - validates :box_4_name, presence: true - validates :box_5_name, presence: true - validates :box_6_name, presence: true - validates :box_7_name, presence: true - validates :box_8_name, presence: true - validates :box_9_name, presence: true - validates :box_10_name, presence: true - validates :box_11_name, presence: true - validates :box_12_name, presence: true - validates :box_13_name, presence: true - validates :box_14_name, presence: true - - def party - pokemon.party.includes(current: [:species]) - end - - def box(n) - pokemon.box(n).includes(current: [:species]) - end - - def box_name(n) - if n > 0 and n <= 14 - send "box_#{n}_name".intern - else - nil - end - end - - def box_contents(n) - pokes = box(n).to_a - - result = [] - (0..29).each do |i| - if pokes.empty? or (pokes.first.slot == i) - result << pokes.shift - else - result << nil - end - end - - result - end - - def boxes - (1..14).map { |n| { - name: box_name(n), - pokemon: box_contents(n) - }} - end - - def display_number - number.to_s.rjust(5, '0') - end - - def gift_ribbon_description(ribbon) - gift_ribbon = send ribbon - - if gift_ribbon.nil? - "" - else - gift_ribbon.description - end - end - end -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 @@ +require 'active_record/diff' + +class Revision < ApplicationRecord + include ActiveRecord::Diff + + diff :species_id, :nickname, :level, :hp, :attack, :defense, + :special_attack, :special_defense, :speed, :coolness, :beauty, :cuteness, + :smartness, :toughness, :sheen, :item_id, :move_1_id, :move_2_id, + :move_3_id, :move_4_id, :move_1_pp_bonuses, :move_2_pp_bonuses, + :move_3_pp_bonuses, :move_4_pp_bonuses, :cool_ribbons, :beauty_ribbons, + :cute_ribbons, :smart_ribbons, :tough_ribbons, :champion_ribbon, + :winning_ribbon, :victory_ribbon, :artist_ribbon, :effort_ribbon, + :marine_ribbon, :land_ribbon, :sky_ribbon, :country_ribbon, + :national_ribbon, :earth_ribbon, :world_ribbon + + belongs_to :pokemon + acts_as_sequenced scope: :pokemon_id + + after_create :cache_pokemon_current + + belongs_to :species + + validates :nickname, presence: true + + validates :experience, presence: true, + numericality: { greater_than_or_equal_to: 1, only_integer: true } + + validates :level, presence: true, + numericality: { greater_than_or_equal_to: 1, only_integer: true } + + validates :hp, presence: true, + numericality: { greater_than_or_equal_to: 1, only_integer: true } + + validates :attack, presence: true, + numericality: { greater_than_or_equal_to: 1, only_integer: true } + + validates :defense, presence: true, + numericality: { greater_than_or_equal_to: 1, only_integer: true } + + validates :special_attack, presence: true, + numericality: { greater_than_or_equal_to: 1, only_integer: true } + + validates :special_defense, presence: true, + numericality: { greater_than_or_equal_to: 1, only_integer: true } + + validates :speed, presence: true, + numericality: { greater_than_or_equal_to: 1, only_integer: true } + + validates :coolness, presence: true, + numericality: { + greater_than_or_equal_to: 0, + less_than_or_equal_to: 10, + only_integer: true } + + validates :beauty, presence: true, + numericality: { + greater_than_or_equal_to: 0, + less_than_or_equal_to: 10, + only_integer: true } + + validates :cuteness, presence: true, + numericality: { + greater_than_or_equal_to: 0, + less_than_or_equal_to: 10, + only_integer: true } + + validates :smartness, presence: true, + numericality: { + greater_than_or_equal_to: 0, + less_than_or_equal_to: 10, + only_integer: true } + + validates :toughness, presence: true, + numericality: { + greater_than_or_equal_to: 0, + less_than_or_equal_to: 10, + only_integer: true } + + validates :sheen, presence: true, + numericality: { + greater_than_or_equal_to: 0, + less_than_or_equal_to: 10, + only_integer: true } + + belongs_to :item, optional: true + + belongs_to :move_1, class_name: "Move" + belongs_to :move_2, class_name: "Move", optional: true + belongs_to :move_3, class_name: "Move", optional: true + belongs_to :move_4, class_name: "Move", optional: true + + validates :move_1_pp_bonuses, presence: true, + numericality: { + greater_than_or_equal_to: 0, + less_than_or_equal_to: 3, + only_integer: true} + + validates :move_2_pp_bonuses, presence: true, + numericality: { + greater_than_or_equal_to: 0, + less_than_or_equal_to: 3, + only_integer: true} + + validates :move_3_pp_bonuses, presence: true, + numericality: { + greater_than_or_equal_to: 0, + less_than_or_equal_to: 3, + only_integer: true} + + validates :move_4_pp_bonuses, presence: true, + numericality: { + greater_than_or_equal_to: 0, + less_than_or_equal_to: 3, + only_integer: true} + + validates :cool_ribbons, presence: true, + numericality: { + greater_than_or_equal_to: 0, + less_than_or_equal_to: 4, + only_integer: true} + + validates :beauty_ribbons, presence: true, + numericality: { + greater_than_or_equal_to: 0, + less_than_or_equal_to: 4, + only_integer: true} + + validates :cute_ribbons, presence: true, + numericality: { + greater_than_or_equal_to: 0, + less_than_or_equal_to: 4, + only_integer: true} + + validates :smart_ribbons, presence: true, + numericality: { + greater_than_or_equal_to: 0, + less_than_or_equal_to: 4, + only_integer: true} + + validates :tough_ribbons, presence: true, + numericality: { + greater_than_or_equal_to: 0, + less_than_or_equal_to: 4, + only_integer: true} + + def icon_path + form = "" + if species_id == 201 + # Handle Unown form + form = "-#{pokemon.unown_letter}" + elsif species_id == 386 + # Handle Deoxys forms + if pokemon.trainer.firered? + form = "-attack" + elsif pokemon.trainer.leafgreen? + form = "-defense" + elsif pokemon.trainer.emerald? + form = "-speed" + end + end + + "icons/#{species_id}#{form}.png" + end + + def sprite_path + shininess = "normal" + if pokemon.shiny + shininess = "shiny" + end + + game = "ruby-sapphire" + unless pokemon.trainer.nil? + if (pokemon.trainer.firered? or pokemon.trainer.leafgreen?) and (species_id <= 151 or species_id == 216 or species_id == 386) + game = "firered-leafgreen" + elsif pokemon.trainer.emerald? + game = "emerald" + end + end + + form = "" + if species_id == 201 + # Handle Unown forms + form = "-#{pokemon.unown_letter}" + elsif species_id == 386 + # Handle Deoxys forms + if pokemon.trainer.firered? + form = "-attack" + elsif pokemon.trainer.leafgreen? + form = "-defense" + elsif pokemon.trainer.emerald? + form = "-speed" + end + end + + if game == "emerald" + "sprites/emerald/#{shininess}/#{species_id}#{form}.gif" + else + "sprites/#{game}/#{shininess}/#{species_id}#{form}.png" + end + end + + def ability + if pokemon.second_ability + species.ability_2 + else + species.ability_1 + end + end + + def move_1_pp + move_1.pp * (5 + move_1_pp_bonuses) / 5 + end + + def move_2_pp + move_2.pp * (5 + move_2_pp_bonuses) / 5 + end + + def move_3_pp + move_3.pp * (5 + move_3_pp_bonuses) / 5 + end + + def move_4_pp + move_4.pp * (5 + move_4_pp_bonuses) / 5 + end + + def ribbons + result = [] + + if cool_ribbons >= 1 + result << { + filename: "cool-ribbon.png", + name: "Cool Ribbon", + description: "Cool Contest Normal Rank Winner!" + } + end + + if cool_ribbons >= 2 + result << { + filename: "cool-ribbon-super.png", + name: "Cool Ribbon Super", + description: "Cool Contest Super Rank Winner!" + } + end + + if cool_ribbons >= 3 + result << { + filename: "cool-ribbon-hyper.png", + name: "Cool Ribbon Hyper", + description: "Cool Contest Hyper Rank Winner!" + } + end + + if cool_ribbons == 4 + result << { + filename: "cool-ribbon-master.png", + name: "Cool Ribbon Master", + description: "Cool Contest Master Rank Winner!" + } + end + + if beauty_ribbons >= 1 + result << { + filename: "beauty-ribbon.png", + name: "Beauty Ribbon", + description: "Beauty Contest Normal Rank Winner!" + } + end + + if beauty_ribbons >= 2 + result << { + filename: "beauty-ribbon-super.png", + name: "Beauty Ribbon Super", + description: "Beauty Contest Super Rank Winner!" + } + end + + if beauty_ribbons >= 3 + result << { + filename: "beauty-ribbon-hyper.png", + name: "Beauty Ribbon Hyper", + description: "Beauty Contest Hyper Rank Winner!" + } + end + + if beauty_ribbons == 4 + result << { + filename: "beauty-ribbon-master.png", + name: "Beauty Ribbon Master", + description: "Beauty Contest Master Rank Winner!" + } + end + + if cute_ribbons >= 1 + result << { + filename: "cute-ribbon.png", + name: "Cute Ribbon", + description: "Cute Contest Normal Rank Winner!" + } + end + + if cute_ribbons >= 2 + result << { + filename: "cute-ribbon-super.png", + name: "Cute Ribbon Super", + description: "Cute Contest Super Rank Winner!" + } + end + + if cute_ribbons >= 3 + result << { + filename: "cute-ribbon-hyper.png", + name: "Cute Ribbon Hyper", + description: "Cute Contest Hyper Rank Winner!" + } + end + + if cute_ribbons == 4 + result << { + filename: "cute-ribbon-master.png", + name: "Cute Ribbon Master", + description: "Cute Contest Master Rank Winner!" + } + end + + if smart_ribbons >= 1 + result << { + filename: "smart-ribbon.png", + name: "Smart Ribbon", + description: "Smart Contest Normal Rank Winner!" + } + end + + if smart_ribbons >= 2 + result << { + filename: "smart-ribbon-super.png", + name: "Smart Ribbon Super", + description: "Smart Contest Super Rank Winner!" + } + end + + if smart_ribbons >= 3 + result << { + filename: "smart-ribbon-hyper.png", + name: "Smart Ribbon Hyper", + description: "Smart Contest Hyper Rank Winner!" + } + end + + if smart_ribbons == 4 + result << { + filename: "smart-ribbon-master.png", + name: "Smart Ribbon Master", + description: "Smart Contest Master Rank Winner!" + } + end + + if tough_ribbons >= 1 + result << { + filename: "tough-ribbon.png", + name: "Tough Ribbon", + description: "Tough Contest Normal Rank Winner!" + } + end + + if tough_ribbons >= 2 + result << { + filename: "tough-ribbon-super.png", + name: "Tough Ribbon Super", + description: "Tough Contest Super Rank Winner!" + } + end + + if tough_ribbons >= 3 + result << { + filename: "tough-ribbon-hyper.png", + name: "Tough Ribbon Hyper", + description: "Tough Contest Hyper Rank Winner!" + } + end + + if tough_ribbons == 4 + result << { + filename: "tough-ribbon-master.png", + name: "Tough Ribbon Master", + description: "Tough Contest Master Rank Winner!" + } + end + + if champion_ribbon + result << { + filename: "champion-ribbon.png", + name: "Champion Ribbon", + description: "Champion-beating, Hall of Fame Member Ribbon" + } + end + + if winning_ribbon + result << { + filename: "winning-ribbon.png", + name: "Winning Ribbon", + description: "Ribbon for clearing LV50 at the Battle Tower." + } + end + + if victory_ribbon + result << { + filename: "victory-ribbon.png", + name: "Victory Ribbon", + description: "Won for clearing LV100 at the Battle Tower." + } + end + + if artist_ribbon + result << { + filename: "artist-ribbon.png", + name: "Artist Ribbon", + description: "Ribbon for being chosen as a super sketch model." + } + end + + if effort_ribbon + result << { + filename: "effort-ribbon.png", + name: "Effort Ribbon", + description: "Ribbon awarded for being a hard worker." + } + end + + if marine_ribbon + result << { + filename: "marine-ribbon.png", + name: "Marine Ribbon", + description: pokemon.gift_ribbon_description(:marine_ribbon) + } + end + + if land_ribbon + result << { + filename: "land-ribbon.png", + name: "Land Ribbon", + description: pokemon.gift_ribbon_description(:land_ribbon) + } + end + + if sky_ribbon + result << { + filename: "sky-ribbon.png", + name: "Sky Ribbon", + description: pokemon.gift_ribbon_description(:sky_ribbon) + } + end + + if country_ribbon + result << { + filename: "country-ribbon.png", + name: "Country Ribbon", + description: pokemon.gift_ribbon_description(:country_ribbon) + } + end + + if national_ribbon + result << { + filename: "national-ribbon.png", + name: "National Ribbon", + description: pokemon.gift_ribbon_description(:national_ribbon) + } + end + + if earth_ribbon + result << { + filename: "earth-ribbon.png", + name: "Earth Ribbon", + description: pokemon.gift_ribbon_description(:earth_ribbon) + } + end + + if world_ribbon + result << { + filename: "world-ribbon.png", + name: "World Ribbon", + description: pokemon.gift_ribbon_description(:world_ribbon) + } + end + + result + end + + private + + def cache_pokemon_current + self.pokemon.current_id = self.id + self.pokemon.save! + end +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 @@ +class Species < ApplicationRecord + extend Enumerize + + has_many :revisions, dependent: :restrict_with_exception + + has_many :pokedex_entries, dependent: :destroy + + validates :name, presence: true, uniqueness: true + + validates :type_1, presence: true + + enumerize :type_1, in: Move::TYPES + enumerize :type_2, in: Move::TYPES + + belongs_to :ability_1, class_name: "Ability" + belongs_to :ability_2, class_name: "Ability", optional: true + + def current_revisions + revisions. + where("pokemon.current_id = revisions.id"). + includes(:pokemon). + references(:pokemon) + end +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 @@ +class Trainer < ApplicationRecord + extend Enumerize + + has_many :pokemon, dependent: :nullify + + has_many :pokedex_entries, dependent: :destroy + + validates :number, presence: true, + numericality: { greater_than_or_equal_to: 0, only_integer: true } + + validates :name, presence: true, uniqueness: { + scope: :number, + message: "and number should be pairwise unique" } + + validates :game, presence: true + enumerize :game, in: [:ruby, :sapphire, :firered, :leafgreen, :emerald], + predicates: true + + belongs_to :marine_ribbon, class_name: "GiftRibbon", optional: true + belongs_to :land_ribbon, class_name: "GiftRibbon", optional: true + belongs_to :sky_ribbon, class_name: "GiftRibbon", optional: true + belongs_to :country_ribbon, class_name: "GiftRibbon", optional: true + belongs_to :national_ribbon, class_name: "GiftRibbon", optional: true + belongs_to :earth_ribbon, class_name: "GiftRibbon", optional: true + belongs_to :world_ribbon, class_name: "GiftRibbon", optional: true + + validates :box_1_name, presence: true + validates :box_2_name, presence: true + validates :box_3_name, presence: true + validates :box_4_name, presence: true + validates :box_5_name, presence: true + validates :box_6_name, presence: true + validates :box_7_name, presence: true + validates :box_8_name, presence: true + validates :box_9_name, presence: true + validates :box_10_name, presence: true + validates :box_11_name, presence: true + validates :box_12_name, presence: true + validates :box_13_name, presence: true + validates :box_14_name, presence: true + + def party + pokemon.party.includes(current: [:species]) + end + + def box(n) + pokemon.box(n).includes(current: [:species]) + end + + def box_name(n) + if n > 0 and n <= 14 + send "box_#{n}_name".intern + else + nil + end + end + + def box_contents(n) + pokes = box(n).to_a + + result = [] + (0..29).each do |i| + if pokes.empty? or (pokes.first.slot == i) + result << pokes.shift + else + result << nil + end + end + + result + end + + def boxes + (1..14).map { |n| { + name: box_name(n), + pokemon: box_contents(n) + }} + end + + def display_number + number.to_s.rjust(5, '0') + end + + def gift_ribbon_description(ribbon) + gift_ribbon = send ribbon + + if gift_ribbon.nil? + "" + else + gift_ribbon.description + end + end +end -- cgit 1.4.1