From ed8e3f9d950a30c135561e9e9bb4345c672a6d39 Mon Sep 17 00:00:00 2001 From: LLytho Date: Sun, 28 Jul 2024 09:42:11 +0200 Subject: [PATCH] Add custom render elements --- CHANGELOG.md | 3 + gradle.properties | 2 +- .../api/CustomPonderOverlayElement.java | 66 +++++++++++++ .../api/CustomPonderSceneElement.java | 97 +++++++++++++++++++ .../ponderjs/api/ExtendedSceneBuilder.java | 63 ++++++++++++ .../ponderjs/api/OnElementAction.java | 12 +++ .../ponderjs/api/OnRenderOverlay.java | 15 +++ .../ponderjs/api/OnRenderWorld.java | 25 +++++ .../ponderjs/mixin/SceneBuilderAccessor.java | 4 + 9 files changed, 286 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/almostreliable/ponderjs/api/CustomPonderOverlayElement.java create mode 100644 src/main/java/com/almostreliable/ponderjs/api/CustomPonderSceneElement.java create mode 100644 src/main/java/com/almostreliable/ponderjs/api/OnElementAction.java create mode 100644 src/main/java/com/almostreliable/ponderjs/api/OnRenderOverlay.java create mode 100644 src/main/java/com/almostreliable/ponderjs/api/OnRenderWorld.java diff --git a/CHANGELOG.md b/CHANGELOG.md index a737c5f..93e4d60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,8 @@ # Changelog +## [1.4.0] +- Add custom render elements + ## [1.3.1] - Fix crash with new kubejs version diff --git a/gradle.properties b/gradle.properties index 144583c..13d6713 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ org.gradle.daemon=false # Mod data mod_id=ponderjs mod_name=PonderJS -mod_version=1.3.1 +mod_version=1.4.0 mod_base_package=com.almostreliable mod_authors=kotakotik22, AlmostReliable mod_description=Allows creating ponder scenes and tags with KubeJS. diff --git a/src/main/java/com/almostreliable/ponderjs/api/CustomPonderOverlayElement.java b/src/main/java/com/almostreliable/ponderjs/api/CustomPonderOverlayElement.java new file mode 100644 index 0000000..833e72b --- /dev/null +++ b/src/main/java/com/almostreliable/ponderjs/api/CustomPonderOverlayElement.java @@ -0,0 +1,66 @@ +package com.almostreliable.ponderjs.api; + +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.element.AnimatedOverlayElement; +import com.simibubi.create.foundation.ponder.ui.PonderUI; +import dev.latvian.mods.rhino.util.HideFromJS; +import net.minecraft.client.gui.GuiGraphics; + +public class CustomPonderOverlayElement extends AnimatedOverlayElement { + protected OnRenderOverlay onRender = (ctx) -> {}; + protected OnElementAction onWhileSkipping = (ctx) -> {}; + protected OnElementAction onTick = (ctx) -> {}; + protected OnElementAction onReset = (ctx) -> {}; + private int currentTick = 0; + + public int getCurrentTick() { + return currentTick; + } + + public CustomPonderOverlayElement onSkipping(OnElementAction onWhileSkipping) { + this.onWhileSkipping = onWhileSkipping; + return this; + } + + public CustomPonderOverlayElement onTick(OnElementAction onTick) { + this.onTick = onTick; + return this; + } + + public CustomPonderOverlayElement onReset(OnElementAction onReset) { + this.onReset = onReset; + return this; + } + + public CustomPonderOverlayElement onRender(OnRenderOverlay onRender) { + this.onRender = onRender; + return this; + } + + @Override + public void whileSkipping(PonderScene scene) { + super.whileSkipping(scene); + onWhileSkipping.accept(new OnElementAction.Context(this, scene)); + } + + @Override + public void tick(PonderScene scene) { + super.tick(scene); + currentTick++; + onTick.accept(new OnElementAction.Context(this, scene)); + } + + @Override + public void reset(PonderScene scene) { + super.reset(scene); + currentTick = 0; + onReset.accept(new OnElementAction.Context(this, scene)); + } + + @HideFromJS + @Override + protected void render(PonderScene scene, PonderUI screen, GuiGraphics graphics, float partialTicks, float fade) { + var ctx = new OnRenderOverlay.RenderContext(this, scene, screen, graphics, partialTicks, fade); + onRender.render(ctx); + } +} diff --git a/src/main/java/com/almostreliable/ponderjs/api/CustomPonderSceneElement.java b/src/main/java/com/almostreliable/ponderjs/api/CustomPonderSceneElement.java new file mode 100644 index 0000000..37bb453 --- /dev/null +++ b/src/main/java/com/almostreliable/ponderjs/api/CustomPonderSceneElement.java @@ -0,0 +1,97 @@ +package com.almostreliable.ponderjs.api; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.PonderWorld; +import com.simibubi.create.foundation.ponder.element.AnimatedSceneElement; +import dev.latvian.mods.rhino.util.HideFromJS; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; + +public class CustomPonderSceneElement extends AnimatedSceneElement { + protected OnRenderWorld onRenderFirst = (ctx) -> {}; + protected OnRenderWorld.Layer onRenderWorldLayer = (ctx) -> {}; + protected OnRenderWorld onRenderLast = (ctx) -> {}; + protected OnElementAction onWhileSkipping = (ctx) -> {}; + protected OnElementAction onTick = (ctx) -> {}; + protected OnElementAction onReset = (ctx) -> {}; + private int currentTick = 0; + + public int getCurrentTick() { + return currentTick; + } + + public CustomPonderSceneElement onSkipping(OnElementAction onWhileSkipping) { + this.onWhileSkipping = onWhileSkipping; + return this; + } + + public CustomPonderSceneElement onTick(OnElementAction onTick) { + this.onTick = onTick; + return this; + } + + public CustomPonderSceneElement onReset(OnElementAction onReset) { + this.onReset = onReset; + return this; + } + + public CustomPonderSceneElement onRenderFirst(OnRenderWorld onRenderWorld) { + this.onRenderFirst = onRenderWorld; + return this; + } + + public CustomPonderSceneElement onRender(OnRenderWorld.Layer onRenderWorldLayer) { + this.onRenderWorldLayer = onRenderWorldLayer; + return this; + } + + public CustomPonderSceneElement onRenderLast(OnRenderWorld onRenderWorld) { + this.onRenderLast = onRenderWorld; + return this; + } + + @Override + public void whileSkipping(PonderScene scene) { + super.whileSkipping(scene); + onWhileSkipping.accept(new OnElementAction.Context(this, scene)); + } + + @Override + public void tick(PonderScene scene) { + super.tick(scene); + currentTick++; + onTick.accept(new OnElementAction.Context(this, scene)); + } + + @Override + public void reset(PonderScene scene) { + super.reset(scene); + currentTick = 0; + onReset.accept(new OnElementAction.Context(this, scene)); + } + + @HideFromJS + @Override + public void renderFirst(PonderWorld world, MultiBufferSource buffer, PoseStack ms, float fade, float pt) { + super.renderFirst(world, buffer, ms, fade, pt); + var ctx = new OnRenderWorld.RenderContext(this, world, buffer, ms, pt, fade); + onRenderFirst.renderWorld(ctx); + } + + @HideFromJS + @Override + public void renderLayer(PonderWorld world, MultiBufferSource buffer, RenderType type, PoseStack ms, float fade, float pt) { + super.renderLayer(world, buffer, type, ms, fade, pt); + var ctx = new OnRenderWorld.Layer.RenderContext(this, world, buffer, type, ms, pt, fade); + onRenderWorldLayer.renderLayer(ctx); + } + + @HideFromJS + @Override + public void renderLast(PonderWorld world, MultiBufferSource buffer, PoseStack ms, float fade, float pt) { + super.renderLast(world, buffer, ms, fade, pt); + var ctx = new OnRenderWorld.RenderContext(this, world, buffer, ms, pt, fade); + onRenderLast.renderWorld(ctx); + } +} diff --git a/src/main/java/com/almostreliable/ponderjs/api/ExtendedSceneBuilder.java b/src/main/java/com/almostreliable/ponderjs/api/ExtendedSceneBuilder.java index 130b4f4..c3e7a4a 100644 --- a/src/main/java/com/almostreliable/ponderjs/api/ExtendedSceneBuilder.java +++ b/src/main/java/com/almostreliable/ponderjs/api/ExtendedSceneBuilder.java @@ -9,7 +9,9 @@ import com.simibubi.create.foundation.ponder.element.EntityElement; import com.simibubi.create.foundation.ponder.element.InputWindowElement; import com.simibubi.create.foundation.ponder.element.TextWindowElement; +import com.simibubi.create.foundation.ponder.instruction.FadeInOutInstruction; import com.simibubi.create.foundation.ponder.instruction.ShowInputInstruction; +import com.simibubi.create.foundation.ponder.instruction.TickingInstruction; import com.simibubi.create.foundation.utility.Pointing; import dev.latvian.mods.kubejs.util.ConsoleJS; import dev.latvian.mods.rhino.util.HideFromJS; @@ -42,6 +44,7 @@ public ExtendedSceneBuilder(PonderScene ponderScene) { this.ponderScene = ponderScene; ((SceneBuilderAccessor) this).ponderjs$setWorldInstructions(new ExtendedWorldInstructions()); ((SceneBuilderAccessor) this).ponderjs$setSpecialInstructions(new ExtendedSpecialInstructions()); + ((SceneBuilderAccessor) this).ponderjs$setOverlayInstructions(new ExtendedOverlayInstructions()); this.particles = new ParticleInstructions(this); } @@ -141,7 +144,67 @@ public InputWindowElement showControls(int duration, Vec3 pos, Pointing pointing return element; } + public class ExtendedOverlayInstructions extends OverlayInstructions { + + public CustomPonderOverlayElement addElement(int ticks) { + var element = new CustomPonderOverlayElement(); + addInstruction(new TickingInstruction(false, ticks) { + @Override + protected void firstTick(PonderScene scene) { + super.firstTick(scene); + scene.addElement(element); + } + }); + + return element; + } + + public CustomPonderOverlayElement addElement() { + var element = new CustomPonderOverlayElement(); + addInstruction(ponderScene -> { + ponderScene.addElement(element); + }); + + return element; + } + } + public class ExtendedWorldInstructions extends WorldInstructions { + + public CustomPonderSceneElement addElement(int ticks) { + var element = new CustomPonderSceneElement(); + element.setVisible(false); + addInstruction(new FadeInOutInstruction(ticks) { + @Override + protected void show(PonderScene scene) { + scene.addElement(element); + element.setVisible(true); + } + + @Override + protected void hide(PonderScene scene) { + element.setVisible(false); + } + + @Override + protected void applyFade(PonderScene scene, float fade) { + element.setFade(fade); + } + }); + + return element; + } + + public CustomPonderSceneElement addElement() { + var element = new CustomPonderSceneElement(); + addInstruction(ponderScene -> { + ponderScene.addElement(element); + element.setVisible(true); + }); + + return element; + } + /** * Create a new entity with some default behavior. The entity will be rotated to face north. * diff --git a/src/main/java/com/almostreliable/ponderjs/api/OnElementAction.java b/src/main/java/com/almostreliable/ponderjs/api/OnElementAction.java new file mode 100644 index 0000000..2dcdd1d --- /dev/null +++ b/src/main/java/com/almostreliable/ponderjs/api/OnElementAction.java @@ -0,0 +1,12 @@ +package com.almostreliable.ponderjs.api; + +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.element.PonderElement; + +@FunctionalInterface +public interface OnElementAction { + + void accept(Context context); + + record Context(PonderElement getElement, PonderScene getScene) {} +} diff --git a/src/main/java/com/almostreliable/ponderjs/api/OnRenderOverlay.java b/src/main/java/com/almostreliable/ponderjs/api/OnRenderOverlay.java new file mode 100644 index 0000000..dc7c55b --- /dev/null +++ b/src/main/java/com/almostreliable/ponderjs/api/OnRenderOverlay.java @@ -0,0 +1,15 @@ +package com.almostreliable.ponderjs.api; + +import com.simibubi.create.foundation.ponder.PonderScene; +import com.simibubi.create.foundation.ponder.element.PonderOverlayElement; +import com.simibubi.create.foundation.ponder.ui.PonderUI; +import net.minecraft.client.gui.GuiGraphics; + +@FunctionalInterface +public interface OnRenderOverlay { + + void render(RenderContext context); + + record RenderContext(PonderOverlayElement getElement, PonderScene getScene, PonderUI getScreen, + GuiGraphics getGraphics, float getPartialTicks, float getFade) {} +} diff --git a/src/main/java/com/almostreliable/ponderjs/api/OnRenderWorld.java b/src/main/java/com/almostreliable/ponderjs/api/OnRenderWorld.java new file mode 100644 index 0000000..99ba7fe --- /dev/null +++ b/src/main/java/com/almostreliable/ponderjs/api/OnRenderWorld.java @@ -0,0 +1,25 @@ +package com.almostreliable.ponderjs.api; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.simibubi.create.foundation.ponder.PonderWorld; +import com.simibubi.create.foundation.ponder.element.PonderElement; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; + +@FunctionalInterface +public interface OnRenderWorld { + + void renderWorld(RenderContext context); + + @FunctionalInterface + interface Layer { + void renderLayer(RenderContext context); + + record RenderContext(PonderElement getElement, PonderWorld getWorld, MultiBufferSource getBuffer, + RenderType getType, PoseStack getPoseStack, float getPartialTicks, float getFade) {} + } + + + record RenderContext(PonderElement getElement, PonderWorld getWorld, MultiBufferSource getBuffer, + PoseStack getPoseStack, float getPartialTicks, float getFade) {} +} diff --git a/src/main/java/com/almostreliable/ponderjs/mixin/SceneBuilderAccessor.java b/src/main/java/com/almostreliable/ponderjs/mixin/SceneBuilderAccessor.java index abdd78f..84240fe 100644 --- a/src/main/java/com/almostreliable/ponderjs/mixin/SceneBuilderAccessor.java +++ b/src/main/java/com/almostreliable/ponderjs/mixin/SceneBuilderAccessor.java @@ -18,4 +18,8 @@ public interface SceneBuilderAccessor { @Accessor(value = "special", remap = false) @Mutable void ponderjs$setSpecialInstructions(SceneBuilder.SpecialInstructions specialInstructions); + + @Accessor(value = "overlay", remap = false) + @Mutable + void ponderjs$setOverlayInstructions(SceneBuilder.OverlayInstructions overlayInstructions); }