/// <summary> /// Resize the map instance. /// </summary> /// <param name="n">Number or rows to be added to or removed from the north side</param> /// <param name="e">Number or columns to be added to or removed from the east side</param> /// <param name="s">Number or rows to be added to or removed from the south side</param> /// <param name="w">Number or columns to be added to or removed from the west side</param> public void Resize(int n, int e, int s, int w) { if (-n >= Height || -s >= Height || -e >= Width || -w >= Width) return; if (-(n + s) >= Height || -(e + w) >= Width) return; Tile[,] cutTiles; if (n < 0) { cutTiles = new Tile[Width, -n]; for (int x = 0; x < Width; x++) for (int y = 0; y < -n; y++) cutTiles[x, y] = tiles[x, y]; } else cutTiles = null; ChangeInternalResize ch = new ChangeInternalResize(Directions.North, n, cutTiles); apply(ch); if (e < 0) { cutTiles = new Tile[-e, Height]; for (int x = Width + e; x < Width; x++) for (int y = 0; y < Height; y++) cutTiles[x - (Width + e), y] = tiles[x, y]; } else cutTiles = null; ch = new ChangeInternalResize(Directions.East, e, cutTiles); apply(ch); if (s < 0) { cutTiles = new Tile[Width, -s]; for (int x = 0; x < Width; x++) for (int y = Height + s; y < Height; y++) cutTiles[x, y - (Height + s)] = tiles[x, y]; } else cutTiles = null; ch = new ChangeInternalResize(Directions.South, s, cutTiles); apply(ch); if (w < 0) { cutTiles = new Tile[-w, Height]; for (int x = 0; x < -w; x++) for (int y = 0; y < Height; y++) cutTiles[x, y] = tiles[x, y]; } else cutTiles = null; ch = new ChangeInternalResize(Directions.West, w, cutTiles); apply(ch); FullRedraw(); }
private void undoSouthResize(ChangeInternalResize ch) { int size = ch.Size; Tile[,] newTiles = new Tile[Width, Height - size]; if (size > 0) { for (int x = 0; x < Width; x++) { for (int y = 0; y < Height - size; y++) { newTiles[x, y] = tiles[x, y]; } } for (int x = 0; x < Width; x++) { newTiles[x, Height - size - 1].DropTile(Directions.South); } } else { for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { newTiles[x, y] = tiles[x, y]; } } Tile[,] oldTiles = ch.Tiles; for (int x = 0; x < Width; x++) { for (int y = 0; y < -size; y++) { newTiles[x, Height + y] = oldTiles[x, y]; } } joinTiles(newTiles, Width, Height - size); for (int x = 0; x < Width; x++) { newTiles[x, Height].AttachToTile(newTiles[x, Height - 1], Directions.South); } } tiles = newTiles; Height -= size; fixScrollblockers(0, 0); reattachScrollBlockers(); }
private void undoWestResize(ChangeInternalResize ch) { int size = ch.Size; Tile[,] newTiles = new Tile[Width - size, Height]; if (size > 0) { for (int x = size; x < Width; x++) { for (int y = 0; y < Height; y++) { newTiles[x - size, y] = tiles[x, y]; } } for (int y = 0; y < Height; y++) { newTiles[0, y].DropTile(Directions.West); } } else { for (int x = -size; x < Width - size; x++) { for (int y = 0; y < Height; y++) { newTiles[x, y] = tiles[x + size, y]; } } Tile[,] oldTiles = ch.Tiles; for (int x = 0; x < -size; x++) { for (int y = 0; y < Height; y++) { newTiles[x, y] = oldTiles[x, y]; } } joinTiles(newTiles, Width - size, Height); for (int y = 0; y < Height; y++) { newTiles[-size - 1, y].AttachToTile(newTiles[-size, y], Directions.West); } } tiles = newTiles; Width -= size; fixScrollblockers(-size, 0); reattachScrollBlockers(); }
private void redoEastResize(ChangeInternalResize ch) { int size = ch.Size; Tile[,] newTiles = new Tile[Width + size, Height]; if (size > 0) { for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { newTiles[x, y] = tiles[x, y]; } } for (int x = Width; x < Width + size; x++) { for (int y = 0; y < Height; y++) { newTiles[x, y] = new Tile(); } } joinTiles(newTiles, Width + size, Height); for (int y = 0; y < Height; y++) { newTiles[Width - 1, y].AttachToTile(newTiles[Width, y], Directions.East); } } else { for (int x = 0; x < Width + size; x++) { for (int y = 0; y < Height; y++) { newTiles[x, y] = tiles[x, y]; } } for (int y = 0; y < Height; y++) { newTiles[Width + size - 1, y].DropTile(Directions.East); } } tiles = newTiles; Width += size; fixScrollblockers(0, 0); }
private void redoNorthResize(ChangeInternalResize ch) { int size = ch.Size; Tile[,] newTiles = new Tile[Width, Height + size]; if (size > 0) { for (int x = 0; x < Width; x++) { for (int y = 0; y < Height; y++) { newTiles[x, y + size] = tiles[x, y]; } } for (int x = 0; x < Width; x++) { for (int y = 0; y < size; y++) { newTiles[x, y] = new Tile(); } } joinTiles(newTiles, Width, Height + size); for (int x = 0; x < Width; x++) { newTiles[x, size - 1].AttachToTile(newTiles[x, size], Directions.North); } } else { for (int x = 0; x < Width; x++) { for (int y = 0; y < Height + size; y++) { newTiles[x, y] = tiles[x, y - size]; } } for (int x = 0; x < Width; x++) { newTiles[x, 0].DropTile(Directions.North); } } tiles = newTiles; Height += size; fixScrollblockers(0, size); }
private void undoWestResize(ChangeInternalResize ch) { int size = ch.Size; Tile[,] newTiles = new Tile[Width - size, Height]; if (size > 0) { for (int x = size; x < Width; x++) for (int y = 0; y < Height; y++) newTiles[x - size, y] = tiles[x, y]; for (int y = 0; y < Height; y++) newTiles[0, y].DropTile(Directions.West); } else { for (int x = -size; x < Width - size; x++) for (int y = 0; y < Height; y++) newTiles[x, y] = tiles[x + size, y]; Tile[,] oldTiles = ch.Tiles; for (int x = 0; x < -size; x++) for (int y = 0; y < Height; y++) newTiles[x, y] = oldTiles[x, y]; joinTiles(newTiles, Width - size, Height); for (int y = 0; y < Height; y++) newTiles[-size - 1, y].AttachToTile(newTiles[-size, y], Directions.West); } tiles = newTiles; Width -= size; fixScrollblockers(-size, 0); reattachScrollBlockers(); }
private void undoSouthResize(ChangeInternalResize ch) { int size = ch.Size; Tile[,] newTiles = new Tile[Width, Height - size]; if (size > 0) { for (int x = 0; x < Width; x++) for (int y = 0; y < Height - size; y++) newTiles[x, y] = tiles[x, y]; for (int x = 0; x < Width; x++) newTiles[x, Height - size - 1].DropTile(Directions.South); } else { for (int x = 0; x < Width; x++) for (int y = 0; y < Height; y++) newTiles[x, y] = tiles[x, y]; Tile[,] oldTiles = ch.Tiles; for (int x = 0; x < Width; x++) for (int y = 0; y < -size; y++) newTiles[x, Height + y] = oldTiles[x, y]; joinTiles(newTiles, Width, Height - size); for (int x = 0; x < Width; x++) newTiles[x, Height].AttachToTile(newTiles[x, Height - 1], Directions.South); } tiles = newTiles; Height -= size; fixScrollblockers(0, 0); reattachScrollBlockers(); }
private void redoNorthResize(ChangeInternalResize ch) { int size = ch.Size; Tile[,] newTiles = new Tile[Width, Height + size]; if (size > 0) { for (int x = 0; x < Width; x++) for (int y = 0; y < Height; y++) newTiles[x, y + size] = tiles[x, y]; for (int x = 0; x < Width; x++) for (int y = 0; y < size; y++) newTiles[x, y] = new Tile(); joinTiles(newTiles, Width, Height + size); for (int x = 0; x < Width; x++) newTiles[x, size - 1].AttachToTile(newTiles[x, size], Directions.North); } else { for (int x = 0; x < Width; x++) for (int y = 0; y < Height + size; y++) newTiles[x, y] = tiles[x, y - size]; for (int x = 0; x < Width; x++) newTiles[x, 0].DropTile(Directions.North); } tiles = newTiles; Height += size; fixScrollblockers(0, size); }
private void redoEastResize(ChangeInternalResize ch) { int size = ch.Size; Tile[,] newTiles = new Tile[Width + size, Height]; if (size > 0) { for (int x = 0; x < Width; x++) for (int y = 0; y < Height; y++) newTiles[x, y] = tiles[x, y]; for (int x = Width; x < Width + size; x++) for (int y = 0; y < Height; y++) newTiles[x, y] = new Tile(); joinTiles(newTiles, Width + size, Height); for (int y = 0; y < Height; y++) newTiles[Width - 1, y].AttachToTile(newTiles[Width, y], Directions.East); } else { for (int x = 0; x < Width + size; x++) for (int y = 0; y < Height; y++) newTiles[x, y] = tiles[x, y]; for (int y = 0; y < Height; y++) newTiles[Width + size - 1, y].DropTile(Directions.East); } tiles = newTiles; Width += size; fixScrollblockers(0, 0); }
/// <summary> /// Resize the map instance. /// </summary> /// <param name="n">Number or rows to be added to or removed from the north side</param> /// <param name="e">Number or columns to be added to or removed from the east side</param> /// <param name="s">Number or rows to be added to or removed from the south side</param> /// <param name="w">Number or columns to be added to or removed from the west side</param> public void Resize(int n, int e, int s, int w) { if (-n >= Height || -s >= Height || -e >= Width || -w >= Width) { return; } if (-(n + s) >= Height || -(e + w) >= Width) { return; } Tile[,] cutTiles; if (n < 0) { cutTiles = new Tile[Width, -n]; for (int x = 0; x < Width; x++) { for (int y = 0; y < -n; y++) { cutTiles[x, y] = tiles[x, y]; } } } else { cutTiles = null; } ChangeInternalResize ch = new ChangeInternalResize(Directions.North, n, cutTiles); apply(ch); if (e < 0) { cutTiles = new Tile[-e, Height]; for (int x = Width + e; x < Width; x++) { for (int y = 0; y < Height; y++) { cutTiles[x - (Width + e), y] = tiles[x, y]; } } } else { cutTiles = null; } ch = new ChangeInternalResize(Directions.East, e, cutTiles); apply(ch); if (s < 0) { cutTiles = new Tile[Width, -s]; for (int x = 0; x < Width; x++) { for (int y = Height + s; y < Height; y++) { cutTiles[x, y - (Height + s)] = tiles[x, y]; } } } else { cutTiles = null; } ch = new ChangeInternalResize(Directions.South, s, cutTiles); apply(ch); if (w < 0) { cutTiles = new Tile[-w, Height]; for (int x = 0; x < -w; x++) { for (int y = 0; y < Height; y++) { cutTiles[x, y] = tiles[x, y]; } } } else { cutTiles = null; } ch = new ChangeInternalResize(Directions.West, w, cutTiles); apply(ch); FullRedraw(); }
private void redo(bool step) { bool quit = true; do { changesIndex++; BaseChange change = changes[changesIndex]; switch (change.Type) { case ChangeType.SetVariant: { ChangeSetVariant ch = change as ChangeSetVariant; tiles[ch.X, ch.Y].Variant = ch.To; updateTile(ch.X, ch.Y); break; } case ChangeType.ToggleTile: { ChangeToggleTile ch = change as ChangeToggleTile; tiles[ch.X, ch.Y].Variant = 0; tiles[ch.X, ch.Y].Filled = !tiles[ch.X, ch.Y].Filled; updateTile(ch.X, ch.Y); break; } case ChangeType.ToggleBlock: { ChangeToggleBlock ch = change as ChangeToggleBlock; tiles[ch.X, ch.Y].ToggleBlock(ch.Dir); updateBlock(ch.X, ch.Y, ch.Dir); break; } case ChangeType.InternalResize: { ChangeInternalResize ch = change as ChangeInternalResize; int size = ch.Size; if (size != 0) { switch (ch.Dir) { case Directions.North: redoNorthResize(ch); break; case Directions.East: redoEastResize(ch); break; case Directions.South: redoSouthResize(ch); break; case Directions.West: redoWestResize(ch); break; default: break; } } if (step) { break; } if (change.StopRedo) { quit = true; FullRedraw(); } else { quit = false; } break; } case ChangeType.Convert: { ChangeConvert ch = change as ChangeConvert; post = ch.Forward; setPostMode(post); FullRedraw(); break; } case ChangeType.ToggleWide: { ChangeToggleWide ch = change as ChangeToggleWide; int tx = ch.X; int ty = ch.Y; tiles[tx, ty].Wide = ch.To; FullRedraw(); break; } case ChangeType.SetScrollblockers: { ChangeSetScrollBlockers ch = change as ChangeSetScrollBlockers; Tile tile = tiles[ch.X, ch.Y]; int idx = ch.Index; if (idx == 0) { tile.ScrollBlocker = scrollBlockers.Count; scrollBlockers.Add(new Pair <int, int>(ch.X, ch.Y)); updateTile(ch.X, ch.Y); break; } for (int i = idx + 1; i < scrollBlockers.Count; i++) { int nx = scrollBlockers[i].First; int ny = scrollBlockers[i].Second; tiles[nx, ny].ScrollBlocker--; updateTile(nx, ny); } tile.ScrollBlocker = 0; updateTile(ch.X, ch.Y); scrollBlockers.RemoveAt(idx); break; } default: break; } } while (!quit); if (changesIndex + 1 == changes.Count) { setRedo(false); } setUndo(true); }
/// <summary> /// Handler for action undoing. /// </summary> public void Undo() { bool quit = true; do { BaseChange change = changes[changesIndex]; switch (change.Type) { case ChangeType.SetVariant: { ChangeSetVariant ch = change as ChangeSetVariant; tiles[ch.X, ch.Y].Variant = ch.From; updateTile(ch.X, ch.Y); break; } case ChangeType.ToggleTile: { ChangeToggleTile ch = change as ChangeToggleTile; tiles[ch.X, ch.Y].Variant = ch.PreviousVariant; tiles[ch.X, ch.Y].Filled = !tiles[ch.X, ch.Y].Filled; updateTile(ch.X, ch.Y); break; } case ChangeType.ToggleBlock: { ChangeToggleBlock ch = change as ChangeToggleBlock; tiles[ch.X, ch.Y].ToggleBlock(ch.Dir); updateBlock(ch.X, ch.Y, ch.Dir); break; } case ChangeType.InternalResize: { ChangeInternalResize ch = change as ChangeInternalResize; int size = ch.Size; if (size != 0) { switch (ch.Dir) { case Directions.North: undoNorthResize(ch); break; case Directions.East: undoEastResize(ch); break; case Directions.South: undoSouthResize(ch); break; case Directions.West: undoWestResize(ch); break; default: break; } } if (change.StopUndo) { FullRedraw(); quit = true; } else { quit = false; } break; } case ChangeType.ToggleWide: { ChangeToggleWide ch = change as ChangeToggleWide; int tx = ch.X; int ty = ch.Y; tiles[tx, ty].Wide = ch.From; FullRedraw(); break; } case ChangeType.Convert: { ChangeConvert ch = change as ChangeConvert; post = !ch.Forward; setPostMode(post); FullRedraw(); break; } case ChangeType.SetScrollblockers: { ChangeSetScrollBlockers ch = change as ChangeSetScrollBlockers; int idx = ch.Index; Tile tile = tiles[ch.X, ch.Y]; if (idx == 0) // was new { tile.ScrollBlocker = 0; scrollBlockers.RemoveAt(scrollBlockers.Count - 1); updateTile(ch.X, ch.Y); break; } // was deleted at idx position tile.ScrollBlocker = idx; scrollBlockers.Insert(idx, new Pair <int, int>(ch.X, ch.Y)); for (int i = idx + 1; i < scrollBlockers.Count; i++) { int nx = scrollBlockers[i].First; int ny = scrollBlockers[i].Second; tiles[nx, ny].ScrollBlocker++; updateTile(nx, ny); } updateTile(ch.X, ch.Y); break; } default: break; } changesIndex--; } while (!quit); if (changesIndex == 0) { setUndo(false); } setRedo(true); }