Compare commits

...

4 Commits

11 changed files with 225 additions and 29 deletions

View File

@@ -0,0 +1,13 @@
package org.neoflock.neocomputers.platforms.fabric.client;
import net.fabricmc.api.ClientModInitializer;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderers;
import org.neoflock.neocomputers.entity.BlockEntities;
import org.neoflock.neocomputers.gui.render.ScreenEntityRenderer;
public class NeoComputersFabricClient implements ClientModInitializer {
@Override
public void onInitializeClient() {
BlockEntityRenderers.register(BlockEntities.INSTANCE.getSCREEN_ENTITY().get(), ScreenEntityRenderer::new);
}
}

View File

@@ -1,5 +1,7 @@
package org.neoflock.neocomputers
import com.mojang.blaze3d.vertex.DefaultVertexFormat
import com.mojang.blaze3d.vertex.VertexFormat
import dev.architectury.event.events.client.ClientLifecycleEvent
import dev.architectury.event.events.common.LifecycleEvent
import dev.architectury.event.events.common.PlayerEvent
@@ -13,11 +15,15 @@ import org.neoflock.neocomputers.gui.menu.Menus
import dev.architectury.utils.Env
import dev.architectury.utils.EnvExecutor
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.RenderStateShard
import net.minecraft.client.renderer.RenderType
import net.minecraft.server.level.ServerPlayer
import org.neoflock.neocomputers.block.NodeBlockEntity
import org.neoflock.neocomputers.block.NodeSynchronizer
import org.neoflock.neocomputers.gui.buffer.BufferRenderer
import org.neoflock.neocomputers.gui.render.ScreenRenderer
import org.neoflock.neocomputers.gui.widget.ComponentRoles
import org.neoflock.neocomputers.item.GPUCard
import org.neoflock.neocomputers.item.Items
import org.neoflock.neocomputers.item.Tabs
import org.neoflock.neocomputers.network.Networking
@@ -26,12 +32,19 @@ import org.neoflock.neocomputers.utils.FontProvider
import org.neoflock.neocomputers.utils.GenericContainerScreen
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import java.nio.Buffer
object NeoComputers {
const val MODID: String = "neocomputers"
val LOGGER: Logger = LoggerFactory.getLogger("NeoComputers")
var PLATFORM: ModPlatform? = null
val BlockEntityRenderType: RenderType = RenderType.create(
"nc_blockentities",
DefaultVertexFormat.POSITION_TEX,
VertexFormat.Mode.QUADS,
0xc000, RenderType.CompositeState.builder().setShaderState(RenderStateShard.POSITION_TEX_SHADER).createCompositeState(false)) // TODO: figure out correct buffer size and composite state
fun entrypoint(platform: ModPlatform?) {
PLATFORM = platform
@@ -53,6 +66,14 @@ object NeoComputers {
ClientLifecycleEvent.CLIENT_STARTED.register {
FontProvider.load(ResourceLocation.fromNamespaceAndPath(MODID, "font/unscii.hex"))
ScreenRenderer.genUnboundTex();
var buffer: MutableList<BufferRenderer.GPUChar> = mutableListOf(BufferRenderer.GPUChar('h'), BufferRenderer.GPUChar('i'))
for (i in 0..398) {
buffer.add(BufferRenderer.GPUChar(' '))
}
var renderer: BufferRenderer = BufferRenderer(20, 20, ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "screen/test"), buffer)
renderer.drawBuffer()
}
ClientLifecycleEvent.CLIENT_STOPPING.register {

View File

@@ -1,20 +1,29 @@
package org.neoflock.neocomputers.block;
import dev.architectury.registry.menu.ExtendedMenuProvider
import dev.architectury.registry.menu.MenuRegistry
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.network.FriendlyByteBuf
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.LivingEntity
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.Block
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.level.block.state.StateDefinition
import net.minecraft.world.level.block.state.properties.BooleanProperty
import net.minecraft.world.level.block.state.properties.EnumProperty
import net.minecraft.world.level.block.state.properties.EnumProperty.*
import net.minecraft.world.phys.BlockHitResult
import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.entity.BlockEntities
@@ -22,8 +31,18 @@ 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
import kotlin.math.abs
import kotlin.math.max
class ScreenBlock() : NodeBlock() {
companion object {
val FACING: EnumProperty<Direction> = EnumProperty.create<Direction>("facing", Direction::class.java)
val ENERGY: Long = 5
}
init {
registerDefaultState(stateDefinition.any().setValue(FACING, Direction.NORTH))
}
override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity? {
val scr = ScreenEntity(blockPos, blockState)
@@ -40,17 +59,44 @@ class ScreenBlock() : NodeBlock() {
): InteractionResult {
if(!level.isClientSide) {
val screenState = level.getBlockEntity(blockPos, BlockEntities.SCREEN_ENTITY.get()).get()
if(!screenState.node.consumeEnergy(5)) {
if(!screenState.node.consumeEnergy(ENERGY)) {
player.sendSystemMessage(Component.literal("Not enough power."))
return InteractionResult.SUCCESS
};
MenuRegistry.openMenu(player as ServerPlayer, object : MenuProvider {
MenuRegistry.openExtendedMenu(player as ServerPlayer, object : ExtendedMenuProvider {
override fun getDisplayName(): Component = Component.literal("SCREEEEEN!")
override fun createMenu(i: Int, inventory: Inventory, player: Player): AbstractContainerMenu {
return Menus.SCREEN_MENU.get().create(i, inventory);
// return Menus.SCREEN_MENU.get().create(i, inventory);
return ScreenMenu(i, inventory, level.getBlockEntity(blockPos, BlockEntities.SCREEN_ENTITY.get()).get())
}
override fun saveExtraData(buf: FriendlyByteBuf?) {
buf!!.writeBlockPos(blockPos)
}
})
}
return InteractionResult.SUCCESS
}
override fun createBlockStateDefinition(builder: StateDefinition.Builder<Block?, BlockState?>) {
builder.add(FACING)
}
override fun setPlacedBy(level: Level, pos: BlockPos, state: BlockState, placer: LivingEntity?, stack: ItemStack) {
super.setPlacedBy(level, pos, state, placer, stack)
// state.setValue(state.)
level.setBlockAndUpdate(pos, state.setValue(FACING, lookingdir(placer!!)))
}
private fun lookingdir(placer: LivingEntity): Direction {
val vec = placer.lookAngle
NeoComputers.LOGGER.info(vec.toString())
val biggest = max(max(abs(vec.x), abs(vec.y)), abs(vec.z))
when(biggest) {
abs(vec.x) -> if(vec.x < 0) return Direction.EAST else return Direction.WEST
abs(vec.y) -> if(vec.y < 0) return Direction.UP else return Direction.DOWN
abs(vec.z) -> if(vec.z < 0) return Direction.SOUTH else return Direction.NORTH
}
NeoComputers.LOGGER.warn("Failed to obtain looking direction!")
return Direction.NORTH // wtf
}
}

View File

@@ -1,8 +1,12 @@
package org.neoflock.neocomputers.entity;
import net.minecraft.core.BlockPos
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.state.BlockState
import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.block.NodeBlockEntity
import org.neoflock.neocomputers.gui.buffer.BufferRenderer
import org.neoflock.neocomputers.network.Networking
import org.neoflock.neocomputers.network.PowerRole
@@ -10,4 +14,38 @@ class ScreenEntity(blockPos: BlockPos, blockState: BlockState) :
NodeBlockEntity(BlockEntities.SCREEN_ENTITY.get(), blockPos, blockState) {
override val node = Networking.Node()
var bound = "screen/unbound"
var render_on_block = false
private var cleanrenderer: () -> Unit = { }; // TODO: THIS SUCKS, FIND A BETTER WAY
override fun setChanged() {
super.setChanged()
if (bound == "screen/unbound") {
createscreenstuffs()
}
}
override fun setRemoved() {
super.setRemoved()
cleanrenderer()
}
private fun createscreenstuffs() {
bound = "screen/"+node.address.toString().replace("-", "_")
NeoComputers.LOGGER.info(bound)
if (level!!.isClientSide) {
var buffer: MutableList<BufferRenderer.GPUChar> = mutableListOf()
for(char in node.address.toString()) {
buffer.add(BufferRenderer.GPUChar(char, 0xFFFF00, 0x0000FF))
}
for (i in 0..((40*20)-36)) {
buffer.add(BufferRenderer.GPUChar(' '))
}
var renderer: BufferRenderer = BufferRenderer(40, 20, ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, bound), buffer)
renderer.drawBuffer()
cleanrenderer = { renderer.clean() }
}
}
}

View File

@@ -17,7 +17,8 @@ import org.neoflock.neocomputers.gui.screen.ScreenScreen
object Menus {
val MENUS: DeferredRegister<MenuType<*>> = DeferredRegister.create(NeoComputers.MODID, Registries.MENU)
val SCREEN_MENU: RegistrySupplier<MenuType<ScreenMenu>> = MENUS.register("screen_menu") { MenuType(::ScreenMenu, FeatureFlagSet.of()) }
// val SCREEN_MENU: RegistrySupplier<MenuType<ScreenMenu>> = MENUS.register("screen_menu") { MenuType(::ScreenMenu, FeatureFlagSet.of()) }
val SCREEN_MENU: RegistrySupplier<MenuType<ScreenMenu>> = MENUS.register("screen_menu") { MenuRegistry.ofExtended<ScreenMenu>(::ScreenMenu) }
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() )}

View File

@@ -1,5 +1,6 @@
package org.neoflock.neocomputers.gui.menu;
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.world.SimpleContainer
import net.minecraft.world.entity.player.Inventory
import org.neoflock.neocomputers.gui.menu.Menus;
@@ -7,7 +8,16 @@ 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 net.minecraft.world.level.block.entity.BlockEntity
import org.neoflock.neocomputers.entity.ScreenEntity
import org.neoflock.neocomputers.utils.GenericContainerMenu
class ScreenMenu(i: Int, inv: Inventory) : GenericContainerMenu(Menus.SCREEN_MENU.get(), i, SimpleContainer(0)) {
class ScreenMenu : GenericContainerMenu {
var entity: ScreenEntity? = null
constructor(i: Int, inv: Inventory, buf: FriendlyByteBuf) : this(i, inv, inv.player.level().getBlockEntity(buf.readBlockPos()))
constructor(i: Int, inv: Inventory, entity: BlockEntity?) : super(Menus.SCREEN_MENU.get(), i, SimpleContainer(0)) {
this.entity = entity as ScreenEntity
}
}

View File

@@ -20,14 +20,18 @@ class BufferRenderer(private var width: Int, private var height: Int, private va
private var image: NativeImage = NativeImage(texwidth, texheight, true); // idk what the boolean is
private var tex: DynamicTexture = DynamicTexture(image)
init {
Minecraft.getInstance().textureManager.register(this.id, tex)
}
fun dump(path: String) {
image.writeToFile(File(path))
NeoComputers.LOGGER.info("DUMPED!!!")
}
fun toRGBA(color: Int): Int {
return color.shl(8).or(0xFF)
}
// fun toRGBA(color: Int): Int {
// return color.shl(8).or(0xFF)
// }
fun drawGlyph(x: Int, y: Int, c: Char, fg: Int) {
var glyph: ArrayList<Byte> = FontProvider.map[c]!!
@@ -36,7 +40,7 @@ class BufferRenderer(private var width: Int, private var height: Int, private va
for (i in 0..<CHARW) {
// var pixel = ((glyph[j] and ((1 shl (CHARW - i - 1)).toByte())).toInt()) ushr (CHARW - i - 1) // retardation
var pixel = (glyph[j] and (0b10000000 ushr i).toByte()).toInt()
if (pixel > 0) image.setPixelRGBA(x+i, y+j, toRGBA(fg))
if (pixel > 0) image.setPixelRGBA(x+i, y+j, 0xFF000000.toInt()+fg)
}
}
}
@@ -59,15 +63,11 @@ class BufferRenderer(private var width: Int, private var height: Int, private va
buffer[y*width+x] = c
}
fun register() {
Minecraft.getInstance().textureManager.register(this.id, tex) // also idk how to unregister this
}
fun clean() {
Minecraft.getInstance().textureManager.release(this.id)
image.close()
tex.close()
}
data class GPUChar(val c: Char, val fg: Int =0xFFFFFF, val bg: Int = 0)
data class GPUChar(val c: Char, val fg: Int =0xFFFFFF, val bg: Int = 0) // all is bgr
}

View File

@@ -0,0 +1,51 @@
package org.neoflock.neocomputers.gui.render
import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.math.Axis
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
import net.minecraft.core.Direction
import net.minecraft.resources.ResourceLocation
import net.minecraft.world.level.block.state.properties.EnumProperty
import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.NeoComputers.BlockEntityRenderType
import org.neoflock.neocomputers.block.ScreenBlock
import org.neoflock.neocomputers.entity.ScreenEntity
class ScreenEntityRenderer(val context: BlockEntityRendererProvider.Context?) : BlockEntityRenderer<ScreenEntity> {
override fun render(entity: ScreenEntity, partialTick: Float, mat: PoseStack, bufferSource: MultiBufferSource, packedLight: Int, packedOverlay: Int) {
mat.pushPose()
handleDirection(entity, mat)
mat.translate(2 / 16f, 2 / 16f, 0.0001f) // am i epstein or am i just retarded
// mat.mulPose(Axis.YP.rotationDegrees(180f))
// handleDirection(entity, mat)
// RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderTexture(0, ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, entity.bound))
val buffer = bufferSource.getBuffer(BlockEntityRenderType) // idk the correct rendertype for ts
buffer.addVertex(mat.last(), 3 / 4f, 0f, 0f).setUv(1f, 1f)
buffer.addVertex(mat.last(), 3 / 4f, 3 / 4f, 0f).setUv(1f, 0f)
buffer.addVertex(mat.last(), 0f, 3 / 4f, 0f).setUv(0f, 0f)
buffer.addVertex(mat.last(), 0f, 0f, 0f).setUv(0f, 1f)
mat.popPose()
}
private fun handleDirection(ent: ScreenEntity, mat: PoseStack) { // TODO: separate up and down from cardinal directions
when (ent.blockState.getValue(ScreenBlock.FACING)) {
Direction.SOUTH -> { mat.translate(0F, 0F, 1F) }
Direction.EAST -> { mat.mulPose(Axis.YP.rotationDegrees(90F)); mat.translate(-1F, 0F, 1F) }
Direction.WEST -> { mat.mulPose(Axis.YN.rotationDegrees(90F)); }
Direction.NORTH -> {mat.mulPose(Axis.YP.rotationDegrees(180F)); mat.translate(-1F, 0F, 0F) }
Direction.UP -> { mat.mulPose(Axis.XN.rotationDegrees(90F)); mat.mulPose(Axis.ZP.rotationDegrees(180F)); mat.translate(-1.0001F, 0F, 1F) } // idek
Direction.DOWN -> { mat.mulPose(Axis.XP.rotationDegrees(90F)); mat.mulPose(Axis.ZN.rotationDegrees(180F)); mat.translate(-1F, -1F, 0F) }
else -> return
}
}
// private fun handleDirection(ent: ScreenEntity, mat: PoseStack?) {
// `when`(ent.getBlockState().get)
// }
}

View File

@@ -10,6 +10,7 @@ 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.entity.ScreenEntity
import org.neoflock.neocomputers.gui.buffer.BufferRenderer
import org.neoflock.neocomputers.gui.menu.ScreenMenu
import org.neoflock.neocomputers.gui.render.ScreenRenderer
@@ -17,17 +18,9 @@ import org.neoflock.neocomputers.gui.render.ScreenRenderer
class ScreenScreen : AbstractContainerScreen<ScreenMenu>{
private var renderer: ScreenRenderer = ScreenRenderer();
private var bufferRenderer: BufferRenderer? = null;
constructor(abstractContainerMenu: ScreenMenu, inventory: Inventory, component: Component) : super(abstractContainerMenu, inventory, component) {
val buffer: ArrayList<BufferRenderer.GPUChar> = arrayListOf(BufferRenderer.GPUChar('h'), BufferRenderer.GPUChar('a'), BufferRenderer.GPUChar('i'))
for (i in 0..<(400-3)) {
buffer.add(BufferRenderer.GPUChar(' '))
}
bufferRenderer = BufferRenderer(20, 20, ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "screen/test"), buffer)
bufferRenderer!!.register()
bufferRenderer!!.drawBuffer()
renderer.bind(ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "screen/test"))
var ent: ScreenEntity = abstractContainerMenu.entity!!;
renderer.bind(ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, ent.bound))
}
override fun renderBg(guiGraphics: GuiGraphics, f: Float, i: Int, j: Int) {}
override fun render(graphics: GuiGraphics, mouseX: Int, mouseY: Int, something: Float) {
@@ -35,8 +28,8 @@ class ScreenScreen : AbstractContainerScreen<ScreenMenu>{
renderer.render(graphics, 50, 50, 100, 200)
}
override fun onClose() {
super.onClose()
bufferRenderer!!.clean()
}
// override fun onClose() {
// super.onClose()
// renderer.
// }
}

View File

@@ -1,7 +1,27 @@
{
"variants": {
"": {
"facing=north": {
"model": "neocomputers:block/screen"
},
"facing=east": {
"model": "neocomputers:block/screen",
"y": 90
},
"facing=west": {
"model": "neocomputers:block/screen",
"y": -90
},
"facing=south": {
"model": "neocomputers:block/screen",
"y": 180
},
"facing=up": {
"model": "neocomputers:block/screen",
"x": -90
},
"facing=down": {
"model": "neocomputers:block/screen",
"x": 90
}
}
}

View File

@@ -21,6 +21,9 @@
],
"main": [
"org.neoflock.neocomputers.platforms.fabric.NeoComputersFabric"
],
"client": [
"org.neoflock.neocomputers.platforms.fabric.client.NeoComputersFabricClient"
]
},
"mixins": [