Skip to content

Commit 244c2aa

Browse files
committed
Improve missing projector handling
1 parent b6715e0 commit 244c2aa

File tree

3 files changed

+140
-57
lines changed

3 files changed

+140
-57
lines changed

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

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

3+
import com.robotgryphon.compactcrafting.field.FieldProjectionSize;
34
import com.robotgryphon.compactcrafting.field.ProjectorHelper;
45
import net.minecraft.block.Block;
56
import net.minecraft.block.BlockState;
@@ -18,7 +19,6 @@
1819
import net.minecraft.util.math.shapes.VoxelShape;
1920
import net.minecraft.util.math.shapes.VoxelShapes;
2021
import net.minecraft.world.IBlockReader;
21-
import net.minecraft.world.IWorld;
2222
import net.minecraft.world.IWorldReader;
2323
import net.minecraft.world.World;
2424
import net.minecraft.world.server.ServerWorld;
@@ -32,15 +32,15 @@
3232
//import mcjty.theoneprobe.api.IProbeInfoProvider;
3333
//import mcjty.theoneprobe.api.ProbeMode;
3434

35-
public class FieldProjectorBlock extends Block {
35+
public class FieldProjectorBlock extends Block {
3636

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

3939
public FieldProjectorBlock(Properties properties) {
4040
super(properties);
4141

4242
setDefaultState(getStateContainer().getBaseState()
43-
.with(FACING, Direction.NORTH));
43+
.with(FACING, Direction.NORTH));
4444
}
4545

4646
public static Optional<Direction> getDirection(IWorldReader world, BlockPos position) {
@@ -58,7 +58,7 @@ public static Optional<Direction> getDirection(IWorldReader world, BlockPos posi
5858
@SuppressWarnings("deprecation")
5959
public void tick(BlockState state, ServerWorld worldIn, BlockPos pos, Random rand) {
6060
FieldProjectorTile tile = (FieldProjectorTile) worldIn.getTileEntity(pos);
61-
if(tile == null)
61+
if (tile == null)
6262
return;
6363

6464
tile.doRecipeScan();
@@ -91,64 +91,93 @@ public TileEntity createTileEntity(BlockState state, IBlockReader world) {
9191
@Override
9292
@SuppressWarnings("deprecation")
9393
public ActionResultType onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) {
94-
if(world.isRemote)
94+
if (world.isRemote)
9595
return ActionResultType.SUCCESS;
9696

9797
FieldProjectorTile tile = (FieldProjectorTile) world.getTileEntity(pos);
9898

9999
// Shouldn't happen, but safety
100-
if(tile == null)
100+
if (tile == null)
101101
return ActionResultType.PASS;
102102

103-
Optional<BlockPos> oppositeProjector = tile.getOppositeProjector();
104-
if(!oppositeProjector.isPresent()) {
103+
104+
Optional<FieldProjectionSize> fieldSize = ProjectorHelper.getClosestOppositeSize(world, pos);
105+
if (!fieldSize.isPresent()) {
105106
// Spawn particle in valid places
106107

107108
ProjectorHelper.getValidOppositePositions(world, pos)
108-
.forEach(opp -> {
109-
((ServerWorld) world).spawnParticle(ParticleTypes.BARRIER,
110-
opp.getX() + 0.5f,
111-
opp.getY() + 0.5f,
112-
opp.getZ() + 0.5f,
113-
1,
114-
0, 0, 0, 0);
115-
});
109+
.forEach(opp -> spawnPlacementParticle((ServerWorld) world, opp));
116110

117-
return ActionResultType.SUCCESS;
118-
}
111+
} else {
112+
FieldProjectionSize size = fieldSize.get();
119113

120-
return ActionResultType.PASS;
121-
}
114+
Optional<BlockPos> centerForSize = ProjectorHelper.getCenterForSize(world, pos, size);
115+
centerForSize.ifPresent(center -> {
116+
Direction.Axis a = state.get(FACING).getAxis();
117+
Direction.Axis opp;
118+
switch (a) {
119+
case X:
120+
opp = Direction.Axis.Z;
121+
break;
122122

123-
@Override
124-
public void onBlockPlacedBy(World worldIn, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
125-
Direction facing = placer.getHorizontalFacing();
123+
case Z:
124+
opp = Direction.Axis.X;
125+
break;
126126

127-
worldIn.setBlockState(pos, state.with(FACING, facing));
127+
default:
128+
return;
129+
}
128130

129-
// Add owner information to field projector
130-
}
131+
ProjectorHelper.getProjectorLocationsForAxis(center, opp, size)
132+
.forEach(loc -> spawnPlacementParticle((ServerWorld) world, loc));
133+
});
131134

132-
@Override
133-
public void onPlayerDestroy(IWorld world, BlockPos pos, BlockState state) {
135+
}
136+
return ActionResultType.SUCCESS;
137+
}
134138

135-
if(world.isRemote())
139+
private static void spawnPlacementParticle(ServerWorld world, BlockPos opp) {
140+
if(world.getBlockState(opp).getBlock() instanceof FieldProjectorBlock)
136141
return;
137142

138-
FieldProjectorTile te = (FieldProjectorTile) world.getTileEntity(pos);
139-
if(te == null)
140-
return;
143+
world.spawnParticle(ParticleTypes.BARRIER,
144+
opp.getX() + 0.5f,
145+
opp.getY() + 0.5f,
146+
opp.getZ() + 0.5f,
147+
1,
148+
0, 0, 0, 0);
149+
}
141150

142-
if(!te.isMainProjector()) {
143-
Optional<BlockPos> mainProjectorPosition = te.getMainProjectorPosition();
144-
if(!mainProjectorPosition.isPresent())
145-
return;
151+
@Override
152+
public void onBlockPlacedBy(World worldIn, BlockPos pos, BlockState state, @Nullable LivingEntity
153+
placer, ItemStack stack) {
154+
Direction facing = placer.getHorizontalFacing();
146155

147-
FieldProjectorTile mainProjectorTE = (FieldProjectorTile) world.getTileEntity(mainProjectorPosition.get());
148-
if(mainProjectorTE == null)
149-
return;
156+
worldIn.setBlockState(pos, state.with(FACING, facing));
150157

151-
mainProjectorTE.invalidateField();
152-
}
158+
// Add owner information to field projector
153159
}
160+
161+
// TODO: Finish in alpha 3, or next major bugfix run
162+
// @Override
163+
// public void onPlayerDestroy(IWorld world, BlockPos pos, BlockState state) {
164+
//
165+
// if (world.isRemote())
166+
// return;
167+
//
168+
// Direction f = state.get(FACING);
169+
// ProjectorHelper.getClosestOppositeSize(world, pos, f)
170+
// .ifPresent(fieldSize -> {
171+
// Optional<BlockPos> centerForSize = ProjectorHelper.getCenterForSize(pos, f, fieldSize);
172+
// centerForSize.ifPresent(center -> {
173+
// BlockPos mainProjectorPosition = ProjectorHelper.getProjectorLocationForDirection(center, Direction.NORTH, fieldSize);
174+
//
175+
// FieldProjectorTile mainProjectorTE = (FieldProjectorTile) world.getTileEntity(mainProjectorPosition);
176+
// if (mainProjectorTE == null)
177+
// return;
178+
//
179+
// mainProjectorTE.invalidateField();
180+
// });
181+
// });
182+
// }
154183
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ public void doRecipeScan() {
200200
if (!center.isPresent())
201201
return;
202202

203-
BlockPos masterPos = ProjectorHelper.getProjectorLocationForDirection(world, center.get(), Direction.NORTH, size);
203+
BlockPos masterPos = ProjectorHelper.getProjectorLocationForDirection(center.get(), Direction.NORTH, size);
204204

205205
FieldProjectorTile masterTile = (FieldProjectorTile) world.getTileEntity(masterPos);
206206
if (masterTile == null)

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

Lines changed: 69 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import net.minecraft.util.math.BlockPos;
77
import net.minecraft.world.IWorldReader;
88

9-
import java.util.Optional;
9+
import java.util.*;
1010
import java.util.stream.Stream;
1111

1212
/**
@@ -36,20 +36,58 @@ public static Optional<BlockPos> getCenterForSize(IWorldReader world, BlockPos i
3636
return Optional.of(center);
3737
}
3838

39-
public static Optional<BlockPos> getOppositeForSize(IWorldReader world, BlockPos initial, FieldProjectionSize size) {
40-
Optional<BlockPos> center = getCenterForSize(world, initial, size);
41-
if(!center.isPresent())
42-
return Optional.empty();
39+
public static Optional<BlockPos> getCenterForSize(BlockPos initial, Direction facing, FieldProjectionSize size) {
40+
BlockPos center = initial.offset(facing, size.getProjectorDistance() + 1);
41+
return Optional.of(center);
42+
}
43+
44+
public static Optional<BlockPos> getOppositePositionForSize(BlockPos initial, Direction direction, FieldProjectionSize size) {
45+
BlockPos center = initial.offset(direction, size.getProjectorDistance() + 1);
46+
BlockPos opp = center.offset(direction, size.getProjectorDistance() + 1);
47+
48+
return Optional.of(opp);
49+
}
50+
51+
public static Optional<BlockPos> getOppositePositionForSize(IWorldReader world, BlockPos initial, FieldProjectionSize size) {
52+
Optional<Direction> facing = FieldProjectorBlock.getDirection(world, initial);
4353

44-
Optional<Direction> direction = FieldProjectorBlock.getDirection(world, initial);
45-
if(!direction.isPresent())
54+
// Initial wasn't a valid field projector, can't get direction to look in
55+
if (!facing.isPresent())
4656
return Optional.empty();
4757

48-
BlockPos projectorLocationForDirection = getProjectorLocationForDirection(world, center.get(), direction.get(), size);
49-
return Optional.of(projectorLocationForDirection);
58+
Direction fieldDirection = facing.get();
59+
return getOppositePositionForSize(initial, fieldDirection, size);
60+
}
61+
62+
public static Optional<FieldProjectionSize> getClosestOppositeSize(IWorldReader world, BlockPos initial) {
63+
for (FieldProjectionSize size : FieldProjectionSize.values()) {
64+
if (hasProjectorOpposite(world, initial, size)) {
65+
return Optional.of(size);
66+
}
67+
}
68+
69+
return Optional.empty();
70+
}
71+
72+
public static Optional<FieldProjectionSize> getClosestOppositeSize(IWorldReader world, BlockPos initial, Direction look) {
73+
for (FieldProjectionSize size : FieldProjectionSize.values()) {
74+
if (hasProjectorOpposite(world, initial, look, size)) {
75+
return Optional.of(size);
76+
}
77+
}
78+
79+
return Optional.empty();
80+
}
81+
82+
public static Set<BlockPos> getProjectorLocationsForAxis(BlockPos center, Direction.Axis axis, FieldProjectionSize size) {
83+
Direction posdir = Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis);
84+
BlockPos posLocation = ProjectorHelper.getProjectorLocationForDirection(center, posdir, size);
85+
BlockPos negLocation = ProjectorHelper.getProjectorLocationForDirection(center, posdir.getOpposite(), size);
86+
87+
return new HashSet<>(Arrays.asList(posLocation, negLocation));
5088
}
5189

52-
public static BlockPos getProjectorLocationForDirection(IWorldReader world, BlockPos center, Direction direction, FieldProjectionSize size) {
90+
public static BlockPos getProjectorLocationForDirection(BlockPos center, Direction direction, FieldProjectionSize size) {
5391
BlockPos location = center.offset(direction, size.getProjectorDistance() + 1);
5492
return location;
5593
}
@@ -63,8 +101,8 @@ public static BlockPos getProjectorLocationForDirection(IWorldReader world, Bloc
63101
* @param size The field size to check.
64102
* @return
65103
*/
66-
public static boolean hasValidProjectorInDirection(IWorldReader world, BlockPos center, Direction direction, FieldProjectionSize size) {
67-
BlockPos location = getProjectorLocationForDirection(world, center, direction, size);
104+
public static boolean hasProjectorInDirection(IWorldReader world, BlockPos center, Direction direction, FieldProjectionSize size) {
105+
BlockPos location = getProjectorLocationForDirection(center, direction, size);
68106
BlockState state = world.getBlockState(location);
69107

70108
if (state.getBlock() instanceof FieldProjectorBlock) {
@@ -75,6 +113,20 @@ public static boolean hasValidProjectorInDirection(IWorldReader world, BlockPos
75113
return false;
76114
}
77115

116+
public static boolean hasProjectorOpposite(IWorldReader world, BlockPos initial, FieldProjectionSize size) {
117+
Optional<BlockPos> opp = getOppositePositionForSize(world, initial, size);
118+
return opp
119+
.map(possible -> world.getBlockState(possible).getBlock() instanceof FieldProjectorBlock)
120+
.orElse(false);
121+
}
122+
123+
public static boolean hasProjectorOpposite(IWorldReader world, BlockPos initial, Direction look, FieldProjectionSize size) {
124+
Optional<BlockPos> opp = getOppositePositionForSize(initial, look, size);
125+
return opp
126+
.map(possible -> world.getBlockState(possible).getBlock() instanceof FieldProjectorBlock)
127+
.orElse(false);
128+
}
129+
78130
/**
79131
* Checks an axis to see if, given a field size, there are two valid projectors.
80132
*
@@ -91,12 +143,12 @@ public static boolean checkAxisForValidProjectors(IWorldReader world, BlockPos c
91143
Direction checkDirection = Direction.getFacingFromAxisDirection(primaryAxis, Direction.AxisDirection.POSITIVE);
92144

93145
// Do we have a valid projector in the first direction?
94-
boolean posValid = hasValidProjectorInDirection(world, center, checkDirection, fieldSize);
146+
boolean posValid = hasProjectorInDirection(world, center, checkDirection, fieldSize);
95147
if (!posValid)
96148
return false;
97149

98150
// What about the negative direction?
99-
boolean negValid = hasValidProjectorInDirection(world, center, checkDirection.getOpposite(), fieldSize);
151+
boolean negValid = hasProjectorInDirection(world, center, checkDirection.getOpposite(), fieldSize);
100152
if (!negValid)
101153
return false;
102154

@@ -124,10 +176,12 @@ public static boolean checkProjectorsValid(IWorldReader world, BlockPos center,
124176

125177
public static Stream<BlockPos> getValidOppositePositions(IWorldReader world, BlockPos initial) {
126178
Stream<BlockPos> validOpposites = Stream.of(FieldProjectionSize.values())
127-
.map(s -> getOppositeForSize(world, initial, s))
179+
.map(s -> getOppositePositionForSize(world, initial, s))
128180
.filter(Optional::isPresent)
129181
.map(Optional::get);
130182

131183
return validOpposites;
132184
}
185+
186+
133187
}

0 commit comments

Comments
 (0)