diff --git a/src/main/java/com/minelittlepony/api/config/PonyConfig.java b/src/main/java/com/minelittlepony/api/config/PonyConfig.java index ce133053..10037467 100644 --- a/src/main/java/com/minelittlepony/api/config/PonyConfig.java +++ b/src/main/java/com/minelittlepony/api/config/PonyConfig.java @@ -3,6 +3,7 @@ package com.minelittlepony.api.config; import net.minecraft.util.math.MathHelper; import com.minelittlepony.api.pony.meta.*; +import com.minelittlepony.common.client.gui.VisibilityMode; import com.minelittlepony.common.util.GamePaths; import com.minelittlepony.common.util.settings.*; @@ -54,7 +55,7 @@ public class PonyConfig extends Config { public final Setting horsieMode = value("settings", "horsieMode", false) .addComment("Enables the alternative horsey models from the April Fools 2023 update"); - public final Setting sizeOverride = value("debug", "sizeOverride", Sizes.UNSET) + public final Setting sizeOverride = value("debug", "sizeOverride", SizePreset.UNSET) .addComment("Overrides pony sizes") .addComment("Possible values: TALL, BULKY, LANKY, NORMAL, YEARLING, FOAL, UNSET (default)"); @@ -72,6 +73,12 @@ public class PonyConfig extends Config { .addComment("Disables certain easter eggs and secrets (party pooper)") .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"); + public PonyConfig(Path path) { super(HEIRARCHICAL_JSON_ADAPTER, path); instance = this; @@ -132,14 +139,14 @@ public class PonyConfig extends Config { } public static Size getEffectiveSize(Size size) { - Sizes sz = instance.sizeOverride.get(); + SizePreset sz = instance.sizeOverride.get(); - if (sz != Sizes.UNSET) { + if (sz != SizePreset.UNSET) { return sz; } - if (size == Sizes.UNSET || !instance.sizes.get()) { - return Sizes.NORMAL; + if (size == SizePreset.UNSET || !instance.sizes.get()) { + return SizePreset.NORMAL; } return size; diff --git a/src/main/java/com/minelittlepony/api/events/MsgPonyData.java b/src/main/java/com/minelittlepony/api/events/MsgPonyData.java index a48d12a8..7d7cbdc5 100644 --- a/src/main/java/com/minelittlepony/api/events/MsgPonyData.java +++ b/src/main/java/com/minelittlepony/api/events/MsgPonyData.java @@ -23,7 +23,7 @@ public class MsgPonyData { new MsgSize(buffer), buffer.readInt(), buffer.readBoolean(), - Flags.read(Wearable.class, buffer) + Flags.read(Wearable.NONE, buffer) ); } diff --git a/src/main/java/com/minelittlepony/api/model/ModelAttributes.java b/src/main/java/com/minelittlepony/api/model/ModelAttributes.java index 417ae803..410edfe1 100644 --- a/src/main/java/com/minelittlepony/api/model/ModelAttributes.java +++ b/src/main/java/com/minelittlepony/api/model/ModelAttributes.java @@ -165,7 +165,7 @@ public class ModelAttributes { } public Interpolator getMainInterpolator() { - return metadata.getInterpolator(interpolatorId); + return Interpolator.linear(interpolatorId); } public boolean shouldLiftArm(ArmPose pose, ArmPose complement, float sigma) { diff --git a/src/main/java/com/minelittlepony/api/model/PonyModel.java b/src/main/java/com/minelittlepony/api/model/PonyModel.java index 6baca27f..baa864f8 100644 --- a/src/main/java/com/minelittlepony/api/model/PonyModel.java +++ b/src/main/java/com/minelittlepony/api/model/PonyModel.java @@ -79,7 +79,7 @@ public interface PonyModel extends MsonModel, ModelWithH * i.e. Used to change wing rendering when using saddlebags. */ default boolean isEmbedded(Wearable wearable) { - return getAttributes().metadata.isWearing(wearable); + return getAttributes().metadata.gear().matches(wearable); } } diff --git a/src/main/java/com/minelittlepony/api/pony/PonyData.java b/src/main/java/com/minelittlepony/api/pony/PonyData.java index dca5ff33..360c0389 100644 --- a/src/main/java/com/minelittlepony/api/pony/PonyData.java +++ b/src/main/java/com/minelittlepony/api/pony/PonyData.java @@ -6,7 +6,6 @@ import org.jetbrains.annotations.Nullable; import com.google.common.collect.ComparisonChain; import com.minelittlepony.api.pony.meta.*; -import com.minelittlepony.common.util.animation.Interpolator; import java.util.*; import java.util.function.Function; @@ -53,64 +52,40 @@ public record PonyData ( /** * Gets the trigger pixel values as they appeared in the underlying image. */ - Map> attributes + Map> attributes ) implements Comparable { - private static final Function OF_RACE = Util.memoize(race -> { - return new PonyData(race, TailLength.FULL, TailShape.STRAIGHT, Gender.MARE, Sizes.NORMAL, 0x4444aa, Wearable.EMPTY_FLAGS, true, Util.make(new TreeMap<>(), attributes -> { - attributes.put("race", race); - attributes.put("tailLength", TailLength.FULL); - attributes.put("tailShape", TailShape.STRAIGHT); - attributes.put("gender", Gender.MARE); - attributes.put("size", Sizes.NORMAL); - attributes.put("magic", TriggerPixelType.of(0x4444aa)); - attributes.put("gear", TriggerPixelType.of(0)); - })); - }); + 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)); public static final PonyData NULL = OF_RACE.apply(Race.HUMAN); public static PonyData emptyOf(Race race) { return OF_RACE.apply(race); } - - 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 -> { - map.put("race", race); - map.put("tailLength", tailLength); - map.put("tailShape", tailShape); - map.put("gender", gender); - map.put("size", size); - map.put("magic", TriggerPixelType.of(glowColor)); - map.put("gear", TriggerPixelType.of(wearables.colorCode())); - })); - } - public PonyData(Race race, TailLength tailLength, TailShape tailShape, Gender gender, Size size, int glowColor, TriggerPixelType.Multiple wearables, boolean noSkin) { - this(race, tailLength, tailShape, gender, size, glowColor, - Flags.of(Wearable.class, wearables.colorCode(), wearables.value()), - noSkin, 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", TriggerPixelType.of(glowColor)); - map.put("gear", wearables); - }) + public PonyData(TriggerPixel.Mat image, boolean noSkin) { + this( + TriggerPixel.RACE.read(image), + TriggerPixel.TAIL.read(image), + TriggerPixel.TAIL_SHAPE.read(image), + TriggerPixel.GENDER.read(image), + TriggerPixel.SIZE.read(image), + TriggerPixel.GLOW.read(image), + noSkin, + TriggerPixel.WEARABLES.read(image) ); } - /** - * Checks it this pony is wearing the given accessory. - */ - public boolean isWearing(Wearable wearable) { - return gear().includes(wearable); - } - - /** - * Gets an interpolator for interpolating values. - */ - public Interpolator getInterpolator(UUID interpolatorId) { - return Interpolator.linear(interpolatorId); + 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 -> { + 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("gear", wearables); + }) + ); } @Override diff --git a/src/main/java/com/minelittlepony/api/pony/PonyManager.java b/src/main/java/com/minelittlepony/api/pony/PonyManager.java index f650a7ff..32e577ea 100644 --- a/src/main/java/com/minelittlepony/api/pony/PonyManager.java +++ b/src/main/java/com/minelittlepony/api/pony/PonyManager.java @@ -1,6 +1,7 @@ package com.minelittlepony.api.pony; import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.Identifier; @@ -10,8 +11,7 @@ import java.util.Optional; import java.util.UUID; /** - * The PonyManager is responsible for reading and recoding all the pony data associated with an entity of skin. - * + * The PonyManager is responsible for reading and recoding all the pony data associated with the skin of an entity. */ public interface PonyManager { /** @@ -19,7 +19,25 @@ public interface PonyManager { * * If the supplied entity is null or can't be determined to be a pony, returns the empty optional. */ - Optional getPony(@Nullable Entity entity); + default Optional getPony(@Nullable Entity entity) { + return entity instanceof LivingEntity living ? getPony(living) : Optional.empty(); + } + + /** + * Gets a pony representation of the passed in entity. + * + * If the supplied entity is null or can't be determined to be a pony, returns the empty optional. + */ + Optional getPony(LivingEntity entity); + + /** + * Gets a random background pony determined by the given uuid. + * + * Useful for mods that offer customisation, especially ones that have a whole lot of NPCs. + * + * @param uuid id of a player + */ + Pony getBackgroundPony(UUID uuid); /** * Gets or creates a pony for the given player. @@ -29,13 +47,6 @@ public interface PonyManager { */ Pony getPony(PlayerEntity player); - /** - * Gets or creates a pony for the given skin resource and vanilla model type. - * - * @param resource A texture resource - */ - Pony getPony(Identifier resource); - /** * Gets or creates a pony for the given skin resource and entity id. * @@ -46,23 +57,16 @@ public interface PonyManager { * @param resource A texture resource * @param uuid id of a player */ - Pony getPony(Identifier resource, UUID uuid); + Pony getPony(@Nullable Identifier resource, @Nullable UUID uuid); /** - * Gets a random background pony determined by the given uuid. + * Gets or creates a pony for the given skin resource and vanilla model type. * - * Useful for mods that offer customisation, especially ones that have a whole lot of NPCs. - * - * @param uuid A UUID. Either a user or an entity. + * @param resource A texture resource */ - Pony getBackgroundPony(UUID uuid); - - /** - * De-registers a pony from the cache. - */ - void removePony(Identifier resource); - - void clearCache(); + default Pony getPony(Identifier resource) { + return getPony(resource, null); + } interface ForcedPony {} diff --git a/src/main/java/com/minelittlepony/api/pony/meta/Flags.java b/src/main/java/com/minelittlepony/api/pony/meta/Flags.java index 3cf0bb8b..94f6159f 100644 --- a/src/main/java/com/minelittlepony/api/pony/meta/Flags.java +++ b/src/main/java/com/minelittlepony/api/pony/meta/Flags.java @@ -4,30 +4,30 @@ import net.minecraft.network.PacketByteBuf; import java.util.*; -public record Flags> ( - boolean[] flags, - List values, +public record Flags & TValue> ( + T def, + Set values, int colorCode - ) implements Comparable> { + ) implements Comparable>, TValue { - public static > Flags of(Class type) { - return new Flags<>(new boolean[type.getEnumConstants().length], List.of(), 0); + public static & TValue> Flags of(T def) { + return new Flags<>(def, Set.of(), 0); } - public static > Flags of(Class type, int colorCode, boolean...flags) { - return new Flags<>(flags, flags(type.getEnumConstants(), flags), colorCode); + public static & TValue> Flags of(T def, int colorCode, Set values) { + return new Flags<>(def, values, colorCode); } - public static > Flags read(Class type, PacketByteBuf buffer) { + public static & TValue> Flags read(T def, PacketByteBuf buffer) { int length = buffer.readVarInt(); - List values = new ArrayList<>(); - T[] all = type.getEnumConstants(); - boolean[] flags = new boolean[all.length]; + @SuppressWarnings("unchecked") + Set values = EnumSet.noneOf((Class)def.getClass()); + @SuppressWarnings("unchecked") + T[] all = (T[])def.getClass().getEnumConstants(); for (int i = 0; i < length; i++) { values.add(all[buffer.readInt()]); - flags[i] = true; } - return new Flags<>(flags, values, buffer.readInt()); + return new Flags<>(def, values, buffer.readInt()); } public static List flags(T[] values, boolean[] flags) { @@ -38,16 +38,30 @@ public record Flags> ( return wears; } - public boolean includes(T t) { - return flags[t.ordinal()]; - } - - public int compareTo(Flags other) { - return Arrays.compare(flags, other.flags); - } - public void write(PacketByteBuf buffer) { buffer.writeCollection(values, (buf, value) -> buf.writeInt(value.ordinal())); buffer.writeInt(colorCode); } + + @Override + public String name() { + return "[Flags " + values + "]"; + } + + @Override + public List> getOptions() { + return def.getOptions(); + } + + @SuppressWarnings("unchecked") + @Override + public boolean matches(TValue o) { + return o.getClass() == def.getClass() && values.contains((T)o); + } + + @Override + public int compareTo(Flags other) { + return Integer.compare(colorCode(), other.colorCode()); + } + } diff --git a/src/main/java/com/minelittlepony/api/pony/meta/Gender.java b/src/main/java/com/minelittlepony/api/pony/meta/Gender.java index 5217ae29..8a9a08d8 100644 --- a/src/main/java/com/minelittlepony/api/pony/meta/Gender.java +++ b/src/main/java/com/minelittlepony/api/pony/meta/Gender.java @@ -1,6 +1,6 @@ package com.minelittlepony.api.pony.meta; -public enum Gender implements TriggerPixelType { +public enum Gender implements TValue { MARE(0), STALLION(0xffffff), ABOMONATION(0x888888); diff --git a/src/main/java/com/minelittlepony/api/pony/meta/Race.java b/src/main/java/com/minelittlepony/api/pony/meta/Race.java index 858a319d..64071f06 100644 --- a/src/main/java/com/minelittlepony/api/pony/meta/Race.java +++ b/src/main/java/com/minelittlepony/api/pony/meta/Race.java @@ -1,8 +1,6 @@ package com.minelittlepony.api.pony.meta; -import java.util.*; - -public enum Race implements TriggerPixelType { +public enum Race implements TValue { HUMAN (0x000000, false, false), EARTH (0xf9b131, false, false), PEGASUS (0x88caf0, true, false), @@ -17,16 +15,13 @@ public enum Race implements TriggerPixelType { BATPONY (0xeeeeee, true, false), SEAPONY (0x3655dd, false, true); - private boolean wings; - private boolean horn; + private final boolean wings; + private final boolean horn; - private int triggerPixel; - - public static final List REGISTRY = Arrays.asList(values()); - - Race(int triggerPixel, boolean wings, boolean horn) { - this.triggerPixel = triggerPixel; + private final int colorCode; + Race(int colorCode, boolean wings, boolean horn) { + this.colorCode = colorCode; this.wings = wings; this.horn = horn; } @@ -68,6 +63,6 @@ public enum Race implements TriggerPixelType { @Override public int colorCode() { - return triggerPixel; + return colorCode; } } diff --git a/src/main/java/com/minelittlepony/api/pony/meta/Size.java b/src/main/java/com/minelittlepony/api/pony/meta/Size.java index dfe132ce..41404baf 100644 --- a/src/main/java/com/minelittlepony/api/pony/meta/Size.java +++ b/src/main/java/com/minelittlepony/api/pony/meta/Size.java @@ -3,13 +3,13 @@ package com.minelittlepony.api.pony.meta; /** * Represents the different model sizes that are possible. * - * For a list of possible presets, look at {@link Sizes}. + * For a list of possible presets, look at {@link SizePreset}. * This interface exists for servers so they can work with this information even though they might not have access to the client config. * */ -public interface Size extends TriggerPixelType { +public interface Size extends TValue { /** - * The Enum index of this size. May be used on the client to convert to an instance of Sizes or use {@link Sizes#of} + * The Enum index of this size. May be used on the client to convert to an instance of Sizes or use {@link SizePreset#of} * * Made to be compatible with the enum variant. */ diff --git a/src/main/java/com/minelittlepony/api/pony/meta/Sizes.java b/src/main/java/com/minelittlepony/api/pony/meta/SizePreset.java similarity index 84% rename from src/main/java/com/minelittlepony/api/pony/meta/Sizes.java rename to src/main/java/com/minelittlepony/api/pony/meta/SizePreset.java index fc3447c4..d49c2223 100644 --- a/src/main/java/com/minelittlepony/api/pony/meta/Sizes.java +++ b/src/main/java/com/minelittlepony/api/pony/meta/SizePreset.java @@ -9,7 +9,7 @@ import com.minelittlepony.api.config.PonyConfig; * * For spooky things at a distance, use {@link Size} instead. */ -public enum Sizes implements Size { +public enum SizePreset implements Size { TALL (0x534b76, 0.45f, 1.1F, 1.15F), BULKY (0xce3254, 0.5f, 1, 1.05F), LANKY (0x3254ce, 0.45F, 0.85F, 0.9F), @@ -18,13 +18,12 @@ public enum Sizes implements Size { FOAL (0xffbe53, 0.25f, 0.6F, 0.5F), UNSET (0x000000, 1, 1, 1); - private int triggerValue; + private final int triggerValue; + private final float shadowSize; + private final float scale; + private final float camera; - private float shadowSize; - private float scale; - private float camera; - - Sizes(int pixel, float shadowSz, float scaleF, float cameraF) { + SizePreset(int pixel, float shadowSz, float scaleF, float cameraF) { triggerValue = pixel; shadowSize = shadowSz; scale = scaleF; @@ -58,5 +57,4 @@ public enum Sizes implements Size { public float eyeDistanceFactor() { return eyeHeightFactor(); } - } diff --git a/src/main/java/com/minelittlepony/api/pony/meta/TValue.java b/src/main/java/com/minelittlepony/api/pony/meta/TValue.java new file mode 100644 index 00000000..cdb5525a --- /dev/null +++ b/src/main/java/com/minelittlepony/api/pony/meta/TValue.java @@ -0,0 +1,66 @@ +package com.minelittlepony.api.pony.meta; + +import java.util.Arrays; +import java.util.List; + +/** + * Interface for enums that can be parsed from an image trigger pixel value. + */ +public interface TValue { + /** + * Gets the pixel colour matching this enum value. + */ + int colorCode(); + + /** + * Gets the pixel colour matching this enum value, adjusted to fill all three channels. + */ + default int getChannelAdjustedColorCode() { + return colorCode(); + } + + /** + * Gets a string representation of this value. + */ + String name(); + + default String getHexValue() { + return toHex(colorCode()); + } + + /** + * Returns a list of possible values this trigger pixel can accept. + */ + @SuppressWarnings("unchecked") + default List> getOptions() { + if (this instanceof Enum) { + // cast is required because gradle's compiler is more strict + return Arrays.asList(getClass().getEnumConstants()); + } + return List.of(); + } + + default boolean matches(TValue o) { + return o != null && colorCode() == o.colorCode(); + } + + static String toHex(int color) { + String v = Integer.toHexString(color).toUpperCase(); + while (v.length() < 6) { + v = "0" + v; + } + return "#" + v; + } + + public record Numeric(int colorCode) implements TValue { + @Override + public String name() { + return "[Numeric " + getHexValue() + "]"; + } + + @Override + public List> getOptions() { + return List.of(); + } + } +} diff --git a/src/main/java/com/minelittlepony/api/pony/meta/TailLength.java b/src/main/java/com/minelittlepony/api/pony/meta/TailLength.java index daaafa22..4650b405 100644 --- a/src/main/java/com/minelittlepony/api/pony/meta/TailLength.java +++ b/src/main/java/com/minelittlepony/api/pony/meta/TailLength.java @@ -1,6 +1,6 @@ package com.minelittlepony.api.pony.meta; -public enum TailLength implements TriggerPixelType { +public enum TailLength implements TValue { STUB (0x425844), QUARTER (0xd19fe4), HALF (0x534b76), diff --git a/src/main/java/com/minelittlepony/api/pony/meta/TailShape.java b/src/main/java/com/minelittlepony/api/pony/meta/TailShape.java index 97504723..db3def93 100644 --- a/src/main/java/com/minelittlepony/api/pony/meta/TailShape.java +++ b/src/main/java/com/minelittlepony/api/pony/meta/TailShape.java @@ -1,6 +1,6 @@ package com.minelittlepony.api.pony.meta; -public enum TailShape implements TriggerPixelType { +public enum TailShape implements TValue { STRAIGHT(0), BUMPY (0xfc539f), SWIRLY (0x3eff22), 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 a33c52c8..18a609f4 100644 --- a/src/main/java/com/minelittlepony/api/pony/meta/TriggerPixel.java +++ b/src/main/java/com/minelittlepony/api/pony/meta/TriggerPixel.java @@ -1,112 +1,91 @@ package com.minelittlepony.api.pony.meta; -import net.minecraft.client.texture.NativeImage; +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; +import net.minecraft.util.math.ColorHelper; + +import org.joml.Vector2i; import com.minelittlepony.common.util.Color; -import java.util.Arrays; +import java.util.*; /** * Individual trigger pixels for a pony skin. - * */ -@SuppressWarnings("unchecked") -public enum TriggerPixel { - RACE(Race.HUMAN, Channel.ALL, 0, 0), - TAIL(TailLength.FULL, Channel.ALL, 1, 0), - GENDER(Gender.MARE, Channel.ALL, 2, 0), - SIZE(Sizes.NORMAL, Channel.ALL, 3, 0), - GLOW(null, Channel.RAW, 0, 1), - WEARABLES(Wearable.NONE, Channel.RAW, 1, 1), - TAIL_SHAPE(TailShape.STRAIGHT, Channel.ALL, 2, 1); +public interface TriggerPixel { + Vector2i MAX_COORDS = new Vector2i(); - private final int x; - private final int y; + TriggerPixel RACE = ofOptions(0, 0, Race.HUMAN, Race.values()); + TriggerPixel TAIL = ofOptions(1, 0, TailLength.FULL, TailLength.values()); + TriggerPixel GENDER = ofOptions(2, 0, Gender.MARE, Gender.values()); + TriggerPixel TAIL_SHAPE = ofOptions(2, 1, TailShape.STRAIGHT, TailShape.values()); + TriggerPixel SIZE = ofOptions(3, 0, SizePreset.NORMAL, SizePreset.values()); + TriggerPixel GLOW = ofColor(0, 1); + TriggerPixel> WEARABLES = ofFlags(1, 1, Wearable.EMPTY_FLAGS, Wearable.values()); - private final Channel channel; + static > TriggerPixel ofOptions(int x, int y, T def, T[] options) { + MAX_COORDS.x = Math.max(MAX_COORDS.x, x); + MAX_COORDS.y = Math.max(MAX_COORDS.y, y); + Int2ObjectOpenHashMap lookup = buildLookup(options); + return image -> { + int color = Color.abgrToArgb(image.getColor(x, y)); - private final TriggerPixelType def; - - private static final TriggerPixel[] VALUES = values(); - private static final int MAX_READ_X = Arrays.stream(VALUES).mapToInt(i -> i.x).max().getAsInt(); - private static final int MAX_READ_Y = Arrays.stream(VALUES).mapToInt(i -> i.y).max().getAsInt(); - - TriggerPixel(TriggerPixelType def, Channel channel, int x, int y) { - this.def = def; - this.channel = channel; - this.x = x; - this.y = y; + if (ColorHelper.Argb.getAlpha(color) < 255) { + return (T)def; + } + return lookup.getOrDefault(color & 0x00FFFFFF, def); + }; } - /** - * Reads this trigger pixel's value and returns the raw colour. - * - * @param image Image to read - */ - public int readColor(NativeImage image) { - return channel.readValue(x, y, image); + static TriggerPixel ofColor(int x, int y) { + MAX_COORDS.x = Math.max(MAX_COORDS.x, x); + MAX_COORDS.y = Math.max(MAX_COORDS.y, y); + return image -> Color.abgrToArgb(image.getColor(x, y)); } - /** - * Reads this trigger pixel's value and parses it to an Enum instance. - * - * @param image Image to read - */ - public > T readValue(NativeImage image) { - int color = readColor(image); + static & TValue> TriggerPixel> ofFlags(int x, int y, Flags def, T[] options) { + MAX_COORDS.x = Math.max(MAX_COORDS.x, x); + MAX_COORDS.y = Math.max(MAX_COORDS.y, y); + Int2ObjectOpenHashMap lookup = buildLookup(options); + var flagReader = new Object() { + boolean readFlag(int color, Set values) { + T value = lookup.get(color); + return value != null && values.add(value); + } + }; + return image -> { + int color = Color.abgrToArgb(image.getColor(x, y)); + if (ColorHelper.Argb.getAlpha(color) < 255) { + return def; + } + @SuppressWarnings("unchecked") + Set values = EnumSet.noneOf((Class)def.def().getClass()); + if (flagReader.readFlag(ColorHelper.Argb.getRed(color), values) + || flagReader.readFlag(ColorHelper.Argb.getGreen(color), values) + || flagReader.readFlag(ColorHelper.Argb.getBlue(color), values)) { + return new Flags<>(def.def(), values, color & 0x00FFFFFF); + } + return def; + }; + } - if (Channel.ALPHA.readValue(x, y, image) < 255) { - return (T)def; + static > Int2ObjectOpenHashMap buildLookup(T[] options) { + Int2ObjectOpenHashMap lookup = new Int2ObjectOpenHashMap<>(); + for (int i = 0; i < options.length; i++) { + lookup.put(options[i].colorCode(), options[i]); } - - return TriggerPixelType.getByTriggerPixel((T)def, color); + return lookup; } - public & TriggerPixelType> TriggerPixelType.Multiple readFlags(NativeImage image) { - boolean[] out = new boolean[def.getClass().getEnumConstants().length]; - readFlags(out, image); - return new TriggerPixelType.Multiple<>(readColor(image), (T)def, out); + + T read(Mat image); + + static boolean isTriggerPixelCoord(int x, int y) { + return x <= MAX_COORDS.x && y <= MAX_COORDS.y; } - public & TriggerPixelType> void readFlags(boolean[] out, NativeImage image) { - readFlag(out, Channel.RED, image); - readFlag(out, Channel.GREEN, image); - readFlag(out, Channel.BLUE, image); + interface Mat { + int getColor(int x, int y); } - private & TriggerPixelType> void readFlag(boolean[] out, Channel channel, NativeImage image) { - - if (Channel.ALPHA.readValue(x, y, image) < 255) { - return; - } - - T value = TriggerPixelType.getByTriggerPixel((T)def, channel.readValue(x, y, image)); - - out[value.ordinal()] |= value != def; - } - - public static boolean isTriggerPixelCoord(int x, int y) { - return x <= MAX_READ_X && y <= MAX_READ_Y; - } - - enum Channel { - RAW (0xFFFFFFFF, 0), - ALL (0x00FFFFFF, 0), - ALPHA(0x000000FF, 24), - RED (0x000000FF, 0), - GREEN(0x000000FF, 8), - BLUE (0x000000FF, 16); - - private int mask; - private int offset; - - Channel(int mask, int offset) { - this.mask = mask; - this.offset = offset; - } - - public int readValue(int x, int y, NativeImage image) { - return (Color.abgrToArgb(image.getColor(x, y)) >> offset) & mask; - } - } } diff --git a/src/main/java/com/minelittlepony/api/pony/meta/TriggerPixelType.java b/src/main/java/com/minelittlepony/api/pony/meta/TriggerPixelType.java deleted file mode 100644 index 6657a445..00000000 --- a/src/main/java/com/minelittlepony/api/pony/meta/TriggerPixelType.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.minelittlepony.api.pony.meta; - -import java.util.Arrays; -import java.util.List; - -/** - * Interface for enums that can be parsed from an image trigger pixel value. - */ -public interface TriggerPixelType> { - /** - * Gets the pixel colour matching this enum value. - */ - int colorCode(); - - /** - * Gets the pixel colour matching this enum value, adjusted to fill all three channels. - */ - default int getChannelAdjustedColorCode() { - return colorCode(); - } - - /** - * Gets a string representation of this value. - */ - default String name() { - return "[Numeric " + getHexValue() + "]"; - } - - default String getHexValue() { - return toHex(colorCode()); - } - - /** - * Returns a list of possible values this trigger pixel can accept. - */ - @SuppressWarnings("unchecked") - default List> getOptions() { - if (this instanceof Enum) { - // cast is required because gradle's compiler is more strict - return Arrays.asList(getClass().getEnumConstants()); - } - return List.of(); - } - - default boolean matches(Object o) { - return equals(o); - } - - /** - * Gets the enum value corresponding to the given enum type and pixel value. - * If none are found, the first parameter is returned as the default. - * - * @param type Return type and default value. - * @param pixelValue The pixel colour to search for. - */ - @SuppressWarnings("unchecked") - static > T getByTriggerPixel(T type, int pixelValue) { - return (T)type.getOptions().stream() - .filter(i -> i.colorCode() == pixelValue) - .findFirst() - .orElse(type); - } - - static > TriggerPixelType of(int color) { - return () -> color; - } - - static String toHex(int color) { - String v = Integer.toHexString(color).toUpperCase(); - while (v.length() < 6) { - v = "0" + v; - } - return "#" + v; - } - - public record Multiple & TriggerPixelType> ( - int colorCode, - T def, - boolean[] value - ) implements TriggerPixelType { - @Override - public String name() { - return "[Flags " + Arrays.toString(value) + "]"; - } - - @Override - public List> getOptions() { - return def.getOptions(); - } - - @Override - public boolean matches(Object o) { - return o.getClass() == def.getClass() && value()[((Enum)o).ordinal()]; - } - } -} diff --git a/src/main/java/com/minelittlepony/api/pony/meta/Wearable.java b/src/main/java/com/minelittlepony/api/pony/meta/Wearable.java index e75a0847..c5b92ade 100644 --- a/src/main/java/com/minelittlepony/api/pony/meta/Wearable.java +++ b/src/main/java/com/minelittlepony/api/pony/meta/Wearable.java @@ -1,14 +1,13 @@ package com.minelittlepony.api.pony.meta; import net.minecraft.util.Identifier; - -import com.minelittlepony.common.util.Color; +import net.minecraft.util.math.ColorHelper; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; -public enum Wearable implements TriggerPixelType { +public enum Wearable implements TValue { NONE (0x00, null), CROWN (0x16, new Identifier("minelittlepony", "textures/models/crown.png")), MUFFIN (0x32, new Identifier("minelittlepony", "textures/models/muffin.png")), @@ -22,13 +21,11 @@ public enum Wearable implements TriggerPixelType { private int triggerValue; private final Identifier id; - private final Identifier texture; - public static final List VALUES = Arrays.stream(values()).toList(); - public static final Map REGISTRY = VALUES.stream().collect(Collectors.toMap(Wearable::getId, Function.identity())); + public static final Map REGISTRY = Arrays.stream(values()).collect(Collectors.toMap(Wearable::getId, Function.identity())); - public static final Flags EMPTY_FLAGS = Flags.of(Wearable.class); + public static final Flags EMPTY_FLAGS = Flags.of(NONE); Wearable(int pixel, Identifier texture) { triggerValue = pixel; @@ -55,6 +52,6 @@ public enum Wearable implements TriggerPixelType { @Override public int getChannelAdjustedColorCode() { - return triggerValue == 0 ? 0 : Color.argbToHex(255, triggerValue, triggerValue, triggerValue); + return triggerValue == 0 ? 0 : ColorHelper.Argb.getArgb(255, triggerValue, triggerValue, triggerValue); } } diff --git a/src/main/java/com/minelittlepony/client/ClientPonyConfig.java b/src/main/java/com/minelittlepony/client/ClientPonyConfig.java deleted file mode 100644 index 6928df91..00000000 --- a/src/main/java/com/minelittlepony/client/ClientPonyConfig.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.minelittlepony.client; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.entity.player.PlayerEntity; - -import com.minelittlepony.api.config.PonyConfig; -import com.minelittlepony.client.model.armour.ArmourTextureResolver; -import com.minelittlepony.client.render.MobRenderers; -import com.minelittlepony.common.client.gui.VisibilityMode; -import com.minelittlepony.common.util.settings.Setting; - -import java.nio.file.Path; - -class ClientPonyConfig extends PonyConfig { - /** - * Visibility mode for the horse button. - */ - 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"); - - public ClientPonyConfig(Path path) { - super(path); - MobRenderers.REGISTRY.values().forEach(r -> value("entities", r.name, true)); - disablePonifiedArmour.onChanged(t -> ArmourTextureResolver.INSTANCE.invalidate()); - } - - @Override - public void save() { - super.save(); - PlayerEntity player = MinecraftClient.getInstance().player; - if (player != null) { - player.calculateDimensions(); - } - } -} diff --git a/src/main/java/com/minelittlepony/client/MineLittlePony.java b/src/main/java/com/minelittlepony/client/MineLittlePony.java index e46c419c..e4ccf122 100644 --- a/src/main/java/com/minelittlepony/client/MineLittlePony.java +++ b/src/main/java/com/minelittlepony/client/MineLittlePony.java @@ -1,8 +1,10 @@ package com.minelittlepony.client; +import com.minelittlepony.api.config.PonyConfig; import com.minelittlepony.api.events.Channel; -import com.minelittlepony.api.pony.PonyManager; import com.minelittlepony.client.model.ModelType; +import com.minelittlepony.client.model.armour.ArmourTextureResolver; +import com.minelittlepony.client.render.MobRenderers; import com.minelittlepony.client.render.PonyRenderDispatcher; import com.minelittlepony.common.client.gui.VisibilityMode; import com.minelittlepony.common.client.gui.element.Button; @@ -12,6 +14,8 @@ import com.minelittlepony.common.event.ScreenInitCallback; import com.minelittlepony.common.event.SkinFilterCallback; import com.minelittlepony.common.util.GamePaths; +import java.nio.file.Path; + import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper; @@ -22,6 +26,7 @@ import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.TitleScreen; import net.minecraft.client.option.KeyBinding; import net.minecraft.client.util.InputUtil; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.resource.ResourceType; import net.minecraft.util.Identifier; import org.apache.logging.log4j.LogManager; @@ -37,7 +42,6 @@ public class MineLittlePony implements ClientModInitializer { public static final Logger logger = LogManager.getLogger("MineLittlePony"); - private ClientPonyConfig config; private PonyManagerImpl ponyManager; private VariatedTextureSupplier variatedTextures; @@ -64,7 +68,7 @@ public class MineLittlePony implements ClientModInitializer { hasHdSkins = FabricLoader.getInstance().isModLoaded("hdskins"); hasModMenu = FabricLoader.getInstance().isModLoaded("modmenu"); - config = new ClientPonyConfig(GamePaths.getConfigDirectory().resolve("minelp.json")); + PonyConfig config = new ClientPonyConfig(GamePaths.getConfigDirectory().resolve("minelp.json")); ponyManager = new PonyManagerImpl(config); variatedTextures = new VariatedTextureSupplier(); @@ -108,7 +112,7 @@ public class MineLittlePony implements ClientModInitializer { private void onScreenInit(Screen screen, ScreenInitCallback.ButtonList buttons) { if (screen instanceof TitleScreen) { - VisibilityMode mode = config.horseButton.get(); + VisibilityMode mode = ClientPonyConfig.getInstance().horseButton.get(); boolean show = mode == VisibilityMode.ON || (mode == VisibilityMode.AUTO && !(hasHdSkins || hasModMenu )); @@ -129,7 +133,7 @@ public class MineLittlePony implements ClientModInitializer { } } - public PonyManager getManager() { + public PonyManagerImpl getManager() { return ponyManager; } @@ -143,5 +147,22 @@ public class MineLittlePony implements ClientModInitializer { public PonyRenderDispatcher getRenderDispatcher() { return renderDispatcher; } + + private static final class ClientPonyConfig extends PonyConfig { + public ClientPonyConfig(Path path) { + super(path); + MobRenderers.REGISTRY.values().forEach(r -> value("entities", r.name, true)); + disablePonifiedArmour.onChanged(t -> ArmourTextureResolver.INSTANCE.invalidate()); + } + + @Override + public void save() { + super.save(); + PlayerEntity player = MinecraftClient.getInstance().player; + if (player != null) { + player.calculateDimensions(); + } + } + } } diff --git a/src/main/java/com/minelittlepony/client/PonyDataLoader.java b/src/main/java/com/minelittlepony/client/PonyDataLoader.java index d97baa34..a02e9176 100644 --- a/src/main/java/com/minelittlepony/client/PonyDataLoader.java +++ b/src/main/java/com/minelittlepony/client/PonyDataLoader.java @@ -6,7 +6,6 @@ import net.minecraft.util.Identifier; import com.google.gson.*; import com.minelittlepony.api.pony.PonyData; -import com.minelittlepony.api.pony.meta.*; import com.minelittlepony.client.util.render.NativeUtil; import java.io.IOException; @@ -53,16 +52,7 @@ class PonyDataLoader { }).map(PonyDataLoader::loaded).orElseGet(() -> { return load(callback -> { NativeUtil.parseImage(identifier, image -> { - callback.accept(new PonyData( - TriggerPixel.RACE.readValue(image), - TriggerPixel.TAIL.readValue(image), - TriggerPixel.TAIL_SHAPE.readValue(image), - TriggerPixel.GENDER.readValue(image), - TriggerPixel.SIZE.readValue(image), - TriggerPixel.GLOW.readColor(image), - TriggerPixel.WEARABLES.readFlags(image), - noSkin - )); + callback.accept(new PonyData(image, noSkin)); }, e -> { MineLittlePony.logger.fatal("Unable to read {} metadata", identifier, e); callback.accept(PonyData.NULL); diff --git a/src/main/java/com/minelittlepony/client/PonyManagerImpl.java b/src/main/java/com/minelittlepony/client/PonyManagerImpl.java index dbc963c7..7eced8d2 100644 --- a/src/main/java/com/minelittlepony/client/PonyManagerImpl.java +++ b/src/main/java/com/minelittlepony/client/PonyManagerImpl.java @@ -9,10 +9,10 @@ import com.minelittlepony.client.render.blockentity.skull.PonySkullRenderer; import org.jetbrains.annotations.Nullable; import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; +import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.AbstractClientPlayerEntity; import net.minecraft.client.util.DefaultSkinHelper; import net.minecraft.resource.ResourceManager; -import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.Identifier; @@ -22,25 +22,18 @@ import java.util.UUID; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; -/** - * The PonyManager is responsible for reading and recoding all the pony data associated with an entity of skin. - */ -class PonyManagerImpl implements PonyManager, SimpleSynchronousResourceReloadListener { +public class PonyManagerImpl implements PonyManager, SimpleSynchronousResourceReloadListener { private static final Identifier ID = new Identifier("minelittlepony", "background_ponies"); private final PonyConfig config; private final LoadingCache defaultedPoniesCache = CacheBuilder.newBuilder() .expireAfterAccess(30, TimeUnit.SECONDS) - .build(CacheLoader.from(resource -> { - return new Pony(resource, PonyDataLoader.parse(resource, true)); - })); + .build(CacheLoader.from(resource -> new Pony(resource, PonyDataLoader.parse(resource, true)))); private final LoadingCache poniesCache = CacheBuilder.newBuilder() .expireAfterAccess(30, TimeUnit.SECONDS) - .build(CacheLoader.from(resource -> { - return new Pony(resource, PonyDataLoader.parse(resource, false)); - })); + .build(CacheLoader.from(resource -> new Pony(resource, PonyDataLoader.parse(resource, false)))); public PonyManagerImpl(PonyConfig config) { this.config = config; @@ -56,78 +49,62 @@ class PonyManagerImpl implements PonyManager, SimpleSynchronousResourceReloadLis } @Override - public Pony getPony(Identifier resource) { - return loadPony(resource, false); + public Pony getPony(PlayerEntity player) { + clearCache(); + return getPony(getSkin(player), player instanceof ForcedPony ? null : player.getGameProfile() == null ? player.getUuid() : player.getGameProfile().getId()); } @Override - public Optional getPony(@Nullable Entity entity) { + public Optional getPony(LivingEntity entity) { if (entity instanceof PlayerEntity player) { return Optional.of(getPony(player)); } - - if (entity instanceof LivingEntity living) { - return Optional.ofNullable(MineLittlePony.getInstance().getRenderDispatcher().getPonyRenderer(living)).map(d -> d.getEntityPony(living)); - } - - return Optional.empty(); + Identifier skin = getSkin(entity); + return skin == null ? Optional.empty() : Optional.of(getPony(skin, null)); } @Override - public Pony getPony(PlayerEntity player) { - Identifier skin = getSkin(player); - UUID uuid = player.getGameProfile() == null ? player.getUuid() : player.getGameProfile().getId(); - - if (skin != null) { - if (player instanceof PonyManager.ForcedPony) { - return getPony(skin); - } - - return getPony(skin, uuid); + public Pony getPony(@Nullable Identifier resource, @Nullable UUID uuid) { + if (resource == null) { + return uuid == null ? loadPony(DefaultSkinHelper.getTexture(), true) : getBackgroundPony(uuid); } - if (config.ponyLevel.get() == PonyLevel.PONIES) { + Pony pony = loadPony(resource, false); + + if (uuid != null && PonyConfig.getInstance().ponyLevel.get() == PonyLevel.PONIES && pony.metadata().race().isHuman()) { return getBackgroundPony(uuid); } - - return loadPony(DefaultSkinHelper.getTexture(uuid).texture(), true); - } - - @Override - public Pony getPony(Identifier resource, UUID uuid) { - Pony pony = getPony(resource); - - if (config.ponyLevel.get() == PonyLevel.PONIES && pony.metadata().race().isHuman()) { - return getBackgroundPony(uuid); - } - return pony; } @Override - public Pony getBackgroundPony(UUID uuid) { - return loadPony(MineLittlePony.getInstance().getVariatedTextures().get(VariatedTextureSupplier.BACKGROUND_PONIES_POOL, uuid).orElse(DefaultSkinHelper.getTexture(uuid).texture()), true); + public Pony getBackgroundPony(@Nullable UUID uuid) { + if (config.ponyLevel.get() == PonyLevel.PONIES) { + return loadPony(MineLittlePony.getInstance().getVariatedTextures().get(VariatedTextureSupplier.BACKGROUND_PONIES_POOL, uuid).orElse(DefaultSkinHelper.getTexture(uuid).texture()), true); + } + return loadPony(DefaultSkinHelper.getTexture(uuid).texture(), true); } @Nullable - private Identifier getSkin(PlayerEntity player) { - if (player.getGameProfile() == null) { - return null; - } - if (player instanceof AbstractClientPlayerEntity) { - return ((AbstractClientPlayerEntity)player).method_52814().texture(); + private Identifier getSkin(LivingEntity entity) { + if (entity instanceof PlayerEntity player) { + if (player.getGameProfile() != null && player instanceof AbstractClientPlayerEntity clientPlayer) { + return clientPlayer.method_52814().texture(); + } + } else { + if (MineLittlePony.getInstance().getRenderDispatcher().getPonyRenderer(entity) != null) { + return MinecraftClient.getInstance().getEntityRenderDispatcher().getRenderer(entity).getTexture(entity); + } } return null; } - @Override public void removePony(Identifier resource) { poniesCache.invalidate(resource); defaultedPoniesCache.invalidate(resource); } - @Override public void clearCache() { MineLittlePony.logger.info("Flushed {} cached ponies.", poniesCache.size()); poniesCache.invalidateAll(); diff --git a/src/main/java/com/minelittlepony/client/PonySettingsscreen.java b/src/main/java/com/minelittlepony/client/PonySettingsscreen.java index a07a2e0a..5894fd97 100644 --- a/src/main/java/com/minelittlepony/client/PonySettingsscreen.java +++ b/src/main/java/com/minelittlepony/client/PonySettingsscreen.java @@ -35,7 +35,7 @@ public class PonySettingsscreen extends GameGui { public static final Text SCALE_SHOW = Text.translatable("minelp.debug.scale.sa"); public static final Text SCALE_MIN = Text.translatable("minelp.debug.scale.min"); - private ClientPonyConfig config; + private final PonyConfig config = PonyConfig.getInstance(); private final ScrollContainer content = new ScrollContainer(); @@ -43,9 +43,6 @@ public class PonySettingsscreen extends GameGui { public PonySettingsscreen(@Nullable Screen parent) { super(Text.literal(OPTIONS_PREFIX + "title"), parent); - - config = (ClientPonyConfig)PonyConfig.getInstance(); - content.margin.top = 30; content.margin.bottom = 30; content.getContentPadding().top = 10; diff --git a/src/main/java/com/minelittlepony/client/compat/hdskins/GuiSkinsMineLP.java b/src/main/java/com/minelittlepony/client/compat/hdskins/GuiSkinsMineLP.java index dc2e0b72..6908749b 100644 --- a/src/main/java/com/minelittlepony/client/compat/hdskins/GuiSkinsMineLP.java +++ b/src/main/java/com/minelittlepony/client/compat/hdskins/GuiSkinsMineLP.java @@ -1,6 +1,5 @@ package com.minelittlepony.client.compat.hdskins; -import com.minelittlepony.api.pony.Pony; import com.minelittlepony.client.PonySettingsscreen; import com.minelittlepony.client.MineLittlePony; import com.minelittlepony.common.client.gui.dimension.Bounds; @@ -29,13 +28,13 @@ class GuiSkinsMineLP extends GuiSkins { chooser.addSkinChangedEventListener(type -> { MineLittlePony.logger.debug("Invalidating old local skin, checking updated local skin"); if (type == SkinType.SKIN) { - Pony.getManager().removePony(previewer.getLocal().getSkins().get(SkinType.SKIN).getId()); + MineLittlePony.getInstance().getManager().removePony(previewer.getLocal().getSkins().get(SkinType.SKIN).getId()); } }); uploader.addSkinLoadedEventListener((type, location, profileTexture) -> { MineLittlePony.logger.debug("Invalidating old remote skin, checking updated remote skin"); if (type == SkinType.SKIN) { - Pony.getManager().removePony(location); + MineLittlePony.getInstance().getManager().removePony(location); } }); } diff --git a/src/main/java/com/minelittlepony/client/compat/hdskins/LegendOverlayWidget.java b/src/main/java/com/minelittlepony/client/compat/hdskins/LegendOverlayWidget.java index 4f31273d..edc3f79e 100644 --- a/src/main/java/com/minelittlepony/client/compat/hdskins/LegendOverlayWidget.java +++ b/src/main/java/com/minelittlepony/client/compat/hdskins/LegendOverlayWidget.java @@ -4,7 +4,7 @@ import net.minecraft.client.gui.DrawContext; import net.minecraft.text.Text; import com.minelittlepony.api.pony.*; -import com.minelittlepony.api.pony.meta.TriggerPixelType; +import com.minelittlepony.api.pony.meta.TValue; import com.minelittlepony.common.client.gui.ITextContext; import com.minelittlepony.common.client.gui.dimension.Bounds; import com.minelittlepony.hdskins.client.gui.Carousel; @@ -37,7 +37,7 @@ class LegendOverlayWidget implements Carousel.Element, ITextContext { }); } - private void drawLegendBlock(DrawContext context, int index, int x, int y, int mouseX, int mouseY, String key, TriggerPixelType value) { + private void drawLegendBlock(DrawContext context, int index, int x, int y, int mouseX, int mouseY, String key, TValue value) { context.fill(0, 0, LEGEND_BLOCK_BOUNDS.width, LEGEND_BLOCK_BOUNDS.height, 0xFF003333); context.fill(1, 1, LEGEND_BLOCK_BOUNDS.width - 1, LEGEND_BLOCK_BOUNDS.height - 1, value.colorCode() | 0xFF000000); 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 fbf54517..0c76ef0d 100644 --- a/src/main/java/com/minelittlepony/client/compat/hdskins/MineLPHDSkins.java +++ b/src/main/java/com/minelittlepony/client/compat/hdskins/MineLPHDSkins.java @@ -43,7 +43,7 @@ public class MineLPHDSkins extends SkinsProxy implements ClientModInitializer { SkinsProxy.instance = this; seaponySkinType = SkinType.register(AquaticPlayerPonyRenderer.SKIN_TYPE_ID, Items.COD_BUCKET.getDefaultStack()); - Wearable.VALUES.forEach(wearable -> { + Wearable.REGISTRY.values().forEach(wearable -> { if (wearable != Wearable.NONE) { wearableTypes.put(SkinType.register(wearable.getId(), Items.BUNDLE.getDefaultStack()), wearable); } @@ -100,7 +100,7 @@ public class MineLPHDSkins extends SkinsProxy implements ClientModInitializer { PlayerSkin main = dummy.getTextures().get(SkinType.SKIN); Wearable wearable = Wearable.REGISTRY.getOrDefault(type.getId(), Wearable.NONE); PonyData metadata = Pony.getManager().getPony(main.getId()).metadata(); - if (wearable != Wearable.NONE && metadata.isWearing(wearable)) { + if (wearable != Wearable.NONE && metadata.gear().matches(wearable)) { if (wearable.isSaddlebags() && metadata.race().supportsLegacySaddlebags()) { return Optional.of(main.getId()); diff --git a/src/main/java/com/minelittlepony/client/model/AbstractPonyModel.java b/src/main/java/com/minelittlepony/client/model/AbstractPonyModel.java index a5aed610..7ce480d6 100644 --- a/src/main/java/com/minelittlepony/client/model/AbstractPonyModel.java +++ b/src/main/java/com/minelittlepony/client/model/AbstractPonyModel.java @@ -2,7 +2,7 @@ package com.minelittlepony.client.model; import com.minelittlepony.api.model.*; import com.minelittlepony.api.events.PonyModelPrepareCallback; -import com.minelittlepony.api.pony.meta.Sizes; +import com.minelittlepony.api.pony.meta.SizePreset; import com.minelittlepony.client.transform.PonyTransformation; import com.minelittlepony.client.util.render.RenderList; import com.minelittlepony.util.MathUtil; @@ -450,10 +450,10 @@ public abstract class AbstractPonyModel extends ClientPo arm.pivotX -= 6 * sigma; arm.pivotZ -= 2; } - if (getSize() == Sizes.TALL) { + if (getSize() == SizePreset.TALL) { arm.pivotY += 1; } - if (getSize() == Sizes.FOAL) { + if (getSize() == SizePreset.FOAL) { arm.pivotY -= 2; } @@ -558,7 +558,7 @@ public abstract class AbstractPonyModel extends ClientPo @Override public float getRiderYOffset() { - switch ((Sizes)getSize()) { + switch ((SizePreset)getSize()) { case NORMAL: return 0.4F; case FOAL: case TALL: diff --git a/src/main/java/com/minelittlepony/client/model/ClientPonyModel.java b/src/main/java/com/minelittlepony/client/model/ClientPonyModel.java index ceb4c76b..321e9f98 100644 --- a/src/main/java/com/minelittlepony/client/model/ClientPonyModel.java +++ b/src/main/java/com/minelittlepony/client/model/ClientPonyModel.java @@ -13,7 +13,7 @@ import com.minelittlepony.api.model.*; import com.minelittlepony.api.pony.Pony; import com.minelittlepony.api.pony.PonyData; import com.minelittlepony.api.pony.meta.Size; -import com.minelittlepony.api.pony.meta.Sizes; +import com.minelittlepony.api.pony.meta.SizePreset; import com.minelittlepony.mson.api.model.biped.MsonPlayer; /** @@ -79,7 +79,7 @@ public abstract class ClientPonyModel extends MsonPlayer @Override public Size getSize() { - return child ? Sizes.FOAL : PonyModel.super.getSize(); + return child ? SizePreset.FOAL : PonyModel.super.getSize(); } @Override diff --git a/src/main/java/com/minelittlepony/client/model/entity/race/UnicornModel.java b/src/main/java/com/minelittlepony/client/model/entity/race/UnicornModel.java index d09f5fed..f67cfe83 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/race/UnicornModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/race/UnicornModel.java @@ -3,7 +3,7 @@ package com.minelittlepony.client.model.entity.race; import com.minelittlepony.api.config.PonyConfig; import com.minelittlepony.api.model.*; import com.minelittlepony.api.pony.meta.Size; -import com.minelittlepony.api.pony.meta.Sizes; +import com.minelittlepony.api.pony.meta.SizePreset; import com.minelittlepony.client.model.part.UnicornHorn; import com.minelittlepony.client.util.render.RenderList; import com.minelittlepony.mson.api.ModelView; @@ -101,9 +101,9 @@ public class UnicornModel extends EarthPonyModel impl float x = 0.3F; float z = -0.4F; - if (size == Sizes.TALL || size == Sizes.YEARLING) { + if (size == SizePreset.TALL || size == SizePreset.YEARLING) { z += 0.05F; - } else if (size == Sizes.FOAL) { + } else if (size == SizePreset.FOAL) { x -= 0.1F; z -= 0.1F; } diff --git a/src/main/java/com/minelittlepony/client/model/gear/SaddleBags.java b/src/main/java/com/minelittlepony/client/model/gear/SaddleBags.java index 03e7764d..4e6005d2 100644 --- a/src/main/java/com/minelittlepony/client/model/gear/SaddleBags.java +++ b/src/main/java/com/minelittlepony/client/model/gear/SaddleBags.java @@ -59,7 +59,7 @@ public class SaddleBags extends WearableGear { strap.visible = wearable == Wearable.SADDLE_BAGS_BOTH; dropAmount = hangLow ? 0.15F : 0; - dropAmount = model.getAttributes().metadata.getInterpolator(interpolatorId).interpolate("dropAmount", dropAmount, 3); + dropAmount = model.getAttributes().getMainInterpolator().interpolate("dropAmount", dropAmount, 3); } @Override diff --git a/src/main/java/com/minelittlepony/client/render/EquineRenderManager.java b/src/main/java/com/minelittlepony/client/render/EquineRenderManager.java index 03a16657..307ffc50 100644 --- a/src/main/java/com/minelittlepony/client/render/EquineRenderManager.java +++ b/src/main/java/com/minelittlepony/client/render/EquineRenderManager.java @@ -26,7 +26,7 @@ public class EquineRenderManager playerModel; - private final IPonyRenderContext renderer; + private final PonyRenderContext renderer; private final FrustrumCheck frustrum = new FrustrumCheck<>(this); @@ -34,11 +34,11 @@ public class EquineRenderManager renderer) { + public EquineRenderManager(PonyRenderContext renderer) { this.renderer = renderer; } - public IPonyRenderContext getContext() { + public PonyRenderContext getContext() { return renderer; } @@ -95,7 +95,7 @@ public class EquineRenderManager renderer = MineLittlePony.getInstance().getRenderDispatcher().getPonyRenderer(ridingEntity); + PonyRenderContext renderer = MineLittlePony.getInstance().getRenderDispatcher().getPonyRenderer(ridingEntity); if (renderer != null) { // negate vanilla translations so the rider begins at the ridees feet. @@ -141,6 +141,10 @@ public class EquineRenderManager & PonyModel> extends Gear.Context { +public interface PonyRenderContext & PonyModel> extends Gear.Context { Pony getEntityPony(T entity); diff --git a/src/main/java/com/minelittlepony/client/render/PonyRenderDispatcher.java b/src/main/java/com/minelittlepony/client/render/PonyRenderDispatcher.java index 9780b8ac..6e50f407 100644 --- a/src/main/java/com/minelittlepony/client/render/PonyRenderDispatcher.java +++ b/src/main/java/com/minelittlepony/client/render/PonyRenderDispatcher.java @@ -6,8 +6,8 @@ import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.api.pony.Pony; import com.minelittlepony.api.pony.PonyPosture; import com.minelittlepony.client.mixin.MixinEntityRenderers; -import com.minelittlepony.client.render.entity.PlayerPonyRenderer; import com.minelittlepony.client.render.entity.AquaticPlayerPonyRenderer; +import com.minelittlepony.client.render.entity.PlayerPonyRenderer; import org.jetbrains.annotations.Nullable; @@ -83,15 +83,15 @@ public class PonyRenderDispatcher { @SuppressWarnings("unchecked") @Nullable - public & PonyModel> IPonyRenderContext getPonyRenderer(@Nullable T entity) { + public & PonyModel> PonyRenderContext getPonyRenderer(@Nullable T entity) { if (entity == null) { return null; } EntityRenderer renderer = MinecraftClient.getInstance().getEntityRenderDispatcher().getRenderer(entity); - if (renderer instanceof IPonyRenderContext) { - return (IPonyRenderContext) renderer; + if (renderer instanceof PonyRenderContext) { + return (PonyRenderContext) renderer; } return null; diff --git a/src/main/java/com/minelittlepony/client/render/entity/AbstractPonyRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/AbstractPonyRenderer.java index f442f00c..07ac6eab 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/AbstractPonyRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/AbstractPonyRenderer.java @@ -5,7 +5,7 @@ import com.minelittlepony.api.pony.Pony; import com.minelittlepony.api.pony.meta.Wearable; import com.minelittlepony.client.model.*; import com.minelittlepony.client.render.DebugBoundingBoxRenderer; -import com.minelittlepony.client.render.IPonyRenderContext; +import com.minelittlepony.client.render.PonyRenderContext; import com.minelittlepony.client.render.EquineRenderManager; import com.minelittlepony.client.render.entity.feature.*; import com.minelittlepony.client.render.entity.npc.textures.TextureSupplier; @@ -27,7 +27,7 @@ import net.minecraft.entity.mob.MobEntity; import net.minecraft.text.Text; import net.minecraft.util.Identifier; -public abstract class AbstractPonyRenderer & PonyModel & ModelWithArms> extends MobEntityRenderer implements IPonyRenderContext { +public abstract class AbstractPonyRenderer & PonyModel & ModelWithArms> extends MobEntityRenderer implements PonyRenderContext { protected final EquineRenderManager manager = new EquineRenderManager<>(this); @@ -91,7 +91,7 @@ public abstract class AbstractPonyRenderer> { +public class PlayerPonyRenderer extends PlayerEntityRenderer implements PonyRenderContext> { protected final EquineRenderManager> manager = new EquineRenderManager<>(this); @@ -81,7 +81,7 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements IPonyRen Pony pony = getEntityPony(entity); model = manager.setModel(modelsCache.apply(getPlayerRace(entity, pony))).body(); // EntityModelFeatures: We have to force it to use our models otherwise EMF overrides it and breaks pony rendering - shadowRadius = manager.getModel().getSize().shadowSize(); + shadowRadius = manager.getShadowSize(); super.render(entity, entityYaw, tickDelta, stack, renderContext, lightUv); DebugBoundingBoxRenderer.render(pony, this, entity, stack, renderContext, tickDelta); @@ -89,7 +89,7 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements IPonyRen // (shadows are drawn after us) if (!entity.hasVehicle() && !entity.isSleeping()) { float yaw = MathHelper.lerpAngleDegrees(tickDelta, entity.prevBodyYaw, entity.bodyYaw); - float l = entity.getWidth() / 2 * pony.size().scaleFactor(); + float l = entity.getWidth() / 2 * manager.getScaleFactor(); stack.multiply(RotationAxis.NEGATIVE_Y.rotationDegrees(yaw)); stack.translate(0, 0, -l); diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/AbstractPonyFeature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/AbstractPonyFeature.java index 2be0b9b8..9369356c 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/AbstractPonyFeature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/feature/AbstractPonyFeature.java @@ -2,7 +2,7 @@ package com.minelittlepony.client.render.entity.feature; import com.minelittlepony.api.model.ModelWrapper; import com.minelittlepony.api.model.PonyModel; -import com.minelittlepony.client.render.IPonyRenderContext; +import com.minelittlepony.client.render.PonyRenderContext; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.feature.FeatureRenderer; @@ -13,10 +13,10 @@ import net.minecraft.entity.LivingEntity; public abstract class AbstractPonyFeature & PonyModel> extends FeatureRenderer { - private final IPonyRenderContext context; + private final PonyRenderContext context; @SuppressWarnings("unchecked") - public AbstractPonyFeature(IPonyRenderContext context) { + public AbstractPonyFeature(PonyRenderContext context) { super((FeatureRendererContext)context); this.context = context; } @@ -39,7 +39,7 @@ public abstract class AbstractPonyFeature & FeatureRendererContext> C getContext() { + protected & FeatureRendererContext> C getContext() { return (C)context; } diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/ArmourFeature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/ArmourFeature.java index d3f7ecbd..2de77f75 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/ArmourFeature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/feature/ArmourFeature.java @@ -3,7 +3,7 @@ package com.minelittlepony.client.render.entity.feature; import com.minelittlepony.api.model.ModelWrapper; import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.client.model.armour.*; -import com.minelittlepony.client.render.IPonyRenderContext; +import com.minelittlepony.client.render.PonyRenderContext; import com.minelittlepony.common.util.Color; import net.minecraft.client.MinecraftClient; @@ -22,7 +22,7 @@ import net.minecraft.util.Identifier; public class ArmourFeature & PonyModel> extends AbstractPonyFeature { - public ArmourFeature(IPonyRenderContext context, BakedModelManager bakery) { + public ArmourFeature(PonyRenderContext context, BakedModelManager bakery) { super(context); } diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/CapeFeature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/CapeFeature.java index baa08fba..9aac7f8c 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/CapeFeature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/feature/CapeFeature.java @@ -2,7 +2,7 @@ package com.minelittlepony.client.render.entity.feature; import com.minelittlepony.api.model.BodyPart; import com.minelittlepony.client.model.ClientPonyModel; -import com.minelittlepony.client.render.IPonyRenderContext; +import com.minelittlepony.client.render.PonyRenderContext; import net.minecraft.client.network.AbstractClientPlayerEntity; import net.minecraft.client.render.OverlayTexture; @@ -17,7 +17,7 @@ import net.minecraft.entity.EquipmentSlot; public class CapeFeature> extends AbstractPonyFeature { - public CapeFeature(IPonyRenderContext context) { + public CapeFeature(PonyRenderContext context) { super(context); } diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/DJPon3Feature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/DJPon3Feature.java index 90f6a23b..2b30505a 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/DJPon3Feature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/feature/DJPon3Feature.java @@ -11,13 +11,13 @@ import com.minelittlepony.client.model.ModelType; import com.minelittlepony.api.model.BodyPart; import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.client.model.DJPon3EarsModel; -import com.minelittlepony.client.render.IPonyRenderContext; +import com.minelittlepony.client.render.PonyRenderContext; public class DJPon3Feature & PonyModel> extends AbstractPonyFeature { private final DJPon3EarsModel deadMau5 = ModelType.DJ_PON_3.createModel(); - public DJPon3Feature(IPonyRenderContext context) { + public DJPon3Feature(PonyRenderContext context) { super(context); } diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/ElytraFeature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/ElytraFeature.java index 3f92cf0a..6aec6652 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/ElytraFeature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/feature/ElytraFeature.java @@ -5,7 +5,7 @@ import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.api.pony.PonyPosture; import com.minelittlepony.client.model.ModelType; import com.minelittlepony.client.model.PonyElytra; -import com.minelittlepony.client.render.IPonyRenderContext; +import com.minelittlepony.client.render.PonyRenderContext; import net.minecraft.client.network.AbstractClientPlayerEntity; import net.minecraft.client.render.OverlayTexture; @@ -29,7 +29,7 @@ public class ElytraFeature & Po @SuppressWarnings("unchecked") private final PonyElytra modelElytra = (PonyElytra)ModelType.ELYTRA.createModel(); - public ElytraFeature(IPonyRenderContext rp) { + public ElytraFeature(PonyRenderContext rp) { super(rp); } diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/GearFeature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/GearFeature.java index 2ba3802f..a5e93b01 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/GearFeature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/feature/GearFeature.java @@ -15,7 +15,7 @@ import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.api.model.gear.Gear; import com.minelittlepony.api.pony.meta.Wearable; import com.minelittlepony.client.model.ModelType; -import com.minelittlepony.client.render.IPonyRenderContext; +import com.minelittlepony.client.render.PonyRenderContext; import java.util.*; import java.util.concurrent.TimeUnit; @@ -42,7 +42,7 @@ public class GearFeature & Pony return randomizedOrder; })); - public GearFeature(IPonyRenderContext renderer) { + public GearFeature(PonyRenderContext renderer) { super(renderer); } diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/GlowingEyesFeature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/GlowingEyesFeature.java index 150bb58c..567f4d5d 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/GlowingEyesFeature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/feature/GlowingEyesFeature.java @@ -8,13 +8,13 @@ import net.minecraft.entity.LivingEntity; import net.minecraft.util.Identifier; import com.minelittlepony.api.model.PonyModel; -import com.minelittlepony.client.render.IPonyRenderContext; +import com.minelittlepony.client.render.PonyRenderContext; public class GlowingEyesFeature & PonyModel> extends EyesFeatureRenderer { private final RenderLayer layer; - public & IPonyRenderContext & IGlowingRenderer> GlowingEyesFeature(V renderer) { + public & PonyRenderContext & IGlowingRenderer> GlowingEyesFeature(V renderer) { super(renderer); layer = RenderLayer.getEyes(renderer.getEyeTexture()); } diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/HeldItemFeature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/HeldItemFeature.java index fc4655a1..3acb2a7c 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/HeldItemFeature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/feature/HeldItemFeature.java @@ -2,7 +2,7 @@ package com.minelittlepony.client.render.entity.feature; import com.minelittlepony.api.model.BodyPart; import com.minelittlepony.api.model.PonyModel; -import com.minelittlepony.client.render.IPonyRenderContext; +import com.minelittlepony.client.render.PonyRenderContext; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.feature.FeatureRendererContext; @@ -18,10 +18,10 @@ import net.minecraft.util.Arm; public class HeldItemFeature & PonyModel & ModelWithArms> extends HeldItemFeatureRenderer { - private final IPonyRenderContext context; + private final PonyRenderContext context; @SuppressWarnings("unchecked") - public HeldItemFeature(IPonyRenderContext context, HeldItemRenderer renderer) { + public HeldItemFeature(PonyRenderContext context, HeldItemRenderer renderer) { super((FeatureRendererContext)context, renderer); this.context = context; } diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/IllagerHeldItemFeature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/IllagerHeldItemFeature.java index ad39e485..98ddad3a 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/IllagerHeldItemFeature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/feature/IllagerHeldItemFeature.java @@ -6,11 +6,11 @@ import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.mob.IllagerEntity; import com.minelittlepony.client.model.entity.race.AlicornModel; -import com.minelittlepony.client.render.IPonyRenderContext; +import com.minelittlepony.client.render.PonyRenderContext; public class IllagerHeldItemFeature> extends HeldItemFeature { - public IllagerHeldItemFeature(IPonyRenderContext livingPony, HeldItemRenderer renderer) { + public IllagerHeldItemFeature(PonyRenderContext livingPony, HeldItemRenderer renderer) { super(livingPony, renderer); } diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/PassengerFeature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/PassengerFeature.java index 4d15a550..ea65138a 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/PassengerFeature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/feature/PassengerFeature.java @@ -17,7 +17,7 @@ import net.minecraft.util.Identifier; import com.minelittlepony.api.model.BodyPart; import com.minelittlepony.client.model.ClientPonyModel; -import com.minelittlepony.client.render.IPonyRenderContext; +import com.minelittlepony.client.render.PonyRenderContext; import java.util.Optional; @@ -25,7 +25,7 @@ public class PassengerFeature renderer, EntityRendererFactory.Context context) { + public PassengerFeature(PonyRenderContext renderer, EntityRendererFactory.Context context) { super(renderer); model = new ParrotEntityModel(context.getPart(EntityModelLayers.PARROT)); } diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/SkullFeature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/SkullFeature.java index 97aaab78..4965edd9 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/SkullFeature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/feature/SkullFeature.java @@ -3,7 +3,7 @@ package com.minelittlepony.client.render.entity.feature; import com.minelittlepony.api.model.BodyPart; import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.client.model.AbstractPonyModel; -import com.minelittlepony.client.render.IPonyRenderContext; +import com.minelittlepony.client.render.PonyRenderContext; import com.mojang.authlib.GameProfile; import java.util.Map; @@ -34,7 +34,7 @@ public class SkullFeature & Pon private final Map headModels; - public SkullFeature(IPonyRenderContext renderPony, EntityModelLoader entityModelLoader) { + public SkullFeature(PonyRenderContext renderPony, EntityModelLoader entityModelLoader) { super(renderPony); headModels = SkullBlockEntityRenderer.getModels(entityModelLoader); } diff --git a/src/main/java/com/minelittlepony/client/render/entity/npc/AbstractNpcRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/npc/AbstractNpcRenderer.java index 2c514b57..9a24520b 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/npc/AbstractNpcRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/npc/AbstractNpcRenderer.java @@ -20,17 +20,12 @@ import com.minelittlepony.client.render.entity.npc.textures.*; import java.util.*; abstract class AbstractNpcRenderer extends PonyRenderer> { - - private final String entityType; - private final Map>> models = new EnumMap<>(Race.class); - private final NpcClothingFeature, AbstractNpcRenderer> clothing; public AbstractNpcRenderer(EntityRendererFactory.Context context, String type, TextureSupplier textureSupplier, TextureSupplier formatter) { - super(context, ModelType.getPlayerModel(Race.EARTH).getKey(false), new SillyPonyTextureSupplier<>(textureSupplier, formatter)); - entityType = type; - clothing = new NpcClothingFeature<>(this, entityType); + super(context, ModelType.getPlayerModel(Race.EARTH).getKey(false), SillyPonyTextureSupplier.create(textureSupplier, formatter)); + clothing = new NpcClothingFeature<>(this, type); addFeature(clothing); } @@ -42,12 +37,9 @@ abstract class AbstractNpcRenderer @Override public boolean shouldRender(ClientPonyModel model, T entity, Wearable wearable, Gear gear) { - - boolean special = SillyPonyTextureSupplier.isBestPony(entity); - if (wearable == Wearable.SADDLE_BAGS_BOTH) { VillagerProfession profession = entity.getVillagerData().getProfession(); - return !special && profession != VillagerProfession.NONE && ( + return !SillyPonyTextureSupplier.isBestPony(entity) && profession != VillagerProfession.NONE && ( profession == VillagerProfession.CARTOGRAPHER || profession == VillagerProfession.FARMER || profession == VillagerProfession.FISHERMAN diff --git a/src/main/java/com/minelittlepony/client/render/entity/npc/NpcClothingFeature.java b/src/main/java/com/minelittlepony/client/render/entity/npc/NpcClothingFeature.java index 66c87ed2..ef8a749b 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/npc/NpcClothingFeature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/npc/NpcClothingFeature.java @@ -17,7 +17,7 @@ import net.minecraft.village.VillagerProfession; import net.minecraft.village.VillagerType; import com.minelittlepony.api.model.PonyModel; -import com.minelittlepony.client.render.IPonyRenderContext; +import com.minelittlepony.client.render.PonyRenderContext; import com.minelittlepony.client.render.entity.feature.AbstractPonyFeature; import com.minelittlepony.client.util.render.TextureFlattener; import com.minelittlepony.util.ResourceUtil; @@ -27,7 +27,7 @@ import java.util.*; class NpcClothingFeature< T extends LivingEntity & VillagerDataContainer, M extends EntityModel & PonyModel, - C extends FeatureRendererContext & IPonyRenderContext> extends AbstractPonyFeature { + C extends FeatureRendererContext & PonyRenderContext> extends AbstractPonyFeature { private static final Int2ObjectMap LEVEL_TO_ID = Util.make(new Int2ObjectOpenHashMap<>(), a -> { a.put(1, new Identifier("stone")); diff --git a/src/main/java/com/minelittlepony/client/render/entity/npc/VillagerPonyRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/npc/VillagerPonyRenderer.java index 6bf02fc0..bf6fa04f 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/npc/VillagerPonyRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/npc/VillagerPonyRenderer.java @@ -1,7 +1,6 @@ package com.minelittlepony.client.render.entity.npc; import net.minecraft.client.render.entity.EntityRendererFactory; -import net.minecraft.entity.passive.MerchantEntity; import net.minecraft.entity.passive.VillagerEntity; import net.minecraft.util.math.MathHelper; @@ -10,12 +9,10 @@ import com.minelittlepony.client.model.ClientPonyModel; import com.minelittlepony.client.render.entity.npc.textures.*; public class VillagerPonyRenderer extends AbstractNpcRenderer { - - private static final String TYPE = "villager"; private static final TextureSupplier FORMATTER = TextureSupplier.formatted("minelittlepony", "textures/entity/villager/%s.png"); public VillagerPonyRenderer(EntityRendererFactory.Context context) { - super(context, TYPE, + super(context, "villager", TextureSupplier.ofPool(VariatedTextureSupplier.BACKGROUND_PONIES_POOL, PlayerTextureSupplier.create(ProfessionTextureSupplier.create(FORMATTER))), FORMATTER); } @@ -25,9 +22,7 @@ public class VillagerPonyRenderer extends AbstractNpcRenderer { model.onSetModelAngles((m, move, swing, ticks, entity) -> { m.getAttributes().visualHeight += SillyPonyTextureSupplier.isCrownPony(entity) ? 0.3F : -0.1F; - boolean isHeadRolling = entity instanceof MerchantEntity && ((MerchantEntity)entity).getHeadRollingTimeLeft() > 0; - - if (isHeadRolling) { + if (entity.getHeadRollingTimeLeft() > 0) { m.head.yaw = 0.3F * MathHelper.sin(0.45F * ticks); } }); diff --git a/src/main/java/com/minelittlepony/client/render/entity/npc/ZomponyVillagerRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/npc/ZomponyVillagerRenderer.java index 93ffccfd..6f660324 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/npc/ZomponyVillagerRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/npc/ZomponyVillagerRenderer.java @@ -11,12 +11,10 @@ import com.minelittlepony.client.model.ClientPonyModel; import com.minelittlepony.client.render.entity.npc.textures.*; public class ZomponyVillagerRenderer extends AbstractNpcRenderer { - - private static final String TYPE = "zombie_villager"; private static final TextureSupplier FORMATTER = TextureSupplier.formatted("minelittlepony", "textures/entity/zombie_villager/zombie_%s.png"); public ZomponyVillagerRenderer(EntityRendererFactory.Context context) { - super(context, TYPE, + super(context, "zombie_villager", TextureSupplier.ofPool(VariatedTextureSupplier.BACKGROUND_ZOMPONIES_POOL, TextureSupplier.ofPool(VariatedTextureSupplier.BACKGROUND_PONIES_POOL, PlayerTextureSupplier.create(ProfessionTextureSupplier.create(FORMATTER)))), diff --git a/src/main/java/com/minelittlepony/client/render/entity/npc/textures/PlayerTextureSupplier.java b/src/main/java/com/minelittlepony/client/render/entity/npc/textures/PlayerTextureSupplier.java index 3964deee..08f26104 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/npc/textures/PlayerTextureSupplier.java +++ b/src/main/java/com/minelittlepony/client/render/entity/npc/textures/PlayerTextureSupplier.java @@ -5,8 +5,6 @@ import net.minecraft.entity.LivingEntity; import net.minecraft.util.Identifier; import net.minecraft.util.Util; -import org.jetbrains.annotations.Nullable; - import com.minelittlepony.api.pony.Pony; import com.minelittlepony.client.SkinsProxy; @@ -15,31 +13,20 @@ import java.util.function.Function; public class PlayerTextureSupplier { public static TextureSupplier create(TextureSupplier fallback) { - Function customNameCache = Util.memoize(Entry::new); + Function> customNameCache = Util.memoize(name -> { + return SkullBlockEntity.fetchProfile(name).thenApply(profile -> { + return profile + .map(p -> SkinsProxy.instance.getSkinTexture(p)) + .filter(skin -> !Pony.getManager().getPony(skin).race().isHuman()) + .orElse(null); + }); + }); return entity -> { - Identifier override = entity.hasCustomName() ? customNameCache.apply(entity.getCustomName().getString()).getTexture() : null; + Identifier override = entity.hasCustomName() ? customNameCache.apply(entity.getCustomName().getString()).getNow(null) : null; if (override != null) { return override; } return fallback.apply(entity); }; } - - static final class Entry { - private final CompletableFuture profile; - - Entry(String name) { - profile = SkullBlockEntity.fetchProfile(name).thenApply(profile -> { - return profile - .map(p -> SkinsProxy.instance.getSkinTexture(p)) - .filter(skin -> !Pony.getManager().getPony(skin).race().isHuman()) - .orElse(null); - }); - } - - @Nullable - public Identifier getTexture() { - return profile.getNow(null); - } - } } diff --git a/src/main/java/com/minelittlepony/client/render/entity/npc/textures/SillyPonyTextureSupplier.java b/src/main/java/com/minelittlepony/client/render/entity/npc/textures/SillyPonyTextureSupplier.java index 1750fed8..5bd82546 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/npc/textures/SillyPonyTextureSupplier.java +++ b/src/main/java/com/minelittlepony/client/render/entity/npc/textures/SillyPonyTextureSupplier.java @@ -4,22 +4,11 @@ import net.minecraft.entity.LivingEntity; import net.minecraft.util.Identifier; import net.minecraft.village.VillagerDataContainer; -public class SillyPonyTextureSupplier implements TextureSupplier { - - private final TextureSupplier fallback; - - private final Identifier egg; - private final Identifier egg2; - - public SillyPonyTextureSupplier(TextureSupplier fallback, TextureSupplier formatter) { - this.fallback = fallback; - this.egg = formatter.apply("silly_pony"); - this.egg2 = formatter.apply("tiny_silly_pony"); - } - - @Override - public Identifier apply(T entity) { - return isBestPony(entity) ? (entity.isBaby() ? egg2 : egg) : fallback.apply(entity); +public class SillyPonyTextureSupplier { + public static TextureSupplier create(TextureSupplier fallback, TextureSupplier formatter) { + Identifier egg = formatter.apply("silly_pony"); + Identifier egg2 = formatter.apply("tiny_silly_pony"); + return entity -> isBestPony(entity) ? (entity.isBaby() ? egg2 : egg) : fallback.apply(entity); } public static boolean isBestPony(LivingEntity entity) { diff --git a/src/main/java/com/minelittlepony/client/transform/PonyTransformation.java b/src/main/java/com/minelittlepony/client/transform/PonyTransformation.java index dd1715ca..63b29976 100644 --- a/src/main/java/com/minelittlepony/client/transform/PonyTransformation.java +++ b/src/main/java/com/minelittlepony/client/transform/PonyTransformation.java @@ -6,7 +6,7 @@ import net.minecraft.util.math.Vec3d; import com.minelittlepony.api.model.BodyPart; import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.api.pony.meta.Size; -import com.minelittlepony.api.pony.meta.Sizes; +import com.minelittlepony.api.pony.meta.SizePreset; import java.util.Arrays; import java.util.Map; @@ -15,7 +15,7 @@ import java.util.stream.Collectors; public enum PonyTransformation { - NORMAL(Sizes.NORMAL, 0, 3F, 0.75F) { + NORMAL(SizePreset.NORMAL, 0, 3F, 0.75F) { @Override public void transform(PonyModel model, BodyPart part, MatrixStack stack) { if (model.getAttributes().isSwimming) stack.translate(0, -0.3F, 0); @@ -37,7 +37,7 @@ public enum PonyTransformation { } } }, - LANKY(Sizes.LANKY, 0, 2.6F, 0.75F) { + LANKY(SizePreset.LANKY, 0, 2.6F, 0.75F) { @Override public void transform(PonyModel model, BodyPart part, MatrixStack stack) { if (model.getAttributes().isSwimming) stack.translate(0, -0.2F, 0); @@ -73,7 +73,7 @@ public enum PonyTransformation { } } }, - BULKY(Sizes.BULKY, 0, 2.3F, 0.75F) { + BULKY(SizePreset.BULKY, 0, 2.3F, 0.75F) { @Override public void transform(PonyModel model, BodyPart part, MatrixStack stack) { if (model.getAttributes().isCrouching) stack.translate(0, -0.15F, 0); @@ -108,7 +108,7 @@ public enum PonyTransformation { } } }, - FOAL(Sizes.FOAL, 0, 3.8F, 0.75F) { + FOAL(SizePreset.FOAL, 0, 3.8F, 0.75F) { @Override public void transform(PonyModel model, BodyPart part, MatrixStack stack) { if (model.getAttributes().isSwimming) stack.translate(0, -0.9F, 0); @@ -138,7 +138,7 @@ public enum PonyTransformation { } } }, - TALL(Sizes.TALL, 0, 2.2F, 0.75F) { + TALL(SizePreset.TALL, 0, 2.2F, 0.75F) { @Override public void transform(PonyModel model, BodyPart part, MatrixStack stack) { if (model.getAttributes().isCrouching) stack.translate(0, -0.15F, 0); @@ -170,7 +170,7 @@ public enum PonyTransformation { } } }, - YEARLING(Sizes.YEARLING, 0, 3.8F, 0.75F) { + YEARLING(SizePreset.YEARLING, 0, 3.8F, 0.75F) { @Override public void transform(PonyModel model, BodyPart part, MatrixStack stack) { if (model.getAttributes().isSwimming) stack.translate(0, -0.6F, 0); @@ -205,12 +205,12 @@ public enum PonyTransformation { } }; - private static final Map REGISTRY = Arrays.stream(values()).collect(Collectors.toMap(i -> i.size, Function.identity())); + private static final Map REGISTRY = Arrays.stream(values()).collect(Collectors.toMap(i -> i.size, Function.identity())); - private final Sizes size; + private final Size size; private final Vec3d riderOffset; - PonyTransformation(Sizes size, float rX, float rY, float rZ) { + PonyTransformation(Size size, float rX, float rY, float rZ) { this.size = size; riderOffset = new Vec3d(rX, rY, rZ); } diff --git a/src/main/java/com/minelittlepony/client/util/render/NativeUtil.java b/src/main/java/com/minelittlepony/client/util/render/NativeUtil.java index 75639cd4..2de10b02 100644 --- a/src/main/java/com/minelittlepony/client/util/render/NativeUtil.java +++ b/src/main/java/com/minelittlepony/client/util/render/NativeUtil.java @@ -5,6 +5,7 @@ import net.minecraft.client.texture.*; import net.minecraft.resource.Resource; import net.minecraft.util.Identifier; +import com.minelittlepony.api.pony.meta.TriggerPixel; import com.mojang.blaze3d.systems.RenderSystem; import java.io.InputStream; @@ -86,11 +87,11 @@ public class NativeUtil { } } - public static void parseImage(Identifier resource, Consumer consumer, Consumer fail) { + public static void parseImage(Identifier resource, Consumer consumer, Consumer fail) { parseImage(resource, consumer, fail, 0); } - private static void parseImage(Identifier resource, Consumer consumer, Consumer fail, int attempt) { + private static void parseImage(Identifier resource, Consumer consumer, Consumer fail, int attempt) { try { if (!RenderSystem.isOnRenderThread()) { RenderSystem.recordRenderCall(() -> parseImage(resource, consumer, fail, attempt)); @@ -105,7 +106,7 @@ public class NativeUtil { if (loadedTexture instanceof NativeImageBackedTexture nibt) { NativeImage image = nibt.getImage(); if (image != null) { - consumer.accept(image); + consumer.accept(image::getColor); return; } } @@ -113,7 +114,7 @@ public class NativeUtil { Resource res = mc.getResourceManager().getResource(resource).orElse(null); if (res != null) { try (InputStream inputStream = res.getInputStream()){ - consumer.accept(NativeImage.read(inputStream)); + consumer.accept(NativeImage.read(inputStream)::getColor); return; } } @@ -124,7 +125,7 @@ public class NativeUtil { } } - private static void __reconstructNativeImage(Identifier resource, Consumer consumer, Consumer fail, int attempt) { + private static void __reconstructNativeImage(Identifier resource, Consumer consumer, Consumer fail, int attempt) { MinecraftClient mc = MinecraftClient.getInstance(); TextureManager textures = mc.getTextureManager(); @@ -156,7 +157,7 @@ public class NativeUtil { // This allocates a new array to store the image every time. // Don't do this every time. Keep a cache and store it so we don't destroy memory. image.loadFromTextureImage(0, false); - consumer.accept(image); + consumer.accept(image::getColor); } } }