1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-11-05 01:26:20 +00:00

Document some of our client classes

This is mostly aiming to give an overview rather than be anything
comprehensive (there's another 230+ undocumented classes to go :p), but
it's a start.

Mostly just an excuse for me to procrastinate working on the nasty bugs
though!
This commit is contained in:
Jonathan Coates 2023-06-02 21:47:52 +01:00
parent 12ca8583f4
commit 4d064d1552
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
36 changed files with 181 additions and 53 deletions

View File

@ -9,7 +9,11 @@ import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.api.turtle.TurtleUpgradeSerialiser;
import dan200.computercraft.impl.client.ComputerCraftAPIClientService;
/**
* The public API for client-only code.
*
* @see dan200.computercraft.api.ComputerCraftAPI The main API
*/
public final class ComputerCraftAPIClient {
private ComputerCraftAPIClient() {
}

View File

@ -11,6 +11,7 @@ import net.minecraft.ChatFormatting;
import net.minecraft.client.GuiMessageTag;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.components.ChatComponent;
import net.minecraft.network.chat.Component;
import net.minecraft.util.Mth;
import org.apache.commons.lang3.StringUtils;
@ -18,6 +19,12 @@ import org.apache.commons.lang3.StringUtils;
import javax.annotation.Nullable;
import java.util.Objects;
/**
* A {@link TableFormatter} subclass which writes directly to {@linkplain ChatComponent the chat GUI}.
* <p>
* Each message written gets a special {@link GuiMessageTag}, so we can remove the previous table of the same
* {@link TableBuilder#getId() id}.
*/
public class ClientTableFormatter implements TableFormatter {
public static final ClientTableFormatter INSTANCE = new ClientTableFormatter();

View File

@ -4,6 +4,11 @@
package dan200.computercraft.client;
/**
* Tracks the current client-side tick and frame.
* <p>
* These are updated via {@link ClientHooks}.
*/
public final class FrameInfo {
private static int tick;
private static long renderFrame;

View File

@ -39,6 +39,12 @@ import java.util.concurrent.TimeUnit;
import static dan200.computercraft.core.util.Nullability.assertNonNull;
/**
* The base class of all screens with a computer terminal (i.e. {@link ComputerScreen}). This works with
* {@link AbstractComputerMenu} to handle the common behaviour such as the terminal, input and file uploading.
*
* @param <T> The concrete type of the associated menu.
*/
public abstract class AbstractComputerScreen<T extends AbstractComputerMenu> extends AbstractContainerScreen<T> {
private static final Logger LOG = LoggerFactory.getLogger(AbstractComputerScreen.class);

View File

@ -16,9 +16,9 @@ import net.minecraft.world.inventory.AbstractContainerMenu;
import javax.annotation.Nullable;
/**
* An {@link InputHandler} which for use on the client.
* An {@link InputHandler} for use on the client.
* <p>
* This queues events on the remote player's open {@link ComputerMenu}
* This queues events on the remote player's open {@link ComputerMenu}.
*/
public final class ClientInputHandler implements InputHandler {
private final AbstractContainerMenu menu;

View File

@ -15,6 +15,13 @@ import net.minecraft.world.entity.player.Inventory;
import static dan200.computercraft.client.render.ComputerBorderRenderer.BORDER;
import static dan200.computercraft.client.render.RenderTypes.FULL_BRIGHT_LIGHTMAP;
/**
* A GUI for computers which renders the terminal (and border), but with no UI elements.
* <p>
* This is used by computers and pocket computers.
*
* @param <T> The concrete type of the associated menu.
*/
public final class ComputerScreen<T extends AbstractComputerMenu> extends AbstractComputerScreen<T> {
public ComputerScreen(T container, Inventory player, Component title) {
super(container, player, title, BORDER);

View File

@ -12,7 +12,9 @@ import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Inventory;
/**
* The GUI for disk drives.
*/
public class DiskDriveScreen extends AbstractContainerScreen<DiskDriveMenu> {
private static final ResourceLocation BACKGROUND = new ResourceLocation("computercraft", "textures/gui/disk_drive.png");

View File

@ -19,6 +19,11 @@ import javax.annotation.Nullable;
import static dan200.computercraft.core.util.Nullability.assertNonNull;
/**
* The GUI for off-hand computers. This accepts keyboard input, but does not render a terminal.
*
* @param <T> The concrete type of the associated menu.
*/
public class NoTermComputerScreen<T extends AbstractComputerMenu> extends Screen implements MenuAccess<T> {
private final T menu;
private final Terminal terminalData;

View File

@ -19,6 +19,11 @@ import java.util.List;
import static dan200.computercraft.core.util.Nullability.assertNonNull;
/**
* A screen which displays a series of buttons (such as a yes/no prompt).
* <p>
* When closed, it returns to the previous screen.
*/
public final class OptionScreen extends Screen {
private static final ResourceLocation BACKGROUND = new ResourceLocation("computercraft", "textures/gui/blank_screen.png");

View File

@ -12,7 +12,9 @@ import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.player.Inventory;
/**
* The GUI for printers.
*/
public class PrinterScreen extends AbstractContainerScreen<PrinterMenu> {
private static final ResourceLocation BACKGROUND = new ResourceLocation("computercraft", "textures/gui/printer.png");

View File

@ -19,6 +19,11 @@ import org.lwjgl.glfw.GLFW;
import static dan200.computercraft.client.render.PrintoutRenderer.*;
import static dan200.computercraft.client.render.RenderTypes.FULL_BRIGHT_LIGHTMAP;
/**
* The GUI for printed pages and books.
*
* @see dan200.computercraft.client.render.PrintoutRenderer
*/
public class PrintoutScreen extends AbstractContainerScreen<HeldItemMenu> {
private final boolean book;
private final int pages;

View File

@ -19,6 +19,9 @@ import net.minecraft.world.entity.player.Inventory;
import static dan200.computercraft.shared.turtle.inventory.TurtleMenu.*;
/**
* The GUI for turtles.
*/
public class TurtleScreen extends AbstractComputerScreen<TurtleMenu> {
private static final ResourceLocation BACKGROUND_NORMAL = new ResourceLocation(ComputerCraftAPI.MOD_ID, "textures/gui/turtle_normal.png");
private static final ResourceLocation BACKGROUND_ADVANCED = new ResourceLocation(ComputerCraftAPI.MOD_ID, "textures/gui/turtle_advanced.png");

View File

@ -25,6 +25,12 @@ import static dan200.computercraft.client.render.ComputerBorderRenderer.MARGIN;
import static dan200.computercraft.client.render.text.FixedWidthFontRenderer.FONT_HEIGHT;
import static dan200.computercraft.client.render.text.FixedWidthFontRenderer.FONT_WIDTH;
/**
* A widget which renders a computer terminal and handles input events (keyboard, mouse, clipboard) and computer
* shortcuts (terminate/shutdown/reboot).
*
* @see dan200.computercraft.client.gui.ClientInputHandler The input handler typically used with this class.
*/
public class TerminalWidget extends AbstractWidget {
private static final Component DESCRIPTION = Component.translatable("gui.computercraft.terminal");

View File

@ -13,6 +13,10 @@ import net.minecraft.client.renderer.RenderType;
import net.minecraft.resources.ResourceLocation;
import org.joml.Matrix4f;
/**
* Renders the borders of computers, either for a GUI ({@link dan200.computercraft.client.gui.ComputerScreen}) or
* {@linkplain PocketItemRenderer in-hand pocket computers}.
*/
public class ComputerBorderRenderer {
public static final ResourceLocation BACKGROUND_NORMAL = new ResourceLocation(ComputerCraftAPI.MOD_ID, "textures/gui/corners_normal.png");
public static final ResourceLocation BACKGROUND_ADVANCED = new ResourceLocation(ComputerCraftAPI.MOD_ID, "textures/gui/corners_advanced.png");

View File

@ -9,14 +9,19 @@ import com.mojang.math.Axis;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ItemInHandRenderer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.block.model.ItemTransforms;
import net.minecraft.util.Mth;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.entity.HumanoidArm;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
/**
* A base class for items which have map-like rendering when held in the hand.
*
* @see dan200.computercraft.client.ClientHooks#onRenderHeldItem(PoseStack, MultiBufferSource, int, InteractionHand, float, float, float, ItemStack)
*/
public abstract class ItemMapLikeRenderer {
/**
* The main rendering method for the item.
@ -25,7 +30,7 @@ public abstract class ItemMapLikeRenderer {
* @param render The buffer to render to
* @param stack The stack to render
* @param light The packed lightmap coordinates.
* @see ItemInHandRenderer#renderItem(LivingEntity, ItemStack, ItemTransforms.TransformType, boolean, PoseStack, MultiBufferSource, int)
* @see ItemInHandRenderer#renderItem(LivingEntity, ItemStack, ItemDisplayContext, boolean, PoseStack, MultiBufferSource, int)
*/
protected abstract void renderItem(PoseStack transform, MultiBufferSource render, ItemStack stack, int light);

View File

@ -15,6 +15,10 @@ import org.joml.Matrix4f;
import static dan200.computercraft.client.render.text.FixedWidthFontRenderer.FONT_HEIGHT;
import static dan200.computercraft.shared.media.items.PrintoutItem.LINES_PER_PAGE;
/**
* Renders printed pages or books, either for a GUI ({@link dan200.computercraft.client.gui.PrintoutScreen}) or
* {@linkplain PrintoutItemRenderer in-hand/item frame printouts}.
*/
public final class PrintoutRenderer {
private static final float BG_SIZE = 256.0f;

View File

@ -22,6 +22,9 @@ import java.util.Objects;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
/**
* Shared {@link RenderType}s used throughout the mod.
*/
public class RenderTypes {
public static final int FULL_BRIGHT_LIGHTMAP = (0xF << 4) | (0xF << 20);

View File

@ -20,6 +20,13 @@ import javax.annotation.Nullable;
import java.util.HashSet;
import java.util.Set;
/**
* Holds the client-side state of a monitor. This both tracks the last place a monitor was rendered at (see the comments
* in {@link MonitorBlockEntityRenderer}) and the current OpenGL buffers allocated for this object.
* <p>
* This is automatically cleared by {@link dan200.computercraft.shared.peripheral.monitor.MonitorBlockEntity} when the
* entity is unloaded on the client side (see {@link MonitorRenderState#close()}).
*/
public class MonitorRenderState implements ClientMonitor.RenderState {
@GuardedBy("allMonitors")
private static final Set<MonitorRenderState> allMonitors = new HashSet<>();

View File

@ -7,6 +7,7 @@ package dan200.computercraft.client.render.monitor;
import com.mojang.blaze3d.shaders.Uniform;
import com.mojang.blaze3d.vertex.VertexFormat;
import dan200.computercraft.client.FrameInfo;
import dan200.computercraft.client.render.RenderTypes;
import dan200.computercraft.client.render.text.FixedWidthFontRenderer;
import dan200.computercraft.core.terminal.Terminal;
import dan200.computercraft.core.terminal.TextBuffer;
@ -24,6 +25,16 @@ import java.nio.ByteBuffer;
import static dan200.computercraft.client.render.text.FixedWidthFontRenderer.getColour;
/**
* The shader used for the monitor TBO renderer.
* <p>
* This extends Minecraft's default shader loading code to extract out the TBO buffer and handle our custom uniforms
* ({@code MonitorData}, {@code CursorBlink}).
* <p>
* See also {@code monitor_tbo.fsh} and {@code monitor_tbo.vsh} in the mod's resources.
*
* @see RenderTypes#getMonitorTextureBufferShader()
*/
public class MonitorTextureBufferShader extends ShaderInstance {
public static final int UNIFORM_SIZE = 4 * 4 * 16 + 4 + 4 + 2 * 4 + 4;

View File

@ -13,13 +13,18 @@ import org.lwjgl.BufferUtils;
import javax.annotation.Nullable;
import javax.sound.sampled.AudioFormat;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayDeque;
import java.util.Queue;
import java.util.concurrent.Executor;
/**
* An {@link AudioStream} which decodes DFPWM streams, converting them to PCM.
*
* @see SpeakerPeripheral Server-side encoding of the audio.
* @see SpeakerInstance
*/
class DfpwmStream implements AudioStream {
private static final int PREC = 10;
private static final int LPF_STRENGTH = 140;
@ -128,7 +133,7 @@ class DfpwmStream implements AudioStream {
}
@Override
public void close() throws IOException {
public void close() {
buffers.clear();
}

View File

@ -20,6 +20,14 @@ import net.minecraft.world.entity.Entity;
import javax.annotation.Nullable;
import java.util.concurrent.CompletableFuture;
/**
* A sound played by a speaker. This has two purposes:
*
* <ul>
* <li>Tracks a {@link SpeakerPosition}, ensuring the sound moves around with the speaker's owner.</li>
* <li>Provides a {@link DfpwmStream} when playing custom audio.</li>
* </ul>
*/
public class SpeakerSound extends AbstractSoundInstance implements TickableSoundInstance {
@Nullable
DfpwmStream stream;

View File

@ -13,6 +13,9 @@ import dan200.computercraft.shared.turtle.upgrades.TurtleModem;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.Nullable;
/**
* A {@link TurtleUpgradeModeller} for modems, providing different models depending on if the modem is on/off.
*/
public class TurtleModemModeller implements TurtleUpgradeModeller<TurtleModem> {
private final ResourceLocation leftOffModel;
private final ResourceLocation rightOffModel;

View File

@ -20,6 +20,11 @@ import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
/**
* A registry of {@link TurtleUpgradeModeller}s.
*
* @see dan200.computercraft.api.client.ComputerCraftAPIClient#registerTurtleUpgradeModeller(TurtleUpgradeSerialiser, TurtleUpgradeModeller)
*/
public final class TurtleUpgradeModellers {
private static final TurtleUpgradeModeller<ITurtleUpgrade> NULL_TURTLE_MODELLER = (upgrade, turtle, side) ->
new TransformedModel(Minecraft.getInstance().getModelManager().getMissingModel(), Transformation.identity());

View File

@ -64,7 +64,6 @@ public final class CommandComputerCraft {
var source = context.getSource();
List<ServerComputer> computers = new ArrayList<>(ServerContext.get(source.getServer()).registry().getComputers());
// Unless we're on a server, limit the number of rows we can send.
Level world = source.getLevel();
var pos = BlockPos.containing(source.getPosition());
@ -125,7 +124,7 @@ public final class CommandComputerCraft {
if (computer.isOn()) shutdown++;
computer.shutdown();
}
context.getSource().sendSuccess(translate("commands.computercraft.shutdown.done", shutdown, computers.size()), false);
context.getSource().sendSuccess(Component.translatable("commands.computercraft.shutdown.done", shutdown, computers.size()), false);
return shutdown;
}))
@ -139,7 +138,7 @@ public final class CommandComputerCraft {
if (!computer.isOn()) on++;
computer.turnOn();
}
context.getSource().sendSuccess(translate("commands.computercraft.turn_on.done", on, computers.size()), false);
context.getSource().sendSuccess(Component.translatable("commands.computercraft.turn_on.done", on, computers.size()), false);
return on;
}))
@ -214,8 +213,8 @@ public final class CommandComputerCraft {
getMetricsInstance(context.getSource()).start();
var stopCommand = "/computercraft track stop";
context.getSource().sendSuccess(translate("commands.computercraft.track.start.stop",
link(text(stopCommand), stopCommand, translate("commands.computercraft.track.stop.action"))), false);
Object[] args = new Object[]{ link(text(stopCommand), stopCommand, Component.translatable("commands.computercraft.track.stop.action")) };
context.getSource().sendSuccess(Component.translatable("commands.computercraft.track.start.stop", args), false);
return 1;
}))
@ -255,7 +254,7 @@ public final class CommandComputerCraft {
out.append(link(
text(Integer.toString(serverComputer.getInstanceID())),
"/computercraft dump " + serverComputer.getInstanceID(),
translate("commands.computercraft.dump.action")
Component.translatable("commands.computercraft.dump.action")
));
}
@ -269,13 +268,13 @@ public final class CommandComputerCraft {
.append(link(
text("\u261b"),
"/computercraft tp " + serverComputer.getInstanceID(),
translate("commands.computercraft.tp.action")
Component.translatable("commands.computercraft.tp.action")
))
.append(" ")
.append(link(
text("\u20e2"),
"/computercraft view " + serverComputer.getInstanceID(),
translate("commands.computercraft.view.action")
Component.translatable("commands.computercraft.view.action")
));
}
@ -292,7 +291,7 @@ public final class CommandComputerCraft {
return link(
position(computer.getPosition()),
"/computercraft tp " + computer.getInstanceID(),
translate("commands.computercraft.tp.action")
Component.translatable("commands.computercraft.tp.action")
);
} else {
return position(computer.getPosition());
@ -306,7 +305,7 @@ public final class CommandComputerCraft {
return link(
text("\u270E"),
"/" + OPEN_COMPUTER + id,
translate("commands.computercraft.dump.open_path")
Component.translatable("commands.computercraft.dump.open_path")
);
}
@ -331,7 +330,7 @@ public final class CommandComputerCraft {
timings.sort(Comparator.<ComputerMetrics, Long>comparing(x -> x.get(sortField.metric(), sortField.aggregate())).reversed());
var headers = new Component[1 + fields.size()];
headers[0] = translate("commands.computercraft.track.dump.computer");
headers[0] = Component.translatable("commands.computercraft.track.dump.computer");
for (var i = 0; i < fields.size(); i++) headers[i + 1] = fields.get(i).displayName();
var table = new TableBuilder("Metrics", headers);

View File

@ -21,7 +21,6 @@ import java.util.Collection;
import static dan200.computercraft.core.util.Nullability.assertNonNull;
import static dan200.computercraft.shared.command.text.ChatHelpers.coloured;
import static dan200.computercraft.shared.command.text.ChatHelpers.translate;
/**
* An alternative to {@link LiteralArgumentBuilder} which also provides a {@code /... help} command, and defaults
@ -77,7 +76,7 @@ public final class HelpingArgumentBuilder extends LiteralArgumentBuilder<Command
private LiteralCommandNode<CommandSourceStack> buildImpl(String id, String command) {
var helpCommand = new HelpCommand(id, command);
var node = new LiteralCommandNode<CommandSourceStack>(getLiteral(), helpCommand, getRequirement(), getRedirect(), getRedirectModifier(), isFork());
var node = new LiteralCommandNode<>(getLiteral(), helpCommand, getRequirement(), getRedirect(), getRedirectModifier(), isFork());
helpCommand.node = node;
// Set up a /... help command
@ -153,9 +152,9 @@ public final class HelpingArgumentBuilder extends LiteralArgumentBuilder<Command
var output = Component.literal("")
.append(coloured("/" + command + usage, HEADER))
.append(" ")
.append(coloured(translate("commands." + id + ".synopsis"), SYNOPSIS))
.append(Component.translatable("commands." + id + ".synopsis").withStyle(SYNOPSIS))
.append("\n")
.append(translate("commands." + id + ".desc"));
.append(Component.translatable("commands." + id + ".desc"));
for (var child : node.getChildren()) {
if (!child.getRequirement().test(context.getSource()) || !(child instanceof LiteralCommandNode)) {
@ -171,7 +170,7 @@ public final class HelpingArgumentBuilder extends LiteralArgumentBuilder<Command
));
output.append(component);
output.append(" - ").append(translate("commands." + id + "." + child.getName() + ".synopsis"));
output.append(" - ").append(Component.translatable("commands." + id + "." + child.getName() + ".synopsis"));
}
return output;

View File

@ -23,28 +23,15 @@ public final class ChatHelpers {
}
public static MutableComponent coloured(@Nullable String text, ChatFormatting colour) {
return Component.literal(text == null ? "" : text).withStyle(colour);
}
public static <T extends MutableComponent> T coloured(T component, ChatFormatting colour) {
component.withStyle(colour);
return component;
return text(text).withStyle(colour);
}
public static MutableComponent text(@Nullable String text) {
return Component.literal(text == null ? "" : text);
}
public static MutableComponent translate(@Nullable String text) {
return Component.translatable(text == null ? "" : text);
}
public static MutableComponent translate(@Nullable String text, Object... args) {
return Component.translatable(text == null ? "" : text, args);
}
public static MutableComponent list(Component... children) {
var component = Component.literal("");
var component = Component.empty();
for (var child : children) {
component.append(child);
}
@ -52,14 +39,14 @@ public final class ChatHelpers {
}
public static MutableComponent position(@Nullable BlockPos pos) {
if (pos == null) return translate("commands.computercraft.generic.no_position");
return translate("commands.computercraft.generic.position", pos.getX(), pos.getY(), pos.getZ());
if (pos == null) return Component.translatable("commands.computercraft.generic.no_position");
return Component.translatable("commands.computercraft.generic.position", pos.getX(), pos.getY(), pos.getZ());
}
public static MutableComponent bool(boolean value) {
return value
? coloured(translate("commands.computercraft.generic.yes"), ChatFormatting.GREEN)
: coloured(translate("commands.computercraft.generic.no"), ChatFormatting.RED);
? Component.translatable("commands.computercraft.generic.yes").withStyle(ChatFormatting.GREEN)
: Component.translatable("commands.computercraft.generic.no").withStyle(ChatFormatting.RED);
}
public static Component link(MutableComponent component, String command, Component toolTip) {
@ -81,10 +68,9 @@ public final class ChatHelpers {
}
public static MutableComponent copy(String text) {
var name = Component.literal(text);
var style = name.getStyle()
return Component.literal(text).withStyle(s -> s
.withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, text))
.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.translatable("gui.computercraft.tooltip.copy")));
return name.withStyle(style);
.withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.translatable("gui.computercraft.tooltip.copy")))
);
}
}

View File

@ -11,7 +11,6 @@ import org.apache.commons.lang3.StringUtils;
import javax.annotation.Nullable;
import static dan200.computercraft.shared.command.text.ChatHelpers.coloured;
import static dan200.computercraft.shared.command.text.ChatHelpers.translate;
public interface TableFormatter {
Component SEPARATOR = coloured("| ", ChatFormatting.GRAY);
@ -99,7 +98,7 @@ public interface TableFormatter {
}
if (table.getAdditional() > 0) {
writeLine(id, coloured(translate("commands.computercraft.generic.additional_rows", table.getAdditional()), ChatFormatting.AQUA));
writeLine(id, Component.translatable("commands.computercraft.generic.additional_rows", table.getAdditional()).withStyle(ChatFormatting.AQUA));
}
}
}

View File

@ -11,7 +11,7 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
/**
* A basic implementation of {@link Container} which operates on a {@linkplain #getContents() stack of items}.
* A basic implementation of {@link Container} which operates on a {@linkplain #getContents() list of stacks}.
*/
public interface BasicContainer extends Container {
NonNullList<ItemStack> getContents();

View File

@ -11,7 +11,7 @@ import net.minecraft.world.item.ItemStack;
import javax.annotation.Nullable;
/**
* A basic implementation of {@link WorldlyContainer} which operates on a {@linkplain #getContents() stack of items}.
* A basic implementation of {@link WorldlyContainer} which operates on a {@linkplain #getContents() list of stacks}.
*/
public interface BasicWorldlyContainer extends BasicContainer, WorldlyContainer {
@Override

View File

@ -9,7 +9,12 @@ import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
/**
* A slot which is invisible and cannot be interacted with.
* <p>
* This is used to ensure inventory slots (normally the hotbar) are synced between client and server, when not actually
* visible in the GUI.
*/
public class InvisibleSlot extends Slot {
public InvisibleSlot(Container container, int slot) {
super(container, slot, 0, 0);

View File

@ -10,6 +10,9 @@ import net.minecraft.world.item.ItemStack;
import java.util.function.Predicate;
/**
* A slot which only accepts items matching a predicate.
*/
public class ValidatingSlot extends Slot {
private final Predicate<ItemStack> predicate;

View File

@ -17,6 +17,11 @@ import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
/**
* The custom model for turtle items, which renders tools and overlays as part of the model.
*
* @see TurtleModelParts
*/
public class TurtleModel extends ForwardingBakedModel {
private final TurtleModelParts parts;

View File

@ -19,6 +19,12 @@ import java.util.List;
import java.util.Objects;
import java.util.function.Function;
/**
* A model "loader" (the concept doesn't quite exist in the same way as it does on Forge) for turtle item models.
* <p>
* This reads in the associated model file (typically {@code computercraft:block/turtle_xxx}) and wraps it in a
* {@link TurtleModel}.
*/
public final class TurtleModelLoader {
private static final ResourceLocation COLOUR_TURTLE_MODEL = new ResourceLocation(ComputerCraftAPI.MOD_ID, "block/turtle_colour");

View File

@ -18,6 +18,9 @@ import net.minecraftforge.client.model.data.ModelData;
import javax.annotation.Nullable;
import java.util.List;
/**
* A {@link BakedModel} which applies a transformation matrix to its underlying quads.
*/
public class TransformedBakedModel extends BakedModelWrapper<BakedModel> {
private final Transformation transformation;
private final boolean invert;

View File

@ -15,6 +15,11 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* The custom model for turtle items, which renders tools and overlays as part of the model.
*
* @see TurtleModelParts
*/
public class TurtleModel extends BakedModelWrapper<BakedModel> {
private final TurtleModelParts parts;
private final Map<TurtleModelParts.Combination, List<BakedModel>> cachedModels = new HashMap<>();

View File

@ -21,6 +21,12 @@ import net.minecraftforge.client.model.geometry.IUnbakedGeometry;
import java.util.function.Function;
/**
* A model loader for turtle item models.
* <p>
* This reads in the associated model file (typically {@code computercraft:block/turtle_xxx}) and wraps it in a
* {@link TurtleModel}.
*/
public final class TurtleModelLoader implements IGeometryLoader<TurtleModelLoader.Unbaked> {
private static final ResourceLocation COLOUR_TURTLE_MODEL = new ResourceLocation(ComputerCraftAPI.MOD_ID, "block/turtle_colour");