move zones to database

This commit is contained in:
Emi Matchu 2013-01-21 19:34:39 -06:00
parent ce4e2fd53c
commit 26ac3782ec
14 changed files with 157 additions and 80 deletions

View file

@ -1,7 +1,5 @@
class ItemZoneSetsController < ApplicationController class ItemZoneSetsController < ApplicationController
caches_page :index
def index def index
render :json => Zone::ItemZoneSets.keys.sort.as_json render :json => Zone.all_plain_labels
end end
end end

View file

@ -45,6 +45,15 @@ class ItemsController < ApplicationController
respond_to do |format| respond_to do |format|
format.html do format.html do
unless localized_fragment_exist?("items/#{@item.id} info")
@occupied_zones = @item.occupied_zones(
:scope => Zone.includes_translations.alphabetical
)
@restricted_zones = @item.restricted_zones(
:scope => Zone.includes_translations.alphabetical
)
end
unless localized_fragment_exist?("items/#{@item.id} contributors") unless localized_fragment_exist?("items/#{@item.id} contributors")
@contributors_with_counts = @item.contributors_with_counts @contributors_with_counts = @item.contributors_with_counts
end end

View file

@ -2,7 +2,7 @@ class SwfAssetsController < ApplicationController
def index def index
if params[:item_id] if params[:item_id]
item = Item.find(params[:item_id]) item = Item.find(params[:item_id])
@swf_assets = item.swf_assets @swf_assets = item.swf_assets.includes_depth
if params[:body_id] if params[:body_id]
@swf_assets = @swf_assets.fitting_body_id(params[:body_id]) @swf_assets = @swf_assets.fitting_body_id(params[:body_id])
else else
@ -16,29 +16,31 @@ class SwfAssetsController < ApplicationController
elsif params[:pet_type_id] && params[:item_ids] elsif params[:pet_type_id] && params[:item_ids]
pet_type = PetType.find(params[:pet_type_id], :select => [:body_id, :species_id]) pet_type = PetType.find(params[:pet_type_id], :select => [:body_id, :species_id])
@swf_assets = SwfAsset.object_assets. @swf_assets = SwfAsset.object_assets.includes_depth.
fitting_body_id(pet_type.body_id). fitting_body_id(pet_type.body_id).
for_item_ids(params[:item_ids]). for_item_ids(params[:item_ids]).
with_parent_ids with_parent_ids
json = @swf_assets.map { |a| a.as_json(:parent_id => a.parent_id.to_i, :for => 'wardrobe') } json = @swf_assets.map { |a| a.as_json(:parent_id => a.parent_id.to_i, :for => 'wardrobe') }
elsif params[:pet_state_id] elsif params[:pet_state_id]
@swf_assets = PetState.find(params[:pet_state_id]).swf_assets.all @swf_assets = PetState.find(params[:pet_state_id]).swf_assets.
includes_depth.all
pet_state_id = params[:pet_state_id].to_i pet_state_id = params[:pet_state_id].to_i
json = @swf_assets.map { |a| a.as_json(:parent_id => pet_state_id, :for => 'wardrobe') } json = @swf_assets.map { |a| a.as_json(:parent_id => pet_state_id, :for => 'wardrobe') }
elsif params[:pet_type_id] elsif params[:pet_type_id]
@swf_assets = PetType.find(params[:pet_type_id]).pet_states.emotion_order.first.swf_assets @swf_assets = PetType.find(params[:pet_type_id]).pet_states.emotion_order
.first.swf_assets.includes_depth
elsif params[:ids] elsif params[:ids]
@swf_assets = [] @swf_assets = []
if params[:ids][:biology] if params[:ids][:biology]
@swf_assets += SwfAsset.biology_assets.where(:remote_id => params[:ids][:biology]).all @swf_assets += SwfAsset.includes_depth.biology_assets.where(:remote_id => params[:ids][:biology]).all
end end
if params[:ids][:object] if params[:ids][:object]
@swf_assets += SwfAsset.object_assets.where(:remote_id => params[:ids][:object]).all @swf_assets += SwfAsset.includes_depth.object_assets.where(:remote_id => params[:ids][:object]).all
end end
elsif params[:body_id] && params[:item_ids] elsif params[:body_id] && params[:item_ids]
# DEPRECATED in favor of pet_type_id and item_ids # DEPRECATED in favor of pet_type_id and item_ids
swf_assets = SwfAsset.arel_table swf_assets = SwfAsset.arel_table
@swf_assets = SwfAsset.object_assets. @swf_assets = SwfAsset.includes_depth.object_assets.
select('swf_assets.*, parents_swf_assets.parent_id'). select('swf_assets.*, parents_swf_assets.parent_id').
fitting_body_id(params[:body_id]). fitting_body_id(params[:body_id]).
for_item_ids(params[:item_ids]) for_item_ids(params[:item_ids])

View file

@ -73,7 +73,7 @@ module ItemsHelper
end end
def list_zones(zones, method=:label) def list_zones(zones, method=:label)
zones.sort { |x,y| x.label <=> y.label }.map(&method).join(', ') zones.map(&method).join(', ')
end end
def nc_icon def nc_icon
@ -125,7 +125,8 @@ module ItemsHelper
def build_on_pet_types(species, special_color=nil, &block) def build_on_pet_types(species, special_color=nil, &block)
species_ids = species.map(&:id) species_ids = species.map(&:id)
pet_types = special_color ? pet_types = special_color ?
PetType.where(:color_id => special_color.id, :species_id => species_ids).order(:species_id) : PetType.where(:color_id => special_color.id, :species_id => species_ids).
order(:species_id).includes_child_translations :
PetType.random_basic_per_species(species.map(&:id)) PetType.random_basic_per_species(species.map(&:id))
pet_types.map(&block).join.html_safe pet_types.map(&block).join.html_safe
end end

View file

@ -110,25 +110,27 @@ class Item < ActiveRecord::Base
@wanted @wanted
end end
def restricted_zones def restricted_zones(options={})
unless @restricted_zones options[:scope] ||= Zone.scoped
@restricted_zones = [] options[:scope].find(restricted_zone_ids)
zones_restrict.split(//).each_with_index do |switch, id|
@restricted_zones << Zone.find(id.to_i + 1) if switch == '1'
end
end
@restricted_zones
end end
def restricted_zone_ids def restricted_zone_ids
restricted_zones.map(&:id) unless @restricted_zone_ids
@restricted_zone_ids = []
zones_restrict.split(//).each_with_index do |switch, id|
@restricted_zone_ids << (id.to_i + 1) if switch == '1'
end
end
@restricted_zone_ids
end end
def occupied_zone_ids def occupied_zone_ids
occupied_zones.map(&:id) occupied_zones.map(&:id)
end end
def occupied_zones def occupied_zones(options={})
options[:scope] ||= Zone.scoped
all_body_ids = [] all_body_ids = []
zone_body_ids = {} zone_body_ids = {}
selected_assets = swf_assets.select('body_id, zone_id').each do |swf_asset| selected_assets = swf_assets.select('body_id, zone_id').each do |swf_asset|
@ -137,12 +139,11 @@ class Item < ActiveRecord::Base
body_ids << swf_asset.body_id unless body_ids.include?(swf_asset.body_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) all_body_ids << swf_asset.body_id unless all_body_ids.include?(swf_asset.body_id)
end end
zones = [] 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 total_body_ids = all_body_ids.size
zone_body_ids.each do |zone_id, body_ids| zone_body_ids.each do |zone_id, body_ids|
zone = Zone.find(zone_id) zones_by_id[zone_id].sometimes = true if body_ids.size < total_body_ids
zone.sometimes = true if body_ids.size < total_body_ids
zones << zone
end end
zones zones
end end

View file

@ -90,8 +90,8 @@ class Item
end end
species.id species.id
}, },
:zone => lambda { |name| :zone => lambda { |label|
zone_set = Zone.find_set(name) zone_set = Zone.with_plain_label(label)
unless zone_set unless zone_set
Item::Search.error 'not_found.zone', :zone_name => name Item::Search.error 'not_found.zone', :zone_name => name
end end

View file

@ -84,7 +84,7 @@ class Outfit < ActiveRecord::Base
# ordered from bottom to top. Careful: this method is memoized, so if the # ordered from bottom to top. Careful: this method is memoized, so if the
# image layers change after its first call we'll get bad results. # image layers change after its first call we'll get bad results.
def image_layers def image_layers
@image_layers ||= visible_assets_with_images.sort { |a, b| a.zone.depth <=> b.zone.depth } @image_layers ||= visible_assets_with_images.sort { |a, b| a.depth <=> b.depth }
end end
# Creates and writes the thumbnail images for this outfit iff the new image # Creates and writes the thumbnail images for this outfit iff the new image
@ -177,9 +177,10 @@ class Outfit < ActiveRecord::Base
end end
def visible_assets def visible_assets
biology_assets = pet_state.swf_assets biology_assets = pet_state.swf_assets.includes(:zone)
object_assets = SwfAsset.object_assets. object_assets = SwfAsset.object_assets.
fitting_body_id(pet_state.pet_type.body_id).for_item_ids(worn_item_ids) fitting_body_id(pet_state.pet_type.body_id).for_item_ids(worn_item_ids).
includes(:zone)
# Now for fun with bitmasks! Rather than building a bunch of integer arrays # Now for fun with bitmasks! Rather than building a bunch of integer arrays
# here, we instead go low-level and use bit-level operations. Build the # here, we instead go low-level and use bit-level operations. Build the

View file

@ -19,8 +19,12 @@ class PetType < ActiveRecord::Base
scope :nonstandard_colors, lambda { where(:color_id => Color.nonstandard) } scope :nonstandard_colors, lambda { where(:color_id => Color.nonstandard) }
scope :includes_child_translations,
lambda { includes({:color => :translations, :species => :translations}) }
def self.standard_pet_types_by_species_id def self.standard_pet_types_by_species_id
PetType.where(:color_id => Color.basic).group_by(&:species_id) PetType.where(:color_id => Color.basic).includes_child_translations.
group_by(&:species_id)
end end
def self.standard_body_ids def self.standard_body_ids
@ -33,8 +37,9 @@ class PetType < ActiveRecord::Base
def self.random_basic_per_species(species_ids) def self.random_basic_per_species(species_ids)
random_pet_types = [] random_pet_types = []
standards = self.standard_pet_types_by_species_id
species_ids.each do |species_id| species_ids.each do |species_id|
pet_types = standard_pet_types_by_species_id[species_id] pet_types = standards[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

@ -23,6 +23,10 @@ class SwfAsset < ActiveRecord::Base
include SwfConverter include SwfConverter
converts_swfs :size => IMAGE_SIZES[:large], :output_sizes => IMAGE_SIZES.values converts_swfs :size => IMAGE_SIZES[:large], :output_sizes => IMAGE_SIZES.values
belongs_to :zone
scope :includes_depth, lambda { includes(:zone) }
def local_swf_path def local_swf_path
LOCAL_ASSET_DIR.join(local_path_within_outfit_swfs) LOCAL_ASSET_DIR.join(local_path_within_outfit_swfs)
@ -200,10 +204,6 @@ class SwfAsset < ActiveRecord::Base
self.zone.type_id < 3 || (@item && @item.body_specific?) self.zone.type_id < 3 || (@item && @item.body_specific?)
end end
def zone
Zone.find(zone_id)
end
def origin_pet_type=(pet_type) def origin_pet_type=(pet_type)
self.body_id = pet_type.body_id self.body_id = pet_type.body_id
end end

View file

@ -1,49 +1,32 @@
class Zone < StaticResource class Zone < ActiveRecord::Base
ATTRIBUTE_NAMES = ['id', 'label', 'depth', 'type_id'] translates :label, :plain_label
ZONE_SETS = {}
attr_reader *ATTRIBUTE_NAMES
# When selecting zones that an asset occupies, we allow the zone to set # 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. # whether or not the zone is "sometimes" occupied. This is false by default.
attr_writer :sometimes attr_writer :sometimes
def initialize(attributes) scope :alphabetical, lambda {
ATTRIBUTE_NAMES.each do |name| includes_translations.order(Zone::Translation.arel_table[:label])
instance_variable_set "@#{name}", attributes[name] }
end scope :includes_translations, lambda { includes(:translations) }
end scope :with_plain_label, lambda { |label|
t = Zone::Translation.arel_table
includes(:translations).where(t[:plain_label].eq(Zone.plainify_label(label)))
}
def uncertain_label def uncertain_label
@sometimes ? "#{label} sometimes" : label @sometimes ? "#{label} sometimes" : label
end end
def self.find_set(name) def self.all_plain_labels
ZONE_SETS[plain(name)] Zone.select([:id]).includes(:translations).all.map(&:plain_label).uniq.sort
end end
def self.plain(name) def self.plainify_label(label)
name.delete('\- /').downcase plain_label = label.delete('\- /').downcase
end if plain_label.end_with?('item')
plain_label = plain_label[0..-5]
n = 0
@objects = YAML.load_file(Rails.root.join('config', 'zones.yml')).map do |a|
a['id'] = (n += 1)
obj = new(a)
plain_name = plain(obj.label)
ZONE_SETS[plain_name] ||= []
ZONE_SETS[plain_name] << obj
obj
end
n = nil
# Add aliases to keys like "lowerforegrounditem" to "lowerforeground"
# ...unless there's already such a key, like "backgrounditem" to "background",
# in which case we don't, because that'd be silly.
ZONE_SETS.keys.each do |name|
if name.end_with?('item')
stripped_name = name[0..-5]
ZONE_SETS[stripped_name] ||= ZONE_SETS[name]
end end
plain_label
end end
end end

View file

@ -53,13 +53,13 @@
#item-zones #item-zones
%p %p
%strong #{t '.zones.occupied_header'}: %strong #{t '.zones.occupied_header'}:
= list_zones @item.occupied_zones, :uncertain_label = list_zones @occupied_zones, :uncertain_label
%p %p
%strong #{t '.zones.restricted_header'}: %strong #{t '.zones.restricted_header'}:
- if @item.restricted_zones.empty? - if @restricted_zones.empty?
= t '.zones.none' = t '.zones.none'
- else - else
= list_zones @item.restricted_zones = list_zones @restricted_zones
#trade-hangers #trade-hangers
- [true, false].each do |owned| - [true, false].each do |owned|

View file

@ -0,0 +1,14 @@
class CreateZones < ActiveRecord::Migration
def self.up
create_table :zones do |t|
t.integer :depth
t.integer :type_id
end
Zone.create_translation_table! :label => :string, :plain_label => :string
end
def self.down
drop_table :zones
Zone.drop_translation_table!
end
end

View file

@ -11,7 +11,7 @@
# #
# It's strongly recommended to check this file into your version control system. # It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20130121205607) do ActiveRecord::Schema.define(:version => 20130121221226) do
create_table "auth_servers", :force => true do |t| create_table "auth_servers", :force => true do |t|
t.string "short_name", :limit => 10, :null => false t.string "short_name", :limit => 10, :null => false
@ -286,11 +286,21 @@ ActiveRecord::Schema.define(:version => 20130121205607) do
t.integer "wanted_closet_hangers_visibility", :default => 1, :null => false t.integer "wanted_closet_hangers_visibility", :default => 1, :null => false
end end
create_table "zone_translations", :force => true do |t|
t.integer "zone_id"
t.string "locale"
t.string "label"
t.string "plain_label"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "zone_translations", ["locale"], :name => "index_zone_translations_on_locale"
add_index "zone_translations", ["zone_id"], :name => "index_zone_translations_on_zone_id"
create_table "zones", :force => true do |t| create_table "zones", :force => true do |t|
t.integer "depth", :limit => 1, :null => false t.integer "depth"
t.integer "type_id", :limit => 1, :null => false t.integer "type_id"
t.string "type", :limit => 40, :null => false
t.string "label", :limit => 40, :null => false
end end
end end

View file

@ -153,3 +153,56 @@ Color.create(:id => 97, :name => "elderlyboy", :basic => false, :standard => tru
Color.create(:id => 98, :name => "elderlygirl", :basic => false, :standard => true) Color.create(:id => 98, :name => "elderlygirl", :basic => false, :standard => true)
Color.create(:id => 99, :name => "stealthy", :basic => false, :standard => true) Color.create(:id => 99, :name => "stealthy", :basic => false, :standard => true)
Color.create(:id => 100, :name => "dimensional", :basic => false, :standard => true) Color.create(:id => 100, :name => "dimensional", :basic => false, :standard => true)
Zone.create(:id => 1, :label => "Music", :plain_label => "music", :depth => 1, :type_id => 4)
Zone.create(:id => 2, :label => "Sound Effects", :plain_label => "soundeffects", :depth => 2, :type_id => 4)
Zone.create(:id => 3, :label => "Background", :plain_label => "background", :depth => 3, :type_id => 3)
Zone.create(:id => 4, :label => "Biology Effects", :plain_label => "biologyeffects", :depth => 6, :type_id => 1)
Zone.create(:id => 5, :label => "Hind Biology", :plain_label => "hindbiology", :depth => 7, :type_id => 1)
Zone.create(:id => 6, :label => "Markings", :plain_label => "markings", :depth => 8, :type_id => 2)
Zone.create(:id => 7, :label => "Hind Disease", :plain_label => "hinddisease", :depth => 9, :type_id => 1)
Zone.create(:id => 8, :label => "Hind Cover", :plain_label => "hindcover", :depth => 10, :type_id => 2)
Zone.create(:id => 9, :label => "Hind Transient Biology", :plain_label => "hindtransientbiology", :depth => 11, :type_id => 1)
Zone.create(:id => 10, :label => "Hind Drippings", :plain_label => "hinddrippings", :depth => 12, :type_id => 1)
Zone.create(:id => 11, :label => "Backpack", :plain_label => "backpack", :depth => 13, :type_id => 2)
Zone.create(:id => 12, :label => "Wings Transient Biology", :plain_label => "wingstransientbiology", :depth => 14, :type_id => 1)
Zone.create(:id => 13, :label => "Wings", :plain_label => "wings", :depth => 15, :type_id => 2)
Zone.create(:id => 14, :label => "Hair Back", :plain_label => "hairback", :depth => 17, :type_id => 1)
Zone.create(:id => 15, :label => "Body", :plain_label => "body", :depth => 18, :type_id => 1)
Zone.create(:id => 16, :label => "Markings", :plain_label => "markings", :depth => 19, :type_id => 2)
Zone.create(:id => 17, :label => "Body Disease", :plain_label => "bodydisease", :depth => 20, :type_id => 1)
Zone.create(:id => 18, :label => "Feet Transient Biology", :plain_label => "feettransientbiology", :depth => 21, :type_id => 1)
Zone.create(:id => 19, :label => "Shoes", :plain_label => "shoes", :depth => 22, :type_id => 2)
Zone.create(:id => 20, :label => "Lower-body Transient Biology", :plain_label => "lowerbodytransientbiology", :depth => 23, :type_id => 1)
Zone.create(:id => 21, :label => "Trousers", :plain_label => "trousers", :depth => 24, :type_id => 2)
Zone.create(:id => 22, :label => "Upper-body Transient Biology", :plain_label => "upperbodytransientbiology", :depth => 25, :type_id => 1)
Zone.create(:id => 23, :label => "Shirt/Dress", :plain_label => "shirtdress", :depth => 26, :type_id => 2)
Zone.create(:id => 24, :label => "Necklace", :plain_label => "necklace", :depth => 28, :type_id => 2)
Zone.create(:id => 25, :label => "Gloves", :plain_label => "gloves", :depth => 29, :type_id => 2)
Zone.create(:id => 26, :label => "Jacket", :plain_label => "jacket", :depth => 30, :type_id => 2)
Zone.create(:id => 27, :label => "Collar", :plain_label => "collar", :depth => 31, :type_id => 2)
Zone.create(:id => 28, :label => "Body Drippings", :plain_label => "bodydrippings", :depth => 32, :type_id => 1)
Zone.create(:id => 29, :label => "Ruff", :plain_label => "ruff", :depth => 33, :type_id => 1)
Zone.create(:id => 30, :label => "Head", :plain_label => "head", :depth => 34, :type_id => 1)
Zone.create(:id => 31, :label => "Markings", :plain_label => "markings", :depth => 35, :type_id => 2)
Zone.create(:id => 32, :label => "Head Disease", :plain_label => "headdisease", :depth => 36, :type_id => 1)
Zone.create(:id => 33, :label => "Eyes", :plain_label => "eyes", :depth => 37, :type_id => 1)
Zone.create(:id => 34, :label => "Mouth", :plain_label => "mouth", :depth => 38, :type_id => 1)
Zone.create(:id => 35, :label => "Glasses", :plain_label => "glasses", :depth => 41, :type_id => 2)
Zone.create(:id => 36, :label => "Earrings", :plain_label => "earrings", :depth => 39, :type_id => 2)
Zone.create(:id => 37, :label => "Hair Front", :plain_label => "hairfront", :depth => 40, :type_id => 1)
Zone.create(:id => 38, :label => "Head Transient Biology", :plain_label => "headtransientbiology", :depth => 42, :type_id => 1)
Zone.create(:id => 39, :label => "Head Drippings", :plain_label => "headdrippings", :depth => 43, :type_id => 1)
Zone.create(:id => 40, :label => "Hat", :plain_label => "hat", :depth => 44, :type_id => 2)
Zone.create(:id => 41, :label => "Earrings", :plain_label => "earrings", :depth => 45, :type_id => 2)
Zone.create(:id => 42, :label => "Right-hand Item", :plain_label => "righthand", :depth => 46, :type_id => 2)
Zone.create(:id => 43, :label => "Left-hand Item", :plain_label => "lefthand", :depth => 47, :type_id => 2)
Zone.create(:id => 44, :label => "Higher Foreground Item", :plain_label => "higherforeground", :depth => 49, :type_id => 3)
Zone.create(:id => 45, :label => "Lower Foreground Item", :plain_label => "lowerforeground", :depth => 50, :type_id => 3)
Zone.create(:id => 46, :label => "Static", :plain_label => "static", :depth => 48, :type_id => 3)
Zone.create(:id => 47, :label => "Thought Bubble", :plain_label => "thoughtbubble", :depth => 51, :type_id => 3)
Zone.create(:id => 48, :label => "Background Item", :plain_label => "background", :depth => 4, :type_id => 3)
Zone.create(:id => 49, :label => "Right-hand Item", :plain_label => "righthand", :depth => 5, :type_id => 2)
Zone.create(:id => 50, :label => "Hat", :plain_label => "hat", :depth => 16, :type_id => 2)
Zone.create(:id => 51, :label => "Belt", :plain_label => "belt", :depth => 27, :type_id => 2)
Zone.create(:id => 52, :label => "Foreground", :plain_label => "foreground", :depth => 52, :type_id => 3)