package net.shadowfacts.phycon.client.model import net.minecraft.block.BlockState import net.minecraft.client.render.model.* import net.minecraft.client.texture.Sprite import net.minecraft.client.util.SpriteIdentifier import net.minecraft.util.Identifier import net.minecraft.util.math.Direction import net.shadowfacts.phycon.PhysicalConnectivity import net.shadowfacts.phycon.block.FaceDeviceBlock import net.shadowfacts.phycon.block.FaceDeviceBlock.FaceCableConnection import java.util.Random import java.util.function.Function /** * @author shadowfacts */ abstract class FaceDeviceModel: UnbakedModel, BakedModel { private val interfaceCableStraightID = Identifier(PhysicalConnectivity.MODID, "block/interface_cable_straight") private val interfaceCableCornerID = Identifier(PhysicalConnectivity.MODID, "block/interface_cable_corner") private val interfaceCableCorner2ID = Identifier(PhysicalConnectivity.MODID, "block/interface_cable_corner_2") private val interfaceCableCapID = Identifier(PhysicalConnectivity.MODID, "block/interface_cable_cap") private var interfaceCableStraight = Array(6) { null } private var interfaceCableCap = Array(6) { null } private var interfaceCableCorner = mutableMapOf() private var interfaceCableCorner2 = mutableMapOf() protected val defaultRotations = listOf( ModelRotation.X0_Y0, ModelRotation.X180_Y0, ModelRotation.X90_Y180, ModelRotation.X90_Y0, ModelRotation.X90_Y90, ModelRotation.X90_Y270, ) abstract fun getSideModelIDs(): Collection abstract fun bakeSideModels(loader: ModelLoader) abstract fun getSideModel(state: BlockState): BakedModel? override fun getModelDependencies(): Collection { return getSideModelIDs() + listOf( interfaceCableStraightID, interfaceCableCornerID, interfaceCableCorner2ID, interfaceCableCapID ) } override fun getTextureDependencies( unbakedModelGetter: Function, unresolvedTextureReferences: MutableSet> ): Collection { return modelDependencies.map(unbakedModelGetter::apply).flatMap { it.getTextureDependencies(unbakedModelGetter, unresolvedTextureReferences) } } override fun bake(loader: ModelLoader, textureGetter: Function, rotationContainer: ModelBakeSettings, modelId: Identifier): BakedModel { bakeSideModels(loader) defaultRotations.forEachIndexed { i, rot -> interfaceCableStraight[i] = loader.bake(interfaceCableStraightID, rot) interfaceCableCap[i] = loader.bake(interfaceCableCapID, rot) } mapOf( interfaceCableCorner to interfaceCableCornerID to ModelRotation.values().toList(), interfaceCableCorner2 to interfaceCableCorner2ID to listOf( ModelRotation.X0_Y0, ModelRotation.X0_Y90, ModelRotation.X0_Y180, ModelRotation.X0_Y270, ModelRotation.X180_Y0, ModelRotation.X180_Y90, ModelRotation.X180_Y180, ModelRotation.X180_Y270, ), ).forEach { (k, rotations) -> val (map, id) = k map.clear() rotations.forEach { rot -> val model = loader.bake(id, rot) if (model == null) map.remove(rot) else map[rot] = model } } return this } override fun getQuads(state: BlockState?, face: Direction?, random: Random): List { if (state == null) return listOf() val facing = state[FaceDeviceBlock.FACING] val connection = state[FaceDeviceBlock.CABLE_CONNECTION] val sideQuads = getSideModel(state)?.getQuads(state, face, random) ?: listOf() val cableQuads = if (connection.direction == facing.opposite) { interfaceCableStraight[facing.ordinal]?.getQuads(state, face, random) ?: listOf() } else if (connection == FaceCableConnection.NONE) { interfaceCableCap[facing.ordinal]?.getQuads(state, face, random) ?: listOf() } else { val model = when (facing) { Direction.DOWN -> when (connection) { FaceCableConnection.NORTH -> interfaceCableCorner[ModelRotation.X0_Y0] FaceCableConnection.EAST -> interfaceCableCorner[ModelRotation.X0_Y90] FaceCableConnection.SOUTH -> interfaceCableCorner[ModelRotation.X0_Y180] FaceCableConnection.WEST -> interfaceCableCorner[ModelRotation.X0_Y270] else -> null } Direction.UP -> when (connection) { FaceCableConnection.NORTH -> interfaceCableCorner[ModelRotation.X180_Y180] FaceCableConnection.EAST -> interfaceCableCorner[ModelRotation.X180_Y270] FaceCableConnection.SOUTH -> interfaceCableCorner[ModelRotation.X180_Y0] FaceCableConnection.WEST -> interfaceCableCorner[ModelRotation.X180_Y90] else -> null } Direction.NORTH -> when (connection) { FaceCableConnection.UP -> interfaceCableCorner[ModelRotation.X270_Y0] FaceCableConnection.EAST -> interfaceCableCorner2[ModelRotation.X180_Y180] FaceCableConnection.DOWN -> interfaceCableCorner[ModelRotation.X90_Y180] FaceCableConnection.WEST -> interfaceCableCorner2[ModelRotation.X0_Y0] else -> null } Direction.SOUTH -> when (connection) { FaceCableConnection.UP -> interfaceCableCorner[ModelRotation.X270_Y180] FaceCableConnection.WEST -> interfaceCableCorner2[ModelRotation.X180_Y0] FaceCableConnection.DOWN -> interfaceCableCorner[ModelRotation.X90_Y0] FaceCableConnection.EAST -> interfaceCableCorner2[ModelRotation.X0_Y180] else -> null } Direction.WEST -> when (connection) { FaceCableConnection.UP -> interfaceCableCorner[ModelRotation.X270_Y270] FaceCableConnection.NORTH -> interfaceCableCorner2[ModelRotation.X180_Y90] FaceCableConnection.DOWN -> interfaceCableCorner[ModelRotation.X90_Y90] FaceCableConnection.SOUTH -> interfaceCableCorner2[ModelRotation.X0_Y270] else -> null } Direction.EAST -> when (connection) { FaceCableConnection.UP -> interfaceCableCorner[ModelRotation.X270_Y90] FaceCableConnection.SOUTH -> interfaceCableCorner2[ModelRotation.X180_Y270] FaceCableConnection.DOWN -> interfaceCableCorner[ModelRotation.X90_Y270] FaceCableConnection.NORTH -> interfaceCableCorner2[ModelRotation.X0_Y90] else -> null } else -> null } model?.getQuads(state, face, random) ?: listOf() } return sideQuads + cableQuads } override fun useAmbientOcclusion() = true override fun hasDepth() = false override fun isSideLit() = false override fun isBuiltin() = false abstract override fun getSprite(): Sprite override fun getTransformation() = null override fun getOverrides() = null }