Convert PonyData classes into records

This commit is contained in:
Sollace 2023-09-25 02:55:43 +01:00
parent ff800006f7
commit 8eca1796e1
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
37 changed files with 189 additions and 440 deletions

View file

@ -53,7 +53,7 @@ public interface IModel {
}
default Race getRace() {
return PonyConfig.getEffectiveRace(getMetadata().getRace());
return PonyConfig.getEffectiveRace(getMetadata().race());
}
/**

View file

@ -25,6 +25,6 @@ public interface IUnicorn extends IModel {
* Gets the preferred magic color for this mode.
*/
default int getMagicColor() {
return getMetadata().getGlowColor();
return getMetadata().glowColor();
}
}

View file

@ -42,14 +42,14 @@ public interface IPony extends Comparable<IPony> {
* Gets the race associated with this pony.
*/
default Race race() {
return PonyConfig.getEffectiveRace(metadata().getRace());
return PonyConfig.getEffectiveRace(metadata().race());
}
/**
* Returns true if and only if this metadata represents a pony that can cast magic.
*/
default boolean hasMagic() {
return race().hasHorn() && metadata().getGlowColor() != 0;
return race().hasHorn() && metadata().glowColor() != 0;
}
/**

View file

@ -19,37 +19,37 @@ public interface IPonyData extends Comparable<IPonyData> {
*
* This is the actual race value. For the effective race, prefer going through {@link IPony#race}
*/
Race getRace();
Race race();
/**
* Gets the length of the pony's tail.
*/
TailLength getTailLength();
TailLength tailLength();
/**
* Gets the shape of the pony's tail.
*/
TailShape getTailShape();
TailShape tailShape();
/**
* Get the pony's gender (usually female).
*/
Gender getGender();
Gender gender();
/**
* Gets the current pony size.
*/
Size getSize();
Size size();
/**
* Gets the magical glow colour for magic-casting races. Returns 0 otherwise.
*/
int getGlowColor();
int glowColor();
/**
* Returns an array of wearables that this pony is carrying.
*/
Wearable[] getGear();
Wearable[] gear();
/**
* Checks it this pony is wearing the given accessory.
@ -59,22 +59,24 @@ public interface IPonyData extends Comparable<IPonyData> {
/**
* Gets an interpolator for interpolating values.
*/
Interpolator getInterpolator(UUID interpolatorId);
default Interpolator getInterpolator(UUID interpolatorId) {
return Interpolator.linear(interpolatorId);
}
/**
* Gets the trigger pixel values as they appeared in the underlying image.
*/
Map<String, TriggerPixelType<?>> getTriggerPixels();
Map<String, TriggerPixelType<?>> attributes();
@Override
default int compareTo(@Nullable IPonyData o) {
return o == this ? 0 : o == null ? 1 : ComparisonChain.start()
.compare(getRace(), o.getRace())
.compare(getTailLength(), o.getTailLength())
.compare(getGender(), o.getGender())
.compare(getSize().ordinal(), o.getSize().ordinal())
.compare(getGlowColor(), o.getGlowColor())
.compare(0, Arrays.compare(getGear(), o.getGear()))
.compare(race(), o.race())
.compare(tailLength(), o.tailLength())
.compare(gender(), o.gender())
.compare(size().ordinal(), o.size().ordinal())
.compare(glowColor(), o.glowColor())
.compare(0, Arrays.compare(gear(), o.gear()))
.result();
}
}

View file

@ -1,24 +0,0 @@
package com.minelittlepony.api.pony;
import java.util.List;
@SuppressWarnings("unchecked")
public class TriggerPixelSet<T extends Enum<T> & TriggerPixelType<T>> extends TriggerPixelValue<boolean[]> {
private final T def;
public TriggerPixelSet(int color, T def, boolean[] value) {
super(color, value);
this.def = def;
}
@Override
public List<TriggerPixelType<T>> getOptions() {
return def.getOptions();
}
@Override
public boolean matches(Object o) {
return o.getClass() == def.getClass() && getValue()[((Enum<?>)o).ordinal()];
}
}

View file

@ -1,5 +1,6 @@
package com.minelittlepony.api.pony;
import java.util.Arrays;
import java.util.List;
/**
@ -9,13 +10,13 @@ public interface TriggerPixelType<T> {
/**
* Gets the pixel colour matching this enum value.
*/
int getColorCode();
int colorCode();
/**
* Gets the pixel colour matching this enum value, adjusted to fill all three channels.
*/
default int getChannelAdjustedColorCode() {
return getColorCode();
return colorCode();
}
/**
@ -26,7 +27,7 @@ public interface TriggerPixelType<T> {
}
default String getHexValue() {
return toHex(getColorCode());
return toHex(colorCode());
}
/**
@ -55,7 +56,7 @@ public interface TriggerPixelType<T> {
@SuppressWarnings("unchecked")
static <T extends TriggerPixelType<T>> T getByTriggerPixel(T type, int pixelValue) {
return (T)type.getOptions().stream()
.filter(i -> i.getColorCode() == pixelValue)
.filter(i -> i.colorCode() == pixelValue)
.findFirst()
.orElse(type);
}
@ -71,4 +72,43 @@ public interface TriggerPixelType<T> {
}
return "#" + v;
}
public record Flags<T extends Enum<T> & TriggerPixelType<T>> (
int colorCode,
T def,
boolean[] value
) implements TriggerPixelType<boolean[]> {
@Override
public String name() {
return "[Flags " + Arrays.toString(value) + "]";
}
@SuppressWarnings("unchecked")
@Override
public List<TriggerPixelType<T>> getOptions() {
return def.getOptions();
}
@Override
public boolean matches(Object o) {
return o.getClass() == def.getClass() && value()[((Enum<?>)o).ordinal()];
}
}
public record Value<T> (
int colorCode,
T value
) implements TriggerPixelType<T> {
@Override
public String name() {
return value instanceof TriggerPixelType t ? t.name() : TriggerPixelType.super.name();
}
@SuppressWarnings("unchecked")
@Override
public <Option extends TriggerPixelType<T>> List<Option> getOptions() {
return value instanceof TriggerPixelType t ? t.getOptions() : TriggerPixelType.super.getOptions();
}
}
}

View file

@ -1,43 +0,0 @@
package com.minelittlepony.api.pony;
import java.util.List;
import java.util.Objects;
public class TriggerPixelValue<T> implements TriggerPixelType<T> {
private final int color;
private final T value;
public TriggerPixelValue(int color, T value) {
this.color = color;
this.value = value;
}
@SuppressWarnings("unchecked")
@Override
public String name() {
return value instanceof TriggerPixelType ? ((TriggerPixelType<T>)value).name() : TriggerPixelType.super.name();
}
@SuppressWarnings("unchecked")
@Override
public <Option extends TriggerPixelType<T>> List<Option> getOptions() {
return value instanceof TriggerPixelType ? ((TriggerPixelType<T>)value).getOptions() : TriggerPixelType.super.getOptions();
}
public T getValue() {
return value;
}
@Override
public int getColorCode() {
return color;
}
@Override
public boolean equals(Object o) {
return super.equals(o)
|| (o instanceof TriggerPixelValue && Objects.equals(((TriggerPixelValue<?>)o).getValue(), getValue()))
|| Objects.equals(o, getValue());
}
}

View file

@ -14,7 +14,7 @@ public enum Gender implements TriggerPixelType<Gender> {
}
@Override
public int getColorCode() {
public int colorCode() {
return triggerValue;
}

View file

@ -69,7 +69,7 @@ public enum Race implements TriggerPixelType<Race> {
}
@Override
public int getColorCode() {
public int colorCode() {
return triggerPixel;
}
}

View file

@ -27,20 +27,20 @@ public interface Size extends TriggerPixelType<Size> {
/**
* A scale factor that controls the size of the shadow that appears under the entity.
*/
float getShadowSize();
float shadowSize();
/**
* The global scale factor applied to all physical dimensions.
*/
float getScaleFactor();
float scaleFactor();
/**
* A scale factor used to alter the vertical eye position.
*/
float getEyeHeightFactor();
float eyeHeightFactor();
/**
* A scale factor used to alter the camera's distance.
*/
float getEyeDistanceFactor();
float eyeDistanceFactor();
}

View file

@ -34,17 +34,17 @@ public enum Sizes implements Size {
}
@Override
public float getShadowSize() {
public float shadowSize() {
return shadowSize * PonyConfig.getInstance().getGlobalScaleFactor();
}
@Override
public float getScaleFactor() {
public float scaleFactor() {
return scale * PonyConfig.getInstance().getGlobalScaleFactor();
}
@Override
public float getEyeHeightFactor() {
public float eyeHeightFactor() {
if (!PonyConfig.getInstance().fillycam.get()) {
return 1;
}
@ -52,7 +52,7 @@ public enum Sizes implements Size {
}
@Override
public float getEyeDistanceFactor() {
public float eyeDistanceFactor() {
if (!PonyConfig.getInstance().fillycam.get()) {
return 1;
}
@ -60,7 +60,7 @@ public enum Sizes implements Size {
}
@Override
public int getColorCode() {
public int colorCode() {
return triggerValue;
}

View file

@ -16,7 +16,7 @@ public enum TailLength implements TriggerPixelType<TailLength> {
}
@Override
public int getColorCode() {
public int colorCode() {
return triggerValue;
}
}

View file

@ -15,7 +15,7 @@ public enum TailShape implements TriggerPixelType<TailShape> {
}
@Override
public int getColorCode() {
public int colorCode() {
return triggerValue;
}
}

View file

@ -2,9 +2,7 @@ package com.minelittlepony.api.pony.meta;
import net.minecraft.client.texture.NativeImage;
import com.minelittlepony.api.pony.TriggerPixelSet;
import com.minelittlepony.api.pony.TriggerPixelType;
import com.minelittlepony.api.pony.TriggerPixelValue;
import com.minelittlepony.common.util.Color;
import java.util.Arrays;
@ -55,20 +53,20 @@ public enum TriggerPixel {
*
* @param image Image to read
*/
public <T extends TriggerPixelType<T>> TriggerPixelValue<T> readValue(NativeImage image) {
public <T extends TriggerPixelType<T>> TriggerPixelType.Value<T> readValue(NativeImage image) {
int color = readColor(image);
if (Channel.ALPHA.readValue(x, y, image) < 255) {
return new TriggerPixelValue<>(color, (T)def);
return new TriggerPixelType.Value<>(color, (T)def);
}
return new TriggerPixelValue<>(color, TriggerPixelType.getByTriggerPixel((T)def, color));
return new TriggerPixelType.Value<>(color, TriggerPixelType.getByTriggerPixel((T)def, color));
}
public <T extends Enum<T> & TriggerPixelType<T>> TriggerPixelSet<T> readFlags(NativeImage image) {
public <T extends Enum<T> & TriggerPixelType<T>> TriggerPixelType.Flags<T> readFlags(NativeImage image) {
boolean[] out = new boolean[def.getClass().getEnumConstants().length];
readFlags(out, image);
return new TriggerPixelSet<>(readColor(image), (T)def, out);
return new TriggerPixelType.Flags<>(readColor(image), (T)def, out);
}
public <T extends Enum<T> & TriggerPixelType<T>> void readFlags(boolean[] out, NativeImage image) {

View file

@ -45,7 +45,7 @@ public enum Wearable implements TriggerPixelType<Wearable> {
}
@Override
public int getColorCode() {
public int colorCode() {
return triggerValue;
}

View file

@ -74,14 +74,14 @@ public class MsgPonyData implements IPonyData {
}
public MsgPonyData(IPonyData data, boolean noSkin) {
race = data.getRace();
tailLength = data.getTailLength();
tailShape = data.getTailShape();
gender = data.getGender();
size = data.getSize();
glowColor = data.getGlowColor();
wearables = Wearable.flags(data.getGear());
wearableColor = data.getTriggerPixels().get("gear").getColorCode();
race = data.race();
tailLength = data.tailLength();
tailShape = data.tailShape();
gender = data.gender();
size = data.size();
glowColor = data.glowColor();
wearables = Wearable.flags(data.gear());
wearableColor = data.attributes().get("gear").colorCode();
this.noSkin = noSkin;
}
@ -96,7 +96,7 @@ public class MsgPonyData implements IPonyData {
buffer.writeInt(glowColor);
buffer.writeBoolean(noSkin);
Wearable[] gear = getGear();
Wearable[] gear = gear();
buffer.writeInt(gear.length);
for (int i = 0; i < gear.length; i++) {
buffer.writeInt(gear[i].ordinal());
@ -110,37 +110,37 @@ public class MsgPonyData implements IPonyData {
}
@Override
public Race getRace() {
public Race race() {
return race;
}
@Override
public TailLength getTailLength() {
public TailLength tailLength() {
return tailLength;
}
@Override
public TailShape getTailShape() {
public TailShape tailShape() {
return tailShape;
}
@Override
public Gender getGender() {
public Gender gender() {
return gender;
}
@Override
public Size getSize() {
public Size size() {
return size;
}
@Override
public int getGlowColor() {
public int glowColor() {
return glowColor;
}
@Override
public Wearable[] getGear() {
public Wearable[] gear() {
return Wearable.flags(wearables);
}
@ -155,7 +155,7 @@ public class MsgPonyData implements IPonyData {
}
@Override
public Map<String, TriggerPixelType<?>> getTriggerPixels() {
public Map<String, TriggerPixelType<?>> attributes() {
return triggerPixels.get();
}
@ -167,88 +167,45 @@ public class MsgPonyData implements IPonyData {
.add("tailShape", tailShape)
.add("gender", gender)
.add("size", size)
.add("wearables", getGear())
.add("wearables", gear())
.add("glowColor", TriggerPixelType.toHex(glowColor))
.toString();
}
private static final class MsgSize implements Size {
private final int ordinal;
private final String name;
private final float shadow;
private final float scale;
private final float eyeHeight;
private final float eyeDistance;
private final int triggerPixel;
private record MsgSize (
int ordinal,
String name,
float shadowSize,
float scaleFactor,
float eyeHeightFactor,
float eyeDistanceFactor,
int triggerPixel) implements Size {
MsgSize(Size size) {
ordinal = size.ordinal();
name = size.name();
shadow = size.getShadowSize();
scale = size.getScaleFactor();
eyeHeight = size.getEyeHeightFactor();
eyeDistance = size.getEyeDistanceFactor();
triggerPixel = size.getColorCode();
this(size.ordinal(), size.name(), size.shadowSize(), size.scaleFactor(), size.eyeHeightFactor(), size.eyeDistanceFactor(), size.colorCode());
}
MsgSize(PacketByteBuf buffer) {
ordinal = buffer.readInt();
name = buffer.readString(32767);
shadow = buffer.readFloat();
scale = buffer.readFloat();
eyeHeight = buffer.readFloat();
eyeDistance = buffer.readFloat();
triggerPixel = buffer.readInt();
this(buffer.readInt(), buffer.readString(32767), buffer.readFloat(), buffer.readFloat(), buffer.readFloat(), buffer.readFloat(), buffer.readInt());
}
public void toBuffer(PacketByteBuf buffer) {
buffer.writeInt(ordinal);
buffer.writeString(name);
buffer.writeFloat(shadow);
buffer.writeFloat(scale);
buffer.writeFloat(eyeHeight);
buffer.writeFloat(eyeDistance);
buffer.writeFloat(shadowSize);
buffer.writeFloat(scaleFactor);
buffer.writeFloat(eyeHeightFactor);
buffer.writeFloat(eyeDistanceFactor);
buffer.writeFloat(triggerPixel);
}
@Override
public int ordinal() {
return ordinal;
}
@Override
public String name() {
return name;
}
@Override
public float getShadowSize() {
return shadow;
}
@Override
public float getScaleFactor() {
return scale;
}
@Override
public float getEyeHeightFactor() {
return eyeHeight;
}
@Override
public float getEyeDistanceFactor() {
return eyeDistance;
}
@Override
public String toString() {
return name;
}
@Override
public int getColorCode() {
public int colorCode() {
return triggerPixel;
}
}

View file

@ -16,8 +16,8 @@ public class PonyBounds {
return PonyPosture.getMountPony(entity).map(ridingPony -> {
LivingEntity vehicle = (LivingEntity)entity.getVehicle();
Vec3d offset = PonyTransformation.forSize(ridingPony.metadata().getSize()).getRiderOffset();
float scale = ridingPony.metadata().getSize().getScaleFactor();
Vec3d offset = PonyTransformation.forSize(ridingPony.metadata().size()).getRiderOffset();
float scale = ridingPony.metadata().size().scaleFactor();
return getAbsoluteRidingOffset(vehicle).add(
0,
@ -41,7 +41,7 @@ public class PonyBounds {
}
public static Box getBoundingBox(IPony pony, LivingEntity entity) {
final float scale = pony.metadata().getSize().getScaleFactor() + 0.1F;
final float scale = pony.metadata().size().scaleFactor() + 0.1F;
final float width = entity.getWidth() * scale;
final float height = entity.getHeight() * scale;

View file

@ -25,7 +25,7 @@ class LegendOverlayWidget implements Carousel.Element, ITextContext {
public void render(DummyPlayer player, DrawContext context, int mouseX, int mouseY) {
IPonyData data = IPony.getManager().getPony(player).metadata();
int[] index = new int[1];
data.getTriggerPixels().forEach((key, value) -> {
data.attributes().forEach((key, value) -> {
context.getMatrices().push();
int i = index[0]++;
int x = frame.left;
@ -38,7 +38,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) {
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.getColorCode() | 0xFF000000);
context.fill(1, 1, LEGEND_BLOCK_BOUNDS.width - 1, LEGEND_BLOCK_BOUNDS.height - 1, value.colorCode() | 0xFF000000);
char symbol = value.name().charAt(0);
if (symbol == '[') {
@ -60,7 +60,7 @@ class LegendOverlayWidget implements Carousel.Element, ITextContext {
if (lines.size() == 1) {
lines.add(Text.literal(value.name()).styled(s -> {
int color = value.getChannelAdjustedColorCode();
return color == 0 ? s : s.withColor(value.getColorCode());
return color == 0 ? s : s.withColor(value.colorCode());
}));
}
context.drawTooltip(getFont(), lines, 2, 10);

View file

@ -105,7 +105,7 @@ public class MineLPHDSkins extends SkinsProxy implements ClientModInitializer {
IPonyData metadata = IPony.getManager().getPony(main.getId()).metadata();
if (wearable != Wearable.NONE && metadata.isWearing(wearable)) {
if (wearable.isSaddlebags() && metadata.getRace().supportsLegacySaddlebags()) {
if (wearable.isSaddlebags() && metadata.race().supportsLegacySaddlebags()) {
return Optional.of(main.getId());
}

View file

@ -21,7 +21,7 @@ abstract class MixinCamera {
IPony pony = IPony.getManager().getPony(MinecraftClient.getInstance().player);
if (!pony.race().isHuman()) {
value *= pony.metadata().getSize().getEyeDistanceFactor();
value *= pony.metadata().size().eyeDistanceFactor();
}
info.setReturnValue(value);

View file

@ -50,7 +50,7 @@ abstract class MixinClientPlayerEntity extends AbstractClientPlayerEntity implem
IPony pony = IPony.getManager().getPony(this);
if (!pony.race().isHuman()) {
float factor = pony.metadata().getSize().getEyeHeightFactor();
float factor = pony.metadata().size().eyeHeightFactor();
if (factor != 1) {
value *= factor;

View file

@ -67,7 +67,7 @@ public abstract class ClientPonyModel<T extends LivingEntity> extends MsonPlayer
@Override
public Size getSize() {
return child ? Sizes.FOAL : getMetadata().getSize();
return child ? Sizes.FOAL : getMetadata().size();
}
@Override

View file

@ -57,7 +57,7 @@ public class ChristmasHat extends AbstractWearableGear {
bodySwing += 0.1F;
tint = model.getMetadata().getGlowColor();
tint = model.getMetadata().glowColor();
left.roll = bodySwing;
right.roll = -bodySwing;
}

View file

@ -56,8 +56,8 @@ public class PonyEars implements IPart, MsonModel {
@Override
public void setVisible(boolean visible, ModelAttributes attributes) {
right.visible = visible && !attributes.metadata.getRace().isHuman();
left.visible = visible && !attributes.metadata.getRace().isHuman();
right.visible = visible && !attributes.metadata.race().isHuman();
left.visible = visible && !attributes.metadata.race().isHuman();
if (attributes.isHorsey) {
left.pivotX = -1;

View file

@ -40,9 +40,9 @@ public class PonySnout implements IPart, MsonModel {
@Override
public void setVisible(boolean visible, ModelAttributes attributes) {
visible &= !attributes.isHorsey
&& !attributes.metadata.getRace().isHuman()
&& !attributes.metadata.race().isHuman()
&& MineLittlePony.getInstance().getConfig().snuzzles.get();
Gender gender = attributes.metadata.getGender();
Gender gender = attributes.metadata.gender();
mare.visible = (visible && gender.isMare());
stallion.visible = (visible && gender.isStallion());

View file

@ -81,8 +81,8 @@ public class PonyTail implements IPart, MsonModel {
@Override
public void setVisible(boolean visible, ModelAttributes attributes) {
tail.visible = visible;
tailStop = attributes.metadata.getTailLength().ordinal();
shape = attributes.metadata.getTailShape();
tailStop = attributes.metadata.tailLength().ordinal();
shape = attributes.metadata.tailShape();
}
@Override

View file

@ -119,14 +119,14 @@ public class PonyWings<T extends Model & IPegasus> implements IPart, MsonModel {
public void rotateWalking(float swing) {
folded.yaw = swing * walkingRotationSpeed;
if (pegasus.getMetadata().getRace().hasBugWings()) {
if (pegasus.getMetadata().race().hasBugWings()) {
extended.yaw = folded.yaw;
}
}
public void rotateFlying(float roll) {
extended.roll = roll;
if (pegasus.getMetadata().getRace().hasBugWings()) {
if (pegasus.getMetadata().race().hasBugWings()) {
folded.roll = roll;
}
}

View file

@ -1,126 +0,0 @@
package com.minelittlepony.client.pony;
import net.minecraft.client.texture.NativeImage;
import com.google.common.base.MoreObjects;
import com.minelittlepony.api.pony.IPonyData;
import com.minelittlepony.api.pony.TriggerPixelSet;
import com.minelittlepony.api.pony.TriggerPixelType;
import com.minelittlepony.api.pony.TriggerPixelValue;
import com.minelittlepony.api.pony.meta.*;
import com.minelittlepony.client.MineLittlePony;
import com.minelittlepony.common.util.animation.Interpolator;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;
import org.jetbrains.annotations.Unmodifiable;
/**
* Implementation for IPonyData.
*/
@Unmodifiable
class NativePonyData implements IPonyData {
private final TriggerPixelValue<Race> race;
private final TriggerPixelValue<TailLength> tailLength;
private final TriggerPixelValue<TailShape> tailShape;
private final TriggerPixelValue<Gender> gender;
private final TriggerPixelValue<Size> size;
private final int glowColor;
private final TriggerPixelSet<Wearable> wearables;
private final Map<String, TriggerPixelType<?>> attributes = new TreeMap<>();
NativePonyData(NativeImage image) {
race = TriggerPixel.RACE.readValue(image);
tailLength = TriggerPixel.TAIL.readValue(image);
tailShape = TriggerPixel.TAIL_SHAPE.readValue(image);
size = TriggerPixel.SIZE.readValue(image);
gender = TriggerPixel.GENDER.readValue(image);
glowColor = TriggerPixel.GLOW.readColor(image);
wearables = TriggerPixel.WEARABLES.readFlags(image);
attributes.put("race", race);
attributes.put("tailLength", tailLength);
attributes.put("tailShape", tailShape);
attributes.put("gender", gender);
attributes.put("size", size);
attributes.put("magic", TriggerPixelType.of(glowColor));
attributes.put("gear", wearables);
}
@Override
public Race getRace() {
return race.getValue();
}
@Override
public TailLength getTailLength() {
return tailLength.getValue();
}
@Override
public TailShape getTailShape() {
return tailShape.getValue();
}
@Override
public Gender getGender() {
return gender.getValue();
}
@Override
public Sizes getSize() {
Sizes sz = MineLittlePony.getInstance().getConfig().sizeOverride.get();
if (sz != Sizes.UNSET) {
return sz;
}
if (size.getValue() == Sizes.UNSET || !MineLittlePony.getInstance().getConfig().sizes.get()) {
return Sizes.NORMAL;
}
return (Sizes)size.getValue();
}
@Override
public int getGlowColor() {
return glowColor;
}
@Override
public Wearable[] getGear() {
return Wearable.flags(wearables.getValue());
}
@Override
public boolean isWearing(Wearable wearable) {
return wearables.matches(wearable);
}
@Override
public Interpolator getInterpolator(UUID interpolatorId) {
return Interpolator.linear(interpolatorId);
}
@Override
public Map<String, TriggerPixelType<?>> getTriggerPixels() {
return attributes;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("race", race.getValue())
.add("tailLength", tailLength.getValue())
.add("tailShape", tailShape.getValue())
.add("gender", gender.getValue())
.add("size", size.getValue())
.add("wearables", getGear())
.add("glowColor", TriggerPixelType.toHex(glowColor))
.toString();
}
}

View file

@ -2,26 +2,30 @@ package com.minelittlepony.client.pony;
import net.minecraft.client.MinecraftClient;
import net.minecraft.util.Identifier;
import com.google.common.base.MoreObjects;
import com.google.gson.annotations.Expose;
import com.minelittlepony.api.pony.IPonyData;
import com.minelittlepony.api.pony.TriggerPixelType;
import com.minelittlepony.api.pony.meta.*;
import com.minelittlepony.client.MineLittlePony;
import com.minelittlepony.client.util.render.NativeUtil;
import com.minelittlepony.common.util.animation.Interpolator;
import java.io.IOException;
import java.util.*;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Unmodifiable;
/**
* Implementation for IPonyData.
*/
@Unmodifiable
public class PonyData implements IPonyData {
public record PonyData (
Race race,
TailLength tailLength,
TailShape tailShape,
Gender gender,
Size size,
int glowColor,
boolean[] wearables,
Map<String, TriggerPixelType<?>> attributes
) implements IPonyData {
private static final PonyDataSerialiser SERIALISER = new PonyDataSerialiser();
@ -46,8 +50,16 @@ public class PonyData implements IPonyData {
return null;
}).map(Memoize::of).orElseGet(() -> {
return Memoize.load(callback -> {
NativeUtil.parseImage(identifier, img -> {
callback.accept(new NativePonyData(img));
NativeUtil.parseImage(identifier, image -> {
callback.accept(new PonyData(
TriggerPixel.RACE.<Race>readValue(image),
TriggerPixel.TAIL.<TailLength>readValue(image),
TriggerPixel.TAIL_SHAPE.<TailShape>readValue(image),
TriggerPixel.GENDER.<Gender>readValue(image),
TriggerPixel.SIZE.<Size>readValue(image),
TriggerPixel.GLOW.readColor(image),
TriggerPixel.WEARABLES.readFlags(image)
));
}, e -> {
MineLittlePony.logger.fatal("Unable to read {} metadata", identifier, e);
callback.accept(NULL);
@ -56,31 +68,8 @@ public class PonyData implements IPonyData {
});
}
@Expose
private final Race race;
@Expose
private final TailLength tailLength = TailLength.FULL;
@Expose
private final TailShape tailShape = TailShape.STRAIGHT;
@Expose
private final Gender gender = Gender.MARE;
@Expose
private final Sizes size = Sizes.NORMAL;
@Expose
private final int glowColor = 0x4444aa;
@Expose
private final boolean[] wearables = new boolean[Wearable.values().length];
private final Map<String, TriggerPixelType<?>> attributes = new TreeMap<>();
public PonyData(Race race) {
this.race = race;
this(race, TailLength.FULL, TailShape.STRAIGHT, Gender.MARE, Sizes.NORMAL, 0x4444aa, new boolean[Wearable.values().length], new TreeMap<>());
attributes.put("race", race);
attributes.put("tailLength", tailLength);
attributes.put("tailShape", tailShape);
@ -90,28 +79,20 @@ public class PonyData implements IPonyData {
attributes.put("gear", TriggerPixelType.of(0));
}
@Override
public Race getRace() {
return race;
PonyData(TriggerPixelType.Value<Race> race, TriggerPixelType.Value<TailLength> tailLength, TriggerPixelType.Value<TailShape> tailShape,
TriggerPixelType.Value<Gender> gender, TriggerPixelType.Value<Size> size, int glowColor, TriggerPixelType.Flags<Wearable> wearables) {
this(race.value(), tailLength.value(), tailShape.value(), gender.value(), size.value(), glowColor, wearables.value(), new TreeMap<>());
attributes.put("race", race);
attributes.put("tailLength", tailLength);
attributes.put("tailShape", tailShape);
attributes.put("gender", gender);
attributes.put("size", size);
attributes.put("magic", TriggerPixelType.of(glowColor));
attributes.put("gear", wearables);
}
@Override
public TailLength getTailLength() {
return tailLength;
}
@Override
public TailShape getTailShape() {
return tailShape;
}
@Override
public Gender getGender() {
return gender;
}
@Override
public Sizes getSize() {
public Size size() {
Sizes sz = MineLittlePony.getInstance().getConfig().sizeOverride.get();
if (sz != Sizes.UNSET) {
@ -126,12 +107,7 @@ public class PonyData implements IPonyData {
}
@Override
public int getGlowColor() {
return glowColor;
}
@Override
public Wearable[] getGear() {
public Wearable[] gear() {
return Wearable.flags(wearables);
}
@ -139,26 +115,4 @@ public class PonyData implements IPonyData {
public boolean isWearing(Wearable wearable) {
return wearables[wearable.ordinal()];
}
@Override
public Interpolator getInterpolator(UUID interpolatorId) {
return Interpolator.linear(interpolatorId);
}
public Map<String, TriggerPixelType<?>> getTriggerPixels() {
return attributes;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("race", race)
.add("tailLength", tailLength)
.add("tailShape", tailShape)
.add("gender", gender)
.add("size", size)
.add("wearables", getGear())
.add("glowColor", TriggerPixelType.toHex(glowColor))
.toString();
}
}

View file

@ -94,7 +94,7 @@ public class PonyManager implements IPonyManager, SimpleSynchronousResourceReloa
public IPony getPony(Identifier resource, UUID uuid) {
IPony pony = getPony(resource);
if (config.ponyLevel.get() == PonyLevel.PONIES && pony.metadata().getRace().isHuman()) {
if (config.ponyLevel.get() == PonyLevel.PONIES && pony.metadata().race().isHuman()) {
return getBackgroundPony(uuid);
}

View file

@ -141,7 +141,7 @@ public class EquineRenderManager<T extends LivingEntity, M extends EntityModel<T
}
public float getScaleFactor() {
return getModel().getSize().getScaleFactor();
return getModel().getSize().scaleFactor();
}
public double getNamePlateYOffset(T entity) {

View file

@ -22,7 +22,7 @@ import net.minecraft.world.World;
public class LevitatingItemRenderer {
private VertexConsumerProvider getProvider(IPony pony, VertexConsumerProvider renderContext) {
final int color = pony.metadata().getGlowColor();
final int color = pony.metadata().glowColor();
return layer -> {
Identifier texture = RenderLayerUtil.getTexture(layer).orElse(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE);
if (texture == ItemRenderer.ENTITY_ENCHANTMENT_GLINT || texture == ItemRenderer.ITEM_ENCHANTMENT_GLINT) {

View file

@ -90,7 +90,7 @@ public abstract class AbstractPonyRenderer<T extends MobEntity, M extends Entity
@Override
public void scale(T entity, MatrixStack stack, float tickDelta) {
shadowRadius = manager.getModel().getSize().getShadowSize();
shadowRadius = manager.getModel().getSize().shadowSize();
if (entity.isBaby()) {
shadowRadius *= 3; // undo vanilla shadow scaling

View file

@ -80,7 +80,7 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements IPonyRen
IPony 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().getShadowSize();
shadowRadius = manager.getModel().getSize().shadowSize();
super.render(entity, entityYaw, tickDelta, stack, renderContext, lightUv);
DebugBoundingBoxRenderer.render(pony, this, entity, stack, renderContext, tickDelta);
@ -88,7 +88,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.metadata().getSize().getScaleFactor();
float l = entity.getWidth() / 2 * pony.metadata().size().scaleFactor();
stack.multiply(RotationAxis.NEGATIVE_Y.rotationDegrees(yaw));
stack.translate(0, 0, -l);
@ -191,7 +191,7 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements IPonyRen
@Override
public Identifier getDefaultTexture(AbstractClientPlayerEntity entity, Wearable wearable) {
return SkinsProxy.instance.getSkin(wearable.getId(), entity).orElseGet(() -> {
if (wearable.isSaddlebags() && getInternalRenderer().getModel().getMetadata().getRace().supportsLegacySaddlebags()) {
if (wearable.isSaddlebags() && getInternalRenderer().getModel().getMetadata().race().supportsLegacySaddlebags()) {
return getTexture(entity);
}

View file

@ -3,20 +3,21 @@ package com.minelittlepony.client.render.entity.npc.textures;
import net.minecraft.block.entity.SkullBlockEntity;
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.IPony;
import com.minelittlepony.client.SkinsProxy;
import com.minelittlepony.util.FunctionUtil;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
public class PlayerTextureSupplier {
public static <T extends LivingEntity> TextureSupplier<T> create(TextureSupplier<T> fallback) {
Function<T, Entry> customNameCache = FunctionUtil.memoize(Entry::new, entity -> entity.getCustomName().getString() + "_" + entity.getUuidAsString());
Function<String, Entry> customNameCache = Util.memoize(Entry::new);
return entity -> {
Identifier override = entity.hasCustomName() ? customNameCache.apply(entity).getTexture() : null;
Identifier override = entity.hasCustomName() ? customNameCache.apply(entity.getCustomName().getString()).getTexture() : null;
if (override != null) {
return override;
}
@ -27,8 +28,8 @@ public class PlayerTextureSupplier {
static final class Entry {
private final CompletableFuture<Identifier> profile;
Entry(LivingEntity entity) {
profile = SkullBlockEntity.fetchProfile(entity.getCustomName().getString()).thenApply(profile -> {
Entry(String name) {
profile = SkullBlockEntity.fetchProfile(name).thenApply(profile -> {
return profile
.map(p -> SkinsProxy.instance.getSkinTexture(p))
.filter(skin -> !IPony.getManager().getPony(skin).race().isHuman())

View file

@ -2,12 +2,14 @@ package com.minelittlepony.client.render.entity.npc.textures;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Identifier;
import net.minecraft.util.Util;
import com.minelittlepony.client.MineLittlePony;
import com.minelittlepony.util.FunctionUtil;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.BiFunction;
import java.util.function.Function;
/**
@ -32,14 +34,14 @@ public interface TextureSupplier<T> extends Function<T, Identifier> {
}
static <T extends LivingEntity> TextureSupplier<T> ofPool(Identifier poolId, TextureSupplier<T> fallback) {
final Function<T, Identifier> cache = FunctionUtil.memoize(entity -> {
final BiFunction<String, UUID, Identifier> cache = Util.memoize((name, uuid) -> {
return MineLittlePony.getInstance().getVariatedTextures()
.get(poolId)
.getByName(entity.getCustomName().getString(), entity.getUuid())
.getByName(name, uuid)
.orElse(null);
}, entity -> entity.getCustomName().getString() + "_" + entity.getUuidAsString());
});
return entity -> {
Identifier override = entity.hasCustomName() ? cache.apply(entity) : null;
Identifier override = entity.hasCustomName() ? cache.apply(entity.getCustomName().getString(), entity.getUuid()) : null;
if (override != null) {
return override;
}

View file

@ -1,12 +0,0 @@
package com.minelittlepony.util;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
public interface FunctionUtil {
static <A, B> Function<A, B> memoize(Function<A, B> func, Function<A, String> keyFunc) {
final Map<String, B> cache = new ConcurrentHashMap<>();
return a -> cache.computeIfAbsent(keyFunc.apply(a), k -> func.apply(a));
}
}