From abfab92d781a07195d2b232674adc69bc2855cdb Mon Sep 17 00:00:00 2001 From: Sollace Date: Fri, 5 Feb 2021 22:11:19 +0200 Subject: [PATCH] Improve modding support for adding custom gear --- .../client/model/AbstractPonyModel.java | 2 +- .../client/model/ClientPonyModel.java | 2 +- .../client/model/ModelWrapper.java | 2 +- .../client/model/gear/AbstractGear.java | 2 +- .../client/model/gear/ChristmasHat.java | 10 ++-- .../client/model/gear/IRenderContext.java | 26 ---------- .../client/model/gear/Muffin.java | 1 + .../client/model/gear/SaddleBags.java | 10 ++-- .../client/model/gear/Stetson.java | 1 + .../client/model/gear/WitchHat.java | 1 + .../client/render/IPonyRenderContext.java | 2 +- .../render/entity/feature/GearFeature.java | 50 +++++++++++------- .../{capabilities => }/IModelWrapper.java | 2 +- .../model/armour/IEquestrianArmour.java | 2 +- .../capabilities/fabric/package-info.java | 4 -- .../fabric/PonyModelPrepareCallback.java | 2 +- .../package-info.java | 2 +- .../com/minelittlepony/model/gear/IGear.java | 51 +++++++++++++++++-- .../model/gear/IRenderContext.java | 41 +++++++++++++++ 19 files changed, 144 insertions(+), 69 deletions(-) delete mode 100644 src/main/java/com/minelittlepony/client/model/gear/IRenderContext.java rename src/main/java/com/minelittlepony/model/{capabilities => }/IModelWrapper.java (81%) delete mode 100644 src/main/java/com/minelittlepony/model/capabilities/fabric/package-info.java rename src/main/java/com/minelittlepony/model/{capabilities => }/fabric/PonyModelPrepareCallback.java (92%) rename src/main/java/com/minelittlepony/model/{capabilities => fabric}/package-info.java (64%) create mode 100644 src/main/java/com/minelittlepony/model/gear/IRenderContext.java diff --git a/src/main/java/com/minelittlepony/client/model/AbstractPonyModel.java b/src/main/java/com/minelittlepony/client/model/AbstractPonyModel.java index b47ea714..5f97cfd0 100644 --- a/src/main/java/com/minelittlepony/client/model/AbstractPonyModel.java +++ b/src/main/java/com/minelittlepony/client/model/AbstractPonyModel.java @@ -2,7 +2,7 @@ package com.minelittlepony.client.model; import com.minelittlepony.client.model.armour.PonyArmourModel; import com.minelittlepony.client.render.EquineRenderManager; -import com.minelittlepony.model.capabilities.fabric.PonyModelPrepareCallback; +import com.minelittlepony.model.fabric.PonyModelPrepareCallback; import com.minelittlepony.api.pony.meta.Race; import com.minelittlepony.api.pony.meta.Sizes; import com.minelittlepony.client.model.armour.ArmourWrapper; diff --git a/src/main/java/com/minelittlepony/client/model/ClientPonyModel.java b/src/main/java/com/minelittlepony/client/model/ClientPonyModel.java index 0e395a77..b385cdca 100644 --- a/src/main/java/com/minelittlepony/client/model/ClientPonyModel.java +++ b/src/main/java/com/minelittlepony/client/model/ClientPonyModel.java @@ -6,7 +6,7 @@ import net.minecraft.entity.LivingEntity; import net.minecraft.util.Arm; import net.minecraft.util.Hand; -import com.minelittlepony.model.capabilities.fabric.PonyModelPrepareCallback; +import com.minelittlepony.model.fabric.PonyModelPrepareCallback; import com.minelittlepony.api.pony.IPony; import com.minelittlepony.api.pony.IPonyData; import com.minelittlepony.api.pony.meta.Size; diff --git a/src/main/java/com/minelittlepony/client/model/ModelWrapper.java b/src/main/java/com/minelittlepony/client/model/ModelWrapper.java index aba00a76..ac853a95 100644 --- a/src/main/java/com/minelittlepony/client/model/ModelWrapper.java +++ b/src/main/java/com/minelittlepony/client/model/ModelWrapper.java @@ -4,9 +4,9 @@ import net.minecraft.entity.LivingEntity; import com.minelittlepony.api.pony.IPonyData; import com.minelittlepony.model.IModel; +import com.minelittlepony.model.IModelWrapper; import com.minelittlepony.model.armour.IArmour; import com.minelittlepony.model.armour.IEquestrianArmour; -import com.minelittlepony.model.capabilities.IModelWrapper; import com.minelittlepony.mson.api.ModelKey; /** diff --git a/src/main/java/com/minelittlepony/client/model/gear/AbstractGear.java b/src/main/java/com/minelittlepony/client/model/gear/AbstractGear.java index b63e7254..864c69c9 100644 --- a/src/main/java/com/minelittlepony/client/model/gear/AbstractGear.java +++ b/src/main/java/com/minelittlepony/client/model/gear/AbstractGear.java @@ -25,7 +25,7 @@ public abstract class AbstractGear extends Model implements IGear { } @Override - public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlayUv, int lightUv, float red, float green, float blue, float alpha, UUID interpolatorId) { + public void render(MatrixStack stack, VertexConsumer vertices, int overlayUv, int lightUv, float red, float green, float blue, float alpha, UUID interpolatorId) { render(stack, vertices, overlayUv, lightUv, red, green, blue, alpha); } diff --git a/src/main/java/com/minelittlepony/client/model/gear/ChristmasHat.java b/src/main/java/com/minelittlepony/client/model/gear/ChristmasHat.java index 2d71c027..29177509 100644 --- a/src/main/java/com/minelittlepony/client/model/gear/ChristmasHat.java +++ b/src/main/java/com/minelittlepony/client/model/gear/ChristmasHat.java @@ -11,11 +11,13 @@ import com.minelittlepony.api.pony.meta.Wearable; import com.minelittlepony.common.util.Color; import com.minelittlepony.model.BodyPart; import com.minelittlepony.model.IModel; +import com.minelittlepony.model.PonyModelConstants; +import com.minelittlepony.model.gear.IRenderContext; import java.util.Calendar; import java.util.UUID; -public class ChristmasHat extends AbstractGear { +public class ChristmasHat extends AbstractGear implements PonyModelConstants { private static boolean dayChecked = false; private static boolean dayResult = false; @@ -49,12 +51,12 @@ public class ChristmasHat extends AbstractGear { } @Override - public void setLivingAnimations(IModel model, Entity entity) { + public void setModelAttributes(IModel model, Entity entity) { tint = model.getMetadata().getGlowColor(); } @Override - public void setRotationAndAngles(boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) { + public void pose(boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) { float pi = PI * (float) Math.pow(swing, 16); float mve = move * 0.6662f; @@ -79,7 +81,7 @@ public class ChristmasHat extends AbstractGear { } @Override - public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlayUv, int lightUv, float red, float green, float blue, float alpha, UUID interpolatorId) { + public void render(MatrixStack stack, VertexConsumer vertices, int overlayUv, int lightUv, float red, float green, float blue, float alpha, UUID interpolatorId) { if (tint != 0) { red = Color.r(tint); green = Color.g(tint); diff --git a/src/main/java/com/minelittlepony/client/model/gear/IRenderContext.java b/src/main/java/com/minelittlepony/client/model/gear/IRenderContext.java deleted file mode 100644 index c5edc1bb..00000000 --- a/src/main/java/com/minelittlepony/client/model/gear/IRenderContext.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.minelittlepony.client.model.gear; - -import net.minecraft.entity.Entity; -import net.minecraft.util.Identifier; - -import com.minelittlepony.api.pony.meta.Wearable; -import com.minelittlepony.model.IModel; -import com.minelittlepony.model.gear.IGear; - -import javax.annotation.Nullable; - -public interface IRenderContext { - - IRenderContext NULL = (e, g) -> null; - - default boolean shouldRender(M model, T entity, Wearable wearable, IGear gear) { - return gear.canRender(model, entity); - } - - @Nullable - default IModel getEntityModel() { - return null; - } - - Identifier getDefaultTexture(T entity, Wearable wearable); -} diff --git a/src/main/java/com/minelittlepony/client/model/gear/Muffin.java b/src/main/java/com/minelittlepony/client/model/gear/Muffin.java index 95ab5fbf..aad00a6f 100644 --- a/src/main/java/com/minelittlepony/client/model/gear/Muffin.java +++ b/src/main/java/com/minelittlepony/client/model/gear/Muffin.java @@ -7,6 +7,7 @@ import net.minecraft.util.Identifier; import com.minelittlepony.api.pony.meta.Wearable; import com.minelittlepony.model.BodyPart; import com.minelittlepony.model.IModel; +import com.minelittlepony.model.gear.IRenderContext; import com.minelittlepony.model.gear.IStackable; public class Muffin extends AbstractGear implements IStackable { diff --git a/src/main/java/com/minelittlepony/client/model/gear/SaddleBags.java b/src/main/java/com/minelittlepony/client/model/gear/SaddleBags.java index 4a45f1c9..18ee223e 100644 --- a/src/main/java/com/minelittlepony/client/model/gear/SaddleBags.java +++ b/src/main/java/com/minelittlepony/client/model/gear/SaddleBags.java @@ -5,6 +5,8 @@ import com.minelittlepony.api.pony.meta.Wearable; import com.minelittlepony.model.BodyPart; import com.minelittlepony.model.IModel; import com.minelittlepony.model.IPegasus; +import com.minelittlepony.model.PonyModelConstants; +import com.minelittlepony.model.gear.IRenderContext; import java.util.UUID; @@ -15,7 +17,7 @@ import net.minecraft.entity.Entity; import net.minecraft.util.Identifier; import net.minecraft.util.math.MathHelper; -public class SaddleBags extends AbstractGear { +public class SaddleBags extends AbstractGear implements PonyModelConstants { public static final Identifier TEXTURE = new Identifier("minelittlepony", "textures/models/saddlebags.png"); @@ -37,7 +39,7 @@ public class SaddleBags extends AbstractGear { } @Override - public void setLivingAnimations(IModel model, Entity entity) { + public void setModelAttributes(IModel model, Entity entity) { this.model = model; hangLow = false; @@ -48,7 +50,7 @@ public class SaddleBags extends AbstractGear { } @Override - public void setRotationAndAngles(boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) { + public void pose(boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) { float pi = PI * (float) Math.pow(swing, 16); float mve = move * 0.6662f; @@ -75,7 +77,7 @@ public class SaddleBags extends AbstractGear { } @Override - public void renderPart(MatrixStack stack, VertexConsumer renderContext, int overlayUv, int lightUv, float red, float green, float blue, float alpha, UUID interpolatorId) { + public void render(MatrixStack stack, VertexConsumer renderContext, int overlayUv, int lightUv, float red, float green, float blue, float alpha, UUID interpolatorId) { dropAmount = model.getMetadata().getInterpolator(interpolatorId).interpolate("dropAmount", dropAmount, 3); stack.push(); diff --git a/src/main/java/com/minelittlepony/client/model/gear/Stetson.java b/src/main/java/com/minelittlepony/client/model/gear/Stetson.java index f4c3fd9d..9df44325 100644 --- a/src/main/java/com/minelittlepony/client/model/gear/Stetson.java +++ b/src/main/java/com/minelittlepony/client/model/gear/Stetson.java @@ -7,6 +7,7 @@ import net.minecraft.util.Identifier; import com.minelittlepony.api.pony.meta.Wearable; import com.minelittlepony.model.BodyPart; import com.minelittlepony.model.IModel; +import com.minelittlepony.model.gear.IRenderContext; import com.minelittlepony.model.gear.IStackable; public class Stetson extends AbstractGear implements IStackable { diff --git a/src/main/java/com/minelittlepony/client/model/gear/WitchHat.java b/src/main/java/com/minelittlepony/client/model/gear/WitchHat.java index cab695c1..de48e6e1 100644 --- a/src/main/java/com/minelittlepony/client/model/gear/WitchHat.java +++ b/src/main/java/com/minelittlepony/client/model/gear/WitchHat.java @@ -7,6 +7,7 @@ import net.minecraft.util.Identifier; import com.minelittlepony.api.pony.meta.Wearable; import com.minelittlepony.model.BodyPart; import com.minelittlepony.model.IModel; +import com.minelittlepony.model.gear.IRenderContext; import com.minelittlepony.model.gear.IStackable; public class WitchHat extends AbstractGear implements IStackable { diff --git a/src/main/java/com/minelittlepony/client/render/IPonyRenderContext.java b/src/main/java/com/minelittlepony/client/render/IPonyRenderContext.java index efaac375..09948fc5 100644 --- a/src/main/java/com/minelittlepony/client/render/IPonyRenderContext.java +++ b/src/main/java/com/minelittlepony/client/render/IPonyRenderContext.java @@ -4,9 +4,9 @@ import com.minelittlepony.api.pony.IPony; import com.minelittlepony.api.pony.meta.Wearable; import com.minelittlepony.client.model.IPonyModel; import com.minelittlepony.client.model.ModelWrapper; -import com.minelittlepony.client.model.gear.IRenderContext; import com.minelittlepony.model.BodyPart; import com.minelittlepony.model.PonyModelConstants; +import com.minelittlepony.model.gear.IRenderContext; import com.minelittlepony.util.MathUtil; import net.minecraft.client.render.entity.model.EntityModel; diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/GearFeature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/GearFeature.java index a3f19ea0..bfc8f2be 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/GearFeature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/feature/GearFeature.java @@ -8,6 +8,7 @@ import net.minecraft.client.render.entity.model.EntityModel; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.LivingEntity; +import com.google.common.collect.Streams; import com.minelittlepony.api.pony.meta.Wearable; import com.minelittlepony.client.model.IPonyModel; import com.minelittlepony.client.model.ModelType; @@ -16,21 +17,27 @@ import com.minelittlepony.model.BodyPart; import com.minelittlepony.model.gear.IGear; import com.minelittlepony.model.gear.IStackable; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.stream.Collectors; public class GearFeature & IPonyModel> extends AbstractPonyFeature { - private final Map gears; + private static final List MOD_GEARS = new ArrayList<>(); + + public static IGear addModGear(IGear gear) { + MOD_GEARS.add(new Entry(gear, Wearable.NONE)); + return gear; + } + + private final List gears; public GearFeature(IPonyRenderContext renderer) { super(renderer); - gears = ModelType.getWearables().collect(Collectors.toMap( - Map.Entry::getKey, - e -> e.getValue().createModel() - )); + gears = Streams.concat(ModelType.getWearables().map(e -> new Entry(e.getValue().createModel(), e.getKey())), MOD_GEARS.stream()).collect(Collectors.toList()); } @Override @@ -40,21 +47,20 @@ public class GearFeature & IPon return; } - M model = getModelWrapper().getBody(); + final M model = getModelWrapper().getBody(); - Map renderStackingOffsets = new HashMap<>(); + final Map renderStackingOffsets = new HashMap<>(); - for (Map.Entry entry : gears.entrySet()) { - Wearable wearable = entry.getKey(); - IGear gear = entry.getValue(); + for (Entry entry : gears) { + final IGear gear = entry.gear; - if (getContext().shouldRender(model, entity, wearable, gear)) { + if (getContext().shouldRender(model, entity, entry.wearable, gear)) { stack.push(); - model.transform(gear.getGearLocation(), stack); - model.getBodyPart(gear.getGearLocation()).rotate(stack); + BodyPart part = gear.getGearLocation(); + model.transform(part, stack); + model.getBodyPart(part).rotate(stack); if (gear instanceof IStackable) { - BodyPart part = gear.getGearLocation(); renderStackingOffsets.compute(part, (k, v) -> { float offset = ((IStackable)gear).getStackingOffset(); if (v != null) { @@ -73,12 +79,22 @@ public class GearFeature & IPon private void renderGear(M model, T entity, IGear gear, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, float limbDistance, float limbAngle, float tickDelta) { - gear.setLivingAnimations(model, entity); - gear.setRotationAndAngles(model.getAttributes().isGoingFast, entity.getUuid(), limbDistance, limbAngle, model.getWobbleAmount(), tickDelta); + gear.setModelAttributes(model, entity); + gear.pose(model.getAttributes().isGoingFast, entity.getUuid(), limbDistance, limbAngle, model.getWobbleAmount(), tickDelta); RenderLayer layer = RenderLayer.getEntityTranslucent(gear.getTexture(entity, getContext())); VertexConsumer vertexConsumer = renderContext.getBuffer(layer); - gear.renderPart(stack, vertexConsumer, lightUv, OverlayTexture.DEFAULT_UV, 1, 1, 1, 1, entity.getUuid()); + gear.render(stack, vertexConsumer, lightUv, OverlayTexture.DEFAULT_UV, 1, 1, 1, 1, entity.getUuid()); + } + + static class Entry { + IGear gear; + Wearable wearable; + + Entry(IGear gear, Wearable wearable) { + this.gear = gear; + this.wearable = wearable; + } } } diff --git a/src/main/java/com/minelittlepony/model/capabilities/IModelWrapper.java b/src/main/java/com/minelittlepony/model/IModelWrapper.java similarity index 81% rename from src/main/java/com/minelittlepony/model/capabilities/IModelWrapper.java rename to src/main/java/com/minelittlepony/model/IModelWrapper.java index 7a68c0cb..5e852472 100644 --- a/src/main/java/com/minelittlepony/model/capabilities/IModelWrapper.java +++ b/src/main/java/com/minelittlepony/model/IModelWrapper.java @@ -1,4 +1,4 @@ -package com.minelittlepony.model.capabilities; +package com.minelittlepony.model; import com.minelittlepony.api.pony.IPonyData; diff --git a/src/main/java/com/minelittlepony/model/armour/IEquestrianArmour.java b/src/main/java/com/minelittlepony/model/armour/IEquestrianArmour.java index f15fd821..2c087196 100644 --- a/src/main/java/com/minelittlepony/model/armour/IEquestrianArmour.java +++ b/src/main/java/com/minelittlepony/model/armour/IEquestrianArmour.java @@ -1,6 +1,6 @@ package com.minelittlepony.model.armour; -import com.minelittlepony.model.capabilities.IModelWrapper; +import com.minelittlepony.model.IModelWrapper; public interface IEquestrianArmour extends IModelWrapper { /** diff --git a/src/main/java/com/minelittlepony/model/capabilities/fabric/package-info.java b/src/main/java/com/minelittlepony/model/capabilities/fabric/package-info.java deleted file mode 100644 index fc6d010f..00000000 --- a/src/main/java/com/minelittlepony/model/capabilities/fabric/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -@ParametersAreNonnullByDefault -package com.minelittlepony.model.capabilities.fabric; - -import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/com/minelittlepony/model/capabilities/fabric/PonyModelPrepareCallback.java b/src/main/java/com/minelittlepony/model/fabric/PonyModelPrepareCallback.java similarity index 92% rename from src/main/java/com/minelittlepony/model/capabilities/fabric/PonyModelPrepareCallback.java rename to src/main/java/com/minelittlepony/model/fabric/PonyModelPrepareCallback.java index 95e849b5..1a2c0eb3 100644 --- a/src/main/java/com/minelittlepony/model/capabilities/fabric/PonyModelPrepareCallback.java +++ b/src/main/java/com/minelittlepony/model/fabric/PonyModelPrepareCallback.java @@ -1,4 +1,4 @@ -package com.minelittlepony.model.capabilities.fabric; +package com.minelittlepony.model.fabric; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; diff --git a/src/main/java/com/minelittlepony/model/capabilities/package-info.java b/src/main/java/com/minelittlepony/model/fabric/package-info.java similarity index 64% rename from src/main/java/com/minelittlepony/model/capabilities/package-info.java rename to src/main/java/com/minelittlepony/model/fabric/package-info.java index d1b0bb02..c8133dbc 100644 --- a/src/main/java/com/minelittlepony/model/capabilities/package-info.java +++ b/src/main/java/com/minelittlepony/model/fabric/package-info.java @@ -1,4 +1,4 @@ @ParametersAreNonnullByDefault -package com.minelittlepony.model.capabilities; +package com.minelittlepony.model.fabric; import javax.annotation.ParametersAreNonnullByDefault; diff --git a/src/main/java/com/minelittlepony/model/gear/IGear.java b/src/main/java/com/minelittlepony/model/gear/IGear.java index 77f8bcb1..5e1c8826 100644 --- a/src/main/java/com/minelittlepony/model/gear/IGear.java +++ b/src/main/java/com/minelittlepony/model/gear/IGear.java @@ -1,14 +1,30 @@ package com.minelittlepony.model.gear; +import net.minecraft.client.render.RenderLayer; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.Entity; import net.minecraft.util.Identifier; -import com.minelittlepony.client.model.gear.IRenderContext; +import com.minelittlepony.client.render.entity.feature.GearFeature; import com.minelittlepony.model.BodyPart; import com.minelittlepony.model.IModel; -import com.minelittlepony.model.IPart; -public interface IGear extends IPart { +import java.util.UUID; + +/** + * Interface for an accessory on a pony's body. + */ +public interface IGear { + /** + * Registers a custom gear to be used with the mod. + *

+ * This would be awesome for creating socks. + */ + static IGear addModGear(IGear gear) { + GearFeature.addModGear(gear); + return gear; + } /** * Determines if this wearable can and is worn by the selected entity. @@ -27,14 +43,39 @@ public interface IGear extends IPart { /** * Gets the texture to use for this wearable. - * Return null to use the same as the primary model. + * + * If you need to use the player's own skin, use {@link IRenderContext#getDefaultTexture(entity, wearable)} */ Identifier getTexture(T entity, IRenderContext context); + default RenderLayer getLayer(T entity, IRenderContext context) { + return RenderLayer.getEntityTranslucent(getTexture(entity, context)); + } + /** * Orients this wearable. */ - default void setLivingAnimations(IModel model, Entity entity) { + default void setModelAttributes(IModel model, Entity entity) { + + } + /** + * Sets the model's various rotation angles. + * + * See {@link AbstractPonyMode.setRotationAndAngle} for an explanation of the various parameters. + */ + default void pose(boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) { + + } + + /** + * Renders this model component. + */ + void render(MatrixStack stack, VertexConsumer vertices, int overlayUv, int lightUv, float red, float green, float blue, float alpha, UUID interpolatorId); + + /** + * Sets whether this part should be rendered. + */ + default void setVisible(boolean visible) { } } diff --git a/src/main/java/com/minelittlepony/model/gear/IRenderContext.java b/src/main/java/com/minelittlepony/model/gear/IRenderContext.java new file mode 100644 index 00000000..78babe8d --- /dev/null +++ b/src/main/java/com/minelittlepony/model/gear/IRenderContext.java @@ -0,0 +1,41 @@ +package com.minelittlepony.model.gear; + +import net.minecraft.entity.Entity; +import net.minecraft.util.Identifier; + +import com.minelittlepony.api.pony.meta.Wearable; +import com.minelittlepony.model.IModel; + +import javax.annotation.Nullable; + +/** + * A render context for instance of IGear. + * + * @param The type of entity being rendered. + * @param The type of the entity's primary model. + */ +public interface IRenderContext { + /** + * The empty context. + */ + IRenderContext NULL = (e, g) -> null; + + /** + * Checks whether the given wearable and gear are able to render for this specific entity and its renderer. + */ + default boolean shouldRender(M model, T entity, Wearable wearable, IGear gear) { + return gear.canRender(model, entity); + } + + @Nullable + default M getEntityModel() { + return null; + } + + /** + * Gets the default texture to use for this entity and wearable. + * + * May be the entity's own texture or a specific texture allocated for that wearable. + */ + Identifier getDefaultTexture(T entity, Wearable wearable); +}