diff --git a/src/main/java/org/betterx/bclib/api/v2/levelgen/LevelGenEvents.java b/src/main/java/org/betterx/bclib/api/v2/levelgen/LevelGenEvents.java index 348d24d0..ee63198f 100644 --- a/src/main/java/org/betterx/bclib/api/v2/levelgen/LevelGenEvents.java +++ b/src/main/java/org/betterx/bclib/api/v2/levelgen/LevelGenEvents.java @@ -7,6 +7,7 @@ import org.betterx.bclib.api.v2.datafixer.DataFixerAPI; import org.betterx.bclib.api.v2.generator.BCLibEndBiomeSource; import org.betterx.bclib.api.v2.generator.config.BCLEndBiomeSourceConfig; import org.betterx.bclib.api.v2.levelgen.biomes.InternalBiomeAPI; +import org.betterx.bclib.api.v2.poi.PoiManager; import org.betterx.bclib.api.v2.tag.TagAPI; import org.betterx.bclib.registry.PresetsRegistry; import org.betterx.worlds.together.tag.v3.TagManager; @@ -43,6 +44,7 @@ public class LevelGenEvents { WorldEvents.ON_WORLD_LOAD.on(LevelGenEvents::onWorldLoad); WorldEvents.WORLD_REGISTRY_READY.on(LevelGenEvents::onRegistryReady); WorldEvents.ON_FINALIZE_LEVEL_STEM.on(LevelGenEvents::finalizeStem); + WorldEvents.ON_FINALIZED_WORLD_LOAD.on(LevelGenEvents::finalizedWorldLoad); WorldEvents.PATCH_WORLD.on(LevelGenEvents::patchExistingWorld); WorldEvents.ADAPT_WORLD_PRESET.on(LevelGenEvents::adaptWorldPresetSettings); @@ -50,6 +52,7 @@ public class LevelGenEvents { WorldEvents.BEFORE_ADDING_TAGS.on(LevelGenEvents::appplyTags); } + private static void appplyTags( String directory, Map> tagsMap @@ -57,7 +60,6 @@ public class LevelGenEvents { //make sure we include Tags registered by the deprecated API TagAPI.apply(directory, tagsMap); - if (directory.equals(TagManager.BIOMES.directory)) { InternalBiomeAPI._runBiomeTagAdders(); } @@ -156,4 +158,8 @@ public class LevelGenEvents { ) { InternalBiomeAPI.applyModifications(levelStem.generator().getBiomeSource(), dimension); } + + private static void finalizedWorldLoad(WorldGenSettings worldGenSettings) { + PoiManager.updateStates(); + } } 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 index 1722b20e..99a5a0fe 100644 --- a/src/main/java/org/betterx/bclib/api/v2/poi/BCLPoiType.java +++ b/src/main/java/org/betterx/bclib/api/v2/poi/BCLPoiType.java @@ -45,7 +45,7 @@ public class BCLPoiType { } public void setTag(TagKey tag) { - org.betterx.bclib.api.v2.poi.PoiManager.setTag(type, tag); + org.betterx.bclib.api.v2.poi.PoiManager.setTag(key, tag); } public Optional findPoiAround( diff --git a/src/main/java/org/betterx/bclib/api/v2/poi/PoiManager.java b/src/main/java/org/betterx/bclib/api/v2/poi/PoiManager.java index 4d08d9e6..d358eeec 100644 --- a/src/main/java/org/betterx/bclib/api/v2/poi/PoiManager.java +++ b/src/main/java/org/betterx/bclib/api/v2/poi/PoiManager.java @@ -1,7 +1,9 @@ package org.betterx.bclib.api.v2.poi; +import org.betterx.bclib.api.v2.levelgen.biomes.InternalBiomeAPI; import org.betterx.worlds.together.tag.v3.CommonPoiTags; +import net.minecraft.core.Holder; import net.minecraft.core.Registry; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; @@ -11,7 +13,7 @@ import net.minecraft.world.entity.ai.village.poi.PoiTypes; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; -import java.util.Set; +import java.util.*; import org.jetbrains.annotations.ApiStatus; public class PoiManager { @@ -27,10 +29,14 @@ public class PoiManager { } public static void setTag(ResourceKey type, TagKey tag) { - setTag(Registry.POINT_OF_INTEREST_TYPE.get(type), tag); + var oHolder = Registry.POINT_OF_INTEREST_TYPE.getHolder(type); + if (oHolder.isPresent()) { + setTag(oHolder.get().value(), tag); + didAddTagFor(oHolder.get(), tag); + } } - public static void setTag(PoiType type, TagKey tag) { + private static void setTag(PoiType type, TagKey tag) { if ((Object) type instanceof PoiTypeExtension ext) { ext.bcl_setTag(tag); } @@ -40,4 +46,40 @@ public class PoiManager { public static void registerAll() { PoiManager.setTag(PoiTypes.FISHERMAN, CommonPoiTags.FISHERMAN_WORKSTATION); } + + + private static final List> TYPES_WITH_TAGS = new ArrayList<>(4); + private static Map> ORIGINAL_BLOCK_STATES = null; + + private static void didAddTagFor(Holder type, TagKey tag) { + TYPES_WITH_TAGS.remove(type); + if (tag != null) TYPES_WITH_TAGS.add(type); + } + + + @ApiStatus.Internal + public static void updateStates() { + if (ORIGINAL_BLOCK_STATES == null) { + //We have not yet tainted the original states, so we will create a copy now + ORIGINAL_BLOCK_STATES = new HashMap<>(PoiTypes.TYPE_BY_STATE); + } else { + //restore unaltered state + PoiTypes.TYPE_BY_STATE.clear(); + PoiTypes.TYPE_BY_STATE.putAll(ORIGINAL_BLOCK_STATES); + } + + for (Holder type : TYPES_WITH_TAGS) { + if ((Object) type.value() instanceof PoiTypeExtension ex) { + TagKey tag = ex.bcl_getTag(); + if (tag != null) { + var registry = InternalBiomeAPI.worldRegistryAccess().registryOrThrow(tag.registry()); + for (var block : registry.getTagOrEmpty(tag)) { + for (var state : block.value().getStateDefinition().getPossibleStates()) { + PoiTypes.TYPE_BY_STATE.put(state, type); + } + } + } + } + } + } } diff --git a/src/main/java/org/betterx/bclib/api/v2/poi/PoiTypeExtension.java b/src/main/java/org/betterx/bclib/api/v2/poi/PoiTypeExtension.java index ce591461..96063ee1 100644 --- a/src/main/java/org/betterx/bclib/api/v2/poi/PoiTypeExtension.java +++ b/src/main/java/org/betterx/bclib/api/v2/poi/PoiTypeExtension.java @@ -5,4 +5,5 @@ import net.minecraft.world.level.block.Block; public interface PoiTypeExtension { void bcl_setTag(TagKey tag); + TagKey bcl_getTag(); } diff --git a/src/main/java/org/betterx/bclib/mixin/common/PoiTypeMixin.java b/src/main/java/org/betterx/bclib/mixin/common/PoiTypeMixin.java index ab71318a..6a081e01 100644 --- a/src/main/java/org/betterx/bclib/mixin/common/PoiTypeMixin.java +++ b/src/main/java/org/betterx/bclib/mixin/common/PoiTypeMixin.java @@ -16,6 +16,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; public class PoiTypeMixin implements PoiTypeExtension { private TagKey bcl_tag = null; + @Inject(method = "is", cancellable = true, at = @At("HEAD")) void bcl_is(BlockState blockState, CallbackInfoReturnable cir) { if (bcl_tag != null && blockState.is(bcl_tag)) { @@ -26,4 +27,9 @@ public class PoiTypeMixin implements PoiTypeExtension { public void bcl_setTag(TagKey tag) { bcl_tag = tag; } + + public TagKey bcl_getTag() { + return bcl_tag; + } + } diff --git a/src/main/java/org/betterx/worlds/together/world/event/OnFinalizeWorldLoad.java b/src/main/java/org/betterx/worlds/together/world/event/OnFinalizeWorldLoad.java new file mode 100644 index 00000000..053e2295 --- /dev/null +++ b/src/main/java/org/betterx/worlds/together/world/event/OnFinalizeWorldLoad.java @@ -0,0 +1,7 @@ +package org.betterx.worlds.together.world.event; + +import net.minecraft.world.level.levelgen.WorldGenSettings; + +public interface OnFinalizeWorldLoad { + void done(WorldGenSettings settings); +} diff --git a/src/main/java/org/betterx/worlds/together/world/event/WorldBootstrap.java b/src/main/java/org/betterx/worlds/together/world/event/WorldBootstrap.java index 1b3cc98f..857e21eb 100644 --- a/src/main/java/org/betterx/worlds/together/world/event/WorldBootstrap.java +++ b/src/main/java/org/betterx/worlds/together/world/event/WorldBootstrap.java @@ -313,6 +313,8 @@ public class WorldBootstrap { } BCLib.LOGGER.info(output); SurfaceRuleUtil.injectSurfaceRulesToAllDimensions(worldGenSettings); + + WorldEventsImpl.ON_FINALIZED_WORLD_LOAD.emit(e -> e.done(worldGenSettings)); } public static WorldGenSettings enforceInNewWorld(WorldGenSettings worldGenSettings) { diff --git a/src/main/java/org/betterx/worlds/together/world/event/WorldEvents.java b/src/main/java/org/betterx/worlds/together/world/event/WorldEvents.java index fa0ff83a..49f57a17 100644 --- a/src/main/java/org/betterx/worlds/together/world/event/WorldEvents.java +++ b/src/main/java/org/betterx/worlds/together/world/event/WorldEvents.java @@ -6,6 +6,7 @@ public class WorldEvents { public static final Event BEFORE_SERVER_WORLD_LOAD = WorldEventsImpl.BEFORE_SERVER_WORLD_LOAD; public static final Event ON_WORLD_LOAD = WorldEventsImpl.ON_WORLD_LOAD; public static final Event ON_FINALIZE_LEVEL_STEM = WorldEventsImpl.ON_FINALIZE_LEVEL_STEM; + public static final Event ON_FINALIZED_WORLD_LOAD = WorldEventsImpl.ON_FINALIZED_WORLD_LOAD; public static final Event PATCH_WORLD = WorldEventsImpl.PATCH_WORLD; public static final Event ADAPT_WORLD_PRESET = WorldEventsImpl.ADAPT_WORLD_PRESET; diff --git a/src/main/java/org/betterx/worlds/together/world/event/WorldEventsImpl.java b/src/main/java/org/betterx/worlds/together/world/event/WorldEventsImpl.java index cc1e93ab..14818400 100644 --- a/src/main/java/org/betterx/worlds/together/world/event/WorldEventsImpl.java +++ b/src/main/java/org/betterx/worlds/together/world/event/WorldEventsImpl.java @@ -10,6 +10,7 @@ public class WorldEventsImpl { public static final EventImpl ON_WORLD_LOAD = new EventImpl<>(); public static final EventImpl ON_FINALIZE_LEVEL_STEM = new EventImpl<>(); + public static final EventImpl ON_FINALIZED_WORLD_LOAD = new EventImpl<>(); public static final PatchWorldEvent PATCH_WORLD = new PatchWorldEvent(); public static final AdaptWorldPresetSettingEvent ADAPT_WORLD_PRESET = new AdaptWorldPresetSettingEvent(); diff --git a/src/main/resources/bclib.accesswidener b/src/main/resources/bclib.accesswidener index 35c028ec..e38a1964 100644 --- a/src/main/resources/bclib.accesswidener +++ b/src/main/resources/bclib.accesswidener @@ -19,4 +19,7 @@ accessible method net/minecraft/client/gui/screens/worldselection/WorldGenSettin accessible method net/minecraft/world/level/storage/loot/LootPool ([Lnet/minecraft/world/level/storage/loot/entries/LootPoolEntryContainer;[Lnet/minecraft/world/level/storage/loot/predicates/LootItemCondition;[Lnet/minecraft/world/level/storage/loot/functions/LootItemFunction;Lnet/minecraft/world/level/storage/loot/providers/number/NumberProvider;Lnet/minecraft/world/level/storage/loot/providers/number/NumberProvider;)V accessible method net/minecraft/world/entity/ai/village/poi/PoiTypes register (Lnet/minecraft/core/Registry;Lnet/minecraft/resources/ResourceKey;Ljava/util/Set;II)Lnet/minecraft/world/entity/ai/village/poi/PoiType; accessible method net/minecraft/world/level/levelgen/SurfaceRules$SequenceRuleSource (Ljava/util/List;)V -accessible method net/minecraft/core/Registry registerSimple (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/core/Registry$RegistryBootstrap;)Lnet/minecraft/core/Registry; \ No newline at end of file +accessible method net/minecraft/core/Registry registerSimple (Lnet/minecraft/resources/ResourceKey;Lnet/minecraft/core/Registry$RegistryBootstrap;)Lnet/minecraft/core/Registry; + +#Fields +accessible field net/minecraft/world/entity/ai/village/poi/PoiTypes TYPE_BY_STATE Ljava/util/Map; \ No newline at end of file