Add Miner block

This commit is contained in:
Shadowfacts 2021-02-14 23:42:19 -05:00
parent 649408c509
commit 0f7689d73c
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
8 changed files with 212 additions and 6 deletions

View File

@ -7,6 +7,8 @@ import net.minecraft.util.Identifier
import net.minecraft.util.registry.Registry
import net.shadowfacts.phycon.network.block.extractor.ExtractorBlock
import net.shadowfacts.phycon.network.block.extractor.ExtractorBlockEntity
import net.shadowfacts.phycon.network.block.miner.MinerBlock
import net.shadowfacts.phycon.network.block.miner.MinerBlockEntity
import net.shadowfacts.phycon.network.block.netinterface.InterfaceBlock
import net.shadowfacts.phycon.network.block.netinterface.InterfaceBlockEntity
import net.shadowfacts.phycon.network.block.netswitch.SwitchBlock
@ -27,6 +29,7 @@ object PhyBlockEntities {
val TERMINAL = create(::TerminalBlockEntity, PhyBlocks.TERMINAL)
val SWITCH = create(::SwitchBlockEntity, PhyBlocks.SWITCH)
val EXTRACTOR = create(::ExtractorBlockEntity, PhyBlocks.EXTRACTOR)
val MINER = create(::MinerBlockEntity, PhyBlocks.MINER)
val SOURCE = create(::SourceBlockEntity, PhyBlocks.SOURCE)
val DEST = create(::DestBlockEntity, PhyBlocks.DEST)
@ -40,6 +43,7 @@ object PhyBlockEntities {
register(TerminalBlock.ID, TERMINAL)
register(SwitchBlock.ID, SWITCH)
register(ExtractorBlock.ID, EXTRACTOR)
register(MinerBlock.ID, MINER)
register(SourceBlock.ID, SOURCE)
register(DestBlock.ID, DEST)

View File

@ -5,6 +5,7 @@ import net.minecraft.util.Identifier
import net.minecraft.util.registry.Registry
import net.shadowfacts.phycon.network.block.cable.CableBlock
import net.shadowfacts.phycon.network.block.extractor.ExtractorBlock
import net.shadowfacts.phycon.network.block.miner.MinerBlock
import net.shadowfacts.phycon.network.block.netinterface.InterfaceBlock
import net.shadowfacts.phycon.network.block.netswitch.SwitchBlock
import net.shadowfacts.phycon.network.block.terminal.TerminalBlock
@ -21,6 +22,7 @@ object PhyBlocks {
val SWITCH = SwitchBlock()
val CABLE = CableBlock()
val EXTRACTOR = ExtractorBlock()
val MINER = MinerBlock()
val SOURCE = SourceBlock()
val DEST = DestBlock()
@ -31,6 +33,7 @@ object PhyBlocks {
register(SwitchBlock.ID, SWITCH)
register(CableBlock.ID, CABLE)
register(ExtractorBlock.ID, EXTRACTOR)
register(MinerBlock.ID, MINER)
register(SourceBlock.ID, SOURCE)
register(DestBlock.ID, DEST)

View File

@ -8,6 +8,7 @@ import net.shadowfacts.phycon.item.ConsoleItem
import net.shadowfacts.phycon.item.ScrewdriverItem
import net.shadowfacts.phycon.network.block.cable.CableBlock
import net.shadowfacts.phycon.network.block.extractor.ExtractorBlock
import net.shadowfacts.phycon.network.block.miner.MinerBlock
import net.shadowfacts.phycon.network.block.netinterface.InterfaceBlock
import net.shadowfacts.phycon.network.block.netswitch.SwitchBlock
import net.shadowfacts.phycon.network.block.terminal.TerminalBlock
@ -24,6 +25,7 @@ object PhyItems {
val SWITCH = BlockItem(PhyBlocks.SWITCH, Item.Settings())
val CABLE = BlockItem(PhyBlocks.CABLE, Item.Settings())
val EXTRACTOR = BlockItem(PhyBlocks.EXTRACTOR, Item.Settings())
val MINER = BlockItem(PhyBlocks.MINER, Item.Settings())
val SOURCE = BlockItem(PhyBlocks.SOURCE, Item.Settings())
val DEST = BlockItem(PhyBlocks.DEST , Item.Settings())
@ -37,6 +39,7 @@ object PhyItems {
register(SwitchBlock.ID, SWITCH)
register(CableBlock.ID, CABLE)
register(ExtractorBlock.ID, EXTRACTOR)
register(MinerBlock.ID, MINER)
register(SourceBlock.ID, SOURCE)
register(DestBlock.ID, DEST)

View File

@ -0,0 +1,68 @@
package net.shadowfacts.phycon.network.block.miner
import net.minecraft.block.Block
import net.minecraft.block.BlockState
import net.minecraft.block.Material
import net.minecraft.entity.LivingEntity
import net.minecraft.item.ItemPlacementContext
import net.minecraft.item.ItemStack
import net.minecraft.state.StateManager
import net.minecraft.state.property.Properties
import net.minecraft.util.Identifier
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction
import net.minecraft.world.BlockView
import net.minecraft.world.World
import net.shadowfacts.phycon.PhysicalConnectivity
import net.shadowfacts.phycon.api.Interface
import net.shadowfacts.phycon.network.DeviceBlock
import net.shadowfacts.phycon.network.block.extractor.ExtractorBlock
import java.util.*
/**
* @author shadowfacts
*/
class MinerBlock: DeviceBlock<MinerBlockEntity>(Settings.of(Material.METAL)) {
companion object {
val ID = Identifier(PhysicalConnectivity.MODID, "miner")
val FACING = Properties.FACING
}
override fun getNetworkConnectedSides(state: BlockState, world: World, pos: BlockPos): Collection<Direction> {
return EnumSet.of(state[FACING].opposite)
}
override fun getNetworkInterfaceForSide(side: Direction, state: BlockState, world: World, pos: BlockPos): Interface? {
return if (side == state[FACING]) {
null
} else {
getBlockEntity(world, pos)
}
}
override fun appendProperties(builder: StateManager.Builder<Block, BlockState>) {
super.appendProperties(builder)
builder.add(FACING)
}
override fun createBlockEntity(world: BlockView) = MinerBlockEntity()
override fun getPlacementState(context: ItemPlacementContext): BlockState? {
val facing = if (context.player?.isSneaking == true) context.side.opposite else context.playerFacing.opposite
return defaultState.with(ExtractorBlock.FACING, facing)
}
override fun onPlaced(world: World, pos: BlockPos, state: BlockState, entity: LivingEntity?, itemStack: ItemStack) {
if (!world.isClient) {
// getBlockEntity(world, pos)!!.updateBlockToMine()
}
}
override fun neighborUpdate(state: BlockState, world: World, pos: BlockPos, neighbor: Block, neighborPos: BlockPos, bl: Boolean) {
if (!world.isClient) {
// getBlockEntity(world, pos)!!.updateBlockToMine()
}
}
}

View File

@ -0,0 +1,127 @@
package net.shadowfacts.phycon.network.block.miner
import alexiil.mc.lib.attributes.item.GroupedItemInvView
import alexiil.mc.lib.attributes.item.ItemStackUtil
import alexiil.mc.lib.attributes.item.filter.ItemFilter
import net.minecraft.block.Block
import net.minecraft.block.BlockState
import net.minecraft.item.ItemStack
import net.minecraft.server.world.ServerWorld
import net.minecraft.util.math.BlockPos
import net.minecraft.util.math.Direction
import net.minecraft.world.World
import net.shadowfacts.phycon.api.packet.Packet
import net.shadowfacts.phycon.api.util.IPAddress
import net.shadowfacts.phycon.init.PhyBlockEntities
import net.shadowfacts.phycon.network.DeviceBlockEntity
import net.shadowfacts.phycon.network.component.NetworkStackProvider
import net.shadowfacts.phycon.network.packet.*
import kotlin.math.min
/**
* @author shadowfacts
*/
class MinerBlockEntity: DeviceBlockEntity(PhyBlockEntities.MINER),
NetworkStackProvider {
private val facing: Direction
get() = cachedState[MinerBlock.FACING]
private val invProxy = MinerInvProxy(this)
override fun handle(packet: Packet) {
when (packet) {
is RequestInventoryPacket -> handleRequestInventory(packet)
is LocateStackPacket -> handleLocateStack(packet)
is ExtractStackPacket -> handleExtractStack(packet)
}
}
private fun handleRequestInventory(packet: RequestInventoryPacket) {
sendPacket(ReadInventoryPacket(invProxy, ipAddress, packet.source))
}
private fun handleLocateStack(packet: LocateStackPacket) {
val amount = invProxy.getAmount(packet.stack)
if (amount > 0) {
sendPacket(StackLocationPacket(packet.stack, amount, this, ipAddress, packet.source))
}
}
private fun handleExtractStack(packet: ExtractStackPacket) {
// always recalculate immediately before breaking
val drops = invProxy.getDrops(true)
if (invProxy.getAmount(packet.stack) > 0) {
world!!.breakBlock(pos.offset(facing), false)
// send the requested amount back to the requester
var remaining = packet.amount
for (droppedStack in drops) {
if (remaining <= 0) {
break
}
if (!ItemStackUtil.areEqualIgnoreAmounts(droppedStack, packet.stack)) {
continue
}
val copy = droppedStack.copy()
val toDecr = min(droppedStack.count, remaining)
droppedStack.decrement(toDecr)
remaining -= toDecr
// todo: should this try to combine stacks and send as few packets as possible?
copy.count = toDecr
sendPacket(ItemStackPacket(copy, ipAddress, packet.source))
}
// dump any remaining drops into the network
for (droppedStack in drops) {
if (droppedStack.isEmpty) continue
sendPacket(ItemStackPacket(droppedStack, ipAddress, IPAddress.BROADCAST))
}
}
}
class MinerInvProxy(val miner: MinerBlockEntity): GroupedItemInvView {
private var cachedState: BlockState? = null
private var cachedDrops: List<ItemStack>? = null
private val world: World
get() = miner.world!!
private val pos: BlockPos
get() = miner.pos!!
private val facing: Direction
get() = miner.facing
fun getDrops(recalculate: Boolean = false): List<ItemStack> {
val targetPos = pos.offset(facing)
val realState = world.getBlockState(targetPos)
// todo: does BlockState.equals actually work?
if (cachedDrops == null || realState != cachedState || recalculate) {
cachedState = realState
val be = if (realState.block.hasBlockEntity()) world.getBlockEntity(targetPos) else null
cachedDrops = Block.getDroppedStacks(realState, world as ServerWorld, targetPos, be)
}
return cachedDrops!!
}
override fun getStoredStacks(): Set<ItemStack> {
return getDrops().toSet()
}
override fun getTotalCapacity(): Int {
return Int.MAX_VALUE
}
override fun getStatistics(filter: ItemFilter): GroupedItemInvView.ItemInvStatistic {
var totalCount = 0
for (s in getDrops()) {
if (filter.matches(s)) {
totalCount += s.count
}
}
return GroupedItemInvView.ItemInvStatistic(filter, totalCount, 0, Int.MAX_VALUE)
}
}
}

View File

@ -1,6 +1,6 @@
package net.shadowfacts.phycon.network.block.terminal
import alexiil.mc.lib.attributes.item.GroupedItemInv
import alexiil.mc.lib.attributes.item.GroupedItemInvView
import alexiil.mc.lib.attributes.item.ItemStackCollections
import alexiil.mc.lib.attributes.item.ItemStackUtil
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap
@ -44,7 +44,7 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL), Invento
val INSERTION_TIMEOUT = 40
}
private val inventoryCache = mutableMapOf<IPAddress, GroupedItemInv>()
private val inventoryCache = mutableMapOf<IPAddress, GroupedItemInvView>()
val internalBuffer = TerminalBufferInventory(18)
private val locateRequestQueue = LinkedList<StackLocateRequest>()

View File

@ -1,13 +1,13 @@
package net.shadowfacts.phycon.network.packet
import alexiil.mc.lib.attributes.item.GroupedItemInv
import alexiil.mc.lib.attributes.item.GroupedItemInvView
import net.shadowfacts.phycon.api.util.IPAddress
/**
* @author shadowfacts
*/
class ReadInventoryPacket(
val inventory: GroupedItemInv,
val inventory: GroupedItemInvView,
source: IPAddress,
destination: IPAddress
): BasePacket(source, destination)

View File

@ -4,6 +4,7 @@
"block.phycon.terminal": "Terminal",
"block.phycon.cable": "Cable",
"block.phycon.extractor": "Inventory Extractor",
"block.phycon.miner": "Block Miner",
"item.phycon.screwdriver": "Screwdriver",
"item.phycon.console": "Console"