@@ -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
|
||||
}
|
||||
@@ -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>? {
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user