|
|
@@ -12,7 +12,6 @@ import net.minecraft.inventory.IInventory;
|
|
|
import net.minecraft.inventory.Inventory;
|
|
|
import net.minecraft.inventory.container.Container;
|
|
|
import net.minecraft.inventory.container.Slot;
|
|
|
-import net.minecraft.item.EnchantedBookItem;
|
|
|
import net.minecraft.item.ItemStack;
|
|
|
import net.minecraft.item.Items;
|
|
|
import net.minecraft.tags.BlockTags;
|
|
|
@@ -71,74 +70,30 @@ public class AnvilContainerRe extends Container {
|
|
|
// 消耗的等级
|
|
|
public final IntReferenceHolder totalCost = IntReferenceHolder.single();
|
|
|
|
|
|
- // 在玩家从输出格拿走物品时触发:铁砧损坏、减少经验等
|
|
|
- private ItemStack onTakeOutput(PlayerEntity player, ItemStack itemStack) {
|
|
|
- if (!player.abilities.isCreativeMode) {
|
|
|
- player.addExperienceLevel(-this.totalCost.get());
|
|
|
- }
|
|
|
-
|
|
|
- float breakChance = net.minecraftforge.common.ForgeHooks.onAnvilRepair(player, itemStack, AnvilContainerRe.this.inputInventory.getStackInSlot(0), AnvilContainerRe.this.inputInventory.getStackInSlot(1));
|
|
|
-
|
|
|
- this.inputInventory.setInventorySlotContents(0, ItemStack.EMPTY);
|
|
|
- if (this.materialCost > 0) {
|
|
|
- ItemStack itemstack = this.inputInventory.getStackInSlot(1);
|
|
|
- if (!itemstack.isEmpty() && itemstack.getCount() > this.materialCost) {
|
|
|
- itemstack.shrink(this.materialCost);
|
|
|
- this.inputInventory.setInventorySlotContents(1, itemstack);
|
|
|
- } else {
|
|
|
- this.inputInventory.setInventorySlotContents(1, ItemStack.EMPTY);
|
|
|
- }
|
|
|
- } else {
|
|
|
- this.inputInventory.setInventorySlotContents(1, ItemStack.EMPTY);
|
|
|
- }
|
|
|
-
|
|
|
- this.totalCost.set(0);
|
|
|
- this.worldPosCallable.consume((p_234633_1_, p_234633_2_) -> {
|
|
|
- BlockState blockstate = p_234633_1_.getBlockState(p_234633_2_);
|
|
|
- if (!player.abilities.isCreativeMode && blockstate.isIn(BlockTags.ANVIL) && player.getRNG().nextFloat() < breakChance) {
|
|
|
- BlockState blockstate1 = AnvilBlock.damage(blockstate);
|
|
|
- if (blockstate1 == null) {
|
|
|
- p_234633_1_.removeBlock(p_234633_2_, false);
|
|
|
- p_234633_1_.playEvent(1029, p_234633_2_, 0);
|
|
|
- } else {
|
|
|
- p_234633_1_.setBlockState(p_234633_2_, blockstate1, 2);
|
|
|
- p_234633_1_.playEvent(1030, p_234633_2_, 0);
|
|
|
- }
|
|
|
- } else {
|
|
|
- p_234633_1_.playEvent(1030, p_234633_2_, 0);
|
|
|
- }
|
|
|
-
|
|
|
- });
|
|
|
- return itemStack;
|
|
|
- }
|
|
|
-
|
|
|
// 当输入物品改变时更新输出
|
|
|
public void updateRepairOutput() {
|
|
|
|
|
|
- ItemStack itemstack = this.inputInventory.getStackInSlot(0);
|
|
|
- if (itemstack.isEmpty()) {
|
|
|
+ // 获取输入物品,并检查不为空
|
|
|
+ ItemStack inputItem = this.inputInventory.getStackInSlot(0);
|
|
|
+ if (inputItem.isEmpty()) {
|
|
|
this.outputInventory.setInventorySlotContents(0, ItemStack.EMPTY);
|
|
|
this.totalCost.set(0);
|
|
|
return;
|
|
|
}
|
|
|
+ ItemStack middleItem = this.inputInventory.getStackInSlot(1);
|
|
|
+ ItemStack outputItem = inputItem.copy();
|
|
|
|
|
|
this.totalCost.set(1);
|
|
|
- int cost1 = 0;
|
|
|
- int cost2 = 0;
|
|
|
- int k = 0;
|
|
|
- ItemStack itemstack1 = itemstack.copy();
|
|
|
- ItemStack itemstack2 = this.inputInventory.getStackInSlot(1);
|
|
|
- Map<Enchantment, Integer> map = EnchantmentHelper.getEnchantments(itemstack1);
|
|
|
- cost2 = cost2 + itemstack.getRepairCost() + (itemstack2.isEmpty() ? 0 : itemstack2.getRepairCost());
|
|
|
+ int recipeCost = 0;
|
|
|
+ int baseCost = inputItem.getRepairCost() + (middleItem.isEmpty() ? 0 : middleItem.getRepairCost());
|
|
|
this.materialCost = 0;
|
|
|
- boolean flag = false;
|
|
|
+ Map<Enchantment, Integer> outputEnchantments = EnchantmentHelper.getEnchantments(outputItem);
|
|
|
|
|
|
- if (!itemstack2.isEmpty()) {
|
|
|
- if (!onAnvilChange(this, itemstack, itemstack2, outputInventory, itemstack.getDisplayName().getString(), cost2))
|
|
|
+ if (!middleItem.isEmpty()) {
|
|
|
+ if (!onAnvilChange(this, inputItem, middleItem, outputInventory, inputItem.getDisplayName().getString(), baseCost))
|
|
|
return;
|
|
|
- flag = itemstack2.getItem() == Items.ENCHANTED_BOOK && !EnchantedBookItem.getEnchantments(itemstack2).isEmpty();
|
|
|
- if (itemstack1.isDamageable() && itemstack1.getItem().getIsRepairable(itemstack, itemstack2)) {
|
|
|
- int l2 = Math.min(itemstack1.getDamage(), itemstack1.getMaxDamage() / 4);
|
|
|
+ if (outputItem.isDamageable() && outputItem.getItem().getIsRepairable(inputItem, middleItem)) {
|
|
|
+ int l2 = Math.min(outputItem.getDamage(), outputItem.getMaxDamage() / 4);
|
|
|
if (l2 <= 0) {
|
|
|
this.outputInventory.setInventorySlotContents(0, ItemStack.EMPTY);
|
|
|
this.totalCost.set(0);
|
|
|
@@ -146,55 +101,55 @@ public class AnvilContainerRe extends Container {
|
|
|
}
|
|
|
|
|
|
int i3;
|
|
|
- for (i3 = 0; l2 > 0 && i3 < itemstack2.getCount(); ++i3) {
|
|
|
- int j3 = itemstack1.getDamage() - l2;
|
|
|
- itemstack1.setDamage(j3);
|
|
|
- ++cost1;
|
|
|
- l2 = Math.min(itemstack1.getDamage(), itemstack1.getMaxDamage() / 4);
|
|
|
+ for (i3 = 0; l2 > 0 && i3 < middleItem.getCount(); ++i3) {
|
|
|
+ int j3 = outputItem.getDamage() - l2;
|
|
|
+ outputItem.setDamage(j3);
|
|
|
+ ++recipeCost;
|
|
|
+ l2 = Math.min(outputItem.getDamage(), outputItem.getMaxDamage() / 4);
|
|
|
}
|
|
|
|
|
|
this.materialCost = i3;
|
|
|
} else {
|
|
|
- if (!flag && (itemstack1.getItem() != itemstack2.getItem() || !itemstack1.isDamageable())) {
|
|
|
+ if (outputItem.getItem() != middleItem.getItem() || !outputItem.isDamageable()) {
|
|
|
this.outputInventory.setInventorySlotContents(0, ItemStack.EMPTY);
|
|
|
this.totalCost.set(0);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- if (itemstack1.isDamageable() && !flag) {
|
|
|
- int l = itemstack.getMaxDamage() - itemstack.getDamage();
|
|
|
- int i1 = itemstack2.getMaxDamage() - itemstack2.getDamage();
|
|
|
- int j1 = i1 + itemstack1.getMaxDamage() * 12 / 100;
|
|
|
+ if (outputItem.isDamageable()) {
|
|
|
+ int l = inputItem.getMaxDamage() - inputItem.getDamage();
|
|
|
+ int i1 = middleItem.getMaxDamage() - middleItem.getDamage();
|
|
|
+ int j1 = i1 + outputItem.getMaxDamage() * 12 / 100;
|
|
|
int k1 = l + j1;
|
|
|
- int l1 = itemstack1.getMaxDamage() - k1;
|
|
|
+ int l1 = outputItem.getMaxDamage() - k1;
|
|
|
if (l1 < 0) {
|
|
|
l1 = 0;
|
|
|
}
|
|
|
|
|
|
- if (l1 < itemstack1.getDamage()) {
|
|
|
- itemstack1.setDamage(l1);
|
|
|
- cost1 += 2;
|
|
|
+ if (l1 < outputItem.getDamage()) {
|
|
|
+ outputItem.setDamage(l1);
|
|
|
+ recipeCost += 2;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- Map<Enchantment, Integer> map1 = EnchantmentHelper.getEnchantments(itemstack2);
|
|
|
+ Map<Enchantment, Integer> map1 = EnchantmentHelper.getEnchantments(middleItem);
|
|
|
boolean flag2 = false;
|
|
|
boolean flag3 = false;
|
|
|
|
|
|
for (Enchantment enchantment1 : map1.keySet()) {
|
|
|
if (enchantment1 != null) {
|
|
|
- int i2 = map.getOrDefault(enchantment1, 0);
|
|
|
+ int i2 = outputEnchantments.getOrDefault(enchantment1, 0);
|
|
|
int j2 = map1.get(enchantment1);
|
|
|
j2 = i2 == j2 ? j2 + 1 : Math.max(j2, i2);
|
|
|
- boolean flag1 = enchantment1.canApply(itemstack);
|
|
|
- if (this.player.abilities.isCreativeMode || itemstack.getItem() == Items.ENCHANTED_BOOK) {
|
|
|
+ boolean flag1 = enchantment1.canApply(inputItem);
|
|
|
+ if (this.player.abilities.isCreativeMode || inputItem.getItem() == Items.ENCHANTED_BOOK) {
|
|
|
flag1 = true;
|
|
|
}
|
|
|
|
|
|
- for (Enchantment enchantment : map.keySet()) {
|
|
|
+ for (Enchantment enchantment : outputEnchantments.keySet()) {
|
|
|
if (enchantment != enchantment1 && !enchantment1.isCompatibleWith(enchantment)) {
|
|
|
flag1 = false;
|
|
|
- ++cost1;
|
|
|
+ ++recipeCost;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -206,7 +161,7 @@ public class AnvilContainerRe extends Container {
|
|
|
j2 = enchantment1.getMaxLevel();
|
|
|
}
|
|
|
|
|
|
- map.put(enchantment1, j2);
|
|
|
+ outputEnchantments.put(enchantment1, j2);
|
|
|
int k3 = 0;
|
|
|
switch (enchantment1.getRarity()) {
|
|
|
case COMMON:
|
|
|
@@ -222,13 +177,9 @@ public class AnvilContainerRe extends Container {
|
|
|
k3 = 8;
|
|
|
}
|
|
|
|
|
|
- if (flag) {
|
|
|
- k3 = Math.max(1, k3 / 2);
|
|
|
- }
|
|
|
-
|
|
|
- cost1 += k3 * j2;
|
|
|
- if (itemstack.getCount() > 1) {
|
|
|
- cost1 = 100;
|
|
|
+ recipeCost += k3 * j2;
|
|
|
+ if (inputItem.getCount() > 1) {
|
|
|
+ recipeCost = 100;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -242,32 +193,23 @@ public class AnvilContainerRe extends Container {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (flag && !itemstack1.isBookEnchantable(itemstack2)) itemstack1 = ItemStack.EMPTY;
|
|
|
+ this.totalCost.set(baseCost + recipeCost);
|
|
|
|
|
|
- this.totalCost.set(cost2 + cost1);
|
|
|
- if (cost1 <= 0) {
|
|
|
- itemstack1 = ItemStack.EMPTY;
|
|
|
- }
|
|
|
+ if (recipeCost <= 0 || this.totalCost.get() >= 100 && !this.player.abilities.isCreativeMode)
|
|
|
+ outputItem = ItemStack.EMPTY;
|
|
|
|
|
|
- if (this.totalCost.get() >= 100 && !this.player.abilities.isCreativeMode) {
|
|
|
- itemstack1 = ItemStack.EMPTY;
|
|
|
- }
|
|
|
-
|
|
|
- if (!itemstack1.isEmpty()) {
|
|
|
- int k2 = itemstack1.getRepairCost();
|
|
|
- if (!itemstack2.isEmpty() && k2 < itemstack2.getRepairCost()) {
|
|
|
- k2 = itemstack2.getRepairCost();
|
|
|
+ if (!outputItem.isEmpty()) {
|
|
|
+ int newRepairCost = outputItem.getRepairCost();
|
|
|
+ if (!middleItem.isEmpty() && newRepairCost < middleItem.getRepairCost()) {
|
|
|
+ newRepairCost = middleItem.getRepairCost();
|
|
|
}
|
|
|
-
|
|
|
- k2 = k2 * 2 + 1; // new repair cost
|
|
|
-
|
|
|
- itemstack1.setRepairCost(k2);
|
|
|
- EnchantmentHelper.setEnchantments(map, itemstack1);
|
|
|
+ newRepairCost = newRepairCost * 2 + 1; // 每次修复都翻倍并 +1
|
|
|
+ outputItem.setRepairCost(newRepairCost);
|
|
|
+ EnchantmentHelper.setEnchantments(outputEnchantments, outputItem);
|
|
|
}
|
|
|
|
|
|
- this.outputInventory.setInventorySlotContents(0, itemstack1);
|
|
|
+ this.outputInventory.setInventorySlotContents(0, outputItem);
|
|
|
this.detectAndSendChanges();
|
|
|
-
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -293,6 +235,48 @@ public class AnvilContainerRe extends Container {
|
|
|
this.trackInt(this.totalCost);
|
|
|
}
|
|
|
|
|
|
+ // 在玩家从输出格拿走物品时触发:扣除等级、损坏铁砧、清空输入
|
|
|
+ private ItemStack onTakeOutput(PlayerEntity player, ItemStack itemStack) {
|
|
|
+
|
|
|
+ // 扣除非创造模式玩家的等级
|
|
|
+ if (!player.abilities.isCreativeMode) player.addExperienceLevel(-this.totalCost.get());
|
|
|
+ this.totalCost.set(0);
|
|
|
+
|
|
|
+ // 触发铁砧的随机损坏
|
|
|
+ float breakChance = net.minecraftforge.common.ForgeHooks.onAnvilRepair(player, itemStack, AnvilContainerRe.this.inputInventory.getStackInSlot(0), AnvilContainerRe.this.inputInventory.getStackInSlot(1));
|
|
|
+ this.worldPosCallable.consume((world, blockPos) -> {
|
|
|
+ BlockState blockstate = world.getBlockState(blockPos);
|
|
|
+ if (!player.abilities.isCreativeMode && blockstate.isIn(BlockTags.ANVIL) && player.getRNG().nextFloat() < breakChance) {
|
|
|
+ BlockState blockstate1 = AnvilBlock.damage(blockstate);
|
|
|
+ if (blockstate1 == null) {
|
|
|
+ world.removeBlock(blockPos, false);
|
|
|
+ world.playEvent(1029, blockPos, 0);
|
|
|
+ } else {
|
|
|
+ world.setBlockState(blockPos, blockstate1, 2);
|
|
|
+ world.playEvent(1030, blockPos, 0);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ world.playEvent(1030, blockPos, 0);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 清空输入
|
|
|
+ this.inputInventory.setInventorySlotContents(0, ItemStack.EMPTY);
|
|
|
+ if (this.materialCost > 0) {
|
|
|
+ ItemStack itemstack = this.inputInventory.getStackInSlot(1);
|
|
|
+ if (!itemstack.isEmpty() && itemstack.getCount() > this.materialCost) {
|
|
|
+ itemstack.shrink(this.materialCost);
|
|
|
+ this.inputInventory.setInventorySlotContents(1, itemstack);
|
|
|
+ } else {
|
|
|
+ this.inputInventory.setInventorySlotContents(1, ItemStack.EMPTY);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ this.inputInventory.setInventorySlotContents(1, ItemStack.EMPTY);
|
|
|
+ }
|
|
|
+
|
|
|
+ return itemStack;
|
|
|
+ }
|
|
|
+
|
|
|
// 接口: 当输入物品改变时触发更新
|
|
|
public void onCraftMatrixChanged(IInventory inventoryIn) {
|
|
|
super.onCraftMatrixChanged(inventoryIn);
|