Skip to content

Commit de9fdaa

Browse files
committed
Recipes: First rough implementation of a recipe
First impl does not currently respect translated recipes in a field; blocks MUST exactly match the north-west corner of the recipe, per normalization.
1 parent 5cf63a4 commit de9fdaa

File tree

10 files changed

+183
-109
lines changed

10 files changed

+183
-109
lines changed

src/main/java/com/robotgryphon/compactcrafting/blocks/FieldProjectorBlock.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
package com.robotgryphon.compactcrafting.blocks;
22

33
import com.robotgryphon.compactcrafting.field.ProjectorHelper;
4-
//import mcjty.theoneprobe.api.IProbeHitData;
5-
//import mcjty.theoneprobe.api.IProbeInfo;
6-
//import mcjty.theoneprobe.api.IProbeInfoProvider;
7-
//import mcjty.theoneprobe.api.ProbeMode;
84
import net.minecraft.block.Block;
95
import net.minecraft.block.BlockState;
106
import net.minecraft.entity.LivingEntity;
@@ -30,6 +26,11 @@
3026
import javax.annotation.Nullable;
3127
import java.util.Optional;
3228

29+
//import mcjty.theoneprobe.api.IProbeHitData;
30+
//import mcjty.theoneprobe.api.IProbeInfo;
31+
//import mcjty.theoneprobe.api.IProbeInfoProvider;
32+
//import mcjty.theoneprobe.api.ProbeMode;
33+
3334
public class FieldProjectorBlock extends Block {
3435

3536
public static final DirectionProperty FACING = DirectionProperty.create("facing", Direction.Plane.HORIZONTAL);

src/main/java/com/robotgryphon/compactcrafting/blocks/FieldProjectorTile.java

Lines changed: 34 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,25 @@
11
package com.robotgryphon.compactcrafting.blocks;
22

3-
import com.robotgryphon.compactcrafting.CompactCrafting;
4-
import com.robotgryphon.compactcrafting.blocks.FieldProjectorBlock;
53
import com.robotgryphon.compactcrafting.core.BlockUpdateType;
6-
import com.robotgryphon.compactcrafting.field.FieldProjection;
7-
import com.robotgryphon.compactcrafting.field.FieldProjectionSize;
84
import com.robotgryphon.compactcrafting.core.Registration;
95
import com.robotgryphon.compactcrafting.crafting.CraftingHelper;
6+
import com.robotgryphon.compactcrafting.field.FieldProjection;
7+
import com.robotgryphon.compactcrafting.field.FieldProjectionSize;
108
import com.robotgryphon.compactcrafting.recipes.MiniaturizationRecipe;
119
import net.minecraft.block.BlockState;
1210
import net.minecraft.entity.item.ItemEntity;
1311
import net.minecraft.item.Item;
1412
import net.minecraft.item.ItemStack;
15-
import net.minecraft.item.Items;
1613
import net.minecraft.tileentity.ITickableTileEntity;
1714
import net.minecraft.tileentity.TileEntity;
1815
import net.minecraft.util.Direction;
19-
import net.minecraft.util.RegistryKey;
2016
import net.minecraft.util.math.AxisAlignedBB;
2117
import net.minecraft.util.math.BlockPos;
22-
import net.minecraft.world.World;
23-
import net.minecraft.world.server.ServerWorld;
2418
import net.minecraftforge.fml.RegistryObject;
25-
import net.minecraftforge.registries.ForgeRegistries;
2619

27-
import java.util.*;
20+
import java.util.Collection;
21+
import java.util.List;
22+
import java.util.Optional;
2823
import java.util.stream.Collectors;
2924
import java.util.stream.Stream;
3025

@@ -121,7 +116,9 @@ public void tick() {
121116
}
122117

123118
doFieldCheck();
124-
tickCrafting();
119+
120+
if(this.currentRecipe != null)
121+
tickCrafting();
125122
}
126123

127124
/**
@@ -166,6 +163,7 @@ private void doRecipeScan() {
166163
Stream<MiniaturizationRecipe> matchedRecipes = entries
167164
.stream()
168165
.map(RegistryObject::get)
166+
.filter(recipe -> recipe.fitsInFieldSize(fieldSize))
169167
.filter(recipe -> recipe.matches(world, fieldSize, fieldBounds));
170168

171169
Optional<MiniaturizationRecipe> matched = matchedRecipes.findFirst();
@@ -174,37 +172,35 @@ private void doRecipeScan() {
174172
}
175173

176174
private void tickCrafting() {
177-
// We don't have a recipe -- get out early
178-
if (this.currentRecipe == null)
179-
return;
180-
181175
if (this.field.isPresent()) {
182-
FieldProjection fp = this.field.get();
183-
AxisAlignedBB fieldBounds = fp.getBounds();
176+
FieldProjection fieldProjection = this.field.get();
177+
AxisAlignedBB fieldBounds = fieldProjection.getBounds();
178+
179+
// Get out, client worlds
180+
if (world.isRemote())
181+
return;
182+
184183
List<ItemEntity> catalystEntities = getCatalystsInField(fieldBounds, currentRecipe.catalyst);
185184
if (catalystEntities.size() > 0) {
186-
// We dropped a catalyst item in - are there any blocks in the field?
187-
// If so, we'll need to check the recipes -- but for now we just use it to
188-
// not delete the item if there's nothing in here
189-
if (CraftingHelper.hasBlocksInField(world, fieldBounds)) {
190-
this.isCrafting = true;
191-
192-
if (!world.isRemote()) {
193-
CraftingHelper.deleteCraftingBlocks(world, fieldBounds);
194-
CraftingHelper.consumeCatalystItem(catalystEntities.get(0), 1);
195-
196-
BlockPos fieldCenter = field.get().getCenterPosition();
197-
for (ItemStack is : currentRecipe.getOutputs()) {
198-
ItemEntity itemEntity = new ItemEntity(world, fieldCenter.getX() + 0.5f, fieldCenter.getY() + 0.5f, fieldCenter.getZ() + 0.5f, is);
199-
((ServerWorld) world).addEntity(itemEntity);
200-
}
201-
202-
}
203-
204-
// We aren't crafting any more - recipe complete, reset for next one
205-
this.isCrafting = false;
206-
this.currentRecipe = null;
185+
// We dropped a catalyst item in
186+
// At this point, we had a valid recipe and a valid catalyst entity
187+
// Start crafting
188+
this.isCrafting = true;
189+
190+
// We know the "recipe" in the field is an exact match already, so wipe the field
191+
fieldProjection.clearBlocks(world);
192+
193+
CraftingHelper.consumeCatalystItem(catalystEntities.get(0), 1);
194+
195+
BlockPos fieldCenter = field.get().getCenterPosition();
196+
for (ItemStack is : currentRecipe.getOutputs()) {
197+
ItemEntity itemEntity = new ItemEntity(world, fieldCenter.getX() + 0.5f, fieldCenter.getY() + 0.5f, fieldCenter.getZ() + 0.5f, is);
198+
world.addEntity(itemEntity);
207199
}
200+
201+
// We aren't crafting any more - recipe complete, reset for next one
202+
this.isCrafting = false;
203+
this.currentRecipe = null;
208204
}
209205
}
210206
}

src/main/java/com/robotgryphon/compactcrafting/core/Registration.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,17 @@
1414
import net.minecraft.item.ItemStack;
1515
import net.minecraft.item.Items;
1616
import net.minecraft.tileentity.TileEntityType;
17-
import net.minecraft.util.math.AxisAlignedBB;
1817
import net.minecraft.util.math.BlockPos;
1918
import net.minecraftforge.common.ToolType;
2019
import net.minecraftforge.eventbus.api.IEventBus;
2120
import net.minecraftforge.fml.RegistryObject;
2221
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
23-
import net.minecraftforge.registries.*;
24-
import org.lwjgl.system.CallbackI;
22+
import net.minecraftforge.registries.DeferredRegister;
23+
import net.minecraftforge.registries.ForgeRegistries;
24+
import net.minecraftforge.registries.RegistryBuilder;
2525

26+
import java.util.Collections;
27+
import java.util.Set;
2628
import java.util.function.Supplier;
2729

2830
import static com.robotgryphon.compactcrafting.CompactCrafting.MOD_ID;
@@ -79,18 +81,22 @@ public class Registration {
7981
public static final RegistryObject<MiniaturizationRecipe> SIMPLE_RECIPE = MINIATURIZATION_RECIPES.register("simple", () ->
8082
{
8183
MiniaturizationRecipe rec = new MiniaturizationRecipe();
84+
85+
Set<BlockPos> layerTemplate = Collections.singleton(new BlockPos(0, 0, 0));
86+
87+
// Example: One obsidian block anywhere in the field can turn into crying obsidian
8288
rec.layers = new IRecipeLayer[]{
83-
new SingleComponentRecipeLayer("I", new BlockPos[0]),
84-
new SingleComponentRecipeLayer("R", new BlockPos[0])
89+
new SingleComponentRecipeLayer("O", layerTemplate)
8590
};
8691

87-
rec.catalyst = Items.REDSTONE;
92+
rec.recalculateDimensions();
93+
94+
rec.catalyst = Items.ANVIL;
8895
rec.outputs = new ItemStack[]{
8996
new ItemStack(Items.CRYING_OBSIDIAN, 1)
9097
};
9198

92-
rec.addComponent("I", Blocks.IRON_BLOCK.getDefaultState());
93-
rec.addComponent("R", Blocks.REDSTONE_WIRE.getDefaultState());
99+
rec.addComponent("O", Blocks.OBSIDIAN.getDefaultState());
94100

95101
return rec;
96102
});

src/main/java/com/robotgryphon/compactcrafting/crafting/CraftingHelper.java

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,18 @@
22

33
import net.minecraft.entity.item.ItemEntity;
44
import net.minecraft.item.ItemStack;
5-
import net.minecraft.particles.ParticleTypes;
65
import net.minecraft.util.math.AxisAlignedBB;
76
import net.minecraft.util.math.BlockPos;
8-
import net.minecraft.world.IWorld;
9-
10-
import java.util.Comparator;
11-
import java.util.List;
12-
import java.util.stream.Collectors;
7+
import net.minecraft.world.IWorldReader;
138

149
public abstract class CraftingHelper {
1510

16-
public static boolean hasBlocksInField(IWorld world, AxisAlignedBB area) {
11+
public static boolean hasBlocksInField(IWorldReader world, AxisAlignedBB area) {
1712
// Remove blocks from the world
1813
return BlockPos.getAllInBox(area)
1914
.anyMatch(p -> !world.isAirBlock(p));
2015
}
2116

22-
public static void deleteCraftingBlocks(IWorld world, AxisAlignedBB area) {
23-
// Remove blocks from the world
24-
BlockPos.getAllInBox(area)
25-
.filter(pos -> !world.isAirBlock(pos))
26-
.map(BlockPos::toImmutable)
27-
.sorted(Comparator.comparingInt(BlockPos::getY).reversed())
28-
.forEach(blockPos -> {
29-
world.destroyBlock(blockPos, false);
30-
world.addParticle(ParticleTypes.LARGE_SMOKE,
31-
blockPos.getX() + 0.5f, blockPos.getY() + 0.5f, blockPos.getZ() + 0.5f,
32-
0d, 0.05D, 0D);
33-
});
34-
}
35-
3617
/**
3718
* Consumes a number of items from a stack in the world.
3819
*

src/main/java/com/robotgryphon/compactcrafting/field/FieldHelper.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
import com.robotgryphon.compactcrafting.blocks.FieldProjectorBlock;
55
import com.robotgryphon.compactcrafting.blocks.FieldProjectorTile;
66
import com.robotgryphon.compactcrafting.core.BlockUpdateType;
7-
import net.minecraft.block.BlockState;
87
import net.minecraft.util.math.AxisAlignedBB;
98
import net.minecraft.util.math.BlockPos;
109
import net.minecraft.world.IWorld;
1110

11+
import java.util.stream.Stream;
12+
1213
/**
1314
* Provides utilities to help with projector field management.
1415
*/
@@ -38,18 +39,18 @@ public static void checkBlockPlacement(IWorld world, BlockPos pos) {
3839
}
3940
}
4041

41-
public static AxisAlignedBB[] splitIntoLayers(FieldProjectionSize size, AxisAlignedBB full) {
42+
public static Stream<AxisAlignedBB> splitIntoLayers(FieldProjectionSize size, AxisAlignedBB full) {
4243

4344
int s = size.getSize();
4445
BlockPos bottomCenter = new BlockPos(full.getCenter()).down(s);
4546
AxisAlignedBB bottomLayerBounds = new AxisAlignedBB(bottomCenter).grow(s, 0, s);
4647

4748
AxisAlignedBB[] layers = new AxisAlignedBB[size.getDimensions()];
48-
for(int layer = 0; layer <= size.getDimensions(); layer++) {
49+
for(int layer = 0; layer < size.getDimensions(); layer++) {
4950
AxisAlignedBB layerBounds = bottomLayerBounds.offset(0, layer, 0);
5051
layers[layer] = layerBounds;
5152
}
5253

53-
return layers;
54+
return Stream.of(layers);
5455
}
5556
}

src/main/java/com/robotgryphon/compactcrafting/field/FieldProjection.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
package com.robotgryphon.compactcrafting.field;
22

33
import com.robotgryphon.compactcrafting.blocks.FieldProjectorBlock;
4+
import net.minecraft.particles.ParticleTypes;
45
import net.minecraft.util.Direction;
56
import net.minecraft.util.math.AxisAlignedBB;
67
import net.minecraft.util.math.BlockPos;
8+
import net.minecraft.world.IWorld;
79
import net.minecraft.world.IWorldReader;
810

9-
import java.util.*;
11+
import java.util.Collections;
12+
import java.util.Comparator;
13+
import java.util.Optional;
14+
import java.util.Set;
1015
import java.util.stream.Collectors;
1116
import java.util.stream.Stream;
1217

@@ -114,4 +119,18 @@ public static Optional<FieldProjection> tryCreateFromPosition(IWorldReader world
114119
public BlockPos getProjectorInDirection(Direction direction) {
115120
return center.offset(direction, size.getProjectorDistance());
116121
}
122+
123+
public void clearBlocks(IWorld world) {
124+
// Remove blocks from the world
125+
BlockPos.getAllInBox(getBounds())
126+
.filter(pos -> !world.isAirBlock(pos))
127+
.map(BlockPos::toImmutable)
128+
.sorted(Comparator.comparingInt(BlockPos::getY).reversed())
129+
.forEach(blockPos -> {
130+
world.destroyBlock(blockPos, false);
131+
world.addParticle(ParticleTypes.LARGE_SMOKE,
132+
blockPos.getX() + 0.5f, blockPos.getY() + 0.5f, blockPos.getZ() + 0.5f,
133+
0d, 0.05D, 0D);
134+
});
135+
}
117136
}

src/main/java/com/robotgryphon/compactcrafting/recipes/IRecipeLayer.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,17 @@ public interface IRecipeLayer {
1414
* cardinal directions.
1515
*
1616
* @param world
17+
* @param recipe
1718
* @param fieldLayer
1819
* @return
1920
*/
20-
boolean matchesFieldLayer(IWorldReader world, AxisAlignedBB fieldLayer);
21-
22-
int getVolume();
21+
boolean matchesFieldLayer(IWorldReader world, MiniaturizationRecipe recipe, AxisAlignedBB fieldLayer);
2322

23+
/**
24+
* Gets the trimmed dimensions of the given recipe layer.
25+
*
26+
* @return
27+
*/
2428
Vector3i getDimensions();
2529

2630
/**

0 commit comments

Comments
 (0)