blocks: improve multipart generating

This commit is contained in:
Bixilon 2021-04-05 22:01:34 +02:00
parent 99d2fd5442
commit 446a500fdb
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4

View File

@ -74,59 +74,57 @@ object BlockGenerator : Generator(
val render = Util.readJsonMinecraftResource("assets/${resourceIdentifier.namespace}/blockstates/${resourceIdentifier.path}.json")
val multipartVariants: MutableMap<MutableMap<String, MutableSet<String>>, JsonElement> = mutableMapOf()
render["multipart"]?.asJsonArray?.let {
val multipart = JsonArray()
for (condition in it) {
check(condition is JsonObject)
val conditionOut = JsonObject()
val properties: MutableSet<MutableMap<String, MutableSet<String>>> = mutableSetOf()
fun addPropertyMap(json: JsonObject) {
val singlePropertyMap: MutableMap<String, MutableSet<String>> = mutableMapOf()
for ((property, propertyValue) in json.entrySet()) {
val valueSet: MutableSet<String> = mutableSetOf()
val propertyValues = propertyValue.asString.split("|")
for (value in propertyValues) {
valueSet.add(value)
}
singlePropertyMap[property.toLowerCase()] = valueSet
}
properties.add(singlePropertyMap)
}
condition["when"]?.asJsonObject?.let letWhen@{
it["OR"]?.asJsonArray?.let {
val propertiesOr = JsonArray()
for (or in it) {
val propertyOr = JsonObject()
for ((property, propertyValue) in or.asJsonObject.entrySet()) {
addJsonWithType(propertyValue.asString, propertyOr, property.toLowerCase())
}
propertiesOr.add(propertyOr)
addPropertyMap(or.asJsonObject)
}
conditionOut.add("properties", propertiesOr)
return@letWhen
}
val properties = JsonObject()
for ((property, propertyValue) in it.entrySet()) {
addJsonWithType(propertyValue.asString, properties, property.toLowerCase())
}
conditionOut.add("properties", properties)
addPropertyMap(it)
}
condition["apply"].let {
addBlockModel(it)
conditionOut.add("apply", it)
if (properties.isEmpty()) {
properties.add(mutableMapOf())
}
addBlockModel(condition["apply"])
for (propertyMap in properties) {
multipartVariants[propertyMap] = condition["apply"]
}
multipart.add(conditionOut)
}
val renderOut = JsonObject()
renderOut.add("multipart", multipart)
blockData.add("render", renderOut)
}
val renderVariants: MutableMap<HashMap<String, String>, JsonElement> = mutableMapOf()
val renderVariants: MutableMap<MutableMap<String, String>, JsonElement> = mutableMapOf()
render["variants"]?.asJsonObject?.entrySet()?.let {
for ((properties, variant) in it) {
addBlockModel(variant)
if (properties.isBlank()) {
renderVariants[HashMap()] = variant
renderVariants[mutableMapOf()] = variant
continue
}
val propertiesOut: HashMap<String, String> = HashMap()
val propertiesOut: MutableMap<String, String> = mutableMapOf()
for (split in properties.split(",")) {
val splitProperty = split.split("=")
propertiesOut[splitProperty[0].toLowerCase()] = splitProperty[1].toLowerCase()
@ -173,13 +171,13 @@ object BlockGenerator : Generator(
val stateData = JsonObject()
if (state.luminance != 0) {
stateData.addProperty("light_emission", state.luminance)
stateData.addProperty("luminance", state.luminance)
}
if (state.hasRandomTicks()) {
stateData.addProperty("is_randomly_ticking", state.hasRandomTicks())
}
if (state.hasSidedTransparency()) {
stateData.addProperty("use_shape_for_light_occlusion", state.hasSidedTransparency())
stateData.addProperty("has_side_transparency", state.hasSidedTransparency())
}
stateData.addProperty("sound_type_volume", state.soundGroup.volume)
stateData.addProperty("sound_type_volume", state.soundGroup.pitch)
@ -195,10 +193,10 @@ object BlockGenerator : Generator(
}
if (!state.isOpaque) {
stateData.addProperty("can_occlude", state.isOpaque)
stateData.addProperty("is_opaque", state.isOpaque)
}
try {
stateData.addProperty("destroy_speed", BLOCK_DESTROY_SPEED_FIELD.getFloat(state))
stateData.addProperty("hardness", BLOCK_DESTROY_SPEED_FIELD.getFloat(state))
} catch (exception: IllegalArgumentException) {
}
@ -228,7 +226,6 @@ object BlockGenerator : Generator(
stateData.add("properties", propertyData)
}
for ((propertyMap, variant) in renderVariants) {
var valid = true
for ((propertyName, propertyValue) in propertyMap) {
@ -241,9 +238,38 @@ object BlockGenerator : Generator(
stateData.add("render", variant)
}
}
val multipart = JsonArray()
for ((properties, element) in multipartVariants) {
var valid = true
for ((propertyName, values) in properties) {
if (!propertyData.has(propertyName)) {
valid = false
break
}
if (!values.contains(propertyData[propertyName].asString)) {
valid = false
break
}
}
if (valid) {
if (element is JsonArray) {
for (apply in element) {
if (!multipart.contains(apply)) {
multipart.add(apply)
}
}
} else if (element is JsonObject) {
if (!multipart.contains(element)) {
multipart.add(element)
}
}
}
}
check(stateData.has("render") || blockData.has("render")) {
"Block state ($resourceIdentifier: $stateData) has no model!"
if (multipart.size() > 0 && !stateData.has("render")) {
val multipartWrapper = JsonArray()
multipartWrapper.add(multipart)
stateData.add("render", multipartWrapper)
}
if (!block.hasDynamicBounds()) {
@ -260,12 +286,12 @@ object BlockGenerator : Generator(
stateData.addProperty("solid_render", it)
}
CACHE_PROPAGATES_SKYLIGHT_DOWN_FIELD.getBoolean(cache).let {
CACHE_TRANSLUCENT_FIELD.getBoolean(cache).let {
if (it) {
return@let
}
stateData.addProperty("propagates_skylight_down", CACHE_PROPAGATES_SKYLIGHT_DOWN_FIELD.getBoolean(cache))
stateData.addProperty("translucent", CACHE_TRANSLUCENT_FIELD.getBoolean(cache))
}
CACHE_LIGHT_BLOCK_FIELD.getInt(cache).let {
@ -396,7 +422,7 @@ object BlockGenerator : Generator(
private val FLUID_BLOCK_FLUID_FIELD = getField(FluidBlock::class.java, "fluid")!!
private val CACHE_SOLID_RENDER_FIELD = BLOCK_STATE_CACHE_CLASS.getDeclaredField("fullOpaque")
private val CACHE_PROPAGATES_SKYLIGHT_DOWN_FIELD = BLOCK_STATE_CACHE_CLASS.getDeclaredField("translucent")
private val CACHE_TRANSLUCENT_FIELD = BLOCK_STATE_CACHE_CLASS.getDeclaredField("translucent")
private val CACHE_LIGHT_BLOCK_FIELD = BLOCK_STATE_CACHE_CLASS.getDeclaredField("lightSubtracted")
private val CACHE_OCCLUSION_SHAPES_FIELD = getField(BLOCK_STATE_CACHE_CLASS, "extrudedFaces", "shapes")!!
private val CACHE_COLLISION_SHAPES_FIELD = getField(BLOCK_STATE_CACHE_CLASS, "collisionShape") // ToDo: Not working in < 1.14.3
@ -414,7 +440,7 @@ object BlockGenerator : Generator(
BLOCK_STATE_CACHE_FIELD.isAccessible = true
CACHE_SOLID_RENDER_FIELD.isAccessible = true
CACHE_PROPAGATES_SKYLIGHT_DOWN_FIELD.isAccessible = true
CACHE_TRANSLUCENT_FIELD.isAccessible = true
CACHE_LIGHT_BLOCK_FIELD.isAccessible = true
CACHE_OCCLUSION_SHAPES_FIELD.isAccessible = true
LARGE_COLLISION_SHAPE_FIELD.isAccessible = true
@ -446,6 +472,26 @@ object BlockGenerator : Generator(
output.addProperty(name, input)
}
fun getType(input: String): Any {
try {
return Integer.parseInt(input)
} catch (exception: Exception) {
}
try {
when (input) {
"true" -> return true
"false" -> return false
else -> {
}
}
} catch (exception: Exception) {
}
return input
}
private fun addBlockModel(json: JsonElement) {
when (json) {
is JsonObject -> {