//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;
    }
Ejemplo n.º 2
0
 public void addPassRequirement(TerrainPassRequirement req)
 {
     _passRequirements.Add(req);
 }