Added proper alex model support to HDSkins. Skin servers should remember what the "model" parameter was when saving a skin and include it in their responses.

This commit is contained in:
Sollace 2018-06-29 23:33:05 +02:00
parent 8a31d6c48f
commit 1e52830c91
13 changed files with 113 additions and 64 deletions

View file

@ -231,7 +231,7 @@ public final class HDSkinManager implements IResourceManagerReloadListener {
return null; return null;
IImageBuffer buffer = new ImageBufferDownloadHD(); IImageBuffer buffer = new ImageBufferDownloadHD();
PreviewTexture skinTexture = new PreviewTexture(url.getUrl(), def, type == Type.SKIN ? new IImageBuffer() { PreviewTexture skinTexture = new PreviewTexture(url.getMetadata("model"), url.getUrl(), def, type == Type.SKIN ? new IImageBuffer() {
@Override @Override
@Nullable @Nullable
public BufferedImage parseUserSkin(BufferedImage image) { public BufferedImage parseUserSkin(BufferedImage image) {

View file

@ -10,8 +10,12 @@ public class PreviewTexture extends ThreadDownloadImageData {
private boolean uploaded; private boolean uploaded;
public PreviewTexture(String url, ResourceLocation fallbackTexture, @Nullable IImageBuffer imageBuffer) { private String model;
public PreviewTexture(String model, String url, ResourceLocation fallbackTexture, @Nullable IImageBuffer imageBuffer) {
super(null, url, fallbackTexture, imageBuffer); super(null, url, fallbackTexture, imageBuffer);
this.model = model;
} }
public boolean isTextureUploaded() { public boolean isTextureUploaded() {
@ -23,4 +27,12 @@ public class PreviewTexture extends ThreadDownloadImageData {
super.deleteGlTexture(); super.deleteGlTexture();
this.uploaded = true; this.uploaded = true;
} }
public boolean hasModel() {
return model != null;
}
public boolean usesThinArms() {
return "thin".equals(model);
}
} }

View file

@ -16,6 +16,7 @@ import net.minecraft.client.resources.SkinManager;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraft.util.EnumHandSide; import net.minecraft.util.EnumHandSide;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
@ -49,9 +50,10 @@ public class EntityPlayerModel extends EntityLivingBase {
private DynamicTexture localElytraTexture; private DynamicTexture localElytraTexture;
private TextureManager textureManager; private TextureManager textureManager;
public final GameProfile profile; public final GameProfile profile;
public boolean isSwinging = false;
protected boolean remoteSkin = false; protected boolean remoteSkin = false;
protected boolean hasLocalTexture = false; protected boolean hasLocalTexture = false;
protected boolean previewThinArms = false;
public EntityPlayerModel(GameProfile profile) { public EntityPlayerModel(GameProfile profile) {
super(null); super(null);
@ -59,8 +61,8 @@ public class EntityPlayerModel extends EntityLivingBase {
this.textureManager = Minecraft.getMinecraft().getTextureManager(); this.textureManager = Minecraft.getMinecraft().getTextureManager();
this.remoteSkinResource = new ResourceLocation("skins/preview_" + this.profile.getName() + ".png"); this.remoteSkinResource = new ResourceLocation("skins/preview_" + this.profile.getName() + ".png");
this.remoteElytraResource = new ResourceLocation("elytras/preview_" + this.profile.getName() + ".png"); this.remoteElytraResource = new ResourceLocation("elytras/preview_" + this.profile.getName() + ".png");
this.localSkinResource = NO_SKIN; this.localSkinResource = getBlankSkin();
this.localElytraResource = NO_ELYTRA; this.localElytraResource = getBlankElytra();
this.textureManager.deleteTexture(this.remoteSkinResource); this.textureManager.deleteTexture(this.remoteSkinResource);
this.textureManager.deleteTexture(this.remoteElytraResource); this.textureManager.deleteTexture(this.remoteElytraResource);
} }
@ -74,8 +76,8 @@ public class EntityPlayerModel extends EntityLivingBase {
this.textureManager.deleteTexture(this.remoteElytraResource); this.textureManager.deleteTexture(this.remoteElytraResource);
} }
this.remoteSkinTexture = HDSkinManager.getPreviewTexture(this.remoteSkinResource, this.profile, Type.SKIN, NO_SKIN, listener); this.remoteSkinTexture = HDSkinManager.getPreviewTexture(this.remoteSkinResource, this.profile, Type.SKIN, getBlankSkin(), listener);
this.remoteElytraTexture = HDSkinManager.getPreviewTexture(this.remoteElytraResource, this.profile, Type.ELYTRA, NO_ELYTRA, null); this.remoteElytraTexture = HDSkinManager.getPreviewTexture(this.remoteElytraResource, this.profile, Type.ELYTRA, getBlankElytra(), null);
} }
@ -94,7 +96,7 @@ public class EntityPlayerModel extends EntityLivingBase {
bufferedImage = new ImageBufferDownloadHD().parseUserSkin(image); bufferedImage = new ImageBufferDownloadHD().parseUserSkin(image);
assert bufferedImage != null; assert bufferedImage != null;
} catch (IOException var4) { } catch (IOException var4) {
this.localSkinResource = NO_SKIN; this.localSkinResource = getBlankSkin();
var4.printStackTrace(); var4.printStackTrace();
return; return;
} }
@ -113,7 +115,7 @@ public class EntityPlayerModel extends EntityLivingBase {
try { try {
bufferedImage = ImageIO.read(skinTextureFile); bufferedImage = ImageIO.read(skinTextureFile);
} catch (IOException var4) { } catch (IOException var4) {
this.localElytraResource = NO_ELYTRA; this.localElytraResource = getBlankElytra();
var4.printStackTrace(); var4.printStackTrace();
return; return;
} }
@ -125,6 +127,14 @@ public class EntityPlayerModel extends EntityLivingBase {
} }
} }
protected ResourceLocation getBlankSkin() {
return NO_SKIN;
}
protected ResourceLocation getBlankElytra() {
return NO_ELYTRA;
}
public boolean isUsingLocalTexture() { public boolean isUsingLocalTexture() {
return !this.remoteSkin && this.hasLocalTexture; return !this.remoteSkin && this.hasLocalTexture;
} }
@ -137,13 +147,13 @@ public class EntityPlayerModel extends EntityLivingBase {
if (this.localSkinTexture != null) { if (this.localSkinTexture != null) {
this.textureManager.deleteTexture(this.localSkinResource); this.textureManager.deleteTexture(this.localSkinResource);
this.localSkinTexture = null; this.localSkinTexture = null;
this.localSkinResource = NO_SKIN; this.localSkinResource = getBlankSkin();
this.hasLocalTexture = false; this.hasLocalTexture = false;
} }
if (this.localElytraTexture != null) { if (this.localElytraTexture != null) {
this.textureManager.deleteTexture(this.localElytraResource); this.textureManager.deleteTexture(this.localElytraResource);
this.localElytraTexture = null; this.localElytraTexture = null;
this.localElytraResource = NO_ELYTRA; this.localElytraResource = getBlankElytra();
this.hasLocalTexture = false; this.hasLocalTexture = false;
} }
} }
@ -157,21 +167,36 @@ public class EntityPlayerModel extends EntityLivingBase {
return this.remoteSkin && this.remoteElytraTexture != null ? this.remoteElytraResource : localElytraResource; return this.remoteSkin && this.remoteElytraTexture != null ? this.remoteElytraResource : localElytraResource;
} }
public void swingArm() { public void setPreviewThinArms(boolean thinArms) {
if (!this.isSwinging || this.swingProgressInt >= 4 || this.swingProgressInt < 0) { previewThinArms = thinArms;
}
public boolean usesThinSkin() {
if (isTextureSetupComplete() && remoteSkinTexture.hasModel()) {
return remoteSkinTexture.usesThinArms();
}
return previewThinArms;
}
@Override
public void swingArm(EnumHand hand) {
super.swingArm(hand);
if (!this.isSwingInProgress || this.swingProgressInt >= 4 || this.swingProgressInt < 0) {
this.swingProgressInt = -1; this.swingProgressInt = -1;
this.isSwinging = true; this.isSwingInProgress = true;
this.swingingHand = hand;
} }
} }
public void updateModel() { public void updateModel() {
this.prevSwingProgress = this.swingProgress; this.prevSwingProgress = this.swingProgress;
if (this.isSwinging) { if (this.isSwingInProgress) {
++this.swingProgressInt; ++this.swingProgressInt;
if (this.swingProgressInt >= 8) { if (this.swingProgressInt >= 8) {
this.swingProgressInt = 0; this.swingProgressInt = 0;
this.isSwinging = false; this.isSwingInProgress = false;
} }
} else { } else {
this.swingProgressInt = 0; this.swingProgressInt = 0;

View file

@ -27,6 +27,7 @@ import net.minecraft.client.resources.I18n;
import net.minecraft.init.Items; import net.minecraft.init.Items;
import net.minecraft.inventory.EntityEquipmentSlot; import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Session; import net.minecraft.util.Session;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
@ -63,6 +64,7 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
private GuiButton btnClear; private GuiButton btnClear;
private GuiButton btnBack; private GuiButton btnBack;
private GuiButton btnModeSkin; private GuiButton btnModeSkin;
private GuiButton btnModeSkinnySkin;
private GuiButton btnModeElytra; private GuiButton btnModeElytra;
protected EntityPlayerModel localPlayer; protected EntityPlayerModel localPlayer;
@ -89,6 +91,7 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
private static GuiSkins instance; private static GuiSkins instance;
private MinecraftProfileTexture.Type textureType = SKIN; private MinecraftProfileTexture.Type textureType = SKIN;
private boolean thinArmType = false;
public GuiSkins() { public GuiSkins() {
Minecraft minecraft = Minecraft.getMinecraft(); Minecraft minecraft = Minecraft.getMinecraft();
@ -181,12 +184,18 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
ItemStack skin = new ItemStack(Items.LEATHER_LEGGINGS); ItemStack skin = new ItemStack(Items.LEATHER_LEGGINGS);
Items.LEATHER_LEGGINGS.setColor(skin, 0x3c5dcb); Items.LEATHER_LEGGINGS.setColor(skin, 0x3c5dcb);
this.buttonList.add(this.btnModeElytra = new GuiItemStackButton(5, 2, 24, new ItemStack(Items.ELYTRA)));
this.buttonList.add(this.btnModeSkin = new GuiItemStackButton(4, 2, 2, skin)); this.buttonList.add(this.btnModeSkin = new GuiItemStackButton(4, 2, 2, skin));
skin = new ItemStack(Items.LEATHER_LEGGINGS);
Items.LEATHER_LEGGINGS.setColor(skin, 0xfff500);
this.buttonList.add(this.btnModeSkinnySkin = new GuiItemStackButton(6, 2, 24, skin));
this.buttonList.add(this.btnModeElytra = new GuiItemStackButton(5, 2, 46, new ItemStack(Items.ELYTRA)));
this.btnUpload.enabled = false; this.btnUpload.enabled = false;
this.btnBrowse.enabled = !this.mc.isFullScreen(); this.btnBrowse.enabled = !this.mc.isFullScreen();
(this.textureType == SKIN ? this.btnModeSkin : this.btnModeElytra).enabled = false;
this.btnModeSkin.enabled = this.thinArmType || this.textureType != SKIN;
this.btnModeSkinnySkin.enabled = !this.thinArmType || this.textureType != SKIN;
this.btnModeElytra.enabled = this.textureType == SKIN;
} }
@ -282,15 +291,24 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
this.mc.displayGuiScreen(new GuiMainMenu()); this.mc.displayGuiScreen(new GuiMainMenu());
} }
if (guiButton.id == this.btnModeSkin.id || guiButton.id == this.btnModeElytra.id) { if (guiButton.id == this.btnModeSkin.id || guiButton.id == this.btnModeElytra.id || guiButton.id == this.btnModeSkinnySkin.id) {
ItemStack stack; ItemStack stack;
if (guiButton.id == this.btnModeSkin.id) { if (guiButton.id == this.btnModeSkin.id) {
this.thinArmType = false;
this.textureType = SKIN; this.textureType = SKIN;
this.btnModeElytra.enabled = true; this.btnModeElytra.enabled = true;
this.btnModeSkinnySkin.enabled = true;
stack = ItemStack.EMPTY;
} else if (guiButton.id == this.btnModeSkinnySkin.id) {
this.thinArmType = true;
this.textureType = SKIN;
this.btnModeSkin.enabled = true;
this.btnModeElytra.enabled = true;
stack = ItemStack.EMPTY; stack = ItemStack.EMPTY;
} else { } else {
this.textureType = ELYTRA; this.textureType = ELYTRA;
this.btnModeSkin.enabled = true; this.btnModeSkin.enabled = true;
this.btnModeSkinnySkin.enabled = true;
stack = new ItemStack(Items.ELYTRA); stack = new ItemStack(Items.ELYTRA);
} }
guiButton.enabled = false; guiButton.enabled = false;
@ -301,6 +319,9 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
// put on or take off the elytra // put on or take off the elytra
this.localPlayer.setItemStackToSlot(EntityEquipmentSlot.CHEST, stack); this.localPlayer.setItemStackToSlot(EntityEquipmentSlot.CHEST, stack);
this.remotePlayer.setItemStackToSlot(EntityEquipmentSlot.CHEST, stack); this.remotePlayer.setItemStackToSlot(EntityEquipmentSlot.CHEST, stack);
this.localPlayer.setPreviewThinArms(thinArmType);
this.remotePlayer.setPreviewThinArms(thinArmType);
} }
} }
@ -317,8 +338,8 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
int bottom = this.height - 40; int bottom = this.height - 40;
int mid = this.width / 2; int mid = this.width / 2;
if ((mouseX > 30 && mouseX < mid - 30 || mouseX > mid + 30 && mouseX < this.width - 30) && mouseY > top && mouseY < bottom) { if ((mouseX > 30 && mouseX < mid - 30 || mouseX > mid + 30 && mouseX < this.width - 30) && mouseY > top && mouseY < bottom) {
this.localPlayer.swingArm(); this.localPlayer.swingArm(EnumHand.MAIN_HAND);
this.remotePlayer.swingArm(); this.remotePlayer.swingArm(EnumHand.MAIN_HAND);
} }
} }
@ -527,11 +548,13 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
Gui.drawRect(40, this.height / 2 - 12, this.width / 2 - 40, this.height / 2 + 12, 0xB0000000); Gui.drawRect(40, this.height / 2 - 12, this.width / 2 - 40, this.height / 2 + 12, 0xB0000000);
this.fontRenderer.drawStringWithShadow(this.skinMessage, (int) (xPos1 - opacity), this.height / 2 - 4, 0xffffff); this.fontRenderer.drawStringWithShadow(this.skinMessage, (int) (xPos1 - opacity), this.height / 2 - 4, 0xffffff);
} }
if (this.btnModeSkin.isMouseOver() || this.btnModeElytra.isMouseOver()) { if (this.btnModeSkin.isMouseOver() || this.btnModeElytra.isMouseOver() || this.btnModeSkinnySkin.isMouseOver()) {
int y = Math.max(mouseY, 16); int y = Math.max(mouseY, 16);
String text; String text;
if (this.btnModeSkin.isMouseOver()) { if (this.btnModeSkin.isMouseOver()) {
text = "hdskins.mode.skin"; text = "hdskins.mode.skin";
} else if (this.btnModeSkinnySkin.isMouseOver()) {
text = "hdskins.mode.skinny";
} else { } else {
text = "hdskins.mode.elytra"; text = "hdskins.mode.elytra";
} }
@ -643,14 +666,14 @@ public class GuiSkins extends GuiScreen implements FutureCallback<SkinUploadResp
private void clearUploadedSkin(Session session) { private void clearUploadedSkin(Session session) {
this.uploadingSkin = true; this.uploadingSkin = true;
this.skinUploadMessage = I18n.format("hdskins.request"); this.skinUploadMessage = I18n.format("hdskins.request");
Futures.addCallback(HDSkinManager.INSTANCE.getGatewayServer().uploadSkin(session, null, this.textureType), this); Futures.addCallback(HDSkinManager.INSTANCE.getGatewayServer().uploadSkin(session, null, this.textureType, this.thinArmType), this);
} }
private void uploadSkin(Session session, @Nullable File skinFile) { private void uploadSkin(Session session, @Nullable File skinFile) {
this.uploadingSkin = true; this.uploadingSkin = true;
this.skinUploadMessage = I18n.format("hdskins.upload"); this.skinUploadMessage = I18n.format("hdskins.upload");
Path path = skinFile == null ? null : skinFile.toPath(); Path path = skinFile == null ? null : skinFile.toPath();
Futures.addCallback(HDSkinManager.INSTANCE.getGatewayServer().uploadSkin(session, path, this.textureType), this); Futures.addCallback(HDSkinManager.INSTANCE.getGatewayServer().uploadSkin(session, path, this.textureType, this.thinArmType), this);
} }
private void setUploadError(@Nullable String error) { private void setUploadError(@Nullable String error) {

View file

@ -27,7 +27,7 @@ public class RenderPlayerModel<M extends EntityPlayerModel> extends RenderLiving
protected final ResourceLocation TEXTURE_ELYTRA = new ResourceLocation("textures/entity/elytra.png"); protected final ResourceLocation TEXTURE_ELYTRA = new ResourceLocation("textures/entity/elytra.png");
private static final ModelPlayer FAT = new ModelPlayer(0, false); private static final ModelPlayer FAT = new ModelPlayer(0, false);
//private static final ModelPlayer THIN = new ModelPlayer(0, true); private static final ModelPlayer THIN = new ModelPlayer(0, true);
public RenderPlayerModel(RenderManager renderer) { public RenderPlayerModel(RenderManager renderer) {
super(renderer, FAT, 0.0F); super(renderer, FAT, 0.0F);
@ -83,7 +83,7 @@ public class RenderPlayerModel<M extends EntityPlayerModel> extends RenderLiving
} }
public ModelPlayer getEntityModel(M entity) { public ModelPlayer getEntityModel(M entity) {
return FAT; return entity.usesThinSkin() ? THIN : FAT;
} }
@Override @Override

View file

@ -88,7 +88,7 @@ public class LegacySkinServer implements SkinServer {
} }
@Override @Override
public ListenableFuture<SkinUploadResponse> uploadSkin(Session session, @Nullable Path image, MinecraftProfileTexture.Type type) { public ListenableFuture<SkinUploadResponse> uploadSkin(Session session, @Nullable Path image, MinecraftProfileTexture.Type type, boolean thinSkinType) {
if (Strings.isNullOrEmpty(this.gateway)) if (Strings.isNullOrEmpty(this.gateway))
return Futures.immediateFailedFuture(new NullPointerException("gateway url is blank")); return Futures.immediateFailedFuture(new NullPointerException("gateway url is blank"));
@ -96,27 +96,28 @@ public class LegacySkinServer implements SkinServer {
return HDSkinManager.skinUploadExecutor.submit(() -> { return HDSkinManager.skinUploadExecutor.submit(() -> {
verifyServerConnection(session, SERVER_ID); verifyServerConnection(session, SERVER_ID);
Map<String, ?> data = image == null ? getClearData(session, type) : getUploadData(session, type, image); Map<String, ?> data = image == null ? getClearData(session, type) : getUploadData(session, type, (thinSkinType ? "thin" : "default"), image);
ThreadMultipartPostUpload upload = new ThreadMultipartPostUpload(this.gateway, data); ThreadMultipartPostUpload upload = new ThreadMultipartPostUpload(this.gateway, data);
String response = upload.uploadMultipart(); String response = upload.uploadMultipart();
return new SkinUploadResponse(response.equalsIgnoreCase("OK"), response); return new SkinUploadResponse(response.equalsIgnoreCase("OK"), response);
}); });
} }
private static Map<String, ?> getData(Session session, MinecraftProfileTexture.Type type, String param, Object val) { private static Map<String, ?> getData(Session session, MinecraftProfileTexture.Type type, String model, String param, Object val) {
return ImmutableMap.of( return ImmutableMap.of(
"user", session.getUsername(), "user", session.getUsername(),
"uuid", session.getPlayerID(), "uuid", session.getPlayerID(),
"type", type.toString().toLowerCase(Locale.US), "type", type.toString().toLowerCase(Locale.US),
"model", model,
param, val); param, val);
} }
private static Map<String, ?> getClearData(Session session, MinecraftProfileTexture.Type type) { private static Map<String, ?> getClearData(Session session, MinecraftProfileTexture.Type type) {
return getData(session, type, "clear", "1"); return getData(session, type, "default", "clear", "1");
} }
private static Map<String, ?> getUploadData(Session session, MinecraftProfileTexture.Type type, Path skinFile) { private static Map<String, ?> getUploadData(Session session, MinecraftProfileTexture.Type type, String model, Path skinFile) {
return getData(session, type, type.toString().toLowerCase(Locale.US), skinFile); return getData(session, type, model, type.toString().toLowerCase(Locale.US), skinFile);
} }
private static String getPath(String address, MinecraftProfileTexture.Type type, GameProfile profile) { private static String getPath(String address, MinecraftProfileTexture.Type type, GameProfile profile) {

View file

@ -20,7 +20,7 @@ public interface SkinServer {
Optional<MinecraftProfileTexture> getPreviewTexture(MinecraftProfileTexture.Type type, GameProfile profile); Optional<MinecraftProfileTexture> getPreviewTexture(MinecraftProfileTexture.Type type, GameProfile profile);
ListenableFuture<SkinUploadResponse> uploadSkin(Session session, @Nullable Path image, MinecraftProfileTexture.Type type); ListenableFuture<SkinUploadResponse> uploadSkin(Session session, @Nullable Path image, MinecraftProfileTexture.Type type, boolean thinArmType);
static SkinServer from(String server) { static SkinServer from(String server) {
int i = server.indexOf(':'); int i = server.indexOf(':');

View file

@ -32,7 +32,7 @@ public class ValhallaSkinServer implements SkinServer {
} }
@Override @Override
public ListenableFuture<SkinUploadResponse> uploadSkin(Session session, @Nullable Path image, MinecraftProfileTexture.Type type) { public ListenableFuture<SkinUploadResponse> uploadSkin(Session session, @Nullable Path image, MinecraftProfileTexture.Type type, boolean thinArmType) {
return null; return null;
} }

View file

@ -17,6 +17,7 @@ hdskins.upload=Uploading skin please wait...
hdskins.local=Local Skin hdskins.local=Local Skin
hdskins.server=Server Skin hdskins.server=Server Skin
hdskins.mode.skin=Skin hdskins.mode.skin=Skin (Steve)
hdskins.mode.skinny=Skin (Alex)
hdskins.mode.elytra=Elytra hdskins.mode.elytra=Elytra

View file

@ -65,7 +65,14 @@ public class PonyManager implements IResourceManagerReloadListener, ISkinCacheCl
* @param resource A texture resource * @param resource A texture resource
*/ */
public Pony getPony(ResourceLocation resource, boolean slim) { public Pony getPony(ResourceLocation resource, boolean slim) {
return poniesCache.computeIfAbsent(resource, res -> new Pony(res, slim)); Pony pony = poniesCache.computeIfAbsent(resource, res -> new Pony(res, slim));
if (pony.usesThinArms() != slim) {
pony = new Pony(resource, slim);
poniesCache.put(resource, pony);
}
return pony;
} }
/** /**

View file

@ -1,12 +1,8 @@
package com.minelittlepony.hdskins.gui; package com.minelittlepony.hdskins.gui;
import java.io.File;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import com.mojang.authlib.minecraft.MinecraftProfileTexture.Type;
import com.voxelmodpack.hdskins.gui.EntityPlayerModel; import com.voxelmodpack.hdskins.gui.EntityPlayerModel;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
/** /**
@ -20,25 +16,8 @@ public class EntityPonyModel extends EntityPlayerModel {
super(profile); super(profile);
} }
public void setLocalTexture(File skinTextureFile, Type type) { @Override
super.setLocalTexture(skinTextureFile, type); protected ResourceLocation getBlankSkin() {
} return NO_SKIN_PONY;
public ResourceLocation getSkinTexture() {
ResourceLocation skin = super.getSkinTexture();
if (skin == NO_SKIN) {
// We're a pony, might as well look like one.
return NO_SKIN_PONY;
}
return skin;
}
public void swingArm() {
super.swingArm();
// Fixes the preview model swinging the wrong arm.
// Who's maintaining HDSkins anyway?
swingingHand = EnumHand.MAIN_HAND;
} }
} }

View file

@ -1,7 +1,6 @@
package com.minelittlepony.hdskins.gui; package com.minelittlepony.hdskins.gui;
import com.minelittlepony.MineLittlePony; import com.minelittlepony.MineLittlePony;
import com.minelittlepony.PonyManager;
import com.minelittlepony.model.ModelWrapper; import com.minelittlepony.model.ModelWrapper;
import com.minelittlepony.model.components.PonyElytra; import com.minelittlepony.model.components.PonyElytra;
import com.minelittlepony.pony.data.Pony; import com.minelittlepony.pony.data.Pony;
@ -40,9 +39,7 @@ public class RenderPonyModel extends RenderPlayerModel<EntityPonyModel> {
return super.getEntityModel(playermodel); return super.getEntityModel(playermodel);
} }
// TODO: We can't find out whether to use thin arms just by the texture. Pony thePony = MineLittlePony.getInstance().getManager().getPony(loc, playermodel.usesThinSkin());
// Maybe a trigger pixel for thin arms? #FutureThoughts
Pony thePony = MineLittlePony.getInstance().getManager().getPony(loc, PonyManager.isSlimSkin(playermodel.profile.getId()));
if (thePony.getRace(false).isHuman()) { if (thePony.getRace(false).isHuman()) {
return super.getEntityModel(playermodel); return super.getEntityModel(playermodel);

View file

@ -136,6 +136,10 @@ public class Pony {
return metadata.getRace().getEffectiveRace(MineLittlePony.getConfig().getEffectivePonyLevel(ignorePony)); return metadata.getRace().getEffectiveRace(MineLittlePony.getConfig().getEffectivePonyLevel(ignorePony));
} }
public boolean usesThinArms() {
return smallArms;
}
public ResourceLocation getTexture() { public ResourceLocation getTexture() {
return texture; return texture;
} }