mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 23:27:59 +01:00
Fix crash when looking at crops in certain situations
This commit is contained in:
parent
15d43d5ab1
commit
8ab8ec9de3
3 changed files with 21 additions and 14 deletions
|
@ -1,10 +1,12 @@
|
||||||
package com.minelittlepony.unicopia.block;
|
package com.minelittlepony.unicopia.block;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import com.minelittlepony.unicopia.util.PosHelper;
|
||||||
|
|
||||||
import net.minecraft.block.Block;
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.util.shape.VoxelShape;
|
import net.minecraft.util.shape.VoxelShape;
|
||||||
import net.minecraft.util.shape.VoxelShapes;
|
import net.minecraft.util.shape.VoxelShapes;
|
||||||
import net.minecraft.world.BlockView;
|
import net.minecraft.world.BlockView;
|
||||||
|
@ -46,18 +48,10 @@ public interface SegmentedBlock {
|
||||||
boolean isNext(BlockState state);
|
boolean isNext(BlockState state);
|
||||||
|
|
||||||
default BlockPos getTip(BlockView world, BlockPos startingPos) {
|
default BlockPos getTip(BlockView world, BlockPos startingPos) {
|
||||||
while (isNext(world.getBlockState(startingPos.up())) && !world.isOutOfHeightLimit(startingPos)) {
|
return PosHelper.traverseChain(world, startingPos, Direction.UP, this::isNext);
|
||||||
startingPos = startingPos.up();
|
|
||||||
}
|
|
||||||
|
|
||||||
return startingPos;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default BlockPos getRoot(BlockView world, BlockPos startingPos) {
|
default BlockPos getRoot(BlockView world, BlockPos startingPos) {
|
||||||
while (isBase(world.getBlockState(startingPos.down())) && !world.isOutOfHeightLimit(startingPos)) {
|
return PosHelper.traverseChain(world, startingPos, Direction.DOWN, this::isBase);
|
||||||
startingPos = startingPos.down();
|
|
||||||
}
|
|
||||||
|
|
||||||
return startingPos;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ public class SegmentedCropBlock extends CropBlock implements SegmentedBlock {
|
||||||
int height = (tip.getY() - root.getY());
|
int height = (tip.getY() - root.getY());
|
||||||
|
|
||||||
BlockState tipState = world.getBlockState(tip);
|
BlockState tipState = world.getBlockState(tip);
|
||||||
double tipHeight = SegmentedBlock.getHeight(((SegmentedCropBlock)tipState.getBlock()).getAge(tipState));
|
double tipHeight = tipState.getBlock() instanceof SegmentedCropBlock tipBlock ? SegmentedBlock.getHeight(tipBlock.getAge(tipState)) : 0;
|
||||||
|
|
||||||
double offset = (root.getY() - pos.getY()) * 16;
|
double offset = (root.getY() - pos.getY()) * 16;
|
||||||
|
|
||||||
|
@ -106,16 +106,16 @@ public class SegmentedCropBlock extends CropBlock implements SegmentedBlock {
|
||||||
@Override
|
@Override
|
||||||
public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
|
public void randomTick(BlockState state, ServerWorld world, BlockPos pos, Random random) {
|
||||||
BlockPos tip = getTip(world, pos);
|
BlockPos tip = getTip(world, pos);
|
||||||
BlockPos base = getRoot(world, pos);
|
BlockPos root = getRoot(world, pos);
|
||||||
|
|
||||||
if (base.getY() != pos.getY()) {
|
if (root.getY() != pos.getY()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (world.getBaseLightLevel(tip, 0) >= 9) {
|
if (world.getBaseLightLevel(tip, 0) >= 9) {
|
||||||
int age = getAge(state);
|
int age = getAge(state);
|
||||||
if (age < getMaxAge()) {
|
if (age < getMaxAge()) {
|
||||||
float moisture = CropBlock.getAvailableMoisture(world.getBlockState(base).getBlock(), world, base);
|
float moisture = CropBlock.getAvailableMoisture(world.getBlockState(root).getBlock(), world, root);
|
||||||
if (random.nextInt((int)(BASE_GROWTH_CHANCE / moisture) + 1) == 0) {
|
if (random.nextInt((int)(BASE_GROWTH_CHANCE / moisture) + 1) == 0) {
|
||||||
world.setBlockState(pos, withAge(age + 1), Block.NOTIFY_LISTENERS);
|
world.setBlockState(pos, withAge(age + 1), Block.NOTIFY_LISTENERS);
|
||||||
propagateGrowth(world, pos, state);
|
propagateGrowth(world, pos, state);
|
||||||
|
|
|
@ -11,11 +11,13 @@ import java.util.stream.StreamSupport;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
import net.minecraft.util.math.Direction.Axis;
|
import net.minecraft.util.math.Direction.Axis;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.util.math.Vec3i;
|
import net.minecraft.util.math.Vec3i;
|
||||||
|
import net.minecraft.world.BlockView;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public interface PosHelper {
|
public interface PosHelper {
|
||||||
|
@ -65,4 +67,15 @@ public interface PosHelper {
|
||||||
}
|
}
|
||||||
}, false);
|
}, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static BlockPos traverseChain(BlockView world, BlockPos startingPos, Direction chainDirection, Predicate<BlockState> isInChain) {
|
||||||
|
BlockPos.Mutable mutablePos = new BlockPos.Mutable();
|
||||||
|
mutablePos.set(startingPos);
|
||||||
|
do {
|
||||||
|
mutablePos.move(chainDirection);
|
||||||
|
} while (isInChain.test(world.getBlockState(mutablePos)) && !world.isOutOfHeightLimit(mutablePos));
|
||||||
|
|
||||||
|
mutablePos.move(chainDirection.getOpposite());
|
||||||
|
return mutablePos.toImmutable();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue