Ejemplo n.º 1
0
    //returns the large unit at a specified su, creates one if it does not exist(every large unit will exist)
    public TULarge getLarge(SurfaceUnit su)
    {
        //quick hopefully temporary check, see getMid for details
        if (su.u < -halfgtuw || su.u >= halfgtuw || su.v < -halfgtuw || su.v >= halfgtuw)
        {
            return(null);
        }

        TULarge lu = null;

        //if it is in the list, return it
        if (largeTUs.TryGetValue(su, out lu))
        {
            return(lu);
        }


        //if not, build one and return it
        TULarge tu = new TULarge();

        //get this large unit's rng
        tu.rng = RandomHandler.transportRandom(su, TLev.LARGE);

        tu.conPoint = new Vector2((su.u + (float)tu.rng.NextDouble()) * sideLengthLarge,
                                  (su.v + (float)tu.rng.NextDouble()) * sideLengthLarge);
        tu.conUp    = true;
        tu.conRight = true;
        tu.indexI   = su.u;
        tu.indexJ   = su.v;
        largeTUs.Add(su, tu);

        return(tu);
    }
Ejemplo n.º 2
0
    //returns the mid unit at the specified su or null if one does not exist
    public TransportUnit getMid(SurfaceUnit su)
    {
        //quick check to see if this mid is out of range on the side
        //later it will be transformed into a unit of other side in order to connect sides
        if (su.u < -halfmidperglob || su.u >= halfmidperglob || su.v < -halfmidperglob || su.v >= halfmidperglob)
        {
            return(null);
        }

        TransportUnit mu = null;

        //if it is in the mid list, return it
        if (midTUs.TryGetValue(su, out mu))
        {
            return(mu);
        }
        //if it's not in the mid list, check if a large unit will contain it

        //the coordinates of the proposed large unit
        SurfaceUnit lus = getLargeSU(su);
        //retrieve the large unit
        TULarge lu = getLarge(lus);

        //Debug.Log("proposed " + lus);
        //if the lu has already been populated, the mu will never exist, so return null
        if (lu.populated)
        {
            return(null);
        }
        else
        {
            populateLarge(lu, lus);
            //populate it with mid units(later will be moved to a separate function)

            /*	int startu = lus.u*largeTUWidth;
             *      int startv = lus.v*largeTUWidth;
             *      //loop through all mid units in the large unit and create them
             *      for(int i = startu; i<startu+largeTUWidth; i++)
             *      {
             *              for(int j = startv; j<startv+largeTUWidth; j++)
             *              {
             *                      //create a new base unit, set its properties, and add it to the base list
             *                      TransportUnit newTU = new TransportUnit();
             *                      newTU.conUp = true;//Random.value>0.5f;
             *                      newTU.conRight = true;//Random.value>0.5f;
             *                      newTU.indexI = i;
             *                      newTU.indexJ = j;
             *                      newTU.conPoint = new Vector2((i+0.5f)*midTUWidth + Random.value-0.5f,(j+0.5f)*midTUWidth + Random.value-0.5f);
             *                      //newTU.conPoint = new Vector2((i+0.5f)*midTUWidth,(j+0.5f)*midTUWidth);
             *                      //newTU.conPoint = new Vector2((i+Random.value)*midTUWidth,(j+Random.value)*midTUWidth);
             *                      midTUs.Add(new SurfaceUnit(su.side, i, j), newTU);
             *              }
             *      }*/
            lu.populated = true;
            //use recursion to return to the top of the function and return the newly created(or not) mid unit
            return(getMid(su));
        }
    }
Ejemplo n.º 3
0
    //builds a street from the center of a large unit to the edge in the given direction
    private void buildMidCurve(TULarge lu, Vector2 outsideConPoint, Dir dir, TransportUnit powMid, PSide side) //powmid is the mid unit that contains the large's conpoint
    {
        int gix = 0, giy = 0;                                                                                  //goal index x and y of the goal mid unit

        float outSlope = GridMath.findSlope(lu.conPoint, outsideConPoint);                                     //find the average slope from this conPoint to the outsideConPoint

        Debug.DrawLine(UnitConverter.getWP(new SurfacePos(PSide.TOP, lu.conPoint.x, lu.conPoint.y), 10000, sideLength),
                       UnitConverter.getWP(new SurfacePos(PSide.TOP, outsideConPoint.x, outsideConPoint.y), 10000, sideLength), Color.blue, Mathf.Infinity);
        //determine the goal mid unit
        if (dir == Dir.RIGHT)
        {
            //find the index of the goal mid unit
            float goalPosX = (lu.indexI + 1) * sideLengthLarge;               //the x value of the very right side of the large unit in mid units
            float goalPosY = GridMath.findY(goalPosX, lu.conPoint, outSlope); //the y value on the line between teh two conpoints
            GridMath.findMidIndexfromPoint(new Vector2(goalPosX - 0.5f, goalPosY), midTUWidth, out gix, out giy);

            TransportUnit goalMid = buildMid(gix, giy, side);
            goalMid.conRight = true;
            goalMid.RightLev = 1;
            //Debug.DrawLine(UnitConverter.getWP(new SurfacePos(PSide.TOP, lu.conPoint.x, lu.conPoint.y), 10000, 1024),
            //             UnitConverter.getWP(new SurfacePos(PSide.TOP, goalPosX, goalPosY), 10000, 1024), Color.blue, Mathf.Infinity);
        }
        else if (dir == Dir.LEFT)
        {
            //find the index of the goal mid unit
            float goalPosX = (lu.indexI) * sideLengthLarge;                   //the x value of the very right side of the large unit in mid units
            float goalPosY = GridMath.findY(goalPosX, lu.conPoint, outSlope); //the y value on the line between teh two conpoints
            GridMath.findMidIndexfromPoint(new Vector2(goalPosX + 0.5f, goalPosY), midTUWidth, out gix, out giy);
            //buildMid(gix, giy, side).conLeft=true;
        }
        else if (dir == Dir.UP)
        {
            //find the index of the goal mid unit
            float goalPosY = (lu.indexJ + 1) * sideLengthLarge;               //the x value of the very right side of the large unit in mid units
            float goalPosX = GridMath.findX(goalPosY, lu.conPoint, outSlope); //the y value on the line between teh two conpoints
            GridMath.findMidIndexfromPoint(new Vector2(goalPosX, goalPosY - 0.5f), midTUWidth, out gix, out giy);
            TransportUnit goalMid = buildMid(gix, giy, side);
            goalMid.conUp = true;
            goalMid.UpLev = 1;
        }
        else if (dir == Dir.DOWN)
        {
            //find the index of the goal mid unit
            float goalPosY = (lu.indexJ) * sideLengthLarge;                   //the x value of the very right side of the large unit in mid units
            float goalPosX = GridMath.findX(goalPosY, lu.conPoint, outSlope); //the y value on the line between teh two conpoints
            GridMath.findMidIndexfromPoint(new Vector2(goalPosX, goalPosY + 0.5f), midTUWidth, out gix, out giy);
        }
        //the x and y index of the mid unit last created in the loop(starts as if pows were last created)
        //int lastix = powIndexX, lastiy = powIndexY;
        TransportUnit lastMid = powMid;

        while (true)
        {
            //the difference in indexes between the current and goal mid units
            int xdif = gix - lastMid.indexI;
            int ydif = giy - lastMid.indexJ;

            //the direction to move in this loop iteration(1=x 2=y)
            int movedir;

            //if they are both not on the goal index, pick a random one to change
            if (xdif != 0 && ydif != 0)
            {
                movedir = lu.rng.NextDouble() > 0.5 ? 1:2;
            }
            else if (xdif != 0)
            {
                movedir = 1;
            }
            else if (ydif != 0)
            {
                movedir = 2;
            }
            else            //if they are both zero we are done maybe?
            {
                break;      //?
            }
            //the index of the mid unit to be created
            int curix = lastMid.indexI, curiy = lastMid.indexJ;

            //if moving in the x direction
            if (movedir == 1)
            {
                if (xdif > 0)
                {
                    curix++;
                }
                else
                {
                    curix--;
                }
            }
            else            //movedir==2
            {
                if (ydif > 0)
                {
                    curiy++;
                }
                else
                {
                    curiy--;
                }
            }

            //create or retrieve the new mid unit
            TransportUnit curMid = buildMid(curix, curiy, side);

            //set its conpoint if it has not already been set
            curMid.setConPoint(new Vector2((curix + (float)lu.rng.NextDouble()) * midTUWidth, (curiy + (float)lu.rng.NextDouble()) * midTUWidth));

            //MyDebug.placeMarker(UnitConverter.getWP(new SurfacePos(PSide.TOP, curMid.conPoint.x, curMid.conPoint.y), 10000, 1024), 5);

            connectUnits(curMid, lastMid, 1);

            lastMid = curMid;
        }
    }
Ejemplo n.º 4
0
    //builds a level 2 street of length from startMid within curLarge transport unit
    private void buildLev2(TULarge curLarge, TransportUnit startMid, int length, PSide side)
    {
        //the max and min indexes that the street can be built to(stay within the large unit)
        //move out of this function so it is not recalculated every time
        int maxI = (curLarge.indexI + 1) * largeTUWidth - 1;
        int minI = (curLarge.indexI) * largeTUWidth;
        int maxJ = (curLarge.indexJ + 1) * largeTUWidth - 1;
        int minJ = (curLarge.indexJ) * largeTUWidth;

        //the last mid unit to build away from
        TransportUnit lastMid = startMid;
        Dir           lastDir;

        for (int i = 0; i < length; i++)
        {
            //the direction to build
            //NOTE: modify later to not build back from the same direction
            Dir dir = (Dir)(curLarge.rng.Next(1, 5));

            //the index of the new mid unit to modify
            int curix = lastMid.indexI;
            int curiy = lastMid.indexJ;

            if (dir == Dir.RIGHT)
            {
                curix++;
                if (curix > maxI)
                {
                    lastMid.conRight = true;
                    lastMid.RightLev = 2;
                    break;
                }
            }
            if (dir == Dir.LEFT)
            {
                curix--;
                if (curix < minI)
                {
                    break;
                }
            }
            if (dir == Dir.UP)
            {
                curiy++;
                if (curiy > maxJ)
                {
                    lastMid.conUp = true;
                    lastMid.UpLev = 2;
                    break;
                }
            }
            if (dir == Dir.DOWN)
            {
                curiy--;
                if (curiy < minJ)
                {
                    break;
                }
            }

            //build (or just retrieve) the mid unit at the new indexes
            TransportUnit curMid = buildMid(curix, curiy, side);

            //set its conpoint if it has not already been set
            curMid.setConPoint(new Vector2((curix + (float)curLarge.rng.NextDouble()) * midTUWidth, (curiy + (float)curLarge.rng.NextDouble()) * midTUWidth));

            //MyDebug.placeMarker(UnitConverter.getWP(new SurfacePos(PSide.TOP, curMid.conPoint.x, curMid.conPoint.y), 10000, 1024), 10);

            //connect on level 2
            connectUnits(curMid, lastMid, 2);

            lastMid = curMid;
        }
    }
Ejemplo n.º 5
0
    //populates a large unit with mid units
    private void populateLarge(TULarge lu, SurfaceUnit lus)
    {
        //Debug.Log("built " + lus);

        //clear the index list
        indexList.Clear();

        //find the mid unit that the large unit's conpoint falls in
        int powIndexX, powIndexY;

        GridMath.findMidIndexfromPoint(lu.conPoint, midTUWidth, out powIndexX, out powIndexY);
        TransportUnit powMid = buildMid(powIndexX, powIndexY, lus.side);

        powMid.conPoint = lu.conPoint;        //same conpoint, or could change to not be, doesn't really  matter
        powMid.conSet   = true;

        TULarge rightLU = getLarge(new SurfaceUnit(lus.side, lus.u + 1, lus.v));
        TULarge leftLU  = getLarge(new SurfaceUnit(lus.side, lus.u - 1, lus.v));
        TULarge upLU    = getLarge(new SurfaceUnit(lus.side, lus.u, lus.v + 1));
        TULarge downLU  = getLarge(new SurfaceUnit(lus.side, lus.u, lus.v - 1));
        //Vector2 conPointRight = rightLU.conPoint;

        //determine in which direction the streets should be built
        bool conRight = lu.conRight;
        bool conLeft  = false;
        bool conUp    = lu.conUp;
        bool conDown  = false;

        //check for null large units
        if (leftLU != null)
        {
            conLeft = leftLU.conRight;
        }
        if (downLU != null)
        {
            conDown = downLU.conUp;
        }

        //list of the index of all the mid transport units that are connected in some way
        if (conRight)
        {
            buildMidCurve(lu, rightLU.conPoint, Dir.RIGHT, powMid, lus.side);
        }
        if (conLeft)
        {
            buildMidCurve(lu, leftLU.conPoint, Dir.LEFT, powMid, lus.side);
        }
        if (conUp)
        {
            buildMidCurve(lu, upLU.conPoint, Dir.UP, powMid, lus.side);
        }
        if (conDown)
        {
            buildMidCurve(lu, downLU.conPoint, Dir.DOWN, powMid, lus.side);
        }

        //build some level 2 streets coming off the level 1 streets or other level 2 streets
        int numStreets = 80;        //(int)(Random.value*5);

        for (int i = 0; i < numStreets; i++)
        {
            int           startNum = lu.rng.Next(0, indexList.Count);
            TransportUnit startMid = indexList[startNum];
            buildLev2(lu, startMid, lu.rng.Next(2, 80), lus.side);
        }


        Vector3 topright = UnitConverter.getWP(new SurfacePos(lus.side, (lu.indexI + 1) * sideLengthLarge, (lu.indexJ + 1) * sideLengthLarge), 10000, sideLength);
        Vector3 topleft  = UnitConverter.getWP(new SurfacePos(lus.side, (lu.indexI) * sideLengthLarge, (lu.indexJ + 1) * sideLengthLarge), 10000, sideLength);
        Vector3 botright = UnitConverter.getWP(new SurfacePos(lus.side, (lu.indexI + 1) * sideLengthLarge, (lu.indexJ) * sideLengthLarge), 10000, sideLength);
        Vector3 botleft  = UnitConverter.getWP(new SurfacePos(lus.side, (lu.indexI) * sideLengthLarge, (lu.indexJ) * sideLengthLarge), 10000, sideLength);

        Debug.DrawLine(topleft, botleft, Color.red, Mathf.Infinity);
        Debug.DrawLine(topleft, topright, Color.red, Mathf.Infinity);
        Debug.DrawLine(topright, botright, Color.red, Mathf.Infinity);
        Debug.DrawLine(botright, botleft, Color.red, Mathf.Infinity);


        lu.populated = true;
    }