WIP Updating to 1.21.3

This commit is contained in:
Sollace 2024-11-21 23:26:35 +00:00
parent 1464b3318a
commit f72fdaaebe
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
36 changed files with 262 additions and 295 deletions

View file

@ -12,4 +12,9 @@ public interface HornedPonyModel<T extends EntityRenderState & PonyModel.Attribu
return state instanceof PlayerEntityRenderState s return state instanceof PlayerEntityRenderState s
&& (getArmPoseForSide(s, Arm.LEFT) != ArmPose.EMPTY || getArmPoseForSide(s, Arm.RIGHT) != ArmPose.EMPTY); && (getArmPoseForSide(s, Arm.LEFT) != ArmPose.EMPTY || getArmPoseForSide(s, Arm.RIGHT) != ArmPose.EMPTY);
} }
@Override
default float getWobbleAmplitude(T state) {
return isCasting(state) ? 0 : 1;
}
} }

View file

@ -111,6 +111,11 @@ public class ModelAttributes {
*/ */
public float wingAngle; public float wingAngle;
/**
* Flag to indicate whether the wings are open or shut
*/
public boolean wingsSpread;
/** /**
* Contains a list of additional skins available for rendering. * Contains a list of additional skins available for rendering.
*/ */
@ -141,6 +146,7 @@ public class ModelAttributes {
motionLerp = MathUtil.clampLimit(zMotion * 30, 1); motionLerp = MathUtil.clampLimit(zMotion * 30, 1);
wingAngle = calcWingRotationFactor(ticks); wingAngle = calcWingRotationFactor(ticks);
wingsSpread = (isSwimming || isFlying || isCrouching) && (PonyConfig.getInstance().flappyElytras.get() || !isGliding);
} }
private float calcWingRotationFactor(float ticks) { private float calcWingRotationFactor(float ticks) {

View file

@ -17,6 +17,10 @@ public interface PonyModel<T extends EntityRenderState & PonyModel.AttributedHol
*/ */
void transform(T state, BodyPart part, MatrixStack stack); void transform(T state, BodyPart part, MatrixStack stack);
default float getWobbleAmplitude(T state) {
return 1;
}
public interface AttributedHolder { public interface AttributedHolder {
ModelAttributes getAttributes(); ModelAttributes getAttributes();

View file

@ -1,22 +1,21 @@
package com.minelittlepony.api.model; package com.minelittlepony.api.model;
import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.entity.state.BipedEntityRenderState; import net.minecraft.client.render.entity.state.EntityRenderState;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
public interface SubModel<T extends BipedEntityRenderState & PonyModel.AttributedHolder> { public interface SubModel<T extends EntityRenderState> {
/**
* Sets the model's various rotation angles.
*/
default void setPartAngles(T state, float limbAngle, float limbSpeed, float bodySwing, float animationProgress) {
}
/** /**
* Renders this model component. * Renders this model component.
*/ */
void renderPart(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color); void renderPart(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color);
/**
* Sets the model's various rotation angles.
*/
default void setPartAngles(T state, float wobbleAmount) {
}
/** /**
* Sets whether this part should be rendered. * Sets whether this part should be rendered.
*/ */

View file

@ -2,8 +2,6 @@ package com.minelittlepony.api.model;
import net.minecraft.client.render.entity.state.BipedEntityRenderState; 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; import com.minelittlepony.util.MathUtil;
public interface WingedPonyModel<T extends BipedEntityRenderState & PonyModel.AttributedHolder> extends PonyModel<T> { public interface WingedPonyModel<T extends BipedEntityRenderState & PonyModel.AttributedHolder> extends PonyModel<T> {
@ -20,14 +18,7 @@ public interface WingedPonyModel<T extends BipedEntityRenderState & PonyModel.At
* Returns true if the wings are spread. * Returns true if the wings are spread.
*/ */
default boolean wingsAreOpen(T state) { default boolean wingsAreOpen(T state) {
return (state.getAttributes().isSwimming || state.getAttributes().isFlying || state.getAttributes().isCrouching) return state.getAttributes().wingsSpread;
&& (PonyConfig.getInstance().flappyElytras.get() || !state.getAttributes().isGliding);
}
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 +26,7 @@ public interface WingedPonyModel<T extends BipedEntityRenderState & PonyModel.At
* *
* @param ticks Partial render ticks * @param ticks Partial render ticks
*/ */
default float getWingRotationFactor(T state, float ticks) { default float getWingRotationFactor(T state) {
return state.getAttributes().wingAngle; return state.getAttributes().wingAngle;
} }
} }

View file

@ -1,8 +1,9 @@
package com.minelittlepony.api.pony.meta; package com.minelittlepony.api.pony.meta;
import net.minecraft.util.math.ColorHelper;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import com.minelittlepony.common.util.Color;
import com.mojang.authlib.minecraft.MinecraftProfileTexture; import com.mojang.authlib.minecraft.MinecraftProfileTexture;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
@ -31,7 +32,7 @@ public interface Mats {
return 0; return 0;
} }
int[] color = raster.getPixel(x, y, new int[] {0, 0, 0, 0}); int[] color = raster.getPixel(x, y, new int[] {0, 0, 0, 0});
return Color.argbToHex(color[3], color[0], color[1], color[2]); return ColorHelper.getArgb(color[3], color[0], color[1], color[2]);
}; };
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
throw new IOException("Could not create mat from image", e); throw new IOException("Could not create mat from image", e);

View file

@ -5,8 +5,6 @@ import net.minecraft.util.math.ColorHelper;
import org.joml.Vector2i; import org.joml.Vector2i;
import com.minelittlepony.common.util.Color;
import java.util.*; import java.util.*;
/** /**
@ -41,7 +39,7 @@ public interface TriggerPixel<T> {
static TriggerPixel<Integer> ofColor(int x, int y) { static TriggerPixel<Integer> ofColor(int x, int y) {
MAX_COORDS.x = Math.max(MAX_COORDS.x, x); MAX_COORDS.x = Math.max(MAX_COORDS.x, x);
MAX_COORDS.y = Math.max(MAX_COORDS.y, y); MAX_COORDS.y = Math.max(MAX_COORDS.y, y);
return image -> Color.abgrToArgb(image.getColor(x, y)); return image -> image.getColor(x, y);
} }
static <T extends Enum<T> & TValue<T>> TriggerPixel<Flags<T>> ofFlags(int x, int y, Flags<T> def, T[] options) { static <T extends Enum<T> & TValue<T>> TriggerPixel<Flags<T>> ofFlags(int x, int y, Flags<T> def, T[] options) {

View file

@ -127,23 +127,18 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
} }
protected void setModelAngles(T entity) { 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; float pitch = entity.attributes.motionPitch * MathHelper.RADIANS_PER_DEGREE;
head.setAngles( head.setAngles(
MathHelper.clamp(entity.attributes.isSleeping ? 0.1f : headPitch / 57.29578F, -1.25f - pitch, 0.5f - pitch), MathHelper.clamp(entity.attributes.isSleeping ? 0.1f : entity.pitch / 57.29578F, -1.25f - pitch, 0.5f - pitch),
entity.attributes.isSleeping ? (Math.signum(MathHelper.wrapDegrees(headYaw)) * 1.3F) : headYaw * MathHelper.RADIANS_PER_DEGREE, entity.attributes.isSleeping ? (Math.signum(MathHelper.wrapDegrees(entity.yawDegrees)) * 1.3F) : entity.yawDegrees * MathHelper.RADIANS_PER_DEGREE,
0 0
); );
float wobbleAmount = entity.getWobbleAmount(); float wobbleAmount = entity.wobbleAmount * getWobbleAmplitude(entity);
body.yaw = wobbleAmount; body.yaw = wobbleAmount;
neck.yaw = wobbleAmount; neck.yaw = wobbleAmount;
rotateLegs(entity, limbAngle, limbSpeed, animationProgress); rotateLegs(entity);
ArmPose left = getArmPose(entity, Arm.LEFT); ArmPose left = getArmPose(entity, Arm.LEFT);
ArmPose right = getArmPose(entity, Arm.RIGHT); ArmPose right = getArmPose(entity, Arm.RIGHT);
@ -153,7 +148,8 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
} }
if (!entity.attributes.isSwimming && !entity.attributes.isGoingFast) { if (!entity.attributes.isSwimming && !entity.attributes.isGoingFast) {
holdItem(entity, limbSpeed, left, right); alignArmForAction(entity, getArm(Arm.LEFT), left, right, 1);
alignArmForAction(entity, getArm(Arm.RIGHT), right, left, -1);
} }
swingItem(entity); swingItem(entity);
@ -165,7 +161,7 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
adjustBody(entity, 0, ORIGIN); adjustBody(entity, 0, ORIGIN);
if (!entity.attributes.isLyingDown) { if (!entity.attributes.isLyingDown) {
animateBreathing(entity, animationProgress, left, right); animateBreathing(entity, left, right);
} }
if (entity.attributes.isSwimmingRotated) { if (entity.attributes.isSwimmingRotated) {
@ -184,7 +180,7 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
head.pitch = 0.5F; head.pitch = 0.5F;
} }
parts.forEach(part -> part.setPartAngles(entity, limbAngle, limbSpeed, wobbleAmount, animationProgress)); parts.forEach(part -> part.setPartAngles(entity, wobbleAmount));
} }
public void setHeadRotation(float animationProgress, float yaw, float pitch) { public void setHeadRotation(float animationProgress, float yaw, float pitch) {
@ -249,11 +245,11 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
* Takes the same parameters as {@link AbstractPonyModel.setRotationAndAngles} * Takes the same parameters as {@link AbstractPonyModel.setRotationAndAngles}
* *
*/ */
protected void rotateLegs(T state, float move, float swing, float ticks) { protected void rotateLegs(T state) {
if (state.attributes.isSwimming) { if (state.attributes.isSwimming) {
rotateLegsSwimming(state, move, swing, ticks); rotateLegsSwimming(state, state.limbAmplitudeInverse, state.limbAmplitudeMultiplier, state.age);
} else { } else {
rotateLegsOnGround(state, move, swing, ticks); rotateLegsOnGround(state, state.limbAmplitudeInverse, state.limbAmplitudeMultiplier, state.age);
} }
float sin = MathHelper.sin(body.yaw) * 5; float sin = MathHelper.sin(body.yaw) * 5;
@ -327,14 +323,6 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
rightLeg.setAngles(MathHelper.lerp(rainboomLegLotation, MathHelper.cos(baseRotation + angle / 5) * scale, MathUtil.Angles._90_DEG * rainboomLegLotation), -yAngle, rightLeg.roll); rightLeg.setAngles(MathHelper.lerp(rainboomLegLotation, MathHelper.cos(baseRotation + angle / 5) * scale, MathUtil.Angles._90_DEG * rainboomLegLotation), -yAngle, rightLeg.roll);
} }
/**
* Adjusts legs as if holding an item. Delegates to the correct arm/leg/limb as necessary.
*/
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 @Override
public ModelPart getBodyPart(BodyPart part) { public ModelPart getBodyPart(BodyPart part) {
switch (part) { switch (part) {
@ -355,7 +343,7 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
* @param pose The post to align to * @param pose The post to align to
* @param limbSpeed Degree to which each 'limb' swings. * @param limbSpeed Degree to which each 'limb' swings.
*/ */
protected void alignArmForAction(T state, ModelPart arm, ArmPose pose, ArmPose complement, float limbSpeed, float sigma) { protected void alignArmForAction(T state, ModelPart arm, ArmPose pose, ArmPose complement, float sigma) {
switch (pose) { switch (pose) {
case ITEM: case ITEM:
arm.yaw = 0; arm.yaw = 0;
@ -365,13 +353,13 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
if (state.attributes.shouldLiftArm(pose, complement, sigma)) { if (state.attributes.shouldLiftArm(pose, complement, sigma)) {
float swag = 1; float swag = 1;
if (!state.attributes.isFlying && both) { if (!state.attributes.isFlying && both) {
swag -= (float)Math.pow(limbSpeed, 2); swag -= (float)Math.pow(state.limbAmplitudeMultiplier, 2);
} }
float mult = 1 - swag/2; float mult = 1 - swag/2;
arm.pitch = arm.pitch * mult - (MathHelper.PI / 10) * swag; arm.pitch = arm.pitch * mult - (MathHelper.PI / 10) * swag;
arm.roll = -sigma * (MathHelper.PI / 15); arm.roll = -sigma * (MathHelper.PI / 15);
arm.roll += 0.3F * -limbSpeed * sigma; arm.roll += 0.3F * -state.limbAmplitudeMultiplier * sigma;
if (state.attributes.isCrouching) { if (state.attributes.isCrouching) {
arm.pivotX -= sigma * 2; arm.pivotX -= sigma * 2;
@ -385,7 +373,7 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
case BLOCK: case BLOCK:
arm.pitch = (arm.pitch / 2 - 0.9424779F) - 0.3F; arm.pitch = (arm.pitch / 2 - 0.9424779F) - 0.3F;
arm.yaw = sigma * MathHelper.PI / 9; arm.yaw = sigma * MathHelper.PI / 9;
arm.roll += 0.3F * -limbSpeed * sigma; arm.roll += 0.3F * -state.limbAmplitudeMultiplier * sigma;
if (complement == pose) { if (complement == pose) {
arm.yaw -= sigma * MathHelper.PI / 18; arm.yaw -= sigma * MathHelper.PI / 18;
} }
@ -396,24 +384,24 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
} }
break; break;
case BOW_AND_ARROW: case BOW_AND_ARROW:
aimBow(state, arm, limbSpeed); aimBow(state, arm);
break; break;
case CROSSBOW_HOLD: case CROSSBOW_HOLD:
aimBow(state, arm, limbSpeed); aimBow(state, arm);
arm.pitch = head.pitch - MathUtil.Angles._90_DEG; arm.pitch = head.pitch - MathUtil.Angles._90_DEG;
arm.yaw = head.yaw + 0.06F; arm.yaw = head.yaw + 0.06F;
break; break;
case CROSSBOW_CHARGE: case CROSSBOW_CHARGE:
aimBow(state, arm, limbSpeed); aimBow(state, arm);
arm.pitch = -0.8F; arm.pitch = -0.8F;
arm.yaw = head.yaw + 0.06F; arm.yaw = head.yaw + 0.06F;
arm.roll += 0.3F * -limbSpeed * sigma; arm.roll += 0.3F * -state.limbAmplitudeMultiplier * sigma;
break; break;
case THROW_SPEAR: case THROW_SPEAR:
arm.pitch = MathUtil.Angles._90_DEG * 2; arm.pitch = MathUtil.Angles._90_DEG * 2;
arm.roll += (0.3F * -limbSpeed + 0.6F) * sigma; arm.roll += (0.3F * -state.limbAmplitudeMultiplier + 0.6F) * sigma;
arm.pivotY ++; arm.pivotY ++;
break; break;
case SPYGLASS: case SPYGLASS:
@ -427,10 +415,10 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
arm.pivotX -= 6 * sigma; arm.pivotX -= 6 * sigma;
arm.pivotZ -= 2; arm.pivotZ -= 2;
} }
if (state.getSize() == SizePreset.TALL) { if (state.size == SizePreset.TALL) {
arm.pivotY += 1; arm.pivotY += 1;
} }
if (state.getSize() == SizePreset.FOAL) { if (state.size == SizePreset.FOAL) {
arm.pivotY -= 2; arm.pivotY -= 2;
} }
@ -439,22 +427,22 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
arm.pitch = MathHelper.clamp(head.pitch, -0.55f, 1.2f) - 1.7835298f; arm.pitch = MathHelper.clamp(head.pitch, -0.55f, 1.2f) - 1.7835298f;
arm.yaw = head.yaw - 0.1235988f * sigma; arm.yaw = head.yaw - 0.1235988f * sigma;
arm.pivotY += 3; arm.pivotY += 3;
arm.roll += 0.3F * -limbSpeed * sigma; arm.roll += 0.3F * -state.limbAmplitudeMultiplier * sigma;
break; break;
case BRUSH: case BRUSH:
arm.pitch = arm.pitch * 0.5f - 0.62831855f; arm.pitch = arm.pitch * 0.5f - 0.62831855f;
arm.yaw = 0; arm.yaw = 0;
arm.roll += 0.3F * -limbSpeed * sigma; arm.roll += 0.3F * -state.limbAmplitudeMultiplier * sigma;
break; break;
default: default:
break; break;
} }
} }
protected void aimBow(T state, ModelPart arm, float limbSpeed) { protected final void aimBow(T state, ModelPart arm) {
arm.pitch = MathUtil.Angles._270_DEG + head.pitch + (MathHelper.sin(limbSpeed * 0.067F) * 0.05F); arm.pitch = MathUtil.Angles._270_DEG + head.pitch + (MathHelper.sin(state.limbAmplitudeMultiplier * 0.067F) * 0.05F);
arm.yaw = head.yaw - 0.06F; arm.yaw = head.yaw - 0.06F;
arm.roll = MathHelper.cos(limbSpeed * 0.09F) * 0.05F + 0.05F; arm.roll = MathHelper.cos(state.limbAmplitudeMultiplier * 0.09F) * 0.05F + 0.05F;
if (state.isInSneakingPose) { if (state.isInSneakingPose) {
arm.pivotY += 4; arm.pivotY += 4;
@ -466,7 +454,7 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
* *
* @param entity The entity we are being called for. * @param entity The entity we are being called for.
*/ */
protected void swingItem(T state) { protected final void swingItem(T state) {
if (state.getSwingAmount() > 0 && !state.attributes.isLyingDown) { if (state.getSwingAmount() > 0 && !state.attributes.isLyingDown) {
swingArm(state, getArm(state.preferredArm)); swingArm(state, getArm(state.preferredArm));
} }
@ -477,7 +465,7 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
* *
* @param arm The arm to swing * @param arm The arm to swing
*/ */
protected void swingArm(T state, ModelPart arm) { protected final void swingArm(T state, ModelPart arm) {
float swing = 1 - (float)Math.pow(1 - state.getSwingAmount(), 3); float swing = 1 - (float)Math.pow(1 - state.getSwingAmount(), 3);
float deltaX = MathHelper.sin(swing * MathHelper.PI); float deltaX = MathHelper.sin(swing * MathHelper.PI);
@ -496,9 +484,9 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
* @param animationProgress Total whole and partial ticks since the entity's existence. * @param animationProgress Total whole and partial ticks since the entity's existence.
* Used in animations together with {@code swing} and {@code move}. * Used in animations together with {@code swing} and {@code move}.
*/ */
protected void animateBreathing(T state, float animationProgress, ArmPose left, ArmPose right) { protected void animateBreathing(T state, ArmPose left, ArmPose right) {
float cos = MathHelper.cos(animationProgress * 0.09F) * 0.05F + 0.05F; float cos = MathHelper.cos(state.age * 0.09F) * 0.05F + 0.05F;
float sin = MathHelper.sin(animationProgress * 0.067F) * 0.05F; float sin = MathHelper.sin(state.age * 0.067F) * 0.05F;
if (state.attributes.shouldLiftArm(right, left, -1)) { if (state.attributes.shouldLiftArm(right, left, -1)) {
ModelPart arm = getArm(Arm.RIGHT); ModelPart arm = getArm(Arm.RIGHT);
@ -596,6 +584,6 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
neck.hidden = !head.visible; neck.hidden = !head.visible;
} }
PonyTransformation.forSize(state.getSize()).transform(state.attributes, part, stack); PonyTransformation.forSize(state.size).transform(state.attributes, part, stack);
} }
} }

View file

@ -8,7 +8,6 @@ import org.jetbrains.annotations.Nullable;
import com.minelittlepony.api.model.*; import com.minelittlepony.api.model.*;
import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.client.render.entity.state.PonyRenderState;
import com.minelittlepony.mson.api.MsonModel;
/** /**
* The raw pony model without any implementations. * The raw pony model without any implementations.
@ -17,7 +16,7 @@ import com.minelittlepony.mson.api.MsonModel;
* *
* Modders can extend this class to make their own pony models if they wish. * Modders can extend this class to make their own pony models if they wish.
*/ */
public abstract class ClientPonyModel<T extends PonyRenderState> extends PlayerEntityModel implements MsonModel, PonyModel<T> { public abstract class ClientPonyModel<T extends PonyRenderState> extends PlayerEntityModel implements PonyModel<T> {
@Nullable @Nullable
protected PosingCallback<T> onSetModelAngles; protected PosingCallback<T> onSetModelAngles;

View file

@ -3,7 +3,6 @@ package com.minelittlepony.client.model.entity;
import net.minecraft.client.model.ModelPart; import net.minecraft.client.model.ModelPart;
import net.minecraft.client.render.VertexConsumer; import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.math.MathHelper;
import com.minelittlepony.client.render.entity.EnderStallionRenderer; import com.minelittlepony.client.render.entity.EnderStallionRenderer;
@ -54,14 +53,4 @@ public class EnderStallionModel extends SkeleponyModel<EnderStallionRenderer.Sta
leftPants.visible = false; leftPants.visible = false;
rightPants.visible = false; rightPants.visible = false;
} }
@Override
public boolean wingsAreOpen(EnderStallionRenderer.State state) {
return state.isAttacking;
}
@Override
public float getWingRotationFactor(EnderStallionRenderer.State state, float ticks) {
return MathHelper.sin(ticks) + WINGS_HALF_SPREAD_ANGLE;
}
} }

View file

@ -49,7 +49,7 @@ public class IllagerPonyModel<S extends IllagerPonyRenderer.State> extends Alico
arm.roll = mult * MathHelper.cos(state.age * 0.6662F) / 4; arm.roll = mult * MathHelper.cos(state.age * 0.6662F) / 4;
arm.yaw = mult * 1.1F; arm.yaw = mult * 1.1F;
} else if (pose == IllagerEntity.State.BOW_AND_ARROW) { } else if (pose == IllagerEntity.State.BOW_AND_ARROW) {
aimBow(state, arm, state.age); aimBow(state, arm);
} }
} }
} }

View file

@ -56,8 +56,8 @@ public class PiglinPonyModel extends ZomponyModel<PonyPiglinRenderer.State> {
} }
@Override @Override
protected void rotateLegs(PonyPiglinRenderer.State state, float move, float swing, float ticks) { protected void rotateLegs(PonyPiglinRenderer.State state) {
super.rotateLegs(state, move, swing, ticks); super.rotateLegs(state);
if (state.activity == PiglinActivity.ADMIRING_ITEM) { if (state.activity == PiglinActivity.ADMIRING_ITEM) {
leftArm.yaw = 0.5F; leftArm.yaw = 0.5F;
@ -65,13 +65,13 @@ public class PiglinPonyModel extends ZomponyModel<PonyPiglinRenderer.State> {
leftArm.pivotY += 4; leftArm.pivotY += 4;
leftArm.pivotZ += 3; leftArm.pivotZ += 3;
leftArm.pivotX += 2; leftArm.pivotX += 2;
head.pitch = MathHelper.sin(ticks / 12) / 6 + 0.5F; head.pitch = MathHelper.sin(state.age / 12) / 6 + 0.5F;
head.yaw = 0; head.yaw = 0;
head.roll = MathHelper.sin(ticks / 10) / 3F; head.roll = MathHelper.sin(state.age / 10) / 3F;
} else if (state.activity == PiglinActivity.DANCING) { } else if (state.activity == PiglinActivity.DANCING) {
float speed = ticks / 60; float speed = state.age / 60;
head.pivotX = MathHelper.sin(speed * 10); head.pivotX = MathHelper.sin(speed * 10);
head.pivotY = MathHelper.sin(speed * 40) + 0.4F; head.pivotY = MathHelper.sin(speed * 40) + 0.4F;

View file

@ -12,8 +12,8 @@ public class ZomponyModel<T extends ZomponyRenderer.State> extends AlicornModel<
} }
@Override @Override
protected void rotateLegs(T state, float move, float swing, float ticks) { protected void rotateLegs(T state) {
super.rotateLegs(state, move, swing, ticks); super.rotateLegs(state);
if (shouldLiftBothArms(state)) { if (shouldLiftBothArms(state)) {
MobPosingHelper.rotateUndeadArms(state, this, state.limbFrequency, state.age); MobPosingHelper.rotateUndeadArms(state, this, state.limbFrequency, state.age);
} }

View file

@ -17,7 +17,7 @@ public class ChangelingModel<T extends PonyRenderState> extends AlicornModel<T>
} }
@Override @Override
public float getWingRotationFactor(T state, float ticks) { public float getWingRotationFactor(T state) {
return state.attributes.isFlying ? MathHelper.sin(ticks * 3) + WINGS_HALF_SPREAD_ANGLE : WINGS_RAISED_ANGLE; return state.attributes.isFlying ? MathHelper.sin(state.age * 3) + WINGS_HALF_SPREAD_ANGLE : WINGS_RAISED_ANGLE;
} }
} }

View file

@ -71,8 +71,8 @@ public class SeaponyModel<T extends PonyRenderState> extends UnicornModel<T> {
} }
@Override @Override
protected void rotateLegs(T state, float move, float swing, float ticks) { protected void rotateLegs(T state) {
super.rotateLegs(state, move, swing, ticks); super.rotateLegs(state);
leftArm.pitch -= 1.4F; leftArm.pitch -= 1.4F;
leftArm.yaw -= 0.3F; leftArm.yaw -= 0.3F;
rightArm.pitch -= 1.4F; rightArm.pitch -= 1.4F;

View file

@ -2,7 +2,6 @@ package com.minelittlepony.client.model.entity.race;
import com.minelittlepony.api.config.PonyConfig; import com.minelittlepony.api.config.PonyConfig;
import com.minelittlepony.api.model.*; import com.minelittlepony.api.model.*;
import com.minelittlepony.api.pony.meta.Size;
import com.minelittlepony.api.pony.meta.SizePreset; import com.minelittlepony.api.pony.meta.SizePreset;
import com.minelittlepony.client.model.part.UnicornHorn; import com.minelittlepony.client.model.part.UnicornHorn;
import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.client.render.entity.state.PonyRenderState;
@ -11,7 +10,6 @@ import com.minelittlepony.mson.util.RenderList;
import net.minecraft.client.model.ModelPart; import net.minecraft.client.model.ModelPart;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.consume.UseAction; import net.minecraft.item.consume.UseAction;
import net.minecraft.registry.Registries; import net.minecraft.registry.Registries;
import net.minecraft.util.*; import net.minecraft.util.*;
@ -43,13 +41,8 @@ public class UnicornModel<T extends PonyRenderState> extends EarthPonyModel<T> i
} }
@Override @Override
public float getWobbleAmount() { protected void rotateLegs(T state) {
return isCasting(currentState) ? 0 : super.getWobbleAmount(); super.rotateLegs(state);
}
@Override
protected void rotateLegs(T state, float move, float swing, float ticks) {
super.rotateLegs(state, move, swing, ticks);
unicornArmRight.setAngles(0, 0, 0); unicornArmRight.setAngles(0, 0, 0);
unicornArmRight.setPivot(-7, 12, -2); unicornArmRight.setPivot(-7, 12, -2);
@ -97,13 +90,12 @@ public class UnicornModel<T extends PonyRenderState> extends EarthPonyModel<T> i
} }
if (main == arm) { if (main == arm) {
if (action == UseAction.SPYGLASS) { if (action == UseAction.SPYGLASS) {
Size size = state.getSize();
float x = 0.3F; float x = 0.3F;
float z = -0.4F; float z = -0.4F;
if (size == SizePreset.TALL || size == SizePreset.YEARLING) { if (state.size == SizePreset.TALL || state.size == SizePreset.YEARLING) {
z += 0.05F; z += 0.05F;
} else if (size == SizePreset.FOAL) { } else if (state.size == SizePreset.FOAL) {
x -= 0.1F; x -= 0.1F;
z -= 0.1F; z -= 0.1F;
} }

View file

@ -48,7 +48,7 @@ public class SaddleBags extends WearableGear {
rightBag.pitch = bodySwing; rightBag.pitch = bodySwing;
if (model instanceof WingedPonyModel pegasus && state.getAttributes().isFlying) { if (model instanceof WingedPonyModel pegasus && state.getAttributes().isFlying) {
bodySwing = pegasus.getWingRotationFactor(state, ticks) - MathUtil.Angles._270_DEG; bodySwing = pegasus.getWingRotationFactor(state) - MathUtil.Angles._270_DEG;
bodySwing /= 10; bodySwing /= 10;
} }

View file

@ -18,18 +18,18 @@ public class LionTail implements SubModel<PonyRenderState> {
} }
@Override @Override
public void setPartAngles(PonyRenderState state, float limbAngle, float limbSpeed, float bodySwing, float animationProgress) { public void setPartAngles(PonyRenderState state, float bodySwing) {
tail.resetTransform(); tail.resetTransform();
bodySwing *= 5; bodySwing *= 5;
float baseSail = 1F; float baseSail = 1F;
float speed = limbSpeed > 0.01F ? 6 : 90; float speed = state.limbAmplitudeMultiplier > 0.01F ? 6 : 90;
Interpolator interpolator = state.attributes.getMainInterpolator(); Interpolator interpolator = state.attributes.getMainInterpolator();
float straightness = 1.6F * (1 + (float)Math.sin(animationProgress / speed) / 8F); float straightness = 1.6F * (1 + (float)Math.sin(state.age / speed) / 8F);
float twist = (float)Math.sin(Math.PI/2F + 2 * animationProgress / speed) / 16F; float twist = (float)Math.sin(Math.PI/2F + 2 * state.age / speed) / 16F;
float bend = state.attributes.motionRoll / 80F; float bend = state.attributes.motionRoll / 80F;
if (state.attributes.isCrouching) { if (state.attributes.isCrouching) {
@ -46,11 +46,11 @@ public class LionTail implements SubModel<PonyRenderState> {
bend = interpolator.interpolate("kirin_tail_bendiness", bend, 10); bend = interpolator.interpolate("kirin_tail_bendiness", bend, 10);
tail.pitch = baseSail; tail.pitch = baseSail;
tail.pitch += limbSpeed / 2; tail.pitch += state.limbAmplitudeMultiplier / 2;
tail.yaw = twist; tail.yaw = twist;
tail.roll = bodySwing * 2; tail.roll = bodySwing * 2;
float sinTickFactor = MathHelper.sin(animationProgress * 0.067f) * 0.05f; float sinTickFactor = MathHelper.sin(state.age * 0.067f) * 0.05f;
tail.pitch += sinTickFactor; tail.pitch += sinTickFactor;
tail.yaw += sinTickFactor; tail.yaw += sinTickFactor;

View file

@ -27,11 +27,11 @@ public class PonyEars implements SubModel<PonyRenderState>, MsonModel {
} }
@Override @Override
public void setPartAngles(PonyRenderState state, float limbAngle, float limbSpeed, float bodySwing, float animationProgress) { public void setPartAngles(PonyRenderState state, float bodySwing) {
right.resetTransform(); right.resetTransform();
left.resetTransform(); left.resetTransform();
limbSpeed = MathHelper.clamp(limbSpeed, 0, 1); float limbSpeed = MathHelper.clamp(state.limbAmplitudeMultiplier, 0, 1);
float forwardFold = 0.14F * limbSpeed; float forwardFold = 0.14F * limbSpeed;
float sidewaysFlop = 0.11F * limbSpeed; float sidewaysFlop = 0.11F * limbSpeed;
@ -42,12 +42,12 @@ public class PonyEars implements SubModel<PonyRenderState>, MsonModel {
right.roll -= sidewaysFlop; right.roll -= sidewaysFlop;
left.roll += sidewaysFlop; left.roll += sidewaysFlop;
float floppyness = Math.abs(MathHelper.sin(animationProgress / 99F)); float floppyness = Math.abs(MathHelper.sin(state.age / 99F));
if (floppyness > 0.99F) { if (floppyness > 0.99F) {
boolean leftFlop = MathHelper.sin(animationProgress / 5F) > 0.5F; boolean leftFlop = MathHelper.sin(state.age / 5F) > 0.5F;
(leftFlop ? left : right).roll += (leftFlop ? left : right).roll +=
0.01F * MathHelper.sin(animationProgress / 2F) 0.01F * MathHelper.sin(state.age / 2F)
+ 0.015F * MathHelper.cos(animationProgress / 3F); + 0.015F * MathHelper.cos(state.age / 3F);
} }
} }

View file

@ -44,9 +44,9 @@ public class PonyTail implements SubModel<PonyRenderState>, MsonModel {
} }
@Override @Override
public void setPartAngles(PonyRenderState state, float limbAngle, float limbSpeed, float bodySwing, float animationProgress) { public void setPartAngles(PonyRenderState state, float bodySwing) {
boolean rainboom = state.attributes.isSwimming || state.attributes.isGoingFast; boolean rainboom = state.attributes.isSwimming || state.attributes.isGoingFast;
tail.roll = rainboom ? 0 : MathHelper.cos(limbAngle * 0.8F) * 0.2f * limbSpeed; tail.roll = rainboom ? 0 : MathHelper.cos(state.limbAmplitudeInverse * 0.8F) * 0.2f * state.limbAmplitudeMultiplier;
tail.yaw = bodySwing * 5; tail.yaw = bodySwing * 5;
if (state.attributes.isCrouching && !rainboom) { if (state.attributes.isCrouching && !rainboom) {
@ -59,11 +59,11 @@ public class PonyTail implements SubModel<PonyRenderState>, MsonModel {
} else { } else {
tail.setPivot(0, 0, TAIL_Z); tail.setPivot(0, 0, TAIL_Z);
if (rainboom) { if (rainboom) {
tail.pitch = MathUtil.Angles._90_DEG + MathHelper.sin(limbAngle) / 10; tail.pitch = MathUtil.Angles._90_DEG + MathHelper.sin(state.limbAmplitudeInverse) / 10;
} else { } else {
tail.pitch = limbSpeed / 2; tail.pitch = state.limbAmplitudeMultiplier / 2;
swingX(animationProgress); swingX(state.age);
} }
} }

View file

@ -57,17 +57,17 @@ public class PonyWings<S extends PonyRenderState> implements SubModel<S>, MsonMo
} }
@Override @Override
public void setPartAngles(S state, float move, float swing, float bodySwing, float ticks) { public void setPartAngles(S state, float bodySwing) {
float flap = 0; float flap = 0;
float progress = state.getSwingAmount(); float progress = state.getSwingAmount();
if (progress > 0) { if (progress > 0) {
flap = MathHelper.sin(MathHelper.sqrt(progress) * MathHelper.TAU); flap = MathHelper.sin(MathHelper.sqrt(progress) * MathHelper.TAU);
} else { } else {
float pi = MathHelper.PI * (float) Math.pow(swing, 16); float pi = MathHelper.PI * (float) Math.pow(state.limbAmplitudeMultiplier, 16);
float mve = move * 0.6662f; // magic number ahoy (actually 2/3) float mve = state.limbAmplitudeInverse * 0.6662f; // magic number ahoy (actually 2/3)
float srt = swing / 4; float srt = state.limbAmplitudeMultiplier * 0.25F;
flap = MathHelper.cos(mve + pi) * srt; flap = MathHelper.cos(mve + pi) * srt;
} }
@ -75,12 +75,12 @@ public class PonyWings<S extends PonyRenderState> implements SubModel<S>, MsonMo
float flapAngle = MathUtil.Angles._270_DEG; float flapAngle = MathUtil.Angles._270_DEG;
if (pegasus.wingsAreOpen(state)) { if (pegasus.wingsAreOpen(state)) {
flapAngle = pegasus.getWingRotationFactor(state, ticks); flapAngle = pegasus.getWingRotationFactor(state);
if (!state.attributes.isCrouching && pegasus.isBurdened(state)) { if (!state.attributes.isCrouching && isBurdened(state)) {
flapAngle -= 1F; flapAngle -= 1F;
} }
} else { } else {
flapAngle = MathUtil.Angles._270_DEG - 0.9F + (float)Math.sin(ticks / 10) / 15F; flapAngle = MathUtil.Angles._270_DEG - 0.9F + (float)Math.sin(state.age * 0.1F) / 15F;
} }
if (!state.attributes.isFlying) { if (!state.attributes.isFlying) {
@ -114,6 +114,13 @@ public class PonyWings<S extends PonyRenderState> implements SubModel<S>, MsonMo
} }
} }
private boolean isBurdened(S state) {
return state.getAttributes().isWearing(Wearable.SADDLE_BAGS_BOTH)
|| state.getAttributes().isWearing(Wearable.SADDLE_BAGS_LEFT)
|| state.getAttributes().isWearing(Wearable.SADDLE_BAGS_RIGHT);
}
@Override @Override
public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color) { public void renderPart(MatrixStack stack, VertexConsumer vertices, int overlay, int light, int color) {
leftWing.render(stack, vertices, overlay, light, color); leftWing.render(stack, vertices, overlay, light, color);

View file

@ -22,8 +22,8 @@ public class SeaponyTail implements SubModel<PonyRenderState>, MsonModel {
} }
@Override @Override
public void setPartAngles(PonyRenderState state, float limbAngle, float limbSpeed, float bodySwing, float animationProgress) { public void setPartAngles(PonyRenderState state, float bodySwing) {
float rotation = state.attributes.isLyingDown ? 0 : MathHelper.sin(animationProgress * 0.536f) / 4; float rotation = state.attributes.isLyingDown ? 0 : MathHelper.sin(state.age * 0.536f) / 4;
tailBase.pitch = MathHelper.HALF_PI + rotation; tailBase.pitch = MathHelper.HALF_PI + rotation;
tailTip.pitch = rotation; tailTip.pitch = rotation;

View file

@ -37,7 +37,7 @@ public final class DebugBoundingBoxRenderer {
} }
public static Box getBoundingBox(PonyRenderState state) { public static Box getBoundingBox(PonyRenderState state) {
final float scale = state.getScaleFactor(); final float scale = state.size.scaleFactor();
final float width = state.width * scale; final float width = state.width * scale;
final float height = state.height * scale; final float height = state.height * scale;

View file

@ -87,7 +87,7 @@ public class EquineRenderManager<
} }
public void setupTransforms(S state, MatrixStack stack, float animationProgress, float bodyYaw) { public void setupTransforms(S state, MatrixStack stack, float animationProgress, float bodyYaw) {
float s = state.getScaleFactor(); float s = state.size.scaleFactor();
stack.scale(s, s, s); stack.scale(s, s, s);
if (state instanceof PlayerEntityRenderState && state.attributes.isSitting) { if (state instanceof PlayerEntityRenderState && state.attributes.isSitting) {

View file

@ -6,7 +6,6 @@ import com.minelittlepony.client.model.ModelType;
import com.minelittlepony.client.model.armour.ArmourRendererPlugin; import com.minelittlepony.client.model.armour.ArmourRendererPlugin;
import com.minelittlepony.client.render.MobRenderers; import com.minelittlepony.client.render.MobRenderers;
import com.minelittlepony.client.render.entity.*; import com.minelittlepony.client.render.entity.*;
import com.minelittlepony.common.util.Color;
import net.minecraft.block.AbstractSkullBlock; import net.minecraft.block.AbstractSkullBlock;
import net.minecraft.block.SkullBlock; import net.minecraft.block.SkullBlock;
@ -18,16 +17,17 @@ import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.block.entity.SkullBlockEntityModel; import net.minecraft.client.render.block.entity.SkullBlockEntityModel;
import net.minecraft.client.render.block.entity.SkullBlockEntityRenderer; import net.minecraft.client.render.block.entity.SkullBlockEntityRenderer;
import net.minecraft.client.render.entity.state.LivingEntityRenderState;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.component.DataComponentTypes; import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.ProfileComponent; import net.minecraft.component.type.ProfileComponent;
import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.BlockItem; import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.equipment.EquipmentModel.LayerType; import net.minecraft.item.equipment.EquipmentModel.LayerType;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.Util; import net.minecraft.util.Util;
import net.minecraft.util.math.ColorHelper;
import net.minecraft.util.math.Direction; import net.minecraft.util.math.Direction;
import java.util.HashMap; import java.util.HashMap;
@ -60,13 +60,13 @@ public class PonySkullRenderer {
headModels = SkullBlockEntityRenderer.getModels(MinecraftClient.getInstance().getEntityModelLoader()); headModels = SkullBlockEntityRenderer.getModels(MinecraftClient.getInstance().getEntityModelLoader());
} }
public void renderSkull(MatrixStack matrices, VertexConsumerProvider provider, ItemStack stack, LivingEntity entity, float tickDelta, int light, boolean isPony) { public void renderSkull(MatrixStack matrices, VertexConsumerProvider provider, ItemStack stack, LivingEntityRenderState entity, float tickDelta, int light, boolean isPony) {
isBeingWorn = true; isBeingWorn = true;
this.isPony = isPony; this.isPony = isPony;
SkullType type = ((AbstractSkullBlock) ((BlockItem) stack.getItem()).getBlock()).getSkullType(); SkullType type = ((AbstractSkullBlock) ((BlockItem) stack.getItem()).getBlock()).getSkullType();
SkullBlockEntityModel skullBlockEntityModel = headModels.get(type); SkullBlockEntityModel skullBlockEntityModel = headModels.get(type);
RenderLayer renderLayer = SkullBlockEntityRenderer.getRenderLayer(type, stack.get(DataComponentTypes.PROFILE)); RenderLayer renderLayer = SkullBlockEntityRenderer.getRenderLayer(type, stack.get(DataComponentTypes.PROFILE));
SkullBlockEntityRenderer.renderSkull(null, 180, (entity.getVehicle() instanceof LivingEntity l ? l : entity).limbAnimator.getPos(tickDelta), matrices, provider, light, skullBlockEntityModel, renderLayer); SkullBlockEntityRenderer.renderSkull(null, 180, entity.headItemAnimationProgress, matrices, provider, light, skullBlockEntityModel, renderLayer);
isBeingWorn = false; isBeingWorn = false;
this.isPony = false; this.isPony = false;
} }
@ -112,7 +112,7 @@ public class PonySkullRenderer {
VertexConsumer vertices = renderContext.getBuffer(layer); VertexConsumer vertices = renderContext.getBuffer(layer);
selectedSkull.setAngles(yaw, animationProgress); selectedSkull.setAngles(yaw, animationProgress);
selectedSkull.render(stack, vertices, light, OverlayTexture.DEFAULT_UV, Color.argbToHex(ArmourRendererPlugin.INSTANCE.get().getArmourAlpha(EquipmentSlot.HEAD, LayerType.HUMANOID), 1, 1, 1)); selectedSkull.render(stack, vertices, light, OverlayTexture.DEFAULT_UV, ColorHelper.fromFloats(ArmourRendererPlugin.INSTANCE.get().getArmourAlpha(EquipmentSlot.HEAD, LayerType.HUMANOID), 1, 1, 1));
stack.pop(); stack.pop();

View file

@ -21,6 +21,7 @@ import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.EntityRendererFactory; import net.minecraft.client.render.entity.EntityRendererFactory;
import net.minecraft.client.render.entity.MobEntityRenderer; import net.minecraft.client.render.entity.MobEntityRenderer;
import net.minecraft.client.render.entity.feature.FeatureRenderer; import net.minecraft.client.render.entity.feature.FeatureRenderer;
import net.minecraft.client.render.entity.feature.HeadFeatureRenderer;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState; import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.mob.MobEntity;
@ -58,7 +59,7 @@ public abstract class AbstractPonyRenderer<
protected void addFeatures(EntityRendererFactory.Context context) { protected void addFeatures(EntityRendererFactory.Context context) {
addFeature(new ArmourFeature<>(this, context.getEquipmentModelLoader())); addFeature(new ArmourFeature<>(this, context.getEquipmentModelLoader()));
addPonyFeature(createHeldItemFeature(context)); addPonyFeature(createHeldItemFeature(context));
addFeature(new SkullFeature<>(this, context.getModelLoader(), context.getItemRenderer())); addFeature(createSkullFeature(context));
addPonyFeature(new ElytraFeature<>(this, context.getEquipmentRenderer())); addPonyFeature(new ElytraFeature<>(this, context.getEquipmentRenderer()));
addFeature(new GearFeature<>(this)); addFeature(new GearFeature<>(this));
} }
@ -71,6 +72,10 @@ public abstract class AbstractPonyRenderer<
return ((List)features).add(feature); return ((List)features).add(feature);
} }
protected SkullFeature<S, M> createSkullFeature(EntityRendererFactory.Context context) {
return new SkullFeature<>(this, context.getModelLoader(), context.getItemRenderer(), HeadFeatureRenderer.HeadTransformation.DEFAULT, true);
}
protected HeldItemFeature<S, M> createHeldItemFeature(EntityRendererFactory.Context context) { protected HeldItemFeature<S, M> createHeldItemFeature(EntityRendererFactory.Context context) {
return new HeldItemFeature<>(this, context.getItemRenderer()); return new HeldItemFeature<>(this, context.getItemRenderer());
} }
@ -92,13 +97,13 @@ public abstract class AbstractPonyRenderer<
} }
@Override @Override
public boolean shouldRender(T state, Frustum visibleRegion, double camX, double camY, double camZ) { public boolean shouldRender(T entity, Frustum visibleRegion, double camX, double camY, double camZ) {
return super.shouldRender(state, manager.getFrustrum(state, visibleRegion), camX, camY, camZ); return super.shouldRender(entity, manager.getFrustrum(entity, visibleRegion), camX, camY, camZ);
} }
@Override @Override
public void scale(S state, MatrixStack stack) { public void scale(S state, MatrixStack stack) {
shadowRadius = state.getShadowSize(); shadowRadius = state.size.shadowSize();
if (state.baby) { if (state.baby) {
shadowRadius *= 3; // undo vanilla shadow scaling shadowRadius *= 3; // undo vanilla shadow scaling

View file

@ -1,7 +1,6 @@
package com.minelittlepony.client.render.entity; package com.minelittlepony.client.render.entity;
import com.minelittlepony.api.model.ModelAttributes; import com.minelittlepony.api.model.*;
import com.minelittlepony.api.model.PonyModel;
import com.minelittlepony.api.pony.Pony; import com.minelittlepony.api.pony.Pony;
import com.minelittlepony.api.pony.meta.Race; import com.minelittlepony.api.pony.meta.Race;
import com.minelittlepony.client.MineLittlePony; import com.minelittlepony.client.MineLittlePony;
@ -21,6 +20,7 @@ import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.mob.EndermanEntity; import net.minecraft.entity.mob.EndermanEntity;
import net.minecraft.util.Arm; import net.minecraft.util.Arm;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.MathHelper;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -92,6 +92,9 @@ public class EnderStallionRenderer extends PonyRenderer<EndermanEntity, EnderSta
leftHandStack = carriedBlock.getBlock().asItem().getDefaultStack(); leftHandStack = carriedBlock.getBlock().asItem().getDefaultStack();
} }
} }
attributes.wingsSpread = isAttacking;
attributes.wingAngle = MathHelper.sin(age) + WingedPonyModel.WINGS_HALF_SPREAD_ANGLE;
} }
@Override @Override

View file

@ -52,6 +52,7 @@ public class PlayerPonyRenderer
addPonyFeatures(context); addPonyFeatures(context);
} }
@SuppressWarnings({"unchecked", "rawtypes"})
protected void addPonyFeatures(EntityRendererFactory.Context context) { protected void addPonyFeatures(EntityRendererFactory.Context context) {
// remove vanilla features (keep modded ones) // remove vanilla features (keep modded ones)
features.removeIf(feature -> { features.removeIf(feature -> {
@ -67,8 +68,8 @@ public class PlayerPonyRenderer
addPonyFeature(new HeldItemFeature<>(this, context.getItemRenderer())); addPonyFeature(new HeldItemFeature<>(this, context.getItemRenderer()));
addPonyFeature(new DJPon3Feature<>(this)); addPonyFeature(new DJPon3Feature<>(this));
addFeature(new CapeFeature(this, context.getModelLoader(), context.getEquipmentModelLoader())); addFeature(new CapeFeature(this, context.getModelLoader(), context.getEquipmentModelLoader()));
addPonyFeature(new SkullFeature<>(this, context.getModelLoader(), context.getItemRenderer())); addPonyFeature(new SkullFeature<>(this, context.getModelLoader(), context.getItemRenderer(), HeadFeatureRenderer.HeadTransformation.DEFAULT, true));
addPonyFeature(new ElytraFeature<>(this, context.getEquipmentRenderer())); addPonyFeature(new ElytraFeature(this, context.getEquipmentRenderer()));
addPonyFeature(new PassengerFeature<>(this, context)); addPonyFeature(new PassengerFeature<>(this, context));
addPonyFeature(new GearFeature<>(this)); addPonyFeature(new GearFeature<>(this));
} }
@ -83,7 +84,7 @@ public class PlayerPonyRenderer
public Vec3d getPositionOffset(PlayerEntityRenderState state) { public Vec3d getPositionOffset(PlayerEntityRenderState state) {
Vec3d offset = super.getPositionOffset(state); Vec3d offset = super.getPositionOffset(state);
return offset.add(state.baseScale * ((PlayerPonyRenderState)state).yOffset).multiply(((PonyRenderState)state).getScaleFactor()); return offset.add(state.baseScale * ((PlayerPonyRenderState)state).yOffset).multiply(((PonyRenderState)state).size.scaleFactor());
} }
@Override @Override
@ -112,7 +113,7 @@ public class PlayerPonyRenderer
@Override @Override
public void render(PlayerEntityRenderState state, MatrixStack stack, VertexConsumerProvider vertices, int light) { 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 // EntityModelFeatures: We have to force it to use our models otherwise EMF overrides it and breaks pony rendering
shadowRadius = ((PlayerPonyRenderState)state).getShadowSize(); shadowRadius = ((PlayerPonyRenderState)state).size.shadowSize();
super.render(state, stack, vertices, light); super.render(state, stack, vertices, light);
DebugBoundingBoxRenderer.render((PlayerPonyRenderState)state, stack, vertices); DebugBoundingBoxRenderer.render((PlayerPonyRenderState)state, stack, vertices);

View file

@ -7,36 +7,86 @@ import net.minecraft.client.render.entity.model.ArmorStandArmorEntityModel;
import net.minecraft.client.render.entity.state.ArmorStandEntityRenderState; import net.minecraft.client.render.entity.state.ArmorStandEntityRenderState;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.decoration.ArmorStandEntity; import net.minecraft.entity.decoration.ArmorStandEntity;
import net.minecraft.util.Identifier;
import com.minelittlepony.api.model.ModelAttributes.Mode;
import com.minelittlepony.api.model.Models; import com.minelittlepony.api.model.Models;
import com.minelittlepony.api.pony.Pony;
import com.minelittlepony.api.pony.PonyData;
import com.minelittlepony.api.pony.meta.Wearable;
import com.minelittlepony.client.model.ModelType; import com.minelittlepony.client.model.ModelType;
import com.minelittlepony.client.model.armour.PonifiedEquipmentRenderer; import com.minelittlepony.client.model.armour.PonifiedEquipmentRenderer;
import com.minelittlepony.client.model.entity.PonyArmourStandModel; import com.minelittlepony.client.model.entity.PonyArmourStandModel;
import com.minelittlepony.client.model.entity.race.EarthPonyModel; import com.minelittlepony.client.model.entity.race.EarthPonyModel;
import com.minelittlepony.client.render.EquineRenderManager;
import com.minelittlepony.client.render.PonyRenderContext;
import com.minelittlepony.client.render.entity.feature.*; import com.minelittlepony.client.render.entity.feature.*;
import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.client.render.entity.state.PonyRenderState;
public class PonyStandRenderer extends ArmorStandEntityRenderer { import java.util.Optional;
import java.util.function.Function;
import java.util.function.Predicate;
public class PonyStandRenderer extends ArmorStandEntityRenderer implements PonyRenderContext<ArmorStandEntity, PonyRenderState, EarthPonyModel<PonyRenderState>> {
static final Pony PONY = new Pony(Identifier.ofVanilla("null"), () -> Optional.of(PonyData.NULL));
private final PonyArmourStandModel pony = ModelType.ARMOUR_STAND.createModel(); private final PonyArmourStandModel pony = ModelType.ARMOUR_STAND.createModel();
private final Models<EarthPonyModel<PonyRenderState>> models = ModelType.EARTH_PONY.create(false);
private final ArmorStandArmorEntityModel human; private final ArmorStandArmorEntityModel human;
private final EquineRenderManager<ArmorStandEntity, PonyRenderState, EarthPonyModel<PonyRenderState>> manager;
public PonyStandRenderer(EntityRendererFactory.Context context) { public PonyStandRenderer(EntityRendererFactory.Context context) {
super(context); super(context);
human = model; human = model;
this.manager = new EquineRenderManager<>(this, (state, stack, progress, yaw) -> {}, models);
Predicate<ArmorStandEntityRenderState> swapPredicate = state -> ((State)state).hasPonyForm;
Function<ArmorStandEntityRenderState, PonyRenderState> converter = state -> ((State)state).ponyState;
for (int i = 0; i < features.size(); i++) { for (int i = 0; i < features.size(); i++) {
var feature = features.get(i); var feature = features.get(i);
if (feature instanceof ArmorFeatureRenderer) { if (feature instanceof ArmorFeatureRenderer) {
features.set(i, new SwappableFeature<>(this, feature, new Armour(this, context), state -> ((State)state).hasPonyForm)); features.set(i, new SwappableFeature<>(this, feature, new Armour(context), swapPredicate, converter));
} }
if (feature instanceof ElytraFeatureRenderer) { if (feature instanceof ElytraFeatureRenderer) {
features.set(i, new SwappableFeature<>(this, feature, new ElytraFeature<>(this, context.getEquipmentRenderer()), state -> ((State)state).hasPonyForm)); features.set(i, new SwappableFeature<>(this,
feature,
new ElytraFeature<>(() -> models.body(), context.getEquipmentRenderer()), swapPredicate, converter));
}
if (feature instanceof HeadFeatureRenderer) {
features.set(i, new SwappableFeature<>(this,
feature,
new SkullFeature<PonyRenderState, EarthPonyModel<PonyRenderState>>(
this,
context.getModelLoader(),
context.getItemRenderer(),
HeadFeatureRenderer.HeadTransformation.DEFAULT,
false
), swapPredicate, converter));
}
} }
} }
//addFeature(new HeadFeatureRenderer<>(this, context.getModelLoader(), context.getItemRenderer()));
@Override
public Identifier getDefaultTexture(PonyRenderState entity, Wearable wearable) {
return wearable.getDefaultTexture();
} }
@Override
public Pony getEntityPony(ArmorStandEntity entity) {
return PONY;
}
@Override
public EquineRenderManager<ArmorStandEntity, PonyRenderState, EarthPonyModel<PonyRenderState>> getInternalRenderer() {
return manager;
}
@Override
public void setModel(EarthPonyModel<PonyRenderState> model) { }
@Override @Override
public ArmorStandEntityRenderState createRenderState() { public ArmorStandEntityRenderState createRenderState() {
return new State(); return new State();
@ -48,6 +98,8 @@ public class PonyStandRenderer extends ArmorStandEntityRenderer {
super.updateRenderState(entity, state, tickDelta); super.updateRenderState(entity, state, tickDelta);
((State)state).hasPonyForm = ponified; ((State)state).hasPonyForm = ponified;
if (ponified) { if (ponified) {
BipedEntityRenderer.updateBipedRenderState(entity, ((State)state).ponyState, tickDelta);
manager.updateState(entity, ((State)state).ponyState, Mode.OTHER);
state.pitch = 0.017453292F * entity.getHeadRotation().getPitch(); state.pitch = 0.017453292F * entity.getHeadRotation().getPitch();
state.yawDegrees = 0.017453292F * entity.getHeadRotation().getYaw(); state.yawDegrees = 0.017453292F * entity.getHeadRotation().getYaw();
} }
@ -64,20 +116,18 @@ public class PonyStandRenderer extends ArmorStandEntityRenderer {
} }
} }
class Armour extends FeatureRenderer<ArmorStandEntityRenderState, ArmorStandArmorEntityModel> { class Armour extends FeatureRenderer<PonyRenderState, EarthPonyModel<PonyRenderState>> {
private final Models<EarthPonyModel<PonyRenderState>> pony = ModelType.EARTH_PONY.create(false);
private final PonifiedEquipmentRenderer equipmentRenderer; private final PonifiedEquipmentRenderer equipmentRenderer;
public Armour(FeatureRendererContext<ArmorStandEntityRenderState, ArmorStandArmorEntityModel> renderer, EntityRendererFactory.Context context) { public Armour(EntityRendererFactory.Context context) {
super(renderer); super(() -> models.body());
equipmentRenderer = new PonifiedEquipmentRenderer(context.getEquipmentModelLoader()); equipmentRenderer = new PonifiedEquipmentRenderer(context.getEquipmentModelLoader());
} }
@Override @Override
public void render(MatrixStack matrices, VertexConsumerProvider vertices, int light, ArmorStandEntityRenderState state, float limbAngle, float limbDistance) { public void render(MatrixStack matrices, VertexConsumerProvider vertices, int light, PonyRenderState state, float limbAngle, float limbDistance) {
pony.body().setAngles(((State)state).ponyState); getContextModel().setAngles(state);
ArmourFeature.renderArmor(pony, matrices, vertices, light, ((State)state).ponyState, limbDistance, limbAngle, equipmentRenderer); ArmourFeature.renderArmor(models, matrices, vertices, light, state, limbDistance, limbAngle, equipmentRenderer);
} }
} }

View file

@ -8,9 +8,9 @@ import com.minelittlepony.client.model.entity.race.SeaponyModel;
import com.minelittlepony.client.render.entity.npc.textures.TextureSupplier; import com.minelittlepony.client.render.entity.npc.textures.TextureSupplier;
import com.minelittlepony.client.render.entity.state.PonyRenderState; import com.minelittlepony.client.render.entity.state.PonyRenderState;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.*; import net.minecraft.client.render.*;
import net.minecraft.client.render.entity.EntityRendererFactory; import net.minecraft.client.render.entity.EntityRendererFactory;
import net.minecraft.client.render.entity.GuardianEntityRenderer;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
@ -50,8 +50,8 @@ public class SeaponyRenderer extends PonyRenderer<GuardianEntity, SeaponyRendere
super.updateRenderState(entity, state, tickDelta); super.updateRenderState(entity, state, tickDelta);
state.spikesExtension = entity.getSpikesExtension(tickDelta); state.spikesExtension = entity.getSpikesExtension(tickDelta);
state.tailAngle = entity.getTailAngle(tickDelta); state.tailAngle = entity.getTailAngle(tickDelta);
state.cameraPosVec = getScaledCameraPosVec(entity, tickDelta, state.getScaleFactor()); state.cameraPosVec = getScaledCameraPosVec(entity, tickDelta, state.size.scaleFactor());
Entity cameraBeamTarget = getBeamTarget(entity); Entity cameraBeamTarget = GuardianEntityRenderer.getBeamTarget(entity);
state.rotationVec = cameraBeamTarget != null ? entity.getRotationVec(tickDelta) : null; state.rotationVec = cameraBeamTarget != null ? entity.getRotationVec(tickDelta) : null;
state.lookAtPos = cameraBeamTarget != null ? cameraBeamTarget.getCameraPosVec(tickDelta) : null; state.lookAtPos = cameraBeamTarget != null ? cameraBeamTarget.getCameraPosVec(tickDelta) : null;
@ -73,7 +73,7 @@ public class SeaponyRenderer extends PonyRenderer<GuardianEntity, SeaponyRendere
float f = state.beamTicks * 0.5F % 1.0F; float f = state.beamTicks * 0.5F % 1.0F;
matrices.push(); matrices.push();
matrices.translate(0.0F, state.standingEyeHeight, 0.0F); matrices.translate(0.0F, state.standingEyeHeight, 0.0F);
renderBeam( GuardianEntityRenderer.renderBeam(
matrices, matrices,
vertices.getBuffer(LAYER), vertices.getBuffer(LAYER),
vec3d.subtract(state.cameraPosVec), vec3d.subtract(state.cameraPosVec),
@ -85,71 +85,6 @@ public class SeaponyRenderer extends PonyRenderer<GuardianEntity, SeaponyRendere
} }
} }
private static void renderBeam(MatrixStack matrices, VertexConsumer vertexConsumer, Vec3d vec3d, float beamTicks, float f, float g) {
float h = (float)(vec3d.length() + 1.0);
vec3d = vec3d.normalize();
float i = (float)Math.acos(vec3d.y);
float j = (float) (Math.PI / 2) - (float)Math.atan2(vec3d.z, vec3d.x);
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(j * (180.0F / (float)Math.PI)));
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(i * (180.0F / (float)Math.PI)));
float k = beamTicks * 0.05F * -1.5F;
float l = f * f;
int m = 64 + (int)(l * 191.0F);
int n = 32 + (int)(l * 191.0F);
int o = 128 - (int)(l * 64.0F);
float p = 0.2F;
float q = 0.282F;
float r = MathHelper.cos(k + (float) (Math.PI * 3.0 / 4.0)) * 0.282F;
float s = MathHelper.sin(k + (float) (Math.PI * 3.0 / 4.0)) * 0.282F;
float t = MathHelper.cos(k + (float) (Math.PI / 4)) * 0.282F;
float u = MathHelper.sin(k + (float) (Math.PI / 4)) * 0.282F;
float v = MathHelper.cos(k + ((float) Math.PI * 5.0F / 4.0F)) * 0.282F;
float w = MathHelper.sin(k + ((float) Math.PI * 5.0F / 4.0F)) * 0.282F;
float x = MathHelper.cos(k + ((float) Math.PI * 7.0F / 4.0F)) * 0.282F;
float y = MathHelper.sin(k + ((float) Math.PI * 7.0F / 4.0F)) * 0.282F;
float z = MathHelper.cos(k + (float) Math.PI) * 0.2F;
float aa = MathHelper.sin(k + (float) Math.PI) * 0.2F;
float ab = MathHelper.cos(k + 0.0F) * 0.2F;
float ac = MathHelper.sin(k + 0.0F) * 0.2F;
float ad = MathHelper.cos(k + (float) (Math.PI / 2)) * 0.2F;
float ae = MathHelper.sin(k + (float) (Math.PI / 2)) * 0.2F;
float af = MathHelper.cos(k + (float) (Math.PI * 3.0 / 2.0)) * 0.2F;
float ag = MathHelper.sin(k + (float) (Math.PI * 3.0 / 2.0)) * 0.2F;
float ai = 0.0F;
float aj = 0.4999F;
float ak = -1.0F + g;
float al = ak + h * 2.5F;
MatrixStack.Entry entry = matrices.peek();
vertex(vertexConsumer, entry, z, h, aa, m, n, o, 0.4999F, al);
vertex(vertexConsumer, entry, z, 0.0F, aa, m, n, o, 0.4999F, ak);
vertex(vertexConsumer, entry, ab, 0.0F, ac, m, n, o, 0.0F, ak);
vertex(vertexConsumer, entry, ab, h, ac, m, n, o, 0.0F, al);
vertex(vertexConsumer, entry, ad, h, ae, m, n, o, 0.4999F, al);
vertex(vertexConsumer, entry, ad, 0.0F, ae, m, n, o, 0.4999F, ak);
vertex(vertexConsumer, entry, af, 0.0F, ag, m, n, o, 0.0F, ak);
vertex(vertexConsumer, entry, af, h, ag, m, n, o, 0.0F, al);
float am = MathHelper.floor(beamTicks) % 2 == 0 ? 0.5F : 0.0F;
vertex(vertexConsumer, entry, r, h, s, m, n, o, 0.5F, am + 0.5F);
vertex(vertexConsumer, entry, t, h, u, m, n, o, 1.0F, am + 0.5F);
vertex(vertexConsumer, entry, x, h, y, m, n, o, 1.0F, am);
vertex(vertexConsumer, entry, v, h, w, m, n, o, 0.5F, am);
}
private static void vertex(VertexConsumer vertexConsumer, MatrixStack.Entry matrix, float x, float y, float z, int red, int green, int blue, float u, float v) {
vertexConsumer.vertex(matrix, x, y, z)
.color(red, green, blue, 255)
.texture(u, v)
.overlay(OverlayTexture.DEFAULT_UV)
.light(LightmapTextureManager.MAX_LIGHT_COORDINATE)
.normal(matrix, 0.0F, 1.0F, 0.0F);
}
@Nullable
private static Entity getBeamTarget(GuardianEntity guardian) {
Entity entity = MinecraftClient.getInstance().getCameraEntity();
return guardian.hasBeamTarget() ? guardian.getBeamTarget() : entity;
}
private Vec3d fromLerpedPosition(LivingEntity entity, double yOffset, float delta) { private Vec3d fromLerpedPosition(LivingEntity entity, double yOffset, float delta) {
double d = MathHelper.lerp((double)delta, entity.lastRenderX, entity.getX()); double d = MathHelper.lerp((double)delta, entity.lastRenderX, entity.getX());
double e = MathHelper.lerp((double)delta, entity.lastRenderY, entity.getY()) + yOffset; double e = MathHelper.lerp((double)delta, entity.lastRenderY, entity.getY()) + yOffset;

View file

@ -11,8 +11,6 @@ import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.equipment.EquipmentRenderer; import net.minecraft.client.render.entity.equipment.EquipmentRenderer;
import net.minecraft.client.render.entity.feature.FeatureRenderer; import net.minecraft.client.render.entity.feature.FeatureRenderer;
import net.minecraft.client.render.entity.feature.FeatureRendererContext; import net.minecraft.client.render.entity.feature.FeatureRendererContext;
import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.client.render.entity.state.BipedEntityRenderState;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState; import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.client.util.SkinTextures; import net.minecraft.client.util.SkinTextures;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
@ -24,8 +22,8 @@ import net.minecraft.item.equipment.EquipmentModel;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
public class ElytraFeature< public class ElytraFeature<
S extends BipedEntityRenderState, S extends PonyRenderState,
M extends EntityModel<S> M extends ClientPonyModel<S>
> extends FeatureRenderer<S, M> { > extends FeatureRenderer<S, M> {
private static final Identifier TEXTURE = Identifier.ofVanilla("textures/entity/elytra.png"); private static final Identifier TEXTURE = Identifier.ofVanilla("textures/entity/elytra.png");

View file

@ -100,7 +100,7 @@ public class GearFeature<
} }
private void renderGear(M model, S entity, Gear gear, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, float limbDistance, float limbAngle, float tickDelta) { private void renderGear(M model, S entity, Gear gear, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, float limbDistance, float limbAngle, float tickDelta) {
gear.pose(model, entity, entity.attributes.isGoingFast, entity.attributes.getEntityId(), limbDistance, limbAngle, entity.getWobbleAmount(), tickDelta); gear.pose(model, entity, entity.attributes.isGoingFast, entity.attributes.getEntityId(), limbDistance, limbAngle, entity.wobbleAmount * model.getWobbleAmplitude(entity), tickDelta);
gear.render(stack, renderContext.getBuffer(gear.getLayer(entity, getContext())), lightUv, OverlayTexture.DEFAULT_UV, Colors.WHITE, entity.attributes.getEntityId()); gear.render(stack, renderContext.getBuffer(gear.getLayer(entity, getContext())), lightUv, OverlayTexture.DEFAULT_UV, Colors.WHITE, entity.attributes.getEntityId());
} }

View file

@ -1,7 +1,6 @@
package com.minelittlepony.client.render.entity.feature; package com.minelittlepony.client.render.entity.feature;
import com.minelittlepony.api.model.BodyPart; import com.minelittlepony.api.model.BodyPart;
import com.minelittlepony.api.model.PonyModel;
import com.minelittlepony.client.model.ClientPonyModel; import com.minelittlepony.client.model.ClientPonyModel;
import com.minelittlepony.client.model.armour.ArmourLayer; import com.minelittlepony.client.model.armour.ArmourLayer;
import com.minelittlepony.client.model.armour.ArmourRendererPlugin; import com.minelittlepony.client.model.armour.ArmourRendererPlugin;
@ -12,27 +11,31 @@ import com.minelittlepony.client.render.entity.state.PonyRenderState;
import net.minecraft.block.AbstractSkullBlock; import net.minecraft.block.AbstractSkullBlock;
import net.minecraft.client.render.*; import net.minecraft.client.render.*;
import net.minecraft.client.render.entity.feature.HeadFeatureRenderer; 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.model.EntityModelLoader;
import net.minecraft.client.render.entity.state.BipedEntityRenderState;
import net.minecraft.client.render.item.ItemRenderer; import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.EquippableComponent;
import net.minecraft.entity.EquipmentSlot; import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.mob.ZombieVillagerEntity;
import net.minecraft.entity.passive.VillagerEntity;
import net.minecraft.item.*; import net.minecraft.item.*;
public class SkullFeature< public class SkullFeature<
T extends LivingEntity,
S extends PonyRenderState, S extends PonyRenderState,
M extends ClientPonyModel<S> M extends ClientPonyModel<S>
> extends AbstractPonyFeature<S, M> { > extends AbstractPonyFeature<S, M> {
private final ItemRenderer itemRenderer; private final ItemRenderer itemRenderer;
public SkullFeature(PonyRenderContext<T, S, M> renderPony, EntityModelLoader entityModelLoader, ItemRenderer itemRenderer) { private final HeadFeatureRenderer.HeadTransformation headTransformation;
super(renderPony);
private final boolean scaleForChild;
public SkullFeature(PonyRenderContext<?, S, M> context, EntityModelLoader entityModelLoader, ItemRenderer itemRenderer,
HeadFeatureRenderer.HeadTransformation headTransformation, boolean scaleForChild) {
super(context);
this.itemRenderer = itemRenderer; this.itemRenderer = itemRenderer;
this.headTransformation = headTransformation;
this.scaleForChild = scaleForChild;
} }
@Override @Override
@ -40,16 +43,20 @@ public class SkullFeature<
ArmourRendererPlugin plugin = ArmourRendererPlugin.INSTANCE.get(); ArmourRendererPlugin plugin = ArmourRendererPlugin.INSTANCE.get();
for (ItemStack stack : plugin.getArmorStacks(state, EquipmentSlot.HEAD, ArmourLayer.OUTER, ArmourRendererPlugin.ArmourType.SKULL)) { for (ItemStack stack : plugin.getArmorStacks(state, EquipmentSlot.HEAD, ArmourLayer.OUTER, ArmourRendererPlugin.ArmourType.SKULL)) {
if (stack.isEmpty()) {
BakedModel headModel = state.equippedHeadItemModel;
if (stack.isEmpty() || headModel == null) {
continue; continue;
} }
M model = getModelWrapper().body(); M model = getModelWrapper().body();
Item item = stack.getItem(); Item item = stack.getItem();
EquippableComponent equipable = stack.get(DataComponentTypes.EQUIPPABLE);
matrices.push(); matrices.push();
if (state.baby && !(state instanceof VillagerEntity)) { if (state.baby && scaleForChild) {
matrices.translate(0, 0.03125F, 0); matrices.translate(0, 0.03125F, 0);
matrices.scale(0.7F, 0.7F, 0.7F); matrices.scale(0.7F, 0.7F, 0.7F);
matrices.translate(0, 1, 0); matrices.translate(0, 1, 0);
@ -58,8 +65,6 @@ public class SkullFeature<
model.transform(state, BodyPart.HEAD, matrices); model.transform(state, BodyPart.HEAD, matrices);
model.getHead().rotate(matrices); model.getHead().rotate(matrices);
boolean isVillager = state instanceof VillagerEntity || state instanceof ZombieVillagerEntity;
float f = 1.1F; float f = 1.1F;
matrices.scale(f, f, f); matrices.scale(f, f, f);
@ -69,10 +74,10 @@ public class SkullFeature<
matrices.translate(0, -0.1F, 0.1F); matrices.translate(0, -0.1F, 0.1F);
matrices.translate(-0.5, 0, -0.5); matrices.translate(-0.5, 0, -0.5);
PonySkullRenderer.INSTANCE.renderSkull(matrices, provider, stack, state, state.age, light, true); PonySkullRenderer.INSTANCE.renderSkull(matrices, provider, stack, state, state.age, light, true);
} else if (!(item instanceof ArmorItem a) || a.getSlotType() != EquipmentSlot.HEAD) { } else if (equipable != null && equipable.slot() != EquipmentSlot.HEAD) {
matrices.translate(0, 0.1F, -0.1F); matrices.translate(0, 0.1F, -0.1F);
HeadFeatureRenderer.translate(matrices, isVillager); HeadFeatureRenderer.translate(matrices, headTransformation);
itemRenderer.renderItem(state, stack, ModelTransformationMode.HEAD, false, matrices, provider, entity.getWorld(), light, OverlayTexture.DEFAULT_UV, entity.getId() + ModelTransformationMode.HEAD.ordinal()); itemRenderer.renderItem(stack, ModelTransformationMode.HEAD, false, matrices, provider, light, OverlayTexture.DEFAULT_UV, headModel);
} }
matrices.pop(); matrices.pop();

View file

@ -7,29 +7,42 @@ import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.client.render.entity.state.EntityRenderState; import net.minecraft.client.render.entity.state.EntityRenderState;
import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.util.math.MatrixStack;
import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
public final class SwappableFeature<S extends EntityRenderState, M extends EntityModel<? super S>> extends FeatureRenderer<S, M> { public final class SwappableFeature<
S extends EntityRenderState,
M extends EntityModel<? super S>,
P extends EntityRenderState,
N extends EntityModel<? super P>
> extends FeatureRenderer<S, M> {
private final FeatureRenderer<S, M> normal; private final FeatureRenderer<S, M> normal;
private final FeatureRenderer<S, M> swapped; private final FeatureRenderer<P, N> swapped;
private final Predicate<S> swapCondition; private final Predicate<S> swapCondition;
private final Function<S, P> stateConverter;
public SwappableFeature( public SwappableFeature(
FeatureRendererContext<S, M> context, FeatureRendererContext<S, M> context,
FeatureRenderer<S, M> normal, FeatureRenderer<S, M> normal,
FeatureRenderer<S, M> swapped, FeatureRenderer<P, N> swapped,
Predicate<S> swapCondition Predicate<S> swapCondition,
Function<S, P> stateConverter
) { ) {
super(context); super(context);
this.normal = normal; this.normal = normal;
this.swapped = swapped; this.swapped = swapped;
this.swapCondition = swapCondition; this.swapCondition = swapCondition;
this.stateConverter = stateConverter;
} }
@Override @Override
public void render(MatrixStack matrices, VertexConsumerProvider vertices, int light, S state, float limbAngle, float limbDistance) { public void render(MatrixStack matrices, VertexConsumerProvider vertices, int light, S state, float limbAngle, float limbDistance) {
(swapCondition.test(state) ? swapped : normal).render(matrices, vertices, light, state, limbAngle, limbDistance); if (swapCondition.test(state)) {
swapped.render(matrices, vertices, light, stateConverter.apply(state), limbAngle, limbDistance);
} else {
normal.render(matrices, vertices, light, state, limbAngle, limbDistance);
}
} }
} }

View file

@ -24,6 +24,7 @@ public class PonyRenderState extends PlayerEntityRenderState implements PonyMode
public float riderOffset; public float riderOffset;
public float nameplateYOffset; public float nameplateYOffset;
public float legOutset; public float legOutset;
public float wobbleAmount;
public boolean smallArms; public boolean smallArms;
public boolean sleepingInBed; public boolean sleepingInBed;
public boolean submergedInWater; public boolean submergedInWater;
@ -31,6 +32,7 @@ public class PonyRenderState extends PlayerEntityRenderState implements PonyMode
public boolean isTechnoblade; public boolean isTechnoblade;
public Pony pony; public Pony pony;
public Size size;
public void updateState(LivingEntity entity, PonyModel<?> model, Pony pony, ModelAttributes.Mode mode) { public void updateState(LivingEntity entity, PonyModel<?> model, Pony pony, ModelAttributes.Mode mode) {
this.pony = pony; this.pony = pony;
@ -43,6 +45,7 @@ public class PonyRenderState extends PlayerEntityRenderState implements PonyMode
isInSneakingPose = attributes.isCrouching && !attributes.isLyingDown; isInSneakingPose = attributes.isCrouching && !attributes.isLyingDown;
sleepingInBed = entity.getSleepingPosition().isPresent() && entity.getEntityWorld().getBlockState(entity.getSleepingPosition().get()).getBlock() instanceof BedBlock; sleepingInBed = entity.getSleepingPosition().isPresent() && entity.getEntityWorld().getBlockState(entity.getSleepingPosition().get()).getBlock() instanceof BedBlock;
submergedInWater = entity.isSubmergedInWater(); submergedInWater = entity.isSubmergedInWater();
wobbleAmount = handSwingProgress <= 0 ? 0 : MathHelper.sin(MathHelper.sqrt(getSwingAmount()) * MathHelper.PI * 2) * 0.04F;
if (attributes.isSitting) { if (attributes.isSitting) {
pose = EntityPose.SITTING; pose = EntityPose.SITTING;
} }
@ -53,18 +56,13 @@ public class PonyRenderState extends PlayerEntityRenderState implements PonyMode
|| entity instanceof ZombifiedPiglinEntity || entity instanceof ZombifiedPiglinEntity
) && entity.hasCustomName() && entity.getCustomName().getString().equalsIgnoreCase("technoblade") ) && entity.hasCustomName() && entity.getCustomName().getString().equalsIgnoreCase("technoblade")
); );
size = baby ? SizePreset.FOAL : PonyConfig.getEffectiveSize(attributes.metadata.size());
PonyPosture.of(attributes).updateState(entity, this); PonyPosture.of(attributes).updateState(entity, this);
PonyModelPrepareCallback.EVENT.invoker().onPonyModelPrepared(attributes, model, ModelAttributes.Mode.OTHER); PonyModelPrepareCallback.EVENT.invoker().onPonyModelPrepared(attributes, model, ModelAttributes.Mode.OTHER);
} }
/** @Override
* 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() { public Race getRace() {
return PonyConfig.getEffectiveRace(attributes.metadata.race()); return PonyConfig.getEffectiveRace(attributes.metadata.race());
} }
@ -73,14 +71,6 @@ public class PonyRenderState extends PlayerEntityRenderState implements PonyMode
return getRace().hasHorn() && attributes.metadata.glowColor() != 0; return getRace().hasHorn() && attributes.metadata.glowColor() != 0;
} }
public final float getScaleFactor() {
return getSize().scaleFactor();
}
public final float getShadowSize() {
return getSize().shadowSize();
}
/** /**
* Gets the current leg swing amount. * Gets the current leg swing amount.
*/ */
@ -88,17 +78,6 @@ public class PonyRenderState extends PlayerEntityRenderState implements PonyMode
return this.handSwingProgress; 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() { protected float getLegOutset() {
float outset = attributes.isLyingDown ? 3.6F : attributes.isCrouching ? 1 : 5; float outset = attributes.isLyingDown ? 3.6F : attributes.isCrouching ? 1 : 5;
@ -112,13 +91,10 @@ public class PonyRenderState extends PlayerEntityRenderState implements PonyMode
* Gets the y-offset applied to entities riding this one. * Gets the y-offset applied to entities riding this one.
*/ */
protected float getRiderYOffset() { protected float getRiderYOffset() {
switch ((SizePreset)getSize()) { return switch ((SizePreset)size) {
case NORMAL: return 0.4F; case NORMAL -> 0.4F;
case FOAL: default -> 0.25F;
case TALL: };
case BULKY:
default: return 0.25F;
}
} }
/** /**
@ -141,7 +117,7 @@ public class PonyRenderState extends PlayerEntityRenderState implements PonyMode
float y = -(height + 0.5F); float y = -(height + 0.5F);
// Then we add our own offsets. // Then we add our own offsets.
y += attributes.visualHeight * getScaleFactor() + 0.25F; y += attributes.visualHeight * size.scaleFactor() + 0.25F;
y += vehicleOffset; y += vehicleOffset;
if (isInSneakingPose) { if (isInSneakingPose) {

View file

@ -1,4 +1,7 @@
accessWidener v1 named accessWidener v1 named
accessible class net/minecraft/client/render/VertexConsumers$Union accessible class net/minecraft/client/render/VertexConsumers$Union
accessible method net/minecraft/client/render/entity/GuardianEntityRenderer renderBeam (Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;Lnet/minecraft/util/math/Vec3d;FFF)V
accessible method net/minecraft/client/render/entity/GuardianEntityRenderer getBeamTarget (Lnet/minecraft/entity/mob/GuardianEntity;)Lnet/minecraft/entity/Entity;
extendable method net/minecraft/client/model/Model render (Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;III)V extendable method net/minecraft/client/model/Model render (Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;III)V