From 545723dc8c564b361b9678b3b9bcfe889c3a265c Mon Sep 17 00:00:00 2001 From: mrp-v2 Date: Mon, 28 Dec 2020 15:17:51 -0500 Subject: [PATCH] Fix modded PointOfInterestType's not populating blockstate map when registered (#7503) --- .../village/PointOfInterestType.java.patch | 30 ++++++++++++ .../minecraftforge/registries/GameData.java | 49 +++++++++++++++++-- 2 files changed, 74 insertions(+), 5 deletions(-) diff --git a/patches/minecraft/net/minecraft/village/PointOfInterestType.java.patch b/patches/minecraft/net/minecraft/village/PointOfInterestType.java.patch index 183e811d0..081dbecc1 100644 --- a/patches/minecraft/net/minecraft/village/PointOfInterestType.java.patch +++ b/patches/minecraft/net/minecraft/village/PointOfInterestType.java.patch @@ -9,3 +9,33 @@ private static final Supplier> field_234168_y_ = Suppliers.memoize(() -> { return Registry.field_218370_L.func_201756_e().map(VillagerProfession::func_221149_b).collect(Collectors.toSet()); }); +@@ -36,7 +36,7 @@ + }).filter((p_234173_0_) -> { + return p_234173_0_.func_177229_b(BedBlock.field_176472_a) == BedPart.HEAD; + }).collect(ImmutableSet.toImmutableSet()); +- private static final Map field_221073_u = Maps.newHashMap(); ++ private static final Map field_221073_u = net.minecraftforge.registries.GameData.getBlockStatePointOfInterestTypeMap(); + public static final PointOfInterestType field_221054_b = func_226360_a_("unemployed", ImmutableSet.of(), 1, field_221071_s, 1); + public static final PointOfInterestType field_221055_c = func_226359_a_("armorer", func_221042_a(Blocks.field_222424_lM), 1, 1); + public static final PointOfInterestType field_221056_d = func_226359_a_("butcher", func_221042_a(Blocks.field_222423_lL), 1, 1); +@@ -112,16 +112,14 @@ + } + + private static PointOfInterestType func_221052_a(PointOfInterestType p_221052_0_) { +- p_221052_0_.field_221075_w.forEach((p_234169_1_) -> { +- PointOfInterestType pointofinteresttype = field_221073_u.put(p_234169_1_, p_221052_0_); +- if (pointofinteresttype != null) { +- throw (IllegalStateException)Util.func_229757_c_(new IllegalStateException(String.format("%s is defined in too many tags", p_234169_1_))); +- } +- }); + return p_221052_0_; + } + + public static Optional func_221047_b(BlockState p_221047_0_) { + return Optional.ofNullable(field_221073_u.get(p_221047_0_)); + } ++ ++ public ImmutableSet getBlockStates() { ++ return ImmutableSet.copyOf(this.field_221075_w); ++ } + } diff --git a/src/main/java/net/minecraftforge/registries/GameData.java b/src/main/java/net/minecraftforge/registries/GameData.java index 67e92e606..5ac47a048 100644 --- a/src/main/java/net/minecraftforge/registries/GameData.java +++ b/src/main/java/net/minecraftforge/registries/GameData.java @@ -51,10 +51,7 @@ import net.minecraft.state.StateContainer; import net.minecraft.stats.StatType; import net.minecraft.tags.TagRegistryManager; import net.minecraft.tileentity.TileEntityType; -import net.minecraft.util.ObjectIntIdentityMap; -import net.minecraft.util.RegistryKey; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.SoundEvent; +import net.minecraft.util.*; import net.minecraft.util.registry.DefaultedRegistry; import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.SimpleRegistry; @@ -115,6 +112,7 @@ public class GameData private static final ResourceLocation BLOCK_TO_ITEM = new ResourceLocation("minecraft:blocktoitemmap"); private static final ResourceLocation BLOCKSTATE_TO_ID = new ResourceLocation("minecraft:blockstatetoid"); + private static final ResourceLocation BLOCKSTATE_TO_POINT_OF_INTEREST_TYPE = new ResourceLocation("minecraft:blockstatetopointofinteresttype"); private static final ResourceLocation SERIALIZER_TO_ENTRY = new ResourceLocation("forge:serializer_to_entry"); private static final ResourceLocation STRUCTURES = new ResourceLocation("minecraft:structures"); @@ -157,7 +155,7 @@ public class GameData // Villagers makeRegistry(VILLAGER_PROFESSIONS, VillagerProfession.class, "none").create(); - makeRegistry(POI_TYPES, PointOfInterestType.class, "unemployed").disableSync().create(); + makeRegistry(POI_TYPES, PointOfInterestType.class, "unemployed").addCallback(PointOfInterestTypeCallbacks.INSTANCE).disableSync().create(); makeRegistry(MEMORY_MODULE_TYPES, c(MemoryModuleType.class), "dummy").disableSync().create(); makeRegistry(SENSOR_TYPES, c(SensorType.class), "dummy").disableSaving().disableSync().create(); makeRegistry(SCHEDULES, Schedule.class).disableSaving().disableSync().create(); @@ -230,6 +228,12 @@ public class GameData { return RegistryManager.ACTIVE.getRegistry(Block.class).getSlaveMap(BLOCKSTATE_TO_ID, ObjectIntIdentityMap.class); } + + @SuppressWarnings("unchecked") + public static Map getBlockStatePointOfInterestTypeMap() + { + return RegistryManager.ACTIVE.getRegistry(PointOfInterestType.class).getSlaveMap(BLOCKSTATE_TO_POINT_OF_INTEREST_TYPE, Map.class); + } @SuppressWarnings("unchecked") public static Map, DataSerializerEntry> getSerializerMap() @@ -615,6 +619,41 @@ public class GameData } } + private static class PointOfInterestTypeCallbacks implements IForgeRegistry.AddCallback , IForgeRegistry.ClearCallback, IForgeRegistry.CreateCallback + { + static final PointOfInterestTypeCallbacks INSTANCE = new PointOfInterestTypeCallbacks(); + + @Override + public void onAdd(IForgeRegistryInternal owner, RegistryManager stage, int id, PointOfInterestType obj, @Nullable PointOfInterestType oldObj) + { + Map map = owner.getSlaveMap(BLOCKSTATE_TO_POINT_OF_INTEREST_TYPE, Map.class); + if (oldObj != null) + { + oldObj.getBlockStates().forEach(map::remove); + } + obj.getBlockStates().forEach((state) -> + { + PointOfInterestType oldType = map.put(state, obj); + if (oldType != null) + { + throw new IllegalStateException(String.format("Point of interest types %s and %s both list %s in their blockstates, this is not allowed. Blockstates can only have one point of interest type each.", oldType, obj, state)); + } + }); + } + + @Override + public void onClear(IForgeRegistryInternal owner, RegistryManager stage) + { + owner.getSlaveMap(BLOCKSTATE_TO_POINT_OF_INTEREST_TYPE, Map.class).clear(); + } + + @Override + public void onCreate(IForgeRegistryInternal owner, RegistryManager stage) + { + owner.setSlaveMap(BLOCKSTATE_TO_POINT_OF_INTEREST_TYPE, new HashMap<>()); + } + } + private static > void loadRegistry(final ResourceLocation registryName, final RegistryManager from, final RegistryManager to, final Class regType, boolean freeze) { ForgeRegistry fromRegistry = from.getRegistry(registryName);