mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-09-03 10:57:55 +00:00
fix: computer, monitor, disk drive and some turtle are works
This commit is contained in:
13
build.gradle
13
build.gradle
@@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id 'fabric-loom' version '0.7-SNAPSHOT'
|
id 'fabric-loom' version '0.9-SNAPSHOT'
|
||||||
id 'maven-publish'
|
id 'maven-publish'
|
||||||
id "checkstyle"
|
id "checkstyle"
|
||||||
id "com.github.hierynomus.license" version "0.15.0"
|
id "com.github.hierynomus.license" version "0.15.0"
|
||||||
@@ -21,12 +21,17 @@ repositories {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven { url 'https://jitpack.io' }
|
maven { url 'https://jitpack.io' }
|
||||||
maven { url "https://maven.shedaniel.me/" }
|
maven { url "https://maven.shedaniel.me/" }
|
||||||
|
maven { url "https://maven.terraformersmc.com/" }
|
||||||
maven {
|
maven {
|
||||||
name "SquidDev"
|
name "SquidDev"
|
||||||
url "https://squiddev.cc/maven"
|
url "https://squiddev.cc/maven"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loom {
|
||||||
|
accessWidenerPath = file("src/main/resources/cc.accesswidener")
|
||||||
|
}
|
||||||
|
|
||||||
configurations {
|
configurations {
|
||||||
implementation.extendsFrom shade
|
implementation.extendsFrom shade
|
||||||
}
|
}
|
||||||
@@ -42,7 +47,7 @@ dependencies {
|
|||||||
modApi("me.shedaniel.cloth:cloth-config-fabric:${cloth_config_version}") {
|
modApi("me.shedaniel.cloth:cloth-config-fabric:${cloth_config_version}") {
|
||||||
exclude(group: "net.fabricmc.fabric-api")
|
exclude(group: "net.fabricmc.fabric-api")
|
||||||
}
|
}
|
||||||
modImplementation "io.github.prospector:modmenu:${modmenu_version}"
|
modImplementation "com.terraformersmc:modmenu:${modmenu_version}"
|
||||||
modImplementation "me.shedaniel.cloth.api:cloth-utils-v1:${cloth_api_version}"
|
modImplementation "me.shedaniel.cloth.api:cloth-utils-v1:${cloth_api_version}"
|
||||||
|
|
||||||
implementation 'com.electronwill.night-config:toml:3.6.3'
|
implementation 'com.electronwill.night-config:toml:3.6.3'
|
||||||
@@ -55,8 +60,8 @@ dependencies {
|
|||||||
include 'com.electronwill.night-config:toml:3.6.3'
|
include 'com.electronwill.night-config:toml:3.6.3'
|
||||||
include "me.shedaniel.cloth:cloth-config-fabric:${cloth_config_version}"
|
include "me.shedaniel.cloth:cloth-config-fabric:${cloth_config_version}"
|
||||||
|
|
||||||
modRuntime "me.shedaniel:RoughlyEnoughItems-api:6.0.254-alpha"
|
modRuntime "me.shedaniel:RoughlyEnoughItems-api-fabric:6.0.254-alpha"
|
||||||
modRuntime "me.shedaniel:RoughlyEnoughItems:6.0.254-alpha"
|
modRuntime "me.shedaniel:RoughlyEnoughItems-fabric:6.0.254-alpha"
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
processResources {
|
||||||
|
@@ -7,6 +7,7 @@
|
|||||||
package dan200.computercraft;
|
package dan200.computercraft;
|
||||||
|
|
||||||
import dan200.computercraft.api.turtle.event.TurtleAction;
|
import dan200.computercraft.api.turtle.event.TurtleAction;
|
||||||
|
import dan200.computercraft.client.render.MonitorTextureBufferShader;
|
||||||
import dan200.computercraft.core.apis.http.options.Action;
|
import dan200.computercraft.core.apis.http.options.Action;
|
||||||
import dan200.computercraft.core.apis.http.options.AddressRule;
|
import dan200.computercraft.core.apis.http.options.AddressRule;
|
||||||
import dan200.computercraft.shared.common.ColourableRecipe;
|
import dan200.computercraft.shared.common.ColourableRecipe;
|
||||||
@@ -30,6 +31,7 @@ import net.fabricmc.fabric.api.client.itemgroup.FabricItemGroupBuilder;
|
|||||||
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
|
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
|
||||||
import net.fabricmc.fabric.api.resource.ResourcePackActivationType;
|
import net.fabricmc.fabric.api.resource.ResourcePackActivationType;
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
|
import net.minecraft.client.render.*;
|
||||||
import net.minecraft.item.ItemGroup;
|
import net.minecraft.item.ItemGroup;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
@@ -37,6 +39,7 @@ import net.minecraft.util.registry.Registry;
|
|||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
@@ -81,6 +84,7 @@ public final class ComputerCraft implements ModInitializer
|
|||||||
public static int maxNotesPerTick = 8;
|
public static int maxNotesPerTick = 8;
|
||||||
public static MonitorRenderer monitorRenderer = MonitorRenderer.BEST;
|
public static MonitorRenderer monitorRenderer = MonitorRenderer.BEST;
|
||||||
public static double monitorDistanceSq = 4096;
|
public static double monitorDistanceSq = 4096;
|
||||||
|
public static int monitorDistance = 65;
|
||||||
public static long monitorBandwidth = 1_000_000;
|
public static long monitorBandwidth = 1_000_000;
|
||||||
|
|
||||||
public static boolean turtlesNeedFuel = true;
|
public static boolean turtlesNeedFuel = true;
|
||||||
|
@@ -77,7 +77,7 @@ public final class ClientRegistry
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings( "NewExpressionSideOnly" )
|
@SuppressWarnings( "NewExpressionSideOnly" )
|
||||||
public static void onModelBakeEvent( ResourceManager manager, Consumer<ModelIdentifier> out )
|
public static void onModelBakeEvent( ResourceManager manager, Consumer<Identifier> out )
|
||||||
{
|
{
|
||||||
for( String model : EXTRA_MODELS )
|
for( String model : EXTRA_MODELS )
|
||||||
{
|
{
|
||||||
|
@@ -0,0 +1,96 @@
|
|||||||
|
package dan200.computercraft.client.gui;
|
||||||
|
|
||||||
|
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
|
||||||
|
import dan200.computercraft.shared.computer.core.ClientComputer;
|
||||||
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
|
import dan200.computercraft.shared.computer.inventory.ContainerComputerBase;
|
||||||
|
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
||||||
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.text.TranslatableText;
|
||||||
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
public abstract class ComputerScreenBase <T extends ContainerComputerBase> extends HandledScreen<T> {
|
||||||
|
|
||||||
|
private static final Text OK = new TranslatableText( "gui.ok" );
|
||||||
|
private static final Text CANCEL = new TranslatableText( "gui.cancel" );
|
||||||
|
private static final Text OVERWRITE = new TranslatableText( "gui.computercraft.upload.overwrite_button" );
|
||||||
|
|
||||||
|
protected WidgetTerminal terminal;
|
||||||
|
protected final ClientComputer computer;
|
||||||
|
protected final ComputerFamily family;
|
||||||
|
|
||||||
|
protected final int sidebarYOffset = 0;
|
||||||
|
|
||||||
|
public ComputerScreenBase(T container, PlayerInventory player, Text title, int sidebarYOffset )
|
||||||
|
{
|
||||||
|
super( container, player, title );
|
||||||
|
computer = (ClientComputer) container.getComputer();
|
||||||
|
family = container.getFamily();
|
||||||
|
// this.sidebarYOffset = sidebarYOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract WidgetTerminal createTerminal();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final void init()
|
||||||
|
{
|
||||||
|
super.init();
|
||||||
|
client.keyboard.setRepeatEvents( true );
|
||||||
|
|
||||||
|
terminal = addDrawableChild( createTerminal() );
|
||||||
|
// ComputerSidebar.addButtons( this, computer, this::addButton, leftPos, topPos + sidebarYOffset );
|
||||||
|
setFocused( terminal );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void removed()
|
||||||
|
{
|
||||||
|
super.removed();
|
||||||
|
client.keyboard.setRepeatEvents( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void handledScreenTick()
|
||||||
|
{
|
||||||
|
super.handledScreenTick();
|
||||||
|
terminal.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean keyPressed( int key, int scancode, int modifiers )
|
||||||
|
{
|
||||||
|
// Forward the tab key to the terminal, rather than moving between controls.
|
||||||
|
if( key == GLFW.GLFW_KEY_TAB && getFocused() != null && getFocused() == terminal )
|
||||||
|
{
|
||||||
|
return getFocused().keyPressed( key, scancode, modifiers );
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.keyPressed( key, scancode, modifiers );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void render(@Nonnull MatrixStack stack, int mouseX, int mouseY, float partialTicks )
|
||||||
|
{
|
||||||
|
renderBackground( stack );
|
||||||
|
super.render( stack, mouseX, mouseY, partialTicks );
|
||||||
|
drawMouseoverTooltip( stack, mouseX, mouseY );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean mouseDragged( double x, double y, int button, double deltaX, double deltaY )
|
||||||
|
{
|
||||||
|
return (getFocused() != null && getFocused().mouseDragged( x, y, button, deltaX, deltaY ))
|
||||||
|
|| super.mouseDragged( x, y, button, deltaX, deltaY );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drawForeground( @Nonnull MatrixStack transform, int mouseX, int mouseY )
|
||||||
|
{
|
||||||
|
// Skip rendering labels.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -7,9 +7,13 @@
|
|||||||
package dan200.computercraft.client.gui;
|
package dan200.computercraft.client.gui;
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.client.FrameInfo;
|
import dan200.computercraft.client.FrameInfo;
|
||||||
|
import dan200.computercraft.client.render.MonitorTextureBufferShader;
|
||||||
|
import dan200.computercraft.client.render.RenderTypes;
|
||||||
import dan200.computercraft.core.terminal.Terminal;
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
import dan200.computercraft.core.terminal.TextBuffer;
|
import dan200.computercraft.core.terminal.TextBuffer;
|
||||||
|
//import dan200.computercraft.fabric.mixin.RenderLayerAccessor;
|
||||||
import dan200.computercraft.shared.util.Colour;
|
import dan200.computercraft.shared.util.Colour;
|
||||||
import dan200.computercraft.shared.util.Palette;
|
import dan200.computercraft.shared.util.Palette;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
@@ -30,45 +34,17 @@ public final class FixedWidthFontRenderer
|
|||||||
public static final float BACKGROUND_START = (WIDTH - 6.0f) / WIDTH;
|
public static final float BACKGROUND_START = (WIDTH - 6.0f) / WIDTH;
|
||||||
public static final float BACKGROUND_END = (WIDTH - 4.0f) / WIDTH;
|
public static final float BACKGROUND_END = (WIDTH - 4.0f) / WIDTH;
|
||||||
private static final Matrix4f IDENTITY = AffineTransformation.identity()
|
private static final Matrix4f IDENTITY = AffineTransformation.identity()
|
||||||
.getMatrix();
|
.getMatrix();
|
||||||
public static final Identifier FONT = new Identifier( "computercraft", "textures/gui/term_font.png" );
|
public static final Identifier FONT = new Identifier( "computercraft", "textures/gui/term_font.png" );
|
||||||
// public static final RenderLayer TYPE = Type.MAIN;
|
// public static final RenderLayer TYPE = Type.MAIN;
|
||||||
|
// public static final RenderLayer MONITOR_TBO = Type.MONITOR_TBO;
|
||||||
|
// public static final Shader FONT_SHADER = new Shader();
|
||||||
|
|
||||||
|
|
||||||
private FixedWidthFontRenderer()
|
private FixedWidthFontRenderer()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void drawString( float x, float y, @Nonnull TextBuffer text, @Nonnull TextBuffer textColour, @Nullable TextBuffer backgroundColour,
|
|
||||||
@Nonnull Palette palette, boolean greyscale, float leftMarginSize, float rightMarginSize )
|
|
||||||
{
|
|
||||||
bindFont();
|
|
||||||
|
|
||||||
VertexConsumerProvider.Immediate renderer = MinecraftClient.getInstance()
|
|
||||||
.getBufferBuilders()
|
|
||||||
.getEntityVertexConsumers();
|
|
||||||
drawString( IDENTITY,
|
|
||||||
Tessellator.getInstance().getBuffer(),
|
|
||||||
x,
|
|
||||||
y,
|
|
||||||
text,
|
|
||||||
textColour,
|
|
||||||
backgroundColour,
|
|
||||||
palette,
|
|
||||||
greyscale,
|
|
||||||
leftMarginSize,
|
|
||||||
rightMarginSize );
|
|
||||||
renderer.draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void bindFont()
|
|
||||||
{
|
|
||||||
MinecraftClient.getInstance()
|
|
||||||
.getTextureManager()
|
|
||||||
.bindTexture( FONT );
|
|
||||||
RenderSystem.texParameter( GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_CLAMP );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void drawString( @Nonnull Matrix4f transform, @Nonnull VertexConsumer renderer, float x, float y, @Nonnull TextBuffer text,
|
public static void drawString( @Nonnull Matrix4f transform, @Nonnull VertexConsumer renderer, float x, float y, @Nonnull TextBuffer text,
|
||||||
@Nonnull TextBuffer textColour, @Nullable TextBuffer backgroundColour, @Nonnull Palette palette, boolean greyscale,
|
@Nonnull TextBuffer textColour, @Nullable TextBuffer backgroundColour, @Nonnull Palette palette, boolean greyscale,
|
||||||
float leftMarginSize, float rightMarginSize )
|
float leftMarginSize, float rightMarginSize )
|
||||||
@@ -342,12 +318,12 @@ public final class FixedWidthFontRenderer
|
|||||||
public static void drawTerminal( @Nonnull Matrix4f transform, float x, float y, @Nonnull Terminal terminal, boolean greyscale, float topMarginSize,
|
public static void drawTerminal( @Nonnull Matrix4f transform, float x, float y, @Nonnull Terminal terminal, boolean greyscale, float topMarginSize,
|
||||||
float bottomMarginSize, float leftMarginSize, float rightMarginSize )
|
float bottomMarginSize, float leftMarginSize, float rightMarginSize )
|
||||||
{
|
{
|
||||||
bindFont();
|
// bindFont();
|
||||||
|
|
||||||
VertexConsumerProvider.Immediate renderer = MinecraftClient.getInstance()
|
VertexConsumerProvider.Immediate renderer = MinecraftClient.getInstance()
|
||||||
.getBufferBuilders()
|
.getBufferBuilders()
|
||||||
.getEntityVertexConsumers();
|
.getEntityVertexConsumers();
|
||||||
VertexConsumer buffer = Tessellator.getInstance().getBuffer();
|
VertexConsumer buffer = renderer.getBuffer( RenderTypes.TERMINAL_WITH_DEPTH );
|
||||||
drawTerminal( transform, buffer, x, y, terminal, greyscale, topMarginSize, bottomMarginSize, leftMarginSize, rightMarginSize );
|
drawTerminal( transform, buffer, x, y, terminal, greyscale, topMarginSize, bottomMarginSize, leftMarginSize, rightMarginSize );
|
||||||
renderer.draw();
|
renderer.draw();
|
||||||
}
|
}
|
||||||
@@ -360,12 +336,13 @@ public final class FixedWidthFontRenderer
|
|||||||
|
|
||||||
public static void drawEmptyTerminal( float x, float y, float width, float height )
|
public static void drawEmptyTerminal( float x, float y, float width, float height )
|
||||||
{
|
{
|
||||||
|
Colour colour = Colour.BLACK;
|
||||||
drawEmptyTerminal( IDENTITY, x, y, width, height );
|
drawEmptyTerminal( IDENTITY, x, y, width, height );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void drawEmptyTerminal( @Nonnull Matrix4f transform, float x, float y, float width, float height )
|
public static void drawEmptyTerminal( @Nonnull Matrix4f transform, float x, float y, float width, float height )
|
||||||
{
|
{
|
||||||
bindFont();
|
// bindFont();
|
||||||
|
|
||||||
VertexConsumerProvider.Immediate renderer = MinecraftClient.getInstance()
|
VertexConsumerProvider.Immediate renderer = MinecraftClient.getInstance()
|
||||||
.getBufferBuilders()
|
.getBufferBuilders()
|
||||||
@@ -378,44 +355,12 @@ public final class FixedWidthFontRenderer
|
|||||||
float height )
|
float height )
|
||||||
{
|
{
|
||||||
Colour colour = Colour.BLACK;
|
Colour colour = Colour.BLACK;
|
||||||
drawQuad( transform, Tessellator.getInstance().getBuffer(), x, y, width, height, colour.getR(), colour.getG(), colour.getB() );
|
drawQuad( transform, renderer.getBuffer( RenderTypes.TERMINAL_WITH_DEPTH ), x, y, width, height, colour.getR(), colour.getG(), colour.getB() );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void drawBlocker( @Nonnull Matrix4f transform, @Nonnull VertexConsumerProvider renderer, float x, float y, float width, float height )
|
public static void drawBlocker( @Nonnull Matrix4f transform, @Nonnull VertexConsumerProvider renderer, float x, float y, float width, float height )
|
||||||
{
|
{
|
||||||
Colour colour = Colour.BLACK;
|
Colour colour = Colour.BLACK;
|
||||||
drawQuad( transform, Tessellator.getInstance().getBuffer(), x, y, width, height, colour.getR(), colour.getG(), colour.getB() );
|
drawQuad( transform, renderer.getBuffer(RenderTypes.TERMINAL_BLOCKER), x, y, width, height, colour.getR(), colour.getG(), colour.getB() );
|
||||||
}
|
}
|
||||||
|
|
||||||
// private static final class Type extends RenderPhase
|
|
||||||
// {
|
|
||||||
// private static final int GL_MODE = GL11.GL_TRIANGLES;
|
|
||||||
//
|
|
||||||
// private static final VertexFormat FORMAT = VertexFormats.POSITION_COLOR_TEXTURE;
|
|
||||||
//
|
|
||||||
// static final RenderLayer MAIN = RenderLayer.of( "terminal_font", FORMAT, GL_MODE, 1024, false, false, // useDelegate, needsSorting
|
|
||||||
// RenderLayer.MultiPhaseParameters.Builder()
|
|
||||||
// .texture( new RenderPhase.Texture( FONT,
|
|
||||||
// false,
|
|
||||||
// false ) ) // blur, minimap
|
|
||||||
// .transparency( TRANSLUCENT_TRANSPARENCY )
|
|
||||||
// .lightmap( DISABLE_LIGHTMAP )
|
|
||||||
// .writeMaskState( COLOR_MASK )
|
|
||||||
// .build( false ) );
|
|
||||||
//
|
|
||||||
// static final RenderLayer BLOCKER = RenderLayer.of( "terminal_blocker", FORMAT, GL_MODE, 256, false, false, // useDelegate, needsSorting
|
|
||||||
// RenderLayer.MultiPhaseParameters.Builder()
|
|
||||||
// .texture( new RenderPhase.Texture( FONT,
|
|
||||||
// false,
|
|
||||||
// false ) ) // blur, minimap
|
|
||||||
// .transparency( TRANSLUCENT_TRANSPARENCY )
|
|
||||||
// .writeMaskState( ALL_MASK )
|
|
||||||
// .lightmap( DISABLE_LIGHTMAP )
|
|
||||||
// .build( false ) );
|
|
||||||
//
|
|
||||||
// private Type( String name, Runnable setup, Runnable destroy )
|
|
||||||
// {
|
|
||||||
// super( name, setup, destroy );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
@@ -11,6 +11,7 @@ import dan200.computercraft.ComputerCraft;
|
|||||||
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
|
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
|
||||||
import dan200.computercraft.client.gui.widgets.WidgetWrapper;
|
import dan200.computercraft.client.gui.widgets.WidgetWrapper;
|
||||||
import dan200.computercraft.client.render.ComputerBorderRenderer;
|
import dan200.computercraft.client.render.ComputerBorderRenderer;
|
||||||
|
import dan200.computercraft.client.render.RenderTypes;
|
||||||
import dan200.computercraft.shared.computer.core.ClientComputer;
|
import dan200.computercraft.shared.computer.core.ClientComputer;
|
||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import dan200.computercraft.shared.computer.inventory.ContainerComputer;
|
import dan200.computercraft.shared.computer.inventory.ContainerComputer;
|
||||||
@@ -25,29 +26,23 @@ import org.lwjgl.glfw.GLFW;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
import static dan200.computercraft.client.render.ComputerBorderRenderer.BORDER;
|
|
||||||
import static dan200.computercraft.client.render.ComputerBorderRenderer.MARGIN;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class GuiComputer<T extends ContainerComputerBase> extends HandledScreen<T>
|
import static dan200.computercraft.client.render.ComputerBorderRenderer.*;
|
||||||
|
|
||||||
|
public final class GuiComputer<T extends ContainerComputerBase> extends ComputerScreenBase<T>
|
||||||
{
|
{
|
||||||
protected final ComputerFamily family;
|
|
||||||
protected final ClientComputer computer;
|
|
||||||
private final int termWidth;
|
private final int termWidth;
|
||||||
private final int termHeight;
|
private final int termHeight;
|
||||||
|
|
||||||
protected WidgetTerminal terminal;
|
private GuiComputer( T container, PlayerInventory player, Text title, int termWidth, int termHeight )
|
||||||
protected WidgetWrapper terminalWrapper;
|
|
||||||
|
|
||||||
protected GuiComputer( T container, PlayerInventory player, Text title, int termWidth, int termHeight )
|
|
||||||
{
|
{
|
||||||
super( container, player, title );
|
super( container, player, title, BORDER );
|
||||||
this.family = container.getFamily();
|
|
||||||
this.computer = (ClientComputer) container.getComputer();
|
|
||||||
this.termWidth = termWidth;
|
this.termWidth = termWidth;
|
||||||
this.termHeight = termHeight;
|
this.termHeight = termHeight;
|
||||||
this.terminal = null;
|
|
||||||
|
backgroundWidth = WidgetTerminal.getWidth( termWidth ) + BORDER * 2;
|
||||||
|
backgroundHeight = WidgetTerminal.getHeight( termHeight ) + BORDER * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GuiComputer<ContainerComputer> create( ContainerComputer container, PlayerInventory inventory, Text component )
|
public static GuiComputer<ContainerComputer> create( ContainerComputer container, PlayerInventory inventory, Text component )
|
||||||
@@ -65,96 +60,18 @@ public class GuiComputer<T extends ContainerComputerBase> extends HandledScreen<
|
|||||||
return new GuiComputer<>( container, inventory, component, container.getWidth(), container.getHeight() );
|
return new GuiComputer<>( container, inventory, component, container.getWidth(), container.getHeight() );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initTerminal( int border, int widthExtra, int heightExtra )
|
|
||||||
{
|
|
||||||
client.keyboard.setRepeatEvents( true );
|
|
||||||
|
|
||||||
int termPxWidth = termWidth * FixedWidthFontRenderer.FONT_WIDTH;
|
|
||||||
int termPxHeight = termHeight * FixedWidthFontRenderer.FONT_HEIGHT;
|
|
||||||
|
|
||||||
backgroundWidth = termPxWidth + MARGIN * 2 + border * 2 + widthExtra;
|
|
||||||
backgroundHeight = termPxHeight + MARGIN * 2 + border * 2 + heightExtra;
|
|
||||||
|
|
||||||
super.init();
|
|
||||||
|
|
||||||
terminal = new WidgetTerminal( client, () -> computer, termWidth, termHeight, MARGIN, MARGIN, MARGIN, MARGIN );
|
|
||||||
terminalWrapper = new WidgetWrapper( terminal, MARGIN + border + x, MARGIN + border + y, termPxWidth, termPxHeight );
|
|
||||||
|
|
||||||
((List<WidgetWrapper>)children()).add( terminalWrapper ); //FIXME: This is bad.
|
|
||||||
setFocused( terminalWrapper );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void init()
|
protected WidgetTerminal createTerminal()
|
||||||
{
|
{
|
||||||
initTerminal( BORDER, 0, 0 );
|
return new WidgetTerminal( computer,
|
||||||
|
x + BORDER, y + BORDER, termWidth, termHeight
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render( @Nonnull MatrixStack stack, int mouseX, int mouseY, float partialTicks )
|
|
||||||
{
|
|
||||||
this.renderBackground( stack );
|
|
||||||
super.render( stack, mouseX, mouseY, partialTicks );
|
|
||||||
drawMouseoverTooltip( stack, mouseX, mouseY );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void drawForeground( @Nonnull MatrixStack transform, int mouseX, int mouseY )
|
|
||||||
{
|
|
||||||
// Skip rendering labels.
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawBackground( @Nonnull MatrixStack stack, float partialTicks, int mouseX, int mouseY )
|
public void drawBackground( @Nonnull MatrixStack stack, float partialTicks, int mouseX, int mouseY )
|
||||||
{
|
{
|
||||||
// Draw terminal
|
ComputerBorderRenderer.render(
|
||||||
terminal.draw( terminalWrapper.getX(), terminalWrapper.getY() );
|
getTexture(family), terminal.x, terminal.y, getZOffset(),
|
||||||
|
RenderTypes.FULL_BRIGHT_LIGHTMAP, terminal.getWidth(), terminal.getHeight() );
|
||||||
// Draw a border around the terminal
|
|
||||||
RenderSystem.clearColor( 1, 1, 1, 1 );
|
|
||||||
client.getTextureManager()
|
|
||||||
.bindTexture( ComputerBorderRenderer.getTexture( family ) );
|
|
||||||
ComputerBorderRenderer.render( terminalWrapper.getX() - MARGIN, terminalWrapper.getY() - MARGIN,
|
|
||||||
getZOffset(), terminalWrapper.getWidth() + MARGIN * 2, terminalWrapper.getHeight() + MARGIN * 2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean mouseDragged( double x, double y, int button, double deltaX, double deltaY )
|
|
||||||
{
|
|
||||||
return (getFocused() != null && getFocused().mouseDragged( x, y, button, deltaX, deltaY )) || super.mouseDragged( x, y, button, deltaX, deltaY );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean mouseReleased( double mouseX, double mouseY, int button )
|
|
||||||
{
|
|
||||||
return (getFocused() != null && getFocused().mouseReleased( mouseX, mouseY, button )) || super.mouseReleased( x, y, button );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean keyPressed( int key, int scancode, int modifiers )
|
|
||||||
{
|
|
||||||
// Forward the tab key to the terminal, rather than moving between controls.
|
|
||||||
if( key == GLFW.GLFW_KEY_TAB && getFocused() != null && getFocused() == terminalWrapper )
|
|
||||||
{
|
|
||||||
return getFocused().keyPressed( key, scancode, modifiers );
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.keyPressed( key, scancode, modifiers );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removed()
|
|
||||||
{
|
|
||||||
super.removed();
|
|
||||||
children().remove( terminal );
|
|
||||||
terminal = null;
|
|
||||||
client.keyboard.setRepeatEvents( false );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void handledScreenTick()
|
|
||||||
{
|
|
||||||
super.handledScreenTick(); // FIXME most likely unneeded.
|
|
||||||
terminal.update();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,8 +7,10 @@
|
|||||||
package dan200.computercraft.client.gui;
|
package dan200.computercraft.client.gui;
|
||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
import dan200.computercraft.client.render.ComputerBorderRenderer;
|
||||||
import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive;
|
import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive;
|
||||||
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
import net.minecraft.client.gui.screen.ingame.HandledScreen;
|
||||||
|
import net.minecraft.client.render.GameRenderer;
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
import net.minecraft.entity.player.PlayerInventory;
|
import net.minecraft.entity.player.PlayerInventory;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
@@ -36,9 +38,9 @@ public class GuiDiskDrive extends HandledScreen<ContainerDiskDrive>
|
|||||||
@Override
|
@Override
|
||||||
protected void drawBackground( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY )
|
protected void drawBackground( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY )
|
||||||
{
|
{
|
||||||
RenderSystem.clearColor( 1.0F, 1.0F, 1.0F, 1.0F );
|
RenderSystem.setShader(GameRenderer::getPositionTexShader);
|
||||||
client.getTextureManager()
|
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
|
||||||
.bindTexture( BACKGROUND );
|
RenderSystem.setShaderTexture(0, BACKGROUND);
|
||||||
drawTexture( transform, x, y, 0, 0, backgroundWidth, backgroundHeight );
|
drawTexture( transform, x, y, 0, 0, backgroundWidth, backgroundHeight );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,8 @@ package dan200.computercraft.client.gui;
|
|||||||
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
|
import dan200.computercraft.client.gui.widgets.WidgetTerminal;
|
||||||
|
import dan200.computercraft.client.render.ComputerBorderRenderer;
|
||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import dan200.computercraft.shared.turtle.inventory.ContainerTurtle;
|
import dan200.computercraft.shared.turtle.inventory.ContainerTurtle;
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
@@ -17,40 +19,51 @@ import net.minecraft.util.Identifier;
|
|||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
public class GuiTurtle extends GuiComputer<ContainerTurtle>
|
import static dan200.computercraft.shared.turtle.inventory.ContainerTurtle.BORDER;
|
||||||
|
|
||||||
|
public class GuiTurtle extends ComputerScreenBase<ContainerTurtle>
|
||||||
{
|
{
|
||||||
private static final Identifier BACKGROUND_NORMAL = new Identifier( "computercraft", "textures/gui/turtle_normal.png" );
|
private static final Identifier BACKGROUND_NORMAL = new Identifier( "computercraft", "textures/gui/turtle_normal.png" );
|
||||||
private static final Identifier BACKGROUND_ADVANCED = new Identifier( "computercraft", "textures/gui/turtle_advanced.png" );
|
private static final Identifier BACKGROUND_ADVANCED = new Identifier( "computercraft", "textures/gui/turtle_advanced.png" );
|
||||||
private final ContainerTurtle container;
|
|
||||||
|
private static final int TEX_WIDTH = 254;
|
||||||
|
private static final int TEX_HEIGHT = 217;
|
||||||
|
|
||||||
|
private final ComputerFamily family;
|
||||||
|
|
||||||
public GuiTurtle( ContainerTurtle container, PlayerInventory player, Text title )
|
public GuiTurtle( ContainerTurtle container, PlayerInventory player, Text title )
|
||||||
{
|
{
|
||||||
super( container, player, title, ComputerCraft.turtleTermWidth, ComputerCraft.turtleTermHeight );
|
super( container, player, title, BORDER );
|
||||||
|
|
||||||
this.container = container;
|
family = container.getFamily();
|
||||||
|
backgroundWidth = TEX_WIDTH;
|
||||||
|
backgroundHeight = TEX_HEIGHT;
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public boolean mouseClicked(double mouseX, double mouseY, int button) {
|
||||||
|
System.out.println(mouseX + " " + mouseY + " " + button);
|
||||||
|
return super.mouseClicked(mouseX, mouseY, button);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void init()
|
protected WidgetTerminal createTerminal()
|
||||||
{
|
{
|
||||||
initTerminal( 8, 0, 80 );
|
return new WidgetTerminal(
|
||||||
|
computer, x + BORDER, y + BORDER,
|
||||||
|
ComputerCraft.turtleTermWidth, ComputerCraft.turtleTermHeight
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void drawBackground( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY )
|
public void drawBackground( @Nonnull MatrixStack transform, float partialTicks, int mouseX, int mouseY )
|
||||||
{
|
{
|
||||||
// Draw term
|
boolean advanced = family == ComputerFamily.ADVANCED;
|
||||||
Identifier texture = family == ComputerFamily.ADVANCED ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL;
|
RenderSystem.setShaderTexture( 0, advanced ? BACKGROUND_ADVANCED : BACKGROUND_NORMAL );
|
||||||
terminal.draw( terminalWrapper.getX(), terminalWrapper.getY() );
|
drawTexture( transform, x, y, 0, 0, TEX_WIDTH, TEX_HEIGHT );
|
||||||
|
|
||||||
// Draw border/inventory
|
|
||||||
RenderSystem.clearColor( 1.0F, 1.0F, 1.0F, 1.0F );
|
|
||||||
client.getTextureManager()
|
|
||||||
.bindTexture( texture );
|
|
||||||
drawTexture( transform, x, y, 0, 0, backgroundWidth, backgroundHeight );
|
|
||||||
|
|
||||||
// Draw selection slot
|
// Draw selection slot
|
||||||
int slot = container.getSelectedSlot();
|
int slot = getScreenHandler().getSelectedSlot();
|
||||||
if( slot >= 0 )
|
if( slot >= 0 )
|
||||||
{
|
{
|
||||||
int slotX = slot % 4;
|
int slotX = slot % 4;
|
||||||
@@ -61,5 +74,7 @@ public class GuiTurtle extends GuiComputer<ContainerTurtle>
|
|||||||
24,
|
24,
|
||||||
24 );
|
24 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RenderSystem.setShaderTexture( 0, advanced ? ComputerBorderRenderer.BACKGROUND_ADVANCED : ComputerBorderRenderer.BACKGROUND_NORMAL );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,57 +8,67 @@ package dan200.computercraft.client.gui.widgets;
|
|||||||
|
|
||||||
import dan200.computercraft.client.gui.FixedWidthFontRenderer;
|
import dan200.computercraft.client.gui.FixedWidthFontRenderer;
|
||||||
import dan200.computercraft.core.terminal.Terminal;
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
|
import dan200.computercraft.shared.command.text.ChatHelpers;
|
||||||
import dan200.computercraft.shared.computer.core.ClientComputer;
|
import dan200.computercraft.shared.computer.core.ClientComputer;
|
||||||
import dan200.computercraft.shared.computer.core.IComputer;
|
import dan200.computercraft.shared.computer.core.IComputer;
|
||||||
import net.minecraft.SharedConstants;
|
import net.minecraft.SharedConstants;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
import net.minecraft.client.gui.Element;
|
import net.minecraft.client.gui.Element;
|
||||||
|
import net.minecraft.client.gui.screen.narration.NarrationMessageBuilder;
|
||||||
|
import net.minecraft.client.gui.widget.ClickableWidget;
|
||||||
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
|
import net.minecraft.text.LiteralText;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.ChatUtil;
|
||||||
|
import net.minecraft.util.math.Matrix4f;
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
import java.util.BitSet;
|
import java.util.BitSet;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT;
|
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_HEIGHT;
|
||||||
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH;
|
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.FONT_WIDTH;
|
||||||
|
import static dan200.computercraft.client.render.ComputerBorderRenderer.MARGIN;
|
||||||
|
|
||||||
public class WidgetTerminal implements Element
|
public class WidgetTerminal extends ClickableWidget {
|
||||||
{
|
|
||||||
private static final float TERMINATE_TIME = 0.5f;
|
private static final float TERMINATE_TIME = 0.5f;
|
||||||
|
|
||||||
private final MinecraftClient client;
|
// private final MinecraftClient client;
|
||||||
private final Supplier<ClientComputer> computer;
|
private final ClientComputer computer;
|
||||||
private final int termWidth;
|
|
||||||
private final int termHeight;
|
// The positions of the actual terminal
|
||||||
private final int leftMargin;
|
private final int innerX;
|
||||||
private final int rightMargin;
|
private final int innerY;
|
||||||
private final int topMargin;
|
private final int innerWidth;
|
||||||
private final int bottomMargin;
|
private final int innerHeight;
|
||||||
|
|
||||||
private final BitSet keysDown = new BitSet( 256 );
|
private final BitSet keysDown = new BitSet( 256 );
|
||||||
private boolean focused;
|
// private boolean focused;
|
||||||
private float terminateTimer = -1;
|
private float terminateTimer = -1;
|
||||||
private float rebootTimer = -1;
|
private float rebootTimer = -1;
|
||||||
private float shutdownTimer = -1;
|
private float shutdownTimer = -1;
|
||||||
|
|
||||||
private int lastMouseButton = -1;
|
private int lastMouseButton = -1;
|
||||||
private int lastMouseX = -1;
|
private int lastMouseX = -1;
|
||||||
private int lastMouseY = -1;
|
private int lastMouseY = -1;
|
||||||
|
|
||||||
public WidgetTerminal( MinecraftClient client, Supplier<ClientComputer> computer, int termWidth, int termHeight, int leftMargin, int rightMargin,
|
public WidgetTerminal( @Nonnull ClientComputer computer, int x, int y, int termWidth, int termHeight )
|
||||||
int topMargin, int bottomMargin )
|
|
||||||
{
|
{
|
||||||
this.client = client;
|
super( x, y, termWidth * FONT_WIDTH + MARGIN * 2, termHeight * FONT_HEIGHT + MARGIN * 2, LiteralText.EMPTY);
|
||||||
|
|
||||||
this.computer = computer;
|
this.computer = computer;
|
||||||
this.termWidth = termWidth;
|
|
||||||
this.termHeight = termHeight;
|
innerX = x + MARGIN;
|
||||||
this.leftMargin = leftMargin;
|
innerY = y + MARGIN;
|
||||||
this.rightMargin = rightMargin;
|
innerWidth = termWidth * FONT_WIDTH;
|
||||||
this.topMargin = topMargin;
|
innerHeight = termHeight * FONT_HEIGHT;
|
||||||
this.bottomMargin = bottomMargin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean mouseClicked( double mouseX, double mouseY, int button )
|
public boolean mouseClicked( double mouseX, double mouseY, int button )
|
||||||
{
|
{
|
||||||
ClientComputer computer = this.computer.get();
|
ClientComputer computer = this.computer;
|
||||||
if( computer == null || !computer.isColour() || button < 0 || button > 2 )
|
if( computer == null || !computer.isColour() || button < 0 || button > 2 )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -85,7 +95,7 @@ public class WidgetTerminal implements Element
|
|||||||
@Override
|
@Override
|
||||||
public boolean mouseReleased( double mouseX, double mouseY, int button )
|
public boolean mouseReleased( double mouseX, double mouseY, int button )
|
||||||
{
|
{
|
||||||
ClientComputer computer = this.computer.get();
|
ClientComputer computer = this.computer;
|
||||||
if( computer == null || !computer.isColour() || button < 0 || button > 2 )
|
if( computer == null || !computer.isColour() || button < 0 || button > 2 )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -115,7 +125,7 @@ public class WidgetTerminal implements Element
|
|||||||
@Override
|
@Override
|
||||||
public boolean mouseDragged( double mouseX, double mouseY, int button, double v2, double v3 )
|
public boolean mouseDragged( double mouseX, double mouseY, int button, double v2, double v3 )
|
||||||
{
|
{
|
||||||
ClientComputer computer = this.computer.get();
|
ClientComputer computer = this.computer;
|
||||||
if( computer == null || !computer.isColour() || button < 0 || button > 2 )
|
if( computer == null || !computer.isColour() || button < 0 || button > 2 )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -143,7 +153,7 @@ public class WidgetTerminal implements Element
|
|||||||
@Override
|
@Override
|
||||||
public boolean mouseScrolled( double mouseX, double mouseY, double delta )
|
public boolean mouseScrolled( double mouseX, double mouseY, double delta )
|
||||||
{
|
{
|
||||||
ClientComputer computer = this.computer.get();
|
ClientComputer computer = this.computer;
|
||||||
if( computer == null || !computer.isColour() || delta == 0 )
|
if( computer == null || !computer.isColour() || delta == 0 )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@@ -198,7 +208,7 @@ public class WidgetTerminal implements Element
|
|||||||
|
|
||||||
case GLFW.GLFW_KEY_V:
|
case GLFW.GLFW_KEY_V:
|
||||||
// Ctrl+V for paste
|
// Ctrl+V for paste
|
||||||
String clipboard = client.keyboard.getClipboard();
|
String clipboard = MinecraftClient.getInstance().keyboard.getClipboard();
|
||||||
if( clipboard != null )
|
if( clipboard != null )
|
||||||
{
|
{
|
||||||
// Clip to the first occurrence of \r or \n
|
// Clip to the first occurrence of \r or \n
|
||||||
@@ -239,7 +249,7 @@ public class WidgetTerminal implements Element
|
|||||||
// Queue the "key" event and add to the down set
|
// Queue the "key" event and add to the down set
|
||||||
boolean repeat = keysDown.get( key );
|
boolean repeat = keysDown.get( key );
|
||||||
keysDown.set( key );
|
keysDown.set( key );
|
||||||
IComputer computer = this.computer.get();
|
IComputer computer = this.computer;
|
||||||
if( computer != null )
|
if( computer != null )
|
||||||
{
|
{
|
||||||
computer.keyDown( key, repeat );
|
computer.keyDown( key, repeat );
|
||||||
@@ -256,7 +266,7 @@ public class WidgetTerminal implements Element
|
|||||||
if( key >= 0 && keysDown.get( key ) )
|
if( key >= 0 && keysDown.get( key ) )
|
||||||
{
|
{
|
||||||
keysDown.set( key, false );
|
keysDown.set( key, false );
|
||||||
IComputer computer = this.computer.get();
|
IComputer computer = this.computer;
|
||||||
if( computer != null )
|
if( computer != null )
|
||||||
{
|
{
|
||||||
computer.keyUp( key );
|
computer.keyUp( key );
|
||||||
@@ -296,35 +306,26 @@ public class WidgetTerminal implements Element
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean changeFocus( boolean reversed )
|
public void onFocusedChanged( boolean focused )
|
||||||
{
|
{
|
||||||
if( focused )
|
if( !focused )
|
||||||
{
|
{
|
||||||
// When blurring, we should make all keys go up
|
// When blurring, we should make all keys go up
|
||||||
for( int key = 0; key < keysDown.size(); key++ )
|
for( int key = 0; key < keysDown.size(); key++ )
|
||||||
{
|
{
|
||||||
if( keysDown.get( key ) )
|
if( keysDown.get( key ) ) computer.keyUp( key );
|
||||||
{
|
|
||||||
queueEvent( "key_up", key );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
keysDown.clear();
|
keysDown.clear();
|
||||||
|
|
||||||
// When blurring, we should make the last mouse button go up
|
// When blurring, we should make the last mouse button go up
|
||||||
if( lastMouseButton > 0 )
|
if( lastMouseButton > 0 )
|
||||||
{
|
{
|
||||||
IComputer computer = this.computer.get();
|
computer.mouseUp( lastMouseButton + 1, lastMouseX + 1, lastMouseY + 1 );
|
||||||
if( computer != null )
|
|
||||||
{
|
|
||||||
computer.mouseUp( lastMouseButton + 1, lastMouseX + 1, lastMouseY + 1 );
|
|
||||||
}
|
|
||||||
lastMouseButton = -1;
|
lastMouseButton = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
shutdownTimer = terminateTimer = rebootTimer = -1;
|
shutdownTimer = terminateTimer = rebootTimer = -1;
|
||||||
}
|
}
|
||||||
focused = !focused;
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -335,7 +336,7 @@ public class WidgetTerminal implements Element
|
|||||||
|
|
||||||
private void queueEvent( String event, Object... args )
|
private void queueEvent( String event, Object... args )
|
||||||
{
|
{
|
||||||
ClientComputer computer = this.computer.get();
|
ClientComputer computer = this.computer;
|
||||||
if( computer != null )
|
if( computer != null )
|
||||||
{
|
{
|
||||||
computer.queueEvent( event, args );
|
computer.queueEvent( event, args );
|
||||||
@@ -351,7 +352,7 @@ public class WidgetTerminal implements Element
|
|||||||
|
|
||||||
if( shutdownTimer >= 0 && shutdownTimer < TERMINATE_TIME && (shutdownTimer += 0.05f) > TERMINATE_TIME )
|
if( shutdownTimer >= 0 && shutdownTimer < TERMINATE_TIME && (shutdownTimer += 0.05f) > TERMINATE_TIME )
|
||||||
{
|
{
|
||||||
ClientComputer computer = this.computer.get();
|
ClientComputer computer = this.computer;
|
||||||
if( computer != null )
|
if( computer != null )
|
||||||
{
|
{
|
||||||
computer.shutdown();
|
computer.shutdown();
|
||||||
@@ -360,7 +361,7 @@ public class WidgetTerminal implements Element
|
|||||||
|
|
||||||
if( rebootTimer >= 0 && rebootTimer < TERMINATE_TIME && (rebootTimer += 0.05f) > TERMINATE_TIME )
|
if( rebootTimer >= 0 && rebootTimer < TERMINATE_TIME && (rebootTimer += 0.05f) > TERMINATE_TIME )
|
||||||
{
|
{
|
||||||
ClientComputer computer = this.computer.get();
|
ClientComputer computer = this.computer;
|
||||||
if( computer != null )
|
if( computer != null )
|
||||||
{
|
{
|
||||||
computer.reboot();
|
computer.reboot();
|
||||||
@@ -370,31 +371,41 @@ public class WidgetTerminal implements Element
|
|||||||
|
|
||||||
private void queueEvent( String event )
|
private void queueEvent( String event )
|
||||||
{
|
{
|
||||||
ClientComputer computer = this.computer.get();
|
ClientComputer computer = this.computer;
|
||||||
if( computer != null )
|
if( computer != null )
|
||||||
{
|
{
|
||||||
computer.queueEvent( event );
|
computer.queueEvent( event );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void draw( int originX, int originY )
|
@Override
|
||||||
|
public void render(@Nonnull MatrixStack transform, int mouseX, int mouseY, float partialTicks )
|
||||||
{
|
{
|
||||||
synchronized( computer )
|
if( !visible ) return;
|
||||||
|
Matrix4f matrix = transform.peek().getModel();
|
||||||
|
Terminal terminal = computer.getTerminal();
|
||||||
|
if( terminal != null )
|
||||||
{
|
{
|
||||||
// Draw the screen contents
|
FixedWidthFontRenderer.drawTerminal( matrix, innerX, innerY, terminal, !computer.isColour(), MARGIN, MARGIN, MARGIN, MARGIN );
|
||||||
ClientComputer computer = this.computer.get();
|
}
|
||||||
Terminal terminal = computer != null ? computer.getTerminal() : null;
|
else
|
||||||
if( terminal != null )
|
{
|
||||||
{
|
FixedWidthFontRenderer.drawEmptyTerminal( matrix, x, y, width, height );
|
||||||
FixedWidthFontRenderer.drawTerminal( originX, originY, terminal, !computer.isColour(), topMargin, bottomMargin, leftMargin,
|
|
||||||
rightMargin );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FixedWidthFontRenderer.drawEmptyTerminal( originX - leftMargin,
|
|
||||||
originY - rightMargin, termWidth * FONT_WIDTH + leftMargin + rightMargin,
|
|
||||||
termHeight * FONT_HEIGHT + topMargin + bottomMargin );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void appendNarrations(NarrationMessageBuilder builder) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getWidth( int termWidth )
|
||||||
|
{
|
||||||
|
return termWidth * FONT_WIDTH + MARGIN * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getHeight( int termHeight )
|
||||||
|
{
|
||||||
|
return termHeight * FONT_HEIGHT + MARGIN * 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,7 @@ import dan200.computercraft.shared.ComputerCraftRegistry;
|
|||||||
import dan200.computercraft.shared.common.ContainerHeldItem;
|
import dan200.computercraft.shared.common.ContainerHeldItem;
|
||||||
import dan200.computercraft.shared.common.IColouredItem;
|
import dan200.computercraft.shared.common.IColouredItem;
|
||||||
import dan200.computercraft.shared.common.TileGeneric;
|
import dan200.computercraft.shared.common.TileGeneric;
|
||||||
|
import dan200.computercraft.shared.computer.blocks.TileComputer;
|
||||||
import dan200.computercraft.shared.computer.inventory.ContainerComputer;
|
import dan200.computercraft.shared.computer.inventory.ContainerComputer;
|
||||||
import dan200.computercraft.shared.computer.inventory.ContainerViewComputer;
|
import dan200.computercraft.shared.computer.inventory.ContainerViewComputer;
|
||||||
import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive;
|
import dan200.computercraft.shared.peripheral.diskdrive.ContainerDiskDrive;
|
||||||
@@ -34,6 +35,7 @@ import net.fabricmc.api.Environment;
|
|||||||
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
|
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
|
||||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientBlockEntityEvents;
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientBlockEntityEvents;
|
||||||
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
|
||||||
|
//import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry;
|
||||||
import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry;
|
import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry;
|
||||||
import net.fabricmc.fabric.api.client.rendering.v1.BlockEntityRendererRegistry;
|
import net.fabricmc.fabric.api.client.rendering.v1.BlockEntityRendererRegistry;
|
||||||
import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry;
|
import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry;
|
||||||
@@ -77,7 +79,6 @@ public final class ComputerCraftProxyClient implements ClientModInitializer
|
|||||||
// While turtles themselves are not transparent, their upgrades may be.
|
// While turtles themselves are not transparent, their upgrades may be.
|
||||||
BlockRenderLayerMap.INSTANCE.putBlock( ComputerCraftRegistry.ModBlocks.TURTLE_NORMAL, RenderLayer.getTranslucent() );
|
BlockRenderLayerMap.INSTANCE.putBlock( ComputerCraftRegistry.ModBlocks.TURTLE_NORMAL, RenderLayer.getTranslucent() );
|
||||||
BlockRenderLayerMap.INSTANCE.putBlock( ComputerCraftRegistry.ModBlocks.TURTLE_ADVANCED, RenderLayer.getTranslucent() );
|
BlockRenderLayerMap.INSTANCE.putBlock( ComputerCraftRegistry.ModBlocks.TURTLE_ADVANCED, RenderLayer.getTranslucent() );
|
||||||
|
|
||||||
// Monitors' textures have transparent fronts and so count as cutouts.
|
// Monitors' textures have transparent fronts and so count as cutouts.
|
||||||
BlockRenderLayerMap.INSTANCE.putBlock( ComputerCraftRegistry.ModBlocks.MONITOR_NORMAL, RenderLayer.getCutout() );
|
BlockRenderLayerMap.INSTANCE.putBlock( ComputerCraftRegistry.ModBlocks.MONITOR_NORMAL, RenderLayer.getCutout() );
|
||||||
BlockRenderLayerMap.INSTANCE.putBlock( ComputerCraftRegistry.ModBlocks.MONITOR_ADVANCED, RenderLayer.getCutout() );
|
BlockRenderLayerMap.INSTANCE.putBlock( ComputerCraftRegistry.ModBlocks.MONITOR_ADVANCED, RenderLayer.getCutout() );
|
||||||
@@ -90,7 +91,7 @@ public final class ComputerCraftProxyClient implements ClientModInitializer
|
|||||||
|
|
||||||
ClientSpriteRegistryCallback.event( PlayerScreenHandler.BLOCK_ATLAS_TEXTURE )
|
ClientSpriteRegistryCallback.event( PlayerScreenHandler.BLOCK_ATLAS_TEXTURE )
|
||||||
.register( ClientRegistry::onTextureStitchEvent );
|
.register( ClientRegistry::onTextureStitchEvent );
|
||||||
ModelLoadingRegistry.INSTANCE.registerAppender( ClientRegistry::onModelBakeEvent );
|
ModelLoadingRegistry.INSTANCE.registerModelProvider( ClientRegistry::onModelBakeEvent );
|
||||||
ModelLoadingRegistry.INSTANCE.registerResourceProvider( loader -> ( name, context ) -> TurtleModelLoader.INSTANCE.accepts( name ) ?
|
ModelLoadingRegistry.INSTANCE.registerResourceProvider( loader -> ( name, context ) -> TurtleModelLoader.INSTANCE.accepts( name ) ?
|
||||||
TurtleModelLoader.INSTANCE.loadModel(
|
TurtleModelLoader.INSTANCE.loadModel(
|
||||||
name ) : null );
|
name ) : null );
|
||||||
|
@@ -8,11 +8,7 @@ package dan200.computercraft.client.render;
|
|||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import net.minecraft.client.render.BufferBuilder;
|
import net.minecraft.client.render.*;
|
||||||
import net.minecraft.client.render.Tessellator;
|
|
||||||
import net.minecraft.client.render.VertexConsumer;
|
|
||||||
import net.minecraft.client.render.VertexFormat;
|
|
||||||
import net.minecraft.client.render.VertexFormats;
|
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.math.Matrix4f;
|
import net.minecraft.util.math.Matrix4f;
|
||||||
import org.lwjgl.opengl.GL11;
|
import org.lwjgl.opengl.GL11;
|
||||||
@@ -55,11 +51,14 @@ public class ComputerBorderRenderer
|
|||||||
private final int z;
|
private final int z;
|
||||||
private final float r, g, b;
|
private final float r, g, b;
|
||||||
|
|
||||||
public ComputerBorderRenderer( Matrix4f transform, VertexConsumer builder, int z, float r, float g, float b )
|
private final int light;
|
||||||
|
|
||||||
|
public ComputerBorderRenderer( Matrix4f transform, VertexConsumer builder, int z, int light, float r, float g, float b )
|
||||||
{
|
{
|
||||||
this.transform = transform;
|
this.transform = transform;
|
||||||
this.builder = builder;
|
this.builder = builder;
|
||||||
this.z = z;
|
this.z = z;
|
||||||
|
this.light = light;
|
||||||
this.r = r;
|
this.r = r;
|
||||||
this.g = g;
|
this.g = g;
|
||||||
this.b = b;
|
this.b = b;
|
||||||
@@ -81,31 +80,17 @@ public class ComputerBorderRenderer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void render( int x, int y, int z, int width, int height )
|
public static void render(Identifier location, int x, int y, int z, int light, int width, int height )
|
||||||
{
|
{
|
||||||
Tessellator tessellator = Tessellator.getInstance();
|
VertexConsumerProvider.Immediate source = VertexConsumerProvider.immediate(Tessellator.getInstance().getBuffer());
|
||||||
BufferBuilder buffer = tessellator.getBuffer();
|
render( IDENTITY, source.getBuffer(RenderLayer.getText(location)), x, y, z, light, width, height, false, 1, 1, 1 );
|
||||||
buffer.begin( VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR_TEXTURE );
|
source.draw();
|
||||||
|
|
||||||
render( IDENTITY, buffer, x, y, z, width, height );
|
|
||||||
|
|
||||||
// RenderSystem.enableDepthTest(); //TODO: enableAlphaTest(). FIXME
|
|
||||||
tessellator.draw();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void render( Matrix4f transform, VertexConsumer buffer, int x, int y, int z, int width, int height )
|
|
||||||
{
|
|
||||||
render( transform, buffer, x, y, z, width, height, 1, 1, 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void render( Matrix4f transform, VertexConsumer buffer, int x, int y, int z, int width, int height, float r, float g, float b )
|
public static void render( Matrix4f transform, VertexConsumer buffer, int x, int y, int z, int light, int width, int height, boolean withLight, float r, float g, float b )
|
||||||
{
|
{
|
||||||
render( transform, buffer, x, y, z, width, height, false, r, g, b );
|
new ComputerBorderRenderer( transform, buffer, z, light, r, g, b ).doRender( x, y, width, height, withLight );
|
||||||
}
|
|
||||||
|
|
||||||
public static void render( Matrix4f transform, VertexConsumer buffer, int x, int y, int z, int width, int height, boolean withLight, float r, float g, float b )
|
|
||||||
{
|
|
||||||
new ComputerBorderRenderer( transform, buffer, z, r, g, b ).doRender( x, y, width, height, withLight );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doRender( int x, int y, int width, int height, boolean withLight )
|
public void doRender( int x, int y, int width, int height, boolean withLight )
|
||||||
@@ -158,18 +143,22 @@ public class ComputerBorderRenderer
|
|||||||
builder.vertex( transform, x, y + height, z )
|
builder.vertex( transform, x, y + height, z )
|
||||||
.color( r, g, b, 1.0f )
|
.color( r, g, b, 1.0f )
|
||||||
.texture( u * TEX_SCALE, (v + textureHeight) * TEX_SCALE )
|
.texture( u * TEX_SCALE, (v + textureHeight) * TEX_SCALE )
|
||||||
|
.light(light)
|
||||||
.next();
|
.next();
|
||||||
builder.vertex( transform, x + width, y + height, z )
|
builder.vertex( transform, x + width, y + height, z )
|
||||||
.color( r, g, b, 1.0f )
|
.color( r, g, b, 1.0f )
|
||||||
.texture( (u + textureWidth) * TEX_SCALE, (v + textureHeight) * TEX_SCALE )
|
.texture( (u + textureWidth) * TEX_SCALE, (v + textureHeight) * TEX_SCALE )
|
||||||
|
.light(light)
|
||||||
.next();
|
.next();
|
||||||
builder.vertex( transform, x + width, y, z )
|
builder.vertex( transform, x + width, y, z )
|
||||||
.color( r, g, b, 1.0f )
|
.color( r, g, b, 1.0f )
|
||||||
.texture( (u + textureWidth) * TEX_SCALE, v * TEX_SCALE )
|
.texture( (u + textureWidth) * TEX_SCALE, v * TEX_SCALE )
|
||||||
|
.light(light)
|
||||||
.next();
|
.next();
|
||||||
builder.vertex( transform, x, y, z )
|
builder.vertex( transform, x, y, z )
|
||||||
.color( r, g, b, 1.0f )
|
.color( r, g, b, 1.0f )
|
||||||
.texture( u * TEX_SCALE, v * TEX_SCALE )
|
.texture( u * TEX_SCALE, v * TEX_SCALE )
|
||||||
|
.light(light)
|
||||||
.next();
|
.next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -117,7 +117,7 @@ public final class ItemPocketRenderer extends ItemMapLikeRenderer
|
|||||||
BufferBuilder buffer = tessellator.getBuffer();
|
BufferBuilder buffer = tessellator.getBuffer();
|
||||||
buffer.begin( VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR_TEXTURE );
|
buffer.begin( VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_COLOR_TEXTURE );
|
||||||
|
|
||||||
ComputerBorderRenderer.render( transform, buffer, 0, 0, 0, width, height, true, r, g, b );
|
// ComputerBorderRenderer.render( transform, buffer, 0, 0, 0, width, height, true, r, g, b );
|
||||||
|
|
||||||
tessellator.draw();
|
tessellator.draw();
|
||||||
}
|
}
|
||||||
|
@@ -12,13 +12,11 @@ import net.fabricmc.api.Environment;
|
|||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.render.RenderLayer;
|
||||||
import net.minecraft.client.render.VertexConsumer;
|
import net.minecraft.client.render.VertexConsumer;
|
||||||
import net.minecraft.client.util.math.MatrixStack;
|
import net.minecraft.client.util.math.MatrixStack;
|
||||||
import net.minecraft.entity.Entity;
|
import net.minecraft.entity.Entity;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.*;
|
||||||
import net.minecraft.util.math.Direction;
|
|
||||||
import net.minecraft.util.math.Matrix4f;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
@@ -49,13 +47,11 @@ public final class MonitorHighlightRenderer
|
|||||||
World world = entity.getEntityWorld();
|
World world = entity.getEntityWorld();
|
||||||
|
|
||||||
BlockEntity tile = world.getBlockEntity( pos );
|
BlockEntity tile = world.getBlockEntity( pos );
|
||||||
if( !(tile instanceof TileMonitor) )
|
if( !(tile instanceof TileMonitor monitor) )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TileMonitor monitor = (TileMonitor) tile;
|
|
||||||
|
|
||||||
// Determine which sides are part of the external faces of the monitor, and so which need to be rendered.
|
// Determine which sides are part of the external faces of the monitor, and so which need to be rendered.
|
||||||
EnumSet<Direction> faces = EnumSet.allOf( Direction.class );
|
EnumSet<Direction> faces = EnumSet.allOf( Direction.class );
|
||||||
Direction front = monitor.getFront();
|
Direction front = monitor.getFront();
|
||||||
@@ -87,53 +83,54 @@ public final class MonitorHighlightRenderer
|
|||||||
// I wish I could think of a better way to do this
|
// I wish I could think of a better way to do this
|
||||||
Matrix4f transform = matrixStack.peek()
|
Matrix4f transform = matrixStack.peek()
|
||||||
.getModel();
|
.getModel();
|
||||||
|
Matrix3f normal = matrixStack.peek().getNormal();
|
||||||
if( faces.contains( NORTH ) || faces.contains( WEST ) )
|
if( faces.contains( NORTH ) || faces.contains( WEST ) )
|
||||||
{
|
{
|
||||||
line( vertexConsumer, transform, 0, 0, 0, UP );
|
line( vertexConsumer, transform, normal, 0, 0, 0, UP );
|
||||||
}
|
}
|
||||||
if( faces.contains( SOUTH ) || faces.contains( WEST ) )
|
if( faces.contains( SOUTH ) || faces.contains( WEST ) )
|
||||||
{
|
{
|
||||||
line( vertexConsumer, transform, 0, 0, 1, UP );
|
line( vertexConsumer, transform, normal, 0, 0, 1, UP );
|
||||||
}
|
}
|
||||||
if( faces.contains( NORTH ) || faces.contains( EAST ) )
|
if( faces.contains( NORTH ) || faces.contains( EAST ) )
|
||||||
{
|
{
|
||||||
line( vertexConsumer, transform, 1, 0, 0, UP );
|
line( vertexConsumer, transform, normal, 1, 0, 0, UP );
|
||||||
}
|
}
|
||||||
if( faces.contains( SOUTH ) || faces.contains( EAST ) )
|
if( faces.contains( SOUTH ) || faces.contains( EAST ) )
|
||||||
{
|
{
|
||||||
line( vertexConsumer, transform, 1, 0, 1, UP );
|
line( vertexConsumer, transform, normal, 1, 0, 1, UP );
|
||||||
}
|
}
|
||||||
if( faces.contains( NORTH ) || faces.contains( DOWN ) )
|
if( faces.contains( NORTH ) || faces.contains( DOWN ) )
|
||||||
{
|
{
|
||||||
line( vertexConsumer, transform, 0, 0, 0, EAST );
|
line( vertexConsumer, transform, normal, 0, 0, 0, EAST );
|
||||||
}
|
}
|
||||||
if( faces.contains( SOUTH ) || faces.contains( DOWN ) )
|
if( faces.contains( SOUTH ) || faces.contains( DOWN ) )
|
||||||
{
|
{
|
||||||
line( vertexConsumer, transform, 0, 0, 1, EAST );
|
line( vertexConsumer, transform, normal, 0, 0, 1, EAST );
|
||||||
}
|
}
|
||||||
if( faces.contains( NORTH ) || faces.contains( UP ) )
|
if( faces.contains( NORTH ) || faces.contains( UP ) )
|
||||||
{
|
{
|
||||||
line( vertexConsumer, transform, 0, 1, 0, EAST );
|
line( vertexConsumer, transform, normal, 0, 1, 0, EAST );
|
||||||
}
|
}
|
||||||
if( faces.contains( SOUTH ) || faces.contains( UP ) )
|
if( faces.contains( SOUTH ) || faces.contains( UP ) )
|
||||||
{
|
{
|
||||||
line( vertexConsumer, transform, 0, 1, 1, EAST );
|
line( vertexConsumer, transform, normal, 0, 1, 1, EAST );
|
||||||
}
|
}
|
||||||
if( faces.contains( WEST ) || faces.contains( DOWN ) )
|
if( faces.contains( WEST ) || faces.contains( DOWN ) )
|
||||||
{
|
{
|
||||||
line( vertexConsumer, transform, 0, 0, 0, SOUTH );
|
line( vertexConsumer, transform, normal, 0, 0, 0, SOUTH );
|
||||||
}
|
}
|
||||||
if( faces.contains( EAST ) || faces.contains( DOWN ) )
|
if( faces.contains( EAST ) || faces.contains( DOWN ) )
|
||||||
{
|
{
|
||||||
line( vertexConsumer, transform, 1, 0, 0, SOUTH );
|
line( vertexConsumer, transform, normal, 1, 0, 0, SOUTH );
|
||||||
}
|
}
|
||||||
if( faces.contains( WEST ) || faces.contains( UP ) )
|
if( faces.contains( WEST ) || faces.contains( UP ) )
|
||||||
{
|
{
|
||||||
line( vertexConsumer, transform, 0, 1, 0, SOUTH );
|
line( vertexConsumer, transform, normal, 0, 1, 0, SOUTH );
|
||||||
}
|
}
|
||||||
if( faces.contains( EAST ) || faces.contains( UP ) )
|
if( faces.contains( EAST ) || faces.contains( UP ) )
|
||||||
{
|
{
|
||||||
line( vertexConsumer, transform, 1, 1, 0, SOUTH );
|
line( vertexConsumer, transform, normal, 1, 1, 0, SOUTH );
|
||||||
}
|
}
|
||||||
|
|
||||||
matrixStack.pop();
|
matrixStack.pop();
|
||||||
@@ -141,13 +138,15 @@ public final class MonitorHighlightRenderer
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void line( VertexConsumer buffer, Matrix4f transform, float x, float y, float z, Direction direction )
|
private static void line( VertexConsumer buffer, Matrix4f transform, Matrix3f normal, float x, float y, float z, Direction direction )
|
||||||
{
|
{
|
||||||
buffer.vertex( transform, x, y, z )
|
buffer.vertex( transform, x, y, z )
|
||||||
.color( 0, 0, 0, 0.4f )
|
.color( 0, 0, 0, 0.4f )
|
||||||
|
.normal(normal, direction.getOffsetX(), direction.getOffsetY(), direction.getOffsetZ())
|
||||||
.next();
|
.next();
|
||||||
buffer.vertex( transform, x + direction.getOffsetX(), y + direction.getOffsetY(), z + direction.getOffsetZ() )
|
buffer.vertex( transform, x + direction.getOffsetX(), y + direction.getOffsetY(), z + direction.getOffsetZ() )
|
||||||
.color( 0, 0, 0, 0.4f )
|
.color( 0, 0, 0, 0.4f )
|
||||||
|
.normal(normal, direction.getOffsetX(), direction.getOffsetY(), direction.getOffsetZ())
|
||||||
.next();
|
.next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,186 +1,105 @@
|
|||||||
/*
|
|
||||||
* This file is part of ComputerCraft - http://www.computercraft.info
|
|
||||||
* Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
|
|
||||||
* Send enquiries to dratcliffe@gmail.com
|
|
||||||
*/
|
|
||||||
package dan200.computercraft.client.render;
|
package dan200.computercraft.client.render;
|
||||||
|
|
||||||
import com.google.common.base.Strings;
|
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
|
||||||
import com.mojang.blaze3d.platform.TextureUtil;
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
|
||||||
import dan200.computercraft.client.gui.FixedWidthFontRenderer;
|
import dan200.computercraft.client.gui.FixedWidthFontRenderer;
|
||||||
import dan200.computercraft.shared.util.Palette;
|
import dan200.computercraft.shared.util.Palette;
|
||||||
import net.minecraft.util.math.Matrix4f;
|
import net.minecraft.client.gl.GlUniform;
|
||||||
import org.lwjgl.BufferUtils;
|
import net.minecraft.client.render.Shader;
|
||||||
|
import net.minecraft.client.render.VertexFormat;
|
||||||
|
import net.minecraft.resource.ResourceFactory;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.lwjgl.opengl.GL13;
|
import org.lwjgl.opengl.GL13;
|
||||||
import org.lwjgl.opengl.GL20;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
import javax.annotation.Nullable;
|
||||||
|
import java.io.IOException;
|
||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
class MonitorTextureBufferShader
|
public class MonitorTextureBufferShader extends Shader
|
||||||
{
|
{
|
||||||
static final int TEXTURE_INDEX = GL13.GL_TEXTURE3;
|
static final int TEXTURE_INDEX = GL13.GL_TEXTURE3;
|
||||||
|
|
||||||
private static final FloatBuffer MATRIX_BUFFER = BufferUtils.createFloatBuffer( 16 );
|
private static final Logger LOGGER = LogManager.getLogger();
|
||||||
private static final FloatBuffer PALETTE_BUFFER = BufferUtils.createFloatBuffer( 16 * 3 );
|
|
||||||
|
|
||||||
private static int uniformMv;
|
private final GlUniform palette;
|
||||||
|
private final GlUniform width;
|
||||||
|
private final GlUniform height;
|
||||||
|
|
||||||
private static int uniformFont;
|
public MonitorTextureBufferShader(ResourceFactory factory, String name, VertexFormat format) throws IOException {
|
||||||
private static int uniformWidth;
|
super(factory, name, format);
|
||||||
private static int uniformHeight;
|
|
||||||
private static int uniformTbo;
|
|
||||||
private static int uniformPalette;
|
|
||||||
|
|
||||||
private static boolean initialised;
|
width = getUniformChecked( "Width" );
|
||||||
private static boolean ok;
|
height = getUniformChecked( "Height" );
|
||||||
private static int program;
|
palette = new GlUniform( "Palette", GlUniform.field_32044 /* UT_FLOAT3 */, 16 * 3, this );
|
||||||
|
updateUniformLocation( palette );
|
||||||
|
|
||||||
static void setupUniform( Matrix4f transform, int width, int height, Palette palette, boolean greyscale )
|
GlUniform tbo = getUniformChecked( "Tbo" );
|
||||||
|
if( tbo != null ) tbo.set( TEXTURE_INDEX - GL13.GL_TEXTURE0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupUniform( int width, int height, Palette palette, boolean greyscale )
|
||||||
{
|
{
|
||||||
MATRIX_BUFFER.rewind();
|
if( this.width != null ) this.width.set( width );
|
||||||
transform.write( MATRIX_BUFFER, true ); //FIXME: Row major or Column major? guessing row major, since that is like C.
|
if( this.height != null ) this.height.set( height );
|
||||||
MATRIX_BUFFER.rewind();
|
setupPalette( palette, greyscale );
|
||||||
RenderSystem.glUniformMatrix4( uniformMv, false, MATRIX_BUFFER );
|
}
|
||||||
|
|
||||||
RenderSystem.glUniform1i( uniformWidth, width );
|
private void setupPalette( Palette palette, boolean greyscale )
|
||||||
RenderSystem.glUniform1i( uniformHeight, height );
|
{
|
||||||
|
if( this.palette == null ) return;
|
||||||
|
|
||||||
PALETTE_BUFFER.rewind();
|
FloatBuffer paletteBuffer = this.palette.getFloatData();
|
||||||
|
paletteBuffer.rewind();
|
||||||
for( int i = 0; i < 16; i++ )
|
for( int i = 0; i < 16; i++ )
|
||||||
{
|
{
|
||||||
double[] colour = palette.getColour( i );
|
double[] colour = palette.getColour( i );
|
||||||
if( greyscale )
|
if( greyscale )
|
||||||
{
|
{
|
||||||
float f = FixedWidthFontRenderer.toGreyscale( colour );
|
float f = FixedWidthFontRenderer.toGreyscale( colour );
|
||||||
PALETTE_BUFFER.put( f )
|
paletteBuffer.put( f ).put( f ).put( f );
|
||||||
.put( f )
|
|
||||||
.put( f );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PALETTE_BUFFER.put( (float) colour[0] )
|
paletteBuffer.put( (float) colour[0] ).put( (float) colour[1] ).put( (float) colour[2] );
|
||||||
.put( (float) colour[1] )
|
|
||||||
.put( (float) colour[2] );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PALETTE_BUFFER.flip();
|
|
||||||
RenderSystem.glUniform3( uniformPalette, PALETTE_BUFFER );
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean use()
|
|
||||||
{
|
|
||||||
if( initialised )
|
|
||||||
{
|
|
||||||
if( ok )
|
|
||||||
{
|
|
||||||
GlStateManager.glLinkProgram( program );
|
|
||||||
}
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( ok = load() )
|
|
||||||
{
|
|
||||||
GL20.glUseProgram( program );
|
|
||||||
RenderSystem.glUniform1i( uniformFont, 0 );
|
|
||||||
RenderSystem.glUniform1i( uniformTbo, TEXTURE_INDEX - GL13.GL_TEXTURE0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean load()
|
|
||||||
{
|
|
||||||
initialised = true;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
int vertexShader = loadShader( GL20.GL_VERTEX_SHADER, "assets/computercraft/shaders/monitor.vert" );
|
|
||||||
int fragmentShader = loadShader( GL20.GL_FRAGMENT_SHADER, "assets/computercraft/shaders/monitor.frag" );
|
|
||||||
|
|
||||||
program = GlStateManager.glCreateProgram();
|
|
||||||
GlStateManager.glAttachShader( program, vertexShader );
|
|
||||||
GlStateManager.glAttachShader( program, fragmentShader );
|
|
||||||
GL20.glBindAttribLocation( program, 0, "v_pos" );
|
|
||||||
|
|
||||||
GlStateManager.glLinkProgram( program );
|
|
||||||
|
|
||||||
boolean ok = GlStateManager.glGetProgrami( program, GL20.GL_LINK_STATUS ) != 0;
|
|
||||||
String log = GlStateManager.glGetProgramInfoLog( program, Short.MAX_VALUE )
|
|
||||||
.trim();
|
|
||||||
if( !Strings.isNullOrEmpty( log ) )
|
|
||||||
{
|
|
||||||
ComputerCraft.log.warn( "Problems when linking monitor shader: {}", log );
|
|
||||||
}
|
|
||||||
|
|
||||||
GL20.glDetachShader( program, vertexShader );
|
|
||||||
GL20.glDetachShader( program, fragmentShader );
|
|
||||||
GlStateManager.glDeleteShader( vertexShader );
|
|
||||||
GlStateManager.glDeleteShader( fragmentShader );
|
|
||||||
|
|
||||||
if( !ok )
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
uniformMv = getUniformLocation( program, "u_mv" );
|
|
||||||
uniformFont = getUniformLocation( program, "u_font" );
|
|
||||||
uniformWidth = getUniformLocation( program, "u_width" );
|
|
||||||
uniformHeight = getUniformLocation( program, "u_height" );
|
|
||||||
uniformTbo = getUniformLocation( program, "u_tbo" );
|
|
||||||
uniformPalette = getUniformLocation( program, "u_palette" );
|
|
||||||
|
|
||||||
ComputerCraft.log.info( "Loaded monitor shader." );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch( Exception e )
|
|
||||||
{
|
|
||||||
ComputerCraft.log.error( "Cannot load monitor shaders", e );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int loadShader( int kind, String path )
|
@Override
|
||||||
|
public void bind()
|
||||||
{
|
{
|
||||||
InputStream stream = TileEntityMonitorRenderer.class.getClassLoader()
|
super.bind();
|
||||||
.getResourceAsStream( path );
|
palette.upload();
|
||||||
if( stream == null )
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException( "Cannot find " + path );
|
|
||||||
}
|
|
||||||
List<String> contents = TextureUtil.readResourceAsString(stream).lines().toList();
|
|
||||||
|
|
||||||
int shader = GlStateManager.glCreateShader( kind );
|
|
||||||
|
|
||||||
GlStateManager.glShaderSource( shader, contents );
|
|
||||||
GlStateManager.glCompileShader( shader );
|
|
||||||
|
|
||||||
boolean ok = GlStateManager.glGetShaderi( shader, GL20.GL_COMPILE_STATUS ) != 0;
|
|
||||||
String log = GlStateManager.glGetShaderInfoLog( shader, Short.MAX_VALUE )
|
|
||||||
.trim();
|
|
||||||
if( !Strings.isNullOrEmpty( log ) )
|
|
||||||
{
|
|
||||||
ComputerCraft.log.warn( "Problems when loading monitor shader {}: {}", path, log );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !ok )
|
|
||||||
{
|
|
||||||
throw new IllegalStateException( "Cannot compile shader " + path );
|
|
||||||
}
|
|
||||||
return shader;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getUniformLocation( int program, String name )
|
@Override
|
||||||
|
public void close()
|
||||||
{
|
{
|
||||||
int uniform = GlStateManager._glGetUniformLocation( program, name );
|
palette.close();
|
||||||
if( uniform == -1 )
|
super.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateUniformLocation( GlUniform uniform )
|
||||||
|
{
|
||||||
|
int id = GlUniform.getUniformLocation( getProgramRef(), uniform.getName() );
|
||||||
|
if( id == -1 )
|
||||||
{
|
{
|
||||||
throw new IllegalStateException( "Cannot find uniform " + name );
|
LOGGER.warn( "Shader {} could not find uniform named {} in the specified shader program.", getName(), uniform.getName() );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uniform.setLoc( id );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private GlUniform getUniformChecked( String name )
|
||||||
|
{
|
||||||
|
GlUniform uniform = getUniform( name );
|
||||||
|
if( uniform == null )
|
||||||
|
{
|
||||||
|
LOGGER.warn( "Monitor shader {} should have uniform {}, but it was not present.", getName(), name );
|
||||||
|
}
|
||||||
|
|
||||||
return uniform;
|
return uniform;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -53,7 +53,7 @@ public final class PrintoutRenderer
|
|||||||
|
|
||||||
public static void drawText( Matrix4f transform, VertexConsumerProvider renderer, int x, int y, int start, TextBuffer[] text, TextBuffer[] colours )
|
public static void drawText( Matrix4f transform, VertexConsumerProvider renderer, int x, int y, int start, TextBuffer[] text, TextBuffer[] colours )
|
||||||
{
|
{
|
||||||
VertexConsumer buffer = Tessellator.getInstance().getBuffer();
|
/*VertexConsumer buffer = renderer.getBuffer( FixedWidthFontRenderer.TYPE );
|
||||||
for( int line = 0; line < LINES_PER_PAGE && line < text.length; line++ )
|
for( int line = 0; line < LINES_PER_PAGE && line < text.length; line++ )
|
||||||
{
|
{
|
||||||
FixedWidthFontRenderer.drawString( transform,
|
FixedWidthFontRenderer.drawString( transform,
|
||||||
@@ -67,12 +67,12 @@ public final class PrintoutRenderer
|
|||||||
false,
|
false,
|
||||||
0,
|
0,
|
||||||
0 );
|
0 );
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void drawText( Matrix4f transform, VertexConsumerProvider renderer, int x, int y, int start, String[] text, String[] colours )
|
public static void drawText( Matrix4f transform, VertexConsumerProvider renderer, int x, int y, int start, String[] text, String[] colours )
|
||||||
{
|
{
|
||||||
VertexConsumer buffer = Tessellator.getInstance().getBuffer();
|
/*VertexConsumer buffer = renderer.getBuffer( FixedWidthFontRenderer.TYPE );
|
||||||
for( int line = 0; line < LINES_PER_PAGE && line < text.length; line++ )
|
for( int line = 0; line < LINES_PER_PAGE && line < text.length; line++ )
|
||||||
{
|
{
|
||||||
FixedWidthFontRenderer.drawString( transform,
|
FixedWidthFontRenderer.drawString( transform,
|
||||||
@@ -86,7 +86,7 @@ public final class PrintoutRenderer
|
|||||||
false,
|
false,
|
||||||
0,
|
0,
|
||||||
0 );
|
0 );
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void drawBorder( Matrix4f transform, VertexConsumerProvider renderer, float x, float y, float z, int page, int pages, boolean isBook )
|
public static void drawBorder( Matrix4f transform, VertexConsumerProvider renderer, float x, float y, float z, int page, int pages, boolean isBook )
|
||||||
@@ -187,28 +187,22 @@ public final class PrintoutRenderer
|
|||||||
.next();
|
.next();
|
||||||
}
|
}
|
||||||
|
|
||||||
// private static final class Type extends RenderLayer
|
private static final class Type extends RenderLayer
|
||||||
// {
|
{
|
||||||
//
|
static final RenderLayer TYPE = null;/*RenderLayer.of( "printout_background",
|
||||||
// static final RenderLayer TYPE = RenderLayer.of( "printout_background",
|
VertexFormats.POSITION_TEXTURE,
|
||||||
// VertexFormats.POSITION_TEXTURE,
|
VertexFormat.DrawMode.QUADS,
|
||||||
// GL11.GL_QUADS,
|
1024,
|
||||||
// 1024,
|
// useDelegate, needsSorting
|
||||||
// false,
|
RenderLayer.MultiPhaseParameters.builder()
|
||||||
// false,
|
.texture( new RenderPhase.Texture( BG, false, false ) ) // blur, minimap
|
||||||
// // useDelegate, needsSorting
|
.transparency( TRANSLUCENT_TRANSPARENCY )
|
||||||
// Type.MultiPhaseParameters.builder()
|
.lightmap( DISABLE_LIGHTMAP )
|
||||||
// .texture( new RenderPhase.Texture( BG, false, false ) ) // blur, minimap
|
.build( false ));*/
|
||||||
// .transparency( TRANSLUCENT_TRANSPARENCY)
|
|
||||||
// .lightmap( DISABLE_LIGHTMAP )
|
private Type( String name, VertexFormat vertexFormat, VertexFormat.DrawMode drawMode, int expectedBufferSize, boolean hasCrumbling, boolean translucent, RenderLayer.MultiPhaseParameters phases, Runnable setup, Runnable destroy )
|
||||||
// .build( false ) );
|
{
|
||||||
//
|
super( name, vertexFormat, drawMode, expectedBufferSize, hasCrumbling, hasCrumbling, setup, destroy );
|
||||||
// public Type( String name, VertexFormat vertexFormat, DrawMode drawMode,
|
}
|
||||||
// int expectedBufferSize, boolean hasCrumbling, boolean translucent,
|
}
|
||||||
// Runnable startAction, Runnable endAction )
|
|
||||||
// {
|
|
||||||
// super( name, vertexFormat, drawMode, expectedBufferSize, hasCrumbling, translucent,
|
|
||||||
// startAction, endAction );
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,88 @@
|
|||||||
|
package dan200.computercraft.client.render;
|
||||||
|
|
||||||
|
import dan200.computercraft.client.gui.FixedWidthFontRenderer;
|
||||||
|
import net.minecraft.client.render.*;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public class RenderTypes {
|
||||||
|
|
||||||
|
public static final int FULL_BRIGHT_LIGHTMAP = (0xF << 4) | (0xF << 20);
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static MonitorTextureBufferShader monitorTboShader;
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static Shader terminalShader;
|
||||||
|
|
||||||
|
public static final RenderLayer TERMINAL_WITHOUT_DEPTH = Types.TERMINAL_WITHOUT_DEPTH;
|
||||||
|
public static final RenderLayer MONITOR_TBO = Types.MONITOR_TBO;
|
||||||
|
public static final RenderLayer TERMINAL_BLOCKER = Types.BLOCKER;
|
||||||
|
public static final RenderLayer TERMINAL_WITH_DEPTH = Types.TERMINAL_WITH_DEPTH;
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
static MonitorTextureBufferShader getMonitorTextureBufferShader()
|
||||||
|
{
|
||||||
|
if( monitorTboShader == null ) throw new NullPointerException( "MonitorTboShader has not been registered" );
|
||||||
|
return monitorTboShader;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
static Shader getTerminalShader()
|
||||||
|
{
|
||||||
|
if( terminalShader == null ) throw new NullPointerException( "MonitorTboShader has not been registered" );
|
||||||
|
return terminalShader;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final class Types extends RenderPhase
|
||||||
|
{
|
||||||
|
private static final VertexFormat.DrawMode GL_MODE = VertexFormat.DrawMode.TRIANGLES;
|
||||||
|
private static final VertexFormat FORMAT = VertexFormats.POSITION_COLOR_TEXTURE;
|
||||||
|
private static final Shader TERM_SHADER = new Shader( RenderTypes::getTerminalShader );
|
||||||
|
|
||||||
|
private static final RenderPhase.Texture TERM_FONT_TEXTURE = new RenderPhase.Texture(
|
||||||
|
FixedWidthFontRenderer.FONT,
|
||||||
|
false, false // blur, minimap
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final RenderLayer MONITOR_TBO = RenderLayer.of( "monitor_tbo", VertexFormats.POSITION_TEXTURE, VertexFormat.DrawMode.TRIANGLE_STRIP, 128, false, false, // useDelegate, needsSorting
|
||||||
|
RenderLayer.MultiPhaseParameters.builder()
|
||||||
|
.texture(TERM_FONT_TEXTURE ) // blur, minimap
|
||||||
|
.shader(new RenderPhase.Shader(RenderTypes::getMonitorTextureBufferShader))
|
||||||
|
.writeMaskState( RenderLayer.ALL_MASK )
|
||||||
|
.build( false ) );
|
||||||
|
|
||||||
|
static final RenderLayer TERMINAL_WITHOUT_DEPTH = RenderLayer.of(
|
||||||
|
"terminal_without_depth", FORMAT, GL_MODE, 1024,
|
||||||
|
false, false, // useDelegate, needsSorting
|
||||||
|
RenderLayer.MultiPhaseParameters.builder()
|
||||||
|
.texture( TERM_FONT_TEXTURE )
|
||||||
|
.shader( TERM_SHADER )
|
||||||
|
.writeMaskState( COLOR_MASK )
|
||||||
|
.build( false )
|
||||||
|
);
|
||||||
|
|
||||||
|
static final RenderLayer BLOCKER = RenderLayer.of( "terminal_blocker", FORMAT, GL_MODE, 256, false, false, // useDelegate, needsSorting
|
||||||
|
RenderLayer.MultiPhaseParameters.builder()
|
||||||
|
.texture( TERM_FONT_TEXTURE )
|
||||||
|
.shader(TERM_SHADER)
|
||||||
|
.writeMaskState( DEPTH_MASK )
|
||||||
|
.build( false ) );
|
||||||
|
|
||||||
|
static final RenderLayer TERMINAL_WITH_DEPTH = RenderLayer.of(
|
||||||
|
"terminal_with_depth", FORMAT, GL_MODE, 1024,
|
||||||
|
false, false, // useDelegate, needsSorting
|
||||||
|
RenderLayer.MultiPhaseParameters.builder()
|
||||||
|
.texture( TERM_FONT_TEXTURE )
|
||||||
|
.shader( TERM_SHADER )
|
||||||
|
.build( false )
|
||||||
|
);
|
||||||
|
|
||||||
|
private Types( String name, Runnable setup, Runnable destroy )
|
||||||
|
{
|
||||||
|
super( name, setup, destroy );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -7,6 +7,8 @@
|
|||||||
package dan200.computercraft.client.render;
|
package dan200.computercraft.client.render;
|
||||||
|
|
||||||
import com.mojang.blaze3d.platform.GlStateManager;
|
import com.mojang.blaze3d.platform.GlStateManager;
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.client.FrameInfo;
|
import dan200.computercraft.client.FrameInfo;
|
||||||
import dan200.computercraft.client.gui.FixedWidthFontRenderer;
|
import dan200.computercraft.client.gui.FixedWidthFontRenderer;
|
||||||
import dan200.computercraft.core.terminal.Terminal;
|
import dan200.computercraft.core.terminal.Terminal;
|
||||||
@@ -39,6 +41,7 @@ import java.nio.Buffer;
|
|||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.*;
|
import static dan200.computercraft.client.gui.FixedWidthFontRenderer.*;
|
||||||
|
import static net.minecraft.client.util.GlAllocationUtils.allocateByteBuffer;
|
||||||
|
|
||||||
public class TileEntityMonitorRenderer implements BlockEntityRenderer<TileMonitor>
|
public class TileEntityMonitorRenderer implements BlockEntityRenderer<TileMonitor>
|
||||||
{ //FIXME get rid of GL Calls. Buffered things or whatever, more research needed.
|
{ //FIXME get rid of GL Calls. Buffered things or whatever, more research needed.
|
||||||
@@ -52,7 +55,7 @@ public class TileEntityMonitorRenderer implements BlockEntityRenderer<TileMonito
|
|||||||
|
|
||||||
public TileEntityMonitorRenderer( BlockEntityRendererFactory.Context context )
|
public TileEntityMonitorRenderer( BlockEntityRendererFactory.Context context )
|
||||||
{
|
{
|
||||||
// super( rendererDispatcher );
|
// super( context );
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void render( @Nonnull TileMonitor monitor, float partialTicks, @Nonnull MatrixStack transform, @Nonnull VertexConsumerProvider renderer,
|
public void render( @Nonnull TileMonitor monitor, float partialTicks, @Nonnull MatrixStack transform, @Nonnull VertexConsumerProvider renderer,
|
||||||
@@ -99,17 +102,6 @@ public class TileEntityMonitorRenderer implements BlockEntityRenderer<TileMonito
|
|||||||
double xSize = origin.getWidth() - 2.0 * (TileMonitor.RENDER_MARGIN + TileMonitor.RENDER_BORDER);
|
double xSize = origin.getWidth() - 2.0 * (TileMonitor.RENDER_MARGIN + TileMonitor.RENDER_BORDER);
|
||||||
double ySize = origin.getHeight() - 2.0 * (TileMonitor.RENDER_MARGIN + TileMonitor.RENDER_BORDER);
|
double ySize = origin.getHeight() - 2.0 * (TileMonitor.RENDER_MARGIN + TileMonitor.RENDER_BORDER);
|
||||||
|
|
||||||
// Draw the background blocker
|
|
||||||
FixedWidthFontRenderer.drawBlocker( transform.peek().getModel(),
|
|
||||||
renderer,
|
|
||||||
(float) -TileMonitor.RENDER_MARGIN,
|
|
||||||
(float) TileMonitor.RENDER_MARGIN,
|
|
||||||
(float) (xSize + 2 * TileMonitor.RENDER_MARGIN),
|
|
||||||
(float) -(ySize + TileMonitor.RENDER_MARGIN * 2) );
|
|
||||||
|
|
||||||
// Set the contents slightly off the surface to prevent z-fighting
|
|
||||||
transform.translate( 0.0, 0.0, 0.001 );
|
|
||||||
|
|
||||||
// Draw the contents
|
// Draw the contents
|
||||||
Terminal terminal = originTerminal.getTerminal();
|
Terminal terminal = originTerminal.getTerminal();
|
||||||
if( terminal != null )
|
if( terminal != null )
|
||||||
@@ -124,24 +116,23 @@ public class TileEntityMonitorRenderer implements BlockEntityRenderer<TileMonito
|
|||||||
|
|
||||||
Matrix4f matrix = transform.peek().getModel();
|
Matrix4f matrix = transform.peek().getModel();
|
||||||
|
|
||||||
// Sneaky hack here: we get a buffer now in order to flush existing ones and set up the appropriate
|
renderTerminal( renderer, matrix, originTerminal, (float) (MARGIN / xScale), (float) (MARGIN / yScale) );
|
||||||
// render state. I've no clue how well this'll work in future versions of Minecraft, but it does the trick
|
|
||||||
// for now.
|
|
||||||
BufferBuilder buffer = Tessellator.getInstance().getBuffer();
|
|
||||||
buffer.begin( VertexFormat.DrawMode.TRIANGLE_STRIP, VertexFormats.POSITION_COLOR_TEXTURE );
|
|
||||||
// FixedWidthFontRenderer.TYPE.startDrawing();
|
|
||||||
|
|
||||||
renderTerminal( matrix, originTerminal, (float) (MARGIN / xScale), (float) (MARGIN / yScale) );
|
|
||||||
|
|
||||||
// We don't draw the cursor with the VBO, as it's dynamic and so we'll end up refreshing far more than is
|
// We don't draw the cursor with the VBO, as it's dynamic and so we'll end up refreshing far more than is
|
||||||
// reasonable.
|
// reasonable.
|
||||||
FixedWidthFontRenderer.drawCursor( matrix, buffer, 0, 0, terminal, !originTerminal.isColour() );
|
FixedWidthFontRenderer.drawCursor( matrix, renderer.getBuffer(RenderTypes.TERMINAL_WITHOUT_DEPTH), 0, 0, terminal, !originTerminal.isColour() );
|
||||||
|
|
||||||
// To go along with sneaky hack above: make sure state changes are undone. I would have thought this would
|
|
||||||
// happen automatically after these buffers are drawn, but chests will render weird around monitors without this.
|
|
||||||
buffer.end();
|
|
||||||
|
|
||||||
transform.pop();
|
transform.pop();
|
||||||
|
|
||||||
|
// Draw the background blocker
|
||||||
|
FixedWidthFontRenderer.drawBlocker( transform.peek().getModel(),
|
||||||
|
renderer,
|
||||||
|
(float) -TileMonitor.RENDER_MARGIN,
|
||||||
|
(float) TileMonitor.RENDER_MARGIN,
|
||||||
|
(float) (xSize + 2 * TileMonitor.RENDER_MARGIN),
|
||||||
|
(float) -(ySize + TileMonitor.RENDER_MARGIN * 2) );
|
||||||
|
|
||||||
|
renderer.getBuffer( RenderLayer.getSolid() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -157,7 +148,7 @@ public class TileEntityMonitorRenderer implements BlockEntityRenderer<TileMonito
|
|||||||
transform.pop();
|
transform.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void renderTerminal( Matrix4f matrix, ClientMonitor monitor, float xMargin, float yMargin )
|
private static void renderTerminal(VertexConsumerProvider renderer, Matrix4f matrix, ClientMonitor monitor, float xMargin, float yMargin )
|
||||||
{
|
{
|
||||||
Terminal terminal = monitor.getTerminal();
|
Terminal terminal = monitor.getTerminal();
|
||||||
|
|
||||||
@@ -172,10 +163,6 @@ public class TileEntityMonitorRenderer implements BlockEntityRenderer<TileMonito
|
|||||||
{
|
{
|
||||||
case TBO:
|
case TBO:
|
||||||
{
|
{
|
||||||
if( !MonitorTextureBufferShader.use() )
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int width = terminal.getWidth(), height = terminal.getHeight();
|
int width = terminal.getWidth(), height = terminal.getHeight();
|
||||||
int pixelWidth = width * FONT_WIDTH, pixelHeight = height * FONT_HEIGHT;
|
int pixelWidth = width * FONT_WIDTH, pixelHeight = height * FONT_HEIGHT;
|
||||||
@@ -185,7 +172,7 @@ public class TileEntityMonitorRenderer implements BlockEntityRenderer<TileMonito
|
|||||||
int size = width * height * 3;
|
int size = width * height * 3;
|
||||||
if( tboContents == null || tboContents.capacity() < size )
|
if( tboContents == null || tboContents.capacity() < size )
|
||||||
{
|
{
|
||||||
tboContents = GlAllocationUtils.allocateByteBuffer( size );
|
tboContents = allocateByteBuffer( size );
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuffer monitorBuffer = tboContents;
|
ByteBuffer monitorBuffer = tboContents;
|
||||||
@@ -201,32 +188,28 @@ public class TileEntityMonitorRenderer implements BlockEntityRenderer<TileMonito
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
monitorBuffer.flip();
|
monitorBuffer.flip();
|
||||||
|
|
||||||
GlStateManager._glBindBuffer( GL31.GL_TEXTURE_BUFFER, monitor.tboBuffer );
|
GlStateManager._glBindBuffer( GL31.GL_TEXTURE_BUFFER, monitor.tboBuffer );
|
||||||
GlStateManager._glBufferData( GL31.GL_TEXTURE_BUFFER, monitorBuffer, GL20.GL_STATIC_DRAW );
|
GlStateManager._glBufferData( GL31.GL_TEXTURE_BUFFER, monitorBuffer, GL20.GL_STATIC_DRAW );
|
||||||
GlStateManager._glBindBuffer( GL31.GL_TEXTURE_BUFFER, 0 );
|
GlStateManager._glBindBuffer( GL31.GL_TEXTURE_BUFFER, 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nobody knows what they're doing!
|
// Nobody knows what they're doing!
|
||||||
GlStateManager._activeTexture( MonitorTextureBufferShader.TEXTURE_INDEX );
|
int active = GlStateManager._getActiveTexture();
|
||||||
|
RenderSystem.activeTexture( MonitorTextureBufferShader.TEXTURE_INDEX );
|
||||||
GL11.glBindTexture( GL31.GL_TEXTURE_BUFFER, monitor.tboTexture );
|
GL11.glBindTexture( GL31.GL_TEXTURE_BUFFER, monitor.tboTexture );
|
||||||
GlStateManager._activeTexture( GL13.GL_TEXTURE0 );
|
RenderSystem.activeTexture( active );
|
||||||
|
|
||||||
MonitorTextureBufferShader.setupUniform( matrix, width, height, terminal.getPalette(), !monitor.isColour() );
|
MonitorTextureBufferShader shader = RenderTypes.getMonitorTextureBufferShader();
|
||||||
|
shader.setupUniform( width, height, terminal.getPalette(), !monitor.isColour() );
|
||||||
|
|
||||||
Tessellator tessellator = Tessellator.getInstance();
|
VertexConsumer buffer = renderer.getBuffer( RenderTypes.MONITOR_TBO );
|
||||||
BufferBuilder buffer = tessellator.getBuffer();
|
tboVertex( buffer, matrix, -xMargin, -yMargin );
|
||||||
buffer.begin( VertexFormat.DrawMode.TRIANGLE_STRIP, VertexFormats.POSITION );
|
tboVertex( buffer, matrix, -xMargin, pixelHeight + yMargin );
|
||||||
buffer.vertex( -xMargin, -yMargin, 0 )
|
tboVertex( buffer, matrix, pixelWidth + xMargin, -yMargin );
|
||||||
.next();
|
tboVertex( buffer, matrix, pixelWidth + xMargin, pixelHeight + yMargin );
|
||||||
buffer.vertex( -xMargin, pixelHeight + yMargin, 0 )
|
|
||||||
.next();
|
|
||||||
buffer.vertex( pixelWidth + xMargin, -yMargin, 0 )
|
|
||||||
.next();
|
|
||||||
buffer.vertex( pixelWidth + xMargin, pixelHeight + yMargin, 0 )
|
|
||||||
.next();
|
|
||||||
tessellator.draw();
|
|
||||||
|
|
||||||
GlStateManager._glUseProgram( 0 );
|
renderer.getBuffer( RenderTypes.TERMINAL_WITHOUT_DEPTH );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +219,7 @@ public class TileEntityMonitorRenderer implements BlockEntityRenderer<TileMonito
|
|||||||
{
|
{
|
||||||
Tessellator tessellator = Tessellator.getInstance();
|
Tessellator tessellator = Tessellator.getInstance();
|
||||||
BufferBuilder builder = tessellator.getBuffer();
|
BufferBuilder builder = tessellator.getBuffer();
|
||||||
builder.begin( VertexFormat.DrawMode.TRIANGLE_STRIP, VertexFormats.POSITION_COLOR_TEXTURE );
|
builder.begin( RenderTypes.TERMINAL_WITHOUT_DEPTH.getDrawMode(), RenderTypes.TERMINAL_WITHOUT_DEPTH.getVertexFormat() );
|
||||||
FixedWidthFontRenderer.drawTerminalWithoutCursor( IDENTITY,
|
FixedWidthFontRenderer.drawTerminalWithoutCursor( IDENTITY,
|
||||||
builder,
|
builder,
|
||||||
0,
|
0,
|
||||||
@@ -252,15 +235,23 @@ public class TileEntityMonitorRenderer implements BlockEntityRenderer<TileMonito
|
|||||||
vbo.upload( builder );
|
vbo.upload( builder );
|
||||||
}
|
}
|
||||||
|
|
||||||
vbo.bind();
|
renderer.getBuffer( RenderTypes.TERMINAL_WITHOUT_DEPTH );
|
||||||
VertexFormats.POSITION_COLOR_TEXTURE
|
|
||||||
.startDrawing();
|
RenderTypes.TERMINAL_WITHOUT_DEPTH.startDrawing();
|
||||||
// vbo.draw( matrix, FixedWidthFontRenderer.TYPE.getDrawMode() );
|
vbo.setShader(matrix, RenderSystem.getProjectionMatrix(), RenderTypes.getTerminalShader());
|
||||||
vbo.drawElements(); //FIXME: Is this ok?
|
|
||||||
VertexBuffer.unbind();
|
|
||||||
VertexFormats.POSITION_COLOR_TEXTURE
|
|
||||||
.endDrawing();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void tboVertex( VertexConsumer builder, Matrix4f matrix, float x, float y )
|
||||||
|
{
|
||||||
|
// We encode position in the UV, as that's not transformed by the matrix.
|
||||||
|
builder.vertex( matrix, x, y, 0 ).texture(x, y).next();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRenderDistance()
|
||||||
|
{
|
||||||
|
return ComputerCraft.monitorDistance;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -48,9 +48,11 @@ public class TileEntityTurtleRenderer implements BlockEntityRenderer<TileTurtle>
|
|||||||
|
|
||||||
private final Random random = new Random( 0 );
|
private final Random random = new Random( 0 );
|
||||||
|
|
||||||
|
BlockEntityRenderDispatcher dispatcher;
|
||||||
|
|
||||||
public TileEntityTurtleRenderer( BlockEntityRendererFactory.Context context )
|
public TileEntityTurtleRenderer( BlockEntityRendererFactory.Context context )
|
||||||
{
|
{
|
||||||
// super( rendererDispatcher );
|
dispatcher = context.getRenderDispatcher();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ModelIdentifier getTurtleModel( ComputerFamily family, boolean coloured )
|
public static ModelIdentifier getTurtleModel( ComputerFamily family, boolean coloured )
|
||||||
|
@@ -117,7 +117,6 @@ public class TurtleMultiModel implements BakedModel
|
|||||||
return baseModel.isBuiltin();
|
return baseModel.isBuiltin();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public Sprite getParticleSprite()
|
public Sprite getParticleSprite()
|
||||||
@@ -125,6 +124,14 @@ public class TurtleMultiModel implements BakedModel
|
|||||||
return baseModel.getParticleSprite();
|
return baseModel.getParticleSprite();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Nonnull
|
||||||
|
// @Override
|
||||||
|
// @Deprecated
|
||||||
|
// public Sprite getSprite()
|
||||||
|
// {
|
||||||
|
// return baseModel.getSprite();
|
||||||
|
// }
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
|
@@ -142,7 +142,6 @@ public class TurtleSmartItemModel implements BakedModel
|
|||||||
return familyModel.isBuiltin();
|
return familyModel.isBuiltin();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
@Override
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public Sprite getParticleSprite()
|
public Sprite getParticleSprite()
|
||||||
@@ -150,6 +149,14 @@ public class TurtleSmartItemModel implements BakedModel
|
|||||||
return familyModel.getParticleSprite();
|
return familyModel.getParticleSprite();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Nonnull
|
||||||
|
// @Override
|
||||||
|
// @Deprecated
|
||||||
|
// public Sprite getSprite()
|
||||||
|
// {
|
||||||
|
// return familyModel.getSprite();
|
||||||
|
// }
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
@Deprecated
|
@Deprecated
|
||||||
|
@@ -0,0 +1,41 @@
|
|||||||
|
package dan200.computercraft.fabric.mixin;
|
||||||
|
|
||||||
|
import com.mojang.datafixers.util.Pair;
|
||||||
|
import dan200.computercraft.ComputerCraft;
|
||||||
|
import dan200.computercraft.client.gui.FixedWidthFontRenderer;
|
||||||
|
import dan200.computercraft.client.render.MonitorTextureBufferShader;
|
||||||
|
import dan200.computercraft.client.render.RenderTypes;
|
||||||
|
import net.minecraft.client.gl.Program;
|
||||||
|
import net.minecraft.client.render.GameRenderer;
|
||||||
|
import net.minecraft.client.render.RenderLayer;
|
||||||
|
import net.minecraft.client.render.Shader;
|
||||||
|
import net.minecraft.client.render.VertexFormats;
|
||||||
|
import net.minecraft.resource.ResourceManager;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
@Mixin(GameRenderer.class)
|
||||||
|
public class GameRendererMixin {
|
||||||
|
@SuppressWarnings("UnresolvedMixinReference")
|
||||||
|
@Inject(method = "loadShaders", at = @At(value = "INVOKE_ASSIGN", target = "Ljava/util/List;add(Ljava/lang/Object;)Z", ordinal = 53), locals = LocalCapture.CAPTURE_FAILSOFT)
|
||||||
|
private void loadShaders(ResourceManager manager, CallbackInfo info, List<Program> list, List<Pair<Shader, Consumer<Shader>>> list2) throws IOException {
|
||||||
|
list2.add(Pair.of(new Shader(
|
||||||
|
manager,
|
||||||
|
"terminal",
|
||||||
|
RenderTypes.TERMINAL_WITHOUT_DEPTH.getVertexFormat()
|
||||||
|
), (shader) -> RenderTypes.terminalShader = shader));
|
||||||
|
list2.add(Pair.of(new MonitorTextureBufferShader(
|
||||||
|
manager,
|
||||||
|
"monitor_tbo",
|
||||||
|
RenderTypes.MONITOR_TBO.getVertexFormat()
|
||||||
|
), (shader) -> RenderTypes.monitorTboShader = (MonitorTextureBufferShader) shader));
|
||||||
|
}
|
||||||
|
}
|
@@ -27,14 +27,14 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|||||||
@Mixin( Block.class )
|
@Mixin( Block.class )
|
||||||
public class MixinBlock
|
public class MixinBlock
|
||||||
{
|
{
|
||||||
@Inject( method = "dropStack(Lnet/minecraft/world/World;Ljava/util/function/Supplier;Lnet/minecraft/item/ItemStack;)V",
|
// @Inject( method = "dropStack",
|
||||||
at = @At( value = "HEAD" ),
|
// at = @At( value = "INVOKE", target = "Lnet/minecraft/world/World;spawnEntity(Lnet/minecraft/entity/Entity;)Z" ),
|
||||||
cancellable = true )
|
// cancellable = true )
|
||||||
private static void dropStack( World world, Supplier<ItemEntity> itemEntitySupplier, ItemStack stack, CallbackInfo callbackInfo )
|
// private static void dropStack( World world, BlockPos pos, ItemStack stack, CallbackInfo callbackInfo )
|
||||||
{
|
// {
|
||||||
if( DropConsumer.onHarvestDrops( world, itemEntitySupplier.get().getBlockPos(), stack ) )
|
// if( DropConsumer.onHarvestDrops( world, itemEntitySupplier.get().getBlockPos(), stack ) )
|
||||||
{
|
// {
|
||||||
callbackInfo.cancel();
|
// callbackInfo.cancel();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
@@ -22,14 +22,14 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
|||||||
@Mixin( Entity.class )
|
@Mixin( Entity.class )
|
||||||
public class MixinEntity
|
public class MixinEntity
|
||||||
{
|
{
|
||||||
@Inject( method = "dropStack(Lnet/minecraft/item/ItemStack;F)Lnet/minecraft/entity/ItemEntity;",
|
// @Inject( method = "dropStack(Lnet/minecraft/item/ItemStack;F)Lnet/minecraft/entity/ItemEntity;",
|
||||||
at = @At( value = "INVOKE", target = "Lnet/minecraft/world/World;spawnEntity(Lnet/minecraft/entity/Entity;)Z" ),
|
// at = @At( value = "INVOKE", target = "Lnet/minecraft/world/World;spawnEntity(Lnet/minecraft/entity/Entity;)Z" ),
|
||||||
cancellable = true )
|
// cancellable = true )
|
||||||
public void dropStack( ItemStack stack, float height, CallbackInfoReturnable<ItemEntity> callbackInfo )
|
// public void dropStack( ItemStack stack, float height, CallbackInfoReturnable<ItemEntity> callbackInfo )
|
||||||
{
|
// {
|
||||||
if( DropConsumer.onLivingDrops( (Entity) (Object) this, stack ) )
|
// if( DropConsumer.onLivingDrops( (Entity) (Object) this, stack ) )
|
||||||
{
|
// {
|
||||||
callbackInfo.setReturnValue( null );
|
// callbackInfo.setReturnValue( null );
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
@@ -30,13 +30,13 @@ public class MixinWorld
|
|||||||
protected boolean iteratingTickingBlockEntities;
|
protected boolean iteratingTickingBlockEntities;
|
||||||
|
|
||||||
// @Inject( method = "setBlockEntity", at = @At( "HEAD" ) )
|
// @Inject( method = "setBlockEntity", at = @At( "HEAD" ) )
|
||||||
// public void setBlockEntity( BlockPos pos, @Nullable BlockEntity entity, CallbackInfo info )
|
public void setBlockEntity( BlockPos pos, @Nullable BlockEntity entity, CallbackInfo info )
|
||||||
// {
|
{
|
||||||
// if( entity != null && !entity.isRemoved() && entity.getWorld().isInBuildLimit(pos) && iteratingTickingBlockEntities )
|
if( entity != null && !entity.isRemoved() && entity.getWorld().isInBuildLimit(pos) && iteratingTickingBlockEntities )
|
||||||
// {
|
{
|
||||||
// setWorld( entity, this );
|
setWorld( entity, this );
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
private static void setWorld( BlockEntity entity, Object world )
|
private static void setWorld( BlockEntity entity, Object world )
|
||||||
{
|
{
|
||||||
@@ -47,14 +47,14 @@ public class MixinWorld
|
|||||||
}
|
}
|
||||||
|
|
||||||
// @Inject( method = "addBlockEntities", at = @At( "HEAD" ) )
|
// @Inject( method = "addBlockEntities", at = @At( "HEAD" ) )
|
||||||
// public void addBlockEntities( Collection<BlockEntity> entities, CallbackInfo info )
|
public void addBlockEntities( Collection<BlockEntity> entities, CallbackInfo info )
|
||||||
// {
|
{
|
||||||
// if( iteratingTickingBlockEntities )
|
if( iteratingTickingBlockEntities )
|
||||||
// {
|
{
|
||||||
// for( BlockEntity entity : entities )
|
for( BlockEntity entity : entities )
|
||||||
// {
|
{
|
||||||
// setWorld( entity, this );
|
setWorld( entity, this );
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,18 @@
|
|||||||
|
//package dan200.computercraft.fabric.mixin;
|
||||||
|
//
|
||||||
|
//import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
//import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
//import org.spongepowered.asm.mixin.gen.Invoker;
|
||||||
|
//
|
||||||
|
//import net.minecraft.client.render.RenderLayer;
|
||||||
|
//import net.minecraft.client.render.VertexFormat;
|
||||||
|
//
|
||||||
|
//@Mixin(RenderLayer.class)
|
||||||
|
//public interface RenderLayerAccessor {
|
||||||
|
//
|
||||||
|
// @Accessor
|
||||||
|
// static RenderLayer.MultiPhaseParameters callOf(String name, VertexFormat vertexFormat, VertexFormat.DrawMode drawMode, int expectedBufferSize, boolean hasCrumbling, boolean translucent, RenderLayer.MultiPhaseParameters phases) {
|
||||||
|
// throw new UnsupportedOperationException();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//}
|
@@ -42,13 +42,11 @@ import dan200.computercraft.shared.turtle.core.TurtlePlayer;
|
|||||||
import dan200.computercraft.shared.turtle.inventory.ContainerTurtle;
|
import dan200.computercraft.shared.turtle.inventory.ContainerTurtle;
|
||||||
import dan200.computercraft.shared.turtle.items.ItemTurtle;
|
import dan200.computercraft.shared.turtle.items.ItemTurtle;
|
||||||
import dan200.computercraft.shared.turtle.upgrades.*;
|
import dan200.computercraft.shared.turtle.upgrades.*;
|
||||||
|
//import dan200.computercraft.shared.util.FixedPointTileEntityType;
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
|
import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
|
||||||
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
import net.fabricmc.fabric.api.object.builder.v1.block.FabricBlockSettings;
|
||||||
import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry;
|
import net.fabricmc.fabric.api.screenhandler.v1.ScreenHandlerRegistry;
|
||||||
import net.minecraft.block.AbstractBlock;
|
import net.minecraft.block.*;
|
||||||
import net.minecraft.block.Block;
|
|
||||||
import net.minecraft.block.Blocks;
|
|
||||||
import net.minecraft.block.Material;
|
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
import net.minecraft.block.entity.BlockEntityType;
|
import net.minecraft.block.entity.BlockEntityType;
|
||||||
import net.minecraft.entity.EntityType;
|
import net.minecraft.entity.EntityType;
|
||||||
@@ -61,6 +59,7 @@ import net.minecraft.screen.ScreenHandler;
|
|||||||
import net.minecraft.screen.ScreenHandlerType;
|
import net.minecraft.screen.ScreenHandlerType;
|
||||||
import net.minecraft.sound.BlockSoundGroup;
|
import net.minecraft.sound.BlockSoundGroup;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.registry.Registry;
|
import net.minecraft.util.registry.Registry;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
@@ -108,8 +107,8 @@ public final class ComputerCraftRegistry
|
|||||||
public static final BlockSpeaker SPEAKER = register( "speaker", new BlockSpeaker( properties() ) );
|
public static final BlockSpeaker SPEAKER = register( "speaker", new BlockSpeaker( properties() ) );
|
||||||
public static final BlockDiskDrive DISK_DRIVE = register( "disk_drive", new BlockDiskDrive( properties() ) );
|
public static final BlockDiskDrive DISK_DRIVE = register( "disk_drive", new BlockDiskDrive( properties() ) );
|
||||||
public static final BlockPrinter PRINTER = register( "printer", new BlockPrinter( properties() ) );
|
public static final BlockPrinter PRINTER = register( "printer", new BlockPrinter( properties() ) );
|
||||||
public static final BlockMonitor MONITOR_NORMAL = register( "monitor_normal", new BlockMonitor( properties(), ModTiles.MONITOR_NORMAL ) );
|
public static final BlockMonitor MONITOR_NORMAL = register( "monitor_normal", new BlockMonitor( properties(), ModTiles.MONITOR_NORMAL, false ) );
|
||||||
public static final BlockMonitor MONITOR_ADVANCED = register( "monitor_advanced", new BlockMonitor( properties(), ModTiles.MONITOR_ADVANCED ) );
|
public static final BlockMonitor MONITOR_ADVANCED = register( "monitor_advanced", new BlockMonitor( properties(), ModTiles.MONITOR_ADVANCED, true ) );
|
||||||
public static final BlockWirelessModem WIRELESS_MODEM_NORMAL = register( "wireless_modem_normal",
|
public static final BlockWirelessModem WIRELESS_MODEM_NORMAL = register( "wireless_modem_normal",
|
||||||
new BlockWirelessModem( properties(), ModTiles.WIRELESS_MODEM_NORMAL ) );
|
new BlockWirelessModem( properties(), ModTiles.WIRELESS_MODEM_NORMAL ) );
|
||||||
public static final BlockWirelessModem WIRELESS_MODEM_ADVANCED = register( "wireless_modem_advanced",
|
public static final BlockWirelessModem WIRELESS_MODEM_ADVANCED = register( "wireless_modem_advanced",
|
||||||
@@ -149,53 +148,53 @@ public final class ComputerCraftRegistry
|
|||||||
public static class ModTiles
|
public static class ModTiles
|
||||||
{
|
{
|
||||||
|
|
||||||
public static final BlockEntityType<TileMonitor> MONITOR_NORMAL = FabricBlockEntityTypeBuilder
|
public static final BlockEntityType<TileMonitor> MONITOR_NORMAL = ofBlock( ModBlocks.MONITOR_NORMAL,
|
||||||
.create( ( blockPos, blockState ) -> new TileMonitor( ModTiles.MONITOR_NORMAL, false, blockPos, blockState ),
|
"monitor_normal",
|
||||||
ModBlocks.MONITOR_NORMAL )
|
(blockPos, blockState) -> new TileMonitor(ModTiles.MONITOR_NORMAL, false, blockPos, blockState) );
|
||||||
.build();
|
public static final BlockEntityType<TileMonitor> MONITOR_ADVANCED = ofBlock( ModBlocks.MONITOR_ADVANCED,
|
||||||
public static final BlockEntityType<TileMonitor> MONITOR_ADVANCED = FabricBlockEntityTypeBuilder
|
"monitor_advanced",
|
||||||
.create( ( blockPos, blockState ) -> new TileMonitor( ModTiles.MONITOR_ADVANCED, false, blockPos, blockState ),
|
(blockPos, blockState) -> new TileMonitor(ModTiles.MONITOR_ADVANCED, true, blockPos, blockState) );
|
||||||
ModBlocks.MONITOR_ADVANCED )
|
public static final BlockEntityType<TileComputer> COMPUTER_NORMAL = ofBlock( ModBlocks.COMPUTER_NORMAL,
|
||||||
.build();
|
"computer_normal",
|
||||||
public static final BlockEntityType<TileComputer> COMPUTER_NORMAL = FabricBlockEntityTypeBuilder.create(
|
(blockPos, blockState) -> new TileComputer(ComputerFamily.NORMAL, ModTiles.COMPUTER_NORMAL, blockPos, blockState) );
|
||||||
( blockPos, blockState ) -> new TileComputer( ComputerFamily.NORMAL, ModTiles.COMPUTER_NORMAL, blockPos, blockState ),
|
public static final BlockEntityType<TileComputer> COMPUTER_ADVANCED = ofBlock( ModBlocks.COMPUTER_ADVANCED,
|
||||||
ModBlocks.COMPUTER_NORMAL ).build();
|
"computer_advanced",
|
||||||
public static final BlockEntityType<TileComputer> COMPUTER_ADVANCED = FabricBlockEntityTypeBuilder
|
(blockPos, blockState) -> new TileComputer(ComputerFamily.ADVANCED, ModTiles.COMPUTER_ADVANCED, blockPos, blockState) );
|
||||||
.create( ( blockPos, blockState ) -> new TileComputer( ComputerFamily.ADVANCED, ModTiles.COMPUTER_ADVANCED, blockPos,
|
public static final BlockEntityType<TileCommandComputer> COMPUTER_COMMAND = ofBlock( ModBlocks.COMPUTER_COMMAND,
|
||||||
blockState ), ModBlocks.COMPUTER_ADVANCED )
|
"computer_command",
|
||||||
.build();
|
(blockPos, blockState) -> new TileCommandComputer(ComputerFamily.COMMAND, ModTiles.COMPUTER_COMMAND, blockPos, blockState) );
|
||||||
public static final BlockEntityType<TileCommandComputer> COMPUTER_COMMAND = FabricBlockEntityTypeBuilder
|
public static final BlockEntityType<TileTurtle> TURTLE_NORMAL = ofBlock( ModBlocks.TURTLE_NORMAL,
|
||||||
.create( ( blockPos, blockState ) -> new TileCommandComputer( ComputerFamily.COMMAND, ModTiles.COMPUTER_COMMAND, blockPos,
|
"turtle_normal",
|
||||||
blockState ), ModBlocks.COMPUTER_COMMAND )
|
(blockPos, blockState) -> new TileTurtle(ModTiles.TURTLE_NORMAL, blockPos, blockState, ComputerFamily.NORMAL ) );
|
||||||
.build();
|
public static final BlockEntityType<TileTurtle> TURTLE_ADVANCED = ofBlock( ModBlocks.TURTLE_ADVANCED,
|
||||||
public static final BlockEntityType<TileTurtle> TURTLE_NORMAL = FabricBlockEntityTypeBuilder.create(
|
"turtle_advanced",
|
||||||
( blockPos, blockState ) -> new TileTurtle( ModTiles.TURTLE_NORMAL, ComputerFamily.NORMAL, blockPos, blockState ),
|
(blockPos, blockState) -> new TileTurtle(ModTiles.TURTLE_ADVANCED, blockPos, blockState, ComputerFamily.ADVANCED ) );
|
||||||
ModBlocks.TURTLE_NORMAL ).build();
|
public static final BlockEntityType<TileSpeaker> SPEAKER = ofBlock( ModBlocks.SPEAKER, "speaker",
|
||||||
public static final BlockEntityType<TileTurtle> TURTLE_ADVANCED = FabricBlockEntityTypeBuilder.create(
|
(blockPos, blockState) -> new TileSpeaker(ModTiles.SPEAKER, blockPos, blockState ) );
|
||||||
( blockPos, blockState ) -> new TileTurtle( ModTiles.TURTLE_ADVANCED, ComputerFamily.ADVANCED, blockPos, blockState ),
|
public static final BlockEntityType<TileDiskDrive> DISK_DRIVE = ofBlock( ModBlocks.DISK_DRIVE, "disk_drive",
|
||||||
ModBlocks.TURTLE_ADVANCED ).build();
|
(blockPos, blockState) -> new TileDiskDrive(ModTiles.DISK_DRIVE, blockPos, blockState ) );
|
||||||
public static final BlockEntityType<TileSpeaker> SPEAKER = FabricBlockEntityTypeBuilder
|
public static final BlockEntityType<TilePrinter> PRINTER = ofBlock( ModBlocks.PRINTER, "printer",
|
||||||
.create( ( blockPos, blockState ) -> new TileSpeaker( ModTiles.SPEAKER, blockPos, blockState ), ModBlocks.SPEAKER )
|
(blockPos, blockState) -> new TilePrinter(ModTiles.PRINTER, blockPos, blockState ) );
|
||||||
.build();
|
public static final BlockEntityType<TileWiredModemFull> WIRED_MODEM_FULL = ofBlock( ModBlocks.WIRED_MODEM_FULL,
|
||||||
public static final BlockEntityType<TileDiskDrive> DISK_DRIVE = FabricBlockEntityTypeBuilder
|
"wired_modem_full",
|
||||||
.create( ( blockPos, blockState ) -> new TileDiskDrive( ModTiles.DISK_DRIVE, blockPos, blockState ),
|
(blockPos, blockState) -> new TileWiredModemFull(ModTiles.WIRED_MODEM_FULL, blockPos, blockState ) );
|
||||||
ModBlocks.DISK_DRIVE )
|
public static final BlockEntityType<TileCable> CABLE = ofBlock( ModBlocks.CABLE, "cable",
|
||||||
.build();
|
(blockPos, blockState) -> new TileCable(ModTiles.CABLE, blockPos, blockState ) );
|
||||||
public static final BlockEntityType<TilePrinter> PRINTER = FabricBlockEntityTypeBuilder
|
public static final BlockEntityType<TileWirelessModem> WIRELESS_MODEM_NORMAL = ofBlock( ModBlocks.WIRELESS_MODEM_NORMAL,
|
||||||
.create( ( blockPos, blockState ) -> new TilePrinter( ModTiles.PRINTER, blockPos, blockState ), ModBlocks.PRINTER )
|
"wireless_modem_normal",
|
||||||
.build();
|
(blockPos, blockState) -> new TileWirelessModem(ModTiles.WIRELESS_MODEM_NORMAL, false, blockPos, blockState) );
|
||||||
public static final BlockEntityType<TileWiredModemFull> WIRED_MODEM_FULL = FabricBlockEntityTypeBuilder
|
public static final BlockEntityType<TileWirelessModem> WIRELESS_MODEM_ADVANCED = ofBlock( ModBlocks.WIRELESS_MODEM_ADVANCED,
|
||||||
.create( ( blockPos, blockState ) -> new TileWiredModemFull( ModTiles.WIRED_MODEM_FULL, blockPos, blockState ),
|
"wireless_modem_advanced",
|
||||||
ModBlocks.WIRED_MODEM_FULL )
|
(blockPos, blockState) -> new TileWirelessModem(ModTiles.WIRELESS_MODEM_ADVANCED, true, blockPos, blockState) );
|
||||||
.build();
|
|
||||||
public static final BlockEntityType<TileCable> CABLE = FabricBlockEntityTypeBuilder
|
private static <T extends BlockEntity> BlockEntityType<T> ofBlock( Block block, String id, BiFunction<BlockPos, BlockState, T> factory )
|
||||||
.create( ( blockPos, blockState ) -> new TileCable( ModTiles.CABLE, blockPos, blockState ), ModBlocks.CABLE ).build();
|
{
|
||||||
public static final BlockEntityType<TileWirelessModem> WIRELESS_MODEM_NORMAL = FabricBlockEntityTypeBuilder.create(
|
BlockEntityType<T> blockEntityType = FabricBlockEntityTypeBuilder.create(factory::apply, block).build();
|
||||||
( blockPos, blockState ) -> new TileWirelessModem( ModTiles.WIRELESS_MODEM_NORMAL, false, blockPos, blockState ),
|
return Registry.register( BLOCK_ENTITY_TYPE,
|
||||||
ModBlocks.WIRELESS_MODEM_NORMAL ).build();
|
new Identifier( MOD_ID, id ),
|
||||||
public static final BlockEntityType<TileWirelessModem> WIRELESS_MODEM_ADVANCED = FabricBlockEntityTypeBuilder.create(
|
blockEntityType
|
||||||
( blockPos, blockState ) -> new TileWirelessModem( ModTiles.WIRELESS_MODEM_ADVANCED, true, blockPos, blockState ),
|
);
|
||||||
ModBlocks.WIRELESS_MODEM_ADVANCED ).build();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class ModItems
|
public static final class ModItems
|
||||||
|
@@ -35,6 +35,10 @@ public abstract class BlockGeneric extends BlockWithEntity
|
|||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BlockEntityType<? extends TileGeneric> getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockRenderType getRenderType( BlockState state )
|
public BlockRenderType getRenderType( BlockState state )
|
||||||
{
|
{
|
||||||
@@ -96,6 +100,9 @@ public abstract class BlockGeneric extends BlockWithEntity
|
|||||||
@Override
|
@Override
|
||||||
public BlockEntity createBlockEntity(BlockPos pos, BlockState state)
|
public BlockEntity createBlockEntity(BlockPos pos, BlockState state)
|
||||||
{
|
{
|
||||||
return type.instantiate(pos, state);
|
if (this.type != null) {
|
||||||
|
return type.instantiate(pos, state);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -6,11 +6,16 @@
|
|||||||
|
|
||||||
package dan200.computercraft.shared.computer.blocks;
|
package dan200.computercraft.shared.computer.blocks;
|
||||||
|
|
||||||
|
import dan200.computercraft.shared.ComputerCraftRegistry;
|
||||||
|
import dan200.computercraft.shared.common.TileGeneric;
|
||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
|
import dan200.computercraft.shared.computer.core.ComputerRegistry;
|
||||||
import dan200.computercraft.shared.computer.core.ComputerState;
|
import dan200.computercraft.shared.computer.core.ComputerState;
|
||||||
import dan200.computercraft.shared.computer.items.ComputerItemFactory;
|
import dan200.computercraft.shared.computer.items.ComputerItemFactory;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.block.entity.BlockEntityTicker;
|
||||||
import net.minecraft.block.entity.BlockEntityType;
|
import net.minecraft.block.entity.BlockEntityType;
|
||||||
import net.minecraft.item.ItemPlacementContext;
|
import net.minecraft.item.ItemPlacementContext;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
@@ -18,7 +23,9 @@ import net.minecraft.state.StateManager;
|
|||||||
import net.minecraft.state.property.DirectionProperty;
|
import net.minecraft.state.property.DirectionProperty;
|
||||||
import net.minecraft.state.property.EnumProperty;
|
import net.minecraft.state.property.EnumProperty;
|
||||||
import net.minecraft.state.property.Properties;
|
import net.minecraft.state.property.Properties;
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@@ -56,4 +63,20 @@ public class BlockComputer extends BlockComputerBase<TileComputer>
|
|||||||
{
|
{
|
||||||
return tile instanceof TileComputer ? ComputerItemFactory.create( (TileComputer) tile ) : ItemStack.EMPTY;
|
return tile instanceof TileComputer ? ComputerItemFactory.create( (TileComputer) tile ) : ItemStack.EMPTY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BlockEntityType<? extends TileComputer> getTypeByFamily(ComputerFamily family)
|
||||||
|
{
|
||||||
|
return switch (family) {
|
||||||
|
case COMMAND -> ComputerCraftRegistry.ModTiles.COMPUTER_COMMAND;
|
||||||
|
case ADVANCED -> ComputerCraftRegistry.ModTiles.COMPUTER_ADVANCED;
|
||||||
|
default -> ComputerCraftRegistry.ModTiles.COMPUTER_NORMAL;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public BlockEntity createBlockEntity(BlockPos pos, BlockState state)
|
||||||
|
{
|
||||||
|
return new TileComputer(getFamily(), getTypeByFamily(getFamily()), pos, state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,13 +8,17 @@ package dan200.computercraft.shared.computer.blocks;
|
|||||||
|
|
||||||
import dan200.computercraft.ComputerCraft;
|
import dan200.computercraft.ComputerCraft;
|
||||||
import dan200.computercraft.core.computer.ComputerSide;
|
import dan200.computercraft.core.computer.ComputerSide;
|
||||||
|
import dan200.computercraft.shared.ComputerCraftRegistry;
|
||||||
import dan200.computercraft.shared.common.BlockGeneric;
|
import dan200.computercraft.shared.common.BlockGeneric;
|
||||||
import dan200.computercraft.shared.common.IBundledRedstoneBlock;
|
import dan200.computercraft.shared.common.IBundledRedstoneBlock;
|
||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import dan200.computercraft.shared.computer.core.ServerComputer;
|
import dan200.computercraft.shared.computer.core.ServerComputer;
|
||||||
import dan200.computercraft.shared.computer.items.IComputerItem;
|
import dan200.computercraft.shared.computer.items.IComputerItem;
|
||||||
|
import dan200.computercraft.shared.turtle.blocks.BlockTurtle;
|
||||||
|
import dan200.computercraft.shared.turtle.blocks.TileTurtle;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
|
import net.minecraft.block.entity.BlockEntityTicker;
|
||||||
import net.minecraft.block.entity.BlockEntityType;
|
import net.minecraft.block.entity.BlockEntityType;
|
||||||
import net.minecraft.entity.LivingEntity;
|
import net.minecraft.entity.LivingEntity;
|
||||||
import net.minecraft.entity.player.PlayerEntity;
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
@@ -211,4 +215,14 @@ public abstract class BlockComputerBase<T extends TileComputerBase> extends Bloc
|
|||||||
state.onStacksDropped( serverWorld, pos, player.getMainHandStack() );
|
state.onStacksDropped( serverWorld, pos, player.getMainHandStack() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type) {
|
||||||
|
return world.isClient ? null : (world1, pos, state1, tile) -> {
|
||||||
|
if (tile instanceof TileComputerBase computer) {
|
||||||
|
TileComputerBase.tick(world1, pos, state1, computer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,7 @@ package dan200.computercraft.shared.peripheral.diskdrive;
|
|||||||
|
|
||||||
import dan200.computercraft.shared.ComputerCraftRegistry;
|
import dan200.computercraft.shared.ComputerCraftRegistry;
|
||||||
import dan200.computercraft.shared.common.BlockGeneric;
|
import dan200.computercraft.shared.common.BlockGeneric;
|
||||||
|
import dan200.computercraft.shared.computer.blocks.TileComputer;
|
||||||
import dan200.computercraft.shared.peripheral.speaker.BlockSpeaker;
|
import dan200.computercraft.shared.peripheral.speaker.BlockSpeaker;
|
||||||
import dan200.computercraft.shared.peripheral.speaker.TileSpeaker;
|
import dan200.computercraft.shared.peripheral.speaker.TileSpeaker;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
@@ -53,13 +54,13 @@ public class BlockDiskDrive extends BlockGeneric
|
|||||||
placement.getPlayerFacing()
|
placement.getPlayerFacing()
|
||||||
.getOpposite() );
|
.getOpposite() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type){
|
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type){
|
||||||
return world.isClient ? null : BlockDiskDrive.checkType( type, ComputerCraftRegistry.ModTiles.DISK_DRIVE, TileDiskDrive::tick );
|
return world.isClient ? null : BlockDiskDrive.checkType( type, ComputerCraftRegistry.ModTiles.DISK_DRIVE, TileDiskDrive::tick );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterBreak(
|
public void afterBreak(
|
||||||
@Nonnull World world, @Nonnull PlayerEntity player, @Nonnull BlockPos pos, @Nonnull BlockState state, @Nullable BlockEntity te, @Nonnull ItemStack stack
|
@Nonnull World world, @Nonnull PlayerEntity player, @Nonnull BlockPos pos, @Nonnull BlockState state, @Nullable BlockEntity te, @Nonnull ItemStack stack
|
||||||
@@ -98,4 +99,11 @@ public class BlockDiskDrive extends BlockGeneric
|
|||||||
{
|
{
|
||||||
properties.add( FACING, STATE );
|
properties.add( FACING, STATE );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public BlockEntity createBlockEntity(BlockPos pos, BlockState state)
|
||||||
|
{
|
||||||
|
return new TileDiskDrive(ComputerCraftRegistry.ModTiles.DISK_DRIVE, pos, state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,7 +7,9 @@
|
|||||||
package dan200.computercraft.shared.peripheral.monitor;
|
package dan200.computercraft.shared.peripheral.monitor;
|
||||||
|
|
||||||
import dan200.computercraft.api.turtle.FakePlayer;
|
import dan200.computercraft.api.turtle.FakePlayer;
|
||||||
|
import dan200.computercraft.shared.ComputerCraftRegistry;
|
||||||
import dan200.computercraft.shared.common.BlockGeneric;
|
import dan200.computercraft.shared.common.BlockGeneric;
|
||||||
|
import dan200.computercraft.shared.computer.blocks.TileComputer;
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.entity.BlockEntity;
|
import net.minecraft.block.entity.BlockEntity;
|
||||||
@@ -34,9 +36,12 @@ public class BlockMonitor extends BlockGeneric
|
|||||||
|
|
||||||
static final EnumProperty<MonitorEdgeState> STATE = EnumProperty.of( "state", MonitorEdgeState.class );
|
static final EnumProperty<MonitorEdgeState> STATE = EnumProperty.of( "state", MonitorEdgeState.class );
|
||||||
|
|
||||||
public BlockMonitor( Settings settings, BlockEntityType<? extends TileMonitor> type )
|
public boolean advanced = false;
|
||||||
|
|
||||||
|
public BlockMonitor( Settings settings, BlockEntityType<? extends TileMonitor> type, boolean advanced )
|
||||||
{
|
{
|
||||||
super( settings, type );
|
super( settings, type );
|
||||||
|
this.advanced = advanced;
|
||||||
// TODO: Test underwater - do we need isSolid at all?
|
// TODO: Test underwater - do we need isSolid at all?
|
||||||
setDefaultState( getStateManager().getDefaultState()
|
setDefaultState( getStateManager().getDefaultState()
|
||||||
.with( ORIENTATION, Direction.NORTH )
|
.with( ORIENTATION, Direction.NORTH )
|
||||||
@@ -97,4 +102,11 @@ public class BlockMonitor extends BlockGeneric
|
|||||||
{
|
{
|
||||||
builder.add( ORIENTATION, FACING, STATE );
|
builder.add( ORIENTATION, FACING, STATE );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public BlockEntity createBlockEntity(BlockPos pos, BlockState state)
|
||||||
|
{
|
||||||
|
return new TileMonitor(advanced ? ComputerCraftRegistry.ModTiles.MONITOR_ADVANCED : ComputerCraftRegistry.ModTiles.MONITOR_NORMAL, advanced, pos, state);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,7 @@ package dan200.computercraft.shared.turtle.blocks;
|
|||||||
import dan200.computercraft.api.turtle.TurtleSide;
|
import dan200.computercraft.api.turtle.TurtleSide;
|
||||||
import dan200.computercraft.shared.ComputerCraftRegistry;
|
import dan200.computercraft.shared.ComputerCraftRegistry;
|
||||||
import dan200.computercraft.shared.computer.blocks.BlockComputerBase;
|
import dan200.computercraft.shared.computer.blocks.BlockComputerBase;
|
||||||
|
import dan200.computercraft.shared.computer.blocks.TileComputer;
|
||||||
import dan200.computercraft.shared.computer.blocks.TileComputerBase;
|
import dan200.computercraft.shared.computer.blocks.TileComputerBase;
|
||||||
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
import dan200.computercraft.shared.computer.core.ComputerFamily;
|
||||||
import dan200.computercraft.shared.peripheral.diskdrive.BlockDiskDrive;
|
import dan200.computercraft.shared.peripheral.diskdrive.BlockDiskDrive;
|
||||||
@@ -140,9 +141,8 @@ public class BlockTurtle extends BlockComputerBase<TileTurtle> implements Waterl
|
|||||||
super.onPlaced( world, pos, state, player, stack );
|
super.onPlaced( world, pos, state, player, stack );
|
||||||
|
|
||||||
BlockEntity tile = world.getBlockEntity( pos );
|
BlockEntity tile = world.getBlockEntity( pos );
|
||||||
if( !world.isClient && tile instanceof TileTurtle )
|
if( !world.isClient && tile instanceof TileTurtle turtle )
|
||||||
{
|
{
|
||||||
TileTurtle turtle = (TileTurtle) tile;
|
|
||||||
|
|
||||||
if( player instanceof PlayerEntity )
|
if( player instanceof PlayerEntity )
|
||||||
{
|
{
|
||||||
@@ -180,10 +180,25 @@ public class BlockTurtle extends BlockComputerBase<TileTurtle> implements Waterl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BlockEntityType<? extends TileTurtle> getTypeByFamily(ComputerFamily family)
|
||||||
|
{
|
||||||
|
if (family == ComputerFamily.ADVANCED) {
|
||||||
|
return ComputerCraftRegistry.ModTiles.TURTLE_ADVANCED;
|
||||||
|
}
|
||||||
|
return ComputerCraftRegistry.ModTiles.TURTLE_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type){
|
public BlockEntity createBlockEntity(BlockPos pos, BlockState state)
|
||||||
return world.isClient ? null : BlockTurtle.checkType( type, ComputerCraftRegistry.ModTiles.TURTLE_NORMAL, TileTurtle::tick );
|
{
|
||||||
|
return new TileTurtle(getTypeByFamily(getFamily()), pos, state, getFamily());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Nullable
|
||||||
|
// @Override
|
||||||
|
// public <T extends BlockEntity> BlockEntityTicker<T> getTicker(World world, BlockState state, BlockEntityType<T> type){
|
||||||
|
// return world.isClient ? BlockTurtle.checkType( type, getTypeByFamily(getFamily()), TileTurtle::tick ) : super.getTicker(world, state, type);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
@@ -12,7 +12,7 @@ import dan200.computercraft.api.turtle.ITurtleAccess;
|
|||||||
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
import dan200.computercraft.api.turtle.ITurtleUpgrade;
|
||||||
import dan200.computercraft.api.turtle.TurtleSide;
|
import dan200.computercraft.api.turtle.TurtleSide;
|
||||||
import dan200.computercraft.core.computer.ComputerSide;
|
import dan200.computercraft.core.computer.ComputerSide;
|
||||||
import dan200.computercraft.fabric.mixin.MixinBlockEntity;
|
import dan200.computercraft.shared.ComputerCraftRegistry;
|
||||||
import dan200.computercraft.shared.common.TileGeneric;
|
import dan200.computercraft.shared.common.TileGeneric;
|
||||||
import dan200.computercraft.shared.computer.blocks.ComputerProxy;
|
import dan200.computercraft.shared.computer.blocks.ComputerProxy;
|
||||||
import dan200.computercraft.shared.computer.blocks.TileComputerBase;
|
import dan200.computercraft.shared.computer.blocks.TileComputerBase;
|
||||||
@@ -64,10 +64,9 @@ public class TileTurtle extends TileComputerBase
|
|||||||
private TurtleBrain brain = new TurtleBrain( this );
|
private TurtleBrain brain = new TurtleBrain( this );
|
||||||
private MoveState moveState = MoveState.NOT_MOVED;
|
private MoveState moveState = MoveState.NOT_MOVED;
|
||||||
|
|
||||||
public TileTurtle( BlockEntityType<? extends TileGeneric> type,
|
public TileTurtle( BlockEntityType<? extends TileGeneric> type, BlockPos pos, BlockState state, ComputerFamily family )
|
||||||
ComputerFamily family, BlockPos pos, BlockState state )
|
|
||||||
{
|
{
|
||||||
super( type, family, pos, state );
|
super(type, family, pos, state );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -256,10 +255,10 @@ public class TileTurtle extends TileComputerBase
|
|||||||
// Open GUI or whatever
|
// Open GUI or whatever
|
||||||
return super.onActivate( player, hand, hit );
|
return super.onActivate( player, hand, hit );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setBlockPos( BlockPos pos ) {
|
// public void setBlockPos( BlockPos pos ) {
|
||||||
((MixinBlockEntity) (Object) this).setBlockPos(pos); // FIXME this looks really bad.
|
// ((MixinBlockEntity) (Object) this).setBlockPos(pos); // FIXME this looks really bad.
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNeighbourChange( @Nonnull BlockPos neighbour )
|
public void onNeighbourChange( @Nonnull BlockPos neighbour )
|
||||||
@@ -282,8 +281,8 @@ public class TileTurtle extends TileComputerBase
|
|||||||
public static void tick( World world, BlockPos pos, BlockState state,
|
public static void tick( World world, BlockPos pos, BlockState state,
|
||||||
TileTurtle tileTurtle )
|
TileTurtle tileTurtle )
|
||||||
{
|
{
|
||||||
tileTurtle.brain.update();
|
tileTurtle.brain.update();
|
||||||
if( !tileTurtle.getWorld().isClient && tileTurtle.inventoryChanged )
|
if( !world.isClient && tileTurtle.inventoryChanged )
|
||||||
{
|
{
|
||||||
ServerComputer computer = tileTurtle.getServerComputer();
|
ServerComputer computer = tileTurtle.getServerComputer();
|
||||||
if( computer != null )
|
if( computer != null )
|
||||||
@@ -565,6 +564,7 @@ public class TileTurtle extends TileComputerBase
|
|||||||
public ScreenHandler createMenu( int id, @Nonnull PlayerInventory inventory,
|
public ScreenHandler createMenu( int id, @Nonnull PlayerInventory inventory,
|
||||||
@Nonnull PlayerEntity player )
|
@Nonnull PlayerEntity player )
|
||||||
{
|
{
|
||||||
|
System.out.println(inventory.player.getDisplayName());
|
||||||
return new ContainerTurtle( id, inventory, brain );
|
return new ContainerTurtle( id, inventory, brain );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -256,7 +256,7 @@ public class TurtleBrain implements ITurtleAccess
|
|||||||
{
|
{
|
||||||
// Copy the old turtle state into the new turtle
|
// Copy the old turtle state into the new turtle
|
||||||
TileTurtle newTurtle = (TileTurtle) newTile;
|
TileTurtle newTurtle = (TileTurtle) newTile;
|
||||||
newTurtle.setBlockPos( pos ); //FIXME: setLocation no longer exists.
|
// newTurtle.setLocation( world, pos ); //FIXME: setLocation no longer exists.
|
||||||
newTurtle.transferStateFrom( oldOwner );
|
newTurtle.transferStateFrom( oldOwner );
|
||||||
newTurtle.createServerComputer()
|
newTurtle.createServerComputer()
|
||||||
.setWorld( world );
|
.setWorld( world );
|
||||||
|
@@ -23,12 +23,18 @@ import net.minecraft.network.PacketByteBuf;
|
|||||||
import net.minecraft.screen.ArrayPropertyDelegate;
|
import net.minecraft.screen.ArrayPropertyDelegate;
|
||||||
import net.minecraft.screen.PropertyDelegate;
|
import net.minecraft.screen.PropertyDelegate;
|
||||||
import net.minecraft.screen.slot.Slot;
|
import net.minecraft.screen.slot.Slot;
|
||||||
|
import net.minecraft.screen.slot.SlotActionType;
|
||||||
|
import net.minecraft.util.crash.CrashException;
|
||||||
|
import net.minecraft.util.crash.CrashReport;
|
||||||
|
import net.minecraft.util.crash.CrashReportSection;
|
||||||
|
import net.minecraft.util.registry.Registry;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
public class ContainerTurtle extends ContainerComputerBase
|
public class ContainerTurtle extends ContainerComputerBase
|
||||||
{
|
{
|
||||||
|
public static final int BORDER = 8;
|
||||||
public static final int PLAYER_START_Y = 134;
|
public static final int PLAYER_START_Y = 134;
|
||||||
public static final int TURTLE_START_X = 175;
|
public static final int TURTLE_START_X = 175;
|
||||||
|
|
||||||
@@ -53,6 +59,8 @@ public class ContainerTurtle extends ContainerComputerBase
|
|||||||
super( ComputerCraftRegistry.ModContainers.TURTLE, id, canUse, computer, family );
|
super( ComputerCraftRegistry.ModContainers.TURTLE, id, canUse, computer, family );
|
||||||
this.properties = properties;
|
this.properties = properties;
|
||||||
|
|
||||||
|
System.out.println("Contaienr Turtle init" + properties);
|
||||||
|
|
||||||
addProperties( properties );
|
addProperties( properties );
|
||||||
|
|
||||||
// Turtle inventory
|
// Turtle inventory
|
||||||
@@ -105,6 +113,7 @@ public class ContainerTurtle extends ContainerComputerBase
|
|||||||
@Override
|
@Override
|
||||||
public ItemStack transferSlot( @Nonnull PlayerEntity player, int slotNum )
|
public ItemStack transferSlot( @Nonnull PlayerEntity player, int slotNum )
|
||||||
{
|
{
|
||||||
|
System.out.println("transferSlot");
|
||||||
if( slotNum >= 0 && slotNum < 16 )
|
if( slotNum >= 0 && slotNum < 16 )
|
||||||
{
|
{
|
||||||
return tryItemMerge( player, slotNum, 16, 52, true );
|
return tryItemMerge( player, slotNum, 16, 52, true );
|
||||||
@@ -119,6 +128,7 @@ public class ContainerTurtle extends ContainerComputerBase
|
|||||||
@Nonnull
|
@Nonnull
|
||||||
private ItemStack tryItemMerge( PlayerEntity player, int slotNum, int firstSlot, int lastSlot, boolean reverse )
|
private ItemStack tryItemMerge( PlayerEntity player, int slotNum, int firstSlot, int lastSlot, boolean reverse )
|
||||||
{
|
{
|
||||||
|
System.out.println("tryItemMerge");
|
||||||
Slot slot = slots.get( slotNum );
|
Slot slot = slots.get( slotNum );
|
||||||
ItemStack originalStack = ItemStack.EMPTY;
|
ItemStack originalStack = ItemStack.EMPTY;
|
||||||
if( slot != null && slot.hasStack() )
|
if( slot != null && slot.hasStack() )
|
||||||
@@ -150,4 +160,10 @@ public class ContainerTurtle extends ContainerComputerBase
|
|||||||
}
|
}
|
||||||
return originalStack;
|
return originalStack;
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public void onSlotClick(int slotIndex, int button, SlotActionType actionType, PlayerEntity player) {
|
||||||
|
super.onSlotClick(slotIndex, button, actionType, player);
|
||||||
|
|
||||||
|
System.out.println("on slot click: " + slotIndex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,17 +3,17 @@
|
|||||||
// * Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
|
// * Copyright Daniel Ratcliffe, 2011-2021. Do not distribute without permission.
|
||||||
// * Send enquiries to dratcliffe@gmail.com
|
// * Send enquiries to dratcliffe@gmail.com
|
||||||
// */
|
// */
|
||||||
//
|
|
||||||
//package dan200.computercraft.shared.util;
|
//package dan200.computercraft.shared.util;
|
||||||
//
|
//
|
||||||
//import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
|
//import net.fabricmc.fabric.api.object.builder.v1.block.entity.FabricBlockEntityTypeBuilder;
|
||||||
//import net.minecraft.block.Block;
|
//import net.minecraft.block.Block;
|
||||||
|
//import net.minecraft.block.BlockState;
|
||||||
//import net.minecraft.block.entity.BlockEntity;
|
//import net.minecraft.block.entity.BlockEntity;
|
||||||
//import net.minecraft.block.entity.BlockEntityType;
|
//import net.minecraft.block.entity.BlockEntityType;
|
||||||
|
//import net.minecraft.util.math.BlockPos;
|
||||||
//
|
//
|
||||||
//import javax.annotation.Nonnull;
|
//import javax.annotation.Nonnull;
|
||||||
//import java.util.Collections;
|
//import java.util.Collections;
|
||||||
//import java.util.function.Function;
|
|
||||||
//import java.util.function.Supplier;
|
//import java.util.function.Supplier;
|
||||||
//
|
//
|
||||||
///**
|
///**
|
||||||
@@ -23,40 +23,52 @@
|
|||||||
// */
|
// */
|
||||||
//public final class FixedPointTileEntityType<T extends BlockEntity> extends BlockEntityType<T>
|
//public final class FixedPointTileEntityType<T extends BlockEntity> extends BlockEntityType<T>
|
||||||
//{
|
//{
|
||||||
// private final Supplier<Block> block;
|
// private final Supplier<? extends Block> block;
|
||||||
//
|
//
|
||||||
// private FixedPointTileEntityType( Supplier<Block> block, Supplier<T> builder )
|
// private FixedPointTileEntityType( Supplier<? extends Block> block, FabricBlockEntityTypeBuilder.Factory<T> builder )
|
||||||
// {
|
// {
|
||||||
// super( builder, Collections.emptySet(), null ); //FIXME: Replace with the new BlockEntity handlers.
|
// super(builder, Collections.emptySet(), null );
|
||||||
// this.block = block;
|
// this.block = block;
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// public static <T extends BlockEntity> FixedPointTileEntityType<T> create( Supplier<Block> block, Function<BlockEntityType<T>, T> builder )
|
// public static <T extends BlockEntity> FixedPointTileEntityType<T> create( Supplier<? extends Block> block, FixedPointBlockEntitySupplier<T> builder )
|
||||||
// {
|
// {
|
||||||
// return new FixedPointSupplier<>( block, builder ).factory;
|
// return new FixedPointSupplier<>( block, builder ).factory;
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
//// @Override
|
// @Override
|
||||||
//// public boolean supports( @Nonnull Block block )
|
// public boolean supports( @Nonnull BlockState block )
|
||||||
//// {
|
// {
|
||||||
//// return block == this.block.get();
|
// return block.getBlock() == this.block.get();
|
||||||
//// }
|
// }
|
||||||
//
|
//
|
||||||
// private static final class FixedPointSupplier<T extends BlockEntity> implements Supplier<T>
|
// public Block getBlock()
|
||||||
|
// {
|
||||||
|
// return block.get();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private static final class FixedPointSupplier<T extends BlockEntity> implements FabricBlockEntityTypeBuilder.Factory<T>
|
||||||
// {
|
// {
|
||||||
// final FixedPointTileEntityType<T> factory;
|
// final FixedPointTileEntityType<T> factory;
|
||||||
// private final Function<BlockEntityType<T>, T> builder;
|
// private final FixedPointBlockEntitySupplier<T> builder;
|
||||||
//
|
//
|
||||||
// private FixedPointSupplier( Supplier<Block> block, Function<BlockEntityType<T>, T> builder )
|
// private FixedPointSupplier( Supplier<? extends Block> block, FixedPointBlockEntitySupplier<T> builder )
|
||||||
// {
|
// {
|
||||||
// factory = FabricBlockEntityTypeBuilder.create( this, block );
|
// factory = new FixedPointTileEntityType<>( block, this );
|
||||||
// this.builder = builder;
|
// this.builder = builder;
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
|
// @Nonnull
|
||||||
// @Override
|
// @Override
|
||||||
// public T get()
|
// public T create(@Nonnull BlockPos pos, @Nonnull BlockState state )
|
||||||
// {
|
// {
|
||||||
// return builder.apply( factory );
|
// return builder.create( factory, pos, state );
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
//
|
||||||
|
// @FunctionalInterface
|
||||||
|
// public interface FixedPointBlockEntitySupplier<T extends BlockEntity>
|
||||||
|
// {
|
||||||
|
// T create( BlockEntityType<T> type, BlockPos pos, BlockState state );
|
||||||
|
// }
|
||||||
//}
|
//}
|
||||||
|
@@ -0,0 +1,40 @@
|
|||||||
|
#version 150
|
||||||
|
|
||||||
|
#define FONT_WIDTH 6.0
|
||||||
|
#define FONT_HEIGHT 9.0
|
||||||
|
|
||||||
|
uniform sampler2D Sampler0; // Font
|
||||||
|
uniform int Width;
|
||||||
|
uniform int Height;
|
||||||
|
uniform usamplerBuffer Tbo;
|
||||||
|
uniform vec3 Palette[16];
|
||||||
|
|
||||||
|
in vec2 f_pos;
|
||||||
|
|
||||||
|
out vec4 colour;
|
||||||
|
|
||||||
|
vec2 texture_corner(int index) {
|
||||||
|
float x = 1.0 + float(index % 16) * (FONT_WIDTH + 2.0);
|
||||||
|
float y = 1.0 + float(index / 16) * (FONT_HEIGHT + 2.0);
|
||||||
|
return vec2(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 term_pos = vec2(f_pos.x / FONT_WIDTH, f_pos.y / FONT_HEIGHT);
|
||||||
|
vec2 corner = floor(term_pos);
|
||||||
|
|
||||||
|
ivec2 cell = ivec2(corner);
|
||||||
|
int index = 3 * (clamp(cell.x, 0, Width - 1) + clamp(cell.y, 0, Height - 1) * Width);
|
||||||
|
|
||||||
|
// 1 if 0 <= x, y < Width, Height, 0 otherwise
|
||||||
|
vec2 outside = step(vec2(0.0, 0.0), vec2(cell)) * step(vec2(cell), vec2(float(Width) - 1.0, float(Height) - 1.0));
|
||||||
|
float mult = outside.x * outside.y;
|
||||||
|
|
||||||
|
int character = int(texelFetch(Tbo, index).r);
|
||||||
|
int fg = int(texelFetch(Tbo, index + 1).r);
|
||||||
|
int bg = int(texelFetch(Tbo, index + 2).r);
|
||||||
|
|
||||||
|
vec2 pos = (term_pos - corner) * vec2(FONT_WIDTH, FONT_HEIGHT);
|
||||||
|
vec4 img = texture(Sampler0, (texture_corner(character) + pos) / 256.0);
|
||||||
|
colour = vec4(mix(Palette[bg], img.rgb * Palette[fg], img.a * mult), 1.0);
|
||||||
|
}
|
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"vertex": "computercraft:monitor_tbo",
|
||||||
|
"fragment": "computercraft:monitor_tbo",
|
||||||
|
"attributes": [ "Position" ],
|
||||||
|
"samplers": [ { "name": "Sampler0" } ],
|
||||||
|
"uniforms": [
|
||||||
|
{ "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
|
||||||
|
{ "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
|
||||||
|
{ "name": "Width", "type": "int", "count": 1, "values": [ 1 ] },
|
||||||
|
{ "name": "Height", "type": "int", "count": 1, "values": [ 1 ] },
|
||||||
|
{ "name": "Tbo", "type": "int", "count": 1, "values": [ 3 ] }
|
||||||
|
]
|
||||||
|
}
|
@@ -0,0 +1,14 @@
|
|||||||
|
#version 150
|
||||||
|
|
||||||
|
in vec3 Position;
|
||||||
|
in vec2 UV0;
|
||||||
|
|
||||||
|
uniform mat4 ModelViewMat;
|
||||||
|
uniform mat4 ProjMat;
|
||||||
|
|
||||||
|
out vec2 f_pos;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = ProjMat * ModelViewMat * vec4(Position, 1);
|
||||||
|
f_pos = UV0;
|
||||||
|
}
|
@@ -0,0 +1,40 @@
|
|||||||
|
#version 140
|
||||||
|
|
||||||
|
#define FONT_WIDTH 6.0
|
||||||
|
#define FONT_HEIGHT 9.0
|
||||||
|
|
||||||
|
uniform sampler2D u_font;
|
||||||
|
uniform int u_width;
|
||||||
|
uniform int u_height;
|
||||||
|
uniform usamplerBuffer u_tbo;
|
||||||
|
uniform vec3 u_palette[16];
|
||||||
|
|
||||||
|
in vec2 f_pos;
|
||||||
|
|
||||||
|
out vec4 colour;
|
||||||
|
|
||||||
|
vec2 texture_corner(int index) {
|
||||||
|
float x = 1.0 + float(index % 16) * (FONT_WIDTH + 2.0);
|
||||||
|
float y = 1.0 + float(index / 16) * (FONT_HEIGHT + 2.0);
|
||||||
|
return vec2(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 term_pos = vec2(f_pos.x / FONT_WIDTH, f_pos.y / FONT_HEIGHT);
|
||||||
|
vec2 corner = floor(term_pos);
|
||||||
|
|
||||||
|
ivec2 cell = ivec2(corner);
|
||||||
|
int index = 3 * (clamp(cell.x, 0, u_width - 1) + clamp(cell.y, 0, u_height - 1) * u_width);
|
||||||
|
|
||||||
|
// 1 if 0 <= x, y < width, height, 0 otherwise
|
||||||
|
vec2 outside = step(vec2(0.0, 0.0), vec2(cell)) * step(vec2(cell), vec2(float(u_width) - 1.0, float(u_height) - 1.0));
|
||||||
|
float mult = outside.x * outside.y;
|
||||||
|
|
||||||
|
int character = int(texelFetch(u_tbo, index).r);
|
||||||
|
int fg = int(texelFetch(u_tbo, index + 1).r);
|
||||||
|
int bg = int(texelFetch(u_tbo, index + 2).r);
|
||||||
|
|
||||||
|
vec2 pos = (term_pos - corner) * vec2(FONT_WIDTH, FONT_HEIGHT);
|
||||||
|
vec4 img = texture(u_font, (texture_corner(character) + pos) / 256.0);
|
||||||
|
colour = vec4(mix(u_palette[bg], img.rgb * u_palette[fg], img.a * mult), 1.0);
|
||||||
|
}
|
@@ -0,0 +1,12 @@
|
|||||||
|
#version 130
|
||||||
|
|
||||||
|
uniform mat4 u_mv;
|
||||||
|
|
||||||
|
in vec3 v_pos;
|
||||||
|
|
||||||
|
out vec2 f_pos;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = gl_ProjectionMatrix * u_mv * vec4(v_pos.x, v_pos.y, 0, 1);
|
||||||
|
f_pos = v_pos.xy;
|
||||||
|
}
|
@@ -0,0 +1,40 @@
|
|||||||
|
#version 150
|
||||||
|
|
||||||
|
#define FONT_WIDTH 6.0
|
||||||
|
#define FONT_HEIGHT 9.0
|
||||||
|
|
||||||
|
uniform sampler2D Sampler0; // Font
|
||||||
|
uniform int Width;
|
||||||
|
uniform int Height;
|
||||||
|
uniform usamplerBuffer Tbo;
|
||||||
|
uniform vec3 Palette[16];
|
||||||
|
|
||||||
|
in vec2 f_pos;
|
||||||
|
|
||||||
|
out vec4 colour;
|
||||||
|
|
||||||
|
vec2 texture_corner(int index) {
|
||||||
|
float x = 1.0 + float(index % 16) * (FONT_WIDTH + 2.0);
|
||||||
|
float y = 1.0 + float(index / 16) * (FONT_HEIGHT + 2.0);
|
||||||
|
return vec2(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 term_pos = vec2(f_pos.x / FONT_WIDTH, f_pos.y / FONT_HEIGHT);
|
||||||
|
vec2 corner = floor(term_pos);
|
||||||
|
|
||||||
|
ivec2 cell = ivec2(corner);
|
||||||
|
int index = 3 * (clamp(cell.x, 0, Width - 1) + clamp(cell.y, 0, Height - 1) * Width);
|
||||||
|
|
||||||
|
// 1 if 0 <= x, y < Width, Height, 0 otherwise
|
||||||
|
vec2 outside = step(vec2(0.0, 0.0), vec2(cell)) * step(vec2(cell), vec2(float(Width) - 1.0, float(Height) - 1.0));
|
||||||
|
float mult = outside.x * outside.y;
|
||||||
|
|
||||||
|
int character = int(texelFetch(Tbo, index).r);
|
||||||
|
int fg = int(texelFetch(Tbo, index + 1).r);
|
||||||
|
int bg = int(texelFetch(Tbo, index + 2).r);
|
||||||
|
|
||||||
|
vec2 pos = (term_pos - corner) * vec2(FONT_WIDTH, FONT_HEIGHT);
|
||||||
|
vec4 img = texture(Sampler0, (texture_corner(character) + pos) / 256.0);
|
||||||
|
colour = vec4(mix(Palette[bg], img.rgb * Palette[fg], img.a * mult), 1.0);
|
||||||
|
}
|
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"vertex": "monitor_tbo",
|
||||||
|
"fragment": "monitor_tbo",
|
||||||
|
"attributes": [ "Position" ],
|
||||||
|
"samplers": [ { "name": "Sampler0" } ],
|
||||||
|
"uniforms": [
|
||||||
|
{ "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
|
||||||
|
{ "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
|
||||||
|
{ "name": "Width", "type": "int", "count": 1, "values": [ 1 ] },
|
||||||
|
{ "name": "Height", "type": "int", "count": 1, "values": [ 1 ] },
|
||||||
|
{ "name": "Tbo", "type": "int", "count": 1, "values": [ 3 ] }
|
||||||
|
]
|
||||||
|
}
|
@@ -0,0 +1,14 @@
|
|||||||
|
#version 150
|
||||||
|
|
||||||
|
in vec3 Position;
|
||||||
|
in vec2 UV0;
|
||||||
|
|
||||||
|
uniform mat4 ModelViewMat;
|
||||||
|
uniform mat4 ProjMat;
|
||||||
|
|
||||||
|
out vec2 f_pos;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = ProjMat * ModelViewMat * vec4(Position, 1);
|
||||||
|
f_pos = UV0;
|
||||||
|
}
|
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"vertex": "position_color_tex",
|
||||||
|
"fragment": "position_color_tex",
|
||||||
|
"attributes": [ "Position", "Color", "UV0" ],
|
||||||
|
"samplers": [ { "name": "Sampler0" } ],
|
||||||
|
"uniforms": [
|
||||||
|
{ "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
|
||||||
|
{ "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
|
||||||
|
{ "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] }
|
||||||
|
]
|
||||||
|
}
|
13
src/main/resources/cc.accesswidener
Normal file
13
src/main/resources/cc.accesswidener
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
accessWidener v1 named
|
||||||
|
|
||||||
|
accessible class net/minecraft/client/render/RenderLayer$MultiPhase
|
||||||
|
accessible class net/minecraft/client/render/RenderLayer$MultiPhaseParameters
|
||||||
|
accessible method net/minecraft/client/render/RenderLayer of (Ljava/lang/String;Lnet/minecraft/client/render/VertexFormat;Lnet/minecraft/client/render/VertexFormat$DrawMode;IZZLnet/minecraft/client/render/RenderLayer$MultiPhaseParameters;)Lnet/minecraft/client/render/RenderLayer$MultiPhase;
|
||||||
|
|
||||||
|
accessible class net/minecraft/client/render/RenderPhase$Shader
|
||||||
|
accessible field net/minecraft/client/render/RenderPhase ALL_MASK Lnet/minecraft/client/render/RenderPhase$WriteMaskState;
|
||||||
|
accessible field net/minecraft/client/render/RenderPhase LIGHTNING_TRANSPARENCY Lnet/minecraft/client/render/RenderPhase$Transparency;
|
||||||
|
accessible field net/minecraft/client/render/RenderPhase TRANSLUCENT_TRANSPARENCY Lnet/minecraft/client/render/RenderPhase$Transparency;
|
||||||
|
accessible field net/minecraft/client/render/RenderPhase WEATHER_TARGET Lnet/minecraft/client/render/RenderPhase$Target;
|
||||||
|
accessible field net/minecraft/client/render/RenderPhase DISABLE_LIGHTMAP Lnet/minecraft/client/render/RenderPhase$Lightmap;
|
||||||
|
accessible class net/minecraft/client/render/RenderPhase$Texture
|
@@ -13,7 +13,8 @@
|
|||||||
"SoundEventAccess",
|
"SoundEventAccess",
|
||||||
"WorldSavePathAccess",
|
"WorldSavePathAccess",
|
||||||
"MixinServerPlayerInteractionManager",
|
"MixinServerPlayerInteractionManager",
|
||||||
"MusicDiscItemAccessor"
|
"MusicDiscItemAccessor",
|
||||||
|
"GameRendererMixin"
|
||||||
],
|
],
|
||||||
"client": [
|
"client": [
|
||||||
"AffineTransformationAccess",
|
"AffineTransformationAccess",
|
||||||
|
@@ -32,6 +32,7 @@
|
|||||||
"canvas": "*",
|
"canvas": "*",
|
||||||
"iris": "*"
|
"iris": "*"
|
||||||
},
|
},
|
||||||
|
"accessWidener": "cc.accesswidener",
|
||||||
"environment": "*",
|
"environment": "*",
|
||||||
"entrypoints": {
|
"entrypoints": {
|
||||||
"main": [
|
"main": [
|
||||||
|
Reference in New Issue
Block a user