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