1.21.3 -> 1.21.4

This commit is contained in:
Sollace 2024-12-15 02:05:41 +01:00
parent 884fb62ff5
commit 787b166936
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
53 changed files with 432 additions and 333 deletions

View file

@ -3,10 +3,10 @@ org.gradle.daemon=false
# Fabric Properties
# check these on https://fabricmc.net/develop
minecraft_version=1.21.3
yarn_mappings=1.21.3+build.2
loader_version=0.16.7
fabric_version=0.106.1+1.21.3
minecraft_version=1.21.4
yarn_mappings=1.21.4+build.2
loader_version=0.16.9
fabric_version=0.111.0+1.21.4
# Mod Properties
group=com.minelittlepony
@ -19,7 +19,7 @@ org.gradle.daemon=false
modrinth_project_id=JBjInUXM
# Dependencies
modmenu_version=12.0.0-beta.1
kirin_version=1.20.3+1.21.3
hd_skins_version=6.14.1+1.21.3
mson_version=1.11.1+1.21.3
modmenu_version=13.0.0-beta.1
kirin_version=1.20.3+1.21.4
hd_skins_version=6.14.2+1.21.4
mson_version=1.11.1+1.21.4

View file

@ -130,6 +130,7 @@ public class ModelAttributes {
public Arm mainArm;
public Hand activeHand;
@Deprecated
public ItemStack heldStack = ItemStack.EMPTY;
public int itemUseTime;

View file

@ -1,7 +1,7 @@
package com.minelittlepony.api.model;
import net.minecraft.client.render.entity.equipment.EquipmentModel;
import net.minecraft.item.ItemStack;
import net.minecraft.item.equipment.EquipmentModel;
import net.minecraft.util.Util;
import org.jetbrains.annotations.Nullable;

View file

@ -6,6 +6,8 @@ import org.jetbrains.annotations.Nullable;
import com.google.common.collect.ComparisonChain;
import com.minelittlepony.api.pony.meta.*;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import java.util.*;
import java.util.function.Function;
@ -70,6 +72,20 @@ public record PonyData (
private static final Function<Race, PonyData> OF_RACE = Util.memoize(race -> new PonyData(race, TailLength.FULL, TailShape.STRAIGHT, Gender.MARE, SizePreset.NORMAL, DEFAULT_MAGIC_COLOR, true, 0, Wearable.EMPTY_FLAGS));
public static final PonyData NULL = OF_RACE.apply(Race.HUMAN);
public static final Codec<PonyData> CODEC = RecordCodecBuilder.create(i -> {
return i.group(
Race.CODEC.fieldOf("race").forGetter(PonyData::race),
TailLength.CODEC.fieldOf("tailLength").forGetter(PonyData::tailLength),
TailShape.CODEC.fieldOf("tailShape").forGetter(PonyData::tailShape),
Gender.CODEC.fieldOf("gender").forGetter(PonyData::gender),
SizePreset.CODEC.xmap(s -> (Size)s, s -> (SizePreset)s).fieldOf("size").forGetter(PonyData::size),
Codec.INT.fieldOf("glowColor").forGetter(PonyData::glowColor),
Codec.BOOL.optionalFieldOf("noSkin", false).forGetter(PonyData::noSkin),
Codec.INT.optionalFieldOf("priority", 0).forGetter(PonyData::priority),
Wearable.FLAGS_CODEC.fieldOf("gear").forGetter(PonyData::gear)
).apply(i, PonyData::new);
});
public static PonyData emptyOf(Race race) {
return OF_RACE.apply(race);
}

View file

@ -2,7 +2,12 @@ package com.minelittlepony.api.pony.meta;
import net.minecraft.network.PacketByteBuf;
import com.mojang.datafixers.util.Either;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import java.util.*;
import java.util.stream.Collectors;
public record Flags<T extends Enum<T> & TValue<T>> (
T def,
@ -10,6 +15,15 @@ public record Flags<T extends Enum<T> & TValue<T>> (
int colorCode
) implements Comparable<Flags<T>>, TValue<T> {
public static <T extends Enum<T> & TValue<T>> Codec<Flags<T>> codec(T def, Codec<T> elementCodec) {
Codec<Set<T>> setCodec = Codec.list(elementCodec).xmap(elements -> elements.stream().distinct().collect(Collectors.toUnmodifiableSet()), set -> List.copyOf(set));
return Codec.xor(setCodec.xmap(elements -> new Flags<>(def, elements, 0), flags -> flags.values()), RecordCodecBuilder.create(i -> i.group(
elementCodec.fieldOf("def").forGetter(Flags::def),
setCodec.fieldOf("values").forGetter(Flags::values),
Codec.INT.fieldOf("colorCode").forGetter(Flags::colorCode)
).apply(i, Flags::new))).xmap(Either::unwrap, Either::left);
}
public static <T extends Enum<T> & TValue<T>> Flags<T> of(T def) {
return new Flags<>(def, Set.<T>of(), 0);
}

View file

@ -1,10 +1,16 @@
package com.minelittlepony.api.pony.meta;
import net.minecraft.util.StringIdentifiable;
import com.mojang.serialization.Codec;
public enum Gender implements TValue<Gender> {
MARE(0),
STALLION(0xffffff),
ABOMONATION(0x888888);
public static final Codec<Gender> CODEC = StringIdentifiable.createCodec(Gender::values);
private int triggerValue;
Gender(int pixel) {

View file

@ -1,5 +1,9 @@
package com.minelittlepony.api.pony.meta;
import net.minecraft.util.StringIdentifiable;
import com.mojang.serialization.Codec;
public enum Race implements TValue<Race> {
HUMAN (0x000000, false, false),
EARTH (0xf9b131, false, false),
@ -15,6 +19,8 @@ public enum Race implements TValue<Race> {
BATPONY (0xeeeeee, true, false),
SEAPONY (0x3655dd, false, true);
public static final Codec<Race> CODEC = StringIdentifiable.createCodec(Race::values);
private final boolean wings;
private final boolean horn;

View file

@ -1,6 +1,9 @@
package com.minelittlepony.api.pony.meta;
import net.minecraft.util.StringIdentifiable;
import com.minelittlepony.api.config.PonyConfig;
import com.mojang.serialization.Codec;
/**
* Represents the different model sizes that are possible.
@ -20,6 +23,8 @@ public enum SizePreset implements Size {
FOAL (0xffbe53, 0.25f, 0.6F, 0.5F),
UNSET (0x000000, 1, 1, 1);
public static final Codec<SizePreset> CODEC = StringIdentifiable.createCodec(SizePreset::values);
private final int triggerValue;
private final float shadowSize;
private final float scale;

View file

@ -1,12 +1,14 @@
package com.minelittlepony.api.pony.meta;
import net.minecraft.util.StringIdentifiable;
import java.util.Arrays;
import java.util.List;
/**
* Interface for enums that can be parsed from an image trigger pixel value.
*/
public interface TValue<T> {
public interface TValue<T> extends StringIdentifiable {
/**
* Gets the pixel colour matching this enum value.
*/
@ -24,6 +26,11 @@ public interface TValue<T> {
*/
String name();
@Override
default String asString() {
return name();
}
default String getHexValue() {
return toHex(colorCode());
}

View file

@ -1,5 +1,9 @@
package com.minelittlepony.api.pony.meta;
import net.minecraft.util.StringIdentifiable;
import com.mojang.serialization.Codec;
public enum TailLength implements TValue<TailLength> {
STUB (0x425844),
QUARTER (0xd19fe4),
@ -7,6 +11,8 @@ public enum TailLength implements TValue<TailLength> {
THREE_QUARTERS (0x8a6b7f),
FULL (0x000000);
public static final Codec<TailLength> CODEC = StringIdentifiable.createCodec(TailLength::values);
private int triggerValue;
TailLength(int pixel) {

View file

@ -1,11 +1,17 @@
package com.minelittlepony.api.pony.meta;
import net.minecraft.util.StringIdentifiable;
import com.mojang.serialization.Codec;
public enum TailShape implements TValue<TailShape> {
STRAIGHT(0),
BUMPY (0xfc539f),
SWIRLY (0x3eff22),
SPIKY (0x3308c7);
public static final Codec<TailShape> CODEC = StringIdentifiable.createCodec(TailShape::values);
private int triggerValue;
TailShape(int pixel) {

View file

@ -1,9 +1,11 @@
package com.minelittlepony.api.pony.meta;
import net.minecraft.util.Identifier;
import net.minecraft.util.StringIdentifiable;
import net.minecraft.util.math.ColorHelper;
import com.minelittlepony.api.pony.Pony;
import com.mojang.serialization.Codec;
import java.util.*;
import java.util.function.Function;
@ -29,6 +31,9 @@ public enum Wearable implements TValue<Wearable> {
public static final Flags<Wearable> EMPTY_FLAGS = Flags.of(NONE);
public static final Codec<Wearable> CODEC = StringIdentifiable.createCodec(Wearable::values);
public static final Codec<Flags<Wearable>> FLAGS_CODEC = Flags.codec(NONE, CODEC);
Wearable(int pixel, Identifier texture) {
triggerValue = pixel;
id = Pony.id(name().toLowerCase(Locale.ROOT));

View file

@ -1,10 +1,9 @@
package com.minelittlepony.client;
import net.minecraft.client.MinecraftClient;
import net.minecraft.resource.metadata.ResourceMetadataReader;
import net.minecraft.resource.metadata.ResourceMetadataSerializer;
import net.minecraft.util.Identifier;
import com.google.gson.*;
import com.minelittlepony.api.pony.PonyData;
import com.minelittlepony.client.util.render.NativeUtil;
@ -17,21 +16,7 @@ import org.jetbrains.annotations.Nullable;
public class PonyDataLoader {
public static final Supplier<Optional<PonyData>> NULL = loaded(PonyData.NULL);
private static final ResourceMetadataReader<PonyData> SERIALIZER = new ResourceMetadataReader<PonyData>() {
private static final Gson GSON = new GsonBuilder()
.excludeFieldsWithoutExposeAnnotation()
.create();
@Override
public String getKey() {
return "pony";
}
@Override
public PonyData fromJson(JsonObject json) {
return GSON.fromJson(json, PonyData.class);
}
};
private static final ResourceMetadataSerializer<PonyData> SERIALIZER = new ResourceMetadataSerializer<PonyData>("pony", PonyData.CODEC);
/**
* Parses the given resource into a new IPonyData.

View file

@ -116,12 +116,9 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
rotateLegs(entity);
ArmPose left = getArmPose(entity, Arm.LEFT);
ArmPose right = getArmPose(entity, Arm.RIGHT);
if (!entity.attributes.isSwimming && !entity.attributes.isGoingFast) {
alignArmForAction(entity, getArm(Arm.LEFT), left, right, 1);
alignArmForAction(entity, getArm(Arm.RIGHT), right, left, -1);
alignArmForAction(entity, getArm(Arm.LEFT), entity.leftArmPose, entity.rightArmPose, 1);
alignArmForAction(entity, getArm(Arm.RIGHT), entity.rightArmPose, entity.leftArmPose, -1);
}
swingItem(entity);
@ -133,7 +130,7 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
adjustBody(entity, 0, ORIGIN);
if (!entity.attributes.isLyingDown) {
animateBreathing(entity, left, right);
animateBreathing(entity);
}
if (entity.attributes.isSwimmingRotated) {
@ -454,17 +451,17 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
* @param animationProgress Total whole and partial ticks since the entity's existence.
* Used in animations together with {@code swing} and {@code move}.
*/
protected void animateBreathing(T state, ArmPose left, ArmPose right) {
protected void animateBreathing(T state) {
float cos = MathHelper.cos(state.age * 0.09F) * 0.05F + 0.05F;
float sin = MathHelper.sin(state.age * 0.067F) * 0.05F;
if (state.attributes.shouldLiftArm(right, left, -1)) {
if (state.attributes.shouldLiftArm(state.rightArmPose, state.leftArmPose, -1)) {
ModelPart arm = getArm(Arm.RIGHT);
arm.roll += cos;
arm.pitch += sin;
}
if (state.attributes.shouldLiftArm(left, right, 1)) {
if (state.attributes.shouldLiftArm(state.leftArmPose, state.rightArmPose, 1)) {
ModelPart arm = getArm(Arm.LEFT);
arm.roll += cos;
arm.pitch += sin;
@ -499,7 +496,7 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
public void positionheldItem(T state, Arm arm, MatrixStack matrices) {
float left = arm == Arm.LEFT ? -1 : 1;
UseAction action = state.attributes.heldStack.getUseAction();
UseAction action = state.getHeldItem(arm).action;
if (action == UseAction.SPYGLASS && state.attributes.itemUseTime > 0) {
return;
@ -507,7 +504,7 @@ public abstract class AbstractPonyModel<T extends PonyRenderState> extends Clien
matrices.translate(-left * 0.1F, 0.45F, 0);
if (state.attributes.heldStack.getUseAction() == UseAction.BLOCK && state.attributes.itemUseTime == 0) {
if (action == UseAction.BLOCK && state.attributes.itemUseTime == 0) {
matrices.translate(left * 0.02F, -0.25F, 0);
}
}

View file

@ -65,11 +65,6 @@ public abstract class ClientPonyModel<T extends PonyRenderState> extends PlayerE
return side == Arm.LEFT ? leftLeg : rightLeg;
}
@Override
public ArmPose getArmPose(PlayerEntityRenderState state, Arm side) {
return super.getArmPose(state, side);
}
static void resetPivot(ModelPart part) {
part.setPivot(part.getDefaultTransform().pivotX(), part.getDefaultTransform().pivotY(), part.getDefaultTransform().pivotZ());
}

View file

@ -36,10 +36,10 @@ public final class ModelType {
public static final ModelKey<WitchPonyModel> WITCH = register("witch", WitchPonyModel::new);
public static final ModelKey<ZomponyModel<?>> ZOMBIE = register("zombie", ZomponyModel::new);
public static final ModelKey<PiglinPonyModel> PIGLIN = register("piglin", PiglinPonyModel::new);
public static final ModelKey<SkeleponyModel<?>> SKELETON = register("skeleton", SkeleponyModel::new);
public static final ModelKey<AlicornModel<?>> SKELETON = register("skeleton", tree -> new AlicornModel<>(tree, false));
public static final ModelKey<SinglePartModel> BOGGED_MUSHROOMS = register("bogged_mushrooms", tree -> new SinglePartModel(tree, RenderLayer::getEntityTranslucent));
public static final ModelKey<SkeleponyModel<?>> SKELETON_CLOTHES = register("skeleton_clothes", SkeleponyModel::new);
public static final ModelKey<PillagerPonyModel> PILLAGER = register("pillager", PillagerPonyModel::new);
public static final ModelKey<AlicornModel<?>> SKELETON_CLOTHES = register("skeleton_clothes", tree -> new AlicornModel<>(tree, false));
public static final ModelKey<ChangelingModel<?>> PILLAGER = register("pillager", tree -> new ChangelingModel<>(tree, false));
public static final ModelKey<IllagerPonyModel<?>> ILLAGER = register("illager", IllagerPonyModel::new);
public static final ModelKey<SeaponyModel<?>> GUARDIAN = register("guardian", SeaponyModel::new);
public static final ModelKey<EnderStallionModel> ENDERMAN = register("enderman", EnderStallionModel::new);

View file

@ -1,7 +1,7 @@
package com.minelittlepony.client.model.armour;
import net.minecraft.item.Item;
import net.minecraft.item.equipment.EquipmentModel;
import net.minecraft.client.render.entity.equipment.EquipmentModel;
import net.minecraft.registry.Registries;
import net.minecraft.util.Identifier;

View file

@ -3,6 +3,7 @@ package com.minelittlepony.client.model.armour;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.model.Model;
import net.minecraft.client.render.*;
import net.minecraft.client.render.entity.equipment.EquipmentModel;
import net.minecraft.client.render.entity.state.BipedEntityRenderState;
import net.minecraft.client.render.entity.state.LivingEntityRenderState;
import net.minecraft.client.render.item.ItemRenderer;
@ -12,9 +13,11 @@ import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.component.type.DyedColorComponent;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.item.*;
import net.minecraft.item.equipment.EquipmentModel;
import net.minecraft.item.equipment.EquipmentModel.LayerType;
import net.minecraft.item.equipment.EquipmentAsset;
import net.minecraft.item.equipment.trim.ArmorTrim;
import net.minecraft.item.equipment.trim.ArmorTrimMaterial;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.entry.RegistryEntry;
import net.minecraft.registry.tag.ItemTags;
import net.minecraft.util.*;
@ -22,6 +25,7 @@ import org.jetbrains.annotations.Nullable;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.function.UnaryOperator;
public interface ArmourRendererPlugin {
AtomicReference<ArmourRendererPlugin> INSTANCE = new AtomicReference<>(new ArmourRendererPlugin() {});
@ -45,8 +49,10 @@ public interface ArmourRendererPlugin {
case LEGS -> state.equippedLegsStack;
case FEET -> state.equippedFeetStack;
case BODY -> state.equippedChestStack;
case MAINHAND -> state.getMainHandStack();
case OFFHAND -> state.mainArm == Arm.LEFT ? state.leftHandStack : state.rightHandStack;
default -> ItemStack.EMPTY;
// TODO: Mojaaaaaaang!!
//case MAINHAND -> state.getMainHandStack();
//case OFFHAND -> state.mainArm == Arm.LEFT ? state.leftHandStack : state.rightHandStack;
}};
}
@ -58,11 +64,11 @@ public interface ArmourRendererPlugin {
return stack.isIn(ItemTags.DYEABLE) ? DyedColorComponent.getColor(stack, -6265536) : Colors.WHITE;
}
default float getArmourAlpha(EquipmentSlot slot, LayerType layer) {
default float getArmourAlpha(EquipmentSlot slot, EquipmentModel.LayerType layer) {
return 1F;
}
default float getTrimAlpha(EquipmentSlot slot, ArmorTrim trim, LayerType layer) {
default float getTrimAlpha(EquipmentSlot slot, ArmorTrim trim, EquipmentModel.LayerType layer) {
return 1F;
}
@ -71,18 +77,29 @@ public interface ArmourRendererPlugin {
}
@Nullable
default VertexConsumer getTrimConsumer(EquipmentSlot slot, VertexConsumerProvider provider, ArmorTrim trim, LayerType layerType, Identifier modelId) {
@Nullable VertexConsumer buffer = getOptionalBuffer(provider, getTrimLayer(slot, trim, layerType, modelId));
default VertexConsumer getTrimConsumer(EquipmentSlot slot, VertexConsumerProvider provider, ArmorTrim trim, EquipmentModel.LayerType layerType, RegistryKey<EquipmentAsset> assetId) {
@Nullable VertexConsumer buffer = getOptionalBuffer(provider, getTrimLayer(slot, trim, layerType, assetId));
if (buffer == null) {
return null;
}
SpriteAtlasTexture armorTrimsAtlas = MinecraftClient.getInstance().getBakedModelManager().getAtlas(TexturedRenderLayers.ARMOR_TRIMS_ATLAS_TEXTURE);
Sprite sprite = armorTrimsAtlas.getSprite(trim.getTexture(layerType, modelId));
Sprite sprite = armorTrimsAtlas.getSprite(getTexture(trim, layerType, assetId));
return sprite.getTextureSpecificVertexConsumer(buffer);
}
private static String getAssetName(RegistryEntry<ArmorTrimMaterial> material, RegistryKey<EquipmentAsset> assetKey) {
String string = (String)material.value().overrideArmorAssets().get(assetKey);
return string != null ? string : material.value().assetName();
}
private static Identifier getTexture(ArmorTrim trim, EquipmentModel.LayerType layerType, RegistryKey<EquipmentAsset> assetId) {
Identifier identifier = trim.pattern().value().assetId();
String string = getAssetName(trim.material(), assetId);
return identifier.withPath((UnaryOperator<String>)(path -> "trims/entity/" + layerType.asString() + "/" + path + "_" + string));
}
@Nullable
default RenderLayer getTrimLayer(EquipmentSlot slot, ArmorTrim trim, LayerType layerType, Identifier modelId) {
default RenderLayer getTrimLayer(EquipmentSlot slot, ArmorTrim trim, EquipmentModel.LayerType layerType, RegistryKey<EquipmentAsset> assetId) {
return TexturedRenderLayers.getArmorTrims(trim.pattern().value().decal());
}

View file

@ -1,7 +1,7 @@
package com.minelittlepony.client.model.armour;
import net.minecraft.client.render.entity.equipment.EquipmentModel;
import net.minecraft.item.ItemStack;
import net.minecraft.item.equipment.EquipmentModel;
public interface ArmourTextureLookup {
ArmourTexture getTexture(ItemStack stack, EquipmentModel.LayerType layerType, EquipmentModel.Layer layer);

View file

@ -1,10 +1,8 @@
package com.minelittlepony.client.model.armour;
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.CustomModelDataComponent;
import net.minecraft.client.render.entity.equipment.EquipmentModel;
import net.minecraft.item.*;
import net.minecraft.item.equipment.EquipmentModel;
import net.minecraft.resource.ResourceManager;
import net.minecraft.resource.ResourceReloader;
import net.minecraft.util.Identifier;
@ -38,14 +36,7 @@ public class ArmourTextureResolver implements ArmourTextureLookup, IdentifiableR
private final LoadingCache<ArmourParameters, ArmourTexture> layerCache = CacheBuilder.newBuilder()
.expireAfterAccess(30, TimeUnit.SECONDS)
.build(CacheLoader.from(parameters -> {
return Stream.of(ArmourTexture.legacy(parameters.textureId())).flatMap(i -> {
if (parameters.customModelId() != 0) {
return Stream.of(ArmourTexture.legacy(i.texture().withPath(p -> p.replace(".png", parameters.customModelId() + ".png"))), i);
}
return Stream.of(i);
}).flatMap(this::performLookup).findFirst().orElse(ArmourTexture.UNKNOWN);
}));
.build(CacheLoader.from(parameters -> Stream.of(ArmourTexture.legacy(parameters.textureId())).flatMap(this::performLookup).findFirst().orElse(ArmourTexture.UNKNOWN)));
private Stream<ArmourTexture> performLookup(ArmourTexture id) {
List<ArmourTexture> options = Stream.of(id).flatMap(ArmourTexture::ponify).toList();
@ -78,14 +69,10 @@ public class ArmourTextureResolver implements ArmourTextureLookup, IdentifiableR
@Override
public ArmourTexture getTexture(ItemStack stack, EquipmentModel.LayerType layerType, EquipmentModel.Layer layer) {
layerCache.invalidateAll();
return layerCache.getUnchecked(new ArmourParameters(layer, layerType, getCustom(stack)));
return layerCache.getUnchecked(new ArmourParameters(layer, layerType));
}
private int getCustom(ItemStack stack) {
return stack.getOrDefault(DataComponentTypes.CUSTOM_MODEL_DATA, CustomModelDataComponent.DEFAULT).value();
}
private record ArmourParameters(EquipmentModel.Layer layer, EquipmentModel.LayerType layerType, int customModelId) {
private record ArmourParameters(EquipmentModel.Layer layer, EquipmentModel.LayerType layerType) {
public Identifier textureId() {
return layer.getFullTextureId(layerType);
}

View file

@ -1,6 +1,6 @@
package com.minelittlepony.client.model.armour;
import net.minecraft.item.equipment.EquipmentModel;
import net.minecraft.client.render.entity.equipment.EquipmentModel;
import com.minelittlepony.client.model.AbstractPonyModel;
import com.minelittlepony.client.model.ModelType;

View file

@ -2,16 +2,16 @@ package com.minelittlepony.client.model.armour;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.*;
import net.minecraft.client.render.entity.equipment.EquipmentModelLoader;
import net.minecraft.client.render.entity.equipment.EquipmentRenderer;
import net.minecraft.client.render.entity.equipment.*;
import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.DyedColorComponent;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.item.ItemStack;
import net.minecraft.item.equipment.EquipmentModel;
import net.minecraft.item.equipment.EquipmentAsset;
import net.minecraft.item.equipment.trim.ArmorTrim;
import net.minecraft.registry.RegistryKey;
import net.minecraft.registry.tag.ItemTags;
import net.minecraft.util.Colors;
import net.minecraft.util.Identifier;
@ -41,7 +41,7 @@ public class PonifiedEquipmentRenderer extends EquipmentRenderer {
public <S extends PonyRenderState, V extends ClientPonyModel<S>> void render(
EquipmentSlot equipmentSlot,
EquipmentModel.LayerType layerType,
Identifier modelId,
RegistryKey<EquipmentAsset> assetId,
S entity,
Models<V> models,
ItemStack stack,
@ -49,13 +49,13 @@ public class PonifiedEquipmentRenderer extends EquipmentRenderer {
VertexConsumerProvider vertexConsumers,
int light
) {
render(equipmentSlot, layerType, modelId, entity, models, stack, matrices, vertexConsumers, light, null);
render(equipmentSlot, layerType, assetId, entity, models, stack, matrices, vertexConsumers, light, null);
}
public <S extends PonyRenderState, V extends ClientPonyModel<S>> void render(
EquipmentSlot equipmentSlot,
EquipmentModel.LayerType layerType,
Identifier modelId,
RegistryKey<EquipmentAsset> assetId,
S entity,
Models<V> models,
ItemStack stack,
@ -64,7 +64,7 @@ public class PonifiedEquipmentRenderer extends EquipmentRenderer {
int light,
@Nullable Identifier texture
) {
List<EquipmentModel.Layer> layers = modelLoader.get(modelId).getLayers(layerType);
List<EquipmentModel.Layer> layers = modelLoader.get(assetId).getLayers(layerType);
if (!layers.isEmpty()) {
ArmourRendererPlugin plugin = ArmourRendererPlugin.INSTANCE.get();
int defaultColor = stack.isIn(ItemTags.DYEABLE) ? DyedColorComponent.getColor(stack, 0) : 0;
@ -103,7 +103,7 @@ public class PonifiedEquipmentRenderer extends EquipmentRenderer {
@Nullable
ArmorTrim armorTrim = stack.get(DataComponentTypes.TRIM);
@Nullable
VertexConsumer trimConsumer = armorTrim != null && plugin.getTrimAlpha(equipmentSlot, armorTrim, layerType) > 0 ? plugin.getTrimConsumer(equipmentSlot, vertices, armorTrim, layerType, modelId) : null;
VertexConsumer trimConsumer = armorTrim != null && plugin.getTrimAlpha(equipmentSlot, armorTrim, layerType) > 0 ? plugin.getTrimConsumer(equipmentSlot, vertices, armorTrim, layerType, assetId) : null;
if (trimConsumer != null) {
for (EntityModel<?> model : drawnModels) {
model.render(matrices, trimConsumer, light, OverlayTexture.DEFAULT_UV);

View file

@ -51,11 +51,8 @@ public class BreezieModel extends BipedEntityModel<AllayRenderer.State> {
rotateLegRiding(rightLeg, 1);
}
ArmPose left = getArmPose(state, Arm.LEFT);
ArmPose right = getArmPose(state, Arm.RIGHT);
rotateArm(leftArm, left, 1);
rotateArm(rightArm, right, 1);
rotateArm(leftArm, state.leftArmPose, 1);
rotateArm(rightArm, state.rightArmPose, 1);
if (state.handSwingProgress > 0) {
swingArms(state, state.preferredArm);
@ -80,9 +77,9 @@ public class BreezieModel extends BipedEntityModel<AllayRenderer.State> {
rightWing.yaw = -rotX * 10;
rightWing.pitch = rotZ;
if (right == ArmPose.BOW_AND_ARROW) {
if (state.rightArmPose == ArmPose.BOW_AND_ARROW) {
raiseArm(rightArm, leftArm, -1);
} else if (left == ArmPose.BOW_AND_ARROW) {
} else if (state.leftArmPose == ArmPose.BOW_AND_ARROW) {
raiseArm(leftArm, rightArm, 1);
}
}

View file

@ -4,15 +4,15 @@ import net.minecraft.client.model.ModelPart;
import net.minecraft.client.util.math.MatrixStack;
import com.minelittlepony.api.model.BodyPart;
import com.minelittlepony.client.model.entity.race.AlicornModel;
import com.minelittlepony.client.render.entity.EnderStallionRenderer;
public class EnderStallionModel extends SkeleponyModel<EnderStallionRenderer.State> {
public class EnderStallionModel extends AlicornModel<EnderStallionRenderer.State> {
private final ModelPart leftHorn;
private final ModelPart rightHorn;
public EnderStallionModel(ModelPart tree) {
super(tree);
super(tree, false);
leftHorn = tree.getChild("left_horn");
rightHorn = tree.getChild("right_horn");
}

View file

@ -1,9 +1,7 @@
package com.minelittlepony.client.model.entity;
import net.minecraft.client.model.ModelPart;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.entity.mob.PiglinActivity;
import net.minecraft.util.Arm;
import net.minecraft.util.math.MathHelper;
import com.minelittlepony.client.render.entity.PonyPiglinRenderer;
@ -19,25 +17,6 @@ public class PiglinPonyModel extends ZomponyModel<PonyPiglinRenderer.State> {
rightFlap = tree.getChild("right_flap");
}
@Override
public ArmPose getArmPose(PlayerEntityRenderState p, Arm arm) {
if (p instanceof PonyPiglinRenderer.State state) {
return switch (arm) {
case LEFT -> switch (state.activity) {
case CROSSBOW_HOLD -> ArmPose.CROSSBOW_HOLD;
case CROSSBOW_CHARGE -> ArmPose.CROSSBOW_CHARGE;
default -> ArmPose.EMPTY;
};
case RIGHT -> switch (state.activity) {
case ADMIRING_ITEM -> ArmPose.ITEM;
default -> ArmPose.EMPTY;
};
};
}
return super.getArmPose(p, arm);
}
@Override
public void setModelAngles(PonyPiglinRenderer.State state) {
super.setModelAngles(state);

View file

@ -1,38 +0,0 @@
package com.minelittlepony.client.model.entity;
import net.minecraft.client.model.ModelPart;
import net.minecraft.client.render.entity.model.BipedEntityModel;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.entity.mob.IllagerEntity;
import net.minecraft.util.Arm;
import com.minelittlepony.client.model.entity.race.ChangelingModel;
import com.minelittlepony.client.render.entity.npc.IllagerPonyRenderer;
public class PillagerPonyModel extends ChangelingModel<IllagerPonyRenderer.State> {
public PillagerPonyModel(ModelPart tree) {
super(tree, false);
}
@Override
public BipedEntityModel.ArmPose getArmPose(PlayerEntityRenderState state, Arm arm) {
ArmPose holdingPose = getHoldingPose(((IllagerPonyRenderer.State)state).state);
if (holdingPose != ArmPose.EMPTY) {
boolean isMain = state.mainArm == Arm.RIGHT;
return isMain ? holdingPose : ArmPose.EMPTY;
}
return super.getArmPose(state, arm);
}
static ArmPose getHoldingPose(IllagerEntity.State state) {
switch (state) {
case BOW_AND_ARROW: return ArmPose.BOW_AND_ARROW;
case CROSSBOW_CHARGE: return ArmPose.CROSSBOW_CHARGE;
case CROSSBOW_HOLD: return ArmPose.CROSSBOW_HOLD;
default: return ArmPose.EMPTY;
}
}
}

View file

@ -1,30 +0,0 @@
package com.minelittlepony.client.model.entity;
import net.minecraft.client.model.ModelPart;
import net.minecraft.client.render.entity.model.BipedEntityModel;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.item.Items;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Arm;
import com.minelittlepony.client.model.entity.race.AlicornModel;
import com.minelittlepony.client.render.entity.SkeleponyRenderer;
public class SkeleponyModel<T extends SkeleponyRenderer.State> extends AlicornModel<T> {
public SkeleponyModel(ModelPart tree) {
super(tree, false);
}
@SuppressWarnings("unchecked")
@Override
public BipedEntityModel.ArmPose getArmPose(PlayerEntityRenderState state, Arm arm) {
if (arm == state.mainArm) {
ItemStack mainHand = state.getMainHandStack();
if (!mainHand.isEmpty()) {
return mainHand.getItem() == Items.BOW && ((T)state).isAttacking ? ArmPose.BOW_AND_ARROW : ArmPose.ITEM;
}
}
return super.getArmPose(state, arm);
}
}

View file

@ -26,7 +26,7 @@ public class WitchPonyModel extends EarthPonyModel<WitchRenderer.State> {
snout.rotate(0, 0, 0);
}
if (!entity.getMainHandStack().isEmpty()) {
if (!entity.getMainHandItemState().isEmpty()) {
float rot = (float)(Math.tan(entity.age / 7) + Math.sin(entity.age / 3));
if (rot > 1) rot = 1;
if (rot < -1) rot = -1;

View file

@ -5,6 +5,7 @@ import com.minelittlepony.client.model.entity.race.AlicornModel;
import com.minelittlepony.client.render.entity.state.PonyRenderState;
import net.minecraft.client.model.ModelPart;
import net.minecraft.util.Arm;
public class ZomponyModel<T extends PonyRenderState> extends AlicornModel<T> {
public ZomponyModel(ModelPart tree) {
@ -20,6 +21,6 @@ public class ZomponyModel<T extends PonyRenderState> extends AlicornModel<T> {
}
protected boolean shouldLiftBothArms(T state) {
return getArmPose(state, state.mainArm) == ArmPose.EMPTY;
return (state.mainArm == Arm.LEFT ? state.leftArmPose : state.rightArmPose) == ArmPose.EMPTY;
}
}

View file

@ -12,7 +12,6 @@ import net.minecraft.client.model.ModelPart;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.item.consume.UseAction;
import net.minecraft.registry.Registries;
import net.minecraft.util.*;
/**
@ -45,8 +44,7 @@ public class UnicornModel<T extends PonyRenderState> extends EarthPonyModel<T> {
}
public boolean isCasting(T state) {
return state instanceof PlayerEntityRenderState s
&& (getArmPose(s, Arm.LEFT) != ArmPose.EMPTY || getArmPose(s, Arm.RIGHT) != ArmPose.EMPTY);
return state instanceof PlayerEntityRenderState && (state.leftArmPose != ArmPose.EMPTY || state.rightArmPose != ArmPose.EMPTY);
}
@Override
@ -75,7 +73,7 @@ public class UnicornModel<T extends PonyRenderState> extends EarthPonyModel<T> {
@SuppressWarnings("deprecation")
@Override
public ModelPart getArm(Arm side) {
if (currentState != null && currentState.hasMagicGlow() && getArmPose(currentState, side) != ArmPose.EMPTY && PonyConfig.getInstance().tpsmagic.get()) {
if (currentState != null && currentState.hasMagicGlow() && (side == Arm.LEFT ? currentState.leftArmPose : currentState.rightArmPose) != ArmPose.EMPTY && PonyConfig.getInstance().tpsmagic.get()) {
return side == Arm.LEFT ? unicornArmLeft : unicornArmRight;
}
return super.getArm(side);
@ -91,7 +89,7 @@ public class UnicornModel<T extends PonyRenderState> extends EarthPonyModel<T> {
float left = arm == Arm.LEFT ? -1 : 1;
UseAction action = state.attributes.heldStack.getUseAction();
UseAction action = state.getHeldItem(arm).action;
if (action == UseAction.SPYGLASS && state.attributes.itemUseTime > 0) {
return;
}
@ -100,7 +98,7 @@ public class UnicornModel<T extends PonyRenderState> extends EarthPonyModel<T> {
boolean shouldAimItem =
(action == UseAction.BOW) && state.attributes.itemUseTime > 0
|| PonyConfig.getInstance().forwardHoldingItems.get().contains(Registries.ITEM.getId(state.attributes.heldStack.getItem()));
|| state.getHeldItem(arm).forwardFacing;
if (shouldAimItem) {
Arm main = state.attributes.mainArm;

View file

@ -21,11 +21,16 @@ import java.util.function.Supplier;
import net.fabricmc.api.EnvType;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.item.ItemModelManager;
import net.minecraft.client.render.entity.model.EntityModel;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.entity.*;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ModelTransformationMode;
import net.minecraft.util.Arm;
import net.minecraft.util.Util;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;
@ -87,11 +92,30 @@ public class EquineRenderManager<
return DebugBoundingBoxRenderer.applyScale(scale, box);
}
public void updateState(T entity, S state, ModelAttributes.Mode mode) {
public void updateState(T entity, S state, ModelAttributes.Mode mode, ItemModelManager modelManager) {
Pony pony = context.getEntityPony(entity);
models = modelsLookup.apply(pony.race());
context.setModel(models.body());
state.updateState(entity, models.body(), pony, mode);
if (PonyConfig.getInstance().tpsmagic.get() && state.hasMagicGlow()) {
modelManager.updateForLivingEntity(
state.glintlessRightHandItemState, getWithoutGlint(entity.getStackInArm(Arm.RIGHT)), ModelTransformationMode.THIRD_PERSON_RIGHT_HAND, false, entity
);
modelManager.updateForLivingEntity(
state.glintlessLeftHandItemState, getWithoutGlint(entity.getStackInArm(Arm.LEFT)), ModelTransformationMode.THIRD_PERSON_LEFT_HAND, true, entity
);
} else {
state.glintlessRightHandItemState.clear();
state.glintlessLeftHandItemState.clear();
}
}
private static ItemStack getWithoutGlint(ItemStack stack) {
if (!stack.isEmpty()) {
stack = stack.copy();
stack.set(DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE, false);
}
return stack;
}
public void setupTransforms(S state, MatrixStack stack, float animationProgress, float bodyYaw) {

View file

@ -12,25 +12,26 @@ import org.jetbrains.annotations.Nullable;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.*;
import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.texture.SpriteAtlasTexture;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.*;
import net.minecraft.item.consume.UseAction;
import net.minecraft.registry.Registries;
import net.minecraft.screen.PlayerScreenHandler;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.RotationAxis;
import net.minecraft.world.World;
public class LevitatingItemRenderer {
@SuppressWarnings("deprecation")
public static VertexConsumerProvider getProvider(Pony pony, VertexConsumerProvider provider) {
final int color = pony.metadata().glowColor();
return layer -> {
if (layer.getVertexFormat() != VertexFormats.POSITION_COLOR_TEXTURE_OVERLAY_LIGHT_NORMAL) {
return provider.getBuffer(layer);
}
return provider.getBuffer(MagicGlow.getColoured(RenderLayerUtil.getTexture(layer).orElse(PlayerScreenHandler.BLOCK_ATLAS_TEXTURE), color));
return provider.getBuffer(MagicGlow.getColoured(RenderLayerUtil.getTexture(layer).orElse(SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE), color));
};
}

View file

@ -6,10 +6,10 @@ import net.minecraft.client.render.RenderPhase;
import net.minecraft.client.render.VertexFormat;
import net.minecraft.client.render.VertexFormats;
import net.minecraft.util.*;
import net.minecraft.util.math.ColorHelper;
import com.mojang.blaze3d.systems.RenderSystem;
import com.google.common.base.Suppliers;
import com.minelittlepony.common.util.Color;
import java.util.function.BiFunction;
import java.util.function.Supplier;
@ -62,9 +62,9 @@ public abstract class MagicGlow extends RenderPhase {
public Colored(Identifier texture, int color) {
super(texture, TriState.FALSE, false);
this.red = Color.r(color);
this.green = Color.g(color);
this.blue = Color.b(color);
this.red = ColorHelper.getRedFloat(color);
this.green = ColorHelper.getGreenFloat(color);
this.blue = ColorHelper.getBlueFloat(color);
this.alpha = 0.8F;
}

View file

@ -18,6 +18,7 @@ import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.block.entity.SkullBlockEntityModel;
import net.minecraft.client.render.block.entity.SkullBlockEntityRenderer;
import net.minecraft.client.render.entity.equipment.EquipmentModel;
import net.minecraft.client.render.entity.state.LivingEntityRenderState;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.component.DataComponentTypes;
@ -25,14 +26,14 @@ import net.minecraft.component.type.ProfileComponent;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.item.BlockItem;
import net.minecraft.item.ItemStack;
import net.minecraft.item.equipment.EquipmentModel.LayerType;
import net.minecraft.util.Identifier;
import net.minecraft.util.Util;
import net.minecraft.util.math.ColorHelper;
import net.minecraft.util.math.Direction;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import org.jetbrains.annotations.Nullable;
/**
@ -41,8 +42,7 @@ import org.jetbrains.annotations.Nullable;
public class PonySkullRenderer {
public static final PonySkullRenderer INSTANCE = new PonySkullRenderer();
private Map<SkullBlock.SkullType, ISkull> skulls = Map.of();
private Map<SkullBlock.SkullType, SkullBlockEntityModel> headModels = Map.of();
private Cache cache = new Cache();
private ISkull selectedSkull;
private Identifier selectedSkin;
@ -51,21 +51,30 @@ public class PonySkullRenderer {
boolean isPony;
public void reload() {
skulls = Util.make(new HashMap<>(), skullMap -> {
skullMap.put(SkullBlock.Type.SKELETON, new MobSkull<>(SkeleponyRenderer.SKELETON, MobRenderers.SKELETON, ModelType.SKELETON, SkeleponyRenderer.State::new));
skullMap.put(SkullBlock.Type.WITHER_SKELETON, new MobSkull<>(SkeleponyRenderer.WITHER, MobRenderers.SKELETON, ModelType.SKELETON, SkeleponyRenderer.State::new));
skullMap.put(SkullBlock.Type.ZOMBIE, new MobSkull<>(ZomponyRenderer.ZOMBIE, MobRenderers.ZOMBIE, ModelType.ZOMBIE, PonyRenderState::new));
skullMap.put(SkullBlock.Type.PIGLIN, new MobSkull<>(PonyPiglinRenderer.PIGLIN, MobRenderers.PIGLIN, ModelType.PIGLIN, PonyPiglinRenderer.State::new));
skullMap.put(SkullBlock.Type.PLAYER, new PlayerPonySkull());
});
headModels = SkullBlockEntityRenderer.getModels(MinecraftClient.getInstance().getEntityModelLoader());
cache = new Cache();
}
record Cache(Function<SkullBlock.SkullType, ISkull> skulls, Function<SkullBlock.SkullType, SkullBlockEntityModel> headModels) {
public Cache() {
this(
Util.memoize(type -> type instanceof SkullBlock.Type t ? switch (t) {
case SKELETON -> new MobSkull<>(SkeleponyRenderer.SKELETON, MobRenderers.SKELETON, ModelType.SKELETON, SkeleponyRenderer.State::new);
case WITHER_SKELETON -> new MobSkull<>(SkeleponyRenderer.WITHER, MobRenderers.SKELETON, ModelType.SKELETON, SkeleponyRenderer.State::new);
case ZOMBIE -> new MobSkull<>(ZomponyRenderer.ZOMBIE, MobRenderers.ZOMBIE, ModelType.ZOMBIE, PonyRenderState::new);
case PIGLIN -> new MobSkull<>(PonyPiglinRenderer.PIGLIN, MobRenderers.PIGLIN, ModelType.PIGLIN, PonyPiglinRenderer.State::new);
case PLAYER -> new PlayerPonySkull();
default -> null;
} : null),
Util.memoize(type -> SkullBlockEntityRenderer.getModels(MinecraftClient.getInstance().getLoadedEntityModels(), type))
);
}
}
public void renderSkull(MatrixStack matrices, VertexConsumerProvider provider, ItemStack stack, LivingEntityRenderState entity, float tickDelta, int light, boolean isPony) {
isBeingWorn = true;
this.isPony = isPony;
SkullType type = ((AbstractSkullBlock) ((BlockItem) stack.getItem()).getBlock()).getSkullType();
SkullBlockEntityModel skullBlockEntityModel = headModels.get(type);
SkullBlockEntityModel skullBlockEntityModel = cache.headModels().apply(type);
RenderLayer renderLayer = SkullBlockEntityRenderer.getRenderLayer(type, stack.get(DataComponentTypes.PROFILE));
SkullBlockEntityRenderer.renderSkull(null, 180, entity.headItemAnimationProgress, matrices, provider, light, skullBlockEntityModel, renderLayer);
isBeingWorn = false;
@ -76,7 +85,7 @@ public class PonySkullRenderer {
selectedSkull = null;
selectedSkin = null;
ISkull skull = skulls.get(skullType);
ISkull skull = cache.skulls().apply(skullType);
if (skull == null || !skull.canRender(PonyConfig.getInstance())) {
return null;
@ -113,7 +122,7 @@ public class PonySkullRenderer {
VertexConsumer vertices = renderContext.getBuffer(layer);
selectedSkull.setAngles(yaw, animationProgress);
selectedSkull.render(stack, vertices, light, OverlayTexture.DEFAULT_UV, ColorHelper.fromFloats(ArmourRendererPlugin.INSTANCE.get().getArmourAlpha(EquipmentSlot.HEAD, LayerType.HUMANOID), 1, 1, 1));
selectedSkull.render(stack, vertices, light, OverlayTexture.DEFAULT_UV, ColorHelper.fromFloats(ArmourRendererPlugin.INSTANCE.get().getArmourAlpha(EquipmentSlot.HEAD, EquipmentModel.LayerType.HUMANOID), 1, 1, 1));
stack.pop();

View file

@ -15,6 +15,7 @@ import com.minelittlepony.mson.api.ModelKey;
import java.util.*;
import java.util.function.*;
import net.minecraft.client.item.ItemModelManager;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.EntityRendererFactory;
import net.minecraft.client.render.entity.MobEntityRenderer;
@ -44,6 +45,8 @@ public abstract class AbstractPonyRenderer<
private final ResourceManager resources;
protected final ItemModelManager itemModelManager;
private final float scale;
public AbstractPonyRenderer(EntityRendererFactory.Context context, ModelKey<? super M> key, TextureSupplier<T> texture, float scale) {
@ -52,13 +55,14 @@ public abstract class AbstractPonyRenderer<
this.texture = texture;
this.scale = scale;
resources = context.getResourceManager();
itemModelManager = context.getItemModelManager();
addFeatures(context);
}
@Override
public void updateRenderState(T entity, S state, float tickDelta) {
super.updateRenderState(entity, state, tickDelta);
manager.updateState(entity, state, ModelAttributes.Mode.THIRD_PERSON);
manager.updateState(entity, state, ModelAttributes.Mode.THIRD_PERSON, itemModelManager);
}
protected void addFeatures(EntityRendererFactory.Context context) {
@ -78,11 +82,11 @@ public abstract class AbstractPonyRenderer<
}
protected SkullFeature<S, M> createSkullFeature(EntityRendererFactory.Context context) {
return new SkullFeature<>(this, context.getModelLoader(), context.getItemRenderer(), HeadFeatureRenderer.HeadTransformation.DEFAULT, true);
return new SkullFeature<>(this, context.getItemModelManager(), HeadFeatureRenderer.HeadTransformation.DEFAULT, true);
}
protected HeldItemFeature<S, M> createHeldItemFeature(EntityRendererFactory.Context context) {
return new HeldItemFeature<>(this, context.getItemRenderer());
return new HeldItemFeature<>(this);
}
@Override

View file

@ -23,7 +23,7 @@ public class AllayRenderer extends MobEntityRenderer<AllayEntity, AllayRenderer.
public AllayRenderer(EntityRendererFactory.Context context) {
super(context, ModelType.ALLAY.createModel(), 0.4f);
addFeature(new HeldItemFeatureRenderer<State, BreezieModel>(this, context.getItemRenderer()));
addFeature(new HeldItemFeatureRenderer<State, BreezieModel>(this));
}
@Override

View file

@ -11,11 +11,13 @@ import com.minelittlepony.client.render.entity.npc.textures.TextureSupplier;
import com.minelittlepony.client.render.entity.feature.GlowingEyesFeature.IGlowingRenderer;
import net.minecraft.block.BlockState;
import net.minecraft.client.item.ItemModelManager;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.EntityRendererFactory;
import net.minecraft.client.render.entity.feature.StuckArrowsFeatureRenderer;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.mob.EndermanEntity;
import net.minecraft.item.ModelTransformationMode;
import net.minecraft.util.Arm;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.MathHelper;
@ -29,9 +31,11 @@ public class EnderStallionRenderer extends PonyRenderer<EndermanEntity, EnderSta
private static final Identifier EYES = MineLittlePony.id("textures/entity/enderman/enderman_pony_eyes.png");
private final Random rnd = new Random();
private final ItemModelManager itemModelManager;
public EnderStallionRenderer(EntityRendererFactory.Context context) {
super(context, ModelType.ENDERMAN, TextureSupplier.of(ENDERMAN));
itemModelManager = context.getItemModelManager();;
}
@SuppressWarnings({"rawtypes", "unchecked"})
@ -40,6 +44,7 @@ public class EnderStallionRenderer extends PonyRenderer<EndermanEntity, EnderSta
addPonyFeature(createHeldItemFeature(context));
addPonyFeature(new StuckArrowsFeatureRenderer<EnderStallionModel>((PonyRenderer)this, context));
addPonyFeature(new GlowingEyesFeature<EnderStallionRenderer.State, EnderStallionModel>(this));
}
@Override
@ -58,10 +63,13 @@ public class EnderStallionRenderer extends PonyRenderer<EndermanEntity, EnderSta
if (state.carriedBlock != null) {
if (state.mainArm == Arm.RIGHT) {
state.rightHandStack = state.carriedBlock.getBlock().asItem().getDefaultStack();
itemModelManager.updateForLivingEntity(state.rightHandItemState, state.carriedBlock.getBlock().asItem().getDefaultStack(), ModelTransformationMode.THIRD_PERSON_RIGHT_HAND, false, entity);
} else {
state.leftHandStack = state.carriedBlock.getBlock().asItem().getDefaultStack();
itemModelManager.updateForLivingEntity(state.leftHandItemState, state.carriedBlock.getBlock().asItem().getDefaultStack(), ModelTransformationMode.THIRD_PERSON_LEFT_HAND, true, entity);
}
} else {
state.rightHandItemState.clear();
state.leftHandItemState.clear();
}
state.attributes.wingsSpread = state.isAttacking;
state.attributes.wingAngle = MathHelper.sin(state.age) + WingedPonyModel.WINGS_HALF_SPREAD_ANGLE;
@ -69,7 +77,7 @@ public class EnderStallionRenderer extends PonyRenderer<EndermanEntity, EnderSta
@Override
protected HeldItemFeature<State, EnderStallionModel> createHeldItemFeature(EntityRendererFactory.Context context) {
return new HeldItemFeature<State, EnderStallionModel>(this, context.getItemRenderer());
return new HeldItemFeature<State, EnderStallionModel>(this);
}
@Override

View file

@ -15,6 +15,7 @@ import java.util.*;
import com.minelittlepony.client.render.EquineRenderManager;
import net.minecraft.client.item.ItemModelManager;
import net.minecraft.client.network.AbstractClientPlayerEntity;
import net.minecraft.client.render.*;
import net.minecraft.client.render.entity.EntityRendererFactory;
@ -37,10 +38,12 @@ public class PlayerPonyRenderer
protected final EquineRenderManager<AbstractClientPlayerEntity, PlayerPonyRenderState, ClientPonyModel<PlayerPonyRenderState>> manager;
private ModelAttributes.Mode mode = ModelAttributes.Mode.THIRD_PERSON;
protected final ItemModelManager itemModelManager;
@SuppressWarnings({"unchecked", "rawtypes"})
public PlayerPonyRenderer(EntityRendererFactory.Context context, boolean slim) {
super(context, slim);
itemModelManager = context.getItemModelManager();
manager = new EquineRenderManager<>(this, super::setupTransforms, race -> ModelType.getPlayerModel(race).create(slim));
// remove vanilla features (keep modded ones)
@ -54,10 +57,10 @@ public class PlayerPonyRenderer
|| feature instanceof ShoulderParrotFeatureRenderer;
});
addPonyFeature(new ArmourFeature<>(this, context.getEquipmentModelLoader()));
addPonyFeature(new HeldItemFeature<>(this, context.getItemRenderer()));
addPonyFeature(new HeldItemFeature<>(this));
addPonyFeature(new DJPon3Feature<>(this));
addFeature(new CapeFeature(this, context.getModelLoader(), context.getEquipmentModelLoader()));
addPonyFeature(new SkullFeature<>(this, context.getModelLoader(), context.getItemRenderer(), HeadFeatureRenderer.HeadTransformation.DEFAULT, true));
addFeature(new CapeFeature(this, context.getEntityModels(), context.getEquipmentModelLoader()));
addPonyFeature(new SkullFeature<>(this, context.getItemModelManager(), HeadFeatureRenderer.HeadTransformation.DEFAULT, true));
addPonyFeature(new ElytraFeature(this, context.getEquipmentRenderer()));
addPonyFeature(new PassengerFeature<>(this, context));
addPonyFeature(new GearFeature<>(this));
@ -86,7 +89,7 @@ public class PlayerPonyRenderer
@Override
public void updateRenderState(AbstractClientPlayerEntity entity, PlayerEntityRenderState state, float tickDelta) {
super.updateRenderState(entity, state, tickDelta);
manager.updateState(entity, (PlayerPonyRenderState)state, mode);
manager.updateState(entity, (PlayerPonyRenderState)state, mode, itemModelManager);
}
public final PlayerPonyRenderState getAndUpdateRenderState(AbstractClientPlayerEntity entity, float tickDelta, ModelAttributes.Mode mode) {
@ -120,7 +123,7 @@ public class PlayerPonyRenderer
matrices.push();
if (state.isInPose(EntityPose.SLEEPING)) {
if (state.sleepingDirection != null && ((PlayerPonyRenderState)state).sleepingInBed) {
double bedRad = Math.toRadians(state.sleepingDirection.asRotation());
double bedRad = Math.toRadians(state.sleepingDirection.getPositiveHorizontalDegrees());
matrices.translate(Math.cos(bedRad), 0, -Math.sin(bedRad));
}

View file

@ -1,7 +1,9 @@
package com.minelittlepony.client.render.entity;
import net.minecraft.client.render.entity.EntityRendererFactory;
import net.minecraft.client.render.entity.model.BipedEntityModel.ArmPose;
import net.minecraft.entity.mob.*;
import net.minecraft.util.Arm;
import net.minecraft.util.Identifier;
import com.minelittlepony.client.MineLittlePony;
@ -36,6 +38,25 @@ public class PonyPiglinRenderer extends PonyRenderer<HostileEntity, PonyPiglinRe
return new State();
}
@Override
public ArmPose getArmPose(ArmPose initial, HostileEntity entity, Arm arm) {
if (entity instanceof AbstractPiglinEntity piglin) {
return switch (arm) {
case LEFT -> switch (piglin.getActivity()) {
case CROSSBOW_HOLD -> ArmPose.CROSSBOW_HOLD;
case CROSSBOW_CHARGE -> ArmPose.CROSSBOW_CHARGE;
default -> ArmPose.EMPTY;
};
case RIGHT -> switch (piglin.getActivity()) {
case ADMIRING_ITEM -> ArmPose.ITEM;
default -> ArmPose.EMPTY;
};
};
}
return initial;
}
public void updateRenderState(HostileEntity entity, State state, float tickDelta) {
super.updateRenderState(entity, state, tickDelta);
state.zombified = entity instanceof ZombifiedPiglinEntity;

View file

@ -7,7 +7,9 @@ import com.minelittlepony.mson.api.ModelKey;
import net.minecraft.client.render.entity.EntityRendererFactory;
import net.minecraft.client.render.entity.feature.StuckArrowsFeatureRenderer;
import net.minecraft.client.render.entity.model.BipedEntityModel;
import net.minecraft.entity.mob.MobEntity;
import net.minecraft.util.Arm;
public abstract class PonyRenderer<
T extends MobEntity,
@ -30,4 +32,14 @@ public abstract class PonyRenderer<
super.addFeatures(context);
addFeature(new StuckArrowsFeatureRenderer(this, context));
}
public void updateRenderState(T entity, S state, float tickDelta) {
super.updateRenderState(entity, state, tickDelta);
state.leftArmPose = getArmPose(state.leftArmPose, entity, Arm.LEFT);
state.rightArmPose = getArmPose(state.rightArmPose, entity, Arm.RIGHT);
}
public BipedEntityModel.ArmPose getArmPose(BipedEntityModel.ArmPose initial, T entity, Arm arm) {
return initial;
}
}

View file

@ -1,5 +1,6 @@
package com.minelittlepony.client.render.entity;
import net.minecraft.client.item.ItemModelManager;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.*;
@ -32,6 +33,7 @@ public class PonyStandRenderer extends LivingEntityRenderer<ArmorStandEntity, Po
static final Pony PONY = new Pony(Identifier.ofVanilla("null"), () -> Optional.of(PonyData.NULL));
private final PonifiedContext context = new PonifiedContext();
private final ItemModelManager itemModelManager;
public static boolean isPonyStand(Entity entity) {
return entity.hasCustomName() && "Ponita".equals(entity.getCustomName().getString());
@ -39,10 +41,11 @@ public class PonyStandRenderer extends LivingEntityRenderer<ArmorStandEntity, Po
public PonyStandRenderer(EntityRendererFactory.Context context) {
super(context, ModelType.ARMOUR_STAND.createModel(), 0);
itemModelManager = context.getItemModelManager();
addFeature(new PonifiedFeature(this, new ArmourFeature<>(this.context, context.getEquipmentModelLoader())));
addFeature(new PonifiedFeature(this, new HeldItemFeature<>(this.context, context.getItemRenderer())));
addFeature(new PonifiedFeature(this, new HeldItemFeature<>(this.context)));
addFeature(new PonifiedFeature(this, new ElytraFeature<>(this.context, context.getEquipmentRenderer())));
addFeature(new PonifiedFeature(this, new SkullFeature<>(this.context, context.getModelLoader(), context.getItemRenderer(), HeadFeatureRenderer.HeadTransformation.DEFAULT, false)));
addFeature(new PonifiedFeature(this, new SkullFeature<>(this.context, context.getItemModelManager(), HeadFeatureRenderer.HeadTransformation.DEFAULT, false)));
}
@Override
@ -57,7 +60,7 @@ public class PonyStandRenderer extends LivingEntityRenderer<ArmorStandEntity, Po
public void updateRenderState(ArmorStandEntity entity, State state, float tickDelta) {
super.updateRenderState(entity, state, tickDelta);
BipedEntityRenderer.updateBipedRenderState(entity, state.ponyState, tickDelta);
BipedEntityRenderer.updateBipedRenderState(entity, state.ponyState, tickDelta, itemModelManager);
state.yaw = MathHelper.lerpAngleDegrees(tickDelta, entity.prevYaw, entity.getYaw());
state.marker = entity.isMarker();
state.small = entity.isSmall();
@ -79,10 +82,9 @@ public class PonyStandRenderer extends LivingEntityRenderer<ArmorStandEntity, Po
state.rightLegRotation = new EulerAngle(-state.rightArmRotation.getPitch(), state.rightArmRotation.getYaw(), state.rightArmRotation.getRoll());
}
context.manager.updateState(entity, state.ponyState, Mode.OTHER);
context.manager.updateState(entity, state.ponyState, Mode.OTHER, itemModelManager);
state.ponyState.baby = state.small;
state.ponyState.attributes.size = state.small ? SizePreset.FOAL : SizePreset.NORMAL;
state.ponyState.equippedHeadStack = state.equippedHeadStack;
state.pitch = MathHelper.RADIANS_PER_DEGREE * entity.getHeadRotation().getPitch();
state.yawDegrees = MathHelper.RADIANS_PER_DEGREE * entity.getHeadRotation().getYaw();
}

View file

@ -5,7 +5,7 @@ import com.minelittlepony.api.pony.Pony;
import com.minelittlepony.api.pony.meta.Race;
import com.minelittlepony.client.MineLittlePony;
import com.minelittlepony.client.model.ModelType;
import com.minelittlepony.client.model.entity.SkeleponyModel;
import com.minelittlepony.client.model.entity.race.AlicornModel;
import com.minelittlepony.client.render.entity.feature.ClothingFeature;
import com.minelittlepony.client.render.entity.npc.textures.TextureSupplier;
import com.minelittlepony.client.render.entity.state.PonyRenderState;
@ -15,13 +15,16 @@ import net.minecraft.client.render.*;
import net.minecraft.client.render.entity.EntityRendererFactory;
import net.minecraft.client.render.entity.LivingEntityRenderer;
import net.minecraft.client.render.entity.feature.FeatureRenderer;
import net.minecraft.client.render.entity.model.BipedEntityModel;
import net.minecraft.client.render.entity.model.BipedEntityModel.ArmPose;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.mob.*;
import net.minecraft.util.Colors;
import net.minecraft.util.Identifier;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.util.*;
public class SkeleponyRenderer<T extends AbstractSkeletonEntity, S extends SkeleponyRenderer.State> extends PonyRenderer<T, S, SkeleponyModel<S>> {
public class SkeleponyRenderer<T extends AbstractSkeletonEntity, S extends SkeleponyRenderer.State> extends PonyRenderer<T, S, AlicornModel<S>> {
public static final Identifier SKELETON = MineLittlePony.id("textures/entity/skeleton/skeleton_pony.png");
public static final Identifier WITHER = MineLittlePony.id("textures/entity/skeleton/skeleton_wither_pony.png");
public static final Identifier STRAY = MineLittlePony.id("textures/entity/skeleton/stray_pony.png");
@ -40,6 +43,18 @@ public class SkeleponyRenderer<T extends AbstractSkeletonEntity, S extends Skele
return (S)new State();
}
@Override
public BipedEntityModel.ArmPose getArmPose(BipedEntityModel.ArmPose initial, T entity, Arm arm) {
if (arm == entity.getMainArm()) {
ItemStack mainHand = entity.getMainHandStack();
if (!mainHand.isEmpty()) {
return mainHand.getItem() == Items.BOW && entity.isAttacking() ? ArmPose.BOW_AND_ARROW : ArmPose.ITEM;
}
}
return initial;
}
public static SkeleponyRenderer<SkeletonEntity, State> skeleton(EntityRendererFactory.Context context) {
return new SkeleponyRenderer<>(context, SKELETON, 1);
}
@ -68,12 +83,12 @@ public class SkeleponyRenderer<T extends AbstractSkeletonEntity, S extends Skele
public static class BoggedMushroomsFeature<
T extends AbstractSkeletonEntity,
S extends SkeleponyRenderer.State
> extends FeatureRenderer<BoggedState, SkeleponyModel<BoggedState>> {
> extends FeatureRenderer<BoggedState, AlicornModel<BoggedState>> {
public static final Identifier MUSHROOMS = MineLittlePony.id("textures/entity/skeleton/bogged_pony_mushrooms.png");
private final SinglePartModel model = ModelType.BOGGED_MUSHROOMS.createModel();
public BoggedMushroomsFeature(LivingEntityRenderer<BoggedEntity, BoggedState, SkeleponyModel<BoggedState>> renderer) {
public BoggedMushroomsFeature(LivingEntityRenderer<BoggedEntity, BoggedState, AlicornModel<BoggedState>> renderer) {
super(renderer);
}

View file

@ -7,6 +7,7 @@ import com.minelittlepony.client.render.PonyRenderContext;
import com.minelittlepony.client.render.entity.state.PonyRenderState;
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.util.math.MatrixStack;
import net.minecraft.component.DataComponentTypes;
@ -14,7 +15,6 @@ import net.minecraft.component.type.EquippableComponent;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.*;
import net.minecraft.item.equipment.EquipmentModel;
import org.jetbrains.annotations.Nullable;
@ -61,7 +61,7 @@ public class ArmourFeature<
EquippableComponent equippableComponent = stack.get(DataComponentTypes.EQUIPPABLE);
if (hasModel(equippableComponent, armorSlot)) {
equipmentRenderer.render(armorSlot, layerType, equippableComponent.model().orElseThrow(), entity, models, stack, matrices, vertices, light);
equipmentRenderer.render(armorSlot, layerType, equippableComponent.assetId().orElseThrow(), entity, models, stack, matrices, vertices, light);
}
}
@ -69,6 +69,6 @@ public class ArmourFeature<
}
private static boolean hasModel(@Nullable EquippableComponent component, EquipmentSlot slot) {
return component != null && component.model().isPresent() && component.slot() == slot;
return component != null && component.assetId().isPresent() && component.slot() == slot;
}
}

View file

@ -9,13 +9,13 @@ import com.minelittlepony.common.util.render.RenderLayerUtil;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.equipment.EquipmentModel;
import net.minecraft.client.render.entity.equipment.EquipmentModelLoader;
import net.minecraft.client.render.entity.feature.CapeFeatureRenderer;
import net.minecraft.client.render.entity.model.EntityModelLoader;
import net.minecraft.client.render.entity.model.LoadedEntityModels;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.item.equipment.EquipmentModel;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.RotationAxis;
@ -23,7 +23,7 @@ public class CapeFeature extends CapeFeatureRenderer {
private final PonyRenderContext<?, PlayerPonyRenderState, ClientPonyModel<PlayerPonyRenderState>> context;
public CapeFeature(PonyRenderContext<?, PlayerPonyRenderState, ClientPonyModel<PlayerPonyRenderState>> context, EntityModelLoader modelLoader, EquipmentModelLoader equipmentModelLoader) {
public CapeFeature(PonyRenderContext<?, PlayerPonyRenderState, ClientPonyModel<PlayerPonyRenderState>> context, LoadedEntityModels modelLoader, EquipmentModelLoader equipmentModelLoader) {
super(context.upcast(), modelLoader, equipmentModelLoader);
this.context = context;
}

View file

@ -7,6 +7,7 @@ import com.minelittlepony.client.render.PonyRenderContext;
import com.minelittlepony.client.render.entity.state.PonyRenderState;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.equipment.EquipmentModel;
import net.minecraft.client.render.entity.equipment.EquipmentRenderer;
import net.minecraft.client.render.entity.feature.FeatureRenderer;
import net.minecraft.client.render.entity.feature.FeatureRendererContext;
@ -17,7 +18,8 @@ import net.minecraft.component.DataComponentTypes;
import net.minecraft.component.type.EquippableComponent;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.item.ItemStack;
import net.minecraft.item.equipment.EquipmentModel;
import net.minecraft.item.equipment.EquipmentAsset;
import net.minecraft.registry.RegistryKey;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.RotationAxis;
@ -45,8 +47,8 @@ public class ElytraFeature<
for (ItemStack stack : plugin.getArmorStacks(state, EquipmentSlot.CHEST, EquipmentModel.LayerType.WINGS, ArmourRendererPlugin.ArmourType.ELYTRA)) {
EquippableComponent equippable = stack.get(DataComponentTypes.EQUIPPABLE);
if (equippable != null && !equippable.model().isEmpty()) {
Identifier equipmentModel = equippable.model().get();
if (equippable != null && !equippable.assetId().isEmpty()) {
RegistryKey<EquipmentAsset> equipmentModel = equippable.assetId().get();
float alpha = plugin.getElytraAlpha(stack, model, state);
if (alpha <= 0) {

View file

@ -4,11 +4,11 @@ import it.unimi.dsi.fastutil.objects.Object2FloatLinkedOpenHashMap;
import it.unimi.dsi.fastutil.objects.Object2FloatMap;
import net.minecraft.block.SkullBlock;
import net.minecraft.client.render.*;
import net.minecraft.client.render.entity.equipment.EquipmentModel;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.EquipmentSlot;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.*;
import net.minecraft.item.equipment.EquipmentModel;
import net.minecraft.util.Colors;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.random.Random;

View file

@ -1,6 +1,5 @@
package com.minelittlepony.client.render.entity.feature;
import com.minelittlepony.api.config.PonyConfig;
import com.minelittlepony.api.model.*;
import com.minelittlepony.client.model.AbstractPonyModel;
import com.minelittlepony.client.model.ClientPonyModel;
@ -11,18 +10,12 @@ import com.minelittlepony.client.render.entity.state.PonyRenderState;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.feature.PlayerHeldItemFeatureRenderer;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.item.ItemRenderState;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.component.DataComponentTypes;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ModelTransformationMode;
import net.minecraft.item.consume.UseAction;
import net.minecraft.util.Arm;
import net.minecraft.util.math.MathHelper;
import org.jetbrains.annotations.Nullable;
public class HeldItemFeature<
S extends PonyRenderState,
M extends ClientPonyModel<S>
@ -30,8 +23,8 @@ public class HeldItemFeature<
private final PonyRenderContext<?, S, M> context;
public HeldItemFeature(PonyRenderContext<?, S, M> context, ItemRenderer renderer) {
super(context.upcast(), renderer);
public HeldItemFeature(PonyRenderContext<?, S, M> context) {
super(context.upcast());
this.context = context;
}
@ -43,57 +36,48 @@ public class HeldItemFeature<
}
public void render(MatrixStack matrices, VertexConsumerProvider vertices, int light, S state, float limbAngle, float limbDistance) {
if (!state.leftHandStack.isEmpty() || !state.rightHandStack.isEmpty()) {
if (!state.leftHandItemState.isEmpty() || !state.rightHandItemState.isEmpty()) {
M model = context.getEquineManager().getModels().body();
matrices.push();
model.transform(state, BodyPart.LEGS, matrices);
ModelAttributes attributes = ((PonyModel.AttributedHolder)state).getAttributes();
attributes.heldStack = state.rightHandStack;
renderItem(state, state.rightHandItemModel, state.rightHandStack, ModelTransformationMode.THIRD_PERSON_RIGHT_HAND, Arm.RIGHT, matrices, vertices, light);
attributes.heldStack = state.leftHandStack;
renderItem(state, state.leftHandItemModel, state.leftHandStack, ModelTransformationMode.THIRD_PERSON_LEFT_HAND, Arm.LEFT, matrices, vertices, light);
attributes.heldStack = ItemStack.EMPTY;
renderItem(state, state.rightHandItemState, state.glintlessRightHandItemState, Arm.RIGHT, matrices, vertices, light);
renderItem(state, state.leftHandItemState, state.glintlessLeftHandItemState, Arm.LEFT, matrices, vertices, light);
matrices.pop();
}
}
@SuppressWarnings(value = {"unchecked"})
protected void renderItem(S state, @Nullable BakedModel model, ItemStack item, ModelTransformationMode mode, Arm arm, MatrixStack matrices, VertexConsumerProvider vertices, int light) {
if (context.getEquineManager().getModels().body() instanceof AbstractPonyModel m) {
m.positionheldItem(state, arm, matrices);
}
renderItem((PlayerEntityRenderState)state, model, item, mode, arm, matrices, vertices, light);
if (PonyConfig.getInstance().tpsmagic.get() && state.hasMagicGlow()) {
vertices = LevitatingItemRenderer.getProvider(state.pony, vertices);
if (item.hasGlint()) {
item = item.copy();
item.set(DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE, false);
protected void renderItem(S state, ItemRenderState item, ItemRenderState glintLessItem, Arm arm, MatrixStack matrices, VertexConsumerProvider vertices, int light) {
if (!item.isEmpty()) {
if (context.getEquineManager().getModels().body() instanceof AbstractPonyModel m) {
m.positionheldItem(state, arm, matrices);
}
renderItem((PlayerEntityRenderState)state, item, arm, matrices, vertices, light);
boolean noTransform = state.attributes.heldStack.getUseAction() == UseAction.SPYGLASS && state.attributes.itemUseTime > 0;
if (!glintLessItem.isEmpty()) {
vertices = LevitatingItemRenderer.getProvider(state.pony, vertices);
float driftStrength = 0.002F;
float xDrift = MathHelper.sin(state.age / 10F) * driftStrength;
float zDrift = MathHelper.cos((state.age + 20) / 10F) * driftStrength;
boolean noTransform = state.getHeldItem(arm).action == UseAction.SPYGLASS && state.attributes.itemUseTime > 0;
float scale = 1.1F + (MathHelper.sin(state.age / 20F) + 1) * driftStrength;
float driftStrength = 0.002F;
float xDrift = MathHelper.sin(state.age / 10F) * driftStrength;
float zDrift = MathHelper.cos((state.age + 20) / 10F) * driftStrength;
float scale = 1.1F + (MathHelper.sin(state.age / 20F) + 1) * driftStrength;
matrices.scale(scale, scale, scale);
if (!noTransform) {
matrices.translate(0.045F + xDrift, 0.01F - 0.12F, 0.03F + zDrift);
}
renderItem((PlayerEntityRenderState)state, model, item, mode, arm, matrices, vertices, light);
if (!noTransform) {
matrices.scale(scale, scale, scale);
matrices.translate(0.1F, -0.1F, 0.1F);
matrices.translate(-0.03F - xDrift, -0.02F, -0.02F - zDrift);
if (!noTransform) {
matrices.translate(0.045F + xDrift, 0.01F - 0.12F, 0.03F + zDrift);
}
renderItem((PlayerEntityRenderState)state, glintLessItem, arm, matrices, vertices, light);
if (!noTransform) {
matrices.scale(scale, scale, scale);
matrices.translate(0.1F, -0.1F, 0.1F);
matrices.translate(-0.03F - xDrift, -0.02F, -0.02F - zDrift);
}
renderItem((PlayerEntityRenderState)state, glintLessItem, arm, matrices, vertices, light);
}
renderItem((PlayerEntityRenderState)state, model, item, mode, arm, matrices, vertices, light);
}
}
}

View file

@ -8,32 +8,28 @@ import com.minelittlepony.client.render.blockentity.skull.PonySkullRenderer;
import com.minelittlepony.client.render.entity.state.PonyRenderState;
import net.minecraft.block.AbstractSkullBlock;
import net.minecraft.client.item.ItemModelManager;
import net.minecraft.client.render.*;
import net.minecraft.client.render.entity.equipment.EquipmentModel;
import net.minecraft.client.render.entity.feature.ArmorFeatureRenderer;
import net.minecraft.client.render.entity.feature.HeadFeatureRenderer;
import net.minecraft.client.render.entity.model.EntityModelLoader;
import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.render.model.BakedModel;
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.item.*;
import net.minecraft.item.equipment.EquipmentModel;
public class SkullFeature<
S extends PonyRenderState,
M extends ClientPonyModel<S>
> extends AbstractPonyFeature<S, M> {
private final ItemRenderer itemRenderer;
protected final ItemModelManager itemModelResolver;
private final HeadFeatureRenderer.HeadTransformation headTransformation;
private final boolean scaleForChild;
public SkullFeature(PonyRenderContext<?, S, M> context, EntityModelLoader entityModelLoader, ItemRenderer itemRenderer,
HeadFeatureRenderer.HeadTransformation headTransformation, boolean scaleForChild) {
public SkullFeature(PonyRenderContext<?, S, M> context, ItemModelManager itemModelResolver, HeadFeatureRenderer.HeadTransformation headTransformation, boolean scaleForChild) {
super(context);
this.itemRenderer = itemRenderer;
this.itemModelResolver = itemModelResolver;
this.headTransformation = headTransformation;
this.scaleForChild = scaleForChild;
}
@ -44,15 +40,23 @@ public class SkullFeature<
for (ItemStack stack : plugin.getArmorStacks(state, EquipmentSlot.HEAD, EquipmentModel.LayerType.HUMANOID, ArmourRendererPlugin.ArmourType.SKULL)) {
BakedModel headModel = state.equippedHeadItemModel;
if (stack.isEmpty() || headModel == null) {
if (stack.isEmpty()) {
continue;
}
M model = getModelWrapper().body();
Item item = stack.getItem();
EquippableComponent equipable = stack.get(DataComponentTypes.EQUIPPABLE);
boolean isSkull = stack.getItem() instanceof BlockItem b && b.getBlock() instanceof AbstractSkullBlock;
if (!isSkull) {
if (!ArmorFeatureRenderer.hasModel(stack, EquipmentSlot.HEAD)) {
itemModelResolver.update(state.headItemRenderState, stack, ModelTransformationMode.HEAD, false, null, null, 0);
} else {
state.headItemRenderState.clear();
}
if (state.headItemRenderState.isEmpty()) {
continue;
}
}
matrices.push();
@ -62,22 +66,23 @@ public class SkullFeature<
matrices.translate(0, 1, 0);
}
M model = getModelWrapper().body();
model.transform(state, BodyPart.HEAD, matrices);
model.getHead().rotate(matrices);
float f = 1.1F;
matrices.scale(f, f, f);
if (item instanceof BlockItem b && b.getBlock() instanceof AbstractSkullBlock) {
if (isSkull) {
float n = 1.1875F;
matrices.scale(n, -n, -n);
matrices.translate(0, -0.1F, 0.1F);
matrices.translate(-0.5, 0, -0.5);
PonySkullRenderer.INSTANCE.renderSkull(matrices, provider, stack, state, state.age, light, true);
} else if (equipable != null && equipable.slot() != EquipmentSlot.HEAD) {
} else if (!ArmorFeatureRenderer.hasModel(stack, EquipmentSlot.HEAD)) {
matrices.translate(0, 0.1F, -0.1F);
HeadFeatureRenderer.translate(matrices, headTransformation);
itemRenderer.renderItem(stack, ModelTransformationMode.HEAD, false, matrices, provider, light, OverlayTexture.DEFAULT_UV, headModel);
state.headItemRenderState.render(matrices, provider, light, OverlayTexture.DEFAULT_UV);
}
matrices.pop();

View file

@ -6,6 +6,7 @@ import com.minelittlepony.api.pony.Pony;
import com.minelittlepony.client.MineLittlePony;
import com.minelittlepony.client.model.ModelType;
import com.minelittlepony.client.model.entity.race.AlicornModel;
import com.minelittlepony.client.model.entity.race.ChangelingModel;
import com.minelittlepony.client.render.entity.npc.textures.TextureSupplier;
import com.minelittlepony.client.render.entity.state.PonyRenderState;
import com.minelittlepony.mson.api.ModelKey;
@ -15,10 +16,11 @@ import com.minelittlepony.client.render.entity.feature.HeldItemFeature;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.EntityRendererFactory;
import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.render.entity.model.BipedEntityModel.ArmPose;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.mob.*;
import net.minecraft.util.Arm;
import net.minecraft.util.Identifier;
public class IllagerPonyRenderer<
@ -41,13 +43,35 @@ public class IllagerPonyRenderer<
return (S)new State();
}
@Override
protected HeldItemFeature<S, M> createHeldItemFeature(EntityRendererFactory.Context context) {
return new IllagerHeldItemFeature<>(this, context.getItemRenderer());
static ArmPose getHoldingPose(IllagerEntity.State state) {
switch (state) {
case BOW_AND_ARROW: return ArmPose.BOW_AND_ARROW;
case CROSSBOW_CHARGE: return ArmPose.CROSSBOW_CHARGE;
case CROSSBOW_HOLD: return ArmPose.CROSSBOW_HOLD;
default: return ArmPose.EMPTY;
}
}
public static IllagerPonyRenderer<PillagerEntity, ?, ?> pillager(EntityRendererFactory.Context context) {
return new IllagerPonyRenderer<>(context, ModelType.PILLAGER, PILLAGER);
@Override
protected HeldItemFeature<S, M> createHeldItemFeature(EntityRendererFactory.Context context) {
return new IllagerHeldItemFeature<>(this);
}
public static IllagerPonyRenderer<PillagerEntity, State, ChangelingModel<State>> pillager(EntityRendererFactory.Context context) {
return new IllagerPonyRenderer<PillagerEntity, State, ChangelingModel<State>>(context, ModelType.PILLAGER, PILLAGER) {
@Override
public ArmPose getArmPose(ArmPose initial, PillagerEntity state, Arm arm) {
ArmPose holdingPose = getHoldingPose(state.getState());
if (holdingPose != ArmPose.EMPTY) {
boolean isMain = state.getMainArm() == Arm.RIGHT;
return isMain ? holdingPose : ArmPose.EMPTY;
}
return initial;
}
};
}
public static IllagerPonyRenderer<VindicatorEntity, ?, ?> vindicator(EntityRendererFactory.Context context) {
@ -73,8 +97,8 @@ public class IllagerPonyRenderer<
M extends AlicornModel<S>
> extends HeldItemFeature<S, M> {
public IllagerHeldItemFeature(PonyRenderContext<T, S, M> livingPony, ItemRenderer renderer) {
super(livingPony, renderer);
public IllagerHeldItemFeature(PonyRenderContext<T, S, M> livingPony) {
super(livingPony);
}
@Override

View file

@ -3,6 +3,7 @@ package com.minelittlepony.client.render.entity.npc;
import net.minecraft.client.render.entity.EntityRendererFactory;
import net.minecraft.client.render.entity.model.BipedEntityModel.ArmPose;
import net.minecraft.entity.mob.ZombieVillagerEntity;
import net.minecraft.util.Arm;
import com.minelittlepony.api.model.*;
import com.minelittlepony.client.VariatedTextureSupplier;
@ -39,7 +40,7 @@ public class ZomponyVillagerRenderer extends AbstractNpcRenderer<ZombieVillagerE
@Override
protected void initializeModel(ClientPonyModel<SillyPonyTextureSupplier.State> model) {
model.onSetModelAngles((m, state) -> {
if (m.getArmPose(state, state.mainArm) == ArmPose.EMPTY) {
if ((state.mainArm == Arm.LEFT ? state.leftArmPose : state.rightArmPose) == ArmPose.EMPTY) {
MobPosingHelper.rotateUndeadArms(state, m, state.limbFrequency, state.age);
}
});

View file

@ -1,14 +1,21 @@
package com.minelittlepony.client.render.entity.state;
import net.minecraft.block.BedBlock;
import net.minecraft.client.item.ItemModelManager;
import net.minecraft.client.render.entity.state.PlayerEntityRenderState;
import net.minecraft.client.render.item.ItemRenderState;
import net.minecraft.entity.EntityPose;
import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.mob.AbstractPiglinEntity;
import net.minecraft.entity.mob.ZombifiedPiglinEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.item.consume.UseAction;
import net.minecraft.registry.Registries;
import net.minecraft.util.Arm;
import net.minecraft.util.math.MathHelper;
import com.minelittlepony.api.config.PonyConfig;
import com.minelittlepony.api.events.PonyModelPrepareCallback;
import com.minelittlepony.api.model.ModelAttributes;
import com.minelittlepony.api.model.PonyModel;
@ -33,6 +40,12 @@ public class PonyRenderState extends PlayerEntityRenderState implements PonyMode
public Pony pony = Pony.getManager().getPony(DefaultPonySkinHelper.STEVE);
public Race race = Race.HUMAN;
public final HeldItemRenderState leftHeldItem = new HeldItemRenderState();
public final HeldItemRenderState rightHeldItem = new HeldItemRenderState();
public final ItemRenderState glintlessRightHandItemState = new ItemRenderState();
public final ItemRenderState glintlessLeftHandItemState = new ItemRenderState();
public void updateState(LivingEntity entity, PonyModel<?> model, Pony pony, ModelAttributes.Mode mode) {
this.pony = pony;
attributes.updateLivingState(entity, pony, mode);
@ -58,6 +71,9 @@ public class PonyRenderState extends PlayerEntityRenderState implements PonyMode
) && entity.hasCustomName() && entity.getCustomName().getString().equalsIgnoreCase("technoblade")
);
leftHeldItem.update(entity.getStackInArm(Arm.LEFT));
rightHeldItem.update(entity.getStackInArm(Arm.RIGHT));
// Adjust cape angles
// capePitch
field_53537 *= 0.3F;
@ -130,4 +146,18 @@ public class PonyRenderState extends PlayerEntityRenderState implements PonyMode
public ModelAttributes getAttributes() {
return attributes;
}
public HeldItemRenderState getHeldItem(Arm arm) {
return arm == Arm.LEFT ? leftHeldItem : rightHeldItem;
}
public static class HeldItemRenderState {
public UseAction action = UseAction.NONE;
public boolean forwardFacing;
private void update(ItemStack stack) {
action = stack.getUseAction();
forwardFacing = PonyConfig.getInstance().forwardHoldingItems.get().contains(Registries.ITEM.getId(stack.getItem()));
}
}
}

View file

@ -17,20 +17,16 @@ public class TextureFlattener {
Preconditions.checkArgument(textures.size() > 0, "Must have at least one image to flatten");
MinecraftClient.getInstance().getTextureManager().registerTexture(output, new ResourceTexture(output) {
@Override
protected TextureData loadTextureData(ResourceManager resourceManager) {
try {
NativeImage image = NativeImage.read(resourceManager.getResourceOrThrow(textures.get(0)).getInputStream());
public TextureContents loadContents(ResourceManager resourceManager) throws IOException {
NativeImage image = NativeImage.read(resourceManager.getResourceOrThrow(textures.get(0)).getInputStream());
for (int i = 1; i < textures.size(); i++) {
try (NativeImage data = NativeImage.read(resourceManager.getResourceOrThrow(textures.get(i)).getInputStream())) {
copyOver(data, image);
}
for (int i = 1; i < textures.size(); i++) {
try (NativeImage data = NativeImage.read(resourceManager.getResourceOrThrow(textures.get(i)).getInputStream())) {
copyOver(data, image);
}
return new TextureData(null, image);
} catch (IOException e) {
return new TextureData(e);
}
return new TextureContents(image, null);
}
});
}

View file

@ -20,9 +20,7 @@ public final class ResourceUtil {
}
public static boolean textureExists(Identifier texture) {
return
MinecraftClient.getInstance().getTextureManager().getOrDefault(texture, null) != null
|| MinecraftClient.getInstance().getResourceManager().getResource(texture).isPresent();
return MinecraftClient.getInstance().getResourceManager().getResource(texture).isPresent();
}
public static Optional<Identifier> verifyTexture(Identifier texture) {