From 9a59f2444ea55503b7c243646222b5ab6ceb8669 Mon Sep 17 00:00:00 2001 From: Sollace Date: Mon, 25 Sep 2023 00:49:38 +0100 Subject: [PATCH] Anyone can now use the seapony skin variant --- .../minelittlepony/api/pony/PonyPosture.java | 10 ++- .../client/hdskins/MineLPHDSkins.java | 4 +- .../client/model/ModelType.java | 25 ++---- .../client/model/PlayerModelKey.java | 20 +---- .../client/render/EquineRenderManager.java | 82 ++++++++----------- .../client/render/FrustrumCheck.java | 2 +- .../client/render/PonyRenderDispatcher.java | 44 +++++----- .../render/entity/AbstractPonyRenderer.java | 4 +- ...er.java => AquaticPlayerPonyRenderer.java} | 22 ++--- .../render/entity/PlayerPonyRenderer.java | 38 +++++---- 10 files changed, 106 insertions(+), 145 deletions(-) rename src/main/java/com/minelittlepony/client/render/entity/{PlayerSeaponyRenderer.java => AquaticPlayerPonyRenderer.java} (77%) diff --git a/src/main/java/com/minelittlepony/api/pony/PonyPosture.java b/src/main/java/com/minelittlepony/api/pony/PonyPosture.java index 3644d0ee..271902f6 100644 --- a/src/main/java/com/minelittlepony/api/pony/PonyPosture.java +++ b/src/main/java/com/minelittlepony/api/pony/PonyPosture.java @@ -2,7 +2,7 @@ package com.minelittlepony.api.pony; import com.minelittlepony.api.pony.meta.Race; import com.minelittlepony.client.SkinsProxy; -import com.minelittlepony.client.render.entity.PlayerSeaponyRenderer; +import com.minelittlepony.client.render.entity.AquaticPlayerPonyRenderer; import java.util.Optional; @@ -88,10 +88,14 @@ public final class PonyPosture { } public static boolean isSeaponyModifier(LivingEntity entity) { + return hasSeaponyForm(entity) && isPartiallySubmerged(entity); + } + + public static boolean hasSeaponyForm(LivingEntity entity) { return IPony.getManager().getPony(entity).filter(pony -> { return (pony.race() == Race.SEAPONY - || (entity instanceof AbstractClientPlayerEntity player && SkinsProxy.instance.getSkin(PlayerSeaponyRenderer.SKIN_TYPE_ID, player).isPresent()) - ) && PonyPosture.isPartiallySubmerged(entity); + || (entity instanceof AbstractClientPlayerEntity player && SkinsProxy.instance.getSkin(AquaticPlayerPonyRenderer.SKIN_TYPE_ID, player).isPresent()) + ); }).isPresent(); } } diff --git a/src/main/java/com/minelittlepony/client/hdskins/MineLPHDSkins.java b/src/main/java/com/minelittlepony/client/hdskins/MineLPHDSkins.java index 16cf620c..eb526393 100644 --- a/src/main/java/com/minelittlepony/client/hdskins/MineLPHDSkins.java +++ b/src/main/java/com/minelittlepony/client/hdskins/MineLPHDSkins.java @@ -29,7 +29,7 @@ import net.minecraft.item.Items; import net.minecraft.util.Identifier; import com.minelittlepony.client.pony.PonyManager; -import com.minelittlepony.client.render.entity.PlayerSeaponyRenderer; +import com.minelittlepony.client.render.entity.AquaticPlayerPonyRenderer; /** * All the interactions with HD Skins. @@ -44,7 +44,7 @@ public class MineLPHDSkins extends SkinsProxy implements ClientModInitializer { public void onInitializeClient() { SkinsProxy.instance = this; - seaponySkinType = SkinType.register(PlayerSeaponyRenderer.SKIN_TYPE_ID, Items.COD_BUCKET.getDefaultStack()); + seaponySkinType = SkinType.register(AquaticPlayerPonyRenderer.SKIN_TYPE_ID, Items.COD_BUCKET.getDefaultStack()); Wearable.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/model/ModelType.java b/src/main/java/com/minelittlepony/client/model/ModelType.java index 5350914d..8fc5e530 100644 --- a/src/main/java/com/minelittlepony/client/model/ModelType.java +++ b/src/main/java/com/minelittlepony/client/model/ModelType.java @@ -16,8 +16,6 @@ import com.minelittlepony.client.model.armour.PonyArmourModel; import com.minelittlepony.client.model.entity.*; import com.minelittlepony.client.model.entity.race.*; import com.minelittlepony.client.model.gear.*; -import com.minelittlepony.client.render.entity.PlayerPonyRenderer; -import com.minelittlepony.client.render.entity.PlayerSeaponyRenderer; import com.minelittlepony.mson.api.ModelKey; import com.minelittlepony.mson.api.Mson; import com.minelittlepony.mson.api.MsonModel; @@ -71,13 +69,9 @@ public final class ModelType { public static final PlayerModelKey> KIRIN = registerPlayer("kirin", Race.KIRIN, KirinModel::new); public static final PlayerModelKey> PEGASUS = registerPlayer("pegasus", Race.PEGASUS, PegasusModel::new); public static final PlayerModelKey> GRYPHON = registerPlayer("gryphon", Race.GRYPHON, PegasusModel::new); - public static final PlayerModelKey> HIPPOGRIFF = registerPlayer("hippogriff", Race.HIPPOGRIFF, PegasusModel::new, PonyArmourModel::new, (ctx, slim, dry) -> { - return new PlayerSeaponyRenderer(ctx, slim, getPlayerModel(Race.SEAPONY), dry); - }); + public static final PlayerModelKey> HIPPOGRIFF = registerPlayer("hippogriff", Race.HIPPOGRIFF, PegasusModel::new, PonyArmourModel::new); public static final PlayerModelKey> EARTH_PONY = registerPlayer("earth_pony", Race.EARTH, EarthPonyModel::new); - public static final PlayerModelKey> SEA_PONY = registerPlayer("sea_pony", Race.SEAPONY, SeaponyModel::new, SeaponyModel.Armour::new, (ctx, slim, wet) -> { - return new PlayerSeaponyRenderer(ctx, slim, wet, getPlayerModel(Race.UNICORN)); - }); + public static final PlayerModelKey> SEA_PONY = registerPlayer("sea_pony", Race.SEAPONY, SeaponyModel::new, SeaponyModel.Armour::new); public static final PlayerModelKey> BAT_PONY = registerPlayer("bat_pony", Race.BATPONY, PegasusModel::new); public static final PlayerModelKey> CHANGELING = registerPlayer("changeling", Race.CHANGELING, ChangelingModel::new); public static final PlayerModelKey> CHANGEDLING = registerPlayer("reformed_changeling", Race.CHANGEDLING, ChangelingModel::new); @@ -85,23 +79,14 @@ public final class ModelType { static PlayerModelKey registerPlayer(String name, Race race, BiFunction constructor) { - return registerPlayer(name, race, constructor, PlayerPonyRenderer::new); - } - - static PlayerModelKey registerPlayer(String name, Race race, - BiFunction constructor, - PlayerModelKey.RendererFactory rendererFactory) { - return registerPlayer(name, race, constructor, PonyArmourModel::new, rendererFactory); + return registerPlayer(name, race, constructor, PonyArmourModel::new); } @SuppressWarnings("unchecked") static PlayerModelKey registerPlayer(String name, Race race, BiFunction constructor, - MsonModel.Factory> armorFactory, - PlayerModelKey.RendererFactory rendererFactory) { - return (PlayerModelKey)PLAYER_MODELS.computeIfAbsent(race, r -> { - return new PlayerModelKey<>(name, constructor, rendererFactory, armorFactory); - }); + MsonModel.Factory> armorFactory) { + return (PlayerModelKey)PLAYER_MODELS.computeIfAbsent(race, r -> new PlayerModelKey<>(name, constructor, armorFactory)); } @SuppressWarnings("unchecked") diff --git a/src/main/java/com/minelittlepony/client/model/PlayerModelKey.java b/src/main/java/com/minelittlepony/client/model/PlayerModelKey.java index 0ec71298..bf41a414 100644 --- a/src/main/java/com/minelittlepony/client/model/PlayerModelKey.java +++ b/src/main/java/com/minelittlepony/client/model/PlayerModelKey.java @@ -2,9 +2,6 @@ package com.minelittlepony.client.model; import net.minecraft.client.model.Model; import net.minecraft.client.model.ModelPart; -import net.minecraft.client.network.AbstractClientPlayerEntity; -import net.minecraft.client.render.entity.EntityRendererFactory; -import net.minecraft.client.render.entity.PlayerEntityRenderer; import net.minecraft.entity.LivingEntity; import net.minecraft.util.Identifier; @@ -19,14 +16,12 @@ import java.util.function.*; public record PlayerModelKey ( ModelKey steveKey, ModelKey alexKey, - RendererFactory factory, MsonModel.Factory> armorFactory ) { - PlayerModelKey(String name, BiFunction modelFactory, RendererFactory rendererFactory, MsonModel.Factory> armorFactory) { + PlayerModelKey(String name, BiFunction modelFactory, MsonModel.Factory> armorFactory) { this( new ModelKeyImpl<>(new Identifier("minelittlepony", "races/steve/" + name), tree -> modelFactory.apply(tree, false)), new ModelKeyImpl<>(new Identifier("minelittlepony", "races/alex/" + name), tree -> modelFactory.apply(tree, true)), - rendererFactory, armorFactory ); } @@ -43,17 +38,4 @@ public record PlayerModelKey ModelWrapper create(boolean slimArms, @Nullable Consumer initializer) { return new ModelWrapper(this, slimArms, initializer); } - - @SuppressWarnings("unchecked") - public Function getFactory(boolean slimArms) { - return d -> factory.create(d, slimArms, (PlayerModelKey>)this); - } - - public interface RendererFactory { - PlayerEntityRenderer create( - EntityRendererFactory.Context context, - boolean slim, - PlayerModelKey> key - ); - } } diff --git a/src/main/java/com/minelittlepony/client/render/EquineRenderManager.java b/src/main/java/com/minelittlepony/client/render/EquineRenderManager.java index d35d0128..37751f13 100644 --- a/src/main/java/com/minelittlepony/client/render/EquineRenderManager.java +++ b/src/main/java/com/minelittlepony/client/render/EquineRenderManager.java @@ -24,14 +24,11 @@ import net.minecraft.client.util.math.MatrixStack; import net.minecraft.entity.Entity; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.util.Identifier; public class EquineRenderManager & IPonyModel> { private ModelWrapper playerModel; - private IPony pony; - private final IPonyRenderContext renderer; private final FrustrumCheck frustrum = new FrustrumCheck<>(this); @@ -44,6 +41,28 @@ public class EquineRenderManager getContext() { + return renderer; + } + + public ModelWrapper getModelWrapper() { + return playerModel; + } + + public M getModel() { + return playerModel.body(); + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + public ModelWrapper setModel(ModelKey key) { + return setModel(new ModelWrapper(key)); + } + + public ModelWrapper setModel(ModelWrapper wrapper) { + playerModel = wrapper; + return wrapper; + } + public Frustum getFrustrum(T entity, Frustum vanilla) { if (RenderPass.getCurrent() == RenderPass.HUD) { return FrustrumCheck.ALWAYS_VISIBLE; @@ -55,15 +74,6 @@ public class EquineRenderManager getModelWrapper() { - return playerModel; - } - - @SuppressWarnings({"rawtypes", "unchecked"}) - public ModelWrapper setModel(ModelKey key) { - return setModel(new ModelWrapper(key)); - } - - public ModelWrapper setModel(ModelWrapper wrapper) { - playerModel = wrapper; - return wrapper; - } - - public void updateMetadata(Identifier texture) { - pony = IPony.getManager().getPony(texture); - playerModel.applyMetadata(pony.metadata()); - } - public IPony updateModel(T entity, ModelAttributes.Mode mode) { - pony = renderer.getEntityPony(entity); + IPony pony = renderer.getEntityPony(entity); playerModel.applyMetadata(pony.metadata()); if (pony.hasMetadata() && entity instanceof RegistrationHandler && ((RegistrationHandler)entity).shouldUpdateRegistration(pony)) { @@ -144,18 +140,6 @@ public class EquineRenderManager extends Frustum { @Override public boolean isVisible(Box bounds) { - return vanilla.isVisible(PonyBounds.getBoundingBox(renderer.getPony(entity), entity)); + return vanilla.isVisible(PonyBounds.getBoundingBox(renderer.getContext().getEntityPony(entity), entity)); } @Override diff --git a/src/main/java/com/minelittlepony/client/render/PonyRenderDispatcher.java b/src/main/java/com/minelittlepony/client/render/PonyRenderDispatcher.java index 1d64fa6e..823f3ae9 100644 --- a/src/main/java/com/minelittlepony/client/render/PonyRenderDispatcher.java +++ b/src/main/java/com/minelittlepony/client/render/PonyRenderDispatcher.java @@ -1,21 +1,18 @@ package com.minelittlepony.client.render; -import java.util.Locale; import java.util.function.Function; -import java.util.function.Predicate; - import com.minelittlepony.api.pony.IPony; -import com.minelittlepony.api.pony.meta.Race; +import com.minelittlepony.api.pony.PonyPosture; import com.minelittlepony.client.mixin.MixinEntityRenderers; import com.minelittlepony.client.model.IPonyModel; -import com.minelittlepony.client.model.ModelType; +import com.minelittlepony.client.render.entity.PlayerPonyRenderer; +import com.minelittlepony.client.render.entity.AquaticPlayerPonyRenderer; import org.jetbrains.annotations.Nullable; import com.minelittlepony.mson.api.Mson; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.network.AbstractClientPlayerEntity; import net.minecraft.client.render.entity.*; import net.minecraft.client.render.entity.model.EntityModel; import net.minecraft.client.util.SkinTextures; @@ -38,27 +35,30 @@ public class PonyRenderDispatcher { * Registers all new player skin types. (currently only pony and slimpony). */ public void initialise(EntityRenderDispatcher manager, boolean force) { - Race.REGISTRY.forEach(r -> { - if (!r.isHuman()) { - registerPlayerSkin(manager, r); - } - }); + for (SkinTextures.Model armShape : SkinTextures.Model.values()) { + addPlayerRenderer(armShape); + } MobRenderers.REGISTRY.values().forEach(i -> i.apply(this, force)); } - private void registerPlayerSkin(EntityRenderDispatcher manager, Race race) { - addPlayerSkin(manager, SkinTextures.Model.SLIM, race); - addPlayerSkin(manager, SkinTextures.Model.WIDE, race); - } - - private void addPlayerSkin(EntityRenderDispatcher manager, SkinTextures.Model armShape, Race race) { + private void addPlayerRenderer(SkinTextures.Model armShape) { Mson.getInstance().getEntityRendererRegistry().registerPlayerRenderer( - new Identifier("minelittlepony", race.name().toLowerCase(Locale.ROOT) + "/" + armShape.getName()), - (Predicate)(player -> { - return IPony.getManager().getPony(player).metadata().getRace() == race + new Identifier("minelittlepony", "sea/" + armShape.getName()), + player -> { + return !IPony.getManager().getPony(player).race().isHuman() + && PonyPosture.hasSeaponyForm(player) && player.method_52814().model() == armShape; - }), - ModelType.getPlayerModel(race).getFactory(armShape == SkinTextures.Model.SLIM) + }, + context -> new AquaticPlayerPonyRenderer(context, false) + ); + Mson.getInstance().getEntityRendererRegistry().registerPlayerRenderer( + new Identifier("minelittlepony", "land/" + armShape.getName()), + player -> { + return !IPony.getManager().getPony(player).race().isHuman() + && !PonyPosture.hasSeaponyForm(player) + && player.method_52814().model() == armShape; + }, + context -> new PlayerPonyRenderer(context, false) ); } diff --git a/src/main/java/com/minelittlepony/client/render/entity/AbstractPonyRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/AbstractPonyRenderer.java index 3b9febd0..767762cd 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/AbstractPonyRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/AbstractPonyRenderer.java @@ -64,7 +64,7 @@ public abstract class AbstractPonyRenderer> wetPony; - private final ModelWrapper> dryPony; - private boolean wet; - public PlayerSeaponyRenderer(EntityRendererFactory.Context context, boolean slim, - PlayerModelKey> wetModel, - PlayerModelKey> dryModel) { - super(context, slim, wetModel); - - dryPony = dryModel.>create(slim); - wetPony = getInternalRenderer().getModelWrapper(); + public AquaticPlayerPonyRenderer(EntityRendererFactory.Context context, boolean slim) { + super(context, slim); } @Override @@ -53,6 +45,11 @@ public class PlayerSeaponyRenderer extends PlayerPonyRenderer { } } + protected Race getPlayerRace(AbstractClientPlayerEntity entity, IPony pony) { + Race race = super.getPlayerRace(entity, pony); + return wet ? Race.SEAPONY : race == Race.SEAPONY ? Race.UNICORN : race; + } + @Override protected void setupTransforms(AbstractClientPlayerEntity entity, MatrixStack stack, float ageInTicks, float rotationYaw, float partialTicks) { if (wet) { @@ -73,7 +70,6 @@ public class PlayerSeaponyRenderer extends PlayerPonyRenderer { private void updateSeaponyState(AbstractClientPlayerEntity player) { IPony pony = getEntityPony(player); wet = PonyPosture.isSeaponyModifier(player); - model = manager.setModel(wet ? wetPony : dryPony).body(); float state = wet ? 100 : 0; float interpolated = pony.metadata().getInterpolator(player.getUuid()).interpolate("seapony_state", state, 5); diff --git a/src/main/java/com/minelittlepony/client/render/entity/PlayerPonyRenderer.java b/src/main/java/com/minelittlepony/client/render/entity/PlayerPonyRenderer.java index 8a1c80f2..9a266dd6 100644 --- a/src/main/java/com/minelittlepony/client/render/entity/PlayerPonyRenderer.java +++ b/src/main/java/com/minelittlepony/client/render/entity/PlayerPonyRenderer.java @@ -2,6 +2,7 @@ package com.minelittlepony.client.render.entity; import com.minelittlepony.api.model.ModelAttributes; import com.minelittlepony.api.pony.IPony; +import com.minelittlepony.api.pony.meta.Race; import com.minelittlepony.api.pony.meta.Wearable; import com.minelittlepony.client.SkinsProxy; import com.minelittlepony.client.model.*; @@ -9,9 +10,11 @@ import com.minelittlepony.client.render.DebugBoundingBoxRenderer; import com.minelittlepony.client.render.IPonyRenderContext; import com.minelittlepony.client.render.entity.feature.*; import com.minelittlepony.client.util.render.RenderLayerUtil; -import com.minelittlepony.client.render.EquineRenderManager; -import java.util.List; +import java.util.*; +import java.util.function.Function; + +import com.minelittlepony.client.render.EquineRenderManager; import net.minecraft.block.BedBlock; import net.minecraft.client.MinecraftClient; @@ -22,19 +25,18 @@ import net.minecraft.client.render.entity.PlayerEntityRenderer; import net.minecraft.client.render.entity.feature.*; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.text.Text; -import net.minecraft.util.Arm; -import net.minecraft.util.Identifier; +import net.minecraft.util.*; import net.minecraft.util.math.*; public class PlayerPonyRenderer extends PlayerEntityRenderer implements IPonyRenderContext> { protected final EquineRenderManager> manager = new EquineRenderManager<>(this); - public PlayerPonyRenderer(EntityRendererFactory.Context context, boolean slim, PlayerModelKey> key) { + private final Function>> modelsCache; + + public PlayerPonyRenderer(EntityRendererFactory.Context context, boolean slim) { super(context, slim); - - this.model = manager.setModel(key.create(slim)).body(); - + modelsCache = Util.memoize(race -> ModelType.getPlayerModel(race).create(slim)); addLayers(context); } @@ -75,16 +77,18 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements IPonyRen @Override public void render(AbstractClientPlayerEntity entity, float entityYaw, float tickDelta, MatrixStack stack, VertexConsumerProvider renderContext, int lightUv) { - model = manager.getModel(); // EntityModelFeatures: We have to force it to use our models otherwise EMF overrides it and breaks pony rendering - shadowRadius = manager.getShadowScale(); + IPony 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().getShadowSize(); super.render(entity, entityYaw, tickDelta, stack, renderContext, lightUv); - DebugBoundingBoxRenderer.render(manager.getPony(entity), this, entity, stack, renderContext, tickDelta); + DebugBoundingBoxRenderer.render(pony, this, entity, stack, renderContext, tickDelta); // Translate the shadow position after everything is done // (shadows are drawn after us) if (!entity.hasVehicle() && !entity.isSleeping()) { float yaw = MathHelper.lerpAngleDegrees(tickDelta, entity.prevBodyYaw, entity.bodyYaw); - float l = entity.getWidth() / 2 * manager.getPony(entity).metadata().getSize().getScaleFactor(); + float l = entity.getWidth() / 2 * pony.metadata().getSize().getScaleFactor(); stack.multiply(RotationAxis.NEGATIVE_Y.rotationDegrees(yaw)); stack.translate(0, 0, -l); @@ -92,6 +96,10 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements IPonyRen } } + protected Race getPlayerRace(AbstractClientPlayerEntity entity, IPony pony) { + return pony.race(); + } + @Override protected void setupTransforms(AbstractClientPlayerEntity entity, MatrixStack stack, float ageInTicks, float rotationYaw, float partialTicks) { manager.preRenderCallback(entity, stack, partialTicks); @@ -136,6 +144,8 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements IPonyRen } protected void renderArm(MatrixStack stack, VertexConsumerProvider renderContext, int lightUv, AbstractClientPlayerEntity player, Arm side) { + IPony pony = getEntityPony(player); + model = manager.setModel(modelsCache.apply(getPlayerRace(player, pony))).body(); manager.updateModel(player, ModelAttributes.Mode.FIRST_PERSON); stack.push(); @@ -165,7 +175,7 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements IPonyRen @Override public Identifier getTexture(AbstractClientPlayerEntity player) { - return manager.getTexture(player); + return getEntityPony(player).texture(); } @Override @@ -182,7 +192,7 @@ public class PlayerPonyRenderer extends PlayerEntityRenderer implements IPonyRen public Identifier getDefaultTexture(AbstractClientPlayerEntity entity, Wearable wearable) { return SkinsProxy.instance.getSkin(wearable.getId(), entity).orElseGet(() -> { if (wearable.isSaddlebags() && getInternalRenderer().getModel().getMetadata().getRace().supportsLegacySaddlebags()) { - return manager.getTexture(entity); + return getTexture(entity); } return wearable.getDefaultTexture();