Skip to content

Commit c7ffb75

Browse files
committed
Fields: Add a bunch of utility code for offsets and calculations
1 parent 856a026 commit c7ffb75

File tree

6 files changed

+441
-111
lines changed

6 files changed

+441
-111
lines changed

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

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,35 @@
22

33
import com.robotgryphon.compactcrafting.blocks.tiles.FieldProjectorTile;
44
import com.robotgryphon.compactcrafting.core.Registration;
5+
import com.robotgryphon.compactcrafting.field.ProjectorHelper;
56
import mcjty.theoneprobe.api.IProbeHitData;
67
import mcjty.theoneprobe.api.IProbeInfo;
78
import mcjty.theoneprobe.api.IProbeInfoProvider;
89
import mcjty.theoneprobe.api.ProbeMode;
910
import net.minecraft.block.Block;
10-
import net.minecraft.block.BlockRenderType;
1111
import net.minecraft.block.BlockState;
1212
import net.minecraft.entity.LivingEntity;
1313
import net.minecraft.entity.player.PlayerEntity;
1414
import net.minecraft.item.ItemStack;
15+
import net.minecraft.particles.ParticleTypes;
1516
import net.minecraft.state.DirectionProperty;
1617
import net.minecraft.state.StateContainer;
1718
import net.minecraft.tileentity.TileEntity;
19+
import net.minecraft.util.ActionResultType;
1820
import net.minecraft.util.Direction;
21+
import net.minecraft.util.Hand;
1922
import net.minecraft.util.math.BlockPos;
23+
import net.minecraft.util.math.BlockRayTraceResult;
2024
import net.minecraft.util.math.shapes.VoxelShape;
2125
import net.minecraft.util.math.shapes.VoxelShapes;
2226
import net.minecraft.world.IBlockReader;
27+
import net.minecraft.world.IWorld;
28+
import net.minecraft.world.IWorldReader;
2329
import net.minecraft.world.World;
30+
import net.minecraft.world.server.ServerWorld;
2431

2532
import javax.annotation.Nullable;
33+
import java.util.Optional;
2634

2735
public class FieldProjectorBlock extends Block implements IProbeInfoProvider {
2836

@@ -35,6 +43,17 @@ public FieldProjectorBlock(Properties properties) {
3543
.with(FACING, Direction.NORTH));
3644
}
3745

46+
public static Optional<Direction> getDirection(IWorldReader world, BlockPos position) {
47+
BlockState positionState = world.getBlockState(position);
48+
49+
// The passed block position was not a field projector, cannot continue
50+
if (!(positionState.getBlock() instanceof FieldProjectorBlock))
51+
return Optional.empty();
52+
53+
Direction facing = positionState.get(FieldProjectorBlock.FACING);
54+
return Optional.of(facing);
55+
}
56+
3857
@Override
3958
public VoxelShape getRenderShape(BlockState state, IBlockReader worldIn, BlockPos pos) {
4059
return VoxelShapes.empty();
@@ -67,6 +86,37 @@ public void addProbeInfo(ProbeMode probeMode, IProbeInfo iProbeInfo, PlayerEntit
6786

6887
}
6988

89+
@Override
90+
public ActionResultType onBlockActivated(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand handIn, BlockRayTraceResult hit) {
91+
if(world.isRemote)
92+
return ActionResultType.PASS;
93+
94+
FieldProjectorTile tile = (FieldProjectorTile) world.getTileEntity(pos);
95+
96+
// Shouldn't happen, but safety
97+
if(tile == null)
98+
return ActionResultType.PASS;
99+
100+
Optional<BlockPos> oppositeProjector = tile.getOppositeProjector();
101+
if(!oppositeProjector.isPresent()) {
102+
// Spawn particle in valid places
103+
104+
ProjectorHelper.getValidOppositePositions(world, pos)
105+
.forEach(opp -> {
106+
((ServerWorld) world).spawnParticle(ParticleTypes.BARRIER,
107+
opp.getX() + 0.5f,
108+
opp.getY() + 0.5f,
109+
opp.getZ() + 0.5f,
110+
1,
111+
0, 0, 0, 0);
112+
});
113+
114+
return ActionResultType.SUCCESS;
115+
}
116+
117+
return ActionResultType.PASS;
118+
}
119+
70120
@Override
71121
public void onBlockPlacedBy(World worldIn, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack stack) {
72122
Direction facing = placer.getHorizontalFacing();
@@ -75,4 +125,27 @@ public void onBlockPlacedBy(World worldIn, BlockPos pos, BlockState state, @Null
75125

76126
// Add owner information to field projector
77127
}
128+
129+
@Override
130+
public void onPlayerDestroy(IWorld world, BlockPos pos, BlockState state) {
131+
132+
if(world.isRemote())
133+
return;
134+
135+
FieldProjectorTile te = (FieldProjectorTile) world.getTileEntity(pos);
136+
if(te == null)
137+
return;
138+
139+
if(!te.isMainProjector()) {
140+
Optional<BlockPos> mainProjectorPosition = te.getMainProjectorPosition();
141+
if(!mainProjectorPosition.isPresent())
142+
return;
143+
144+
FieldProjectorTile mainProjectorTE = (FieldProjectorTile) world.getTileEntity(mainProjectorPosition.get());
145+
if(mainProjectorTE == null)
146+
return;
147+
148+
mainProjectorTE.invalidateField();
149+
}
150+
}
78151
}
Lines changed: 100 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,41 @@
11
package com.robotgryphon.compactcrafting.blocks.tiles;
22

3-
import com.robotgryphon.compactcrafting.CompactCrafting;
43
import com.robotgryphon.compactcrafting.blocks.FieldProjectorBlock;
5-
import com.robotgryphon.compactcrafting.core.FieldProjectionSize;
4+
import com.robotgryphon.compactcrafting.field.FieldProjection;
5+
import com.robotgryphon.compactcrafting.field.FieldProjectionSize;
66
import com.robotgryphon.compactcrafting.core.Registration;
77
import com.robotgryphon.compactcrafting.crafting.CraftingHelper;
88
import net.minecraft.block.BlockState;
99
import net.minecraft.entity.item.ItemEntity;
10-
import net.minecraft.entity.player.PlayerEntity;
1110
import net.minecraft.item.Item;
1211
import net.minecraft.item.ItemStack;
1312
import net.minecraft.item.Items;
14-
import net.minecraft.particles.ParticleTypes;
1513
import net.minecraft.tileentity.ITickableTileEntity;
1614
import net.minecraft.tileentity.TileEntity;
17-
import net.minecraft.tileentity.TileEntityType;
1815
import net.minecraft.util.Direction;
1916
import net.minecraft.util.math.AxisAlignedBB;
2017
import net.minecraft.util.math.BlockPos;
21-
import net.minecraft.util.math.vector.Vector3d;
22-
import net.minecraft.util.math.vector.Vector3f;
23-
import net.minecraft.util.math.vector.Vector3i;
24-
import net.minecraftforge.items.ItemHandlerHelper;
2518

19+
import java.time.Instant;
2620
import java.util.*;
2721
import java.util.stream.Collectors;
28-
import java.util.stream.Stream;
2922

3023
public class FieldProjectorTile extends TileEntity implements ITickableTileEntity {
3124

32-
private FieldProjectionSize projectionSize = FieldProjectionSize.MEDIUM;
25+
private boolean isCrafting = false;
26+
private Optional<FieldProjection> field = Optional.empty();
27+
private int fieldCheckTimeout = 0;
3328

3429
public FieldProjectorTile() {
3530
super(Registration.FIELD_PROJECTOR_TILE.get());
3631
}
3732

38-
public Optional<BlockPos> getCenter() {
39-
BlockState bs = this.getBlockState();
40-
Direction facing = bs.get(FieldProjectorBlock.FACING);
41-
42-
43-
Optional<BlockPos> location = getOppositeProjector();
44-
if (location.isPresent()) {
45-
BlockPos opp = location.get();
46-
int centerOffset = opp.manhattanDistance(pos);
47-
48-
BlockPos center = pos.offset(facing, centerOffset / 2);
49-
return Optional.of(center);
50-
} else {
51-
// No center -- no found opposite
52-
return Optional.empty();
53-
}
54-
}
55-
56-
public Optional<FieldProjectionSize> getFieldSize() {
57-
BlockState bs = this.getBlockState();
58-
Direction facing = bs.get(FieldProjectorBlock.FACING);
59-
60-
Optional<FieldProjectionSize> matchedSize = Arrays
61-
.stream(FieldProjectionSize.values())
62-
.sorted(Comparator.comparingInt(FieldProjectionSize::getOffset))
63-
.filter(size -> {
64-
// check block exists in offset position
65-
BlockPos offsetInDirection = pos.offset(facing, size.getOffset() + 1);
66-
BlockState stateInPos = world.getBlockState(offsetInDirection);
67-
68-
if (stateInPos.getBlock() instanceof FieldProjectorBlock) {
69-
// We have a field projector
70-
Direction otherFpDirection = stateInPos.get(FieldProjectorBlock.FACING);
71-
if (otherFpDirection == facing.getOpposite())
72-
return true;
73-
}
74-
75-
return false;
76-
})
77-
.findFirst();
33+
@Override
34+
public void remove() {
35+
super.remove();
7836

79-
return matchedSize;
37+
// Invalidate field
38+
invalidateField();
8039
}
8140

8241
/**
@@ -85,15 +44,16 @@ public Optional<FieldProjectionSize> getFieldSize() {
8544
* @return
8645
*/
8746
public Optional<BlockPos> getOppositeProjector() {
88-
Optional<FieldProjectionSize> size = getFieldSize();
89-
if(size.isPresent()) {
90-
int offset = size.get().getOffset() + 1;
91-
BlockPos opposite = getPos().offset(getFacing(), offset);
47+
if (!field.isPresent())
48+
return Optional.empty();
9249

93-
return Optional.of(opposite);
94-
}
50+
FieldProjection field = this.field.get();
51+
FieldProjectionSize size = field.getFieldSize();
9552

96-
return Optional.empty();
53+
int offset = (size.getOffset() * 2) + 1;
54+
BlockPos opposite = getPos().offset(getFacing(), offset);
55+
56+
return Optional.of(opposite);
9757
}
9858

9959
public Direction getFacing() {
@@ -115,49 +75,87 @@ public boolean isMainProjector() {
11575
return side == Direction.NORTH;
11676
}
11777

78+
public Optional<BlockPos> getMainProjectorPosition() {
79+
if (this.isMainProjector())
80+
return Optional.of(this.pos);
81+
82+
if (this.field.isPresent()) {
83+
FieldProjection fp = this.field.get();
84+
BlockPos north = fp.getProjectorInDirection(Direction.NORTH);
85+
86+
return Optional.of(north);
87+
}
88+
89+
return Optional.empty();
90+
}
91+
92+
public void invalidateField() {
93+
this.field = Optional.empty();
94+
this.fieldCheckTimeout = 20;
95+
}
96+
11897
@Override
11998
public void tick() {
120-
if (!isMainProjector())
121-
return;
122-
123-
Optional<AxisAlignedBB> fieldBounds = getFieldBounds();
124-
if (fieldBounds.isPresent()) {
125-
// TODO: Check crafting state of projection field, update that state instead of doing manual work here
126-
boolean hasCatalyst = hasCatalystInBounds(fieldBounds.get(), Items.ENDER_PEARL);
127-
128-
if (hasCatalyst) {
129-
List<ItemEntity> enderPearls = getCatalystsInField(fieldBounds.get(), Items.ENDER_PEARL);
130-
131-
// We dropped an ender pearl in - are there any blocks in the field?
132-
// If so, we'll need to check the recipes -- but for now we just use it to
133-
// not delete the item if there's nothing in here
134-
if (CraftingHelper.hasBlocksInField(world, fieldBounds.get())) {
135-
CraftingHelper.deleteCraftingBlocks(world, fieldBounds.get());
136-
CraftingHelper.consumeCatalystItem(enderPearls.get(0), 1);
137-
}
99+
// If we don't have a valid field, search again
100+
if (!field.isPresent()) {
101+
if (fieldCheckTimeout > 0) {
102+
fieldCheckTimeout--;
103+
return;
138104
}
105+
106+
// Check timeout has elapsed, run field scan
107+
doFieldCheck();
108+
109+
// If we still don't have a valid field, get out of tick logic
110+
if (!field.isPresent())
111+
return;
112+
}
113+
114+
if (fieldCheckTimeout > 0) {
115+
fieldCheckTimeout--;
116+
} else {
117+
doFieldCheck();
139118
}
140119
}
141120

142-
private Optional<AxisAlignedBB> getFieldBounds() {
143-
Optional<BlockPos> center = getCenter();
121+
/**
122+
* Invalidates the current field projection and attempts to rebuild it from this position as an initial.
123+
*/
124+
private void doFieldCheck() {
125+
Optional<FieldProjection> field = FieldProjection.tryCreateFromPosition(world, this.pos);
126+
if (field.isPresent()) {
127+
this.field = field;
128+
return;
129+
}
144130

145-
// No center area - no other projector present
146-
if (!center.isPresent())
147-
return Optional.empty();
131+
this.field = Optional.empty();
148132

149-
BlockPos centerPos = center.get();
150-
Optional<FieldProjectionSize> size = this.getFieldSize();
151-
if(size.isPresent()) {
152-
AxisAlignedBB bounds = new AxisAlignedBB(centerPos).grow(size.get().getSize());
133+
// If we didn't find a valid field, restart timer and keep looking
134+
fieldCheckTimeout = 20;
135+
}
153136

154-
return Optional.of(bounds);
155-
}
137+
private void beginCraft() {
138+
this.isCrafting = true;
139+
}
156140

157-
// No valid field found
158-
return Optional.empty();
141+
private void tickCrafting() {
142+
FieldProjection fp = this.field.get();
143+
Optional<AxisAlignedBB> fieldBounds = fp.getBounds();
144+
145+
List<ItemEntity> enderPearls = getCatalystsInField(fieldBounds.get(), Items.ENDER_PEARL);
146+
147+
// We dropped an ender pearl in - are there any blocks in the field?
148+
// If so, we'll need to check the recipes -- but for now we just use it to
149+
// not delete the item if there's nothing in here
150+
if (CraftingHelper.hasBlocksInField(world, fieldBounds.get())) {
151+
CraftingHelper.deleteCraftingBlocks(world, fieldBounds.get());
152+
CraftingHelper.consumeCatalystItem(enderPearls.get(0), 1);
153+
154+
this.isCrafting = false;
155+
}
159156
}
160157

158+
161159
private List<ItemEntity> getCatalystsInField(AxisAlignedBB fieldBounds, Item itemFilter) {
162160
List<ItemEntity> itemsInRange = world.getEntitiesWithinAABB(ItemEntity.class, fieldBounds);
163161
return itemsInRange.stream()
@@ -180,7 +178,6 @@ private boolean hasCatalystInBounds(AxisAlignedBB bounds, Item itemFilter) {
180178

181179
private int collectItems(List<ItemEntity> itemsInRange) {
182180
return itemsInRange.stream()
183-
// .filter(ise -> ise.getItem().getItem() == item)
184181
.map(ItemEntity::getItem)
185182
.map(ItemStack::getCount)
186183
.mapToInt(Integer::intValue)
@@ -189,11 +186,20 @@ private int collectItems(List<ItemEntity> itemsInRange) {
189186

190187
@Override
191188
public AxisAlignedBB getRenderBoundingBox() {
192-
Optional<AxisAlignedBB> field = this.getFieldBounds();
193-
if (field.isPresent()) {
194-
return field.get().grow(10);
189+
// Check - if we have a valid field use the entire field plus space
190+
// Otherwise just use the super implementation
191+
if (this.field.isPresent()) {
192+
FieldProjection fp = this.field.get();
193+
if (!fp.getBounds().isPresent())
194+
return super.getRenderBoundingBox();
195+
196+
return fp.getBounds().get().grow(10);
195197
}
196198

197199
return super.getRenderBoundingBox();
198200
}
201+
202+
public Optional<FieldProjection> getField() {
203+
return this.field;
204+
}
199205
}

0 commit comments

Comments
 (0)