1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-10-24 18:37:38 +00:00

Ignore enchantments/attributes on the original item

Turtle tools were not equippable, as we considered the stack enchanted
due to the item's base attribute modifiers. We now only check the
component patch for enchantments/attribute modifiers.

This also removes the craftItem property of tools - this hasn't worked
since we added support for enchanted tools!

Fixes #1810
This commit is contained in:
Jonathan Coates
2024-04-29 21:02:14 +01:00
parent 2226df7224
commit 94c864759d
5 changed files with 37 additions and 49 deletions

View File

@@ -11,6 +11,7 @@ import dan200.computercraft.api.turtle.ITurtleAccess;
import dan200.computercraft.api.turtle.TurtleSide;
import dan200.computercraft.shared.ModRegistry;
import dan200.computercraft.shared.turtle.upgrades.TurtleModem;
import dan200.computercraft.shared.util.DataComponentUtil;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.Nullable;
@@ -23,8 +24,7 @@ import java.util.stream.Stream;
public class TurtleModemModeller implements TurtleUpgradeModeller<TurtleModem> {
@Override
public TransformedModel getModel(TurtleModem upgrade, @Nullable ITurtleAccess turtle, TurtleSide side, DataComponentPatch data) {
var component = data.get(ModRegistry.DataComponents.ON.get());
var active = component != null && component.isPresent() && component.get();
var active = DataComponentUtil.isPresent(data, ModRegistry.DataComponents.ON.get(), x -> x);
var models = upgrade.advanced() ? ModemModels.ADVANCED : ModemModels.NORMAL;
return side == TurtleSide.LEFT

View File

@@ -14,6 +14,7 @@ import dan200.computercraft.shared.platform.PlatformHelper;
import dan200.computercraft.shared.turtle.TurtleUtil;
import dan200.computercraft.shared.turtle.core.TurtlePlaceCommand;
import dan200.computercraft.shared.turtle.core.TurtlePlayer;
import dan200.computercraft.shared.util.DataComponentUtil;
import dan200.computercraft.shared.util.DropConsumer;
import dan200.computercraft.shared.util.WorldUtil;
import net.minecraft.core.BlockPos;
@@ -49,37 +50,26 @@ public class TurtleTool extends AbstractTurtleUpgrade {
private static final TurtleCommandResult INEFFECTIVE = TurtleCommandResult.failure("Cannot break block with this tool");
final TurtleToolSpec spec;
final ItemStack item;
final float damageMulitiplier;
final boolean allowEnchantments;
final TurtleToolDurability consumeDurability;
final @Nullable TagKey<Block> breakable;
public TurtleTool(TurtleToolSpec spec) {
super(TurtleUpgradeType.TOOL, spec.adjective(), new ItemStack(spec.craftItem().orElse(spec.toolItem())));
super(TurtleUpgradeType.TOOL, spec.adjective(), new ItemStack(spec.item()));
this.spec = spec;
item = new ItemStack(spec.toolItem());
this.damageMulitiplier = spec.damageMultiplier();
this.allowEnchantments = spec.allowEnchantments();
this.consumeDurability = spec.consumeDurability();
this.breakable = spec.breakable().orElse(null);
}
@Override
public boolean isItemSuitable(ItemStack stack) {
if (consumeDurability == TurtleToolDurability.NEVER && stack.isDamaged()) return false;
if (!allowEnchantments && isEnchanted(stack)) return false;
if (spec.consumeDurability() == TurtleToolDurability.NEVER && stack.isDamaged()) return false;
if (!spec.allowEnchantments() && isEnchanted(stack)) return false;
return true;
}
private static boolean isEnchanted(ItemStack stack) {
var enchantments = stack.get(DataComponents.ENCHANTMENTS);
if (enchantments != null && !enchantments.isEmpty()) return true;
var modifiers = stack.get(DataComponents.ATTRIBUTE_MODIFIERS);
if (modifiers != null && !modifiers.modifiers().isEmpty()) return true;
return false;
// Only check whether the stack has been modified. We ignore components on the original item.
var patch = stack.getComponentsPatch();
return DataComponentUtil.isPresent(patch, DataComponents.ENCHANTMENTS, x -> !x.isEmpty())
|| DataComponentUtil.isPresent(patch, DataComponents.ATTRIBUTE_MODIFIERS, x -> !x.modifiers().isEmpty());
}
@Override
@@ -100,9 +90,7 @@ public class TurtleTool extends AbstractTurtleUpgrade {
}
private void setToolStack(ITurtleAccess turtle, TurtleSide side, ItemStack oldStack, ItemStack stack) {
var upgradeData = turtle.getUpgradeData(side);
var useDurability = switch (consumeDurability) {
var useDurability = switch (spec.consumeDurability()) {
case NEVER -> false;
case WHEN_ENCHANTED -> isEnchanted(oldStack);
case ALWAYS -> true;
@@ -116,7 +104,7 @@ public class TurtleTool extends AbstractTurtleUpgrade {
}
// If the tool has changed, no clue what's going on.
if (stack.getItem() != item.getItem()) return;
if (stack.getItem() != spec.item()) return;
turtle.setUpgradeData(side, stack.getComponentsPatch());
}
@@ -218,7 +206,7 @@ public class TurtleTool extends AbstractTurtleUpgrade {
* @see Player#attack(Entity)
*/
private boolean attack(ServerPlayer player, Direction direction, Entity entity) {
var baseDamage = (float) player.getAttributeValue(Attributes.ATTACK_DAMAGE) * damageMulitiplier;
var baseDamage = (float) player.getAttributeValue(Attributes.ATTACK_DAMAGE) * spec.damageMultiplier();
var bonusDamage = EnchantmentHelper.getDamageBonus(player.getItemInHand(InteractionHand.MAIN_HAND), entity.getType());
var damage = baseDamage + bonusDamage;
if (damage <= 0) return false;

View File

@@ -5,6 +5,7 @@
package dan200.computercraft.shared.util;
import net.minecraft.core.component.DataComponentHolder;
import net.minecraft.core.component.DataComponentPatch;
import net.minecraft.core.component.DataComponentType;
import net.minecraft.core.component.DataComponents;
import net.minecraft.network.chat.Component;
@@ -13,6 +14,7 @@ import net.minecraft.world.level.ItemLike;
import org.jetbrains.annotations.Contract;
import javax.annotation.Nullable;
import java.util.function.Predicate;
/**
* Utilities for working with {@linkplain DataComponentType data components}.
@@ -43,4 +45,18 @@ public class DataComponentUtil {
public static <T> ItemStack createStack(ItemLike item, DataComponentType<T> type, @Nullable T value) {
return set(new ItemStack(item), type, value);
}
/**
* Check a component is present in a {@link DataComponentPatch} and matches the supplied predicate.
*
* @param patch The current component patch.
* @param component The component type.
* @param check The predicate to check against.
* @param <T> The type of component.
* @return Whether the component is present in this patch, and matches the supplied predicate.
*/
public static <T> boolean isPresent(DataComponentPatch patch, DataComponentType<T> component, Predicate<T> check) {
var value = patch.get(component);
return value != null && value.isPresent() && check.test(value.get());
}
}