#!/usr/bin/env ruby # frozen_string_literal: true require 'mikunyan' require 'fileutils' begin require 'usamin' require 'usamin/overwrite' rescue LoadError require 'json' end opts = { as_asset: false, outputdir: nil, sprite: false, pretty: false } arg = nil i = 0 while i < ARGV.count if ARGV[i].start_with?('-') case ARGV[i] when '--as-asset', '-a' opts[:as_asset] = true when '--outputdir', '-o' i += 1 opts[:outputdir] = ARGV[i] when '--sprite', '-s' opts[:sprite] = true when '--pretty', '-p' opts[:pretty] = true else warn("Unknown option: #{ARGV[i]}") end else arg ||= ARGV[i] end i += 1 end unless arg warn('Input file is not specified') exit(1) end unless File.file?(arg) warn("File not found: #{arg}") exit(1) end assets = opts[:as_asset] ? [Mikunyan::Asset.file(arg)] : Mikunyan::AssetBundle.file(arg).assets outdir = opts[:outputdir] || File.basename(arg, '.*') FileUtils.mkpath(outdir) assets.each do |asset| if opts[:sprite] json = {} textures = {} asset.each_object do |obj| next unless obj.type == 'Sprite' obj = obj.parse next unless obj texture_id = obj.m_RD&.texture&.m_PathID&.value next unless texture_id unless textures.key?(texture_id) texture_obj = asset.parse_object(texture_id) if texture_obj.is_a?(Mikunyan::CustomTypes::Texture2D) textures[texture_id] = texture_obj.generate_png json[texture_id] = { name: texture_obj.m_Name&.value, width: texture_obj.m_Width&.value, height: texture_obj.m_Height&.value, format: texture_obj.m_TextureFormat&.value, path_id: texture_id, sprites: [] } end end x = obj.m_Rect&.x&.value y = obj.m_Rect&.y&.value width = obj.m_Rect&.width&.value height = obj.m_Rect&.height&.value json[texture_id][:sprites] << { name: obj.object_name, x: x, y: y, width: width, height: height, path_id: obj.path_id } next unless textures[texture_id] && x && y && width && height textures[texture_id].crop( x.round, (textures[texture_id].height - height - y).round, width.round, height.round ).save("#{outdir}/#{obj.object_name}.png") end puts opts[:pretty] ? JSON.pretty_generate(json.values) : JSON.generate(json.values) else json = [] asset.each_object do |obj| next unless obj.type == 'Texture2D' obj = obj.parse next unless obj.is_a?(Mikunyan::CustomTypes::Texture2D) json << { name: obj.object_name, width: obj.width, height: obj.height, format: obj.texture_format, path_id: obj.path_id } obj.generate_png&.save("#{outdir}/#{obj.object_name}.png") end puts opts[:pretty] ? JSON.pretty_generate(json) : JSON.generate(json) end end