Place face devices directly on cables

This commit is contained in:
Shadowfacts 2021-03-07 10:38:22 -05:00
parent eb1aa6cf19
commit 9acceeae3c
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
10 changed files with 149 additions and 10 deletions

View File

@ -60,7 +60,7 @@ abstract class FaceDeviceBlock<T: DeviceBlockEntity>(settings: Settings): Device
}
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 {
mapOf(
Direction.DOWN to createCuboidShape(6.0, faceThickness, 6.0, 10.0, 10.0, 10.0),

View File

@ -24,7 +24,9 @@ import net.shadowfacts.phycon.api.Interface
import net.shadowfacts.phycon.api.NetworkCableBlock
import net.shadowfacts.phycon.api.NetworkComponentBlock
import net.shadowfacts.phycon.init.PhyItems
import net.shadowfacts.phycon.item.FaceDeviceBlockItem
import net.shadowfacts.phycon.util.CableConnection
import net.shadowfacts.phycon.util.containsInclusive
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) ->
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 {
val prop = CONNECTIONS[side]
val current = state[prop]
@ -141,8 +147,7 @@ class CableBlock: Block(
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 hitConnection = SIDE_SHAPES.entries.firstOrNull { (_, shape) ->
val box = shape.boundingBox
hitPos.x >= box.minX && hitPos.x <= box.maxX && hitPos.y >= box.minY && hitPos.y <= box.maxY && hitPos.z >= box.minZ && hitPos.z <= box.maxZ
shape.boundingBox.containsInclusive(hitPos)
}
if (hitConnection != null) {
val side = hitConnection.key
@ -169,6 +174,10 @@ class CableBlock: Block(
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 {
return true
}

View File

@ -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.terminal.TerminalBlock
import net.shadowfacts.phycon.item.DeviceBlockItem
import net.shadowfacts.phycon.item.FaceDeviceBlockItem
/**
* @author shadowfacts
*/
object PhyItems {
val INTERFACE = DeviceBlockItem(PhyBlocks.INTERFACE, Item.Settings())
val INTERFACE = FaceDeviceBlockItem(PhyBlocks.INTERFACE, Item.Settings())
val TERMINAL = DeviceBlockItem(PhyBlocks.TERMINAL, Item.Settings())
val SWITCH = BlockItem(PhyBlocks.SWITCH, Item.Settings())
val CABLE = BlockItem(PhyBlocks.CABLE, Item.Settings())
val EXTRACTOR = DeviceBlockItem(PhyBlocks.EXTRACTOR, Item.Settings())
val INSERTER = DeviceBlockItem(PhyBlocks.INSERTER, Item.Settings())
val MINER = DeviceBlockItem(PhyBlocks.MINER, Item.Settings())
val REDSTONE_CONTROLLER = DeviceBlockItem(PhyBlocks.REDSTONE_CONTROLLER, Item.Settings())
val REDSTONE_EMITTER = DeviceBlockItem(PhyBlocks.REDSTONE_EMITTER, Item.Settings())
val REDSTONE_CONTROLLER = FaceDeviceBlockItem(PhyBlocks.REDSTONE_CONTROLLER, Item.Settings())
val REDSTONE_EMITTER = FaceDeviceBlockItem(PhyBlocks.REDSTONE_EMITTER, Item.Settings())
val SCREWDRIVER = ScrewdriverItem()
val CONSOLE = ConsoleItem()

View File

@ -12,7 +12,7 @@ import net.shadowfacts.phycon.util.text
/**
* @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) {
val beTag = stack.getSubTag("BlockEntityTag")

View File

@ -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
}
}

View File

@ -9,9 +9,12 @@ import net.minecraft.sound.SoundCategory
import net.minecraft.sound.SoundEvents
import net.minecraft.util.ActionResult
import net.minecraft.util.Identifier
import net.minecraft.util.math.Vec3d
import net.shadowfacts.phycon.PhysicalConnectivity
import net.shadowfacts.phycon.block.DeviceBlock
import net.shadowfacts.phycon.block.FaceDeviceBlock
import net.shadowfacts.phycon.init.PhyBlocks
import net.shadowfacts.phycon.util.containsInclusive
/**
* @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)
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)

View File

@ -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
}

View File

@ -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"
}
]
}
]
}

View File

@ -14,6 +14,20 @@
"condition": "minecraft:survives_explosion"
}
]
},
{
"rolls": 1,
"entries": [
{
"type": "minecraft:item",
"name": "phycon:cable"
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
]
}
]
}

View File

@ -14,6 +14,20 @@
"condition": "minecraft:survives_explosion"
}
]
},
{
"rolls": 1,
"entries": [
{
"type": "minecraft:item",
"name": "phycon:cable"
}
],
"conditions": [
{
"condition": "minecraft:survives_explosion"
}
]
}
]
}