private GeneratedLevelSet GetLevelSetObject(LevelSet set, int index)
    {
        LevelType         type     = LevelType.Normal;
        GeneratedLevelSet levelSet = areaObject.normalLevel.levelSetObject.GetRandom();

        if (encounters.Contains(index))
        {
            if (hasSpawnedCharacter == false && System.Array.IndexOf(encounters, index) == encounters.Length - 1 && Game.Instance.PlayerParty.characters.Count < 4)
            {
                type = LevelType.Character;
            }
            else
            {
                type = Probability.Range(levelTypeRanges);
            }

            levelSet = areaObject.encounters.Single(x => x.type == type).levelSetObject.GetRandom();

            CreateLevelTypeRanges();
        }

        if (type == LevelType.Character)
        {
            hasSpawnedCharacter = true;
        }

        set.Type = type;
        return(levelSet);
    }
    private void Generate(int index = 0)
    {
        if (generatedSets > maxSets && index == 0)
        {
            return;
        }

        GeneratedLevelSet setObject = null;
        GameObject        go        = Instantiate(emptyPrefab, transform);
        LevelSet          set       = go.GetComponent <LevelSet>();

        if (generatedSets == maxSets && index == 0)
        {
            setObject = areaObject.exit.levelSetObject[0];
            set.Type  = LevelType.Exit;
        }

        if (index == 0)
        {
            generatedSets++;
        }

        set.Index = index == 0 ? generatedSets : index;
        if (setObject == null)
        {
            setObject = GetLevelSetObject(set, index == 0 ? generatedSets : index);
        }

        GameObject ground = Instantiate(setObject.groundPrefab, set.transform);

        List <LevelLayer> layers = new List <LevelLayer>();

        layers.AddRange(setObject.foreground);
        layers.AddRange(setObject.antiVoid);
        layers.AddRange(setObject.background);
        layers.AddRange(setObject.guaranteedSpawns);

        foreach (LevelLayer layer in layers)
        {
            Transform parent = null;

            if (setObject.foreground.Any(x => x == layer))
            {
                parent = set.foreground.transform;
            }
            else if (setObject.antiVoid.Any(x => x == layer))
            {
                parent = set.antiVoid.transform;
            }
            else if (setObject.background.Any(x => x == layer))
            {
                parent = set.background.transform;
            }
            else if (setObject.guaranteedSpawns.Any(x => x == layer))
            {
                parent = set.encounterObjects.transform;
            }

            for (int i = layer.amountNegative * -1; i <= layer.amountPositive; i++)
            {
                GameObject obj = Instantiate(layer.prefabs.GetRandom(), parent);
                obj.transform.localPosition = new Vector3(layer.origin.x + (layer.offset * i), layer.origin.y, layer.origin.z);
            }

            if (layer.scaleWithPositive && sets.Count > 0)
            {
                parent.Translate(new Vector3(layer.amountPositive * setObject.groundOffset * sets.Count, 0, 0), Space.Self);
            }
        }

        if (index == 0)
        {
            sets.Add(set);
        }
        else
        {
            LevelSet oldSet = sets.Single(x => x.Index == index);
            sets[sets.IndexOf(oldSet)] = set;
        }

        int setIndex = sets.IndexOf(set);

        if (setIndex != 0)
        {
            Transform previousSet = sets[setIndex - 1].transform;
            set.transform.localPosition = new Vector3(previousSet.localPosition.x + setObject.groundOffset, previousSet.localPosition.y, previousSet.localPosition.z);
        }
    }