From e0a177adbea5213c662347bc3f050ad7eb659a37 Mon Sep 17 00:00:00 2001 From: Pyrofab Date: Mon, 20 May 2024 19:09:32 +0200 Subject: [PATCH] Split the mod into common and client sourcesets --- build.gradle | 33 ++++- .../api/client/BlabberDialogueScreen.java | 40 ++++-- .../api/client/BlabberScreenRegistry.java | 0 .../DialogueIllustrationRenderer.java | 54 ++++++++ .../blabber/impl/client/BlabberClient.java | 35 +++++- .../impl/client/BlabberRpgDialogueScreen.java | 0 .../compat/BlabberClientMixinPlugin.java} | 6 +- .../client}/compat/BlabberOverlayDecider.java | 2 +- .../compat/BlabberReiClientPlugin.java | 2 +- .../impl/client}/compat/package-info.java | 2 +- .../EntityIllustrationRenderer.java | 72 +++++++++++ .../FakePlayerIllustrationRenderer.java | 53 ++++++++ .../IllustrationCollectionRenderer.java | 48 +++++++ .../ItemIllustrationRenderer.java | 59 +++++++++ .../NbtEntityIllustrationRenderer.java | 46 +++++++ .../SelectedEntityIllustrationRenderer.java | 34 +++++ .../TextureIllustrationRenderer.java | 47 +++++++ .../blabber/impl/client/package-info.java | 0 .../AbstractClientPlayerEntityAccessor.java | 0 .../impl/mixin/client/DrawContextMixin.java | 4 +- .../compat/emi/EmiScreenManagerMixin.java | 2 +- .../client}/compat/emi/package-info.java | 2 +- .../resources/assets/blabber/lang/en_us.json | 0 .../resources/assets/blabber/lang/fr_fr.json | 0 .../resources/assets/blabber/lang/nl_nl.json | 0 .../resources/assets/blabber/lang/pt_br.json | 0 .../resources/assets/blabber/lang/ro_ro.json | 0 .../resources/assets/blabber/lang/ru_ru.json | 0 .../resources/assets/blabber/lang/uk_ua.json | 0 .../resources/assets/blabber/lang/zh_cn.json | 0 .../container/dialogue/dialogue_arrow_1.png | Bin .../container/dialogue/dialogue_arrow_2.png | Bin .../container/dialogue/dialogue_arrow_3.png | Bin .../container/dialogue/dialogue_arrow_4.png | Bin .../container/dialogue/dialogue_arrow_5.png | Bin .../container/dialogue/dialogue_lock_1.png | Bin .../container/dialogue/dialogue_lock_2.png | Bin .../container/dialogue/dialogue_lock_3.png | Bin .../resources/blabber.client.mixins.json | 15 +++ .../illustration/DialogueIllustration.java | 15 --- .../impl/common/DialogueScreenHandler.java | 12 +- .../DialogueIllustrationCollection.java | 9 -- .../DialogueIllustrationItem.java | 27 ---- .../DialogueIllustrationTexture.java | 19 --- .../entity/DialogueIllustrationEntity.java | 94 +------------- .../DialogueIllustrationFakePlayer.java | 113 ++++++----------- .../entity/DialogueIllustrationNbtEntity.java | 119 +++++++----------- .../DialogueIllustrationSelectorEntity.java | 54 +++++++- .../common/machine/DialogueStateMachine.java | 5 +- .../settings/BlabberSettingsComponent.java | 1 - .../impl/mixin/EntitySelectorReaderMixin.java | 2 +- src/main/resources/blabber.mixins.json | 8 +- src/main/resources/fabric.mod.json | 8 +- .../babblings/tests/BlabberTestSuite.java | 7 +- 54 files changed, 681 insertions(+), 368 deletions(-) rename src/{main => client}/java/org/ladysnake/blabber/api/client/BlabberDialogueScreen.java (90%) rename src/{main => client}/java/org/ladysnake/blabber/api/client/BlabberScreenRegistry.java (100%) create mode 100644 src/client/java/org/ladysnake/blabber/api/client/illustration/DialogueIllustrationRenderer.java rename src/{main => client}/java/org/ladysnake/blabber/impl/client/BlabberClient.java (63%) rename src/{main => client}/java/org/ladysnake/blabber/impl/client/BlabberRpgDialogueScreen.java (100%) rename src/{main/java/org/ladysnake/blabber/impl/compat/BlabberMixinPlugin.java => client/java/org/ladysnake/blabber/impl/client/compat/BlabberClientMixinPlugin.java} (94%) rename src/{main/java/org/ladysnake/blabber/impl => client/java/org/ladysnake/blabber/impl/client}/compat/BlabberOverlayDecider.java (96%) rename src/{main/java/org/ladysnake/blabber/impl => client/java/org/ladysnake/blabber/impl/client}/compat/BlabberReiClientPlugin.java (95%) rename src/{main/java/org/ladysnake/blabber/impl => client/java/org/ladysnake/blabber/impl/client}/compat/package-info.java (95%) create mode 100644 src/client/java/org/ladysnake/blabber/impl/client/illustrations/EntityIllustrationRenderer.java create mode 100644 src/client/java/org/ladysnake/blabber/impl/client/illustrations/FakePlayerIllustrationRenderer.java create mode 100644 src/client/java/org/ladysnake/blabber/impl/client/illustrations/IllustrationCollectionRenderer.java create mode 100644 src/client/java/org/ladysnake/blabber/impl/client/illustrations/ItemIllustrationRenderer.java create mode 100644 src/client/java/org/ladysnake/blabber/impl/client/illustrations/NbtEntityIllustrationRenderer.java create mode 100644 src/client/java/org/ladysnake/blabber/impl/client/illustrations/SelectedEntityIllustrationRenderer.java create mode 100644 src/client/java/org/ladysnake/blabber/impl/client/illustrations/TextureIllustrationRenderer.java rename src/{main => client}/java/org/ladysnake/blabber/impl/client/package-info.java (100%) rename src/{main => client}/java/org/ladysnake/blabber/impl/mixin/client/AbstractClientPlayerEntityAccessor.java (100%) rename src/{main => client}/java/org/ladysnake/blabber/impl/mixin/client/DrawContextMixin.java (91%) rename src/{main/java/org/ladysnake/blabber/impl/mixin => client/java/org/ladysnake/blabber/impl/mixin/client}/compat/emi/EmiScreenManagerMixin.java (96%) rename src/{main/java/org/ladysnake/blabber/impl/mixin => client/java/org/ladysnake/blabber/impl/mixin/client}/compat/emi/package-info.java (94%) rename src/{main => client}/resources/assets/blabber/lang/en_us.json (100%) rename src/{main => client}/resources/assets/blabber/lang/fr_fr.json (100%) rename src/{main => client}/resources/assets/blabber/lang/nl_nl.json (100%) rename src/{main => client}/resources/assets/blabber/lang/pt_br.json (100%) rename src/{main => client}/resources/assets/blabber/lang/ro_ro.json (100%) rename src/{main => client}/resources/assets/blabber/lang/ru_ru.json (100%) rename src/{main => client}/resources/assets/blabber/lang/uk_ua.json (100%) rename src/{main => client}/resources/assets/blabber/lang/zh_cn.json (100%) rename src/{main => client}/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_1.png (100%) rename src/{main => client}/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_2.png (100%) rename src/{main => client}/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_3.png (100%) rename src/{main => client}/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_4.png (100%) rename src/{main => client}/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_5.png (100%) rename src/{main => client}/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_lock_1.png (100%) rename src/{main => client}/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_lock_2.png (100%) rename src/{main => client}/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_lock_3.png (100%) create mode 100644 src/client/resources/blabber.client.mixins.json diff --git a/build.gradle b/build.gradle index 56ca001..f528b23 100644 --- a/build.gradle +++ b/build.gradle @@ -5,10 +5,13 @@ plugins { id 'io.github.ladysnake.chenille' version '0.12.2' } -archivesBaseName = project.archives_base_name version = project.mod_version group = project.maven_group +base { + archivesName = project.archives_base_name +} + chenille { configureTestmod { withBaseTestRuns() @@ -19,8 +22,30 @@ chenille { javaVersion = project.java_version.toInteger() } +java { + withSourcesJar() +} + +loom { + splitEnvironmentSourceSets() + + mods { + "blabber" { + sourceSet sourceSets.main + sourceSet sourceSets.client + } + "babblings" { + sourceSet sourceSets.testmod + } + } +} + sourceSets { reiDummy + testmod { + compileClasspath += client.compileClasspath + runtimeClasspath += client.runtimeClasspath + } } repositories { @@ -35,6 +60,8 @@ repositories { } dependencies { + testmodImplementation(sourceSets.client.output) + // To change the versions see the gradle.properties file minecraft "com.mojang:minecraft:${project.minecraft_version}" mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2" @@ -83,10 +110,6 @@ processResources { } } -java { - withSourcesJar() -} - jar { from("COPYING.LESSER") { rename { "LICENSE_${project.archivesBaseName}"} diff --git a/src/main/java/org/ladysnake/blabber/api/client/BlabberDialogueScreen.java b/src/client/java/org/ladysnake/blabber/api/client/BlabberDialogueScreen.java similarity index 90% rename from src/main/java/org/ladysnake/blabber/api/client/BlabberDialogueScreen.java rename to src/client/java/org/ladysnake/blabber/api/client/BlabberDialogueScreen.java index 1a13e4e..930330d 100644 --- a/src/main/java/org/ladysnake/blabber/api/client/BlabberDialogueScreen.java +++ b/src/client/java/org/ladysnake/blabber/api/client/BlabberDialogueScreen.java @@ -33,8 +33,9 @@ import org.jetbrains.annotations.Nullable; import org.joml.Vector2i; import org.ladysnake.blabber.Blabber; -import org.ladysnake.blabber.api.illustration.DialogueIllustration; +import org.ladysnake.blabber.api.client.illustration.DialogueIllustrationRenderer; import org.ladysnake.blabber.api.layout.DialogueLayout; +import org.ladysnake.blabber.impl.client.BlabberClient; import org.ladysnake.blabber.impl.common.DialogueScreenHandler; import org.ladysnake.blabber.impl.common.illustrations.PositionTransform; import org.ladysnake.blabber.impl.common.machine.AvailableChoice; @@ -45,7 +46,9 @@ import org.lwjgl.glfw.GLFW; import java.util.EnumMap; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.stream.IntStream; @ApiStatus.Experimental // half internal, expect some things to change @@ -112,6 +115,8 @@ public class BlabberDialogueScreen

extends Hand protected int selectedChoice; protected boolean hoveringChoice; + protected Map> illustrations = new HashMap<>(); + public BlabberDialogueScreen(DialogueScreenHandler handler, PlayerInventory inventory, Text title) { super(handler, inventory, title); GameOptions options = MinecraftClient.getInstance().options; @@ -130,10 +135,12 @@ protected P params() { @Override protected void init() { super.init(); - this.layout(); + this.prepareLayout(); + this.illustrations.clear(); + this.handler.getIllustrations().forEach((key, illustration) -> this.illustrations.put(key, BlabberClient.createRenderer(illustration))); } - protected void layout() { + protected void prepareLayout() { this.computeMargins(); this.layoutIllustrationAnchors(); } @@ -186,7 +193,7 @@ public boolean keyPressed(int key, int scancode, int modifiers) { return null; } - ChoiceResult result = this.handler.makeChoice(selectedChoice); + ChoiceResult result = this.makeChoice(selectedChoice); switch (result) { case END_DIALOGUE -> this.client.setScreen(null); @@ -203,7 +210,7 @@ public boolean keyPressed(int key, int scancode, int modifiers) { default -> { this.selectedChoice = 0; this.hoveringChoice = false; - this.layout(); + this.prepareLayout(); } } @@ -265,10 +272,7 @@ public void render(DrawContext context, int mouseX, int mouseY, float tickDelta) int y = mainTextMinY; for (String illustrationName : this.handler.getCurrentIllustrations()) { - DialogueIllustration illustration = this.handler.getIllustration(illustrationName); - if (illustration != null) { - illustration.render(context, this.textRenderer, positionTransform, mouseX, mouseY, tickDelta); - } + this.getIllustrationRenderer(illustrationName).render(context, this.textRenderer, positionTransform, mouseX, mouseY, tickDelta); } Text mainText = this.handler.getCurrentText(); @@ -287,10 +291,7 @@ public void render(DrawContext context, int mouseX, int mouseY, float tickDelta) positionTransform.setControlPoints(choiceListMinX, y, choiceListMinX + choiceListMaxWidth, y + strHeight); for (String illustrationName : choice.illustrations()) { - DialogueIllustration illustration = this.handler.getIllustration(illustrationName); - if (illustration != null) { - illustration.render(context, this.textRenderer, positionTransform, mouseX, mouseY, tickDelta); - } + this.getIllustrationRenderer(illustrationName).render(context, this.textRenderer, positionTransform, mouseX, mouseY, tickDelta); } if (selected) { @@ -313,6 +314,12 @@ public void render(DrawContext context, int mouseX, int mouseY, float tickDelta) } } + private DialogueIllustrationRenderer getIllustrationRenderer(String illustrationName) { + DialogueIllustrationRenderer renderer = this.illustrations.get(illustrationName); + if (renderer == null) throw new IllegalArgumentException("Unknown illustration " + illustrationName); + return renderer; + } + protected @NotNull PositionTransform createPositionTransform() { return new PositionTransform(this.illustrationSlots); } @@ -355,4 +362,11 @@ protected void drawBackground(DrawContext matrices, float delta, int mouseX, int protected void drawForeground(DrawContext matrices, int mouseX, int mouseY) { // NO-OP } + + public ChoiceResult makeChoice(int choice) { + int originalChoiceIndex = this.handler.getAvailableChoices().get(choice).originalChoiceIndex(); + ChoiceResult result = this.handler.makeChoice(originalChoiceIndex); + BlabberClient.sendDialogueActionMessage(originalChoiceIndex); + return result; + } } diff --git a/src/main/java/org/ladysnake/blabber/api/client/BlabberScreenRegistry.java b/src/client/java/org/ladysnake/blabber/api/client/BlabberScreenRegistry.java similarity index 100% rename from src/main/java/org/ladysnake/blabber/api/client/BlabberScreenRegistry.java rename to src/client/java/org/ladysnake/blabber/api/client/BlabberScreenRegistry.java diff --git a/src/client/java/org/ladysnake/blabber/api/client/illustration/DialogueIllustrationRenderer.java b/src/client/java/org/ladysnake/blabber/api/client/illustration/DialogueIllustrationRenderer.java new file mode 100644 index 0000000..4eb1c85 --- /dev/null +++ b/src/client/java/org/ladysnake/blabber/api/client/illustration/DialogueIllustrationRenderer.java @@ -0,0 +1,54 @@ +/* + * Blabber + * Copyright (C) 2022-2024 Ladysnake + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; If not, see . + */ +package org.ladysnake.blabber.api.client.illustration; + +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; +import org.ladysnake.blabber.api.illustration.DialogueIllustration; +import org.ladysnake.blabber.api.illustration.DialogueIllustrationType; +import org.ladysnake.blabber.impl.client.BlabberClient; +import org.ladysnake.blabber.impl.common.illustrations.PositionTransform; + +public abstract class DialogueIllustrationRenderer { + public static void register(DialogueIllustrationType type, DialogueIllustrationRenderer.Factory factory) { + BlabberClient.registerIllustrationRenderer(type, factory); + } + + protected final I illustration; + + public DialogueIllustrationRenderer(I illustration) { + this.illustration = illustration; + } + + /** + * Draw this illustration to the screen. + * + * @param context a context to draw in + * @param textRenderer a text renderer + * @param positionTransform an object that gives you real coordinates from illustration-local ones + * @param mouseX the current x mouse position + * @param mouseY the current y mouse position + * @param tickDelta how much time has passed since last frame + */ + public abstract void render(DrawContext context, TextRenderer textRenderer, PositionTransform positionTransform, int mouseX, int mouseY, float tickDelta); + + @FunctionalInterface + public interface Factory { + DialogueIllustrationRenderer create(I illustration); + } +} diff --git a/src/main/java/org/ladysnake/blabber/impl/client/BlabberClient.java b/src/client/java/org/ladysnake/blabber/impl/client/BlabberClient.java similarity index 63% rename from src/main/java/org/ladysnake/blabber/impl/client/BlabberClient.java rename to src/client/java/org/ladysnake/blabber/impl/client/BlabberClient.java index 5b02f71..e031665 100644 --- a/src/main/java/org/ladysnake/blabber/impl/client/BlabberClient.java +++ b/src/client/java/org/ladysnake/blabber/impl/client/BlabberClient.java @@ -27,25 +27,47 @@ import org.ladysnake.blabber.Blabber; import org.ladysnake.blabber.api.client.BlabberDialogueScreen; import org.ladysnake.blabber.api.client.BlabberScreenRegistry; +import org.ladysnake.blabber.api.client.illustration.DialogueIllustrationRenderer; +import org.ladysnake.blabber.api.illustration.DialogueIllustration; +import org.ladysnake.blabber.api.illustration.DialogueIllustrationType; import org.ladysnake.blabber.api.layout.DialogueLayout; import org.ladysnake.blabber.api.layout.DialogueLayoutType; +import org.ladysnake.blabber.impl.client.illustrations.FakePlayerIllustrationRenderer; +import org.ladysnake.blabber.impl.client.illustrations.IllustrationCollectionRenderer; +import org.ladysnake.blabber.impl.client.illustrations.ItemIllustrationRenderer; +import org.ladysnake.blabber.impl.client.illustrations.NbtEntityIllustrationRenderer; +import org.ladysnake.blabber.impl.client.illustrations.SelectedEntityIllustrationRenderer; +import org.ladysnake.blabber.impl.client.illustrations.TextureIllustrationRenderer; import org.ladysnake.blabber.impl.common.BlabberRegistrar; import org.ladysnake.blabber.impl.common.DialogueRegistry; import org.ladysnake.blabber.impl.common.DialogueScreenHandler; +import org.ladysnake.blabber.impl.common.illustrations.DialogueIllustrationCollection; +import org.ladysnake.blabber.impl.common.illustrations.DialogueIllustrationItem; +import org.ladysnake.blabber.impl.common.illustrations.DialogueIllustrationTexture; +import org.ladysnake.blabber.impl.common.illustrations.entity.DialogueIllustrationFakePlayer; +import org.ladysnake.blabber.impl.common.illustrations.entity.DialogueIllustrationNbtEntity; +import org.ladysnake.blabber.impl.common.illustrations.entity.DialogueIllustrationSelectorEntity; import org.ladysnake.blabber.impl.common.packets.ChoiceAvailabilityPacket; import org.ladysnake.blabber.impl.common.packets.DialogueListPacket; import org.ladysnake.blabber.impl.common.packets.SelectedDialogueStatePacket; -import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.Map; import static io.netty.buffer.Unpooled.buffer; public final class BlabberClient implements ClientModInitializer { - private static final Map, HandledScreens.Provider> screenRegistry = new HashMap<>(); + private static final Map, HandledScreens.Provider> screenRegistry = new LinkedHashMap<>(); + private static final Map, DialogueIllustrationRenderer.Factory> illustrationRenderers = new LinkedHashMap<>(); @Override public void onInitializeClient() { + DialogueIllustrationRenderer.register(DialogueIllustrationCollection.TYPE, IllustrationCollectionRenderer::new); + DialogueIllustrationRenderer.register(DialogueIllustrationItem.TYPE, ItemIllustrationRenderer::new); + DialogueIllustrationRenderer.register(DialogueIllustrationNbtEntity.TYPE, NbtEntityIllustrationRenderer::new); + DialogueIllustrationRenderer.register(DialogueIllustrationFakePlayer.TYPE, FakePlayerIllustrationRenderer::new); + DialogueIllustrationRenderer.register(DialogueIllustrationSelectorEntity.TYPE, SelectedEntityIllustrationRenderer::new); + DialogueIllustrationRenderer.register(DialogueIllustrationTexture.TYPE, TextureIllustrationRenderer::new); BlabberScreenRegistry.register(BlabberRegistrar.CLASSIC_LAYOUT, BlabberDialogueScreen::new); BlabberScreenRegistry.register(BlabberRegistrar.RPG_LAYOUT, BlabberRpgDialogueScreen::new); HandledScreens.register(BlabberRegistrar.DIALOGUE_SCREEN_HANDLER, (HandledScreens.Provider>) BlabberClient::createDialogueScreen); @@ -70,6 +92,15 @@ public static

void registerLayoutScreen( screenRegistry.put(layoutId, screenProvider); } + public static void registerIllustrationRenderer(DialogueIllustrationType type, DialogueIllustrationRenderer.Factory rendererFactory) { + illustrationRenderers.put(type, rendererFactory); + } + + public static DialogueIllustrationRenderer createRenderer(I illustration) { + @SuppressWarnings("unchecked") DialogueIllustrationRenderer.Factory renderer = (DialogueIllustrationRenderer.Factory) illustrationRenderers.get(illustration.getType()); + return renderer.create(illustration); + } + private static

BlabberDialogueScreen

createDialogueScreen(DialogueScreenHandler handler, PlayerInventory inventory, Text title) { @SuppressWarnings("unchecked") DialogueLayoutType

layoutType = (DialogueLayoutType

) handler.getLayout().type(); @SuppressWarnings("unchecked") HandledScreens.Provider> provider = diff --git a/src/main/java/org/ladysnake/blabber/impl/client/BlabberRpgDialogueScreen.java b/src/client/java/org/ladysnake/blabber/impl/client/BlabberRpgDialogueScreen.java similarity index 100% rename from src/main/java/org/ladysnake/blabber/impl/client/BlabberRpgDialogueScreen.java rename to src/client/java/org/ladysnake/blabber/impl/client/BlabberRpgDialogueScreen.java diff --git a/src/main/java/org/ladysnake/blabber/impl/compat/BlabberMixinPlugin.java b/src/client/java/org/ladysnake/blabber/impl/client/compat/BlabberClientMixinPlugin.java similarity index 94% rename from src/main/java/org/ladysnake/blabber/impl/compat/BlabberMixinPlugin.java rename to src/client/java/org/ladysnake/blabber/impl/client/compat/BlabberClientMixinPlugin.java index b0e1711..bf08279 100644 --- a/src/main/java/org/ladysnake/blabber/impl/compat/BlabberMixinPlugin.java +++ b/src/client/java/org/ladysnake/blabber/impl/client/compat/BlabberClientMixinPlugin.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program; If not, see . */ -package org.ladysnake.blabber.impl.compat; +package org.ladysnake.blabber.impl.client.compat; import net.fabricmc.loader.api.FabricLoader; import org.jetbrains.annotations.Nullable; @@ -28,8 +28,8 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -public class BlabberMixinPlugin implements IMixinConfigPlugin { - private static final String COMPAT_PREFIX = "org.ladysnake.blabber.mixin.compat."; +public class BlabberClientMixinPlugin implements IMixinConfigPlugin { + private static final String COMPAT_PREFIX = "org.ladysnake.blabber.mixin.client.compat."; private static final Pattern COMPAT_MIXIN_PATTERN = Pattern.compile(Pattern.quote(COMPAT_PREFIX) + "(?[a-z_]+?)\\..*"); private final FabricLoader loader = FabricLoader.getInstance(); diff --git a/src/main/java/org/ladysnake/blabber/impl/compat/BlabberOverlayDecider.java b/src/client/java/org/ladysnake/blabber/impl/client/compat/BlabberOverlayDecider.java similarity index 96% rename from src/main/java/org/ladysnake/blabber/impl/compat/BlabberOverlayDecider.java rename to src/client/java/org/ladysnake/blabber/impl/client/compat/BlabberOverlayDecider.java index 9c5d035..58dbf42 100644 --- a/src/main/java/org/ladysnake/blabber/impl/compat/BlabberOverlayDecider.java +++ b/src/client/java/org/ladysnake/blabber/impl/client/compat/BlabberOverlayDecider.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program; If not, see . */ -package org.ladysnake.blabber.impl.compat; +package org.ladysnake.blabber.impl.client.compat; import me.shedaniel.rei.api.client.registry.screen.OverlayDecider; import net.minecraft.client.gui.screen.Screen; diff --git a/src/main/java/org/ladysnake/blabber/impl/compat/BlabberReiClientPlugin.java b/src/client/java/org/ladysnake/blabber/impl/client/compat/BlabberReiClientPlugin.java similarity index 95% rename from src/main/java/org/ladysnake/blabber/impl/compat/BlabberReiClientPlugin.java rename to src/client/java/org/ladysnake/blabber/impl/client/compat/BlabberReiClientPlugin.java index f897a69..df63bca 100644 --- a/src/main/java/org/ladysnake/blabber/impl/compat/BlabberReiClientPlugin.java +++ b/src/client/java/org/ladysnake/blabber/impl/client/compat/BlabberReiClientPlugin.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program; If not, see . */ -package org.ladysnake.blabber.impl.compat; +package org.ladysnake.blabber.impl.client.compat; import me.shedaniel.rei.api.client.plugins.REIClientPlugin; import me.shedaniel.rei.api.client.registry.screen.ScreenRegistry; diff --git a/src/main/java/org/ladysnake/blabber/impl/compat/package-info.java b/src/client/java/org/ladysnake/blabber/impl/client/compat/package-info.java similarity index 95% rename from src/main/java/org/ladysnake/blabber/impl/compat/package-info.java rename to src/client/java/org/ladysnake/blabber/impl/client/compat/package-info.java index 0c63c1b..3dc2d1e 100644 --- a/src/main/java/org/ladysnake/blabber/impl/compat/package-info.java +++ b/src/client/java/org/ladysnake/blabber/impl/client/compat/package-info.java @@ -21,7 +21,7 @@ @FieldsAreNonnullByDefault @MethodsReturnNonnullByDefault @ApiStatus.Internal -package org.ladysnake.blabber.impl.compat; +package org.ladysnake.blabber.impl.client.compat; import net.minecraft.util.annotation.FieldsAreNonnullByDefault; import net.minecraft.util.annotation.MethodsReturnNonnullByDefault; diff --git a/src/client/java/org/ladysnake/blabber/impl/client/illustrations/EntityIllustrationRenderer.java b/src/client/java/org/ladysnake/blabber/impl/client/illustrations/EntityIllustrationRenderer.java new file mode 100644 index 0000000..4b4bdc6 --- /dev/null +++ b/src/client/java/org/ladysnake/blabber/impl/client/illustrations/EntityIllustrationRenderer.java @@ -0,0 +1,72 @@ +/* + * Blabber + * Copyright (C) 2022-2024 Ladysnake + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; If not, see . + */ +package org.ladysnake.blabber.impl.client.illustrations; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.ingame.InventoryScreen; +import net.minecraft.entity.LivingEntity; +import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; +import org.ladysnake.blabber.api.client.illustration.DialogueIllustrationRenderer; +import org.ladysnake.blabber.impl.common.illustrations.PositionTransform; +import org.ladysnake.blabber.impl.common.illustrations.entity.DialogueIllustrationEntity; +import org.ladysnake.blabber.impl.common.illustrations.entity.StareTarget; + +public abstract class EntityIllustrationRenderer extends DialogueIllustrationRenderer { + private @Nullable LivingEntity renderedEntity; + + public EntityIllustrationRenderer(I illustration) { + super(illustration); + } + + protected abstract @Nullable LivingEntity getRenderedEntity(World world); + + @Override + @Environment(EnvType.CLIENT) + public void render(DrawContext context, TextRenderer textRenderer, PositionTransform positionTransform, int mouseX, int mouseY, float tickDelta) { + LivingEntity e = this.renderedEntity == null + ? this.renderedEntity = this.getRenderedEntity(MinecraftClient.getInstance().world) + : this.renderedEntity; + + if (e == null) return; // Something went wrong creating the entity, so don't render. + + int x1 = illustration.minX(positionTransform); + int y1 = illustration.minY(positionTransform); + int x2 = illustration.maxX(positionTransform); + int y2 = illustration.maxY(positionTransform); + + StareTarget stareTarget = illustration.stareAt(); + int fakedMouseX = stareTarget.x().isPresent() ? stareTarget.anchor().isPresent() ? positionTransform.transformX(stareTarget.anchor().get(), stareTarget.x().getAsInt()) : stareTarget.x().getAsInt() + (x1 + x2) / 2 : mouseX; + int fakedMouseY = stareTarget.y().isPresent() ? stareTarget.anchor().isPresent() ? positionTransform.transformY(stareTarget.anchor().get(), stareTarget.y().getAsInt()) : stareTarget.y().getAsInt() + (y1 + y2) / 2 : mouseY; + + InventoryScreen.drawEntity(context, + x1, + y1, + x2, + y2, + illustration.entitySize(), + illustration.yOffset(), + fakedMouseX, + fakedMouseY, + e); + } +} diff --git a/src/client/java/org/ladysnake/blabber/impl/client/illustrations/FakePlayerIllustrationRenderer.java b/src/client/java/org/ladysnake/blabber/impl/client/illustrations/FakePlayerIllustrationRenderer.java new file mode 100644 index 0000000..3bc2164 --- /dev/null +++ b/src/client/java/org/ladysnake/blabber/impl/client/illustrations/FakePlayerIllustrationRenderer.java @@ -0,0 +1,53 @@ +/* + * Blabber + * Copyright (C) 2022-2024 Ladysnake + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; If not, see . + */ +package org.ladysnake.blabber.impl.client.illustrations; + +import com.mojang.authlib.GameProfile; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.network.OtherClientPlayerEntity; +import net.minecraft.client.network.PlayerListEntry; +import net.minecraft.client.world.ClientWorld; +import net.minecraft.entity.LivingEntity; +import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; +import org.ladysnake.blabber.impl.common.illustrations.entity.DialogueIllustrationFakePlayer; +import org.ladysnake.blabber.impl.mixin.PlayerEntityAccessor; +import org.ladysnake.blabber.impl.mixin.client.AbstractClientPlayerEntityAccessor; + +public class FakePlayerIllustrationRenderer extends EntityIllustrationRenderer { + public FakePlayerIllustrationRenderer(DialogueIllustrationFakePlayer illustration) { + super(illustration); + } + + @SuppressWarnings("UnreachableCode") + @Environment(EnvType.CLIENT) + @Override + protected @Nullable LivingEntity getRenderedEntity(World world) { + GameProfile profile = this.illustration.profile(); + OtherClientPlayerEntity fakePlayer = new OtherClientPlayerEntity((ClientWorld) world, profile); + this.illustration.data().ifPresent(fakePlayer::readNbt); + ((AbstractClientPlayerEntityAccessor) fakePlayer).setPlayerListEntry(new PlayerListEntry(profile, false)); + fakePlayer.prevBodyYaw = fakePlayer.bodyYaw = 0.0f; + fakePlayer.prevHeadYaw = fakePlayer.headYaw = 0.0f; + DialogueIllustrationFakePlayer.PlayerModelOptions playerModelOptions = this.illustration.modelOptionsOrDefault(); + fakePlayer.getDataTracker().set(PlayerEntityAccessor.getPlayerModelParts(), playerModelOptions.packVisibleParts()); + fakePlayer.setMainArm(playerModelOptions.mainHand()); + return fakePlayer; + } +} diff --git a/src/client/java/org/ladysnake/blabber/impl/client/illustrations/IllustrationCollectionRenderer.java b/src/client/java/org/ladysnake/blabber/impl/client/illustrations/IllustrationCollectionRenderer.java new file mode 100644 index 0000000..9fea71b --- /dev/null +++ b/src/client/java/org/ladysnake/blabber/impl/client/illustrations/IllustrationCollectionRenderer.java @@ -0,0 +1,48 @@ +/* + * Blabber + * Copyright (C) 2022-2024 Ladysnake + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; If not, see . + */ +package org.ladysnake.blabber.impl.client.illustrations; + +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; +import org.ladysnake.blabber.api.client.illustration.DialogueIllustrationRenderer; +import org.ladysnake.blabber.api.illustration.DialogueIllustration; +import org.ladysnake.blabber.impl.client.BlabberClient; +import org.ladysnake.blabber.impl.common.illustrations.DialogueIllustrationCollection; +import org.ladysnake.blabber.impl.common.illustrations.PositionTransform; + +import java.util.ArrayList; +import java.util.List; + +public class IllustrationCollectionRenderer extends DialogueIllustrationRenderer { + private final List> elements; + + public IllustrationCollectionRenderer(DialogueIllustrationCollection illustration) { + super(illustration); + this.elements = new ArrayList<>(); + for (DialogueIllustration element : illustration.elements()) { + this.elements.add(BlabberClient.createRenderer(element)); + } + } + + @Override + public void render(DrawContext context, TextRenderer textRenderer, PositionTransform positionTransform, int mouseX, int mouseY, float tickDelta) { + for (DialogueIllustrationRenderer i : elements) { + i.render(context, textRenderer, positionTransform, mouseX, mouseY, tickDelta); + } + } +} diff --git a/src/client/java/org/ladysnake/blabber/impl/client/illustrations/ItemIllustrationRenderer.java b/src/client/java/org/ladysnake/blabber/impl/client/illustrations/ItemIllustrationRenderer.java new file mode 100644 index 0000000..7cfe3aa --- /dev/null +++ b/src/client/java/org/ladysnake/blabber/impl/client/illustrations/ItemIllustrationRenderer.java @@ -0,0 +1,59 @@ +/* + * Blabber + * Copyright (C) 2022-2024 Ladysnake + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; If not, see . + */ +package org.ladysnake.blabber.impl.client.illustrations; + +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.item.ItemStack; +import org.ladysnake.blabber.api.client.illustration.DialogueIllustrationRenderer; +import org.ladysnake.blabber.impl.common.illustrations.DialogueIllustrationItem; +import org.ladysnake.blabber.impl.common.illustrations.PositionTransform; + +public class ItemIllustrationRenderer extends DialogueIllustrationRenderer { + public ItemIllustrationRenderer(DialogueIllustrationItem illustration) { + super(illustration); + } + + @Override + public void render(DrawContext context, TextRenderer textRenderer, PositionTransform positionTransform, int mouseX, int mouseY, float tickDelta) { + // We draw the actual item, then the count and bar and such. + try { + ItemStack stack = this.illustration.stack(); + float scale = this.illustration.scale(); + + ((DrawContextHooks) context).blabber$setItemScale(scale); + int originX = positionTransform.transformX(this.illustration.anchor(), this.illustration.x()); + int originY = positionTransform.transformY(this.illustration.anchor(), this.illustration.y()); + context.drawItem(stack, originX + Math.round(8 * (scale - 1)), originY + Math.round(8 * (scale - 1))); + if (scale == 1) { // Not supporting rescaled stack decorations right now + context.drawItemInSlot(textRenderer, stack, originX, originY); + } + if (this.illustration.showTooltip() && + originX <= mouseX && originX + (16 * scale) + 4 > mouseX && + originY <= mouseY && originY + (16 * scale) + 4 > mouseY) { + context.drawItemTooltip(textRenderer, stack, mouseX, mouseY); + } + } finally { + ((DrawContextHooks) context).blabber$setItemScale(1f); + } + } + + public interface DrawContextHooks { + void blabber$setItemScale(float itemScale); + } +} diff --git a/src/client/java/org/ladysnake/blabber/impl/client/illustrations/NbtEntityIllustrationRenderer.java b/src/client/java/org/ladysnake/blabber/impl/client/illustrations/NbtEntityIllustrationRenderer.java new file mode 100644 index 0000000..656ee7e --- /dev/null +++ b/src/client/java/org/ladysnake/blabber/impl/client/illustrations/NbtEntityIllustrationRenderer.java @@ -0,0 +1,46 @@ +/* + * Blabber + * Copyright (C) 2022-2024 Ladysnake + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; If not, see . + */ +package org.ladysnake.blabber.impl.client.illustrations; + +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.registry.Registries; +import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; +import org.ladysnake.blabber.impl.common.illustrations.entity.DialogueIllustrationNbtEntity; + +public class NbtEntityIllustrationRenderer extends EntityIllustrationRenderer { + public NbtEntityIllustrationRenderer(DialogueIllustrationNbtEntity illustration) { + super(illustration); + } + + @Override + protected @Nullable LivingEntity getRenderedEntity(World world) { + EntityType entityType = Registries.ENTITY_TYPE.getOrEmpty(illustration.id()).orElse(null); + if (entityType == null) return null; + + if (entityType.create(world) instanceof LivingEntity living) { + illustration.data().ifPresent(living::readNbt); + living.prevBodyYaw = living.bodyYaw = 0.0f; + living.prevHeadYaw = living.headYaw = 0.0f; + return living; + } + + return null; + } +} diff --git a/src/client/java/org/ladysnake/blabber/impl/client/illustrations/SelectedEntityIllustrationRenderer.java b/src/client/java/org/ladysnake/blabber/impl/client/illustrations/SelectedEntityIllustrationRenderer.java new file mode 100644 index 0000000..d822098 --- /dev/null +++ b/src/client/java/org/ladysnake/blabber/impl/client/illustrations/SelectedEntityIllustrationRenderer.java @@ -0,0 +1,34 @@ +/* + * Blabber + * Copyright (C) 2022-2024 Ladysnake + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; If not, see . + */ +package org.ladysnake.blabber.impl.client.illustrations; + +import net.minecraft.entity.LivingEntity; +import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; +import org.ladysnake.blabber.impl.common.illustrations.entity.DialogueIllustrationSelectorEntity; + +public class SelectedEntityIllustrationRenderer extends EntityIllustrationRenderer { + public SelectedEntityIllustrationRenderer(DialogueIllustrationSelectorEntity illustration) { + super(illustration); + } + + @Override + protected @Nullable LivingEntity getRenderedEntity(World world) { + return this.illustration.getSelectedEntity(world); + } +} diff --git a/src/client/java/org/ladysnake/blabber/impl/client/illustrations/TextureIllustrationRenderer.java b/src/client/java/org/ladysnake/blabber/impl/client/illustrations/TextureIllustrationRenderer.java new file mode 100644 index 0000000..ad9dae1 --- /dev/null +++ b/src/client/java/org/ladysnake/blabber/impl/client/illustrations/TextureIllustrationRenderer.java @@ -0,0 +1,47 @@ +/* + * Blabber + * Copyright (C) 2022-2024 Ladysnake + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; If not, see . + */ +package org.ladysnake.blabber.impl.client.illustrations; + +import net.minecraft.client.font.TextRenderer; +import net.minecraft.client.gui.DrawContext; +import org.ladysnake.blabber.api.client.illustration.DialogueIllustrationRenderer; +import org.ladysnake.blabber.impl.common.illustrations.DialogueIllustrationTexture; +import org.ladysnake.blabber.impl.common.illustrations.PositionTransform; + +public class TextureIllustrationRenderer extends DialogueIllustrationRenderer { + public TextureIllustrationRenderer(DialogueIllustrationTexture illustration) { + super(illustration); + } + + @Override + public void render(DrawContext context, TextRenderer textRenderer, PositionTransform positionTransform, int mouseX, int mouseY, float tickDelta) { + context.drawTexture( + illustration.texture(), + illustration.minX(positionTransform), + illustration.minY(positionTransform), + illustration.width(), + illustration.height(), + 0, + 0, + illustration.regionWidth().orElse(illustration.width()), + illustration.regionHeight().orElse(illustration.height()), + illustration.textureWidth().orElse(illustration.width()), + illustration.textureHeight().orElse(illustration.height()) + ); + } +} diff --git a/src/main/java/org/ladysnake/blabber/impl/client/package-info.java b/src/client/java/org/ladysnake/blabber/impl/client/package-info.java similarity index 100% rename from src/main/java/org/ladysnake/blabber/impl/client/package-info.java rename to src/client/java/org/ladysnake/blabber/impl/client/package-info.java diff --git a/src/main/java/org/ladysnake/blabber/impl/mixin/client/AbstractClientPlayerEntityAccessor.java b/src/client/java/org/ladysnake/blabber/impl/mixin/client/AbstractClientPlayerEntityAccessor.java similarity index 100% rename from src/main/java/org/ladysnake/blabber/impl/mixin/client/AbstractClientPlayerEntityAccessor.java rename to src/client/java/org/ladysnake/blabber/impl/mixin/client/AbstractClientPlayerEntityAccessor.java diff --git a/src/main/java/org/ladysnake/blabber/impl/mixin/client/DrawContextMixin.java b/src/client/java/org/ladysnake/blabber/impl/mixin/client/DrawContextMixin.java similarity index 91% rename from src/main/java/org/ladysnake/blabber/impl/mixin/client/DrawContextMixin.java rename to src/client/java/org/ladysnake/blabber/impl/mixin/client/DrawContextMixin.java index 2688dd4..a088ae6 100644 --- a/src/main/java/org/ladysnake/blabber/impl/mixin/client/DrawContextMixin.java +++ b/src/client/java/org/ladysnake/blabber/impl/mixin/client/DrawContextMixin.java @@ -19,14 +19,14 @@ import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import net.minecraft.client.gui.DrawContext; -import org.ladysnake.blabber.impl.common.illustrations.DialogueIllustrationItem; +import org.ladysnake.blabber.impl.client.illustrations.ItemIllustrationRenderer; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Slice; @Mixin(DrawContext.class) -public abstract class DrawContextMixin implements DialogueIllustrationItem.DrawContextHooks { +public abstract class DrawContextMixin implements ItemIllustrationRenderer.DrawContextHooks { @Unique private float blabber$itemScale = 1; diff --git a/src/main/java/org/ladysnake/blabber/impl/mixin/compat/emi/EmiScreenManagerMixin.java b/src/client/java/org/ladysnake/blabber/impl/mixin/client/compat/emi/EmiScreenManagerMixin.java similarity index 96% rename from src/main/java/org/ladysnake/blabber/impl/mixin/compat/emi/EmiScreenManagerMixin.java rename to src/client/java/org/ladysnake/blabber/impl/mixin/client/compat/emi/EmiScreenManagerMixin.java index 7cc7cff..e5e142f 100644 --- a/src/main/java/org/ladysnake/blabber/impl/mixin/compat/emi/EmiScreenManagerMixin.java +++ b/src/client/java/org/ladysnake/blabber/impl/mixin/client/compat/emi/EmiScreenManagerMixin.java @@ -15,7 +15,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program; If not, see . */ -package org.ladysnake.blabber.impl.mixin.compat.emi; +package org.ladysnake.blabber.impl.mixin.client.compat.emi; import dev.emi.emi.screen.EmiScreenManager; import net.minecraft.client.MinecraftClient; diff --git a/src/main/java/org/ladysnake/blabber/impl/mixin/compat/emi/package-info.java b/src/client/java/org/ladysnake/blabber/impl/mixin/client/compat/emi/package-info.java similarity index 94% rename from src/main/java/org/ladysnake/blabber/impl/mixin/compat/emi/package-info.java rename to src/client/java/org/ladysnake/blabber/impl/mixin/client/compat/emi/package-info.java index 19b11bd..d0e04a7 100644 --- a/src/main/java/org/ladysnake/blabber/impl/mixin/compat/emi/package-info.java +++ b/src/client/java/org/ladysnake/blabber/impl/mixin/client/compat/emi/package-info.java @@ -21,7 +21,7 @@ @FieldsAreNonnullByDefault @MethodsReturnNonnullByDefault @ApiStatus.Internal -package org.ladysnake.blabber.impl.mixin.compat.emi; +package org.ladysnake.blabber.impl.mixin.client.compat.emi; import net.minecraft.util.annotation.FieldsAreNonnullByDefault; import net.minecraft.util.annotation.MethodsReturnNonnullByDefault; diff --git a/src/main/resources/assets/blabber/lang/en_us.json b/src/client/resources/assets/blabber/lang/en_us.json similarity index 100% rename from src/main/resources/assets/blabber/lang/en_us.json rename to src/client/resources/assets/blabber/lang/en_us.json diff --git a/src/main/resources/assets/blabber/lang/fr_fr.json b/src/client/resources/assets/blabber/lang/fr_fr.json similarity index 100% rename from src/main/resources/assets/blabber/lang/fr_fr.json rename to src/client/resources/assets/blabber/lang/fr_fr.json diff --git a/src/main/resources/assets/blabber/lang/nl_nl.json b/src/client/resources/assets/blabber/lang/nl_nl.json similarity index 100% rename from src/main/resources/assets/blabber/lang/nl_nl.json rename to src/client/resources/assets/blabber/lang/nl_nl.json diff --git a/src/main/resources/assets/blabber/lang/pt_br.json b/src/client/resources/assets/blabber/lang/pt_br.json similarity index 100% rename from src/main/resources/assets/blabber/lang/pt_br.json rename to src/client/resources/assets/blabber/lang/pt_br.json diff --git a/src/main/resources/assets/blabber/lang/ro_ro.json b/src/client/resources/assets/blabber/lang/ro_ro.json similarity index 100% rename from src/main/resources/assets/blabber/lang/ro_ro.json rename to src/client/resources/assets/blabber/lang/ro_ro.json diff --git a/src/main/resources/assets/blabber/lang/ru_ru.json b/src/client/resources/assets/blabber/lang/ru_ru.json similarity index 100% rename from src/main/resources/assets/blabber/lang/ru_ru.json rename to src/client/resources/assets/blabber/lang/ru_ru.json diff --git a/src/main/resources/assets/blabber/lang/uk_ua.json b/src/client/resources/assets/blabber/lang/uk_ua.json similarity index 100% rename from src/main/resources/assets/blabber/lang/uk_ua.json rename to src/client/resources/assets/blabber/lang/uk_ua.json diff --git a/src/main/resources/assets/blabber/lang/zh_cn.json b/src/client/resources/assets/blabber/lang/zh_cn.json similarity index 100% rename from src/main/resources/assets/blabber/lang/zh_cn.json rename to src/client/resources/assets/blabber/lang/zh_cn.json diff --git a/src/main/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_1.png b/src/client/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_1.png similarity index 100% rename from src/main/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_1.png rename to src/client/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_1.png diff --git a/src/main/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_2.png b/src/client/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_2.png similarity index 100% rename from src/main/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_2.png rename to src/client/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_2.png diff --git a/src/main/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_3.png b/src/client/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_3.png similarity index 100% rename from src/main/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_3.png rename to src/client/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_3.png diff --git a/src/main/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_4.png b/src/client/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_4.png similarity index 100% rename from src/main/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_4.png rename to src/client/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_4.png diff --git a/src/main/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_5.png b/src/client/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_5.png similarity index 100% rename from src/main/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_5.png rename to src/client/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_arrow_5.png diff --git a/src/main/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_lock_1.png b/src/client/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_lock_1.png similarity index 100% rename from src/main/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_lock_1.png rename to src/client/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_lock_1.png diff --git a/src/main/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_lock_2.png b/src/client/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_lock_2.png similarity index 100% rename from src/main/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_lock_2.png rename to src/client/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_lock_2.png diff --git a/src/main/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_lock_3.png b/src/client/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_lock_3.png similarity index 100% rename from src/main/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_lock_3.png rename to src/client/resources/assets/blabber/textures/gui/sprites/container/dialogue/dialogue_lock_3.png diff --git a/src/client/resources/blabber.client.mixins.json b/src/client/resources/blabber.client.mixins.json new file mode 100644 index 0000000..e235781 --- /dev/null +++ b/src/client/resources/blabber.client.mixins.json @@ -0,0 +1,15 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "org.ladysnake.blabber.impl.mixin.client", + "compatibilityLevel": "JAVA_17", + "plugin": "org.ladysnake.blabber.impl.client.compat.BlabberClientMixinPlugin", + "client": [ + "AbstractClientPlayerEntityAccessor", + "DrawContextMixin", + "compat.emi.EmiScreenManagerMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/src/main/java/org/ladysnake/blabber/api/illustration/DialogueIllustration.java b/src/main/java/org/ladysnake/blabber/api/illustration/DialogueIllustration.java index e7d30d0..8ff34b7 100644 --- a/src/main/java/org/ladysnake/blabber/api/illustration/DialogueIllustration.java +++ b/src/main/java/org/ladysnake/blabber/api/illustration/DialogueIllustration.java @@ -18,13 +18,10 @@ package org.ladysnake.blabber.api.illustration; import com.mojang.brigadier.exceptions.CommandSyntaxException; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; import net.minecraft.entity.Entity; import net.minecraft.server.command.ServerCommandSource; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; -import org.ladysnake.blabber.impl.common.illustrations.PositionTransform; /** * An illustration that can be rendered in dialogues, such as entities or items. @@ -33,18 +30,6 @@ */ @ApiStatus.Experimental public interface DialogueIllustration { - /** - * Draw this illustration to the screen. - * - * @param context a context to draw in - * @param textRenderer a text renderer - * @param positionTransform an object that gives you real coordinates from illustration-local ones - * @param mouseX the current x mouse position - * @param mouseY the current y mouse position - * @param tickDelta how much time has passed since last frame - */ - void render(DrawContext context, TextRenderer textRenderer, PositionTransform positionTransform, int mouseX, int mouseY, float tickDelta); - /** * @return the DialogueIllustrationType that corresponds to this illustration */ diff --git a/src/main/java/org/ladysnake/blabber/impl/common/DialogueScreenHandler.java b/src/main/java/org/ladysnake/blabber/impl/common/DialogueScreenHandler.java index be3e32c..ff1759e 100644 --- a/src/main/java/org/ladysnake/blabber/impl/common/DialogueScreenHandler.java +++ b/src/main/java/org/ladysnake/blabber/impl/common/DialogueScreenHandler.java @@ -31,13 +31,13 @@ import org.ladysnake.blabber.Blabber; import org.ladysnake.blabber.api.illustration.DialogueIllustration; import org.ladysnake.blabber.api.layout.DialogueLayout; -import org.ladysnake.blabber.impl.client.BlabberClient; import org.ladysnake.blabber.impl.common.machine.AvailableChoice; import org.ladysnake.blabber.impl.common.machine.DialogueStateMachine; import org.ladysnake.blabber.impl.common.model.ChoiceResult; import org.ladysnake.blabber.impl.common.packets.ChoiceAvailabilityPacket; import java.util.List; +import java.util.Map; public class DialogueScreenHandler extends ScreenHandler { private final DialogueStateMachine dialogue; @@ -75,9 +75,8 @@ public List getCurrentIllustrations() { return this.dialogue.getCurrentIllustrations(); } - @Nullable - public DialogueIllustration getIllustration(String name) { - return this.dialogue.getIllustration(name); + public Map getIllustrations() { + return this.dialogue.getIllustrations(); } public ImmutableList getAvailableChoices() { @@ -108,10 +107,7 @@ public void handleAvailabilityUpdate(ChoiceAvailabilityPacket packet) { @CheckEnv(Env.CLIENT) public ChoiceResult makeChoice(int choice) { - int originalChoiceIndex = this.getAvailableChoices().get(choice).originalChoiceIndex(); - ChoiceResult result = this.dialogue.choose(originalChoiceIndex, action -> {}); - BlabberClient.sendDialogueActionMessage(originalChoiceIndex); - return result; + return this.dialogue.choose(choice, action -> {}); } public boolean makeChoice(ServerPlayerEntity player, int choice) { diff --git a/src/main/java/org/ladysnake/blabber/impl/common/illustrations/DialogueIllustrationCollection.java b/src/main/java/org/ladysnake/blabber/impl/common/illustrations/DialogueIllustrationCollection.java index f834e17..b762ab2 100644 --- a/src/main/java/org/ladysnake/blabber/impl/common/illustrations/DialogueIllustrationCollection.java +++ b/src/main/java/org/ladysnake/blabber/impl/common/illustrations/DialogueIllustrationCollection.java @@ -20,8 +20,6 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; import net.minecraft.entity.Entity; import net.minecraft.server.command.ServerCommandSource; import org.jetbrains.annotations.Nullable; @@ -52,13 +50,6 @@ public record DialogueIllustrationCollection(List elements }) ); - @Override - public void render(DrawContext context, TextRenderer textRenderer, PositionTransform positionTransform, int mouseX, int mouseY, float tickDelta) { - for (DialogueIllustration i : elements) { - i.render(context, textRenderer, positionTransform, mouseX, mouseY, tickDelta); - } - } - @Override public DialogueIllustrationType getType() { return TYPE; diff --git a/src/main/java/org/ladysnake/blabber/impl/common/illustrations/DialogueIllustrationItem.java b/src/main/java/org/ladysnake/blabber/impl/common/illustrations/DialogueIllustrationItem.java index 310e0fb..e972797 100644 --- a/src/main/java/org/ladysnake/blabber/impl/common/illustrations/DialogueIllustrationItem.java +++ b/src/main/java/org/ladysnake/blabber/impl/common/illustrations/DialogueIllustrationItem.java @@ -19,8 +19,6 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NbtCompound; import net.minecraft.util.dynamic.Codecs; @@ -61,33 +59,8 @@ public int height() { return Math.round(16 * (this.scale)) + 4; } - @Override - public void render(DrawContext context, TextRenderer textRenderer, PositionTransform positionTransform, int mouseX, int mouseY, float tickDelta) { - // We draw the actual item, then the count and bar and such. - try { - ((DrawContextHooks) context).blabber$setItemScale(scale); - int originX = positionTransform.transformX(this.anchor, this.x); - int originY = positionTransform.transformY(this.anchor, this.y); - context.drawItem(stack, originX + Math.round(8 * (this.scale - 1)), originY + Math.round(8 * (this.scale - 1))); - if (scale() == 1) { // Not supporting rescaled stack decorations right now - context.drawItemInSlot(textRenderer, stack, originX, originY); - } - if (showTooltip && - originX <= mouseX && originX + (16 * this.scale) + 4 > mouseX && - originY <= mouseY && originY + (16 * this.scale) + 4 > mouseY) { - context.drawItemTooltip(textRenderer, stack, mouseX, mouseY); - } - } finally { - ((DrawContextHooks) context).blabber$setItemScale(1f); - } - } - @Override public DialogueIllustrationType getType() { return TYPE; } - - public interface DrawContextHooks { - void blabber$setItemScale(float itemScale); - } } diff --git a/src/main/java/org/ladysnake/blabber/impl/common/illustrations/DialogueIllustrationTexture.java b/src/main/java/org/ladysnake/blabber/impl/common/illustrations/DialogueIllustrationTexture.java index fd099d7..e87832f 100644 --- a/src/main/java/org/ladysnake/blabber/impl/common/illustrations/DialogueIllustrationTexture.java +++ b/src/main/java/org/ladysnake/blabber/impl/common/illustrations/DialogueIllustrationTexture.java @@ -19,8 +19,6 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; import net.minecraft.util.Identifier; import net.minecraft.util.dynamic.Codecs; import org.ladysnake.blabber.api.illustration.DialogueIllustration; @@ -90,23 +88,6 @@ public record DialogueIllustrationTexture( } ); - @Override - public void render(DrawContext context, TextRenderer textRenderer, PositionTransform positionTransform, int mouseX, int mouseY, float tickDelta) { - context.drawTexture( - texture(), - minX(positionTransform), - minY(positionTransform), - width(), - height(), - 0, - 0, - regionWidth().orElse(width()), - regionHeight().orElse(height()), - textureWidth().orElse(width()), - textureHeight().orElse(height()) - ); - } - @Override public DialogueIllustrationType getType() { return TYPE; diff --git a/src/main/java/org/ladysnake/blabber/impl/common/illustrations/entity/DialogueIllustrationEntity.java b/src/main/java/org/ladysnake/blabber/impl/common/illustrations/entity/DialogueIllustrationEntity.java index d17b6ae..1f6a655 100644 --- a/src/main/java/org/ladysnake/blabber/impl/common/illustrations/entity/DialogueIllustrationEntity.java +++ b/src/main/java/org/ladysnake/blabber/impl/common/illustrations/entity/DialogueIllustrationEntity.java @@ -17,96 +17,10 @@ */ package org.ladysnake.blabber.impl.common.illustrations.entity; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.MinecraftClient; -import net.minecraft.client.font.TextRenderer; -import net.minecraft.client.gui.DrawContext; -import net.minecraft.client.gui.screen.ingame.InventoryScreen; -import net.minecraft.entity.LivingEntity; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; -import org.ladysnake.blabber.impl.common.illustrations.PositionTransform; import org.ladysnake.blabber.impl.common.illustrations.SizedDialogueIllustration; -import org.ladysnake.blabber.impl.common.model.IllustrationAnchor; -public abstract class DialogueIllustrationEntity implements SizedDialogueIllustration { - private final S spec; - private transient @Nullable LivingEntity renderedEntity; - - protected DialogueIllustrationEntity(S spec) { - this.spec = spec; - } - - public S spec() { - return spec; - } - - protected abstract @Nullable LivingEntity getRenderedEntity(World world); - - @Override - public IllustrationAnchor anchor() { - return spec().anchor(); - } - - @Override - public int x() { - return spec().x(); - } - - @Override - public int y() { - return spec().y(); - } - - @Override - public int width() { - return spec().width(); - } - - @Override - public int height() { - return spec().height(); - } - - @Override - @Environment(EnvType.CLIENT) - public void render(DrawContext context, TextRenderer textRenderer, PositionTransform positionTransform, int mouseX, int mouseY, float tickDelta) { - LivingEntity e = this.renderedEntity == null - ? this.renderedEntity = this.getRenderedEntity(MinecraftClient.getInstance().world) - : this.renderedEntity; - - if (e == null) return; // Something went wrong creating the entity, so don't render. - - int x1 = minX(positionTransform); - int y1 = minY(positionTransform); - int x2 = maxX(positionTransform); - int y2 = maxY(positionTransform); - - StareTarget stareTarget = spec().stareAt(); - int fakedMouseX = stareTarget.x().isPresent() ? stareTarget.anchor().isPresent() ? positionTransform.transformX(stareTarget.anchor().get(), stareTarget.x().getAsInt()) : stareTarget.x().getAsInt() + (x1 + x2) / 2 : mouseX; - int fakedMouseY = stareTarget.y().isPresent() ? stareTarget.anchor().isPresent() ? positionTransform.transformY(stareTarget.anchor().get(), stareTarget.y().getAsInt()) : stareTarget.y().getAsInt() + (y1 + y2) / 2 : mouseY; - - InventoryScreen.drawEntity(context, - x1, - y1, - x2, - y2, - spec().entitySize(), - spec().yOffset(), - fakedMouseX, - fakedMouseY, - e); - } - - public interface Spec { - IllustrationAnchor anchor(); - StareTarget stareAt(); - int x(); - int y(); - int width(); - int height(); - float yOffset(); - int entitySize(); - } +public interface DialogueIllustrationEntity extends SizedDialogueIllustration { + StareTarget stareAt(); + float yOffset(); + int entitySize(); } diff --git a/src/main/java/org/ladysnake/blabber/impl/common/illustrations/entity/DialogueIllustrationFakePlayer.java b/src/main/java/org/ladysnake/blabber/impl/common/illustrations/entity/DialogueIllustrationFakePlayer.java index f86008c..4de8c6a 100644 --- a/src/main/java/org/ladysnake/blabber/impl/common/illustrations/entity/DialogueIllustrationFakePlayer.java +++ b/src/main/java/org/ladysnake/blabber/impl/common/illustrations/entity/DialogueIllustrationFakePlayer.java @@ -20,26 +20,15 @@ import com.mojang.authlib.GameProfile; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; -import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.fabricmc.api.EnvType; -import net.fabricmc.api.Environment; -import net.minecraft.client.network.OtherClientPlayerEntity; -import net.minecraft.client.network.PlayerListEntry; import net.minecraft.client.render.entity.PlayerModelPart; -import net.minecraft.client.world.ClientWorld; -import net.minecraft.entity.LivingEntity; import net.minecraft.nbt.NbtCompound; import net.minecraft.network.PacketByteBuf; import net.minecraft.util.Arm; import net.minecraft.util.StringIdentifiable; import net.minecraft.util.dynamic.Codecs; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; import org.ladysnake.blabber.api.illustration.DialogueIllustrationType; import org.ladysnake.blabber.impl.common.model.IllustrationAnchor; -import org.ladysnake.blabber.impl.mixin.PlayerEntityAccessor; -import org.ladysnake.blabber.impl.mixin.client.AbstractClientPlayerEntityAccessor; import java.util.EnumSet; import java.util.HashMap; @@ -47,12 +36,34 @@ import java.util.Map; import java.util.Optional; -public class DialogueIllustrationFakePlayer extends DialogueIllustrationEntity { +public record DialogueIllustrationFakePlayer(GameProfile profile, + IllustrationAnchor anchor, + int x, + int y, + int width, + int height, + int entitySize, + float yOffset, + StareTarget stareAt, + Optional modelOptions, + Optional data) implements DialogueIllustrationEntity { + private static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + Codecs.GAME_PROFILE_WITH_PROPERTIES.fieldOf("profile").forGetter(DialogueIllustrationFakePlayer::profile), + Codecs.createStrictOptionalFieldCodec(IllustrationAnchor.CODEC, "anchor", IllustrationAnchor.TOP_LEFT).forGetter(DialogueIllustrationFakePlayer::anchor), + Codec.INT.fieldOf("x").forGetter(DialogueIllustrationFakePlayer::x), + Codec.INT.fieldOf("y").forGetter(DialogueIllustrationFakePlayer::y), + Codec.INT.fieldOf("width").forGetter(DialogueIllustrationFakePlayer::width), + Codec.INT.fieldOf("height").forGetter(DialogueIllustrationFakePlayer::height), + Codec.INT.fieldOf("entity_size").forGetter(DialogueIllustrationFakePlayer::entitySize), + Codecs.createStrictOptionalFieldCodec(Codec.FLOAT, "y_offset", 0.0f).forGetter(DialogueIllustrationFakePlayer::yOffset), + Codecs.createStrictOptionalFieldCodec(StareTarget.CODEC, "stare_at", StareTarget.FOLLOW_MOUSE).forGetter(DialogueIllustrationFakePlayer::stareAt), + Codecs.createStrictOptionalFieldCodec(PlayerModelOptions.CODEC, "model_customization").forGetter(DialogueIllustrationFakePlayer::modelOptions), + Codecs.createStrictOptionalFieldCodec(NbtCompound.CODEC, "data").forGetter(DialogueIllustrationFakePlayer::data) + ).apply(instance, DialogueIllustrationFakePlayer::new)); // Need to have a MapCodecCodec here, otherwise it will deserialize differently - private static final Codec CODEC = Spec.CODEC.xmap(DialogueIllustrationFakePlayer::new, DialogueIllustrationFakePlayer::spec).codec(); public static final DialogueIllustrationType TYPE = new DialogueIllustrationType<>( CODEC, - buf -> new DialogueIllustrationFakePlayer(new Spec( + buf -> new DialogueIllustrationFakePlayer( buf.readGameProfile(), buf.readEnumConstant(IllustrationAnchor.class), buf.readVarInt(), @@ -64,45 +75,29 @@ public class DialogueIllustrationFakePlayer extends DialogueIllustrationEntity { - buf.writeGameProfile(i.spec().profile()); - buf.writeEnumConstant(i.spec().anchor()); - buf.writeVarInt(i.spec().x()); - buf.writeVarInt(i.spec().y()); - buf.writeVarInt(i.spec().width()); - buf.writeVarInt(i.spec().height()); - buf.writeVarInt(i.spec().entitySize()); - buf.writeFloat(i.spec().yOffset()); - StareTarget.writeToPacket(buf, i.spec().stareAt()); - buf.writeOptional(i.spec().modelOptions(), (b, opts) -> opts.writeToBuffer(b)); - buf.writeOptional(i.spec().data(), PacketByteBuf::writeNbt); + buf.writeGameProfile(i.profile()); + buf.writeEnumConstant(i.anchor()); + buf.writeVarInt(i.x()); + buf.writeVarInt(i.y()); + buf.writeVarInt(i.width()); + buf.writeVarInt(i.height()); + buf.writeVarInt(i.entitySize()); + buf.writeFloat(i.yOffset()); + StareTarget.writeToPacket(buf, i.stareAt()); + buf.writeOptional(i.modelOptions(), (b, opts) -> opts.writeToBuffer(b)); + buf.writeOptional(i.data(), PacketByteBuf::writeNbt); } ); - public DialogueIllustrationFakePlayer(Spec spec) { - super(spec); - } - @Override public DialogueIllustrationType getType() { return TYPE; } - @SuppressWarnings("UnreachableCode") - @Environment(EnvType.CLIENT) - @Override - protected @Nullable LivingEntity getRenderedEntity(World world) { - GameProfile profile = this.spec().profile(); - OtherClientPlayerEntity fakePlayer = new OtherClientPlayerEntity((ClientWorld) world, profile); - this.spec().data().ifPresent(fakePlayer::readNbt); - ((AbstractClientPlayerEntityAccessor) fakePlayer).setPlayerListEntry(new PlayerListEntry(profile, false)); - fakePlayer.prevBodyYaw = fakePlayer.bodyYaw = 0.0f; - fakePlayer.prevHeadYaw = fakePlayer.headYaw = 0.0f; - PlayerModelOptions playerModelOptions = this.spec().modelOptionsOrDefault(); - fakePlayer.getDataTracker().set(PlayerEntityAccessor.getPlayerModelParts(), playerModelOptions.packVisibleParts()); - fakePlayer.setMainArm(playerModelOptions.mainHand()); - return fakePlayer; + public PlayerModelOptions modelOptionsOrDefault() { + return this.modelOptions().orElse(PlayerModelOptions.DEFAULT); } public record PlayerModelOptions(Arm mainHand, EnumSet visibleParts) { @@ -154,34 +149,4 @@ public byte packVisibleParts() { return packed; } } - - public record Spec(GameProfile profile, - IllustrationAnchor anchor, - int x, - int y, - int width, - int height, - int entitySize, - float yOffset, - StareTarget stareAt, - Optional modelOptions, - Optional data) implements DialogueIllustrationEntity.Spec { - private static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - Codecs.GAME_PROFILE_WITH_PROPERTIES.fieldOf("profile").forGetter(Spec::profile), - Codecs.createStrictOptionalFieldCodec(IllustrationAnchor.CODEC, "anchor", IllustrationAnchor.TOP_LEFT).forGetter(Spec::anchor), - Codec.INT.fieldOf("x").forGetter(Spec::x), - Codec.INT.fieldOf("y").forGetter(Spec::y), - Codec.INT.fieldOf("width").forGetter(Spec::width), - Codec.INT.fieldOf("height").forGetter(Spec::height), - Codec.INT.fieldOf("entity_size").forGetter(Spec::entitySize), - Codecs.createStrictOptionalFieldCodec(Codec.FLOAT, "y_offset", 0.0f).forGetter(Spec::yOffset), - Codecs.createStrictOptionalFieldCodec(StareTarget.CODEC, "stare_at", StareTarget.FOLLOW_MOUSE).forGetter(Spec::stareAt), - Codecs.createStrictOptionalFieldCodec(PlayerModelOptions.CODEC, "model_customization").forGetter(Spec::modelOptions), - Codecs.createStrictOptionalFieldCodec(NbtCompound.CODEC, "data").forGetter(Spec::data) - ).apply(instance, Spec::new)); - - public PlayerModelOptions modelOptionsOrDefault() { - return this.modelOptions().orElse(PlayerModelOptions.DEFAULT); - } - } } diff --git a/src/main/java/org/ladysnake/blabber/impl/common/illustrations/entity/DialogueIllustrationNbtEntity.java b/src/main/java/org/ladysnake/blabber/impl/common/illustrations/entity/DialogueIllustrationNbtEntity.java index 2bf6333..7cdc708 100644 --- a/src/main/java/org/ladysnake/blabber/impl/common/illustrations/entity/DialogueIllustrationNbtEntity.java +++ b/src/main/java/org/ladysnake/blabber/impl/common/illustrations/entity/DialogueIllustrationNbtEntity.java @@ -20,15 +20,10 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.minecraft.entity.EntityType; -import net.minecraft.entity.LivingEntity; import net.minecraft.nbt.NbtCompound; import net.minecraft.network.PacketByteBuf; -import net.minecraft.registry.Registries; import net.minecraft.util.Identifier; import net.minecraft.util.dynamic.Codecs; -import net.minecraft.world.World; -import org.jetbrains.annotations.Nullable; import org.ladysnake.blabber.api.illustration.DialogueIllustrationType; import org.ladysnake.blabber.impl.common.model.IllustrationAnchor; import org.ladysnake.blabber.impl.common.serialization.EitherMapCodec; @@ -36,12 +31,42 @@ import java.util.Optional; -public class DialogueIllustrationNbtEntity extends DialogueIllustrationEntity { - // Need to have a MapCodecCodec here, otherwise it will deserialize differently - private static final Codec CODEC = Spec.CODEC.xmap(DialogueIllustrationNbtEntity::new, DialogueIllustrationNbtEntity::spec).codec(); +public record DialogueIllustrationNbtEntity(Identifier id, IllustrationAnchor anchor, int x, int y, int width, int height, int entitySize, float yOffset, StareTarget stareAt, Optional data) implements DialogueIllustrationEntity { + private static final MapCodec CODEC_V0 = RecordCodecBuilder.mapCodec(instance -> instance.group( + Identifier.CODEC.fieldOf("id").forGetter(DialogueIllustrationNbtEntity::id), + Codecs.createStrictOptionalFieldCodec(IllustrationAnchor.CODEC, "anchor", IllustrationAnchor.TOP_LEFT).forGetter(DialogueIllustrationNbtEntity::anchor), + Codec.INT.fieldOf("x1").forGetter(DialogueIllustrationNbtEntity::x), + Codec.INT.fieldOf("y1").forGetter(DialogueIllustrationNbtEntity::y), + Codec.INT.fieldOf("x2").forGetter(s -> s.x() + s.width()), + Codec.INT.fieldOf("y2").forGetter(s -> s.y() + s.height()), + Codec.INT.fieldOf("size").forGetter(DialogueIllustrationNbtEntity::entitySize), + Codecs.createStrictOptionalFieldCodec(Codec.FLOAT, "y_offset", 0.0f).forGetter(DialogueIllustrationNbtEntity::yOffset), + OptionalSerialization.optionalIntField("stare_at_x").forGetter(s -> s.stareAt().x()), + OptionalSerialization.optionalIntField("stare_at_y").forGetter(s -> s.stareAt().y()), + Codecs.createStrictOptionalFieldCodec(NbtCompound.CODEC, "data").forGetter(DialogueIllustrationNbtEntity::data) + ).apply(instance, (id, anchor, x1, y1, x2, y2, size, yOff, stareAtX, stareAtY, data) -> { + int minX = Math.min(x1, x2); + int minY = Math.min(y1, y2); + int maxX = Math.max(x1, x2); + int maxY = Math.max(y1, y2); + return new DialogueIllustrationNbtEntity(id, anchor, minX, minY, maxX - minX, maxY - minY, size, yOff, new StareTarget(Optional.empty(), stareAtX, stareAtY), data); + })); + private static final MapCodec CODEC_V1 = RecordCodecBuilder.mapCodec(instance -> instance.group( + Identifier.CODEC.fieldOf("id").forGetter(DialogueIllustrationNbtEntity::id), + Codecs.createStrictOptionalFieldCodec(IllustrationAnchor.CODEC, "anchor", IllustrationAnchor.TOP_LEFT).forGetter(DialogueIllustrationNbtEntity::anchor), + Codec.INT.fieldOf("x").forGetter(DialogueIllustrationNbtEntity::x), + Codec.INT.fieldOf("y").forGetter(DialogueIllustrationNbtEntity::y), + Codec.INT.fieldOf("width").forGetter(DialogueIllustrationNbtEntity::width), + Codec.INT.fieldOf("height").forGetter(DialogueIllustrationNbtEntity::height), + Codec.INT.fieldOf("entity_size").forGetter(DialogueIllustrationNbtEntity::entitySize), + Codecs.createStrictOptionalFieldCodec(Codec.FLOAT, "y_offset", 0.0f).forGetter(DialogueIllustrationNbtEntity::yOffset), + Codecs.createStrictOptionalFieldCodec(StareTarget.CODEC, "stare_at", StareTarget.FOLLOW_MOUSE).forGetter(DialogueIllustrationNbtEntity::stareAt), + Codecs.createStrictOptionalFieldCodec(NbtCompound.CODEC, "data").forGetter(DialogueIllustrationNbtEntity::data) + ).apply(instance, DialogueIllustrationNbtEntity::new)); + public static final Codec CODEC = EitherMapCodec.alternatively(CODEC_V0, CODEC_V1).codec(); public static final DialogueIllustrationType TYPE = new DialogueIllustrationType<>( CODEC, - buf -> new DialogueIllustrationNbtEntity(new Spec( + buf -> new DialogueIllustrationNbtEntity( buf.readIdentifier(), buf.readEnumConstant(IllustrationAnchor.class), buf.readInt(), @@ -52,77 +77,23 @@ public class DialogueIllustrationNbtEntity extends DialogueIllustrationEntity { - buf.writeIdentifier(i.spec().id()); - buf.writeEnumConstant(i.spec().anchor()); - buf.writeInt(i.spec().x()); - buf.writeInt(i.spec().y()); - buf.writeInt(i.spec().width()); - buf.writeInt(i.spec().height()); - buf.writeInt(i.spec().entitySize()); - buf.writeFloat(i.spec().yOffset()); - StareTarget.writeToPacket(buf, i.spec().stareAt()); - buf.writeOptional(i.spec().data(), PacketByteBuf::writeNbt); + buf.writeIdentifier(i.id()); + buf.writeEnumConstant(i.anchor()); + buf.writeInt(i.x()); + buf.writeInt(i.y()); + buf.writeInt(i.width()); + buf.writeInt(i.height()); + buf.writeInt(i.entitySize()); + buf.writeFloat(i.yOffset()); + StareTarget.writeToPacket(buf, i.stareAt()); + buf.writeOptional(i.data(), PacketByteBuf::writeNbt); } ); - public DialogueIllustrationNbtEntity(Spec spec) { - super(spec); - } - - @Override - protected @Nullable LivingEntity getRenderedEntity(World world) { - EntityType entityType = Registries.ENTITY_TYPE.getOrEmpty(spec().id()).orElse(null); - if (entityType == null) return null; - - if (entityType.create(world) instanceof LivingEntity living) { - this.spec().data().ifPresent(living::readNbt); - living.prevBodyYaw = living.bodyYaw = 0.0f; - living.prevHeadYaw = living.headYaw = 0.0f; - return living; - } - - return null; - } - @Override public DialogueIllustrationType getType() { return TYPE; } - - public record Spec(Identifier id, IllustrationAnchor anchor, int x, int y, int width, int height, int entitySize, float yOffset, StareTarget stareAt, Optional data) implements DialogueIllustrationEntity.Spec { - private static final MapCodec CODEC_V0 = RecordCodecBuilder.mapCodec(instance -> instance.group( - Identifier.CODEC.fieldOf("id").forGetter(Spec::id), - Codecs.createStrictOptionalFieldCodec(IllustrationAnchor.CODEC, "anchor", IllustrationAnchor.TOP_LEFT).forGetter(Spec::anchor), - Codec.INT.fieldOf("x1").forGetter(Spec::x), - Codec.INT.fieldOf("y1").forGetter(Spec::y), - Codec.INT.fieldOf("x2").forGetter(s -> s.x() + s.width()), - Codec.INT.fieldOf("y2").forGetter(s -> s.y() + s.height()), - Codec.INT.fieldOf("size").forGetter(Spec::entitySize), - Codecs.createStrictOptionalFieldCodec(Codec.FLOAT, "y_offset", 0.0f).forGetter(Spec::yOffset), - OptionalSerialization.optionalIntField("stare_at_x").forGetter(s -> s.stareAt().x()), - OptionalSerialization.optionalIntField("stare_at_y").forGetter(s -> s.stareAt().y()), - Codecs.createStrictOptionalFieldCodec(NbtCompound.CODEC, "data").forGetter(Spec::data) - ).apply(instance, (id, anchor, x1, y1, x2, y2, size, yOff, stareAtX, stareAtY, data) -> { - int minX = Math.min(x1, x2); - int minY = Math.min(y1, y2); - int maxX = Math.max(x1, x2); - int maxY = Math.max(y1, y2); - return new Spec(id, anchor, minX, minY, maxX - minX, maxY - minY, size, yOff, new StareTarget(Optional.empty(), stareAtX, stareAtY), data); - })); - private static final MapCodec CODEC_V1 = RecordCodecBuilder.mapCodec(instance -> instance.group( - Identifier.CODEC.fieldOf("id").forGetter(Spec::id), - Codecs.createStrictOptionalFieldCodec(IllustrationAnchor.CODEC, "anchor", IllustrationAnchor.TOP_LEFT).forGetter(Spec::anchor), - Codec.INT.fieldOf("x").forGetter(Spec::x), - Codec.INT.fieldOf("y").forGetter(Spec::y), - Codec.INT.fieldOf("width").forGetter(Spec::width), - Codec.INT.fieldOf("height").forGetter(Spec::height), - Codec.INT.fieldOf("entity_size").forGetter(Spec::entitySize), - Codecs.createStrictOptionalFieldCodec(Codec.FLOAT, "y_offset", 0.0f).forGetter(Spec::yOffset), - Codecs.createStrictOptionalFieldCodec(StareTarget.CODEC, "stare_at", StareTarget.FOLLOW_MOUSE).forGetter(Spec::stareAt), - Codecs.createStrictOptionalFieldCodec(NbtCompound.CODEC, "data").forGetter(Spec::data) - ).apply(instance, Spec::new)); - public static final MapCodec CODEC = EitherMapCodec.alternatively(CODEC_V0, CODEC_V1); - } } diff --git a/src/main/java/org/ladysnake/blabber/impl/common/illustrations/entity/DialogueIllustrationSelectorEntity.java b/src/main/java/org/ladysnake/blabber/impl/common/illustrations/entity/DialogueIllustrationSelectorEntity.java index a83005c..bb6a117 100644 --- a/src/main/java/org/ladysnake/blabber/impl/common/illustrations/entity/DialogueIllustrationSelectorEntity.java +++ b/src/main/java/org/ladysnake/blabber/impl/common/illustrations/entity/DialogueIllustrationSelectorEntity.java @@ -38,7 +38,7 @@ import java.util.Optional; -public class DialogueIllustrationSelectorEntity extends DialogueIllustrationEntity { +public class DialogueIllustrationSelectorEntity implements DialogueIllustrationEntity { // Need to have a MapCodecCodec here, otherwise it will deserialize differently public static final Codec CODEC = Spec.CODEC.xmap(DialogueIllustrationSelectorEntity::new, DialogueIllustrationSelectorEntity::spec).codec(); @@ -56,6 +56,7 @@ public class DialogueIllustrationSelectorEntity extends DialogueIllustrationEnti private static final int NO_ENTITY_FOUND = -1; + private final Spec spec; private int selectedEntityId; public DialogueIllustrationSelectorEntity(Spec spec) { @@ -63,17 +64,60 @@ public DialogueIllustrationSelectorEntity(Spec spec) { } private DialogueIllustrationSelectorEntity(Spec spec, int selectedEntityId) { - super(spec); + this.spec = spec; this.selectedEntityId = selectedEntityId; } - @Override - protected @Nullable LivingEntity getRenderedEntity(World world) { + public LivingEntity getSelectedEntity(World world) { if (this.selectedEntityId == -1) return null; // shortcut Entity e = world.getEntityById(this.selectedEntityId); return e instanceof LivingEntity living ? living : null; } + public Spec spec() { + return spec; + } + + @Override + public StareTarget stareAt() { + return this.spec.stareAt(); + } + + @Override + public float yOffset() { + return this.spec.yOffset(); + } + + @Override + public int entitySize() { + return this.spec.entitySize(); + } + + @Override + public IllustrationAnchor anchor() { + return this.spec.anchor(); + } + + @Override + public int x() { + return this.spec.x(); + } + + @Override + public int y() { + return this.spec.y(); + } + + @Override + public int width() { + return this.spec.width(); + } + + @Override + public int height() { + return this.spec.height(); + } + @Override public DialogueIllustrationType getType() { return TYPE; @@ -93,7 +137,7 @@ public DialogueIllustrationSelectorEntity parseText(@Nullable ServerCommandSourc public record Spec(String selector, IllustrationAnchor anchor, int x, int y, int width, int height, int entitySize, float yOffset, - StareTarget stareAt) implements DialogueIllustrationEntity.Spec { + StareTarget stareAt) { private static final MapCodec CODEC_V0 = RecordCodecBuilder.mapCodec(instance -> instance.group( Codec.STRING.fieldOf("entity").forGetter(Spec::selector), Codecs.createStrictOptionalFieldCodec(IllustrationAnchor.CODEC, "anchor", IllustrationAnchor.TOP_LEFT).forGetter(Spec::anchor), diff --git a/src/main/java/org/ladysnake/blabber/impl/common/machine/DialogueStateMachine.java b/src/main/java/org/ladysnake/blabber/impl/common/machine/DialogueStateMachine.java index 5f7105e..da5b480 100644 --- a/src/main/java/org/ladysnake/blabber/impl/common/machine/DialogueStateMachine.java +++ b/src/main/java/org/ladysnake/blabber/impl/common/machine/DialogueStateMachine.java @@ -120,9 +120,8 @@ public List getCurrentIllustrations() { return this.getCurrentState().illustrations(); } - @Nullable - public DialogueIllustration getIllustration(String name) { - return this.template.illustrations().get(name); + public Map getIllustrations() { + return this.template.illustrations(); } public ImmutableList getAvailableChoices() { diff --git a/src/main/java/org/ladysnake/blabber/impl/common/settings/BlabberSettingsComponent.java b/src/main/java/org/ladysnake/blabber/impl/common/settings/BlabberSettingsComponent.java index 762508a..8bd2bbf 100644 --- a/src/main/java/org/ladysnake/blabber/impl/common/settings/BlabberSettingsComponent.java +++ b/src/main/java/org/ladysnake/blabber/impl/common/settings/BlabberSettingsComponent.java @@ -34,7 +34,6 @@ public class BlabberSettingsComponent implements AutoSyncedComponent { public static final ComponentKey KEY = ComponentRegistry.getOrCreate(Blabber.id("settings"), BlabberSettingsComponent.class); - private static final EnumSet NO_SETTING = EnumSet.noneOf(BlabberSetting.class); public static BlabberSettingsComponent get(PlayerEntity player) { return player.getComponent(KEY); diff --git a/src/main/java/org/ladysnake/blabber/impl/mixin/EntitySelectorReaderMixin.java b/src/main/java/org/ladysnake/blabber/impl/mixin/EntitySelectorReaderMixin.java index 746940a..71ba7a2 100644 --- a/src/main/java/org/ladysnake/blabber/impl/mixin/EntitySelectorReaderMixin.java +++ b/src/main/java/org/ladysnake/blabber/impl/mixin/EntitySelectorReaderMixin.java @@ -36,7 +36,7 @@ public abstract class EntitySelectorReaderMixin { private boolean blabber$interlocutorSelector; @SuppressWarnings("InvalidInjectorMethodSignature") - @ModifyVariable(method = "readAtVariable", at = @At(value = "INVOKE_ASSIGN", target = "Lcom/mojang/brigadier/StringReader;read()C"), allow = 1) + @ModifyVariable(method = "readAtVariable", at = @At(value = "INVOKE_ASSIGN", target = "Lcom/mojang/brigadier/StringReader;read()C", remap = false), allow = 1) private char parseInterlocutor(char selector) { if (selector == 'i') { int cursor = this.reader.getCursor(); diff --git a/src/main/resources/blabber.mixins.json b/src/main/resources/blabber.mixins.json index c2a3e69..7dbe436 100644 --- a/src/main/resources/blabber.mixins.json +++ b/src/main/resources/blabber.mixins.json @@ -3,17 +3,11 @@ "minVersion": "0.8", "package": "org.ladysnake.blabber.impl.mixin", "compatibilityLevel": "JAVA_17", - "plugin": "org.ladysnake.blabber.impl.compat.BlabberMixinPlugin", - "client": [ - "client.AbstractClientPlayerEntityAccessor", - "client.DrawContextMixin" - ], "mixins": [ "EntitySelectorMixin", "EntitySelectorReaderMixin", "PlayerEntityAccessor", - "PlayerManagerMixin", - "compat.emi.EmiScreenManagerMixin" + "PlayerManagerMixin" ], "injectors": { "defaultRequire": 1 diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index fd9d70a..0436218 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -29,11 +29,15 @@ "org.ladysnake.blabber.impl.common.BlabberRegistrar" ], "rei_client": [ - "org.ladysnake.blabber.impl.compat.BlabberReiClientPlugin" + "org.ladysnake.blabber.impl.client.compat.BlabberReiClientPlugin" ] }, "mixins": [ - "blabber.mixins.json" + "blabber.mixins.json", + { + "config": "blabber.client.mixins.json", + "environment": "client" + } ], "depends": { diff --git a/src/testmod/java/org/ladysnake/babblings/tests/BlabberTestSuite.java b/src/testmod/java/org/ladysnake/babblings/tests/BlabberTestSuite.java index f299291..0d1af71 100644 --- a/src/testmod/java/org/ladysnake/babblings/tests/BlabberTestSuite.java +++ b/src/testmod/java/org/ladysnake/babblings/tests/BlabberTestSuite.java @@ -50,8 +50,9 @@ public void nominal(TestContext ctx) { @GameTest(templateName = EMPTY_STRUCTURE) public void registryGetsPopulated(TestContext ctx) { - GameTestUtil.assertTrue("dialogue registry should match expected state", + GameTestUtil.assertTrue("dialogue registry should match expected state (was " + DialogueRegistry.getIds() + ")", DialogueRegistry.getIds().equals(Set.of( + new Identifier("babblings:illustration_tests"), new Identifier("babblings:mountain_king"), new Identifier("babblings:perception_check"), new Identifier("babblings:remnant_choice") @@ -63,7 +64,7 @@ public void registryGetsPopulated(TestContext ctx) { @GameTest(templateName = EMPTY_STRUCTURE) public void availableChoicesCanGetSelected(TestContext ctx) { ServerPlayerEntity player = ctx.spawnServerPlayer(2, 2, 2); - Blabber.startDialogue(player, new Identifier("babblings:mountain_king")); + Blabber.startDialogue(player, new Identifier("babblings:mountain_king"), player); ((DialogueScreenHandler) player.currentScreenHandler).makeChoice(player, 1); ((DialogueScreenHandler) player.currentScreenHandler).makeChoice(player, 0); GameTestUtil.assertTrue("dialogue should end", player.currentScreenHandler == player.playerScreenHandler); @@ -74,7 +75,7 @@ public void availableChoicesCanGetSelected(TestContext ctx) { public void unavailableChoicesCannotGetSelected(TestContext ctx) { ServerPlayerEntity player = ctx.spawnServerPlayer(2, 2, 2); player.setHealth(10f); - Blabber.startDialogue(player, new Identifier("babblings:mountain_king")); + Blabber.startDialogue(player, new Identifier("babblings:mountain_king"), player); ((DialogueScreenHandler) player.currentScreenHandler).makeChoice(player, 1); GameTestUtil.assertTrue("dialogue should be at state bargain", player.currentScreenHandler instanceof DialogueScreenHandler handler && handler.getCurrentStateKey().equals("bargain")); ((DialogueScreenHandler) player.currentScreenHandler).makeChoice(player, 0);