Added a trigger pixel display to the skin uploader

This commit is contained in:
Sollace 2021-05-17 00:21:20 +02:00
parent e85ac9f6c1
commit 0c76804cac
16 changed files with 436 additions and 82 deletions

View file

@ -7,6 +7,7 @@ import com.minelittlepony.api.pony.meta.TailLength;
import com.minelittlepony.api.pony.meta.Wearable;
import com.minelittlepony.common.util.animation.Interpolator;
import java.util.Map;
import java.util.UUID;
/**
@ -46,7 +47,9 @@ public interface IPonyData {
/**
* Returns true if and only if this metadata represents a pony that can cast magic.
*/
boolean hasMagic();
default boolean hasMagic() {
return hasHorn() && getGlowColor() != 0;
}
/**
* Returns an array of wearables that this pony is carrying.
@ -62,4 +65,9 @@ public interface IPonyData {
* Gets an interpolator for interpolating values.
*/
Interpolator getInterpolator(UUID interpolatorId);
/**
* Gets the trigger pixel values as they appeared in the underlying image.
*/
Map<String, TriggerPixelType<?>> getTriggerPixels();
}

View file

@ -1,29 +0,0 @@
package com.minelittlepony.api.pony;
/**
* Interface for enums that can be parsed from an image trigger pixel value.
*/
public interface ITriggerPixelMapped<T extends Enum<T> & ITriggerPixelMapped<T>> {
/**
* Gets the pixel colour matching this enum value.
*/
int getTriggerPixel();
/**
* 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 extends Enum<T> & ITriggerPixelMapped<T>> T getByTriggerPixel(T type, int pixelValue) {
for (T i : (T[])type.getClass().getEnumConstants()) {
if (i.getTriggerPixel() == pixelValue) {
return i;
}
}
return type;
}
}

View file

@ -0,0 +1,24 @@
package com.minelittlepony.api.pony;
import java.util.List;
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;
}
@SuppressWarnings("unchecked")
@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

@ -0,0 +1,73 @@
package com.minelittlepony.api.pony;
import java.util.List;
import java.util.stream.Collectors;
/**
* Interface for enums that can be parsed from an image trigger pixel value.
*/
public interface TriggerPixelType<T> {
/**
* Gets the pixel colour matching this enum value.
*/
int getColorCode();
/**
* Gets the pixel colour matching this enum value, adjusted to fill all three channels.
*/
default int getChannelAdjustedColorCode() {
return getColorCode();
}
/**
* Gets a string representation of this value.
*/
default String name() {
return "[Numeric " + getHexValue() + "]";
}
default String getHexValue() {
return toHex(getColorCode());
}
/**
* Returns a list of possible values this trigger pixel can accept.
*/
default <Option extends TriggerPixelType<T>> List<Option> getOptions() {
if (this instanceof Enum) {
return List.of(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 extends TriggerPixelType<T>> T getByTriggerPixel(T type, int pixelValue) {
return (T)type.getOptions().stream()
.filter(i -> i.getColorCode() == 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;
}
}

View file

@ -0,0 +1,43 @@
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

@ -1,8 +1,8 @@
package com.minelittlepony.api.pony.meta;
import com.minelittlepony.api.pony.ITriggerPixelMapped;
import com.minelittlepony.api.pony.TriggerPixelType;
public enum Gender implements ITriggerPixelMapped<Gender> {
public enum Gender implements TriggerPixelType<Gender> {
MARE(0),
STALLION(0xffffff),
ABOMONATION(0x888888);
@ -14,7 +14,7 @@ public enum Gender implements ITriggerPixelMapped<Gender> {
}
@Override
public int getTriggerPixel() {
public int getColorCode() {
return triggerValue;
}

View file

@ -1,10 +1,10 @@
package com.minelittlepony.api.pony.meta;
import com.minelittlepony.api.pony.ITriggerPixelMapped;
import com.minelittlepony.api.pony.TriggerPixelType;
import javax.annotation.Nonnull;
public enum Race implements ITriggerPixelMapped<Race> {
public enum Race implements TriggerPixelType<Race> {
HUMAN (0x000000, false, false),
EARTH (0xf9b131, false, false),
@ -93,7 +93,7 @@ public enum Race implements ITriggerPixelMapped<Race> {
}
@Override
public int getTriggerPixel() {
public int getColorCode() {
return triggerPixel;
}
}

View file

@ -1,5 +1,7 @@
package com.minelittlepony.api.pony.meta;
import com.minelittlepony.api.pony.TriggerPixelType;
/**
* Represents the different model sizes that are possible.
*
@ -7,8 +9,7 @@ package com.minelittlepony.api.pony.meta;
* 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 {
public interface Size extends TriggerPixelType<Size> {
/**
* The Enum index of this size. May be used on the client to convert to an instance of Sizes or use {@link Sizes#of}
*

View file

@ -1,6 +1,5 @@
package com.minelittlepony.api.pony.meta;
import com.minelittlepony.api.pony.ITriggerPixelMapped;
import com.minelittlepony.client.MineLittlePony;
/**
@ -10,7 +9,7 @@ import com.minelittlepony.client.MineLittlePony;
*
* For spooky things at a distance, use {@link Size} instead.
*/
public enum Sizes implements ITriggerPixelMapped<Sizes>, Size {
public enum Sizes 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),
@ -61,7 +60,7 @@ public enum Sizes implements ITriggerPixelMapped<Sizes>, Size {
}
@Override
public int getTriggerPixel() {
public int getColorCode() {
return triggerValue;
}

View file

@ -1,9 +1,8 @@
package com.minelittlepony.api.pony.meta;
import com.minelittlepony.api.pony.ITriggerPixelMapped;
public enum TailLength implements ITriggerPixelMapped<TailLength> {
import com.minelittlepony.api.pony.TriggerPixelType;
public enum TailLength implements TriggerPixelType<TailLength> {
STUB (0x425844),
QUARTER (0xd19fe4),
HALF (0x534b76),
@ -17,7 +16,7 @@ public enum TailLength implements ITriggerPixelMapped<TailLength> {
}
@Override
public int getTriggerPixel() {
public int getColorCode() {
return triggerValue;
}
}

View file

@ -2,7 +2,9 @@ package com.minelittlepony.api.pony.meta;
import net.minecraft.client.texture.NativeImage;
import com.minelittlepony.api.pony.ITriggerPixelMapped;
import com.minelittlepony.api.pony.TriggerPixelSet;
import com.minelittlepony.api.pony.TriggerPixelType;
import com.minelittlepony.api.pony.TriggerPixelValue;
import com.minelittlepony.common.util.Color;
/**
@ -10,7 +12,7 @@ import com.minelittlepony.common.util.Color;
*
*/
@SuppressWarnings("unchecked")
public enum TriggerPixels {
public enum TriggerPixel {
RACE(Race.HUMAN, Channel.ALL, 0, 0),
TAIL(TailLength.FULL, Channel.ALL, 1, 0),
GENDER(Gender.MARE, Channel.ALL, 2, 0),
@ -23,9 +25,9 @@ public enum TriggerPixels {
private Channel channel;
ITriggerPixelMapped<?> def;
TriggerPixelType<?> def;
TriggerPixels(ITriggerPixelMapped<?> def, Channel channel, int x, int y) {
TriggerPixel(TriggerPixelType<?> def, Channel channel, int x, int y) {
this.def = def;
this.channel = channel;
this.x = x;
@ -46,33 +48,35 @@ public enum TriggerPixels {
*
* @param image Image to read
*/
public <T extends Enum<T> & ITriggerPixelMapped<T>> T readValue(NativeImage image) {
public <T extends TriggerPixelType<T>> TriggerPixelValue<T> readValue(NativeImage image) {
int color = readColor(image);
if (Channel.ALPHA.readValue(x, y, image) < 255) {
return (T)def;
return new TriggerPixelValue<>(color, (T)def);
}
return ITriggerPixelMapped.getByTriggerPixel((T)def, readColor(image));
return new TriggerPixelValue<>(color, TriggerPixelType.getByTriggerPixel((T)def, color));
}
public <T extends Enum<T> & ITriggerPixelMapped<T>> boolean[] readFlags(NativeImage image) {
public <T extends Enum<T> & TriggerPixelType<T>> TriggerPixelSet<T> readFlags(NativeImage image) {
boolean[] out = new boolean[def.getClass().getEnumConstants().length];
readFlags(out, image);
return out;
return new TriggerPixelSet<>(readColor(image), (T)def, out);
}
public <T extends Enum<T> & ITriggerPixelMapped<T>> void readFlags(boolean[] out, NativeImage image) {
public <T extends Enum<T> & TriggerPixelType<T>> void readFlags(boolean[] out, NativeImage image) {
readFlag(out, Channel.RED, image);
readFlag(out, Channel.GREEN, image);
readFlag(out, Channel.BLUE, image);
}
private <T extends Enum<T> & ITriggerPixelMapped<T>> void readFlag(boolean[] out, Channel channel, NativeImage image) {
private <T extends Enum<T> & TriggerPixelType<T>> void readFlag(boolean[] out, Channel channel, NativeImage image) {
if (Channel.ALPHA.readValue(x, y, image) < 255) {
return;
}
T value = ITriggerPixelMapped.getByTriggerPixel((T)def, channel.readValue(x, y, image));
T value = TriggerPixelType.getByTriggerPixel((T)def, channel.readValue(x, y, image));
out[value.ordinal()] |= value != def;
}

View file

@ -1,11 +1,12 @@
package com.minelittlepony.api.pony.meta;
import com.minelittlepony.api.pony.ITriggerPixelMapped;
import com.minelittlepony.api.pony.TriggerPixelType;
import com.minelittlepony.common.util.Color;
import java.util.ArrayList;
import java.util.List;
public enum Wearable implements ITriggerPixelMapped<Wearable> {
public enum Wearable implements TriggerPixelType<Wearable> {
NONE (0x00),
MUFFIN (0x32),
HAT (0x64),
@ -20,10 +21,15 @@ public enum Wearable implements ITriggerPixelMapped<Wearable> {
}
@Override
public int getTriggerPixel() {
public int getColorCode() {
return triggerValue;
}
@Override
public int getChannelAdjustedColorCode() {
return triggerValue == 0 ? 0 : Color.argbToHex(255, triggerValue, triggerValue, triggerValue);
}
public static boolean[] flags(Wearable[] wears) {
boolean[] flags = new boolean[values().length];
for (int i = 0; i < wears.length; i++) {

View file

@ -1,8 +1,11 @@
package com.minelittlepony.api.pony.network;
import net.minecraft.network.PacketByteBuf;
import net.minecraft.util.Lazy;
import net.minecraft.util.Util;
import com.minelittlepony.api.pony.IPonyData;
import com.minelittlepony.api.pony.TriggerPixelType;
import com.minelittlepony.api.pony.meta.Gender;
import com.minelittlepony.api.pony.meta.Race;
import com.minelittlepony.api.pony.meta.Size;
@ -10,6 +13,8 @@ import com.minelittlepony.api.pony.meta.TailLength;
import com.minelittlepony.api.pony.meta.Wearable;
import com.minelittlepony.common.util.animation.Interpolator;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;
public class MsgPonyData implements IPonyData {
@ -24,8 +29,19 @@ public class MsgPonyData implements IPonyData {
private final boolean noSkin;
private final int wearableColor;
private final boolean[] wearables;
private final Lazy<Map<String, TriggerPixelType<?>>> triggerPixels = new Lazy<>(() -> Util.make(new TreeMap<>(), this::initTriggerPixels));
private void initTriggerPixels(Map<String, TriggerPixelType<?>> map) {
map.put("race", race);
map.put("tail", tailLength);
map.put("gender", gender);
map.put("size", size);
map.put("magic", TriggerPixelType.of(glowColor));
map.put("gear", TriggerPixelType.of(wearableColor));
}
public MsgPonyData(PacketByteBuf buffer) {
race = Race.values()[buffer.readInt()];
tailLength = TailLength.values()[buffer.readInt()];
@ -41,6 +57,7 @@ public class MsgPonyData implements IPonyData {
gear[i] = all[buffer.readInt()];
}
wearables = Wearable.flags(gear);
wearableColor = buffer.readInt();
}
public MsgPonyData(IPonyData data, boolean noSkin) {
@ -52,6 +69,7 @@ public class MsgPonyData implements IPonyData {
hasHorn = data.hasHorn();
hasMagic = data.hasMagic();
wearables = Wearable.flags(data.getGear());
wearableColor = data.getTriggerPixels().get("gear").getColorCode();
this.noSkin = noSkin;
}
@ -70,6 +88,7 @@ public class MsgPonyData implements IPonyData {
for (int i = 0; i < gear.length; i++) {
buffer.writeInt(gear[i].ordinal());
}
buffer.writeInt(wearableColor);
}
public boolean isNoSkin() {
@ -126,6 +145,11 @@ public class MsgPonyData implements IPonyData {
return Interpolator.linear(interpolatorId);
}
@Override
public Map<String, TriggerPixelType<?>> getTriggerPixels() {
return triggerPixels.get();
}
private static final class MsgSize implements Size {
private final int ordinal;
@ -134,6 +158,7 @@ public class MsgPonyData implements IPonyData {
private final float scale;
private final float eyeHeight;
private final float eyeDistance;
private final int triggerPixel;
MsgSize(Size size) {
ordinal = size.ordinal();
@ -142,6 +167,7 @@ public class MsgPonyData implements IPonyData {
scale = size.getScaleFactor();
eyeHeight = size.getEyeHeightFactor();
eyeDistance = size.getEyeDistanceFactor();
triggerPixel = size.getColorCode();
}
MsgSize(PacketByteBuf buffer) {
@ -151,6 +177,7 @@ public class MsgPonyData implements IPonyData {
scale = buffer.readFloat();
eyeHeight = buffer.readFloat();
eyeDistance = buffer.readFloat();
triggerPixel = buffer.readInt();
}
public void toBuffer(PacketByteBuf buffer) {
@ -160,6 +187,7 @@ public class MsgPonyData implements IPonyData {
buffer.writeFloat(scale);
buffer.writeFloat(eyeHeight);
buffer.writeFloat(eyeDistance);
buffer.writeFloat(triggerPixel);
}
@Override
@ -196,5 +224,10 @@ public class MsgPonyData implements IPonyData {
public String toString() {
return name;
}
@Override
public int getColorCode() {
return triggerPixel;
}
}
}

View file

@ -1,11 +1,20 @@
package com.minelittlepony.client.hdskins;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.text.LiteralText;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import com.minelittlepony.api.pony.IPonyData;
import com.minelittlepony.api.pony.TriggerPixelType;
import com.minelittlepony.client.MineLittlePony;
import com.minelittlepony.hdskins.client.dummy.DummyPlayer;
import com.minelittlepony.hdskins.client.dummy.PlayerPreview;
import com.minelittlepony.hdskins.profile.SkinType;
import java.util.List;
import java.util.stream.Collectors;
class PonyPreview extends PlayerPreview {
public static final Identifier NO_SKIN_STEVE_PONY = new Identifier("minelittlepony", "textures/mob/noskin.png");
@ -47,9 +56,70 @@ class PonyPreview extends PlayerPreview {
return remotePony;
}
@Override
public DummyPlayer getLocal() {
return localPony;
}
@Override
public void renderWorldAndPlayer(DummyPlayer thePlayer,
int frameLeft, int frameRight, int frameBottom, int frameTop,
float xPos, float yPos, int horizon, int mouseX, int mouseY, int ticks, float partialTick, float scale,
MatrixStack matrices) {
super.renderWorldAndPlayer(thePlayer, frameLeft, frameRight, frameBottom, frameTop, xPos, yPos, horizon, mouseX, mouseY, ticks, partialTick, scale, matrices);
IPonyData data = MineLittlePony.getInstance().getManager().getPony(thePlayer).getMetadata();
int[] index = new int[1];
data.getTriggerPixels().forEach((key, value) -> {
drawLegendBlock(matrices, index[0]++, frameLeft, frameTop, mouseX, mouseY, key, value);
});
}
private void drawLegendBlock(MatrixStack matrices, int index, int x, int y, int mouseX, int mouseY, String key, TriggerPixelType<?> value) {
int size = 10;
int yPos = y + index * size + 20;
fill(matrices,
x, yPos,
x + size, yPos + size,
0xFF003333
);
fill(matrices,
x + 1, yPos + 1,
x - 1 + size, yPos - 1 + size,
value.getColorCode() | 0xFF000000
);
char symbol = value.name().charAt(0);
if (symbol == '[') {
symbol = key.charAt(0);
}
minecraft.textRenderer.drawWithShadow(matrices,
Text.of(String.valueOf(symbol).toUpperCase()),
x + 2,
yPos + 1,
0xFFFFFFFF
);
if (mouseX > x && mouseX < (x + size) && mouseY > yPos && mouseY < (yPos + size)) {
List<Text> lines = value.getOptions().stream().map(option -> {
boolean selected = value.matches(option);
return new LiteralText((selected ? "* " : " ") + option.name()).styled(s -> {
int color = option.getChannelAdjustedColorCode();
return (color == 0 ? s : s.withColor(color)).withItalic(selected);
});
}).collect(Collectors.toList());
lines.add(0, Text.of(key.toUpperCase() + ": " + value.getHexValue()));
if (lines.size() == 1) {
lines.add(new LiteralText(value.name()).styled(s -> {
int color = value.getChannelAdjustedColorCode();
return color == 0 ? s : s.withColor(value.getColorCode());
}));
}
minecraft.currentScreen.renderTooltip(matrices, lines, mouseX, mouseY);
}
}
}

View file

@ -0,0 +1,127 @@
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.Gender;
import com.minelittlepony.api.pony.meta.Race;
import com.minelittlepony.api.pony.meta.Size;
import com.minelittlepony.api.pony.meta.Sizes;
import com.minelittlepony.api.pony.meta.TailLength;
import com.minelittlepony.api.pony.meta.TriggerPixel;
import com.minelittlepony.api.pony.meta.Wearable;
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 javax.annotation.concurrent.Immutable;
/**
* Implementation for IPonyData.
*/
@Immutable
class NativePonyData implements IPonyData {
private final TriggerPixelValue<Race> race;
private final TriggerPixelValue<TailLength> tailSize;
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);
tailSize = TriggerPixel.TAIL.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("tail", tailSize);
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 getTail() {
return tailSize.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 boolean hasHorn() {
return getRace() != null && Pony.getEffectiveRace(getRace(), false).hasHorn();
}
@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);
}
public Map<String, TriggerPixelType<?>> getTriggerPixels() {
return attributes;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
.add("race", race.getValue())
.add("tailSize", tailSize.getValue())
.add("gender", gender.getValue())
.add("size", size.getValue())
.add("wearables", getGear())
.add("glowColor", TriggerPixelType.toHex(glowColor))
.toString();
}
}

View file

@ -1,18 +1,16 @@
package com.minelittlepony.client.pony;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.texture.NativeImage;
import net.minecraft.resource.Resource;
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.Gender;
import com.minelittlepony.api.pony.meta.Race;
import com.minelittlepony.api.pony.meta.Sizes;
import com.minelittlepony.api.pony.meta.TailLength;
import com.minelittlepony.api.pony.meta.TriggerPixels;
import com.minelittlepony.api.pony.meta.Wearable;
import com.minelittlepony.client.MineLittlePony;
import com.minelittlepony.client.util.render.NativeUtil;
@ -20,6 +18,8 @@ import com.minelittlepony.common.util.animation.Interpolator;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;
import javax.annotation.Nullable;
@ -27,7 +27,6 @@ import javax.annotation.concurrent.Immutable;
/**
* Implementation for IPonyData.
*
*/
@Immutable
public class PonyData implements IPonyData {
@ -58,7 +57,7 @@ public class PonyData implements IPonyData {
}
try {
return NativeUtil.parseImage(identifier, PonyData::new);
return NativeUtil.parseImage(identifier, NativePonyData::new);
} catch (IllegalStateException e) {
MineLittlePony.logger.fatal("Unable to read {} metadata", identifier, e);
return NULL;
@ -83,24 +82,22 @@ public class PonyData implements IPonyData {
@Expose
private final boolean[] wearables;
private final Map<String, TriggerPixelType<?>> attributes = new TreeMap<>();
public PonyData(Race race) {
this.race = race;
tailSize = TailLength.FULL;
gender = Gender.MARE;
size = Sizes.NORMAL;
glowColor = 0x4444aa;
wearables = new boolean[Wearable.values().length];
}
private PonyData(NativeImage image) {
race = TriggerPixels.RACE.readValue(image);
tailSize = TriggerPixels.TAIL.readValue(image);
size = TriggerPixels.SIZE.readValue(image);
gender = TriggerPixels.GENDER.readValue(image);
glowColor = TriggerPixels.GLOW.readColor(image);
wearables = TriggerPixels.WEARABLES.readFlags(image);
attributes.put("race", race);
attributes.put("tail", tailSize);
attributes.put("gender", gender);
attributes.put("size", size);
attributes.put("magic", TriggerPixelType.of(glowColor));
attributes.put("gear", TriggerPixelType.of(0));
}
@Override
@ -143,11 +140,6 @@ public class PonyData implements IPonyData {
return getRace() != null && Pony.getEffectiveRace(getRace(), false).hasHorn();
}
@Override
public boolean hasMagic() {
return hasHorn() && getGlowColor() != 0;
}
@Override
public Wearable[] getGear() {
return Wearable.flags(wearables);
@ -163,6 +155,10 @@ public class PonyData implements IPonyData {
return Interpolator.linear(interpolatorId);
}
public Map<String, TriggerPixelType<?>> getTriggerPixels() {
return attributes;
}
@Override
public String toString() {
return MoreObjects.toStringHelper(this)
@ -171,7 +167,7 @@ public class PonyData implements IPonyData {
.add("gender", gender)
.add("size", size)
.add("wearables", getGear())
.add("glowColor", "#" + Integer.toHexString(glowColor))
.add("glowColor", TriggerPixelType.toHex(glowColor))
.toString();
}
}