/// <summary> /// Changes a cell's contents, correcting for layer. /// </summary> /// <param name="gridPosition"></param> /// <param name="tileToPlace"></param> public void PaintCell(Point gridPosition, ZTile tileToPlace) { if (!Map.IsOnGrid(gridPosition)) return; // Set correct layer var layer = 1; if (!_useAltEditLayer) { layer = 0; if (tileToPlace.TileType != TileType.Floor) { layer = 3; // Layers 2 & 4 are generally used for wall filler tiles atm if (tileToPlace.Name.Contains("_ct_") || tileToPlace.Name.Contains("_c_") || tileToPlace.Name.Contains("_d_")) layer = 4; if (tileToPlace.Name.Contains("_b_") || tileToPlace.Name.Contains("b&d") ) layer = 2; } if (tileToPlace.Flags.Contains(TileFlag.Ethereal)) layer = 4; } // Check we're not swapping for the same thing if (Map.Cells[gridPosition.X, gridPosition.Y][layer] == tileToPlace) return; // Update the undo buffer with the old info var newNode = new DoubleLinkedListNode<MapDefinition>(Map.Clone(), _currentUndoNode); if (_currentUndoNode != null) _currentUndoNode.Next = newNode; _currentUndoNode = newNode; Map.UndoInfo.Clear(); Map.UndoInfo.UnionWith(Map.LegallyPlaceTile(gridPosition, layer, tileToPlace)); MapCanvas.AdaptiveTileRefresh(Map.UndoInfo.OrderBy(x => x.Y)); }
// Remember to update Clone() before adding any more instance variables! /// <summary> /// Constructor. /// </summary> public MapDefinition(ZTile defaultFloorTile, Isometry iso, string baseContentDir) { _baseContentDir = baseContentDir; Iso = iso; DefaultFloorTile = defaultFloorTile; TileHeight = 37; TileWidth = 73; UndoInfo = new HashSet<Point>(); Cells = new MapCell[0, 0]; ClearAllCells(26, 45); }
/// <summary> /// Adds a new tile, taking care of regions and other objects. /// </summary> /// <param name="gridPosition"></param> /// <param name="layer"></param> /// <param name="tileToPlace"></param> /// <returns></returns> public IOrderedEnumerable<Point> LegallyPlaceTile(Point gridPosition, int layer, ZTile tileToPlace) { // Get the footprint of the new tile HashSet<Point> footPrint = getFootprint(gridPosition, tileToPlace); // Step thru each cell in the footprint... foreach (Point p in footPrint.ToList()) { // If it has a link then find the parent, delete that and set its children to none if (Cells[p.X, p.Y].ParentCell != null) { Point parent = Cells[p.X, p.Y].ParentCell.MapCoordinate; HashSet<Point> children = getFootprint(parent, Cells[p.X, p.Y].ParentCell[layer]); Cells[p.X, p.Y].ParentCell[layer] = null; foreach (Point q in children) { Cells[q.X, q.Y].ParentCell = null; } footPrint.UnionWith(children); } // If it has an object delete it and set that objects children to none if (Cells[p.X, p.Y][layer] != null) { HashSet<Point> children = getFootprint(p, Cells[p.X, p.Y][layer]); foreach (Point q in children) { Cells[q.X, q.Y].ParentCell = null; } Cells[p.X, p.Y][layer] = null; footPrint.UnionWith(children); } } foreach (Point p in getFootprint(gridPosition, tileToPlace)) // Set each footprint cell's parent Cells[p.X, p.Y].ParentCell = Cells[gridPosition.X, gridPosition.Y]; // Set the 'actual' position Cells[gridPosition.X, gridPosition.Y][layer] = tileToPlace; Cells[gridPosition.X, gridPosition.Y].ParentCell = null; // Now add in extra cells to take into account height foreach (Point p in footPrint.ToList()) { footPrint.Add(Iso.TileWalker(p, CompassDirection.North)); footPrint.Add(Iso.TileWalker(p, CompassDirection.NorthWest)); footPrint.Add(Iso.TileWalker(p, CompassDirection.NorthEast)); } foreach (Point p in footPrint.ToList()) { footPrint.Add(Iso.TileWalker(p, CompassDirection.North)); footPrint.Add(Iso.TileWalker(p, CompassDirection.NorthWest)); } return footPrint.ToList().OrderBy(x => x.Y).ThenBy(n => n.X); }
/// <summary> /// Returns a list of cells which contain a portion of the given tile. /// </summary> /// <param name="gridPosition"></param> /// <param name="layer"></param> /// <returns></returns> internal HashSet<Point> getFootprint(Point gridPosition, ZTile tile) { var children = new HashSet<Point> {gridPosition}; if (tile == null) return children; var ne = tile.BoundingBox[0] / 6; var nw = tile.BoundingBox[2] / 6; // Adjust for tile-fraction overlaps if (tile.BoundingBox[0] % 6 > 0) { ne++; } if (tile.BoundingBox[2] % 6 > 0) { nw++; } var startPosition = gridPosition; for (var i = 0; i < ne; i++) { for (var j = 0; j < nw; j++) { if (IsOnGrid(gridPosition)) children.Add(gridPosition); gridPosition = Iso.TileWalker(gridPosition, CompassDirection.NorthWest); } gridPosition = Iso.TileWalker(startPosition, CompassDirection.NorthEast, i + 1); } return children; }