149 lines
4.9 KiB
Kotlin
149 lines
4.9 KiB
Kotlin
package net.shadowfacts.phycon.block.inserter
|
|
|
|
import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory
|
|
import net.minecraft.block.Block
|
|
import net.minecraft.block.BlockState
|
|
import net.minecraft.block.Material
|
|
import net.minecraft.block.ShapeContext
|
|
import net.minecraft.entity.LivingEntity
|
|
import net.minecraft.entity.player.PlayerEntity
|
|
import net.minecraft.entity.player.PlayerInventory
|
|
import net.minecraft.item.ItemPlacementContext
|
|
import net.minecraft.item.ItemStack
|
|
import net.minecraft.network.PacketByteBuf
|
|
import net.minecraft.screen.ScreenHandler
|
|
import net.minecraft.server.network.ServerPlayerEntity
|
|
import net.minecraft.sound.BlockSoundGroup
|
|
import net.minecraft.state.StateManager
|
|
import net.minecraft.state.property.Properties
|
|
import net.minecraft.text.Text
|
|
import net.minecraft.util.ActionResult
|
|
import net.minecraft.util.Hand
|
|
import net.minecraft.util.Identifier
|
|
import net.minecraft.util.hit.BlockHitResult
|
|
import net.minecraft.util.math.BlockPos
|
|
import net.minecraft.util.math.Direction
|
|
import net.minecraft.util.shape.VoxelShape
|
|
import net.minecraft.util.shape.VoxelShapes
|
|
import net.minecraft.world.BlockView
|
|
import net.minecraft.world.World
|
|
import net.minecraft.world.WorldAccess
|
|
import net.shadowfacts.phycon.PhysicalConnectivity
|
|
import net.shadowfacts.phycon.api.Interface
|
|
import net.shadowfacts.phycon.block.DeviceBlock
|
|
import net.shadowfacts.phycon.block.extractor.ExtractorBlock
|
|
import java.util.*
|
|
|
|
/**
|
|
* @author shadowfacts
|
|
*/
|
|
class InserterBlock: DeviceBlock<InserterBlockEntity>(
|
|
Settings.of(Material.METAL)
|
|
.strength(1.5f)
|
|
.sounds(BlockSoundGroup.METAL)
|
|
) {
|
|
companion object {
|
|
val ID = Identifier(PhysicalConnectivity.MODID, "inserter")
|
|
val FACING = Properties.FACING
|
|
private val INSERTER_SHAPES = mutableMapOf<Direction, VoxelShape>()
|
|
|
|
init {
|
|
val components = arrayOf(
|
|
doubleArrayOf(4.0, 0.0, 4.0, 12.0, 2.0, 12.0),
|
|
doubleArrayOf(2.0, 2.0, 2.0, 14.0, 4.0, 14.0),
|
|
doubleArrayOf(0.0, 4.0, 0.0, 16.0, 6.0, 16.0),
|
|
doubleArrayOf(6.0, 6.0, 6.0, 10.0, 16.0, 10.0)
|
|
)
|
|
val directions = arrayOf(
|
|
Triple(Direction.DOWN, null, false),
|
|
Triple(Direction.UP, null, true),
|
|
Triple(Direction.NORTH, 2, false),
|
|
Triple(Direction.SOUTH, 2, true),
|
|
Triple(Direction.WEST, 1, false),
|
|
Triple(Direction.EAST, 1, true),
|
|
)
|
|
for ((dir, rotate, flip) in directions) {
|
|
val shapes = components.map { it ->
|
|
val arr = it.copyOf()
|
|
if (rotate != null) {
|
|
for (i in 0 until 3) {
|
|
arr[i] = it[(i + rotate) % 3]
|
|
arr[3 + i] = it[3 + ((i + rotate) % 3)]
|
|
}
|
|
}
|
|
if (flip) {
|
|
for (i in arr.indices) {
|
|
arr[i] = 16.0 - arr[i]
|
|
}
|
|
}
|
|
createCuboidShape(arr[0], arr[1], arr[2], arr[3], arr[4], arr[5])
|
|
}
|
|
INSERTER_SHAPES[dir] = shapes.reduce { a, b -> VoxelShapes.union(a, b) }
|
|
}
|
|
}
|
|
}
|
|
|
|
override fun getNetworkConnectedSides(state: BlockState, world: WorldAccess, pos: BlockPos): Collection<Direction> {
|
|
return EnumSet.of(state[FACING].opposite)
|
|
}
|
|
|
|
override fun getNetworkInterfaceForSide(side: Direction, state: BlockState, world: WorldAccess, pos: BlockPos): Interface? {
|
|
return if (side == state[FACING].opposite) {
|
|
getBlockEntity(world, pos)
|
|
} else {
|
|
null
|
|
}
|
|
}
|
|
|
|
override fun appendProperties(builder: StateManager.Builder<Block, BlockState>) {
|
|
super.appendProperties(builder)
|
|
builder.add(FACING)
|
|
}
|
|
|
|
override fun createBlockEntity(world: BlockView) = InserterBlockEntity()
|
|
|
|
override fun getPlacementState(context: ItemPlacementContext): BlockState {
|
|
val facing = if (context.player?.isSneaking == true) context.side.opposite else context.playerLookDirection.opposite
|
|
return defaultState.with(FACING, facing)
|
|
}
|
|
|
|
override fun getOutlineShape(state: BlockState, world: BlockView, pos: BlockPos, context: ShapeContext): VoxelShape {
|
|
return INSERTER_SHAPES[state[FACING]]!!
|
|
}
|
|
|
|
override fun onPlaced(world: World, pos: BlockPos, state: BlockState, entity: LivingEntity?, stack: ItemStack) {
|
|
if (!world.isClient) {
|
|
getBlockEntity(world, pos)!!.updateInventory()
|
|
}
|
|
}
|
|
|
|
override fun neighborUpdate(state: BlockState, world: World, pos: BlockPos, neighborBlock: Block, neighborPos: BlockPos, bl: Boolean) {
|
|
if (!world.isClient) {
|
|
getBlockEntity(world, pos)!!.updateInventory()
|
|
}
|
|
}
|
|
|
|
override fun onUse(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, hitResult: BlockHitResult): ActionResult {
|
|
if (!world.isClient) {
|
|
val be = getBlockEntity(world, pos)!!
|
|
|
|
be.sync()
|
|
|
|
val factory = object: ExtendedScreenHandlerFactory {
|
|
override fun createMenu(syncId: Int, playerInv: PlayerInventory, player: PlayerEntity): ScreenHandler {
|
|
return InserterScreenHandler(syncId, playerInv, be)
|
|
}
|
|
|
|
override fun getDisplayName() = this@InserterBlock.name
|
|
|
|
override fun writeScreenOpeningData(player: ServerPlayerEntity, buf: PacketByteBuf) {
|
|
buf.writeBlockPos(be.pos)
|
|
}
|
|
}
|
|
player.openHandledScreen(factory)
|
|
}
|
|
return ActionResult.SUCCESS
|
|
}
|
|
|
|
}
|