Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- A hack to parse player appearance until we get access to inventory slots and
- -- identity blocks.
- function parse_portrait(entity_portrait, item_database)
- local part_patterns = {
- head = "/humanoid/.+head%.png",
- body = "/humanoid/.+body%.png",
- frontarm = "/humanoid/.+/frontarm%.png",
- hair = "/humanoid/.+/hair/",
- emote = "/humanoid/.+emote%.png",
- hat = "/items/.+/head.?%.png",
- chest = "/items/.+/chest.?%.png",
- legs = "/items/.+/pants.?%.png",
- back = "/items/.+/back.?%.png"
- }
- local field_patterns = {
- image = "^(.-)%?",
- image_name = "^.-/([^/]+)%.png",
- directives = "%?.+$",
- folder = "^(.-)/[^/]-png",
- frame = "png:(.-)%?",
- gender = "^.-/([^/]+)body%.png",
- parent_folder = "/([^/]-)/[^/]-png",
- species = "/humanoid/([^/]+)"
- }
- local function extract_field(part, field)
- if not part then return "" end
- return string.match(part.image, field_patterns[field])
- end
- local function extract_part_by_keyword(portrait, keyword)
- if not keyword or keyword == "" then return nil end
- local pattern = "/humanoid/.-" .. keyword .. ".-/.-png"
- for _, entry in pairs(portrait) do
- if string.match(entry.image, pattern) then return entry end
- end
- end
- local function extract_parts(portrait)
- new_table = {}
- for part, pattern in pairs(part_patterns) do
- for _, entry in pairs(portrait) do
- if string.match(entry.image, pattern) then
- new_table[part] = entry
- break
- end
- end
- end
- return new_table
- end
- local function facial_groups(species, gender)
- local species_file = "/species/" .. species .. ".species"
- local species_config = root.assetJson(species_file)
- for _, gender_config in ipairs(species_config.genders) do
- if gender_config.name == gender then
- return gender_config.facialHairGroup, gender_config.facialMaskGroup
- end
- end
- end
- local function facial_data(portrait, species, gender)
- local hair_group, mask_group = facial_groups(species, gender)
- local hair = extract_part_by_keyword(portrait, hair_group)
- local mask = extract_part_by_keyword(portrait, mask_group)
- return {
- hair_group = hair_group,
- mask_group = mask_group,
- hair_type = extract_field(hair, "image_name"),
- mask_type = extract_field(mask, "image_name"),
- hair_directives = extract_field(hair, "directives"),
- mask_directives = extract_field(mask, "directives")
- }
- end
- local function search_paths(folder, slot, paths)
- sb.logInfo("-> Searching paths for %s in %s...", folder, slot)
- local item_name = paths[slot][folder]
- if item_name then sb.logInfo("--> Found " .. item_name) end
- return item_name
- end
- local function search_blueprints(token, slot, blueprints)
- sb.logInfo("-> Searching blueprints for %s in %s...", token, slot)
- local exact_match = nil
- local fuzzy_match = nil
- for item,_ in pairs(blueprints[slot .. 'armor']) do
- if item == token then
- sb.logInfo("-> Found exact match: " .. item)
- exact_match = item
- end
- if not fuzzy_match and (item:match(token) or token:match(item)) then
- sb.logInfo("-> Found fuzzy match: " .. item)
- fuzzy_match = item
- end
- end
- return exact_match, fuzzy_match
- end
- local function item_from_path(folder, token, slot)
- local path = folder .. "/" .. token .. "." .. slot
- sb.logInfo("-> Trying to load item from %s...", path)
- local success, item = pcall(function()
- local item_name = root.assetJson(path).itemName
- if root.itemType(item_name) == slot .. "armor" then return item_name end
- return nil
- end)
- if success and item then
- sb.logInfo("--> Found %s in %s", item, path)
- return item
- end
- return nil
- end
- local function recognize_armor(part, slot, database)
- if not part then return { name = "perfectlygenericitem" } end
- sb.logInfo("Trying to determine %s item...", slot)
- local directives = extract_field(part, "directives")
- local folder = extract_field(part, "folder")
- local token = string.gsub(extract_field(part, "parent_folder"), "-", "")
- local item_name = search_paths(folder, slot, database.paths)
- if not item_name then
- local exact_match, fuzzy_match =
- search_blueprints(token, slot, database.blueprints)
- item_name =
- exact_match
- or item_from_path(folder, token, slot)
- or fuzzy_match
- or "perfectlygenericitem"
- end
- sb.logInfo("Settling for " .. item_name)
- params = { directives = extract_field(part, "directives") }
- return { name = item_name, parameters = params }
- end
- local function identity_and_costume(portrait, database)
- local parts = extract_parts(portrait)
- local species = extract_field(parts.body, "species")
- local gender = extract_field(parts.body, "gender")
- local name = "Clone"
- local face = facial_data(portrait, species, gender)
- local hair_directives = extract_field(parts.hair, "directives")
- hair_directives = string.gsub(hair_directives, "%?addmask.+$", "")
- local data = {
- identity = {
- bodyDirectives = extract_field(parts.body, "directives"),
- emoteDirectives = extract_field(parts.emote, "directives"),
- facialHairDirectives = face.hair_directives,
- facialHairGroup = face.hair_group,
- facialHairType = face.hair_type,
- facialMaskDirectives = face.mask_directives,
- facialMaskGroup = face.mask_group,
- facialMaskType = face.mask_type,
- gender = gender,
- hairDirectives = hair_directives,
- hairGroup = "hair",
- hairType = extract_field(parts.hair, "image_name"),
- name = name,
- personalityArmIdle = extract_field(parts.frontarm, "frame"),
- personalityArmOffset = parts.frontarm.position,
- personalityHeadOffset = parts.head.position,
- personalityIdle = extract_field(parts.body, "frame"),
- species = species
- },
- costume = {
- head = recognize_armor(parts.hat, "head", database),
- chest = recognize_armor(parts.chest, "chest", database),
- legs = recognize_armor(parts.legs, "legs", database),
- back = recognize_armor(parts.back, "back", database),
- }
- }
- return data
- end
- return identity_and_costume(entity_portrait, item_database)
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement