From 0d226b51f9d43d6198eb37410d0228dff1d1b3c9 Mon Sep 17 00:00:00 2001 From: Sollace Date: Mon, 25 Sep 2023 21:07:09 +0100 Subject: [PATCH] Rewrite pretty much everything to make more effective use of java's Records --- .../minelittlepony/api/config/PonyConfig.java | 17 +- .../api/model/HornedPonyModel.java | 17 ++ .../minelittlepony/api/model/ICapitated.java | 11 -- .../api/model/IModelWrapper.java | 4 +- .../minelittlepony/api/model/IUnicorn.java | 30 --- .../model/MobPosingHelper.java} | 15 +- .../api/model/ModelAttributes.java | 15 +- .../api/model/{IModel.java => PonyModel.java} | 59 ++---- .../{IPegasus.java => WingedPonyModel.java} | 10 +- .../api/model/armour/IArmourModel.java | 4 +- .../fabric/PonyModelPrepareCallback.java | 4 +- .../model/gear/AbstractGearModel.java} | 24 ++- .../api/model/gear/{IGear.java => Gear.java} | 46 +++-- .../api/model/gear/IStackable.java | 14 -- .../model/gear/WearableGear.java} | 11 +- .../api/pony/DefaultPonySkinHelper.java | 2 +- .../minelittlepony/api/pony/IPonyData.java | 82 -------- .../api/pony/{IPony.java => Pony.java} | 60 +++--- .../com/minelittlepony/api/pony/PonyData.java | 127 ++++++++++++ .../{IPonyManager.java => PonyManager.java} | 16 +- .../minelittlepony/api/pony/PonyPosture.java | 18 +- .../minelittlepony/api/pony/meta/Flags.java | 53 +++++ .../minelittlepony/api/pony/meta/Gender.java | 2 - .../minelittlepony/api/pony/meta/Race.java | 2 - .../minelittlepony/api/pony/meta/Size.java | 2 - .../api/pony/meta/TailLength.java | 2 - .../api/pony/meta/TailShape.java | 2 - .../api/pony/meta/TriggerPixel.java | 19 +- .../api/pony/{ => meta}/TriggerPixelType.java | 21 +- .../api/pony/meta/Wearable.java | 19 +- .../api/pony/network/MsgPonyData.java | 186 +++--------------- .../api/pony/network/fabric/Channel.java | 15 +- .../pony/network/fabric/PonyDataCallback.java | 10 +- .../{settings => }/ClientPonyConfig.java | 2 +- .../com/minelittlepony/client/HorseCam.java | 4 +- .../client/LegacySkinConverter.java | 1 - .../minelittlepony/client/MineLittlePony.java | 12 +- .../com/minelittlepony/client/PonyBounds.java | 8 +- .../minelittlepony/client/PonyDataLoader.java | 97 +++++++++ .../PonyManager.java => PonyManagerImpl.java} | 63 +++--- ...ySettings.java => PonySettingsscreen.java} | 5 +- .../{IPreviewModel.java => PreviewModel.java} | 2 +- .../{pony => }/VariatedTextureSupplier.java | 5 +- .../{ => compat}/hdskins/DummyPony.java | 8 +- .../{ => compat}/hdskins/GuiSkinsMineLP.java | 14 +- .../hdskins/LegendOverlayWidget.java | 5 +- .../{ => compat}/hdskins/MineLPHDSkins.java | 15 +- .../hdskins/PonifiedDualCarouselWidget.java | 2 +- .../modmenu/MineLPModMenuFactory.java | 6 +- .../client/mixin/MixinCamera.java | 6 +- .../client/mixin/MixinClientPlayerEntity.java | 13 +- .../client/model/AbstractPonyModel.java | 4 +- .../client/model/ClientPonyModel.java | 38 ++-- .../client/model/IPonyMixinModel.java | 21 +- .../client/model/IPonyModel.java | 22 --- .../client/model/ModelType.java | 29 +-- .../client/model/ModelWrapper.java | 8 +- .../client/model/PlayerModelKey.java | 8 +- .../client/model/armour/PonyArmourModel.java | 4 +- .../model/entity/EnderStallionModel.java | 6 +- .../client/model/entity/PiglinPonyModel.java | 4 +- .../client/model/entity/SkeleponyModel.java | 6 +- .../client/model/entity/WitchPonyModel.java | 9 +- .../client/model/entity/ZomponyModel.java | 11 +- .../model/entity/race/AlicornModel.java | 6 +- .../model/entity/race/ChangelingModel.java | 4 +- .../model/entity/race/PegasusModel.java | 4 +- .../model/entity/race/SeaponyModel.java | 6 +- .../model/entity/race/UnicornModel.java | 8 +- .../client/model/gear/Crown.java | 15 +- .../{ChristmasHat.java => DeerAntlers.java} | 16 +- .../client/model/gear/Muffin.java | 19 -- .../client/model/gear/SaddleBags.java | 23 +-- .../client/model/gear/Stetson.java | 19 -- .../client/model/gear/WitchHat.java | 19 -- .../client/model/part/PonyWings.java | 16 +- .../minelittlepony/client/pony/Memoize.java | 43 ---- .../com/minelittlepony/client/pony/Pony.java | 32 --- .../minelittlepony/client/pony/PonyData.java | 118 ----------- .../client/pony/PonyDataSerialiser.java | 26 --- .../render/DebugBoundingBoxRenderer.java | 4 +- .../client/render/EquineRenderManager.java | 21 +- .../client/render/IPonyRenderContext.java | 12 +- .../client/render/LevitatingItemRenderer.java | 6 +- .../client/render/PonyRenderDispatcher.java | 11 +- .../render/blockentity/skull/MobSkull.java | 4 +- .../blockentity/skull/PlayerPonySkull.java | 4 +- .../blockentity/skull/PonySkullRenderer.java | 6 +- .../render/entity/AbstractPonyRenderer.java | 11 +- .../entity/AquaticPlayerPonyRenderer.java | 12 +- .../render/entity/PlayerPonyRenderer.java | 16 +- .../render/entity/PonyStandRenderer.java | 4 +- .../feature/AbstractClothingFeature.java | 4 +- .../entity/feature/AbstractPonyFeature.java | 4 +- .../render/entity/feature/ArmourFeature.java | 6 +- .../render/entity/feature/DJPon3Feature.java | 4 +- .../render/entity/feature/ElytraFeature.java | 4 +- .../render/entity/feature/GearFeature.java | 28 +-- .../entity/feature/GlowingEyesFeature.java | 4 +- .../entity/feature/HeldItemFeature.java | 4 +- .../render/entity/feature/SkullFeature.java | 4 +- .../entity/npc/AbstractNpcRenderer.java | 4 +- .../render/entity/npc/NpcClothingFeature.java | 5 +- .../entity/npc/VillagerPonyRenderer.java | 4 +- .../entity/npc/ZomponyVillagerRenderer.java | 10 +- .../npc/textures/PlayerTextureSupplier.java | 4 +- .../client/transform/PonyPosture.java | 8 +- .../client/transform/PonyTransformation.java | 16 +- .../client/transform/PostureFlight.java | 4 +- src/main/resources/fabric.mod.json | 4 +- 110 files changed, 821 insertions(+), 1142 deletions(-) create mode 100644 src/main/java/com/minelittlepony/api/model/HornedPonyModel.java delete mode 100644 src/main/java/com/minelittlepony/api/model/ICapitated.java delete mode 100644 src/main/java/com/minelittlepony/api/model/IUnicorn.java rename src/main/java/com/minelittlepony/{client/model/IMobModel.java => api/model/MobPosingHelper.java} (72%) rename src/main/java/com/minelittlepony/api/model/{IModel.java => PonyModel.java} (62%) rename src/main/java/com/minelittlepony/api/model/{IPegasus.java => WingedPonyModel.java} (71%) rename src/main/java/com/minelittlepony/{client/model/gear/AbstractGear.java => api/model/gear/AbstractGearModel.java} (66%) rename src/main/java/com/minelittlepony/api/model/gear/{IGear.java => Gear.java} (71%) delete mode 100644 src/main/java/com/minelittlepony/api/model/gear/IStackable.java rename src/main/java/com/minelittlepony/{client/model/gear/AbstractWearableGear.java => api/model/gear/WearableGear.java} (66%) delete mode 100644 src/main/java/com/minelittlepony/api/pony/IPonyData.java rename src/main/java/com/minelittlepony/api/pony/{IPony.java => Pony.java} (52%) create mode 100644 src/main/java/com/minelittlepony/api/pony/PonyData.java rename src/main/java/com/minelittlepony/api/pony/{IPonyManager.java => PonyManager.java} (84%) create mode 100644 src/main/java/com/minelittlepony/api/pony/meta/Flags.java rename src/main/java/com/minelittlepony/api/pony/{ => meta}/TriggerPixelType.java (80%) rename src/main/java/com/minelittlepony/client/{settings => }/ClientPonyConfig.java (96%) create mode 100644 src/main/java/com/minelittlepony/client/PonyDataLoader.java rename src/main/java/com/minelittlepony/client/{pony/PonyManager.java => PonyManagerImpl.java} (64%) rename src/main/java/com/minelittlepony/client/{GuiPonySettings.java => PonySettingsscreen.java} (98%) rename src/main/java/com/minelittlepony/client/{IPreviewModel.java => PreviewModel.java} (66%) rename src/main/java/com/minelittlepony/client/{pony => }/VariatedTextureSupplier.java (91%) rename src/main/java/com/minelittlepony/client/{ => compat}/hdskins/DummyPony.java (73%) rename src/main/java/com/minelittlepony/client/{ => compat}/hdskins/GuiSkinsMineLP.java (85%) rename src/main/java/com/minelittlepony/client/{ => compat}/hdskins/LegendOverlayWidget.java (93%) rename src/main/java/com/minelittlepony/client/{ => compat}/hdskins/MineLPHDSkins.java (89%) rename src/main/java/com/minelittlepony/client/{ => compat}/hdskins/PonifiedDualCarouselWidget.java (97%) rename src/main/java/com/minelittlepony/client/{ => compat}/modmenu/MineLPModMenuFactory.java (64%) delete mode 100644 src/main/java/com/minelittlepony/client/model/IPonyModel.java rename src/main/java/com/minelittlepony/client/model/gear/{ChristmasHat.java => DeerAntlers.java} (78%) delete mode 100644 src/main/java/com/minelittlepony/client/model/gear/Muffin.java delete mode 100644 src/main/java/com/minelittlepony/client/model/gear/Stetson.java delete mode 100644 src/main/java/com/minelittlepony/client/model/gear/WitchHat.java delete mode 100644 src/main/java/com/minelittlepony/client/pony/Memoize.java delete mode 100644 src/main/java/com/minelittlepony/client/pony/Pony.java delete mode 100644 src/main/java/com/minelittlepony/client/pony/PonyData.java delete mode 100644 src/main/java/com/minelittlepony/client/pony/PonyDataSerialiser.java diff --git a/src/main/java/com/minelittlepony/api/config/PonyConfig.java b/src/main/java/com/minelittlepony/api/config/PonyConfig.java index 1dd18610..ce133053 100644 --- a/src/main/java/com/minelittlepony/api/config/PonyConfig.java +++ b/src/main/java/com/minelittlepony/api/config/PonyConfig.java @@ -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; + } } diff --git a/src/main/java/com/minelittlepony/api/model/HornedPonyModel.java b/src/main/java/com/minelittlepony/api/model/HornedPonyModel.java new file mode 100644 index 00000000..65f50d2f --- /dev/null +++ b/src/main/java/com/minelittlepony/api/model/HornedPonyModel.java @@ -0,0 +1,17 @@ +package com.minelittlepony.api.model; + +import net.minecraft.entity.LivingEntity; + +public interface HornedPonyModel extends PonyModel { + /** + * Returns true if this model is being applied to a race that can use magic. + */ + default boolean hasMagic() { + return getRace().hasHorn() && getAttributes().metadata.glowColor() != 0; + } + + /** + * Returns true if this model is currently using magic (horn is lit). + */ + boolean isCasting(); +} diff --git a/src/main/java/com/minelittlepony/api/model/ICapitated.java b/src/main/java/com/minelittlepony/api/model/ICapitated.java deleted file mode 100644 index a838408d..00000000 --- a/src/main/java/com/minelittlepony/api/model/ICapitated.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.minelittlepony.api.model; - -/** - * Interface for models that have a head. - */ -public interface ICapitated { - /** - * Gets the head of this capitated object. - */ - T getHead(); -} diff --git a/src/main/java/com/minelittlepony/api/model/IModelWrapper.java b/src/main/java/com/minelittlepony/api/model/IModelWrapper.java index dddb62b7..72b2bbdc 100644 --- a/src/main/java/com/minelittlepony/api/model/IModelWrapper.java +++ b/src/main/java/com/minelittlepony/api/model/IModelWrapper.java @@ -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); } diff --git a/src/main/java/com/minelittlepony/api/model/IUnicorn.java b/src/main/java/com/minelittlepony/api/model/IUnicorn.java deleted file mode 100644 index c8e981f1..00000000 --- a/src/main/java/com/minelittlepony/api/model/IUnicorn.java +++ /dev/null @@ -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(); - } -} diff --git a/src/main/java/com/minelittlepony/client/model/IMobModel.java b/src/main/java/com/minelittlepony/api/model/MobPosingHelper.java similarity index 72% rename from src/main/java/com/minelittlepony/client/model/IMobModel.java rename to src/main/java/com/minelittlepony/api/model/MobPosingHelper.java index 5d570ac2..a8a226b8 100644 --- a/src/main/java/com/minelittlepony/client/model/IMobModel.java +++ b/src/main/java/com/minelittlepony/api/model/MobPosingHelper.java @@ -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; } } diff --git a/src/main/java/com/minelittlepony/api/model/ModelAttributes.java b/src/main/java/com/minelittlepony/api/model/ModelAttributes.java index 6a4dc40e..9a218e77 100644 --- a/src/main/java/com/minelittlepony/api/model/ModelAttributes.java +++ b/src/main/java/com/minelittlepony/api/model/ModelAttributes.java @@ -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; diff --git a/src/main/java/com/minelittlepony/api/model/IModel.java b/src/main/java/com/minelittlepony/api/model/PonyModel.java similarity index 62% rename from src/main/java/com/minelittlepony/api/model/IModel.java rename to src/main/java/com/minelittlepony/api/model/PonyModel.java index e5e7d7a6..33a82749 100644 --- a/src/main/java/com/minelittlepony/api/model/IModel.java +++ b/src/main/java/com/minelittlepony/api/model/PonyModel.java @@ -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 extends MsonModel, ModelWithArms, ModelWithHat, ModelWithHead { + + void copyAttributes(BipedEntityModel 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); } + } diff --git a/src/main/java/com/minelittlepony/api/model/IPegasus.java b/src/main/java/com/minelittlepony/api/model/WingedPonyModel.java similarity index 71% rename from src/main/java/com/minelittlepony/api/model/IPegasus.java rename to src/main/java/com/minelittlepony/api/model/WingedPonyModel.java index 00fcd015..fe2fe2e8 100644 --- a/src/main/java/com/minelittlepony/api/model/IPegasus.java +++ b/src/main/java/com/minelittlepony/api/model/WingedPonyModel.java @@ -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 extends PonyModel { public static final float WINGS_HALF_SPREAD_ANGLE = MathUtil.Angles._270_DEG; public static final float WINGS_FULL_SPREAD_ANGLE = MathUtil.Angles._270_DEG + 0.4F; public static final float WINGS_RAISED_ANGLE = 4; @@ -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); } /** diff --git a/src/main/java/com/minelittlepony/api/model/armour/IArmourModel.java b/src/main/java/com/minelittlepony/api/model/armour/IArmourModel.java index 454680b7..0dfec519 100644 --- a/src/main/java/com/minelittlepony/api/model/armour/IArmourModel.java +++ b/src/main/java/com/minelittlepony/api/model/armour/IArmourModel.java @@ -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 { /** @@ -13,5 +13,5 @@ public interface IArmourModel { */ boolean poseModel(T entity, float limbAngle, float limbDistance, float age, float headYaw, float headPitch, EquipmentSlot slot, ArmourLayer layer, - IPonyModel mainModel); + PonyModel mainModel); } diff --git a/src/main/java/com/minelittlepony/api/model/fabric/PonyModelPrepareCallback.java b/src/main/java/com/minelittlepony/api/model/fabric/PonyModelPrepareCallback.java index fc4c03d2..19f2811c 100644 --- a/src/main/java/com/minelittlepony/api/model/fabric/PonyModelPrepareCallback.java +++ b/src/main/java/com/minelittlepony/api/model/fabric/PonyModelPrepareCallback.java @@ -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); } diff --git a/src/main/java/com/minelittlepony/client/model/gear/AbstractGear.java b/src/main/java/com/minelittlepony/api/model/gear/AbstractGearModel.java similarity index 66% rename from src/main/java/com/minelittlepony/client/model/gear/AbstractGear.java rename to src/main/java/com/minelittlepony/api/model/gear/AbstractGearModel.java index 646614ce..8b6c6eb9 100644 --- a/src/main/java/com/minelittlepony/client/model/gear/AbstractGear.java +++ b/src/main/java/com/minelittlepony/api/model/gear/AbstractGearModel.java @@ -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 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; + } } diff --git a/src/main/java/com/minelittlepony/api/model/gear/IGear.java b/src/main/java/com/minelittlepony/api/model/gear/Gear.java similarity index 71% rename from src/main/java/com/minelittlepony/api/model/gear/IGear.java rename to src/main/java/com/minelittlepony/api/model/gear/Gear.java index d0177920..bd625ec4 100644 --- a/src/main/java/com/minelittlepony/api/model/gear/IGear.java +++ b/src/main/java/com/minelittlepony/api/model/gear/Gear.java @@ -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. *

* This would be awesome for creating socks. */ - static Supplier register(Supplier gear) { + static Supplier register(Supplier 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 & IPonyModel> void transform(M model, MatrixStack matrices) { + default & 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 The type of entity being rendered. * @param The type of the entity's primary model. */ - public interface Context { + public interface Context> { /** * 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); } diff --git a/src/main/java/com/minelittlepony/api/model/gear/IStackable.java b/src/main/java/com/minelittlepony/api/model/gear/IStackable.java deleted file mode 100644 index c519f68f..00000000 --- a/src/main/java/com/minelittlepony/api/model/gear/IStackable.java +++ /dev/null @@ -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(); - -} diff --git a/src/main/java/com/minelittlepony/client/model/gear/AbstractWearableGear.java b/src/main/java/com/minelittlepony/api/model/gear/WearableGear.java similarity index 66% rename from src/main/java/com/minelittlepony/client/model/gear/AbstractWearableGear.java rename to src/main/java/com/minelittlepony/api/model/gear/WearableGear.java index bcc80d05..5862afbd 100644 --- a/src/main/java/com/minelittlepony/client/model/gear/AbstractWearableGear.java +++ b/src/main/java/com/minelittlepony/api/model/gear/WearableGear.java @@ -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); } diff --git a/src/main/java/com/minelittlepony/api/pony/DefaultPonySkinHelper.java b/src/main/java/com/minelittlepony/api/pony/DefaultPonySkinHelper.java index 1c8e6b61..a1b4c69f 100644 --- a/src/main/java/com/minelittlepony/api/pony/DefaultPonySkinHelper.java +++ b/src/main/java/com/minelittlepony/api/pony/DefaultPonySkinHelper.java @@ -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) { diff --git a/src/main/java/com/minelittlepony/api/pony/IPonyData.java b/src/main/java/com/minelittlepony/api/pony/IPonyData.java deleted file mode 100644 index 2f35d990..00000000 --- a/src/main/java/com/minelittlepony/api/pony/IPonyData.java +++ /dev/null @@ -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 { - /** - * 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> 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(); - } -} diff --git a/src/main/java/com/minelittlepony/api/pony/IPony.java b/src/main/java/com/minelittlepony/api/pony/Pony.java similarity index 52% rename from src/main/java/com/minelittlepony/api/pony/IPony.java rename to src/main/java/com/minelittlepony/api/pony/Pony.java index 3671415a..28242c37 100644 --- a/src/main/java/com/minelittlepony/api/pony/IPony.java +++ b/src/main/java/com/minelittlepony/api/pony/Pony.java @@ -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 { +import java.util.Optional; +import java.util.function.Supplier; +public record Pony ( + /** + * Gets the texture used for rendering this pony. + */ + Identifier texture, + Supplier> metadataGetter + ) implements Comparable { /** * 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 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()) diff --git a/src/main/java/com/minelittlepony/api/pony/PonyData.java b/src/main/java/com/minelittlepony/api/pony/PonyData.java new file mode 100644 index 00000000..dca5ff33 --- /dev/null +++ b/src/main/java/com/minelittlepony/api/pony/PonyData.java @@ -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 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> attributes + ) implements Comparable { + private static final Function 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 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 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(); + } +} diff --git a/src/main/java/com/minelittlepony/api/pony/IPonyManager.java b/src/main/java/com/minelittlepony/api/pony/PonyManager.java similarity index 84% rename from src/main/java/com/minelittlepony/api/pony/IPonyManager.java rename to src/main/java/com/minelittlepony/api/pony/PonyManager.java index 0ce48b77..f650a7ff 100644 --- a/src/main/java/com/minelittlepony/api/pony/IPonyManager.java +++ b/src/main/java/com/minelittlepony/api/pony/PonyManager.java @@ -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 getPony(@Nullable Entity entity); + Optional 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; } } diff --git a/src/main/java/com/minelittlepony/api/pony/PonyPosture.java b/src/main/java/com/minelittlepony/api/pony/PonyPosture.java index cc3f698a..8247df46 100644 --- a/src/main/java/com/minelittlepony/api/pony/PonyPosture.java +++ b/src/main/java/com/minelittlepony/api/pony/PonyPosture.java @@ -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 getMountPony(LivingEntity entity) { + public static Optional 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()) ); diff --git a/src/main/java/com/minelittlepony/api/pony/meta/Flags.java b/src/main/java/com/minelittlepony/api/pony/meta/Flags.java new file mode 100644 index 00000000..3cf0bb8b --- /dev/null +++ b/src/main/java/com/minelittlepony/api/pony/meta/Flags.java @@ -0,0 +1,53 @@ +package com.minelittlepony.api.pony.meta; + +import net.minecraft.network.PacketByteBuf; + +import java.util.*; + +public record Flags> ( + boolean[] flags, + List values, + int colorCode + ) implements Comparable> { + + public static > Flags of(Class type) { + return new Flags<>(new boolean[type.getEnumConstants().length], List.of(), 0); + } + + public static > Flags of(Class type, int colorCode, boolean...flags) { + return new Flags<>(flags, flags(type.getEnumConstants(), flags), colorCode); + } + + public static > Flags read(Class type, PacketByteBuf buffer) { + int length = buffer.readVarInt(); + List 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 List flags(T[] values, boolean[] flags) { + List 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 other) { + return Arrays.compare(flags, other.flags); + } + + public void write(PacketByteBuf buffer) { + buffer.writeCollection(values, (buf, value) -> buf.writeInt(value.ordinal())); + buffer.writeInt(colorCode); + } +} diff --git a/src/main/java/com/minelittlepony/api/pony/meta/Gender.java b/src/main/java/com/minelittlepony/api/pony/meta/Gender.java index 0ea755e7..5217ae29 100644 --- a/src/main/java/com/minelittlepony/api/pony/meta/Gender.java +++ b/src/main/java/com/minelittlepony/api/pony/meta/Gender.java @@ -1,7 +1,5 @@ package com.minelittlepony.api.pony.meta; -import com.minelittlepony.api.pony.TriggerPixelType; - public enum Gender implements TriggerPixelType { MARE(0), STALLION(0xffffff), diff --git a/src/main/java/com/minelittlepony/api/pony/meta/Race.java b/src/main/java/com/minelittlepony/api/pony/meta/Race.java index 97b42294..858a319d 100644 --- a/src/main/java/com/minelittlepony/api/pony/meta/Race.java +++ b/src/main/java/com/minelittlepony/api/pony/meta/Race.java @@ -1,7 +1,5 @@ package com.minelittlepony.api.pony.meta; -import com.minelittlepony.api.pony.TriggerPixelType; - import java.util.*; public enum Race implements TriggerPixelType { diff --git a/src/main/java/com/minelittlepony/api/pony/meta/Size.java b/src/main/java/com/minelittlepony/api/pony/meta/Size.java index f859fa75..dfe132ce 100644 --- a/src/main/java/com/minelittlepony/api/pony/meta/Size.java +++ b/src/main/java/com/minelittlepony/api/pony/meta/Size.java @@ -1,7 +1,5 @@ package com.minelittlepony.api.pony.meta; -import com.minelittlepony.api.pony.TriggerPixelType; - /** * Represents the different model sizes that are possible. * diff --git a/src/main/java/com/minelittlepony/api/pony/meta/TailLength.java b/src/main/java/com/minelittlepony/api/pony/meta/TailLength.java index c4152e41..daaafa22 100644 --- a/src/main/java/com/minelittlepony/api/pony/meta/TailLength.java +++ b/src/main/java/com/minelittlepony/api/pony/meta/TailLength.java @@ -1,7 +1,5 @@ package com.minelittlepony.api.pony.meta; -import com.minelittlepony.api.pony.TriggerPixelType; - public enum TailLength implements TriggerPixelType { STUB (0x425844), QUARTER (0xd19fe4), diff --git a/src/main/java/com/minelittlepony/api/pony/meta/TailShape.java b/src/main/java/com/minelittlepony/api/pony/meta/TailShape.java index e4c3a7be..97504723 100644 --- a/src/main/java/com/minelittlepony/api/pony/meta/TailShape.java +++ b/src/main/java/com/minelittlepony/api/pony/meta/TailShape.java @@ -1,7 +1,5 @@ package com.minelittlepony.api.pony.meta; -import com.minelittlepony.api.pony.TriggerPixelType; - public enum TailShape implements TriggerPixelType { STRAIGHT(0), BUMPY (0xfc539f), diff --git a/src/main/java/com/minelittlepony/api/pony/meta/TriggerPixel.java b/src/main/java/com/minelittlepony/api/pony/meta/TriggerPixel.java index 11f11d89..a33c52c8 100644 --- a/src/main/java/com/minelittlepony/api/pony/meta/TriggerPixel.java +++ b/src/main/java/com/minelittlepony/api/pony/meta/TriggerPixel.java @@ -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 > TriggerPixelType.Value readValue(NativeImage image) { + public > 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 & TriggerPixelType> TriggerPixelType.Flags readFlags(NativeImage image) { + public & TriggerPixelType> TriggerPixelType.Multiple 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 & TriggerPixelType> void readFlags(boolean[] out, NativeImage image) { diff --git a/src/main/java/com/minelittlepony/api/pony/TriggerPixelType.java b/src/main/java/com/minelittlepony/api/pony/meta/TriggerPixelType.java similarity index 80% rename from src/main/java/com/minelittlepony/api/pony/TriggerPixelType.java rename to src/main/java/com/minelittlepony/api/pony/meta/TriggerPixelType.java index 578ea03e..dfbb1838 100644 --- a/src/main/java/com/minelittlepony/api/pony/TriggerPixelType.java +++ b/src/main/java/com/minelittlepony/api/pony/meta/TriggerPixelType.java @@ -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 { return "#" + v; } - public record Flags & TriggerPixelType> ( + public record Multiple & TriggerPixelType> ( int colorCode, T def, boolean[] value @@ -94,21 +94,4 @@ public interface TriggerPixelType { return o.getClass() == def.getClass() && value()[((Enum)o).ordinal()]; } } - - public record Value ( - int colorCode, - T value - ) implements TriggerPixelType { - - @Override - public String name() { - return value instanceof TriggerPixelType t ? t.name() : TriggerPixelType.super.name(); - } - - @SuppressWarnings("unchecked") - @Override - public