LTCatt пре 5 година
родитељ
комит
17e3604a02

+ 0 - 3
src/main/java/com/hexdragon/corere/item/EnchantmentHelperRe.java

@@ -3,10 +3,7 @@ package com.hexdragon.corere.item;
 import com.sun.istack.internal.NotNull;
 import net.minecraft.enchantment.Enchantment;
 import net.minecraft.enchantment.EnchantmentHelper;
-import net.minecraft.item.EnchantedBookItem;
 import net.minecraft.item.ItemStack;
-import net.minecraft.item.Items;
-import net.minecraft.nbt.ListNBT;
 
 import java.util.Map;
 import java.util.stream.Collectors;

+ 152 - 163
src/main/java/com/hexdragon/enchre/block/enchantingtable/EnchantmentContainerRe.java

@@ -28,11 +28,9 @@ import java.util.List;
 import java.util.Random;
 
 public class EnchantmentContainerRe extends Container {
+
+    // 物品栏与数据存储
     private final IInventory tableInventory = new Inventory(2) {
-        /**
-         * For tile entities, ensures the chunk containing the tile entity is saved to disk later - the game won't think
-         * it hasn't changed and skip it.
-         */
         public void markDirty() {
             super.markDirty();
             EnchantmentContainerRe.this.onCraftMatrixChanged(this);
@@ -41,214 +39,209 @@ public class EnchantmentContainerRe extends Container {
     private final IWorldPosCallable worldPosCallable;
     private final Random rand = new Random();
     private final IntReferenceHolder xpSeed = IntReferenceHolder.single();
-    public final int[] enchantLevels = new int[3];
-    public final int[] enchantClue = new int[]{-1, -1, -1};
-    public final int[] worldClue = new int[]{-1, -1, -1};
-
-    public EnchantmentContainerRe(int id, PlayerInventory playerInventory) {
-        this(id, playerInventory, IWorldPosCallable.DUMMY);
-    }
 
+    // 构造函数
+    public EnchantmentContainerRe(int id, PlayerInventory playerInventory) {this(id, playerInventory, IWorldPosCallable.DUMMY);}
     public EnchantmentContainerRe(int id, PlayerInventory playerInventory, IWorldPosCallable worldPosCallable) {
         super(RegMain.containerEnchantment.get(), id);
         this.worldPosCallable = worldPosCallable;
+
+        // 追踪数据变化,以自动 makeDirty
+        this.trackInt(IntReferenceHolder.create(this.enchantLevels, 0));
+        this.trackInt(IntReferenceHolder.create(this.enchantLevels, 1));
+        this.trackInt(IntReferenceHolder.create(this.enchantLevels, 2));
+        this.trackInt(this.xpSeed).set(playerInventory.player.getXPSeed());
+        this.trackInt(IntReferenceHolder.create(this.guiEnchantId, 0));
+        this.trackInt(IntReferenceHolder.create(this.guiEnchantId, 1));
+        this.trackInt(IntReferenceHolder.create(this.guiEnchantId, 2));
+        this.trackInt(IntReferenceHolder.create(this.guiEnchantLevel, 0));
+        this.trackInt(IntReferenceHolder.create(this.guiEnchantLevel, 1));
+        this.trackInt(IntReferenceHolder.create(this.guiEnchantLevel, 2));
+
+        // 添加被附魔物品格
         this.addSlot(new Slot(this.tableInventory, 0, 15, 47) {
-            /**
-             * Check if the stack is allowed to be placed in this slot, used for armor slots as well as furnace fuel.
-             */
             public boolean isItemValid(ItemStack stack) {
                 return true;
             }
-
-            /**
-             * Returns the maximum stack size for a given slot (usually the same as getInventoryStackLimit(), but 1 in the
-             * case of armor slots)
-             */
             public int getSlotStackLimit() {
                 return 1;
             }
         });
-        this.addSlot(new Slot(this.tableInventory, 1, 35, 47) {
-            /**
-             * Check if the stack is allowed to be placed in this slot, used for armor slots as well as furnace fuel.
-             */
+        // 添加青金石物品格
+        this.addSlot(new Slot(this.tableInventory, 1, 15, 17) {
             public boolean isItemValid(ItemStack stack) {
                 return net.minecraftforge.common.Tags.Items.GEMS_LAPIS.contains(stack.getItem());
             }
         });
-
+        // 添加背包物品格
         for(int i = 0; i < 3; ++i) {
             for(int j = 0; j < 9; ++j) {
                 this.addSlot(new Slot(playerInventory, j + i * 9 + 9, 8 + j * 18, 84 + i * 18));
             }
         }
-
         for(int k = 0; k < 9; ++k) {
             this.addSlot(new Slot(playerInventory, k, 8 + k * 18, 142));
         }
 
-        this.trackInt(IntReferenceHolder.create(this.enchantLevels, 0));
-        this.trackInt(IntReferenceHolder.create(this.enchantLevels, 1));
-        this.trackInt(IntReferenceHolder.create(this.enchantLevels, 2));
-        this.trackInt(this.xpSeed).set(playerInventory.player.getXPSeed());
-        this.trackInt(IntReferenceHolder.create(this.enchantClue, 0));
-        this.trackInt(IntReferenceHolder.create(this.enchantClue, 1));
-        this.trackInt(IntReferenceHolder.create(this.enchantClue, 2));
-        this.trackInt(IntReferenceHolder.create(this.worldClue, 0));
-        this.trackInt(IntReferenceHolder.create(this.worldClue, 1));
-        this.trackInt(IntReferenceHolder.create(this.worldClue, 2));
     }
 
-    private float getPower(net.minecraft.world.World world, net.minecraft.util.math.BlockPos pos) {
-        return world.getBlockState(pos).getEnchantPowerBonus(world, pos);
-    }
+    // 附魔参数
+    public final int[] enchantLevels = new int[3]; // 显示在右下角的每个附魔选项的等级
+    public final int[] guiEnchantId = new int[]{-1, -1, -1}; // GUI 指向中显示的附魔 ID
+    public final int[] guiEnchantLevel = new int[]{-1, -1, -1}; // GUI 指向中显示的附魔等级
 
-    /**
-     * Callback for when the crafting matrix is changed.
-     */
+    // 更新附魔选项的等级与 GUI 显示信息
     public void onCraftMatrixChanged(IInventory inventoryIn) {
-        if (inventoryIn == this.tableInventory) {
-            ItemStack itemstack = inventoryIn.getStackInSlot(0);
-            if (!itemstack.isEmpty() && itemstack.isEnchantable()) {
-                this.worldPosCallable.consume((p_217002_2_, p_217002_3_) -> {
-                    int power = 0;
-
-                    for(int k = -1; k <= 1; ++k) {
-                        for(int l = -1; l <= 1; ++l) {
-                            if ((k != 0 || l != 0) && p_217002_2_.isAirBlock(p_217002_3_.add(l, 0, k)) && p_217002_2_.isAirBlock(p_217002_3_.add(l, 1, k))) {
-                                power += getPower(p_217002_2_, p_217002_3_.add(l * 2, 0, k * 2));
-                                power += getPower(p_217002_2_, p_217002_3_.add(l * 2, 1, k * 2));
-
-                                if (l != 0 && k != 0) {
-                                    power += getPower(p_217002_2_, p_217002_3_.add(l * 2, 0, k));
-                                    power += getPower(p_217002_2_, p_217002_3_.add(l * 2, 1, k));
-                                    power += getPower(p_217002_2_, p_217002_3_.add(l, 0, k * 2));
-                                    power += getPower(p_217002_2_, p_217002_3_.add(l, 1, k * 2));
-                                }
-                            }
-                        }
-                    }
-
-                    this.rand.setSeed((long)this.xpSeed.get());
-
-                    for(int i1 = 0; i1 < 3; ++i1) {
-                        this.enchantLevels[i1] = EnchantmentHelper.calcItemStackEnchantability(this.rand, i1, (int)power, itemstack);
-                        this.enchantClue[i1] = -1;
-                        this.worldClue[i1] = -1;
-                        if (this.enchantLevels[i1] < i1 + 1) {
-                            this.enchantLevels[i1] = 0;
-                        }
-                        this.enchantLevels[i1] = net.minecraftforge.event.ForgeEventFactory.onEnchantmentLevelSet(p_217002_2_, p_217002_3_, i1, (int)power, itemstack, enchantLevels[i1]);
-                    }
+        if (inventoryIn != this.tableInventory) return;
+
+        // 检查输入物品
+        ItemStack inputItem = inventoryIn.getStackInSlot(0);
+        if (inputItem.isEmpty() || !inputItem.isEnchantable()) {
+            for(int i = 0; i < 3; ++i) {
+                this.enchantLevels[i] = 0;
+                this.guiEnchantId[i] = -1;
+                this.guiEnchantLevel[i] = -1;
+            }
+            return;
+        }
 
-                    for(int j1 = 0; j1 < 3; ++j1) {
-                        if (this.enchantLevels[j1] > 0) {
-                            List<EnchantmentData> list = this.getEnchantmentList(itemstack, j1, this.enchantLevels[j1]);
-                            if (list != null && !list.isEmpty()) {
-                                EnchantmentData enchantmentdata = list.get(this.rand.nextInt(list.size()));
-                                this.enchantClue[j1] = Registry.ENCHANTMENT.getId(enchantmentdata.enchantment);
-                                this.worldClue[j1] = enchantmentdata.enchantmentLevel;
-                            }
+        this.worldPosCallable.consume((world, pos) -> {
+
+            // 获取书架提供的总附魔能力值
+            int power = 0;
+            for(int k = -1; k <= 1; ++k) {
+                for(int l = -1; l <= 1; ++l) {
+                    if ((k != 0 || l != 0) && world.isAirBlock(pos.add(l, 0, k)) && world.isAirBlock(pos.add(l, 1, k))) {
+                        power += getPower(world, pos.add(l * 2, 0, k * 2));
+                        power += getPower(world, pos.add(l * 2, 1, k * 2));
+                        if (l != 0 && k != 0) {
+                            power += getPower(world, pos.add(l * 2, 0, k));
+                            power += getPower(world, pos.add(l * 2, 1, k));
+                            power += getPower(world, pos.add(l, 0, k * 2));
+                            power += getPower(world, pos.add(l, 1, k * 2));
                         }
                     }
-
-                    this.detectAndSendChanges();
-                });
-            } else {
-                for(int i = 0; i < 3; ++i) {
-                    this.enchantLevels[i] = 0;
-                    this.enchantClue[i] = -1;
-                    this.worldClue[i] = -1;
                 }
             }
-        }
 
+            // 设置随机数种子
+            this.rand.setSeed(this.xpSeed.get());
+
+            // 获取附魔
+            for(int id = 0; id < 3; ++id) {
+                // 清空其他参数
+                this.guiEnchantId[id] = -1;
+                this.guiEnchantLevel[id] = -1;
+                // 根据物品与附魔编号,获取各个附魔的预计等级
+                this.enchantLevels[id] = EnchantmentHelper.calcItemStackEnchantability(this.rand, id, power, inputItem);
+                if (this.enchantLevels[id] < id + 1)  this.enchantLevels[id] = 0;
+                this.enchantLevels[id] = net.minecraftforge.event.ForgeEventFactory.onEnchantmentLevelSet(world, pos, id, power, inputItem, enchantLevels[id]);
+                if (this.enchantLevels[id] <= 0) continue;
+                // 根据等级,获取实际会附加的附魔列表
+                List<EnchantmentData> list = this.getEnchantmentList(inputItem, id, this.enchantLevels[id]);
+                if (list.isEmpty()) continue;
+                // 从附魔列表中抽取一项用于 GUI 显示
+                EnchantmentData enchantmentdata = list.get(this.rand.nextInt(list.size()));
+                this.guiEnchantId[id] = Registry.ENCHANTMENT.getId(enchantmentdata.enchantment);
+                this.guiEnchantLevel[id] = enchantmentdata.enchantmentLevel;
+            }
+
+            // 提交更改
+            this.detectAndSendChanges();
+
+        });
     }
 
-    /**
-     * Handles the given Button-click on the server, currently only used by enchanting. Name is for legacy.
-     */
+    // 实际为物品进行附魔(服务端触发)
     public boolean enchantItem(PlayerEntity playerIn, int id) {
-        ItemStack itemstack = this.tableInventory.getStackInSlot(0);
-        ItemStack itemstack1 = this.tableInventory.getStackInSlot(1);
-        int i = id + 1;
-        if ((itemstack1.isEmpty() || itemstack1.getCount() < i) && !playerIn.abilities.isCreativeMode) {
+        ItemStack inputItem = this.tableInventory.getStackInSlot(0);
+        ItemStack lapisItem = this.tableInventory.getStackInSlot(1);
+
+        // 前置条件检查
+        int cost = id + 1; // 青金石与等级花费
+        if ((lapisItem.isEmpty() || lapisItem.getCount() < cost) && !playerIn.abilities.isCreativeMode) {
+            // 检查青金石是否足够
             return false;
-        } else if (this.enchantLevels[id] <= 0 || itemstack.isEmpty() || (playerIn.experienceLevel < i || playerIn.experienceLevel < this.enchantLevels[id]) && !playerIn.abilities.isCreativeMode) {
+        } else if (this.enchantLevels[id] <= 0 || inputItem.isEmpty() || (playerIn.experienceLevel < cost || playerIn.experienceLevel < this.enchantLevels[id]) && !playerIn.abilities.isCreativeMode) {
+            // 检查玩家等级是否足够
             return false;
-        } else {
-            this.worldPosCallable.consume((p_217003_6_, p_217003_7_) -> {
-                ItemStack itemstack2 = itemstack;
-                List<EnchantmentData> list = this.getEnchantmentList(itemstack, id, this.enchantLevels[id]);
-                if (!list.isEmpty()) {
-                    playerIn.onEnchant(itemstack, i);
-                    boolean flag = itemstack.getItem() == Items.BOOK;
-                    if (flag) {
-                        itemstack2 = new ItemStack(Items.ENCHANTED_BOOK);
-                        CompoundNBT compoundnbt = itemstack.getTag();
-                        if (compoundnbt != null) {
-                            itemstack2.setTag(compoundnbt.copy());
-                        }
-
-                        this.tableInventory.setInventorySlotContents(0, itemstack2);
-                    }
-
-                    for(int j = 0; j < list.size(); ++j) {
-                        EnchantmentData enchantmentdata = list.get(j);
-                        if (flag) {
-                            EnchantedBookItem.addEnchantment(itemstack2, enchantmentdata);
-                        } else {
-                            itemstack2.addEnchantment(enchantmentdata.enchantment, enchantmentdata.enchantmentLevel);
-                        }
-                    }
-
-                    if (!playerIn.abilities.isCreativeMode) {
-                        itemstack1.shrink(i);
-                        if (itemstack1.isEmpty()) {
-                            this.tableInventory.setInventorySlotContents(1, ItemStack.EMPTY);
-                        }
-                    }
-
-                    playerIn.addStat(Stats.ENCHANT_ITEM);
-                    if (playerIn instanceof ServerPlayerEntity) {
-                        CriteriaTriggers.ENCHANTED_ITEM.trigger((ServerPlayerEntity)playerIn, itemstack2, i);
-                    }
-
-                    this.tableInventory.markDirty();
-                    this.xpSeed.set(playerIn.getXPSeed());
-                    this.onCraftMatrixChanged(this.tableInventory);
-                    p_217003_6_.playSound((PlayerEntity)null, p_217003_7_, SoundEvents.BLOCK_ENCHANTMENT_TABLE_USE, SoundCategory.BLOCKS, 1.0F, p_217003_6_.rand.nextFloat() * 0.1F + 0.9F);
+        }
+        // 检查准备附魔的列表是否为空
+        this.worldPosCallable.consume((world, pos) -> {
+            ItemStack outputItem = inputItem;
+            List<EnchantmentData> enchList = this.getEnchantmentList(inputItem, id, this.enchantLevels[id]); // 附魔列表
+            if (enchList.isEmpty()) return;
+
+            // 如果输入为书,则将输出替换为附魔书
+            boolean isBook = inputItem.getItem() == Items.BOOK;
+            if (isBook) {
+                outputItem = new ItemStack(Items.ENCHANTED_BOOK);
+                CompoundNBT compoundnbt = inputItem.getTag();
+                if (compoundnbt != null) outputItem.setTag(compoundnbt.copy());
+                this.tableInventory.setInventorySlotContents(0, outputItem);
+            }
+            // 为输出物品添加附魔
+            for(int j = 0; j < enchList.size(); ++j) {
+                EnchantmentData enchantmentdata = enchList.get(j);
+                if (isBook) {
+                    EnchantedBookItem.addEnchantment(outputItem, enchantmentdata);
+                } else {
+                    outputItem.addEnchantment(enchantmentdata.enchantment, enchantmentdata.enchantmentLevel);
                 }
+            }
+            // 扣除玩家等级,并重置附魔随机种子
+            playerIn.onEnchant(inputItem, cost);
+            // 扣除青金石
+            if (!playerIn.abilities.isCreativeMode) {
+                lapisItem.shrink(cost);
+                if (lapisItem.isEmpty()) this.tableInventory.setInventorySlotContents(1, ItemStack.EMPTY);
+            }
 
-            });
-            return true;
-        }
+            // 改变统计信息,触发 Trigger
+            playerIn.addStat(Stats.ENCHANT_ITEM);
+            if (playerIn instanceof ServerPlayerEntity) {
+                CriteriaTriggers.ENCHANTED_ITEM.trigger((ServerPlayerEntity)playerIn, outputItem, cost);
+            }
+            // 更新结果
+            this.tableInventory.markDirty();
+            this.xpSeed.set(playerIn.getXPSeed());
+            this.onCraftMatrixChanged(this.tableInventory);
+            world.playSound(null, pos, SoundEvents.BLOCK_ENCHANTMENT_TABLE_USE, SoundCategory.BLOCKS, 1.0F, world.rand.nextFloat() * 0.1F + 0.9F);
+
+        });
+        return true;
     }
 
+    // 为 [ItemStack、附魔位与等级] 提供固定的 [实际附魔列表] 输出
+    // 其中没有随机因素,相同输入会给出固定的输出(这基于玩家的一个种子)
     private List<EnchantmentData> getEnchantmentList(ItemStack stack, int enchantSlot, int level) {
-        this.rand.setSeed((long)(this.xpSeed.get() + enchantSlot));
+        this.rand.setSeed(this.xpSeed.get() + enchantSlot);
         List<EnchantmentData> list = EnchantmentHelper.buildEnchantmentList(this.rand, stack, level, false);
-        if (stack.getItem() == Items.BOOK && list.size() > 1) {
-            list.remove(this.rand.nextInt(list.size()));
-        }
-
+        if (stack.getItem() == Items.BOOK && list.size() > 1) list.remove(this.rand.nextInt(list.size()));
         return list;
     }
 
-    @OnlyIn(Dist.CLIENT)
-    public int getLapisAmount() {
+    /*********************************
+     *       无需修改的代码
+     ********************************/
+
+    // 获取某个方块的附魔能力值
+    private float getPower(net.minecraft.world.World world, net.minecraft.util.math.BlockPos pos) {
+        return world.getBlockState(pos).getEnchantPowerBonus(world, pos);
+    }
+
+    // 获取青金石数量
+    @OnlyIn(Dist.CLIENT) public int getLapisAmount() {
         ItemStack itemstack = this.tableInventory.getStackInSlot(1);
         return itemstack.isEmpty() ? 0 : itemstack.getCount();
     }
 
-    @OnlyIn(Dist.CLIENT)
-    public int func_217005_f() {
+    // 获取 xpSeed
+    @OnlyIn(Dist.CLIENT) public int getXpSeed() {
         return this.xpSeed.get();
     }
 
-    /**
-     * Called when the container is closed.
-     */
+    // 在容器关闭时返还物品
     public void onContainerClosed(PlayerEntity playerIn) {
         super.onContainerClosed(playerIn);
         this.worldPosCallable.consume((p_217004_2_, p_217004_3_) -> {
@@ -256,17 +249,12 @@ public class EnchantmentContainerRe extends Container {
         });
     }
 
-    /**
-     * Determines whether supplied player can use this container
-     */
+    // 玩家是否能与其交互
     public boolean canInteractWith(PlayerEntity playerIn) {
         return isWithinUsableDistance(this.worldPosCallable, playerIn, Blocks.ENCHANTING_TABLE);
     }
 
-    /**
-     * Handle when the stack in slot {@code index} is shift-clicked. Normally this moves the stack between the player
-     * inventory and the other inventory(s).
-     */
+    // 按 Shift+左键 时转移物品
     public ItemStack transferStackInSlot(PlayerEntity playerIn, int index) {
         ItemStack itemstack = ItemStack.EMPTY;
         Slot slot = this.inventorySlots.get(index);
@@ -311,4 +299,5 @@ public class EnchantmentContainerRe extends Container {
 
         return itemstack;
     }
+
 }

+ 143 - 165
src/main/java/com/hexdragon/enchre/block/enchantingtable/EnchantmentScreenRe.java

@@ -14,7 +14,6 @@ import net.minecraft.client.renderer.entity.model.BookModel;
 import net.minecraft.client.renderer.texture.OverlayTexture;
 import net.minecraft.enchantment.Enchantment;
 import net.minecraft.entity.player.PlayerInventory;
-import net.minecraft.inventory.container.EnchantmentContainer;
 import net.minecraft.item.ItemStack;
 import net.minecraft.util.EnchantmentNameParts;
 import net.minecraft.util.ResourceLocation;
@@ -32,55 +31,127 @@ import net.minecraftforge.api.distmarker.OnlyIn;
 
 @OnlyIn(Dist.CLIENT)
 public class EnchantmentScreenRe extends ContainerScreen<EnchantmentContainerRe> {
-    /** The ResourceLocation containing the Enchantment GUI texture location */
+    public EnchantmentScreenRe(EnchantmentContainerRe container, PlayerInventory playerInventory, ITextComponent textComponent) {super(container, playerInventory, textComponent); }
+
+    // 资源与模型导入
     private static final ResourceLocation ENCHANTMENT_TABLE_GUI_TEXTURE = new ResourceLocation("textures/gui/container/enchanting_table.png");
-    /** The ResourceLocation containing the texture for the Book rendered above the enchantment table */
     private static final ResourceLocation ENCHANTMENT_TABLE_BOOK_TEXTURE = new ResourceLocation("textures/entity/enchanting_table_book.png");
-    /** The ModelBook instance used for rendering the book on the Enchantment table */
     private static final BookModel MODEL_BOOK = new BookModel();
-    /** A Random instance for use with the enchantment gui */
-    private final Random random = new Random();
-    public int ticks;
-    public float flip;
-    public float oFlip;
-    public float flipT;
-    public float flipA;
-    public float open;
-    public float oOpen;
-    private ItemStack last = ItemStack.EMPTY;
 
-    public EnchantmentScreenRe(EnchantmentContainerRe container, PlayerInventory playerInventory, ITextComponent textComponent) {
-        super(container, playerInventory, textComponent);
+    // 鼠标点击事件
+    public boolean mouseClicked(double mouseX, double mouseY, int button) {
+        int guiX = (this.width - this.xSize) / 2;
+        int guiY = (this.height - this.ySize) / 2;
+        for(int id = 0; id < 3; ++id) {
+            // 检测是否点击的附魔选项按钮
+            double x = mouseX - (double)(guiX + 60);
+            double y = mouseY - (double)(guiY + 14 + 19 * id);
+            if (x >= 0.0D && y >= 0.0D && x < 108.0D && y < 19.0D && this.container.enchantItem(this.minecraft.player, id)) {
+                this.minecraft.playerController.sendEnchantPacket((this.container).windowId, id);
+                return true;
+            }
+        }
+        return super.mouseClicked(mouseX, mouseY, button);
     }
 
+    // GUI 上书本的打开关闭动画,和各种控制书本的杂七杂八的参数
+    private final Random bookRandom = new Random();
+    public float flip; public float oFlip;
+    public float flipT; public float flipA;
+    public float open; public float oOpen;
+    private ItemStack lastItemStack = ItemStack.EMPTY;
     public void tick() {
         super.tick();
         this.tickBook();
     }
-
-    public boolean mouseClicked(double mouseX, double mouseY, int button) {
-        int i = (this.width - this.xSize) / 2;
-        int j = (this.height - this.ySize) / 2;
-
-        for(int k = 0; k < 3; ++k) {
-            double d0 = mouseX - (double)(i + 60);
-            double d1 = mouseY - (double)(j + 14 + 19 * k);
-            if (d0 >= 0.0D && d1 >= 0.0D && d0 < 108.0D && d1 < 19.0D && this.container.enchantItem(this.minecraft.player, k)) {
-                this.minecraft.playerController.sendEnchantPacket((this.container).windowId, k);
-                return true;
+    public void tickBook() {
+        ItemStack itemstack = this.container.getSlot(0).getStack();
+        if (!ItemStack.areItemStacksEqual(itemstack, this.lastItemStack)) {
+            this.lastItemStack = itemstack;
+            do {
+                this.flipT += (float)(this.bookRandom.nextInt(4) - this.bookRandom.nextInt(4));
+            } while(this.flip <= this.flipT + 1.0F && this.flip >= this.flipT - 1.0F);
+        }
+        this.oFlip = this.flip;
+        this.oOpen = this.open;
+        boolean shouldBookOpen = false;
+        for(int i = 0; i < 3; ++i) {
+            if ((this.container).enchantLevels[i] != 0) {
+                shouldBookOpen = true;
             }
         }
+        if (shouldBookOpen) {
+            this.open += 0.2F;
+        } else {
+            this.open -= 0.2F;
+        }
+        this.open = MathHelper.clamp(this.open, 0.0F, 1.0F);
+        float f1 = (this.flipT - this.flip) * 0.4F;
+        float f = 0.2F;
+        f1 = MathHelper.clamp(f1, -0.2F, 0.2F);
+        this.flipA += (f1 - this.flipA) * 0.9F;
+        this.flip += this.flipA;
+    }
 
-        return super.mouseClicked(mouseX, mouseY, button);
+    // 渲染 ToolTip
+    public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
+        partialTicks = this.minecraft.getRenderPartialTicks();
+        this.renderBackground(matrixStack);
+        super.render(matrixStack, mouseX, mouseY, partialTicks);
+        this.renderHoveredTooltip(matrixStack, mouseX, mouseY);
+        // 渲染 ToolTip 文本
+        for(int id = 0; id < 3; ++id) {
+            int enchantLevels = (this.container).enchantLevels[id];
+            Enchantment enchantment = Enchantment.getEnchantmentByID((this.container).guiEnchantId[id]);
+            int guiEnchantLevel = (this.container).guiEnchantLevel[id];
+            // 判断鼠标是否在按钮上
+            if (!this.isPointInRegion(60, 14 + 19 * id, 108, 17, mouseX, mouseY) && enchantLevels > 0) continue;
+            List<ITextComponent> list = Lists.newArrayList();
+            if(enchantment == null) {
+                // 没有可用附魔,显示 limitedEnchantability 信息
+                list.add((new TranslationTextComponent("container.enchant.clue", "")).mergeStyle(TextFormatting.WHITE));
+                list.add(new StringTextComponent(""));
+                list.add(new TranslationTextComponent("forge.container.enchant.limitedEnchantability").mergeStyle(TextFormatting.RED));
+            } else if (!this.minecraft.player.abilities.isCreativeMode) {
+                // 显示第一条附魔
+                list.add((new TranslationTextComponent("container.enchant.clue", enchantment.getDisplayName(guiEnchantLevel))).mergeStyle(TextFormatting.WHITE));
+                // 显示附魔消耗(等级、青金石)
+                list.add(StringTextComponent.EMPTY);
+                if (this.minecraft.player.experienceLevel < enchantLevels) {
+                    list.add((new TranslationTextComponent("container.enchant.level.requirement", (this.container).enchantLevels[id])).mergeStyle(TextFormatting.RED));
+                } else {
+                    IFormattableTextComponent iformattabletextcomponent;
+                    int cost = id + 1;
+                    if (cost == 1) {
+                        iformattabletextcomponent = new TranslationTextComponent("container.enchant.lapis.one");
+                    } else {
+                        iformattabletextcomponent = new TranslationTextComponent("container.enchant.lapis.many", cost);
+                    }
+                    list.add(iformattabletextcomponent.mergeStyle(this.container.getLapisAmount() >= cost ? TextFormatting.GRAY : TextFormatting.RED));
+                    IFormattableTextComponent iformattabletextcomponent1;
+                    if (cost == 1) {
+                        iformattabletextcomponent1 = new TranslationTextComponent("container.enchant.level.one");
+                    } else {
+                        iformattabletextcomponent1 = new TranslationTextComponent("container.enchant.level.many", cost);
+                    }
+                    list.add(iformattabletextcomponent1.mergeStyle(TextFormatting.GRAY));
+                }
+            }
+            // 提交 ToolTip 渲染
+            this.func_243308_b(matrixStack, list, mouseX, mouseY);
+            break;
+        }
     }
 
-    protected void drawGuiContainerBackgroundLayer(MatrixStack matrixStack, float partialTicks, int x, int y) {
+    // 渲染 GUI 组件
+    protected void drawGuiContainerBackgroundLayer(MatrixStack matrixStack, float partialTicks, int mouseX, int mouseY) {
+        // 大概是渲染 GUI 上那本书,没注释看着太屎坑了
         RenderHelper.setupGuiFlatDiffuseLighting();
         RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
         this.minecraft.getTextureManager().bindTexture(ENCHANTMENT_TABLE_GUI_TEXTURE);
-        int i = (this.width - this.xSize) / 2;
-        int j = (this.height - this.ySize) / 2;
-        this.blit(matrixStack, i, j, 0, 0, this.xSize, this.ySize);
+        int guiX = (this.width - this.xSize) / 2;
+        int guiY = (this.height - this.ySize) / 2;
+        this.blit(matrixStack, guiX, guiY, 0, 0, this.xSize, this.ySize);
         RenderSystem.matrixMode(5889);
         RenderSystem.pushMatrix();
         RenderSystem.loadIdentity();
@@ -94,35 +165,21 @@ public class EnchantmentScreenRe extends ContainerScreen<EnchantmentContainerRe>
         matrixstack$entry.getMatrix().setIdentity();
         matrixstack$entry.getNormal().setIdentity();
         matrixStack.translate(0.0D, (double)3.3F, 1984.0D);
-        float f = 5.0F;
         matrixStack.scale(5.0F, 5.0F, 5.0F);
         matrixStack.rotate(Vector3f.ZP.rotationDegrees(180.0F));
         matrixStack.rotate(Vector3f.XP.rotationDegrees(20.0F));
         float f1 = MathHelper.lerp(partialTicks, this.oOpen, this.open);
         matrixStack.translate((double)((1.0F - f1) * 0.2F), (double)((1.0F - f1) * 0.1F), (double)((1.0F - f1) * 0.25F));
-        float f2 = -(1.0F - f1) * 90.0F - 90.0F;
-        matrixStack.rotate(Vector3f.YP.rotationDegrees(f2));
+        matrixStack.rotate(Vector3f.YP.rotationDegrees(-(1.0F - f1) * 90.0F - 90.0F));
         matrixStack.rotate(Vector3f.XP.rotationDegrees(180.0F));
         float f3 = MathHelper.lerp(partialTicks, this.oFlip, this.flip) + 0.25F;
         float f4 = MathHelper.lerp(partialTicks, this.oFlip, this.flip) + 0.75F;
         f3 = (f3 - (float)MathHelper.fastFloor((double)f3)) * 1.6F - 0.3F;
         f4 = (f4 - (float)MathHelper.fastFloor((double)f4)) * 1.6F - 0.3F;
-        if (f3 < 0.0F) {
-            f3 = 0.0F;
-        }
-
-        if (f4 < 0.0F) {
-            f4 = 0.0F;
-        }
-
-        if (f3 > 1.0F) {
-            f3 = 1.0F;
-        }
-
-        if (f4 > 1.0F) {
-            f4 = 1.0F;
-        }
-
+        if (f3 < 0.0F) f3 = 0.0F;
+        if (f4 < 0.0F) f4 = 0.0F;
+        if (f3 > 1.0F) f3 = 1.0F;
+        if (f4 > 1.0F) f4 = 1.0F;
         RenderSystem.enableRescaleNormal();
         MODEL_BOOK.setBookState(0.0F, f3, f4, f1);
         IRenderTypeBuffer.Impl irendertypebuffer$impl = IRenderTypeBuffer.getImpl(Tessellator.getInstance().getBuffer());
@@ -134,133 +191,54 @@ public class EnchantmentScreenRe extends ContainerScreen<EnchantmentContainerRe>
         RenderSystem.viewport(0, 0, this.minecraft.getMainWindow().getFramebufferWidth(), this.minecraft.getMainWindow().getFramebufferHeight());
         RenderSystem.popMatrix();
         RenderSystem.matrixMode(5888);
+        // 渲染右边三个按钮
         RenderHelper.setupGui3DDiffuseLighting();
         RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
-        EnchantmentNameParts.getInstance().reseedRandomGenerator((long)this.container.func_217005_f());
-        int l = this.container.getLapisAmount();
-
-        for(int i1 = 0; i1 < 3; ++i1) {
-            int j1 = i + 60;
-            int k1 = j1 + 20;
+        EnchantmentNameParts.getInstance().reseedRandomGenerator((long)this.container.getXpSeed());
+        int lapisAmount = this.container.getLapisAmount();
+        for(int id = 0; id < 3; id++) {
+            int buttonX = guiX + 60;
+            int textX = buttonX + 20;
             this.setBlitOffset(0);
             this.minecraft.getTextureManager().bindTexture(ENCHANTMENT_TABLE_GUI_TEXTURE);
-            int l1 = (this.container).enchantLevels[i1];
+            int enchantLevel = (this.container).enchantLevels[id];
             RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F);
-            if (l1 == 0) {
-                this.blit(matrixStack, j1, j + 14 + 19 * i1, 0, 185, 108, 19);
+            if (enchantLevel == 0) {
+                // 渲染 “不可用” 空白按钮背景
+                this.blit(matrixStack, buttonX, guiY + 14 + 19 * id, 0, 185, 108, 19);
             } else {
-                String s = "" + l1;
-                int i2 = 86 - this.font.getStringWidth(s);
-                ITextProperties itextproperties = EnchantmentNameParts.getInstance().getGalacticEnchantmentName(this.font, i2);
-                int j2 = 6839882;
-                if (((l < i1 + 1 || this.minecraft.player.experienceLevel < l1) && !this.minecraft.player.abilities.isCreativeMode) || this.container.enchantClue[i1] == -1) { // Forge: render buttons as disabled when enchantable but enchantability not met on lower levels
-                    this.blit(matrixStack, j1, j + 14 + 19 * i1, 0, 185, 108, 19);
-                    this.blit(matrixStack, j1 + 1, j + 15 + 19 * i1, 16 * i1, 239, 16, 16);
-                    this.font.func_238418_a_(itextproperties, k1, j + 16 + 19 * i1, i2, (j2 & 16711422) >> 1);
-                    j2 = 4226832;
+                String enchantLevelString = String.valueOf(enchantLevel);
+                int enchantLevelStringWidth = 86 - this.font.getStringWidth(enchantLevelString);
+                ITextProperties itextproperties = EnchantmentNameParts.getInstance().getGalacticEnchantmentName(this.font, enchantLevelStringWidth);
+                int stringColor = 6839882;
+                if (((lapisAmount < id + 1 || this.minecraft.player.experienceLevel < enchantLevel) && !this.minecraft.player.abilities.isCreativeMode) || this.container.guiEnchantId[id] == -1) {
+                    // 渲染 “买不起” 按钮背景
+                    this.blit(matrixStack, buttonX, guiY + 14 + 19 * id, 0, 185, 108, 19);
+                    // 渲染附魔等级文本与图片
+                    this.blit(matrixStack, buttonX + 1, guiY + 15 + 19 * id, 16 * id, 239, 16, 16);
+                    this.font.func_238418_a_(itextproperties, textX, guiY + 16 + 19 * id, enchantLevelStringWidth, (stringColor & 16711422) >> 1);
+                    stringColor = 4226832;
                 } else {
-                    int k2 = x - (i + 60);
-                    int l2 = y - (j + 14 + 19 * i1);
-                    if (k2 >= 0 && l2 >= 0 && k2 < 108 && l2 < 19) {
-                        this.blit(matrixStack, j1, j + 14 + 19 * i1, 0, 204, 108, 19);
-                        j2 = 16777088;
+                    // 渲染按钮背景
+                    int k2 = mouseX - (guiX + 60);
+                    int l2 = mouseY - (guiY + 14 + 19 * id);
+                    if (k2 >= 0 && l2 >= 0 && k2 < 108 && l2 < 19) { // 鼠标悬浮检测
+                        // 渲染鼠标指向的按钮背景
+                        this.blit(matrixStack, buttonX, guiY + 14 + 19 * id, 0, 204, 108, 19);
+                        stringColor = 16777088;
                     } else {
-                        this.blit(matrixStack, j1, j + 14 + 19 * i1, 0, 166, 108, 19);
+                        // 渲染普通按钮背景
+                        this.blit(matrixStack, buttonX, guiY + 14 + 19 * id, 0, 166, 108, 19);
                     }
-
-                    this.blit(matrixStack, j1 + 1, j + 15 + 19 * i1, 16 * i1, 223, 16, 16);
-                    this.font.func_238418_a_(itextproperties, k1, j + 16 + 19 * i1, i2, j2);
-                    j2 = 8453920;
+                    // 渲染附魔等级文本与图片
+                    this.blit(matrixStack, buttonX + 1, guiY + 15 + 19 * id, 16 * id, 223, 16, 16);
+                    this.font.func_238418_a_(itextproperties, textX, guiY + 16 + 19 * id, enchantLevelStringWidth, stringColor);
+                    stringColor = 8453920;
                 }
-
-                this.font.drawStringWithShadow(matrixStack, s, (float)(k1 + 86 - this.font.getStringWidth(s)), (float)(j + 16 + 19 * i1 + 7), j2);
+                this.font.drawStringWithShadow(matrixStack, enchantLevelString, (float)(textX + 86 - this.font.getStringWidth(enchantLevelString)), (float)(guiY + 16 + 19 * id + 7), stringColor);
             }
         }
 
     }
 
-    public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) {
-        partialTicks = this.minecraft.getRenderPartialTicks();
-        this.renderBackground(matrixStack);
-        super.render(matrixStack, mouseX, mouseY, partialTicks);
-        this.renderHoveredTooltip(matrixStack, mouseX, mouseY);
-        boolean flag = this.minecraft.player.abilities.isCreativeMode;
-        int i = this.container.getLapisAmount();
-
-        for(int j = 0; j < 3; ++j) {
-            int k = (this.container).enchantLevels[j];
-            Enchantment enchantment = Enchantment.getEnchantmentByID((this.container).enchantClue[j]);
-            int l = (this.container).worldClue[j];
-            int i1 = j + 1;
-            if (this.isPointInRegion(60, 14 + 19 * j, 108, 17, (double)mouseX, (double)mouseY) && k > 0) {
-                List<ITextComponent> list = Lists.newArrayList();
-                list.add((new TranslationTextComponent("container.enchant.clue", enchantment == null ? "" : enchantment.getDisplayName(l))).mergeStyle(TextFormatting.WHITE));
-                if(enchantment == null) {
-                    list.add(new StringTextComponent(""));
-                    list.add(new TranslationTextComponent("forge.container.enchant.limitedEnchantability").mergeStyle(TextFormatting.RED));
-                } else if (!flag) {
-                    list.add(StringTextComponent.EMPTY);
-                    if (this.minecraft.player.experienceLevel < k) {
-                        list.add((new TranslationTextComponent("container.enchant.level.requirement", (this.container).enchantLevels[j])).mergeStyle(TextFormatting.RED));
-                    } else {
-                        IFormattableTextComponent iformattabletextcomponent;
-                        if (i1 == 1) {
-                            iformattabletextcomponent = new TranslationTextComponent("container.enchant.lapis.one");
-                        } else {
-                            iformattabletextcomponent = new TranslationTextComponent("container.enchant.lapis.many", i1);
-                        }
-
-                        list.add(iformattabletextcomponent.mergeStyle(i >= i1 ? TextFormatting.GRAY : TextFormatting.RED));
-                        IFormattableTextComponent iformattabletextcomponent1;
-                        if (i1 == 1) {
-                            iformattabletextcomponent1 = new TranslationTextComponent("container.enchant.level.one");
-                        } else {
-                            iformattabletextcomponent1 = new TranslationTextComponent("container.enchant.level.many", i1);
-                        }
-
-                        list.add(iformattabletextcomponent1.mergeStyle(TextFormatting.GRAY));
-                    }
-                }
-
-                this.func_243308_b(matrixStack, list, mouseX, mouseY);
-                break;
-            }
-        }
-
-    }
-
-    public void tickBook() {
-        ItemStack itemstack = this.container.getSlot(0).getStack();
-        if (!ItemStack.areItemStacksEqual(itemstack, this.last)) {
-            this.last = itemstack;
-
-            do {
-                this.flipT += (float)(this.random.nextInt(4) - this.random.nextInt(4));
-            } while(this.flip <= this.flipT + 1.0F && this.flip >= this.flipT - 1.0F);
-        }
-
-        ++this.ticks;
-        this.oFlip = this.flip;
-        this.oOpen = this.open;
-        boolean flag = false;
-
-        for(int i = 0; i < 3; ++i) {
-            if ((this.container).enchantLevels[i] != 0) {
-                flag = true;
-            }
-        }
-
-        if (flag) {
-            this.open += 0.2F;
-        } else {
-            this.open -= 0.2F;
-        }
-
-        this.open = MathHelper.clamp(this.open, 0.0F, 1.0F);
-        float f1 = (this.flipT - this.flip) * 0.4F;
-        float f = 0.2F;
-        f1 = MathHelper.clamp(f1, -0.2F, 0.2F);
-        this.flipA += (f1 - this.flipA) * 0.9F;
-        this.flip += this.flipA;
-    }
 }