예제 #1
0
파일: Town.cs 프로젝트: havri/ActionGame
 /// <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();
 }
예제 #2
0
파일: Town.cs 프로젝트: havri/ActionGame
        /// <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);
        }
예제 #3
0
파일: Town.cs 프로젝트: havri/ActionGame
        /// <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;
                }
            }
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
파일: Town.cs 프로젝트: havri/ActionGame
        /// <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;
        }
예제 #6
0
파일: Town.cs 프로젝트: havri/ActionGame
        /// <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];
        }
예제 #7
0
파일: Town.cs 프로젝트: havri/ActionGame
        /// <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);
        }