Skip to content

Commit

Permalink
Merge pull request #46 from mayant15/priority
Browse files Browse the repository at this point in the history
Add priority system for rail blocks
  • Loading branch information
iaronaraujo authored Jun 9, 2019
2 parents 961574d + cdf42d5 commit a5a0b10
Showing 1 changed file with 98 additions and 25 deletions.
123 changes: 98 additions & 25 deletions src/main/java/org/terasology/minecarts/blocks/RailBlockFamily.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,24 @@
import org.terasology.math.geom.Vector3i;
import org.terasology.naming.Name;
import org.terasology.segmentedpaths.blocks.PathFamily;
import org.terasology.world.BlockEntityRegistry;
import org.terasology.world.WorldProvider;
import org.terasology.world.block.Block;
import org.terasology.world.block.BlockBuilderHelper;
import org.terasology.world.block.BlockManager;
import org.terasology.world.block.BlockUri;
import org.terasology.world.block.family.BlockSections;
import org.terasology.world.block.family.MultiConnectFamily;
import org.terasology.world.block.family.RegisterBlockFamily;
import org.terasology.world.block.loader.BlockFamilyDefinition;
import org.terasology.world.block.shapes.BlockShape;

import javax.print.attribute.standard.Sides;
import java.util.*;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@RegisterBlockFamily("rails")
@BlockSections({"no_connections", "one_connection", "one_connection_slope", "line_connection", "2d_corner", "2d_t", "cross"})
public class RailBlockFamily extends MultiConnectFamily implements PathFamily {
public class RailBlockFamily extends MultiConnectFamily implements PathFamily {
public static final String NO_CONNECTIONS = "no_connections";
public static final String ONE_CONNECTION = "one_connection";
public static final String ONE_CONNECTIONS_SLOPE = "one_connection_slope";
Expand All @@ -51,36 +51,46 @@ public class RailBlockFamily extends MultiConnectFamily implements PathFamily {
public static final String THREE_CONNECTIONS_T = "2d_t";
public static final String FOUR_CONNECTIONS_CROSS = "cross";

private TByteObjectMap<Rotation> rotationMap = new TByteObjectHashMap<>();
private TByteObjectMap<Rotation> rotationMap = new TByteObjectHashMap<>();
private Map<String, Byte> baseSideBitMap = new HashMap<>();

public RailBlockFamily(BlockFamilyDefinition definition, BlockShape shape, BlockBuilderHelper blockBuilder) {
super(definition, shape, blockBuilder);
initSideBitMap();
}

public RailBlockFamily(BlockFamilyDefinition definition, BlockBuilderHelper blockBuilder) {
super(definition, blockBuilder);

BlockUri blockUri = new BlockUri(definition.getUrn());

this.registerBlock(blockUri,definition,blockBuilder,NO_CONNECTIONS, (byte) 0, Rotation.horizontalRotations());
this.registerBlock(blockUri,definition,blockBuilder,ONE_CONNECTION, SideBitFlag.getSides(Side.RIGHT), Rotation.horizontalRotations());
this.registerBlock(blockUri,definition,blockBuilder,ONE_CONNECTIONS_SLOPE, SideBitFlag.getSides(Side.FRONT, Side.TOP), Rotation.horizontalRotations());
this.registerBlock(blockUri,definition,blockBuilder,TWO_CONNECTIONS_LINE, SideBitFlag.getSides(Side.LEFT, Side.RIGHT), Rotation.horizontalRotations());
this.registerBlock(blockUri,definition,blockBuilder,TWO_CONNECTIONS_CORNER, SideBitFlag.getSides(Side.LEFT, Side.FRONT), Rotation.horizontalRotations());
this.registerBlock(blockUri,definition,blockBuilder,THREE_CONNECTIONS_T, SideBitFlag.getSides(Side.LEFT, Side.RIGHT, Side.FRONT), Rotation.horizontalRotations());
this.registerBlock(blockUri,definition,blockBuilder,FOUR_CONNECTIONS_CROSS, SideBitFlag.getSides(Side.RIGHT, Side.LEFT, Side.BACK, Side.FRONT), Rotation.horizontalRotations());
}
initSideBitMap();

for (String k : baseSideBitMap.keySet()) {
this.registerBlock(blockUri, definition, blockBuilder, k, baseSideBitMap.get(k), Rotation.horizontalRotations());
}
}

private void initSideBitMap() {
baseSideBitMap.put(NO_CONNECTIONS, (byte) 0);
baseSideBitMap.put(ONE_CONNECTION, (byte) 0b010000);
baseSideBitMap.put(ONE_CONNECTIONS_SLOPE, (byte) 0b000101);
baseSideBitMap.put(TWO_CONNECTIONS_LINE, (byte) 0b010010);
baseSideBitMap.put(TWO_CONNECTIONS_CORNER, (byte) 0b000110);
baseSideBitMap.put(THREE_CONNECTIONS_T, (byte) 0b010110);
baseSideBitMap.put(FOUR_CONNECTIONS_CROSS, (byte) 0b110110);
}

@Override
public Set<Block> registerBlock(BlockUri root, BlockFamilyDefinition definition, BlockBuilderHelper blockBuilder, String name, byte sides, Iterable<Rotation> rotations) {
Set<Block> result = Sets.newLinkedHashSet();
for (Rotation rotation: rotations) {
for (Rotation rotation : rotations) {
byte sideBits = 0;
for (Side side : SideBitFlag.getSides(sides)) {
sideBits += SideBitFlag.getSide(rotation.rotate(side));
}
Block block = blockBuilder.constructTransformedBlock(definition, name, rotation, new BlockUri(root, new Name(String.valueOf(sideBits))), this);
rotationMap.put(sideBits,rotation);
rotationMap.put(sideBits, rotation);
blocks.put(sideBits, block);
result.add(block);
}
Expand All @@ -91,7 +101,7 @@ public Set<Block> registerBlock(BlockUri root, BlockFamilyDefinition definition,
public Block getBlockForPlacement(Vector3i location, Side attachmentSide, Side direction) {
byte connections = 0;
for (Side connectSide : SideBitFlag.getSides(getConnectionSides())) {
if (this.connectionCondition(location, connectSide) && !isFullyConnected(location,connectSide)) {
if (this.connectionCondition(location, connectSide) && !isFullyConnected(location, connectSide)) {
connections |= SideBitFlag.getSide(connectSide);
}
}
Expand All @@ -102,18 +112,79 @@ public Block getBlockForPlacement(Vector3i location, Side attachmentSide, Side d
}
}

Side topSide = Side.BOTTOM;
for (Side connectSide : SideBitFlag.getSides(getConnectionSides())) {
if (this.connectionCondition(new Vector3i(location).add(Vector3i.up()), connectSide)) {
connections |= SideBitFlag.getSide(Side.TOP);
if(SideBitFlag.getSides(connections).size() == 1){
topSide = connectSide;
if (SideBitFlag.getSides(connections).size() == 1) {
connections |= SideBitFlag.getSide(connectSide.reverse());
}
break;
}
}
return blocks.get(connections);

Block result = blocks.get(connections);
if (result != null) {
return result;
} else {
return getClosestMatch(connections, topSide);
}
}

private Block getClosestMatch(byte connections, Side topSide) {
EnumSet<Side> sides = SideBitFlag.getSides(connections);

// Indices represent priorities, 0 being the highest and 6 being the lowest
String[] keys = new String[baseSideBitMap.size()];
keys[0] = FOUR_CONNECTIONS_CROSS;
keys[1] = THREE_CONNECTIONS_T;
keys[2] = ONE_CONNECTIONS_SLOPE;
keys[3] = TWO_CONNECTIONS_CORNER;
keys[4] = TWO_CONNECTIONS_LINE;
keys[5] = ONE_CONNECTION;
keys[6] = NO_CONNECTIONS;

for (String k : keys) {
Block result = checkConnection(sides, k, topSide);
if (result != null) {
return result;
}
}

return blocks.get((byte) 0); // default block, simple no connection block
}

private Block checkConnection(EnumSet<Side> sides, String connection, Side topSide) {

// if building slopes, make sure it is in the direction of the top block
if (connection.equals(ONE_CONNECTIONS_SLOPE)) {
if (sides.contains(Side.TOP) && sides.contains(topSide.reverse())) {
byte b = SideBitFlag.getSides(topSide.reverse(), Side.TOP);
return blocks.get(b);
} else {
return null;
}
}

Set<Byte> arrangements = new HashSet<>();

for (Rotation rotation : Rotation.horizontalRotations()) {
byte sideBits = 0;
for (Side side : SideBitFlag.getSides(baseSideBitMap.get(connection))) {
sideBits += SideBitFlag.getSide(rotation.rotate(side));
}
arrangements.add(sideBits);
}

for (byte b : arrangements) {
if (sides.containsAll(SideBitFlag.getSides(b))) {
return blocks.get(b);
}
}

return null;
}


@Override
Expand All @@ -122,7 +193,6 @@ public Block getBlockForNeighborUpdate(Vector3i location, Block oldBlock) {
}



/**
* a fully connected tile has more then 1 connected edge and is not attached to the reference tile
*
Expand All @@ -137,14 +207,17 @@ private boolean isFullyConnected(Vector3i location, Side connectSide) {
EnumSet<Side> sides = SideBitFlag.getSides(Byte.parseByte(worldProvider.getBlock(neighborLocation).getURI().getIdentifier().toString()));

for (Side side : sides) {
if (side == Side.TOP || side == Side.BOTTOM)
if (side == Side.TOP || side == Side.BOTTOM) {
continue;
}
if (new Vector3i(neighborLocation).add(side.getVector3i()).equals(location)) {
return false;
}
}
if (sides.size() > 1)
if (sides.size() > 1) {
return true;
}

}
return false;
}
Expand All @@ -160,12 +233,12 @@ protected boolean connectionCondition(Vector3i blockLocation, Side connectSide)

@Override
public byte getConnectionSides() {
return SideBitFlag.getSides(Side.LEFT,Side.FRONT,Side.BACK,Side.RIGHT);
return SideBitFlag.getSides(Side.LEFT, Side.FRONT, Side.BACK, Side.RIGHT);
}

@Override
public Block getArchetypeBlock() {
return blocks.get(SideBitFlag.getSides(Side.RIGHT,Side.LEFT));
return blocks.get(SideBitFlag.getSides(Side.RIGHT, Side.LEFT));
}

public Block getBlockByConnection(byte connectionSides) {
Expand Down

0 comments on commit a5a0b10

Please sign in to comment.