Add API to get transformed block (#28)

This commit is contained in:
DarkShadow44 authored and GitHub committed 2026-11-01 12:35:57 +01:00
1 parent 82349735e4
commit e590bbfb61
3 files changed
+78

No files matched your search

@@ -0,0 +1,22 @@
package com.gtnewhorizons.postea.api;
/**
* A block referenced by its namespaced id, together with a meta value. Returned by
* {@link BlockReplacementManager#transformBlock(String, int)}.
*/
public final class BlockNameAndMeta {
/**
* The namespaced id of the block.
*/
public final String name;
/**
* The meta value of the block.
*/
public final int metadata;
public BlockNameAndMeta(String name, int metadata) {
this.name = name;
this.metadata = metadata;
}
}
@@ -3,6 +3,7 @@ package com.gtnewhorizons.postea.api;
import java.util.function.Consumer;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraftforge.oredict.OreDictionary;
@@ -54,6 +55,32 @@ public abstract class BlockReplacementManager {
// endregion custom transformer registration
// region lookup
/**
* Runs the block transformers registered for the given id on a block that isn't placed in the world, and returns
* what it would be transformed into.<br>
* <br>
* This is meant for mods that store blocks by their namespaced id inside their own NBT (e.g.: blocks that are
* made out of other blocks), which Postea can't reach while converting chunks. Calling this when such a block is
* loaded applies every migration registered to Postea to it.
*
* @apiNote Only call this while a world is loaded, transformers rely on the numeric ids resolved for that world.
* The transformers are given a {@link com.gtnewhorizons.postea.utility.BlockConversionInfo} without a
* world, and with all coordinates set to 0. Tile entity transformers are not run.
*
* @param name The namespaced id of the block.
* @param metadata The meta value of the block.
* @return The namespaced id and meta value of the block to use instead, or null if no transformer applies.
*/
@SuppressWarnings("unused")
public static @Nullable BlockNameAndMeta transformBlock(@Nonnull String name, int metadata) {
if (name == null) throw new NullPointerException("name cannot be null");
return TransformerRegistry.transformBlock(name, metadata);
}
// endregion lookup
// region id resolving
// spotless:off
@@ -6,6 +6,7 @@ import java.util.List;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
@@ -13,6 +14,7 @@ import net.minecraft.world.chunk.Chunk;
import org.apache.commons.lang3.tuple.Pair;
import com.google.common.collect.LinkedListMultimap;
import com.gtnewhorizons.postea.api.BlockNameAndMeta;
import com.gtnewhorizons.postea.api.IBlockTransformationHandler;
import com.gtnewhorizons.postea.api.IDExtenderCompat;
import com.gtnewhorizons.postea.api.IItemStackTransformationHandler;
@@ -20,6 +22,7 @@ import com.gtnewhorizons.postea.api.TriFunction;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.LoaderState;
import cpw.mods.fml.common.registry.GameData;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
/**
@@ -156,6 +159,32 @@ public class TransformerRegistry {
return null;
}
public static @Nullable BlockNameAndMeta transformBlock(@Nonnull String name, int metadata) {
List<IBlockTransformationHandler> handlers = BLOCK_REPLACEMENT_MAP.get(name);
if (handlers.isEmpty()) return null;
// there is no position nor world, the block isn't placed anywhere
BlockConversionInfo blockConversionInfo = new BlockConversionInfo(
name,
IDRegistry.getBlockId(name),
metadata,
0,
0,
0,
null);
for (IBlockTransformationHandler transformer : handlers) {
if (transformer.apply(blockConversionInfo)) {
Block block = GameData.getBlockRegistry()
.getRaw(blockConversionInfo.blockID);
if (block == null) return null;
return new BlockNameAndMeta(
GameData.getBlockRegistry()
.getNameForObject(block),
blockConversionInfo.metadata);
}
}
return null;
}
public static void transformItem(NBTTagCompound tag) {
// abort early if tag is bad.
if (tag.hasNoTags() || !tag.hasKey("id")) return;