Use POI to find EternalPortalFrame
This commit is contained in:
parent
73b20f88c5
commit
b731ba6598
5 changed files with 221 additions and 13 deletions
84
src/main/java/org/betterx/bclib/api/v2/poi/BCLPoiType.java
Normal file
84
src/main/java/org/betterx/bclib/api/v2/poi/BCLPoiType.java
Normal 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());
|
||||
}
|
||||
}
|
44
src/main/java/org/betterx/bclib/api/v2/poi/PoiRegistry.java
Normal file
44
src/main/java/org/betterx/bclib/api/v2/poi/PoiRegistry.java
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
"NoiseBasedChunkGeneratorMixin",
|
||||
"NoiseGeneratorSettingsMixin",
|
||||
"PistonBaseBlockMixin",
|
||||
"PoiTypesMixin",
|
||||
"PortalShapeMixin",
|
||||
"PotionBrewingAccessor",
|
||||
"PresetEditorMixin",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue