Skip to content

Commit 84f79c1

Browse files
committed
Update block break handling to schedule an update on FP tile
1 parent fe21538 commit 84f79c1

File tree

8 files changed

+96
-42
lines changed

8 files changed

+96
-42
lines changed

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
import javax.annotation.Nullable;
2727
import java.util.Optional;
28+
import java.util.Random;
2829

2930
//import mcjty.theoneprobe.api.IProbeHitData;
3031
//import mcjty.theoneprobe.api.IProbeInfo;
@@ -53,6 +54,16 @@ public static Optional<Direction> getDirection(IWorldReader world, BlockPos posi
5354
return Optional.of(facing);
5455
}
5556

57+
@Override
58+
public void tick(BlockState state, ServerWorld worldIn, BlockPos pos, Random rand) {
59+
FieldProjectorTile tile = (FieldProjectorTile) worldIn.getTileEntity(pos);
60+
if(tile == null)
61+
return;
62+
63+
tile.doRecipeScan();
64+
}
65+
66+
5667
@Override
5768
public VoxelShape getRenderShape(BlockState state, IBlockReader worldIn, BlockPos pos) {
5869
return VoxelShapes.empty();

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

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

3-
import com.robotgryphon.compactcrafting.core.BlockUpdateType;
43
import com.robotgryphon.compactcrafting.core.Registration;
54
import com.robotgryphon.compactcrafting.crafting.CraftingHelper;
65
import com.robotgryphon.compactcrafting.field.FieldProjection;
@@ -162,7 +161,7 @@ private void doFieldCheck() {
162161
/**
163162
* Scans the field and attempts to match a recipe that's placed in it.
164163
*/
165-
private void doRecipeScan() {
164+
public void doRecipeScan() {
166165
if(!this.field.isPresent())
167166
return;
168167

@@ -276,27 +275,4 @@ public AxisAlignedBB getRenderBoundingBox() {
276275
public Optional<FieldProjection> getField() {
277276
return this.field;
278277
}
279-
280-
/**
281-
* Called whenever a nearby block is changed near the field.
282-
*
283-
* @param pos The position a block was updated at.
284-
*/
285-
public void handleNearbyBlockUpdate(BlockPos pos, BlockUpdateType updateType) {
286-
if (updateType == BlockUpdateType.UNKNOWN)
287-
return;
288-
289-
// Is there a current projection field that's active?
290-
if(this.field.isPresent()) {
291-
AxisAlignedBB fieldBounds = this.field.get().getBounds();
292-
293-
// Is the block update INSIDE the current field?
294-
boolean blockInField = fieldBounds
295-
.contains(pos.getX() + 0.5f, pos.getY() + 0.5f, pos.getZ() + 0.5f);
296-
297-
// Recipe update
298-
if(blockInField)
299-
doRecipeScan();
300-
}
301-
}
302278
}

src/main/java/com/robotgryphon/compactcrafting/events/EventHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
public class EventHandler {
1515

1616
@SubscribeEvent
17-
public static void onBlockDestroyed(final BlockEvent.EntityPlaceEvent blockPlaced) {
17+
public static void onBlockPlaced(final BlockEvent.EntityPlaceEvent blockPlaced) {
1818
// Check if block is in or around a projector field
1919

2020
IWorld world = blockPlaced.getWorld();

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

Lines changed: 61 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,21 @@
33
import com.robotgryphon.compactcrafting.CompactCrafting;
44
import com.robotgryphon.compactcrafting.blocks.FieldProjectorTile;
55
import com.robotgryphon.compactcrafting.core.BlockUpdateType;
6+
import com.robotgryphon.compactcrafting.core.Registration;
7+
import com.robotgryphon.compactcrafting.recipes.MiniaturizationRecipe;
8+
import com.robotgryphon.compactcrafting.recipes.RecipeHelper;
69
import com.robotgryphon.compactcrafting.world.ProjectionFieldSavedData;
710
import com.robotgryphon.compactcrafting.world.ProjectorFieldData;
11+
import net.minecraft.block.BlockState;
12+
import net.minecraft.fluid.FluidState;
813
import net.minecraft.util.math.AxisAlignedBB;
914
import net.minecraft.util.math.BlockPos;
1015
import net.minecraft.world.IWorld;
16+
import net.minecraft.world.IWorldReader;
17+
import net.minecraft.world.TickPriority;
1118
import net.minecraft.world.server.ServerWorld;
1219

13-
import java.util.ArrayList;
14-
import java.util.List;
20+
import java.util.*;
1521
import java.util.stream.Stream;
1622

1723
/**
@@ -49,7 +55,23 @@ public static void checkBlockPlacement(IWorld world, BlockPos pos, BlockUpdateTy
4955
continue;
5056
}
5157

52-
tile.handleNearbyBlockUpdate(pos, type);
58+
Optional<FieldProjection> field = tile.getField();
59+
60+
if(field.isPresent()) {
61+
AxisAlignedBB fieldBounds = field.get().getBounds();
62+
63+
// Is the block update INSIDE the current field?
64+
boolean blockInField = fieldBounds
65+
.contains(pos.getX() + 0.5f, pos.getY() + 0.5f, pos.getZ() + 0.5f);
66+
67+
if(!blockInField)
68+
continue;;
69+
70+
// Schedule an update tick for half a second out, handles blocks breaking better
71+
world
72+
.getPendingBlockTicks()
73+
.scheduleTick(p, Registration.FIELD_PROJECTOR_BLOCK.get(), 10, TickPriority.NORMAL);
74+
}
5375
}
5476
}
5577

@@ -67,4 +89,39 @@ public static Stream<AxisAlignedBB> splitIntoLayers(FieldProjectionSize size, Ax
6789

6890
return Stream.of(layers);
6991
}
70-
}
92+
93+
/**
94+
* Converts a layer of a field into its relative recipe component definition.
95+
*
96+
* @param world
97+
* @param recipe
98+
* @param fieldSize
99+
* @param layer
100+
* @return
101+
*/
102+
public static Map<BlockPos, String> remapLayerToRecipe(IWorldReader world, MiniaturizationRecipe recipe, FieldProjectionSize fieldSize, AxisAlignedBB layer) {
103+
Map<BlockPos, String> relativeMap = new HashMap<>();
104+
105+
BlockPos[] filled = BlockPos.getAllInBox(layer)
106+
.filter(pos -> !world.isAirBlock(pos))
107+
.map(BlockPos::toImmutable)
108+
.toArray(BlockPos[]::new);
109+
110+
for(BlockPos pos : filled) {
111+
BlockState state = world.getBlockState(pos);
112+
FluidState fluid = world.getFluidState(pos);
113+
114+
// TODO: Fluid crafting! :D
115+
116+
Optional<String> recipeComponentKey = recipe.getRecipeComponentKey(state);
117+
if(recipeComponentKey.isPresent())
118+
{
119+
// Get relative position in layer and add to map
120+
BlockPos normalized = RecipeHelper.normalizeLayerPosition(layer, pos);
121+
relativeMap.put(normalized, recipeComponentKey.get());
122+
}
123+
}
124+
125+
return relativeMap;
126+
}
127+
}

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

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

3+
import com.robotgryphon.compactcrafting.field.FieldProjectionSize;
34
import net.minecraft.util.math.AxisAlignedBB;
45
import net.minecraft.util.math.BlockPos;
56
import net.minecraft.world.IWorldReader;
@@ -26,10 +27,11 @@ public interface IRecipeLayer {
2627
*
2728
* @param world
2829
* @param recipe
30+
* @param fieldSize
2931
* @param fieldLayer
3032
* @return
3133
*/
32-
boolean matchesFieldLayer(IWorldReader world, MiniaturizationRecipe recipe, AxisAlignedBB fieldLayer);
34+
boolean matchesFieldLayer(IWorldReader world, MiniaturizationRecipe recipe, FieldProjectionSize fieldSize, AxisAlignedBB fieldLayer);
3335

3436
/**
3537
* Gets the trimmed dimensions of the given recipe layer.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public boolean matches(IWorldReader world, FieldProjectionSize fieldSize, AxisAl
9090

9191
// Check each layer bottom to see if it matches the bottom layer of this recipe
9292
return possibleRecipeBottomLayers.stream()
93-
.anyMatch(fieldLayer -> layers[0].matchesFieldLayer(world, this, fieldLayer));
93+
.anyMatch(fieldLayer -> layers[0].matchesFieldLayer(world, this, fieldSize, fieldLayer));
9494
}
9595

9696
public ItemStack[] getOutputs() {

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

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77
import net.minecraft.util.math.vector.Vector3i;
88
import net.minecraft.world.IWorldReader;
99

10-
import java.util.*;
10+
import java.util.Arrays;
11+
import java.util.Collection;
12+
import java.util.Optional;
13+
import java.util.Set;
1114
import java.util.stream.Stream;
1215

1316
public abstract class RecipeHelper {
@@ -19,6 +22,13 @@ public static BlockState getBlockStateForNormalizedLocation(IWorldReader world,
1922
return world.getBlockState(offsetPos);
2023
}
2124

25+
public static BlockPos normalizeLayerPosition(AxisAlignedBB layerBounds, BlockPos pos) {
26+
return new BlockPos(
27+
pos.getX() - layerBounds.minX,
28+
pos.getY() - layerBounds.minY,
29+
pos.getZ() - layerBounds.minZ
30+
);
31+
}
2232
/**
2333
* Converts world-coordinate positions into relative field positions.
2434
*
@@ -30,11 +40,7 @@ public static BlockPos[] normalizeLayerPositions(AxisAlignedBB layerBounds, Bloc
3040
// Normalize the block positions so the recipe can match easier
3141
return Stream.of(fieldPositions)
3242
.parallel()
33-
.map(p -> new BlockPos(
34-
p.getX() - layerBounds.minX,
35-
p.getY() - layerBounds.minY,
36-
p.getZ() - layerBounds.minZ
37-
))
43+
.map(p -> normalizeLayerPosition(layerBounds, p))
3844
.map(BlockPos::toImmutable)
3945
.toArray(BlockPos[]::new);
4046
}
@@ -75,6 +81,7 @@ public static String[][] getTrimmedTemplateForLayer(IRecipeLayer layer, AxisAlig
7581

7682
return components;
7783
}
84+
7885
/**
7986
* Checks if a layer matches a template by extracting information about components
8087
* from the various filled positions.
@@ -88,15 +95,13 @@ public static boolean layerMatchesTemplate(IWorldReader world, MiniaturizationRe
8895
AxisAlignedBB trimmedBounds = getBoundsForBlocks(Arrays.asList(filledLocations));
8996
BlockPos[] normalizedLocations = normalizeLayerPositions(trimmedBounds, filledLocations);
9097

91-
String[][] template = getTrimmedTemplateForLayer(layer, fieldBounds);
92-
9398
// Finally, simply check the normalized template
9499
for(BlockPos pos : normalizedLocations) {
95100
String key = layer.getRequiredComponentKeyForPosition(pos);
96101
if(key == null)
97102
return false;
98103

99-
BlockState state = getBlockStateForNormalizedLocation(world, pos, layer.getDimensions());
104+
BlockState state = getBlockStateForNormalizedLocation(world, pos, fieldBounds);
100105
Optional<String> worldKey = recipe.getRecipeComponentKey(state);
101106

102107
// Is the position the correct block?

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

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

33
import com.robotgryphon.compactcrafting.CompactCrafting;
4+
import com.robotgryphon.compactcrafting.field.FieldHelper;
5+
import com.robotgryphon.compactcrafting.field.FieldProjectionSize;
46
import net.minecraft.block.BlockState;
57
import net.minecraft.util.math.AxisAlignedBB;
68
import net.minecraft.util.math.BlockPos;
@@ -39,7 +41,7 @@ public boolean hasPadding(IWorldReader world, MiniaturizationRecipe recipe) {
3941
}
4042

4143
@Override
42-
public boolean matchesFieldLayer(IWorldReader world, MiniaturizationRecipe recipe, AxisAlignedBB fieldLayer) {
44+
public boolean matchesFieldLayer(IWorldReader world, MiniaturizationRecipe recipe, FieldProjectionSize fieldSize, AxisAlignedBB fieldLayer) {
4345
Optional<BlockState> component = recipe.getRecipeComponent(componentKey);
4446
// We can't find a component definition in the recipe, so something very wrong happened
4547
if(!component.isPresent()) {
@@ -77,6 +79,7 @@ public boolean matchesFieldLayer(IWorldReader world, MiniaturizationRecipe recip
7779
// Whitespace trim done - no padding needed, min and max bounds are already correct
7880

7981
// Check recipe template against padded world layout
82+
Map<BlockPos, String> templateMap = FieldHelper.remapLayerToRecipe(world, recipe, fieldSize, fieldLayer);
8083

8184
return RecipeHelper.layerMatchesTemplate(world, recipe, this, fieldLayer, normalizedFilledPositions);
8285
}

0 commit comments

Comments
 (0)