Place face devices directly on cables
This commit is contained in:
parent
eb1aa6cf19
commit
9acceeae3c
|
@ -60,7 +60,7 @@ abstract class FaceDeviceBlock<T: DeviceBlockEntity>(settings: Settings): Device
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract val faceThickness: Double
|
protected abstract val faceThickness: Double
|
||||||
protected abstract val faceShapes: Map<Direction, VoxelShape>
|
abstract val faceShapes: Map<Direction, VoxelShape>
|
||||||
private val centerShapes: Map<Direction, VoxelShape> by lazy {
|
private val centerShapes: Map<Direction, VoxelShape> by lazy {
|
||||||
mapOf(
|
mapOf(
|
||||||
Direction.DOWN to createCuboidShape(6.0, faceThickness, 6.0, 10.0, 10.0, 10.0),
|
Direction.DOWN to createCuboidShape(6.0, faceThickness, 6.0, 10.0, 10.0, 10.0),
|
||||||
|
|
|
@ -24,7 +24,9 @@ import net.shadowfacts.phycon.api.Interface
|
||||||
import net.shadowfacts.phycon.api.NetworkCableBlock
|
import net.shadowfacts.phycon.api.NetworkCableBlock
|
||||||
import net.shadowfacts.phycon.api.NetworkComponentBlock
|
import net.shadowfacts.phycon.api.NetworkComponentBlock
|
||||||
import net.shadowfacts.phycon.init.PhyItems
|
import net.shadowfacts.phycon.init.PhyItems
|
||||||
|
import net.shadowfacts.phycon.item.FaceDeviceBlockItem
|
||||||
import net.shadowfacts.phycon.util.CableConnection
|
import net.shadowfacts.phycon.util.CableConnection
|
||||||
|
import net.shadowfacts.phycon.util.containsInclusive
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,12 +89,16 @@ class CableBlock: Block(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getPlacementState(context: ItemPlacementContext): BlockState {
|
fun getInitialState(world: World, pos: BlockPos): BlockState {
|
||||||
return CONNECTIONS.entries.fold(defaultState, { acc, (dir, prop) ->
|
return CONNECTIONS.entries.fold(defaultState, { acc, (dir, prop) ->
|
||||||
acc.with(prop, getConnectionStateInDirection(context.world, context.blockPos, dir))
|
acc.with(prop, getConnectionStateInDirection(world, pos, dir))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getPlacementState(context: ItemPlacementContext): BlockState {
|
||||||
|
return getInitialState(context.world, context.blockPos)
|
||||||
|
}
|
||||||
|
|
||||||
override fun getStateForNeighborUpdate(state: BlockState, side: Direction, neighborState: BlockState, world: WorldAccess, blockPos_1: BlockPos, blockPos_2: BlockPos): BlockState {
|
override fun getStateForNeighborUpdate(state: BlockState, side: Direction, neighborState: BlockState, world: WorldAccess, blockPos_1: BlockPos, blockPos_2: BlockPos): BlockState {
|
||||||
val prop = CONNECTIONS[side]
|
val prop = CONNECTIONS[side]
|
||||||
val current = state[prop]
|
val current = state[prop]
|
||||||
|
@ -141,8 +147,7 @@ class CableBlock: Block(
|
||||||
if (player.getStackInHand(hand).item == PhyItems.SCREWDRIVER) {
|
if (player.getStackInHand(hand).item == PhyItems.SCREWDRIVER) {
|
||||||
val hitPos = Vec3d(hitResult.pos.x - pos.x, hitResult.pos.y - pos.y, hitResult.pos.z - pos.z)
|
val hitPos = Vec3d(hitResult.pos.x - pos.x, hitResult.pos.y - pos.y, hitResult.pos.z - pos.z)
|
||||||
val hitConnection = SIDE_SHAPES.entries.firstOrNull { (_, shape) ->
|
val hitConnection = SIDE_SHAPES.entries.firstOrNull { (_, shape) ->
|
||||||
val box = shape.boundingBox
|
shape.boundingBox.containsInclusive(hitPos)
|
||||||
hitPos.x >= box.minX && hitPos.x <= box.maxX && hitPos.y >= box.minY && hitPos.y <= box.maxY && hitPos.z >= box.minZ && hitPos.z <= box.maxZ
|
|
||||||
}
|
}
|
||||||
if (hitConnection != null) {
|
if (hitConnection != null) {
|
||||||
val side = hitConnection.key
|
val side = hitConnection.key
|
||||||
|
@ -169,6 +174,10 @@ class CableBlock: Block(
|
||||||
return ActionResult.PASS
|
return ActionResult.PASS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun canReplace(state: BlockState, context: ItemPlacementContext): Boolean {
|
||||||
|
return context.stack.item is FaceDeviceBlockItem
|
||||||
|
}
|
||||||
|
|
||||||
override fun isTranslucent(blockState_1: BlockState?, blockView_1: BlockView?, blockPos_1: BlockPos?): Boolean {
|
override fun isTranslucent(blockState_1: BlockState?, blockView_1: BlockView?, blockPos_1: BlockPos?): Boolean {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,21 +17,22 @@ import net.shadowfacts.phycon.block.redstone_controller.RedstoneControllerBlock
|
||||||
import net.shadowfacts.phycon.block.redstone_emitter.RedstoneEmitterBlock
|
import net.shadowfacts.phycon.block.redstone_emitter.RedstoneEmitterBlock
|
||||||
import net.shadowfacts.phycon.block.terminal.TerminalBlock
|
import net.shadowfacts.phycon.block.terminal.TerminalBlock
|
||||||
import net.shadowfacts.phycon.item.DeviceBlockItem
|
import net.shadowfacts.phycon.item.DeviceBlockItem
|
||||||
|
import net.shadowfacts.phycon.item.FaceDeviceBlockItem
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author shadowfacts
|
* @author shadowfacts
|
||||||
*/
|
*/
|
||||||
object PhyItems {
|
object PhyItems {
|
||||||
|
|
||||||
val INTERFACE = DeviceBlockItem(PhyBlocks.INTERFACE, Item.Settings())
|
val INTERFACE = FaceDeviceBlockItem(PhyBlocks.INTERFACE, Item.Settings())
|
||||||
val TERMINAL = DeviceBlockItem(PhyBlocks.TERMINAL, Item.Settings())
|
val TERMINAL = DeviceBlockItem(PhyBlocks.TERMINAL, Item.Settings())
|
||||||
val SWITCH = BlockItem(PhyBlocks.SWITCH, Item.Settings())
|
val SWITCH = BlockItem(PhyBlocks.SWITCH, Item.Settings())
|
||||||
val CABLE = BlockItem(PhyBlocks.CABLE, Item.Settings())
|
val CABLE = BlockItem(PhyBlocks.CABLE, Item.Settings())
|
||||||
val EXTRACTOR = DeviceBlockItem(PhyBlocks.EXTRACTOR, Item.Settings())
|
val EXTRACTOR = DeviceBlockItem(PhyBlocks.EXTRACTOR, Item.Settings())
|
||||||
val INSERTER = DeviceBlockItem(PhyBlocks.INSERTER, Item.Settings())
|
val INSERTER = DeviceBlockItem(PhyBlocks.INSERTER, Item.Settings())
|
||||||
val MINER = DeviceBlockItem(PhyBlocks.MINER, Item.Settings())
|
val MINER = DeviceBlockItem(PhyBlocks.MINER, Item.Settings())
|
||||||
val REDSTONE_CONTROLLER = DeviceBlockItem(PhyBlocks.REDSTONE_CONTROLLER, Item.Settings())
|
val REDSTONE_CONTROLLER = FaceDeviceBlockItem(PhyBlocks.REDSTONE_CONTROLLER, Item.Settings())
|
||||||
val REDSTONE_EMITTER = DeviceBlockItem(PhyBlocks.REDSTONE_EMITTER, Item.Settings())
|
val REDSTONE_EMITTER = FaceDeviceBlockItem(PhyBlocks.REDSTONE_EMITTER, Item.Settings())
|
||||||
|
|
||||||
val SCREWDRIVER = ScrewdriverItem()
|
val SCREWDRIVER = ScrewdriverItem()
|
||||||
val CONSOLE = ConsoleItem()
|
val CONSOLE = ConsoleItem()
|
||||||
|
|
|
@ -12,7 +12,7 @@ import net.shadowfacts.phycon.util.text
|
||||||
/**
|
/**
|
||||||
* @author shadowfacts
|
* @author shadowfacts
|
||||||
*/
|
*/
|
||||||
class DeviceBlockItem(block: DeviceBlock<*>, settings: Settings = Settings()): BlockItem(block, settings) {
|
open class DeviceBlockItem(block: DeviceBlock<*>, settings: Settings = Settings()): BlockItem(block, settings) {
|
||||||
|
|
||||||
override fun appendTooltip(stack: ItemStack, world: World?, list: MutableList<Text>, context: TooltipContext) {
|
override fun appendTooltip(stack: ItemStack, world: World?, list: MutableList<Text>, context: TooltipContext) {
|
||||||
val beTag = stack.getSubTag("BlockEntityTag")
|
val beTag = stack.getSubTag("BlockEntityTag")
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
package net.shadowfacts.phycon.item
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState
|
||||||
|
import net.minecraft.item.ItemPlacementContext
|
||||||
|
import net.minecraft.util.math.Direction
|
||||||
|
import net.shadowfacts.phycon.block.FaceDeviceBlock
|
||||||
|
import net.shadowfacts.phycon.block.cable.CableBlock
|
||||||
|
import net.shadowfacts.phycon.init.PhyBlocks
|
||||||
|
import net.shadowfacts.phycon.util.CableConnection
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author shadowfacts
|
||||||
|
*/
|
||||||
|
class FaceDeviceBlockItem(block: FaceDeviceBlock<*>, settings: Settings = Settings()): DeviceBlockItem(block, settings) {
|
||||||
|
|
||||||
|
override fun getPlacementState(context: ItemPlacementContext): BlockState? {
|
||||||
|
val hitState = context.world.getBlockState(context.blockPos)
|
||||||
|
if (hitState.block == PhyBlocks.CABLE) {
|
||||||
|
val hitBlockEdge = context.hitPos.getComponentAlongAxis(context.side.axis) % 1 == 0.0
|
||||||
|
|
||||||
|
val placementSide = if (hitBlockEdge) context.side.opposite else context.side
|
||||||
|
|
||||||
|
if (hitState[CableBlock.CONNECTIONS[placementSide]] != CableConnection.ON) {
|
||||||
|
var connection = FaceDeviceBlock.FaceCableConnection.NONE
|
||||||
|
for (dir in Direction.values()) {
|
||||||
|
if (hitState[CableBlock.CONNECTIONS[dir]] == CableConnection.ON) {
|
||||||
|
connection = FaceDeviceBlock.FaceCableConnection.from(dir)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return block.defaultState
|
||||||
|
.with(FaceDeviceBlock.FACING, placementSide)
|
||||||
|
.with(FaceDeviceBlock.CABLE_CONNECTION, connection)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -9,9 +9,12 @@ import net.minecraft.sound.SoundCategory
|
||||||
import net.minecraft.sound.SoundEvents
|
import net.minecraft.sound.SoundEvents
|
||||||
import net.minecraft.util.ActionResult
|
import net.minecraft.util.ActionResult
|
||||||
import net.minecraft.util.Identifier
|
import net.minecraft.util.Identifier
|
||||||
|
import net.minecraft.util.math.Vec3d
|
||||||
import net.shadowfacts.phycon.PhysicalConnectivity
|
import net.shadowfacts.phycon.PhysicalConnectivity
|
||||||
import net.shadowfacts.phycon.block.DeviceBlock
|
import net.shadowfacts.phycon.block.DeviceBlock
|
||||||
|
import net.shadowfacts.phycon.block.FaceDeviceBlock
|
||||||
import net.shadowfacts.phycon.init.PhyBlocks
|
import net.shadowfacts.phycon.init.PhyBlocks
|
||||||
|
import net.shadowfacts.phycon.util.containsInclusive
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author shadowfacts
|
* @author shadowfacts
|
||||||
|
@ -44,7 +47,21 @@ class ScrewdriverItem: Item(Settings()) {
|
||||||
val entity = ItemEntity(context.world, context.blockPos.x.toDouble(), context.blockPos.y.toDouble(), context.blockPos.z.toDouble(), stack)
|
val entity = ItemEntity(context.world, context.blockPos.x.toDouble(), context.blockPos.y.toDouble(), context.blockPos.z.toDouble(), stack)
|
||||||
context.world.spawnEntity(entity)
|
context.world.spawnEntity(entity)
|
||||||
|
|
||||||
context.world.setBlockState(context.blockPos, Blocks.AIR.defaultState, 3, 512)
|
var newState = Blocks.AIR.defaultState
|
||||||
|
|
||||||
|
if (block is FaceDeviceBlock<*>) {
|
||||||
|
val hitInsideBlock = Vec3d(context.hitPos.x - context.blockPos.x, context.hitPos.y - context.blockPos.y, context.hitPos.z - context.blockPos.z)
|
||||||
|
val faceShape = block.faceShapes[state[FaceDeviceBlock.FACING]]!!
|
||||||
|
// if we hit the face part of block, leave the cable behind
|
||||||
|
if (faceShape.boundingBox.containsInclusive(hitInsideBlock)) {
|
||||||
|
newState = PhyBlocks.CABLE.getInitialState(context.world, context.blockPos)
|
||||||
|
} else {
|
||||||
|
val cable = ItemEntity(context.world, context.blockPos.x.toDouble(), context.blockPos.y.toDouble(), context.blockPos.z.toDouble(), ItemStack(PhyBlocks.CABLE))
|
||||||
|
context.world.spawnEntity(cable)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
context.world.setBlockState(context.blockPos, newState, 3, 512)
|
||||||
}
|
}
|
||||||
|
|
||||||
context.world.playSound(context.player, context.blockPos, SoundEvents.BLOCK_METAL_PLACE, SoundCategory.BLOCKS, 0.8f, 0.65f)
|
context.world.playSound(context.player, context.blockPos, SoundEvents.BLOCK_METAL_PLACE, SoundCategory.BLOCKS, 0.8f, 0.65f)
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package net.shadowfacts.phycon.util
|
||||||
|
|
||||||
|
import net.minecraft.util.math.Box
|
||||||
|
import net.minecraft.util.math.Vec3d
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author shadowfacts
|
||||||
|
*/
|
||||||
|
fun Box.containsInclusive(point: Vec3d): Boolean {
|
||||||
|
return point.x >= minX && point.x <= maxX && point.y >= minY && point.y <= maxY && point.z >= minZ && point.z <= maxZ
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
{
|
||||||
|
"type": "minecraft:block",
|
||||||
|
"pools": [
|
||||||
|
{
|
||||||
|
"rolls": 1,
|
||||||
|
"entries": [
|
||||||
|
{
|
||||||
|
"type": "minecraft:item",
|
||||||
|
"name": "phycon:network_interface"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"condition": "minecraft:survives_explosion"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rolls": 1,
|
||||||
|
"entries": [
|
||||||
|
{
|
||||||
|
"type": "minecraft:item",
|
||||||
|
"name": "phycon:cable"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"condition": "minecraft:survives_explosion"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -14,6 +14,20 @@
|
||||||
"condition": "minecraft:survives_explosion"
|
"condition": "minecraft:survives_explosion"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rolls": 1,
|
||||||
|
"entries": [
|
||||||
|
{
|
||||||
|
"type": "minecraft:item",
|
||||||
|
"name": "phycon:cable"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"condition": "minecraft:survives_explosion"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,20 @@
|
||||||
"condition": "minecraft:survives_explosion"
|
"condition": "minecraft:survives_explosion"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rolls": 1,
|
||||||
|
"entries": [
|
||||||
|
{
|
||||||
|
"type": "minecraft:item",
|
||||||
|
"name": "phycon:cable"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"condition": "minecraft:survives_explosion"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue