forked from OpenNeo/impress
Oops, fix bug with saving outfits of pets loaded from Neopets.com
Okay right, the wardrobe-2020 app treats `state` as a bit of an override thing, and `pose` is the main canonical field for how a pet looks. We were missing a few pieces here: 1. After loading a pet, we weren't including the `pose` field in the initial query string for the wardrobe URL, but we _were_ including the `state` field, so the outfit would get set up with a conflicting pet state ID vs pose. 2. When saving an outfit, we weren't taking the `state` field into account at all. This could cause the saved outfit to not quite match how it actually looked in-app, because the default pet state for that species/color/pose trio could be different; and regardless, the outfit state would come back with `appearanceId` set to `null`, which wouldn't match the local outfit state, which would trigger an infinite loop. Here, we complete the round-trip of the `state` field, from pet loading to outfit saving to the outfit data that comes back after saving!
This commit is contained in:
parent
566ac241a1
commit
dc44b4dbb3
4 changed files with 21 additions and 13 deletions
|
@ -116,7 +116,7 @@ class OutfitsController < ApplicationController
|
|||
def outfit_params
|
||||
params.require(:outfit).permit(
|
||||
:name, :starred, :alt_style_id, item_ids: {worn: [], closeted: []},
|
||||
biology: [:species_id, :color_id, :pose])
|
||||
biology: [:species_id, :color_id, :pose, :pet_state_id])
|
||||
end
|
||||
|
||||
def find_authorized_outfit
|
||||
|
|
|
@ -58,6 +58,7 @@ async function saveOutfit({
|
|||
speciesId,
|
||||
colorId,
|
||||
pose,
|
||||
appearanceId,
|
||||
altStyleId,
|
||||
wornItemIds,
|
||||
closetedItemIds,
|
||||
|
@ -69,6 +70,7 @@ async function saveOutfit({
|
|||
species_id: speciesId,
|
||||
color_id: colorId,
|
||||
pose: pose,
|
||||
pet_state_id: appearanceId,
|
||||
},
|
||||
alt_style_id: altStyleId,
|
||||
item_ids: { worn: wornItemIds, closeted: closetedItemIds },
|
||||
|
@ -127,6 +129,7 @@ function normalizeOutfit(outfit) {
|
|||
speciesId: String(outfit.species_id),
|
||||
colorId: String(outfit.color_id),
|
||||
pose: outfit.pose,
|
||||
appearanceId: outfit.pet_state_id,
|
||||
altStyleId: outfit.alt_style_id ? String(outfit.alt_style_id) : null,
|
||||
wornItemIds: (outfit.item_ids?.worn || []).map((id) => String(id)),
|
||||
closetedItemIds: (outfit.item_ids?.closeted || []).map((id) =>
|
||||
|
|
|
@ -102,15 +102,19 @@ class Outfit < ApplicationRecord
|
|||
end
|
||||
|
||||
def biology=(biology)
|
||||
@biology = biology.slice(:species_id, :color_id, :pose)
|
||||
@biology = biology.slice(:species_id, :color_id, :pose, :pet_state_id)
|
||||
|
||||
begin
|
||||
pet_type = PetType.where(
|
||||
species_id: @biology[:species_id],
|
||||
color_id: @biology[:color_id],
|
||||
).first!
|
||||
self.pet_state = pet_type.pet_states.with_pose(@biology[:pose]).
|
||||
emotion_order.first!
|
||||
if @biology[:pet_state_id]
|
||||
self.pet_state = PetState.find(@biology[:pet_state_id])
|
||||
else
|
||||
pet_type = PetType.where(
|
||||
species_id: @biology[:species_id],
|
||||
color_id: @biology[:color_id],
|
||||
).first!
|
||||
self.pet_state = pet_type.pet_states.with_pose(@biology[:pose]).
|
||||
emotion_order.first!
|
||||
end
|
||||
rescue ActiveRecord::RecordNotFound
|
||||
# If there's no such pet state (which shouldn't happen normally in-app),
|
||||
# we don't set `pet_state` but we keep `@biology` for validation.
|
||||
|
|
|
@ -85,11 +85,12 @@ class Pet < ApplicationRecord
|
|||
|
||||
def wardrobe_query
|
||||
{
|
||||
:name => self.name,
|
||||
:color => self.pet_type.color.id,
|
||||
:species => self.pet_type.species.id,
|
||||
:state => self.pet_state.id,
|
||||
:objects => self.items.map(&:id)
|
||||
name: self.name,
|
||||
color: self.pet_type.color.id,
|
||||
species: self.pet_type.species.id,
|
||||
pose: self.pet_state.pose,
|
||||
state: self.pet_state.id,
|
||||
objects: self.items.map(&:id),
|
||||
}.to_query
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue