refactor SchematicRegistry to use BlockMetaPairs, add fluid and block heuristics

This commit is contained in:
asiekierka 2014-10-26 11:43:54 +01:00
parent 95f13ba439
commit 3eae592b59
10 changed files with 143 additions and 27 deletions

View file

@ -34,7 +34,6 @@ import buildcraft.api.core.IInvSlot;
* buildcraft.core.schematics.
*/
public abstract class Schematic {
/**
* Blocks are build in various stages, in order to make sure that a block
* can indeed be placed, and that it's unlikely to disturb other blocks.

View file

@ -23,7 +23,8 @@ import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidContainerRegistry;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
import net.minecraftforge.oredict.OreDictionary;
import buildcraft.api.core.BlockMetaPair;
import buildcraft.api.core.JavaTools;
public final class SchematicRegistry {
@ -31,8 +32,8 @@ public final class SchematicRegistry {
public static int BREAK_ENERGY = 100;
public static final int BUILD_ENERGY = 200;
private static final HashMap<Block, SchematicConstructor> schematicBlocks =
new HashMap<Block, SchematicConstructor>();
private static final HashMap<BlockMetaPair, SchematicConstructor> schematicBlocks =
new HashMap<BlockMetaPair, SchematicConstructor>();
private static final HashMap<Class<? extends Entity>, SchematicConstructor> schematicEntities = new HashMap<Class<? extends Entity>, SchematicConstructor>();
@ -92,12 +93,16 @@ public final class SchematicRegistry {
throw new IllegalArgumentException("Could not find matching constructor for class " + clazz);
}
}
public static void registerSchematicBlock(Block block, Class<? extends Schematic> clazz, Object... params) {
if (schematicBlocks.containsKey(block)) {
registerSchematicBlock(block, OreDictionary.WILDCARD_VALUE, clazz, params);
}
public static void registerSchematicBlock(Block block, int meta, Class<? extends Schematic> clazz, Object... params) {
if (schematicBlocks.containsKey(new BlockMetaPair(block, meta))) {
throw new RuntimeException("Block " + Block.blockRegistry.getNameForObject(block) + " is already associated with a schematic.");
}
schematicBlocks.put(block, new SchematicConstructor(clazz, params));
schematicBlocks.put(new BlockMetaPair(block, meta), new SchematicConstructor(clazz, params));
}
public static void registerSchematicEntity(
@ -109,17 +114,27 @@ public final class SchematicRegistry {
schematicEntities.put(entityClass, new SchematicConstructor(schematicClass, params));
}
public static SchematicBlock newSchematicBlock(Block block) {
public static SchematicBlock newSchematicBlock(Block block, int metadata) {
if (block == Blocks.air) {
return null;
}
if (!schematicBlocks.containsKey(block)) {
return null;
BlockMetaPair pairWildcard = new BlockMetaPair(block, OreDictionary.WILDCARD_VALUE);
BlockMetaPair pair = new BlockMetaPair(block, metadata);
SchematicConstructor c = null;
if (schematicBlocks.containsKey(pair)) {
c = schematicBlocks.get(pair);
} else if (schematicBlocks.containsKey(pairWildcard)) {
c = schematicBlocks.get(pairWildcard);
}
if (c == null) {
return null;
}
try {
SchematicConstructor c = schematicBlocks.get(block);
SchematicBlock s = (SchematicBlock) c.newInstance();
s.block = block;
return s;
@ -159,13 +174,14 @@ public final class SchematicRegistry {
return null;
}
public static boolean isSupported(Block block) {
return schematicBlocks.containsKey(block);
public static boolean isSupported(Block block, int metadata) {
return schematicBlocks.containsKey(new BlockMetaPair(block, OreDictionary.WILDCARD_VALUE))
|| schematicBlocks.containsKey(new BlockMetaPair(block, metadata));
}
public static boolean isAllowedForBuilding(Block block) {
public static boolean isAllowedForBuilding(Block block, int metadata) {
String name = Block.blockRegistry.getNameForObject(block);
return isSupported(block) && !blocksForbidden.contains(name) && !modsForbidden.contains(name.split(":", 2)[0]);
return isSupported(block, metadata) && !blocksForbidden.contains(name) && !modsForbidden.contains(name.split(":", 2)[0]);
}
public static void readConfiguration(Configuration conf) {

View file

@ -0,0 +1,43 @@
package buildcraft.api.core;
import net.minecraft.block.Block;
public class BlockMetaPair implements Comparable<BlockMetaPair> {
private int id, meta;
public BlockMetaPair(Block block, int meta) {
this.id = Block.getIdFromBlock(block);
this.meta = meta;
}
public Block getBlock() {
return Block.getBlockById(id);
}
public int meta() {
return meta;
}
@Override
public int hashCode() {
return 17 * meta + id;
}
@Override
public boolean equals(Object other) {
if (other == null || !(other instanceof BlockMetaPair)) {
return false;
}
return ((BlockMetaPair) other).id == id && ((BlockMetaPair) other).meta == meta;
}
@Override
public int compareTo(BlockMetaPair arg) {
if (arg.id != id) {
return (id - arg.id) * 16;
} else {
return (meta - arg.meta);
}
}
}

View file

@ -28,6 +28,7 @@ import cpw.mods.fml.common.Mod;
import cpw.mods.fml.common.event.FMLInitializationEvent;
import cpw.mods.fml.common.event.FMLInterModComms;
import cpw.mods.fml.common.event.FMLMissingMappingsEvent;
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
import cpw.mods.fml.common.event.FMLServerStoppingEvent;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
@ -60,6 +61,7 @@ import buildcraft.builders.BlockPathMarker;
import buildcraft.builders.BuilderProxy;
import buildcraft.builders.EventHandlerBuilders;
import buildcraft.builders.GuiHandler;
import buildcraft.builders.HeuristicBlockDetection;
import buildcraft.builders.ItemBlueprintStandard;
import buildcraft.builders.ItemBlueprintTemplate;
import buildcraft.builders.ItemConstructionMarker;
@ -233,6 +235,11 @@ public class BuildCraftBuilders extends BuildCraftMod {
return result;
}
@Mod.EventHandler
public void postInit(FMLPostInitializationEvent evt) {
HeuristicBlockDetection.start();
}
@Mod.EventHandler
public void init(FMLInitializationEvent evt) {
@ -243,7 +250,6 @@ public class BuildCraftBuilders extends BuildCraftMod {
MinecraftForge.EVENT_BUS.register(new EventHandlerBuilders());
// Standard blocks
SchematicRegistry.registerSchematicBlock(Blocks.snow, SchematicIgnore.class);
SchematicRegistry.registerSchematicBlock(Blocks.tallgrass, SchematicIgnore.class);
SchematicRegistry.registerSchematicBlock(Blocks.double_plant, SchematicIgnore.class);

View file

@ -0,0 +1,51 @@
package buildcraft.builders;
import buildcraft.api.blueprints.SchematicBlock;
import buildcraft.api.blueprints.SchematicFluid;
import buildcraft.api.blueprints.SchematicRegistry;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
import net.minecraftforge.fluids.Fluid;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fluids.FluidStack;
public final class HeuristicBlockDetection {
private HeuristicBlockDetection() {
}
public static void start() {
// Register fluids
for (Fluid f : FluidRegistry.getRegisteredFluids().values()) {
SchematicRegistry.registerSchematicBlock(f.getBlock(), SchematicFluid.class, new FluidStack(f, 1000));
}
// Register blocks
for (Object o : Block.blockRegistry.getKeys()) {
Block block = (Block) Block.blockRegistry.getObject(o);
if (block == null) {
continue;
}
for (int meta = 0; meta < 16; meta++) {
if (!SchematicRegistry.isSupported(block, meta)) {
// Stops dupes with (for instance) ore blocks
try {
if (block.getItemDropped(meta, null, 0) != Item.getItemFromBlock(block)) {
continue;
}
} catch(NullPointerException e) {
// The "null" for Random in getItemDropped stops blocks
// depending on an RNG for deciding the dropped item
// from being autodetected.
}
if (block.hasTileEntity(meta)) {
continue;
}
SchematicRegistry.registerSchematicBlock(block, meta, SchematicBlock.class);
}
}
}
}
}

View file

@ -33,7 +33,7 @@ public class SchematicFactoryBlock extends SchematicFactory<SchematicBlock> {
return s;
} else {
SchematicBlock s = SchematicRegistry.newSchematicBlock(b);
SchematicBlock s = SchematicRegistry.newSchematicBlock(b, nbt.getInteger("blockMeta"));
if (s != null) {
s.readFromNBT(nbt, registry);

View file

@ -77,7 +77,8 @@ public class Blueprint extends BlueprintBase {
public void readFromWorld(IBuilderContext context, TileEntity anchorTile, int x, int y, int z) {
BptContext bptContext = (BptContext) context;
Block block = anchorTile.getWorldObj().getBlock(x, y, z);
int meta = anchorTile.getWorldObj().getBlockMetadata(x, y, z);
if (context.world().isAirBlock(x, y, z)) {
// Although no schematic will be returned for the block "air" by
// the registry, there can be other blocks considered as air. This
@ -85,7 +86,7 @@ public class Blueprint extends BlueprintBase {
return;
}
SchematicBlock slot = SchematicRegistry.newSchematicBlock(block);
SchematicBlock slot = SchematicRegistry.newSchematicBlock(block, meta);
if (slot == null) {
return;
@ -96,9 +97,9 @@ public class Blueprint extends BlueprintBase {
int posZ = (int) (z - context.surroundingBox().pMin().z);
slot.block = block;
slot.meta = anchorTile.getWorldObj().getBlockMetadata(x, y, z);
slot.meta = meta;
if (!SchematicRegistry.isSupported(block)) {
if (!SchematicRegistry.isSupported(block, meta)) {
return;
}
@ -212,7 +213,7 @@ public class Blueprint extends BlueprintBase {
}
if (block != null) {
contents[x][y][z] = SchematicRegistry.newSchematicBlock(block);
contents[x][y][z] = SchematicRegistry.newSchematicBlock(block, cpt.getInteger("blockMeta"));
contents[x][y][z].readFromNBT(cpt, mapping);
if (!contents[x][y][z].doNotUse()) {

View file

@ -95,7 +95,7 @@ public class BptBuilderBlueprint extends BptBuilderBase {
slot.block = Blocks.air;
}
if (!SchematicRegistry.isAllowedForBuilding(slot.block)) {
if (!SchematicRegistry.isAllowedForBuilding(slot.block, slot.meta)) {
continue;
}
@ -131,7 +131,7 @@ public class BptBuilderBlueprint extends BptBuilderBase {
continue;
}
if (!SchematicRegistry.isAllowedForBuilding(slot.block)) {
if (!SchematicRegistry.isAllowedForBuilding(slot.block, slot.meta)) {
continue;
}

View file

@ -113,7 +113,7 @@ public abstract class FillerPattern implements IFillerPattern {
public abstract Template getTemplate (Box box, World world);
public Blueprint getBlueprint (Box box, World world, Block block) {
public Blueprint getBlueprint (Box box, World world, Block block, int meta) {
Blueprint result = new Blueprint (box.sizeX(), box.sizeY(), box.sizeZ());
Template tmpl = getTemplate(box, world);
@ -123,7 +123,7 @@ public abstract class FillerPattern implements IFillerPattern {
for (int z = 0; z < box.sizeZ(); ++z) {
if (tmpl.contents[x][y][z] != null) {
result.contents[x][y][z] = SchematicRegistry
.newSchematicBlock(block);
.newSchematicBlock(block, meta);
}
}

View file

@ -620,7 +620,7 @@ public class TileQuarry extends TileAbstractBuilder implements IMachine, ISidedI
private void initializeBlueprintBuilder() {
Blueprint bpt = ((FillerPattern) FillerManager.registry.getPattern("buildcraft:frame"))
.getBlueprint(box, worldObj, BuildCraftFactory.frameBlock);
.getBlueprint(box, worldObj, BuildCraftFactory.frameBlock, 0);
builder = new BptBuilderBlueprint(bpt, worldObj, box.xMin, yCoord, box.zMin);
stage = Stage.BUILDING;