/// <summary> /// Removes the recently drawed quarters from the drawer component. /// </summary> public void ClearDrawer() { if (lastNearestInterfaceIndex >= 0) { TownQuarterInterface usedInterface = currentQuarter.Interfaces[lastNearestInterfaceIndex]; usedInterface.OppositeInterface.Quarter.RemoveFromDrawer(); } currentQuarter.RemoveFromDrawer(); }
/// <summary> /// Updates the town logic. It looks for the quarter the player is located in and for the nearby quarter that should be drawn as well. /// </summary> /// <param name="gameTime">Game time</param> public override void Update(GameTime gameTime) { base.Update(gameTime); Debug.Write("Current quarter", currentQuarter.Name); Vector2 playerPosition = Game.Player.PositionInQuarter.XZToVector2(); Vector2 quarterSize = new Vector2(currentQuarter.BitmapSize.Width * TownQuarter.SquareWidth, currentQuarter.BitmapSize.Height * TownQuarter.SquareWidth); if (gameTime.TotalGameTime - lastQuarterChange > quarterChangeTimeOut && ((playerPosition.X > quarterSize.X || playerPosition.Y > quarterSize.Y) || (playerPosition.X < 0 || playerPosition.Y < 0)) && lastNearestInterfaceIndex >= 0) { //Remove drawed quaeters from drawer ClearDrawer(); //Remove player from old quarter space grid currentQuarter.SpaceGrid.RemoveObject(Game.Player); //Changes current quarter TownQuarterInterface usedInterface = currentQuarter.Interfaces[lastNearestInterfaceIndex]; currentQuarter = usedInterface.OppositeInterface.Quarter; //Moves player into new current quarter float angle = ResolveQuarterAzimuthDelta(usedInterface.SidePosition, usedInterface.OppositeInterface.SidePosition); Vector2 delta = ResolveQuarterPositionDelta(usedInterface); Game.Player.MoveTo( new PositionInTown(currentQuarter, Vector3.Transform(Game.Player.PositionInQuarter, Matrix.CreateTranslation(-delta.ToVector3(0)) * Matrix.CreateRotationY(angle)).XZToVector2() // reverse transform of nearest quarter ), Game.Player.Azimuth - angle ); Game.Drawer.MovePanorama(-delta, -angle); //Assings player to new space grid currentQuarter.SpaceGrid.AddObject(Game.Player); Game.Drawer.ShowMessage(gameTime, String.Format("You've entered {0}.", currentQuarter.Name)); //Restart for drawing lastNearestInterfaceIndex = -1; currentQuarterDrawed = false; lastQuarterChange = gameTime.TotalGameTime; } FillDrawer(); currentQuarter.Update(gameTime, false); }
/// <summary> /// Fills the drawer with the selected quarters. /// </summary> void FillDrawer() { int nearestInterfaceIndex = -2; float length = float.MaxValue; for (int i = 0; i < currentQuarter.Interfaces.Count; i++) { Vector3 diff = Game.Camera.Position - currentQuarter.Interfaces[i].Position().ToVector3(0); if (diff.Length() < length) { length = diff.Length(); nearestInterfaceIndex = i; } } if (nearestInterfaceIndex != lastNearestInterfaceIndex) { if (lastNearestInterfaceIndex >= 0) { currentQuarter.Interfaces[lastNearestInterfaceIndex].OppositeInterface.Quarter.RemoveFromDrawer(); } lastNearestInterfaceIndex = nearestInterfaceIndex; TownQuarterInterface iface = currentQuarter.Interfaces[nearestInterfaceIndex]; Vector2 delta = ResolveQuarterPositionDelta(iface); float angle = ResolveQuarterAzimuthDelta(iface.SidePosition, iface.OppositeInterface.SidePosition); iface.OppositeInterface.Quarter.FillDrawer(angle, delta); if (!currentQuarterDrawed) { Game.Drawer.CurrentQuarter = currentQuarter; currentQuarter.FillDrawer(); currentQuarterDrawed = true; } } }
/// <summary> /// Generates road and sidewalks interfaces - street for joining with other quarters. /// </summary> /// <param name="degree">Number of'quarters neighbors - degree of vertex</param> /// <param name="roadTexture">Used road texture</param> /// <param name="sidewalkTexture">Used sidewalk texture</param> private void GenerateInterfaces(int degree, Texture2D roadTexture, Texture2D sidewalkTexture) { Dictionary<TownQuarterInterfacePosition, List<Range>> emptyRanges = new Dictionary<TownQuarterInterfacePosition, List<Range>>(4); emptyRanges.Add(TownQuarterInterfacePosition.Top, new List<Range>(new Range[] { new Range(BlockWidth + 1, bitmapSize.Width - BlockWidth - 1) })); emptyRanges.Add(TownQuarterInterfacePosition.Bottom, new List<Range>(new Range[] { new Range(BlockWidth + 1, bitmapSize.Width - BlockWidth - 1) })); emptyRanges.Add(TownQuarterInterfacePosition.Left, new List<Range>(new Range[] { new Range(BlockWidth + 1, bitmapSize.Height - BlockWidth - 1) })); emptyRanges.Add(TownQuarterInterfacePosition.Right, new List<Range>(new Range[] { new Range(BlockWidth + 1, bitmapSize.Height - BlockWidth - 1) })); for (int i = 0; i < degree; i++) { TownQuarterInterfacePosition side; List<TownQuarterInterfacePosition> possibleSides = new List<TownQuarterInterfacePosition>( from key in emptyRanges.Keys where emptyRanges[key].Count(rangeItem => rangeItem.Length > 2 * BlockWidth + 1) > 0 select key ); if (possibleSides.Count < 1) { throw new NoSpaceForInterfaceException("This quarter has already full all sides of interfaces. Degree argument is too big."); } side = possibleSides[game.Random.Next(0, possibleSides.Count - 1)]; List<Range> possibleRanges = emptyRanges[side].FindAll(rangeItem => rangeItem.Length > 2 * BlockWidth + 1); int rangeIndex = game.Random.Next(0, possibleRanges.Count - 1); Range range = possibleRanges[rangeIndex]; emptyRanges[side].Remove(range); int position = range.Begin + (int)((0.35 + game.Random.NextDouble() * 0.3) // percentage position in range * range.Length); emptyRanges[side].Add(new Range(range.Begin, position - 1)); emptyRanges[side].Add(new Range(position + 1, range.End)); AxisDirection direction = (side == TownQuarterInterfacePosition.Right || side == TownQuarterInterfacePosition.Left) ? AxisDirection.Horizontal : AxisDirection.Vertical; TownQuarterInterface iface = new TownQuarterInterface { SidePosition = side, Quarter = this, OppositeInterface = null }; for (int p = 0; p < BlockWidth; p++) { int rx, ry, slx, sly, srx, sry; switch (direction) { case AxisDirection.Horizontal: rx = (p + (side == TownQuarterInterfacePosition.Left ? 0 : bitmapSize.Width - BlockWidth)); ry = position; slx = rx; srx = rx; sly = ry - 1; sry = ry + 1; break; case AxisDirection.Vertical: rx = position; ry = (p + (side == TownQuarterInterfacePosition.Top ? 0 : bitmapSize.Height - BlockWidth)); slx = rx - 1; srx = rx + 1; sly = ry; sry = ry; break; default: throw new InvalidOperationException("Unknown AxisDirection value."); } if (direction == AxisDirection.Horizontal) iface.BitmapPosition = ry; if (direction == AxisDirection.Vertical) iface.BitmapPosition = rx; mapBitmap[rx * bitmapSize.Height + ry] = MapFillType.Road; mapBitmap[slx * bitmapSize.Height + sly] = MapFillType.Sidewalk; mapBitmap[srx * bitmapSize.Height + sry] = MapFillType.Sidewalk; FlatObject road = new FlatObject(new PositionInTown(this, new Vector2(rx * SquareWidth, ry * SquareWidth)), 0, new Vector2(SquareWidth, SquareWidth), roadTexture); FlatObject sidewalkL = new FlatObject(new PositionInTown(this, new Vector2(slx * SquareWidth, sly * SquareWidth)), 0, new Vector2(SquareWidth, SquareWidth), sidewalkTexture); FlatObject sidewalkR = new FlatObject(new PositionInTown(this, new Vector2(srx * SquareWidth, sry * SquareWidth)), 0, new Vector2(SquareWidth, SquareWidth), sidewalkTexture); groundObjects.AddLast(road); groundObjects.AddLast(sidewalkL); groundObjects.AddLast(sidewalkR); } //wall generator { Texture2D wallTexture = game.ContentRepository.InterfaceWall; float wallWidth = 6f; //m const float wallHeight = 4.5f; int count = (int)((BlockWidth - 1) * SquareWidth / wallWidth); //minus sidewalk wallWidth = (BlockWidth - 1) * SquareWidth / count; const float ifaceWallEpsilon = 0.006f; // 3mm for (int p = 0; p < count; p++) { Vector2 beginL, endL, beginR, endR; switch (direction) { case AxisDirection.Horizontal: beginL.X = p * wallWidth + (side == TownQuarterInterfacePosition.Left ? 0 : bitmapSize.Width - BlockWidth + 1) * SquareWidth; beginL.Y = (position - 1) * SquareWidth + ifaceWallEpsilon; endL = beginL; endL.X += wallWidth; beginR.X = p * wallWidth + (side == TownQuarterInterfacePosition.Left ? 0 : bitmapSize.Width - BlockWidth + 1) * SquareWidth; beginR.Y = (position + 2) * SquareWidth - ifaceWallEpsilon; endR = beginR; endR.X += wallWidth; break; case AxisDirection.Vertical: beginL.Y = p * wallWidth + (side == TownQuarterInterfacePosition.Top ? 0 : bitmapSize.Height - BlockWidth + 1) * SquareWidth; beginL.X = (position - 1) * SquareWidth + ifaceWallEpsilon; endL = beginL; endL.Y += wallWidth; beginR.Y = p * wallWidth + (side == TownQuarterInterfacePosition.Top ? 0 : bitmapSize.Height - BlockWidth + 1) * SquareWidth; beginR.X = (position + 2) * SquareWidth - ifaceWallEpsilon; endR = beginR; endR.Y += wallWidth; break; default: throw new InvalidOperationException("Unknown AxisDirection value."); } Plate wallL = new Plate(this, beginL.ToVector3(wallHeight), endL.ToVector3(wallHeight), beginL.ToVector3(0), endL.ToVector3(0), wallTexture, wallTexture, true); solidPlates.AddLast(wallL); Plate wallr = new Plate(this, beginR.ToVector3(wallHeight), endR.ToVector3(wallHeight), beginR.ToVector3(0), endR.ToVector3(0), wallTexture, wallTexture, true); solidPlates.AddLast(wallr); } } interfaces.Add(iface); } GenerateRestOfBorderSidewalks(emptyRanges, sidewalkTexture); GenerateBorderBuildings(emptyRanges); }
/// <summary> /// Calculates space translation between two quarters. /// </summary> /// <param name="iface">The interface symbolizing the two quarters join</param> /// <returns>The position delta</returns> public static Vector2 ResolveQuarterPositionDelta(TownQuarterInterface iface) { Vector2 delta = Vector2.Zero; switch (iface.SidePosition) { case TownQuarterInterfacePosition.Top: switch (iface.OppositeInterface.SidePosition) { case TownQuarterInterfacePosition.Top: delta.X = (iface.BitmapPosition + iface.OppositeInterface.BitmapPosition + 1) * TownQuarter.SquareWidth; delta.Y = 0; break; case TownQuarterInterfacePosition.Right: delta.X = (iface.BitmapPosition + iface.OppositeInterface.BitmapPosition + 1) * TownQuarter.SquareWidth; delta.Y = -(iface.OppositeInterface.Quarter.BitmapSize.Width * TownQuarter.SquareWidth); break; case TownQuarterInterfacePosition.Bottom: delta.X = (iface.BitmapPosition - iface.OppositeInterface.BitmapPosition) * TownQuarter.SquareWidth; delta.Y = -(iface.OppositeInterface.Quarter.BitmapSize.Height * TownQuarter.SquareWidth); break; case TownQuarterInterfacePosition.Left: delta.X = (iface.BitmapPosition - iface.OppositeInterface.BitmapPosition) * TownQuarter.SquareWidth; delta.Y = 0; break; } break; case TownQuarterInterfacePosition.Right: switch (iface.OppositeInterface.SidePosition) { case TownQuarterInterfacePosition.Top: delta.X = iface.Quarter.BitmapSize.Width * TownQuarter.SquareWidth; delta.Y = (iface.BitmapPosition + iface.OppositeInterface.BitmapPosition + 1) * TownQuarter.SquareWidth; break; case TownQuarterInterfacePosition.Right: delta.X = (iface.Quarter.BitmapSize.Width + iface.OppositeInterface.Quarter.BitmapSize.Width) * TownQuarter.SquareWidth; delta.Y = (iface.BitmapPosition + iface.OppositeInterface.BitmapPosition + 1) * TownQuarter.SquareWidth; break; case TownQuarterInterfacePosition.Bottom: delta.X = (iface.Quarter.BitmapSize.Width + iface.OppositeInterface.Quarter.BitmapSize.Height) * TownQuarter.SquareWidth; delta.Y = (iface.BitmapPosition - iface.OppositeInterface.BitmapPosition) * TownQuarter.SquareWidth; break; case TownQuarterInterfacePosition.Left: delta.X = iface.Quarter.BitmapSize.Width * TownQuarter.SquareWidth; delta.Y = (iface.BitmapPosition - iface.OppositeInterface.BitmapPosition) * TownQuarter.SquareWidth; break; } break; case TownQuarterInterfacePosition.Bottom: switch (iface.OppositeInterface.SidePosition) { case TownQuarterInterfacePosition.Top: delta.X = (iface.BitmapPosition - iface.OppositeInterface.BitmapPosition) * TownQuarter.SquareWidth; delta.Y = (iface.Quarter.BitmapSize.Height * TownQuarter.SquareWidth); break; case TownQuarterInterfacePosition.Right: delta.X = (iface.BitmapPosition - iface.OppositeInterface.BitmapPosition) * TownQuarter.SquareWidth; delta.Y = ((iface.Quarter.BitmapSize.Height + iface.OppositeInterface.Quarter.BitmapSize.Width) * TownQuarter.SquareWidth); break; case TownQuarterInterfacePosition.Bottom: delta.X = (iface.BitmapPosition + iface.OppositeInterface.BitmapPosition + 1) * TownQuarter.SquareWidth; delta.Y = ((iface.Quarter.BitmapSize.Height + iface.OppositeInterface.Quarter.BitmapSize.Height) * TownQuarter.SquareWidth); break; case TownQuarterInterfacePosition.Left: delta.X = (iface.BitmapPosition + iface.OppositeInterface.BitmapPosition + 1) * TownQuarter.SquareWidth; delta.Y = (iface.Quarter.BitmapSize.Height * TownQuarter.SquareWidth); break; } break; case TownQuarterInterfacePosition.Left: switch (iface.OppositeInterface.SidePosition) { case TownQuarterInterfacePosition.Top: delta.X = 0; delta.Y = (iface.BitmapPosition - iface.OppositeInterface.BitmapPosition) * TownQuarter.SquareWidth; break; case TownQuarterInterfacePosition.Right: delta.X = -(iface.OppositeInterface.Quarter.BitmapSize.Width) * TownQuarter.SquareWidth; delta.Y = (iface.BitmapPosition - iface.OppositeInterface.BitmapPosition) * TownQuarter.SquareWidth; break; case TownQuarterInterfacePosition.Bottom: delta.X = -(iface.OppositeInterface.Quarter.BitmapSize.Height) * TownQuarter.SquareWidth; delta.Y = (iface.BitmapPosition + iface.OppositeInterface.BitmapPosition + 1) * TownQuarter.SquareWidth; break; case TownQuarterInterfacePosition.Left: delta.X = 0; delta.Y = (iface.BitmapPosition + iface.OppositeInterface.BitmapPosition + 1) * TownQuarter.SquareWidth; break; } break; } return delta; }
/// <summary> /// Creates and generates the whole town. /// </summary> /// <param name="game">The game</param> /// <param name="loadingFrom">Loading form where the generating progress will be shown</param> public Town(ActionGame game, Loading loadingFrom) : base(game) { EmptyTownQuarterOwner.LoadContent(game.Content); quarters = new TownQuarter[game.Settings.TownQuarterCount]; //Town graph creation loadingFrom.SetLabel("Generating town graph..."); loadingFrom.SetValue(0); int[] degrees = new int[game.Settings.TownQuarterCount]; bool[,] edges = new bool[game.Settings.TownQuarterCount, game.Settings.TownQuarterCount]; // Graph is unoriented (symetric). edges[i, j] can be true only if i<j! for (int i = 0; i < game.Settings.TownQuarterCount - 1; i++) // First is made path through all. Graph has to have only one component. { int j = i + 1; degrees[i]++; degrees[j]++; edges[i, j] = true; } for (int i = 0; i < game.Settings.TownQuarterCount; i++) { loadingFrom.SetValue(100 * i / game.Settings.TownQuarterCount); for (int j = i + 1; j < game.Settings.TownQuarterCount; j++) //graph isn't oriented and reflexion is denied { if (!edges[i, j] && degrees[i] < MaxQuarterDegree && degrees[j] < MaxQuarterDegree) { if (game.Random.NextDouble() < 0.65) { degrees[i]++; degrees[j]++; edges[i, j] = true; } } } } //Quarter creating by degrees loadingFrom.SetLabel("Generating quarters and streets..."); loadingFrom.SetValue(0); for (int i = 0; i < game.Settings.TownQuarterCount; i++) { loadingFrom.SetValue(100 * i / game.Settings.TownQuarterCount); float perimeterLength = MinSideLengthPerInterface * Math.Max(degrees[i], 4); // Even interface isn't needed the side must be there perimeterLength *= (float)game.Random.NextDouble() + 1f; //Minimal length can be doubled float width = (perimeterLength / 2f) * (float)(game.Random.NextDouble() * 0.3 + 0.35); //aspect ratio float height = (perimeterLength / 2f) - width; if (width < MinQuarterSideLength) { width = MinQuarterSideLength; } if (height < MinQuarterSideLength) { height = MinQuarterSideLength; } do { try { TownQuarter quarter = new TownQuarter(game, new Vector2(width, height), degrees[i]); quarters[i] = quarter; } catch (NoSpaceForInterfaceException) { float widthIncement = MinSideLengthPerInterface * (float)game.Random.NextDouble(); width += widthIncement; height += MinSideLengthPerInterface - widthIncement; } }while (quarters[i] == null); } //Joining interfaces loadingFrom.SetLabel("Building town..."); loadingFrom.SetValue(0); for (int i = 0; i < game.Settings.TownQuarterCount; i++) { loadingFrom.SetValue(100 * i / game.Settings.TownQuarterCount); for (int j = i + 1; j < game.Settings.TownQuarterCount; j++) { if (edges[i, j]) { TownQuarterInterface ifaceI = (from iface in quarters[i].Interfaces where iface.OppositeInterface == null orderby game.Random.Next() select iface).First(); TownQuarterInterface ifaceJ = (from iface in quarters[j].Interfaces where iface.OppositeInterface == null orderby game.Random.Next() select iface).First(); ifaceI.OppositeInterface = ifaceJ; ifaceJ.OppositeInterface = ifaceI; ifaceI.LeftPathGraphVertex.AddNeighborBothDirection(ifaceJ.RightPathGraphVertex, TownQuarter.SquareWidth); ifaceI.RightPathGraphVertex.AddNeighborBothDirection(ifaceJ.LeftPathGraphVertex, TownQuarter.SquareWidth); } } } foreach (var quarter in quarters) { quarter.BuildInterfaceRoadSigns(); } //Town map base creating { Bitmap mapRaster = new Bitmap(MapImageWidth, MapImageHeight); using (Graphics graphics = Graphics.FromImage(mapRaster)) { graphics.FillRectangle(Brushes.White, 0, 0, mapRaster.Width, mapRaster.Height); float angleJump = MathHelper.TwoPi / Game.Settings.TownQuarterCount; float radius = Math.Min(MapImageWidth, MapImageHeight) / 2f - 20f; PointF center = new PointF(MapImageWidth / 2f, MapImageHeight / 2f); for (int i = 0; i < Game.Settings.TownQuarterCount; i++) { for (int j = i + 1; j < Game.Settings.TownQuarterCount; j++) { if (edges[i, j]) { graphics.DrawLine(Pens.Green, center.X + (float)Math.Cos(i * angleJump) * radius, center.Y + (float)Math.Sin(i * angleJump) * radius, center.X + (float)Math.Cos(j * angleJump) * radius, center.Y + (float)Math.Sin(j * angleJump) * radius ); } } } for (int i = 0; i < Game.Settings.TownQuarterCount; i++) { graphics.FillEllipse(Brushes.Black, center.X + (float)Math.Cos(i * angleJump) * radius - 3.5f, center.Y + (float)Math.Sin(i * angleJump) * radius - 3.5f, 7, 7); graphics.DrawString(quarters[i].Name, new Font("Verdana", 12), Brushes.Black, center.X + (float)Math.Cos(i * angleJump) * radius, center.Y + (float)Math.Sin(i * angleJump) * radius - 16); } } mapImage = mapRaster; } GC.Collect(); //Selecting starting quarter currentQuarter = quarters[0]; }
/// <summary> /// Calculates space translation between two quarters. /// </summary> /// <param name="iface">The interface symbolizing the two quarters join</param> /// <returns>The position delta</returns> public static Vector2 ResolveQuarterPositionDelta(TownQuarterInterface iface) { Vector2 delta = Vector2.Zero; switch (iface.SidePosition) { case TownQuarterInterfacePosition.Top: switch (iface.OppositeInterface.SidePosition) { case TownQuarterInterfacePosition.Top: delta.X = (iface.BitmapPosition + iface.OppositeInterface.BitmapPosition + 1) * TownQuarter.SquareWidth; delta.Y = 0; break; case TownQuarterInterfacePosition.Right: delta.X = (iface.BitmapPosition + iface.OppositeInterface.BitmapPosition + 1) * TownQuarter.SquareWidth; delta.Y = -(iface.OppositeInterface.Quarter.BitmapSize.Width * TownQuarter.SquareWidth); break; case TownQuarterInterfacePosition.Bottom: delta.X = (iface.BitmapPosition - iface.OppositeInterface.BitmapPosition) * TownQuarter.SquareWidth; delta.Y = -(iface.OppositeInterface.Quarter.BitmapSize.Height * TownQuarter.SquareWidth); break; case TownQuarterInterfacePosition.Left: delta.X = (iface.BitmapPosition - iface.OppositeInterface.BitmapPosition) * TownQuarter.SquareWidth; delta.Y = 0; break; } break; case TownQuarterInterfacePosition.Right: switch (iface.OppositeInterface.SidePosition) { case TownQuarterInterfacePosition.Top: delta.X = iface.Quarter.BitmapSize.Width * TownQuarter.SquareWidth; delta.Y = (iface.BitmapPosition + iface.OppositeInterface.BitmapPosition + 1) * TownQuarter.SquareWidth; break; case TownQuarterInterfacePosition.Right: delta.X = (iface.Quarter.BitmapSize.Width + iface.OppositeInterface.Quarter.BitmapSize.Width) * TownQuarter.SquareWidth; delta.Y = (iface.BitmapPosition + iface.OppositeInterface.BitmapPosition + 1) * TownQuarter.SquareWidth; break; case TownQuarterInterfacePosition.Bottom: delta.X = (iface.Quarter.BitmapSize.Width + iface.OppositeInterface.Quarter.BitmapSize.Height) * TownQuarter.SquareWidth; delta.Y = (iface.BitmapPosition - iface.OppositeInterface.BitmapPosition) * TownQuarter.SquareWidth; break; case TownQuarterInterfacePosition.Left: delta.X = iface.Quarter.BitmapSize.Width * TownQuarter.SquareWidth; delta.Y = (iface.BitmapPosition - iface.OppositeInterface.BitmapPosition) * TownQuarter.SquareWidth; break; } break; case TownQuarterInterfacePosition.Bottom: switch (iface.OppositeInterface.SidePosition) { case TownQuarterInterfacePosition.Top: delta.X = (iface.BitmapPosition - iface.OppositeInterface.BitmapPosition) * TownQuarter.SquareWidth; delta.Y = (iface.Quarter.BitmapSize.Height * TownQuarter.SquareWidth); break; case TownQuarterInterfacePosition.Right: delta.X = (iface.BitmapPosition - iface.OppositeInterface.BitmapPosition) * TownQuarter.SquareWidth; delta.Y = ((iface.Quarter.BitmapSize.Height + iface.OppositeInterface.Quarter.BitmapSize.Width) * TownQuarter.SquareWidth); break; case TownQuarterInterfacePosition.Bottom: delta.X = (iface.BitmapPosition + iface.OppositeInterface.BitmapPosition + 1) * TownQuarter.SquareWidth; delta.Y = ((iface.Quarter.BitmapSize.Height + iface.OppositeInterface.Quarter.BitmapSize.Height) * TownQuarter.SquareWidth); break; case TownQuarterInterfacePosition.Left: delta.X = (iface.BitmapPosition + iface.OppositeInterface.BitmapPosition + 1) * TownQuarter.SquareWidth; delta.Y = (iface.Quarter.BitmapSize.Height * TownQuarter.SquareWidth); break; } break; case TownQuarterInterfacePosition.Left: switch (iface.OppositeInterface.SidePosition) { case TownQuarterInterfacePosition.Top: delta.X = 0; delta.Y = (iface.BitmapPosition - iface.OppositeInterface.BitmapPosition) * TownQuarter.SquareWidth; break; case TownQuarterInterfacePosition.Right: delta.X = -(iface.OppositeInterface.Quarter.BitmapSize.Width) * TownQuarter.SquareWidth; delta.Y = (iface.BitmapPosition - iface.OppositeInterface.BitmapPosition) * TownQuarter.SquareWidth; break; case TownQuarterInterfacePosition.Bottom: delta.X = -(iface.OppositeInterface.Quarter.BitmapSize.Height) * TownQuarter.SquareWidth; delta.Y = (iface.BitmapPosition + iface.OppositeInterface.BitmapPosition + 1) * TownQuarter.SquareWidth; break; case TownQuarterInterfacePosition.Left: delta.X = 0; delta.Y = (iface.BitmapPosition + iface.OppositeInterface.BitmapPosition + 1) * TownQuarter.SquareWidth; break; } break; } return(delta); }