From 53497c70d658013574ed2123a52778ec5e1f5bb3 Mon Sep 17 00:00:00 2001 From: Sollace Date: Tue, 20 Feb 2024 20:21:16 +0000 Subject: [PATCH] Fix incompatibility with mods that add points of interest containing chests --- .../com/minelittlepony/unicopia/UPOIs.java | 74 +++++++++++++++++-- .../ability/SeaponySonarPulseAbility.java | 6 +- .../mixin/MixinPointOfInterestType.java | 16 ++++ .../mixin/PointOfInterestTypesAccessor.java | 19 +++++ src/main/resources/unicopia.mixin.json | 2 + 5 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 src/main/java/com/minelittlepony/unicopia/mixin/MixinPointOfInterestType.java create mode 100644 src/main/java/com/minelittlepony/unicopia/mixin/PointOfInterestTypesAccessor.java diff --git a/src/main/java/com/minelittlepony/unicopia/UPOIs.java b/src/main/java/com/minelittlepony/unicopia/UPOIs.java index 3a7b07e4..32f82e84 100644 --- a/src/main/java/com/minelittlepony/unicopia/UPOIs.java +++ b/src/main/java/com/minelittlepony/unicopia/UPOIs.java @@ -1,16 +1,78 @@ package com.minelittlepony.unicopia; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import com.minelittlepony.unicopia.mixin.MixinPointOfInterestType; +import com.minelittlepony.unicopia.mixin.PointOfInterestTypesAccessor; + +import net.fabricmc.fabric.api.event.registry.DynamicRegistrySetupCallback; +import net.fabricmc.fabric.api.event.registry.RegistryEntryAddedCallback; import net.fabricmc.fabric.api.object.builder.v1.world.poi.PointOfInterestHelper; import net.minecraft.block.AbstractChestBlock; -import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.ChestBlock; import net.minecraft.registry.Registries; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.util.Identifier; import net.minecraft.world.poi.PointOfInterestType; +import net.minecraft.world.poi.PointOfInterestTypes; public interface UPOIs { - PointOfInterestType CHESTS = PointOfInterestHelper.register(Unicopia.id("chests"), 1, 64, Registries.BLOCK.getEntrySet().stream() - .map(entry -> entry.getValue()) - .filter(b -> b instanceof AbstractChestBlock) - .toArray(Block[]::new)); + Set> CHEST_POINTS_OF_INTEREST = new HashSet<>(); + RegistryKey CHESTS = register(Unicopia.id("chests"), 1, 64, () -> { + return Registries.BLOCK.getEntrySet().stream() + .map(entry -> entry.getValue()) + .filter(b -> b instanceof AbstractChestBlock) + .flatMap(block -> { + List states = block.getStateManager().getStates(); + List> existingTypes = states.stream() + .flatMap(state -> PointOfInterestTypes.getTypeForState(state).stream()) + .flatMap(entry -> entry.getKey().stream()) + .toList(); - static void bootstrap() { } + if (!existingTypes.isEmpty()) { + CHEST_POINTS_OF_INTEREST.addAll(existingTypes); + return Stream.empty(); + } + return states.stream(); + }) + .distinct(); + }); + + static RegistryKey register(Identifier id, int ticketCount, int searchDistance, Supplier> states) { + PointOfInterestType type = PointOfInterestHelper.register(id, ticketCount, searchDistance, List.of()); + ((MixinPointOfInterestType)(Object)type).setStates(new HashSet<>()); + DynamicRegistrySetupCallback.EVENT.register(registries -> { + if (type.blockStates().isEmpty()) { + type.blockStates().addAll(states.get().collect(Collectors.toSet())); + PointOfInterestTypesAccessor.registerStates(Registries.POINT_OF_INTEREST_TYPE.entryOf(CHESTS), type.blockStates()); + } + }); + return RegistryKey.of(RegistryKeys.POINT_OF_INTEREST_TYPE, id); + } + + static boolean isChest(RegistryEntry type) { + return type.getKey().filter(CHEST_POINTS_OF_INTEREST::contains).isPresent(); + } + + static void bootstrap() { + CHEST_POINTS_OF_INTEREST.add(CHESTS); + Registries.POINT_OF_INTEREST_TYPE.getEntrySet().forEach(poi -> { + if (poi.getValue().blockStates().stream().anyMatch(state -> state.getBlock() instanceof ChestBlock)) { + CHEST_POINTS_OF_INTEREST.add(poi.getKey()); + } + }); + RegistryEntryAddedCallback.event(Registries.POINT_OF_INTEREST_TYPE).register((raw, key, value) -> { + if (value.blockStates().stream().anyMatch(state -> state.getBlock() instanceof ChestBlock)) { + CHEST_POINTS_OF_INTEREST.add(RegistryKey.of(RegistryKeys.POINT_OF_INTEREST_TYPE, key)); + } + }); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/SeaponySonarPulseAbility.java b/src/main/java/com/minelittlepony/unicopia/ability/SeaponySonarPulseAbility.java index c4df03a4..95078776 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/SeaponySonarPulseAbility.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/SeaponySonarPulseAbility.java @@ -13,6 +13,8 @@ import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.particle.ParticleUtils; import com.minelittlepony.unicopia.particle.UParticles; + +import net.minecraft.block.ChestBlock; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityGroup; import net.minecraft.entity.LivingEntity; @@ -78,8 +80,8 @@ public class SeaponySonarPulseAbility implements Ability { if (player.asWorld() instanceof ServerWorld sw) { sw.getPointOfInterestStorage().getNearestPosition( - type -> type.value() == UPOIs.CHESTS, - pos -> player.asWorld().getFluidState(pos).isIn(FluidTags.WATER), player.getOrigin(), 64, OccupationStatus.ANY) + UPOIs::isChest, + pos -> player.asWorld().getFluidState(pos).isIn(FluidTags.WATER) && (player.asWorld().getBlockState(pos).getBlock() instanceof ChestBlock), player.getOrigin(), 64, OccupationStatus.ANY) .ifPresent(chestPos -> { emitPing(player, chestPos.toCenterPos(), 20, 0.5F, 2F); }); diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinPointOfInterestType.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinPointOfInterestType.java new file mode 100644 index 00000000..3f772b99 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinPointOfInterestType.java @@ -0,0 +1,16 @@ +package com.minelittlepony.unicopia.mixin; + +import java.util.Set; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Mutable; +import org.spongepowered.asm.mixin.gen.Accessor; +import net.minecraft.block.BlockState; +import net.minecraft.world.poi.PointOfInterestType; + +@Mixin(PointOfInterestType.class) +public interface MixinPointOfInterestType { + @Mutable + @Accessor("blockStates") + void setStates(Set states); +} diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/PointOfInterestTypesAccessor.java b/src/main/java/com/minelittlepony/unicopia/mixin/PointOfInterestTypesAccessor.java new file mode 100644 index 00000000..4d212846 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/mixin/PointOfInterestTypesAccessor.java @@ -0,0 +1,19 @@ +package com.minelittlepony.unicopia.mixin; + +import java.util.Set; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +import net.minecraft.block.BlockState; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.world.poi.PointOfInterestType; +import net.minecraft.world.poi.PointOfInterestTypes; + +@Mixin(PointOfInterestTypes.class) +public interface PointOfInterestTypesAccessor { + @Invoker("registerStates") + static void registerStates(RegistryEntry poiTypeEntry, Set states) { + + } +} diff --git a/src/main/resources/unicopia.mixin.json b/src/main/resources/unicopia.mixin.json index 20a09367..d59bf63e 100644 --- a/src/main/resources/unicopia.mixin.json +++ b/src/main/resources/unicopia.mixin.json @@ -36,6 +36,7 @@ "MixinPlayerEntity", "MixinPlayerInventory", "MixinPlayerManager", + "MixinPointOfInterestType", "MixinPowderSnowBlock", "MixinProjectileEntity", "MixinPufferfishEntity", @@ -53,6 +54,7 @@ "MixinWardenEntity", "MixinWorld", "MixinWorldChunk", + "PointOfInterestTypesAccessor", "trinkets.MixinTrinketSurvivalSlot", "trinkets.MixinTrinketItem", "trinkets.MixinTrinketInventory",