2024-05-29 18:36:30 -07:00
|
|
|
require "addressable/template"
|
|
|
|
|
2024-01-24 03:25:23 -08:00
|
|
|
class AltStyle < ApplicationRecord
|
|
|
|
belongs_to :species
|
|
|
|
belongs_to :color
|
|
|
|
|
|
|
|
has_many :parent_swf_asset_relationships, as: :parent
|
|
|
|
has_many :swf_assets, through: :parent_swf_asset_relationships
|
2024-01-24 03:54:43 -08:00
|
|
|
has_many :contributions, as: :contributed, inverse_of: :contributed
|
|
|
|
|
2024-05-29 18:42:41 -07:00
|
|
|
validates :body_id, presence: true
|
|
|
|
|
2024-05-29 18:46:17 -07:00
|
|
|
before_create :infer_series_name
|
|
|
|
|
2024-02-27 15:33:08 -08:00
|
|
|
scope :matching_name, ->(series_name, color_name, species_name) {
|
|
|
|
color = Color.find_by_name!(color_name)
|
|
|
|
species = Species.find_by_name!(species_name)
|
|
|
|
where(series_name:, color_id: color.id, species_id: species.id)
|
|
|
|
}
|
|
|
|
|
2024-01-24 03:54:43 -08:00
|
|
|
def name
|
|
|
|
I18n.translate('pet_types.human_name', color_human_name: color.human_name,
|
|
|
|
species_human_name: species.human_name)
|
|
|
|
end
|
2024-01-24 03:25:23 -08:00
|
|
|
|
2024-02-27 15:48:28 -08:00
|
|
|
# If the series_name hasn't yet been set manually by support staff, show the
|
|
|
|
# string "<New?>" instead. But it won't be searchable by that string—that is,
|
|
|
|
# `fits:<New?>-faerie-draik` intentionally will not work, and the canonical
|
|
|
|
# filter name will be `fits:alt-style-IDNUMBER`, instead.
|
|
|
|
def series_name
|
|
|
|
self[:series_name] || "<New?>"
|
|
|
|
end
|
|
|
|
|
|
|
|
# You can use this to check whether `series_name` is returning the actual
|
|
|
|
# value or its placeholder value.
|
|
|
|
def has_real_series_name?
|
|
|
|
self[:series_name].present?
|
|
|
|
end
|
|
|
|
|
2024-01-29 03:20:48 -08:00
|
|
|
def adjective_name
|
2024-01-30 05:54:20 -08:00
|
|
|
"#{series_name} #{color.human_name}"
|
2024-01-29 03:20:48 -08:00
|
|
|
end
|
|
|
|
|
2024-05-29 18:36:30 -07:00
|
|
|
THUMBNAIL_URL_TEMPLATE = Addressable::Template.new(
|
|
|
|
"https://images.neopets.com/items/{series}_{color}_{species}.gif"
|
|
|
|
)
|
|
|
|
DEFAULT_THUMBNAIL_URL = "https://images.neopets.com/items/mall_bg_circle.gif"
|
2024-01-24 06:53:37 -08:00
|
|
|
def thumbnail_url
|
2024-05-29 18:36:30 -07:00
|
|
|
return DEFAULT_THUMBNAIL_URL unless has_real_series_name?
|
|
|
|
|
|
|
|
# HACK: We're assuming this is the format long-term! But if it changes, we
|
|
|
|
# may need to add it as a database field instead.
|
|
|
|
THUMBNAIL_URL_TEMPLATE.expand(
|
|
|
|
series: series_name.gsub(/\s+/, '').downcase,
|
|
|
|
color: color.name.gsub(/\s+/, '').downcase,
|
|
|
|
species: species.name.gsub(/\s+/, '').downcase,
|
|
|
|
).to_s
|
2024-01-24 06:53:37 -08:00
|
|
|
end
|
|
|
|
|
|
|
|
def preview_image_url
|
|
|
|
swf_asset = swf_assets.first
|
|
|
|
return nil if swf_asset.nil?
|
|
|
|
|
2024-02-24 16:12:02 -08:00
|
|
|
swf_asset.image_url
|
2024-01-24 06:53:37 -08:00
|
|
|
end
|
|
|
|
|
2024-02-27 16:11:06 -08:00
|
|
|
# Given a list of item IDs, return how they look on this alt style.
|
|
|
|
def appearances_for(item_ids, ...)
|
|
|
|
Item.appearances_for(item_ids, self, ...)
|
|
|
|
end
|
|
|
|
|
2024-01-24 03:25:23 -08:00
|
|
|
def biology=(biology)
|
|
|
|
# TODO: This is very similar to what `PetState` does, but like… much much
|
|
|
|
# more compact? Idk if I'm missing something, or if I was just that much
|
|
|
|
# more clueless back when I wrote it, lol 😅
|
2024-01-24 04:01:34 -08:00
|
|
|
self.swf_assets = biology.values.map do |asset_data|
|
|
|
|
SwfAsset.from_biology_data(self.body_id, asset_data)
|
2024-01-24 03:25:23 -08:00
|
|
|
end
|
|
|
|
end
|
2024-01-24 06:12:03 -08:00
|
|
|
|
2024-05-29 18:46:17 -07:00
|
|
|
# Until the end of 2024, assume new alt styles are from the "Nostalgic"
|
|
|
|
# series. That way, we can stop having to manually label them all as they
|
|
|
|
# come out and get modeled (TNT is prolific rn!), but we aren't gonna get too
|
|
|
|
# greedy and forget about this and use Nostalgic for some far-future thing,
|
|
|
|
# in ways that will certainly be fixable but would also be confusing and
|
|
|
|
# embarrassing.
|
|
|
|
NOSTALGIC_FINAL_DAY = Date.new(2024, 12, 31)
|
|
|
|
def infer_series_name
|
|
|
|
if !has_real_series_name? && Date.today <= NOSTALGIC_FINAL_DAY
|
|
|
|
self.series_name = "Nostalgic"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-01-24 06:12:03 -08:00
|
|
|
# For convenience in the console!
|
|
|
|
def self.find_by_name(color_name, species_name)
|
|
|
|
color = Color.find_by_name(color_name)
|
|
|
|
species = Species.find_by_name(species_name)
|
|
|
|
where(color_id: color, species_id: species).first
|
|
|
|
end
|
2024-01-24 03:25:23 -08:00
|
|
|
end
|