Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
e53de23
added section padding
Grahmindol Aug 8, 2026
bd2b0e3
added section title
Grahmindol Aug 9, 2026
00e8f57
sneak-dbl click
CaitlynMainer Aug 7, 2026
51ea97d
Complete the double-sneak-click system.
CaitlynMainer Aug 7, 2026
46f7bb8
Support? Create movement?
CaitlynMainer Aug 8, 2026
35c3cdd
Fix fan sound being heard everywhere.
CaitlynMainer Aug 8, 2026
cb08486
Create contraption support.
CaitlynMainer Aug 8, 2026
9abe1f6
Fix java.lang.NoClassDefFoundError
CaitlynMainer Aug 8, 2026
6c40015
Computers work on trains.
CaitlynMainer Aug 8, 2026
1b653c7
Create Train component.
CaitlynMainer Aug 8, 2026
5784fcf
Fixes crash on dedicated server
CaitlynMainer Aug 8, 2026
4e1eb14
Fix tablet crashing on dedicated server
CaitlynMainer Aug 8, 2026
b123acb
Implement #39 with the component clear method
CaitlynMainer Aug 8, 2026
02cdcfb
Undo the async beep that somehow snuck back in
CaitlynMainer Aug 8, 2026
868d18e
update funscii to unifont 17.0.05
CaitlynMainer Aug 9, 2026
db1ae7d
Create bug_report.md
CaitlynMainer Aug 9, 2026
52d3808
Fix disassembler template output handling
CaitlynMainer Aug 9, 2026
a8e2f80
Generate block state files
SquidDev Aug 9, 2026
8b33eb1
Use a dedicated component for chamelium color
SquidDev Aug 9, 2026
28142a6
Prideflag Robots!
CaitlynMainer Aug 9, 2026
cc0871e
Correct CC:T Pride flag license
CaitlynMainer Aug 9, 2026
56388d9
Add Create train computer integration and train robot
CaitlynMainer Aug 8, 2026
b4dfefe
Create CC-Tweaked.txt
CaitlynMainer Aug 9, 2026
97d5705
Persist train component, make sure screens initialize after restore
CaitlynMainer Aug 9, 2026
dd4267f
Fix TextBuffers loading blank after restore
CaitlynMainer Aug 9, 2026
be4f800
Fix tablet rendering with batching mods and shaders
CaitlynMainer Aug 10, 2026
477abf0
Open tablet UIs even when not looking at a block
CaitlynMainer Aug 10, 2026
c8241bf
Open manual on right click again...
CaitlynMainer Aug 10, 2026
02454bb
Resync monitor resolution and color on load
CaitlynMainer Aug 10, 2026
1dfe1bb
better banner
Grahmindol Aug 10, 2026
1638803
Merge branch 'main-MC1.21.1' into feature/creative-tab
Grahmindol Aug 11, 2026
561f695
add disk/eeprom support
Grahmindol Aug 11, 2026
f1e0c87
handle network T2 card ban
Grahmindol Aug 11, 2026
0ffcc11
handle openprinter.....
Grahmindol Aug 11, 2026
6383f0d
merge resolve OCItems
Daydrain Aug 12, 2026
8704f39
some few fixs
Daydrain Aug 12, 2026
d5e1eb9
Merge branch 'main-MC1.21.1' into feature/creative-tab
Grahmindol Aug 12, 2026
0e755f4
fix server crach
Grahmindol Aug 13, 2026
e4b7f35
just to test the modificated API, it's not that bad.
Grahmindol Aug 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/main/java/li/cil/oc/api/Items.java
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,22 @@ public static ItemStack registerEEPROM(String name, byte[] code, byte[] data, bo
return ItemStack.EMPTY;
}

/**
* The stack will be listed in the creative tab of OpenComputers.
*
* Call this in the init phase or later, <em>not</em> in pre-init.
*
* @param stack the stack to add in the creative tab.
* @param name the label of the EEPROM.
* @param section_id the section to put the stack in.
*
*/
public static ItemStack registerStack(ItemStack stack, String name, String section_id) {
if (API.items != null)
return API.items.registerStack(stack, name, section_id);
return ItemStack.EMPTY;
}

// ----------------------------------------------------------------------- //

private Items() {
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/li/cil/oc/api/detail/ItemAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,16 @@ ItemStack registerFloppy(String name, ResourceLocation loc, DyeColor color,
* adding a recipe for your custom BIOS, for example.
*/
ItemStack registerEEPROM(String name, byte[] code, byte[] data, boolean readonly);

/**
* The stack will be listed in the creative tab of OpenComputers.
*
* Call this in the init phase or later, <em>not</em> in pre-init.
*
* @param stack the stack to add in the creative tab.
* @param name the label of the EEPROM.
* @param sectionId the section to put the stack in.
*
*/
ItemStack registerStack(ItemStack stack, String name, String sectionId);
}
27 changes: 14 additions & 13 deletions src/main/java/li/cil/oc/common/openprinter/OpenPrinter.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.function.Consumer;

/**
* OpenPrinter, integrated directly into OpenComputers.
*
Expand Down Expand Up @@ -162,20 +164,19 @@ private static void registerOpenComputersIntegration() {
} catch (RuntimeException exception) {
LOGGER.warn("Could not register the OpenPrinter tools disk", exception);
}
}

public static void addCreativeItems(BuildCreativeModeTabContentsEvent event) {
event.accept(PRINTER.get());
event.accept(SHREDDER.get());
event.accept(FILE_CABINET.get());
event.accept(BRIEFCASE.get());
event.accept(PRINTED_PAGE.get());
event.accept(BLACK_INK.get());
event.accept(COLOR_INK.get());
event.accept(PAPER_SHREDS.get());
event.accept(FOLDER.get());
// The tools disk is registered through OpenComputers' public floppy API,
// which already adds it to the OpenComputers creative tab.

li.cil.oc.api.Items.registerStack(PRINTER.toStack(), PRINTER.getRegisteredName(), "25_components");

li.cil.oc.api.Items.registerStack(SHREDDER.toStack(), SHREDDER.getRegisteredName(), "49_tools");
li.cil.oc.api.Items.registerStack(FILE_CABINET.toStack(), FILE_CABINET.getRegisteredName(), "49_tools");
li.cil.oc.api.Items.registerStack(BRIEFCASE.toStack(), BRIEFCASE.getRegisteredName(), "49_tools");
li.cil.oc.api.Items.registerStack(PRINTED_PAGE.toStack(), PRINTED_PAGE.getRegisteredName(), "49_tools");
li.cil.oc.api.Items.registerStack(FOLDER.toStack(), PRINTED_PAGE.getRegisteredName(), "49_tools");

li.cil.oc.api.Items.registerStack(BLACK_INK.toStack(), BLACK_INK.getRegisteredName(), "50_materials");
li.cil.oc.api.Items.registerStack(COLOR_INK.toStack(), COLOR_INK.getRegisteredName(), "50_materials");
li.cil.oc.api.Items.registerStack(PAPER_SHREDS.toStack(), PAPER_SHREDS.getRegisteredName(), "50_materials");
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package li.cil.oc.mixin.accessor;

import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;

@Mixin(AbstractContainerScreen.class)
public interface AbstractContainerScreenAccess {
@Accessor()
int getLeftPos();

@Accessor
int getTopPos();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package li.cil.oc.mixin.accessor;

import net.minecraft.client.gui.screens.inventory.CreativeModeInventoryScreen;
import net.minecraft.util.Mth;
import net.minecraft.world.item.CreativeModeTab;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;

@Mixin(CreativeModeInventoryScreen.class)
public interface CreativeModeInventoryScreenAccess {
@Shadow
static CreativeModeTab selectedTab = null;
}
6 changes: 6 additions & 0 deletions src/main/resources/assets/opencomputers/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,12 @@
"item.oc.worldsensorcard": "World Sensor Card",
"item.oc.wrench": "Scrench",
"itemGroup.OpenComputers": "OpenComputers",
"itemGroup.OpenComputers.section.10_networking": "Networking§f",
"itemGroup.OpenComputers.section.25_components": "Components§f",
"itemGroup.OpenComputers.section.49_tools": "Tools§f",
"itemGroup.OpenComputers.section.50_materials": "Materials§f",
"itemGroup.OpenComputers.section.80_upgrade": "Upgrades§f",
"itemGroup.OpenComputers.section.99_misc": "Miscellaneous§f",
"entity.oc.Drone": "Drone",
"entity.oc.TrainRobot": "Train Robot",
"oc:gui.Analyzer.Address": "§6Address§f: %s",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions src/main/resources/opencomputers.core.mixins.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"required": false,
"minVersion": "0.8",
"package": "li.cil.oc.mixin",
"compatibilityLevel": "JAVA_21",
"client": [
"CreativeModeInventoryScreenMixin",
"ItemPickerMenuMixin",
"accessor.CreativeModeInventoryScreenAccess",
"accessor.AbstractContainerScreenAccess"
],
"mixins": [
"CreativeModeTabMixin"
],
"injectors": {
"defaultRequire": 1
}
}
1 change: 0 additions & 1 deletion src/main/scala/li/cil/oc/Constants.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package li.cil.oc
import li.cil.oc.util.ItemUtils

object Constants {

object BlockName {
final val Adapter = "adapter"
final val Assembler = "assembler"
Expand Down
15 changes: 5 additions & 10 deletions src/main/scala/li/cil/oc/CreativeTab.scala

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Attempted to load class net/minecraft/client/gui/GuiGraphics for invalid dist DEDICATED_SERVER

CreativeTab is loaded on both Client and Server, you can't have client rendering code in a common location.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also with this PR in place I am no longer able to register floppies directly from external mods, all floppy names seem to be forced to their internal name, and I am unable to register an item to the OC creative tab from another mod.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The renderBannersn method wasn't even being called, but that simple declaration was what caused the error—I never would have guessed. So, I moved it.

@Grahmindol Grahmindol Aug 13, 2026

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normally, you can continue adding items to the end of the tab just as before, since I’m not adding padding at the end.

When using the API, floppy disks and EEPROMs should already appear in the tab.
To be able to add items to a section, a method would need to be added to li.cil.oc.api.Items.java.

kind of :

// in li.cil.oc.api.Items.java
public static void registerStack(ItemStack stack, String name, String section_id) {
        if (API.items != null)
            API.items.registerStack(stack, name, section_id);
    }
// in  li.cil.oc.common.init.OCItems.scala
def registerStack(stack: ItemStack, id: String, section_id : String): ItemStack = {
    val immutableStack = stack.copy()
    ITEM_TO_SECTION.put(id, section_id);
    descriptors += id -> new ItemInfo {
      override def name: String = id

      override def block = null

      override def createItemStack(size: Int): ItemStack = {
        val copy = immutableStack.copy()
        copy.setCount(size)
        copy
      }

      override def item: Item = immutableStack.getItem
    }
    stack
  }

However, this entails a significant change to the API.

A comment in li.cil.oc.api.CreativeTab should be used to explain how to register items in a section.

(It doesn't seem ideal to me, but if it works for you, it works for me.)
(I haven't committed anything for this yet because I'm waiting to see if you have a better idea.)
Thanks for the review!

Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,14 @@ import li.cil.oc.common.init.OCItems
import net.minecraft.core.registries.Registries
import net.minecraft.network.chat.Component
import net.minecraft.world.item.{CreativeModeTab, CreativeModeTabs}
import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent
import net.neoforged.bus.api.SubscribeEvent
import net.neoforged.neoforge.registries.{DeferredRegister, DeferredHolder}
import li.cil.oc.integration.opencomputers.ModOpenComputers
import li.cil.oc.common.openprinter.OpenPrinter
import net.neoforged.neoforge.event.BuildCreativeModeTabContentsEvent
import net.neoforged.neoforge.registries.{DeferredHolder, DeferredRegister}

object CreativeTab {
val CREATIVE_TABS: DeferredRegister[CreativeModeTab] =
DeferredRegister.create(Registries.CREATIVE_MODE_TAB, OpenComputers.ID)

var CURRENT_ROW = 0
val MAIN: DeferredHolder[CreativeModeTab, CreativeModeTab] = CREATIVE_TABS.register("main", () =>
CreativeModeTab.builder()
.title(Component.translatable(s"itemGroup.${OpenComputers.Name}"))
Expand All @@ -23,11 +21,8 @@ object CreativeTab {

@SubscribeEvent
def onBuildContents(event: BuildCreativeModeTabContentsEvent): Unit = {
if (event.getTabKey == MAIN.getKey) {
OCItems.decorateCreativeTab(event, ModOpenComputers.hasRedstoneCardT2)
OpenPrinter.addCreativeItems(event)
} else if (event.getTabKey == CreativeModeTabs.TOOLS_AND_UTILITIES) {
if (event.getTabKey == CreativeModeTabs.TOOLS_AND_UTILITIES) {
event.accept(OCItems.createChargedHoverBoots())
}
}
}
}
10 changes: 3 additions & 7 deletions src/main/scala/li/cil/oc/common/Loot.scala
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ object Loot {
val root = "opencomputers/eeproms/" + id.getPath
val code = readEEPROMResource(json, "code", id, root, manager)
val data = readEEPROMResource(json, "data", id, root, manager)
val stack = OCItems.createEEPROM(label, code.orNull, data.orNull, readonly)
val stack = OCItems.registerEEPROM(label, code.orNull, data.orNull, readonly)
datapackEEPROMs += stack
eepromsForServer += stack
eepromsForClient += stack.copy()
Expand Down Expand Up @@ -332,12 +332,8 @@ object Loot {
} else new Callable[FileSystem] {
override def call(): FileSystem = api.FileSystem.fromResource(ResourceLocation.fromNamespaceAndPath(Settings.resourceDomain, "loot/" + path))
}
val stack = registerLootDisk(path, ResourceLocation.fromNamespaceAndPath(Settings.resourceDomain, path), color.getOrElse(DyeColor.LIGHT_GRAY), callable, doRecipeCycling = true)
stack.set(DataComponents.CUSTOM_NAME, Component.literal(name))
if (!external) {
OCItems.registerStack(stack, path)
lootDiskDescriptorIds += path
}
val stack = OCItems.registerFloppy(path, ResourceLocation.fromNamespaceAndPath(Settings.resourceDomain, path), color.getOrElse(DyeColor.LIGHT_GRAY), callable, doRecipeCycling = true)
lootDiskDescriptorIds += path
stack
}
}
Loading
Loading