diff --git a/src/main/javacc/BlockConfig.jj b/src/main/javacc/BlockConfig.jj index e11bb20..29cea2d 100644 --- a/src/main/javacc/BlockConfig.jj +++ b/src/main/javacc/BlockConfig.jj @@ -99,4 +99,7 @@ Node.Value matchValue() : { | "model.texture" t = { return new Node.Value.Texture(t.image); } + | + "model.tint" t = + { return new Node.Value.Tint(t.image); } } \ No newline at end of file diff --git a/src/main/kotlin/mods/betterfoliage/config/match/Matchers.kt b/src/main/kotlin/mods/betterfoliage/config/match/Matchers.kt index 1c152ab..516fdb9 100644 --- a/src/main/kotlin/mods/betterfoliage/config/match/Matchers.kt +++ b/src/main/kotlin/mods/betterfoliage/config/match/Matchers.kt @@ -2,6 +2,7 @@ package mods.betterfoliage.config.match import mods.betterfoliage.resource.discovery.RuleProcessingContext import mods.betterfoliage.resource.discovery.getAncestry +import mods.betterfoliage.util.findFirst import mods.betterfoliage.util.tryDefault import net.minecraft.block.Block import net.minecraft.client.renderer.model.BlockModel @@ -29,7 +30,7 @@ object MatchRuleList { when (node.matchSource) { Node.MatchSource.BLOCK_CLASS -> BlockMatchRules.visitClass(ctx, node, value) Node.MatchSource.BLOCK_NAME -> BlockMatchRules.visitName(ctx, node, value) - Node.MatchSource.MODEL_LOCATION -> ModelMatchRules.visit(ctx, node, value) + Node.MatchSource.MODEL_LOCATION -> ModelMatchRules.visitModel(ctx, node, value) } } catch (e: Exception) { MatchResult.Error(node.configSource, e.message ?: "") @@ -85,7 +86,7 @@ object BlockMatchRules { } object ModelMatchRules { - fun visit(ctx: RuleProcessingContext, node: Node.MatchValueList, value: Node.Value): MatchResult { + fun visitModel(ctx: RuleProcessingContext, node: Node.MatchValueList, value: Node.Value): MatchResult { val source = ctx.discovery.modelLocation.let { MatchValue.Found("model \"$it\"", it) } if (value !is Node.Value.Literal) return node.invalidValueType("model", value) val (namespace, path) = value.value.splitLocation() @@ -137,14 +138,29 @@ object ParamMatchRules { val target = when(node.value) { is Node.Value.Literal -> node.value.value.let { MatchValue.Found("\"$it\"", it) } is Node.Value.Texture -> when(val model = ctx.discovery.getUnbaked()) { - is BlockModel -> model.getMaterial(node.value.value).texture().toString().let { - MatchValue.Found("texture \"${node.value.value}\" = \"$it\"", it) - } + is BlockModel -> getModelTexture(model, node.value.value) else -> return node.error("cannot get texture from ${model::class.java.name}") } + is Node.Value.Tint -> when(val model = ctx.discovery.getUnbaked()) { + is BlockModel -> getModelTint(ctx.discovery.loadHierarchy(model), node.value.value) + else -> return node.error("cannot get tint index from ${model::class.java.name}") + } else -> return node.invalidValueType("parameter", node.value) } ctx.params[node.name] = target.value return node.action("parameter \"${node.name}\" set to ${target.description}") } + + fun getModelTexture(model: BlockModel, spriteName: String) = + model.getMaterial(spriteName).texture().toString().let { + MatchValue.Found("texture \"${spriteName}\" = \"$it\"", it) + } + + fun getModelTint(model: BlockModel, spriteName: String) = + model.elements.findFirst { element -> + element.faces.entries.firstOrNull { (_, face) -> + face.texture == "#$spriteName" + }?.value?.tintIndex ?: -1 + }?.let { MatchValue.Found("tint index \"$it\" for sprite \"${spriteName}\"", it.toString()) } + ?: MatchValue.Found("tint index \"-1\" for unused sprite \"${spriteName}\"", "-1") } \ No newline at end of file diff --git a/src/main/kotlin/mods/betterfoliage/config/match/ParseTree.kt b/src/main/kotlin/mods/betterfoliage/config/match/ParseTree.kt index a27379f..a4d8219 100644 --- a/src/main/kotlin/mods/betterfoliage/config/match/ParseTree.kt +++ b/src/main/kotlin/mods/betterfoliage/config/match/ParseTree.kt @@ -33,5 +33,6 @@ sealed class Node { class Literal(value: String) : Value(value) class ClassOf(value: String) : Value(value) class Texture(value: String) : Value(value) + class Tint(value: String) : Value(value) } } diff --git a/src/main/kotlin/mods/betterfoliage/model/TuftMeshes.kt b/src/main/kotlin/mods/betterfoliage/model/TuftMeshes.kt index eebdf17..65780c1 100644 --- a/src/main/kotlin/mods/betterfoliage/model/TuftMeshes.kt +++ b/src/main/kotlin/mods/betterfoliage/model/TuftMeshes.kt @@ -49,13 +49,13 @@ fun tuftQuadSingle(size: Double, height: Double, flipU: Boolean) = ) .mirrorUV(flipU, false) -fun tuftModelSet(shapes: Array, overrideColor: Color?, spriteGetter: (Int) -> TextureAtlasSprite) = +fun tuftModelSet(shapes: Array, color: Color, tint: Int, spriteGetter: (Int) -> TextureAtlasSprite) = shapes.mapIndexed { idx, shape -> listOf( tuftQuadSingle(shape.size, shape.height, shape.flipU1), tuftQuadSingle(shape.size, shape.height, shape.flipU2).rotate(rot(UP)) ).map { it.move(shape.offset) } - .map { it.colorAndIndex(overrideColor) } + .map { it.color(color).colorIndex(tint) } .map { it.sprite(spriteGetter(idx)) } } diff --git a/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Cactus.kt b/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Cactus.kt index dd05c66..68f575d 100644 --- a/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Cactus.kt +++ b/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Cactus.kt @@ -77,7 +77,7 @@ class StandardCactusModel( } val cactusArmModels by BetterFoliage.modelManager.lazy { val shapes = Config.cactus.let { tuftShapeSet(0.8, 0.8, 0.8, 0.2) } - val models = tuftModelSet(shapes, Color.white) { cactusArmSprites[randomI()] } + val models = tuftModelSet(shapes, Color.white, -1) { cactusArmSprites[randomI()] } horizontalDirections.map { side -> models.transform { move(0.0625 to DOWN).rotate(Rotation.fromUp[side.ordinal]) }.buildTufts() }.toTypedArray() diff --git a/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Dirt.kt b/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Dirt.kt index 32a70c1..8fca675 100644 --- a/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Dirt.kt +++ b/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Dirt.kt @@ -125,11 +125,11 @@ class StandardDirtModel( ) val algaeModels by BetterFoliage.modelManager.lazy { val shapes = Config.algae.let { tuftShapeSet(it.size, it.heightMin, it.heightMax, it.hOffset) } - tuftModelSet(shapes, Color.white) { algaeSprites[randomI()] }.buildTufts() + tuftModelSet(shapes, Color.white, -1) { algaeSprites[randomI()] }.buildTufts() } val reedModels by BetterFoliage.modelManager.lazy { val shapes = Config.reed.let { tuftShapeSet(2.0, it.heightMin, it.heightMax, it.hOffset) } - tuftModelSet(shapes, Color.white) { reedSprites[randomI()] }.buildTufts() + tuftModelSet(shapes, Color.white, -1) { reedSprites[randomI()] }.buildTufts() } } } \ No newline at end of file diff --git a/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Grass.kt b/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Grass.kt index 35208ef..a07723f 100644 --- a/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Grass.kt +++ b/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Grass.kt @@ -24,12 +24,11 @@ import mods.betterfoliage.resource.discovery.ModelBakingContext import mods.betterfoliage.resource.discovery.ModelDiscoveryContext import mods.betterfoliage.resource.discovery.ParametrizedModelDiscovery import mods.betterfoliage.util.Atlas -import mods.betterfoliage.util.averageColor -import mods.betterfoliage.util.colorOverride +import mods.betterfoliage.util.averageHSB import mods.betterfoliage.util.idxOrNull import mods.betterfoliage.util.lazy import mods.betterfoliage.util.lazyMap -import mods.betterfoliage.util.logColorOverride +import mods.betterfoliage.util.lighten import mods.betterfoliage.util.randomI import net.minecraft.client.renderer.RenderType import net.minecraft.util.Direction.DOWN @@ -39,8 +38,10 @@ import java.util.Random object StandardGrassDiscovery : ParametrizedModelDiscovery() { override fun processModel(ctx: ModelDiscoveryContext, params: Map) { - val textureGrass = params.texture("texture-grass") ?: return - ctx.addReplacement(StandardGrassKey(textureGrass, null)) + val texture = params.location("texture") ?: return + val tint = params.int("tint") ?: -1 + val color = Atlas.BLOCKS.file(texture).averageHSB.lighten() + ctx.addReplacement(StandardGrassKey(texture, tint, color)) BetterFoliage.blockTypes.grass.add(ctx.blockState) ctx.blockState.block.extendLayers() } @@ -48,16 +49,11 @@ object StandardGrassDiscovery : ParametrizedModelDiscovery() { data class StandardGrassKey( val sprite: ResourceLocation, - val overrideColor: Color? + val tintIndex: Int, + val avgColor: Color, ) : HalfBakedWrapperKey() { - val tintIndex: Int get() = if (overrideColor == null) 0 else -1 - override fun bake(ctx: ModelBakingContext, wrapped: SpecialRenderModel): SpecialRenderModel { - val grassColor = Atlas.BLOCKS[sprite].averageColor.let { hsb -> - logColorOverride(BetterFoliageMod.detailLogger(this), Config.shortGrass.saturationThreshold, hsb) - hsb.colorOverride(Config.shortGrass.saturationThreshold) - } - return StandardGrassModel(wrapped, this.copy(overrideColor = grassColor)) + return StandardGrassModel(wrapped, this) } } @@ -130,10 +126,10 @@ class StandardGrassModel( Config.shortGrass.let { tuftShapeSet(it.size, it.heightMin, it.heightMax, it.hOffset) } } val grassTuftMeshesNormal = BetterFoliage.modelManager.lazyMap { key: StandardGrassKey -> - tuftModelSet(grassTuftShapes, key.overrideColor) { idx -> grassTuftSprites[randomI()] }.buildTufts() + tuftModelSet(grassTuftShapes, key.avgColor, key.tintIndex) { idx -> grassTuftSprites[randomI()] }.buildTufts() } val grassTuftMeshesSnowed = BetterFoliage.modelManager.lazyMap { key: StandardGrassKey -> - tuftModelSet(grassTuftShapes, Color.white) { idx -> grassTuftSprites[randomI()] }.buildTufts() + tuftModelSet(grassTuftShapes, Color.white, -1) { idx -> grassTuftSprites[randomI()] }.buildTufts() } val grassFullBlockMeshes = BetterFoliage.modelManager.lazyMap { key: StandardGrassKey -> Array(64) { fullCubeTextured(key.sprite, key.tintIndex) } diff --git a/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Leaf.kt b/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Leaf.kt index bc4b77f..ed5a859 100644 --- a/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Leaf.kt +++ b/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Leaf.kt @@ -22,8 +22,6 @@ import mods.betterfoliage.resource.discovery.ModelDiscoveryContext import mods.betterfoliage.resource.discovery.ParametrizedModelDiscovery import mods.betterfoliage.resource.generated.GeneratedLeafSprite import mods.betterfoliage.util.Atlas -import mods.betterfoliage.util.averageColor -import mods.betterfoliage.util.colorOverride import mods.betterfoliage.util.lazyMap import mods.betterfoliage.util.logColorOverride import net.minecraft.client.renderer.RenderType @@ -33,7 +31,7 @@ import org.apache.logging.log4j.Level.INFO object StandardLeafDiscovery : ParametrizedModelDiscovery() { override fun processModel(ctx: ModelDiscoveryContext, params: Map) { - val leafSprite = params.texture("texture-leaf") ?: return + val leafSprite = params.location("texture-leaf") ?: return val leafType = LeafParticleRegistry.typeMappings.getType(leafSprite) ?: "default" val generated = GeneratedLeafSprite(leafSprite, leafType) .register(BetterFoliage.generatedPack) @@ -52,11 +50,7 @@ data class StandardLeafKey( val tintIndex: Int get() = if (overrideColor == null) 0 else -1 override fun bake(ctx: ModelBakingContext, wrapped: SpecialRenderModel): SpecialRenderModel { - val leafSpriteColor = Atlas.BLOCKS[roundLeafTexture].averageColor.let { hsb -> - logColorOverride(BetterFoliageMod.detailLogger(this), Config.leaves.saturationThreshold, hsb) - hsb.colorOverride(Config.leaves.saturationThreshold) - } - return StandardLeafModel(wrapped, this.copy(overrideColor = leafSpriteColor)) + return StandardLeafModel(wrapped, this) } } diff --git a/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Lilypad.kt b/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Lilypad.kt index 2286902..c129721 100644 --- a/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Lilypad.kt +++ b/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Lilypad.kt @@ -74,13 +74,13 @@ class StandardLilypadModel( } val lilypadRootModels by BetterFoliage.modelManager.lazy { val shapes = tuftShapeSet(1.0, 1.0, 1.0, Config.lilypad.hOffset) - tuftModelSet(shapes, Color.white) { lilypadRootSprites[it] } + tuftModelSet(shapes, Color.white, -1) { lilypadRootSprites[it] } .transform { move(2.0 to DOWN) } .buildTufts() } val lilypadFlowerModels by BetterFoliage.modelManager.lazy { val shapes = tuftShapeSet(0.5, 0.5, 0.5, Config.lilypad.hOffset) - tuftModelSet(shapes, Color.white) { lilypadFlowerSprites[it] } + tuftModelSet(shapes, Color.white, -1) { lilypadFlowerSprites[it] } .transform { move(1.0 to DOWN) } .buildTufts() } diff --git a/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Mycelium.kt b/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Mycelium.kt index c1b0887..6bdf67a 100644 --- a/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Mycelium.kt +++ b/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Mycelium.kt @@ -21,12 +21,11 @@ import mods.betterfoliage.resource.discovery.ModelBakingContext import mods.betterfoliage.resource.discovery.ModelDiscoveryContext import mods.betterfoliage.resource.discovery.ParametrizedModelDiscovery import mods.betterfoliage.util.Atlas -import mods.betterfoliage.util.averageColor -import mods.betterfoliage.util.colorOverride +import mods.betterfoliage.util.averageHSB import mods.betterfoliage.util.idxOrNull import mods.betterfoliage.util.lazy import mods.betterfoliage.util.lazyMap -import mods.betterfoliage.util.logColorOverride +import mods.betterfoliage.util.lighten import mods.betterfoliage.util.randomI import net.minecraft.client.renderer.RenderType import net.minecraft.util.Direction @@ -35,22 +34,21 @@ import java.util.Random object StandardMyceliumDiscovery : ParametrizedModelDiscovery() { override fun processModel(ctx: ModelDiscoveryContext, params: Map) { - val textureMycelium = params.texture("texture-mycelium") ?: return - ctx.addReplacement(StandardMyceliumKey(textureMycelium, null)) + val texture = params.location("texture") ?: return + val tint = params.int("tint") ?: -1 + val color = Atlas.BLOCKS.file(texture).averageHSB.lighten(multiplier = 1.5f) + ctx.addReplacement(StandardMyceliumKey(texture, tint, color)) ctx.blockState.block.extendLayers() } } data class StandardMyceliumKey( val sprite: ResourceLocation, - val overrideColor: Color? + val tintIndex: Int, + val avgColor: Color, ) : HalfBakedWrapperKey() { override fun bake(ctx: ModelBakingContext, wrapped: SpecialRenderModel): SpecialRenderModel { - val myceliumColor = Atlas.BLOCKS[sprite].averageColor.let { hsb -> - logColorOverride(BetterFoliageMod.detailLogger(this), Config.shortGrass.saturationThreshold, hsb) - hsb.colorOverride(Config.shortGrass.saturationThreshold) - } - return StandardMyceliumModel(wrapped, copy(overrideColor = myceliumColor)) + return StandardMyceliumModel(wrapped, this) } } @@ -95,7 +93,7 @@ class StandardMyceliumModel( Config.shortGrass.let { tuftShapeSet(it.size, it.heightMin, it.heightMax, it.hOffset) } } val myceliumTuftModels = BetterFoliage.modelManager.lazyMap { key: StandardMyceliumKey -> - tuftModelSet(myceliumTuftShapes, key.overrideColor) { idx -> myceliumTuftSprites[randomI()] }.buildTufts() + tuftModelSet(myceliumTuftShapes, key.avgColor, key.tintIndex) { idx -> myceliumTuftSprites[randomI()] }.buildTufts() } } } \ No newline at end of file diff --git a/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Netherrack.kt b/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Netherrack.kt index 8659c76..36edbc9 100644 --- a/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Netherrack.kt +++ b/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Netherrack.kt @@ -78,7 +78,7 @@ class StandardNetherrackModel( } val netherrackTuftModels by BetterFoliage.modelManager.lazy { val shapes = Config.netherrack.let { tuftShapeSet(it.size, it.heightMin, it.heightMax, it.hOffset) } - tuftModelSet(shapes, Color.white) { netherrackTuftSprites[randomI()] } + tuftModelSet(shapes, Color.white, -1) { netherrackTuftSprites[randomI()] } .transform { rotate(Rotation.fromUp[DOWN.ordinal]).rotateUV(2) } .buildTufts() } diff --git a/src/main/kotlin/mods/betterfoliage/render/block/vanilla/RoundLog.kt b/src/main/kotlin/mods/betterfoliage/render/block/vanilla/RoundLog.kt index b1af002..a2fac84 100644 --- a/src/main/kotlin/mods/betterfoliage/render/block/vanilla/RoundLog.kt +++ b/src/main/kotlin/mods/betterfoliage/render/block/vanilla/RoundLog.kt @@ -36,8 +36,8 @@ object RoundLogOverlayLayer : ColumnRenderLayer() { object StandardRoundLogDiscovery : ParametrizedModelDiscovery() { override fun processModel(ctx: ModelDiscoveryContext, params: Map) { - val barkSprite = params.texture("texture-side") ?: return - val endSprite = params.texture("texture-end") ?: return + val barkSprite = params.location("texture-side") ?: return + val endSprite = params.location("texture-end") ?: return val axis = getAxis(ctx.blockState) detailLogger.log(INFO, " axis $axis, material ${ctx.blockState.material}") diff --git a/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Sand.kt b/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Sand.kt index ddea6ea..f749a9d 100644 --- a/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Sand.kt +++ b/src/main/kotlin/mods/betterfoliage/render/block/vanilla/Sand.kt @@ -106,7 +106,7 @@ class StandardSandModel( val coralTuftModels by BetterFoliage.modelManager.lazy { val shapes = Config.coral.let { tuftShapeSet(it.size, 1.0, 1.0, it.hOffset) } allDirections.mapArray { face -> - tuftModelSet(shapes, Color.white) { coralTuftSprites[randomI()] } + tuftModelSet(shapes, Color.white, -1) { coralTuftSprites[randomI()] } .transform { rotate(Rotation.fromUp[face]) } .buildTufts() } diff --git a/src/main/kotlin/mods/betterfoliage/resource/discovery/BakingLifecycle.kt b/src/main/kotlin/mods/betterfoliage/resource/discovery/BakingLifecycle.kt index 8c2e90f..ab51b41 100644 --- a/src/main/kotlin/mods/betterfoliage/resource/discovery/BakingLifecycle.kt +++ b/src/main/kotlin/mods/betterfoliage/resource/discovery/BakingLifecycle.kt @@ -57,6 +57,9 @@ data class ModelDiscoveryContext( if (addToStateKeys) BetterFoliage.blockTypes.stateKeys[blockState] = key logger.log(INFO, "Adding model replacement $modelLocation -> $key") } + fun loadHierarchy(model: T) = model.apply { + getMaterials(this@ModelDiscoveryContext::getUnbaked, mutableSetOf()) + } } data class ModelBakingContext( diff --git a/src/main/kotlin/mods/betterfoliage/resource/discovery/RuleBasedDiscovery.kt b/src/main/kotlin/mods/betterfoliage/resource/discovery/RuleBasedDiscovery.kt index 06428a2..9693402 100644 --- a/src/main/kotlin/mods/betterfoliage/resource/discovery/RuleBasedDiscovery.kt +++ b/src/main/kotlin/mods/betterfoliage/resource/discovery/RuleBasedDiscovery.kt @@ -13,11 +13,17 @@ import org.apache.logging.log4j.Level abstract class ParametrizedModelDiscovery : HasLogger() { abstract fun processModel(ctx: ModelDiscoveryContext, params: Map) - fun Map.texture(key: String): ResourceLocation? { + fun Map.location(key: String): ResourceLocation? { val result = get(key)?.let { ResourceLocation(it) } if (result == null) detailLogger.log(Level.WARN, "Cannot find texture parameter \"$key\"") return result } + + fun Map.int(key: String): Int? { + val result = get(key)?.toInt() + if (result == null) detailLogger.log(Level.WARN, "Cannot find integer parameter \"$key\"") + return result + } } class RuleProcessingContext( diff --git a/src/main/resources/assets/betterfoliage/config/betterfoliage/vanilla.rules b/src/main/resources/assets/betterfoliage/config/betterfoliage/vanilla.rules index 276b2f3..8965e41 100644 --- a/src/main/resources/assets/betterfoliage/config/betterfoliage/vanilla.rules +++ b/src/main/resources/assets/betterfoliage/config/betterfoliage/vanilla.rules @@ -4,6 +4,7 @@ match block.class.extends(classOf("minecraft:oak_leaves")) setParam("type", "lea match isParam("type", "leaf") model.extends("minecraft:block/leaves", "minecraft:block/cube_all") setParam("texture-leaf", model.texture("all")) +setParam("tint-leaf", model.tint("all")) end // Podzol @@ -14,7 +15,8 @@ match block.class.extends(classOf("minecraft:grass_block")) setParam("type", "gr match isParam("type", "grass") model.extends("minecraft:block/grass_block", "minecraft:block/cube_bottom_top") -setParam("texture-grass", model.texture("top")) +setParam("texture", model.texture("top")) +setParam("tint", model.tint("top")) end // Mycelium & Nylium @@ -22,7 +24,8 @@ match block.name.matches("minecraft:mycelium", "minecraft:crimson_nylium", "mine match isParam("type", "mycelium") model.extends("minecraft:block/cube_bottom_top") -setParam("texture-mycelium", model.texture("top")) +setParam("texture", model.texture("top")) +setParam("tint", model.tint("top")) end // Dirt