Files
NeoComputers/src/main/kotlin/org/neoflock/neocomputers/NeoComputers.kt

166 lines
7.2 KiB
Kotlin

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
import dev.architectury.event.events.common.TickEvent
import dev.architectury.networking.NetworkManager
import dev.architectury.platform.Platform
import net.minecraft.resources.ResourceLocation
import org.neoflock.neocomputers.block.Blocks
import org.neoflock.neocomputers.entity.BlockEntities
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
import org.neoflock.neocomputers.sounds.Sounds
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
Blocks.BLOCKS.register()
Blocks.registerBlockItems()
Items.ITEMS.register()
BlockEntities.BLOCKENTITIES.register()
BlockEntities.registerPowerBlocks()
Menus.MENUS.register()
Tabs.TABS.register()
Sounds.SOUNDS.register()
ComponentRoles.mapDefaultTextures()
// i dont know why architectury wants two lambdas but whatever
EnvExecutor.runInEnv(Env.CLIENT) {{
ClientLifecycleEvent.CLIENT_SETUP.register {
Menus.registerScreens()
}
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 {
ScreenRenderer.cleanUnboundTex()
}
}}
TickEvent.SERVER_POST.register {
Networking.tickAllNodes()
NodeSynchronizer.syncScreens()
}
TickEvent.PLAYER_POST.register {
Sounds.tickCustomSounds()
}
LifecycleEvent.SERVER_STARTING.register {
Networking.allNodes.remove()
Networking.wirelessNodes.remove()
Networking.channels.remove()
}
ClientLifecycleEvent.CLIENT_STARTED.register {
Networking.allNodes.remove()
Networking.wirelessNodes.remove()
Networking.channels.remove()
}
PlayerEvent.CLOSE_MENU.register {
player, menu ->
if(player is ServerPlayer) NodeSynchronizer.playerScreenClosed(player)
}
PlayerEvent.PLAYER_QUIT.register {
player ->
NodeSynchronizer.playerScreenClosed(player)
}
// networking has no way to define a C2S packet type, so we need the listener on both
// however, defining it separately on both breaks both ends
// so we define it once, but on both platforms
if(Platform.getEnvironment() == Env.CLIENT || Platform.getEnvironment() == Env.SERVER) {
NetworkManager.registerReceiver(NetworkManager.c2s(),NodeSynchronizer.ScreenDataPayload.TYPE, NodeSynchronizer.ScreenDataPayload.CODEC, {
packet, ctx ->
val player = ctx.player
if(player is ServerPlayer) {
NodeSynchronizer.screenMap[player]?.processScreenInteraction(player, packet.buffer)
}
})
}
// we have to do this because the datagen task runs in the physical server
EnvExecutor.runInEnv(Env.CLIENT) {{
NetworkManager.registerReceiver(NetworkManager.s2c(),NodeSynchronizer.StatePayload.TYPE, NodeSynchronizer.StatePayload.CODEC, {
packet, ctx ->
val level = ctx.player.level()
val ent = level.getBlockEntity(packet.blockPos)
if(ent is NodeBlockEntity) {
ent.syncWithUpstream(packet.buffer)
}
})
NetworkManager.registerReceiver(NetworkManager.s2c(),NodeSynchronizer.ScreenPayload.TYPE, NodeSynchronizer.ScreenPayload.CODEC, {
packet, ctx ->
val scr = Minecraft.getInstance().screen
if(scr is GenericContainerScreen<*>) {
scr.processScreenStatePacket(packet.buffer)
}
})
NetworkManager.registerReceiver(NetworkManager.s2c(),NodeSynchronizer.BeepDataPayload.TYPE, NodeSynchronizer.BeepDataPayload.CODEC, {
packet, ctx ->
// TODO: implement volume
Sounds.beep(packet.pos.center, packet.pattern, packet.freq, packet.duration.toMillis().toInt())
})
}}
EnvExecutor.runInEnv(Env.SERVER) {{
// https://github.com/architectury/architectury-api/issues/518
NetworkManager.registerS2CPayloadType(NodeSynchronizer.StatePayload.TYPE, NodeSynchronizer.StatePayload.CODEC)
NetworkManager.registerS2CPayloadType(NodeSynchronizer.ScreenPayload.TYPE, NodeSynchronizer.ScreenPayload.CODEC)
NetworkManager.registerS2CPayloadType(NodeSynchronizer.BeepDataPayload.TYPE, NodeSynchronizer.BeepDataPayload.CODEC)
}}
LOGGER.info("Registered!")
//LOGGER.info("Started mod in %s loader".formatted(NeoComputersInit.PLATFORM.getModloader()))
//LOGGER.info("Kotlin: %s".formatted(NeoComputers.hello()))
LOGGER.info("Started mod in ${PLATFORM?.modloader} loader")
LOGGER.info("Hello from kotlin!")
}
}