List<Weapon> weapons; // a list to hold all of the weapons for the level #endregion Fields #region Constructors // constructor public Level(string mapFile) { // initializes things this.mapFile = mapFile; basicEnemies = new List<Enemy>(); walls = new List<Wall>(); weapons = new List<Weapon>(); coins = new List<Coin>(); doors = new List<Door>(); keys = new List<Key>(); disguises = new List<Disguise>(); floorSwitchers = new List<FloorSwitcher>(); font = ScreenManager.SharedManager.Content.Load<SpriteFont>("Arial"); graphics = ScreenManager.SharedManager.gDevice; spriteBatch = ScreenManager.SharedManager.sBatch; levelMap = new Map(mapFile, new int[11] { 1, 1, 1, 1, 1, int.MaxValue, int.MaxValue, int.MaxValue, int.MaxValue, 0, 0 }); roomGraph = new RoomGraph(); foreach (var groupname in levelMap.ObjectGroups.Keys) // goes through each layer in the map file { int currentFloor = int.Parse(groupname[5].ToString()) - 1; // gets the floor number of the map layer. if (groupname.Substring(6, 8) == "Entities") // the layer contains GameObjects { foreach (var entity in levelMap.ObjectGroups[groupname]) // goes through each entity and creates a GameObject if possible. { if (entity.Type == "Enemy") // adds an enemy to the basicEnemies list. { string sDir = entity.Properties.Find(x => x.Item1 == "startDirection").Item2; int dir = (sDir != null) ? int.Parse(sDir) : 3; basicEnemies.Add(EntityGenerator.GenerateEnemy(new Vector3(entity.X, entity.Y, currentFloor), entity.Properties, dir)); } else if (entity.Type == "Player") // creates the player. { player = EntityGenerator.GeneratePlayer(new Vector3(entity.X, entity.Y, currentFloor), 5, 400); } else if (entity.Type == "Wall") // adds a wall to the walls list. { walls.Add(EntityGenerator.GenerateWall(new Vector3(entity.X, entity.Y, currentFloor), entity.Width, entity.Height)); } else if (entity.Type == "LockedDoor") // adds a door to the doors list. { doors.Add(EntityGenerator.GenerateDoor(new Vector3(entity.X, entity.Y, currentFloor), doors.Count)); } else if (entity.Type == "Key") // adds a key to the keys list. { keys.Add(EntityGenerator.GenerateKey(new Vector3(entity.X, entity.Y, currentFloor), keys.Count)); } else if (entity.Type == "Weapon") // adds a weapon to the weapons list. { weapons.Add(EntityGenerator.GenerateWeapon(new Vector3(entity.X, entity.Y, currentFloor), int.Parse(entity.Properties.Find(x => x.Item1 == "durability").Item2), entity.Properties.Find(x => x.Item1 == "type").Item2)); } else if (entity.Type == "Coin") // adds a coin to the coins list. { coins.Add(EntityGenerator.GenerateCoin(new Vector3(entity.X, entity.Y, currentFloor), int.Parse(entity.Properties.Find(x => x.Item1 == "value").Item2))); } else if (entity.Type == "Disguise") //adds a disguise to the disguises list. { disguises.Add(EntityGenerator.GenerateDisguise(new Vector3(entity.X, entity.Y, currentFloor), entity.Properties.Find(x => x.Item1 == "disguiseType").Item2)); } else if (entity.Type == "FloorSwitcher") // adds a floor switcher to the floorSwitchers list. { floorSwitchers.Add(new FloorSwitcher(new Rectangle(entity.X, entity.Y, entity.Width, entity.Height), currentFloor, currentFloor + 1, bool.Parse(entity.Properties.Find(x => x.Item1 == "Horizontal").Item2))); } } } if (groupname.Contains("Room")) // layer contains rooms { foreach (var entity in levelMap.ObjectGroups[groupname]) // goes through each room object in the layer. { // creates a new RoomGraphNode and sets up it's connections. RoomGraphNode node = new RoomGraphNode(new Rectangle(entity.X, entity.Y, entity.Width, entity.Height), currentFloor, entity.Name); List<string> connections = new List<string>(); foreach (var t in entity.Properties) { if (t.Item1 != null) connections.Add(t.Item1); if (t.Item2 != null) node.validDisguises.Add(t.Item2); } roomGraph.AddNode(node, connections); } } // how much money the player needs to complete the level is 70% of the total money in the level. player.moneyNeeded = (basicEnemies.Count + coins.Count) * 70; } foreach (Door lockedDoor in doors) // if there aren't enough keys, the extra locked doors are unlocked. { if (keys[lockedDoor.keyAssociation] == null) lockedDoor.locked = false; } // sets up what part of the level to show on screen. windowSpace = new Rectangle((int)(player.location.X + (player.rectangle.Width / 2)) - (graphics.Viewport.Width / 2), (int)(player.location.Y + (player.rectangle.Height / 2)) - (graphics.Viewport.Height / 2), graphics.Viewport.Width, graphics.Viewport.Height); }
/// <summary> /// Gets an adjacent space for a model to move to in order to reach a given target. /// </summary> /// <param name="model">The model for which the next space should be found.</param> /// <param name="target">The model's intended destination.</param> /// <param name="ignoreLayers">Layers that the object ignores when pathfinding.</param> /// <returns>An adjacent space if the model has a path to its target, or the model's /// original space if there is no such path.</returns> public Vector2 Pathfind(WorldObjectModel model, WorldObjectModel destination) { if (!graphValid) { RebuildPathfindingGraph(); } Vector2 current = model.Position.RoundComponents(); Vector2 target = destination.Position.RoundComponents(); if (current == target) { // what are we doing return(target); } // temp var List <RoomGraphNode> nodesToAdd = new List <RoomGraphNode>(4); Dictionary <RoomGraphNode, RoomGraphNode> prevPointers = new Dictionary <RoomGraphNode, RoomGraphNode>(); Queue <RoomGraphNode> queue = new Queue <RoomGraphNode>(); // initial population prevPointers[emptySpaceGraph[current]] = null; queue.Enqueue(emptySpaceGraph[current]); while (queue.Count > 0) { RoomGraphNode currentNode = queue.Dequeue(); // Check if we are at the target if (currentNode.Position == target) { // we found it while (prevPointers[currentNode].Position != current) { currentNode = prevPointers[currentNode]; } return(currentNode.Position); } // TODO: Pathfinding currently ignores size completely. (Is this OK?) // Get current node's neighbors nodesToAdd.Clear(); foreach (var adjacentNode in currentNode.AdjacencyList.GetElementsInRandomOrder()) { if (!prevPointers.ContainsKey(adjacentNode) && (adjacentNode.ModelAtNode == null || currentNode.ModelAtNode == adjacentNode.ModelAtNode || adjacentNode.ModelAtNode == destination)) { nodesToAdd.Add(adjacentNode); } } // If current node is original, we want to favor the direction that the object's currently facing if (currentNode.Position == current) { for (int i = 0; i < nodesToAdd.Count; i++) { if (nodesToAdd[i].Position - current == model.Direction) { nodesToAdd.Swap(0, i); break; } } } // Add valid neighbors to queue foreach (var nextNode in nodesToAdd) { prevPointers[nextNode] = currentNode; queue.Enqueue(nextNode); } } // couldn't find it Debug.Log("Couldn't find a path from " + current + " to " + target); return(current); }