Compare commits

...

7 commits

Author SHA1 Message Date
e0f9a27adc Merge branch 'main' into simpler-item-previews 2024-08-31 13:43:10 -07:00
1c36276865 Remove unused special_color logic from Item
We used to use this to determine what color to show by default on the
item page preview for, like, Maraquan-specific items. Now, we infer it
from our actual customization data, rather than these heuristics!

There's still a database field for `Item#manual_special_color_id`. We
can still read and write this from the support UI, and Impress 2020
still slightly uses it from the homepage, so I'm not removing from the
database right now.
2024-08-31 13:42:25 -07:00
6fdeffebf1 Simplify PetType.random_basic_per_species
I'm mostly just going around looking for `special_color`, a concept I
think the app doesn't use anymore, and removing it where I see it!
2024-08-31 13:37:12 -07:00
2f341cfd39 Merge branch 'main' into simpler-item-previews 2024-08-31 13:31:46 -07:00
6312253b82 Simplify standard_species_search_links helper
The `build_on_pet_types` helper used to be reused on the items page, to
generate the list of species to display. We don't use it anymore, so
simplify and remove!
2024-08-31 13:31:24 -07:00
8ab5af1aca Remove unused logic for whether a zone is "sometimes" occupied
I'm about to reimplement the more-robust version of what this used to
be: how the item page used to say "sometimes" after certain zones in
the occupied list.

Now, we're going to do parity with 2020, and list the actual species!

I like that this takes away the weird `#sometimes` method on the `Zone`
class, which was always an odd hack for just this small thing.
2024-08-31 13:16:47 -07:00
bd62476722 Add basic zone info to simpler item previews
We're missing the feature where we enumerate the exact species in
ambiguous cases, though!
2024-08-31 13:11:50 -07:00
6 changed files with 51 additions and 95 deletions

View file

@ -160,3 +160,26 @@ body.items-show
select select
border-color: $error-border-color border-color: $error-border-color
color: $error-color color: $error-color
.item-zones-info
margin-top: .5em
h3
display: inline
font: inherit
font-weight: bold
&:after
content: ": "
ul
list-style-type: none
display: inline
li
display: inline
&:not(:last-of-type):after
content: ", "
.no-zones
font-style: italic
opacity: .85

View file

@ -31,11 +31,12 @@ module ItemsHelper
end end
def standard_species_search_links def standard_species_search_links
build_on_pet_types(Species.alphabetical) do |pet_type| all_species = Species.alphabetical.map(&:id)
PetType.random_basic_per_species(all_species).map do |pet_type|
image = pet_type_image(pet_type, :happy, :zoom) image = pet_type_image(pet_type, :happy, :zoom)
query = "species:#{pet_type.species.name}" query = "species:#{pet_type.species.name}"
link_to(image, items_path(:q => query)) link_to(image, items_path(:q => query))
end end.join.html_safe
end end
def closet_list_verb(owned) def closet_list_verb(owned)
@ -223,15 +224,6 @@ module ItemsHelper
private private
def build_on_pet_types(species, special_color=nil, &block)
species_ids = species.map(&:id)
pet_types = special_color ?
PetType.where(:color_id => special_color.id, :species_id => species_ids).
order(:species_id) :
PetType.random_basic_per_species(species.map(&:id))
pet_types.map(&block).join.html_safe
end
def pet_type_image(pet_type, emotion, size) def pet_type_image(pet_type, emotion, size)
src = pet_type_image_url(pet_type, emotion:, size:) src = pet_type_image_url(pet_type, emotion:, size:)
human_name = pet_type.species.name.humanize human_name = pet_type.species.name.humanize

View file

@ -25,8 +25,6 @@ class Item < ApplicationRecord
NCRarities = [0, 500] NCRarities = [0, 500]
PAINTBRUSH_SET_DESCRIPTION = 'This item is part of a deluxe paint brush set!' PAINTBRUSH_SET_DESCRIPTION = 'This item is part of a deluxe paint brush set!'
SPECIAL_COLOR_DESCRIPTION_REGEX =
/This item is only wearable by [a-zA-Z]+ painted ([a-zA-Z]+)\.|WARNING: This [a-zA-Z]+ can be worn by ([a-zA-Z]+) [a-zA-Z]+ ONLY!|If your Neopet is not painted ([a-zA-Z]+), it will not be able to wear this item\./
scope :newest, -> { scope :newest, -> {
order(arel_table[:created_at].desc) if arel_table[:created_at] order(arel_table[:created_at].desc) if arel_table[:created_at]
@ -283,78 +281,15 @@ class Item < ApplicationRecord
occupied_zones.map(&:id) occupied_zones.map(&:id)
end end
def occupied_zones(options={}) def occupied_zones
options[:scope] ||= Zone.all zone_ids = swf_assets.map(&:zone_id).uniq
all_body_ids = [] Zone.find(zone_ids)
zone_body_ids = {}
selected_assets = swf_assets.select('body_id, zone_id').each do |swf_asset|
zone_body_ids[swf_asset.zone_id] ||= []
body_ids = zone_body_ids[swf_asset.zone_id]
body_ids << swf_asset.body_id unless body_ids.include?(swf_asset.body_id)
all_body_ids << swf_asset.body_id unless all_body_ids.include?(swf_asset.body_id)
end
zones = options[:scope].find(zone_body_ids.keys)
zones_by_id = zones.inject({}) { |h, z| h[z.id] = z; h }
total_body_ids = all_body_ids.size
zone_body_ids.each do |zone_id, body_ids|
zones_by_id[zone_id].sometimes = true if body_ids.size < total_body_ids
end
zones
end end
def affected_zones def affected_zones
restricted_zones + occupied_zones restricted_zones + occupied_zones
end end
def special_color
@special_color ||= determine_special_color
end
def special_color_id
special_color.try(:id)
end
protected
def determine_special_color
I18n.with_locale(I18n.default_locale) do
# Rather than go find the special description in all locales, let's just
# run this logic in English.
if description.include?(PAINTBRUSH_SET_DESCRIPTION)
name_words = name.downcase.split
Color.nonstandard.each do |color|
return color if name_words.include?(color.name)
end
end
match = description.match(SPECIAL_COLOR_DESCRIPTION_REGEX)
if match
# Since there are multiple formats in the one regex, there are multiple
# possible color name captures. So, take the first non-nil capture.
color = match.captures.detect(&:present?)
return Color.find_by_name(color.downcase)
end
# HACK: this should probably be a flag on the record instead of
# being hardcoded :P
if [71893, 76192, 76202, 77367, 77368, 77369, 77370].include?(id)
return Color.find_by_name('baby')
end
if [76198].include?(id)
return Color.find_by_name('mutant')
end
if [75372].include?(id)
return Color.find_by_name('maraquan')
end
if manual_special_color_id?
return Color.find(manual_special_color_id)
end
end
end
public
def species_support_ids def species_support_ids
@species_support_ids_array ||= read_attribute('species_support_ids').split(',').map(&:to_i) rescue nil @species_support_ids_array ||= read_attribute('species_support_ids').split(',').map(&:to_i) rescue nil
end end

View file

@ -11,6 +11,7 @@ class PetType < ApplicationRecord
BasicHashes = YAML::load_file(Rails.root.join('config', 'basic_type_hashes.yml')) BasicHashes = YAML::load_file(Rails.root.join('config', 'basic_type_hashes.yml'))
scope :basic, -> { joins(:color).merge(Color.basic) }
scope :matching_name, ->(color_name, species_name) { scope :matching_name, ->(color_name, species_name) {
color = Color.find_by_name!(color_name) color = Color.find_by_name!(color_name)
species = Species.find_by_name!(species_name) species = Species.find_by_name!(species_name)
@ -28,17 +29,11 @@ class PetType < ApplicationRecord
merge(Color.order(basic: :desc, standard: :desc, name: :asc)) merge(Color.order(basic: :desc, standard: :desc, name: :asc))
} }
def self.special_color_or_basic(special_color)
color_ids = special_color ? [special_color.id] : Color.basic.select([:id]).map(&:id)
where(color_id: color_ids)
end
def self.random_basic_per_species(species_ids) def self.random_basic_per_species(species_ids)
random_pet_types = [] random_pet_types = []
# TODO: omg so lame :P basics_by_species_id = basic.group_by(&:species_id)
standards = special_color_or_basic(nil).group_by(&:species_id)
species_ids.each do |species_id| species_ids.each do |species_id|
pet_types = standards[species_id] pet_types = basics_by_species_id[species_id]
random_pet_types << pet_types[rand(pet_types.size)] if pet_types random_pet_types << pet_types[rand(pet_types.size)] if pet_types
end end
random_pet_types random_pet_types

View file

@ -1,8 +1,4 @@
class Zone < ActiveRecord::Base class Zone < ActiveRecord::Base
# When selecting zones that an asset occupies, we allow the zone to set
# whether or not the zone is "sometimes" occupied. This is false by default.
attr_writer :sometimes
scope :alphabetical, -> { order(:label) } scope :alphabetical, -> { order(:label) }
scope :matching_label, ->(label) { scope :matching_label, ->(label) {
where(plain_label: Zone.plainify_label(label)) where(plain_label: Zone.plainify_label(label))
@ -13,10 +9,6 @@ class Zone < ActiveRecord::Base
super({only: [:id, :depth, :label]}.merge(options)) super({only: [:id, :depth, :label]}.merge(options))
end end
def uncertain_label
@sometimes ? "#{label} sometimes" : label
end
def is_commonly_used_by_items def is_commonly_used_by_items
# Zone metadata marks item zones with types 2, 3, and 4. But also, in # Zone metadata marks item zones with types 2, 3, and 4. But also, in
# practice, the Biology Effects zone (type 1, ID 4) has been used for a few # practice, the Biology Effects zone (type 1, ID 4) has been used for a few

View file

@ -33,6 +33,25 @@
"id", "human_name", @selected_preview_pet_type.species_id) "id", "human_name", @selected_preview_pet_type.species_id)
= submit_tag "Go", name: nil = submit_tag "Go", name: nil
.item-zones-info
%section
%h3 Occupies
- if @item.occupied_zones.present?
%ul
- @item.occupied_zones.sort_by(&:label).each do |zone|
%li= zone.label
- else
%span.no-zones (None)
%section
%h3 Restricts
- if @item.restricted_zones.present?
%ul
- @item.restricted_zones.sort_by(&:label).each do |zone|
%li= zone.label
- else
%span.no-zones (None)
- unless @contributors_with_counts.empty? - unless @contributors_with_counts.empty?
#item-contributors #item-contributors
%header #{t '.contributors.header'}: %header #{t '.contributors.header'}: