Esempio n. 1
0
        /// <summary>
        /// Performs a gun action - the shoot. It Releases the bullet into the space and calls the bullet collision resolving.
        /// </summary>
        /// <param name="gameTime">Game time</param>
        /// <param name="position">The gun position in the shoot moment</param>
        /// <param name="azimuth">The shoot direction</param>
        public override void DoAction(GameTime gameTime, PositionInTown position, float azimuth)
        {
            if (gameTime.TotalGameTime - lastTimeShot >= type.ShotTimeout && Usable)
            {
                bool somethingWasHit = PerformShoot(gameTime, position, azimuth, true);

                if (!somethingWasHit && Holder is Player) //affect the secondary drawn quarter
                {
                    TownQuarter secondaryQuarter = Game.Town.SecondaryDrawnQuarter;
                    Debug.Write("Secondary quarer", secondaryQuarter.Name);
                    Vector2        positionDelta     = secondaryQuarter.CurrentDrawingPositionDelta;
                    float          azimuthDelta      = secondaryQuarter.CurrentDrawingAzimuthDelta;
                    PositionInTown secondaryPosition = new PositionInTown(secondaryQuarter, Vector3.Transform(position.PositionInQuarter.ToVector3(0), Matrix.CreateTranslation(-positionDelta.ToVector3(0)) * Matrix.CreateRotationY(azimuthDelta)).XZToVector2());
                    float          secondaryAzimuth  = azimuth - azimuthDelta;
                    PerformShoot(gameTime, secondaryPosition, secondaryAzimuth, false);
                    if (secondaryQuarter != Game.Opponent.Position.Quarter && gameTime.IsRunningSlowly)
                    {
                        secondaryQuarter.Update(gameTime, true);
                    }
                }

                Game.SoundPlayer.PlaySound(type.ShootSount, position);
                lastTimeShot = gameTime.TotalGameTime;
                bullets--;
            }
        }
Esempio n. 2
0
 /// <summary>
 /// Plays specified sound at specified place. It automaticly sets the volume.
 /// </summary>
 /// <param name="sound">The specified sound</param>
 /// <param name="position">The specified position</param>
 public void PlaySound(SoundEffect sound, PositionInTown position)
 {
     if (game.Player.Position.Quarter == position.Quarter)
     {
         float quarterDiagonalLength = (new Vector2(position.Quarter.BitmapSize.Width, position.Quarter.BitmapSize.Height) * TownQuarter.SquareWidth).Length();
         sound.Play(1f - (position.MinimalDistanceTo(game.Player.Position) / quarterDiagonalLength), 0f, 0f);
     }
 }
Esempio n. 3
0
 /// <summary>
 /// Recomputes the waypoints according to path graph to get to the task target.
 /// </summary>
 /// <param name="from">Start position</param>
 /// <param name="to">Destination position</param>
 protected void RecomputeWaypoints(PositionInTown from, PositionInTown to)
 {
     wayPoints.Clear();
     foreach (PathGraphVertex v in PathGraph.FindShortestPath(from, to, !(holder is Opponent)))
     {
         wayPoints.Enqueue(new WayPoint(v.Position));
     }
     wayPoints.Enqueue(new WayPoint(to));
 }
Esempio n. 4
0
 /// <summary>
 /// Respawns the human into a specified quarter.
 /// </summary>
 /// <param name="targetQuarter">The destination quarter</param>
 public void RespawnInto(TownQuarter targetQuarter)
 {
     Position.Quarter.BeLeftBy(this);
     Position = new PositionInTown(targetQuarter,
                                   targetQuarter.GetRandomSquare(fillType => fillType == MapFillType.Road, point => point != targetQuarter.FlagPoint).ToVector2() * TownQuarter.SquareWidth);
     Position.Quarter.BeEnteredBy(this);
     health = 100;
     tasks.Clear();
 }
Esempio n. 5
0
 /// <summary>
 /// Creates a new instance of human
 /// </summary>
 /// <param name="game">The game</param>
 /// <param name="model">Model</param>
 /// <param name="position">Position</param>
 /// <param name="azimuth">Azimuth</param>
 /// <param name="worldTransform">World transform matrix</param>
 public Human(ActionGame game, Model model, PositionInTown position, double azimuth, Matrix worldTransform)
     : base(model, position, azimuth, worldTransform)
 {
     this.game = game;
     health    = 100;
     tools.AddRange(
         from gunType in game.HumanDefaultGuns select new Gun(gunType, gunType.DefaultBulletCount, this, game)
         );
     selectedToolIndex = 0;
     lastPosition      = position.PositionInQuarter;
     lastSeenEnemy     = null;
     lastTimeSawEnemy  = TimeSpan.Zero;
 }
Esempio n. 6
0
        protected void Load(Model model, PositionInTown position, float verticalPosition, double azimuth, Matrix worldTransform)
        {
            this.model            = model;
            this.verticalPosition = verticalPosition;
            Vector3 size = Vector3.Zero;

            if (model != null)
            {
                size         = model.GetSize(worldTransform);
                verticalSize = size.Y;
            }
            base.Load(position, azimuth, size.XZToVector2());
        }
Esempio n. 7
0
        /// <summary>
        /// Loads and sets the player's specific content and settings.
        /// </summary>
        /// <param name="model">Model</param>
        /// <param name="position">Position</param>
        /// <param name="azimuth">Azimuth</param>
        /// <param name="worldTransform">The world transform matrix</param>
        public new void Load(Model model, PositionInTown position, double azimuth, Matrix worldTransform)
        {
            base.Load(model, position, azimuth, worldTransform);

            Content = new TownQuarterOwnerContent
            {
                AllyHumanModel  = Game.Content.Load <Model>("Objects/Humans/botBlue"),
                FlagModel       = Game.Content.Load <Model>("Objects/Decorations/flagBlue2"),
                RoadSignTexture = Game.Content.Load <Texture2D>("Textures/roadSignBlue"),
                ColorTexture    = Game.Content.Load <Texture2D>("Textures/blue"),
                DrawingColor    = System.Drawing.Color.Blue
            };
        }
Esempio n. 8
0
        /// <summary>
        /// Loads and sets the opponent specific content and settings
        /// </summary>
        /// <param name="model">Model</param>
        /// <param name="position">Postion</param>
        /// <param name="azimuth">Azimuth</param>
        /// <param name="worldTransform">World transform matrix</param>
        public void Load(Model model, PositionInTown position, double azimuth, Matrix worldTransform)
        {
            base.Load(model, position, 0, azimuth, worldTransform);

            Content = new TownQuarterOwnerContent
            {
                AllyHumanModel  = Game.Content.Load <Model>("Objects/Humans/botYellow"),
                FlagModel       = Game.Content.Load <Model>("Objects/Decorations/flagYellow2"),
                RoadSignTexture = Game.Content.Load <Texture2D>("Textures/roadSignYellow"),
                ColorTexture    = Game.Content.Load <Texture2D>("Textures/yellow"),
                DrawingColor    = System.Drawing.Color.Yellow
            };

            Running = true;
        }
Esempio n. 9
0
 /// <summary>
 /// Rotates the human toward the specified destination.
 /// </summary>
 /// <param name="destination">The destination</param>
 /// <param name="seconds">Moving duration</param>
 public void TurnThisWay(PositionInTown destination, float seconds)
 {
     if (destination.Quarter == Position.Quarter)
     {
         double actualRotateAngle = RotateAngle * seconds;
         float  direction         = (destination.PositionInQuarter - Position.PositionInQuarter).GetAngle() + 1 * MathHelper.PiOver2;
         direction = direction % MathHelper.TwoPi;
         if (IsAzimuthTooFarFrom(direction, actualRotateAngle))
         {
             bool toLeft = (azimuth > direction && direction >= 0 && azimuth - direction < MathHelper.Pi) || (direction > azimuth && direction - azimuth > MathHelper.Pi);
             Rotate(toLeft, seconds);
         }
         else
         {
             azimuth = direction;
         }
     }
 }
Esempio n. 10
0
        /// <summary>
        /// Creates a new flat object.
        /// </summary>
        /// <param name="position">Position of the object</param>
        /// <param name="azimuth">Azimuth</param>
        /// <param name="size">Size (width, lenght)</param>
        /// <param name="texture">Used texture</param>
        public FlatObject(PositionInTown position, double azimuth, Vector2 size, Texture2D texture)
            : base(position, azimuth, size)
        {
            this.texture = texture;
            vertices     = new VertexPositionNormalTexture[4];
            indexes      = new short[6];

            Vector2 textureUpperLeft  = new Vector2(0.0f, 0.0f);
            Vector2 textureUpperRight = new Vector2(1.0f, 0.0f);
            Vector2 textureLowerLeft  = new Vector2(0.0f, 1.0f);
            Vector2 textureLowerRight = new Vector2(1.0f, 1.0f);

            for (int i = 0; i < vertices.Length; i++)
            {
                vertices[i].Normal = Vector3.Up;
            }

            vertices[0].Position          = LowerLeftCorner.ToVector3(verticalPosition);
            vertices[0].TextureCoordinate = textureLowerLeft;
            vertices[1].Position          = UpperLeftCorner.ToVector3(verticalPosition);
            vertices[1].TextureCoordinate = textureUpperLeft;
            vertices[2].Position          = LowerRightCorner.ToVector3(verticalPosition);
            vertices[2].TextureCoordinate = textureLowerRight;
            vertices[3].Position          = UpperRightCorner.ToVector3(verticalPosition);
            vertices[3].TextureCoordinate = textureUpperRight;

            indexes[0] = 0;
            indexes[1] = 1;
            indexes[2] = 2;
            indexes[3] = 2;
            indexes[4] = 1;
            indexes[5] = 3;

            quadEffect = new BasicEffect(texture.GraphicsDevice);
            quadEffect.EnableDefaultLighting();
            quadEffect.TextureEnabled = true;
            quadEffect.Texture        = texture;
        }
Esempio n. 11
0
        /// <summary>
        /// Creates a new guard for this human.
        /// </summary>
        /// <param name="targetQuarter">Quarted that has to be guarded</param>
        /// <returns>The guard</returns>
        public Human CreateAllyGuard(TownQuarter targetQuarter)
        {
            PositionInTown pos   = new PositionInTown(targetQuarter, targetQuarter.GetRandomSquare(x => x == MapFillType.Road).ToVector2() * TownQuarter.SquareWidth);
            Human          guard = new Human(game, Content.AllyHumanModel, pos, 0, game.Drawer.WorldTransformMatrix);

            foreach (Human enemy in enemies)
            {
                guard.AddEnemy(enemy);
            }
            foreach (Human friend in friends)
            {
                guard.AddFriend(friend);
            }
            foreach (Human has in hasMeAsEnemy)
            {
                has.AddEnemy(guard);
            }
            guard.AddTask(new InfinityWalkingTask(guard, targetQuarter.GetRandomWalkingWaypoints()));
            foreach (GunType gt in game.GuardDefaultGuns)
            {
                guard.AddTool(new Gun(gt, gt.DefaultBulletCount, guard, game));
            }
            return(guard);
        }
Esempio n. 12
0
 protected void Load(PositionInTown position, double azimuth, Vector2 size)
 {
     this.position = position;
     this.azimuth  = azimuth;
     this.size     = size;
 }
Esempio n. 13
0
 /// <summary>
 /// Creates a new spatial object.
 /// </summary>
 /// <param name="model">Model</param>
 /// <param name="position">Posistion</param>
 /// <param name="azimuth">Azimuth</param>
 /// <param name="worldTransform">World transform matrix</param>
 public SpatialObject(Model model, PositionInTown position, double azimuth, Matrix worldTransform)
     : base(position, azimuth, (model == null ? Vector2.Zero : model.GetSize(worldTransform).XZToVector2()))
 {
     Load(model, position, 0, azimuth, worldTransform);
 }
Esempio n. 14
0
 /// <summary>
 /// Creates a new flag action object
 /// </summary>
 /// <param name="game">The game</param>
 /// <param name="model">Model</param>
 /// <param name="position">Position</param>
 /// <param name="azimuth">Azimuth</param>
 /// <param name="worldTransform">World transform matrix</param>
 public Flag(ActionGame game, Model model, PositionInTown position, double azimuth, Matrix worldTransform)
     : base(game, ActionDistance, model, position, azimuth, worldTransform)
 {
 }
Esempio n. 15
0
 /// <summary>
 /// Creates a new Box
 /// </summary>
 /// <param name="game">The game</param>
 /// <param name="takeSound">Sound that will be played if the box is taken</param>
 /// <param name="model"></param>
 /// <param name="position"></param>
 /// <param name="world"></param>
 public Box(ActionGame game, SoundEffect takeSound, Model model, PositionInTown position, Matrix world)
     : base(model, position, 0, world)
 {
     this.takeSound = takeSound;
     this.game      = game;
 }
Esempio n. 16
0
 /// <summary>
 /// Chages the objects position and azimuth.
 /// </summary>
 /// <param name="newPosition">The new position</param>
 /// <param name="azimuth">The new azimuth</param>
 public void MoveTo(PositionInTown newPosition, double azimuth)
 {
     position     = newPosition;
     this.azimuth = azimuth;
 }
Esempio n. 17
0
 /// <summary>
 /// Performs the specific tool action if it is overriden.
 /// </summary>
 /// <param name="gameTime">Game time</param>
 /// <param name="position">The position of the tool at the action moment</param>
 /// <param name="azimuth">The action direction</param>
 public abstract void DoAction(GameTime gameTime, PositionInTown position, float azimuth);
Esempio n. 18
0
        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            if (running)
            {
                using (Loading loadingForm = new Loading())
                {
                    GameTime gameTime = new GameTime(TimeSpan.Zero, TimeSpan.Zero);
                    loadingForm.Show();

                    loadingForm.SetLabel("Loading graphics device tools...");
                    spriteBatch = new SpriteBatch(GraphicsDevice);

                    loadingForm.SetLabel("Loading content...");
                    contentRepository.LoadContent();

                    loadingForm.SetLabel("Loading gun types...");
                    LoadGunTypes();

                    player   = new Player(this);
                    opponent = new Opponent(this);

                    town = new Town(this, loadingForm);

                    loadingForm.SetLabel("Loading player...");
                    loadingForm.SetValue(0);
                    Point          playerPoint    = town.CurrentQuarter.GetRandomSquare(s => s == MapFillType.Sidewalk);
                    PositionInTown playerPosition = new PositionInTown(town.CurrentQuarter, playerPoint.ToVector2() * TownQuarter.SquareWidth + Vector2.One * 0.5f * TownQuarter.SquareWidth);
                    player.Load(contentRepository.Player, playerPosition, MathHelper.PiOver2, drawer.WorldTransformMatrix);
                    town.CurrentQuarter.SpaceGrid.AddObject(player);
                    town.CurrentQuarter.SetOwner(player, gameTime);
                    player.AddEnemy(opponent);

                    loadingForm.SetLabel("Loading opponent...");
                    loadingForm.SetValue(0);
                    TownQuarter    oppQuarter  = (from q in town.Quarters where q != town.CurrentQuarter orderby random.Next() select q).First();
                    Point          oppPoint    = oppQuarter.GetRandomSquare(s => s == MapFillType.Sidewalk);
                    PositionInTown oppPosition = new PositionInTown(oppQuarter, oppPoint.ToVector2() * TownQuarter.SquareWidth);
                    opponent.Load(contentRepository.Opponent, oppPosition, 0, drawer.WorldTransformMatrix);
                    oppQuarter.BeEnteredBy(opponent);
                    oppQuarter.SetOwner(opponent, gameTime);
                    opponent.AddEnemy(player);
                    Components.Add(town);


                    BulletVisualisation.Texture = Content.Load <Texture2D>("Textures/white");
                    backgroundSound             = Content.Load <SoundEffect>("Sounds/background").CreateInstance();

                    loadingForm.SetLabel("Cleaning memory...");
                    loadingForm.SetValue(0);
                    GC.Collect();
                    loadingForm.SetValue(100);

                    loadingForm.SetLabel("Content loaded. Get ready to play!");
                    loadingForm.SetValue(100);
                    loadingForm.Close();

                    backgroundSound.IsLooped = true;
                    backgroundSound.Play();
                    drawer.ShowMessage(new GameTime(), String.Format("Wellcome in the game. You're in {0}.", player.Position.Quarter.Name));
                }
                if (settings.Fullscreen)
                {
                    graphics.ToggleFullScreen();
                }
            }
        }
Esempio n. 19
0
 public WayPoint(PositionInTown point)
 {
     this.point = point;
 }
Esempio n. 20
0
 /// <summary>
 /// Creates new action object.
 /// </summary>
 /// <param name="game">The game</param>
 /// <param name="actionDistance">Distance from which the action can be performed</param>
 /// <param name="model">Model of the action object</param>
 /// <param name="position">Position</param>
 /// <param name="azimuth">Azimuth</param>
 /// <param name="worldTransform">World transform matrix</param>
 public ActionObject(ActionGame game, float actionDistance, Model model, PositionInTown position, double azimuth, Matrix worldTransform)
     : base(model, position, azimuth, worldTransform)
 {
     this.actionDistance = actionDistance;
     this.game           = game;
 }
Esempio n. 21
0
 void ComputeWayPointsFrom(PositionInTown from)
 {
     RecomputeWaypoints(from, destination);
 }
Esempio n. 22
0
        /// <summary>
        /// Performs move to the spcifed target.
        /// </summary>
        /// <param name="destination">Wished destination</param>
        /// <param name="seconds">Duration</param>
        public void GoThisWay(PositionInTown destination, float seconds)
        {
            if (destination.Quarter == Position.Quarter)
            {
                double actualRotateAngle = RotateAngle * seconds;
                float  direction         = (destination.PositionInQuarter - Position.PositionInQuarter).GetAngle() + 1 * MathHelper.PiOver2;
                direction = direction % MathHelper.TwoPi;
                if (IsAzimuthTooFarFrom(direction, actualRotateAngle))
                {
                    bool toLeft = (azimuth > direction && direction >= 0 && azimuth - direction < MathHelper.Pi) || (direction > azimuth && direction - azimuth > MathHelper.Pi);
                    Rotate(toLeft, seconds);

                    if (Math.Abs(azimuth - direction) < MathHelper.PiOver2 && Position.MinimalDistanceTo(destination) > TownQuarter.SquareWidth)
                    {
                        Go(seconds);
                    }
                }
                else
                {
                    azimuth = direction;
                    Go(seconds);
                }
            }
            else
            {
                TownQuarterInterface rightIface = null;
                foreach (TownQuarterInterface iface in Position.Quarter.Interfaces)
                {
                    if (iface.OppositeInterface.Quarter == destination.Quarter)
                    {
                        rightIface = iface;
                    }
                }
                if (rightIface != null)
                {
                    if (Position.MinimalDistanceTo(rightIface.LeftPathGraphVertex.Position) <= Human.EpsilonDistance ||
                        Position.MinimalDistanceTo(rightIface.RightPathGraphVertex.Position) <= Human.EpsilonDistance)
                    {
                        //Changes home quarter
                        TownQuarter newQuarter = rightIface.OppositeInterface.Quarter;
                        Position.Quarter.BeLeftBy(this);
                        Game.Drawer.StopDrawingObject(this);
                        Vector2 posDelta = Town.ResolveQuarterPositionDelta(rightIface);
                        float   azDelta  = Town.ResolveQuarterAzimuthDelta(rightIface.SidePosition, rightIface.OppositeInterface.SidePosition);
                        MoveTo(
                            new PositionInTown(newQuarter, Vector3.Transform(PositionInQuarter,
                                                                             Matrix.CreateTranslation(-posDelta.ToVector3(0)) * Matrix.CreateRotationY(azDelta)).XZToVector2()),
                            Azimuth - azDelta
                            );
                        newQuarter.BeEnteredBy(this);
                        if (newQuarter.CurrentlyDrawed)
                        {
                            Game.Drawer.StartDrawingObject(this, newQuarter.CurrentDrawingAzimuthDelta, newQuarter.CurrentDrawingPositionDelta);
                        }
                    }
                    else
                    {
                        GoThisWay(rightIface.LeftPathGraphVertex.Position, seconds);
                    }
                }
            }
        }
Esempio n. 23
0
 /// <summary>
 /// Loads the human specific content. This can be used if the content wasn't specified in the construct.
 /// </summary>
 /// <param name="model">Model</param>
 /// <param name="position">Position</param>
 /// <param name="azimuth">Azimuth</param>
 /// <param name="worldTransform">World transform matrix</param>
 public void Load(Model model, PositionInTown position, double azimuth, Matrix worldTransform)
 {
     base.Load(model, position, 0, azimuth, worldTransform);
     lastPosition = position.PositionInQuarter;
 }
Esempio n. 24
0
 /// <summary>
 /// Creates a new game object
 /// </summary>
 /// <param name="position">Position</param>
 /// <param name="azimuth">Azimuth</param>
 /// <param name="size">Size (width, length)</param>
 public GameObject(PositionInTown position, double azimuth, Vector2 size)
 {
     Load(position, azimuth, size);
 }
Esempio n. 25
0
 /// <summary>
 /// Creates a new heal box.
 /// </summary>
 /// <param name="healPercentage">Percentage that will be added to the human's health status if he takes it.</param>
 /// <param name="game">The game</param>
 /// <param name="takeSound">The take sound effect</param>
 /// <param name="model">Model of the box</param>
 /// <param name="position">Position</param>
 /// <param name="world">World transformation matrix</param>
 public HealBox(int healPercentage, ActionGame game, SoundEffect takeSound, Model model, PositionInTown position, Matrix world)
     : base(game, takeSound, model, position, world)
 {
     this.healPercentage = healPercentage;
 }
Esempio n. 26
0
 /// <summary>
 /// Creates a new toolbox
 /// </summary>
 /// <param name="toolInside">The tool instance inside</param>
 /// <param name="game">The game</param>
 /// <param name="takeSound">The taking sound</param>
 /// <param name="model">Model of the box</param>
 /// <param name="position">Position of the box</param>
 /// <param name="world">World transformation matrix</param>
 public ToolBox(Tool toolInside, ActionGame game, SoundEffect takeSound, Model model, PositionInTown position, Matrix world)
     : base(game, takeSound, model, position, world)
 {
     tool = toolInside;
 }
Esempio n. 27
0
 /// <summary>
 /// Creates a new move task.
 /// </summary>
 /// <param name="holder">The holder of the task.</param>
 /// <param name="destination">The destination that has to be reached</param>
 public MoveTask(Human holder, PositionInTown destination)
     : base(holder)
 {
     this.destination = destination;
 }
Esempio n. 28
0
        /// <summary>
        /// Performes the bullet releasing in the shoot process
        /// </summary>
        /// <param name="gameTime">Game time</param>
        /// <param name="position">Start position</param>
        /// <param name="azimuth">Flight direction</param>
        /// <param name="visualiseBullet">Whether the bullet should be visualised indicator</param>
        /// <returns>True if the bullet hit something</returns>
        bool PerformShoot(GameTime gameTime, PositionInTown position, float azimuth, bool visualiseBullet)
        {
            const float bulletWidth = 0.02f;
            //const float startHeight = 0.5f;
            const float bulletWidthHalf = bulletWidth / 2;

            bool   solveHeight = (Holder is Player);
            double lookAngle   = Holder.LookAngle;
            //Vector2 quarterPosition = position.PositionInQuarter;
            float       startHeight     = Holder.FirstHeadPosition.Y - bulletWidth;
            Vector2     quarterPosition = position.PositionInQuarter;
            Vector2     left            = quarterPosition.Go(bulletWidthHalf, azimuth - MathHelper.PiOver2);
            Vector2     right           = quarterPosition.Go(bulletWidthHalf, azimuth + MathHelper.PiOver2);
            Quadrangle  bullet          = new Quadrangle(right, left, right.Go(type.Range, azimuth), left.Go(type.Range, azimuth));
            TownQuarter quarter         = position.Quarter;

            List <Quadrangle> colliders = new List <Quadrangle>(quarter.SpaceGrid.GetAllCollisions(bullet));

            colliders.RemoveAll(x => x == Holder);

            //Half-interval search
            Stack <RangeF>            testedParts = new Stack <RangeF>();
            Dictionary <float, float> heights     = new Dictionary <float, float>();

            testedParts.Push(new RangeF(0, type.Range));
            if (solveHeight)
            {
                heights.Add(0, startHeight);
                heights.Add(type.Range, startHeight + type.Range * (float)Math.Tan(lookAngle));
            }

            Quadrangle nearest  = null;
            float      distance = type.Range;

            while (testedParts.Count != 0)
            {
                RangeF bulletRangePart = testedParts.Pop();
                float  h1 = 0f;
                float  h2 = 0f;
                if (solveHeight)
                {
                    h1 = heights[bulletRangePart.Begin];
                    h2 = heights[bulletRangePart.End];
                }
                Quadrangle bulletPart = new Quadrangle(
                    left.Go(bulletRangePart.Begin, azimuth),
                    right.Go(bulletRangePart.Begin, azimuth),
                    left.Go(bulletRangePart.End, azimuth),
                    right.Go(bulletRangePart.End, azimuth));
                List <Quadrangle> newColliders = new List <Quadrangle>(
                    colliders.Where(
                        x =>
                        (solveHeight && x is SpatialObject && (((SpatialObject)x).Size.Y >= h2 || ((SpatialObject)x).Size.Y >= h2) && (0 <= h1 || 0 <= h2) && x.IsInCollisionWith(bulletPart))
                        ||
                        (!solveHeight && x.IsInCollisionWith(bulletPart))
                        )
                    );
                if (newColliders.Count != 0)
                {
                    if (newColliders.Count == 1 || bulletRangePart.Length <= bulletWidthHalf)
                    {
                        nearest  = newColliders[0];
                        distance = bulletRangePart.End;
                        break;
                    }
                    colliders = newColliders;
                    float halfLength = bulletRangePart.Length * 0.5f;
                    float middle     = bulletRangePart.Begin + halfLength;
                    testedParts.Push(new RangeF(middle, bulletRangePart.End));
                    testedParts.Push(new RangeF(bulletRangePart.Begin, middle));
                    if (solveHeight && halfLength != 0f)
                    {
                        heights.Add(middle, startHeight + middle * (float)Math.Tan(lookAngle));
                    }
                }
            }


            if (visualiseBullet)
            {
                quarter.AddBullet(gameTime, new BulletVisualisation(quarter, quarterPosition, azimuth, distance, startHeight, startHeight + distance * (float)Math.Tan(lookAngle)));
            }
            if (nearest != null)
            {
                Debug.Write("Shot", nearest.ToString());
                nearest.BecomeShoot(gameTime, type.Damage, Holder);
                return(true);
            }
            return(false);
        }