diff --git a/src/main/java/com/falsepattern/lib/internal/FalsePatternLib.java b/src/main/java/com/falsepattern/lib/internal/FalsePatternLib.java index b5b8bf9..8b990d4 100644 --- a/src/main/java/com/falsepattern/lib/internal/FalsePatternLib.java +++ b/src/main/java/com/falsepattern/lib/internal/FalsePatternLib.java @@ -23,6 +23,7 @@ package com.falsepattern.lib.internal; import com.falsepattern.lib.internal.proxy.CommonProxy; import cpw.mods.fml.common.*; +import cpw.mods.fml.common.event.FMLConstructionEvent; import cpw.mods.fml.common.event.FMLPostInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; @@ -41,7 +42,7 @@ import org.apache.logging.log4j.Logger; name = Tags.MODNAME, version = Tags.VERSION, acceptedMinecraftVersions = "[1.7.10]", - guiFactory = Tags.GROUPNAME + ".internal.LibraryGuiFactory", + guiFactory = Tags.GROUPNAME + ".internal.config.LibraryGuiFactory", acceptableRemoteVersions = "*") public class FalsePatternLib { public static final String UPDATE_URL = "https://falsepattern.com/mc/versions.json"; @@ -58,6 +59,11 @@ public class FalsePatternLib { log.info("Version " + Tags.VERSION + " initialized!"); } + @Mod.EventHandler + public void construct(FMLConstructionEvent e) { + proxy.construct(e); + } + @Mod.EventHandler public void preInit(FMLPreInitializationEvent e) { proxy.preInit(e); diff --git a/src/main/java/com/falsepattern/lib/internal/LibraryConfig.java b/src/main/java/com/falsepattern/lib/internal/config/LibraryConfig.java similarity index 67% rename from src/main/java/com/falsepattern/lib/internal/LibraryConfig.java rename to src/main/java/com/falsepattern/lib/internal/config/LibraryConfig.java index 1e18a00..e648872 100644 --- a/src/main/java/com/falsepattern/lib/internal/LibraryConfig.java +++ b/src/main/java/com/falsepattern/lib/internal/config/LibraryConfig.java @@ -18,21 +18,24 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ -package com.falsepattern.lib.internal; +package com.falsepattern.lib.internal.config; import com.falsepattern.lib.config.Config; +import com.falsepattern.lib.internal.Tags; @Config(modid = Tags.MODID) public class LibraryConfig { @Config.Comment({"Used to control whether FalsePatternLib should check for outdated mods.", - "If you're building a public modpack, you should turn this off so that your users don't " + - "get nagged about outdated mods."}) + "If you're building a public modpack, you should turn this off so that your users don't " + + "get nagged about outdated mods."}) @Config.LangKey("config.falsepatternlib.updatecheck") - public static boolean ENABLE_UPDATE_CHECKER = true; + @Config.DefaultBoolean(true) + public static boolean ENABLE_UPDATE_CHECKER; @Config.Comment({"Used to control whether FalsePatternLib should be allowed to use the internet.", - "If this is disabled, library downloads will be blocked.", - "Note that if a mod tries to download a library that is not downloaded yet, the game will crash."}) + "If this is disabled, library downloads will be blocked.", + "Note that if a mod tries to download a library that is not downloaded yet, the game will crash."}) @Config.LangKey("config.falsepatternlib.disableinternet") - public static boolean ENABLE_LIBRARY_DOWNLOADS = true; + @Config.DefaultBoolean(true) + public static boolean ENABLE_LIBRARY_DOWNLOADS; } diff --git a/src/main/java/com/falsepattern/lib/internal/LibraryGuiConfig.java b/src/main/java/com/falsepattern/lib/internal/config/LibraryGuiConfig.java similarity index 86% rename from src/main/java/com/falsepattern/lib/internal/LibraryGuiConfig.java rename to src/main/java/com/falsepattern/lib/internal/config/LibraryGuiConfig.java index 3a292af..5d0ad96 100644 --- a/src/main/java/com/falsepattern/lib/internal/LibraryGuiConfig.java +++ b/src/main/java/com/falsepattern/lib/internal/config/LibraryGuiConfig.java @@ -18,10 +18,12 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ -package com.falsepattern.lib.internal; +package com.falsepattern.lib.internal.config; import com.falsepattern.lib.config.ConfigException; import com.falsepattern.lib.config.SimpleGuiConfig; +import com.falsepattern.lib.internal.Tags; + import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.client.gui.GuiScreen; @@ -29,6 +31,6 @@ import net.minecraft.client.gui.GuiScreen; @SideOnly(Side.CLIENT) public class LibraryGuiConfig extends SimpleGuiConfig { public LibraryGuiConfig(GuiScreen parent) throws ConfigException { - super(parent, LibraryConfig.class, Tags.MODID, Tags.MODNAME); + super(parent, new Class[]{LibraryConfig.class, ToastConfig.class}, Tags.MODID, Tags.MODNAME); } } diff --git a/src/main/java/com/falsepattern/lib/internal/LibraryGuiFactory.java b/src/main/java/com/falsepattern/lib/internal/config/LibraryGuiFactory.java similarity index 96% rename from src/main/java/com/falsepattern/lib/internal/LibraryGuiFactory.java rename to src/main/java/com/falsepattern/lib/internal/config/LibraryGuiFactory.java index 3bfc131..cbb33e0 100644 --- a/src/main/java/com/falsepattern/lib/internal/LibraryGuiFactory.java +++ b/src/main/java/com/falsepattern/lib/internal/config/LibraryGuiFactory.java @@ -18,7 +18,7 @@ * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ -package com.falsepattern.lib.internal; +package com.falsepattern.lib.internal.config; import com.falsepattern.lib.config.SimpleGuiFactory; import cpw.mods.fml.relauncher.Side; diff --git a/src/main/java/com/falsepattern/lib/internal/config/ToastConfig.java b/src/main/java/com/falsepattern/lib/internal/config/ToastConfig.java new file mode 100644 index 0000000..a32e8ac --- /dev/null +++ b/src/main/java/com/falsepattern/lib/internal/config/ToastConfig.java @@ -0,0 +1,55 @@ +/** + * Copyright (C) 2022 FalsePattern + * All Rights Reserved + * + * The above copyright notice, this permission notice and the word "SNEED" + * shall be included in all copies or substantial portions of the Software. + * + * 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 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 com.falsepattern.lib.internal.config; + +import com.falsepattern.lib.config.Config; +import com.falsepattern.lib.internal.Tags; + +@Config(modid = Tags.MODID, + category = "toasts") +public class ToastConfig { + @Config.Comment("The maximum amount of toasts to show on the screen") + @Config.LangKey("config.falsepatternlib.maxtoasts") + @Config.DefaultInt(5) + @Config.RangeInt(min = 1, + max = 10) + public static int MAX_VISIBLE; + + @Config.Comment("The amount of empty space from the top of the screen in pixels") + @Config.LangKey("config.falsepatternlib.toastoffset") + @Config.DefaultInt(0) + @Config.RangeInt(min = 0, + max = 10000) + public static int Y_OFFSET; + + @Config.Comment("Which side of the screen should toasts show up on") + @Config.LangKey("config.falsepatternlib.toastalign") + @Config.DefaultEnum("Right") + public static Side ALIGN; + + public static boolean leftAlign() { + return ALIGN == Side.Left; + } + + public enum Side { + Left, Right + } +} diff --git a/src/main/java/com/falsepattern/lib/internal/impl/dependencies/DependencyLoaderImpl.java b/src/main/java/com/falsepattern/lib/internal/impl/dependencies/DependencyLoaderImpl.java index c7ca12f..b670921 100644 --- a/src/main/java/com/falsepattern/lib/internal/impl/dependencies/DependencyLoaderImpl.java +++ b/src/main/java/com/falsepattern/lib/internal/impl/dependencies/DependencyLoaderImpl.java @@ -24,7 +24,7 @@ import com.falsepattern.lib.dependencies.DependencyLoader; import com.falsepattern.lib.dependencies.Version; import com.falsepattern.lib.internal.FalsePatternLib; import com.falsepattern.lib.internal.Internet; -import com.falsepattern.lib.internal.LibraryConfig; +import com.falsepattern.lib.internal.config.LibraryConfig; import com.falsepattern.lib.internal.Tags; import com.falsepattern.lib.util.FileUtil; import lombok.NonNull; diff --git a/src/main/java/com/falsepattern/lib/internal/impl/toast/GuiToastImpl.java b/src/main/java/com/falsepattern/lib/internal/impl/toast/GuiToastImpl.java new file mode 100644 index 0000000..4040e9b --- /dev/null +++ b/src/main/java/com/falsepattern/lib/internal/impl/toast/GuiToastImpl.java @@ -0,0 +1,186 @@ +/** + * Copyright (C) 2022 FalsePattern + * All Rights Reserved + *

+ * The above copyright notice, this permission notice and the word "SNEED" + * shall be included in all copies or substantial portions of the Software. + *

+ * 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 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 com.falsepattern.lib.internal.impl.toast; + +import com.falsepattern.lib.internal.config.LibraryConfig; +import com.falsepattern.lib.internal.config.ToastConfig; +import com.falsepattern.lib.toasts.IToast; +import com.falsepattern.lib.util.MathUtil; +import com.google.common.collect.Queues; +import lombok.val; +import lombok.var; +import org.lwjgl.opengl.GL11; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.ScaledResolution; +import net.minecraft.client.renderer.RenderHelper; +import cpw.mods.fml.common.FMLCommonHandler; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import cpw.mods.fml.common.gameevent.TickEvent; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import javax.annotation.Nullable; +import java.util.Arrays; +import java.util.Deque; + +@SideOnly(Side.CLIENT) +public class GuiToastImpl extends Gui { + private final Minecraft mc; + private final Deque toastsQueue = Queues.newArrayDeque(); + private ToastInstance[] visible = new ToastInstance[0]; + private static GuiToastImpl instance; + + public static void initialize(Minecraft mc) { + if (instance != null) { + return; + } + instance = new GuiToastImpl(mc); + FMLCommonHandler.instance().bus().register(instance); + } + + public static GuiToastImpl getInstance() { + return instance; + } + + @SubscribeEvent + public void updateToasts(TickEvent.RenderTickEvent event) { + if ( event.phase != TickEvent.Phase.END) { + return; + } + mc.mcProfiler.startSection("toasts"); + drawToast(new ScaledResolution(mc, mc.displayWidth, mc.displayHeight)); + mc.mcProfiler.endSection(); + } + + + public GuiToastImpl(Minecraft mcIn) { + this.mc = mcIn; + } + + public void drawToast(ScaledResolution resolution) { + if (!this.mc.gameSettings.hideGUI) { + RenderHelper.disableStandardItemLighting(); + if (ToastConfig.MAX_VISIBLE != visible.length) { + visible = Arrays.copyOf(visible, ToastConfig.MAX_VISIBLE); + } + + for (int i = 0; i < this.visible.length; ++i) { + val toast = this.visible[i]; + + if (toast != null && toast.render(ToastConfig.leftAlign() ? 0 : resolution.getScaledWidth(), i)) { + this.visible[i] = null; + } + + if (this.visible[i] == null && !this.toastsQueue.isEmpty()) { + this.visible[i] = new ToastInstance<>(this.toastsQueue.removeFirst()); + } + } + } + } + + @Nullable + public T getToast(Class toastClass, Object type) { + for (val toast : this.visible) { + if (toast != null && toastClass.isAssignableFrom(toast.getToast().getClass()) && + toast.getToast().getType().equals(type)) { + return toastClass.cast(toast); + } + } + + for (val toast : this.toastsQueue) { + if (toastClass.isAssignableFrom(toast.getClass()) && toast.getType().equals(type)) { + return toastClass.cast(toast); + } + } + + return null; + } + + public void clear() { + Arrays.fill(this.visible, null); + this.toastsQueue.clear(); + } + + public void add(IToast toastIn) { + this.toastsQueue.add(toastIn); + } + + public Minecraft getMinecraft() { + return this.mc; + } + + @SideOnly(Side.CLIENT) + class ToastInstance { + private final T toast; + private long animationTime; + private long visibleTime; + private IToast.Visibility visibility; + + private ToastInstance(T toastIn) { + this.animationTime = -1L; + this.visibleTime = -1L; + this.visibility = IToast.Visibility.SHOW; + this.toast = toastIn; + } + + public T getToast() { + return this.toast; + } + + private float getVisibility(long currentTime) { + var visibility = MathUtil.clamp((float) (currentTime - this.animationTime) / 600.0F, 0.0F, 1.0F); + visibility = visibility * visibility; + return this.visibility == IToast.Visibility.HIDE ? 1.0F - visibility : visibility; + } + + public boolean render(int x, int y) { + val sysTime = Minecraft.getSystemTime(); + + if (this.animationTime == -1L) { + this.animationTime = sysTime; + this.visibility.playSound(GuiToastImpl.this.mc.getSoundHandler()); + } + + if (this.visibility == IToast.Visibility.SHOW && sysTime - this.animationTime <= 600L) { + this.visibleTime = sysTime; + } + + GL11.glPushMatrix(); + val shift = toast.width() * getVisibility(sysTime); + val X = ToastConfig.leftAlign() ? shift - toast.width() : x - shift; + GL11.glTranslatef(X, + (float) (y * 32) + ToastConfig.Y_OFFSET, + (float) (500 + y)); + val visibility = this.toast.draw(GuiToastImpl.this, sysTime - this.visibleTime); + GL11.glPopMatrix(); + + if (visibility != this.visibility) { + this.animationTime = sysTime - (long) ((int) ((1.0F - this.getVisibility(sysTime)) * 600.0F)); + this.visibility = visibility; + this.visibility.playSound(GuiToastImpl.this.mc.getSoundHandler()); + } + + return this.visibility == IToast.Visibility.HIDE && sysTime - this.animationTime > 600L; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/falsepattern/lib/internal/proxy/ClientProxy.java b/src/main/java/com/falsepattern/lib/internal/proxy/ClientProxy.java index baedda4..cd1ab8b 100644 --- a/src/main/java/com/falsepattern/lib/internal/proxy/ClientProxy.java +++ b/src/main/java/com/falsepattern/lib/internal/proxy/ClientProxy.java @@ -22,18 +22,21 @@ package com.falsepattern.lib.internal.proxy; import com.falsepattern.lib.internal.FalsePatternLib; import com.falsepattern.lib.internal.Tags; +import com.falsepattern.lib.internal.impl.toast.GuiToastImpl; import com.falsepattern.lib.updates.UpdateChecker; -import cpw.mods.fml.client.IModGuiFactory; +import lombok.val; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.util.IChatComponent; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.EntityJoinWorldEvent; +import cpw.mods.fml.common.event.FMLConstructionEvent; import cpw.mods.fml.common.event.FMLPostInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; -import lombok.val; -import net.minecraft.client.entity.EntityPlayerSP; -import net.minecraft.util.IChatComponent; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.event.entity.EntityJoinWorldEvent; import java.util.Collections; import java.util.List; @@ -43,6 +46,12 @@ import java.util.concurrent.CompletableFuture; public class ClientProxy extends CommonProxy { private CompletableFuture> chatFuture; + @Override + public void construct(FMLConstructionEvent e) { + super.construct(e); + GuiToastImpl.initialize(Minecraft.getMinecraft()); + } + @Override public void preInit(FMLPreInitializationEvent e) { super.preInit(e); diff --git a/src/main/java/com/falsepattern/lib/internal/proxy/CommonProxy.java b/src/main/java/com/falsepattern/lib/internal/proxy/CommonProxy.java index 50ad1b0..a6f4795 100644 --- a/src/main/java/com/falsepattern/lib/internal/proxy/CommonProxy.java +++ b/src/main/java/com/falsepattern/lib/internal/proxy/CommonProxy.java @@ -23,10 +23,13 @@ package com.falsepattern.lib.internal.proxy; import com.falsepattern.lib.config.ConfigException; import com.falsepattern.lib.config.ConfigurationManager; import com.falsepattern.lib.internal.FalsePatternLib; -import com.falsepattern.lib.internal.LibraryConfig; +import com.falsepattern.lib.internal.config.LibraryConfig; +import com.falsepattern.lib.internal.config.ToastConfig; import com.falsepattern.lib.internal.impl.config.ConfigurationManagerImpl; import com.falsepattern.lib.updates.ModUpdateInfo; import com.falsepattern.lib.updates.UpdateChecker; + +import cpw.mods.fml.common.event.FMLConstructionEvent; import cpw.mods.fml.common.event.FMLPostInitializationEvent; import cpw.mods.fml.common.event.FMLPreInitializationEvent; import lombok.val; @@ -39,10 +42,14 @@ public class CommonProxy { protected CompletableFuture> updatesFuture; + public void construct(FMLConstructionEvent e) { + } + public void preInit(FMLPreInitializationEvent e) { ConfigurationManagerImpl.registerBus(); try { ConfigurationManager.registerConfig(LibraryConfig.class); + ConfigurationManager.registerConfig(ToastConfig.class); } catch (ConfigException ex) { FalsePatternLib.getLog().error("Failed to register config!", ex); } diff --git a/src/main/java/com/falsepattern/lib/toasts/GuiToast.java b/src/main/java/com/falsepattern/lib/toasts/GuiToast.java new file mode 100644 index 0000000..9f15bb8 --- /dev/null +++ b/src/main/java/com/falsepattern/lib/toasts/GuiToast.java @@ -0,0 +1,49 @@ +/** + * Copyright (C) 2022 FalsePattern + * All Rights Reserved + *

+ * The above copyright notice, this permission notice and the word "SNEED" + * shall be included in all copies or substantial portions of the Software. + *

+ * 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 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 com.falsepattern.lib.toasts; + +import com.falsepattern.lib.StableAPI; +import com.falsepattern.lib.internal.impl.toast.GuiToastImpl; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import javax.annotation.Nullable; + +@SideOnly(Side.CLIENT) +@StableAPI(since = "0.10.0") +public class GuiToast { + @StableAPI(since = "0.10.0") + @Nullable + public static T getToast(Class toastClass, Object type) { + return GuiToastImpl.getInstance().getToast(toastClass, type); + } + + @StableAPI(since = "0.10.0") + public static void clear() { + GuiToastImpl.getInstance().clear(); + } + + @StableAPI(since = "0.10.0") + public static void add(IToast toastIn) { + GuiToastImpl.getInstance().add(toastIn); + } +} diff --git a/src/main/java/com/falsepattern/lib/toasts/IToast.java b/src/main/java/com/falsepattern/lib/toasts/IToast.java new file mode 100644 index 0000000..c0b5309 --- /dev/null +++ b/src/main/java/com/falsepattern/lib/toasts/IToast.java @@ -0,0 +1,70 @@ +/** + * Copyright (C) 2022 FalsePattern + * All Rights Reserved + *

+ * The above copyright notice, this permission notice and the word "SNEED" + * shall be included in all copies or substantial portions of the Software. + *

+ * 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 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 com.falsepattern.lib.toasts; + +import com.falsepattern.lib.StableAPI; +import com.falsepattern.lib.internal.Tags; +import com.falsepattern.lib.internal.impl.toast.GuiToastImpl; + +import net.minecraft.client.audio.PositionedSoundRecord; +import net.minecraft.client.audio.SoundHandler; +import net.minecraft.util.ResourceLocation; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +@StableAPI(since = "0.10.0") +public interface IToast { + @StableAPI(since = "0.10.0") + Object NO_TOKEN = new Object(); + + @StableAPI(since = "0.10.0") + Visibility draw(GuiToastImpl toastGui, long delta); + + @StableAPI(since = "0.10.0") + int width(); + + @StableAPI(since = "0.10.0") + int height(); + + @StableAPI(since = "0.10.0") + default Object getType() { + return NO_TOKEN; + } + + @StableAPI(since = "0.10.0") + @SideOnly(Side.CLIENT) + enum Visibility { + SHOW(new ResourceLocation(Tags.MODID, "ui.toast.in")), + HIDE(new ResourceLocation(Tags.MODID, "ui.toast.out")); + + private final ResourceLocation sound; + + Visibility(ResourceLocation soundIn) { + this.sound = soundIn; + } + + @StableAPI(since = "0.10.0") + public void playSound(SoundHandler handler) { + handler.playSound(PositionedSoundRecord.func_147674_a(this.sound, 1.0F)); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/falsepattern/lib/toasts/SimpleToast.java b/src/main/java/com/falsepattern/lib/toasts/SimpleToast.java new file mode 100644 index 0000000..f06865e --- /dev/null +++ b/src/main/java/com/falsepattern/lib/toasts/SimpleToast.java @@ -0,0 +1,126 @@ +/** + * Copyright (C) 2022 FalsePattern + * All Rights Reserved + *

+ * The above copyright notice, this permission notice and the word "SNEED" + * shall be included in all copies or substantial portions of the Software. + *

+ * 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 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 com.falsepattern.lib.toasts; + +import com.falsepattern.lib.StableAPI; +import com.falsepattern.lib.internal.impl.toast.GuiToastImpl; +import com.falsepattern.lib.toasts.icon.ToastBG; +import com.falsepattern.lib.toasts.icon.ToastIcon; +import com.falsepattern.lib.util.MathUtil; +import lombok.NonNull; +import lombok.val; +import org.lwjgl.opengl.GL11; + +import net.minecraft.client.gui.Gui; +import net.minecraft.util.IChatComponent; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +import javax.annotation.Nullable; + +@SideOnly(Side.CLIENT) +@StableAPI(since = "0.10.0") +public class SimpleToast implements IToast { + private final ToastBG background; + private final ToastIcon icon; + private final String title; + private final String subtitle; + private final boolean hasProgressBar; + private final long timeout; + private IToast.Visibility visibility = IToast.Visibility.SHOW; + private long lastDelta; + private float displayedProgress; + private float currentProgress; + + @StableAPI(since = "0.10.0") + public SimpleToast(@NonNull ToastBG background, @Nullable ToastIcon icon, + IChatComponent titleComponent, @Nullable IChatComponent subtitleComponent, + boolean drawProgressBar, long timeout) { + this.background = background; + this.icon = icon; + this.title = titleComponent.getFormattedText(); + this.subtitle = subtitleComponent == null ? null : subtitleComponent.getFormattedText(); + this.hasProgressBar = drawProgressBar; + this.timeout = timeout; + } + + @Override + public IToast.Visibility draw(GuiToastImpl toastGui, long delta) { + GL11.glColor3f(1, 1, 1); + background.draw(toastGui, 0, 0); + if (icon != null) { + icon.draw(toastGui, 6, 6); + } + + val x = icon == null ? 5 : 5 + icon.getIcon().getIconWidth(); + val bgHeight = background.getIcon().getIconHeight(); + val fontRenderer = toastGui.getMinecraft().fontRenderer; + if (subtitle == null) { + fontRenderer.drawString(title, x, bgHeight / 2 - 5, 0xFFFFFFFF); + } else { + fontRenderer.drawString(title, x, 7, 0xFFFFFFFF); + fontRenderer.drawString(subtitle, x, bgHeight - 14, 0xFFFFFFFF); + } + + if (hasProgressBar) { + val bgWidth = background.getIcon().getIconWidth(); + Gui.drawRect(3, bgHeight - 4, bgWidth - 3, bgHeight - 3, 0xFFFFFFFF); + float f = (float) MathUtil.clampedLerp(displayedProgress, currentProgress, (float) (delta - lastDelta) / 100.0F); + int i; + + if (currentProgress >= displayedProgress) { + i = 0xff005500; + } else { + i = 0xff550000; + } + val barLength = bgWidth - 6; + Gui.drawRect(3, bgHeight - 4, (int) (3.0F + barLength * f), bgHeight - 3, i); + displayedProgress = f; + lastDelta = delta; + } + if (timeout > 0) { + if (delta >= timeout) { + hide(); + } + } + return visibility; + } + + @Override + public int width() { + return background.getIcon().getIconWidth(); + } + + @Override + public int height() { + return background.getIcon().getIconHeight(); + } + + @StableAPI(since = "0.10.0") + public void hide() { + visibility = IToast.Visibility.HIDE; + } + + @StableAPI(since = "0.10.0") + public void setProgress(float progress) { + this.currentProgress = progress; + } +} \ No newline at end of file diff --git a/src/main/java/com/falsepattern/lib/toasts/icon/ToastBG.java b/src/main/java/com/falsepattern/lib/toasts/icon/ToastBG.java new file mode 100644 index 0000000..b7ffbce --- /dev/null +++ b/src/main/java/com/falsepattern/lib/toasts/icon/ToastBG.java @@ -0,0 +1,70 @@ +/** + * Copyright (C) 2022 FalsePattern + * All Rights Reserved + *

+ * The above copyright notice, this permission notice and the word "SNEED" + * shall be included in all copies or substantial portions of the Software. + *

+ * 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 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 com.falsepattern.lib.toasts.icon; + +import com.falsepattern.lib.StableAPI; +import com.falsepattern.lib.internal.Tags; +import lombok.NonNull; +import org.lwjgl.opengl.GL11; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.util.IIcon; +import net.minecraft.util.ResourceLocation; + +@StableAPI(since = "0.10.0") +public class ToastBG extends ToastTexture { + @StableAPI(since = "0.10.0") + public static final ToastBG TOAST_DARK = new ToastBG(new ResourceLocation(Tags.MODID, "textures/gui/toast_dark.png"), 160, 32, 0xFFFFFFFF); + @StableAPI(since = "0.10.0") + public static final ToastBG TOAST_DARK_ROUNDED = new ToastBG(new ResourceLocation(Tags.MODID, "textures/gui/toast_dark_rounded.png"), 160, 32, 0xFFFFFFFF); + @StableAPI(since = "0.10.0") + public static final ToastBG TOAST_NARRATOR = new ToastBG(new ResourceLocation(Tags.MODID, "textures/gui/toast_narrator.png"), 160, 32, 0xFFAAAA00); + @StableAPI(since = "0.10.0") + public static final ToastBG TOAST_NARRATOR_ROUNDED = new ToastBG(new ResourceLocation(Tags.MODID, "textures/gui/toast_narrator_rounded.png"), 160, 32, 0xFFAAAA00); + @StableAPI(since = "0.10.0") + public static final ToastBG TOAST_WHITE = new ToastBG(new ResourceLocation(Tags.MODID, "textures/gui/toast_white.png"), 160, 32, 0xFF500050); + @StableAPI(since = "0.10.0") + public static final ToastBG TOAST_WHITE_ROUNDED = new ToastBG(new ResourceLocation(Tags.MODID, "textures/gui/toast_white_rounded.png"), 160, 32, 0xFF500050); + + @StableAPI(since = "0.10.0") + public final int defaultTextColor; + + @StableAPI(since = "0.10.0") + public ToastBG(@NonNull ResourceLocation texture, int width, int height, int defaultTextColor) { + super(texture, width, height); + this.defaultTextColor = defaultTextColor; + } + + @StableAPI(since = "0.10.0") + public ToastBG(@NonNull ResourceLocation texture, @NonNull IIcon icon, int defaultTextColor) { + super(texture, icon); + this.defaultTextColor = defaultTextColor; + } + + @Override + public void draw(Gui guiIn, int x, int y) { + GL11.glPushAttrib(GL11.GL_TEXTURE_BIT); + Minecraft.getMinecraft().getTextureManager().bindTexture(texture); + guiIn.drawTexturedModelRectFromIcon(x, y, icon, icon.getIconWidth(), icon.getIconHeight()); + GL11.glPopAttrib(); + } +} \ No newline at end of file diff --git a/src/main/java/com/falsepattern/lib/toasts/icon/ToastIcon.java b/src/main/java/com/falsepattern/lib/toasts/icon/ToastIcon.java new file mode 100644 index 0000000..5b78893 --- /dev/null +++ b/src/main/java/com/falsepattern/lib/toasts/icon/ToastIcon.java @@ -0,0 +1,52 @@ +/** + * Copyright (C) 2022 FalsePattern + * All Rights Reserved + *

+ * The above copyright notice, this permission notice and the word "SNEED" + * shall be included in all copies or substantial portions of the Software. + *

+ * 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 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 com.falsepattern.lib.toasts.icon; + +import com.falsepattern.lib.StableAPI; +import lombok.NonNull; +import org.lwjgl.opengl.GL11; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.util.IIcon; +import net.minecraft.util.ResourceLocation; + +@StableAPI(since = "0.10.0") +public class ToastIcon extends ToastTexture { + @StableAPI(since = "0.10.0") + public ToastIcon(@NonNull ResourceLocation texture, int width, int height) { + super(texture, width, height); + } + + @StableAPI(since = "0.10.0") + public ToastIcon(@NonNull ResourceLocation texture, @NonNull IIcon icon) { + super(texture, icon); + } + + @Override + public void draw(Gui guiIn, int x, int y) { + GL11.glPushAttrib(GL11.GL_TEXTURE_BIT | GL11.GL_ENABLE_BIT); + Minecraft.getMinecraft().getTextureManager().bindTexture(texture); + GL11.glEnable(GL11.GL_BLEND); + guiIn.drawTexturedModelRectFromIcon(x, y, icon, icon.getIconWidth(), icon.getIconHeight()); + GL11.glPopAttrib(); + } +} \ No newline at end of file diff --git a/src/main/java/com/falsepattern/lib/toasts/icon/ToastTexture.java b/src/main/java/com/falsepattern/lib/toasts/icon/ToastTexture.java new file mode 100644 index 0000000..c532ff1 --- /dev/null +++ b/src/main/java/com/falsepattern/lib/toasts/icon/ToastTexture.java @@ -0,0 +1,55 @@ +/** + * Copyright (C) 2022 FalsePattern + * All Rights Reserved + *

+ * The above copyright notice, this permission notice and the word "SNEED" + * shall be included in all copies or substantial portions of the Software. + *

+ * 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 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 com.falsepattern.lib.toasts.icon; + +import com.falsepattern.lib.StableAPI; +import com.falsepattern.lib.util.RenderUtil; +import lombok.Getter; +import lombok.NonNull; + +import net.minecraft.client.gui.Gui; +import net.minecraft.util.IIcon; +import net.minecraft.util.ResourceLocation; + +@StableAPI(since = "0.10.0") +public abstract class ToastTexture { + @Getter(onMethod_={@StableAPI(since = "0.10.0")}) + protected final IIcon icon; + @Getter(onMethod_={@StableAPI(since = "0.10.0")}) + protected final ResourceLocation texture; + + @StableAPI(since = "0.10.0") + public ToastTexture(@NonNull ResourceLocation texture, int width, int height) { + this(texture, RenderUtil.getFullTextureIcon(texture.toString(), width, height)); + } + + @StableAPI(since = "0.10.0") + public ToastTexture(@NonNull ResourceLocation texture, @NonNull IIcon icon) { + this.icon = icon; + this.texture = texture; + } + + /** + * Draws the icon at the specified position in the specified Gui + */ + @StableAPI(since = "0.10.0") + public abstract void draw(Gui guiIn, int x, int y); +} \ No newline at end of file diff --git a/src/main/java/com/falsepattern/lib/updates/UpdateChecker.java b/src/main/java/com/falsepattern/lib/updates/UpdateChecker.java index bef728a..3d62b8b 100644 --- a/src/main/java/com/falsepattern/lib/updates/UpdateChecker.java +++ b/src/main/java/com/falsepattern/lib/updates/UpdateChecker.java @@ -25,7 +25,7 @@ import com.falsepattern.lib.StableAPI; import com.falsepattern.lib.dependencies.DependencyLoader; import com.falsepattern.lib.dependencies.SemanticVersion; import com.falsepattern.lib.internal.Internet; -import com.falsepattern.lib.internal.LibraryConfig; +import com.falsepattern.lib.internal.config.LibraryConfig; import com.falsepattern.lib.internal.Tags; import com.falsepattern.lib.text.FormattedText; import cpw.mods.fml.common.Loader; diff --git a/src/main/java/com/falsepattern/lib/util/RenderUtil.java b/src/main/java/com/falsepattern/lib/util/RenderUtil.java index c0ac0ab..87d8d34 100644 --- a/src/main/java/com/falsepattern/lib/util/RenderUtil.java +++ b/src/main/java/com/falsepattern/lib/util/RenderUtil.java @@ -21,11 +21,15 @@ package com.falsepattern.lib.util; import com.falsepattern.lib.StableAPI; +import lombok.NoArgsConstructor; +import lombok.SneakyThrows; +import lombok.val; + +import net.minecraft.client.Minecraft; +import net.minecraft.util.IIcon; +import net.minecraft.util.Timer; import cpw.mods.fml.relauncher.ReflectionHelper; import cpw.mods.fml.relauncher.SideOnly; -import lombok.*; -import net.minecraft.client.Minecraft; -import net.minecraft.util.Timer; import static cpw.mods.fml.relauncher.Side.CLIENT; import static lombok.AccessLevel.PRIVATE; @@ -44,6 +48,56 @@ public final class RenderUtil { return (Timer) timerField.get(getMinecraft()); } + @StableAPI(since = "0.10.0") + public static IIcon getFullTextureIcon(String iconName, int width, int height) { + return new IIcon() { + @Override + public int getIconWidth() { + return width; + } + + @Override + public int getIconHeight() { + return height; + } + + @Override + public float getMinU() { + return 0; + } + + @Override + public float getMaxU() { + return 1; + } + + @Override + public float getInterpolatedU(double u) { + return (float) (u / 16D); + } + + @Override + public float getMinV() { + return 0; + } + + @Override + public float getMaxV() { + return 1; + } + + @Override + public float getInterpolatedV(double v) { + return (float) (v / 16D); + } + + @Override + public String getIconName() { + return iconName; + } + }; + } + public static float partialTick() { return MINECRAFT_TIMER.renderPartialTicks; } diff --git a/src/main/resources/assets/falsepatternlib/lang/en_US.lang b/src/main/resources/assets/falsepatternlib/lang/en_US.lang index 0583508..d6134cf 100644 --- a/src/main/resources/assets/falsepatternlib/lang/en_US.lang +++ b/src/main/resources/assets/falsepatternlib/lang/en_US.lang @@ -1,3 +1,9 @@ +config.falsepatternlib.maxtoasts=Max Toasts +config.falsepatternlib.maxtoasts.tooltip=The maximum amount of toasts to show on the screen +config.falsepatternlib.toastoffset=Toast Y Offset +config.falsepatternlib.toastoffset.tooltip=The amount of empty space from the top of the screen in pixels +config.falsepatternlib.toastalign=Toast Alignment +config.falsepatternlib.toastalign.tooltip=Which side of the screen should toasts show up on config.falsepatternlib.updatecheck=Enable update checks config.falsepatternlib.updatecheck.tooltip=Used to control whether FalsePatternLib should check for outdated mods. config.falsepatternlib.disableinternet=FalsePatternLib Offline Mode diff --git a/src/main/resources/assets/falsepatternlib/sounds.json b/src/main/resources/assets/falsepatternlib/sounds.json new file mode 100644 index 0000000..a29f455 --- /dev/null +++ b/src/main/resources/assets/falsepatternlib/sounds.json @@ -0,0 +1,14 @@ +{ + "ui.toast.in": { + "category": "master", + "sounds": [ + "toast/in" + ] + }, + "ui.toast.out": { + "category": "master", + "sounds": [ + "toast/out" + ] + } +} diff --git a/src/main/resources/assets/falsepatternlib/sounds/toast/in.ogg b/src/main/resources/assets/falsepatternlib/sounds/toast/in.ogg new file mode 100644 index 0000000..5ec26ff Binary files /dev/null and b/src/main/resources/assets/falsepatternlib/sounds/toast/in.ogg differ diff --git a/src/main/resources/assets/falsepatternlib/sounds/toast/out.ogg b/src/main/resources/assets/falsepatternlib/sounds/toast/out.ogg new file mode 100644 index 0000000..78d4b72 Binary files /dev/null and b/src/main/resources/assets/falsepatternlib/sounds/toast/out.ogg differ diff --git a/src/main/resources/assets/falsepatternlib/textures/gui/toast_dark.png b/src/main/resources/assets/falsepatternlib/textures/gui/toast_dark.png new file mode 100644 index 0000000..d1a948e Binary files /dev/null and b/src/main/resources/assets/falsepatternlib/textures/gui/toast_dark.png differ diff --git a/src/main/resources/assets/falsepatternlib/textures/gui/toast_dark_rounded.png b/src/main/resources/assets/falsepatternlib/textures/gui/toast_dark_rounded.png new file mode 100644 index 0000000..db50b4d Binary files /dev/null and b/src/main/resources/assets/falsepatternlib/textures/gui/toast_dark_rounded.png differ diff --git a/src/main/resources/assets/falsepatternlib/textures/gui/toast_narrator.png b/src/main/resources/assets/falsepatternlib/textures/gui/toast_narrator.png new file mode 100644 index 0000000..20a9303 Binary files /dev/null and b/src/main/resources/assets/falsepatternlib/textures/gui/toast_narrator.png differ diff --git a/src/main/resources/assets/falsepatternlib/textures/gui/toast_narrator_rounded.png b/src/main/resources/assets/falsepatternlib/textures/gui/toast_narrator_rounded.png new file mode 100644 index 0000000..513691c Binary files /dev/null and b/src/main/resources/assets/falsepatternlib/textures/gui/toast_narrator_rounded.png differ diff --git a/src/main/resources/assets/falsepatternlib/textures/gui/toast_white.png b/src/main/resources/assets/falsepatternlib/textures/gui/toast_white.png new file mode 100644 index 0000000..c70f366 Binary files /dev/null and b/src/main/resources/assets/falsepatternlib/textures/gui/toast_white.png differ diff --git a/src/main/resources/assets/falsepatternlib/textures/gui/toast_white_rounded.png b/src/main/resources/assets/falsepatternlib/textures/gui/toast_white_rounded.png new file mode 100644 index 0000000..b241f6a Binary files /dev/null and b/src/main/resources/assets/falsepatternlib/textures/gui/toast_white_rounded.png differ