Add Miner block
This commit is contained in:
parent
649408c509
commit
0f7689d73c
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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>()
|
||||
|
|
|
@ -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,
|
||||
source: IPAddress,
|
||||
destination: IPAddress
|
||||
val inventory: GroupedItemInvView,
|
||||
source: IPAddress,
|
||||
destination: IPAddress
|
||||
): BasePacket(source, destination)
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue