-- Avatar Customization in UI -- Author: Jeff the Intern -- Created On: 10/10/2008 -- Revisions -- [J.McNab] 10/10/08 - New Script -- [J.McNab] 10/16/08 - Integration into Avatar Module -- [J.McNab] 10/17/08 - Changes to UI Layout -- Addition of color bounding boxes to palette wells -- PNG 8 Images to replace Photoshop exported PNGs -- Split of Hair from Body -- [J.McNab] 10/20/08 -- Integration into Avatar Module -- [J.McNab] 10/23/08 -- Addition of darkening/button background -- CONSTANTS WINDOW = {WIDTH = 640, HEIGHT = 480} CHARACTER_SPRITE = {WIDTH = 267, HEIGHT = 480} -- UI Layout Assets SWATCH = '8282:474' GENDER_SECTION = '8282:476' SECTION_SMALL = '8282:477' SECTION_LG = '8282:478' HAIR_SECTION = '8282:479' BODY_SECTION = '8282:480' TOPS_SECTION = '8282:481' BOTTOMS_SECTION = '8282:482' PALETTE = '8282:483' PALETTE_BG = '8282:484' -- UI Button Assets ARROW_LEFT = '8282:475' ARROW_RIGHT = '8282:485' OKAY_NORMAL = '8282:468' OKAY_HOVER = '8282:469' RANDOM_NORMAL = '8282:470' RANDOM_HOVER = '8282:471' RESET_NORMAL = '8282:472' RESET_HOVER = '8282:473' CHARACTER_SPRITE_URL = 'http://assets.metaplace.com/mp/avatars_skiv2/' 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' } SLOTS = {'body', 'tops', 'bottoms', 'hair'} MALE_CLOTHING_CHANNELS = '14879:664' FEMALE_CLOTHING_CHANNELS = '14879:665' MALE_CLOTHING_PALETTES = '14879:666' FEMALE_CLOTHING_PALETTES = '14879:667' SKIN_PALETTES = '14879:784' COLOR_PALETTE = { {r = 213, g = 101, b = 103}, {r = 150, g = 80, b = 81}, {r = 244, g = 159, b = 159}, {r = 127, g = 100, b = 100}, {r = 215, g = 140, b = 98}, {r = 156, g = 109, b = 82}, {r = 101, g = 213, b = 118}, {r = 80, g = 150, b = 91}, {r = 159, g = 224, b = 169}, {r = 159, g = 162, b = 224}, {r = 101, g = 106, b = 213}, {r = 80, g = 84, b = 150}, {r = 98, g = 215, b = 158}, {r = 136, g = 98, b = 215}, {r = 82, g = 156, b = 121}, {r = 107, g = 82, b = 156}, {r = 100, g = 127, b = 105}, {r = 100, g = 101, b = 127}, {r = 159, g = 211, b = 224}, {r = 224, g = 171, b = 159}, {r = 242, g = 244, b = 187}, {r = 101, g = 192, b = 213}, {r = 213, g = 122, b = 101}, {r = 242, g = 242, b = 147}, {r = 80, g = 137, b = 150}, {r = 150, g = 94, b = 80}, {r = 198, g = 200, b = 139}, {r = 98, g = 150, b = 215}, {r = 215, g = 163, b = 98}, {r = 206, g = 245, b = 144}, {r = 82, g = 113, b = 156}, {r = 156, g = 124, b = 82}, {r = 178, g = 203, b = 140}, {r = 100, g = 121, b = 127}, {r = 127, g = 106, b = 100}, {r = 177, g = 179, b = 156}, {r = 255, g = 255, b = 255}, {r = 239, g = 239, b = 239}, {r = 184, g = 184, b = 184}, {r = 141, g = 141, b = 141}, {r = 95, g = 95, b = 95}, {r = 40, g = 40, b = 40}} -- Properties Define Properties() IncludeScript('13197:21') -- ui_library customize_window = 0 customize_window_backdrop = 0 current_outfit = { styles = {body = '', tops = '', bottoms = '', hair = ''}, tints = { tops = {}, bottoms = {}, hair = {}, body = {} } } mode = 'body' tints = {tops = {base = {r = 0, g = 0, b = 0}, detail1 = {r = 0, g = 0, b = 0}, detail2 = {r = 0, g = 0, b = 0}}, bottoms = {base = {r = 0, g = 0, b = 0}, detail1 = {r = 0, g = 0, b = 0}, detail2 = {r = 0, g = 0, b = 0}}, hair = {base = {r = 0, g = 0, b = 0}, detail1 = {r = 0, g = 0, b = 0}, detail2 = {r = 0, g = 0, b = 0}}, body = {base = {r = 0, g = 0, b = 0}}} current_tint = 'body_base' end Define Commands() MakeCommand('newyou', 'Customize your avatar') MakeCommand('slot_style', 'Change the slot to by the offset', 'slot:string', 'offset:int') MakeCommand('slot_color', 'Change the slot color', 'slot:string', 'red:int', 'green:int', 'blue:int', 'channel:int') MakeCommand('select_tint', 'Set the current tint to the selected tint', 'tint:string') MakeCommand('avatar_image_map_return', 'x:int', 'y:int', 'red:int', 'green:int', 'blue:int') MakeCommand('apply_outfit', 'Apply the current outfit to the avatar') MakeCommand('random_outfit', 'Give your avatar a random outfit') MakeCommand('set_selection', 'Set the current selection zone', 'selection:string') end -- Commands Command newyou() if(self.customize_window ~= 0) then UiDelete(self.customize_window) self.customize_window = 0 end -- Create the window and attach it to the player local element = UiElement(0, 'avatar_customization', 0, 0, 2000, 2000) local backdrop = UiRect(element, 'backdrop', -1500, -1500, 3000, 3000) UiColor(backdrop, 0, 0, 0, .75) self.customize_window_backdrop = backdrop local blocker = UiImageButton(element, 'blocker', 0, 0, WINDOW.WIDTH, WINDOW.HEIGHT, SWATCH, SWATCH, SWATCH, '') UiColor(blocker, 0, 0, 0, 0) local window = UiWindow(element, 'window', 0, 0, WINDOW.WIDTH, WINDOW.HEIGHT, UI_LIBRARY.WINSTYLE) local close_button = UiImageButton(window, 'close_btn', WINDOW.WIDTH - UI_LIBRARY.CLOSE.WIDTH - 6, 6, UI_LIBRARY.CLOSE.WIDTH, UI_LIBRARY.CLOSE.HEIGHT, UI_LIBRARY.CLOSE.NORMAL, UI_LIBRARY.CLOSE.HOVER, UI_LIBRARY.CLOSE.PRESS, string.format('ui_library_close_window %d', element)) UiAlign(element, -WINDOW.WIDTH/2, -WINDOW.HEIGHT/2, 'center', 'scale_none') UiAttachUser(self, element) self.customize_window = element -- Initialize the player data initialize(self) local background = UiRect(window, 'background', 6, 30, WINDOW.WIDTH - 12, WINDOW.HEIGHT - 37) local gender_selection = UiImage(window, 'genders_select', 25, 35, 330, 45, GENDER_SECTION) local hair_section = UiElement(window, 'hair_section', 25, 95) local hair_section_bg = UiImageButton(hair_section, 'background', 206, 0, 274, 86, SECTION_SMALL, SECTION_SMALL, SECTION_SMALL, 'set_selection hair_base') local hair_selection = UiImageButton(hair_section, 'hair_item', 0, 45, 206, 30, HAIR_SECTION, HAIR_SECTION, HAIR_SECTION, 'set_selection hair_base') local body_section = UiImageButton(hair_section, 'body_item', 0, 10, 206, 30, BODY_SECTION, BODY_SECTION, BODY_SECTION, 'set_selection body_base') local top_section = UiElement(window, 'tops_section', 25, 195) local top_bg = UiImageButton(top_section, 'background', 206, 0, 274, 86, SECTION_SMALL, SECTION_SMALL, SECTION_SMALL, 'set_selection tops_base') local top_sel = UiImageButton(top_section, 'tops_item', 0, 25, 206, 30, TOPS_SECTION, TOPS_SECTION, TOPS_SECTION, 'set_selection tops_base') local bottom_section = UiElement(window, 'bottoms_section', 25, 295) local bottom_bg = UiImageButton(bottom_section, 'background', 206, 0, 274, 137, SECTION_LG, SECTION_LG, SECTION_LG, 'set_selection bottoms_base') local bottom_sel = UiImageButton(bottom_section, 'bottoms_item', 0, 45, 206, 30, BOTTOMS_SECTION, BOTTOMS_SECTION, BOTTOMS_SECTION, 'set_selection bottoms_base') local color_picker = UiImage(window, 'color_picker', 520, 95, 95, 273, PALETTE_BG) local color_choice = UiImageMap(color_picker, 'color_choices', 8, 17, 79, 239, PALETTE, 1, 'avatar_image_map_return') -- Gather the different styles of the character local gender = self.current_outfit.styles.body local top_style = self.current_outfit.styles.tops local bottom_style = self.current_outfit.styles.bottoms local hair_style = self.current_outfit.styles.hair -- Calculate the width and height of the character render based on window size local render_width = (WINDOW.HEIGHT - 30) * (CHARACTER_SPRITE.WIDTH/CHARACTER_SPRITE.HEIGHT) local render_height = (WINDOW.HEIGHT - 30) -- Draw the various pieces of the character local body_img = UiImageRef(window, 'body', 222, 30, render_width, render_height, CHARACTER_SPRITE_URL .. '/' .. gender .. '_large/body/' .. gender .. '/idle_s.png') local bottom_img = UiImageRef(window, 'bottoms', 222, 30, render_width, render_height, CHARACTER_SPRITE_URL .. '/' .. gender .. '_large/bottoms/' .. bottom_style .. '/idle_s.png') local top_img = UiImageRef(window, 'tops', 222, 30, render_width, render_height, CHARACTER_SPRITE_URL .. '/' .. gender .. '_large/tops/' .. top_style .. '/idle_s.png') local hair_img = UiImageRef(window, 'hair', 222, 30, render_width, render_height, CHARACTER_SPRITE_URL .. '/' .. gender .. '_large/hair/' .. hair_style .. '/idle_s.png') local apply = UiImageButton(window, 'apply', WINDOW.WIDTH - 125, WINDOW.HEIGHT - 69, 112, 51, OKAY_NORMAL, OKAY_HOVER, OKAY_NORMAL, 'apply_outfit') local randomize = UiImageButton(window, 'randomize', 20, WINDOW.HEIGHT - 58, 152, 38, RANDOM_NORMAL, RANDOM_HOVER, RANDOM_NORMAL, 'random_outfit') local reset = UiImageButton(window, 'reset', WINDOW.WIDTH - 123, WINDOW.HEIGHT - 104, 108, 39, RESET_NORMAL, RESET_HOVER, RESET_NORMAL, 'newyou') DoCommand(self, 'set_selection', 'body_base') local title = UiMultiLabel(window, 'title', 0, 0, WINDOW.WIDTH - 100, 25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) UiText(title, 'The New You! - Customize your appearance') render_character(self) end Command slot_style(slot, offset) local new_style = '' if(slot ~= 'body') then new_style = slot_style_offset(self, slot, offset) else local gender = self.current_outfit.styles.body if(offset ~= 0) then if(gender == 'male') then new_style = 'female' else new_style = 'male' end else new_style = gender end end if(new_style == nil) then return end if(slot == 'body') then gender(self, new_style) else set_slot(self, slot, new_style) end local slot_info = string.split(self.current_tint, '_') -- Debug('%s == %s', slot, slot_info[1]) if(slot_info[1] ~= slot) then self.current_tint = slot .. '_base' end local channel = get_slot_tint_channels(self, slot, new_style) local channel_count = 0 for _, slot in pairs(channel) do if(slot ~= 'none') then channel_count = channel_count + 1 end end if((slot_info[2] == 'detail1' and channel_count < 2) or (slot_info[2] == 'detail2' and channel_count < 3) ) then self.current_tint = slot .. '_base' end -- Debug(self.current_tint) DoCommand(self, 'set_selection', self.current_tint) render_character(self) end Command slot_color(slot, red, green, blue, channel) local slot_check = 0 for _, slot_opt in pairs(SLOTS) do if(slot == slot_opt) then slot_check = 1 break end end if(slot_check == 0) then return end red = math.max(red, 0) red = math.min(red, 255) green = math.max(green, 0) green = math.min(green, 255) blue = math.max(blue, 0) blue = math.min(blue, 255) if(channel < 1 or channel > 3) then return end local channel_options = {'base', 'detail1', 'detail2'} local current_channel = channel_options[channel] self.tints[slot][current_channel].r = red self.tints[slot][current_channel].g = green self.tints[slot][current_channel].b = blue render_character(self) end Command select_tint(tint) self.current_tint = tint render_character(self) end Command avatar_image_map_return(x, y, red, green, blue) local items = string.split(self.current_tint, '_') local slot = items[1] local channel_name = items[2] local channel = 0 if (channel_name == 'base') then channel = 1 end if(channel_name == 'detail1') then channel = 2 end if(channel_name == 'detail2') then channel = 3 end DoCommand(self, 'slot_color', slot, red, green, blue, channel) end Command random_outfit() DoCommand(self, 'slot_style', 'body', 0) for _, slot in pairs(SLOTS) do if(slot ~= 'body') then for channel = 1, 3, 1 do local index = math.random(1, #COLOR_PALETTE) local red = COLOR_PALETTE[index].r local green = COLOR_PALETTE[index].g local blue = COLOR_PALETTE[index].b DoCommand(self, 'slot_color', slot, red, green, blue, channel) end end end end Command apply_outfit() AttachCharacter(self, self.current_outfit.styles.body, 'idle', 's') SwapSlotStyle(self, 'tops', self.current_outfit.styles.tops) SwapSlotStyle(self, 'bottoms', self.current_outfit.styles.bottoms) SwapSlotStyle(self, 'hair', self.current_outfit.styles.hair) -- Populate tinting information local tints = self.tints for _, slot in pairs(SLOTS) do local channel = get_slot_tint_channels(self, slot, self.current_outfit.styles[slot]) DeleteTint(self, slot) for channel_name, channel_value in pairs(channel) do if(channel_value ~= 'none') then local color = self.tints[slot][channel_name] TintSpritePartial(self, slot, color.r, color.g, color.b, channel_value) end end end RenderCharacterOutfit(self) SaveCharData(self, 'metaplace1008') DoCommand(self, 'ui_library_close_window', self.customize_window) SendTo(self, 'avatar_customization_complete', 0) end Command set_selection(selection) self.current_tint = selection local find_section = string.split(self.current_tint, '_') local current_section = find_section[1] local section = {hair_section = UiFindWindow(self.customize_window, 'hair_section'), tops_section = UiFindWindow(self.customize_window, 'tops_section'), bottoms_section = UiFindWindow(self.customize_window, 'bottoms_section')} for _, window_id in pairs(section) do local bg = UiFindWindow(window_id, 'background') UiDeleteTint(bg) for _, slot in pairs(SLOTS) do local item = UiFindWindow(window_id, slot .. '_item') if(item ~= 0) then UiDeleteTint(item) end end end if(current_section == 'body') then main_section = 'hair' else main_section = current_section end local bg = UiFindWindow(section[main_section .. '_section'], 'background') UiTint(bg, 255, 187, 0) local sel = UiFindWindow(section[main_section .. '_section'], current_section .. '_item') UiTint(sel, 255, 187, 0) draw_selection(self) end -- Triggers Trigger ui_library_window_closed(window_id) if(window_id == self.customize_window) then self.customize_window = 0 self.current_tint = 'body_base' SendTo(self, 'avatar_customization_complete', 0) if(self.customize_window_backdrop ~= 0) then UiDelete(self.customize_window_backdrop) self.customize_window_backdrop = 0 end end end Trigger enter() end -- Functions ------------------------------ --- DISPLAY FUNCTIONS --- ------------------------------ function render_character(self) -- Clear the current character render if there is one local window = UiFindWindow(self.customize_window, 'window') local character_render = UiFindWindow(window, 'character_render') -- Debug(window) if(character_render ~= 0) then UiDelete(character_render) end DoCommand(self, 'set_selection', self.current_tint) -- Create a new character render local character_render = UiElement(window, 'character_render', 222, 30) -- Populate tinting information local tints = self.tints for _, slot in pairs(SLOTS) do local gender = self.current_outfit.styles['body'] local style = self.current_outfit.styles[slot] local tint_slot = UiFindWindow(self.customize_window, slot) local url = CHARACTER_SPRITE_URL .. gender .. '_large/' .. slot .. '/' .. style .. '/idle_s.png' UiSetUrl(tint_slot, url) end for _, slot in pairs(SLOTS) do local tint_slot = UiFindWindow(self.customize_window, slot) UiDeleteTint(tint_slot) local channel = get_slot_tint_channels(self, slot, self.current_outfit.styles[slot]) for channel_name, channel_value in pairs(channel) do if(channel_value ~= 'none') then local color = self.tints[slot][channel_name] UiTintPartial(tint_slot, color.r, color.g, color.b, channel_value) end end end -- Draw Buttons local hair_left = UiImageButton(character_render, 'prev_hair', 25, 80, 31, 48, ARROW_LEFT, ARROW_LEFT, ARROW_LEFT, string.format('slot_style hair -1')) local hair_right = UiImageButton(character_render, 'next_hair', 200, 80, 31, 48, ARROW_RIGHT, ARROW_RIGHT, ARROW_RIGHT, string.format('slot_style hair 1')) local hair_select = UiImageButton(character_render, 'hair_select', 70, 70, 120, 82, SWATCH, SWATCH, SWATCH, 'set_selection hair_base') UiColor(hair_select, 0, 0, 0, 0) local hair_index = UiMultiLabel(character_render, 'hair_index', 20, 130, 50, 30, 40, 40, 40, 0, 0, 0, 0, 0, 0, 1) UiText(hair_index, slot_number(self, 'hair')) local tops_left = UiImageButton(character_render, 'prev_tops', 25, 180, 31, 48, ARROW_LEFT, ARROW_LEFT, ARROW_LEFT, string.format('slot_style tops -1')) local tops_right = UiImageButton(character_render, 'next_tops', 200, 180, 31, 48, ARROW_RIGHT, ARROW_RIGHT, ARROW_RIGHT, string.format('slot_style tops 1')) local tops_select = UiImageButton(character_render, 'tops_select', 70, 170, 120, 82, SWATCH, SWATCH, SWATCH, 'set_selection tops_base') UiColor(tops_select, 0, 0, 0, 0) local tops_index = UiMultiLabel(character_render, 'tops_index', 20, 230, 50, 30, 40, 40, 40, 0, 0, 0, 0, 0, 0, 1) UiText(tops_index, slot_number(self, 'tops')) local bots_left = UiImageButton(character_render, 'prev_bottoms', 25, 310, 31, 48, ARROW_LEFT, ARROW_LEFT, ARROW_LEFT, string.format('slot_style bottoms -1')) local bots_right = UiImageButton(character_render, 'next_bottoms', 200, 310, 31, 48, ARROW_RIGHT, ARROW_RIGHT, ARROW_RIGHT, string.format('slot_style bottoms 1')) local bottoms_select = UiImageButton(character_render, 'bottoms_select', 70, 270, 120, 135, SWATCH, SWATCH, SWATCH, 'set_selection bottoms_base') UiColor(bottoms_select, 0, 0, 0, 0) local bottoms_index = UiMultiLabel(character_render, 'bottoms_index', 20, 380, 50, 30, 40, 40, 40, 0, 0, 0, 0, 0, 0, 1) UiText(bottoms_index, slot_number(self, 'bottoms')) -- Set gender local gender = self.current_outfit.styles.body local x_coords = {male = 57, female = 103} local gender_dot = UiOval(character_render, 'gender_dot', x_coords[gender], 25, 9, 9) local new_gender = '' if(gender == 'male') then new_gender = 'female' else new_gender = 'male' end local gender_btn = UiImageButton(character_render, 'gender_btn', x_coords[new_gender], 25, 12, 12, UI_LIBRARY.ACCEPT.NORMAL, UI_LIBRARY.ACCEPT.HOVER, UI_LIBRARY.ACCEPT.PRESS, string.format('slot_style body 1')) UiColor(gender_btn, 0, 0, 0, 0) draw_selection(self) end --------------------------- --- DATA FUNCTIONS --- --------------------------- -- Initalize sets the UI to the current avatar information function initialize(self) -- Populate the current outfit data local current_outfit = GetCharacterData(self) self.current_outfit.styles = current_outfit.styles self.current_outfit.tints = current_outfit.tints -- Fill in the other channels that may not be found for the slot. for slot, value in pairs(self.current_outfit.tints) do local channels = get_slot_tint_channels(self, slot, self.current_outfit.styles[slot]) local channel_indices = {red = 1, green = 1, blue = 1} -- Find what values exist for index, tint_data in pairs(self.current_outfit.tints[slot]) do if(tint_data.channel == 'red') then channel_indices.red = index end if(tint_data.channel == 'green') then channel_indices.green = index end if(tint_data.channel == 'blue') then channel_indices.blue = index end end -- Set the appropriate tint for each value for channel_name, channel_value in pairs(channels) do if(channel_value ~= 'none') then local channel_index = channel_indices[channel_value] -- Debug('%s: %s', channel_value, channel_index) self.tints[slot][channel_name].r = self.current_outfit.tints[slot][channel_index].r self.tints[slot][channel_name].g = self.current_outfit.tints[slot][channel_index].g self.tints[slot][channel_name].b = self.current_outfit.tints[slot][channel_index].b end end end end -- Get the base, detail1 and detail2 color channel names function get_slot_tint_channels(self, slot, style) -- Table to return with teh data local return_table = {} -- The current gender local gender = self.current_outfit.styles.body -- Load search criteries local search_criteria = {slot = slot, style = style} -- Debug(style) -- Get the data for the appropriate gender if(gender == 'male') then channels = stylesheet.SearchDataById(MALE_CLOTHING_CHANNELS, search_criteria) end if(gender == 'female') then channels = stylesheet.SearchDataById(FEMALE_CLOTHING_CHANNELS, search_criteria) end -- Debug(table.tostring(channels)) -- Populate the return table return_table.base = channels[1].base_channel return_table.detail1 = channels[1].detail1_channel return_table.detail2 = channels[1].detail2_channel return return_table end -- Get the possible styles for the slot function get_slot_options(gender, slot) -- Return if gender is wrong if(gender ~= 'male' and gender ~= 'female') then return end -- Return if slot not found local slot_found = 0 for _, slot_name in pairs(SLOTS) do if(slot_name == slot) then slot_found = 1 end end if(slot_found == 0) then return end -- Get the appropriate styles based on gender if(gender == 'male') then slot_data = MALE_SLOT_DATA end if(gender == 'female') then slot_data = FEMALE_SLOT_DATA end local slot_full_data = stylesheet.GetDataRowsById(slot_data[slot]) -- Populate the slot table and return local slot_names = {} for _, slot_item_data in pairs(slot_full_data) do table.insert(slot_names, slot_item_data.style_name) end return slot_names end -- Return the new style from the list of styles given an offset from the current style function slot_style_offset(self, slot, offset) if(slot ~= 'tops' and slot ~= 'bottoms' and slot ~= 'hair' and slot ~= 'body') then return end local style_list = get_slot_options(self.current_outfit.styles.body, slot) local current_index = 0 for index, style in pairs(style_list) do if (style == self.current_outfit.styles[slot]) then current_index = index break end end local new_index = current_index + offset if(new_index > #style_list) then new_index = new_index - #style_list end if(new_index < 1) then new_index = #style_list + new_index end return style_list[new_index] end -- Set a slot to a specific style function set_slot(self, slot, style) if(slot ~= 'tops' and slot ~= 'bottoms' and slot ~= 'hair') then return end local style_test = 0 local styles = get_slot_options(self.current_outfit.styles.body, slot) for _, name in pairs(styles) do if(style == name) then style_test = 1 end end if(style_test == 0) then return end self.current_outfit.styles[slot] = style end function gender(self, gender) if(gender ~= 'male' and gender ~= 'female') then return end self.current_outfit.styles.body = gender local top_styles = get_slot_options(gender, 'tops') local top_selection = math.random(1, #top_styles) self.current_outfit.styles.tops = top_styles[top_selection] local bottom_styles = get_slot_options(gender, 'bottoms') local bottom_selection = math.random(1, #bottom_styles) self.current_outfit.styles.bottoms = bottom_styles[bottom_selection] local hair_styles = get_slot_options(gender, 'hair') local hair_selection = math.random(1, #hair_styles) self.current_outfit.styles.hair = hair_styles[hair_selection] render_character(self, self.customize_window) end function draw_selection(self) local character_render = UiFindWindow(self.customize_window, 'character_render') if(character_render == 0) then return end local select_arrow = UiFindWindow(character_render, 'select') if(select_arrow ~= 0) then UiDelete(select_arrow) end local string_break = string.split(self.current_tint, '_') local slot = string_break[1] -- Debug(slot) local slot_locations = {body = 112, hair = 112, tops = 212, bottoms = 342} local arrow_locations = {body_base = 78, hair_base = 100, hair_detail1 = 122, tops_base = 178, tops_detail1 = 200, tops_detail2 = 222, bottoms_base = 308, bottoms_detail1 = 330, bottoms_detail2 = 352} local selection = UiElement(character_render, 'select', 247, arrow_locations[self.current_tint] - 1) local y = slot_locations[slot] - arrow_locations[self.current_tint] - 1 local center = 212 - arrow_locations[self.current_tint] - 1 local tint_r = 255 local tint_g = 187 local tint_b = 1 for offset = -1, 1, 1 do local line_1 = UiLine(selection, 'line_1', 12, 11 + offset, 47, 11 + offset) local line_3 = UiLine(selection, 'line_3', 45 + offset, 11, 45 + offset, center) local line_4 = UiLine(selection, 'line_4', 44, center + offset, 54, center + offset) UiColor(line_1, tint_r, tint_g, tint_b, 1) UiColor(line_3, tint_r, tint_g, tint_b, 1) UiColor(line_4, tint_r, tint_g, tint_b, 1) end local select_box = UiRect(selection, 'box', 0, 0, 22, 22) UiColor(select_box, tint_r, tint_g, tint_b, 1) draw_colors(self) end function draw_colors(self) local options = {'body_base', 'hair_base', 'hair_detail1', 'tops_base', 'tops_detail1', 'tops_detail2', 'bottoms_base', 'bottoms_detail1', 'bottoms_detail2'} local window = UiFindWindow(self.customize_window, 'window') local character_render = UiFindWindow(window, 'character_render') for _, slot in pairs(options) do local slot_icon = UiFindWindow(character_render, slot) if(slot_icon ~= 0) then UiDelete(slot_icon) end end -- Slot Colors local slot_count = {hair = 0, tops = 0, bottoms = 0} for slot,_ in pairs(slot_count) do local channel = get_slot_tint_channels(self, slot, self.current_outfit.styles[slot]) for channel_name, channel_value in pairs(channel) do if(channel_value ~= 'none') then slot_count[slot] = slot_count[slot] + 1 end end end local body_color = UiImageButton(character_render, 'body_base', 250, 80, 17, 17, SWATCH, SWATCH, SWATCH, 'select_tint body_base') local hair_color_1 = UiImageButton(character_render, 'hair_base', 250, 102, 17, 17, SWATCH, SWATCH, SWATCH, 'select_tint hair_base') if(slot_count['hair'] > 1) then local hair_color_2 = UiImageButton(character_render, 'hair_detail1', 250, 124, 17, 17, SWATCH, SWATCH, SWATCH, 'select_tint hair_detail1') end local channel_tmp = {'base', 'detail1', 'detail2'} for index, channel_name in pairs(channel_tmp) do if( (channel_name == 'base') or (channel_name == 'detail1' and slot_count['tops'] > 1) or (channel_name == 'detail2' and slot_count['tops'] > 2)) then local slot = UiImageButton(character_render, 'tops_' .. channel_name, 250, 180 + (index - 1) * 22, 17, 17, SWATCH, SWATCH, SWATCH, 'select_tint tops_' .. channel_name) end if( (channel_name == 'base') or (channel_name == 'detail1' and slot_count['bottoms'] > 1) or (channel_name == 'detail2' and slot_count['bottoms'] > 2)) then local slot = UiImageButton(character_render, 'bottoms_' .. channel_name, 250, 310 + (index - 1) * 22, 17, 17, SWATCH, SWATCH, SWATCH, 'select_tint bottoms_' .. channel_name) end end -- Debug(table.tostring(self.tints)) for _, slot in pairs(SLOTS) do for _, channel in pairs(channel_tmp) do local item = UiFindWindow(character_render, slot .. '_' .. channel) if(item ~= 0) then UiTint(item, self.tints[slot][channel].r, self.tints[slot][channel].g, self.tints[slot][channel].b) end end end end function slot_number(self, slot) local slot_options = get_slot_options(self.current_outfit.styles.body, slot) for index, style in pairs(slot_options) do if(style == self.current_outfit.styles[slot]) then return string.format('%d of %d', index, #slot_options) end end return 'ERROR' end