Example #1
0
        public void PacificNorthwestSpecies()
        {
            Project pnwProject = new(LandTest.GetPacificNorthwestProjectPath(this.TestContext !));

            TreeSpeciesSet pnwSpecies = new(Constant.Database.DefaultSpeciesTable);

            pnwSpecies.Setup(pnwProject);

            TreeSpecies abam = pnwSpecies["abam"];
            TreeSpecies abgr = pnwSpecies["abgr"];
            TreeSpecies abpr = pnwSpecies["abpr"];
            TreeSpecies acma = pnwSpecies["acma"];
            TreeSpecies alru = pnwSpecies["alru"];
            TreeSpecies pisi = pnwSpecies["pisi"];
            TreeSpecies pipo = pnwSpecies["pipo"]; // TODO: what ecoregion are parameters for?
            TreeSpecies psme = pnwSpecies["psme"];
            TreeSpecies tshe = pnwSpecies["tshe"];
            TreeSpecies tsme = pnwSpecies["tsme"];
            TreeSpecies thpl = pnwSpecies["thpl"];

            Assert.IsTrue(pnwSpecies.ActiveSpecies.Count == 11);
            Assert.IsTrue(pnwSpecies.Count == 11);
            Assert.IsTrue((abam != null) && (abgr != null) && (abpr != null) && (acma != null) && (alru != null) && (pisi != null) &&
                          (pipo != null) && (psme != null) && (tshe != null) && (tsme != null) && (thpl != null));
        }
        public CohortIteration(
            Int64 period,
            Int64 timeStepLength,
            Double initialNumberOfTrees,
            Double initialVolume,
            Double initialBiomass,
            Double initialDensity,
            TreeSpecies species,
            bool performCalculation,
            DecayModel model)
        {
            Period = period;
            Species = species;
            Model = model;

            if (performCalculation)
            {
                //V_t = V_0 * exp(- alpha*t)
                Volume = initialVolume * Math.Exp(-GetVolumeAlpha() * timeStepLength);
                Biomass = initialBiomass * Math.Exp(-GetBiomassAlpha() * timeStepLength);
                Density = initialDensity * Math.Exp(-GetDensityAlpha() * timeStepLength);
            }
            else
            {
                Volume = initialVolume;
                Biomass = initialBiomass;
                Density = initialDensity;
            }
            DecayClass = GetDecayClass(Density);
            NumberOfStems = initialNumberOfTrees;
        }
        protected override void LogYear(Model model, SqliteCommand insertRow)
        {
            foreach (ResourceUnit ru in model.Landscape.ResourceUnits)
            {
                if (ru.EnvironmentID == -1)
                {
                    continue; // do not include if out of project area
                }

                // exclude if a condition is specified and condition is not met
                if (this.mResourceUnitFilter.IsEmpty == false)
                {
                    Debug.Assert(this.mResourceUnitFilter.Wrapper != null);
                    ((ResourceUnitWrapper)this.mResourceUnitFilter.Wrapper).ResourceUnit = ru;
                    if (this.mResourceUnitFilter.Execute() == 0.0)
                    {
                        continue;
                    }
                }

                SaplingCell[]? saplingCells = ru.SaplingCells;
                if (saplingCells != null)
                {
                    for (int lightCellIndex = 0; lightCellIndex < saplingCells.Length; ++lightCellIndex)
                    {
                        SaplingCell saplingCell = saplingCells[lightCellIndex];
                        int         n_on_px     = saplingCell.GetOccupiedSlotCount();
                        if (n_on_px > 0)
                        {
                            for (int index = 0; index < saplingCell.Saplings.Length; ++index)
                            {
                                if (saplingCell.Saplings[index].IsOccupied())
                                {
                                    ResourceUnitTreeSpecies ruSpecies   = saplingCell.Saplings[index].GetResourceUnitSpecies(ru);
                                    TreeSpecies             treeSpecies = ruSpecies.Species;
                                    float dbh = 100.0F * saplingCell.Saplings[index].Height / treeSpecies.SaplingGrowthParameters.HeightDiameterRatio;
                                    // check minimum dbh
                                    if (dbh < this.mMinDbh)
                                    {
                                        continue;
                                    }
                                    float n_repr = treeSpecies.SaplingGrowthParameters.RepresentedStemNumberFromHeight(saplingCell.Saplings[index].Height) / n_on_px;

                                    insertRow.Parameters[0].Value = model.CurrentYear;
                                    insertRow.Parameters[1].Value = ru.ResourceUnitGridIndex;
                                    insertRow.Parameters[2].Value = ru.EnvironmentID;
                                    insertRow.Parameters[3].Value = ruSpecies.Species.ID;
                                    insertRow.Parameters[4].Value = n_repr;
                                    insertRow.Parameters[5].Value = dbh;
                                    insertRow.Parameters[6].Value = saplingCell.Saplings[index].Height;
                                    insertRow.Parameters[7].Value = saplingCell.Saplings[index].Age;
                                    insertRow.ExecuteNonQuery();
                                }
                            }
                        }
                    }
                }
            }
        }
Example #4
0
        public void SetContents(MaterialData materialData)
        {
            Material mat = materialData.ItemType;

            if (mat == Material.RedRose)
            {
                Data = ((byte)1);
            }
            else if (mat == Material.YellowFlower)
            {
                Data = ((byte)2);
            }
            else if (mat == Material.RedMushroom)
            {
                Data = ((byte)7);
            }
            else if (mat == Material.BrownMushroom)
            {
                Data = ((byte)8);
            }
            else if (mat == Material.Cactus)
            {
                Data = ((byte)9);
            }
            else if (mat == Material.DeadBush)
            {
                Data = ((byte)10);
            }
            else if (mat == Material.Sapling)
            {
                TreeSpecies species = ((Tree)materialData).Species;

                if (species == TreeSpecies.Generic)
                {
                    Data = ((byte)3);
                }
                else if (species == TreeSpecies.Redwood)
                {
                    Data = ((byte)4);
                }
                else if (species == TreeSpecies.Birch)
                {
                    Data = ((byte)5);
                }
                else
                {
                    Data = ((byte)6);
                }
            }
            else if (mat == Material.LongGrass)
            {
                GrassSpecies species = ((LongGrass)materialData).Species;

                if (species == GrassSpecies.FernLike)
                {
                    Data = ((byte)11);
                }
            }
        }
Example #5
0
    private GameObject AddTree(TreeSpecies species)
    {
        GameObject tree     = new GameObject("TreeInstance");
        PGTreeBase treeBase = tree.AddComponent <PGTreeBase>();

        treeBase.SetSpecies(species);
        return(tree);
    }
Example #6
0
 private void GenerateTrees(TreeSpecies species, int treeNum, float xMin, float xMax, float zMin, float zMax)
 {
     for (int i = 0; i < treeNum; i++)
     {
         GameObject newTree    = AddTree(species);
         float      randX      = Random.Range(xMin, xMax);
         float      randZ      = Random.Range(zMin, zMax);
         float      treeHeight = terrain.SampleHeight(new Vector3(randX, 0.0f, randZ));
         newTree.transform.position = new Vector3(randX, treeHeight, randZ);
     }
 }
    // Use this for initialization
    void Start()
    {
        species = GetComponent <TreeSpecies>();
        CreateSlider("Trunk Height", "m_height", 1.0f, 5.0f);
        CreateSlider("Trunk Start Radius", "m_start_radius", 0.5f, 5.0f);
        CreateSlider("Trunk End Radius", "m_end_radius", 0.5f, 5.0f);
        CreateSlider("Trunk Twist Angle", "m_twist_angle", 0.0f, 180.0f);
        CreateSlider("Trunk Max Bend", "m_max_bend", 0.0f, 90.0f);
        //CreateSlider("Blending", "m_expolinear_blend", 0.0f, 1.0f);
        CreateSlider("Irregularity", "m_start_irregularity", 0.0f, 1.0f);
        CreateSlider("Irregularity Falloff", "m_irregularity_falloff", 0.0f, 10.0f);


        CreateSlider("Branch Length", "m_branch_length", 0.5f, 10.0f);
        CreateSlider("Branch Length Randomness", "m_branch_length_randomness", 0.0f, 5.0f);
        CreateSlider("Branch Length Falloff", "m_branch_length_falloff", 0.0f, 2.0f);
        CreateSlider("Branch Max Bend", "m_branch_max_bend", 0.0f, 90.0f);
        CreateSlider("Branch Bend Falloff", "m_branch_bend_falloff", 0.0f, 5.0f);
        CreateSlider("Branch Min Upright", "m_branch_min_uprightness", 0.0f, 10.0f);
        CreateSlider("Branch Fork Angle Min", "m_branch_min_fork_angle", 0.0f, 90.0f);
        CreateSlider("Branch Fork Angle Max", "m_branch_max_fork_angle", 0.0f, 90.0f);
        CreateSlider("Branch Twist Angle", "m_branch_twist_angle", 0.0f, 90.0f);
        CreateSlider("Branch Twist Randomness", "m_branch_twist_randomness", 0.0f, 30.0f);
        CreateSlider("Branch Twist Falloff", "m_branch_twist_falloff", 0.0f, 2.0f);
        CreateSlider("Branch Min Radius", "m_branch_min_radius", 0.0f, 10.0f);
        CreateSlider("Branch Radius Falloff", "m_branch_radius_falloff", 0.0f, 10.0f);



        //public float m_branch_length = 2.0f;
        //public float m_branch_length_randomness = 1.0f;
        //public float m_branch_length_falloff = 0.8f;
        //public int m_branch_segments = 3;

        //public float m_branch_max_bend = 45f;
        //public float m_branch_bend_falloff = 0.8f;
        //public float m_branch_min_uprightness = 0.5f;

        //public float m_branch_min_fork_angle = 0f;
        //public float m_branch_max_fork_angle = 75f;
        //public float m_branch_twist_angle = 90f;
        //public float m_branch_twist_randomness = 15f;
        //public float m_branch_twist_falloff = 0.8f;

        //public float m_branch_min_radius = 0.1f;
        //public float m_branch_radius_falloff = 1.0f;

        //public int m_radial_segments = 8;
        //public int m_height_segments = 10;
    }
Example #8
0
    int treeMaxCap = 5000; // Used to prevent performance problems and crashes when treeMax is too large.

    void Start()
    {
        terrain = Terrain.activeTerrain;

        // Generate random tree species
        for (int i = 0; i < speciesNum; i++)
        {
            TreeSpecies species = new TreeSpecies();
            species.CreateNewSpecies();
            Species.Add(species);
        }
        // Determine maximum number of trees to create
        treeMax = (int)Mathf.RoundToInt((float)(xMax - xMin) * (float)(zMax - zMin) * treeDensity * 0.1f);
    }
Example #9
0
        private static void VerifyNorwaySpruce(Model model)
        {
            TreeSpecies species = model.Landscape.ResourceUnits[0].Trees.TreeSpeciesSet["piab"];

            AssertNullable.IsNotNull(species);

            // PIAB: 1/(1 + (x/0.55)^2)
            float youngAgingFactor  = species.GetAgingFactor(10.0F, 10);
            float middleAgingFactor = species.GetAgingFactor(40.0F, 80);
            float oldAgingFactor    = species.GetAgingFactor(55.5F, 575);

            Assert.IsTrue(MathF.Abs(youngAgingFactor - 0.964912F) < 0.001F);
            Assert.IsTrue(MathF.Abs(middleAgingFactor - 0.481931F) < 0.001F);
            Assert.IsTrue(MathF.Abs(oldAgingFactor - 0.2375708F) < 0.001F);

            // PIAB: mf = 0.095565 * dbh^1.56
            // round(0.095565 * c(2, 20, 50, 100) ^ 1.56, 5)
            Assert.IsTrue(String.Equals(species.ID, "piab", StringComparison.Ordinal));
            Assert.IsTrue(Math.Abs(species.GetBiomassFoliage(2) - 0.281777) < 0.001);
            Assert.IsTrue(Math.Abs(species.GetBiomassFoliage(20) - 10.23070) < 0.001);
            Assert.IsTrue(Math.Abs(species.GetBiomassFoliage(50) - 42.72598) < 0.001);
            Assert.IsTrue(Math.Abs(species.GetBiomassFoliage(100) - 125.97920) < 0.001);

            // PIAB: HDlow = 170*(1)*d^-0.5, HDhigh = (195.547*1.004*(-0.2396+1)*d^-0.2396)*1
            // round(170*(1)*c(3.3, 10, 33)^-0.5, 2)
            // round((195.547*1.004*(-0.2396+1)*c(3.3, 10, 33)^-0.2396)*1, 2)
            species.GetHeightDiameterRatioLimits(3.3F, out float lowLimitSmall, out float highLimitSmall);
            species.GetHeightDiameterRatioLimits(10.0F, out float lowLimitMedium, out float highLimitMedium);
            species.GetHeightDiameterRatioLimits(33.0F, out float lowLimitLarge, out float highLimitLarge);

            Assert.IsTrue(MathF.Abs(lowLimitSmall - 93.58F) < 0.01F);
            Assert.IsTrue(MathF.Abs(lowLimitMedium - 53.76F) < 0.01F);
            Assert.IsTrue(MathF.Abs(lowLimitLarge - 29.59F) < 0.01F);
            Assert.IsTrue(MathF.Abs(highLimitSmall - 112.15F) < 0.01F);
            Assert.IsTrue(MathF.Abs(highLimitMedium - 85.99F) < 0.01F);
            Assert.IsTrue(MathF.Abs(highLimitLarge - 64.59F) < 0.01F);

            // PIAB: 44.7*(1-(1-(h/44.7)^(1/3))*exp(-0.044))^3
            // round(44.7*(1-(1-(c(0.25, 1, 4.5)/44.7)^(1/3))*exp(-0.044))^3, 3)
            double shortPotential  = species.SaplingGrowthParameters.HeightGrowthPotential.Evaluate(0.25);
            double mediumPotential = species.SaplingGrowthParameters.HeightGrowthPotential.Evaluate(1);
            double tallPotential   = species.SaplingGrowthParameters.HeightGrowthPotential.Evaluate(4.5);

            Assert.IsTrue(Math.Abs(shortPotential - 0.431) < 0.01);
            Assert.IsTrue(Math.Abs(mediumPotential - 1.367) < 0.01);
            Assert.IsTrue(Math.Abs(tallPotential - 5.202) < 0.01);
        }
        public CohortStatistics(
            int periodCreated,
            String plot,
            TreeSpecies species,
            String sizeClass,
            DecayModel model,
            int maxDecayClass,
            int maxTimeStep,
            Double numberOfStemsCreated,
            Double volumeCreated,
            Double biomassCreated,
            Double densityCreated,
            Double diameterCreated
            )
        {
            CohortIteration iteration;

            PeriodCreated = periodCreated;
            Plot = plot;
            Species = species;
            SizeClass = sizeClass;
            NumberOfStemsCreated = numberOfStemsCreated;
            VolumeCreated = volumeCreated;
            BiomassCreated = biomassCreated;
            DiameterAtBrestHeightCreated = diameterCreated;

            int decayClass = 0;
            int period = periodCreated;
            Double numberOfStems = NumberOfStemsCreated;
            Double volume = volumeCreated;
            Double biomass = biomassCreated;
            Double density = densityCreated;
            Iterations = new List<CohortIteration>();
            iteration = new CohortIteration(period++, TimeStepLength, numberOfStems, volume, biomass, density, Species, false, model);
            Iterations.Add(iteration);
            while (decayClass < maxDecayClass && period < (periodCreated + maxTimeStep)) //Iterates the decay of the cohort of all dead tree stems until reaching max decay class.
            {
                iteration = new CohortIteration(period++, TimeStepLength, numberOfStems, volume, biomass, density, Species, true, model);
                Iterations.Add(iteration);
                decayClass = iteration.DecayClass;
                volume = iteration.Volume;
                biomass = iteration.Biomass;
                density = iteration.Density;
            }
        }
        public ForestStandStatistics(
            Int64 period,
            String plot,
            TreeSpecies species,
            String sizeClass
            )
        {
            Period = period;
            Plot = plot;
            Species = species;
            SizeClass = sizeClass;

            _volumeValues = new List<double>();
            _decayClassValues = new List<double>();
            _diameterValues = new List<double>();
            _numberOfStemsValues = new List<double>();
            _biomass = 0;
        }
Example #12
0
 public Tree(TreeSpecies species) : this()
 {
     Species = species;
 }
 public TreeEntity(TreeSpecies species, WorldPosition3i position, PlantPack plantPack)
     : base(species, position, plantPack)
 {
 }
        protected override void LogYear(Model model, SqliteCommand insertRow)
        {
            if (this.mFieldList.Count == 0)
            {
                return;
            }
            if (this.mYearFilter.IsEmpty == false)
            {
                if (this.mYearFilter.Evaluate(model.CurrentYear) != 0.0)
                {
                    return;
                }
            }

            //using DebugTimer dt = model.DebugTimers.Create("DynamicStandOutput.LogYear()");
            bool perSpecies = model.Project.Output.Annual.DynamicStand.BySpecies;
            bool perRU      = model.Project.Output.Annual.DynamicStand.ByResourceUnit;

            if (perRU)
            {
                // when looping over resource units, do it differently (old way)
                this.ExtractByResourceUnit(model, perSpecies, insertRow);
                return;
            }

            // grouping
            if (model.Landscape.Environment.SpeciesSetsByTableName.Count != 1)
            {
                throw new NotImplementedException("Generation of a unique list of species from multiple species sets is not currently supported.");
            }
            List <double> fieldData        = new(); //statistics data
            TreeWrapper   treeWrapper      = new(model);
            Expression    customExpression = new();

            TreeSpeciesSet treeSpeciesSet     = model.Landscape.Environment.SpeciesSetsByTableName.First().Value;
            List <Trees>   liveTreesOfSpecies = new();

            for (int speciesSet = 0; speciesSet < treeSpeciesSet.ActiveSpecies.Count; ++speciesSet)
            {
                liveTreesOfSpecies.Clear();

                TreeSpecies        species           = treeSpeciesSet.ActiveSpecies[speciesSet];
                AllTreesEnumerator allTreeEnumerator = new(model.Landscape);
                while (allTreeEnumerator.MoveNextLiving())
                {
                    if (perSpecies && allTreeEnumerator.CurrentTrees.Species != species)
                    {
                        continue;
                    }
                    liveTreesOfSpecies.Add(allTreeEnumerator.CurrentTrees);
                }
                if (liveTreesOfSpecies.Count == 0)
                {
                    continue;
                }

                // dynamic calculations
                int columnIndex = 0;
                SummaryStatistics fieldStatistics = new(); // statistcs helper class
                foreach (DynamicOutputField field in this.mFieldList)
                {
                    if (String.IsNullOrEmpty(field.Expression) == false)
                    {
                        // setup dynamic dynamic expression if present
                        customExpression.SetExpression(field.Expression);
                        customExpression.Wrapper = treeWrapper;
                    }

                    // fetch data values from the trees
                    fieldData.Clear();
                    foreach (Trees trees in liveTreesOfSpecies)
                    {
                        treeWrapper.Trees = trees;
                        for (int treeIndex = 0; treeIndex < trees.Count; ++treeIndex)
                        {
                            treeWrapper.TreeIndex = treeIndex;
                            if (field.VariableIndex >= 0)
                            {
                                fieldData.Add(treeWrapper.GetValue(field.VariableIndex));
                            }
                            else
                            {
                                fieldData.Add(customExpression.Execute());
                            }
                        }
                    }

                    // constant values (if not already present)
                    if (columnIndex == 0)
                    {
                        insertRow.Parameters[0].Value = model.CurrentYear;
                        insertRow.Parameters[1].Value = -1;
                        insertRow.Parameters[2].Value = -1;
                        if (perSpecies)
                        {
                            insertRow.Parameters[3].Value = species.ID;
                        }
                        else
                        {
                            insertRow.Parameters[3].Value = String.Empty;
                        }
                        columnIndex = 3;
                    }

                    // calculate statistics
                    fieldStatistics.SetData(fieldData);
                    double value = field.AggregationIndex switch
                    {
                        0 => fieldStatistics.Mean,
                        1 => fieldStatistics.Sum,
                        2 => fieldStatistics.Min,
                        3 => fieldStatistics.Max,
                        4 => fieldStatistics.GetPercentile25(),
                        5 => fieldStatistics.GetMedian(),
                        6 => fieldStatistics.GetPercentile75(),
                        7 => fieldStatistics.GetPercentile(5),
                        8 => fieldStatistics.GetPercentile(10),
                        9 => fieldStatistics.GetPercentile(90),
                        10 => fieldStatistics.GetPercentile(95),
                        11 => fieldStatistics.GetStandardDeviation(),
                        _ => 0.0,
                    };
                    // add current value to output
                    insertRow.Parameters[++columnIndex].Value = value;
                }

                if (columnIndex > 0)
                {
                    insertRow.ExecuteNonQuery();
                }

                if (perSpecies == false)
                {
                    break;
                }
            }
        }
Example #15
0
 public void SetSpecies(TreeSpecies species)
 {
     treeSpecies = species;
 }
Example #16
0
    public void Init(int seed)
    {
        Random.InitState(seed);

        treeSpecies = gameObject.GetComponent <TreeSpecies>();
        // Load variables from species creator
        if (treeSpecies == null)
        {
            Debug.LogError("ERROR: No tree species attached!");
        }
        GetVariablesFromSpecies();
        treeSpecies.GenerateMaterials();

        //LODManager lodManager = new LODManager();

        //trunkObject = new GameObject("Trunk");
        //trunkObject.transform.parent = transform;
        trunkObject = gameObject.EnsureChildGameObject("Trunk");
        trunkObject.transform.localPosition = Vector3.zero;                                // Remove offset from parenting
        PGTreeTrunkSimple trunkScript = trunkObject.EnsureComponent <PGTreeTrunkSimple>(); //trunkObject.AddComponent<PGTreeTrunkSimple>();

        trunkObject.EnsureComponent <MeshRenderer>();                                      //trunkObject.AddComponent<MeshRenderer>();
        trunkObject.GetComponent <Renderer>().material = treeSpecies.m_trunk_mat;

        trunkScript.CreateObject(false);

        // Add collider
        collider        = trunkObject.EnsureComponent <CapsuleCollider>();
        collider.radius = (m_start_radius + m_end_radius) / 2.0f;
        collider.height = m_height;
        collider.center = new Vector3(0.0f, m_height / 2.0f - collider.radius, 0.0f);

        if (m_hasLeaves)
        {
            leafObject = gameObject.EnsureChildGameObject("Leaves");
            //leafObject.transform.parent = transform;
            leafObject.transform.localPosition = Vector3.zero;             // Remove offset from parenting
            PGTreeLeaf leafScript = leafObject.EnsureComponent <PGTreeLeaf>();
            leafObject.EnsureComponent <MeshRenderer>();
            leafObject.GetComponent <Renderer>().material = treeSpecies.m_leaf_mat;

            leafScript.CreateObject(false);
        }

        // Add fruit
        if (m_has_fruit)
        {
            int   fruitNum        = Random.Range(treeSpecies.m_fruit_num_min, treeSpecies.m_fruit_num_max + 1);
            int   leafPositionNum = trunkScript.Leaves.Count;
            int[] usedIndices     = new int[fruitNum];

            for (int i = 0; i < fruitNum && i < leafPositionNum; i++)
            {
                GameObject newFruit           = GameObject.Instantiate(treeSpecies.m_fruit) as GameObject;
                int        fruitPositionIndex = Random.Range(0, leafPositionNum - 1);
                bool       spareIndex         = false;
                int        loopSafetyCount    = 0;
                while (spareIndex && loopSafetyCount < leafPositionNum)
                {
                    fruitPositionIndex = Random.Range(0, leafPositionNum - 1);
                    // Check if position index already has a fruit
                    bool matchFound = false;
                    for (int j = 0; j < fruitNum; j++)
                    {
                        if (fruitPositionIndex == usedIndices[j])
                        {
                            matchFound = true;
                        }
                    }
                    loopSafetyCount++;
                    // If no match is found, no fruit is at that index
                    spareIndex = !matchFound;
                }
                usedIndices[i]                   = fruitPositionIndex;
                newFruit.transform.parent        = transform;
                newFruit.transform.localPosition = trunkScript.Leaves[fruitPositionIndex].position;
                newFruit.transform.rotation      = trunkScript.Leaves[fruitPositionIndex].rotation * Quaternion.Euler(180.0f, 0.0f, 0.0f);
            }
        }
    }
        public static void TreeDetails()
        {
            // dictionary of plant properties
            Dictionary <string, string> treeDetails = new Dictionary <string, string>()
            {
                // INFO
                { "untranslated", "nil" },
                { "isDecorative", "nil" },
                { "doesSpread", "nil" },

                // LIFETIME
                { "maturity", "nil" },
                { "treeHealth", "nil" }, // The health of the tree for chopping.
                { "logHealth", "nil" },  // The health of the log for chopping.

                // GENERATION
                { "isWater", "nil" },
                { "height", "nil" },

                // FOOD
                { "calorieValue", "nil" },

                // RESOURCES
                { "requireHarvestable", "nil" },
                { "pickableAtPercent", "nil" },
                { "experiencePerHarvest", "nil" },
                { "harvestTool", "nil" },
                { "killOnHarvest", "nil" },
                { "postHarvestGrowth", "nil" },
                { "scytheKills", "nil" },
                { "resourceItem", "nil" },
                { "resourceMin", "nil" },
                { "resourceMax", "nil" },
                { "debrisSpawnChance", "nil" }, // Chance to spawn debris.
                { "debrisType", "nil" },        // The debris created when chopping this tree. BlockType.
                { "debrisResources", "nil" },   // The resources returned for chopping the debris.
                { "trunkResources", "nil" },    // The resources returned for chopping the trunk.

                // WORLD LAYERS
                { "carbonRelease", "nil" },
                { "idealGrowthRate", "nil" },
                { "idealDeathRate", "nil" },
                { "spreadRate", "nil" },
                { "nitrogenHalfSpeed", "nil" },
                { "nitrogenContent", "nil" },
                { "phosphorusHalfSpeed", "nil" },
                { "phosphorusContent", "nil" },
                { "potassiumHalfSpeed", "nil" },
                { "potassiumContent", "nil" },
                { "soilMoistureHalfSpeed", "nil" },
                { "soilMoistureContent", "nil" },
                { "consumedFertileGround", "nil" },
                { "consumedCanopySpace", "nil" },
                { "consumedUnderwaterFertileGround", "nil" },
                { "consumedShrubSpace", "nil" },
                { "extremeTempMin", "nil" },
                { "idealTempMin", "nil" },
                { "idealTempMax", "nil" },
                { "extremeTempMax", "nil" },
                { "extremeMoistureMin", "nil" },
                { "idealMoistureMin", "nil" },
                { "idealMoistureMax", "nil" },
                { "extremeMoistureMax", "nil" },
                { "extremeSaltMin", "nil" },
                { "idealSaltMin", "nil" },
                { "idealSaltMax", "nil" },
                { "extremeSaltMax", "nil" },
                { "maxPollutionDensity", "nil" },
                { "pollutionTolerance", "nil" }
            };

            IEnumerable <Species> species = EcoSim.AllSpecies;

            foreach (Species s in species)
            {
                if (s is TreeSpecies)
                {
                    TreeSpecies tree = s as TreeSpecies;
                    //Console.WriteLine(tree.Name);
                    if (!EveryTree.ContainsKey(tree.DisplayName))
                    {
                        string treeName = tree.DisplayName;
                        EveryTree.Add(treeName, new Dictionary <string, string>(treeDetails));

                        #region INFO
                        EveryTree[treeName]["untranslated"] = $"'{tree.DisplayName.NotTranslated}'";
                        EveryTree[treeName]["isDecorative"] = tree.Decorative ? $"'{Localizer.DoStr("Decorative")}'" : "nil";
                        EveryTree[treeName]["doesSpread"]   = tree.NoSpread ? $"'{Localizer.DoStr("No")}'" : $"'{Localizer.DoStr("Yes")}'";
                        #endregion

                        #region LIFETIME
                        EveryTree[treeName]["maturity"]   = "'" + tree.MaturityAgeDays.ToString("F1") + "'";
                        EveryTree[treeName]["treeHealth"] = "'" + tree.TreeHealth.ToString("F1") + "'";
                        EveryTree[treeName]["logHealth"]  = "'" + tree.LogHealth.ToString("F1") + "'";
                        #endregion

                        #region GENERATION
                        EveryTree[treeName]["isWater"] = tree.Water ? $"'{Localizer.DoStr("Underwater")}'" : "nil";
                        EveryTree[treeName]["height"]  = "'" + tree.Height.ToString("F1") + "'";
                        #endregion

                        #region FOOD
                        EveryTree[treeName]["calorieValue"] = "'" + tree.CalorieValue.ToString("F1") + "'";
                        #endregion

                        #region RESOURCES
                        EveryTree[treeName]["requireHarvestable"]   = tree.RequireHarvestable ? $"'{Localizer.DoStr("Yes")}'" : "nil";
                        EveryTree[treeName]["pickableAtPercent"]    = "'" + (tree.PickableAtPercent * 100).ToString("F0") + "'";
                        EveryTree[treeName]["experiencePerHarvest"] = "'" + (tree.ExperiencePerHarvest).ToString("F1") + "'";

                        if (tree.PostHarvestingGrowth == 0)
                        {
                            EveryTree[treeName]["killOnHarvest"] = $"'{Localizer.DoStr("Yes")}'";
                        }
                        else
                        {
                            EveryTree[treeName]["killOnHarvest"] = $"'{Localizer.DoStr("No")}'";
                        }

                        if (tree.PostHarvestingGrowth != 0)
                        {
                            EveryTree[treeName]["postHarvestGrowth"] = "'" + (tree.PostHarvestingGrowth * 100).ToString("F0") + "'";
                        }

                        EveryTree[treeName]["scytheKills"] = tree.ScythingKills ? $"'{Localizer.DoStr("Yes")}'" : "nil";

                        if (tree.ResourceItemType != null)
                        {
                            EveryTree[treeName]["resourceItem"] = "'[[" + Localizer.DoStr(SplitName(RemoveItemTag(tree.ResourceItemType.Name))) + "]]'";
                        }

                        EveryTree[treeName]["resourceMin"]   = "'" + tree.ResourceRange.Min.ToString("F1") + "'";
                        EveryTree[treeName]["resourceMax"]   = "'" + tree.ResourceRange.Max.ToString("F1") + "'";
                        EveryTree[treeName]["resourceBonus"] = "'" + (tree.ResourceBonusAtGrowth * 100).ToString("F0") + "'";

                        // Debris
                        EveryTree[treeName]["debrisSpawnChance"] = "'" + (tree.ChanceToSpawnDebris * 100).ToString("F0") + "'";
                        EveryTree[treeName]["debrisType"]        = "'" + Localizer.DoStr(SplitName(RemoveItemTag(tree.DebrisType.Name))) + "'";

                        // The resources returned for chopping the debris.
                        var debrisResources = new StringBuilder();
                        tree.DebrisResources.ForEach(kvp =>
                        {
                            debrisResources.Append("'[[" + Item.Get(kvp.Key).DisplayName + "]]'");
                            if (tree.DebrisResources.Last().Key != kvp.Key)
                            {
                                debrisResources.Append(",");
                            }
                        });
                        EveryTree[treeName]["debrisResources"] = "{" + debrisResources + "}";

                        // The resources returned for chopping the trunk.
                        var trunkResources = new StringBuilder();
                        tree.TrunkResources.ForEach(kvp =>
                        {
                            var item = Item.Get(kvp.Key);
                            if (item != null)
                            {
                                debrisResources.Append("'[[" + item.DisplayName + "]]'");
                                if (tree.TrunkResources.Last().Key != kvp.Key)
                                {
                                    trunkResources.Append(",");
                                }
                            }
                        });
                        EveryTree[treeName]["trunkResources"] = "{" + trunkResources + "}";

                        #endregion

                        #region VISUALS

                        #endregion

                        #region WORLDLAYERS
                        EveryTree[treeName]["carbonRelease"] = "'" + tree.ReleasesCO2TonsPerDay.ToString("F4") + "'";

                        EveryTree[treeName]["idealGrowthRate"] = "'" + tree.MaxGrowthRate.ToString("F4") + "'";

                        EveryTree[treeName]["idealDeathRate"] = "'" + tree.MaxDeathRate.ToString("F4") + "'";

                        EveryTree[treeName]["spreadRate"] = "'" + tree.SpreadRate.ToString("F4") + "'";

                        // The resource constraints that slow growth rate.
                        #region Resource Constraints
                        if (tree.ResourceConstraints != null)
                        {
                            foreach (ResourceConstraint r in tree.ResourceConstraints)
                            {
                                if (r.LayerName == "Nitrogen")
                                {
                                    EveryTree[treeName]["nitrogenHalfSpeed"] = "'" + (r.HalfSpeedConcentration * 100).ToString("F0") + "'";
                                    EveryTree[treeName]["nitrogenContent"]   = "'" + (r.MaxResourceContent * 100).ToString("F0") + "'";
                                }
                                if (r.LayerName == "Phosphorus")
                                {
                                    EveryTree[treeName]["phosphorusHalfSpeed"] = "'" + (r.HalfSpeedConcentration * 100).ToString("F0") + "'";
                                    EveryTree[treeName]["phosphorusContent"]   = "'" + (r.MaxResourceContent * 100).ToString("F0") + "'";
                                }
                                if (r.LayerName == "Potassium")
                                {
                                    EveryTree[treeName]["potassiumHalfSpeed"] = "'" + (r.HalfSpeedConcentration * 100).ToString("F0") + "'";
                                    EveryTree[treeName]["potassiumContent"]   = "'" + (r.MaxResourceContent * 100).ToString("F0") + "'";
                                }
                                if (r.LayerName == "SoilMoisture")
                                {
                                    EveryTree[treeName]["soilMoistureHalfSpeed"] = "'" + (r.HalfSpeedConcentration * 100).ToString("F0") + "'";
                                    EveryTree[treeName]["soilMoistureContent"]   = "'" + (r.MaxResourceContent * 100).ToString("F0") + "'";
                                }
                            }
                        }
                        #endregion

                        // The capacity constraints which slow growth.
                        #region Capacity Constraints
                        if (tree.CapacityConstraints != null)
                        {
                            foreach (CapacityConstraint c in tree.CapacityConstraints)
                            {
                                if (c.CapacityLayerName == "FertileGorund")
                                {
                                    EveryTree[treeName]["consumedFertileGround"] = "'" + (c.ConsumedCapacityPerPop).ToString("F1") + "'";
                                }
                                if (c.CapacityLayerName == "CanopySpace")
                                {
                                    EveryTree[treeName]["consumedCanopySpace"] = "'" + (c.ConsumedCapacityPerPop).ToString("F1") + "'";
                                }
                                if (c.CapacityLayerName == "UnderwaterFertileGorund")
                                {
                                    EveryTree[treeName]["consumedUnderwaterFertileGround"] = "'" + (c.ConsumedCapacityPerPop).ToString("F1") + "'";
                                }
                                if (c.CapacityLayerName == "ShrubSpace")
                                {
                                    EveryTree[treeName]["consumedShrubSpace"] = "'" + (c.ConsumedCapacityPerPop).ToString("F1") + "'";
                                }
                            }
                        }
                        #endregion

                        // The environmental ranges this plant can tolerate.
                        #region Environment Ranges

                        // Temperature
                        EveryTree[treeName]["extremeTempMin"] = "'" + tree.TemperatureExtremes.Min.ToString("F1") + "'";
                        EveryTree[treeName]["idealTempMin"]   = "'" + tree.IdealTemperatureRange.Min.ToString("F1") + "'";
                        EveryTree[treeName]["idealTempMax"]   = "'" + tree.IdealTemperatureRange.Max.ToString("F1") + "'";
                        EveryTree[treeName]["extremeTempMax"] = "'" + tree.TemperatureExtremes.Max.ToString("F1") + "'";

                        // Moisture
                        EveryTree[treeName]["extremeMoistureMin"] = "'" + tree.MoistureExtremes.Min.ToString("F1") + "'";
                        EveryTree[treeName]["idealMoistureMin"]   = "'" + tree.IdealMoistureRange.Min.ToString("F1") + "'";
                        EveryTree[treeName]["idealMoistureMax"]   = "'" + tree.IdealMoistureRange.Max.ToString("F1") + "'";
                        EveryTree[treeName]["extremeMoistureMax"] = "'" + tree.MoistureExtremes.Max.ToString("F1") + "'";

                        // Salt Content
                        EveryTree[treeName]["extremeSaltMin"] = "'" + tree.WaterExtremes.Min.ToString("F1") + "'";
                        EveryTree[treeName]["idealSaltMin"]   = "'" + tree.IdealWaterRange.Min.ToString("F1") + "'";
                        EveryTree[treeName]["idealSaltMax"]   = "'" + tree.IdealWaterRange.Max.ToString("F1") + "'";
                        EveryTree[treeName]["extremeSaltMax"] = "'" + tree.WaterExtremes.Max.ToString("F1") + "'";

                        #endregion

                        EveryTree[treeName]["maxPollutionDensity"] = "'" + tree.MaxPollutionDensity.ToString("F4") + "'";
                        EveryTree[treeName]["pollutionTolerance"]  = "'" + tree.PollutionDensityTolerance.ToString("F4") + "'";

                        #endregion

                        #region UNCATEGORISED
                        #endregion

                        #region OBSOLETE
                        #endregion
                    }
                }
            }
            WriteDictionaryToFile("Wiki_Module_TreeData.txt", "trees", EveryTree);
        }
Example #18
0
 public LandscapeRemovalData(TreeSpecies treeSpecies)
 {
     this.TreeSpecies = treeSpecies;
     this.Zero();
 }
Example #19
0
 public WoodenStep(TreeSpecies species, bool inv) : this()
 {
     Species  = species;
     Inverted = inv;
 }
Example #20
0
 public WoodenStep(TreeSpecies species) : this()
 {
     Species = species;
 }
Example #21
0
 public Tree(TreeSpecies species, BlockFace dir) : this()
 {
     Species = species;
     SetDirection(dir);
 }
Example #22
0
        private static void VerifyMalcolmKnappDouglasFir(Model model)
        {
            TreeSpecies douglasFir = model.Landscape.ResourceUnits[0].Trees.TreeSpeciesSet[0];

            Assert.IsTrue(douglasFir.Active);
            Assert.IsTrue(String.Equals(douglasFir.ID, "psme", StringComparison.Ordinal));
            // maximumHeight   100
            // aging   1 / (1 + (x/0.95)^4)
            // douglasFir.Aging();
            // barkThickness   0.065
            // bmWoody_a   0.10568
            // bmWoody_b   2.4247
            // bmFoliage_a 0.05226
            // bmFoliage_b 1.7009
            // bmRoot_a    0.0418
            // bmRoot_b    2.33
            // bmBranch_a  0.04004
            // bmBranch_b  2.1382
            Assert.IsTrue(MathF.Abs(douglasFir.CNRatioFineRoot - 9.0F) < 0.001F);
            Assert.IsTrue(MathF.Abs(douglasFir.CNRatioFoliage - 60.3F) < 0.001F);
            Assert.IsTrue(MathF.Abs(douglasFir.CNRatioWood - 452.0F) < 0.001F);
            Assert.IsTrue(MathF.Abs(douglasFir.DeathProbabilityFixed - 0.00355005264F) < 0.000001F); // transformed from 0.67
            // probStress  6.9
            // displayColor D6F288
            Assert.IsTrue(douglasFir.EstablishmentParameters.ChillRequirement == 30);
            Assert.IsTrue(MathF.Abs(douglasFir.EstablishmentParameters.FrostTolerance - 0.5F) < 0.001);
            Assert.IsTrue(MathF.Abs(douglasFir.EstablishmentParameters.GrowingDegreeDaysBaseTemperature - 3.4F) < 0.001F);
            Assert.IsTrue(douglasFir.EstablishmentParameters.GddBudBurst == 255);
            Assert.IsTrue(douglasFir.EstablishmentParameters.MaximumGrowingDegreeDays == 3261);
            Assert.IsTrue(douglasFir.EstablishmentParameters.MinimumGrowingDegreeDays == 177);
            Assert.IsTrue(douglasFir.EstablishmentParameters.MinimumFrostFreeDays == 65);
            Assert.IsTrue(MathF.Abs(douglasFir.EstablishmentParameters.MinTemp + 37.0F) < 0.001F);
            Assert.IsTrue(Single.IsNaN(douglasFir.EstablishmentParameters.PsiMin));
            Assert.IsTrue(MathF.Abs(douglasFir.FecundityM2 - 20.0F) < 0.001F);
            Assert.IsTrue(MathF.Abs(douglasFir.FecunditySerotiny - 0.0F) < 0.001F);
            Assert.IsTrue(MathF.Abs(douglasFir.FinerootFoliageRatio - 1.0F) < 0.001F);
            // HDlow   145.0998 * 1 * 0.8 * (1 - 0.28932) * d ^ -0.28932
            // HDhigh  100 / d + 25 + 100 * exp(-0.3 * (0.08 * d) ^ 1.5) + 120 * exp(-0.01 * d)
            Assert.IsTrue(String.Equals(douglasFir.ID, "psme", StringComparison.OrdinalIgnoreCase));
            Assert.IsTrue(douglasFir.Index == 0);
            Assert.IsTrue(douglasFir.IsConiferous == true);
            Assert.IsTrue(douglasFir.IsEvergreen == true);
            Assert.IsTrue(douglasFir.IsSeedYear == false);
            Assert.IsTrue(douglasFir.IsTreeSerotinousRandom(model.RandomGenerator, 40) == false);
            // lightResponseClass  2.78
            Assert.IsTrue(Math.Abs(douglasFir.MaxCanopyConductance - 0.017) < 0.001);
            Assert.IsTrue(String.Equals(douglasFir.Name, "Pseudotsuga menziesii", StringComparison.OrdinalIgnoreCase));
            Assert.IsTrue(Math.Abs(douglasFir.NonSeedYearFraction - 0.25) < 0.001);
            Assert.IsTrue(douglasFir.PhenologyClass == 0);
            Assert.IsTrue(Math.Abs(douglasFir.MinimumSoilWaterPotential + 1.234) < 0.001);
            // respNitrogenClass   2
            // respTempMax 20
            // respTempMin 0
            // respVpdExponent - 0.6
            // maturityYears   14
            // seedYearInterval    5
            // nonSeedYearFraction 0.25
            // seedKernel_as1  30
            // seedKernel_as2  200
            // seedKernel_ks0  0.2
            Assert.IsTrue(MathF.Abs(douglasFir.SaplingGrowthParameters.BrowsingProbability - 0.5F) < 0.001F);
            Assert.IsTrue(MathF.Abs(douglasFir.SaplingGrowthParameters.HeightDiameterRatio - 112.0F) < 0.001F);
            Assert.IsTrue(String.Equals(douglasFir.SaplingGrowthParameters.HeightGrowthPotential.ExpressionString, "1.2*72.2*(1-(1-(h/72.2)^(1/3))*exp(-0.0427))^3", StringComparison.OrdinalIgnoreCase));
            Assert.IsTrue(douglasFir.SaplingGrowthParameters.MaxStressYears == 2);
            Assert.IsTrue(MathF.Abs(douglasFir.SaplingGrowthParameters.ReferenceRatio - 0.503F) < 0.001F);
            Assert.IsTrue(MathF.Abs(douglasFir.SaplingGrowthParameters.ReinekeR - 164.0F) < 0.001F);
            Assert.IsTrue(douglasFir.SaplingGrowthParameters.RepresentedClasses.Count == 41);
            Assert.IsTrue(Single.IsNaN(douglasFir.SaplingGrowthParameters.SproutGrowth));
            Assert.IsTrue(MathF.Abs(douglasFir.SaplingGrowthParameters.StressThreshold - 0.1F) < 0.001F);
            Assert.IsTrue(douglasFir.SeedDispersal == null);
            // Assert.IsTrue(String.Equals(douglasFir.SeedDispersal.DumpNextYearFileName, null, StringComparison.OrdinalIgnoreCase));
            // Assert.IsTrue(douglasFir.SeedDispersal.SeedMap == null);
            // Assert.IsTrue(Object.ReferenceEquals(douglasFir.SeedDispersal.Species, douglasFir));
            Assert.IsTrue(douglasFir.SnagHalflife == 20);
            Assert.IsTrue(MathF.Abs(douglasFir.SnagDecompositionRate - 0.04F) < 0.001F);
            Assert.IsTrue(MathF.Abs(douglasFir.LitterDecompositionRate - 0.22F) < 0.001F);
            Assert.IsTrue(MathF.Abs(douglasFir.CoarseWoodyDebrisDecompositionRate - 0.08F) < 0.001F);
            Assert.IsTrue(MathF.Abs(douglasFir.SpecificLeafArea - 5.80F) < 0.001F);
            Assert.IsTrue(MathF.Abs(douglasFir.TurnoverLeaf - 0.2F) < 0.001F);
            Assert.IsTrue(MathF.Abs(douglasFir.TurnoverFineRoot - 0.33F) < 0.001F);
            Assert.IsTrue(MathF.Abs(douglasFir.VolumeFactor - 0.353429F) < 0.001F); // 0.45 * pi/4
            Assert.IsTrue(MathF.Abs(douglasFir.WoodDensity - 450.0F) < 0.001F);

            foreach (ResourceUnit ru in model.Landscape.ResourceUnits)
            {
                Assert.IsTrue(Object.ReferenceEquals(douglasFir.SpeciesSet, ru.Trees.TreeSpeciesSet));
                Assert.IsTrue(ru.Trees.TreeSpeciesSet.Count == 11);
                Assert.IsTrue(Object.ReferenceEquals(douglasFir, ru.Trees.TreeSpeciesSet.ActiveSpecies[0]));
            }
        }
Example #23
0
 void SetSpecies(TreeSpecies newSpecies)
 {
     species = newSpecies;
 }