diff --git a/build-logic/src/main/kotlin/kit_tunes.java.16.gradle.kts b/build-logic/src/main/kotlin/kit_tunes.java.16.gradle.kts new file mode 100644 index 0000000..8d6e747 --- /dev/null +++ b/build-logic/src/main/kotlin/kit_tunes.java.16.gradle.kts @@ -0,0 +1,19 @@ +plugins { + id("java") +} + +java { + withSourcesJar() + + toolchain { + languageVersion = JavaLanguageVersion.of(16) + } +} + +tasks.withType { + options.encoding = "UTF-8" + + javaCompiler = javaToolchains.compilerFor { + languageVersion = JavaLanguageVersion.of(16) + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b384777..acc53da 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,8 +7,8 @@ quilt_loader = "0.26.0" qsl = "8.0.0-alpha.11+1.20.4" -annotations = "24.1.0" -gson = "2.11.0" +annotations = "13.0" +gson = "2.8.0" slf4j = "2.0.13" [libraries] diff --git a/kit-tunes/build.gradle.kts b/kit-tunes/build.gradle.kts index 43fe34c..c79083f 100644 --- a/kit-tunes/build.gradle.kts +++ b/kit-tunes/build.gradle.kts @@ -7,9 +7,11 @@ dependencies { include(project(":kit-tunes-api")) include(project(":kitten-heart")) - include(project(":kitten-star:r1.20.4")) + include(project(":kitten-star:r1.17.0")) + include(project(":kitten-star:r1.20.4")) - include(project(":kitten-square:r1.20.4")) + include(project(":kitten-square:r1.17.0")) + include(project(":kitten-square:r1.20.4")) include(project(":kitten-square:r1.21.0")) } diff --git a/kit-tunes/src/main/resources/assets/kit_tunes/textures/gui/sprites/widget/button.png b/kit-tunes/src/main/resources/assets/kit_tunes/textures/gui/sprites/widget/button.png new file mode 100644 index 0000000..28a3269 Binary files /dev/null and b/kit-tunes/src/main/resources/assets/kit_tunes/textures/gui/sprites/widget/button.png differ diff --git a/kit-tunes/src/main/resources/assets/kit_tunes/textures/gui/sprites/widget/button.png.mcmeta b/kit-tunes/src/main/resources/assets/kit_tunes/textures/gui/sprites/widget/button.png.mcmeta new file mode 100644 index 0000000..c3065ff --- /dev/null +++ b/kit-tunes/src/main/resources/assets/kit_tunes/textures/gui/sprites/widget/button.png.mcmeta @@ -0,0 +1,10 @@ +{ + "gui": { + "scaling": { + "type": "nine_slice", + "width": 200, + "height": 20, + "border": 3 + } + } +} diff --git a/kit-tunes/src/main/resources/assets/kit_tunes/textures/gui/sprites/widget/button_disabled.png b/kit-tunes/src/main/resources/assets/kit_tunes/textures/gui/sprites/widget/button_disabled.png new file mode 100644 index 0000000..7822467 Binary files /dev/null and b/kit-tunes/src/main/resources/assets/kit_tunes/textures/gui/sprites/widget/button_disabled.png differ diff --git a/kit-tunes/src/main/resources/assets/kit_tunes/textures/gui/sprites/widget/button_disabled.png.mcmeta b/kit-tunes/src/main/resources/assets/kit_tunes/textures/gui/sprites/widget/button_disabled.png.mcmeta new file mode 100644 index 0000000..6e42b43 --- /dev/null +++ b/kit-tunes/src/main/resources/assets/kit_tunes/textures/gui/sprites/widget/button_disabled.png.mcmeta @@ -0,0 +1,10 @@ +{ + "gui": { + "scaling": { + "type": "nine_slice", + "width": 200, + "height": 20, + "border": 1 + } + } +} diff --git a/kit-tunes/src/main/resources/assets/kit_tunes/textures/gui/sprites/widget/button_highlighted.png b/kit-tunes/src/main/resources/assets/kit_tunes/textures/gui/sprites/widget/button_highlighted.png new file mode 100644 index 0000000..47fa007 Binary files /dev/null and b/kit-tunes/src/main/resources/assets/kit_tunes/textures/gui/sprites/widget/button_highlighted.png differ diff --git a/kit-tunes/src/main/resources/assets/kit_tunes/textures/gui/sprites/widget/button_highlighted.png.mcmeta b/kit-tunes/src/main/resources/assets/kit_tunes/textures/gui/sprites/widget/button_highlighted.png.mcmeta new file mode 100644 index 0000000..c3065ff --- /dev/null +++ b/kit-tunes/src/main/resources/assets/kit_tunes/textures/gui/sprites/widget/button_highlighted.png.mcmeta @@ -0,0 +1,10 @@ +{ + "gui": { + "scaling": { + "type": "nine_slice", + "width": 200, + "height": 20, + "border": 3 + } + } +} diff --git a/kitten-heart/src/main/java/net/pixaurora/kitten_cube/impl/ui/widget/button/RectangularButton.java b/kitten-heart/src/main/java/net/pixaurora/kitten_cube/impl/ui/widget/button/RectangularButton.java index 5c14e4b..b303dfa 100644 --- a/kitten-heart/src/main/java/net/pixaurora/kitten_cube/impl/ui/widget/button/RectangularButton.java +++ b/kitten-heart/src/main/java/net/pixaurora/kitten_cube/impl/ui/widget/button/RectangularButton.java @@ -16,11 +16,11 @@ public class RectangularButton implements Button { public static final Size DEFAULT_SIZE = Size.of(200, 20); private static final GuiTexture DEFAULT_DISABLED_TEXTURE = GuiTexture - .of(new ResourcePathImpl("minecraft", "textures/gui/sprites/widget/button_disabled.png"), DEFAULT_SIZE); + .of(new ResourcePathImpl("kit_tunes", "textures/gui/sprites/widget/button_disabled.png"), DEFAULT_SIZE); private static final GuiTexture DEFAULT_UNHIGLIGHTED_TEXTURE = GuiTexture - .of(new ResourcePathImpl("minecraft", "textures/gui/sprites/widget/button.png"), DEFAULT_SIZE); + .of(new ResourcePathImpl("kit_tunes", "textures/gui/sprites/widget/button.png"), DEFAULT_SIZE); private static final GuiTexture DEFAULT_HIGHLIGHTED_TEXTURE = GuiTexture - .of(new ResourcePathImpl("minecraft", "textures/gui/sprites/widget/button_highlighted.png"), DEFAULT_SIZE); + .of(new ResourcePathImpl("kit_tunes", "textures/gui/sprites/widget/button_highlighted.png"), DEFAULT_SIZE); private final ButtonBackground background; private final RectangularSurface surface; diff --git a/kitten-heart/src/main/java/net/pixaurora/kitten_heart/impl/config/ScrobblerCache.java b/kitten-heart/src/main/java/net/pixaurora/kitten_heart/impl/config/ScrobblerCache.java index 0d56d42..5312d89 100644 --- a/kitten-heart/src/main/java/net/pixaurora/kitten_heart/impl/config/ScrobblerCache.java +++ b/kitten-heart/src/main/java/net/pixaurora/kitten_heart/impl/config/ScrobblerCache.java @@ -75,7 +75,7 @@ public ScrobblerCache deserialize(JsonElement json, Type _type, JsonDeserializat throws JsonParseException { ArrayList scrobblers = new ArrayList<>(); - for (JsonElement scrobblerData : json.getAsJsonArray().asList()) { + for (JsonElement scrobblerData : json.getAsJsonArray()) { Scrobbler scrobbler = context.deserialize(scrobblerData, Scrobbler.class); scrobblers.add(scrobbler); } diff --git a/kitten-square/r1.17.0/build.gradle.kts b/kitten-square/r1.17.0/build.gradle.kts new file mode 100644 index 0000000..73296ef --- /dev/null +++ b/kitten-square/r1.17.0/build.gradle.kts @@ -0,0 +1,21 @@ +plugins { + id("kit_tunes.java.16") + id("kit_tunes.module") +} + +repositories { + maven { + name = "Terraformers" + url = uri("https://maven.terraformersmc.com/") + } +} + +dependencies { + implementation(project(":kit-tunes-api")) + implementation(project(":kitten-heart")) + + modImplementation(libs.qsl.resource.loader) + + modImplementation("com.terraformersmc:modmenu:${project.property("modmenu_version")}") + modImplementation(fabricApi.module("fabric-resource-loader-v0", project.property("fabric_api_version").toString())) +} diff --git a/kitten-square/r1.17.0/gradle.properties b/kitten-square/r1.17.0/gradle.properties new file mode 100644 index 0000000..4bfe845 --- /dev/null +++ b/kitten-square/r1.17.0/gradle.properties @@ -0,0 +1,8 @@ +# Mod properties +sub_mod_name = ui +minecraft_version_min = 1.17.0 + +minecraft_version = 1.17 + +modmenu_version=2.0.17 +fabric_api_version=0.36.0+1.17 diff --git a/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/FakeComponent.java b/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/FakeComponent.java new file mode 100644 index 0000000..509ac55 --- /dev/null +++ b/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/FakeComponent.java @@ -0,0 +1,22 @@ +package net.pixaurora.kitten_square.impl; + +import net.minecraft.network.chat.MutableComponent; +import net.pixaurora.kitten_cube.impl.text.Component; +import net.pixaurora.kitten_square.impl.service.UICompatImpl; + +public class FakeComponent implements Component { + private final MutableComponent parent; + + public FakeComponent(MutableComponent component) { + this.parent = component; + } + + public MutableComponent gameVer() { + return this.parent; + } + + @Override + public Component concat(Component component) { + return new FakeComponent(this.parent.copy().append(UICompatImpl.internalToMinecraftType(component))); + } +} diff --git a/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/SoundUtil.java b/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/SoundUtil.java new file mode 100644 index 0000000..4420931 --- /dev/null +++ b/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/SoundUtil.java @@ -0,0 +1,17 @@ +package net.pixaurora.kitten_square.impl; + +import net.minecraft.client.resources.sounds.SimpleSoundInstance; +import net.minecraft.client.resources.sounds.SoundInstance; +import net.minecraft.sounds.SoundEvents; +import net.pixaurora.kitten_cube.impl.ui.sound.Sound; + +public class SoundUtil { + public static SoundInstance soundFromInternalID(Sound sound) { + switch (sound) { + case BUTTON_CLICK: + return SimpleSoundInstance.forUI(SoundEvents.UI_BUTTON_CLICK, 1.0F); + default: + throw new RuntimeException("Sound " + sound.name() + " was not mapped!"); + } + } +} diff --git a/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/compat/ModMenuIntegration.java b/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/compat/ModMenuIntegration.java new file mode 100644 index 0000000..03bf3f0 --- /dev/null +++ b/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/compat/ModMenuIntegration.java @@ -0,0 +1,23 @@ +package net.pixaurora.kitten_square.impl.compat; + +import java.util.Map; + +import com.terraformersmc.modmenu.api.ConfigScreenFactory; +import com.terraformersmc.modmenu.api.ModMenuApi; + +import net.minecraft.client.gui.screens.Screen; +import net.pixaurora.kitten_heart.impl.Constants; +import net.pixaurora.kitten_heart.impl.ui.screen.KitTunesHomeScreen; +import net.pixaurora.kitten_square.impl.ui.screen.MinecraftScreen; +import net.pixaurora.kitten_square.impl.ui.screen.ScreenImpl; + +public class ModMenuIntegration implements ModMenuApi { + public ScreenImpl modHomeScreen(Screen parent) { + return new ScreenImpl(new KitTunesHomeScreen(new MinecraftScreen(parent))); + } + + @Override + public Map> getProvidedConfigScreenFactories() { + return Map.of(Constants.MOD_ID, this::modHomeScreen); + } +} diff --git a/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/mixin/GuiMixin.java b/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/mixin/GuiMixin.java new file mode 100644 index 0000000..b66b429 --- /dev/null +++ b/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/mixin/GuiMixin.java @@ -0,0 +1,19 @@ +package net.pixaurora.kitten_square.impl.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.client.gui.Gui; +import net.minecraft.network.chat.Component; + +@Mixin(Gui.class) +public class GuiMixin { + // Because we want to show our own notification, we cancel this one so it + // doesn't show twice. + @Inject(method = "setNowPlaying", at = @At("HEAD"), cancellable = true) + private void cancelNowPlayingNotification(Component description, CallbackInfo cInfo) { + cInfo.cancel(); + } +} diff --git a/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/service/UICompatImpl.java b/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/service/UICompatImpl.java new file mode 100644 index 0000000..377464e --- /dev/null +++ b/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/service/UICompatImpl.java @@ -0,0 +1,124 @@ +package net.pixaurora.kitten_square.impl.service; + +import java.util.List; + +import net.minecraft.Util; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.screens.ConfirmLinkScreen; +import net.minecraft.network.chat.MutableComponent; +import net.minecraft.network.chat.TextComponent; +import net.minecraft.network.chat.TranslatableComponent; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.FormattedCharSequence; +import net.pixaurora.kit_tunes.api.resource.ResourcePath; +import net.pixaurora.kitten_cube.impl.math.Point; +import net.pixaurora.kitten_cube.impl.text.Color; +import net.pixaurora.kitten_cube.impl.text.Component; +import net.pixaurora.kitten_cube.impl.ui.screen.Screen; +import net.pixaurora.kitten_cube.impl.ui.sound.Sound; +import net.pixaurora.kitten_cube.impl.ui.widget.text.TextBox; +import net.pixaurora.kitten_heart.impl.resource.ResourcePathImpl; +import net.pixaurora.kitten_heart.impl.resource.ResourcePathUtils; +import net.pixaurora.kitten_heart.impl.service.MinecraftUICompat; +import net.pixaurora.kitten_square.impl.FakeComponent; +import net.pixaurora.kitten_square.impl.SoundUtil; +import net.pixaurora.kitten_square.impl.ui.screen.MinecraftScreen; +import net.pixaurora.kitten_square.impl.ui.screen.ScreenImpl; +import net.pixaurora.kitten_square.impl.ui.toast.ToastImpl; +import net.pixaurora.kitten_square.impl.ui.widget.TextBoxImpl; + +public class UICompatImpl implements MinecraftUICompat { + private final Minecraft client = Minecraft.getInstance(); + + public static ResourceLocation internalToMinecraftType(ResourcePath path) { + return new ResourceLocation(path.namespace(), path.path()); + } + + public static MutableComponent internalToMinecraftType(Component component) { + if (component instanceof FakeComponent) { + return ((FakeComponent) component).gameVer(); + } else { + throw new RuntimeException( + "Internal component is of an unconvertable type `" + component.getClass().getName() + "`!"); + } + } + + @Override + public void sendToast(net.pixaurora.kitten_cube.impl.ui.toast.Toast toast) { + this.client.getToasts().addToast(new ToastImpl(toast)); + } + + @Override + public ResourcePath convertToRegularAsset(ResourcePath path) { + return path; + } + + @Override + public ResourcePath convertToGuiAsset(ResourcePath path) { + return path; + } + + @Override + public Component translatable(String key) { + return new FakeComponent(new TranslatableComponent(key)); + } + + @Override + public Component translatableWithFallback(String key, String defaultText) { + return new FakeComponent(new TranslatableComponent(key)); + } + + @Override + public Component literal(String text) { + return new FakeComponent(new TextComponent(text)); + } + + @Override + public int textHeight() { + return this.client.font.lineHeight; + } + + @Override + public int textWidth(Component text) { + return this.client.font.width(internalToMinecraftType(text)); + } + + @Override + public void playSound(Sound sound) { + this.client.getSoundManager().play(SoundUtil.soundFromInternalID(sound)); + } + + @Override + public void setScreen(Screen screen) { + net.minecraft.client.gui.screens.Screen mcScreen; + if (screen instanceof MinecraftScreen) { + mcScreen = ((MinecraftScreen) screen).parent(); + } else { + mcScreen = new ScreenImpl(screen); + } + this.client.setScreen(mcScreen); + } + + @Override + public void confirmURL(String url) { + confirmLinkNow(this.client.screen, url); + } + + private void confirmLinkNow(net.minecraft.client.gui.screens.Screen screen, String url) { + this.client.setScreen(new ConfirmLinkScreen((result) -> { + if (result) { + Util.getPlatform().openUri(url); + } + + this.client.setScreen(screen); + }, url, true)); + } + + @Override + public TextBox createTextbox(List lines, Color color, int maxLineLength, Point pos) { + List text = lines.stream().map(UICompatImpl::internalToMinecraftType) + .flatMap(line -> this.client.font.split(line, maxLineLength).stream()).toList(); + + return new TextBoxImpl(text, color, pos); + } +} diff --git a/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/ui/ConversionCacheImpl.java b/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/ui/ConversionCacheImpl.java new file mode 100644 index 0000000..c4e443e --- /dev/null +++ b/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/ui/ConversionCacheImpl.java @@ -0,0 +1,20 @@ +package net.pixaurora.kitten_square.impl.ui; + +import net.minecraft.resources.ResourceLocation; +import net.pixaurora.kit_tunes.api.resource.ResourcePath; +import net.pixaurora.kitten_cube.impl.ConversionCache; +import net.pixaurora.kitten_square.impl.service.UICompatImpl; + +public class ConversionCacheImpl extends ConversionCache { + @Override + protected ResourceLocation resourceToMinecraftType(ResourcePath path) { + return UICompatImpl.internalToMinecraftType(path); + } + + @Override + protected net.minecraft.network.chat.Component componentToMinecraftType( + net.pixaurora.kitten_cube.impl.text.Component component) { + return UICompatImpl.internalToMinecraftType(component); + } + +} diff --git a/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/ui/display/GuiDisplayImpl.java b/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/ui/display/GuiDisplayImpl.java new file mode 100644 index 0000000..2e83ae2 --- /dev/null +++ b/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/ui/display/GuiDisplayImpl.java @@ -0,0 +1,67 @@ +package net.pixaurora.kitten_square.impl.ui.display; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiComponent; +import net.minecraft.util.FormattedCharSequence; +import net.pixaurora.kit_tunes.api.resource.ResourcePath; +import net.pixaurora.kitten_cube.impl.MinecraftClient; +import net.pixaurora.kitten_cube.impl.math.Point; +import net.pixaurora.kitten_cube.impl.math.Size; +import net.pixaurora.kitten_cube.impl.text.Color; +import net.pixaurora.kitten_cube.impl.text.Component; +import net.pixaurora.kitten_cube.impl.ui.display.GuiDisplay; +import net.pixaurora.kitten_cube.impl.ui.widget.text.TextBox; +import net.pixaurora.kitten_square.impl.ui.ConversionCacheImpl; +import net.pixaurora.kitten_square.impl.ui.widget.TextBoxImpl; + +public class GuiDisplayImpl implements GuiDisplay { + private final PoseStack poseStack; + + private final ConversionCacheImpl conversions; + + public GuiDisplayImpl(PoseStack poseStack, ConversionCacheImpl conversions) { + this.poseStack = poseStack; + this.conversions = conversions; + } + + @Override + public void drawTexture(ResourcePath path, Size size, Point pos) { + int width = size.width(); + int height = size.height(); + + RenderSystem.setShaderTexture(0, conversions.convert(path)); + GuiComponent.blit(poseStack, pos.x(), pos.y(), 0, 0.0F, 0.0F, width, height, width, height); + } + + @Override + public void drawGuiTextureSubsection(ResourcePath path, Size size, Point pos, Size subsection, Point offset) { + RenderSystem.setShaderTexture(0, conversions.convert(path)); + GuiComponent.blit(poseStack, pos.x(), pos.y(), offset.x(), offset.y(), subsection.width(), subsection.height(), size.width(), size.height()); + } + + @SuppressWarnings("resource") + @Override + public void drawText(Component text, Color color, Point pos, boolean shadowed) { + GuiComponent.drawString(poseStack, Minecraft.getInstance().font, conversions.convert(text), pos.x(), pos.y(), color.hex()); + } + + @SuppressWarnings("resource") + @Override + public void drawTextBox(TextBox textBox) { + if (textBox instanceof TextBoxImpl) { + TextBoxImpl impl = (TextBoxImpl) textBox; + + int y = impl.startPos.y(); + + for (FormattedCharSequence line : impl.lines) { + GuiComponent.drawString(poseStack, Minecraft.getInstance().font, line, impl.startPos.x(), y, impl.color.hex()); + + y += MinecraftClient.textHeight(); + } + } else { + throw new UnsupportedOperationException("Unsupported instance of textbox"); + } + } +} diff --git a/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/ui/screen/MinecraftScreen.java b/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/ui/screen/MinecraftScreen.java new file mode 100644 index 0000000..d0b793f --- /dev/null +++ b/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/ui/screen/MinecraftScreen.java @@ -0,0 +1,31 @@ +package net.pixaurora.kitten_square.impl.ui.screen; + +import net.pixaurora.kitten_cube.impl.math.Point; +import net.pixaurora.kitten_cube.impl.math.Size; +import net.pixaurora.kitten_cube.impl.ui.display.GuiDisplay; +import net.pixaurora.kitten_cube.impl.ui.screen.Screen; + +public class MinecraftScreen implements Screen { + private final net.minecraft.client.gui.screens.Screen parent; + + public MinecraftScreen(net.minecraft.client.gui.screens.Screen parent) { + this.parent = parent; + } + + @Override + public void draw(GuiDisplay gui, Point mousePos) { + } + + @Override + public void init(Size window) { + throw new RuntimeException("This isn't a real Kit Tunes screen!"); + } + + @Override + public void handleClick(Point mousePos, int button) { + } + + public net.minecraft.client.gui.screens.Screen parent() { + return this.parent; + } +} diff --git a/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/ui/screen/ScreenImpl.java b/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/ui/screen/ScreenImpl.java new file mode 100644 index 0000000..e8c1bba --- /dev/null +++ b/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/ui/screen/ScreenImpl.java @@ -0,0 +1,66 @@ +package net.pixaurora.kitten_square.impl.ui.screen; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.network.chat.Component; +import net.pixaurora.kitten_cube.impl.math.Point; +import net.pixaurora.kitten_cube.impl.math.Size; +import net.pixaurora.kitten_cube.impl.ui.display.GuiDisplay; +import net.pixaurora.kitten_cube.impl.ui.screen.Screen; +import net.pixaurora.kitten_square.impl.ui.ConversionCacheImpl; +import net.pixaurora.kitten_square.impl.ui.display.GuiDisplayImpl; + +public class ScreenImpl extends net.minecraft.client.gui.screens.Screen { + private final Screen screen; + + private final ConversionCacheImpl conversions; + + public ScreenImpl(Screen screen) { + super(Component.nullToEmpty(null)); + + this.screen = screen; + + this.conversions = new ConversionCacheImpl(); + } + + // "Minecraft Screen" functions + + @Override + public void init() { + this.screen.init(Size.of(this.width, this.height)); + } + + @Override + public void render(PoseStack poseStack, int mouseX, int mouseY, float delta) { + this.renderDirtBackground(0); + super.render(poseStack, mouseX, mouseY, delta); + + GuiDisplay display = new GuiDisplayImpl(poseStack, this.conversions); + Point mousePos = Point.of(mouseX, mouseY); + + this.screen.draw(display, mousePos); + } + + @Override + public void onClose() { + this.screen.onExit(); + } + + @Override + public boolean shouldCloseOnEsc() { + return true; + } + + @Override + public boolean mouseClicked(double x, double y, int button) { + Point mousePos = Point.of((int) x, (int) y); + + this.screen.handleClick(mousePos, button); + + return false; + } + + @Override + public void tick() { + this.screen.tick(); + } +} diff --git a/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/ui/toast/ToastImpl.java b/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/ui/toast/ToastImpl.java new file mode 100644 index 0000000..d56cb19 --- /dev/null +++ b/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/ui/toast/ToastImpl.java @@ -0,0 +1,46 @@ +package net.pixaurora.kitten_square.impl.ui.toast; + +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.gui.components.toasts.Toast; +import net.minecraft.client.gui.components.toasts.ToastComponent; +import net.pixaurora.kitten_square.impl.ui.ConversionCacheImpl; +import net.pixaurora.kitten_square.impl.ui.display.GuiDisplayImpl; + +public class ToastImpl implements Toast { + private final net.pixaurora.kitten_cube.impl.ui.toast.Toast toast; + private final long millisecondsShown; + + private final ConversionCacheImpl conversions; + + private boolean hasRendered; + private long firstRenderedTime; + + public ToastImpl(net.pixaurora.kitten_cube.impl.ui.toast.Toast toast) { + this.toast = toast; + this.millisecondsShown = toast.timeShown().toMillis(); + this.conversions = new ConversionCacheImpl(); + } + + @Override + public int width() { + return this.toast.size().width(); + } + + @Override + public int height() { + return this.toast.size().height(); + } + + @Override + public Toast.Visibility render(PoseStack poseStack, ToastComponent manager, long frameTime) { + if (!this.hasRendered) { + this.hasRendered = true; + this.firstRenderedTime = frameTime; + } + + this.toast.draw(new GuiDisplayImpl(poseStack, conversions)); + + return frameTime - this.firstRenderedTime < this.millisecondsShown ? Toast.Visibility.SHOW + : Toast.Visibility.HIDE; + } +} diff --git a/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/ui/widget/TextBoxImpl.java b/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/ui/widget/TextBoxImpl.java new file mode 100644 index 0000000..2b0b5a0 --- /dev/null +++ b/kitten-square/r1.17.0/src/main/java/net/pixaurora/kitten_square/impl/ui/widget/TextBoxImpl.java @@ -0,0 +1,35 @@ +package net.pixaurora.kitten_square.impl.ui.widget; + +import java.util.List; + +import net.minecraft.client.Minecraft; +import net.minecraft.util.FormattedCharSequence; +import net.pixaurora.kitten_cube.impl.MinecraftClient; +import net.pixaurora.kitten_cube.impl.math.Point; +import net.pixaurora.kitten_cube.impl.math.Size; +import net.pixaurora.kitten_cube.impl.text.Color; +import net.pixaurora.kitten_cube.impl.ui.widget.text.TextBox; + +public class TextBoxImpl implements TextBox { + public final List lines; + public final Color color; + public final Point startPos; + + public TextBoxImpl(List lines, Color color, Point startPos) { + this.lines = lines; + this.color = color; + this.startPos = startPos; + } + + @SuppressWarnings("resource") + @Override + public Size size() { + int width = 0; + + for (FormattedCharSequence line : lines) { + width = Math.max(width, Minecraft.getInstance().font.width(line)); + } + + return Size.of(width, MinecraftClient.textHeight() * lines.size()); + } +} diff --git a/kitten-square/r1.17.0/src/main/resources/META-INF/services/net.pixaurora.kitten_heart.impl.service.MinecraftUICompat b/kitten-square/r1.17.0/src/main/resources/META-INF/services/net.pixaurora.kitten_heart.impl.service.MinecraftUICompat new file mode 100644 index 0000000..f8e21a9 --- /dev/null +++ b/kitten-square/r1.17.0/src/main/resources/META-INF/services/net.pixaurora.kitten_heart.impl.service.MinecraftUICompat @@ -0,0 +1 @@ +net.pixaurora.kitten_square.impl.service.UICompatImpl diff --git a/kitten-square/r1.17.0/src/main/resources/kitten_square.mixins.json b/kitten-square/r1.17.0/src/main/resources/kitten_square.mixins.json new file mode 100644 index 0000000..26425ab --- /dev/null +++ b/kitten-square/r1.17.0/src/main/resources/kitten_square.mixins.json @@ -0,0 +1,13 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "net.pixaurora.kitten_square.impl.mixin", + "compatibilityLevel": "JAVA_16", + "mixins": [], + "client": [ + "GuiMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/kitten-square/r1.17.0/src/main/resources/quilt.mod.json b/kitten-square/r1.17.0/src/main/resources/quilt.mod.json new file mode 100644 index 0000000..425ffb2 --- /dev/null +++ b/kitten-square/r1.17.0/src/main/resources/quilt.mod.json @@ -0,0 +1,50 @@ +{ + "schema_version": 1, + "quilt_loader": { + "group": "net.pixaurora", + "id": "kitten_square", + "version": "${version}", + "metadata": { + "name": "Kitten Square", + "description": "The things you see!", + "contributors": { + "Pixaurora": "Owner", + "LostLuma": "Contributor" + }, + "contact": { + "homepage": "https://github.com/Pixaurora/Kit-Tunes", + "issues": "https://github.com/Pixaurora/Kit-Tunes/issues", + "sources": "https://github.com/Pixaurora/Kit-Tunes" + } + }, + "intermediate_mappings": "net.fabricmc:intermediary", + "entrypoints": { + "modmenu": [ + "net.pixaurora.kitten_square.impl.compat.ModMenuIntegration" + ] + }, + "depends": [ + { + "id": "quilt_loader", + "versions": ">=0.26.0" + }, + { + "id": "minecraft", + "versions": { + "all": [">=1.17.0", "<=1.17.1"] + } + }, + { + "id": "fabric-resource-loader-v0", + "versions": "*" + } + ] + }, + "mixin": "kitten_square.mixins.json", + "modmenu": { + "parent": "kit_tunes", + "badges": [ + "library" + ] + } +} diff --git a/kitten-square/r1.20.4/src/main/resources/kitten_square.mixins.json b/kitten-square/r1.20.4/src/main/resources/kitten_square.mixins.json index 9943f5a..cf3533d 100644 --- a/kitten-square/r1.20.4/src/main/resources/kitten_square.mixins.json +++ b/kitten-square/r1.20.4/src/main/resources/kitten_square.mixins.json @@ -3,7 +3,7 @@ "minVersion": "0.8", "package": "net.pixaurora.kitten_square.impl.mixin", "compatibilityLevel": "JAVA_17", - "mixins": [ ], + "mixins": [], "client": [ "GuiMixin" ], diff --git a/kitten-square/r1.21.0/src/main/resources/kitten_square.mixins.json b/kitten-square/r1.21.0/src/main/resources/kitten_square.mixins.json index d3e780f..0b70321 100644 --- a/kitten-square/r1.21.0/src/main/resources/kitten_square.mixins.json +++ b/kitten-square/r1.21.0/src/main/resources/kitten_square.mixins.json @@ -3,7 +3,7 @@ "minVersion": "0.8", "package": "net.pixaurora.kitten_square.impl.mixin", "compatibilityLevel": "JAVA_21", - "mixins": [ ], + "mixins": [], "client": [ "GuiMixin" ], diff --git a/kitten-star/r1.17.0/build.gradle.kts b/kitten-star/r1.17.0/build.gradle.kts new file mode 100644 index 0000000..78e5754 --- /dev/null +++ b/kitten-star/r1.17.0/build.gradle.kts @@ -0,0 +1,9 @@ +plugins { + id("kit_tunes.java.17") + id("kit_tunes.module") +} + +dependencies { + implementation(project(":kit-tunes-api")) + implementation(project(":kitten-heart")) +} diff --git a/kitten-star/r1.17.0/gradle.properties b/kitten-star/r1.17.0/gradle.properties new file mode 100644 index 0000000..e1049a3 --- /dev/null +++ b/kitten-star/r1.17.0/gradle.properties @@ -0,0 +1,5 @@ +# Mod properties +sub_mod_name = star +minecraft_version_min = 1.17.0 + +minecraft_version = 1.17 diff --git a/kitten-star/r1.17.0/src/main/java/net/pixaurora/kitten_star/impl/MusicPolling.java b/kitten-star/r1.17.0/src/main/java/net/pixaurora/kitten_star/impl/MusicPolling.java new file mode 100644 index 0000000..910729d --- /dev/null +++ b/kitten-star/r1.17.0/src/main/java/net/pixaurora/kitten_star/impl/MusicPolling.java @@ -0,0 +1,60 @@ +package net.pixaurora.kitten_star.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import net.minecraft.client.resources.sounds.SoundInstance; +import net.minecraft.client.sounds.ChannelAccess; +import net.minecraft.client.sounds.SoundEventListener; +import net.minecraft.client.sounds.WeighedSoundEvents; +import net.minecraft.client.sounds.ChannelAccess.ChannelHandle; +import net.minecraft.sounds.SoundSource; +import net.pixaurora.kitten_heart.impl.EventHandling; +import net.pixaurora.kitten_heart.impl.music.progress.PolledListeningProgress; +import net.pixaurora.kitten_heart.impl.music.progress.SongProgressTracker; +import net.pixaurora.kitten_heart.impl.util.Pair; + +public class MusicPolling implements SoundEventListener { + private static List> TRACKS_TO_POLL = new ArrayList<>(); + private static List> POLLED_TRACKS = new ArrayList<>(); + + @Override + public void onPlaySound(SoundInstance sound, WeighedSoundEvents soundSet) { + SoundSource source = sound.getSource(); + if (source == SoundSource.MUSIC || source == SoundSource.RECORDS) { + PolledListeningProgress progress = EventHandling + .handleTrackStart(SoundEventsUtils.minecraftTypeToInternalType(sound.getSound().getLocation())); + + TRACKS_TO_POLL.add(Pair.of(sound, progress)); + } + } + + public static void pollTrackProgress(Map instanceToChannel) { + TRACKS_TO_POLL.removeIf((soundAndProgress) -> { + Optional channel = Optional.ofNullable(instanceToChannel.get(soundAndProgress.first())); + + if (channel.isPresent()) { + POLLED_TRACKS.add(Pair.of(channel.get(), soundAndProgress.second())); + + return true; + } else { + return false; + } + }); + + POLLED_TRACKS.removeIf((channelAndProgress) -> { + if (channelAndProgress.first().isStopped()) { + EventHandling.handleTrackEnd(channelAndProgress.second()); + + return true; + } else { + channelAndProgress.first().execute( + channel -> channelAndProgress.second().measureProgress((SongProgressTracker) (Object) channel)); + + return false; + } + }); + } +} diff --git a/kitten-star/r1.17.0/src/main/java/net/pixaurora/kitten_star/impl/SoundEventsUtils.java b/kitten-star/r1.17.0/src/main/java/net/pixaurora/kitten_star/impl/SoundEventsUtils.java new file mode 100644 index 0000000..b0226c1 --- /dev/null +++ b/kitten-star/r1.17.0/src/main/java/net/pixaurora/kitten_star/impl/SoundEventsUtils.java @@ -0,0 +1,11 @@ +package net.pixaurora.kitten_star.impl; + +import net.minecraft.resources.ResourceLocation; +import net.pixaurora.kit_tunes.api.resource.ResourcePath; +import net.pixaurora.kitten_heart.impl.resource.ResourcePathImpl; + +public class SoundEventsUtils { + public static ResourcePath minecraftTypeToInternalType(ResourceLocation identifier) { + return new ResourcePathImpl(identifier.getNamespace(), identifier.getPath()); + } +} diff --git a/kitten-star/r1.17.0/src/main/java/net/pixaurora/kitten_star/impl/mixin/ChannelMixin.java b/kitten-star/r1.17.0/src/main/java/net/pixaurora/kitten_star/impl/mixin/ChannelMixin.java new file mode 100644 index 0000000..d44ef19 --- /dev/null +++ b/kitten-star/r1.17.0/src/main/java/net/pixaurora/kitten_star/impl/mixin/ChannelMixin.java @@ -0,0 +1,37 @@ +package net.pixaurora.kitten_star.impl.mixin; + +import org.lwjgl.openal.AL10; +import org.lwjgl.openal.AL11; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.mojang.blaze3d.audio.Channel; + +import net.pixaurora.kitten_heart.impl.music.progress.SongProgressTracker; + +@Mixin(Channel.class) +public class ChannelMixin implements SongProgressTracker { + @Shadow + @Final + private int source; + + private int completedBufferCount = 0; + + @Inject(method = "pumpBuffers", at = @At("HEAD")) + private void trackCompletedBuffers(int bufferCount, CallbackInfo ci) { + this.completedBufferCount += bufferCount; + } + + private float trackedSeconds() { + return Channel.BUFFER_DURATION_SECONDS * this.completedBufferCount; + } + + @Override + public float kit_tunes$playbackPosition() { + return this.trackedSeconds() + AL10.alGetSourcef(this.source, AL11.AL_SEC_OFFSET); + } +} diff --git a/kitten-star/r1.17.0/src/main/java/net/pixaurora/kitten_star/impl/mixin/MinecraftMixin.java b/kitten-star/r1.17.0/src/main/java/net/pixaurora/kitten_star/impl/mixin/MinecraftMixin.java new file mode 100644 index 0000000..32c4a13 --- /dev/null +++ b/kitten-star/r1.17.0/src/main/java/net/pixaurora/kitten_star/impl/mixin/MinecraftMixin.java @@ -0,0 +1,32 @@ +package net.pixaurora.kitten_star.impl.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.client.Minecraft; +import net.pixaurora.kitten_heart.impl.KitTunes; +import net.pixaurora.kitten_star.impl.MusicPolling; + +@Mixin(Minecraft.class) +public class MinecraftMixin { + @SuppressWarnings("resource") + @Inject(method = "", at = @At("TAIL")) + public void addMusicListener(CallbackInfo ci) { + Minecraft client = (Minecraft) (Object) this; + client.getSoundManager().addListener(new MusicPolling()); + + KitTunes.init(); + } + + @Inject(method = "tick", at = @At("HEAD")) + public void onTick(CallbackInfo ci) { + KitTunes.tick(); + } + + @Inject(method = "destroy", at = @At("HEAD")) + public void onStop(CallbackInfo ci) { + KitTunes.stop(); + } +} diff --git a/kitten-star/r1.17.0/src/main/java/net/pixaurora/kitten_star/impl/mixin/SoundEngineMixin.java b/kitten-star/r1.17.0/src/main/java/net/pixaurora/kitten_star/impl/mixin/SoundEngineMixin.java new file mode 100644 index 0000000..eeecb01 --- /dev/null +++ b/kitten-star/r1.17.0/src/main/java/net/pixaurora/kitten_star/impl/mixin/SoundEngineMixin.java @@ -0,0 +1,27 @@ +package net.pixaurora.kitten_star.impl.mixin; + +import java.util.Map; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import net.minecraft.client.resources.sounds.SoundInstance; +import net.minecraft.client.sounds.ChannelAccess; +import net.minecraft.client.sounds.SoundEngine; +import net.pixaurora.kitten_star.impl.MusicPolling; + +@Mixin(SoundEngine.class) +public class SoundEngineMixin { + @Shadow + @Final + public Map instanceToChannel; + + @Inject(method = "tick", at = @At("HEAD")) + public void onTick(CallbackInfo cInfo) { + MusicPolling.pollTrackProgress(instanceToChannel); + } +} diff --git a/kitten-star/r1.17.0/src/main/resources/kitten_star.mixins.json b/kitten-star/r1.17.0/src/main/resources/kitten_star.mixins.json new file mode 100644 index 0000000..272d0b4 --- /dev/null +++ b/kitten-star/r1.17.0/src/main/resources/kitten_star.mixins.json @@ -0,0 +1,15 @@ +{ + "required": true, + "minVersion": "0.8", + "package": "net.pixaurora.kitten_star.impl.mixin", + "compatibilityLevel": "JAVA_16", + "mixins": [], + "client": [ + "ChannelMixin", + "MinecraftMixin", + "SoundEngineMixin" + ], + "injectors": { + "defaultRequire": 1 + } +} diff --git a/kitten-star/r1.17.0/src/main/resources/quilt.mod.json b/kitten-star/r1.17.0/src/main/resources/quilt.mod.json new file mode 100644 index 0000000..448ec33 --- /dev/null +++ b/kitten-star/r1.17.0/src/main/resources/quilt.mod.json @@ -0,0 +1,45 @@ +{ + "schema_version": 1, + "quilt_loader": { + "group": "net.pixaurora", + "id": "kitten_star", + "version": "${version}", + "metadata": { + "name": "Kitten Star", + "description": "Hooks into the game's code to send sound events for API consumers.", + "contributors": { + "Pixaurora": "Owner", + "LostLuma": "Contributor" + }, + "contact": { + "homepage": "https://github.com/Pixaurora/Kit-Tunes", + "issues": "https://github.com/Pixaurora/Kit-Tunes/issues", + "sources": "https://github.com/Pixaurora/Kit-Tunes" + } + }, + "intermediate_mappings": "net.fabricmc:intermediary", + "depends": [ + { + "id": "quilt_loader", + "versions": ">=0.26.0" + }, + { + "id": "minecraft", + "versions": { + "all": [ ">=1.17.0", "<=1.17.1" ] + } + }, + { + "id": "fabric-resource-loader-v0", + "versions": "*" + } + ] + }, + "mixin": "kitten_star.mixins.json", + "modmenu": { + "parent": "kit_tunes", + "badges": [ + "library" + ] + } +} diff --git a/kitten-star/r1.20.4/src/main/resources/kitten_star.mixins.json b/kitten-star/r1.20.4/src/main/resources/kitten_star.mixins.json index f73effa..33e9390 100644 --- a/kitten-star/r1.20.4/src/main/resources/kitten_star.mixins.json +++ b/kitten-star/r1.20.4/src/main/resources/kitten_star.mixins.json @@ -3,7 +3,7 @@ "minVersion": "0.8", "package": "net.pixaurora.kitten_star.impl.mixin", "compatibilityLevel": "JAVA_17", - "mixins": [ ], + "mixins": [], "client": [ "ChannelMixin", "MinecraftMixin", diff --git a/settings.gradle.kts b/settings.gradle.kts index d162031..05d2746 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -24,7 +24,9 @@ include("kit-tunes") include("kit-tunes-api") include("kitten-heart") +include("kitten-star:r1.17.0") include("kitten-star:r1.20.4") +include("kitten-square:r1.17.0") include("kitten-square:r1.20.4") include("kitten-square:r1.21.0")