From b731ba659802648ab9ca697da383f8292d7efc6e Mon Sep 17 00:00:00 2001 From: Frank Date: Wed, 8 Jun 2022 11:57:48 +0200 Subject: [PATCH] Use POI to find EternalPortalFrame --- .../betterx/bclib/api/v2/poi/BCLPoiType.java | 84 +++++++++++++++++++ .../betterx/bclib/api/v2/poi/PoiRegistry.java | 44 ++++++++++ .../bclib/mixin/common/PoiTypesMixin.java | 45 ++++++++++ .../bclib/particles/BCLParticleType.java | 60 ++++++++++--- src/main/resources/bclib.mixins.common.json | 1 + 5 files changed, 221 insertions(+), 13 deletions(-) create mode 100644 src/main/java/org/betterx/bclib/api/v2/poi/BCLPoiType.java create mode 100644 src/main/java/org/betterx/bclib/api/v2/poi/PoiRegistry.java create mode 100644 src/main/java/org/betterx/bclib/mixin/common/PoiTypesMixin.java diff --git a/src/main/java/org/betterx/bclib/api/v2/poi/BCLPoiType.java b/src/main/java/org/betterx/bclib/api/v2/poi/BCLPoiType.java new file mode 100644 index 00000000..93c8db91 --- /dev/null +++ b/src/main/java/org/betterx/bclib/api/v2/poi/BCLPoiType.java @@ -0,0 +1,84 @@ +package org.betterx.bclib.api.v2.poi; + +import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceKey; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.entity.ai.village.poi.PoiManager; +import net.minecraft.world.entity.ai.village.poi.PoiRecord; +import net.minecraft.world.entity.ai.village.poi.PoiType; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.border.WorldBorder; + +import com.google.common.collect.ImmutableSet; + +import java.util.Comparator; +import java.util.Optional; +import java.util.Set; +import java.util.function.Supplier; + +public class BCLPoiType { + public final ResourceKey key; + public final Supplier> matchingStatesProvider; + public final int maxTickets; + public final int validRange; + + public BCLPoiType(ResourceKey key, + Supplier> matchingStatesProvider, + int maxTickets, + int validRange) { + this.key = key; + this.matchingStatesProvider = matchingStatesProvider; + this.maxTickets = maxTickets; + this.validRange = validRange; + } + + public static Set getBlockStates(Block block) { + return ImmutableSet.copyOf(block.getStateDefinition().getPossibleStates()); + } + + public Optional findPoiAround(ServerLevel level, + BlockPos center, + boolean wideSearch, + WorldBorder worldBorder) { + return findPoiAround(key, level, center, wideSearch, worldBorder); + } + + public Optional findPoiAround(ServerLevel level, + BlockPos center, + int radius, + WorldBorder worldBorder) { + return findPoiAround(key, level, center, radius, worldBorder); + } + + public static Optional findPoiAround( + ResourceKey key, + ServerLevel level, + BlockPos center, + boolean wideSearch, + WorldBorder worldBorder) { + return findPoiAround(key, level, center, wideSearch ? 16 : 128, worldBorder); + } + + public static Optional findPoiAround( + ResourceKey key, + ServerLevel level, + BlockPos center, + int radius, + WorldBorder worldBorder) { + PoiManager poiManager = level.getPoiManager(); + + poiManager.ensureLoadedAndValid(level, center, radius); + Optional record = poiManager + .getInSquare(holder -> holder.is(key), center, radius, PoiManager.Occupancy.ANY) + .filter(poiRecord -> worldBorder.isWithinBounds(poiRecord.getPos())) + .sorted(Comparator.comparingDouble(poiRecord -> poiRecord.getPos().distSqr(center)) + .thenComparingInt(poiRecord -> poiRecord.getPos().getY())) + .filter(poiRecord -> level.getBlockState(poiRecord.getPos()) + .hasProperty(BlockStateProperties.HORIZONTAL_AXIS)) + .findFirst(); + + return record.map(poiRecord -> poiRecord.getPos()); + } +} diff --git a/src/main/java/org/betterx/bclib/api/v2/poi/PoiRegistry.java b/src/main/java/org/betterx/bclib/api/v2/poi/PoiRegistry.java new file mode 100644 index 00000000..09d21e8d --- /dev/null +++ b/src/main/java/org/betterx/bclib/api/v2/poi/PoiRegistry.java @@ -0,0 +1,44 @@ +package org.betterx.bclib.api.v2.poi; + +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.ai.village.poi.PoiType; +import net.minecraft.world.level.block.state.BlockState; + +import com.google.common.collect.ImmutableList; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.function.Supplier; + +public class PoiRegistry { + @FunctionalInterface + public interface OnBootstrap { + void run(); + } + + private final static List KNOWN_TYPES = new ArrayList<>(4); + private final static List KNOW = new ArrayList<>(4); + + public static void registerForBootstrap(OnBootstrap callback) { + KNOW.add(callback); + } + + public static BCLPoiType register(ResourceLocation location, + Supplier> supplier, + int maxTickets, + int validRange) { + ResourceKey key = ResourceKey.create(Registry.POINT_OF_INTEREST_TYPE_REGISTRY, location); + + BCLPoiType type = new BCLPoiType(key, supplier, maxTickets, validRange); + KNOWN_TYPES.add(type); + return type; + } + + public static List getCustomPOIs() { + for (OnBootstrap bootstrap : KNOW) bootstrap.run(); + return ImmutableList.copyOf(KNOWN_TYPES); + } +} diff --git a/src/main/java/org/betterx/bclib/mixin/common/PoiTypesMixin.java b/src/main/java/org/betterx/bclib/mixin/common/PoiTypesMixin.java new file mode 100644 index 00000000..6b377a96 --- /dev/null +++ b/src/main/java/org/betterx/bclib/mixin/common/PoiTypesMixin.java @@ -0,0 +1,45 @@ +package org.betterx.bclib.mixin.common; + +import net.minecraft.core.Holder; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; +import net.minecraft.world.entity.ai.village.poi.PoiType; +import net.minecraft.world.entity.ai.village.poi.PoiTypes; +import net.minecraft.world.level.block.state.BlockState; + +import org.betterx.bclib.api.v2.poi.BCLPoiType; +import org.betterx.bclib.api.v2.poi.PoiRegistry; +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.CallbackInfoReturnable; + +import java.util.List; +import java.util.Set; + +@Mixin(PoiTypes.class) +public abstract class PoiTypesMixin { + + @Shadow + protected static PoiType register(Registry registry, + ResourceKey resourceKey, + Set set, + int i, + int j) { + throw new RuntimeException("Just a Shadow."); + } + + @Shadow + protected static void registerBlockStates(Holder holder) { + throw new RuntimeException("Just a Shadow."); + } + + @Inject(method = "bootstrap", at = @At(value = "HEAD")) + private static void bcl_bootstrap(Registry registry, CallbackInfoReturnable cir) { + List list = PoiRegistry.getCustomPOIs(); + for (BCLPoiType type : list) { + register(registry, type.key, type.matchingStatesProvider.get(), type.maxTickets, type.validRange); + } + } +} diff --git a/src/main/java/org/betterx/bclib/particles/BCLParticleType.java b/src/main/java/org/betterx/bclib/particles/BCLParticleType.java index 69b5f567..d9a5f698 100644 --- a/src/main/java/org/betterx/bclib/particles/BCLParticleType.java +++ b/src/main/java/org/betterx/bclib/particles/BCLParticleType.java @@ -1,14 +1,48 @@ package org.betterx.bclib.particles; import net.minecraft.core.Registry; +import net.minecraft.core.particles.ParticleOptions; +import net.minecraft.core.particles.ParticleType; import net.minecraft.core.particles.SimpleParticleType; import net.minecraft.resources.ResourceLocation; import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry; +import com.mojang.serialization.Codec; + public class BCLParticleType { - public static SimpleParticleType simple(boolean alwaysSpawn) { - return new SimpleParticleType(alwaysSpawn) { + + public static ParticleType deserializer(ParticleOptions.Deserializer factory, + Codec codec) { + return deserializer(false, factory, codec); + } + + public static ParticleType deserializer(boolean overrideLimiter, + ParticleOptions.Deserializer factory, + Codec codec) { + return new ParticleType(overrideLimiter, factory) { + @Override + public Codec codec() { + return codec; + } + }; + } + + public static ParticleType register(ResourceLocation location, + ParticleOptions.Deserializer factory, + Codec codec) { + return register(location, false, factory, codec); + } + + public static ParticleType register(ResourceLocation location, + boolean overrideLimiter, + ParticleOptions.Deserializer factory, + Codec codec) { + return Registry.register(Registry.PARTICLE_TYPE, location, deserializer(overrideLimiter, factory, codec)); + } + + public static SimpleParticleType simple(boolean overrideLimiter) { + return new SimpleParticleType(overrideLimiter) { }; } @@ -16,23 +50,23 @@ public class BCLParticleType { return simple(false); } - public static SimpleParticleType registerSimple(ResourceLocation location) { - return registerSimple(location, false); + public static SimpleParticleType register(ResourceLocation location) { + return register(location, false); } - public static SimpleParticleType registerSimple(ResourceLocation location, boolean alwaysSpawn) { - return Registry.register(Registry.PARTICLE_TYPE, location, simple(alwaysSpawn)); + public static SimpleParticleType register(ResourceLocation location, boolean overrideLimiter) { + return Registry.register(Registry.PARTICLE_TYPE, location, simple(overrideLimiter)); } - public static SimpleParticleType registerSimple(ResourceLocation location, - ParticleFactoryRegistry.PendingParticleFactory provider) { - return registerSimple(location, false, provider); + public static SimpleParticleType register(ResourceLocation location, + ParticleFactoryRegistry.PendingParticleFactory provider) { + return register(location, false, provider); } - public static SimpleParticleType registerSimple(ResourceLocation location, - boolean alwaysSpawn, - ParticleFactoryRegistry.PendingParticleFactory provider) { - SimpleParticleType type = Registry.register(Registry.PARTICLE_TYPE, location, simple(alwaysSpawn)); + public static SimpleParticleType register(ResourceLocation location, + boolean overrideLimiter, + ParticleFactoryRegistry.PendingParticleFactory provider) { + SimpleParticleType type = Registry.register(Registry.PARTICLE_TYPE, location, simple(overrideLimiter)); ParticleFactoryRegistry.getInstance().register(type, provider); return type; } diff --git a/src/main/resources/bclib.mixins.common.json b/src/main/resources/bclib.mixins.common.json index 49b27c46..1c181d99 100644 --- a/src/main/resources/bclib.mixins.common.json +++ b/src/main/resources/bclib.mixins.common.json @@ -27,6 +27,7 @@ "NoiseBasedChunkGeneratorMixin", "NoiseGeneratorSettingsMixin", "PistonBaseBlockMixin", + "PoiTypesMixin", "PortalShapeMixin", "PotionBrewingAccessor", "PresetEditorMixin",