-
Notifications
You must be signed in to change notification settings - Fork 497
/
BlockHandler.java
187 lines (171 loc) · 5.7 KB
/
BlockHandler.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
package buildcraft.api.builder;
import buildcraft.core.utils.Utils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.world.World;
import net.minecraftforge.common.ForgeDirection;
/**
* BlockHandlers are used to serialize blocks for saving/loading from
* Blueprints.
*
* @author CovertJaguar <http://www.railcraft.info/>
*/
public class BlockHandler {
private static final BlockHandler DEFAULT_HANDLER = new BlockHandler();
private static final Map<Integer, BlockHandler> handlers = new HashMap<Integer, BlockHandler>();
public static BlockHandler getHandler(int blockId) {
BlockHandler handler = handlers.get(blockId);
if (handler == null) {
return DEFAULT_HANDLER;
}
return handler;
}
public static BlockHandler getHandler(BlockSchematic schematic) {
BlockHandler handler = null; // TODO: replace with mapping -> id code
if (handler == null) {
return DEFAULT_HANDLER;
}
return handler;
}
public static void registerHandler(int blockId, BlockHandler handler) {
handlers.put(blockId, handler);
}
protected BlockHandler() {
}
/**
* By default we will ignore all blocks with Tile Entities.
*
* We will also skip any blocks that drop actual items like Ore blocks.
*/
public boolean canSaveBlockToSchematic(World world, int x, int y, int z) {
if (world.isAirBlock(x, y, z)) {
return false;
}
int blockId = world.getBlockId(x, y, z);
Block block = Block.blocksList[blockId];
if (block == null) {
return false;
}
int meta = world.getBlockMetadata(x, y, z);
try {
if (block.idDropped(meta, null, 0) != blockId) {
return false;
}
} catch (NullPointerException ex) {
return false;
}
return !block.hasTileEntity(meta);
}
/**
* It is assumed that Blueprints always face North on save.
*
* Tile Entities should store some NBT data in the BlockSchematic.blockData
* tag.
*/
public BlockSchematic saveBlockToSchematic(World world, int x, int y, int z) {
int blockId = world.getBlockId(x, y, z);
Block block = Block.blocksList[blockId];
if (block == null) {
return null;
}
BlockSchematic schematic = new BlockSchematic(block);
schematic.blockMeta = world.getBlockMetadata(x, y, z);
return schematic;
}
/**
* Provide a list of all the items that must be present to build this
* schematic.
*
* If you need axillary items like a painter or gate, list them as well.
* Items will be consumed in the consumeItems() callback below.
*
* This default implementation will only work for simple blocks without tile
* entities and will in fact break on Ore blocks as well. Which is why those
* blocks can't be saved by default.
*/
public List<ItemStack> getCostForSchematic(BlockSchematic schematic) {
List<ItemStack> cost = new ArrayList<ItemStack>();
Block block = null; // TODO: replace with mapping -> id code
if (block != null) {
cost.add(new ItemStack(block.idDropped(schematic.blockMeta, Utils.RANDOM, 0), 1, block.damageDropped(schematic.blockMeta)));
}
return cost;
}
/**
* Called when items are consumed for this block. The builder's inventory is
* passed in. Use them as you see fit.
*
* If the function returns false, the block is not placed. You should not
* modify any ItemStack until you have determined that everything you
* require is present.
*/
public boolean consumeItems(BlockSchematic schematic, IInventory builderInventory) {
List<ItemStack> requiredItems = getCostForSchematic(schematic);
List<Integer> slotsToConsume = new ArrayList<Integer>();
for (ItemStack cost : requiredItems) {
boolean found = false;
for (int slot = 0; slot < builderInventory.getSizeInventory(); slot++) {
if (areItemsEqual(builderInventory.getStackInSlot(slot), cost)) {
slotsToConsume.add(slot);
found = true;
break;
}
}
if (!found)
return false;
}
for (Integer slot : slotsToConsume) {
builderInventory.setInventorySlotContents(slot, Utils.consumeItem(builderInventory.getStackInSlot(slot)));
}
return true;
}
private boolean areItemsEqual(ItemStack stack1, ItemStack stack2) {
if (stack1 == null || stack2 == null)
return false;
if (!stack1.isItemEqual(stack2))
return false;
if (!ItemStack.areItemStackTagsEqual(stack1, stack2))
return false;
return true;
}
/**
* Can the block be placed currently or is it waiting on some other block to
* be placed first?
*/
public boolean canPlaceNow(World world, int x, int y, int z, ForgeDirection blueprintOrientation, BlockSchematic schematic) {
return true;
}
/**
* This function handles the placement of the block in the world.
*
* The ForgeDirection parameter can be use to determine the orientation of
* the blueprint. Blueprints are always saved facing North. This function
* will have to rotate the block accordingly.
*/
public boolean readBlockFromSchematic(World world, int x, int y, int z, ForgeDirection blueprintOrientation, BlockSchematic schematic, EntityPlayer bcPlayer) {
if (schematic.blockId != 0) {
return world.setBlock(x, y, z, schematic.blockId, schematic.blockMeta, 3);
}
return false;
}
/**
* Checks if the block matches the schematic.
*/
public boolean doesBlockMatchSchematic(World world, int x, int y, int z, ForgeDirection blueprintOrientation, BlockSchematic schematic) {
int blockId = world.getBlockId(x, y, z);
Block block = Block.blocksList[blockId];
if (block == null) {
return false;
}
if (!schematic.blockName.equals(block.getUnlocalizedName())) {
return false;
}
return schematic.blockMeta == world.getBlockMetadata(x, y, z);
}
}