/* * Level.cs * Authors: Karl Orosz, Brain Chesborough * Copyright (c) 2007-2008 Cornell University This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ using System; using System.Collections.Generic; using System.Text; using System.Xml; namespace StarJack { /// /// Contains the parameters for the current level and rooms associated with it /// public class Level { private string mLevelName; public string Name { get { return mLevelName; } } private int mNumRooms; private Room mCurRoom; public Room curRoom { get { return mCurRoom; } set { mCurRoom = value; } } private int mDifficulty; public int difficulty { get { return mDifficulty; } set { mDifficulty = value; } } private int mCurRoomNum; public int curRoomNum { get { return mCurRoomNum; } set { mCurRoomNum = value; } } private List mRooms; public List Rooms { get { return mRooms; } } public Level(string levelName, int numRooms, int levelDiff) { mLevelName = levelName; mNumRooms = numRooms; mCurRoomNum = 0; mDifficulty = levelDiff; mRooms = new List(); } public void AddRoom(Room newRoom) { mRooms.Add(newRoom); /*if (mRooms.Count == (mCurRoomNum + 1)) { mCurRoom = mRooms[mCurRoomNum]; }*/ } //If there are still rooms left increase the room, else return false public Boolean NextRoom() { mCurRoomNum++; if (mCurRoomNum >= mRooms.Count) { return false; } mCurRoom = mRooms[mCurRoomNum]; return true; } public static Level Load(string filePath, DungeonScreen mGameManager) { Level mLevel = null; //load the xml file into the XmlTextReader object XmlTextReader xmlRdr = new System.Xml.XmlTextReader(filePath); //temp varriables string roomName = ""; string tileTexture; List roomTiles = new List(); //list of entities as well for intereactives List roomObjects = new List(); string guardName = ""; Enemy curGuard = new Enemy(); PatrolAI curPatrol = new PatrolAI(); //Parse through XML file, read() goes to the next 'node' in the xml file until there are no nodes left while (xmlRdr.Read()) { //if the node is an element aka if (xmlRdr.NodeType == XmlNodeType.Element) { if (xmlRdr.Name == "level") { string lvlName = filePath.Remove(filePath.LastIndexOf(".")).Substring(filePath.LastIndexOf(@"\") + 1); int numRooms = Convert.ToInt32(xmlRdr.GetAttribute("rooms")); int levelDiff = Convert.ToInt32(xmlRdr.GetAttribute("difficulty")); mLevel = new Level(lvlName, numRooms, levelDiff); } if (xmlRdr.Name == "room") { roomName = xmlRdr.GetAttribute("name"); } if (xmlRdr.Name == "tile") { //Gather tile's collision information string tileCollision = xmlRdr.GetAttribute("collision"); //Gather Tile's texture tileTexture = xmlRdr.ReadElementContentAsString(); //create new tile Tile newTile = new Tile(tileTexture); //set the tile's collision newTile.Collision = Convert.ToBoolean(tileCollision); //add it to list of tiles for this room roomTiles.Add(newTile); } if (xmlRdr.Name == "GameObject") { //create interactive here and add it to the list ObjectTypes objectType = (ObjectTypes)Convert.ToInt32(xmlRdr.GetAttribute("type")); string activeTexture = xmlRdr.GetAttribute("activeTexture"); string inactiveTexture = xmlRdr.GetAttribute("inactiveTexture"); string faceDir = xmlRdr.GetAttribute("facing"); int x = Convert.ToInt32(xmlRdr.GetAttribute("x")); int y = Convert.ToInt32(xmlRdr.GetAttribute("y")); string objCollision = xmlRdr.GetAttribute("collision"); bool tileAttachment = Convert.ToBoolean(xmlRdr.GetAttribute("tileAttachment")); if (objectType == ObjectTypes.StartPosition)//start pos { GameObject startObj = new GameObject("Start", true); startObj.Position = new int[] { x, y }; startObj.TextureName = "Start"; startObj.ObjectName = "Start"; roomObjects.Add(startObj); } if (objectType == ObjectTypes.HackableObject) //hackable object { int requiredAttempts = Convert.ToInt32(xmlRdr.GetAttribute("attempts")); bool objEnabled = Convert.ToBoolean(xmlRdr.GetAttribute("enabled")); //string linkColor = xmlRdr.GetAttribute("linkedColor"); string objName = xmlRdr.ReadElementContentAsString(); HackableObject hackObj = new HackableObject(activeTexture, tileAttachment, roomName); #if DEBUG hackObj.Attempts = 1; #else hackObj.Attempts = 3; #endif hackObj.ObjectName = objName; hackObj.Attempts = requiredAttempts; // hackObj.EnabledTextureName = activeTexture; // hackObj.DisabledTextureName = inactiveTexture; hackObj.Group = "Terminal"; //hackObj.LinkedColor = (Color)Enum.Parse(typeof(Color), linkColor, true); //hackObj.Facing = (GameObject.Direction)Enum.Parse(typeof(GameObject.Direction), faceDir, true); hackObj.Position = new int[] { x, y }; hackObj.Enabled = objEnabled; hackObj.Collision = Convert.ToBoolean(objCollision); roomObjects.Add(hackObj); } if (objectType == ObjectTypes.LinkedCamera) //linked Camera { string linkedObj = xmlRdr.GetAttribute("linkedObj"); //bool enableObj = xmlRdr.GetAttribute("enabled"); string textureGroup = xmlRdr.GetAttribute("textureGroup"); string objName = xmlRdr.ReadElementContentAsString(); LinkedCamera cameraObj = new LinkedCamera(activeTexture, tileAttachment, roomName); cameraObj.ObjectName = objName; cameraObj.LinkedName = linkedObj; cameraObj.Group = textureGroup; cameraObj.Facing = (GameObject.Direction)Enum.Parse(typeof(GameObject.Direction), faceDir, true); cameraObj.Position = new int[] { x, y }; cameraObj.Collision = Convert.ToBoolean(objCollision); LOSCheckAI losAI = new LOSCheckAI(cameraObj, mGameManager.Player); cameraObj.AddAI(losAI); roomObjects.Add(cameraObj); } if (objectType == ObjectTypes.LinkedDoor) //linked Door { string linkedObj = xmlRdr.GetAttribute("linkedObj"); string objName = xmlRdr.ReadElementContentAsString(); LinkedDoor doorObj = new LinkedDoor(activeTexture, tileAttachment, roomName); doorObj.ObjectName = objName; doorObj.LinkedName = linkedObj; doorObj.Group = "Door"; // doorObj.EnabledTextureName = activeTexture; // doorObj.DisabledTextureName = inactiveTexture; doorObj.MyAnimation = new Animation(); doorObj.MyAnimation.Group = "Door"; doorObj.MyAnimation.SetAnimation("DoorClose"); doorObj.MyAnimation.Mode = Animation.PlayMode.Once; //doorObj.Facing = (GameObject.Direction)Enum.Parse(typeof(GameObject.Direction), faceDir, true); doorObj.Position = new int[] { x, y }; doorObj.Collision = Convert.ToBoolean(objCollision); roomObjects.Add(doorObj); } if (objectType == ObjectTypes.SallyAnne) //Sally ann { int requiredAttempts = Convert.ToInt32(xmlRdr.GetAttribute("attempts")); bool objEnabled = Convert.ToBoolean(xmlRdr.GetAttribute("enabled")); string objName = xmlRdr.ReadElementContentAsString(); SallyAnneObject sallyObj = new SallyAnneObject(activeTexture, tileAttachment, roomName); #if DEBUG sallyObj.Attempts = 1; #else sallyObj.Attempts = 5; #endif sallyObj.ObjectName = objName; sallyObj.Attempts = requiredAttempts; sallyObj.EnabledTextureName = activeTexture; sallyObj.DisabledTextureName = inactiveTexture; sallyObj.Group = "Console"; // sallyObj.Facing = (GameObject.Direction)Enum.Parse(typeof(GameObject.Direction), faceDir, true); sallyObj.Position = new int[] { x, y }; sallyObj.Collision = Convert.ToBoolean(objCollision); sallyObj.Enabled = objEnabled; roomObjects.Add(sallyObj); } if (objectType == ObjectTypes.Enemy) //Enemies { string textureGroup = xmlRdr.GetAttribute("textureGroup"); guardName = xmlRdr.ReadElementContentAsString(); Enemy enemyObj = new Enemy(activeTexture, tileAttachment); enemyObj.ObjectName = guardName; enemyObj.Group = textureGroup; enemyObj.Facing = (GameObject.Direction)Enum.Parse(typeof(GameObject.Direction), faceDir, true); enemyObj.Position = new int[] { x, y }; enemyObj.Collision = Convert.ToBoolean(objCollision); LOSCheckAI losAI = new LOSCheckAI(enemyObj, mGameManager.Player); enemyObj.AddAI(losAI); curGuard = enemyObj; roomObjects.Add(enemyObj); } if (objectType == ObjectTypes.Teleporter) //end of level teleporter - Linked { string linkedObj = xmlRdr.GetAttribute("linkedObj"); string objName = xmlRdr.ReadElementContentAsString(); LevelEnd endObj = new LevelEnd(objName, tileAttachment, roomName); endObj.ObjectName = objName; endObj.LinkedName = linkedObj; endObj.TextureName = inactiveTexture; endObj.EnabledTextureName = activeTexture; endObj.Group = "LevelEnd"; endObj.Enabled = true; //endObj.DisabledTextureName = inactiveTexture; //endObj.Facing = (GameObject.Direction)Enum.Parse(typeof(GameObject.Direction), faceDir, true); endObj.Position = new int[] { x, y }; endObj.Collision = Convert.ToBoolean(objCollision); roomObjects.Add(endObj); } if (objectType == ObjectTypes.TutorialPrompt) //Tutorial Event Prompt { int eventNum = Convert.ToInt32(xmlRdr.GetAttribute("EventNumber")); string objName = xmlRdr.ReadElementContentAsString(); TutorialPrompt tutPrompt = new TutorialPrompt(objName, true); tutPrompt.EventNum = eventNum; //tutPrompt.TextureName = "LOS"; tutPrompt.Position = new int[] { x, y }; tutPrompt.Collision = Convert.ToBoolean(objCollision); tutPrompt.ObjectName = objName; PromptAI pai = new PromptAI(); pai.Prompt = tutPrompt; tutPrompt.AddAI(pai); roomObjects.Add(tutPrompt); } } if (xmlRdr.Name == "AI") { curPatrol = new PatrolAI(curGuard); } if (xmlRdr.Name == "node") { string faceDir = xmlRdr.GetAttribute("facing"); int x = Convert.ToInt32(xmlRdr.GetAttribute("x")); int y = Convert.ToInt32(xmlRdr.GetAttribute("y")); curPatrol.AddNode(new int[] { x, y }, (GameObject.Direction)Enum.Parse(typeof(GameObject.Direction), faceDir, true)); } } if (xmlRdr.NodeType == XmlNodeType.EndElement) { if (xmlRdr.Name == "room") { //create a new room with the current name and tile list //add it to the current level Room newRoom = new Room(roomTiles); newRoom.Name = roomName; for (int i = 0; i < roomObjects.Count; i++) { GameObject gameObject = roomObjects[i]; gameObject.MyRoom = newRoom; //If the GameObject is a LinkedObject, link it LinkedObject l = gameObject as LinkedObject; if (l != null) foreach (GameObject o2 in roomObjects) if (o2.ObjectName == l.LinkedName) l.Linked = o2 as LinkedObject; if (gameObject.ObjectName == "Start") newRoom.PlayerStartingPos = gameObject.Position; newRoom.AddGameObject(gameObject); } //reset roomObjects list roomObjects.Clear(); mLevel.AddRoom(newRoom); //reset roomTile list roomTiles.Clear(); } if (xmlRdr.Name == "AI") { //pass guard AI here curGuard.AddAI(curPatrol); } if (xmlRdr.Name == "level") { //do whatever you gotta do when your finished making a level } } } return mLevel; } } public enum ObjectTypes { StartPosition = 0, HackableObject = 1, LinkedCamera = 2, LinkedDoor = 3, SallyAnne = 4, Enemy = 5, Teleporter = 6, TutorialPrompt = 7 } }