Dynamic slot

This commit is contained in:
mewhenthe
2026-04-18 19:48:40 +02:00
parent 07c8dc914d
commit 15b6b2c5ad
25 changed files with 188 additions and 12 deletions

View File

@@ -31,6 +31,7 @@ object Blocks {
val CAPACITOR_BLOCK3: RegistrySupplier<Block> = BaseBlock.register("capacitor3") { CapacitorBlock(3) }
val SOLARGEN_BLOCK: RegistrySupplier<Block> = BaseBlock.register("solargen") { SolarGeneratorBlock() }
val COMBUSTGEN_BLOCK: RegistrySupplier<Block> = BaseBlock.register("combustgen") { CombustionGeneratorBlock() }
val CASE_BLOCK: RegistrySupplier<Block> = BaseBlock.register("case") { CaseBlock() }
fun registerBlockItems() {
BLOCKS.forEach(Consumer { sup: RegistrySupplier<Block> ->

View File

@@ -0,0 +1,44 @@
package org.neoflock.neocomputers.block;
import dev.architectury.registry.menu.MenuRegistry
import net.minecraft.core.BlockPos
import net.minecraft.network.chat.Component
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.InteractionHand
import net.minecraft.world.InteractionResult
import net.minecraft.world.MenuProvider
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.EntityBlock
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.phys.BlockHitResult
import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.entity.BlockEntities
import org.neoflock.neocomputers.entity.ScreenEntity
import org.neoflock.neocomputers.gui.menu.Menus
import org.neoflock.neocomputers.gui.menu.ScreenMenu
import org.neoflock.neocomputers.network.Networking
class CaseBlock() : BaseBlock() { // placeholder stuff
override fun useWithoutItem(
blockState: BlockState,
level: Level,
blockPos: BlockPos,
player: Player,
blockHitResult: BlockHitResult
): InteractionResult {
if(!level.isClientSide) {
MenuRegistry.openMenu(player as ServerPlayer, object : MenuProvider {
override fun getDisplayName(): Component = Component.literal("Computer")
override fun createMenu(i: Int, inventory: Inventory, player: Player): AbstractContainerMenu {
return Menus.CASE_MENU.get().create(i, inventory);
}
})
}
return InteractionResult.SUCCESS
}
}

View File

@@ -0,0 +1,36 @@
package org.neoflock.neocomputers.gui.menu;
import net.minecraft.world.SimpleContainer
import net.minecraft.world.entity.player.Inventory
import org.neoflock.neocomputers.gui.menu.Menus;
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.inventory.MenuType
import net.minecraft.world.item.ItemStack
import org.neoflock.neocomputers.gui.widget.DynamicSlot
import org.neoflock.neocomputers.utils.GenericContainerMenu
class CaseMenu : GenericContainerMenu {
constructor(i: Int, inv: Inventory) : super(Menus.CASE_MENU.get(), i, SimpleContainer(10)) {
this.addInventorySlots(inv, 8, 84)
for (col in 0..2) {
for (row in 0..2) {
var i = col*3+row
this.addSlot(DynamicSlot(this.container!!, i, 98+(col*22), 18*(row+1)-2))
}
}
// for (int col=1; col<4; col++) {
// for (int row=1; row<4; row++) {
// int i = (row-1)*3+(col-1);
// if(slotmap[tier][i] != null) {
// this.addSlot(new ComponentSlot(entity.getContainer(), ((col-1)*3)+row, 98+((col-1)*22), 18*row-2, slotmap[tier][i], tiermap[tier][i]));
// }
// }
// }
}
override fun stillValid(player: Player) = true // TODO: implement this properly
override fun quickMoveStack(player: Player, i: Int): ItemStack = ItemStack.EMPTY // there's no container here anyways
}

View File

@@ -7,10 +7,11 @@ import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.inventory.Slot
import net.minecraft.world.item.ItemStack
import org.neoflock.neocomputers.gui.widget.DynamicSlot
import org.neoflock.neocomputers.utils.ContainerUtils
import org.neoflock.neocomputers.utils.GenericContainerMenu
class CombustionFuelSlot(container: Container, slot: Int, x: Int, y: Int): Slot(container, slot, x, y) {
class CombustionFuelSlot(container: Container, slot: Int, x: Int, y: Int): DynamicSlot(container, slot, x, y) {
override fun mayPlace(itemStack: ItemStack): Boolean {
return ContainerUtils.isBurningFuel(itemStack)
}

View File

@@ -10,6 +10,7 @@ import net.minecraft.world.flag.FeatureFlags
import net.minecraft.world.inventory.MenuType
import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.gui.menu.ScreenMenu
import org.neoflock.neocomputers.gui.screen.CaseScreen
import org.neoflock.neocomputers.gui.screen.CombustionGeneratorScreen
import org.neoflock.neocomputers.gui.screen.ScreenScreen
@@ -18,9 +19,11 @@ object Menus {
val SCREEN_MENU: RegistrySupplier<MenuType<ScreenMenu>> = MENUS.register("screen_menu") { MenuType(::ScreenMenu, FeatureFlagSet.of()) }
val COMBUSTGEN_MENU: RegistrySupplier<MenuType<CombustionGeneratorMenu>> = MENUS.register("combustgen_menu") { MenuType(::CombustionGeneratorMenu, FeatureFlagSet.of() ) }
val CASE_MENU: RegistrySupplier<MenuType<CaseMenu>> = MENUS.register("case_menu") { MenuType(::CaseMenu, FeatureFlagSet.of() )}
fun registerScreens() {
MenuScreens.register(Menus.COMBUSTGEN_MENU.get(), {m: CombustionGeneratorMenu, u, comp -> CombustionGeneratorScreen(m, u, comp)})
MenuScreens.register(Menus.COMBUSTGEN_MENU.get()) { m: CombustionGeneratorMenu, u, comp ->CombustionGeneratorScreen(m,u,comp)}
MenuScreens.register(Menus.SCREEN_MENU.get(), ::ScreenScreen)
MenuScreens.register(Menus.CASE_MENU.get(), ::CaseScreen)
}
}

View File

@@ -6,9 +6,8 @@ import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.inventory.MenuType
import net.minecraft.world.item.ItemStack
import org.neoflock.neocomputers.utils.GenericContainerMenu
class ScreenMenu(i: Int, inv: Inventory) : GenericContainerMenu(Menus.SCREEN_MENU.get(), i, null) {
class ScreenMenu(i: Int, inv: Inventory) : AbstractContainerMenu(Menus.SCREEN_MENU.get(), i) {
override fun stillValid(player: Player) = true // TODO: implement this properly
override fun quickMoveStack(player: Player, i: Int): ItemStack = ItemStack.EMPTY // there's no container here anyways

View File

@@ -64,9 +64,9 @@ class BufferRenderer(private var width: Int, private var height: Int, private va
}
fun clean() {
Minecraft.getInstance().textureManager.release(this.id)
image.close()
tex.close()
Minecraft.getInstance().textureManager.release(this.id)
}
data class GPUChar(val c: Char, val fg: Int =0xFFFFFF, val bg: Int = 0)

View File

@@ -0,0 +1,39 @@
package org.neoflock.neocomputers.gui.screen;
import com.mojang.blaze3d.vertex.BufferBuilder
import com.mojang.blaze3d.vertex.DefaultVertexFormat
import com.mojang.blaze3d.vertex.Tesselator
import com.mojang.blaze3d.vertex.VertexFormat
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen
import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.entity.player.Inventory
import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.gui.menu.CaseMenu
import org.neoflock.neocomputers.gui.widget.DynamicSlot
import org.neoflock.neocomputers.utils.GenericContainerScreen
class CaseScreen : GenericContainerScreen<CaseMenu> {
private val PCB: ResourceLocation = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/gui/computer.png")
constructor(abstractContainerMenu: CaseMenu, inventory: Inventory, component: Component) : super(abstractContainerMenu, inventory, component)
override fun renderBg(guiGraphics: GuiGraphics, f: Float, i: Int, j: Int) {
super.renderBg(guiGraphics, f, i ,j)
val relX = (this.width - this.imageWidth) / 2
val relY = (this.height - this.imageHeight) / 2
guiGraphics.blit(PCB, relX, relY, 0, 0, this.imageWidth, this.imageHeight)
// this.renderSlots(relX, relY)
}
// private fun renderSlots(relX: Int, relY: Int) { // TODO: put this in some generic screen class
// for (slot in menu.slots) {
// if (slot is DynamicSlot) {
// slot.draw(relX, relY)
// }
// }
// }
}

View File

@@ -13,7 +13,7 @@ import org.neoflock.neocomputers.utils.GenericContainerScreen
class CombustionGeneratorScreen(abstractContainerMenu: CombustionGeneratorMenu, inventory: Inventory, component: Component) : GenericContainerScreen<CombustionGeneratorMenu>(abstractContainerMenu, inventory, component) {
// override fun findMenuTexture(): ResourceLocation = ResourceLocation.withDefaultNamespace("textures/gui/container/dispenser.png")
override fun findMenuTexture(): ResourceLocation = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/gui/combustgui.png")
override fun findMenuTexture(): ResourceLocation = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/gui/background.png")
var energy: Long = 0
var energyCapacity: Long = 1

View File

@@ -28,7 +28,6 @@ class ScreenScreen : AbstractContainerScreen<ScreenMenu>{
bufferRenderer!!.drawBuffer()
renderer.bind(ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "screen/test"))
NeoComputers.LOGGER.info("created")
}
override fun renderBg(guiGraphics: GuiGraphics, f: Float, i: Int, j: Int) {}
override fun render(graphics: GuiGraphics, mouseX: Int, mouseY: Int, something: Float) {
@@ -37,6 +36,7 @@ class ScreenScreen : AbstractContainerScreen<ScreenMenu>{
}
override fun onClose() {
super.onClose()
bufferRenderer!!.clean()
}
}

View File

@@ -0,0 +1,45 @@
package org.neoflock.neocomputers.gui.widget
import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.BufferBuilder
import com.mojang.blaze3d.vertex.BufferUploader
import com.mojang.blaze3d.vertex.DefaultVertexFormat
import com.mojang.blaze3d.vertex.Tesselator
import com.mojang.blaze3d.vertex.VertexFormat
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.renderer.GameRenderer
import net.minecraft.client.renderer.RenderType
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.Container
import net.minecraft.world.inventory.Slot
import org.neoflock.neocomputers.NeoComputers
open class DynamicSlot(container: Container, slot: Int, x: Int, y: Int) : Slot(container, slot, x, y) {
val BACKGROUND: ResourceLocation = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/gui/slots/slot.png")
fun draw(graphics: GuiGraphics, relX: Int, relY: Int, mouseX: Int, mouseY: Int) {
RenderSystem.enableBlend() // background
RenderSystem.setShaderTexture(0, BACKGROUND)
RenderSystem.setShader { GameRenderer.getPositionTexShader() }
drawQuad(relX+x-1, relY+y-1, 18, 18, 0F, 0F, 15F, 15F)
RenderSystem.disableBlend()
}
private fun drawQuad(x: Int, y: Int, width: Int, height: Int, u1: Float, v1: Float, u2: Float, v2: Float) {
var t: Tesselator = Tesselator.getInstance()
var builder: BufferBuilder = t.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX)
builder.addVertex(x.toFloat(), (y+height).toFloat(), 1f).setUv(u1/15F, v2/15F)
builder.addVertex((x+width).toFloat(), (y+height).toFloat(), 1f).setUv(u2/15F, v2/15F)
builder.addVertex((x+width).toFloat(), y.toFloat(), 1f).setUv(u2/15F, v1/15F)
builder.addVertex(x.toFloat(), y.toFloat(), 1f).setUv(u1/15F,v1/15F)
BufferUploader.drawWithShader(builder.build()!!)
}
// private fun renderSlotHighlight(guiGraphics: GuiGraphics, x: Int, y: Int, k: Int) { // im not sure but i tihnk i copied this from mc source code
// guiGraphics.fillGradient(RenderType.guiOverlay(), x, y, x + 16, y + 16, -2130706433, -2130706433, k);
// }
}

View File

@@ -18,6 +18,8 @@ import net.minecraft.world.inventory.MenuType
import net.minecraft.world.inventory.Slot
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.block.entity.BlockEntityType
import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.gui.widget.DynamicSlot
// Common container interface, assumes the entire purpose is purely raw item storage
interface GenericContainer : Container {
@@ -113,7 +115,7 @@ abstract class GenericContainerMenu(menuType: MenuType<*>, id: Int, var containe
abstract class GenericContainerScreen<T: GenericContainerMenu>(menu: T, inventory: Inventory, component: Component): AbstractContainerScreen<T>(menu, inventory, component) {
open fun shouldCenterTitle() = true
open fun shouldRenderTooltip() = true
open fun findMenuTexture(): ResourceLocation? = null
open fun findMenuTexture(): ResourceLocation = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/gui/background.png")
open fun getBoundBlockEntityType(): Set<BlockEntityType<*>> = setOf()
@@ -133,16 +135,22 @@ abstract class GenericContainerScreen<T: GenericContainerMenu>(menu: T, inventor
override fun renderBg(guiGraphics: GuiGraphics, f: Float, i: Int, j: Int) {
val menuTex = findMenuTexture()
if(menuTex != null) {
val cx = (width - imageWidth) / 2
val cy = (height - imageHeight) / 2
val cx = (width - imageWidth) / 2
val cy = (height - imageHeight) / 2
guiGraphics.blit(menuTex, imageX, imageY, 0, 0, imageWidth, imageHeight)
guiGraphics.blit(menuTex, imageX, imageY, 0, 0, imageWidth, imageHeight)
for (slot in menu.slots) {
if (slot is DynamicSlot) {
// NeoComputers.LOGGER.info("slot")
slot.draw(guiGraphics, cx, cy, i, j)
}
}
}
override fun render(graphics: GuiGraphics, mouseX: Int, mouseY: Int, something: Float) {
super.render(graphics, mouseX, mouseY, something)
if(shouldRenderTooltip()) super.renderTooltip(graphics, mouseX, mouseY)
}
}