more leti fixes

This commit is contained in:
Ella Paws 2022-02-06 17:56:03 +01:00
parent f9c6de9fec
commit 223f55d184
3 changed files with 70 additions and 72 deletions

View File

@ -25,13 +25,13 @@ import net.minecraft.world.WorldView;
public class Connector extends LetiConnectable /*implements LetiBlock, Waterloggable*/ {
static final VoxelShape BASE_SHAPE = createCuboidShape( 5d, 5d, 5d, 11d, 11d, 11d);
static final VoxelShape NORTH_SHAPE = createCuboidShape( 6d, 6d, 0d, 10d, 10d, 5d);
static final VoxelShape SOUTH_SHAPE = createCuboidShape( 6d, 6d, 11d, 10d, 10d, 16d);
static final VoxelShape EAST_SHAPE = createCuboidShape(11d, 6d, 6d, 16d, 10d, 10d);
static final VoxelShape WEST_SHAPE = createCuboidShape( 0d, 6d, 6d, 5d, 10d, 10d);
static final VoxelShape UP_SHAPE = createCuboidShape( 6d, 11d, 6d, 10d, 16d, 10d);
static final VoxelShape DOWN_SHAPE = createCuboidShape( 6d, 0d, 6d, 10d, 5d, 10d);
final VoxelShape BASE_SHAPE = createCuboidShape( 5d, 5d, 5d, 11d, 11d, 11d);
final VoxelShape NORTH_SHAPE = createCuboidShape( 6d, 6d, 0d, 10d, 10d, 5d);
final VoxelShape SOUTH_SHAPE = createCuboidShape( 6d, 6d, 11d, 10d, 10d, 16d);
final VoxelShape EAST_SHAPE = createCuboidShape(11d, 6d, 6d, 16d, 10d, 10d);
final VoxelShape WEST_SHAPE = createCuboidShape( 0d, 6d, 6d, 5d, 10d, 10d);
final VoxelShape UP_SHAPE = createCuboidShape( 6d, 11d, 6d, 10d, 16d, 10d);
final VoxelShape DOWN_SHAPE = createCuboidShape( 6d, 0d, 6d, 10d, 5d, 10d);
public Connector(net.minecraft.block.AbstractBlock.Settings settings){
super(settings);
@ -47,25 +47,8 @@ public class Connector extends LetiConnectable /*implements LetiBlock, Waterlogg
super.onBroken(world, pos, state);
LetiNetwork.remove(world, pos);
}
@Override
public BlockState getStateForNeighborUpdate(
BlockState state,
Direction side,
BlockState neighborState,
WorldAccess world,
BlockPos pos,
BlockPos neighborPos
){
// can't be assed to only update one side
// FIXME probably extremely laggy on medium to big networks
return state
.with(Properties.NORTH, LetiNetwork.connects(world.getBlockState(pos.north()), Direction.SOUTH))
.with(Properties.SOUTH, LetiNetwork.connects(world.getBlockState(pos.south()), Direction.NORTH))
.with(Properties.EAST , LetiNetwork.connects(world.getBlockState(pos.east() ), Direction.WEST ))
.with(Properties.WEST , LetiNetwork.connects(world.getBlockState(pos.west() ), Direction.EAST ))
.with(Properties.UP , LetiNetwork.connects(world.getBlockState(pos.up() ), Direction.DOWN ))
.with(Properties.DOWN , LetiNetwork.connects(world.getBlockState(pos.down() ), Direction.UP ))
/*.with(Properties.POWERED, /*powered(world.getBlockState(pos))* /false)*/;
public boolean output(/*ServerWorld world, BlockPos pos,*/ BlockState state, Direction direction){
return state.get(Properties.POWERED);
}
}

View File

@ -23,17 +23,17 @@ import net.minecraft.world.World;
import net.minecraft.world.WorldAccess;
import net.minecraft.world.WorldView;
public class LetiConnectable extends Block implements LetiBlock, Waterloggable {
public abstract class LetiConnectable extends Block implements LetiBlock, Waterloggable {
static final VoxelShape BASE_SHAPE;
static final VoxelShape NORTH_SHAPE;
static final VoxelShape SOUTH_SHAPE;
static final VoxelShape EAST_SHAPE;
static final VoxelShape WEST_SHAPE;
static final VoxelShape UP_SHAPE;
static final VoxelShape DOWN_SHAPE;
abstract final VoxelShape BASE_SHAPE;
abstract final VoxelShape NORTH_SHAPE;
abstract final VoxelShape SOUTH_SHAPE;
abstract final VoxelShape EAST_SHAPE;
abstract final VoxelShape WEST_SHAPE;
abstract final VoxelShape UP_SHAPE;
abstract final VoxelShape DOWN_SHAPE;
public LetiToggle(net.minecraft.block.AbstractBlock.Settings settings){
public LetiConnectable(net.minecraft.block.AbstractBlock.Settings settings){
super(settings);
this.setDefaultState(
this.stateManager.getDefaultState()
@ -123,10 +123,6 @@ public class LetiConnectable extends Block implements LetiBlock, Waterloggable {
public boolean connects(BlockState state, Direction direction){
return true;
}
@Override
public boolean output(/*ServerWorld world, BlockPos pos,*/ BlockState state, Direction direction){
return state.get(Properties.POWERED);
}
/*@Override
BlockState rotate(BlockState state, BlockRotation rotation){
return state;

View File

@ -5,22 +5,26 @@ import java.util.Map.Entry;
import net.minecraft.state.property.Properties;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.world.ServerWorld;
import net.minecraft.world.World;
public class LetiNetwork {
private static final Map<Entry<ServerWorld, BlockPos>, LetiNetwork> networks = Maps.newHashMap();
private ServerWorld world;
private static final Map<Entry<World, BlockPos>, LetiNetwork> networks = Maps.newHashMap();
private World world;
ArrayList<BlockPos> nodes;
ArrayList<Entry<BlockPos, Direction>> inputs;
public LetiNetwork(ServerWorld world, BlockPos pos){
boolean powered;
private LetiNetwork(World world){
this.world = world;
nodes = new ArrayList<>();
nodes.add(pos);
inputs = new ArrayList<>();
// TODO population of inputs is nowhere in the code
// NOTE handling outputs probably happens when set(boolean) updates states, but we may want to look into this further
}
private LetiNetwork(World world, BlockPos pos){
this(world);
add(pos);
}
// NOTE that this code assumes correct behaviour of callers and that it does what it's meant to do
// this is of course not ideal, but as long as it's not messed up in this mod it should be fine...
@ -29,71 +33,86 @@ public class LetiNetwork {
for(BlockPos pos : nodes){
world.setBlockState(pos, world.getBlockState(pos).with(Properties.POWERED, powered));
}
this.powered = powered;
}
// assumes that there is no node here already
public static void new(ServerWorld world, BlockPos pos){
// this name is probably a misnomer, what this code really does is finds a network for a position that isn't already in a network
public static void new(World world, BlockPos pos){
if(!(world.getBlockState(pos).getBlock() instanceof Connector))
throw new IllegalArgumentException("Only connectors may be in a network");
// check adjacent positions for networks, if >1 join them together, if >0 join the network, if 0 create a network
LetiNetwork current = null;
for(BlockPos np : neighbors(pos)){
Entry<ServerWorld, BlockPos> key = new Entry<>(world, pos);
Entry<World, BlockPos> key = new Entry<>(world, pos);
if(networks.containsKey(key)){
if(current == null){
current = networks.get(key);
current.add(pos);
}
else current.mergeWith(networks.get(key));
else if(!current.equals(networks.get(key))) current.mergeWith(networks.get(key));
}
}
if(current == null){
networks.set(new Entry<ServerWorld, BlockPos>(world, pos), new LetiNetwork(world, pos));
new LetiNetwork(world, pos);
}
}
public static LetiNetwork at(ServerWorld world, BlockPos pos){
return networks.get(new Entry<ServerWorld, BlockPos>(world, pos));
public static LetiNetwork at(World world, BlockPos pos){
return networks.get(new Entry<World, BlockPos>(world, pos));
}
private void add(ServerWorld world, BlockPos pos){
private void add(BlockPos pos){
nodes.add(pos);
networks.set(new Entry<ServerWorld, BlockPos>(world, pos), this);
networks.set(new Entry<World, BlockPos>(world, pos), this);
}
private void remove(ServerWorld world, BlockPos pos){
private static void remove(World world, BlockPos pos){
nodes.remove(pos);
networks.remove(new Entry<ServerWorld, BlockPos>(world, pos));
// FIXME known bug: won't separate networks
// start at pos, traverse neighbours (and add those searched to an array to prevent loops),
networks.remove(new Entry<World, BlockPos>(world, pos));
// start at neighbours of pos, traverse neighbours (and add those searched to an array to prevent loops),
// check if we found all (equal), report error if too many entries were found
// if fewer entries were found, traverse through all other directions and replace those to a new network
// i was thinking what if these blocks are on different networks but that should never happen
// this code is a start but recursion...
/*ArrayList<BlockPos> found;
int finds = 0;
for(BlockPos np : neighbors(pos)){
Entry<ServerWorld, BlockPos> key = new Entry<>(world, np);
if(networks.containsKey(key)){
LetiNetwork n = networks.get(key);
if(!found.contains(key.getValue())){
found.add(key.getValue());
++finds;
recurse(np);
if(nodes.contains(np)){
ArrayList<BlockPos> found = new ArrayList<>();
ArrayList<BlockPos> next = new ArrayList<>();
while(!next.isEmpty()){
for(BlockPos nep : neighbors(next.get(0))){
if(nodes.contains(nep) && !found.contains(next.get(0)))
next.add(nep);
}
found.add(next.get(0));
next.remove(0);
}
int finds = found.size();
int s = nodes.size();
if(finds > s){
throw new AssertionError("Found " + finds + " nodes; network has " + s + " nodes");
}
if(finds == s){
break;
}
// known issue: this is a lot of unnecessary overwriting
// if two blocks adjacing the removed block are connected the first network will get wiped out immediately
LetiNetwork n = new LetiNetwork(world);
for(BlockPos nep : found){
n.add(nep);
}
}
}*/
}
private void addInput(ServerWorld world, BlockPos pos, Direction direction){
}
private void addInput(World world, BlockPos pos, Direction direction){
inputs.add(new Entry<BlockPos, Direction>(pos, direction));
}
private void removeInput(ServerWorld world, BlockPos pos, Direction direction){
private void removeInput(World world, BlockPos pos, Direction direction){
inputs.remove(new Entry<BlockPos, Direction>(pos, direction));
}
private void mergeWith(LetiNetwork network){
for(BlockPos pos : nodes){
Entry<ServerWorld, BlockPos> entry = new Entry<>(world, pos)
Entry<World, BlockPos> entry = new Entry<>(world, pos)
network.add(pos);
networks.set(entry, network);
}
@ -146,7 +165,7 @@ public class LetiNetwork {
public static ArrayList<LetiNetwork> findAdjacentNetworks(){
ArrayList<LetiNetwork> ret;
for(BlockPos np : neighbors(pos)){
Entry<ServerWorld, BlockPos> key = new Entry<>(world, np);
Entry<World, BlockPos> key = new Entry<>(world, np);
if(networks.containsKey(key)){
LetiNetwork n = networks.get(key);
if(!ret.contains(n)) ret.add(n);