From 8635849b39d26aa9cc33599f15317b3f6fbdb390 Mon Sep 17 00:00:00 2001 From: ErrorCraft Date: Sun, 12 Apr 2026 19:40:40 +0200 Subject: [PATCH] Move the set_item_pointer_location action to an item modifier --- .../data/minecraft/item/compass.json | 27 +++----- .../itematic/access/item/ItemStackAccess.java | 5 ++ .../errorcraft/itematic/item/ItemUtil.java | 11 +--- .../function/ItematicItemModifierTypes.java | 1 + .../SetItemPointerLocationItemModifier.java | 64 +++++++++++++++++++ .../loot/function/SplitItemModifier.java | 7 +- .../mixin/item/ItemStackExtender.java | 15 +++++ .../itematic/world/action/ActionTypeKeys.java | 1 - .../itematic/world/action/ActionTypes.java | 1 - .../action/actions/ModifyItemAction.java | 2 +- .../actions/SetItemPointerLocationAction.java | 56 ---------------- .../world/action/context/ItemStackTarget.java | 18 ++---- 12 files changed, 110 insertions(+), 98 deletions(-) create mode 100644 src/main/java/net/errorcraft/itematic/loot/function/SetItemPointerLocationItemModifier.java delete mode 100644 src/main/java/net/errorcraft/itematic/world/action/actions/SetItemPointerLocationAction.java diff --git a/src/main/generated/data/minecraft/item/compass.json b/src/main/generated/data/minecraft/item/compass.json index e57462bc..8dd38ab3 100644 --- a/src/main/generated/data/minecraft/item/compass.json +++ b/src/main/generated/data/minecraft/item/compass.json @@ -12,28 +12,20 @@ "type": "minecraft:sequence", "handler": "minecraft:passing", "entries": [ - { - "action": { - "type": "minecraft:modify_item", - "item_modifier": { - "count": 1.0, - "function": "minecraft:split" - } - } - }, - { - "action": { - "type": "minecraft:set_item_pointer_location", - "position": "interacted", - "stack": "result" - } - }, { "action": { "type": "minecraft:modify_item", "item_modifier": { "function": "minecraft:sequence", "functions": [ + { + "count": 1.0, + "function": "minecraft:split" + }, + { + "function": "minecraft:set_item_pointer_location", + "position": "interacted" + }, { "function": "minecraft:set_name", "name": { @@ -48,8 +40,7 @@ "function": "minecraft:set_components" } ] - }, - "stack": "result" + } } }, { diff --git a/src/main/java/net/errorcraft/itematic/access/item/ItemStackAccess.java b/src/main/java/net/errorcraft/itematic/access/item/ItemStackAccess.java index 19f54e13..8208ca29 100644 --- a/src/main/java/net/errorcraft/itematic/access/item/ItemStackAccess.java +++ b/src/main/java/net/errorcraft/itematic/access/item/ItemStackAccess.java @@ -5,6 +5,7 @@ import net.errorcraft.itematic.item.event.ItemEvent; import net.errorcraft.itematic.world.action.context.ActionContext; import net.minecraft.component.MergedComponentMap; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -12,6 +13,7 @@ import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.util.Hand; import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; import java.util.Optional; @@ -24,6 +26,9 @@ public interface ItemStackAccess { default int itematic$tryDecrement(int amount) { return 0; } + default ItemStack itematic$copyOrSplit(@Nullable LivingEntity holder, int amount) { + return ItemStack.EMPTY; + } default ItemStack itematic$copyWithItem(RegistryEntry item) { return ItemStack.EMPTY; } diff --git a/src/main/java/net/errorcraft/itematic/item/ItemUtil.java b/src/main/java/net/errorcraft/itematic/item/ItemUtil.java index 64611afa..3ca5c5d1 100644 --- a/src/main/java/net/errorcraft/itematic/item/ItemUtil.java +++ b/src/main/java/net/errorcraft/itematic/item/ItemUtil.java @@ -19,6 +19,7 @@ import net.errorcraft.itematic.item.shooter.method.methods.DirectShooterMethod; import net.errorcraft.itematic.item.smithing.template.SmithingTemplates; import net.errorcraft.itematic.loot.condition.LocationCheckLootConditionUtil; +import net.errorcraft.itematic.loot.function.SetItemPointerLocationItemModifier; import net.errorcraft.itematic.loot.function.SplitItemModifier; import net.errorcraft.itematic.loot.predicate.SideCheckPredicate; import net.errorcraft.itematic.mixin.item.BrushItemAccessor; @@ -10991,14 +10992,8 @@ private void bootstrapMiscellaneous() { PassingSequenceHandler.builder() .add(ModifyItemAction.of( ItemStackTarget.TOOL, - SplitItemModifier.builder(1) - )) - .add(SetItemPointerLocationAction.of( - ItemStackTarget.RESULT, - PositionTarget.INTERACTED_POSITION - )) - .add(ModifyItemAction.of( - ItemStackTarget.RESULT, + SplitItemModifier.builder(1), + SetItemPointerLocationItemModifier.builder(PositionTarget.INTERACTED_POSITION), SetNameLootFunction.builder( Text.translatable(Util.createTranslationKey("item", Identifier.ofVanilla("lodestone_compass"))), SetNameLootFunction.Target.ITEM_NAME diff --git a/src/main/java/net/errorcraft/itematic/loot/function/ItematicItemModifierTypes.java b/src/main/java/net/errorcraft/itematic/loot/function/ItematicItemModifierTypes.java index 8d095f41..edfd7c0e 100644 --- a/src/main/java/net/errorcraft/itematic/loot/function/ItematicItemModifierTypes.java +++ b/src/main/java/net/errorcraft/itematic/loot/function/ItematicItemModifierTypes.java @@ -7,6 +7,7 @@ public class ItematicItemModifierTypes { public static final LootFunctionType DYE = LootFunctionTypesAccessor.register("dye", DyeItemModifier.CODEC); public static final LootFunctionType SET_RANDOM_POTION = LootFunctionTypesAccessor.register("set_random_potion", SetRandomPotionItemModifier.CODEC); public static final LootFunctionType SPLIT = LootFunctionTypesAccessor.register("split", SplitItemModifier.CODEC); + public static final LootFunctionType SET_ITEM_POINTER_LOCATION = LootFunctionTypesAccessor.register("set_item_pointer_location", SetItemPointerLocationItemModifier.CODEC); private ItematicItemModifierTypes() {} diff --git a/src/main/java/net/errorcraft/itematic/loot/function/SetItemPointerLocationItemModifier.java b/src/main/java/net/errorcraft/itematic/loot/function/SetItemPointerLocationItemModifier.java new file mode 100644 index 00000000..6abdce41 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/loot/function/SetItemPointerLocationItemModifier.java @@ -0,0 +1,64 @@ +package net.errorcraft.itematic.loot.function; + +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.errorcraft.itematic.world.action.context.PositionTarget; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.LodestoneTrackerComponent; +import net.minecraft.item.ItemStack; +import net.minecraft.loot.condition.LootCondition; +import net.minecraft.loot.context.LootContext; +import net.minecraft.loot.function.ConditionalLootFunction; +import net.minecraft.loot.function.LootFunctionType; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.GlobalPos; +import net.minecraft.util.math.Vec3d; + +import java.util.List; +import java.util.Optional; + +public class SetItemPointerLocationItemModifier extends ConditionalLootFunction { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> addConditionsField(instance).and( + PositionTarget.CODEC.fieldOf("position").forGetter(split -> split.position) + ).apply(instance, SetItemPointerLocationItemModifier::new)); + + private final PositionTarget position; + + public SetItemPointerLocationItemModifier(PositionTarget position) { + this(List.of(), position); + } + + public SetItemPointerLocationItemModifier(List conditions, PositionTarget position) { + super(conditions); + this.position = position; + } + + public static Builder builder(PositionTarget position) { + return builder(conditions -> new SetItemPointerLocationItemModifier(conditions, position)); + } + + @Override + public LootFunctionType getType() { + return ItematicItemModifierTypes.SET_ITEM_POINTER_LOCATION; + } + + @Override + protected ItemStack process(ItemStack stack, LootContext context) { + Vec3d pos = context.get(this.position.parameter()); + if (pos == null) { + return stack; + } + + stack.set( + DataComponentTypes.LODESTONE_TRACKER, + new LodestoneTrackerComponent( + Optional.of(GlobalPos.create( + context.getWorld().getRegistryKey(), + BlockPos.ofFloored(pos) + )), + true + ) + ); + return stack; + } +} diff --git a/src/main/java/net/errorcraft/itematic/loot/function/SplitItemModifier.java b/src/main/java/net/errorcraft/itematic/loot/function/SplitItemModifier.java index 13591201..690b4f43 100644 --- a/src/main/java/net/errorcraft/itematic/loot/function/SplitItemModifier.java +++ b/src/main/java/net/errorcraft/itematic/loot/function/SplitItemModifier.java @@ -2,9 +2,11 @@ import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.entity.LivingEntity; import net.minecraft.item.ItemStack; import net.minecraft.loot.condition.LootCondition; import net.minecraft.loot.context.LootContext; +import net.minecraft.loot.context.LootContextParameters; import net.minecraft.loot.function.ConditionalLootFunction; import net.minecraft.loot.function.LootFunctionType; import net.minecraft.loot.provider.number.ConstantLootNumberProvider; @@ -30,7 +32,7 @@ public SplitItemModifier(List conditions, LootNumberProvider coun } public static Builder builder(int count) { - return builder(conditions -> new SplitItemModifier(ConstantLootNumberProvider.create(count))); + return builder(conditions -> new SplitItemModifier(conditions, ConstantLootNumberProvider.create(count))); } @Override @@ -40,6 +42,7 @@ public LootFunctionType getType() { @Override protected ItemStack process(ItemStack stack, LootContext context) { - return stack.split(this.count.nextInt(context)); + LivingEntity holder = context.get(LootContextParameters.THIS_ENTITY) instanceof LivingEntity target ? target : null; + return stack.itematic$copyOrSplit(holder, this.count.nextInt(context)); } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/item/ItemStackExtender.java b/src/main/java/net/errorcraft/itematic/mixin/item/ItemStackExtender.java index e9f147a2..b298d4a6 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/item/ItemStackExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/item/ItemStackExtender.java @@ -88,6 +88,9 @@ public abstract class ItemStackExtender implements ComponentHolder, ItemStackAcc @Shadow public abstract boolean isEmpty(); + @Shadow + public abstract ItemStack split(int amount); + @Shadow public abstract void damage(int amount, ServerWorld world, @Nullable ServerPlayerEntity player, Consumer breakCallback); @@ -103,6 +106,9 @@ public abstract class ItemStackExtender implements ComponentHolder, ItemStackAcc @Shadow public abstract int getMaxCount(); + @Shadow + public abstract ItemStack copyWithCount(int count); + @Shadow public abstract int getCount(); @@ -707,6 +713,15 @@ public boolean canBeEnchantedWith(RegistryEntry enchantment, Enchan return actualAmount; } + @Override + public ItemStack itematic$copyOrSplit(@Nullable LivingEntity holder, int amount) { + if (holder != null && holder.isInCreativeMode()) { + return this.copyWithCount(amount); + } + + return this.split(amount); + } + @Override public ItemStack itematic$copyWithItem(RegistryEntry item) { return this.itematic$copyComponentsToNewStack(item, this.count); diff --git a/src/main/java/net/errorcraft/itematic/world/action/ActionTypeKeys.java b/src/main/java/net/errorcraft/itematic/world/action/ActionTypeKeys.java index ac50015d..f5155ff9 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/ActionTypeKeys.java +++ b/src/main/java/net/errorcraft/itematic/world/action/ActionTypeKeys.java @@ -20,7 +20,6 @@ public class ActionTypeKeys { public static final RegistryKey> MODIFY_SIGN = of("modify_sign"); public static final RegistryKey> WAX_BLOCK = of("wax_block"); public static final RegistryKey> DECREMENT_ITEM = of("decrement_item"); - public static final RegistryKey> SET_ITEM_POINTER_LOCATION = of("set_item_pointer_location"); public static final RegistryKey> LIGHT_END_PORTAL = of("light_end_portal"); public static final RegistryKey> PLAY_SOUND = of("play_sound"); public static final RegistryKey> DISPLAY_PARTICLE = of("display_particle"); diff --git a/src/main/java/net/errorcraft/itematic/world/action/ActionTypes.java b/src/main/java/net/errorcraft/itematic/world/action/ActionTypes.java index 059f07e7..e75b82bc 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/ActionTypes.java +++ b/src/main/java/net/errorcraft/itematic/world/action/ActionTypes.java @@ -21,7 +21,6 @@ public class ActionTypes { public static final ActionType MODIFY_SIGN = register(ActionTypeKeys.MODIFY_SIGN, new ActionType<>(ModifySignAction.CODEC)); public static final ActionType WAX_BLOCK = register(ActionTypeKeys.WAX_BLOCK, new ActionType<>(WaxBlockAction.CODEC)); public static final ActionType DECREMENT_ITEM = register(ActionTypeKeys.DECREMENT_ITEM, new ActionType<>(DecrementItemAction.CODEC)); - public static final ActionType SET_ITEM_POINTER_LOCATION = register(ActionTypeKeys.SET_ITEM_POINTER_LOCATION, new ActionType<>(SetItemPointerLocationAction.CODEC)); public static final ActionType LIGHT_END_PORTAL = register(ActionTypeKeys.LIGHT_END_PORTAL, new ActionType<>(LightEndPortalAction.CODEC)); public static final ActionType PLAY_SOUND = register(ActionTypeKeys.PLAY_SOUND, new ActionType<>(PlaySoundAction.CODEC)); public static final ActionType DISPLAY_PARTICLE = register(ActionTypeKeys.DISPLAY_PARTICLE, new ActionType<>(DisplayParticleAction.CODEC)); diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/ModifyItemAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/ModifyItemAction.java index b2450ef4..ee2cacc5 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/ModifyItemAction.java +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/ModifyItemAction.java @@ -42,7 +42,7 @@ public ActionType type() { @Override public boolean execute(ActionContext context) { - ItemStack stack = this.stack.get(context); + ItemStack stack = context.get(this.stack.parameter()); if (ItemStackUtil.isNullOrEmpty(stack)) { return false; } diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/SetItemPointerLocationAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/SetItemPointerLocationAction.java deleted file mode 100644 index 8aad98ea..00000000 --- a/src/main/java/net/errorcraft/itematic/world/action/actions/SetItemPointerLocationAction.java +++ /dev/null @@ -1,56 +0,0 @@ -package net.errorcraft.itematic.world.action.actions; - -import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.errorcraft.itematic.item.ItemStackUtil; -import net.errorcraft.itematic.world.action.Action; -import net.errorcraft.itematic.world.action.ActionType; -import net.errorcraft.itematic.world.action.ActionTypes; -import net.errorcraft.itematic.world.action.context.ActionContext; -import net.errorcraft.itematic.world.action.context.ItemStackTarget; -import net.errorcraft.itematic.world.action.context.PositionTarget; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.LodestoneTrackerComponent; -import net.minecraft.item.ItemStack; -import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.GlobalPos; - -import java.util.Optional; - -public record SetItemPointerLocationAction(ItemStackTarget stack, PositionTarget position) implements Action { - public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ItemStackTarget.CODEC.optionalFieldOf("stack", ItemStackTarget.TOOL).forGetter(SetItemPointerLocationAction::stack), - PositionTarget.CODEC.fieldOf("position").forGetter(SetItemPointerLocationAction::position) - ).apply(instance, SetItemPointerLocationAction::new)); - - public static SetItemPointerLocationAction of(ItemStackTarget stack, PositionTarget position) { - return new SetItemPointerLocationAction(stack, position); - } - - @Override - public ActionType type() { - return ActionTypes.SET_ITEM_POINTER_LOCATION; - } - - @Override - public boolean execute(ActionContext context) { - ItemStack stack = this.stack.get(context); - if (ItemStackUtil.isNullOrEmpty(stack)) { - return false; - } - - BlockPos pos = context.get(this.position.parameter(), BlockPos::ofFloored); - if (pos == null) { - return false; - } - - stack.set( - DataComponentTypes.LODESTONE_TRACKER, - new LodestoneTrackerComponent( - Optional.of(GlobalPos.create(context.world().getRegistryKey(), pos)), - true - ) - ); - return true; - } -} diff --git a/src/main/java/net/errorcraft/itematic/world/action/context/ItemStackTarget.java b/src/main/java/net/errorcraft/itematic/world/action/context/ItemStackTarget.java index acdb58d1..692f240d 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/context/ItemStackTarget.java +++ b/src/main/java/net/errorcraft/itematic/world/action/context/ItemStackTarget.java @@ -4,22 +4,19 @@ import net.minecraft.item.ItemStack; import net.minecraft.loot.context.LootContextParameters; import net.minecraft.util.StringIdentifiable; -import org.jetbrains.annotations.Nullable; - -import java.util.function.Function; +import net.minecraft.util.context.ContextParameter; public enum ItemStackTarget implements StringIdentifiable { - TOOL("tool", context -> context.get(LootContextParameters.TOOL)), - RESULT("result", ActionContext::resultStack); + TOOL("tool", LootContextParameters.TOOL); public static final Codec CODEC = StringIdentifiable.createCodec(ItemStackTarget::values); private final String name; - private final Function itemStackSupplier; + private final ContextParameter parameter; - ItemStackTarget(String name, Function itemStackSupplier) { + ItemStackTarget(String name, ContextParameter parameter) { this.name = name; - this.itemStackSupplier = itemStackSupplier; + this.parameter = parameter; } @Override @@ -27,8 +24,7 @@ public String asString() { return this.name; } - @Nullable - public ItemStack get(ActionContext context) { - return this.itemStackSupplier.apply(context); + public ContextParameter parameter() { + return this.parameter; } }