/*
* 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
}
}