From 68115e4994b6400d3b067e6f898747b57f18929a Mon Sep 17 00:00:00 2001 From: 17146 <1714673995@qq.com> Date: Tue, 13 Aug 2024 03:34:59 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=87=8D=E9=93=B8=E5=8F=B0?= =?UTF-8?q?=E7=9A=84=E9=83=A8=E5=88=86=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../block/menu/ReforgingTableMenu.java | 161 ++++++++++++++++-- .../superbwarfare/event/TempEventHandler.java | 10 ++ .../superbwarfare/item/gun/GunItem.java | 4 +- .../superbwarfare/perk/PerkHelper.java | 28 +++ 4 files changed, 189 insertions(+), 14 deletions(-) diff --git a/src/main/java/net/mcreator/superbwarfare/block/menu/ReforgingTableMenu.java b/src/main/java/net/mcreator/superbwarfare/block/menu/ReforgingTableMenu.java index 1904ed0ab..a064bad3c 100644 --- a/src/main/java/net/mcreator/superbwarfare/block/menu/ReforgingTableMenu.java +++ b/src/main/java/net/mcreator/superbwarfare/block/menu/ReforgingTableMenu.java @@ -79,15 +79,21 @@ public class ReforgingTableMenu extends AbstractContainerMenu { if (slot.hasItem()) { ItemStack stack = slot.getItem(); itemstack = stack.copy(); - if (pIndex == RESULT_SLOT) { - if (!this.moveItemStackTo(stack, RESULT_SLOT, RESULT_SLOT + 36, false)) { + + if (pIndex == INPUT_SLOT) { + onTakeGun(stack); + if (!this.moveItemStackTo(stack, RESULT_SLOT + 1, RESULT_SLOT + 37, false)) { return ItemStack.EMPTY; } } else if (pIndex >= AMMO_PERK_SLOT && pIndex <= DAMAGE_PERK_SLOT) { if (!this.moveItemStackTo(stack, RESULT_SLOT + 1, RESULT_SLOT + 37, false)) { return ItemStack.EMPTY; } - } else if (pIndex != INPUT_SLOT) { + } else if (pIndex == RESULT_SLOT) { + if (!this.moveItemStackTo(stack, RESULT_SLOT, RESULT_SLOT + 36, false)) { + return ItemStack.EMPTY; + } + } else { if (stack.is(ModTags.Items.GUN)) { if (!this.moveItemStackTo(stack, INPUT_SLOT, INPUT_SLOT + 1, false)) { return ItemStack.EMPTY; @@ -108,8 +114,6 @@ public class ReforgingTableMenu extends AbstractContainerMenu { } } } - } else if (!this.moveItemStackTo(stack, RESULT_SLOT + 1, RESULT_SLOT + 37, false)) { - return ItemStack.EMPTY; } if (stack.isEmpty()) { @@ -159,6 +163,9 @@ public class ReforgingTableMenu extends AbstractContainerMenu { } } + /** + * 根据输入槽的枪械和Perk槽中的物品与等级,生成重铸后的武器,并放入输出槽中 + */ public void generateResult() { ItemStack gun = this.container.getItem(INPUT_SLOT); if (!(gun.getItem() instanceof GunItem gunItem)) { @@ -175,21 +182,21 @@ public class ReforgingTableMenu extends AbstractContainerMenu { ItemStack result = gun.copy(); if (!ammo.isEmpty() && ammo.getItem() instanceof PerkItem perkItem) { - if (gunItem.canApplyPerk(result, perkItem.getPerk(), Perk.Type.AMMO)) { + if (gunItem.canApplyPerk(result, perkItem.getPerk())) { PerkHelper.setPerk(result, perkItem.getPerk(), this.ammoPerkLevel.get()); this.container.setItem(AMMO_PERK_SLOT, ItemStack.EMPTY); } } if (!func.isEmpty() && func.getItem() instanceof PerkItem perkItem) { - if (gunItem.canApplyPerk(result, perkItem.getPerk(), Perk.Type.FUNCTIONAL)) { + if (gunItem.canApplyPerk(result, perkItem.getPerk())) { PerkHelper.setPerk(result, perkItem.getPerk(), this.funcPerkLevel.get()); this.container.setItem(FUNC_PERK_SLOT, ItemStack.EMPTY); } } if (!damage.isEmpty() && damage.getItem() instanceof PerkItem perkItem) { - if (gunItem.canApplyPerk(result, perkItem.getPerk(), Perk.Type.DAMAGE)) { + if (gunItem.canApplyPerk(result, perkItem.getPerk())) { PerkHelper.setPerk(result, perkItem.getPerk(), this.damagePerkLevel.get()); this.container.setItem(DAMAGE_PERK_SLOT, ItemStack.EMPTY); } @@ -200,21 +207,145 @@ public class ReforgingTableMenu extends AbstractContainerMenu { this.container.setChanged(); } - static class InputSlot extends Slot { + /** + * 从Perk槽中取出对应的Perk物品时,根据其类型移除输入槽中枪械的Perk + * + * @param type Perk类型 + */ + private void onTakePerk(Perk.Type type) { + ItemStack gun = this.container.getItem(INPUT_SLOT); + if (!(gun.getItem() instanceof GunItem)) { + return; + } + + ItemStack perk = switch (type) { + case AMMO -> this.container.getItem(AMMO_PERK_SLOT); + case FUNCTIONAL -> this.container.getItem(FUNC_PERK_SLOT); + case DAMAGE -> this.container.getItem(DAMAGE_PERK_SLOT); + }; + + if (perk.getItem() instanceof PerkItem perkItem) { + if (PerkHelper.getItemPerkLevel(perkItem.getPerk(), gun) <= 0) { + return; + } + + switch (type) { + case AMMO -> this.ammoPerkLevel.set(1); + case FUNCTIONAL -> this.funcPerkLevel.set(1); + case DAMAGE -> this.damagePerkLevel.set(1); + } + + PerkHelper.removePerkByType(gun, perkItem.getPerk().type); + this.container.setItem(INPUT_SLOT, gun); + this.container.setChanged(); + } + } + + /** + * 将枪械放入输入槽中时,根据枪械上已有的Perk生成对应的Perk物品,并将等级调整为当前的等级 + * + * @param pStack 输入的枪械 + */ + private void onPlaceGun(ItemStack pStack) { + if (!(pStack.getItem() instanceof GunItem)) { + return; + } + + var ammoPerk = PerkHelper.getPerkByType(pStack, Perk.Type.AMMO); + if (ammoPerk != null) { + this.ammoPerkLevel.set(PerkHelper.getItemPerkLevel(ammoPerk, pStack)); + var ammoPerkItem = PerkHelper.getPerkItem(ammoPerk); + ammoPerkItem.ifPresent(registryObject -> this.container.setItem(AMMO_PERK_SLOT, registryObject.get().getDefaultInstance())); + } + + var funcPerk = PerkHelper.getPerkByType(pStack, Perk.Type.FUNCTIONAL); + if (funcPerk != null) { + this.funcPerkLevel.set(PerkHelper.getItemPerkLevel(funcPerk, pStack)); + var funcPerkItem = PerkHelper.getPerkItem(funcPerk); + funcPerkItem.ifPresent(registryObject -> this.container.setItem(FUNC_PERK_SLOT, registryObject.get().getDefaultInstance())); + } + + var damagePerk = PerkHelper.getPerkByType(pStack, Perk.Type.DAMAGE); + if (damagePerk != null) { + this.damagePerkLevel.set(PerkHelper.getItemPerkLevel(damagePerk, pStack)); + var damagePerkItem = PerkHelper.getPerkItem(damagePerk); + damagePerkItem.ifPresent(registryObject -> this.container.setItem(DAMAGE_PERK_SLOT, registryObject.get().getDefaultInstance())); + } + } + + /** + * 拿走输入槽中的枪械时,如果Perk槽中存在放入枪械时生成的Perk物品,则将其移除,如果是没有的Perk则无视 + * + * @param pStack 输入的枪械 + */ + private void onTakeGun(ItemStack pStack) { + if (!(pStack.getItem() instanceof GunItem)) { + return; + } + + var ammoPerk = PerkHelper.getPerkByType(pStack, Perk.Type.AMMO); + if (ammoPerk != null) { + if (this.container.getItem(AMMO_PERK_SLOT).getItem() instanceof PerkItem perkItem && perkItem.getPerk() == ammoPerk) { + this.container.setItem(AMMO_PERK_SLOT, ItemStack.EMPTY); + this.container.setChanged(); + } + } + + var funcPerk = PerkHelper.getPerkByType(pStack, Perk.Type.FUNCTIONAL); + if (funcPerk != null) { + if (this.container.getItem(FUNC_PERK_SLOT).getItem() instanceof PerkItem perkItem && perkItem.getPerk() == funcPerk) { + this.container.setItem(FUNC_PERK_SLOT, ItemStack.EMPTY); + this.container.setChanged(); + } + } + + var damagePerk = PerkHelper.getPerkByType(pStack, Perk.Type.DAMAGE); + if (damagePerk != null) { + if (this.container.getItem(DAMAGE_PERK_SLOT).getItem() instanceof PerkItem perkItem && perkItem.getPerk() == damagePerk) { + this.container.setItem(DAMAGE_PERK_SLOT, ItemStack.EMPTY); + this.container.setChanged(); + } + } + } + + class InputSlot extends Slot { public InputSlot(Container pContainer, int pSlot, int pX, int pY) { super(pContainer, pSlot, pX, pY); } public boolean mayPlace(ItemStack pStack) { - return pStack.is(ModTags.Items.GUN); + if (pStack.getItem() instanceof GunItem gunItem) { + ItemStack ammoPerk = this.container.getItem(AMMO_PERK_SLOT); + ItemStack funcPerk = this.container.getItem(FUNC_PERK_SLOT); + ItemStack damagePerk = this.container.getItem(DAMAGE_PERK_SLOT); + + boolean flag1 = ammoPerk.isEmpty() || (ammoPerk.getItem() instanceof PerkItem perkItem && gunItem.canApplyPerk(pStack, perkItem.getPerk())); + boolean flag2 = funcPerk.isEmpty() || (funcPerk.getItem() instanceof PerkItem perkItem && gunItem.canApplyPerk(pStack, perkItem.getPerk())); + boolean flag3 = damagePerk.isEmpty() || (damagePerk.getItem() instanceof PerkItem perkItem && gunItem.canApplyPerk(pStack, perkItem.getPerk())); + + return flag1 && flag2 && flag3 && this.container.getItem(RESULT_SLOT).isEmpty(); + } + return false; } public int getMaxStackSize() { return 1; } + + @Override + public void onTake(Player pPlayer, ItemStack pStack) { + super.onTake(pPlayer, pStack); + onTakeGun(pStack); + } + + @Override + public void setByPlayer(ItemStack pStack) { + super.setByPlayer(pStack); + onPlaceGun(pStack); + } } - static class PerkSlot extends Slot { + class PerkSlot extends Slot { public Perk.Type type; public PerkSlot(Container pContainer, int pSlot, Perk.Type type, int pX, int pY) { @@ -223,12 +354,18 @@ public class ReforgingTableMenu extends AbstractContainerMenu { } public boolean mayPlace(ItemStack pStack) { - return pStack.getItem() instanceof PerkItem perkItem && perkItem.getPerk().type == type; + return pStack.getItem() instanceof PerkItem perkItem && perkItem.getPerk().type == type && !container.getItem(INPUT_SLOT).isEmpty(); } public int getMaxStackSize() { return 1; } + + @Override + public void onTake(Player pPlayer, ItemStack pStack) { + onTakePerk(type); + super.onTake(pPlayer, pStack); + } } static class ResultSlot extends Slot { diff --git a/src/main/java/net/mcreator/superbwarfare/event/TempEventHandler.java b/src/main/java/net/mcreator/superbwarfare/event/TempEventHandler.java index 7a30478ac..d85d17dae 100644 --- a/src/main/java/net/mcreator/superbwarfare/event/TempEventHandler.java +++ b/src/main/java/net/mcreator/superbwarfare/event/TempEventHandler.java @@ -27,5 +27,15 @@ public class TempEventHandler { event.setCost(10); event.setMaterialCost(1); } + + if (right.is(ModTags.Items.GUN) && left.getItem() instanceof PerkItem perkItem) { + ItemStack output = right.copy(); + + PerkHelper.removePerkByType(output, perkItem.getPerk().type); + + event.setOutput(output); + event.setCost(10); + event.setMaterialCost(0); + } } } diff --git a/src/main/java/net/mcreator/superbwarfare/item/gun/GunItem.java b/src/main/java/net/mcreator/superbwarfare/item/gun/GunItem.java index 5f44dbee0..8d630782f 100644 --- a/src/main/java/net/mcreator/superbwarfare/item/gun/GunItem.java +++ b/src/main/java/net/mcreator/superbwarfare/item/gun/GunItem.java @@ -182,7 +182,7 @@ public abstract class GunItem extends Item { } } - public boolean canApplyPerk(ItemStack stack, Perk perk, Perk.Type slot) { - return perk.type == slot; + public boolean canApplyPerk(ItemStack stack, Perk perk) { + return true; } } diff --git a/src/main/java/net/mcreator/superbwarfare/perk/PerkHelper.java b/src/main/java/net/mcreator/superbwarfare/perk/PerkHelper.java index 33994f100..e68a89883 100644 --- a/src/main/java/net/mcreator/superbwarfare/perk/PerkHelper.java +++ b/src/main/java/net/mcreator/superbwarfare/perk/PerkHelper.java @@ -1,13 +1,17 @@ package net.mcreator.superbwarfare.perk; +import net.mcreator.superbwarfare.init.ModItems; import net.mcreator.superbwarfare.init.ModPerks; +import net.mcreator.superbwarfare.item.PerkItem; import net.minecraft.nbt.CompoundTag; import net.minecraft.resources.ResourceLocation; import net.minecraft.util.Mth; +import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraftforge.registries.RegistryObject; import javax.annotation.Nullable; +import java.util.Optional; public class PerkHelper { private static final String TAG_PERK_ID = "id"; @@ -146,6 +150,30 @@ public class PerkHelper { }; } + public static void removePerkByType(ItemStack stack, Perk.Type type) { + var tag = stack.getTag(); + if (tag == null) { + return; + } + + var tagPerk = tag.getCompound(TAG_PERK); + if (!tagPerk.contains(type.getName())) { + return; + } + + tagPerk.remove(type.getName()); + stack.addTagElement(TAG_PERK, tagPerk); + } + + public static Optional> getPerkItem(Perk perk) { + return ModItems.PERKS.getEntries().stream().filter(p -> { + if (p.get() instanceof PerkItem perkItem) { + return perkItem.getPerk() == perk; + } + return false; + }).findFirst(); + } + public static String makeId(ResourceLocation resourceLocation) { return resourceLocation.getNamespace() + ":" + resourceLocation.getPath(); }