Start adding terminal container and GUI

This commit is contained in:
Shadowfacts 2019-10-29 15:15:27 -04:00
parent 0c5e353525
commit 64c18e9eae
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
9 changed files with 198 additions and 6 deletions

View File

@ -1,9 +1,17 @@
package net.shadowfacts.phycon package net.shadowfacts.phycon
import net.fabricmc.api.ModInitializer import net.fabricmc.api.ModInitializer
import net.fabricmc.fabric.api.container.ContainerFactory
import net.fabricmc.fabric.api.container.ContainerProviderRegistry
import net.minecraft.container.Container
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.util.Identifier
import net.minecraft.util.PacketByteBuf
import net.shadowfacts.phycon.init.PhyBlockEntities import net.shadowfacts.phycon.init.PhyBlockEntities
import net.shadowfacts.phycon.init.PhyBlocks import net.shadowfacts.phycon.init.PhyBlocks
import net.shadowfacts.phycon.init.PhyItems import net.shadowfacts.phycon.init.PhyItems
import net.shadowfacts.phycon.network.block.terminal.TerminalBlock
import net.shadowfacts.phycon.network.block.terminal.TerminalContainer
/** /**
* @author shadowfacts * @author shadowfacts
@ -16,5 +24,13 @@ object PhysicalConnectivity: ModInitializer {
PhyBlocks.init() PhyBlocks.init()
PhyBlockEntities.init() PhyBlockEntities.init()
PhyItems.init() PhyItems.init()
ContainerProviderRegistry.INSTANCE.registerFactory(TerminalContainer.ID, ContainerFactory(::createTerminalContainer))
} }
private fun createTerminalContainer(syncId: Int, identifier: Identifier, player: PlayerEntity, buf: PacketByteBuf): Container {
val pos = buf.readBlockPos()
val terminalEntity = PhyBlocks.TERMINAL.getBlockEntity(player.world, pos)!!
return TerminalContainer(syncId, player.inventory, terminalEntity)
}
} }

View File

@ -0,0 +1,22 @@
package net.shadowfacts.phycon
import net.fabricmc.api.ClientModInitializer
import net.fabricmc.fabric.api.client.screen.ContainerScreenFactory
import net.fabricmc.fabric.api.client.screen.ScreenProviderRegistry
import net.minecraft.client.MinecraftClient
import net.minecraft.util.Identifier
import net.shadowfacts.phycon.network.block.terminal.TerminalContainer
import net.shadowfacts.phycon.network.block.terminal.TerminalScreen
/**
* @author shadowfacts
*/
object PhysicalConnectivityClient: ClientModInitializer {
override fun onInitializeClient() {
ScreenProviderRegistry.INSTANCE.registerFactory(TerminalContainer.ID, ContainerScreenFactory(::createTerminalScreen))
}
fun createTerminalScreen(container: TerminalContainer): TerminalScreen {
return TerminalScreen(container, MinecraftClient.getInstance().player.inventory)
}
}

View File

@ -31,8 +31,8 @@ class TerminalBlock: BlockWithEntity<TerminalBlockEntity>(Settings.of(Material.M
override fun createBlockEntity(world: BlockView) = TerminalBlockEntity() override fun createBlockEntity(world: BlockView) = TerminalBlockEntity()
override fun activate(blockState_1: BlockState?, world_1: World?, blockPos_1: BlockPos?, playerEntity_1: PlayerEntity?, hand_1: Hand?, blockHitResult_1: BlockHitResult?): Boolean { override fun activate(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, hitResult: BlockHitResult): Boolean {
getBlockEntity(world_1!!, blockPos_1!!)!!.onActivate() getBlockEntity(world, pos)!!.onActivate(player)
return true return true
} }

View File

@ -2,7 +2,13 @@ package net.shadowfacts.phycon.network.block.terminal
import alexiil.mc.lib.attributes.item.GroupedItemInv import alexiil.mc.lib.attributes.item.GroupedItemInv
import alexiil.mc.lib.attributes.item.ItemStackCollections import alexiil.mc.lib.attributes.item.ItemStackCollections
import net.fabricmc.fabric.api.container.ContainerProviderRegistry
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.inventory.BasicInventory
import net.minecraft.inventory.Inventory
import net.minecraft.inventory.InventoryListener
import net.minecraft.item.ItemStack import net.minecraft.item.ItemStack
import net.minecraft.nbt.CompoundTag
import net.shadowfacts.phycon.api.packet.Packet import net.shadowfacts.phycon.api.packet.Packet
import net.shadowfacts.phycon.api.util.MACAddress import net.shadowfacts.phycon.api.util.MACAddress
import net.shadowfacts.phycon.init.PhyBlockEntities import net.shadowfacts.phycon.init.PhyBlockEntities
@ -10,13 +16,20 @@ import net.shadowfacts.phycon.network.DeviceBlockEntity
import net.shadowfacts.phycon.network.packet.DeviceRemovedPacket import net.shadowfacts.phycon.network.packet.DeviceRemovedPacket
import net.shadowfacts.phycon.network.packet.ReadInventoryPacket import net.shadowfacts.phycon.network.packet.ReadInventoryPacket
import net.shadowfacts.phycon.network.packet.RequestInventoryPacket import net.shadowfacts.phycon.network.packet.RequestInventoryPacket
import net.shadowfacts.phycon.util.fromTag
import net.shadowfacts.phycon.util.toTag
/** /**
* @author shadowfacts * @author shadowfacts
*/ */
class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL) { class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL), InventoryListener {
private val inventoryCache = mutableMapOf<MACAddress, GroupedItemInv>() private val inventoryCache = mutableMapOf<MACAddress, GroupedItemInv>()
val internalBuffer = BasicInventory(18)
init {
internalBuffer.addListener(this)
}
override fun handlePacket(packet: Packet) { override fun handlePacket(packet: Packet) {
when (packet) { when (packet) {
@ -46,11 +59,30 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL) {
return net return net
} }
fun onActivate() { fun onActivate(player: PlayerEntity) {
if (!world!!.isClient) { if (!world!!.isClient) {
inventoryCache.clear() inventoryCache.clear()
enqueueToSingle(RequestInventoryPacket(macAddress)) enqueueToSingle(RequestInventoryPacket(macAddress))
ContainerProviderRegistry.INSTANCE.openContainer(TerminalContainer.ID, player) { buf ->
buf.writeBlockPos(pos)
}
} }
} }
override fun onInvChange(inv: Inventory) {
if (inv == internalBuffer) {
markDirty()
}
}
override fun toTag(tag: CompoundTag): CompoundTag {
tag.put("InternalBuffer", internalBuffer.toTag())
return super.toTag(tag)
}
override fun fromTag(tag: CompoundTag) {
super.fromTag(tag)
internalBuffer.fromTag(tag.getList("InternalBuffer", 10))
}
} }

View File

@ -0,0 +1,42 @@
package net.shadowfacts.phycon.network.block.terminal
import net.minecraft.container.Container
import net.minecraft.container.Slot
import net.minecraft.entity.player.PlayerEntity
import net.minecraft.entity.player.PlayerInventory
import net.minecraft.util.Identifier
import net.shadowfacts.phycon.PhysicalConnectivity
/**
* @author shadowfacts
*/
class TerminalContainer(syncId: Int, playerInv: PlayerInventory, val terminal: TerminalBlockEntity): Container(null, syncId) {
companion object {
val ID = Identifier(PhysicalConnectivity.MODID, "terminal")
}
init {
// internal buffer
for (y in 0 until 6) {
for (x in 0 until 3) {
addSlot(Slot(terminal.internalBuffer, y * 3 + x, 8 + x * 18, 18 + y * 18))
}
}
// player inv
for (y in 0 until 3) {
for (x in 0 until 9) {
addSlot(Slot(playerInv, x + y * 9 + 9, 66 + x * 18, 140 + y * 18))
}
}
// hotbar
for (x in 0 until 9) {
addSlot(Slot(playerInv, x, 66 + x * 18, 198))
}
}
override fun canUse(player: PlayerEntity): Boolean {
return true
}
}

View File

@ -0,0 +1,40 @@
package net.shadowfacts.phycon.network.block.terminal
import com.mojang.blaze3d.platform.GlStateManager
import net.minecraft.client.gui.screen.ingame.AbstractContainerScreen
import net.minecraft.entity.player.PlayerInventory
import net.minecraft.text.LiteralText
import net.minecraft.util.Identifier
import net.shadowfacts.phycon.PhysicalConnectivity
/**
* @author shadowfacts
*/
// todo: translate title
class TerminalScreen(container: TerminalContainer, playerInv: PlayerInventory): AbstractContainerScreen<TerminalContainer>(container, playerInv, LiteralText("Terminal")) {
companion object {
val BACKGROUND = Identifier(PhysicalConnectivity.MODID, "textures/gui/terminal.png")
}
init {
containerWidth = 252
containerHeight = 222
}
override fun drawForeground(mouseX: Int, mouseY: Int) {
font.draw(title.asFormattedString(), 65f, 6f, 0x404040)
font.draw(playerInventory.displayName.asFormattedString(), 65f, containerHeight - 94f, 0x404040)
// todo: translate this
font.draw("Buffer", 7f, 6f, 0x404040)
}
override fun drawBackground(delta: Float, mouseX: Int, mouseY: Int) {
GlStateManager.color4f(1f, 1f, 1f, 1f)
minecraft!!.textureManager.bindTexture(BACKGROUND)
val x = (width - containerWidth) / 2
val y = (height - containerHeight) / 2
blit(x, y, 0, 0, containerWidth, containerHeight)
}
}

View File

@ -0,0 +1,34 @@
package net.shadowfacts.phycon.util
import net.minecraft.inventory.BasicInventory
import net.minecraft.item.ItemStack
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.ListTag
import java.lang.RuntimeException
/**
* @author shadowfacts
*/
fun BasicInventory.toTag(): ListTag {
val list = ListTag()
for (slot in 0 until invSize) {
val stack = getInvStack(slot)
if (!stack.isEmpty) {
val stackTag = stack.toTag(CompoundTag())
stackTag.putInt("Slot", slot)
list.add(stackTag)
}
}
return list
}
fun BasicInventory.fromTag(list: ListTag) {
if (list.listType != 10) throw RuntimeException("Can't decode BasicInventory from list tag that does not contain compound tags")
this.clear()
for (tag in list) {
val compound = tag as CompoundTag
val stack = ItemStack.fromTag(compound)
val slot = compound.getInt("Slot")
setInvStack(slot, stack)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

@ -19,6 +19,12 @@
"adapter": "kotlin", "adapter": "kotlin",
"value": "net.shadowfacts.phycon.PhysicalConnectivity" "value": "net.shadowfacts.phycon.PhysicalConnectivity"
} }
],
"client": [
{
"adapter": "kotlin",
"value": "net.shadowfacts.phycon.PhysicalConnectivityClient"
}
] ]
}, },
"mixins": [ "mixins": [