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

View File

@ -5,6 +5,7 @@ import net.minecraft.util.Identifier
import net.minecraft.util.registry.Registry import net.minecraft.util.registry.Registry
import net.shadowfacts.phycon.network.block.cable.CableBlock import net.shadowfacts.phycon.network.block.cable.CableBlock
import net.shadowfacts.phycon.network.block.extractor.ExtractorBlock 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.netinterface.InterfaceBlock
import net.shadowfacts.phycon.network.block.netswitch.SwitchBlock import net.shadowfacts.phycon.network.block.netswitch.SwitchBlock
import net.shadowfacts.phycon.network.block.terminal.TerminalBlock import net.shadowfacts.phycon.network.block.terminal.TerminalBlock
@ -21,6 +22,7 @@ object PhyBlocks {
val SWITCH = SwitchBlock() val SWITCH = SwitchBlock()
val CABLE = CableBlock() val CABLE = CableBlock()
val EXTRACTOR = ExtractorBlock() val EXTRACTOR = ExtractorBlock()
val MINER = MinerBlock()
val SOURCE = SourceBlock() val SOURCE = SourceBlock()
val DEST = DestBlock() val DEST = DestBlock()
@ -31,6 +33,7 @@ object PhyBlocks {
register(SwitchBlock.ID, SWITCH) register(SwitchBlock.ID, SWITCH)
register(CableBlock.ID, CABLE) register(CableBlock.ID, CABLE)
register(ExtractorBlock.ID, EXTRACTOR) register(ExtractorBlock.ID, EXTRACTOR)
register(MinerBlock.ID, MINER)
register(SourceBlock.ID, SOURCE) register(SourceBlock.ID, SOURCE)
register(DestBlock.ID, DEST) 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.item.ScrewdriverItem
import net.shadowfacts.phycon.network.block.cable.CableBlock import net.shadowfacts.phycon.network.block.cable.CableBlock
import net.shadowfacts.phycon.network.block.extractor.ExtractorBlock 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.netinterface.InterfaceBlock
import net.shadowfacts.phycon.network.block.netswitch.SwitchBlock import net.shadowfacts.phycon.network.block.netswitch.SwitchBlock
import net.shadowfacts.phycon.network.block.terminal.TerminalBlock import net.shadowfacts.phycon.network.block.terminal.TerminalBlock
@ -24,6 +25,7 @@ object PhyItems {
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 = BlockItem(PhyBlocks.EXTRACTOR, Item.Settings()) val EXTRACTOR = BlockItem(PhyBlocks.EXTRACTOR, Item.Settings())
val MINER = BlockItem(PhyBlocks.MINER, Item.Settings())
val SOURCE = BlockItem(PhyBlocks.SOURCE, Item.Settings()) val SOURCE = BlockItem(PhyBlocks.SOURCE, Item.Settings())
val DEST = BlockItem(PhyBlocks.DEST , Item.Settings()) val DEST = BlockItem(PhyBlocks.DEST , Item.Settings())
@ -37,6 +39,7 @@ object PhyItems {
register(SwitchBlock.ID, SWITCH) register(SwitchBlock.ID, SWITCH)
register(CableBlock.ID, CABLE) register(CableBlock.ID, CABLE)
register(ExtractorBlock.ID, EXTRACTOR) register(ExtractorBlock.ID, EXTRACTOR)
register(MinerBlock.ID, MINER)
register(SourceBlock.ID, SOURCE) register(SourceBlock.ID, SOURCE)
register(DestBlock.ID, DEST) 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 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.ItemStackCollections
import alexiil.mc.lib.attributes.item.ItemStackUtil import alexiil.mc.lib.attributes.item.ItemStackUtil
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap
@ -44,7 +44,7 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL), Invento
val INSERTION_TIMEOUT = 40 val INSERTION_TIMEOUT = 40
} }
private val inventoryCache = mutableMapOf<IPAddress, GroupedItemInv>() private val inventoryCache = mutableMapOf<IPAddress, GroupedItemInvView>()
val internalBuffer = TerminalBufferInventory(18) val internalBuffer = TerminalBufferInventory(18)
private val locateRequestQueue = LinkedList<StackLocateRequest>() private val locateRequestQueue = LinkedList<StackLocateRequest>()

View File

@ -1,13 +1,13 @@
package net.shadowfacts.phycon.network.packet 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 import net.shadowfacts.phycon.api.util.IPAddress
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
class ReadInventoryPacket( class ReadInventoryPacket(
val inventory: GroupedItemInv, val inventory: GroupedItemInvView,
source: IPAddress, source: IPAddress,
destination: IPAddress destination: IPAddress
): BasePacket(source, destination) ): BasePacket(source, destination)

View File

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