]> git.jsancho.org Git - lugaru.git/blob - Source/Terrain.cpp
b0aff61581df56406c7c174de27d4fa09bf620cb
[lugaru.git] / Source / Terrain.cpp
1 /*
2 Copyright (C) 2003, 2010 - Wolfire Games
3
4 This file is part of Lugaru.
5
6 Lugaru is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 Lugaru 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 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "Game.h"
21 #include "Terrain.h"
22 #include "Objects.h"
23 extern XYZ viewer;
24 extern float viewdistance;
25 extern float fadestart;
26 extern int environment;
27 extern float texscale;
28 extern Light light;
29 extern float multiplier;
30 extern FRUSTUM frustum;
31 extern float texdetail;
32 extern int detail;
33 extern bool decals;
34 extern float blurness;
35 extern float targetblurness;
36 extern Objects objects;
37 extern TGAImageRec texture;
38 extern bool visibleloading;
39 extern bool skyboxtexture;
40 extern int tutoriallevel;
41
42 //Functions
43
44 int Terrain::lineTerrain(XYZ p1, XYZ p2, XYZ *p)
45 {
46     static int i, j, k;
47     static float distance;
48     static float olddistance;
49     static int intersecting;
50     static int firstintersecting;
51     static XYZ point;
52     static int startx, starty;
53     static int endx, endy;
54     static float highest, lowest;
55
56     firstintersecting = -1;
57     olddistance = 10000;
58     distance = 1;
59
60     XYZ triangles[3];
61
62     p1 /= scale;
63     p2 /= scale;
64
65     startx = p1.x;
66     starty = p1.z;
67     endx = p2.x;
68     endy = p2.z;
69
70     if (startx > endx) {
71         i = endx;
72         endx = startx;
73         startx = i;
74     }
75     if (starty > endy) {
76         i = endy;
77         endy = starty;
78         starty = i;
79     }
80
81     if (startx < 0)
82         startx = 0;
83     if (starty < 0)
84         starty = 0;
85     if (endx > size - 1)
86         endx = size - 1;
87     if (endy > size - 1)
88         endy = size - 1;
89
90     for (i = startx; i <= endx; i++) {
91         for (j = starty; j <= endy; j++) {
92             highest = -1000;
93             lowest = 1000;
94             for (k = 0; k < 2; k++) {
95                 if (heightmap[i + k][j] > highest)
96                     highest = heightmap[i + k][j];
97                 if (heightmap[i + k][j] < lowest)
98                     lowest = heightmap[i + k][j];
99                 if (heightmap[i + k][j + 1] > highest)
100                     highest = heightmap[i + k][j + 1];
101                 if (heightmap[i + k][j + 1] < lowest)
102                     lowest = heightmap[i + k][j + 1];
103             }
104             if ((p1.y <= highest || p2.y <= highest) && (p1.y >= lowest || p2.y >= lowest)) {
105                 triangles[0].x = i;
106                 triangles[0].y = heightmap[i][j];
107                 triangles[0].z = j;
108
109                 triangles[1].x = i;
110                 triangles[1].y = heightmap[i][j + 1];
111                 triangles[1].z = j + 1;
112
113                 triangles[2].x = i + 1;
114                 triangles[2].y = heightmap[i + 1][j];
115                 triangles[2].z = j;
116
117                 intersecting = LineFacet(p1, p2, triangles[0], triangles[1], triangles[2], &point);
118                 distance = distsq(&p1, &point);
119                 if ((distance < olddistance || firstintersecting == -1) && intersecting == 1) {
120                     olddistance = distance;
121                     firstintersecting = 1;
122                     *p = point;
123                 }
124
125                 triangles[0].x = i + 1;
126                 triangles[0].y = heightmap[i + 1][j];
127                 triangles[0].z = j;
128
129                 triangles[1].x = i;
130                 triangles[1].y = heightmap[i][j + 1];
131                 triangles[1].z = j + 1;
132
133                 triangles[2].x = i + 1;
134                 triangles[2].y = heightmap[i + 1][j + 1];
135                 triangles[2].z = j + 1;
136
137                 intersecting = LineFacet(p1, p2, triangles[0], triangles[1], triangles[2], &point);
138                 distance = distsq(&p1, &point);
139                 if ((distance < olddistance || firstintersecting == -1) && intersecting == 1) {
140                     olddistance = distance;
141                     firstintersecting = 1;
142                     *p = point;
143                 }
144             }
145         }
146     }
147     return firstintersecting;
148 }
149
150 void Terrain::UpdateTransparency(int whichx, int whichy)
151 {
152     static XYZ vertex;
153     static int i, j, a, b, c, d, patch_size, stepsize;
154     static float distance;
155
156     static float viewdistsquared;
157
158     viewdistsquared = viewdistance * viewdistance;
159     patch_size = size / subdivision;
160
161     stepsize = 1;
162     c = whichx * patch_elements + whichy * patch_elements * subdivision;
163
164     for (i = patch_size * whichx; i < patch_size * (whichx + 1) + 1; i += stepsize) {
165         for (j = patch_size * whichy; j < patch_size * (whichy + 1) + 1; j += stepsize) {
166             if (i < size && j < size) {
167                 vertex.x = i * scale;
168                 vertex.z = j * scale;
169                 vertex.y = heightmap[i][j] * scale;
170                 distance = distsq(&viewer, &vertex);
171                 if (distance > viewdistsquared)
172                     distance = viewdistsquared;
173                 colors[i][j][3] = (viewdistsquared - (distance - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
174             }
175         }
176     }
177
178     for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) {
179         for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) {
180             a = (i - (patch_size * whichx)) / stepsize;
181             b = (j - (patch_size * whichy)) / stepsize;
182             d = (a * 54) + (b * 54 * patch_size / stepsize);
183             vArray[d + c + 6] = colors[i][j][3];
184
185             vArray[d + c + 15] = colors[i][j + stepsize][3];
186
187             vArray[d + c + 24] = colors[i + stepsize][j][3];
188
189             vArray[d + c + 33] = colors[i + stepsize][j][3];
190
191             vArray[d + c + 42] = colors[i][j + stepsize][3];
192
193             vArray[d + c + 51] = colors[i + stepsize][j + stepsize][3];
194         }
195     }
196 }
197
198 void Terrain::UpdateTransparencyother(int whichx, int whichy)
199 {
200     static XYZ vertex;
201     static int i, j, a, b, c, d, patch_size, stepsize;
202
203     patch_size = size / subdivision;
204
205     stepsize = 1;
206     c = whichx * patch_elements + whichy * patch_elements * subdivision;
207
208     for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) {
209         for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) {
210             a = (i - (patch_size * whichx)) / stepsize;
211             b = (j - (patch_size * whichy)) / stepsize;
212             d = (a * 54) + (b * 54 * patch_size / stepsize);
213             vArray[d + c + 6] = colors[i][j][3] * opacityother[i][j];
214
215             vArray[d + c + 15] = colors[i][j + stepsize][3] * opacityother[i][j + stepsize];
216
217             vArray[d + c + 24] = colors[i + stepsize][j][3] * opacityother[i + stepsize][j];
218
219             vArray[d + c + 33] = colors[i + stepsize][j][3] * opacityother[i + stepsize][j];
220
221             vArray[d + c + 42] = colors[i][j + stepsize][3] * opacityother[i][j + stepsize];
222
223             vArray[d + c + 51] = colors[i + stepsize][j + stepsize][3] * opacityother[i + stepsize][j + stepsize];
224         }
225     }
226 }
227
228 void Terrain::UpdateTransparencyotherother(int whichx, int whichy)
229 {
230     static XYZ vertex;
231     static int i, j, a, b, c, d, patch_size, stepsize;
232     static float distance;
233
234     static float viewdistsquared;
235
236     viewdistsquared = viewdistance * viewdistance;
237     patch_size = size / subdivision;
238
239     stepsize = 1;
240     c = whichx * patch_elements + whichy * patch_elements * subdivision;
241
242     for (i = patch_size * whichx; i < patch_size * (whichx + 1) + 1; i += stepsize) {
243         for (j = patch_size * whichy; j < patch_size * (whichy + 1) + 1; j += stepsize) {
244             if (i < size && j < size) {
245                 vertex.x = i * scale;
246                 vertex.z = j * scale;
247                 vertex.y = heightmap[i][j] * scale;
248                 distance = distsq(&viewer, &vertex);
249                 if (distance > viewdistsquared)
250                     distance = viewdistsquared;
251                 colors[i][j][3] = (viewdistsquared - (distance - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
252             }
253         }
254     }
255
256     for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) {
257         for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) {
258             a = (i - (patch_size * whichx)) / stepsize;
259             b = (j - (patch_size * whichy)) / stepsize;
260             d = (a * 54) + (b * 54 * patch_size / stepsize);
261             vArray[d + c + 6] = colors[i][j][3];
262
263             vArray[d + c + 15] = colors[i][j + stepsize][3];
264
265             vArray[d + c + 24] = colors[i + stepsize][j][3];
266
267             vArray[d + c + 33] = colors[i + stepsize][j][3];
268
269             vArray[d + c + 42] = colors[i][j + stepsize][3];
270
271             vArray[d + c + 51] = colors[i + stepsize][j + stepsize][3];
272         }
273     }
274 }
275
276 void Terrain::UpdateVertexArray(int whichx, int whichy)
277 {
278     static int i, j, a, b, c, patch_size, stepsize;
279
280
281     numtris[whichx][whichy] = 0;
282
283     patch_size = size / subdivision;
284
285     stepsize = 1;
286     c = whichx * patch_elements + whichy * patch_elements * subdivision;
287     for (i = patch_size * whichx; i < patch_size * (whichx + 1); i += stepsize) {
288         for (j = patch_size * whichy; j < patch_size * (whichy + 1); j += stepsize) {
289             a = (i - ((float)size / subdivision * (float)whichx)) / stepsize;
290             b = (j - ((float)size / subdivision * (float)whichy)) / stepsize;
291             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 0] = i * scale;
292             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 1] = heightmap[i][j] * scale;
293             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 2] = j * scale;
294             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 3] = colors[i][j][0];
295             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 4] = colors[i][j][1];
296             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 5] = colors[i][j][2];
297             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 6] = colors[i][j][3];
298             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 7] = i * scale * texscale + texoffsetx[i][j];
299             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 8] = j * scale * texscale + texoffsety[i][j];
300
301             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 9] = i * scale;
302             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 10] = heightmap[i][j + stepsize] * scale;
303             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 11] = j * scale + stepsize * scale;
304             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 12] = colors[i][j + stepsize][0];
305             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 13] = colors[i][j + stepsize][1];
306             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 14] = colors[i][j + stepsize][2];
307             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 15] = colors[i][j + stepsize][3];
308             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 16] = i * scale * texscale + texoffsetx[i][j + stepsize];
309             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 17] = j * scale * texscale + stepsize * scale * texscale + texoffsety[i][j + stepsize];
310
311             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 18] = i * scale + stepsize * scale;
312             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 19] = heightmap[i + stepsize][j] * scale;
313             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 20] = j * scale;
314             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 21] = colors[i + stepsize][j][0];
315             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 22] = colors[i + stepsize][j][1];
316             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 23] = colors[i + stepsize][j][2];
317             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 24] = colors[i + stepsize][j][3];
318             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 25] = i * scale * texscale + stepsize * scale * texscale + texoffsetx[i + stepsize][j];
319             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 26] = j * scale * texscale + texoffsety[i + stepsize][j];
320
321             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 27] = i * scale + stepsize * scale;
322             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 28] = heightmap[i + stepsize][j] * scale;
323             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 29] = j * scale;
324             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 30] = colors[i + stepsize][j][0];
325             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 31] = colors[i + stepsize][j][1];
326             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 32] = colors[i + stepsize][j][2];
327             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 33] = colors[i + stepsize][j][3];
328             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 34] = i * scale * texscale + stepsize * scale * texscale + texoffsetx[i + stepsize][j];
329             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 35] = j * scale * texscale + texoffsety[i + stepsize][j];
330
331             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 36] = i * scale;
332             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 37] = heightmap[i][j + stepsize] * scale;
333             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 38] = j * scale + stepsize * scale;
334             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 39] = colors[i][j + stepsize][0];
335             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 40] = colors[i][j + stepsize][1];
336             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 41] = colors[i][j + stepsize][2];
337             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 42] = colors[i][j + stepsize][3];
338             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 43] = i * scale * texscale + texoffsetx[i][j + stepsize];
339             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 44] = j * scale * texscale + stepsize * scale * texscale + texoffsety[i][j + stepsize];
340
341             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 45] = i * scale + stepsize * scale;
342             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 46] = heightmap[i + stepsize][j + stepsize] * scale;
343             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 47] = j * scale + stepsize * scale;
344             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 48] = colors[i + stepsize][j + stepsize][0];
345             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 49] = colors[i + stepsize][j + stepsize][1];
346             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 50] = colors[i + stepsize][j + stepsize][2];
347             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 51] = colors[i + stepsize][j + stepsize][3];
348             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 52] = i * scale * texscale + stepsize * scale * texscale + texoffsetx[i + stepsize][j + stepsize];
349             vArray[(a * 54) + (b * 54 * patch_size / stepsize) + c + 53] = j * scale * texscale + stepsize * scale * texscale + texoffsety[i + stepsize][j + stepsize];
350             numtris[whichx][whichy] += 2;
351         }
352     }
353
354     maxypatch[whichx][whichy] = -10000;
355     minypatch[whichx][whichy] = 10000;
356     for (a = 0; a < size / subdivision; a++) {
357         for (b = 0; b < size / subdivision; b++) {
358             if (heightmap[(size / subdivision)*whichx + a][(size / subdivision)*whichy + b]*scale > maxypatch[whichx][whichy])
359                 maxypatch[whichx][whichy] = heightmap[(size / subdivision) * whichx + a][(size / subdivision) * whichy + b] * scale;
360             if (heightmap[(size / subdivision)*whichx + a][(size / subdivision)*whichy + b]*scale < minypatch[whichx][whichy])
361                 minypatch[whichx][whichy] = heightmap[(size / subdivision) * whichx + a][(size / subdivision) * whichy + b] * scale;
362         }
363     }
364     heightypatch[whichx][whichy] = (maxypatch[whichx][whichy] - minypatch[whichx][whichy]);
365     if (heightypatch[whichx][whichy] < size / subdivision * scale)
366         heightypatch[whichx][whichy] = size / subdivision * scale;
367     avgypatch[whichx][whichy] = (minypatch[whichx][whichy] + maxypatch[whichx][whichy]) / 2;
368
369     for (i = whichx * size / subdivision; i < (whichx + 1)*size / subdivision - 1; i++) {
370         for (j = whichy * size / subdivision; j < (whichy + 1)*size / subdivision - 1; j++) {
371             triangles[(i * (size - 1) * 2) + (j * 2)][0].x = i * scale;
372             triangles[(i * (size - 1) * 2) + (j * 2)][0].y = heightmap[i][j] * scale;
373             triangles[(i * (size - 1) * 2) + (j * 2)][0].z = j * scale;
374
375             triangles[(i * (size - 1) * 2) + (j * 2)][1].x = i * scale;
376             triangles[(i * (size - 1) * 2) + (j * 2)][1].y = heightmap[i][j + 1] * scale;
377             triangles[(i * (size - 1) * 2) + (j * 2)][1].z = j * scale + scale;
378
379             triangles[(i * (size - 1) * 2) + (j * 2)][2].x = i * scale + 1 * scale;
380             triangles[(i * (size - 1) * 2) + (j * 2)][2].y = heightmap[i + 1][j] * scale;
381             triangles[(i * (size - 1) * 2) + (j * 2)][2].z = j * scale;
382
383             triangles[(i * (size - 1) * 2) + (j * 2) + 1][0].x = i * scale + 1 * scale;
384             triangles[(i * (size - 1) * 2) + (j * 2) + 1][0].y = heightmap[i + 1][j] * scale;
385             triangles[(i * (size - 1) * 2) + (j * 2) + 1][0].z = j * scale;
386
387             triangles[(i * (size - 1) * 2) + (j * 2) + 1][1].x = i * scale;
388             triangles[(i * (size - 1) * 2) + (j * 2) + 1][1].y = heightmap[i][j + 1] * scale;
389             triangles[(i * (size - 1) * 2) + (j * 2) + 1][1].z = j * scale + 1 * scale;
390
391             triangles[(i * (size - 1) * 2) + (j * 2) + 1][2].x = i * scale + 1 * scale;
392             triangles[(i * (size - 1) * 2) + (j * 2) + 1][2].y = heightmap[i + 1][j + 1] * scale;
393             triangles[(i * (size - 1) * 2) + (j * 2) + 1][2].z = j * scale + 1 * scale;
394         }
395     }
396
397 }
398
399
400 bool Terrain::load(const char *fileName)
401 {
402     static long i, j;
403     static long x, y;
404     static float patch_size;
405
406     float temptexdetail = texdetail;
407     //LoadTGA( fileName );
408
409     // Fixing filename so that it works with its own os
410     char * FixedFN = ConvertFileName(fileName);
411
412     unsigned char fileNamep[256];
413     CopyCStringToPascal(FixedFN, fileNamep);
414     //Load Image
415     upload_image( fileNamep , 0);
416
417     //Is it valid?
418     if (texture.bpp > 24) {
419         int bytesPerPixel = texture.bpp / 8;
420
421         int tempnum = 0;
422         for (i = 0; i < (long)(texture.sizeY * texture.sizeX * bytesPerPixel); i++) {
423             if ((i + 1) % 4) {
424                 texture.data[tempnum] = texture.data[i];
425                 tempnum++;
426             }
427         }
428     }
429     texture.bpp = 24;
430     if (visibleloading)
431         Game::LoadingScreen();
432
433     texdetail = temptexdetail;
434
435     size = texture.sizeX;
436
437     for (i = 0; i < size; i++) {
438         for (j = 0; j < size; j++) {
439             heightmap[size - 1 - i][j] = (float)((texture.data[(i + (j * size)) * texture.bpp / 8])) / 5;
440         }
441     }
442
443     if (visibleloading)
444         Game::LoadingScreen();
445
446     float slopeness;
447
448     for (i = 0; i < subdivision; i++) {
449         for (j = 0; j < subdivision; j++) {
450             textureness[i][j] = -1;
451         }
452     }
453     if (visibleloading)
454         Game::LoadingScreen();
455
456
457     for (i = 0; i < size; i++) {
458         for (j = 0; j < size; j++) {
459             heightmap[i][j] *= .5;
460
461             texoffsetx[i][j] = (float)abs(Random() % 100) / 1200 / scale * 3;
462             texoffsety[i][j] = (float)abs(Random() % 100) / 1200 / scale * 3;
463
464             slopeness = 0;
465             if (environment == snowyenvironment) {
466                 if (j != 0 && heightmap[i][j] - heightmap[i][j - 1] > slopeness) {
467                     slopeness = heightmap[i][j] - heightmap[i][j - 1];
468                 }
469                 opacityother[i][j] = slopeness * slopeness * 2;
470                 if (opacityother[i][j] > 1)
471                     opacityother[i][j] = 1;
472                 opacityother[i][j] -= (float)abs(Random() % 100) / 300;
473             }
474             if (environment == desertenvironment) {
475                 if (j != 0 && heightmap[i][j] - heightmap[i][j - 1] > slopeness) {
476                     slopeness = heightmap[i][j] - heightmap[i][j - 1];
477                 }
478                 opacityother[i][j] = slopeness * slopeness * 2;
479                 if (opacityother[i][j] > 1)
480                     opacityother[i][j] = 1;
481                 opacityother[i][j] -= (float)abs(Random() % 100) / 300;
482             }
483             if (environment == grassyenvironment) {
484                 if (i != 0 && heightmap[i][j] - heightmap[i - 1][j] > slopeness) {
485                     slopeness = heightmap[i][j] - heightmap[i - 1][j];
486                 }
487                 if (j != 0 && heightmap[i][j] - heightmap[i][j - 1] > slopeness) {
488                     slopeness = heightmap[i][j] - heightmap[i][j - 1];
489                 }
490                 if (i < size - 1 && heightmap[i][j] - heightmap[i + 1][j] > slopeness) {
491                     slopeness = heightmap[i][j] - heightmap[i + 1][j];
492                 }
493                 if (j < size - 1 && heightmap[i][j] - heightmap[i][j + 1] > slopeness) {
494                     slopeness = heightmap[i][j] - heightmap[i][j + 1];
495                 }
496                 opacityother[i][j] = slopeness * slopeness * 10;
497                 if (opacityother[i][j] > 1)
498                     opacityother[i][j] = 1;
499                 opacityother[i][j] -= (float)abs(Random() % 100) / 100;
500             }
501         }
502     }
503     if (visibleloading)
504         Game::LoadingScreen();
505
506     for (i = 0; i < size; i++) {
507         for (j = 0; j < size; j++) {
508             if (environment == snowyenvironment) {
509                 heightmap[i][j] -= opacityother[i][j];
510             }
511             if (environment == desertenvironment) {
512                 heightmap[i][j] -= opacityother[i][j];
513             }
514         }
515     }
516     if (visibleloading)
517         Game::LoadingScreen();
518
519     /*float total;
520     int todivide;
521     //Smooth opacityother
522     for(i=0;i<size;i++){
523     for(j=0;j<size;j++){
524     total=0;
525     todivide=0;
526     if(i!=0){total+=opacityother[j][i-1]; todivide++;}
527     if(i!=size-1){total+=opacityother[j][i+1]; todivide++;}
528     if(j!=0){total+=opacityother[j-1][i]; todivide++;}
529     if(j!=size-1){total+=opacityother[j+1][i]; todivide++;}
530     if(i!=0&&j!=0){total+=opacityother[j-1][i-1]; todivide++;}
531     if(i!=size-1&&j!=0){total+=opacityother[j-1][i+1]; todivide++;}
532     if(j!=size-1&&i!=size-1){total+=opacityother[j+1][i+1]; todivide++;}
533     if(j!=size-1&&i!=0){total+=opacityother[j+1][i-1]; todivide++;}
534     total+=opacityother[j][i]; todivide++;
535
536     opacityother[j][i]=total/(float)todivide;
537     }
538     }*/
539
540
541     for (i = 0; i < size; i++) {
542         for (j = 0; j < size; j++) {
543             if (opacityother[i][j] < .1)
544                 opacityother[i][j] = 0;
545             if (textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == -1) {
546                 if (!opacityother[i][j])
547                     textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = allfirst;
548                 if (opacityother[i][j] == 1)
549                     textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = allsecond;
550             }
551             if (opacityother[i][j] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
552                 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
553             if (opacityother[i][j] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
554                 textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
555
556             x = i;
557             y = j;
558             if (i > 0) {
559                 i--;
560                 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
561                     textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
562                 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
563                     textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
564                 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
565                     textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
566                 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
567                     textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
568
569                 if (j > 0) {
570                     j--;
571                     if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
572                         textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
573                     if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
574                         textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
575                     if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
576                         textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
577                     if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
578                         textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
579                     j++;
580                 }
581
582                 if (j < size - 1) {
583                     j++;
584                     if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
585                         textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
586                     if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
587                         textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
588                     if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
589                         textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
590                     if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
591                         textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
592                     j--;
593                 }
594                 i++;
595             }
596
597             if (i < size - 1) {
598                 i++;
599                 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
600                     textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
601                 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
602                     textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
603                 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
604                     textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
605                 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
606                     textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
607
608                 if (j > 0) {
609                     j--;
610                     if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
611                         textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
612                     if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
613                         textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
614                     if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
615                         textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
616                     if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
617                         textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
618                     j++;
619                 }
620
621                 if (j < size - 1) {
622                     j++;
623                     if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
624                         textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
625                     if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
626                         textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
627                     if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
628                         textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
629                     if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
630                         textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
631                     j--;
632                 }
633                 i--;
634             }
635
636             if (j > 0) {
637                 j--;
638                 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
639                     textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
640                 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
641                     textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
642                 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
643                     textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
644                 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
645                     textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
646                 j++;
647             }
648
649             if (j < size - 1) {
650                 j++;
651                 if (opacityother[x][y] && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allfirst)
652                     textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
653                 if (opacityother[x][y] != 1 && textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] == allsecond)
654                     textureness[(int)(i * subdivision / size)][(int)(j * subdivision / size)] = mixed;
655                 if (opacityother[i][j] && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allfirst)
656                     textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
657                 if (opacityother[i][j] != 1 && textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] == allsecond)
658                     textureness[(int)(x * subdivision / size)][(int)(y * subdivision / size)] = mixed;
659                 j--;
660
661             }
662         }
663     }
664     if (visibleloading)
665         Game::LoadingScreen();
666
667     patch_size = size / subdivision;
668     patch_elements = (patch_size) * (patch_size) * 54;
669     CalculateNormals();
670     /*DoShadows();
671
672     for(i=0;i<subdivision;i++){
673     for(j=0;j<subdivision;j++){
674     UpdateVertexArray(i,j);
675     }
676     }*/
677
678     return 1;
679 }
680
681 void Terrain::CalculateNormals()
682 {
683     static int i, j;
684     static XYZ facenormal;
685     static XYZ p, q, a, b, c;
686
687     for (i = 0; i < size; i++) {
688         for (j = 0; j < size; j++) {
689             normals[i][j].x = 0;
690             normals[i][j].y = 0;
691             normals[i][j].z = 0;
692         }
693     }
694
695     for (i = 0; i < size - 1; i++) {
696         for (j = 0; j < size - 1; j++) {
697             a.x = i;
698             a.y = heightmap[i][j];
699             a.z = j;
700             b.x = i;
701             b.y = heightmap[i][j + 1];
702             b.z = j + 1;
703             c.x = i + 1;
704             c.y = heightmap[i + 1][j];
705             c.z = j;
706
707             p.x = b.x - a.x;
708             p.y = b.y - a.y;
709             p.z = b.z - a.z;
710             q.x = c.x - a.x;
711             q.y = c.y - a.y;
712             q.z = c.z - a.z;
713
714             CrossProduct(&p, &q, &facenormal);
715
716             facenormals[i][j] = facenormal;
717
718             normals[i][j] = normals[i][j] + facenormal;
719             normals[i][j + 1] = normals[i][j + 1] + facenormal;
720             normals[i + 1][j] = normals[i + 1][j] + facenormal;
721
722
723             a.x = i + 1;
724             a.y = heightmap[i + 1][j];
725             a.z = j;
726             b.x = i;
727             b.y = heightmap[i][j + 1];
728             b.z = j + 1;
729             c.x = i + 1;
730             c.y = heightmap[i + 1][j + 1];
731             c.z = j + 1;
732
733             p.x = b.x - a.x;
734             p.y = b.y - a.y;
735             p.z = b.z - a.z;
736             q.x = c.x - a.x;
737             q.y = c.y - a.y;
738             q.z = c.z - a.z;
739
740             CrossProduct(&p, &q, &facenormal);
741
742             normals[i + 1][j + 1] = normals[i + 1][j + 1] + facenormal;
743             normals[i][j + 1] = normals[i][j + 1] + facenormal;
744             normals[i + 1][j] = normals[i + 1][j] + facenormal;
745
746             Normalise(&facenormals[i][j]);
747         }
748     }
749
750     for (i = 0; i < size; i++) {
751         for (j = 0; j < size; j++) {
752             Normalise(&normals[i][j]);
753         }
754     }
755 }
756
757 void Terrain::drawpatch(int whichx, int whichy, float opacity)
758 {
759     if (opacity >= 1)
760         glDisable(GL_BLEND);
761     if (opacity < 1) {
762         glEnable(GL_BLEND);
763         UpdateTransparency(whichx, whichy);
764     }
765     glColor4f(1, 1, 1, 1);
766     //Set up vertex array
767     glEnableClientState(GL_VERTEX_ARRAY);
768     glEnableClientState(GL_COLOR_ARRAY);
769     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
770     glVertexPointer(3, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[0 + whichx * patch_elements + whichy * patch_elements * subdivision]);
771     glColorPointer(4, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[3 + whichx * patch_elements + whichy * patch_elements * subdivision]);
772     glTexCoordPointer(2, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[7 + whichx * patch_elements + whichy * patch_elements * subdivision]);
773
774     //Draw
775     glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy] * 3);
776
777     glDisableClientState(GL_VERTEX_ARRAY);
778     glDisableClientState(GL_COLOR_ARRAY);
779     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
780 }
781
782 void Terrain::drawpatchother(int whichx, int whichy, float opacity)
783 {
784     glEnable(GL_BLEND);
785     if (opacity < 1) {
786         UpdateTransparency(whichx, whichy);
787     }
788     UpdateTransparencyother(whichx, whichy);
789     glColor4f(1, 1, 1, 1);
790     //Set up vertex array
791     glEnableClientState(GL_VERTEX_ARRAY);
792     glEnableClientState(GL_COLOR_ARRAY);
793     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
794     glVertexPointer(3, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[0 + whichx * patch_elements + whichy * patch_elements * subdivision]);
795     glColorPointer(4, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[3 + whichx * patch_elements + whichy * patch_elements * subdivision]);
796     glTexCoordPointer(2, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[7 + whichx * patch_elements + whichy * patch_elements * subdivision]);
797
798     //Draw
799     glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy] * 3);
800
801     glDisableClientState(GL_VERTEX_ARRAY);
802     glDisableClientState(GL_COLOR_ARRAY);
803     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
804 }
805
806 void Terrain::drawpatchotherother(int whichx, int whichy, float opacity)
807 {
808     glEnable(GL_BLEND);
809     UpdateTransparencyotherother(whichx, whichy);
810
811     glMatrixMode(GL_TEXTURE);
812     glPushMatrix();
813     glScalef(6, 6, 6);
814
815     glColor4f(1, 1, 1, 1);
816
817     //Set up vertex array
818     glEnableClientState(GL_VERTEX_ARRAY);
819     glEnableClientState(GL_COLOR_ARRAY);
820     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
821     glVertexPointer(3, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[0 + whichx * patch_elements + whichy * patch_elements * subdivision]);
822     glColorPointer(4, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[3 + whichx * patch_elements + whichy * patch_elements * subdivision]);
823     glTexCoordPointer(2, GL_FLOAT, 9 * sizeof(GLfloat), &vArray[7 + whichx * patch_elements + whichy * patch_elements * subdivision]);
824
825     //Draw
826     glDrawArrays(GL_TRIANGLES, 0, numtris[whichx][whichy] * 3);
827
828     glDisableClientState(GL_VERTEX_ARRAY);
829     glDisableClientState(GL_COLOR_ARRAY);
830     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
831
832     glPopMatrix();
833     glMatrixMode(GL_MODELVIEW);
834 }
835
836
837 float Terrain::getHeight(float pointx, float pointz)
838 {
839     static int tilex, tiley;
840     static XYZ startpoint, endpoint, intersect, triangle[3], average;
841
842     pointx /= scale;
843     pointz /= scale;
844
845     if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
846         return 0;
847
848     startpoint.x = pointx;
849     startpoint.y = -1000;
850     startpoint.z = pointz;
851
852     endpoint = startpoint;
853     endpoint.y = 1000;
854
855     tilex = pointx;
856     tiley = pointz;
857
858     triangle[0].x = tilex;
859     triangle[0].z = tiley;
860     triangle[0].y = heightmap[tilex][tiley];
861
862     triangle[1].x = tilex + 1;
863     triangle[1].z = tiley;
864     triangle[1].y = heightmap[tilex + 1][tiley];
865
866     triangle[2].x = tilex;
867     triangle[2].z = tiley + 1;
868     triangle[2].y = heightmap[tilex][tiley + 1];
869
870     if (!LineFacetd(&startpoint, &endpoint, &triangle[0], &triangle[1], &triangle[2], &intersect)) {
871         triangle[0].x = tilex + 1;
872         triangle[0].z = tiley;
873         triangle[0].y = heightmap[tilex + 1][tiley];
874
875         triangle[1].x = tilex + 1;
876         triangle[1].z = tiley + 1;
877         triangle[1].y = heightmap[tilex + 1][tiley + 1];
878
879         triangle[2].x = tilex;
880         triangle[2].z = tiley + 1;
881         triangle[2].y = heightmap[tilex][tiley + 1];
882         LineFacetd(&startpoint, &endpoint, &triangle[0], &triangle[1], &triangle[2], &intersect);
883     }
884     return intersect.y * scale + getOpacity(pointx * scale, pointz * scale) / 8;
885
886     //height1=heightmap[tilex][tiley]*(1-(pointx-tilex))+heightmap[tilex+1][tiley]*(pointx-tilex);
887     //height2=heightmap[tilex][tiley+1]*(1-(pointx-tilex))+heightmap[tilex+1][tiley+1]*(pointx-tilex);
888
889     //return height1*(1-(pointz-tiley))*scale+height2*(pointz-tiley)*scale;
890 }
891
892 float Terrain::getOpacity(float pointx, float pointz)
893 {
894     static float height1, height2;
895     static int tilex, tiley;
896
897     pointx /= scale;
898     pointz /= scale;
899
900     if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
901         return 0;
902
903     tilex = pointx;
904     tiley = pointz;
905
906     height1 = opacityother[tilex][tiley] * (1 - (pointx - tilex)) + opacityother[tilex + 1][tiley] * (pointx - tilex);
907     height2 = opacityother[tilex][tiley + 1] * (1 - (pointx - tilex)) + opacityother[tilex + 1][tiley + 1] * (pointx - tilex);
908
909     return height1 * (1 - (pointz - tiley)) + height2 * (pointz - tiley);
910 }
911
912 XYZ Terrain::getNormal(float pointx, float pointz)
913 {
914     static XYZ height1, height2, total;
915     static int tilex, tiley;
916
917     pointx /= scale;
918     pointz /= scale;
919
920     height1 = 0;
921     if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
922         return height1;
923     tilex = pointx;
924     tiley = pointz;
925
926     height1 = normals[tilex][tiley] * (1 - (pointx - tilex)) + normals[tilex + 1][tiley] * (pointx - tilex);
927     height2 = normals[tilex][tiley + 1] * (1 - (pointx - tilex)) + normals[tilex + 1][tiley + 1] * (pointx - tilex);
928     total = height1 * (1 - (pointz - tiley)) + height2 * (pointz - tiley);
929     Normalise(&total);
930     return total;
931 }
932
933 XYZ Terrain::getLighting(float pointx, float pointz)
934 {
935     static XYZ height1, height2;
936     static int tilex, tiley;
937
938     pointx /= scale;
939     pointz /= scale;
940
941     height1 = 0;
942     if (pointx >= size - 1 || pointz >= size - 1 || pointx <= 0 || pointz <= 0)
943         return height1;
944     tilex = pointx;
945     tiley = pointz;
946
947     height1.x = colors[tilex][tiley][0] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley][0] * (pointx - tilex);
948     height1.y = colors[tilex][tiley][1] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley][1] * (pointx - tilex);
949     height1.z = colors[tilex][tiley][2] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley][2] * (pointx - tilex);
950     height2.x = colors[tilex][tiley + 1][0] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley + 1][0] * (pointx - tilex);
951     height2.y = colors[tilex][tiley + 1][1] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley + 1][1] * (pointx - tilex);
952     height2.z = colors[tilex][tiley + 1][2] * (1 - (pointx - tilex)) + colors[tilex + 1][tiley + 1][2] * (pointx - tilex);
953
954     return height1 * (1 - (pointz - tiley)) + height2 * (pointz - tiley);
955 }
956
957 void Terrain::draw(int layer)
958 {
959     static int i, j;
960     static float opacity;
961     static XYZ terrainpoint;
962     static float distance[subdivision][subdivision];
963
964     static int beginx, endx;
965     static int beginz, endz;
966
967     static float patch_size = size / subdivision * scale;
968     static float viewdistsquared;
969
970     viewdistsquared = viewdistance * viewdistance;
971
972     //Only nearby blocks
973     beginx = (viewer.x - viewdistance) / (patch_size) - 1;
974     if (beginx < 0)
975         beginx = 0;
976     beginz = (viewer.z - viewdistance) / (patch_size) - 1;
977     if (beginz < 0)
978         beginz = 0;
979
980     endx = (viewer.x + viewdistance) / (patch_size) + 1;
981     if (endx > subdivision)
982         endx = subdivision;
983     endz = (viewer.z + viewdistance) / (patch_size) + 1;
984     if (endz > subdivision)
985         endz = subdivision;
986
987     if (!layer) {
988         for (i = beginx; i < endx; i++) {
989             for (j = beginz; j < endz; j++) {
990                 terrainpoint.x = i * patch_size + (patch_size) / 2;
991                 terrainpoint.y = viewer.y; //heightmap[i][j]*scale;
992                 terrainpoint.z = j * patch_size + (patch_size) / 2;
993                 distance[i][j] = distsq(&viewer, &terrainpoint);
994             }
995         }
996     }
997     for (i = beginx; i < endx; i++) {
998         for (j = beginz; j < endz; j++) {
999             if (distance[i][j] < (viewdistance + patch_size) * (viewdistance + patch_size)) {
1000                 opacity = 1;
1001                 if (distance[i][j] > viewdistsquared * fadestart - viewdistsquared)
1002                     opacity = 0;
1003                 if (opacity == 1 && i != subdivision)
1004                     if (distance[i + 1][j] > viewdistsquared * fadestart - viewdistsquared)
1005                         opacity = 0;
1006                 if (opacity == 1 && j != subdivision)
1007                     if (distance[i][j + 1] > viewdistsquared * fadestart - viewdistsquared)
1008                         opacity = 0;
1009                 if (opacity == 1 && j != subdivision && i != subdivision)
1010                     if (distance[i + 1][j + 1] > viewdistsquared * fadestart - viewdistsquared)
1011                         opacity = 0;
1012                 glMatrixMode(GL_MODELVIEW);
1013                 glPushMatrix();
1014                 if (frustum.CubeInFrustum(i * patch_size + patch_size * .5, avgypatch[i][j], j * patch_size + patch_size * .5, heightypatch[i][j] / 2)) {
1015                     if (environment == desertenvironment && distance[i][j] > viewdistsquared / 4)
1016                         glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, blurness);
1017                     else if (environment == desertenvironment)
1018                         glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
1019                     if (!layer && textureness[i][j] != allsecond)
1020                         drawpatch(i, j, opacity);
1021                     if (layer == 1 && textureness[i][j] != allfirst)
1022                         drawpatchother(i, j, opacity);
1023                     if (layer == 2 && textureness[i][j] != allfirst)
1024                         drawpatchotherother(i, j, opacity);
1025                 }
1026                 glPopMatrix();
1027             }
1028         }
1029     }
1030     if (environment == desertenvironment)
1031         glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
1032 }
1033
1034 void Terrain::drawdecals()
1035 {
1036     if (decals) {
1037         static int i;
1038         static float distancemult;
1039         static int lasttype;
1040
1041         static float viewdistsquared;
1042         static bool blend;
1043
1044         viewdistsquared = viewdistance * viewdistance;
1045         blend = 1;
1046
1047         lasttype = -1;
1048         glEnable(GL_BLEND);
1049         glDisable(GL_LIGHTING);
1050         glDisable(GL_CULL_FACE);
1051         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1052         glDepthMask(0);
1053         for (i = 0; i < numdecals; i++) {
1054             if (decaltype[i] == blooddecalfast && decalalivetime[i] < 2)
1055                 decalalivetime[i] = 2;
1056             if ((decaltype[i] == shadowdecal || decaltype[i] == shadowdecalpermanent) && decaltype[i] != lasttype) {
1057                 shadowtexture.bind();
1058                 if (!blend) {
1059                     blend = 1;
1060                     glAlphaFunc(GL_GREATER, 0.0001);
1061                     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1062                 }
1063             }
1064             if (decaltype[i] == footprintdecal && decaltype[i] != lasttype) {
1065                 footprinttexture.bind();
1066                 if (!blend) {
1067                     blend = 1;
1068                     glAlphaFunc(GL_GREATER, 0.0001);
1069                     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1070                 }
1071             }
1072             if (decaltype[i] == bodyprintdecal && decaltype[i] != lasttype) {
1073                 bodyprinttexture.bind();
1074                 if (!blend) {
1075                     blend = 1;
1076                     glAlphaFunc(GL_GREATER, 0.0001);
1077                     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1078                 }
1079             }
1080             if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalslow) && decaltype[i] != lasttype) {
1081                 bloodtexture.bind();
1082                 if (blend) {
1083                     blend = 0;
1084                     glAlphaFunc(GL_GREATER, 0.15);
1085                     glBlendFunc(GL_ONE, GL_ZERO);
1086                 }
1087             }
1088             if ((decaltype[i] == blooddecalfast) && decaltype[i] != lasttype) {
1089                 bloodtexture2.bind();
1090                 if (blend) {
1091                     blend = 0;
1092                     glAlphaFunc(GL_GREATER, 0.15);
1093                     glBlendFunc(GL_ONE, GL_ZERO);
1094                 }
1095             }
1096             if (decaltype[i] == shadowdecal || decaltype[i] == shadowdecalpermanent) {
1097                 distancemult = (viewdistsquared - (distsq(&viewer, &decalposition[i]) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
1098                 if (distancemult >= 1)
1099                     glColor4f(1, 1, 1, decalopacity[i]);
1100                 if (distancemult < 1)
1101                     glColor4f(1, 1, 1, decalopacity[i]*distancemult);
1102             }
1103             if (decaltype[i] == footprintdecal || decaltype[i] == bodyprintdecal) {
1104                 distancemult = (viewdistsquared - (distsq(&viewer, &decalposition[i]) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
1105                 if (distancemult >= 1) {
1106                     glColor4f(1, 1, 1, decalopacity[i]);
1107                     if (decalalivetime[i] > 3)
1108                         glColor4f(1, 1, 1, decalopacity[i] * (5 - decalalivetime[i]) / 2);
1109                 }
1110                 if (distancemult < 1) {
1111                     glColor4f(1, 1, 1, decalopacity[i]*distancemult);
1112                     if (decalalivetime[i] > 3)
1113                         glColor4f(1, 1, 1, decalopacity[i] * (5 - decalalivetime[i]) / 2 * distancemult);
1114                 }
1115             }
1116             if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow)) {
1117                 distancemult = (viewdistsquared - (distsq(&viewer, &decalposition[i]) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
1118                 if (distancemult >= 1) {
1119                     glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]);
1120                     if (decalalivetime[i] < 4)
1121                         glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]*decalalivetime[i]*.25);
1122                     if (decalalivetime[i] > 58)
1123                         glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i] * (60 - decalalivetime[i]) / 2);
1124                 }
1125                 if (distancemult < 1) {
1126                     glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]*distancemult);
1127                     if (decalalivetime[i] < 4)
1128                         glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]*decalalivetime[i]*distancemult * .25);
1129                     if (decalalivetime[i] > 58)
1130                         glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i] * (60 - decalalivetime[i]) / 2 * distancemult);
1131                 }
1132             }
1133             lasttype = decaltype[i];
1134             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
1135             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
1136
1137             glMatrixMode(GL_MODELVIEW);
1138             glPushMatrix();
1139             glBegin(GL_TRIANGLES);
1140             for (int j = 0; j < 3; j++) {
1141                 glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]);
1142                 glVertex3f(decalvertex[i][j].x, decalvertex[i][j].y, decalvertex[i][j].z);
1143             }
1144             glEnd();
1145             glPopMatrix();
1146         }
1147         for (i = numdecals - 1; i >= 0; i--) {
1148             decalalivetime[i] += multiplier;
1149             if (decaltype[i] == blooddecalslow)
1150                 decalalivetime[i] -= multiplier * 2 / 3;
1151             if (decaltype[i] == blooddecalfast)
1152                 decalalivetime[i] += multiplier * 4;
1153             if (decaltype[i] == shadowdecal)
1154                 DeleteDecal(i);
1155             if (decaltype[i] == footprintdecal && decalalivetime[i] >= 5)
1156                 DeleteDecal(i);
1157             if (decaltype[i] == bodyprintdecal && decalalivetime[i] >= 5)
1158                 DeleteDecal(i);
1159             if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow) && decalalivetime[i] >= 60)
1160                 DeleteDecal(i);
1161         }
1162         glAlphaFunc(GL_GREATER, 0.0001);
1163     }
1164 }
1165
1166 void Terrain::AddObject(XYZ where, float radius, int id)
1167 {
1168     bool done;
1169     int i, j;
1170     XYZ points[4];
1171     if (id >= 0 && id < 10000)
1172         for (i = 0; i < subdivision; i++) {
1173             for (j = 0; j < subdivision; j++) {
1174                 if (patchobjectnum[i][j] < 300 - 1) {
1175                     done = 0;
1176                     points[0].x = (size / subdivision) * i;
1177                     points[0].z = (size / subdivision) * j;
1178                     points[0].y = heightmap[(int)points[0].x][(int)points[0].z];
1179                     points[1].x = (size / subdivision) * (i + 1);
1180                     points[1].z = (size / subdivision) * j;
1181                     points[1].y = heightmap[(int)points[1].x][(int)points[1].z];
1182                     points[2].x = (size / subdivision) * (i + 1);
1183                     points[2].z = (size / subdivision) * (j + 1);
1184                     points[2].y = heightmap[(int)points[2].x][(int)points[2].z];
1185                     points[3].x = (size / subdivision) * i;
1186                     points[3].z = (size / subdivision) * (j + 1);
1187                     points[3].y = heightmap[(int)points[3].x][(int)points[3].z];
1188                     points[0] *= scale;
1189                     points[1] *= scale;
1190                     points[2] *= scale;
1191                     points[3] *= scale;
1192                     if (!done && where.x + radius > points[0].x && where.x - radius < points[2].x && where.z + radius > points[0].z && where.z - radius < points[2].z) {
1193                         patchobjects[i][j][patchobjectnum[i][j]] = id;
1194                         patchobjectnum[i][j]++;
1195                         done = 1;
1196                     }
1197                 }
1198             }
1199         }
1200 }
1201
1202 void Terrain::DeleteDecal(int which)
1203 {
1204     if (decals) {
1205         decaltype[which] = decaltype[numdecals - 1];
1206         decalposition[which] = decalposition[numdecals - 1];
1207         for (int i = 0; i < 3; i++) {
1208             decalvertex[which][i] = decalvertex[numdecals - 1][i];
1209             decaltexcoords[which][i][0] = decaltexcoords[numdecals - 1][i][0];
1210             decaltexcoords[which][i][1] = decaltexcoords[numdecals - 1][i][1];
1211         }
1212         decalrotation[which] = decalrotation[numdecals - 1];
1213         decalalivetime[which] = decalalivetime[numdecals - 1];
1214         decalopacity[which] = decalopacity[numdecals - 1];
1215         decalbrightness[which] = decalbrightness[numdecals - 1];
1216         numdecals--;
1217     }
1218 }
1219
1220 void Terrain::MakeDecal(int type, XYZ where, float size, float opacity, float rotation)
1221 {
1222     if (decals) {
1223         if (opacity > 0 && size > 0) {
1224             static int patchx[4];
1225             static int patchy[4];
1226
1227             decaltexcoords[numdecals][0][0] = 1;
1228             decaltexcoords[numdecals][0][1] = 0;
1229
1230             patchx[0] = (where.x + size) / scale;
1231             patchx[1] = (where.x - size) / scale;
1232             patchx[2] = (where.x - size) / scale;
1233             patchx[3] = (where.x + size) / scale;
1234
1235             patchy[0] = (where.z - size) / scale;
1236             patchy[1] = (where.z - size) / scale;
1237             patchy[2] = (where.z + size) / scale;
1238             patchy[3] = (where.z + size) / scale;
1239
1240             /*if(patchx[1]<subdivision-1&&patchy[1]<subdivision-1&&patchx[1]>0&&patchy[1]>0)
1241             if(patchx[2]<subdivision-1&&patchy[2]<subdivision-1&&patchx[2]>0&&patchy[2]>0)
1242             if(patchx[3]<subdivision-1&&patchy[3]<subdivision-1&&patchx[3]>0&&patchy[3]>0)
1243             if(patchx[0]<subdivision-1&&patchy[0]<subdivision-1&&patchx[0]>0&&patchy[0]>0){
1244             */
1245             if ((patchx[0] != patchx[1] || patchy[0] != patchy[1]) && (patchx[0] != patchx[2] || patchy[0] != patchy[2]) && (patchx[0] != patchx[3] || patchy[0] != patchy[3])) {
1246                 MakeDecalLock(type, where, patchx[0], patchy[0], size, opacity, rotation);
1247             }
1248
1249             if ((patchx[1] != patchx[2] || patchy[1] != patchy[2]) && (patchx[1] != patchx[3] || patchy[1] != patchy[3])) {
1250                 MakeDecalLock(type, where, patchx[1], patchy[1], size, opacity, rotation);
1251             }
1252
1253             if ((patchx[2] != patchx[3] || patchy[2] != patchy[3])) {
1254                 MakeDecalLock(type, where, patchx[2], patchy[2], size, opacity, rotation);
1255             }
1256             MakeDecalLock(type, where, patchx[3], patchy[3], size, opacity, rotation);
1257         }
1258     }
1259     //}
1260 }
1261
1262 void Terrain::MakeDecalLock(int type, XYZ where, int whichx, int whichy, float size, float opacity, float rotation)
1263 {
1264     if (decals) {
1265         static float placex, placez;
1266         static XYZ rot;
1267
1268         float decalbright;
1269
1270         rot = getLighting(where.x, where.z);
1271         decalbrightness[numdecals] = (rot.x + rot.y + rot.z) / 3;
1272         if (decalbrightness[numdecals] < .4)
1273             decalbrightness[numdecals] = .4;
1274
1275         if (environment == grassyenvironment) {
1276             decalbrightness[numdecals] *= .6;
1277         }
1278
1279         if (decalbrightness[numdecals] > 1)
1280             decalbrightness[numdecals] = 1;
1281         decalbright = decalbrightness[numdecals];
1282
1283         decalposition[numdecals] = where;
1284         decaltype[numdecals] = type;
1285         decalopacity[numdecals] = opacity;
1286         decalrotation[numdecals] = rotation;
1287         decalalivetime[numdecals] = 0;
1288
1289         placex = (float)whichx * scale + scale;
1290         placez = (float)whichy * scale;
1291
1292         decaltexcoords[numdecals][0][0] = (placex - where.x) / size / 2 + .5;
1293         decaltexcoords[numdecals][0][1] = (placez - where.z) / size / 2 + .5;
1294
1295         decalvertex[numdecals][0].x = placex;
1296         decalvertex[numdecals][0].z = placez;
1297         decalvertex[numdecals][0].y = heightmap[whichx + 1][whichy] * scale + .01;
1298
1299
1300         placex = (float)whichx * scale + scale;
1301         placez = (float)whichy * scale + scale;
1302
1303         decaltexcoords[numdecals][1][0] = (placex - where.x) / size / 2 + .5;
1304         decaltexcoords[numdecals][1][1] = (placez - where.z) / size / 2 + .5;
1305
1306         decalvertex[numdecals][1].x = placex;
1307         decalvertex[numdecals][1].z = placez;
1308         decalvertex[numdecals][1].y = heightmap[whichx + 1][whichy + 1] * scale + .01;
1309
1310
1311         placex = (float)whichx * scale;
1312         placez = (float)whichy * scale + scale;
1313
1314         decaltexcoords[numdecals][2][0] = (placex - where.x) / size / 2 + .5;
1315         decaltexcoords[numdecals][2][1] = (placez - where.z) / size / 2 + .5;
1316
1317         decalvertex[numdecals][2].x = placex;
1318         decalvertex[numdecals][2].z = placez;
1319         decalvertex[numdecals][2].y = heightmap[whichx][whichy + 1] * scale + .01;
1320
1321         if (decalrotation[numdecals]) {
1322             for (int i = 0; i < 3; i++) {
1323                 rot.y = 0;
1324                 rot.x = decaltexcoords[numdecals][i][0] - .5;
1325                 rot.z = decaltexcoords[numdecals][i][1] - .5;
1326                 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1327                 decaltexcoords[numdecals][i][0] = rot.x + .5;
1328                 decaltexcoords[numdecals][i][1] = rot.z + .5;
1329             }
1330         }
1331
1332         if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1333             if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1334                 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1335                     if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1))
1336                         if (numdecals < max_decals - 1)
1337                             numdecals++;
1338
1339         decalbrightness[numdecals] = decalbright;
1340
1341         decalposition[numdecals] = where;
1342         decaltype[numdecals] = type;
1343         decalopacity[numdecals] = opacity;
1344         decalrotation[numdecals] = rotation;
1345         decalalivetime[numdecals] = 0;
1346
1347         placex = (float)whichx * scale + scale;
1348         placez = (float)whichy * scale;
1349
1350         decaltexcoords[numdecals][0][0] = (placex - where.x) / size / 2 + .5;
1351         decaltexcoords[numdecals][0][1] = (placez - where.z) / size / 2 + .5;
1352
1353         decalvertex[numdecals][0].x = placex;
1354         decalvertex[numdecals][0].z = placez;
1355         decalvertex[numdecals][0].y = heightmap[whichx + 1][whichy] * scale + .01;
1356
1357
1358         placex = (float)whichx * scale;
1359         placez = (float)whichy * scale;
1360
1361         decaltexcoords[numdecals][1][0] = (placex - where.x) / size / 2 + .5;
1362         decaltexcoords[numdecals][1][1] = (placez - where.z) / size / 2 + .5;
1363
1364         decalvertex[numdecals][1].x = placex;
1365         decalvertex[numdecals][1].z = placez;
1366         decalvertex[numdecals][1].y = heightmap[whichx][whichy] * scale + .01;
1367
1368
1369         placex = (float)whichx * scale;
1370         placez = (float)whichy * scale + scale;
1371
1372         decaltexcoords[numdecals][2][0] = (placex - where.x) / size / 2 + .5;
1373         decaltexcoords[numdecals][2][1] = (placez - where.z) / size / 2 + .5;
1374
1375         decalvertex[numdecals][2].x = placex;
1376         decalvertex[numdecals][2].z = placez;
1377         decalvertex[numdecals][2].y = heightmap[whichx][whichy + 1] * scale + .01;
1378
1379         if (decalrotation[numdecals]) {
1380             for (int i = 0; i < 3; i++) {
1381                 rot.y = 0;
1382                 rot.x = decaltexcoords[numdecals][i][0] - .5;
1383                 rot.z = decaltexcoords[numdecals][i][1] - .5;
1384                 rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
1385                 decaltexcoords[numdecals][i][0] = rot.x + .5;
1386                 decaltexcoords[numdecals][i][1] = rot.z + .5;
1387             }
1388         }
1389
1390         if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
1391             if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
1392                 if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
1393                     if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1))
1394                         if (numdecals < max_decals - 1)
1395                             numdecals++;
1396     }
1397 }
1398
1399 void Terrain::DoShadows()
1400 {
1401     static int i, j, k, l, todivide;
1402     static float brightness, total;
1403     static XYZ testpoint, testpoint2, terrainpoint, lightloc, col;
1404     lightloc = light.location;
1405     if (!skyboxtexture) {
1406         lightloc.x = 0;
1407         lightloc.z = 0;
1408     }
1409     if (skyboxtexture && tutoriallevel) {
1410         lightloc.x *= .4;
1411         lightloc.z *= .4;
1412     }
1413     int patchx, patchz;
1414     float shadowed;
1415     Normalise(&lightloc);
1416     //Calculate shadows
1417     for (i = 0; i < size; i++) {
1418         for (j = 0; j < size; j++) {
1419             terrainpoint.x = (float)(i) * scale;
1420             terrainpoint.z = (float)(j) * scale;
1421             terrainpoint.y = heightmap[i][j] * scale;
1422
1423             shadowed = 0;
1424             patchx = (float)(i) * subdivision / size;
1425             patchz = (float)(j) * subdivision / size;
1426             if (patchobjectnum[patchx][patchz]) {
1427                 for (k = 0; k < patchobjectnum[patchx][patchz]; k++) {
1428                     l = patchobjects[patchx][patchz][k];
1429                     if (objects.type[l] != treetrunktype) {
1430                         testpoint = terrainpoint;
1431                         testpoint2 = terrainpoint + lightloc * 50 * (1 - shadowed);
1432                         if (objects.model[l].LineCheck(&testpoint, &testpoint2, &col, &objects.position[l], &objects.yaw[l]) != -1) {
1433                             shadowed = 1 - (findDistance(&terrainpoint, &col) / 50);
1434                         }
1435                     }
1436                 }
1437                 if (visibleloading)
1438                     Game::LoadingScreen();
1439             }
1440             brightness = dotproduct(&lightloc, &normals[i][j]);
1441             if (shadowed)
1442                 brightness *= 1 - shadowed;
1443
1444             if (brightness > 1)
1445                 brightness = 1;
1446             if (brightness < 0)
1447                 brightness = 0;
1448
1449             colors[i][j][0] = light.color[0] * brightness + light.ambient[0];
1450             colors[i][j][1] = light.color[1] * brightness + light.ambient[1];
1451             colors[i][j][2] = light.color[2] * brightness + light.ambient[2];
1452
1453             if (colors[i][j][0] > 1) colors[i][j][0] = 1;
1454             if (colors[i][j][1] > 1) colors[i][j][1] = 1;
1455             if (colors[i][j][2] > 1) colors[i][j][2] = 1;
1456             if (colors[i][j][0] < 0) colors[i][j][0] = 0;
1457             if (colors[i][j][1] < 0) colors[i][j][1] = 0;
1458             if (colors[i][j][2] < 0) colors[i][j][2] = 0;
1459         }
1460     }
1461
1462     if (visibleloading)
1463         Game::LoadingScreen();
1464
1465     //Smooth shadows
1466     for (i = 0; i < size; i++) {
1467         for (j = 0; j < size; j++) {
1468             for (k = 0; k < 3; k++) {
1469                 total = 0;
1470                 todivide = 0;
1471                 if (i != 0) {
1472                     total += colors[j][i - 1][k];
1473                     todivide++;
1474                 }
1475                 if (i != size - 1) {
1476                     total += colors[j][i + 1][k];
1477                     todivide++;
1478                 }
1479                 if (j != 0) {
1480                     total += colors[j - 1][i][k];
1481                     todivide++;
1482                 }
1483                 if (j != size - 1) {
1484                     total += colors[j + 1][i][k];
1485                     todivide++;
1486                 }
1487                 if (i != 0 && j != 0) {
1488                     total += colors[j - 1][i - 1][k];
1489                     todivide++;
1490                 }
1491                 if (i != size - 1 && j != 0) {
1492                     total += colors[j - 1][i + 1][k];
1493                     todivide++;
1494                 }
1495                 if (j != size - 1 && i != size - 1) {
1496                     total += colors[j + 1][i + 1][k];
1497                     todivide++;
1498                 }
1499                 if (j != size - 1 && i != 0) {
1500                     total += colors[j + 1][i - 1][k];
1501                     todivide++;
1502                 }
1503                 total += colors[j][i][k];
1504                 todivide++;
1505
1506                 colors[j][i][k] = total / todivide;
1507             }
1508         }
1509     }
1510
1511     for (i = 0; i < subdivision; i++) {
1512         for (j = 0; j < subdivision; j++) {
1513             UpdateVertexArray(i, j);
1514         }
1515     }
1516 }
1517
1518 Terrain::Terrain()
1519 {
1520     size = 0;
1521
1522     memset(patchobjectnum, 0, sizeof(patchobjectnum));
1523     memset(patchobjects, 0, sizeof(patchobjects));
1524
1525     scale = 1.0f;
1526     type = 0;
1527     memset(heightmap, 0, sizeof(heightmap));
1528     memset(normals, 0, sizeof(normals));
1529     memset(facenormals, 0, sizeof(facenormals));
1530     memset(triangles, 0, sizeof(triangles));
1531     memset(colors, 0, sizeof(colors));
1532     memset(opacityother, 0, sizeof(opacityother));
1533     memset(texoffsetx, 0, sizeof(texoffsetx));
1534     memset(texoffsety, 0, sizeof(texoffsety));
1535     memset(numtris, 0, sizeof(numtris));
1536     memset(textureness, 0, sizeof(textureness));
1537
1538     memset(vArray, 0, sizeof(vArray));
1539
1540     memset(visible, 0, sizeof(visible));
1541     memset(avgypatch, 0, sizeof(avgypatch));
1542     memset(maxypatch, 0, sizeof(maxypatch));
1543     memset(minypatch, 0, sizeof(minypatch));
1544     memset(heightypatch, 0, sizeof(heightypatch));
1545
1546     patch_elements = 0;
1547
1548     memset(decaltexcoords, 0, sizeof(decaltexcoords));
1549     memset(decalvertex, 0, sizeof(decalvertex));
1550     memset(decaltype, 0, sizeof(decaltype));
1551     memset(decalopacity, 0, sizeof(decalopacity));
1552     memset(decalrotation, 0, sizeof(decalrotation));
1553     memset(decalalivetime, 0, sizeof(decalalivetime));
1554     memset(decalbrightness, 0, sizeof(decalbrightness));
1555     memset(decalposition, 0, sizeof(decalposition));
1556     numdecals = 0;
1557 }
1558 Terrain::~Terrain()
1559 {
1560     terraintexture.destroy();
1561     shadowtexture.destroy();
1562     bodyprinttexture.destroy();
1563     footprinttexture.destroy();
1564     bloodtexture.destroy();
1565     bloodtexture2.destroy();
1566     breaktexture.destroy();
1567 }
1568