Beispiel #1
0
        /// <summary>
        /// Seareches for the available respawn quarter for the given playerDefaultGuns.
        /// </summary>
        /// <param name="quarterOwner">The given player that has to be respawned</param>
        /// <param name="gameTime">Game time</param>
        /// <returns>Quarter where the given player can be respawned</returns>
        TownQuarter FindAndRespawnQuartersFor(ITownQuarterOwner quarterOwner, GameTime gameTime)
        {
            TownQuarter newPosQuarter = null;
            IOrderedEnumerable <TownQuarter> randomizedQuarters = from q in town.Quarters where q.Owner == quarterOwner || q.Owner == EmptyTownQuarterOwner.Instance orderby random.Next() select q;

            foreach (TownQuarter quarter in town.Quarters)
            {
                if (quarter.Owner == quarterOwner)
                {
                    if (newPosQuarter == null)
                    {
                        newPosQuarter = quarter;
                    }
                    else
                    {
                        quarter.SetOwner(EmptyTownQuarterOwner.Instance, gameTime);
                    }
                }
            }
            if (newPosQuarter == null)
            {
                newPosQuarter = randomizedQuarters.First();
            }
            return(newPosQuarter);
        }
Beispiel #2
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--;
            }
        }
Beispiel #3
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();
 }
Beispiel #4
0
        /// <summary>
        /// Updates the kill task logic.  It navigates the holder to the target and waits for him to shoot the target. If the holder has not a usable gun, it leads him to search for a toolbox. It can also lead him to for a healbox if it is needed.
        /// </summary>
        /// <param name="gameTime">Game time</param>
        public override void Update(GameTime gameTime)
        {
            if (Holder.SelectedTool is Gun && ((Gun)Holder.SelectedTool).Type.Range < TownQuarter.SquareWidth)
            {
                Box nearestToolBox = Holder.Position.Quarter.GetNearestBox(Holder.Position, true);
                if (nearestToolBox != null)
                {
                    Holder.AddUrgentTask(new MoveTask(Holder, nearestToolBox.Pivot));
                }
            }
            int neededHealth = target.Health - (Holder.SelectedTool is Gun ? ((Gun)Holder.SelectedTool).Type.Damage : 0);

            if (Holder.Health < neededHealth)
            {
                Box nearestHealBox = Holder.Position.Quarter.GetNearestBox(Holder.Position, false);
                if (nearestHealBox != null)
                {
                    Holder.AddUrgentTask(new MoveTask(Holder, nearestHealBox.Pivot));
                }
            }

            if (gameTime.TotalGameTime - lastUpdatedWaypoints > RecomputeWaypointsTimeout && (lastTargetQuarter != target.Position.Quarter || target.Position.Quarter == Holder.Position.Quarter))
            {
                lastTargetQuarter  = target.Position.Quarter;
                goStraightToTarget = false;
                if (Holder.Position.Quarter == target.Position.Quarter)
                {
                    Vector2    wayVect   = (target.Position.PositionInQuarter - Holder.Position.PositionInQuarter);
                    float      direction = (wayVect.GetAngle() + 1 * MathHelper.PiOver2) % MathHelper.TwoPi;
                    Quadrangle viewLine  = Quadrangle.CreateBand(Holder.Pivot.PositionInQuarter, direction, Holder.Size.X, wayVect.Length());
                    goStraightToTarget = !Grid.IsInCollision(viewLine, c => !(c is Human));
                }
                if (!goStraightToTarget)
                {
                    RecomputeWaypoints(Holder.Position, target.Position);
                }
                lastUpdatedWaypoints = gameTime.TotalGameTime;
            }

            if (goStraightToTarget)
            {
                if (Holder.Position.MinimalDistanceTo(target.Position) > TownQuarter.SquareWidth)
                {
                    Holder.GoThisWay(target.Position, (float)gameTime.ElapsedGameTime.TotalSeconds);
                }
                else
                {
                    Holder.TurnThisWay(target.Position, (float)gameTime.ElapsedGameTime.TotalSeconds);
                }
            }
            else
            {
                base.Update(gameTime);
            }
        }
Beispiel #5
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);
        }
Beispiel #6
0
 /// <summary>
 /// Creates a new plate.
 /// </summary>
 /// <param name="homeQuarter">Town quarter where is it located</param>
 /// <param name="upperLeft">Upper left corner</param>
 /// <param name="upperRight">Upper right corner</param>
 /// <param name="lowerLeft">Lower left corner</param>
 /// <param name="lowerRight">Lower right corner</param>
 /// <param name="front">Front side texture</param>
 /// <param name="back">Back side texture</param>
 /// <param name="enableDefaultLightning">Determines if the default lightning is used</param>
 public Plate(TownQuarter homeQuarter, Vector3 upperLeft, Vector3 upperRight, Vector3 lowerLeft, Vector3 lowerRight, Texture2D front, Texture2D back, bool enableDefaultLightning)
     : base(upperLeft.XZToVector2(), upperRight.XZToVector2(), lowerLeft.XZToVector2(), lowerRight.XZToVector2())
 {
     quarter        = homeQuarter;
     ul             = upperLeft;
     ur             = upperRight;
     ll             = lowerLeft;
     lr             = lowerRight;
     this.back      = back;
     this.front     = front;
     graphicsDevice = front.GraphicsDevice;
     frontVertices  = new VertexPositionNormalTexture[4];
     backVertices   = new VertexPositionNormalTexture[4];
     indexes        = new short[6];
     BuildEffects(enableDefaultLightning);
 }
Beispiel #7
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);
        }
Beispiel #8
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            if (running)
            {
                base.Update(gameTime);
                Debug.Write("UPS", 1d / gameTime.ElapsedGameTime.TotalSeconds);

                // Allows the game to exit
                if (Keyboard.GetState().IsKeyDown(Keys.Escape))
                {
                    this.Restart();
                    return;
                }
                bool opponentInTheSameQuarter = opponent.Position.Quarter == town.CurrentQuarter;
                if (!opponentInTheSameQuarter)
                {
                    opponent.Position.Quarter.Update(gameTime, true);
                }
                if (town.SecondaryDrawnQuarter != null && town.SecondaryDrawnQuarter != opponent.Position.Quarter && town.SecondaryDrawnQuarter != player.Position.Quarter && !gameTime.IsRunningSlowly)
                {
                    town.SecondaryDrawnQuarter.Update(gameTime, false);
                }
                opponent.Update(gameTime, !opponentInTheSameQuarter);
                player.Update(gameTime);

                ITownQuarterOwner owner = town.Quarters[0].Owner;

                if ((owner == player || owner == opponent) && town.Quarters.All(q => q.Owner == owner))
                {
                    System.Drawing.Bitmap townMap = town.CreateTownMapImage();
                    PrepareEnd();
                    bool playAgain;
                    using (GameOver gameOver = new GameOver(owner == player, townMap))
                    {
                        System.Windows.Forms.DialogResult result = gameOver.ShowDialog();
                        playAgain = result != System.Windows.Forms.DialogResult.Cancel;
                    }
                    townMap.Dispose();
                    if (playAgain)
                    {
                        ShowMainMenuDialog(false);
                        PrepareStart();
                    }
                    else
                    {
                        Exit();
                    }
                    return;
                }

                if (player.Health <= 0)
                {
                    TownQuarter newQuarter = FindAndRespawnQuartersFor(player, gameTime);
                    player.RespawnInto(newQuarter);
                    drawer.ShowMessage(gameTime, String.Format("You were killed! You are now in {0}.", newQuarter.Name));
                    town.CurrentQuarter = newQuarter;
                    drawer.ShowFullscreenEffect(gameTime, contentRepository.RespawnFullscreenEffect, Player.RespawnFullscreenEffectDuration);
                }
                if (opponent.Health <= 0)
                {
                    TownQuarter newQuarter = FindAndRespawnQuartersFor(opponent, gameTime);
                    opponent.RespawnInto(newQuarter);
                    opponent.ClearTasks();
                    drawer.ShowMessage(gameTime, String.Format("Congratulations, your opponent was killed. He respawned in {0}.", newQuarter.Name));
                }
            }
        }
Beispiel #9
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();
                }
            }
        }
Beispiel #10
0
 /// <summary>
 /// Creates a new spatial object.
 /// </summary>
 /// <param name="model">Model</param>
 /// <param name="quarter">Town quarter</param>
 /// <param name="positionInQuarter">Position inside the town quarter</param>
 /// <param name="azimuth">Azimuth</param>
 /// <param name="worldTransform">World transform matrix</param>
 public SpatialObject(Model model, TownQuarter quarter, Vector3 positionInQuarter, double azimuth, Matrix worldTransform)
     : base(new PositionInTown(quarter, positionInQuarter.XZToVector2()), azimuth, (model == null? Vector2.Zero : model.GetSize(worldTransform).XZToVector2()))
 {
     Load(model, new PositionInTown(quarter, positionInQuarter.XZToVector2()), positionInQuarter.Y, azimuth, worldTransform);
 }
Beispiel #11
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);
        }
Beispiel #12
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);
                    }
                }
            }
        }