Add more eldritch horrors to the build system
- Add a basic data exporter to the test mod, run via a /ccexport command. This dumps all of CC's recipes, and the item icons needed to display those recipes. - Post-process our illuaminate HTML, applying several transforms: - Apply syntax highlighting to code blocks. We previously did this at runtime, so this shaves some bytes off the bundle. - Convert a mc-recipe custom element into a recipe grid using react/react-dom. - Add a recipe to the speaker page. I'll probably clean this up in the future (though someone else is free to too!), but it's a nice start and proof-of-concept. I tried so hard here to use next.js and MDX instead of rolling our own solution again, but it's so hard to make it play well with "normal" Markdown, which isn't explicitly written for MDX.
28
build.gradle
@ -158,7 +158,7 @@ dependencies {
|
||||
|
||||
testModImplementation sourceSets.main.output
|
||||
|
||||
cctJavadoc 'cc.tweaked:cct-javadoc:1.4.5'
|
||||
cctJavadoc 'cc.tweaked:cct-javadoc:1.4.6'
|
||||
}
|
||||
|
||||
// Compile tasks
|
||||
@ -298,7 +298,7 @@ task rollup(type: Exec) {
|
||||
|
||||
task illuaminateDocs(type: Exec, dependsOn: [rollup, luaJavadoc]) {
|
||||
group = "build"
|
||||
description = "Bundles JS into rollup"
|
||||
description = "Generates docs using Illuaminate"
|
||||
|
||||
inputs.files(fileTree("doc")).withPropertyName("docs")
|
||||
inputs.files(fileTree("src/main/resources/data/computercraft/lua/rom")).withPropertyName("lua rom")
|
||||
@ -311,7 +311,20 @@ task illuaminateDocs(type: Exec, dependsOn: [rollup, luaJavadoc]) {
|
||||
commandLine mkCommand('"bin/illuaminate" doc-gen')
|
||||
}
|
||||
|
||||
task docWebsite(type: Copy, dependsOn: [illuaminateDocs]) {
|
||||
task jsxDocs(type: Exec, dependsOn: [illuaminateDocs]) {
|
||||
group = "build"
|
||||
description = "Post-processes documentation to statically render some dynamic content."
|
||||
|
||||
inputs.files(fileTree("src/web")).withPropertyName("sources")
|
||||
inputs.file("package-lock.json").withPropertyName("package-lock.json")
|
||||
inputs.file("tsconfig.json").withPropertyName("Typescript config")
|
||||
inputs.files(fileTree("$buildDir/docs/lua"))
|
||||
outputs.dir("$buildDir/docs/site")
|
||||
|
||||
commandLine mkCommand("'node_modules/.bin/ts-node' --esm src/web/transform.tsx")
|
||||
}
|
||||
|
||||
task docWebsite(type: Copy, dependsOn: [jsxDocs]) {
|
||||
from('doc') {
|
||||
include 'logo.png'
|
||||
include 'images/**'
|
||||
@ -319,7 +332,14 @@ task docWebsite(type: Copy, dependsOn: [illuaminateDocs]) {
|
||||
from("$buildDir/rollup") {
|
||||
exclude 'index.js'
|
||||
}
|
||||
into "${project.docsDir}/lua"
|
||||
from("$buildDir/docs/lua") {
|
||||
exclude '**/*.html'
|
||||
}
|
||||
from("src/web/export/items") {
|
||||
into("images/items")
|
||||
}
|
||||
|
||||
into "${project.docsDir}/site"
|
||||
}
|
||||
|
||||
// Check tasks
|
||||
|
@ -76,7 +76,9 @@
|
||||
<module name="JavadocBlockTagLocation" />
|
||||
<module name="JavadocMethod"/>
|
||||
<module name="JavadocType"/>
|
||||
<module name="JavadocStyle" />
|
||||
<module name="JavadocStyle">
|
||||
<property name="checkHtml" value="false" />
|
||||
</module>
|
||||
<module name="NonEmptyAtclauseDescription" />
|
||||
<module name="SingleLineJavadoc" />
|
||||
<module name="SummaryJavadocCheck"/>
|
||||
|
1719
package-lock.json
generated
10
package.json
@ -4,6 +4,7 @@
|
||||
"description": "Website additions for tweaked.cc",
|
||||
"author": "SquidDev",
|
||||
"license": "BSD-3-Clause",
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"preact": "^10.5.5",
|
||||
"tslib": "^2.0.3"
|
||||
@ -11,9 +12,18 @@
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-typescript": "^8.2.5",
|
||||
"@rollup/plugin-url": "^6.1.0",
|
||||
"@types/glob": "^7.2.0",
|
||||
"@types/react-dom": "^18.0.5",
|
||||
"glob": "^8.0.3",
|
||||
"react": "^18.1.0",
|
||||
"react-dom": "^18.1.0",
|
||||
"rehype": "^12.0.1",
|
||||
"rehype-highlight": "^5.0.2",
|
||||
"rehype-react": "^7.1.1",
|
||||
"requirejs": "^2.3.6",
|
||||
"rollup": "^2.33.1",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"ts-node": "^10.8.0",
|
||||
"typescript": "^4.0.5"
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,9 @@ import static dan200.computercraft.api.lua.LuaValues.checkFinite;
|
||||
* - {@link #playSound} plays any built-in Minecraft sound, such as block sounds or mob noises.
|
||||
* - {@link #playAudio} can play arbitrary audio.
|
||||
*
|
||||
* <h2>Recipe</h2>
|
||||
* <McRecipe recipe="computercraft:speaker"></McRecipe>
|
||||
*
|
||||
* @cc.module speaker
|
||||
* @cc.since 1.80pr1
|
||||
*/
|
||||
|
153
src/testMod/java/dan200/computercraft/export/Exporter.java
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
package dan200.computercraft.export;
|
||||
|
||||
import com.google.common.io.MoreFiles;
|
||||
import com.google.common.io.RecursiveDeleteOption;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import dan200.computercraft.ComputerCraft;
|
||||
import dan200.computercraft.ingame.mod.TestMod;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.crafting.*;
|
||||
import net.minecraft.util.NonNullList;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.client.event.ClientChatEvent;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.io.Writer;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Provides a {@literal /ccexport <path>} command which exports icons and recipes for all ComputerCraft items.
|
||||
*/
|
||||
@Mod.EventBusSubscriber( modid = TestMod.MOD_ID, value = Dist.CLIENT )
|
||||
public class Exporter
|
||||
{
|
||||
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onClientCommands( ClientChatEvent event )
|
||||
{
|
||||
String prefix = "/ccexport";
|
||||
if( !event.getMessage().startsWith( prefix ) ) return;
|
||||
event.setCanceled( true );
|
||||
|
||||
Path output = new File( event.getMessage().substring( prefix.length() ).trim() ).getAbsoluteFile().toPath();
|
||||
if( !Files.isDirectory( output ) )
|
||||
{
|
||||
Minecraft.getInstance().gui.getChat().addMessage( new StringTextComponent( "Output path does not exist" ) );
|
||||
return;
|
||||
}
|
||||
|
||||
RenderSystem.assertThread( RenderSystem::isOnRenderThread );
|
||||
try( ImageRenderer renderer = new ImageRenderer() )
|
||||
{
|
||||
export( output, renderer );
|
||||
}
|
||||
catch( IOException e )
|
||||
{
|
||||
throw new UncheckedIOException( e );
|
||||
}
|
||||
|
||||
Minecraft.getInstance().gui.getChat().addMessage( new StringTextComponent( "Export finished!" ) );
|
||||
}
|
||||
|
||||
private static void export( Path root, ImageRenderer renderer ) throws IOException
|
||||
{
|
||||
JsonDump dump = new JsonDump();
|
||||
|
||||
Set<Item> items = new HashSet<>();
|
||||
|
||||
// First find all CC items
|
||||
for( Item item : ForgeRegistries.ITEMS.getValues() )
|
||||
{
|
||||
if( item.getRegistryName().getNamespace().equals( ComputerCraft.MOD_ID ) ) items.add( item );
|
||||
}
|
||||
|
||||
// Now find all CC recipes.
|
||||
for( ICraftingRecipe recipe : Minecraft.getInstance().level.getRecipeManager().getAllRecipesFor( IRecipeType.CRAFTING ) )
|
||||
{
|
||||
ItemStack result = recipe.getResultItem();
|
||||
if( !result.getItem().getRegistryName().getNamespace().equals( ComputerCraft.MOD_ID ) ) continue;
|
||||
if( result.hasTag() )
|
||||
{
|
||||
ComputerCraft.log.warn( "Skipping recipe {} as it has NBT", recipe.getId() );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( recipe instanceof ShapedRecipe )
|
||||
{
|
||||
JsonDump.Recipe converted = new JsonDump.Recipe( result );
|
||||
|
||||
ShapedRecipe shaped = (ShapedRecipe) recipe;
|
||||
for( int x = 0; x < shaped.getWidth(); x++ )
|
||||
{
|
||||
for( int y = 0; y < shaped.getHeight(); y++ )
|
||||
{
|
||||
Ingredient ingredient = shaped.getIngredients().get( x + y * shaped.getWidth() );
|
||||
if( ingredient.isEmpty() ) continue;
|
||||
|
||||
converted.setInput( x + y * 3, ingredient, items );
|
||||
}
|
||||
}
|
||||
|
||||
dump.recipes.put( recipe.getId().toString(), converted );
|
||||
}
|
||||
else if( recipe instanceof ShapelessRecipe )
|
||||
{
|
||||
JsonDump.Recipe converted = new JsonDump.Recipe( result );
|
||||
|
||||
ShapelessRecipe shapeless = (ShapelessRecipe) recipe;
|
||||
NonNullList<Ingredient> ingredients = shapeless.getIngredients();
|
||||
for( int i = 0; i < ingredients.size(); i++ )
|
||||
{
|
||||
converted.setInput( i, ingredients.get( i ), items );
|
||||
}
|
||||
|
||||
dump.recipes.put( recipe.getId().toString(), converted );
|
||||
}
|
||||
else
|
||||
{
|
||||
ComputerCraft.log.info( "Don't know how to handle recipe {}", recipe );
|
||||
}
|
||||
}
|
||||
|
||||
Path itemDir = root.resolve( "items" );
|
||||
if( Files.exists( itemDir ) ) MoreFiles.deleteRecursively( itemDir, RecursiveDeleteOption.ALLOW_INSECURE );
|
||||
|
||||
renderer.setupState();
|
||||
for( Item item : items )
|
||||
{
|
||||
ItemStack stack = new ItemStack( item );
|
||||
dump.itemNames.put( item.getRegistryName().toString(), stack.getHoverName().getString() );
|
||||
|
||||
ResourceLocation location = item.getRegistryName();
|
||||
renderer.captureRender( itemDir.resolve( location.getNamespace() ).resolve( location.getPath() + ".png" ),
|
||||
() -> Minecraft.getInstance().getItemRenderer().renderAndDecorateFakeItem( stack, 0, 0 )
|
||||
);
|
||||
}
|
||||
renderer.clearState();
|
||||
|
||||
try( Writer writer = Files.newBufferedWriter( root.resolve( "index.json" ) ) )
|
||||
{
|
||||
GSON.toJson( dump, writer );
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
package dan200.computercraft.export;
|
||||
|
||||
import com.mojang.blaze3d.systems.RenderSystem;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.renderer.FogRenderer;
|
||||
import net.minecraft.client.renderer.texture.NativeImage;
|
||||
import net.minecraft.client.shader.Framebuffer;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL12;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
* Utilities for saving OpenGL output to an image rather than displaying it on the screen.
|
||||
*/
|
||||
public class ImageRenderer implements AutoCloseable
|
||||
{
|
||||
public static final int WIDTH = 64;
|
||||
public static final int HEIGHT = 64;
|
||||
|
||||
private final Framebuffer framebuffer = new Framebuffer( WIDTH, HEIGHT, true, Minecraft.ON_OSX );
|
||||
private final NativeImage image = new NativeImage( WIDTH, HEIGHT, Minecraft.ON_OSX );
|
||||
|
||||
public ImageRenderer()
|
||||
{
|
||||
framebuffer.setClearColor( 0, 0, 0, 0 );
|
||||
framebuffer.clear( Minecraft.ON_OSX );
|
||||
}
|
||||
|
||||
public void setupState()
|
||||
{
|
||||
RenderSystem.matrixMode( GL11.GL_PROJECTION );
|
||||
RenderSystem.pushMatrix();
|
||||
RenderSystem.loadIdentity();
|
||||
RenderSystem.ortho( 0, 16, 16, 0, 1000, 3000 );
|
||||
|
||||
RenderSystem.matrixMode( GL11.GL_MODELVIEW );
|
||||
RenderSystem.pushMatrix();
|
||||
RenderSystem.loadIdentity();
|
||||
RenderSystem.translatef( 0, 0, -2000f );
|
||||
|
||||
FogRenderer.setupNoFog();
|
||||
}
|
||||
|
||||
public void clearState()
|
||||
{
|
||||
RenderSystem.matrixMode( GL11.GL_PROJECTION );
|
||||
RenderSystem.popMatrix();
|
||||
|
||||
RenderSystem.matrixMode( GL11.GL_MODELVIEW );
|
||||
RenderSystem.popMatrix();
|
||||
}
|
||||
|
||||
public void captureRender( Path output, Runnable render ) throws IOException
|
||||
{
|
||||
Files.createDirectories( output.getParent() );
|
||||
|
||||
framebuffer.bindWrite( true );
|
||||
RenderSystem.clear( GL12.GL_COLOR_BUFFER_BIT | GL12.GL_DEPTH_BUFFER_BIT, Minecraft.ON_OSX );
|
||||
render.run();
|
||||
framebuffer.unbindWrite();
|
||||
|
||||
framebuffer.bindRead();
|
||||
image.downloadTexture( 0, false );
|
||||
image.flipY();
|
||||
framebuffer.unbindRead();
|
||||
|
||||
image.writeToFile( output );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
image.close();
|
||||
framebuffer.destroyBuffers();
|
||||
}
|
||||
}
|
65
src/testMod/java/dan200/computercraft/export/JsonDump.java
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
||||
* Copyright Daniel Ratcliffe, 2011-2022. Do not distribute without permission.
|
||||
* Send enquiries to dratcliffe@gmail.com
|
||||
*/
|
||||
package dan200.computercraft.export;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.item.Items;
|
||||
import net.minecraft.item.crafting.Ingredient;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class JsonDump
|
||||
{
|
||||
public Map<String, String> itemNames = new TreeMap<>();
|
||||
public Map<String, Recipe> recipes = new TreeMap<>();
|
||||
|
||||
public static class Recipe
|
||||
{
|
||||
public final String[][] inputs = new String[9][];
|
||||
public String output;
|
||||
public int count;
|
||||
|
||||
public Recipe( ItemStack output )
|
||||
{
|
||||
this.output = output.getItem().getRegistryName().toString();
|
||||
count = output.getCount();
|
||||
}
|
||||
|
||||
public void setInput( int pos, Ingredient ingredient, Set<Item> trackedItems )
|
||||
{
|
||||
if( ingredient.isEmpty() ) return;
|
||||
|
||||
ItemStack[] items = ingredient.getItems();
|
||||
|
||||
// First try to simplify some tags to something easier.
|
||||
for( ItemStack stack : items )
|
||||
{
|
||||
Item item = stack.getItem();
|
||||
if( !canonicalItem.contains( item ) ) continue;
|
||||
|
||||
trackedItems.add( item );
|
||||
inputs[pos] = new String[] { item.getRegistryName().toString() };
|
||||
return;
|
||||
}
|
||||
|
||||
String[] itemIds = new String[items.length];
|
||||
for( int i = 0; i < items.length; i++ )
|
||||
{
|
||||
Item item = items[i].getItem();
|
||||
trackedItems.add( item );
|
||||
itemIds[i] = item.getRegistryName().toString();
|
||||
}
|
||||
Arrays.sort( itemIds );
|
||||
|
||||
inputs[pos] = itemIds;
|
||||
}
|
||||
|
||||
private static final Set<Item> canonicalItem = new HashSet<>( Arrays.asList(
|
||||
Items.GLASS_PANE, Items.STONE, Items.CHEST
|
||||
) );
|
||||
}
|
||||
}
|
44
src/web/components/Recipe.tsx
Normal file
@ -0,0 +1,44 @@
|
||||
import type { FunctionComponent } from "react";
|
||||
import { createElement as h } from "react";
|
||||
import useExport from "./WithExport.js";
|
||||
|
||||
const Item: FunctionComponent<{ item: string }> = ({ item }) => {
|
||||
const data = useExport();
|
||||
const itemName = data.itemNames[item];
|
||||
|
||||
return <img
|
||||
src={`/images/items/${item.replace(":", "/")}.png`}
|
||||
alt={itemName}
|
||||
title={itemName}
|
||||
/>
|
||||
};
|
||||
|
||||
const Arrow: FunctionComponent<JSX.IntrinsicElements["svg"]> = (props) => <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 45.513 45.512" {...props}>
|
||||
<g>
|
||||
<path d="M44.275,19.739L30.211,5.675c-0.909-0.909-2.275-1.18-3.463-0.687c-1.188,0.493-1.959,1.654-1.956,2.938l0.015,5.903
|
||||
l-21.64,0.054C1.414,13.887-0.004,15.312,0,17.065l0.028,11.522c0.002,0.842,0.338,1.648,0.935,2.242s1.405,0.927,2.247,0.925
|
||||
l21.64-0.054l0.014,5.899c0.004,1.286,0.781,2.442,1.971,2.931c1.189,0.487,2.557,0.21,3.46-0.703L44.29,25.694
|
||||
C45.926,24.043,45.92,21.381,44.275,19.739z" fill="var(--recipe-hover)" />
|
||||
</g>
|
||||
</svg>;
|
||||
|
||||
const Recipe: FunctionComponent<{ recipe: string }> = ({ recipe }) => {
|
||||
const data = useExport();
|
||||
const recipeInfo = data.recipes[recipe];
|
||||
if (!recipeInfo) throw Error("Cannot find recipe for " + recipe);
|
||||
|
||||
return <div className="recipe-container">
|
||||
<div className="recipe">
|
||||
<strong className="recipe-title">{data.itemNames[recipeInfo.output]}</strong>
|
||||
<div className="recipe-inputs">
|
||||
{recipeInfo.inputs.map((items, i) => <div className="recipe-item recipe-input" key={i}>{items && <Item item={items[0]} />}</div>)}
|
||||
</div>
|
||||
<Arrow className="recipe-arrow" />
|
||||
<div className="recipe-item recipe-output">
|
||||
<Item item={recipeInfo.output} />
|
||||
{recipeInfo.count > 1 && <span className="recipe-count">{recipeInfo.count}</span>}
|
||||
</div>
|
||||
</div>
|
||||
</div>;
|
||||
}
|
||||
export default Recipe;
|
23
src/web/components/WithExport.tsx
Normal file
@ -0,0 +1,23 @@
|
||||
import { createElement as h, useContext, createContext, FunctionComponent, ReactNode } from "react";
|
||||
|
||||
export type DataExport = {
|
||||
readonly itemNames: Record<string, string>,
|
||||
readonly recipes: Record<string, Recipe>,
|
||||
};
|
||||
|
||||
export type Recipe = {
|
||||
readonly inputs: Array<Array<string>>,
|
||||
readonly output: string,
|
||||
readonly count: number,
|
||||
};
|
||||
|
||||
const DataExport = createContext<DataExport>({
|
||||
itemNames: {},
|
||||
recipes: {},
|
||||
});
|
||||
|
||||
export const useExport = () => useContext(DataExport);
|
||||
export default useExport;
|
||||
|
||||
export const WithExport: FunctionComponent<{ data: DataExport, children: ReactNode }> =
|
||||
({ data, children }) => <DataExport.Provider value={data}> {children}</DataExport.Provider >;
|
25
src/web/components/support.tsx
Normal file
@ -0,0 +1,25 @@
|
||||
import type { FunctionComponent } from "react";
|
||||
|
||||
/**
|
||||
* Wrap a component and ensure that no children are passed to it.
|
||||
*
|
||||
* Our custom tags *must* be explicitly closed, as <foo /> will be parsed as
|
||||
* <foo>(rest of the document)</foo>. This ensures you've not forgotten to do
|
||||
* that.
|
||||
*
|
||||
* @param component The component to wrap
|
||||
* @returns A new functional component identical to the previous one
|
||||
*/
|
||||
export const noChildren = function <T>(component: FunctionComponent<T>): FunctionComponent<T> {
|
||||
// I hope that our few remaining friends
|
||||
// Give up on trying to save us
|
||||
|
||||
const name = component.displayName ?? component.name;
|
||||
const wrapped: FunctionComponent<T> = props => {
|
||||
if ((props as any).children) throw Error("Unexpected children in " + name);
|
||||
|
||||
return component(props);
|
||||
};
|
||||
wrapped.displayName = name;
|
||||
return wrapped;
|
||||
}
|
760
src/web/export/index.json
Normal file
@ -0,0 +1,760 @@
|
||||
{
|
||||
"itemNames": {
|
||||
"computercraft:cable": "Networking Cable",
|
||||
"computercraft:computer_advanced": "Advanced Computer",
|
||||
"computercraft:computer_command": "Command Computer",
|
||||
"computercraft:computer_normal": "Computer",
|
||||
"computercraft:disk": "Floppy Disk",
|
||||
"computercraft:disk_drive": "Disk Drive",
|
||||
"computercraft:monitor_advanced": "Advanced Monitor",
|
||||
"computercraft:monitor_normal": "Monitor",
|
||||
"computercraft:pocket_computer_advanced": "Advanced Pocket Computer",
|
||||
"computercraft:pocket_computer_normal": "Pocket Computer",
|
||||
"computercraft:printed_book": "Printed Book",
|
||||
"computercraft:printed_page": "Printed Page",
|
||||
"computercraft:printed_pages": "Printed Pages",
|
||||
"computercraft:printer": "Printer",
|
||||
"computercraft:speaker": "Speaker",
|
||||
"computercraft:treasure_disk": "Floppy Disk",
|
||||
"computercraft:turtle_advanced": "Advanced Turtle",
|
||||
"computercraft:turtle_normal": "Turtle",
|
||||
"computercraft:wired_modem": "Wired Modem",
|
||||
"computercraft:wired_modem_full": "Wired Modem",
|
||||
"computercraft:wireless_modem_advanced": "Ender Modem",
|
||||
"computercraft:wireless_modem_normal": "Wireless Modem",
|
||||
"minecraft:black_dye": "Black Dye",
|
||||
"minecraft:blue_dye": "Blue Dye",
|
||||
"minecraft:brown_dye": "Brown Dye",
|
||||
"minecraft:chest": "Chest",
|
||||
"minecraft:command_block": "Command Block",
|
||||
"minecraft:cyan_dye": "Cyan Dye",
|
||||
"minecraft:ender_eye": "Eye of Ender",
|
||||
"minecraft:ender_pearl": "Ender Pearl",
|
||||
"minecraft:glass_pane": "Glass Pane",
|
||||
"minecraft:gold_block": "Block of Gold",
|
||||
"minecraft:gold_ingot": "Gold Ingot",
|
||||
"minecraft:golden_apple": "Golden Apple",
|
||||
"minecraft:gray_dye": "Gray Dye",
|
||||
"minecraft:green_dye": "Green Dye",
|
||||
"minecraft:iron_ingot": "Iron Ingot",
|
||||
"minecraft:leather": "Leather",
|
||||
"minecraft:light_blue_dye": "Light Blue Dye",
|
||||
"minecraft:light_gray_dye": "Light Gray Dye",
|
||||
"minecraft:lime_dye": "Lime Dye",
|
||||
"minecraft:magenta_dye": "Magenta Dye",
|
||||
"minecraft:note_block": "Note Block",
|
||||
"minecraft:orange_dye": "Orange Dye",
|
||||
"minecraft:pink_dye": "Pink Dye",
|
||||
"minecraft:purple_dye": "Purple Dye",
|
||||
"minecraft:red_dye": "Red Dye",
|
||||
"minecraft:redstone": "Redstone Dust",
|
||||
"minecraft:stone": "Stone",
|
||||
"minecraft:string": "String",
|
||||
"minecraft:white_dye": "White Dye",
|
||||
"minecraft:yellow_dye": "Yellow Dye"
|
||||
},
|
||||
"recipes": {
|
||||
"computercraft:cable": {
|
||||
"inputs": [
|
||||
null,
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
null,
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:redstone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
null,
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
null
|
||||
],
|
||||
"output": "computercraft:cable",
|
||||
"count": 6
|
||||
},
|
||||
"computercraft:computer_advanced": {
|
||||
"inputs": [
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:redstone"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:glass_pane"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
]
|
||||
],
|
||||
"output": "computercraft:computer_advanced",
|
||||
"count": 1
|
||||
},
|
||||
"computercraft:computer_advanced_upgrade": {
|
||||
"inputs": [
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"computercraft:computer_normal"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
null,
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
]
|
||||
],
|
||||
"output": "computercraft:computer_advanced",
|
||||
"count": 1
|
||||
},
|
||||
"computercraft:computer_command": {
|
||||
"inputs": [
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:command_block"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:glass_pane"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
]
|
||||
],
|
||||
"output": "computercraft:computer_command",
|
||||
"count": 1
|
||||
},
|
||||
"computercraft:computer_normal": {
|
||||
"inputs": [
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:redstone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:glass_pane"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
]
|
||||
],
|
||||
"output": "computercraft:computer_normal",
|
||||
"count": 1
|
||||
},
|
||||
"computercraft:disk_drive": {
|
||||
"inputs": [
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:redstone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:redstone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
]
|
||||
],
|
||||
"output": "computercraft:disk_drive",
|
||||
"count": 1
|
||||
},
|
||||
"computercraft:monitor_advanced": {
|
||||
"inputs": [
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:glass_pane"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
]
|
||||
],
|
||||
"output": "computercraft:monitor_advanced",
|
||||
"count": 4
|
||||
},
|
||||
"computercraft:monitor_normal": {
|
||||
"inputs": [
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:glass_pane"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
]
|
||||
],
|
||||
"output": "computercraft:monitor_normal",
|
||||
"count": 1
|
||||
},
|
||||
"computercraft:pocket_computer_advanced": {
|
||||
"inputs": [
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:golden_apple"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:glass_pane"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
]
|
||||
],
|
||||
"output": "computercraft:pocket_computer_advanced",
|
||||
"count": 1
|
||||
},
|
||||
"computercraft:pocket_computer_advanced_upgrade": {
|
||||
"inputs": [
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"computercraft:pocket_computer_normal"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
null,
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
]
|
||||
],
|
||||
"output": "computercraft:pocket_computer_advanced",
|
||||
"count": 1
|
||||
},
|
||||
"computercraft:pocket_computer_normal": {
|
||||
"inputs": [
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:golden_apple"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:glass_pane"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
]
|
||||
],
|
||||
"output": "computercraft:pocket_computer_normal",
|
||||
"count": 1
|
||||
},
|
||||
"computercraft:printed_book": {
|
||||
"inputs": [
|
||||
[
|
||||
"minecraft:leather"
|
||||
],
|
||||
[
|
||||
"computercraft:printed_page"
|
||||
],
|
||||
[
|
||||
"minecraft:string"
|
||||
],
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
],
|
||||
"output": "computercraft:printed_book",
|
||||
"count": 1
|
||||
},
|
||||
"computercraft:printed_pages": {
|
||||
"inputs": [
|
||||
[
|
||||
"computercraft:printed_page"
|
||||
],
|
||||
[
|
||||
"computercraft:printed_page"
|
||||
],
|
||||
[
|
||||
"minecraft:string"
|
||||
],
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
],
|
||||
"output": "computercraft:printed_pages",
|
||||
"count": 1
|
||||
},
|
||||
"computercraft:printer": {
|
||||
"inputs": [
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:redstone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:black_dye",
|
||||
"minecraft:blue_dye",
|
||||
"minecraft:brown_dye",
|
||||
"minecraft:cyan_dye",
|
||||
"minecraft:gray_dye",
|
||||
"minecraft:green_dye",
|
||||
"minecraft:light_blue_dye",
|
||||
"minecraft:light_gray_dye",
|
||||
"minecraft:lime_dye",
|
||||
"minecraft:magenta_dye",
|
||||
"minecraft:orange_dye",
|
||||
"minecraft:pink_dye",
|
||||
"minecraft:purple_dye",
|
||||
"minecraft:red_dye",
|
||||
"minecraft:white_dye",
|
||||
"minecraft:yellow_dye"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
]
|
||||
],
|
||||
"output": "computercraft:printer",
|
||||
"count": 1
|
||||
},
|
||||
"computercraft:speaker": {
|
||||
"inputs": [
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:note_block"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:redstone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
]
|
||||
],
|
||||
"output": "computercraft:speaker",
|
||||
"count": 1
|
||||
},
|
||||
"computercraft:turtle_advanced": {
|
||||
"inputs": [
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"computercraft:computer_advanced"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:chest"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
]
|
||||
],
|
||||
"output": "computercraft:turtle_advanced",
|
||||
"count": 1
|
||||
},
|
||||
"computercraft:turtle_advanced_upgrade": {
|
||||
"inputs": [
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"computercraft:turtle_normal"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
null,
|
||||
[
|
||||
"minecraft:gold_block"
|
||||
],
|
||||
null
|
||||
],
|
||||
"output": "computercraft:turtle_advanced",
|
||||
"count": 1
|
||||
},
|
||||
"computercraft:turtle_normal": {
|
||||
"inputs": [
|
||||
[
|
||||
"minecraft:iron_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:iron_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:iron_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:iron_ingot"
|
||||
],
|
||||
[
|
||||
"computercraft:computer_normal"
|
||||
],
|
||||
[
|
||||
"minecraft:iron_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:iron_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:chest"
|
||||
],
|
||||
[
|
||||
"minecraft:iron_ingot"
|
||||
]
|
||||
],
|
||||
"output": "computercraft:turtle_normal",
|
||||
"count": 1
|
||||
},
|
||||
"computercraft:wired_modem": {
|
||||
"inputs": [
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:redstone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
]
|
||||
],
|
||||
"output": "computercraft:wired_modem",
|
||||
"count": 1
|
||||
},
|
||||
"computercraft:wired_modem_full_from": {
|
||||
"inputs": [
|
||||
[
|
||||
"computercraft:wired_modem"
|
||||
],
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
],
|
||||
"output": "computercraft:wired_modem_full",
|
||||
"count": 1
|
||||
},
|
||||
"computercraft:wired_modem_full_to": {
|
||||
"inputs": [
|
||||
[
|
||||
"computercraft:wired_modem_full"
|
||||
],
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
],
|
||||
"output": "computercraft:wired_modem",
|
||||
"count": 1
|
||||
},
|
||||
"computercraft:wireless_modem_advanced": {
|
||||
"inputs": [
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:ender_eye"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
],
|
||||
[
|
||||
"minecraft:gold_ingot"
|
||||
]
|
||||
],
|
||||
"output": "computercraft:wireless_modem_advanced",
|
||||
"count": 1
|
||||
},
|
||||
"computercraft:wireless_modem_normal": {
|
||||
"inputs": [
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:ender_pearl"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
],
|
||||
[
|
||||
"minecraft:stone"
|
||||
]
|
||||
],
|
||||
"output": "computercraft:wireless_modem_normal",
|
||||
"count": 1
|
||||
}
|
||||
}
|
||||
}
|
BIN
src/web/export/items/computercraft/cable.png
Normal file
After Width: | Height: | Size: 375 B |
BIN
src/web/export/items/computercraft/computer_advanced.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
src/web/export/items/computercraft/computer_command.png
Normal file
After Width: | Height: | Size: 3.1 KiB |
BIN
src/web/export/items/computercraft/computer_normal.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
src/web/export/items/computercraft/disk.png
Normal file
After Width: | Height: | Size: 189 B |
BIN
src/web/export/items/computercraft/disk_drive.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
src/web/export/items/computercraft/monitor_advanced.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
src/web/export/items/computercraft/monitor_normal.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
src/web/export/items/computercraft/pocket_computer_advanced.png
Normal file
After Width: | Height: | Size: 158 B |
BIN
src/web/export/items/computercraft/pocket_computer_normal.png
Normal file
After Width: | Height: | Size: 158 B |
BIN
src/web/export/items/computercraft/printed_book.png
Normal file
After Width: | Height: | Size: 287 B |
BIN
src/web/export/items/computercraft/printed_page.png
Normal file
After Width: | Height: | Size: 208 B |
BIN
src/web/export/items/computercraft/printed_pages.png
Normal file
After Width: | Height: | Size: 259 B |
BIN
src/web/export/items/computercraft/printer.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
src/web/export/items/computercraft/speaker.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
src/web/export/items/computercraft/treasure_disk.png
Normal file
After Width: | Height: | Size: 189 B |
BIN
src/web/export/items/computercraft/turtle_advanced.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/web/export/items/computercraft/turtle_normal.png
Normal file
After Width: | Height: | Size: 977 B |
BIN
src/web/export/items/computercraft/wired_modem.png
Normal file
After Width: | Height: | Size: 593 B |
BIN
src/web/export/items/computercraft/wired_modem_full.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
src/web/export/items/computercraft/wireless_modem_advanced.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
src/web/export/items/computercraft/wireless_modem_normal.png
Normal file
After Width: | Height: | Size: 620 B |
BIN
src/web/export/items/minecraft/black_dye.png
Normal file
After Width: | Height: | Size: 218 B |
BIN
src/web/export/items/minecraft/blue_dye.png
Normal file
After Width: | Height: | Size: 228 B |
BIN
src/web/export/items/minecraft/brown_dye.png
Normal file
After Width: | Height: | Size: 218 B |
BIN
src/web/export/items/minecraft/chest.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/web/export/items/minecraft/command_block.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
src/web/export/items/minecraft/cyan_dye.png
Normal file
After Width: | Height: | Size: 243 B |
BIN
src/web/export/items/minecraft/ender_eye.png
Normal file
After Width: | Height: | Size: 278 B |
BIN
src/web/export/items/minecraft/ender_pearl.png
Normal file
After Width: | Height: | Size: 266 B |
BIN
src/web/export/items/minecraft/glass_pane.png
Normal file
After Width: | Height: | Size: 186 B |
BIN
src/web/export/items/minecraft/gold_block.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
src/web/export/items/minecraft/gold_ingot.png
Normal file
After Width: | Height: | Size: 240 B |
BIN
src/web/export/items/minecraft/golden_apple.png
Normal file
After Width: | Height: | Size: 257 B |
BIN
src/web/export/items/minecraft/gray_dye.png
Normal file
After Width: | Height: | Size: 229 B |
BIN
src/web/export/items/minecraft/green_dye.png
Normal file
After Width: | Height: | Size: 236 B |
BIN
src/web/export/items/minecraft/iron_ingot.png
Normal file
After Width: | Height: | Size: 240 B |
BIN
src/web/export/items/minecraft/leather.png
Normal file
After Width: | Height: | Size: 242 B |
BIN
src/web/export/items/minecraft/light_blue_dye.png
Normal file
After Width: | Height: | Size: 224 B |
BIN
src/web/export/items/minecraft/light_gray_dye.png
Normal file
After Width: | Height: | Size: 229 B |
BIN
src/web/export/items/minecraft/lime_dye.png
Normal file
After Width: | Height: | Size: 221 B |
BIN
src/web/export/items/minecraft/magenta_dye.png
Normal file
After Width: | Height: | Size: 220 B |
BIN
src/web/export/items/minecraft/note_block.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
src/web/export/items/minecraft/orange_dye.png
Normal file
After Width: | Height: | Size: 232 B |
BIN
src/web/export/items/minecraft/pink_dye.png
Normal file
After Width: | Height: | Size: 220 B |
BIN
src/web/export/items/minecraft/purple_dye.png
Normal file
After Width: | Height: | Size: 220 B |
BIN
src/web/export/items/minecraft/red_dye.png
Normal file
After Width: | Height: | Size: 233 B |
BIN
src/web/export/items/minecraft/redstone.png
Normal file
After Width: | Height: | Size: 236 B |
BIN
src/web/export/items/minecraft/stone.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
src/web/export/items/minecraft/string.png
Normal file
After Width: | Height: | Size: 193 B |
BIN
src/web/export/items/minecraft/white_dye.png
Normal file
After Width: | Height: | Size: 245 B |
BIN
src/web/export/items/minecraft/yellow_dye.png
Normal file
After Width: | Height: | Size: 235 B |
@ -9,8 +9,6 @@ import exampleNft from "./mount/example.nft";
|
||||
import exampleAudioLicense from "./mount/example.dfpwm.LICENSE";
|
||||
import exampleAudioUrl from "./mount/example.dfpwm";
|
||||
|
||||
import "./prism.js";
|
||||
|
||||
const defaultFiles: { [filename: string]: string } = {
|
||||
".settings": settingsFile,
|
||||
"startup.lua": startupFile,
|
||||
|
@ -12,7 +12,8 @@ table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table td, table th {
|
||||
table td,
|
||||
table th {
|
||||
border: 1px solid #cccccc;
|
||||
padding: 2px 4px;
|
||||
}
|
||||
@ -38,7 +39,8 @@ pre.highlight {
|
||||
position: fixed;
|
||||
z-index: 200;
|
||||
top: 0px;
|
||||
top: 0px;;
|
||||
top: 0px;
|
||||
;
|
||||
}
|
||||
|
||||
/* Behold, the most cursed CSS! copy-cat's resizing algorithm is a weird, in
|
||||
@ -78,7 +80,9 @@ pre.highlight {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.titlebar-close:hover { background: #cc4c4c; }
|
||||
.titlebar-close:hover {
|
||||
background: #cc4c4c;
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
.computer-container {
|
||||
@ -86,6 +90,79 @@ pre.highlight {
|
||||
height: calc(179px + 40px);
|
||||
}
|
||||
|
||||
.titlebar { height: 20px; }
|
||||
.titlebar-close { font-size: 7px; }
|
||||
.titlebar {
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.titlebar-close {
|
||||
font-size: 7px;
|
||||
}
|
||||
}
|
||||
|
||||
:root {
|
||||
--recipe-bg: #ddd;
|
||||
--recipe-fg: #bbb;
|
||||
--recipe-hover: #aaa;
|
||||
|
||||
--recipe-padding: 4px;
|
||||
--recipe-size: 32px;
|
||||
}
|
||||
|
||||
|
||||
.recipe-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.recipe {
|
||||
display: inline-grid;
|
||||
padding: var(--recipe-padding);
|
||||
|
||||
background: var(--recipe-bg);
|
||||
column-gap: var(--recipe-padding);
|
||||
row-gap: var(--recipe-padding);
|
||||
grid-template-rows: auto auto;
|
||||
grid-template-columns: max-content 1fr max-content;
|
||||
}
|
||||
|
||||
.recipe-title {
|
||||
grid-column-start: span 3;
|
||||
}
|
||||
|
||||
.recipe-inputs {
|
||||
display: inline-grid;
|
||||
column-gap: var(--recipe-padding);
|
||||
row-gap: var(--recipe-padding);
|
||||
align-items: center;
|
||||
grid-template-rows: 1fr 1fr 1fr;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
}
|
||||
|
||||
.recipe-item {
|
||||
padding: var(--recipe-padding);
|
||||
background-color: var(--recipe-fg);
|
||||
}
|
||||
|
||||
.recipe-item:hover {
|
||||
background-color: var(--recipe-hover);
|
||||
}
|
||||
|
||||
.recipe-item > img {
|
||||
display: block;
|
||||
width: var(--recipe-size);
|
||||
height: var(--recipe-size);
|
||||
max-width: 10vw;
|
||||
max-height: 10vw;
|
||||
}
|
||||
|
||||
.recipe-arrow {
|
||||
width: var(--recipe-size);
|
||||
max-width: 10vw;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.recipe-output {
|
||||
/* Hrm! */
|
||||
align-self: center;
|
||||
}
|
||||
|
53
src/web/transform.tsx
Normal file
@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Find all HTML files generated by illuaminate and pipe them through a remark.
|
||||
*
|
||||
* This performs compile-time syntax highlighting and expands our custom
|
||||
* components using React SSR.
|
||||
*
|
||||
* Yes, this would be so much nicer with next.js.
|
||||
*/
|
||||
import * as fs from "fs/promises";
|
||||
import globModule from "glob";
|
||||
import * as path from "path";
|
||||
import { createElement, createElement as h, Fragment } from 'react';
|
||||
import { renderToStaticMarkup } from "react-dom/server";
|
||||
import rehypeHighlight from "rehype-highlight";
|
||||
import rehypeParse from 'rehype-parse';
|
||||
import rehypeReact from 'rehype-react';
|
||||
import { unified } from 'unified';
|
||||
import { promisify } from "util";
|
||||
// Our components
|
||||
import Recipe from "./components/Recipe.js";
|
||||
import { noChildren } from "./components/support.js";
|
||||
import { DataExport, WithExport } from "./components/WithExport.js";
|
||||
|
||||
const glob = promisify(globModule);
|
||||
|
||||
(async () => {
|
||||
const base = "build/docs/lua";
|
||||
|
||||
const processor = unified()
|
||||
.use(rehypeParse, { emitParseErrors: true })
|
||||
.use(rehypeHighlight, { prefix: "" })
|
||||
.use(rehypeReact, {
|
||||
createElement,
|
||||
Fragment,
|
||||
passNode: false,
|
||||
components: {
|
||||
['mc-recipe']: noChildren(Recipe),
|
||||
['mcrecipe']: noChildren(Recipe),
|
||||
} as any
|
||||
});
|
||||
|
||||
const dataExport = JSON.parse(await fs.readFile("src/web/export/index.json", "utf-8")) as DataExport;
|
||||
|
||||
for (const file of await glob(base + "/**/*.html")) {
|
||||
const contents = await fs.readFile(file, "utf-8");
|
||||
|
||||
const { result } = await processor.process(contents);
|
||||
|
||||
const outputPath = path.resolve("build/docs/site", path.relative(base, file));
|
||||
await fs.mkdir(path.dirname(outputPath), { recursive: true });
|
||||
await fs.writeFile(outputPath, "<!doctype HTML>" + renderToStaticMarkup(<WithExport data={dataExport}>{result}</WithExport>));
|
||||
}
|
||||
})();
|
@ -22,6 +22,9 @@
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"importsNotUsedAsValues": "error",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
|
||||
// Needed for some of our internal stuff.
|
||||
"allowSyntheticDefaultImports": true,
|
||||
},
|
||||
"include": [
|
||||
"src/web",
|
||||
|