diff --git a/src/main/java/com/minelittlepony/api/model/PreviewModel.java b/src/main/java/com/minelittlepony/api/model/PreviewModel.java index ef68773f..1bfdc008 100644 --- a/src/main/java/com/minelittlepony/api/model/PreviewModel.java +++ b/src/main/java/com/minelittlepony/api/model/PreviewModel.java @@ -2,4 +2,6 @@ package com.minelittlepony.api.model; public interface PreviewModel { boolean forceSeapony(); + + boolean forceNirik(); } diff --git a/src/main/java/com/minelittlepony/api/pony/DefaultPonySkinHelper.java b/src/main/java/com/minelittlepony/api/pony/DefaultPonySkinHelper.java index 5eb9065d..432f4bb2 100644 --- a/src/main/java/com/minelittlepony/api/pony/DefaultPonySkinHelper.java +++ b/src/main/java/com/minelittlepony/api/pony/DefaultPonySkinHelper.java @@ -12,6 +12,7 @@ public final class DefaultPonySkinHelper { public static final Identifier STEVE = new Identifier("minelittlepony", "textures/entity/player/wide/steve_pony.png"); public static final Identifier SEAPONY_SKIN_TYPE_ID = new Identifier("minelp", "seapony"); + public static final Identifier NIRIK_SKIN_TYPE_ID = new Identifier("minelp", "nirik"); private static final Map SKINS = new HashMap<>(); diff --git a/src/main/java/com/minelittlepony/api/pony/PonyPosture.java b/src/main/java/com/minelittlepony/api/pony/PonyPosture.java index cbc28e3d..b929eabd 100644 --- a/src/main/java/com/minelittlepony/api/pony/PonyPosture.java +++ b/src/main/java/com/minelittlepony/api/pony/PonyPosture.java @@ -103,4 +103,23 @@ public final class PonyPosture { ); }).isPresent(); } + + public static boolean isNirikModifier(LivingEntity entity) { + if (entity instanceof PreviewModel preview) { + return preview.forceNirik(); + } + return false; + } + + + public static boolean hasNirikForm(LivingEntity entity) { + if (entity instanceof PreviewModel preview) { + return preview.forceNirik(); + } + return Pony.getManager().getPony(entity).filter(pony -> { + return (pony.race() == Race.KIRIN + && (entity instanceof AbstractClientPlayerEntity player && SkinsProxy.instance.getSkin(DefaultPonySkinHelper.NIRIK_SKIN_TYPE_ID, player).isPresent()) + ); + }).isPresent(); + } } diff --git a/src/main/java/com/minelittlepony/client/compat/hdskins/DummyPony.java b/src/main/java/com/minelittlepony/client/compat/hdskins/DummyPony.java index 059d8a40..93a45ab6 100644 --- a/src/main/java/com/minelittlepony/client/compat/hdskins/DummyPony.java +++ b/src/main/java/com/minelittlepony/client/compat/hdskins/DummyPony.java @@ -23,4 +23,9 @@ class DummyPony extends DummyPlayer implements PreviewModel, PonyManager.ForcedP public boolean forceSeapony() { return getTextures().getPosture().getActiveSkinType() == MineLPHDSkins.seaponySkinType; } + + @Override + public boolean forceNirik() { + return getTextures().getPosture().getActiveSkinType() == MineLPHDSkins.nirikSkinType; + } } diff --git a/src/main/java/com/minelittlepony/client/compat/hdskins/MineLPHDSkins.java b/src/main/java/com/minelittlepony/client/compat/hdskins/MineLPHDSkins.java index 09d8b0d3..d697fb6c 100644 --- a/src/main/java/com/minelittlepony/client/compat/hdskins/MineLPHDSkins.java +++ b/src/main/java/com/minelittlepony/client/compat/hdskins/MineLPHDSkins.java @@ -35,6 +35,7 @@ import com.minelittlepony.client.*; public class MineLPHDSkins extends SkinsProxy implements ClientModInitializer { static SkinType seaponySkinType; + static SkinType nirikSkinType; static final Map wearableTypes = new HashMap<>(); @@ -44,6 +45,7 @@ public class MineLPHDSkins extends SkinsProxy implements ClientModInitializer { PonySettingsScreen.buttonFactory = this::renderOption; seaponySkinType = SkinType.register(DefaultPonySkinHelper.SEAPONY_SKIN_TYPE_ID, Items.COD_BUCKET.getDefaultStack()); + nirikSkinType = SkinType.register(DefaultPonySkinHelper.NIRIK_SKIN_TYPE_ID, Items.LAVA_BUCKET.getDefaultStack()); Wearable.REGISTRY.values().forEach(wearable -> { if (wearable != Wearable.NONE) { wearableTypes.put(SkinType.register(wearable.getId(), Items.BUNDLE.getDefaultStack()), wearable); diff --git a/src/main/java/com/minelittlepony/client/compat/hdskins/PonifiedDualCarouselWidget.java b/src/main/java/com/minelittlepony/client/compat/hdskins/PonifiedDualCarouselWidget.java index 59b0abb6..60b48817 100644 --- a/src/main/java/com/minelittlepony/client/compat/hdskins/PonifiedDualCarouselWidget.java +++ b/src/main/java/com/minelittlepony/client/compat/hdskins/PonifiedDualCarouselWidget.java @@ -31,6 +31,9 @@ class PonifiedDualCarouselWidget extends DualCarouselWidget { if (type == MineLPHDSkins.seaponySkinType) { return NativeImageFilters.GREYSCALE.load(SeaponyRenderer.SEAPONY, SeaponyRenderer.SEAPONY, getExclusion()); } + if (type == MineLPHDSkins.nirikSkinType) { + return super.getDefaultSkin(SkinType.SKIN, modelVariant); + } Wearable wearable = MineLPHDSkins.wearableTypes.getOrDefault(type, Wearable.NONE); diff --git a/src/main/java/com/minelittlepony/client/render/PonyRenderDispatcher.java b/src/main/java/com/minelittlepony/client/render/PonyRenderDispatcher.java index 6e50f407..5220859b 100644 --- a/src/main/java/com/minelittlepony/client/render/PonyRenderDispatcher.java +++ b/src/main/java/com/minelittlepony/client/render/PonyRenderDispatcher.java @@ -3,11 +3,9 @@ package com.minelittlepony.client.render; import java.util.function.Function; import com.minelittlepony.api.model.PonyModel; -import com.minelittlepony.api.pony.Pony; -import com.minelittlepony.api.pony.PonyPosture; +import com.minelittlepony.api.pony.*; import com.minelittlepony.client.mixin.MixinEntityRenderers; -import com.minelittlepony.client.render.entity.AquaticPlayerPonyRenderer; -import com.minelittlepony.client.render.entity.PlayerPonyRenderer; +import com.minelittlepony.client.render.entity.*; import org.jetbrains.annotations.Nullable; @@ -52,11 +50,20 @@ public class PonyRenderDispatcher { }, context -> new AquaticPlayerPonyRenderer(context, armShape == SkinTextures.Model.SLIM) ); + Mson.getInstance().getEntityRendererRegistry().registerPlayerRenderer( + new Identifier("minelittlepony", "nirik/" + armShape.getName()), + player -> { + return !Pony.getManager().getPony(player).race().isHuman() + && PonyPosture.hasNirikForm(player) + && player.method_52814().model() == armShape; + }, + context -> new FormChangingPlayerPonyRenderer(context, armShape == SkinTextures.Model.SLIM, DefaultPonySkinHelper.NIRIK_SKIN_TYPE_ID, PonyPosture::isNirikModifier) + ); Mson.getInstance().getEntityRendererRegistry().registerPlayerRenderer( new Identifier("minelittlepony", "land/" + armShape.getName()), player -> { return !Pony.getManager().getPony(player).race().isHuman() - && !PonyPosture.hasSeaponyForm(player) + && !PonyPosture.hasSeaponyForm(player) && !PonyPosture.hasNirikForm(player) && player.method_52814().model() == armShape; }, context -> new PlayerPonyRenderer(context, armShape == SkinTextures.Model.SLIM) diff --git a/src/main/java/com/minelittlepony/client/render/entity/AquaticPlayerPonyRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/AquaticPlayerPonyRenderer.java index fcb70c05..c6390289 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/AquaticPlayerPonyRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/AquaticPlayerPonyRenderer.java @@ -10,38 +10,26 @@ import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.entity.EntityRendererFactory; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.particle.ParticleTypes; -import net.minecraft.util.Arm; -import net.minecraft.util.Identifier; -public class AquaticPlayerPonyRenderer extends PlayerPonyRenderer { - private boolean wet; +public class AquaticPlayerPonyRenderer extends FormChangingPlayerPonyRenderer { public AquaticPlayerPonyRenderer(EntityRendererFactory.Context context, boolean slim) { - super(context, slim); - } - - @Override - public Identifier getTexture(AbstractClientPlayerEntity player) { - if (wet) { - return SkinsProxy.instance.getSkin(DefaultPonySkinHelper.SEAPONY_SKIN_TYPE_ID, player).orElseGet(() -> super.getTexture(player)); - } - return super.getTexture(player); + super(context, slim, DefaultPonySkinHelper.SEAPONY_SKIN_TYPE_ID, PonyPosture::isSeaponyModifier); } @Override public void render(AbstractClientPlayerEntity player, float entityYaw, float tickDelta, MatrixStack stack, VertexConsumerProvider renderContext, int light) { super.render(player, entityYaw, tickDelta, stack, renderContext, light); - updateSeaponyState(player); - if (!(player instanceof PreviewModel) && wet && player.getVelocity().length() > 0.1F) { + if (!(player instanceof PreviewModel) && transformed && player.getVelocity().length() > 0.1F) { double x = player.getEntityWorld().getRandom().nextTriangular(player.getX(), 1); double y = player.getEntityWorld().getRandom().nextTriangular(player.getY(), 1); double z = player.getEntityWorld().getRandom().nextTriangular(player.getZ(), 1); - player.getEntityWorld().addParticle(ParticleTypes.BUBBLE, x, y, z, 0, 0, 0); } } + @Override protected Race getPlayerRace(AbstractClientPlayerEntity entity, Pony pony) { Race race = super.getPlayerRace(entity, pony); return PonyPosture.isSeaponyModifier(entity) ? Race.SEAPONY : race == Race.SEAPONY ? Race.UNICORN : race; @@ -59,15 +47,10 @@ public class AquaticPlayerPonyRenderer extends PlayerPonyRenderer { } @Override - protected void renderArm(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, AbstractClientPlayerEntity player, Arm side) { - super.renderArm(stack, renderContext, lightUv, player, side); - updateSeaponyState(player); - } - - private void updateSeaponyState(AbstractClientPlayerEntity player) { - wet = PonyPosture.isSeaponyModifier(player); + protected void updateForm(AbstractClientPlayerEntity player) { + super.updateForm(player); if (!(player instanceof PreviewModel)) { - float state = wet ? 100 : 0; + float state = transformed ? 100 : 0; float interpolated = getInternalRenderer().getModels().body().getAttributes().getMainInterpolator().interpolate("seapony_state", state, 5); if (!MathUtil.compareFloats(interpolated, state)) { diff --git a/src/main/java/com/minelittlepony/client/render/entity/FormChangingPlayerPonyRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/FormChangingPlayerPonyRenderer.java new file mode 100644 index 00000000..da571585 --- /dev/null +++ b/src/main/java/com/minelittlepony/client/render/entity/FormChangingPlayerPonyRenderer.java @@ -0,0 +1,50 @@ +package com.minelittlepony.client.render.entity; + +import com.minelittlepony.api.pony.*; + +import java.util.function.Predicate; + +import net.minecraft.client.network.AbstractClientPlayerEntity; +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.entity.EntityRendererFactory; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.Arm; +import net.minecraft.util.Identifier; + +public class FormChangingPlayerPonyRenderer extends PlayerPonyRenderer { + protected boolean transformed; + + private final Identifier alternateFormSkinId; + private final Predicate formModifierPredicate; + + public FormChangingPlayerPonyRenderer(EntityRendererFactory.Context context, + boolean slim, Identifier alternateFormSkinId, Predicate formModifierPredicate) { + super(context, slim); + this.alternateFormSkinId = alternateFormSkinId; + this.formModifierPredicate = formModifierPredicate; + } + + @Override + public Identifier getTexture(AbstractClientPlayerEntity player) { + if (transformed) { + return SkinsProxy.instance.getSkin(alternateFormSkinId, player).orElseGet(() -> super.getTexture(player)); + } + return super.getTexture(player); + } + + @Override + public void render(AbstractClientPlayerEntity player, float entityYaw, float tickDelta, MatrixStack stack, VertexConsumerProvider renderContext, int light) { + super.render(player, entityYaw, tickDelta, stack, renderContext, light); + updateForm(player); + } + + @Override + protected void renderArm(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, AbstractClientPlayerEntity player, Arm side) { + super.renderArm(stack, renderContext, lightUv, player, side); + updateForm(player); + } + + protected void updateForm(AbstractClientPlayerEntity player) { + transformed = formModifierPredicate.test(player); + } +} diff --git a/src/main/resources/assets/minelittlepony/lang/en_us.json b/src/main/resources/assets/minelittlepony/lang/en_us.json index cd86f801..ada3bd8a 100644 --- a/src/main/resources/assets/minelittlepony/lang/en_us.json +++ b/src/main/resources/assets/minelittlepony/lang/en_us.json @@ -54,7 +54,8 @@ "minelp.debug.race": "Race Override", "minelp.debug.armour": "Disable ponified armour textures", - "skin_type.minelp.seapony": "Seapony", + "skin_type.minelp.seapony": "Seapony Form", + "skin_type.minelp.nirik": "Kirin Nirik Form", "skin_type.minelittlepony.crown": "Crown", "skin_type.minelittlepony.muffin": "Muffin Hat", "skin_type.minelittlepony.hat": "Witch Hat", diff --git a/src/main/resources/assets/minelp/textures/gui/skin_type/nirik.png b/src/main/resources/assets/minelp/textures/gui/skin_type/nirik.png new file mode 100644 index 00000000..c615cdce Binary files /dev/null and b/src/main/resources/assets/minelp/textures/gui/skin_type/nirik.png differ