diff --git a/src/main/java/com/simibubi/create/CreateClient.java b/src/main/java/com/simibubi/create/CreateClient.java index 51f5007e5..07668a3b6 100644 --- a/src/main/java/com/simibubi/create/CreateClient.java +++ b/src/main/java/com/simibubi/create/CreateClient.java @@ -16,6 +16,8 @@ import com.simibubi.create.foundation.block.render.CustomBlockModels; import com.simibubi.create.foundation.block.render.SpriteShifter; import com.simibubi.create.foundation.item.CustomItemModels; import com.simibubi.create.foundation.item.CustomRenderedItems; +import com.simibubi.create.foundation.metadoc.MetaDocs; +import com.simibubi.create.foundation.metadoc.WorldSectionElement; import com.simibubi.create.foundation.utility.SuperByteBufferCache; import com.simibubi.create.foundation.utility.outliner.Outliner; @@ -66,6 +68,7 @@ public class CreateClient { bufferCache = new SuperByteBufferCache(); bufferCache.registerCompartment(KineticTileEntityRenderer.KINETIC_TILE); bufferCache.registerCompartment(ContraptionRenderer.CONTRAPTION, 20); + bufferCache.registerCompartment(WorldSectionElement.DOC_WORLD_SECTION, 20); AllKeys.register(); AllContainerTypes.registerScreenFactories(); @@ -73,6 +76,7 @@ public class CreateClient { AllEntityTypes.registerRenderers(); getColorHandler().init(); AllFluids.assignRenderLayers(); + MetaDocs.register(); IResourceManager resourceManager = Minecraft.getInstance() .getResourceManager(); diff --git a/src/main/java/com/simibubi/create/events/ClientEvents.java b/src/main/java/com/simibubi/create/events/ClientEvents.java index f502d8be4..a434233c7 100644 --- a/src/main/java/com/simibubi/create/events/ClientEvents.java +++ b/src/main/java/com/simibubi/create/events/ClientEvents.java @@ -26,7 +26,7 @@ import com.simibubi.create.content.logistics.block.mechanicalArm.ArmInteractionP 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.metadoc.MetaDocHandler; +import com.simibubi.create.foundation.metadoc.MetaDocTooltipHandler; import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.networking.LeftClickPacket; import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; @@ -88,7 +88,7 @@ public class ClientEvents { CapabilityMinecartController.tick(world); CouplingPhysics.tick(world); - MetaDocHandler.tick(); + MetaDocTooltipHandler.tick(); ScreenOpener.tick(); ServerSpeedProvider.clientTick(); BeltConnectorHandler.tick(); @@ -150,7 +150,7 @@ public class ClientEvents { @SubscribeEvent public static void getItemTooltipColor(RenderTooltipEvent.Color event) { - MetaDocHandler.handleTooltipColor(event); + MetaDocTooltipHandler.handleTooltipColor(event); } @SubscribeEvent @@ -175,7 +175,7 @@ public class ClientEvents { itemTooltip.addAll(0, toolTip); } - MetaDocHandler.addToTooltip(event.getToolTip(), stack); + MetaDocTooltipHandler.addToTooltip(event.getToolTip(), stack); } @SubscribeEvent diff --git a/src/main/java/com/simibubi/create/foundation/metadoc/AnimatedSceneElement.java b/src/main/java/com/simibubi/create/foundation/metadoc/AnimatedSceneElement.java new file mode 100644 index 000000000..fc13b7bff --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/metadoc/AnimatedSceneElement.java @@ -0,0 +1,43 @@ +package com.simibubi.create.foundation.metadoc; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.foundation.utility.LerpedFloat; +import com.simibubi.create.foundation.utility.MatrixStacker; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.util.math.Vec3d; + +public abstract class AnimatedSceneElement extends MetaDocSceneElement { + + protected Vec3d fadeVec; + protected LerpedFloat fade; + + public AnimatedSceneElement() { + fade = LerpedFloat.linear() + .startWithValue(0); + } + + public void setFade(float fade) { + this.fade.setValue(fade); + } + + public void setFadeVec(Vec3d fadeVec) { + this.fadeVec = fadeVec; + } + + @Override + public final void render(MetaDocWorld world, IRenderTypeBuffer buffer, MatrixStack ms) { + ms.push(); + float currentFade = fade.getValue(Minecraft.getInstance() + .getRenderPartialTicks()); + if (fadeVec != null) + MatrixStacker.of(ms) + .translate(fadeVec.scale(-1 + currentFade)); + render(world, buffer, ms, currentFade); + ms.pop(); + } + + protected abstract void render(MetaDocWorld world, IRenderTypeBuffer buffer, MatrixStack ms, float fade); + +} diff --git a/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocInstruction.java b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocInstruction.java new file mode 100644 index 000000000..e392cf7eb --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocInstruction.java @@ -0,0 +1,13 @@ +package com.simibubi.create.foundation.metadoc; + +public abstract class MetaDocInstruction { + + public boolean isBlocking() { + return false; + } + + 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 new file mode 100644 index 000000000..2c786329b --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocScene.java @@ -0,0 +1,117 @@ +package com.simibubi.create.foundation.metadoc; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +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.ShowCompleteSchematicInstruction; + +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MutableBoundingBox; +import net.minecraft.util.math.Vec3i; + +public class MetaDocScene { + + List schedule, activeSchedule; + Set elements; + Map> groups; + MetaDocWorld world; + + public MetaDocScene(MetaDocWorld world) { + this.world = world; + elements = new HashSet<>(); + groups = new IdentityHashMap<>(); + schedule = new ArrayList<>(); + activeSchedule = new ArrayList<>(); + } + + public void begin() { + activeSchedule.clear(); + activeSchedule.addAll(schedule); + } + + public void render(IRenderTypeBuffer buffer, MatrixStack ms) { + ms.push(); + MutableBoundingBox bounds = world.getBounds(); + ms.translate(bounds.getXSize() / -2f, -.5f, bounds.getZSize() / -2f); + elements.forEach(e -> { + if (e.visible) + e.render(world, buffer, ms); + }); + ms.pop(); + } + + public void tick() { + for (Iterator iterator = activeSchedule.iterator(); iterator.hasNext();) { + MetaDocInstruction metaDocInstruction = iterator.next(); + metaDocInstruction.tick(this); + if (metaDocInstruction.isComplete()) { + iterator.remove(); + continue; + } + if (metaDocInstruction.isBlocking()) + break; + } + } + + public void addElement(MetaDocSceneElement e) { + elements.add(e); + } + + public MetaDocWorld getWorld() { + return world; + } + + public MutableBoundingBox getBounds() { + return world.getBounds(); + } + + public SceneBuilder builder() { + return new SceneBuilder(); + } + + public class SceneBuilder { + + public SceneBuilder showBasePlate() { + Vec3i length = getBounds().getLength(); + return showSection(BlockPos.ZERO, new Vec3i(length.getX(), 0, length.getZ()), Direction.UP); + } + + public SceneBuilder showSection(BlockPos origin, Vec3i size, Direction fadeInDirection) { + return addInstruction( + new DisplayWorldSectionInstruction(10, fadeInDirection, new WorldSectionElement.Cuboid(origin, size))); + } + + public SceneBuilder showSection(WorldSectionElement element, Direction fadeInDirection) { + return addInstruction(new DisplayWorldSectionInstruction(10, fadeInDirection, element)); + } + + public SceneBuilder debugSchematic() { + return addInstruction(new ShowCompleteSchematicInstruction()); + } + + public SceneBuilder idle(int ticks) { + return addInstruction(new DelayInstruction(ticks)); + } + + public SceneBuilder idleSeconds(int seconds) { + return idle(seconds * 20); + } + + public SceneBuilder addInstruction(MetaDocInstruction instruction) { + schedule.add(instruction); + return this; + } + + } + +} \ No newline at end of file diff --git a/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocSceneElement.java b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocSceneElement.java new file mode 100644 index 000000000..fff1429d3 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocSceneElement.java @@ -0,0 +1,13 @@ +package com.simibubi.create.foundation.metadoc; + +import com.mojang.blaze3d.matrix.MatrixStack; + +import net.minecraft.client.renderer.IRenderTypeBuffer; + +public abstract class MetaDocSceneElement { + + boolean visible = true; + + public abstract void render(MetaDocWorld world, IRenderTypeBuffer buffer, MatrixStack ms); + +} 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 45553b045..36561772a 100644 --- a/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocScreen.java +++ b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocScreen.java @@ -1,29 +1,86 @@ package com.simibubi.create.foundation.metadoc; +import java.util.List; + +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.GuiGameElement; -import com.simibubi.create.foundation.utility.AnimationTickHolder; +import com.simibubi.create.foundation.gui.AllIcons; +import com.simibubi.create.foundation.renderState.SuperRenderTypeBuffer; +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.block.Blocks; import net.minecraftforge.fml.client.gui.GuiUtils; public class MetaDocScreen extends AbstractSimiScreen { + private List stories; + private int index = 0; + private LerpedFloat fadeIn; + + public MetaDocScreen(List stories) { + this.stories = stories; + fadeIn = LerpedFloat.linear() + .startWithValue(0) + .chase(1, .5f, Chaser.EXP); + } + + @Override + public void tick() { + fadeIn.tickChaser(); + stories.get(index) + .tick(); + } + @Override protected void renderWindow(int mouseX, int mouseY, float partialTicks) { + RenderSystem.enableBlend(); + renderStory(); + renderWidgets(partialTicks); + } - int tooltipX = 50; - int tooltipY = 50; - int tooltipTextWidth = width - 100; - int backgroundColor = GuiUtils.DEFAULT_BACKGROUND_COLOR; - int borderColorStart = GuiUtils.DEFAULT_BORDER_COLOR_START; - int borderColorEnd = GuiUtils.DEFAULT_BORDER_COLOR_END; - int zLevel = 100; - int tooltipHeight = height - 100; + protected void renderStory() { + MetaDocScene story = stories.get(index); + MatrixStack ms = new MatrixStack(); + ms.push(); - drawString(font, "MetaDoc Experimental 0", tooltipX, tooltipY - 16, 0xffffff); + ms.translate(width / 2, height / 2, 200); + MatrixStacker.of(ms) + .rotateX(-45) + .rotateY(45); + ms.scale(30, -30, 30); + SuperRenderTypeBuffer buffer = SuperRenderTypeBuffer.getInstance(); + story.render(buffer, ms); + buffer.draw(); + ms.pop(); + } + + protected void renderWidgets(float pt) { + float fade = fadeIn.getValue(pt); + int textColor = 0xeeeeee; + + drawString(font, "MetaDoc Experimental 0", 50, 50 - 16, textColor); + + RenderSystem.pushMatrix(); + + if (fade < 1) + RenderSystem.translated(0, (1 - fade) * 5, 0); + + int closeWidth = 24; + int closeHeight = 24; + int closeX = (width - closeWidth) / 2; + int closeY = height - closeHeight - 31; + renderBox(closeX, closeY, closeWidth, closeHeight, 0xdd000000, 0x30eebb00, 0x10eebb00); + AllIcons.I_CONFIRM.draw(closeX + 4, closeY + 4); + + RenderSystem.popMatrix(); + } + + protected void renderBox(int tooltipX, int tooltipY, int tooltipTextWidth, int tooltipHeight, int backgroundColor, + int borderColorStart, int borderColorEnd) { + int zLevel = 400; GuiUtils.drawGradientRect(zLevel, tooltipX - 3, tooltipY - 4, tooltipX + tooltipTextWidth + 3, tooltipY - 3, backgroundColor, backgroundColor); GuiUtils.drawGradientRect(zLevel, tooltipX - 3, tooltipY + tooltipHeight + 3, tooltipX + tooltipTextWidth + 3, @@ -42,15 +99,6 @@ public class MetaDocScreen extends AbstractSimiScreen { borderColorStart, borderColorStart); GuiUtils.drawGradientRect(zLevel, tooltipX - 3, tooltipY + tooltipHeight + 2, tooltipX + tooltipTextWidth + 3, tooltipY + tooltipHeight + 3, borderColorEnd, borderColorEnd); - - RenderSystem.pushMatrix(); - RenderSystem.translated(width/2, height/2, 200); - GuiGameElement.of(Blocks.DIAMOND_BLOCK.getDefaultState()) - .rotate(22.5, AnimationTickHolder.getRenderTick() % 360f, 0) - .scale(50) - .render(); - RenderSystem.popMatrix(); - } } diff --git a/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocStoryBoard.java b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocStoryBoard.java new file mode 100644 index 000000000..ecd1e78ca --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocStoryBoard.java @@ -0,0 +1,13 @@ +package com.simibubi.create.foundation.metadoc; + +import com.simibubi.create.foundation.metadoc.MetaDocScene.SceneBuilder; + +import net.minecraft.util.math.Vec3i; + +public abstract class MetaDocStoryBoard { + + public abstract String getSchematicName(); + + public abstract void program(SceneBuilder scene, Vec3i worldSize); + +} diff --git a/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocHandler.java b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocTooltipHandler.java similarity index 85% rename from src/main/java/com/simibubi/create/foundation/metadoc/MetaDocHandler.java rename to src/main/java/com/simibubi/create/foundation/metadoc/MetaDocTooltipHandler.java index e5e33b156..75247e7c8 100644 --- a/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocHandler.java +++ b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocTooltipHandler.java @@ -18,7 +18,7 @@ import net.minecraft.util.text.StringTextComponent; import net.minecraft.util.text.TextFormatting; import net.minecraftforge.client.event.RenderTooltipEvent; -public class MetaDocHandler { +public class MetaDocTooltipHandler { static LerpedFloat holdWProgress = LerpedFloat.linear() .startWithValue(0); @@ -38,21 +38,27 @@ public class MetaDocHandler { return; ItemStack stack = slotUnderMouse.getStack(); + + if (!MetaDocs.all.containsKey(stack.getItem() + .getRegistryName())) + return; + if (prevStack != stack) holdWProgress.startWithValue(0); float value = holdWProgress.getValue(); - if (InputMappings.isKeyDown(instance.getWindow() - .getHandle(), - instance.gameSettings.keyBindForward.getKey() - .getKeyCode())) { -// if (AllKeys.altDown()) { + int keyCode = instance.gameSettings.keyBindForward.getKey() + .getKeyCode(); + long window = instance.getWindow() + .getHandle(); + + if (InputMappings.isKeyDown(window, keyCode)) { if (value >= 1) - ScreenOpener.open(new MetaDocScreen()); + ScreenOpener.open(new MetaDocScreen(MetaDocs.compile(stack.getItem() + .getRegistryName()))); holdWProgress.setValue(Math.min(1, value + Math.max(.25f, value) * .25f)); - } else { + } else holdWProgress.setValue(Math.max(0, value - .05f)); - } lastHoveredStack = stack; } @@ -88,7 +94,7 @@ public class MetaDocHandler { return ColorHelper.mixColors(0x5000FF, 5592575, progress * 2); // if (progress < .75f) // return ColorHelper.mixColors(16733695, 5636095, (progress - .5f) * 4); - return ColorHelper.mixColors(5592575, 5636095, (progress - .5f) * 2); + return ColorHelper.mixColors(5592575, 0xffffff, (progress - .5f) * 2); } private static ITextComponent makeProgressBar(float progress) { @@ -98,11 +104,11 @@ public class MetaDocHandler { if (progress < 1) bar += Strings.repeat("\u2592", 12 - filledLength); - TextFormatting color = TextFormatting.GRAY; + TextFormatting color = TextFormatting.DARK_GRAY; if (progress > 0) - color = TextFormatting.BLUE; + color = TextFormatting.GRAY; if (progress == 1f) - color = TextFormatting.AQUA; + color = TextFormatting.WHITE; ITextComponent leftBr = new StringTextComponent("").applyTextStyle(TextFormatting.WHITE); ITextComponent rightBr = new StringTextComponent("").applyTextStyle(TextFormatting.WHITE); diff --git a/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocWorld.java b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocWorld.java new file mode 100644 index 000000000..de74c9309 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocWorld.java @@ -0,0 +1,14 @@ +package com.simibubi.create.foundation.metadoc; + +import com.simibubi.create.content.schematics.SchematicWorld; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.World; + +public class MetaDocWorld extends SchematicWorld { + + public MetaDocWorld(BlockPos anchor, World original) { + super(anchor, original); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocs.java b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocs.java new file mode 100644 index 000000000..61a2fea77 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/metadoc/MetaDocs.java @@ -0,0 +1,73 @@ +package com.simibubi.create.foundation.metadoc; + +import java.io.BufferedInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.zip.GZIPInputStream; + +import com.simibubi.create.AllBlocks; +import com.simibubi.create.Create; +import com.simibubi.create.foundation.metadoc.stories.CogwheelStory; +import com.tterrag.registrate.util.entry.ItemProviderEntry; + +import net.minecraft.client.Minecraft; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.CompressedStreamTools; +import net.minecraft.nbt.NBTSizeTracker; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.gen.feature.template.PlacementSettings; +import net.minecraft.world.gen.feature.template.Template; + +public class MetaDocs { + + static Map> all = new HashMap<>(); + + public static void register() { + + addStoryBoard(AllBlocks.COGWHEEL, new CogwheelStory()); + + } + + private static void addStoryBoard(ItemProviderEntry component, MetaDocStoryBoard storyBoard) { + ResourceLocation id = component.getId(); + all.computeIfAbsent(id, $ -> new ArrayList<>()) + .add(storyBoard); + } + + public static List compile(ResourceLocation id) { + return all.get(id) + .stream() + .map(sb -> { + Template activeTemplate = loadSchematic(sb.getSchematicName()); + MetaDocWorld world = new MetaDocWorld(BlockPos.ZERO, Minecraft.getInstance().world); + activeTemplate.addBlocksToWorld(world, BlockPos.ZERO, new PlacementSettings()); + MetaDocScene scene = new MetaDocScene(world); + sb.program(scene.builder(), world.getBounds() + .getLength()); + scene.begin(); + return scene; + }) + .collect(Collectors.toList()); + } + + public static Template loadSchematic(String path) { + Template t = new Template(); + String filepath = "doc/" + path + ".nbt"; + try (DataInputStream stream = + new DataInputStream(new BufferedInputStream(new GZIPInputStream(Create.class.getClassLoader() + .getResourceAsStream(filepath))))) { + CompoundNBT nbt = CompressedStreamTools.read(stream, new NBTSizeTracker(0x20000000L)); + t.read(nbt); + } catch (IOException e) { + Create.logger.warn("Failed to read metadoc schematic", e); + } + return t; + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/metadoc/WorldSectionElement.java b/src/main/java/com/simibubi/create/foundation/metadoc/WorldSectionElement.java new file mode 100644 index 000000000..6f5e1ede0 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/metadoc/WorldSectionElement.java @@ -0,0 +1,152 @@ +package com.simibubi.create.foundation.metadoc; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Random; +import java.util.function.Predicate; +import java.util.stream.Stream; + +import org.apache.commons.lang3.tuple.Pair; +import org.lwjgl.opengl.GL11; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.simibubi.create.CreateClient; +import com.simibubi.create.foundation.utility.SuperByteBuffer; +import com.simibubi.create.foundation.utility.SuperByteBufferCache; +import com.simibubi.create.foundation.utility.SuperByteBufferCache.Compartment; +import com.simibubi.create.foundation.utility.TileEntityRenderHelper; + +import net.minecraft.block.BlockRenderType; +import net.minecraft.block.BlockState; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.BlockModelRenderer; +import net.minecraft.client.renderer.BlockRendererDispatcher; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.RenderTypeLookup; +import net.minecraft.client.renderer.model.IBakedModel; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MutableBoundingBox; +import net.minecraft.util.math.Vec3i; +import net.minecraftforge.client.ForgeHooksClient; +import net.minecraftforge.client.model.data.EmptyModelData; + +public abstract class WorldSectionElement extends AnimatedSceneElement implements Predicate { + + public static final Compartment> DOC_WORLD_SECTION = new Compartment<>(); + + List renderedTileEntities; + + @Override + public void render(MetaDocWorld world, IRenderTypeBuffer buffer, MatrixStack ms, float fade) { + renderTileEntities(world, ms, buffer); + if (buffer instanceof IRenderTypeBuffer.Impl) + ((IRenderTypeBuffer.Impl) buffer).draw(); + renderStructure(world, ms, buffer, fade); + } + + @Override + public abstract int hashCode(); + + public abstract Stream all(); + + public static class Cuboid extends WorldSectionElement { + + MutableBoundingBox bb; + Vec3i origin; + Vec3i size; + + public Cuboid(BlockPos origin, Vec3i size) { + bb = new MutableBoundingBox(origin, origin.add(size)); + this.origin = origin; + this.size = size; + } + + @Override + public boolean test(BlockPos t) { + return bb.isVecInside(t); + } + + @Override + public Stream all() { + return BlockPos.func_229383_a_(bb); + } + + @Override + public int hashCode() { + return origin.hashCode() ^ size.hashCode(); + } + + } + + protected void renderStructure(MetaDocWorld world, MatrixStack ms, IRenderTypeBuffer buffer, float fade) { + SuperByteBufferCache bufferCache = CreateClient.bufferCache; + List blockLayers = RenderType.getBlockLayers(); + int code = hashCode(); + + buffer.getBuffer(RenderType.getSolid()); + for (int i = 0; i < blockLayers.size(); i++) { + RenderType layer = blockLayers.get(i); + Pair key = Pair.of(code, i); + SuperByteBuffer contraptionBuffer = + bufferCache.get(DOC_WORLD_SECTION, key, () -> buildStructureBuffer(world, layer)); + if (contraptionBuffer.isEmpty()) + continue; + + int light = 0xF000F0; + if (fade != 1) { + light = (int) (0xF * fade); + light = light << 4 | light << 20; + } + + contraptionBuffer.light(light) + .renderInto(ms, buffer.getBuffer(layer)); + } + } + + private void renderTileEntities(MetaDocWorld world, MatrixStack ms, IRenderTypeBuffer buffer) { + if (renderedTileEntities == null) { + renderedTileEntities = new ArrayList<>(); + all().map(world::getTileEntity) + .filter(Objects::nonNull) + .forEach(renderedTileEntities::add); + } + + TileEntityRenderHelper.renderTileEntities(world, renderedTileEntities, ms, new MatrixStack(), buffer); + } + + private SuperByteBuffer buildStructureBuffer(MetaDocWorld world, RenderType layer) { + ForgeHooksClient.setRenderLayer(layer); + MatrixStack ms = new MatrixStack(); + BlockRendererDispatcher dispatcher = Minecraft.getInstance() + .getBlockRendererDispatcher(); + BlockModelRenderer blockRenderer = dispatcher.getBlockModelRenderer(); + Random random = new Random(); + BufferBuilder builder = new BufferBuilder(DefaultVertexFormats.BLOCK.getIntegerSize()); + builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK); + + all().forEach(pos -> { + BlockState state = world.getBlockState(pos); + if (state.getRenderType() == BlockRenderType.ENTITYBLOCK_ANIMATED) + return; + if (!RenderTypeLookup.canRenderInLayer(state, layer)) + return; + + IBakedModel originalModel = dispatcher.getModelForState(state); + ms.push(); + ms.translate(pos.getX(), pos.getY(), pos.getZ()); + blockRenderer.renderModel(world, originalModel, state, pos, ms, builder, true, random, 42, + OverlayTexture.DEFAULT_UV, EmptyModelData.INSTANCE); + ms.pop(); + }); + + builder.finishDrawing(); + return new SuperByteBuffer(builder); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/metadoc/instructions/DelayInstruction.java b/src/main/java/com/simibubi/create/foundation/metadoc/instructions/DelayInstruction.java new file mode 100644 index 000000000..a44bed1fb --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/metadoc/instructions/DelayInstruction.java @@ -0,0 +1,9 @@ +package com.simibubi.create.foundation.metadoc.instructions; + +public class DelayInstruction extends TickingInstruction { + + public DelayInstruction(int ticks) { + super(true, ticks); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/metadoc/instructions/DisplayWorldSectionInstruction.java b/src/main/java/com/simibubi/create/foundation/metadoc/instructions/DisplayWorldSectionInstruction.java new file mode 100644 index 000000000..ba07163c1 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/metadoc/instructions/DisplayWorldSectionInstruction.java @@ -0,0 +1,37 @@ +package com.simibubi.create.foundation.metadoc.instructions; + +import com.simibubi.create.foundation.metadoc.MetaDocScene; +import com.simibubi.create.foundation.metadoc.WorldSectionElement; + +import net.minecraft.util.Direction; +import net.minecraft.util.math.Vec3d; + +public class DisplayWorldSectionInstruction extends TickingInstruction { + + private Direction fadeInFrom; + private WorldSectionElement element; + + public DisplayWorldSectionInstruction(int fadeInTicks, Direction fadeInFrom, WorldSectionElement element) { + super(false, fadeInTicks); + this.fadeInFrom = fadeInFrom; + this.element = element; + } + + @Override + protected void firstTick(MetaDocScene scene) { + super.firstTick(scene); + scene.addElement(element); + element.setFade(0); + element.setFadeVec(new Vec3d(fadeInFrom.getDirectionVec()).scale(.5f)); + } + + @Override + public void tick(MetaDocScene scene) { + super.tick(scene); + float fade = (remainingTicks / (float) totalTicks); + element.setFade(1 - fade * fade); + if (remainingTicks == 0) + element.setFade(1); + } + +} diff --git a/src/main/java/com/simibubi/create/foundation/metadoc/instructions/ShowCompleteSchematicInstruction.java b/src/main/java/com/simibubi/create/foundation/metadoc/instructions/ShowCompleteSchematicInstruction.java new file mode 100644 index 000000000..dbfa9c776 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/metadoc/instructions/ShowCompleteSchematicInstruction.java @@ -0,0 +1,22 @@ +package com.simibubi.create.foundation.metadoc.instructions; + +import com.simibubi.create.foundation.metadoc.MetaDocInstruction; +import com.simibubi.create.foundation.metadoc.MetaDocScene; +import com.simibubi.create.foundation.metadoc.WorldSectionElement; + +import net.minecraft.util.math.BlockPos; + +public class ShowCompleteSchematicInstruction extends MetaDocInstruction { + + @Override + public void tick(MetaDocScene scene) { + scene.addElement(new WorldSectionElement.Cuboid(BlockPos.ZERO, scene.getBounds() + .getLength())); + } + + @Override + public boolean isComplete() { + return true; + } + +} 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 new file mode 100644 index 000000000..cef9e1e25 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/metadoc/instructions/TickingInstruction.java @@ -0,0 +1,37 @@ +package com.simibubi.create.foundation.metadoc.instructions; + +import com.simibubi.create.foundation.metadoc.MetaDocInstruction; +import com.simibubi.create.foundation.metadoc.MetaDocScene; + +public abstract class TickingInstruction extends MetaDocInstruction { + + private boolean blocking; + protected int totalTicks; + protected int remainingTicks; + + public TickingInstruction(boolean blocking, int ticks) { + this.blocking = blocking; + remainingTicks = totalTicks = ticks; + } + + protected void firstTick(MetaDocScene scene) {} + + @Override + public void tick(MetaDocScene scene) { + if (remainingTicks == totalTicks) + firstTick(scene); + if (remainingTicks > 0) + remainingTicks--; + } + + @Override + public boolean isComplete() { + return remainingTicks == 0; + } + + @Override + public boolean isBlocking() { + return blocking; + } + +} 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 new file mode 100644 index 000000000..b44e403d4 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/metadoc/stories/CogwheelStory.java @@ -0,0 +1,24 @@ +package com.simibubi.create.foundation.metadoc.stories; + +import com.simibubi.create.foundation.metadoc.MetaDocScene.SceneBuilder; +import com.simibubi.create.foundation.metadoc.MetaDocStoryBoard; + +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Vec3i; + +public class CogwheelStory extends MetaDocStoryBoard { + + @Override + public String getSchematicName() { + return "cogwheel/test"; + } + + @Override + public void program(SceneBuilder scene, Vec3i worldSize) { + scene.showBasePlate() + .idle(5) + .showSection(BlockPos.ZERO.up(), worldSize, Direction.DOWN); + } + +} diff --git a/src/main/resources/doc/cogwheel/test.nbt b/src/main/resources/doc/cogwheel/test.nbt new file mode 100644 index 000000000..4aa492260 Binary files /dev/null and b/src/main/resources/doc/cogwheel/test.nbt differ