diff --git a/src/main/java/com/minelittlepony/common/client/gui/OutsideWorldRenderer.java b/src/main/java/com/minelittlepony/common/client/gui/OutsideWorldRenderer.java index 4cb7316f..ee849359 100644 --- a/src/main/java/com/minelittlepony/common/client/gui/OutsideWorldRenderer.java +++ b/src/main/java/com/minelittlepony/common/client/gui/OutsideWorldRenderer.java @@ -54,7 +54,7 @@ public static BlockEntityRenderDispatcher configure(@Nullable World world) { public static void renderStack(DrawContext context, ItemStack stack, int x, int y) { try { configure(null); - } catch (Throwable t) {} + } catch (Throwable ignored) {} context.drawItem(stack, x, y); } } diff --git a/src/main/java/com/minelittlepony/common/client/gui/ScrollContainer.java b/src/main/java/com/minelittlepony/common/client/gui/ScrollContainer.java index 5534158d..69f8e091 100644 --- a/src/main/java/com/minelittlepony/common/client/gui/ScrollContainer.java +++ b/src/main/java/com/minelittlepony/common/client/gui/ScrollContainer.java @@ -85,10 +85,9 @@ public void init(Runnable contentInitializer) { @Override public final void render(DrawContext context, int mouseX, int mouseY, float tickDelta) { - MatrixStack matrices = context.getMatrices(); - context.enableScissor(margin.left, margin.top, margin.left + getBounds().width, margin.top + getBounds().height); + MatrixStack matrices = context.getMatrices(); matrices.push(); getBounds().translate(matrices); diff --git a/src/main/java/com/minelittlepony/common/client/gui/element/Cycler.java b/src/main/java/com/minelittlepony/common/client/gui/element/Cycler.java index 0d1480e2..766428ce 100644 --- a/src/main/java/com/minelittlepony/common/client/gui/element/Cycler.java +++ b/src/main/java/com/minelittlepony/common/client/gui/element/Cycler.java @@ -9,8 +9,6 @@ /** * Represents a toggle button that switches between different * styles as you toggle through its different states. - *

- * "Iconic" here refers to how it uses an icon instead of text * * @author Sollace * diff --git a/src/main/java/com/minelittlepony/common/client/gui/element/Selector.java b/src/main/java/com/minelittlepony/common/client/gui/element/Selector.java new file mode 100644 index 00000000..cef7d55c --- /dev/null +++ b/src/main/java/com/minelittlepony/common/client/gui/element/Selector.java @@ -0,0 +1,77 @@ +package com.minelittlepony.common.client.gui.element; + +import java.util.function.Function; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.common.client.gui.IField; +import com.minelittlepony.common.client.gui.style.IMultiStyled; +import com.minelittlepony.common.client.gui.style.Style; + +/** + * Represents a toggle button that switches between different + * values as you toggle through its different states. + * + * @author Sollace + * + */ +public class Selector extends Button implements IMultiStyled>, IField> { + private final Style defaultStyle; + private final T defaultValue; + private T value; + + @NotNull + private IChangeCallback action = IChangeCallback::none; + + private final Function styleFunction; + + public Selector(int x, int y, int width, int height, T value, Function styleFunction) { + super(x, y, width, height); + this.defaultValue = value; + this.value = value; + this.styleFunction = styleFunction; + this.defaultStyle = styleFunction.apply(value); + setStyle(this.defaultStyle); + } + + @Override + public Selector onChange(IChangeCallback action) { + this.action = action; + + return this; + } + + @Override + public T getValue() { + return value; + } + + @Override + public Selector setValue(@Nullable T value) { + this.value = value == null ? defaultValue : value; + this.setStyle(styleFunction.apply(this.value)); + + return this; + } + + /** + * Sets the styles to use for each state this toggle is able to be in. + * The number of styles here determines the number of possible states + * and the value is the index to the array of styles. + */ + @Override + public Selector setStyles(Style... styles) { + return this; + } + + @Override + public Style[] getStyles() { + return new Style[] {getStyle()}; + } + + @Override + public void onPress() { + setValue(action.perform(getValue())); + super.onPress(); + } +} diff --git a/src/main/java/com/minelittlepony/common/client/gui/element/Slider.java b/src/main/java/com/minelittlepony/common/client/gui/element/Slider.java index 27ac56a0..b5eb1986 100644 --- a/src/main/java/com/minelittlepony/common/client/gui/element/Slider.java +++ b/src/main/java/com/minelittlepony/common/client/gui/element/Slider.java @@ -9,7 +9,6 @@ * @author Sollace */ public class Slider extends AbstractSlider { - public Slider(int x, int y, float min, float max, Supplier value) { this(x, y, min, max, Objects.requireNonNull(value.get(), "value was null").floatValue()); } diff --git a/src/main/java/com/minelittlepony/common/client/gui/sprite/ItemStackSprite.java b/src/main/java/com/minelittlepony/common/client/gui/sprite/ItemStackSprite.java index b359d1ba..c57db449 100644 --- a/src/main/java/com/minelittlepony/common/client/gui/sprite/ItemStackSprite.java +++ b/src/main/java/com/minelittlepony/common/client/gui/sprite/ItemStackSprite.java @@ -8,12 +8,13 @@ import net.minecraft.component.type.DyedColorComponent; import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemStack; +import net.minecraft.util.Colors; public class ItemStackSprite implements ISprite { private ItemStack stack = ItemStack.EMPTY; - private int tint = 0xFFFFFFFF; + private int tint = Colors.WHITE; private boolean renderFailed; private boolean needsWorld; @@ -24,11 +25,14 @@ public ItemStackSprite setStack(ItemConvertible iitem) { public ItemStackSprite setStack(ItemStack stack) { this.stack = stack; + renderFailed = false; + needsWorld = false; return setTint(tint); } public ItemStackSprite setTint(int tint) { + this.tint = tint; stack.set(DataComponentTypes.DYED_COLOR, new DyedColorComponent(tint, true)); return this; } @@ -41,7 +45,7 @@ public void render(DrawContext context, int x, int y, int mouseX, int mouseY, fl if (!needsWorld) { try { - context.drawItem(stack, x, y); + context.drawItem(stack, x + 2, y + 2); RenderSystem.disableDepthTest(); return; } catch (Throwable ignored) { @@ -51,7 +55,7 @@ public void render(DrawContext context, int x, int y, int mouseX, int mouseY, fl try { OutsideWorldRenderer.configure(null); - context.drawItem(stack, x, y); + context.drawItem(stack, x + 2, y + 2); RenderSystem.disableDepthTest(); } catch (Throwable ignored) { renderFailed = true; diff --git a/src/main/java/com/minelittlepony/common/event/SkinFilterCallback.java b/src/main/java/com/minelittlepony/common/event/SkinFilterCallback.java index c4b4a7d9..637ddf00 100644 --- a/src/main/java/com/minelittlepony/common/event/SkinFilterCallback.java +++ b/src/main/java/com/minelittlepony/common/event/SkinFilterCallback.java @@ -20,6 +20,7 @@ public NativeImage processImage(NativeImage image, int initialWidth, int initial return image; } + @Deprecated @Override public boolean shouldAllowTransparency(NativeImage image, int initialWidth, int initialHeight) { for (SkinFilterCallback event : listeners) { @@ -39,14 +40,34 @@ default boolean shouldAllowTransparency(NativeImage image, int initialWidth, int return true; // default is true since in most cases this is the desired effect } + /** + * Checks whether the incoming image size corresponds to the old 1:2 ratio player skins. + */ static boolean isLegacyAspectRatio(int width, int height) { return width == height * 2; } + /** + * Gets the scale of the image as a multiple of its vanilla image width. + */ static int getResolutionScale(int width, int height) { return width / VANILLA_SKIN_WIDTH; } + /** + * Fills a scaled section of an image with a solid color. + * @param image + * @param xFrom + * @param yFrom + * @param xTo + * @param yTo + * @param color + */ + static void fill(NativeImage image, int xFrom, int yFrom, int xTo, int yTo, int color) { + int scale = getResolutionScale(image.getWidth(), image.getHeight()); + image.fillRect(xFrom * scale, yFrom * scale, xTo * scale, yTo * scale, color); + } + /** * Copies a scaled section from one region to another. * @@ -64,7 +85,7 @@ static void copy(NativeImage image, int xOffset, int yOffset, int width, int height, boolean mirrorX, boolean mirrorY) { - int scale = image.getWidth() / 64; + int scale = getResolutionScale(image.getWidth(), image.getHeight()); image.copyRect( xFrom * scale, yFrom * scale, xOffset * scale, yOffset * scale, diff --git a/src/main/java/com/minelittlepony/common/mixin/MixinPlayerSkinTexture.java b/src/main/java/com/minelittlepony/common/mixin/MixinPlayerSkinTexture.java index 621cb31e..0d3e0606 100644 --- a/src/main/java/com/minelittlepony/common/mixin/MixinPlayerSkinTexture.java +++ b/src/main/java/com/minelittlepony/common/mixin/MixinPlayerSkinTexture.java @@ -1,5 +1,7 @@ package com.minelittlepony.common.mixin; +import com.llamalad7.mixinextras.sugar.Share; +import com.llamalad7.mixinextras.sugar.ref.LocalIntRef; import com.minelittlepony.common.event.SkinFilterCallback; import net.minecraft.client.texture.NativeImage; import net.minecraft.client.texture.PlayerSkinTexture; @@ -7,40 +9,44 @@ 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 org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @Mixin(PlayerSkinTexture.class) public abstract class MixinPlayerSkinTexture extends ResourceTexture { private MixinPlayerSkinTexture() { super(null); } - private static int initialWidth; - private static int initialHeight; + private static final String FILTER_IMAGE = "remapTexture(Lnet/minecraft/client/texture/NativeImage;)Lnet/minecraft/client/texture/NativeImage;"; + private static final String STRIP_COLOR = "net/minecraft/client/texture/PlayerSkinTexture.stripColor(Lnet/minecraft/client/texture/NativeImage;IIII)V"; + private static final String STRIP_ALPHA = "net/minecraft/client/texture/PlayerSkinTexture.stripAlpha(Lnet/minecraft/client/texture/NativeImage;IIII)V"; - @Inject(method = "remapTexture", at = @At("HEAD")) - private void beforeUpdate(NativeImage image, CallbackInfoReturnable info) { - initialWidth = image.getWidth(); - initialHeight = image.getHeight(); + @Inject(method = FILTER_IMAGE, at = @At("HEAD")) + private void beforeUpdate(NativeImage image, + CallbackInfoReturnable ci, + @Share(value = "kirinmlp_initialWidth") LocalIntRef initialWidth, + @Share(value = "kirinmlp_initialHeight") LocalIntRef initialHeight) { + initialWidth.set(image.getWidth()); + initialHeight.set(image.getHeight()); } - @Inject(method = "remapTexture", at = @At("RETURN")) - private void update(NativeImage image, CallbackInfoReturnable ci) { + @Inject(method = FILTER_IMAGE, at = @At("RETURN"), cancellable = true) + private void update(NativeImage image, + CallbackInfoReturnable ci, + @Share(value = "kirinmlp_initialWidth") LocalIntRef initialWidth, + @Share(value = "kirinmlp_initialHeight") LocalIntRef initialHeight) { // convert skins from mojang server - ci.setReturnValue(SkinFilterCallback.EVENT.invoker().processImage(ci.getReturnValue(), initialWidth, initialHeight)); + ci.setReturnValue(SkinFilterCallback.EVENT.invoker().processImage(ci.getReturnValue(), initialWidth.get(), initialHeight.get())); } // Sorry, Mahjon. Input validation is good 'n all, but this interferes with our other mods. - @Inject(method = "stripAlpha", at = @At("HEAD"), cancellable = true) - private static void cancelAlphaStrip(NativeImage image, int beginX, int beginY, int endX, int endY, CallbackInfo info) { - if (SkinFilterCallback.EVENT.invoker().shouldAllowTransparency(image, initialWidth, initialHeight)) { - info.cancel(); - } - } - - @Inject(method = "stripColor", at = @At("HEAD"), cancellable = true) - private static void cancelColorStrip(NativeImage image, int beginX, int beginY, int endX, int endY, CallbackInfo info) { - if (SkinFilterCallback.EVENT.invoker().shouldAllowTransparency(image, initialWidth, initialHeight)) { - info.cancel(); + @Inject(method = FILTER_IMAGE, at = { + @At(value = "INVOKE", target = STRIP_ALPHA), + @At(value = "INVOKE", target = STRIP_COLOR) + }, cancellable = true) + private void cancelAlphaStrip(NativeImage image, CallbackInfoReturnable ci, + @Share(value = "kirinmlp_initialWidth") LocalIntRef initialWidth, + @Share(value = "kirinmlp_initialHeight") LocalIntRef initialHeight) { + if (SkinFilterCallback.EVENT.invoker().shouldAllowTransparency(image, initialWidth.get(), initialHeight.get())) { + ci.cancel(); } } // -