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