Fix crash due to transient components not being initialised

This commit is contained in:
Sollace 2024-10-03 19:56:43 +01:00
parent 214acef12c
commit 7de1675a82
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
2 changed files with 30 additions and 30 deletions

View file

@ -21,7 +21,7 @@ import net.minecraft.util.Util;
public class TransientComponentMap {
private static final BiFunction<ItemStack, ?, ?> 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<ComponentType<?>, BiFunction<ItemStack, ?, ?>> components = new HashMap<>();
@Nullable
private final TransientComponentMap parent;
private Map<ComponentType<?>, BiFunction<ItemStack, ?, ?>> components;
private Optional<Entity> carrier = Optional.empty();
private TransientComponentMap() {}
private TransientComponentMap(TransientComponentMap parent) {
this.parent = parent;
if (parent == null) {
components = new HashMap<>();
}
}
public Optional<Entity> getCarrier() {
return carrier;
@ -71,18 +78,25 @@ public class TransientComponentMap {
}
public <T> void set(ComponentType<? extends T> type, BiFunction<ItemStack, T, T> getter) {
if (components == null) {
components = parent == null ? new HashMap<>() : new HashMap<>(parent.components);
}
components.put(type, getter);
}
@SuppressWarnings("unchecked")
public <T> T get(ComponentType<? extends T> type, ItemStack stack, T upstreamValue) {
if (components != null) {
return ((BiFunction<ItemStack, T, T>)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 {

View file

@ -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 <T extends TooltipAppender> void appendTooltip(
ComponentType<T> componentType, Item.TooltipContext context, Consumer<Text> textConsumer, TooltipType type
);
private final Supplier<TransientComponentMap> 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<TypedActionResult<ItemStack>> info) {
transientComponents.setCarrier(user);
getTransientComponents().setCarrier(user);
TypedActionResult<ItemStack> 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<ItemStack> 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<List<Text>> 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<List<Text>> 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<List<Text>> info) {
getTransientComponents().setCarrier(null);
}
@Inject(method = "takesDamageFrom", at = @At("HEAD"))