diff --git a/build.gradle b/build.gradle index 42915b88..dfbb8c71 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ buildscript { } } plugins { - id 'fabric-loom' version '1.6-SNAPSHOT' + id 'fabric-loom' version '1.7-SNAPSHOT' id 'maven-publish' id 'com.modrinth.minotaur' version '2.+' id 'org.ajoberstar.reckon' version '0.13.1' diff --git a/gradle.properties b/gradle.properties index ffeb7aad..7ad8514c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,10 +3,10 @@ org.gradle.daemon=false # Fabric Properties # check these on https://fabricmc.net/develop - minecraft_version=1.21 - yarn_mappings=1.21+build.9 - loader_version=0.15.11 - fabric_version=0.100.7+1.21 + minecraft_version=1.21.3 + yarn_mappings=1.21.3+build.2 + loader_version=0.16.7 + fabric_version=0.106.1+1.21.3 # Mod Properties group=com.minelittlepony @@ -19,7 +19,7 @@ org.gradle.daemon=false modrinth_project_id=JBjInUXM # Dependencies - modmenu_version=11.0.0-beta.1 + modmenu_version=12.0.0-beta.1 kirin_version=1.19.1+1.21 hd_skins_version=6.13.0+1.21 - mson_version=1.10.0+1.21 + mson_version=1.11.0+1.21.3 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 17655d0e..0d184210 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/src/main/java/com/minelittlepony/api/events/PonyModelPrepareCallback.java b/src/main/java/com/minelittlepony/api/events/PonyModelPrepareCallback.java index 4d61c68f..9b8e0e4f 100644 --- a/src/main/java/com/minelittlepony/api/events/PonyModelPrepareCallback.java +++ b/src/main/java/com/minelittlepony/api/events/PonyModelPrepareCallback.java @@ -2,7 +2,6 @@ package com.minelittlepony.api.events; import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; -import net.minecraft.entity.Entity; import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.api.model.ModelAttributes; @@ -20,5 +19,5 @@ public interface PonyModelPrepareCallback { } }); - void onPonyModelPrepared(Entity entity, PonyModel model, ModelAttributes.Mode mode); + void onPonyModelPrepared(ModelAttributes attributes, PonyModel model, ModelAttributes.Mode mode); } diff --git a/src/main/java/com/minelittlepony/api/model/HornedPonyModel.java b/src/main/java/com/minelittlepony/api/model/HornedPonyModel.java index 65f50d2f..c82d1629 100644 --- a/src/main/java/com/minelittlepony/api/model/HornedPonyModel.java +++ b/src/main/java/com/minelittlepony/api/model/HornedPonyModel.java @@ -1,17 +1,17 @@ package com.minelittlepony.api.model; -import net.minecraft.entity.LivingEntity; +import com.minelittlepony.client.render.entity.state.PonyRenderState; -public interface HornedPonyModel extends PonyModel { +public interface HornedPonyModel extends PonyModel { /** * Returns true if this model is being applied to a race that can use magic. */ - default boolean hasMagic() { - return getRace().hasHorn() && getAttributes().metadata.glowColor() != 0; + default boolean hasMagic(T state) { + return state.getRace().hasHorn() && state.attributes.metadata.glowColor() != 0; } /** * Returns true if this model is currently using magic (horn is lit). */ - boolean isCasting(); + boolean isCasting(T state); } diff --git a/src/main/java/com/minelittlepony/api/model/ModelAttributes.java b/src/main/java/com/minelittlepony/api/model/ModelAttributes.java index bf3eca89..2ecc60bd 100644 --- a/src/main/java/com/minelittlepony/api/model/ModelAttributes.java +++ b/src/main/java/com/minelittlepony/api/model/ModelAttributes.java @@ -2,6 +2,7 @@ package com.minelittlepony.api.model; import com.minelittlepony.api.config.PonyConfig; import com.minelittlepony.api.pony.*; +import com.minelittlepony.api.pony.meta.Wearable; import com.minelittlepony.common.util.animation.Interpolator; import com.minelittlepony.util.MathUtil; @@ -73,6 +74,11 @@ public class ModelAttributes { */ public boolean isHorsey; + /** + * Flag indicating whether the pony is a player + */ + public boolean isPlayer; + /** * Vertical pitch whilst flying. */ @@ -130,7 +136,7 @@ public class ModelAttributes { isGoingFast = (isFlying && model instanceof WingedPonyModel) || isGliding; isGoingFast &= zMotion > 0.4F; isGoingFast |= entity.isUsingRiptide(); - isGoingFast |= entity.isFallFlying(); + isGoingFast |= entity.isGliding(); motionLerp = MathUtil.clampLimit(zMotion * 30, 1); @@ -148,18 +154,19 @@ public class ModelAttributes { } public void updateLivingState(LivingEntity entity, Pony pony, Mode mode) { + isPlayer = entity instanceof PlayerEntity; visualHeight = entity.getHeight() + 0.125F; isSitting = PonyPosture.isSitting(entity); isSleeping = entity.isAlive() && entity.isSleeping();; isLyingDown = isSleeping; - if (entity instanceof PlayerEntity) { + if (isPlayer) { boolean moving = entity.getVelocity().multiply(1, 0, 1).length() == 0 && entity.isSneaking(); isLyingDown |= getMainInterpolator().interpolate("lyingDown", moving ? 10 : 0, 200) >= 9; } isCrouching = !isLyingDown && !isSitting && mode == Mode.THIRD_PERSON && PonyPosture.isCrouching(pony, entity); isFlying = !isLyingDown && mode == Mode.THIRD_PERSON && PonyPosture.isFlying(entity); - isGliding = entity.isFallFlying(); + isGliding = entity.isGliding(); isSwimming = mode == Mode.THIRD_PERSON && PonyPosture.isSwimming(entity); isSwimmingRotated = isSwimming; isRiptide = entity.isUsingRiptide(); @@ -185,6 +192,21 @@ public class ModelAttributes { && (complement != ArmPose.BLOCK && complement != ArmPose.CROSSBOW_HOLD); } + /** + * Tests if this model is wearing the given piece of gear. + */ + public boolean isWearing(Wearable wearable) { + return isEmbedded(wearable) || featureSkins.contains(wearable.getId()); + } + + /** + * Tests if the chosen piece of gear is sourcing its texture from the main skin. + * i.e. Used to change wing rendering when using saddlebags. + */ + public boolean isEmbedded(Wearable wearable) { + return metadata.gear().matches(wearable); + } + public enum Mode { FIRST_PERSON, THIRD_PERSON, diff --git a/src/main/java/com/minelittlepony/api/model/ModelWithHooves.java b/src/main/java/com/minelittlepony/api/model/ModelWithHooves.java index 1d9e9d6e..a104efdf 100644 --- a/src/main/java/com/minelittlepony/api/model/ModelWithHooves.java +++ b/src/main/java/com/minelittlepony/api/model/ModelWithHooves.java @@ -2,6 +2,7 @@ package com.minelittlepony.api.model; import net.minecraft.client.model.ModelPart; import net.minecraft.client.render.entity.model.ModelWithArms; +import net.minecraft.client.render.entity.state.PlayerEntityRenderState; import net.minecraft.client.render.entity.model.BipedEntityModel.ArmPose; import net.minecraft.util.Arm; @@ -10,5 +11,5 @@ public interface ModelWithHooves extends ModelWithArms { ModelPart getHindLeg(Arm side); - ArmPose getArmPoseForSide(Arm side); + ArmPose getArmPoseForSide(S state, Arm side); } diff --git a/src/main/java/com/minelittlepony/api/model/PonyModel.java b/src/main/java/com/minelittlepony/api/model/PonyModel.java index baa864f8..63031652 100644 --- a/src/main/java/com/minelittlepony/api/model/PonyModel.java +++ b/src/main/java/com/minelittlepony/api/model/PonyModel.java @@ -2,84 +2,21 @@ 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.util.math.MatrixStack; -import net.minecraft.entity.LivingEntity; -import net.minecraft.util.math.MathHelper; -import com.minelittlepony.api.config.PonyConfig; -import com.minelittlepony.api.pony.Pony; -import com.minelittlepony.api.pony.PonyData; -import com.minelittlepony.api.pony.meta.*; import com.minelittlepony.mson.api.MsonModel; -public interface PonyModel extends MsonModel, ModelWithHooves, ModelWithHat, ModelWithHead { - - void copyAttributes(BipedEntityModel other); - - void updateLivingState(T entity, Pony pony, ModelAttributes.Mode mode); +public interface PonyModel extends MsonModel, ModelWithHooves, ModelWithHat, ModelWithHead { ModelPart getBodyPart(BodyPart part); /** * Applies a transform particular to a certain body part. */ - void transform(BodyPart part, MatrixStack stack); + void transform(T state, BodyPart part, MatrixStack stack); - /** - * Gets the transitive properties of this model. - */ - ModelAttributes getAttributes(); - - /** - * Sets the pony metadata object associated with this model. - */ - void setMetadata(PonyData meta); - - /** - * Gets the active scaling profile used to lay out this model's parts. - */ - default Size getSize() { - return PonyConfig.getEffectiveSize(getAttributes().metadata.size()); + public interface AttributedHolder { + ModelAttributes getAttributes(); } - - default Race getRace() { - return PonyConfig.getEffectiveRace(getAttributes().metadata.race()); - } - - /** - * Gets the current leg swing amount. - */ - float getSwingAmount(); - - /** - * Gets the step wobble used for various hair bits and animations. - */ - default float getWobbleAmount() { - if (getSwingAmount() <= 0) { - return 0; - } - - return MathHelper.sin(MathHelper.sqrt(getSwingAmount()) * MathHelper.PI * 2) * 0.04F; - } - - /** - * Gets the y-offset applied to entities riding this one. - */ - float getRiderYOffset(); - - /** - * Tests if this model is wearing the given piece of gear. - */ - default boolean isWearing(Wearable wearable) { - return isEmbedded(wearable) || getAttributes().featureSkins.contains(wearable.getId()); - } - - /** - * Tests if the chosen piece of gear is sourcing its texture from the main skin. - * i.e. Used to change wing rendering when using saddlebags. - */ - default boolean isEmbedded(Wearable wearable) { - return getAttributes().metadata.gear().matches(wearable); - } - } diff --git a/src/main/java/com/minelittlepony/api/model/PonyModelMixin.java b/src/main/java/com/minelittlepony/api/model/PonyModelMixin.java index a4582220..c471e92c 100644 --- a/src/main/java/com/minelittlepony/api/model/PonyModelMixin.java +++ b/src/main/java/com/minelittlepony/api/model/PonyModelMixin.java @@ -3,9 +3,9 @@ package com.minelittlepony.api.model; import net.minecraft.client.model.ModelPart; import net.minecraft.client.render.entity.model.BipedEntityModel; import net.minecraft.client.render.entity.model.ModelWithArms; +import net.minecraft.client.render.entity.state.BipedEntityRenderState; import net.minecraft.client.render.entity.model.BipedEntityModel.ArmPose; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.LivingEntity; import net.minecraft.util.Arm; import com.minelittlepony.api.pony.Pony; @@ -14,7 +14,7 @@ import com.minelittlepony.api.pony.meta.Size; import com.minelittlepony.mson.api.ModelView; import com.minelittlepony.mson.api.model.BoxBuilder.RenderLayerSetter; -public interface PonyModelMixin> extends PonyModel { +public interface PonyModelMixin> extends PonyModel { M mixin(); @Override @@ -108,7 +108,7 @@ public interface PonyModelMixin> mixin().setHatVisible(hatVisible); } - interface Caster & HornedPonyModel, ArmModel> extends PonyModelMixin, HornedPonyModel { + interface Caster & HornedPonyModel, ArmModel> extends PonyModelMixin, HornedPonyModel { @Override default boolean isCasting() { return mixin().isCasting(); diff --git a/src/main/java/com/minelittlepony/api/model/WingedPonyModel.java b/src/main/java/com/minelittlepony/api/model/WingedPonyModel.java index 4fdd0c82..72312e9a 100644 --- a/src/main/java/com/minelittlepony/api/model/WingedPonyModel.java +++ b/src/main/java/com/minelittlepony/api/model/WingedPonyModel.java @@ -1,12 +1,12 @@ package com.minelittlepony.api.model; -import net.minecraft.entity.LivingEntity; +import net.minecraft.client.render.entity.state.BipedEntityRenderState; import com.minelittlepony.api.config.PonyConfig; import com.minelittlepony.api.pony.meta.Wearable; import com.minelittlepony.util.MathUtil; -public interface WingedPonyModel extends PonyModel { +public interface WingedPonyModel extends PonyModel { public static final float WINGS_HALF_SPREAD_ANGLE = MathUtil.Angles._270_DEG; public static final float WINGS_FULL_SPREAD_ANGLE = MathUtil.Angles._270_DEG + 0.4F; public static final float WINGS_RAISED_ANGLE = 4; @@ -14,15 +14,15 @@ public interface WingedPonyModel extends PonyModel { /** * Returns true if the wings are spread. */ - default boolean wingsAreOpen() { - return (getAttributes().isSwimming || getAttributes().isFlying || getAttributes().isCrouching) - && (PonyConfig.getInstance().flappyElytras.get() || !getAttributes().isGliding); + default boolean wingsAreOpen(T state) { + return (state.getAttributes().isSwimming || state.getAttributes().isFlying || state.getAttributes().isCrouching) + && (PonyConfig.getInstance().flappyElytras.get() || !state.getAttributes().isGliding); } - default boolean isBurdened() { - return isWearing(Wearable.SADDLE_BAGS_BOTH) - || isWearing(Wearable.SADDLE_BAGS_LEFT) - || isWearing(Wearable.SADDLE_BAGS_RIGHT); + default boolean isBurdened(T state) { + return state.getAttributes().isWearing(Wearable.SADDLE_BAGS_BOTH) + || state.getAttributes().isWearing(Wearable.SADDLE_BAGS_LEFT) + || state.getAttributes().isWearing(Wearable.SADDLE_BAGS_RIGHT); } /** @@ -35,8 +35,8 @@ public interface WingedPonyModel extends PonyModel { * * @param ticks Partial render ticks */ - default float getWingRotationFactor(float ticks) { - return getAttributes().wingAngle; + default float getWingRotationFactor(T state, float ticks) { + return state.getAttributes().wingAngle; } } diff --git a/src/main/java/com/minelittlepony/api/model/gear/AbstractGearModel.java b/src/main/java/com/minelittlepony/api/model/gear/AbstractGearModel.java index 08c87b84..330b1b65 100644 --- a/src/main/java/com/minelittlepony/api/model/gear/AbstractGearModel.java +++ b/src/main/java/com/minelittlepony/api/model/gear/AbstractGearModel.java @@ -6,38 +6,22 @@ import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.util.math.MatrixStack; -import java.util.ArrayList; -import java.util.List; import java.util.UUID; public abstract class AbstractGearModel extends Model implements Gear { - private final List parts = new ArrayList<>(); - private final float stackingHeight; - public AbstractGearModel(float stackingHeight) { - super(RenderLayer::getEntitySolid); + public AbstractGearModel(ModelPart root, float stackingHeight) { + super(root, RenderLayer::getEntitySolid); this.stackingHeight = stackingHeight; } - public AbstractGearModel addPart(ModelPart t) { - parts.add(t); - return this; - } - @Override public void render(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color, UUID interpolatorId) { render(stack, vertices, overlay, light, color); } - @Override - public void render(MatrixStack stack, VertexConsumer renderContext, int overlay, int light, int color) { - parts.forEach(part -> { - part.render(stack, renderContext, overlay, light, color); - }); - } - @Override public boolean isStackable() { return stackingHeight > 0; diff --git a/src/main/java/com/minelittlepony/api/model/gear/Gear.java b/src/main/java/com/minelittlepony/api/model/gear/Gear.java index 021255e2..35b38d4a 100644 --- a/src/main/java/com/minelittlepony/api/model/gear/Gear.java +++ b/src/main/java/com/minelittlepony/api/model/gear/Gear.java @@ -3,6 +3,7 @@ package com.minelittlepony.api.model.gear; import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.entity.model.EntityModel; +import net.minecraft.client.render.entity.state.EntityRenderState; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.Entity; import net.minecraft.util.Identifier; @@ -37,7 +38,7 @@ public interface Gear { * * @return True to render this wearable */ - boolean canRender(PonyModel model, Entity entity); + boolean canRender(PonyModel model, EntityRenderState entity); /** * Gets the body location that this wearable appears on. @@ -62,12 +63,12 @@ public interface Gear { * * If you need to use the player's own skin, use {@link IRenderContext#getDefaultTexture(entity, wearable)} */ - Identifier getTexture(T entity, Context context); + Identifier getTexture(S entity, Context context); /** * Gets the layer used to render this piece of gear. */ - default RenderLayer getLayer(T entity, Context context) { + default RenderLayer getLayer(S entity, Context context) { return RenderLayer.getEntityTranslucent(getTexture(entity, context)); } @@ -100,7 +101,7 @@ public interface Gear { * @param The type of entity being rendered. * @param The type of the entity's primary model. */ - public interface Context> { + public interface Context> { /** * The empty context. */ @@ -109,7 +110,7 @@ public interface Gear { /** * Checks whether the given wearable and gear are able to render for this specific entity and its renderer. */ - default boolean shouldRender(M model, T entity, Wearable wearable, Gear gear) { + default boolean shouldRender(M model, S entity, Wearable wearable, Gear gear) { return gear.canRender(model, entity); } @@ -118,6 +119,6 @@ public interface Gear { * * May be the entity's own texture or a specific texture allocated for that wearable. */ - Identifier getDefaultTexture(T entity, Wearable wearable); + Identifier getDefaultTexture(S entity, Wearable wearable); } } 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 5862afbd..4aacbf7e 100644 --- a/src/main/java/com/minelittlepony/api/model/gear/WearableGear.java +++ b/src/main/java/com/minelittlepony/api/model/gear/WearableGear.java @@ -1,5 +1,6 @@ package com.minelittlepony.api.model.gear; +import net.minecraft.client.model.ModelPart; import net.minecraft.entity.Entity; import net.minecraft.util.Identifier; @@ -12,8 +13,8 @@ public class WearableGear extends AbstractGearModel { protected final Wearable wearable; protected final BodyPart location; - public WearableGear(Wearable wearable, BodyPart location, float stackingHeight) { - super(stackingHeight); + public WearableGear(ModelPart root, Wearable wearable, BodyPart location, float stackingHeight) { + super(root, stackingHeight); this.wearable = wearable; this.location = location; } diff --git a/src/main/java/com/minelittlepony/api/pony/PonyPosture.java b/src/main/java/com/minelittlepony/api/pony/PonyPosture.java index 1d037f82..46342f26 100644 --- a/src/main/java/com/minelittlepony/api/pony/PonyPosture.java +++ b/src/main/java/com/minelittlepony/api/pony/PonyPosture.java @@ -32,7 +32,7 @@ public final class PonyPosture { Vec3d motion = entity.getVelocity(); double zMotion = Math.sqrt(motion.x * motion.x + motion.z * motion.z); - return (isFlying(entity) && pony.race().hasWings()) || entity.isFallFlying() & zMotion > 0.4F; + return (isFlying(entity) && pony.race().hasWings()) || entity.isGliding() & zMotion > 0.4F; } public static boolean isFlying(LivingEntity entity) { diff --git a/src/main/java/com/minelittlepony/api/pony/meta/TriggerPixel.java b/src/main/java/com/minelittlepony/api/pony/meta/TriggerPixel.java index 6537c926..d7c19b47 100644 --- a/src/main/java/com/minelittlepony/api/pony/meta/TriggerPixel.java +++ b/src/main/java/com/minelittlepony/api/pony/meta/TriggerPixel.java @@ -29,9 +29,9 @@ public interface TriggerPixel { MAX_COORDS.y = Math.max(MAX_COORDS.y, y); Int2ObjectOpenHashMap lookup = buildLookup(options); return image -> { - int color = Color.abgrToArgb(image.getColor(x, y)); + int color = image.getColor(x, y); - if (ColorHelper.Argb.getAlpha(color) < 255) { + if (ColorHelper.getAlpha(color) < 255) { return (T)def; } return lookup.getOrDefault(color & 0x00FFFFFF, def); @@ -55,15 +55,15 @@ public interface TriggerPixel { } }; return image -> { - int color = Color.abgrToArgb(image.getColor(x, y)); - if (ColorHelper.Argb.getAlpha(color) < 255) { + int color = image.getColor(x, y); + if (ColorHelper.getAlpha(color) < 255) { return def; } @SuppressWarnings("unchecked") Set values = EnumSet.noneOf((Class)def.def().getClass()); - if (flagReader.readFlag(ColorHelper.Argb.getRed(color), values) - | flagReader.readFlag(ColorHelper.Argb.getGreen(color), values) - | flagReader.readFlag(ColorHelper.Argb.getBlue(color), values)) { + if (flagReader.readFlag(ColorHelper.getRed(color), values) + | flagReader.readFlag(ColorHelper.getGreen(color), values) + | flagReader.readFlag(ColorHelper.getBlue(color), values)) { return new Flags<>(def.def(), values, color & 0x00FFFFFF); } return def; diff --git a/src/main/java/com/minelittlepony/api/pony/meta/Wearable.java b/src/main/java/com/minelittlepony/api/pony/meta/Wearable.java index 75c7af43..f23f829a 100644 --- a/src/main/java/com/minelittlepony/api/pony/meta/Wearable.java +++ b/src/main/java/com/minelittlepony/api/pony/meta/Wearable.java @@ -54,6 +54,6 @@ public enum Wearable implements TValue { @Override public int getChannelAdjustedColorCode() { - return triggerValue == 0 ? 0 : ColorHelper.Argb.getArgb(255, triggerValue, triggerValue, triggerValue); + return triggerValue == 0 ? 0 : ColorHelper.getArgb(255, triggerValue, triggerValue, triggerValue); } } diff --git a/src/main/java/com/minelittlepony/client/compat/hdskins/MineLPHDSkins.java b/src/main/java/com/minelittlepony/client/compat/hdskins/MineLPHDSkins.java index 6d8916bf..32451a83 100644 --- a/src/main/java/com/minelittlepony/client/compat/hdskins/MineLPHDSkins.java +++ b/src/main/java/com/minelittlepony/client/compat/hdskins/MineLPHDSkins.java @@ -93,7 +93,7 @@ public class MineLPHDSkins extends ClientSkinsProxy implements ClientModInitiali @Override public Optional getSkin(Identifier skinTypeId, PlayerEntity player) { if (player instanceof AbstractClientPlayerEntity clientPlayer) { - return SkinType.REGISTRY.getOrEmpty(skinTypeId).flatMap(type -> getSkin(type, clientPlayer)); + return SkinType.REGISTRY.getOptionalValue(skinTypeId).flatMap(type -> getSkin(type, clientPlayer)); } diff --git a/src/main/java/com/minelittlepony/client/mixin/MixinHeldItemRenderer.java b/src/main/java/com/minelittlepony/client/mixin/MixinHeldItemRenderer.java index aa3d4c54..e4036f16 100644 --- a/src/main/java/com/minelittlepony/client/mixin/MixinHeldItemRenderer.java +++ b/src/main/java/com/minelittlepony/client/mixin/MixinHeldItemRenderer.java @@ -10,10 +10,10 @@ import org.jetbrains.annotations.Nullable; import net.minecraft.client.render.item.HeldItemRenderer; import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.model.json.ModelTransformationMode; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.LivingEntity; import net.minecraft.item.ItemStack; +import net.minecraft.item.ModelTransformationMode; import net.minecraft.world.World; import net.minecraft.client.render.item.ItemRenderer; diff --git a/src/main/java/com/minelittlepony/client/model/AbstractPonyModel.java b/src/main/java/com/minelittlepony/client/model/AbstractPonyModel.java index 868474ff..929c34b2 100644 --- a/src/main/java/com/minelittlepony/client/model/AbstractPonyModel.java +++ b/src/main/java/com/minelittlepony/client/model/AbstractPonyModel.java @@ -3,6 +3,7 @@ package com.minelittlepony.client.model; import com.minelittlepony.api.model.*; import com.minelittlepony.api.events.PonyModelPrepareCallback; import com.minelittlepony.api.pony.meta.SizePreset; +import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.client.transform.PonyTransformation; import com.minelittlepony.mson.util.RenderList; import com.minelittlepony.util.MathUtil; @@ -14,15 +15,22 @@ import java.util.function.Supplier; import net.minecraft.client.model.ModelPart; import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.entity.PlayerEntityRenderer; +import net.minecraft.client.render.entity.state.BipedEntityRenderState; +import net.minecraft.client.render.entity.state.PlayerEntityRenderState; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.EntityPose; import net.minecraft.entity.LivingEntity; +import net.minecraft.item.consume.UseAction; import net.minecraft.util.*; import net.minecraft.util.math.*; +import org.jetbrains.annotations.Nullable; + /** * Foundation class for all types of ponies. */ -public abstract class AbstractPonyModel extends ClientPonyModel { +public abstract class AbstractPonyModel extends ClientPonyModel { public static final float NECK_X = 0.166F; public static final float LEG_SNEAKING_PITCH_ADJUSTMENT = 0.4F; public static final float BODY_RIDING_PITCH = MathHelper.PI * 3.8F; @@ -51,8 +59,11 @@ public abstract class AbstractPonyModel extends ClientPo private final List parts = new ArrayList<>(); - public AbstractPonyModel(ModelPart tree) { - super(tree); + @Nullable + protected T currentState; + + public AbstractPonyModel(ModelPart tree, boolean smallArms) { + super(tree, smallArms); neck = tree.getChild("neck"); mainRenderList = RenderList.of() @@ -71,14 +82,19 @@ public abstract class AbstractPonyModel extends ClientPo } protected RenderList forPart(Supplier part) { - return (stack, vertices, overlay, light, color) -> { - part.get().renderPart(stack, vertices, overlay, light, color, attributes); - }; + return (stack, vertices, overlay, light, color) -> part.get().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, currentState.attributes); + } + + protected RenderList withStage(BodyPart part, RenderList action) { return (stack, vertices, overlay, light, color) -> { - part.renderPart(stack, vertices, overlay, light, color, attributes); + stack.push(); + transform(currentState, part, stack); + action.accept(stack, vertices, overlay, light, color); + stack.pop(); }; } @@ -87,27 +103,19 @@ public abstract class AbstractPonyModel extends ClientPo mainRenderList.accept(stack, vertices, overlay, light, color); } - protected RenderList withStage(BodyPart part, RenderList action) { - return (stack, vertices, overlay, light, color) -> { - stack.push(); - transform(part, stack); - action.accept(stack, vertices, overlay, light, color); - stack.pop(); - }; - } - /** * Sets the model's various rotation angles. */ + @SuppressWarnings("unchecked") @Override - public final void setAngles(T entity, float limbAngle, float limbSpeed, float animationProgress, float headYaw, float headPitch) { - attributes.checkRainboom(entity, this, animationProgress); - PonyModelPrepareCallback.EVENT.invoker().onPonyModelPrepared(entity, this, ModelAttributes.Mode.OTHER); - super.setAngles(entity, limbAngle, limbSpeed, animationProgress, headYaw, headPitch); + public final void setAngles(PlayerEntityRenderState entity) { + currentState = (T)entity; + super.setAngles((PlayerEntityRenderState)entity); resetPivot(head, neck, leftArm, rightArm, leftLeg, rightLeg); - setModelAngles(entity, limbAngle, limbSpeed, animationProgress, headYaw, headPitch); + setModelVisibilities((T)entity); + setModelAngles((T)entity); leftSleeve.copyTransform(leftArm); rightSleeve.copyTransform(rightArm); @@ -117,57 +125,70 @@ public abstract class AbstractPonyModel extends ClientPo hat.copyTransform(head); } - protected void setModelAngles(T entity, float limbAngle, float limbSpeed, float animationProgress, float headYaw, float headPitch) { - float pitch = attributes.motionPitch * MathHelper.RADIANS_PER_DEGREE; + protected void setModelVisibilities(T state) { + hat.visible = head.visible && !state.attributes.isHorsey; + parts.forEach(part -> part.setVisible(body.visible, state.attributes)); + } + + protected void setModelAngles(T entity) { + setModelAngles((T)entity, entity.limbAmplitudeInverse, entity.limbAmplitudeMultiplier, entity.age, entity.yawDegrees, entity.pitch); + } + + @Deprecated + protected final void setModelAngles(T entity, float limbAngle, float limbSpeed, float animationProgress, float headYaw, float headPitch) { + float pitch = entity.attributes.motionPitch * MathHelper.RADIANS_PER_DEGREE; head.setAngles( - MathHelper.clamp(attributes.isSleeping ? 0.1f : headPitch / 57.29578F, -1.25f - pitch, 0.5f - pitch), - attributes.isSleeping ? (Math.signum(MathHelper.wrapDegrees(headYaw)) * 1.3F) : headYaw * MathHelper.RADIANS_PER_DEGREE, + MathHelper.clamp(entity.attributes.isSleeping ? 0.1f : headPitch / 57.29578F, -1.25f - pitch, 0.5f - pitch), + entity.attributes.isSleeping ? (Math.signum(MathHelper.wrapDegrees(headYaw)) * 1.3F) : headYaw * MathHelper.RADIANS_PER_DEGREE, 0 ); - float wobbleAmount = getWobbleAmount(); + float wobbleAmount = entity.getWobbleAmount(); body.yaw = wobbleAmount; neck.yaw = wobbleAmount; - rotateLegs(limbAngle, limbSpeed, animationProgress, entity); + rotateLegs(entity, limbAngle, limbSpeed, animationProgress, entity); + + ArmPose left = getArmPose(entity, Arm.LEFT); + ArmPose right = getArmPose(entity, Arm.RIGHT); if (onSetModelAngles != null) { - onSetModelAngles.poseModel(this, limbAngle, limbSpeed, animationProgress, entity); + onSetModelAngles.poseModel(this, entity); } - if (!attributes.isSwimming && !attributes.isGoingFast) { - holdItem(limbSpeed); + if (!entity.attributes.isSwimming && !entity.attributes.isGoingFast) { + holdItem(entity, limbSpeed, left, right); } swingItem(entity); - if (attributes.isCrouching) { - ponyCrouch(); - } else if (riding) { + if (entity.attributes.isCrouching) { + ponyCrouch(entity); + } else if (entity.isInPose(EntityPose.SITTING)) { ponySit(); } else { - adjustBody(0, ORIGIN); + adjustBody(entity, 0, ORIGIN); - if (!attributes.isLyingDown) { - animateBreathing(animationProgress); + if (!entity.attributes.isLyingDown) { + animateBreathing(entity, animationProgress, left, right); } - if (attributes.isSwimmingRotated) { + if (entity.attributes.isSwimmingRotated) { rightLeg.pivotZ -= 1.5F; leftLeg.pivotZ -= 1.5F; } } - if (attributes.isLyingDown) { + if (entity.attributes.isLyingDown) { ponySleep(); } - if (attributes.isHorsey) { + if (entity.attributes.isHorsey) { head.pivotY -= 3; head.pivotZ -= 2; head.pitch = 0.5F; } - parts.forEach(part -> part.setPartAngles(attributes, limbAngle, limbSpeed, wobbleAmount, animationProgress)); + parts.forEach(part -> part.setPartAngles(entity.attributes, limbAngle, limbSpeed, wobbleAmount, animationProgress)); } public void setHeadRotation(float animationProgress, float yaw, float pitch) { @@ -179,8 +200,8 @@ public abstract class AbstractPonyModel extends ClientPo /** * Aligns legs to a sneaky position. */ - protected void ponyCrouch() { - adjustBody(BODY_SNEAKING_PITCH, BODY_SNEAKING); + protected void ponyCrouch(T state) { + adjustBody(state, BODY_SNEAKING_PITCH, BODY_SNEAKING); HEAD_SNEAKING.set(head); rightArm.pitch -= LEG_SNEAKING_PITCH_ADJUSTMENT; @@ -232,11 +253,11 @@ public abstract class AbstractPonyModel extends ClientPo * Takes the same parameters as {@link AbstractPonyModel.setRotationAndAngles} * */ - protected void rotateLegs(float move, float swing, float ticks, T entity) { - if (attributes.isSwimming) { - rotateLegsSwimming(move, swing, ticks, entity); + protected void rotateLegs(T state, float move, float swing, float ticks, T entity) { + if (state.attributes.isSwimming) { + rotateLegsSwimming(state, move, swing, ticks, entity); } else { - rotateLegsOnGround(move, swing, ticks, entity); + rotateLegsOnGround(state, move, swing, ticks, entity); } float sin = MathHelper.sin(body.yaw) * 5; @@ -245,8 +266,8 @@ public abstract class AbstractPonyModel extends ClientPo rightArm.pivotZ = 2 + sin; leftArm.pivotZ = 2 - sin; - float legRPX = attributes.getMainInterpolator().interpolate("legOffset", cos - getLegOutset() - 0.001F, 2); - if (attributes.isHorsey) { + float legRPX = state.attributes.getMainInterpolator().interpolate("legOffset", cos - state.legOutset - 0.001F, 2); + if (state.attributes.isHorsey) { legRPX += 2; } @@ -259,7 +280,7 @@ public abstract class AbstractPonyModel extends ClientPo rightArm.yaw += body.yaw; leftArm.yaw += body.yaw; - if (attributes.isHorsey) { + if (state.attributes.isHorsey) { rightArm.pivotZ = leftArm.pivotZ = -1; rightArm.pivotY = leftArm.pivotY = 6; rightLeg.pivotZ = leftLeg.pivotZ = 19; @@ -272,9 +293,9 @@ public abstract class AbstractPonyModel extends ClientPo * * Takes the same parameters as {@link AbstractPonyModel.setRotationAndAngles} */ - protected void rotateLegsSwimming(float move, float swing, float ticks, T entity) { + protected void rotateLegsSwimming(T state, float move, float swing, float ticks, T entity) { - float lerp = entity.isSwimming() ? (float)attributes.motionLerp : 1; + float lerp = entity.isInPose(EntityPose.SWIMMING) ? (float)state.attributes.motionLerp : 1; float legLeft = (MathUtil.Angles._90_DEG + MathHelper.sin((move / 3) + 2 * MathHelper.PI/3) / 2) * lerp; @@ -291,15 +312,15 @@ public abstract class AbstractPonyModel extends ClientPo * Rotates legs in quopy fashion for walking. * */ - protected void rotateLegsOnGround(float move, float swing, float ticks, T entity) { + protected void rotateLegsOnGround(T state, float move, float swing, float ticks, T entity) { float angle = MathHelper.PI * (float) Math.pow(swing, 16); float baseRotation = move * 0.6662F; // magic number ahoy float scale = swing / 4; - float rainboomLegLotation = attributes.getMainInterpolator().interpolate( + float rainboomLegLotation = state.attributes.getMainInterpolator().interpolate( "rainboom_leg_rotation", - attributes.isGoingFast ? 1 : 0, + state.attributes.isGoingFast ? 1 : 0, 5 ); float yAngle = 0.2F * rainboomLegLotation; @@ -310,24 +331,12 @@ public abstract class AbstractPonyModel extends ClientPo rightLeg.setAngles(MathHelper.lerp(rainboomLegLotation, MathHelper.cos(baseRotation + angle / 5) * scale, MathUtil.Angles._90_DEG * rainboomLegLotation), -yAngle, rightLeg.roll); } - protected float getLegOutset() { - if (attributes.isLyingDown) { - return 3.6f; - } - - if (attributes.isCrouching) { - return 1; - } - - return 5; - } - /** * Adjusts legs as if holding an item. Delegates to the correct arm/leg/limb as necessary. */ - protected void holdItem(float limbSpeed) { - alignArmForAction(getArm(Arm.LEFT), leftArmPose, rightArmPose, limbSpeed, 1); - alignArmForAction(getArm(Arm.RIGHT), rightArmPose, leftArmPose, limbSpeed, -1); + protected void holdItem(T state, float limbSpeed, ArmPose left, ArmPose right) { + alignArmForAction(state, getArm(Arm.LEFT), left, right, limbSpeed, 1); + alignArmForAction(state, getArm(Arm.RIGHT), right, left, limbSpeed, -1); } @Override @@ -350,16 +359,16 @@ public abstract class AbstractPonyModel extends ClientPo * @param pose The post to align to * @param limbSpeed Degree to which each 'limb' swings. */ - protected void alignArmForAction(ModelPart arm, ArmPose pose, ArmPose complement, float limbSpeed, float sigma) { + protected void alignArmForAction(T state, ModelPart arm, ArmPose pose, ArmPose complement, float limbSpeed, float sigma) { switch (pose) { case ITEM: arm.yaw = 0; boolean both = pose == complement; - if (attributes.shouldLiftArm(pose, complement, sigma)) { + if (state.attributes.shouldLiftArm(pose, complement, sigma)) { float swag = 1; - if (!getAttributes().isFlying && both) { + if (!state.attributes.isFlying && both) { swag -= (float)Math.pow(limbSpeed, 2); } @@ -368,7 +377,7 @@ public abstract class AbstractPonyModel extends ClientPo arm.roll = -sigma * (MathHelper.PI / 15); arm.roll += 0.3F * -limbSpeed * sigma; - if (attributes.isCrouching) { + if (state.attributes.isCrouching) { arm.pivotX -= sigma * 2; } } @@ -386,21 +395,21 @@ public abstract class AbstractPonyModel extends ClientPo } arm.pivotX += sigma; arm.pivotZ += 3; - if (attributes.isCrouching) { + if (state.attributes.isCrouching) { arm.pivotY += 4; } break; case BOW_AND_ARROW: - aimBow(arm, limbSpeed); + aimBow(state, arm, limbSpeed); break; case CROSSBOW_HOLD: - aimBow(arm, limbSpeed); + aimBow(state, arm, limbSpeed); arm.pitch = head.pitch - MathUtil.Angles._90_DEG; arm.yaw = head.yaw + 0.06F; break; case CROSSBOW_CHARGE: - aimBow(arm, limbSpeed); + aimBow(state, arm, limbSpeed); arm.pitch = -0.8F; arm.yaw = head.yaw + 0.06F; @@ -412,20 +421,20 @@ public abstract class AbstractPonyModel extends ClientPo arm.pivotY ++; break; case SPYGLASS: - float addedPitch = sneaking ? -0.2617994F : 0; - float minPitch = sneaking ? -1.8F : -2.4F; + float addedPitch = state.isInSneakingPose ? -0.2617994F : 0; + float minPitch = state.isInSneakingPose ? -1.8F : -2.4F; arm.pitch = MathHelper.clamp(head.pitch - 1.9198622F - addedPitch, minPitch, 3.3F); arm.yaw = head.yaw; - if (sneaking) { + if (state.isInSneakingPose) { arm.pivotY += 9; arm.pivotX -= 6 * sigma; arm.pivotZ -= 2; } - if (getSize() == SizePreset.TALL) { + if (state.getSize() == SizePreset.TALL) { arm.pivotY += 1; } - if (getSize() == SizePreset.FOAL) { + if (state.getSize() == SizePreset.FOAL) { arm.pivotY -= 2; } @@ -446,26 +455,24 @@ public abstract class AbstractPonyModel extends ClientPo } } - protected void aimBow(ModelPart arm, float limbSpeed) { + protected void aimBow(T state, ModelPart arm, float limbSpeed) { arm.pitch = MathUtil.Angles._270_DEG + head.pitch + (MathHelper.sin(limbSpeed * 0.067F) * 0.05F); arm.yaw = head.yaw - 0.06F; arm.roll = MathHelper.cos(limbSpeed * 0.09F) * 0.05F + 0.05F; - if (sneaking) { + if (state.isInSneakingPose) { arm.pivotY += 4; } } /** - * Animates arm swinging. Delegates to the correct arm/leg/limb as neccessary. + * Animates arm swinging. Delegates to the correct arm/leg/limb as necessary. * * @param entity The entity we are being called for. */ - protected void swingItem(T entity) { - if (getSwingAmount() > 0 && !attributes.isLyingDown) { - Arm mainSide = getPreferredArm(entity); - - swingArm(getArm(mainSide)); + protected void swingItem(T state) { + if (state.getSwingAmount() > 0 && !state.attributes.isLyingDown) { + swingArm(state, getArm(state.preferredArm)); } } @@ -474,11 +481,11 @@ public abstract class AbstractPonyModel extends ClientPo * * @param arm The arm to swing */ - protected void swingArm(ModelPart arm) { - float swing = 1 - (float)Math.pow(1 - getSwingAmount(), 3); + protected void swingArm(T state, ModelPart arm) { + float swing = 1 - (float)Math.pow(1 - state.getSwingAmount(), 3); float deltaX = MathHelper.sin(swing * MathHelper.PI); - float deltaZ = MathHelper.sin(getSwingAmount() * MathHelper.PI); + float deltaZ = MathHelper.sin(state.getSwingAmount() * MathHelper.PI); float deltaAim = deltaZ * (0.7F - head.pitch) * 0.75F; @@ -493,26 +500,26 @@ public abstract class AbstractPonyModel extends ClientPo * @param animationProgress Total whole and partial ticks since the entity's existence. * Used in animations together with {@code swing} and {@code move}. */ - protected void animateBreathing(float animationProgress) { + protected void animateBreathing(T state, float animationProgress, ArmPose left, ArmPose right) { float cos = MathHelper.cos(animationProgress * 0.09F) * 0.05F + 0.05F; float sin = MathHelper.sin(animationProgress * 0.067F) * 0.05F; - if (attributes.shouldLiftArm(rightArmPose, leftArmPose, -1)) { + if (state.attributes.shouldLiftArm(right, left, -1)) { ModelPart arm = getArm(Arm.RIGHT); arm.roll += cos; arm.pitch += sin; } - if (attributes.shouldLiftArm(leftArmPose, rightArmPose, 1)) { + if (state.attributes.shouldLiftArm(left, right, 1)) { ModelPart arm = getArm(Arm.LEFT); arm.roll += cos; arm.pitch += sin; } } - protected void adjustBody(float pitch, Pivot pivot) { + protected void adjustBody(T state, float pitch, Pivot pivot) { adjustBodyComponents(pitch, pivot); - if (!attributes.isHorsey) { + if (!state.attributes.isHorsey) { neck.setPivot(NECK_X + pitch, pivot.y(), pivot.z()); rightLeg.pivotY = FRONT_LEGS_Y; leftLeg.pivotY = FRONT_LEGS_Y; @@ -528,23 +535,11 @@ public abstract class AbstractPonyModel extends ClientPo body.pivotZ = pivot.z(); } - @Override - public float getRiderYOffset() { - switch ((SizePreset)getSize()) { - case NORMAL: return 0.4F; - case FOAL: - case TALL: - case BULKY: - default: return 0.25F; - } - } - @Override public void setVisible(boolean visible) { super.setVisible(visible); neck.visible = visible; - hat.visible &= !attributes.isHorsey; - parts.forEach(part -> part.setVisible(visible, attributes)); + hat.visible = false; } @Override @@ -553,15 +548,15 @@ public abstract class AbstractPonyModel extends ClientPo positionheldItem(arm, matrices); } - protected void positionheldItem(Arm arm, MatrixStack matrices) { + protected void positionheldItem(T state, Arm arm, MatrixStack matrices) { float left = arm == Arm.LEFT ? -1 : 1; - UseAction action = getAttributes().heldStack.getUseAction(); + UseAction action = state.attributes.heldStack.getUseAction(); - if (action == UseAction.SPYGLASS && getAttributes().itemUseTime > 0) { + if (action == UseAction.SPYGLASS && state.attributes.itemUseTime > 0) { - Arm main = getAttributes().mainArm; - if (getAttributes().activeHand == Hand.OFF_HAND) { + Arm main = state.attributes.mainArm; + if (state.attributes.activeHand == Hand.OFF_HAND) { main = main.getOpposite(); } if (main == arm) { @@ -574,28 +569,28 @@ public abstract class AbstractPonyModel extends ClientPo matrices.translate(-left * 0.1F, 0.45F, 0); - if (getAttributes().heldStack.getUseAction() == UseAction.BLOCK && getAttributes().itemUseTime == 0) { + if (state.attributes.heldStack.getUseAction() == UseAction.BLOCK && state.attributes.itemUseTime == 0) { matrices.translate(left * 0.02F, -0.25F, 0); } } @Override - public void transform(BodyPart part, MatrixStack stack) { + public void transform(T state, BodyPart part, MatrixStack stack) { - if (attributes.isHorsey) { + if (state.attributes.isHorsey) { stack.translate(0, 0.1F, 0); } - if (attributes.isSleeping || attributes.isRiptide) { + if (state.attributes.isSleeping || state.attributes.isRiptide) { stack.multiply(RotationAxis.POSITIVE_X.rotationDegrees(90)); stack.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(180)); } - if (attributes.isLyingDown && !attributes.isSleeping) { + if (state.attributes.isLyingDown && !state.attributes.isSleeping) { stack.translate(0, 1.35F, 0); } - if (attributes.isHorsey) { + if (state.attributes.isHorsey) { if (part == BodyPart.BODY) { stack.scale(1.5F, 1, 1.5F); } @@ -605,6 +600,6 @@ public abstract class AbstractPonyModel extends ClientPo neck.hidden = !head.visible; } - PonyTransformation.forSize(getSize()).transform(this, part, stack); + PonyTransformation.forSize(state.getSize()).transform(this, part, stack); } } diff --git a/src/main/java/com/minelittlepony/client/model/ClientPonyModel.java b/src/main/java/com/minelittlepony/client/model/ClientPonyModel.java index 2caf39d8..8a374f12 100644 --- a/src/main/java/com/minelittlepony/client/model/ClientPonyModel.java +++ b/src/main/java/com/minelittlepony/client/model/ClientPonyModel.java @@ -2,19 +2,13 @@ package com.minelittlepony.client.model; import net.minecraft.client.model.ModelPart; import net.minecraft.client.render.entity.model.*; -import net.minecraft.entity.LivingEntity; +import net.minecraft.client.render.entity.state.PlayerEntityRenderState; import net.minecraft.util.Arm; -import net.minecraft.util.Hand; - import org.jetbrains.annotations.Nullable; -import com.minelittlepony.api.events.PonyModelPrepareCallback; import com.minelittlepony.api.model.*; -import com.minelittlepony.api.pony.Pony; -import com.minelittlepony.api.pony.PonyData; -import com.minelittlepony.api.pony.meta.Size; -import com.minelittlepony.api.pony.meta.SizePreset; -import com.minelittlepony.mson.api.model.biped.MsonPlayer; +import com.minelittlepony.client.render.entity.state.PonyRenderState; +import com.minelittlepony.mson.api.MsonModel; /** * The raw pony model without any implementations. @@ -23,75 +17,18 @@ import com.minelittlepony.mson.api.model.biped.MsonPlayer; * * Modders can extend this class to make their own pony models if they wish. */ -public abstract class ClientPonyModel extends MsonPlayer implements PonyModel { - - /** - * The model attributes. - */ - protected ModelAttributes attributes = new ModelAttributes(); - +public abstract class ClientPonyModel extends PlayerEntityModel implements MsonModel, PonyModel { @Nullable protected PosingCallback onSetModelAngles; - public ClientPonyModel(ModelPart tree) { - super(tree); + public ClientPonyModel(ModelPart tree, boolean smallArms) { + super(tree, smallArms); } public void onSetModelAngles(PosingCallback callback) { onSetModelAngles = callback; } - protected Arm getPreferredArm(T livingEntity) { - Arm arm = livingEntity.getMainArm(); - return livingEntity.preferredHand == Hand.MAIN_HAND ? arm : arm.getOpposite(); - } - - @Override - public void updateLivingState(T entity, Pony pony, ModelAttributes.Mode mode) { - child = entity.isBaby(); - attributes.updateLivingState(entity, pony, mode); - PonyModelPrepareCallback.EVENT.invoker().onPonyModelPrepared(entity, this, mode); - sneaking = attributes.isCrouching && !attributes.isLyingDown; - riding = attributes.isSitting; - } - - @Override - public final void copyAttributes(BipedEntityModel other) { - copyStateTo(other); - } - - /** - * Copies this model's attributes into the passed model. - */ - @Override - public void copyStateTo(EntityModel model) { - super.copyStateTo(model); - - if (model instanceof ClientPonyModel) { - ((ClientPonyModel)model).attributes = attributes; - } - } - - @Override - public final ModelAttributes getAttributes() { - return attributes; - } - - @Override - public Size getSize() { - return child ? SizePreset.FOAL : PonyModel.super.getSize(); - } - - @Override - public void setMetadata(PonyData meta) { - attributes.metadata = meta; - } - - @Override - public float getSwingAmount() { - return handSwingProgress; - } - @Override public ModelPart getForeLeg(Arm side) { return getArm(side); @@ -103,8 +40,8 @@ public abstract class ClientPonyModel extends MsonPlayer } @Override - public ArmPose getArmPoseForSide(Arm side) { - return side == Arm.RIGHT ? rightArmPose : leftArmPose; + public ArmPose getArmPoseForSide(S state, Arm side) { + return getArmPose(state, side); } @Override @@ -113,7 +50,7 @@ public abstract class ClientPonyModel extends MsonPlayer } static void resetPivot(ModelPart part) { - part.setPivot(part.getDefaultTransform().pivotX, part.getDefaultTransform().pivotY, part.getDefaultTransform().pivotZ); + part.setPivot(part.getDefaultTransform().pivotX(), part.getDefaultTransform().pivotY(), part.getDefaultTransform().pivotZ()); } static void resetPivot(ModelPart...parts) { @@ -122,7 +59,7 @@ public abstract class ClientPonyModel extends MsonPlayer } } - public interface PosingCallback { - void poseModel(ClientPonyModel model, float move, float swing, float ticks, T entity); + public interface PosingCallback { + void poseModel(ClientPonyModel model, S state); } } diff --git a/src/main/java/com/minelittlepony/client/model/ModelType.java b/src/main/java/com/minelittlepony/client/model/ModelType.java index cf98cd48..fa5c8e61 100644 --- a/src/main/java/com/minelittlepony/client/model/ModelType.java +++ b/src/main/java/com/minelittlepony/client/model/ModelType.java @@ -39,7 +39,7 @@ public final class ModelType { public static final ModelKey PIGLIN = register("piglin", PiglinPonyModel::new); public static final ModelKey> SKELETON = register("skeleton", SkeleponyModel::new); public static final ModelKey> SKELETON_CLOTHES = register("skeleton_clothes", SkeleponyModel::new); - public static final ModelKey> PILLAGER = register("pillager", PillagerPonyModel::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 ENDERMAN = register("enderman", EnderStallionModel::new); 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 773b7181..324390f7 100644 --- a/src/main/java/com/minelittlepony/client/model/armour/PonyArmourModel.java +++ b/src/main/java/com/minelittlepony/client/model/armour/PonyArmourModel.java @@ -2,13 +2,14 @@ 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; -public class PonyArmourModel extends AbstractPonyModel { +public class PonyArmourModel extends AbstractPonyModel { public PonyArmourModel(ModelPart tree) { super(tree); 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 be3debf5..b327818a 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/BreezieModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/BreezieModel.java @@ -2,24 +2,18 @@ package com.minelittlepony.client.model.entity; import net.minecraft.client.model.ModelPart; import net.minecraft.client.render.entity.model.BipedEntityModel; -import net.minecraft.entity.LivingEntity; +import net.minecraft.client.render.entity.state.BipedEntityRenderState; +import net.minecraft.entity.EntityPose; import net.minecraft.util.Arm; -import net.minecraft.util.Hand; import net.minecraft.util.math.MathHelper; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; - -public class BreezieModel extends BipedEntityModel { - - private ModelPart neck; +public class BreezieModel extends BipedEntityModel { private ModelPart leftWing; private ModelPart rightWing; public BreezieModel(ModelPart tree) { super(tree); - neck = tree.getChild("neck"); leftWing = tree.getChild("left_wing"); rightWing = tree.getChild("right_wing"); } @@ -31,15 +25,13 @@ public class BreezieModel extends BipedEntityModel { } @Override - protected Iterable getBodyParts() { - return Iterables.concat(super.getBodyParts(), ImmutableList.of(neck, leftWing, rightWing)); - } + public void setAngles(T state) { - @Override - public void setAngles(T entity, float move, float swing, float ticks, float headYaw, float headPitch) { + float move = state.limbFrequency; + float swing = state.limbAmplitudeMultiplier; - head.yaw = headYaw * 0.017453292F; - head.pitch = headPitch * 0.017453292F; + head.yaw = state.yawDegrees * 0.017453292F; + head.pitch = state.pitch * 0.017453292F; hat.copyTransform(head); @@ -50,7 +42,7 @@ public class BreezieModel extends BipedEntityModel { leftLeg .setAngles(swing * MathHelper.cos(move * 0.6662F + MathHelper.PI) * 1.4F, 0, 0); rightLeg.setAngles(swing * MathHelper.cos(move * 0.6662F) * 1.4F, 0, 0); - if (riding) { + if (state.isInPose(EntityPose.SITTING)) { leftArm.pitch += -MathHelper.PI / 5; rightArm.pitch += -MathHelper.PI / 5; @@ -58,15 +50,18 @@ public class BreezieModel extends BipedEntityModel { rotateLegRiding(rightLeg, 1); } - rotateArm(leftArm, leftArmPose, 1); - rotateArm(rightArm, rightArmPose, 1); + ArmPose left = getArmPose(state, Arm.LEFT); + ArmPose right = getArmPose(state, Arm.RIGHT); - if (handSwingProgress > 0) { - swingArms(getPreferredArm(entity)); + rotateArm(leftArm, left, 1); + rotateArm(rightArm, right, 1); + + if (state.handSwingProgress > 0) { + swingArms(state, state.preferredArm); } - float rotX = MathHelper.sin(ticks * 0.067F) * 0.05F; - float rotZ = MathHelper.cos(ticks * 0.09F) * 0.05F + 0.05F; + float rotX = MathHelper.sin(state.age * 0.067F) * 0.05F; + float rotZ = MathHelper.cos(state.age * 0.09F) * 0.05F + 0.05F; leftArm.pitch -= rotX; leftArm.roll -= rotZ; @@ -74,8 +69,8 @@ public class BreezieModel extends BipedEntityModel { rightArm.pitch += rotX; rightArm.roll += rotZ; - rotX = MathHelper.sin(ticks * 0.3F) * 0.05F; - rotZ = MathHelper.cos(ticks * 0.2F) * 0.05F + 0.05F; + rotX = MathHelper.sin(state.age * 0.3F) * 0.05F; + rotZ = MathHelper.cos(state.age * 0.2F) * 0.05F + 0.05F; rotX -= 0.05F; @@ -84,25 +79,19 @@ public class BreezieModel extends BipedEntityModel { rightWing.yaw = -rotX * 10; rightWing.pitch = rotZ; - if (rightArmPose == ArmPose.BOW_AND_ARROW) { + if (right == ArmPose.BOW_AND_ARROW) { raiseArm(rightArm, leftArm, -1); - } else if (leftArmPose == ArmPose.BOW_AND_ARROW) { + } else if (left == ArmPose.BOW_AND_ARROW) { raiseArm(leftArm, rightArm, 1); } } - private Arm getPreferredArm(T livingEntity) { - Arm arm = livingEntity.getMainArm(); - return livingEntity.preferredHand == Hand.MAIN_HAND ? arm : arm.getOpposite(); - } - - protected void rotateLegRiding(ModelPart leg, float factor) { leg.setAngles(-1.4137167F, factor * MathHelper.PI / 10, factor * 0.07853982F); } - protected void swingArms(Arm mainHand) { - body.yaw = MathHelper.sin(MathHelper.sqrt(handSwingProgress) * MathHelper.TAU) / 5; + protected void swingArms(T state, Arm mainHand) { + body.yaw = MathHelper.sin(MathHelper.sqrt(state.handSwingProgress) * MathHelper.TAU) / 5; if (mainHand == Arm.LEFT) { body.yaw *= -1; @@ -120,15 +109,15 @@ public class BreezieModel extends BipedEntityModel { rightArm.pivotX = -cos; rightArm.pivotZ = sin; - float swingAmount = 1 - (float)Math.pow(1 - handSwingProgress, 4); + float swingAmount = 1 - (float)Math.pow(1 - state.handSwingProgress, 4); float swingFactorX = MathHelper.sin(swingAmount * MathHelper.PI); - float swingX = MathHelper.sin(handSwingProgress * MathHelper.PI) * (0.7F - head.pitch) * 0.75F; + float swingX = MathHelper.sin(state.handSwingProgress * MathHelper.PI) * (0.7F - head.pitch) * 0.75F; ModelPart mainArm = getArm(mainHand); mainArm.pitch -= swingFactorX * 1.2F + swingX; mainArm.yaw += body.yaw * 2; - mainArm.roll -= MathHelper.sin(handSwingProgress * MathHelper.PI) * 0.4F; + mainArm.roll -= MathHelper.sin(state.handSwingProgress * MathHelper.PI) * 0.4F; } protected void rotateArm(ModelPart arm, ArmPose pose, float factor) { diff --git a/src/main/java/com/minelittlepony/client/model/entity/EnderStallionModel.java b/src/main/java/com/minelittlepony/client/model/entity/EnderStallionModel.java index 38ad68ea..5043ab63 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/EnderStallionModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/EnderStallionModel.java @@ -3,18 +3,11 @@ package com.minelittlepony.client.model.entity; import net.minecraft.client.model.ModelPart; import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.mob.EndermanEntity; import net.minecraft.util.math.MathHelper; -import com.minelittlepony.api.pony.meta.Race; +import com.minelittlepony.client.render.entity.EnderStallionRenderer; -public class EnderStallionModel extends SkeleponyModel { - - public boolean isCarrying; - public boolean isAttacking; - - public boolean isAlicorn; - public boolean isBoss; +public class EnderStallionModel extends SkeleponyModel { private final ModelPart leftHorn; private final ModelPart rightHorn; @@ -26,23 +19,19 @@ public class EnderStallionModel extends SkeleponyModel { } @Override - public void animateModel(EndermanEntity entity, float move, float swing, float ticks) { - rightArmPose = isCarrying ? ArmPose.BLOCK : ArmPose.EMPTY; - leftArmPose = rightArmPose; - - isUnicorn = true; - isAlicorn = entity.getUuid().getLeastSignificantBits() % 3 == 0; - isBoss = !isAlicorn && entity.getUuid().getLeastSignificantBits() % 90 == 0; - - leftHorn.visible = rightHorn.visible = isBoss; - horn.setVisible(!isBoss, attributes); + protected void setModelVisibilities(EnderStallionRenderer.State state) { + super.setModelVisibilities(state); + tail.setVisible(false, state.attributes); + snout.setVisible(false, state.attributes); + horn.setVisible(!state.isBoss, state.attributes); + leftHorn.visible = rightHorn.visible = state.isBoss; } @Override - public void setModelAngles(EndermanEntity entity, float move, float swing, float ticks, float headYaw, float headPitch) { - super.setModelAngles(entity, move, swing, ticks, headYaw, headPitch); + public void setModelAngles(EnderStallionRenderer.State state) { + super.setModelAngles(state); - if (isAttacking) { + if (state.isAttacking) { head.pivotY -= 5; } } @@ -55,24 +44,10 @@ public class EnderStallionModel extends SkeleponyModel { stack.pop(); } - @Override - public Race getRace() { - return isAlicorn ? (super.getRace().hasHorn() ? Race.ALICORN : Race.PEGASUS) : super.getRace(); - } - - @Override - public void rotateArmHolding(ModelPart arm, float direction, float swingProgress, float ticks) { - arm.pitch = -0.3707964F; - arm.pitch += 0.4F + MathHelper.sin(ticks * 0.067F) / 10; - } - @Override public void setVisible(boolean visible) { super.setVisible(visible); - tail.setVisible(false, attributes); - snout.setVisible(false, attributes); - leftSleeve.visible = false; rightSleeve.visible = false; @@ -81,12 +56,12 @@ public class EnderStallionModel extends SkeleponyModel { } @Override - public boolean wingsAreOpen() { - return isAttacking; + public boolean wingsAreOpen(EnderStallionRenderer.State state) { + return state.isAttacking; } @Override - public float getWingRotationFactor(float ticks) { + public float getWingRotationFactor(EnderStallionRenderer.State state, float ticks) { return MathHelper.sin(ticks) + WINGS_HALF_SPREAD_ANGLE; } } 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 ece627f7..339316fd 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/PiglinPonyModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/PiglinPonyModel.java @@ -1,18 +1,21 @@ 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 { - private PiglinActivity activity; - private final ModelPart leftFlap; private final ModelPart rightFlap; @@ -23,24 +26,22 @@ public class PiglinPonyModel extends ZomponyModel { } @Override - public void updateLivingState(HostileEntity entity, Pony pony, ModelAttributes.Mode mode) { - super.updateLivingState(entity, pony, mode); - leftArmPose = ArmPose.EMPTY; - rightArmPose = entity.getMainHandStack().isEmpty() ? ArmPose.EMPTY : ArmPose.ITEM; - - if (entity instanceof AbstractPiglinEntity) { - activity = ((AbstractPiglinEntity)entity).getActivity(); - - if (activity == PiglinActivity.CROSSBOW_HOLD) { - rightArmPose = ArmPose.CROSSBOW_HOLD; - } else if (activity == PiglinActivity.CROSSBOW_CHARGE) { - rightArmPose = ArmPose.CROSSBOW_CHARGE; - } else if (activity == PiglinActivity.ADMIRING_ITEM) { - leftArmPose = ArmPose.ITEM; - } - } else { - activity = PiglinActivity.DEFAULT; + protected ArmPose getArmPose(PlayerEntityRenderState p, Arm arm) { + if (p instanceof PonyPiglinRenderer.State state) { + return switch (arm) { + case LEFT -> switch (state.activity) { + case CROSSBOW_HOLD -> ArmPose.CROSSBOW_HOLD; + case CROSSBOW_CHARGE -> ArmPose.CROSSBOW_CHARGE; + default -> ArmPose.EMPTY; + }; + case RIGHT -> switch (state.activity) { + case ADMIRING_ITEM -> ArmPose.ITEM; + default -> ArmPose.EMPTY; + }; + }; } + + return super.getArmPose(p, arm); } @Override 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 4d4aa654..8a129849 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/PillagerPonyModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/PillagerPonyModel.java @@ -1,31 +1,33 @@ 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.PlayerEntityRenderState; import net.minecraft.entity.mob.IllagerEntity; -import net.minecraft.entity.mob.PillagerEntity; import net.minecraft.util.Arm; import com.minelittlepony.client.model.entity.race.ChangelingModel; +import com.minelittlepony.client.render.entity.npc.PillagerRenderer; -public class PillagerPonyModel extends ChangelingModel { - +public class PillagerPonyModel extends ChangelingModel { public PillagerPonyModel(ModelPart tree) { super(tree, false); } @Override - public void animateModel(T entity, float move, float swing, float ticks) { - ArmPose holdingPose = getHoldingPose(entity.getState()); + protected BipedEntityModel.ArmPose getArmPose(PlayerEntityRenderState state, Arm arm) { + ArmPose holdingPose = getHoldingPose(((PillagerRenderer.State)state).state); if (holdingPose != ArmPose.EMPTY) { - boolean rightHanded = entity.getMainArm() == Arm.RIGHT; + boolean isMain = state.mainArm == Arm.RIGHT; - leftArmPose = rightHanded ? ArmPose.EMPTY : holdingPose; - rightArmPose = rightHanded ? holdingPose : ArmPose.EMPTY; + return isMain ? holdingPose : ArmPose.EMPTY; } + + return super.getArmPose(state, arm); } - protected ArmPose getHoldingPose(IllagerEntity.State state) { + static ArmPose getHoldingPose(IllagerEntity.State state) { switch (state) { case BOW_AND_ARROW: return ArmPose.BOW_AND_ARROW; case CROSSBOW_CHARGE: return ArmPose.CROSSBOW_CHARGE; diff --git a/src/main/java/com/minelittlepony/client/model/entity/PonyArmourStandModel.java b/src/main/java/com/minelittlepony/client/model/entity/PonyArmourStandModel.java index c5d308aa..db29be49 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/PonyArmourStandModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/PonyArmourStandModel.java @@ -2,43 +2,30 @@ package com.minelittlepony.client.model.entity; import net.minecraft.client.model.ModelPart; import net.minecraft.client.render.entity.model.ArmorStandEntityModel; -import net.minecraft.client.render.entity.model.BipedEntityModel; +import net.minecraft.client.render.entity.state.ArmorStandEntityRenderState; import net.minecraft.entity.decoration.ArmorStandEntity; -import net.minecraft.util.math.EulerAngle; import com.minelittlepony.mson.util.PartUtil; public class PonyArmourStandModel extends ArmorStandEntityModel { - private static final EulerAngle DEFAULT_LEFT_LEG_ROTATION = new EulerAngle(-1, 0, -1); - private static final EulerAngle DEFAULT_RIGHT_LEG_ROTATION = new EulerAngle(1, 0, 1); - public PonyArmourStandModel(ModelPart modelPart) { super(modelPart); } @Override - public void setAngles(ArmorStandEntity entity, float move, float swing, float ticks, float headYaw, float headPitch) { - super.setAngles(entity, move, swing, ticks, headYaw, headPitch); + public void setAngles(ArmorStandEntityRenderState state) { + super.setAngles(state); leftArm.visible = true; rightArm.visible = true; - if (entity.getLeftLegRotation().equals(DEFAULT_LEFT_LEG_ROTATION)) { + if (state.leftLegRotation.equals(ArmorStandEntity.DEFAULT_LEFT_LEG_ROTATION)) { PartUtil.copyAngles(leftArm, leftLeg); leftLeg.pitch *= -1; } - if (entity.getRightLegRotation().equals(DEFAULT_RIGHT_LEG_ROTATION)) { + if (state.rightLegRotation.equals(ArmorStandEntity.DEFAULT_RIGHT_LEG_ROTATION)) { PartUtil.copyAngles(rightArm, rightLeg); rightLeg.pitch *= -1; } } - - public void applyAnglesTo(BipedEntityModel dest) { - PartUtil.copyAngles(head, dest.head); - PartUtil.copyAngles(hat, dest.hat); - PartUtil.copyAngles(leftLeg, dest.leftLeg); - PartUtil.copyAngles(rightLeg, dest.rightLeg); - PartUtil.copyAngles(leftArm, dest.leftArm); - PartUtil.copyAngles(rightArm, dest.rightArm); - } } 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 4736ebee..b9c43931 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/SaddleModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/SaddleModel.java @@ -1,27 +1,17 @@ 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.util.math.MatrixStack; -import net.minecraft.entity.LivingEntity; +import net.minecraft.client.render.entity.state.LivingEntityRenderState; import net.minecraft.util.math.MathHelper; -public class SaddleModel extends EntityModel { - - private ModelPart root; - +public class SaddleModel extends EntityModel { public SaddleModel(ModelPart tree) { - root = tree; + super(tree); } @Override - public void setAngles(T entity, float move, float swing, float ticks, float headYaw, float headPitch) { - root.pivotY = 2 - MathHelper.cos(move * 1.5f) * 3.0f * swing; - } - - @Override - public void render(MatrixStack matrices, VertexConsumer vertices, int light, int overlay, int color) { - root.render(matrices, vertices, light, overlay, color); + public void setAngles(T 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 5a27673a..35efe038 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/SkeleponyModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/SkeleponyModel.java @@ -1,86 +1,34 @@ package com.minelittlepony.client.model.entity; -import net.minecraft.entity.mob.WitherSkeletonEntity; import net.minecraft.client.model.ModelPart; -import net.minecraft.entity.mob.HostileEntity; +import net.minecraft.client.render.entity.model.BipedEntityModel; +import net.minecraft.client.render.entity.state.PlayerEntityRenderState; import net.minecraft.item.Items; import net.minecraft.item.ItemStack; import net.minecraft.util.Arm; -import net.minecraft.util.Hand; -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.state.SkeletonPonyRenderState; -public class SkeleponyModel extends AlicornModel { - - public boolean isUnicorn; - - public boolean isWithered; - +public class SkeleponyModel extends AlicornModel { public SkeleponyModel(ModelPart tree) { super(tree, false); - this.vestRenderList.clear(); - this.sleevesRenderList.clear(); + vestRenderList.clear(); + sleevesRenderList.clear(); } + @SuppressWarnings("unchecked") @Override - public void animateModel(T entity, float move, float swing, float ticks) { - isUnicorn = entity.getUuid().getLeastSignificantBits() % 3 != 0; - isWithered = entity instanceof WitherSkeletonEntity; + protected BipedEntityModel.ArmPose getArmPose(PlayerEntityRenderState state, Arm arm) { + boolean isMain = arm == state.mainArm; - rightArmPose = ArmPose.EMPTY; - leftArmPose = ArmPose.EMPTY; - - ItemStack mainHand = entity.getStackInHand(Hand.MAIN_HAND); - ItemStack offHand = entity.getStackInHand(Hand.OFF_HAND); - - boolean right = entity.getMainArm() == Arm.RIGHT; - - if (!offHand.isEmpty()) { - if (right) { - leftArmPose = ArmPose.ITEM; - } else { - rightArmPose = ArmPose.ITEM; + if (isMain) { + ItemStack mainHand = state.getMainHandStack(); + if (!mainHand.isEmpty()) { + return mainHand.getItem() == Items.BOW && ((T)state).isAttacking ? ArmPose.BOW_AND_ARROW : ArmPose.ITEM; } } - if (!mainHand.isEmpty()) { - ArmPose pose = mainHand.getItem() == Items.BOW && entity.isAttacking() ? ArmPose.BOW_AND_ARROW : ArmPose.ITEM; - - if (right) { - rightArmPose = pose; - } else { - leftArmPose = pose; - } - } - } - - @Override - protected void rotateLegs(float move, float swing, float ticks, T entity) { - super.rotateLegs(move, swing, ticks, entity); - if (rightArmPose != ArmPose.EMPTY && entity.isAttacking()) { - rotateArmHolding(getArm(Arm.RIGHT), -1, getSwingAmount(), ticks); - } - - if (leftArmPose != ArmPose.EMPTY && entity.isAttacking()) { - rotateArmHolding(getArm(Arm.LEFT), -1, getSwingAmount(), ticks); - } - } - - protected void rotateArmHolding(ModelPart arm, float direction, float swingProgress, float ticks) { - MobPosingHelper.rotateArmHolding(arm, direction, swingProgress, ticks); - } - - @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; + return super.getArmPose(state, arm); } } 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 2bd98601..2fc4822c 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/SpikeModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/SpikeModel.java @@ -2,11 +2,12 @@ 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 { +public class SpikeModel extends BipedEntityModel { private final ModelPart tail; private final ModelPart tail2; @@ -20,22 +21,22 @@ public class SpikeModel extends BipedEntityModel { } @Override - public void setAngles(T entity, float move, float swing, float ticks, float headYaw, float headPitch) { - swing *= 2; - move *= 1.5F; - child = false; + public void setAngles(T entity) { + entity.limbFrequency *= 2; + entity.limbAmplitudeMultiplier *= 1.5F; + entity.baby = false; head.pivotX = 0; head.pivotZ = 0; head.pivotY = 0; - super.setAngles(entity, move, swing, ticks, headYaw, headPitch); + super.setAngles(entity); leftArm.pivotY++; rightArm.pivotY++; body.pitch += 0.15F; - if ((entity instanceof StriderEntity strider && strider.isSaddled())) { + if ((entity instanceof SaddleableRenderState strider && strider.isSaddled())) { leftArm.pitch = 3.15F; leftArm.yaw = 1; rightArm.pitch = 3.15F; @@ -60,8 +61,8 @@ public class SpikeModel extends BipedEntityModel { rightArm.pivotZ += 2; rightArm.pitch -= 0.3F; - if (entity instanceof StriderEntity strider && strider.isCold()) { - float armMotion = (float)Math.sin(ticks / 10F) / 10F; + if (entity instanceof StriderEntityRenderState strider && strider.cold) { + float armMotion = (float)Math.sin(entity.age / 10F) / 10F; leftArm.pitch = -1 - armMotion; rightArm.pitch = -1 + armMotion; @@ -74,21 +75,15 @@ public class SpikeModel extends BipedEntityModel { } } - tail.pitch = (float)Math.sin(move) / 3F - 0.5F; + tail.pitch = (float)Math.sin(entity.limbFrequency) / 3F - 0.5F; tail2.pitch = -tail.pitch / 2; tail3.pitch = tail2.pitch / 2; - tail.yaw = (float)Math.sin(ticks / 20F) / 40 + (float)Math.sin(move / 20F) / 4; + tail.yaw = (float)Math.sin(entity.age / 20F) / 40 + (float)Math.sin(entity.limbFrequency / 20F) / 4; tail2.yaw = tail.yaw / 2; tail3.yaw = tail2.yaw / 2; - for (var part : getHeadParts()) { - part.pivotY += 7; - } - - for (var part : getBodyParts()) { - part.pivotY += 7; - } + getRootPart().pivotY += 7; } } diff --git a/src/main/java/com/minelittlepony/client/model/entity/WitchPonyModel.java b/src/main/java/com/minelittlepony/client/model/entity/WitchPonyModel.java index 08d1fe57..424cf82a 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/WitchPonyModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/WitchPonyModel.java @@ -2,39 +2,23 @@ package com.minelittlepony.client.model.entity; import net.minecraft.client.model.ModelPart; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.mob.WitchEntity; import net.minecraft.util.*; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.RotationAxis; -import com.minelittlepony.api.model.ModelAttributes; -import com.minelittlepony.api.pony.Pony; -import com.minelittlepony.api.pony.meta.*; import com.minelittlepony.client.model.entity.race.EarthPonyModel; +import com.minelittlepony.client.render.entity.WitchRenderer; -public class WitchPonyModel extends EarthPonyModel { - +public class WitchPonyModel extends EarthPonyModel { public WitchPonyModel(ModelPart tree) { super(tree, false); } @Override - public void updateLivingState(WitchEntity entity, Pony pony, ModelAttributes.Mode mode) { - super.updateLivingState(entity, pony, mode); + public void setModelAngles(WitchRenderer.State entity) { + super.setModelAngles(entity); - if (entity.hasCustomName() && "Filly".equals(entity.getCustomName().getString())) { - child = true; - } - attributes.visualHeight += 0.5F; - leftArmPose = ArmPose.EMPTY; - rightArmPose = entity.getMainHandStack().isEmpty() ? ArmPose.EMPTY : ArmPose.ITEM; - } - - @Override - public void setModelAngles(WitchEntity entity, float move, float swing, float ticks, float headYaw, float headPitch) { - super.setModelAngles(entity, move, swing, ticks, headYaw, headPitch); - - if (entity.isDrinking()) { + if (entity.drinking) { float noseRot = MathHelper.sin(entity.age); snout.rotate(noseRot * 4.5F * 0.02F, 0, noseRot * 2.5F * 0.02F); @@ -42,12 +26,12 @@ public class WitchPonyModel extends EarthPonyModel { snout.rotate(0, 0, 0); } - if (rightArmPose != ArmPose.EMPTY) { - float rot = (float)(Math.tan(ticks / 7) + Math.sin(ticks / 3)); + if (!entity.getMainHandStack().isEmpty()) { + float rot = (float)(Math.tan(entity.age / 7) + Math.sin(entity.age / 3)); if (rot > 1) rot = 1; if (rot < -1) rot = -1; - float legDrinkingAngle = -1 * MathHelper.PI/3 + rot; + float legDrinkingAngle = -1 * MathHelper.PI / 3F + rot; rightArm.pitch = legDrinkingAngle; rightArm.yaw = 0.1F; @@ -64,13 +48,8 @@ public class WitchPonyModel extends EarthPonyModel { } @Override - protected void positionheldItem(Arm arm, MatrixStack matrices) { - super.positionheldItem(arm, matrices); + protected void positionheldItem(WitchRenderer.State state, Arm arm, MatrixStack matrices) { + super.positionheldItem(state, arm, matrices); matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(10)); } - - @Override - public boolean isWearing(Wearable wearable) { - return wearable == Wearable.HAT || super.isWearing(wearable); - } } 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 aeb45361..4ad605cd 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 @@ -3,12 +3,13 @@ package com.minelittlepony.client.model.entity.race; import com.minelittlepony.api.model.SubModel; import com.minelittlepony.api.model.WingedPonyModel; import com.minelittlepony.client.model.part.PonyWings; +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 { +public class AlicornModel extends UnicornModel implements WingedPonyModel { private PonyWings> 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 72d2af1f..fe919525 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 @@ -1,23 +1,25 @@ package com.minelittlepony.client.model.entity.race; import net.minecraft.client.model.ModelPart; -import net.minecraft.entity.LivingEntity; import net.minecraft.util.math.MathHelper; -public class ChangelingModel extends AlicornModel { +import com.minelittlepony.api.model.ModelAttributes; +import com.minelittlepony.client.render.entity.state.PonyRenderState; + +public class ChangelingModel extends AlicornModel { public ChangelingModel(ModelPart tree, boolean smallArms) { super(tree, smallArms); } @Override - public boolean wingsAreOpen() { - return (getAttributes().isFlying || getAttributes().isCrouching) && !getAttributes().isGliding; + public boolean wingsAreOpen(ModelAttributes state) { + return (state.isFlying || state.isCrouching) && !state.isGliding; } @Override - public float getWingRotationFactor(float ticks) { - if (getAttributes().isFlying) { + public float getWingRotationFactor(ModelAttributes state, float ticks) { + if (state.isFlying) { return MathHelper.sin(ticks * 3) + WINGS_HALF_SPREAD_ANGLE; } return 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 60cfde72..a2b3e52b 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 @@ -3,14 +3,12 @@ package com.minelittlepony.client.model.entity.race; import com.minelittlepony.api.model.SubModel; import com.minelittlepony.client.model.AbstractPonyModel; import com.minelittlepony.client.model.part.*; +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 EarthPonyModel extends AbstractPonyModel { - - private final boolean smallArms; +public class EarthPonyModel extends AbstractPonyModel { protected SubModel tail; protected PonySnout snout; @@ -21,11 +19,10 @@ public class EarthPonyModel extends AbstractPonyModel private final ModelPart tailStub; public EarthPonyModel(ModelPart tree, boolean smallArms) { - super(tree); + super(tree, smallArms); mane = neck.getChild("mane"); nose = head.getChild("nose"); tailStub = body.getChild("tail_stub"); - this.smallArms = smallArms; } @Override @@ -39,25 +36,18 @@ public class EarthPonyModel extends AbstractPonyModel bodyRenderList.add(forPart(tail)); } - @Override - public void setModelAngles(T entity, float move, float swing, float ticks, float headYaw, float headPitch) { - super.setModelAngles(entity, move, swing, ticks, headYaw, headPitch); - cape.pivotY = sneaking ? 2 : riding ? -4 : 0; - } - - @Override - protected float getLegOutset() { - if (smallArms) { - return Math.max(1, super.getLegOutset() - 1); - } - return super.getLegOutset(); + protected void setModelVisibilities(T state) { + super.setModelVisibilities(state); + mane.visible = state.attributes.isHorsey; + nose.visible = state.attributes.isHorsey; + tailStub.visible = !state.attributes.isHorsey; } @Override public void setVisible(boolean visible) { super.setVisible(visible); - mane.visible = attributes.isHorsey; - nose.visible = attributes.isHorsey; - tailStub.visible = !attributes.isHorsey; + mane.visible = visible; + nose.visible = visible; + tailStub.visible = visible; } } diff --git a/src/main/java/com/minelittlepony/client/model/entity/race/KirinModel.java b/src/main/java/com/minelittlepony/client/model/entity/race/KirinModel.java index dead6554..f420dfc9 100644 --- a/src/main/java/com/minelittlepony/client/model/entity/race/KirinModel.java +++ b/src/main/java/com/minelittlepony/client/model/entity/race/KirinModel.java @@ -1,11 +1,11 @@ package com.minelittlepony.client.model.entity.race; import net.minecraft.client.model.ModelPart; -import net.minecraft.entity.LivingEntity; import com.minelittlepony.api.model.Pivot; +import com.minelittlepony.client.render.entity.state.PonyRenderState; -public class KirinModel extends UnicornModel { +public class KirinModel extends UnicornModel { private final ModelPart beard; @@ -15,8 +15,8 @@ public class KirinModel extends UnicornModel { } @Override - protected void adjustBody(float pitch, Pivot pivot) { - super.adjustBody(pitch, pivot); + protected void adjustBody(T state, float pitch, Pivot pivot) { + super.adjustBody(state, pitch, pivot); beard.resetTransform(); beard.pitch -= neck.pitch; } 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 f120d9da..2beaf718 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 @@ -3,12 +3,12 @@ package com.minelittlepony.client.model.entity.race; import com.minelittlepony.api.model.SubModel; import com.minelittlepony.api.model.WingedPonyModel; import com.minelittlepony.client.model.part.PonyWings; +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 PegasusModel extends EarthPonyModel implements WingedPonyModel { +public class PegasusModel extends EarthPonyModel implements WingedPonyModel { private PonyWings> 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 dd95f528..08687f0b 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 @@ -4,13 +4,14 @@ 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 { +public class SeaponyModel extends UnicornModel { private static final float FIN_Y_ANGLE = MathHelper.PI / 6; @@ -60,12 +61,12 @@ public class SeaponyModel extends UnicornModel { protected void ponySit() {} @Override - public void setModelAngles(T entity, float move, float swing, float ticks, float headYaw, float headPitch) { - super.setModelAngles(entity, move, swing, ticks, headYaw, headPitch); + protected void setModelAngles(T entity) { + super.setModelAngles(entity); - float flapMotion = MathHelper.cos(ticks / 10) / 5; + float flapMotion = MathHelper.cos(entity.age / 10) / 5; - if (attributes.isLyingDown) { + if (entity.attributes.isLyingDown) { flapMotion /= 2; } @@ -75,20 +76,20 @@ public class SeaponyModel extends UnicornModel { rightFin.yaw = -finAngle; centerFin.roll = flapMotion; - if (!entity.isSubmergedInWater()) { + if (!entity.submergedInWater) { leftArm.pitch -= 0.5F; rightArm.pitch -= 0.5F; } - if (!entity.isSubmergedInWater() || entity.isOnGround()) { + if (!entity.submergedInWater || entity.onGround) { leftArm.yaw -= 0.5F; rightArm.yaw += 0.5F; } } @Override - protected void rotateLegs(float move, float swing, float ticks, T entity) { - super.rotateLegs(move, swing, ticks, entity); + protected void rotateLegs(T state, float move, float swing, float ticks, T entity) { + super.rotateLegs(state, move, swing, ticks, entity); leftArm.pitch -= 1.4F; leftArm.yaw -= 0.3F; rightArm.pitch -= 1.4F; @@ -96,8 +97,8 @@ public class SeaponyModel extends UnicornModel { } @Override - protected void rotateLegsSwimming(float move, float swing, float ticks, T entity) { - super.rotateLegsOnGround(move, swing, ticks, entity); + protected void rotateLegsSwimming(T state, float move, float swing, float ticks, T entity) { + super.rotateLegsOnGround(state, move, swing, ticks, entity); } @Override @@ -114,7 +115,7 @@ public class SeaponyModel extends UnicornModel { rightFin.visible = visible; } - public static class Armour extends PonyArmourModel { + public static class Armour extends PonyArmourModel { public Armour(ModelPart tree) { super(tree); @@ -131,14 +132,13 @@ public class SeaponyModel extends UnicornModel { } @Override - protected void rotateLegsSwimming(float move, float swing, float ticks, T entity) { - super.rotateLegsOnGround(move, swing, ticks, entity); + 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) { stack.translate(0, 0.6F, 0); - super.transform(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 b7882433..2028fb2e 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 @@ -5,19 +5,21 @@ import com.minelittlepony.api.model.*; import com.minelittlepony.api.pony.meta.Size; import com.minelittlepony.api.pony.meta.SizePreset; import com.minelittlepony.client.model.part.UnicornHorn; +import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.mson.api.ModelView; import com.minelittlepony.mson.util.RenderList; import net.minecraft.client.model.ModelPart; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.LivingEntity; +import net.minecraft.item.consume.UseAction; import net.minecraft.registry.Registries; import net.minecraft.util.*; /** * Used for both unicorns and alicorns since there's no logical way to keep them distinct and not duplicate stuff. */ -public class UnicornModel extends EarthPonyModel implements HornedPonyModel { +public class UnicornModel extends EarthPonyModel implements HornedPonyModel { protected final ModelPart unicornArmRight; protected final ModelPart unicornArmLeft; @@ -34,20 +36,20 @@ public class UnicornModel extends EarthPonyModel impl public void init(ModelView context) { super.init(context); horn = addPart(context.findByName("horn")); - headRenderList.add(RenderList.of().add(head::rotate).add(forPart(horn)).checked(() -> getRace().hasHorn())); + 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, getAttributes().metadata.glowColor()); - })).checked(() -> hasMagic() && isCasting())); + horn.renderMagic(stack, vertices, currentState.attributes.metadata.glowColor()); + })).checked(() -> hasMagic(currentState) && isCasting(currentState))); } @Override public float getWobbleAmount() { - return isCasting() ? 0 : super.getWobbleAmount(); + return isCasting(currentState) ? 0 : super.getWobbleAmount(); } @Override - protected void rotateLegs(float move, float swing, float ticks, T entity) { - super.rotateLegs(move, swing, ticks, entity); + protected void rotateLegs(T state, float move, float swing, float ticks, T entity) { + super.rotateLegs(state, move, swing, ticks, entity); unicornArmRight.setAngles(0, 0, 0); unicornArmRight.setPivot(-7, 12, -2); @@ -57,31 +59,30 @@ public class UnicornModel extends EarthPonyModel impl } @Override - public boolean isCasting() { - return PonyConfig.getInstance().tpsmagic.get() - && (rightArmPose != ArmPose.EMPTY || leftArmPose != ArmPose.EMPTY); + public boolean isCasting(T state) { + return PonyConfig.getInstance().tpsmagic.get() && (!state.leftHandStack.isEmpty() || !state.rightHandStack.isEmpty()); } @Override - protected void ponyCrouch() { - super.ponyCrouch(); + protected void ponyCrouch(T state) { + super.ponyCrouch(state); unicornArmRight.pitch -= LEG_SNEAKING_PITCH_ADJUSTMENT; unicornArmLeft.pitch -= LEG_SNEAKING_PITCH_ADJUSTMENT; } @Override public ModelPart getArm(Arm side) { - if (hasMagic() && getArmPoseForSide(side) != ArmPose.EMPTY && PonyConfig.getInstance().tpsmagic.get()) { + if (hasMagic(currentState) && getArmPoseForSide(currentState, side) != ArmPose.EMPTY && PonyConfig.getInstance().tpsmagic.get()) { return side == Arm.LEFT ? unicornArmLeft : unicornArmRight; } return super.getArm(side); } @Override - protected void positionheldItem(Arm arm, MatrixStack matrices) { - super.positionheldItem(arm, matrices); + protected void positionheldItem(T state, Arm arm, MatrixStack matrices) { + super.positionheldItem(state, arm, matrices); - if (!PonyConfig.getInstance().tpsmagic.get() || !hasMagic()) { + if (!PonyConfig.getInstance().tpsmagic.get() || !hasMagic(state)) { return; } @@ -89,19 +90,19 @@ public class UnicornModel extends EarthPonyModel impl matrices.translate(0.4F - (0.3F * left), -0.675F, -0.3F); - UseAction action = getAttributes().heldStack.getUseAction(); + UseAction action = state.attributes.heldStack.getUseAction(); boolean shouldAimItem = - (action == UseAction.SPYGLASS || action == UseAction.BOW) && getAttributes().itemUseTime > 0 - || PonyConfig.getInstance().forwardHoldingItems.get().contains(Registries.ITEM.getId(getAttributes().heldStack.getItem())); + (action == UseAction.SPYGLASS || action == UseAction.BOW) && state.attributes.itemUseTime > 0 + || PonyConfig.getInstance().forwardHoldingItems.get().contains(Registries.ITEM.getId(state.attributes.heldStack.getItem())); if (shouldAimItem) { - Arm main = getAttributes().mainArm; - if (getAttributes().activeHand == Hand.OFF_HAND) { + Arm main = state.attributes.mainArm; + if (state.attributes.activeHand == Hand.OFF_HAND) { main = main.getOpposite(); } if (main == arm) { if (action == UseAction.SPYGLASS) { - Size size = getSize(); + Size size = state.getSize(); float x = 0.3F; float z = -0.4F; diff --git a/src/main/java/com/minelittlepony/client/render/DebugBoundingBoxRenderer.java b/src/main/java/com/minelittlepony/client/render/DebugBoundingBoxRenderer.java index 1359858f..9174a96e 100644 --- a/src/main/java/com/minelittlepony/client/render/DebugBoundingBoxRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/DebugBoundingBoxRenderer.java @@ -6,6 +6,7 @@ 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.util.math.MatrixStack; import net.minecraft.entity.LivingEntity; import net.minecraft.util.math.Box; @@ -15,34 +16,32 @@ 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 { - public static void render(Pony pony, EntityRenderer renderer, T entity, MatrixStack stack, VertexConsumerProvider renderContext, float tickDelta) { - + public static void render(T state, MatrixStack stack, VertexConsumerProvider matrices) { if (RenderPass.getCurrent() != RenderPass.WORLD) { return; } MinecraftClient client = MinecraftClient.getInstance(); - if (!client.getEntityRenderDispatcher().shouldRenderHitboxes() || entity.isInvisible() || client.hasReducedDebugInfo()) { + if (!client.getEntityRenderDispatcher().shouldRenderHitboxes() || state.invisible || client.hasReducedDebugInfo()) { return; } - Vec3d offset = renderer.getPositionOffset(entity, tickDelta); + Vec3d offset = state.positionOffset; stack.push(); stack.translate(-offset.x, -offset.y, -offset.z); - Box boundingBox = PonyBounds.getBoundingBox(pony, entity); + Box boundingBox = PonyBounds.getBoundingBox(state.pony, state); - Vec3d pos = entity.getPos(); + double x = -state.x; + double y = -state.y; + double z = -state.z; - double x = - MathHelper.lerp(tickDelta, entity.lastRenderX, pos.x); - double y = - MathHelper.lerp(tickDelta, entity.lastRenderY, pos.y); - double z = - MathHelper.lerp(tickDelta, entity.lastRenderZ, pos.z); - - VertexConsumer vertices = renderContext.getBuffer(RenderLayer.getLines()); + VertexConsumer vertices = matrices.getBuffer(RenderLayer.getLines()); WorldRenderer.drawBox(stack, vertices, boundingBox.offset(x, y, z), 1, 1, 0, 1); stack.pop(); diff --git a/src/main/java/com/minelittlepony/client/render/EquineRenderManager.java b/src/main/java/com/minelittlepony/client/render/EquineRenderManager.java index 2d6fe1d1..306c7867 100644 --- a/src/main/java/com/minelittlepony/client/render/EquineRenderManager.java +++ b/src/main/java/com/minelittlepony/client/render/EquineRenderManager.java @@ -7,6 +7,7 @@ import com.minelittlepony.api.model.*; import com.minelittlepony.api.pony.Pony; import com.minelittlepony.api.pony.PonyData; 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; @@ -20,20 +21,26 @@ 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; import org.jetbrains.annotations.Nullable; -public class EquineRenderManager & PonyModel> { +public class EquineRenderManager< + T extends LivingEntity, + S extends PonyRenderState, + M extends EntityModel & PonyModel> { private Models models; @Nullable - private Function> modelsLookup; + private Function> modelsLookup; - private final PonyRenderContext context; - private final Transformer transformer; + private final PonyRenderContext context; + private final Transformer transformer; private final FrustrumCheck frustrum; @@ -41,7 +48,7 @@ public class EquineRenderManager context, Transformer transformer, Models models) { + public EquineRenderManager(PonyRenderContext context, Transformer transformer, Models models) { this.context = context; this.transformer = transformer; this.models = models; @@ -50,11 +57,11 @@ public class EquineRenderManager context, Transformer transformer, ModelKey key) { + public EquineRenderManager(PonyRenderContext context, Transformer transformer, ModelKey key) { this(context, transformer, new Models(key)); } - public void setModelsLookup(@Nullable Function> modelsLookup) { + public void setModelsLookup(@Nullable Function> modelsLookup) { this.modelsLookup = modelsLookup; } @@ -73,78 +80,40 @@ public class EquineRenderManager { - void setupTransforms(T entity, MatrixStack stack, float animationProgress, float bodyYaw, float tickDelta, float scale); + public interface Transformer { + void setupTransforms(S state, MatrixStack stack, float animationProgress, float bodyYaw); } public interface RegistrationHandler { SyncedPony getSyncedPony(); } - public interface ModelHolder & PonyModel> { + public interface ModelHolder & PonyModel> { void setModel(M model); } diff --git a/src/main/java/com/minelittlepony/client/render/FrustrumCheck.java b/src/main/java/com/minelittlepony/client/render/FrustrumCheck.java index 40ab90ea..270f5b36 100644 --- a/src/main/java/com/minelittlepony/client/render/FrustrumCheck.java +++ b/src/main/java/com/minelittlepony/client/render/FrustrumCheck.java @@ -19,9 +19,9 @@ public class FrustrumCheck extends Frustum { private Frustum vanilla; - private final PonyRenderContext context; + private final PonyRenderContext context; - public FrustrumCheck(PonyRenderContext context) { + public FrustrumCheck(PonyRenderContext context) { super(new Matrix4f(), new Matrix4f()); this.context = context; } diff --git a/src/main/java/com/minelittlepony/client/render/MagicGlow.java b/src/main/java/com/minelittlepony/client/render/MagicGlow.java index 97da7dc0..e5ab9b62 100644 --- a/src/main/java/com/minelittlepony/client/render/MagicGlow.java +++ b/src/main/java/com/minelittlepony/client/render/MagicGlow.java @@ -5,8 +5,7 @@ import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.RenderPhase; import net.minecraft.client.render.VertexFormat; import net.minecraft.client.render.VertexFormats; -import net.minecraft.util.Identifier; -import net.minecraft.util.Util; +import net.minecraft.util.*; import com.mojang.blaze3d.systems.RenderSystem; import com.google.common.base.Suppliers; @@ -62,7 +61,7 @@ public abstract class MagicGlow extends RenderPhase { private final float alpha; public Colored(Identifier texture, int color) { - super(texture, false, false); + super(texture, TriState.FALSE, false); this.red = Color.r(color); this.green = Color.g(color); this.blue = Color.b(color); diff --git a/src/main/java/com/minelittlepony/client/render/PonyRenderContext.java b/src/main/java/com/minelittlepony/client/render/PonyRenderContext.java index 3c244c96..33f99d64 100644 --- a/src/main/java/com/minelittlepony/client/render/PonyRenderContext.java +++ b/src/main/java/com/minelittlepony/client/render/PonyRenderContext.java @@ -3,15 +3,20 @@ package com.minelittlepony.client.render; import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.api.model.gear.Gear; import com.minelittlepony.api.pony.Pony; +import com.minelittlepony.client.render.entity.state.PonyRenderState; import net.minecraft.client.render.entity.model.EntityModel; import net.minecraft.entity.LivingEntity; -public interface PonyRenderContext & PonyModel> extends Gear.Context { +public interface PonyRenderContext< + T extends LivingEntity, + S extends PonyRenderState, + M extends EntityModel & PonyModel + > extends Gear.Context { Pony getEntityPony(T entity); - EquineRenderManager getInternalRenderer(); + EquineRenderManager getInternalRenderer(); void setModel(M model); } diff --git a/src/main/java/com/minelittlepony/client/render/PonyRenderDispatcher.java b/src/main/java/com/minelittlepony/client/render/PonyRenderDispatcher.java index 71eb5b5f..b27a3bf7 100644 --- a/src/main/java/com/minelittlepony/client/render/PonyRenderDispatcher.java +++ b/src/main/java/com/minelittlepony/client/render/PonyRenderDispatcher.java @@ -8,6 +8,7 @@ import com.minelittlepony.api.model.PreviewModel; import com.minelittlepony.api.pony.*; import com.minelittlepony.client.mixin.MixinEntityRenderers; import com.minelittlepony.client.render.entity.*; +import com.minelittlepony.client.render.entity.state.PonyRenderState; import org.jetbrains.annotations.Nullable; @@ -16,6 +17,7 @@ import com.minelittlepony.mson.api.Mson; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.entity.*; import net.minecraft.client.render.entity.model.EntityModel; +import net.minecraft.client.render.entity.state.EntityRenderState; import net.minecraft.client.util.SkinTextures; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityType; @@ -69,7 +71,7 @@ public class PonyRenderDispatcher { * @param factory The replacement value * @param The entity type */ - void switchRenderer(MobRenderers state, EntityType type, Function> factory) { + void switchRenderer(MobRenderers state, EntityType type, Function> factory) { Mson.getInstance().getEntityRendererRegistry().registerEntityRenderer(type, ctx -> state.get() ? factory.apply(ctx) : MixinEntityRenderers.getRendererFactories().get(type).create(ctx) @@ -78,7 +80,7 @@ public class PonyRenderDispatcher { @SuppressWarnings("unchecked") @Nullable - public & PonyModel> PonyRenderContext getPonyRenderer(@Nullable T entity) { + public & PonyModel> PonyRenderContext getPonyRenderer(@Nullable T entity) { if (entity != null && MinecraftClient.getInstance().getEntityRenderDispatcher().getRenderer(entity) instanceof PonyRenderContext c) { return c; } 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 fa94254c..fc37bc2c 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/AbstractPonyRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/AbstractPonyRenderer.java @@ -10,11 +10,11 @@ import com.minelittlepony.client.render.PonyRenderContext; import com.minelittlepony.client.render.EquineRenderManager; import com.minelittlepony.client.render.entity.feature.*; import com.minelittlepony.client.render.entity.npc.textures.TextureSupplier; +import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.mson.api.ModelKey; import java.util.*; -import java.util.function.Consumer; -import java.util.function.Function; +import java.util.function.*; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.Frustum; @@ -23,29 +23,41 @@ import net.minecraft.client.render.entity.EntityRendererFactory; import net.minecraft.client.render.entity.MobEntityRenderer; import net.minecraft.client.render.entity.feature.FeatureRenderer; import net.minecraft.client.render.entity.model.*; +import net.minecraft.client.render.entity.state.BipedEntityRenderState; +import net.minecraft.client.render.entity.state.PlayerEntityRenderState; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.mob.MobEntity; import net.minecraft.text.Text; import net.minecraft.util.Identifier; -public abstract class AbstractPonyRenderer & PonyModel & ModelWithArms> extends MobEntityRenderer implements PonyRenderContext { +public abstract class AbstractPonyRenderer< + T extends MobEntity, + S extends PonyRenderState, + M extends EntityModel & PonyModel + > extends MobEntityRenderer implements PonyRenderContext { - protected final EquineRenderManager manager; + protected final EquineRenderManager manager; private final Map wearableTextures = new EnumMap<>(Wearable.class); - private final TextureSupplier texture; + private final TextureSupplier texture; private final float scale; - public AbstractPonyRenderer(EntityRendererFactory.Context context, ModelKey key, TextureSupplier texture, float scale) { + public AbstractPonyRenderer(EntityRendererFactory.Context context, ModelKey key, TextureSupplier texture, float scale) { super(context, null, 0.5F); - this.manager = new EquineRenderManager<>(this, super::setupTransforms, key); + this.manager = new EquineRenderManager(this, super::setupTransforms, key); this.texture = texture; this.scale = scale; addFeatures(context); } + @Override + public void updateRenderState(T entity, S state, float tickDelta) { + super.updateRenderState(entity, state, tickDelta); + manager.preRender(entity, state, ModelAttributes.Mode.THIRD_PERSON); + } + protected void addFeatures(EntityRendererFactory.Context context) { addFeature(new ArmourFeature<>(this, context.getModelManager())); addFeature(createHeldItemFeature(context)); @@ -54,47 +66,48 @@ public abstract class AbstractPonyRenderer(this)); } - protected HeldItemFeature createHeldItemFeature(EntityRendererFactory.Context context) { - return new HeldItemFeature<>(this, context.getHeldItemRenderer()); + @SuppressWarnings({"unchecked", "rawtypes"}) + protected final boolean addPonyFeature(FeatureRenderer> feature) { + return ((List)features).add(feature); + } + + protected HeldItemFeature createHeldItemFeature(EntityRendererFactory.Context context) { + return new HeldItemFeature(this, context.getItemRenderer()); } @Override - public final Identifier getTexture(T entity) { + public final Identifier getTexture(S entity) { return texture.apply(entity); } @Override - public void render(T entity, float entityYaw, float tickDelta, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv) { - manager.preRender(entity, ModelAttributes.Mode.THIRD_PERSON); - if (manager.getModels().body() instanceof BipedEntityModel model) { - model.setVisible(true); - } - super.render(entity, entityYaw, tickDelta, stack, renderContext, lightUv); - DebugBoundingBoxRenderer.render(getEntityPony(entity), this, entity, stack, renderContext, tickDelta); + 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); } @Override - protected void setupTransforms(T entity, MatrixStack stack, float animationProgress, float bodyYaw, float tickDelta, float scale) { - manager.setupTransforms(entity, stack, animationProgress, bodyYaw, tickDelta, scale); + protected void setupTransforms(S state, MatrixStack stack, float animationProgress, float bodyYaw) { + manager.setupTransforms(state, stack, animationProgress, bodyYaw); } @Override - public boolean shouldRender(T entity, Frustum visibleRegion, double camX, double camY, double camZ) { - return super.shouldRender(entity, manager.getFrustrum(entity, visibleRegion), camX, camY, camZ); + public boolean shouldRender(T state, Frustum visibleRegion, double camX, double camY, double camZ) { + return super.shouldRender(state, manager.getFrustrum(state, visibleRegion), camX, camY, camZ); } @Override - public void scale(T entity, MatrixStack stack, float tickDelta) { - shadowRadius = manager.getShadowSize(); + public void scale(S state, MatrixStack stack) { + shadowRadius = state.getShadowSize(); - if (entity.isBaby()) { + if (state.baby) { shadowRadius *= 3; // undo vanilla shadow scaling } - if (!entity.hasVehicle()) { - stack.translate(0, 0, -entity.getWidth() / 2); // move us to the center of the shadow + if (!state.hasVehicle) { + stack.translate(0, 0, -state.width / 2); // move us to the center of the shadow } else { - if (manager.getModels().body().getAttributes().isSitting && entity.hasVehicle()) { + if (state.attributes.isSitting && state.hasVehicle) { stack.translate(0, 0.25F, 0); } } @@ -103,17 +116,17 @@ public abstract class AbstractPonyRenderer { - Identifier texture = getTexture(entity).withPath(path -> path.split("\\.")[0] + "_" + wearable.name().toLowerCase(Locale.ROOT) + ".png"); + Identifier texture = getTexture(state).withPath(path -> path.split("\\.")[0] + "_" + wearable.name().toLowerCase(Locale.ROOT) + ".png"); if (MinecraftClient.getInstance().getResourceManager().getResource(texture).isPresent()) { return texture; @@ -128,7 +141,7 @@ public abstract class AbstractPonyRenderer getInternalRenderer() { + public EquineRenderManager getInternalRenderer() { return manager; } @@ -137,25 +150,39 @@ public abstract class AbstractPonyRenderer, T extends PonyRenderer, F extends FeatureRenderer> + public static , T extends PonyRenderer, F extends FeatureRenderer> T appendFeature(T renderer, Function featureFactory) { renderer.addFeature(featureFactory.apply(renderer)); return renderer; } @SuppressWarnings({"unchecked", "rawtypes"}) - public static & PonyModel & ModelWithArms> AbstractPonyRenderer proxy(EntityRendererFactory.Context context, ModelKey key, TextureSupplier texture, float scale, - List exportedLayers, Consumer modelConsumer) { - var renderer = new AbstractPonyRenderer(context, key, texture, scale) { + public static < + T extends MobEntity, + S extends PonyRenderState, + M extends EntityModel & PonyModel> AbstractPonyRenderer proxy( + EntityRendererFactory.Context context, ModelKey key, + TextureSupplier texture, + float scale, + List exportedLayers, + Consumer modelConsumer, + Supplier renderStateSupplier) { + return new AbstractPonyRenderer(context, key, texture, scale) { + { + exportedLayers.clear(); + exportedLayers.addAll(features); + modelConsumer.accept(getModel()); + } @Override protected void addFeatures(EntityRendererFactory.Context context) { features.clear(); super.addFeatures(context); } + + @Override + public S createRenderState() { + return renderStateSupplier.get(); + } }; - exportedLayers.clear(); - exportedLayers.addAll(renderer.features); - modelConsumer.accept(renderer.getModel()); - return renderer; } } 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 99922f3c..3217cba3 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/EnderStallionRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/EnderStallionRenderer.java @@ -1,11 +1,16 @@ 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.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; @@ -13,13 +18,16 @@ import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.EntityRendererFactory; import net.minecraft.client.render.entity.feature.StuckArrowsFeatureRenderer; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.mob.EndermanEntity; -import net.minecraft.item.ItemStack; +import net.minecraft.util.Arm; import net.minecraft.util.Identifier; +import org.jetbrains.annotations.Nullable; + import java.util.Random; -public class EnderStallionRenderer extends PonyRenderer implements IGlowingRenderer { +public class EnderStallionRenderer extends PonyRenderer implements IGlowingRenderer { public static final Identifier ENDERMAN = MineLittlePony.id("textures/entity/enderman/enderman_pony.png"); private static final Identifier EYES = MineLittlePony.id("textures/entity/enderman/enderman_pony_eyes.png"); @@ -29,42 +37,67 @@ public class EnderStallionRenderer extends PonyRenderer(context, this)); - addFeature(new GlowingEyesFeature<>(this)); + addPonyFeature(createHeldItemFeature(context)); + addPonyFeature(new StuckArrowsFeatureRenderer((PonyRenderer)this, context)); + addPonyFeature(new GlowingEyesFeature(this)); } @Override - protected HeldItemFeature createHeldItemFeature(EntityRendererFactory.Context context) { - return new HeldItemFeature(this, context.getHeldItemRenderer()) { - @Override - protected ItemStack getRightItem(EndermanEntity entity) { - BlockState state = entity.getCarriedBlock(); - if (state == null) { - return ItemStack.EMPTY; - } - - return new ItemStack(state.getBlock().asItem()); - } - }; + protected HeldItemFeature createHeldItemFeature(EntityRendererFactory.Context context) { + return new HeldItemFeature(this, context.getItemRenderer()); } @Override - public void render(EndermanEntity entity, float entityYaw, float tickDelta, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv) { - model.isCarrying = entity.getCarriedBlock() != null; - model.isAttacking = entity.isAngry(); - - if (entity.isAngry()) { - stack.translate(rnd.nextGaussian() / 50, 0, rnd.nextGaussian() / 50); + public void render(State entity, MatrixStack matrices, VertexConsumerProvider vertices, int light) { + if (entity.angry) { + matrices.translate(rnd.nextGaussian() / 50, 0, rnd.nextGaussian() / 50); } - super.render(entity, entityYaw, tickDelta, stack, renderContext, lightUv); + super.render(entity, matrices, vertices, light); } @Override public Identifier getEyeTexture() { return EYES; } + + public class State extends SkeletonPonyRenderState { + public boolean angry; + @Nullable + public BlockState carriedBlock; + + public boolean isAlicorn; + public boolean isBoss; + + public void updateState(LivingEntity entity, PonyModel model, Pony pony, ModelAttributes.Mode mode) { + super.updateState(entity, model, pony, mode); + isUnicorn = true; + isAlicorn = entity.getUuid().getLeastSignificantBits() % 3 == 0; + isBoss = !isAlicorn && entity.getUuid().getLeastSignificantBits() % 90 == 0; + + angry = ((EndermanEntity)entity).isAngry(); + carriedBlock = ((EndermanEntity)entity).getCarriedBlock(); + + if (carriedBlock != null) { + if (mainArm == Arm.RIGHT) { + rightHandStack = carriedBlock.getBlock().asItem().getDefaultStack(); + } else { + leftHandStack = carriedBlock.getBlock().asItem().getDefaultStack(); + } + } + } + + @Override + public Race getRace() { + return isAlicorn ? (super.getRace().hasHorn() ? Race.ALICORN : Race.PEGASUS) : super.getRace(); + } + } } 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 b91d6bde..e48e81aa 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/PlayerPonyRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/PlayerPonyRenderer.java @@ -10,6 +10,8 @@ import com.minelittlepony.client.model.*; import com.minelittlepony.client.render.DebugBoundingBoxRenderer; import com.minelittlepony.client.render.PonyRenderContext; import com.minelittlepony.client.render.entity.feature.*; +import com.minelittlepony.client.render.entity.state.PlayerPonyRenderState; +import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.common.util.render.RenderLayerUtil; import java.util.*; @@ -24,19 +26,26 @@ import net.minecraft.client.render.*; import net.minecraft.client.render.entity.EntityRendererFactory; import net.minecraft.client.render.entity.PlayerEntityRenderer; import net.minecraft.client.render.entity.feature.*; +import net.minecraft.client.render.entity.state.PlayerEntityRenderState; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.EntityPose; import net.minecraft.text.Text; import net.minecraft.util.*; +import net.minecraft.util.math.Vec3d; -public class PlayerPonyRenderer extends PlayerEntityRenderer implements PonyRenderContext> { - private final Function>> modelsCache; - protected final EquineRenderManager> manager; +public class PlayerPonyRenderer + extends PlayerEntityRenderer + implements PonyRenderContext> { + private final Function>> modelsCache; + protected final EquineRenderManager> manager; + + private ModelAttributes.Mode mode = ModelAttributes.Mode.THIRD_PERSON; public PlayerPonyRenderer(EntityRendererFactory.Context context, boolean slim) { super(context, slim); modelsCache = Util.memoize(race -> ModelType.getPlayerModel(race).create(slim)); manager = new EquineRenderManager<>(this, super::setupTransforms, modelsCache.apply(Race.EARTH)); - manager.setModelsLookup(entity -> modelsCache.apply(getPlayerRace(entity, getEntityPony(entity)))); + manager.setModelsLookup(entity -> modelsCache.apply(getPlayerRace(entity))); addPonyFeatures(context); } @@ -53,7 +62,7 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements PonyRend || feature instanceof ShoulderParrotFeatureRenderer; }); addPonyFeature(new ArmourFeature<>(this, context.getModelManager())); - addPonyFeature(new HeldItemFeature(this, context.getHeldItemRenderer())); + addPonyFeature(new HeldItemFeature(this, context.getItemRenderer())); addPonyFeature(new DJPon3Feature<>(this)); addPonyFeature(new CapeFeature<>(this)); addPonyFeature(new SkullFeature<>(this, context.getModelLoader(), context.getItemRenderer())); @@ -63,29 +72,41 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements PonyRend } @SuppressWarnings({"unchecked", "rawtypes"}) - protected final boolean addPonyFeature(FeatureRenderer> feature) { + protected final boolean addPonyFeature(FeatureRenderer> feature) { return ((List)features).add(feature); } + public Vec3d getPositionOffset(PlayerEntityRenderState state) { + Vec3d offset = super.getPositionOffset(state); + return offset.multiply(((PonyRenderState)state).getScaleFactor()); + } + @Override - protected void scale(AbstractClientPlayerEntity entity, MatrixStack stack, float tickDelta) { - if (manager.getModels().body().getAttributes().isSitting && entity.hasVehicle()) { - stack.translate(0, -0.25F * manager.getScaleFactor(), 0); + public PlayerEntityRenderState createRenderState() { + return new PlayerPonyRenderState(); + } + + @Override + public void updateRenderState(AbstractClientPlayerEntity entity, PlayerEntityRenderState state, float tickDelta) { + super.updateRenderState(entity, state, tickDelta); + manager.preRender(entity, (PlayerPonyRenderState)state, mode); + } + + public final PlayerPonyRenderState getAndUpdateRenderState(AbstractClientPlayerEntity entity, float tickDelta, ModelAttributes.Mode mode) { + try { + this.mode = mode; + return (PlayerPonyRenderState)getAndUpdateRenderState(entity, tickDelta); + } finally { + this.mode = ModelAttributes.Mode.THIRD_PERSON; } - super.scale(entity, stack, tickDelta); - } - - protected void preRender(AbstractClientPlayerEntity player, ModelAttributes.Mode mode) { - manager.preRender(player, mode); } @Override - public void render(AbstractClientPlayerEntity entity, float entityYaw, float tickDelta, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv) { + public void render(PlayerEntityRenderState state, MatrixStack stack, VertexConsumerProvider vertices, int light) { // EntityModelFeatures: We have to force it to use our models otherwise EMF overrides it and breaks pony rendering - preRender(entity, ModelAttributes.Mode.THIRD_PERSON); - shadowRadius = manager.getShadowSize(); - super.render(entity, entityYaw, tickDelta, stack, renderContext, lightUv); - DebugBoundingBoxRenderer.render(getEntityPony(entity), this, entity, stack, renderContext, tickDelta); + shadowRadius = ((PlayerPonyRenderState)state).getShadowSize(); + super.render(state, stack, vertices, light); + DebugBoundingBoxRenderer.render((PlayerPonyRenderState)state, stack, vertices); // Translate the shadow position after everything is done // (shadows are drawn after us) @@ -102,13 +123,13 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements PonyRend } - protected Race getPlayerRace(AbstractClientPlayerEntity entity, Pony pony) { - return pony.race(); + protected Race getPlayerRace(PlayerPonyRenderState state) { + return state.getRace(); } @Override - protected void setupTransforms(AbstractClientPlayerEntity entity, MatrixStack matrices, float animationProgress, float bodyYaw, float tickDelta, float scale) { - manager.setupTransforms(entity, matrices, animationProgress, bodyYaw, tickDelta, scale); + protected void setupTransforms(PlayerEntityRenderState state, MatrixStack matrices, float animationProgress, float bodyYaw) { + manager.setupTransforms((PlayerPonyRenderState)state, matrices, animationProgress, bodyYaw); } @Override @@ -121,71 +142,61 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements PonyRend } @Override - protected void renderLabelIfPresent(AbstractClientPlayerEntity entity, Text name, MatrixStack stack, VertexConsumerProvider renderContext, int light, float tickDelta) { - stack.push(); + protected void renderLabelIfPresent(PlayerEntityRenderState state, Text name, MatrixStack matrices, VertexConsumerProvider vertices, int light) { + matrices.push(); + if (state.isInPose(EntityPose.SLEEPING)) { + if (state.sleepingDirection != null && ((PlayerPonyRenderState)state).sleepingInBed) { + double bedRad = Math.toRadians(state.sleepingDirection.asRotation()); - if (entity.isSleeping()) { - if (entity.getSleepingPosition().isPresent() && entity.getEntityWorld().getBlockState(entity.getSleepingPosition().get()).getBlock() instanceof BedBlock) { - double bedRad = Math.toRadians(entity.getSleepingDirection().asRotation()); - - stack.translate(Math.cos(bedRad), 0, -Math.sin(bedRad)); + matrices.translate(Math.cos(bedRad), 0, -Math.sin(bedRad)); } } - stack.translate(0, manager.getNamePlateYOffset(entity), 0); - super.renderLabelIfPresent(entity, name, stack, renderContext, light, tickDelta); - stack.pop(); + matrices.translate(0, ((PlayerPonyRenderState)state).nameplateYOffset, 0); + super.renderLabelIfPresent(state, name, matrices, vertices, light); + matrices.pop(); } @Override - public final void renderRightArm(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, AbstractClientPlayerEntity player) { - renderArm(stack, renderContext, lightUv, player, Arm.RIGHT); + public final void renderRightArm(MatrixStack matrices, VertexConsumerProvider vertices, int light, Identifier skinTexture, boolean sleeveVisible) { + renderArm(matrices, vertices, light, skinTexture, sleeveVisible, Arm.RIGHT); } @Override - public final void renderLeftArm(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, AbstractClientPlayerEntity player) { - renderArm(stack, renderContext, lightUv, player, Arm.LEFT); + public final void renderLeftArm(MatrixStack matrices, VertexConsumerProvider vertices, int light, Identifier skinTexture, boolean sleeveVisible) { + renderArm(matrices, vertices, light, skinTexture, sleeveVisible, Arm.LEFT); } - protected void renderArm(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, AbstractClientPlayerEntity player, Arm side) { - preRender(player, ModelAttributes.Mode.FIRST_PERSON); - + protected void renderArm(MatrixStack stack, VertexConsumerProvider renderContext, int light, Identifier skinTexture, boolean sleeveVisible, Arm side) { stack.push(); float reflect = side == Arm.LEFT ? 1 : -1; stack.translate(reflect * 0.1F, -0.54F, 0); - Identifier texture = getTexture(player); - Identifier playerSkin = player.getSkinTextures().texture(); VertexConsumerProvider interceptedContext = layer -> { return renderContext.getBuffer(RenderLayerUtil .getTexture(layer) - .filter(playerSkin::equals) - .map(i -> RenderLayer.getEntityTranslucent(texture)) + .filter(skinTexture::equals) + .map(i -> RenderLayer.getEntityTranslucent(skinTexture)) .orElse(layer) ); }; if (side == Arm.LEFT) { - super.renderLeftArm(stack, interceptedContext, lightUv, player); + super.renderLeftArm(stack, interceptedContext, light, skinTexture, sleeveVisible); } else { - super.renderRightArm(stack, interceptedContext, lightUv, player); + super.renderRightArm(stack, interceptedContext, light, skinTexture, sleeveVisible); } stack.pop(); } @Override - public Identifier getTexture(AbstractClientPlayerEntity player) { - return getEntityPony(player).texture(); - } - - @Override - public void setModel(ClientPonyModel model) { + public void setModel(ClientPonyModel model) { this.model = model; } @Override - public EquineRenderManager> getInternalRenderer() { + public EquineRenderManager> getInternalRenderer() { return manager; } @@ -195,13 +206,20 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements PonyRend } @Override - public Identifier getDefaultTexture(AbstractClientPlayerEntity entity, Wearable wearable) { - return SkinsProxy.getInstance().getSkin(wearable.getId(), entity).orElseGet(() -> { - if (wearable.isSaddlebags() && getInternalRenderer().getModels().body().getRace().supportsLegacySaddlebags()) { - return getTexture(entity); - } + public Identifier getTexture(PlayerEntityRenderState state) { + return ((PonyRenderState)state).pony.texture(); + } - return wearable.getDefaultTexture(); - }); + @Override + public Identifier getDefaultTexture(PlayerPonyRenderState state, Wearable wearable) { + if (state.wearabledTextures.containsKey(wearable)) { + return state.wearabledTextures.get(wearable); + } + + if (wearable.isSaddlebags() && state.getRace().supportsLegacySaddlebags()) { + return getTexture(state); + } + + return wearable.getDefaultTexture(); } } diff --git a/src/main/java/com/minelittlepony/client/render/entity/PonyPigRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/PonyPigRenderer.java index 0f76375b..179bfce6 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/PonyPigRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/PonyPigRenderer.java @@ -6,35 +6,32 @@ import net.minecraft.client.render.entity.EntityRendererFactory; import net.minecraft.client.render.entity.PigEntityRenderer; import net.minecraft.client.render.entity.feature.*; import net.minecraft.client.render.entity.model.*; +import net.minecraft.client.render.entity.state.PigEntityRenderState; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.passive.PigEntity; import com.minelittlepony.api.pony.meta.Wearable; public class PonyPigRenderer extends PigEntityRenderer { - public PonyPigRenderer(EntityRendererFactory.Context context) { super(context); addFeature(new CrownFeature(this)); } - private final class CrownFeature extends FeatureRenderer> { - private final PigEntityModel model; + private final class CrownFeature extends FeatureRenderer { + private final PigEntityModel model; - public CrownFeature(FeatureRendererContext> context) { + public CrownFeature(FeatureRendererContext context) { super(context); - model = new PigEntityModel<>(PigEntityModel.getTexturedModelData(new Dilation(0.5F)).createModel()); + model = new PigEntityModel(PigEntityModel.getTexturedModelData(new Dilation(0.5F)).createModel()); } @Override - public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, PigEntity entity, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) { - if (!entity.hasCustomName() || !entity.getCustomName().getString().equalsIgnoreCase("technoblade")) { + public void render(MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, PigEntityRenderState entity, float limbDistance, float limbAngle) { + if (entity.customName == null || !entity.customName.getString().equalsIgnoreCase("technoblade")) { return; } - getContextModel().copyStateTo(model); - model.animateModel(entity, limbAngle, limbDistance, tickDelta); - model.setAngles(entity, limbAngle, limbDistance, animationProgress, headYaw, headPitch); + model.setAngles(entity); VertexConsumer vertexConsumer = vertexConsumers.getBuffer(RenderLayer.getEntityCutoutNoCull(Wearable.CROWN.getDefaultTexture())); model.render(matrices, vertexConsumer, light, OverlayTexture.DEFAULT_UV, 0xFFFFFFFF); } 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 33941110..bbd3e97b 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/PonyPiglinRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/PonyPiglinRenderer.java @@ -1,16 +1,19 @@ package com.minelittlepony.client.render.entity; import net.minecraft.client.render.entity.EntityRendererFactory; -import net.minecraft.entity.mob.AbstractPiglinEntity; -import net.minecraft.entity.mob.HostileEntity; +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 class PonyPiglinRenderer extends PonyRenderer { public static final Identifier PIGLIN = MineLittlePony.id("textures/entity/piglin/piglin_pony.png"); public static final Identifier PIGLIN_BRUTE = MineLittlePony.id("textures/entity/piglin/piglin_brute_pony.png"); public static final Identifier ZOMBIFIED_PIGLIN = MineLittlePony.id("textures/entity/piglin/zombified_piglin_pony.png"); @@ -32,7 +35,24 @@ public class PonyPiglinRenderer extends PonyRenderer> extends AbstractPonyRenderer { +public abstract class PonyRenderer< + T extends MobEntity, + S extends PonyRenderState, + M extends ClientPonyModel + > extends AbstractPonyRenderer { protected static final float BASE_MODEL_SCALE = 15/16F; - public PonyRenderer(EntityRendererFactory.Context context, ModelKey key, TextureSupplier texture) { + public PonyRenderer(EntityRendererFactory.Context context, ModelKey key, TextureSupplier texture) { this(context, key, texture, 1); } - public PonyRenderer(EntityRendererFactory.Context context, ModelKey key, TextureSupplier texture, float scale) { + public PonyRenderer(EntityRendererFactory.Context context, ModelKey key, TextureSupplier texture, float scale) { super(context, key, texture, scale); } + @SuppressWarnings({"rawtypes", "unchecked"}) @Override protected void addFeatures(EntityRendererFactory.Context context) { super.addFeatures(context); - addFeature(new StuckArrowsFeatureRenderer<>(context, this)); + addFeature(new StuckArrowsFeatureRenderer(this, context)); } } diff --git a/src/main/java/com/minelittlepony/client/render/entity/WitchRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/WitchRenderer.java index e456b748..af15d485 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/WitchRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/WitchRenderer.java @@ -1,18 +1,48 @@ 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.Wearable; import com.minelittlepony.client.MineLittlePony; import com.minelittlepony.client.model.ModelType; import com.minelittlepony.client.model.entity.WitchPonyModel; 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.entity.LivingEntity; import net.minecraft.entity.mob.WitchEntity; import net.minecraft.util.Identifier; -public class WitchRenderer extends PonyRenderer { +public class WitchRenderer extends PonyRenderer { private static final Identifier WITCH_TEXTURES = MineLittlePony.id("textures/entity/witch_pony.png"); public WitchRenderer(EntityRendererFactory.Context context) { super(context, ModelType.WITCH, TextureSupplier.of(WITCH_TEXTURES), BASE_MODEL_SCALE); } + + @Override + public State createRenderState() { + return new State(); + } + + public static class State extends PonyRenderState { + public boolean drinking; + + @Override + public void updateState(LivingEntity entity, PonyModel model, Pony pony, ModelAttributes.Mode mode) { + super.updateState(entity, model, pony, mode); + drinking = entity instanceof WitchEntity w && w.isDrinking(); + attributes.visualHeight += 0.5F; + if (customName != null && "Filly".equals(customName.getString())) { + baby = true; + } + } + + @Override + public boolean isWearing(Wearable wearable) { + return wearable == Wearable.HAT || super.isWearing(wearable); + } + } } 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 f9904335..01985523 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 @@ -12,31 +12,32 @@ import net.minecraft.util.Colors; import net.minecraft.util.Identifier; import com.minelittlepony.api.model.PonyModel; +import com.minelittlepony.client.render.entity.state.PonyRenderState; // separate class in case I need it later -public abstract class AbstractClothingFeature & PonyModel> extends FeatureRenderer { +public abstract class AbstractClothingFeature< + T extends LivingEntity, + S extends PonyRenderState, + M extends BipedEntityModel & PonyModel + > extends FeatureRenderer { - protected final FeatureRendererContext renderer; + protected final FeatureRendererContext renderer; - public AbstractClothingFeature(FeatureRendererContext render) { + public AbstractClothingFeature(FeatureRendererContext render) { super(render); renderer = render; } @Override - public void render(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, T entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) { + public void render(MatrixStack matrices, VertexConsumerProvider vertices, int light, S state, float limbAngle, float limbDistance) { M overlayModel = getOverlayModel(); - renderer.getModel().copyStateTo(overlayModel); - overlayModel.animateModel(entity, limbDistance, limbAngle, tickDelta); - overlayModel.setAngles(entity, limbDistance, limbAngle, age, headYaw, headPitch); - - VertexConsumer vertexConsumer = renderContext.getBuffer(overlayModel.getLayer(getOverlayTexture())); - overlayModel.render(stack, vertexConsumer, lightUv, OverlayTexture.DEFAULT_UV, Colors.WHITE); + overlayModel.setAngles(state); + VertexConsumer buffer = vertices.getBuffer(overlayModel.getLayer(getOverlayTexture())); + overlayModel.render(matrices, buffer, light, OverlayTexture.DEFAULT_UV, Colors.WHITE); } protected abstract M getOverlayModel(); protected abstract Identifier getOverlayTexture(); - } \ No newline at end of file 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 1664b64a..3eb8d46f 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 @@ -3,43 +3,28 @@ package com.minelittlepony.client.render.entity.feature; import com.minelittlepony.api.model.Models; import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.client.render.PonyRenderContext; +import com.minelittlepony.client.render.entity.state.PonyRenderState; -import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.feature.FeatureRenderer; import net.minecraft.client.render.entity.feature.FeatureRendererContext; import net.minecraft.client.render.entity.model.EntityModel; -import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.LivingEntity; -public abstract class AbstractPonyFeature & PonyModel> extends FeatureRenderer { +public abstract class AbstractPonyFeature< + S extends PonyRenderState, + M extends EntityModel & PonyModel + > extends FeatureRenderer { - private final PonyRenderContext context; + private final PonyRenderContext context; @SuppressWarnings("unchecked") - public AbstractPonyFeature(PonyRenderContext context) { - super((FeatureRendererContext)context); + public AbstractPonyFeature(PonyRenderContext context) { + super((FeatureRendererContext)context); this.context = context; } - /** - * Renders this layer. - * - * @param stack The GL transformation matrix - * @param vertices The output 3D vertex buffer - * @param lightUv The current light value - * @param entity The entity we're being called for. - * @param limbDistance Entity motion parameter - i.e. velocity in no specific direction used in bipeds to calculate step amount. - * @param limbAngle Degree to which each 'limb' swings. - * @param tickDelta Render partial ticks - * @param age Total whole and partial ticks since the entity's existance. Used in animations together with {@code swing} and {@code move}. - * @param headYaw Horizontal head motion in radians. - * @param headPitch Vertical head motion in radians. - */ - @Override - public abstract void render(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, T entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch); - @SuppressWarnings("unchecked") - protected & FeatureRendererContext> C getContext() { + protected & FeatureRendererContext> C getContext() { return (C)context; } @@ -48,7 +33,7 @@ public abstract class AbstractPonyFeature 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 0c9f9569..202b98a7 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 @@ -10,6 +10,7 @@ import java.util.*; import net.minecraft.client.render.*; 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; @@ -19,19 +20,19 @@ import net.minecraft.item.*; import net.minecraft.item.trim.ArmorTrim; import net.minecraft.util.Colors; -public class ArmourFeature & PonyModel> extends AbstractPonyFeature { - public ArmourFeature(PonyRenderContext context, BakedModelManager bakery) { +public class ArmourFeature & PonyModel> extends AbstractPonyFeature { + public ArmourFeature(PonyRenderContext context, BakedModelManager bakery) { super(context); } @Override - public void render(MatrixStack matrices, VertexConsumerProvider provider, int light, T entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) { - renderArmor(getModelWrapper(), matrices, provider, light, entity, limbDistance, limbAngle, age, headYaw, headPitch); + public void render(MatrixStack matrices, VertexConsumerProvider provider, int light, S entity, float limbDistance, float limbAngle) { + renderArmor(getModelWrapper(), matrices, provider, light, entity, limbDistance, limbAngle); } - public static > void renderArmor( - Models> pony, MatrixStack matrices, - VertexConsumerProvider provider, int light, T entity, + 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(); @@ -44,9 +45,9 @@ public class ArmourFeature & Po } } - private static > void renderArmor( - Models> pony, MatrixStack matrices, - VertexConsumerProvider provider, int light, T entity, + private static > void renderArmor( + Models> pony, MatrixStack matrices, + VertexConsumerProvider provider, int light, S entity, float limbDistance, float limbAngle, float age, float headYaw, float headPitch, EquipmentSlot armorSlot, ArmourLayer layer, ArmourRendererPlugin plugin) { diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/DJPon3Feature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/DJPon3Feature.java index c1a1ecd2..5fee5d70 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/DJPon3Feature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/feature/DJPon3Feature.java @@ -13,23 +13,28 @@ import com.minelittlepony.api.model.BodyPart; import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.client.model.DJPon3EarsModel; import com.minelittlepony.client.render.PonyRenderContext; +import com.minelittlepony.client.render.entity.state.PonyRenderState; -public class DJPon3Feature & PonyModel> extends AbstractPonyFeature { +public class DJPon3Feature< + T extends AbstractClientPlayerEntity, + S extends PonyRenderState, + M extends EntityModel & PonyModel + > extends AbstractPonyFeature { private final DJPon3EarsModel deadMau5 = ModelType.DJ_PON_3.createModel(); - public DJPon3Feature(PonyRenderContext context) { + public DJPon3Feature(PonyRenderContext context) { super(context); } @Override - public void render(MatrixStack stack, VertexConsumerProvider renderContext, int light, T entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) { - if ("deadmau5".equals(entity.getName().getString())) { + public void render(MatrixStack stack, VertexConsumerProvider renderContext, int light, S state, float limbAngle, float limbDistance) { + if ("deadmau5".equals(state.name)) { stack.push(); M body = getModelWrapper().body(); - body.transform(BodyPart.HEAD, stack); + body.transform(state, BodyPart.HEAD, stack); body.getHead().rotate(stack); stack.scale(1.3333334F, 1.3333334F, 1.3333334F); @@ -37,7 +42,7 @@ public class DJPon3Feature & PonyModel> extends AbstractPonyFeature { +public class ElytraFeature< + T extends LivingEntity, + S extends PonyRenderState, + M extends EntityModel & PonyModel + > extends AbstractPonyFeature { private static final Identifier TEXTURE = Identifier.ofVanilla("textures/entity/elytra.png"); private final PonyElytra model = ModelType.ELYTRA.createModel(); - public ElytraFeature(PonyRenderContext context) { + public ElytraFeature(PonyRenderContext context) { super(context); } @Override - public void render(MatrixStack matrices, VertexConsumerProvider provider, int light, T entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) { + public void render(MatrixStack matrices, VertexConsumerProvider provider, int light, S entity, float limbAngle, float limbDistance) { ArmourRendererPlugin plugin = ArmourRendererPlugin.INSTANCE.get(); for (ItemStack stack : plugin.getArmorStacks(entity, EquipmentSlot.CHEST, ArmourLayer.OUTER, ArmourRendererPlugin.ArmourType.ELYTRA)) { @@ -50,9 +56,7 @@ public class ElytraFeature & Po matrices.push(); preRenderCallback(matrices); - getContextModel().copyStateTo(model); - model.isSneaking = PonyPosture.isCrouching(getContext().getEntityPony(entity), entity); - model.setAngles(entity, limbDistance, limbAngle, age, headYaw, headPitch); + model.setAngles(entity); model.render(matrices, vertexConsumer, light, OverlayTexture.DEFAULT_UV, (Colors.WHITE & 0xFFFFFF) | (int)(alpha * 255) << 24); matrices.pop(); @@ -61,10 +65,10 @@ public class ElytraFeature & Po plugin.onArmourRendered(entity, matrices, provider, EquipmentSlot.BODY, ArmourLayer.OUTER, ArmourRendererPlugin.ArmourType.ELYTRA); } - protected void preRenderCallback(MatrixStack stack) { + protected void preRenderCallback(S state, MatrixStack stack) { M body = getModelWrapper().body(); - stack.translate(0, body.getRiderYOffset(), 0.125); - body.transform(BodyPart.BODY, stack); + stack.translate(0, state.riderOffset, 0.125); + body.transform(state, BodyPart.BODY, stack); } protected Identifier getElytraTexture(T entity) { 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 d12e48b7..7a4812e5 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,6 +5,7 @@ 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; @@ -24,12 +25,17 @@ 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.PonyRenderContext; +import com.minelittlepony.client.render.entity.state.PonyRenderState; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; -public class GearFeature & PonyModel> extends AbstractPonyFeature { +public class GearFeature< + T extends LivingEntity, + S extends PonyRenderState, + M extends EntityModel & PonyModel + > extends AbstractPonyFeature { private final List gears = Streams.concat( ModelType.getWearables().map(e -> new Entry(e.getValue().createModel(), e.getKey())), @@ -50,13 +56,13 @@ public class GearFeature & Pony return randomizedOrder; })); - public GearFeature(PonyRenderContext renderer) { + public GearFeature(PonyRenderContext renderer) { super(renderer); } @Override - public void render(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, T entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) { - if (entity.isInvisible()) { + public void render(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, S entity, float limbAngle, float limbDistance) { + if (entity.invisible) { return; } @@ -89,7 +95,7 @@ public class GearFeature & Pony renderStackingOffsets.put(part, v + gear.getStackingHeight()); } - renderGear(model, entity, gear, stack, renderContext, lightUv, limbDistance, limbAngle, tickDelta); + renderGear(model, entity, gear, stack, renderContext, lightUv, limbDistance, limbAngle, entity.age); stack.pop(); } } diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/GlowingEyesFeature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/GlowingEyesFeature.java index 567f4d5d..7fa3640a 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/GlowingEyesFeature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/feature/GlowingEyesFeature.java @@ -4,17 +4,22 @@ import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.entity.feature.EyesFeatureRenderer; import net.minecraft.client.render.entity.feature.FeatureRendererContext; import net.minecraft.client.render.entity.model.EntityModel; -import net.minecraft.entity.LivingEntity; +import net.minecraft.client.render.entity.state.PlayerEntityRenderState; import net.minecraft.util.Identifier; import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.client.render.PonyRenderContext; +import com.minelittlepony.client.render.entity.state.PonyRenderState; -public class GlowingEyesFeature & PonyModel> extends EyesFeatureRenderer { +public class GlowingEyesFeature< + S extends PonyRenderState, + M extends EntityModel & PonyModel + > extends EyesFeatureRenderer { private final RenderLayer layer; - public & PonyRenderContext & IGlowingRenderer> GlowingEyesFeature(V renderer) { + @SuppressWarnings({"rawtypes", "unchecked"}) + public & IGlowingRenderer> GlowingEyesFeature(V renderer) { super(renderer); layer = RenderLayer.getEyes(renderer.getEyeTexture()); } diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/HeldItemFeature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/HeldItemFeature.java index 4a5c8179..44fcf34a 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/HeldItemFeature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/feature/HeldItemFeature.java @@ -1,62 +1,53 @@ package com.minelittlepony.client.render.entity.feature; -import com.minelittlepony.api.model.BodyPart; -import com.minelittlepony.api.model.PonyModel; +import com.minelittlepony.api.model.*; import com.minelittlepony.client.render.PonyRenderContext; +import com.minelittlepony.client.render.entity.state.PonyRenderState; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.feature.FeatureRendererContext; import net.minecraft.client.render.entity.feature.HeldItemFeatureRenderer; import net.minecraft.client.render.entity.model.EntityModel; -import net.minecraft.client.render.entity.model.ModelWithArms; -import net.minecraft.client.render.item.HeldItemRenderer; -import net.minecraft.client.render.model.json.ModelTransformationMode; +import net.minecraft.client.render.entity.state.PlayerEntityRenderState; +import net.minecraft.client.render.item.ItemRenderer; import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.LivingEntity; import net.minecraft.item.ItemStack; +import net.minecraft.item.ModelTransformationMode; import net.minecraft.util.Arm; -public class HeldItemFeature & PonyModel & ModelWithArms> extends HeldItemFeatureRenderer { +@SuppressWarnings(value = {"unchecked"}) +public class HeldItemFeature< + S extends PonyRenderState, + M extends EntityModel & PonyModel + > extends HeldItemFeatureRenderer { - private final PonyRenderContext context; + private final PonyRenderContext context; - @SuppressWarnings("unchecked") - public HeldItemFeature(PonyRenderContext context, HeldItemRenderer renderer) { - super((FeatureRendererContext)context, renderer); + public HeldItemFeature(PonyRenderContext context, ItemRenderer renderer) { + super((FeatureRendererContext)context, renderer); this.context = context; } - protected ItemStack getLeftItem(T entity) { - boolean main = entity.getMainArm() == Arm.LEFT; + public void render(MatrixStack matrices, VertexConsumerProvider vertices, int light, S state, float limbAngle, float limbDistance) { + if (!state.leftHandStack.isEmpty() || !state.rightHandStack.isEmpty()) { + M model = context.getInternalRenderer().getModels().body(); - return main ? entity.getMainHandStack() : entity.getOffHandStack(); - } + matrices.push(); + model.transform(state, BodyPart.LEGS, matrices); - protected ItemStack getRightItem(T entity) { - boolean main = entity.getMainArm() == Arm.RIGHT; + ModelAttributes attributes = ((PonyModel.AttributedHolder)state).getAttributes(); - return main ? entity.getMainHandStack() : entity.getOffHandStack(); + attributes.heldStack = state.rightHandStack; + renderItem(state, state.rightHandItemModel, state.rightHandStack, ModelTransformationMode.THIRD_PERSON_RIGHT_HAND, Arm.RIGHT, matrices, vertices, light); + attributes.heldStack = state.leftHandStack; + renderItem(state, state.leftHandItemModel, state.leftHandStack, ModelTransformationMode.THIRD_PERSON_LEFT_HAND, Arm.LEFT, matrices, vertices, light); + attributes.heldStack = ItemStack.EMPTY; + matrices.pop(); + } } @Override - public void render(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, T entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) { - - ItemStack left = getLeftItem(entity); - ItemStack right = getRightItem(entity); - - if (!left.isEmpty() || !right.isEmpty()) { - M model = context.getInternalRenderer().getModels().body(); - - stack.push(); - - model.transform(BodyPart.LEGS, stack); - - model.getAttributes().heldStack = right; - renderItem(entity, right, ModelTransformationMode.THIRD_PERSON_RIGHT_HAND, Arm.RIGHT, stack, renderContext, lightUv); - model.getAttributes().heldStack = left; - renderItem(entity, left, ModelTransformationMode.THIRD_PERSON_LEFT_HAND, Arm.LEFT, stack, renderContext, lightUv); - model.getAttributes().heldStack = ItemStack.EMPTY; - stack.pop(); - } + public final void render(MatrixStack matrices, VertexConsumerProvider vertices, int light, PlayerEntityRenderState state, float limbAngle, float limbDistance) { + render(matrices, vertices, light, (S)state, limbAngle, limbDistance); } } diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/IllagerHeldItemFeature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/IllagerHeldItemFeature.java deleted file mode 100644 index 98ddad3a..00000000 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/IllagerHeldItemFeature.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.minelittlepony.client.render.entity.feature; - -import net.minecraft.client.render.VertexConsumerProvider; -import net.minecraft.client.render.item.HeldItemRenderer; -import net.minecraft.client.util.math.MatrixStack; -import net.minecraft.entity.mob.IllagerEntity; - -import com.minelittlepony.client.model.entity.race.AlicornModel; -import com.minelittlepony.client.render.PonyRenderContext; - -public class IllagerHeldItemFeature> extends HeldItemFeature { - - public IllagerHeldItemFeature(PonyRenderContext livingPony, HeldItemRenderer renderer) { - super(livingPony, renderer); - } - - @Override - public void render(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, T entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) { - if (shouldRender(entity)) { - super.render(stack, renderContext, lightUv, entity, limbDistance, limbAngle, tickDelta, age, headYaw, headPitch); - } - } - - public boolean shouldRender(T entity) { - return entity.getState() != IllagerEntity.State.CROSSED; - } -} diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/PassengerFeature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/PassengerFeature.java index ea65138a..4565de8a 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/PassengerFeature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/feature/PassengerFeature.java @@ -1,64 +1,73 @@ package com.minelittlepony.client.render.entity.feature; import net.minecraft.client.render.OverlayTexture; -import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.EntityRendererFactory; import net.minecraft.client.render.entity.ParrotEntityRenderer; import net.minecraft.client.render.entity.model.EntityModelLayers; import net.minecraft.client.render.entity.model.ParrotEntityModel; +import net.minecraft.client.render.entity.state.ParrotEntityRenderState; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.math.RotationAxis; -import net.minecraft.entity.EntityType; import net.minecraft.entity.passive.ParrotEntity; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.nbt.NbtCompound; -import net.minecraft.util.Identifier; import com.minelittlepony.api.model.BodyPart; import com.minelittlepony.client.model.ClientPonyModel; import com.minelittlepony.client.render.PonyRenderContext; +import com.minelittlepony.client.render.entity.state.PonyRenderState; -import java.util.Optional; - -public class PassengerFeature> extends AbstractPonyFeature { +public class PassengerFeature< + T extends PlayerEntity, + S extends PonyRenderState, + M extends ClientPonyModel + > extends AbstractPonyFeature { private final ParrotEntityModel model; + private final ParrotEntityRenderState parrotState = new ParrotEntityRenderState(); - public PassengerFeature(PonyRenderContext renderer, EntityRendererFactory.Context context) { + public PassengerFeature(PonyRenderContext renderer, EntityRendererFactory.Context context) { super(renderer); model = new ParrotEntityModel(context.getPart(EntityModelLayers.PARROT)); + parrotState.parrotPose = ParrotEntityModel.Pose.ON_SHOULDER; } + @Override - public void render(MatrixStack stack, VertexConsumerProvider renderContext, int light, T entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) { - getShoulderParrot(entity.getShoulderEntityLeft()).ifPresent(texture -> { - renderShoulderParrot(stack, renderContext, light, entity, limbDistance, limbAngle, headYaw, headPitch, texture, 1); - }); - getShoulderParrot(entity.getShoulderEntityRight()).ifPresent(texture -> { - renderShoulderParrot(stack, renderContext, light, entity, limbDistance, limbAngle, headYaw, headPitch, texture, -1); - }); + public void render(MatrixStack matrices, VertexConsumerProvider vertices, int light, S state, float limbAngle, float limbDistance) { + if (state.leftShoulderParrotVariant != null) { + render(matrices, vertices, light, state, state.leftShoulderParrotVariant, limbAngle, limbDistance, true); + } + + if (state.rightShoulderParrotVariant != null) { + render(matrices, vertices, light, state, state.rightShoulderParrotVariant, limbAngle, limbDistance, false); + } } - private Optional getShoulderParrot(NbtCompound tag) { - return EntityType.get(tag.getString("id")) - .filter(p -> p == EntityType.PARROT) - .map(type -> ParrotEntityRenderer.getTexture(ParrotEntity.Variant.byIndex(tag.getInt("Variant")))); - } - - private void renderShoulderParrot(MatrixStack stack, VertexConsumerProvider renderContext, int light, T entity, float limbDistance, float limbAngle, float headYaw, float headPitch, Identifier texture, int sigma) { - stack.push(); - - getContextModel().transform(BodyPart.BODY, stack); - - stack.translate( - sigma * 0.25, - entity.isInSneakingPose() ? -0.9 : -1.2, - 0.45); - stack.multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(sigma * -5)); - - VertexConsumer buffer = renderContext.getBuffer(model.getLayer(texture)); - model.poseOnShoulder(stack, buffer, light, OverlayTexture.DEFAULT_UV, limbDistance, limbAngle, headYaw, headPitch, entity.age); - stack.pop(); + private void render( + MatrixStack matrices, + VertexConsumerProvider vertexConsumers, + int light, + S state, + ParrotEntity.Variant parrotVariant, + float headYaw, + float headPitch, + boolean left + ) { + matrices.push(); + getContextModel().transform(state, BodyPart.BACK, matrices); + matrices.translate( + left ? 0.25F : -0.25F, + state.isInSneakingPose ? -1.3F : -1.5F, 0.0F + ); + matrices.multiply(RotationAxis.NEGATIVE_Z.rotationDegrees(left ? -5 : 5)); + parrotState.age = state.age; + parrotState.limbFrequency = state.limbFrequency; + parrotState.limbAmplitudeMultiplier = state.limbAmplitudeMultiplier; + parrotState.yawDegrees = headYaw; + parrotState.pitch = headPitch; + model.setAngles(parrotState); + model.render(matrices, vertexConsumers.getBuffer(model.getLayer(ParrotEntityRenderer.getTexture(parrotVariant))), light, OverlayTexture.DEFAULT_UV); + matrices.pop(); } } diff --git a/src/main/java/com/minelittlepony/client/render/entity/feature/SkullFeature.java b/src/main/java/com/minelittlepony/client/render/entity/feature/SkullFeature.java index fa98f7c3..3fbb53cd 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/feature/SkullFeature.java +++ b/src/main/java/com/minelittlepony/client/render/entity/feature/SkullFeature.java @@ -6,37 +6,38 @@ import com.minelittlepony.client.model.armour.ArmourLayer; import com.minelittlepony.client.model.armour.ArmourRendererPlugin; import com.minelittlepony.client.render.PonyRenderContext; import com.minelittlepony.client.render.blockentity.skull.PonySkullRenderer; +import com.minelittlepony.client.render.entity.state.PonyRenderState; import net.minecraft.block.AbstractSkullBlock; import net.minecraft.client.render.*; import net.minecraft.client.render.entity.feature.HeadFeatureRenderer; import net.minecraft.client.render.entity.model.EntityModel; import net.minecraft.client.render.entity.model.EntityModelLoader; +import net.minecraft.client.render.entity.state.BipedEntityRenderState; 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.entity.EquipmentSlot; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.mob.ZombieVillagerEntity; import net.minecraft.entity.passive.VillagerEntity; -import net.minecraft.item.ArmorItem; -import net.minecraft.item.BlockItem; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; +import net.minecraft.item.*; -public class SkullFeature & PonyModel> extends AbstractPonyFeature { +public class SkullFeature< + T extends LivingEntity, + S extends PonyRenderState, + M extends EntityModel & PonyModel> extends AbstractPonyFeature { private final ItemRenderer itemRenderer; - public SkullFeature(PonyRenderContext renderPony, EntityModelLoader entityModelLoader, ItemRenderer itemRenderer) { + public SkullFeature(PonyRenderContext renderPony, EntityModelLoader entityModelLoader, ItemRenderer itemRenderer) { super(renderPony); this.itemRenderer = itemRenderer; } @Override - public void render(MatrixStack matrices, VertexConsumerProvider provider, int light, T entity, float limbDistance, float limbAngle, float tickDelta, float age, float headYaw, float headPitch) { + public void render(MatrixStack matrices, VertexConsumerProvider provider, int light, S state, float limbAngle, float limbDistance) { ArmourRendererPlugin plugin = ArmourRendererPlugin.INSTANCE.get(); - for (ItemStack stack : plugin.getArmorStacks(entity, EquipmentSlot.HEAD, ArmourLayer.OUTER, ArmourRendererPlugin.ArmourType.SKULL)) { + for (ItemStack stack : plugin.getArmorStacks(state, EquipmentSlot.HEAD, ArmourLayer.OUTER, ArmourRendererPlugin.ArmourType.SKULL)) { if (stack.isEmpty()) { continue; } @@ -46,16 +47,16 @@ public class SkullFeature & Pon matrices.push(); - if (entity.isBaby() && !(entity instanceof VillagerEntity)) { + if (state.baby && !(state instanceof VillagerEntity)) { matrices.translate(0, 0.03125F, 0); matrices.scale(0.7F, 0.7F, 0.7F); matrices.translate(0, 1, 0); } - model.transform(BodyPart.HEAD, matrices); + model.transform(state, BodyPart.HEAD, matrices); model.getHead().rotate(matrices); - boolean isVillager = entity instanceof VillagerEntity || entity instanceof ZombieVillagerEntity; + boolean isVillager = state instanceof VillagerEntity || state instanceof ZombieVillagerEntity; float f = 1.1F; matrices.scale(f, f, f); @@ -65,16 +66,16 @@ public class SkullFeature & Pon matrices.scale(n, -n, -n); matrices.translate(0, -0.1F, 0.1F); matrices.translate(-0.5, 0, -0.5); - PonySkullRenderer.INSTANCE.renderSkull(matrices, provider, stack, entity, tickDelta, light, true); + PonySkullRenderer.INSTANCE.renderSkull(matrices, provider, stack, state, state.age, light, true); } else if (!(item instanceof ArmorItem a) || a.getSlotType() != EquipmentSlot.HEAD) { matrices.translate(0, 0.1F, -0.1F); HeadFeatureRenderer.translate(matrices, isVillager); - itemRenderer.renderItem(entity, stack, ModelTransformationMode.HEAD, false, matrices, provider, entity.getWorld(), light, OverlayTexture.DEFAULT_UV, entity.getId() + ModelTransformationMode.HEAD.ordinal()); + itemRenderer.renderItem(state, stack, ModelTransformationMode.HEAD, false, matrices, provider, entity.getWorld(), light, OverlayTexture.DEFAULT_UV, entity.getId() + ModelTransformationMode.HEAD.ordinal()); } matrices.pop(); } - plugin.onArmourRendered(entity, matrices, provider, EquipmentSlot.BODY, ArmourLayer.OUTER, ArmourRendererPlugin.ArmourType.SKULL); + plugin.onArmourRendered(state, matrices, provider, EquipmentSlot.BODY, ArmourLayer.OUTER, ArmourRendererPlugin.ArmourType.SKULL); } } 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 9339764d..a2a1b121 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 @@ -14,12 +14,16 @@ 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 extends PonyRenderer> { - private final NpcClothingFeature, AbstractNpcRenderer> clothing; - private final Function>> models = Util.memoize(race -> { +abstract class AbstractNpcRenderer< + T extends MobEntity & VillagerDataContainer, + S extends PonyRenderState + > extends PonyRenderer> { + private final NpcClothingFeature, AbstractNpcRenderer> clothing; + private final Function>> models = Util.memoize(race -> { if (race.isHuman()) { race = Race.EARTH; } @@ -34,7 +38,7 @@ abstract class AbstractNpcRenderer } @Override - public boolean shouldRender(ClientPonyModel model, T entity, Wearable wearable, Gear gear) { + 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 && ( @@ -52,12 +56,12 @@ abstract class AbstractNpcRenderer return super.shouldRender(model, entity, wearable, gear); } - protected void initializeModel(ClientPonyModel model) { + protected void initializeModel(ClientPonyModel model) { } @Override - public Identifier getDefaultTexture(T villager, Wearable wearable) { + public Identifier getDefaultTexture(S villager, Wearable wearable) { if (wearable.isSaddlebags()) { return clothing.createTexture(villager, "accessory"); } 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 7f7be0b5..b5f0b2ab 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 @@ -19,6 +19,7 @@ import com.minelittlepony.api.model.PonyModel; import com.minelittlepony.client.MineLittlePony; 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.util.render.TextureFlattener; import com.minelittlepony.util.ResourceUtil; @@ -26,8 +27,9 @@ import java.util.*; class NpcClothingFeature< T extends LivingEntity & VillagerDataContainer, - M extends EntityModel & PonyModel, - C extends FeatureRendererContext & PonyRenderContext> extends AbstractPonyFeature { + S extends PonyRenderState, + M extends EntityModel & PonyModel, + C extends FeatureRendererContext & PonyRenderContext> extends AbstractPonyFeature { private static final Int2ObjectMap LEVEL_TO_ID = Util.make(new Int2ObjectOpenHashMap<>(), a -> { a.put(1, Identifier.ofVanilla("stone")); @@ -46,22 +48,22 @@ class NpcClothingFeature< } @Override - public void render(MatrixStack matrixStack, VertexConsumerProvider provider, int i, T entity, float f, float g, float h, float j, float k, float l) { - if (entity.isInvisible()) { + public void render(MatrixStack matrixStack, VertexConsumerProvider provider, int light, S entity, float limbAngle, float limbDistance) { + if (entity.invisible) { return; } VillagerData data = entity.getVillagerData(); M entityModel = getContextModel(); - if (entity.isBaby() || data.getProfession() == VillagerProfession.NONE) { + if (entity.baby || data.getProfession() == VillagerProfession.NONE) { Identifier typeSkin = createTexture("type", Registries.VILLAGER_TYPE.getId(data.getType())); if (!ResourceUtil.textureExists(typeSkin)) { typeSkin = createTexture("type", Registries.VILLAGER_TYPE.getId(VillagerType.PLAINS)); } - renderModel(entityModel, typeSkin, matrixStack, provider, i, entity, Colors.WHITE); + renderModel(entityModel, typeSkin, matrixStack, provider, light, entity, Colors.WHITE); } else { - renderModel(entityModel, getMergedTexture(data), matrixStack, provider, i, entity, Colors.WHITE); + renderModel(entityModel, getMergedTexture(data), matrixStack, provider, light, entity, Colors.WHITE); } } 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 index a25072a9..10dd0756 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/npc/PillagerRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/npc/PillagerRenderer.java @@ -1,18 +1,28 @@ 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.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.client.render.PonyRenderContext; import com.minelittlepony.client.render.entity.PonyRenderer; import com.minelittlepony.client.render.entity.feature.HeldItemFeature; -public class PillagerRenderer extends PonyRenderer> { +public class PillagerRenderer extends PonyRenderer { private static final Identifier TEXTURE = MineLittlePony.id("textures/entity/illager/pillager_pony.png"); public PillagerRenderer(EntityRendererFactory.Context context) { @@ -20,7 +30,43 @@ public class PillagerRenderer extends PonyRenderer> createHeldItemFeature(EntityRendererFactory.Context context) { - return new IllagerHeldItemFeature<>(this, context.getHeldItemRenderer()); + 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/TraderRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/npc/TraderRenderer.java index 99ebcaa2..af741842 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/npc/TraderRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/npc/TraderRenderer.java @@ -9,11 +9,17 @@ import com.minelittlepony.client.model.ModelType; import com.minelittlepony.client.model.entity.race.AlicornModel; import com.minelittlepony.client.render.entity.PonyRenderer; import com.minelittlepony.client.render.entity.npc.textures.TextureSupplier; +import com.minelittlepony.client.render.entity.state.PonyRenderState; -public class TraderRenderer extends PonyRenderer> { +public class TraderRenderer extends PonyRenderer> { public static final Identifier TEXTURE = MineLittlePony.id("textures/entity/wandering_trader_pony.png"); public TraderRenderer(EntityRendererFactory.Context context) { super(context, ModelType.ALICORN.getKey(false), TextureSupplier.of(TEXTURE), BASE_MODEL_SCALE); } + + @Override + public PonyRenderState createRenderState() { + return new PonyRenderState(); + } } 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 new file mode 100644 index 00000000..3841e64d --- /dev/null +++ b/src/main/java/com/minelittlepony/client/render/entity/state/PlayerPonyRenderState.java @@ -0,0 +1,31 @@ +package com.minelittlepony.client.render.entity.state; + +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.pony.Pony; +import com.minelittlepony.api.pony.SkinsProxy; +import com.minelittlepony.api.pony.meta.Wearable; + +import java.util.HashMap; +import java.util.Map; + +public class PlayerPonyRenderState extends PonyRenderState { + public final Map wearabledTextures = new HashMap<>(); + + @Override + public void updateState(LivingEntity entity, PonyModel model, Pony pony, ModelAttributes.Mode mode) { + super.updateState(entity, model, pony, mode); + wearabledTextures.clear(); + for (Wearable wearable : Wearable.REGISTRY.values()) { + if (isWearing(wearable)) { + SkinsProxy.getInstance().getSkin(wearable.getId(), (PlayerEntity)entity).ifPresent(skin -> { + wearabledTextures.put(wearable, skin); + }); + } + } + } +} 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 new file mode 100644 index 00000000..095ce234 --- /dev/null +++ b/src/main/java/com/minelittlepony/client/render/entity/state/PonyRenderState.java @@ -0,0 +1,146 @@ +package com.minelittlepony.client.render.entity.state; + +import net.minecraft.block.BedBlock; +import net.minecraft.client.render.entity.state.PlayerEntityRenderState; +import net.minecraft.entity.EntityPose; +import net.minecraft.entity.LivingEntity; +import net.minecraft.util.math.MathHelper; + +import com.minelittlepony.api.config.PonyConfig; +import com.minelittlepony.api.events.PonyModelPrepareCallback; +import com.minelittlepony.api.model.ModelAttributes; +import com.minelittlepony.api.model.PonyModel; +import com.minelittlepony.api.pony.Pony; +import com.minelittlepony.api.pony.meta.*; + +public class PonyRenderState extends PlayerEntityRenderState implements PonyModel.AttributedHolder { + public final ModelAttributes attributes = new ModelAttributes(); + + public float vehicleOffset; + public float riderOffset; + public float nameplateYOffset; + public float legOutset; + public boolean smallArms; + public boolean sleepingInBed; + public boolean submergedInWater; + public boolean onGround; + + public Pony pony; + + public void updateState(LivingEntity entity, PonyModel model, Pony pony, ModelAttributes.Mode mode) { + 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); + legOutset = getLegOutset(); + isInSneakingPose = attributes.isCrouching && !attributes.isLyingDown; + sleepingInBed = entity.getSleepingPosition().isPresent() && entity.getEntityWorld().getBlockState(entity.getSleepingPosition().get()).getBlock() instanceof BedBlock; + submergedInWater = entity.isSubmergedInWater(); + if (attributes.isSitting) { + pose = EntityPose.SITTING; + } + + PonyModelPrepareCallback.EVENT.invoker().onPonyModelPrepared(attributes, model, ModelAttributes.Mode.OTHER); + } + + /** + * Gets the active scaling profile used to lay out this model's parts. + */ + public Size getSize() { + return baby ? SizePreset.FOAL : PonyConfig.getEffectiveSize(attributes.metadata.size()); + } + + public Race getRace() { + return PonyConfig.getEffectiveRace(attributes.metadata.race()); + } + + public final float getScaleFactor() { + return getSize().scaleFactor(); + } + + public final float getShadowSize() { + return getSize().shadowSize(); + } + + /** + * Gets the current leg swing amount. + */ + public float getSwingAmount() { + return this.handSwingProgress; + } + + /** + * Gets the step wobble used for various hair bits and animations. + */ + public float getWobbleAmount() { + if (getSwingAmount() <= 0) { + return 0; + } + + return MathHelper.sin(MathHelper.sqrt(getSwingAmount()) * MathHelper.PI * 2) * 0.04F; + } + + protected float getLegOutset() { + + float outset = attributes.isLyingDown ? 3.6F : attributes.isCrouching ? 1 : 5; + + if (smallArms) { + return Math.max(1, outset - 1); + } + return outset; + } + + /** + * Gets the y-offset applied to entities riding this one. + */ + protected float getRiderYOffset() { + switch ((SizePreset)getSize()) { + case NORMAL: return 0.4F; + case FOAL: + case TALL: + case BULKY: + default: return 0.25F; + } + } + + /** + * Tests if this model is wearing the given piece of gear. + */ + public boolean isWearing(Wearable wearable) { + return isEmbedded(wearable) || attributes.featureSkins.contains(wearable.getId()); + } + + /** + * Tests if the chosen piece of gear is sourcing its texture from the main skin. + * i.e. Used to change wing rendering when using saddlebags. + */ + public boolean isEmbedded(Wearable wearable) { + return attributes.metadata.gear().matches(wearable); + } + + private float getNamePlateYOffset(LivingEntity entity) { + // We start by negating the height calculation done by mahjong. + float y = -(height + 0.5F); + + // Then we add our own offsets. + y += attributes.visualHeight * getScaleFactor() + 0.25F; + y += vehicleOffset; + + if (isInSneakingPose) { + y -= 0.25F; + } + + if (isInPose(EntityPose.SLEEPING)) { + y /= 2; + } + + return y; + } + + @Override + public ModelAttributes getAttributes() { + return attributes; + } +} 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 new file mode 100644 index 00000000..ba4b06f9 --- /dev/null +++ b/src/main/java/com/minelittlepony/client/render/entity/state/SkeletonPonyRenderState.java @@ -0,0 +1,34 @@ +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 e7ecd2a7..16cb8278 100644 --- a/src/main/java/com/minelittlepony/client/transform/PonyPosture.java +++ b/src/main/java/com/minelittlepony/client/transform/PonyPosture.java @@ -50,7 +50,7 @@ public interface PonyPosture { // this reverts the rotations done in PlayerEntityRenderer#setupTransforms if (player instanceof PlayerEntity) { float leaningPitch = player.getLeaningPitch(tickDelta); - if (player.isFallFlying()) { + if (player.isGliding()) { if (RenderPass.getCurrent() == RenderPass.GUI) { Vec3d vec3d = player.getRotationVec(tickDelta); @@ -64,7 +64,7 @@ public interface PonyPosture { } } - float roll = (float)player.getFallFlyingTicks() + tickDelta; + 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()))); diff --git a/src/main/java/com/minelittlepony/client/util/render/NativeUtil.java b/src/main/java/com/minelittlepony/client/util/render/NativeUtil.java index 5ec669e4..551f9ae5 100644 --- a/src/main/java/com/minelittlepony/client/util/render/NativeUtil.java +++ b/src/main/java/com/minelittlepony/client/util/render/NativeUtil.java @@ -107,7 +107,7 @@ public class NativeUtil { if (loadedTexture instanceof NativeImageBackedTexture nibt) { NativeImage image = nibt.getImage(); if (image != null) { - consumer.accept(image::getColor); + consumer.accept(image::getColorArgb); return; } } @@ -115,7 +115,7 @@ public class NativeUtil { Resource res = mc.getResourceManager().getResource(resource).orElse(null); if (res != null) { try (InputStream inputStream = res.getInputStream()){ - consumer.accept(NativeImage.read(inputStream)::getColor); + consumer.accept(NativeImage.read(inputStream)::getColorArgb); return; } } @@ -128,10 +128,9 @@ public class NativeUtil { private static void __reconstructNativeImage(Identifier resource, Consumer consumer, Consumer fail, int attempt) { MinecraftClient mc = MinecraftClient.getInstance(); - TextureManager textures = mc.getTextureManager(); // recreate NativeImage from the GL matrix - textures.bindTexture(resource); + RenderSystem.setShaderTexture(GL_TEXTURE_2D, resource); // TODO: This returns values that are too specific. // Can we change the level (0) here to something @@ -158,7 +157,7 @@ public class NativeUtil { // This allocates a new array to store the image every time. // Don't do this every time. Keep a cache and store it so we don't destroy memory. image.loadFromTextureImage(0, false); - consumer.accept(image::getColor); + consumer.accept(image::getColorArgb); } } } diff --git a/src/main/java/com/minelittlepony/client/util/render/TextureFlattener.java b/src/main/java/com/minelittlepony/client/util/render/TextureFlattener.java index 44c5556d..59ec0cd6 100644 --- a/src/main/java/com/minelittlepony/client/util/render/TextureFlattener.java +++ b/src/main/java/com/minelittlepony/client/util/render/TextureFlattener.java @@ -51,9 +51,9 @@ public class TextureFlattener { } public static void copy(NativeImage from, NativeImage to, int x, int y) { - int color = from.getColor(x, y); - if (ColorHelper.Argb.getAlpha(color) > 0) { - to.setColor(x, y, color); + int color = from.getColorArgb(x, y); + if (ColorHelper.getAlpha(color) > 0) { + to.setColorArgb(x, y, color); } } }