public static VeggieObject growPlant(VeggieObject thisVeggie)
    {
        if (thisVeggie != null)
        {
            float lightAff = CommonGameObjects.veggieProperties [thisVeggie.plantID, 6];
            float waterAff = CommonGameObjects.veggieProperties [thisVeggie.plantID, 4];
            //float soilAff = CommonGameObjects.veggieProperties [thisVeggie.plantID, 5];
            float affFactor = Mathf.Min(thisVeggie.lightEnergy / lightAff, thisVeggie.waterEnergy / waterAff);
            //float affFactor = Mathf.Min(thisVeggie.lightEnergy/lightAff,thisVeggie.waterEnergy/waterAff, thisVeggie.soilEnergy/soilAff);

            float totalEnergy = affFactor * lightAff + affFactor * waterAff;
            //float totalEnergy = affFactor*lightAff + affFactor*waterAff+ affFactor*soilAff;

            thisVeggie.bioMass += totalEnergy;

            float usingEnegry = thisVeggie.bioMass * CommonGameObjects.veggieProperties [thisVeggie.plantID, 12];
            thisVeggie.bioMass = Mathf.Clamp(thisVeggie.bioMass - usingEnegry, 0, 500);

            thisVeggie.lightEnergy = 0;
            thisVeggie.waterEnergy = 0;
            //thisVeggie.soilEnergy = 0;

            if (thisVeggie.bioMass < bioMassMinimum)
            {
                thisVeggie = null;
            }
        }
        return(thisVeggie);
    }
    public static VeggieObject assignVeggieProps(int idNum, int zone, Vector3 pos)
    {
        int   theIDNum = idNum + zone * 5;
        float isPlaced = (float)rand.NextDouble();

        if (isPlaced < veggieProperties[theIDNum, 11])
        {
            VeggieObject thisVeggie = new VeggieObject();
            thisVeggie.plantID = theIDNum;
            int yRot = rand.Next(0, 360);
            thisVeggie.rot     = Quaternion.Euler(new Vector3(0, yRot, 0));
            thisVeggie.zoneNum = zone;
            thisVeggie.bioMass = 1f;
            thisVeggie.pos     = pos;
            return(thisVeggie);
        }
        else
        {
            return(null);
        }
    }
    public static IEnumerator createVeggieMap2()
    {
        Debug.Log("Creating Veggiemap!");
        yield return(new WaitForSeconds(0.01f));

        bool  fin = true;
        float sT  = Time.realtimeSinceStartup;

        VeggieObject[][]        vm1;
        int[][]                 zm;
        float[][]               wm;//, soilMap;
        List <VeggieObject>[][] aboveGroundComp;
        List <VeggieObject>[][] belowGroundComp;

        lock (GameManager.tSets)
        {
            vm1 = (VeggieObject[][])GameManager.tSets.globalVeggieMap.Clone();
            zm  = (int[][])GameManager.tSets.globalZoneMap.Clone();
            wm  = (float[][])GameManager.tSets.globalWaterMap.Clone();
        }

        VeggieObject[][] seedMap = new VeggieObject[vm1.Length][];
        //soilMap = new float[vm1.Length][];
        for (int i = 0; i < vm1.Length; i++)
        {
            seedMap [i] = new VeggieObject[vm1 [i].Length];
            //soilMap [i] = new float[vm1 [i].Length];
        }

        aboveGroundComp = new List <VeggieObject> [vm1.Length][];
        belowGroundComp = new List <VeggieObject> [vm1.Length][];

        for (int i = 0; i < vm1.Length; i++)
        {
            aboveGroundComp [i] = new List <VeggieObject> [vm1[i].Length];
            for (int j = 0; j < aboveGroundComp [i].Length; j++)
            {
                aboveGroundComp [i] [j] = new List <VeggieObject> ();
            }

            belowGroundComp [i] = new List <VeggieObject> [vm1[i].Length];
            for (int j = 0; j < belowGroundComp [i].Length; j++)
            {
                belowGroundComp [i] [j] = new List <VeggieObject> ();
            }
        }

        lock (GameManager.lSets)
        {
            GameManager.lSets.totalToFill += vm1.Length * vm1.Length * (ageOfWorld * 3 + 1);
        }

        yield return(new WaitForSeconds(1f));

        CustomThreadPool.Instance.QueueUserTask(() =>
        {
            System.Random rand = new System.Random();

            Debug.Log("Veggiemap " + vm1.Length + "x" + vm1.Length + " started");
            for (int x = 0; x < vm1.Length; x++)
            {
                for (int z = 0; z < vm1[x].Length; z++)
                {
                    Vector3 zoneIndex = GameManager.gamemapToGamemap(new Vector3(x, 0, z), 6, 2);
                    int zoneNum       = zm[(int)zoneIndex.x][(int)zoneIndex.z];

                    seedMap[x][z] = CommonGameObjects.assignVeggieProps(rand.Next(0, 5), zoneNum, GameManager.gamemapToWorld(new Vector3(x, 0, z), 6));
                    //soilMap[x][z] =  (float)rand.NextDouble();
                }

                lock (GameManager.lSets)
                {
                    GameManager.lSets.totalFilled += vm1.Length;
                }
                Thread.Sleep(0);
            }

            for (int a = 0; a < ageOfWorld; a++)
            {
                for (int x = 0; x < vm1.Length; x++)
                {
                    for (int z = 0; z < vm1[x].Length; z++)
                    {
                        VeggieObject currentV = seedMap[x][z];
                        if (currentV != null)
                        {
                            float bioM      = currentV.bioMass;
                            float convConst = (1 / CommonGameObjects.veggieProperties [currentV.plantID, 0]) / (1 / CommonGameObjects.veggieProperties [currentV.plantID, 2]);
                            float roi       = Mathf.Pow(6 * bioM / Mathf.PI / convConst, 1f / 3f) / 2;
                            float aboveRoI  = CommonGameObjects.veggieProperties [currentV.plantID, 13] * roi;
                            float belowRoI  = CommonGameObjects.veggieProperties [currentV.plantID, 14] * roi;
                            currentV.width  = roi * 2;

                            float thisHeight = Mathf.Pow(6 * currentV.bioMass / Mathf.PI / Mathf.Pow(1 / convConst, 2), 1f / 3f);
                            currentV.height  = thisHeight;

                            int smallerAI = (int)Mathf.Min(x, Mathf.Ceil(aboveRoI));
                            int smallerAJ = (int)Mathf.Min(z, Mathf.Ceil(aboveRoI));
                            int largerAI  = (int)Mathf.Min(vm1.Length - x - 1, Mathf.Ceil(aboveRoI));
                            int largerAJ  = (int)Mathf.Min(vm1.Length - z - 1, Mathf.Ceil(aboveRoI));

                            int smallerBI = (int)Mathf.Min(x, Mathf.Ceil(belowRoI));
                            int smallerBJ = (int)Mathf.Min(z, Mathf.Ceil(belowRoI));
                            int largerBI  = (int)Mathf.Min(vm1.Length - x - 1, Mathf.Ceil(belowRoI));
                            int largerBJ  = (int)Mathf.Min(vm1.Length - z - 1, Mathf.Ceil(belowRoI));

                            for (int i = -smallerAI; i <= largerAI; i++)
                            {
                                for (int j = -smallerAJ; j <= largerAJ; j++)
                                {
                                    float dist = calcPlantDistance(x, z, x + i, z + j);
                                    if (dist <= aboveRoI)
                                    {
                                        aboveGroundComp[x + i][z + j].Add(currentV);
                                    }
                                }
                            }

                            for (int i = -smallerBI; i <= largerBI; i++)
                            {
                                for (int j = -smallerBJ; j <= largerBJ; j++)
                                {
                                    float dist = calcPlantDistance(x, z, x + i, z + j);
                                    if (dist <= belowRoI)
                                    {
                                        belowGroundComp[x + i][z + j].Add(currentV);
                                    }
                                }
                            }
                        }
                    }

                    lock (GameManager.lSets)
                    {
                        GameManager.lSets.totalFilled += vm1.Length;
                    }
                    Thread.Sleep(0);
                }

                for (int x = 0; x < vm1.Length; x++)
                {
                    for (int z = 0; z < vm1[x].Length; z++)
                    {
                        float totalSoilComp  = 0;
                        float totalWaterComp = 0;
                        float totalLightComp = 0;

                        foreach (VeggieObject vO in aboveGroundComp[x][z])
                        {
                            totalLightComp += Mathf.Pow(vO.height + 1, 6);
                        }

                        foreach (VeggieObject vO in belowGroundComp[x][z])
                        {
                            totalWaterComp += CommonGameObjects.veggieProperties[vO.plantID, 4];
                            totalSoilComp  += CommonGameObjects.veggieProperties[vO.plantID, 5];
                        }

                        foreach (VeggieObject vO in aboveGroundComp[x][z])
                        {
                            float thisLightComp  = Mathf.Pow(vO.height + 1, 6);
                            float lightForGrowth = thisLightComp / totalLightComp;

                            Vector3 compIndex = GameManager.worldToGamemap(vO.pos, 6);
                            float distance    = calcPlantDistance(x, z, (int)compIndex.x, (int)compIndex.z);

                            vO.lightEnergy += lightForGrowth * resourceEfficiencyFromDistance(distance, vO.plantID, true);
                        }

                        foreach (VeggieObject vO in belowGroundComp[x][z])
                        {
                            float thisWaterComp  = CommonGameObjects.veggieProperties[vO.plantID, 4];
                            float waterForGrowth = thisWaterComp / totalWaterComp * wm[x][z];
                            //float thisSoilComp = CommonGameObjects.veggieProperties[vO.plantID,5];
                            //float soilForGrowth = thisSoilComp/totalSoilComp*soilMap[x][z];

                            Vector3 compIndex = GameManager.worldToGamemap(vO.pos, 6);
                            float distance    = calcPlantDistance(x, z, (int)compIndex.x, (int)compIndex.z);

                            //vO.bioMass += (waterForGrowth+soilForGrowth)*resourceEfficiencyFromDistance(distance,vO.plantID,false);
                            vO.waterEnergy += (waterForGrowth) * resourceEfficiencyFromDistance(distance, vO.plantID, false);
                        }
                    }

                    lock (GameManager.lSets)
                    {
                        GameManager.lSets.totalFilled += vm1.Length;
                    }
                    Thread.Sleep(0);
                }

                for (int x = 0; x < vm1.Length; x++)
                {
                    for (int z = 0; z < vm1[x].Length; z++)
                    {
                        seedMap[x][z] = growPlant(seedMap[x][z]);
                    }
                    lock (GameManager.lSets)
                    {
                        GameManager.lSets.totalFilled += vm1.Length;
                    }
                    Thread.Sleep(0);
                }
            }
        },
                                                (ts) =>
        {
            fin = false;
        });

        while (fin)
        {
            yield return(new WaitForSeconds(0.5f));
        }

        lock (GameManager.tSets)
        {
            GameManager.tSets.globalVeggieMap = (VeggieObject[][])seedMap.Clone();
            GameManager.tSets.isVeggieSet     = true;
            float eT = Mathf.Round(100f * (Time.realtimeSinceStartup - sT)) / 100f;
            Debug.Log("Veggiemap finished after " + eT + " seconds");
        }
    }