Skip to content

Commit 156988e

Browse files
committed
Recipe rotation checking works; state matching does not
1 parent 79b4679 commit 156988e

File tree

5 files changed

+108
-73
lines changed

5 files changed

+108
-73
lines changed

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import com.robotgryphon.compactcrafting.field.MiniaturizationFieldBlockData;
88
import com.robotgryphon.compactcrafting.field.ProjectorHelper;
99
import com.robotgryphon.compactcrafting.recipes.MiniaturizationRecipe;
10-
import com.robotgryphon.compactcrafting.util.BlockSpaceUtil;
1110
import com.robotgryphon.compactcrafting.world.ProjectionFieldSavedData;
1211
import com.robotgryphon.compactcrafting.world.ProjectorFieldData;
1312
import net.minecraft.block.BlockState;
@@ -22,7 +21,10 @@
2221
import net.minecraft.world.server.ServerWorld;
2322
import net.minecraftforge.fml.RegistryObject;
2423

25-
import java.util.*;
24+
import java.util.Collection;
25+
import java.util.List;
26+
import java.util.Optional;
27+
import java.util.Set;
2628
import java.util.stream.Collectors;
2729

2830
public class FieldProjectorTile extends TileEntity implements ITickableTileEntity {
@@ -208,8 +210,7 @@ public void doRecipeScan() {
208210
Set<MiniaturizationRecipe> recipesBoundFitted = entries
209211
.stream()
210212
.map(RegistryObject::get)
211-
.filter(recipe -> recipe.fitsInFieldSize(size))
212-
.filter(recipe -> BlockSpaceUtil.boundsFitsInside(recipe.getDimensions(), fieldBlocks.getFilledBounds()))
213+
.filter(recipe -> recipe.fitsInDimensions(fieldBlocks.getFilledBounds()))
213214
.collect(Collectors.toSet());
214215

215216
// All the recipes we have registered won't fit in the filled bounds -

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

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -85,28 +85,39 @@ public class Registration {
8585

8686
Set<BlockPos> template = new HashSet<>();
8787

88-
// cross pattern, see docs
89-
BlockPos[] layerBlocks = new BlockPos[]{
90-
new BlockPos(1, 0, 0),
91-
new BlockPos(0, 0, 1),
88+
BlockPos[] complexPattern = new BlockPos[] {
89+
// Glass
90+
new BlockPos(3, 0, 0),
91+
new BlockPos(4, 0, 0),
9292
new BlockPos(2, 0, 1),
93-
new BlockPos(1, 0, 2)
93+
new BlockPos(5, 0, 1),
94+
new BlockPos(2, 0, 2),
95+
new BlockPos(5, 0, 2),
96+
new BlockPos(3, 0, 3),
97+
new BlockPos(4, 0, 3),
98+
99+
// Tail
100+
new BlockPos(2, 0, 3),
101+
new BlockPos(1, 0, 4),
102+
new BlockPos(0, 0, 5)
94103
};
95104

96-
Collections.addAll(template, layerBlocks);
105+
Collections.addAll(template, complexPattern);
97106

98107
rec.setLayers(new IRecipeLayer[]{
99-
new SingleComponentRecipeLayer("O", template),
100-
new SingleComponentRecipeLayer("G", template)
108+
new SingleComponentRecipeLayer("S", template)
109+
// new SingleComponentRecipeLayer("O", template),
110+
// new SingleComponentRecipeLayer("G", template)
101111
});
102112

103-
rec.catalyst = Items.ANVIL;
113+
rec.catalyst = Items.GLASS;
104114
rec.outputs = new ItemStack[]{
105-
new ItemStack(Items.CRYING_OBSIDIAN, 1)
115+
new ItemStack(Items.BELL, 1)
106116
};
107117

108-
rec.addComponent("O", Blocks.OBSIDIAN.getDefaultState());
109-
rec.addComponent("G", Blocks.GLOWSTONE.getDefaultState());
118+
rec.addComponent("S", Blocks.STONE.getDefaultState());
119+
// rec.addComponent("O", Blocks.OBSIDIAN.getDefaultState());
120+
// rec.addComponent("G", Blocks.GLOWSTONE.getDefaultState());
110121

111122
return rec;
112123
});

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

Lines changed: 66 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import net.minecraft.item.Item;
99
import net.minecraft.item.ItemStack;
1010
import net.minecraft.util.Direction;
11+
import net.minecraft.util.Rotation;
1112
import net.minecraft.util.math.AxisAlignedBB;
1213
import net.minecraft.util.math.BlockPos;
1314
import net.minecraft.util.math.vector.Vector3d;
@@ -84,27 +85,39 @@ public boolean fitsInFieldSize(FieldProjectionSize fieldSize) {
8485
return fits;
8586
}
8687

87-
private boolean hasMatchingBottomLayer(IWorldReader world, FieldProjectionSize fieldSize, AxisAlignedBB field) {
88-
if (!fitsInFieldSize(fieldSize))
89-
return false;
90-
91-
return true;
92-
}
93-
9488
public boolean matches(IWorldReader world, FieldProjectionSize fieldSize, MiniaturizationFieldBlockData fieldBlocks) {
9589
if (!fitsInFieldSize(fieldSize))
9690
return false;
9791

9892
// We know that the recipe will at least fit inside the current projection field
9993
AxisAlignedBB filledBounds = fieldBlocks.getFilledBounds();
10094

101-
// Check rest of the recipe layers
95+
Rotation[] validRotations = new Rotation[] {
96+
Rotation.NONE,
97+
Rotation.CLOCKWISE_90,
98+
Rotation.CLOCKWISE_180,
99+
Rotation.COUNTERCLOCKWISE_90
100+
};
101+
102+
for(Rotation rot : validRotations) {
103+
boolean matchesRot = checkRotation(world, rot, filledBounds);
104+
if(matchesRot)
105+
return true;
106+
}
107+
108+
return false;
109+
}
110+
111+
private boolean checkRotation(IWorldReader world, Rotation rot, AxisAlignedBB filledBounds) {
112+
// Check the recipe layer by layer
113+
102114
int maxY = (int) dimensions.getYSize();
103-
for(int offset = 0; offset < maxY; offset++) {
115+
for (int offset = 0; offset < maxY; offset++) {
104116
BlockPos[] layerFilled = BlockSpaceUtil.getFilledBlocksByLayer(world, filledBounds, offset);
117+
BlockPos[] layerRotated = BlockSpaceUtil.rotatePositionsInPlace(layerFilled, rot);
105118

106-
boolean layerMatches = doLayerBlocksMatch(world, filledBounds, layerFilled);
107-
if(!layerMatches)
119+
boolean layerMatches = doLayerBlocksMatch(world, rot, filledBounds, layerRotated);
120+
if (!layerMatches)
108121
return false;
109122
}
110123

@@ -149,68 +162,77 @@ public AxisAlignedBB getDimensions() {
149162
* @param filledPositions The filled positions on the layer to check.
150163
* @return
151164
*/
152-
public boolean doLayerBlocksMatch(IWorldReader world, AxisAlignedBB fieldFilledBounds, BlockPos[] filledPositions) {
165+
public boolean doLayerBlocksMatch(IWorldReader world, Rotation rot, AxisAlignedBB fieldFilledBounds, BlockPos[] filledPositions) {
153166
// Recipe layers using this method must define at least one filled space
154167
if(filledPositions.length == 0)
155168
return false;
156169

157-
int filledYLevel = filledPositions[0].getY();
158-
int minFilledLevel = (int) Math.floor(fieldFilledBounds.minY);
159-
int yLevelRelative = filledYLevel - minFilledLevel;
160-
161-
Optional<IRecipeLayer> layer = this.getLayer(yLevelRelative);
162-
163-
// No such layer exists
164-
if(!layer.isPresent())
170+
Optional<IRecipeLayer> layer = getRecipeLayerFromPositions(fieldFilledBounds, filledPositions);
171+
if (!layer.isPresent())
165172
return false;
166173

167174
IRecipeLayer l = layer.get();
168175

169176
int totalFilled = filledPositions.length;
170177
int requiredFilled = l.getNumberFilledPositions();
171178

179+
// Early exit if we don't have the correct number of blocks in the layer
172180
if(totalFilled != requiredFilled)
173181
return false;
174182

175-
BlockPos[] fieldNormalizedPositions = BlockSpaceUtil.normalizeLayerPositions(fieldFilledBounds, filledPositions);
176-
int extraYOffset = fieldNormalizedPositions[0].getY();
183+
BlockPos[] fieldNormalizedPositionsFieldOffset = BlockSpaceUtil.normalizeLayerPositions(fieldFilledBounds, filledPositions);
177184

178-
for(BlockPos fieldFilledPosition : fieldNormalizedPositions) {
179-
BlockPos realPos = BlockSpaceUtil.denormalizeLayerPosition(fieldFilledBounds, fieldFilledPosition);
180-
BlockState state = world.getBlockState(realPos);
185+
// TODO: Make recipe loading respect multiple layers as Y=0, 1, etc
186+
int extraYOffset = fieldNormalizedPositionsFieldOffset[0].getY();
181187

182-
// If we require a block at a position and it's air...
183-
BlockPos zeroedRecipePosition = fieldFilledPosition.offset(Direction.DOWN, extraYOffset);
184-
if(!l.isPositionRequired(zeroedRecipePosition)) {
185-
CompactCrafting.LOGGER.debug("Position filled but the recipe does not require a block there; recipe not matched.");
186-
return false;
187-
}
188+
// We'll need an extra offset layer to match against the recipe layer's Y=0
189+
BlockPos[] fieldNormalizedPositionsLayerOffset = Stream.of(fieldNormalizedPositionsFieldOffset)
190+
.parallel()
191+
.map(p -> p.offset(Direction.DOWN, extraYOffset))
192+
.map(BlockPos::toImmutable)
193+
.toArray(BlockPos[]::new);
188194

189-
// Position is required but the block there is air?
190-
// This shouldn't happen, the air check should have happened before this
191-
if(state.isAir(world, realPos))
192-
return false;
195+
for(BlockPos normalizedFieldPosition : fieldNormalizedPositionsLayerOffset) {
193196

194-
String requiredCompKey = l.getRequiredComponentKeyForPosition(zeroedRecipePosition);
195-
Optional<String> realComponentInPosition = this.getRecipeComponentKey(state);
197+
// normalizedFieldPosition is the normalized position in the ROTATED layout
198+
boolean required = l.isPositionRequired(normalizedFieldPosition);
199+
if(!required) {
200+
// is block set? - if so, exit as a failure
201+
}
196202

203+
String requiredCompKey = l.getRequiredComponentKeyForPosition(normalizedFieldPosition);
197204
if(requiredCompKey == null) {
198205
CompactCrafting.LOGGER.error("Relative position marked as required but the recipe layer did not have a lookup.");
199206
return false;
200207
}
201208

202-
// No lookup defined in the recipe for the state in the position
203-
if(!realComponentInPosition.isPresent())
204-
return false;
205-
206-
// Does component match in position?
207-
if(!realComponentInPosition.get().equals(requiredCompKey))
208-
return false;
209+
// Optional<String> realComponentInPosition = this.getRecipeComponentKey(state);
210+
//
211+
//
212+
//
213+
// // No lookup defined in the recipe for the state in the position
214+
// if(!realComponentInPosition.isPresent())
215+
// return false;
216+
//
217+
// // Does component match in position?
218+
// if(!realComponentInPosition.get().equals(requiredCompKey))
219+
// return false;
209220
}
210221

211222
return true;
212223
}
213224

225+
private Optional<IRecipeLayer> getRecipeLayerFromPositions(AxisAlignedBB fieldFilledBounds, BlockPos[] filledPositions) {
226+
if(filledPositions.length == 0)
227+
return Optional.empty();
228+
229+
int filledYLevel = filledPositions[0].getY();
230+
int minFilledLevel = (int) Math.floor(fieldFilledBounds.minY);
231+
int yLevelRelative = filledYLevel - minFilledLevel;
232+
233+
return this.getLayer(yLevelRelative);
234+
}
235+
214236
public Optional<IRecipeLayer> getLayer(int y) {
215237
if(y < 0 || y > this.layers.length - 1)
216238
return Optional.empty();

src/main/java/com/robotgryphon/compactcrafting/util/BlockSpaceUtil.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.robotgryphon.compactcrafting.util;
22

3-
import com.robotgryphon.compactcrafting.field.MiniaturizationFieldBlockData;
43
import net.minecraft.util.Rotation;
54
import net.minecraft.util.math.AxisAlignedBB;
65
import net.minecraft.util.math.BlockPos;
@@ -38,6 +37,20 @@ public static BlockPos[] rotatePositionsInPlace(BlockPos[] positions) {
3837
return rotatePositionsInPlace(positions, Rotation.CLOCKWISE_90);
3938
}
4039

40+
public static BlockPos rotatePositionInPlace(AxisAlignedBB bounds, BlockPos rotated, Rotation rotation) {
41+
Rotation rotBack = rotation.add(Rotation.CLOCKWISE_180);
42+
43+
BlockPos normalized = normalizeLayerPosition(bounds, rotated);
44+
BlockPos rotatedBack = normalized.rotate(rotBack);
45+
BlockPos denormalized = denormalizeLayerPosition(bounds, rotatedBack);
46+
47+
AxisAlignedBB boundsRotated = new AxisAlignedBB(denormalized, denormalized);
48+
BlockPos reNormalized = normalizeLayerPosition(boundsRotated, denormalized);
49+
50+
return denormalizeLayerPosition(bounds, reNormalized);
51+
52+
}
53+
4154
public static BlockPos[] rotatePositionsInPlace(BlockPos[] positions, Rotation rot) {
4255
AxisAlignedBB bounds = getBoundsForBlocks(positions);
4356

src/test/java/com/robotgryphon/compactcrafting/MiniaturizationFieldBlockDataTest.java

Lines changed: 0 additions & 12 deletions
This file was deleted.

0 commit comments

Comments
 (0)