Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/game/StarBiomePlacement.hpp
blob: d572a6013347f20b1edf83c7b8086e1aab18334c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#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<TreeVariant, TreeVariant> TreePair;

// Weighted pairs of object name / parameters.
typedef WeightedPool<pair<String, Json>> ObjectPool;

strong_typedef(String, TreasureBoxSet);
strong_typedef(StringSet, MicroDungeonNames);

typedef Variant<GrassVariant, BushVariant, TreePair, ObjectPool, TreasureBoxSet, MicroDungeonNames> 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<BiomePlacementMode> 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<BiomeItem> 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<BiomeItem> 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<BiomeItemPlacement> 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<DistributionType> 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<BiomeItem> 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<pair<BiomeItem, PerlinF>> m_weightedItems;
};

}