Add cable colors to face device blocks

This commit is contained in:
Shadowfacts 2021-03-15 18:30:35 -04:00
parent 611c4bb0ae
commit bc50017b4a
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
105 changed files with 179 additions and 112 deletions

View File

@ -7,6 +7,7 @@ import net.minecraft.item.ItemPlacementContext
import net.minecraft.state.StateManager import net.minecraft.state.StateManager
import net.minecraft.state.property.EnumProperty import net.minecraft.state.property.EnumProperty
import net.minecraft.state.property.Properties import net.minecraft.state.property.Properties
import net.minecraft.util.DyeColor
import net.minecraft.util.StringIdentifiable import net.minecraft.util.StringIdentifiable
import net.minecraft.util.math.BlockPos import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction import net.minecraft.util.math.Direction
@ -28,6 +29,7 @@ abstract class FaceDeviceBlock<T: DeviceBlockEntity>(settings: Settings): Device
companion object { companion object {
val FACING = Properties.FACING val FACING = Properties.FACING
val CABLE_CONNECTION = EnumProperty.of("cable_connection", FaceCableConnection::class.java) val CABLE_CONNECTION = EnumProperty.of("cable_connection", FaceCableConnection::class.java)
val COLOR = EnumProperty.of("color", DyeColor::class.java)
} }
enum class FaceCableConnection : StringIdentifiable { enum class FaceCableConnection : StringIdentifiable {
@ -100,44 +102,56 @@ abstract class FaceDeviceBlock<T: DeviceBlockEntity>(settings: Settings): Device
super.appendProperties(builder) super.appendProperties(builder)
builder.add(FACING) builder.add(FACING)
builder.add(CABLE_CONNECTION) builder.add(CABLE_CONNECTION)
builder.add(COLOR)
} }
override fun getPlacementState(context: ItemPlacementContext): BlockState { override fun getPlacementState(context: ItemPlacementContext): BlockState {
val facing = if (context.player?.isSneaking == true) context.side.opposite else context.playerLookDirection.opposite val facing = if (context.player?.isSneaking == true) context.side.opposite else context.playerLookDirection.opposite
val cableConnection = FaceCableConnection.from(getCableConnectedSide(context.world, context.blockPos, facing)) // todo: this should never be called
val cableConnection = FaceCableConnection.from(getCableConnectedSide(context.world, context.blockPos, facing, DyeColor.BLUE))
return defaultState return defaultState
.with(FACING, facing) .with(FACING, facing)
.with(CABLE_CONNECTION, cableConnection) .with(CABLE_CONNECTION, cableConnection)
} }
private fun getCableConnectedSide(world: WorldAccess, pos: BlockPos, facing: Direction): Direction? { private fun getCableConnectedSide(world: WorldAccess, pos: BlockPos, facing: Direction, color: DyeColor): Direction? {
for (side in Direction.values()) { for (side in Direction.values()) {
if (side == facing) { if (side == facing) {
continue continue
} }
val offsetPos = pos.offset(side) val offsetPos = pos.offset(side)
val state = world.getBlockState(offsetPos) val state = world.getBlockState(offsetPos)
val block = state.block if (canConnectTo(world, side, state, offsetPos, color)) {
if (block is NetworkComponentBlock && block.getNetworkConnectedSides(state, world, offsetPos).contains(side.opposite)) {
return side return side
} }
} }
return null return null
} }
private fun canConnectTo(world: WorldAccess, side: Direction, candidateState: BlockState, candidatePos: BlockPos, myColor: DyeColor): Boolean {
val block = candidateState.block
return if (block is FaceDeviceBlock<*> && candidateState[COLOR] == myColor) {
true
} else if (block is CableBlock && block.color == myColor) {
true
} else {
block is NetworkComponentBlock && block.getNetworkConnectedSides(candidateState, world, candidatePos).contains(side.opposite)
}
}
override fun getStateForNeighborUpdate(state: BlockState, side: Direction, neighborState: BlockState, world: WorldAccess, pos: BlockPos, neighborPos: BlockPos): BlockState { override fun getStateForNeighborUpdate(state: BlockState, side: Direction, neighborState: BlockState, world: WorldAccess, pos: BlockPos, neighborPos: BlockPos): BlockState {
val current = state[CABLE_CONNECTION] val current = state[CABLE_CONNECTION]
var newConnection = current var newConnection = current
if (current == FaceCableConnection.NONE) { if (current == FaceCableConnection.NONE) {
if (neighborState.block is NetworkComponentBlock) { if (canConnectTo(world, side, neighborState, neighborPos, state[COLOR])) {
newConnection = FaceCableConnection.from(side) newConnection = FaceCableConnection.from(side)
} }
} else { } else {
val currentConnectedPos = pos.offset(current.direction) val currentConnectedPos = pos.offset(current.direction)
if (neighborPos == currentConnectedPos && neighborState.block !is NetworkComponentBlock) { if (neighborPos == currentConnectedPos && neighborState.block !is NetworkComponentBlock) {
// the old cable connection is no longer correct, try to find another // the old cable connection is no longer correct, try to find another
newConnection = FaceCableConnection.from(getCableConnectedSide(world, pos, state[FACING])) newConnection = FaceCableConnection.from(getCableConnectedSide(world, pos, state[FACING], state[COLOR]))
} }
} }
return state.with(CABLE_CONNECTION, newConnection) return state.with(CABLE_CONNECTION, newConnection)

View File

@ -3,8 +3,6 @@ package net.shadowfacts.phycon.client.model
import com.mojang.datafixers.util.Pair import com.mojang.datafixers.util.Pair
import net.minecraft.block.BlockState import net.minecraft.block.BlockState
import net.minecraft.client.render.model.* import net.minecraft.client.render.model.*
import net.minecraft.client.render.model.json.ModelOverrideList
import net.minecraft.client.render.model.json.ModelTransformation
import net.minecraft.client.texture.Sprite import net.minecraft.client.texture.Sprite
import net.minecraft.client.texture.SpriteAtlasTexture import net.minecraft.client.texture.SpriteAtlasTexture
import net.minecraft.client.util.SpriteIdentifier import net.minecraft.client.util.SpriteIdentifier
@ -13,6 +11,7 @@ import net.minecraft.util.Identifier
import net.minecraft.util.math.Direction import net.minecraft.util.math.Direction
import net.shadowfacts.phycon.PhysicalConnectivity import net.shadowfacts.phycon.PhysicalConnectivity
import net.shadowfacts.phycon.block.cable.CableBlock import net.shadowfacts.phycon.block.cable.CableBlock
import net.shadowfacts.phycon.client.util.bakeRecoloredCable
import net.shadowfacts.phycon.util.CableConnection import net.shadowfacts.phycon.util.CableConnection
import java.util.Random import java.util.Random
import java.util.function.Function import java.util.function.Function
@ -89,8 +88,8 @@ class ColoredCableModel(
centerSprite = textureGetter.apply(SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, Identifier(PhysicalConnectivity.MODID, "block/cable/${color.getName()}/straight"))) centerSprite = textureGetter.apply(SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, Identifier(PhysicalConnectivity.MODID, "block/cable/${color.getName()}/straight")))
sideRotations.forEach { (side, rot) -> sideRotations.forEach { (side, rot) ->
this.side[side.ordinal] = loader.bakeRetextured(SIDE, textureGetter, rot) this.side[side.ordinal] = loader.bakeRecoloredCable(SIDE, rot, textureGetter, color)
this.center[side.ordinal] = loader.bakeRetextured(CENTER, textureGetter, rot) this.center[side.ordinal] = loader.bakeRecoloredCable(CENTER, rot, textureGetter, color)
} }
diagCorner.clear() diagCorner.clear()
@ -105,8 +104,8 @@ class ColoredCableModel(
ModelRotation.X180_Y90, ModelRotation.X180_Y90,
ModelRotation.X180_Y270, ModelRotation.X180_Y270,
).forEach { rot -> ).forEach { rot ->
diagCorner[rot] = loader.bakeRetextured(DIAG_CORNER, textureGetter, rot) diagCorner[rot] = loader.bakeRecoloredCable(DIAG_CORNER, rot, textureGetter, color)
diagCornerCont[rot] = loader.bakeRetextured(DIAG_CORNER_CONT, textureGetter, rot) diagCornerCont[rot] = loader.bakeRecoloredCable(DIAG_CORNER_CONT, rot, textureGetter, color)
} }
diagCornerXZ.clear() diagCornerXZ.clear()
@ -117,26 +116,13 @@ class ColoredCableModel(
ModelRotation.X0_Y180, ModelRotation.X0_Y180,
ModelRotation.X0_Y270, ModelRotation.X0_Y270,
).forEach { rot -> ).forEach { rot ->
diagCornerXZ[rot] = loader.bakeRetextured(DIAG_CORNER_XZ, textureGetter, rot) diagCornerXZ[rot] = loader.bakeRecoloredCable(DIAG_CORNER_XZ, rot, textureGetter, color)
diagCornerXZCont[rot] = loader.bakeRetextured(DIAG_CORNER_XZ_CONT, textureGetter, rot) diagCornerXZCont[rot] = loader.bakeRecoloredCable(DIAG_CORNER_XZ_CONT, rot, textureGetter, color)
} }
return this return this
} }
private fun ModelLoader.bakeRetextured(id: Identifier, textureGetter: Function<SpriteIdentifier, Sprite>, rot: ModelRotation): BakedModel {
val unbaked = getOrLoadModel(id)
val wrappedTextureGetter: (SpriteIdentifier) -> Sprite = {
var newId = it
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()}/")
newId = SpriteIdentifier(it.atlasId, Identifier(PhysicalConnectivity.MODID, newPath))
}
textureGetter.apply(newId)
}
return unbaked.bake(this, wrappedTextureGetter, rot, id)!!
}
override fun getQuads(state: BlockState?, face: Direction?, random: Random): List<BakedQuad> { override fun getQuads(state: BlockState?, face: Direction?, random: Random): List<BakedQuad> {
if (state == null) { if (state == null) {
return center.flatMap { return center.flatMap {

View File

@ -4,11 +4,13 @@ import net.minecraft.block.BlockState
import net.minecraft.client.render.model.* import net.minecraft.client.render.model.*
import net.minecraft.client.texture.Sprite import net.minecraft.client.texture.Sprite
import net.minecraft.client.util.SpriteIdentifier import net.minecraft.client.util.SpriteIdentifier
import net.minecraft.util.DyeColor
import net.minecraft.util.Identifier import net.minecraft.util.Identifier
import net.minecraft.util.math.Direction import net.minecraft.util.math.Direction
import net.shadowfacts.phycon.PhysicalConnectivity import net.shadowfacts.phycon.PhysicalConnectivity
import net.shadowfacts.phycon.block.FaceDeviceBlock import net.shadowfacts.phycon.block.FaceDeviceBlock
import net.shadowfacts.phycon.block.FaceDeviceBlock.FaceCableConnection import net.shadowfacts.phycon.block.FaceDeviceBlock.FaceCableConnection
import net.shadowfacts.phycon.client.util.bakeRecoloredCable
import java.util.Random import java.util.Random
import java.util.function.Function import java.util.function.Function
@ -21,10 +23,14 @@ abstract class FaceDeviceModel: UnbakedModel, BakedModel {
private val interfaceCableCornerID = Identifier(PhysicalConnectivity.MODID, "block/interface_cable_corner") private val interfaceCableCornerID = Identifier(PhysicalConnectivity.MODID, "block/interface_cable_corner")
private val interfaceCableCorner2ID = Identifier(PhysicalConnectivity.MODID, "block/interface_cable_corner_2") private val interfaceCableCorner2ID = Identifier(PhysicalConnectivity.MODID, "block/interface_cable_corner_2")
private val interfaceCableCapID = Identifier(PhysicalConnectivity.MODID, "block/interface_cable_cap") private val interfaceCableCapID = Identifier(PhysicalConnectivity.MODID, "block/interface_cable_cap")
private var interfaceCableStraight = Array<BakedModel?>(6) { null } // private var interfaceCableStraight = Array<BakedModel?>(6) { null }
private var interfaceCableCap = Array<BakedModel?>(6) { null } // private var interfaceCableCap = Array<BakedModel?>(6) { null }
private var interfaceCableCorner = mutableMapOf<ModelRotation, BakedModel>() // private var interfaceCableCorner = mutableMapOf<ModelRotation, BakedModel>()
private var interfaceCableCorner2 = mutableMapOf<ModelRotation, BakedModel>() // private var interfaceCableCorner2 = mutableMapOf<ModelRotation, BakedModel>()
private var interfaceCableStraight = mutableMapOf<DyeColor, Array<BakedModel>>()
private var interfaceCableCap = mutableMapOf<DyeColor, Array<BakedModel>>()
private var interfaceCableCorner = mutableMapOf<DyeColor, MutableMap<ModelRotation, BakedModel>>()
private var interfaceCableCorner2 = mutableMapOf<DyeColor, MutableMap<ModelRotation, BakedModel>>()
protected val defaultRotations = listOf( protected val defaultRotations = listOf(
ModelRotation.X0_Y0, ModelRotation.X0_Y0,
@ -36,7 +42,7 @@ abstract class FaceDeviceModel: UnbakedModel, BakedModel {
) )
abstract fun getSideModelIDs(): Collection<Identifier> abstract fun getSideModelIDs(): Collection<Identifier>
abstract fun bakeSideModels(loader: ModelLoader) abstract fun bakeSideModels(loader: ModelLoader, textureGetter: Function<SpriteIdentifier, Sprite>)
abstract fun getSideModel(state: BlockState): BakedModel? abstract fun getSideModel(state: BlockState): BakedModel?
override fun getModelDependencies(): Collection<Identifier> { override fun getModelDependencies(): Collection<Identifier> {
@ -52,36 +58,54 @@ abstract class FaceDeviceModel: UnbakedModel, BakedModel {
unbakedModelGetter: Function<Identifier, UnbakedModel>, unbakedModelGetter: Function<Identifier, UnbakedModel>,
unresolvedTextureReferences: MutableSet<com.mojang.datafixers.util.Pair<String, String>> unresolvedTextureReferences: MutableSet<com.mojang.datafixers.util.Pair<String, String>>
): Collection<SpriteIdentifier> { ): Collection<SpriteIdentifier> {
return modelDependencies.map(unbakedModelGetter::apply).flatMap { it.getTextureDependencies(unbakedModelGetter, unresolvedTextureReferences) } val textures = mutableListOf<SpriteIdentifier>()
for (dep in modelDependencies) {
val unbakedDep = unbakedModelGetter.apply(dep)
val depTextures = unbakedDep.getTextureDependencies(unbakedModelGetter, unresolvedTextureReferences)
for (tex in depTextures) {
if (tex.textureId.namespace == PhysicalConnectivity.MODID && tex.textureId.path.startsWith("block/cable/color/")) {
for (color in DyeColor.values()) {
val newPath = tex.textureId.path.replace("block/cable/color/", "block/cable/${color.getName()}/")
val substituted = SpriteIdentifier(tex.atlasId, Identifier(PhysicalConnectivity.MODID, newPath))
textures.add(substituted)
}
} else {
textures.add(tex)
}
}
}
return textures
} }
override fun bake(loader: ModelLoader, textureGetter: Function<SpriteIdentifier, Sprite>, rotationContainer: ModelBakeSettings, modelId: Identifier): BakedModel { override fun bake(loader: ModelLoader, textureGetter: Function<SpriteIdentifier, Sprite>, rotationContainer: ModelBakeSettings, modelId: Identifier): BakedModel {
bakeSideModels(loader) bakeSideModels(loader, textureGetter)
defaultRotations.forEachIndexed { i, rot -> DyeColor.values().forEach { color ->
interfaceCableStraight[i] = loader.bake(interfaceCableStraightID, rot) interfaceCableStraight[color] = Array(6) { i ->
interfaceCableCap[i] = loader.bake(interfaceCableCapID, rot) loader.bakeRecoloredCable(interfaceCableStraightID, defaultRotations[i], textureGetter, color)
} }
interfaceCableCap[color] = Array(6) { i ->
loader.bakeRecoloredCable(interfaceCableCapID, defaultRotations[i], textureGetter, color)
}
mapOf( mapOf(
interfaceCableCorner to interfaceCableCornerID to ModelRotation.values().toList(), interfaceCableCorner to interfaceCableCornerID to ModelRotation.values().toList(),
interfaceCableCorner2 to interfaceCableCorner2ID to listOf( interfaceCableCorner2 to interfaceCableCorner2ID to listOf(
ModelRotation.X0_Y0, ModelRotation.X0_Y0,
ModelRotation.X0_Y90, ModelRotation.X0_Y90,
ModelRotation.X0_Y180, ModelRotation.X0_Y180,
ModelRotation.X0_Y270, ModelRotation.X0_Y270,
ModelRotation.X180_Y0, ModelRotation.X180_Y0,
ModelRotation.X180_Y90, ModelRotation.X180_Y90,
ModelRotation.X180_Y180, ModelRotation.X180_Y180,
ModelRotation.X180_Y270, ModelRotation.X180_Y270,
), ),
).forEach { (k, rotations) -> ).forEach { (k, rotations) ->
val (map, id) = k val (map, id) = k
map.clear() map[color] = mutableMapOf()
rotations.forEach { rot -> rotations.forEach { rot ->
val model = loader.bake(id, rot) map[color]!![rot] = loader.bakeRecoloredCable(id, rot, textureGetter, color)
if (model == null) map.remove(rot) }
else map[rot] = model
} }
} }
@ -92,54 +116,55 @@ abstract class FaceDeviceModel: UnbakedModel, BakedModel {
if (state == null) return listOf() if (state == null) return listOf()
val facing = state[FaceDeviceBlock.FACING] val facing = state[FaceDeviceBlock.FACING]
val connection = state[FaceDeviceBlock.CABLE_CONNECTION] val connection = state[FaceDeviceBlock.CABLE_CONNECTION]
val color = state[FaceDeviceBlock.COLOR]
val sideQuads = getSideModel(state)?.getQuads(state, face, random) ?: listOf() val sideQuads = getSideModel(state)?.getQuads(state, face, random) ?: listOf()
val cableQuads = if (connection.direction == facing.opposite) { val cableQuads = if (connection.direction == facing.opposite) {
interfaceCableStraight[facing.ordinal]?.getQuads(state, face, random) ?: listOf() interfaceCableStraight[color]!![facing.ordinal]?.getQuads(state, face, random) ?: listOf()
} else if (connection == FaceCableConnection.NONE) { } else if (connection == FaceCableConnection.NONE) {
interfaceCableCap[facing.ordinal]?.getQuads(state, face, random) ?: listOf() interfaceCableCap[color]!![facing.ordinal]?.getQuads(state, face, random) ?: listOf()
} else { } else {
val model = when (facing) { val model = when (facing) {
Direction.DOWN -> when (connection) { Direction.DOWN -> when (connection) {
FaceCableConnection.NORTH -> interfaceCableCorner[ModelRotation.X0_Y0] FaceCableConnection.NORTH -> interfaceCableCorner[color]!![ModelRotation.X0_Y0]
FaceCableConnection.EAST -> interfaceCableCorner[ModelRotation.X0_Y90] FaceCableConnection.EAST -> interfaceCableCorner[color]!![ModelRotation.X0_Y90]
FaceCableConnection.SOUTH -> interfaceCableCorner[ModelRotation.X0_Y180] FaceCableConnection.SOUTH -> interfaceCableCorner[color]!![ModelRotation.X0_Y180]
FaceCableConnection.WEST -> interfaceCableCorner[ModelRotation.X0_Y270] FaceCableConnection.WEST -> interfaceCableCorner[color]!![ModelRotation.X0_Y270]
else -> null else -> null
} }
Direction.UP -> when (connection) { Direction.UP -> when (connection) {
FaceCableConnection.NORTH -> interfaceCableCorner[ModelRotation.X180_Y180] FaceCableConnection.NORTH -> interfaceCableCorner[color]!![ModelRotation.X180_Y180]
FaceCableConnection.EAST -> interfaceCableCorner[ModelRotation.X180_Y270] FaceCableConnection.EAST -> interfaceCableCorner[color]!![ModelRotation.X180_Y270]
FaceCableConnection.SOUTH -> interfaceCableCorner[ModelRotation.X180_Y0] FaceCableConnection.SOUTH -> interfaceCableCorner[color]!![ModelRotation.X180_Y0]
FaceCableConnection.WEST -> interfaceCableCorner[ModelRotation.X180_Y90] FaceCableConnection.WEST -> interfaceCableCorner[color]!![ModelRotation.X180_Y90]
else -> null else -> null
} }
Direction.NORTH -> when (connection) { Direction.NORTH -> when (connection) {
FaceCableConnection.UP -> interfaceCableCorner[ModelRotation.X270_Y0] FaceCableConnection.UP -> interfaceCableCorner[color]!![ModelRotation.X270_Y0]
FaceCableConnection.EAST -> interfaceCableCorner2[ModelRotation.X180_Y180] FaceCableConnection.EAST -> interfaceCableCorner2[color]!![ModelRotation.X180_Y180]
FaceCableConnection.DOWN -> interfaceCableCorner[ModelRotation.X90_Y180] FaceCableConnection.DOWN -> interfaceCableCorner[color]!![ModelRotation.X90_Y180]
FaceCableConnection.WEST -> interfaceCableCorner2[ModelRotation.X0_Y0] FaceCableConnection.WEST -> interfaceCableCorner2[color]!![ModelRotation.X0_Y0]
else -> null else -> null
} }
Direction.SOUTH -> when (connection) { Direction.SOUTH -> when (connection) {
FaceCableConnection.UP -> interfaceCableCorner[ModelRotation.X270_Y180] FaceCableConnection.UP -> interfaceCableCorner[color]!![ModelRotation.X270_Y180]
FaceCableConnection.WEST -> interfaceCableCorner2[ModelRotation.X180_Y0] FaceCableConnection.WEST -> interfaceCableCorner2[color]!![ModelRotation.X180_Y0]
FaceCableConnection.DOWN -> interfaceCableCorner[ModelRotation.X90_Y0] FaceCableConnection.DOWN -> interfaceCableCorner[color]!![ModelRotation.X90_Y0]
FaceCableConnection.EAST -> interfaceCableCorner2[ModelRotation.X0_Y180] FaceCableConnection.EAST -> interfaceCableCorner2[color]!![ModelRotation.X0_Y180]
else -> null else -> null
} }
Direction.WEST -> when (connection) { Direction.WEST -> when (connection) {
FaceCableConnection.UP -> interfaceCableCorner[ModelRotation.X270_Y270] FaceCableConnection.UP -> interfaceCableCorner[color]!![ModelRotation.X270_Y270]
FaceCableConnection.NORTH -> interfaceCableCorner2[ModelRotation.X180_Y90] FaceCableConnection.NORTH -> interfaceCableCorner2[color]!![ModelRotation.X180_Y90]
FaceCableConnection.DOWN -> interfaceCableCorner[ModelRotation.X90_Y90] FaceCableConnection.DOWN -> interfaceCableCorner[color]!![ModelRotation.X90_Y90]
FaceCableConnection.SOUTH -> interfaceCableCorner2[ModelRotation.X0_Y270] FaceCableConnection.SOUTH -> interfaceCableCorner2[color]!![ModelRotation.X0_Y270]
else -> null else -> null
} }
Direction.EAST -> when (connection) { Direction.EAST -> when (connection) {
FaceCableConnection.UP -> interfaceCableCorner[ModelRotation.X270_Y90] FaceCableConnection.UP -> interfaceCableCorner[color]!![ModelRotation.X270_Y90]
FaceCableConnection.SOUTH -> interfaceCableCorner2[ModelRotation.X180_Y270] FaceCableConnection.SOUTH -> interfaceCableCorner2[color]!![ModelRotation.X180_Y270]
FaceCableConnection.DOWN -> interfaceCableCorner[ModelRotation.X90_Y270] FaceCableConnection.DOWN -> interfaceCableCorner[color]!![ModelRotation.X90_Y270]
FaceCableConnection.NORTH -> interfaceCableCorner2[ModelRotation.X0_Y90] FaceCableConnection.NORTH -> interfaceCableCorner2[color]!![ModelRotation.X0_Y90]
else -> null else -> null
} }
else -> null else -> null

View File

@ -4,10 +4,12 @@ import net.minecraft.block.BlockState
import net.minecraft.client.render.model.BakedModel import net.minecraft.client.render.model.BakedModel
import net.minecraft.client.render.model.ModelLoader import net.minecraft.client.render.model.ModelLoader
import net.minecraft.client.texture.Sprite import net.minecraft.client.texture.Sprite
import net.minecraft.client.util.SpriteIdentifier
import net.minecraft.util.Identifier import net.minecraft.util.Identifier
import net.shadowfacts.phycon.PhysicalConnectivity import net.shadowfacts.phycon.PhysicalConnectivity
import net.shadowfacts.phycon.block.FaceDeviceBlock import net.shadowfacts.phycon.block.FaceDeviceBlock
import net.shadowfacts.phycon.block.redstone_controller.RedstoneControllerBlock import net.shadowfacts.phycon.block.redstone_controller.RedstoneControllerBlock
import java.util.function.Function
/** /**
* @author shadowfacts * @author shadowfacts
@ -23,7 +25,7 @@ object RedstoneControllerModel: FaceDeviceModel() {
return listOf(ON, OFF) return listOf(ON, OFF)
} }
override fun bakeSideModels(loader: ModelLoader) { override fun bakeSideModels(loader: ModelLoader, textureGetter: Function<SpriteIdentifier, Sprite>) {
defaultRotations.forEachIndexed { i, rot -> defaultRotations.forEachIndexed { i, rot ->
onModels[i] = loader.bake(ON, rot) onModels[i] = loader.bake(ON, rot)
offModels[i] = loader.bake(OFF, rot) offModels[i] = loader.bake(OFF, rot)

View File

@ -4,8 +4,12 @@ import net.minecraft.block.BlockState
import net.minecraft.client.render.model.BakedModel import net.minecraft.client.render.model.BakedModel
import net.minecraft.client.render.model.ModelLoader import net.minecraft.client.render.model.ModelLoader
import net.minecraft.client.texture.Sprite import net.minecraft.client.texture.Sprite
import net.minecraft.client.util.SpriteIdentifier
import net.minecraft.util.DyeColor
import net.minecraft.util.Identifier import net.minecraft.util.Identifier
import net.shadowfacts.phycon.block.FaceDeviceBlock import net.shadowfacts.phycon.block.FaceDeviceBlock
import net.shadowfacts.phycon.client.util.bakeRecoloredCable
import java.util.function.Function
/** /**
* @author shadowfacts * @author shadowfacts
@ -13,23 +17,25 @@ import net.shadowfacts.phycon.block.FaceDeviceBlock
class SimpleFaceDeviceModel( class SimpleFaceDeviceModel(
private val sideModelID: Identifier, private val sideModelID: Identifier,
): FaceDeviceModel() { ): FaceDeviceModel() {
private val sideModels = Array<BakedModel?>(6) { null } private val sideModels = mutableMapOf<DyeColor, Array<BakedModel>>()
override fun getSideModelIDs(): Collection<Identifier> { override fun getSideModelIDs(): Collection<Identifier> {
return listOf(sideModelID) return listOf(sideModelID)
} }
override fun bakeSideModels(loader: ModelLoader) { override fun bakeSideModels(loader: ModelLoader, textureGetter: Function<SpriteIdentifier, Sprite>) {
defaultRotations.forEachIndexed { i, rot -> DyeColor.values().forEach { color ->
sideModels[i] = loader.bake(sideModelID, rot) sideModels[color] = Array(6) { i ->
loader.bakeRecoloredCable(sideModelID, defaultRotations[i], textureGetter, color)
}
} }
} }
override fun getSideModel(state: BlockState): BakedModel? { override fun getSideModel(state: BlockState): BakedModel {
return sideModels[state[FaceDeviceBlock.FACING].ordinal] return sideModels[state[FaceDeviceBlock.COLOR]]!![state[FaceDeviceBlock.FACING].ordinal]
} }
override fun getSprite(): Sprite { override fun getSprite(): Sprite {
return sideModels.first()!!.sprite return sideModels[DyeColor.BLACK]!!.first().sprite
} }
} }

View File

@ -0,0 +1,32 @@
package net.shadowfacts.phycon.client.util
import net.minecraft.client.render.model.BakedModel
import net.minecraft.client.render.model.ModelLoader
import net.minecraft.client.render.model.ModelRotation
import net.minecraft.client.texture.Sprite
import net.minecraft.client.util.SpriteIdentifier
import net.minecraft.util.DyeColor
import net.minecraft.util.Identifier
import net.shadowfacts.phycon.PhysicalConnectivity
import java.util.function.Function
/**
* @author shadowfacts
*/
fun ModelLoader.bakeRecoloredCable(
id: Identifier,
rot: ModelRotation,
textureGetter: Function<SpriteIdentifier, Sprite>,
color: DyeColor
): BakedModel {
val unbaked = getOrLoadModel(id)
val wrappedTextureGetter: (SpriteIdentifier) -> Sprite = {
var newId = it
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()}/")
newId = SpriteIdentifier(it.atlasId, Identifier(PhysicalConnectivity.MODID, newPath))
}
textureGetter.apply(newId)
}
return unbaked.bake(this, wrappedTextureGetter, rot, id)!!
}

View File

@ -15,7 +15,8 @@ class FaceDeviceBlockItem(block: FaceDeviceBlock<*>, settings: Settings = Settin
override fun getPlacementState(context: ItemPlacementContext): BlockState? { override fun getPlacementState(context: ItemPlacementContext): BlockState? {
val hitState = context.world.getBlockState(context.blockPos) val hitState = context.world.getBlockState(context.blockPos)
if (hitState.block is CableBlock) { val hitBlock = hitState.block
if (hitBlock is CableBlock) {
val hitBlockEdge = context.hitPos.getComponentAlongAxis(context.side.axis) % 1 == 0.0 val hitBlockEdge = context.hitPos.getComponentAlongAxis(context.side.axis) % 1 == 0.0
val placementSide = if (hitBlockEdge) context.side.opposite else context.side val placementSide = if (hitBlockEdge) context.side.opposite else context.side
@ -32,6 +33,7 @@ class FaceDeviceBlockItem(block: FaceDeviceBlock<*>, settings: Settings = Settin
return block.defaultState return block.defaultState
.with(FaceDeviceBlock.FACING, placementSide) .with(FaceDeviceBlock.FACING, placementSide)
.with(FaceDeviceBlock.CABLE_CONNECTION, connection) .with(FaceDeviceBlock.CABLE_CONNECTION, connection)
.with(FaceDeviceBlock.COLOR, hitBlock.color)
} }
} }
return null return null

View File

@ -1,7 +1,7 @@
{ {
"textures": { "textures": {
"cap": "phycon:block/cable_cap_end", "cap": "phycon:block/cable/color/cap_end",
"straight": "phycon:block/cable_straight" "straight": "phycon:block/cable/color/straight"
}, },
"elements": [ "elements": [
{ {

View File

@ -1,9 +1,9 @@
{ {
"textures": { "textures": {
"straight": "phycon:block/cable_straight", "straight": "phycon:block/cable/color/straight",
"cap": "phycon:block/cable_cap_end", "cap": "phycon:block/cable/color/cap_end",
"corner_r": "phycon:block/interface_cable_corner_r", "corner_r": "phycon:block/cable/color/corner_r_down",
"corner_l": "phycon:block/interface_cable_corner_l" "corner_l": "phycon:block/cable/color/corner_l_down"
}, },
"elements": [ "elements": [
{ {
@ -19,4 +19,4 @@
} }
} }
] ]
} }

View File

@ -1,9 +1,9 @@
{ {
"textures": { "textures": {
"straight": "phycon:block/cable_straight_rotated", "straight": "phycon:block/cable/color/straight_rotated",
"cap": "phycon:block/cable_cap_end", "cap": "phycon:block/cable/color/cap_end",
"corner_up": "phycon:block/interface_cable_corner_l_up", "corner_up": "phycon:block/cable/color/corner_l_up",
"corner_down": "phycon:block/interface_cable_corner_r" "corner_down": "phycon:block/cable/color/corner_r_down"
}, },
"elements": [ "elements": [
{ {
@ -19,4 +19,4 @@
} }
} }
] ]
} }

View File

@ -1,7 +1,7 @@
{ {
"textures": { "textures": {
"cable": "phycon:block/cable_straight", "cable": "phycon:block/cable/color/straight",
"cap": "phycon:block/cable_cap_end" "cap": "phycon:block/cable/color/cap_end"
}, },
"elements": [ "elements": [
{ {
@ -16,4 +16,4 @@
} }
} }
] ]
} }

View File

@ -1,7 +1,7 @@
{ {
"parent": "block/block", "parent": "block/block",
"textures": { "textures": {
"cable": "phycon:block/cable_straight", "cable": "phycon:block/cable/color/straight",
"particle": "#front", "particle": "#front",
"back": "phycon:block/interface_back", "back": "phycon:block/interface_back",
"front": "phycon:block/interface_front" "front": "phycon:block/interface_front"
@ -13,10 +13,10 @@
"faces": { "faces": {
"down": { "texture": "#front" }, "down": { "texture": "#front" },
"up": { "texture": "#back" }, "up": { "texture": "#back" },
"north": { "texture": "#back" }, "north": { "texture": "#back", "uv": [2, 2, 14, 4] },
"south": { "texture": "#back" }, "south": { "texture": "#back", "uv": [2, 2, 14, 4] },
"west": { "texture": "#back" }, "west": { "texture": "#back", "uv": [2, 2, 14, 4] },
"east": { "texture": "#back" } "east": { "texture": "#back", "uv": [2, 2, 14, 4] }
} }
}, },
{ {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 B

After

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 321 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 173 B

After

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 B

After

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 B

After

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 239 B

After

Width:  |  Height:  |  Size: 501 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 B

After

Width:  |  Height:  |  Size: 481 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 B

After

Width:  |  Height:  |  Size: 359 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 251 B

After

Width:  |  Height:  |  Size: 556 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 229 B

After

Width:  |  Height:  |  Size: 530 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 B

After

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 405 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 231 B

After

Width:  |  Height:  |  Size: 455 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 206 B

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 B

After

Width:  |  Height:  |  Size: 348 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 228 B

After

Width:  |  Height:  |  Size: 487 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 211 B

After

Width:  |  Height:  |  Size: 466 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 B

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 446 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 276 B

After

Width:  |  Height:  |  Size: 553 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 246 B

After

Width:  |  Height:  |  Size: 527 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 B

After

Width:  |  Height:  |  Size: 359 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 249 B

After

Width:  |  Height:  |  Size: 477 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 B

After

Width:  |  Height:  |  Size: 456 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 B

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 274 B

After

Width:  |  Height:  |  Size: 564 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 B

After

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 B

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 255 B

After

Width:  |  Height:  |  Size: 564 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 236 B

After

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 B

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 259 B

After

Width:  |  Height:  |  Size: 559 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 236 B

After

Width:  |  Height:  |  Size: 533 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 150 B

After

Width:  |  Height:  |  Size: 359 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 448 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 447 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 280 B

After

Width:  |  Height:  |  Size: 536 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 249 B

After

Width:  |  Height:  |  Size: 512 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 B

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 264 B

After

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 B

After

Width:  |  Height:  |  Size: 530 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 B

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 258 B

After

Width:  |  Height:  |  Size: 564 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 228 B

After

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 B

After

Width:  |  Height:  |  Size: 314 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 335 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 169 B

After

Width:  |  Height:  |  Size: 366 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 B

After

Width:  |  Height:  |  Size: 344 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 B

After

Width:  |  Height:  |  Size: 362 B

Some files were not shown because too many files have changed in this diff Show More