diff --git a/src/main/java/com/minelittlepony/api/model/HornedPonyModel.java b/src/main/java/com/minelittlepony/api/model/HornedPonyModel.java index c82d1629..b5833559 100644 --- a/src/main/java/com/minelittlepony/api/model/HornedPonyModel.java +++ b/src/main/java/com/minelittlepony/api/model/HornedPonyModel.java @@ -1,17 +1,15 @@ package com.minelittlepony.api.model; -import com.minelittlepony.client.render.entity.state.PonyRenderState; - -public interface HornedPonyModel extends PonyModel { - /** - * Returns true if this model is being applied to a race that can use magic. - */ - default boolean hasMagic(T state) { - return state.getRace().hasHorn() && state.attributes.metadata.glowColor() != 0; - } +import net.minecraft.client.render.entity.model.BipedEntityModel.ArmPose; +import net.minecraft.client.render.entity.state.*; +import net.minecraft.util.Arm; +public interface HornedPonyModel extends PonyModel { /** * Returns true if this model is currently using magic (horn is lit). */ - boolean isCasting(T state); + default boolean isCasting(T state) { + return state instanceof PlayerEntityRenderState s + && (getArmPoseForSide(s, Arm.LEFT) != ArmPose.EMPTY || getArmPoseForSide(s, Arm.RIGHT) != ArmPose.EMPTY); + } } diff --git a/src/main/java/com/minelittlepony/api/model/MobPosingHelper.java b/src/main/java/com/minelittlepony/api/model/MobPosingHelper.java index 49e8279b..f0749e87 100644 --- a/src/main/java/com/minelittlepony/api/model/MobPosingHelper.java +++ b/src/main/java/com/minelittlepony/api/model/MobPosingHelper.java @@ -30,26 +30,25 @@ public final class MobPosingHelper { arm.roll = cos; } - public static void rotateUndeadArms(PonyModel model, float move, float ticks) { - ModelPart leftArm = model.getForeLeg(Arm.LEFT); - ModelPart rightArm = model.getForeLeg(Arm.RIGHT); - - if (islookAngleRight(move)) { - rotateArmHolding(rightArm, 1, model.getSwingAmount(), ticks); - if (model.getAttributes().isSitting) { + public static void rotateUndeadArms(PonyModel.AttributedHolder attributes, PonyModel model, float limbAngle, float ticks) { + if (islookAngleRight(limbAngle)) { + ModelPart rightArm = model.getForeLeg(Arm.RIGHT); + rotateArmHolding(rightArm, 1, attributes.getSwingAmount(), ticks); + if (attributes.getAttributes().isSitting) { rightArm.pitch += 0.6F; } PartUtil.shift(rightArm, 0.5F, 1.5F, 3); } else { - rotateArmHolding(leftArm, -1, model.getSwingAmount(), ticks); - if (model.getAttributes().isSitting) { + ModelPart leftArm = model.getForeLeg(Arm.LEFT); + rotateArmHolding(leftArm, -1, attributes.getSwingAmount(), ticks); + if (attributes.getAttributes().isSitting) { leftArm.pitch += 0.6F; } PartUtil.shift(leftArm, -0.5F, 1.5F, 3); } } - public static boolean islookAngleRight(float move) { - return MathHelper.sin(move / 20) < 0; + public static boolean islookAngleRight(float limbAngle) { + return MathHelper.sin(limbAngle / 20) < 0; } } diff --git a/src/main/java/com/minelittlepony/api/model/ModelAttributes.java b/src/main/java/com/minelittlepony/api/model/ModelAttributes.java index 2ecc60bd..a8ba0eb9 100644 --- a/src/main/java/com/minelittlepony/api/model/ModelAttributes.java +++ b/src/main/java/com/minelittlepony/api/model/ModelAttributes.java @@ -186,6 +186,10 @@ public class ModelAttributes { return Interpolator.linear(interpolatorId); } + public UUID getEntityId() { + return interpolatorId; + } + public boolean shouldLiftArm(ArmPose pose, ArmPose complement, float sigma) { return pose != ArmPose.EMPTY && (pose != complement || sigma == (isLeftHanded ? 1 : -1)) diff --git a/src/main/java/com/minelittlepony/api/model/Models.java b/src/main/java/com/minelittlepony/api/model/Models.java index 3b1cd550..5abd3c91 100644 --- a/src/main/java/com/minelittlepony/api/model/Models.java +++ b/src/main/java/com/minelittlepony/api/model/Models.java @@ -1,57 +1,40 @@ package com.minelittlepony.api.model; -import net.minecraft.entity.LivingEntity; import net.minecraft.item.ArmorItem; import net.minecraft.item.ItemStack; +import net.minecraft.util.Util; import org.jetbrains.annotations.Nullable; -import com.minelittlepony.api.pony.PonyData; 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; /** * Container class for the various models and their associated piece of armour. */ -public class Models> { - @Nullable - private final MsonModel.Factory> armorFactory; - private final Map>, PonyArmourModel> armor = new HashMap<>(); +public record Models> ( + Function>, PonyArmourModel> armor, + M body + ) { - private final M body; - - public Models(PlayerModelKey playerModelKey, boolean slimArms, @Nullable Consumer initializer) { - this.armorFactory = playerModelKey.armorFactory(); - this.body = playerModelKey.getKey(slimArms).createModel(); + public Models(PlayerModelKey playerModelKey, boolean slimArms, @Nullable Consumer initializer) { + this(Util.memoize(key -> key.createModel(playerModelKey.armorFactory())), playerModelKey.getKey(slimArms).createModel()); if (initializer != null) { - initializer.accept(this.body); + initializer.accept(body); } } public Models(ModelKey key) { - this.armorFactory = null; - this.body = key.createModel(); + this(Util.memoize(k -> k.createModel()), key.createModel()); } - public M body() { - return body; - } - - public Optional> getArmourModel(ItemStack stack, ArmourLayer layer, ArmourVariant variant) { + public Optional> getArmourModel(ItemStack stack, ArmourLayer layer, ArmourVariant variant) { return ArmorModelRegistry.getModelKey(stack.getItem(), layer).or(() -> variant.getDefaultModel(layer).filter(l -> stack.getItem() instanceof ArmorItem)) - .map(key -> armor.computeIfAbsent(key, k -> { - return armorFactory == null ? k.createModel() : k.createModel(armorFactory); - })); - } - - public Models applyMetadata(PonyData meta) { - body.setMetadata(meta); - armor.values().forEach(a -> a.setMetadata(meta)); - return this; + .map(armor); } } diff --git a/src/main/java/com/minelittlepony/api/model/PonyModel.java b/src/main/java/com/minelittlepony/api/model/PonyModel.java index 63031652..60ec663e 100644 --- a/src/main/java/com/minelittlepony/api/model/PonyModel.java +++ b/src/main/java/com/minelittlepony/api/model/PonyModel.java @@ -2,12 +2,13 @@ package com.minelittlepony.api.model; import net.minecraft.client.model.ModelPart; import net.minecraft.client.render.entity.model.*; -import net.minecraft.client.render.entity.state.BipedEntityRenderState; +import net.minecraft.client.render.entity.state.EntityRenderState; import net.minecraft.client.util.math.MatrixStack; +import com.minelittlepony.api.pony.meta.Race; import com.minelittlepony.mson.api.MsonModel; -public interface PonyModel extends MsonModel, ModelWithHooves, ModelWithHat, ModelWithHead { +public interface PonyModel extends MsonModel, ModelWithHooves, ModelWithHat, ModelWithHead { ModelPart getBodyPart(BodyPart part); @@ -18,5 +19,9 @@ public interface PonyModel> extends PonyModel { - M mixin(); - - @Override - default void init(ModelView context) { - mixin().init(context); - if (mixin() instanceof RenderLayerSetter && this instanceof RenderLayerSetter) { - ((RenderLayerSetter)this).setRenderLayerFactory(((RenderLayerSetter)mixin()).getRenderLayerFactory()); - } - } - - @Override - default void updateLivingState(T entity, Pony pony, ModelAttributes.Mode mode) { - mixin().updateLivingState(entity, pony, mode); - } - - @Override - default void copyAttributes(BipedEntityModel other) { - mixin().copyAttributes(other); - } - - @Override - default void transform(BodyPart part, MatrixStack stack) { - mixin().transform(part, stack); - } - - @Override - default ModelAttributes getAttributes() { - return mixin().getAttributes(); - } - - @Override - default Size getSize() { - return mixin().getSize(); - } - - @Override - default void setMetadata(PonyData meta) { - mixin().setMetadata(meta); - } - - @Override - default float getSwingAmount() { - return mixin().getSwingAmount(); - } - - @Override - default float getWobbleAmount() { - return mixin().getWobbleAmount(); - } - - @Override - default float getRiderYOffset() { - return mixin().getRiderYOffset(); - } - - - @Override - default ModelPart getForeLeg(Arm side) { - return mixin().getForeLeg(side); - } - - @Override - default ModelPart getHindLeg(Arm side) { - return mixin().getHindLeg(side); - } - - @Override - default ArmPose getArmPoseForSide(Arm side) { - return mixin().getArmPoseForSide(side); - } - - @Override - default void setArmAngle(Arm arm, MatrixStack stack) { - if (mixin() instanceof ModelWithArms) { - ((ModelWithArms)mixin()).setArmAngle(arm, stack); - } - } - - @Override - default ModelPart getHead() { - return mixin().getHead(); - } - - @Override - default ModelPart getBodyPart(BodyPart part) { - return mixin().getBodyPart(part); - } - - @Override - default void setHatVisible(boolean hatVisible) { - mixin().setHatVisible(hatVisible); - } - - interface Caster & HornedPonyModel, ArmModel> extends PonyModelMixin, HornedPonyModel { - @Override - default boolean isCasting() { - return mixin().isCasting(); - } - } -} diff --git a/src/main/java/com/minelittlepony/api/model/SubModel.java b/src/main/java/com/minelittlepony/api/model/SubModel.java index 9624d758..533e4e75 100644 --- a/src/main/java/com/minelittlepony/api/model/SubModel.java +++ b/src/main/java/com/minelittlepony/api/model/SubModel.java @@ -1,25 +1,26 @@ package com.minelittlepony.api.model; import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.entity.state.BipedEntityRenderState; import net.minecraft.client.util.math.MatrixStack; -public interface SubModel { +public interface SubModel { /** * Sets the model's various rotation angles. */ - default void setPartAngles(ModelAttributes attributes, float limbAngle, float limbSpeed, float bodySwing, float animationProgress) { + default void setPartAngles(T state, float limbAngle, float limbSpeed, float bodySwing, float animationProgress) { } /** * Renders this model component. */ - void renderPart(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color, ModelAttributes attributes); + void renderPart(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color); /** * Sets whether this part should be rendered. */ - default void setVisible(boolean visible, ModelAttributes attributes) { + default void setVisible(boolean visible, T state) { } } diff --git a/src/main/java/com/minelittlepony/api/model/WingedPonyModel.java b/src/main/java/com/minelittlepony/api/model/WingedPonyModel.java index 72312e9a..4d0fd3d9 100644 --- a/src/main/java/com/minelittlepony/api/model/WingedPonyModel.java +++ b/src/main/java/com/minelittlepony/api/model/WingedPonyModel.java @@ -11,6 +11,11 @@ public interface WingedPonyModel getWings(); + /** * Returns true if the wings are spread. */ @@ -25,11 +30,6 @@ public interface WingedPonyModel & PonyModel> void transform(M model, MatrixStack matrices) { + default void transform(S state, PonyModel model, MatrixStack matrices) { BodyPart part = getGearLocation(); - model.transform(part, matrices); + model.transform(state, part, matrices); model.getBodyPart(part).rotate(matrices); } @@ -86,7 +85,7 @@ public interface Gear { * * See {@link AbstractPonyMode.setRotationAndAngle} for an explanation of the various parameters. */ - default void pose(PonyModel model, Entity entity, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) { + default void pose(PonyModel model, S state, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) { } diff --git a/src/main/java/com/minelittlepony/api/model/gear/WearableGear.java b/src/main/java/com/minelittlepony/api/model/gear/WearableGear.java index 4aacbf7e..b227d87b 100644 --- a/src/main/java/com/minelittlepony/api/model/gear/WearableGear.java +++ b/src/main/java/com/minelittlepony/api/model/gear/WearableGear.java @@ -1,12 +1,13 @@ package com.minelittlepony.api.model.gear; import net.minecraft.client.model.ModelPart; -import net.minecraft.entity.Entity; +import net.minecraft.client.render.entity.state.EntityRenderState; import net.minecraft.util.Identifier; import com.minelittlepony.api.model.BodyPart; import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.api.pony.meta.Wearable; +import com.minelittlepony.client.render.entity.state.PonyRenderState; public class WearableGear extends AbstractGearModel { @@ -25,12 +26,12 @@ public class WearableGear extends AbstractGearModel { } @Override - public boolean canRender(PonyModel model, Entity entity) { - return model.isWearing(wearable); + public boolean canRender(PonyModel model, EntityRenderState entity) { + return entity instanceof PonyRenderState state && state.isWearing(wearable); } @Override - public Identifier getTexture(T entity, Context context) { + public Identifier getTexture(S entity, Context context) { return context.getDefaultTexture(entity, wearable); } } diff --git a/src/main/java/com/minelittlepony/client/PonyBounds.java b/src/main/java/com/minelittlepony/client/PonyBounds.java deleted file mode 100644 index ae88e153..00000000 --- a/src/main/java/com/minelittlepony/client/PonyBounds.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.minelittlepony.client; - -import com.minelittlepony.api.pony.Pony; - -import net.minecraft.client.MinecraftClient; -import net.minecraft.entity.LivingEntity; -import net.minecraft.util.math.Box; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.Vec3d; - -public class PonyBounds { - private static Vec3d getBaseRidingOffset(LivingEntity entity) { - float delta = MinecraftClient.getInstance().getRenderTickCounter().getTickDelta(false); - return new Vec3d( - MathHelper.lerp(delta, entity.prevX, entity.getX()), - MathHelper.lerp(delta, entity.prevY, entity.getY()), - MathHelper.lerp(delta, entity.prevZ, entity.getZ()) - ); - } - - public static Box getBoundingBox(Pony pony, LivingEntity entity) { - final float scale = pony.size().scaleFactor(); - final float width = entity.getWidth() * scale; - final float height = entity.getHeight() * scale; - - return new Box(-width, 0, -width, width, height, width).offset(getBaseRidingOffset(entity)); - } -} diff --git a/src/main/java/com/minelittlepony/client/PonyManagerImpl.java b/src/main/java/com/minelittlepony/client/PonyManagerImpl.java index 4b68eecd..1bd21148 100644 --- a/src/main/java/com/minelittlepony/client/PonyManagerImpl.java +++ b/src/main/java/com/minelittlepony/client/PonyManagerImpl.java @@ -11,8 +11,9 @@ import com.minelittlepony.client.render.blockentity.skull.PonySkullRenderer; import org.jetbrains.annotations.Nullable; import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener; -import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.AbstractClientPlayerEntity; +import net.minecraft.client.render.entity.LivingEntityRenderer; +import net.minecraft.client.render.entity.state.LivingEntityRenderState; import net.minecraft.client.util.DefaultSkinHelper; import net.minecraft.resource.ResourceManager; import net.minecraft.server.network.ServerPlayerEntity; @@ -108,6 +109,7 @@ public class PonyManagerImpl implements PonyManager, SimpleSynchronousResourceRe return loadPony(DefaultSkinHelper.getSkinTextures(uuid).texture(), true); } + @SuppressWarnings("unchecked") @Nullable private Identifier getSkin(LivingEntity entity) { if (entity instanceof PlayerEntity player) { @@ -115,8 +117,8 @@ public class PonyManagerImpl implements PonyManager, SimpleSynchronousResourceRe return clientPlayer.getSkinTextures().texture(); } } else { - if (MineLittlePony.getInstance().getRenderDispatcher().getPonyRenderer(entity) != null) { - return MinecraftClient.getInstance().getEntityRenderDispatcher().getRenderer(entity).getTexture(entity); + if (MineLittlePony.getInstance().getRenderDispatcher().getPonyRenderer(entity) instanceof LivingEntityRenderer renderer) { + return renderer.getTexture((LivingEntityRenderState)renderer.getAndUpdateRenderState(entity, 1)); } } diff --git a/src/main/java/com/minelittlepony/client/model/AbstractPonyModel.java b/src/main/java/com/minelittlepony/client/model/AbstractPonyModel.java index 929c34b2..f4c38b3e 100644 --- a/src/main/java/com/minelittlepony/client/model/AbstractPonyModel.java +++ b/src/main/java/com/minelittlepony/client/model/AbstractPonyModel.java @@ -57,7 +57,7 @@ public abstract class AbstractPonyModel extends Clien protected final RenderList mainRenderList; - private final List parts = new ArrayList<>(); + private final List> parts = new ArrayList<>(); @Nullable protected T currentState; @@ -76,17 +76,17 @@ public abstract class AbstractPonyModel extends Clien .add(withStage(BodyPart.HEAD, helmetRenderList = RenderList.of(hat))); } - protected

P addPart(P part) { + protected

> P addPart(P part) { parts.add(part); return part; } - protected RenderList forPart(Supplier part) { - return (stack, vertices, overlay, light, color) -> part.get().renderPart(stack, vertices, overlay, light, color, currentState.attributes); + protected RenderList forPart(Supplier> part) { + return (stack, vertices, overlay, light, color) -> part.get().renderPart(stack, vertices, overlay, light, color); } - protected RenderList forPart(SubModel part) { - return (stack, vertices, overlay, light, color) -> part.renderPart(stack, vertices, overlay, light, color, currentState.attributes); + protected RenderList forPart(SubModel part) { + return (stack, vertices, overlay, light, color) -> part.renderPart(stack, vertices, overlay, light, color); } protected RenderList withStage(BodyPart part, RenderList action) { @@ -127,7 +127,7 @@ public abstract class AbstractPonyModel extends Clien protected void setModelVisibilities(T state) { hat.visible = head.visible && !state.attributes.isHorsey; - parts.forEach(part -> part.setVisible(body.visible, state.attributes)); + parts.forEach(part -> part.setVisible(body.visible, state)); } protected void setModelAngles(T entity) { @@ -147,7 +147,7 @@ public abstract class AbstractPonyModel extends Clien body.yaw = wobbleAmount; neck.yaw = wobbleAmount; - rotateLegs(entity, limbAngle, limbSpeed, animationProgress, entity); + rotateLegs(entity, limbAngle, limbSpeed, animationProgress); ArmPose left = getArmPose(entity, Arm.LEFT); ArmPose right = getArmPose(entity, Arm.RIGHT); @@ -188,7 +188,7 @@ public abstract class AbstractPonyModel extends Clien head.pitch = 0.5F; } - parts.forEach(part -> part.setPartAngles(entity.attributes, limbAngle, limbSpeed, wobbleAmount, animationProgress)); + parts.forEach(part -> part.setPartAngles(entity, limbAngle, limbSpeed, wobbleAmount, animationProgress)); } public void setHeadRotation(float animationProgress, float yaw, float pitch) { @@ -253,11 +253,11 @@ public abstract class AbstractPonyModel extends Clien * Takes the same parameters as {@link AbstractPonyModel.setRotationAndAngles} * */ - protected void rotateLegs(T state, float move, float swing, float ticks, T entity) { + protected void rotateLegs(T state, float move, float swing, float ticks) { if (state.attributes.isSwimming) { - rotateLegsSwimming(state, move, swing, ticks, entity); + rotateLegsSwimming(state, move, swing, ticks); } else { - rotateLegsOnGround(state, move, swing, ticks, entity); + rotateLegsOnGround(state, move, swing, ticks); } float sin = MathHelper.sin(body.yaw) * 5; @@ -293,14 +293,14 @@ public abstract class AbstractPonyModel extends Clien * * Takes the same parameters as {@link AbstractPonyModel.setRotationAndAngles} */ - protected void rotateLegsSwimming(T state, float move, float swing, float ticks, T entity) { + protected void rotateLegsSwimming(T state, @Deprecated float move, @Deprecated float swing, @Deprecated float ticks) { - float lerp = entity.isInPose(EntityPose.SWIMMING) ? (float)state.attributes.motionLerp : 1; + float lerp = state.isInPose(EntityPose.SWIMMING) ? (float)state.attributes.motionLerp : 1; - float legLeft = (MathUtil.Angles._90_DEG + MathHelper.sin((move / 3) + 2 * MathHelper.PI/3) / 2) * lerp; + float legLeft = (MathUtil.Angles._90_DEG + MathHelper.sin((state.limbFrequency / 3) + 2 * MathHelper.PI/3) / 2) * lerp; - float left = (MathUtil.Angles._90_DEG + MathHelper.sin((move / 3) + 2 * MathHelper.PI) / 2) * lerp; - float right = (MathUtil.Angles._90_DEG + MathHelper.sin(move / 3) / 2) * lerp; + float left = (MathUtil.Angles._90_DEG + MathHelper.sin((state.limbFrequency / 3) + 2 * MathHelper.PI) / 2) * lerp; + float right = (MathUtil.Angles._90_DEG + MathHelper.sin(state.limbFrequency / 3) / 2) * lerp; leftArm.setAngles(-left, -left/2, left/2); rightArm.setAngles(-right, right/2, -right/2); @@ -312,7 +312,7 @@ public abstract class AbstractPonyModel extends Clien * Rotates legs in quopy fashion for walking. * */ - protected void rotateLegsOnGround(T state, float move, float swing, float ticks, T entity) { + protected void rotateLegsOnGround(T state, float move, float swing, float ticks) { float angle = MathHelper.PI * (float) Math.pow(swing, 16); float baseRotation = move * 0.6662F; // magic number ahoy @@ -545,7 +545,7 @@ public abstract class AbstractPonyModel extends Clien @Override public final void setArmAngle(Arm arm, MatrixStack matrices) { super.setArmAngle(arm, matrices); - positionheldItem(arm, matrices); + positionheldItem(currentState, arm, matrices); } protected void positionheldItem(T state, Arm arm, MatrixStack matrices) { @@ -600,6 +600,6 @@ public abstract class AbstractPonyModel extends Clien neck.hidden = !head.visible; } - PonyTransformation.forSize(state.getSize()).transform(this, part, stack); + PonyTransformation.forSize(state.getSize()).transform(state.attributes, part, stack); } } diff --git a/src/main/java/com/minelittlepony/client/model/ModelType.java b/src/main/java/com/minelittlepony/client/model/ModelType.java index fa5c8e61..ab13364d 100644 --- a/src/main/java/com/minelittlepony/client/model/ModelType.java +++ b/src/main/java/com/minelittlepony/client/model/ModelType.java @@ -4,8 +4,6 @@ import net.minecraft.client.model.Model; import net.minecraft.client.model.ModelPart; import net.minecraft.client.render.entity.model.ArmorStandEntityModel; import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.mob.VexEntity; -import net.minecraft.entity.passive.*; import com.minelittlepony.api.model.BodyPart; import com.minelittlepony.api.model.PonyModel; @@ -29,7 +27,7 @@ import java.util.function.BiFunction; import java.util.stream.Stream; public final class ModelType { - private static final Map> PLAYER_MODELS = new HashMap<>(); + private static final Map> PLAYER_MODELS = new HashMap<>(); private static final Map> GEAR_MODELS = new HashMap<>(); public static final ModelKey DJ_PON_3 = register("dj_pon_three", DJPon3EarsModel::new); @@ -41,12 +39,12 @@ public final class ModelType { public static final ModelKey> SKELETON_CLOTHES = register("skeleton_clothes", SkeleponyModel::new); public static final ModelKey PILLAGER = register("pillager", PillagerPonyModel::new); public static final ModelKey> ILLAGER = register("illager", IllagerPonyModel::new); - public static final ModelKey GUARDIAN = register("guardian", GuardianPonyModel::new); + public static final ModelKey> GUARDIAN = register("guardian", SeaponyModel::new); public static final ModelKey ENDERMAN = register("enderman", EnderStallionModel::new); - public static final ModelKey> VEX = register("vex", ParaspriteModel::new); - public static final ModelKey> STRIDER = register("strider", SpikeModel::new); - public static final ModelKey> STRIDER_SADDLE = register("strider_saddle", SaddleModel::new); - public static final ModelKey> ALLAY = register("allay", BreezieModel::new); + public static final ModelKey VEX = register("vex", ParaspriteModel::new); + public static final ModelKey STRIDER = register("strider", SpikeModel::new); + public static final ModelKey STRIDER_SADDLE = register("strider_saddle", SaddleModel::new); + public static final ModelKey ALLAY = register("allay", BreezieModel::new); public static final ModelKey> ELYTRA = register("elytra", PonyElytra::new); @@ -56,38 +54,38 @@ public final class ModelType { public static final ModelKey> INNER_PONY_ARMOR = register("armor/inner_pony_armor", PonyArmourModel::new); public static final ModelKey> OUTER_PONY_ARMOR = register("armor/outer_pony_armor", PonyArmourModel::new); - public static final GearModelKey STETSON = registerGear("stetson", Wearable.STETSON, t -> new WearableGear(Wearable.STETSON, BodyPart.HEAD, 0.15F).addPart(t)); + public static final GearModelKey STETSON = registerGear("stetson", Wearable.STETSON, t -> new WearableGear(t, Wearable.STETSON, BodyPart.HEAD, 0.15F)); public static final GearModelKey SADDLEBAGS_BOTH = registerGear("saddlebags", Wearable.SADDLE_BAGS_BOTH, t -> new SaddleBags(t, Wearable.SADDLE_BAGS_BOTH)); public static final GearModelKey SADDLEBAGS_LEFT = registerGear(SADDLEBAGS_BOTH, Wearable.SADDLE_BAGS_LEFT, t -> new SaddleBags(t, Wearable.SADDLE_BAGS_LEFT)); public static final GearModelKey SADDLEBAGS_RIGHT = registerGear(SADDLEBAGS_BOTH, Wearable.SADDLE_BAGS_RIGHT, t -> new SaddleBags(t, Wearable.SADDLE_BAGS_RIGHT)); public static final GearModelKey CROWN = registerGear("crown", Wearable.CROWN, Crown::new); - public static final GearModelKey MUFFIN = registerGear("muffin", Wearable.MUFFIN, t -> new WearableGear(Wearable.MUFFIN, BodyPart.HEAD, 0.45F).addPart(t.getChild("crown"))); - public static final GearModelKey WITCH_HAT = registerGear("witch_hat", Wearable.HAT, t -> new WearableGear(Wearable.HAT, BodyPart.HEAD, 0.7F).addPart(t.getChild("hat"))); + public static final GearModelKey MUFFIN = registerGear("muffin", Wearable.MUFFIN, t -> new WearableGear(t.getChild("crown"), Wearable.MUFFIN, BodyPart.HEAD, 0.45F)); + public static final GearModelKey WITCH_HAT = registerGear("witch_hat", Wearable.HAT, t -> new WearableGear(t.getChild("hat"), Wearable.HAT, BodyPart.HEAD, 0.7F)); public static final GearModelKey ANTLERS = registerGear("antlers", Wearable.ANTLERS, DeerAntlers::new); - public static final PlayerModelKey> ALICORN = registerPlayer("alicorn", Race.ALICORN, AlicornModel::new); - public static final PlayerModelKey> UNICORN = registerPlayer("unicorn", Race.UNICORN, UnicornModel::new); - public static final PlayerModelKey> KIRIN = registerPlayer("kirin", Race.KIRIN, KirinModel::new); - public static final PlayerModelKey> PEGASUS = registerPlayer("pegasus", Race.PEGASUS, PegasusModel::new); - public static final PlayerModelKey> GRYPHON = registerPlayer("gryphon", Race.GRYPHON, PegasusModel::new); - public static final PlayerModelKey> HIPPOGRIFF = registerPlayer("hippogriff", Race.HIPPOGRIFF, PegasusModel::new, PonyArmourModel::new); - public static final PlayerModelKey> EARTH_PONY = registerPlayer("earth_pony", Race.EARTH, EarthPonyModel::new); - public static final PlayerModelKey> SEA_PONY = registerPlayer("sea_pony", Race.SEAPONY, SeaponyModel::new, SeaponyModel.Armour::new); - public static final PlayerModelKey> BAT_PONY = registerPlayer("bat_pony", Race.BATPONY, PegasusModel::new); - public static final PlayerModelKey> CHANGELING = registerPlayer("changeling", Race.CHANGELING, ChangelingModel::new); - public static final PlayerModelKey> CHANGEDLING = registerPlayer("reformed_changeling", Race.CHANGEDLING, ChangelingModel::new); - public static final PlayerModelKey> ZEBRA = registerPlayer("zebra", Race.ZEBRA, EarthPonyModel::new); + public static final PlayerModelKey> ALICORN = registerPlayer("alicorn", Race.ALICORN, AlicornModel::new); + public static final PlayerModelKey> UNICORN = registerPlayer("unicorn", Race.UNICORN, UnicornModel::new); + public static final PlayerModelKey> KIRIN = registerPlayer("kirin", Race.KIRIN, KirinModel::new); + public static final PlayerModelKey> PEGASUS = registerPlayer("pegasus", Race.PEGASUS, PegasusModel::new); + public static final PlayerModelKey> GRYPHON = registerPlayer("gryphon", Race.GRYPHON, PegasusModel::new); + public static final PlayerModelKey> HIPPOGRIFF = registerPlayer("hippogriff", Race.HIPPOGRIFF, PegasusModel::new, PonyArmourModel::new); + public static final PlayerModelKey> EARTH_PONY = registerPlayer("earth_pony", Race.EARTH, EarthPonyModel::new); + public static final PlayerModelKey> SEA_PONY = registerPlayer("sea_pony", Race.SEAPONY, SeaponyModel::new, SeaponyModel.Armour::new); + public static final PlayerModelKey> BAT_PONY = registerPlayer("bat_pony", Race.BATPONY, PegasusModel::new); + public static final PlayerModelKey> CHANGELING = registerPlayer("changeling", Race.CHANGELING, ChangelingModel::new); + public static final PlayerModelKey> CHANGEDLING = registerPlayer("reformed_changeling", Race.CHANGEDLING, ChangelingModel::new); + public static final PlayerModelKey> ZEBRA = registerPlayer("zebra", Race.ZEBRA, EarthPonyModel::new); - static > PlayerModelKey registerPlayer(String name, Race race, + static > PlayerModelKey registerPlayer(String name, Race race, BiFunction constructor) { return registerPlayer(name, race, constructor, PonyArmourModel::new); } @SuppressWarnings("unchecked") - static > PlayerModelKey registerPlayer(String name, Race race, + static > PlayerModelKey registerPlayer(String name, Race race, BiFunction constructor, - MsonModel.Factory> armorFactory) { - return (PlayerModelKey)PLAYER_MODELS.computeIfAbsent(race, r -> new PlayerModelKey<>(name, constructor, armorFactory)); + MsonModel.Factory> armorFactory) { + return (PlayerModelKey)PLAYER_MODELS.computeIfAbsent(race, r -> new PlayerModelKey(name, constructor, armorFactory)); } @SuppressWarnings("unchecked") @@ -108,8 +106,8 @@ public final class ModelType { @SuppressWarnings("unchecked") @Nullable - public static > PlayerModelKey getPlayerModel(Race race) { - return (PlayerModelKey)PLAYER_MODELS.get(race); + public static > PlayerModelKey getPlayerModel(Race race) { + return (PlayerModelKey)PLAYER_MODELS.get(race); } public static Stream>> getWearables() { diff --git a/src/main/java/com/minelittlepony/client/model/PlayerModelKey.java b/src/main/java/com/minelittlepony/client/model/PlayerModelKey.java index 36e0f08e..d0de3d97 100644 --- a/src/main/java/com/minelittlepony/client/model/PlayerModelKey.java +++ b/src/main/java/com/minelittlepony/client/model/PlayerModelKey.java @@ -2,7 +2,6 @@ package com.minelittlepony.client.model; import net.minecraft.client.model.Model; import net.minecraft.client.model.ModelPart; -import net.minecraft.entity.LivingEntity; import org.jetbrains.annotations.Nullable; @@ -14,12 +13,15 @@ import com.minelittlepony.mson.api.*; import java.util.function.*; -public record PlayerModelKey> ( +public record PlayerModelKey> ( ModelKey steveKey, ModelKey alexKey, - MsonModel.Factory> armorFactory + MsonModel.Factory> armorFactory ) { - PlayerModelKey(String name, BiFunction modelFactory, MsonModel.Factory> armorFactory) { + PlayerModelKey(String name, + BiFunction modelFactory, + MsonModel.Factory> armorFactory + ) { this( new ModelKeyImpl<>(MineLittlePony.id("races/steve/" + name), tree -> modelFactory.apply(tree, false)), new ModelKeyImpl<>(MineLittlePony.id("races/alex/" + name), tree -> modelFactory.apply(tree, true)), @@ -31,12 +33,11 @@ public record PlayerModelKey Models create(boolean slimArms) { + public Models create(boolean slimArms) { return create(slimArms, null); } - @SuppressWarnings({"rawtypes", "unchecked"}) - public Models create(boolean slimArms, @Nullable Consumer initializer) { - return new Models(this, slimArms, initializer); + public Models create(boolean slimArms, @Nullable Consumer initializer) { + return new Models<>(this, slimArms, initializer); } } diff --git a/src/main/java/com/minelittlepony/client/model/PonyElytra.java b/src/main/java/com/minelittlepony/client/model/PonyElytra.java index 466b3f11..0ab58496 100644 --- a/src/main/java/com/minelittlepony/client/model/PonyElytra.java +++ b/src/main/java/com/minelittlepony/client/model/PonyElytra.java @@ -1,90 +1,30 @@ package com.minelittlepony.client.model; import net.minecraft.client.model.ModelPart; -import net.minecraft.client.network.AbstractClientPlayerEntity; -import net.minecraft.client.render.entity.model.AnimalModel; -import net.minecraft.entity.LivingEntity; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.Vec3d; - -import com.google.common.collect.ImmutableList; +import net.minecraft.client.render.entity.model.EntityModel; +import net.minecraft.client.render.entity.state.BipedEntityRenderState; /** * Modified from ModelElytra. */ -public class PonyElytra extends AnimalModel { +public class PonyElytra extends EntityModel { public boolean isSneaking; private final ModelPart rightWing; private final ModelPart leftWing; - public PonyElytra(ModelPart tree) { - rightWing = tree.getChild("right_wing"); - leftWing = tree.getChild("left_wing"); + public PonyElytra(ModelPart root) { + super(root); + rightWing = root.getChild("right_wing"); + leftWing = root.getChild("left_wing"); } @Override - protected Iterable getHeadParts() { - return ImmutableList.of(); - } - - @Override - protected Iterable getBodyParts() { - return ImmutableList.of(leftWing, rightWing); - } - - /** - * Sets the model's various rotation angles. - * - * See {@link AbstractPonyModel.setRotationAngles} for an explanation of the various parameters. - */ - @Override - public void setAngles(T entity, float limbDistance, float limbAngle, float age, float headYaw, float headPitch) { - float rotateX = MathHelper.PI / 2; - float rotateY = MathHelper.PI / 8; - float rotateZ = MathHelper.PI / 12; - - float rpY = 0; - - if (entity.isFallFlying()) { - float velY = 1; - - Vec3d motion = entity.getVelocity(); - if (motion.y < 0) { - velY = 1 - (float) Math.pow(-motion.normalize().y, 1.5); - } - - rotateX = velY * MathHelper.PI * (2 / 3F) + (1 - velY) * rotateX; - rotateY = velY * (MathHelper.PI / 2) + (1 - velY) * rotateY; - } else if (isSneaking) { - rotateX = MathHelper.PI * 1.175F; - rotateY = MathHelper.PI / 2; - rotateZ = MathHelper.PI / 4; - rpY = AbstractPonyModel.BODY_SNEAKING.y(); - } - - leftWing.pivotX = 5; - leftWing.pivotY = rpY; - - if (entity instanceof AbstractClientPlayerEntity) { - AbstractClientPlayerEntity player = (AbstractClientPlayerEntity) entity; - - player.elytraPitch += (rotateX - player.elytraPitch) / 10; - player.elytraYaw += (rotateY - player.elytraYaw) / 10; - player.elytraRoll += (rotateZ - player.elytraRoll) / 10; - - leftWing.pitch = player.elytraPitch; - leftWing.yaw = player.elytraYaw; - leftWing.roll = player.elytraRoll; - } else { - leftWing.pitch = rotateX; - leftWing.yaw = rotateZ; - leftWing.roll = rotateY; - } - - rightWing.pivotX = -leftWing.pivotX; - rightWing.pivotY = leftWing.pivotY; + public void setAngles(T state) { + leftWing.pitch = state.leftWingPitch; + leftWing.yaw = state.leftWingYaw; + leftWing.roll = state.leftWingRoll; rightWing.pitch = leftWing.pitch; rightWing.yaw = -leftWing.yaw; rightWing.roll = -leftWing.roll; diff --git a/src/main/java/com/minelittlepony/client/model/armour/ArmourRendererPlugin.java b/src/main/java/com/minelittlepony/client/model/armour/ArmourRendererPlugin.java index d26b8f24..ff0c79a1 100644 --- a/src/main/java/com/minelittlepony/client/model/armour/ArmourRendererPlugin.java +++ b/src/main/java/com/minelittlepony/client/model/armour/ArmourRendererPlugin.java @@ -3,6 +3,8 @@ package com.minelittlepony.client.model.armour; import net.minecraft.client.MinecraftClient; import net.minecraft.client.model.Model; import net.minecraft.client.render.*; +import net.minecraft.client.render.entity.state.BipedEntityRenderState; +import net.minecraft.client.render.entity.state.LivingEntityRenderState; import net.minecraft.client.render.item.ItemRenderer; import net.minecraft.client.texture.Sprite; import net.minecraft.client.texture.SpriteAtlasTexture; @@ -11,11 +13,11 @@ import net.minecraft.component.type.DyedColorComponent; import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.LivingEntity; import net.minecraft.item.*; -import net.minecraft.item.trim.ArmorTrim; -import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.item.equipment.EquipmentModel; +import net.minecraft.item.equipment.EquipmentModel.LayerType; +import net.minecraft.item.equipment.trim.ArmorTrim; import net.minecraft.registry.tag.ItemTags; -import net.minecraft.util.Colors; -import net.minecraft.util.Identifier; +import net.minecraft.util.*; import org.jetbrains.annotations.Nullable; @@ -33,12 +35,20 @@ public interface ArmourRendererPlugin { return ArmourTextureResolver.INSTANCE; } - default void onArmourRendered(LivingEntity entity, MatrixStack matrices, VertexConsumerProvider provider, EquipmentSlot armorSlot, ArmourLayer layer, ArmourType type) { + default void onArmourRendered(LivingEntityRenderState state, MatrixStack matrices, VertexConsumerProvider provider, EquipmentSlot armorSlot, ArmourLayer layer, ArmourType type) { } - default ItemStack[] getArmorStacks(LivingEntity entity, EquipmentSlot armorSlot, ArmourLayer layer, ArmourType type) { - return new ItemStack[] { entity.getEquippedStack(armorSlot) }; + default ItemStack[] getArmorStacks(BipedEntityRenderState state, EquipmentSlot armorSlot, ArmourLayer layer, ArmourType type) { + return new ItemStack[] { switch (armorSlot) { + case HEAD -> state.equippedHeadStack; + case CHEST -> state.equippedChestStack; + case LEGS -> state.equippedLegsStack; + case FEET -> state.equippedFeetStack; + case BODY -> state.equippedChestStack; + case MAINHAND -> state.getMainHandStack(); + case OFFHAND -> state.mainArm == Arm.LEFT ? state.leftHandStack : state.rightHandStack; + }}; } default float getGlintAlpha(EquipmentSlot slot, ItemStack stack) { @@ -49,51 +59,51 @@ public interface ArmourRendererPlugin { return stack.isIn(ItemTags.DYEABLE) ? DyedColorComponent.getColor(stack, -6265536) : Colors.WHITE; } - default float getArmourAlpha(EquipmentSlot slot, ArmourLayer layer) { + default float getArmourAlpha(EquipmentSlot slot, LayerType layer) { return 1F; } - default float getTrimAlpha(EquipmentSlot slot, RegistryEntry material, ArmorTrim trim, ArmourLayer layer) { + default float getTrimAlpha(EquipmentSlot slot, ArmorTrim trim, LayerType layer) { return 1F; } - default float getElytraAlpha(ItemStack stack, Model model, LivingEntity entity) { + default float getElytraAlpha(ItemStack stack, Model model, LivingEntityRenderState entity) { return stack.isOf(Items.ELYTRA) ? 1F : 0F; } @Nullable - default VertexConsumer getTrimConsumer(EquipmentSlot slot, VertexConsumerProvider provider, RegistryEntry material, ArmorTrim trim, ArmourLayer layer) { - @Nullable VertexConsumer buffer = getOptionalBuffer(provider, getTrimLayer(slot, material, trim, layer)); + default VertexConsumer getTrimConsumer(EquipmentSlot slot, VertexConsumerProvider provider, ArmorTrim trim, LayerType layerType, Identifier modelId) { + @Nullable VertexConsumer buffer = getOptionalBuffer(provider, getTrimLayer(slot, trim, layerType, modelId)); if (buffer == null) { return null; } SpriteAtlasTexture armorTrimsAtlas = MinecraftClient.getInstance().getBakedModelManager().getAtlas(TexturedRenderLayers.ARMOR_TRIMS_ATLAS_TEXTURE); - Sprite sprite = armorTrimsAtlas.getSprite(layer == ArmourLayer.INNER ? trim.getLeggingsModelId(material) : trim.getGenericModelId(material)); + Sprite sprite = armorTrimsAtlas.getSprite(trim.getTexture(layerType, modelId)); return sprite.getTextureSpecificVertexConsumer(buffer); } @Nullable - default RenderLayer getTrimLayer(EquipmentSlot slot, RegistryEntry material, ArmorTrim trim, ArmourLayer layer) { - return TexturedRenderLayers.getArmorTrims(trim.getPattern().value().decal()); + default RenderLayer getTrimLayer(EquipmentSlot slot, ArmorTrim trim, LayerType layerType, Identifier modelId) { + return TexturedRenderLayers.getArmorTrims(trim.pattern().value().decal()); } @Nullable - default VertexConsumer getArmourConsumer(EquipmentSlot slot, VertexConsumerProvider provider, Identifier texture, ArmourLayer layer) { + default VertexConsumer getArmourConsumer(EquipmentSlot slot, VertexConsumerProvider provider, Identifier texture, EquipmentModel.LayerType layer) { return getOptionalBuffer(provider, getArmourLayer(slot, texture, layer)); } @Nullable - default RenderLayer getArmourLayer(EquipmentSlot slot, Identifier texture, ArmourLayer layer) { + default RenderLayer getArmourLayer(EquipmentSlot slot, Identifier texture, EquipmentModel.LayerType layer) { return RenderLayer.getArmorCutoutNoCull(texture); } @Nullable - default VertexConsumer getGlintConsumer(EquipmentSlot slot, VertexConsumerProvider provider, ArmourLayer layer) { + default VertexConsumer getGlintConsumer(EquipmentSlot slot, VertexConsumerProvider provider, EquipmentModel.LayerType layer) { return getOptionalBuffer(provider, getGlintLayer(slot, layer)); } @Nullable - default RenderLayer getGlintLayer(EquipmentSlot slot, ArmourLayer layer) { + default RenderLayer getGlintLayer(EquipmentSlot slot, EquipmentModel.LayerType layer) { return RenderLayer.getArmorEntityGlint(); } @@ -110,9 +120,13 @@ public interface ArmourRendererPlugin { return RenderLayer.getEntitySolid(texture); } + /** + * @deprecated Method is no longer used + */ + @Deprecated @Nullable - default VertexConsumer getElytraConsumer(ItemStack stack, Model model, LivingEntity entity, VertexConsumerProvider provider, Identifier texture) { - return ItemRenderer.getDirectItemGlintConsumer(provider, model.getLayer(texture), false, getGlintAlpha(EquipmentSlot.CHEST, stack) > 0F); + default VertexConsumer getElytraConsumer(ItemStack stack, Model model, BipedEntityRenderState state, VertexConsumerProvider provider, Identifier texture) { + return ItemRenderer.getArmorGlintConsumer(provider, RenderLayer.getArmorCutoutNoCull(texture), getGlintAlpha(EquipmentSlot.CHEST, stack) > 0F); } @Nullable diff --git a/src/main/java/com/minelittlepony/client/model/armour/ArmourTextureLookup.java b/src/main/java/com/minelittlepony/client/model/armour/ArmourTextureLookup.java index 9364b39e..f5e33590 100644 --- a/src/main/java/com/minelittlepony/client/model/armour/ArmourTextureLookup.java +++ b/src/main/java/com/minelittlepony/client/model/armour/ArmourTextureLookup.java @@ -1,12 +1,8 @@ package com.minelittlepony.client.model.armour; -import net.minecraft.item.ArmorMaterial; import net.minecraft.item.ItemStack; - -import java.util.List; +import net.minecraft.item.equipment.EquipmentModel; public interface ArmourTextureLookup { - ArmourTexture getTexture(ItemStack stack, ArmourLayer layer, ArmorMaterial.Layer armorLayer); - - List getArmorLayers(ItemStack stack, int dyeColor); + ArmourTexture getTexture(ItemStack stack, ArmourLayer layerType, EquipmentModel.Layer layer); } diff --git a/src/main/java/com/minelittlepony/client/model/armour/ArmourTextureResolver.java b/src/main/java/com/minelittlepony/client/model/armour/ArmourTextureResolver.java index 235f83a0..bc73356d 100644 --- a/src/main/java/com/minelittlepony/client/model/armour/ArmourTextureResolver.java +++ b/src/main/java/com/minelittlepony/client/model/armour/ArmourTextureResolver.java @@ -4,15 +4,12 @@ import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.CustomModelDataComponent; import net.minecraft.item.*; -import net.minecraft.registry.Registries; +import net.minecraft.item.equipment.EquipmentModel; import net.minecraft.resource.ResourceManager; -import net.minecraft.util.Colors; +import net.minecraft.resource.ResourceReloader; import net.minecraft.util.Identifier; -import net.minecraft.util.profiler.Profiler; import com.google.common.cache.*; -import com.google.common.collect.Interner; -import com.google.common.collect.Interners; import com.minelittlepony.client.MineLittlePony; import java.util.*; @@ -39,14 +36,12 @@ public class ArmourTextureResolver implements ArmourTextureLookup, IdentifiableR public static final Identifier ID = MineLittlePony.id("armor_textures"); public static final ArmourTextureResolver INSTANCE = new ArmourTextureResolver(); - private static final Interner LAYER_INTERNER = Interners.newWeakInterner(); - private final LoadingCache layerCache = CacheBuilder.newBuilder() .expireAfterAccess(30, TimeUnit.SECONDS) .build(CacheLoader.from(parameters -> { - return Stream.of(ArmourTexture.legacy(parameters.material().getTexture(parameters.layer() == ArmourLayer.OUTER))).flatMap(i -> { + return Stream.of(ArmourTexture.legacy(parameters.material().textureId())).flatMap(i -> { if (parameters.layer() == ArmourLayer.OUTER) { - return Stream.of(i, ArmourTexture.legacy(parameters.material().getTexture(false))); + return Stream.of(i, ArmourTexture.legacy(parameters.material().textureId())); } return Stream.of(i); }).flatMap(i -> { @@ -56,15 +51,6 @@ public class ArmourTextureResolver implements ArmourTextureLookup, IdentifiableR return Stream.of(i); }).flatMap(this::performLookup).findFirst().orElse(ArmourTexture.UNKNOWN); })); - private final LoadingCache> nonDyedLayers = CacheBuilder.newBuilder() - .expireAfterAccess(30, TimeUnit.SECONDS) - .build(CacheLoader.from(material -> List.of(LAYER_INTERNER.intern(new ArmorMaterial.Layer(material, "", false))))); - private final LoadingCache> dyedLayers = CacheBuilder.newBuilder() - .expireAfterAccess(30, TimeUnit.SECONDS) - .build(CacheLoader.from(material -> List.of( - LAYER_INTERNER.intern(new ArmorMaterial.Layer(material, "", false)), - LAYER_INTERNER.intern(new ArmorMaterial.Layer(material, "overlay", true)) - ))); private Stream performLookup(ArmourTexture id) { List options = Stream.of(id) @@ -85,12 +71,10 @@ public class ArmourTextureResolver implements ArmourTextureLookup, IdentifiableR public void invalidate() { layerCache.invalidateAll(); - nonDyedLayers.invalidateAll(); - dyedLayers.invalidateAll(); } @Override - public CompletableFuture reload(Synchronizer synchronizer, ResourceManager manager, Profiler prepareProfiler, Profiler applyProfiler, Executor prepareExecutor, Executor applyExecutor) { + public CompletableFuture reload(ResourceReloader.Synchronizer synchronizer, ResourceManager manager, Executor prepareExecutor, Executor applyExecutor) { return CompletableFuture.runAsync(this::invalidate, prepareExecutor).thenCompose(synchronizer::whenPrepared); } @@ -100,24 +84,15 @@ public class ArmourTextureResolver implements ArmourTextureLookup, IdentifiableR } @Override - public ArmourTexture getTexture(ItemStack stack, ArmourLayer layer, ArmorMaterial.Layer armorLayer) { + public ArmourTexture getTexture(ItemStack stack, ArmourLayer layer, EquipmentModel.Layer armorLayer) { return layerCache.getUnchecked(new ArmourParameters(layer, armorLayer, getCustom(stack))); } - @Override - public List getArmorLayers(ItemStack stack, int dyeColor) { - if (stack.getItem() instanceof ArmorItem armor) { - return armor.getMaterial().value().layers(); - } - - return (dyeColor == Colors.WHITE ? nonDyedLayers : dyedLayers).getUnchecked(Registries.ITEM.getId(stack.getItem())); - } - private int getCustom(ItemStack stack) { return stack.getOrDefault(DataComponentTypes.CUSTOM_MODEL_DATA, CustomModelDataComponent.DEFAULT).value(); } - private record ArmourParameters(ArmourLayer layer, ArmorMaterial.Layer material, int customModelId) { + private record ArmourParameters(ArmourLayer layer, EquipmentModel.Layer material, int customModelId) { } } diff --git a/src/main/java/com/minelittlepony/client/model/armour/PonifiedEquipmentRenderer.java b/src/main/java/com/minelittlepony/client/model/armour/PonifiedEquipmentRenderer.java new file mode 100644 index 00000000..2360de4d --- /dev/null +++ b/src/main/java/com/minelittlepony/client/model/armour/PonifiedEquipmentRenderer.java @@ -0,0 +1,113 @@ +package com.minelittlepony.client.model.armour; + +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.render.*; +import net.minecraft.client.render.entity.equipment.EquipmentModelLoader; +import net.minecraft.client.render.entity.equipment.EquipmentRenderer; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.DyedColorComponent; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.item.ItemStack; +import net.minecraft.item.equipment.EquipmentModel; +import net.minecraft.item.equipment.EquipmentModel.LayerType; +import net.minecraft.item.equipment.trim.ArmorTrim; +import net.minecraft.registry.tag.ItemTags; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.ColorHelper; + +import org.jetbrains.annotations.Nullable; + +import com.minelittlepony.api.model.Models; +import com.minelittlepony.api.model.PonyModel; +import com.minelittlepony.client.render.entity.state.PonyRenderState; + +import java.util.*; + +public class PonifiedEquipmentRenderer extends EquipmentRenderer { + + private final EquipmentModelLoader modelLoader; + + public PonifiedEquipmentRenderer(EquipmentModelLoader modelLoader) { + super(modelLoader, MinecraftClient.getInstance().getBakedModelManager().getAtlas(TexturedRenderLayers.ARMOR_TRIMS_ATLAS_TEXTURE)); + this.modelLoader = modelLoader; + } + + public > void render( + EquipmentSlot equipmentSlot, + EquipmentModel.LayerType layerType, + Identifier modelId, + Models> models, + ItemStack stack, + MatrixStack matrices, + VertexConsumerProvider vertexConsumers, + int light + ) { + this.render(equipmentSlot, layerType, modelId, models, stack, matrices, vertexConsumers, light, null); + } + + public > void render( + EquipmentSlot equipmentSlot, + EquipmentModel.LayerType layerType, + Identifier modelId, + Models> models, + ItemStack stack, + MatrixStack matrices, + VertexConsumerProvider vertexConsumers, + int light, + @Nullable Identifier texture + ) { + + List layers = modelLoader.get(modelId).getLayers(layerType); + if (!layers.isEmpty()) { + ArmourRendererPlugin plugin = ArmourRendererPlugin.INSTANCE.get(); + int i = stack.isIn(ItemTags.DYEABLE) ? DyedColorComponent.getColor(stack, 0) : 0; + float armorAlpha = plugin.getArmourAlpha(equipmentSlot, layerType); + boolean hasGlint = plugin.getGlintAlpha(equipmentSlot, stack) > 0 && stack.hasGlint(); + + Set drawnModels = new HashSet<>(); + + if (armorAlpha > 0) { + for (EquipmentModel.Layer layer : layers) { + int j = getDyeColor(layer, i); + if (j != 0) { + ArmourTexture armorTexture = plugin.getTextureLookup().getTexture(stack, layerType == LayerType.HUMANOID_LEGGINGS ? ArmourLayer.INNER : ArmourLayer.OUTER, layer); + Identifier layerTexture = layer.usePlayerTexture() && texture != null + ? texture + : armorTexture.texture(); + + VertexConsumer armorConsumer = plugin.getArmourConsumer(equipmentSlot, vertexConsumers, layerTexture, layerType); + if (armorConsumer != null) { + ArmourVariant variant = layer.usePlayerTexture() ? ArmourVariant.NORMAL : armorTexture.variant(); + models.getArmourModel(stack, null, variant).ifPresent(model -> { + VertexConsumer glintConsumer = hasGlint ? plugin.getGlintConsumer(equipmentSlot, vertexConsumers, layerType) : null; + model.render(matrices, glintConsumer != null ? VertexConsumers.union(plugin.getGlintConsumer(equipmentSlot, vertexConsumers, layerType), armorConsumer) : armorConsumer, light, OverlayTexture.DEFAULT_UV, j); + }); + } + } + } + } + + ArmorTrim armorTrim = stack.get(DataComponentTypes.TRIM); + if (armorTrim != null && plugin.getTrimAlpha(equipmentSlot, armorTrim, layerType) > 0) { + VertexConsumer trimConsumer = plugin.getTrimConsumer(equipmentSlot, vertexConsumers, armorTrim, layerType, modelId); + if (trimConsumer != null) { + drawnModels.forEach(model -> { + model.render(matrices, trimConsumer, light, OverlayTexture.DEFAULT_UV); + }); + } + } + } + } + + private static int getDyeColor(EquipmentModel.Layer layer, int dyeColor) { + Optional optional = layer.dyeable(); + if (optional.isPresent()) { + int i = (Integer)((EquipmentModel.Dyeable)optional.get()).colorWhenUndyed().map(ColorHelper::fullAlpha).orElse(0); + return dyeColor != 0 ? dyeColor : i; + } else { + return -1; + } + } + +} diff --git a/src/main/java/com/minelittlepony/client/model/armour/PonyArmourModel.java b/src/main/java/com/minelittlepony/client/model/armour/PonyArmourModel.java index 324390f7..3d75fb88 100644 --- a/src/main/java/com/minelittlepony/client/model/armour/PonyArmourModel.java +++ b/src/main/java/com/minelittlepony/client/model/armour/PonyArmourModel.java @@ -2,28 +2,26 @@ package com.minelittlepony.client.model.armour; import net.minecraft.client.model.ModelPart; import net.minecraft.client.render.entity.model.BipedEntityModel; -import net.minecraft.client.render.entity.state.BipedEntityRenderState; import net.minecraft.entity.EquipmentSlot; -import net.minecraft.entity.LivingEntity; import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.client.model.AbstractPonyModel; +import com.minelittlepony.client.render.entity.state.PonyRenderState; -public class PonyArmourModel extends AbstractPonyModel { +public class PonyArmourModel extends AbstractPonyModel { public PonyArmourModel(ModelPart tree) { - super(tree); + super(tree, false); } - public boolean poseModel(T entity, float limbAngle, float limbDistance, float age, float headYaw, float headPitch, + public boolean poseModel(S state, EquipmentSlot slot, ArmourLayer layer, - PonyModel mainModel) { + PonyModel mainModel) { if (!setVisibilities(slot, layer)) { return false; } - mainModel.copyAttributes(this); - setAngles(entity, limbAngle, limbDistance, age, headYaw, headPitch); + setAngles(state); if (mainModel instanceof BipedEntityModel biped) { head.copyTransform(biped.head); body.copyTransform(biped.body); diff --git a/src/main/java/com/minelittlepony/client/model/entity/BreezieModel.java b/src/main/java/com/minelittlepony/client/model/entity/BreezieModel.java index b327818a..ae96989a 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/BreezieModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/BreezieModel.java @@ -2,12 +2,13 @@ package com.minelittlepony.client.model.entity; import net.minecraft.client.model.ModelPart; import net.minecraft.client.render.entity.model.BipedEntityModel; -import net.minecraft.client.render.entity.state.BipedEntityRenderState; import net.minecraft.entity.EntityPose; import net.minecraft.util.Arm; import net.minecraft.util.math.MathHelper; -public class BreezieModel extends BipedEntityModel { +import com.minelittlepony.client.render.entity.AllayRenderer; + +public class BreezieModel extends BipedEntityModel { private ModelPart leftWing; private ModelPart rightWing; @@ -25,7 +26,7 @@ public class BreezieModel extends BipedEntityM } @Override - public void setAngles(T state) { + public void setAngles(AllayRenderer.State state) { float move = state.limbFrequency; float swing = state.limbAmplitudeMultiplier; @@ -90,7 +91,7 @@ public class BreezieModel extends BipedEntityM leg.setAngles(-1.4137167F, factor * MathHelper.PI / 10, factor * 0.07853982F); } - protected void swingArms(T state, Arm mainHand) { + protected void swingArms(AllayRenderer.State state, Arm mainHand) { body.yaw = MathHelper.sin(MathHelper.sqrt(state.handSwingProgress) * MathHelper.TAU) / 5; if (mainHand == Arm.LEFT) { diff --git a/src/main/java/com/minelittlepony/client/model/entity/GuardianPonyModel.java b/src/main/java/com/minelittlepony/client/model/entity/GuardianPonyModel.java deleted file mode 100644 index 377903a8..00000000 --- a/src/main/java/com/minelittlepony/client/model/entity/GuardianPonyModel.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.minelittlepony.client.model.entity; - -import net.minecraft.client.model.ModelPart; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.entity.model.EntityModel; -import net.minecraft.client.render.entity.model.GuardianEntityModel; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.mob.GuardianEntity; - -import com.minelittlepony.api.model.PonyModelMixin; -import com.minelittlepony.client.model.entity.race.SeaponyModel; - -public class GuardianPonyModel extends GuardianEntityModel implements PonyModelMixin.Caster, ModelPart> { - private final SeaponyModel mixin; - - public GuardianPonyModel(ModelPart tree) { - super(getTexturedModelData().createModel()); - mixin = new SeaponyModel<>(tree); - } - - @Override - public SeaponyModel mixin() { - return mixin; - } - - @Override - public void render(MatrixStack matrices, VertexConsumer vertices, int light, int overlay, int color) { - mixin().render(matrices, vertices, light, overlay, color); - } - - @Override - public void animateModel(GuardianEntity entity, float limbAngle, float limbDistance, float tickDelta) { - mixin().animateModel(entity, limbAngle, limbDistance, tickDelta); - } - - @Override - public void copyStateTo(EntityModel copy) { - mixin().copyStateTo(copy); - } - - @Override - public void setAngles(GuardianEntity entity, float limbAngle, float limbSpeed, float animationProgress, float headYaw, float headPitch) { - mixin().setVisible(true); - mixin().setAngles(entity, limbAngle, limbSpeed, animationProgress, headYaw, headPitch); - } -} diff --git a/src/main/java/com/minelittlepony/client/model/entity/IllagerPonyModel.java b/src/main/java/com/minelittlepony/client/model/entity/IllagerPonyModel.java index 6859b5c4..c7915b92 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/IllagerPonyModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/IllagerPonyModel.java @@ -6,30 +6,30 @@ import net.minecraft.util.Arm; import net.minecraft.util.math.MathHelper; import com.minelittlepony.client.model.entity.race.AlicornModel; +import com.minelittlepony.client.render.entity.npc.IllagerPonyRenderer; -public class IllagerPonyModel extends AlicornModel { +public class IllagerPonyModel extends AlicornModel { public IllagerPonyModel(ModelPart tree) { super(tree, false); } @Override - public void setModelAngles(T illager, float move, float swing, float ticks, float headYaw, float headPitch) { - super.setModelAngles(illager, move, swing, ticks, headYaw, headPitch); + public void setModelAngles(S state) { + super.setModelAngles(state); + IllagerEntity.State pose = state.state; - IllagerEntity.State pose = illager.getState(); - - boolean rightHanded = illager.getMainArm() == Arm.RIGHT; + boolean rightHanded = state.mainArm == Arm.RIGHT; float mult = rightHanded ? 1 : -1; - ModelPart arm = getArm(illager.getMainArm()); + ModelPart arm = getArm(state.mainArm); if (pose == IllagerEntity.State.ATTACKING) { // vindicator attacking - float f = MathHelper.sin(getSwingAmount() * (float) Math.PI); - float f1 = MathHelper.sin((1 - (1 - getSwingAmount()) * (1 - getSwingAmount())) * (float) Math.PI); + float f = MathHelper.sin(state.getSwingAmount() * (float) Math.PI); + float f1 = MathHelper.sin((1 - (1 - state.getSwingAmount()) * (1 - state.getSwingAmount())) * (float) Math.PI); - float cos = MathHelper.cos(ticks * 0.09F) * 0.05F + 0.05F; - float sin = MathHelper.sin(ticks * 0.067F) * 0.05F; + float cos = MathHelper.cos(state.age * 0.09F) * 0.05F + 0.05F; + float sin = MathHelper.sin(state.age * 0.067F) * 0.05F; rightArm.roll = cos; leftArm.roll = cos; @@ -37,7 +37,7 @@ public class IllagerPonyModel extends AlicornModel { rightArm.yaw = 0.15707964F; leftArm.yaw = -0.15707964F; - arm.pitch = -1.8849558F + MathHelper.cos(ticks * 0.09F) * 0.15F; + arm.pitch = -1.8849558F + MathHelper.cos(state.age * 0.09F) * 0.15F; arm.pitch += f * 2.2F - f1 * 0.4F; rightArm.pitch += sin; @@ -46,10 +46,10 @@ public class IllagerPonyModel extends AlicornModel { // waving arms! // rightArm.rotationPointZ = 0; arm.pitch = (float) (-.75F * Math.PI); - arm.roll = mult * MathHelper.cos(ticks * 0.6662F) / 4; + arm.roll = mult * MathHelper.cos(state.age * 0.6662F) / 4; arm.yaw = mult * 1.1F; } else if (pose == IllagerEntity.State.BOW_AND_ARROW) { - aimBow(arm, ticks); + aimBow(state, arm, state.age); } } } diff --git a/src/main/java/com/minelittlepony/client/model/entity/ParaspriteModel.java b/src/main/java/com/minelittlepony/client/model/entity/ParaspriteModel.java index 7ab49bcf..c7e283f5 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/ParaspriteModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/ParaspriteModel.java @@ -2,19 +2,12 @@ package com.minelittlepony.client.model.entity; import net.minecraft.client.model.ModelPart; import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.entity.model.EntityModel; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.mob.VexEntity; import net.minecraft.util.math.MathHelper; -import com.minelittlepony.common.util.animation.Interpolator; - -public class ParaspriteModel extends EntityModel { - - private final ModelPart root; +import com.minelittlepony.client.render.entity.VexRenderer; +public class ParaspriteModel extends EntityModel { private final ModelPart body; private final ModelPart jaw; private final ModelPart lips; @@ -24,70 +17,45 @@ public class ParaspriteModel extends EntityModel { private final ModelPart leftWing2; private final ModelPart rightWing2; - public ParaspriteModel(ModelPart tree) { - super(RenderLayer::getEntityTranslucent); - child = false; - root = tree; - body = tree.getChild("body"); + public ParaspriteModel(ModelPart root) { + super(root, RenderLayer::getEntityTranslucent); + body = root.getChild("body"); jaw = body.getChild("jaw"); lips = body.getChild("lips"); - leftWing = tree.getChild("leftWing"); - rightWing = tree.getChild("rightWing"); - leftWing2 = tree.getChild("leftWing2"); - rightWing2 = tree.getChild("rightWing2"); + leftWing = root.getChild("leftWing"); + rightWing = root.getChild("rightWing"); + leftWing2 = root.getChild("leftWing2"); + rightWing2 = root.getChild("rightWing2"); } @Override - public void render(MatrixStack matrices, VertexConsumer vertices, int light, int overlay, int color) { - root.render(matrices, vertices, light, overlay, color); - } - - @Override - public void setAngles(T entity, float move, float swing, float ticks, float headYaw, float headPitch) { - - root.pitch = MathHelper.clamp((float)entity.getVelocity().horizontalLength() / 10F, 0, 0.1F); + public void setAngles(VexRenderer.State state) { + root.pitch = state.bodyPitch; body.pitch = 0; + root.pitch = state.pitch * MathHelper.RADIANS_PER_DEGREE; + root.yaw = state.yawDegrees * MathHelper.RADIANS_PER_DEGREE; - if (entity.hasPassengers()) { - root.yaw = 0; - root.pitch = 0; - } else { - root.yaw = headYaw * 0.017453292F; - root.pitch = headPitch * 0.017453292F; - } - - float sin = (float)Math.sin(ticks) / 2F; - float cos = (float)Math.cos(ticks) / 3F; - - float jawOpenAmount = Interpolator.linear(entity.getUuid()).interpolate("jawOpen", entity instanceof VexEntity vex && vex.isCharging() ? 1 : 0, 10); - - jaw.pivotY = Math.max(0, 1.2F * jawOpenAmount); + jaw.pivotY = Math.max(0, 1.2F * state.jawOpenAmount); lips.pivotY = jaw.pivotY - 0.9F; - lips.visible = jawOpenAmount > 0; - body.pitch += 0.3F * jawOpenAmount; - jaw.pitch = 0.4F * jawOpenAmount; - lips.pitch = 0.2F * jawOpenAmount; - - float basWingExpand = 1; - float innerWingExpand = basWingExpand / 2F; + lips.visible = state.jawOpenAmount > 0; + body.pitch += 0.3F * state.jawOpenAmount; + jaw.pitch = 0.4F * state.jawOpenAmount; + lips.pitch = 0.2F * state.jawOpenAmount; leftWing.pitch = 0; - leftWing.roll = basWingExpand + cos + 0.3F; - leftWing.yaw = basWingExpand - sin; + leftWing.roll = state.wingRoll; + leftWing.yaw = state.wingYaw; rightWing.pitch = 0; - rightWing.roll = -basWingExpand - cos - 0.3F; - rightWing.yaw = -basWingExpand + sin; - - sin = -(float)Math.sin(ticks + Math.PI / 4F) / 2F; - cos = (float)Math.cos(ticks + Math.PI / 4F) / 3F; + rightWing.roll = -state.wingRoll; + rightWing.yaw = -state.wingYaw; leftWing2.pitch = 0; - leftWing2.roll = innerWingExpand + sin - 0.3F; - leftWing2.yaw = innerWingExpand - cos + 0.3F; + leftWing2.roll = state.innerWingRoll; + leftWing2.yaw = state.innerWingPitch; rightWing2.pitch = 0; - rightWing2.roll = -innerWingExpand - sin + 0.3F; - rightWing2.yaw = -innerWingExpand + cos - 0.3F; + rightWing2.roll = -state.innerWingRoll; + rightWing2.yaw = -state.innerWingPitch; } } diff --git a/src/main/java/com/minelittlepony/client/model/entity/PiglinPonyModel.java b/src/main/java/com/minelittlepony/client/model/entity/PiglinPonyModel.java index 339316fd..ba2e64b4 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/PiglinPonyModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/PiglinPonyModel.java @@ -1,20 +1,14 @@ package com.minelittlepony.client.model.entity; import net.minecraft.client.model.ModelPart; -import net.minecraft.client.render.entity.PlayerEntityRenderer; -import net.minecraft.client.render.entity.model.BipedEntityModel; import net.minecraft.client.render.entity.state.PlayerEntityRenderState; -import net.minecraft.entity.mob.AbstractPiglinEntity; -import net.minecraft.entity.mob.HostileEntity; import net.minecraft.entity.mob.PiglinActivity; import net.minecraft.util.Arm; import net.minecraft.util.math.MathHelper; -import com.minelittlepony.api.model.ModelAttributes; -import com.minelittlepony.api.pony.Pony; import com.minelittlepony.client.render.entity.PonyPiglinRenderer; -public class PiglinPonyModel extends ZomponyModel { +public class PiglinPonyModel extends ZomponyModel { private final ModelPart leftFlap; private final ModelPart rightFlap; @@ -45,11 +39,11 @@ public class PiglinPonyModel extends ZomponyModel { } @Override - public void setModelAngles(HostileEntity entity, float move, float swing, float ticks, float headYaw, float headPitch) { - super.setModelAngles(entity, move, swing, ticks, headYaw, headPitch); + public void setModelAngles(PonyPiglinRenderer.State state) { + super.setModelAngles(state); - float progress = ticks * 0.1F + move * 0.5F; - float range = 0.08F + swing * 0.4F; + float progress = state.age * 0.1F + state.limbFrequency * 0.5F; + float range = 0.08F + state.limbAmplitudeMultiplier * 0.4F; rightFlap.roll = -0.5235988F - MathHelper.cos(progress * 1.2F) * range; leftFlap.roll = 0.5235988F + MathHelper.cos(progress) * range; } @@ -62,10 +56,10 @@ public class PiglinPonyModel extends ZomponyModel { } @Override - protected void rotateLegs(float move, float swing, float ticks, HostileEntity entity) { - super.rotateLegs(move, swing, ticks, entity); + protected void rotateLegs(PonyPiglinRenderer.State state, float move, float swing, float ticks) { + super.rotateLegs(state, move, swing, ticks); - if (activity == PiglinActivity.ADMIRING_ITEM) { + if (state.activity == PiglinActivity.ADMIRING_ITEM) { leftArm.yaw = 0.5F; leftArm.pitch = -1.9F; leftArm.pivotY += 4; @@ -75,7 +69,7 @@ public class PiglinPonyModel extends ZomponyModel { head.yaw = 0; head.roll = MathHelper.sin(ticks / 10) / 3F; - } else if (activity == PiglinActivity.DANCING) { + } else if (state.activity == PiglinActivity.DANCING) { float speed = ticks / 60; @@ -101,7 +95,7 @@ public class PiglinPonyModel extends ZomponyModel { } @Override - protected boolean isZombified(HostileEntity entity) { - return !(entity instanceof AbstractPiglinEntity); + protected boolean shouldLiftBothArms(PonyPiglinRenderer.State state) { + return state.zombified && super.shouldLiftBothArms(state); } } diff --git a/src/main/java/com/minelittlepony/client/model/entity/PillagerPonyModel.java b/src/main/java/com/minelittlepony/client/model/entity/PillagerPonyModel.java index 8a129849..5711df4a 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/PillagerPonyModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/PillagerPonyModel.java @@ -7,16 +7,16 @@ import net.minecraft.entity.mob.IllagerEntity; import net.minecraft.util.Arm; import com.minelittlepony.client.model.entity.race.ChangelingModel; -import com.minelittlepony.client.render.entity.npc.PillagerRenderer; +import com.minelittlepony.client.render.entity.npc.IllagerPonyRenderer; -public class PillagerPonyModel extends ChangelingModel { +public class PillagerPonyModel extends ChangelingModel { public PillagerPonyModel(ModelPart tree) { super(tree, false); } @Override protected BipedEntityModel.ArmPose getArmPose(PlayerEntityRenderState state, Arm arm) { - ArmPose holdingPose = getHoldingPose(((PillagerRenderer.State)state).state); + ArmPose holdingPose = getHoldingPose(((IllagerPonyRenderer.State)state).state); if (holdingPose != ArmPose.EMPTY) { boolean isMain = state.mainArm == Arm.RIGHT; diff --git a/src/main/java/com/minelittlepony/client/model/entity/SaddleModel.java b/src/main/java/com/minelittlepony/client/model/entity/SaddleModel.java index b9c43931..2e2ac72e 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/SaddleModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/SaddleModel.java @@ -2,16 +2,17 @@ package com.minelittlepony.client.model.entity; import net.minecraft.client.model.ModelPart; import net.minecraft.client.render.entity.model.EntityModel; -import net.minecraft.client.render.entity.state.LivingEntityRenderState; import net.minecraft.util.math.MathHelper; -public class SaddleModel extends EntityModel { +import com.minelittlepony.client.render.entity.StriderRenderer; + +public class SaddleModel extends EntityModel { public SaddleModel(ModelPart tree) { super(tree); } @Override - public void setAngles(T entity) { + public void setAngles(StriderRenderer.State entity) { root.pivotY = 2 - MathHelper.cos(entity.limbFrequency * 1.5F) * 3 * entity.limbAmplitudeMultiplier; } } diff --git a/src/main/java/com/minelittlepony/client/model/entity/SkeleponyModel.java b/src/main/java/com/minelittlepony/client/model/entity/SkeleponyModel.java index 35efe038..45d975b3 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/SkeleponyModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/SkeleponyModel.java @@ -8,9 +8,9 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.Arm; import com.minelittlepony.client.model.entity.race.AlicornModel; -import com.minelittlepony.client.render.entity.state.SkeletonPonyRenderState; +import com.minelittlepony.client.render.entity.SkeleponyRenderer; -public class SkeleponyModel extends AlicornModel { +public class SkeleponyModel extends AlicornModel { public SkeleponyModel(ModelPart tree) { super(tree, false); vestRenderList.clear(); diff --git a/src/main/java/com/minelittlepony/client/model/entity/SpikeModel.java b/src/main/java/com/minelittlepony/client/model/entity/SpikeModel.java index 2fc4822c..baa567f0 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/SpikeModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/SpikeModel.java @@ -2,12 +2,10 @@ package com.minelittlepony.client.model.entity; import net.minecraft.client.model.ModelPart; import net.minecraft.client.render.entity.model.BipedEntityModel; -import net.minecraft.client.render.entity.state.*; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.passive.StriderEntity; -import net.minecraft.util.math.MathHelper; -public class SpikeModel extends BipedEntityModel { +import com.minelittlepony.client.render.entity.StriderRenderer; + +public class SpikeModel extends BipedEntityModel { private final ModelPart tail; private final ModelPart tail2; @@ -21,7 +19,7 @@ public class SpikeModel extends BipedEntityMo } @Override - public void setAngles(T entity) { + public void setAngles(StriderRenderer.State entity) { entity.limbFrequency *= 2; entity.limbAmplitudeMultiplier *= 1.5F; entity.baby = false; @@ -36,7 +34,7 @@ public class SpikeModel extends BipedEntityMo rightArm.pivotY++; body.pitch += 0.15F; - if ((entity instanceof SaddleableRenderState strider && strider.isSaddled())) { + if (entity.saddled) { leftArm.pitch = 3.15F; leftArm.yaw = 1; rightArm.pitch = 3.15F; @@ -50,10 +48,8 @@ public class SpikeModel extends BipedEntityMo leftLeg.pitch += 0.4F; rightLeg.pitch += 0.4F; } else { - float flailAmount = 1 + (float)MathHelper.clamp(entity.getVelocity().y * 10, 0, 7); - - leftArm.roll -= 0.2F * flailAmount; - rightArm.roll += 0.2F * flailAmount; + leftArm.roll -= 0.2F * entity.flailAmount; + rightArm.roll += 0.2F * entity.flailAmount; leftArm.pivotZ += 2; leftArm.pitch -= 0.3F; @@ -61,7 +57,7 @@ public class SpikeModel extends BipedEntityMo rightArm.pivotZ += 2; rightArm.pitch -= 0.3F; - if (entity instanceof StriderEntityRenderState strider && strider.cold) { + if (entity.cold) { float armMotion = (float)Math.sin(entity.age / 10F) / 10F; leftArm.pitch = -1 - armMotion; diff --git a/src/main/java/com/minelittlepony/client/model/entity/ZomponyModel.java b/src/main/java/com/minelittlepony/client/model/entity/ZomponyModel.java index 13317588..656e02b8 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/ZomponyModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/ZomponyModel.java @@ -1,39 +1,25 @@ package com.minelittlepony.client.model.entity; import com.minelittlepony.api.model.MobPosingHelper; -import com.minelittlepony.api.pony.meta.Race; import com.minelittlepony.client.model.entity.race.AlicornModel; +import com.minelittlepony.client.render.entity.ZomponyRenderer; + import net.minecraft.client.model.ModelPart; -import net.minecraft.entity.mob.HostileEntity; - -public class ZomponyModel extends AlicornModel { - - private boolean isPegasus; +public class ZomponyModel extends AlicornModel { public ZomponyModel(ModelPart tree) { super(tree, false); } @Override - public void animateModel(Zombie entity, float move, float swing, float ticks) { - super.animateModel(entity, move, swing, ticks); - isPegasus = entity.getUuid().getLeastSignificantBits() % 30 == 0; - } - - @Override - protected void rotateLegs(float move, float swing, float ticks, Zombie entity) { - super.rotateLegs(move, swing, ticks, entity); - if (isZombified(entity)) { - MobPosingHelper.rotateUndeadArms(this, move, ticks); + protected void rotateLegs(T state, float move, float swing, float ticks) { + super.rotateLegs(state, move, swing, ticks); + if (shouldLiftBothArms(state)) { + MobPosingHelper.rotateUndeadArms(state, this, state.limbFrequency, state.age); } } - @Override - public Race getRace() { - return isPegasus ? (super.getRace().hasHorn() ? Race.ALICORN : Race.PEGASUS) : super.getRace(); - } - - protected boolean isZombified(Zombie entity) { - return rightArmPose == ArmPose.EMPTY; + protected boolean shouldLiftBothArms(T state) { + return getArmPose(state, state.mainArm) == ArmPose.EMPTY; } } diff --git a/src/main/java/com/minelittlepony/client/model/entity/race/AlicornModel.java b/src/main/java/com/minelittlepony/client/model/entity/race/AlicornModel.java index 4ad605cd..a1e018ac 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/race/AlicornModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/race/AlicornModel.java @@ -7,11 +7,10 @@ import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.mson.api.ModelView; import net.minecraft.client.model.ModelPart; -import net.minecraft.entity.LivingEntity; public class AlicornModel extends UnicornModel implements WingedPonyModel { - private PonyWings> wings; + private PonyWings wings; public AlicornModel(ModelPart tree, boolean smallArms) { super(tree, smallArms); @@ -21,11 +20,11 @@ public class AlicornModel extends UnicornModel imp public void init(ModelView context) { super.init(context); wings = addPart(context.findByName("wings")); - bodyRenderList.add(forPart(this::getWings).checked(() -> getRace().hasWings())); + bodyRenderList.add(forPart(this::getWings).checked(() -> currentState.getRace().hasWings())); } @Override - public SubModel getWings() { + public SubModel getWings() { return wings; } } diff --git a/src/main/java/com/minelittlepony/client/model/entity/race/ChangelingModel.java b/src/main/java/com/minelittlepony/client/model/entity/race/ChangelingModel.java index fe919525..55cab18a 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/race/ChangelingModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/race/ChangelingModel.java @@ -3,7 +3,6 @@ package com.minelittlepony.client.model.entity.race; import net.minecraft.client.model.ModelPart; import net.minecraft.util.math.MathHelper; -import com.minelittlepony.api.model.ModelAttributes; import com.minelittlepony.client.render.entity.state.PonyRenderState; public class ChangelingModel extends AlicornModel { @@ -13,15 +12,12 @@ public class ChangelingModel extends AlicornModel } @Override - public boolean wingsAreOpen(ModelAttributes state) { - return (state.isFlying || state.isCrouching) && !state.isGliding; + public boolean wingsAreOpen(T state) { + return (state.attributes.isFlying || state.attributes.isCrouching) && !state.attributes.isGliding; } @Override - public float getWingRotationFactor(ModelAttributes state, float ticks) { - if (state.isFlying) { - return MathHelper.sin(ticks * 3) + WINGS_HALF_SPREAD_ANGLE; - } - return WINGS_RAISED_ANGLE; + public float getWingRotationFactor(T state, float ticks) { + return state.attributes.isFlying ? MathHelper.sin(ticks * 3) + WINGS_HALF_SPREAD_ANGLE : WINGS_RAISED_ANGLE; } } diff --git a/src/main/java/com/minelittlepony/client/model/entity/race/EarthPonyModel.java b/src/main/java/com/minelittlepony/client/model/entity/race/EarthPonyModel.java index a2b3e52b..614e0ef9 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/race/EarthPonyModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/race/EarthPonyModel.java @@ -10,7 +10,7 @@ import net.minecraft.client.model.ModelPart; public class EarthPonyModel extends AbstractPonyModel { - protected SubModel tail; + protected SubModel tail; protected PonySnout snout; protected PonyEars ears; diff --git a/src/main/java/com/minelittlepony/client/model/entity/race/PegasusModel.java b/src/main/java/com/minelittlepony/client/model/entity/race/PegasusModel.java index 2beaf718..a4ca2ceb 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/race/PegasusModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/race/PegasusModel.java @@ -10,7 +10,7 @@ import net.minecraft.client.model.ModelPart; public class PegasusModel extends EarthPonyModel implements WingedPonyModel { - private PonyWings> wings; + private PonyWings wings; public PegasusModel(ModelPart tree, boolean smallArms) { super(tree, smallArms); @@ -24,7 +24,7 @@ public class PegasusModel extends EarthPonyModel i } @Override - public SubModel getWings() { + public SubModel getWings() { return wings; } } diff --git a/src/main/java/com/minelittlepony/client/model/entity/race/SeaponyModel.java b/src/main/java/com/minelittlepony/client/model/entity/race/SeaponyModel.java index 08687f0b..ad6c948c 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/race/SeaponyModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/race/SeaponyModel.java @@ -2,13 +2,11 @@ package com.minelittlepony.client.model.entity.race; import com.minelittlepony.mson.api.ModelView; import com.minelittlepony.api.model.*; -import com.minelittlepony.api.pony.Pony; import com.minelittlepony.client.model.armour.PonyArmourModel; import com.minelittlepony.client.render.entity.state.PonyRenderState; import net.minecraft.client.model.ModelPart; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.LivingEntity; import net.minecraft.util.math.MathHelper; public class SeaponyModel extends UnicornModel { @@ -45,21 +43,6 @@ public class SeaponyModel extends UnicornModel { bodyRenderList.add(body).add(body::rotate).add(forPart(tail)).add(leftFin, centerFin, rightFin); } - @Override - public void updateLivingState(T entity, Pony pony, ModelAttributes.Mode mode) { - super.updateLivingState(entity, pony, mode); - - // Seaponies can't sneak, silly - sneaking = false; - attributes.isCrouching = false; - } - - @Override - protected void ponySleep() {} - - @Override - protected void ponySit() {} - @Override protected void setModelAngles(T entity) { super.setModelAngles(entity); @@ -88,8 +71,8 @@ public class SeaponyModel extends UnicornModel { } @Override - protected void rotateLegs(T state, float move, float swing, float ticks, T entity) { - super.rotateLegs(state, move, swing, ticks, entity); + protected void rotateLegs(T state, float move, float swing, float ticks) { + super.rotateLegs(state, move, swing, ticks); leftArm.pitch -= 1.4F; leftArm.yaw -= 0.3F; rightArm.pitch -= 1.4F; @@ -97,14 +80,14 @@ public class SeaponyModel extends UnicornModel { } @Override - protected void rotateLegsSwimming(T state, float move, float swing, float ticks, T entity) { - super.rotateLegsOnGround(state, move, swing, ticks, entity); + protected void rotateLegsSwimming(T state, float move, float swing, float ticks) { + rotateLegsOnGround(state, move, swing, ticks); } @Override - public void transform(BodyPart part, MatrixStack stack) { + public void transform(T state, BodyPart part, MatrixStack stack) { stack.translate(0, 0.6F, 0); - super.transform(part, stack); + super.transform(state, part, stack); } @Override @@ -116,7 +99,6 @@ public class SeaponyModel extends UnicornModel { } public static class Armour extends PonyArmourModel { - public Armour(ModelPart tree) { super(tree); rightLeg.hidden = true; @@ -124,22 +106,14 @@ public class SeaponyModel extends UnicornModel { } @Override - public void updateLivingState(T entity, Pony pony, ModelAttributes.Mode mode) { - super.updateLivingState(entity, pony, mode); - - // Seaponies can't sneak, silly - sneaking = false; + protected void rotateLegsSwimming(T state, float move, float swing, float ticks) { + rotateLegsOnGround(state, move, swing, ticks); } @Override - protected void rotateLegsSwimming(T state, float move, float swing, float ticks, T entity) { - super.rotateLegsOnGround(state, move, swing, ticks, entity); - } - - @Override - public void transform(BodyPart part, MatrixStack stack) { + public void transform(T state, BodyPart part, MatrixStack stack) { stack.translate(0, 0.6F, 0); - super.transform(part, stack); + super.transform(state, part, stack); } } } diff --git a/src/main/java/com/minelittlepony/client/model/entity/race/UnicornModel.java b/src/main/java/com/minelittlepony/client/model/entity/race/UnicornModel.java index 2028fb2e..07318e44 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/race/UnicornModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/race/UnicornModel.java @@ -39,7 +39,7 @@ public class UnicornModel extends EarthPonyModel i headRenderList.add(RenderList.of().add(head::rotate).add(forPart(horn)).checked(() -> currentState.getRace().hasHorn())); this.mainRenderList.add(withStage(BodyPart.HEAD, RenderList.of().add(head::rotate).add((stack, vertices, overlay, light, color) -> { horn.renderMagic(stack, vertices, currentState.attributes.metadata.glowColor()); - })).checked(() -> hasMagic(currentState) && isCasting(currentState))); + })).checked(() -> currentState.hasMagicGlow() && isCasting(currentState))); } @Override @@ -48,8 +48,8 @@ public class UnicornModel extends EarthPonyModel i } @Override - protected void rotateLegs(T state, float move, float swing, float ticks, T entity) { - super.rotateLegs(state, move, swing, ticks, entity); + protected void rotateLegs(T state, float move, float swing, float ticks) { + super.rotateLegs(state, move, swing, ticks); unicornArmRight.setAngles(0, 0, 0); unicornArmRight.setPivot(-7, 12, -2); @@ -58,11 +58,6 @@ public class UnicornModel extends EarthPonyModel i unicornArmLeft.setPivot(-7, 12, -2); } - @Override - public boolean isCasting(T state) { - return PonyConfig.getInstance().tpsmagic.get() && (!state.leftHandStack.isEmpty() || !state.rightHandStack.isEmpty()); - } - @Override protected void ponyCrouch(T state) { super.ponyCrouch(state); @@ -72,7 +67,7 @@ public class UnicornModel extends EarthPonyModel i @Override public ModelPart getArm(Arm side) { - if (hasMagic(currentState) && getArmPoseForSide(currentState, side) != ArmPose.EMPTY && PonyConfig.getInstance().tpsmagic.get()) { + if (currentState.hasMagicGlow() && getArmPoseForSide(currentState, side) != ArmPose.EMPTY && PonyConfig.getInstance().tpsmagic.get()) { return side == Arm.LEFT ? unicornArmLeft : unicornArmRight; } return super.getArm(side); @@ -82,7 +77,7 @@ public class UnicornModel extends EarthPonyModel i protected void positionheldItem(T state, Arm arm, MatrixStack matrices) { super.positionheldItem(state, arm, matrices); - if (!PonyConfig.getInstance().tpsmagic.get() || !hasMagic(state)) { + if (!PonyConfig.getInstance().tpsmagic.get() || !currentState.hasMagicGlow()) { return; } diff --git a/src/main/java/com/minelittlepony/client/model/gear/Crown.java b/src/main/java/com/minelittlepony/client/model/gear/Crown.java index 5f737e0d..d6ff11a7 100644 --- a/src/main/java/com/minelittlepony/client/model/gear/Crown.java +++ b/src/main/java/com/minelittlepony/client/model/gear/Crown.java @@ -1,6 +1,7 @@ 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; @@ -14,12 +15,11 @@ import com.minelittlepony.api.pony.meta.Wearable; public class Crown extends WearableGear { public Crown(ModelPart tree) { - super(Wearable.CROWN, BodyPart.HEAD, 0.1F); - addPart(tree.getChild("crown")); + super(tree.getChild("crown"), Wearable.CROWN, BodyPart.HEAD, 0.1F); } @Override - public boolean canRender(PonyModel model, Entity entity) { + public boolean canRender(PonyModel model, EntityRenderState entity) { return super.canRender(model, entity) || (( entity instanceof AbstractPiglinEntity diff --git a/src/main/java/com/minelittlepony/client/model/gear/DeerAntlers.java b/src/main/java/com/minelittlepony/client/model/gear/DeerAntlers.java index f76e9aa3..e7f9dfcf 100644 --- a/src/main/java/com/minelittlepony/client/model/gear/DeerAntlers.java +++ b/src/main/java/com/minelittlepony/client/model/gear/DeerAntlers.java @@ -2,8 +2,9 @@ package com.minelittlepony.client.model.gear; import net.minecraft.client.model.ModelPart; import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.entity.state.BipedEntityRenderState; +import net.minecraft.client.render.entity.state.EntityRenderState; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.Entity; import net.minecraft.util.math.MathHelper; import com.minelittlepony.api.model.BodyPart; @@ -35,18 +36,18 @@ public class DeerAntlers extends WearableGear { private int tint; public DeerAntlers(ModelPart tree) { - super(Wearable.ANTLERS, BodyPart.HEAD, 0); + super(tree, Wearable.ANTLERS, BodyPart.HEAD, 0); left = tree.getChild("left"); right = tree.getChild("right"); } @Override - public boolean canRender(PonyModel model, Entity entity) { + public boolean canRender(PonyModel model, EntityRenderState entity) { return isChristmasDay() || super.canRender(model, entity); } @Override - public void pose(PonyModel model, Entity entity, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) { + public void pose(PonyModel model, S state, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) { float pi = MathHelper.PI * (float) Math.pow(swing, 16); float mve = move * 0.6662f; @@ -56,7 +57,7 @@ public class DeerAntlers extends WearableGear { bodySwing += 0.1F; - tint = model.getAttributes().metadata.glowColor(); + tint = state.getAttributes().metadata.glowColor(); left.roll = bodySwing; right.roll = -bodySwing; } diff --git a/src/main/java/com/minelittlepony/client/model/gear/SaddleBags.java b/src/main/java/com/minelittlepony/client/model/gear/SaddleBags.java index 9b168f53..4aaabe83 100644 --- a/src/main/java/com/minelittlepony/client/model/gear/SaddleBags.java +++ b/src/main/java/com/minelittlepony/client/model/gear/SaddleBags.java @@ -11,8 +11,8 @@ import java.util.UUID; import net.minecraft.client.model.ModelPart; import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.entity.state.BipedEntityRenderState; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.Entity; import net.minecraft.util.math.MathHelper; public class SaddleBags extends WearableGear { @@ -26,15 +26,16 @@ public class SaddleBags extends WearableGear { private float dropAmount = 0; public SaddleBags(ModelPart tree, Wearable wearable) { - super(wearable, BodyPart.BODY, 0); + super(tree, wearable, BodyPart.BODY, 0); strap = tree.getChild("strap"); leftBag = tree.getChild("left_bag"); rightBag = tree.getChild("right_bag"); } + @SuppressWarnings("unchecked") @Override - public void pose(PonyModel model, Entity entity, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) { - hangLow = model instanceof WingedPonyModel pegasus && pegasus.wingsAreOpen(); + public void pose(PonyModel model, S state, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) { + hangLow = model instanceof WingedPonyModel pegasus && pegasus.wingsAreOpen(state); float pi = MathHelper.PI * (float) Math.pow(swing, 16); @@ -46,8 +47,8 @@ public class SaddleBags extends WearableGear { leftBag.pitch = bodySwing; rightBag.pitch = bodySwing; - if (model instanceof WingedPonyModel pegasus && pegasus.getAttributes().isFlying) { - bodySwing = pegasus.getWingRotationFactor(ticks) - MathUtil.Angles._270_DEG; + if (model instanceof WingedPonyModel pegasus && state.getAttributes().isFlying) { + bodySwing = pegasus.getWingRotationFactor(state, ticks) - MathUtil.Angles._270_DEG; bodySwing /= 10; } @@ -59,7 +60,7 @@ public class SaddleBags extends WearableGear { strap.visible = wearable == Wearable.SADDLE_BAGS_BOTH; dropAmount = hangLow ? 0.15F : 0; - dropAmount = model.getAttributes().getMainInterpolator().interpolate("dropAmount", dropAmount, 3); + dropAmount = state.getAttributes().getMainInterpolator().interpolate("dropAmount", dropAmount, 3); } @Override diff --git a/src/main/java/com/minelittlepony/client/model/part/LionTail.java b/src/main/java/com/minelittlepony/client/model/part/LionTail.java index 9c35e963..8bc3cfff 100644 --- a/src/main/java/com/minelittlepony/client/model/part/LionTail.java +++ b/src/main/java/com/minelittlepony/client/model/part/LionTail.java @@ -6,10 +6,10 @@ import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.math.MathHelper; import com.minelittlepony.api.model.SubModel; -import com.minelittlepony.api.model.ModelAttributes; +import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.common.util.animation.Interpolator; -public class LionTail implements SubModel { +public class LionTail implements SubModel { private ModelPart tail; @@ -18,7 +18,7 @@ public class LionTail implements SubModel { } @Override - public void setPartAngles(ModelAttributes attributes, float limbAngle, float limbSpeed, float bodySwing, float animationProgress) { + public void setPartAngles(PonyRenderState state, float limbAngle, float limbSpeed, float bodySwing, float animationProgress) { tail.resetTransform(); bodySwing *= 5; @@ -26,18 +26,18 @@ public class LionTail implements SubModel { float baseSail = 1F; float speed = limbSpeed > 0.01F ? 6 : 90; - Interpolator interpolator = attributes.getMainInterpolator(); + Interpolator interpolator = state.attributes.getMainInterpolator(); float straightness = 1.6F * (1 + (float)Math.sin(animationProgress / speed) / 8F); float twist = (float)Math.sin(Math.PI/2F + 2 * animationProgress / speed) / 16F; - float bend = attributes.motionRoll / 80F; + float bend = state.attributes.motionRoll / 80F; - if (attributes.isCrouching) { + if (state.attributes.isCrouching) { baseSail += 1; straightness += 0.5F; } - if (attributes.isGoingFast || attributes.isSwimming) { + if (state.attributes.isGoingFast || state.attributes.isSwimming) { straightness *= 2; } @@ -84,19 +84,19 @@ public class LionTail implements SubModel { tail5.roll += bend; tail6.roll += bend; - if (attributes.isHorsey) { + if (state.attributes.isHorsey) { tail.pivotZ = 14; tail.pivotY = 7; } } @Override - public void setVisible(boolean visible, ModelAttributes attributes) { + public void setVisible(boolean visible, PonyRenderState state) { tail.visible = visible; } @Override - public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color, ModelAttributes attributes) { + public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color) { tail.render(stack, vertices, overlay, light, color); } } diff --git a/src/main/java/com/minelittlepony/client/model/part/PonyEars.java b/src/main/java/com/minelittlepony/client/model/part/PonyEars.java index f0f68013..627238b6 100644 --- a/src/main/java/com/minelittlepony/client/model/part/PonyEars.java +++ b/src/main/java/com/minelittlepony/client/model/part/PonyEars.java @@ -6,11 +6,11 @@ import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.math.MathHelper; import com.minelittlepony.api.model.SubModel; -import com.minelittlepony.api.model.ModelAttributes; +import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.mson.api.*; import com.minelittlepony.mson.api.model.PartBuilder; -public class PonyEars implements SubModel, MsonModel { +public class PonyEars implements SubModel, MsonModel { private final ModelPart right; private final ModelPart left; @@ -27,7 +27,7 @@ public class PonyEars implements SubModel, MsonModel { } @Override - public void setPartAngles(ModelAttributes attributes, float limbAngle, float limbSpeed, float bodySwing, float animationProgress) { + public void setPartAngles(PonyRenderState state, float limbAngle, float limbSpeed, float bodySwing, float animationProgress) { right.resetTransform(); left.resetTransform(); @@ -52,15 +52,15 @@ public class PonyEars implements SubModel, MsonModel { } @Override - public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color, ModelAttributes attributes) { + public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color) { } @Override - public void setVisible(boolean visible, ModelAttributes attributes) { - right.visible = visible && !attributes.metadata.race().isHuman(); - left.visible = visible && !attributes.metadata.race().isHuman(); + public void setVisible(boolean visible, PonyRenderState state) { + right.visible = visible && !state.getRace().isHuman(); + left.visible = visible && !state.getRace().isHuman(); - if (attributes.isHorsey) { + if (state.attributes.isHorsey) { left.pivotX = -1; right.pivotX = 1; left.pivotY = right.pivotY = 1; diff --git a/src/main/java/com/minelittlepony/client/model/part/PonySnout.java b/src/main/java/com/minelittlepony/client/model/part/PonySnout.java index e2f4c5cc..d5e599ea 100644 --- a/src/main/java/com/minelittlepony/client/model/part/PonySnout.java +++ b/src/main/java/com/minelittlepony/client/model/part/PonySnout.java @@ -6,12 +6,12 @@ import net.minecraft.client.util.math.MatrixStack; import com.minelittlepony.api.config.PonyConfig; import com.minelittlepony.api.model.SubModel; -import com.minelittlepony.api.model.ModelAttributes; import com.minelittlepony.api.pony.meta.Gender; +import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.mson.api.*; import com.minelittlepony.mson.api.model.PartBuilder; -public class PonySnout implements SubModel, MsonModel { +public class PonySnout implements SubModel, MsonModel { private final ModelPart mare; private final ModelPart stallion; @@ -34,15 +34,15 @@ public class PonySnout implements SubModel, MsonModel { } @Override - public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color, ModelAttributes attributes) { + public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color) { } @Override - public void setVisible(boolean visible, ModelAttributes attributes) { - visible &= !attributes.isHorsey - && !attributes.metadata.race().isHuman() + public void setVisible(boolean visible, PonyRenderState state) { + visible &= !state.attributes.isHorsey + && !state.attributes.metadata.race().isHuman() && PonyConfig.getInstance().snuzzles.get(); - Gender gender = attributes.metadata.gender(); + Gender gender = state.attributes.metadata.gender(); mare.visible = (visible && gender.isMare()); stallion.visible = (visible && gender.isStallion()); diff --git a/src/main/java/com/minelittlepony/client/model/part/PonyTail.java b/src/main/java/com/minelittlepony/client/model/part/PonyTail.java index d386d067..31053d90 100644 --- a/src/main/java/com/minelittlepony/client/model/part/PonyTail.java +++ b/src/main/java/com/minelittlepony/client/model/part/PonyTail.java @@ -8,13 +8,14 @@ import net.minecraft.util.math.MathHelper; import com.minelittlepony.api.model.*; import com.minelittlepony.api.pony.meta.TailShape; import com.minelittlepony.client.model.AbstractPonyModel; +import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.mson.api.*; import com.minelittlepony.util.MathUtil; import java.util.List; import java.util.stream.IntStream; -public class PonyTail implements SubModel, MsonModel { +public class PonyTail implements SubModel, MsonModel { private static final float TAIL_Z = 14; private static final float TAIL_RIDING_Y = 3; private static final float TAIL_RIDING_Z = 13; @@ -43,15 +44,15 @@ public class PonyTail implements SubModel, MsonModel { } @Override - public void setPartAngles(ModelAttributes attributes, float limbAngle, float limbSpeed, float bodySwing, float animationProgress) { - boolean rainboom = attributes.isSwimming || attributes.isGoingFast; + public void setPartAngles(PonyRenderState state, float limbAngle, float limbSpeed, float bodySwing, float animationProgress) { + boolean rainboom = state.attributes.isSwimming || state.attributes.isGoingFast; tail.roll = rainboom ? 0 : MathHelper.cos(limbAngle * 0.8F) * 0.2f * limbSpeed; tail.yaw = bodySwing * 5; - if (attributes.isCrouching && !rainboom) { + if (state.attributes.isCrouching && !rainboom) { tail.setPivot(0, 0, TAIL_SNEAKING_Z); tail.pitch = -model.body.pitch + 0.1F; - } else if (attributes.isSitting) { + } else if (state.attributes.isSitting) { tail.pivotZ = TAIL_RIDING_Z; tail.pivotY = TAIL_RIDING_Y; tail.pitch = MathHelper.PI / 5; @@ -70,6 +71,10 @@ public class PonyTail implements SubModel, MsonModel { tail.pivotY += 6; tail.pivotZ++; } + + for (int i = 0; i < segments.size(); i++) { + segments.get(i).setAngles(i, this, state.attributes); + } } private void swingX(float ticks) { @@ -79,19 +84,19 @@ public class PonyTail implements SubModel, MsonModel { } @Override - public void setVisible(boolean visible, ModelAttributes attributes) { + public void setVisible(boolean visible, PonyRenderState state) { tail.visible = visible; - tailStop = attributes.metadata.tailLength().ordinal(); - shape = attributes.metadata.tailShape(); + tailStop = state.attributes.metadata.tailLength().ordinal(); + shape = state.attributes.metadata.tailShape(); } @Override - public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color, ModelAttributes attributes) { + public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color) { stack.push(); tail.rotate(stack); for (int i = 0; i < segments.size(); i++) { - segments.get(i).render(this, stack, vertices, i, overlay, light, color, attributes); + segments.get(i).render(stack, vertices, i, overlay, light, color); } stack.pop(); @@ -99,15 +104,17 @@ public class PonyTail implements SubModel, MsonModel { public static class Segment { private final ModelPart tree; + private TailShape shape; + private boolean horsey; public Segment(ModelPart tree) { this.tree = tree; } - public void render(PonyTail tail, MatrixStack stack, VertexConsumer renderContext, int index, int overlay, int light, int color, ModelAttributes attributes) { - if (index >= tail.tailStop) { - return; - } + public void setAngles(int index, PonyTail tail, ModelAttributes attributes) { + tree.visible = index >= tail.tailStop; + shape = tail.shape; + horsey = attributes.isHorsey; if (attributes.isHorsey) { tree.pitch = 0.5F; @@ -115,29 +122,35 @@ public class PonyTail implements SubModel, MsonModel { } else { tree.resetTransform(); } + } - if (attributes.isHorsey || tail.shape == TailShape.STRAIGHT) { + public void render(MatrixStack stack, VertexConsumer renderContext, int index, int overlay, int light, int color) { + if (!tree.visible) { + return; + } + + if (horsey || shape == TailShape.STRAIGHT) { tree.yaw = 0; tree.render(stack, renderContext, overlay, light, color); return; } stack.push(); - if (tail.shape == TailShape.BUMPY) { + if (shape == TailShape.BUMPY) { stack.translate(0, 0, -9/16F); float scale = 1 + MathHelper.cos(index + 5) / 2F; stack.scale(scale, 1, scale); stack.translate(1 / 16F * scale - 0.1F, 0, -2 / 16F * scale); tree.pivotZ = 9; } - if (tail.shape == TailShape.SWIRLY) { + if (shape == TailShape.SWIRLY) { stack.translate(0, 0, -6/16F); float scale = 1 + MathHelper.cos(index + 10) / 5F; stack.scale(1, 1, scale); stack.translate(0, 0, -2 / 16F * scale); tree.pivotZ = 9; } - if (tail.shape == TailShape.SPIKY) { + if (shape == TailShape.SPIKY) { stack.translate(0, 0, -6/16F); float scale = 1 + MathHelper.cos(index + 10) / 5F; stack.scale(1, 1, scale); diff --git a/src/main/java/com/minelittlepony/client/model/part/PonyWings.java b/src/main/java/com/minelittlepony/client/model/part/PonyWings.java index e2ab603a..aed26454 100644 --- a/src/main/java/com/minelittlepony/client/model/part/PonyWings.java +++ b/src/main/java/com/minelittlepony/client/model/part/PonyWings.java @@ -1,6 +1,5 @@ package com.minelittlepony.client.model.part; -import net.minecraft.client.model.Model; import net.minecraft.client.model.ModelPart; import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.util.math.MatrixStack; @@ -8,18 +7,19 @@ import net.minecraft.util.math.MathHelper; import com.minelittlepony.api.model.*; import com.minelittlepony.api.pony.meta.Wearable; +import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.mson.api.ModelView; import com.minelittlepony.mson.api.MsonModel; import com.minelittlepony.util.MathUtil; -public class PonyWings> implements SubModel, MsonModel { +public class PonyWings implements SubModel, MsonModel { - protected T pegasus; + private WingedPonyModel pegasus; - protected Wing leftWing; - protected Wing rightWing; + protected Wing leftWing; + protected Wing rightWing; - protected Wing legacyWing; + protected Wing legacyWing; public PonyWings(ModelPart tree) { @@ -44,22 +44,22 @@ public class PonyWings> implements SubModel legacyWing.walkingRotationSpeed = walkingRotationSpeed; } - public Wing getLeft() { + public Wing getLeft(S state) { return leftWing; } - public Wing getRight() { + public Wing getRight(S state) { return ( - pegasus.isEmbedded(Wearable.SADDLE_BAGS_BOTH) - || pegasus.isEmbedded(Wearable.SADDLE_BAGS_LEFT) - || pegasus.isEmbedded(Wearable.SADDLE_BAGS_RIGHT) + state.isEmbedded(Wearable.SADDLE_BAGS_BOTH) + || state.isEmbedded(Wearable.SADDLE_BAGS_LEFT) + || state.isEmbedded(Wearable.SADDLE_BAGS_RIGHT) ) ? legacyWing : rightWing; } @Override - public void setPartAngles(ModelAttributes attributes, float move, float swing, float bodySwing, float ticks) { + public void setPartAngles(S state, float move, float swing, float bodySwing, float ticks) { float flap = 0; - float progress = pegasus.getSwingAmount(); + float progress = state.getSwingAmount(); if (progress > 0) { flap = MathHelper.sin(MathHelper.sqrt(progress) * MathHelper.TAU); @@ -72,38 +72,58 @@ public class PonyWings> implements SubModel flap = MathHelper.cos(mve + pi) * srt; } - getLeft().rotateWalking(flap); - getRight().rotateWalking(-flap); - float flapAngle = MathUtil.Angles._270_DEG; - if (pegasus.wingsAreOpen()) { - flapAngle = pegasus.getWingRotationFactor(ticks); - if (!attributes.isCrouching && pegasus.isBurdened()) { + if (pegasus.wingsAreOpen(state)) { + flapAngle = pegasus.getWingRotationFactor(state, ticks); + if (!state.attributes.isCrouching && pegasus.isBurdened(state)) { flapAngle -= 1F; } } else { flapAngle = MathUtil.Angles._270_DEG - 0.9F + (float)Math.sin(ticks / 10) / 15F; } - if (!pegasus.getAttributes().isFlying) { - flapAngle = attributes.getMainInterpolator().interpolate("wingFlap", flapAngle, 10); + if (!state.attributes.isFlying) { + flapAngle = state.attributes.getMainInterpolator().interpolate("wingFlap", flapAngle, 10); } - getLeft().rotateFlying(flapAngle); - getRight().rotateFlying(-flapAngle); + boolean extended = pegasus.wingsAreOpen(state); + boolean bags = !extended && state.isWearing(Wearable.SADDLE_BAGS_BOTH); + + boolean useLegacyWing = ( + state.isEmbedded(Wearable.SADDLE_BAGS_BOTH) + || state.isEmbedded(Wearable.SADDLE_BAGS_LEFT) + || state.isEmbedded(Wearable.SADDLE_BAGS_RIGHT) + ); + + leftWing.open = extended; + leftWing.bags = bags; + leftWing.setAngles(state, flap, flapAngle); + + rightWing.open = extended; + rightWing.bags = bags; + rightWing.setAngles(state, -flap, -flapAngle); + + if (legacyWing != rightWing) { + rightWing.root.hidden = useLegacyWing; + legacyWing.root.hidden = !useLegacyWing; + legacyWing.open = extended; + legacyWing.bags = bags; + legacyWing.setAngles(state, -flap, -flapAngle); + } } @Override - public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color, ModelAttributes attributes) { - getLeft().render(stack, vertices, overlay, light, color); - getRight().render(stack, vertices, overlay, light, color); + public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color) { + leftWing.render(stack, vertices, overlay, light, color); + rightWing.render(stack, vertices, overlay, light, color); + legacyWing.render(stack, vertices, overlay, light, color); } - public static class Wing implements MsonModel { + public static class Wing implements MsonModel { - protected WingedPonyModel pegasus; + private final ModelPart root; protected final ModelPart extended; protected final ModelPart folded; @@ -111,49 +131,36 @@ public class PonyWings> implements SubModel private float wingScale = 1; private float walkingRotationSpeed = 0.15F; + public boolean hidden; + public boolean open; + public boolean bags; + public Wing(ModelPart tree) { + root = tree; extended = tree.getChild("extended"); folded = tree.getChild("folded"); } - @Override - public void init(ModelView context) { - pegasus = context.getModel(); - } - - public void rotateWalking(float swing) { + public void setAngles(S state, float swing, float roll) { + root.pivotY = root.getDefaultTransform().pivotY() + (bags ? 0.198F / wingScale : 0); + root.xScale = wingScale; + root.yScale = wingScale; + root.zScale = wingScale; + extended.visible = open; + folded.visible = !open; folded.yaw = swing * walkingRotationSpeed; - if (pegasus.getRace().hasBugWings()) { + if (state.getRace().hasBugWings()) { extended.yaw = folded.yaw; } - } - public void rotateFlying(float roll) { extended.roll = roll; - if (pegasus.getRace().hasBugWings()) { + if (state.getRace().hasBugWings()) { folded.roll = roll; } } - public void render(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color) { - stack.push(); - stack.scale(wingScale, wingScale, wingScale); - - if (pegasus.wingsAreOpen()) { - extended.render(stack, vertices, overlay, light, color); - } else { - boolean bags = pegasus.isWearing(Wearable.SADDLE_BAGS_BOTH); - if (bags) { - stack.push(); - stack.translate(0, 0, 0.198F); - } - folded.render(stack, vertices, overlay, light, color); - if (bags) { - stack.pop(); - } - } - - stack.pop(); + public void render(MatrixStack matrices, VertexConsumer vertices, int overlay, int light, int color) { + root.render(matrices, vertices, overlay, light, color); } } } diff --git a/src/main/java/com/minelittlepony/client/model/part/SeaponyTail.java b/src/main/java/com/minelittlepony/client/model/part/SeaponyTail.java index 364a39ab..0e90d45e 100644 --- a/src/main/java/com/minelittlepony/client/model/part/SeaponyTail.java +++ b/src/main/java/com/minelittlepony/client/model/part/SeaponyTail.java @@ -1,7 +1,7 @@ package com.minelittlepony.client.model.part; import com.minelittlepony.api.model.SubModel; -import com.minelittlepony.api.model.ModelAttributes; +import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.mson.api.MsonModel; import net.minecraft.client.model.ModelPart; @@ -9,7 +9,7 @@ import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.math.MathHelper; -public class SeaponyTail implements SubModel, MsonModel { +public class SeaponyTail implements SubModel, MsonModel { private final ModelPart tailBase; private final ModelPart tailTip; @@ -22,14 +22,14 @@ public class SeaponyTail implements SubModel, MsonModel { } @Override - public void setPartAngles(ModelAttributes attributes, float limbAngle, float limbSpeed, float bodySwing, float animationProgress) { - float rotation = attributes.isLyingDown ? 0 : MathHelper.sin(animationProgress * 0.536f) / 4; + public void setPartAngles(PonyRenderState state, float limbAngle, float limbSpeed, float bodySwing, float animationProgress) { + float rotation = state.attributes.isLyingDown ? 0 : MathHelper.sin(animationProgress * 0.536f) / 4; tailBase.pitch = MathHelper.HALF_PI + rotation; tailTip.pitch = rotation; tailFins.pitch = rotation - MathHelper.HALF_PI; - float turn = MathHelper.clamp(attributes.motionRoll * 0.05F + bodySwing, -0.4F, 0.4F); + float turn = MathHelper.clamp(state.attributes.motionRoll * 0.05F + bodySwing, -0.4F, 0.4F); tailBase.yaw = turn; turn /= 2F; @@ -39,7 +39,7 @@ public class SeaponyTail implements SubModel, MsonModel { } @Override - public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color, ModelAttributes attributes) { + public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color) { tailBase.render(stack, vertices, overlay, light, color); } diff --git a/src/main/java/com/minelittlepony/client/model/part/UnicornHorn.java b/src/main/java/com/minelittlepony/client/model/part/UnicornHorn.java index 4c9c2520..43b0335b 100644 --- a/src/main/java/com/minelittlepony/client/model/part/UnicornHorn.java +++ b/src/main/java/com/minelittlepony/client/model/part/UnicornHorn.java @@ -8,10 +8,10 @@ import net.minecraft.client.render.VertexConsumerProvider.Immediate; import net.minecraft.client.util.math.MatrixStack; import com.minelittlepony.api.model.SubModel; -import com.minelittlepony.api.model.ModelAttributes; import com.minelittlepony.client.render.MagicGlow; +import com.minelittlepony.client.render.entity.state.PonyRenderState; -public class UnicornHorn implements SubModel { +public class UnicornHorn implements SubModel { private final ModelPart horn; private final ModelPart glow; @@ -24,7 +24,7 @@ public class UnicornHorn implements SubModel { } @Override - public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color, ModelAttributes attributes) { + public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color) { horn.render(stack, vertices, overlay, light, color); } @@ -38,7 +38,7 @@ public class UnicornHorn implements SubModel { } @Override - public void setVisible(boolean visible, ModelAttributes attributes) { + public void setVisible(boolean visible, PonyRenderState state) { horn.visible = visible; glow.visible = visible; } diff --git a/src/main/java/com/minelittlepony/client/render/ArmorRenderLayers.java b/src/main/java/com/minelittlepony/client/render/ArmorRenderLayers.java index 261732a3..e720f4ff 100644 --- a/src/main/java/com/minelittlepony/client/render/ArmorRenderLayers.java +++ b/src/main/java/com/minelittlepony/client/render/ArmorRenderLayers.java @@ -2,8 +2,7 @@ package com.minelittlepony.client.render; import net.minecraft.client.render.*; import net.minecraft.client.render.RenderLayer.MultiPhaseParameters; -import net.minecraft.util.Identifier; -import net.minecraft.util.Util; +import net.minecraft.util.*; import java.util.function.BiFunction; @@ -16,7 +15,7 @@ public class ArmorRenderLayers extends RenderPhase { return RenderLayer.of(decal ? "armor_decal_translucent_no_cull" : "armor_translucent_no_cull", VertexFormats.POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL, VertexFormat.DrawMode.QUADS, 256, true, false, MultiPhaseParameters.builder() .program(ARMOR_CUTOUT_NO_CULL_PROGRAM) - .texture(new RenderPhase.Texture(texture, false, false)) + .texture(new RenderPhase.Texture(texture, TriState.FALSE, false)) .transparency(TRANSLUCENT_TRANSPARENCY) .cull(DISABLE_CULLING) .lightmap(ENABLE_LIGHTMAP) diff --git a/src/main/java/com/minelittlepony/client/render/DebugBoundingBoxRenderer.java b/src/main/java/com/minelittlepony/client/render/DebugBoundingBoxRenderer.java index 9174a96e..e209f5f4 100644 --- a/src/main/java/com/minelittlepony/client/render/DebugBoundingBoxRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/DebugBoundingBoxRenderer.java @@ -1,21 +1,12 @@ package com.minelittlepony.client.render; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.VertexConsumer; -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.WorldRenderer; -import net.minecraft.client.render.entity.EntityRenderer; -import net.minecraft.client.render.entity.state.BipedEntityRenderState; +import net.minecraft.client.render.*; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.LivingEntity; import net.minecraft.util.math.Box; -import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; import com.minelittlepony.api.model.RenderPass; -import com.minelittlepony.api.pony.Pony; -import com.minelittlepony.client.PonyBounds; import com.minelittlepony.client.render.entity.state.PonyRenderState; public final class DebugBoundingBoxRenderer { @@ -35,15 +26,21 @@ public final class DebugBoundingBoxRenderer { stack.push(); stack.translate(-offset.x, -offset.y, -offset.z); - Box boundingBox = PonyBounds.getBoundingBox(state.pony, state); - double x = -state.x; double y = -state.y; double z = -state.z; VertexConsumer vertices = matrices.getBuffer(RenderLayer.getLines()); - WorldRenderer.drawBox(stack, vertices, boundingBox.offset(x, y, z), 1, 1, 0, 1); + VertexRendering.drawBox(stack, vertices, getBoundingBox(state).offset(x, y, z), 1, 1, 0, 1); stack.pop(); } + + public static Box getBoundingBox(PonyRenderState state) { + final float scale = state.getScaleFactor(); + final float width = state.width * scale; + final float height = state.height * scale; + + return new Box(-width, 0, -width, width, height, width).offset(state.x, state.y, state.z); + } } diff --git a/src/main/java/com/minelittlepony/client/render/EquineRenderManager.java b/src/main/java/com/minelittlepony/client/render/EquineRenderManager.java index 306c7867..86931672 100644 --- a/src/main/java/com/minelittlepony/client/render/EquineRenderManager.java +++ b/src/main/java/com/minelittlepony/client/render/EquineRenderManager.java @@ -10,7 +10,6 @@ import com.minelittlepony.client.PonyDataLoader; import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.client.transform.PonyPosture; import com.minelittlepony.mson.api.ModelKey; -import com.minelittlepony.util.MathUtil; import com.mojang.blaze3d.systems.RenderSystem; import java.util.*; @@ -21,10 +20,8 @@ import net.fabricmc.api.EnvType; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.Frustum; 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.util.math.MatrixStack; -import net.minecraft.entity.EntityPose; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; @@ -35,9 +32,9 @@ public class EquineRenderManager< S extends PonyRenderState, M extends EntityModel & PonyModel> { - private Models models; - @Nullable - private Function> modelsLookup; + private Models models; + + private Function> modelsLookup = s -> models; private final PonyRenderContext context; private final Transformer transformer; @@ -48,7 +45,7 @@ public class EquineRenderManager< RenderSystem.disableBlend(); } - public EquineRenderManager(PonyRenderContext context, Transformer transformer, Models models) { + public EquineRenderManager(PonyRenderContext context, Transformer transformer, Models models) { this.context = context; this.transformer = transformer; this.models = models; @@ -61,11 +58,11 @@ public class EquineRenderManager< this(context, transformer, new Models(key)); } - public void setModelsLookup(@Nullable Function> modelsLookup) { + public void setModelsLookup(Function> modelsLookup) { this.modelsLookup = modelsLookup; } - public Models getModels() { + public Models getModels() { return models; } @@ -80,32 +77,28 @@ public class EquineRenderManager< return frustrum.withCamera(entity, vanilla); } - public void preRender(T entity, S state, ModelAttributes.Mode mode) { - Pony pony = context.getEntityPony(entity); - if (modelsLookup != null) { - models = modelsLookup.apply(state); - context.setModel(models.body()); - } - models.applyMetadata(pony.metadata()); - state.updateState(entity, models.body(), pony, mode); + public void updateState(T entity, S state, ModelAttributes.Mode mode) { + models = modelsLookup.apply(state); + context.setModel(models.body()); + state.updateState(entity, models.body(), context.getEntityPony(entity), mode); } public void setupTransforms(S state, MatrixStack stack, float animationProgress, float bodyYaw) { float s = state.getScaleFactor(); stack.scale(s, s, s); - if (state instanceof PlayerEntityRenderState) { - if (state.attributes.isSitting) { - stack.translate(0, 0.125D, 0); - } + if (state instanceof PlayerEntityRenderState && state.attributes.isSitting) { + stack.translate(0, 0.125D, 0); } transformer.setupTransforms(state, stack, animationProgress, bodyYaw); - PonyPosture.of(state.attributes).apply(state, getModels().body(), stack, bodyYaw, state.age, 1); + if (RenderPass.getCurrent() == RenderPass.WORLD) { + PonyPosture.of(state.attributes).transform(state, stack); + } } - public interface Transformer { + public interface Transformer { void setupTransforms(S state, MatrixStack stack, float animationProgress, float bodyYaw); } @@ -113,7 +106,7 @@ public class EquineRenderManager< SyncedPony getSyncedPony(); } - public interface ModelHolder & PonyModel> { + public interface ModelHolder & PonyModel> { void setModel(M model); } diff --git a/src/main/java/com/minelittlepony/client/render/LevitatingItemRenderer.java b/src/main/java/com/minelittlepony/client/render/LevitatingItemRenderer.java index e45e7dd2..6fe54f53 100644 --- a/src/main/java/com/minelittlepony/client/render/LevitatingItemRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/LevitatingItemRenderer.java @@ -4,21 +4,22 @@ import com.minelittlepony.api.config.PonyConfig; import com.minelittlepony.api.model.HornedPonyModel; import com.minelittlepony.api.pony.Pony; import com.minelittlepony.client.MineLittlePony; +import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.common.util.render.RenderLayerUtil; import org.jetbrains.annotations.Nullable; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.*; +import net.minecraft.client.render.entity.LivingEntityRenderer; import net.minecraft.client.render.item.ItemRenderer; -import net.minecraft.client.render.model.json.ModelTransformationMode; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.component.DataComponentTypes; import net.minecraft.entity.LivingEntity; import net.minecraft.item.*; +import net.minecraft.item.consume.UseAction; import net.minecraft.registry.Registries; import net.minecraft.screen.PlayerScreenHandler; -import net.minecraft.util.UseAction; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.RotationAxis; import net.minecraft.world.World; @@ -43,47 +44,47 @@ public class LevitatingItemRenderer { || mode == ModelTransformationMode.THIRD_PERSON_LEFT_HAND || mode == ModelTransformationMode.THIRD_PERSON_RIGHT_HAND) ) { - if (MineLittlePony.getInstance().getRenderDispatcher().getPonyRenderer(entity) instanceof PonyRenderContext context) { - Pony pony = context.getEntityPony(entity); - if (context.getInternalRenderer().getModels().body() instanceof HornedPonyModel model) { - matrix.push(); + var context = MineLittlePony.getInstance().getRenderDispatcher().getPonyRenderer(entity); + if (context != null) { + var state = context.getAndUpdateRenderState(entity, MinecraftClient.getInstance().getRenderTickCounter().getTickDelta(false)); - boolean doMagic = (mode.isFirstPerson() ? PonyConfig.getInstance().fpsmagic : PonyConfig.getInstance().tpsmagic).get() && model.hasMagic(); + matrix.push(); - if (doMagic && mode.isFirstPerson()) { - setupPerspective(itemRenderer, entity, stack, left, matrix); - } + boolean doMagic = (mode.isFirstPerson() ? PonyConfig.getInstance().fpsmagic : PonyConfig.getInstance().tpsmagic).get() && state.hasMagicGlow(); - itemRenderer.renderItem(entity, stack, mode, left, matrix, renderContext, world, lightUv, OverlayTexture.DEFAULT_UV, posLong); - - if (doMagic) { - VertexConsumerProvider interceptedContext = getProvider(pony, renderContext); - - if (stack.hasGlint()) { - stack = stack.copy(); - stack.set(DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE, false); - } - - float tickDelta = MinecraftClient.getInstance().getRenderTickCounter().getTickDelta(false) + entity.age; - - - float driftStrength = 0.002F; - float xDrift = MathHelper.sin(tickDelta / 20F) * driftStrength; - float zDrift = MathHelper.cos((tickDelta + 20) / 20F) * driftStrength; - - float scale = 1.1F + (MathHelper.sin(tickDelta / 20F) + 1) * driftStrength; - matrix.scale(scale, scale, scale); - matrix.translate(0.015F + xDrift, 0.01F, 0.01F + zDrift); - - itemRenderer.renderItem(entity, stack, mode, left, matrix, interceptedContext, world, lightUv, OverlayTexture.DEFAULT_UV, posLong); - matrix.scale(scale, scale, scale); - matrix.translate(-0.03F - xDrift, -0.02F, -0.02F - zDrift); - itemRenderer.renderItem(entity, stack, mode, left, matrix, interceptedContext, world, lightUv, OverlayTexture.DEFAULT_UV, posLong); - } - - matrix.pop(); - return; + if (doMagic && mode.isFirstPerson()) { + setupPerspective(itemRenderer, entity, stack, left, matrix); } + + itemRenderer.renderItem(entity, stack, mode, left, matrix, renderContext, world, lightUv, OverlayTexture.DEFAULT_UV, posLong); + + if (doMagic) { + VertexConsumerProvider interceptedContext = getProvider(state.pony, renderContext); + + if (stack.hasGlint()) { + stack = stack.copy(); + stack.set(DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE, false); + } + + float tickDelta = MinecraftClient.getInstance().getRenderTickCounter().getTickDelta(false) + entity.age; + + + float driftStrength = 0.002F; + float xDrift = MathHelper.sin(tickDelta / 20F) * driftStrength; + float zDrift = MathHelper.cos((tickDelta + 20) / 20F) * driftStrength; + + float scale = 1.1F + (MathHelper.sin(tickDelta / 20F) + 1) * driftStrength; + matrix.scale(scale, scale, scale); + matrix.translate(0.015F + xDrift, 0.01F, 0.01F + zDrift); + + itemRenderer.renderItem(entity, stack, mode, left, matrix, interceptedContext, world, lightUv, OverlayTexture.DEFAULT_UV, posLong); + matrix.scale(scale, scale, scale); + matrix.translate(-0.03F - xDrift, -0.02F, -0.02F - zDrift); + itemRenderer.renderItem(entity, stack, mode, left, matrix, interceptedContext, world, lightUv, OverlayTexture.DEFAULT_UV, posLong); + } + + matrix.pop(); + return; } } diff --git a/src/main/java/com/minelittlepony/client/render/MobRenderers.java b/src/main/java/com/minelittlepony/client/render/MobRenderers.java index d18553fe..23c3ab2a 100644 --- a/src/main/java/com/minelittlepony/client/render/MobRenderers.java +++ b/src/main/java/com/minelittlepony/client/render/MobRenderers.java @@ -28,8 +28,8 @@ public class MobRenderers { pony.switchRenderer(state, EntityType.VEX, VexRenderer::new); pony.switchRenderer(state, EntityType.EVOKER, IllagerPonyRenderer::evoker); pony.switchRenderer(state, EntityType.VINDICATOR, IllagerPonyRenderer::vindicator); - pony.switchRenderer(state, EntityType.ILLUSIONER, IllagerPonyRenderer.Illusionist::new); - pony.switchRenderer(state, EntityType.PILLAGER, PillagerRenderer::new); + pony.switchRenderer(state, EntityType.ILLUSIONER, IllusionistPonyRenderer::new); + pony.switchRenderer(state, EntityType.PILLAGER, IllagerPonyRenderer::pillager); }); public static final MobRenderers ZOMBIE = register("zombies", (state, pony) -> { pony.switchRenderer(state, EntityType.ZOMBIE, ZomponyRenderer::zombie); diff --git a/src/main/java/com/minelittlepony/client/render/PonyRenderDispatcher.java b/src/main/java/com/minelittlepony/client/render/PonyRenderDispatcher.java index b27a3bf7..a2b69967 100644 --- a/src/main/java/com/minelittlepony/client/render/PonyRenderDispatcher.java +++ b/src/main/java/com/minelittlepony/client/render/PonyRenderDispatcher.java @@ -80,9 +80,9 @@ public class PonyRenderDispatcher { @SuppressWarnings("unchecked") @Nullable - public & PonyModel> PonyRenderContext getPonyRenderer(@Nullable T entity) { + public & PonyModel, R extends LivingEntityRenderer & PonyRenderContext> R getPonyRenderer(@Nullable T entity) { if (entity != null && MinecraftClient.getInstance().getEntityRenderDispatcher().getRenderer(entity) instanceof PonyRenderContext c) { - return c; + return (R)c; } return null; diff --git a/src/main/java/com/minelittlepony/client/render/blockentity/skull/MobSkull.java b/src/main/java/com/minelittlepony/client/render/blockentity/skull/MobSkull.java index c08556b3..956fd229 100644 --- a/src/main/java/com/minelittlepony/client/render/blockentity/skull/MobSkull.java +++ b/src/main/java/com/minelittlepony/client/render/blockentity/skull/MobSkull.java @@ -44,7 +44,6 @@ public class MobSkull implements ISkull { @Override public boolean bindPony(Pony pony) { - ponyHead.get().setMetadata(pony.metadata()); return true; } diff --git a/src/main/java/com/minelittlepony/client/render/blockentity/skull/PlayerPonySkull.java b/src/main/java/com/minelittlepony/client/render/blockentity/skull/PlayerPonySkull.java index 84cd9825..c7c0b8c6 100644 --- a/src/main/java/com/minelittlepony/client/render/blockentity/skull/PlayerPonySkull.java +++ b/src/main/java/com/minelittlepony/client/render/blockentity/skull/PlayerPonySkull.java @@ -23,7 +23,7 @@ import org.joml.Vector3f; public class PlayerPonySkull implements ISkull { private AbstractPonyModel ponyHead; - private final Map>, AbstractPonyModel> modelCache = new HashMap<>(); + private final Map>, AbstractPonyModel> modelCache = new HashMap<>(); private final DJPon3EarsModel deadMau5 = ModelType.DJ_PON_3.createModel(); @@ -61,7 +61,6 @@ public class PlayerPonySkull implements ISkull { } } ponyHead = modelCache.computeIfAbsent(ModelType.getPlayerModel(race), key -> key.getKey(false).createModel()); - ponyHead.setMetadata(pony.metadata()); return true; } diff --git a/src/main/java/com/minelittlepony/client/render/blockentity/skull/PonySkullRenderer.java b/src/main/java/com/minelittlepony/client/render/blockentity/skull/PonySkullRenderer.java index 691064e1..423bede8 100644 --- a/src/main/java/com/minelittlepony/client/render/blockentity/skull/PonySkullRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/blockentity/skull/PonySkullRenderer.java @@ -3,7 +3,6 @@ package com.minelittlepony.client.render.blockentity.skull; import com.minelittlepony.api.config.PonyConfig; import com.minelittlepony.api.pony.Pony; import com.minelittlepony.client.model.ModelType; -import com.minelittlepony.client.model.armour.ArmourLayer; import com.minelittlepony.client.model.armour.ArmourRendererPlugin; import com.minelittlepony.client.render.MobRenderers; import com.minelittlepony.client.render.entity.*; @@ -26,6 +25,7 @@ import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.LivingEntity; import net.minecraft.item.BlockItem; import net.minecraft.item.ItemStack; +import net.minecraft.item.equipment.EquipmentModel.LayerType; import net.minecraft.util.Identifier; import net.minecraft.util.Util; import net.minecraft.util.math.Direction; @@ -112,7 +112,7 @@ public class PonySkullRenderer { VertexConsumer vertices = renderContext.getBuffer(layer); selectedSkull.setAngles(yaw, animationProgress); - selectedSkull.render(stack, vertices, light, OverlayTexture.DEFAULT_UV, Color.argbToHex(ArmourRendererPlugin.INSTANCE.get().getArmourAlpha(EquipmentSlot.HEAD, ArmourLayer.OUTER), 1, 1, 1)); + selectedSkull.render(stack, vertices, light, OverlayTexture.DEFAULT_UV, Color.argbToHex(ArmourRendererPlugin.INSTANCE.get().getArmourAlpha(EquipmentSlot.HEAD, LayerType.HUMANOID), 1, 1, 1)); stack.pop(); diff --git a/src/main/java/com/minelittlepony/client/render/entity/AbstractPonyRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/AbstractPonyRenderer.java index fc37bc2c..d6c96c40 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/AbstractPonyRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/AbstractPonyRenderer.java @@ -55,7 +55,7 @@ public abstract class AbstractPonyRenderer< @Override public void updateRenderState(T entity, S state, float tickDelta) { super.updateRenderState(entity, state, tickDelta); - manager.preRender(entity, state, ModelAttributes.Mode.THIRD_PERSON); + manager.updateState(entity, state, ModelAttributes.Mode.THIRD_PERSON); } protected void addFeatures(EntityRendererFactory.Context context) { @@ -83,7 +83,7 @@ public abstract class AbstractPonyRenderer< @Override public void render(S state, MatrixStack stack, VertexConsumerProvider vertices, int light) { super.render(state, stack, vertices, light); - DebugBoundingBoxRenderer.render(getEntityPony(state), this, state, stack, vertices); + DebugBoundingBoxRenderer.render(state, stack, vertices); } @Override diff --git a/src/main/java/com/minelittlepony/client/render/entity/AllayRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/AllayRenderer.java index 538bd632..3253b41a 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/AllayRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/AllayRenderer.java @@ -2,6 +2,7 @@ package com.minelittlepony.client.render.entity; import net.minecraft.client.render.entity.*; import net.minecraft.client.render.entity.feature.HeldItemFeatureRenderer; +import net.minecraft.client.render.entity.state.BipedEntityRenderState; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.passive.AllayEntity; import net.minecraft.util.Identifier; @@ -12,29 +13,53 @@ import com.minelittlepony.client.MineLittlePony; import com.minelittlepony.client.model.ModelType; import com.minelittlepony.client.model.entity.BreezieModel; +import java.util.UUID; + /** * AKA a breezie :D */ -public class AllayRenderer extends MobEntityRenderer> { +public class AllayRenderer extends MobEntityRenderer { public static final Identifier BREEZIE_PONIES = MineLittlePony.id("textures/entity/allay/pony"); public AllayRenderer(EntityRendererFactory.Context context) { super(context, ModelType.ALLAY.createModel(), 0.4f); - addFeature(new HeldItemFeatureRenderer>(this, context.getHeldItemRenderer())); + addFeature(new HeldItemFeatureRenderer(this, context.getItemRenderer())); } @Override - public Identifier getTexture(AllayEntity allayEntity) { - return MineLittlePony.getInstance().getVariatedTextures().get(BREEZIE_PONIES, allayEntity).orElse(DefaultPonySkinHelper.STEVE); + public State createRenderState() { + return new State(); + } + + public void updateRenderState(AllayEntity entity, State state, float tickDelta) { + super.updateRenderState(entity, state, tickDelta); + state.uuid = entity.getUuid(); + state.dancing = entity.isDancing(); + state.spinning = entity.isSpinning(); + state.spinningAnimationTicks = entity.getSpinningAnimationTicks(tickDelta); + state.itemHoldAnimationTicks = entity.getItemHoldAnimationTicks(tickDelta); } @Override - protected void scale(AllayEntity entity, MatrixStack stack, float ticks) { - stack.scale(0.4F, 0.4F, 0.4F); + public Identifier getTexture(State state) { + return MineLittlePony.getInstance().getVariatedTextures().get(BREEZIE_PONIES, state.uuid).orElse(DefaultPonySkinHelper.STEVE); + } + + @Override + protected void scale(State state, MatrixStack matrices) { + matrices.scale(0.4F, 0.4F, 0.4F); } @Override protected int getBlockLight(AllayEntity allayEntity, BlockPos blockPos) { return 15; } + + public static class State extends BipedEntityRenderState { + public UUID uuid; + public boolean dancing; + public boolean spinning; + public float spinningAnimationTicks; + public float itemHoldAnimationTicks; + } } diff --git a/src/main/java/com/minelittlepony/client/render/entity/AquaticPlayerPonyRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/AquaticPlayerPonyRenderer.java index e1a64ce4..7acbc9d9 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/AquaticPlayerPonyRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/AquaticPlayerPonyRenderer.java @@ -1,16 +1,17 @@ package com.minelittlepony.client.render.entity; -import com.minelittlepony.api.model.PreviewModel; +import com.minelittlepony.api.model.*; import com.minelittlepony.api.pony.*; import com.minelittlepony.api.pony.meta.Race; +import com.minelittlepony.client.render.entity.state.PlayerPonyRenderState; import com.minelittlepony.util.MathUtil; import java.util.function.Predicate; import net.minecraft.client.network.AbstractClientPlayerEntity; -import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.EntityRendererFactory; -import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.EntityPose; +import net.minecraft.entity.LivingEntity; import net.minecraft.particle.ParticleTypes; import net.minecraft.util.Identifier; @@ -21,47 +22,37 @@ public class AquaticPlayerPonyRenderer extends FormChangingPlayerPonyRenderer { } @Override - public void render(AbstractClientPlayerEntity player, float entityYaw, float tickDelta, MatrixStack stack, VertexConsumerProvider renderContext, int light) { - super.render(player, entityYaw, tickDelta, stack, renderContext, light); - - if (!(player instanceof PreviewModel) && transformed && player.getVelocity().length() > 0.1F) { - double x = player.getEntityWorld().getRandom().nextTriangular(player.getX(), 1); - double y = player.getEntityWorld().getRandom().nextTriangular(player.getY(), 1); - double z = player.getEntityWorld().getRandom().nextTriangular(player.getZ(), 1); - player.getEntityWorld().addParticle(ParticleTypes.BUBBLE, x, y, z, 0, 0, 0); - } + protected Race getPlayerRace(PlayerPonyRenderState state) { + Race race = super.getPlayerRace(state); + return ((State)state).skinOverride != null ? Race.SEAPONY : race == Race.SEAPONY ? Race.UNICORN : race; } - @Override - protected Race getPlayerRace(AbstractClientPlayerEntity entity, Pony pony) { - Race race = super.getPlayerRace(entity, pony); - return transformed ? Race.SEAPONY : race == Race.SEAPONY ? Race.UNICORN : race; - } + protected class State extends FormChangingPlayerPonyRenderer.State { + @Override + public void updateState(LivingEntity entity, PonyModel model, Pony pony, ModelAttributes.Mode mode) { + super.updateState(entity, model, pony, mode); + yOffset = skinOverride != null ? (0.6 + (isInSneakingPose ? 0.125 : 0)) : 0; + pose = EntityPose.STANDING; + isInSneakingPose = false; + attributes.isCrouching = false; + if (!isPreviewModel) { + float state = skinOverride != null ? 100 : 0; + float interpolated = attributes.getMainInterpolator().interpolate("seapony_state", state, 5); - @Override - protected void setupTransforms(AbstractClientPlayerEntity player, MatrixStack matrices, float animationProgress, float bodyYaw, float tickDelta, float scale) { - if (transformed) { - matrices.translate(0, 0.6 * scale, 0); - if (player.isInSneakingPose()) { - matrices.translate(0, 0.125 * scale, 0); - } - } - super.setupTransforms(player, matrices, animationProgress, bodyYaw, tickDelta, scale); - } + if (!MathUtil.compareFloats(interpolated, state)) { + double x = entity.getEntityWorld().getRandom().nextTriangular(entity.getX(), 1); + double y = entity.getEntityWorld().getRandom().nextTriangular(entity.getY() + entity.getHeight() * 0.5F, 1); + double z = entity.getEntityWorld().getRandom().nextTriangular(entity.getZ(), 1); - @Override - protected void updateForm(AbstractClientPlayerEntity player) { - super.updateForm(player); - if (!(player instanceof PreviewModel)) { - float state = transformed ? 100 : 0; - float interpolated = getInternalRenderer().getModels().body().getAttributes().getMainInterpolator().interpolate("seapony_state", state, 5); + entity.getEntityWorld().addParticle(ParticleTypes.END_ROD, x, y, z, 0, 0, 0); + } - if (!MathUtil.compareFloats(interpolated, state)) { - double x = player.getEntityWorld().getRandom().nextTriangular(player.getX(), 1); - double y = player.getEntityWorld().getRandom().nextTriangular(player.getY() + player.getHeight() * 0.5F, 1); - double z = player.getEntityWorld().getRandom().nextTriangular(player.getZ(), 1); - - player.getEntityWorld().addParticle(ParticleTypes.END_ROD, x, y, z, 0, 0, 0); + if (!isPreviewModel && skinOverride != null && entity.getVelocity().length() > 0.1F) { + double x = entity.getEntityWorld().getRandom().nextTriangular(entity.getX(), 1); + double y = entity.getEntityWorld().getRandom().nextTriangular(entity.getY(), 1); + double z = entity.getEntityWorld().getRandom().nextTriangular(entity.getZ(), 1); + entity.getEntityWorld().addParticle(ParticleTypes.BUBBLE, x, y, z, 0, 0, 0); + } } } } diff --git a/src/main/java/com/minelittlepony/client/render/entity/EnderStallionRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/EnderStallionRenderer.java index 3217cba3..aa204edf 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/EnderStallionRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/EnderStallionRenderer.java @@ -10,7 +10,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.state.SkeletonPonyRenderState; import com.minelittlepony.client.render.entity.feature.GlowingEyesFeature.IGlowingRenderer; import net.minecraft.block.BlockState; @@ -69,7 +68,7 @@ public class EnderStallionRenderer extends PonyRenderer formModifierPredicate; @@ -22,21 +26,32 @@ public class FormChangingPlayerPonyRenderer extends PlayerPonyRenderer { this.formModifierPredicate = formModifierPredicate; } + public PlayerEntityRenderState createRenderState() { + return new State(); + } + @Override - public Identifier getTexture(AbstractClientPlayerEntity player) { - if (transformed) { - return SkinsProxy.getInstance().getSkin(alternateFormSkinId, player).orElseGet(() -> super.getTexture(player)); + public Identifier getTexture(PlayerEntityRenderState state) { + if (((State)state).skinOverride != null) { + return ((State)state).skinOverride; } - return super.getTexture(player); + return super.getTexture(state); } - @Override - protected final void preRender(AbstractClientPlayerEntity player, ModelAttributes.Mode mode) { - super.preRender(player, mode); - updateForm(player); - } + protected class State extends PlayerPonyRenderState { + @Nullable + public Identifier skinOverride; - protected void updateForm(AbstractClientPlayerEntity player) { - transformed = formModifierPredicate.test(player); + @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) { + return SkinsProxy.getInstance().getSkin(alternateFormSkinId, player).orElse(null); + } } } diff --git a/src/main/java/com/minelittlepony/client/render/entity/PlayerPonyRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/PlayerPonyRenderer.java index e48e81aa..e656e947 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/PlayerPonyRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/PlayerPonyRenderer.java @@ -36,7 +36,7 @@ import net.minecraft.util.math.Vec3d; public class PlayerPonyRenderer extends PlayerEntityRenderer implements PonyRenderContext> { - private final Function>> modelsCache; + private final Function>> modelsCache; protected final EquineRenderManager> manager; private ModelAttributes.Mode mode = ModelAttributes.Mode.THIRD_PERSON; @@ -78,7 +78,7 @@ public class PlayerPonyRenderer public Vec3d getPositionOffset(PlayerEntityRenderState state) { Vec3d offset = super.getPositionOffset(state); - return offset.multiply(((PonyRenderState)state).getScaleFactor()); + return offset.add(state.baseScale * ((PlayerPonyRenderState)state).yOffset).multiply(((PonyRenderState)state).getScaleFactor()); } @Override @@ -89,7 +89,7 @@ public class PlayerPonyRenderer @Override public void updateRenderState(AbstractClientPlayerEntity entity, PlayerEntityRenderState state, float tickDelta) { super.updateRenderState(entity, state, tickDelta); - manager.preRender(entity, (PlayerPonyRenderState)state, mode); + manager.updateState(entity, (PlayerPonyRenderState)state, mode); } public final PlayerPonyRenderState getAndUpdateRenderState(AbstractClientPlayerEntity entity, float tickDelta, ModelAttributes.Mode mode) { diff --git a/src/main/java/com/minelittlepony/client/render/entity/PonyPiglinRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/PonyPiglinRenderer.java index bbd3e97b..5d30a6ef 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/PonyPiglinRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/PonyPiglinRenderer.java @@ -1,17 +1,13 @@ package com.minelittlepony.client.render.entity; import net.minecraft.client.render.entity.EntityRendererFactory; -import net.minecraft.client.render.entity.state.PiglinEntityRenderState; -import net.minecraft.entity.EntityType; import net.minecraft.entity.mob.*; -import net.minecraft.item.CrossbowItem; import net.minecraft.util.Identifier; import com.minelittlepony.client.MineLittlePony; import com.minelittlepony.client.model.ModelType; import com.minelittlepony.client.model.entity.PiglinPonyModel; import com.minelittlepony.client.render.entity.npc.textures.TextureSupplier; -import com.minelittlepony.client.render.entity.state.PonyRenderState; public class PonyPiglinRenderer extends PonyRenderer { public static final Identifier PIGLIN = MineLittlePony.id("textures/entity/piglin/piglin_pony.png"); @@ -39,10 +35,11 @@ public class PonyPiglinRenderer extends PonyRenderer> { public static final Identifier SEAPONY = MineLittlePony.id("textures/entity/guardian/blueball.png"); private static final Identifier SEAPONY_TEXTURES = MineLittlePony.id("textures/entity/guardian"); public static final Identifier ELDER_SEAPONY = MineLittlePony.id("textures/entity/elder_guardian/blueball.png"); private static final Identifier ELDER_SEAPONY_TEXTURES = MineLittlePony.id("textures/entity/elder_guardian"); - private final AbstractPonyRenderer ponyRenderer; + 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 final float scale; + public SeaponyRenderer(EntityRendererFactory.Context context, TextureSupplier texture, float scale) { + super(context, ModelType.GUARDIAN, texture, scale); + } - public SeaponyRenderer(EntityRendererFactory.Context context, TextureSupplier texture, float scale) { - super(context); - ponyRenderer = AbstractPonyRenderer.proxy(context, ModelType.GUARDIAN, texture, scale, features, m -> model = m); - this.scale = scale; + @Override + public State createRenderState() { + return new State(); } public static SeaponyRenderer guardian(EntityRendererFactory.Context context) { @@ -42,30 +46,135 @@ public class SeaponyRenderer extends GuardianEntityRenderer { } @Override - @NotNull - public final Identifier getTexture(GuardianEntity entity) { - return ponyRenderer.getTexture(entity); + public void updateRenderState(GuardianEntity entity, State state, float tickDelta) { + super.updateRenderState(entity, state, tickDelta); + state.spikesExtension = entity.getSpikesExtension(tickDelta); + state.tailAngle = entity.getTailAngle(tickDelta); + state.cameraPosVec = getScaledCameraPosVec(entity, tickDelta, state.getScaleFactor()); + Entity cameraBeamTarget = getBeamTarget(entity); + state.rotationVec = cameraBeamTarget != null ? entity.getRotationVec(tickDelta) : null; + state.lookAtPos = cameraBeamTarget != null ? cameraBeamTarget.getCameraPosVec(tickDelta) : null; + + LivingEntity beamTarget = entity.getBeamTarget(); + if (beamTarget != null) { + state.beamProgress = entity.getBeamProgress(tickDelta); + state.beamTicks = entity.getBeamTicks() + tickDelta; + state.beamTargetPos = fromLerpedPosition(beamTarget, (double)beamTarget.getHeight() * 0.5, tickDelta); + } else { + state.beamTargetPos = null; + } } @Override - protected void scale(GuardianEntity entity, MatrixStack stack, float ticks) { - ponyRenderer.scale(entity, stack, ticks); + public void render(State state, MatrixStack matrices, VertexConsumerProvider vertices, int light) { + super.render(state, matrices, vertices, light); + Vec3d vec3d = state.beamTargetPos; + if (vec3d != null) { + float f = state.beamTicks * 0.5F % 1.0F; + matrices.push(); + matrices.translate(0.0F, state.standingEyeHeight, 0.0F); + renderBeam( + matrices, + vertices.getBuffer(LAYER), + vec3d.subtract(state.cameraPosVec), + state.beamTicks, + state.beamProgress, + f + ); + matrices.pop(); + } } - @Override - public void render(GuardianEntity entity, float entityYaw, float tickDelta, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv) { - ponyRenderer.manager.preRender(entity, ModelAttributes.Mode.THIRD_PERSON); - - float height = entity.getStandingEyeHeight(); - - // aligns the beam to their horns - ((IResizeable)entity).setStandingEyeHeight(2 * scale * ponyRenderer.manager.getScaleFactor()); - super.render(entity, entityYaw, tickDelta, stack, renderContext, lightUv); - ((IResizeable)entity).setStandingEyeHeight(height); + private static void renderBeam(MatrixStack matrices, VertexConsumer vertexConsumer, Vec3d vec3d, float beamTicks, float f, float g) { + float h = (float)(vec3d.length() + 1.0); + vec3d = vec3d.normalize(); + float i = (float)Math.acos(vec3d.y); + float j = (float) (Math.PI / 2) - (float)Math.atan2(vec3d.z, vec3d.x); + matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(j * (180.0F / (float)Math.PI))); + matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(i * (180.0F / (float)Math.PI))); + float k = beamTicks * 0.05F * -1.5F; + float l = f * f; + int m = 64 + (int)(l * 191.0F); + int n = 32 + (int)(l * 191.0F); + int o = 128 - (int)(l * 64.0F); + float p = 0.2F; + float q = 0.282F; + float r = MathHelper.cos(k + (float) (Math.PI * 3.0 / 4.0)) * 0.282F; + float s = MathHelper.sin(k + (float) (Math.PI * 3.0 / 4.0)) * 0.282F; + float t = MathHelper.cos(k + (float) (Math.PI / 4)) * 0.282F; + float u = MathHelper.sin(k + (float) (Math.PI / 4)) * 0.282F; + float v = MathHelper.cos(k + ((float) Math.PI * 5.0F / 4.0F)) * 0.282F; + float w = MathHelper.sin(k + ((float) Math.PI * 5.0F / 4.0F)) * 0.282F; + float x = MathHelper.cos(k + ((float) Math.PI * 7.0F / 4.0F)) * 0.282F; + float y = MathHelper.sin(k + ((float) Math.PI * 7.0F / 4.0F)) * 0.282F; + float z = MathHelper.cos(k + (float) Math.PI) * 0.2F; + float aa = MathHelper.sin(k + (float) Math.PI) * 0.2F; + float ab = MathHelper.cos(k + 0.0F) * 0.2F; + float ac = MathHelper.sin(k + 0.0F) * 0.2F; + float ad = MathHelper.cos(k + (float) (Math.PI / 2)) * 0.2F; + float ae = MathHelper.sin(k + (float) (Math.PI / 2)) * 0.2F; + float af = MathHelper.cos(k + (float) (Math.PI * 3.0 / 2.0)) * 0.2F; + float ag = MathHelper.sin(k + (float) (Math.PI * 3.0 / 2.0)) * 0.2F; + float ai = 0.0F; + float aj = 0.4999F; + float ak = -1.0F + g; + float al = ak + h * 2.5F; + MatrixStack.Entry entry = matrices.peek(); + vertex(vertexConsumer, entry, z, h, aa, m, n, o, 0.4999F, al); + vertex(vertexConsumer, entry, z, 0.0F, aa, m, n, o, 0.4999F, ak); + vertex(vertexConsumer, entry, ab, 0.0F, ac, m, n, o, 0.0F, ak); + vertex(vertexConsumer, entry, ab, h, ac, m, n, o, 0.0F, al); + vertex(vertexConsumer, entry, ad, h, ae, m, n, o, 0.4999F, al); + vertex(vertexConsumer, entry, ad, 0.0F, ae, m, n, o, 0.4999F, ak); + vertex(vertexConsumer, entry, af, 0.0F, ag, m, n, o, 0.0F, ak); + vertex(vertexConsumer, entry, af, h, ag, m, n, o, 0.0F, al); + float am = MathHelper.floor(beamTicks) % 2 == 0 ? 0.5F : 0.0F; + vertex(vertexConsumer, entry, r, h, s, m, n, o, 0.5F, am + 0.5F); + vertex(vertexConsumer, entry, t, h, u, m, n, o, 1.0F, am + 0.5F); + vertex(vertexConsumer, entry, x, h, y, m, n, o, 1.0F, am); + vertex(vertexConsumer, entry, v, h, w, m, n, o, 0.5F, am); } - @Override - protected void setupTransforms(GuardianEntity entity, MatrixStack stack, float animationProgress, float bodyYaw, float tickDelta, float scale) { - ponyRenderer.manager.setupTransforms(entity, stack, animationProgress, bodyYaw, tickDelta, scale); + private static void vertex(VertexConsumer vertexConsumer, MatrixStack.Entry matrix, float x, float y, float z, int red, int green, int blue, float u, float v) { + vertexConsumer.vertex(matrix, x, y, z) + .color(red, green, blue, 255) + .texture(u, v) + .overlay(OverlayTexture.DEFAULT_UV) + .light(LightmapTextureManager.MAX_LIGHT_COORDINATE) + .normal(matrix, 0.0F, 1.0F, 0.0F); + } + + @Nullable + private static Entity getBeamTarget(GuardianEntity guardian) { + Entity entity = MinecraftClient.getInstance().getCameraEntity(); + return guardian.hasBeamTarget() ? guardian.getBeamTarget() : entity; + } + + private Vec3d fromLerpedPosition(LivingEntity entity, double yOffset, float delta) { + double d = MathHelper.lerp((double)delta, entity.lastRenderX, entity.getX()); + double e = MathHelper.lerp((double)delta, entity.lastRenderY, entity.getY()) + yOffset; + double f = MathHelper.lerp((double)delta, entity.lastRenderZ, entity.getZ()); + return new Vec3d(d, e, f); + } + + public static Vec3d getScaledCameraPosVec(GuardianEntity entity, float tickDelta, float scale) { + double d = MathHelper.lerp((double)tickDelta, entity.prevX, entity.getX()); + double e = MathHelper.lerp((double)tickDelta, entity.prevY, entity.getY()) + ((double)entity.getStandingEyeHeight() * scale); + double f = MathHelper.lerp((double)tickDelta, entity.prevZ, entity.getZ()); + return new Vec3d(d, e, f); + } + + public static class State extends PonyRenderState { + public float spikesExtension; + public float tailAngle; + public Vec3d cameraPosVec = Vec3d.ZERO; + @Nullable + public Vec3d rotationVec; + @Nullable + public Vec3d lookAtPos; + @Nullable + public Vec3d beamTargetPos; + public float beamTicks; + public float beamProgress; } } diff --git a/src/main/java/com/minelittlepony/client/render/entity/SkeleponyRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/SkeleponyRenderer.java index 815c6053..a3dede1e 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/SkeleponyRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/SkeleponyRenderer.java @@ -1,16 +1,23 @@ package com.minelittlepony.client.render.entity; +import com.minelittlepony.api.model.ModelAttributes; +import com.minelittlepony.api.model.PonyModel; +import com.minelittlepony.api.pony.Pony; +import com.minelittlepony.api.pony.meta.Race; import com.minelittlepony.client.MineLittlePony; import com.minelittlepony.client.model.ModelType; import com.minelittlepony.client.model.entity.SkeleponyModel; -import com.minelittlepony.client.render.entity.feature.StrayClothingFeature; +import com.minelittlepony.client.render.entity.feature.AbstractClothingFeature; import com.minelittlepony.client.render.entity.npc.textures.TextureSupplier; +import com.minelittlepony.client.render.entity.state.PonyRenderState; import net.minecraft.client.render.entity.EntityRendererFactory; +import net.minecraft.client.render.entity.LivingEntityRenderer; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.mob.*; import net.minecraft.util.Identifier; -public class SkeleponyRenderer extends PonyRenderer> { +public class SkeleponyRenderer extends PonyRenderer> { public static final Identifier SKELETON = MineLittlePony.id("textures/entity/skeleton/skeleton_pony.png"); public static final Identifier WITHER = MineLittlePony.id("textures/entity/skeleton/skeleton_wither_pony.png"); public static final Identifier STRAY = MineLittlePony.id("textures/entity/skeleton/stray_pony.png"); @@ -19,6 +26,11 @@ public class SkeleponyRenderer extends super(context, ModelType.SKELETON, TextureSupplier.of(texture), scale); } + @Override + public SkeleponyRenderer.State createRenderState() { + return new State(); + } + public static SkeleponyRenderer skeleton(EntityRendererFactory.Context context) { return new SkeleponyRenderer<>(context, SKELETON, 1); } @@ -30,4 +42,51 @@ public class SkeleponyRenderer extends public static SkeleponyRenderer wither(EntityRendererFactory.Context context) { return new SkeleponyRenderer<>(context, WITHER, 1.2F); } + + public static class StrayClothingFeature< + T extends AbstractSkeletonEntity, + S extends SkeleponyRenderer.State + > extends AbstractClothingFeature> { + public static final Identifier STRAY_SKELETON_OVERLAY = MineLittlePony.id("textures/entity/skeleton/stray_pony_overlay.png"); + + private final SkeleponyModel overlayModel = ModelType.SKELETON_CLOTHES.createModel(); + + public StrayClothingFeature(LivingEntityRenderer> render) { + super(render); + } + + @Override + protected SkeleponyModel getOverlayModel() { + return overlayModel; + } + + @Override + protected Identifier getOverlayTexture() { + return STRAY_SKELETON_OVERLAY; + } + } + + public static class State extends PonyRenderState { + public boolean isUnicorn; + public boolean isWithered; + public boolean isAttacking; + + public void updateState(LivingEntity entity, PonyModel model, Pony pony, ModelAttributes.Mode mode) { + isUnicorn = entity.getUuid().getLeastSignificantBits() % 3 != 0; + isWithered = entity instanceof WitherSkeletonEntity; + isAttacking = entity instanceof HostileEntity h && h.isAttacking(); + } + + @Override + public Race getRace() { + return isUnicorn ? super.getRace() : Race.EARTH; + } + + @Override + protected float getLegOutset() { + if (attributes.isLyingDown) return 2.6f; + if (attributes.isCrouching) return 0; + return 4; + } + } } diff --git a/src/main/java/com/minelittlepony/client/render/entity/StriderRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/StriderRenderer.java index 3300c6e5..983f08bb 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/StriderRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/StriderRenderer.java @@ -3,35 +3,55 @@ package com.minelittlepony.client.render.entity; import net.minecraft.client.render.entity.EntityRendererFactory; import net.minecraft.client.render.entity.MobEntityRenderer; import net.minecraft.client.render.entity.feature.SaddleFeatureRenderer; -import net.minecraft.client.render.entity.model.EntityModel; +import net.minecraft.client.render.entity.state.BipedEntityRenderState; +import net.minecraft.client.render.entity.state.SaddleableRenderState; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.passive.StriderEntity; import net.minecraft.util.Identifier; +import net.minecraft.util.math.MathHelper; import com.minelittlepony.api.pony.DefaultPonySkinHelper; import com.minelittlepony.client.MineLittlePony; import com.minelittlepony.client.model.ModelType; +import com.minelittlepony.client.model.entity.SpikeModel; -public class StriderRenderer extends MobEntityRenderer> { +import java.util.UUID; + +public class StriderRenderer extends MobEntityRenderer { public static final Identifier DRAGON_PONIES = MineLittlePony.id("textures/entity/strider/pony"); public static final Identifier COLD_DRAGON_PONIES = MineLittlePony.id("textures/entity/strider/cold_pony"); private static final Identifier SADDLE = MineLittlePony.id("textures/entity/strider/strider_saddle_pony.png"); + @SuppressWarnings({"unchecked", "rawtypes"}) public StriderRenderer(EntityRendererFactory.Context context) { super(context, ModelType.STRIDER.createModel(), 0.5F); - addFeature(new SaddleFeatureRenderer<>(this, ModelType.STRIDER_SADDLE.createModel(), SADDLE)); + addFeature(new SaddleFeatureRenderer(this, ModelType.STRIDER_SADDLE.createModel(), SADDLE)); } @Override - public Identifier getTexture(StriderEntity entity) { - return MineLittlePony.getInstance().getVariatedTextures().get(entity.isCold() ? COLD_DRAGON_PONIES : DRAGON_PONIES, entity).orElse(DefaultPonySkinHelper.STEVE); + public State createRenderState() { + return new State(); } @Override - protected void scale(StriderEntity entity, MatrixStack stack, float ticks) { + public void updateRenderState(StriderEntity entity, State state, float tickDelta) { + super.updateRenderState(entity, state, tickDelta); + state.uuid = entity.getUuid(); + state.cold = entity.isCold(); + state.saddled = entity.isSaddled(); + state.flailAmount = 1 + (float)MathHelper.clamp(entity.getVelocity().y * 10, 0, 7); + } + + @Override + public Identifier getTexture(State state) { + return MineLittlePony.getInstance().getVariatedTextures().get(state.cold ? COLD_DRAGON_PONIES : DRAGON_PONIES, state.uuid).orElse(DefaultPonySkinHelper.STEVE); + } + + @Override + protected void scale(State state, MatrixStack stack) { float scale = 0.9375F; - if (entity.isBaby()) { + if (state.baby) { scale *= 0.5F; shadowRadius = 0.25F; } else { @@ -42,7 +62,19 @@ public class StriderRenderer extends MobEntityRenderer> { +import java.util.UUID; + +public class VexRenderer extends MobEntityRenderer { public static final Identifier PARASPRITE_PONIES = MineLittlePony.id("textures/entity/illager/vex_pony"); public VexRenderer(EntityRendererFactory.Context context) { @@ -18,13 +23,43 @@ public class VexRenderer extends MobEntityRenderer extends PonyRenderer> { +public class ZomponyRenderer extends PonyRenderer> { public static final Identifier ZOMBIE = MineLittlePony.id("textures/entity/zombie/zombie_pony.png"); public static final Identifier HUSK = MineLittlePony.id("textures/entity/zombie/husk_pony.png"); public static final Identifier DROWNED = MineLittlePony.id("textures/entity/zombie/drowned_pony.png"); public static final Identifier DEMON_CHILD = MineLittlePony.id("textures/entity/zombie/demon_child.png"); - public ZomponyRenderer(EntityRendererFactory.Context context, TextureSupplier texture, float scale) { + protected ZomponyRenderer(EntityRendererFactory.Context context, TextureSupplier texture, float scale) { super(context, ModelType.ZOMBIE, texture, scale); } + @Override + public State createRenderState() { + return new State(); + } + public static ZomponyRenderer zombie(EntityRendererFactory.Context context) { - return new ZomponyRenderer<>(context, entity -> { - if (entity.isBaby() && entity.getUuid().getLeastSignificantBits() % 160 == 0) { - return DEMON_CHILD; - } - return ZOMBIE; - }, 1); + return new ZomponyRenderer<>(context, entity -> entity.isCozyGlow ? DEMON_CHILD : ZOMBIE, 1); } public static ZomponyRenderer husk(EntityRendererFactory.Context context) { @@ -40,4 +46,20 @@ public class ZomponyRenderer extends PonyRenderer< public static ZomponyRenderer giant(EntityRendererFactory.Context context) { return new ZomponyRenderer<>(context, TextureSupplier.of(ZOMBIE), 6.8F); } + + public static class State extends PonyRenderState { + public boolean isWinged; + public boolean isCozyGlow; + + public void updateState(LivingEntity entity, PonyModel model, Pony pony, ModelAttributes.Mode mode) { + super.updateState(entity, model, pony, mode); + isCozyGlow = baby && entity.getUuid().getLeastSignificantBits() % 160 == 0; + isWinged = entity.getUuid().getLeastSignificantBits() % 30 == 0; + } + + @Override + public Race getRace() { + return isWinged ? (super.getRace().hasHorn() ? Race.ALICORN : Race.PEGASUS) : super.getRace(); + } + } } diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/AbstractClothingFeature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/AbstractClothingFeature.java index 01985523..5fe33a01 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/AbstractClothingFeature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/feature/AbstractClothingFeature.java @@ -18,7 +18,7 @@ import com.minelittlepony.client.render.entity.state.PonyRenderState; public abstract class AbstractClothingFeature< T extends LivingEntity, S extends PonyRenderState, - M extends BipedEntityModel & PonyModel + M extends BipedEntityModel & PonyModel > extends FeatureRenderer { protected final FeatureRendererContext renderer; diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/AbstractPonyFeature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/AbstractPonyFeature.java index 3eb8d46f..91215018 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/AbstractPonyFeature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/feature/AbstractPonyFeature.java @@ -33,7 +33,7 @@ public abstract class AbstractPonyFeature< return context.getInternalRenderer().getModels().body(); } - protected Models getModelWrapper() { + protected Models getModelWrapper() { return context.getInternalRenderer().getModels(); } } diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/ArmourFeature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/ArmourFeature.java index 202b98a7..06c2052f 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/ArmourFeature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/feature/ArmourFeature.java @@ -4,119 +4,71 @@ import com.minelittlepony.api.model.Models; import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.client.model.armour.*; import com.minelittlepony.client.render.PonyRenderContext; -import com.minelittlepony.common.util.Color; - -import java.util.*; +import com.minelittlepony.client.render.entity.state.PonyRenderState; import net.minecraft.client.render.*; +import net.minecraft.client.render.entity.equipment.EquipmentModelLoader; import net.minecraft.client.render.entity.model.*; -import net.minecraft.client.render.entity.state.BipedEntityRenderState; -import net.minecraft.client.render.model.BakedModelManager; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.EquippableComponent; import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.LivingEntity; import net.minecraft.item.*; -import net.minecraft.item.trim.ArmorTrim; -import net.minecraft.util.Colors; +import net.minecraft.item.equipment.EquipmentModel; +import net.minecraft.util.Identifier; -public class ArmourFeature & PonyModel> extends AbstractPonyFeature { - public ArmourFeature(PonyRenderContext context, BakedModelManager bakery) { +public class ArmourFeature & PonyModel> extends AbstractPonyFeature { + + private final PonifiedEquipmentRenderer equipmentRenderer; + + public ArmourFeature(PonyRenderContext context, EquipmentModelLoader modelLoader) { super(context); + this.equipmentRenderer = new PonifiedEquipmentRenderer(modelLoader); } @Override public void render(MatrixStack matrices, VertexConsumerProvider provider, int light, S entity, float limbDistance, float limbAngle) { - renderArmor(getModelWrapper(), matrices, provider, light, entity, limbDistance, limbAngle); + renderArmor(getModelWrapper(), matrices, provider, light, entity, limbDistance, limbAngle, equipmentRenderer); } - public static > void renderArmor( - Models> pony, MatrixStack matrices, + public static > void renderArmor( + Models> pony, MatrixStack matrices, VertexConsumerProvider provider, int light, S entity, - float limbDistance, float limbAngle, - float age, float headYaw, float headPitch) { - ArmourRendererPlugin plugin = ArmourRendererPlugin.INSTANCE.get(); + float limbDistance, float limbAngle, PonifiedEquipmentRenderer equipmentRenderer) { for (EquipmentSlot i : EquipmentSlot.values()) { if (i.getType() == EquipmentSlot.Type.HUMANOID_ARMOR) { - renderArmor(pony, matrices, provider, light, entity, limbDistance, limbAngle, age, headYaw, headPitch, i, ArmourLayer.INNER, plugin); - renderArmor(pony, matrices, provider, light, entity, limbDistance, limbAngle, age, headYaw, headPitch, i, ArmourLayer.OUTER, plugin); + renderArmor(pony, matrices, provider, light, entity, limbDistance, limbAngle, i, ArmourLayer.INNER, equipmentRenderer); + renderArmor(pony, matrices, provider, light, entity, limbDistance, limbAngle, i, ArmourLayer.OUTER, equipmentRenderer); } } } - private static > void renderArmor( - Models> pony, MatrixStack matrices, - VertexConsumerProvider provider, int light, S entity, + private static > void renderArmor( + Models> models, MatrixStack matrices, + VertexConsumerProvider vertices, int light, S entity, float limbDistance, float limbAngle, - float age, float headYaw, float headPitch, - EquipmentSlot armorSlot, ArmourLayer layer, ArmourRendererPlugin plugin) { + EquipmentSlot armorSlot, ArmourLayer layer, PonifiedEquipmentRenderer equipmentRenderer) { + + ArmourRendererPlugin plugin = ArmourRendererPlugin.INSTANCE.get(); for (ItemStack stack : plugin.getArmorStacks(entity, armorSlot, layer, ArmourRendererPlugin.ArmourType.ARMOUR)) { - if (stack.isEmpty()) { - continue; - } + EquippableComponent equippableComponent = stack.get(DataComponentTypes.EQUIPPABLE); - float glintAlpha = plugin.getGlintAlpha(armorSlot, stack); - boolean glint = glintAlpha > 0; - int color = plugin.getDyeColor(armorSlot, stack); - - Set> models = glint ? new HashSet<>() : null; - - ArmourTextureLookup textureLookup = plugin.getTextureLookup(); - - float alpha = plugin.getArmourAlpha(armorSlot, layer); - - if (alpha > 0) { - for (ArmorMaterial.Layer armorLayer : textureLookup.getArmorLayers(stack, color)) { - ArmourTexture layerTexture = textureLookup.getTexture(stack, layer, armorLayer); - - if (layerTexture == ArmourTexture.UNKNOWN) { - continue; - } - - var m = pony.getArmourModel(stack, layer, layerTexture.variant()).orElse(null); - if (m != null && m.poseModel(entity, limbAngle, limbDistance, age, headYaw, headPitch, armorSlot, layer, pony.body())) { - VertexConsumer armorConsumer = plugin.getArmourConsumer(armorSlot, provider, layerTexture.texture(), layer); - if (armorConsumer != null) { - int armorTint = Colors.WHITE; - if (armorLayer.isDyeable() && color != Colors.WHITE) { - armorTint = color; - } - m.render(matrices, armorConsumer, light, OverlayTexture.DEFAULT_UV, (armorTint & 0xFFFFFF) | ((int)(alpha * 255) << 24)); - } - if (glint) { - models.add(m); - } - } - } - } - - ArmorTrim trim = stack.get(DataComponentTypes.TRIM); - - if (trim != null && stack.getItem() instanceof ArmorItem armor) { - float trimAlpha = plugin.getTrimAlpha(armorSlot, armor.getMaterial(), trim, layer); - if (trimAlpha > 0) { - var m = pony.getArmourModel(stack, layer, ArmourVariant.TRIM).orElse(null); - if (m != null && m.poseModel(entity, limbAngle, limbDistance, age, headYaw, headPitch, armorSlot, layer, pony.body())) { - VertexConsumer trimConsumer = plugin.getTrimConsumer(armorSlot, provider, armor.getMaterial(), trim, layer); - if (trimConsumer != null) { - m.render(matrices, trimConsumer, light, OverlayTexture.DEFAULT_UV, 0xFFFFFFFF); - } - } - } - } - - if (glint) { - VertexConsumer glintConsumer = plugin.getGlintConsumer(armorSlot, provider, layer); - if (glintConsumer != null) { - for (var m : models) { - m.render(matrices, glintConsumer, light, OverlayTexture.DEFAULT_UV, Color.argbToHex(glintAlpha, 1, 1, 1)); - } - } + if (equippableComponent != null && hasModel(equippableComponent, armorSlot)) { + EquipmentModel.LayerType layerType = layer == ArmourLayer.INNER + ? EquipmentModel.LayerType.HUMANOID_LEGGINGS + : EquipmentModel.LayerType.HUMANOID; + Identifier modelId = equippableComponent.model().orElseThrow(); + equipmentRenderer.render(armorSlot, layerType, modelId, models, stack, matrices, vertices, light); } } - plugin.onArmourRendered(entity, matrices, provider, armorSlot, layer, ArmourRendererPlugin.ArmourType.ARMOUR); + plugin.onArmourRendered(entity, matrices, vertices, armorSlot, layer, ArmourRendererPlugin.ArmourType.ARMOUR); + } + + private static boolean hasModel(EquippableComponent component, EquipmentSlot slot) { + return component.model().isPresent() && component.slot() == slot; } } diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/ElytraFeature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/ElytraFeature.java index 24fce9d0..7c6041b2 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/ElytraFeature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/feature/ElytraFeature.java @@ -2,7 +2,6 @@ package com.minelittlepony.client.render.entity.feature; import com.minelittlepony.api.model.BodyPart; import com.minelittlepony.api.model.PonyModel; -import com.minelittlepony.api.pony.PonyPosture; import com.minelittlepony.client.model.ModelType; import com.minelittlepony.client.model.PonyElytra; import com.minelittlepony.client.model.armour.ArmourLayer; @@ -10,19 +9,18 @@ import com.minelittlepony.client.model.armour.ArmourRendererPlugin; import com.minelittlepony.client.render.PonyRenderContext; import com.minelittlepony.client.render.entity.state.PonyRenderState; -import net.minecraft.client.network.AbstractClientPlayerEntity; -import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.entity.equipment.EquipmentRenderer; 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.util.SkinTextures; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.EquippableComponent; import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.player.PlayerModelPart; import net.minecraft.entity.EquipmentSlot; import net.minecraft.item.ItemStack; -import net.minecraft.util.Colors; +import net.minecraft.item.equipment.EquipmentModel; import net.minecraft.util.Identifier; public class ElytraFeature< @@ -32,10 +30,13 @@ public class ElytraFeature< > extends AbstractPonyFeature { private static final Identifier TEXTURE = Identifier.ofVanilla("textures/entity/elytra.png"); - private final PonyElytra model = ModelType.ELYTRA.createModel(); + private final PonyElytra model = ModelType.ELYTRA.createModel(); - public ElytraFeature(PonyRenderContext context) { + private final EquipmentRenderer equipmentRenderer; + + public ElytraFeature(PonyRenderContext context, EquipmentRenderer equipmentRenderer) { super(context); + this.equipmentRenderer = equipmentRenderer; } @Override @@ -43,23 +44,22 @@ public class ElytraFeature< ArmourRendererPlugin plugin = ArmourRendererPlugin.INSTANCE.get(); for (ItemStack stack : plugin.getArmorStacks(entity, EquipmentSlot.CHEST, ArmourLayer.OUTER, ArmourRendererPlugin.ArmourType.ELYTRA)) { - float alpha = plugin.getElytraAlpha(stack, model, entity); - if (alpha <= 0) { - return; + EquippableComponent equippable = stack.get(DataComponentTypes.EQUIPPABLE); + + if (equippable != null && !equippable.model().isEmpty()) { + Identifier equipmentModel = equippable.model().get(); + + float alpha = plugin.getElytraAlpha(stack, model, entity); + if (alpha <= 0) { + return; + } + + matrices.push(); + model.setAngles(entity); + preRenderCallback(entity, matrices); + equipmentRenderer.render(EquipmentModel.LayerType.WINGS, equipmentModel, model, stack, matrices, provider, light, getElytraTexture(entity)); + matrices.pop(); } - - VertexConsumer vertexConsumer = plugin.getElytraConsumer(stack, model, entity, provider, getElytraTexture(entity)); - if (vertexConsumer == null) { - return; - } - - matrices.push(); - preRenderCallback(matrices); - - model.setAngles(entity); - model.render(matrices, vertexConsumer, light, OverlayTexture.DEFAULT_UV, (Colors.WHITE & 0xFFFFFF) | (int)(alpha * 255) << 24); - - matrices.pop(); } plugin.onArmourRendered(entity, matrices, provider, EquipmentSlot.BODY, ArmourLayer.OUTER, ArmourRendererPlugin.ArmourType.ELYTRA); @@ -71,15 +71,15 @@ public class ElytraFeature< body.transform(state, BodyPart.BODY, stack); } - protected Identifier getElytraTexture(T entity) { - if (entity instanceof AbstractClientPlayerEntity player) { - SkinTextures textures = player.getSkinTextures(); + protected Identifier getElytraTexture(S state) { + if (state instanceof PlayerEntityRenderState playerState) { + SkinTextures textures = playerState.skinTextures; if (textures.elytraTexture() != null) { return textures.elytraTexture(); } - if (textures.capeTexture() != null && player.isPartVisible(PlayerModelPart.CAPE)) { + if (textures.capeTexture() != null && state.capeVisible) { return textures.capeTexture(); } } diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/GearFeature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/GearFeature.java index 7a4812e5..0d0e1669 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/GearFeature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/feature/GearFeature.java @@ -5,7 +5,6 @@ import it.unimi.dsi.fastutil.objects.Object2FloatMap; import net.minecraft.block.SkullBlock; import net.minecraft.client.render.*; import net.minecraft.client.render.entity.model.EntityModel; -import net.minecraft.client.render.entity.state.BipedEntityRenderState; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.LivingEntity; @@ -77,11 +76,11 @@ public class GearFeature< final M model = getModelWrapper().body(); final Object2FloatMap renderStackingOffsets = new Object2FloatLinkedOpenHashMap<>(); - for (var entry : randomisedGearCache.getUnchecked(entity.getUuid().getLeastSignificantBits())) { + for (var entry : randomisedGearCache.getUnchecked(entity.attributes.getEntityId().getLeastSignificantBits())) { if (getContext().shouldRender(model, entity, entry.wearable(), entry.gear())) { stack.push(); Gear gear = entry.gear(); - gear.transform(model, stack); + gear.transform(entity, model, stack); BodyPart part = gear.getGearLocation(); if (hasSkull && part== BodyPart.HEAD && renderStackingOffsets.getFloat(part) == 0) { renderStackingOffsets.put(part, 0.25F); @@ -101,9 +100,9 @@ public class GearFeature< } } - private void renderGear(M model, T entity, Gear gear, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, float limbDistance, float limbAngle, float tickDelta) { - gear.pose(model, entity, model.getAttributes().isGoingFast, entity.getUuid(), limbDistance, limbAngle, model.getWobbleAmount(), tickDelta); - gear.render(stack, renderContext.getBuffer(gear.getLayer(entity, getContext())), lightUv, OverlayTexture.DEFAULT_UV, Colors.WHITE, entity.getUuid()); + private void renderGear(M model, S entity, Gear gear, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, float limbDistance, float limbAngle, float tickDelta) { + gear.pose(model, entity, entity.attributes.isGoingFast, entity.attributes.getEntityId(), limbDistance, limbAngle, entity.getWobbleAmount(), tickDelta); + gear.render(stack, renderContext.getBuffer(gear.getLayer(entity, getContext())), lightUv, OverlayTexture.DEFAULT_UV, Colors.WHITE, entity.attributes.getEntityId()); } static record Entry(Gear gear, Wearable wearable) { } diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/StrayClothingFeature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/StrayClothingFeature.java deleted file mode 100644 index 4f4bb9cd..00000000 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/StrayClothingFeature.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.minelittlepony.client.render.entity.feature; - -import net.minecraft.client.render.entity.LivingEntityRenderer; -import net.minecraft.entity.mob.AbstractSkeletonEntity; -import net.minecraft.util.Identifier; - -import com.minelittlepony.client.MineLittlePony; -import com.minelittlepony.client.model.ModelType; -import com.minelittlepony.client.model.entity.SkeleponyModel; - -public class StrayClothingFeature extends AbstractClothingFeature> { - public static final Identifier STRAY_SKELETON_OVERLAY = MineLittlePony.id("textures/entity/skeleton/stray_pony_overlay.png"); - - @SuppressWarnings("unchecked") - private final SkeleponyModel overlayModel = (SkeleponyModel)ModelType.SKELETON_CLOTHES.createModel(); - - public StrayClothingFeature(LivingEntityRenderer> render) { - super(render); - } - - @Override - protected SkeleponyModel getOverlayModel() { - return overlayModel; - } - - @Override - protected Identifier getOverlayTexture() { - return STRAY_SKELETON_OVERLAY; - } -} diff --git a/src/main/java/com/minelittlepony/client/render/entity/npc/AbstractNpcRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/npc/AbstractNpcRenderer.java index a2a1b121..ac6d3ad2 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/npc/AbstractNpcRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/npc/AbstractNpcRenderer.java @@ -4,53 +4,45 @@ import net.minecraft.client.render.entity.EntityRendererFactory; import net.minecraft.entity.mob.MobEntity; import net.minecraft.util.Identifier; import net.minecraft.util.Util; -import net.minecraft.village.VillagerDataContainer; -import net.minecraft.village.VillagerProfession; +import net.minecraft.village.*; -import com.minelittlepony.api.model.Models; +import com.minelittlepony.api.model.*; import com.minelittlepony.api.model.gear.Gear; import com.minelittlepony.api.pony.meta.Race; import com.minelittlepony.api.pony.meta.Wearable; import com.minelittlepony.client.model.*; import com.minelittlepony.client.render.entity.PonyRenderer; import com.minelittlepony.client.render.entity.npc.textures.*; -import com.minelittlepony.client.render.entity.state.PonyRenderState; import java.util.function.Function; abstract class AbstractNpcRenderer< T extends MobEntity & VillagerDataContainer, - S extends PonyRenderState + S extends SillyPonyTextureSupplier.State > extends PonyRenderer> { private final NpcClothingFeature, AbstractNpcRenderer> clothing; - private final Function>> models = Util.memoize(race -> { + private final Function>> models = Util.memoize(race -> { if (race.isHuman()) { race = Race.EARTH; } return ModelType.getPlayerModel(race).create(false, this::initializeModel); }); - public AbstractNpcRenderer(EntityRendererFactory.Context context, String type, TextureSupplier textureSupplier, TextureSupplier formatter) { + public AbstractNpcRenderer(EntityRendererFactory.Context context, String type, TextureSupplier textureSupplier, TextureSupplier formatter) { super(context, ModelType.getPlayerModel(Race.EARTH).getKey(false), SillyPonyTextureSupplier.create(textureSupplier, formatter)); clothing = new NpcClothingFeature<>(this, type); - this.manager.setModelsLookup(entity -> models.apply(getEntityPony(entity).race())); + this.manager.setModelsLookup(entity -> models.apply(entity.getRace())); addFeature(clothing); } @Override public boolean shouldRender(ClientPonyModel model, S entity, Wearable wearable, Gear gear) { if (wearable == Wearable.SADDLE_BAGS_BOTH) { - VillagerProfession profession = entity.getVillagerData().getProfession(); - return !SillyPonyTextureSupplier.isBestPony(entity) && profession != VillagerProfession.NONE && ( - profession == VillagerProfession.CARTOGRAPHER - || profession == VillagerProfession.FARMER - || profession == VillagerProfession.FISHERMAN - || profession == VillagerProfession.LIBRARIAN - || profession == VillagerProfession.SHEPHERD); + return entity.hasSaddlebags; } if (wearable == Wearable.MUFFIN) { - return SillyPonyTextureSupplier.isCrownPony(entity); + return entity.hasMuffinHat; } return super.shouldRender(model, entity, wearable, gear); diff --git a/src/main/java/com/minelittlepony/client/render/entity/npc/IllagerPonyRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/npc/IllagerPonyRenderer.java index 7407d524..e5eba545 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/npc/IllagerPonyRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/npc/IllagerPonyRenderer.java @@ -1,76 +1,91 @@ package com.minelittlepony.client.render.entity.npc; +import com.minelittlepony.api.model.ModelAttributes; +import com.minelittlepony.api.model.PonyModel; +import com.minelittlepony.api.pony.Pony; import com.minelittlepony.client.MineLittlePony; import com.minelittlepony.client.model.ModelType; -import com.minelittlepony.client.model.entity.IllagerPonyModel; -import com.minelittlepony.client.render.entity.feature.IllagerHeldItemFeature; +import com.minelittlepony.client.model.entity.race.AlicornModel; import com.minelittlepony.client.render.entity.npc.textures.TextureSupplier; +import com.minelittlepony.client.render.entity.state.PonyRenderState; +import com.minelittlepony.mson.api.ModelKey; +import com.minelittlepony.client.render.PonyRenderContext; import com.minelittlepony.client.render.entity.PonyRenderer; import com.minelittlepony.client.render.entity.feature.HeldItemFeature; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.EntityRendererFactory; +import net.minecraft.client.render.item.ItemRenderer; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.mob.EvokerEntity; -import net.minecraft.entity.mob.IllagerEntity; -import net.minecraft.entity.mob.IllusionerEntity; -import net.minecraft.entity.mob.VindicatorEntity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.mob.*; import net.minecraft.util.Identifier; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.Vec3d; -public class IllagerPonyRenderer extends PonyRenderer> { +public class IllagerPonyRenderer< + T extends IllagerEntity, + S extends IllagerPonyRenderer.State, + M extends AlicornModel + > extends PonyRenderer { + public static final Identifier PILLAGER = MineLittlePony.id("textures/entity/illager/pillager_pony.png"); public static final Identifier ILLUSIONIST = MineLittlePony.id("textures/entity/illager/illusionist_pony.png"); public static final Identifier EVOKER = MineLittlePony.id("textures/entity/illager/evoker_pony.png"); public static final Identifier VINDICATOR = MineLittlePony.id("textures/entity/illager/vindicator_pony.png"); - public IllagerPonyRenderer(EntityRendererFactory.Context context, Identifier texture) { - super(context, ModelType.ILLAGER, TextureSupplier.of(texture), BASE_MODEL_SCALE); + public IllagerPonyRenderer(EntityRendererFactory.Context context, ModelKey key, Identifier texture) { + super(context, key, TextureSupplier.of(texture), BASE_MODEL_SCALE); + } + + @SuppressWarnings("unchecked") + @Override + public S createRenderState() { + return (S)new State(); } @Override - protected HeldItemFeature> createHeldItemFeature(EntityRendererFactory.Context context) { - return new IllagerHeldItemFeature<>(this, context.getHeldItemRenderer()); + protected HeldItemFeature createHeldItemFeature(EntityRendererFactory.Context context) { + return new IllagerHeldItemFeature<>(this, context.getItemRenderer()); } - public static IllagerPonyRenderer vindicator(EntityRendererFactory.Context context) { - return new IllagerPonyRenderer<>(context, VINDICATOR); + public static IllagerPonyRenderer pillager(EntityRendererFactory.Context context) { + return new IllagerPonyRenderer<>(context, ModelType.PILLAGER, PILLAGER); } - public static IllagerPonyRenderer evoker(EntityRendererFactory.Context context) { - return new IllagerPonyRenderer<>(context, EVOKER); + public static IllagerPonyRenderer vindicator(EntityRendererFactory.Context context) { + return new IllagerPonyRenderer<>(context, (ModelKey)ModelType.ILLAGER, VINDICATOR); } - public static class Illusionist extends IllagerPonyRenderer { + public static IllagerPonyRenderer evoker(EntityRendererFactory.Context context) { + return new IllagerPonyRenderer<>(context, (ModelKey)ModelType.ILLAGER, EVOKER); + } - public Illusionist(EntityRendererFactory.Context context) { - super(context, ILLUSIONIST); + public static class State extends PonyRenderState { + public IllagerEntity.State state; + + public void updateState(LivingEntity entity, PonyModel model, Pony pony, ModelAttributes.Mode mode) { + super.updateState(entity, model, pony, mode); + state = ((IllagerEntity)entity).getState(); + } + } + + public static class IllagerHeldItemFeature< + T extends IllagerEntity, + S extends IllagerPonyRenderer.State, + M extends AlicornModel + > extends HeldItemFeature { + + public IllagerHeldItemFeature(PonyRenderContext livingPony, ItemRenderer renderer) { + super(livingPony, renderer); } @Override - public void render(IllusionerEntity entity, float entityYaw, float tickDelta, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv) { - if (entity.isInvisible()) { - Vec3d[] clones = entity.getMirrorCopyOffsets(tickDelta); - float rotation = getAnimationProgress(entity, tickDelta); - - for (int i = 0; i < clones.length; ++i) { - stack.push(); - stack.translate( - clones[i].x + MathHelper.cos(i + rotation * 0.5F) * 0.025D, - clones[i].y + MathHelper.cos(i + rotation * 0.75F) * 0.0125D, - clones[i].z + MathHelper.cos(i + rotation * 0.7F) * 0.025D - ); - super.render(entity, entityYaw, tickDelta, stack, renderContext, lightUv); - stack.pop(); - } - } else { - super.render(entity, entityYaw, tickDelta, stack, renderContext, lightUv); + public void render(MatrixStack matrices, VertexConsumerProvider vertices, int light, S state, float limbAngle, float limbDistance) { + if (shouldRender(state)) { + super.render(matrices, vertices, light, state, limbAngle, limbDistance); } } - @Override - protected boolean isVisible(IllusionerEntity entity) { - return true; + protected boolean shouldRender(S state) { + return state.state != IllagerEntity.State.CROSSED; } } } diff --git a/src/main/java/com/minelittlepony/client/render/entity/npc/IllusionistPonyRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/npc/IllusionistPonyRenderer.java new file mode 100644 index 00000000..72aa3e4e --- /dev/null +++ b/src/main/java/com/minelittlepony/client/render/entity/npc/IllusionistPonyRenderer.java @@ -0,0 +1,62 @@ +package com.minelittlepony.client.render.entity.npc; + +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.entity.EntityRendererFactory; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.mob.IllusionerEntity; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.Vec3d; + +import com.minelittlepony.client.model.ModelType; +import com.minelittlepony.client.model.entity.IllagerPonyModel; + +import java.util.Arrays; + +public class IllusionistPonyRenderer extends IllagerPonyRenderer> { + public IllusionistPonyRenderer(EntityRendererFactory.Context context) { + super(context, ModelType.ILLAGER, ILLUSIONIST); + } + + @Override + public State createRenderState() { + return new State(); + } + + @Override + public void render(IllusionistPonyRenderer.State entity, MatrixStack stack, VertexConsumerProvider renderContext, int light) { + if (!entity.invisible) { + Vec3d[] clones = entity.mirrorCopyOffsets; + + for (int i = 0; i < clones.length; ++i) { + stack.push(); + stack.translate( + clones[i].x + MathHelper.cos(i + entity.age * 0.5F) * 0.025D, + clones[i].y + MathHelper.cos(i + entity.age * 0.75F) * 0.0125D, + clones[i].z + MathHelper.cos(i + entity.age * 0.7F) * 0.025D + ); + super.render(entity, stack, renderContext, light); + stack.pop(); + } + } else { + super.render(entity, stack, renderContext, light); + } + } + + @Override + protected boolean isVisible(IllusionistPonyRenderer.State entity) { + return true; + } + + @Override + public void updateRenderState(IllusionerEntity entity, IllusionistPonyRenderer.State state, float tickDelta) { + super.updateRenderState(entity, state, tickDelta); + Vec3d[] vec3ds = entity.getMirrorCopyOffsets(tickDelta); + state.mirrorCopyOffsets = (Vec3d[])Arrays.copyOf(vec3ds, vec3ds.length); + state.spellcasting = entity.isSpellcasting(); + } + + public static class State extends IllagerPonyRenderer.State { + public Vec3d[] mirrorCopyOffsets; + public boolean spellcasting; + } +} \ No newline at end of file diff --git a/src/main/java/com/minelittlepony/client/render/entity/npc/NpcClothingFeature.java b/src/main/java/com/minelittlepony/client/render/entity/npc/NpcClothingFeature.java index b5f0b2ab..cb1d2acd 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/npc/NpcClothingFeature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/npc/NpcClothingFeature.java @@ -4,7 +4,6 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.feature.FeatureRendererContext; -import net.minecraft.client.render.entity.model.EntityModel; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.LivingEntity; import net.minecraft.registry.Registries; @@ -15,11 +14,11 @@ import net.minecraft.village.VillagerDataContainer; import net.minecraft.village.VillagerProfession; import net.minecraft.village.VillagerType; -import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.client.MineLittlePony; +import com.minelittlepony.client.model.ClientPonyModel; import com.minelittlepony.client.render.PonyRenderContext; import com.minelittlepony.client.render.entity.feature.AbstractPonyFeature; -import com.minelittlepony.client.render.entity.state.PonyRenderState; +import com.minelittlepony.client.render.entity.npc.textures.SillyPonyTextureSupplier; import com.minelittlepony.client.util.render.TextureFlattener; import com.minelittlepony.util.ResourceUtil; @@ -27,8 +26,8 @@ import java.util.*; class NpcClothingFeature< T extends LivingEntity & VillagerDataContainer, - S extends PonyRenderState, - M extends EntityModel & PonyModel, + S extends SillyPonyTextureSupplier.State, + M extends ClientPonyModel, C extends FeatureRendererContext & PonyRenderContext> extends AbstractPonyFeature { private static final Int2ObjectMap LEVEL_TO_ID = Util.make(new Int2ObjectOpenHashMap<>(), a -> { @@ -53,7 +52,7 @@ class NpcClothingFeature< return; } - VillagerData data = entity.getVillagerData(); + VillagerData data = entity.villagerData; M entityModel = getContextModel(); if (entity.baby || data.getProfession() == VillagerProfession.NONE) { @@ -102,8 +101,8 @@ class NpcClothingFeature< return skins; } - public Identifier createTexture(VillagerDataContainer entity, String category) { - return createTexture(category, Registries.VILLAGER_PROFESSION.getId(entity.getVillagerData().getProfession())); + public Identifier createTexture(S entity, String category) { + return createTexture(category, Registries.VILLAGER_PROFESSION.getId(entity.villagerData.getProfession())); } private Identifier createTexture(String category, Identifier identifier) { diff --git a/src/main/java/com/minelittlepony/client/render/entity/npc/PillagerRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/npc/PillagerRenderer.java deleted file mode 100644 index 10dd0756..00000000 --- a/src/main/java/com/minelittlepony/client/render/entity/npc/PillagerRenderer.java +++ /dev/null @@ -1,72 +0,0 @@ -package com.minelittlepony.client.render.entity.npc; - -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.entity.EntityRendererFactory; -import net.minecraft.client.render.item.ItemRenderer; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.mob.IllagerEntity; -import net.minecraft.entity.mob.PillagerEntity; -import net.minecraft.util.Identifier; - -import com.minelittlepony.api.model.ModelAttributes; -import com.minelittlepony.api.model.PonyModel; -import com.minelittlepony.api.pony.Pony; -import com.minelittlepony.client.MineLittlePony; -import com.minelittlepony.client.model.ModelType; -import com.minelittlepony.client.model.entity.PillagerPonyModel; -import com.minelittlepony.client.model.entity.race.AlicornModel; -import com.minelittlepony.client.render.entity.npc.textures.TextureSupplier; -import com.minelittlepony.client.render.entity.state.PonyRenderState; -import com.minelittlepony.client.render.PonyRenderContext; -import com.minelittlepony.client.render.entity.PonyRenderer; -import com.minelittlepony.client.render.entity.feature.HeldItemFeature; - -public class PillagerRenderer extends PonyRenderer { - private static final Identifier TEXTURE = MineLittlePony.id("textures/entity/illager/pillager_pony.png"); - - public PillagerRenderer(EntityRendererFactory.Context context) { - super(context, ModelType.PILLAGER, TextureSupplier.of(TEXTURE)); - } - - @Override - protected HeldItemFeature createHeldItemFeature(EntityRendererFactory.Context context) { - return new IllagerHeldItemFeature<>(this, context.getItemRenderer()); - } - - @Override - public State createRenderState() { - return new State(); - } - - public class State extends PonyRenderState { - public IllagerEntity.State state; - - public void updateState(LivingEntity entity, PonyModel model, Pony pony, ModelAttributes.Mode mode) { - super.updateState(entity, model, pony, mode); - state = ((IllagerEntity)entity).getState(); - } - } - - public class IllagerHeldItemFeature< - T extends IllagerEntity, - S extends PillagerRenderer.State, - M extends AlicornModel - > extends HeldItemFeature { - - public IllagerHeldItemFeature(PonyRenderContext livingPony, ItemRenderer renderer) { - super(livingPony, renderer); - } - - @Override - public void render(MatrixStack matrices, VertexConsumerProvider vertices, int light, S state, float limbAngle, float limbDistance) { - if (shouldRender(state)) { - super.render(matrices, vertices, light, state, limbAngle, limbDistance); - } - } - - protected boolean shouldRender(S state) { - return state.state != IllagerEntity.State.CROSSED; - } - } -} diff --git a/src/main/java/com/minelittlepony/client/render/entity/npc/VillagerPonyRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/npc/VillagerPonyRenderer.java index bf6fa04f..d2f2702c 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/npc/VillagerPonyRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/npc/VillagerPonyRenderer.java @@ -1,30 +1,39 @@ package com.minelittlepony.client.render.entity.npc; import net.minecraft.client.render.entity.EntityRendererFactory; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.passive.VillagerEntity; import net.minecraft.util.math.MathHelper; +import com.minelittlepony.api.model.ModelAttributes; +import com.minelittlepony.api.model.PonyModel; +import com.minelittlepony.api.pony.Pony; import com.minelittlepony.client.VariatedTextureSupplier; -import com.minelittlepony.client.model.ClientPonyModel; import com.minelittlepony.client.render.entity.npc.textures.*; -public class VillagerPonyRenderer extends AbstractNpcRenderer { +public class VillagerPonyRenderer extends AbstractNpcRenderer { private static final TextureSupplier FORMATTER = TextureSupplier.formatted("minelittlepony", "textures/entity/villager/%s.png"); + private static final TextureSupplier TEXTURES = TextureSupplier.ofPool( + VariatedTextureSupplier.BACKGROUND_PONIES_POOL, + PlayerTextureSupplier.create(ProfessionTextureSupplier.create(FORMATTER)) + ); public VillagerPonyRenderer(EntityRendererFactory.Context context) { - super(context, "villager", - TextureSupplier.ofPool(VariatedTextureSupplier.BACKGROUND_PONIES_POOL, - PlayerTextureSupplier.create(ProfessionTextureSupplier.create(FORMATTER))), FORMATTER); + super(context, "villager", TEXTURES, FORMATTER); } @Override - protected void initializeModel(ClientPonyModel model) { - model.onSetModelAngles((m, move, swing, ticks, entity) -> { - m.getAttributes().visualHeight += SillyPonyTextureSupplier.isCrownPony(entity) ? 0.3F : -0.1F; + public State createRenderState() { + return new State(); + } - if (entity.getHeadRollingTimeLeft() > 0) { - m.head.yaw = 0.3F * MathHelper.sin(0.45F * ticks); + public static class State extends SillyPonyTextureSupplier.State { + public int headRollingTime; + public void updateState(LivingEntity entity, PonyModel model, Pony pony, ModelAttributes.Mode mode) { + super.updateState(entity, model, pony, mode); + if (((VillagerEntity)entity).getHeadRollingTimeLeft() > 0) { + this.yawDegrees = 0.3F * MathHelper.sin(0.45F * age); } - }); + } } } diff --git a/src/main/java/com/minelittlepony/client/render/entity/npc/ZomponyVillagerRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/npc/ZomponyVillagerRenderer.java index 4edfb7f4..367e628a 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/npc/ZomponyVillagerRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/npc/ZomponyVillagerRenderer.java @@ -2,42 +2,50 @@ package com.minelittlepony.client.render.entity.npc; import net.minecraft.client.render.entity.EntityRendererFactory; import net.minecraft.client.render.entity.model.BipedEntityModel.ArmPose; -import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.mob.ZombieVillagerEntity; -import com.minelittlepony.api.model.MobPosingHelper; +import com.minelittlepony.api.model.*; +import com.minelittlepony.api.pony.Pony; import com.minelittlepony.client.VariatedTextureSupplier; import com.minelittlepony.client.model.ClientPonyModel; import com.minelittlepony.client.render.entity.npc.textures.*; -public class ZomponyVillagerRenderer extends AbstractNpcRenderer { +public class ZomponyVillagerRenderer extends AbstractNpcRenderer { private static final TextureSupplier FORMATTER = TextureSupplier.formatted("minelittlepony", "textures/entity/zombie_villager/zombie_%s.png"); + private static final TextureSupplier TEXTURES = TextureSupplier.ofPool( + VariatedTextureSupplier.BACKGROUND_ZOMPONIES_POOL, + TextureSupplier.ofPool( + VariatedTextureSupplier.BACKGROUND_PONIES_POOL, + PlayerTextureSupplier.create(ProfessionTextureSupplier.create(FORMATTER)) + ) + ); public ZomponyVillagerRenderer(EntityRendererFactory.Context context) { - super(context, "zombie_villager", - TextureSupplier.ofPool(VariatedTextureSupplier.BACKGROUND_ZOMPONIES_POOL, - TextureSupplier.ofPool(VariatedTextureSupplier.BACKGROUND_PONIES_POOL, - PlayerTextureSupplier.create(ProfessionTextureSupplier.create(FORMATTER)))), - FORMATTER); + super(context, "zombie_villager", TEXTURES, FORMATTER); } @Override - protected void initializeModel(ClientPonyModel model) { - model.onSetModelAngles((m, move, swing, ticks, entity) -> { - m.getAttributes().visualHeight += SillyPonyTextureSupplier.isCrownPony(entity) ? 0.3F : -0.1F; + public State createRenderState() { + return new State(); + } - if (m.rightArmPose == ArmPose.EMPTY) { - MobPosingHelper.rotateUndeadArms(m, move, ticks); + @Override + protected void initializeModel(ClientPonyModel model) { + model.onSetModelAngles((m, state) -> { + if (m.getArmPoseForSide(state, state.mainArm) == ArmPose.EMPTY) { + MobPosingHelper.rotateUndeadArms(state, m, state.limbFrequency, state.age); } }); } - @Override - protected void setupTransforms(ZombieVillagerEntity entity, MatrixStack matrices, float animationProgress, float bodyYaw, float tickDelta, float scale) { - if (entity.isConverting()) { - bodyYaw += (float) (Math.cos(entity.age * 3.25D) * (Math.PI / 4)); + public static class State extends SillyPonyTextureSupplier.State { + @Override + public void updateState(LivingEntity entity, PonyModel model, Pony pony, ModelAttributes.Mode mode) { + super.updateState(entity, model, pony, mode); + if (((ZombieVillagerEntity)entity).isConverting()) { + bodyYaw += (float) (Math.cos(entity.age * 3.25D) * (Math.PI / 4)); + } } - - super.setupTransforms(entity, matrices, animationProgress, bodyYaw, tickDelta, scale); } } diff --git a/src/main/java/com/minelittlepony/client/render/entity/npc/textures/PlayerTextureSupplier.java b/src/main/java/com/minelittlepony/client/render/entity/npc/textures/PlayerTextureSupplier.java index 2c07fc23..e05e27b1 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/npc/textures/PlayerTextureSupplier.java +++ b/src/main/java/com/minelittlepony/client/render/entity/npc/textures/PlayerTextureSupplier.java @@ -1,18 +1,18 @@ package com.minelittlepony.client.render.entity.npc.textures; import net.minecraft.block.entity.SkullBlockEntity; -import net.minecraft.entity.LivingEntity; import net.minecraft.util.Identifier; import net.minecraft.util.Util; import com.minelittlepony.api.pony.Pony; import com.minelittlepony.api.pony.SkinsProxy; +import com.minelittlepony.client.render.entity.state.PonyRenderState; import java.util.concurrent.CompletableFuture; import java.util.function.Function; public class PlayerTextureSupplier { - public static TextureSupplier create(TextureSupplier fallback) { + public static TextureSupplier create(TextureSupplier fallback) { Function> customNameCache = Util.memoize(name -> { return SkullBlockEntity.fetchProfileByName(name).thenApply(profile -> { return profile @@ -22,7 +22,7 @@ public class PlayerTextureSupplier { }); }); return entity -> { - Identifier override = entity.hasCustomName() ? customNameCache.apply(entity.getCustomName().getString()).getNow(null) : null; + Identifier override = entity.customName != null ? customNameCache.apply(entity.customName.getString()).getNow(null) : null; if (override != null) { return override; } diff --git a/src/main/java/com/minelittlepony/client/render/entity/npc/textures/SillyPonyTextureSupplier.java b/src/main/java/com/minelittlepony/client/render/entity/npc/textures/SillyPonyTextureSupplier.java index 276a0379..2bb79a37 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/npc/textures/SillyPonyTextureSupplier.java +++ b/src/main/java/com/minelittlepony/client/render/entity/npc/textures/SillyPonyTextureSupplier.java @@ -2,15 +2,18 @@ package com.minelittlepony.client.render.entity.npc.textures; import net.minecraft.entity.LivingEntity; import net.minecraft.util.Identifier; -import net.minecraft.village.VillagerDataContainer; +import net.minecraft.village.*; + +import com.minelittlepony.api.model.ModelAttributes; +import com.minelittlepony.api.model.PonyModel; +import com.minelittlepony.api.pony.Pony; +import com.minelittlepony.client.render.entity.state.PonyRenderState; public class SillyPonyTextureSupplier { - public static TextureSupplier create(TextureSupplier fallback, TextureSupplier formatter) { + public static TextureSupplier create(TextureSupplier fallback, TextureSupplier formatter) { Identifier egg = formatter.apply("silly_pony"); Identifier egg2 = formatter.apply("tiny_silly_pony"); - return entity -> { - return isBestPony(entity) ? ("Dinky".equals(entity.getCustomName().getString()) ? egg2 : egg) : fallback.apply(entity); - }; + return entity -> entity.isDerpy ? (entity.isDinky ? egg2 : egg) : fallback.apply(entity); } public static boolean isBestPony(LivingEntity entity) { @@ -24,4 +27,40 @@ public class SillyPonyTextureSupplier { public static boolean isCrownPony(LivingEntity entity) { return isBestPony(entity) && entity.getUuid().getLeastSignificantBits() % 20 == 0; } + + public static class State extends PonyRenderState implements VillagerDataContainer { + public VillagerData villagerData; + + public boolean isDerpy; + public boolean isDinky; + public boolean hasMuffinHat; + public boolean hasSaddlebags; + + public void updateState(LivingEntity entity, PonyModel model, Pony pony, ModelAttributes.Mode mode) { + super.updateState(entity, model, pony, mode); + attributes.visualHeight += hasMuffinHat ? 0.3F : -0.1F; + isDerpy = SillyPonyTextureSupplier.isBestPony(entity); + isDinky = isDerpy && customName != null && "Dinky".equals(customName.getString()); + hasMuffinHat = SillyPonyTextureSupplier.isCrownPony(entity); + + villagerData = ((VillagerDataContainer)entity).getVillagerData(); + VillagerProfession profession = villagerData.getProfession(); + + hasSaddlebags = !isDerpy && profession != VillagerProfession.NONE && ( + profession == VillagerProfession.CARTOGRAPHER + || profession == VillagerProfession.FARMER + || profession == VillagerProfession.FISHERMAN + || profession == VillagerProfession.LIBRARIAN + || profession == VillagerProfession.SHEPHERD); + } + + @Override + public VillagerData getVillagerData() { + return villagerData; + } + + @Override + public void setVillagerData(VillagerData villagerData) { + } + } } diff --git a/src/main/java/com/minelittlepony/client/render/entity/npc/textures/TextureSupplier.java b/src/main/java/com/minelittlepony/client/render/entity/npc/textures/TextureSupplier.java index 93ffa316..f682e4b7 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/npc/textures/TextureSupplier.java +++ b/src/main/java/com/minelittlepony/client/render/entity/npc/textures/TextureSupplier.java @@ -1,10 +1,10 @@ package com.minelittlepony.client.render.entity.npc.textures; -import net.minecraft.entity.LivingEntity; import net.minecraft.util.Identifier; import net.minecraft.util.Util; import com.minelittlepony.client.MineLittlePony; +import com.minelittlepony.client.render.entity.state.PonyRenderState; import java.util.Map; import java.util.UUID; @@ -27,13 +27,13 @@ public interface TextureSupplier extends Function { return key -> Identifier.of(domain, String.format(path, key)); } - static TextureSupplier ofVariations(Identifier poolId, TextureSupplier fallback) { + static TextureSupplier ofVariations(Identifier poolId, TextureSupplier fallback) { return entity -> { - return MineLittlePony.getInstance().getVariatedTextures().get(poolId).getId(entity.getUuid()).orElse(fallback.apply(entity)); + return MineLittlePony.getInstance().getVariatedTextures().get(poolId).getId(entity.attributes.getEntityId()).orElse(fallback.apply(entity)); }; } - static TextureSupplier ofPool(Identifier poolId, TextureSupplier fallback) { + static TextureSupplier ofPool(Identifier poolId, TextureSupplier fallback) { final BiFunction cache = Util.memoize((name, uuid) -> { return MineLittlePony.getInstance().getVariatedTextures() .get(poolId) @@ -41,7 +41,7 @@ public interface TextureSupplier extends Function { .orElse(null); }); return entity -> { - Identifier override = entity.hasCustomName() ? cache.apply(entity.getCustomName().getString(), entity.getUuid()) : null; + Identifier override = entity.customName != null ? cache.apply(entity.customName.getString(), entity.attributes.getEntityId()) : null; if (override != null) { return override; } diff --git a/src/main/java/com/minelittlepony/client/render/entity/state/PlayerPonyRenderState.java b/src/main/java/com/minelittlepony/client/render/entity/state/PlayerPonyRenderState.java index 3841e64d..2590cf1b 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/state/PlayerPonyRenderState.java +++ b/src/main/java/com/minelittlepony/client/render/entity/state/PlayerPonyRenderState.java @@ -4,8 +4,7 @@ import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.util.Identifier; -import com.minelittlepony.api.model.ModelAttributes; -import com.minelittlepony.api.model.PonyModel; +import com.minelittlepony.api.model.*; import com.minelittlepony.api.pony.Pony; import com.minelittlepony.api.pony.SkinsProxy; import com.minelittlepony.api.pony.meta.Wearable; @@ -15,10 +14,13 @@ import java.util.Map; public class PlayerPonyRenderState extends PonyRenderState { public final Map wearabledTextures = new HashMap<>(); + public boolean isPreviewModel; + public double yOffset; @Override public void updateState(LivingEntity entity, PonyModel model, Pony pony, ModelAttributes.Mode mode) { super.updateState(entity, model, pony, mode); + isPreviewModel = entity instanceof PreviewModel; wearabledTextures.clear(); for (Wearable wearable : Wearable.REGISTRY.values()) { if (isWearing(wearable)) { diff --git a/src/main/java/com/minelittlepony/client/render/entity/state/PonyRenderState.java b/src/main/java/com/minelittlepony/client/render/entity/state/PonyRenderState.java index 095ce234..a899c026 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/state/PonyRenderState.java +++ b/src/main/java/com/minelittlepony/client/render/entity/state/PonyRenderState.java @@ -12,6 +12,7 @@ import com.minelittlepony.api.model.ModelAttributes; import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.api.pony.Pony; import com.minelittlepony.api.pony.meta.*; +import com.minelittlepony.client.transform.PonyPosture; public class PonyRenderState extends PlayerEntityRenderState implements PonyModel.AttributedHolder { public final ModelAttributes attributes = new ModelAttributes(); @@ -28,9 +29,9 @@ public class PonyRenderState extends PlayerEntityRenderState implements PonyMode public Pony pony; public void updateState(LivingEntity entity, PonyModel model, Pony pony, ModelAttributes.Mode mode) { + this.pony = pony; attributes.updateLivingState(entity, pony, mode); attributes.checkRainboom(entity, model, age); - this.pony = pony; vehicleOffset = hasVehicle ? entity.getVehicle().getEyeHeight(pose) : 0; riderOffset = getRiderYOffset(); nameplateYOffset = getNamePlateYOffset(entity); @@ -42,6 +43,7 @@ public class PonyRenderState extends PlayerEntityRenderState implements PonyMode pose = EntityPose.SITTING; } + PonyPosture.of(attributes).updateState(entity, this); PonyModelPrepareCallback.EVENT.invoker().onPonyModelPrepared(attributes, model, ModelAttributes.Mode.OTHER); } @@ -56,6 +58,10 @@ public class PonyRenderState extends PlayerEntityRenderState implements PonyMode return PonyConfig.getEffectiveRace(attributes.metadata.race()); } + public boolean hasMagicGlow() { + return getRace().hasHorn() && attributes.metadata.glowColor() != 0; + } + public final float getScaleFactor() { return getSize().scaleFactor(); } @@ -83,7 +89,6 @@ public class PonyRenderState extends PlayerEntityRenderState implements PonyMode } protected float getLegOutset() { - float outset = attributes.isLyingDown ? 3.6F : attributes.isCrouching ? 1 : 5; if (smallArms) { diff --git a/src/main/java/com/minelittlepony/client/render/entity/state/SkeletonPonyRenderState.java b/src/main/java/com/minelittlepony/client/render/entity/state/SkeletonPonyRenderState.java deleted file mode 100644 index ba4b06f9..00000000 --- a/src/main/java/com/minelittlepony/client/render/entity/state/SkeletonPonyRenderState.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.minelittlepony.client.render.entity.state; - -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.mob.HostileEntity; -import net.minecraft.entity.mob.WitherSkeletonEntity; - -import com.minelittlepony.api.model.ModelAttributes; -import com.minelittlepony.api.model.PonyModel; -import com.minelittlepony.api.pony.Pony; -import com.minelittlepony.api.pony.meta.Race; - -public class SkeletonPonyRenderState extends PonyRenderState { - public boolean isUnicorn; - public boolean isWithered; - public boolean isAttacking; - - public void updateState(LivingEntity entity, PonyModel model, Pony pony, ModelAttributes.Mode mode) { - isUnicorn = entity.getUuid().getLeastSignificantBits() % 3 != 0; - isWithered = entity instanceof WitherSkeletonEntity; - isAttacking = entity instanceof HostileEntity h && h.isAttacking(); - } - - @Override - public Race getRace() { - return isUnicorn ? super.getRace() : Race.EARTH; - } - - @Override - protected float getLegOutset() { - if (attributes.isLyingDown) return 2.6f; - if (attributes.isCrouching) return 0; - return 4; - } -} diff --git a/src/main/java/com/minelittlepony/client/transform/PonyPosture.java b/src/main/java/com/minelittlepony/client/transform/PonyPosture.java index 16cb8278..135376c4 100644 --- a/src/main/java/com/minelittlepony/client/transform/PonyPosture.java +++ b/src/main/java/com/minelittlepony/client/transform/PonyPosture.java @@ -3,28 +3,34 @@ package com.minelittlepony.client.transform; import net.minecraft.client.network.AbstractClientPlayerEntity; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.util.math.*; import org.jetbrains.annotations.NotNull; import com.minelittlepony.api.model.*; +import com.minelittlepony.client.render.entity.state.PonyRenderState; -public interface PonyPosture { - PonyPosture STANDING = (PonyModel model, LivingEntity entity, MatrixStack stack, double motionX, double motionY, double motionZ, float yaw, float tickDelta) -> { - model.getAttributes().motionPitch /= 10; - model.getAttributes().motionLerp /= 10; - model.getAttributes().motionRoll /= 10; +public abstract class PonyPosture { + public static final PonyPosture STANDING = new PonyPosture() { + @Override + public void updateState(LivingEntity entity, PonyRenderState state) { + super.updateState(entity, state); + state.attributes.motionPitch /= 10; + state.attributes.motionLerp /= 10; + state.attributes.motionRoll /= 10; + } }; - PonyPosture ELYTRA = (PonyModel model, LivingEntity entity, MatrixStack stack, double motionX, double motionY, double motionZ, float yaw, float tickDelta) -> { - stack.translate(0, entity.isInSneakingPose() ? -0.825F : -1, 0); + public static final PonyPosture ELYTRA = new PonyPosture() { + @Override + public void transform(PonyRenderState state, MatrixStack stack) { + stack.translate(0, state.isInSneakingPose ? -0.825F : -1, 0); + } }; - PonyPosture FLYING = new PostureFlight(1, 0); - PonyPosture SWIMMING = new PostureFlight(2, -0.9F); - PonyPosture FALLING = STANDING; + public static final PonyPosture FLYING = new PostureFlight(1, 0); + public static final PonyPosture SWIMMING = new PostureFlight(2, -0.9F); + public static final PonyPosture FALLING = STANDING; @NotNull - static PonyPosture of(ModelAttributes attributes) { + public static PonyPosture of(ModelAttributes attributes) { if (attributes.isGliding) { return ELYTRA; } @@ -44,52 +50,16 @@ public interface PonyPosture { return FALLING; } - default void apply(LivingEntity player, PonyModel model, MatrixStack stack, float yaw, float tickDelta, int invert) { - + public void updateState(LivingEntity entity, PonyRenderState state) { if (RenderPass.getCurrent() == RenderPass.GUI || RenderPass.getCurrent() == RenderPass.WORLD) { - // this reverts the rotations done in PlayerEntityRenderer#setupTransforms - if (player instanceof PlayerEntity) { - float leaningPitch = player.getLeaningPitch(tickDelta); - if (player.isGliding()) { - - if (RenderPass.getCurrent() == RenderPass.GUI) { - Vec3d vec3d = player.getRotationVec(tickDelta); - Vec3d vec3d2 = ((AbstractClientPlayerEntity)player).lerpVelocity(tickDelta); - double d = vec3d2.horizontalLengthSquared(); - double e = vec3d.horizontalLengthSquared(); - if (d > 0.0 && e > 0.0) { - double l = (vec3d2.x * vec3d.x + vec3d2.z * vec3d.z) / Math.sqrt(d * e); - double m = vec3d2.x * vec3d.z - vec3d2.z * vec3d.x; - stack.multiply(RotationAxis.NEGATIVE_Y.rotation((float)(Math.signum(m) * Math.acos(l)))); - } - } - - float roll = (float)player.getGlidingTicks() + tickDelta; - float targetRoll = MathHelper.clamp(roll * roll / 100F, 0, 1); - if (!player.isUsingRiptide()) { - stack.multiply(RotationAxis.NEGATIVE_X.rotationDegrees(targetRoll * (-90 - player.getPitch()))); - } - - } else if (leaningPitch > 0) { - if (player.isInSwimmingPose()) { - stack.translate(0.0f, 1.0f, -0.3f); - } - float pitch = MathHelper.lerp(leaningPitch, 0, player.isTouchingWater() ? -90 - player.getPitch() : -90); - stack.multiply(RotationAxis.NEGATIVE_X.rotationDegrees(pitch)); - } + if (entity instanceof AbstractClientPlayerEntity) { + state.isGliding = false; + state.leaningPitch = 0; } } - - if (RenderPass.getCurrent() != RenderPass.WORLD) { - return; - } - - double motionX = player.getX() - player.prevX; - double motionY = player.isOnGround() ? 0 : player.getY() - player.prevY; - double motionZ = player.getZ() - player.prevZ; - - transform(model, player, stack, motionX, invert * motionY, motionZ, yaw, tickDelta); } - void transform(PonyModel model, LivingEntity entity, MatrixStack stack, double motionX, double motionY, double motionZ, float yaw, float tickDelta); + public void transform(PonyRenderState state, MatrixStack stack) { + + } } diff --git a/src/main/java/com/minelittlepony/client/transform/PonyTransformation.java b/src/main/java/com/minelittlepony/client/transform/PonyTransformation.java index dbdc2f8e..0d098c8c 100644 --- a/src/main/java/com/minelittlepony/client/transform/PonyTransformation.java +++ b/src/main/java/com/minelittlepony/client/transform/PonyTransformation.java @@ -3,8 +3,7 @@ package com.minelittlepony.client.transform; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.math.Vec3d; -import com.minelittlepony.api.model.BodyPart; -import com.minelittlepony.api.model.PonyModel; +import com.minelittlepony.api.model.*; import com.minelittlepony.api.pony.meta.Size; import com.minelittlepony.api.pony.meta.SizePreset; @@ -14,23 +13,22 @@ import java.util.function.Function; import java.util.stream.Collectors; public enum PonyTransformation { - NORMAL(SizePreset.NORMAL, 0, 3F, 0.75F) { @Override - public void transform(PonyModel model, BodyPart part, MatrixStack stack) { - if (model.getAttributes().isSwimming) stack.translate(0, -0.3F, 0); - if (model.getAttributes().isCrouching) stack.translate(0, -0.2F, 0); - if (model.getAttributes().isLyingDown) stack.translate(0, -0.77F, 0.1F); - if (model.getAttributes().isSleeping) stack.translate(0, 0.16F, 0); - if (model.getAttributes().isSitting) stack.translate(0, -0.2F, -0.2F); + public void transform(ModelAttributes attributes, BodyPart part, MatrixStack stack) { + if (attributes.isSwimming) stack.translate(0, -0.3F, 0); + if (attributes.isCrouching) stack.translate(0, -0.2F, 0); + if (attributes.isLyingDown) stack.translate(0, -0.77F, 0.1F); + if (attributes.isSleeping) stack.translate(0, 0.16F, 0); + if (attributes.isSitting) stack.translate(0, -0.2F, -0.2F); switch (part) { case NECK: - if (model.getAttributes().isCrouching) stack.translate(-0.03F, 0.03F, 0.13F); + if (attributes.isCrouching) stack.translate(-0.03F, 0.03F, 0.13F); break; case HEAD: - if (model.getAttributes().isLyingDown) stack.translate(-0.05F, -0.05F, 0); - if (model.getAttributes().isCrouching) stack.translate(0, 0.1F, -0); + if (attributes.isLyingDown) stack.translate(-0.05F, -0.05F, 0); + if (attributes.isCrouching) stack.translate(0, 0.1F, -0); break; case BACK: translateForRider(stack); @@ -41,23 +39,23 @@ public enum PonyTransformation { }, LANKY(SizePreset.LANKY, 0, 2.6F, 0.75F) { @Override - public void transform(PonyModel model, BodyPart part, MatrixStack stack) { - if (model.getAttributes().isSwimming) stack.translate(0, -0.2F, 0); - if (model.getAttributes().isCrouching) stack.translate(0, -0.15F, 0); - if (model.getAttributes().isLyingDown) stack.translate(0, -0.68F, 0.15F); - if (model.getAttributes().isSleeping) stack.translate(0, 0.08F, 0); - if (model.getAttributes().isSitting) stack.translate(0, 0, -0.2F); + public void transform(ModelAttributes attributes, BodyPart part, MatrixStack stack) { + if (attributes.isSwimming) stack.translate(0, -0.2F, 0); + if (attributes.isCrouching) stack.translate(0, -0.15F, 0); + if (attributes.isLyingDown) stack.translate(0, -0.68F, 0.15F); + if (attributes.isSleeping) stack.translate(0, 0.08F, 0); + if (attributes.isSitting) stack.translate(0, 0, -0.2F); switch (part) { case NECK: stack.translate(0, -0.2F, -0.05F); stack.scale(1, 1.3F, 1); - if (model.getAttributes().isCrouching) stack.translate(-0.03F, 0.01F, 0.2F); + if (attributes.isCrouching) stack.translate(-0.03F, 0.01F, 0.2F); break; case HEAD: stack.translate(0, -0.14F, -0.04F); - if (model.getAttributes().isLyingDown) stack.translate(0, 0, -0.1F); - if (model.getAttributes().isCrouching) stack.translate(0, 0.15F, 0); + if (attributes.isLyingDown) stack.translate(0, 0, -0.1F); + if (attributes.isCrouching) stack.translate(0, 0.15F, 0); break; case BODY: stack.translate(0, -0.2F, -0.04F); @@ -78,22 +76,22 @@ public enum PonyTransformation { }, BULKY(SizePreset.BULKY, 0, 2.3F, 0.75F) { @Override - public void transform(PonyModel model, BodyPart part, MatrixStack stack) { - if (model.getAttributes().isCrouching) stack.translate(0, -0.15F, 0); - if (model.getAttributes().isLyingDown) stack.translate(0, -0.66F, 0.25F); - if (model.getAttributes().isSleeping) stack.translate(0, 0.06F, 0); - if (model.getAttributes().isSitting) stack.translate(0, 0, -0.2F); + public void transform(ModelAttributes attributes, BodyPart part, MatrixStack stack) { + if (attributes.isCrouching) stack.translate(0, -0.15F, 0); + if (attributes.isLyingDown) stack.translate(0, -0.66F, 0.25F); + if (attributes.isSleeping) stack.translate(0, 0.06F, 0); + if (attributes.isSitting) stack.translate(0, 0, -0.2F); switch (part) { case NECK: stack.translate(0, -0.2F, -0.07F); stack.scale(1, 1.3F, 1); - if (model.getAttributes().isCrouching) stack.translate(-0.03F, -0.07F, 0.09F); + if (attributes.isCrouching) stack.translate(-0.03F, -0.07F, 0.09F); break; case HEAD: stack.translate(0, -0.14F, -0.06F); - if (model.getAttributes().isLyingDown) stack.translate(-0.05F, 0, -0.1F); - if (model.getAttributes().isCrouching) stack.translate(0, 0.15F, 0); + if (attributes.isLyingDown) stack.translate(-0.05F, 0, -0.1F); + if (attributes.isCrouching) stack.translate(0, 0.15F, 0); break; case BODY: stack.translate(0, -0.2F, -0.04F); @@ -114,12 +112,12 @@ public enum PonyTransformation { }, FOAL(SizePreset.FOAL, 0, 3.8F, 0.75F) { @Override - public void transform(PonyModel model, BodyPart part, MatrixStack stack) { - if (model.getAttributes().isSwimming) stack.translate(0, -0.9F, 0); - if (model.getAttributes().isCrouching) stack.translate(0, -0.2F, 0); - if (model.getAttributes().isLyingDown) stack.translate(0, -0.98F, -0.3F); - if (model.getAttributes().isSleeping) stack.translate(0, 0.18F, 0); - if (model.getAttributes().isSitting) stack.translate(0, -0.6F, -0.2F); + public void transform(ModelAttributes attributes, BodyPart part, MatrixStack stack) { + if (attributes.isSwimming) stack.translate(0, -0.9F, 0); + if (attributes.isCrouching) stack.translate(0, -0.2F, 0); + if (attributes.isLyingDown) stack.translate(0, -0.98F, -0.3F); + if (attributes.isSleeping) stack.translate(0, 0.18F, 0); + if (attributes.isSitting) stack.translate(0, -0.6F, -0.2F); stack.translate(0, 0.2F, 0); @@ -127,7 +125,7 @@ public enum PonyTransformation { case NECK: stack.translate(0, 0, 0.04F); stack.scale(1.3F, 1.3F, 1.3F); - if (model.getAttributes().isCrouching) stack.translate(-0.03F, -0.16F, 0.15F); + if (attributes.isCrouching) stack.translate(-0.03F, -0.16F, 0.15F); break; case HEAD: stack.scale(1.3F, 1.3F, 1.3F); @@ -145,21 +143,21 @@ public enum PonyTransformation { }, TALL(SizePreset.TALL, 0, 2.2F, 0.75F) { @Override - public void transform(PonyModel model, BodyPart part, MatrixStack stack) { - if (model.getAttributes().isCrouching) stack.translate(0, -0.15F, 0); - if (model.getAttributes().isLyingDown) stack.translate(0, -0.6F, 0.35F); - if (model.getAttributes().isSleeping) stack.translate(0, 0.1F, 0); - if (model.getAttributes().isSitting) stack.translate(0, 0.1F, -0.2F); + public void transform(ModelAttributes attributes, BodyPart part, MatrixStack stack) { + if (attributes.isCrouching) stack.translate(0, -0.15F, 0); + if (attributes.isLyingDown) stack.translate(0, -0.6F, 0.35F); + if (attributes.isSleeping) stack.translate(0, 0.1F, 0); + if (attributes.isSitting) stack.translate(0, 0.1F, -0.2F); switch (part) { case NECK: stack.translate(0, -0.21F, -0.01F); stack.scale(1, 1.28F, 1); - if (model.getAttributes().isCrouching) stack.translate(-0.04F, -0.1F, 0.15F); + if (attributes.isCrouching) stack.translate(-0.04F, -0.1F, 0.15F); break; case HEAD: stack.translate(0, -0.11F, 0); - if (model.getAttributes().isCrouching) stack.translate(0, 0.04F, 0); + if (attributes.isCrouching) stack.translate(0, 0.04F, 0); break; case BODY: case TAIL: @@ -168,7 +166,7 @@ public enum PonyTransformation { case LEGS: stack.translate(0, -0.27F, 0.03F); stack.scale(1, 1.18F, 1); - if (model.getAttributes().isGoingFast) stack.translate(0, 0.05F, 0); + if (attributes.isGoingFast) stack.translate(0, 0.05F, 0); break; case BACK: translateForRider(stack); @@ -178,22 +176,22 @@ public enum PonyTransformation { }, YEARLING(SizePreset.YEARLING, 0, 3.8F, 0.75F) { @Override - public void transform(PonyModel model, BodyPart part, MatrixStack stack) { - if (model.getAttributes().isSwimming) stack.translate(0, -0.6F, 0); - if (model.getAttributes().isCrouching) stack.translate(0, -0.15F, 0); - if (model.getAttributes().isLyingDown) stack.translate(0, -0.71F, -0.3F); - if (model.getAttributes().isSleeping) stack.translate(0, 0.26F, 0); - if (model.getAttributes().isSitting) stack.translate(0, -0.4F, -0.2F); + public void transform(ModelAttributes attributes, BodyPart part, MatrixStack stack) { + if (attributes.isSwimming) stack.translate(0, -0.6F, 0); + if (attributes.isCrouching) stack.translate(0, -0.15F, 0); + if (attributes.isLyingDown) stack.translate(0, -0.71F, -0.3F); + if (attributes.isSleeping) stack.translate(0, 0.26F, 0); + if (attributes.isSitting) stack.translate(0, -0.4F, -0.2F); switch (part) { case NECK: stack.translate(0, -0.2F, 0); stack.scale(1, 1.3F, 1); - if (model.getAttributes().isCrouching) stack.translate(-0.04F, -0.05F, 0.15F); + if (attributes.isCrouching) stack.translate(-0.04F, -0.05F, 0.15F); break; case HEAD: stack.translate(0, -0.15F, 0); - if (model.getAttributes().isCrouching) stack.translate(0, 0.04F, 0); + if (attributes.isCrouching) stack.translate(0, 0.04F, 0); stack.scale(1.15F, 1.15F, 1.15F); break; case BODY: @@ -203,7 +201,7 @@ public enum PonyTransformation { case LEGS: stack.translate(0, -0.265F, 0.03F); stack.scale(1, 1.18F, 1); - if (model.getAttributes().isGoingFast) stack.translate(0, 0.05F, 0); + if (attributes.isGoingFast) stack.translate(0, 0.05F, 0); break; case BACK: translateForRider(stack); @@ -230,7 +228,7 @@ public enum PonyTransformation { stack.translate(riderOffset.x, riderOffset.y, riderOffset.z); } - public abstract void transform(PonyModel model, BodyPart part, MatrixStack stack); + public abstract void transform(ModelAttributes attributes, BodyPart part, MatrixStack stack); public static PonyTransformation forSize(Size size) { return REGISTRY.getOrDefault(size, NORMAL); diff --git a/src/main/java/com/minelittlepony/client/transform/PostureFlight.java b/src/main/java/com/minelittlepony/client/transform/PostureFlight.java index b10812f4..6f6c4516 100644 --- a/src/main/java/com/minelittlepony/client/transform/PostureFlight.java +++ b/src/main/java/com/minelittlepony/client/transform/PostureFlight.java @@ -1,13 +1,14 @@ package com.minelittlepony.client.transform; -import com.minelittlepony.api.model.PonyModel; +import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.common.util.animation.MotionCompositor; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.math.RotationAxis; import net.minecraft.entity.LivingEntity; -public class PostureFlight extends MotionCompositor implements PonyPosture { +public class PostureFlight extends PonyPosture { + private final MotionCompositor compositor = new MotionCompositor(); private final float xScale; private final float yOffset; @@ -17,15 +18,22 @@ public class PostureFlight extends MotionCompositor implements PonyPosture { this.yOffset = yOffset; } + public void updateState(LivingEntity entity, PonyRenderState state) { + super.updateState(entity, state); + + double motionX = entity.getX() - entity.prevX; + double motionY = entity.isOnGround() ? 0 : entity.getY() - entity.prevY; + double motionZ = entity.getZ() - entity.prevZ; + + state.attributes.motionPitch = (float)compositor.calculateIncline(entity, motionX, motionY, motionZ); + state.attributes.motionRoll = (float)compositor.calculateRoll(entity, motionX * xScale, motionY, motionZ * xScale); + state.attributes.motionRoll = state.attributes.getMainInterpolator().interpolate("pegasusRoll", state.attributes.motionRoll, 10); + } + @Override - public void transform(PonyModel model, LivingEntity player, MatrixStack stack, double motionX, double motionY, double motionZ, float yaw, float ticks) { - model.getAttributes().motionPitch = (float)calculateIncline(player, motionX, motionY, motionZ); - model.getAttributes().motionRoll = (float)calculateRoll(player, motionX * xScale, motionY, motionZ * xScale); - - model.getAttributes().motionRoll = model.getAttributes().getMainInterpolator().interpolate("pegasusRoll", model.getAttributes().motionRoll, 10); - - stack.multiply(RotationAxis.POSITIVE_X.rotationDegrees(model.getAttributes().motionPitch)); - stack.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(model.getAttributes().motionRoll)); + public void transform(PonyRenderState state, MatrixStack stack) { + stack.multiply(RotationAxis.POSITIVE_X.rotationDegrees(state.attributes.motionPitch)); + stack.multiply(RotationAxis.POSITIVE_Z.rotationDegrees(state.attributes.motionRoll)); stack.translate(0, yOffset, 0); } }