From 64c18e9eae9643c940446027109fcd666c4c906d Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Tue, 29 Oct 2019 15:15:27 -0400 Subject: [PATCH] Start adding terminal container and GUI --- .../phycon/PhysicalConnectivity.kt | 18 +++++++- .../phycon/PhysicalConnectivityClient.kt | 22 +++++++++ .../network/block/terminal/TerminalBlock.kt | 4 +- .../block/terminal/TerminalBlockEntity.kt | 36 ++++++++++++++- .../block/terminal/TerminalContainer.kt | 42 ++++++++++++++++++ .../network/block/terminal/TerminalScreen.kt | 40 +++++++++++++++++ .../kotlin/net/shadowfacts/phycon/util/nbt.kt | 34 ++++++++++++++ .../assets/phycon/textures/gui/terminal.png | Bin 0 -> 10143 bytes src/main/resources/fabric.mod.json | 8 +++- 9 files changed, 198 insertions(+), 6 deletions(-) create mode 100644 src/main/kotlin/net/shadowfacts/phycon/PhysicalConnectivityClient.kt create mode 100644 src/main/kotlin/net/shadowfacts/phycon/network/block/terminal/TerminalContainer.kt create mode 100644 src/main/kotlin/net/shadowfacts/phycon/network/block/terminal/TerminalScreen.kt create mode 100644 src/main/kotlin/net/shadowfacts/phycon/util/nbt.kt create mode 100644 src/main/resources/assets/phycon/textures/gui/terminal.png diff --git a/src/main/kotlin/net/shadowfacts/phycon/PhysicalConnectivity.kt b/src/main/kotlin/net/shadowfacts/phycon/PhysicalConnectivity.kt index 889b255..54e1321 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/PhysicalConnectivity.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/PhysicalConnectivity.kt @@ -1,9 +1,17 @@ package net.shadowfacts.phycon 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.PhyBlocks import net.shadowfacts.phycon.init.PhyItems +import net.shadowfacts.phycon.network.block.terminal.TerminalBlock +import net.shadowfacts.phycon.network.block.terminal.TerminalContainer /** * @author shadowfacts @@ -16,5 +24,13 @@ object PhysicalConnectivity: ModInitializer { PhyBlocks.init() PhyBlockEntities.init() PhyItems.init() + ContainerProviderRegistry.INSTANCE.registerFactory(TerminalContainer.ID, ContainerFactory(::createTerminalContainer)) } -} \ No newline at end of file + + 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) + } + +} diff --git a/src/main/kotlin/net/shadowfacts/phycon/PhysicalConnectivityClient.kt b/src/main/kotlin/net/shadowfacts/phycon/PhysicalConnectivityClient.kt new file mode 100644 index 0000000..60b1fc4 --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/phycon/PhysicalConnectivityClient.kt @@ -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) + } +} diff --git a/src/main/kotlin/net/shadowfacts/phycon/network/block/terminal/TerminalBlock.kt b/src/main/kotlin/net/shadowfacts/phycon/network/block/terminal/TerminalBlock.kt index 8a068d7..6658866 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/network/block/terminal/TerminalBlock.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/network/block/terminal/TerminalBlock.kt @@ -31,8 +31,8 @@ class TerminalBlock: BlockWithEntity(Settings.of(Material.M 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 { - getBlockEntity(world_1!!, blockPos_1!!)!!.onActivate() + override fun activate(state: BlockState, world: World, pos: BlockPos, player: PlayerEntity, hand: Hand, hitResult: BlockHitResult): Boolean { + getBlockEntity(world, pos)!!.onActivate(player) return true } diff --git a/src/main/kotlin/net/shadowfacts/phycon/network/block/terminal/TerminalBlockEntity.kt b/src/main/kotlin/net/shadowfacts/phycon/network/block/terminal/TerminalBlockEntity.kt index 03f3197..3307e8e 100644 --- a/src/main/kotlin/net/shadowfacts/phycon/network/block/terminal/TerminalBlockEntity.kt +++ b/src/main/kotlin/net/shadowfacts/phycon/network/block/terminal/TerminalBlockEntity.kt @@ -2,7 +2,13 @@ package net.shadowfacts.phycon.network.block.terminal import alexiil.mc.lib.attributes.item.GroupedItemInv 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.nbt.CompoundTag import net.shadowfacts.phycon.api.packet.Packet import net.shadowfacts.phycon.api.util.MACAddress 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.ReadInventoryPacket import net.shadowfacts.phycon.network.packet.RequestInventoryPacket +import net.shadowfacts.phycon.util.fromTag +import net.shadowfacts.phycon.util.toTag /** * @author shadowfacts */ -class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL) { +class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL), InventoryListener { private val inventoryCache = mutableMapOf() + val internalBuffer = BasicInventory(18) + + init { + internalBuffer.addListener(this) + } override fun handlePacket(packet: Packet) { when (packet) { @@ -46,11 +59,30 @@ class TerminalBlockEntity: DeviceBlockEntity(PhyBlockEntities.TERMINAL) { return net } - fun onActivate() { + fun onActivate(player: PlayerEntity) { if (!world!!.isClient) { inventoryCache.clear() 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)) + } + } diff --git a/src/main/kotlin/net/shadowfacts/phycon/network/block/terminal/TerminalContainer.kt b/src/main/kotlin/net/shadowfacts/phycon/network/block/terminal/TerminalContainer.kt new file mode 100644 index 0000000..9483196 --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/phycon/network/block/terminal/TerminalContainer.kt @@ -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 + } +} diff --git a/src/main/kotlin/net/shadowfacts/phycon/network/block/terminal/TerminalScreen.kt b/src/main/kotlin/net/shadowfacts/phycon/network/block/terminal/TerminalScreen.kt new file mode 100644 index 0000000..23c6386 --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/phycon/network/block/terminal/TerminalScreen.kt @@ -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(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) + + } + +} diff --git a/src/main/kotlin/net/shadowfacts/phycon/util/nbt.kt b/src/main/kotlin/net/shadowfacts/phycon/util/nbt.kt new file mode 100644 index 0000000..47a6d3e --- /dev/null +++ b/src/main/kotlin/net/shadowfacts/phycon/util/nbt.kt @@ -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) + } +} diff --git a/src/main/resources/assets/phycon/textures/gui/terminal.png b/src/main/resources/assets/phycon/textures/gui/terminal.png new file mode 100644 index 0000000000000000000000000000000000000000..7fd4d1386faa2e45945bf101536365de0bf05a18 GIT binary patch literal 10143 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 qLvJc(m&+-uf literal 0 HcmV?d00001 diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index bcde358..793fb9d 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -19,6 +19,12 @@ "adapter": "kotlin", "value": "net.shadowfacts.phycon.PhysicalConnectivity" } + ], + "client": [ + { + "adapter": "kotlin", + "value": "net.shadowfacts.phycon.PhysicalConnectivityClient" + } ] }, "mixins": [ @@ -29,4 +35,4 @@ "fabric": "*", "fabric-language-kotlin": ">=1.3.50" } -} \ No newline at end of file +}