From 7de1675a820eea6389ea3b2f29dcc4118e27bb25 Mon Sep 17 00:00:00 2001 From: Sollace Date: Thu, 3 Oct 2024 19:56:43 +0100 Subject: [PATCH] Fix crash due to transient components not being initialised --- .../item/component/TransientComponentMap.java | 28 ++++++++++++---- .../unicopia/mixin/MixinItemStack.java | 32 ++++++------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/main/java/com/minelittlepony/unicopia/item/component/TransientComponentMap.java b/src/main/java/com/minelittlepony/unicopia/item/component/TransientComponentMap.java index 7f1834fb..3f9e568b 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/component/TransientComponentMap.java +++ b/src/main/java/com/minelittlepony/unicopia/item/component/TransientComponentMap.java @@ -21,7 +21,7 @@ import net.minecraft.util.Util; public class TransientComponentMap { private static final BiFunction DEFAULT = (stack, t) -> t; - public static final TransientComponentMap INITIAL = Util.make(new TransientComponentMap(), map -> { + public static final TransientComponentMap INITIAL = Util.make(new TransientComponentMap(null), map -> { map.set(UDataComponentTypes.DIET_PROFILE, (s, original) -> { if (original != null) { return original; @@ -56,11 +56,18 @@ public class TransientComponentMap { }); }); - private final Map, BiFunction> components = new HashMap<>(); + @Nullable + private final TransientComponentMap parent; + private Map, BiFunction> components; private Optional carrier = Optional.empty(); - private TransientComponentMap() {} + private TransientComponentMap(TransientComponentMap parent) { + this.parent = parent; + if (parent == null) { + components = new HashMap<>(); + } + } public Optional getCarrier() { return carrier; @@ -71,18 +78,25 @@ public class TransientComponentMap { } public void set(ComponentType type, BiFunction getter) { + if (components == null) { + components = parent == null ? new HashMap<>() : new HashMap<>(parent.components); + } components.put(type, getter); } @SuppressWarnings("unchecked") public T get(ComponentType type, ItemStack stack, T upstreamValue) { - return ((BiFunction)components.getOrDefault(type, DEFAULT)).apply(stack, upstreamValue); + if (components != null) { + return ((BiFunction)components.getOrDefault(type, DEFAULT)).apply(stack, upstreamValue); + } + if (parent != null) { + return parent.get(type, stack, upstreamValue); + } + return upstreamValue; } public TransientComponentMap createCopy() { - TransientComponentMap copy = new TransientComponentMap(); - copy.components.putAll(components); - return copy; + return new TransientComponentMap(this); } public interface Holder { diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinItemStack.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinItemStack.java index 8c855118..a0b3669b 100644 --- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinItemStack.java +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinItemStack.java @@ -1,16 +1,16 @@ package com.minelittlepony.unicopia.mixin; import java.util.List; -import java.util.function.Consumer; +import java.util.function.Supplier; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import com.google.common.base.Suppliers; import com.minelittlepony.unicopia.entity.effect.FoodPoisoningStatusEffect; import com.minelittlepony.unicopia.item.DamageChecker; import com.minelittlepony.unicopia.item.ItemStackDuck; @@ -23,7 +23,6 @@ import net.minecraft.entity.damage.DamageSource; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.item.tooltip.TooltipAppender; import net.minecraft.item.tooltip.TooltipType; import net.minecraft.text.Text; import net.minecraft.util.ActionResult; @@ -33,21 +32,16 @@ import net.minecraft.world.World; @Mixin(ItemStack.class) abstract class MixinItemStack implements ItemStackDuck { - private final TransientComponentMap transientComponents = TransientComponentMap.INITIAL.createCopy(); - - @Shadow - abstract void appendTooltip( - ComponentType componentType, Item.TooltipContext context, Consumer textConsumer, TooltipType type - ); + private final Supplier transientComponents = Suppliers.memoize(() -> TransientComponentMap.INITIAL.createCopy()); @Override public TransientComponentMap getTransientComponents() { - return transientComponents; + return transientComponents.get(); } @Inject(method = "use", at = @At("HEAD"), cancellable = true) private void onUse(World world, PlayerEntity user, Hand hand, CallbackInfoReturnable> info) { - transientComponents.setCarrier(user); + getTransientComponents().setCarrier(user); TypedActionResult result = FoodPoisoningStatusEffect.apply((ItemStack)(Object)this, user); if (result.getResult() != ActionResult.PASS) { info.setReturnValue(result); @@ -56,30 +50,22 @@ abstract class MixinItemStack implements ItemStackDuck { @Inject(method = "onStoppedUsing", at = @At("RETURN")) public void onOnStoppedUsing(World world, LivingEntity user, int remainingUseTicks, CallbackInfo info) { - transientComponents.setCarrier(null); + getTransientComponents().setCarrier(null); } @Inject(method = "finishUsing", at = @At("RETURN")) private void afterFinishUsing(World world, LivingEntity user, CallbackInfoReturnable info) { - transientComponents.setCarrier(null); + getTransientComponents().setCarrier(null); } @Inject(method = "getTooltip", at = @At("HEAD")) public void beforeGetTooltip(Item.TooltipContext context, @Nullable PlayerEntity player, TooltipType type, CallbackInfoReturnable> info) { - transientComponents.setCarrier(player); + getTransientComponents().setCarrier(player); } @Inject(method = "getTooltip", at = @At("RETURN")) public void afterGetTooltip(Item.TooltipContext context, @Nullable PlayerEntity player, TooltipType type, CallbackInfoReturnable> info) { - transientComponents.setCarrier(null); - } - - @Inject(method = "getTooltip", - at = @At(value = "INVOKE", - target = "net/minecraft/item/ItemStack.appendAttributeModifiersTooltip(Ljava/util/function/Consumer;Lnet/minecraft/entity/player/PlayerEntity;)V" - )) - public void onGetTooltip(Item.TooltipContext context, @Nullable PlayerEntity player, TooltipType type, CallbackInfoReturnable> info) { - + getTransientComponents().setCarrier(null); } @Inject(method = "takesDamageFrom", at = @At("HEAD"))