add helper functions to api to stream development

This commit is contained in:
Guillaume Mercier committed 2026-01-20 18:06:33 -05:00
1 parent 5c524c2461
commit 1f5a792ceb
6 files changed
+462 -19

No files matched your search

@@ -37,6 +37,7 @@ public class Postea {
@Mod.EventHandler
public void onLoadCompleted(FMLLoadCompleteEvent event) {
TransformerRegistry.onLoadCompleted();
MissingMappingHandler.onLoadCompleted();
}
@@ -2,9 +2,14 @@ package com.gtnewhorizons.postea.api;
import java.util.function.BiFunction;
import javax.annotation.Nonnull;
import net.minecraft.block.Block;
import net.minecraft.world.World;
import net.minecraftforge.oredict.OreDictionary;
import com.gtnewhorizons.postea.utility.BlockConversionInfo;
import com.gtnewhorizons.postea.utility.MissingMappingHandler;
import com.gtnewhorizons.postea.utility.TransformerRegistry;
public class BlockReplacementManager {
@@ -12,12 +17,149 @@ public class BlockReplacementManager {
/**
* Adds a custom transformer for a given id.
*
* @param blockNameIn The id of the block to transform.
* @param originalId The id of the block to transform.
* @param transformer The transformer to apply.
*/
@SuppressWarnings("unused")
public static void addBlockReplacement(String blockNameIn,
BiFunction<BlockConversionInfo, World, BlockConversionInfo> transformer) {
TransformerRegistry.addBlockReplacement(blockNameIn, transformer);
public static void addBlockReplacement(@Nonnull String originalId,
@Nonnull BiFunction<BlockConversionInfo, World, BlockConversionInfo> transformer) {
if (originalId == null) throw new IllegalArgumentException("original id is null");
if (transformer == null) throw new IllegalArgumentException("transformer is null");
TransformerRegistry.addBlockReplacement(originalId, transformer);
}
/**
* Adds a mapping to remap stacks and block instances of a specific removed block to the given block whilst, whilst
* maintaining its meta value.
* <p>
* <b><u>IMPORTANT: This only works if the world does not have an existing id set for the target block. If you need
* to transform a missing block into something that was previously given an id (e.g.: Transforming a removed block
* into dirt), use {@link #addBlockReplacement(String, Block)} with both meta parameters set to
* OreDictionary.WILDCARD_VALUE.</u></b>
*
* @param originalId The id of the block to remap.
* @param block The block to remap to.
*/
@SuppressWarnings("unused")
public static void replaceMissingBlockWithNewBlock(@Nonnull String originalId, @Nonnull Block block) {
if (originalId == null) throw new IllegalArgumentException("original id is null");
if (block == null) throw new IllegalArgumentException("block is null");
MissingMappingHandler.addSimpleReplacement(originalId, block);
}
/**
* Suppresses any missing mapping warning for the given id.
* @param originalId The id of the block or item to suppress the warning for.
*/
@SuppressWarnings("unused")
public static void ignoreMissingMapping(@Nonnull String originalId) {
MissingMappingHandler.addIgnore(originalId);
}
// block -> block
/**
* Adds a mapping to remap all stacks and block instances of a given block to another block, whilst maintaining its
* meta value. This also adds a matching item stack replacement.
*
* @apiNote Use this if you are replacing a block with something that was already registered to a world's id
* mappings,
* (e.g.: Transforming a removed block into dirt)
*
* @param originalId The id of the item to remap.
* @param block The block to remap to.
*/
@SuppressWarnings("unused")
public static void addBlockReplacement(@Nonnull String originalId, @Nonnull Block block) {
addBlockReplacement(originalId, OreDictionary.WILDCARD_VALUE, block, OreDictionary.WILDCARD_VALUE, false);
}
/**
* Adds a mapping to remap all stacks and block instances of a given block to another block, whilst maintaining its
* meta value.
*
* @apiNote Use this if you are replacing an item with something that was already registered to a world's id
* mappings,
* (e.g.: Transforming a removed block into dirt)
*
* @param originalId The id of the item to remap.
* @param block The block to remap to.
* @param skipStackRemap Set to true to skip auto-adding an item stack remapper.
*/
@SuppressWarnings("unused")
public static void addBlockReplacement(@Nonnull String originalId, @Nonnull Block block, boolean skipStackRemap) {
addBlockReplacement(
originalId,
OreDictionary.WILDCARD_VALUE,
block,
OreDictionary.WILDCARD_VALUE,
skipStackRemap);
}
// block -> block+meta
/**
* Adds a mapping to remap all stacks and block instances of a given block to another block with a given damage/meta
* value. This also adds a matching item stack replacement.
*
* @param originalId The id of the block to remap.
* @param block The block to remap to.
* @param newMeta The meta of the block to remap to. OreDictionary.WILDCARD_VALUE maintains the existing value.
*/
@SuppressWarnings("unused")
public static void addBlockReplacement(@Nonnull String originalId, @Nonnull Block block, int newMeta) {
addBlockReplacement(originalId, OreDictionary.WILDCARD_VALUE, block, newMeta, false);
}
/**
* Adds a mapping to remap all stacks and block instances of a given block to another block with a given damage/meta
* value.
*
* @param originalId The id of the block to remap.
* @param block The block to remap to.
* @param newMeta The meta of the block to remap to. OreDictionary.WILDCARD_VALUE maintains the existing
* value.
* @param skipStackRemap Set to true to skip auto-adding an item stack remapper.
*/
@SuppressWarnings("unused")
public static void addBlockReplacement(@Nonnull String originalId, @Nonnull Block block, int newMeta,
boolean skipStackRemap) {
addBlockReplacement(originalId, OreDictionary.WILDCARD_VALUE, block, newMeta, skipStackRemap);
}
// block+meta -> block+meta
/**
* Adds a mapping to remap all stacks and block instances of a given block and damage/meta value to another block
* with a given damage/meta value. This also adds a matching item stack replacement.
*
* @param originalId The id of the block to remap.
* @param originalMeta The meta of the block to remap. OreDictionary.WILDCARD_VALUE acts as a wildcard.
* @param block The block to remap to.
* @param newMeta The meta of the block to remap to. OreDictionary.WILDCARD_VALUE maintains the existing value.
*/
@SuppressWarnings("unused")
public static void addBlockReplacement(@Nonnull String originalId, int originalMeta, @Nonnull Block block,
int newMeta) {
addBlockReplacement(originalId, originalMeta, block, newMeta, false);
}
/**
* Adds a mapping to remap all stacks and block instances of a given block and damage/meta value to another block
* with a given damage/meta value.
*
* @param originalId The id of the block to remap.
* @param originalMeta The meta of the block to remap. OreDictionary.WILDCARD_VALUE acts as a wildcard.
* @param block The block to remap to.
* @param newMeta The meta of the block to remap to. OreDictionary.WILDCARD_VALUE maintains the existing
* value.
* @param skipStackRemap Set to true to skip auto-adding an item stack remapper.
*/
@SuppressWarnings("unused")
public static void addBlockReplacement(@Nonnull String originalId, int originalMeta, @Nonnull Block block,
int newMeta, boolean skipStackRemap) {
if (originalId == null) throw new IllegalArgumentException("original id is null");
if (block == null) throw new IllegalArgumentException("block is null");
TransformerRegistry.addSimpleTransformer(originalId, originalMeta, block, newMeta, skipStackRemap);
}
}
@@ -2,7 +2,13 @@ package com.gtnewhorizons.postea.api;
import java.util.function.Function;
import javax.annotation.Nonnull;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.oredict.OreDictionary;
import com.gtnewhorizons.postea.utility.MissingMappingHandler;
import com.gtnewhorizons.postea.utility.TransformerRegistry;
@@ -14,12 +20,176 @@ public class ItemStackReplacementManager {
/**
* Adds a custom transformer for a given id.
*
* @param itemName The id of the item to transform.
* @param originalId The id of the item to transform.
* @param transformer The transformer to apply.
*/
@SuppressWarnings("unused")
public static void addItemReplacement(String itemName, Function<NBTTagCompound, NBTTagCompound> transformer) {
MissingMappingHandler.createDummyItemIfNeeded(itemName);
TransformerRegistry.addItemReplacement(itemName, transformer);
public static void addItemReplacement(@Nonnull String originalId,
@Nonnull Function<NBTTagCompound, NBTTagCompound> transformer) {
if (originalId == null) throw new IllegalArgumentException("original id is null");
if (transformer == null) throw new IllegalArgumentException("transformer is null");
TransformerRegistry.addItemReplacement(originalId, transformer);
}
/**
* Adds a mapping to remap stacks of a specific removed item to the given item.
* <p>
* <b><u>IMPORTANT: This only works if the world does not have an existing id set for the target item. If you need
* to transform a missing item into something that was previously given an id (e.g.: Transforming a removed item
* into a stick), use {@link #addItemReplacement(String, int, Item, int)} with both meta values set to
* OreDictionary.WILDCARD_VALUE.</u></b>
*
* @param originalId The id of the item to remap.
* @param item The item to remap to.
*/
@SuppressWarnings("unused")
public static void replaceMissingItemWithNewItem(@Nonnull String originalId, @Nonnull Item item) {
if (originalId == null) throw new IllegalArgumentException("original id is null");
if (item == null) throw new IllegalArgumentException("item is null");
MissingMappingHandler.addSimpleReplacement(originalId, item);
}
/**
* Suppresses any missing mapping warning for the given id.
* @param originalId The id of the block or item to suppress the warning for.
*/
@SuppressWarnings("unused")
public static void ignoreMissingMapping(@Nonnull String originalId) {
MissingMappingHandler.addIgnore(originalId);
}
// item -> item
/**
* Adds a mapping to remap stacks of a given item to another item, whilst maintaining its damage/meta value. This
* also adds a matching block replacement if this item happens to be an ItemBlock.
*
* @apiNote Use this if you are replacing an item with something that was already registered to a world's id
* mappings,
* (e.g.: Transforming a removed item into a stick)
*
* @param originalId The id of the item to remap.
* @param item The item to remap to.
*/
@SuppressWarnings("unused")
public static void addItemReplacement(@Nonnull String originalId, @Nonnull Item item) {
addItemReplacement(originalId, OreDictionary.WILDCARD_VALUE, item, OreDictionary.WILDCARD_VALUE, false);
}
/**
* Adds a mapping to remap stacks of a given item to another item, whilst maintaining its damage/meta value.
*
* @apiNote Use this if you are replacing an item with something that was already registered to a world's id
* mappings,
* (e.g.: Transforming a removed item into a stick)
*
* @param originalId The id of the item to remap.
* @param item The item to remap to.
* @param skipBlockRemap Set to true to skip auto-adding a block remapper if the item happens to be an ItemBlock.
*/
@SuppressWarnings("unused")
public static void addItemReplacement(@Nonnull String originalId, @Nonnull Item item, boolean skipBlockRemap) {
addItemReplacement(
originalId,
OreDictionary.WILDCARD_VALUE,
item,
OreDictionary.WILDCARD_VALUE,
skipBlockRemap);
}
// item -> item+meta
/**
* Adds a mapping to remap stacks of a given item to another item with a given damage/meta value. This also adds a
* matching block replacement if this item happens to be an ItemBlock.
*
* @param originalId The id of the item to remap.
* @param item The item to remap to.
* @param newMeta The meta of the item to remap to. OreDictionary.WILDCARD_VALUE maintains the existing value.
*/
@SuppressWarnings("unused")
public static void addItemReplacement(@Nonnull String originalId, @Nonnull Item item, int newMeta) {
addItemReplacement(originalId, OreDictionary.WILDCARD_VALUE, item, newMeta, false);
}
/**
* Adds a mapping to remap stacks of a given item to another item with a given damage/meta value.
*
* @param originalId The id of the item to remap.
* @param item The item to remap to.
* @param newMeta The meta of the item to remap to. OreDictionary.WILDCARD_VALUE maintains the existing
* value.
* @param skipBlockRemap Set to true to skip auto-adding a block remapper if the item happens to be an ItemBlock.
*/
@SuppressWarnings("unused")
public static void addItemReplacement(@Nonnull String originalId, @Nonnull Item item, int newMeta,
boolean skipBlockRemap) {
addItemReplacement(originalId, OreDictionary.WILDCARD_VALUE, item, newMeta, skipBlockRemap);
}
// item+meta -> stack
/**
* Adds a mapping to remap all stacks of a given item and damage/meta value to another item with a
* given damage/meta value. This also adds a matching block replacement if this item happens to be an ItemBlock.
*
* @param originalId The id of the item to remap.
* @param originalMeta The meta of the item to remap. OreDictionary.WILDCARD_VALUE acts as a wildcard.
* @param stack A stack of the item to replace to.
*/
@SuppressWarnings("unused")
public static void addItemReplacement(@Nonnull String originalId, int originalMeta, @Nonnull ItemStack stack) {
addItemReplacement(originalId, originalMeta, stack, false);
}
/**
* Adds a mapping to remap all stacks of a given item and damage/meta value to another item with a
* given damage/meta value.
*
* @param originalId The id of the item to remap.
* @param originalMeta The meta of the item to remap. OreDictionary.WILDCARD_VALUE acts as a wildcard.
* @param stack A stack of the item to replace to.
* @param skipBlockRemap Set to true to skip auto-adding a block remapper if the item happens to be an ItemBlock.
*/
@SuppressWarnings("unused")
public static void addItemReplacement(@Nonnull String originalId, int originalMeta, @Nonnull ItemStack stack,
boolean skipBlockRemap) {
addItemReplacement(originalId, originalMeta, stack.getItem(), Items.feather.getDamage(stack), skipBlockRemap);
}
// item+meta -> item+meta
/**
* Adds a mapping to remap all stacks of a given item and damage/meta value to another item with a
* given damage/meta value. This also adds a matching block replacement if this item happens to be an ItemBlock.
*
* @param originalId The id of the item to remap.
* @param originalMeta The meta of the item to remap. OreDictionary.WILDCARD_VALUE acts as a wildcard.
* @param item The item to remap to.
* @param newMeta The meta of the item to remap to. OreDictionary.WILDCARD_VALUE maintains the existing value.
*/
@SuppressWarnings("unused")
public static void addItemReplacement(@Nonnull String originalId, int originalMeta, @Nonnull Item item,
int newMeta) {
addItemReplacement(originalId, originalMeta, item, newMeta, false);
}
/**
* Adds a mapping to remap all stacks of a given item and damage/meta value to another item with a
* given damage/meta value.
*
* @param originalId The id of the item to remap.
* @param originalMeta The meta of the item to remap. OreDictionary.WILDCARD_VALUE acts as a wildcard.
* @param item The item to remap to.
* @param newMeta The meta of the item to remap to. OreDictionary.WILDCARD_VALUE maintains the existing
* value.
* @param skipBlockRemap Set to true to skip auto-adding a item remapper if the .
*/
@SuppressWarnings("unused")
public static void addItemReplacement(String originalId, int originalMeta, Item item, int newMeta,
boolean skipBlockRemap) {
if (originalId == null) throw new IllegalArgumentException("original id is null");
if (item == null) throw new IllegalArgumentException("item is null");
TransformerRegistry.addSimpleTransformer(originalId, originalMeta, item, newMeta, skipBlockRemap);
}
}
@@ -1,7 +1,9 @@
package com.gtnewhorizons.postea.utility;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
@@ -18,6 +20,7 @@ import cpw.mods.fml.common.registry.GameRegistry;
public abstract class MissingMappingHandler {
enum MappingType {
/** Tells the mapping logic to register an Item. */
Item,
@@ -59,6 +62,7 @@ public abstract class MissingMappingHandler {
}
}
private static final Set<String> MISSING_IDS_TO_IGNORE = new HashSet<>();
private static final HashMap<String, Item> MISSING_ITEM_MAPPINGS = new HashMap<>();
private static final HashMap<String, Block> MISSING_BLOCK_MAPPINGS = new HashMap<>();
private static final HashMap<String, DummyMapping> DUMMY_TARGET_TYPES = new HashMap<>();
@@ -101,8 +105,8 @@ public abstract class MissingMappingHandler {
public static void onMissingMapping(FMLMissingMappingsEvent event) {
for (FMLMissingMappingsEvent.MissingMapping mapping : event.getAll()) {
if (mapping.name.startsWith(DUMMY_ID_PREFIX)) {
// for when a migrator ceases being registered, likely due to a removal.
// ignore things that can be ignored safely, and our own dummy items for when a handler is removed.
if (MISSING_IDS_TO_IGNORE.contains(mapping.name) || mapping.name.startsWith(DUMMY_ID_PREFIX)) {
mapping.ignore();
continue;
}
@@ -126,9 +130,6 @@ public abstract class MissingMappingHandler {
}
}
}
// no longer needed free what ever used to be in there
MISSING_BLOCK_MAPPINGS.clear();
MISSING_ITEM_MAPPINGS.clear();
}
private static void onMappingAdded(String originalId, MappingType mappingType) {
@@ -150,6 +151,18 @@ public abstract class MissingMappingHandler {
}
}
public static void addSimpleReplacement(String originalId, Item item) {
MISSING_ITEM_MAPPINGS.put(originalId, item);
}
public static void addSimpleReplacement(String originalId, Block block) {
MISSING_BLOCK_MAPPINGS.put(originalId, block);
}
public static void addIgnore(String originalId) {
MISSING_IDS_TO_IGNORE.add(originalId);
}
public static void createDummyBlockIfNeeded(String originalId) {
DummyMapping existing = DUMMY_TARGET_TYPES.get(originalId);
// item mappings should be over-written
@@ -0,0 +1,54 @@
package com.gtnewhorizons.postea.utility;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
import net.minecraftforge.oredict.OreDictionary;
import org.apache.commons.lang3.tuple.Pair;
public class SimpleTransformationMap {
private final Map<String, Map<Integer, Pair<Integer, Short>>> registry = new HashMap<>();
/**
* Puts a mapping in this registry.
*
* @param originalId The original id of the item/block to replace.
* @param originalMeta The metadata of the item/block to replace. OreDictionary.WILDCARD_VALUE can be used as a
* wildcard.
* @param newId The id of the replacement block/item.
* @param newMeta The new meta of the block to block/item.
*/
public void put(String originalId, int originalMeta, int newId, int newMeta) {
if (originalMeta == -1) originalMeta = OreDictionary.WILDCARD_VALUE;
if (newMeta == -1) newMeta = OreDictionary.WILDCARD_VALUE;
this.registry.computeIfAbsent(originalId, k -> new HashMap<>())
.put(originalMeta, Pair.of(newId, (short) newMeta));
}
/**
* Gets the mapping from the registry.
*
* @param id The id of the item/block to replace.
* @param meta The meta of the item/block to replace.
* @return The new id and meta for the item/block if found.
*/
public @Nullable Pair<Integer, Short> get(String id, int meta) {
Map<Integer, Pair<Integer, Short>> metaMap = this.registry.get(id);
if (metaMap == null) return null;
Pair<Integer, Short> mapping = metaMap.get(meta);
if (mapping != null) return mapping;
return metaMap.get(OreDictionary.WILDCARD_VALUE);
}
/**
* @return the set of all registered item ids.
*/
public Set<String> keySet() {
return this.registry.keySet();
}
}
@@ -4,11 +4,19 @@ import java.util.Collection;
import java.util.function.BiFunction;
import java.util.function.Function;
import javax.annotation.Nullable;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.world.World;
import net.minecraftforge.oredict.OreDictionary;
import org.apache.commons.lang3.tuple.Pair;
import com.google.common.collect.LinkedListMultimap;
import com.gtnewhorizons.postea.api.IDExtenderCompat;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
@@ -20,15 +28,70 @@ public class TransformerRegistry {
.create();
public static final IntOpenHashSet POSTEA_MARKED_IDS = new IntOpenHashSet();
public static void addBlockReplacement(String blockNameIn,
public static final SimpleTransformationMap SIMPLE_ITEM_TRANSFORMATION_MAP = new SimpleTransformationMap();
public static final SimpleTransformationMap SIMPLE_BLOCK_TRANSFORMATION_MAP = new SimpleTransformationMap();
public static void addBlockReplacement(String originalId,
BiFunction<BlockConversionInfo, World, BlockConversionInfo> transformer) {
MissingMappingHandler.createDummyBlockIfNeeded(blockNameIn);
BLOCK_REPLACEMENT_MAP.put(blockNameIn, transformer);
MissingMappingHandler.createDummyBlockIfNeeded(originalId);
BLOCK_REPLACEMENT_MAP.put(originalId, transformer);
}
public static void addItemReplacement(String itemName, Function<NBTTagCompound, NBTTagCompound> transformer) {
MissingMappingHandler.createDummyItemIfNeeded(itemName);
ITEM_REPLACEMENT_MAP.put(itemName, transformer);
public static void addItemReplacement(String originalId, Function<NBTTagCompound, NBTTagCompound> transformer) {
MissingMappingHandler.createDummyItemIfNeeded(originalId);
ITEM_REPLACEMENT_MAP.put(originalId, transformer);
}
public static void addSimpleTransformer(String originalId, int originalMeta, Block newBlock, int newMeta,
boolean skipStackRemap) {
SIMPLE_BLOCK_TRANSFORMATION_MAP.put(originalId, originalMeta, Block.getIdFromBlock(newBlock), newMeta);
if (!skipStackRemap) {
Item item = Item.getItemFromBlock(newBlock);
if (item != null) {
SIMPLE_ITEM_TRANSFORMATION_MAP.put(originalId, originalMeta, Item.getIdFromItem(item), newMeta);
}
}
}
public static void addSimpleTransformer(String originalId, int originalMeta, Item newItem, int newMeta,
boolean skipBlockRemap) {
if (!skipBlockRemap && newItem instanceof ItemBlock ib) {
SIMPLE_BLOCK_TRANSFORMATION_MAP
.put(originalId, originalMeta, Block.getIdFromBlock(ib.field_150939_a), newMeta);
}
SIMPLE_ITEM_TRANSFORMATION_MAP.put(originalId, originalMeta, Item.getIdFromItem(newItem), newMeta);
}
public static void onLoadCompleted() {
for (String originalId : SIMPLE_BLOCK_TRANSFORMATION_MAP.keySet()) {
MissingMappingHandler.createDummyBlockIfNeeded(originalId);
BLOCK_REPLACEMENT_MAP.put(originalId, TransformerRegistry::simpleBlockTransformer);
}
for (String originalId : SIMPLE_ITEM_TRANSFORMATION_MAP.keySet()) {
MissingMappingHandler.createDummyItemIfNeeded(originalId);
ITEM_REPLACEMENT_MAP.put(originalId, tag -> simpleItemStackTransformer(tag, originalId));
}
}
private static @Nullable BlockConversionInfo simpleBlockTransformer(BlockConversionInfo info, World world) {
Pair<Integer, Short> mapping = SIMPLE_BLOCK_TRANSFORMATION_MAP.get(info.blockName, info.metadata);
if (mapping == null) return null;
info.blockID = mapping.getKey();
if (mapping.getValue() != OreDictionary.WILDCARD_VALUE) {
info.metadata = mapping.getValue();
}
return info;
}
private static @Nullable NBTTagCompound simpleItemStackTransformer(NBTTagCompound tag, String originalId) {
short damage = tag.getShort("Damage");
Pair<Integer, Short> mapping = SIMPLE_ITEM_TRANSFORMATION_MAP.get(originalId, damage);
if (mapping == null) return null;
IDExtenderCompat.setItemStackID(tag, mapping.getKey());
if (mapping.getValue() != OreDictionary.WILDCARD_VALUE) {
tag.setShort("Damage", mapping.getValue());
}
return tag;
}
public static void onIdMappingsChanged() {