diff --git a/README.md b/README.md index 34b5b91..0a48885 100644 --- a/README.md +++ b/README.md @@ -4,14 +4,17 @@ A computer mod that aims to teach functional programming concepts through a tutorial book and a simple visual interface. Depends on: -- Fabric API -- Fabric Language Kotlin +- [Fabric API](https://www.curseforge.com/minecraft/mc-mods/fabric-api) +- [Fabric Language Kotlin](https://www.curseforge.com/minecraft/mc-mods/fabric-language-kotlin) +- [LibGui](https://github.com/CottonMC/LibGui) Recommended: -- Patchouli: The mod uses Patchouli for its documentation. **Don't leave - out Patchouli unless you know what you're doing.** +- [Patchouli](https://www.curseforge.com/minecraft/mc-mods/patchouli-fabric): + The mod uses Patchouli for its documentation. **Don't leave out Patchouli + unless you know what you're doing.** Suggested: -- Mod Menu: Shows mod information. -- Polymorph: Adds a recipe conflict resolver. Certain crafting recipes in - MonadMachines may conflict with other mods. +- [Mod Menu](https://modrinth.com/mod/modmenu): Shows mod information. +- [Polymorph](https://www.curseforge.com/minecraft/mc-mods/polymorph-fabric): + Adds a recipe conflict resolver. Certain crafting recipes in MonadMachines + may conflict with other mods. diff --git a/build.gradle b/build.gradle index 9f5a600..211ab80 100644 --- a/build.gradle +++ b/build.gradle @@ -20,6 +20,12 @@ repositories { // for Patchouli maven { url 'https://maven.blamejared.com' } + + // for LibGui + maven { + name = "CottonMC" + url = "https://server.bbkr.space/artifactory/libs-release" + } } dependencies { @@ -34,8 +40,10 @@ dependencies { modImplementation "net.fabricmc:fabric-language-kotlin:${project.fabric_kotlin_version}" // Patchouli - // modCompileOnly "vazkii.patchouli:Patchouli:1.16.4-48-FABRIC:api" modImplementation "vazkii.patchouli:Patchouli:1.16.4-48-FABRIC" + + // LibGui + modImplementation "io.github.cottonmc:LibGui:3.3.3+1.16.5" } processResources { diff --git a/src/main/kotlin/tf/bug/monadmachines/MonadMachines.kt b/src/main/kotlin/tf/bug/monadmachines/MonadMachines.kt index 98474dd..6e89db9 100644 --- a/src/main/kotlin/tf/bug/monadmachines/MonadMachines.kt +++ b/src/main/kotlin/tf/bug/monadmachines/MonadMachines.kt @@ -4,7 +4,6 @@ import net.fabricmc.api.EnvType import net.fabricmc.api.Environment import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder import net.fabricmc.fabric.api.client.screenhandler.v1.ScreenRegistry -import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry import net.minecraft.entity.player.PlayerInventory import net.minecraft.item.ItemGroup import net.minecraft.item.ItemStack @@ -13,7 +12,7 @@ import net.minecraft.util.Identifier import net.minecraft.util.registry.Registry import tf.bug.monadmachines.block.ProgramWorkstationBlock import tf.bug.monadmachines.block.ProgramWorkstationScreen -import tf.bug.monadmachines.block.ProgramWorkstationScreenHandler +import tf.bug.monadmachines.block.ProgramWorkstationGuiDescription import tf.bug.monadmachines.item.MonadMachinesManualItem import tf.bug.monadmachines.item.ProgramCardItem @@ -35,8 +34,8 @@ fun init() { @Suppress("unused") @Environment(EnvType.CLIENT) fun clientInit() { - ScreenRegistry.register(ProgramWorkstationScreenHandler.type) { - handler: ProgramWorkstationScreenHandler, inventory: PlayerInventory, title: Text -> - ProgramWorkstationScreen(handler, inventory, title) + ScreenRegistry.register(ProgramWorkstationGuiDescription.type) { + handler: ProgramWorkstationGuiDescription, inventory: PlayerInventory, title: Text -> + ProgramWorkstationScreen(handler, inventory.player, title) } } diff --git a/src/main/kotlin/tf/bug/monadmachines/block/ProgramWorkstationBlockEntity.kt b/src/main/kotlin/tf/bug/monadmachines/block/ProgramWorkstationBlockEntity.kt index c763841..e65feee 100644 --- a/src/main/kotlin/tf/bug/monadmachines/block/ProgramWorkstationBlockEntity.kt +++ b/src/main/kotlin/tf/bug/monadmachines/block/ProgramWorkstationBlockEntity.kt @@ -1,83 +1,58 @@ package tf.bug.monadmachines.block import net.minecraft.block.BlockState +import net.minecraft.block.InventoryProvider import net.minecraft.block.entity.BlockEntity import net.minecraft.block.entity.BlockEntityType +import net.minecraft.block.entity.LootableContainerBlockEntity import net.minecraft.entity.player.PlayerEntity import net.minecraft.entity.player.PlayerInventory import net.minecraft.inventory.Inventories import net.minecraft.inventory.Inventory +import net.minecraft.inventory.SidedInventory import net.minecraft.item.ItemStack import net.minecraft.nbt.CompoundTag import net.minecraft.screen.NamedScreenHandlerFactory import net.minecraft.screen.ScreenHandler +import net.minecraft.screen.ScreenHandlerContext import net.minecraft.text.Text import net.minecraft.text.TranslatableText import net.minecraft.util.collection.DefaultedList +import net.minecraft.util.math.BlockPos +import net.minecraft.world.WorldAccess import tf.bug.monadmachines.item.ProgramCardItem -class ProgramWorkstationBlockEntity : BlockEntity(type), NamedScreenHandlerFactory, Inventory { +class ProgramWorkstationBlockEntity : LootableContainerBlockEntity(type) { - private val card: DefaultedList = DefaultedList.ofSize(1, ItemStack.EMPTY) + private var card: DefaultedList = DefaultedList.ofSize(1, ItemStack.EMPTY) companion object { val type: BlockEntityType = BlockEntityType.Builder.create({ ProgramWorkstationBlockEntity() }, ProgramWorkstationBlock).build(null) } - override fun createMenu(syncId: Int, inv: PlayerInventory, player: PlayerEntity): ScreenHandler { - return ProgramWorkstationScreenHandler(syncId, inv, this) + override fun createScreenHandler(syncId: Int, inv: PlayerInventory): ScreenHandler { + return ProgramWorkstationGuiDescription(syncId, inv, ScreenHandlerContext.create(world, pos)) } - override fun getDisplayName(): Text { + override fun getContainerName(): Text { return TranslatableText(cachedState.block.translationKey) } - override fun clear() { - card.clear() + override fun getInvStackList(): DefaultedList { + return card + } + + override fun setInvStackList(list: DefaultedList) { + card = list } override fun size(): Int { - return card.size - } - - override fun isEmpty(): Boolean { - return card.isEmpty() - } - - override fun getStack(slot: Int): ItemStack { - return card[slot] - } - - override fun removeStack(slot: Int, amount: Int): ItemStack { - val result = Inventories.splitStack(card, slot, amount) - if (!result.isEmpty) { - markDirty() - } - return result - } - - override fun removeStack(slot: Int): ItemStack { - return Inventories.removeStack(card, slot) - } - - override fun setStack(slot: Int, stack: ItemStack) { - card[slot] = stack - if (stack.count > maxCountPerStack) { - stack.count = maxCountPerStack; - } - } - - override fun canPlayerUse(player: PlayerEntity?): Boolean { - return true - } - - override fun getMaxCountPerStack(): Int { return 1 } override fun isValid(slot: Int, stack: ItemStack): Boolean { - return slot == 0 && (stack.item is ProgramCardItem && stack.count <= 1) + return stack.isEmpty || stack.item is ProgramCardItem } override fun fromTag(state: BlockState, tag: CompoundTag) { diff --git a/src/main/kotlin/tf/bug/monadmachines/block/ProgramWorkstationGuiDescription.kt b/src/main/kotlin/tf/bug/monadmachines/block/ProgramWorkstationGuiDescription.kt new file mode 100644 index 0000000..cf73232 --- /dev/null +++ b/src/main/kotlin/tf/bug/monadmachines/block/ProgramWorkstationGuiDescription.kt @@ -0,0 +1,39 @@ +package tf.bug.monadmachines.block + +import io.github.cottonmc.cotton.gui.SyncedGuiDescription +import io.github.cottonmc.cotton.gui.widget.WGridPanel +import io.github.cottonmc.cotton.gui.widget.WItemSlot +import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry +import net.minecraft.entity.player.PlayerInventory +import net.minecraft.screen.ScreenHandlerContext +import net.minecraft.screen.ScreenHandlerType + +class ProgramWorkstationGuiDescription(syncId: Int, playerInventory: PlayerInventory, context: ScreenHandlerContext) : SyncedGuiDescription(type, syncId, playerInventory, getBlockInventory(context, inventorySize), getBlockPropertyDelegate(context)) { + + init { + val root = WGridPanel() + setRootPanel(root) + root.setSize(300, 200) + + val itemSlot = WItemSlot.of(blockInventory, 0) + root.add(itemSlot, 4, 1) + + root.add(this.createPlayerInventoryPanel(), 0, 3) + + root.validate(this) + } + + companion object { + const val inventorySize: Int = 1 + + val type: ScreenHandlerType = + ScreenHandlerRegistry.registerSimple(ProgramWorkstationBlock.id) { syncId: Int, playerInventory: PlayerInventory -> + ProgramWorkstationGuiDescription( + syncId, + playerInventory, + ScreenHandlerContext.EMPTY + ) + } + } + +} diff --git a/src/main/kotlin/tf/bug/monadmachines/block/ProgramWorkstationScreen.kt b/src/main/kotlin/tf/bug/monadmachines/block/ProgramWorkstationScreen.kt index 2d65835..11e3d9d 100644 --- a/src/main/kotlin/tf/bug/monadmachines/block/ProgramWorkstationScreen.kt +++ b/src/main/kotlin/tf/bug/monadmachines/block/ProgramWorkstationScreen.kt @@ -1,26 +1,12 @@ package tf.bug.monadmachines.block -import net.minecraft.client.gui.screen.ingame.HandledScreen +import io.github.cottonmc.cotton.gui.GuiDescription +import io.github.cottonmc.cotton.gui.client.CottonInventoryScreen import net.minecraft.client.util.math.MatrixStack +import net.minecraft.entity.player.PlayerEntity import net.minecraft.entity.player.PlayerInventory import net.minecraft.text.Text -class ProgramWorkstationScreen(handler: ProgramWorkstationScreenHandler, inventory: PlayerInventory, title: Text) : HandledScreen(handler, inventory, title) { - - override fun drawBackground(matrices: MatrixStack, delta: Float, mouseX: Int, mouseY: Int) { - // TODO - } - - override fun render(matrices: MatrixStack, mouseX: Int, mouseY: Int, delta: Float) { - renderBackground(matrices) - super.render(matrices, mouseX, mouseY, delta) - drawMouseoverTooltip(matrices, mouseX, mouseY) - } - - override fun init() { - super.init() - - titleX = (backgroundWidth - textRenderer.getWidth(title)) / 2 - } +class ProgramWorkstationScreen(gui: ProgramWorkstationGuiDescription, player: PlayerEntity, title: Text) : CottonInventoryScreen(gui, player, title) { } diff --git a/src/main/kotlin/tf/bug/monadmachines/block/ProgramWorkstationScreenHandler.kt b/src/main/kotlin/tf/bug/monadmachines/block/ProgramWorkstationScreenHandler.kt deleted file mode 100644 index 3864567..0000000 --- a/src/main/kotlin/tf/bug/monadmachines/block/ProgramWorkstationScreenHandler.kt +++ /dev/null @@ -1,44 +0,0 @@ -package tf.bug.monadmachines.block - -import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry -import net.minecraft.entity.player.PlayerEntity -import net.minecraft.entity.player.PlayerInventory -import net.minecraft.inventory.Inventory -import net.minecraft.inventory.SimpleInventory -import net.minecraft.screen.ScreenHandler -import net.minecraft.screen.ScreenHandlerType -import net.minecraft.screen.slot.Slot - -class ProgramWorkstationScreenHandler(syncId: Int, playerInventory: PlayerInventory, inventory: Inventory) : ScreenHandler(type, syncId) { - - private val inventory: Inventory - - init { - checkSize(inventory, 1) - this.inventory = inventory - inventory.onOpen(playerInventory.player) - - for(m in 0..2) { - for(l in 0..8) { - addSlot(Slot(playerInventory, l + m * 9 + 9, 8 + l * 18, 84 + m * 18)) - } - } - } - - companion object { - val type: ScreenHandlerType = - ScreenHandlerRegistry.registerSimple(ProgramWorkstationBlock.id) { syncId: Int, playerInventory: PlayerInventory -> - ProgramWorkstationScreenHandler( - syncId, - playerInventory - ) - } - } - - constructor(syncId: Int, playerInventory: PlayerInventory) : this(syncId, playerInventory, SimpleInventory(1)) - - override fun canUse(player: PlayerEntity?): Boolean { - return this.inventory.canPlayerUse(player) - } - -}