Compare commits

...

13 Commits

Author SHA1 Message Date
a65cb6f261 stuff 2026-06-06 13:27:03 +02:00
d5202067d1 Add 1.21.1-neoforge, still doesn't work though 2026-06-06 13:00:36 +02:00
a362658371 just in case i fuck everything up 2026-06-06 12:56:01 +02:00
97ed29fc23 changed something. 2026-05-20 20:18:22 +02:00
1c03653fee todo slop 2026-05-19 21:58:35 +02:00
c016cebb0f accuracy slop 2026-05-19 21:51:20 +02:00
885f594ca0 dutch translation but it sucks 2026-05-19 21:46:52 +02:00
45831b780a FRENCH ew 2026-05-19 21:42:16 +02:00
6b0c4468ec FRENCH 2026-05-19 21:37:51 +02:00
d15b34939e models and shi 2026-05-08 03:47:03 +03:00
3f95944314 rack stateslop 2026-05-07 22:43:42 +02:00
21493fec04 add proper container and do some syncy stuff and save 2026-05-07 00:30:08 +02:00
42331390e7 clicky 2026-05-06 17:00:31 +02:00
55 changed files with 835 additions and 135 deletions

View File

@@ -1,6 +1,10 @@
# Networking
> All that is left is optimization
## Mergeable device nodes
For optimization of screen grouping and cables, we should add a system that allows merging nodes
## Copy the networking optimizations of OC
> https://github.com/MightyPirates/OpenComputers/blob/master-MC1.7.10/src/main/scala/li/cil/oc/server/network/Network.scala

View File

@@ -26,9 +26,16 @@ base {
archivesName.set("${mod.id}-$loader")
}
//val foid = ["forge", "fabric", "neoforge"]
//architectury.common(foid)
//architectury.common(["forge", "fabric"])
//println(stonecutter.current.project.split('-').subList(1, 2))
//architectury.common(stonecutter.current.project.split('-').subList(1, 2))
//architectury.common(stonecutter.current.version)
architectury.common(stonecutter.tree.branches.mapNotNull {
if (stonecutter.current.project !in it) null
else it.prop("loom.platform")
// println(stonecutter.current.project !in it)
if (stonecutter.current.project !in it) return null
else return it.prop("loom.platform")
})
repositories {
@@ -118,8 +125,8 @@ dependencies {
// }
// })
if (minecraft=="1.21.9" || minecraft=="1.21.11") modApi("dev.architectury:architectury-neoforge:${archversion}")
else modApi("dev.architectury:architectury-forge:${archversion}") // NOTE: this could be wrong
if (minecraft=="1.21.1" || minecraft=="1.21.9" || minecraft=="1.21.11") modApi("dev.architectury:architectury-neoforge:${archversion}")
else modApi("dev.architectury:architectury-neoforge:${archversion}") // NOTE: this could be wrong
implementation("thedarkcolour:kotlinforforge-neoforge:6.0.0")
}

BIN
rack.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -27,7 +27,7 @@ stonecutter {
mc("forge", "1.20.1")
//WARNING: neoforge uses mods.toml instead of neoforge.mods.toml for versions 1.20.4 (?) and earlier
//mc("neoforge", "1.20.4", "1.21.1", "1.21.3", "1.21.4", "1.21.5", "1.21.6", "1.21.7", "1.21.8", "1.21.9", "1.21.10", "1.21.11")
mc("neoforge", "1.20.4", "1.21.9", "1.21.11")
mc("neoforge", "1.20.4", "1.21.1", "1.21.9", "1.21.11")
}
create(rootProject)
}

View File

@@ -1,5 +1,5 @@
//? if fabric {
package org.neoflock.neocomputers.platforms.fabric;
/*package org.neoflock.neocomputers.platforms.fabric;
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi;
@@ -10,4 +10,4 @@ public class ModMenuIntegration implements ModMenuApi {
return ConfigScreen::createConfigScreen;
}
}
//?}
*///?}

View File

@@ -1,5 +1,5 @@
//? if fabric {
package org.neoflock.neocomputers.platforms.fabric;
/*package org.neoflock.neocomputers.platforms.fabric;
import org.neoflock.neocomputers.ModPlatform;
import net.fabricmc.api.ModInitializer;
@@ -24,4 +24,4 @@ public class NeoComputersFabric implements ModInitializer {
}
}
}
//?}
*///?}

View File

@@ -21,11 +21,6 @@ public class NeoComputersFabricClient implements ClientModInitializer {
@Override
public void onInitializeClient() {
ModelLoadingPlugin.register(new ModelLoader());
BlockEntityRenderers.register(BlockEntities.INSTANCE.getSCREEN_ENTITY().get(), ScreenEntityRenderer::new); // TODO: put this in common
BlockEntityRenderers.register(BlockEntities.INSTANCE.getCASE_ENTITY().get(), CaseEntityRenderer::new);
BlockEntityRenderers.register(BlockEntities.INSTANCE.getRELAY_ENTITY().get(), RelayEntityRenderer::new);
BlockEntityRenderers.register(BlockEntities.INSTANCE.getROBOT_ENTITY().get(), RobotEntityRenderer::new);
BlockEntityRenderers.register(BlockEntities.INSTANCE.getRACK_ENTITY().get(), RackEntityRenderer::new);
ColorProviderRegistry.BLOCK.register((state, world, pos, index) -> {
if (index == 0) {

View File

@@ -1,5 +1,5 @@
//? if neoforge {
/*package org.neoflock.neocomputers.platforms.neoforge;
package org.neoflock.neocomputers.platforms.neoforge;
import org.neoflock.neocomputers.ConfigScreen;
import org.neoflock.neocomputers.ModPlatform;
@@ -8,8 +8,8 @@ import net.neoforged.fml.ModLoadingContext;
import net.neoforged.fml.common.Mod;
import org.neoflock.neocomputers.NeoComputers;
//? if <1.21 {
/^import net.neoforged.neoforge.client.ConfigScreenHandler;
^///?} else {
/*import net.neoforged.neoforge.client.ConfigScreenHandler;
*///?} else {
import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
//?}
@Mod("neocomputers")
@@ -18,11 +18,11 @@ public class NeoComputersNeoForge {
NeoComputers.INSTANCE.entrypoint(new NeoForgePlatform());
ModLoadingContext.get().registerExtensionPoint(
//? if <1.21 {
/^ConfigScreenHandler.ConfigScreenFactory.class,
/*ConfigScreenHandler.ConfigScreenFactory.class,
() -> new ConfigScreenHandler.ConfigScreenFactory(
((client, parent) -> ConfigScreen.createConfigScreen(parent))
)
^///?} else {
*///?} else {
IConfigScreenFactory.class,
() -> (client, parent) -> ConfigScreen.createConfigScreen(parent)
//?}
@@ -40,4 +40,4 @@ public class NeoComputersNeoForge {
}
}
}
*///?}
//?}

View File

@@ -13,8 +13,10 @@ 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.blockentity.BlockEntityRenderers
import net.minecraft.server.level.ServerPlayer
import org.neoflock.neocomputers.block.DeviceBlockEntity
import org.neoflock.neocomputers.entity.render.EntityRenderers
import org.neoflock.neocomputers.gui.render.ScreenRenderer
import org.neoflock.neocomputers.gui.widget.ComponentRoles
import org.neoflock.neocomputers.item.Items
@@ -56,6 +58,10 @@ object NeoComputers {
EnvExecutor.runInEnv(Env.CLIENT) {{
ClientLifecycleEvent.CLIENT_SETUP.register {
Menus.registerScreens()
Networking.allNodes.remove()
Networking.wirelessNodes.remove()
Networking.channels.remove()
EntityRenderers.registerBlockEntityRenderers()
}
ClientLifecycleEvent.CLIENT_STARTED.register {
FontProvider.load(ResourceLocation.fromNamespaceAndPath(MODID, "font/unscii.hex"))
@@ -81,12 +87,6 @@ object NeoComputers {
Networking.channels.remove()
}
ClientLifecycleEvent.CLIENT_SETUP.register {
Networking.allNodes.remove()
Networking.wirelessNodes.remove()
Networking.channels.remove()
}
PlayerEvent.CLOSE_MENU.register {
player, menu ->
if(player is ServerPlayer) NodeSynchronizer.playerScreenClosed(player)

View File

@@ -0,0 +1,16 @@
package org.neoflock.neocomputers.block
import net.minecraft.core.BlockPos
import net.minecraft.world.level.block.EntityBlock
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.state.BlockState
import org.neoflock.neocomputers.entity.AssemblerEntity
class AssemblerBlock : BaseBlock(), EntityBlock { // TODO: component stuff
override fun newBlockEntity(
pos: BlockPos,
state: BlockState
): BlockEntity? {
return AssemblerEntity(pos, state)
}
}

View File

@@ -5,6 +5,7 @@ import dev.architectury.registry.registries.DeferredRegister
import dev.architectury.registry.registries.Registrar
import dev.architectury.registry.registries.RegistrarManager
import dev.architectury.registry.registries.RegistrySupplier
import net.minecraft.client.renderer.RenderType
import net.minecraft.core.registries.Registries
import net.minecraft.resources.ResourceLocation
import net.minecraft.resources.ResourceKey
@@ -37,6 +38,7 @@ object Blocks {
val RELAY_BLOCK: RegistrySupplier<Block> = BaseBlock.register("relay") { RelayBlock() }
val ROBOT_BLOCK: RegistrySupplier<Block> = BaseBlock.register("robot") { RobotBlock() }
val RACK_BLOCK: RegistrySupplier<Block> = BaseBlock.register("rack") { RackBlock() }
val ASSEMBLER_BLOCK: RegistrySupplier<Block> = BaseBlock.register("assembler") { AssemblerBlock() }
fun registerBlockItems() {
BLOCKS.forEach(Consumer { sup: RegistrySupplier<Block> ->

View File

@@ -3,38 +3,25 @@ package org.neoflock.neocomputers.block;
import dev.architectury.registry.menu.MenuRegistry
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.resources.ResourceLocation
import net.minecraft.server.level.ServerPlayer
import net.minecraft.sounds.SoundEvent
import net.minecraft.sounds.SoundEvents
import net.minecraft.sounds.SoundSource
import net.minecraft.util.RandomSource
import net.minecraft.world.Containers
import net.minecraft.world.InteractionResult
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.context.BlockPlaceContext
import net.minecraft.world.level.BlockGetter
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.FurnaceBlock
import net.minecraft.world.level.block.SoundType
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.phys.BlockHitResult
import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.block.CombustionGeneratorBlock.Companion.COMBUSTGEN_ACTIVE
import org.neoflock.neocomputers.entity.BlockEntities
import org.neoflock.neocomputers.entity.CaseBlockEntity
import org.neoflock.neocomputers.entity.MachineEntity
import org.neoflock.neocomputers.network.NodeSynchronizer
import org.neoflock.neocomputers.sounds.Sounds
class CaseBlock() : DeviceBlock(Properties.of().sound(SoundType.METAL).lightLevel(CaseBlock::getLuminance)) { // placeholder stuff
class CaseBlock() : DeviceBlock(Properties.of().sound(SoundType.METAL).lightLevel(CaseBlock::getLuminance).noOcclusion()) { // placeholder stuff
companion object {
val FACING: EnumProperty<Direction> = EnumProperty.create<Direction>("facing", Direction::class.java)
val COMPUTER_RUNNING = BooleanProperty.create("running")!!
@@ -71,7 +58,7 @@ class CaseBlock() : DeviceBlock(Properties.of().sound(SoundType.METAL).lightLeve
}
override fun onPlace(
blockState: BlockState,
state: BlockState,
level: Level,
blockPos: BlockPos,
blockState2: BlockState,
@@ -81,7 +68,7 @@ class CaseBlock() : DeviceBlock(Properties.of().sound(SoundType.METAL).lightLeve
level.updateNeighborsAt(blockPos, this)
getMachine(level, blockPos).refetchAllRedstone()
}
super.onPlace(blockState, level, blockPos, blockState2, bl)
super.onPlace(state, level, blockPos, blockState2, bl)
}
override fun getStateForPlacement(context: BlockPlaceContext): BlockState? {

View File

@@ -20,8 +20,9 @@ import net.minecraft.world.phys.shapes.VoxelShape
import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.entity.BlockEntities
import org.neoflock.neocomputers.entity.RackEntity
import org.neoflock.neocomputers.network.NodeSynchronizer
class RackBlock : BaseBlock(Properties.of().noOcclusion()), EntityBlock {
class RackBlock : DeviceBlock(Properties.of().noOcclusion()), EntityBlock {
override fun newBlockEntity(
pos: BlockPos,
state: BlockState
@@ -59,7 +60,10 @@ class RackBlock : BaseBlock(Properties.of().noOcclusion()), EntityBlock {
}
}
if (!level.isClientSide) MenuRegistry.openMenu(player as ServerPlayer, ent)
if (!level.isClientSide) {
MenuRegistry.openExtendedMenu(player as ServerPlayer, ent)
NodeSynchronizer.registerPlayerScreen(player as ServerPlayer, ent.node)
}
return InteractionResult.SUCCESS
}
}

View File

@@ -4,15 +4,19 @@ import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput
import net.fabricmc.fabric.api.datagen.v1.provider.FabricModelProvider
import net.minecraft.data.models.BlockModelGenerators
import net.minecraft.data.models.ItemModelGenerators
import net.minecraft.data.models.model.ModelTemplate
import net.minecraft.data.models.model.ModelTemplates
import org.neoflock.neocomputers.block.Blocks
import org.neoflock.neocomputers.item.Items
class ModelGenerator(output: FabricDataOutput) : FabricModelProvider(output) {
override fun generateBlockStateModels(blockStateModelGenerator: BlockModelGenerators) {
blockStateModelGenerator.createGenericCube(Blocks.CASE_BLOCK.get())
// blockStateModelGenerator.createGenericCube(Blocks.CASE_BLOCK.get())
}
override fun generateItemModels(itemModelGenerator: ItemModelGenerators) {
// itemModelGenerator.generateFlatItem(Items.SERVER0.get(), ModelTemplates.FLAT_ITEM)
}
}

View File

@@ -0,0 +1,8 @@
package org.neoflock.neocomputers.entity
import net.minecraft.core.BlockPos
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.state.BlockState
class AssemblerEntity(pos: BlockPos, state: BlockState) : BlockEntity(BlockEntities.ASSEMBLER_ENTITY.get(), pos, state) {
}

View File

@@ -106,6 +106,12 @@ object BlockEntities {
)
}
val ASSEMBLER_ENTITY: RegistrySupplier<BlockEntityType<AssemblerEntity>> = BLOCKENTITIES.register("assembler") {
BlockEntityType(
::AssemblerEntity, setOf(Blocks.ASSEMBLER_BLOCK.get()), BullshitFix()
)
}
fun registerPowerBlocks() {
PowerManager.registerPowerDevice(CAPACITOR_ENTITY.get())
PowerManager.registerPowerDevice(CAPACITOR2_ENTITY.get())

View File

@@ -1,19 +1,134 @@
package org.neoflock.neocomputers.entity
import dev.architectury.registry.menu.ExtendedMenuProvider
import net.minecraft.client.renderer.RenderType
import net.minecraft.core.BlockPos
import net.minecraft.core.Direction
import net.minecraft.core.HolderLookup
import net.minecraft.core.NonNullList
import net.minecraft.nbt.CompoundTag
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.network.chat.Component
import net.minecraft.network.protocol.Packet
import net.minecraft.network.protocol.game.ClientGamePacketListener
import net.minecraft.server.level.ServerPlayer
import net.minecraft.world.ContainerHelper
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.block.entity.AbstractFurnaceBlockEntity
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.entity.ChestBlockEntity
import net.minecraft.world.level.block.entity.FurnaceBlockEntity
import net.minecraft.world.level.block.state.BlockState
import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.block.DeviceBlockEntity
import org.neoflock.neocomputers.gui.menu.RackMenu
import org.neoflock.neocomputers.network.DeviceNode
import org.neoflock.neocomputers.network.Networking
import org.neoflock.neocomputers.utils.ContainerUtils
import org.neoflock.neocomputers.utils.GenericContainer
class RackEntity(pos: BlockPos, state: BlockState) : DeviceBlockEntity(BlockEntities.RACK_ENTITY.get(), pos, state), ExtendedMenuProvider, GenericContainer {
val stacks: NonNullList<ItemStack> = NonNullList<ItemStack>.withSize(4, ItemStack.EMPTY)
var conns = mutableListOf(
-1, -1, -1, -1,
-1, -1, -1, -1,
-1, -1, -1, -1,
-1, -1, -1, -1
)
var relayMode = false
val node: DeviceNode = object : DeviceNode() {
override var reachability: Networking.Visibility = Networking.Visibility.NONE
override fun writeFullStateCommit(buf: FriendlyByteBuf) {
super.writeFullStateCommit(buf)
buf.writeBoolean(relayMode)
val tag = CompoundTag() // better way to do this, a better way i do not care to find atm
ContainerHelper.saveAllItems(tag, stacks, level!!.registryAccess())
buf.writeNbt(tag)
for (conn in conns) {
buf.writeInt(conn)
}
}
override fun processCommit(buf: FriendlyByteBuf) {
super.processCommit(buf)
relayMode = buf.readBoolean()
val tag = buf.readNbt()
ContainerHelper.loadAllItems(tag!!, stacks, level!!.registryAccess())
for (i in 0..15) {
conns[i] = buf.readInt()
}
markChanged()
setChanged()
}
override fun processScreenInteraction(player: ServerPlayer, buf: FriendlyByteBuf) {
super.processScreenInteraction(player, buf)
relayMode = buf.readBoolean()
val slot = buf.readInt()
conns[slot*4+0] = buf.readInt()
conns[slot*4+1] = buf.readInt()
conns[slot*4+2] = buf.readInt()
conns[slot*4+3] = buf.readInt()
markChanged()
setChanged()
}
override fun encodeScreenData(player: ServerPlayer, buf: FriendlyByteBuf) { // TODO: set this up so other players can mess with racks
super.encodeScreenData(player, buf)
}
}
override fun setChanged() {
super.setChanged()
node.markChanged()
}
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)
return RackMenu(i, inventory, this)
}
override fun getDeviceNodes(): List<DeviceNode> = listOf(node)
override fun getNodeFromSide(directionToRequester: Direction): DeviceNode? = node
override fun loadAdditional(tag: CompoundTag, registries: HolderLookup.Provider) {
super.loadAdditional(tag, registries)
ContainerHelper.loadAllItems(tag, getItems(), registries)
relayMode = tag.getBoolean("relay")
val connarray = tag.getIntArray("conns")
if (connarray.size == 16) conns = connarray.toMutableList()
setChanged()
}
override fun saveAdditional(tag: CompoundTag, registries: HolderLookup.Provider) {
super.saveAdditional(tag, registries)
ContainerHelper.saveAllItems(tag, getItems(), registries)
tag.putBoolean("relay", relayMode)
tag.putIntArray("conns", conns.toIntArray())
}
// override fun getItems(): NonNullList<ItemStack> = items
override fun getItems(): NonNullList<ItemStack> = stacks
override fun stillValid(player: Player): Boolean = true
override fun saveExtraData(buf: FriendlyByteBuf?) {
buf!!.writeBlockPos(blockPos)
}
}

View File

@@ -2,13 +2,17 @@ package org.neoflock.neocomputers.entity
import net.minecraft.client.model.geom.ModelPart
import net.minecraft.core.BlockPos
import net.minecraft.network.chat.Component
import net.minecraft.world.Nameable
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity
import net.minecraft.world.level.block.state.BlockState
import org.neoflock.neocomputers.NeoComputers
class RobotEntity(pos: BlockPos, state: BlockState) : BlockEntity(BlockEntities.ROBOT_ENTITY.get(), pos, state,) {
class RobotEntity(pos: BlockPos, state: BlockState) : BlockEntity(BlockEntities.ROBOT_ENTITY.get(), pos, state,), Nameable {
val body: ModelPart? = null
val name = "Diddyx" //TODO: names
override fun getName(): Component? = Component.literal(name)
init {
NeoComputers.LOGGER.info("yooo")

View File

@@ -0,0 +1,46 @@
package org.neoflock.neocomputers.entity.render
import com.mojang.blaze3d.vertex.DefaultVertexFormat
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.blaze3d.vertex.VertexFormat
import com.mojang.math.Axis
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.RenderStateShard
import net.minecraft.client.renderer.RenderType
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
import net.minecraft.resources.ResourceLocation
import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.entity.AssemblerEntity
class AssemblerEntityRenderer(val context: BlockEntityRendererProvider.Context) : BlockEntityRenderer<AssemblerEntity> {
val RENDER_TYPE = {l: ResourceLocation ->
RenderType.create("nc_assembler", DefaultVertexFormat.POSITION_TEX, VertexFormat.Mode.QUADS, RenderType.TRANSIENT_BUFFER_SIZE, RenderType.CompositeState.builder()
.setTextureState(RenderStateShard.TextureStateShard(l, false, false))
.setShaderState(RenderStateShard.ShaderStateShard.POSITION_TEX_SHADER)
.createCompositeState(false))
}
override fun render(blockEntity: AssemblerEntity, partialTick: Float, poseStack: PoseStack, bufferSource: MultiBufferSource, packedLight: Int, packedOverlay: Int) {
var buffer = bufferSource.getBuffer(RENDER_TYPE(ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/block/assembler_top_on.png")))
val pose = poseStack.last()
buffer.addVertex(pose, 0f, 17/16f, 1f).setUv(1f, 0f)
buffer.addVertex(pose, 1f, 17/16f, 1f).setUv(1f, 1f)
buffer.addVertex(pose, 1f, 17/16f, 0f).setUv(0f, 1f)
buffer.addVertex(pose, 0f, 17/16f, 0f).setUv(0f, 0f)
// TODO: do assembling texture
buffer = bufferSource.getBuffer(RENDER_TYPE(ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/block/assembler_side_on.png")))
poseStack.pushPose()
for (i in 0..3) {
val pose = poseStack.last()
buffer.addVertex(pose, 1.001f, 1f, 0f).setUv(0f, 0f)
buffer.addVertex(pose, 1.001f, 1f, 1f).setUv(1f, 0f)
buffer.addVertex(pose, 1.001f, 0f, 1f).setUv(1f, 1f)
buffer.addVertex(pose, 1.001f, 0f, 0f).setUv(0f, 1f)
poseStack.rotateAround(Axis.YP.rotationDegrees(90f), 0.5f, 0.5f, 0.5f)
}
poseStack.popPose()
}
}

View File

@@ -5,12 +5,14 @@ import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.blaze3d.vertex.VertexConsumer
import com.mojang.blaze3d.vertex.VertexFormat
import com.mojang.math.Axis
import net.minecraft.client.renderer.LightTexture
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.RenderStateShard
import net.minecraft.client.renderer.RenderType
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
import net.minecraft.core.Direction
import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.block.CaseBlock
import org.neoflock.neocomputers.entity.CaseBlockEntity
@@ -23,9 +25,10 @@ class CaseEntityRenderer(private val context: BlockEntityRendererProvider.Contex
val BLINKTIME: Long = 10 // in ticks
val RENDER_TYPE = RenderType.create("nc_case", DefaultVertexFormat.POSITION_COLOR, VertexFormat.Mode.QUADS,
val RENDER_TYPE = RenderType.create("nc_case", DefaultVertexFormat.POSITION_COLOR_LIGHTMAP, VertexFormat.Mode.QUADS,
RenderType.TRANSIENT_BUFFER_SIZE, RenderType.CompositeState.builder()
.setShaderState(RenderStateShard.POSITION_COLOR_SHADER)
.setShaderState(RenderStateShard.POSITION_COLOR_LIGHTMAP_SHADER)
.setLightmapState(RenderStateShard.LightmapStateShard.LIGHTMAP)
.createCompositeState(false))
override fun render(ent: CaseBlockEntity, partialTick: Float, mat: PoseStack, bufferSource: MultiBufferSource, packedLight: Int, packedOverlay: Int) {
@@ -38,20 +41,20 @@ class CaseEntityRenderer(private val context: BlockEntityRendererProvider.Contex
if (ent.isOn) drawLED(buffer, mat.last(), 3F)
else if (ent.getLastError() != null) { // if else hell
if ((ent.level!!.dayTime/BLINKTIME) % 2 == 1.toLong()) drawLED(buffer, mat.last(), 3F, RED)
else drawLED(buffer, mat.last(), 3F, OFF)
} else drawLED(buffer, mat.last(), 3F, OFF)
else drawLED(buffer, mat.last(), 3F, OFF, packedLight)
} else drawLED(buffer, mat.last(), 3F, OFF, packedLight)
mat.translate(6/16F, 0F, 0F)
drawLED(buffer, mat.last(), 2F, if (ent.diskActivityTime > 0) GREEN else OFF)
drawLED(buffer, mat.last(), 2F, if (ent.diskActivityTime > 0) GREEN else OFF, if (ent.diskActivityTime > 0) LightTexture.FULL_BRIGHT else packedLight)
mat.popPose()
}
private fun drawLED(buffer: VertexConsumer, mat: PoseStack.Pose, width: Float, color: Int = GREEN) {
buffer.addVertex(mat, width/16F, 0F, 0F).setColor(color)
buffer.addVertex(mat, width/16F, 1/16F, 0F).setColor(color)
buffer.addVertex(mat, 0F, 1/16F, 0F).setColor(color)
buffer.addVertex(mat, 0F, 0F, 0F).setColor(color)
private fun drawLED(buffer: VertexConsumer, mat: PoseStack.Pose, width: Float, color: Int = GREEN, light: Int = LightTexture.FULL_BRIGHT) {
buffer.addVertex(mat, width/16F, 0F, 0F).setColor(color).setLight(light)
buffer.addVertex(mat, width/16F, 1/16F, 0F).setColor(color).setLight(light)
buffer.addVertex(mat, 0F, 1/16F, 0F).setColor(color).setLight(light)
buffer.addVertex(mat, 0F, 0F, 0F).setColor(color).setLight(light)
}
private fun handleDirection(facing: Direction, mat: PoseStack) {

View File

@@ -0,0 +1,15 @@
package org.neoflock.neocomputers.entity.render
import net.minecraft.client.renderer.blockentity.BlockEntityRenderers
import org.neoflock.neocomputers.entity.BlockEntities
object EntityRenderers {
fun registerBlockEntityRenderers() {
BlockEntityRenderers.register(BlockEntities.SCREEN_ENTITY.get(), ::ScreenEntityRenderer); // TODO: put this in common
BlockEntityRenderers.register(BlockEntities.CASE_ENTITY.get(), ::CaseEntityRenderer);
BlockEntityRenderers.register(BlockEntities.RELAY_ENTITY.get(), ::RelayEntityRenderer);
BlockEntityRenderers.register(BlockEntities.ROBOT_ENTITY.get(), ::RobotEntityRenderer);
BlockEntityRenderers.register(BlockEntities.RACK_ENTITY.get(), ::RackEntityRenderer);
BlockEntityRenderers.register(BlockEntities.ASSEMBLER_ENTITY.get(), ::AssemblerEntityRenderer)
}
}

View File

@@ -22,10 +22,18 @@ class RackEntityRenderer(val context: BlockEntityRendererProvider.Context) : Blo
poseStack.pushPose()
poseStack.translate(1/16f, 11/16f, 1/16f)
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 { override fun render_lights(source: MultiBufferSource, stack: PoseStack, light: Int) { } }
server.render(source, poseStack, packedLight, 2f+(3*render_slot)) // who knows atp
val items = ent.stacks
for (i in 0..3) {
if (items[i].item is RackItem) {
val item = items[i].item as RackItem
item.render(source, poseStack, packedLight, 2f+(3*i))
}
poseStack.translate(0f, -3/16f, 0f)
}
// 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 { override fun render_lights(source: MultiBufferSource, stack: PoseStack, light: Int) { } }
// server.render(source, poseStack, packedLight, 2f+(3*render_slot)) // who knows atp
poseStack.popPose()
}
}

View File

@@ -20,6 +20,8 @@ import net.minecraft.client.renderer.block.ModelBlockRenderer
import net.minecraft.client.renderer.block.model.BakedQuad
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
import net.minecraft.client.renderer.blockentity.ChestRenderer
import net.minecraft.client.renderer.entity.EntityRenderer
import net.minecraft.client.renderer.entity.LivingEntityRenderer
import net.minecraft.client.renderer.texture.OverlayTexture
import net.minecraft.client.renderer.texture.TextureAtlas
@@ -33,6 +35,7 @@ import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.RandomSource
import net.minecraft.world.item.DyeColor
import net.minecraft.world.level.block.entity.ChestBlockEntity
import net.minecraft.world.phys.Vec3
import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.block.model.RobotModel
@@ -51,6 +54,7 @@ class RobotEntityRenderer(val context: BlockEntityRendererProvider.Context) : Bl
CompositeState.builder()
.setShaderState(RenderStateShard.ShaderStateShard { GameRenderer.getPositionTexColorShader() })
.setTransparencyState(RenderStateShard.ADDITIVE_TRANSPARENCY)
.setCullState(RenderStateShard.CullStateShard.NO_CULL)
.setTextureState(RenderStateShard.TextureStateShard(ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/block/robot.png"), false, false))
.createCompositeState(false))
@@ -70,9 +74,10 @@ class RobotEntityRenderer(val context: BlockEntityRendererProvider.Context) : Bl
// TODO: crafting table and chest little models
// EntityRenderer
poseStack.popPose()
renderTag(ent, Component.literal(ent.name), poseStack, bufferSource, packedLight, partialTick)
poseStack.popPose()
}
// offset is 0-15
@@ -106,16 +111,18 @@ class RobotEntityRenderer(val context: BlockEntityRendererProvider.Context) : Bl
stack.pushPose()
stack.translate(vec.x, vec.y, vec.z)
// stack.mulPose(context.entityRenderer.cameraOrientation())
stack.mulPose(context.entityRenderer.cameraOrientation())
stack.scale(0.025F, -0.025F, 0.025F)
val opacity = Minecraft.getInstance().options.getBackgroundOpacity(0.25F)
val alpha: Int = (opacity * 255.0f).toInt() shl 24
// val alpha = 255
val halfwidth = (-context.font.width(name)) / 2;
RenderSystem.disableDepthTest()
context.font.drawInBatch(name, halfwidth.toFloat(), 2f, 0xFFFFFF, false, stack.last().pose(), source, Font.DisplayMode.SEE_THROUGH, alpha, light)
// RenderSystem.enableDepthTest()
// RenderSystem.enableBlend()
// RenderSystem.depthMask(true)
RenderSystem.enableDepthTest()
context.font.drawInBatch(name, halfwidth.toFloat(), 2f, 0xFFFFFF, false, stack.last().pose(), source, Font.DisplayMode.SEE_THROUGH, alpha, light)
(source as MultiBufferSource.BufferSource).endBatch()
stack.popPose()
}

View File

@@ -0,0 +1,29 @@
package org.neoflock.neocomputers.gui.menu
import net.fabricmc.fabric.mixin.item.client.HeldItemRendererMixin
import net.minecraft.client.gui.MapRenderer
import net.minecraft.client.renderer.entity.ItemRenderer
import net.minecraft.world.Container
import net.minecraft.world.SimpleContainer
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.item.ItemStack
import org.neoflock.neocomputers.block.Blocks
import org.neoflock.neocomputers.gui.widget.DynamicSlot
import org.neoflock.neocomputers.utils.GenericContainer
import org.neoflock.neocomputers.utils.GenericContainerMenu
class CaseSlot(container: Container, index: Int, x: Int, y: Int) : DynamicSlot(container, index, x, y) {
val caseItems = listOf(Blocks.CASE_BLOCK.get().asItem())
override fun mayPlace(stack: ItemStack): Boolean = stack.item in caseItems
}
class AssemblerMenu : GenericContainerMenu {
constructor(id: Int, inv: Inventory) : this(id, inv, SimpleContainer(1))
constructor(id: Int, inv: Inventory, container: Container) : super(Menus.ASSEMBLER_MENU.get(), id, container) {
this.addSlot(CaseSlot(container, 0, 12, 12))
this.addInventoryHotbar(inv, 8, 84)
}
}

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.AssemblerScreen
import org.neoflock.neocomputers.gui.screen.CaseScreen
import org.neoflock.neocomputers.gui.screen.CombustionGeneratorScreen
import org.neoflock.neocomputers.gui.screen.RackScreen
@@ -23,7 +24,9 @@ object Menus {
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() )}
val RELAY_MENU: RegistrySupplier<MenuType<RelayMenu>> = MENUS.register("relay_menu") { MenuType(::RelayMenu, FeatureFlagSet.of() )}
val RACK_MENU: RegistrySupplier<MenuType<RackMenu>> = MENUS.register("rack_menu") { MenuType(::RackMenu, FeatureFlagSet.of() )}
val RACK_MENU: RegistrySupplier<MenuType<RackMenu>> = MENUS.register("rack_menu") { MenuRegistry.ofExtended(::RackMenu) }
val ASSEMBLER_MENU: RegistrySupplier<MenuType<AssemblerMenu>> = MENUS.register("assembler_menu") { MenuType(::AssemblerMenu, FeatureFlagSet.of() )}
// val RACK_MENU: RegistrySupplier<MenuType<RackMenu>> = MENUS.register("rack_menu") { MenuType(::RackMenu, FeatureFlagSet.of() )}
fun registerScreens() {
MenuScreens.register(Menus.COMBUSTGEN_MENU.get()) { m: CombustionGeneratorMenu, u, comp ->CombustionGeneratorScreen(m,u,comp)}
@@ -31,5 +34,6 @@ object Menus {
MenuScreens.register(Menus.CASE_MENU.get(), ::CaseScreen)
MenuScreens.register(Menus.RELAY_MENU.get(), ::RelayScreen)
MenuScreens.register(Menus.RACK_MENU.get(), ::RackScreen)
MenuScreens.register(Menus.ASSEMBLER_MENU.get(), ::AssemblerScreen)
}
}

View File

@@ -6,34 +6,65 @@ 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 io.netty.buffer.Unpooled
import net.minecraft.client.Minecraft
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.gui.components.events.GuiEventListener
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.client.resources.sounds.SimpleSoundInstance
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.sounds.SoundEvents
import net.minecraft.world.Container
import net.minecraft.world.SimpleContainer
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack
import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.entity.RackEntity
import org.neoflock.neocomputers.gui.widget.ComponentRoles
import org.neoflock.neocomputers.gui.widget.DynamicSlot
import org.neoflock.neocomputers.item.ComponentItem
import org.neoflock.neocomputers.utils.GenericContainerMenu
class RackSlot(container: Container, slot: Int, x: Int, y: Int) : DynamicSlot(container, slot, x, y) {
class RackSlot(container: Container, slot: Int, x: Int, y: Int) : DynamicSlot(container, slot, x, y), GuiEventListener {
// i hate that i made this, my regret is immeasurable
// i genuinely cant help myself
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())
val secondaries = 2 // TODO: make this actually change depending on how many network cards
// todo: kotlin getters and setters
fun getSelected(i: Int): Int = (container as RackEntity).conns[containerSlot*4+i]
fun setSelected(i: Int, v: Int) { (container as RackEntity).conns[containerSlot*4+i] = v }
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)
for (i in 0..secondaries) {
if (getSelected(i) > -1) drawConnection(graphics, getSelected(i), i-1)
}
drawEndpoints(graphics, mouseX, mouseY, secondaries)
}
override fun mayPlace(stack: ItemStack): Boolean {
if (stack.item !is ComponentItem) return false
return (stack.item as ComponentItem).getComponentRoles(stack).contains(ComponentRoles.RACK_MOUNTABLE)
}
override fun onTake(player: Player, stack: ItemStack) {
super.onTake(player, stack)
setSelected(0, -1)
setSelected(1, -1)
setSelected(2, -1)
setSelected(3, -1)
(container as RackEntity).setChanged()
drawEndpoints(graphics, 2)
}
fun drawConnection(guiGraphics: GuiGraphics, side: Int, sec: Int = -1) {
@@ -51,7 +82,7 @@ class RackSlot(container: Container, slot: Int, x: Int, y: Int) : DynamicSlot(co
}
fun drawEndpoints(guiGraphics: GuiGraphics, sec: Int =0) {
fun drawEndpoints(guiGraphics: GuiGraphics, mx: Int, my: Int, sec: Int =0) {
val bufferSource = guiGraphics.bufferSource()
val buffer = bufferSource.getBuffer(RenderType.gui())
@@ -64,6 +95,11 @@ class RackSlot(container: Container, slot: Int, x: Int, y: Int) : DynamicSlot(co
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)
// highlight
if (mx >= x+25+(11*i) && mx <= x+27+(11*i) && my >= y+1 && my <= y+3) {
drawColor(guiGraphics, buffer, 25+(11*i), 1, 0x80FFFFFF.toInt(), 3, 3)
}
}
// secondary endpoints
@@ -77,10 +113,24 @@ class RackSlot(container: Container, slot: Int, x: Int, y: Int) : DynamicSlot(co
drawColor(guiGraphics, buffer, 24+(11*j), 6+(4*i), 0xff333333.toInt(), 1, 2)
drawColor(guiGraphics, buffer, 25+(11*j), 6+(4*i), MAIN_COLOURS[j], 3, 2)
drawColor(guiGraphics, buffer, 28+(11*j), 6+(4*i), 0xffffffff.toInt(), 1, 2)
// highlight
if (mx >= x+25+(11*j) && mx <= x+27+(11*j) && my >= y+6+(4*i) && my <= y+8+(4*i)) {
drawColor(guiGraphics, buffer, 25+(11*j), 6+(4*i), 0x80FFFFFF.toInt(), 3, 2)
}
}
}
}
fun encode(buf: FriendlyByteBuf) { // client -> server
buf.writeInt(containerSlot)
buf.writeInt(getSelected(0))
buf.writeInt(getSelected(1))
buf.writeInt(getSelected(2))
buf.writeInt(getSelected(3))
}
// TODO: replace with graphics.fill (cant be assed atm)
fun drawColor(guiGraphics: GuiGraphics, buffer: VertexConsumer, _x:Int, _y: Int, col: Int, width: Int=1, height: Int=1) {
val pose = guiGraphics.pose().last()
@@ -91,15 +141,51 @@ class RackSlot(container: Container, slot: Int, x: Int, y: Int) : DynamicSlot(co
buffer.addVertex(pose, x+_x.toFloat(), y+_y.toFloat(), 2f).setColor(col)
buffer.addVertex(pose, x+_x.toFloat(), y+_y+height.toFloat(), 2f).setColor(col)
}
fun clickynoise() {
val handler = Minecraft.getInstance().soundManager
handler.play(SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F));
}
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
for (i in 0..4) { // main line
if (mouseX >= x+25+(11*i) && mouseX <= x+28+(11*i) && mouseY >= y+1 && mouseY <= y+4 && button == 0) {
setSelected(0, if (getSelected(0) != i) i else -1)
(container as RackEntity).setChanged()
clickynoise()
return true
}
}
for (i in 0..<secondaries) { // secondary lines
for (j in 0..4) {
if (mouseX >= x+25+(11*j) && mouseX <= x+28+(11*j) && mouseY >= y+6+(4*i) && mouseY <= y+8+(4*i) && button == 0) {
setSelected(i+1, if (getSelected(i+1) != j) j else -1)
(container as RackEntity).setChanged()
clickynoise()
return true
}
}
}
return super.mouseClicked(mouseX, mouseY, button)
}
override fun setFocused(focused: Boolean) {
}
override fun isFocused(): Boolean {
return false
}
}
class RackMenu : GenericContainerMenu {
constructor(i: Int, inv: Inventory) : this(i, inv, SimpleContainer(4))
constructor(i: Int, inv: Inventory, buf: FriendlyByteBuf) : this(i, inv, (inv.player.level().getBlockEntity(buf.readBlockPos()) as RackEntity))
constructor(i: Int, inv: Inventory, container: Container) : super(Menus.RACK_MENU.get(), i, container) {
for(i in 0..3) {
this.addSlot(RackSlot(container, i, 20, 23+i*20))
val slot = RackSlot(container, i, 20, 23+i*20)
this.addSlot(slot)
}
this.addInventorySlots(inv, 8, 128)
}

View File

@@ -13,7 +13,7 @@ import java.io.File
import kotlin.experimental.and
import kotlin.experimental.xor
class BufferRenderer(private var id: ResourceLocation, private var buffer: TextBuffer) { // TODO: NN buffer
class BufferRenderer(private var id: ResourceLocation, var buffer: TextBuffer) { // TODO: NN buffer
val CHARW = 8
val CHARH = 16

View File

@@ -0,0 +1,39 @@
package org.neoflock.neocomputers.gui.screen
import io.netty.buffer.Unpooled
import net.minecraft.client.gui.GuiGraphics
import net.minecraft.network.FriendlyByteBuf
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.AssemblerMenu
import org.neoflock.neocomputers.gui.menu.CaseMenu
import org.neoflock.neocomputers.gui.widget.ButtonSprites
import org.neoflock.neocomputers.gui.widget.ImagerButton
import org.neoflock.neocomputers.network.NodeSynchronizer
import org.neoflock.neocomputers.utils.GenericContainerScreen
class AssemblerScreen : GenericContainerScreen<AssemblerMenu> {
private var btn: ImagerButton? = null
private val PCB: ResourceLocation = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/gui/computer.png")
private val BTN: ResourceLocation = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/gui/button_power.png")
constructor(abstractContainerMenu: AssemblerMenu, inventory: Inventory, component: Component) : super(abstractContainerMenu, inventory, component) {
btn = ImagerButton(
8, 104,
18, 18,
ButtonSprites(BTN, 18, 18, 36, 36)
) {
// val buf = FriendlyByteBuf(Unpooled.buffer())
// buf.writeByte(if(isOn) 0x02 else 0x01)
// NodeSynchronizer.sendScreenInteraction(buf)
}
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
}
}

View File

@@ -1,16 +1,22 @@
package org.neoflock.neocomputers.gui.screen
import io.netty.buffer.Unpooled
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.components.events.GuiEventListener
import net.minecraft.client.gui.narration.NarrationElementOutput
import net.minecraft.network.FriendlyByteBuf
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.entity.RackEntity
import org.neoflock.neocomputers.gui.menu.RackMenu
import org.neoflock.neocomputers.gui.menu.RackSlot
import org.neoflock.neocomputers.gui.widget.IconTextButton
import org.neoflock.neocomputers.network.NodeSynchronizer
import org.neoflock.neocomputers.utils.GenericContainerScreen
import java.util.function.Supplier
@@ -18,9 +24,9 @@ class RackScreen(menu: RackMenu, inventory: Inventory, component: Component) : G
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
var relay_mode = if (menu.container is RackEntity) (menu.container as RackEntity).relayMode else false
val relaybtn = IconTextButton(100, 96, "Disabled", RELAY, width = 64) {
val relaybtn = IconTextButton(100, 96, if(relay_mode) "Enabled" else "Disabled", RELAY, width = 64) {
if (relay_mode){
it.message = Component.literal("Disabled")
relay_mode = false
@@ -28,6 +34,11 @@ class RackScreen(menu: RackMenu, inventory: Inventory, component: Component) : G
it.message = Component.literal("Enabled")
relay_mode = true
}
val buffer = FriendlyByteBuf(Unpooled.buffer())
buffer.writeBoolean(relay_mode)
(menu.slots[0] as RackSlot).encode(buffer)
NodeSynchronizer.sendScreenInteraction(buffer)
}
init {
this.imageWidth = 175
@@ -59,4 +70,37 @@ class RackScreen(menu: RackMenu, inventory: Inventory, component: Component) : G
graphics.drawString(font, "Right", x, y+33, 0x404040, false)
graphics.drawString(font, "Left", x, y+44, 0x404040, false)
}
// override fun processScreenStatePacket(buf: FriendlyByteBuf) {
// super.processScreenStatePacket(buf)
//// NeoComputers.LOGGER.info("porcessing screen state packet...")
//// relay_mode = buf.readBoolean()
//// if (relay_mode) relaybtn.message = Component.literal("Enabled")
//// else relaybtn.message = Component.literal("Disabled")
////
//// for (slot in menu.slots) {
//// if (slot is RackSlot) {
//// slot.processStateScreenPacket(buf)
//// }
//// }
//
// }
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
if (super.mouseClicked(mouseX, mouseY, button)) return true
for (slot in menu.slots) {
if (slot is RackSlot) {
if(slot.mouseClicked(mouseX-imageX, mouseY-imageY, button)) {
val buf = FriendlyByteBuf(Unpooled.buffer())
buf.writeBoolean(relay_mode)
slot.encode(buf)
NodeSynchronizer.sendScreenInteraction(buf)
return true
}
}
}
return false;
}
}

View File

@@ -83,13 +83,10 @@ 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) {
class ComponentSlot(container: Container, slot: Int, x: Int, y: Int, val machine: ComponentUser?, var requirement: ComponentSlotRequirement): DynamicSlot(container, slot, x, y) {
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(graphics, ComponentRoles.getTextureFor(requirement.role), x - 1, y - 1, 18, 18, 0F, 0F, 15F, 15F)
if (requirement.tier > 0) {
RenderSystem.setShaderTexture(

View File

@@ -17,7 +17,7 @@ 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) {
open class DynamicSlot(container: Container, slot: Int, x: Int, y: Int, var active: Boolean = true) : Slot(container, slot, x, y) {
val BACKGROUND: ResourceLocation = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/gui/slots/slot.png")
val RENDER_TYPE = { r: ResourceLocation ->
@@ -42,4 +42,6 @@ open class DynamicSlot(container: Container, slot: Int, x: Int, y: Int) : Slot(c
builder.addVertex(pose, x.toFloat(), y.toFloat(), 1f).setUv(u1/15F,v1/15F)
}
override fun isActive() = active
}

View File

@@ -10,7 +10,7 @@ import org.neoflock.neocomputers.gui.widget.ComponentRoles
class InternetCard: Item(Item.Properties()), ComponentItem {
override fun getComponentRoles(itemStack: ItemStack): Set<String> = setOf(ComponentRoles.CARD, ComponentRoles.INET)
override fun getComponentTier(itemStack: ItemStack): Int = 1
override fun getComponentTier(itemStack: ItemStack): Int = 2
override fun whenComponentPlaced(itemStack: ItemStack, machine: ComponentUser?, newRole: String) {
if(machine != null) ensureHasAddress(itemStack)

View File

@@ -46,4 +46,6 @@ object Items {
val REDIO0 = ITEMS.register("redio0") { RedstoneCard0() }
val REDIO1 = ITEMS.register("redio1") { RedstoneCard1() }
val SERVER0 = ITEMS.register("server0") { ServerItem() }
}

View File

@@ -0,0 +1,27 @@
package org.neoflock.neocomputers.item
import com.mojang.blaze3d.vertex.PoseStack
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.entity.ItemRenderer
import net.minecraft.client.renderer.item.ItemProperties
import net.minecraft.world.item.Item
import net.minecraft.world.item.ItemStack
import org.neoflock.neocomputers.entity.ComponentUser
import org.neoflock.neocomputers.gui.widget.ComponentRoles
import org.neoflock.neocomputers.network.DeviceNode
class ServerItem() : Item(Properties()), ComponentItem, RackItem {
override fun getComponentRoles(itemStack: ItemStack): Set<String> = setOf(ComponentRoles.RACK_MOUNTABLE)
override fun getComponentTier(itemStack: ItemStack): Int = 0
override fun toComponentNode(
itemStack: ItemStack,
machine: ComponentUser?
): DeviceNode? {
return null // TODO: atom machine item plz
}
override fun render_lights(source: MultiBufferSource, stack: PoseStack, light: Int) {
}
}

View File

@@ -23,38 +23,9 @@ object Tabs {
ItemStack(Items.MEM0.get())
}
builder.displayItems { parameters, output ->
// TODO: get rid of arch$tab and this shi and replace with loop over items registry
output.accept(ItemStack(Items.CPU0.get()))
output.accept(ItemStack(Items.CPU1.get()))
output.accept(ItemStack(Items.CPU2.get()))
output.accept(ItemStack(Items.CBUS0.get()))
output.accept(ItemStack(Items.CBUS1.get()))
output.accept(ItemStack(Items.CBUS2.get()))
output.accept(ItemStack(Items.CBUS_CREATIVE.get()))
output.accept(ItemStack(Items.DATA0.get()))
output.accept(ItemStack(Items.DATA1.get()))
output.accept(ItemStack(Items.DATA2.get()))
output.accept(ItemStack(Items.GPU0.get()))
output.accept(ItemStack(Items.GPU1.get()))
output.accept(ItemStack(Items.GPU2.get()))
output.accept(ItemStack(Items.HDD0.get()))
output.accept(ItemStack(Items.HDD1.get()))
output.accept(ItemStack(Items.HDD2.get()))
output.accept(ItemStack(Items.INET.get()))
output.accept(ItemStack(Items.TUNNEL.get()))
output.accept(ItemStack(Items.LAN.get()))
output.accept(ItemStack(Items.WLAN0.get()))
output.accept(ItemStack(Items.WLAN1.get()))
output.accept(ItemStack(Items.REDIO0.get()))
output.accept(ItemStack(Items.REDIO1.get()))
output.accept(ItemStack(Items.EE0.get()))
Items.ITEMS.forEach {
output.accept(ItemStack(it.get()))
}
// Criminal black magic to put LuaBIOS EEPROM in the tabs
do {

View File

@@ -3,10 +3,10 @@ package org.neoflock.neocomputers.network
import net.minecraft.world.level.block.entity.BlockEntityType
import org.neoflock.neocomputers.block.DeviceBlockEntity
//? if fabric {
import net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext
/*import net.fabricmc.fabric.api.transfer.v1.transaction.TransactionContext
import net.minecraft.core.Direction
import team.reborn.energy.api.EnergyStorage;
//?}
*///?}
// our soul purpose is to fuse bullshit power APIs together
// the NodeBlockEntity and Node given us a way to get power from a block, we just
@@ -14,7 +14,7 @@ import team.reborn.energy.api.EnergyStorage;
object PowerManager {
fun<T: DeviceBlockEntity> registerPowerDevice(blockEntityType: BlockEntityType<T>) {
//? if fabric {
EnergyStorage.SIDED.registerForBlockEntity({
/*EnergyStorage.SIDED.registerForBlockEntity({
// TODO: as this is currently written, if the node instance changes and the mod cached the conversion, we're boned. Consider fixing it.
entity, dir ->
val node = entity.getNodeFromSide(dir ?: Direction.UP)
@@ -41,6 +41,6 @@ object PowerManager {
}
}
}, blockEntityType);
//?}
*///?}
}
}

View File

@@ -6,6 +6,7 @@ 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.components.events.GuiEventListener
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen
import net.minecraft.client.renderer.RenderStateShard
import net.minecraft.client.renderer.RenderStateShard.ShaderStateShard
@@ -165,7 +166,7 @@ abstract class GenericContainerScreen<T: GenericContainerMenu>(menu: T, inventor
for (slot in menu.slots) {
if (slot is DynamicSlot) {
slot.draw(guiGraphics, i, j)
slot.draw(guiGraphics, i-cx, j-cy)
}
}
@@ -188,9 +189,11 @@ abstract class GenericContainerScreen<T: GenericContainerMenu>(menu: T, inventor
}
override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean {
super.mouseClicked(mouseX, mouseY, button)
for (widget in widgets) {
if (widget.mouseClicked(mouseX-imageX, mouseY-imageY, button)) return true
}
return false
}

View File

@@ -1,14 +1,73 @@
package org.neoflock.neocomputers.utils
import com.mojang.blaze3d.platform.NativeImage
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.texture.DynamicTexture
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import net.minecraft.util.ResourceLocationPattern
import org.neoflock.neocomputers.gui.widget.DynamicSlot
import kotlin.experimental.and
import kotlin.math.min
data class GPUChar(val c: Char, val fg: Int =0xFFFFFF, val bg: Int = 0) // all is bgr
// TODO: wrapper over NN buffer
class TextBuffer(var width: Int, var height: Int) {
// val CHARW = 8
// val CHARH = 16
//
// val texwidth: Int
// get() = width*CHARW
//
// val texheight: Int
// get() = height*CHARH
//
// var image = NativeImage(texwidth, texheight, true)
// var tex = DynamicTexture(image)
val blank = GPUChar(' ')
var buf = Array(width*height) { blank }
// init {
// Minecraft.getInstance().textureManager.register(this.id, tex)
// }
// fun toRGBA(color: Int): Int {
// // Minecaft lies, its AGBR
// return java.lang.Integer.reverseBytes((color.toLong() * 256 + 0xFF).toInt())
// }
//
// fun drawGlyph(x: Int, y: Int, c: Char, fg: Int) {
// var glyph: ArrayList<Byte> = FontProvider.map[c]!!
//
// for (j in 0..<CHARH) {
// 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))
// }
// }
// }
//
// fun drawBuffer() {
// for (i in 0..<width) {
// for (j in 0..<height) {
// var char: GPUChar = buf[j*height+i]
// var x = i*CHARW
// var y = j*CHARH
// image.fillRect(x, y, CHARW, CHARH, toRGBA(char.bg))
// if (char.c != ' ' && char.c != '\u0000') drawGlyph(x, y, char.c, char.fg)
// }
// }
// tex.upload()
// }
//
// fun clean() {
// Minecraft.getInstance().textureManager.release(this.id)
// image.close()
// tex.close()
// }
fun encodeContents(buf: FriendlyByteBuf) {
// 0x01 means set fg, 0x02 means set bg,
@@ -75,16 +134,19 @@ class TextBuffer(var width: Int, var height: Int) {
fun inBounds(x: Int, y: Int) = x >= 0 && y >= 0 && x < width && y < height
fun get(x: Int, y: Int) = if(inBounds(x, y)) buf[x+y*width] else blank
fun set(x: Int, y: Int, pixel: GPUChar) {
fun _set(x: Int, y: Int, pixel: GPUChar) {
if(!inBounds(x, y)) return
buf[x+y*width] = pixel
// image.fillRect(x, y, CHARW, CHARH, toRGBA(pixel.bg))
// if (pixel.c != ' ' && pixel.c != '\u0000') drawGlyph(x, y, pixel.c, pixel.fg)
}
fun set(x: Int, y: Int, text: String, fg: Int = 0xFFFFFF, bg: Int = 0x000000, vertical: Boolean = false) {
for ((i, c) in text.toCharArray().withIndex()) {
val cx = if(vertical) x else x + i
val cy = if(vertical) y + i else y
set(cx, cy, GPUChar(c, fg, bg))
_set(cx, cy, GPUChar(c, fg, bg))
}
// tex.upload()
}
fun fill(x: Int, y: Int, w: Int, h: Int, pixel: GPUChar = blank) {
// turn it into values we can fw
@@ -92,8 +154,9 @@ class TextBuffer(var width: Int, var height: Int) {
val fh = min(h, height)
for(py in y..<y+fh) {
for (px in x..<x + fw) {
set(px, py, pixel)
_set(px, py, pixel)
}
}
// tex.upload()
}
}

View File

@@ -1,8 +0,0 @@
{
"sources": [
{
"type": "single",
"source": "neocomputers:block/relay_top"
}
]
}

View File

@@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "neocomputers:block/assembler" }
}
}

View File

@@ -0,0 +1,67 @@
{
"neocomputers.confirm": "Confirmer",
"neocomputers.cancel": "Annuler",
"block.neocomputers.combustgen": "Générateur à combustion",
"block.neocomputers.redio": "Controleur de redstone",
"item.neocomputers.redio0": "Carte redstone (niveau 1)",
"item.neocomputers.redio1": "Carte redstone (niveau 2)",
"block.neocomputers.solargen": "Panneau solaire",
"block.neocomputers.screen": "Écran (sans niveau)",
"block.neocomputers.capacitor": "Petit condensateur",
"block.neocomputers.capacitor2": "Condensateur moyen",
"block.neocomputers.capacitor3": "Grand condensateur",
"block.neocomputers.case": "Boîtier (sans niveau)",
"block.neocomputers.cable": "Cable",
"block.neocomputers.relay": "Relais",
"item.neocomputers.eeprom0": "EEPROM (niveau 1)",
"item.neocomputers.cpu0": "Processeur (niveau 1)",
"item.neocomputers.cpu1": "Processeur (niveau 2)",
"item.neocomputers.cpu2": "Processeur (niveau 3)",
"item.neocomputers.cbus0": "Bus informatique (niveau 1)",
"item.neocomputers.cbus1": "Bus informatique (niveau 2)",
"item.neocomputers.cbus2": "Bus informatique (niveau 3)",
"item.neocomputers.cbus_creative": "Bus informatique (créatif)",
"item.neocomputers.memory0": "Mémoire (niveau 1)",
"item.neocomputers.memory1": "Mémoire (niveau 1,5)",
"item.neocomputers.memory2": "Mémoire (niveau 2)",
"item.neocomputers.memory3": "Mémoire (niveau 2,5)",
"item.neocomputers.memory4": "Mémoire (niveau 3)",
"item.neocomputers.memory5": "Mémoire (niveau 3,5)",
"item.neocomputers.inet": "Carte internet",
"item.neocomputers.lan": "Carte réseau sans fil",
"item.neocomputers.wlan0": "Carte réseau sans fil (niveau 1)",
"item.neocomputers.wlan1": "Carte réseau sans fil (niveau 2)",
"item.neocomputers.tunnel": "Carte liée",
"item.neocomputers.data0": "Carte de données (niveau 1)",
"item.neocomputers.data1": "Carte de données (niveau 2)",
"item.neocomputers.data2": "Carte de données (niveau 3)",
"item.neocomputers.gpu0": "Carte graphiques (niveau 1)",
"item.neocomputers.gpu1": "Carte graphiques (niveau 2)",
"item.neocomputers.gpu2": "Carte graphiques (niveau 3)",
"item.neocomputers.hdd0": "Disque dur (niveau 1)",
"item.neocomputers.hdd1": "Disque dur (niveau 2)",
"item.neocomputers.hdd2": "Disque dur (niveau 3)",
"neocomputers.errors.ENOCPU": "absence d'un processeur",
"neocomputers.errors.E2BIG": "trop de composants",
"neocomputers.errors.ENOENJ": "niveau d'énergie dangereusement bas",
"neocomputers.errors.ENOMEM": "absence de mémoire",
"neocomputers.wlan.range": "Portée: %1$s blocs",
"neocomputers.data.limit": "Mémoire: %1$s",
"neocomputers.gpu.vram": "Mémoire vidéo: %1$spx",
"neocomputers.disk.spaceused": "Espace utilisé: %1$s / %2$s",
"neocomputers.readonly": "Lecture seule",
"neocomputers.readwrite": "Lecture-écriture",
"neocomputers.noaddr": "Pas d'adresse attribué",
"neocomputers.computer.on": "ALLUMÉ",
"neocomputers.computer.off": "ÉTEINT",
"neocomputers.computer.errorNoMsg": "Erreur: ",
"neocomputers.computer.energy": "Énergie: %1$s / %2$s J",
"neocomputers.computer.memory": "Mémoire: %1$s / %2$s",
"neocomputers.computer.components": "Composants: %1$s / %2$s",
"neocomputers.memory.capacity": "Capacité: %1$s",
"neocomputers.arch": "Architecture: %1$s",
"neocomputers.eeprom.codeused": "Code stocké: %1$s / %2$s",
"neocomputers.eeprom.dataused": "Données stockées: %1$s / %2$s",
"neocomputers.tunnel.channel": "Chaîne connectée: %1$s",
"sounds.neocomputers.computer_running": "Ventilateurs d'ordinateur"
}

View File

@@ -0,0 +1,67 @@
{
"neocomputers.confirm": "Bevestigen",
"neocomputers.cancel": "Annuleren",
"block.neocomputers.combustgen": "Verbrandingsgenerator",
"block.neocomputers.redio": "Redstone I/O",
"item.neocomputers.redio0": "Redstonekaart (niveau 1)",
"item.neocomputers.redio1": "Redstonekaart (niveau 2)",
"block.neocomputers.solargen": "Zonnegenerator",
"block.neocomputers.screen": "Scherm (niveauloos)",
"block.neocomputers.capacitor": "Kleine condensator",
"block.neocomputers.capacitor2": "Middelgrote condensator",
"block.neocomputers.capacitor3": "Grote condensator",
"block.neocomputers.case": "Behuizing (niveauloos)",
"block.neocomputers.cable": "Kabel",
"block.neocomputers.relay": "Doorgever",
"item.neocomputers.eeprom0": "EEPROM (niveau 1)",
"item.neocomputers.cpu0": "Processor (niveau 1)",
"item.neocomputers.cpu1": "Processor (niveau 2)",
"item.neocomputers.cpu2": "Processor (niveau 3)",
"item.neocomputers.cbus0": "Componentenbus (niveau 1)",
"item.neocomputers.cbus1": "Componentenbus (niveau 2)",
"item.neocomputers.cbus2": "Componentenbus (niveau 3)",
"item.neocomputers.cbus_creative": "Componentenbus (creatief)",
"item.neocomputers.memory0": "Geheugen (niveau 1)",
"item.neocomputers.memory1": "Geheugen (niveau 1,5)",
"item.neocomputers.memory2": "Geheugen (niveau 2)",
"item.neocomputers.memory3": "Geheugen (niveau 2,5)",
"item.neocomputers.memory4": "Geheugen (niveau 3)",
"item.neocomputers.memory5": "Geheugen (niveau 3,5)",
"item.neocomputers.inet": "Internetkaart",
"item.neocomputers.lan": "Bedrade netwerkkaart",
"item.neocomputers.wlan0": "Draadloze netwerkkaart (niveau 1)",
"item.neocomputers.wlan1": "Draadloze netwerkkaart (niveau 2)",
"item.neocomputers.tunnel": "Gekoppelde kaart",
"item.neocomputers.data0": "Datakaart (niveau 1)",
"item.neocomputers.data1": "Datakaart (niveau 2)",
"item.neocomputers.data2": "Datakaart (niveau 3)",
"item.neocomputers.gpu0": "Videokaart (niveau 1)",
"item.neocomputers.gpu1": "Videokaart (niveau 2)",
"item.neocomputers.gpu2": "Videokaart (niveau 3)",
"item.neocomputers.hdd0": "Harde schijf (niveau 1)",
"item.neocomputers.hdd1": "Harde schijf (niveau 2)",
"item.neocomputers.hdd2": "Harde schijf (niveau 3)",
"neocomputers.errors.ENOCPU": "geen processor",
"neocomputers.errors.E2BIG": "te veel componenten",
"neocomputers.errors.ENOENJ": "gevaarlijk weinig stroom",
"neocomputers.errors.ENOMEM": "geen geheugen",
"neocomputers.wlan.range": "Bereik: %1$s blokken",
"neocomputers.data.limit": "Geheugen: %1$s",
"neocomputers.gpu.vram": "Videogeheugen: %1$spx",
"neocomputers.disk.spaceused": "Gebruikte ruimte: %1$s / %2$s",
"neocomputers.readonly": "Alleen-lezen",
"neocomputers.readwrite": "Lezen-schrijven",
"neocomputers.noaddr": "Geen adres toegewezen",
"neocomputers.computer.on": "AAN",
"neocomputers.computer.off": "UIT",
"neocomputers.computer.errorNoMsg": "Fout: ",
"neocomputers.computer.energy": "Stroom: %1$s / %2$s J",
"neocomputers.computer.memory": "Geheugen: %1$s / %2$s",
"neocomputers.computer.components": "Componenten: %1$s / %2$s",
"neocomputers.memory.capacity": "Capaciteit: %1$s",
"neocomputers.arch": "Architectuur: %1$s",
"neocomputers.eeprom.codeused": "Opgeslagen code: %1$s / %2$s",
"neocomputers.eeprom.dataused": "Opgeslagen data: %1$s / %2$s",
"neocomputers.tunnel.channel": "Gekoppeld kanaal: %1$s",
"sounds.neocomputers.computer_running": "Computerventilatoren"
}

View File

@@ -0,0 +1,44 @@
{
"parent": "block/block",
"textures": {
"bottom": "neocomputers:block/generic_top",
"top": "neocomputers:block/assembler_top",
"side": "neocomputers:block/assembler_side",
"particle": "neocomputers:block/generic_top"
},
"elements": [
{ "from": [ 0, 0, 0 ],
"to": [ 16, 7, 16 ],
"faces": {
"up": { "uv": [ 0, 0, 16, 16 ], "texture": "#top" },
"down": { "uv": [ 0, 0, 16, 16 ], "texture": "#bottom" },
"north": { "uv": [ 0, 0, 16, 7 ], "texture": "#side" },
"south": { "uv": [ 0, 0, 16, 7 ], "texture": "#side" },
"west": { "uv": [ 0, 0, 16, 7 ], "texture": "#side" },
"east": { "uv": [ 0, 0, 16, 7 ], "texture": "#side" }
}
},
{ "from": [ 2, 7, 2 ],
"to": [ 14, 9, 14 ],
"faces": {
"up": { "uv": [ 2, 2, 14, 14 ], "texture": "#top" },
"down": { "uv": [ 2, 2, 14, 14 ], "texture": "#bottom" },
"north": { "uv": [ 2, 7, 14, 9 ], "texture": "#side" },
"south": { "uv": [ 2, 7, 14, 9 ], "texture": "#side" },
"west": { "uv": [ 2, 7, 14, 9 ], "texture": "#side" },
"east": { "uv": [ 2, 7, 14, 9 ], "texture": "#side" }
}
},
{ "from": [ 0, 9, 0 ],
"to": [ 16, 16, 16 ],
"faces": {
"up": { "uv": [ 0, 0, 16, 16 ], "texture": "#top" },
"down": { "uv": [ 0, 0, 16, 16 ], "texture": "#bottom" },
"north": { "uv": [ 0, 9, 16, 16 ], "texture": "#side" },
"south": { "uv": [ 0, 9, 16, 16 ], "texture": "#side" },
"west": { "uv": [ 0, 9, 16, 16 ], "texture": "#side" },
"east": { "uv": [ 0, 9, 16, 16 ], "texture": "#side" }
}
}
]
}

View File

@@ -0,0 +1,3 @@
{
"parent": "neocomputers:block/rack"
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "neocomputers:item/server0"
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "neocomputers:item/server1"
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "neocomputers:item/server2"
}
}

View File

@@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "neocomputers:item/server_creative"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 153 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 KiB

After

Width:  |  Height:  |  Size: 242 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

View File

@@ -5,7 +5,7 @@ plugins {
id("com.gradleup.shadow") version "9.3.0" apply false
id("me.modmuss50.mod-publish-plugin") version "0.8.4" apply false
}
stonecutter active "1.21.1-fabric" /* [SC] DO NOT EDIT */
stonecutter active "1.21.1-neoforge" /* [SC] DO NOT EDIT */
stonecutter.automaticPlatformConstants = true
// Builds every version into `build/libs/{mod.version}/{loader}`