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;