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 extends Number> 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();
}
}
// -