package net.shadowfacts.phycon.client.model import com.mojang.datafixers.util.Pair import net.minecraft.block.BlockState import net.minecraft.client.render.model.* import net.minecraft.client.texture.Sprite import net.minecraft.client.texture.SpriteAtlasTexture import net.minecraft.client.util.SpriteIdentifier import net.minecraft.screen.PlayerScreenHandler import net.minecraft.util.DyeColor import net.minecraft.util.Identifier import net.minecraft.util.math.Direction import net.shadowfacts.phycon.PhysicalConnectivity import net.shadowfacts.phycon.block.cable.CableBlock import net.shadowfacts.phycon.client.util.bakeRecoloredCable import net.shadowfacts.phycon.util.CableConnection import java.util.Random import java.util.function.Function /** * @author shadowfacts */ class ColoredCableModel( val color: DyeColor, ): UnbakedModel, BakedModel { companion object { val SIDE = Identifier(PhysicalConnectivity.MODID, "block/cable_side") val CENTER = Identifier(PhysicalConnectivity.MODID, "block/cable_center") val DIAG_CORNER = Identifier(PhysicalConnectivity.MODID, "block/cable_diag_corner") val DIAG_CORNER_CONT = Identifier(PhysicalConnectivity.MODID, "block/cable_diag_corner_cont") val DIAG_CORNER_XZ = Identifier(PhysicalConnectivity.MODID, "block/cable_diag_corner_xz") val DIAG_CORNER_XZ_CONT = Identifier(PhysicalConnectivity.MODID, "block/cable_diag_corner_xz_cont") } private var centerSprite: Sprite? = null private var side: Array = Array(6) { null } private var center: Array = Array(6) { null } private var diagCorner = mutableMapOf() private var diagCornerCont = mutableMapOf() private var diagCornerXZ = mutableMapOf() private var diagCornerXZCont = mutableMapOf() private val sideRotations = listOf( Direction.DOWN to ModelRotation.X0_Y0, Direction.UP to ModelRotation.X180_Y0, Direction.NORTH to ModelRotation.X270_Y0, Direction.SOUTH to ModelRotation.X90_Y0, Direction.WEST to ModelRotation.X90_Y90, Direction.EAST to ModelRotation.X90_Y270, ) override fun getModelDependencies(): Collection { return setOf( SIDE, CENTER, DIAG_CORNER, DIAG_CORNER_CONT, DIAG_CORNER_XZ, DIAG_CORNER_XZ_CONT, ) } override fun getTextureDependencies( unbakedModelGetter: Function, unresolvedTextureDependencies: MutableSet> ): Collection { val newSet = mutableSetOf>() val res = modelDependencies.map(unbakedModelGetter::apply).flatMap { it.getTextureDependencies(unbakedModelGetter, newSet) } unresolvedTextureDependencies.addAll(newSet) return res.map { if (it.textureId.namespace == PhysicalConnectivity.MODID && it.textureId.path.startsWith("block/cable/color/")) { val newPath = it.textureId.path.replace("block/cable/color/", "block/cable/${color.getName()}/") SpriteIdentifier(it.atlasId, Identifier(PhysicalConnectivity.MODID, newPath)) } else { it } } } override fun bake( loader: ModelLoader, textureGetter: Function, rotationContainer: ModelBakeSettings, modelId: Identifier ): BakedModel { centerSprite = textureGetter.apply(SpriteIdentifier(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE, Identifier(PhysicalConnectivity.MODID, "block/cable/${color.getName()}/straight"))) sideRotations.forEach { (side, rot) -> this.side[side.ordinal] = loader.bakeRecoloredCable(SIDE, rot, textureGetter, color) this.center[side.ordinal] = loader.bakeRecoloredCable(CENTER, rot, textureGetter, color) } diagCorner.clear() diagCornerCont.clear() listOf( ModelRotation.X0_Y0, ModelRotation.X0_Y180, ModelRotation.X180_Y180, ModelRotation.X180_Y0, ModelRotation.X0_Y270, ModelRotation.X0_Y90, ModelRotation.X180_Y90, ModelRotation.X180_Y270, ).forEach { rot -> diagCorner[rot] = loader.bakeRecoloredCable(DIAG_CORNER, rot, textureGetter, color) diagCornerCont[rot] = loader.bakeRecoloredCable(DIAG_CORNER_CONT, rot, textureGetter, color) } diagCornerXZ.clear() diagCornerXZCont.clear() listOf( ModelRotation.X0_Y0, ModelRotation.X0_Y90, ModelRotation.X0_Y180, ModelRotation.X0_Y270, ).forEach { rot -> diagCornerXZ[rot] = loader.bakeRecoloredCable(DIAG_CORNER_XZ, rot, textureGetter, color) diagCornerXZCont[rot] = loader.bakeRecoloredCable(DIAG_CORNER_XZ_CONT, rot, textureGetter, color) } return this } override fun getQuads(state: BlockState?, face: Direction?, random: Random): List { if (state == null) { return center.flatMap { it?.getQuads(state, face, random) ?: listOf() } } val quads = mutableListOf() fun addModel(model: BakedModel?) { if (model == null) return quads.addAll(model.getQuads(state, face, random)) } for ((side, prop) in CableBlock.CONNECTIONS) { if (state[prop] == CableConnection.ON) { addModel(this.side[side.ordinal]) } else { addModel(this.center[side.ordinal]) } } val down = state[CableBlock.CONNECTIONS[Direction.DOWN]] == CableConnection.ON val up = state[CableBlock.CONNECTIONS[Direction.UP]] == CableConnection.ON val north = state[CableBlock.CONNECTIONS[Direction.NORTH]] == CableConnection.ON val south = state[CableBlock.CONNECTIONS[Direction.SOUTH]] == CableConnection.ON val west = state[CableBlock.CONNECTIONS[Direction.WEST]] == CableConnection.ON val east = state[CableBlock.CONNECTIONS[Direction.EAST]] == CableConnection.ON if (!down && !north) { if (up && south && !east && !west) { addModel(diagCornerCont[ModelRotation.X0_Y0]) } else { addModel(diagCorner[ModelRotation.X0_Y0]) } } if (!down && !south) { if (up && north && !east && !west) { addModel(diagCornerCont[ModelRotation.X0_Y180]) } else { addModel(diagCorner[ModelRotation.X0_Y180]) } } if (!up && !north) { if (down && south && !east && !west) { addModel(diagCornerCont[ModelRotation.X180_Y180]) } else { addModel(diagCorner[ModelRotation.X180_Y180]) } } if (!up && !south) { if (down && north && !east && !west) { addModel(diagCornerCont[ModelRotation.X180_Y0]) } else { addModel(diagCorner[ModelRotation.X180_Y0]) } } if (!down && !west) { if (up && east && !north && !south) { addModel(diagCornerCont[ModelRotation.X0_Y270]) } else { addModel(diagCorner[ModelRotation.X0_Y270]) } } if (!down && !east) { if (up && west && !north && !south) { addModel(diagCornerCont[ModelRotation.X0_Y90]) } else { addModel(diagCorner[ModelRotation.X0_Y90]) } } if (!up && !west) { if (down && east && !north && !south) { addModel(diagCornerCont[ModelRotation.X180_Y90]) } else { addModel(diagCorner[ModelRotation.X180_Y90]) } } if (!up && !east) { if (down && west && !north && !south) { addModel(diagCornerCont[ModelRotation.X180_Y270]) } else { addModel(diagCorner[ModelRotation.X180_Y270]) } } if (!north && !west) { if (south && east && !down && !up) { addModel(diagCornerXZCont[ModelRotation.X0_Y0]) } else { addModel(diagCornerXZ[ModelRotation.X0_Y0]) } } if (!north && !east) { if (south && west && !down && !up) { addModel(diagCornerXZCont[ModelRotation.X0_Y90]) } else { addModel(diagCornerXZ[ModelRotation.X0_Y90]) } } if (!south && !east) { if (north && west && !down && !up) { addModel(diagCornerXZCont[ModelRotation.X0_Y180]) } else { addModel(diagCornerXZ[ModelRotation.X0_Y180]) } } if (!south && !west) { if (north && east && !down && !up) { addModel(diagCornerXZCont[ModelRotation.X0_Y270]) } else { addModel(diagCornerXZ[ModelRotation.X0_Y270]) } } return quads } override fun useAmbientOcclusion() = true override fun hasDepth() = false override fun isSideLit() = false override fun isBuiltin() = false override fun getParticleSprite() = centerSprite override fun getTransformation() = null override fun getOverrides() = null }