outfits now know their own visible assets

This commit is contained in:
Emi Matchu 2012-03-06 22:20:40 -05:00
parent 7ec75bb139
commit 22cfff66e9

View file

@ -64,9 +64,11 @@ class Outfit < ActiveRecord::Base
end
self.item_outfit_relationships = new_rels
end
def worn_item_ids
worn_and_unworn_item_ids[:worn]
# Returns the array of SwfAssets representing each layer of the output image,
# ordered from bottom to top.
def layered_assets
visible_assets.sort { |a, b| a.zone.depth <=> b.zone.depth }
end
def self.build_for_user(user, params)
@ -82,5 +84,31 @@ class Outfit < ActiveRecord::Base
outfit.attributes = params
end
end
protected
def visible_assets
biology_assets = pet_state.swf_assets
object_assets = SwfAsset.object_assets.
fitting_body_id(pet_state.pet_type.body_id).for_item_ids(worn_item_ids)
# 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
# bitmask by parsing the binary string (reversing it to get the lower zone
# numbers on the right), then OR them all together to get the mask
# representing all the restricted zones. (Note to self: why not just store
# in this format in the first place?)
restrictors = biology_assets + worn_items
restricted_zones_mask = restrictors.inject(0) do |mask, restrictor|
mask | restrictor.zones_restrict.reverse.to_i(2)
end
# Now, check each asset's zone is not restricted in the bitmask using
# bitwise operations: shift 1 to the zone_id position, then AND it with
# the restricted zones mask. If we get 0, then the bit for that zone ID was
# not turned on, so the zone is not restricted and this asset is visible.
all_assets = biology_assets + object_assets
all_assets.select { |a| (1 << (a.zone_id - 1)) & restricted_zones_mask == 0 }
end
end