2 Copyright (C) 2003, 2010 - Wolfire Games
4 This file is part of Lugaru.
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.
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.
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/>.
22 extern float viewdistance;
23 extern float fadestart;
24 extern int environment;
25 extern float texscale;
27 extern float multiplier;
29 extern FRUSTUM frustum;
30 extern Terrain terrain;
33 extern float blurness;
35 extern float playerdist;
36 extern bool skyboxtexture;
40 bool Objects::checkcollide(XYZ startpoint, XYZ endpoint, int which)
42 static XYZ colpoint, colviewer, coltarget;
50 for (i = 0; i < numobjects; i++) {
51 if (type[i] != treeleavestype && type[i] != treetrunktype && type[i] != bushtype && type[i] != firetype && i != which) {
52 colviewer = startpoint;
54 if (model[i].LineCheck(&colviewer, &coltarget, &colpoint, &position[i], &yaw[i]) != -1)
62 void Objects::SphereCheckPossible(XYZ *p1, float radius)
65 static int whichpatchx;
66 static int whichpatchz;
68 whichpatchx = p1->x / (terrain.size / subdivision * terrain.scale);
69 whichpatchz = p1->z / (terrain.size / subdivision * terrain.scale);
71 if (whichpatchx >= 0 && whichpatchz >= 0 && whichpatchx < subdivision && whichpatchz < subdivision)
72 if (terrain.patchobjectnum[whichpatchx][whichpatchz] > 0 && terrain.patchobjectnum[whichpatchx][whichpatchz] < 500)
73 for (j = 0; j < terrain.patchobjectnum[whichpatchx][whichpatchz]; j++) {
74 i = terrain.patchobjects[whichpatchx][whichpatchz][j];
76 if (model[i].SphereCheckPossible(p1, radius, &position[i], &yaw[i]) != -1) {
84 static float distance;
86 static XYZ moved, terrainlight;
89 for (i = 0; i < numobjects; i++) {
90 if (type[i] != firetype) {
91 moved = DoRotation(model[i].boundingspherecenter, 0, yaw[i], 0);
92 if (type[i] == tunneltype || frustum.SphereInFrustum(position[i].x + moved.x, position[i].y + moved.y, position[i].z + moved.z, model[i].boundingsphereradius)) {
93 distance = distsq(&viewer, &position[i]);
95 hidden = !(distsqflat(&viewer, &position[i]) > playerdist + 3 || (type[i] != bushtype && type[i] != treeleavestype));
98 if (detail == 2 && distance > viewdistance * viewdistance / 4 && environment == desertenvironment)
99 glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, blurness );
101 glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
102 distance = (viewdistance * viewdistance - (distance - (viewdistance * viewdistance * fadestart)) * (1 / (1 - fadestart))) / viewdistance / viewdistance;
107 if (occluded[i] < 6) {
108 glMatrixMode(GL_MODELVIEW);
111 glEnable(GL_LIGHTING);
113 glDisable(GL_LIGHTING);
115 glTranslatef(position[i].x, position[i].y, position[i].z);
116 if (type[i] == bushtype) {
117 messedwith[i] -= multiplier;
118 if (rotxvel[i] || rotx[i]) {
119 if (rotx[i] > 0) rotxvel[i] -= multiplier * 8 * fabs(rotx[i]);
120 if (rotx[i] < 0) rotxvel[i] += multiplier * 8 * fabs(rotx[i]);
121 if (rotx[i] > 0) rotxvel[i] -= multiplier * 4;
122 if (rotx[i] < 0) rotxvel[i] += multiplier * 4;
123 if (rotxvel[i] > 0) rotxvel[i] -= multiplier * 4;
124 if (rotxvel[i] < 0) rotxvel[i] += multiplier * 4;
125 if (fabs(rotx[i]) < multiplier * 4)
127 if (fabs(rotxvel[i]) < multiplier * 4)
130 rotx[i] += rotxvel[i] * multiplier * 4;
132 if (rotyvel[i] || roty[i]) {
133 if (roty[i] > 0) rotyvel[i] -= multiplier * 8 * fabs(roty[i]);
134 if (roty[i] < 0) rotyvel[i] += multiplier * 8 * fabs(roty[i]);
135 if (roty[i] > 0) rotyvel[i] -= multiplier * 4;
136 if (roty[i] < 0) rotyvel[i] += multiplier * 4;
137 if (rotyvel[i] > 0) rotyvel[i] -= multiplier * 4;
138 if (rotyvel[i] < 0) rotyvel[i] += multiplier * 4;
139 if (fabs(roty[i]) < multiplier * 4)
141 if (fabs(rotyvel[i]) < multiplier * 4)
144 roty[i] += rotyvel[i] * multiplier * 4;
147 glRotatef(roty[i], 1, 0, 0);
150 glRotatef(-rotx[i], 0, 0, 1);
161 if (type[i] == treetrunktype || type[i] == treeleavestype) {
162 if (type[i] == treetrunktype || environment == 2) {
163 messedwith[i] -= multiplier;
164 if (rotxvel[i] || rotx[i]) {
165 if (rotx[i] > 0) rotxvel[i] -= multiplier * 8 * fabs(rotx[i]);
166 if (rotx[i] < 0) rotxvel[i] += multiplier * 8 * fabs(rotx[i]);
167 if (rotx[i] > 0) rotxvel[i] -= multiplier * 4;
168 if (rotx[i] < 0) rotxvel[i] += multiplier * 4;
169 if (rotxvel[i] > 0) rotxvel[i] -= multiplier * 4;
170 if (rotxvel[i] < 0) rotxvel[i] += multiplier * 4;
171 if (fabs(rotx[i]) < multiplier * 4)
173 if (fabs(rotxvel[i]) < multiplier * 4)
176 rotx[i] += rotxvel[i] * multiplier * 4;
178 if (rotyvel[i] || roty[i]) {
179 if (roty[i] > 0) rotyvel[i] -= multiplier * 8 * fabs(roty[i]);
180 if (roty[i] < 0) rotyvel[i] += multiplier * 8 * fabs(roty[i]);
181 if (roty[i] > 0) rotyvel[i] -= multiplier * 4;
182 if (roty[i] < 0) rotyvel[i] += multiplier * 4;
183 if (rotyvel[i] > 0) rotyvel[i] -= multiplier * 4;
184 if (rotyvel[i] < 0) rotyvel[i] += multiplier * 4;
185 if (fabs(roty[i]) < multiplier * 4)
187 if (fabs(rotyvel[i]) < multiplier * 4)
190 roty[i] += rotyvel[i] * multiplier * 4;
193 glRotatef(roty[i] / 6, 1, 0, 0);
196 glRotatef(-rotx[i] / 6, 0, 0, 1);
207 messedwith[i] -= multiplier;
208 if (rotxvel[i] || rotx[i]) {
209 if (rotx[i] > 0) rotxvel[i] -= multiplier * 8 * fabs(rotx[i]);
210 if (rotx[i] < 0) rotxvel[i] += multiplier * 8 * fabs(rotx[i]);
211 if (rotx[i] > 0) rotxvel[i] -= multiplier * 4;
212 if (rotx[i] < 0) rotxvel[i] += multiplier * 4;
213 if (rotxvel[i] > 0) rotxvel[i] -= multiplier * 4;
214 if (rotxvel[i] < 0) rotxvel[i] += multiplier * 4;
215 if (fabs(rotx[i]) < multiplier * 4)
217 if (fabs(rotxvel[i]) < multiplier * 4)
220 rotx[i] += rotxvel[i] * multiplier * 4;
222 if (rotyvel[i] || roty[i]) {
223 if (roty[i] > 0) rotyvel[i] -= multiplier * 8 * fabs(roty[i]);
224 if (roty[i] < 0) rotyvel[i] += multiplier * 8 * fabs(roty[i]);
225 if (roty[i] > 0) rotyvel[i] -= multiplier * 4;
226 if (roty[i] < 0) rotyvel[i] += multiplier * 4;
227 if (rotyvel[i] > 0) rotyvel[i] -= multiplier * 4;
228 if (rotyvel[i] < 0) rotyvel[i] += multiplier * 4;
229 if (fabs(roty[i]) < multiplier * 4)
231 if (fabs(rotyvel[i]) < multiplier * 4)
234 roty[i] += rotyvel[i] * multiplier * 4;
237 glRotatef(roty[i] / 4, 1, 0, 0);
240 glRotatef(-rotx[i] / 4, 0, 0, 1);
253 if (/*detail==2&&*/environment == snowyenvironment) {
254 if (type[i] == treeleavestype) {
255 glRotatef((sin(windvar + position[i].x * .3) + .5) * 1.5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
257 if (type[i] == treetrunktype) {
258 glRotatef((sin(windvar + position[i].x * .3) + .5)*.5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
260 if (type[i] == bushtype) {
261 glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
264 if (/*detail==2&&*/environment == grassyenvironment) {
265 if (type[i] == treeleavestype) {
266 glRotatef((sin(windvar + position[i].x * .3) + .5) * 1.5 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
268 if (type[i] == treetrunktype) {
269 glRotatef((sin(windvar + position[i].x * .3) + .5)*.5 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
271 if (type[i] == bushtype) {
272 glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
275 if (/*detail==2&&*/environment == desertenvironment) {
276 if (type[i] == bushtype) {
277 glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
280 glRotatef(yaw[i], 0, 1, 0);
283 glColor4f((1 - shadowed[i]) / 2 + .5, (1 - shadowed[i]) / 2 + .5, (1 - shadowed[i]) / 2 + .5, distance);
286 glAlphaFunc(GL_GREATER, 0.5);
290 glAlphaFunc(GL_GREATER, 0.1);
292 if (type[i] != treetrunktype && type[i] != treeleavestype && type[i] != bushtype && type[i] != rocktype) {
293 glEnable(GL_CULL_FACE);
294 glAlphaFunc(GL_GREATER, 0.0001);
295 model[i].drawdifftex(boxtextureptr);
296 model[i].drawdecals(terrain.shadowtexture, terrain.bloodtexture, terrain.bloodtexture2, terrain.breaktexture);
298 if (type[i] == rocktype) {
299 glEnable(GL_CULL_FACE);
300 glAlphaFunc(GL_GREATER, 0.0001);
301 glColor4f((1 - shadowed[i]) / 2 + light.ambient[0], (1 - shadowed[i]) / 2 + light.ambient[1], (1 - shadowed[i]) / 2 + light.ambient[2], distance);
302 model[i].drawdifftex(rocktextureptr);
303 model[i].drawdecals(terrain.shadowtexture, terrain.bloodtexture, terrain.bloodtexture2, terrain.breaktexture);
305 if (type[i] == treeleavestype) {
306 glDisable(GL_CULL_FACE);
307 glDisable(GL_LIGHTING);
308 terrainlight = terrain.getLighting(position[i].x, position[i].z);
310 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance);
312 glAlphaFunc(GL_GREATER, 0.2);
317 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance / 3);
318 glAlphaFunc(GL_GREATER, 0);
320 model[i].drawdifftex(treetextureptr);
322 if (type[i] == bushtype) {
323 glDisable(GL_CULL_FACE);
324 glDisable(GL_LIGHTING);
325 terrainlight = terrain.getLighting(position[i].x, position[i].z);
327 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance);
329 glAlphaFunc(GL_GREATER, 0.2);
334 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance / 3);
335 glAlphaFunc(GL_GREATER, 0);
337 model[i].drawdifftex(bushtextureptr);
339 if (type[i] == treetrunktype) {
340 glEnable(GL_CULL_FACE);
341 terrainlight = terrain.getLighting(position[i].x, position[i].z);
342 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance);
343 model[i].drawdifftex(treetextureptr);
353 glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
354 for (i = 0; i < numobjects; i++) {
355 if (type[i] == treeleavestype || type[i] == bushtype) {
356 moved = DoRotation(model[i].boundingspherecenter, 0, yaw[i], 0);
357 if (frustum.SphereInFrustum(position[i].x + moved.x, position[i].y + moved.y, position[i].z + moved.z, model[i].boundingsphereradius)) {
358 hidden = distsqflat(&viewer, &position[i]) <= playerdist + 3;
361 glMatrixMode(GL_MODELVIEW);
363 glEnable(GL_LIGHTING);
365 glTranslatef(position[i].x, position[i].y, position[i].z);
366 if (type[i] == bushtype) {
367 messedwith[i] -= multiplier;
368 if (rotxvel[i] || rotx[i]) {
369 if (rotx[i] > 0) rotxvel[i] -= multiplier * 8 * fabs(rotx[i]);
370 if (rotx[i] < 0) rotxvel[i] += multiplier * 8 * fabs(rotx[i]);
371 if (rotx[i] > 0) rotxvel[i] -= multiplier * 4;
372 if (rotx[i] < 0) rotxvel[i] += multiplier * 4;
373 if (rotxvel[i] > 0) rotxvel[i] -= multiplier * 4;
374 if (rotxvel[i] < 0) rotxvel[i] += multiplier * 4;
375 if (fabs(rotx[i]) < multiplier * 4)
377 if (fabs(rotxvel[i]) < multiplier * 4)
380 rotx[i] += rotxvel[i] * multiplier * 4;
382 if (rotyvel[i] || roty[i]) {
383 if (roty[i] > 0) rotyvel[i] -= multiplier * 8 * fabs(roty[i]);
384 if (roty[i] < 0) rotyvel[i] += multiplier * 8 * fabs(roty[i]);
385 if (roty[i] > 0) rotyvel[i] -= multiplier * 4;
386 if (roty[i] < 0) rotyvel[i] += multiplier * 4;
387 if (rotyvel[i] > 0) rotyvel[i] -= multiplier * 4;
388 if (rotyvel[i] < 0) rotyvel[i] += multiplier * 4;
389 if (fabs(roty[i]) < multiplier * 4)
391 if (fabs(rotyvel[i]) < multiplier * 4)
394 roty[i] += rotyvel[i] * multiplier * 4;
397 glRotatef(roty[i], 1, 0, 0);
400 glRotatef(-rotx[i], 0, 0, 1);
411 if (type[i] == treetrunktype || type[i] == treeleavestype) {
412 messedwith[i] -= multiplier;
413 if (rotxvel[i] || rotx[i]) {
414 if (rotx[i] > 0) rotxvel[i] -= multiplier * 8 * fabs(rotx[i]);
415 if (rotx[i] < 0) rotxvel[i] += multiplier * 8 * fabs(rotx[i]);
416 if (rotx[i] > 0) rotxvel[i] -= multiplier * 4;
417 if (rotx[i] < 0) rotxvel[i] += multiplier * 4;
418 if (rotxvel[i] > 0) rotxvel[i] -= multiplier * 4;
419 if (rotxvel[i] < 0) rotxvel[i] += multiplier * 4;
420 if (fabs(rotx[i]) < multiplier * 4)
422 if (fabs(rotxvel[i]) < multiplier * 4)
425 rotx[i] += rotxvel[i] * multiplier * 4;
427 if (rotyvel[i] || roty[i]) {
428 if (roty[i] > 0) rotyvel[i] -= multiplier * 8 * fabs(roty[i]);
429 if (roty[i] < 0) rotyvel[i] += multiplier * 8 * fabs(roty[i]);
430 if (roty[i] > 0) rotyvel[i] -= multiplier * 4;
431 if (roty[i] < 0) rotyvel[i] += multiplier * 4;
432 if (rotyvel[i] > 0) rotyvel[i] -= multiplier * 4;
433 if (rotyvel[i] < 0) rotyvel[i] += multiplier * 4;
434 if (fabs(roty[i]) < multiplier * 4)
436 if (fabs(rotyvel[i]) < multiplier * 4)
439 roty[i] += rotyvel[i] * multiplier * 4;
442 glRotatef(roty[i] / 2, 1, 0, 0);
445 glRotatef(-rotx[i] / 2, 0, 0, 1);
456 if (environment == snowyenvironment) {
457 if (type[i] == treeleavestype) {
458 glRotatef((sin(windvar + position[i].x * .3) + .5) * 1.5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
460 if (type[i] == treetrunktype) {
461 glRotatef((sin(windvar + position[i].x * .3) + .5)*.5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
463 if (type[i] == bushtype) {
464 glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
467 if (environment == grassyenvironment) {
468 if (type[i] == treeleavestype) {
469 glRotatef((sin(windvar + position[i].x * .3) + .5) * 1.5 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
471 if (type[i] == treetrunktype) {
472 glRotatef((sin(windvar + position[i].x * .3) + .5)*.5 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
474 if (type[i] == bushtype) {
475 glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
478 glRotatef(yaw[i], 0, 1, 0);
479 glColor4f(1, 1, 1, distance);
480 if (type[i] == treeleavestype) {
481 glDisable(GL_CULL_FACE);
482 glDisable(GL_LIGHTING);
483 terrainlight = terrain.getLighting(position[i].x, position[i].z);
486 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, .3);
487 glAlphaFunc(GL_GREATER, 0);
488 glDisable(GL_ALPHA_TEST);
489 model[i].drawdifftex(treetextureptr);
491 if (type[i] == bushtype) {
492 glDisable(GL_CULL_FACE);
493 glDisable(GL_LIGHTING);
494 terrainlight = terrain.getLighting(position[i].x, position[i].z);
497 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, .3);
498 glAlphaFunc(GL_GREATER, 0);
499 glDisable(GL_ALPHA_TEST);
500 model[i].drawdifftex(bushtextureptr);
507 if (environment == desertenvironment)
508 glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
509 glEnable(GL_ALPHA_TEST);
510 SetUpLight(&light, 0);
513 void Objects::DeleteObject(int which)
515 type[numobjects - 1] = 0;
516 yaw[numobjects - 1] = 0;
517 position[numobjects - 1] = 0;
518 scale[numobjects - 1] = 0;
519 friction[numobjects - 1] = 0;
524 void Objects::MakeObject(int atype, XYZ where, float ayaw, float ascale)
526 if ((atype != treeleavestype && atype != bushtype) || foliage == 1) {
527 scale[numobjects] = ascale;
528 if (atype == treeleavestype)
529 scale[numobjects] += fabs((float)(Random() % 100) / 900) * ascale;
531 onfire[numobjects] = 0;
532 flamedelay[numobjects] = 0;
533 type[numobjects] = atype;
535 if (atype == firetype)
536 onfire[numobjects] = 1;
538 position[numobjects] = where;
539 if (atype == bushtype)
540 position[numobjects].y = terrain.getHeight(position[numobjects].x, position[numobjects].z) - .3;
541 yaw[numobjects] = ayaw;
543 rotxvel[numobjects] = 0;
544 rotyvel[numobjects] = 0;
545 rotx[numobjects] = 0;
546 roty[numobjects] = 0;
548 if (atype == boxtype) model[numobjects].loaddecal((char *)":Data:Models:Box.solid", 0);
549 if (atype == cooltype) model[numobjects].loaddecal((char *)":Data:Models:Cool.solid", 0);
550 if (atype == walltype) model[numobjects].loaddecal((char *)":Data:Models:Wall.solid", 0);
551 if (atype == tunneltype) model[numobjects].loaddecal((char *)":Data:Models:Tunnel.solid", 0);
552 if (atype == chimneytype) model[numobjects].loaddecal((char *)":Data:Models:Chimney.solid", 0);
553 if (atype == spiketype) model[numobjects].load((char *)":Data:Models:Spike.solid", 0);
554 if (atype == weirdtype) model[numobjects].loaddecal((char *)":Data:Models:Weird.solid", 0);
555 if (atype == rocktype) model[numobjects].loaddecal((char *)":Data:Models:Rock.solid", 0);
556 if (atype == treetrunktype) model[numobjects].load((char *)":Data:Models:Treetrunk.solid", 0);
557 if (atype == treeleavestype) model[numobjects].load((char *)":Data:Models:Leaves.solid", 0);
558 if (atype == bushtype) model[numobjects].load((char *)":Data:Models:Bush.solid", 0);
560 if (atype == boxtype) friction[numobjects] = 1.5;
561 if (atype == cooltype) friction[numobjects] = 1.5;
562 if (atype == walltype) friction[numobjects] = 1.5;
563 if (atype == platformtype) friction[numobjects] = 1.5;
564 if (atype == tunneltype) friction[numobjects] = 1.5;
565 if (atype == chimneytype) friction[numobjects] = 1.5;
566 if (atype == rocktype) friction[numobjects] = .5;
567 if (atype == rocktype && ascale>.5) friction[numobjects] = 1.5;
568 if (atype == weirdtype) friction[numobjects] = 1.5;
569 if (atype == spiketype) friction[numobjects] = .4;
570 if (atype == treetrunktype) friction[numobjects] = .4;
571 if (atype == treeleavestype) friction[numobjects] = 0;
573 if (atype == platformtype) {
574 model[numobjects].loaddecal((char *)":Data:Models:Platform.solid", 0);
575 model[numobjects].Rotate(90, 0, 0);
578 if (type[numobjects] == boxtype || type[numobjects] == cooltype || type[numobjects] == spiketype || type[numobjects] == weirdtype || type[numobjects] == walltype || type[numobjects] == chimneytype || type[numobjects] == tunneltype || type[numobjects] == platformtype) {
579 model[numobjects].ScaleTexCoords(scale[numobjects] * 1.5);
581 if (type[numobjects] == rocktype) {
582 model[numobjects].ScaleTexCoords(scale[numobjects] * 3);
584 model[numobjects].flat = 1;
585 if (atype == treetrunktype || atype == treeleavestype || atype == rocktype) {
586 model[numobjects].flat = 0;
588 model[numobjects].Scale(.3 * scale[numobjects], .3 * scale[numobjects], .3 * scale[numobjects]);
589 model[numobjects].Rotate(90, 1, 1);
590 if (type[numobjects] == rocktype) {
591 model[numobjects].Rotate(ayaw * 5, 1, 1);
593 model[numobjects].CalculateNormals(1);
594 model[numobjects].ScaleNormals(-1, -1, -1);
596 if (atype == treetrunktype && position[numobjects].y < terrain.getHeight(position[numobjects].x, position[numobjects].z) + 1) {
598 terrain.MakeDecal(shadowdecalpermanent, position[numobjects], 2, .4, 0);
601 if (atype == bushtype && position[numobjects].y < terrain.getHeight(position[numobjects].x, position[numobjects].z) + 1) {
603 terrain.MakeDecal(shadowdecalpermanent, position[numobjects], 1, .4, 0);
606 if (atype != treeleavestype && atype != bushtype && atype != firetype)
607 terrain.AddObject(where + DoRotation(model[numobjects].boundingspherecenter, 0, ayaw, 0), model[numobjects].boundingsphereradius, numobjects);
613 void Objects::MakeObject(int atype, XYZ where, float ayaw, float apitch, float ascale)
615 if ((atype != treeleavestype && atype != bushtype) || foliage == 1) {
616 scale[numobjects] = ascale;
617 if (atype == treeleavestype)
618 scale[numobjects] += fabs((float)(Random() % 100) / 900) * ascale;
620 onfire[numobjects] = 0;
621 flamedelay[numobjects] = 0;
622 type[numobjects] = atype;
624 if (atype == firetype)
625 onfire[numobjects] = 1;
627 position[numobjects] = where;
628 if (atype == bushtype)
629 position[numobjects].y = terrain.getHeight(position[numobjects].x, position[numobjects].z) - .3;
630 yaw[numobjects] = ayaw;
631 pitch[numobjects] = apitch;
633 rotxvel[numobjects] = 0;
634 rotyvel[numobjects] = 0;
635 rotx[numobjects] = 0;
636 roty[numobjects] = 0;
638 if (atype == boxtype) model[numobjects].loaddecal((char *)":Data:Models:Box.solid", 0);
639 if (atype == cooltype) model[numobjects].loaddecal((char *)":Data:Models:Cool.solid", 0);
640 if (atype == walltype) model[numobjects].loaddecal((char *)":Data:Models:Wall.solid", 0);
641 if (atype == tunneltype) model[numobjects].loaddecal((char *)":Data:Models:Tunnel.solid", 0);
642 if (atype == chimneytype) model[numobjects].loaddecal((char *)":Data:Models:Chimney.solid", 0);
643 if (atype == spiketype) model[numobjects].load((char *)":Data:Models:Spike.solid", 0);
644 if (atype == weirdtype) model[numobjects].loaddecal((char *)":Data:Models:Weird.solid", 0);
645 if (atype == rocktype) model[numobjects].loaddecal((char *)":Data:Models:Rock.solid", 0);
646 if (atype == treetrunktype) model[numobjects].load((char *)":Data:Models:Treetrunk.solid", 0);
647 if (atype == treeleavestype) model[numobjects].load((char *)":Data:Models:Leaves.solid", 0);
648 if (atype == bushtype) model[numobjects].load((char *)":Data:Models:Bush.solid", 0);
650 if (atype == boxtype) friction[numobjects] = 1.5;
651 if (atype == cooltype) friction[numobjects] = 1.5;
652 if (atype == walltype) friction[numobjects] = 1.5;
653 if (atype == platformtype) friction[numobjects] = 1.5;
654 if (atype == tunneltype) friction[numobjects] = 1.5;
655 if (atype == chimneytype) friction[numobjects] = 1.5;
656 if (atype == rocktype) friction[numobjects] = .5;
657 if (atype == rocktype && ascale>.5) friction[numobjects] = 1.5;
658 if (atype == weirdtype) friction[numobjects] = 1.5;
659 if (atype == spiketype) friction[numobjects] = .4;
660 if (atype == treetrunktype) friction[numobjects] = .4;
661 if (atype == treeleavestype) friction[numobjects] = 0;
663 if (friction[numobjects] == 1.5 && fabs(apitch) > 5)
664 friction[numobjects] = .5;
666 if (atype == platformtype) {
667 model[numobjects].loaddecal((char *)":Data:Models:Platform.solid", 0);
668 model[numobjects].Rotate(90, 0, 0);
671 if (type[numobjects] == boxtype || type[numobjects] == cooltype || type[numobjects] == spiketype || type[numobjects] == weirdtype || type[numobjects] == walltype || type[numobjects] == chimneytype || type[numobjects] == tunneltype || type[numobjects] == platformtype) {
672 model[numobjects].ScaleTexCoords(scale[numobjects] * 1.5);
674 if (type[numobjects] == rocktype) {
675 model[numobjects].ScaleTexCoords(scale[numobjects] * 3);
677 model[numobjects].flat = 1;
678 if (atype == treetrunktype || atype == treeleavestype || atype == rocktype) {
679 model[numobjects].flat = 0;
681 model[numobjects].Scale(.3 * scale[numobjects], .3 * scale[numobjects], .3 * scale[numobjects]);
682 model[numobjects].Rotate(90, 1, 1);
683 model[numobjects].Rotate(apitch, 0, 0);
684 if (type[numobjects] == rocktype) {
685 model[numobjects].Rotate(ayaw * 5, 0, 0);
687 model[numobjects].CalculateNormals(1);
688 model[numobjects].ScaleNormals(-1, -1, -1);
690 if (atype == treetrunktype && position[numobjects].y < terrain.getHeight(position[numobjects].x, position[numobjects].z) + 1) {
692 terrain.MakeDecal(shadowdecalpermanent, position[numobjects], 2, .4, 0);
695 if (atype == bushtype && position[numobjects].y < terrain.getHeight(position[numobjects].x, position[numobjects].z) + 1) {
697 terrain.MakeDecal(shadowdecalpermanent, position[numobjects], 1, .4, 0);
700 if (atype != treeleavestype && atype != bushtype && atype != firetype)
701 terrain.AddObject(where + DoRotation(model[numobjects].boundingspherecenter, 0, ayaw, 0), model[numobjects].boundingsphereradius, numobjects);
707 void Objects::DoStuff()
710 for (int i = 0; i < numobjects; i++) {
711 if (type[i] == firetype)
714 if (type[i] == bushtype)
715 flamedelay[i] -= multiplier * 3;
716 if (type[i] == firetype)
717 flamedelay[i] -= multiplier * 3;
718 if (type[i] == treeleavestype)
719 flamedelay[i] -= multiplier * 4;
720 while (flamedelay[i] < 0 && onfire[i]) {
721 flamedelay[i] += .006;
722 if (type[i] == bushtype || type[i] == firetype) {
723 spawnpoint.x = ((float)(Random() % 100)) / 30 * scale[i];
724 spawnpoint.y = ((float)(Random() % 100) + 60) / 30 * scale[i];
726 spawnpoint = DoRotation(spawnpoint, 0, Random() % 360, 0);
727 spawnpoint += position[i];
728 Sprite::MakeSprite(flamesprite, spawnpoint, spawnpoint * 0, 1, 1, 1, (.6 + (float)abs(Random() % 100) / 200 - .25) * 5 * scale[i], 1);
730 if (type[i] == treeleavestype) {
731 spawnpoint.x = ((float)(Random() % 100)) / 80 * scale[i];
732 spawnpoint.y = ((float)(Random() % 100) + 80) / 12 * scale[i];
734 spawnpoint = DoRotation(spawnpoint, 0, Random() % 360, 0);
735 spawnpoint += position[i];
736 Sprite::MakeSprite(flamesprite, spawnpoint, spawnpoint * 0, 1, 1, 1, (.6 + (float)abs(Random() % 100) / 200 - .25) * 6, 1);
744 void Objects::DoShadows()
747 static XYZ testpoint, testpoint2, terrainpoint, lightloc, col;
748 lightloc = light.location;
752 Normalise(&lightloc);
756 for (i = 0; i < numobjects; i++) {
757 if (type[i] != treeleavestype && type[i] != treetrunktype && type[i] != bushtype && type[i] != firetype) {
758 for (j = 0; j < model[i].vertexNum; j++) {
759 terrainpoint = position[i] + DoRotation(model[i].vertex[j] + model[i].normals[j] * .1, 0, yaw[i], 0);
760 //terrainpoint.y+=model[i].boundingsphereradius;
762 patchx = terrainpoint.x / (terrain.size / subdivision * terrain.scale);
763 patchz = terrainpoint.z / (terrain.size / subdivision * terrain.scale);
764 if (patchx >= 0 && patchz >= 0 && patchx < subdivision && patchz < subdivision)
765 if (terrain.patchobjectnum[patchx][patchz])
766 for (k = 0; k < terrain.patchobjectnum[patchx][patchz]; k++) {
767 l = terrain.patchobjects[patchx][patchz][k];
768 if (type[l] != treetrunktype/*&&l!=i*/) {
769 testpoint = terrainpoint;
770 testpoint2 = terrainpoint + lightloc * 50 * (1 - shadowed[i]);
771 if (model[l].LineCheck(&testpoint, &testpoint2, &col, &position[l], &yaw[l]) != -1) {
772 shadowed[i] = 1 - (findDistance(&terrainpoint, &col) / 50);
776 if (shadowed[i] > 0) {
777 col = model[i].normals[j] - DoRotation(lightloc * shadowed[i], 0, -yaw[i], 0);
779 for (k = 0; k < model[i].TriangleNum; k++) {
780 if (model[i].Triangles[k].vertex[0] == j) {
782 model[i].vArray[l + 2] = col.x;
783 model[i].vArray[l + 3] = col.y;
784 model[i].vArray[l + 4] = col.z;
786 if (model[i].Triangles[k].vertex[1] == j) {
788 model[i].vArray[l + 10] = col.x;
789 model[i].vArray[l + 11] = col.y;
790 model[i].vArray[l + 12] = col.z;
792 if (model[i].Triangles[k].vertex[2] == j) {
794 model[i].vArray[l + 18] = col.x;
795 model[i].vArray[l + 19] = col.y;
796 model[i].vArray[l + 20] = col.z;
812 memset(position, 0, sizeof(position));
813 memset(type, 0, sizeof(type));
814 memset(yaw, 0, sizeof(yaw));
815 memset(pitch, 0, sizeof(pitch));
816 memset(rotx, 0, sizeof(rotx));
817 memset(rotxvel, 0, sizeof(rotxvel));
818 memset(roty, 0, sizeof(roty));
819 memset(rotyvel, 0, sizeof(rotyvel));
820 memset(possible, 0, sizeof(possible));
821 memset(model, 0, sizeof(model));
822 memset(displaymodel, 0, sizeof(displaymodel));
823 memset(friction, 0, sizeof(friction));
824 memset(scale, 0, sizeof(scale));
825 memset(messedwith, 0, sizeof(messedwith));
826 memset(checked, 0, sizeof(checked));
827 memset(shadowed, 0, sizeof(shadowed));
828 memset(occluded, 0, sizeof(occluded));
829 memset(onfire, 0, sizeof(onfire));
830 memset(flamedelay, 0, sizeof(flamedelay));
835 boxtextureptr.destroy();
836 treetextureptr.destroy();
837 bushtextureptr.destroy();
838 rocktextureptr.destroy();