refactor SchematicRegistry to use BlockMetaPairs, add fluid and block heuristics
This commit is contained in:
parent
95f13ba439
commit
3eae592b59
10 changed files with 143 additions and 27 deletions
|
@ -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.
|
||||
|
|
|
@ -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>();
|
||||
|
||||
|
@ -94,10 +95,14 @@ public final class SchematicRegistry {
|
|||
}
|
||||
|
||||
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)) {
|
||||
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) {
|
||||
|
|
43
api/buildcraft/api/core/BlockMetaPair.java
Normal file
43
api/buildcraft/api/core/BlockMetaPair.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
@ -234,6 +236,11 @@ public class BuildCraftBuilders extends BuildCraftMod {
|
|||
return result;
|
||||
}
|
||||
|
||||
@Mod.EventHandler
|
||||
public void postInit(FMLPostInitializationEvent evt) {
|
||||
HeuristicBlockDetection.start();
|
||||
}
|
||||
|
||||
@Mod.EventHandler
|
||||
public void init(FMLInitializationEvent evt) {
|
||||
// Register gui handler
|
||||
|
@ -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);
|
||||
|
|
51
common/buildcraft/builders/HeuristicBlockDetection.java
Normal file
51
common/buildcraft/builders/HeuristicBlockDetection.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -77,6 +77,7 @@ 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
|
||||
|
@ -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()) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue