コード例 #1
0
        /// <summary>
        /// Pathfind towards a given player
        /// </summary>
        /// <param name="player">The player to target with Pathfinding</param>
        public override void GoTo(HashSet <GameObject> changedObjects, Player player)
        {
            TileField tf = GameWorld.Find("TileField") as TileField;


            if (player.Tile.SeenBy.ContainsKey(this))
            {
                bool ableToHit = AttackEvent.AbleToHit(this, player.Tile, this.Reach);

                Special_AbleToHit(player);

                if (special_ableToHit && actionpoints_used >= actionpoints_cooldown)
                {
                    Special_Attack(player, mod);

                    actionpoints_used = 0;
                    actionPoints      = 0;
                    changedObjects.Add(player);
                }
                else if (ableToHit)
                {
                    Attack(player);

                    int cost = BaseActionCost;
                    if ((EquipmentSlots.Find("bodySlot") as ItemSlot).SlotItem != null)
                    {
                        cost = (int)(cost * ((EquipmentSlots.Find("bodySlot") as ItemSlot).SlotItem as BodyEquipment).WalkCostMod);
                    }
                    actionPoints -= cost;
                    changedObjects.Add(player);
                }
                else
                {
                    PathFinder  pf   = new PathFinder(tf);
                    List <Tile> path = pf.ShortestPath(Tile, player.Tile);
                    // TODO?:(assuming there are tiles that cannot be walked over but can be fired over)
                    // check if there is a path to a spot that can hit the player (move closer water to fire over it)
                    if (path.Count > 0)
                    {
                        changedObjects.Add(this);
                        changedObjects.Add(Tile);
                        changedObjects.Add(path[0]);

                        MoveTo(path[0]);
                        actionPoints -= BaseActionCost;
                    }
                    else
                    {
                        Idle();
                    }
                }
            }
            else
            {
                Idle();
            }
        }
コード例 #2
0
        public PathFinder(TileField tf)
        {
            addedCosts = new List <Func <Node, Node, int> >();
            nodeTable  = new Dictionary <Tile, Node>();
            tileField  = tf;

            //Add diagonal cost.
            AddCost((current, adjacent) =>
            {
                Point diff = adjacent.tile.TilePosition - current.tile.TilePosition;
                return(diff.X == 0 || diff.Y == 0 ? 0 : 41);
            });
        }
コード例 #3
0
 public override void DrawDebug(GameTime gameTime, SpriteBatch spriteBatch, Camera camera)
 {
     if (debugTags.ContainsKey("ExitConnectionPoint"))
     {
         string[]  coord = debugTags["ExitConnectionPoint"].Split(',');
         TileField tf    = parent as TileField;
         Tile      t     = tf.Get(int.Parse(coord[0]), int.Parse(coord[1])) as Tile;
         if (t != null)
         {
             Line.DrawLine(spriteBatch, camera.CalculateScreenPosition(this), camera.CalculateScreenPosition(t), Color.Red);
         }
     }
     base.DrawDebug(gameTime, spriteBatch, camera);
 }
コード例 #4
0
        private Tile LoadWallTile(int x, int y, string assetName = "test-wall-sprite2@10x5", string id = "")
        {
            TileField tf        = Find("TileField") as TileField;
            Tile      aboveTile = tf[x, y - 1] as Tile;

            Tile newTile;

            if (aboveTile != null && aboveTile.TileType == TileType.Floor)
            {
                newTile = new Tile("*" + assetName, TileType.Wall, 0, id);
            }
            else
            {
                newTile = new Tile(assetName, TileType.Wall, 0, id);
            }
            return(newTile);
        }
コード例 #5
0
        /// <summary>
        /// Process which tiles the living object can and cannot see using ShadowCast
        /// </summary>
        public void ComputeVisibility()
        {
            TileField tf  = GameWorld.Find("TileField") as TileField;
            Point     pos = Tile.TilePosition;

            if (tf.Find(obj => obj is Tile && (obj as Tile).SeenBy.ContainsKey(this)) != null)
            {
                foreach (Tile t in tf.Objects)
                {
                    t.SeenBy.Remove(this);
                }
            }

            ShadowCast.ComputeVisibility(tf, pos.X, pos.Y, this);
            //skill idea: peek corner, allows the player to move its FOV position 1 tile in N,S,E or W direction,
            //allowing the player to peek around a corner into a halway whithout actualy stepping out
        }
コード例 #6
0
        public void LoadTiles(string path)
        {
            List <string> textLines  = new List <string>();
            StreamReader  fileReader = new StreamReader(path);
            string        line       = fileReader.ReadLine();
            int           width      = line.Length;

            while (line != null)
            {
                textLines.Add(line);
                line = fileReader.ReadLine();
            }
            //timelimit = int.Parse(textLines[textLines.Count - 1]);
            TileField tf = new TileField(textLines.Count, width, 0, "TileField");

            Add(tf);

            for (int y = 0; y < textLines.Count; ++y)
            {
                for (int x = 0; x < width; ++x)
                {
                    Tile t = LoadTile(textLines[y][x], x, y);
                    tf.Add(t, x, y);
                }
            }
            //Putting the item one layer above the inventory box
            int inventoryLayer = layer + 1;
            int itemLayer      = layer + 2;

            #region ENEMY CODE (test)
            for (int i = 0; i < 2; i++)
            {
                Enemy testEnemy = new Enemy(0, Index, EnemyType.random, "Enemy" + i);
                testEnemy.SetStats();
                //First find all passable tiles then select one at random.
                List <GameObject> tileCandidates = tf.FindAll(obj => obj is Tile && (obj as Tile).Passable);
                Tile startTile = tileCandidates[GameEnvironment.Random.Next(tileCandidates.Count)] as Tile;
                startTile.PutOnTile(testEnemy);
            }
            #endregion
            tf.InitSpriteSheetIndexation();
        }
コード例 #7
0
        /// <summary>
        /// Pathfind towards a given player
        /// </summary>
        /// <param name="player">The player to target with Pathfinding</param>
        public virtual void GoTo(HashSet <GameObject> changedObjects, Player player)
        {
            TileField  tf = GameWorld.Find("TileField") as TileField;
            PathFinder pf = new PathFinder(tf);

            List <Tile> path = pf.ShortestPath(Tile, player.Tile);

            // TODO?:(assuming there are tiles that cannot be walked over but can be fired over)
            // check if there is a path to a spot that can hit the player (move closer water to fire over it)
            if (path.Count > 0)
            {
                changedObjects.Add(this);
                changedObjects.Add(Tile.OnTile);
                changedObjects.Add(path[0].OnTile);

                MoveTo(path[0]);
                actionPoints -= BaseActionCost;
            }
            else
            { //No path possible.
                Idle();
            }
        }
コード例 #8
0
        private TileField GenerateTiles(List <Room> rooms, List <Tuple <Room, Room> > hallwayPairs)
        {
            //Get the highest coordinates so we know the size of the TileField.
            int highestX = int.MinValue;
            int highestY = int.MinValue;

            foreach (Room r in rooms)
            {
                if (r.BoundingBox.Right > highestX)
                {
                    highestX = r.BoundingBox.Right;
                }
                if (r.BoundingBox.Bottom > highestY)
                {
                    highestY = r.BoundingBox.Bottom;
                }
            }

            //Make the tilefield and fill with default Tiles.
            TileField tf = new TileField(highestY + 1, highestX + 1, 0, "TileField");

            Add(tf);
            for (int x = 0; x < tf.Columns; x++)
            {
                for (int y = 0; y < tf.Rows; y++)
                {
                    tf.Add(new Tile(), x, y);
                }
            }

            List <Tuple <XNAPoint, XNAPoint> > hallways = new List <Tuple <XNAPoint, XNAPoint> >();

            //Find good points for the hallways connect to.
            foreach (Tuple <Room, Room> pair in hallwayPairs)
            {
                Vector2 center1 = pair.Item1.BoundingBox.Center.ToVector2();
                Vector2 center2 = pair.Item2.BoundingBox.Center.ToVector2();

                //Vector from center of room1 to center of room2 and vice versa
                Vector2 v1 = center2 - center1;
                Vector2 v2 = center1 - center2;

                Collision.Side s1 = CalculateExitSide(pair.Item1, v1);
                Collision.Side s2 = CalculateExitSide(pair.Item2, v2);

                v1.Normalize();
                v2.Normalize();

                XNAPoint cRelExit1 = CalculateExit(v1, center1, s1, pair.Item1.BoundingBox.GetMiddleOfSide(s1)).ToPoint();
                XNAPoint cRelExit2 = CalculateExit(v2, center2, s2, pair.Item2.BoundingBox.GetMiddleOfSide(s2)).ToPoint();
                XNAPoint absExit1  = cRelExit1 + pair.Item1.BoundingBox.Center;
                XNAPoint absExit2  = cRelExit2 + pair.Item2.BoundingBox.Center;

                hallways.Add(new Tuple <XNAPoint, XNAPoint>(absExit1, absExit2));
            }

            //for each room, add floor tiles to the tilefield.
            for (int i = 0; i < rooms.Count; i++)
            {
                Room r      = rooms[i];
                int  width  = r.BoundingBox.Width;
                int  height = r.BoundingBox.Height;

                XNAPoint relCenter = r.BoundingBox.Center - r.BoundingBox.Location;

                for (int x = 0; x < width; x++)
                {
                    for (int y = 0; y < height; y++)
                    {
                        Tile tile = LoadFloorTile();
                        if (x == relCenter.X && y == relCenter.Y)
                        {
                            tile.AddDebugTag("Room", "" + i);
                        }
                        tf.Add(tile, x + r.BoundingBox.X, y + r.BoundingBox.Y);
                    }
                }
            }

            //Generate hallways
            foreach (Tuple <XNAPoint, XNAPoint> pair in hallways)
            {
                //Use the pathfinder to get a path from exitpoint to exitpoint.
                PathFinder pf = new PathFinder(tf);
                pf.EnableStraightLines();
                List <Tile> path = pf.ShortestPath(tf[pair.Item1.X, pair.Item1.Y] as Tile, tf[pair.Item2.X, pair.Item2.Y] as Tile, tile => true);

                Tile t = tf[pair.Item1.X, pair.Item1.Y] as Tile;
                t.AddDebugTag("ExitConnectionPoint", pair.Item2.X + "," + pair.Item2.Y);
                path.Add(t);

                //Add a floor tile for every tile in the path.
                foreach (Tile tile in path)
                {
                    Tile newTile = LoadFloorTile();
                    newTile.AddDebugTags(tile.DebugTags);
                    tf.Add(newTile, tile.TilePosition.X, tile.TilePosition.Y);
                }
            }

            //Exchange all remaining background tiles for Wall tiles.
            for (int x = 0; x < tf.Columns; x++)
            {
                for (int y = 0; y < tf.Rows; y++)
                {
                    Tile currentTile = tf[x, y] as Tile;
                    Tile aboveTile   = tf[x, y - 1] as Tile;
                    if (currentTile != null && aboveTile != null && currentTile.TileType == TileType.Background)
                    {
                        Tile newTile = LoadWallTile(x, y);
                        newTile.AddDebugTags(currentTile.DebugTags);
                        tf.Add(newTile, x, y);
                    }
                }
            }

            //Add starttiles
            for (int p = 0; p < 4; p++)
            {
                tf.Add(LoadStartTile(p + 1), rooms[0].Location.ToRoundedPoint().X + 1 + p % 2, rooms[0].Location.ToRoundedPoint().Y + 1 + p / 2);
            }

            //Generate EndTile
            List <Room> forEnd    = new List <Room>();
            List <Room> usedRooms = new List <Room>();

            for (int a = 0; a < hallwayPairs.Count; a++)
            {
                if (!forEnd.Contains(hallwayPairs[a].Item1))
                {
                    forEnd.Add(hallwayPairs[a].Item1);
                    usedRooms.Add(hallwayPairs[a].Item1);
                }
                if (!forEnd.Contains(hallwayPairs[a].Item2))
                {
                    forEnd.Add(hallwayPairs[a].Item2);
                    usedRooms.Add(hallwayPairs[a].Item2);
                }
            }

            for (int a = 0; a < hallwayPairs.Count; a++)
            {
                if (hallwayPairs[a].Item1 == rooms[0] || hallwayPairs[a].Item2 == rooms[0])
                {
                    if (forEnd.Contains(hallwayPairs[a].Item1))
                    {
                        forEnd.Remove(hallwayPairs[a].Item1);
                    }
                    if (forEnd.Contains(hallwayPairs[a].Item2))
                    {
                        forEnd.Remove(hallwayPairs[a].Item2);
                    }
                }
            }
            tf.Add(LoadEndTile(), forEnd[0].Location.ToRoundedPoint().X + 1, forEnd[0].Location.ToRoundedPoint().Y + 1);
            tf.Add(LoadChestTile(levelIndex), forEnd[0].Location.ToRoundedPoint().X + forEnd[0].Size.X - 2, forEnd[0].Location.ToRoundedPoint().Y + 1);

            //Door spawn
            for (int i = 0; i < usedRooms.Count; i++)
            {
                for (int x = rooms[i].Location.ToRoundedPoint().X; x < rooms[i].Location.ToRoundedPoint().X + rooms[i].Size.X; x++)
                {
                    if (!tf.IsWall(x, rooms[i].Location.ToRoundedPoint().Y - 1))
                    {
                        if (tf.IsWall(x + 1, rooms[i].Location.ToRoundedPoint().Y - 1) && tf.IsWall(x - 1, rooms[i].Location.ToRoundedPoint().Y - 1))
                        {
                            tf.Add(LoadDoorTile(), x, rooms[i].Location.ToRoundedPoint().Y - 1);
                        }
                    }
                    if (!tf.IsWall(x, rooms[i].Location.ToRoundedPoint().Y + rooms[i].Size.Y))
                    {
                        if (tf.IsWall(x + 1, rooms[i].Location.ToRoundedPoint().Y + rooms[i].Size.Y) && tf.IsWall(x - 1, rooms[i].Location.ToRoundedPoint().Y + rooms[i].Size.Y))
                        {
                            tf.Add(LoadDoorTile(), x, rooms[i].Location.ToRoundedPoint().Y + rooms[i].Size.Y);
                        }
                    }
                }
            }

            //Test chest spawn
            int chestAmount = Random.Next(1, 2);

            usedRooms.Remove(rooms[0]);
            for (int i = 0; i < chestAmount; i++)
            {
                int chestRoom = Random.Next(usedRooms.Count);
                usedRooms.Remove(rooms[chestRoom]);
                int xChest = rooms[chestRoom].Location.ToRoundedPoint().X + rooms[chestRoom].Size.X / 2;
                int yChest = rooms[chestRoom].Location.ToRoundedPoint().Y + rooms[chestRoom].Size.Y / 2;
                tf.Add(LoadChestTile(levelIndex), xChest, yChest);
            }
            //End test

            //Test enemy spawn
            int numberOfEnemys = 8;

            for (int n = 0; n < numberOfEnemys; n++)
            {
                Enemy             enemy          = new Enemy(0, Index, EnemyType.random, "Enemy");
                List <GameObject> spawnLocations = tf.FindAll(obj => obj is Tile && (obj as Tile).Passable && !(obj as Tile).Blocked);
                Tile spawnLocation = spawnLocations[GameEnvironment.Random.Next(spawnLocations.Count)] as Tile;
                spawnLocation.PutOnTile(enemy);
            }
            //End test

            //Must be last statement, executed after the Tilefield is done.
            tf.InitSpriteSheetIndexation();
            return(tf);
        }