mirror of
https://github.com/MineLittlePony/MineLittlePony.git
synced 2025-02-13 08:14:23 +01:00
Rewrite pretty much everything to make more effective use of java's Records
This commit is contained in:
parent
8eca1796e1
commit
0d226b51f9
110 changed files with 821 additions and 1142 deletions
|
@ -2,8 +2,7 @@ package com.minelittlepony.api.config;
|
|||
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
import com.minelittlepony.api.pony.meta.Race;
|
||||
import com.minelittlepony.api.pony.meta.Sizes;
|
||||
import com.minelittlepony.api.pony.meta.*;
|
||||
import com.minelittlepony.common.util.GamePaths;
|
||||
import com.minelittlepony.common.util.settings.*;
|
||||
|
||||
|
@ -131,4 +130,18 @@ public class PonyConfig extends Config {
|
|||
|
||||
return race;
|
||||
}
|
||||
|
||||
public static Size getEffectiveSize(Size size) {
|
||||
Sizes sz = instance.sizeOverride.get();
|
||||
|
||||
if (sz != Sizes.UNSET) {
|
||||
return sz;
|
||||
}
|
||||
|
||||
if (size == Sizes.UNSET || !instance.sizes.get()) {
|
||||
return Sizes.NORMAL;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package com.minelittlepony.api.model;
|
||||
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
||||
public interface HornedPonyModel<T extends LivingEntity> extends PonyModel<T> {
|
||||
/**
|
||||
* Returns true if this model is being applied to a race that can use magic.
|
||||
*/
|
||||
default boolean hasMagic() {
|
||||
return getRace().hasHorn() && getAttributes().metadata.glowColor() != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this model is currently using magic (horn is lit).
|
||||
*/
|
||||
boolean isCasting();
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
package com.minelittlepony.api.model;
|
||||
|
||||
/**
|
||||
* Interface for models that have a head.
|
||||
*/
|
||||
public interface ICapitated<T> {
|
||||
/**
|
||||
* Gets the head of this capitated object.
|
||||
*/
|
||||
T getHead();
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
package com.minelittlepony.api.model;
|
||||
|
||||
import com.minelittlepony.api.pony.IPonyData;
|
||||
import com.minelittlepony.api.pony.PonyData;
|
||||
|
||||
public interface IModelWrapper {
|
||||
/**
|
||||
* Updates metadata values to this wrapper's contained models.
|
||||
*/
|
||||
IModelWrapper applyMetadata(IPonyData meta);
|
||||
IModelWrapper applyMetadata(PonyData meta);
|
||||
}
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
package com.minelittlepony.api.model;
|
||||
|
||||
public interface IUnicorn extends IModel {
|
||||
/**
|
||||
* Returns true if this model is being applied to a race that can use magic.
|
||||
*/
|
||||
default boolean hasMagic() {
|
||||
return hasHorn() && getMagicColor() != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this model has an visible horns.
|
||||
*/
|
||||
default boolean hasHorn() {
|
||||
return getRace().hasHorn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this model is currently using magic (horn is lit).
|
||||
* @return
|
||||
*/
|
||||
boolean isCasting();
|
||||
|
||||
/**
|
||||
* Gets the preferred magic color for this mode.
|
||||
*/
|
||||
default int getMagicColor() {
|
||||
return getMetadata().glowColor();
|
||||
}
|
||||
}
|
|
@ -1,15 +1,16 @@
|
|||
package com.minelittlepony.client.model;
|
||||
package com.minelittlepony.api.model;
|
||||
|
||||
import net.minecraft.client.model.ModelPart;
|
||||
import net.minecraft.util.Arm;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
import com.minelittlepony.client.model.ClientPonyModel;
|
||||
import com.minelittlepony.mson.util.PartUtil;
|
||||
|
||||
/**
|
||||
* Common interface for all undead enemies.
|
||||
*/
|
||||
public interface IMobModel {
|
||||
public final class MobPosingHelper {
|
||||
/**
|
||||
* Rotates the provided arm to the correct orientation for holding an item.
|
||||
*
|
||||
|
@ -18,7 +19,7 @@ public interface IMobModel {
|
|||
* @param swingProgress How far we are through the current swing
|
||||
* @param ticks Render partial ticks
|
||||
*/
|
||||
static void rotateArmHolding(ModelPart arm, float direction, float swingProgress, float ticks) {
|
||||
public static void rotateArmHolding(ModelPart arm, float direction, float swingProgress, float ticks) {
|
||||
float swing = MathHelper.sin(swingProgress * MathHelper.PI);
|
||||
float roll = MathHelper.sin((1 - (1 - swingProgress) * (1 - swingProgress)) * MathHelper.PI);
|
||||
|
||||
|
@ -33,20 +34,20 @@ public interface IMobModel {
|
|||
arm.roll = cos;
|
||||
}
|
||||
|
||||
static void rotateUndeadArms(ClientPonyModel<?> model, float move, float ticks) {
|
||||
public static void rotateUndeadArms(ClientPonyModel<?> model, float move, float ticks) {
|
||||
ModelPart leftArm = model.getArm(Arm.LEFT);
|
||||
ModelPart rightArm = model.getArm(Arm.RIGHT);
|
||||
|
||||
if (islookAngleRight(move)) {
|
||||
IMobModel.rotateArmHolding(rightArm, 1, model.getSwingAmount(), ticks);
|
||||
rotateArmHolding(rightArm, 1, model.getSwingAmount(), ticks);
|
||||
PartUtil.shift(rightArm, 0.5F, 1.5F, 3);
|
||||
} else {
|
||||
IMobModel.rotateArmHolding(leftArm, -1, model.getSwingAmount(), ticks);
|
||||
rotateArmHolding(leftArm, -1, model.getSwingAmount(), ticks);
|
||||
PartUtil.shift(leftArm, -0.5F, 1.5F, 3);
|
||||
}
|
||||
}
|
||||
|
||||
static boolean islookAngleRight(float move) {
|
||||
public static boolean islookAngleRight(float move) {
|
||||
return MathHelper.sin(move / 20) < 0;
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@ package com.minelittlepony.api.model;
|
|||
|
||||
import com.minelittlepony.api.pony.*;
|
||||
import com.minelittlepony.client.*;
|
||||
import com.minelittlepony.client.pony.PonyData;
|
||||
import com.minelittlepony.common.util.animation.Interpolator;
|
||||
import com.minelittlepony.util.MathUtil;
|
||||
|
||||
|
@ -108,7 +107,7 @@ public class ModelAttributes {
|
|||
/**
|
||||
* Contains the skin metadata associated with this model.
|
||||
*/
|
||||
public IPonyData metadata = PonyData.NULL;
|
||||
public PonyData metadata = PonyData.NULL;
|
||||
|
||||
public Arm mainArm;
|
||||
public Hand activeHand;
|
||||
|
@ -118,11 +117,11 @@ public class ModelAttributes {
|
|||
/**
|
||||
* Checks flying and speed conditions and sets rainboom to true if we're a species with wings and is going faaast.
|
||||
*/
|
||||
public void checkRainboom(LivingEntity entity, boolean hasWings, float ticks) {
|
||||
public void checkRainboom(LivingEntity entity, PonyModel<?> model, float ticks) {
|
||||
Vec3d motion = entity.getVelocity();
|
||||
double zMotion = Math.sqrt(motion.x * motion.x + motion.z * motion.z);
|
||||
|
||||
isGoingFast = (isFlying && hasWings) || isGliding;
|
||||
isGoingFast = (isFlying && model instanceof WingedPonyModel) || isGliding;
|
||||
isGoingFast &= zMotion > 0.4F;
|
||||
isGoingFast |= entity.isUsingRiptide();
|
||||
isGoingFast |= entity.isFallFlying();
|
||||
|
@ -137,12 +136,12 @@ public class ModelAttributes {
|
|||
return (MathHelper.sin(ticks * 0.136f) / 2) + MathUtil.Angles._270_DEG;
|
||||
}
|
||||
if (isFlying) {
|
||||
return MathHelper.sin(ticks * 0.536f) + IPegasus.WINGS_FULL_SPREAD_ANGLE;
|
||||
return MathHelper.sin(ticks * 0.536f) + WingedPonyModel.WINGS_FULL_SPREAD_ANGLE;
|
||||
}
|
||||
return IPegasus.WINGS_RAISED_ANGLE;
|
||||
return WingedPonyModel.WINGS_RAISED_ANGLE;
|
||||
}
|
||||
|
||||
public void updateLivingState(LivingEntity entity, IPony pony, Mode mode) {
|
||||
public void updateLivingState(LivingEntity entity, Pony pony, Mode mode) {
|
||||
visualHeight = entity.getHeight() + 0.125F;
|
||||
isSitting = PonyPosture.isSitting(entity);
|
||||
isCrouching = !isSitting && mode == Mode.THIRD_PERSON && PonyPosture.isCrouching(pony, entity);
|
||||
|
@ -153,7 +152,7 @@ public class ModelAttributes {
|
|||
isSwimmingRotated = isSwimming;
|
||||
isRiptide = entity.isUsingRiptide();
|
||||
isRidingInteractive = PonyPosture.isRidingAPony(entity);
|
||||
if (!(entity instanceof IPreviewModel)) {
|
||||
if (!(entity instanceof PreviewModel)) {
|
||||
interpolatorId = entity.getUuid();
|
||||
}
|
||||
isLeftHanded = entity.getMainArm() == Arm.LEFT;
|
||||
|
|
|
@ -1,66 +1,49 @@
|
|||
package com.minelittlepony.api.model;
|
||||
|
||||
import net.minecraft.client.model.ModelPart;
|
||||
import net.minecraft.client.render.entity.model.*;
|
||||
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.IPonyData;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.PonyData;
|
||||
import com.minelittlepony.api.pony.meta.*;
|
||||
import com.minelittlepony.mson.api.MsonModel;
|
||||
|
||||
public interface PonyModel<T extends LivingEntity> extends MsonModel, ModelWithArms, ModelWithHat, ModelWithHead {
|
||||
|
||||
void copyAttributes(BipedEntityModel<T> other);
|
||||
|
||||
void updateLivingState(T entity, Pony pony, ModelAttributes.Mode mode);
|
||||
|
||||
ModelPart getBodyPart(BodyPart part);
|
||||
|
||||
public interface IModel {
|
||||
/**
|
||||
* Applies a transform particular to a certain body part.
|
||||
*/
|
||||
void transform(BodyPart part, MatrixStack stack);
|
||||
|
||||
/**
|
||||
* Gets the active scaling profile used to lay out this model's parts.
|
||||
*/
|
||||
Size getSize();
|
||||
|
||||
/**
|
||||
* Gets the transitive properties of this model.
|
||||
*/
|
||||
ModelAttributes getAttributes();
|
||||
|
||||
/**
|
||||
* Gets the skin metadata associated with this model.
|
||||
*/
|
||||
default IPonyData getMetadata() {
|
||||
return getAttributes().metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pony metadata object associated with this model.
|
||||
*/
|
||||
void setMetadata(IPonyData meta);
|
||||
void setMetadata(PonyData meta);
|
||||
|
||||
/**
|
||||
* Returns true if the model is flying.
|
||||
* Gets the active scaling profile used to lay out this model's parts.
|
||||
*/
|
||||
default boolean isFlying() {
|
||||
return getAttributes().isFlying && canFly();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this model is riding a boat, horse, or other animals.
|
||||
*
|
||||
* @deprecated User model#getAttributes().isSitting
|
||||
*/
|
||||
@Deprecated
|
||||
default boolean isRiding() {
|
||||
return getAttributes().isSitting;
|
||||
default Size getSize() {
|
||||
return PonyConfig.getEffectiveSize(getAttributes().metadata.size());
|
||||
}
|
||||
|
||||
default Race getRace() {
|
||||
return PonyConfig.getEffectiveRace(getMetadata().race());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this model is being applied to a race that has wings.
|
||||
*/
|
||||
default boolean canFly() {
|
||||
return getRace().hasWings();
|
||||
return PonyConfig.getEffectiveRace(getAttributes().metadata.race());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,7 +55,6 @@ public interface IModel {
|
|||
* Gets the step wobble used for various hair bits and animations.
|
||||
*/
|
||||
default float getWobbleAmount() {
|
||||
|
||||
if (getSwingAmount() <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -97,6 +79,7 @@ public interface IModel {
|
|||
* i.e. Used to change wing rendering when using saddlebags.
|
||||
*/
|
||||
default boolean isEmbedded(Wearable wearable) {
|
||||
return getMetadata().isWearing(wearable);
|
||||
return getAttributes().metadata.isWearing(wearable);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +1,12 @@
|
|||
package com.minelittlepony.api.model;
|
||||
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
import com.minelittlepony.util.MathUtil;
|
||||
|
||||
public interface IPegasus extends IModel {
|
||||
public interface WingedPonyModel<T extends LivingEntity> extends PonyModel<T> {
|
||||
public static final float WINGS_HALF_SPREAD_ANGLE = MathUtil.Angles._270_DEG;
|
||||
public static final float WINGS_FULL_SPREAD_ANGLE = MathUtil.Angles._270_DEG + 0.4F;
|
||||
public static final float WINGS_RAISED_ANGLE = 4;
|
||||
|
@ -13,12 +15,14 @@ public interface IPegasus extends IModel {
|
|||
* Returns true if the wings are spread.
|
||||
*/
|
||||
default boolean wingsAreOpen() {
|
||||
return (getAttributes().isSwimming || isFlying() || getAttributes().isCrouching)
|
||||
return (getAttributes().isSwimming || getAttributes().isFlying || getAttributes().isCrouching)
|
||||
&& (MineLittlePony.getInstance().getConfig().flappyElytras.get() || !getAttributes().isGliding);
|
||||
}
|
||||
|
||||
default boolean isBurdened() {
|
||||
return isWearing(Wearable.SADDLE_BAGS_BOTH) || isWearing(Wearable.SADDLE_BAGS_LEFT) || isWearing(Wearable.SADDLE_BAGS_RIGHT);
|
||||
return isWearing(Wearable.SADDLE_BAGS_BOTH)
|
||||
|| isWearing(Wearable.SADDLE_BAGS_LEFT)
|
||||
|| isWearing(Wearable.SADDLE_BAGS_RIGHT);
|
||||
}
|
||||
|
||||
/**
|
|
@ -3,7 +3,7 @@ package com.minelittlepony.api.model.armour;
|
|||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
||||
import com.minelittlepony.client.model.IPonyModel;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
|
||||
public interface IArmourModel<T extends LivingEntity> {
|
||||
/**
|
||||
|
@ -13,5 +13,5 @@ public interface IArmourModel<T extends LivingEntity> {
|
|||
*/
|
||||
boolean poseModel(T entity, float limbAngle, float limbDistance, float age, float headYaw, float headPitch,
|
||||
EquipmentSlot slot, ArmourLayer layer,
|
||||
IPonyModel<T> mainModel);
|
||||
PonyModel<T> mainModel);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ import net.fabricmc.fabric.api.event.Event;
|
|||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
import net.minecraft.entity.Entity;
|
||||
|
||||
import com.minelittlepony.api.model.IModel;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.api.model.ModelAttributes;
|
||||
|
||||
public interface PonyModelPrepareCallback {
|
||||
|
@ -15,5 +15,5 @@ public interface PonyModelPrepareCallback {
|
|||
}
|
||||
});
|
||||
|
||||
void onPonyModelPrepared(Entity entity, IModel model, ModelAttributes.Mode mode);
|
||||
void onPonyModelPrepared(Entity entity, PonyModel<?> model, ModelAttributes.Mode mode);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package com.minelittlepony.client.model.gear;
|
||||
package com.minelittlepony.api.model.gear;
|
||||
|
||||
import net.minecraft.client.model.Model;
|
||||
import net.minecraft.client.model.ModelPart;
|
||||
|
@ -6,22 +6,24 @@ import net.minecraft.client.render.RenderLayer;
|
|||
import net.minecraft.client.render.VertexConsumer;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
||||
import com.minelittlepony.api.model.gear.IGear;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class AbstractGear extends Model implements IGear {
|
||||
public abstract class AbstractGearModel extends Model implements Gear {
|
||||
|
||||
private final List<ModelPart> parts = new ArrayList<>();
|
||||
|
||||
public AbstractGear() {
|
||||
private final float stackingHeight;
|
||||
|
||||
public AbstractGearModel(float stackingHeight) {
|
||||
super(RenderLayer::getEntitySolid);
|
||||
this.stackingHeight = stackingHeight;
|
||||
}
|
||||
|
||||
public void addPart(ModelPart t) {
|
||||
public AbstractGearModel addPart(ModelPart t) {
|
||||
parts.add(t);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -35,4 +37,14 @@ public abstract class AbstractGear extends Model implements IGear {
|
|||
part.render(stack, renderContext, overlayUv, lightUv, red, green, blue, alpha);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStackable() {
|
||||
return stackingHeight > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getStackingHeight() {
|
||||
return stackingHeight;
|
||||
}
|
||||
}
|
|
@ -7,10 +7,8 @@ import net.minecraft.client.util.math.MatrixStack;
|
|||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import com.minelittlepony.api.model.BodyPart;
|
||||
import com.minelittlepony.api.model.IModel;
|
||||
import com.minelittlepony.api.model.*;
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
import com.minelittlepony.client.model.IPonyModel;
|
||||
import com.minelittlepony.client.render.entity.feature.GearFeature;
|
||||
|
||||
import java.util.UUID;
|
||||
|
@ -19,13 +17,13 @@ import java.util.function.Supplier;
|
|||
/**
|
||||
* Interface for an accessory on a pony's body.
|
||||
*/
|
||||
public interface IGear {
|
||||
public interface Gear {
|
||||
/**
|
||||
* Registers a custom gear to be used with the mod.
|
||||
* <p>
|
||||
* This would be awesome for creating socks.
|
||||
*/
|
||||
static Supplier<IGear> register(Supplier<IGear> gear) {
|
||||
static Supplier<Gear> register(Supplier<Gear> gear) {
|
||||
GearFeature.addModGear(gear);
|
||||
return gear;
|
||||
}
|
||||
|
@ -38,13 +36,26 @@ public interface IGear {
|
|||
*
|
||||
* @return True to render this wearable
|
||||
*/
|
||||
boolean canRender(IModel model, Entity entity);
|
||||
boolean canRender(PonyModel<?> model, Entity entity);
|
||||
|
||||
/**
|
||||
* Gets the body location that this wearable appears on.
|
||||
*/
|
||||
BodyPart getGearLocation();
|
||||
|
||||
default boolean isStackable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* The vertical height of this gear when present in a stack.
|
||||
*
|
||||
* Any gear rendered after this one will be shifted to sit on top of it.
|
||||
*/
|
||||
default float getStackingHeight() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the texture to use for this wearable.
|
||||
*
|
||||
|
@ -62,7 +73,7 @@ public interface IGear {
|
|||
/**
|
||||
* Applies body transformations for this wearable
|
||||
*/
|
||||
default <M extends EntityModel<?> & IPonyModel<?>> void transform(M model, MatrixStack matrices) {
|
||||
default <M extends EntityModel<?> & PonyModel<?>> void transform(M model, MatrixStack matrices) {
|
||||
BodyPart part = getGearLocation();
|
||||
model.transform(part, matrices);
|
||||
model.getBodyPart(part).rotate(matrices);
|
||||
|
@ -73,23 +84,10 @@ public interface IGear {
|
|||
*
|
||||
* See {@link AbstractPonyMode.setRotationAndAngle} for an explanation of the various parameters.
|
||||
*/
|
||||
default void pose(IModel model, Entity entity, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
|
||||
setModelAttributes(model, entity);
|
||||
pose(rainboom, interpolatorId, move, swing, bodySwing, ticks);
|
||||
default void pose(PonyModel<?> model, Entity entity, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use pose(model, entity, rainboom, interpolatorId, move, swing, bodySwing, ticks) instead
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
default void setModelAttributes(IModel model, Entity entity) { }
|
||||
|
||||
/**
|
||||
* @deprecated Use pose(model, entity, rainboom, interpolatorId, move, swing, bodySwing, ticks) instead
|
||||
*/
|
||||
@Deprecated(forRemoval = true)
|
||||
default void pose(boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) { }
|
||||
|
||||
/**
|
||||
* Renders this model component.
|
||||
*/
|
||||
|
@ -101,7 +99,7 @@ public interface IGear {
|
|||
* @param <T> The type of entity being rendered.
|
||||
* @param <M> The type of the entity's primary model.
|
||||
*/
|
||||
public interface Context<T extends Entity, M extends IModel> {
|
||||
public interface Context<T extends Entity, M extends PonyModel<?>> {
|
||||
/**
|
||||
* The empty context.
|
||||
*/
|
||||
|
@ -110,7 +108,7 @@ public interface IGear {
|
|||
/**
|
||||
* 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, IGear gear) {
|
||||
default boolean shouldRender(M model, T entity, Wearable wearable, Gear gear) {
|
||||
return gear.canRender(model, entity);
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
package com.minelittlepony.api.model.gear;
|
||||
|
||||
/**
|
||||
* Interface for any gear that changes its position based on where it is in the hat stack.
|
||||
*/
|
||||
public interface IStackable {
|
||||
/**
|
||||
* The vertical height of this gear when present in a stack.
|
||||
*
|
||||
* Any gear rendered after this one will be shifted to sit on top of it.
|
||||
*/
|
||||
float getStackingHeight();
|
||||
|
||||
}
|
|
@ -1,18 +1,19 @@
|
|||
package com.minelittlepony.client.model.gear;
|
||||
package com.minelittlepony.api.model.gear;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import com.minelittlepony.api.model.BodyPart;
|
||||
import com.minelittlepony.api.model.IModel;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
|
||||
public abstract class AbstractWearableGear extends AbstractGear {
|
||||
public class WearableGear extends AbstractGearModel {
|
||||
|
||||
protected final Wearable wearable;
|
||||
protected final BodyPart location;
|
||||
|
||||
protected AbstractWearableGear(Wearable wearable, BodyPart location) {
|
||||
public WearableGear(Wearable wearable, BodyPart location, float stackingHeight) {
|
||||
super(stackingHeight);
|
||||
this.wearable = wearable;
|
||||
this.location = location;
|
||||
}
|
||||
|
@ -23,7 +24,7 @@ public abstract class AbstractWearableGear extends AbstractGear {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canRender(IModel model, Entity entity) {
|
||||
public boolean canRender(PonyModel<?> model, Entity entity) {
|
||||
return model.isWearing(wearable);
|
||||
}
|
||||
|
|
@ -28,7 +28,7 @@ public final class DefaultPonySkinHelper {
|
|||
|
||||
public static String getModelType(UUID id) {
|
||||
SkinTextures textures = DefaultSkinHelper.getTexture(id);
|
||||
return getModelType(IPony.getManager().getPony(textures.texture(), id).race(), textures.model());
|
||||
return getModelType(Pony.getManager().getPony(textures.texture(), id).race(), textures.model());
|
||||
}
|
||||
|
||||
public static String getModelType(Race race, SkinTextures.Model armShape) {
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
package com.minelittlepony.api.pony;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.google.common.collect.ComparisonChain;
|
||||
import com.minelittlepony.api.pony.meta.*;
|
||||
import com.minelittlepony.common.util.animation.Interpolator;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Metadata for a pony.
|
||||
*/
|
||||
public interface IPonyData extends Comparable<IPonyData> {
|
||||
/**
|
||||
* Gets this pony's race.
|
||||
*
|
||||
* This is the actual race value. For the effective race, prefer going through {@link IPony#race}
|
||||
*/
|
||||
Race race();
|
||||
|
||||
/**
|
||||
* Gets the length of the pony's tail.
|
||||
*/
|
||||
TailLength tailLength();
|
||||
|
||||
/**
|
||||
* Gets the shape of the pony's tail.
|
||||
*/
|
||||
TailShape tailShape();
|
||||
|
||||
/**
|
||||
* Get the pony's gender (usually female).
|
||||
*/
|
||||
Gender gender();
|
||||
|
||||
/**
|
||||
* Gets the current pony size.
|
||||
*/
|
||||
Size size();
|
||||
|
||||
/**
|
||||
* Gets the magical glow colour for magic-casting races. Returns 0 otherwise.
|
||||
*/
|
||||
int glowColor();
|
||||
|
||||
/**
|
||||
* Returns an array of wearables that this pony is carrying.
|
||||
*/
|
||||
Wearable[] gear();
|
||||
|
||||
/**
|
||||
* Checks it this pony is wearing the given accessory.
|
||||
*/
|
||||
boolean isWearing(Wearable wearable);
|
||||
|
||||
/**
|
||||
* Gets an interpolator for interpolating values.
|
||||
*/
|
||||
default Interpolator getInterpolator(UUID interpolatorId) {
|
||||
return Interpolator.linear(interpolatorId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the trigger pixel values as they appeared in the underlying image.
|
||||
*/
|
||||
Map<String, TriggerPixelType<?>> attributes();
|
||||
|
||||
@Override
|
||||
default int compareTo(@Nullable IPonyData o) {
|
||||
return o == this ? 0 : o == null ? 1 : ComparisonChain.start()
|
||||
.compare(race(), o.race())
|
||||
.compare(tailLength(), o.tailLength())
|
||||
.compare(gender(), o.gender())
|
||||
.compare(size().ordinal(), o.size().ordinal())
|
||||
.compare(glowColor(), o.glowColor())
|
||||
.compare(0, Arrays.compare(gear(), o.gear()))
|
||||
.result();
|
||||
}
|
||||
}
|
|
@ -7,64 +7,64 @@ import org.jetbrains.annotations.Nullable;
|
|||
import com.google.common.collect.ComparisonChain;
|
||||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.api.pony.meta.Race;
|
||||
import com.minelittlepony.api.pony.meta.Size;
|
||||
|
||||
public interface IPony extends Comparable<IPony> {
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public record Pony (
|
||||
/**
|
||||
* Gets the texture used for rendering this pony.
|
||||
*/
|
||||
Identifier texture,
|
||||
Supplier<Optional<PonyData>> metadataGetter
|
||||
) implements Comparable<Pony> {
|
||||
/**
|
||||
* Gets the global pony manager instance.
|
||||
*/
|
||||
static IPonyManager getManager() {
|
||||
return IPonyManager.Instance.instance;
|
||||
public static PonyManager getManager() {
|
||||
return PonyManager.Instance.instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets or creates a new pony associated with the provided resource location.
|
||||
* The results of this method should not be cached.
|
||||
*
|
||||
* @deprecated User IPony.getManager().getPony(texture) instead
|
||||
* Gets the metadata associated with this pony's model texture.
|
||||
*/
|
||||
@Deprecated
|
||||
static IPony forResource(Identifier texture) {
|
||||
return getManager().getPony(texture);
|
||||
public PonyData metadata() {
|
||||
return metadataGetter().get().orElse(PonyData.NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this is one of the default ponies assigned to a player without a custom skin.
|
||||
*/
|
||||
boolean defaulted();
|
||||
|
||||
/**
|
||||
* Returns whether this pony's metadata block has been initialized.
|
||||
*/
|
||||
boolean hasMetadata();
|
||||
public boolean hasMetadata() {
|
||||
return metadataGetter().get().isPresent();
|
||||
}
|
||||
|
||||
public Pony immutableCopy() {
|
||||
final Optional<PonyData> metadata = metadataGetter().get();
|
||||
return new Pony(texture(), () -> metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the race associated with this pony.
|
||||
*/
|
||||
default Race race() {
|
||||
public Race race() {
|
||||
return PonyConfig.getEffectiveRace(metadata().race());
|
||||
}
|
||||
|
||||
public Size size() {
|
||||
return PonyConfig.getEffectiveSize(metadata().size());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if and only if this metadata represents a pony that can cast magic.
|
||||
*/
|
||||
default boolean hasMagic() {
|
||||
public boolean hasMagic() {
|
||||
return race().hasHorn() && metadata().glowColor() != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the texture used for rendering this pony.
|
||||
*/
|
||||
Identifier texture();
|
||||
|
||||
/**
|
||||
* Gets the metadata associated with this pony's model texture.
|
||||
*/
|
||||
IPonyData metadata();
|
||||
|
||||
|
||||
@Override
|
||||
default int compareTo(@Nullable IPony o) {
|
||||
public int compareTo(@Nullable Pony o) {
|
||||
return o == this ? 0 : o == null ? 1 : ComparisonChain.start()
|
||||
.compare(texture(), o.texture())
|
||||
.compare(metadata(), o.metadata())
|
127
src/main/java/com/minelittlepony/api/pony/PonyData.java
Normal file
127
src/main/java/com/minelittlepony/api/pony/PonyData.java
Normal file
|
@ -0,0 +1,127 @@
|
|||
package com.minelittlepony.api.pony;
|
||||
|
||||
import net.minecraft.util.Util;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.google.common.collect.ComparisonChain;
|
||||
import com.minelittlepony.api.pony.meta.*;
|
||||
import com.minelittlepony.common.util.animation.Interpolator;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Metadata for a pony.
|
||||
*/
|
||||
public record PonyData (
|
||||
/**
|
||||
* Gets this pony's race.
|
||||
*
|
||||
* This is the actual race value. For the effective race, prefer going through {@link Pony#race}
|
||||
*/
|
||||
Race race,
|
||||
/**
|
||||
* Gets the length of the pony's tail.
|
||||
*/
|
||||
TailLength tailLength,
|
||||
/**
|
||||
* Gets the shape of the pony's tail.
|
||||
*/
|
||||
TailShape tailShape,
|
||||
/**
|
||||
* Get the pony's gender (usually female).
|
||||
*/
|
||||
Gender gender,
|
||||
/**
|
||||
* Gets the current pony size.
|
||||
*/
|
||||
Size size,
|
||||
/**
|
||||
* Gets the magical glow colour for magic-casting races. Returns 0 otherwise.
|
||||
*/
|
||||
int glowColor,
|
||||
/**
|
||||
* Returns an array of wearables that this pony is carrying.
|
||||
*/
|
||||
Flags<Wearable> gear,
|
||||
/**
|
||||
* Indicates whether this pony data corresponds to one of the default/built-in skins
|
||||
* rather than a user-uploaded one.
|
||||
*/
|
||||
boolean noSkin,
|
||||
/**
|
||||
* Gets the trigger pixel values as they appeared in the underlying image.
|
||||
*/
|
||||
Map<String, TriggerPixelType<?>> attributes
|
||||
) implements Comparable<PonyData> {
|
||||
private static final Function<Race, PonyData> OF_RACE = Util.memoize(race -> {
|
||||
return new PonyData(race, TailLength.FULL, TailShape.STRAIGHT, Gender.MARE, Sizes.NORMAL, 0x4444aa, Wearable.EMPTY_FLAGS, true, Util.make(new TreeMap<>(), attributes -> {
|
||||
attributes.put("race", race);
|
||||
attributes.put("tailLength", TailLength.FULL);
|
||||
attributes.put("tailShape", TailShape.STRAIGHT);
|
||||
attributes.put("gender", Gender.MARE);
|
||||
attributes.put("size", Sizes.NORMAL);
|
||||
attributes.put("magic", TriggerPixelType.of(0x4444aa));
|
||||
attributes.put("gear", TriggerPixelType.of(0));
|
||||
}));
|
||||
});
|
||||
public static final PonyData NULL = OF_RACE.apply(Race.HUMAN);
|
||||
|
||||
public static PonyData emptyOf(Race race) {
|
||||
return OF_RACE.apply(race);
|
||||
}
|
||||
|
||||
|
||||
public PonyData(Race race, TailLength tailLength, TailShape tailShape, Gender gender, Size size, int glowColor, boolean noSkin, Flags<Wearable> wearables) {
|
||||
this(race, tailLength, tailShape, gender, size, glowColor, wearables, noSkin, Util.make(new TreeMap<>(), map -> {
|
||||
map.put("race", race);
|
||||
map.put("tailLength", tailLength);
|
||||
map.put("tailShape", tailShape);
|
||||
map.put("gender", gender);
|
||||
map.put("size", size);
|
||||
map.put("magic", TriggerPixelType.of(glowColor));
|
||||
map.put("gear", TriggerPixelType.of(wearables.colorCode()));
|
||||
}));
|
||||
}
|
||||
public PonyData(Race race, TailLength tailLength, TailShape tailShape, Gender gender, Size size, int glowColor, TriggerPixelType.Multiple<Wearable> wearables, boolean noSkin) {
|
||||
this(race, tailLength, tailShape, gender, size, glowColor,
|
||||
Flags.of(Wearable.class, wearables.colorCode(), wearables.value()),
|
||||
noSkin, Util.make(new TreeMap<>(), map -> {
|
||||
map.put("race", race);
|
||||
map.put("tailLength", tailLength);
|
||||
map.put("tailShape", tailShape);
|
||||
map.put("gender", gender);
|
||||
map.put("size", size);
|
||||
map.put("magic", TriggerPixelType.of(glowColor));
|
||||
map.put("gear", wearables);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks it this pony is wearing the given accessory.
|
||||
*/
|
||||
public boolean isWearing(Wearable wearable) {
|
||||
return gear().includes(wearable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an interpolator for interpolating values.
|
||||
*/
|
||||
public Interpolator getInterpolator(UUID interpolatorId) {
|
||||
return Interpolator.linear(interpolatorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@Nullable PonyData o) {
|
||||
return o == this ? 0 : o == null ? 1 : ComparisonChain.start()
|
||||
.compare(race(), o.race())
|
||||
.compare(tailLength(), o.tailLength())
|
||||
.compare(gender(), o.gender())
|
||||
.compare(size().ordinal(), o.size().ordinal())
|
||||
.compare(glowColor(), o.glowColor())
|
||||
.compare(0, gear().compareTo(o.gear()))
|
||||
.result();
|
||||
}
|
||||
}
|
|
@ -13,13 +13,13 @@ import java.util.UUID;
|
|||
* The PonyManager is responsible for reading and recoding all the pony data associated with an entity of skin.
|
||||
*
|
||||
*/
|
||||
public interface IPonyManager {
|
||||
public interface PonyManager {
|
||||
/**
|
||||
* Gets a pony representation of the passed in entity.
|
||||
*
|
||||
* If the supplied entity is null or can't be determined to be a pony, returns the empty optional.
|
||||
*/
|
||||
Optional<IPony> getPony(@Nullable Entity entity);
|
||||
Optional<Pony> getPony(@Nullable Entity entity);
|
||||
|
||||
/**
|
||||
* Gets or creates a pony for the given player.
|
||||
|
@ -27,14 +27,14 @@ public interface IPonyManager {
|
|||
*
|
||||
* @param player the player
|
||||
*/
|
||||
IPony getPony(PlayerEntity player);
|
||||
Pony getPony(PlayerEntity player);
|
||||
|
||||
/**
|
||||
* Gets or creates a pony for the given skin resource and vanilla model type.
|
||||
*
|
||||
* @param resource A texture resource
|
||||
*/
|
||||
IPony getPony(Identifier resource);
|
||||
Pony getPony(Identifier resource);
|
||||
|
||||
/**
|
||||
* Gets or creates a pony for the given skin resource and entity id.
|
||||
|
@ -46,7 +46,7 @@ public interface IPonyManager {
|
|||
* @param resource A texture resource
|
||||
* @param uuid id of a player
|
||||
*/
|
||||
IPony getPony(Identifier resource, UUID uuid);
|
||||
Pony getPony(Identifier resource, UUID uuid);
|
||||
|
||||
/**
|
||||
* Gets a random background pony determined by the given uuid.
|
||||
|
@ -55,16 +55,18 @@ public interface IPonyManager {
|
|||
*
|
||||
* @param uuid A UUID. Either a user or an entity.
|
||||
*/
|
||||
IPony getBackgroundPony(UUID uuid);
|
||||
Pony getBackgroundPony(UUID uuid);
|
||||
|
||||
/**
|
||||
* De-registers a pony from the cache.
|
||||
*/
|
||||
void removePony(Identifier resource);
|
||||
|
||||
void clearCache();
|
||||
|
||||
interface ForcedPony {}
|
||||
|
||||
final class Instance {
|
||||
public static IPonyManager instance;
|
||||
public static PonyManager instance;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
package com.minelittlepony.api.pony;
|
||||
|
||||
import com.minelittlepony.api.pony.meta.Race;
|
||||
import com.minelittlepony.client.IPreviewModel;
|
||||
import com.minelittlepony.client.PreviewModel;
|
||||
import com.minelittlepony.client.SkinsProxy;
|
||||
import com.minelittlepony.client.render.entity.AquaticPlayerPonyRenderer;
|
||||
|
||||
|
@ -17,13 +17,13 @@ import net.minecraft.util.math.BlockPos;
|
|||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public final class PonyPosture {
|
||||
public static Optional<IPony> getMountPony(LivingEntity entity) {
|
||||
public static Optional<Pony> getMountPony(LivingEntity entity) {
|
||||
return entity.getVehicle() instanceof LivingEntity mount
|
||||
? IPony.getManager().getPony(mount)
|
||||
? Pony.getManager().getPony(mount)
|
||||
: Optional.empty();
|
||||
}
|
||||
|
||||
public static boolean isCrouching(IPony pony, LivingEntity entity) {
|
||||
public static boolean isCrouching(Pony pony, LivingEntity entity) {
|
||||
boolean isSneak = entity.isInSneakingPose();
|
||||
boolean isFlying = isFlying(entity);
|
||||
boolean isSwimming = isSwimming(entity);
|
||||
|
@ -31,7 +31,7 @@ public final class PonyPosture {
|
|||
return !isPerformingRainboom(pony, entity) && !isSwimming && isSneak && !isFlying;
|
||||
}
|
||||
|
||||
private static boolean isPerformingRainboom(IPony pony, LivingEntity entity) {
|
||||
private static boolean isPerformingRainboom(Pony pony, LivingEntity entity) {
|
||||
Vec3d motion = entity.getVelocity();
|
||||
double zMotion = Math.sqrt(motion.x * motion.x + motion.z * motion.z);
|
||||
|
||||
|
@ -85,21 +85,21 @@ public final class PonyPosture {
|
|||
}
|
||||
|
||||
public static boolean isRidingAPony(LivingEntity entity) {
|
||||
return isSitting(entity) && getMountPony(entity).map(IPony::race).orElse(Race.HUMAN) != Race.HUMAN;
|
||||
return isSitting(entity) && getMountPony(entity).map(Pony::race).orElse(Race.HUMAN) != Race.HUMAN;
|
||||
}
|
||||
|
||||
public static boolean isSeaponyModifier(LivingEntity entity) {
|
||||
if (entity instanceof IPreviewModel preview) {
|
||||
if (entity instanceof PreviewModel preview) {
|
||||
return preview.forceSeapony();
|
||||
}
|
||||
return hasSeaponyForm(entity) && isPartiallySubmerged(entity);
|
||||
}
|
||||
|
||||
public static boolean hasSeaponyForm(LivingEntity entity) {
|
||||
if (entity instanceof IPreviewModel preview) {
|
||||
if (entity instanceof PreviewModel preview) {
|
||||
return preview.forceSeapony();
|
||||
}
|
||||
return IPony.getManager().getPony(entity).filter(pony -> {
|
||||
return Pony.getManager().getPony(entity).filter(pony -> {
|
||||
return (pony.race() == Race.SEAPONY
|
||||
|| (entity instanceof AbstractClientPlayerEntity player && SkinsProxy.instance.getSkin(AquaticPlayerPonyRenderer.SKIN_TYPE_ID, player).isPresent())
|
||||
);
|
||||
|
|
53
src/main/java/com/minelittlepony/api/pony/meta/Flags.java
Normal file
53
src/main/java/com/minelittlepony/api/pony/meta/Flags.java
Normal file
|
@ -0,0 +1,53 @@
|
|||
package com.minelittlepony.api.pony.meta;
|
||||
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public record Flags<T extends Enum<T>> (
|
||||
boolean[] flags,
|
||||
List<T> values,
|
||||
int colorCode
|
||||
) implements Comparable<Flags<T>> {
|
||||
|
||||
public static <T extends Enum<T>> Flags<T> of(Class<T> type) {
|
||||
return new Flags<>(new boolean[type.getEnumConstants().length], List.<T>of(), 0);
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> Flags<T> of(Class<T> type, int colorCode, boolean...flags) {
|
||||
return new Flags<>(flags, flags(type.getEnumConstants(), flags), colorCode);
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> Flags<T> read(Class<T> type, PacketByteBuf buffer) {
|
||||
int length = buffer.readVarInt();
|
||||
List<T> values = new ArrayList<>();
|
||||
T[] all = type.getEnumConstants();
|
||||
boolean[] flags = new boolean[all.length];
|
||||
for (int i = 0; i < length; i++) {
|
||||
values.add(all[buffer.readInt()]);
|
||||
flags[i] = true;
|
||||
}
|
||||
return new Flags<>(flags, values, buffer.readInt());
|
||||
}
|
||||
|
||||
public static <T> List<T> flags(T[] values, boolean[] flags) {
|
||||
List<T> wears = new ArrayList<>();
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
if (flags[i]) wears.add(values[i]);
|
||||
}
|
||||
return wears;
|
||||
}
|
||||
|
||||
public boolean includes(T t) {
|
||||
return flags[t.ordinal()];
|
||||
}
|
||||
|
||||
public int compareTo(Flags<T> other) {
|
||||
return Arrays.compare(flags, other.flags);
|
||||
}
|
||||
|
||||
public void write(PacketByteBuf buffer) {
|
||||
buffer.writeCollection(values, (buf, value) -> buf.writeInt(value.ordinal()));
|
||||
buffer.writeInt(colorCode);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
package com.minelittlepony.api.pony.meta;
|
||||
|
||||
import com.minelittlepony.api.pony.TriggerPixelType;
|
||||
|
||||
public enum Gender implements TriggerPixelType<Gender> {
|
||||
MARE(0),
|
||||
STALLION(0xffffff),
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package com.minelittlepony.api.pony.meta;
|
||||
|
||||
import com.minelittlepony.api.pony.TriggerPixelType;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public enum Race implements TriggerPixelType<Race> {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package com.minelittlepony.api.pony.meta;
|
||||
|
||||
import com.minelittlepony.api.pony.TriggerPixelType;
|
||||
|
||||
/**
|
||||
* Represents the different model sizes that are possible.
|
||||
*
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package com.minelittlepony.api.pony.meta;
|
||||
|
||||
import com.minelittlepony.api.pony.TriggerPixelType;
|
||||
|
||||
public enum TailLength implements TriggerPixelType<TailLength> {
|
||||
STUB (0x425844),
|
||||
QUARTER (0xd19fe4),
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package com.minelittlepony.api.pony.meta;
|
||||
|
||||
import com.minelittlepony.api.pony.TriggerPixelType;
|
||||
|
||||
public enum TailShape implements TriggerPixelType<TailShape> {
|
||||
STRAIGHT(0),
|
||||
BUMPY (0xfc539f),
|
||||
|
|
|
@ -2,7 +2,6 @@ package com.minelittlepony.api.pony.meta;
|
|||
|
||||
import net.minecraft.client.texture.NativeImage;
|
||||
|
||||
import com.minelittlepony.api.pony.TriggerPixelType;
|
||||
import com.minelittlepony.common.util.Color;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
@ -21,12 +20,12 @@ public enum TriggerPixel {
|
|||
WEARABLES(Wearable.NONE, Channel.RAW, 1, 1),
|
||||
TAIL_SHAPE(TailShape.STRAIGHT, Channel.ALL, 2, 1);
|
||||
|
||||
private int x;
|
||||
private int y;
|
||||
private final int x;
|
||||
private final int y;
|
||||
|
||||
private Channel channel;
|
||||
private final Channel channel;
|
||||
|
||||
TriggerPixelType<?> def;
|
||||
private final TriggerPixelType<?> def;
|
||||
|
||||
private static final TriggerPixel[] VALUES = values();
|
||||
private static final int MAX_READ_X = Arrays.stream(VALUES).mapToInt(i -> i.x).max().getAsInt();
|
||||
|
@ -53,20 +52,20 @@ public enum TriggerPixel {
|
|||
*
|
||||
* @param image Image to read
|
||||
*/
|
||||
public <T extends TriggerPixelType<T>> TriggerPixelType.Value<T> readValue(NativeImage image) {
|
||||
public <T extends TriggerPixelType<T>> T readValue(NativeImage image) {
|
||||
int color = readColor(image);
|
||||
|
||||
if (Channel.ALPHA.readValue(x, y, image) < 255) {
|
||||
return new TriggerPixelType.Value<>(color, (T)def);
|
||||
return (T)def;
|
||||
}
|
||||
|
||||
return new TriggerPixelType.Value<>(color, TriggerPixelType.getByTriggerPixel((T)def, color));
|
||||
return TriggerPixelType.getByTriggerPixel((T)def, color);
|
||||
}
|
||||
|
||||
public <T extends Enum<T> & TriggerPixelType<T>> TriggerPixelType.Flags<T> readFlags(NativeImage image) {
|
||||
public <T extends Enum<T> & TriggerPixelType<T>> TriggerPixelType.Multiple<T> readFlags(NativeImage image) {
|
||||
boolean[] out = new boolean[def.getClass().getEnumConstants().length];
|
||||
readFlags(out, image);
|
||||
return new TriggerPixelType.Flags<>(readColor(image), (T)def, out);
|
||||
return new TriggerPixelType.Multiple<>(readColor(image), (T)def, out);
|
||||
}
|
||||
|
||||
public <T extends Enum<T> & TriggerPixelType<T>> void readFlags(boolean[] out, NativeImage image) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package com.minelittlepony.api.pony;
|
||||
package com.minelittlepony.api.pony.meta;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
@ -73,7 +73,7 @@ public interface TriggerPixelType<T> {
|
|||
return "#" + v;
|
||||
}
|
||||
|
||||
public record Flags<T extends Enum<T> & TriggerPixelType<T>> (
|
||||
public record Multiple<T extends Enum<T> & TriggerPixelType<T>> (
|
||||
int colorCode,
|
||||
T def,
|
||||
boolean[] value
|
||||
|
@ -94,21 +94,4 @@ public interface TriggerPixelType<T> {
|
|||
return o.getClass() == def.getClass() && value()[((Enum<?>)o).ordinal()];
|
||||
}
|
||||
}
|
||||
|
||||
public record Value<T> (
|
||||
int colorCode,
|
||||
T value
|
||||
) implements TriggerPixelType<T> {
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return value instanceof TriggerPixelType t ? t.name() : TriggerPixelType.super.name();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <Option extends TriggerPixelType<T>> List<Option> getOptions() {
|
||||
return value instanceof TriggerPixelType t ? t.getOptions() : TriggerPixelType.super.getOptions();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@ package com.minelittlepony.api.pony.meta;
|
|||
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import com.minelittlepony.api.pony.TriggerPixelType;
|
||||
import com.minelittlepony.client.model.gear.SaddleBags;
|
||||
import com.minelittlepony.common.util.Color;
|
||||
|
||||
|
@ -30,6 +29,8 @@ public enum Wearable implements TriggerPixelType<Wearable> {
|
|||
public static final List<Wearable> VALUES = Arrays.stream(values()).toList();
|
||||
public static final Map<Identifier, Wearable> REGISTRY = VALUES.stream().collect(Collectors.toMap(Wearable::getId, Function.identity()));
|
||||
|
||||
public static final Flags<Wearable> EMPTY_FLAGS = Flags.of(Wearable.class);
|
||||
|
||||
Wearable(int pixel, Identifier texture) {
|
||||
triggerValue = pixel;
|
||||
id = new Identifier("minelittlepony", name().toLowerCase(Locale.ROOT));
|
||||
|
@ -57,20 +58,4 @@ public enum Wearable implements TriggerPixelType<Wearable> {
|
|||
public int getChannelAdjustedColorCode() {
|
||||
return triggerValue == 0 ? 0 : Color.argbToHex(255, triggerValue, triggerValue, triggerValue);
|
||||
}
|
||||
|
||||
public static boolean[] flags(Wearable[] wears) {
|
||||
boolean[] flags = new boolean[VALUES.size()];
|
||||
for (int i = 0; i < wears.length; i++) {
|
||||
flags[wears[i].ordinal()] = true;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
public static Wearable[] flags(boolean[] flags) {
|
||||
List<Wearable> wears = new ArrayList<>();
|
||||
for (int i = 0; i < VALUES.size(); i++) {
|
||||
if (flags[i]) wears.add(VALUES.get(i));
|
||||
}
|
||||
return wears.toArray(new Wearable[0]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,177 +1,46 @@
|
|||
package com.minelittlepony.api.pony.network;
|
||||
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.util.Util;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.minelittlepony.api.pony.IPonyData;
|
||||
import com.minelittlepony.api.pony.TriggerPixelType;
|
||||
import com.minelittlepony.api.pony.PonyData;
|
||||
import com.minelittlepony.api.pony.meta.*;
|
||||
import com.minelittlepony.common.util.animation.Interpolator;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class MsgPonyData implements IPonyData {
|
||||
public class MsgPonyData {
|
||||
private static final short API_IDENTIFIER = (short) 0xABCD;
|
||||
// API version - increment this number before any time any data is added/removed/moved in the data stream
|
||||
private static final byte API_VERSION = 2;
|
||||
|
||||
private final Race race;
|
||||
private final TailLength tailLength;
|
||||
private final TailShape tailShape;
|
||||
private final Gender gender;
|
||||
private final Size size;
|
||||
private final int glowColor;
|
||||
|
||||
private final boolean noSkin;
|
||||
|
||||
private final int wearableColor;
|
||||
private final boolean[] wearables;
|
||||
|
||||
private final Supplier<Map<String, TriggerPixelType<?>>> triggerPixels = Suppliers.memoize(() -> Util.make(new TreeMap<>(), this::initTriggerPixels));
|
||||
private void initTriggerPixels(Map<String, TriggerPixelType<?>> map) {
|
||||
map.put("race", race);
|
||||
map.put("tailLength", tailLength);
|
||||
map.put("tailShape", tailShape);
|
||||
map.put("gender", gender);
|
||||
map.put("size", size);
|
||||
map.put("magic", TriggerPixelType.of(glowColor));
|
||||
map.put("gear", TriggerPixelType.of(wearableColor));
|
||||
}
|
||||
|
||||
public MsgPonyData(PacketByteBuf buffer) {
|
||||
public static PonyData read(PacketByteBuf buffer) {
|
||||
short data = buffer.readShort();
|
||||
if (data != API_IDENTIFIER || buffer.readByte() != API_VERSION) {
|
||||
race = null;
|
||||
tailLength = null;
|
||||
tailShape = null;
|
||||
gender = null;
|
||||
size = null;
|
||||
glowColor = 0;
|
||||
noSkin = true;
|
||||
wearables = null;
|
||||
wearableColor = 0;
|
||||
return;
|
||||
return PonyData.NULL;
|
||||
}
|
||||
race = buffer.readEnumConstant(Race.class);
|
||||
tailLength = buffer.readEnumConstant(TailLength.class);
|
||||
tailShape = buffer.readEnumConstant(TailShape.class);
|
||||
gender = buffer.readEnumConstant(Gender.class);
|
||||
size = new MsgSize(buffer);
|
||||
glowColor = buffer.readInt();
|
||||
noSkin = buffer.readBoolean();
|
||||
Wearable[] gear = new Wearable[buffer.readInt()];
|
||||
Wearable[] all = Wearable.values();
|
||||
for (int i = 0; i < gear.length; i++) {
|
||||
gear[i] = all[buffer.readInt()];
|
||||
}
|
||||
wearables = Wearable.flags(gear);
|
||||
wearableColor = buffer.readInt();
|
||||
return new PonyData(
|
||||
buffer.readEnumConstant(Race.class),
|
||||
buffer.readEnumConstant(TailLength.class),
|
||||
buffer.readEnumConstant(TailShape.class),
|
||||
buffer.readEnumConstant(Gender.class),
|
||||
new MsgSize(buffer),
|
||||
buffer.readInt(),
|
||||
buffer.readBoolean(),
|
||||
Flags.read(Wearable.class, buffer)
|
||||
);
|
||||
}
|
||||
|
||||
public MsgPonyData(IPonyData data, boolean noSkin) {
|
||||
race = data.race();
|
||||
tailLength = data.tailLength();
|
||||
tailShape = data.tailShape();
|
||||
gender = data.gender();
|
||||
size = data.size();
|
||||
glowColor = data.glowColor();
|
||||
wearables = Wearable.flags(data.gear());
|
||||
wearableColor = data.attributes().get("gear").colorCode();
|
||||
this.noSkin = noSkin;
|
||||
}
|
||||
|
||||
public PacketByteBuf toBuffer(PacketByteBuf buffer) {
|
||||
public static PacketByteBuf write(PonyData data, PacketByteBuf buffer) {
|
||||
buffer.writeShort(API_IDENTIFIER);
|
||||
buffer.writeByte(API_VERSION);
|
||||
buffer.writeEnumConstant(race);
|
||||
buffer.writeEnumConstant(tailLength);
|
||||
buffer.writeEnumConstant(tailShape);
|
||||
buffer.writeEnumConstant(gender);
|
||||
new MsgSize(size).toBuffer(buffer);
|
||||
buffer.writeInt(glowColor);
|
||||
buffer.writeBoolean(noSkin);
|
||||
|
||||
Wearable[] gear = gear();
|
||||
buffer.writeInt(gear.length);
|
||||
for (int i = 0; i < gear.length; i++) {
|
||||
buffer.writeInt(gear[i].ordinal());
|
||||
}
|
||||
buffer.writeInt(wearableColor);
|
||||
buffer.writeEnumConstant(data.race());
|
||||
buffer.writeEnumConstant(data.tailLength());
|
||||
buffer.writeEnumConstant(data.tailShape());
|
||||
buffer.writeEnumConstant(data.gender());
|
||||
new MsgSize(data.size()).toBuffer(buffer);
|
||||
buffer.writeInt(data.glowColor());
|
||||
buffer.writeBoolean(data.noSkin());
|
||||
data.gear().write(buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public boolean isNoSkin() {
|
||||
return noSkin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Race race() {
|
||||
return race;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TailLength tailLength() {
|
||||
return tailLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TailShape tailShape() {
|
||||
return tailShape;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Gender gender() {
|
||||
return gender;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Size size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int glowColor() {
|
||||
return glowColor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Wearable[] gear() {
|
||||
return Wearable.flags(wearables);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWearing(Wearable wearable) {
|
||||
return wearables[wearable.ordinal()];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Interpolator getInterpolator(UUID interpolatorId) {
|
||||
return Interpolator.linear(interpolatorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, TriggerPixelType<?>> attributes() {
|
||||
return triggerPixels.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return MoreObjects.toStringHelper(this)
|
||||
.add("race", race)
|
||||
.add("tailLength", tailLength)
|
||||
.add("tailShape", tailShape)
|
||||
.add("gender", gender)
|
||||
.add("size", size)
|
||||
.add("wearables", gear())
|
||||
.add("glowColor", TriggerPixelType.toHex(glowColor))
|
||||
.toString();
|
||||
}
|
||||
|
||||
private record MsgSize (
|
||||
int ordinal,
|
||||
String name,
|
||||
|
@ -179,7 +48,7 @@ public class MsgPonyData implements IPonyData {
|
|||
float scaleFactor,
|
||||
float eyeHeightFactor,
|
||||
float eyeDistanceFactor,
|
||||
int triggerPixel) implements Size {
|
||||
int colorCode) implements Size {
|
||||
|
||||
MsgSize(Size size) {
|
||||
this(size.ordinal(), size.name(), size.shadowSize(), size.scaleFactor(), size.eyeHeightFactor(), size.eyeDistanceFactor(), size.colorCode());
|
||||
|
@ -196,17 +65,12 @@ public class MsgPonyData implements IPonyData {
|
|||
buffer.writeFloat(scaleFactor);
|
||||
buffer.writeFloat(eyeHeightFactor);
|
||||
buffer.writeFloat(eyeDistanceFactor);
|
||||
buffer.writeFloat(triggerPixel);
|
||||
buffer.writeFloat(colorCode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int colorCode() {
|
||||
return triggerPixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,8 @@ import net.fabricmc.loader.api.FabricLoader;
|
|||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.PonyData;
|
||||
import com.minelittlepony.api.pony.network.MsgPonyData;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
|
||||
|
@ -35,22 +36,22 @@ public class Channel {
|
|||
|
||||
ClientPlayNetworking.registerGlobalReceiver(REQUEST_PONY_DATA, (client, handler, ignored, sender) -> {
|
||||
if (client.player != null) {
|
||||
IPony pony = IPony.getManager().getPony(client.player);
|
||||
Pony pony = Pony.getManager().getPony(client.player);
|
||||
registered = true;
|
||||
MineLittlePony.logger.info("Server has just consented");
|
||||
|
||||
sender.sendPacket(CLIENT_PONY_DATA, new MsgPonyData(pony.metadata(), pony.defaulted()).toBuffer(PacketByteBufs.create()));
|
||||
sender.sendPacket(CLIENT_PONY_DATA, MsgPonyData.write(pony.metadata(), PacketByteBufs.create()));
|
||||
}
|
||||
});
|
||||
ServerPlayNetworking.registerGlobalReceiver(CLIENT_PONY_DATA, (server, player, ignore, buffer, ignore2) -> {
|
||||
MsgPonyData packet = new MsgPonyData(buffer);
|
||||
PonyData packet = MsgPonyData.read(buffer);
|
||||
server.execute(() -> {
|
||||
PonyDataCallback.EVENT.invoker().onPonyDataAvailable(player, packet, packet.isNoSkin(), EnvType.SERVER);
|
||||
PonyDataCallback.EVENT.invoker().onPonyDataAvailable(player, packet, EnvType.SERVER);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public static void broadcastPonyData(MsgPonyData packet) {
|
||||
public static void broadcastPonyData(PonyData packet) {
|
||||
if (FabricLoader.getInstance().getEnvironmentType() != EnvType.CLIENT) {
|
||||
throw new RuntimeException("Client packet send called by the server");
|
||||
}
|
||||
|
@ -64,6 +65,6 @@ public class Channel {
|
|||
}
|
||||
}
|
||||
|
||||
ClientPlayNetworking.send(CLIENT_PONY_DATA, packet.toBuffer(PacketByteBufs.create()));
|
||||
ClientPlayNetworking.send(CLIENT_PONY_DATA, MsgPonyData.write(packet, PacketByteBufs.create()));
|
||||
}
|
||||
}
|
|
@ -5,17 +5,16 @@ import net.fabricmc.fabric.api.event.Event;
|
|||
import net.fabricmc.fabric.api.event.EventFactory;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
|
||||
import com.minelittlepony.api.pony.IPonyData;
|
||||
import com.minelittlepony.api.pony.PonyData;
|
||||
|
||||
/**
|
||||
* Callback triggered on the server when receiving pony data from a client.
|
||||
*
|
||||
*/
|
||||
public interface PonyDataCallback {
|
||||
|
||||
Event<PonyDataCallback> EVENT = EventFactory.createArrayBacked(PonyDataCallback.class, listeners -> (sender, data, noSkin, env) -> {
|
||||
Event<PonyDataCallback> EVENT = EventFactory.createArrayBacked(PonyDataCallback.class, listeners -> (sender, data, env) -> {
|
||||
for (PonyDataCallback event : listeners) {
|
||||
event.onPonyDataAvailable(sender, data, noSkin, env);
|
||||
event.onPonyDataAvailable(sender, data, env);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -23,8 +22,7 @@ public interface PonyDataCallback {
|
|||
* Called when pony data is received.
|
||||
* @param sender The player who sent the data - this is the owner of the skin/pony data.
|
||||
* @param data The skin/pony data
|
||||
* @param noSkin Whether the data is for a player with a default/unset custom skin.
|
||||
* @param env The environment. Whether this call is coming from the client or server. Clients may get two calls, one for both.
|
||||
*/
|
||||
void onPonyDataAvailable(PlayerEntity sender, IPonyData data, boolean noSkin, EnvType env);
|
||||
void onPonyDataAvailable(PlayerEntity sender, PonyData data, EnvType env);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package com.minelittlepony.client.settings;
|
||||
package com.minelittlepony.client;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
|
@ -5,7 +5,7 @@ import net.minecraft.entity.player.PlayerEntity;
|
|||
import net.minecraft.util.hit.HitResult;
|
||||
import net.minecraft.util.math.*;
|
||||
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.common.util.settings.Setting;
|
||||
|
||||
public class HorseCam {
|
||||
|
@ -48,7 +48,7 @@ public class HorseCam {
|
|||
return pitch;
|
||||
}
|
||||
|
||||
IPony pony = IPony.getManager().getPony(player);
|
||||
Pony pony = Pony.getManager().getPony(player);
|
||||
|
||||
if (!pony.race().isHuman()) {
|
||||
Setting<Boolean> fillyCam = MineLittlePony.getInstance().getConfig().fillycam;
|
||||
|
|
|
@ -13,7 +13,6 @@ import static com.minelittlepony.common.event.SkinFilterCallback.copy;
|
|||
*
|
||||
*/
|
||||
class LegacySkinConverter implements SkinFilterCallback {
|
||||
|
||||
@Override
|
||||
public void processImage(NativeImage image, boolean legacy) {
|
||||
if (legacy) {
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
package com.minelittlepony.client;
|
||||
|
||||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.api.pony.PonyManager;
|
||||
import com.minelittlepony.api.pony.network.fabric.Channel;
|
||||
import com.minelittlepony.client.model.ModelType;
|
||||
import com.minelittlepony.client.pony.PonyManager;
|
||||
import com.minelittlepony.client.pony.VariatedTextureSupplier;
|
||||
import com.minelittlepony.client.render.PonyRenderDispatcher;
|
||||
import com.minelittlepony.client.settings.ClientPonyConfig;
|
||||
import com.minelittlepony.common.client.gui.VisibilityMode;
|
||||
import com.minelittlepony.common.client.gui.element.Button;
|
||||
import com.minelittlepony.common.client.gui.sprite.TextureSprite;
|
||||
|
@ -41,7 +39,7 @@ public class MineLittlePony implements ClientModInitializer {
|
|||
public static final Logger logger = LogManager.getLogger("MineLittlePony");
|
||||
|
||||
private ClientPonyConfig config;
|
||||
private PonyManager ponyManager;
|
||||
private PonyManagerImpl ponyManager;
|
||||
private VariatedTextureSupplier variatedTextures;
|
||||
|
||||
private final KeyBinding keyBinding = new KeyBinding("key.minelittlepony.settings", InputUtil.Type.KEYSYM, GLFW.GLFW_KEY_F9, "key.categories.misc");
|
||||
|
@ -68,7 +66,7 @@ public class MineLittlePony implements ClientModInitializer {
|
|||
hasModMenu = FabricLoader.getInstance().isModLoaded("modmenu");
|
||||
|
||||
config = new ClientPonyConfig(GamePaths.getConfigDirectory().resolve("minelp.json"));
|
||||
ponyManager = new PonyManager(config);
|
||||
ponyManager = new PonyManagerImpl(config);
|
||||
variatedTextures = new VariatedTextureSupplier();
|
||||
|
||||
KeyBindingHelper.registerKeyBinding(keyBinding);
|
||||
|
@ -105,7 +103,7 @@ public class MineLittlePony implements ClientModInitializer {
|
|||
}
|
||||
|
||||
if ((mainMenu || inGame) && keyBinding.isPressed()) {
|
||||
client.setScreen(new GuiPonySettings(client.currentScreen));
|
||||
client.setScreen(new PonySettingsscreen(client.currentScreen));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,7 +117,7 @@ public class MineLittlePony implements ClientModInitializer {
|
|||
if (show) {
|
||||
int y = hasHdSkins ? 75 : 50;
|
||||
Button button = buttons.addButton(new Button(screen.width - 50, screen.height - y, 20, 20))
|
||||
.onClick(sender -> MinecraftClient.getInstance().setScreen(new GuiPonySettings(screen)));
|
||||
.onClick(sender -> MinecraftClient.getInstance().setScreen(new PonySettingsscreen(screen)));
|
||||
button.getStyle()
|
||||
.setIcon(new TextureSprite()
|
||||
.setPosition(2, 2)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.minelittlepony.client;
|
||||
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.PonyPosture;
|
||||
import com.minelittlepony.client.transform.PonyTransformation;
|
||||
|
||||
|
@ -16,7 +16,7 @@ public class PonyBounds {
|
|||
return PonyPosture.getMountPony(entity).map(ridingPony -> {
|
||||
LivingEntity vehicle = (LivingEntity)entity.getVehicle();
|
||||
|
||||
Vec3d offset = PonyTransformation.forSize(ridingPony.metadata().size()).getRiderOffset();
|
||||
Vec3d offset = PonyTransformation.forSize(ridingPony.size()).getRiderOffset();
|
||||
float scale = ridingPony.metadata().size().scaleFactor();
|
||||
|
||||
return getAbsoluteRidingOffset(vehicle).add(
|
||||
|
@ -40,8 +40,8 @@ public class PonyBounds {
|
|||
);
|
||||
}
|
||||
|
||||
public static Box getBoundingBox(IPony pony, LivingEntity entity) {
|
||||
final float scale = pony.metadata().size().scaleFactor() + 0.1F;
|
||||
public static Box getBoundingBox(Pony pony, LivingEntity entity) {
|
||||
final float scale = pony.size().scaleFactor() + 0.1F;
|
||||
final float width = entity.getWidth() * scale;
|
||||
final float height = entity.getHeight() * scale;
|
||||
|
||||
|
|
97
src/main/java/com/minelittlepony/client/PonyDataLoader.java
Normal file
97
src/main/java/com/minelittlepony/client/PonyDataLoader.java
Normal file
|
@ -0,0 +1,97 @@
|
|||
package com.minelittlepony.client;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.resource.metadata.ResourceMetadataReader;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import com.google.gson.*;
|
||||
import com.minelittlepony.api.pony.PonyData;
|
||||
import com.minelittlepony.api.pony.meta.*;
|
||||
import com.minelittlepony.client.util.render.NativeUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
class PonyDataLoader {
|
||||
static final Supplier<Optional<PonyData>> NULL = loaded(PonyData.NULL);
|
||||
private static final ResourceMetadataReader<PonyData> SERIALIZER = new ResourceMetadataReader<PonyData>() {
|
||||
private static final Gson GSON = new GsonBuilder()
|
||||
.excludeFieldsWithoutExposeAnnotation()
|
||||
.create();
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return "pony";
|
||||
}
|
||||
|
||||
@Override
|
||||
public PonyData fromJson(JsonObject json) {
|
||||
return GSON.fromJson(json, PonyData.class);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Parses the given resource into a new IPonyData.
|
||||
* This may either come from an attached json file or the image itself.
|
||||
*/
|
||||
public static Supplier<Optional<PonyData>> parse(@Nullable Identifier identifier, boolean noSkin) {
|
||||
if (identifier == null) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return MinecraftClient.getInstance().getResourceManager().getResource(identifier).flatMap(res -> {
|
||||
try {
|
||||
return res.getMetadata().decode(SERIALIZER);
|
||||
} catch (IOException e) {
|
||||
MineLittlePony.logger.warn("Unable to read {} metadata", identifier, e);
|
||||
}
|
||||
return Optional.empty();
|
||||
}).map(PonyDataLoader::loaded).orElseGet(() -> {
|
||||
return load(callback -> {
|
||||
NativeUtil.parseImage(identifier, image -> {
|
||||
callback.accept(new PonyData(
|
||||
TriggerPixel.RACE.readValue(image),
|
||||
TriggerPixel.TAIL.readValue(image),
|
||||
TriggerPixel.TAIL_SHAPE.readValue(image),
|
||||
TriggerPixel.GENDER.readValue(image),
|
||||
TriggerPixel.SIZE.readValue(image),
|
||||
TriggerPixel.GLOW.readColor(image),
|
||||
TriggerPixel.WEARABLES.readFlags(image),
|
||||
noSkin
|
||||
));
|
||||
}, e -> {
|
||||
MineLittlePony.logger.fatal("Unable to read {} metadata", identifier, e);
|
||||
callback.accept(PonyData.NULL);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private static <T> Supplier<Optional<T>> loaded(T t) {
|
||||
final Optional<T> value = Optional.of(t);
|
||||
return () -> value;
|
||||
}
|
||||
|
||||
private static <T> Supplier<Optional<T>> load(Consumer<Consumer<T>> factory) {
|
||||
return new Supplier<Optional<T>>() {
|
||||
Optional<T> value = Optional.empty();
|
||||
boolean loadRequested;
|
||||
@Override
|
||||
public Optional<T> get() {
|
||||
synchronized (this) {
|
||||
if (!loadRequested) {
|
||||
loadRequested = true;
|
||||
factory.accept(value -> {
|
||||
this.value = Optional.ofNullable(value);
|
||||
});
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,11 +1,9 @@
|
|||
package com.minelittlepony.client.pony;
|
||||
package com.minelittlepony.client;
|
||||
|
||||
import com.google.common.cache.*;
|
||||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.api.config.PonyLevel;
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.IPonyManager;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
import com.minelittlepony.api.pony.*;
|
||||
import com.minelittlepony.client.render.blockentity.skull.PonySkullRenderer;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
@ -26,39 +24,44 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
/**
|
||||
* The PonyManager is responsible for reading and recoding all the pony data associated with an entity of skin.
|
||||
*
|
||||
*/
|
||||
public class PonyManager implements IPonyManager, SimpleSynchronousResourceReloadListener {
|
||||
class PonyManagerImpl implements PonyManager, SimpleSynchronousResourceReloadListener {
|
||||
private static final Identifier ID = new Identifier("minelittlepony", "background_ponies");
|
||||
public static final Identifier BACKGROUND_PONIES = new Identifier("minelittlepony", "textures/entity/pony");
|
||||
public static final Identifier BACKGROUND_ZOMPONIES = new Identifier("minelittlepony", "textures/entity/zompony");
|
||||
|
||||
private final PonyConfig config;
|
||||
|
||||
private final Cache<Identifier, IPony> defaultedPoniesCache = CacheBuilder.newBuilder()
|
||||
private final LoadingCache<Identifier, Pony> defaultedPoniesCache = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(30, TimeUnit.SECONDS)
|
||||
.build();
|
||||
.build(CacheLoader.from(resource -> {
|
||||
return new Pony(resource, PonyDataLoader.parse(resource, true));
|
||||
}));
|
||||
|
||||
private final LoadingCache<Identifier, IPony> poniesCache = CacheBuilder.newBuilder()
|
||||
private final LoadingCache<Identifier, Pony> poniesCache = CacheBuilder.newBuilder()
|
||||
.expireAfterAccess(30, TimeUnit.SECONDS)
|
||||
.build(CacheLoader.from(Pony::new));
|
||||
.build(CacheLoader.from(resource -> {
|
||||
return new Pony(resource, PonyDataLoader.parse(resource, false));
|
||||
}));
|
||||
|
||||
public PonyManager(PonyConfig config) {
|
||||
public PonyManagerImpl(PonyConfig config) {
|
||||
this.config = config;
|
||||
Instance.instance = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPony getPony(Identifier resource) {
|
||||
private Pony loadPony(Identifier resource, boolean defaulted) {
|
||||
try {
|
||||
return poniesCache.get(resource);
|
||||
return (defaulted ? defaultedPoniesCache : poniesCache).get(resource);
|
||||
} catch (ExecutionException e) {
|
||||
return new Pony(resource, PonyData.MEM_NULL, true);
|
||||
return new Pony(resource, PonyDataLoader.NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<IPony> getPony(@Nullable Entity entity) {
|
||||
public Pony getPony(Identifier resource) {
|
||||
return loadPony(resource, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Pony> getPony(@Nullable Entity entity) {
|
||||
if (entity instanceof PlayerEntity player) {
|
||||
return Optional.of(getPony(player));
|
||||
}
|
||||
|
@ -71,12 +74,12 @@ public class PonyManager implements IPonyManager, SimpleSynchronousResourceReloa
|
|||
}
|
||||
|
||||
@Override
|
||||
public IPony getPony(PlayerEntity player) {
|
||||
public Pony getPony(PlayerEntity player) {
|
||||
Identifier skin = getSkin(player);
|
||||
UUID uuid = player.getGameProfile() == null ? player.getUuid() : player.getGameProfile().getId();
|
||||
|
||||
if (skin != null) {
|
||||
if (player instanceof IPonyManager.ForcedPony) {
|
||||
if (player instanceof PonyManager.ForcedPony) {
|
||||
return getPony(skin);
|
||||
}
|
||||
|
||||
|
@ -87,12 +90,12 @@ public class PonyManager implements IPonyManager, SimpleSynchronousResourceReloa
|
|||
return getBackgroundPony(uuid);
|
||||
}
|
||||
|
||||
return getAsDefaulted(getPony(DefaultSkinHelper.getTexture(uuid).texture()));
|
||||
return loadPony(DefaultSkinHelper.getTexture(uuid).texture(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPony getPony(Identifier resource, UUID uuid) {
|
||||
IPony pony = getPony(resource);
|
||||
public Pony getPony(Identifier resource, UUID uuid) {
|
||||
Pony pony = getPony(resource);
|
||||
|
||||
if (config.ponyLevel.get() == PonyLevel.PONIES && pony.metadata().race().isHuman()) {
|
||||
return getBackgroundPony(uuid);
|
||||
|
@ -102,16 +105,8 @@ public class PonyManager implements IPonyManager, SimpleSynchronousResourceReloa
|
|||
}
|
||||
|
||||
@Override
|
||||
public IPony getBackgroundPony(UUID uuid) {
|
||||
return getAsDefaulted(getPony(MineLittlePony.getInstance().getVariatedTextures().get(BACKGROUND_PONIES, uuid).orElse(DefaultSkinHelper.getTexture(uuid).texture())));
|
||||
}
|
||||
|
||||
private IPony getAsDefaulted(IPony pony) {
|
||||
try {
|
||||
return defaultedPoniesCache.get(pony.texture(), () -> new Pony(pony.texture(), ((Pony)pony).memoizedData(), true));
|
||||
} catch (ExecutionException e) {
|
||||
return pony;
|
||||
}
|
||||
public Pony getBackgroundPony(UUID uuid) {
|
||||
return loadPony(MineLittlePony.getInstance().getVariatedTextures().get(VariatedTextureSupplier.BACKGROUND_PONIES_POOL, uuid).orElse(DefaultSkinHelper.getTexture(uuid).texture()), true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -132,6 +127,7 @@ public class PonyManager implements IPonyManager, SimpleSynchronousResourceReloa
|
|||
defaultedPoniesCache.invalidate(resource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearCache() {
|
||||
MineLittlePony.logger.info("Flushed {} cached ponies.", poniesCache.size());
|
||||
poniesCache.invalidateAll();
|
||||
|
@ -148,5 +144,4 @@ public class PonyManager implements IPonyManager, SimpleSynchronousResourceReloa
|
|||
public Identifier getFabricId() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
}
|
|
@ -6,7 +6,6 @@ import net.minecraft.client.gui.screen.Screen;
|
|||
import net.minecraft.text.*;
|
||||
|
||||
import com.minelittlepony.client.render.MobRenderers;
|
||||
import com.minelittlepony.client.settings.ClientPonyConfig;
|
||||
import com.minelittlepony.common.client.gui.GameGui;
|
||||
import com.minelittlepony.common.client.gui.ScrollContainer;
|
||||
import com.minelittlepony.common.client.gui.Tooltip;
|
||||
|
@ -24,7 +23,7 @@ import org.jetbrains.annotations.Nullable;
|
|||
* In-Game options menu.
|
||||
*
|
||||
*/
|
||||
public class GuiPonySettings extends GameGui {
|
||||
public class PonySettingsscreen extends GameGui {
|
||||
private static final String OPTIONS_PREFIX = "minelp.options.";
|
||||
private static final String PONY_LEVEL = OPTIONS_PREFIX + "ponylevel";
|
||||
private static final String MOB_PREFIX = "minelp.mobs.";
|
||||
|
@ -41,7 +40,7 @@ public class GuiPonySettings extends GameGui {
|
|||
|
||||
private final boolean hiddenOptions;
|
||||
|
||||
public GuiPonySettings(@Nullable Screen parent) {
|
||||
public PonySettingsscreen(@Nullable Screen parent) {
|
||||
super(Text.literal(OPTIONS_PREFIX + "title"), parent);
|
||||
|
||||
config = (ClientPonyConfig)MineLittlePony.getInstance().getConfig();
|
|
@ -1,5 +1,5 @@
|
|||
package com.minelittlepony.client;
|
||||
|
||||
public interface IPreviewModel {
|
||||
public interface PreviewModel {
|
||||
boolean forceSeapony();
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package com.minelittlepony.client.pony;
|
||||
package com.minelittlepony.client;
|
||||
|
||||
import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
|
@ -6,13 +6,14 @@ import net.minecraft.entity.Entity;
|
|||
import net.minecraft.resource.ResourceManager;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
import com.minelittlepony.util.MathUtil;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class VariatedTextureSupplier implements SimpleSynchronousResourceReloadListener {
|
||||
private static final Identifier ID = new Identifier("minelittlepony", "variated_textures");
|
||||
public static final Identifier BACKGROUND_PONIES_POOL = new Identifier("minelittlepony", "textures/entity/pony");
|
||||
public static final Identifier BACKGROUND_ZOMPONIES_POOL = new Identifier("minelittlepony", "textures/entity/zompony");
|
||||
|
||||
private final Map<Identifier, SkinList> entries = new HashMap<>();
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
package com.minelittlepony.client.hdskins;
|
||||
package com.minelittlepony.client.compat.hdskins;
|
||||
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
|
||||
import com.minelittlepony.api.pony.*;
|
||||
import com.minelittlepony.client.IPreviewModel;
|
||||
import com.minelittlepony.client.PreviewModel;
|
||||
import com.minelittlepony.client.render.EquineRenderManager;
|
||||
import com.minelittlepony.hdskins.client.gui.player.*;
|
||||
import com.minelittlepony.hdskins.client.gui.player.skins.PlayerSkins;
|
||||
|
@ -13,7 +13,7 @@ import java.util.UUID;
|
|||
/**
|
||||
* Dummy model used for the skin uploading screen.
|
||||
*/
|
||||
class DummyPony extends DummyPlayer implements IPreviewModel, IPonyManager.ForcedPony, EquineRenderManager.RegistrationHandler {
|
||||
class DummyPony extends DummyPlayer implements PreviewModel, PonyManager.ForcedPony, EquineRenderManager.RegistrationHandler {
|
||||
|
||||
public DummyPony(ClientWorld world, PlayerSkins<?> textures) {
|
||||
super(world, textures);
|
||||
|
@ -21,7 +21,7 @@ class DummyPony extends DummyPlayer implements IPreviewModel, IPonyManager.Force
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldUpdateRegistration(IPony pony) {
|
||||
public boolean shouldUpdateRegistration(Pony pony) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
package com.minelittlepony.client.hdskins;
|
||||
package com.minelittlepony.client.compat.hdskins;
|
||||
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.client.GuiPonySettings;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.client.PonySettingsscreen;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
import com.minelittlepony.common.client.gui.dimension.Bounds;
|
||||
import com.minelittlepony.common.client.gui.element.Button;
|
||||
|
@ -29,22 +29,22 @@ class GuiSkinsMineLP extends GuiSkins {
|
|||
chooser.addSkinChangedEventListener(type -> {
|
||||
MineLittlePony.logger.debug("Invalidating old local skin, checking updated local skin");
|
||||
if (type == SkinType.SKIN) {
|
||||
IPony.getManager().removePony(previewer.getLocal().getSkins().get(SkinType.SKIN).getId());
|
||||
Pony.getManager().removePony(previewer.getLocal().getSkins().get(SkinType.SKIN).getId());
|
||||
}
|
||||
});
|
||||
uploader.addSkinLoadedEventListener((type, location, profileTexture) -> {
|
||||
MineLittlePony.logger.debug("Invalidating old remote skin, checking updated remote skin");
|
||||
if (type == SkinType.SKIN) {
|
||||
IPony.getManager().removePony(location);
|
||||
Pony.getManager().removePony(location);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initServerPreviewButtons(Bounds area) {
|
||||
if (!(parent instanceof GuiPonySettings)) {
|
||||
if (!(parent instanceof PonySettingsscreen)) {
|
||||
addButton(new Button(area.right() - 20, area.bottom() + 5, 20, 20))
|
||||
.onClick(sender -> client.setScreen(new GuiPonySettings(this)))
|
||||
.onClick(sender -> client.setScreen(new PonySettingsscreen(this)))
|
||||
.getStyle()
|
||||
.setIcon(new TextureSprite()
|
||||
.setPosition(2, 2)
|
|
@ -1,9 +1,10 @@
|
|||
package com.minelittlepony.client.hdskins;
|
||||
package com.minelittlepony.client.compat.hdskins;
|
||||
|
||||
import net.minecraft.client.gui.DrawContext;
|
||||
import net.minecraft.text.Text;
|
||||
|
||||
import com.minelittlepony.api.pony.*;
|
||||
import com.minelittlepony.api.pony.meta.TriggerPixelType;
|
||||
import com.minelittlepony.common.client.gui.ITextContext;
|
||||
import com.minelittlepony.common.client.gui.dimension.Bounds;
|
||||
import com.minelittlepony.hdskins.client.gui.Carousel;
|
||||
|
@ -23,7 +24,7 @@ class LegendOverlayWidget implements Carousel.Element, ITextContext {
|
|||
|
||||
@Override
|
||||
public void render(DummyPlayer player, DrawContext context, int mouseX, int mouseY) {
|
||||
IPonyData data = IPony.getManager().getPony(player).metadata();
|
||||
PonyData data = Pony.getManager().getPony(player).metadata();
|
||||
int[] index = new int[1];
|
||||
data.attributes().forEach((key, value) -> {
|
||||
context.getMatrices().push();
|
|
@ -1,10 +1,8 @@
|
|||
package com.minelittlepony.client.hdskins;
|
||||
package com.minelittlepony.client.compat.hdskins;
|
||||
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.IPonyData;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.PonyData;
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
import com.minelittlepony.client.SkinsProxy;
|
||||
import com.minelittlepony.common.client.gui.ScrollContainer;
|
||||
import com.minelittlepony.common.client.gui.element.Button;
|
||||
import com.minelittlepony.common.event.ClientReadyCallback;
|
||||
|
@ -28,7 +26,7 @@ import net.minecraft.entity.Entity;
|
|||
import net.minecraft.item.Items;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import com.minelittlepony.client.pony.PonyManager;
|
||||
import com.minelittlepony.client.*;
|
||||
import com.minelittlepony.client.render.entity.AquaticPlayerPonyRenderer;
|
||||
|
||||
/**
|
||||
|
@ -53,8 +51,7 @@ public class MineLPHDSkins extends SkinsProxy implements ClientModInitializer {
|
|||
|
||||
ClientReadyCallback.EVENT.register(client -> {
|
||||
// Clear ponies when skins are cleared
|
||||
PonyManager ponyManager = (PonyManager) MineLittlePony.getInstance().getManager();
|
||||
SkinCacheClearCallback.EVENT.register(ponyManager::clearCache);
|
||||
SkinCacheClearCallback.EVENT.register(MineLittlePony.getInstance().getManager()::clearCache);
|
||||
|
||||
// Ponify the skins GUI.
|
||||
GuiSkins.setSkinsGui(GuiSkinsMineLP::new);
|
||||
|
@ -102,7 +99,7 @@ public class MineLPHDSkins extends SkinsProxy implements ClientModInitializer {
|
|||
|
||||
PlayerSkin main = dummy.getTextures().get(SkinType.SKIN);
|
||||
Wearable wearable = Wearable.REGISTRY.getOrDefault(type.getId(), Wearable.NONE);
|
||||
IPonyData metadata = IPony.getManager().getPony(main.getId()).metadata();
|
||||
PonyData metadata = Pony.getManager().getPony(main.getId()).metadata();
|
||||
if (wearable != Wearable.NONE && metadata.isWearing(wearable)) {
|
||||
|
||||
if (wearable.isSaddlebags() && metadata.race().supportsLegacySaddlebags()) {
|
|
@ -1,4 +1,4 @@
|
|||
package com.minelittlepony.client.hdskins;
|
||||
package com.minelittlepony.client.compat.hdskins;
|
||||
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.util.Identifier;
|
|
@ -1,13 +1,13 @@
|
|||
package com.minelittlepony.client.modmenu;
|
||||
package com.minelittlepony.client.compat.modmenu;
|
||||
|
||||
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
|
||||
import com.terraformersmc.modmenu.api.ModMenuApi;
|
||||
|
||||
import com.minelittlepony.client.GuiPonySettings;
|
||||
import com.minelittlepony.client.PonySettingsscreen;
|
||||
|
||||
public class MineLPModMenuFactory implements ModMenuApi {
|
||||
@Override
|
||||
public ConfigScreenFactory<?> getModConfigScreenFactory() {
|
||||
return GuiPonySettings::new;
|
||||
return PonySettingsscreen::new;
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@ import org.spongepowered.asm.mixin.injection.At;
|
|||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.render.Camera;
|
||||
|
@ -18,10 +18,10 @@ abstract class MixinCamera {
|
|||
private void redirectCameraDistance(double initial, CallbackInfoReturnable<Double> info) {
|
||||
double value = info.getReturnValueD();
|
||||
|
||||
IPony pony = IPony.getManager().getPony(MinecraftClient.getInstance().player);
|
||||
Pony pony = Pony.getManager().getPony(MinecraftClient.getInstance().player);
|
||||
|
||||
if (!pony.race().isHuman()) {
|
||||
value *= pony.metadata().size().eyeDistanceFactor();
|
||||
value *= pony.size().eyeDistanceFactor();
|
||||
}
|
||||
|
||||
info.setReturnValue(value);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.minelittlepony.client.mixin;
|
||||
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.client.pony.Pony;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.client.render.EquineRenderManager;
|
||||
|
||||
import net.minecraft.client.network.AbstractClientPlayerEntity;
|
||||
|
@ -22,7 +21,7 @@ abstract class MixinClientPlayerEntity extends AbstractClientPlayerEntity implem
|
|||
public MixinClientPlayerEntity() { super(null, null); }
|
||||
|
||||
@Nullable
|
||||
private IPony pony;
|
||||
private Pony pony;
|
||||
|
||||
@Inject(method = "startRiding(Lnet/minecraft/entity/Entity;Z)Z", at = @At("RETURN"))
|
||||
private void onStartRiding(Entity entity, boolean bl, CallbackInfoReturnable<Boolean> info) {
|
||||
|
@ -35,9 +34,9 @@ abstract class MixinClientPlayerEntity extends AbstractClientPlayerEntity implem
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldUpdateRegistration(IPony pony) {
|
||||
public boolean shouldUpdateRegistration(Pony pony) {
|
||||
if (this.pony != pony && (this.pony == null || this.pony.metadata().compareTo(pony.metadata()) != 0)) {
|
||||
this.pony = Pony.snapshot(pony);
|
||||
this.pony = pony.immutableCopy();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -47,10 +46,10 @@ abstract class MixinClientPlayerEntity extends AbstractClientPlayerEntity implem
|
|||
public float getActiveEyeHeight(EntityPose pose, EntityDimensions dimensions) {
|
||||
float value = super.getActiveEyeHeight(pose, dimensions);
|
||||
|
||||
IPony pony = IPony.getManager().getPony(this);
|
||||
Pony pony = Pony.getManager().getPony(this);
|
||||
|
||||
if (!pony.race().isHuman()) {
|
||||
float factor = pony.metadata().size().eyeHeightFactor();
|
||||
float factor = pony.size().eyeHeightFactor();
|
||||
if (factor != 1) {
|
||||
value *= factor;
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
|
|||
*/
|
||||
@Override
|
||||
public final void setAngles(T entity, float limbAngle, float limbSpeed, float animationProgress, float headYaw, float headPitch) {
|
||||
attributes.checkRainboom(entity, canFly(), animationProgress);
|
||||
attributes.checkRainboom(entity, this, animationProgress);
|
||||
PonyModelPrepareCallback.EVENT.invoker().onPonyModelPrepared(entity, this, ModelAttributes.Mode.OTHER);
|
||||
super.setAngles(entity, limbAngle, limbSpeed, animationProgress, headYaw, headPitch);
|
||||
|
||||
|
@ -388,7 +388,7 @@ public abstract class AbstractPonyModel<T extends LivingEntity> extends ClientPo
|
|||
|
||||
if (attributes.shouldLiftArm(pose, complement, sigma)) {
|
||||
float swag = 1;
|
||||
if (!isFlying() && both) {
|
||||
if (!getAttributes().isFlying && both) {
|
||||
swag -= (float)Math.pow(limbSpeed, 2);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,10 +8,10 @@ import net.minecraft.util.Hand;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.api.model.ModelAttributes;
|
||||
import com.minelittlepony.api.model.*;
|
||||
import com.minelittlepony.api.model.fabric.PonyModelPrepareCallback;
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.IPonyData;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.PonyData;
|
||||
import com.minelittlepony.api.pony.meta.Size;
|
||||
import com.minelittlepony.api.pony.meta.Sizes;
|
||||
import com.minelittlepony.mson.api.model.biped.MsonPlayer;
|
||||
|
@ -23,7 +23,7 @@ import com.minelittlepony.mson.api.model.biped.MsonPlayer;
|
|||
*
|
||||
* Modders can extend this class to make their own pony models if they wish.
|
||||
*/
|
||||
public abstract class ClientPonyModel<T extends LivingEntity> extends MsonPlayer<T> implements IPonyModel<T>, ModelWithHat, ModelWithArms {
|
||||
public abstract class ClientPonyModel<T extends LivingEntity> extends MsonPlayer<T> implements PonyModel<T> {
|
||||
|
||||
/**
|
||||
* The model attributes.
|
||||
|
@ -47,7 +47,7 @@ public abstract class ClientPonyModel<T extends LivingEntity> extends MsonPlayer
|
|||
}
|
||||
|
||||
@Override
|
||||
public void updateLivingState(T entity, IPony pony, ModelAttributes.Mode mode) {
|
||||
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);
|
||||
|
@ -60,6 +60,18 @@ public abstract class ClientPonyModel<T extends LivingEntity> extends MsonPlayer
|
|||
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;
|
||||
|
@ -67,11 +79,11 @@ public abstract class ClientPonyModel<T extends LivingEntity> extends MsonPlayer
|
|||
|
||||
@Override
|
||||
public Size getSize() {
|
||||
return child ? Sizes.FOAL : getMetadata().size();
|
||||
return child ? Sizes.FOAL : PonyModel.super.getSize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMetadata(IPonyData meta) {
|
||||
public void setMetadata(PonyData meta) {
|
||||
attributes.metadata = meta;
|
||||
}
|
||||
|
||||
|
@ -89,18 +101,6 @@ public abstract class ClientPonyModel<T extends LivingEntity> extends MsonPlayer
|
|||
return side == Arm.RIGHT ? rightArmPose : leftArmPose;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 void setHatVisible(boolean visible) {
|
||||
|
||||
|
|
|
@ -7,16 +7,14 @@ import net.minecraft.client.util.math.MatrixStack;
|
|||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.util.Arm;
|
||||
|
||||
import com.minelittlepony.api.model.BodyPart;
|
||||
import com.minelittlepony.api.model.IUnicorn;
|
||||
import com.minelittlepony.api.model.ModelAttributes;
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.IPonyData;
|
||||
import com.minelittlepony.api.model.*;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.PonyData;
|
||||
import com.minelittlepony.api.pony.meta.Size;
|
||||
import com.minelittlepony.mson.api.ModelView;
|
||||
import com.minelittlepony.mson.api.model.BoxBuilder.RenderLayerSetter;
|
||||
|
||||
public interface IPonyMixinModel<T extends LivingEntity, M extends IPonyModel<T>> extends IPonyModel<T>, ModelWithArms {
|
||||
public interface IPonyMixinModel<T extends LivingEntity, M extends PonyModel<T>> extends PonyModel<T> {
|
||||
|
||||
M mixin();
|
||||
|
||||
|
@ -29,7 +27,7 @@ public interface IPonyMixinModel<T extends LivingEntity, M extends IPonyModel<T>
|
|||
}
|
||||
|
||||
@Override
|
||||
default void updateLivingState(T entity, IPony pony, ModelAttributes.Mode mode) {
|
||||
default void updateLivingState(T entity, Pony pony, ModelAttributes.Mode mode) {
|
||||
mixin().updateLivingState(entity, pony, mode);
|
||||
}
|
||||
|
||||
|
@ -54,7 +52,7 @@ public interface IPonyMixinModel<T extends LivingEntity, M extends IPonyModel<T>
|
|||
}
|
||||
|
||||
@Override
|
||||
default void setMetadata(IPonyData meta) {
|
||||
default void setMetadata(PonyData meta) {
|
||||
mixin().setMetadata(meta);
|
||||
}
|
||||
|
||||
|
@ -90,7 +88,12 @@ public interface IPonyMixinModel<T extends LivingEntity, M extends IPonyModel<T>
|
|||
return mixin().getBodyPart(part);
|
||||
}
|
||||
|
||||
interface Caster<T extends LivingEntity, M extends IPonyModel<T> & IUnicorn, ArmModel> extends IPonyMixinModel<T, M>, IUnicorn {
|
||||
@Override
|
||||
default void setHatVisible(boolean hatVisible) {
|
||||
mixin().setHatVisible(hatVisible);
|
||||
}
|
||||
|
||||
interface Caster<T extends LivingEntity, M extends PonyModel<T> & HornedPonyModel<T>, ArmModel> extends IPonyMixinModel<T, M>, HornedPonyModel<T> {
|
||||
@Override
|
||||
default boolean isCasting() {
|
||||
return mixin().isCasting();
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
package com.minelittlepony.client.model;
|
||||
|
||||
import net.minecraft.client.model.ModelPart;
|
||||
import net.minecraft.client.render.entity.model.BipedEntityModel;
|
||||
import net.minecraft.client.render.entity.model.ModelWithArms;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
||||
import com.minelittlepony.api.model.BodyPart;
|
||||
import com.minelittlepony.api.model.ICapitated;
|
||||
import com.minelittlepony.api.model.IModel;
|
||||
import com.minelittlepony.api.model.ModelAttributes;
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.mson.api.MsonModel;
|
||||
|
||||
public interface IPonyModel<T extends LivingEntity> extends IModel, ICapitated<ModelPart>, ModelWithArms, MsonModel {
|
||||
|
||||
void copyAttributes(BipedEntityModel<T> other);
|
||||
|
||||
void updateLivingState(T entity, IPony pony, ModelAttributes.Mode mode);
|
||||
|
||||
ModelPart getBodyPart(BodyPart part);
|
||||
}
|
|
@ -8,8 +8,9 @@ import net.minecraft.entity.mob.VexEntity;
|
|||
import net.minecraft.entity.passive.*;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import com.minelittlepony.api.model.IModel;
|
||||
import com.minelittlepony.api.model.gear.IGear;
|
||||
import com.minelittlepony.api.model.BodyPart;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.api.model.gear.*;
|
||||
import com.minelittlepony.api.pony.meta.Race;
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
import com.minelittlepony.client.model.armour.PonyArmourModel;
|
||||
|
@ -29,7 +30,7 @@ import java.util.stream.Stream;
|
|||
|
||||
public final class ModelType {
|
||||
private static final Map<Race, PlayerModelKey<?, ?>> PLAYER_MODELS = new HashMap<>();
|
||||
private static final Map<Wearable, GearModelKey<? extends IGear>> GEAR_MODELS = new HashMap<>();
|
||||
private static final Map<Wearable, GearModelKey<? extends Gear>> GEAR_MODELS = new HashMap<>();
|
||||
|
||||
public static final ModelKey<DJPon3EarsModel> DJ_PON_3 = register("dj_pon_three", DJPon3EarsModel::new);
|
||||
|
||||
|
@ -55,14 +56,14 @@ public final class ModelType {
|
|||
public static final ModelKey<PonyArmourModel<?>> INNER_PONY_ARMOR = register("armor/inner_pony_armor", PonyArmourModel::new);
|
||||
public static final ModelKey<PonyArmourModel<?>> OUTER_PONY_ARMOR = register("armor/outer_pony_armor", PonyArmourModel::new);
|
||||
|
||||
public static final GearModelKey<Stetson> STETSON = registerGear("stetson", Wearable.STETSON, Stetson::new);
|
||||
public static final GearModelKey<AbstractGearModel> STETSON = registerGear("stetson", Wearable.STETSON, t -> new WearableGear(Wearable.STETSON, BodyPart.HEAD, 0.15F));
|
||||
public static final GearModelKey<SaddleBags> SADDLEBAGS_BOTH = registerGear("saddlebags", Wearable.SADDLE_BAGS_BOTH, t -> new SaddleBags(t, Wearable.SADDLE_BAGS_BOTH));
|
||||
public static final GearModelKey<SaddleBags> SADDLEBAGS_LEFT = registerGear(SADDLEBAGS_BOTH, Wearable.SADDLE_BAGS_LEFT, t -> new SaddleBags(t, Wearable.SADDLE_BAGS_LEFT));
|
||||
public static final GearModelKey<SaddleBags> SADDLEBAGS_RIGHT = registerGear(SADDLEBAGS_BOTH, Wearable.SADDLE_BAGS_RIGHT, t -> new SaddleBags(t, Wearable.SADDLE_BAGS_RIGHT));
|
||||
public static final GearModelKey<Crown> CROWN = registerGear("crown", Wearable.CROWN, Crown::new);
|
||||
public static final GearModelKey<Muffin> MUFFIN = registerGear("muffin", Wearable.MUFFIN, Muffin::new);
|
||||
public static final GearModelKey<WitchHat> WITCH_HAT = registerGear("witch_hat", Wearable.HAT, WitchHat::new);
|
||||
public static final GearModelKey<ChristmasHat> ANTLERS = registerGear("antlers", Wearable.ANTLERS, ChristmasHat::new);
|
||||
public static final GearModelKey<AbstractGearModel> MUFFIN = registerGear("muffin", Wearable.MUFFIN, t -> new WearableGear(Wearable.MUFFIN, BodyPart.HEAD, 0.45F).addPart(t.getChild("crown")));
|
||||
public static final GearModelKey<AbstractGearModel> WITCH_HAT = registerGear("witch_hat", Wearable.HAT, t -> new WearableGear(Wearable.HAT, BodyPart.HEAD, 0.7F).addPart(t.getChild("hat")));
|
||||
public static final GearModelKey<DeerAntlers> ANTLERS = registerGear("antlers", Wearable.ANTLERS, DeerAntlers::new);
|
||||
|
||||
public static final PlayerModelKey<LivingEntity, AlicornModel<?>> ALICORN = registerPlayer("alicorn", Race.ALICORN, AlicornModel::new);
|
||||
public static final PlayerModelKey<LivingEntity, UnicornModel<?>> UNICORN = registerPlayer("unicorn", Race.UNICORN, UnicornModel::new);
|
||||
|
@ -77,27 +78,27 @@ public final class ModelType {
|
|||
public static final PlayerModelKey<LivingEntity, ChangelingModel<?>> CHANGEDLING = registerPlayer("reformed_changeling", Race.CHANGEDLING, ChangelingModel::new);
|
||||
public static final PlayerModelKey<LivingEntity, EarthPonyModel<?>> ZEBRA = registerPlayer("zebra", Race.ZEBRA, EarthPonyModel::new);
|
||||
|
||||
static <E extends LivingEntity, T extends Model & MsonModel & IModel> PlayerModelKey<E, T> registerPlayer(String name, Race race,
|
||||
static <E extends LivingEntity, T extends Model & MsonModel & PonyModel<?>> PlayerModelKey<E, T> registerPlayer(String name, Race race,
|
||||
BiFunction<ModelPart, Boolean, T> constructor) {
|
||||
return registerPlayer(name, race, constructor, PonyArmourModel::new);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static <E extends LivingEntity, T extends Model & MsonModel & IModel> PlayerModelKey<E, T> registerPlayer(String name, Race race,
|
||||
static <E extends LivingEntity, T extends Model & MsonModel & PonyModel<?>> PlayerModelKey<E, T> registerPlayer(String name, Race race,
|
||||
BiFunction<ModelPart, Boolean, T> constructor,
|
||||
MsonModel.Factory<PonyArmourModel<E>> armorFactory) {
|
||||
return (PlayerModelKey<E, T>)PLAYER_MODELS.computeIfAbsent(race, r -> new PlayerModelKey<>(name, constructor, armorFactory));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static <T extends AbstractGear> GearModelKey<T> registerGear(String name, Wearable wearable, MsonModel.Factory<T> constructor) {
|
||||
static <T extends AbstractGearModel> GearModelKey<T> registerGear(String name, Wearable wearable, MsonModel.Factory<T> constructor) {
|
||||
return (GearModelKey<T>)GEAR_MODELS.computeIfAbsent(wearable, w -> {
|
||||
return new GearModelKey<T>(Mson.getInstance().registerModel(new Identifier("minelittlepony", "gear/" + name), constructor), constructor);
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
static <T extends AbstractGear> GearModelKey<T> registerGear(GearModelKey<T> key, Wearable wearable, MsonModel.Factory<T> constructor) {
|
||||
static <T extends AbstractGearModel> GearModelKey<T> registerGear(GearModelKey<T> key, Wearable wearable, MsonModel.Factory<T> constructor) {
|
||||
return (GearModelKey<T>)GEAR_MODELS.computeIfAbsent(wearable, w -> new GearModelKey<T>(key.key, constructor));
|
||||
}
|
||||
|
||||
|
@ -107,17 +108,17 @@ public final class ModelType {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
public static <E extends LivingEntity, T extends Model & MsonModel & IModel> PlayerModelKey<E, T> getPlayerModel(Race race) {
|
||||
public static <E extends LivingEntity, T extends Model & MsonModel & PonyModel<?>> PlayerModelKey<E, T> getPlayerModel(Race race) {
|
||||
return (PlayerModelKey<E, T>)PLAYER_MODELS.get(race);
|
||||
}
|
||||
|
||||
public static Stream<Map.Entry<Wearable, GearModelKey<? extends IGear>>> getWearables() {
|
||||
public static Stream<Map.Entry<Wearable, GearModelKey<? extends Gear>>> getWearables() {
|
||||
return GEAR_MODELS.entrySet().stream();
|
||||
}
|
||||
|
||||
public static void bootstrap() { }
|
||||
|
||||
public record GearModelKey<T extends IGear>(ModelKey<T> key, MsonModel.Factory<T> constructor) {
|
||||
public record GearModelKey<T extends Gear>(ModelKey<T> key, MsonModel.Factory<T> constructor) {
|
||||
public T createModel() {
|
||||
return key.createModel(constructor);
|
||||
}
|
||||
|
|
|
@ -6,10 +6,10 @@ import net.minecraft.item.ItemStack;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.api.model.IModel;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.api.model.IModelWrapper;
|
||||
import com.minelittlepony.api.model.armour.*;
|
||||
import com.minelittlepony.api.pony.IPonyData;
|
||||
import com.minelittlepony.api.pony.PonyData;
|
||||
import com.minelittlepony.client.model.armour.PonyArmourModel;
|
||||
import com.minelittlepony.mson.api.*;
|
||||
|
||||
|
@ -19,7 +19,7 @@ import java.util.function.Consumer;
|
|||
/**
|
||||
* Container class for the various models and their associated piece of armour.
|
||||
*/
|
||||
public class ModelWrapper<T extends LivingEntity, M extends IModel> implements IModelWrapper {
|
||||
public class ModelWrapper<T extends LivingEntity, M extends PonyModel<?>> implements IModelWrapper {
|
||||
@Nullable
|
||||
private final MsonModel.Factory<PonyArmourModel<T>> armorFactory;
|
||||
private final Map<ModelKey<PonyArmourModel<?>>, PonyArmourModel<T>> armor = new HashMap<>();
|
||||
|
@ -51,7 +51,7 @@ public class ModelWrapper<T extends LivingEntity, M extends IModel> implements I
|
|||
}
|
||||
|
||||
@Override
|
||||
public ModelWrapper<T, M> applyMetadata(IPonyData meta) {
|
||||
public ModelWrapper<T, M> applyMetadata(PonyData meta) {
|
||||
body.setMetadata(meta);
|
||||
armor.values().forEach(a -> a.setMetadata(meta));
|
||||
return this;
|
||||
|
|
|
@ -7,13 +7,13 @@ import net.minecraft.util.Identifier;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.api.model.IModel;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.client.model.armour.PonyArmourModel;
|
||||
import com.minelittlepony.mson.api.*;
|
||||
|
||||
import java.util.function.*;
|
||||
|
||||
public record PlayerModelKey<T extends LivingEntity, M extends Model & MsonModel & IModel> (
|
||||
public record PlayerModelKey<T extends LivingEntity, M extends Model & PonyModel<?>> (
|
||||
ModelKey<M> steveKey,
|
||||
ModelKey<M> alexKey,
|
||||
MsonModel.Factory<PonyArmourModel<T>> armorFactory
|
||||
|
@ -30,12 +30,12 @@ public record PlayerModelKey<T extends LivingEntity, M extends Model & MsonModel
|
|||
return slimArms ? alexKey : steveKey;
|
||||
}
|
||||
|
||||
public <K extends T, N extends M> ModelWrapper<K, N> create(boolean slimArms) {
|
||||
public <E extends T, N extends M> ModelWrapper<E, N> create(boolean slimArms) {
|
||||
return create(slimArms, null);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public <K extends T, N extends M> ModelWrapper<K, N> create(boolean slimArms, @Nullable Consumer<N> initializer) {
|
||||
public <E extends T, N extends M> ModelWrapper<E, N> create(boolean slimArms, @Nullable Consumer<N> initializer) {
|
||||
return new ModelWrapper(this, slimArms, initializer);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,9 +5,9 @@ import net.minecraft.client.render.entity.model.BipedEntityModel;
|
|||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.api.model.armour.*;
|
||||
import com.minelittlepony.client.model.AbstractPonyModel;
|
||||
import com.minelittlepony.client.model.IPonyModel;
|
||||
|
||||
public class PonyArmourModel<T extends LivingEntity> extends AbstractPonyModel<T> implements IArmourModel<T> {
|
||||
|
||||
|
@ -18,7 +18,7 @@ public class PonyArmourModel<T extends LivingEntity> extends AbstractPonyModel<T
|
|||
@Override
|
||||
public boolean poseModel(T entity, float limbAngle, float limbDistance, float age, float headYaw, float headPitch,
|
||||
EquipmentSlot slot, ArmourLayer layer,
|
||||
IPonyModel<T> mainModel) {
|
||||
PonyModel<T> mainModel) {
|
||||
|
||||
if (!setVisibilities(slot, layer)) {
|
||||
return false;
|
||||
|
|
|
@ -6,6 +6,8 @@ import net.minecraft.client.util.math.MatrixStack;
|
|||
import net.minecraft.entity.mob.EndermanEntity;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
import com.minelittlepony.api.pony.meta.Race;
|
||||
|
||||
public class EnderStallionModel extends SkeleponyModel<EndermanEntity> {
|
||||
|
||||
public boolean isCarrying;
|
||||
|
@ -54,8 +56,8 @@ public class EnderStallionModel extends SkeleponyModel<EndermanEntity> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean canFly() {
|
||||
return isAlicorn;
|
||||
public Race getRace() {
|
||||
return isAlicorn ? (super.getRace().hasHorn() ? Race.ALICORN : Race.PEGASUS) : super.getRace();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,7 +7,7 @@ import net.minecraft.entity.mob.PiglinActivity;
|
|||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
import com.minelittlepony.api.model.ModelAttributes;
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
|
||||
public class PiglinPonyModel extends ZomponyModel<HostileEntity> {
|
||||
|
||||
|
@ -23,7 +23,7 @@ public class PiglinPonyModel extends ZomponyModel<HostileEntity> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void updateLivingState(HostileEntity entity, IPony pony, ModelAttributes.Mode mode) {
|
||||
public void updateLivingState(HostileEntity entity, Pony pony, ModelAttributes.Mode mode) {
|
||||
super.updateLivingState(entity, pony, mode);
|
||||
leftArmPose = ArmPose.EMPTY;
|
||||
rightArmPose = entity.getMainHandStack().isEmpty() ? ArmPose.EMPTY : ArmPose.ITEM;
|
||||
|
|
|
@ -8,10 +8,10 @@ import net.minecraft.item.ItemStack;
|
|||
import net.minecraft.util.Arm;
|
||||
import net.minecraft.util.Hand;
|
||||
|
||||
import com.minelittlepony.client.model.IMobModel;
|
||||
import com.minelittlepony.api.model.MobPosingHelper;
|
||||
import com.minelittlepony.client.model.entity.race.AlicornModel;
|
||||
|
||||
public class SkeleponyModel<T extends HostileEntity> extends AlicornModel<T> implements IMobModel {
|
||||
public class SkeleponyModel<T extends HostileEntity> extends AlicornModel<T> {
|
||||
|
||||
public boolean isUnicorn;
|
||||
|
||||
|
@ -68,7 +68,7 @@ public class SkeleponyModel<T extends HostileEntity> extends AlicornModel<T> imp
|
|||
}
|
||||
|
||||
protected void rotateArmHolding(ModelPart arm, float direction, float swingProgress, float ticks) {
|
||||
IMobModel.rotateArmHolding(arm, direction, swingProgress, ticks);
|
||||
MobPosingHelper.rotateArmHolding(arm, direction, swingProgress, ticks);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -8,7 +8,7 @@ import net.minecraft.util.math.MathHelper;
|
|||
import net.minecraft.util.math.RotationAxis;
|
||||
|
||||
import com.minelittlepony.api.model.ModelAttributes;
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.meta.*;
|
||||
import com.minelittlepony.client.model.entity.race.EarthPonyModel;
|
||||
|
||||
|
@ -19,7 +19,7 @@ public class WitchPonyModel extends EarthPonyModel<WitchEntity> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void updateLivingState(WitchEntity entity, IPony pony, ModelAttributes.Mode mode) {
|
||||
public void updateLivingState(WitchEntity entity, Pony pony, ModelAttributes.Mode mode) {
|
||||
super.updateLivingState(entity, pony, mode);
|
||||
|
||||
if (entity.hasCustomName() && "Filly".equals(entity.getCustomName().getString())) {
|
||||
|
@ -71,9 +71,6 @@ public class WitchPonyModel extends EarthPonyModel<WitchEntity> {
|
|||
|
||||
@Override
|
||||
public boolean isWearing(Wearable wearable) {
|
||||
if (wearable == Wearable.HAT) {
|
||||
return true;
|
||||
}
|
||||
return super.isWearing(wearable);
|
||||
return wearable == Wearable.HAT || super.isWearing(wearable);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
package com.minelittlepony.client.model.entity;
|
||||
|
||||
import com.minelittlepony.client.model.IMobModel;
|
||||
import com.minelittlepony.api.model.MobPosingHelper;
|
||||
import com.minelittlepony.api.pony.meta.Race;
|
||||
import com.minelittlepony.client.model.entity.race.AlicornModel;
|
||||
import net.minecraft.client.model.ModelPart;
|
||||
import net.minecraft.entity.mob.HostileEntity;
|
||||
|
||||
public class ZomponyModel<Zombie extends HostileEntity> extends AlicornModel<Zombie> implements IMobModel {
|
||||
public class ZomponyModel<Zombie extends HostileEntity> extends AlicornModel<Zombie> {
|
||||
|
||||
private boolean isPegasus;
|
||||
|
||||
|
@ -23,13 +24,13 @@ public class ZomponyModel<Zombie extends HostileEntity> extends AlicornModel<Zom
|
|||
protected void rotateLegs(float move, float swing, float ticks, Zombie entity) {
|
||||
super.rotateLegs(move, swing, ticks, entity);
|
||||
if (isZombified(entity)) {
|
||||
IMobModel.rotateUndeadArms(this, move, ticks);
|
||||
MobPosingHelper.rotateUndeadArms(this, move, ticks);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canFly() {
|
||||
return isPegasus;
|
||||
public Race getRace() {
|
||||
return isPegasus ? (super.getRace().hasHorn() ? Race.ALICORN : Race.PEGASUS) : super.getRace();
|
||||
}
|
||||
|
||||
protected boolean isZombified(Zombie entity) {
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
package com.minelittlepony.client.model.entity.race;
|
||||
|
||||
import com.minelittlepony.api.model.IPart;
|
||||
import com.minelittlepony.api.model.IPegasus;
|
||||
import com.minelittlepony.api.model.WingedPonyModel;
|
||||
import com.minelittlepony.client.model.part.PonyWings;
|
||||
import com.minelittlepony.mson.api.ModelView;
|
||||
|
||||
import net.minecraft.client.model.ModelPart;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
||||
public class AlicornModel<T extends LivingEntity> extends UnicornModel<T> implements IPegasus {
|
||||
public class AlicornModel<T extends LivingEntity> extends UnicornModel<T> implements WingedPonyModel<T> {
|
||||
|
||||
private PonyWings<AlicornModel<T>> wings;
|
||||
|
||||
|
@ -20,7 +20,7 @@ public class AlicornModel<T extends LivingEntity> extends UnicornModel<T> implem
|
|||
public void init(ModelView context) {
|
||||
super.init(context);
|
||||
wings = addPart(context.findByName("wings"));
|
||||
bodyRenderList.add(forPart(this::getWings).checked(this::canFly));
|
||||
bodyRenderList.add(forPart(this::getWings).checked(() -> getRace().hasWings()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -12,12 +12,12 @@ public class ChangelingModel<T extends LivingEntity> extends AlicornModel<T> {
|
|||
|
||||
@Override
|
||||
public boolean wingsAreOpen() {
|
||||
return (isFlying() || attributes.isCrouching) && !getAttributes().isGliding;
|
||||
return (getAttributes().isFlying || getAttributes().isCrouching) && !getAttributes().isGliding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getWingRotationFactor(float ticks) {
|
||||
if (isFlying()) {
|
||||
if (getAttributes().isFlying) {
|
||||
return MathHelper.sin(ticks * 3) + WINGS_HALF_SPREAD_ANGLE;
|
||||
}
|
||||
return WINGS_RAISED_ANGLE;
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
package com.minelittlepony.client.model.entity.race;
|
||||
|
||||
import com.minelittlepony.api.model.IPart;
|
||||
import com.minelittlepony.api.model.IPegasus;
|
||||
import com.minelittlepony.api.model.WingedPonyModel;
|
||||
import com.minelittlepony.client.model.part.PonyWings;
|
||||
import com.minelittlepony.mson.api.ModelView;
|
||||
|
||||
import net.minecraft.client.model.ModelPart;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
||||
public class PegasusModel<T extends LivingEntity> extends EarthPonyModel<T> implements IPegasus {
|
||||
public class PegasusModel<T extends LivingEntity> extends EarthPonyModel<T> implements WingedPonyModel<T> {
|
||||
|
||||
private PonyWings<PegasusModel<T>> wings;
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.minelittlepony.client.model.entity.race;
|
|||
import com.minelittlepony.client.model.armour.PonyArmourModel;
|
||||
import com.minelittlepony.mson.api.ModelView;
|
||||
import com.minelittlepony.api.model.*;
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
|
||||
import net.minecraft.client.model.ModelPart;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
@ -45,7 +45,7 @@ public class SeaponyModel<T extends LivingEntity> extends UnicornModel<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void updateLivingState(T entity, IPony pony, ModelAttributes.Mode mode) {
|
||||
public void updateLivingState(T entity, Pony pony, ModelAttributes.Mode mode) {
|
||||
super.updateLivingState(entity, pony, mode);
|
||||
|
||||
// Seaponies can't sneak, silly
|
||||
|
@ -123,7 +123,7 @@ public class SeaponyModel<T extends LivingEntity> extends UnicornModel<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void updateLivingState(T entity, IPony pony, ModelAttributes.Mode mode) {
|
||||
public void updateLivingState(T entity, Pony pony, ModelAttributes.Mode mode) {
|
||||
super.updateLivingState(entity, pony, mode);
|
||||
|
||||
// Seaponies can't sneak, silly
|
||||
|
|
|
@ -16,7 +16,7 @@ import net.minecraft.util.*;
|
|||
/**
|
||||
* Used for both unicorns and alicorns since there's no logical way to keep them distinct and not duplicate stuff.
|
||||
*/
|
||||
public class UnicornModel<T extends LivingEntity> extends EarthPonyModel<T> implements IUnicorn {
|
||||
public class UnicornModel<T extends LivingEntity> extends EarthPonyModel<T> implements HornedPonyModel<T> {
|
||||
|
||||
protected final ModelPart unicornArmRight;
|
||||
protected final ModelPart unicornArmLeft;
|
||||
|
@ -33,10 +33,10 @@ public class UnicornModel<T extends LivingEntity> extends EarthPonyModel<T> impl
|
|||
public void init(ModelView context) {
|
||||
super.init(context);
|
||||
horn = addPart(context.findByName("horn"));
|
||||
headRenderList.add(RenderList.of().add(head::rotate).add(forPart(horn)).checked(this::hasHorn));
|
||||
headRenderList.add(RenderList.of().add(head::rotate).add(forPart(horn)).checked(() -> getRace().hasHorn()));
|
||||
this.mainRenderList.add(withStage(BodyPart.HEAD, RenderList.of().add(head::rotate).add((stack, vertices, overlayUv, lightUv, red, green, blue, alpha) -> {
|
||||
horn.renderMagic(stack, vertices, getMagicColor());
|
||||
})).checked(() -> hasHorn() && hasMagic() && isCasting()));
|
||||
horn.renderMagic(stack, vertices, getAttributes().metadata.glowColor());
|
||||
})).checked(() -> hasMagic() && isCasting()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,19 +7,19 @@ import net.minecraft.entity.mob.ZombifiedPiglinEntity;
|
|||
import net.minecraft.entity.player.PlayerEntity;
|
||||
|
||||
import com.minelittlepony.api.model.BodyPart;
|
||||
import com.minelittlepony.api.model.IModel;
|
||||
import com.minelittlepony.api.model.gear.IStackable;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.api.model.gear.WearableGear;
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
|
||||
public class Crown extends AbstractWearableGear implements IStackable {
|
||||
public class Crown extends WearableGear {
|
||||
|
||||
public Crown(ModelPart tree) {
|
||||
super(Wearable.CROWN, BodyPart.HEAD);
|
||||
super(Wearable.CROWN, BodyPart.HEAD, 0.1F);
|
||||
addPart(tree.getChild("crown"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRender(IModel model, Entity entity) {
|
||||
public boolean canRender(PonyModel<?> model, Entity entity) {
|
||||
return super.canRender(model, entity)
|
||||
|| ((
|
||||
entity instanceof AbstractPiglinEntity
|
||||
|
@ -28,9 +28,4 @@ public class Crown extends AbstractWearableGear implements IStackable {
|
|||
) && entity.hasCustomName() && entity.getCustomName().getString().equalsIgnoreCase("technoblade")
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getStackingHeight() {
|
||||
return 0.1F;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,15 +7,15 @@ import net.minecraft.entity.Entity;
|
|||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
import com.minelittlepony.api.model.BodyPart;
|
||||
import com.minelittlepony.api.model.IModel;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.api.model.gear.WearableGear;
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
import com.minelittlepony.common.util.Color;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ChristmasHat extends AbstractWearableGear {
|
||||
|
||||
public class DeerAntlers extends WearableGear {
|
||||
private static boolean dayChecked = false;
|
||||
private static boolean dayResult = false;
|
||||
private static boolean isChristmasDay() {
|
||||
|
@ -35,19 +35,19 @@ public class ChristmasHat extends AbstractWearableGear {
|
|||
|
||||
private int tint;
|
||||
|
||||
public ChristmasHat(ModelPart tree) {
|
||||
super(Wearable.ANTLERS, BodyPart.HEAD);
|
||||
public DeerAntlers(ModelPart tree) {
|
||||
super(Wearable.ANTLERS, BodyPart.HEAD, 0);
|
||||
left = tree.getChild("left");
|
||||
right = tree.getChild("right");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canRender(IModel model, Entity entity) {
|
||||
public boolean canRender(PonyModel<?> model, Entity entity) {
|
||||
return isChristmasDay() || super.canRender(model, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pose(IModel model, Entity entity, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
|
||||
public void pose(PonyModel<?> model, Entity entity, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
|
||||
float pi = MathHelper.PI * (float) Math.pow(swing, 16);
|
||||
|
||||
float mve = move * 0.6662f;
|
||||
|
@ -57,7 +57,7 @@ public class ChristmasHat extends AbstractWearableGear {
|
|||
|
||||
bodySwing += 0.1F;
|
||||
|
||||
tint = model.getMetadata().glowColor();
|
||||
tint = model.getAttributes().metadata.glowColor();
|
||||
left.roll = bodySwing;
|
||||
right.roll = -bodySwing;
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package com.minelittlepony.client.model.gear;
|
||||
|
||||
import net.minecraft.client.model.ModelPart;
|
||||
import com.minelittlepony.api.model.BodyPart;
|
||||
import com.minelittlepony.api.model.gear.IStackable;
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
|
||||
public class Muffin extends AbstractWearableGear implements IStackable {
|
||||
|
||||
public Muffin(ModelPart tree) {
|
||||
super(Wearable.MUFFIN, BodyPart.HEAD);
|
||||
addPart(tree.getChild("crown"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getStackingHeight() {
|
||||
return 0.45F;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
package com.minelittlepony.client.model.gear;
|
||||
|
||||
import com.minelittlepony.api.model.BodyPart;
|
||||
import com.minelittlepony.api.model.IModel;
|
||||
import com.minelittlepony.api.model.IPegasus;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.api.model.WingedPonyModel;
|
||||
import com.minelittlepony.api.model.gear.WearableGear;
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
import com.minelittlepony.util.MathUtil;
|
||||
|
||||
|
@ -15,7 +16,7 @@ import net.minecraft.entity.Entity;
|
|||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
|
||||
public class SaddleBags extends AbstractWearableGear {
|
||||
public class SaddleBags extends WearableGear {
|
||||
|
||||
public static final Identifier TEXTURE = new Identifier("minelittlepony", "textures/models/saddlebags.png");
|
||||
|
||||
|
@ -29,19 +30,15 @@ public class SaddleBags extends AbstractWearableGear {
|
|||
private float dropAmount = 0;
|
||||
|
||||
public SaddleBags(ModelPart tree, Wearable wearable) {
|
||||
super(wearable, BodyPart.BODY);
|
||||
super(wearable, BodyPart.BODY, 0);
|
||||
strap = tree.getChild("strap");
|
||||
leftBag = tree.getChild("left_bag");
|
||||
rightBag = tree.getChild("right_bag");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pose(IModel model, Entity entity, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
|
||||
hangLow = false;
|
||||
|
||||
if (model instanceof IPegasus) {
|
||||
hangLow = model.canFly() && ((IPegasus)model).wingsAreOpen();
|
||||
}
|
||||
public void pose(PonyModel<?> model, Entity entity, boolean rainboom, UUID interpolatorId, float move, float swing, float bodySwing, float ticks) {
|
||||
hangLow = model instanceof WingedPonyModel pegasus && pegasus.wingsAreOpen();
|
||||
|
||||
float pi = MathHelper.PI * (float) Math.pow(swing, 16);
|
||||
|
||||
|
@ -53,8 +50,8 @@ public class SaddleBags extends AbstractWearableGear {
|
|||
leftBag.pitch = bodySwing;
|
||||
rightBag.pitch = bodySwing;
|
||||
|
||||
if (model instanceof IPegasus && model.isFlying()) {
|
||||
bodySwing = ((IPegasus)model).getWingRotationFactor(ticks) - MathUtil.Angles._270_DEG;
|
||||
if (model instanceof WingedPonyModel pegasus && pegasus.getAttributes().isFlying) {
|
||||
bodySwing = pegasus.getWingRotationFactor(ticks) - MathUtil.Angles._270_DEG;
|
||||
bodySwing /= 10;
|
||||
}
|
||||
|
||||
|
@ -66,7 +63,7 @@ public class SaddleBags extends AbstractWearableGear {
|
|||
strap.visible = wearable == Wearable.SADDLE_BAGS_BOTH;
|
||||
|
||||
dropAmount = hangLow ? 0.15F : 0;
|
||||
dropAmount = model.getMetadata().getInterpolator(interpolatorId).interpolate("dropAmount", dropAmount, 3);
|
||||
dropAmount = model.getAttributes().metadata.getInterpolator(interpolatorId).interpolate("dropAmount", dropAmount, 3);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
package com.minelittlepony.client.model.gear;
|
||||
|
||||
import net.minecraft.client.model.ModelPart;
|
||||
import com.minelittlepony.api.model.BodyPart;
|
||||
import com.minelittlepony.api.model.gear.IStackable;
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
|
||||
public class Stetson extends AbstractWearableGear implements IStackable {
|
||||
|
||||
public Stetson(ModelPart tree) {
|
||||
super(Wearable.STETSON, BodyPart.HEAD);
|
||||
addPart(tree.getChild("rim"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getStackingHeight() {
|
||||
return 0.15F;
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
package com.minelittlepony.client.model.gear;
|
||||
|
||||
import net.minecraft.client.model.ModelPart;
|
||||
import com.minelittlepony.api.model.BodyPart;
|
||||
import com.minelittlepony.api.model.gear.IStackable;
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
|
||||
public class WitchHat extends AbstractWearableGear implements IStackable {
|
||||
|
||||
public WitchHat(ModelPart tree) {
|
||||
super(Wearable.HAT, BodyPart.HEAD);
|
||||
addPart(tree.getChild("hat"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getStackingHeight() {
|
||||
return 0.7F;
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@ import com.minelittlepony.mson.api.ModelView;
|
|||
import com.minelittlepony.mson.api.MsonModel;
|
||||
import com.minelittlepony.util.MathUtil;
|
||||
|
||||
public class PonyWings<T extends Model & IPegasus> implements IPart, MsonModel {
|
||||
public class PonyWings<T extends Model & WingedPonyModel<?>> implements IPart, MsonModel {
|
||||
|
||||
protected T pegasus;
|
||||
|
||||
|
@ -49,7 +49,11 @@ public class PonyWings<T extends Model & IPegasus> implements IPart, MsonModel {
|
|||
}
|
||||
|
||||
public Wing getRight() {
|
||||
return (pegasus.isEmbedded(Wearable.SADDLE_BAGS_BOTH) || pegasus.isEmbedded(Wearable.SADDLE_BAGS_LEFT) || pegasus.isEmbedded(Wearable.SADDLE_BAGS_RIGHT)) ? legacyWing : rightWing;
|
||||
return (
|
||||
pegasus.isEmbedded(Wearable.SADDLE_BAGS_BOTH)
|
||||
|| pegasus.isEmbedded(Wearable.SADDLE_BAGS_LEFT)
|
||||
|| pegasus.isEmbedded(Wearable.SADDLE_BAGS_RIGHT)
|
||||
) ? legacyWing : rightWing;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -82,7 +86,7 @@ public class PonyWings<T extends Model & IPegasus> implements IPart, MsonModel {
|
|||
flapAngle = MathUtil.Angles._270_DEG - 0.9F + (float)Math.sin(ticks / 10) / 15F;
|
||||
}
|
||||
|
||||
if (!pegasus.isFlying()) {
|
||||
if (!pegasus.getAttributes().isFlying) {
|
||||
flapAngle = attributes.getMainInterpolator().interpolate("wingFlap", flapAngle, 10);
|
||||
}
|
||||
|
||||
|
@ -99,7 +103,7 @@ public class PonyWings<T extends Model & IPegasus> implements IPart, MsonModel {
|
|||
|
||||
public static class Wing implements MsonModel {
|
||||
|
||||
protected IPegasus pegasus;
|
||||
protected WingedPonyModel<?> pegasus;
|
||||
|
||||
protected final ModelPart extended;
|
||||
protected final ModelPart folded;
|
||||
|
@ -119,14 +123,14 @@ public class PonyWings<T extends Model & IPegasus> implements IPart, MsonModel {
|
|||
|
||||
public void rotateWalking(float swing) {
|
||||
folded.yaw = swing * walkingRotationSpeed;
|
||||
if (pegasus.getMetadata().race().hasBugWings()) {
|
||||
if (pegasus.getRace().hasBugWings()) {
|
||||
extended.yaw = folded.yaw;
|
||||
}
|
||||
}
|
||||
|
||||
public void rotateFlying(float roll) {
|
||||
extended.roll = roll;
|
||||
if (pegasus.getMetadata().race().hasBugWings()) {
|
||||
if (pegasus.getRace().hasBugWings()) {
|
||||
folded.roll = roll;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
package com.minelittlepony.client.pony;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public interface Memoize<T> {
|
||||
T get();
|
||||
|
||||
default T get(T fallback) {
|
||||
T value = get();
|
||||
return value == null ? fallback : value;
|
||||
}
|
||||
|
||||
default boolean isPresent() {
|
||||
return true;
|
||||
}
|
||||
|
||||
static <T> Memoize<T> of(T value) {
|
||||
return () -> value;
|
||||
}
|
||||
|
||||
static <T> Memoize<T> load(Consumer<Consumer<T>> factory) {
|
||||
return new Memoize<>() {
|
||||
T value;
|
||||
boolean loadRequested;
|
||||
@Override
|
||||
public T get() {
|
||||
synchronized (this) {
|
||||
if (!loadRequested) {
|
||||
loadRequested = true;
|
||||
factory.accept(value -> {
|
||||
this.value = value;
|
||||
});
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@Override
|
||||
public boolean isPresent() {
|
||||
return value != null;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
package com.minelittlepony.client.pony;
|
||||
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.IPonyData;
|
||||
import com.minelittlepony.api.pony.network.MsgPonyData;
|
||||
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public record Pony (
|
||||
Identifier texture,
|
||||
Memoize<IPonyData> memoizedData,
|
||||
boolean defaulted
|
||||
) implements IPony {
|
||||
|
||||
Pony(Identifier resource) {
|
||||
this(resource, PonyData.parse(resource), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMetadata() {
|
||||
return memoizedData.isPresent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPonyData metadata() {
|
||||
return memoizedData.get(PonyData.NULL);
|
||||
}
|
||||
|
||||
public static IPony snapshot(IPony pony) {
|
||||
return new Pony(pony.texture(), Memoize.of(new MsgPonyData(pony.metadata(), pony.defaulted())), pony.defaulted());
|
||||
}
|
||||
}
|
|
@ -1,118 +0,0 @@
|
|||
package com.minelittlepony.client.pony;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.util.Identifier;
|
||||
import com.minelittlepony.api.pony.IPonyData;
|
||||
import com.minelittlepony.api.pony.TriggerPixelType;
|
||||
import com.minelittlepony.api.pony.meta.*;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
import com.minelittlepony.client.util.render.NativeUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Implementation for IPonyData.
|
||||
*/
|
||||
public record PonyData (
|
||||
Race race,
|
||||
TailLength tailLength,
|
||||
TailShape tailShape,
|
||||
Gender gender,
|
||||
Size size,
|
||||
int glowColor,
|
||||
boolean[] wearables,
|
||||
Map<String, TriggerPixelType<?>> attributes
|
||||
) implements IPonyData {
|
||||
|
||||
private static final PonyDataSerialiser SERIALISER = new PonyDataSerialiser();
|
||||
|
||||
public static final IPonyData NULL = new PonyData(Race.HUMAN);
|
||||
public static final Memoize<IPonyData> MEM_NULL = Memoize.of(NULL);
|
||||
|
||||
/**
|
||||
* Parses the given resource into a new IPonyData.
|
||||
* This may either come from an attached json file or the image itself.
|
||||
*/
|
||||
public static Memoize<IPonyData> parse(@Nullable Identifier identifier) {
|
||||
if (identifier == null) {
|
||||
return MEM_NULL;
|
||||
}
|
||||
|
||||
return MinecraftClient.getInstance().getResourceManager().getResource(identifier).flatMap(res -> {
|
||||
try {
|
||||
return res.getMetadata().decode(SERIALISER);
|
||||
} catch (IOException e) {
|
||||
MineLittlePony.logger.warn("Unable to read {} metadata", identifier, e);
|
||||
}
|
||||
return null;
|
||||
}).map(Memoize::of).orElseGet(() -> {
|
||||
return Memoize.load(callback -> {
|
||||
NativeUtil.parseImage(identifier, image -> {
|
||||
callback.accept(new PonyData(
|
||||
TriggerPixel.RACE.<Race>readValue(image),
|
||||
TriggerPixel.TAIL.<TailLength>readValue(image),
|
||||
TriggerPixel.TAIL_SHAPE.<TailShape>readValue(image),
|
||||
TriggerPixel.GENDER.<Gender>readValue(image),
|
||||
TriggerPixel.SIZE.<Size>readValue(image),
|
||||
TriggerPixel.GLOW.readColor(image),
|
||||
TriggerPixel.WEARABLES.readFlags(image)
|
||||
));
|
||||
}, e -> {
|
||||
MineLittlePony.logger.fatal("Unable to read {} metadata", identifier, e);
|
||||
callback.accept(NULL);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public PonyData(Race race) {
|
||||
this(race, TailLength.FULL, TailShape.STRAIGHT, Gender.MARE, Sizes.NORMAL, 0x4444aa, new boolean[Wearable.values().length], new TreeMap<>());
|
||||
attributes.put("race", race);
|
||||
attributes.put("tailLength", tailLength);
|
||||
attributes.put("tailShape", tailShape);
|
||||
attributes.put("gender", gender);
|
||||
attributes.put("size", size);
|
||||
attributes.put("magic", TriggerPixelType.of(glowColor));
|
||||
attributes.put("gear", TriggerPixelType.of(0));
|
||||
}
|
||||
|
||||
PonyData(TriggerPixelType.Value<Race> race, TriggerPixelType.Value<TailLength> tailLength, TriggerPixelType.Value<TailShape> tailShape,
|
||||
TriggerPixelType.Value<Gender> gender, TriggerPixelType.Value<Size> size, int glowColor, TriggerPixelType.Flags<Wearable> wearables) {
|
||||
this(race.value(), tailLength.value(), tailShape.value(), gender.value(), size.value(), glowColor, wearables.value(), new TreeMap<>());
|
||||
attributes.put("race", race);
|
||||
attributes.put("tailLength", tailLength);
|
||||
attributes.put("tailShape", tailShape);
|
||||
attributes.put("gender", gender);
|
||||
attributes.put("size", size);
|
||||
attributes.put("magic", TriggerPixelType.of(glowColor));
|
||||
attributes.put("gear", wearables);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Size size() {
|
||||
Sizes sz = MineLittlePony.getInstance().getConfig().sizeOverride.get();
|
||||
|
||||
if (sz != Sizes.UNSET) {
|
||||
return sz;
|
||||
}
|
||||
|
||||
if (size == Sizes.UNSET || !MineLittlePony.getInstance().getConfig().sizes.get()) {
|
||||
return Sizes.NORMAL;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Wearable[] gear() {
|
||||
return Wearable.flags(wearables);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWearing(Wearable wearable) {
|
||||
return wearables[wearable.ordinal()];
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package com.minelittlepony.client.pony;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.minelittlepony.api.pony.IPonyData;
|
||||
|
||||
import net.minecraft.resource.metadata.ResourceMetadataReader;
|
||||
|
||||
class PonyDataSerialiser implements ResourceMetadataReader<IPonyData> {
|
||||
|
||||
private static final Gson gson = new GsonBuilder()
|
||||
.excludeFieldsWithoutExposeAnnotation()
|
||||
.create();
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return "pony";
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPonyData fromJson(JsonObject json) {
|
||||
return gson.fromJson(json, PonyData.class);
|
||||
}
|
||||
}
|
||||
|
|
@ -13,12 +13,12 @@ import net.minecraft.util.math.MathHelper;
|
|||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
import com.minelittlepony.api.model.RenderPass;
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.client.PonyBounds;
|
||||
|
||||
public final class DebugBoundingBoxRenderer {
|
||||
|
||||
public static <T extends LivingEntity> void render(IPony pony, EntityRenderer<T> renderer, T entity, MatrixStack stack, VertexConsumerProvider renderContext, float tickDelta) {
|
||||
public static <T extends LivingEntity> void render(Pony pony, EntityRenderer<T> renderer, T entity, MatrixStack stack, VertexConsumerProvider renderContext, float tickDelta) {
|
||||
|
||||
if (RenderPass.getCurrent() != RenderPass.WORLD) {
|
||||
return;
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
package com.minelittlepony.client.render;
|
||||
|
||||
import com.minelittlepony.api.model.ModelAttributes;
|
||||
import com.minelittlepony.api.model.RenderPass;
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.network.MsgPonyData;
|
||||
import com.minelittlepony.api.model.*;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.network.fabric.Channel;
|
||||
import com.minelittlepony.api.pony.network.fabric.PonyDataCallback;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
import com.minelittlepony.client.model.IPonyModel;
|
||||
import com.minelittlepony.client.model.ModelWrapper;
|
||||
import com.minelittlepony.client.transform.PonyPosture;
|
||||
import com.minelittlepony.mson.api.ModelKey;
|
||||
|
@ -25,7 +22,7 @@ import net.minecraft.entity.Entity;
|
|||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
|
||||
public class EquineRenderManager<T extends LivingEntity, M extends EntityModel<T> & IPonyModel<T>> {
|
||||
public class EquineRenderManager<T extends LivingEntity, M extends EntityModel<T> & PonyModel<T>> {
|
||||
|
||||
private ModelWrapper<T, M> playerModel;
|
||||
|
||||
|
@ -104,7 +101,7 @@ public class EquineRenderManager<T extends LivingEntity, M extends EntityModel<T
|
|||
// negate vanilla translations so the rider begins at the ridees feet.
|
||||
stack.translate(0, -ridingEntity.getHeight(), 0);
|
||||
|
||||
IPony riderPony = renderer.getEntityPony(ridingEntity);
|
||||
Pony riderPony = renderer.getEntityPony(ridingEntity);
|
||||
|
||||
renderer.translateRider(ridingEntity, riderPony, entity, renderer.getEntityPony(entity), stack, ticks);
|
||||
}
|
||||
|
@ -119,8 +116,8 @@ public class EquineRenderManager<T extends LivingEntity, M extends EntityModel<T
|
|||
PonyPosture.of(getModel().getAttributes()).apply(entity, getModel(), stack, yaw, tickDelta, -1);
|
||||
}
|
||||
|
||||
public IPony updateModel(T entity, ModelAttributes.Mode mode) {
|
||||
IPony pony = renderer.getEntityPony(entity);
|
||||
public Pony updateModel(T entity, ModelAttributes.Mode mode) {
|
||||
Pony pony = renderer.getEntityPony(entity);
|
||||
playerModel.applyMetadata(pony.metadata());
|
||||
|
||||
if (pony.hasMetadata() && entity instanceof RegistrationHandler && ((RegistrationHandler)entity).shouldUpdateRegistration(pony)) {
|
||||
|
@ -129,10 +126,10 @@ public class EquineRenderManager<T extends LivingEntity, M extends EntityModel<T
|
|||
PlayerEntity clientPlayer = MinecraftClient.getInstance().player;
|
||||
if (clientPlayer != null) {
|
||||
if (Objects.equals(entity, clientPlayer) || Objects.equals(((PlayerEntity)entity).getGameProfile(), clientPlayer.getGameProfile())) {
|
||||
Channel.broadcastPonyData(new MsgPonyData(pony.metadata(), pony.defaulted()));
|
||||
Channel.broadcastPonyData(pony.metadata());
|
||||
}
|
||||
}
|
||||
PonyDataCallback.EVENT.invoker().onPonyDataAvailable((PlayerEntity)entity, pony.metadata(), pony.defaulted(), EnvType.CLIENT);
|
||||
PonyDataCallback.EVENT.invoker().onPonyDataAvailable((PlayerEntity)entity, pony.metadata(), EnvType.CLIENT);
|
||||
}
|
||||
|
||||
getModel().updateLivingState(entity, pony, mode);
|
||||
|
@ -168,6 +165,6 @@ public class EquineRenderManager<T extends LivingEntity, M extends EntityModel<T
|
|||
}
|
||||
|
||||
public interface RegistrationHandler {
|
||||
boolean shouldUpdateRegistration(IPony pony);
|
||||
boolean shouldUpdateRegistration(Pony pony);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
package com.minelittlepony.client.render;
|
||||
|
||||
import com.minelittlepony.api.model.BodyPart;
|
||||
import com.minelittlepony.api.model.gear.IGear;
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.client.model.*;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.api.model.gear.Gear;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.util.MathUtil;
|
||||
|
||||
import net.minecraft.client.render.entity.model.EntityModel;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
||||
public interface IPonyRenderContext<T extends LivingEntity, M extends EntityModel<T> & IPonyModel<T>> extends IGear.Context<T, M> {
|
||||
public interface IPonyRenderContext<T extends LivingEntity, M extends EntityModel<T> & PonyModel<T>> extends Gear.Context<T, M> {
|
||||
|
||||
IPony getEntityPony(T entity);
|
||||
Pony getEntityPony(T entity);
|
||||
|
||||
EquineRenderManager<T, M> getInternalRenderer();
|
||||
|
||||
/**
|
||||
* Called by riders to have their transportation adjust their position.
|
||||
*/
|
||||
default void translateRider(T entity, IPony entityPony, LivingEntity passenger, IPony passengerPony, MatrixStack stack, float ticks) {
|
||||
default void translateRider(T entity, Pony entityPony, LivingEntity passenger, Pony passengerPony, MatrixStack stack, float ticks) {
|
||||
if (!passengerPony.race().isHuman()) {
|
||||
float yaw = MathUtil.interpolateDegress((float)entity.prevY, (float)entity.getY(), ticks);
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.minelittlepony.client.render;
|
||||
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
import com.minelittlepony.client.util.render.RenderLayerUtil;
|
||||
|
||||
|
@ -21,7 +21,7 @@ import net.minecraft.util.math.RotationAxis;
|
|||
import net.minecraft.world.World;
|
||||
|
||||
public class LevitatingItemRenderer {
|
||||
private VertexConsumerProvider getProvider(IPony pony, VertexConsumerProvider renderContext) {
|
||||
private VertexConsumerProvider getProvider(Pony pony, VertexConsumerProvider renderContext) {
|
||||
final int color = pony.metadata().glowColor();
|
||||
return layer -> {
|
||||
Identifier texture = RenderLayerUtil.getTexture(layer).orElse(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE);
|
||||
|
@ -39,7 +39,7 @@ public class LevitatingItemRenderer {
|
|||
|
||||
if (entity instanceof PlayerEntity && (mode.isFirstPerson() || mode == ModelTransformationMode.THIRD_PERSON_LEFT_HAND || mode == ModelTransformationMode.THIRD_PERSON_RIGHT_HAND)) {
|
||||
|
||||
IPony pony = IPony.getManager().getPony((PlayerEntity)entity);
|
||||
Pony pony = Pony.getManager().getPony((PlayerEntity)entity);
|
||||
|
||||
matrix.push();
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package com.minelittlepony.client.render;
|
||||
|
||||
import java.util.function.Function;
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.PonyPosture;
|
||||
import com.minelittlepony.client.mixin.MixinEntityRenderers;
|
||||
import com.minelittlepony.client.model.IPonyModel;
|
||||
import com.minelittlepony.client.render.entity.PlayerPonyRenderer;
|
||||
import com.minelittlepony.client.render.entity.AquaticPlayerPonyRenderer;
|
||||
|
||||
|
@ -45,7 +46,7 @@ public class PonyRenderDispatcher {
|
|||
Mson.getInstance().getEntityRendererRegistry().registerPlayerRenderer(
|
||||
new Identifier("minelittlepony", "sea/" + armShape.getName()),
|
||||
player -> {
|
||||
return !IPony.getManager().getPony(player).race().isHuman()
|
||||
return !Pony.getManager().getPony(player).race().isHuman()
|
||||
&& PonyPosture.hasSeaponyForm(player)
|
||||
&& player.method_52814().model() == armShape;
|
||||
},
|
||||
|
@ -54,7 +55,7 @@ public class PonyRenderDispatcher {
|
|||
Mson.getInstance().getEntityRendererRegistry().registerPlayerRenderer(
|
||||
new Identifier("minelittlepony", "land/" + armShape.getName()),
|
||||
player -> {
|
||||
return !IPony.getManager().getPony(player).race().isHuman()
|
||||
return !Pony.getManager().getPony(player).race().isHuman()
|
||||
&& !PonyPosture.hasSeaponyForm(player)
|
||||
&& player.method_52814().model() == armShape;
|
||||
},
|
||||
|
@ -82,7 +83,7 @@ public class PonyRenderDispatcher {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
public <T extends LivingEntity, M extends EntityModel<T> & IPonyModel<T>> IPonyRenderContext<T, M> getPonyRenderer(@Nullable T entity) {
|
||||
public <T extends LivingEntity, M extends EntityModel<T> & PonyModel<T>> IPonyRenderContext<T, M> getPonyRenderer(@Nullable T entity) {
|
||||
if (entity == null) {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.minelittlepony.client.render.blockentity.skull;
|
|||
|
||||
import com.google.common.base.Suppliers;
|
||||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.client.model.AbstractPonyModel;
|
||||
import com.minelittlepony.client.render.MobRenderers;
|
||||
import com.minelittlepony.client.render.blockentity.skull.PonySkullRenderer.ISkull;
|
||||
|
@ -43,7 +43,7 @@ public class MobSkull implements ISkull {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean bindPony(IPony pony) {
|
||||
public boolean bindPony(Pony pony) {
|
||||
ponyHead.get().setMetadata(pony.metadata());
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.minelittlepony.client.render.blockentity.skull;
|
|||
|
||||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.api.config.PonyLevel;
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.meta.Race;
|
||||
import com.minelittlepony.client.SkinsProxy;
|
||||
import com.minelittlepony.client.model.*;
|
||||
|
@ -52,7 +52,7 @@ public class PlayerPonySkull implements ISkull {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean bindPony(IPony pony) {
|
||||
public boolean bindPony(Pony pony) {
|
||||
Race race = pony.race();
|
||||
if (race.isHuman()) {
|
||||
race = Race.EARTH;
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.minelittlepony.client.render.blockentity.skull;
|
|||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.client.MineLittlePony;
|
||||
import com.minelittlepony.client.model.ModelType;
|
||||
import com.minelittlepony.client.render.MobRenderers;
|
||||
|
@ -68,7 +68,7 @@ public class PonySkullRenderer {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!selectedSkull.bindPony(IPony.getManager().getPony(selectedSkin))) {
|
||||
if (!selectedSkull.bindPony(Pony.getManager().getPony(selectedSkin))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -112,6 +112,6 @@ public class PonySkullRenderer {
|
|||
|
||||
Identifier getSkinResource(@Nullable GameProfile profile);
|
||||
|
||||
boolean bindPony(IPony pony);
|
||||
boolean bindPony(Pony pony);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.minelittlepony.client.render.entity;
|
||||
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
import com.minelittlepony.client.model.*;
|
||||
import com.minelittlepony.client.render.DebugBoundingBoxRenderer;
|
||||
|
@ -26,7 +27,7 @@ import net.minecraft.entity.mob.MobEntity;
|
|||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public abstract class AbstractPonyRenderer<T extends MobEntity, M extends EntityModel<T> & IPonyModel<T> & ModelWithArms> extends MobEntityRenderer<T, M> implements IPonyRenderContext<T, M> {
|
||||
public abstract class AbstractPonyRenderer<T extends MobEntity, M extends EntityModel<T> & PonyModel<T> & ModelWithArms> extends MobEntityRenderer<T, M> implements IPonyRenderContext<T, M> {
|
||||
|
||||
protected final EquineRenderManager<T, M> manager = new EquineRenderManager<>(this);
|
||||
|
||||
|
@ -132,8 +133,8 @@ public abstract class AbstractPonyRenderer<T extends MobEntity, M extends Entity
|
|||
}
|
||||
|
||||
@Override
|
||||
public IPony getEntityPony(T entity) {
|
||||
return IPony.getManager().getPony(getTexture(entity));
|
||||
public Pony getEntityPony(T 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>>
|
||||
|
@ -143,7 +144,7 @@ public abstract class AbstractPonyRenderer<T extends MobEntity, M extends Entity
|
|||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public static <T extends MobEntity, M extends EntityModel<T> & IPonyModel<T> & ModelWithArms> AbstractPonyRenderer<T, M> proxy(EntityRendererFactory.Context context, ModelKey<? super M> key, TextureSupplier<T> texture, float scale,
|
||||
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,
|
||||
List exportedLayers, Consumer<M> modelConsumer) {
|
||||
var renderer = new AbstractPonyRenderer<T, M>(context, key, texture, scale) {
|
||||
@Override
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
package com.minelittlepony.client.render.entity;
|
||||
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.PonyPosture;
|
||||
import com.minelittlepony.api.pony.meta.Race;
|
||||
import com.minelittlepony.client.IPreviewModel;
|
||||
import com.minelittlepony.client.PreviewModel;
|
||||
import com.minelittlepony.client.SkinsProxy;
|
||||
import com.minelittlepony.util.MathUtil;
|
||||
|
||||
|
@ -37,7 +37,7 @@ public class AquaticPlayerPonyRenderer extends PlayerPonyRenderer {
|
|||
updateSeaponyState(player);
|
||||
super.render(player, entityYaw, tickDelta, stack, renderContext, light);
|
||||
|
||||
if (!(player instanceof IPreviewModel) && wet && player.getVelocity().length() > 0.1F) {
|
||||
if (!(player instanceof PreviewModel) && wet && player.getVelocity().length() > 0.1F) {
|
||||
double x = player.getEntityWorld().getRandom().nextTriangular(player.getX(), 1);
|
||||
double y = player.getEntityWorld().getRandom().nextTriangular(player.getY(), 1);
|
||||
double z = player.getEntityWorld().getRandom().nextTriangular(player.getZ(), 1);
|
||||
|
@ -46,7 +46,7 @@ public class AquaticPlayerPonyRenderer extends PlayerPonyRenderer {
|
|||
}
|
||||
}
|
||||
|
||||
protected Race getPlayerRace(AbstractClientPlayerEntity entity, IPony pony) {
|
||||
protected Race getPlayerRace(AbstractClientPlayerEntity entity, Pony pony) {
|
||||
Race race = super.getPlayerRace(entity, pony);
|
||||
return wet ? Race.SEAPONY : race == Race.SEAPONY ? Race.UNICORN : race;
|
||||
}
|
||||
|
@ -69,10 +69,10 @@ public class AquaticPlayerPonyRenderer extends PlayerPonyRenderer {
|
|||
}
|
||||
|
||||
private void updateSeaponyState(AbstractClientPlayerEntity player) {
|
||||
IPony pony = getEntityPony(player);
|
||||
Pony pony = getEntityPony(player);
|
||||
wet = PonyPosture.isSeaponyModifier(player);
|
||||
|
||||
if (!(player instanceof IPreviewModel)) {
|
||||
if (!(player instanceof PreviewModel)) {
|
||||
float state = wet ? 100 : 0;
|
||||
float interpolated = pony.metadata().getInterpolator(player.getUuid()).interpolate("seapony_state", state, 5);
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.minelittlepony.client.render.entity;
|
||||
|
||||
import com.minelittlepony.api.model.ModelAttributes;
|
||||
import com.minelittlepony.api.pony.IPony;
|
||||
import com.minelittlepony.api.pony.Pony;
|
||||
import com.minelittlepony.api.pony.meta.Race;
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
import com.minelittlepony.client.SkinsProxy;
|
||||
|
@ -77,7 +77,7 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements IPonyRen
|
|||
|
||||
@Override
|
||||
public void render(AbstractClientPlayerEntity entity, float entityYaw, float tickDelta, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv) {
|
||||
IPony pony = getEntityPony(entity);
|
||||
Pony pony = getEntityPony(entity);
|
||||
model = manager.setModel(modelsCache.apply(getPlayerRace(entity, pony))).body();
|
||||
// EntityModelFeatures: We have to force it to use our models otherwise EMF overrides it and breaks pony rendering
|
||||
shadowRadius = manager.getModel().getSize().shadowSize();
|
||||
|
@ -88,7 +88,7 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements IPonyRen
|
|||
// (shadows are drawn after us)
|
||||
if (!entity.hasVehicle() && !entity.isSleeping()) {
|
||||
float yaw = MathHelper.lerpAngleDegrees(tickDelta, entity.prevBodyYaw, entity.bodyYaw);
|
||||
float l = entity.getWidth() / 2 * pony.metadata().size().scaleFactor();
|
||||
float l = entity.getWidth() / 2 * pony.size().scaleFactor();
|
||||
|
||||
stack.multiply(RotationAxis.NEGATIVE_Y.rotationDegrees(yaw));
|
||||
stack.translate(0, 0, -l);
|
||||
|
@ -96,7 +96,7 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements IPonyRen
|
|||
}
|
||||
}
|
||||
|
||||
protected Race getPlayerRace(AbstractClientPlayerEntity entity, IPony pony) {
|
||||
protected Race getPlayerRace(AbstractClientPlayerEntity entity, Pony pony) {
|
||||
return pony.race();
|
||||
}
|
||||
|
||||
|
@ -144,7 +144,7 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements IPonyRen
|
|||
}
|
||||
|
||||
protected void renderArm(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, AbstractClientPlayerEntity player, Arm side) {
|
||||
IPony pony = getEntityPony(player);
|
||||
Pony pony = getEntityPony(player);
|
||||
model = manager.setModel(modelsCache.apply(getPlayerRace(player, pony))).body();
|
||||
manager.updateModel(player, ModelAttributes.Mode.FIRST_PERSON);
|
||||
|
||||
|
@ -184,14 +184,14 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements IPonyRen
|
|||
}
|
||||
|
||||
@Override
|
||||
public IPony getEntityPony(AbstractClientPlayerEntity entity) {
|
||||
return IPony.getManager().getPony(entity);
|
||||
public Pony getEntityPony(AbstractClientPlayerEntity entity) {
|
||||
return Pony.getManager().getPony(entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Identifier getDefaultTexture(AbstractClientPlayerEntity entity, Wearable wearable) {
|
||||
return SkinsProxy.instance.getSkin(wearable.getId(), entity).orElseGet(() -> {
|
||||
if (wearable.isSaddlebags() && getInternalRenderer().getModel().getMetadata().race().supportsLegacySaddlebags()) {
|
||||
if (wearable.isSaddlebags() && getInternalRenderer().getModel().getRace().supportsLegacySaddlebags()) {
|
||||
return getTexture(entity);
|
||||
}
|
||||
|
||||
|
|
|
@ -12,12 +12,12 @@ import net.minecraft.entity.decoration.ArmorStandEntity;
|
|||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
import com.minelittlepony.api.model.armour.ArmourLayer;
|
||||
import com.minelittlepony.api.pony.PonyData;
|
||||
import com.minelittlepony.api.pony.meta.Race;
|
||||
import com.minelittlepony.client.model.ModelType;
|
||||
import com.minelittlepony.client.model.ModelWrapper;
|
||||
import com.minelittlepony.client.model.entity.PonyArmourStandModel;
|
||||
import com.minelittlepony.client.model.entity.race.EarthPonyModel;
|
||||
import com.minelittlepony.client.pony.PonyData;
|
||||
import com.minelittlepony.client.render.entity.feature.ArmourFeature;
|
||||
|
||||
public class PonyStandRenderer extends ArmorStandEntityRenderer {
|
||||
|
@ -69,7 +69,7 @@ public class PonyStandRenderer extends ArmorStandEntityRenderer {
|
|||
context.getModelManager()
|
||||
);
|
||||
|
||||
pony.applyMetadata(new PonyData(Race.EARTH));
|
||||
pony.applyMetadata(PonyData.emptyOf(Race.EARTH));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -10,10 +10,10 @@ import net.minecraft.client.util.math.MatrixStack;
|
|||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import com.minelittlepony.api.model.IModel;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
|
||||
// separate class in case I need it later
|
||||
public abstract class AbstractClothingFeature<T extends LivingEntity, M extends BipedEntityModel<T> & IModel> extends FeatureRenderer<T, M> {
|
||||
public abstract class AbstractClothingFeature<T extends LivingEntity, M extends BipedEntityModel<T> & PonyModel<T>> extends FeatureRenderer<T, M> {
|
||||
|
||||
protected final FeatureRendererContext<T, M> renderer;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.minelittlepony.client.render.entity.feature;
|
||||
|
||||
import com.minelittlepony.client.model.IPonyModel;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.client.model.ModelWrapper;
|
||||
import com.minelittlepony.client.render.IPonyRenderContext;
|
||||
|
||||
|
@ -11,7 +11,7 @@ import net.minecraft.client.render.entity.model.EntityModel;
|
|||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
||||
public abstract class AbstractPonyFeature<T extends LivingEntity, M extends EntityModel<T> & IPonyModel<T>> extends FeatureRenderer<T, M> {
|
||||
public abstract class AbstractPonyFeature<T extends LivingEntity, M extends EntityModel<T> & PonyModel<T>> extends FeatureRenderer<T, M> {
|
||||
|
||||
private final IPonyRenderContext<T, M> context;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.minelittlepony.client.render.entity.feature;
|
||||
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.api.model.armour.*;
|
||||
import com.minelittlepony.client.model.IPonyModel;
|
||||
import com.minelittlepony.client.model.ModelWrapper;
|
||||
import com.minelittlepony.client.model.armour.DefaultArmourTextureResolver;
|
||||
import com.minelittlepony.client.render.IPonyRenderContext;
|
||||
|
@ -21,7 +21,7 @@ import net.minecraft.item.*;
|
|||
import net.minecraft.item.trim.ArmorTrim;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class ArmourFeature<T extends LivingEntity, M extends EntityModel<T> & IPonyModel<T>> extends AbstractPonyFeature<T, M> {
|
||||
public class ArmourFeature<T extends LivingEntity, M extends EntityModel<T> & PonyModel<T>> extends AbstractPonyFeature<T, M> {
|
||||
|
||||
public ArmourFeature(IPonyRenderContext<T, M> context, BakedModelManager bakery) {
|
||||
super(context);
|
||||
|
@ -40,7 +40,7 @@ public class ArmourFeature<T extends LivingEntity, M extends EntityModel<T> & IP
|
|||
}
|
||||
|
||||
public static <T extends LivingEntity, V extends BipedEntityModel<T> & IArmourModel<T>> void renderArmor(
|
||||
ModelWrapper<T, ? extends IPonyModel<T>> pony, MatrixStack matrices,
|
||||
ModelWrapper<T, ? extends PonyModel<T>> pony, MatrixStack matrices,
|
||||
VertexConsumerProvider renderContext, int light, T entity,
|
||||
float limbDistance, float limbAngle,
|
||||
float age, float headYaw, float headPitch,
|
||||
|
|
|
@ -7,13 +7,13 @@ import net.minecraft.client.render.VertexConsumerProvider;
|
|||
import net.minecraft.client.render.entity.model.EntityModel;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
||||
import com.minelittlepony.client.model.IPonyModel;
|
||||
import com.minelittlepony.client.model.ModelType;
|
||||
import com.minelittlepony.api.model.BodyPart;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.client.model.DJPon3EarsModel;
|
||||
import com.minelittlepony.client.render.IPonyRenderContext;
|
||||
|
||||
public class DJPon3Feature<T extends AbstractClientPlayerEntity, M extends EntityModel<T> & IPonyModel<T>> extends AbstractPonyFeature<T, M> {
|
||||
public class DJPon3Feature<T extends AbstractClientPlayerEntity, M extends EntityModel<T> & PonyModel<T>> extends AbstractPonyFeature<T, M> {
|
||||
|
||||
private final DJPon3EarsModel deadMau5 = ModelType.DJ_PON_3.createModel();
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
package com.minelittlepony.client.render.entity.feature;
|
||||
|
||||
import com.minelittlepony.api.model.BodyPart;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.api.pony.PonyPosture;
|
||||
import com.minelittlepony.client.model.IPonyModel;
|
||||
import com.minelittlepony.client.model.ModelType;
|
||||
import com.minelittlepony.client.model.PonyElytra;
|
||||
import com.minelittlepony.client.render.IPonyRenderContext;
|
||||
|
@ -22,7 +22,7 @@ import net.minecraft.entity.EquipmentSlot;
|
|||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
public class ElytraFeature<T extends LivingEntity, M extends EntityModel<T> & IPonyModel<T>> extends AbstractPonyFeature<T, M> {
|
||||
public class ElytraFeature<T extends LivingEntity, M extends EntityModel<T> & PonyModel<T>> extends AbstractPonyFeature<T, M> {
|
||||
|
||||
private static final Identifier TEXTURE_ELYTRA = new Identifier("textures/entity/elytra.png");
|
||||
|
||||
|
|
|
@ -11,10 +11,9 @@ import net.minecraft.util.math.random.Random;
|
|||
import com.google.common.cache.*;
|
||||
import com.google.common.collect.Streams;
|
||||
import com.minelittlepony.api.model.BodyPart;
|
||||
import com.minelittlepony.api.model.gear.IGear;
|
||||
import com.minelittlepony.api.model.gear.IStackable;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.api.model.gear.Gear;
|
||||
import com.minelittlepony.api.pony.meta.Wearable;
|
||||
import com.minelittlepony.client.model.IPonyModel;
|
||||
import com.minelittlepony.client.model.ModelType;
|
||||
import com.minelittlepony.client.render.IPonyRenderContext;
|
||||
|
||||
|
@ -23,11 +22,11 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class GearFeature<T extends LivingEntity, M extends EntityModel<T> & IPonyModel<T>> extends AbstractPonyFeature<T, M> {
|
||||
public class GearFeature<T extends LivingEntity, M extends EntityModel<T> & PonyModel<T>> extends AbstractPonyFeature<T, M> {
|
||||
|
||||
private static final List<Supplier<IGear>> MOD_GEARS = new ArrayList<>();
|
||||
private static final List<Supplier<Gear>> MOD_GEARS = new ArrayList<>();
|
||||
|
||||
public static void addModGear(Supplier<IGear> gear) {
|
||||
public static void addModGear(Supplier<Gear> gear) {
|
||||
MOD_GEARS.add(gear);
|
||||
}
|
||||
|
||||
|
@ -64,29 +63,30 @@ public class GearFeature<T extends LivingEntity, M extends EntityModel<T> & IPon
|
|||
final Object2FloatMap<BodyPart> renderStackingOffsets = new Object2FloatLinkedOpenHashMap<>();
|
||||
|
||||
for (var entry : randomisedGearCache.getUnchecked(entity.getUuid().getLeastSignificantBits())) {
|
||||
if (getContext().shouldRender(model, entity, entry.wearable, entry.gear)) {
|
||||
if (getContext().shouldRender(model, entity, entry.wearable(), entry.gear())) {
|
||||
stack.push();
|
||||
BodyPart part = entry.gear.getGearLocation();
|
||||
entry.gear.transform(model, stack);
|
||||
Gear gear = entry.gear();
|
||||
gear.transform(model, stack);
|
||||
|
||||
if (entry.gear instanceof IStackable s) {
|
||||
if (gear.isStackable()) {
|
||||
BodyPart part = gear.getGearLocation();
|
||||
float v = renderStackingOffsets.getFloat(part);
|
||||
if (v != 0) {
|
||||
stack.translate(0, -v, 0);
|
||||
}
|
||||
renderStackingOffsets.put(part, v + s.getStackingHeight());
|
||||
renderStackingOffsets.put(part, v + gear.getStackingHeight());
|
||||
}
|
||||
|
||||
renderGear(model, entity, entry.gear, stack, renderContext, lightUv, limbDistance, limbAngle, tickDelta);
|
||||
renderGear(model, entity, gear, stack, renderContext, lightUv, limbDistance, limbAngle, tickDelta);
|
||||
stack.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void renderGear(M model, T entity, IGear gear, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, float limbDistance, float limbAngle, float tickDelta) {
|
||||
private void renderGear(M model, T entity, Gear gear, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, float limbDistance, float limbAngle, float tickDelta) {
|
||||
gear.pose(model, entity, model.getAttributes().isGoingFast, entity.getUuid(), limbDistance, limbAngle, model.getWobbleAmount(), tickDelta);
|
||||
gear.render(stack, renderContext.getBuffer(gear.getLayer(entity, getContext())), lightUv, OverlayTexture.DEFAULT_UV, 1, 1, 1, 1, entity.getUuid());
|
||||
}
|
||||
|
||||
static record Entry(IGear gear, Wearable wearable) {}
|
||||
static record Entry(Gear gear, Wearable wearable) { }
|
||||
}
|
||||
|
|
|
@ -7,10 +7,10 @@ import net.minecraft.client.render.entity.model.EntityModel;
|
|||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.util.Identifier;
|
||||
|
||||
import com.minelittlepony.client.model.IPonyModel;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.client.render.IPonyRenderContext;
|
||||
|
||||
public class GlowingEyesFeature<T extends LivingEntity, M extends EntityModel<T> & IPonyModel<T>> extends EyesFeatureRenderer<T, M> {
|
||||
public class GlowingEyesFeature<T extends LivingEntity, M extends EntityModel<T> & PonyModel<T>> extends EyesFeatureRenderer<T, M> {
|
||||
|
||||
private final RenderLayer layer;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package com.minelittlepony.client.render.entity.feature;
|
||||
|
||||
import com.minelittlepony.api.model.BodyPart;
|
||||
import com.minelittlepony.client.model.IPonyModel;
|
||||
import com.minelittlepony.api.model.PonyModel;
|
||||
import com.minelittlepony.client.render.IPonyRenderContext;
|
||||
|
||||
import net.minecraft.client.render.VertexConsumerProvider;
|
||||
|
@ -16,7 +16,7 @@ import net.minecraft.entity.LivingEntity;
|
|||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.Arm;
|
||||
|
||||
public class HeldItemFeature<T extends LivingEntity, M extends EntityModel<T> & IPonyModel<T> & ModelWithArms> extends HeldItemFeatureRenderer<T, M> {
|
||||
public class HeldItemFeature<T extends LivingEntity, M extends EntityModel<T> & PonyModel<T> & ModelWithArms> extends HeldItemFeatureRenderer<T, M> {
|
||||
|
||||
private final IPonyRenderContext<T, M> context;
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue