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*/ { public class Connector extends LetiConnectable /*implements LetiBlock, Waterloggable*/ {
static final VoxelShape BASE_SHAPE = createCuboidShape( 5d, 5d, 5d, 11d, 11d, 11d); final VoxelShape BASE_SHAPE = createCuboidShape( 5d, 5d, 5d, 11d, 11d, 11d);
static final VoxelShape NORTH_SHAPE = createCuboidShape( 6d, 6d, 0d, 10d, 10d, 5d); final VoxelShape NORTH_SHAPE = createCuboidShape( 6d, 6d, 0d, 10d, 10d, 5d);
static final VoxelShape SOUTH_SHAPE = createCuboidShape( 6d, 6d, 11d, 10d, 10d, 16d); final VoxelShape SOUTH_SHAPE = createCuboidShape( 6d, 6d, 11d, 10d, 10d, 16d);
static final VoxelShape EAST_SHAPE = createCuboidShape(11d, 6d, 6d, 16d, 10d, 10d); final VoxelShape EAST_SHAPE = createCuboidShape(11d, 6d, 6d, 16d, 10d, 10d);
static final VoxelShape WEST_SHAPE = createCuboidShape( 0d, 6d, 6d, 5d, 10d, 10d); final VoxelShape WEST_SHAPE = createCuboidShape( 0d, 6d, 6d, 5d, 10d, 10d);
static final VoxelShape UP_SHAPE = createCuboidShape( 6d, 11d, 6d, 10d, 16d, 10d); 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 DOWN_SHAPE = createCuboidShape( 6d, 0d, 6d, 10d, 5d, 10d);
public Connector(net.minecraft.block.AbstractBlock.Settings settings){ public Connector(net.minecraft.block.AbstractBlock.Settings settings){
super(settings); super(settings);
@ -47,25 +47,8 @@ public class Connector extends LetiConnectable /*implements LetiBlock, Waterlogg
super.onBroken(world, pos, state); super.onBroken(world, pos, state);
LetiNetwork.remove(world, pos); LetiNetwork.remove(world, pos);
} }
@Override @Override
public BlockState getStateForNeighborUpdate( public boolean output(/*ServerWorld world, BlockPos pos,*/ BlockState state, Direction direction){
BlockState state, return state.get(Properties.POWERED);
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)*/;
} }
} }

View File

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

View File

@ -5,22 +5,26 @@ import java.util.Map.Entry;
import net.minecraft.state.property.Properties; import net.minecraft.state.property.Properties;
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.world.ServerWorld; import net.minecraft.world.World;
public class LetiNetwork { public class LetiNetwork {
private static final Map<Entry<ServerWorld, BlockPos>, LetiNetwork> networks = Maps.newHashMap(); private static final Map<Entry<World, BlockPos>, LetiNetwork> networks = Maps.newHashMap();
private ServerWorld world; private World world;
ArrayList<BlockPos> nodes; ArrayList<BlockPos> nodes;
ArrayList<Entry<BlockPos, Direction>> inputs; ArrayList<Entry<BlockPos, Direction>> inputs;
public LetiNetwork(ServerWorld world, BlockPos pos){ boolean powered;
private LetiNetwork(World world){
this.world = world; this.world = world;
nodes = new ArrayList<>(); nodes = new ArrayList<>();
nodes.add(pos);
inputs = new ArrayList<>(); inputs = new ArrayList<>();
// TODO population of inputs is nowhere in the code // 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 // 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 // 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... // 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){ for(BlockPos pos : nodes){
world.setBlockState(pos, world.getBlockState(pos).with(Properties.POWERED, powered)); world.setBlockState(pos, world.getBlockState(pos).with(Properties.POWERED, powered));
} }
this.powered = powered;
} }
// assumes that there is no node here already // 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)) if(!(world.getBlockState(pos).getBlock() instanceof Connector))
throw new IllegalArgumentException("Only connectors may be in a network"); 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 // check adjacent positions for networks, if >1 join them together, if >0 join the network, if 0 create a network
LetiNetwork current = null; LetiNetwork current = null;
for(BlockPos np : neighbors(pos)){ 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(networks.containsKey(key)){
if(current == null){ if(current == null){
current = networks.get(key); current = networks.get(key);
current.add(pos); current.add(pos);
} }
else current.mergeWith(networks.get(key)); else if(!current.equals(networks.get(key))) current.mergeWith(networks.get(key));
} }
} }
if(current == null){ 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){ public static LetiNetwork at(World world, BlockPos pos){
return networks.get(new Entry<ServerWorld, BlockPos>(world, 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); 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); nodes.remove(pos);
networks.remove(new Entry<ServerWorld, BlockPos>(world, pos)); networks.remove(new Entry<World, 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), // 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 // 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 // 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)){ for(BlockPos np : neighbors(pos)){
Entry<ServerWorld, BlockPos> key = new Entry<>(world, np); if(nodes.contains(np)){
if(networks.containsKey(key)){ ArrayList<BlockPos> found = new ArrayList<>();
LetiNetwork n = networks.get(key); ArrayList<BlockPos> next = new ArrayList<>();
if(!found.contains(key.getValue())){ while(!next.isEmpty()){
found.add(key.getValue()); for(BlockPos nep : neighbors(next.get(0))){
++finds; if(nodes.contains(nep) && !found.contains(next.get(0)))
recurse(np); 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)); 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)); inputs.remove(new Entry<BlockPos, Direction>(pos, direction));
} }
private void mergeWith(LetiNetwork network){ private void mergeWith(LetiNetwork network){
for(BlockPos pos : nodes){ for(BlockPos pos : nodes){
Entry<ServerWorld, BlockPos> entry = new Entry<>(world, pos) Entry<World, BlockPos> entry = new Entry<>(world, pos)
network.add(pos); network.add(pos);
networks.set(entry, network); networks.set(entry, network);
} }
@ -146,7 +165,7 @@ public class LetiNetwork {
public static ArrayList<LetiNetwork> findAdjacentNetworks(){ public static ArrayList<LetiNetwork> findAdjacentNetworks(){
ArrayList<LetiNetwork> ret; ArrayList<LetiNetwork> ret;
for(BlockPos np : neighbors(pos)){ 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)){ if(networks.containsKey(key)){
LetiNetwork n = networks.get(key); LetiNetwork n = networks.get(key);
if(!ret.contains(n)) ret.add(n); if(!ret.contains(n)) ret.add(n);