Change mixed humans skins option to a dual skin mode and add a priority trigger pixel to facilitate skin sorting

This commit is contained in:
Sollace 2023-09-27 02:00:18 +01:00
parent 6013fa2ad5
commit 24a8afc508
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
6 changed files with 44 additions and 25 deletions

View file

@ -26,13 +26,13 @@ public class PonyConfig extends Config {
* Sets the pony level. Want MOAR PONEHS? Well here you go. * Sets the pony level. Want MOAR PONEHS? Well here you go.
*/ */
public final Setting<PonyLevel> ponyLevel = value("ponylevel", PonyLevel.PONIES) public final Setting<PonyLevel> ponyLevel = value("ponylevel", PonyLevel.PONIES)
.addComment("How much pony do you want?") .addComment("How much pony do you want?")
.addComment("PONIES - all players are turned into ponies") .addComment("PONIES - all players are turned into ponies")
.addComment("HUMANS - all players are humans") .addComment("HUMANS - all players are humans")
.addComment("BOTH - players with compatible skins will be ponies whilst the rest are humans"); .addComment("BOTH - players with compatible skins will be ponies whilst the rest are humans");
private final Setting<Float> scaleFactor = value("globalScaleFactor", 0.9F) private final Setting<Float> scaleFactor = value("globalScaleFactor", 0.9F)
.addComment("How large do you want your ponies to be?") .addComment("How large do you want your ponies to be?")
.addComment("Default is show scale (0.9)"); .addComment("Default is show scale (0.9)");
public final Setting<Boolean> sizes = value("settings", "sizes", true) public final Setting<Boolean> sizes = value("settings", "sizes", true)
.addComment("Allows ponies of different sizes/ages"); .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("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"); .addComment("Helps to prevent entities from vanishing when they're in long stacks");
public final Setting<Boolean> horsieMode = value("settings", "horsieMode", false) public final Setting<Boolean> horsieMode = value("settings", "horsieMode", false)
.addComment("Enables the alternative horsey models from the April Fools 2023 update"); .addComment("Enables the alternative horsey models from the April Fools 2023 update");
public final Setting<Boolean> mixedHumanSkins = value("settings", "mixedHumanSkins", false) public final Setting<Boolean> mixedHumanSkins = value("settings", "dualSkinMode", false)
.addComment("(Experimental) When displaying humans, use mojang's skin server instead.") .addComment("(Experimental) Use priority to decide between displaying the HDSkins' texture, or vanilla mojang server skin")
.addComment("(Experimental) Only takes effect on pony level = HUMANS") .addComment("(Experimental) eg. On pony level = HUMANS")
.addComment("(Experimental) Will cause the vanilla skin to show if the hd skin is a pony skin"); .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<SizePreset> sizeOverride = value("debug", "sizeOverride", SizePreset.UNSET) public final Setting<SizePreset> sizeOverride = value("debug", "sizeOverride", SizePreset.UNSET)
.addComment("Overrides pony sizes") .addComment("Overrides pony sizes")
@ -79,10 +80,10 @@ public class PonyConfig extends Config {
.addComment("Turning this off may help with compatibility in some cases"); .addComment("Turning this off may help with compatibility in some cases");
public final Setting<VisibilityMode> horseButton = value("horseButton", VisibilityMode.AUTO) public final Setting<VisibilityMode> horseButton = value("horseButton", VisibilityMode.AUTO)
.addComment("Whether to show the mine little pony settings button on the main menu") .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("AUTO (default) - only show when HDSkins is not installed")
.addComment("ON - always show") .addComment("ON - always show")
.addComment("OFF - never show"); .addComment("OFF - never show");
public PonyConfig(Path path) { public PonyConfig(Path path) {
super(HEIRARCHICAL_JSON_ADAPTER, path); super(HEIRARCHICAL_JSON_ADAPTER, path);

View file

@ -23,6 +23,7 @@ public class MsgPonyData {
new MsgSize(buffer), new MsgSize(buffer),
buffer.readInt(), buffer.readInt(),
buffer.readBoolean(), buffer.readBoolean(),
buffer.readVarInt(),
Flags.read(Wearable.NONE, buffer) Flags.read(Wearable.NONE, buffer)
); );
} }
@ -34,6 +35,7 @@ public class MsgPonyData {
buffer.writeEnumConstant(data.tailLength()); buffer.writeEnumConstant(data.tailLength());
buffer.writeEnumConstant(data.tailShape()); buffer.writeEnumConstant(data.tailShape());
buffer.writeEnumConstant(data.gender()); buffer.writeEnumConstant(data.gender());
buffer.writeVarInt(data.priority());
new MsgSize(data.size()).toBuffer(buffer); new MsgSize(data.size()).toBuffer(buffer);
buffer.writeInt(data.glowColor()); buffer.writeInt(data.glowColor());
buffer.writeBoolean(data.noSkin()); buffer.writeBoolean(data.noSkin());

View file

@ -49,13 +49,25 @@ public record PonyData (
* rather than a user-uploaded one. * rather than a user-uploaded one.
*/ */
boolean noSkin, 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. * Gets the trigger pixel values as they appeared in the underlying image.
*/ */
Map<String, TValue<?>> attributes Map<String, TValue<?>> attributes
) implements Comparable<PonyData> { ) implements Comparable<PonyData> {
public static final int DEFAULT_MAGIC_COLOR = 0x4444aa; public static final int DEFAULT_MAGIC_COLOR = 0x4444aa;
private static final Function<Race, PonyData> 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<Race, PonyData> 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 final PonyData NULL = OF_RACE.apply(Race.HUMAN);
public static PonyData emptyOf(Race race) { public static PonyData emptyOf(Race race) {
@ -71,18 +83,20 @@ public record PonyData (
TriggerPixel.SIZE.read(image), TriggerPixel.SIZE.read(image),
TriggerPixel.GLOW.read(image), TriggerPixel.GLOW.read(image),
noSkin, noSkin,
TriggerPixel.PRIORITY.read(image),
TriggerPixel.WEARABLES.read(image) TriggerPixel.WEARABLES.read(image)
); );
} }
public PonyData(Race race, TailLength tailLength, TailShape tailShape, Gender gender, Size size, int glowColor, boolean noSkin, Flags<Wearable> wearables) { public PonyData(Race race, TailLength tailLength, TailShape tailShape, Gender gender, Size size, int glowColor, boolean noSkin, int priority, Flags<Wearable> wearables) {
this(race, tailLength, tailShape, gender, size, glowColor, wearables, noSkin, Util.make(new TreeMap<>(), map -> { this(race, tailLength, tailShape, gender, size, glowColor, wearables, noSkin, priority, Util.make(new TreeMap<>(), map -> {
map.put("race", race); map.put("race", race);
map.put("tailLength", tailLength); map.put("tailLength", tailLength);
map.put("tailShape", tailShape); map.put("tailShape", tailShape);
map.put("gender", gender); map.put("gender", gender);
map.put("size", size); map.put("size", size);
map.put("magic", new TValue.Numeric(glowColor)); map.put("magic", new TValue.Numeric(glowColor));
map.put("priority", new TValue.Numeric(priority));
map.put("gear", wearables); map.put("gear", wearables);
}) })
); );

View file

@ -22,6 +22,7 @@ public interface TriggerPixel<T> {
TriggerPixel<Size> SIZE = ofOptions(3, 0, SizePreset.NORMAL, SizePreset.values()); TriggerPixel<Size> SIZE = ofOptions(3, 0, SizePreset.NORMAL, SizePreset.values());
TriggerPixel<Integer> GLOW = ofColor(0, 1); TriggerPixel<Integer> GLOW = ofColor(0, 1);
TriggerPixel<Flags<Wearable>> WEARABLES = ofFlags(1, 1, Wearable.EMPTY_FLAGS, Wearable.values()); TriggerPixel<Flags<Wearable>> WEARABLES = ofFlags(1, 1, Wearable.EMPTY_FLAGS, Wearable.values());
TriggerPixel<Integer> PRIORITY = ofColor(2, 2);
static <T extends TValue<T>> TriggerPixel<T> ofOptions(int x, int y, T def, T[] options) { static <T extends TValue<T>> TriggerPixel<T> ofOptions(int x, int y, T def, T[] options) {
MAX_COORDS.x = Math.max(MAX_COORDS.x, x); MAX_COORDS.x = Math.max(MAX_COORDS.x, x);

View file

@ -61,9 +61,12 @@ public class MineLPHDSkins extends SkinsProxy implements ClientModInitializer {
HDSkins.getInstance().getSkinPrioritySorter().addSelector((skinType, playerSkins) -> { HDSkins.getInstance().getSkinPrioritySorter().addSelector((skinType, playerSkins) -> {
if (skinType == SkinType.SKIN && PonyConfig.getInstance().mixedHumanSkins.get()) { if (skinType == SkinType.SKIN && PonyConfig.getInstance().mixedHumanSkins.get()) {
PonyLevel level = PonyConfig.getInstance().ponyLevel.get(); Optional<Pony> hdPony = getPony(playerSkins.hd());
Optional<Pony> 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(); return playerSkins.vanilla();
} }
} }
@ -71,12 +74,10 @@ public class MineLPHDSkins extends SkinsProxy implements ClientModInitializer {
}); });
} }
static boolean isPony(PlayerSkins.Layer layer) { static Optional<Pony> getPony(PlayerSkins.Layer layer) {
return layer return layer
.getSkin(SkinType.SKIN) .getSkin(SkinType.SKIN)
.map(Pony.getManager()::getPony) .map(Pony.getManager()::getPony);
.filter(pony -> !pony.metadata().race().isHuman())
.isPresent();
} }
@Override @Override

View file

@ -23,7 +23,7 @@
"minelp.options.flappyelytras": "Flap Wings whilst Gliding", "minelp.options.flappyelytras": "Flap Wings whilst Gliding",
"minelp.options.horsiemode": "Horsey Horse Mode", "minelp.options.horsiemode": "Horsey Horse Mode",
"minelp.options.nofun": "Boring 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": "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.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", "minelp.options.button.auto": "Display only when HD Skins is not installed",