c66c2494c405fd6a844e3b47ef3249772c7c2ab3
[oweals/minetest.git] / src / biome.cpp
1 /*
2 Minetest-c55
3 Copyright (C) 2010-2011 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 "main.h"
24
25 #define BT_NONE                 0
26 #define BT_OCEAN                1
27 #define BT_LAKE                 2
28 #define BT_SBEACH               3
29 #define BT_GBEACH               4
30 #define BT_PLAINS               5
31 #define BT_HILLS                6
32 #define BT_EXTREMEHILLS 7
33 #define BT_MOUNTAINS    8
34 #define BT_DESERT               9
35 #define BT_DESERTHILLS  10
36 #define BT_HELL                 11
37 #define BT_AETHER               12
38
39 #define BT_BTMASK               0x3F
40
41 #define BTF_SNOW                0x40
42 #define BTF_FOREST              0x80
43
44 #define BGFREQ_1 (           0.40)
45 #define BGFREQ_2 (BGFREQ_1 + 0.05)
46 #define BGFREQ_3 (BGFREQ_2 + 0.08)
47 #define BGFREQ_4 (BGFREQ_3 + 0.35)
48 #define BGFREQ_5 (BGFREQ_4 + 0.18)
49 //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.
50
51
52 /*float bg1_temps[] = {0.0};
53 int bg1_biomes[]  = {BT_OCEAN};
54
55 float bg2_temps[] = {10.0};
56 int bg2_biomes[]  = {BT_GBEACH, BT_SBEACH};
57
58 float bg3_temps[] = {30.0, 40.0};
59 int bg3_biomes[]  = {BT_HILLS, BT_EXTREMEHILLS, BT_MOUNTAINS};
60
61 float bg4_temps[] = {25.0, 30.0, 35.0, 40.0};
62 int bg4_biomes[]  = {BT_HILLS, BT_EXTREMEHILLS, BT_MOUNTAINS, BT_DESERT, BT_DESERTHILLS};
63
64 float bg5_temps[] = {5.0, 40.0};
65 int bg5_biomes[]  = {BT_LAKE, BT_PLAINS, BT_DESERT};*/
66
67 NoiseParams np_default = {0.0, 20.0, v3f(250., 250., 250.), 82341, 5, 0.6};
68
69
70 BiomeDefManager::BiomeDefManager(IGameDef *gamedef) {
71         this->m_gamedef = gamedef;
72         this->ndef      = gamedef->ndef();
73
74         bgroups.push_back(new std::vector<Biome *>); //the initial biome group
75         //addDefaultBiomes(); //can't do this in the ctor, too early
76 }
77
78
79 BiomeDefManager::~BiomeDefManager() {
80         for (int i = 0; i != bgroups.size(); i++)
81                 delete bgroups[i];
82 }
83
84
85 Biome *BiomeDefManager::createBiome(BiomeTerrainType btt) {
86         switch (btt) {
87                 case BIOME_TERRAIN_NORMAL:
88                         return new Biome;
89                 case BIOME_TERRAIN_LIQUID:
90                         return new BiomeLiquid;
91                 case BIOME_TERRAIN_NETHER:
92                         return new BiomeHell;
93                 case BIOME_TERRAIN_AETHER:
94                         return new BiomeAether;
95                 case BIOME_TERRAIN_FLAT:
96                         return new BiomeSuperflat;
97         }
98 }
99
100
101 void BiomeDefManager::addBiomeGroup(float freq) {
102         int size = bgroup_freqs.size();
103         float newfreq = freq;
104
105         if (size)
106                 newfreq += bgroup_freqs[size - 1];
107         bgroup_freqs.push_back(newfreq);
108         bgroups.push_back(new std::vector<Biome *>);
109         printf("added biome with freq %f\n", newfreq);
110 }
111
112
113 void BiomeDefManager::addBiome(int groupid, Biome *b) {
114         std::vector<Biome *> *bgroup;
115
116         if (groupid >= bgroups.size()) {
117                 printf("blahblahblah");
118                 return;
119         }
120
121         bgroup = bgroups[groupid];
122         bgroup->push_back(b);
123 }
124
125
126 void BiomeDefManager::addDefaultBiomes() {
127         std::vector<Biome *> *bgroup;
128         Biome *b;
129
130         b = new Biome;
131         b->name         = "Default";
132         b->n_top        = MapNode(ndef->getId("mapgen_stone"));
133         b->n_filler     = b->n_top;
134         b->ntopnodes    = 0;
135         b->height_min   = -MAP_GENERATION_LIMIT;
136         b->height_max   = MAP_GENERATION_LIMIT;
137         b->heat_min     = FLT_MIN;
138         b->heat_max     = FLT_MAX;
139         b->humidity_min = FLT_MIN;
140         b->humidity_max = FLT_MAX;
141         b->np = &np_default;
142         biome_default = b;
143 }
144
145
146 Biome *BiomeDefManager::getBiome(float bgfreq, float heat, float humidity) {
147         std::vector<Biome *> *bgroup;
148         Biome *b;
149         int i;
150
151         int ngroups = bgroup_freqs.size();
152         if (!ngroups)
153                 return biome_default;
154         for (i = 0; (i != ngroups) && (bgfreq > bgroup_freqs[i]); i++);
155         bgroup = bgroups[i];
156
157         int nbiomes = bgroup->size();
158         for (i = 0; i != nbiomes; i++) {
159                 b = bgroup->operator[](i);///////////////////////////
160                 if (heat >= b->heat_min && heat <= b->heat_max &&
161                         humidity >= b->humidity_min && humidity <= b->humidity_max)
162                         return b;
163         }
164
165         return biome_default;
166 }
167
168
169 //////////////////////////// [ Generic biome ] ////////////////////////////////
170
171
172 int Biome::getSurfaceHeight(float noise_terrain) {
173         return np->offset + np->scale * noise_terrain;
174 }
175
176
177 void Biome::genColumn(Mapgen *mg, int x, int z, int y1, int y2) {
178         int i = (z - mg->node_min.Z) * mg->csize.Z + (x - mg->node_min.X);
179         int surfaceh = np->offset + np->scale * mg->map_terrain[i];
180         int y = y1;
181
182         i = mg->vmanip->m_area.index(x, y, z);
183         for (; y <= surfaceh - ntopnodes && y <= y2; y++, i += mg->ystride)
184                 mg->vmanip->m_data[i] = n_filler;
185         for (; y <= surfaceh && y <= y2; y++, i += mg->ystride)
186                 mg->vmanip->m_data[i] = n_top;
187         for (; y <= y2; y++, i += mg->ystride)
188                 mg->vmanip->m_data[i] = mg->n_air;
189 }
190
191
192
193 ///////////////////////////// [ Ocean biome ] /////////////////////////////////
194
195
196
197 void BiomeLiquid::genColumn(Mapgen *mg, int x, int z, int y1, int y2) {
198         int i = (z - mg->node_min.Z) * mg->csize.Z + (x - mg->node_min.X);
199         int surfaceh = np->offset + np->scale * mg->map_terrain[i];
200         int y = y1;
201
202         i = mg->vmanip->m_area.index(x, y, z);
203         for (; y <= surfaceh - ntopnodes && y <= y2; y++, i += mg->ystride)
204                 mg->vmanip->m_data[i] = n_filler;
205         for (; y <= surfaceh && y <= y2; y++, i += mg->ystride)
206                 mg->vmanip->m_data[i] = n_top;
207         for (; y <= mg->water_level && y <= y2; y++, i += mg->ystride)
208                 mg->vmanip->m_data[i] = mg->n_water;
209         for (; y <= y2; y++, i += mg->ystride)
210                 mg->vmanip->m_data[i] = mg->n_air;
211 }
212
213
214 ///////////////////////////// [ Nether biome ] /////////////////////////////////
215
216
217 int BiomeHell::getSurfaceHeight(float noise_terrain) {
218         return np->offset + np->scale * noise_terrain;
219 }
220
221
222 void BiomeHell::genColumn(Mapgen *mg, int x, int z, int y1, int y2) {
223
224 }
225
226
227 ///////////////////////////// [ Aether biome ] ////////////////////////////////
228
229
230 int BiomeAether::getSurfaceHeight(float noise_terrain) {
231         return np->offset + np->scale * noise_terrain;
232 }
233
234
235 void BiomeAether::genColumn(Mapgen *mg, int x, int z, int y1, int y2) {
236
237 }
238
239
240 /////////////////////////// [ Superflat biome ] ///////////////////////////////
241
242
243 int BiomeSuperflat::getSurfaceHeight(float noise_terrain) {
244         return ntopnodes;
245 }
246
247
248 void BiomeSuperflat::genColumn(Mapgen *mg, int x, int z, int y1, int y2) {
249
250 }