Add support for Forestry logs

fixes #82
This commit is contained in:
octarine-noise
2016-09-05 15:13:31 +02:00
parent e00ccd5919
commit 4a4d39b523
18 changed files with 217 additions and 178 deletions

View File

@@ -1,97 +0,0 @@
package mods.octarinecore.client.resource
import mods.betterfoliage.loader.Refs
import mods.octarinecore.common.config.BlockMatcher
import net.minecraft.block.Block
import net.minecraft.block.state.IBlockState
import net.minecraft.client.renderer.block.model.ModelResourceLocation
import net.minecraft.client.renderer.block.statemap.DefaultStateMapper
import net.minecraft.client.renderer.block.statemap.IStateMapper
import net.minecraft.client.renderer.texture.TextureAtlasSprite
import net.minecraft.client.renderer.texture.TextureMap
import net.minecraft.util.ResourceLocation
import net.minecraftforge.client.event.TextureStitchEvent
import net.minecraftforge.client.model.IModel
import net.minecraftforge.client.model.ModelLoader
import net.minecraftforge.common.MinecraftForge
import net.minecraftforge.fml.common.eventhandler.Event
import net.minecraftforge.fml.common.eventhandler.EventPriority
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
class LoadModelDataEvent(val loader: ModelLoader) : Event()
abstract class ModelDataInspector {
abstract fun onAfterModelLoad()
abstract fun processModelDefinition(state: IBlockState, location: ModelResourceLocation, model: IModel)
abstract fun onStitch(atlas: TextureMap)
init { MinecraftForge.EVENT_BUS.register(this) }
@Suppress("UNCHECKED_CAST")
@SubscribeEvent
fun handleLoadModelData(event: LoadModelDataEvent) {
val stateMappings = Block.REGISTRY.flatMap { block ->
val mapper = event.loader.blockModelShapes.blockStateMapper.blockStateMap[block] as? IStateMapper ?: DefaultStateMapper()
(mapper.putStateModelLocations(block as Block) as Map<IBlockState, ModelResourceLocation>).entries
}
val stateModels = Refs.stateModels.get(event.loader) as Map<ModelResourceLocation, IModel>
onAfterModelLoad()
stateMappings.forEach { mapping ->
if (mapping.key.block != null)
stateModels[mapping.value]?.let { processModelDefinition(mapping.key, mapping.value, it) }
}
}
@SubscribeEvent(priority = EventPriority.LOW)
fun handleTextureReload(event: TextureStitchEvent.Pre) { onStitch(event.map) }
}
abstract class BlockTextureInspector<T> : ModelDataInspector() {
val state2Names = hashMapOf<IBlockState, Iterable<String>>()
val modelMappings = mutableListOf<Pair<(IBlockState, IModel)->Boolean, Iterable<String>>>()
val stateMap = hashMapOf<IBlockState, T>()
fun match(textureNames: Iterable<String>, predicate: (IBlockState, IModel)->Boolean) =
modelMappings.add(predicate to textureNames)
fun matchClassAndModel(blockClass: BlockMatcher, modelLocation: String, textureNames: Iterable<String>) =
match(textureNames) { state, model -> blockClass.matchesClass(state.block) && model.derivesFromModel(modelLocation) }
operator fun get(state: IBlockState) = stateMap[state]
override fun onAfterModelLoad() {
stateMap.clear()
}
override fun processModelDefinition(state: IBlockState, modelDefLoc: ModelResourceLocation, model: IModel) {
modelMappings.forEach { mapping ->
if (mapping.first(state, model)) {
model.modelBlockAndLoc?.first?.let { modelBlock ->
val textures = mapping.second.map { modelBlock.resolveTextureName(it) }
if (textures.all { it != null && it != "missingno" }) {
state2Names.put(state, textures)
}
}
}
}
}
override fun onStitch(atlas: TextureMap) {
val state2Texture = hashMapOf<IBlockState, List<TextureAtlasSprite>>()
val texture2Info = hashMapOf<List<TextureAtlasSprite>, T>()
state2Names.forEach { state, textureNames ->
val textures = textureNames.map { atlas.getTextureExtry(ResourceLocation(it).toString()) }
if (textures.all { it != null }) {
state2Texture.put(state, textures)
if (textures !in texture2Info) texture2Info.put(textures, processTextures(state, textures, atlas))
}
}
state2Texture.forEach { state, texture -> stateMap.put(state, texture2Info[texture]!!) }
state2Names.clear()
}
abstract fun processTextures(state: IBlockState, textures: List<TextureAtlasSprite>, atlas: TextureMap): T
}

View File

@@ -2,7 +2,8 @@ package mods.octarinecore.client.resource
import com.google.common.base.Joiner
import mods.betterfoliage.loader.Refs
import mods.octarinecore.common.config.BlockMatcher
import mods.octarinecore.common.config.ConfigurableBlockMatcher
import mods.octarinecore.common.config.IBlockMatcher
import mods.octarinecore.common.config.ModelTextureList
import mods.octarinecore.filterValuesNotNull
import net.minecraft.block.Block
@@ -14,11 +15,15 @@ import net.minecraft.client.renderer.texture.TextureAtlasSprite
import net.minecraft.client.renderer.texture.TextureMap
import net.minecraftforge.client.event.TextureStitchEvent
import net.minecraftforge.client.model.IModel
import net.minecraftforge.client.model.ModelLoader
import net.minecraftforge.fml.common.eventhandler.Event
import net.minecraftforge.fml.common.eventhandler.EventPriority
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import org.apache.logging.log4j.Level
import org.apache.logging.log4j.Logger
class LoadModelDataEvent(val loader: ModelLoader) : Event()
interface ModelProcessor<T1, T2> {
val logger: Logger?
var stateToKey: MutableMap<IBlockState, T1>
@@ -58,7 +63,7 @@ interface ModelProcessor<T1, T2> {
interface TextureListModelProcessor<T2> : ModelProcessor<List<String>, T2> {
val logName: String
val matchClasses: BlockMatcher
val matchClasses: IBlockMatcher
val modelTextures: List<ModelTextureList>
override fun processModelLoad(state: IBlockState, modelLoc: ModelResourceLocation, model: IModel): List<String>? {

View File

@@ -35,7 +35,7 @@ operator fun IResourceManager.get(domain: String, path: String): IResource? = ge
operator fun IResourceManager.get(location: ResourceLocation): IResource? = tryDefault(null) { getResource(location) }
/** Index operator to get a texture sprite. */
operator fun TextureMap.get(name: String): TextureAtlasSprite? = getTextureExtry(name)
operator fun TextureMap.get(name: String): TextureAtlasSprite? = getTextureExtry(ResourceLocation(name).toString())
/** Load an image resource. */
fun IResource.loadImage() = ImageIO.read(this.inputStream)

View File

@@ -4,17 +4,32 @@ import mods.octarinecore.metaprog.getJavaClass
import net.minecraft.block.Block
import net.minecraft.util.ResourceLocation
class BlockMatcher(domain: String, path: String) : BlackWhiteListConfigOption<Class<*>>(domain, path) {
interface IBlockMatcher {
fun matchesClass(block: Block): Boolean
fun matchingClass(block: Block): Class<*>?
}
class SimpleBlockMatcher(vararg val classes: Class<*>) : IBlockMatcher {
override fun matchesClass(block: Block) = matchingClass(block) != null
override fun matchingClass(block: Block): Class<*>? {
val blockClass = block.javaClass
classes.forEach { if (it.isAssignableFrom(blockClass)) return it }
return null
}
}
class ConfigurableBlockMatcher(domain: String, path: String) : IBlockMatcher, BlackWhiteListConfigOption<Class<*>>(domain, path) {
override fun convertValue(line: String) = getJavaClass(line)
fun matchesClass(block: Block): Boolean {
override fun matchesClass(block: Block): Boolean {
val blockClass = block.javaClass
blackList.forEach { if (it.isAssignableFrom(blockClass)) return false }
whiteList.forEach { if (it.isAssignableFrom(blockClass)) return true }
return false
}
fun matchingClass(block: Block): Class<*>? {
override fun matchingClass(block: Block): Class<*>? {
val blockClass = block.javaClass
blackList.forEach { if (it.isAssignableFrom(blockClass)) return null }
whiteList.forEach { if (it.isAssignableFrom(blockClass)) return it }
@@ -24,6 +39,8 @@ class BlockMatcher(domain: String, path: String) : BlackWhiteListConfigOption<Cl
data class ModelTextureList(val modelLocation: ResourceLocation, val textureNames: List<String>)
fun modelTextures(vararg args: String) = ModelTextureList(ResourceLocation(args[0]), listOf(*args).drop(1))
class ModelTextureListConfigOption(domain: String, path: String, val minTextures: Int) : StringListConfigOption<ModelTextureList>(domain, path) {
override fun convertValue(line: String): ModelTextureList? {
val elements = line.split(",")