Simplify armour code and fix armour visibility being set before setting the armour variant

This commit is contained in:
Sollace 2023-02-27 13:31:37 +00:00
parent 20372dbfd3
commit 94592212c6
14 changed files with 88 additions and 130 deletions

View file

@ -61,6 +61,10 @@ public class PonyConfig extends Config {
.addComment("Overrides pony races") .addComment("Overrides pony races")
.addComment("Possible values: HUMAN (default), EARTH, PEGASUS, UNICORN, ALICORN, CHANGELING, ZEBRA, CHANGEDLING, GRYPHON, HIPPOGRIFF, KIRIN, BAYPONT, SEAPONY"); .addComment("Possible values: HUMAN (default), EARTH, PEGASUS, UNICORN, ALICORN, CHANGELING, ZEBRA, CHANGEDLING, GRYPHON, HIPPOGRIFF, KIRIN, BAYPONT, SEAPONY");
public final Setting<Boolean> disablePonifiedArmour = value("debug", "usePonifiedArmour", false)
.addComment("Disables pony armour textures.")
.addComment("If enabled, only the vanilla textures will be considered");
public final Setting<Boolean> flappyElytras = value("customisation", "flappyElytras", false) public final Setting<Boolean> flappyElytras = value("customisation", "flappyElytras", false)
.addComment("Pegasi will use their wings to fly even when they're wearing an elytra"); .addComment("Pegasi will use their wings to fly even when they're wearing an elytra");
public final Setting<Boolean> noFun = value("customisation", "noFun", false) public final Setting<Boolean> noFun = value("customisation", "noFun", false)

View file

@ -12,13 +12,6 @@ public interface IArmourModel {
*/ */
void synchroniseAngles(IModel model); void synchroniseAngles(IModel model);
/**
* Resets the state of this model to all invisible.
*/
void setInVisible();
void setVariant(ArmourVariant variant);
/** /**
* Prepares an armour model for rendering, first hiding all the pieces and then incrementally showing them as appropriate. * Prepares an armour model for rendering, first hiding all the pieces and then incrementally showing them as appropriate.
* *
@ -27,65 +20,5 @@ public interface IArmourModel {
* *
* @return false to skip this render pass. * @return false to skip this render pass.
*/ */
default boolean prepareToRender(EquipmentSlot slot, ArmourLayer layer) { boolean setVisibilities(EquipmentSlot slot, ArmourLayer layer, ArmourVariant variant);
setInVisible();
switch (layer) {
case OUTER:
switch (slot) {
case HEAD:
showHelmet();
return true;
case FEET:
showBoots();
return true;
case CHEST:
showSaddle();
return true;
default:
return false;
}
case INNER:
switch (slot) {
case LEGS:
showLeggings();
return true;
case CHEST:
showChestplate();
return true;
default:
return false;
}
}
return false;
}
/**
* Called to display the model's boots.
*/
void showBoots();
/**
* Called to display the leg part of the model. Legs and boots use the same components just with separated texture files
* so it's reasonable that this would also call showBoots()
*/
void showLeggings();
/**
* Shows the chestplate and saddle.
*
* @param outside true when being called to render the external cloth layer (saddle), false for the main body piece.
*/
void showChestplate();
/**
* Ponies wear saddles. #dealwithit
*/
void showSaddle();
/**
* Used to make the helmet visible
*/
void showHelmet();
} }

View file

@ -15,7 +15,7 @@ import com.minelittlepony.client.model.armour.DefaultArmourTextureResolver;
* This is for modders who want to override the default implementation found in {@link DefaultArmourTextureResolver}. * This is for modders who want to override the default implementation found in {@link DefaultArmourTextureResolver}.
*/ */
public interface IArmourTextureResolver { public interface IArmourTextureResolver {
IArmourTextureResolver DEFAULT = new DefaultArmourTextureResolver(); IArmourTextureResolver DEFAULT = DefaultArmourTextureResolver.INSTANCE;
/** /**
* Gets the armour texture to be used for the given entity, armour piece, slot, and render layer. * Gets the armour texture to be used for the given entity, armour piece, slot, and render layer.

View file

@ -101,6 +101,9 @@ public class GuiPonySettings extends GameGui {
content.addButton(new Label(LEFT, row += 30)).getStyle().setText("minelp.debug.race"); content.addButton(new Label(LEFT, row += 30)).getStyle().setText("minelp.debug.race");
content.addButton(new EnumSlider<>(LEFT, row += 15, config.raceOverride.get()) content.addButton(new EnumSlider<>(LEFT, row += 15, config.raceOverride.get())
.onChange(config.raceOverride::set)); .onChange(config.raceOverride::set));
content.addButton(new Label(LEFT, row += 30)).getStyle().setText("minelp.debug.armour");
content.addButton(new Toggle(LEFT, row += 15, config.disablePonifiedArmour.get())
.onChange(config.disablePonifiedArmour::set));
} }
row += 20; row += 20;

View file

@ -11,6 +11,7 @@ import net.minecraft.util.Identifier;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.google.common.cache.Cache; import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.minelittlepony.api.config.PonyConfig;
import com.minelittlepony.api.model.armour.ArmourLayer; import com.minelittlepony.api.model.armour.ArmourLayer;
import com.minelittlepony.api.model.armour.ArmourVariant; import com.minelittlepony.api.model.armour.ArmourVariant;
import com.minelittlepony.api.model.armour.IArmourTextureResolver; import com.minelittlepony.api.model.armour.IArmourTextureResolver;
@ -43,17 +44,23 @@ import java.util.concurrent.TimeUnit;
* @see IArmourTextureResolver * @see IArmourTextureResolver
*/ */
public class DefaultArmourTextureResolver implements IArmourTextureResolver { public class DefaultArmourTextureResolver implements IArmourTextureResolver {
public static final DefaultArmourTextureResolver INSTANCE = new DefaultArmourTextureResolver();
private final Cache<String, Identifier> cache = CacheBuilder.newBuilder() private final Cache<String, Identifier> cache = CacheBuilder.newBuilder()
.expireAfterAccess(30, TimeUnit.SECONDS) .expireAfterAccess(30, TimeUnit.SECONDS)
.<String, Identifier>build(); .<String, Identifier>build();
public void invalidate() {
cache.invalidateAll();
}
@Override @Override
public Identifier getTexture(LivingEntity entity, ItemStack stack, EquipmentSlot slot, ArmourLayer layer, @Nullable String type) { public Identifier getTexture(LivingEntity entity, ItemStack stack, EquipmentSlot slot, ArmourLayer layer, @Nullable String type) {
Identifier material = new Identifier(((ArmorItem) stack.getItem()).getMaterial().getName()); Identifier material = new Identifier(((ArmorItem) stack.getItem()).getMaterial().getName());
String custom = getCustom(stack); String custom = getCustom(stack);
try { try {
cache.invalidateAll();
return cache.get(String.format("%s#%s#%s#%s", material, layer, type, custom), () -> { return cache.get(String.format("%s#%s#%s#%s", material, layer, type, custom), () -> {
String typed = Strings.nullToEmpty(type); String typed = Strings.nullToEmpty(type);
String extra = typed.isEmpty() ? "" : "_" + typed; String extra = typed.isEmpty() ? "" : "_" + typed;
@ -106,10 +113,13 @@ public class DefaultArmourTextureResolver implements IArmourTextureResolver {
domain = "minelittlepony"; // it's a vanilla armor. I provide these. domain = "minelittlepony"; // it's a vanilla armor. I provide these.
} }
Identifier pony = new Identifier(domain, human.getPath().replace(".png", "_pony.png")); if (!PonyConfig.getInstance().disablePonifiedArmour.get()) {
if (isValid(pony)) { Identifier pony = new Identifier(domain, human.getPath().replace(".png", "_pony.png"));
return pony;
if (isValid(pony)) {
return pony;
}
} }
if (isValid(human)) { if (isValid(human)) {

View file

@ -2,6 +2,7 @@ package com.minelittlepony.client.model.armour;
import net.minecraft.client.model.ModelPart; import net.minecraft.client.model.ModelPart;
import net.minecraft.client.render.entity.model.BipedEntityModel; import net.minecraft.client.render.entity.model.BipedEntityModel;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import com.minelittlepony.api.model.IModel; import com.minelittlepony.api.model.IModel;
@ -15,8 +16,6 @@ public class PonyArmourModel<T extends LivingEntity> extends AbstractPonyModel<T
private ModelPart steveRightLeg; private ModelPart steveRightLeg;
private ModelPart steveLeftLeg; private ModelPart steveLeftLeg;
private ArmourVariant variant = ArmourVariant.NORMAL;
public PonyArmourModel(ModelPart tree) { public PonyArmourModel(ModelPart tree) {
super(tree); super(tree);
chestPiece = tree.getChild("chestpiece"); chestPiece = tree.getChild("chestpiece");
@ -41,11 +40,6 @@ public class PonyArmourModel<T extends LivingEntity> extends AbstractPonyModel<T
chestPiece.pivotZ = rotationPointZ; chestPiece.pivotZ = rotationPointZ;
} }
@Override
public void setVariant(ArmourVariant variant) {
this.variant = variant;
}
@Override @Override
public void synchroniseAngles(IModel model) { public void synchroniseAngles(IModel model) {
if (model instanceof BipedEntityModel) { if (model instanceof BipedEntityModel) {
@ -66,7 +60,7 @@ public class PonyArmourModel<T extends LivingEntity> extends AbstractPonyModel<T
} }
@Override @Override
public void setInVisible() { public boolean setVisibilities(EquipmentSlot slot, ArmourLayer layer, ArmourVariant variant) {
setVisible(false); setVisible(false);
chestPiece.visible = false; chestPiece.visible = false;
head.visible = false; head.visible = false;
@ -74,10 +68,43 @@ public class PonyArmourModel<T extends LivingEntity> extends AbstractPonyModel<T
upperTorso.visible = false; upperTorso.visible = false;
steveLeftLeg.visible = false; steveLeftLeg.visible = false;
steveRightLeg.visible = false; steveRightLeg.visible = false;
switch (layer) {
case OUTER:
switch (slot) {
case HEAD:
head.visible = true;
return true;
case FEET:
showLeggings(layer, variant);
return true;
case CHEST:
body.visible = variant == ArmourVariant.LEGACY;
upperTorso.visible = variant == ArmourVariant.LEGACY;
chestPiece.visible = variant == ArmourVariant.NORMAL;
return true;
default:
return false;
}
case INNER:
switch (slot) {
case LEGS:
showLeggings(layer, variant);
return true;
case CHEST:
body.visible = variant == ArmourVariant.LEGACY;
upperTorso.visible = variant == ArmourVariant.LEGACY;
chestPiece.visible = variant == ArmourVariant.NORMAL;
return true;
default:
return false;
}
default:
return false;
}
} }
@Override protected void showLeggings(ArmourLayer layer, ArmourVariant variant) {
public void showBoots() {
rightArm.visible = true; rightArm.visible = true;
leftArm.visible = true; leftArm.visible = true;
rightLeg.visible = variant == ArmourVariant.NORMAL; rightLeg.visible = variant == ArmourVariant.NORMAL;
@ -85,28 +112,4 @@ public class PonyArmourModel<T extends LivingEntity> extends AbstractPonyModel<T
steveLeftLeg.visible = variant == ArmourVariant.LEGACY; steveLeftLeg.visible = variant == ArmourVariant.LEGACY;
steveRightLeg.visible = variant == ArmourVariant.LEGACY; steveRightLeg.visible = variant == ArmourVariant.LEGACY;
} }
@Override
public void showLeggings() {
showBoots();
}
@Override
public void showChestplate() {
body.visible = variant == ArmourVariant.LEGACY;
upperTorso.visible = variant == ArmourVariant.LEGACY;
chestPiece.visible = variant == ArmourVariant.NORMAL;
}
@Override
public void showSaddle() {
body.visible = variant == ArmourVariant.LEGACY;
upperTorso.visible = variant == ArmourVariant.LEGACY;
chestPiece.visible = variant == ArmourVariant.NORMAL;
}
@Override
public void showHelmet() {
head.visible = true;
}
} }

View file

@ -47,7 +47,6 @@ public class ParaspriteModel<T extends LivingEntity> extends EntityModel<T> {
root.pitch = MathHelper.clamp((float)entity.getVelocity().horizontalLength() / 10F, 0, 0.1F); root.pitch = MathHelper.clamp((float)entity.getVelocity().horizontalLength() / 10F, 0, 0.1F);
body.pitch = 0; body.pitch = 0;
lips.visible = false;
if (entity.hasPassengers()) { if (entity.hasPassengers()) {
root.yaw = 0; root.yaw = 0;
@ -72,12 +71,10 @@ public class ParaspriteModel<T extends LivingEntity> extends EntityModel<T> {
float basWingExpand = 1; float basWingExpand = 1;
float innerWingExpand = basWingExpand / 2F; float innerWingExpand = basWingExpand / 2F;
leftWing.visible = true;
leftWing.pitch = 0; leftWing.pitch = 0;
leftWing.roll = basWingExpand + cos + 0.3F; leftWing.roll = basWingExpand + cos + 0.3F;
leftWing.yaw = basWingExpand - sin; leftWing.yaw = basWingExpand - sin;
rightWing.visible = true;
rightWing.pitch = 0; rightWing.pitch = 0;
rightWing.roll = -basWingExpand - cos - 0.3F; rightWing.roll = -basWingExpand - cos - 0.3F;
rightWing.yaw = -basWingExpand + sin; rightWing.yaw = -basWingExpand + sin;
@ -85,12 +82,10 @@ public class ParaspriteModel<T extends LivingEntity> extends EntityModel<T> {
sin = -(float)Math.sin(ticks + Math.PI / 4F) / 2F; sin = -(float)Math.sin(ticks + Math.PI / 4F) / 2F;
cos = (float)Math.cos(ticks + Math.PI / 4F) / 3F; cos = (float)Math.cos(ticks + Math.PI / 4F) / 3F;
leftWing2.visible = true;
leftWing2.pitch = 0; leftWing2.pitch = 0;
leftWing2.roll = innerWingExpand + sin - 0.3F; leftWing2.roll = innerWingExpand + sin - 0.3F;
leftWing2.yaw = innerWingExpand - cos + 0.3F; leftWing2.yaw = innerWingExpand - cos + 0.3F;
rightWing2.visible = true;
rightWing2.pitch = 0; rightWing2.pitch = 0;
rightWing2.roll = -innerWingExpand - sin + 0.3F; rightWing2.roll = -innerWingExpand - sin + 0.3F;
rightWing2.yaw = -innerWingExpand + cos - 0.3F; rightWing2.yaw = -innerWingExpand + cos - 0.3F;

View file

@ -4,6 +4,8 @@ import com.minelittlepony.client.model.armour.PonyArmourModel;
import com.minelittlepony.mson.api.ModelContext; import com.minelittlepony.mson.api.ModelContext;
import com.minelittlepony.api.model.BodyPart; import com.minelittlepony.api.model.BodyPart;
import com.minelittlepony.api.model.ModelAttributes; import com.minelittlepony.api.model.ModelAttributes;
import com.minelittlepony.api.model.armour.ArmourLayer;
import com.minelittlepony.api.model.armour.ArmourVariant;
import com.minelittlepony.api.pony.IPony; import com.minelittlepony.api.pony.IPony;
import net.minecraft.client.model.ModelPart; import net.minecraft.client.model.ModelPart;
@ -138,7 +140,7 @@ public class SeaponyModel<T extends LivingEntity> extends UnicornModel<T> {
} }
@Override @Override
public void showBoots() { public void showLeggings(ArmourLayer layer, ArmourVariant variant) {
rightArm.visible = true; rightArm.visible = true;
leftArm.visible = true; leftArm.visible = true;
} }

View file

@ -6,7 +6,6 @@ import com.minelittlepony.api.pony.meta.Race;
import com.minelittlepony.api.pony.meta.Wearable; import com.minelittlepony.api.pony.meta.Wearable;
import com.minelittlepony.client.SkinsProxy; import com.minelittlepony.client.SkinsProxy;
import com.minelittlepony.client.model.*; import com.minelittlepony.client.model.*;
import com.minelittlepony.client.model.gear.SaddleBags;
import com.minelittlepony.client.render.DebugBoundingBoxRenderer; import com.minelittlepony.client.render.DebugBoundingBoxRenderer;
import com.minelittlepony.client.render.IPonyRenderContext; import com.minelittlepony.client.render.IPonyRenderContext;
import com.minelittlepony.client.render.EquineRenderManager; import com.minelittlepony.client.render.EquineRenderManager;
@ -197,8 +196,11 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements IPonyRen
@Override @Override
public Identifier getDefaultTexture(AbstractClientPlayerEntity entity, Wearable wearable) { public Identifier getDefaultTexture(AbstractClientPlayerEntity entity, Wearable wearable) {
return SkinsProxy.instance.getSkin(wearable.getId(), entity).orElseGet(() -> { return SkinsProxy.instance.getSkin(wearable.getId(), entity).orElseGet(() -> {
if (wearable.isSaddlebags() && getInternalRenderer().getModel().getMetadata().getRace() == Race.BATPONY) { if (wearable.isSaddlebags()) {
return SaddleBags.TEXTURE; if (getInternalRenderer().getModel().getMetadata().getRace() == Race.BATPONY) {
return wearable.getDefaultTexture();
}
return manager.getTexture(entity);
} }
return wearable.getDefaultTexture(); return wearable.getDefaultTexture();

View file

@ -56,15 +56,21 @@ public class ArmourFeature<T extends LivingEntity, M extends EntityModel<T> & IP
return; return;
} }
model.setMetadata(pony.body().getMetadata()); IArmourTextureResolver resolver = model.getArmourTextureResolver();
boolean glint = itemstack.hasGlint();
Identifier texture = resolver.getTexture(entity, itemstack, armorSlot, layer, null);
Item item = itemstack.getItem();
if (model.setVisibilities(armorSlot, layer, resolver.getVariant(layer, texture))) {
model.setMetadata(pony.body().getMetadata());
if (model.prepareToRender(armorSlot, layer)) {
pony.body().copyAttributes(model); pony.body().copyAttributes(model);
model.setAngles(entity, limbAngle, limbDistance, age, headYaw, headPitch); model.setAngles(entity, limbAngle, limbDistance, age, headYaw, headPitch);
model.synchroniseAngles(pony.body()); model.synchroniseAngles(pony.body());
Item item = itemstack.getItem();
float red = 1; float red = 1;
float green = 1; float green = 1;
float blue = 1; float blue = 1;
@ -76,25 +82,22 @@ public class ArmourFeature<T extends LivingEntity, M extends EntityModel<T> & IP
blue = Color.b(color); blue = Color.b(color);
} }
IArmourTextureResolver resolver = model.getArmourTextureResolver(); renderArmourPart(stack, renderContext, lightUv, glint, model, red, green, blue, texture);
boolean glint = itemstack.hasGlint();
renderArmourPart(stack, renderContext, lightUv, glint, model, red, green, blue, resolver, layer, resolver.getTexture(entity, itemstack, armorSlot, layer, null));
if (item instanceof DyeableArmorItem) { if (item instanceof DyeableArmorItem) {
renderArmourPart(stack, renderContext, lightUv, false, model, 1, 1, 1, resolver, layer, resolver.getTexture(entity, itemstack, armorSlot, layer, "overlay")); texture = resolver.getTexture(entity, itemstack, armorSlot, layer, "overlay");
if (model.setVisibilities(armorSlot, layer, resolver.getVariant(layer, texture))) {
renderArmourPart(stack, renderContext, lightUv, false, model, 1, 1, 1, texture);
}
} }
} }
} }
private static <T extends LivingEntity, V extends BipedEntityModel<T> & IArmourModel> void renderArmourPart( private static <T extends LivingEntity, V extends BipedEntityModel<T> & IArmourModel> void renderArmourPart(
MatrixStack matrices, VertexConsumerProvider provider, MatrixStack matrices, VertexConsumerProvider provider,
int light, boolean glint, V model, float r, float g, float b, IArmourTextureResolver resolver, ArmourLayer layer, Identifier texture) { int light, boolean glint, V model, float r, float g, float b, Identifier texture) {
VertexConsumer vertices = ItemRenderer.getArmorGlintConsumer(provider, RenderLayer.getArmorCutoutNoCull(texture), false, glint); VertexConsumer vertices = ItemRenderer.getArmorGlintConsumer(provider, RenderLayer.getArmorCutoutNoCull(texture), false, glint);
model.setVariant(resolver.getVariant(layer, texture));
model.render(matrices, vertices, light, OverlayTexture.DEFAULT_UV, r, g, b, 1); model.render(matrices, vertices, light, OverlayTexture.DEFAULT_UV, r, g, b, 1);
} }
} }

View file

@ -4,6 +4,7 @@ import net.minecraft.client.MinecraftClient;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
import com.minelittlepony.api.config.PonyConfig; import com.minelittlepony.api.config.PonyConfig;
import com.minelittlepony.client.model.armour.DefaultArmourTextureResolver;
import com.minelittlepony.client.render.MobRenderers; import com.minelittlepony.client.render.MobRenderers;
import com.minelittlepony.common.client.gui.VisibilityMode; import com.minelittlepony.common.client.gui.VisibilityMode;
import com.minelittlepony.common.util.settings.Setting; import com.minelittlepony.common.util.settings.Setting;
@ -24,6 +25,7 @@ public class ClientPonyConfig extends PonyConfig {
public ClientPonyConfig(Path path) { public ClientPonyConfig(Path path) {
super(path); super(path);
MobRenderers.REGISTRY.values().forEach(r -> value("entities", r.name, true)); MobRenderers.REGISTRY.values().forEach(r -> value("entities", r.name, true));
disablePonifiedArmour.onChanged(t -> DefaultArmourTextureResolver.INSTANCE.invalidate());
} }
@Override @Override

View file

@ -50,6 +50,7 @@
"minelp.debug.scale.min": "Miniscule", "minelp.debug.scale.min": "Miniscule",
"minelp.debug.size": "Size Override", "minelp.debug.size": "Size Override",
"minelp.debug.race": "Race Override", "minelp.debug.race": "Race Override",
"minelp.debug.armour": "Disable ponified armour textures",
"hdskins.mode.minelp_seapony": "Seapony", "hdskins.mode.minelp_seapony": "Seapony",
"hdskins.mode.minelittlepony_crown": "Crown", "hdskins.mode.minelittlepony_crown": "Crown",

View file

@ -1,7 +1,7 @@
{ {
"parent": "minelittlepony:steve_pony", "parent": "minelittlepony:steve_pony",
"texture": {"w": 64, "h": 32}, "texture": {"w": 64, "h": 32},
"dilate": 0.27, "dilate": 0.2,
"data": { "data": {
"body": { "body": {
"texture": { "u": 16, "v": 18 }, "texture": { "u": 16, "v": 18 },

View file

@ -1,4 +1,4 @@
{ {
"parent": "minelittlepony:armor/inner_pony_armor", "parent": "minelittlepony:armor/inner_pony_armor",
"dilate": 0.3 "dilate": 0.4
} }