/// <summary>
 /// Creates a new bullet visualisation.
 /// </summary>
 /// <param name="quarter">Town quarter where the bullet is located</param>
 /// <param name="start">Starting position</param>
 /// <param name="azimuth">The flight direction</param>
 /// <param name="range">The flight range</param>
 /// <param name="startHeight">Starting height</param>
 /// <param name="endHeight">Ending height</param>
 public BulletVisualisation(TownQuarter quarter, Vector2 start, float azimuth, float range, float startHeight, float endHeight)
 {
     Vector2 end = start.Go(range, azimuth);
     Vector2 startL = start.Go(Width, azimuth - MathHelper.PiOver2);
     Vector2 startR = start.Go(Width, azimuth + MathHelper.PiOver2);
     Vector2 endL = end.Go(Width, azimuth - MathHelper.PiOver2);
     Vector2 endR = end.Go(Width, azimuth + MathHelper.PiOver2);
     horizontalPlate = new Plate(quarter, startL.ToVector3(startHeight), startR.ToVector3(startHeight), endL.ToVector3(endHeight), endR.ToVector3(endHeight), Texture, Texture, false);
     verticalPlate = new Plate(quarter, start.ToVector3(startHeight + Width), start.ToVector3(startHeight - Width), end.ToVector3(endHeight + Width), end.ToVector3(endHeight - Width), Texture, Texture, false);
 }
Exemple #2
0
        /// <summary>
        /// Creates a new bullet visualisation.
        /// </summary>
        /// <param name="quarter">Town quarter where the bullet is located</param>
        /// <param name="start">Starting position</param>
        /// <param name="azimuth">The flight direction</param>
        /// <param name="range">The flight range</param>
        /// <param name="startHeight">Starting height</param>
        /// <param name="endHeight">Ending height</param>
        public BulletVisualisation(TownQuarter quarter, Vector2 start, float azimuth, float range, float startHeight, float endHeight)
        {
            Vector2 end    = start.Go(range, azimuth);
            Vector2 startL = start.Go(Width, azimuth - MathHelper.PiOver2);
            Vector2 startR = start.Go(Width, azimuth + MathHelper.PiOver2);
            Vector2 endL   = end.Go(Width, azimuth - MathHelper.PiOver2);
            Vector2 endR   = end.Go(Width, azimuth + MathHelper.PiOver2);

            horizontalPlate = new Plate(quarter, startL.ToVector3(startHeight), startR.ToVector3(startHeight), endL.ToVector3(endHeight), endR.ToVector3(endHeight), Texture, Texture, false);
            verticalPlate   = new Plate(quarter, start.ToVector3(startHeight + Width), start.ToVector3(startHeight - Width), end.ToVector3(endHeight + Width), end.ToVector3(endHeight - Width), Texture, Texture, false);
        }
        /// <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>
        /// Builds the roadsigns for the neighbor quarters.
        /// </summary>
        public void BuildInterfaceRoadSigns()
        {
            const float vPosition = 8;
            float height = 2f;
            const float width = 6f;
            const float halfWidth = width / 2;
            Model handleModel = game.Content.Load<Model>("Objects/roadSignHandle");
            Vector3 handleModelSize = handleModel.GetSize(game.Drawer.WorldTransformMatrix);
            foreach (TownQuarterInterface iface in interfaces)
            {
                Vector2 handlePos = Vector2.Zero;
                float handleAzimuth = 0f;
                Vector3 upperLeft = iface.Position().ToVector3(vPosition);
                Vector3 upperRight = upperLeft;
                const float handleEpsilon = 0.02f; //2cm
                switch (iface.SidePosition)
                {
                    case TownQuarterInterfacePosition.Top:
                        upperLeft.X -= halfWidth;
                        upperRight.X += halfWidth;
                        upperLeft.Z += (BlockWidth - 2) * SquareWidth;
                        upperRight.Z += (BlockWidth - 2) * SquareWidth;

                        handlePos = upperLeft.XZToVector2();
                        handlePos.X += halfWidth;
                        handlePos.X -= handleModelSize.X * 0.5f;
                        handlePos.Y -= handleModelSize.Z + handleEpsilon;
                        handleAzimuth = 0f;
                        break;
                    case TownQuarterInterfacePosition.Right:
                        upperLeft.Z -= halfWidth;
                        upperRight.Z += halfWidth;
                        upperLeft.X -= (BlockWidth - 2) * SquareWidth;
                        upperRight.X -= (BlockWidth - 2) * SquareWidth;

                        handlePos = upperLeft.XZToVector2();
                        handlePos.Y += halfWidth;
                        //handlePos.Y -= handleModelSize.X * 0.5f;
                        handlePos.X += handleModelSize.Z + handleEpsilon - handleModelSize.X * 0.5f - handleModelSize.Z * 0.5f;
                        handleAzimuth = MathHelper.PiOver2;
                        break;
                    case TownQuarterInterfacePosition.Bottom:
                        upperLeft.X += halfWidth;
                        upperRight.X -= halfWidth;
                        upperLeft.Z -= (BlockWidth - 2) * SquareWidth;
                        upperRight.Z -= (BlockWidth - 2) * SquareWidth;

                        handlePos = upperLeft.XZToVector2();
                        handlePos.X -= halfWidth;
                        handlePos.X -= handleModelSize.X * 0.5f;
                        handlePos.Y += handleEpsilon;
                        handleAzimuth = 0f;
                        break;
                    case TownQuarterInterfacePosition.Left:
                        upperLeft.Z += halfWidth;
                        upperRight.Z -= halfWidth;
                        upperLeft.X += (BlockWidth - 2) * SquareWidth;
                        upperRight.X += (BlockWidth - 2) * SquareWidth;

                        handlePos = upperLeft.XZToVector2();
                        handlePos.Y -= halfWidth;
                        //handlePos.Y -= handleModelSize.X * 0.5f;
                        handlePos.X -= handleModelSize.Z + handleEpsilon + handleModelSize.X * 0.5f - handleModelSize.Z * 0.5f;
                        handleAzimuth = MathHelper.PiOver2;
                        break;
                    default:
                        break;
                }
                Vector3 lowerLeft = upperLeft, lowerRight = upperRight;
                lowerLeft.Y -= height;
                lowerRight.Y -= height;
                Plate signPlate = new Plate(this, upperLeft, upperRight, lowerLeft, lowerRight, iface.OppositeInterface.Quarter.RoadSignTexture, game.Content.Load<Texture2D>("Textures/metal"), true);
                magicPlates.AddLast(signPlate);
                iface.OppositeInterface.Quarter.RegisterNewRoadSign(signPlate);
                SpatialObject handle = new SpatialObject(handleModel, new PositionInTown(this, handlePos), handleAzimuth, game.Drawer.WorldTransformMatrix);
                solidObjects.AddLast(handle);
            }
        }
Exemple #5
0
 /// <summary>
 /// Registers a roadsign that is pointing to this quarter
 /// </summary>
 /// <param name="roadSign">The roadsign</param>
 public void RegisterNewRoadSign(Plate roadSign)
 {
     roadSignsPointingToMe.Add(roadSign);
 }