Skip to content
This repository has been archived by the owner on Oct 21, 2022. It is now read-only.

Commit

Permalink
why did i make this
Browse files Browse the repository at this point in the history
  • Loading branch information
GDColon committed Jul 7, 2020
0 parents commit 21b00c7
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 0 deletions.
31 changes: 31 additions & 0 deletions assets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{

"gdPath": "C:/Program Files (x86)/Steam/steamapps/common/Geometry Dash/Resources",

"sheets": {
"FireSheet_01-uhd": 40,
"GauntletSheet-uhd": 50,
"GJ_GameSheet-uhd": 30,
"GJ_GameSheet02-uhd": 40,
"GJ_GameSheet03-uhd": 30,
"GJ_GameSheet04-uhd": 25,
"GJ_GameSheetGlow-uhd": 30,
"GJ_LaunchSheet-uhd": 150,
"GJ_ShopSheet-uhd": 60,
"SecretSheet-uhd": 150

"sprites": [
"dialogIcon_#",
"game_bg_#_001",
"GJ_button_#",
"GJ_square#",
"groundSquare_#_2_001||*",
"tutorial_#",
"groundSquare_#_001||g1",
"groundSquare_#_001||g2"
],

"forms": [
"player_ball", "player", "ship", "bird", "dart", "robot", "spider"
]
}
17 changes: 17 additions & 0 deletions readme.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
BACK UP YOUR GD RESOURCES FOLDER BEFORE RUNNING THIS PROGRAM!
C:\Program Files (x86)\Steam\steamapps\common\Geometry Dash\Resources
(just make a copy of the folder or something)

===

In a nutshell, this program randomizes all the GD textures.
To keep things tidy, textures will only be replaced with similar-sized ones.
All icons are also randomized.
It's also compatible with texture packs!

===

HOW TO USE:
- Run the "shuffle.exe" file.
- When it finishes, drag the files in the "pack" folder into your GD resources folder.
- When asked to overwrite files, click yes.
126 changes: 126 additions & 0 deletions shuffle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
const fs = require('fs')
const plist = require('plist');
const assets = require('./assets.json')

Array.prototype.shuffle = function() {
let length = this.length; let unshuffled = this; let shuffled = [];
while (shuffled.length !== length) {
let index = Math.floor(Math.random() * unshuffled.length);
shuffled.push(unshuffled[index]);
unshuffled = unshuffled.filter((x, y) => y !== (index))}
return shuffled;
}

function plistToJson(file) {
let data = plist.parse(file)
for (let key in data.frames) {
let fileData = data.frames[key];
for (let innerKey in fileData) {
if (typeof fileData[innerKey] === 'string') fileData[innerKey] = JSON.parse(fileData[innerKey].replace(/{/g, '[').replace(/}/g, ']'));
}}
return data.frames
}

if (!fs.existsSync('./pack')) fs.mkdirSync('./pack');

function glow(name) { return name.replace("_001.png", "_glow_001.png") }
function undupe (arr) { return arr.filter((x, y) => arr.indexOf(x) == y) }
//function spriteRegex(name) { return new RegExp(`(<key>${name.replace(".", "\\.")}<\/key>\\s*)(<dict>(.|\\n)+?<\\/dict>)`) }
let iconRegex = /^.+?_(\d+?)_.+/

let forms = assets.forms
let sheetList = Object.keys(assets.sheets)
let glowName = sheetList.filter(x => x.startsWith('GJ_GameSheetGlow'))
let glowPlist = fs.readFileSync(`${assets.gdPath}/${glowName[0]}.plist`, 'utf8')
let sheetNames = sheetList.filter(x => !glowName.includes(x))
let resources = fs.readdirSync(assets.gdPath)

let plists = []
let sheets = []
let glowBackups = []
let glowSheet = plistToJson(glowPlist)

resources.forEach(x => {
if (x.startsWith('PlayerExplosion_') && x.endsWith('-uhd.plist')) sheetNames.push(x.slice(0, -6))
})

sheetNames.forEach(x => {
let file = fs.readFileSync(`${assets.gdPath}/${x}.plist`, 'utf8')
plists.push(file)
sheets.push(plistToJson(file))
})

sheets.forEach((gameSheet, sheetNum) => {
let plist = plists[sheetNum]
let name = sheetNames[sheetNum]
if (!name.startsWith('PlayerExplosion_')) console.log("Shuffling " + name)
else if (name == "PlayerExplosion_01-uhd") console.log("Shuffling death effects")

let sizes = {}
Object.keys(gameSheet).forEach(x => {
let obj = gameSheet[x]
obj.name = x
if (sheetNum == sheetNames.findIndex(y => y.startsWith('GJ_GameSheet02')) && forms.some(y => x.startsWith(y))) {
let form = forms.find(y => x.startsWith(y))
if (!sizes[form]) sizes[form] = [obj]
else sizes[form].push(obj)
}
else {
let sizeDiff = assets.sheets[name] || 30
let size = obj.textureRect[1].map(x => Math.round(x / sizeDiff) * sizeDiff).join()
if (name.startsWith('PlayerExplosion')) size = "deatheffect"
if (!sizes[size]) sizes[size] = [obj]
else sizes[size].push(obj)
}
})

Object.keys(sizes).forEach(obj => {
let objects = sizes[obj]
if (objects.length == 1) return delete sizes[obj]
let iconMode = forms.includes(obj)
let oldNames = objects.map(x => x.name)
if (iconMode) oldNames = undupe(oldNames.map(x => x.replace(iconRegex, "$1")))
let newNames = oldNames.shuffle()
if (iconMode) {
let iconList = {}
oldNames.forEach((x, y) => iconList[x] = newNames[y])
newNames = iconList
}

oldNames.forEach((x, y) => {
let newName = newNames[iconMode ? x : y]
if (iconMode) {
plist = plist.replace(new RegExp(`<key>${obj}_${x}_`, "g"), `<key>###${obj}_${newName}_`)
glowPlist = glowPlist.replace(`<key>${obj}_${x}_`, `<key>###${obj}_${newName}_`)
}
else {
plist = plist.replace(`<key>${x}</key>`, `<key>###${newName}</key>`)
if (glowSheet[glow(x)]) {
glowBackups.push(glow(x))
glowPlist = glowPlist.replace(`<key>${glow(x)}</key>`, `<key>###${glow(newName)}</key>`)
}
}
})
})
plist = plist.replace(/###/g, "")
fs.writeFileSync('./pack/' + sheetNames[sheetNum] + '.plist', plist, 'utf8')
})

console.log("Shuffling misc textures")
let specialGrounds = []
assets.sprites.forEach(img => {
let spriteMatch = img.split("|")
let foundTextures = resources.filter(x => x.match(new RegExp(`^${spriteMatch[0].replace("#", "\\d+?")}-uhd\\.${spriteMatch[1] || "png"}`)))

if (spriteMatch[2] == "*") specialGrounds = specialGrounds.concat(foundTextures.map(x => x.slice(0, 15)))
if (spriteMatch[2] == "g1") foundTextures = foundTextures.filter(x => !specialGrounds.some(y => x.startsWith(y)))
if (spriteMatch[2] == "g2") foundTextures = foundTextures.filter(x => specialGrounds.some(y => x.startsWith(y)))

let shuffledTextures = foundTextures.shuffle()
foundTextures.forEach((x, y) => fs.copyFileSync(`${assets.gdPath}/${x}`, `./pack/${shuffledTextures[y]}`))
})

let emptyDict = glowPlist.match(/<dict>\s*<key>aliases<\/key>(.|\n)+?<\/dict>/)[0].replace(/{\d+,\d+}/g, "{0, 0}")
let mappedBackups = glowBackups.reverse().map(x => `<key>${x}</key>${emptyDict}`).join("")
glowPlist = fs.writeFileSync('./pack/GJ_GameSheetGlow-uhd.plist', glowPlist.replace(/###/g, "").replace(/<dict>\s*<key>frames<\/key>\s*<dict>/g, "$&" + mappedBackups), 'utf8')
console.log("Randomization complete!")

0 comments on commit 21b00c7

Please sign in to comment.