Use POI to find EternalPortalFrame

This commit is contained in:
Frank 2022-06-08 11:57:48 +02:00
parent 73b20f88c5
commit b731ba6598
5 changed files with 221 additions and 13 deletions

View file

@ -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<PoiType> key;
public final Supplier<Set<BlockState>> matchingStatesProvider;
public final int maxTickets;
public final int validRange;
public BCLPoiType(ResourceKey<PoiType> key,
Supplier<Set<BlockState>> matchingStatesProvider,
int maxTickets,
int validRange) {
this.key = key;
this.matchingStatesProvider = matchingStatesProvider;
this.maxTickets = maxTickets;
this.validRange = validRange;
}
public static Set<BlockState> getBlockStates(Block block) {
return ImmutableSet.copyOf(block.getStateDefinition().getPossibleStates());
}
public Optional<BlockPos> findPoiAround(ServerLevel level,
BlockPos center,
boolean wideSearch,
WorldBorder worldBorder) {
return findPoiAround(key, level, center, wideSearch, worldBorder);
}
public Optional<BlockPos> findPoiAround(ServerLevel level,
BlockPos center,
int radius,
WorldBorder worldBorder) {
return findPoiAround(key, level, center, radius, worldBorder);
}
public static Optional<BlockPos> findPoiAround(
ResourceKey<PoiType> key,
ServerLevel level,
BlockPos center,
boolean wideSearch,
WorldBorder worldBorder) {
return findPoiAround(key, level, center, wideSearch ? 16 : 128, worldBorder);
}
public static Optional<BlockPos> findPoiAround(
ResourceKey<PoiType> key,
ServerLevel level,
BlockPos center,
int radius,
WorldBorder worldBorder) {
PoiManager poiManager = level.getPoiManager();
poiManager.ensureLoadedAndValid(level, center, radius);
Optional<PoiRecord> record = poiManager
.getInSquare(holder -> holder.is(key), center, radius, PoiManager.Occupancy.ANY)
.filter(poiRecord -> worldBorder.isWithinBounds(poiRecord.getPos()))
.sorted(Comparator.<PoiRecord>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());
}
}

View file

@ -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<BCLPoiType> KNOWN_TYPES = new ArrayList<>(4);
private final static List<OnBootstrap> KNOW = new ArrayList<>(4);
public static void registerForBootstrap(OnBootstrap callback) {
KNOW.add(callback);
}
public static BCLPoiType register(ResourceLocation location,
Supplier<Set<BlockState>> supplier,
int maxTickets,
int validRange) {
ResourceKey<PoiType> 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<BCLPoiType> getCustomPOIs() {
for (OnBootstrap bootstrap : KNOW) bootstrap.run();
return ImmutableList.copyOf(KNOWN_TYPES);
}
}

View file

@ -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<PoiType> registry,
ResourceKey<PoiType> resourceKey,
Set<BlockState> set,
int i,
int j) {
throw new RuntimeException("Just a Shadow.");
}
@Shadow
protected static void registerBlockStates(Holder<PoiType> holder) {
throw new RuntimeException("Just a Shadow.");
}
@Inject(method = "bootstrap", at = @At(value = "HEAD"))
private static void bcl_bootstrap(Registry<PoiType> registry, CallbackInfoReturnable<PoiType> cir) {
List<BCLPoiType> list = PoiRegistry.getCustomPOIs();
for (BCLPoiType type : list) {
register(registry, type.key, type.matchingStatesProvider.get(), type.maxTickets, type.validRange);
}
}
}

View file

@ -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 <T extends ParticleOptions> ParticleType<T> deserializer(ParticleOptions.Deserializer<T> factory,
Codec<T> codec) {
return deserializer(false, factory, codec);
}
public static <T extends ParticleOptions> ParticleType<T> deserializer(boolean overrideLimiter,
ParticleOptions.Deserializer<T> factory,
Codec<T> codec) {
return new ParticleType<T>(overrideLimiter, factory) {
@Override
public Codec<T> codec() {
return codec;
}
};
}
public static <T extends ParticleOptions> ParticleType<T> register(ResourceLocation location,
ParticleOptions.Deserializer<T> factory,
Codec<T> codec) {
return register(location, false, factory, codec);
}
public static <T extends ParticleOptions> ParticleType<T> register(ResourceLocation location,
boolean overrideLimiter,
ParticleOptions.Deserializer<T> factory,
Codec<T> 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,
public static SimpleParticleType register(ResourceLocation location,
ParticleFactoryRegistry.PendingParticleFactory<SimpleParticleType> provider) {
return registerSimple(location, false, provider);
return register(location, false, provider);
}
public static SimpleParticleType registerSimple(ResourceLocation location,
boolean alwaysSpawn,
public static SimpleParticleType register(ResourceLocation location,
boolean overrideLimiter,
ParticleFactoryRegistry.PendingParticleFactory<SimpleParticleType> provider) {
SimpleParticleType type = Registry.register(Registry.PARTICLE_TYPE, location, simple(alwaysSpawn));
SimpleParticleType type = Registry.register(Registry.PARTICLE_TYPE, location, simple(overrideLimiter));
ParticleFactoryRegistry.getInstance().register(type, provider);
return type;
}

View file

@ -27,6 +27,7 @@
"NoiseBasedChunkGeneratorMixin",
"NoiseGeneratorSettingsMixin",
"PistonBaseBlockMixin",
"PoiTypesMixin",
"PortalShapeMixin",
"PotionBrewingAccessor",
"PresetEditorMixin",