From e60c5bfef550c2e9380b6754ce911e2ab6d242da Mon Sep 17 00:00:00 2001 From: C4 <29991504+TheIllusiveC4@users.noreply.github.com> Date: Sun, 3 Sep 2023 02:03:46 -0700 Subject: [PATCH] Properly filter curios inserted directly through item handlers, but actually this time, closes #238 --- .../curios/api/event/CurioChangeEvent.java | 2 +- .../curios/common/inventory/CurioSlot.java | 35 ------------- .../common/inventory/CurioStacksHandler.java | 18 +++---- .../common/inventory/DynamicStackHandler.java | 49 +++++++++++++++++-- .../curiostest/common/item/AmuletItem.java | 1 - 5 files changed, 51 insertions(+), 54 deletions(-) diff --git a/src/main/java/top/theillusivec4/curios/api/event/CurioChangeEvent.java b/src/main/java/top/theillusivec4/curios/api/event/CurioChangeEvent.java index 501644a8..892c2a61 100644 --- a/src/main/java/top/theillusivec4/curios/api/event/CurioChangeEvent.java +++ b/src/main/java/top/theillusivec4/curios/api/event/CurioChangeEvent.java @@ -29,7 +29,7 @@ /** * {@link CurioChangeEvent} is fired when the Curio of a LivingEntity changes.
This event is * fired whenever changes in curios are detected in - *
{@link net.minecraftforge.event.entity.living.LivingEvent.LivingUpdateEvent}. + *
{@link net.minecraftforge.event.entity.living.LivingEvent.LivingTickEvent}. *
This also includes entities joining the World, as well as being cloned.
This event is * fired on server-side only.
*
diff --git a/src/main/java/top/theillusivec4/curios/common/inventory/CurioSlot.java b/src/main/java/top/theillusivec4/curios/common/inventory/CurioSlot.java index f84b2a5a..604086d7 100644 --- a/src/main/java/top/theillusivec4/curios/common/inventory/CurioSlot.java +++ b/src/main/java/top/theillusivec4/curios/common/inventory/CurioSlot.java @@ -25,16 +25,11 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.InventoryMenu; import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.enchantment.EnchantmentHelper; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.common.MinecraftForge; -import net.minecraftforge.eventbus.api.Event; import net.minecraftforge.items.SlotItemHandler; import top.theillusivec4.curios.api.CuriosApi; import top.theillusivec4.curios.api.SlotContext; -import top.theillusivec4.curios.api.event.CurioEquipEvent; -import top.theillusivec4.curios.api.event.CurioUnequipEvent; import top.theillusivec4.curios.api.type.inventory.IDynamicStackHandler; import top.theillusivec4.curios.mixin.core.AccessorEntity; @@ -95,38 +90,8 @@ public void set(@Nonnull ItemStack stack) { } } - @Override - public boolean mayPlace(@Nonnull ItemStack stack) { - CurioEquipEvent equipEvent = new CurioEquipEvent(stack, slotContext); - MinecraftForge.EVENT_BUS.post(equipEvent); - Event.Result result = equipEvent.getResult(); - - if (result == Event.Result.DENY) { - return false; - } - return result == Event.Result.ALLOW || (CuriosApi.isStackValid(slotContext, stack) && - CuriosApi.getCurio(stack).map(curio -> curio.canEquip(slotContext)).orElse(true) && - super.mayPlace(stack)); - } - @Override public boolean allowModification(@Nonnull Player pPlayer) { return true; } - - @Override - public boolean mayPickup(Player playerIn) { - ItemStack stack = this.getItem(); - CurioUnequipEvent unequipEvent = new CurioUnequipEvent(stack, slotContext); - MinecraftForge.EVENT_BUS.post(unequipEvent); - Event.Result result = unequipEvent.getResult(); - - if (result == Event.Result.DENY) { - return false; - } - return result == Event.Result.ALLOW || - ((stack.isEmpty() || playerIn.isCreative() || !EnchantmentHelper.hasBindingCurse(stack)) && - CuriosApi.getCurio(stack).map(curio -> curio.canUnequip(slotContext)).orElse(true) && - super.mayPickup(playerIn)); - } } diff --git a/src/main/java/top/theillusivec4/curios/common/inventory/CurioStacksHandler.java b/src/main/java/top/theillusivec4/curios/common/inventory/CurioStacksHandler.java index 9297dd48..98eef193 100644 --- a/src/main/java/top/theillusivec4/curios/common/inventory/CurioStacksHandler.java +++ b/src/main/java/top/theillusivec4/curios/common/inventory/CurioStacksHandler.java @@ -87,19 +87,13 @@ public CurioStacksHandler(ICuriosItemHandler itemHandler, String identifier, int this.identifier = identifier; this.canToggleRender = canToggleRender; this.dropRule = dropRule; - this.stackHandler = new DynamicStackHandler(size, (slot, stack) -> { - NonNullList list = getRenders(); - SlotContext ctx = new SlotContext(identifier, itemHandler.getWearer(), slot, false, - list.size() > slot && list.get(slot)); - return CuriosApi.isStackValid(ctx, stack); - }); - this.cosmeticStackHandler = new DynamicStackHandler(size, (slot, stack) -> { - NonNullList list = getRenders(); - SlotContext ctx = new SlotContext(identifier, itemHandler.getWearer(), slot, true, - list.size() > slot && list.get(slot)); - return CuriosApi.isStackValid(ctx, stack); - }); this.renderHandler = NonNullList.withSize(size, true); + this.stackHandler = new DynamicStackHandler(size, + (index) -> new SlotContext(identifier, itemHandler.getWearer(), index, false, + this.getRenders().get(index))); + this.cosmeticStackHandler = new DynamicStackHandler(size, + (index) -> new SlotContext(identifier, itemHandler.getWearer(), index, true, + this.getRenders().get(index))); } @Override diff --git a/src/main/java/top/theillusivec4/curios/common/inventory/DynamicStackHandler.java b/src/main/java/top/theillusivec4/curios/common/inventory/DynamicStackHandler.java index a3f7ba2b..5e10fa5d 100644 --- a/src/main/java/top/theillusivec4/curios/common/inventory/DynamicStackHandler.java +++ b/src/main/java/top/theillusivec4/curios/common/inventory/DynamicStackHandler.java @@ -19,22 +19,30 @@ package top.theillusivec4.curios.common.inventory; -import java.util.function.BiPredicate; +import java.util.function.Function; import javax.annotation.Nonnull; import net.minecraft.core.NonNullList; +import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.enchantment.EnchantmentHelper; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.eventbus.api.Event; import net.minecraftforge.items.ItemStackHandler; +import top.theillusivec4.curios.api.CuriosApi; +import top.theillusivec4.curios.api.SlotContext; +import top.theillusivec4.curios.api.event.CurioEquipEvent; +import top.theillusivec4.curios.api.event.CurioUnequipEvent; import top.theillusivec4.curios.api.type.inventory.IDynamicStackHandler; public class DynamicStackHandler extends ItemStackHandler implements IDynamicStackHandler { protected NonNullList previousStacks; - protected BiPredicate validator; + protected Function ctxBuilder; - public DynamicStackHandler(int size, BiPredicate validator) { + public DynamicStackHandler(int size, Function ctxBuilder) { super(size); this.previousStacks = NonNullList.withSize(size, ItemStack.EMPTY); - this.validator = validator; + this.ctxBuilder = ctxBuilder; } @Override @@ -53,7 +61,38 @@ public ItemStack getPreviousStackInSlot(int slot) { @Override public boolean isItemValid(int slot, @Nonnull ItemStack stack) { - return this.validator.test(slot, stack); + SlotContext ctx = ctxBuilder.apply(slot); + CurioEquipEvent equipEvent = new CurioEquipEvent(stack, ctx); + MinecraftForge.EVENT_BUS.post(equipEvent); + Event.Result result = equipEvent.getResult(); + + if (result == Event.Result.DENY) { + return false; + } + return result == Event.Result.ALLOW || (CuriosApi.isStackValid(ctx, stack) && + CuriosApi.getCurio(stack).map(curio -> curio.canEquip(ctx)).orElse(true) && + super.isItemValid(slot, stack)); + } + + @Override + public @Nonnull ItemStack extractItem(int slot, int amount, boolean simulate) { + ItemStack existing = this.stacks.get(slot); + SlotContext ctx = ctxBuilder.apply(slot); + CurioUnequipEvent unequipEvent = new CurioUnequipEvent(existing, ctx); + MinecraftForge.EVENT_BUS.post(unequipEvent); + Event.Result result = unequipEvent.getResult(); + + if (result == Event.Result.DENY) { + return ItemStack.EMPTY; + } + boolean isCreative = ctx.entity() instanceof Player player && player.isCreative(); + + if (result == Event.Result.ALLOW || + ((existing.isEmpty() || isCreative || !EnchantmentHelper.hasBindingCurse(existing)) && + CuriosApi.getCurio(existing).map(curio -> curio.canUnequip(ctx)).orElse(true))) { + return super.extractItem(slot, amount, simulate); + } + return ItemStack.EMPTY; } @Override diff --git a/src/test/java/top/theillusivec4/curiostest/common/item/AmuletItem.java b/src/test/java/top/theillusivec4/curiostest/common/item/AmuletItem.java index 00eccd5d..49782663 100644 --- a/src/test/java/top/theillusivec4/curiostest/common/item/AmuletItem.java +++ b/src/test/java/top/theillusivec4/curiostest/common/item/AmuletItem.java @@ -34,7 +34,6 @@ import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.effect.MobEffects; import net.minecraft.world.entity.LivingEntity; -import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.storage.loot.LootContext;