tagging along

- added tags and chapters to the ponder registry
- slightly changed how scenes are registered
- added a back stack to the screen opener and some animations to go along with it
- added a interface for icons drawn into screens
This commit is contained in:
zelophed 2021-03-04 12:53:24 +01:00
parent 2e1129a3a5
commit d590b23aa7
30 changed files with 1619 additions and 171 deletions

View file

@ -1,10 +1,5 @@
package com.simibubi.create;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher;
import com.simibubi.create.content.contraptions.relays.encased.CasingConnectivity;
@ -14,6 +9,7 @@ import com.simibubi.create.content.schematics.client.SchematicHandler;
import com.simibubi.create.foundation.ResourceReloadHandler;
import com.simibubi.create.foundation.block.render.CustomBlockModels;
import com.simibubi.create.foundation.block.render.SpriteShifter;
import com.simibubi.create.foundation.gui.UIRenderHelper;
import com.simibubi.create.foundation.item.CustomItemModels;
import com.simibubi.create.foundation.item.CustomRenderedItems;
import com.simibubi.create.foundation.ponder.content.PonderIndex;
@ -24,7 +20,6 @@ import com.simibubi.create.foundation.render.backend.Backend;
import com.simibubi.create.foundation.render.backend.OptifineHandler;
import com.simibubi.create.foundation.utility.ghost.GhostBlocks;
import com.simibubi.create.foundation.utility.outliner.Outliner;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BlockModelShapes;
@ -42,6 +37,11 @@ import net.minecraftforge.client.model.ModelLoader;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
public class CreateClient {
public static ClientSchematicLoader schematicSender;
@ -90,6 +90,9 @@ public class CreateClient {
getColorHandler().init();
AllFluids.assignRenderLayers();
PonderIndex.register();
PonderIndex.registerTags();
UIRenderHelper.init();
IResourceManager resourceManager = Minecraft.getInstance()
.getResourceManager();

View file

@ -1,8 +1,5 @@
package com.simibubi.create.events;
import java.util.ArrayList;
import java.util.List;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.AllFluids;
@ -25,7 +22,6 @@ import com.simibubi.create.content.curiosities.zapper.blockzapper.BlockzapperRen
import com.simibubi.create.content.curiosities.zapper.terrainzapper.WorldshaperRenderHandler;
import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionPointHandler;
import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.gui.ScreenOpener;
import com.simibubi.create.foundation.item.TooltipHelper;
import com.simibubi.create.foundation.networking.AllPackets;
import com.simibubi.create.foundation.networking.LeftClickPacket;
@ -40,7 +36,6 @@ import com.simibubi.create.foundation.tileEntity.behaviour.scrollvalue.ScrollVal
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.ServerSpeedProvider;
import com.simibubi.create.foundation.utility.placement.PlacementHelpers;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.client.renderer.IRenderTypeBuffer;
@ -68,6 +63,9 @@ import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.Mod.EventBusSubscriber;
import java.util.ArrayList;
import java.util.List;
@EventBusSubscriber(value = Dist.CLIENT)
public class ClientEvents {
@ -95,7 +93,7 @@ public class ClientEvents {
CouplingPhysics.tick(world);
PonderTooltipHandler.tick();
ScreenOpener.tick();
//ScreenOpener.tick();
ServerSpeedProvider.clientTick();
BeltConnectorHandler.tick();
FilteringRenderer.tick();

View file

@ -28,6 +28,7 @@ public class AllCommands {
.then(FixLightingCommand.register())
.then(HighlightCommand.register())
.then(CouplingCommand.register())
.then(PonderCommand.register())
//utility
.then(util)

View file

@ -4,6 +4,7 @@ import com.simibubi.create.content.contraptions.goggles.GoggleConfigScreen;
import com.simibubi.create.foundation.config.AllConfigs;
import com.simibubi.create.foundation.gui.ScreenOpener;
import com.simibubi.create.foundation.networking.SimplePacketBase;
import com.simibubi.create.foundation.ponder.content.PonderIndexScreen;
import com.simibubi.create.foundation.render.backend.FastRenderDispatcher;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.player.ClientPlayerEntity;
@ -65,6 +66,7 @@ public class ConfigureConfigPacket extends SimplePacketBase {
fixLighting(() -> Actions::experimentalLighting),
overlayReset(() -> Actions::overlayReset),
experimentalRendering(() -> Actions::experimentalRendering),
ponderIndex(() -> Actions::ponderIndex),
;
@ -130,6 +132,11 @@ public class ConfigureConfigPacket extends SimplePacketBase {
Minecraft.getInstance().worldRenderer.loadRenderers();
}
@OnlyIn(Dist.CLIENT)
private static void ponderIndex(String value) {
ScreenOpener.transitionTo(new PonderIndexScreen());
}
private static ITextComponent boolToText(boolean b) {
return b
? new StringTextComponent("enabled").applyTextStyle(TextFormatting.DARK_GREEN)

View file

@ -0,0 +1,25 @@
package com.simibubi.create.foundation.command;
import com.mojang.brigadier.builder.ArgumentBuilder;
import com.simibubi.create.foundation.networking.AllPackets;
import net.minecraft.command.CommandSource;
import net.minecraft.command.Commands;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraftforge.fml.network.PacketDistributor;
public class PonderCommand {
static ArgumentBuilder<CommandSource, ?> register() {
return Commands.literal("ponder")
.requires(cs -> cs.hasPermissionLevel(0))
.executes(ctx -> {
ServerPlayerEntity player = ctx.getSource().asPlayer();
AllPackets.channel.send(
PacketDistributor.PLAYER.with(() -> player),
new ConfigureConfigPacket(ConfigureConfigPacket.Actions.ponderIndex.name(), ""));
return 1;
});
}
}

View file

@ -1,16 +1,23 @@
package com.simibubi.create.foundation.gui;
import java.util.ArrayList;
import java.util.List;
import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget;
import com.simibubi.create.foundation.utility.LerpedFloat;
import net.minecraft.client.MainWindow;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.gui.widget.Widget;
import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.apache.commons.lang3.mutable.MutableInt;
import org.apache.logging.log4j.LogManager;
import org.lwjgl.glfw.GLFW;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@OnlyIn(Dist.CLIENT)
public abstract class AbstractSimiScreen extends Screen {
@ -18,6 +25,7 @@ public abstract class AbstractSimiScreen extends Screen {
protected int sWidth, sHeight;
protected int guiLeft, guiTop;
protected List<Widget> widgets;
public final LerpedFloat transition = LerpedFloat.linear().startWithValue(0).chase(0, .1f, LerpedFloat.Chaser.LINEAR);
protected AbstractSimiScreen() {
super(new StringTextComponent(""));
@ -31,17 +39,86 @@ public abstract class AbstractSimiScreen extends Screen {
guiTop = (this.height - sHeight) / 2;
}
@Override
public void tick() {
super.tick();
transition.tickChaser();
if (transition.getValue() < -0.9995f) {
transition.updateChaseTarget(0);
transition.setValue(0);
ScreenOpener.openLastScreen();
} else if (transition.getValue() > 0.9995f) {
transition.updateChaseTarget(0);
transition.setValue(0);
}
}
@Override
public void render(int mouseX, int mouseY, float partialTicks) {
RenderSystem.pushMatrix();
renderTransition(mouseX, mouseY, partialTicks);
partialTicks = Minecraft.getInstance()
.getRenderPartialTicks();
renderBackground();
renderWindow(mouseX, mouseY, partialTicks);
for (Widget widget : widgets)
widget.render(mouseX, mouseY, partialTicks);
renderBreadcrumbs(mouseX, mouseY, partialTicks);
renderWindowForeground(mouseX, mouseY, partialTicks);
for (Widget widget : widgets)
widget.renderToolTip(mouseX, mouseY);
RenderSystem.popMatrix();
}
private void renderTransition(int mouseX, int mouseY, float partialTicks) {
if (transition.getChaseTarget() != 0) {
if (ScreenOpener.getLastScreen() == null) {
return;
} else if (ScreenOpener.getLastScreen() == this) {
LogManager.getLogger().warn("Tired to render last screen recursively during transition");
return;
}
//draw last screen into buffer
RenderSystem.pushMatrix();//1
UIRenderHelper.framebuffer.framebufferClear(Minecraft.IS_RUNNING_ON_MAC);
UIRenderHelper.prepFramebufferSize();
RenderSystem.pushMatrix();//2
RenderSystem.translated(0, 0, -1000);
UIRenderHelper.framebuffer.bindFramebuffer(true);
ScreenOpener.getLastScreen().render(mouseX, mouseY, partialTicks);
RenderSystem.popMatrix();//2
Minecraft.getInstance().getFramebuffer().bindFramebuffer(true);
//use the buffer texture
float transitionValue = transition.getValue(partialTicks);
if (transition.getChaseTarget() < 0)
transitionValue += 1;
//transitionV is ~1 when the older screen is hidden
//transitionV is ~0 when the older screen is still fully visible
double scale = 1 - 0.25 * transitionValue;
MainWindow window = Minecraft.getInstance().getWindow();
int sw = window.getScaledWidth();
int sh = window.getScaledHeight();
RenderSystem.translated(sw * 0.5, sh * 0.5, -10);
RenderSystem.scaled(scale, scale, 1);
RenderSystem.translated(sw * -0.5, sh * -0.5, 0);
UIRenderHelper.drawFramebuffer(sw, sh, 1f - transitionValue);
RenderSystem.popMatrix();//1
//modify current screen as well
scale = 1 + 0.02 * (1 - transitionValue);
RenderSystem.translated(sw * 0.5, sh * 0.5, 0);
RenderSystem.scaled(scale, scale, 1);
RenderSystem.translated(sw * -0.5, sh * -0.5, 0);
}
}
@Override
@ -60,6 +137,12 @@ public abstract class AbstractSimiScreen extends Screen {
if (widget.keyPressed(code, p_keyPressed_2_, p_keyPressed_3_))
return true;
}
if (code == GLFW.GLFW_KEY_BACKSPACE) {
ScreenOpener.transitionToLast();
return true;
}
return super.keyPressed(code, p_keyPressed_2_, p_keyPressed_3_);
}
@ -98,6 +181,12 @@ public abstract class AbstractSimiScreen extends Screen {
return true;
}
@Override
public void onClose() {
ScreenOpener.clearStack();
super.onClose();
}
@Override
public boolean isPauseScreen() {
return false;
@ -105,6 +194,53 @@ public abstract class AbstractSimiScreen extends Screen {
protected abstract void renderWindow(int mouseX, int mouseY, float partialTicks);
protected void renderBreadcrumbs(int mouseX, int mouseY, float partialTicks) {
List<Screen> history = ScreenOpener.getScreenHistory();
if (history.isEmpty())
return;
history.add(0, Minecraft.getInstance().currentScreen);
int spacing = 20;
List<String> names = history
.stream()
.map(AbstractSimiScreen::screenTitle)
.collect(Collectors.toList());
int bWidth = names
.stream()
.mapToInt(s -> font.getStringWidth(s) + spacing)
.sum();
MutableInt x = new MutableInt(width - bWidth);
MutableInt y = new MutableInt(height - 18);
MutableBoolean first = new MutableBoolean(true);
if (x.getValue() < 25)
x.setValue(25);
names.forEach(s -> {
int sWidth = font.getStringWidth(s);
//UIRenderHelper.breadcrumbArrow(x.getValue(), y.getValue(), sWidth + spacing, 14, spacing/2, 0xbbababab, 0x22ababab);
UIRenderHelper.breadcrumbArrow(x.getValue(), y.getValue(), sWidth + spacing, 14, spacing/2, 0xdd101010, 0x44101010);
drawString(font, s, x.getValue() + 5, y.getValue() + 3, first.getValue() ? 0xffeeffee : 0xffddeeff);
first.setFalse();
x.add(sWidth + spacing);
});
}
private static String screenTitle(Screen screen) {
if (screen instanceof AbstractSimiScreen)
return ((AbstractSimiScreen) screen).getBreadcrumbTitle();
return screen.getClass().getSimpleName();
}
protected String getBreadcrumbTitle() {
return this.getClass().getSimpleName();
}
protected void renderWindowForeground(int mouseX, int mouseY, float partialTicks) {
for (Widget widget : widgets) {
if (!widget.isHovered())

View file

@ -1,15 +1,13 @@
package com.simibubi.create.foundation.gui;
import com.simibubi.create.Create;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public enum AllGuiTextures {
public enum AllGuiTextures implements IScreenRenderable {
// Inventories
PLAYER_INVENTORY("player_inventory.png", 176, 108),
@ -117,16 +115,10 @@ public enum AllGuiTextures {
.bindTexture(location);
}
@Override
@OnlyIn(Dist.CLIENT)
public void draw(AbstractGui screen, int x, int y) {
bind();
screen.blit(x, y, startX, startY, width, height);
}
@OnlyIn(Dist.CLIENT)
public void draw(int x, int y) {
draw(new Screen(null) {
}, x, y);
}
}

View file

@ -5,10 +5,8 @@ import com.mojang.blaze3d.matrix.MatrixStack.Entry;
import com.mojang.blaze3d.vertex.IVertexBuilder;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.utility.ColorHelper;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.renderer.IRenderTypeBuffer;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.util.ResourceLocation;
@ -16,7 +14,7 @@ import net.minecraft.util.math.Vec3d;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class AllIcons {
public class AllIcons implements IScreenRenderable {
public static final ResourceLocation ICON_ATLAS = Create.asResource("textures/gui/icons.png");
private static int x = 0, y = -1;
@ -146,18 +144,13 @@ public class AllIcons {
.bindTexture(ICON_ATLAS);
}
@Override
@OnlyIn(Dist.CLIENT)
public void draw(AbstractGui screen, int x, int y) {
bind();
screen.blit(x, y, iconX, iconY, 16, 16);
}
@OnlyIn(Dist.CLIENT)
public void draw(int x, int y) {
draw(new Screen(null) {
}, x, y);
}
@OnlyIn(Dist.CLIENT)
public void draw(MatrixStack ms, IRenderTypeBuffer buffer, int color) {
IVertexBuilder builder = buffer.getBuffer(RenderType.getTextSeeThrough(ICON_ATLAS));

View file

@ -0,0 +1,18 @@
package com.simibubi.create.foundation.gui;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public interface IScreenRenderable {
@OnlyIn(Dist.CLIENT)
void draw(AbstractGui screen, int x, int y);
@OnlyIn(Dist.CLIENT)
default void draw(int x, int y) {
draw(new Screen(new StringTextComponent("")) {}, x, y);
}
}

View file

@ -2,28 +2,72 @@ package com.simibubi.create.foundation.gui;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screen.Screen;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.DistExecutor;
import javax.annotation.Nullable;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;
public class ScreenOpener {
@OnlyIn(Dist.CLIENT)
private static Screen openedGuiNextTick;
private static final Deque<Screen> backStack = new ArrayDeque<>();
public static void tick() {
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> {
if (openedGuiNextTick != null) {
Minecraft.getInstance().displayGuiScreen(openedGuiNextTick);
openedGuiNextTick = null;
}
});
public static void open(Screen screen) {
open(Minecraft.getInstance().currentScreen, screen);
}
public static void open(Screen gui) {
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> {
openedGuiNextTick = gui;
});
public static void open(@Nullable Screen current, Screen toOpen) {
if (current != null) {
if (backStack.size() >= 15) //don't go deeper than 15 steps
backStack.pollLast();
backStack.push(current);
} else
backStack.clear();
openScreen(toOpen);
}
public static void openLastScreen() {
if (backStack.isEmpty())
return;
openScreen(backStack.pop());
}
//transitions are only supported in simiScreens atm. they take care of all the rendering for it
public static void transitionTo(AbstractSimiScreen screen) {
screen.transition.updateChaseTarget(1);
open(screen);
}
public static void transitionToLast() {
if (backStack.isEmpty())
return;
Screen currentScreen = Minecraft.getInstance().currentScreen;
if (currentScreen instanceof AbstractSimiScreen)
((AbstractSimiScreen) currentScreen).transition.updateChaseTarget(-1);
else
openLastScreen();
}
public static void clearStack() {
backStack.clear();
}
public static List<Screen> getScreenHistory() {
return new ArrayList<>(backStack);
}
@Nullable
public static Screen getLastScreen() {
return backStack.peek();
}
private static void openScreen(Screen screen) {
Minecraft.getInstance().enqueue(() -> Minecraft.getInstance().displayGuiScreen(screen));
}
}

View file

@ -0,0 +1,174 @@
package com.simibubi.create.foundation.gui;
import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.foundation.utility.ColorHelper;
import net.minecraft.client.MainWindow;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.client.shader.Framebuffer;
import net.minecraftforge.fml.client.gui.GuiUtils;
import org.lwjgl.opengl.GL11;
public class UIRenderHelper {
public static Framebuffer framebuffer;
public static void init() {
RenderSystem.recordRenderCall(() -> {
MainWindow mainWindow = Minecraft.getInstance().getWindow();
framebuffer = new Framebuffer(mainWindow.getFramebufferWidth(), mainWindow.getFramebufferHeight(), true, Minecraft.IS_RUNNING_ON_MAC);
framebuffer.deleteFramebuffer();
});
}
public static void prepFramebufferSize() {
MainWindow window = Minecraft.getInstance().getWindow();
if (framebuffer.framebufferWidth != window.getFramebufferWidth() || framebuffer.framebufferHeight != window.getFramebufferHeight()) {
framebuffer.func_216491_a(window.getFramebufferWidth(), window.getFramebufferHeight(), Minecraft.IS_RUNNING_ON_MAC);
}
}
public static void drawFramebuffer(int width, int height, float alpha) {
float vx = (float) width;
float vy = (float) height;
float tx = (float) framebuffer.framebufferWidth / (float) framebuffer.framebufferTextureWidth;
float ty = (float) framebuffer.framebufferHeight / (float) framebuffer.framebufferTextureHeight;
RenderSystem.enableTexture();
RenderSystem.enableBlend();
RenderSystem.disableLighting();
RenderSystem.disableAlphaTest();
RenderSystem.defaultBlendFunc();
RenderSystem.enableDepthTest();
framebuffer.bindFramebufferTexture();
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferbuilder = tessellator.getBuffer();
bufferbuilder.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR_TEXTURE);
bufferbuilder.vertex(0, vy, 0).color(1, 1, 1, alpha).texture(0,0).endVertex();
bufferbuilder.vertex(vx, vy, 0).color(1, 1, 1, alpha).texture(tx,0).endVertex();
bufferbuilder.vertex(vx, 0, 0).color(1, 1, 1, alpha).texture(tx, ty).endVertex();
bufferbuilder.vertex(0, 0, 0).color(1, 1, 1, alpha).texture(0, ty).endVertex();
tessellator.draw();
framebuffer.unbindFramebufferTexture();
RenderSystem.disableBlend();
RenderSystem.enableAlphaTest();
}
//angle in degrees; 0° -> fading to the right
//x and y specify the middle point of the starting edge
//width is the total width of the streak
public static void streak(float angle, int x, int y, int width, int length, int color) {
int a1 = 0xa0 << 24;
int a2 = 0x80 << 24;
int a3 = 0x10 << 24;
int a4 = 0x00 << 24;
color = color & 0x00FFFFFF;
int c1 = a1 | color;
int c2 = a2 | color;
int c3 = a3 | color;
int c4 = a4 | color;
RenderSystem.pushMatrix();
RenderSystem.translated(x, y, 0);
RenderSystem.rotatef(angle - 90, 0, 0, 1);
streak(width/2, length, c1, c2, c3, c4);
RenderSystem.popMatrix();
}
private static void streak(int width, int height, int c1, int c2, int c3, int c4) {
double split1 = .5;
double split2 = .75;
GuiUtils.drawGradientRect(0, -width, 0, width, (int) (split1 * height), c1, c2);
GuiUtils.drawGradientRect(0, -width, (int) (split1 * height), width, (int) (split2 * height), c2, c3);
GuiUtils.drawGradientRect(0, -width, (int) (split2 * height), width, height, c3, c4);
}
//draws a wide chevron-style breadcrumb arrow pointing left
public static void breadcrumbArrow(int x, int y, int width, int height, int indent, int startColor, int endColor) {
RenderSystem.pushMatrix();
RenderSystem.translated(x - indent, y, 0);
breadcrumbArrow(width, height, indent, startColor, endColor);
RenderSystem.popMatrix();
}
private static void breadcrumbArrow(int width, int height, int indent, int c1, int c2) {
/*
* 0,0 x1,y1 ********************* x4,y4 ***** x7,y7
* **** ****
* **** ****
* x0,y0 x2,y2 x5,y5
* **** ****
* **** ****
* x3,y3 ********************* x6,y6 ***** x8,y8
*
* */
double x0 = 0, y0 = height / 2d;
double x1 = indent, y1 = 0;
double x2 = indent, y2 = height / 2d;
double x3 = indent, y3 = height;
double x4 = width, y4 = 0;
double x5 = width, y5 = height / 2d;
double x6 = width, y6 = height;
double x7 = indent + width, y7 = 0;
double x8 = indent + width, y8 = height;
int fc1 = ColorHelper.mixAlphaColors(c1, c2, 0);
int fc2 = ColorHelper.mixAlphaColors(c1, c2, (indent)/(width + 2f * indent));
int fc3 = ColorHelper.mixAlphaColors(c1, c2, (indent + width)/(width + 2f * indent));
int fc4 = ColorHelper.mixAlphaColors(c1, c2, 1);
RenderSystem.disableTexture();
RenderSystem.enableBlend();
RenderSystem.disableAlphaTest();
RenderSystem.defaultBlendFunc();
RenderSystem.shadeModel(GL11.GL_SMOOTH);
Tessellator tessellator = Tessellator.getInstance();
BufferBuilder bufferbuilder = tessellator.getBuffer();
bufferbuilder.begin(GL11.GL_TRIANGLES, DefaultVertexFormats.POSITION_COLOR);
bufferbuilder.vertex(x0, y0, 0).color(fc1 >> 16 & 0xFF, fc1 >> 8 & 0xFF, fc1 & 0xFF, fc1 >> 24 & 0xFF).endVertex();
bufferbuilder.vertex(x1, y1, 0).color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF).endVertex();
bufferbuilder.vertex(x2, y2, 0).color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF).endVertex();
bufferbuilder.vertex(x0, y0, 0).color(fc1 >> 16 & 0xFF, fc1 >> 8 & 0xFF, fc1 & 0xFF, fc1 >> 24 & 0xFF).endVertex();
bufferbuilder.vertex(x2, y2, 0).color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF).endVertex();
bufferbuilder.vertex(x3, y3, 0).color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF).endVertex();
bufferbuilder.vertex(x3, y3, 0).color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF).endVertex();
bufferbuilder.vertex(x1, y1, 0).color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF).endVertex();
bufferbuilder.vertex(x4, y4, 0).color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF).endVertex();
bufferbuilder.vertex(x3, y3, 0).color(fc2 >> 16 & 0xFF, fc2 >> 8 & 0xFF, fc2 & 0xFF, fc2 >> 24 & 0xFF).endVertex();
bufferbuilder.vertex(x4, y4, 0).color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF).endVertex();
bufferbuilder.vertex(x6, y6, 0).color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF).endVertex();
bufferbuilder.vertex(x5, y5, 0).color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF).endVertex();
bufferbuilder.vertex(x4, y4, 0).color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF).endVertex();
bufferbuilder.vertex(x7, y7, 0).color(fc4 >> 16 & 0xFF, fc4 >> 8 & 0xFF, fc4 & 0xFF, fc4 >> 24 & 0xFF).endVertex();
bufferbuilder.vertex(x6, y6, 0).color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF).endVertex();
bufferbuilder.vertex(x5, y5, 0).color(fc3 >> 16 & 0xFF, fc3 >> 8 & 0xFF, fc3 & 0xFF, fc3 >> 24 & 0xFF).endVertex();
bufferbuilder.vertex(x8, y8, 0).color(fc4 >> 16 & 0xFF, fc4 >> 8 & 0xFF, fc4 & 0xFF, fc4 >> 24 & 0xFF).endVertex();
tessellator.draw();
RenderSystem.shadeModel(GL11.GL_FLAT);
RenderSystem.disableBlend();
RenderSystem.enableAlphaTest();
RenderSystem.enableTexture();
}
}

View file

@ -1,22 +1,10 @@
package com.simibubi.create.foundation.ponder;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import com.google.gson.JsonElement;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.ponder.PonderStoryBoardEntry.PonderStoryBoard;
import com.simibubi.create.foundation.ponder.content.PonderIndex;
import com.simibubi.create.foundation.ponder.content.SharedText;
import com.simibubi.create.foundation.ponder.content.*;
import com.tterrag.registrate.util.entry.ItemProviderEntry;
import net.minecraft.client.Minecraft;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.CompressedStreamTools;
@ -26,38 +14,66 @@ import net.minecraft.util.math.BlockPos;
import net.minecraft.world.gen.feature.template.PlacementSettings;
import net.minecraft.world.gen.feature.template.Template;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.function.Consumer;
import java.util.zip.GZIPInputStream;
public class PonderRegistry {
static Map<ResourceLocation, List<PonderStoryBoardEntry>> all = new HashMap<>();
public static final PonderTagRegistry tags = new PonderTagRegistry();
public static final PonderChapterRegistry chapters = new PonderChapterRegistry();
public static Map<ResourceLocation, List<PonderStoryBoardEntry>> all = new HashMap<>();
public static void addStoryBoard(ItemProviderEntry<?> component, String schematic, PonderStoryBoard storyBoard) {
public static PonderSceneBuilder addStoryBoard(ItemProviderEntry<?> component, String schematic, PonderStoryBoard storyBoard) {
ResourceLocation id = component.getId();
all.computeIfAbsent(id, $ -> new ArrayList<>())
.add(new PonderStoryBoardEntry(storyBoard, schematic));
PonderStoryBoardEntry entry = new PonderStoryBoardEntry(storyBoard, schematic, id);
PonderSceneBuilder builder = new PonderSceneBuilder(entry);
all.computeIfAbsent(id, _$ -> new ArrayList<>()).add(entry);
return builder;
}
public static MultiSceneBuilder forComponents(ItemProviderEntry<?> component, ItemProviderEntry<?>... additional) {
return new MultiSceneBuilder(component, additional);
public static PonderSceneBuilder addStoryBoard(PonderChapter chapter, ResourceLocation component, String schematic, PonderStoryBoard storyBoard) {
if (component == null)
component = new ResourceLocation("minecraft", "stick");
PonderStoryBoardEntry entry = new PonderStoryBoardEntry(storyBoard, schematic, component);
PonderSceneBuilder builder = new PonderSceneBuilder(entry);
chapters.addStoriesToChapter(chapter, entry);
return builder;
}
public static MultiSceneBuilder forComponents(ItemProviderEntry<?>... components) {
return new MultiSceneBuilder(Arrays.asList(components));
}
public static List<PonderScene> compile(ResourceLocation id) {
if (PonderIndex.EDITOR_MODE) {
PonderLocalization.shared.clear();
PonderLocalization.specific.clear();
SharedText.gatherText();
return compile(all.get(id));
}
public static List<PonderScene> compile(PonderChapter chapter) {
return compile(chapters.getStories(chapter));
}
public static List<PonderScene> compile(List<PonderStoryBoardEntry> entries) {
if (PonderIndex.EDITOR_MODE) {
//PonderLocalization.shared.clear();
//PonderLocalization.specific.clear();
//SharedText.gatherText();
}
List<PonderStoryBoardEntry> list = all.get(id);
List<PonderScene> scenes = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
PonderStoryBoardEntry sb = list.get(i);
for (int i = 0; i < entries.size(); i++) {
PonderStoryBoardEntry sb = entries.get(i);
Template activeTemplate = loadSchematic(sb.getSchematicName());
PonderWorld world = new PonderWorld(BlockPos.ZERO, Minecraft.getInstance().world);
activeTemplate.addBlocksToWorld(world, BlockPos.ZERO, new PlacementSettings());
world.createBackup();
PonderScene scene = compileScene(id, i, sb, world);
PonderScene scene = compileScene(i, sb, world);
scene.begin();
scenes.add(scene);
}
@ -65,11 +81,10 @@ public class PonderRegistry {
return scenes;
}
public static PonderScene compileScene(ResourceLocation id, int i, PonderStoryBoardEntry sb, PonderWorld world) {
PonderScene scene = new PonderScene(world, id, i);
public static PonderScene compileScene(int i, PonderStoryBoardEntry sb, PonderWorld world) {
PonderScene scene = new PonderScene(world, sb.getComponent(), i, sb.getTags());
SceneBuilder builder = scene.builder();
sb.getBoard()
.program(builder, scene.getSceneBuildingUtil());
sb.getBoard().program(builder, scene.getSceneBuildingUtil());
return scene;
}
@ -95,28 +110,58 @@ public class PonderRegistry {
SharedText.gatherText();
all.forEach((id, list) -> {
for (int i = 0; i < list.size(); i++)
compileScene(id, i, list.get(i), null);
compileScene(i, list.get(i), null);
});
return PonderLocalization.record();
}
public static class MultiSceneBuilder {
private ItemProviderEntry<?> component;
private ItemProviderEntry<?>[] additional;
private final Collection<ItemProviderEntry<?>> components;
MultiSceneBuilder(ItemProviderEntry<?> component, ItemProviderEntry<?>[] additional) {
this.component = component;
this.additional = additional;
MultiSceneBuilder(Collection<ItemProviderEntry<?>> components) {
this.components = components;
}
public MultiSceneBuilder addStoryBoard(String schematicPath, PonderStoryBoard storyBoard) {
PonderRegistry.addStoryBoard(component, schematicPath, storyBoard);
for (ItemProviderEntry<?> itemProviderEntry : additional)
PonderRegistry.addStoryBoard(itemProviderEntry, schematicPath, storyBoard);
return addStoryBoard(schematicPath, storyBoard, PonderSceneBuilder::highlightAllTags);
}
public MultiSceneBuilder addStoryBoard(String schematicPath, PonderStoryBoard storyBoard, Consumer<PonderSceneBuilder> extras) {
components.forEach(c -> extras.accept(PonderRegistry.addStoryBoard(c, schematicPath, storyBoard)));
return this;
}
}
public static class PonderSceneBuilder {
private final PonderStoryBoardEntry entry;
PonderSceneBuilder(PonderStoryBoardEntry entry) {
this.entry = entry;
}
public PonderSceneBuilder highlightAllTags() {
entry.getTags().add(PonderTag.Highlight.ALL);
return this;
}
public PonderSceneBuilder highlightTags(PonderTag... tags) {
entry.getTags().addAll(Arrays.asList(tags));
return this;
}
public PonderSceneBuilder chapter(PonderChapter chapter) {
PonderRegistry.chapters.addStoriesToChapter(chapter, entry);
return this;
}
public PonderSceneBuilder chapters(PonderChapter... chapters) {
for (PonderChapter c : chapters)
chapter(c);
return this;
}
}
}

View file

@ -1,34 +1,15 @@
package com.simibubi.create.foundation.ponder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
import org.apache.commons.lang3.mutable.MutableDouble;
import org.apache.commons.lang3.mutable.MutableObject;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.ponder.content.PonderIndex;
import com.simibubi.create.foundation.ponder.content.PonderTag;
import com.simibubi.create.foundation.ponder.elements.PonderOverlayElement;
import com.simibubi.create.foundation.ponder.elements.PonderSceneElement;
import com.simibubi.create.foundation.ponder.elements.WorldSectionElement;
import com.simibubi.create.foundation.ponder.instructions.HideAllInstruction;
import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.LerpedFloat;
import com.simibubi.create.foundation.utility.MatrixStacker;
import com.simibubi.create.foundation.utility.Pair;
import com.simibubi.create.foundation.utility.VecHelper;
import com.simibubi.create.foundation.utility.*;
import com.simibubi.create.foundation.utility.outliner.Outliner;
import net.minecraft.block.BlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.ActiveRenderInfo;
@ -41,12 +22,14 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.Direction;
import net.minecraft.util.Direction.Axis;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.MutableBoundingBox;
import net.minecraft.util.math.Vec2f;
import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.Vec3i;
import net.minecraft.util.math.*;
import org.apache.commons.lang3.mutable.MutableDouble;
import org.apache.commons.lang3.mutable.MutableObject;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
public class PonderScene {
@ -59,6 +42,7 @@ public class PonderScene {
List<PonderInstruction> schedule, activeSchedule;
Map<UUID, PonderElement> linkedElements;
Set<PonderElement> elements;
List<PonderTag> tags;
PonderWorld world;
ResourceLocation component;
@ -79,7 +63,7 @@ public class PonderScene {
int totalTime;
int currentTime;
public PonderScene(PonderWorld world, ResourceLocation component, int sceneIndex) {
public PonderScene(PonderWorld world, ResourceLocation component, int sceneIndex, Collection<PonderTag> tags) {
pointOfInterest = Vec3d.ZERO;
textIndex = 1;
@ -90,6 +74,7 @@ public class PonderScene {
outliner = new Outliner();
elements = new HashSet<>();
linkedElements = new HashMap<>();
this.tags = new ArrayList<>(tags);
schedule = new ArrayList<>();
activeSchedule = new ArrayList<>();
transform = new SceneTransform();

View file

@ -1,17 +1,27 @@
package com.simibubi.create.foundation.ponder;
import com.simibubi.create.foundation.ponder.content.PonderTag;
import net.minecraft.util.ResourceLocation;
import java.util.ArrayList;
import java.util.List;
public class PonderStoryBoardEntry {
private String schematicName;
private PonderStoryBoard board;
private final String schematicName;
private final PonderStoryBoard board;
private final List<PonderTag> tags;
private final ResourceLocation component;
public PonderStoryBoardEntry(PonderStoryBoard board, String schematicName) {
public PonderStoryBoardEntry(PonderStoryBoard board, String schematicName, ResourceLocation component) {
this.board = board;
this.schematicName = schematicName;
this.tags = new ArrayList<>();
this.component = component;
}
public interface PonderStoryBoard {
public abstract void program(SceneBuilder scene, SceneBuildingUtil util);
void program(SceneBuilder scene, SceneBuildingUtil util);
}
public String getSchematicName() {
@ -22,4 +32,12 @@ public class PonderStoryBoardEntry {
return board;
}
public List<PonderTag> getTags() {
return tags;
}
public ResourceLocation getComponent() {
return component;
}
}

View file

@ -1,14 +1,13 @@
package com.simibubi.create.foundation.ponder;
import java.util.List;
import com.google.common.base.Strings;
import com.simibubi.create.foundation.gui.ScreenOpener;
import com.simibubi.create.foundation.ponder.content.PonderIndexScreen;
import com.simibubi.create.foundation.ponder.content.PonderTagScreen;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.ColorHelper;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.LerpedFloat;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.screen.Screen;
@ -22,6 +21,8 @@ import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.client.event.RenderTooltipEvent;
import java.util.List;
public class PonderTooltipHandler {
static LerpedFloat holdWProgress = LerpedFloat.linear()
@ -51,6 +52,12 @@ public class PonderTooltipHandler {
stack = ponderUI.getHoveredTooltipItem();
if (stack.isItemEqual(ponderUI.getSubject()))
subject = true;
} else if (currentScreen instanceof PonderTagScreen) {
PonderTagScreen tagScreen = (PonderTagScreen) currentScreen;
stack = tagScreen.getHoveredTooltipItem();
} else if (currentScreen instanceof PonderIndexScreen) {
PonderIndexScreen indexScreen = (PonderIndexScreen) currentScreen;
stack = indexScreen.getHoveredTooltipItem();
} else
return;
@ -71,8 +78,7 @@ public class PonderTooltipHandler {
if (!subject && InputMappings.isKeyDown(window, keyCode)) {
if (value >= 1) {
ScreenOpener.open(new PonderUI(PonderRegistry.compile(stack.getItem()
.getRegistryName())));
ScreenOpener.transitionTo(PonderUI.of(stack));
holdWProgress.startWithValue(0);
return;
}

View file

@ -1,27 +1,14 @@
package com.simibubi.create.foundation.ponder;
import java.util.List;
import org.apache.commons.lang3.mutable.MutableBoolean;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.foundation.gui.AbstractSimiScreen;
import com.simibubi.create.foundation.gui.AllGuiTextures;
import com.simibubi.create.foundation.gui.AllIcons;
import com.simibubi.create.foundation.gui.*;
import com.simibubi.create.foundation.ponder.PonderScene.SceneTransform;
import com.simibubi.create.foundation.ponder.content.PonderIndex;
import com.simibubi.create.foundation.ponder.content.*;
import com.simibubi.create.foundation.ponder.ui.PonderButton;
import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.ColorHelper;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.Lang;
import com.simibubi.create.foundation.utility.LerpedFloat;
import com.simibubi.create.foundation.utility.*;
import com.simibubi.create.foundation.utility.LerpedFloat.Chaser;
import com.simibubi.create.foundation.utility.Pair;
import com.simibubi.create.foundation.utility.Pointing;
import net.minecraft.client.ClipboardHelper;
import net.minecraft.client.GameSettings;
import net.minecraft.client.MainWindow;
@ -41,16 +28,28 @@ import net.minecraft.world.gen.feature.template.PlacementSettings;
import net.minecraft.world.gen.feature.template.Template;
import net.minecraftforge.fml.client.gui.GuiUtils;
import net.minecraftforge.registries.ForgeRegistries;
import org.apache.commons.lang3.mutable.MutableBoolean;
import org.lwjgl.opengl.GL11;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.IntStream;
public class PonderUI extends AbstractSimiScreen {
public static final String PONDERING = PonderLocalization.LANG_PREFIX + "pondering";
public static final String IDENTIFY_MODE = PonderLocalization.LANG_PREFIX + "identify_mode";
public static final String IN_CHAPTER = PonderLocalization.LANG_PREFIX + "in_chapter";
private List<PonderScene> scenes;
private List<PonderTag> tags;
private List<PonderButton> tagButtons;
private List<LerpedFloat> tagFades;
private LerpedFloat fadeIn;
private LerpedFloat sceneProgress;
ItemStack stack;
PonderChapter chapter = null;
private boolean identifyMode;
private ItemStack hoveredTooltipItem;
@ -62,10 +61,24 @@ public class PonderUI extends AbstractSimiScreen {
private LerpedFloat lazyIndex;
private int index = 0;
private PonderButton left, right, icon, scan;
private PonderButton left, right, icon, scan, chap;
public static PonderUI of(ItemStack item) {
return new PonderUI(PonderRegistry.compile(item.getItem().getRegistryName()));
}
public static PonderUI of(PonderChapter chapter) {
PonderUI ui = new PonderUI(PonderRegistry.compile(chapter));
ui.chapter = chapter;
return ui;
}
public PonderUI(List<PonderScene> scenes) {
this.scenes = scenes;
if (scenes.isEmpty()) {
List<PonderStoryBoardEntry> l = Collections.singletonList(new PonderStoryBoardEntry(DebugScenes::empty, "debug/scene_1", new ResourceLocation("minecraft", "stick")));
scenes.addAll(PonderRegistry.compile(l));
}
lazyIndex = LerpedFloat.linear()
.startWithValue(index);
sceneProgress = LerpedFloat.linear()
@ -87,14 +100,43 @@ public class PonderUI extends AbstractSimiScreen {
else
stack = new ItemStack(ForgeRegistries.BLOCKS.getValue(component));
int bY = height - 20 - 31;
tags = new ArrayList<>(PonderRegistry.tags.getTags(component));
tagButtons = new ArrayList<>();
tagFades = new ArrayList<>();
tags.forEach(t -> {
int i = tagButtons.size();
int x = 31;
int y = 91 + i * 40;
PonderButton b = new PonderButton(x, y, () -> {
ScreenOpener.transitionTo(new PonderTagScreen(t));
})
.showing(t)
.fade(0, -1);
widgets.add(b);
tagButtons.add(b);
LerpedFloat chase = LerpedFloat.linear()
.startWithValue(0)
.chase(0, .05f, Chaser.exp(.1));
tagFades.add(chase);
});
widgets.add(icon = new PonderButton(31, 31, () -> {
}).showing(stack)
.fade(0, -1));
}).showing(stack).fade(0, -1));
if (chapter != null) {
widgets.add(chap = new PonderButton(width - 31 - 24, 31, () -> {
}).showing(chapter).fade(0, -1));
}
GameSettings bindings = minecraft.gameSettings;
int spacing = 8;
int bX = (width - 20) / 2 - (70 + 2 * spacing);
int bY = height - 20 - 31;
widgets.add(scan = new PonderButton(bX, bY, () -> {
identifyMode = !identifyMode;
@ -129,6 +171,7 @@ public class PonderUI extends AbstractSimiScreen {
@Override
public void tick() {
super.tick();
PonderScene activeScene = scenes.get(index);
if (!identifyMode)
activeScene.tick();
@ -182,7 +225,7 @@ public class PonderUI extends AbstractSimiScreen {
PonderWorld world = new PonderWorld(BlockPos.ZERO, Minecraft.getInstance().world);
activeTemplate.addBlocksToWorld(world, BlockPos.ZERO, new PlacementSettings());
world.createBackup();
scene = PonderRegistry.compileScene(scene.component, index, sb, world);
scene = PonderRegistry.compileScene(index, sb, world);
scene.begin();
scenes.set(index, scene);
}
@ -309,13 +352,30 @@ public class PonderUI extends AbstractSimiScreen {
RenderSystem.translated(0, 0, 800);
int x = icon.x + icon.getWidth() + 8;
int y = icon.y;
UIRenderHelper.streak(0, x - 4, y + 10, 26, (int) (150 * fade), 0x101010);
drawString(font, Lang.translate(PONDERING), x, y, 0xffa3a3a3);
y += 12;
x += 0;
RenderSystem.translated(0, 3 * (indexDiff), 0);
font.drawSplitString(activeScene.getTitle(), x, y, left.x - x,
ColorHelper.applyAlpha(textColor, 1 - indexDiff));
//RenderSystem.translated(0, 3 * (indexDiff), 0);
RenderSystem.translated(x, y, 0);
RenderSystem.rotatef(indexDiff * -75, 1, 0, 0);
RenderSystem.translated(0, 0, 5);
font.drawSplitString(activeScene.getTitle(), 0, 0, left.x, ColorHelper.applyAlpha(textColor, 1 - indexDiff));
RenderSystem.popMatrix();
if (chapter != null) {
RenderSystem.pushMatrix();
RenderSystem.translated(chap.x - 4 - 4, chap.y, 0);
UIRenderHelper.streak(180, 4, 10, 26, (int) (150 * fade), 0x101010);
drawRightAlignedString(font, Lang.translate(IN_CHAPTER), 0, 0, 0xffa3a3a3);
drawRightAlignedString(font, Lang.translate(PonderLocalization.LANG_PREFIX + "chapter." + chapter.getId()), 0, 12, 0xffeeeeee);
RenderSystem.popMatrix();
}
}
if (identifyMode) {
@ -387,6 +447,44 @@ public class PonderUI extends AbstractSimiScreen {
GuiUtils.drawGradientRect(200, 0, 3, 1, 4, 0x60ffeedd, 0x60ffeedd);
RenderSystem.popMatrix();
}
//Tags
List<PonderTag> sceneTags = activeScene.tags;
boolean highlightAll = sceneTags.contains(PonderTag.Highlight.ALL);
double s = Minecraft.getInstance().getWindow().getGuiScaleFactor();
IntStream.range(0, tagButtons.size()).forEach(i -> {
RenderSystem.pushMatrix();
LerpedFloat chase = tagFades.get(i);
PonderButton button = tagButtons.get(i);
if (button.isMouseOver(mouseX, mouseY)) {
chase.updateChaseTarget(1);
} else
chase.updateChaseTarget(0);
chase.tickChaser();
if (highlightAll || sceneTags.contains(this.tags.get(i)))
button.flash();
else
button.dim();
int x = button.x + button.getWidth() + 4;
int y = button.y - 2;
RenderSystem.translated(x, y + 5 * (1 - fade), 0);
float fadedWidth = 200 * chase.getValue(partialTicks);
UIRenderHelper.streak(0, 0, 12, 26, (int) fadedWidth, 0x101010);
GL11.glScissor((int) (x * s), 0, (int) (fadedWidth * s), (int) (height * s));
GL11.glEnable(GL11.GL_SCISSOR_TEST);
String tagName = Lang.translate("ponder.tag." + this.tags.get(i).getId());
drawString(tagName, 3, 8, 0xffeedd);
GL11.glDisable(GL11.GL_SCISSOR_TEST);
RenderSystem.popMatrix();
});
}
protected void lowerButtonGroup(int index, int mouseX, int mouseY, float fade, AllIcons icon, KeyBinding key) {
@ -484,6 +582,14 @@ public class PonderUI extends AbstractSimiScreen {
return super.keyPressed(code, p_keyPressed_2_, p_keyPressed_3_);
}
@Override
protected String getBreadcrumbTitle() {
if (chapter != null)
return Lang.translate(PonderLocalization.LANG_PREFIX + "chapter." + chapter.getId());
return stack.getItem().getName().getFormattedText();
}
public FontRenderer getFontRenderer() {
return font;
}

View file

@ -4,19 +4,14 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems;
import com.simibubi.create.content.contraptions.base.IRotate.SpeedLevel;
import com.simibubi.create.content.contraptions.particle.RotationIndicatorParticleData;
import com.simibubi.create.foundation.ponder.ElementLink;
import com.simibubi.create.foundation.ponder.PonderRegistry;
import com.simibubi.create.foundation.ponder.*;
import com.simibubi.create.foundation.ponder.PonderStoryBoardEntry.PonderStoryBoard;
import com.simibubi.create.foundation.ponder.SceneBuilder;
import com.simibubi.create.foundation.ponder.SceneBuildingUtil;
import com.simibubi.create.foundation.ponder.Selection;
import com.simibubi.create.foundation.ponder.elements.BeltItemElement;
import com.simibubi.create.foundation.ponder.elements.InputWindowElement;
import com.simibubi.create.foundation.ponder.elements.WorldSectionElement;
import com.simibubi.create.foundation.ponder.instructions.EmitParticlesInstruction.Emitter;
import com.simibubi.create.foundation.utility.Pointing;
import com.tterrag.registrate.util.entry.ItemEntry;
import net.minecraft.block.Blocks;
import net.minecraft.entity.Entity;
import net.minecraft.entity.item.ItemEntity;
@ -48,10 +43,18 @@ public class DebugScenes {
private static void add(PonderStoryBoard sb) {
ItemEntry<Item> item = AllItems.BRASS_HAND;
String schematicPath = "debug/scene_" + index;
PonderRegistry.addStoryBoard(item, schematicPath, sb);
PonderRegistry.addStoryBoard(item, schematicPath, sb)
.highlightAllTags()
.chapter(PonderChapter.of("debug"));
index++;
}
public static void empty(SceneBuilder scene, SceneBuildingUtil util) {
scene.title("Missing Content");
scene.showBasePlate();
scene.idle(5);
}
public static void coordinateScene(SceneBuilder scene, SceneBuildingUtil util) {
scene.title("Coordinate Space");
scene.showBasePlate();

View file

@ -0,0 +1,52 @@
package com.simibubi.create.foundation.ponder.content;
import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.Create;
import com.simibubi.create.foundation.gui.IScreenRenderable;
import com.simibubi.create.foundation.ponder.PonderRegistry;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.util.ResourceLocation;
import javax.annotation.Nonnull;
public class PonderChapter implements IScreenRenderable {
private final String id;
private final ResourceLocation icon;
private PonderChapter(String id) {
this.id = id;
icon = new ResourceLocation(Create.ID, "textures/ponder/chapter/" + id + ".png");
}
@Override
public void draw(AbstractGui screen, int x, int y) {
RenderSystem.pushMatrix();
Minecraft.getInstance().getTextureManager().bindTexture(icon);
RenderSystem.scaled(0.25, 0.25, 1);
//x and y offset, blit z offset, tex x and y, tex width and height, entire tex sheet width and height
AbstractGui.blit(x, y, 0, 0, 0, 64, 64, 64, 64);
RenderSystem.popMatrix();
}
@Nonnull
public static PonderChapter of(String id) {
PonderChapter chapter = PonderRegistry.chapters.getChapter(id);
if (chapter == null) {
chapter = PonderRegistry.chapters.addChapter(new PonderChapter(id));
}
return chapter;
}
public PonderChapter addTagsToChapter(PonderTag... tags) {
for (PonderTag t : tags)
PonderRegistry.tags.add(t, this);
return this;
}
public String getId() {
return id;
}
}

View file

@ -0,0 +1,49 @@
package com.simibubi.create.foundation.ponder.content;
import com.simibubi.create.foundation.ponder.PonderStoryBoardEntry;
import com.simibubi.create.foundation.utility.Pair;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;
import java.util.stream.Collectors;
public class PonderChapterRegistry {
private final Map<String, Pair<PonderChapter, List<PonderStoryBoardEntry>>> chapters;
public PonderChapterRegistry() {
chapters = new HashMap<>();
}
public void addStoriesToChapter(@Nonnull PonderChapter chapter, PonderStoryBoardEntry... entries) {
chapters.get(chapter.getId()).getSecond().addAll(Arrays.asList(entries));
}
PonderChapter addChapter(@Nonnull PonderChapter chapter) {
chapters.put(chapter.getId(), Pair.of(chapter, new ArrayList<>()));
return chapter;
}
@Nullable
PonderChapter getChapter(String id) {
Pair<PonderChapter, List<PonderStoryBoardEntry>> pair = chapters.get(id);
if (pair == null)
return null;
return pair.getFirst();
}
public List<PonderChapter> getAllChapters() {
return chapters
.values()
.stream()
.map(Pair::getFirst)
.collect(Collectors.toList());
}
public List<PonderStoryBoardEntry> getStories(PonderChapter chapter) {
return chapters.get(chapter.getId()).getSecond();
}
}

View file

@ -1,7 +1,10 @@
package com.simibubi.create.foundation.ponder.content;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.AllItems;
import com.simibubi.create.foundation.ponder.PonderRegistry;
import net.minecraft.block.Blocks;
import net.minecraft.item.Items;
public class PonderIndex {
@ -13,8 +16,8 @@ public class PonderIndex {
// (!) Modifications inside storyboard methods only require re-opening the ui
PonderRegistry.forComponents(AllBlocks.SHAFT)
.addStoryBoard("shaft/relay", KineticsScenes::shaftAsRelay)
.addStoryBoard("shaft/encasing", KineticsScenes::shaftsCanBeEncased);
.addStoryBoard("shaft/relay", KineticsScenes::shaftAsRelay, b -> b.highlightAllTags().chapter(PonderChapter.of("basic_kinetics")))
.addStoryBoard("shaft/encasing", KineticsScenes::shaftsCanBeEncased, b -> b.chapter(PonderChapter.of("encasing")));
// Funnels
PonderRegistry.addStoryBoard(AllBlocks.BRASS_FUNNEL, "funnels/brass", FunnelScenes::brass);
@ -39,4 +42,30 @@ public class PonderIndex {
DebugScenes.registerAll();
}
public static void registerTags() {
PonderRegistry.tags.forItems(AllBlocks.SHAFT.getId())
.add(PonderTag.Create.KINETICS);
PonderRegistry.tags.forItems(AllBlocks.ANDESITE_FUNNEL.getId(), AllBlocks.BRASS_FUNNEL.getId())
.add(PonderTag.Create.ARM_ACCESS)
.add(PonderTag.Vanilla.ITEM_TRANSFER)
.add(PonderTag.Vanilla.REDSTONE_CONTROL);
PonderRegistry.tags.forTag(PonderTag.Vanilla.REDSTONE_CONTROL)
.add(Items.REDSTONE.getRegistryName())
.add(Blocks.LEVER.getRegistryName());
PonderRegistry.tags.forTag(PonderTag.Create.KINETICS)
.add(AllBlocks.COGWHEEL.getId())
.add(AllBlocks.LARGE_COGWHEEL.getId())
.add(AllItems.BELT_CONNECTOR.getId())
.add(AllBlocks.ENCASED_CHAIN_DRIVE.getId());
PonderChapter.of("basic_kinetics").addTagsToChapter(
PonderTag.Create.KINETICS
);
}
}

View file

@ -0,0 +1,170 @@
package com.simibubi.create.foundation.ponder.content;
import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.foundation.gui.AbstractSimiScreen;
import com.simibubi.create.foundation.gui.ScreenOpener;
import com.simibubi.create.foundation.gui.UIRenderHelper;
import com.simibubi.create.foundation.ponder.PonderRegistry;
import com.simibubi.create.foundation.ponder.PonderUI;
import com.simibubi.create.foundation.ponder.ui.ChapterLabel;
import com.simibubi.create.foundation.ponder.ui.LayoutHelper;
import com.simibubi.create.foundation.ponder.ui.PonderButton;
import net.minecraft.block.Block;
import net.minecraft.client.MainWindow;
import net.minecraft.client.gui.widget.Widget;
import net.minecraft.client.renderer.Rectangle2d;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.registries.ForgeRegistries;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class PonderIndexScreen extends AbstractSimiScreen {
protected final List<PonderChapter> chapters;
private final double chapterXmult = 0.5;
private final double chapterYmult = 0.3;
protected Rectangle2d chapterArea;
protected final List<Item> items;
private final double itemXmult = 0.5;
private final double itemYmult = 0.75;
protected Rectangle2d itemArea;
private ItemStack hoveredItem = ItemStack.EMPTY;
public PonderIndexScreen() {
chapters = new ArrayList<>();
items = new ArrayList<>();
}
@Override
protected void init() {
super.init();
widgets.clear();
chapters.clear();
chapters.addAll(PonderRegistry.chapters.getAllChapters());
LayoutHelper layout = LayoutHelper.centeredHorizontal(
chapters.size(),
MathHelper.clamp((int) Math.ceil(chapters.size() / 4f), 1, 4),
200,
38,
16
);
chapterArea = layout.getArea();
int chapterCenterX = (int) (width * chapterXmult);
int chapterCenterY = (int) (height * chapterYmult);
//todo at some point pagination or horizontal scrolling may be needed for chapters/items
for (PonderChapter chapter : chapters) {
ChapterLabel label = new ChapterLabel(chapter, chapterCenterX + layout.getX(), chapterCenterY + layout.getY(), () -> {
ScreenOpener.transitionTo(PonderUI.of(chapter));
});
widgets.add(label);
layout.next();
}
items.clear();
PonderRegistry.all.keySet()
.stream()
.map(key -> {
Item item = ForgeRegistries.ITEMS.getValue(key);
if (item == null) {
Block b = ForgeRegistries.BLOCKS.getValue(key);
if (b != null)
item = b.asItem();
}
return item;
})
.filter(Objects::nonNull)
.forEach(items::add);
layout = LayoutHelper.centeredHorizontal(
items.size(),
MathHelper.clamp((int) Math.ceil(items.size() / 11f), 1, 4),
28,
28,
8
);
itemArea = layout.getArea();
int itemCenterX = (int) (width * itemXmult);
int itemCenterY = (int) (height * itemYmult);
for (Item item : items) {
PonderButton button = new PonderButton(itemCenterX + layout.getX() + 4, itemCenterY + layout.getY() + 4, () -> {})
.showing(new ItemStack(item));
button.fade(1);
widgets.add(button);
layout.next();
}
}
@Override
public void tick() {
super.tick();
hoveredItem = ItemStack.EMPTY;
MainWindow w = minecraft.getWindow();
double mouseX = minecraft.mouseHelper.getMouseX() * w.getScaledWidth() / w.getWidth();
double mouseY = minecraft.mouseHelper.getMouseY() * w.getScaledHeight() / w.getHeight();
for (Widget widget : widgets) {
if (widget instanceof PonderButton)
if (widget.isMouseOver(mouseX, mouseY)) {
hoveredItem = ((PonderButton) widget).getItem();
}
}
}
@Override
protected void renderWindow(int mouseX, int mouseY, float partialTicks) {
int x = (int) (width * chapterXmult);
int y = (int) (height * chapterYmult);
RenderSystem.pushMatrix();
RenderSystem.translated(x, y, 0);
UIRenderHelper.streak(0, chapterArea.getX() - 10, chapterArea.getY() - 20, 20, 220, 0x101010);
drawString(font, "Topics to Ponder about", chapterArea.getX() - 5, chapterArea.getY() - 25, 0xffddeeff);
RenderSystem.popMatrix();
x = (int) (width * itemXmult);
y = (int) (height * itemYmult);
RenderSystem.pushMatrix();
RenderSystem.translated(x, y, 0);
UIRenderHelper.streak(0, itemArea.getX() - 10, itemArea.getY() - 20, 20, 220, 0x101010);
drawString(font, "Items to inspect", itemArea.getX() - 5, itemArea.getY() - 25, 0xffddeeff);
RenderSystem.popMatrix();
}
@Override
protected void renderWindowForeground(int mouseX, int mouseY, float partialTicks) {
if (hoveredItem.isEmpty())
return;
RenderSystem.pushMatrix();
RenderSystem.translated(0, 0, 200);
renderTooltip(hoveredItem, mouseX, mouseY);
RenderSystem.popMatrix();
}
public ItemStack getHoveredTooltipItem() {
return hoveredItem;
}
}

View file

@ -0,0 +1,88 @@
package com.simibubi.create.foundation.ponder.content;
import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.AllBlocks;
import com.simibubi.create.foundation.gui.GuiGameElement;
import com.simibubi.create.foundation.gui.IScreenRenderable;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.AbstractGui;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class PonderTag implements IScreenRenderable {
private final String id;
private ResourceLocation icon;
private ItemStack itemIcon = ItemStack.EMPTY;
private ItemStack mainItem = ItemStack.EMPTY;
public PonderTag(String id) {
this.id = id;
}
public String getId() {
return id;
}
public ItemStack getMainItem() {
return mainItem;
}
public PonderTag idAsIcon() {
return icon(id);
}
public PonderTag icon(String location) {
this.icon = new ResourceLocation(com.simibubi.create.Create.ID, "textures/ponder/tag/" + location + ".png");
return this;
}
public PonderTag item(Item item) {
return this.item(item, true, true);
}
public PonderTag item(Item item, boolean useAsIcon, boolean useAsMainItem) {
if (useAsIcon) this.itemIcon = new ItemStack(item);
if (useAsMainItem) this.mainItem = new ItemStack(item);
return this;
}
@Override
@OnlyIn(Dist.CLIENT)
public void draw(AbstractGui screen, int x, int y) {
RenderSystem.pushMatrix();
RenderSystem.translated(x, y, 0);
if (icon != null) {
Minecraft.getInstance().getTextureManager().bindTexture(icon);
RenderSystem.scaled(0.25, 0.25, 1);
//x and y offset, blit z offset, tex x and y, tex width and height, entire tex sheet width and height
AbstractGui.blit(0, 0, 0, 0, 0, 64, 64, 64, 64);
} else if (!itemIcon.isEmpty()) {
RenderSystem.translated(-4, -4, 0);
RenderSystem.scaled(1.5, 1.5, 1);
GuiGameElement.of(itemIcon).render();
}
RenderSystem.popMatrix();
}
public static class Create {
public static final PonderTag KINETICS = new PonderTag("kinetics").item(AllBlocks.COGWHEEL.get().asItem(), true, false);
public static final PonderTag FLUID_TRANSFER = new PonderTag("fluid_transfer").idAsIcon();
public static final PonderTag OPEN_INVENTORY = new PonderTag("open_inventory").item(AllBlocks.BASIN.get().asItem());
public static final PonderTag ARM_ACCESS = new PonderTag("arm_access").item(AllBlocks.MECHANICAL_ARM.get().asItem());
}
public static class Vanilla {
public static final PonderTag REDSTONE_CONTROL = new PonderTag("redstone_control").item(Items.REDSTONE, true, false);
public static final PonderTag ITEM_TRANSFER = new PonderTag("item_transfer").idAsIcon();
}
public static class Highlight {
public static final PonderTag ALL = new PonderTag("_all");
}
}

View file

@ -0,0 +1,94 @@
package com.simibubi.create.foundation.ponder.content;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import com.simibubi.create.foundation.ponder.PonderRegistry;
import net.minecraft.util.ResourceLocation;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
public class PonderTagRegistry {
private final Multimap<ResourceLocation, PonderTag> tags;
private final Multimap<PonderChapter, PonderTag> chapterTags;
public PonderTagRegistry() {
tags = LinkedHashMultimap.create();
chapterTags = LinkedHashMultimap.create();
}
public Set<PonderTag> getTags(ResourceLocation item) {
return ImmutableSet.copyOf(tags.get(item));
}
public Set<PonderTag> getTags(PonderChapter chapter) {
return ImmutableSet.copyOf(chapterTags.get(chapter));
}
public Set<ResourceLocation> getItems(PonderTag tag) {
return tags
.entries()
.stream()
.filter(e -> e.getValue() == tag)
.map(Map.Entry::getKey)
.collect(ImmutableSet.toImmutableSet());
}
public Set<PonderChapter> getChapters(PonderTag tag) {
return chapterTags
.entries()
.stream()
.filter(e -> e.getValue() == tag)
.map(Map.Entry::getKey)
.collect(ImmutableSet.toImmutableSet());
}
public void add(PonderTag tag, ResourceLocation item) {
tags.put(item, tag);
}
public void add(PonderTag tag, PonderChapter chapter) {
chapterTags.put(chapter, tag);
}
public ItemBuilder forItems(ResourceLocation... items) {
return new ItemBuilder(items);
}
public TagBuilder forTag(PonderTag tag) {
return new TagBuilder(tag);
}
public static class ItemBuilder {
private final Collection<ResourceLocation> items;
private ItemBuilder(ResourceLocation... items) {
this.items = Arrays.asList(items);
}
public ItemBuilder add(PonderTag tag) {
items.forEach(i -> PonderRegistry.tags.add(tag, i));
return this;
}
}
public static class TagBuilder {
private final PonderTag tag;
private TagBuilder(PonderTag tag) {
this.tag = tag;
}
public TagBuilder add(ResourceLocation item) {
PonderRegistry.tags.add(tag, item);
return this;
}
}
}

View file

@ -0,0 +1,231 @@
package com.simibubi.create.foundation.ponder.content;
import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.foundation.gui.AbstractSimiScreen;
import com.simibubi.create.foundation.gui.GuiGameElement;
import com.simibubi.create.foundation.gui.ScreenOpener;
import com.simibubi.create.foundation.gui.UIRenderHelper;
import com.simibubi.create.foundation.ponder.PonderRegistry;
import com.simibubi.create.foundation.ponder.PonderUI;
import com.simibubi.create.foundation.ponder.ui.ChapterLabel;
import com.simibubi.create.foundation.ponder.ui.LayoutHelper;
import com.simibubi.create.foundation.ponder.ui.PonderButton;
import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.block.Block;
import net.minecraft.client.MainWindow;
import net.minecraft.client.gui.widget.Widget;
import net.minecraft.client.renderer.Rectangle2d;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.MathHelper;
import net.minecraftforge.registries.ForgeRegistries;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class PonderTagScreen extends AbstractSimiScreen {
protected final PonderTag tag;
protected final List<Item> items;
private final double itemXmult = 0.5;
private final double itemYmult = 0.4;
protected Rectangle2d itemArea;
protected final List<PonderChapter> chapters;
private final double chapterXmult = 0.5;
private final double chapterYmult = 0.75;
protected Rectangle2d chapterArea;
private final double mainXmult = 0.5;
private final double mainYmult = 0.15;
private ItemStack hoveredItem = ItemStack.EMPTY;
public PonderTagScreen(PonderTag tag) {
this.tag = tag;
items = new ArrayList<>();
chapters = new ArrayList<>();
}
@Override
protected void init() {
super.init();
widgets.clear();
//items
items.clear();
PonderRegistry.tags.getItems(tag)
.stream()
.map(key -> {
Item item = ForgeRegistries.ITEMS.getValue(key);
if (item == null) {
Block b = ForgeRegistries.BLOCKS.getValue(key);
if (b != null)
item = b.asItem();
}
return item;
})
.filter(Objects::nonNull)
.forEach(items::add);
int rowCount = MathHelper.clamp((int) Math.ceil(items.size() / 11d), 1, 3);
LayoutHelper layout = LayoutHelper.centeredHorizontal(items.size(), rowCount, 28, 28, 8);
itemArea = layout.getArea();
int itemCenterX = (int) (width * itemXmult);
int itemCenterY = (int) (height * itemYmult);
for (Item i : items) {
PonderButton button = new PonderButton(itemCenterX + layout.getX() + 4, itemCenterY + layout.getY() + 4, () -> {})
.showing(new ItemStack(i));
button.fade(1);
widgets.add(button);
layout.next();
}
//chapters
chapters.clear();
chapters.addAll(PonderRegistry.tags.getChapters(tag));
rowCount = MathHelper.clamp((int) Math.ceil(chapters.size() / 3f), 1, 3);
layout = LayoutHelper.centeredHorizontal(chapters.size(), rowCount, 200, 38, 16);
chapterArea = layout.getArea();
int chapterCenterX = (int) (width * chapterXmult);
int chapterCenterY = (int) (height * chapterYmult);
for (PonderChapter chapter : chapters) {
ChapterLabel label = new ChapterLabel(chapter, chapterCenterX + layout.getX(), chapterCenterY + layout.getY(), () -> {
ScreenOpener.transitionTo(PonderUI.of(chapter));
});
widgets.add(label);
layout.next();
}
}
@Override
public void tick() {
super.tick();
hoveredItem = ItemStack.EMPTY;
MainWindow w = minecraft.getWindow();
double mouseX = minecraft.mouseHelper.getMouseX() * w.getScaledWidth() / w.getWidth();
double mouseY = minecraft.mouseHelper.getMouseY() * w.getScaledHeight() / w.getHeight();
for (Widget widget : widgets) {
if (widget instanceof PonderButton)
if (widget.isMouseOver(mouseX, mouseY)) {
hoveredItem = ((PonderButton) widget).getItem();
}
}
}
@Override
protected void renderWindow(int mouseX, int mouseY, float partialTicks) {
renderItems(mouseX, mouseY, partialTicks);
renderChapters(mouseX, mouseY, partialTicks);
//
int x = (int) (width * mainXmult);
int y = (int) (height * mainYmult);
RenderSystem.pushMatrix();
RenderSystem.translated(x, y, 0);
RenderSystem.translated(-150, 0, 0);
if (!tag.getMainItem().isEmpty()) {
RenderSystem.translated(-25, 0, 0);
PonderUI.renderBox(0, -10, 20, 20, false);
RenderSystem.pushMatrix();
RenderSystem.translated(-2, -12, 0);
RenderSystem.scaled(1.5, 1.5, 1);
GuiGameElement.of(tag.getMainItem()).render();
RenderSystem.popMatrix();
RenderSystem.translated(75, 0, 0);
}
RenderSystem.pushMatrix();
RenderSystem.scaled(1.5, 1.5, 1);
//render icon & box
PonderUI.renderBox(0, -10, 20, 20, true);
RenderSystem.translated(2, 2 - 10, 100);
tag.draw(this, 0, 0);
RenderSystem.popMatrix();
//tag name & description
UIRenderHelper.streak(0, 36, 0, 39, 350, 0x101010);
drawString(font, Lang.translate("ponder.tag." + tag.getId()), 41, -16, 0xffff_ffff);
drawString(font, Lang.translate("ponder.tag." + tag.getId() + ".desc"), 41, -4, 0xffff_ffff);
RenderSystem.popMatrix();
}
protected void renderItems(int mouseX, int mouseY, float partialTicks) {
if (items.isEmpty())
return;
int x = (int) (width * itemXmult);
int y = (int) (height * itemYmult);
RenderSystem.pushMatrix();
RenderSystem.translated(x, y, 0);
UIRenderHelper.streak(0, itemArea.getX() - 10, itemArea.getY() - 20, 20, 180, 0x101010);
drawString(font, "Related Items", itemArea.getX() - 5, itemArea.getY() - 25, 0xffddeeff);
UIRenderHelper.streak(0, 0, 0, itemArea.getHeight() + 10, itemArea.getWidth()/2 + 75, 0x101010);
UIRenderHelper.streak(180, 0, 0, itemArea.getHeight() + 10, itemArea.getWidth()/2 + 75, 0x101010);
RenderSystem.popMatrix();
}
protected void renderChapters(int mouseX, int mouseY, float partialTicks) {
if (chapters.isEmpty())
return;
int chapterX = (int) (width * chapterXmult);
int chapterY = (int) (height * chapterYmult);
RenderSystem.pushMatrix();
RenderSystem.translated(chapterX, chapterY, 0);
UIRenderHelper.streak(0, chapterArea.getX() - 10, chapterArea.getY() - 20, 20, 220, 0x101010);
drawString(font, "More Topics to Ponder about", chapterArea.getX() - 5, chapterArea.getY() - 25, 0xffddeeff);
RenderSystem.popMatrix();
}
@Override
protected void renderWindowForeground(int mouseX, int mouseY, float partialTicks) {
RenderSystem.pushMatrix();
RenderSystem.disableRescaleNormal();
RenderSystem.disableDepthTest();
RenderSystem.translated(0, 0, 200);
if (!hoveredItem.isEmpty()) {
renderTooltip(hoveredItem, mouseX, mouseY);
}
RenderSystem.enableDepthTest();
RenderSystem.enableRescaleNormal();
RenderSystem.popMatrix();
}
@Override
protected String getBreadcrumbTitle() {
return Lang.translate("ponder.tag." + tag.getId());
}
public ItemStack getHoveredTooltipItem() {
return hoveredItem;
}
}

View file

@ -0,0 +1,39 @@
package com.simibubi.create.foundation.ponder.ui;
import com.simibubi.create.foundation.gui.UIRenderHelper;
import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget;
import com.simibubi.create.foundation.ponder.content.PonderChapter;
import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.client.Minecraft;
public class ChapterLabel extends AbstractSimiWidget {
private final PonderChapter chapter;
private final PonderButton button;
public ChapterLabel(PonderChapter chapter, int x, int y, Runnable onClick) {
super(x, y, 175, 38);
this.button = new PonderButton(x + 4, y + 4, onClick, 30, 30).showing(chapter);
this.button.fade(1);
this.chapter = chapter;
}
@Override
public void render(int mouseX, int mouseY, float partialTicks) {
UIRenderHelper.streak(0, x, y + height/2, height - 2, width, 0x101010);
drawString(Minecraft.getInstance().fontRenderer, Lang.translate("ponder.chapter." + chapter.getId()), x + 50, y + 20, 0xffddeeff);
button.renderButton(mouseX, mouseY, partialTicks);
super.render(mouseX, mouseY, partialTicks);
}
@Override
public void onClick(double x, double y) {
if (!button.isMouseOver(x, y))
return;
button.runCallback();
}
}

View file

@ -0,0 +1,126 @@
package com.simibubi.create.foundation.ponder.ui;
import net.minecraft.client.renderer.Rectangle2d;
public interface LayoutHelper {
static LayoutHelper centeredHorizontal(int itemCount, int rows, int width, int height, int spacing) {
return new CenteredHorizontalLayoutHelper(itemCount, rows, width, height, spacing);
}
int getX();
int getY();
void next();
int getTotalWidth();
int getTotalHeight();
default Rectangle2d getArea() {
int lWidth = getTotalWidth();
int lHeight = getTotalHeight();
return new Rectangle2d(
-lWidth/2,
-lHeight/2,
lWidth,
lHeight
);
}
class CenteredHorizontalLayoutHelper implements LayoutHelper {
int itemCount;
int rows;
int width;
int height;
int spacing;
int currentColumn = 0;
int currentRow = 0;
int[] rowCounts;
int x = 0, y = 0;
CenteredHorizontalLayoutHelper(int itemCount, int rows, int width, int height, int spacing) {
this.itemCount = itemCount;
this.rows = rows;
this.width = width;
this.height = height;
this.spacing = spacing;
rowCounts = new int[rows];
int itemsPerRow = itemCount / rows;
int itemDiff = itemCount - itemsPerRow * rows;
for (int i = 0; i < rows; i++) {
rowCounts[i] = itemsPerRow;
if (itemDiff > 0) {
rowCounts[i]++;
itemDiff--;
}
}
init();
}
@Override
public int getX() {
return x;
}
@Override
public int getY() {
return y;
}
@Override
public void next() {
currentColumn++;
if (currentColumn >= rowCounts[currentRow]) {
//nextRow
if (++currentRow >= rows) {
x = 0;
y = 0;
return;
}
currentColumn = 0;
prepareX();
y += height + spacing;
return;
}
x += width + spacing;
}
private void init() {
prepareX();
prepareY();
}
private void prepareX() {
int rowWidth = rowCounts[currentRow] * width + (rowCounts[currentRow] - 1) * spacing;
x = -(rowWidth / 2);
}
private void prepareY() {
int totalHeight = rows * height + (rows > 1 ? ((rows - 1) * spacing) : 0);
y = -(totalHeight / 2);
}
@Override
public int getTotalWidth() {
return rowCounts[0] * width + (rowCounts[0] - 1) * spacing;
}
@Override
public int getTotalHeight() {
return rows * height + (rows > 1 ? ((rows - 1) * spacing) : 0);
}
}
}

View file

@ -1,21 +1,20 @@
package com.simibubi.create.foundation.ponder.ui;
import com.mojang.blaze3d.systems.RenderSystem;
import com.simibubi.create.foundation.gui.AllIcons;
import com.simibubi.create.foundation.gui.GuiGameElement;
import com.simibubi.create.foundation.gui.IScreenRenderable;
import com.simibubi.create.foundation.gui.widgets.AbstractSimiWidget;
import com.simibubi.create.foundation.ponder.PonderUI;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.ColorHelper;
import com.simibubi.create.foundation.utility.LerpedFloat;
import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.item.ItemStack;
public class PonderButton extends AbstractSimiWidget {
private AllIcons icon;
private IScreenRenderable icon;
private ItemStack item;
protected boolean pressed;
private Runnable onClick;
@ -27,14 +26,17 @@ public class PonderButton extends AbstractSimiWidget {
public static final int SIZE = 20;
public PonderButton(int x, int y, Runnable onClick) {
super(x, y, SIZE, SIZE);
public PonderButton(int x, int y, Runnable onClick, int width, int height) {
super(x, y, width, height);
this.onClick = onClick;
flash = LerpedFloat.linear()
.startWithValue(0);
flash = LerpedFloat.linear().startWithValue(0);
}
public PonderButton showing(AllIcons icon) {
public PonderButton(int x, int y, Runnable onClick) {
this(x, y, onClick, SIZE, SIZE);
}
public PonderButton showing(IScreenRenderable icon) {
this.icon = icon;
return this;
}
@ -97,17 +99,24 @@ public class PonderButton extends AbstractSimiWidget {
if (icon != null) {
RenderSystem.enableBlend();
RenderSystem.color4f(1, 1, 1, fade);
icon.draw(this, x + 2, y + 2);
RenderSystem.pushMatrix();
RenderSystem.translated(x + 2, y + 2, 0);
RenderSystem.scaled((width - 4) / 16d, (height - 4) / 16d, 1);
icon.draw(this, 0, 0);
RenderSystem.popMatrix();
}
if (item != null) {
RenderSystem.pushMatrix();
RenderSystem.translated(0, 0, -800);
GuiGameElement.of(item)
.at(x - 2, y - 2)
.scale(1.5f)
.render();
RenderSystem.popMatrix();
}
if (shortcut != null)
drawCenteredString(Minecraft.getInstance().fontRenderer, shortcut.getLocalizedName(), x + SIZE / 2 + 8,
y + SIZE - 6, ColorHelper.applyAlpha(0xff606060, fade));
drawCenteredString(Minecraft.getInstance().fontRenderer, shortcut.getLocalizedName(), x + width / 2 + 8,
y + height - 6, ColorHelper.applyAlpha(0xff606060, fade));
RenderSystem.popMatrix();
}
@ -133,4 +142,7 @@ public class PonderButton extends AbstractSimiWidget {
toolTip.add(text);
}
public ItemStack getItem() {
return item;
}
}

View file

@ -46,6 +46,10 @@ public class LerpedFloat {
return this;
}
public void updateChaseTarget(float target) {
this.chaseTarget = target;
}
public boolean updateChaseSpeed(double speed) {
float prevSpeed = this.chaseSpeed;
this.chaseSpeed = (float) speed;

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB