1 /*
2 Minetest
3 Copyright (C) 2014-2020 paramat
4 Copyright (C) 2014-2016 kwolekr, Ryan Kwolek <kwolekr@minetest.net>
5 
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU Lesser General Public License for more details.
15 
16 You should have received a copy of the GNU Lesser General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20 
21 #pragma once
22 
23 #include "objdef.h"
24 #include "nodedef.h"
25 #include "noise.h"
26 
27 class Server;
28 class Settings;
29 class BiomeManager;
30 
31 ////
32 //// Biome
33 ////
34 
35 typedef u16 biome_t;
36 
37 #define BIOME_NONE ((biome_t)0)
38 
39 enum BiomeType {
40 	BIOMETYPE_NORMAL,
41 };
42 
43 class Biome : public ObjDef, public NodeResolver {
44 public:
45 	ObjDef *clone() const;
46 
47 	u32 flags;
48 
49 	content_t c_top;
50 	content_t c_filler;
51 	content_t c_stone;
52 	content_t c_water_top;
53 	content_t c_water;
54 	content_t c_river_water;
55 	content_t c_riverbed;
56 	content_t c_dust;
57 	std::vector<content_t> c_cave_liquid;
58 	content_t c_dungeon;
59 	content_t c_dungeon_alt;
60 	content_t c_dungeon_stair;
61 
62 	s16 depth_top;
63 	s16 depth_filler;
64 	s16 depth_water_top;
65 	s16 depth_riverbed;
66 
67 	v3s16 min_pos;
68 	v3s16 max_pos;
69 	float heat_point;
70 	float humidity_point;
71 	s16 vertical_blend;
72 
73 	virtual void resolveNodeNames();
74 };
75 
76 
77 ////
78 //// BiomeGen
79 ////
80 
81 enum BiomeGenType {
82 	BIOMEGEN_ORIGINAL,
83 };
84 
85 struct BiomeParams {
86 	virtual void readParams(const Settings *settings) = 0;
87 	virtual void writeParams(Settings *settings) const = 0;
88 	virtual ~BiomeParams() = default;
89 
90 	s32 seed;
91 };
92 
93 // WARNING: this class is not thread-safe
94 class BiomeGen {
95 public:
96 	virtual ~BiomeGen() = default;
97 
98 	virtual BiomeGenType getType() const = 0;
99 
100 	// Calculates the biome at the exact position provided.  This function can
101 	// be called at any time, but may be less efficient than the latter methods,
102 	// depending on implementation.
103 	virtual Biome *calcBiomeAtPoint(v3s16 pos) const = 0;
104 
105 	// Computes any intermediate results needed for biome generation.  Must be
106 	// called before using any of: getBiomes, getBiomeAtPoint, or getBiomeAtIndex.
107 	// Calling this invalidates the previous results stored in biomemap.
108 	virtual void calcBiomeNoise(v3s16 pmin) = 0;
109 
110 	// Gets all biomes in current chunk using each corresponding element of
111 	// heightmap as the y position, then stores the results by biome index in
112 	// biomemap (also returned)
113 	virtual biome_t *getBiomes(s16 *heightmap, v3s16 pmin) = 0;
114 
115 	// Gets a single biome at the specified position, which must be contained
116 	// in the region formed by m_pmin and (m_pmin + m_csize - 1).
117 	virtual Biome *getBiomeAtPoint(v3s16 pos) const = 0;
118 
119 	// Same as above, but uses a raw numeric index correlating to the (x,z) position.
120 	virtual Biome *getBiomeAtIndex(size_t index, v3s16 pos) const = 0;
121 
122 	// Result of calcBiomes bulk computation.
123 	biome_t *biomemap = nullptr;
124 
125 protected:
126 	BiomeManager *m_bmgr = nullptr;
127 	v3s16 m_pmin;
128 	v3s16 m_csize;
129 };
130 
131 
132 ////
133 //// BiomeGen implementations
134 ////
135 
136 //
137 // Original biome algorithm (Whittaker's classification + surface height)
138 //
139 
140 struct BiomeParamsOriginal : public BiomeParams {
BiomeParamsOriginalBiomeParamsOriginal141 	BiomeParamsOriginal() :
142 		np_heat(50, 50, v3f(1000.0, 1000.0, 1000.0), 5349, 3, 0.5, 2.0),
143 		np_humidity(50, 50, v3f(1000.0, 1000.0, 1000.0), 842, 3, 0.5, 2.0),
144 		np_heat_blend(0, 1.5, v3f(8.0, 8.0, 8.0), 13, 2, 1.0, 2.0),
145 		np_humidity_blend(0, 1.5, v3f(8.0, 8.0, 8.0), 90003, 2, 1.0, 2.0)
146 	{
147 	}
148 
149 	virtual void readParams(const Settings *settings);
150 	virtual void writeParams(Settings *settings) const;
151 
152 	NoiseParams np_heat;
153 	NoiseParams np_humidity;
154 	NoiseParams np_heat_blend;
155 	NoiseParams np_humidity_blend;
156 };
157 
158 class BiomeGenOriginal : public BiomeGen {
159 public:
160 	BiomeGenOriginal(BiomeManager *biomemgr,
161 		BiomeParamsOriginal *params, v3s16 chunksize);
162 	virtual ~BiomeGenOriginal();
163 
getType()164 	BiomeGenType getType() const { return BIOMEGEN_ORIGINAL; }
165 
166 	Biome *calcBiomeAtPoint(v3s16 pos) const;
167 	void calcBiomeNoise(v3s16 pmin);
168 
169 	biome_t *getBiomes(s16 *heightmap, v3s16 pmin);
170 	Biome *getBiomeAtPoint(v3s16 pos) const;
171 	Biome *getBiomeAtIndex(size_t index, v3s16 pos) const;
172 
173 	Biome *calcBiomeFromNoise(float heat, float humidity, v3s16 pos) const;
174 
175 	float *heatmap;
176 	float *humidmap;
177 
178 private:
179 	BiomeParamsOriginal *m_params;
180 
181 	Noise *noise_heat;
182 	Noise *noise_humidity;
183 	Noise *noise_heat_blend;
184 	Noise *noise_humidity_blend;
185 };
186 
187 
188 ////
189 //// BiomeManager
190 ////
191 
192 class BiomeManager : public ObjDefManager {
193 public:
194 	BiomeManager(Server *server);
195 	virtual ~BiomeManager() = default;
196 
197 	BiomeManager *clone() const;
198 
getObjectTitle()199 	const char *getObjectTitle() const
200 	{
201 		return "biome";
202 	}
203 
create(BiomeType type)204 	static Biome *create(BiomeType type)
205 	{
206 		return new Biome;
207 	}
208 
createBiomeGen(BiomeGenType type,BiomeParams * params,v3s16 chunksize)209 	BiomeGen *createBiomeGen(BiomeGenType type, BiomeParams *params, v3s16 chunksize)
210 	{
211 		switch (type) {
212 		case BIOMEGEN_ORIGINAL:
213 			return new BiomeGenOriginal(this,
214 				(BiomeParamsOriginal *)params, chunksize);
215 		default:
216 			return NULL;
217 		}
218 	}
219 
createBiomeParams(BiomeGenType type)220 	static BiomeParams *createBiomeParams(BiomeGenType type)
221 	{
222 		switch (type) {
223 		case BIOMEGEN_ORIGINAL:
224 			return new BiomeParamsOriginal;
225 		default:
226 			return NULL;
227 		}
228 	}
229 
230 	virtual void clear();
231 
232 	// For BiomeGen type 'BiomeGenOriginal'
233 	float getHeatAtPosOriginal(v3s16 pos, NoiseParams &np_heat,
234 		NoiseParams &np_heat_blend, u64 seed) const;
235 	float getHumidityAtPosOriginal(v3s16 pos, NoiseParams &np_humidity,
236 		NoiseParams &np_humidity_blend, u64 seed) const;
237 	const Biome *getBiomeFromNoiseOriginal(float heat, float humidity,
238 		v3s16 pos) const;
239 
240 private:
BiomeManager()241 	BiomeManager() {};
242 
243 	Server *m_server;
244 
245 };
246