Files
BetterFoliage/src/main/kotlin/mods/betterfoliage/client/integration/RubberIntegration.kt
2019-04-13 09:37:57 +02:00

182 lines
8.2 KiB
Kotlin

package mods.betterfoliage.client.integration
import mods.betterfoliage.BetterFoliageMod
import mods.betterfoliage.client.Client
import mods.betterfoliage.client.config.Config
import mods.betterfoliage.client.render.IColumnRegistry
import mods.betterfoliage.client.render.IColumnTextureInfo
import mods.betterfoliage.client.render.LogRegistry
import mods.betterfoliage.client.render.StaticColumnInfo
import mods.betterfoliage.client.texture.StandardLeafSupport
import mods.betterfoliage.loader.Refs
import mods.octarinecore.client.render.Quad
import mods.octarinecore.client.render.QuadIconResolver
import mods.octarinecore.client.render.ShadingContext
import mods.octarinecore.client.render.blockContext
import mods.octarinecore.client.resource.*
import mods.octarinecore.common.rotate
import mods.octarinecore.metaprog.ClassRef
import mods.octarinecore.metaprog.MethodRef
import mods.octarinecore.metaprog.allAvailable
import net.minecraft.block.state.IBlockState
import net.minecraft.client.renderer.block.model.ModelResourceLocation
import net.minecraft.client.renderer.texture.TextureAtlasSprite
import net.minecraft.client.renderer.texture.TextureMap
import net.minecraft.util.EnumFacing
import net.minecraft.util.ResourceLocation
import net.minecraftforge.client.model.IModel
import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.fml.common.Loader
import net.minecraftforge.fml.relauncher.Side
import net.minecraftforge.fml.relauncher.SideOnly
import org.apache.logging.log4j.Level
import org.apache.logging.log4j.Logger
@SideOnly(Side.CLIENT)
object IC2Integration {
val BlockRubWood = ClassRef("ic2.core.block.BlockRubWood")
init {
if (Loader.isModLoaded("ic2") && allAvailable(BlockRubWood)) {
Client.log(Level.INFO, "IC2 support initialized")
LogRegistry.subRegistries.add(IC2LogSupport)
}
}
}
@SideOnly(Side.CLIENT)
object TechRebornIntegration {
val BlockRubberLog = ClassRef("techreborn.blocks.BlockRubberLog")
init {
if (Loader.isModLoaded("techreborn") && allAvailable(BlockRubberLog)) {
Client.log(Level.INFO, "TechReborn support initialized")
LogRegistry.subRegistries.add(TechRebornLogSupport)
}
}
}
@SideOnly(Side.CLIENT)
data class RubberLogModelInfo(
val axis: EnumFacing.Axis?,
val spotDir: EnumFacing?,
val textures: List<String>
)
// TODO avoid copy-paste pattern with regards to StaticColumnInfo
@SideOnly(Side.CLIENT)
data class RubberLogColumnInfo(override val axis: EnumFacing.Axis?,
val spotDir: EnumFacing,
val topTexture: TextureAtlasSprite,
val bottomTexture: TextureAtlasSprite,
val sideTexture: TextureAtlasSprite,
val spotTexture: TextureAtlasSprite): IColumnTextureInfo {
override val top: QuadIconResolver = { _, _, _ -> topTexture }
override val bottom: QuadIconResolver = { _, _, _ -> bottomTexture }
override val side: QuadIconResolver = { ctx: ShadingContext, idx: Int, quad: Quad ->
val worldRelativeSide = (if ((idx and 1) == 0) EnumFacing.SOUTH else EnumFacing.EAST).rotate(ctx.rotation)
if (worldRelativeSide == spotDir) spotTexture else sideTexture
}
}
@SideOnly(Side.CLIENT)
abstract class RubberLogSupportBase : ModelProcessor<RubberLogModelInfo, IColumnTextureInfo>, IColumnRegistry {
override var variants = mutableMapOf<IBlockState, MutableList<ModelVariant>>()
override var variantToKey = mutableMapOf<ModelVariant, RubberLogModelInfo>()
override var variantToValue = mapOf<ModelVariant, IColumnTextureInfo>()
override val logger = BetterFoliageMod.logDetail
init { MinecraftForge.EVENT_BUS.register(this) }
override fun processStitch(variant: ModelVariant, key: RubberLogModelInfo, atlas: TextureMap): IColumnTextureInfo? {
val topTex = atlas.registerSprite(key.textures[0])
val bottomTex = atlas.registerSprite(key.textures[1])
val sideTex = atlas.registerSprite(key.textures[2])
if (key.spotDir == null)
return StaticColumnInfo(key.axis, topTex, bottomTex, listOf(sideTex))
else {
val spotTex = atlas.registerSprite(key.textures[3])
return RubberLogColumnInfo(key.axis, key.spotDir, topTex, bottomTex, sideTex, spotTex)
}
}
override fun get(state: IBlockState, rand: Int): IColumnTextureInfo? {
val variant = getVariant(state, rand) ?: return null
return variantToValue[variant]
}
}
@SideOnly(Side.CLIENT)
object IC2LogSupport : RubberLogSupportBase() {
override fun processModelLoad(state: IBlockState, modelLoc: ModelResourceLocation, model: IModel) {
// check for proper block class, existence of ModelBlock, and "state" blockstate property
if (!IC2Integration.BlockRubWood.isInstance(state.block)) return
val blockLoc = model.modelBlockAndLoc.firstOrNull() ?: return
val type = state.properties.entries.find { it.key.getName() == "state" }?.value?.toString() ?: return
// logs with no rubber spot
if (blockLoc.derivesFrom(ResourceLocation("block/cube_column"))) {
val axis = when(type) {
"plain_y" -> EnumFacing.Axis.Y
"plain_x" -> EnumFacing.Axis.X
"plain_z" -> EnumFacing.Axis.Z
else -> null
}
val textureNames = listOf("end", "end", "side").map { blockLoc.first.resolveTextureName(it) }
logger.log(Level.DEBUG, "IC2LogSupport: block state ${state.toString()}")
logger.log(Level.DEBUG, "IC2LogSupport: axis=$axis, end=${textureNames[0]}, side=${textureNames[2]}")
if (textureNames.all { it != "missingno" }) {
putKeySingle(state, RubberLogModelInfo(axis, null, textureNames))
}
return
}
// logs with rubber spot
val spotDir = when(type) {
"dry_north", "wet_north" -> EnumFacing.NORTH
"dry_south", "wet_south" -> EnumFacing.SOUTH
"dry_west", "wet_west" -> EnumFacing.WEST
"dry_east", "wet_east" -> EnumFacing.EAST
else -> null
}
val textureNames = listOf("up", "down", "south", "north").map { blockLoc.first.resolveTextureName(it) }
logger.log(Level.DEBUG, "IC2LogSupport: block state ${state.toString()}")
logger.log(Level.DEBUG, "IC2LogSupport: spotDir=$spotDir, up=${textureNames[0]}, down=${textureNames[1]}, side=${textureNames[2]}, spot=${textureNames[3]}")
if (textureNames.all { it != "missingno" }) {
putKeySingle(state, RubberLogModelInfo(EnumFacing.Axis.Y, spotDir, textureNames))
}
}
}
@SideOnly(Side.CLIENT)
object TechRebornLogSupport : RubberLogSupportBase() {
override fun processModelLoad(state: IBlockState, modelLoc: ModelResourceLocation, model: IModel) {
// check for proper block class, existence of ModelBlock
if (!TechRebornIntegration.BlockRubberLog.isInstance(state.block)) return
val blockLoc = model.modelBlockAndLoc.firstOrNull() ?: return
val hasSap = state.properties.entries.find { it.key.getName() == "hassap" }?.value as? Boolean ?: return
val sapSide = state.properties.entries.find { it.key.getName() == "sapside" }?.value as? EnumFacing ?: return
val textureNames = listOf("end", "end", "side", "sapside").map { blockLoc.first.resolveTextureName(it) }
logger.log(Level.DEBUG, "TechRebornLogSupport: block state ${state.toString()}")
if (hasSap) {
logger.log(Level.DEBUG, "TechRebornLogSupport: spotDir=$sapSide, end=${textureNames[0]}, side=${textureNames[2]}, spot=${textureNames[3]}")
if (textureNames.all { it != "missingno" }) {
putKeySingle(state, RubberLogModelInfo(EnumFacing.Axis.Y, sapSide, textureNames))
}
} else {
logger.log(Level.DEBUG, "TechRebornLogSupport: end=${textureNames[0]}, side=${textureNames[2]}")
if (textureNames.all { it != "missingno" }) {
putKeySingle(state, RubberLogModelInfo(EnumFacing.Axis.Y, null, textureNames))
}
}
}
}