Compare commits
4 Commits
611c4bb0ae
...
47ff975449
Author | SHA1 | Date |
---|---|---|
Shadowfacts | 47ff975449 | |
Shadowfacts | 369dcebe1b | |
Shadowfacts | ee6fb1e725 | |
Shadowfacts | bc50017b4a |
|
@ -4,10 +4,13 @@ import net.fabricmc.api.ClientModInitializer
|
||||||
import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry
|
import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry
|
||||||
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking
|
import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking
|
||||||
import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry
|
import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry
|
||||||
|
import net.fabricmc.fabric.api.renderer.v1.RendererAccess
|
||||||
|
import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial
|
||||||
import net.shadowfacts.phycon.block.inserter.InserterScreen
|
import net.shadowfacts.phycon.block.inserter.InserterScreen
|
||||||
import net.shadowfacts.phycon.block.redstone_emitter.RedstoneEmitterScreen
|
import net.shadowfacts.phycon.block.redstone_emitter.RedstoneEmitterScreen
|
||||||
import net.shadowfacts.phycon.init.PhyScreens
|
import net.shadowfacts.phycon.init.PhyScreens
|
||||||
import net.shadowfacts.phycon.block.terminal.TerminalScreen
|
import net.shadowfacts.phycon.block.terminal.TerminalScreen
|
||||||
|
import net.shadowfacts.phycon.client.PhyExtendedModelProvider
|
||||||
import net.shadowfacts.phycon.client.PhyModelProvider
|
import net.shadowfacts.phycon.client.PhyModelProvider
|
||||||
import net.shadowfacts.phycon.networking.ClientReceiver
|
import net.shadowfacts.phycon.networking.ClientReceiver
|
||||||
import net.shadowfacts.phycon.networking.S2CTerminalUpdateDisplayedItems
|
import net.shadowfacts.phycon.networking.S2CTerminalUpdateDisplayedItems
|
||||||
|
@ -17,9 +20,22 @@ import net.shadowfacts.phycon.networking.S2CTerminalUpdateDisplayedItems
|
||||||
*/
|
*/
|
||||||
object PhysicalConnectivityClient: ClientModInitializer {
|
object PhysicalConnectivityClient: ClientModInitializer {
|
||||||
|
|
||||||
|
var screenMaterial: RenderMaterial? = null
|
||||||
|
private set
|
||||||
|
|
||||||
override fun onInitializeClient() {
|
override fun onInitializeClient() {
|
||||||
ModelLoadingRegistry.INSTANCE.registerResourceProvider(::PhyModelProvider)
|
ModelLoadingRegistry.INSTANCE.registerResourceProvider(::PhyModelProvider)
|
||||||
|
|
||||||
|
RendererAccess.INSTANCE.renderer?.also { renderer ->
|
||||||
|
screenMaterial = renderer.materialFinder()
|
||||||
|
.emissive(0, true)
|
||||||
|
.disableAo(0, true)
|
||||||
|
.disableDiffuse(0, true)
|
||||||
|
.find()
|
||||||
|
|
||||||
|
ModelLoadingRegistry.INSTANCE.registerResourceProvider(::PhyExtendedModelProvider)
|
||||||
|
}
|
||||||
|
|
||||||
ScreenRegistry.register(PhyScreens.TERMINAL, ::TerminalScreen)
|
ScreenRegistry.register(PhyScreens.TERMINAL, ::TerminalScreen)
|
||||||
ScreenRegistry.register(PhyScreens.INSERTER, ::InserterScreen)
|
ScreenRegistry.register(PhyScreens.INSERTER, ::InserterScreen)
|
||||||
ScreenRegistry.register(PhyScreens.REDSTONE_EMITTER, ::RedstoneEmitterScreen)
|
ScreenRegistry.register(PhyScreens.REDSTONE_EMITTER, ::RedstoneEmitterScreen)
|
||||||
|
|
|
@ -4,20 +4,23 @@ import net.minecraft.block.Block
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.block.ShapeContext
|
import net.minecraft.block.ShapeContext
|
||||||
import net.minecraft.item.ItemPlacementContext
|
import net.minecraft.item.ItemPlacementContext
|
||||||
|
import net.minecraft.item.ItemStack
|
||||||
|
import net.minecraft.server.world.ServerWorld
|
||||||
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
|
||||||
import net.minecraft.util.shape.VoxelShape
|
import net.minecraft.util.shape.VoxelShape
|
||||||
import net.minecraft.util.shape.VoxelShapes
|
import net.minecraft.util.shape.VoxelShapes
|
||||||
import net.minecraft.world.BlockView
|
import net.minecraft.world.BlockView
|
||||||
import net.minecraft.world.World
|
|
||||||
import net.minecraft.world.WorldAccess
|
import net.minecraft.world.WorldAccess
|
||||||
import net.shadowfacts.phycon.api.Interface
|
import net.shadowfacts.phycon.api.Interface
|
||||||
import net.shadowfacts.phycon.api.NetworkComponentBlock
|
import net.shadowfacts.phycon.api.NetworkComponentBlock
|
||||||
import net.shadowfacts.phycon.block.cable.CableBlock
|
import net.shadowfacts.phycon.block.cable.CableBlock
|
||||||
|
import net.shadowfacts.phycon.init.PhyItems
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,6 +31,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 +104,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)
|
||||||
|
@ -146,4 +162,11 @@ abstract class FaceDeviceBlock<T: DeviceBlockEntity>(settings: Settings): Device
|
||||||
override fun getOutlineShape(state: BlockState, world: BlockView, pos: BlockPos, context: ShapeContext): VoxelShape {
|
override fun getOutlineShape(state: BlockState, world: BlockView, pos: BlockPos, context: ShapeContext): VoxelShape {
|
||||||
return getShape(state[FACING], state[CABLE_CONNECTION])
|
return getShape(state[FACING], state[CABLE_CONNECTION])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onStacksDropped(state: BlockState, world: ServerWorld, pos: BlockPos, stack: ItemStack) {
|
||||||
|
super.onStacksDropped(state, world, pos, stack)
|
||||||
|
|
||||||
|
val cableStack = ItemStack(PhyItems.CABLES[state[COLOR]])
|
||||||
|
dropStack(world, pos, cableStack)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package net.shadowfacts.phycon.block.cable
|
||||||
|
|
||||||
import net.fabricmc.fabric.api.`object`.builder.v1.block.FabricBlockSettings
|
import net.fabricmc.fabric.api.`object`.builder.v1.block.FabricBlockSettings
|
||||||
import net.minecraft.block.*
|
import net.minecraft.block.*
|
||||||
import net.minecraft.block.piston.PistonBehavior
|
|
||||||
import net.minecraft.entity.player.PlayerEntity
|
import net.minecraft.entity.player.PlayerEntity
|
||||||
import net.minecraft.item.ItemPlacementContext
|
import net.minecraft.item.ItemPlacementContext
|
||||||
import net.minecraft.state.StateManager
|
import net.minecraft.state.StateManager
|
||||||
|
@ -53,19 +52,25 @@ class CableBlock(
|
||||||
Direction.WEST to createCuboidShape(0.0, 6.0, 6.0, 6.0, 10.0, 10.0),
|
Direction.WEST to createCuboidShape(0.0, 6.0, 6.0, 6.0, 10.0, 10.0),
|
||||||
Direction.EAST to createCuboidShape(10.0, 6.0, 6.0, 16.0, 10.0, 10.0)
|
Direction.EAST to createCuboidShape(10.0, 6.0, 6.0, 16.0, 10.0, 10.0)
|
||||||
)
|
)
|
||||||
private val SHAPE_CACHE = mutableMapOf<BlockState, VoxelShape>()
|
private val SHAPE_CACHE = Array<VoxelShape>(64) { key ->
|
||||||
|
val connectedSides = Direction.values().filterIndexed { index, _ ->
|
||||||
|
((key shr index) and 1) == 1
|
||||||
|
}
|
||||||
|
connectedSides.fold(CENTER_SHAPE) { acc, side ->
|
||||||
|
VoxelShapes.union(acc, SIDE_SHAPES[side])
|
||||||
|
}
|
||||||
|
}
|
||||||
val CONNECTIONS: Map<Direction, EnumProperty<CableConnection>> = Direction.values().associate { it to EnumProperty.of(it.name.toLowerCase(), CableConnection::class.java) }
|
val CONNECTIONS: Map<Direction, EnumProperty<CableConnection>> = Direction.values().associate { it to EnumProperty.of(it.name.toLowerCase(), CableConnection::class.java) }
|
||||||
|
|
||||||
fun getShape(state: BlockState): VoxelShape {
|
fun getShape(state: BlockState): VoxelShape {
|
||||||
return SHAPE_CACHE.getOrPut(state) {
|
val key = Direction.values().foldIndexed(0) { i, acc, dir ->
|
||||||
var shape = CENTER_SHAPE
|
if (state[CONNECTIONS[dir]] == CableConnection.ON) {
|
||||||
for ((side, prop) in CONNECTIONS) {
|
acc or (1 shl i)
|
||||||
if (state[prop] == CableConnection.ON) {
|
} else {
|
||||||
shape = VoxelShapes.union(shape, SIDE_SHAPES[side])
|
acc
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return shape
|
|
||||||
}
|
}
|
||||||
|
return SHAPE_CACHE[key]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package net.shadowfacts.phycon.client
|
||||||
|
|
||||||
|
import net.fabricmc.fabric.api.client.model.ModelProviderContext
|
||||||
|
import net.fabricmc.fabric.api.client.model.ModelResourceProvider
|
||||||
|
import net.minecraft.client.render.model.UnbakedModel
|
||||||
|
import net.minecraft.resource.ResourceManager
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
|
import net.shadowfacts.phycon.PhysicalConnectivity
|
||||||
|
import net.shadowfacts.phycon.client.model.TerminalModel
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author shadowfacts
|
||||||
|
*/
|
||||||
|
class PhyExtendedModelProvider(resourceManager: ResourceManager): ModelResourceProvider {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val TERMINAL = Identifier(PhysicalConnectivity.MODID, "block/terminal")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun loadModelResource(resourceId: Identifier, context: ModelProviderContext): UnbakedModel? {
|
||||||
|
return when (resourceId) {
|
||||||
|
TERMINAL -> TerminalModel
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
package net.shadowfacts.phycon.client.model
|
||||||
|
|
||||||
|
import com.mojang.datafixers.util.Pair
|
||||||
|
import net.fabricmc.fabric.api.renderer.v1.RendererAccess
|
||||||
|
import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh
|
||||||
|
import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView
|
||||||
|
import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter
|
||||||
|
import net.fabricmc.fabric.api.renderer.v1.model.FabricBakedModel
|
||||||
|
import net.fabricmc.fabric.api.renderer.v1.render.RenderContext
|
||||||
|
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.item.ItemStack
|
||||||
|
import net.minecraft.util.Identifier
|
||||||
|
import net.minecraft.util.math.BlockPos
|
||||||
|
import net.minecraft.util.math.Direction
|
||||||
|
import net.minecraft.world.BlockRenderView
|
||||||
|
import net.shadowfacts.phycon.PhysicalConnectivity
|
||||||
|
import net.shadowfacts.phycon.PhysicalConnectivityClient
|
||||||
|
import net.shadowfacts.phycon.block.terminal.TerminalBlock
|
||||||
|
import java.util.Random
|
||||||
|
import java.util.function.Function
|
||||||
|
import java.util.function.Supplier
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author shadowfacts
|
||||||
|
*/
|
||||||
|
object TerminalModel: UnbakedModel, BakedModel, FabricBakedModel {
|
||||||
|
|
||||||
|
private val TERMINAL = SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, Identifier(PhysicalConnectivity.MODID, "block/terminal"))
|
||||||
|
private val CASING = SpriteIdentifier(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE, Identifier(PhysicalConnectivity.MODID, "block/casing"))
|
||||||
|
|
||||||
|
private lateinit var meshes: Array<Mesh>
|
||||||
|
private lateinit var terminalSprite: Sprite
|
||||||
|
|
||||||
|
override fun getModelDependencies(): Collection<Identifier> {
|
||||||
|
return listOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getTextureDependencies(
|
||||||
|
unbakedModelGetter: Function<Identifier, UnbakedModel>,
|
||||||
|
unresolvedTextureDependencies: MutableSet<Pair<String, String>>
|
||||||
|
): Collection<SpriteIdentifier> {
|
||||||
|
return listOf(TERMINAL, CASING)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun bake(
|
||||||
|
loader: ModelLoader,
|
||||||
|
textureGetter: Function<SpriteIdentifier, Sprite>,
|
||||||
|
rotationContainer: ModelBakeSettings,
|
||||||
|
modelId: Identifier
|
||||||
|
): BakedModel {
|
||||||
|
|
||||||
|
terminalSprite = textureGetter.apply(TERMINAL)
|
||||||
|
val casingSprite = textureGetter.apply(CASING)
|
||||||
|
|
||||||
|
val renderer = RendererAccess.INSTANCE.renderer!!
|
||||||
|
|
||||||
|
meshes = Array(6) { i ->
|
||||||
|
val facing = Direction.values()[i]
|
||||||
|
|
||||||
|
val builder = renderer.meshBuilder()
|
||||||
|
val emitter = builder.emitter
|
||||||
|
|
||||||
|
for (dir in Direction.values()) {
|
||||||
|
if (dir == facing) {
|
||||||
|
emitter.square(facing, 0f, 0f, 1f, 1f, QuadEmitter.CULL_FACE_EPSILON * 10)
|
||||||
|
emitter.spriteBake(0, terminalSprite, MutableQuadView.BAKE_LOCK_UV)
|
||||||
|
emitter.spriteColor(0, -1, -1, -1, -1)
|
||||||
|
emitter.emit()
|
||||||
|
|
||||||
|
emitter.material(PhysicalConnectivityClient.screenMaterial)
|
||||||
|
emitter.square(facing, 3/16f, 2/16f, 13/16f, 3/16f, 0f)
|
||||||
|
emitter.spriteBake(0, terminalSprite, MutableQuadView.BAKE_LOCK_UV)
|
||||||
|
emitter.spriteColor(0, -1, -1, -1, -1)
|
||||||
|
emitter.emit()
|
||||||
|
|
||||||
|
emitter.material(PhysicalConnectivityClient.screenMaterial)
|
||||||
|
emitter.square(facing, 2/16f, 3/16f, 14/16f, 13/16f, 0f)
|
||||||
|
emitter.spriteBake(0, terminalSprite, MutableQuadView.BAKE_LOCK_UV)
|
||||||
|
emitter.spriteColor(0, -1, -1, -1, -1)
|
||||||
|
emitter.emit()
|
||||||
|
|
||||||
|
emitter.material(PhysicalConnectivityClient.screenMaterial)
|
||||||
|
emitter.square(facing, 3/16f, 13/16f, 13/16f, 14/16f, 0f)
|
||||||
|
emitter.spriteBake(0, terminalSprite, MutableQuadView.BAKE_LOCK_UV)
|
||||||
|
emitter.spriteColor(0, -1, -1, -1, -1)
|
||||||
|
emitter.emit()
|
||||||
|
} else {
|
||||||
|
emitter.square(dir, 0f, 0f, 1f, 1f, 0f)
|
||||||
|
emitter.spriteBake(0, casingSprite, MutableQuadView.BAKE_LOCK_UV)
|
||||||
|
emitter.spriteColor(0, -1, -1, -1, -1)
|
||||||
|
emitter.emit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isVanillaAdapter() = false
|
||||||
|
|
||||||
|
override fun emitBlockQuads(
|
||||||
|
blockView: BlockRenderView,
|
||||||
|
state: BlockState,
|
||||||
|
pos: BlockPos,
|
||||||
|
randomSupplier: Supplier<Random>,
|
||||||
|
context: RenderContext
|
||||||
|
) {
|
||||||
|
val mesh = meshes[state[TerminalBlock.FACING].ordinal]
|
||||||
|
context.meshConsumer().accept(mesh)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun emitItemQuads(stack: ItemStack, randomSupplier: Supplier<Random>, context: RenderContext) {
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getQuads(state: BlockState?, face: Direction?, random: Random) = null
|
||||||
|
|
||||||
|
override fun useAmbientOcclusion() = true
|
||||||
|
|
||||||
|
override fun hasDepth() = false
|
||||||
|
|
||||||
|
override fun isSideLit() = false
|
||||||
|
|
||||||
|
override fun isBuiltin() = false
|
||||||
|
|
||||||
|
override fun getSprite() = terminalSprite
|
||||||
|
|
||||||
|
override fun getTransformation() = null
|
||||||
|
|
||||||
|
override fun getOverrides() = null
|
||||||
|
}
|
|
@ -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)!!
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -82,7 +82,8 @@ class ScrewdriverItem: Item(Settings().maxCount(1)) {
|
||||||
val faceShape = block.faceShapes[state[FaceDeviceBlock.FACING]]!!
|
val faceShape = block.faceShapes[state[FaceDeviceBlock.FACING]]!!
|
||||||
// if we hit the face part of block, leave the cable behind
|
// if we hit the face part of block, leave the cable behind
|
||||||
if (faceShape.boundingBox.containsInclusive(hitInsideBlock)) {
|
if (faceShape.boundingBox.containsInclusive(hitInsideBlock)) {
|
||||||
return (state.block as CableBlock).getInitialState(context.world, context.blockPos)
|
val cableBlock = PhyBlocks.CABLES[state[FaceDeviceBlock.COLOR]]!!
|
||||||
|
return cableBlock.getInitialState(context.world, context.blockPos)
|
||||||
} else {
|
} else {
|
||||||
if (!context.world.isClient) {
|
if (!context.world.isClient) {
|
||||||
val cable = ItemEntity(context.world, context.blockPos.x.toDouble(), context.blockPos.y.toDouble(), context.blockPos.z.toDouble(), ItemStack(state.block))
|
val cable = ItemEntity(context.world, context.blockPos.x.toDouble(), context.blockPos.y.toDouble(), context.blockPos.z.toDouble(), ItemStack(state.block))
|
||||||
|
|
|
@ -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": [
|
||||||
{
|
{
|
||||||
|
|
|
@ -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": [
|
||||||
{
|
{
|
||||||
|
|
|
@ -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": [
|
||||||
{
|
{
|
||||||
|
|
|
@ -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": [
|
||||||
{
|
{
|
||||||
|
|
|
@ -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] }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
Before Width: | Height: | Size: 104 B After Width: | Height: | Size: 308 B |
After Width: | Height: | Size: 317 B |
After Width: | Height: | Size: 321 B |
After Width: | Height: | Size: 322 B |
Before Width: | Height: | Size: 173 B After Width: | Height: | Size: 342 B |
Before Width: | Height: | Size: 128 B After Width: | Height: | Size: 322 B |
Before Width: | Height: | Size: 194 B After Width: | Height: | Size: 194 B |
Before Width: | Height: | Size: 201 B After Width: | Height: | Size: 201 B |
Before Width: | Height: | Size: 203 B After Width: | Height: | Size: 203 B |
Before Width: | Height: | Size: 144 B After Width: | Height: | Size: 348 B |
After Width: | Height: | Size: 427 B |
After Width: | Height: | Size: 426 B |
After Width: | Height: | Size: 426 B |
Before Width: | Height: | Size: 239 B After Width: | Height: | Size: 501 B |
Before Width: | Height: | Size: 217 B After Width: | Height: | Size: 481 B |
Before Width: | Height: | Size: 148 B After Width: | Height: | Size: 359 B |
After Width: | Height: | Size: 452 B |
After Width: | Height: | Size: 454 B |
After Width: | Height: | Size: 454 B |
Before Width: | Height: | Size: 251 B After Width: | Height: | Size: 556 B |
Before Width: | Height: | Size: 229 B After Width: | Height: | Size: 530 B |
Before Width: | Height: | Size: 142 B After Width: | Height: | Size: 345 B |
After Width: | Height: | Size: 406 B |
After Width: | Height: | Size: 405 B |
After Width: | Height: | Size: 405 B |
Before Width: | Height: | Size: 231 B After Width: | Height: | Size: 455 B |
Before Width: | Height: | Size: 206 B After Width: | Height: | Size: 438 B |
Before Width: | Height: | Size: 143 B After Width: | Height: | Size: 348 B |
After Width: | Height: | Size: 428 B |
After Width: | Height: | Size: 430 B |
After Width: | Height: | Size: 430 B |
Before Width: | Height: | Size: 228 B After Width: | Height: | Size: 487 B |
Before Width: | Height: | Size: 211 B After Width: | Height: | Size: 466 B |
Before Width: | Height: | Size: 148 B After Width: | Height: | Size: 362 B |
After Width: | Height: | Size: 446 B |
After Width: | Height: | Size: 448 B |
After Width: | Height: | Size: 448 B |
Before Width: | Height: | Size: 276 B After Width: | Height: | Size: 553 B |
Before Width: | Height: | Size: 246 B After Width: | Height: | Size: 527 B |
Before Width: | Height: | Size: 145 B After Width: | Height: | Size: 359 B |
After Width: | Height: | Size: 427 B |
After Width: | Height: | Size: 426 B |
After Width: | Height: | Size: 426 B |
Before Width: | Height: | Size: 249 B After Width: | Height: | Size: 477 B |
Before Width: | Height: | Size: 222 B After Width: | Height: | Size: 456 B |
Before Width: | Height: | Size: 149 B After Width: | Height: | Size: 362 B |
After Width: | Height: | Size: 455 B |
After Width: | Height: | Size: 457 B |
After Width: | Height: | Size: 457 B |
Before Width: | Height: | Size: 274 B After Width: | Height: | Size: 564 B |
Before Width: | Height: | Size: 243 B After Width: | Height: | Size: 539 B |
Before Width: | Height: | Size: 148 B After Width: | Height: | Size: 362 B |
After Width: | Height: | Size: 455 B |
After Width: | Height: | Size: 457 B |
After Width: | Height: | Size: 457 B |
Before Width: | Height: | Size: 255 B After Width: | Height: | Size: 564 B |
Before Width: | Height: | Size: 236 B After Width: | Height: | Size: 539 B |
Before Width: | Height: | Size: 145 B After Width: | Height: | Size: 362 B |
After Width: | Height: | Size: 455 B |
After Width: | Height: | Size: 457 B |
After Width: | Height: | Size: 457 B |
Before Width: | Height: | Size: 259 B After Width: | Height: | Size: 559 B |
Before Width: | Height: | Size: 236 B After Width: | Height: | Size: 533 B |
Before Width: | Height: | Size: 150 B After Width: | Height: | Size: 359 B |
After Width: | Height: | Size: 448 B |
After Width: | Height: | Size: 447 B |
After Width: | Height: | Size: 447 B |
Before Width: | Height: | Size: 280 B After Width: | Height: | Size: 536 B |
Before Width: | Height: | Size: 249 B After Width: | Height: | Size: 512 B |
Before Width: | Height: | Size: 148 B After Width: | Height: | Size: 362 B |
After Width: | Height: | Size: 452 B |
After Width: | Height: | Size: 454 B |
After Width: | Height: | Size: 454 B |
Before Width: | Height: | Size: 264 B After Width: | Height: | Size: 555 B |
Before Width: | Height: | Size: 243 B After Width: | Height: | Size: 530 B |
Before Width: | Height: | Size: 148 B After Width: | Height: | Size: 362 B |
After Width: | Height: | Size: 455 B |
After Width: | Height: | Size: 457 B |
After Width: | Height: | Size: 457 B |
Before Width: | Height: | Size: 258 B After Width: | Height: | Size: 564 B |
Before Width: | Height: | Size: 228 B After Width: | Height: | Size: 539 B |
Before Width: | Height: | Size: 109 B After Width: | Height: | Size: 314 B |
After Width: | Height: | Size: 329 B |