Exemplo n.º 1
0
    private bool GenerateConnector(Level nextLevel, int3 exitPosition, LiminalBlock exit, List <int3> liminalBlocksGenerated)
    {
        List <int3> blocksToIgnore = new List <int3> (liminalBlocksGenerated);

        foreach (int3 pos in whitelist)
        {
            blocksToIgnore.Add(pos + position);
        }

        List <int3> liminalBlocksToAdd = new List <int3> ();

        for (int i = 0; i < nextLevels.Count; i++)
        {
            exitPosition += directions [exit.dir];
            liminalBlocksToAdd.Add(exitPosition);
        }

        LiminalBlock entrance = nextLevel.GenerateLiminalBlock(nextLevel.startBlocks);

        int3[] entranceBlocks = new int3[LEVEL_BORDER];

        int3 entrancePosition = entrance.pos;

        for (int n = 0; n < LEVEL_BORDER + 1; n++)
        {
            if (n > 0)
            {
                entranceBlocks [n - 1] = entrancePosition;
            }
            entrancePosition += directions[entrance.dir];
        }

        List <int3> tempDirections    = new List <int3> (directions);
        List <int3> directionPriority = new List <int3> ();

        for (int j = 4; j > 0; j--)
        {
            int index = Random.Range(0, j);
            directionPriority.Add(tempDirections[index]);
            tempDirections.RemoveAt(index);
        }

        Dictionary <int3, int3> parents        = new Dictionary <int3, int3> ();
        List <int3>             squaresChecked = new List <int3> ();
        Queue <int3>            squaresToCheck = new Queue <int3> ();

        squaresToCheck.Enqueue(exitPosition);
        parents.Add(exitPosition, exitPosition);

        int3 successBlock = null;

        while (squaresToCheck.Count > 0)
        {
            int3 currentSquare = squaresToCheck.Dequeue();
            squaresChecked.Add(currentSquare);

            List <int3> extraBlocks = Chain(new List <int3> (), parents, currentSquare);

            if (!WorldManager.regionIntersect(currentSquare - entrancePosition, nextLevel.min, nextLevel.max, nextLevel.visualMin, nextLevel.visualMax, LEVEL_BORDER * 2, extraBlocks))
            {
                successBlock = currentSquare;
                break;
            }
            foreach (int3 d in directionPriority)
            {
                int3 newSquare = currentSquare + d;
                if (!squaresChecked.Contains(newSquare) &&
                    !squaresToCheck.Contains(newSquare) &&
                    !WorldManager.blockIntersect(newSquare, blocksToIgnore, LEVEL_BORDER * 2))
                {
                    squaresToCheck.Enqueue(newSquare);
                    parents.Add(newSquare, currentSquare);
                }
            }
        }

        if (successBlock == null)
        {
            return(false);
        }

        nextLevel.position = successBlock - entrancePosition;

        Chain(liminalBlocksToAdd, parents, successBlock);

        WorldManager.levelsSpawned.Add(nextLevel);

        foreach (int3 pos in entranceBlocks)
        {
            liminalBlocksToAdd.Add(pos + nextLevel.position);
        }

        foreach (int3 pos in liminalBlocksToAdd)
        {
            AddLiminalBlock(pos);
            liminalBlocksGenerated.Add(pos);
        }
        return(true);
    }
Exemplo n.º 2
0
    public void GenerateConnectors()
    {
        if (nextLevels.Count == 0)
        {
            return;
        }

        List <int3> liminalBlocksGenerated = new List <int3>();

        List <Level> toRemove = new List <Level> ();

        for (int i = 0; i < nextLevels.Count; i++)
        {
            Level nextLevel = nextLevels [i];

            bool success = false;
            for (int n = 0; n < 6; n++)
            {
                LiminalBlock exit         = GenerateLiminalBlock(endBlocks);
                int3         exitPosition = exit.pos + position;

                if (GenerateConnector(nextLevel, exitPosition, exit, liminalBlocksGenerated))
                {
                    success = true;
                    break;
                }
            }

            if (!success)
            {
                toRemove.Add(nextLevel);
            }
        }

        foreach (Level l in toRemove)
        {
            nextLevels.Remove(l);
            WorldManager.extraLevels.Enqueue(l);
            WorldManager.shortcuts.Add(l, this);
        }

        if (nextLevels.Count == 0)
        {
            return;
        }

        List <int3> liminalWhitelist = new List <int3> (liminalBlocksGenerated);

        foreach (int3 b in whitelist)
        {
            liminalWhitelist.Add(b + position);
            //GameObject.Instantiate (WorldManager.blockTypes [2].prefab, (b + position).ToVector(), Quaternion.identity);
        }

        foreach (Level l in nextLevels)
        {
            foreach (int3 b in l.whitelist)
            {
                liminalWhitelist.Add(b + l.position);
                //GameObject.Instantiate (WorldManager.blockTypes [2].prefab, (b + l.position).ToVector(), Quaternion.identity);
            }
        }

        int extraBlockCount = 100;        //liminalBlocksGenerated.Count * 2;

        List <Level> allLevels = new List <Level> (nextLevels);

        allLevels.Add(this);

        for (int n = 0; n < extraBlockCount; n++)
        {
            int3 pos = liminalBlocksGenerated [Random.Range(0, liminalBlocksGenerated.Count)];
            pos += directions [Random.Range(0, 4)];
            if (!WorldManager.blockIntersect(pos, liminalWhitelist, LEVEL_BORDER * 2, allLevels) && !liminalBlocksGenerated.Contains(pos))
            {
                AddLiminalBlock(pos);
                liminalBlocksGenerated.Add(pos);
                liminalWhitelist.Add(pos);
            }
        }

        for (int n = 0; n < LEVEL_BORDER; n++)
        {
            int len = liminalBlocksGenerated.Count;
            for (int i = 0; i < len; i++)
            {
                int3 b = liminalBlocksGenerated [i];
                foreach (int3 d in directions)
                {
                    if (!WorldManager.liminalBlocks.Contains(b + d))
                    {
                        WorldManager.liminalBlocks.Add(b + d);
                        liminalBlocksGenerated.Add(b + d);
                    }
                }
            }
        }
    }