summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/components/map/layers/HoverTileLayerComponent.js56
-rw-r--r--src/containers/map/layers/HoverTileLayer.js22
-rw-r--r--src/util/tile-calculations.js79
3 files changed, 138 insertions, 19 deletions
diff --git a/src/components/map/layers/HoverTileLayerComponent.js b/src/components/map/layers/HoverTileLayerComponent.js
index 691b9733..a4d9446a 100644
--- a/src/components/map/layers/HoverTileLayerComponent.js
+++ b/src/components/map/layers/HoverTileLayerComponent.js
@@ -3,25 +3,45 @@ import {Layer} from "react-konva";
import HoverTile from "../elements/HoverTile";
import {TILE_SIZE_IN_PIXELS} from "../MapConstants";
-const HoverTileLayerComponent = ({mainGroupX, mainGroupY, mouseX, mouseY, currentRoomInConstruction, isValid, onClick}) => {
- if (currentRoomInConstruction === -1) {
- return <Layer/>
+class HoverTileLayerComponent extends React.Component {
+ state = {
+ positionX: -1,
+ positionY: -1,
+ validity: false,
+ };
+
+ componentDidUpdate() {
+ if (this.props.currentRoomInConstruction === -1) {
+ return;
+ }
+
+ const positionX = Math.floor((this.props.mouseX - this.props.mainGroupX) / TILE_SIZE_IN_PIXELS);
+ const positionY = Math.floor((this.props.mouseY - this.props.mainGroupY) / TILE_SIZE_IN_PIXELS);
+
+ if (positionX !== this.state.positionX || positionY !== this.state.positionY) {
+ this.setState({positionX, positionY, validity: this.props.isValid(positionX, positionY)});
+ }
}
- const positionX = Math.floor((mouseX - mainGroupX) / TILE_SIZE_IN_PIXELS);
- const positionY = Math.floor((mouseY - mainGroupY) / TILE_SIZE_IN_PIXELS);
- const pixelX = positionX * TILE_SIZE_IN_PIXELS + mainGroupX;
- const pixelY = positionY * TILE_SIZE_IN_PIXELS + mainGroupY;
- const validity = isValid(positionX, positionY);
-
- return (
- <Layer>
- <HoverTile
- pixelX={pixelX} pixelY={pixelY}
- isValid={validity} onClick={() => onClick(positionX, positionY)}
- />
- </Layer>
- );
-};
+ render() {
+ if (this.props.currentRoomInConstruction === -1) {
+ return <Layer/>;
+ }
+
+ const positionX = Math.floor((this.props.mouseX - this.props.mainGroupX) / TILE_SIZE_IN_PIXELS);
+ const positionY = Math.floor((this.props.mouseY - this.props.mainGroupY) / TILE_SIZE_IN_PIXELS);
+ const pixelX = positionX * TILE_SIZE_IN_PIXELS + this.props.mainGroupX;
+ const pixelY = positionY * TILE_SIZE_IN_PIXELS + this.props.mainGroupY;
+
+ return (
+ <Layer>
+ <HoverTile
+ pixelX={pixelX} pixelY={pixelY}
+ isValid={this.state.validity} onClick={() => this.props.onClick(positionX, positionY)}
+ />
+ </Layer>
+ );
+ }
+}
export default HoverTileLayerComponent;
diff --git a/src/containers/map/layers/HoverTileLayer.js b/src/containers/map/layers/HoverTileLayer.js
index b8868233..d8a1d983 100644
--- a/src/containers/map/layers/HoverTileLayer.js
+++ b/src/containers/map/layers/HoverTileLayer.js
@@ -1,11 +1,31 @@
import {connect} from "react-redux";
import {toggleTileAtLocation} from "../../../actions/topology";
import HoverTileLayerComponent from "../../../components/map/layers/HoverTileLayerComponent";
+import {
+ deriveValidNextTilePositions,
+ findPositionInPositions,
+ findPositionInRooms
+} from "../../../util/tile-calculations";
const mapStateToProps = state => {
return {
currentRoomInConstruction: state.currentRoomInConstruction,
- isValid: (x, y) => true, // TODO implement proper validation
+ isValid: (x, y) => {
+ const newRoom = Object.assign({}, state.objects.room[state.currentRoomInConstruction]);
+ const oldRooms = Object.keys(state.objects.room)
+ .map(id => Object.assign({}, state.objects.room[id]))
+ .filter(room => room.id !== state.currentRoomInConstruction);
+
+ [...oldRooms, newRoom].forEach(room => {
+ room.tiles = room.tileIds.map(tileId => state.objects.tile[tileId]);
+ });
+ if (newRoom.tileIds.length === 0) {
+ return findPositionInRooms(oldRooms, x, y) === -1;
+ }
+
+ const validNextPositions = deriveValidNextTilePositions(oldRooms, newRoom.tiles);
+ return findPositionInPositions(validNextPositions, x, y) !== -1;
+ },
};
};
diff --git a/src/util/tile-calculations.js b/src/util/tile-calculations.js
index 3050a404..4d81dd31 100644
--- a/src/util/tile-calculations.js
+++ b/src/util/tile-calculations.js
@@ -125,3 +125,82 @@ export function deriveWallLocations(tiles) {
return result;
}
+
+export function deriveValidNextTilePositions(rooms, selectedTiles) {
+ const result = [], newPosition = {x: 0, y: 0};
+ let isSurroundingTile;
+
+ selectedTiles.forEach((tile) => {
+ const x = tile.positionX;
+ const y = tile.positionY;
+ result.push({x, y});
+
+ for (let dX = -1; dX <= 1; dX++) {
+ for (let dY = -1; dY <= 1; dY++) {
+ if (Math.abs(dX) === Math.abs(dY)) {
+ continue;
+ }
+
+ newPosition.x = x + dX;
+ newPosition.y = y + dY;
+
+ isSurroundingTile = true;
+ for (let index in selectedTiles) {
+ if (selectedTiles[index].positionX === newPosition.x
+ && selectedTiles[index].positionY === newPosition.y) {
+ isSurroundingTile = false;
+ break;
+ }
+ }
+
+ if (isSurroundingTile && findPositionInRooms(rooms, newPosition.x, newPosition.y) === -1) {
+ result.push({x: newPosition.x, y: newPosition.y});
+ }
+ }
+ }
+ });
+
+ return result;
+}
+
+export function findPositionInPositions(positions, positionX, positionY) {
+ let index = -1;
+
+ for (let i = 0; i < positions.length; i++) {
+ const position = positions[i];
+ if (positionX === position.x && positionY === position.y) {
+ index = i;
+ break;
+ }
+ }
+
+ return index;
+}
+
+export function findPositionInRooms(rooms, positionX, positionY) {
+ let index = -1;
+
+ for (let i = 0; i < rooms.length; i++) {
+ const room = rooms[i];
+ if (findPositionInTiles(room.tiles, positionX, positionY) !== -1) {
+ index = i;
+ break;
+ }
+ }
+
+ return index;
+}
+
+function findPositionInTiles(tiles, positionX, positionY) {
+ let index = -1;
+
+ for (let i = 0; i < tiles.length; i++) {
+ const tile = tiles[i];
+ if (positionX === tile.positionX && positionY === tile.positionY) {
+ index = i;
+ break;
+ }
+ }
+
+ return index;
+}