Skip to content

Commit 9be8d21

Browse files
committed
Add abstraction so that multiple types of item providers can be used
IInventories can for example also be used now.
1 parent 497d2bb commit 9be8d21

8 files changed

Lines changed: 324 additions & 30 deletions

src/main/java/org/cyclops/structurecrafting/StructuredCrafting.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@
1313
import org.cyclops.cyclopscore.proxy.ICommonProxy;
1414
import org.cyclops.structurecrafting.block.BlockStructuredCrafter;
1515
import org.cyclops.structurecrafting.block.BlockStructuredCrafterConfig;
16+
import org.cyclops.structurecrafting.craft.provider.IItemStackProviderRegistry;
17+
import org.cyclops.structurecrafting.craft.provider.InventoryItemStackProvider;
18+
import org.cyclops.structurecrafting.craft.provider.ItemStackProviderRegistry;
19+
import org.cyclops.structurecrafting.craft.provider.WorldItemStackProvider;
1620

1721
/**
1822
* The main mod class of StructuredCrafting.
@@ -40,13 +44,19 @@ public StructuredCrafting() {
4044
@Mod.EventHandler
4145
@Override
4246
public final void preInit(FMLPreInitializationEvent event) {
47+
getRegistryManager().addRegistry(IItemStackProviderRegistry.class, new ItemStackProviderRegistry());
48+
4349
super.preInit(event);
4450
}
4551

4652
@Mod.EventHandler
4753
@Override
4854
public final void init(FMLInitializationEvent event) {
4955
super.init(event);
56+
57+
IItemStackProviderRegistry registry = getRegistryManager().getRegistry(IItemStackProviderRegistry.class);
58+
registry.registerProvider(new InventoryItemStackProvider());
59+
registry.registerProvider(new WorldItemStackProvider());
5060
}
5161

5262
@Mod.EventHandler

src/main/java/org/cyclops/structurecrafting/block/BlockStructuredCrafter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public BlockStructuredCrafter(ExtendedConfig eConfig) {
3838

3939
@Override
4040
public void onNeighborBlockChange(World world, BlockPos pos, IBlockState state, Block neighborBlock) {
41-
if(!world.isBlockPowered(pos)) {
41+
if(!world.isRemote && !world.isBlockPowered(pos)) {
4242
WorldCraftingMatrix[] matrices = WorldCraftingMatrix.deriveMatrices(world, pos);
4343
for (WorldCraftingMatrix matrix : matrices) {
4444
if (matrix.craft()) break;

src/main/java/org/cyclops/structurecrafting/craft/WorldCraftingMatrix.java

Lines changed: 62 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
package org.cyclops.structurecrafting.craft;
22

3-
import net.minecraft.block.state.IBlockState;
4-
import net.minecraft.item.Item;
3+
import com.google.common.collect.Lists;
54
import net.minecraft.item.ItemBlock;
65
import net.minecraft.item.ItemStack;
76
import net.minecraft.item.crafting.CraftingManager;
87
import net.minecraft.util.BlockPos;
98
import net.minecraft.util.EnumFacing;
109
import net.minecraft.world.World;
10+
import org.apache.commons.lang3.tuple.Pair;
11+
import org.cyclops.structurecrafting.StructuredCrafting;
12+
import org.cyclops.structurecrafting.craft.provider.IItemStackProvider;
13+
import org.cyclops.structurecrafting.craft.provider.IItemStackProviderRegistry;
14+
15+
import java.util.List;
1116

1217
/**
1318
* A crafting matrix represented with blockstates.
@@ -21,12 +26,16 @@ public class WorldCraftingMatrix {
2126
private final BlockPos centerPos;
2227
private final EnumFacing.Axis axis;
2328
private final BlockPos targetPos;
29+
private final EnumFacing targetSide;
30+
private final EnumFacing inputSide;
2431

25-
public WorldCraftingMatrix(World world, BlockPos centerPos, EnumFacing.Axis axis, BlockPos targetPos) {
32+
public WorldCraftingMatrix(World world, BlockPos centerPos, EnumFacing.Axis axis, BlockPos targetPos, EnumFacing inputSide) {
2633
this.world = world;
2734
this.centerPos = centerPos;
2835
this.axis = axis;
2936
this.targetPos = targetPos;
37+
this.targetSide = inputSide.getOpposite();
38+
this.inputSide = inputSide;
3039
}
3140

3241
protected BlockPos addInAxis(BlockPos pos, EnumFacing.Axis axis, int i, int j) {
@@ -40,62 +49,86 @@ protected BlockPos addInAxis(BlockPos pos, EnumFacing.Axis axis, int i, int j) {
4049
return null;
4150
}
4251

52+
protected List<IItemStackProvider> getItemStackProviders() {
53+
return StructuredCrafting._instance.getRegistryManager().
54+
getRegistry(IItemStackProviderRegistry.class).getProviders();
55+
}
56+
57+
protected Pair<ItemStack, IItemStackProvider> determineItemStackProviderForInput(World world, BlockPos pos, EnumFacing side) {
58+
for(IItemStackProvider provider : getItemStackProviders()) {
59+
if(provider.hasItemStack(world, pos, side)) {
60+
return Pair.of(provider.getItemStack(world, pos, side), provider);
61+
}
62+
}
63+
return null;
64+
}
65+
66+
protected boolean addItemStackForOutput(World world, BlockPos pos, EnumFacing side, List<IItemStackProvider> outputProviders, ItemStack itemStack) {
67+
for(IItemStackProvider provider : outputProviders) {
68+
if(provider.addItemStack(world, pos, side, itemStack)) {
69+
return true;
70+
}
71+
}
72+
return false;
73+
}
74+
4375
public boolean craft() {
44-
if(!world.isAirBlock(targetPos)) {
76+
// Check if at least one of the providers can write to the output target.
77+
List<IItemStackProvider> outputProviders = Lists.newLinkedList();
78+
for(IItemStackProvider provider : getItemStackProviders()) {
79+
if(provider.isValidForResults(world, targetPos, targetSide)) {
80+
outputProviders.add(provider);
81+
}
82+
}
83+
if(outputProviders.isEmpty()) {
4584
return false;
4685
}
4786

4887
BlockPos[] positions = new BlockPos[9];
88+
IItemStackProvider[] providers = new IItemStackProvider[9];
4989

5090
// Set crafting grid
5191
for(int i = -1; i < 2; i++) {
5292
for(int j = -1; j < 2; j++) {
93+
int arrayIndex = (j + 1) * 3 + (i + 1);
5394
BlockPos pos = addInAxis(centerPos, axis, i, j);
54-
IBlockState blockState = world.getBlockState(pos);
55-
56-
ItemStack itemStack = null;
57-
if(blockState != null) {
58-
Item item = blockState.getBlock().getItem(world, pos);
59-
if(item != null) {
60-
itemStack = new ItemStack(item, blockState.getBlock().getDamageValue(world, pos));
61-
}
95+
Pair<ItemStack, IItemStackProvider> result = determineItemStackProviderForInput(world, pos, inputSide);
96+
ItemStack itemStack = result != null ? result.getLeft() : null;
97+
if(itemStack != null) {
98+
itemStack = itemStack.copy();
99+
itemStack.stackSize = 1;
62100
}
63101
INVENTORY_CRAFTING.setItemStack(i + 1, j + 1, itemStack);
64-
positions[(j + 1) * 3 + (i + 1)] = pos;
102+
positions[arrayIndex] = pos;
103+
providers[arrayIndex] = result != null ? result.getRight() : null;
65104
}
66105
}
67106

68107
// Determine output
69108
ItemStack itemStack = CraftingManager.getInstance().findMatchingRecipe(INVENTORY_CRAFTING, world);
70-
if(itemStack != null && itemStack.getItem() instanceof ItemBlock) {
71-
// replace blocks depending on what the crafting results are.
72-
world.setBlockState(targetPos, ((ItemBlock) itemStack.getItem()).getBlock().getStateFromMeta(itemStack.getItemDamage()));
73-
109+
if(itemStack != null && addItemStackForOutput(world, targetPos, targetSide, outputProviders, itemStack)) {
74110
// Handle remaining container items: place blocks and drop items
75-
for(int i = 0; i < INVENTORY_CRAFTING.getSizeInventory(); i++) {
76-
ItemStack remainingStack = INVENTORY_CRAFTING.getStackInSlot(i);
77-
if(remainingStack != null && remainingStack.stackSize > 0) {
78-
if(remainingStack.getItem() instanceof ItemBlock) {
79-
world.setBlockState(positions[i],((ItemBlock) remainingStack.getItem()).getBlock().
80-
getStateFromMeta(remainingStack.getItemDamage()));
81-
} else {
82-
// TODO: drop as entity, temp
111+
ItemStack[] remainingStacks = CraftingManager.getInstance().func_180303_b(INVENTORY_CRAFTING, world);
112+
for(int i = 0; i < remainingStacks.length; i++) {
113+
ItemStack remainingStack = remainingStacks[i];
114+
if(providers[i] != null) {
115+
providers[i].reduceItemStack(world, positions[i], inputSide);
116+
if (remainingStack != null && remainingStack.stackSize > 0) {
117+
providers[i].addItemStack(world, positions[i], inputSide, remainingStack);
83118
}
84-
} else {
85-
world.setBlockToAir(positions[i]);
86119
}
87120
}
88121
return true;
89122
}
90-
91123
return false;
92124
}
93125

94126
public static WorldCraftingMatrix[] deriveMatrices(World world, BlockPos centerPos) {
95127
final WorldCraftingMatrix[] matrices = new WorldCraftingMatrix[6]; // Test for all faces of the center position.
96128
for(int i = 0; i < EnumFacing.values().length; i++) {
97129
EnumFacing side = EnumFacing.values()[i];
98-
matrices[i] = new WorldCraftingMatrix(world, centerPos.offset(side), side.getAxis(), centerPos.offset(side.getOpposite()));
130+
matrices[i] = new WorldCraftingMatrix(world, centerPos.offset(side), side.getAxis(),
131+
centerPos.offset(side.getOpposite()), side.getOpposite());
99132
}
100133
return matrices;
101134
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package org.cyclops.structurecrafting.craft.provider;
2+
3+
import net.minecraft.item.ItemStack;
4+
import net.minecraft.util.BlockPos;
5+
import net.minecraft.util.EnumFacing;
6+
import net.minecraft.world.World;
7+
8+
/**
9+
* Types of providers for itemstacks
10+
* @author rubensworks
11+
*/
12+
public interface IItemStackProvider {
13+
14+
/**
15+
* Check if the given target is valid for output results for this provider type.
16+
* @param world The world.
17+
* @param pos The position.
18+
* @param side The side.
19+
* @return If valid.
20+
*/
21+
public boolean isValidForResults(World world, BlockPos pos, EnumFacing side);
22+
23+
/**
24+
* If the given provider has an itemstack at the given position.
25+
* @param world The world.
26+
* @param pos The position.
27+
* @param side The side.
28+
* @return If it has an itemstack.
29+
*/
30+
public boolean hasItemStack(World world, BlockPos pos, EnumFacing side);
31+
32+
/**
33+
* The itemstack at the given position.
34+
* @param world The world.
35+
* @param pos The position.
36+
* @param side The side.
37+
* @return The itemstack at the given position.
38+
*/
39+
public ItemStack getItemStack(World world, BlockPos pos, EnumFacing side);
40+
41+
/**
42+
* Consumes one amount of the itemstack, will only work if such a stack existed.
43+
* @param world The world.
44+
* @param pos The position.
45+
* @param side The side.
46+
*/
47+
public void reduceItemStack(World world, BlockPos pos, EnumFacing side);
48+
49+
/**
50+
* Adds an itemstack.
51+
* @param world The world.
52+
* @param pos The position.
53+
* @param side The side.
54+
* @param itemStack The itemstack to set.
55+
* @return If the insertion succeeded.
56+
*/
57+
public boolean addItemStack(World world, BlockPos pos, EnumFacing side, ItemStack itemStack);
58+
59+
/**
60+
* Set the itemstack.
61+
* @param world The world.
62+
* @param pos The position.
63+
* @param side The side.
64+
* @param itemStack The itemstack to set.
65+
* @return If the insertion succeeded.
66+
*/
67+
public boolean setItemStack(World world, BlockPos pos, EnumFacing side, ItemStack itemStack);
68+
69+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.cyclops.structurecrafting.craft.provider;
2+
3+
import org.cyclops.cyclopscore.init.IRegistry;
4+
5+
import java.util.List;
6+
7+
/**
8+
* Registry for {@link IItemStackProvider}.
9+
* @author rubensworks
10+
*/
11+
public interface IItemStackProviderRegistry extends IRegistry {
12+
13+
public void registerProvider(IItemStackProvider provider);
14+
15+
public List<IItemStackProvider> getProviders();
16+
17+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package org.cyclops.structurecrafting.craft.provider;
2+
3+
import net.minecraft.inventory.IInventory;
4+
import net.minecraft.item.ItemStack;
5+
import net.minecraft.util.BlockPos;
6+
import net.minecraft.util.EnumFacing;
7+
import net.minecraft.world.World;
8+
import org.apache.commons.lang3.tuple.Pair;
9+
import org.cyclops.cyclopscore.helper.InventoryHelpers;
10+
import org.cyclops.cyclopscore.helper.TileHelpers;
11+
12+
/**
13+
* Inventory that can provide itemstacks.
14+
* @author rubensworks
15+
*/
16+
public class InventoryItemStackProvider implements IItemStackProvider {
17+
18+
protected Pair<Integer, ItemStack> getFirstItem(IInventory inventory, EnumFacing side) {
19+
for(int slot = 0; slot < inventory.getSizeInventory(); slot++) {
20+
ItemStack itemStack = inventory.getStackInSlot(slot);
21+
if(itemStack != null) {
22+
return Pair.of(slot, itemStack);
23+
}
24+
}
25+
return null;
26+
}
27+
28+
@Override
29+
public boolean isValidForResults(World world, BlockPos pos, EnumFacing side) {
30+
IInventory inventory = TileHelpers.getSafeTile(world, pos, IInventory.class);
31+
return inventory != null;
32+
}
33+
34+
@Override
35+
public boolean hasItemStack(World world, BlockPos pos, EnumFacing side) {
36+
IInventory inventory = TileHelpers.getSafeTile(world, pos, IInventory.class);
37+
return inventory != null && getFirstItem(inventory, side) != null;
38+
}
39+
40+
@Override
41+
public ItemStack getItemStack(World world, BlockPos pos, EnumFacing side) {
42+
IInventory inventory = TileHelpers.getSafeTile(world, pos, IInventory.class);
43+
return getFirstItem(inventory, side).getRight();
44+
}
45+
46+
@Override
47+
public void reduceItemStack(World world, BlockPos pos, EnumFacing side) {
48+
IInventory inventory = TileHelpers.getSafeTile(world, pos, IInventory.class);
49+
Pair<Integer, ItemStack> result = getFirstItem(inventory, side);
50+
ItemStack newItemStack = result.getRight().copy();
51+
newItemStack.stackSize--;
52+
if(newItemStack.stackSize <= 0) {
53+
newItemStack = null;
54+
}
55+
inventory.setInventorySlotContents(result.getLeft(), newItemStack);
56+
}
57+
58+
@Override
59+
public boolean addItemStack(World world, BlockPos pos, EnumFacing side, ItemStack itemStack) {
60+
IInventory inventory = TileHelpers.getSafeTile(world, pos, IInventory.class);
61+
for(int slot = 0; slot < inventory.getSizeInventory(); slot++) {
62+
if(InventoryHelpers.addToSlot(inventory, slot, itemStack)) {
63+
return true;
64+
}
65+
}
66+
return false;
67+
}
68+
69+
@Override
70+
public boolean setItemStack(World world, BlockPos pos, EnumFacing side, ItemStack itemStack) {
71+
IInventory inventory = TileHelpers.getSafeTile(world, pos, IInventory.class);
72+
Pair<Integer, ItemStack> result = getFirstItem(inventory, side);
73+
if(result != null) {
74+
inventory.setInventorySlotContents(result.getLeft(), itemStack);
75+
return true;
76+
}
77+
return false;
78+
}
79+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package org.cyclops.structurecrafting.craft.provider;
2+
3+
import com.google.common.collect.Lists;
4+
5+
import java.util.List;
6+
7+
/**
8+
* Registry for {@link IItemStackProvider}.
9+
* @author rubensworks
10+
*/
11+
public class ItemStackProviderRegistry implements IItemStackProviderRegistry {
12+
13+
private final List<IItemStackProvider> providers = Lists.newLinkedList();
14+
15+
@Override
16+
public void registerProvider(IItemStackProvider provider) {
17+
providers.add(provider);
18+
}
19+
20+
@Override
21+
public List<IItemStackProvider> getProviders() {
22+
return providers;
23+
}
24+
25+
}

0 commit comments

Comments
 (0)