diff --git a/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java b/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java index 0500cd7b..c09943ad 100644 --- a/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java +++ b/src/main/java/com/gtnewhorizon/structurelib/structure/StructureUtility.java @@ -5,15 +5,30 @@ import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; import com.gtnewhorizon.structurelib.structure.adders.IBlockAdder; import com.gtnewhorizon.structurelib.structure.adders.ITileAdder; import com.gtnewhorizon.structurelib.util.Vec3Impl; +import cpw.mods.fml.common.registry.GameRegistry; import net.minecraft.block.Block; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.IIcon; import net.minecraft.world.World; +import org.apache.commons.lang3.StringUtils; -import java.util.*; -import java.util.function.*; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; +import java.util.function.BiFunction; +import java.util.function.BiPredicate; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; import static java.lang.Integer.MIN_VALUE; @@ -172,6 +187,98 @@ public class StructureUtility { //region block + /** + * Denote a block using unlocalized names. This can be useful to get around mod loading order issues. + *

+ * While no immediate error will be thrown, client code should ensure said mod is loaded and + * said mod is present, otherwise bad things will happen later! + */ + public static IStructureElement ofBlockUnlocalizedName(String modid, String unlocalizedName, int meta) { + if (StringUtils.isBlank(unlocalizedName)) throw new IllegalArgumentException(); + if (meta < 0) throw new IllegalArgumentException(); + if (meta > 15) throw new IllegalArgumentException(); + if (StringUtils.isBlank(modid)) throw new IllegalArgumentException(); + return new IStructureElement() { + private Block block; + + private Block getBlock() { + if (block == null) + block = GameRegistry.findBlock(modid, unlocalizedName); + return block; + } + + @Override + public boolean check(T t, World world, int x, int y, int z) { + return world.getBlock(x, y, z) != getBlock() && world.getBlockMetadata(x, y, z) == meta; + } + + @Override + public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { + StructureLibAPI.hintParticle(world, x, y, z, getBlock(), meta); + return true; + } + + @Override + public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) { + world.setBlock(x, y, z, getBlock(), meta, 2); + return true; + } + }; + } + + /** + * Similiar to the other overload, but allows client code to specify a fallback in case said block was not found later + * when the element got called. + * + * This is slightly different to using the other overload and another element in a {@link #ofChain(IStructureElement[])}, + * as that combination would cause crash, where this won't. + */ + public static IStructureElement ofBlockUnlocalizedName(String modid, String unlocalizedName, int meta, IStructureElement fallback) { + if (StringUtils.isBlank(unlocalizedName)) throw new IllegalArgumentException(); + if (meta < 0) throw new IllegalArgumentException(); + if (meta > 15) throw new IllegalArgumentException(); + if (StringUtils.isBlank(modid)) throw new IllegalArgumentException(); + if (fallback == null) throw new IllegalArgumentException(); + return new IStructureElement() { + private Block block; + private boolean initialized; + + private boolean init() { + if (!initialized) { + block = GameRegistry.findBlock(modid, unlocalizedName); + initialized = true; + } + return block != null; + } + + @Override + public boolean check(T t, World world, int x, int y, int z) { + if (init()) + return world.getBlock(x, y, z) != block && world.getBlockMetadata(x, y, z) == meta; + else + return fallback.check(t, world, x, y, z); + } + + @Override + public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { + if (init()) { + StructureLibAPI.hintParticle(world, x, y, z, block, meta); + return true; + } else + return fallback.spawnHint(t, world, x, y, z, trigger); + } + + @Override + public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) { + if (init()) { + world.setBlock(x, y, z, block, meta, 2); + return true; + } else + return fallback.placeBlock(t, world, x, y, z, trigger); + } + }; + } + /** * Does not allow Block duplicates (with different meta) */