Fix incompatibility with mods that add points of interest containing chests

This commit is contained in:
Sollace 2024-02-20 20:21:16 +00:00
parent 703c8e6d39
commit 53497c70d6
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
5 changed files with 109 additions and 8 deletions

View file

@ -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<RegistryKey<PointOfInterestType>> CHEST_POINTS_OF_INTEREST = new HashSet<>();
RegistryKey<PointOfInterestType> CHESTS = register(Unicopia.id("chests"), 1, 64, () -> {
return Registries.BLOCK.getEntrySet().stream()
.map(entry -> entry.getValue())
.filter(b -> b instanceof AbstractChestBlock)
.flatMap(block -> {
List<BlockState> states = block.getStateManager().getStates();
List<RegistryKey<PointOfInterestType>> 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<PointOfInterestType> register(Identifier id, int ticketCount, int searchDistance, Supplier<Stream<BlockState>> 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<PointOfInterestType> 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));
}
});
}
}

View file

@ -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<Hit> {
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);
});

View file

@ -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<BlockState> states);
}

View file

@ -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<PointOfInterestType> poiTypeEntry, Set<BlockState> states) {
}
}

View file

@ -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",