Skip to content

Commit bc424c0

Browse files
committed
Tridents?
1 parent b8cb0d8 commit bc424c0

File tree

8 files changed

+309
-9
lines changed

8 files changed

+309
-9
lines changed

build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ fletchingTable {
7272
"survivalblock.atmosphere.atmospheric_api.mixin.item.render.client",
7373
"survivalblock.atmosphere.atmospheric_api.mixin.item.scrolling.client",
7474
"survivalblock.atmosphere.atmospheric_api.mixin.item.spyglass.client",
75+
"survivalblock.atmosphere.atmospheric_api.mixin.item.trident.client",
7576
"survivalblock.atmosphere.atmospheric_api.mixin.item.two_handed.client",
7677
"survivalblock.atmosphere.atmospheric_api.mixin.particle.client",
7778
"survivalblock.atmosphere.atmospheric_api.mixin.render.overlay.client",
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//? if =1.21.1 {
2+
/*package survivalblock.atmosphere.atmospheric_api.mixin.item.trident.client;
3+
4+
import com.llamalad7.mixinextras.expression.Definition;
5+
import com.llamalad7.mixinextras.expression.Expression;
6+
import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
7+
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
8+
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
9+
import com.llamalad7.mixinextras.sugar.Local;
10+
import net.minecraft.client.renderer.entity.ItemRenderer;
11+
import net.minecraft.client.resources.model.ModelResourceLocation;
12+
import net.minecraft.world.item.Item;
13+
import net.minecraft.world.item.ItemStack;
14+
import org.spongepowered.asm.mixin.Mixin;
15+
import org.spongepowered.asm.mixin.injection.At;
16+
import survivalblock.atmosphere.atmospheric_api.not_mixin.item.client.AtmosphericTridentRegistryImpl;
17+
18+
import static survivalblock.atmosphere.atmospheric_api.not_mixin.item.client.AtmosphericTridentRegistryImpl.TRIDENTS;
19+
20+
@Mixin(ItemRenderer.class)
21+
public class ItemRendererMixin {
22+
23+
@Definition(id = "is", method = "Lnet/minecraft/world/item/ItemStack;is(Lnet/minecraft/world/item/Item;)Z")
24+
@Definition(id = "TRIDENT", field = "Lnet/minecraft/world/item/Items;TRIDENT:Lnet/minecraft/world/item/Item;")
25+
@Expression("?.is(TRIDENT)")
26+
@WrapOperation(method = {"getModel", "render"}, at = @At("MIXINEXTRAS:EXPRESSION"))
27+
private boolean checkModdedTrident(ItemStack instance, Item item, Operation<Boolean> original) {
28+
return original.call(instance, item) || TRIDENTS.containsKey(item);
29+
}
30+
31+
@ModifyExpressionValue(method = "render", at = @At(value = "FIELD", target = "Lnet/minecraft/client/renderer/entity/ItemRenderer;TRIDENT_MODEL:Lnet/minecraft/client/resources/model/ModelResourceLocation;"))
32+
private ModelResourceLocation getModdedTridentInventory(ModelResourceLocation original, @Local(argsOnly = true) ItemStack stack) {
33+
Item item = stack.getItem();
34+
if (TRIDENTS.containsKey(item)) {
35+
AtmosphericTridentRegistryImpl.Renderer renderer = TRIDENTS.get(item);
36+
return renderer.modelResourceLocation;
37+
}
38+
return original;
39+
}
40+
}
41+
*///?}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//? if >=1.21.4 {
2+
package survivalblock.atmosphere.atmospheric_api.mixin.item.trident.client;
3+
4+
import com.mojang.serialization.MapCodec;
5+
import net.minecraft.client.renderer.special.SpecialModelRenderer;
6+
import net.minecraft.client.renderer.special.SpecialModelRenderers;
7+
import net.minecraft.resources.ResourceLocation;
8+
import net.minecraft.util.ExtraCodecs;
9+
import org.spongepowered.asm.mixin.Final;
10+
import org.spongepowered.asm.mixin.Mixin;
11+
import org.spongepowered.asm.mixin.Shadow;
12+
import org.spongepowered.asm.mixin.injection.At;
13+
import org.spongepowered.asm.mixin.injection.Inject;
14+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
15+
import survivalblock.atmosphere.atmospheric_api.not_mixin.item.client.AtmosphericTridentModelRenderer;
16+
17+
@Mixin(SpecialModelRenderers.class)
18+
public class SpecialModelTypesMixin {
19+
@Shadow
20+
@Final
21+
public static ExtraCodecs.LateBoundIdMapper<ResourceLocation, MapCodec<? extends SpecialModelRenderer.Unbaked>> ID_MAPPER;
22+
23+
@Inject(method = "bootstrap", at = @At("RETURN"))
24+
private static void addAtmosphericTrident(CallbackInfo ci) {
25+
ID_MAPPER.put(AtmosphericTridentModelRenderer.ID, AtmosphericTridentModelRenderer.Unbaked.MAP_CODEC);
26+
}
27+
}
28+
//?}

src/main/java/survivalblock/atmosphere/atmospheric_api/not_mixin/item/CreativeTabEnchantmentAdder.java

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import net.minecraft.core.Holder;
44
import net.minecraft.core.registries.BuiltInRegistries;
55
import net.minecraft.core.registries.Registries;
6+
import net.minecraft.resources.ResourceKey;
67
import net.minecraft.resources.ResourceLocation;
78
import net.minecraft.world.item.CreativeModeTab;
89
import net.minecraft.world.item.Item;
@@ -13,26 +14,40 @@
1314

1415
import java.util.Optional;
1516
import java.util.function.Consumer;
17+
import java.util.function.Predicate;
18+
import java.util.function.Supplier;
1619

1720
@SuppressWarnings("unused")
1821
public class CreativeTabEnchantmentAdder {
1922

20-
public static void addEnchantedStack(Item item, CreativeModeTab.ItemDisplayParameters displayContext, String enchantmentId, CreativeModeTab.Output entries) {
21-
addEnchantedStack(item, displayContext, enchantmentId, entries, null);
23+
public static void addEnchantedStack(Item item, CreativeModeTab.ItemDisplayParameters displayContext, String enchantment, CreativeModeTab.Output entries) {
24+
addEnchantedStack(item, displayContext, enchantment, entries, null);
2225
}
2326

24-
public static void addEnchantedStack(Item item, CreativeModeTab.ItemDisplayParameters displayContext, String enchantmentId, CreativeModeTab.Output entries, @Nullable Consumer<ItemStack> stackModifier) {
27+
public static void addEnchantedStack(Item item, CreativeModeTab.ItemDisplayParameters displayContext, String enchantment, CreativeModeTab.Output entries, @Nullable Consumer<ItemStack> stackModifier) {
28+
ResourceLocation enchantmentId = ResourceLocation.tryParse(enchantment);
29+
addEnchantedStack(item, displayContext, reference -> reference.is(enchantmentId), () -> enchantment, entries, stackModifier);
30+
}
31+
32+
public static void addEnchantedStack(Item item, CreativeModeTab.ItemDisplayParameters displayContext, ResourceKey<Enchantment> enchantment, CreativeModeTab.Output entries) {
33+
addEnchantedStack(item, displayContext, enchantment, entries, null);
34+
}
35+
36+
public static void addEnchantedStack(Item item, CreativeModeTab.ItemDisplayParameters displayContext, ResourceKey<Enchantment> enchantment, CreativeModeTab.Output entries, @Nullable Consumer<ItemStack> stackModifier) {
37+
addEnchantedStack(item, displayContext, reference -> reference.is(enchantment), () -> enchantment.location().toString(), entries, stackModifier);
38+
}
39+
40+
public static void addEnchantedStack(Item item, CreativeModeTab.ItemDisplayParameters displayContext, Predicate<Holder.Reference<Enchantment>> enchantmentChecker, Supplier<String> idSupplierOnError, CreativeModeTab.Output entries, @Nullable Consumer<ItemStack> stackModifier) {
2541
try {
2642
ItemStack stack = new ItemStack(item);
27-
ResourceLocation id = ResourceLocation.parse(enchantmentId);
2843

2944
Optional<Holder.Reference<Enchantment>> optional = displayContext.holders()
3045
.lookupOrThrow(Registries.ENCHANTMENT)
3146
.listElements()
32-
.filter(enchantmentRef -> enchantmentRef.is(id))
47+
.filter(enchantmentChecker)
3348
.findFirst();
3449
if (optional.isEmpty()) {
35-
throw new NullPointerException("Enchantment " + enchantmentId + " was not found");
50+
throw new NullPointerException("Enchantment " + idSupplierOnError.get() + " was not found");
3651
}
3752

3853
Holder<Enchantment> enchantmentEntry = optional.get();
@@ -43,14 +58,14 @@ public static void addEnchantedStack(Item item, CreativeModeTab.ItemDisplayParam
4358
}
4459
entries.accept(stack);
4560
} else {
46-
AtmosphericAPI.LOGGER.error("Avoided adding an ItemStack of {} because enchantment {} does not support that item", BuiltInRegistries.ITEM.getId(item), id);
61+
AtmosphericAPI.LOGGER.error("Avoided adding an ItemStack of {} because enchantment {} does not support that item", BuiltInRegistries.ITEM.getId(item), idSupplierOnError.get());
4762
}
4863

4964
} catch (Throwable throwable) {
5065
try {
51-
AtmosphericAPI.LOGGER.error("Unable to add an ItemStack of {} because of an error when getting enchantment {}", BuiltInRegistries.ITEM.getId(item), enchantmentId, throwable);
66+
AtmosphericAPI.LOGGER.error("Unable to add an ItemStack of {} because of an error when getting enchantment {}", BuiltInRegistries.ITEM.getId(item), idSupplierOnError.get(), throwable);
5267
} catch (Throwable throwable1) {
53-
AtmosphericAPI.LOGGER.error("There was an error while getting enchantment {}", enchantmentId, throwable);
68+
AtmosphericAPI.LOGGER.error("There was an error while getting enchantment {}", idSupplierOnError.get(), throwable);
5469
AtmosphericAPI.LOGGER.error("There was an error while trying to get an item's id from the registry!", throwable1);
5570
}
5671
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
//? if >=1.21.4 {
2+
package survivalblock.atmosphere.atmospheric_api.not_mixin.item.client;
3+
4+
import com.mojang.blaze3d.vertex.PoseStack;
5+
import com.mojang.blaze3d.vertex.VertexConsumer;
6+
import com.mojang.serialization.Codec;
7+
import com.mojang.serialization.MapCodec;
8+
import com.mojang.serialization.codecs.RecordCodecBuilder;
9+
import net.fabricmc.api.EnvType;
10+
import net.fabricmc.api.Environment;
11+
import net.minecraft.client.model.Model;
12+
import net.minecraft.client.model.TridentModel;
13+
import net.minecraft.client.model.geom.EntityModelSet;
14+
import net.minecraft.client.model.geom.ModelLayerLocation;
15+
import net.minecraft.client.model.geom.ModelLayers;
16+
//? if <1.21.9
17+
import net.minecraft.client.renderer.MultiBufferSource;
18+
//? if >=1.21.9
19+
/*import net.minecraft.client.renderer.SubmitNodeCollector;*/
20+
import net.minecraft.client.renderer.entity.ItemRenderer;
21+
import net.minecraft.client.renderer.special.NoDataSpecialModelRenderer;
22+
import net.minecraft.client.renderer.special.SpecialModelRenderer;
23+
import net.minecraft.resources.ResourceLocation;
24+
import net.minecraft.world.item.ItemDisplayContext;
25+
import org.joml.Vector3f;
26+
import survivalblock.atmosphere.atmospheric_api.not_mixin.AtmosphericAPI;
27+
28+
import java.util.Set;
29+
30+
@SuppressWarnings("ClassCanBeRecord")
31+
@Environment(EnvType.CLIENT)
32+
public class AtmosphericTridentModelRenderer implements NoDataSpecialModelRenderer {
33+
public static final ResourceLocation ID = AtmosphericAPI.id("trident");
34+
private final Model model;
35+
private final ResourceLocation texture;
36+
37+
public AtmosphericTridentModelRenderer(Model model, ResourceLocation texture) {
38+
this.model = model;
39+
this.texture = texture;
40+
}
41+
42+
@Override
43+
public void /*? >=1.21.9 {*/ /*submit *//*?} else {*/ render /*?}*/(ItemDisplayContext displayContext, PoseStack matrices,/*? >=1.21.9 {*/ /*SubmitNodeCollector renderQueue *//*?} else {*/ MultiBufferSource bufferSource /*?}*/, int packedLight, int packedOverlay, boolean hasFoil/*? >=1.21.9 {*/ /*, int outlineColor *//*?}*/) {
44+
matrices.pushPose();
45+
matrices.scale(1.0F, -1.0F, -1.0F);
46+
//? if <1.21.9 {
47+
VertexConsumer vertexConsumer = ItemRenderer.getFoilBuffer(bufferSource, this.model.renderType(this.texture), false, hasFoil);
48+
this.model.renderToBuffer(matrices, vertexConsumer, packedLight, packedOverlay);
49+
//?} else {
50+
/*renderQueue.submitModelPart(this.model.root(), matrices, this.model.renderType(this.texture), packedLight, packedOverlay, null, false, hasFoil, -1, null, outlineColor);
51+
*///?}
52+
matrices.popPose();
53+
}
54+
55+
@Override
56+
public void getExtents(Set<Vector3f> output) {
57+
PoseStack matrices = new PoseStack();
58+
matrices.scale(1.0F, -1.0F, -1.0F);
59+
this.model.root().getExtentsForGui(matrices, output);
60+
}
61+
62+
@Environment(EnvType.CLIENT)
63+
public record Unbaked(ResourceLocation texture, ModelLayerLocation entityModelLayer) implements SpecialModelRenderer.Unbaked {
64+
public static final Codec<ModelLayerLocation> MODEL_LAYER_CODEC = RecordCodecBuilder.create(
65+
instance -> instance.group(
66+
ResourceLocation.CODEC.fieldOf("model").forGetter(ModelLayerLocation::model),
67+
Codec.STRING.optionalFieldOf("layer", "main").forGetter(ModelLayerLocation::layer)
68+
)
69+
.apply(instance, ModelLayerLocation::new)
70+
);
71+
public static final MapCodec<Unbaked> MAP_CODEC = RecordCodecBuilder.mapCodec(
72+
instance -> instance.group(
73+
ResourceLocation.CODEC.fieldOf("texture").forGetter(unbaked -> unbaked.texture),
74+
MODEL_LAYER_CODEC.optionalFieldOf("entityModelLayer", ModelLayers.TRIDENT).forGetter(unbaked -> unbaked.entityModelLayer)
75+
)
76+
.apply(instance, Unbaked::new)
77+
);
78+
79+
public MapCodec<Unbaked> type() {
80+
return MAP_CODEC;
81+
}
82+
83+
public SpecialModelRenderer<?> bake(EntityModelSet modelSet) {
84+
return new AtmosphericTridentModelRenderer(new TridentModel(modelSet.bakeLayer(this.entityModelLayer)), this.texture);
85+
}
86+
}
87+
}
88+
//?}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//? if =1.21.1 {
2+
/*package survivalblock.atmosphere.atmospheric_api.not_mixin.item.client;
3+
4+
import net.fabricmc.api.EnvType;
5+
import net.fabricmc.api.Environment;
6+
import net.minecraft.client.model.geom.ModelLayerLocation;
7+
import net.minecraft.client.resources.model.ModelResourceLocation;
8+
import net.minecraft.resources.ResourceLocation;
9+
import net.minecraft.world.item.Item;
10+
11+
@SuppressWarnings("unused")
12+
@Environment(EnvType.CLIENT)
13+
public class AtmosphericTridentRegistry {
14+
15+
public static void register(Item item, ResourceLocation texture) {
16+
AtmosphericTridentRegistryImpl.register(item, texture);
17+
}
18+
19+
public static void register(Item item, ResourceLocation texture, ModelResourceLocation modelResourceLocation) {
20+
AtmosphericTridentRegistryImpl.register(item, texture, modelResourceLocation);
21+
}
22+
23+
public static void register(Item item, ResourceLocation texture, ModelLayerLocation modelLayerLocation) {
24+
AtmosphericTridentRegistryImpl.register(item, texture, modelLayerLocation);
25+
}
26+
27+
public static void register(Item item, ResourceLocation texture, ModelResourceLocation modelResourceLocation, ModelLayerLocation modelLayerLocation) {
28+
AtmosphericTridentRegistryImpl.register(item, texture, modelResourceLocation, modelLayerLocation);
29+
}
30+
}
31+
*///?}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
//? if =1.21.1 {
2+
/*package survivalblock.atmosphere.atmospheric_api.not_mixin.item.client;
3+
4+
import com.mojang.blaze3d.vertex.PoseStack;
5+
import com.mojang.blaze3d.vertex.VertexConsumer;
6+
import net.fabricmc.api.EnvType;
7+
import net.fabricmc.api.Environment;
8+
import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry;
9+
import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
10+
import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener;
11+
import net.minecraft.client.Minecraft;
12+
import net.minecraft.client.model.Model;
13+
import net.minecraft.client.model.TridentModel;
14+
import net.minecraft.client.model.geom.EntityModelSet;
15+
import net.minecraft.client.model.geom.ModelLayerLocation;
16+
import net.minecraft.client.renderer.MultiBufferSource;
17+
import net.minecraft.client.renderer.entity.ItemRenderer;
18+
import net.minecraft.client.resources.model.ModelResourceLocation;
19+
import net.minecraft.core.registries.BuiltInRegistries;
20+
import net.minecraft.resources.ResourceLocation;
21+
import net.minecraft.server.packs.PackType;
22+
import net.minecraft.server.packs.resources.ResourceManager;
23+
import net.minecraft.world.item.Item;
24+
import net.minecraft.world.item.ItemDisplayContext;
25+
import net.minecraft.world.item.ItemStack;
26+
import org.jetbrains.annotations.ApiStatus;
27+
28+
import java.util.HashMap;
29+
import java.util.Map;
30+
31+
@ApiStatus.Internal
32+
@Environment(EnvType.CLIENT)
33+
public class AtmosphericTridentRegistryImpl {
34+
35+
public static final Map<Item, Renderer> TRIDENTS = new HashMap<>();
36+
37+
static void register(Item item, ResourceLocation texture) {
38+
register(item, texture, ModelResourceLocation.inventory(BuiltInRegistries.ITEM.getKey(item)));
39+
}
40+
41+
public static void register(Item item, ResourceLocation texture, ModelResourceLocation modelResourceLocation) {
42+
register(item, texture, modelResourceLocation, new ModelLayerLocation(BuiltInRegistries.ITEM.getKey(item), "main"));
43+
}
44+
45+
public static void register(Item item, ResourceLocation texture, ModelLayerLocation modelLayerLocation) {
46+
register(item, texture, ModelResourceLocation.inventory(BuiltInRegistries.ITEM.getKey(item)), modelLayerLocation);
47+
}
48+
49+
public static void register(Item item, ResourceLocation texture, ModelResourceLocation modelResourceLocation, ModelLayerLocation modelLayerLocation) {
50+
Renderer renderer = new Renderer(texture, modelResourceLocation, modelLayerLocation);
51+
52+
BuiltinItemRendererRegistry.INSTANCE.register(item, renderer);
53+
ResourceManagerHelper.get(PackType.CLIENT_RESOURCES).registerReloadListener(renderer);
54+
55+
TRIDENTS.put(item, renderer);
56+
}
57+
58+
public static class Renderer implements BuiltinItemRendererRegistry.DynamicItemRenderer, SimpleSynchronousResourceReloadListener {
59+
private Model modelTrident;
60+
private final ResourceLocation texture;
61+
public final ModelResourceLocation modelResourceLocation;
62+
public final ModelLayerLocation modelLayerLocation;
63+
private final ResourceLocation id;
64+
65+
public Renderer(ResourceLocation texture, ModelResourceLocation modelResourceLocation, ModelLayerLocation modelLayerLocation) {
66+
this.texture = texture;
67+
this.modelResourceLocation = modelResourceLocation;
68+
this.modelLayerLocation = modelLayerLocation;
69+
this.id = modelLayerLocation.getModel().withPath(path -> path + "_item_renderer");
70+
}
71+
72+
@Override
73+
public void render(ItemStack stack, ItemDisplayContext displayContext, PoseStack matrices, MultiBufferSource vertexConsumers, int light, int overlay) {
74+
matrices.pushPose();
75+
matrices.scale(1.0F, -1.0F, -1.0F);
76+
VertexConsumer vertexConsumer2 = ItemRenderer.getFoilBufferDirect(
77+
vertexConsumers, this.modelTrident.renderType(this.texture), false, stack.hasFoil()
78+
);
79+
this.modelTrident.renderToBuffer(matrices, vertexConsumer2, light, overlay);
80+
matrices.popPose();
81+
}
82+
83+
@Override
84+
public ResourceLocation getFabricId() {
85+
return this.id;
86+
}
87+
88+
@Override
89+
public void onResourceManagerReload(ResourceManager resourceManager) {
90+
EntityModelSet entityModelLoader = Minecraft.getInstance().getEntityModels();
91+
this.modelTrident = new TridentModel(entityModelLoader.bakeLayer(this.modelLayerLocation));
92+
}
93+
}
94+
}
95+
*///?}

src/main/resources/atmospheric_api.mixins.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
"item.spyglass.client.InGameHudAccessor",
3939
"item.spyglass.client.InGameHudMixin",
4040
"item.spyglass.client.MouseMixin",
41+
"item.trident.client.SpecialModelTypesMixin",
4142
"item.two_handed.client.BipedEntityModelMixin",
4243
"item.two_handed.client.CrossbowPosingMixin",
4344
"item.two_handed.client.HeldItemRendererMixin",

0 commit comments

Comments
 (0)