mirror of
https://github.com/MineLittlePony/MineLittlePony.git
synced 2025-02-13 00:04:23 +01:00
Merge branch '1.21.3' into 1.21.4
# Conflicts: # src/main/java/com/minelittlepony/client/render/entity/feature/ArmourFeature.java
This commit is contained in:
commit
6b7b33958b
6 changed files with 109 additions and 8 deletions
|
@ -1 +1 @@
|
|||
Subproject commit 1ae97d064e7579d94a93f2784473dc7ce0e1e670
|
||||
Subproject commit 913c35681b09cfbab0bf5def678db3407f5834bb
|
|
@ -77,6 +77,15 @@ public class PonyConfig extends Config {
|
|||
.addComment("Disables certain easter eggs and secrets (party pooper)")
|
||||
.addComment("Turning this off may help with compatibility in some cases");
|
||||
|
||||
public final Setting<Boolean> enableFabricModelsApiSupport = value("settings", "enableFabricModelsApiSupport", false)
|
||||
.addComment("Enables rendering of modded armour registered via the fabric api")
|
||||
.addComment("Note that since any armour registered in this way is designed to work for the human model, pieces may not fit exactly.")
|
||||
.addComment("i.e. Anything that goes on the plyer's backs needs to be rotated by the mod developer when rendered on a pony")
|
||||
.addComment("Developers: To know if you're being rendered on a pony model, check the renderstate or model class with")
|
||||
.addComment(" state instanceof com.minelittlepony.api.model.PonyModel$AttributedHolder or model instanceof com.minelittlepony.api.model.PonyModel")
|
||||
.addComment(" Note that the matrix stack your receieve is pre-transformed for the body part your model is attached to, so if you intend to call model.transform(state, part, matrices)")
|
||||
.addComment(" with a different part (ie BACK) you must pop the stack to revert to the previous first.");
|
||||
|
||||
public final Setting<VisibilityMode> horseButton = value("horseButton", VisibilityMode.AUTO)
|
||||
.addComment("Whether to show the mine little pony settings button on the main menu")
|
||||
.addComment("AUTO (default) - only show when HDSkins is not installed")
|
||||
|
|
|
@ -23,7 +23,6 @@ import com.minelittlepony.api.model.Models;
|
|||
import com.minelittlepony.client.model.AbstractPonyModel;
|
||||
import com.minelittlepony.client.model.ClientPonyModel;
|
||||
import com.minelittlepony.client.render.entity.state.PonyRenderState;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class PonifiedEquipmentRenderer extends EquipmentRenderer {
|
||||
|
|
|
@ -1,21 +1,31 @@
|
|||
package com.minelittlepony.client.render.entity.feature;
|
||||
|
||||
import com.minelittlepony.api.model.Models;
|
||||
import com.minelittlepony.api.config.PonyConfig;
|
||||
import com.minelittlepony.api.model.*;
|
||||
import com.minelittlepony.client.model.ClientPonyModel;
|
||||
import com.minelittlepony.client.model.armour.*;
|
||||
import com.minelittlepony.client.render.PonyRenderContext;
|
||||
import com.minelittlepony.client.render.entity.state.PonyRenderState;
|
||||
import com.minelittlepony.client.util.render.MatrixStackUtil;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import net.fabricmc.fabric.api.client.rendering.v1.ArmorRenderer;
|
||||
import net.fabricmc.fabric.impl.client.rendering.ArmorRendererRegistryImpl;
|
||||
import net.minecraft.client.render.*;
|
||||
import net.minecraft.client.render.entity.equipment.EquipmentModel;
|
||||
import net.minecraft.client.render.entity.equipment.EquipmentModelLoader;
|
||||
import net.minecraft.client.render.entity.model.BipedEntityModel;
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
import net.minecraft.component.DataComponentTypes;
|
||||
import net.minecraft.component.type.EquippableComponent;
|
||||
import net.minecraft.entity.EquipmentSlot;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.item.*;
|
||||
import net.minecraft.util.Unit;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ArmourFeature<
|
||||
|
@ -23,6 +33,9 @@ public class ArmourFeature<
|
|||
S extends PonyRenderState,
|
||||
M extends ClientPonyModel<S>
|
||||
> extends AbstractPonyFeature<S, M> {
|
||||
private static final Logger LOGGER = LogManager.getLogger("PonifiedEquipmentRenderer");
|
||||
|
||||
private static boolean FABRIC_API_FAILURE;
|
||||
|
||||
private final PonifiedEquipmentRenderer equipmentRenderer;
|
||||
|
||||
|
@ -58,17 +71,77 @@ public class ArmourFeature<
|
|||
ArmourRendererPlugin plugin = ArmourRendererPlugin.INSTANCE.get();
|
||||
|
||||
for (ItemStack stack : plugin.getArmorStacks(entity, armorSlot, layerType, ArmourRendererPlugin.ArmourType.ARMOUR)) {
|
||||
EquippableComponent equippableComponent = stack.get(DataComponentTypes.EQUIPPABLE);
|
||||
|
||||
if (hasModel(equippableComponent, armorSlot)) {
|
||||
equipmentRenderer.render(armorSlot, layerType, equippableComponent.assetId().orElseThrow(), entity, models, stack, matrices, vertices, light);
|
||||
}
|
||||
render(armorSlot, layerType, entity, models, stack, matrices, vertices, light, equipmentRenderer);
|
||||
}
|
||||
|
||||
plugin.onArmourRendered(entity, matrices, vertices, armorSlot, layerType, ArmourRendererPlugin.ArmourType.ARMOUR);
|
||||
}
|
||||
|
||||
private static <S extends PonyRenderState, V extends ClientPonyModel<S>> void render(
|
||||
EquipmentSlot slot,
|
||||
EquipmentModel.LayerType layerType,
|
||||
S entity,
|
||||
Models<V> models,
|
||||
ItemStack stack,
|
||||
MatrixStack matrices,
|
||||
VertexConsumerProvider vertices,
|
||||
int light, PonifiedEquipmentRenderer equipmentRenderer
|
||||
) {
|
||||
if (!FABRIC_API_FAILURE && PonyConfig.getInstance().enableFabricModelsApiSupport.get()) {
|
||||
try {
|
||||
if (FabricArmorRendererInvoker.renderArmor(stack, models, matrices, vertices, light, entity, slot, layerType)) {
|
||||
return;
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
LOGGER.error("Failure calling fabric armor rendering api", t);
|
||||
FABRIC_API_FAILURE = true;
|
||||
}
|
||||
}
|
||||
EquippableComponent equippableComponent = stack.get(DataComponentTypes.EQUIPPABLE);
|
||||
if (hasModel(equippableComponent, slot)) {
|
||||
equipmentRenderer.render(slot, layerType, equippableComponent.assetId().orElseThrow(), entity, models, stack, matrices, vertices, light, null);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean hasModel(@Nullable EquippableComponent component, EquipmentSlot slot) {
|
||||
return component != null && component.assetId().isPresent() && component.slot() == slot;
|
||||
}
|
||||
|
||||
private static final class FabricArmorRendererInvoker {
|
||||
private static final Map<ArmorRenderer, Unit> FAILING_RENDERERS = new WeakHashMap<>();
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
private static <S extends PonyRenderState, V extends ClientPonyModel<S>> boolean renderArmor(
|
||||
ItemStack stack,
|
||||
Models<V> models, MatrixStack matrices,
|
||||
VertexConsumerProvider vertices, int light, S entity,
|
||||
EquipmentSlot armorSlot, EquipmentModel.LayerType layerType) {
|
||||
ArmorRenderer renderer = ArmorRendererRegistryImpl.get(stack.getItem());
|
||||
|
||||
if (renderer != null && !FAILING_RENDERERS.containsKey(renderer)) {
|
||||
MatrixStack isolation = MatrixStackUtil.pushIsolation(matrices);
|
||||
try {
|
||||
isolation.push();
|
||||
models.body().transform(entity, getBodyPart(armorSlot), isolation);
|
||||
renderer.render(isolation, vertices, stack, entity, armorSlot, light, (BipedEntityModel)models.body());
|
||||
isolation.pop();
|
||||
} catch (Throwable t) {
|
||||
LOGGER.error("Exception occured whilst rendering custom armor via fabric api. Renderer {} has been disabled", renderer, t);
|
||||
FAILING_RENDERERS.put(renderer, Unit.INSTANCE);
|
||||
} finally {
|
||||
MatrixStackUtil.popIsolation();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static BodyPart getBodyPart(EquipmentSlot slot) {
|
||||
return switch (slot) {
|
||||
case HEAD -> BodyPart.HEAD;
|
||||
case CHEST, BODY -> BodyPart.BODY;
|
||||
case LEGS, FEET, MAINHAND, OFFHAND -> BodyPart.LEGS;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package com.minelittlepony.client.util.render;
|
||||
|
||||
import net.minecraft.client.util.math.MatrixStack;
|
||||
|
||||
public class MatrixStackUtil {
|
||||
static final MatrixStack ISOLATION_STACK = new MatrixStack();
|
||||
|
||||
public static MatrixStack pushIsolation(MatrixStack matrices) {
|
||||
ISOLATION_STACK.peek().getNormalMatrix().set(matrices.peek().getNormalMatrix());
|
||||
ISOLATION_STACK.peek().getPositionMatrix().set(matrices.peek().getPositionMatrix());
|
||||
return ISOLATION_STACK;
|
||||
}
|
||||
|
||||
public static void popIsolation() {
|
||||
while (!ISOLATION_STACK.isEmpty()) {
|
||||
ISOLATION_STACK.pop();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@
|
|||
"minelp.options.skins.hdskins.open": "Open HD Skins",
|
||||
"minelp.options.skins.hdskins.disabled": "HD Skins is not installed\n\nThe HD Skins mod is required to upload skins from in-game and to use custom skin servers.\n\nIf you cannot use that you will have to go to www.minecraft.net to upload your skin there.",
|
||||
"minelp.options.snuzzles": "Show Snuzzles",
|
||||
"minelp.options.enablefabricmodelsapisupport": "(Experimental) Show Modded Armor",
|
||||
"minelp.options.fillycam": "Filly Cam",
|
||||
"minelp.options.showscale": "Show-accurate scaling",
|
||||
"minelp.options.fpsmagic": "Magic in first-person",
|
||||
|
|
Loading…
Reference in a new issue