Skip to content

Instantly share code, notes, and snippets.

@DevSrSouza
Last active June 11, 2023 05:34
Show Gist options
  • Save DevSrSouza/26be00d58894eec8ec4f0a076c1f2169 to your computer and use it in GitHub Desktop.
Save DevSrSouza/26be00d58894eec8ec4f0a076c1f2169 to your computer and use it in GitHub Desktop.
Generate Oraxen configuration for MTVehicles Texture with Furniture support
/** This script will migrate MTVehicles resource pack to Oraxen
* This will include:
* - Fixing ItemFrame position of the models
* - Fix new texture folder that will not anymore bem on custom/cars/, instead it will be at default/mtvehicles
* - For each model that is only a texture replacement, it will generate an Orxen config with Generate enabled with the given name. So... no more bunch of Cars models with only texture change
* - Will remove from models the: "particle": "items/particle" and "texture": "items/texture", that Oraxen says is not proper format.
*/
@file:DependsOn("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1")
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.*
import java.io.File
val Int.j: JsonPrimitive get() = JsonPrimitive(this)
val String.j: JsonPrimitive get() = JsonPrimitive(this)
val resourcePackFolder = File("pack")
val outputModelsFolder = File("out-pack/models/default/mtvehicles")
outputModelsFolder.mkdirs()
val outputOrxenConfig = File("furniture-oraxen.yaml")
val models = File(resourcePackFolder, "assets/minecraft/models/custom/vehicles")
val modelsFiles = models.listFiles()!!
var furnitureOraxenConfig: String = ""
fun furnitureBaseItem(
name: String,
): String {
// TODO: better display name
// TODO: support seat
// TODO: hitbox?
// TODO: height based on mtvehicles config?
// TODO: why does Scale is necessary? does this value actually true for all vehicles?
return """
|$name:
| displayname: "<gray>$name Decorative"
| material: PAPER
| Mechanics:
| furniture:
| type: DISPLAY_ENTITY
| hitbox:
| width: 1.0
| height: 1.0
| display_entity_properties:
| display_transform: FIXED
| scale:
| x: 0.65
| y: 0.65
| z: 0.65
| barrier: true
| limited_placing:
| roof: false
| floor: true
| wall: false
| drop:
| silktouch: false
| loots:
| - { oraxen_item: $name, probability: 1.0 }
""".trimMargin()
}
fun oraxenGenerateItem(
name: String,
parentModel: String,
texturesLayers: Map<String, String>
): String {
val textures = texturesLayers.map { " ${it.key}: ${it.value}.png" }.joinToString("\n")
return furnitureBaseItem(name) + "\n" + """
| Pack:
| generate_model: true
| parent_model: "$parentModel"
| textures:
""".trimMargin() + "\n" + textures
}
fun oraxenModelItem(
name: String,
model: String,
): String {
return furnitureBaseItem(name) + "\n" + """
| Pack:
| generate_model: false
| model: "$model"
""".trimMargin()
}
fun correctModelLocation(texturePath: String) = texturePath.replace("custom/vehicles/", "default/mtvehicles/")
for (modelFile in modelsFiles.filter { it.extension == "json" }) {
println("------------")
println("Reading model: ${modelFile.name}")
if(modelFile.name.startsWith("broomstick")) {
println("Ignoring model not a Car")
continue
}
val modelJson = Json.parseToJsonElement(modelFile.readText()).jsonObject.toMutableMap()
val parent = modelJson["parent"]?.jsonPrimitive?.content
val texturesBlock = modelJson["textures"]!!.jsonObject
val texturesFilter = texturesBlock.filterNot {
// filter reference to minecraft default texture pack
listOf("items/", "blocks/").any { exclude -> it.value.jsonPrimitive.content.startsWith(exclude) }
}
if(parent != null) {
println("Parent found ($parent), generating oraxen config")
val config = oraxenGenerateItem(
name = modelFile.nameWithoutExtension,
parentModel = correctModelLocation(parent),
texturesLayers = texturesFilter.mapValues { it.value.jsonPrimitive.content }
)
println(config)
furnitureOraxenConfig += config + "\n"
} else {
val display = modelJson["display"]!!.jsonObject
val headBlock = display["head"]!!.jsonObject
val headScale = headBlock["scale"]!!.jsonArray
val fixedBlock = display["fixed"]?.jsonObject ?: JsonObject(emptyMap())
val updatedFixedBlock = JsonObject(
mutableMapOf(
"rotation" to JsonArray(listOf((-90).j, 0.j, 0.j)),
"translation" to JsonArray(
listOf(
0.j,
fixedBlock["translation"]?.jsonArray?.get(1)?.jsonPrimitive ?: 0.j,
(-28).j // magic number, this does not work for all cars, maybe a solution reading the MTVehicles should be better approach
)
),
"scale" to headScale,
)
)
val updatedDisplayBlock = JsonObject(
display.toMutableMap().apply {
set("fixed", updatedFixedBlock)
}
)
val updatedTextureBlock = JsonObject(
texturesFilter
)
modelJson.set("textures", updatedTextureBlock)
modelJson.set("display", updatedDisplayBlock)
val updatedModel = JsonObject(modelJson)
File(outputModelsFolder, modelFile.name).writeText(Json.encodeToString(updatedModel))
furnitureOraxenConfig += oraxenModelItem(
modelFile.nameWithoutExtension,
"default/mtvehicles/" + modelFile.nameWithoutExtension
) + "\n"
}
}
outputOrxenConfig.writeText(furnitureOraxenConfig)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment