Emi Matchu
48c1a58df9
This bug never made it into production I think, it was a consequence of some of how I refactored stuff in the recent changes? I think?? But yeah, I refactor how we manage `SwfAsset#body_id`, to be a bit more explicit about when and how it can change, instead of the weird callbacks that tbqh have bit us too often…
103 lines
3.4 KiB
Ruby
103 lines
3.4 KiB
Ruby
# A representation of a Neopets::CustomPets viewer data response, translated
|
|
# to DTI's database models!
|
|
class Pet::ModelingSnapshot
|
|
def initialize(viewer_data_hash)
|
|
@custom_pet = viewer_data_hash[:custom_pet]
|
|
@object_info_registry = viewer_data_hash[:object_info_registry]
|
|
@object_asset_registry = viewer_data_hash[:object_asset_registry]
|
|
end
|
|
|
|
def pet_type
|
|
@pet_type ||= begin
|
|
raise Pet::UnexpectedDataFormat unless @custom_pet[:species_id]
|
|
raise Pet::UnexpectedDataFormat unless @custom_pet[:color_id]
|
|
raise Pet::UnexpectedDataFormat unless @custom_pet[:body_id]
|
|
|
|
@custom_pet => {species_id:, color_id:}
|
|
PetType.find_or_initialize_by(species_id:, color_id:).tap do |pet_type|
|
|
# Apply the pet's body ID to the pet type, unless it's wearing an alt
|
|
# style, in which case ignore it, because it's the *alt style*'s body ID.
|
|
# (This can theoretically cause a problem saving a new pet type when
|
|
# there's an alt style too!)
|
|
pet_type.body_id = @custom_pet[:body_id] unless @custom_pet[:alt_style]
|
|
if pet_type.body_id.nil?
|
|
raise Pet::UnexpectedDataFormat,
|
|
"can't process alt style on first occurrence of pet type"
|
|
end
|
|
|
|
# Try using this pet for the pet type's thumbnail, but don't worry
|
|
# if it fails.
|
|
begin
|
|
pet_type.consider_pet_image(@custom_pet[:name])
|
|
rescue => error
|
|
Rails.logger.warn "Failed to load pet image: #{error.full_message}"
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def pet_state
|
|
@pet_state ||= begin
|
|
swf_asset_ids = biology_assets.map(&:remote_id)
|
|
pet_type.pet_states.find_or_initialize_by(swf_asset_ids:).tap do |pet_state|
|
|
pet_state.swf_assets = biology_assets
|
|
end
|
|
end
|
|
end
|
|
|
|
def alt_style
|
|
@alt_style ||= begin
|
|
return nil unless @custom_pet[:alt_style]
|
|
raise Pet::UnexpectedDataFormat unless @custom_pet[:alt_color]
|
|
|
|
id = @custom_pet[:alt_style].to_i
|
|
AltStyle.find_or_initialize_by(id:).tap do |alt_style|
|
|
alt_style.assign_attributes(
|
|
color_id: @custom_pet[:alt_color].to_i,
|
|
species_id: @custom_pet[:species_id].to_i,
|
|
body_id: @custom_pet[:body_id].to_i,
|
|
swf_assets: alt_style_assets,
|
|
)
|
|
end
|
|
end
|
|
end
|
|
|
|
def items
|
|
@items ||= @object_info_registry.map do |id, item_data|
|
|
Item.find_or_initialize_by(id:).tap do |item|
|
|
item.add_origin_registry_info item_data
|
|
item.swf_assets = item_assets_for id
|
|
end
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def biology_assets
|
|
@biology_assets ||= begin
|
|
biology = @custom_pet[:alt_style].present? ?
|
|
@custom_pet[:original_biology] :
|
|
@custom_pet[:biology_by_zone]
|
|
assets_from_biology(biology)
|
|
end
|
|
end
|
|
|
|
def item_assets_for(item_id)
|
|
all_infos = @object_asset_registry.values
|
|
infos = all_infos.select { |a| a[:obj_info_id].to_i == item_id.to_i }
|
|
infos.map do |asset_data|
|
|
SwfAsset.from_object_data(@custom_pet[:body_id], asset_data)
|
|
end
|
|
end
|
|
|
|
def alt_style_assets
|
|
raise Pet::UnexpectedDataFormat if @custom_pet[:biology_by_zone].empty?
|
|
@alt_style_assets ||= assets_from_biology(@custom_pet[:biology_by_zone])
|
|
end
|
|
|
|
def assets_from_biology(biology)
|
|
raise Pet::UnexpectedDataFormat if biology.empty?
|
|
body_id = @custom_pet[:body_id].to_i
|
|
biology.values.map { |b| SwfAsset.from_biology_data(body_id, b) }
|
|
end
|
|
end
|