diff --git a/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocInstruction.java b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocInstruction.java index e392cf7eb..13bdda9e9 100644 --- a/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocInstruction.java +++ b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocInstruction.java @@ -1,13 +1,15 @@ package com.simibubi.create.foundation.metadoc; public abstract class MetaDocInstruction { - + public boolean isBlocking() { return false; } - + + public void reset(MetaDocScene scene) {} + public abstract boolean isComplete(); - + public abstract void tick(MetaDocScene scene); } diff --git a/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocScene.java b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocScene.java index 2c786329b..cc17692af 100644 --- a/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocScene.java +++ b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocScene.java @@ -11,6 +11,7 @@ import java.util.Set; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.foundation.metadoc.instructions.DelayInstruction; import com.simibubi.create.foundation.metadoc.instructions.DisplayWorldSectionInstruction; +import com.simibubi.create.foundation.metadoc.instructions.HideAllInstruction; import com.simibubi.create.foundation.metadoc.instructions.ShowCompleteSchematicInstruction; import net.minecraft.client.renderer.IRenderTypeBuffer; @@ -34,11 +35,21 @@ public class MetaDocScene { activeSchedule = new ArrayList<>(); } - public void begin() { + public void reset() { activeSchedule.clear(); + schedule.forEach(mdi -> mdi.reset(this)); + } + + public void begin() { + reset(); activeSchedule.addAll(schedule); } + public void fadeOut() { + reset(); + activeSchedule.add(new HideAllInstruction(10, Direction.DOWN)); + } + public void render(IRenderTypeBuffer buffer, MatrixStack ms) { ms.push(); MutableBoundingBox bounds = world.getBounds(); @@ -71,6 +82,10 @@ public class MetaDocScene { return world; } + public Set getElements() { + return elements; + } + public MutableBoundingBox getBounds() { return world.getBounds(); } @@ -88,11 +103,11 @@ public class MetaDocScene { public SceneBuilder showSection(BlockPos origin, Vec3i size, Direction fadeInDirection) { return addInstruction( - new DisplayWorldSectionInstruction(10, fadeInDirection, new WorldSectionElement.Cuboid(origin, size))); + new DisplayWorldSectionInstruction(20, fadeInDirection, new WorldSectionElement.Cuboid(origin, size))); } public SceneBuilder showSection(WorldSectionElement element, Direction fadeInDirection) { - return addInstruction(new DisplayWorldSectionInstruction(10, fadeInDirection, element)); + return addInstruction(new DisplayWorldSectionInstruction(20, fadeInDirection, element)); } public SceneBuilder debugSchematic() { diff --git a/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocSceneElement.java b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocSceneElement.java index fff1429d3..1b208c990 100644 --- a/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocSceneElement.java +++ b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocSceneElement.java @@ -10,4 +10,8 @@ public abstract class MetaDocSceneElement { public abstract void render(MetaDocWorld world, IRenderTypeBuffer buffer, MatrixStack ms); + public void setVisible(boolean visible) { + this.visible = visible; + } + } diff --git a/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocScreen.java b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocScreen.java index 36561772a..faccdf6f1 100644 --- a/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocScreen.java +++ b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocScreen.java @@ -11,16 +11,21 @@ import com.simibubi.create.foundation.utility.LerpedFloat; import com.simibubi.create.foundation.utility.LerpedFloat.Chaser; import com.simibubi.create.foundation.utility.MatrixStacker; +import net.minecraft.util.math.MathHelper; import net.minecraftforge.fml.client.gui.GuiUtils; public class MetaDocScreen extends AbstractSimiScreen { private List stories; - private int index = 0; private LerpedFloat fadeIn; + private LerpedFloat lazyIndex; + private int index = 0; + public MetaDocScreen(List stories) { this.stories = stories; + lazyIndex = LerpedFloat.linear() + .startWithValue(index); fadeIn = LerpedFloat.linear() .startWithValue(0) .chase(1, .5f, Chaser.EXP); @@ -28,27 +33,63 @@ public class MetaDocScreen extends AbstractSimiScreen { @Override public void tick() { + lazyIndex.tickChaser(); fadeIn.tickChaser(); stories.get(index) .tick(); + float lazyIndexValue = lazyIndex.getValue(); + if (Math.abs(lazyIndexValue - index) > 1 / 512f) + stories.get(lazyIndexValue < index ? index - 1 : index + 1) + .tick(); + } + + @Override + public boolean mouseScrolled(double mouseX, double mouseY, double delta) { + int prevIndex = index; + index = delta > 0 ? index + 1 : index - 1; + index = MathHelper.clamp(index, 0, stories.size() - 1); + if (prevIndex != index && Math.abs(index - lazyIndex.getValue()) < 1.25f) { + stories.get(prevIndex) + .fadeOut(); + stories.get(index) + .begin(); + lazyIndex.chase(index, 1 / 4f, Chaser.EXP); + return true; + } else + index = prevIndex; + return super.mouseScrolled(mouseX, mouseY, delta); } @Override protected void renderWindow(int mouseX, int mouseY, float partialTicks) { RenderSystem.enableBlend(); - renderStory(); - renderWidgets(partialTicks); + renderStories(partialTicks); + renderWidgets(mouseX, mouseY, partialTicks); } - protected void renderStory() { - MetaDocScene story = stories.get(index); + protected void renderStories(float partialTicks) { + renderStory(index, partialTicks); + float lazyIndexValue = lazyIndex.getValue(partialTicks); + if (Math.abs(lazyIndexValue - index) > 1 / 512f) + renderStory(lazyIndexValue < index ? index - 1 : index + 1, partialTicks); + } + + protected void renderStory(int i, float partialTicks) { + MetaDocScene story = stories.get(i); MatrixStack ms = new MatrixStack(); ms.push(); + ms.translate(width / 2, height / 2, 200); MatrixStacker.of(ms) .rotateX(-45) .rotateY(45); + + float value = lazyIndex.getValue(partialTicks); + float diff = i - value; + float slide = i == index ? 400 : MathHelper.lerp(Math.abs(diff), 0, 400); + ms.translate(diff * slide, 0, 0); + ms.scale(30, -30, 30); SuperRenderTypeBuffer buffer = SuperRenderTypeBuffer.getInstance(); @@ -57,7 +98,7 @@ public class MetaDocScreen extends AbstractSimiScreen { ms.pop(); } - protected void renderWidgets(float pt) { + protected void renderWidgets(int mouseX, int mouseY, float pt) { float fade = fadeIn.getValue(pt); int textColor = 0xeeeeee; @@ -72,7 +113,12 @@ public class MetaDocScreen extends AbstractSimiScreen { int closeHeight = 24; int closeX = (width - closeWidth) / 2; int closeY = height - closeHeight - 31; - renderBox(closeX, closeY, closeWidth, closeHeight, 0xdd000000, 0x30eebb00, 0x10eebb00); + + boolean hovered = !(mouseX < closeX || mouseX > closeX + closeWidth); + hovered &= !(mouseY < closeY || mouseY > closeY + closeHeight); + + renderBox(closeX, closeY, closeWidth, closeHeight, 0xdd000000, hovered ? 0x70ffffff : 0x30eebb00, + hovered ? 0x30ffffff : 0x10eebb00); AllIcons.I_CONFIRM.draw(closeX + 4, closeY + 4); RenderSystem.popMatrix(); diff --git a/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocWorld.java b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocWorld.java index de74c9309..5307ba49c 100644 --- a/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocWorld.java +++ b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocWorld.java @@ -3,12 +3,28 @@ package com.simibubi.create.foundation.metadoc; import com.simibubi.create.content.schematics.SchematicWorld; import net.minecraft.util.math.BlockPos; +import net.minecraft.world.LightType; import net.minecraft.world.World; public class MetaDocWorld extends SchematicWorld { + int overrideLight; + public MetaDocWorld(BlockPos anchor, World original) { super(anchor, original); } + public void pushFakeLight(int light) { + this.overrideLight = light; + } + + public void popLight() { + this.overrideLight = -1; + } + + @Override + public int getLightLevel(LightType p_226658_1_, BlockPos p_226658_2_) { + return overrideLight == -1 ? super.getLightLevel(p_226658_1_, p_226658_2_) : overrideLight; + } + } diff --git a/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocs.java b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocs.java index 61a2fea77..649b7fb71 100644 --- a/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocs.java +++ b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocs.java @@ -3,6 +3,7 @@ package com.simibubi.create.foundation.metadoc; 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; @@ -30,7 +31,8 @@ public class MetaDocs { public static void register() { - addStoryBoard(AllBlocks.COGWHEEL, new CogwheelStory()); + for (int i = 1; i < 6; i++) + addStoryBoard(AllBlocks.COGWHEEL, new CogwheelStory(i)); } @@ -59,9 +61,12 @@ public class MetaDocs { public static Template loadSchematic(String path) { Template t = new Template(); String filepath = "doc/" + path + ".nbt"; + InputStream resourceAsStream = Create.class.getClassLoader() + .getResourceAsStream(filepath); + if (resourceAsStream == null) + throw new IllegalStateException("Could not find metadoc schematic: " + filepath); try (DataInputStream stream = - new DataInputStream(new BufferedInputStream(new GZIPInputStream(Create.class.getClassLoader() - .getResourceAsStream(filepath))))) { + new DataInputStream(new BufferedInputStream(new GZIPInputStream(resourceAsStream)))) { CompoundNBT nbt = CompressedStreamTools.read(stream, new NBTSizeTracker(0x20000000L)); t.read(nbt); } catch (IOException e) { diff --git a/src/main/java/com/simibubi/create/foundation/metadoc/WorldSectionElement.java b/src/main/java/com/simibubi/create/foundation/metadoc/WorldSectionElement.java index 6f5e1ede0..274551085 100644 --- a/src/main/java/com/simibubi/create/foundation/metadoc/WorldSectionElement.java +++ b/src/main/java/com/simibubi/create/foundation/metadoc/WorldSectionElement.java @@ -44,7 +44,14 @@ public abstract class WorldSectionElement extends AnimatedSceneElement implement @Override public void render(MetaDocWorld world, IRenderTypeBuffer buffer, MatrixStack ms, float fade) { + int light = -1; + if (fade != 1) + light = (int) (0xF * fade); + + world.pushFakeLight(light); renderTileEntities(world, ms, buffer); + world.popLight(); + if (buffer instanceof IRenderTypeBuffer.Impl) ((IRenderTypeBuffer.Impl) buffer).draw(); renderStructure(world, ms, buffer, fade); @@ -87,7 +94,7 @@ public abstract class WorldSectionElement extends AnimatedSceneElement implement protected void renderStructure(MetaDocWorld world, MatrixStack ms, IRenderTypeBuffer buffer, float fade) { SuperByteBufferCache bufferCache = CreateClient.bufferCache; List blockLayers = RenderType.getBlockLayers(); - int code = hashCode(); + int code = hashCode() ^ world.hashCode(); buffer.getBuffer(RenderType.getSolid()); for (int i = 0; i < blockLayers.size(); i++) { diff --git a/src/main/java/com/simibubi/create/foundation/metadoc/instructions/HideAllInstruction.java b/src/main/java/com/simibubi/create/foundation/metadoc/instructions/HideAllInstruction.java new file mode 100644 index 000000000..46d8a2833 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/metadoc/instructions/HideAllInstruction.java @@ -0,0 +1,47 @@ +package com.simibubi.create.foundation.metadoc.instructions; + +import com.simibubi.create.foundation.metadoc.AnimatedSceneElement; +import com.simibubi.create.foundation.metadoc.MetaDocScene; + +import net.minecraft.util.Direction; +import net.minecraft.util.math.Vec3d; + +public class HideAllInstruction extends TickingInstruction { + + private Direction fadeOutTo; + + public HideAllInstruction(int fadeOutTicks, Direction fadeOutTo) { + super(false, fadeOutTicks); + this.fadeOutTo = fadeOutTo; + } + + @Override + protected void firstTick(MetaDocScene scene) { + super.firstTick(scene); + scene.getElements() + .forEach(element -> { + if (element instanceof AnimatedSceneElement) { + AnimatedSceneElement animatedSceneElement = (AnimatedSceneElement) element; + animatedSceneElement.setFade(1); + animatedSceneElement.setFadeVec(new Vec3d(fadeOutTo.getDirectionVec()).scale(.5f)); + } else + element.setVisible(false); + }); + } + + @Override + public void tick(MetaDocScene scene) { + super.tick(scene); + float fade = (remainingTicks / (float) totalTicks); + scene.getElements() + .forEach(element -> { + if (!(element instanceof AnimatedSceneElement)) + return; + AnimatedSceneElement animatedSceneElement = (AnimatedSceneElement) element; + animatedSceneElement.setFade(fade * fade); + if (remainingTicks == 0) + animatedSceneElement.setFade(0); + }); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/metadoc/instructions/TickingInstruction.java b/src/main/java/com/simibubi/create/foundation/metadoc/instructions/TickingInstruction.java index cef9e1e25..eae1b3f41 100644 --- a/src/main/java/com/simibubi/create/foundation/metadoc/instructions/TickingInstruction.java +++ b/src/main/java/com/simibubi/create/foundation/metadoc/instructions/TickingInstruction.java @@ -14,6 +14,12 @@ public abstract class TickingInstruction extends MetaDocInstruction { remainingTicks = totalTicks = ticks; } + @Override + public void reset(MetaDocScene scene) { + super.reset(scene); + remainingTicks = totalTicks; + } + protected void firstTick(MetaDocScene scene) {} @Override diff --git a/src/main/java/com/simibubi/create/foundation/metadoc/stories/CogwheelStory.java b/src/main/java/com/simibubi/create/foundation/metadoc/stories/CogwheelStory.java index b44e403d4..f640b6cb5 100644 --- a/src/main/java/com/simibubi/create/foundation/metadoc/stories/CogwheelStory.java +++ b/src/main/java/com/simibubi/create/foundation/metadoc/stories/CogwheelStory.java @@ -9,9 +9,15 @@ import net.minecraft.util.math.Vec3i; public class CogwheelStory extends MetaDocStoryBoard { + private int index; + + public CogwheelStory(int index) { + this.index = index; + } + @Override public String getSchematicName() { - return "cogwheel/test"; + return "cogwheel/s" + index; } @Override diff --git a/src/main/resources/doc/cogwheel/test.nbt b/src/main/resources/doc/cogwheel/s1.nbt similarity index 100% rename from src/main/resources/doc/cogwheel/test.nbt rename to src/main/resources/doc/cogwheel/s1.nbt diff --git a/src/main/resources/doc/cogwheel/s2.nbt b/src/main/resources/doc/cogwheel/s2.nbt new file mode 100644 index 000000000..e7889a802 Binary files /dev/null and b/src/main/resources/doc/cogwheel/s2.nbt differ diff --git a/src/main/resources/doc/cogwheel/s3.nbt b/src/main/resources/doc/cogwheel/s3.nbt new file mode 100644 index 000000000..b60d58b68 Binary files /dev/null and b/src/main/resources/doc/cogwheel/s3.nbt differ diff --git a/src/main/resources/doc/cogwheel/s4.nbt b/src/main/resources/doc/cogwheel/s4.nbt new file mode 100644 index 000000000..643511335 Binary files /dev/null and b/src/main/resources/doc/cogwheel/s4.nbt differ diff --git a/src/main/resources/doc/cogwheel/s5.nbt b/src/main/resources/doc/cogwheel/s5.nbt new file mode 100644 index 000000000..056249163 Binary files /dev/null and b/src/main/resources/doc/cogwheel/s5.nbt differ