From bef7cd7b4f705b5a77c59a716ad862660149a6a9 Mon Sep 17 00:00:00 2001 From: Michael Pollind Date: Sat, 2 Jun 2018 22:39:27 -0700 Subject: [PATCH] updated block family --- assets/blocks/railTurn.block | 2 +- assets/blocks/rails.block | 2 +- assets/blocks/railsBlockPoweredPlain.block | 2 +- assets/blocks/railsTBlockInverted.block | 2 +- module.txt | 2 +- .../minecarts/action/WrenchAction.java | 10 +- ...UpdateFamily.java => RailBlockFamily.java} | 237 ++++++++++-------- .../blocks/RailsBlockFamilyUpdateSystem.java | 180 ------------- .../minecarts/blocks/RailsFamilyFactory.java | 202 --------------- .../org/terasology/minecarts/RailsTest.java | 3 +- 10 files changed, 141 insertions(+), 501 deletions(-) rename src/main/java/org/terasology/minecarts/blocks/{RailsUpdateFamily.java => RailBlockFamily.java} (50%) delete mode 100644 src/main/java/org/terasology/minecarts/blocks/RailsBlockFamilyUpdateSystem.java delete mode 100644 src/main/java/org/terasology/minecarts/blocks/RailsFamilyFactory.java diff --git a/assets/blocks/railTurn.block b/assets/blocks/railTurn.block index 0e104e8..5bb8f65 100644 --- a/assets/blocks/railTurn.block +++ b/assets/blocks/railTurn.block @@ -17,7 +17,7 @@ { "shadowCasting": "false", "translucent" : true, - "rotation" : "horizontal", + "family" : "horizontal", "penetrable" : false, "tile" : "Rails:TrainTrackTeeInversed", diff --git a/assets/blocks/rails.block b/assets/blocks/rails.block index 8a73ac6..b348638 100644 --- a/assets/blocks/rails.block +++ b/assets/blocks/rails.block @@ -17,7 +17,7 @@ { "shadowCasting": "false", "translucent" : true, - "rotation": "Rails:rails", + "family": "rails", "penetrable" : false, "no_connections": { diff --git a/assets/blocks/railsBlockPoweredPlain.block b/assets/blocks/railsBlockPoweredPlain.block index 693f4a0..43d4cb3 100644 --- a/assets/blocks/railsBlockPoweredPlain.block +++ b/assets/blocks/railsBlockPoweredPlain.block @@ -17,7 +17,7 @@ { "shadowCasting": "false", "translucent" : true, - "rotation" : "horizontal", + "family" : "horizontal", "penetrable" : false, "tile" : "Rails:TrainTrackTeeInversed", diff --git a/assets/blocks/railsTBlockInverted.block b/assets/blocks/railsTBlockInverted.block index 918e872..b1e218d 100644 --- a/assets/blocks/railsTBlockInverted.block +++ b/assets/blocks/railsTBlockInverted.block @@ -17,7 +17,7 @@ { "shadowCasting": "false", "translucent" : true, - "rotation": "Rails:rails", + "family": "rails", "penetrable" : false, "2d_t": { diff --git a/module.txt b/module.txt index b2d6140..4710df7 100644 --- a/module.txt +++ b/module.txt @@ -1,6 +1,6 @@ { "id": "Rails", - "version" : "0.3.10-SNAPSHOT", + "version" : "0.3.2-SNAPSHOT", "author": "small-jeeper, SkySom, Cervator, pollend, msteiger", "displayName": "Rails", "description": "A module that adds rails and carts.", diff --git a/src/main/java/org/terasology/minecarts/action/WrenchAction.java b/src/main/java/org/terasology/minecarts/action/WrenchAction.java index 0a5250c..a41a08a 100644 --- a/src/main/java/org/terasology/minecarts/action/WrenchAction.java +++ b/src/main/java/org/terasology/minecarts/action/WrenchAction.java @@ -17,19 +17,16 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.terasology.entitySystem.entity.EntityManager; import org.terasology.entitySystem.entity.EntityRef; import org.terasology.entitySystem.event.ReceiveEvent; import org.terasology.entitySystem.systems.BaseComponentSystem; import org.terasology.entitySystem.systems.RegisterMode; import org.terasology.entitySystem.systems.RegisterSystem; import org.terasology.logic.common.ActivateEvent; -import org.terasology.logic.location.LocationComponent; import org.terasology.math.SideBitFlag; import org.terasology.math.geom.Vector3i; -import org.terasology.minecarts.Constants; +import org.terasology.minecarts.blocks.RailBlockFamily; import org.terasology.minecarts.blocks.RailComponent; -import org.terasology.minecarts.blocks.RailsUpdateFamily; import org.terasology.minecarts.components.CartJointComponent; import org.terasology.minecarts.components.RailVehicleComponent; import org.terasology.minecarts.components.WrenchComponent; @@ -82,14 +79,13 @@ public void onRailFlipAction(ActivateEvent event, EntityRef item) { Vector3i position = targetEntity.getComponent(BlockComponent.class).getPosition(); - RailsUpdateFamily railFamily = (RailsUpdateFamily) blockManager.getBlockFamily("Rails:rails"); - RailsUpdateFamily invertFamily = (RailsUpdateFamily) blockManager.getBlockFamily("railsTBlockInverted"); + RailBlockFamily railFamily = (RailBlockFamily) blockManager.getBlockFamily("Rails:rails"); + RailBlockFamily invertFamily = (RailBlockFamily) blockManager.getBlockFamily("railsTBlockInverted"); Block block = worldProvider.getBlock(targetEntity.getComponent(BlockComponent.class).getPosition()); byte connections = Byte.parseByte(block.getURI().getIdentifier().toString()); - if (SideBitFlag.getSides(connections).size() == 3) { if (block.getBlockFamily() == railFamily) { blockEntityRegistry.setBlockForceUpdateEntity(position, invertFamily.getBlockByConnection(connections)); diff --git a/src/main/java/org/terasology/minecarts/blocks/RailsUpdateFamily.java b/src/main/java/org/terasology/minecarts/blocks/RailBlockFamily.java similarity index 50% rename from src/main/java/org/terasology/minecarts/blocks/RailsUpdateFamily.java rename to src/main/java/org/terasology/minecarts/blocks/RailBlockFamily.java index 8c378c8..58cfd74 100644 --- a/src/main/java/org/terasology/minecarts/blocks/RailsUpdateFamily.java +++ b/src/main/java/org/terasology/minecarts/blocks/RailBlockFamily.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 MovingBlocks + * Copyright 2018 MovingBlocks * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,130 +15,89 @@ */ package org.terasology.minecarts.blocks; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; import gnu.trove.map.TByteObjectMap; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import gnu.trove.map.hash.TByteObjectHashMap; +import org.terasology.entitySystem.entity.EntityRef; import org.terasology.math.Rotation; import org.terasology.math.Side; import org.terasology.math.SideBitFlag; 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.AbstractBlockFamily; -import org.terasology.world.block.family.ConnectionCondition; - +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.family.UpdatesWithNeighboursFamily; +import org.terasology.world.block.loader.BlockFamilyDefinition; +import org.terasology.world.block.shapes.BlockShape; + +import javax.print.attribute.standard.Sides; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; - -public class RailsUpdateFamily extends AbstractBlockFamily implements PathFamily { - private static final Logger logger = LoggerFactory.getLogger(RailsUpdateFamily.class); - - private ConnectionCondition connectionCondition; - private Block archetypeBlock; - - private TByteObjectMap blocks; - private TByteObjectMap rotation; - private byte connectionSides; - - public RailsUpdateFamily(ConnectionCondition connectionCondition, BlockUri blockUri, - List categories, Block archetypeBlock, TByteObjectMap blocks, byte connectionSides, TByteObjectMap rotation) { - - super(blockUri, categories); - this.connectionCondition = connectionCondition; - this.archetypeBlock = archetypeBlock; - this.blocks = blocks; - this.connectionSides = connectionSides; - this.rotation = rotation; - - for (Block block : blocks.valueCollection()) { - block.setBlockFamily(this); - } +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 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"; + public static final String TWO_CONNECTIONS_LINE = "line_connection"; + public static final String TWO_CONNECTIONS_CORNER = "2d_corner"; + public static final String THREE_CONNECTIONS_T = "2d_t"; + public static final String FOUR_CONNECTIONS_CROSS = "cross"; + + private TByteObjectMap rotationMap = new TByteObjectHashMap<>(); + + public RailBlockFamily(BlockFamilyDefinition definition, BlockShape shape, BlockBuilderHelper blockBuilder) { + super(definition, shape, blockBuilder); } - @Override - public Block getArchetypeBlock() { - return archetypeBlock; - } - - @Override - public Block getBlockForPlacement(WorldProvider worldProvider, BlockEntityRegistry blockEntityRegistry, Vector3i location, Side attachmentSide, Side direction) { - return blocks.get(getByteConnections(worldProvider, blockEntityRegistry, location)); - } + public RailBlockFamily(BlockFamilyDefinition definition, BlockBuilderHelper blockBuilder) { + super(definition, blockBuilder); - public Block getBlockForNeighborRailUpdate(WorldProvider worldProvider, BlockEntityRegistry blockEntityRegistry, Vector3i location, Block oldBlock) { - return blocks.get(getByteConnections(worldProvider, blockEntityRegistry, location)); - } + BlockUri blockUri = new BlockUri(definition.getUrn()); - - public Rotation getRotationFor(BlockUri blockUri) { - if (getURI().equals(blockUri.getFamilyUri())) { - try { - byte connections = Byte.parseByte(blockUri.getIdentifier().toString()); - return rotation.get(connections); - } catch (IllegalArgumentException e) { - return null; - } - } - return null; - } + 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.BACK, 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()); + } @Override - public Block getBlockFor(BlockUri blockUri) { - if (getURI().equals(blockUri.getFamilyUri())) { - try { - byte connections = Byte.parseByte(blockUri.getIdentifier().toString()); - return blocks.get(connections); - } catch (IllegalArgumentException e) { - return null; + public Set registerBlock(BlockUri root, BlockFamilyDefinition definition, BlockBuilderHelper blockBuilder, String name, byte sides, Iterable rotations) { + Set result = Sets.newLinkedHashSet(); + 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); + blocks.put(sideBits, block); + result.add(block); } - return null; - } - - public Block getBlockByConnection(byte connectionSides) { - return blocks.get(connectionSides); + return result; } @Override - public Iterable getBlocks() { - return blocks.valueCollection(); - } - - - /** - * a fully connected tile has more then 1 connected edge and is not attached to the reference tile - * - * @param location - * @param connectSide - * @param worldProvider - * @param blockEntityRegistry - * @return - */ - private boolean isFullyConnected(Vector3i location, Side connectSide, WorldProvider worldProvider, BlockEntityRegistry blockEntityRegistry) { - if (connectionCondition.isConnectingTo(location, connectSide, worldProvider, blockEntityRegistry)) { - Vector3i neighborLocation = new Vector3i(location); - neighborLocation.add(connectSide.getVector3i()); - EnumSet sides = SideBitFlag.getSides(Byte.parseByte(worldProvider.getBlock(neighborLocation).getURI().getIdentifier().toString())); - - for (Side side : sides) { - if (side == Side.TOP || side == Side.BOTTOM) - continue; - if (new Vector3i(neighborLocation).add(side.getVector3i()).equals(location)) { - return false; - } - } - if (sides.size() > 1) - return true; - } - return false; + public Block getBlockForPlacement(Vector3i location, Side attachmentSide, Side direction) { + return blocks.get(getByteConnections(location)); } - private byte getByteConnections(WorldProvider worldProvider, BlockEntityRegistry blockEntityRegistry, Vector3i location) { + private byte getByteConnections(Vector3i location) { byte connections = 0; byte fullConnectedEdges = 0; int countConnetions = 0; @@ -152,8 +111,8 @@ private byte getByteConnections(WorldProvider worldProvider, BlockEntityRegistry hasTopBlock = true; } - for (Side connectSide : SideBitFlag.getSides(connectionSides)) { - if (connectionCondition.isConnectingTo(location, connectSide, worldProvider, blockEntityRegistry)) { + for (Side connectSide : Side.values()) { + if (connectionCondition(location, connectSide)) { if (isFullyConnected(location, connectSide, worldProvider, blockEntityRegistry)) fullConnectedEdges += SideBitFlag.getSide(connectSide); else @@ -173,19 +132,19 @@ private byte getByteConnections(WorldProvider worldProvider, BlockEntityRegistry countConnetions = SideBitFlag.getSides(connections).size(); upLocation.y -= 2; - for (Side connectSide : SideBitFlag.getSides(connectionSides)) { - if (connectionCondition.isConnectingTo(upLocation, connectSide, worldProvider, blockEntityRegistry)) { + for (Side connectSide : Side.values()) { + if (connectionCondition(upLocation, connectSide)) { connections += SideBitFlag.getSide(connectSide); } } upLocation.y += 2; switch (countConnetions) { case 0: - for (Side connectSide : SideBitFlag.getSides(connectionSides)) { + for (Side connectSide : Side.values()) { if (skipSides.contains(connectSide)) { continue; } - if (connectionCondition.isConnectingTo(upLocation, connectSide, worldProvider, blockEntityRegistry)) { + if (connectionCondition(upLocation, connectSide)) { connections = 0; connections += SideBitFlag.getSide(connectSide); connections += SideBitFlag.getSide(Side.TOP); @@ -200,7 +159,8 @@ private byte getByteConnections(WorldProvider worldProvider, BlockEntityRegistry if (skipSides.contains(connectSide)) { break; } - if (connectionCondition.isConnectingTo(upLocation, connectSide, worldProvider, blockEntityRegistry)) { + + if (connectionCondition(upLocation,connectSide)) { connections = 0; connections += SideBitFlag.getSide(connectSide); connections += SideBitFlag.getSide(Side.TOP); @@ -210,4 +170,71 @@ private byte getByteConnections(WorldProvider worldProvider, BlockEntityRegistry } return connections; } + + + /** + * a fully connected tile has more then 1 connected edge and is not attached to the reference tile + * + * @param location + * @param connectSide + * @param worldProvider + * @param blockEntityRegistry + * @return + */ + private boolean isFullyConnected(Vector3i location, Side connectSide, WorldProvider worldProvider, BlockEntityRegistry blockEntityRegistry) { + if (connectionCondition(location, connectSide)) { + Vector3i neighborLocation = new Vector3i(location); + neighborLocation.add(connectSide.getVector3i()); + EnumSet sides = SideBitFlag.getSides(Byte.parseByte(worldProvider.getBlock(neighborLocation).getURI().getIdentifier().toString())); + + for (Side side : sides) { + if (side == Side.TOP || side == Side.BOTTOM) + continue; + if (new Vector3i(neighborLocation).add(side.getVector3i()).equals(location)) { + return false; + } + } + if (sides.size() > 1) + return true; + } + return false; + } + + + @Override + protected boolean connectionCondition(Vector3i blockLocation, Side connectSide) { + Vector3i neighborLocation = new Vector3i(blockLocation); + neighborLocation.add(connectSide.getVector3i()); + EntityRef neighborEntity = blockEntityRegistry.getEntityAt(neighborLocation); + return neighborEntity != null && neighborEntity.hasComponent(RailComponent.class); + } + + @Override + public byte getConnectionSides() { + return SideBitFlag.getSides(Side.LEFT,Side.FRONT,Side.BACK,Side.RIGHT); + } + + @Override + public Block getArchetypeBlock() { + return blocks.get(SideBitFlag.getSides(Side.RIGHT,Side.LEFT)); + } + + public Block getBlockByConnection(byte connectionSides) { + return blocks.get(connectionSides); + } + + + @Override + public Rotation getRotationFor(BlockUri blockUri) { + if (getURI().equals(blockUri.getFamilyUri())) { + try { + byte connections = Byte.parseByte(blockUri.getIdentifier().toString()); + return rotationMap.get(connections); + } catch (IllegalArgumentException e) { + return null; + } + } + return null; + } + } diff --git a/src/main/java/org/terasology/minecarts/blocks/RailsBlockFamilyUpdateSystem.java b/src/main/java/org/terasology/minecarts/blocks/RailsBlockFamilyUpdateSystem.java deleted file mode 100644 index 7275047..0000000 --- a/src/main/java/org/terasology/minecarts/blocks/RailsBlockFamilyUpdateSystem.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright 2015 MovingBlocks - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.terasology.minecarts.blocks; - -import com.google.common.collect.Sets; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.terasology.entitySystem.entity.EntityRef; -import org.terasology.entitySystem.event.EventPriority; -import org.terasology.entitySystem.event.ReceiveEvent; -import org.terasology.entitySystem.systems.BaseComponentSystem; -import org.terasology.entitySystem.systems.RegisterMode; -import org.terasology.entitySystem.systems.RegisterSystem; -import org.terasology.entitySystem.systems.UpdateSubscriberSystem; -import org.terasology.logic.common.ActivateEvent; -import org.terasology.logic.health.DoDamageEvent; -import org.terasology.logic.health.DoDestroyEvent; -import org.terasology.logic.health.EngineDamageTypes; -import org.terasology.logic.inventory.ItemComponent; -import org.terasology.math.Side; -import org.terasology.math.SideBitFlag; -import org.terasology.math.geom.Vector3i; -import org.terasology.registry.In; -import org.terasology.world.BlockEntityRegistry; -import org.terasology.world.OnChangedBlock; -import org.terasology.world.WorldProvider; -import org.terasology.world.block.Block; -import org.terasology.world.block.BlockComponent; -import org.terasology.world.block.BlockManager; -import org.terasology.world.block.entity.neighbourUpdate.LargeBlockUpdateFinished; -import org.terasology.world.block.entity.neighbourUpdate.LargeBlockUpdateStarting; -import org.terasology.world.block.items.BlockItemComponent; -import org.terasology.world.block.items.OnBlockItemPlaced; - -import java.util.Set; - -@RegisterSystem(RegisterMode.AUTHORITY) -public class RailsBlockFamilyUpdateSystem extends BaseComponentSystem implements UpdateSubscriberSystem { - private static final Logger logger = LoggerFactory.getLogger(RailsBlockFamilyUpdateSystem.class); - - @In - private WorldProvider worldProvider; - @In - private BlockEntityRegistry blockEntityRegistry; - @In - private BlockManager blockManager; - - private int largeBlockUpdateCount; - private Set blocksUpdatedInLargeBlockUpdate = Sets.newHashSet(); - private int[] checkOnHeight = {-1, 0, 1}; - - @ReceiveEvent - public void largeBlockUpdateStarting(LargeBlockUpdateStarting event, EntityRef entity) { - largeBlockUpdateCount++; - } - - @ReceiveEvent - public void largeBlockUpdateFinished(LargeBlockUpdateFinished event, EntityRef entity) { - largeBlockUpdateCount--; - if (largeBlockUpdateCount < 0) { - largeBlockUpdateCount = 0; - throw new IllegalStateException("LargeBlockUpdateFinished invoked too many times"); - } - - if (largeBlockUpdateCount == 0) { - notifyNeighboursOfChangedBlocks(); - } - } - - @ReceiveEvent() - public void doDestroy(DoDestroyEvent event, EntityRef entity, BlockComponent blockComponent) { - Vector3i upBlock = new Vector3i(blockComponent.getPosition()); - upBlock.y += 1; - Block block = worldProvider.getBlock(upBlock); - - if (block.getBlockFamily() instanceof RailsUpdateFamily) { - blockEntityRegistry.getEntityAt(upBlock).send(new DoDamageEvent(1000, EngineDamageTypes.DIRECT.get())); - } - } - - //prevents rails from being stacked on top of each other. - @ReceiveEvent(components = {BlockItemComponent.class, ItemComponent.class}, priority = EventPriority.PRIORITY_HIGH) - public void onBlockActivated(ActivateEvent event, EntityRef item) { - BlockComponent blockComponent = event.getTarget().getComponent(BlockComponent.class); - if (blockComponent == null) - return; - - Vector3i targetBlock = blockComponent.getPosition(); - Block centerBlock = worldProvider.getBlock(targetBlock.x, targetBlock.y, targetBlock.z); - - if (centerBlock.getBlockFamily() instanceof RailsUpdateFamily) { - event.consume(); - } - } - - @ReceiveEvent(components = {BlockItemComponent.class, ItemComponent.class}) - public void onPlaceBlock(OnBlockItemPlaced event, EntityRef entity) { - BlockComponent blockComponent = event.getPlacedBlock().getComponent(BlockComponent.class); - if (blockComponent == null) - return; - - Vector3i targetBlock = blockComponent.getPosition(); - Block centerBlock = worldProvider.getBlock(targetBlock.x, targetBlock.y, targetBlock.z); - - if (centerBlock.getBlockFamily() instanceof RailsUpdateFamily) { - processUpdateForBlockLocation(targetBlock); - } - - } - - private void notifyNeighboursOfChangedBlocks() { - // Invoke the updates in another large block change for this class only - largeBlockUpdateCount++; - while (!blocksUpdatedInLargeBlockUpdate.isEmpty()) { - Set blocksToUpdate = blocksUpdatedInLargeBlockUpdate; - - // Setup new collection for blocks changed in this pass - blocksUpdatedInLargeBlockUpdate = Sets.newHashSet(); - - for (Vector3i blockLocation : blocksToUpdate) { - processUpdateForBlockLocation(blockLocation); - } - } - largeBlockUpdateCount--; - } - - @ReceiveEvent(components = {BlockComponent.class}) - public void blockUpdate(OnChangedBlock event, EntityRef blockEntity) { - if (largeBlockUpdateCount > 0) { - blocksUpdatedInLargeBlockUpdate.add(event.getBlockPosition()); - } else { - Vector3i blockLocation = event.getBlockPosition(); - processUpdateForBlockLocation(blockLocation); - } - } - - private void processUpdateForBlockLocation(Vector3i blockLocation) { - for (int height : checkOnHeight) { - for (Side side : Side.horizontalSides()) { - Vector3i neighborLocation = new Vector3i(blockLocation); - neighborLocation.add(side.getVector3i()); - neighborLocation.y += height; - Block neighborBlock = worldProvider.getBlock(neighborLocation); - EntityRef blockEntity = blockEntityRegistry.getBlockEntityAt(neighborLocation); - if (blockEntity.hasComponent(RailComponent.class)) { - RailsUpdateFamily railsFamily = (RailsUpdateFamily) neighborBlock.getBlockFamily(); - Block neighborBlockAfterUpdate = railsFamily.getBlockForNeighborRailUpdate(worldProvider, blockEntityRegistry, neighborLocation, neighborBlock); - if (neighborBlock != neighborBlockAfterUpdate && neighborBlockAfterUpdate != null) { - byte connections = Byte.parseByte(neighborBlock.getURI().getIdentifier().toString()); - //only add segment with two connections - if (SideBitFlag.getSides(connections).size() <= 1) - worldProvider.setBlock(neighborLocation, neighborBlockAfterUpdate); - } - } - } - } - } - - @Override - public void update(float delta) { - if (largeBlockUpdateCount > 0) { - logger.error("Unmatched LargeBlockUpdateStarted - LargeBlockUpdateFinished not invoked enough times"); - } - largeBlockUpdateCount = 0; - } -} - diff --git a/src/main/java/org/terasology/minecarts/blocks/RailsFamilyFactory.java b/src/main/java/org/terasology/minecarts/blocks/RailsFamilyFactory.java deleted file mode 100644 index 272201c..0000000 --- a/src/main/java/org/terasology/minecarts/blocks/RailsFamilyFactory.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright 2014 MovingBlocks - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.terasology.minecarts.blocks; - -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Sets; -import gnu.trove.iterator.TByteObjectIterator; -import gnu.trove.map.TByteObjectMap; -import gnu.trove.map.hash.TByteObjectHashMap; -import org.terasology.entitySystem.entity.EntityRef; -import org.terasology.math.Rotation; -import org.terasology.math.Side; -import org.terasology.math.SideBitFlag; -import org.terasology.math.geom.Vector3i; -import org.terasology.naming.Name; -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.BlockUri; -import org.terasology.world.block.family.BlockFamily; -import org.terasology.world.block.family.BlockFamilyFactory; -import org.terasology.world.block.family.ConnectionCondition; -import org.terasology.world.block.family.RegisterBlockFamilyFactory; -import org.terasology.world.block.loader.BlockFamilyDefinition; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; - - -@RegisterBlockFamilyFactory(value = "Rails:rails") -public class RailsFamilyFactory implements BlockFamilyFactory { - 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"; - public static final String TWO_CONNECTIONS_LINE = "line_connection"; - public static final String TWO_CONNECTIONS_CORNER = "2d_corner"; - public static final String THREE_CONNECTIONS_T = "2d_t"; - public static final String FOUR_CONNECTIONS_CROSS = "cross"; - public static final Map RAILS_MAPPING = - new HashMap() { - { - put(NO_CONNECTIONS, (byte) 0); - put(ONE_CONNECTION, SideBitFlag.getSides(Side.RIGHT)); - put(ONE_CONNECTIONS_SLOPE, SideBitFlag.getSides(Side.BACK, Side.TOP)); - put(TWO_CONNECTIONS_LINE, SideBitFlag.getSides(Side.LEFT, Side.RIGHT)); - put(TWO_CONNECTIONS_CORNER, SideBitFlag.getSides(Side.LEFT, Side.FRONT)); - put(THREE_CONNECTIONS_T, SideBitFlag.getSides(Side.LEFT, Side.RIGHT, Side.FRONT)); - put(FOUR_CONNECTIONS_CROSS, SideBitFlag.getSides(Side.RIGHT, Side.LEFT, Side.BACK, Side.FRONT)); - } - }; - - private ConnectionCondition connectionCondition; - private byte connectionSides; - - private TByteObjectMap rotations = new TByteObjectHashMap<>(); - - public RailsFamilyFactory() { - connectionCondition = new RailsConnectionCondition(); - connectionSides = SideBitFlag.getSides(Side.BACK, Side.FRONT, Side.RIGHT, Side.LEFT, Side.TOP); - } - - @Override - public Set getSectionNames() { - - return ImmutableSet.builder() - .add(NO_CONNECTIONS) - .add(ONE_CONNECTION) - .add(ONE_CONNECTIONS_SLOPE) - .add(TWO_CONNECTIONS_LINE) - .add(TWO_CONNECTIONS_CORNER) - .add(THREE_CONNECTIONS_T) - .add(FOUR_CONNECTIONS_CROSS) - .build(); - } - - @Override - public BlockFamily createBlockFamily(BlockFamilyDefinition definition, BlockBuilderHelper blockBuilder) { - TByteObjectMap[] basicBlocks = new TByteObjectMap[5]; - TByteObjectMap blocksForConnections = new TByteObjectHashMap<>(); - - addConnections(basicBlocks, 0, NO_CONNECTIONS); - addConnections(basicBlocks, 1, ONE_CONNECTION); - addConnections(basicBlocks, 2, ONE_CONNECTIONS_SLOPE); - addConnections(basicBlocks, 2, TWO_CONNECTIONS_LINE); - addConnections(basicBlocks, 2, TWO_CONNECTIONS_CORNER); - addConnections(basicBlocks, 3, THREE_CONNECTIONS_T); - addConnections(basicBlocks, 4, FOUR_CONNECTIONS_CROSS); - - BlockUri blockUri = new BlockUri(definition.getUrn()); - - // Now make sure we have all combinations based on the basic set (above) and rotations - for (byte connections = 0; connections < 60; connections++) { - // Only the allowed connections should be created - if ((connections & connectionSides) == connections) { - Block block = constructBlockForConnections(connections, blockUri, blockBuilder, definition, basicBlocks); - if (block != null) { - block.setUri(new BlockUri(blockUri, new Name(String.valueOf(connections)))); - blocksForConnections.put(connections, block); - } - } - } - - final Block archetypeBlock = blocksForConnections.get(SideBitFlag.getSides(Side.RIGHT, Side.LEFT)); - return new RailsUpdateFamily(connectionCondition, blockUri, definition.getCategories(), - archetypeBlock, blocksForConnections, (byte) (connectionSides & 0b111110), rotations); - } - - private void addConnections(TByteObjectMap[] basicBlocks, int index, String connections) { - if (basicBlocks[index] == null) { - basicBlocks[index] = new TByteObjectHashMap<>(); - } - Byte val = RAILS_MAPPING.get(connections); - if (val != null) { - basicBlocks[index].put(RAILS_MAPPING.get(connections), connections); - } - } - - /** - * find a block to fill the set of connections - * - * @param connections - * @param uri - * @param blockBuilder - * @param definition - * @param basicBlocks - * @return - */ - private Block constructBlockForConnections(final byte connections, BlockUri uri, final BlockBuilderHelper blockBuilder, - BlockFamilyDefinition definition, TByteObjectMap[] basicBlocks) { - int connectionCount = SideBitFlag.getSides(connections).size(); - if (connectionCount > basicBlocks.length - 1) - return null; - TByteObjectMap possibleBlockDefinitions = basicBlocks[connectionCount]; - final TByteObjectIterator blockDefinitionIterator = possibleBlockDefinitions.iterator(); - while (blockDefinitionIterator.hasNext()) { - blockDefinitionIterator.advance(); - final byte originalConnections = blockDefinitionIterator.key(); - final String section = blockDefinitionIterator.value(); - Rotation rot = getRotationToAchieve(originalConnections, connections); - if (rot != null) { - rotations.put(connections, rot); - return blockBuilder.constructTransformedBlock(definition, section, rot); - } - } - return null; - } - - /** - * attempt to find rotation to satisfy block - * - * @param source - * @param target - * @return - */ - private Rotation getRotationToAchieve(byte source, byte target) { - Collection originalSides = SideBitFlag.getSides(source); - - Iterable rotations = Rotation.horizontalRotations(); - for (Rotation rot : rotations) { - Set transformedSides = Sets.newHashSet(); - transformedSides.addAll(originalSides.stream().map(rot::rotate).collect(Collectors.toList())); - - byte transformedSide = SideBitFlag.getSides(transformedSides); - if (transformedSide == target) { - return rot; - } - } - return null; - } - - - public static class RailsConnectionCondition implements ConnectionCondition { - @Override - public boolean isConnectingTo(Vector3i blockLocation, Side connectSide, WorldProvider worldProvider, BlockEntityRegistry blockEntityRegistry) { - Vector3i neighborLocation = new Vector3i(blockLocation); - neighborLocation.add(connectSide.getVector3i()); - EntityRef neighborEntity = blockEntityRegistry.getEntityAt(neighborLocation); - return neighborEntity != null && connectsToNeighbor(neighborEntity, connectSide.reverse()); - } - - private boolean connectsToNeighbor(EntityRef neighborEntity, Side side) { - return neighborEntity.hasComponent(RailComponent.class); - } - } -} \ No newline at end of file diff --git a/src/test/java/org/terasology/minecarts/RailsTest.java b/src/test/java/org/terasology/minecarts/RailsTest.java index 2040d66..70ee0ea 100644 --- a/src/test/java/org/terasology/minecarts/RailsTest.java +++ b/src/test/java/org/terasology/minecarts/RailsTest.java @@ -163,8 +163,7 @@ private void setBlock(Vector3i position, Block material) { } private void setBlockForFamily(Vector3i position, BlockFamily blockFamily) { - setBlock(position, blockFamily.getBlockForPlacement(worldProvider, blockEntityRegistry, position, - Side.TOP, Side.TOP)); + setBlock(position, blockFamily.getBlockForPlacement(position, Side.TOP, Side.TOP)); } private void setRailBlock(Vector3i position) {