Compare commits

...

7 commits

Author SHA1 Message Date
d34bebc336 Use a pet face when there's no paint brush, in Item Getting Guide
Now, for colors like Mutant or Magma where there's no paint brush
image to show, we use a sample pet image instead, to help it have equal
visual weight and clarity as the cases with the paint brushes.

We do some cleverness in here to make sure to always show the relevant
species, if possible!
2024-05-22 17:53:52 -07:00
4e11ee4da7 Add paint brush images to Item Getting Guide
In the previous change, we started grouping PB items by color. But I
wanted to better express that the grouping itself *is* an item, and the
items below it are secondary!

The main change we make here is to leverage DTI's existing design
language that "thumbnail image means item", and record thumbnail URLs
as well as paint brush names now, too!

We're still not leveraging the full Item system here, just fields on
Color. Keeping it simple for now!

Here's the script I ran to add the paint brush images to all the
existing colors!

```rb
Color.find_by_name("Baby").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/babypaintbrush.gif")
Color.find_by_name("Biscuit").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_biscuit.gif")
Color.find_by_name("Blue").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/bluepntbrsh.gif")
Color.find_by_name("Brown").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/brownpntbrush.gif")
Color.find_by_name("Camouflage").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_camo.gif")
Color.find_by_name("Candy").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_candy.gif")
Color.find_by_name("Checkered").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/checkeredpntbrush.gif")
Color.find_by_name("Christmas").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/xmaspaintbrush.gif")
Color.find_by_name("Cloud").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/cloudpntbrush.gif")
Color.find_by_name("Darigan").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/pb_darigan.gif")
Color.find_by_name("Dimensional").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_dimensional.gif")
Color.find_by_name("Disco").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/discopntbrush.gif")
Color.find_by_name("Electric").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/electricbluepntbrush.gif")
Color.find_by_name("Eventide").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/eventidepaintbrush.gif")
Color.find_by_name("Faerie").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/faeriepntbrush.gif")
Color.find_by_name("Fire").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/firepntbrush.gif")
Color.find_by_name("Elderlyboy").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/pb_elderly.gif")
Color.find_by_name("Elderlygirl").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/pb_elderly.gif")
Color.find_by_name("Ghost").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/ghostpntbrush.gif")
Color.find_by_name("Glowing").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/glowingpntbrsh.gif")
Color.find_by_name("Gold").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/gold_pntbrush.gif")
Color.find_by_name("Green").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/greenpntbrsh.gif")
Color.find_by_name("Grey").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/greypntbrush.gif")
Color.find_by_name("Halloween").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/halloweenpntbrsh.gif")
Color.find_by_name("Invisible").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/invisiblepntbrsh.gif")
Color.find_by_name("Desert").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/desertpaintbrush.gif")
Color.find_by_name("Maractite").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/maractitepaintbrush.gif")
Color.find_by_name("Maraquan").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/maraquanpntbrush.gif")
Color.find_by_name("Marble").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_marble.gif")
Color.find_by_name("Island").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/islandpntbrush.gif")
Color.find_by_name("Oil Paint").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/oilpaintingpntbrsh.gif")
Color.find_by_name("Orange").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/orange_paint_brush.gif")
Color.find_by_name("Origami").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_origami.gif")
Color.find_by_name("Pastel").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_pastel.gif")
Color.find_by_name("Pink").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/pink_paint_brush.gif")
Color.find_by_name("Pirate").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/piratepntbrush.gif")
Color.find_by_name("Plushie").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/plushiepaintbrush.gif")
Color.find_by_name("Polka Dot").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_polkadot.gif")
Color.find_by_name("Purple").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/purplepntbrsh.gif")
Color.find_by_name("Rainbow").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/rainbowpntbrsh.gif")
Color.find_by_name("Red").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/redpntbrsh.gif")
Color.find_by_name("Relic").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/relic_pntbrush.gif")
Color.find_by_name("Royalboy").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_royal.gif")
Color.find_by_name("Royalgirl").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_royal.gif")
Color.find_by_name("Sketch").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/sketchpntbrush.gif")
Color.find_by_name("Shadow").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/shadowpntbrsh.gif")
Color.find_by_name("Silver").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/silverpntbrsh.gif")
Color.find_by_name("Skunk").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/skunkpntbrush.gif")
Color.find_by_name("Snow").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_snowman.gif")
Color.find_by_name("Speckled").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/greenwhitedotspntbrush.gif")
Color.find_by_name("Split").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/halfandhalfpntbrsh.gif")
Color.find_by_name("Spotted").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/spottedpntbrush.gif")
Color.find_by_name("Starry").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/starspntbrush.gif")
Color.find_by_name("Stealthy").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/pb_stealthy.gif")
Color.find_by_name("Steampunk").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_steampunk.gif")
Color.find_by_name("Strawberry").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/strawberrypntbrush.gif")
Color.find_by_name("Striped").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/stripedpntbrsh.gif")
Color.find_by_name("Swamp Gas").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/newpbsg2011color.gif")
Color.find_by_name("Toy").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_toy.gif")
Color.find_by_name("Transparent").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/transparentpaintbrush.gif")
Color.find_by_name("Tyrannian").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/tyrannianpntbrush.gif")
Color.find_by_name("Usuki Boy").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/usukipaintbrush.gif")
Color.find_by_name("Usuki Girl").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/usukipaintbrush.gif")
Color.find_by_name("Valentine").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_valentine.gif")
Color.find_by_name("Water").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_water.gif")
Color.find_by_name("White").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/whitepntbrsh.gif")
Color.find_by_name("Woodland").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_woodland.gif")
Color.find_by_name("Wraith").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_wraith.gif")
Color.find_by_name("Yellow").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/yellowpntbrsh.gif")
Color.find_by_name("Zombie").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_zombie.gif")
```
2024-05-22 16:59:36 -07:00
1a76923ce6 Group PB items by color in Item Getting Guide
Ohh yeah, this helps communicate the process much better, especially
for what the Shops/Trades links mean.

I think I'm gonna also go get the paint brush thumbnail images and add
them to the database too, to help better communicate that this is a
paint brush item situation.
2024-05-22 16:34:48 -07:00
a8648fc9c1 Add a limit to the number of items for the Item Getting Guide
Just to make it harder to willfully overload the server or whatever!
2024-05-22 16:09:49 -07:00
1b03c2caed Add more PB item info and links to Item Getting Guide
I add some infrastructural support for inferring an item's paintbrush
color (if any), and a field to the database to manually track an item's
paint brush item name! This is both useful for tracking which colors
are even *available* via paint brush, and also for working with colors
with unusual paint brush names, like the "Get Off My Lawn Paint Brush"
(for Elderly pets).

Here's the script I ran to backfill this for current colors and their
paint brushes!

```rb
Color.find_by_name("Baby").update!(pb_item_name: "Baby Paint Brush")
Color.find_by_name("Biscuit").update!(pb_item_name: "Biscuit Paint Brush")
Color.find_by_name("Blue").update!(pb_item_name: "Blue Paint Brush")
Color.find_by_name("Brown").update!(pb_item_name: "Brown Paint Brush")
Color.find_by_name("Camouflage").update!(pb_item_name: "Camouflage Paint Brush")
Color.find_by_name("Candy").update!(pb_item_name: "Candy Paint Brush")
Color.find_by_name("Checkered").update!(pb_item_name: "Checkered Paint Brush")
Color.find_by_name("Christmas").update!(pb_item_name: "Christmas Paint Brush")
Color.find_by_name("Cloud").update!(pb_item_name: "Cloud Paint Brush")
Color.find_by_name("Darigan").update!(pb_item_name: "Darigan Paint Brush")
Color.find_by_name("Dimensional").update!(pb_item_name: "Dimensional Paint Brush")
Color.find_by_name("Disco").update!(pb_item_name: "Disco Fever Paint Brush")
Color.find_by_name("Electric").update!(pb_item_name: "Electric Blue Paint Brush")
Color.find_by_name("Eventide").update!(pb_item_name: "Eventide Paint Brush")
Color.find_by_name("Faerie").update!(pb_item_name: "Faerie Paint Brush")
Color.find_by_name("Fire").update!(pb_item_name: "Fire, Fire, Your Pants On Fire Paint Brush")
Color.find_by_name("Elderlyboy").update!(pb_item_name: "Get Off My Lawn Paint Brush")
Color.find_by_name("Elderlygirl").update!(pb_item_name: "Get Off My Lawn Paint Brush")
Color.find_by_name("Ghost").update!(pb_item_name: "Ghost Paint Brush")
Color.find_by_name("Glowing").update!(pb_item_name: "Glowing Paint Brush")
Color.find_by_name("Gold").update!(pb_item_name: "Golden Paint Brush")
Color.find_by_name("Green").update!(pb_item_name: "Green Paint Brush")
Color.find_by_name("Grey").update!(pb_item_name: "Grey Paint Brush")
Color.find_by_name("Halloween").update!(pb_item_name: "Halloween Paint Brush")
Color.find_by_name("Invisible").update!(pb_item_name: "Invisible Paint Brush")
Color.find_by_name("Desert").update!(pb_item_name: "Lost Desert Paint Brush")
Color.find_by_name("Maractite").update!(pb_item_name: "Maractite Paint Brush")
Color.find_by_name("Maraquan").update!(pb_item_name: "Maraquan Paint Brush")
Color.find_by_name("Marble").update!(pb_item_name: "Marble Paint Brush")
Color.find_by_name("Island").update!(pb_item_name: "Mystery Island Paint Brush")
Color.find_by_name("Oil Paint").update!(pb_item_name: "Oil Paint Brush")
Color.find_by_name("Orange").update!(pb_item_name: "Orange Paint Brush")
Color.find_by_name("Origami").update!(pb_item_name: "Origami Paint Brush")
Color.find_by_name("Pastel").update!(pb_item_name: "Pastel Paint Brush")
Color.find_by_name("Pink").update!(pb_item_name: "Pink Paint Brush")
Color.find_by_name("Pirate").update!(pb_item_name: "Pirate Paint Brush")
Color.find_by_name("Plushie").update!(pb_item_name: "Plushie Paint Brush")
Color.find_by_name("Polka Dot").update!(pb_item_name: "Polka Dot Paint Brush")
Color.find_by_name("Purple").update!(pb_item_name: "Purple Paint Brush")
Color.find_by_name("Rainbow").update!(pb_item_name: "Rainbow Paint Brush")
Color.find_by_name("Red").update!(pb_item_name: "Red Paint Brush")
Color.find_by_name("Relic").update!(pb_item_name: "Relic Paint Brush")
Color.find_by_name("Royalboy").update!(pb_item_name: "Royal Paint Brush")
Color.find_by_name("Royalgirl").update!(pb_item_name: "Royal Paint Brush")
Color.find_by_name("Sketch").update!(pb_item_name: "Scritchy Sketchy Paint Brush")
Color.find_by_name("Shadow").update!(pb_item_name: "Shadow Paint Brush")
Color.find_by_name("Silver").update!(pb_item_name: "Silver Paint Brush")
Color.find_by_name("Skunk").update!(pb_item_name: "Skunk Paint Brush")
Color.find_by_name("Snow").update!(pb_item_name: "Snow Paint Brush")
Color.find_by_name("Speckled").update!(pb_item_name: "Speckled Paint Brush")
Color.find_by_name("Split").update!(pb_item_name: "Split Paint Brush")
Color.find_by_name("Spotted").update!(pb_item_name: "Spotted Paint Brush")
Color.find_by_name("Starry").update!(pb_item_name: "Starry Paint Brush")
Color.find_by_name("Stealthy").update!(pb_item_name: "Stealth Paint Brush")
Color.find_by_name("Steampunk").update!(pb_item_name: "Steampunk Paint Brush")
Color.find_by_name("Strawberry").update!(pb_item_name: "Strawberry Fields Forever Paint Brush")
Color.find_by_name("Striped").update!(pb_item_name: "Striped Paint Brush")
Color.find_by_name("Swamp Gas").update!(pb_item_name: "Swamp Gas Paint Brush")
Color.find_by_name("Toy").update!(pb_item_name: "Toy Paint Brush")
Color.find_by_name("Transparent").update!(pb_item_name: "Transparent Paint Brush")
Color.find_by_name("Tyrannian").update!(pb_item_name: "Tyrannian Paint Brush")
Color.find_by_name("Usuki Boy").update!(pb_item_name: "Usuki Paint Brush")
Color.find_by_name("Usuki Girl").update!(pb_item_name: "Usuki Paint Brush")
Color.find_by_name("Valentine").update!(pb_item_name: "Valentine Paint Brush")
Color.find_by_name("Water").update!(pb_item_name: "Water Paint Brush")
Color.find_by_name("White").update!(pb_item_name: "White Paint Brush")
Color.find_by_name("Woodland").update!(pb_item_name: "Woodland Paint Brush")
Color.find_by_name("Wraith").update!(pb_item_name: "Wraith Paint Brush")
Color.find_by_name("Yellow").update!(pb_item_name: "Yellow Paint Brush")
Color.find_by_name("Zombie").update!(pb_item_name: "Zombie Paint Brush")

```
2024-05-22 16:09:49 -07:00
1bd5598b64 Improve row focus and keyboard nav in Item Getting Guide
Clearer focus states, row changes bg color on hover/focus to help you
track where you are, remove the redundant image thumbnail link from the
tab order (it's the same as the item name link!)
2024-05-22 14:58:02 -07:00
189cb6a132 Set fixed table width for Item Getting Guide tables
We'll need to dig into this more for mobile, but here's my initial
attempt at getting the tables to be consistently-sized and such!
2024-05-22 14:47:43 -07:00
10 changed files with 162 additions and 28 deletions

View file

@ -4,6 +4,9 @@
.item-list
border-collapse: collapse
border: 1px solid $soft-border-color
width: 60%
table-layout: auto
margin-bottom: 2em
td, th
border-top: 1px solid $soft-border-color
@ -17,20 +20,29 @@
&:last-child
padding-right: .5em
.thumbnail-cell img
display: block
.thumbnail-cell
width: 2.5em
height: 2.5em
img
display: block
width: 100%
height: 100%
.name-cell a
text-decoration: none
&:hover, &:focus
text-decoration: underline
.actions-cell
text-align: right
padding-left: 1em
font-size: 85%
.name-cell a
text-decoration: none
&:hover
text-decoration: underline
tbody
tr
&:hover, &:focus-within
background: rgba($module-bg-color, 0.5)
thead
background: $module-bg-color
@ -38,6 +50,23 @@
th
text-align: left
.thumbnail-cell img
outline: 1px solid $soft-border-color
.actions-cell button
/* Bootstrap's Purple 600 */
+awesome-button-color(#59359a)
.special-color-explanation
text-wrap: balance
font-style: italic
/* For wearable items that belong to a specific set that all come together,
* like a Paint Brush. */
&[data-group-type="bundle"]
tbody
.thumbnail-cell
opacity: 0.65
tr:hover .thumbnail-cell
opacity: 0.85

View file

@ -114,18 +114,36 @@ class ItemsController < ApplicationController
def sources
item_ids = params[:ids].split(",")
@items = Item.where(id: item_ids).includes(:nc_mall_record).order(:name)
@items = Item.where(id: item_ids).includes(:nc_mall_record).order(:name).
limit(50)
if @items.empty?
render file: "public/404.html", status: :not_found, layout: nil
return
end
# Group the items by category!
@nc_mall_items = @items.select(&:currently_in_mall?)
@other_nc_items = @items.select(&:nc?).reject(&:currently_in_mall?)
@np_items = @items.select(&:np?)
@pb_items = @items.select(&:pb?)
# Also, PB items have some special handling: we group them by color, then
# load example pet types for the colors that don't have paint brushes.
@pb_items_by_color = @pb_items.group_by(&:pb_color).
sort_by { |color, items| color.name }.to_h
colors_without_thumbnails =
@pb_items_by_color.keys.reject(&:pb_item_thumbnail_url?)
@pb_color_pet_types = colors_without_thumbnails.map do |color|
# Infer the ideal species from the first item we can, then try to find a
# matching pet type to use as the thumbnail, if needed.
species = @pb_items_by_color[color].map(&:pb_species).select(&:present?)
.first
[color, color.example_pet_type(preferred_species: species)]
end.to_h
render layout: "application"
end

View file

@ -2,23 +2,34 @@ require "addressable/template"
module ItemsHelper
module PetTypeImage
Format = 'https://pets.neopets.com/cp/%s/%i/%i.png'
Template = Addressable::Template.new(
"https://pets.neopets.com/cp/{hash}/{emotion}/{size}.png"
)
Emotions = {
:happy => 1,
:sad => 2,
:angry => 3,
:ill => 4
happy: 1,
sad: 2,
angry: 3,
ill: 4,
}
Sizes = {
:face => 1,
:thumb => 2,
:zoom => 3,
:full => 4
face: 1,
thumb: 2,
zoom: 3,
full: 4,
face_2x: 6,
}
end
def pet_type_image_url(pet_type, emotion: :happy, size: :face)
PetTypeImage::Template.expand(
hash: pet_type.basic_image_hash || pet_type.image_hash,
emotion: PetTypeImage::Emotions[emotion],
size: PetTypeImage::Sizes[size],
).to_s
end
def standard_species_search_links
build_on_pet_types(Species.alphabetical) do |pet_type|
image = pet_type_image(pet_type, :happy, :zoom)
@ -97,8 +108,9 @@ module ItemsHelper
SHOP_WIZARD_URL_TEMPLATE = Addressable::Template.new(
"https://www.neopets.com/shops/wizard.phtml{?string}"
)
def shop_wizard_url_for(item)
SHOP_WIZARD_URL_TEMPLATE.expand(string: item.name).to_s
def shop_wizard_url_for(item_or_name)
item_or_name = item_or_name.name if item_or_name.is_a? Item
SHOP_WIZARD_URL_TEMPLATE.expand(string: item_or_name).to_s
end
SUPER_SHOP_WIZARD_URL_TEMPLATE = Addressable::Template.new(
@ -111,8 +123,9 @@ module ItemsHelper
TRADING_POST_URL_TEMPLATE = Addressable::Template.new(
"https://www.neopets.com/island/tradingpost.phtml?type=browse&criteria=item_exact{&search_string}"
)
def trading_post_url_for(item)
TRADING_POST_URL_TEMPLATE.expand(search_string: item.name).to_s
def trading_post_url_for(item_or_name)
item_or_name = item_or_name.name if item_or_name.is_a? Item
TRADING_POST_URL_TEMPLATE.expand(search_string: item_or_name).to_s
end
AUCTION_GENIE_URL_TEMPLATE = Addressable::Template.new(
@ -155,9 +168,7 @@ module ItemsHelper
end
def pet_type_image(pet_type, emotion, size)
emotion_id = PetTypeImage::Emotions[emotion]
size_id = PetTypeImage::Sizes[size]
src = sprintf(PetTypeImage::Format, pet_type.basic_image_hash, emotion_id, size_id)
src = pet_type_image_url(pet_type, emotion:, size:)
human_name = pet_type.species.name.humanize
image_tag(src, :alt => human_name, :title => human_name)
end

View file

@ -21,6 +21,11 @@ class Color < ApplicationRecord
end
end
def example_pet_type(preferred_species: Species.first)
pet_types.order([Arel.sql("species_id = ? DESC"), preferred_species.id],
"species_id ASC").first
end
def unfunny_human_name
if name
name.split(' ').map { |word| word.capitalize }.join(' ')

View file

@ -179,6 +179,36 @@ class Item < ApplicationRecord
nc_mall_record&.current_price
end
# If this is a PB item, return the corresponding Color, inferred from the
# item name. If it's not a PB item, or we fail to infer, return nil.
def pb_color
return nil unless pb?
# NOTE: To handle colors like "Royalboy", where the items aren't consistent
# with the color name regarding whether or not there's spaces, we remove
# all spaces from the item name and color name when matching. We also
# hackily handle the fact that "Elderlyboy" color has items named "Elderly
# Male" (and same for Girl/Female) by replacing those words, too. These
# hacks could cause false matches in theory, but I'm not aware of any rn!
normalized_name = name.downcase.gsub("female", "girl").gsub("male", "boy").
gsub(/\s/, "")
Color.order(:name).
find { |c| normalized_name.include?(c.name.downcase.gsub(/\s/, "")) }
end
# If this is a PB item, return the corresponding Species, inferred from the
# item name. If it's not a PB item, or we fail to infer, return nil.
def pb_species
return nil unless pb?
normalized_name = name.downcase
Species.order(:name).find { |s| normalized_name.include?(s.name.downcase) }
end
def pb_item_name
pb_color&.pb_item_name
end
def restricted_zones(options={})
options[:scope] ||= Zone.all
options[:scope].find(restricted_zone_ids)

View file

@ -1,4 +1,6 @@
%tr
%td.thumbnail-cell= link_to item_thumbnail_for(item), item, target: "_blank"
%td.thumbnail-cell
= link_to item_thumbnail_for(item), item, target: "_blank",
tabindex: "-1"
%td.name-cell= link_to item.name, item, target: "_blank"
%td.actions-cell= yield

View file

@ -54,13 +54,40 @@
target: "_blank", icon: search_icon
- if @pb_items.present?
%h2 Paintbrush items
%h2 Paint Brush items
:markdown
These items are part of a paintbrush set. Once you paint your pet,
These items are part of a paint brush set. Once you paint your pet,
these items will be semi-permanently added to your Closet, even if your
pet changes color again! You can use this to mix-and-match styles for
"cross-paint" outfits.
= render @pb_items
- @pb_items_by_color.each do |color, items|
%table.item-list{"data-group-type": "bundle"}
%thead
%td.thumbnail-cell
- if color.pb_item_thumbnail_url?
= image_tag color.pb_item_thumbnail_url,
alt: "Item thumbnail for #{color.pb_item_name}"
- else
= image_tag pet_type_image_url(@pb_color_pet_types[color], size: :face),
srcset: ["#{pet_type_image_url(@pb_color_pet_types[color], size: :face_2x)} 2x"],
alt: @pb_color_pet_types[color].human_name
%th
#{color.pb_item_name || color.name.humanize}
(#{pluralize items.size, "item"})
%td.actions-cell
- if color.pb_item_name?
= button_link_to "Shops",
shop_wizard_url_for(color.pb_item_name),
target: "_blank", icon: search_icon
= button_link_to "Trades",
trading_post_url_for(color.pb_item_name),
target: "_blank", icon: search_icon
- else
.special-color-explanation
Get via Lab Ray, morphing potions, etc.
%tbody
- items.each do |item|
= render "item_list_row", item:
- if @other_nc_items.present?
%h2 Neocash items (Capsules, Dyeworks, events, retired, etc.)

View file

@ -0,0 +1,5 @@
class AddPbItemNameToColors < ActiveRecord::Migration[7.1]
def change
add_column :colors, :pb_item_name, :string
end
end

View file

@ -0,0 +1,5 @@
class AddPbItemThumbnailUrlToColors < ActiveRecord::Migration[7.1]
def change
add_column :colors, :pb_item_thumbnail_url, :string
end
end

View file

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.1].define(version: 2024_05_11_003019) do
ActiveRecord::Schema[7.1].define(version: 2024_05_22_233638) do
create_table "alt_styles", charset: "utf8mb4", collation: "utf8mb4_unicode_520_ci", force: :cascade do |t|
t.integer "species_id", null: false
t.integer "color_id", null: false
@ -76,6 +76,8 @@ ActiveRecord::Schema[7.1].define(version: 2024_05_11_003019) do
t.boolean "standard"
t.boolean "prank", default: false, null: false
t.string "name", null: false
t.string "pb_item_name"
t.string "pb_item_thumbnail_url"
end
create_table "contributions", id: :integer, charset: "utf8mb4", collation: "utf8mb4_unicode_520_ci", force: :cascade do |t|