From cdb98bd85e49841402a5749f1f3af344108f20c9 Mon Sep 17 00:00:00 2001 From: mewhenthe Date: Tue, 5 May 2026 21:39:40 +0200 Subject: [PATCH] all rack rendering (afaik) and basic right click logic stuff and refactors nobody asked for --- rack.png | Bin 0 -> 1046 bytes .../neoflock/neocomputers/block/RackBlock.kt | 9 +- .../neocomputers/entity/RackEntity.kt | 13 ++- .../entity/render/RackEntityRenderer.kt | 2 +- .../neoflock/neocomputers/gui/menu/Menus.kt | 3 + .../neocomputers/gui/menu/RackMenu.kt | 107 ++++++++++++++++++ .../neocomputers/gui/menu/RelayMenu.kt | 10 +- .../neocomputers/gui/screen/CaseScreen.kt | 26 +---- .../neocomputers/gui/screen/RackScreen.kt | 62 ++++++++++ .../neocomputers/gui/screen/ScreenScreen.kt | 2 + .../neocomputers/gui/widget/ComponentSlot.kt | 19 ++-- .../neocomputers/gui/widget/DynamicSlot.kt | 40 +++---- .../neocomputers/gui/widget/IconTextButton.kt | 49 ++++++++ .../neoflock/neocomputers/item/RackItem.kt | 6 + .../neocomputers/utils/GenericContainer.kt | 53 +++++++-- .../assets/neocomputers/atlases/gui.json | 8 ++ .../assets/neocomputers/textures/gui/rack.png | Bin 0 -> 5235 bytes .../neocomputers/textures/gui/relay.png | Bin 0 -> 547 bytes src/main/resources/neocomputers.accesswidener | 2 +- 19 files changed, 344 insertions(+), 67 deletions(-) create mode 100644 rack.png create mode 100644 src/main/kotlin/org/neoflock/neocomputers/gui/menu/RackMenu.kt create mode 100644 src/main/kotlin/org/neoflock/neocomputers/gui/screen/RackScreen.kt create mode 100644 src/main/kotlin/org/neoflock/neocomputers/gui/widget/IconTextButton.kt create mode 100644 src/main/resources/assets/neocomputers/atlases/gui.json create mode 100644 src/main/resources/assets/neocomputers/textures/gui/rack.png create mode 100644 src/main/resources/assets/neocomputers/textures/gui/relay.png diff --git a/rack.png b/rack.png new file mode 100644 index 0000000000000000000000000000000000000000..3b1deb3ecb2336570baf69954dac6710550aa362 GIT binary patch literal 1046 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911MRQ8&P5FjO4;u=vBoS#-wo>-L1;Fyx1 zl&avFo0y&&l$w}QS$Hzl2B^q8z$e7@$dMx*9UcGw|2H-^28sm)1T;6@DBXMT#Hsk( zwWW0@<8^g)`}-$^hKAm`^I_2vzpShcZ{A$F`SR6=+c(n}`)y83xc%lz!pylq6OL*` zi-7G8@(TuXu>uB06RzzH49qs3E{-7;x8B@|EWTwR!WNJ-dBcvE`+ofYe~D}BF_R|? z*Dhr#Jb%2q?WE74&S|f^6ODauml;hxpLXlp+b8^u$LE+xEURO6@Ls?Fehk;1)0#{h zGFAEc_189CWteToSZ3MCc+NZFuG$SfhaajN&Rg#Nm)UwiR;O_T!^7zZ6xBbdS?D*~ z{nEVP%4+c}f~nB_;D_Z0j?X#3@bnjB{eN~I=kNB1tr*@H$4Nf;_~-E9Jjr*{A0|r5 z{SLpy9QRQqg4^IpNh(9#lP#vqZF_Ql8!;3+FZpxy!Uvn@^^w0`KTrI1_p?Fllyiqe z=A1tqvg8Wuk2%4t3#zB>Q#cU8lc32wi%G+r+3v}e8_ZISGpwDS`ZrcF+ z(sUi$YsQe3%w~a%`<`CO=rCalSg(4GMuE&I#>cWsz)pp z$$Ker#&^z%(gSrpd<8-syc1ZesvCkLGT>-NaNS|Vixvx;0ef|pDjw<&b*XDt;3ksORwqu{;uWR!z3T|RSkpOY5 zoUELtVTd}oXRtP$=VfAeFnRH=L$A=~9l|5RBm4yz8lq2Kz8qZHkU2X>+Ecb6^R|G) x$LsY>Gq$}=S;ZuP&9Uevq4Eo+|I|Fd;KBWW)*OXfz@>DpvwRN literal 0 HcmV?d00001 diff --git a/src/main/kotlin/org/neoflock/neocomputers/block/RackBlock.kt b/src/main/kotlin/org/neoflock/neocomputers/block/RackBlock.kt index 3326d93..93bb416 100644 --- a/src/main/kotlin/org/neoflock/neocomputers/block/RackBlock.kt +++ b/src/main/kotlin/org/neoflock/neocomputers/block/RackBlock.kt @@ -1,8 +1,11 @@ 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.InteractionResult +import net.minecraft.world.MenuProvider import net.minecraft.world.entity.player.Player import net.minecraft.world.level.BlockGetter import net.minecraft.world.level.Level @@ -42,6 +45,7 @@ class RackBlock : BaseBlock(Properties.of().noOcclusion()), EntityBlock { override fun useWithoutItem(state: BlockState, level: Level, pos: BlockPos, player: Player, hitResult: BlockHitResult): InteractionResult? { val res = hitResult.location + val ent = level.getBlockEntity(pos, BlockEntities.RACK_ENTITY.get()).get() if(res.x == 18.0) { // TODO: handle rotation NeoComputers.LOGGER.info("{} > {} > {}, {} > {} > {}", pos.z+15/16f, res.z, pos.z+1/16f, pos.y+14/16f, res.y, pos.y+2/16f) if (pos.z + 15 / 16f > res.z && res.z > pos.z + 1 / 16f && pos.y + 14 / 16f > res.y && res.y > pos.y + 2 / 16f) { @@ -51,8 +55,11 @@ class RackBlock : BaseBlock(Properties.of().noOcclusion()), EntityBlock { rack += if(res.y < pos.y+12/16f) 1 else 0 player.sendSystemMessage(Component.literal(String.format("Hit server #%d", rack))) // TODO: call some RackItem method + return InteractionResult.SUCCESS } } - return super.useWithoutItem(state, level, pos, player, hitResult) + + if (!level.isClientSide) MenuRegistry.openMenu(player as ServerPlayer, ent) + return InteractionResult.SUCCESS } } \ No newline at end of file diff --git a/src/main/kotlin/org/neoflock/neocomputers/entity/RackEntity.kt b/src/main/kotlin/org/neoflock/neocomputers/entity/RackEntity.kt index 9283ee7..aef8b48 100644 --- a/src/main/kotlin/org/neoflock/neocomputers/entity/RackEntity.kt +++ b/src/main/kotlin/org/neoflock/neocomputers/entity/RackEntity.kt @@ -1,8 +1,19 @@ package org.neoflock.neocomputers.entity import net.minecraft.core.BlockPos +import net.minecraft.network.chat.Component +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.level.block.entity.BlockEntity import net.minecraft.world.level.block.state.BlockState +import org.neoflock.neocomputers.gui.menu.RackMenu -class RackEntity(pos: BlockPos, state: BlockState) : BlockEntity(BlockEntities.RACK_ENTITY.get(), pos, state) { +class RackEntity(pos: BlockPos, state: BlockState) : BlockEntity(BlockEntities.RACK_ENTITY.get(), pos, state), MenuProvider { + override fun getDisplayName(): Component? = Component.literal("Rack") + + override fun createMenu(i: Int, inventory: Inventory, player: Player): AbstractContainerMenu { + return RackMenu(i, inventory) + } } \ No newline at end of file diff --git a/src/main/kotlin/org/neoflock/neocomputers/entity/render/RackEntityRenderer.kt b/src/main/kotlin/org/neoflock/neocomputers/entity/render/RackEntityRenderer.kt index c7a346c..6497c14 100644 --- a/src/main/kotlin/org/neoflock/neocomputers/entity/render/RackEntityRenderer.kt +++ b/src/main/kotlin/org/neoflock/neocomputers/entity/render/RackEntityRenderer.kt @@ -24,7 +24,7 @@ class RackEntityRenderer(val context: BlockEntityRendererProvider.Context) : Blo val render_slot = (ent.level!!.dayTime/40)%4 // this is purely temporary type shit like true alpha shit, anyway it go to 0-3, change and test it if you want poseStack.translate(0f, (render_slot)*-3/16f, 0f) - val server = object : RackItem {} + val server = object : RackItem { override fun render_lights(source: MultiBufferSource, stack: PoseStack, light: Int) { } } server.render(source, poseStack, packedLight, 2f+(3*render_slot)) // who knows atp poseStack.popPose() } diff --git a/src/main/kotlin/org/neoflock/neocomputers/gui/menu/Menus.kt b/src/main/kotlin/org/neoflock/neocomputers/gui/menu/Menus.kt index 00e5d4c..1e038bd 100644 --- a/src/main/kotlin/org/neoflock/neocomputers/gui/menu/Menus.kt +++ b/src/main/kotlin/org/neoflock/neocomputers/gui/menu/Menus.kt @@ -12,6 +12,7 @@ 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.RackScreen import org.neoflock.neocomputers.gui.screen.RelayScreen import org.neoflock.neocomputers.gui.screen.ScreenScreen @@ -22,11 +23,13 @@ object Menus { val COMBUSTGEN_MENU: RegistrySupplier> = MENUS.register("combustgen_menu") { MenuType(::CombustionGeneratorMenu, FeatureFlagSet.of() ) } val CASE_MENU: RegistrySupplier> = MENUS.register("case_menu") { MenuType(::CaseMenu, FeatureFlagSet.of() )} val RELAY_MENU: RegistrySupplier> = MENUS.register("relay_menu") { MenuType(::RelayMenu, FeatureFlagSet.of() )} + val RACK_MENU: RegistrySupplier> = MENUS.register("rack_menu") { MenuType(::RackMenu, FeatureFlagSet.of() )} fun registerScreens() { 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) MenuScreens.register(Menus.RELAY_MENU.get(), ::RelayScreen) + MenuScreens.register(Menus.RACK_MENU.get(), ::RackScreen) } } \ No newline at end of file diff --git a/src/main/kotlin/org/neoflock/neocomputers/gui/menu/RackMenu.kt b/src/main/kotlin/org/neoflock/neocomputers/gui/menu/RackMenu.kt new file mode 100644 index 0000000..c18ea71 --- /dev/null +++ b/src/main/kotlin/org/neoflock/neocomputers/gui/menu/RackMenu.kt @@ -0,0 +1,107 @@ +package org.neoflock.neocomputers.gui.menu + +import com.mojang.blaze3d.systems.RenderSystem +import com.mojang.blaze3d.vertex.BufferUploader +import com.mojang.blaze3d.vertex.DefaultVertexFormat +import com.mojang.blaze3d.vertex.Tesselator +import com.mojang.blaze3d.vertex.VertexConsumer +import com.mojang.blaze3d.vertex.VertexFormat +import net.minecraft.client.gui.GuiGraphics +import net.minecraft.client.renderer.GameRenderer +import net.minecraft.client.renderer.MultiBufferSource +import net.minecraft.client.renderer.RenderStateShard +import net.minecraft.client.renderer.RenderType +import net.minecraft.world.Container +import net.minecraft.world.SimpleContainer +import net.minecraft.world.entity.player.Inventory +import org.neoflock.neocomputers.NeoComputers +import org.neoflock.neocomputers.gui.widget.ComponentRoles +import org.neoflock.neocomputers.gui.widget.DynamicSlot +import org.neoflock.neocomputers.utils.GenericContainerMenu + +class RackSlot(container: Container, slot: Int, x: Int, y: Int) : DynamicSlot(container, slot, x, y) { + // i hate that i made this, my regret is immeasurable + val MAIN_COLOURS = listOf(0xff8382d8.toInt(), 0xff75bdc1.toInt(), 0xffc8ca5f.toInt(), 0xffdb7d75.toInt(), 0xff7ec95f.toInt()) + val DARK_COLOURS = listOf(0xff6a6ab0.toInt(), 0xff60999d.toInt(), 0xffa2a44e.toInt(), 0xffb36660.toInt(), 0xff67a34e.toInt()) + val LIGHT_COLOURS = listOf(0xffdcdcf0.toInt(), 0xffdcdcf0.toInt(), 0xffececd4.toInt(), 0xfff0dbd9.toInt(), 0xffdbecd4.toInt()) + + override fun draw(graphics: GuiGraphics, mouseX: Int, mouseY: Int) { + super.draw(graphics, mouseX, mouseY) + if (!hasItem()) { drawQuad(graphics, ComponentRoles.getTextureFor("rack"), x, y, 16, 16, 0f, 0f, 15f, 15f); return; } + // TODO: make this do stuff based on the item inputted + drawConnection(graphics, item.count%5) + drawConnection(graphics, (item.count+1)%5, 0) + drawConnection(graphics, (item.count+2)%5, 1) + + drawEndpoints(graphics, 2) + } + + fun drawConnection(guiGraphics: GuiGraphics, side: Int, sec: Int = -1) { + val bufferSource = guiGraphics.bufferSource() + val buffer = bufferSource.getBuffer(RenderType.gui()) + + if (sec == -1) { + drawColor(guiGraphics, buffer, 18, 1, DARK_COLOURS[side], 6 + (11 * side)) + drawColor(guiGraphics, buffer, 18, 2, MAIN_COLOURS[side], 6 + (11 * side)) + drawColor(guiGraphics, buffer, 18, 3, LIGHT_COLOURS[side], 6 + (11 * side)) + } else { + drawColor(guiGraphics, buffer, 18, 6+(4*sec), MAIN_COLOURS[side], 6+(11*side)) + drawColor(guiGraphics, buffer, 18, 7+(4*sec), 0xff8f8f90.toInt(), 6+(11*side)) + } + } + + + fun drawEndpoints(guiGraphics: GuiGraphics, sec: Int =0) { + val bufferSource = guiGraphics.bufferSource() + val buffer = bufferSource.getBuffer(RenderType.gui()) + + // main slot endpoint + drawColor(guiGraphics, buffer, 17, 1, 0xff888888.toInt()) + drawColor(guiGraphics, buffer, 17, 3, 0xffffffff.toInt()) + + // main cable endpoints + for (i in 0..4) { + drawColor(guiGraphics, buffer, 24+(11*i), 1, 0xff333333.toInt(), 1, 3) + drawColor(guiGraphics, buffer, 25+(11*i), 1, MAIN_COLOURS[i], 3, 3) + drawColor(guiGraphics, buffer, 28+(11*i), 1, 0xffffffff.toInt(), 1, 3) + } + + // secondary endpoints + for (i in 0.. { private var btn: ImagerButton? = null override fun shouldCenterTitle(): Boolean = false +// override fun findMenuTexture(): ResourceLocation = BG var isOn = false var lastError: String? = null @@ -77,7 +78,7 @@ class CaseScreen : GenericContainerScreen { constructor(abstractContainerMenu: CaseMenu, inventory: Inventory, component: Component) : super(abstractContainerMenu, inventory, component) { btn = ImagerButton( - 15, 15, + 71, 33, 18, 18, ButtonSprites(BTN, 18, 18, 36, 36) ) { @@ -85,17 +86,11 @@ class CaseScreen : GenericContainerScreen { buf.writeByte(if(isOn) 0x02 else 0x01) NodeSynchronizer.sendScreenInteraction(buf) } -// addRenderableWidget(btn!!) - } - 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 - btn!!.x = relX+70 - btn!!.y = relY+33 - btn!!.render(guiGraphics, i, j, f) // minecraft SUCKSSS - guiGraphics.blit(PCB, relX, relY, 0, 0, this.imageWidth, this.imageHeight) + addWidget(btn!!) + } + override fun renderbg(guiGraphics: GuiGraphics, f: Float, i: Int, j: Int) { + guiGraphics.blit(PCB, 0, 0, 0, 0, this.imageWidth, this.imageHeight) // WE'RE FREE } override fun renderCustomOverlay(graphics: GuiGraphics, mouseX: Int, mouseY: Int, blend: Float) { @@ -105,13 +100,4 @@ class CaseScreen : GenericContainerScreen { } } - override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean { // todo: make a better widget system than mojang, practically not even using the fact it's a widget atp - if (button == 0 && btn!!.isHovered) { - btn!!.playDownSound(Minecraft.getInstance().soundManager) - btn!!.onClick(mouseX, mouseY) - return true - } - return super.mouseClicked(mouseX, mouseY, button) - } - } \ No newline at end of file diff --git a/src/main/kotlin/org/neoflock/neocomputers/gui/screen/RackScreen.kt b/src/main/kotlin/org/neoflock/neocomputers/gui/screen/RackScreen.kt new file mode 100644 index 0000000..c5b503a --- /dev/null +++ b/src/main/kotlin/org/neoflock/neocomputers/gui/screen/RackScreen.kt @@ -0,0 +1,62 @@ +package org.neoflock.neocomputers.gui.screen + +import net.minecraft.client.gui.GuiGraphics +import net.minecraft.client.gui.components.Button +import net.minecraft.client.gui.components.SpriteIconButton +import net.minecraft.client.gui.narration.NarrationElementOutput +import net.minecraft.network.chat.Component +import net.minecraft.network.chat.MutableComponent +import net.minecraft.resources.ResourceLocation +import net.minecraft.world.entity.player.Inventory +import org.neoflock.neocomputers.NeoComputers +import org.neoflock.neocomputers.gui.menu.RackMenu +import org.neoflock.neocomputers.gui.widget.IconTextButton +import org.neoflock.neocomputers.utils.GenericContainerScreen +import java.util.function.Supplier + +class RackScreen(menu: RackMenu, inventory: Inventory, component: Component) : GenericContainerScreen(menu, inventory, component) { + override fun findMenuTexture(): ResourceLocation = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/gui/rack.png") + val RELAY = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/gui/relay.png") + + var relay_mode = false // TODO: tie this to the menu or entity or whatever + + val relaybtn = IconTextButton(100, 96, "Disabled", RELAY, width = 64) { + if (relay_mode){ + it.message = Component.literal("Disabled") + relay_mode = false + } else { + it.message = Component.literal("Enabled") + relay_mode = true + } + } + init { + this.imageWidth = 175 + this.imageHeight = 209 + this.inventoryLabelY = imageHeight - 93 + addWidget(relaybtn) + } + + override fun renderbg(guiGraphics: GuiGraphics, partialTick: Float, mouseX: Int, mouseY: Int) { + renderSideLabels(guiGraphics) + if(relay_mode) renderRelayConnections(guiGraphics) + } + + fun renderRelayConnections(graphics: GuiGraphics) { + for(i in 0..3) { + val x = 50+(i*11) + graphics.fill(x, 104, x+4, 105, 0xffffffff.toInt()) + graphics.fill(x, 105, x+4, 106, 0xff888888.toInt()) + } + } + + fun renderSideLabels(graphics: GuiGraphics) { + val x = 115+7 + val y = 20 + + graphics.drawString(font, "Bottom", x, y, 0x404040, false) + graphics.drawString(font, "Top", x, y+11, 0x404040, false) + graphics.drawString(font, "Back", x, y+22, 0x404040, false) + graphics.drawString(font, "Right", x, y+33, 0x404040, false) + graphics.drawString(font, "Left", x, y+44, 0x404040, false) + } +} \ No newline at end of file diff --git a/src/main/kotlin/org/neoflock/neocomputers/gui/screen/ScreenScreen.kt b/src/main/kotlin/org/neoflock/neocomputers/gui/screen/ScreenScreen.kt index 40c7b5b..aab4c4b 100644 --- a/src/main/kotlin/org/neoflock/neocomputers/gui/screen/ScreenScreen.kt +++ b/src/main/kotlin/org/neoflock/neocomputers/gui/screen/ScreenScreen.kt @@ -46,6 +46,8 @@ class ScreenScreen : GenericContainerScreen{ } } + override fun renderLabels(guiGraphics: GuiGraphics, mouseX: Int, mouseY: Int) { } + // override fun onClose() { // super.onClose() // renderer. diff --git a/src/main/kotlin/org/neoflock/neocomputers/gui/widget/ComponentSlot.kt b/src/main/kotlin/org/neoflock/neocomputers/gui/widget/ComponentSlot.kt index 8a9e940..df86936 100644 --- a/src/main/kotlin/org/neoflock/neocomputers/gui/widget/ComponentSlot.kt +++ b/src/main/kotlin/org/neoflock/neocomputers/gui/widget/ComponentSlot.kt @@ -84,13 +84,13 @@ data class ComponentSlotRequirement(val tier: Int, val role: String) { // Tier 0 allows ALL tiers, making it completely untiered. // Role determines what the role is. class ComponentSlot(container: Container, slot: Int, x: Int, y: Int, val machine: ComponentUser?, val requirement: ComponentSlotRequirement): DynamicSlot(container, slot, x, y) { - override fun draw(graphics: GuiGraphics, relX: Int, relY: Int, mouseX: Int, mouseY: Int) { - super.draw(graphics, relX, relY, mouseX, mouseY) + override fun draw(graphics: GuiGraphics, mouseX: Int, mouseY: Int) { + super.draw(graphics, mouseX, mouseY) if(!hasItem()) { - RenderSystem.enableBlend() - RenderSystem.setShaderTexture(0, ComponentRoles.getTextureFor(requirement.role)) - RenderSystem.setShader { GameRenderer.getPositionTexShader() } - drawQuad(relX + x - 1, relY + y - 1, 18, 18, 0F, 0F, 15F, 15F) +// RenderSystem.enableBlend() +// RenderSystem.setShaderTexture(0, ComponentRoles.getTextureFor(requirement.role)) +// RenderSystem.setShader { GameRenderer.getPositionTexShader() } + drawQuad(graphics, ComponentRoles.getTextureFor(requirement.role), x - 1, y - 1, 18, 18, 0F, 0F, 15F, 15F) if (requirement.tier > 0) { RenderSystem.setShaderTexture( 0, @@ -99,10 +99,11 @@ class ComponentSlot(container: Container, slot: Int, x: Int, y: Int, val machine "textures/gui/slots/tier${requirement.tier - 1}.png" ) ) - RenderSystem.setShader { GameRenderer.getPositionTexShader() } - drawQuad(relX + x - 1, relY + y - 1, 18, 18, 0F, 0F, 15F, 15F) + val tex = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/gui/slots/tier${requirement.tier - 1}.png") +// RenderSystem.setShader { GameRenderer.getPositionTexShader() } + drawQuad(graphics, tex, x - 1, y - 1, 18, 18, 0F, 0F, 15F, 15F) } - RenderSystem.disableBlend() +// RenderSystem.disableBlend() } } diff --git a/src/main/kotlin/org/neoflock/neocomputers/gui/widget/DynamicSlot.kt b/src/main/kotlin/org/neoflock/neocomputers/gui/widget/DynamicSlot.kt index a13c83e..d7e803d 100644 --- a/src/main/kotlin/org/neoflock/neocomputers/gui/widget/DynamicSlot.kt +++ b/src/main/kotlin/org/neoflock/neocomputers/gui/widget/DynamicSlot.kt @@ -5,9 +5,12 @@ 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.VertexConsumer import com.mojang.blaze3d.vertex.VertexFormat import net.minecraft.client.gui.GuiGraphics import net.minecraft.client.renderer.GameRenderer +import net.minecraft.client.renderer.RenderStateShard +import net.minecraft.client.renderer.RenderStateShard.ShaderStateShard import net.minecraft.client.renderer.RenderType import net.minecraft.resources.ResourceLocation import net.minecraft.world.Container @@ -17,29 +20,26 @@ 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") - - open 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() + val RENDER_TYPE = { r: ResourceLocation -> + RenderType.create("nc_gui_slot", DefaultVertexFormat.POSITION_TEX, VertexFormat.Mode.QUADS, RenderType.TRANSIENT_BUFFER_SIZE, RenderType.CompositeState.builder() + .setShaderState(ShaderStateShard.POSITION_TEX_SHADER) + .setTextureState(RenderStateShard.TextureStateShard(r, false, false)) + .setTransparencyState(RenderStateShard.TransparencyStateShard.TRANSLUCENT_TRANSPARENCY) + .createCompositeState(false)) } - 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()!!) + open fun draw(graphics: GuiGraphics, mouseX: Int, mouseY: Int) { + drawQuad(graphics, BACKGROUND, x-1, y-1, 18, 18, 0F, 0F, 15F, 15F) } - // 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); - // } + fun drawQuad(guiGraphics: GuiGraphics, tex: ResourceLocation, x: Int, y: Int, width: Int, height: Int, u1: Float, v1: Float, u2: Float, v2: Float) { + val pose = guiGraphics.pose().last() + val builder = guiGraphics.bufferSource().getBuffer(RENDER_TYPE(tex)) + + builder.addVertex(pose, x.toFloat(), (y+height).toFloat(), 1f).setUv(u1/15F, v2/15F) + builder.addVertex(pose, (x+width).toFloat(), (y+height).toFloat(), 1f).setUv(u2/15F, v2/15F) + builder.addVertex(pose, (x+width).toFloat(), y.toFloat(), 1f).setUv(u2/15F, v1/15F) + builder.addVertex(pose, x.toFloat(), y.toFloat(), 1f).setUv(u1/15F,v1/15F) + } } \ No newline at end of file diff --git a/src/main/kotlin/org/neoflock/neocomputers/gui/widget/IconTextButton.kt b/src/main/kotlin/org/neoflock/neocomputers/gui/widget/IconTextButton.kt new file mode 100644 index 0000000..4608783 --- /dev/null +++ b/src/main/kotlin/org/neoflock/neocomputers/gui/widget/IconTextButton.kt @@ -0,0 +1,49 @@ +package org.neoflock.neocomputers.gui.widget + +import com.mojang.blaze3d.systems.RenderSystem +import net.minecraft.client.Minecraft +import net.minecraft.client.gui.Font +import net.minecraft.client.gui.GuiGraphics +import net.minecraft.client.gui.components.Button +import net.minecraft.client.renderer.texture.TextureAtlas +import net.minecraft.network.chat.Component +import net.minecraft.network.chat.MutableComponent +import net.minecraft.resources.ResourceLocation +import net.minecraft.util.ResourceLocationPattern +import org.neoflock.neocomputers.NeoComputers +import java.util.function.Supplier + +class press(val lambda: (IconTextButton) -> Unit) : Button.OnPress { + override fun onPress(button: Button) { + lambda(button as IconTextButton) + } +} + +class narr : Button.CreateNarration { + override fun createNarrationMessage(supplier: Supplier): MutableComponent? { + return supplier.get() // no narration for u + } + +} + +class IconTextButton(x: Int, y: Int, text: String, val icon: ResourceLocation, val iconw: Int =16, val iconh: Int = 16, width: Int=150, height: Int=20, lambda: (IconTextButton) -> Unit) : + Button(x, y, width, height, Component.literal(text),press(lambda), narr()) { + + + var xOffset = 2 + override fun renderWidget(guiGraphics: GuiGraphics, mouseX: Int, mouseY: Int, partialTick: Float) { + super.renderWidget(guiGraphics, mouseX, mouseY, partialTick) + + RenderSystem.disableBlend() // i hate this + val imx = x + xOffset + val imy = y + (height/2) - (iconh/2) + guiGraphics.blit(icon, imx, imy, 0f, 0f, iconw, iconh, iconw, iconh) + RenderSystem.enableBlend() + } + + override fun renderString(guiGraphics: GuiGraphics, font: Font, color: Int) { + val startx = x + iconw/2 // idk why /2, might be coincidence thing + renderScrollingString(guiGraphics, font, message, startx, y, startx+width, y+height, color) + } + +} \ No newline at end of file diff --git a/src/main/kotlin/org/neoflock/neocomputers/item/RackItem.kt b/src/main/kotlin/org/neoflock/neocomputers/item/RackItem.kt index d0a89b8..1972205 100644 --- a/src/main/kotlin/org/neoflock/neocomputers/item/RackItem.kt +++ b/src/main/kotlin/org/neoflock/neocomputers/item/RackItem.kt @@ -28,6 +28,8 @@ interface RackItem { val FRONT_TEX: ResourceLocation get() = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/block/rack_server.png") + fun render_lights(source: MultiBufferSource, stack: PoseStack, light: Int) + fun render(source: MultiBufferSource, stack: PoseStack, light: Int, v_offset: Float = 2f) { val pose = stack.last() @@ -51,6 +53,10 @@ interface RackItem { buffer.addVertex(pose, 14/16f, 0/16f, 0/16f).setUv(15/16f, (v_offset+3)/16f).setColor(1f, 1f, 1f, 1f).setLight(light).setNormal(pose, 1f, 0f, 0f).setOverlay(OverlayTexture.NO_OVERLAY) buffer.addVertex(pose, 14/16f, 3/16f, 0/16f).setUv(15/16f, v_offset/16f).setColor(1f, 1f, 1f, 1f).setLight(light).setNormal(pose, 1f, 0f, 0f).setOverlay(OverlayTexture.NO_OVERLAY) + stack.pushPose() + stack.translate((14/16f)+0.001F, 0f, 0f) + render_lights(source, stack, light) + stack.popPose() } } \ No newline at end of file diff --git a/src/main/kotlin/org/neoflock/neocomputers/utils/GenericContainer.kt b/src/main/kotlin/org/neoflock/neocomputers/utils/GenericContainer.kt index 1de3349..4e2aeab 100644 --- a/src/main/kotlin/org/neoflock/neocomputers/utils/GenericContainer.kt +++ b/src/main/kotlin/org/neoflock/neocomputers/utils/GenericContainer.kt @@ -1,9 +1,15 @@ package org.neoflock.neocomputers.utils // based off the ImplementedContainer of https://docs.fabricmc.net/develop/blocks/block-containers +import com.mojang.blaze3d.vertex.DefaultVertexFormat +import com.mojang.blaze3d.vertex.VertexFormat import dev.architectury.registry.menu.MenuRegistry import net.minecraft.client.gui.GuiGraphics +import net.minecraft.client.gui.components.AbstractWidget import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen +import net.minecraft.client.renderer.RenderStateShard +import net.minecraft.client.renderer.RenderStateShard.ShaderStateShard +import net.minecraft.client.renderer.RenderType import net.minecraft.world.Container; import net.minecraft.core.NonNullList; import net.minecraft.network.FriendlyByteBuf @@ -68,7 +74,7 @@ abstract class GenericContainerMenu(menuType: MenuType<*>, id: Int, var containe // Based off the code in ChestMenu for (i in 0..2) { for (j in 0..8) { - this.addSlot(Slot(inventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18)) + this.addSlot(Slot(inventory, j + i * 9 + 9, 8 + j * 18, y + i * 18)) } } @@ -128,6 +134,15 @@ abstract class GenericContainerScreen(menu: T, inventor val imageY: Int get() = (height - imageHeight) / 2 + var widgets = mutableListOf() + + val RENDER_TYPE = { r: ResourceLocation -> + RenderType.create("nc_gui_bg", DefaultVertexFormat.POSITION_TEX, VertexFormat.Mode.QUADS, RenderType.TRANSIENT_BUFFER_SIZE, RenderType.CompositeState.builder() + .setShaderState(ShaderStateShard.POSITION_TEX_SHADER) + .setTextureState(RenderStateShard.TextureStateShard(r, false, false)) + .createCompositeState(false)) + } + override fun init() { super.init() @@ -138,24 +153,48 @@ abstract class GenericContainerScreen(menu: T, inventor val menuTex = findMenuTexture() val cx = (width - imageWidth) / 2 val cy = (height - imageHeight) / 2 + guiGraphics.pose().pushPose() + guiGraphics.pose().translate(cx.toFloat(), cy.toFloat(), 0f) - guiGraphics.blit(menuTex, imageX, imageY, 0, 0, imageWidth, imageHeight) + guiGraphics.blit(menuTex, 0, 0, 0, 0, imageWidth, imageHeight) + renderbg(guiGraphics, f, i-cx, j-cy) + + for (widget in widgets) { + widget.render(guiGraphics, i-cx, j-cy, f) + } for (slot in menu.slots) { if (slot is DynamicSlot) { - // NeoComputers.LOGGER.info("slot") - slot.draw(guiGraphics, cx, cy, i, j) + slot.draw(guiGraphics, i, j) } } + + guiGraphics.pose().popPose() } - open fun renderCustomOverlay(graphics: GuiGraphics, mouseX: Int, mouseY: Int, blend: Float) { + open fun renderbg(guiGraphics: GuiGraphics, partialTick: Float, mouseX: Int, mouseY: Int) {} - } + open fun renderCustomOverlay(graphics: GuiGraphics, mouseX: Int, mouseY: Int, blend: Float) { } override fun render(graphics: GuiGraphics, mouseX: Int, mouseY: Int, something: Float) { super.render(graphics, mouseX, mouseY, something) - renderCustomOverlay(graphics, mouseX, mouseY, something) + + graphics.pose().pushPose() + graphics.pose().translate(imageX.toFloat(), imageY.toFloat(), 0f) + renderCustomOverlay(graphics, mouseX-imageX, mouseY-imageY, something) + graphics.pose().popPose() // not even doing this because it's better anymore, im just doing this because i dont want to change it back + if(shouldRenderTooltip()) super.renderTooltip(graphics, mouseX, mouseY) } + + override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean { + for (widget in widgets) { + if (widget.mouseClicked(mouseX-imageX, mouseY-imageY, button)) return true + } + return false + } + + fun addWidget(widget: AbstractWidget) { + widgets.add(widget) + } } \ No newline at end of file diff --git a/src/main/resources/assets/neocomputers/atlases/gui.json b/src/main/resources/assets/neocomputers/atlases/gui.json new file mode 100644 index 0000000..cfc5b41 --- /dev/null +++ b/src/main/resources/assets/neocomputers/atlases/gui.json @@ -0,0 +1,8 @@ +{ + "sources": [ + { + "type": "single", + "source": "neocomputers:block/relay_top" + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/neocomputers/textures/gui/rack.png b/src/main/resources/assets/neocomputers/textures/gui/rack.png new file mode 100644 index 0000000000000000000000000000000000000000..428ff65ac9dc8f3b5add1713ed2a417dc0bf3050 GIT binary patch literal 5235 zcmeHLYfuwe7Vdz6Ac&3*qT<-b@oguaq(eFxB0++Xfndbo_$Z5X(jAD9he;#B2Syp6 zI6li4LZJrH9hG%;)KyfX;&WVa$G3o>qRuENx(+&n;NB#N;7sk7wd+5-l1kruzVqF4 zzI)ECbT3iFM+f-z@q-{JKo%oSfFK6AWk8)h!B6V0iAwNOHd8r~P9QR1li8@%rBN`Q zX`*1ts?$P{^_E^SrRz!9zv*GmuRJoLJ2+imSfx5sFz<)qmq(tO-oq4m;#p?t3469I zyGVWLK?q~_hJ*w$Zd*sT=LA@ufq(VnF?cNukBQNw`YZ%k`;`D*g?=N0x z)YOKr9@Rav&Y-M{v4)-vxHWsig{$YAeJi?ub7R>h+4+WJaapDNRkLP|9=9QIz!FvW ze9xE_A%ziz$CqY*>Af4j*6qO>)qppRG;=nia`L2pkJtDe1<5VYMMf%Qk&$on0a@hD zSydW)QWA11X)dv9>HL1u5U#RU{Z{7k{eDq9x=mX!p`*Myh?8ozCvC&mTUrOm{VgvuaCo;i9=Wp5@f8K9|TC zc*bLzVt_EKA^cUIUD$NjG8i^AB2wK0s`7Ik-PxZQZ(Gy9P@oS^c*MO4c3zx*GCX zl7U*u!-_Gk;bTJ5u{N~v8;L%s5}S? z3%8mGO)5phYARW05Hp{alrmu*DQ14dm!oo1B$c9znQ5lR&x}`UW~OR{Br|-JUzk+{ z2=o+9z*c>l!6LGXnJ!)txOYyonXn5&r;3>qg7r3X+8Se4UZ$!M8e(dOZl zAX%q3xx9eb9gwt6`%bJ5u{kZSblL|3+}n6Npx@^10t1v>E|MBG>CW(EQZduHzKAqx zbfn02%O_9@Cn+3J6NCoAP)v;wd=7?$k|;rNH7HlW6}F?287wqm&`?e)K+e(u9uB1u z@=211@OUH_!9pn#AvhQhp?El#$D{Zt2UWMD7;DynswC3dN9Cj<0Tmfa5}|wnhLAk9 z7Qt{7LvTWaB0M!tY6JoxwkwH{BN#;r5FwYxMYxn2 zSF3R?iK%%V*)2vbok5tXh-9E6&&Rqb4At)bl3kEdfpsj+j zKYofh$;AjljUrqDA44$EKM0P6YLQTaAUFaZh2v^>!?X$bzo*!~CR$SrV>^$Gr0qxFFAdPztoX_C6XSbdAt(t*&Kjzh1ZXa_A82+@#2kHAsu1|7(kOChB{#0F` zFuW0PdI1Usoe)1Bl03KpUWz~rb!@a0TI|&?1`K>nF_SD1)TM{>%Ybt8 zg2AK@Et5z2Jo4()ZN%Vje;T(4f;=wEq!CK%t@_HF=1pj@ZQNfCu zJ9||S5&K*D`o8j_UcdJCCA~^?xq2}_^@sXLzp&>`ofh&!-mCW4j7^6ei!Rgr4;k5KMm3+{FR#LD|zuu?D44caZkx`7<@mqj}&;- z#6CLq)H|orCvB_8>zJySlER_3=#V9!do>{G$9$GYRr-xhR%`Y{g;l9VC61R$%DAvG za+EDP&o_wgnN{@2Gq`bMb(e4R8GH}2%I|vTZY?qX5VZZoh_nT%9x;pXRWBKf28bM! z;84fVONYE~_*M7-)g2RXrsVf2V`}F(rU%az@f`lBXWD{#=esV|h>$?ISr-0$R1LN) zd<*0Bb)z?3%s6nO(fLB`KVOn9(46Y0x5CS<-<@p6!s1Te!@~C8EKPjzPv~;S@qZla zqG_DuxVi6AY=PIX{;CboLf@L-vDZIspZB#_u;HTZ&IAA8+b{k9p4Iv09tC3- literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/neocomputers/textures/gui/relay.png b/src/main/resources/assets/neocomputers/textures/gui/relay.png new file mode 100644 index 0000000000000000000000000000000000000000..d4067e79ecc2d52cd1bb67ac2e8dee9fc61c47c9 GIT binary patch literal 547 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G|;0G|+785tQtLBXJ)Aa8GP7Z(>tM@MC4WqEmdDJdx{D=U5m)8e3W(+d8J zi;D{}*l(NtUrtU=guzEvR@TJCWYZccCZIW-1s;*b3=DjSL74G){)!Z!phSslL`iUd zT1k0gQ7S_~VrE{6o}X)of~lUNo`rPgs}(>s+fpMu(>y)37&w3&Rt70XRt82O%L|C5 zp=^+^G#Ht|;vl;W8JWPoi~_PV+gZTkSwJ=jBmgl;Ka57RlmQqn6WAG8fGP}(j13qU zKuiVcU|j$)X$p`H0!%=2n7}H7EG>X6s4hbT1CZ?M21ViEc@`Q#W|yanV~9p@Y=0x) zVFeDCg<)$QHs1RG|N7jL=uNREhWh&I7vd$-qdlX&s_#iAJPz{G-FnIKj+lm$mQq{w zGxmz`%kT8A-!70&X1K)@a8&d_+vz=wL5=r(#TWD&E_iW0fQhYR_|KM{|^|KMVjCnh^?!GIibKE|$j`4~Q`=wR9t@}VO^mO%eS?83{1OP1j BgUkQ` literal 0 HcmV?d00001 diff --git a/src/main/resources/neocomputers.accesswidener b/src/main/resources/neocomputers.accesswidener index e1340ab..084cdb5 100644 --- a/src/main/resources/neocomputers.accesswidener +++ b/src/main/resources/neocomputers.accesswidener @@ -1,4 +1,4 @@ accessWidener v2 named -accessible method net/minecraft/world/level/block/entity/BlockEntityType (Lnet/minecraft/world/level/block/entity/BlockEntityType$BlockEntitySupplier;Ljava/util/Set;)V +# accessible method net/minecraft/world/level/block/entity/BlockEntityType (Lnet/minecraft/world/level/block/entity/BlockEntityType$BlockEntitySupplier;Ljava/util/Set;)V accessible field net/minecraft/core/Direction$Plane faces [Lnet/minecraft/core/Direction; \ No newline at end of file