-- avatars - Avatar customization code -- Created by: Johnny Waitt -- Created on: 1/10/08 -- Revision History -- 09/23/2008 Johnny - Updated to handle new palette system. -- LISTENS FOR TRIGGERS: -- enter() -- slide_ui() -- anim_logo() -- count_items() -- turn_page(direction) -- goto_page(page_number) -- set_clothing(slot) -- BROADCASTS TRIGGERS -- enter() -- slide_ui() -- anim_logo() -- count_items() -- turn_page(direction) -- goto_page(page_number) -- set_clothing(slot) DEAD_FRAME = 5 COLOR_DATA_ID = '14879:196' color = {} -- With this code we don't need to adjust the color keys in the color table -- if we change one. BUT! They can come out of pairs in any order. colorNames = {} -- slot names slots = {'body', 'hair', 'tops', 'bottoms'} MALE_DATA_ID = '14879:194' male_clothing = { body = {}, hair = {}, tops = {}, bottoms = {}, } FEMALE_DATA_ID = '14879:195' female_clothing = { body = {}, hair = {}, tops = {}, bottoms = {}, } MALE_SLOT_DATA = { body = '14879:764', hair = '14879:402', tops = '14879:404', bottoms = '14879:406' } FEMALE_SLOT_DATA = { body = '14879:765', hair = '14879:403', tops = '14879:405', bottoms = '14879:407' } MALE_CLOTHING_CHANNELS = '14879:664' FEMALE_CLOTHING_CHANNELS = '14879:665' MALE_CLOTHING_PALETTES = '14879:666' FEMALE_CLOTHING_PALETTES = '14879:667' SKIN_PALETTES = '14879:784' male_body_styles = '14879:764' male_hair_styles = '14879:402' male_tops_styles = '14879:404' male_bottoms_styles = '14879:406' male_data = { slots = {'body', 'hair', 'tops', 'bottoms'}, style_templates = { body = '14879:764', hair = '14879:402', tops = '14879:404', bottoms = '14879:406', }, animations_template = '14879:409', directions = { n = {'body', 'hair', 'bottoms', 'tops'}, ne = {'body', 'hair', 'bottoms', 'tops'}, e = {'body', 'hair', 'bottoms', 'tops'}, se = {'body', 'hair', 'bottoms', 'tops'}, s = {'body', 'hair', 'bottoms', 'tops'}, sw = {'body', 'hair', 'bottoms', 'tops'}, w = {'body', 'hair', 'bottoms', 'tops'}, nw = {'body', 'hair', 'bottoms', 'tops'} }, extension = '.png' } female_body_styles = '14879:765' female_hair_styles = '14879:403' female_tops_styles = '14879:405' female_bottoms_styles = '14879:407' female_data = { slots = {'body', 'hair', 'tops', 'bottoms'}, style_templates = { body = '14879:765', hair = '14879:403', tops = '14879:405', bottoms = '14879:407', }, animations_template = '14879:410', directions = { n = {'body', 'hair', 'bottoms', 'tops'}, ne = {'body', 'hair', 'bottoms', 'tops'}, e = {'body', 'hair', 'bottoms', 'tops'}, se = {'body', 'hair', 'bottoms', 'tops'}, s = {'body', 'hair', 'bottoms', 'tops'}, sw = {'body', 'hair', 'bottoms', 'tops'}, w = {'body', 'hair', 'bottoms', 'tops'}, nw = {'body', 'hair', 'bottoms', 'tops'} }, extension = '.png' } giant_male_data = { slots = {'body', 'hair', 'tops', 'bottoms'}, style_templates = { body = '14879:764', hair = '14879:402', tops = '14879:404', bottoms = '14879:406', }, animations = { wave = '0:48', }, directions = { s = {'body', 'hair', 'bottoms', 'tops'} }, extension = '.png' } giant_female_data = { slots = {'body', 'hair', 'tops', 'bottoms'}, style_templates = { body = '14879:765', hair = '14879:403', tops = '14879:405', bottoms = '14879:407', }, animations = { wave = '0:47', }, directions = { s = {'body', 'hair', 'bottoms', 'tops'} }, extension = '.png' } Define Properties() name_label = 0 selected_male_styles = { body = {style = 'male', palette_id = '14879:785'}, hair = {style = 'ballah', palette_id = '14879:794'}, tops = {style = 'ballah', palette_id = '14879:798'}, bottoms = {style = 'ballah', palette_id = '14879:800'} } selected_female_styles = { body = {style = 'female', palette_id = '14879:785'}, hair = {style = 'goth', palette_id = '14879:804'}, tops = {style = 'goth', palette_id = '14879:808'}, bottoms = {style = 'goth', palette_id = '14879:811'} } -- CLOTHING COUNTS male_body_count = 0 male_hair_count = 0 male_tops_count = 0 male_bottoms_count = 0 female_body_count = 0 female_hair_count = 0 female_tops_count = 0 female_bottoms_count = 0 load_attempted = 0 guest_appearance = 0 returning_user = 0 last_place = '' last_placeX = 0 last_placeY = 0 avatar_selected = 0 PersistProperty('last_place') PersistProperty('last_placeX') PersistProperty('last_placeY') PersistProperty('avatar_selected') -- animated emote support emote_callback = 0 avatar_anim = 'idle' end Define Commands() MakeCommand('reset_avatar', 'Reset avatar choices') end -- SEND THE PLAYER BACK TO THE DRESSING ROOM Command reset_avatar() world = GetWorld() clean_name = string.gsub(world.name, ' ', '') --Debug('Called module') UserGotoUrl(self, 'http://alpha.metaplace.com/AvatarWorld/play#start?place='..clean_name..'&b=1') end -- HANDLES SENDING PLAYER TO CORRECT LOCATION -- AND MODEL/UI SETUPS Trigger enter() --Debug ('Entering.') --Debug ('male_selections: %s', table.tostring(self.selected_male_styles)) --Debug ('female_selections: %s', table.tostring(self.selected_female_styles)) -- load color and selection data --Debug ('color template: %s', COLOR_DATA_ID) local color_data = stylesheet.GetDataRowsById(COLOR_DATA_ID) for k,v in pairs(color_data) do color[v.color] = {v.red, v.green, v.blue} end -- With this code we don't need to adjust the color keys in the color table -- if we change one. BUT! They can come out of pairs in any order. index = 1 for k,v in pairs(color) do colorNames[index] = k index = index+1 end for slot_name, slot_table in pairs(male_clothing) do if slot_name ~= 'body' then search_criteria = {} search_criteria['slot'] = slot_name palettes = stylesheet.SearchDataById(MALE_CLOTHING_PALETTES, search_criteria) else --Debug ('skin color template: %s', SKIN_PALETTES) palettes = stylesheet.GetDataRowsById(SKIN_PALETTES) end --Debug ('slot %s: %s', slot_name, table.tostring(palettes)) --Debug ('male color template: %s', MALE_SLOT_DATA[slot_name]) local slot_styles = stylesheet.GetDataRowsById(MALE_SLOT_DATA[slot_name]) for style_count, style_row in ipairs(slot_styles) do for palette_count, palette in ipairs (palettes) do clothing_row = (((style_count - 1) * #palettes) + palette_count) style_name = style_row['style_name'] male_clothing[slot_name][clothing_row] = {} article = male_clothing[slot_name][clothing_row] article['style'] = style_name article['palette_id'] = palette['id'] end end end for slot_name, slot_table in pairs(female_clothing) do if slot_name ~= 'body' then search_criteria = {} search_criteria['slot'] = slot_name palettes = stylesheet.SearchDataById(FEMALE_CLOTHING_PALETTES, search_criteria) else --Debug ('color template: %s', COLOR_DATA_ID) palettes = stylesheet.GetDataRowsById(SKIN_PALETTES) end -- Debug ('slot %s: %s', slot_name, table.tostring(palettes)) --Debug ('female color template: %s', FEMALE_SLOT_DATA[slot_name]) local slot_styles = stylesheet.GetDataRowsById(FEMALE_SLOT_DATA[slot_name]) for style_count, style_row in ipairs(slot_styles) do for palette_count, palette in ipairs (palettes) do clothing_row = (((style_count - 1) * #palettes) + palette_count) style_name = style_row['style_name'] female_clothing[slot_name][clothing_row] = {} article = female_clothing[slot_name][clothing_row] article['style'] = style_name article['palette_id'] = palette['id'] end end end --Debug ('Character register code.') RegisterCharacter('male', male_data) RegisterCharacter('female', female_data) AttachCharacter(self, 'male', 'idle', 's') LoadCharData(self, 'metaplace1008') end Trigger char_complete() RenderCharacterOutfit(self) end Trigger char_render() PlayCharacterAnim(self, "idle", 's') SendTo(self, 'set_name_tag', 0, self, self.id, '') end Trigger char_failure() SendTo(self, 'random_appearance', 0) self.guest_appearance = 1 self.load_attempted = 1 end -- COUNT THE ARTICLES OF CLOTHING FOR PAGING Trigger count_items() --Debug ('Counting items.') --Debug (table.tostring(male_clothing)) for slot, clothing_list in pairs(male_clothing) do -- Debug ('%s, %s', slot, table.tostring(clothing_list)) self['male_'..slot..'_count'] = #clothing_list end for slot, clothing_list in pairs(female_clothing) do self['female_'..slot..'_count'] = #clothing_list end end Trigger random_appearance() SendTo(self, 'count_items', 0) if math.random(2) == 1 then gender = 'male' clothing = male_clothing selected = self.selected_male_styles else gender = 'female' clothing = female_clothing selected = self.selected_female_styles end AttachCharacter(self, gender, 'idle', 's') for index = 1, #slots do slot = slots[index] choices = clothing [slot] max_styles = self[gender..'_'..slot..'_count'] random_style = math.random(max_styles) choice = choices[random_style] style = choice.style palette_id = choice.palette_id selected[slot]['style'] = style selected[slot]['palette_id'] = palette_id search_criteria = {} search_criteria['slot'] = slot search_criteria['style'] = style SwapSlotStyle(self, slot, style) if gender == 'male' then article_channels = stylesheet.SearchDataById(MALE_CLOTHING_CHANNELS, search_criteria) else article_channels = stylesheet.SearchDataById(FEMALE_CLOTHING_CHANNELS, search_criteria) end if slot == 'body' then parent_id = SKIN_PALETTES else if gender == 'male' then parent_id = MALE_CLOTHING_PALETTES else parent_id = FEMALE_CLOTHING_PALETTES end end palette_colors = stylesheet.GetDataItemById(parent_id, palette_id) DeleteTint(self, slot) layers = {'base', 'detail1', 'detail2'} for i = 1, #layers do --Debug ('Tinting layer %s', layers[i]) layer_name = layers[i] layer_channel = article_channels[1][layer_name..'_channel'] layer_color = palette_colors[layer_name..'_color'] if layer_channel ~= 'none' then TintSpritePartial(self, slot, color[layer_color] [1], color[layer_color] [2], color[layer_color] [3], layer_channel) end end end self.avatar_selected = 1 RenderCharacterOutfit(self) SaveCharData(self, 'metaplace1008') DoCommand(self, 'newyou') end -- Return to an appropriate idle state at the end of an emote animation (or continue to loop) Trigger avatar_emote_callback(emote_time, count, loop) if (emote_time == nil) then emote_time = DEFAULT_EMOTE_TIME end if (count == nil) then count = 0 end if (loop == nil) then loop = 0 end if (count < 1) then if (self.avatar_anim ~= 'die') then if (self.speed ~= 0) then PlayCharacterAnim(self, self.move_mode, self.dir) else PlayCharacterAnim(self, 'idle', self.dir) end else self.spriteFrame = DEAD_FRAME end set_anim(self, 'idle') else self.emote_callback = SendTo(self, 'avatar_emote_callback', emote_time, emote_time, count - 1 + loop, loop) end end -- Perform animations Trigger avatar_emote_wave() set_anim(self, 'walk') play_emote(self, 'wave', 's', 2, 0) end Trigger avatar_emote_dance1() set_anim(self, 'walk') play_emote(self, 'dance01', 's', 1, 1) end Trigger avatar_emote_dance2() set_anim(self, 'walk') play_emote(self, 'dance02', 's', 1, 1) end Trigger avatar_emote_jump() set_anim(self, 'walk') play_emote(self, 'jump', self.dir, 0, 0) end Trigger avatar_emote_die() set_anim(self, 'die') play_emote(self, 'die', self.dir, 0, 0) end Trigger avatar_emote_swing() set_anim(self, 'walk') play_emote(self, 'swing', self.dir, 0, 0) end Trigger avatar_emote_point() set_anim(self, 'walk') play_emote(self, 'point', self.dir, 2, 0) end -- End animation callbacks if pathing goes on Trigger path_begin(x, y) safe_clear_callback(self) end Trigger path_end(x, y) safe_clear_callback(self) end -- Local functions function safe_clear_callback(self) if (self.emote_callback ~= 0) then CancelSend(self, self.emote_callback) self.emote_callback = 0 end end function play_emote(self, emote, dir, count, loop) safe_clear_callback(self) if ( (self.speed ~= 0) and (emote ~= 'jump') ) then set_anim(self, 'walk') return nil end local emote_time = PlayCharacterAnim(self, emote, dir) if (emote_time == nil) then emote_time = DEFAULT_EMOTE_TIME end self.emote_callback = SendTo(self, 'avatar_emote_callback', emote_time, emote_time, count, loop) end function set_anim(self, mode) if (mode == 'die') or (self.avatar_anim == 'die') then self.avatar_anim = mode end end