//Returns a success code (0) or an error code (>= 1) private int LoadLevel() { if(_map != null) //Add any uninitialization here, or maybe even repurposing. { GameObject tempMap = _map.gameObject; //Utilizing a temp to make sure the memory clears properly. If it ever becomes an issue make this better. _map = null; _objMap = null; GameObject.Destroy(tempMap); } _objMap = new GameObject("Game Map"); _map = _objMap.AddComponent<componentGameMap>(); if(_notifier != null) //Make a new notifier for each game. { _notifier = null; } _notifier = new Notifier(); //Load these from the file once it's created TextAsset txtAsset = (TextAsset)Resources.Load("Maps/testMap"); //Eventually add a validator to the XML to determine whether or not to pass or fail before starting. XDocument xmlMap = XDocument.Parse(txtAsset.text); Debug.Log("Map Name : " + (string)xmlMap.Root.Attribute("name")); XElement xmlPalette = xmlMap.Root.Element("Palette"); Dictionary<string, TypeTerrain> terrains = new Dictionary<string, TypeTerrain>(); IEnumerable<XElement> xmlTerrainList = xmlPalette.Elements("Terrain"); foreach (XElement xmlTerrain in xmlTerrainList) { string terrainName = (string)xmlTerrain.Attribute("name"); TypeTerrain terrain = new TypeTerrain(terrainName); IEnumerable<XElement> xmlTerrainRequirementList = xmlTerrain.Elements("Requirement"); //Terrain Pass Requirements foreach (XElement xmlTerrainRequirement in xmlTerrainRequirementList) { TerrainPassRequirement terrainPassRequirement = new TerrainPassRequirement(); //Terrain Individual Pass Requirement IEnumerable<XElement> xmlTerrainPassRequirements = xmlTerrainRequirement.Elements("Type"); foreach (XElement xmlTerrainPassRequirement in xmlTerrainPassRequirements) { terrainPassRequirement.addRequirement((string)xmlTerrainPassRequirement.Attribute("name"), (bool)xmlTerrainPassRequirement.Attribute("required")); } terrain.addPassRequirement(terrainPassRequirement); } terrains.Add(terrainName, terrain); } Dictionary<string, componentTile> tiles = new Dictionary<string, componentTile>(); //ShortName is the key tiles.Add("0", componentTile.generateObject("EmptyTileTemplate").GetComponent<componentTile>()); IEnumerable<XElement> xmlTileList = xmlPalette.Elements("Tile"); foreach (XElement xmlTile in xmlTileList) { //Attributes string tileName = (string)xmlTile.Attribute("name"); string tileShortName = (string)xmlTile.Attribute("shortName"); string tileTerrainTypeName = (string)xmlTile.Attribute("terrain"); TypeTerrain tileTerrainType = (tileTerrainTypeName == null)?(null):(terrains[tileTerrainTypeName]); string tileParentShortName = (string)xmlTile.Attribute("parent"); componentMapObject tileParent = (tileParentShortName == null)?(null):((componentTile)tiles[tileParentShortName]); //Elements string tileSpriteName = (string)xmlTile.Element("Sprite"); //TODO: Load Tile Behavior componentTile cTile = componentTile.generateObject(tileName, tileSpriteName, tileTerrainType, tileParent).GetComponent<componentTile>(); //Load Collider XElement xmlCollider = xmlTile.Element("Collider"); if (xmlCollider != null) { string colliderType = (string)xmlCollider.Attribute("type"); switch(colliderType) { case "box": XElement xmlColliderWidth = xmlCollider.Element("Width"); bool scaleRelativeWidth = ((string)(xmlColliderWidth.Attribute("scale"))).ToUpper().Equals("RELATIVE"); float colliderWidthBase = (float)xmlColliderWidth; float colliderWidth = colliderWidthBase; if(scaleRelativeWidth == true) { colliderWidth = cTile.getSpriteRenderer().bounds.size.x * colliderWidthBase; } XElement xmlColliderHeight = xmlCollider.Element("Height"); bool scaleRelativeHeight = ((string)(xmlColliderHeight.Attribute("scale"))).ToUpper().Equals("RELATIVE"); float colliderHeightBase = (float)xmlColliderHeight; float colliderHeight = colliderHeightBase; if(scaleRelativeHeight == true) { colliderHeight = cTile.getSpriteRenderer().bounds.size.y * colliderHeightBase; } bool isTrigger = (bool)xmlCollider.Attribute("isTrigger"); BoxCollider2D boxCollider = cTile.gameObject.AddComponent<BoxCollider2D>(); boxCollider.isTrigger = isTrigger; boxCollider.size = new Vector2(colliderWidth, colliderHeight); break; case "circle": break; default: Debug.Log("Unknown Collider Type : " + colliderType); break; } /* <Collider type="box" isTrigger="false"> <width scale="relative">1</width> <height scale="relative">1</height> </Collider> */ } cTile.gameObject.SetActive(false); tiles.Add(tileShortName, cTile); if (tileShortName == "C") //TEMPORARY { cTile.addNotifyBehavior("CTesting", new NotifyBehaviorMapObject()); } } //Map Layout XElement xmlLayout = xmlMap.Root.Element("Layout"); List<XElement> xmlRowList = xmlLayout.Elements("Row").ToList<XElement>(); //Dynamically grab the width from the length of the first row, and the height from the number of rows. //Dynamically grabbing them helps reduce human error that will happen during map XML creation, but adds a little bit of time to loading. int w = 0; if(xmlRowList.Count > 0) { w = ((string)(xmlRowList[0])).Split(',').Length; } int mapHeight = xmlRowList.Count; int mapWidth = w; _map.init(mapWidth, mapHeight); int cY = 0; foreach(XElement xmlRow in xmlRowList) { string rawRowData = (string)xmlRow; IEnumerable<string> splitRowData = rawRowData.Split(','); int cX = 0; foreach(string cellData in splitRowData) { string cellDataTrimmed = cellData.Trim(); componentTile tileTemplate = tiles["0"]; if (tiles.ContainsKey(cellDataTrimmed)) { tileTemplate = tiles[cellDataTrimmed]; } else { Debug.Log("Error could not find tile of short name : " + cellDataTrimmed + " - Replacing with a default tile \"0\""); } GameObject newTileObject = _map.addTile(cX, cY, tileTemplate, _notifier); cX++; } cY++; } //Load Map Objects (This must occur after the initialization of the tiles.) Dictionary<string, componentMapObject.dBuildObject> mapObjectRegistry = createMapObjectRegistry(); IEnumerable<XElement> xmlObjects = xmlMap.Root.Element("MapObjects").Elements("Object"); foreach (XElement xmlObject in xmlObjects) { string objType = ((string)xmlObject.Attribute("type")).ToUpper(); //auto to upper for case insensitivity if (mapObjectRegistry.ContainsKey(objType)) { GameObject mapObject = mapObjectRegistry[objType](xmlObject); int objX = (xmlObject.Element("x") != null) ? ((int)xmlObject.Element("x")) : (0); int objY = (xmlObject.Element("y") != null) ? ((int)xmlObject.Element("y")) : (0); _map.addMapObject(objX, objY, mapObject); } else { Debug.Log("Unknown Map Object Type : " + objType); } } //Clean Up /* Not sure if I want to do this. Memory overhead seems minimal, and maybe I'll use them in the future. foreach (string tileKey in tiles.Keys) { DestroyObject(tiles[tileKey].gameObject); } */ //Temporary player creating stuff List<componentMapObject> startLocations = _map.getMapObjectsByType(componentStartLocation.OBJECT_TYPE); int idx = Random.Range(0, startLocations.Count); GameObject playerUnitObject = componentUnit.createUnit("Player One Mega Tank Golem!", new SimpleUnitStatTemplate("Useless Name!", 10, 10), 1, "Player 1", "testTile_White_Black"); componentMapObject playerUnitMapObject = playerUnitObject.GetComponent<componentMapObject>(); playerUnitMapObject.addNotifyBehavior("Testing", new NotifyBehaviorMapObject()); playerUnitMapObject.setNotifier(_notifier); componentUnit tempUnitComponent = playerUnitObject.GetComponent<componentUnit>(); _map.addMapObject(_map.getObjectLocation(startLocations[idx]), playerUnitObject); notify("Testing", new Notification()); notify("CTesting", new Notification()); return 0; }
public void addPassRequirement(TerrainPassRequirement req) { _passRequirements.Add(req); }