Skip to content

Commit

Permalink
fix loot, render book as model in hand now
Browse files Browse the repository at this point in the history
  • Loading branch information
reoseah committed Oct 30, 2024
1 parent a8f7b2a commit 2a6fe9f
Show file tree
Hide file tree
Showing 14 changed files with 214 additions and 19 deletions.
5 changes: 1 addition & 4 deletions src/main/java/io/github/reoseah/magisterium/Magisterium.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import net.fabricmc.fabric.api.loot.v3.LootTableSource;
import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry;
import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking;
import net.minecraft.block.BlockState;
import net.minecraft.block.LecternBlock;
import net.minecraft.block.entity.LecternBlockEntity;
import net.minecraft.entity.player.PlayerEntity;
Expand All @@ -35,14 +34,12 @@
import net.minecraft.registry.*;
import net.minecraft.screen.NamedScreenHandlerFactory;
import net.minecraft.screen.ScreenHandler;
import net.minecraft.sound.BlockSoundGroup;
import net.minecraft.sound.SoundCategory;
import net.minecraft.text.Text;
import net.minecraft.util.ActionResult;
import net.minecraft.util.Hand;
import net.minecraft.util.Identifier;
import net.minecraft.util.hit.BlockHitResult;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.event.GameEvent;
import org.slf4j.Logger;
Expand Down Expand Up @@ -77,7 +74,7 @@ public void onInitialize() {
Registry.register(Registries.ITEM, "magisterium:bookmark", BookmarkItem.INSTANCE);

Registry.register(Registries.DATA_COMPONENT_TYPE, "magisterium:current_page", SpellBookItem.CURRENT_PAGE);
Registry.register(Registries.DATA_COMPONENT_TYPE, "magisterium:page_data", SpellBookItem.PAGES);
Registry.register(Registries.DATA_COMPONENT_TYPE, "magisterium:contents", SpellBookItem.CONTENTS);
Registry.register(Registries.DATA_COMPONENT_TYPE, "magisterium:unstable_charge", SpellBookItem.UNSTABLE_CHARGE);

var group = FabricItemGroup.builder() //
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/io/github/reoseah/magisterium/MagisteriumClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,23 @@
import io.github.reoseah.magisterium.block.GlyphBlock;
import io.github.reoseah.magisterium.block.IllusoryWallBlockEntity;
import io.github.reoseah.magisterium.block.IllusoryWallBlockEntityRenderer;
import io.github.reoseah.magisterium.item.SpellBookItem;
import io.github.reoseah.magisterium.screen.ArcaneTableScreen;
import io.github.reoseah.magisterium.screen.ArcaneTableScreenHandler;
import io.github.reoseah.magisterium.screen.SpellBookScreen;
import io.github.reoseah.magisterium.screen.SpellBookScreenHandler;
import io.github.reoseah.magisterium.spellbook.SpellDataLoader;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap;
import net.fabricmc.fabric.api.client.model.loading.v1.ModelLoadingPlugin;
import net.fabricmc.fabric.impl.resource.loader.ResourceManagerHelperImpl;
import net.minecraft.client.gui.screen.ingame.HandledScreens;
import net.minecraft.client.item.ModelPredicateProviderRegistry;
import net.minecraft.client.render.RenderLayer;
import net.minecraft.client.render.block.entity.BlockEntityRendererFactories;
import net.minecraft.client.util.ModelIdentifier;
import net.minecraft.resource.ResourceType;
import net.minecraft.util.Identifier;

public class MagisteriumClient implements ClientModInitializer {
@Override
Expand All @@ -27,6 +32,11 @@ public void onInitializeClient() {

BlockRenderLayerMap.INSTANCE.putBlocks(RenderLayer.getCutout(), ArcaneTableBlock.INSTANCE, GlyphBlock.INSTANCE);

ModelLoadingPlugin.register(ctx -> ctx.addModels(Identifier.of("magisterium", "item/spell_book_in_hand")));

ModelPredicateProviderRegistry.register(SpellBookItem.INSTANCE, Identifier.of("magisterium:is_in_hand"), //
(stack, world, entity, seed) -> entity != null && entity.getActiveItem().equals(stack) ? 1.0F : 0.0F);

HandledScreens.register(SpellBookScreenHandler.TYPE, SpellBookScreen::new);
HandledScreens.register(ArcaneTableScreenHandler.TYPE, ArcaneTableScreen::new);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class SpellBookItem extends Item {
.codec(Codecs.NONNEGATIVE_INT) //
.packetCodec(PacketCodecs.VAR_INT) //
.build();
public static final ComponentType<List<ItemStack>> PAGES = ComponentType.<List<ItemStack>>builder() //
public static final ComponentType<List<ItemStack>> CONTENTS = ComponentType.<List<ItemStack>>builder() //
.codec(ItemStack.OPTIONAL_CODEC.listOf()) //
.packetCodec(ItemStack.OPTIONAL_PACKET_CODEC.collect(PacketCodecs.toList())) //
.build();
Expand All @@ -47,7 +47,7 @@ protected SpellBookItem(Settings settings) {
public static ItemStack createTestBook() {
ItemStack book = new ItemStack(INSTANCE);

book.set(PAGES, Util.make(DefaultedList.ofSize(18, ItemStack.EMPTY), list -> {
book.set(CONTENTS, Util.make(DefaultedList.ofSize(18, ItemStack.EMPTY), list -> {
list.set(0, BookmarkItem.INSTANCE.getDefaultStack());
list.set(1, SpellPageItem.AWAKEN_THE_FLAME.getDefaultStack());
list.set(2, SpellPageItem.QUENCH_THE_FLAME.getDefaultStack());
Expand All @@ -65,7 +65,7 @@ public static ItemStack createTestBook() {
public TypedActionResult<ItemStack> use(World world, PlayerEntity player, Hand hand) {
var book = player.getStackInHand(hand);

if (!book.contains(PAGES)) {
if (!book.contains(CONTENTS)) {
return TypedActionResult.fail(book);
}

Expand All @@ -88,7 +88,7 @@ public Text getDisplayName() {
@Override
public void appendTooltip(ItemStack stack, TooltipContext context, List<Text> tooltip, TooltipType type) {
super.appendTooltip(stack, context, tooltip, type);
var pages = stack.get(PAGES);
var pages = stack.get(CONTENTS);
if (pages != null && !pages.isEmpty()) {
var nonEmptyCount = pages.stream().filter(page -> !page.isEmpty()).count();
tooltip.add(Text.translatable("item.magisterium.spell_book.pages", nonEmptyCount).formatted(Formatting.GRAY));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package io.github.reoseah.magisterium.mixin.client;

import io.github.reoseah.magisterium.item.SpellBookItem;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.render.VertexConsumer;
import net.minecraft.client.render.VertexConsumerProvider;
import net.minecraft.client.render.entity.model.BookModel;
import net.minecraft.client.render.entity.model.EntityModelLayers;
import net.minecraft.client.render.item.BuiltinModelItemRenderer;
import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.render.model.json.ModelTransformationMode;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.resource.ResourceManager;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(BuiltinModelItemRenderer.class)
public class BuiltinItemModelRendererMixin {
@Unique
private static final Identifier TEXTURE = Identifier.of("magisterium", "textures/entity/spell_book.png");

@Unique
private BookModel bookModel;

@Inject(at = @At("HEAD"), method = "reload")
public void reload(ResourceManager manager, CallbackInfo ci) {
this.bookModel = new BookModel(MinecraftClient.getInstance().getEntityModelLoader().getModelPart(EntityModelLayers.BOOK));
}

@Inject(at = @At("HEAD"), method = "render", cancellable = true)
public void render(ItemStack stack, ModelTransformationMode mode, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, CallbackInfo ci) {
Item item = stack.getItem();
if (item == SpellBookItem.INSTANCE) {
matrices.push();
matrices.scale(1, -1, -1);
VertexConsumer vertexConsumer = ItemRenderer.getDirectItemGlintConsumer(vertexConsumers, this.bookModel.getLayer(TEXTURE), false, false);
this.bookModel.setPageAngles(0, 0.1F, 0.9F, 1.2F);
this.bookModel.render(matrices, vertexConsumer, light, overlay, 0xFFFFFF);
matrices.pop();
ci.cancel();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package io.github.reoseah.magisterium.mixin.client;

import io.github.reoseah.magisterium.item.SpellBookItem;
import net.minecraft.client.render.*;
import net.minecraft.client.render.item.BuiltinModelItemRenderer;
import net.minecraft.client.render.item.ItemModels;
import net.minecraft.client.render.item.ItemRenderer;
import net.minecraft.client.render.model.BakedModel;
import net.minecraft.client.render.model.json.ModelTransformationMode;
import net.minecraft.client.util.ModelIdentifier;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.entity.LivingEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.Identifier;
import net.minecraft.world.World;
import org.jetbrains.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;

import java.util.Objects;

@Mixin(ItemRenderer.class)
public abstract class ItemRendererMixin {
@Unique
private static final ModelIdentifier SPELL_BOOK = ModelIdentifier.ofInventoryVariant(Identifier.of("magisterium", "spell_book"));
@Unique
private static final Identifier SPELL_BOOK_IN_HAND = Identifier.of("magisterium", "item/spell_book_in_hand");

@Shadow
private @Final ItemModels models;
@Shadow
private @Final BuiltinModelItemRenderer builtinModelItemRenderer;

@Shadow
protected abstract void renderBakedItemModel(BakedModel model, ItemStack stack, int light, int overlay, MatrixStack matrices, VertexConsumer vertices);

@Inject(at = @At("HEAD"), method = "getModel", cancellable = true)
public void setHemonomiconModel(ItemStack stack, @Nullable World world, @Nullable LivingEntity entity, int seed, CallbackInfoReturnable<BakedModel> ci) {
Item item = stack.getItem();
if (item == SpellBookItem.INSTANCE) {
BakedModel model = this.models.getModelManager().getModel(SPELL_BOOK_IN_HAND);
ClientWorld clientWorld = world instanceof ClientWorld ? (ClientWorld) world : null;
model = model.getOverrides().apply(model, stack, clientWorld, entity, seed);
ci.setReturnValue(model == null ? this.models.getModelManager().getMissingModel() : model);
}
}

@Inject(at = @At("HEAD"), method = "renderItem", cancellable = true)
public void renderHemonomicon(ItemStack stack, ModelTransformationMode mode, boolean leftHanded, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, int overlay, BakedModel model, CallbackInfo ci) {
if (!stack.isEmpty() && stack.getItem() == SpellBookItem.INSTANCE) {
matrices.push();
boolean gui = mode == ModelTransformationMode.GUI;
boolean notInHand = gui || mode == ModelTransformationMode.GROUND || mode == ModelTransformationMode.FIXED;
if (notInHand) {
model = this.models.getModelManager().getModel(SPELL_BOOK);
}
model.getTransformation().getTransformation(mode).apply(leftHanded, matrices);
matrices.translate(-0.5D, -0.5D, -0.5D);
if (model.isBuiltin() || !notInHand) {
this.builtinModelItemRenderer.render(stack, mode, matrices, vertexConsumers, light, overlay);
} else {
RenderLayer itemLayer = RenderLayers.getItemLayer(stack, true);
RenderLayer layer;
if (gui && Objects.equals(itemLayer, TexturedRenderLayers.getEntityTranslucentCull())) {
layer = TexturedRenderLayers.getEntityTranslucentCull();
} else {
layer = itemLayer;
}

VertexConsumer vertexConsumer = ItemRenderer.getDirectItemGlintConsumer(vertexConsumers, layer, true, stack.hasGlint());
this.renderBakedItemModel(model, stack, light, overlay, matrices, vertexConsumer);
}
matrices.pop();
ci.cancel();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// but first two buttons ids are taken by page navigation
// and I find it awkward to have to "encode" page into a distinct button id
public record UseBookmarkPayload(int page) implements CustomPayload {
public static final CustomPayload.Id<UseBookmarkPayload> ID = new CustomPayload.Id<>(Identifier.of("hematurgy:hemonomicon/use_bookmark"));
public static final CustomPayload.Id<UseBookmarkPayload> ID = new CustomPayload.Id<>(Identifier.of("magisterium:use_bookmark"));
public static final PacketCodec<PacketByteBuf, UseBookmarkPayload> CODEC = CustomPayload.codecOf(UseBookmarkPayload::write, UseBookmarkPayload::new);

public UseBookmarkPayload(PacketByteBuf buf) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ public boolean canInsert(ItemStack stack) {
this.addSlot(new Slot(this.bookContentsInventory, column + row * 6, 81 + column * 18, 18 + row * 18) {
@Override
public boolean canTakeItems(PlayerEntity playerEntity) {
return bookInventory.getStack(0).contains(SpellBookItem.PAGES);
return bookInventory.getStack(0).contains(SpellBookItem.CONTENTS);
}

@Override
public boolean canInsert(ItemStack stack) {
return bookInventory.getStack(0).contains(SpellBookItem.PAGES) //
return bookInventory.getStack(0).contains(SpellBookItem.CONTENTS) //
&& stack.isIn(MagisteriumItemTags.SPELL_BOOK_COMPONENTS);
}
});
Expand Down Expand Up @@ -97,7 +97,7 @@ public ItemStack quickMove(PlayerEntity player, int index) {
if (!this.insertItem(stack, 0, 1, false)) {
return ItemStack.EMPTY;
}
} else if (stack.isIn(MagisteriumItemTags.SPELL_BOOK_COMPONENTS) && bookInventory.getStack(0).contains(SpellBookItem.PAGES)) {
} else if (stack.isIn(MagisteriumItemTags.SPELL_BOOK_COMPONENTS) && bookInventory.getStack(0).contains(SpellBookItem.CONTENTS)) {
if (!this.insertItem(stack, 1, 1 + 18, false)) {
return ItemStack.EMPTY;
}
Expand Down Expand Up @@ -151,7 +151,7 @@ public BookContentsInventory(SimpleInventory bookInventory) {
if (book != this.book) {
this.clearWithoutNotifyingListeners();
if (book.isOf(SpellBookItem.INSTANCE)) {
var bookPages = book.get(SpellBookItem.PAGES);
var bookPages = book.get(SpellBookItem.CONTENTS);
if (bookPages != null) {
for (int i = 0; i < bookPages.size(); i++) {
this.heldStacks.set(i, bookPages.get(i));
Expand All @@ -165,7 +165,7 @@ public BookContentsInventory(SimpleInventory bookInventory) {
var book = this.bookInventory.getStack(0);
if (book.isOf(SpellBookItem.INSTANCE)) {
book.set(SpellBookItem.CURRENT_PAGE, 0);
book.set(SpellBookItem.PAGES, new ArrayList<>(this.getHeldStacks()));
book.set(SpellBookItem.CONTENTS, new ArrayList<>(this.getHeldStacks()));
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ protected void init() {
.formatted(Formatting.ITALIC).styled(style -> style.withColor(0xc4b090));

private void buildPages() {
var pages = this.handler.getSpellBook().getOrDefault(SpellBookItem.PAGES, DefaultedList.ofSize(18, ItemStack.EMPTY));
var pages = this.handler.getSpellBook().getOrDefault(SpellBookItem.CONTENTS, DefaultedList.ofSize(18, ItemStack.EMPTY));

var builder = new BookLayout.Builder(this.properties);
for (ItemStack stack : pages) {
Expand Down
Binary file modified src/main/resources/assets/magisterium/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,13 @@
"parent": "minecraft:item/generated",
"textures": {
"layer0": "magisterium:item/spell_book"
}
},
"overrides": [
{
"predicate": {
"magisterium:is_in_hand": 1
},
"model": "magisterium:item/spell_book_in_hand"
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"parent": "builtin/entity",
"gui_light": "front",
"textures": {
"particle": "magisterium:item/spell_book"
},
"display": {
"thirdperson_righthand": {
"rotation": [0, -120, 0],
"translation": [-12, 12, 3],
"scale": [1, 1, 1]
},
"thirdperson_lefthand": {
"rotation": [0, 60, 0],
"translation": [3, 12, 12],
"scale": [1, 1, 1]
},
"firstperson_righthand": {
"rotation": [0, -90, 25],
"translation": [-3, 12, 1],
"scale": [1, 1, 1]
},
"firstperson_lefthand": {
"rotation": [0, 90, -25],
"translation": [13, 12, 1],
"scale": [1, 1, 1]
},
"gui": {
"rotation": [15, -25, -5],
"translation": [2, 3, 0],
"scale": [0.65, 0.65, 0.65]
},
"fixed": {
"rotation": [0, 180, 0],
"translation": [-2, 4, -5],
"scale": [0.5, 0.5, 0.5]
},
"ground": {
"rotation": [0, 0, 0],
"translation": [4, 4, 2],
"scale": [0.25, 0.25, 0.25]
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
{
"type": "minecraft:item",
"weight": 10,
"name": "magisterium:awaken_the_fire_page"
"name": "magisterium:awaken_the_flame_page"
},
{
"type": "minecraft:item",
"weight": 10,
"name": "magisterium:quench_the_fire_page"
"name": "magisterium:quench_the_flame_page"
},
{
"type": "minecraft:item",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
{
"function": "set_components",
"components": {
"magisterium:pages": [
"magisterium:contents": [
{
"id": "magisterium:awaken_the_flame_page",
"count": 1
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/magisterium.client.mixins.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
"package": "io.github.reoseah.magisterium.mixin.client",
"compatibilityLevel": "JAVA_21",
"client": [
"BuiltinItemModelRendererMixin",
"ItemRendererMixin",
"LecternBlockEntityRendererMixin"
],
"injectors": {
Expand Down

0 comments on commit 2a6fe9f

Please sign in to comment.