2023-08-02 16:05:02 -07:00
|
|
|
class PetState < ApplicationRecord
|
2010-05-20 18:11:08 -07:00
|
|
|
SwfAssetType = 'biology'
|
2024-10-04 19:24:40 -07:00
|
|
|
|
|
|
|
MAIN_POSES = %w(HAPPY_FEM HAPPY_MASC SAD_FEM SAD_MASC SICK_FEM SICK_MASC)
|
2012-01-12 15:17:59 -08:00
|
|
|
|
2013-03-05 18:51:24 -08:00
|
|
|
has_many :contributions, :as => :contributed,
|
|
|
|
:inverse_of => :contributed # in case of duplicates being merged
|
2010-11-15 18:15:33 -08:00
|
|
|
has_many :outfits
|
2024-11-06 14:31:16 -08:00
|
|
|
has_many :parent_swf_asset_relationships, :as => :parent,
|
|
|
|
:autosave => false
|
2012-01-12 15:17:59 -08:00
|
|
|
has_many :swf_assets, :through => :parent_swf_asset_relationships
|
2011-06-21 17:42:41 -07:00
|
|
|
|
2010-10-07 07:46:23 -07:00
|
|
|
belongs_to :pet_type
|
2011-06-21 17:42:41 -07:00
|
|
|
|
2024-10-07 17:38:53 -07:00
|
|
|
delegate :species_id, :species, :color_id, :color, to: :pet_type
|
2014-03-28 13:15:04 -07:00
|
|
|
|
2010-10-07 07:46:23 -07:00
|
|
|
alias_method :swf_asset_ids_from_association, :swf_asset_ids
|
2024-11-06 14:31:16 -08:00
|
|
|
|
|
|
|
attr_writer :parent_swf_asset_relationships_to_update
|
2011-06-21 17:42:41 -07:00
|
|
|
|
2023-11-02 13:50:33 -07:00
|
|
|
# A simple ordering that tries to bring reliable pet states to the front.
|
2023-07-22 14:04:01 -07:00
|
|
|
scope :emotion_order, -> {
|
2023-11-02 13:50:33 -07:00
|
|
|
order(Arel.sql(
|
|
|
|
"(mood_id IS NULL) ASC, mood_id ASC, female DESC, unconverted DESC, " +
|
|
|
|
"glitched ASC, id DESC"
|
|
|
|
))
|
2023-07-22 14:04:01 -07:00
|
|
|
}
|
2011-06-21 17:42:41 -07:00
|
|
|
|
2023-11-02 13:50:33 -07:00
|
|
|
# Filter pet states using the "pose" concept we use in the editor.
|
2023-12-05 18:04:54 -08:00
|
|
|
scope :with_pose, -> pose {
|
2023-11-02 13:50:33 -07:00
|
|
|
case pose
|
|
|
|
when "UNCONVERTED"
|
|
|
|
where(unconverted: true)
|
|
|
|
when "HAPPY_MASC"
|
|
|
|
where(mood_id: 1, female: false)
|
|
|
|
when "HAPPY_FEM"
|
|
|
|
where(mood_id: 1, female: true)
|
|
|
|
when "SAD_MASC"
|
|
|
|
where(mood_id: 2, female: false)
|
|
|
|
when "SAD_FEM"
|
|
|
|
where(mood_id: 2, female: true)
|
|
|
|
when "SICK_MASC"
|
|
|
|
where(mood_id: 4, female: false)
|
|
|
|
when "SICK_FEM"
|
|
|
|
where(mood_id: 4, female: true)
|
|
|
|
when "UNKNOWN"
|
|
|
|
where(mood_id: nil).or(where(female: nil))
|
|
|
|
else
|
|
|
|
raise ArgumentError, "unexpected pose value #{pose}"
|
|
|
|
end
|
|
|
|
}
|
|
|
|
|
|
|
|
def pose
|
|
|
|
if unconverted?
|
|
|
|
"UNCONVERTED"
|
|
|
|
elsif mood_id.nil? || female.nil?
|
|
|
|
"UNKNOWN"
|
|
|
|
elsif mood_id == 1 && !female?
|
|
|
|
"HAPPY_MASC"
|
|
|
|
elsif mood_id == 1 && female?
|
|
|
|
"HAPPY_FEM"
|
|
|
|
elsif mood_id == 2 && !female?
|
|
|
|
"SAD_MASC"
|
|
|
|
elsif mood_id == 2 && female?
|
|
|
|
"SAD_FEM"
|
|
|
|
elsif mood_id == 4 && !female?
|
|
|
|
"SICK_MASC"
|
|
|
|
elsif mood_id == 4 && female?
|
|
|
|
"SICK_FEM"
|
|
|
|
else
|
|
|
|
raise "could not identify pose: moodId=#{mood_id}, female=#{female}, " +
|
|
|
|
"unconverted=#{unconverted}"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-09-27 22:14:00 -07:00
|
|
|
# TODO: More and more, wanting to refactor poses…
|
|
|
|
def pose=(pose)
|
|
|
|
case pose
|
|
|
|
when "UNKNOWN"
|
|
|
|
label_pose nil, nil, unconverted: nil, labeled: false
|
|
|
|
when "HAPPY_MASC"
|
|
|
|
label_pose 1, false
|
|
|
|
when "HAPPY_FEM"
|
|
|
|
label_pose 1, true
|
|
|
|
when "SAD_MASC"
|
|
|
|
label_pose 2, false
|
|
|
|
when "SAD_FEM"
|
|
|
|
label_pose 2, true
|
|
|
|
when "SICK_MASC"
|
|
|
|
label_pose 4, false
|
|
|
|
when "SICK_FEM"
|
|
|
|
label_pose 4, true
|
|
|
|
when "UNCONVERTED"
|
|
|
|
label_pose nil, nil, unconverted: true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-11-06 14:31:16 -08:00
|
|
|
def sort_swf_asset_ids!
|
|
|
|
self.swf_asset_ids = swf_asset_ids_array.sort.join(',')
|
|
|
|
end
|
|
|
|
|
|
|
|
def swf_asset_ids
|
|
|
|
self['swf_asset_ids']
|
|
|
|
end
|
|
|
|
|
|
|
|
def swf_asset_ids_array
|
|
|
|
swf_asset_ids.split(',').map(&:to_i)
|
|
|
|
end
|
|
|
|
|
|
|
|
def swf_asset_ids=(ids)
|
|
|
|
self['swf_asset_ids'] = ids
|
|
|
|
end
|
|
|
|
|
|
|
|
def handle_assets!
|
|
|
|
@parent_swf_asset_relationships_to_update.each do |rel|
|
|
|
|
rel.swf_asset.save!
|
|
|
|
rel.save!
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2024-09-26 20:24:31 -07:00
|
|
|
def to_param
|
|
|
|
"#{id}-#{pose.split('_').map(&:capitalize).join('-')}"
|
|
|
|
end
|
|
|
|
|
2024-11-06 14:31:16 -08:00
|
|
|
def self.from_pet_type_and_biology_info(pet_type, info)
|
|
|
|
swf_asset_ids = []
|
|
|
|
info.each do |zone_id, asset_info|
|
|
|
|
if zone_id.present? && asset_info
|
|
|
|
swf_asset_ids << asset_info[:part_id].to_i
|
|
|
|
end
|
|
|
|
end
|
|
|
|
swf_asset_ids_str = swf_asset_ids.sort.join(',')
|
|
|
|
if pet_type.new_record?
|
|
|
|
pet_state = self.new :swf_asset_ids => swf_asset_ids_str
|
|
|
|
else
|
|
|
|
pet_state = self.find_or_initialize_by(
|
|
|
|
pet_type_id: pet_type.id,
|
|
|
|
swf_asset_ids: swf_asset_ids_str
|
|
|
|
)
|
|
|
|
end
|
|
|
|
existing_swf_assets = SwfAsset.biology_assets.includes(:zone).
|
|
|
|
where(remote_id: swf_asset_ids)
|
|
|
|
existing_swf_assets_by_id = {}
|
|
|
|
existing_swf_assets.each do |swf_asset|
|
|
|
|
existing_swf_assets_by_id[swf_asset.remote_id] = swf_asset
|
|
|
|
end
|
|
|
|
existing_relationships_by_swf_asset_id = {}
|
|
|
|
unless pet_state.new_record?
|
|
|
|
pet_state.parent_swf_asset_relationships.each do |relationship|
|
|
|
|
existing_relationships_by_swf_asset_id[relationship.swf_asset_id] = relationship
|
|
|
|
end
|
|
|
|
end
|
|
|
|
pet_state.pet_type = pet_type # save the second case from having to look it up by ID
|
|
|
|
relationships = []
|
|
|
|
info.each do |zone_id, asset_info|
|
|
|
|
if zone_id.present? && asset_info
|
|
|
|
swf_asset_id = asset_info[:part_id].to_i
|
|
|
|
swf_asset = existing_swf_assets_by_id[swf_asset_id]
|
|
|
|
unless swf_asset
|
|
|
|
swf_asset = SwfAsset.new
|
|
|
|
swf_asset.remote_id = swf_asset_id
|
|
|
|
end
|
|
|
|
swf_asset.origin_biology_data = asset_info
|
|
|
|
swf_asset.origin_pet_type = pet_type
|
|
|
|
relationship = existing_relationships_by_swf_asset_id[swf_asset.id]
|
|
|
|
unless relationship
|
|
|
|
relationship ||= ParentSwfAssetRelationship.new
|
|
|
|
relationship.parent = pet_state
|
|
|
|
relationship.swf_asset_id = swf_asset.id
|
|
|
|
end
|
|
|
|
relationship.swf_asset = swf_asset
|
|
|
|
relationships << relationship
|
|
|
|
end
|
|
|
|
end
|
|
|
|
pet_state.parent_swf_asset_relationships_to_update = relationships
|
|
|
|
pet_state
|
2024-11-03 12:16:27 -08:00
|
|
|
end
|
|
|
|
|
2024-09-27 22:14:00 -07:00
|
|
|
private
|
|
|
|
|
|
|
|
# A helper for the `pose=` method.
|
|
|
|
def label_pose(mood_id, female, unconverted: false, labeled: true)
|
|
|
|
self.labeled = labeled
|
|
|
|
self.mood_id = mood_id
|
|
|
|
self.female = female
|
|
|
|
self.unconverted = unconverted
|
|
|
|
end
|
2024-10-07 17:38:53 -07:00
|
|
|
|
|
|
|
def self.last_updated_key
|
2024-10-07 17:56:42 -07:00
|
|
|
PetState.maximum(:updated_at)
|
2024-10-07 17:38:53 -07:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.all_supported_poses
|
|
|
|
Rails.cache.fetch("PetState.all_supported_poses #{last_updated_key}") do
|
|
|
|
{}.tap do |h|
|
|
|
|
includes(:pet_type).find_each do |pet_state|
|
|
|
|
h[pet_state.species_id] ||= {}
|
|
|
|
h[pet_state.species_id][pet_state.color_id] ||= []
|
|
|
|
h[pet_state.species_id][pet_state.color_id] << pet_state.pose
|
|
|
|
end
|
|
|
|
|
|
|
|
h.values.map(&:values).flatten(1).each(&:uniq!).each(&:sort!)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2010-05-20 18:11:08 -07:00
|
|
|
end
|
2011-06-21 17:42:41 -07:00
|
|
|
|