Merge branch '1.21.3' into 1.21.4

This commit is contained in:
Sollace 2024-12-16 22:58:00 +01:00
commit 808797689e
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
20 changed files with 81 additions and 90 deletions

View file

@ -145,6 +145,7 @@ public class ModelAttributes {
isGoingFast &= zMotion > 0.4F;
isGoingFast |= entity.isUsingRiptide();
isGoingFast |= entity.isGliding();
isGoingFast &= !entity.isSpectator();
motionLerp = MathUtil.clampLimit(zMotion * 30, 1);

View file

@ -4,15 +4,11 @@ import net.minecraft.client.render.entity.equipment.EquipmentModel;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Util;
import org.jetbrains.annotations.Nullable;
import com.minelittlepony.client.model.AbstractPonyModel;
import com.minelittlepony.client.model.PlayerModelKey;
import com.minelittlepony.client.model.armour.*;
import com.minelittlepony.mson.api.ModelKey;
import com.minelittlepony.mson.api.MsonModel;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
/**
@ -23,20 +19,15 @@ public record Models<M extends PonyModel<?>> (
M body
) {
public Models(PlayerModelKey<? super M> playerModelKey, boolean slimArms, @Nullable Consumer<M> initializer) {
this(Util.memoize(key -> key.createModel(playerModelKey.armorFactory())), playerModelKey.getKey(slimArms).createModel());
if (initializer != null) {
initializer.accept(body);
}
public Models(ModelKey<? super M> modelKey, MsonModel.Factory<AbstractPonyModel<?>> armorFactory) {
this(Util.memoize(key -> key.createModel(armorFactory)), modelKey.createModel());
}
public Models(ModelKey<M> key) {
public Models(ModelKey<? super M> key) {
this(Util.memoize(k -> k.createModel()), key.createModel());
}
public Optional<AbstractPonyModel<?>> getArmourModel(ItemStack stack, EquipmentModel.LayerType layerType, ArmourVariant variant) {
return ArmorModelRegistry.getModelKey(stack.getItem(), layerType)
.or(() -> variant.getDefaultModel(layerType))
.map(armor);
public AbstractPonyModel<?> getArmourModel(ItemStack stack, EquipmentModel.LayerType layerType, ArmourVariant variant) {
return armor.apply(ArmorModelRegistry.getModelKey(stack.getItem(), layerType, variant));
}
}

View file

@ -86,6 +86,7 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
protected void setModelVisibilities(T state) {
resetPivot(head, neck, leftArm, rightArm, leftLeg, rightLeg);
hat.visible = head.visible && !state.attributes.isHorsey;
neck.visible = body.visible;
if (state.attributes.isHorsey) {
neck.visible = head.visible;
} else {

View file

@ -3,8 +3,6 @@ package com.minelittlepony.client.model;
import net.minecraft.client.model.Model;
import net.minecraft.client.model.ModelPart;
import org.jetbrains.annotations.Nullable;
import com.minelittlepony.api.model.Models;
import com.minelittlepony.api.model.PonyModel;
import com.minelittlepony.client.MineLittlePony;
@ -28,15 +26,15 @@ public record PlayerModelKey<M extends Model & PonyModel<?>> (
);
}
public ModelKey<M> getKey(boolean slimArms) {
return slimArms ? alexKey : steveKey;
public <N extends M> Models<N> alex() {
return new Models<N>(alexKey, armorFactory);
}
public <N extends M> Models<N> create(boolean slimArms) {
return create(slimArms, null);
public <N extends M> Models<N> steve() {
return new Models<N>(steveKey, armorFactory);
}
public <N extends M> Models<N> create(boolean slimArms, @Nullable Consumer<N> initializer) {
return new Models<>(this, slimArms, initializer);
public <N extends M> Models<N> create(boolean slimArms) {
return slimArms ? alex() : steve();
}
}

View file

@ -2,25 +2,35 @@ package com.minelittlepony.client.model.armour;
import net.minecraft.item.Item;
import net.minecraft.client.render.entity.equipment.EquipmentModel;
import net.minecraft.registry.Registries;
import net.minecraft.util.Identifier;
import com.minelittlepony.client.model.AbstractPonyModel;
import com.minelittlepony.mson.api.ModelKey;
import com.minelittlepony.mson.api.Mson;
import com.minelittlepony.util.ResourceUtil;
import java.util.*;
public interface ArmorModelRegistry {
static final Map<Identifier, Optional<ModelKey<AbstractPonyModel<?>>>> REGISTRY = new HashMap<>();
public static Optional<ModelKey<AbstractPonyModel<?>>> getModelKey(Item item, EquipmentModel.LayerType layerType) {
Identifier id = Registries.ITEM.getId(item);
if (id.getNamespace().equals("minecraft")) {
return Optional.empty();
}
return REGISTRY.computeIfAbsent(id.withPath(p -> "armor/" + layerType.name().toLowerCase(Locale.ROOT) + "_" + p + ".json"), i -> {
return Optional.of(Mson.getInstance().registerModel(i, PonyArmourModel::new));
}).filter(key -> key.getModelData().isPresent());
@SuppressWarnings("deprecation")
public static ModelKey<AbstractPonyModel<?>> getModelKey(Item item, EquipmentModel.LayerType layerType, ArmourVariant variant) {
return item.getRegistryEntry().getKey().map(key -> key.getValue()).flatMap(id -> {
if (id.getNamespace().equals("minecraft")) {
return Optional.empty();
}
return REGISTRY.computeIfAbsent(id.withPath(p -> ResourceUtil.format("armor/%s_%s.json", layerName(layerType), p)), i -> {
return Optional.of(Mson.getInstance().registerModel(i, PonyArmourModel::new));
}).filter(key -> key.getModelData().isPresent());
}).orElse(variant.getDefaultModel(layerType));
}
private static String layerName(EquipmentModel.LayerType layerType) {
return switch (layerType) {
case HUMANOID -> "outer";
case HUMANOID_LEGGINGS -> "inner";
default -> layerType.name().toLowerCase(Locale.ROOT);
};
}
}

View file

@ -18,17 +18,22 @@ import java.util.stream.Stream;
/**
* The default texture resolver used by Mine Little Pony.
* <p>
* Textures found are of the format:
* Textures are resolved by taking the original path and replacing "humanoid" with "ponified".
* <p>
* namespace:textures/models/armor/material_layer_[outer|1|inner|2](_overlay)(_custom_#)(_pony).png
* <p>
* <p>
* - Textures ending _pony are returned first if found
* - _custom_# corresponds to a CustomModelData NBT integer value on the item passed, if available
* - _overlay is used for the second layer of leather armour, or mods if they make use of it. Can be anything! Check your mod's documentation for values supported.
* - outer|1|inner|2 is the layer. outer is an alias for 1 and inner is an alias for 2. Named versions are used instead of numbers if available.
* - the "minecraft" namespace is always replaced with "minelittlepony"
* For example:
*
* assets/minecraft/textures/entity/equipment/humanoid/iron.png
* Becomes: assets/minecraft/textures/entity/equipment/ponified/iron.png
*
* assets/minecraft/textures/entity/equipment/humanoid_leggings/iron.png
* Becomes: assets/minecraft/textures/entity/equipment/ponified_leggings/iron.png
* <p>
* In addition to the above, unlike in vanilla, all pony armour pieces make use of both the regular and leggings textures to show in two different layers.
* In general, the textures are distributed as follows:
* Helmet = ponified_leggings
* Chestplate = ponified (banner) + ponified_leggings (body plates)
* Leggings = ponified_leggings (leg chainmail)
* Boots = ponified (knee guards and boots)
*/
public class ArmourTextureResolver implements ArmourTextureLookup, IdentifiableResourceReloadListener {
public static final Identifier ID = MineLittlePony.id("armor_textures");

View file

@ -6,22 +6,20 @@ import com.minelittlepony.client.model.AbstractPonyModel;
import com.minelittlepony.client.model.ModelType;
import com.minelittlepony.mson.api.ModelKey;
import java.util.Optional;
public enum ArmourVariant {
NORMAL(ModelType.INNER_PONY_ARMOR, ModelType.OUTER_PONY_ARMOR),
LEGACY(ModelType.INNER_VANILLA_ARMOR, ModelType.OUTER_VANILLA_ARMOR),
TRIM(ModelType.INNER_VANILLA_ARMOR, ModelType.OUTER_VANILLA_ARMOR);
private final Optional<ModelKey<AbstractPonyModel<?>>> innerModel;
private final Optional<ModelKey<AbstractPonyModel<?>>> outerModel;
private final ModelKey<AbstractPonyModel<?>> innerModel;
private final ModelKey<AbstractPonyModel<?>> outerModel;
ArmourVariant(ModelKey<AbstractPonyModel<?>> inner, ModelKey<AbstractPonyModel<?>> outer) {
this.innerModel = Optional.of(inner);
this.outerModel = Optional.of(outer);
this.innerModel = inner;
this.outerModel = outer;
}
public Optional<ModelKey<AbstractPonyModel<?>>> getDefaultModel(EquipmentModel.LayerType layerType) {
public ModelKey<AbstractPonyModel<?>> getDefaultModel(EquipmentModel.LayerType layerType) {
return layerType == EquipmentModel.LayerType.HUMANOID_LEGGINGS ? innerModel : outerModel;
}
}

View file

@ -82,7 +82,7 @@ public class PonifiedEquipmentRenderer extends EquipmentRenderer {
VertexConsumer armorConsumer = getArmorVertexConsumer(plugin, equipmentSlot, vertices, layerTexture, layerType, hasGlint);
if (armorConsumer != null) {
ArmourVariant variant = layer.usePlayerTexture() ? ArmourVariant.LEGACY : armorTexture.variant();
AbstractPonyModel<?> model = models.getArmourModel(stack, layerType, variant).orElse(null);
AbstractPonyModel<?> model = models.getArmourModel(stack, layerType, variant);
if (model != null) {
model.setAngles(entity);
models.body().copyTransforms(model);

View file

@ -57,8 +57,8 @@ public class PonyEars implements SubModel<PonyRenderState>, MsonModel {
@Override
public void setVisible(boolean visible, PonyRenderState state) {
right.visible = visible && !state.race.isHuman();
left.visible = visible && !state.race.isHuman();
right.visible = !state.race.isHuman();
left.visible = !state.race.isHuman();
if (state.attributes.isHorsey) {
left.pivotX = -1;

View file

@ -39,7 +39,7 @@ public class PonySnout implements SubModel<PonyRenderState>, MsonModel {
@Override
public void setVisible(boolean visible, PonyRenderState state) {
visible &= !state.attributes.isHorsey
visible = !state.attributes.isHorsey
&& !state.attributes.metadata.race().isHuman()
&& PonyConfig.getInstance().snuzzles.get();
Gender gender = state.attributes.metadata.gender();

View file

@ -92,14 +92,16 @@ public class PonyTail implements SubModel<PonyRenderState>, MsonModel {
@Override
public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color) {
stack.push();
tail.rotate(stack);
if (tail.visible) {
stack.push();
tail.rotate(stack);
for (int i = 0; i < segments.size(); i++) {
segments.get(i).render(stack, vertices, i, overlay, light, color);
for (int i = 0; i < segments.size(); i++) {
segments.get(i).render(stack, vertices, i, overlay, light, color);
}
stack.pop();
}
stack.pop();
}
public static class Segment {

View file

@ -67,9 +67,8 @@ public class EquineRenderManager<
context.setModel(models.body());
}
@SuppressWarnings({"rawtypes", "unchecked"})
public EquineRenderManager(PonyRenderContext<T, S, M> context, Transformer<? super S> transformer, ModelKey<? super M> key) {
this(context, transformer, new Models(key));
this(context, transformer, new Models<>(key));
}
public void setModelsLookup(Function<Race, Models<M>> modelsLookup) {

View file

@ -62,7 +62,7 @@ public class PlayerPonySkull implements ISkull {
return false;
}
}
ponyHead = modelCache.computeIfAbsent(ModelType.getPlayerModel(race), key -> key.getKey(false).createModel());
ponyHead = modelCache.computeIfAbsent(ModelType.getPlayerModel(race), key -> key.steveKey().createModel());
state.pony = pony;
state.race = pony.race();
state.attributes.size = pony.size();

View file

@ -8,7 +8,6 @@ import com.minelittlepony.client.model.entity.EnderStallionModel;
import com.minelittlepony.client.render.entity.feature.GlowingEyesFeature;
import com.minelittlepony.client.render.entity.feature.HeldItemFeature;
import com.minelittlepony.client.render.entity.npc.textures.TextureSupplier;
import com.minelittlepony.client.render.entity.feature.GlowingEyesFeature.IGlowingRenderer;
import net.minecraft.block.BlockState;
import net.minecraft.client.item.ItemModelManager;
@ -26,7 +25,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.Random;
public class EnderStallionRenderer extends PonyRenderer<EndermanEntity, EnderStallionRenderer.State, EnderStallionModel> implements IGlowingRenderer {
public class EnderStallionRenderer extends PonyRenderer<EndermanEntity, EnderStallionRenderer.State, EnderStallionModel> {
public static final Identifier ENDERMAN = MineLittlePony.id("textures/entity/enderman/enderman_pony.png");
private static final Identifier EYES = MineLittlePony.id("textures/entity/enderman/enderman_pony_eyes.png");
@ -43,8 +42,7 @@ public class EnderStallionRenderer extends PonyRenderer<EndermanEntity, EnderSta
protected void addFeatures(EntityRendererFactory.Context context) {
addPonyFeature(createHeldItemFeature(context));
addPonyFeature(new StuckArrowsFeatureRenderer<EnderStallionModel>((PonyRenderer)this, context));
addPonyFeature(new GlowingEyesFeature<EnderStallionRenderer.State, EnderStallionModel>(this));
addPonyFeature(new GlowingEyesFeature<EnderStallionRenderer.State, EnderStallionModel>(this, EYES));
}
@Override
@ -89,11 +87,6 @@ public class EnderStallionRenderer extends PonyRenderer<EndermanEntity, EnderSta
super.render(entity, matrices, vertices, light);
}
@Override
public Identifier getEyeTexture() {
return EYES;
}
public class State extends SkeleponyRenderer.State {
public boolean angry;
@Nullable

View file

@ -17,6 +17,7 @@ import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.RotationAxis;
public class CapeFeature extends CapeFeatureRenderer {
@ -52,12 +53,9 @@ public class CapeFeature extends CapeFeatureRenderer {
rendered[0] = true;
matrices.translate(0, 0.34F, 0);
if (((PlayerPonyRenderState)player).getAttributes().isLyingDown) {
matrices.translate(0, -0.05F, 0);
}
model.transform((PlayerPonyRenderState)player, BodyPart.BODY, matrices);
model.getBodyPart(BodyPart.BODY).rotate(matrices);
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(85));
model.body.rotate(matrices);
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(85 - model.body.pitch * MathHelper.DEGREES_PER_RADIAN));
if (player.baby) {
matrices.scale(1.1F, 1.1F, 1.1F);
}

View file

@ -2,7 +2,6 @@ package com.minelittlepony.client.render.entity.feature;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.entity.feature.EyesFeatureRenderer;
import net.minecraft.client.render.entity.feature.FeatureRendererContext;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.util.Identifier;
@ -17,18 +16,13 @@ public class GlowingEyesFeature<
private final RenderLayer layer;
@SuppressWarnings({"rawtypes", "unchecked"})
public <V extends FeatureRendererContext & PonyRenderContext<?, S, M> & IGlowingRenderer> GlowingEyesFeature(V renderer) {
super(renderer);
layer = RenderLayer.getEyes(renderer.getEyeTexture());
public GlowingEyesFeature(PonyRenderContext<?, S, M> context, Identifier texture) {
super(context.upcast());
layer = RenderLayer.getEyes(texture);
}
@Override
public RenderLayer getEyesTexture() {
return layer;
}
public interface IGlowingRenderer {
Identifier getEyeTexture();
}
}

View file

@ -25,13 +25,10 @@ public class SkullFeature<
protected final ItemModelManager itemModelResolver;
private final HeadFeatureRenderer.HeadTransformation headTransformation;
private final boolean scaleForChild;
public SkullFeature(PonyRenderContext<?, S, M> context, ItemModelManager itemModelResolver, HeadFeatureRenderer.HeadTransformation headTransformation, boolean scaleForChild) {
super(context);
this.itemModelResolver = itemModelResolver;
this.headTransformation = headTransformation;
this.scaleForChild = scaleForChild;
}
@Override

View file

@ -5,6 +5,7 @@ import net.minecraft.entity.mob.MobEntity;
import net.minecraft.util.Identifier;
import net.minecraft.village.*;
import com.minelittlepony.api.model.Models;
import com.minelittlepony.api.model.gear.Gear;
import com.minelittlepony.api.pony.meta.Race;
import com.minelittlepony.api.pony.meta.Wearable;
@ -19,13 +20,15 @@ abstract class AbstractNpcRenderer<
private final NpcClothingFeature<T, S, ClientPonyModel<S>, AbstractNpcRenderer<T, S>> clothing;
public AbstractNpcRenderer(EntityRendererFactory.Context context, String type, TextureSupplier<T> textureSupplier, TextureSupplier<String> formatter) {
super(context, ModelType.getPlayerModel(Race.EARTH).getKey(false), SillyPonyTextureSupplier.create(textureSupplier, formatter));
super(context, ModelType.getPlayerModel(Race.EARTH).steveKey(), SillyPonyTextureSupplier.create(textureSupplier, formatter));
clothing = new NpcClothingFeature<>(this, type);
this.manager.setModelsLookup(race -> {
if (race.isHuman()) {
race = Race.EARTH;
}
return ModelType.getPlayerModel(race).create(false, this::initializeModel);
Models<ClientPonyModel<S>> models = ModelType.getPlayerModel(race).steve();
initializeModel(models.body());
return models;
});
addFeature(clothing);
}

View file

@ -15,7 +15,7 @@ public class TraderRenderer extends PonyRenderer<WanderingTraderEntity, PonyRend
public static final Identifier TEXTURE = MineLittlePony.id("textures/entity/wandering_trader_pony.png");
public TraderRenderer(EntityRendererFactory.Context context) {
super(context, ModelType.ALICORN.getKey(false), TextureSupplier.of(TEXTURE), BASE_MODEL_SCALE);
super(context, ModelType.ALICORN.steveKey(), TextureSupplier.of(TEXTURE), BASE_MODEL_SCALE);
}
@Override

View file

@ -23,6 +23,7 @@ public interface MathUtil {
return value;
}
@Deprecated(forRemoval = true)
static float interpolateDegress(float prev, float current, float partialTicks) {
float difference = current - prev;