mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-06-11 15:19:00 +02:00
9098002c17
- add flywheel as a dependency to catnip
241 lines
7.9 KiB
Java
241 lines
7.9 KiB
Java
package com.simibubi.create.content.trains.display;
|
|
|
|
import java.util.List;
|
|
|
|
import com.jozufozu.flywheel.util.transform.TransformStack;
|
|
import com.mojang.blaze3d.font.GlyphInfo;
|
|
import com.mojang.blaze3d.vertex.PoseStack;
|
|
import com.mojang.blaze3d.vertex.PoseStack.Pose;
|
|
import com.mojang.blaze3d.vertex.VertexConsumer;
|
|
import com.mojang.math.Matrix4f;
|
|
import com.simibubi.create.AllPartialModels;
|
|
import com.simibubi.create.content.kinetics.base.KineticBlockEntityRenderer;
|
|
|
|
import net.createmod.catnip.render.CachedBuffers;
|
|
import net.createmod.catnip.render.SuperByteBuffer;
|
|
import net.createmod.catnip.utility.math.AngleHelper;
|
|
import net.createmod.ponder.utility.WorldTickHolder;
|
|
import net.minecraft.client.Minecraft;
|
|
import net.minecraft.client.gui.Font;
|
|
import net.minecraft.client.gui.font.FontSet;
|
|
import net.minecraft.client.gui.font.glyphs.BakedGlyph;
|
|
import net.minecraft.client.gui.font.glyphs.EmptyGlyph;
|
|
import net.minecraft.client.renderer.MultiBufferSource;
|
|
import net.minecraft.client.renderer.MultiBufferSource.BufferSource;
|
|
import net.minecraft.client.renderer.RenderType;
|
|
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
|
|
import net.minecraft.network.chat.Style;
|
|
import net.minecraft.network.chat.TextColor;
|
|
import net.minecraft.util.FormattedCharSink;
|
|
import net.minecraft.util.StringDecomposer;
|
|
import net.minecraft.world.level.Level;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraftforge.api.distmarker.Dist;
|
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
|
|
|
public class FlapDisplayRenderer extends KineticBlockEntityRenderer<FlapDisplayBlockEntity> {
|
|
|
|
public FlapDisplayRenderer(BlockEntityRendererProvider.Context context) {
|
|
super(context);
|
|
}
|
|
|
|
@Override
|
|
protected void renderSafe(FlapDisplayBlockEntity be, float partialTicks, PoseStack ms, MultiBufferSource buffer,
|
|
int light, int overlay) {
|
|
super.renderSafe(be, partialTicks, ms, buffer, light, overlay);
|
|
|
|
Font fontRenderer = Minecraft.getInstance().font;
|
|
FontSet fontSet = fontRenderer.getFontSet(Style.DEFAULT_FONT);
|
|
|
|
float scale = 1 / 32f;
|
|
|
|
if (!be.isController)
|
|
return;
|
|
|
|
List<FlapDisplayLayout> lines = be.getLines();
|
|
|
|
ms.pushPose();
|
|
TransformStack.cast(ms)
|
|
.centre()
|
|
.rotateY(AngleHelper.horizontalAngle(be.getBlockState()
|
|
.getValue(FlapDisplayBlock.HORIZONTAL_FACING)))
|
|
.unCentre()
|
|
.translate(0, 0, -3 / 16f);
|
|
|
|
ms.translate(0, 1, 1);
|
|
ms.scale(scale, scale, scale);
|
|
ms.scale(1, -1, 1);
|
|
ms.translate(0, 0, 1 / 2f);
|
|
|
|
for (int j = 0; j < lines.size(); j++) {
|
|
List<FlapDisplaySection> line = lines.get(j)
|
|
.getSections();
|
|
int color = be.getLineColor(j);
|
|
ms.pushPose();
|
|
|
|
float w = 0;
|
|
for (FlapDisplaySection section : line)
|
|
w += section.getSize() + (section.hasGap ? 8 : 1);
|
|
ms.translate(be.xSize * 16 - w / 2 + 1, 4.5f, 0);
|
|
|
|
Pose transform = ms.last();
|
|
FlapDisplayRenderOutput renderOutput = new FlapDisplayRenderOutput(buffer, color, transform.pose(), light,
|
|
j, !be.isSpeedRequirementFulfilled(), be.getLevel(), be.isLineGlowing(j));
|
|
|
|
for (int i = 0; i < line.size(); i++) {
|
|
FlapDisplaySection section = line.get(i);
|
|
renderOutput.nextSection(section);
|
|
int ticks = WorldTickHolder.getTicks(be.getLevel());
|
|
String text = section.renderCharsIndividually() || !section.spinning[0] ? section.text
|
|
: section.cyclingOptions[((ticks / 3) + i * 13) % section.cyclingOptions.length];
|
|
StringDecomposer.iterateFormatted(text, Style.EMPTY, renderOutput);
|
|
ms.translate(section.size + (section.hasGap ? 8 : 1), 0, 0);
|
|
}
|
|
|
|
if (buffer instanceof BufferSource bs) {
|
|
BakedGlyph texturedglyph = fontSet.whiteGlyph();
|
|
bs.endBatch(texturedglyph.renderType(Font.DisplayMode.NORMAL));
|
|
}
|
|
|
|
ms.popPose();
|
|
ms.translate(0, 16, 0);
|
|
}
|
|
|
|
ms.popPose();
|
|
}
|
|
|
|
@OnlyIn(Dist.CLIENT)
|
|
static class FlapDisplayRenderOutput implements FormattedCharSink {
|
|
|
|
final MultiBufferSource bufferSource;
|
|
final float r, g, b, a;
|
|
final Matrix4f pose;
|
|
final int light;
|
|
final boolean paused;
|
|
|
|
FlapDisplaySection section;
|
|
float x;
|
|
private int lineIndex;
|
|
private Level level;
|
|
|
|
public FlapDisplayRenderOutput(MultiBufferSource buffer, int color, Matrix4f pose, int light, int lineIndex,
|
|
boolean paused, Level level, boolean glowing) {
|
|
this.bufferSource = buffer;
|
|
this.lineIndex = lineIndex;
|
|
this.level = level;
|
|
this.a = glowing ? .975f : .85f;
|
|
this.r = (color >> 16 & 255) / 255f;
|
|
this.g = (color >> 8 & 255) / 255f;
|
|
this.b = (color & 255) / 255f;
|
|
this.pose = pose;
|
|
this.light = glowing ? 0xf000f0 : light;
|
|
this.paused = paused;
|
|
}
|
|
|
|
public void nextSection(FlapDisplaySection section) {
|
|
this.section = section;
|
|
x = 0;
|
|
}
|
|
|
|
public boolean accept(int charIndex, Style style, int glyph) {
|
|
FontSet fontset = getFontSet();
|
|
int ticks = paused ? 0 : WorldTickHolder.getTicks(level);
|
|
float time = paused ? 0 : WorldTickHolder.getRenderTime(level);
|
|
float dim = 1;
|
|
|
|
if (section.renderCharsIndividually() && section.spinning[Math.min(charIndex, section.spinning.length)]) {
|
|
float speed = section.spinningTicks > 5 && section.spinningTicks < 20 ? 1.75f : 2.5f;
|
|
float cycle = (time / speed) + charIndex * 16.83f + lineIndex * 0.75f;
|
|
float partial = cycle % 1;
|
|
char cyclingGlyph = section.cyclingOptions[((int) cycle) % section.cyclingOptions.length].charAt(0);
|
|
glyph = paused ? cyclingGlyph : partial > 1 / 2f ? partial > 3 / 4f ? '_' : '-' : cyclingGlyph;
|
|
dim = 0.75f;
|
|
}
|
|
|
|
GlyphInfo glyphinfo = fontset.getGlyphInfo(glyph);
|
|
float glyphWidth = glyphinfo.getAdvance(false);
|
|
|
|
if (!section.renderCharsIndividually() && section.spinning[0]) {
|
|
glyph = ticks % 3 == 0 ? glyphWidth == 6 ? '-' : glyphWidth == 1 ? '\'' : glyph : glyph;
|
|
glyph = ticks % 3 == 2 ? glyphWidth == 6 ? '_' : glyphWidth == 1 ? '.' : glyph : glyph;
|
|
if (ticks % 3 != 1)
|
|
dim = 0.75f;
|
|
}
|
|
|
|
BakedGlyph bakedglyph =
|
|
style.isObfuscated() && glyph != 32 ? fontset.getRandomGlyph(glyphinfo) : fontset.getGlyph(glyph);
|
|
TextColor textcolor = style.getColor();
|
|
|
|
float red = this.r * dim;
|
|
float green = this.g * dim;
|
|
float blue = this.b * dim;
|
|
|
|
if (textcolor != null) {
|
|
int i = textcolor.getValue();
|
|
red = (i >> 16 & 255) / 255f;
|
|
green = (i >> 8 & 255) / 255f;
|
|
blue = (i & 255) / 255f;
|
|
}
|
|
|
|
float standardWidth = section.wideFlaps ? FlapDisplaySection.WIDE_MONOSPACE : FlapDisplaySection.MONOSPACE;
|
|
|
|
if (section.renderCharsIndividually())
|
|
x += (standardWidth - glyphWidth) / 2f;
|
|
|
|
if (isNotEmpty(bakedglyph)) {
|
|
VertexConsumer vertexconsumer = bufferSource.getBuffer(renderTypeOf(bakedglyph));
|
|
bakedglyph.render(style.isItalic(), x, 0, pose, vertexconsumer, red, green, blue, a, light);
|
|
}
|
|
|
|
if (section.renderCharsIndividually())
|
|
x += standardWidth - (standardWidth - glyphWidth) / 2f;
|
|
else
|
|
x += glyphWidth;
|
|
|
|
return true;
|
|
}
|
|
|
|
public float finish(int bgColor) {
|
|
if (bgColor == 0)
|
|
return x;
|
|
|
|
float a = (bgColor >> 24 & 255) / 255f;
|
|
float r = (bgColor >> 16 & 255) / 255f;
|
|
float g = (bgColor >> 8 & 255) / 255f;
|
|
float b = (bgColor & 255) / 255f;
|
|
|
|
BakedGlyph bakedglyph = getFontSet().whiteGlyph();
|
|
VertexConsumer vertexconsumer = bufferSource.getBuffer(renderTypeOf(bakedglyph));
|
|
bakedglyph.renderEffect(new BakedGlyph.Effect(-1f, 9f, section.size, -2f, 0.01f, r, g, b, a), this.pose,
|
|
vertexconsumer, light);
|
|
|
|
return x;
|
|
}
|
|
|
|
private FontSet getFontSet() {
|
|
return Minecraft.getInstance().font.getFontSet(Style.DEFAULT_FONT);
|
|
}
|
|
|
|
private RenderType renderTypeOf(BakedGlyph bakedglyph) {
|
|
return bakedglyph.renderType(Font.DisplayMode.NORMAL);
|
|
}
|
|
|
|
private boolean isNotEmpty(BakedGlyph bakedglyph) {
|
|
return !(bakedglyph instanceof EmptyGlyph);
|
|
}
|
|
|
|
}
|
|
|
|
@Override
|
|
protected SuperByteBuffer getRotatedModel(FlapDisplayBlockEntity be, BlockState state) {
|
|
return CachedBuffers.partialFacingVertical(AllPartialModels.SHAFTLESS_COGWHEEL, state,
|
|
state.getValue(FlapDisplayBlock.HORIZONTAL_FACING));
|
|
}
|
|
|
|
@Override
|
|
public boolean shouldRenderOffScreen(FlapDisplayBlockEntity be) {
|
|
return be.isController;
|
|
}
|
|
|
|
}
|