public void SetSquare(Vector3 location, AbstractSquare square) { Vector3 addr; Vector3 newoff; Vector3.Divide(location, this.pageSize, out addr, out newoff); if (!Pages.ContainsKey(addr)) { AddPage(new BasicPage(pageSize), addr); } Pages[addr].SetSquare(newoff.x, newoff.y, newoff.z, square); if (location.z == view.z) { if (Viewport.Contains(new Point(location.x, location.y))) { InvalidateTiles(new Rectangle(location.x - view.x, location.y - view.y, 1, 1)); } } if (square != null) { square.Map = this; square.Location = location; } }
/// <summary> /// Sets a location in the map to the specified square. /// </summary> /// <param name="location">Location on the map to edit.</param> /// <param name="square">Square to use</param> public void SetSquare(Vector3 location, AbstractSquare square) { Vector3 addr; Vector3 newoff; Vector3.Divide(location, this.PageSize, out addr, out newoff); if (!Pages.ContainsKey(addr)) { AddPage(new BasicPage(PageSize), addr); } Pages[addr].SetSquare(newoff.X, newoff.Y, newoff.Z, square); if (location.Z == view.Z) { if (Viewport.Contains(new Point(location.X, location.Y))) { InvalidateTiles(new Rectangle(location.X - view.X, location.Y - view.Y, 1, 1)); this.Dirty = false; } } if (square != null) { square.Map = this; square.Location = location; } }
/// <summary> /// Fills all squares between start and end with a copy of the passed in squares. /// The outter square will outline the are, while the inner square will be used to fille. If a dimension /// is only one unit thick, the inner_square will be used as a meterial instead. /// </summary> /// <param name="start">The inclusive upper-bound to fill.</param> /// <param name="end">The includive lower-bound to fill.</param> /// <param name="outter_square"></param> /// <param name="inner_square"></param> protected void Fill(Vector3 start, Vector3 end, AbstractSquare outter_square, AbstractSquare inner_square) { Vector3 min_pos = new Vector3(Math.Min(start.X, end.X), Math.Min(start.Y, end.Y), Math.Min(start.Z, end.Z)); Vector3 max_pos = new Vector3(Math.Max(start.X, end.X), Math.Max(start.Y, end.Y), Math.Max(start.Z, end.Z)); Vector3 posdiff = max_pos - min_pos; for (int x = min_pos.X; x <= max_pos.X; x++) { for (int y = min_pos.Y; y <= max_pos.Y; y++) { for (int z = min_pos.Z; z <= max_pos.Z; z++) { // Basically, considering each dimension that isn't flat, check if you are on the edge. // if so, use an edge piece. otherise, use an inner piece. if ((posdiff.X > 1 && (x == min_pos.X || x == max_pos.X)) || (posdiff.Y > 1 && (y == min_pos.Y || y == max_pos.Y)) || (posdiff.Z > 1 && (z == min_pos.Z || z == max_pos.Z))) { this[x, y, z] = outter_square; } else { this[x, y, z] = inner_square; } } } } }
/// <summary> /// Sets a square in this page to a clone of the passed in square. /// </summary> /// <param name="x">The X position to place the square.</param> /// <param name="y">The Y position to place the square.</param> /// <param name="z">The Z position to place the square.</param> /// <param name="sq">The square to clone.</param> public void SetSquare(Int32 x, Int32 y, Int32 z, AbstractSquare sq) { AbstractSquare newsq = sq.Clone(); this.map[x, y, z] = newsq; newsq.Map = this.ParentMap; newsq.Location = new Vector3(x, y, z); }
protected override void Render() { for (int screen_x = 0; screen_x < this.Size.Width; screen_x++) { int world_x = screen_x + View.X; for (int screen_y = 0; screen_y < this.Size.Height; screen_y++) { int world_y = screen_y + View.Y; this.RegionTiles[screen_x, screen_y].Reset(); AbstractSquare sq = this.GetSafeSquare(new Vector3(world_x, world_y, View.Z)); if (sq != null) { this.RegionTiles[screen_x, screen_y].AddGlyphProvider(sq); } else { //Draw a nice red error tile if we're looking out of bounds in debug mode, //but just black if we're in release mode. #if DEBUG int n = 249; // circle if (world_x % 2 == 0 && world_y % 2 == 0) { n = 197; // + } if (world_x % 2 != 0 && world_y % 2 == 0) { n = 196; // - } if (world_x % 2 == 0 && world_y % 2 != 0) { n = 179; // | } this.RegionTiles[screen_x, screen_y].AddGlyphProvider(new ErrorSquare(n)); #else this.RegionTiles[screen_x, screen_y].AddGlyphProvider(new EmptySquare()); #endif } } } Vector3 addr; Vector3 newoff; Vector3.Divide(this.View, this.PageSize, out addr, out newoff); foreach (AbstractPage p in GetPagesInRange(View, new Vector3(this.Size.Width, this.Size.Height, 1))) { foreach (AbstractEntity ent in p.Entities) { if (ent.Location.IntersectsWith(this.Viewport) && ent.Location.Z == view.Z) { this.RegionTiles[ent.Location.X - view.X, ent.Location.Y - view.Y].AddGlyphProvider(ent); } } } }
public Vector3 GetVisibleSquareLocation(AbstractSquare square) { lock (this) { foreach (AbstractPage page in this.GetPagesInRange(this.View, new Vector3(this.Viewport.Width, this.Viewport.Height, 1))) { for (int y = 0; y < PageSize.Y; ++y) { for (int x = 0; x < PageSize.X; ++x) { Vector3 location = new Vector3(x, y, this.View.Z); if (page[location].Equals(square)) { return(location); } } } } } return(Vector3.Zero); }
public void SetSquare(Int32 x, Int32 y, Int32 z, AbstractSquare sq) { this.map[x, y, z] = sq; }
/// <summary> /// Sets the viewport to a specific location on the map. /// </summary> /// <param name="nView">The coordinates of the top-left most square to view from.</param> /// <param name="forceRender">Whether or not to force a redraw of the viewport. /// This only has an effect when the viewport doesn't change.</param> public void ViewFrom(Vector3 nView, Boolean forceRender) { if (nView.Equals(view) == false || forceRender == true) { this.Clear(); for (int x = 0; x < this.Size.Width; x++) { int gx = x + nView.x; for (int y = 0; y < this.Size.Height; y++) { int gy = y + nView.y; this.RegionTiles[x, y].Reset(); AbstractSquare sq = this.GetSafeSquare(new Vector3(gx, gy, nView.z)); if (sq != null) { this.RegionTiles[x, y].AddGlyphProvider(sq); } else { //Draw a nice red error tile if we're looking out of bounds in debug mode, //but just black if we're in release mode. #if DEBUG int n = 249; // circle if (gx % 2 == 0 && gy % 2 == 0) { n = 197; // + } if (gx % 2 != 0 && gy % 2 == 0) { n = 196; // - } if (gx % 2 == 0 && gy % 2 != 0) { n = 179; // | } this.RegionTiles[x, y].AddGlyphProvider(new ErrorSquare(n)); #else this.RegionTiles[x, y].AddGlyphProvider(new EmptySquare()); #endif } } } view = nView; Vector3 addr; Vector3 newoff; Vector3.Divide(nView, this.pageSize, out addr, out newoff); foreach (AbstractPage p in GetPagesInRange(nView, new Vector3(this.Size.Width, this.Size.Height, 1))) { foreach (AbstractEntity ent in p.Entities) { if (ent.Location.IntersectsWith(this.Viewport) && ent.Location.z == view.z) { this.RegionTiles[ent.Location.x - view.x, ent.Location.y - view.y].AddGlyphProvider(ent); } } } } }
/// <summary> /// Adds a square change operation. This does not actually change the square, but rather stores /// the modification for handing in undo and redo. /// </summary> /// <param name="oldSquare">The square that was previously at the map location.</param> /// <param name="newSquare">The new square being placed at the map location.</param> /// <param name="location">The location on the map that this operation takes place.</param> public void AddOperation(AbstractSquare oldSquare, AbstractSquare newSquare, Vector3 location) { if (!changes.ContainsKey(location) && oldSquare != newSquare) { SquareChanged c = new SquareChanged(); c.oldSquare = oldSquare; c.newSquare = newSquare; changes.Add(location, c); } }
/// <summary> /// Fills all squares between start and end with a copy of the passed in square. /// The actual min/max for each component of both vectors are checked, so don't fret about mixing coordinate bounds. /// </summary> /// <param name="start">The inclusive upper-bound to fill.</param> /// <param name="end">The includive lower-bound to fill.</param> /// <param name="square">The prototype square to use.</param> protected void Fill(Vector3 start, Vector3 end, AbstractSquare square) { this.Fill(start, end, square, square); }