Compare commits

...

20 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
cdb98bd85e all rack rendering (afaik) and basic right click logic stuff and refactors nobody asked for 2026-05-05 21:39:40 +02:00
7f58fdf55b server hit stuff 2026-05-03 19:06:37 +02:00
17bc614eb9 textures 2026-05-03 18:24:07 +02:00
b78cc44d89 Merge branch 'main' of https://gitea.codersquack.nl/NeoFlock/NeoComputers 2026-05-03 17:21:34 +02:00
4d37483057 render a singular server 2026-05-03 17:21:24 +02:00
4d84ec2ed4 todo stuff 2026-05-03 16:04:38 +03:00
5249832bd6 work on optimized networking 2026-05-02 23:28:02 +03:00
72 changed files with 1384 additions and 198 deletions

27
TODO.md
View File

@@ -1,29 +1,16 @@
# Networking # Networking
> All that is left is optimization > All that is left is optimization
## ERADICATE DIRECT ## Mergeable device nodes
We only need NONE, SOME and NETWORK. For optimization of screen grouping and cables, we should add a system that allows merging nodes
## Optimize compute and memory ## Copy the networking optimizations of OC
> OC does this too > https://github.com/MightyPirates/OpenComputers/blob/master-MC1.7.10/src/main/scala/li/cil/oc/server/network/Network.scala
Optimize both *time* and *memory* using graph theory. We should implement this, as it not only makes behavior match better, but also optimizes
it a lot. We do need to replace the NEIGHBORS rule with implementing the SOME visibility.
### Requirements A direct port is not needed, just taking heavy inspiration from OC.
It obviously must be fast and memory-efficient, and respect the current semantics.
The current idea is to make NETWORK style nodes the only ones with a cache,
and to instead appoint a connection that is also a NETWORK node, if any, as
the one source of truth, or steal the source. This means only one node
in a local network gets to actually compute the graph layout.
Complications can happen when merges happen, the idea is to pick one source of truth
then as well.
Also, `onNodeAdded` and `onNodeRemoved` should also be called when a reachable node is added/removed.
This is for perf. We only care about nodes being added/removed then.
This can be done by broadcasting to all of their *connections*, to circumvent the NONE/SOME/NETWORK asymmetric reachability sets.
## Optimize power balancing ## Optimize power balancing

View File

@@ -26,9 +26,16 @@ base {
archivesName.set("${mod.id}-$loader") 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 { architectury.common(stonecutter.tree.branches.mapNotNull {
if (stonecutter.current.project !in it) null // println(stonecutter.current.project !in it)
else it.prop("loom.platform") if (stonecutter.current.project !in it) return null
else return it.prop("loom.platform")
}) })
repositories { repositories {
@@ -118,8 +125,8 @@ dependencies {
// } // }
// }) // })
if (minecraft=="1.21.9" || minecraft=="1.21.11") modApi("dev.architectury:architectury-neoforge:${archversion}") if (minecraft=="1.21.1" || 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 else modApi("dev.architectury:architectury-neoforge:${archversion}") // NOTE: this could be wrong
implementation("thedarkcolour:kotlinforforge-neoforge:6.0.0") implementation("thedarkcolour:kotlinforforge-neoforge:6.0.0")
} }

View File

@@ -27,7 +27,7 @@ stonecutter {
mc("forge", "1.20.1") mc("forge", "1.20.1")
//WARNING: neoforge uses mods.toml instead of neoforge.mods.toml for versions 1.20.4 (?) and earlier //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.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) create(rootProject)
} }

View File

@@ -1,5 +1,5 @@
//? if fabric { //? 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.ConfigScreenFactory;
import com.terraformersmc.modmenu.api.ModMenuApi; import com.terraformersmc.modmenu.api.ModMenuApi;
@@ -10,4 +10,4 @@ public class ModMenuIntegration implements ModMenuApi {
return ConfigScreen::createConfigScreen; return ConfigScreen::createConfigScreen;
} }
} }
//?} *///?}

View File

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

View File

@@ -13,10 +13,7 @@ import org.neoflock.neocomputers.NeoComputers;
import org.neoflock.neocomputers.block.Blocks; import org.neoflock.neocomputers.block.Blocks;
import org.neoflock.neocomputers.block.CableBlock; import org.neoflock.neocomputers.block.CableBlock;
import org.neoflock.neocomputers.entity.BlockEntities; import org.neoflock.neocomputers.entity.BlockEntities;
import org.neoflock.neocomputers.entity.render.CaseEntityRenderer; import org.neoflock.neocomputers.entity.render.*;
import org.neoflock.neocomputers.entity.render.RelayEntityRenderer;
import org.neoflock.neocomputers.entity.render.RobotEntityRenderer;
import org.neoflock.neocomputers.entity.render.ScreenEntityRenderer;
import org.neoflock.neocomputers.item.Items; import org.neoflock.neocomputers.item.Items;
import org.neoflock.neocomputers.platforms.fabric.client.model.ModelLoader; import org.neoflock.neocomputers.platforms.fabric.client.model.ModelLoader;
@@ -24,10 +21,6 @@ public class NeoComputersFabricClient implements ClientModInitializer {
@Override @Override
public void onInitializeClient() { public void onInitializeClient() {
ModelLoadingPlugin.register(new ModelLoader()); ModelLoadingPlugin.register(new ModelLoader());
BlockEntityRenderers.register(BlockEntities.INSTANCE.getSCREEN_ENTITY().get(), ScreenEntityRenderer::new);
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);
ColorProviderRegistry.BLOCK.register((state, world, pos, index) -> { ColorProviderRegistry.BLOCK.register((state, world, pos, index) -> {
if (index == 0) { if (index == 0) {

View File

@@ -1,5 +1,5 @@
//? if neoforge { //? if neoforge {
/*package org.neoflock.neocomputers.platforms.neoforge; package org.neoflock.neocomputers.platforms.neoforge;
import org.neoflock.neocomputers.ConfigScreen; import org.neoflock.neocomputers.ConfigScreen;
import org.neoflock.neocomputers.ModPlatform; import org.neoflock.neocomputers.ModPlatform;
@@ -8,8 +8,8 @@ import net.neoforged.fml.ModLoadingContext;
import net.neoforged.fml.common.Mod; import net.neoforged.fml.common.Mod;
import org.neoflock.neocomputers.NeoComputers; import org.neoflock.neocomputers.NeoComputers;
//? if <1.21 { //? if <1.21 {
/^import net.neoforged.neoforge.client.ConfigScreenHandler; /*import net.neoforged.neoforge.client.ConfigScreenHandler;
^///?} else { *///?} else {
import net.neoforged.neoforge.client.gui.IConfigScreenFactory; import net.neoforged.neoforge.client.gui.IConfigScreenFactory;
//?} //?}
@Mod("neocomputers") @Mod("neocomputers")
@@ -18,11 +18,11 @@ public class NeoComputersNeoForge {
NeoComputers.INSTANCE.entrypoint(new NeoForgePlatform()); NeoComputers.INSTANCE.entrypoint(new NeoForgePlatform());
ModLoadingContext.get().registerExtensionPoint( ModLoadingContext.get().registerExtensionPoint(
//? if <1.21 { //? if <1.21 {
/^ConfigScreenHandler.ConfigScreenFactory.class, /*ConfigScreenHandler.ConfigScreenFactory.class,
() -> new ConfigScreenHandler.ConfigScreenFactory( () -> new ConfigScreenHandler.ConfigScreenFactory(
((client, parent) -> ConfigScreen.createConfigScreen(parent)) ((client, parent) -> ConfigScreen.createConfigScreen(parent))
) )
^///?} else { *///?} else {
IConfigScreenFactory.class, IConfigScreenFactory.class,
() -> (client, parent) -> ConfigScreen.createConfigScreen(parent) () -> (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.Env
import dev.architectury.utils.EnvExecutor import dev.architectury.utils.EnvExecutor
import net.minecraft.client.Minecraft import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.blockentity.BlockEntityRenderers
import net.minecraft.server.level.ServerPlayer import net.minecraft.server.level.ServerPlayer
import org.neoflock.neocomputers.block.DeviceBlockEntity 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.render.ScreenRenderer
import org.neoflock.neocomputers.gui.widget.ComponentRoles import org.neoflock.neocomputers.gui.widget.ComponentRoles
import org.neoflock.neocomputers.item.Items import org.neoflock.neocomputers.item.Items
@@ -56,6 +58,10 @@ object NeoComputers {
EnvExecutor.runInEnv(Env.CLIENT) {{ EnvExecutor.runInEnv(Env.CLIENT) {{
ClientLifecycleEvent.CLIENT_SETUP.register { ClientLifecycleEvent.CLIENT_SETUP.register {
Menus.registerScreens() Menus.registerScreens()
Networking.allNodes.remove()
Networking.wirelessNodes.remove()
Networking.channels.remove()
EntityRenderers.registerBlockEntityRenderers()
} }
ClientLifecycleEvent.CLIENT_STARTED.register { ClientLifecycleEvent.CLIENT_STARTED.register {
FontProvider.load(ResourceLocation.fromNamespaceAndPath(MODID, "font/unscii.hex")) FontProvider.load(ResourceLocation.fromNamespaceAndPath(MODID, "font/unscii.hex"))
@@ -81,12 +87,6 @@ object NeoComputers {
Networking.channels.remove() Networking.channels.remove()
} }
ClientLifecycleEvent.CLIENT_SETUP.register {
Networking.allNodes.remove()
Networking.wirelessNodes.remove()
Networking.channels.remove()
}
PlayerEvent.CLOSE_MENU.register { PlayerEvent.CLOSE_MENU.register {
player, menu -> player, menu ->
if(player is ServerPlayer) NodeSynchronizer.playerScreenClosed(player) 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.Registrar
import dev.architectury.registry.registries.RegistrarManager import dev.architectury.registry.registries.RegistrarManager
import dev.architectury.registry.registries.RegistrySupplier import dev.architectury.registry.registries.RegistrySupplier
import net.minecraft.client.renderer.RenderType
import net.minecraft.core.registries.Registries import net.minecraft.core.registries.Registries
import net.minecraft.resources.ResourceLocation import net.minecraft.resources.ResourceLocation
import net.minecraft.resources.ResourceKey import net.minecraft.resources.ResourceKey
@@ -36,6 +37,8 @@ object Blocks {
val CABLE_BLOCK: RegistrySupplier<Block> = BaseBlock.register("cable") { CableBlock() } val CABLE_BLOCK: RegistrySupplier<Block> = BaseBlock.register("cable") { CableBlock() }
val RELAY_BLOCK: RegistrySupplier<Block> = BaseBlock.register("relay") { RelayBlock() } val RELAY_BLOCK: RegistrySupplier<Block> = BaseBlock.register("relay") { RelayBlock() }
val ROBOT_BLOCK: RegistrySupplier<Block> = BaseBlock.register("robot") { RobotBlock() } 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() { fun registerBlockItems() {
BLOCKS.forEach(Consumer { sup: RegistrySupplier<Block> -> BLOCKS.forEach(Consumer { sup: RegistrySupplier<Block> ->

View File

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

View File

@@ -0,0 +1,69 @@
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
import net.minecraft.world.level.block.EntityBlock
import net.minecraft.world.level.block.RenderShape
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.phys.BlockHitResult
import net.minecraft.world.phys.shapes.CollisionContext
import net.minecraft.world.phys.shapes.Shapes
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 : DeviceBlock(Properties.of().noOcclusion()), EntityBlock {
override fun newBlockEntity(
pos: BlockPos,
state: BlockState
): BlockEntity? {
return RackEntity(pos, state)
}
// override fun getShape(
// state: BlockState,
// level: BlockGetter,
// pos: BlockPos,
// context: CollisionContext
// ): VoxelShape? {
// return Shapes.box(0.0,0.0,0.0,0.01,0.01,0.01)
// }
// override fun getRenderShape(state: BlockState): RenderShape? {
// return RenderShape
// }
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) {
var rack = 0
rack += if(res.y < pos.y+5/16f) 1 else 0
rack += if(res.y < pos.y+8/16f) 1 else 0
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
}
}
if (!level.isClientSide) {
MenuRegistry.openExtendedMenu(player as ServerPlayer, ent)
NodeSynchronizer.registerPlayerScreen(player as ServerPlayer, ent.node)
}
return InteractionResult.SUCCESS
}
}

View File

@@ -17,7 +17,6 @@ import org.neoflock.neocomputers.entity.RobotEntity
class RobotBlock : BaseBlock(Properties.of().noOcclusion()), EntityBlock { // todo: node stuff class RobotBlock : BaseBlock(Properties.of().noOcclusion()), EntityBlock { // todo: node stuff
override fun newBlockEntity(pos: BlockPos, state: BlockState): BlockEntity { override fun newBlockEntity(pos: BlockPos, state: BlockState): BlockEntity {
NeoComputers.LOGGER.info("block entity created..") NeoComputers.LOGGER.info("block entity created..")
Blocks.CHEST
return RobotEntity(pos, state) return RobotEntity(pos, state)
} }

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.fabricmc.fabric.api.datagen.v1.provider.FabricModelProvider
import net.minecraft.data.models.BlockModelGenerators import net.minecraft.data.models.BlockModelGenerators
import net.minecraft.data.models.ItemModelGenerators 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.block.Blocks
import org.neoflock.neocomputers.item.Items
class ModelGenerator(output: FabricDataOutput) : FabricModelProvider(output) { class ModelGenerator(output: FabricDataOutput) : FabricModelProvider(output) {
override fun generateBlockStateModels(blockStateModelGenerator: BlockModelGenerators) { override fun generateBlockStateModels(blockStateModelGenerator: BlockModelGenerators) {
blockStateModelGenerator.createGenericCube(Blocks.CASE_BLOCK.get()) // blockStateModelGenerator.createGenericCube(Blocks.CASE_BLOCK.get())
} }
override fun generateItemModels(itemModelGenerator: ItemModelGenerators) { 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

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

View File

@@ -0,0 +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()
}
override fun getDisplayName(): Component? = Component.literal("Rack")
override fun createMenu(i: Int, inventory: Inventory, player: Player): AbstractContainerMenu {
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.client.model.geom.ModelPart
import net.minecraft.core.BlockPos 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.BlockEntity
import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity
import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.block.state.BlockState
import org.neoflock.neocomputers.NeoComputers 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 body: ModelPart? = null
val name = "Diddyx" //TODO: names val name = "Diddyx" //TODO: names
override fun getName(): Component? = Component.literal(name)
init { init {
NeoComputers.LOGGER.info("yooo") 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.VertexConsumer
import com.mojang.blaze3d.vertex.VertexFormat import com.mojang.blaze3d.vertex.VertexFormat
import com.mojang.math.Axis import com.mojang.math.Axis
import net.minecraft.client.renderer.LightTexture
import net.minecraft.client.renderer.MultiBufferSource import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.RenderStateShard import net.minecraft.client.renderer.RenderStateShard
import net.minecraft.client.renderer.RenderType import net.minecraft.client.renderer.RenderType
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
import net.minecraft.core.Direction import net.minecraft.core.Direction
import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.block.CaseBlock import org.neoflock.neocomputers.block.CaseBlock
import org.neoflock.neocomputers.entity.CaseBlockEntity import org.neoflock.neocomputers.entity.CaseBlockEntity
@@ -23,9 +25,10 @@ class CaseEntityRenderer(private val context: BlockEntityRendererProvider.Contex
val BLINKTIME: Long = 10 // in ticks 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() RenderType.TRANSIENT_BUFFER_SIZE, RenderType.CompositeState.builder()
.setShaderState(RenderStateShard.POSITION_COLOR_SHADER) .setShaderState(RenderStateShard.POSITION_COLOR_LIGHTMAP_SHADER)
.setLightmapState(RenderStateShard.LightmapStateShard.LIGHTMAP)
.createCompositeState(false)) .createCompositeState(false))
override fun render(ent: CaseBlockEntity, partialTick: Float, mat: PoseStack, bufferSource: MultiBufferSource, packedLight: Int, packedOverlay: Int) { 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) if (ent.isOn) drawLED(buffer, mat.last(), 3F)
else if (ent.getLastError() != null) { // if else hell else if (ent.getLastError() != null) { // if else hell
if ((ent.level!!.dayTime/BLINKTIME) % 2 == 1.toLong()) drawLED(buffer, mat.last(), 3F, RED) 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, packedLight)
} else drawLED(buffer, mat.last(), 3F, OFF) } else drawLED(buffer, mat.last(), 3F, OFF, packedLight)
mat.translate(6/16F, 0F, 0F) 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() mat.popPose()
} }
private fun drawLED(buffer: VertexConsumer, mat: PoseStack.Pose, width: Float, color: Int = GREEN) { 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) buffer.addVertex(mat, width/16F, 0F, 0F).setColor(color).setLight(light)
buffer.addVertex(mat, width/16F, 1/16F, 0F).setColor(color) buffer.addVertex(mat, width/16F, 1/16F, 0F).setColor(color).setLight(light)
buffer.addVertex(mat, 0F, 1/16F, 0F).setColor(color) buffer.addVertex(mat, 0F, 1/16F, 0F).setColor(color).setLight(light)
buffer.addVertex(mat, 0F, 0F, 0F).setColor(color) buffer.addVertex(mat, 0F, 0F, 0F).setColor(color).setLight(light)
} }
private fun handleDirection(facing: Direction, mat: PoseStack) { 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

@@ -0,0 +1,39 @@
package org.neoflock.neocomputers.entity.render
import com.mojang.authlib.minecraft.client.MinecraftClient
import com.mojang.blaze3d.vertex.PoseStack
import net.minecraft.client.Minecraft
import net.minecraft.client.renderer.LevelRenderer
import net.minecraft.client.renderer.LightTexture
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.block.ModelBlockRenderer
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
import net.minecraft.world.level.LightLayer
import net.minecraft.world.level.dimension.DimensionType
import net.minecraft.world.level.lighting.BlockLightEngine
import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.entity.RackEntity
import org.neoflock.neocomputers.item.RackItem
class RackEntityRenderer(val context: BlockEntityRendererProvider.Context) : BlockEntityRenderer<RackEntity> {
override fun render(ent: RackEntity, partialTick: Float, poseStack: PoseStack, source: MultiBufferSource, packedLight: Int, packedOverlay: Int) {
poseStack.pushPose()
poseStack.translate(1/16f, 11/16f, 1/16f)
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

@@ -13,6 +13,7 @@ import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider
import net.minecraft.resources.ResourceLocation import net.minecraft.resources.ResourceLocation
import org.neoflock.neocomputers.NeoComputers import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.block.RelayEntity import org.neoflock.neocomputers.block.RelayEntity
import java.util.Timer
import kotlin.math.min import kotlin.math.min
class RelayEntityRenderer(val context: BlockEntityRendererProvider.Context?): BlockEntityRenderer<RelayEntity> { class RelayEntityRenderer(val context: BlockEntityRendererProvider.Context?): BlockEntityRenderer<RelayEntity> {

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.block.model.BakedQuad
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer import net.minecraft.client.renderer.blockentity.BlockEntityRenderer
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider 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.entity.LivingEntityRenderer
import net.minecraft.client.renderer.texture.OverlayTexture import net.minecraft.client.renderer.texture.OverlayTexture
import net.minecraft.client.renderer.texture.TextureAtlas 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.resources.ResourceLocation
import net.minecraft.util.RandomSource import net.minecraft.util.RandomSource
import net.minecraft.world.item.DyeColor import net.minecraft.world.item.DyeColor
import net.minecraft.world.level.block.entity.ChestBlockEntity
import net.minecraft.world.phys.Vec3 import net.minecraft.world.phys.Vec3
import org.neoflock.neocomputers.NeoComputers import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.block.model.RobotModel import org.neoflock.neocomputers.block.model.RobotModel
@@ -51,6 +54,7 @@ class RobotEntityRenderer(val context: BlockEntityRendererProvider.Context) : Bl
CompositeState.builder() CompositeState.builder()
.setShaderState(RenderStateShard.ShaderStateShard { GameRenderer.getPositionTexColorShader() }) .setShaderState(RenderStateShard.ShaderStateShard { GameRenderer.getPositionTexColorShader() })
.setTransparencyState(RenderStateShard.ADDITIVE_TRANSPARENCY) .setTransparencyState(RenderStateShard.ADDITIVE_TRANSPARENCY)
.setCullState(RenderStateShard.CullStateShard.NO_CULL)
.setTextureState(RenderStateShard.TextureStateShard(ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/block/robot.png"), false, false)) .setTextureState(RenderStateShard.TextureStateShard(ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/block/robot.png"), false, false))
.createCompositeState(false)) .createCompositeState(false))
@@ -70,9 +74,10 @@ class RobotEntityRenderer(val context: BlockEntityRendererProvider.Context) : Bl
// TODO: crafting table and chest little models // TODO: crafting table and chest little models
// EntityRenderer
poseStack.popPose()
renderTag(ent, Component.literal(ent.name), poseStack, bufferSource, packedLight, partialTick) renderTag(ent, Component.literal(ent.name), poseStack, bufferSource, packedLight, partialTick)
poseStack.popPose()
} }
// offset is 0-15 // offset is 0-15
@@ -106,16 +111,18 @@ class RobotEntityRenderer(val context: BlockEntityRendererProvider.Context) : Bl
stack.pushPose() stack.pushPose()
stack.translate(vec.x, vec.y, vec.z) 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) stack.scale(0.025F, -0.025F, 0.025F)
val opacity = Minecraft.getInstance().options.getBackgroundOpacity(0.25F) val opacity = Minecraft.getInstance().options.getBackgroundOpacity(0.25F)
val alpha: Int = (opacity * 255.0f).toInt() shl 24 val alpha: Int = (opacity * 255.0f).toInt() shl 24
// val alpha = 255 // val alpha = 255
val halfwidth = (-context.font.width(name)) / 2; val halfwidth = (-context.font.width(name)) / 2;
RenderSystem.disableDepthTest() // RenderSystem.enableDepthTest()
context.font.drawInBatch(name, halfwidth.toFloat(), 2f, 0xFFFFFF, false, stack.last().pose(), source, Font.DisplayMode.SEE_THROUGH, alpha, light) // 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() 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,8 +10,10 @@ import net.minecraft.world.flag.FeatureFlags
import net.minecraft.world.inventory.MenuType import net.minecraft.world.inventory.MenuType
import org.neoflock.neocomputers.NeoComputers import org.neoflock.neocomputers.NeoComputers
import org.neoflock.neocomputers.gui.menu.ScreenMenu 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.CaseScreen
import org.neoflock.neocomputers.gui.screen.CombustionGeneratorScreen 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.RelayScreen
import org.neoflock.neocomputers.gui.screen.ScreenScreen import org.neoflock.neocomputers.gui.screen.ScreenScreen
@@ -22,11 +24,16 @@ object Menus {
val COMBUSTGEN_MENU: RegistrySupplier<MenuType<CombustionGeneratorMenu>> = MENUS.register("combustgen_menu") { MenuType(::CombustionGeneratorMenu, FeatureFlagSet.of() ) } val COMBUSTGEN_MENU: RegistrySupplier<MenuType<CombustionGeneratorMenu>> = MENUS.register("combustgen_menu") { MenuType(::CombustionGeneratorMenu, FeatureFlagSet.of() ) }
val CASE_MENU: RegistrySupplier<MenuType<CaseMenu>> = MENUS.register("case_menu") { MenuType(::CaseMenu, FeatureFlagSet.of() )} 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 RELAY_MENU: RegistrySupplier<MenuType<RelayMenu>> = MENUS.register("relay_menu") { MenuType(::RelayMenu, 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() { fun registerScreens() {
MenuScreens.register(Menus.COMBUSTGEN_MENU.get()) { m: CombustionGeneratorMenu, u, comp ->CombustionGeneratorScreen(m,u,comp)} MenuScreens.register(Menus.COMBUSTGEN_MENU.get()) { m: CombustionGeneratorMenu, u, comp ->CombustionGeneratorScreen(m,u,comp)}
MenuScreens.register(Menus.SCREEN_MENU.get(), ::ScreenScreen) MenuScreens.register(Menus.SCREEN_MENU.get(), ::ScreenScreen)
MenuScreens.register(Menus.CASE_MENU.get(), ::CaseScreen) MenuScreens.register(Menus.CASE_MENU.get(), ::CaseScreen)
MenuScreens.register(Menus.RELAY_MENU.get(), ::RelayScreen) MenuScreens.register(Menus.RELAY_MENU.get(), ::RelayScreen)
MenuScreens.register(Menus.RACK_MENU.get(), ::RackScreen)
MenuScreens.register(Menus.ASSEMBLER_MENU.get(), ::AssemblerScreen)
} }
} }

View File

@@ -0,0 +1,193 @@
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 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), 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; }
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()
}
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, mx: Int, my: Int, 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)
// 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
for (i in 0..<sec) {
// slot
drawColor(guiGraphics, buffer, 17, 6+(4*i), 0xffffffff.toInt())
drawColor(guiGraphics, buffer, 17, 7+(4*i), 0xff888888.toInt())
// cable
for (j in 0..4) {
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()
// x+_x+1 is one im not proud of
buffer.addVertex(pose, x+_x+width.toFloat(), y+_y+height.toFloat(), 2f).setColor(col)
buffer.addVertex(pose, x+_x+width.toFloat(), y+_y.toFloat(), 2f).setColor(col)
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, 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) {
val slot = RackSlot(container, i, 20, 23+i*20)
this.addSlot(slot)
}
this.addInventorySlots(inv, 8, 128)
}
}

View File

@@ -55,14 +55,10 @@ class RelaySlot(container: Container, slot: Int, x: Int, y: Int, val role: Strin
override fun getMaxStackSize() = 1 override fun getMaxStackSize() = 1
override fun getMaxStackSize(stack: ItemStack) = 1 override fun getMaxStackSize(stack: ItemStack) = 1
override fun draw(graphics: GuiGraphics, relX: Int, relY: Int, mouseX: Int, mouseY: Int) { override fun draw(graphics: GuiGraphics, mouseX: Int, mouseY: Int) {
super.draw(graphics, relX, relY, mouseX, mouseY) super.draw(graphics, mouseX, mouseY)
if(!hasItem()) { if(!hasItem()) {
RenderSystem.enableBlend() drawQuad(graphics, ComponentRoles.getTextureFor(role), x-1, y-1, 18, 18, 0f, 0f, 15f, 15f)
RenderSystem.setShaderTexture(0, ComponentRoles.getTextureFor(role))
RenderSystem.setShader { GameRenderer.getPositionTexShader() }
drawQuad(relX + x - 1, relY + y - 1, 18, 18, 0F, 0F, 15F, 15F)
RenderSystem.disableBlend()
} }
} }
} }

View File

@@ -13,7 +13,7 @@ import java.io.File
import kotlin.experimental.and import kotlin.experimental.and
import kotlin.experimental.xor 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 CHARW = 8
val CHARH = 16 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

@@ -26,6 +26,7 @@ class CaseScreen : GenericContainerScreen<CaseMenu> {
private var btn: ImagerButton? = null private var btn: ImagerButton? = null
override fun shouldCenterTitle(): Boolean = false override fun shouldCenterTitle(): Boolean = false
// override fun findMenuTexture(): ResourceLocation = BG
var isOn = false var isOn = false
var lastError: String? = null var lastError: String? = null
@@ -77,7 +78,7 @@ class CaseScreen : GenericContainerScreen<CaseMenu> {
constructor(abstractContainerMenu: CaseMenu, inventory: Inventory, component: Component) : super(abstractContainerMenu, inventory, component) { constructor(abstractContainerMenu: CaseMenu, inventory: Inventory, component: Component) : super(abstractContainerMenu, inventory, component) {
btn = ImagerButton( btn = ImagerButton(
15, 15, 71, 33,
18, 18, 18, 18,
ButtonSprites(BTN, 18, 18, 36, 36) ButtonSprites(BTN, 18, 18, 36, 36)
) { ) {
@@ -85,17 +86,11 @@ class CaseScreen : GenericContainerScreen<CaseMenu> {
buf.writeByte(if(isOn) 0x02 else 0x01) buf.writeByte(if(isOn) 0x02 else 0x01)
NodeSynchronizer.sendScreenInteraction(buf) 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 addWidget(btn!!)
btn!!.y = relY+33 }
btn!!.render(guiGraphics, i, j, f) // minecraft SUCKSSS override fun renderbg(guiGraphics: GuiGraphics, f: Float, i: Int, j: Int) {
guiGraphics.blit(PCB, relX, relY, 0, 0, this.imageWidth, this.imageHeight) 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) { override fun renderCustomOverlay(graphics: GuiGraphics, mouseX: Int, mouseY: Int, blend: Float) {
@@ -105,13 +100,4 @@ class CaseScreen : GenericContainerScreen<CaseMenu> {
} }
} }
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)
}
} }

View File

@@ -0,0 +1,106 @@
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
class RackScreen(menu: RackMenu, inventory: Inventory, component: Component) : GenericContainerScreen<RackMenu>(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 = if (menu.container is RackEntity) (menu.container as RackEntity).relayMode else false
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
} else {
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
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)
}
// 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

@@ -46,6 +46,8 @@ class ScreenScreen : GenericContainerScreen<ScreenMenu>{
} }
} }
override fun renderLabels(guiGraphics: GuiGraphics, mouseX: Int, mouseY: Int) { }
// override fun onClose() { // override fun onClose() {
// super.onClose() // super.onClose()
// renderer. // renderer.

View File

@@ -83,14 +83,11 @@ data class ComponentSlotRequirement(val tier: Int, val role: String) {
// Tier 0 allows ALL tiers, making it completely untiered. // Tier 0 allows ALL tiers, making it completely untiered.
// Role determines what the role is. // 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, relX: Int, relY: Int, mouseX: Int, mouseY: Int) { override fun draw(graphics: GuiGraphics, mouseX: Int, mouseY: Int) {
super.draw(graphics, relX, relY, mouseX, mouseY) super.draw(graphics, mouseX, mouseY)
if(!hasItem()) { if(!hasItem()) {
RenderSystem.enableBlend() drawQuad(graphics, ComponentRoles.getTextureFor(requirement.role), x - 1, y - 1, 18, 18, 0F, 0F, 15F, 15F)
RenderSystem.setShaderTexture(0, ComponentRoles.getTextureFor(requirement.role))
RenderSystem.setShader { GameRenderer.getPositionTexShader() }
drawQuad(relX + x - 1, relY + y - 1, 18, 18, 0F, 0F, 15F, 15F)
if (requirement.tier > 0) { if (requirement.tier > 0) {
RenderSystem.setShaderTexture( RenderSystem.setShaderTexture(
0, 0,
@@ -99,10 +96,11 @@ class ComponentSlot(container: Container, slot: Int, x: Int, y: Int, val machine
"textures/gui/slots/tier${requirement.tier - 1}.png" "textures/gui/slots/tier${requirement.tier - 1}.png"
) )
) )
RenderSystem.setShader { GameRenderer.getPositionTexShader() } val tex = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/gui/slots/tier${requirement.tier - 1}.png")
drawQuad(relX + x - 1, relY + y - 1, 18, 18, 0F, 0F, 15F, 15F) // RenderSystem.setShader { GameRenderer.getPositionTexShader() }
drawQuad(graphics, tex, x - 1, y - 1, 18, 18, 0F, 0F, 15F, 15F)
} }
RenderSystem.disableBlend() // RenderSystem.disableBlend()
} }
} }

View File

@@ -5,41 +5,43 @@ import com.mojang.blaze3d.vertex.BufferBuilder
import com.mojang.blaze3d.vertex.BufferUploader import com.mojang.blaze3d.vertex.BufferUploader
import com.mojang.blaze3d.vertex.DefaultVertexFormat import com.mojang.blaze3d.vertex.DefaultVertexFormat
import com.mojang.blaze3d.vertex.Tesselator import com.mojang.blaze3d.vertex.Tesselator
import com.mojang.blaze3d.vertex.VertexConsumer
import com.mojang.blaze3d.vertex.VertexFormat import com.mojang.blaze3d.vertex.VertexFormat
import net.minecraft.client.gui.GuiGraphics import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.renderer.GameRenderer 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.client.renderer.RenderType
import net.minecraft.resources.ResourceLocation import net.minecraft.resources.ResourceLocation
import net.minecraft.world.Container import net.minecraft.world.Container
import net.minecraft.world.inventory.Slot import net.minecraft.world.inventory.Slot
import org.neoflock.neocomputers.NeoComputers 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 BACKGROUND: ResourceLocation = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/gui/slots/slot.png")
val RENDER_TYPE = { r: ResourceLocation ->
open fun draw(graphics: GuiGraphics, relX: Int, relY: Int, mouseX: Int, mouseY: Int) { RenderType.create("nc_gui_slot", DefaultVertexFormat.POSITION_TEX, VertexFormat.Mode.QUADS, RenderType.TRANSIENT_BUFFER_SIZE, RenderType.CompositeState.builder()
RenderSystem.enableBlend() // background .setShaderState(ShaderStateShard.POSITION_TEX_SHADER)
RenderSystem.setShaderTexture(0, BACKGROUND) .setTextureState(RenderStateShard.TextureStateShard(r, false, false))
RenderSystem.setShader { GameRenderer.getPositionTexShader() } .setTransparencyState(RenderStateShard.TransparencyStateShard.TRANSLUCENT_TRANSPARENCY)
drawQuad(relX+x-1, relY+y-1, 18, 18, 0F, 0F, 15F, 15F) .createCompositeState(false))
RenderSystem.disableBlend()
} }
fun drawQuad(x: Int, y: Int, width: Int, height: Int, u1: Float, v1: Float, u2: Float, v2: Float) { open fun draw(graphics: GuiGraphics, mouseX: Int, mouseY: Int) {
var t: Tesselator = Tesselator.getInstance() drawQuad(graphics, BACKGROUND, x-1, y-1, 18, 18, 0F, 0F, 15F, 15F)
var builder: BufferBuilder = t.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX)
builder.addVertex(x.toFloat(), (y+height).toFloat(), 1f).setUv(u1/15F, v2/15F)
builder.addVertex((x+width).toFloat(), (y+height).toFloat(), 1f).setUv(u2/15F, v2/15F)
builder.addVertex((x+width).toFloat(), y.toFloat(), 1f).setUv(u2/15F, v1/15F)
builder.addVertex(x.toFloat(), y.toFloat(), 1f).setUv(u1/15F,v1/15F)
BufferUploader.drawWithShader(builder.build()!!)
} }
// private fun renderSlotHighlight(guiGraphics: GuiGraphics, x: Int, y: Int, k: Int) { // im not sure but i tihnk i copied this from mc source code fun drawQuad(guiGraphics: GuiGraphics, tex: ResourceLocation, x: Int, y: Int, width: Int, height: Int, u1: Float, v1: Float, u2: Float, v2: Float) {
// guiGraphics.fillGradient(RenderType.guiOverlay(), x, y, x + 16, y + 16, -2130706433, -2130706433, k); 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)
}
override fun isActive() = active
} }

View File

@@ -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?>): 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)
}
}

View File

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

View File

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

View File

@@ -0,0 +1,62 @@
package org.neoflock.neocomputers.item
import com.mojang.blaze3d.shaders.Shader
import com.mojang.blaze3d.vertex.DefaultVertexFormat
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.blaze3d.vertex.VertexConsumer
import com.mojang.blaze3d.vertex.VertexFormat
import net.minecraft.client.renderer.MultiBufferSource
import net.minecraft.client.renderer.RenderStateShard
import net.minecraft.client.renderer.RenderType
import net.minecraft.client.renderer.texture.OverlayTexture
import net.minecraft.resources.ResourceLocation
import org.neoflock.neocomputers.NeoComputers
interface RackItem {
// companion object {
// val RENDER_TYPE = {l: ResourceLocation ->
// RenderType.create("nc_server", DefaultVertexFormat.POSITION_COLOR_TEX_LIGHTMAP, VertexFormat.Mode.QUADS, RenderType.SMALL_BUFFER_SIZE, RenderType.CompositeState.builder()
// .setShaderState(RenderStateShard.ShaderStateShard.POSITION_COLOR_TEX_LIGHTMAP_SHADER)
// .setLightmapState(RenderStateShard.LIGHTMAP)
// .setTextureState(RenderStateShard.TextureStateShard(l, false, false))
// .createCompositeState(false))
// }
// }
val TOP_TEX: ResourceLocation
get() = ResourceLocation.fromNamespaceAndPath(NeoComputers.MODID, "textures/block/generic_top.png")
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()
// var buffer = source.getBuffer(RenderType.gui()) // TODO: correct rendertype
var buffer = source.getBuffer(RenderType.entitySolid(TOP_TEX))
// val u1 = 1/16f
buffer.addVertex(pose, 0f, 0f, 0f).setUv(1/16f, 15/16f).setColor(1f, 1f, 1f, 1f).setLight(light).setNormal(pose, 0f, -1f, 0f).setOverlay(OverlayTexture.NO_OVERLAY)
buffer.addVertex(pose, 14/16f, 0f, 0f).setUv(1/16f, 1/16f).setColor(1f, 1f, 1f, 1f).setLight(light).setNormal(pose, 0f, -1f, 0f).setOverlay(OverlayTexture.NO_OVERLAY)
buffer.addVertex(pose, 14/16f, 0f, 14/16f).setUv(15/16f, 1/16f).setColor(1f, 1f, 1f, 1f).setLight(light).setNormal(pose, 0f, -1f, 0f).setOverlay(OverlayTexture.NO_OVERLAY)
buffer.addVertex(pose, 0f, 0f, 14/16f).setUv(15/16f, 1/16f).setColor(1f, 1f, 1f, 1f).setLight(light).setNormal(pose, 0f, -1f, 0f).setOverlay(OverlayTexture.NO_OVERLAY)
buffer.addVertex(pose, 0f, 3/16f, 14/16f).setUv(15/16f, 1/16f).setColor(1f, 1f, 1f, 1f).setLight(light).setNormal(pose, 0f, 1f, 0f).setOverlay(OverlayTexture.NO_OVERLAY)
buffer.addVertex(pose, 14/16f, 3/16f, 14/16f).setUv(15/16f, 15/16f).setColor(1f, 1f, 1f, 1f).setLight(light).setNormal(pose, 0f, 1f, 0f).setOverlay(OverlayTexture.NO_OVERLAY)
buffer.addVertex(pose, 14/16f, 3/16f, 0f).setUv(1/16f, 15/16f).setColor(1f, 1f, 1f, 1f).setLight(light).setNormal(pose, 0f, 1f, 0f).setOverlay(OverlayTexture.NO_OVERLAY)
buffer.addVertex(pose, 0f, 3/16f, 0f).setUv(1/16f, 1/16f).setColor(1f, 1f, 1f, 1f).setLight(light).setNormal(pose, 0f, 1f, 0f).setOverlay(OverlayTexture.NO_OVERLAY)
buffer = source.getBuffer(RenderType.entitySolid(FRONT_TEX))
buffer.addVertex(pose, 14/16f, 3/16f, 14/16f).setUv(1/16f, v_offset/16f).setColor(1f, 1f, 1f, 1f).setLight(light).setNormal(pose, 1f, 0f, 0f).setOverlay(OverlayTexture.NO_OVERLAY)
buffer.addVertex(pose, 14/16f, 0f, 14/16f).setUv(1/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, 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()
}
}

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()) ItemStack(Items.MEM0.get())
} }
builder.displayItems { parameters, output -> builder.displayItems { parameters, output ->
// TODO: get rid of arch$tab and this shi and replace with loop over items registry Items.ITEMS.forEach {
output.accept(ItemStack(Items.CPU0.get())) output.accept(ItemStack(it.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()))
// Criminal black magic to put LuaBIOS EEPROM in the tabs // Criminal black magic to put LuaBIOS EEPROM in the tabs
do { do {

View File

@@ -170,9 +170,6 @@ open class DeviceNode(_address: UUID? = null) {
if(reachability == Visibility.SOME) { if(reachability == Visibility.SOME) {
return getPreferredFew() return getPreferredFew()
} }
if(reachability == Visibility.DIRECT) {
return connections.minus(this)
}
if(reachability == Visibility.NETWORK) { if(reachability == Visibility.NETWORK) {
// absolute cinema // absolute cinema
val working = HashSet<DeviceNode>() val working = HashSet<DeviceNode>()
@@ -185,8 +182,6 @@ open class DeviceNode(_address: UUID? = null) {
working.add(subnode) working.add(subnode)
if(subnode.reachability == Visibility.NETWORK) { if(subnode.reachability == Visibility.NETWORK) {
pending.addAll(subnode.connections) pending.addAll(subnode.connections)
} else if(subnode.reachability == Visibility.DIRECT) {
working.addAll(subnode.connections)
} else if(subnode.reachability == Visibility.SOME) { } else if(subnode.reachability == Visibility.SOME) {
pending.addAll(subnode.getPreferredFew()) pending.addAll(subnode.getPreferredFew())
} }

View File

@@ -30,8 +30,6 @@ object Networking {
NONE, NONE,
// some, as determined by getPreferredFew() // some, as determined by getPreferredFew()
SOME, SOME,
// can only see its direct connections
DIRECT,
// Can see everything network-wide // Can see everything network-wide
NETWORK, NETWORK,
} }

View File

@@ -3,10 +3,10 @@ package org.neoflock.neocomputers.network
import net.minecraft.world.level.block.entity.BlockEntityType import net.minecraft.world.level.block.entity.BlockEntityType
import org.neoflock.neocomputers.block.DeviceBlockEntity import org.neoflock.neocomputers.block.DeviceBlockEntity
//? if fabric { //? 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 net.minecraft.core.Direction
import team.reborn.energy.api.EnergyStorage; import team.reborn.energy.api.EnergyStorage;
//?} *///?}
// our soul purpose is to fuse bullshit power APIs together // 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 // 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 { object PowerManager {
fun<T: DeviceBlockEntity> registerPowerDevice(blockEntityType: BlockEntityType<T>) { fun<T: DeviceBlockEntity> registerPowerDevice(blockEntityType: BlockEntityType<T>) {
//? if fabric { //? 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. // 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 -> entity, dir ->
val node = entity.getNodeFromSide(dir ?: Direction.UP) val node = entity.getNodeFromSide(dir ?: Direction.UP)
@@ -41,6 +41,6 @@ object PowerManager {
} }
} }
}, blockEntityType); }, blockEntityType);
//?} *///?}
} }
} }

View File

@@ -1,9 +1,16 @@
package org.neoflock.neocomputers.utils package org.neoflock.neocomputers.utils
// based off the ImplementedContainer of https://docs.fabricmc.net/develop/blocks/block-containers // 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 dev.architectury.registry.menu.MenuRegistry
import net.minecraft.client.gui.GuiGraphics 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.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.world.Container;
import net.minecraft.core.NonNullList; import net.minecraft.core.NonNullList;
import net.minecraft.network.FriendlyByteBuf import net.minecraft.network.FriendlyByteBuf
@@ -68,7 +75,7 @@ abstract class GenericContainerMenu(menuType: MenuType<*>, id: Int, var containe
// Based off the code in ChestMenu // Based off the code in ChestMenu
for (i in 0..2) { for (i in 0..2) {
for (j in 0..8) { 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 +135,15 @@ abstract class GenericContainerScreen<T: GenericContainerMenu>(menu: T, inventor
val imageY: Int val imageY: Int
get() = (height - imageHeight) / 2 get() = (height - imageHeight) / 2
var widgets = mutableListOf<AbstractWidget>()
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() { override fun init() {
super.init() super.init()
@@ -138,24 +154,50 @@ abstract class GenericContainerScreen<T: GenericContainerMenu>(menu: T, inventor
val menuTex = findMenuTexture() val menuTex = findMenuTexture()
val cx = (width - imageWidth) / 2 val cx = (width - imageWidth) / 2
val cy = (height - imageHeight) / 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) { for (slot in menu.slots) {
if (slot is DynamicSlot) { if (slot is DynamicSlot) {
// NeoComputers.LOGGER.info("slot") slot.draw(guiGraphics, i-cx, j-cy)
slot.draw(guiGraphics, cx, cy, i, j)
}
} }
} }
open fun renderCustomOverlay(graphics: GuiGraphics, mouseX: Int, mouseY: Int, blend: Float) { guiGraphics.pose().popPose()
} }
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) { override fun render(graphics: GuiGraphics, mouseX: Int, mouseY: Int, something: Float) {
super.render(graphics, mouseX, mouseY, something) 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) if(shouldRenderTooltip()) super.renderTooltip(graphics, mouseX, mouseY)
} }
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
}
fun addWidget(widget: AbstractWidget) {
widgets.add(widget)
}
} }

View File

@@ -1,14 +1,73 @@
package org.neoflock.neocomputers.utils 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.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 import kotlin.math.min
data class GPUChar(val c: Char, val fg: Int =0xFFFFFF, val bg: Int = 0) // all is bgr data class GPUChar(val c: Char, val fg: Int =0xFFFFFF, val bg: Int = 0) // all is bgr
// TODO: wrapper over NN buffer // TODO: wrapper over NN buffer
class TextBuffer(var width: Int, var height: Int) { 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(' ') val blank = GPUChar(' ')
var buf = Array(width*height) { blank } 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) { fun encodeContents(buf: FriendlyByteBuf) {
// 0x01 means set fg, 0x02 means set bg, // 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 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 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 if(!inBounds(x, y)) return
buf[x+y*width] = pixel 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) { fun set(x: Int, y: Int, text: String, fg: Int = 0xFFFFFF, bg: Int = 0x000000, vertical: Boolean = false) {
for ((i, c) in text.toCharArray().withIndex()) { for ((i, c) in text.toCharArray().withIndex()) {
val cx = if(vertical) x else x + i val cx = if(vertical) x else x + i
val cy = if(vertical) y + i else y 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) { fun fill(x: Int, y: Int, w: Int, h: Int, pixel: GPUChar = blank) {
// turn it into values we can fw // turn it into values we can fw
@@ -92,8 +154,9 @@ class TextBuffer(var width: Int, var height: Int) {
val fh = min(h, height) val fh = min(h, height)
for(py in y..<y+fh) { for(py in y..<y+fh) {
for (px in x..<x + fw) { for (px in x..<x + fw) {
set(px, py, pixel) _set(px, py, pixel)
} }
} }
// tex.upload()
} }
} }

View File

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

View File

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

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,70 @@
{
"parent": "minecraft:block/block",
"render_type": "minecraft:solid",
"textures": {
"side": "neocomputers:block/rack_side",
"top": "neocomputers:block/generic_top"
},
"elements": [
{
"from": [0, 0, 0],
"to": [1, 16, 16],
"faces": {
"west": { "uv": [0, 0, 16, 16], "texture": "side", "tint_index": 0 },
"east": { "uv": [0, 0, 16, 16], "texture": "side", "tint_index": 0 },
"north": { "uv": [0, 0, 16, 1], "texture": "side", "tint_index": 0 },
"south": { "uv": [0, 0, 16, 1], "texture": "side", "tint_index": 0 },
"up": { "uv": [0, 0, 16, 1], "texture": "side", "tint_index": 0 },
"down": { "uv": [0, 0, 16, 1], "texture": "side", "tint_index": 0 }
}
},
{
"from": [1, 0, 0],
"to": [16, 16, 1],
"faces": {
"north": { "uv": [0, 0, 15, 16], "texture": "side", "tint_index": 0 },
"south": { "uv": [1, 0, 16, 16], "texture": "side", "tint_index": 0 },
"west": { "uv": [0, 0, 1, 16], "texture": "side", "tint_index": 0 },
"east": { "uv": [0, 0, 1, 16], "texture": "side", "tint_index": 0 },
"up": { "uv": [0, 0, 16, 1], "texture": "side", "tint_index": 0 },
"down": { "uv": [0, 0, 16, 1], "texture": "side", "tint_index": 0 }
}
},
{
"from": [1, 0, 15],
"to": [16, 16, 16],
"faces": {
"north": { "uv": [0, 0, 15, 16], "texture": "side", "tint_index": 0 },
"south": { "uv": [1, 0, 16, 16], "texture": "side", "tint_index": 0 },
"west": { "uv": [0, 0, 1, 16], "texture": "side", "tint_index": 0 },
"east": { "uv": [0, 0, 1, 16], "texture": "side", "tint_index": 0 },
"up": { "uv": [0, 0, 16, 1], "texture": "side", "tint_index": 0 },
"down": { "uv": [0, 0, 16, 1], "texture": "side", "tint_index": 0 }
}
},
{
"from": [1, 0, 1],
"to": [16, 2, 15],
"faces": {
"north": { "uv": [0, 0, 1, 16], "texture": "top", "tint_index": 0 },
"south": { "uv": [0, 0, 1, 16], "texture": "top", "tint_index": 0 },
"west": { "uv": [0, 0, 1, 16], "texture": "top", "tint_index": 0 },
"east": { "uv": [0, 0, 1, 16], "texture": "top", "tint_index": 0 },
"up": { "uv": [2, 1, 16, 15], "texture": "top", "tint_index": 0 },
"down": { "uv": [0, 0, 1, 1], "texture": "top", "tint_index": 0 }
}
},
{
"from": [1, 14, 1],
"to": [16, 16, 15],
"faces": {
"north": { "uv": [0, 0, 1, 16], "texture": "top", "tint_index": 0 },
"south": { "uv": [0, 0, 1, 16], "texture": "top", "tint_index": 0 },
"west": { "uv": [0, 0, 1, 16], "texture": "top", "tint_index": 0 },
"east": { "uv": [1, 0, 15, 2], "texture": "top", "tint_index": 0 },
"up": { "uv": [1, 1, 16, 15], "texture": "top", "tint_index": 0 },
"down": { "uv": [0, 0, 1, 1], "texture": "top", "tint_index": 0 }
}
}
]
}

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.

After

Width:  |  Height:  |  Size: 328 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 431 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 KiB

After

Width:  |  Height:  |  Size: 242 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 342 B

After

Width:  |  Height:  |  Size: 718 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 B

View File

@@ -1,4 +1,4 @@
accessWidener v2 named accessWidener v2 named
accessible method net/minecraft/world/level/block/entity/BlockEntityType <init> (Lnet/minecraft/world/level/block/entity/BlockEntityType$BlockEntitySupplier;Ljava/util/Set;)V # accessible method net/minecraft/world/level/block/entity/BlockEntityType <init> (Lnet/minecraft/world/level/block/entity/BlockEntityType$BlockEntitySupplier;Ljava/util/Set;)V
accessible field net/minecraft/core/Direction$Plane faces [Lnet/minecraft/core/Direction; accessible field net/minecraft/core/Direction$Plane faces [Lnet/minecraft/core/Direction;

View File

@@ -5,7 +5,7 @@ plugins {
id("com.gradleup.shadow") version "9.3.0" apply false id("com.gradleup.shadow") version "9.3.0" apply false
id("me.modmuss50.mod-publish-plugin") version "0.8.4" 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 stonecutter.automaticPlatformConstants = true
// Builds every version into `build/libs/{mod.version}/{loader}` // Builds every version into `build/libs/{mod.version}/{loader}`