From 24a8afc5083d197553246efd80d37cafd3643aad Mon Sep 17 00:00:00 2001 From: Sollace Date: Wed, 27 Sep 2023 02:00:18 +0100 Subject: [PATCH] Change mixed humans skins option to a dual skin mode and add a priority trigger pixel to facilitate skin sorting --- .../minelittlepony/api/config/PonyConfig.java | 31 ++++++++++--------- .../api/events/MsgPonyData.java | 2 ++ .../com/minelittlepony/api/pony/PonyData.java | 20 ++++++++++-- .../api/pony/meta/TriggerPixel.java | 1 + .../client/compat/hdskins/MineLPHDSkins.java | 13 ++++---- .../assets/minelittlepony/lang/en_us.json | 2 +- 6 files changed, 44 insertions(+), 25 deletions(-) diff --git a/src/main/java/com/minelittlepony/api/config/PonyConfig.java b/src/main/java/com/minelittlepony/api/config/PonyConfig.java index 6a1d4b2a..848d0406 100644 --- a/src/main/java/com/minelittlepony/api/config/PonyConfig.java +++ b/src/main/java/com/minelittlepony/api/config/PonyConfig.java @@ -26,13 +26,13 @@ public class PonyConfig extends Config { * Sets the pony level. Want MOAR PONEHS? Well here you go. */ public final Setting ponyLevel = value("ponylevel", PonyLevel.PONIES) - .addComment("How much pony do you want?") - .addComment("PONIES - all players are turned into ponies") - .addComment("HUMANS - all players are humans") - .addComment("BOTH - players with compatible skins will be ponies whilst the rest are humans"); + .addComment("How much pony do you want?") + .addComment("PONIES - all players are turned into ponies") + .addComment("HUMANS - all players are humans") + .addComment("BOTH - players with compatible skins will be ponies whilst the rest are humans"); private final Setting scaleFactor = value("globalScaleFactor", 0.9F) - .addComment("How large do you want your ponies to be?") - .addComment("Default is show scale (0.9)"); + .addComment("How large do you want your ponies to be?") + .addComment("Default is show scale (0.9)"); public final Setting sizes = value("settings", "sizes", true) .addComment("Allows ponies of different sizes/ages"); @@ -53,11 +53,12 @@ public class PonyConfig extends Config { .addComment("Adjust camera intersection checks to properly cull entities when they're not in view.") .addComment("Helps to prevent entities from vanishing when they're in long stacks"); public final Setting horsieMode = value("settings", "horsieMode", false) - .addComment("Enables the alternative horsey models from the April Fools 2023 update"); - public final Setting mixedHumanSkins = value("settings", "mixedHumanSkins", false) - .addComment("(Experimental) When displaying humans, use mojang's skin server instead.") - .addComment("(Experimental) Only takes effect on pony level = HUMANS") - .addComment("(Experimental) Will cause the vanilla skin to show if the hd skin is a pony skin"); + .addComment("Enables the alternative horsey models from the April Fools 2023 update"); + public final Setting mixedHumanSkins = value("settings", "dualSkinMode", false) + .addComment("(Experimental) Use priority to decide between displaying the HDSkins' texture, or vanilla mojang server skin") + .addComment("(Experimental) eg. On pony level = HUMANS") + .addComment("(Experimental) Any time both skins resolve to the same race (eg. on pony-level HUMANS, or if both are ponies)") + .addComment("(Experimental) the skin with the highest priority will be chosen.");; public final Setting sizeOverride = value("debug", "sizeOverride", SizePreset.UNSET) .addComment("Overrides pony sizes") @@ -79,10 +80,10 @@ public class PonyConfig extends Config { .addComment("Turning this off may help with compatibility in some cases"); public final Setting horseButton = value("horseButton", VisibilityMode.AUTO) - .addComment("Whether to show the mine little pony settings button on the main menu") - .addComment("AUTO (default) - only show when HDSkins is not installed") - .addComment("ON - always show") - .addComment("OFF - never show"); + .addComment("Whether to show the mine little pony settings button on the main menu") + .addComment("AUTO (default) - only show when HDSkins is not installed") + .addComment("ON - always show") + .addComment("OFF - never show"); public PonyConfig(Path path) { super(HEIRARCHICAL_JSON_ADAPTER, path); diff --git a/src/main/java/com/minelittlepony/api/events/MsgPonyData.java b/src/main/java/com/minelittlepony/api/events/MsgPonyData.java index 7d7cbdc5..ab7623d6 100644 --- a/src/main/java/com/minelittlepony/api/events/MsgPonyData.java +++ b/src/main/java/com/minelittlepony/api/events/MsgPonyData.java @@ -23,6 +23,7 @@ public class MsgPonyData { new MsgSize(buffer), buffer.readInt(), buffer.readBoolean(), + buffer.readVarInt(), Flags.read(Wearable.NONE, buffer) ); } @@ -34,6 +35,7 @@ public class MsgPonyData { buffer.writeEnumConstant(data.tailLength()); buffer.writeEnumConstant(data.tailShape()); buffer.writeEnumConstant(data.gender()); + buffer.writeVarInt(data.priority()); new MsgSize(data.size()).toBuffer(buffer); buffer.writeInt(data.glowColor()); buffer.writeBoolean(data.noSkin()); diff --git a/src/main/java/com/minelittlepony/api/pony/PonyData.java b/src/main/java/com/minelittlepony/api/pony/PonyData.java index 360c0389..86161571 100644 --- a/src/main/java/com/minelittlepony/api/pony/PonyData.java +++ b/src/main/java/com/minelittlepony/api/pony/PonyData.java @@ -49,13 +49,25 @@ public record PonyData ( * rather than a user-uploaded one. */ boolean noSkin, + /** + * (Experimental) Priority. + * Used to decide which skin to use when dual skin mode is active. + * Provides an optional tie-breaker when the client has to decide between displaying + * either the HDSkins texture or vanilla texture given both are otherwise acceptable. + * + * Any time both skins resolve to the same race (eg. on pony-level HUMANS, or if both are ponies) + * the skin with the highest priority will be chosen. + * + * If both have the same priority, HD Skins' texture will always be used (old default). + */ + int priority, /** * Gets the trigger pixel values as they appeared in the underlying image. */ Map> attributes ) implements Comparable { public static final int DEFAULT_MAGIC_COLOR = 0x4444aa; - private static final Function OF_RACE = Util.memoize(race -> new PonyData(race, TailLength.FULL, TailShape.STRAIGHT, Gender.MARE, SizePreset.NORMAL, DEFAULT_MAGIC_COLOR, true, Wearable.EMPTY_FLAGS)); + private static final Function OF_RACE = Util.memoize(race -> new PonyData(race, TailLength.FULL, TailShape.STRAIGHT, Gender.MARE, SizePreset.NORMAL, DEFAULT_MAGIC_COLOR, true, 0, Wearable.EMPTY_FLAGS)); public static final PonyData NULL = OF_RACE.apply(Race.HUMAN); public static PonyData emptyOf(Race race) { @@ -71,18 +83,20 @@ public record PonyData ( TriggerPixel.SIZE.read(image), TriggerPixel.GLOW.read(image), noSkin, + TriggerPixel.PRIORITY.read(image), TriggerPixel.WEARABLES.read(image) ); } - public PonyData(Race race, TailLength tailLength, TailShape tailShape, Gender gender, Size size, int glowColor, boolean noSkin, Flags wearables) { - this(race, tailLength, tailShape, gender, size, glowColor, wearables, noSkin, Util.make(new TreeMap<>(), map -> { + public PonyData(Race race, TailLength tailLength, TailShape tailShape, Gender gender, Size size, int glowColor, boolean noSkin, int priority, Flags wearables) { + this(race, tailLength, tailShape, gender, size, glowColor, wearables, noSkin, priority, Util.make(new TreeMap<>(), map -> { map.put("race", race); map.put("tailLength", tailLength); map.put("tailShape", tailShape); map.put("gender", gender); map.put("size", size); map.put("magic", new TValue.Numeric(glowColor)); + map.put("priority", new TValue.Numeric(priority)); map.put("gear", wearables); }) ); diff --git a/src/main/java/com/minelittlepony/api/pony/meta/TriggerPixel.java b/src/main/java/com/minelittlepony/api/pony/meta/TriggerPixel.java index 18a609f4..2f818adb 100644 --- a/src/main/java/com/minelittlepony/api/pony/meta/TriggerPixel.java +++ b/src/main/java/com/minelittlepony/api/pony/meta/TriggerPixel.java @@ -22,6 +22,7 @@ public interface TriggerPixel { TriggerPixel SIZE = ofOptions(3, 0, SizePreset.NORMAL, SizePreset.values()); TriggerPixel GLOW = ofColor(0, 1); TriggerPixel> WEARABLES = ofFlags(1, 1, Wearable.EMPTY_FLAGS, Wearable.values()); + TriggerPixel PRIORITY = ofColor(2, 2); static > TriggerPixel ofOptions(int x, int y, T def, T[] options) { MAX_COORDS.x = Math.max(MAX_COORDS.x, x); diff --git a/src/main/java/com/minelittlepony/client/compat/hdskins/MineLPHDSkins.java b/src/main/java/com/minelittlepony/client/compat/hdskins/MineLPHDSkins.java index 47c6d548..9d5784d1 100644 --- a/src/main/java/com/minelittlepony/client/compat/hdskins/MineLPHDSkins.java +++ b/src/main/java/com/minelittlepony/client/compat/hdskins/MineLPHDSkins.java @@ -61,9 +61,12 @@ public class MineLPHDSkins extends SkinsProxy implements ClientModInitializer { HDSkins.getInstance().getSkinPrioritySorter().addSelector((skinType, playerSkins) -> { if (skinType == SkinType.SKIN && PonyConfig.getInstance().mixedHumanSkins.get()) { - PonyLevel level = PonyConfig.getInstance().ponyLevel.get(); + Optional hdPony = getPony(playerSkins.hd()); + Optional vanillaPony = getPony(playerSkins.vanilla()); - if (level == PonyLevel.HUMANS && isPony(playerSkins.hd()) && !isPony(playerSkins.vanilla())) { + if (hdPony.isPresent() && vanillaPony.isPresent() + && vanillaPony.get().metadata().priority() > hdPony.get().metadata().priority() + && (PonyConfig.getInstance().ponyLevel.get() == PonyLevel.HUMANS || vanillaPony.get().metadata().race().isHuman() == hdPony.get().metadata().race().isHuman())) { return playerSkins.vanilla(); } } @@ -71,12 +74,10 @@ public class MineLPHDSkins extends SkinsProxy implements ClientModInitializer { }); } - static boolean isPony(PlayerSkins.Layer layer) { + static Optional getPony(PlayerSkins.Layer layer) { return layer .getSkin(SkinType.SKIN) - .map(Pony.getManager()::getPony) - .filter(pony -> !pony.metadata().race().isHuman()) - .isPresent(); + .map(Pony.getManager()::getPony); } @Override diff --git a/src/main/resources/assets/minelittlepony/lang/en_us.json b/src/main/resources/assets/minelittlepony/lang/en_us.json index 393149ba..cd86f801 100644 --- a/src/main/resources/assets/minelittlepony/lang/en_us.json +++ b/src/main/resources/assets/minelittlepony/lang/en_us.json @@ -23,7 +23,7 @@ "minelp.options.flappyelytras": "Flap Wings whilst Gliding", "minelp.options.horsiemode": "Horsey Horse Mode", "minelp.options.nofun": "Boring Mode", - "minelp.options.mixedhumanskins": "(Experimental) Vanilla Humans", + "minelp.options.dualskinmode": "(Experimental) Dual Skin Mode", "minelp.options.button": "Display On Title Screen", "minelp.options.button.on": "Always Display\n\nBoth the pony button and HD Skins button are visible (if installed)", "minelp.options.button.auto": "Display only when HD Skins is not installed",