Re-add jungles, apple trees
[oweals/minetest.git] / src / biome.cpp
1 /*
2 Minetest
3 Copyright (C) 2010-2013 kwolekr, Ryan Kwolek <kwolekr2@cs.scranton.edu>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "biome.h"
21 #include "nodedef.h"
22 #include "map.h" //for ManualMapVoxelManipulator
23 #include "log.h"
24 #include "main.h"
25
26 #define BT_NONE                 0
27 #define BT_OCEAN                1
28 #define BT_LAKE                 2
29 #define BT_SBEACH               3
30 #define BT_GBEACH               4
31 #define BT_PLAINS               5
32 #define BT_HILLS                6
33 #define BT_EXTREMEHILLS 7
34 #define BT_MOUNTAINS    8
35 #define BT_DESERT               9
36 #define BT_DESERTHILLS  10
37 #define BT_HELL                 11
38 #define BT_AETHER               12
39
40 #define BT_BTMASK               0x3F
41
42 #define BTF_SNOW                0x40
43 #define BTF_FOREST              0x80
44
45 #define BGFREQ_1 (           0.40)
46 #define BGFREQ_2 (BGFREQ_1 + 0.05)
47 #define BGFREQ_3 (BGFREQ_2 + 0.08)
48 #define BGFREQ_4 (BGFREQ_3 + 0.35)
49 #define BGFREQ_5 (BGFREQ_4 + 0.18)
50 //BGFREQ_5 is not checked as an upper bound; it ought to sum up to 1.00, but it's okay if it doesn't.
51
52
53 /*float bg1_temps[] = {0.0};
54 int bg1_biomes[]  = {BT_OCEAN};
55
56 float bg2_temps[] = {10.0};
57 int bg2_biomes[]  = {BT_GBEACH, BT_SBEACH};
58
59 float bg3_temps[] = {30.0, 40.0};
60 int bg3_biomes[]  = {BT_HILLS, BT_EXTREMEHILLS, BT_MOUNTAINS};
61
62 float bg4_temps[] = {25.0, 30.0, 35.0, 40.0};
63 int bg4_biomes[]  = {BT_HILLS, BT_EXTREMEHILLS, BT_MOUNTAINS, BT_DESERT, BT_DESERTHILLS};
64
65 float bg5_temps[] = {5.0, 40.0};
66 int bg5_biomes[]  = {BT_LAKE, BT_PLAINS, BT_DESERT};*/
67
68 NoiseParams np_default = {20.0, 15.0, v3f(250., 250., 250.), 82341, 5, 0.6};
69
70
71 BiomeDefManager::BiomeDefManager(IGameDef *gamedef) {
72         this->m_gamedef = gamedef;
73         this->ndef      = gamedef->ndef();
74
75         //the initial biome group
76         bgroups.push_back(new std::vector<Biome *>);
77 }
78
79
80 BiomeDefManager::~BiomeDefManager() {
81         for (unsigned int i = 0; i != bgroups.size(); i++)
82                 delete bgroups[i];
83 }
84
85
86 Biome *BiomeDefManager::createBiome(BiomeTerrainType btt) {
87         switch (btt) {
88                 case BIOME_TERRAIN_NORMAL:
89                         return new Biome;
90                 case BIOME_TERRAIN_LIQUID:
91                         return new BiomeLiquid;
92                 case BIOME_TERRAIN_NETHER:
93                         return new BiomeHell;
94                 case BIOME_TERRAIN_AETHER:
95                         return new BiomeAether;
96                 case BIOME_TERRAIN_FLAT:
97                         return new BiomeSuperflat;
98         }
99         return NULL;
100 }
101
102
103 void BiomeDefManager::addBiomeGroup(float freq) {
104         int size = bgroup_freqs.size();
105         float newfreq = freq;
106
107         if (size)
108                 newfreq += bgroup_freqs[size - 1];
109         bgroup_freqs.push_back(newfreq);
110         bgroups.push_back(new std::vector<Biome *>);
111
112         verbosestream << "BiomeDefManager: added biome group with frequency " <<
113                 newfreq << std::endl;
114 }
115
116
117 void BiomeDefManager::addBiome(Biome *b) {
118         std::vector<Biome *> *bgroup;
119
120         if ((unsigned int)b->groupid >= bgroups.size()) {
121                 errorstream << "BiomeDefManager: attempted to add biome '" << b->name
122                  << "' to nonexistent biome group " << b->groupid << std::endl;
123                 return;
124         }
125
126         bgroup = bgroups[b->groupid];
127         bgroup->push_back(b);
128
129         verbosestream << "BiomeDefManager: added biome '" << b->name <<
130                 "' to biome group " << (int)b->groupid << std::endl;
131 }
132
133
134 void BiomeDefManager::addDefaultBiomes() {
135         Biome *b;
136
137         b = new Biome;
138         b->name         = "Default";
139         b->n_top        = MapNode(ndef->getId("mapgen_stone"));
140         b->n_filler     = b->n_top;
141         b->ntopnodes    = 0;
142         b->height_min   = -MAP_GENERATION_LIMIT;
143         b->height_max   = MAP_GENERATION_LIMIT;
144         b->heat_min     = FLT_MIN;
145         b->heat_max     = FLT_MAX;
146         b->humidity_min = FLT_MIN;
147         b->humidity_max = FLT_MAX;
148         b->np = &np_default;
149         biome_default = b;
150 }
151
152
153 Biome *BiomeDefManager::getBiome(float bgfreq, float heat, float humidity) {
154         std::vector<Biome *> *bgroup;
155         Biome *b;
156         int i;
157
158         int ngroups = bgroup_freqs.size();
159         if (!ngroups)
160                 return biome_default;
161         for (i = 0; (i != ngroups) && (bgfreq > bgroup_freqs[i]); i++);
162         bgroup = bgroups[i];
163
164         int nbiomes = bgroup->size();
165         for (i = 0; i != nbiomes; i++) {
166                 b = bgroup->operator[](i);
167                 if (heat >= b->heat_min && heat <= b->heat_max &&
168                         humidity >= b->humidity_min && humidity <= b->humidity_max)
169                         return b;
170         }
171
172         return biome_default;
173 }
174
175
176 //////////////////////////// [ Generic biome ] ////////////////////////////////
177
178
179 int Biome::getSurfaceHeight(float noise_terrain) {
180         return np->offset + np->scale * noise_terrain;
181 }
182
183
184 void Biome::genColumn(Mapgen *mapgen, int x, int z, int y1, int y2) {
185
186 }
187
188
189 ///////////////////////////// [ Ocean biome ] /////////////////////////////////
190
191
192 void BiomeLiquid::genColumn(Mapgen *mapgen, int x, int z, int y1, int y2) {
193
194 }
195
196
197 ///////////////////////////// [ Nether biome ] /////////////////////////////////
198
199
200 int BiomeHell::getSurfaceHeight(float noise_terrain) {
201         return np->offset + np->scale * noise_terrain;
202 }
203
204
205 void BiomeHell::genColumn(Mapgen *mapgen, int x, int z, int y1, int y2) {
206
207 }
208
209
210 ///////////////////////////// [ Aether biome ] ////////////////////////////////
211
212
213 int BiomeAether::getSurfaceHeight(float noise_terrain) {
214         return np->offset + np->scale * noise_terrain;
215 }
216
217
218 void BiomeAether::genColumn(Mapgen *mapgen, int x, int z, int y1, int y2) {
219
220 }
221
222
223 /////////////////////////// [ Superflat biome ] ///////////////////////////////
224
225
226 int BiomeSuperflat::getSurfaceHeight(float noise_terrain) {
227         return ntopnodes;
228 }
229
230
231 void BiomeSuperflat::genColumn(Mapgen *mapgen, int x, int z, int y1, int y2) {
232
233 }