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.entity.LivingEntity import net.minecraft.entity.player.PlayerEntity import net.minecraft.entity.player.PlayerInventory 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.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.shadowfacts.phycon.PhysicalConnectivity import net.shadowfacts.phycon.block.FaceDeviceBlock import java.util.* import kotlin.math.max import kotlin.math.min /** * @author shadowfacts */ class InserterBlock: FaceDeviceBlock( Settings.of(Material.METAL) .strength(1.5f) .sounds(BlockSoundGroup.METAL) ) { companion object { val ID = Identifier(PhysicalConnectivity.MODID, "inserter") private val INSERTER_SHAPES = mutableMapOf() 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), ) 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(min(arr[0], arr[3]), min(arr[1], arr[4]), min(arr[2], arr[5]), max(arr[0], arr[3]), max(arr[1], arr[4]), max(arr[2], arr[5])) } INSERTER_SHAPES[dir] = shapes.reduce { a, b -> VoxelShapes.union(a, b) } } } } override val faceThickness = 6.0 override val faceShapes: Map = INSERTER_SHAPES override fun createBlockEntity(pos: BlockPos, state: BlockState) = InserterBlockEntity(pos, state) 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.markUpdate() 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 } }