#pragma once #include "StarPerlin.hpp" #include "StarWeightedPool.hpp" #include "StarBiMap.hpp" #include "StarPlant.hpp" #include "StarTreasure.hpp" #include "StarStrongTypedef.hpp" namespace Star { STAR_CLASS(BiomeItemDistribution); STAR_EXCEPTION(BiomeException, StarException); typedef pair TreePair; // Weighted pairs of object name / parameters. typedef WeightedPool> ObjectPool; strong_typedef(String, TreasureBoxSet); strong_typedef(StringSet, MicroDungeonNames); typedef Variant BiomeItem; BiomeItem variantToBiomeItem(Json const& store); Json variantFromBiomeItem(BiomeItem const& biomeItem); enum class BiomePlacementArea { Surface, Underground }; enum class BiomePlacementMode { Floor, Ceiling, Background, Ocean }; extern EnumMap const BiomePlacementModeNames; struct BiomeItemPlacement { BiomeItemPlacement(BiomeItem item, Vec2I position, float priority); // Orders by priority bool operator<(BiomeItemPlacement const& rhs) const; BiomeItem item; Vec2I position; float priority; }; class BiomeItemDistribution { public: struct PeriodicWeightedItem { BiomeItem item; PerlinF weight; }; static Maybe createItem(Json const& itemSettings, RandomSource& rand, float biomeHueShift); BiomeItemDistribution(); BiomeItemDistribution(Json const& config, uint64_t seed, float biomeHueShift = 0.0f); BiomeItemDistribution(Json const& store); Json toJson() const; BiomePlacementMode mode() const; List allItems() const; // Returns the best BiomeItem for this position out of the weighted item set, // if the density function specifies that an item should go in this position. Maybe itemToPlace(int x, int y) const; private: enum class DistributionType { // Pure random distribution Random, // Uses perlin noise to morph a periodic function into a less predictable // periodic clumpy noise. Periodic }; static EnumMap const DistributionTypeNames; BiomePlacementMode m_mode; DistributionType m_distribution; float m_priority; // Used if the distribution type is Random float m_blockProbability; uint64_t m_blockSeed; List m_randomItems; // Used if the distribution type is Periodic PerlinF m_densityFunction; PerlinF m_modulusDistortion; int m_modulus; int m_modulusOffset; // Pairs items with a periodic weight. Weight will vary over the space of // the distribution, If multiple items are present, this can be used to // select one of the items (with the highest weight) out of a list of items, // causing items to be grouped spatially in a way determined by the shape of // each weight function. List> m_weightedItems; }; }