GDBrowser/misc/manual parsers/parseRobotPlist.js
2022-05-19 22:30:54 -04:00

71 lines
No EOL
2.8 KiB
JavaScript

const plist = require('plist');
const fs = require('fs');
const gdPath = 'C:\\Program Files (x86)\\Steam\\steamapps\\common\\Geometry Dash\\Resources\\'
const animationPlists = ["Robot_AnimDesc.plist", "Spider_AnimDesc.plist"]
const objectDefinitions = "objectDefinitions.plist"
const info = {
"robot": {
names: ["Back leg", "Back connector", "Left foot", "Head", "Front leg", "Front connector", "Front foot"],
tints: { 0: 178, 1: 178, 2: 178 }
},
"spider": {
names: ["Leg 3", "Leg 4", "Connector", "Head", "Leg 1", "Leg 2"],
tints: { 0: 127, 1: 127 }
}
}
function parseSet(str) {
return str.slice(1, -1).split(", ").map(x => cleanFloat(x))
}
function cleanFloat(str) {
return Number(Number(str).toFixed(4))
}
let fullAnimationData = {}
let plistData = animationPlists.map(x => plist.parse(fs.readFileSync(gdPath + x, 'utf8')))
let timings = plist.parse(fs.readFileSync(gdPath + objectDefinitions, 'utf8'))
plistData.forEach(x => {
Object.keys(x.animationContainer).forEach(a => fullAnimationData[a] = x.animationContainer[a])
})
let animations = { "robot": {}, "spider": {} }
for (let animation in fullAnimationData) {
let animationName = animation.split(".")[0].split("_")
let animationForm = animationName.shift()
let animationIndex = Number(animationName.pop()) - 1
animationName = animationName.join("_")
let animationList = Object.values(fullAnimationData[animation])
let formName = animation.split("_")[0].toLowerCase()
let animationData = animationList.map(anim => {
let textureInfo = anim.texture.split("_")
let flips = parseSet(anim.flipped)
return {
part: +textureInfo[2],
pos: parseSet(anim.position),
scale: parseSet(anim.scale),
rotation: cleanFloat(anim.rotation),
flipped: [flips[0] > 0, flips[1] > 0],
z: Number(anim.zValue)
}
})
if (!animations[formName][animationName]) {
let timingDefs = timings[animationForm].animations[animationName] || {}
let animationInfo = { duration: cleanFloat(Number(timingDefs.delay || 0.05) * 1000) }
if (timingDefs.looped == '1' || (!timingDefs.looped && animationName.includes("loop"))) animationInfo.loop = true
if (timingDefs.singleFrame) animationInfo.single = true
animations[formName][animationName] = { info: animationInfo, frames: [] }
}
animations[formName][animationName].frames[animationIndex] = animationData
}
let cleanJSON = JSON.stringify({info, animations}, null, 2)
.replace(/: \[\n\s+([0-9a-z.-]+),\n\s+([0-9a-z.-]+)\n\s+],/g, ": [$1, $2],") // keep sets on one line
.replace(/],\n(\s+)"(.+?)": \[\n/g, '],\n\n$1"$2": [\n') // blank line between animations
.replace(' "animations"', '\n "animations"') // blank line before animation list
fs.writeFileSync('./parsed/robotAnimations.json', cleanJSON); // regex to make it easier to read
console.log("Successfully parsed!")