WIP Update to 1.21.3

This commit is contained in:
Sollace 2024-11-21 20:40:51 +00:00
parent 98abb4f384
commit 1464b3318a
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
42 changed files with 310 additions and 320 deletions

View file

@ -34,7 +34,8 @@ public record Models<M extends PonyModel<?>> (
} }
public Optional<PonyArmourModel<?>> getArmourModel(ItemStack stack, ArmourLayer layer, ArmourVariant variant) { public Optional<PonyArmourModel<?>> getArmourModel(ItemStack stack, ArmourLayer layer, ArmourVariant variant) {
return ArmorModelRegistry.getModelKey(stack.getItem(), layer).or(() -> variant.getDefaultModel(layer).filter(l -> stack.getItem() instanceof ArmorItem)) return ArmorModelRegistry.getModelKey(stack.getItem(), layer)
.or(() -> variant.getDefaultModel(layer).filter(l -> stack.getItem() instanceof ArmorItem))
.map(armor); .map(armor);
} }
} }

View file

@ -14,8 +14,8 @@ import static com.minelittlepony.common.event.SkinFilterCallback.copy;
*/ */
class LegacySkinConverter implements SkinFilterCallback { class LegacySkinConverter implements SkinFilterCallback {
@Override @Override
public void processImage(NativeImage image, boolean legacy) { public NativeImage processImage(NativeImage image, int initialWidth, int initialHeight) {
if (legacy) { if (SkinFilterCallback.isLegacyAspectRatio(initialWidth, initialHeight)) {
// ( from ) ( offset ) (size) flipX flipY // ( from ) ( offset ) (size) flipX flipY
copy(image, 58, 16, 0, 16, 2, 2, true, false); // top copy(image, 58, 16, 0, 16, 2, 2, true, false); // top
copy(image, 60, 16, 0, 16, 2, 2, true, false); // bottom copy(image, 60, 16, 0, 16, 2, 2, true, false); // bottom
@ -24,5 +24,7 @@ class LegacySkinConverter implements SkinFilterCallback {
copy(image, 56, 18, 4, 16, 2, 14, true, false); // outside copy(image, 56, 18, 4, 16, 2, 14, true, false); // outside
copy(image, 62, 18, 0, 16, 2, 14, true, false); // front copy(image, 62, 18, 0, 16, 2, 14, true, false); // front
} }
return image;
} }
} }

View file

@ -1,7 +1,6 @@
package com.minelittlepony.client.model; package com.minelittlepony.client.model;
import com.minelittlepony.api.model.*; import com.minelittlepony.api.model.*;
import com.minelittlepony.api.events.PonyModelPrepareCallback;
import com.minelittlepony.api.pony.meta.SizePreset; import com.minelittlepony.api.pony.meta.SizePreset;
import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.client.render.entity.state.PonyRenderState;
import com.minelittlepony.client.transform.PonyTransformation; import com.minelittlepony.client.transform.PonyTransformation;
@ -15,12 +14,9 @@ import java.util.function.Supplier;
import net.minecraft.client.model.ModelPart; import net.minecraft.client.model.ModelPart;
import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.entity.PlayerEntityRenderer;
import net.minecraft.client.render.entity.state.BipedEntityRenderState;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState; import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.EntityPose; import net.minecraft.entity.EntityPose;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.consume.UseAction; import net.minecraft.item.consume.UseAction;
import net.minecraft.util.*; import net.minecraft.util.*;
import net.minecraft.util.math.*; import net.minecraft.util.math.*;

View file

@ -58,7 +58,7 @@ public final class ModelType {
public static final GearModelKey<SaddleBags> SADDLEBAGS_BOTH = registerGear("saddlebags", Wearable.SADDLE_BAGS_BOTH, t -> new SaddleBags(t, Wearable.SADDLE_BAGS_BOTH)); public static final GearModelKey<SaddleBags> SADDLEBAGS_BOTH = registerGear("saddlebags", Wearable.SADDLE_BAGS_BOTH, t -> new SaddleBags(t, Wearable.SADDLE_BAGS_BOTH));
public static final GearModelKey<SaddleBags> SADDLEBAGS_LEFT = registerGear(SADDLEBAGS_BOTH, Wearable.SADDLE_BAGS_LEFT, t -> new SaddleBags(t, Wearable.SADDLE_BAGS_LEFT)); public static final GearModelKey<SaddleBags> SADDLEBAGS_LEFT = registerGear(SADDLEBAGS_BOTH, Wearable.SADDLE_BAGS_LEFT, t -> new SaddleBags(t, Wearable.SADDLE_BAGS_LEFT));
public static final GearModelKey<SaddleBags> SADDLEBAGS_RIGHT = registerGear(SADDLEBAGS_BOTH, Wearable.SADDLE_BAGS_RIGHT, t -> new SaddleBags(t, Wearable.SADDLE_BAGS_RIGHT)); public static final GearModelKey<SaddleBags> SADDLEBAGS_RIGHT = registerGear(SADDLEBAGS_BOTH, Wearable.SADDLE_BAGS_RIGHT, t -> new SaddleBags(t, Wearable.SADDLE_BAGS_RIGHT));
public static final GearModelKey<Crown> CROWN = registerGear("crown", Wearable.CROWN, Crown::new); public static final GearModelKey<AbstractGearModel> CROWN = registerGear("crown", Wearable.CROWN, t -> new WearableGear(t.getChild("crown"), Wearable.CROWN, BodyPart.HEAD, 0.1F));
public static final GearModelKey<AbstractGearModel> MUFFIN = registerGear("muffin", Wearable.MUFFIN, t -> new WearableGear(t.getChild("crown"), Wearable.MUFFIN, BodyPart.HEAD, 0.45F)); public static final GearModelKey<AbstractGearModel> MUFFIN = registerGear("muffin", Wearable.MUFFIN, t -> new WearableGear(t.getChild("crown"), Wearable.MUFFIN, BodyPart.HEAD, 0.45F));
public static final GearModelKey<AbstractGearModel> WITCH_HAT = registerGear("witch_hat", Wearable.HAT, t -> new WearableGear(t.getChild("hat"), Wearable.HAT, BodyPart.HEAD, 0.7F)); public static final GearModelKey<AbstractGearModel> WITCH_HAT = registerGear("witch_hat", Wearable.HAT, t -> new WearableGear(t.getChild("hat"), Wearable.HAT, BodyPart.HEAD, 0.7F));
public static final GearModelKey<DeerAntlers> ANTLERS = registerGear("antlers", Wearable.ANTLERS, DeerAntlers::new); public static final GearModelKey<DeerAntlers> ANTLERS = registerGear("antlers", Wearable.ANTLERS, DeerAntlers::new);

View file

@ -11,7 +11,6 @@ import net.minecraft.client.texture.SpriteAtlasTexture;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.component.type.DyedColorComponent; import net.minecraft.component.type.DyedColorComponent;
import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.*; import net.minecraft.item.*;
import net.minecraft.item.equipment.EquipmentModel; import net.minecraft.item.equipment.EquipmentModel;
import net.minecraft.item.equipment.EquipmentModel.LayerType; import net.minecraft.item.equipment.EquipmentModel.LayerType;
@ -108,15 +107,15 @@ public interface ArmourRendererPlugin {
} }
@Nullable @Nullable
default VertexConsumer getCapeConsumer(LivingEntity entity, VertexConsumerProvider provider, Identifier texture) { default VertexConsumer getCapeConsumer(BipedEntityRenderState entity, VertexConsumerProvider provider, Identifier texture) {
if (entity.getEquippedStack(EquipmentSlot.CHEST).isOf(Items.ELYTRA)) { if (entity.equippedChestStack.isOf(Items.ELYTRA)) {
return null; return null;
} }
return getOptionalBuffer(provider, getCapeLayer(entity, texture)); return getOptionalBuffer(provider, getCapeLayer(entity, texture));
} }
@Nullable @Nullable
default RenderLayer getCapeLayer(LivingEntity entity, Identifier texture) { default RenderLayer getCapeLayer(BipedEntityRenderState entity, Identifier texture) {
return RenderLayer.getEntitySolid(texture); return RenderLayer.getEntitySolid(texture);
} }

View file

@ -71,7 +71,8 @@ public class PonifiedEquipmentRenderer extends EquipmentRenderer {
for (EquipmentModel.Layer layer : layers) { for (EquipmentModel.Layer layer : layers) {
int j = getDyeColor(layer, i); int j = getDyeColor(layer, i);
if (j != 0) { if (j != 0) {
ArmourTexture armorTexture = plugin.getTextureLookup().getTexture(stack, layerType == LayerType.HUMANOID_LEGGINGS ? ArmourLayer.INNER : ArmourLayer.OUTER, layer); ArmourLayer armourLayer = layerType == LayerType.HUMANOID_LEGGINGS ? ArmourLayer.INNER : ArmourLayer.OUTER;
ArmourTexture armorTexture = plugin.getTextureLookup().getTexture(stack, armourLayer, layer);
Identifier layerTexture = layer.usePlayerTexture() && texture != null Identifier layerTexture = layer.usePlayerTexture() && texture != null
? texture ? texture
: armorTexture.texture(); : armorTexture.texture();
@ -81,7 +82,9 @@ public class PonifiedEquipmentRenderer extends EquipmentRenderer {
ArmourVariant variant = layer.usePlayerTexture() ? ArmourVariant.NORMAL : armorTexture.variant(); ArmourVariant variant = layer.usePlayerTexture() ? ArmourVariant.NORMAL : armorTexture.variant();
models.getArmourModel(stack, null, variant).ifPresent(model -> { models.getArmourModel(stack, null, variant).ifPresent(model -> {
VertexConsumer glintConsumer = hasGlint ? plugin.getGlintConsumer(equipmentSlot, vertexConsumers, layerType) : null; VertexConsumer glintConsumer = hasGlint ? plugin.getGlintConsumer(equipmentSlot, vertexConsumers, layerType) : null;
if (model.poseModel(equipmentSlot, armourLayer, models.body())) {
model.render(matrices, glintConsumer != null ? VertexConsumers.union(plugin.getGlintConsumer(equipmentSlot, vertexConsumers, layerType), armorConsumer) : armorConsumer, light, OverlayTexture.DEFAULT_UV, j); model.render(matrices, glintConsumer != null ? VertexConsumers.union(plugin.getGlintConsumer(equipmentSlot, vertexConsumers, layerType), armorConsumer) : armorConsumer, light, OverlayTexture.DEFAULT_UV, j);
}
}); });
} }
} }

View file

@ -1,7 +1,6 @@
package com.minelittlepony.client.model.armour; 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.entity.EquipmentSlot; import net.minecraft.entity.EquipmentSlot;
import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.api.model.PonyModel;
@ -14,21 +13,12 @@ public class PonyArmourModel<S extends PonyRenderState> extends AbstractPonyMode
super(tree, false); super(tree, false);
} }
public boolean poseModel(S state, public boolean poseModel(EquipmentSlot slot, ArmourLayer layer, PonyModel<?> mainModel) {
EquipmentSlot slot, ArmourLayer layer,
PonyModel<S> mainModel) {
if (!setVisibilities(slot, layer)) { if (!setVisibilities(slot, layer)) {
return false; return false;
} }
setAngles(state); if (mainModel instanceof AbstractPonyModel abs) {
if (mainModel instanceof BipedEntityModel<?> biped) { abs.copyTransforms(this);
head.copyTransform(biped.head);
body.copyTransform(biped.body);
rightArm.copyTransform(biped.rightArm);
leftArm.copyTransform(biped.leftArm);
rightLeg.copyTransform(biped.rightLeg);
leftLeg.copyTransform(biped.leftLeg);
} }
return true; return true;
} }

View file

@ -21,9 +21,9 @@ public class EnderStallionModel extends SkeleponyModel<EnderStallionRenderer.Sta
@Override @Override
protected void setModelVisibilities(EnderStallionRenderer.State state) { protected void setModelVisibilities(EnderStallionRenderer.State state) {
super.setModelVisibilities(state); super.setModelVisibilities(state);
tail.setVisible(false, state.attributes); tail.setVisible(false, state);
snout.setVisible(false, state.attributes); snout.setVisible(false, state);
horn.setVisible(!state.isBoss, state.attributes); horn.setVisible(!state.isBoss, state);
leftHorn.visible = rightHorn.visible = state.isBoss; leftHorn.visible = rightHorn.visible = state.isBoss;
} }

View file

@ -24,7 +24,7 @@ public class UnicornModel<T extends PonyRenderState> extends EarthPonyModel<T> i
protected final ModelPart unicornArmRight; protected final ModelPart unicornArmRight;
protected final ModelPart unicornArmLeft; protected final ModelPart unicornArmLeft;
protected UnicornHorn horn; protected UnicornHorn<T> horn;
public UnicornModel(ModelPart tree, boolean smallArms) { public UnicornModel(ModelPart tree, boolean smallArms) {
super(tree, smallArms); super(tree, smallArms);

View file

@ -1,31 +0,0 @@
package com.minelittlepony.client.model.gear;
import net.minecraft.client.model.ModelPart;
import net.minecraft.client.render.entity.state.EntityRenderState;
import net.minecraft.entity.Entity;
import net.minecraft.entity.mob.AbstractPiglinEntity;
import net.minecraft.entity.mob.ZombifiedPiglinEntity;
import net.minecraft.entity.player.PlayerEntity;
import com.minelittlepony.api.model.BodyPart;
import com.minelittlepony.api.model.PonyModel;
import com.minelittlepony.api.model.gear.WearableGear;
import com.minelittlepony.api.pony.meta.Wearable;
public class Crown extends WearableGear {
public Crown(ModelPart tree) {
super(tree.getChild("crown"), Wearable.CROWN, BodyPart.HEAD, 0.1F);
}
@Override
public boolean canRender(PonyModel<?> model, EntityRenderState entity) {
return super.canRender(model, entity)
|| ((
entity instanceof AbstractPiglinEntity
|| entity instanceof PlayerEntity
|| entity instanceof ZombifiedPiglinEntity
) && entity.hasCustomName() && entity.getCustomName().getString().equalsIgnoreCase("technoblade")
);
}
}

View file

@ -11,7 +11,7 @@ import com.minelittlepony.api.model.SubModel;
import com.minelittlepony.client.render.MagicGlow; import com.minelittlepony.client.render.MagicGlow;
import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.client.render.entity.state.PonyRenderState;
public class UnicornHorn implements SubModel<PonyRenderState> { public class UnicornHorn<T extends PonyRenderState> implements SubModel<T> {
private final ModelPart horn; private final ModelPart horn;
private final ModelPart glow; private final ModelPart glow;
@ -38,8 +38,8 @@ public class UnicornHorn implements SubModel<PonyRenderState> {
} }
@Override @Override
public void setVisible(boolean visible, PonyRenderState state) { public void setVisible(boolean visible, T state) {
horn.visible = visible; horn.visible = this.visible && visible;
glow.visible = visible; glow.visible = this.visible && visible;
} }
} }

View file

@ -7,6 +7,7 @@ import com.minelittlepony.api.model.*;
import com.minelittlepony.api.pony.Pony; import com.minelittlepony.api.pony.Pony;
import com.minelittlepony.api.pony.PonyData; import com.minelittlepony.api.pony.PonyData;
import com.minelittlepony.client.PonyDataLoader; import com.minelittlepony.client.PonyDataLoader;
import com.minelittlepony.client.model.ClientPonyModel;
import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.client.render.entity.state.PonyRenderState;
import com.minelittlepony.client.transform.PonyPosture; import com.minelittlepony.client.transform.PonyPosture;
import com.minelittlepony.mson.api.ModelKey; import com.minelittlepony.mson.api.ModelKey;
@ -30,7 +31,7 @@ import org.jetbrains.annotations.Nullable;
public class EquineRenderManager< public class EquineRenderManager<
T extends LivingEntity, T extends LivingEntity,
S extends PonyRenderState, S extends PonyRenderState,
M extends EntityModel<? super S> & PonyModel<S>> { M extends ClientPonyModel<S>> {
private Models<M> models; private Models<M> models;
@ -39,7 +40,9 @@ public class EquineRenderManager<
private final PonyRenderContext<T, S, M> context; private final PonyRenderContext<T, S, M> context;
private final Transformer<? super S> transformer; private final Transformer<? super S> transformer;
private final FrustrumCheck<T> frustrum; private final FrustrumCheck<S> frustrum = new FrustrumCheck<>();
private final MinecraftClient client = MinecraftClient.getInstance();
public static void disableModelRenderProfile() { public static void disableModelRenderProfile() {
RenderSystem.disableBlend(); RenderSystem.disableBlend();
@ -49,7 +52,6 @@ public class EquineRenderManager<
this.context = context; this.context = context;
this.transformer = transformer; this.transformer = transformer;
this.models = models; this.models = models;
frustrum = new FrustrumCheck<>(context);
context.setModel(models.body()); context.setModel(models.body());
} }
@ -74,7 +76,8 @@ public class EquineRenderManager<
if (entity.isSleeping() || !PonyConfig.getInstance().frustrum.get()) { if (entity.isSleeping() || !PonyConfig.getInstance().frustrum.get()) {
return vanilla; return vanilla;
} }
return frustrum.withCamera(entity, vanilla);
return frustrum.withCamera(context.getVanillaRenderer().getAndUpdateRenderState(entity, client.getRenderTickCounter().getTickDelta(false)), vanilla);
} }
public void updateState(T entity, S state, ModelAttributes.Mode mode) { public void updateState(T entity, S state, ModelAttributes.Mode mode) {

View file

@ -1,14 +1,13 @@
package com.minelittlepony.client.render; package com.minelittlepony.client.render;
import net.minecraft.client.render.Frustum; import net.minecraft.client.render.Frustum;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.math.Box; import net.minecraft.util.math.Box;
import org.joml.Matrix4f; import org.joml.Matrix4f;
import com.minelittlepony.client.PonyBounds; import com.minelittlepony.client.render.entity.state.PonyRenderState;
public class FrustrumCheck<T extends LivingEntity> extends Frustum { public class FrustrumCheck<T extends PonyRenderState> extends Frustum {
public static final Frustum ALWAYS_VISIBLE = new Frustum(new Matrix4f(), new Matrix4f()) { public static final Frustum ALWAYS_VISIBLE = new Frustum(new Matrix4f(), new Matrix4f()) {
public boolean isVisible(Box bounds) { public boolean isVisible(Box bounds) {
return true; return true;
@ -19,11 +18,8 @@ public class FrustrumCheck<T extends LivingEntity> extends Frustum {
private Frustum vanilla; private Frustum vanilla;
private final PonyRenderContext<T, ?, ?> context; public FrustrumCheck() {
public FrustrumCheck(PonyRenderContext<T, ?, ?> context) {
super(new Matrix4f(), new Matrix4f()); super(new Matrix4f(), new Matrix4f());
this.context = context;
} }
public Frustum withCamera(T entity, Frustum vanillaFrustrum) { public Frustum withCamera(T entity, Frustum vanillaFrustrum) {
@ -34,7 +30,7 @@ public class FrustrumCheck<T extends LivingEntity> extends Frustum {
@Override @Override
public boolean isVisible(Box bounds) { public boolean isVisible(Box bounds) {
return vanilla.isVisible(PonyBounds.getBoundingBox(context.getEntityPony(entity), entity)); return vanilla.isVisible(DebugBoundingBoxRenderer.getBoundingBox(entity));
} }
@Override @Override

View file

@ -1,17 +1,14 @@
package com.minelittlepony.client.render; package com.minelittlepony.client.render;
import com.minelittlepony.api.config.PonyConfig; import com.minelittlepony.api.config.PonyConfig;
import com.minelittlepony.api.model.HornedPonyModel;
import com.minelittlepony.api.pony.Pony; import com.minelittlepony.api.pony.Pony;
import com.minelittlepony.client.MineLittlePony; import com.minelittlepony.client.MineLittlePony;
import com.minelittlepony.client.render.entity.state.PonyRenderState;
import com.minelittlepony.common.util.render.RenderLayerUtil; import com.minelittlepony.common.util.render.RenderLayerUtil;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.*; import net.minecraft.client.render.*;
import net.minecraft.client.render.entity.LivingEntityRenderer;
import net.minecraft.client.render.item.ItemRenderer; import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.component.DataComponentTypes; import net.minecraft.component.DataComponentTypes;
@ -110,8 +107,7 @@ public class LevitatingItemRenderer {
action == UseAction.BOW action == UseAction.BOW
|| action == UseAction.CROSSBOW || action == UseAction.CROSSBOW
|| action == UseAction.BLOCK || action == UseAction.BLOCK
|| item.getItem() instanceof ToolItem || item.contains(DataComponentTypes.TOOL)
|| item.getItem() instanceof RangedWeaponItem
|| PonyConfig.getInstance().forwardHoldingItems.get().contains(Registries.ITEM.getId(item.getItem())); || PonyConfig.getInstance().forwardHoldingItems.get().contains(Registries.ITEM.getId(item.getItem()));
float distanceChange = handHeldTool ? -0.3F : -0.6F; float distanceChange = handHeldTool ? -0.3F : -0.6F;

View file

@ -1,17 +1,22 @@
package com.minelittlepony.client.render; package com.minelittlepony.client.render;
import com.minelittlepony.api.model.PonyModel;
import com.minelittlepony.api.model.gear.Gear; import com.minelittlepony.api.model.gear.Gear;
import com.minelittlepony.api.pony.Pony; import com.minelittlepony.api.pony.Pony;
import com.minelittlepony.client.model.ClientPonyModel;
import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.client.render.entity.state.PonyRenderState;
import net.minecraft.client.render.entity.EntityRenderer;
import net.minecraft.client.render.entity.feature.FeatureRendererContext;
import net.minecraft.client.render.entity.model.EntityModel; import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.client.render.entity.state.EntityRenderState;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import org.jetbrains.annotations.Nullable;
public interface PonyRenderContext< public interface PonyRenderContext<
T extends LivingEntity, T extends LivingEntity,
S extends PonyRenderState, S extends PonyRenderState,
M extends EntityModel<? super S> & PonyModel<S> M extends ClientPonyModel<S>
> extends Gear.Context<S, M> { > extends Gear.Context<S, M> {
Pony getEntityPony(T entity); Pony getEntityPony(T entity);
@ -19,4 +24,15 @@ public interface PonyRenderContext<
EquineRenderManager<T, S, M> getInternalRenderer(); EquineRenderManager<T, S, M> getInternalRenderer();
void setModel(M model); void setModel(M model);
@Nullable
@SuppressWarnings("unchecked")
default EntityRenderer<T, S> getVanillaRenderer() {
return this instanceof EntityRenderer ? (EntityRenderer<T, S>)(Object)this : null;
}
@SuppressWarnings("unchecked")
default <S2 extends EntityRenderState, M2 extends EntityModel<? super S2>> FeatureRendererContext<S2, M2> upcast() {
return (FeatureRendererContext<S2, M2>)this;
}
} }

View file

@ -3,10 +3,10 @@ package com.minelittlepony.client.render;
import java.util.function.Function; import java.util.function.Function;
import com.google.common.base.Predicates; import com.google.common.base.Predicates;
import com.minelittlepony.api.model.PonyModel;
import com.minelittlepony.api.model.PreviewModel; import com.minelittlepony.api.model.PreviewModel;
import com.minelittlepony.api.pony.*; import com.minelittlepony.api.pony.*;
import com.minelittlepony.client.mixin.MixinEntityRenderers; import com.minelittlepony.client.mixin.MixinEntityRenderers;
import com.minelittlepony.client.model.ClientPonyModel;
import com.minelittlepony.client.render.entity.*; import com.minelittlepony.client.render.entity.*;
import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.client.render.entity.state.PonyRenderState;
@ -16,7 +16,6 @@ import com.minelittlepony.mson.api.Mson;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.entity.*; import net.minecraft.client.render.entity.*;
import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.client.render.entity.state.EntityRenderState; import net.minecraft.client.render.entity.state.EntityRenderState;
import net.minecraft.client.util.SkinTextures; import net.minecraft.client.util.SkinTextures;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
@ -80,7 +79,7 @@ public class PonyRenderDispatcher {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Nullable @Nullable
public <T extends LivingEntity, S extends PonyRenderState, M extends EntityModel<S> & PonyModel<S>, R extends LivingEntityRenderer<T, S, M> & PonyRenderContext<T, S, M>> R getPonyRenderer(@Nullable T entity) { public <T extends LivingEntity, S extends PonyRenderState, M extends ClientPonyModel<S>, R extends LivingEntityRenderer<T, S, M> & PonyRenderContext<T, S, M>> R getPonyRenderer(@Nullable T entity) {
if (entity != null && MinecraftClient.getInstance().getEntityRenderDispatcher().getRenderer(entity) instanceof PonyRenderContext c) { if (entity != null && MinecraftClient.getInstance().getEntityRenderDispatcher().getRenderer(entity) instanceof PonyRenderContext c) {
return (R)c; return (R)c;
} }

View file

@ -1,7 +1,6 @@
package com.minelittlepony.client.render.entity; package com.minelittlepony.client.render.entity;
import com.minelittlepony.api.model.ModelAttributes; import com.minelittlepony.api.model.ModelAttributes;
import com.minelittlepony.api.model.PonyModel;
import com.minelittlepony.api.pony.Pony; import com.minelittlepony.api.pony.Pony;
import com.minelittlepony.api.pony.meta.Wearable; import com.minelittlepony.api.pony.meta.Wearable;
import com.minelittlepony.client.model.*; import com.minelittlepony.client.model.*;
@ -22,8 +21,6 @@ import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.EntityRendererFactory; import net.minecraft.client.render.entity.EntityRendererFactory;
import net.minecraft.client.render.entity.MobEntityRenderer; import net.minecraft.client.render.entity.MobEntityRenderer;
import net.minecraft.client.render.entity.feature.FeatureRenderer; import net.minecraft.client.render.entity.feature.FeatureRenderer;
import net.minecraft.client.render.entity.model.*;
import net.minecraft.client.render.entity.state.BipedEntityRenderState;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState; import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.mob.MobEntity;
@ -33,18 +30,18 @@ import net.minecraft.util.Identifier;
public abstract class AbstractPonyRenderer< public abstract class AbstractPonyRenderer<
T extends MobEntity, T extends MobEntity,
S extends PonyRenderState, S extends PonyRenderState,
M extends EntityModel<? super S> & PonyModel<S> M extends ClientPonyModel<S>
> extends MobEntityRenderer<T, S, M> implements PonyRenderContext<T, S, M> { > extends MobEntityRenderer<T, S, M> implements PonyRenderContext<T, S, M> {
protected final EquineRenderManager<T, S, M> manager; protected final EquineRenderManager<T, S, M> manager;
private final Map<Wearable, Identifier> wearableTextures = new EnumMap<>(Wearable.class); private final Map<Wearable, Identifier> wearableTextures = new EnumMap<>(Wearable.class);
private final TextureSupplier<S> texture; private final TextureSupplier<T> texture;
private final float scale; private final float scale;
public AbstractPonyRenderer(EntityRendererFactory.Context context, ModelKey<? super M> key, TextureSupplier<S> texture, float scale) { public AbstractPonyRenderer(EntityRendererFactory.Context context, ModelKey<? super M> key, TextureSupplier<T> texture, float scale) {
super(context, null, 0.5F); super(context, null, 0.5F);
this.manager = new EquineRenderManager<T, S, M>(this, super::setupTransforms, key); this.manager = new EquineRenderManager<T, S, M>(this, super::setupTransforms, key);
this.texture = texture; this.texture = texture;
@ -59,25 +56,28 @@ public abstract class AbstractPonyRenderer<
} }
protected void addFeatures(EntityRendererFactory.Context context) { protected void addFeatures(EntityRendererFactory.Context context) {
addFeature(new ArmourFeature<>(this, context.getModelManager())); addFeature(new ArmourFeature<>(this, context.getEquipmentModelLoader()));
addFeature(createHeldItemFeature(context)); addPonyFeature(createHeldItemFeature(context));
addFeature(new SkullFeature<>(this, context.getModelLoader(), context.getItemRenderer())); addFeature(new SkullFeature<>(this, context.getModelLoader(), context.getItemRenderer()));
addFeature(new ElytraFeature<>(this)); addPonyFeature(new ElytraFeature<>(this, context.getEquipmentRenderer()));
addFeature(new GearFeature<>(this)); addFeature(new GearFeature<>(this));
} }
@SuppressWarnings({"unchecked", "rawtypes"}) @SuppressWarnings({"unchecked", "rawtypes"})
protected final boolean addPonyFeature(FeatureRenderer<? extends PlayerEntityRenderState, ? extends ClientPonyModel<? extends PlayerEntityRenderState>> feature) { protected final boolean addPonyFeature(FeatureRenderer<
? extends PlayerEntityRenderState,
? extends ClientPonyModel<? extends PlayerEntityRenderState>
> feature) {
return ((List)features).add(feature); return ((List)features).add(feature);
} }
protected HeldItemFeature createHeldItemFeature(EntityRendererFactory.Context context) { protected HeldItemFeature<S, M> createHeldItemFeature(EntityRendererFactory.Context context) {
return new HeldItemFeature(this, context.getItemRenderer()); return new HeldItemFeature<>(this, context.getItemRenderer());
} }
@Override @Override
public final Identifier getTexture(S entity) { public final Identifier getTexture(S entity) {
return texture.apply(entity); return entity.pony.texture();
} }
@Override @Override
@ -147,7 +147,7 @@ public abstract class AbstractPonyRenderer<
@Override @Override
public Pony getEntityPony(T entity) { public Pony getEntityPony(T entity) {
return Pony.getManager().getPony(getTexture(entity)); return Pony.getManager().getPony(texture.apply(entity));
} }
public static <E extends MobEntity, C extends PonyRenderState, M extends ClientPonyModel<C>, T extends PonyRenderer<E, C, M>, F extends FeatureRenderer<C, M>> public static <E extends MobEntity, C extends PonyRenderState, M extends ClientPonyModel<C>, T extends PonyRenderer<E, C, M>, F extends FeatureRenderer<C, M>>
@ -160,9 +160,9 @@ public abstract class AbstractPonyRenderer<
public static < public static <
T extends MobEntity, T extends MobEntity,
S extends PonyRenderState, S extends PonyRenderState,
M extends EntityModel<S> & PonyModel<S>> AbstractPonyRenderer<T, S, M> proxy( M extends ClientPonyModel<S>> AbstractPonyRenderer<T, S, M> proxy(
EntityRendererFactory.Context context, ModelKey<? super M> key, EntityRendererFactory.Context context, ModelKey<? super M> key,
TextureSupplier<S> texture, TextureSupplier<T> texture,
float scale, float scale,
List exportedLayers, List exportedLayers,
Consumer<M> modelConsumer, Consumer<M> modelConsumer,

View file

@ -2,7 +2,6 @@ package com.minelittlepony.client.render.entity;
import com.minelittlepony.api.model.*; import com.minelittlepony.api.model.*;
import com.minelittlepony.api.pony.*; import com.minelittlepony.api.pony.*;
import com.minelittlepony.api.pony.meta.Race;
import com.minelittlepony.client.render.entity.state.PlayerPonyRenderState; import com.minelittlepony.client.render.entity.state.PlayerPonyRenderState;
import com.minelittlepony.util.MathUtil; import com.minelittlepony.util.MathUtil;
@ -10,6 +9,7 @@ import java.util.function.Predicate;
import net.minecraft.client.network.AbstractClientPlayerEntity; import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.render.entity.EntityRendererFactory; import net.minecraft.client.render.entity.EntityRendererFactory;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.entity.EntityPose; import net.minecraft.entity.EntityPose;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.particle.ParticleTypes; import net.minecraft.particle.ParticleTypes;
@ -22,15 +22,15 @@ public class AquaticPlayerPonyRenderer extends FormChangingPlayerPonyRenderer {
} }
@Override @Override
protected Race getPlayerRace(PlayerPonyRenderState state) { public PlayerEntityRenderState createRenderState() {
Race race = super.getPlayerRace(state); return new State();
return ((State)state).skinOverride != null ? Race.SEAPONY : race == Race.SEAPONY ? Race.UNICORN : race;
} }
protected class State extends FormChangingPlayerPonyRenderer.State { class State extends PlayerPonyRenderState {
@Override @Override
public void updateState(LivingEntity entity, PonyModel<?> model, Pony pony, ModelAttributes.Mode mode) { public void updateState(LivingEntity entity, PonyModel<?> model, Pony pony, ModelAttributes.Mode mode) {
super.updateState(entity, model, pony, mode); super.updateState(entity, model, pony, mode);
Identifier skinOverride = getSkinOverride((AbstractClientPlayerEntity)entity);
yOffset = skinOverride != null ? (0.6 + (isInSneakingPose ? 0.125 : 0)) : 0; yOffset = skinOverride != null ? (0.6 + (isInSneakingPose ? 0.125 : 0)) : 0;
pose = EntityPose.STANDING; pose = EntityPose.STANDING;
isInSneakingPose = false; isInSneakingPose = false;

View file

@ -1,20 +1,13 @@
package com.minelittlepony.client.render.entity; package com.minelittlepony.client.render.entity;
import com.minelittlepony.api.model.ModelAttributes;
import com.minelittlepony.api.model.PonyModel;
import com.minelittlepony.api.pony.*; import com.minelittlepony.api.pony.*;
import com.minelittlepony.client.render.entity.state.PlayerPonyRenderState;
import java.util.function.Predicate; import java.util.function.Predicate;
import net.minecraft.client.network.AbstractClientPlayerEntity; import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.render.entity.EntityRendererFactory; import net.minecraft.client.render.entity.EntityRendererFactory;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import org.jetbrains.annotations.Nullable;
public class FormChangingPlayerPonyRenderer extends PlayerPonyRenderer { public class FormChangingPlayerPonyRenderer extends PlayerPonyRenderer {
private final Identifier alternateFormSkinId; private final Identifier alternateFormSkinId;
private final Predicate<AbstractClientPlayerEntity> formModifierPredicate; private final Predicate<AbstractClientPlayerEntity> formModifierPredicate;
@ -26,32 +19,13 @@ public class FormChangingPlayerPonyRenderer extends PlayerPonyRenderer {
this.formModifierPredicate = formModifierPredicate; this.formModifierPredicate = formModifierPredicate;
} }
public PlayerEntityRenderState createRenderState() {
return new State();
}
@Override @Override
public Identifier getTexture(PlayerEntityRenderState state) { public Pony getEntityPony(AbstractClientPlayerEntity entity) {
if (((State)state).skinOverride != null) { Identifier skinOverride = getSkinOverride((AbstractClientPlayerEntity)entity);
return ((State)state).skinOverride; return skinOverride == null ? super.getEntityPony(entity) : Pony.getManager().getPony(skinOverride);
}
return super.getTexture(state);
}
protected class State extends PlayerPonyRenderState {
@Nullable
public Identifier skinOverride;
@Override
public void updateState(LivingEntity entity, PonyModel<?> model, Pony pony, ModelAttributes.Mode mode) {
super.updateState(entity, model, pony, mode);
skinOverride = formModifierPredicate.test((AbstractClientPlayerEntity)entity)
? getSkinOverride((AbstractClientPlayerEntity)entity)
: null;
} }
protected Identifier getSkinOverride(AbstractClientPlayerEntity player) { protected Identifier getSkinOverride(AbstractClientPlayerEntity player) {
return SkinsProxy.getInstance().getSkin(alternateFormSkinId, player).orElse(null); return formModifierPredicate.test(player) ? SkinsProxy.getInstance().getSkin(alternateFormSkinId, player).orElse(null) : null;
}
} }
} }

View file

@ -3,7 +3,6 @@ package com.minelittlepony.client.render.entity;
import com.minelittlepony.api.model.ModelAttributes; import com.minelittlepony.api.model.ModelAttributes;
import com.minelittlepony.api.model.Models; import com.minelittlepony.api.model.Models;
import com.minelittlepony.api.pony.Pony; import com.minelittlepony.api.pony.Pony;
import com.minelittlepony.api.pony.SkinsProxy;
import com.minelittlepony.api.pony.meta.Race; 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.model.*; import com.minelittlepony.client.model.*;
@ -19,7 +18,6 @@ import java.util.function.Function;
import com.minelittlepony.client.render.EquineRenderManager; import com.minelittlepony.client.render.EquineRenderManager;
import net.minecraft.block.BedBlock;
import net.minecraft.client.MinecraftClient; import net.minecraft.client.MinecraftClient;
import net.minecraft.client.network.AbstractClientPlayerEntity; import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.render.*; import net.minecraft.client.render.*;
@ -31,11 +29,16 @@ import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.EntityPose; import net.minecraft.entity.EntityPose;
import net.minecraft.text.Text; import net.minecraft.text.Text;
import net.minecraft.util.*; import net.minecraft.util.*;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
public class PlayerPonyRenderer public class PlayerPonyRenderer
extends PlayerEntityRenderer extends PlayerEntityRenderer
implements PonyRenderContext<AbstractClientPlayerEntity, PlayerPonyRenderState, ClientPonyModel<PlayerPonyRenderState>> { implements PonyRenderContext<
AbstractClientPlayerEntity,
PlayerPonyRenderState,
ClientPonyModel<PlayerPonyRenderState>
> {
private final Function<Race, Models<ClientPonyModel<PlayerPonyRenderState>>> modelsCache; private final Function<Race, Models<ClientPonyModel<PlayerPonyRenderState>>> modelsCache;
protected final EquineRenderManager<AbstractClientPlayerEntity, PlayerPonyRenderState, ClientPonyModel<PlayerPonyRenderState>> manager; protected final EquineRenderManager<AbstractClientPlayerEntity, PlayerPonyRenderState, ClientPonyModel<PlayerPonyRenderState>> manager;
@ -49,7 +52,6 @@ public class PlayerPonyRenderer
addPonyFeatures(context); addPonyFeatures(context);
} }
@SuppressWarnings({"unchecked", "rawtypes"})
protected void addPonyFeatures(EntityRendererFactory.Context context) { protected void addPonyFeatures(EntityRendererFactory.Context context) {
// remove vanilla features (keep modded ones) // remove vanilla features (keep modded ones)
features.removeIf(feature -> { features.removeIf(feature -> {
@ -61,18 +63,21 @@ public class PlayerPonyRenderer
|| feature instanceof ElytraFeatureRenderer || feature instanceof ElytraFeatureRenderer
|| feature instanceof ShoulderParrotFeatureRenderer; || feature instanceof ShoulderParrotFeatureRenderer;
}); });
addPonyFeature(new ArmourFeature<>(this, context.getModelManager())); addPonyFeature(new ArmourFeature<>(this, context.getEquipmentModelLoader()));
addPonyFeature(new HeldItemFeature(this, context.getItemRenderer())); addPonyFeature(new HeldItemFeature<>(this, context.getItemRenderer()));
addPonyFeature(new DJPon3Feature<>(this)); addPonyFeature(new DJPon3Feature<>(this));
addPonyFeature(new CapeFeature<>(this)); addFeature(new CapeFeature(this, context.getModelLoader(), context.getEquipmentModelLoader()));
addPonyFeature(new SkullFeature<>(this, context.getModelLoader(), context.getItemRenderer())); addPonyFeature(new SkullFeature<>(this, context.getModelLoader(), context.getItemRenderer()));
addPonyFeature(new ElytraFeature<>(this)); addPonyFeature(new ElytraFeature<>(this, context.getEquipmentRenderer()));
addPonyFeature(new PassengerFeature<>(this, context)); addPonyFeature(new PassengerFeature<>(this, context));
addPonyFeature(new GearFeature<>(this)); addPonyFeature(new GearFeature<>(this));
} }
@SuppressWarnings({"unchecked", "rawtypes"}) @SuppressWarnings({"unchecked", "rawtypes"})
protected final boolean addPonyFeature(FeatureRenderer<? extends PonyRenderState, ? extends ClientPonyModel<? extends PonyRenderState>> feature) { protected final boolean addPonyFeature(FeatureRenderer<
? extends PlayerEntityRenderState,
? extends ClientPonyModel<? extends PonyRenderState>
> feature) {
return ((List)features).add(feature); return ((List)features).add(feature);
} }
@ -90,6 +95,9 @@ public class PlayerPonyRenderer
public void updateRenderState(AbstractClientPlayerEntity entity, PlayerEntityRenderState state, float tickDelta) { public void updateRenderState(AbstractClientPlayerEntity entity, PlayerEntityRenderState state, float tickDelta) {
super.updateRenderState(entity, state, tickDelta); super.updateRenderState(entity, state, tickDelta);
manager.updateState(entity, (PlayerPonyRenderState)state, mode); manager.updateState(entity, (PlayerPonyRenderState)state, mode);
// Rotate cape to align with the pony back
state.field_53536 += MathHelper.PI / 2;
} }
public final PlayerPonyRenderState getAndUpdateRenderState(AbstractClientPlayerEntity entity, float tickDelta, ModelAttributes.Mode mode) { public final PlayerPonyRenderState getAndUpdateRenderState(AbstractClientPlayerEntity entity, float tickDelta, ModelAttributes.Mode mode) {
@ -206,7 +214,7 @@ public class PlayerPonyRenderer
} }
@Override @Override
public Identifier getTexture(PlayerEntityRenderState state) { public final Identifier getTexture(PlayerEntityRenderState state) {
return ((PonyRenderState)state).pony.texture(); return ((PonyRenderState)state).pony.texture();
} }

View file

@ -16,11 +16,11 @@ public abstract class PonyRenderer<
> extends AbstractPonyRenderer<T, S, M> { > extends AbstractPonyRenderer<T, S, M> {
protected static final float BASE_MODEL_SCALE = 15/16F; protected static final float BASE_MODEL_SCALE = 15/16F;
public PonyRenderer(EntityRendererFactory.Context context, ModelKey<? super M> key, TextureSupplier<S> texture) { public PonyRenderer(EntityRendererFactory.Context context, ModelKey<? super M> key, TextureSupplier<T> texture) {
this(context, key, texture, 1); this(context, key, texture, 1);
} }
public PonyRenderer(EntityRendererFactory.Context context, ModelKey<? super M> key, TextureSupplier<S> texture, float scale) { public PonyRenderer(EntityRendererFactory.Context context, ModelKey<? super M> key, TextureSupplier<T> texture, float scale) {
super(context, key, texture, scale); super(context, key, texture, scale);
} }

View file

@ -1,25 +1,22 @@
package com.minelittlepony.client.render.entity; package com.minelittlepony.client.render.entity;
import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.ArmorStandEntityRenderer; import net.minecraft.client.render.entity.*;
import net.minecraft.client.render.entity.EntityRendererFactory;
import net.minecraft.client.render.entity.feature.*; import net.minecraft.client.render.entity.feature.*;
import net.minecraft.client.render.entity.model.ArmorStandArmorEntityModel; import net.minecraft.client.render.entity.model.ArmorStandArmorEntityModel;
import net.minecraft.client.render.entity.model.EntityModelLayers; import net.minecraft.client.render.entity.state.ArmorStandEntityRenderState;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.decoration.ArmorStandEntity; import net.minecraft.entity.decoration.ArmorStandEntity;
import net.minecraft.util.math.Vec3d;
import com.minelittlepony.api.model.Models; import com.minelittlepony.api.model.Models;
import com.minelittlepony.api.pony.PonyData;
import com.minelittlepony.api.pony.meta.Race;
import com.minelittlepony.client.model.ModelType; import com.minelittlepony.client.model.ModelType;
import com.minelittlepony.client.model.armour.PonifiedEquipmentRenderer;
import com.minelittlepony.client.model.entity.PonyArmourStandModel; import com.minelittlepony.client.model.entity.PonyArmourStandModel;
import com.minelittlepony.client.model.entity.race.EarthPonyModel; import com.minelittlepony.client.model.entity.race.EarthPonyModel;
import com.minelittlepony.client.render.entity.feature.ArmourFeature; import com.minelittlepony.client.render.entity.feature.*;
import com.minelittlepony.client.render.entity.state.PonyRenderState;
public class PonyStandRenderer extends ArmorStandEntityRenderer { public class PonyStandRenderer extends ArmorStandEntityRenderer {
private final PonyArmourStandModel pony = ModelType.ARMOUR_STAND.createModel(); private final PonyArmourStandModel pony = ModelType.ARMOUR_STAND.createModel();
private final ArmorStandArmorEntityModel human; private final ArmorStandArmorEntityModel human;
@ -27,67 +24,65 @@ public class PonyStandRenderer extends ArmorStandEntityRenderer {
super(context); super(context);
human = model; human = model;
features.removeIf(feature -> { for (int i = 0; i < features.size(); i++) {
return feature instanceof ArmorFeatureRenderer var feature = features.get(i);
|| feature instanceof HeldItemFeatureRenderer if (feature instanceof ArmorFeatureRenderer) {
|| feature instanceof ElytraFeatureRenderer features.set(i, new SwappableFeature<>(this, feature, new Armour(this, context), state -> ((State)state).hasPonyForm));
|| feature instanceof HeadFeatureRenderer; }
}); if (feature instanceof ElytraFeatureRenderer) {
addFeature(new Armour(this, context)); features.set(i, new SwappableFeature<>(this, feature, new ElytraFeature<>(this, context.getEquipmentRenderer()), state -> ((State)state).hasPonyForm));
addFeature(new HeldItemFeatureRenderer<>(this, context.getHeldItemRenderer())); }
addFeature(new ElytraFeatureRenderer<>(this, context.getModelLoader()));
addFeature(new HeadFeatureRenderer<>(this, context.getModelLoader(), context.getHeldItemRenderer()));
} }
public Vec3d getPositionOffset(ArmorStandEntity entity, float tickDelta) { //addFeature(new HeadFeatureRenderer<>(this, context.getModelLoader(), context.getItemRenderer()));
this.model = isPonita(entity) ? pony : human; }
try {
return super.getPositionOffset(entity, tickDelta); @Override
} catch (Throwable t) { public ArmorStandEntityRenderState createRenderState() {
// We need to avoid overriding render() because other mods keep overriding it via mixins which breaks the class heirarchy. return new State();
return Vec3d.ZERO; }
public void updateRenderState(ArmorStandEntity entity, ArmorStandEntityRenderState state, float tickDelta) {
boolean ponified = entity.hasCustomName() && "Ponita".equals(entity.getCustomName().getString());
super.updateRenderState(entity, state, tickDelta);
((State)state).hasPonyForm = ponified;
if (ponified) {
state.pitch = 0.017453292F * entity.getHeadRotation().getPitch();
state.yawDegrees = 0.017453292F * entity.getHeadRotation().getYaw();
} }
} }
@Override @Override
protected void setupTransforms(ArmorStandEntity entity, MatrixStack stack, float animationProgress, float bodyYaw, float tickDelta, float scale) { protected void setupTransforms(ArmorStandEntityRenderState state, MatrixStack stack, float animationProgress, float bodyYaw) {
super.setupTransforms(entity, stack, animationProgress, bodyYaw, tickDelta, scale); super.setupTransforms(state, stack, animationProgress, bodyYaw);
if (isPonita(entity)) { if (((State)state).hasPonyForm) {
stack.translate(0, 0, scale * -4/16F); stack.translate(0, 0, state.baseScale * -4/16F);
} this.model = pony;
}
class Armour extends ArmorFeatureRenderer<ArmorStandEntity, ArmorStandArmorEntityModel, ArmorStandArmorEntityModel> {
private final Models<ArmorStandEntity, EarthPonyModel<ArmorStandEntity>> pony = ModelType.EARTH_PONY.<ArmorStandEntity, EarthPonyModel<ArmorStandEntity>>create(false);
public Armour(FeatureRendererContext<ArmorStandEntity, ArmorStandArmorEntityModel> renderer, EntityRendererFactory.Context context) {
super(renderer,
new ArmorStandArmorEntityModel(context.getPart(EntityModelLayers.ARMOR_STAND_INNER_ARMOR)),
new ArmorStandArmorEntityModel(context.getPart(EntityModelLayers.ARMOR_STAND_OUTER_ARMOR)),
context.getModelManager()
);
pony.applyMetadata(PonyData.emptyOf(Race.EARTH));
}
@Override
public void render(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, ArmorStandEntity entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) {
if (isPonita(entity)) {
headPitch = 0.017453292F * entity.getHeadRotation().getPitch();
headYaw = 0.017453292F * entity.getHeadRotation().getYaw();
pony.body().animateModel(entity, limbDistance, limbAngle, tickDelta);
pony.body().setAngles(entity, limbDistance, limbAngle, age, headYaw, headPitch);
PonyStandRenderer.this.pony.applyAnglesTo(pony.body());
ArmourFeature.renderArmor(pony, stack, renderContext, lightUv, entity, limbDistance, limbAngle, age, headYaw, headPitch);
} else { } else {
super.render(stack, renderContext, lightUv, entity, limbDistance, limbAngle, tickDelta, age, headYaw, headPitch); this.model = human;
}
} }
} }
static boolean isPonita(ArmorStandEntity entity) { class Armour extends FeatureRenderer<ArmorStandEntityRenderState, ArmorStandArmorEntityModel> {
return entity.hasCustomName() && "Ponita".equals(entity.getCustomName().getString()); private final Models<EarthPonyModel<PonyRenderState>> pony = ModelType.EARTH_PONY.create(false);
private final PonifiedEquipmentRenderer equipmentRenderer;
public Armour(FeatureRendererContext<ArmorStandEntityRenderState, ArmorStandArmorEntityModel> renderer, EntityRendererFactory.Context context) {
super(renderer);
equipmentRenderer = new PonifiedEquipmentRenderer(context.getEquipmentModelLoader());
}
@Override
public void render(MatrixStack matrices, VertexConsumerProvider vertices, int light, ArmorStandEntityRenderState state, float limbAngle, float limbDistance) {
pony.body().setAngles(((State)state).ponyState);
ArmourFeature.renderArmor(pony, matrices, vertices, light, ((State)state).ponyState, limbDistance, limbAngle, equipmentRenderer);
}
}
public static final class State extends ArmorStandEntityRenderState {
public boolean hasPonyForm;
public PonyRenderState ponyState = new PonyRenderState();
} }
} }

View file

@ -28,7 +28,7 @@ public class SeaponyRenderer extends PonyRenderer<GuardianEntity, SeaponyRendere
private static final Identifier EXPLOSION_BEAM_TEXTURE = Identifier.ofVanilla("textures/entity/guardian_beam.png"); private static final Identifier EXPLOSION_BEAM_TEXTURE = Identifier.ofVanilla("textures/entity/guardian_beam.png");
private static final RenderLayer LAYER = RenderLayer.getEntityCutoutNoCull(EXPLOSION_BEAM_TEXTURE); private static final RenderLayer LAYER = RenderLayer.getEntityCutoutNoCull(EXPLOSION_BEAM_TEXTURE);
public SeaponyRenderer(EntityRendererFactory.Context context, TextureSupplier<State> texture, float scale) { public SeaponyRenderer(EntityRendererFactory.Context context, TextureSupplier<GuardianEntity> texture, float scale) {
super(context, ModelType.GUARDIAN, texture, scale); super(context, ModelType.GUARDIAN, texture, scale);
} }

View file

@ -22,7 +22,7 @@ public class ZomponyRenderer<T extends HostileEntity> extends PonyRenderer<T, Zo
public static final Identifier DEMON_CHILD = MineLittlePony.id("textures/entity/zombie/demon_child.png"); public static final Identifier DEMON_CHILD = MineLittlePony.id("textures/entity/zombie/demon_child.png");
protected ZomponyRenderer(EntityRendererFactory.Context context, TextureSupplier<State> texture, float scale) { protected ZomponyRenderer(EntityRendererFactory.Context context, TextureSupplier<T> texture, float scale) {
super(context, ModelType.ZOMBIE, texture, scale); super(context, ModelType.ZOMBIE, texture, scale);
} }
@ -32,7 +32,7 @@ public class ZomponyRenderer<T extends HostileEntity> extends PonyRenderer<T, Zo
} }
public static ZomponyRenderer<ZombieEntity> zombie(EntityRendererFactory.Context context) { public static ZomponyRenderer<ZombieEntity> zombie(EntityRendererFactory.Context context) {
return new ZomponyRenderer<>(context, entity -> entity.isCozyGlow ? DEMON_CHILD : ZOMBIE, 1); return new ZomponyRenderer<>(context, entity -> isCozyGlow(entity) ? DEMON_CHILD : ZOMBIE, 1);
} }
public static ZomponyRenderer<HuskEntity> husk(EntityRendererFactory.Context context) { public static ZomponyRenderer<HuskEntity> husk(EntityRendererFactory.Context context) {
@ -47,13 +47,17 @@ public class ZomponyRenderer<T extends HostileEntity> extends PonyRenderer<T, Zo
return new ZomponyRenderer<>(context, TextureSupplier.of(ZOMBIE), 6.8F); return new ZomponyRenderer<>(context, TextureSupplier.of(ZOMBIE), 6.8F);
} }
static boolean isCozyGlow(LivingEntity entity) {
return entity.isBaby() && entity.getUuid().getLeastSignificantBits() % 160 == 0;
}
public static class State extends PonyRenderState { public static class State extends PonyRenderState {
public boolean isWinged; public boolean isWinged;
public boolean isCozyGlow; public boolean isCozyGlow;
public void updateState(LivingEntity entity, PonyModel<?> model, Pony pony, ModelAttributes.Mode mode) { public void updateState(LivingEntity entity, PonyModel<?> model, Pony pony, ModelAttributes.Mode mode) {
super.updateState(entity, model, pony, mode); super.updateState(entity, model, pony, mode);
isCozyGlow = baby && entity.getUuid().getLeastSignificantBits() % 160 == 0; isCozyGlow = isCozyGlow(entity);
isWinged = entity.getUuid().getLeastSignificantBits() % 30 == 0; isWinged = entity.getUuid().getLeastSignificantBits() % 30 == 0;
} }

View file

@ -1,25 +1,23 @@
package com.minelittlepony.client.render.entity.feature; package com.minelittlepony.client.render.entity.feature;
import com.minelittlepony.api.model.Models; import com.minelittlepony.api.model.Models;
import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.client.model.ClientPonyModel;
import com.minelittlepony.client.render.PonyRenderContext; import com.minelittlepony.client.render.PonyRenderContext;
import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.client.render.entity.state.PonyRenderState;
import net.minecraft.client.render.entity.feature.FeatureRenderer; import net.minecraft.client.render.entity.feature.FeatureRenderer;
import net.minecraft.client.render.entity.feature.FeatureRendererContext; import net.minecraft.client.render.entity.feature.FeatureRendererContext;
import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
public abstract class AbstractPonyFeature< public abstract class AbstractPonyFeature<
S extends PonyRenderState, S extends PonyRenderState,
M extends EntityModel<? super S> & PonyModel<S> M extends ClientPonyModel<S>
> extends FeatureRenderer<S, M> { > extends FeatureRenderer<S, M> {
private final PonyRenderContext<?, S, M> context; private final PonyRenderContext<?, S, M> context;
@SuppressWarnings("unchecked")
public AbstractPonyFeature(PonyRenderContext<?, S, M> context) { public AbstractPonyFeature(PonyRenderContext<?, S, M> context) {
super((FeatureRendererContext<S, M>)context); super(context.upcast());
this.context = context; this.context = context;
} }

View file

@ -2,13 +2,13 @@ package com.minelittlepony.client.render.entity.feature;
import com.minelittlepony.api.model.Models; import com.minelittlepony.api.model.Models;
import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.api.model.PonyModel;
import com.minelittlepony.client.model.ClientPonyModel;
import com.minelittlepony.client.model.armour.*; import com.minelittlepony.client.model.armour.*;
import com.minelittlepony.client.render.PonyRenderContext; import com.minelittlepony.client.render.PonyRenderContext;
import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.client.render.entity.state.PonyRenderState;
import net.minecraft.client.render.*; import net.minecraft.client.render.*;
import net.minecraft.client.render.entity.equipment.EquipmentModelLoader; import net.minecraft.client.render.entity.equipment.EquipmentModelLoader;
import net.minecraft.client.render.entity.model.*;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.component.DataComponentTypes; import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.EquippableComponent; import net.minecraft.component.type.EquippableComponent;
@ -18,7 +18,11 @@ import net.minecraft.item.*;
import net.minecraft.item.equipment.EquipmentModel; import net.minecraft.item.equipment.EquipmentModel;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
public class ArmourFeature<T extends LivingEntity, S extends PonyRenderState, M extends EntityModel<? super S> & PonyModel<S>> extends AbstractPonyFeature<S, M> { public class ArmourFeature<
T extends LivingEntity,
S extends PonyRenderState,
M extends ClientPonyModel<S>
> extends AbstractPonyFeature<S, M> {
private final PonifiedEquipmentRenderer equipmentRenderer; private final PonifiedEquipmentRenderer equipmentRenderer;

View file

@ -5,79 +5,63 @@ import com.minelittlepony.client.model.ClientPonyModel;
import com.minelittlepony.client.model.armour.ArmourLayer; import com.minelittlepony.client.model.armour.ArmourLayer;
import com.minelittlepony.client.model.armour.ArmourRendererPlugin; import com.minelittlepony.client.model.armour.ArmourRendererPlugin;
import com.minelittlepony.client.render.PonyRenderContext; import com.minelittlepony.client.render.PonyRenderContext;
import com.minelittlepony.client.render.entity.state.PlayerPonyRenderState;
import com.minelittlepony.common.util.render.RenderLayerUtil;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.render.OverlayTexture;
import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.equipment.EquipmentModelLoader;
import net.minecraft.client.render.entity.feature.CapeFeatureRenderer;
import net.minecraft.client.render.entity.model.EntityModelLoader;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.player.PlayerModelPart; import net.minecraft.util.Identifier;
import net.minecraft.util.math.*;
public class CapeFeature<M extends ClientPonyModel<AbstractClientPlayerEntity>> extends AbstractPonyFeature<AbstractClientPlayerEntity, M> { public class CapeFeature extends CapeFeatureRenderer {
public CapeFeature(PonyRenderContext<AbstractClientPlayerEntity, M> context) { private final PonyRenderContext<?, PlayerPonyRenderState, ClientPonyModel<PlayerPonyRenderState>> context;
super(context);
public CapeFeature(PonyRenderContext<?, PlayerPonyRenderState, ClientPonyModel<PlayerPonyRenderState>> context, EntityModelLoader modelLoader, EquipmentModelLoader equipmentModelLoader) {
super(context.upcast(), modelLoader, equipmentModelLoader);
this.context = context;
} }
@Override @Override
public void render(MatrixStack matrices, VertexConsumerProvider provider, int light, AbstractClientPlayerEntity player, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) { public void render(MatrixStack matrices, VertexConsumerProvider vertices, int light, PlayerEntityRenderState player, float limbAngle, float limbDistance) {
M model = getModelWrapper().body(); ClientPonyModel<PlayerPonyRenderState> model = context.getInternalRenderer().getModels().body();
if (!player.isInvisible()
&& player.isPartVisible(PlayerModelPart.CAPE)
&& player.getSkinTextures().capeTexture() != null) {
if (!player.invisible && player.capeVisible) {
ArmourRendererPlugin plugin = ArmourRendererPlugin.INSTANCE.get(); ArmourRendererPlugin plugin = ArmourRendererPlugin.INSTANCE.get();
VertexConsumer vertices = plugin.getCapeConsumer(player, provider, player.getSkinTextures().capeTexture()); Identifier capeTexture = player.skinTextures.capeTexture();
if (vertices == null) { VertexConsumer buffer = plugin.getCapeConsumer(player, vertices, player.skinTextures.capeTexture());
if (buffer == null) {
return; return;
} }
boolean[] rendered = {false};
matrices.push(); matrices.push();
super.render(matrices, layer -> {
if (RenderLayerUtil.getTexture(layer).orElse(null) == capeTexture) {
rendered[0] = true;
matrices.translate(0, 0.24F, 0); matrices.translate(0, 0.24F, 0);
if (model.getAttributes().isLyingDown) { if (((PlayerPonyRenderState)player).getAttributes().isLyingDown) {
matrices.translate(0, -0.05F, 0); matrices.translate(0, -0.05F, 0);
} }
model.transform(BodyPart.BODY, matrices); model.transform((PlayerPonyRenderState)player, BodyPart.BODY, matrices);
model.getBodyPart(BodyPart.BODY).rotate(matrices); model.getBodyPart(BodyPart.BODY).rotate(matrices);
double capeX = MathHelper.lerp(tickDelta, player.capeX, player.prevCapeX) - MathHelper.lerp(tickDelta, player.prevX, player.getX()); return buffer;
double capeY = MathHelper.lerp(tickDelta, player.capeY, player.prevCapeY) - MathHelper.lerp(tickDelta, player.prevY, player.getY()); }
double capeZ = MathHelper.lerp(tickDelta, player.capeZ, player.prevCapeZ) - MathHelper.lerp(tickDelta, player.prevZ, player.getZ()); return vertices.getBuffer(layer);
}, light, player, limbAngle, limbDistance);
float motionYaw = player.prevBodyYaw + (player.bodyYaw - player.prevBodyYaw);
double sin = MathHelper.sin(motionYaw * MathHelper.RADIANS_PER_DEGREE);
double cos = -MathHelper.cos(motionYaw * MathHelper.RADIANS_PER_DEGREE);
float capeMotionY = (float) capeY * 10;
if (capeMotionY < -6) capeMotionY = -6;
if (capeMotionY > 32) capeMotionY = 32;
float capeMotionX = (float) (capeX * sin + capeZ * cos) * 100;
float diagMotion = (float) (capeX * cos - capeZ * sin) * 100;
if (capeMotionX < 0) capeMotionX = 0;
float camera = MathHelper.lerp(tickDelta, player.prevStrideDistance, player.strideDistance);
capeMotionY += MathHelper.sin(MathHelper.lerp(tickDelta, player.prevHorizontalSpeed, player.horizontalSpeed) * 6) * 32 * camera;
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(2 + capeMotionX / 12 + capeMotionY));
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees( diagMotion / 2));
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(-diagMotion / 2));
matrices.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(180));
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(90));
model.renderCape(matrices, vertices, light, OverlayTexture.DEFAULT_UV);
matrices.pop(); matrices.pop();
plugin.onArmourRendered(player, matrices, provider, EquipmentSlot.BODY, ArmourLayer.OUTER, ArmourRendererPlugin.ArmourType.CAPE); if (rendered[0]) {
plugin.onArmourRendered(player, matrices, vertices, EquipmentSlot.BODY, ArmourLayer.OUTER, ArmourRendererPlugin.ArmourType.CAPE);
}
} }
} }
} }

View file

@ -4,21 +4,18 @@ import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.render.OverlayTexture; import net.minecraft.client.render.OverlayTexture;
import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.Colors; import net.minecraft.util.Colors;
import com.minelittlepony.client.model.ModelType;
import com.minelittlepony.api.model.BodyPart; import com.minelittlepony.api.model.BodyPart;
import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.client.model.*;
import com.minelittlepony.client.model.DJPon3EarsModel;
import com.minelittlepony.client.render.PonyRenderContext; import com.minelittlepony.client.render.PonyRenderContext;
import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.client.render.entity.state.PonyRenderState;
public class DJPon3Feature< public class DJPon3Feature<
T extends AbstractClientPlayerEntity, T extends AbstractClientPlayerEntity,
S extends PonyRenderState, S extends PonyRenderState,
M extends EntityModel<? super S> & PonyModel<S> M extends ClientPonyModel<S>
> extends AbstractPonyFeature<S, M> { > extends AbstractPonyFeature<S, M> {
private final DJPon3EarsModel deadMau5 = ModelType.DJ_PON_3.createModel(); private final DJPon3EarsModel deadMau5 = ModelType.DJ_PON_3.createModel();

View file

@ -1,9 +1,7 @@
package com.minelittlepony.client.render.entity.feature; package com.minelittlepony.client.render.entity.feature;
import com.minelittlepony.api.model.BodyPart; import com.minelittlepony.api.model.BodyPart;
import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.client.model.*;
import com.minelittlepony.client.model.ModelType;
import com.minelittlepony.client.model.PonyElytra;
import com.minelittlepony.client.model.armour.ArmourLayer; import com.minelittlepony.client.model.armour.ArmourLayer;
import com.minelittlepony.client.model.armour.ArmourRendererPlugin; import com.minelittlepony.client.model.armour.ArmourRendererPlugin;
import com.minelittlepony.client.render.PonyRenderContext; import com.minelittlepony.client.render.PonyRenderContext;
@ -11,64 +9,70 @@ import com.minelittlepony.client.render.entity.state.PonyRenderState;
import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.equipment.EquipmentRenderer; import net.minecraft.client.render.entity.equipment.EquipmentRenderer;
import net.minecraft.client.render.entity.feature.FeatureRenderer;
import net.minecraft.client.render.entity.feature.FeatureRendererContext;
import net.minecraft.client.render.entity.model.EntityModel; import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.client.render.entity.state.BipedEntityRenderState;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState; import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.client.util.SkinTextures; import net.minecraft.client.util.SkinTextures;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.component.DataComponentTypes; import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.EquippableComponent; import net.minecraft.component.type.EquippableComponent;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.EquipmentSlot;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.equipment.EquipmentModel; import net.minecraft.item.equipment.EquipmentModel;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
public class ElytraFeature< public class ElytraFeature<
T extends LivingEntity, S extends BipedEntityRenderState,
S extends PonyRenderState, M extends EntityModel<S>
M extends EntityModel<? super S> & PonyModel<S> > extends FeatureRenderer<S, M> {
> extends AbstractPonyFeature<S, M> {
private static final Identifier TEXTURE = Identifier.ofVanilla("textures/entity/elytra.png"); private static final Identifier TEXTURE = Identifier.ofVanilla("textures/entity/elytra.png");
private final PonyElytra<S> model = ModelType.ELYTRA.createModel(); private final PonyElytra<S> model = ModelType.ELYTRA.createModel();
private final FeatureRendererContext<S, M> context;
private final EquipmentRenderer equipmentRenderer; private final EquipmentRenderer equipmentRenderer;
public ElytraFeature(PonyRenderContext<T, S, M> context, EquipmentRenderer equipmentRenderer) { public ElytraFeature(FeatureRendererContext<S, M> context, EquipmentRenderer equipmentRenderer) {
super(context); super(context);
this.context = context;
this.equipmentRenderer = equipmentRenderer; this.equipmentRenderer = equipmentRenderer;
} }
@Override @Override
public void render(MatrixStack matrices, VertexConsumerProvider provider, int light, S entity, float limbAngle, float limbDistance) { public void render(MatrixStack matrices, VertexConsumerProvider provider, int light, S state, float limbAngle, float limbDistance) {
ArmourRendererPlugin plugin = ArmourRendererPlugin.INSTANCE.get(); ArmourRendererPlugin plugin = ArmourRendererPlugin.INSTANCE.get();
for (ItemStack stack : plugin.getArmorStacks(entity, EquipmentSlot.CHEST, ArmourLayer.OUTER, ArmourRendererPlugin.ArmourType.ELYTRA)) { for (ItemStack stack : plugin.getArmorStacks(state, EquipmentSlot.CHEST, ArmourLayer.OUTER, ArmourRendererPlugin.ArmourType.ELYTRA)) {
EquippableComponent equippable = stack.get(DataComponentTypes.EQUIPPABLE); EquippableComponent equippable = stack.get(DataComponentTypes.EQUIPPABLE);
if (equippable != null && !equippable.model().isEmpty()) { if (equippable != null && !equippable.model().isEmpty()) {
Identifier equipmentModel = equippable.model().get(); Identifier equipmentModel = equippable.model().get();
float alpha = plugin.getElytraAlpha(stack, model, entity); float alpha = plugin.getElytraAlpha(stack, model, state);
if (alpha <= 0) { if (alpha <= 0) {
return; return;
} }
matrices.push(); matrices.push();
model.setAngles(entity); model.setAngles(state);
preRenderCallback(entity, matrices); preRenderCallback(state, matrices);
equipmentRenderer.render(EquipmentModel.LayerType.WINGS, equipmentModel, model, stack, matrices, provider, light, getElytraTexture(entity)); equipmentRenderer.render(EquipmentModel.LayerType.WINGS, equipmentModel, model, stack, matrices, provider, light, getElytraTexture(state));
matrices.pop(); matrices.pop();
} }
} }
plugin.onArmourRendered(entity, matrices, provider, EquipmentSlot.BODY, ArmourLayer.OUTER, ArmourRendererPlugin.ArmourType.ELYTRA); plugin.onArmourRendered(state, matrices, provider, EquipmentSlot.BODY, ArmourLayer.OUTER, ArmourRendererPlugin.ArmourType.ELYTRA);
} }
@SuppressWarnings("unchecked")
protected void preRenderCallback(S state, MatrixStack stack) { protected void preRenderCallback(S state, MatrixStack stack) {
M body = getModelWrapper().body(); if (state instanceof PonyRenderState ponyState && context instanceof PonyRenderContext context) {
stack.translate(0, state.riderOffset, 0.125); stack.translate(0, ponyState.riderOffset, 0.125);
body.transform(state, BodyPart.BODY, stack);
((ClientPonyModel<PonyRenderState>)context.getInternalRenderer().getModels().body()).transform(ponyState, BodyPart.BODY, stack);
}
} }
protected Identifier getElytraTexture(S state) { protected Identifier getElytraTexture(S state) {
@ -79,7 +83,7 @@ public class ElytraFeature<
return textures.elytraTexture(); return textures.elytraTexture();
} }
if (textures.capeTexture() != null && state.capeVisible) { if (textures.capeTexture() != null && playerState.capeVisible) {
return textures.capeTexture(); return textures.capeTexture();
} }
} }

View file

@ -4,7 +4,6 @@ import it.unimi.dsi.fastutil.objects.Object2FloatLinkedOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2FloatMap; import it.unimi.dsi.fastutil.objects.Object2FloatMap;
import net.minecraft.block.SkullBlock; import net.minecraft.block.SkullBlock;
import net.minecraft.client.render.*; import net.minecraft.client.render.*;
import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
@ -17,9 +16,9 @@ import net.minecraft.world.EmptyBlockView;
import com.google.common.cache.*; import com.google.common.cache.*;
import com.google.common.collect.Streams; import com.google.common.collect.Streams;
import com.minelittlepony.api.model.BodyPart; import com.minelittlepony.api.model.BodyPart;
import com.minelittlepony.api.model.PonyModel;
import com.minelittlepony.api.model.gear.Gear; import com.minelittlepony.api.model.gear.Gear;
import com.minelittlepony.api.pony.meta.Wearable; import com.minelittlepony.api.pony.meta.Wearable;
import com.minelittlepony.client.model.ClientPonyModel;
import com.minelittlepony.client.model.ModelType; import com.minelittlepony.client.model.ModelType;
import com.minelittlepony.client.model.armour.ArmourLayer; import com.minelittlepony.client.model.armour.ArmourLayer;
import com.minelittlepony.client.model.armour.ArmourRendererPlugin; import com.minelittlepony.client.model.armour.ArmourRendererPlugin;
@ -33,7 +32,7 @@ import java.util.stream.Collectors;
public class GearFeature< public class GearFeature<
T extends LivingEntity, T extends LivingEntity,
S extends PonyRenderState, S extends PonyRenderState,
M extends EntityModel<? super S> & PonyModel<S> M extends ClientPonyModel<S>
> extends AbstractPonyFeature<S, M> { > extends AbstractPonyFeature<S, M> {
private final List<Entry> gears = Streams.concat( private final List<Entry> gears = Streams.concat(

View file

@ -3,17 +3,16 @@ package com.minelittlepony.client.render.entity.feature;
import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.entity.feature.EyesFeatureRenderer; import net.minecraft.client.render.entity.feature.EyesFeatureRenderer;
import net.minecraft.client.render.entity.feature.FeatureRendererContext; import net.minecraft.client.render.entity.feature.FeatureRendererContext;
import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState; import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.client.model.ClientPonyModel;
import com.minelittlepony.client.render.PonyRenderContext; import com.minelittlepony.client.render.PonyRenderContext;
import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.client.render.entity.state.PonyRenderState;
public class GlowingEyesFeature< public class GlowingEyesFeature<
S extends PonyRenderState, S extends PonyRenderState,
M extends EntityModel<PlayerEntityRenderState> & PonyModel<S> M extends ClientPonyModel<S>
> extends EyesFeatureRenderer<PlayerEntityRenderState, M> { > extends EyesFeatureRenderer<PlayerEntityRenderState, M> {
private final RenderLayer layer; private final RenderLayer layer;

View file

@ -1,13 +1,12 @@
package com.minelittlepony.client.render.entity.feature; package com.minelittlepony.client.render.entity.feature;
import com.minelittlepony.api.model.*; import com.minelittlepony.api.model.*;
import com.minelittlepony.client.model.ClientPonyModel;
import com.minelittlepony.client.render.PonyRenderContext; import com.minelittlepony.client.render.PonyRenderContext;
import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.client.render.entity.state.PonyRenderState;
import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.feature.FeatureRendererContext; import net.minecraft.client.render.entity.feature.PlayerHeldItemFeatureRenderer;
import net.minecraft.client.render.entity.feature.HeldItemFeatureRenderer;
import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState; import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.client.render.item.ItemRenderer; import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
@ -18,13 +17,13 @@ import net.minecraft.util.Arm;
@SuppressWarnings(value = {"unchecked"}) @SuppressWarnings(value = {"unchecked"})
public class HeldItemFeature< public class HeldItemFeature<
S extends PonyRenderState, S extends PonyRenderState,
M extends EntityModel<PlayerEntityRenderState> & PonyModel<S> M extends ClientPonyModel<S>
> extends HeldItemFeatureRenderer<PlayerEntityRenderState, M> { > extends PlayerHeldItemFeatureRenderer<PlayerEntityRenderState, M> {
private final PonyRenderContext<?, S, M> context; private final PonyRenderContext<?, S, M> context;
public HeldItemFeature(PonyRenderContext<?, S, M> context, ItemRenderer renderer) { public HeldItemFeature(PonyRenderContext<?, S, M> context, ItemRenderer renderer) {
super((FeatureRendererContext<PlayerEntityRenderState, M>)context, renderer); super(context.upcast(), renderer);
this.context = context; this.context = context;
} }

View file

@ -2,6 +2,7 @@ package com.minelittlepony.client.render.entity.feature;
import com.minelittlepony.api.model.BodyPart; import com.minelittlepony.api.model.BodyPart;
import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.api.model.PonyModel;
import com.minelittlepony.client.model.ClientPonyModel;
import com.minelittlepony.client.model.armour.ArmourLayer; import com.minelittlepony.client.model.armour.ArmourLayer;
import com.minelittlepony.client.model.armour.ArmourRendererPlugin; import com.minelittlepony.client.model.armour.ArmourRendererPlugin;
import com.minelittlepony.client.render.PonyRenderContext; import com.minelittlepony.client.render.PonyRenderContext;
@ -25,7 +26,8 @@ import net.minecraft.item.*;
public class SkullFeature< public class SkullFeature<
T extends LivingEntity, T extends LivingEntity,
S extends PonyRenderState, S extends PonyRenderState,
M extends EntityModel<? super S> & PonyModel<S>> extends AbstractPonyFeature<S, M> { M extends ClientPonyModel<S>
> extends AbstractPonyFeature<S, M> {
private final ItemRenderer itemRenderer; private final ItemRenderer itemRenderer;
public SkullFeature(PonyRenderContext<T, S, M> renderPony, EntityModelLoader entityModelLoader, ItemRenderer itemRenderer) { public SkullFeature(PonyRenderContext<T, S, M> renderPony, EntityModelLoader entityModelLoader, ItemRenderer itemRenderer) {

View file

@ -0,0 +1,35 @@
package com.minelittlepony.client.render.entity.feature;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.feature.FeatureRenderer;
import net.minecraft.client.render.entity.feature.FeatureRendererContext;
import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.client.render.entity.state.EntityRenderState;
import net.minecraft.client.util.math.MatrixStack;
import java.util.function.Predicate;
public final class SwappableFeature<S extends EntityRenderState, M extends EntityModel<? super S>> extends FeatureRenderer<S, M> {
private final FeatureRenderer<S, M> normal;
private final FeatureRenderer<S, M> swapped;
private final Predicate<S> swapCondition;
public SwappableFeature(
FeatureRendererContext<S, M> context,
FeatureRenderer<S, M> normal,
FeatureRenderer<S, M> swapped,
Predicate<S> swapCondition
) {
super(context);
this.normal = normal;
this.swapped = swapped;
this.swapCondition = swapCondition;
}
@Override
public void render(MatrixStack matrices, VertexConsumerProvider vertices, int light, S state, float limbAngle, float limbDistance) {
(swapCondition.test(state) ? swapped : normal).render(matrices, vertices, light, state, limbAngle, limbDistance);
}
}

View file

@ -28,7 +28,7 @@ abstract class AbstractNpcRenderer<
return ModelType.getPlayerModel(race).create(false, this::initializeModel); return ModelType.getPlayerModel(race).create(false, this::initializeModel);
}); });
public AbstractNpcRenderer(EntityRendererFactory.Context context, String type, TextureSupplier<S> textureSupplier, TextureSupplier<String> formatter) { 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).getKey(false), SillyPonyTextureSupplier.create(textureSupplier, formatter));
clothing = new NpcClothingFeature<>(this, type); clothing = new NpcClothingFeature<>(this, type);
this.manager.setModelsLookup(entity -> models.apply(entity.getRace())); this.manager.setModelsLookup(entity -> models.apply(entity.getRace()));

View file

@ -13,7 +13,7 @@ import com.minelittlepony.client.render.entity.npc.textures.*;
public class VillagerPonyRenderer extends AbstractNpcRenderer<VillagerEntity, VillagerPonyRenderer.State> { public class VillagerPonyRenderer extends AbstractNpcRenderer<VillagerEntity, VillagerPonyRenderer.State> {
private static final TextureSupplier<String> FORMATTER = TextureSupplier.formatted("minelittlepony", "textures/entity/villager/%s.png"); private static final TextureSupplier<String> FORMATTER = TextureSupplier.formatted("minelittlepony", "textures/entity/villager/%s.png");
private static final TextureSupplier<State> TEXTURES = TextureSupplier.ofPool( private static final TextureSupplier<VillagerEntity> TEXTURES = TextureSupplier.ofPool(
VariatedTextureSupplier.BACKGROUND_PONIES_POOL, VariatedTextureSupplier.BACKGROUND_PONIES_POOL,
PlayerTextureSupplier.create(ProfessionTextureSupplier.create(FORMATTER)) PlayerTextureSupplier.create(ProfessionTextureSupplier.create(FORMATTER))
); );

View file

@ -13,7 +13,7 @@ import com.minelittlepony.client.render.entity.npc.textures.*;
public class ZomponyVillagerRenderer extends AbstractNpcRenderer<ZombieVillagerEntity, ZomponyVillagerRenderer.State> { public class ZomponyVillagerRenderer extends AbstractNpcRenderer<ZombieVillagerEntity, ZomponyVillagerRenderer.State> {
private static final TextureSupplier<String> FORMATTER = TextureSupplier.formatted("minelittlepony", "textures/entity/zombie_villager/zombie_%s.png"); private static final TextureSupplier<String> FORMATTER = TextureSupplier.formatted("minelittlepony", "textures/entity/zombie_villager/zombie_%s.png");
private static final TextureSupplier<State> TEXTURES = TextureSupplier.ofPool( private static final TextureSupplier<ZombieVillagerEntity> TEXTURES = TextureSupplier.ofPool(
VariatedTextureSupplier.BACKGROUND_ZOMPONIES_POOL, VariatedTextureSupplier.BACKGROUND_ZOMPONIES_POOL,
TextureSupplier.ofPool( TextureSupplier.ofPool(
VariatedTextureSupplier.BACKGROUND_PONIES_POOL, VariatedTextureSupplier.BACKGROUND_PONIES_POOL,

View file

@ -1,18 +1,18 @@
package com.minelittlepony.client.render.entity.npc.textures; package com.minelittlepony.client.render.entity.npc.textures;
import net.minecraft.block.entity.SkullBlockEntity; import net.minecraft.block.entity.SkullBlockEntity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.Util; import net.minecraft.util.Util;
import com.minelittlepony.api.pony.Pony; import com.minelittlepony.api.pony.Pony;
import com.minelittlepony.api.pony.SkinsProxy; import com.minelittlepony.api.pony.SkinsProxy;
import com.minelittlepony.client.render.entity.state.PonyRenderState;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.function.Function; import java.util.function.Function;
public class PlayerTextureSupplier { public class PlayerTextureSupplier {
public static <T extends PonyRenderState> TextureSupplier<T> create(TextureSupplier<T> fallback) { public static <T extends LivingEntity> TextureSupplier<T> create(TextureSupplier<T> fallback) {
Function<String, CompletableFuture<Identifier>> customNameCache = Util.memoize(name -> { Function<String, CompletableFuture<Identifier>> customNameCache = Util.memoize(name -> {
return SkullBlockEntity.fetchProfileByName(name).thenApply(profile -> { return SkullBlockEntity.fetchProfileByName(name).thenApply(profile -> {
return profile return profile
@ -22,7 +22,7 @@ public class PlayerTextureSupplier {
}); });
}); });
return entity -> { return entity -> {
Identifier override = entity.customName != null ? customNameCache.apply(entity.customName.getString()).getNow(null) : null; Identifier override = entity.hasCustomName() ? customNameCache.apply(entity.getCustomName().getString()).getNow(null) : null;
if (override != null) { if (override != null) {
return override; return override;
} }

View file

@ -10,10 +10,10 @@ import com.minelittlepony.api.pony.Pony;
import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.client.render.entity.state.PonyRenderState;
public class SillyPonyTextureSupplier { public class SillyPonyTextureSupplier {
public static <T extends State> TextureSupplier<T> create(TextureSupplier<T> fallback, TextureSupplier<String> formatter) { public static <T extends LivingEntity> TextureSupplier<T> create(TextureSupplier<T> fallback, TextureSupplier<String> formatter) {
Identifier egg = formatter.apply("silly_pony"); Identifier egg = formatter.apply("silly_pony");
Identifier egg2 = formatter.apply("tiny_silly_pony"); Identifier egg2 = formatter.apply("tiny_silly_pony");
return entity -> entity.isDerpy ? (entity.isDinky ? egg2 : egg) : fallback.apply(entity); return entity -> SillyPonyTextureSupplier.isBestPony(entity) ? (isDinky(entity) ? egg2 : egg) : fallback.apply(entity);
} }
public static boolean isBestPony(LivingEntity entity) { public static boolean isBestPony(LivingEntity entity) {
@ -28,6 +28,10 @@ public class SillyPonyTextureSupplier {
return isBestPony(entity) && entity.getUuid().getLeastSignificantBits() % 20 == 0; return isBestPony(entity) && entity.getUuid().getLeastSignificantBits() % 20 == 0;
} }
public static boolean isDinky(LivingEntity entity) {
return entity.hasCustomName() && "Dinky".equals(entity.getCustomName().getString());
}
public static class State extends PonyRenderState implements VillagerDataContainer { public static class State extends PonyRenderState implements VillagerDataContainer {
public VillagerData villagerData; public VillagerData villagerData;

View file

@ -1,10 +1,11 @@
package com.minelittlepony.client.render.entity.npc.textures; package com.minelittlepony.client.render.entity.npc.textures;
import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.Util; import net.minecraft.util.Util;
import com.minelittlepony.client.MineLittlePony; import com.minelittlepony.client.MineLittlePony;
import com.minelittlepony.client.render.entity.state.PonyRenderState;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
@ -27,13 +28,13 @@ public interface TextureSupplier<T> extends Function<T, Identifier> {
return key -> Identifier.of(domain, String.format(path, key)); return key -> Identifier.of(domain, String.format(path, key));
} }
static <T extends PonyRenderState> TextureSupplier<T> ofVariations(Identifier poolId, TextureSupplier<T> fallback) { static <T extends Entity> TextureSupplier<T> ofVariations(Identifier poolId, TextureSupplier<T> fallback) {
return entity -> { return entity -> {
return MineLittlePony.getInstance().getVariatedTextures().get(poolId).getId(entity.attributes.getEntityId()).orElse(fallback.apply(entity)); return MineLittlePony.getInstance().getVariatedTextures().get(poolId).getId(entity.getUuid()).orElse(fallback.apply(entity));
}; };
} }
static <T extends PonyRenderState> TextureSupplier<T> ofPool(Identifier poolId, TextureSupplier<T> fallback) { static <T extends LivingEntity> TextureSupplier<T> ofPool(Identifier poolId, TextureSupplier<T> fallback) {
final BiFunction<String, UUID, Identifier> cache = Util.memoize((name, uuid) -> { final BiFunction<String, UUID, Identifier> cache = Util.memoize((name, uuid) -> {
return MineLittlePony.getInstance().getVariatedTextures() return MineLittlePony.getInstance().getVariatedTextures()
.get(poolId) .get(poolId)
@ -41,7 +42,7 @@ public interface TextureSupplier<T> extends Function<T, Identifier> {
.orElse(null); .orElse(null);
}); });
return entity -> { return entity -> {
Identifier override = entity.customName != null ? cache.apply(entity.customName.getString(), entity.attributes.getEntityId()) : null; Identifier override = entity.hasCustomName() ? cache.apply(entity.getCustomName().getString(), entity.getUuid()) : null;
if (override != null) { if (override != null) {
return override; return override;
} }

View file

@ -4,6 +4,9 @@ import net.minecraft.block.BedBlock;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState; import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.entity.EntityPose; import net.minecraft.entity.EntityPose;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.mob.AbstractPiglinEntity;
import net.minecraft.entity.mob.ZombifiedPiglinEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import com.minelittlepony.api.config.PonyConfig; import com.minelittlepony.api.config.PonyConfig;
@ -25,6 +28,7 @@ public class PonyRenderState extends PlayerEntityRenderState implements PonyMode
public boolean sleepingInBed; public boolean sleepingInBed;
public boolean submergedInWater; public boolean submergedInWater;
public boolean onGround; public boolean onGround;
public boolean isTechnoblade;
public Pony pony; public Pony pony;
@ -43,6 +47,13 @@ public class PonyRenderState extends PlayerEntityRenderState implements PonyMode
pose = EntityPose.SITTING; pose = EntityPose.SITTING;
} }
isTechnoblade = ((
entity instanceof AbstractPiglinEntity
|| entity instanceof PlayerEntity
|| entity instanceof ZombifiedPiglinEntity
) && entity.hasCustomName() && entity.getCustomName().getString().equalsIgnoreCase("technoblade")
);
PonyPosture.of(attributes).updateState(entity, this); PonyPosture.of(attributes).updateState(entity, this);
PonyModelPrepareCallback.EVENT.invoker().onPonyModelPrepared(attributes, model, ModelAttributes.Mode.OTHER); PonyModelPrepareCallback.EVENT.invoker().onPonyModelPrepared(attributes, model, ModelAttributes.Mode.OTHER);
} }
@ -114,7 +125,7 @@ public class PonyRenderState extends PlayerEntityRenderState implements PonyMode
* Tests if this model is wearing the given piece of gear. * Tests if this model is wearing the given piece of gear.
*/ */
public boolean isWearing(Wearable wearable) { public boolean isWearing(Wearable wearable) {
return isEmbedded(wearable) || attributes.featureSkins.contains(wearable.getId()); return isEmbedded(wearable) || attributes.featureSkins.contains(wearable.getId()) || isTechnoblade && wearable == Wearable.CROWN;
} }
/** /**

View file

@ -1,2 +1,4 @@
accessWidener v1 named accessWidener v1 named
accessible class net/minecraft/client/render/VertexConsumers$Union accessible class net/minecraft/client/render/VertexConsumers$Union
extendable method net/minecraft/client/model/Model render (Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;III)V