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
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation; either version 2
9 of the License, or (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 See the GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 extern float viewdistance;
25 extern float fadestart;
26 extern int environment;
27 extern float texscale;
29 extern float multiplier;
31 extern FRUSTUM frustum;
32 extern Terrain terrain;
35 extern float blurness;
37 extern float playerdist;
38 extern bool skyboxtexture;
42 bool Objects::checkcollide(XYZ startpoint, XYZ endpoint, int which)
44 static XYZ colpoint, colviewer, coltarget;
52 for (i = 0; i < numobjects; i++) {
53 if (type[i] != treeleavestype && type[i] != treetrunktype && type[i] != bushtype && type[i] != firetype && i != which) {
54 colviewer = startpoint;
56 if (model[i].LineCheck(&colviewer, &coltarget, &colpoint, &position[i], &yaw[i]) != -1)
64 void Objects::SphereCheckPossible(XYZ *p1, float radius)
67 static int whichpatchx;
68 static int whichpatchz;
70 whichpatchx = p1->x / (terrain.size / subdivision * terrain.scale);
71 whichpatchz = p1->z / (terrain.size / subdivision * terrain.scale);
73 if (whichpatchx >= 0 && whichpatchz >= 0 && whichpatchx < subdivision && whichpatchz < subdivision)
74 if (terrain.patchobjectnum[whichpatchx][whichpatchz] > 0 && terrain.patchobjectnum[whichpatchx][whichpatchz] < 500)
75 for (j = 0; j < terrain.patchobjectnum[whichpatchx][whichpatchz]; j++) {
76 i = terrain.patchobjects[whichpatchx][whichpatchz][j];
78 if (model[i].SphereCheckPossible(p1, radius, &position[i], &yaw[i]) != -1) {
86 static float distance;
88 static XYZ moved, terrainlight;
91 for (i = 0; i < numobjects; i++) {
92 if (type[i] != firetype) {
93 moved = DoRotation(model[i].boundingspherecenter, 0, yaw[i], 0);
94 if (type[i] == tunneltype || frustum.SphereInFrustum(position[i].x + moved.x, position[i].y + moved.y, position[i].z + moved.z, model[i].boundingsphereradius)) {
95 distance = distsq(&viewer, &position[i]);
97 hidden = !(distsqflat(&viewer, &position[i]) > playerdist + 3 || (type[i] != bushtype && type[i] != treeleavestype));
100 if (detail == 2 && distance > viewdistance * viewdistance / 4 && environment == desertenvironment)
101 glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, blurness );
103 glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
104 distance = (viewdistance * viewdistance - (distance - (viewdistance * viewdistance * fadestart)) * (1 / (1 - fadestart))) / viewdistance / viewdistance;
109 /*if(checkcollide(viewer,DoRotation(model[i].vertex[model[i].vertexNum],0,yaw[i],0)*scale[i]+position[i],i)){
112 else occluded[i]=0;*/
113 if (occluded[i] < 6) {
114 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
117 glEnable(GL_LIGHTING);
119 glDisable(GL_LIGHTING);
121 glTranslatef(position[i].x, position[i].y, position[i].z);
122 if (type[i] == bushtype) {
123 messedwith[i] -= multiplier;
124 if (rotxvel[i] || rotx[i]) {
125 if (rotx[i] > 0) rotxvel[i] -= multiplier * 8 * fabs(rotx[i]);
126 if (rotx[i] < 0) rotxvel[i] += multiplier * 8 * fabs(rotx[i]);
127 if (rotx[i] > 0) rotxvel[i] -= multiplier * 4;
128 if (rotx[i] < 0) rotxvel[i] += multiplier * 4;
129 if (rotxvel[i] > 0) rotxvel[i] -= multiplier * 4;
130 if (rotxvel[i] < 0) rotxvel[i] += multiplier * 4;
131 if (fabs(rotx[i]) < multiplier * 4)
133 if (fabs(rotxvel[i]) < multiplier * 4)
136 rotx[i] += rotxvel[i] * multiplier * 4;
138 if (rotyvel[i] || roty[i]) {
139 if (roty[i] > 0) rotyvel[i] -= multiplier * 8 * fabs(roty[i]);
140 if (roty[i] < 0) rotyvel[i] += multiplier * 8 * fabs(roty[i]);
141 if (roty[i] > 0) rotyvel[i] -= multiplier * 4;
142 if (roty[i] < 0) rotyvel[i] += multiplier * 4;
143 if (rotyvel[i] > 0) rotyvel[i] -= multiplier * 4;
144 if (rotyvel[i] < 0) rotyvel[i] += multiplier * 4;
145 if (fabs(roty[i]) < multiplier * 4)
147 if (fabs(rotyvel[i]) < multiplier * 4)
150 roty[i] += rotyvel[i] * multiplier * 4;
153 glRotatef(roty[i], 1, 0, 0);
156 glRotatef(-rotx[i], 0, 0, 1);
167 if (type[i] == treetrunktype || type[i] == treeleavestype) {
168 if (type[i] == treetrunktype || environment == 2) {
169 messedwith[i] -= multiplier;
170 if (rotxvel[i] || rotx[i]) {
171 if (rotx[i] > 0) rotxvel[i] -= multiplier * 8 * fabs(rotx[i]);
172 if (rotx[i] < 0) rotxvel[i] += multiplier * 8 * fabs(rotx[i]);
173 if (rotx[i] > 0) rotxvel[i] -= multiplier * 4;
174 if (rotx[i] < 0) rotxvel[i] += multiplier * 4;
175 if (rotxvel[i] > 0) rotxvel[i] -= multiplier * 4;
176 if (rotxvel[i] < 0) rotxvel[i] += multiplier * 4;
177 if (fabs(rotx[i]) < multiplier * 4)
179 if (fabs(rotxvel[i]) < multiplier * 4)
182 rotx[i] += rotxvel[i] * multiplier * 4;
184 if (rotyvel[i] || roty[i]) {
185 if (roty[i] > 0) rotyvel[i] -= multiplier * 8 * fabs(roty[i]);
186 if (roty[i] < 0) rotyvel[i] += multiplier * 8 * fabs(roty[i]);
187 if (roty[i] > 0) rotyvel[i] -= multiplier * 4;
188 if (roty[i] < 0) rotyvel[i] += multiplier * 4;
189 if (rotyvel[i] > 0) rotyvel[i] -= multiplier * 4;
190 if (rotyvel[i] < 0) rotyvel[i] += multiplier * 4;
191 if (fabs(roty[i]) < multiplier * 4)
193 if (fabs(rotyvel[i]) < multiplier * 4)
196 roty[i] += rotyvel[i] * multiplier * 4;
199 glRotatef(roty[i] / 6, 1, 0, 0);
202 glRotatef(-rotx[i] / 6, 0, 0, 1);
213 messedwith[i] -= multiplier;
214 if (rotxvel[i] || rotx[i]) {
215 if (rotx[i] > 0) rotxvel[i] -= multiplier * 8 * fabs(rotx[i]);
216 if (rotx[i] < 0) rotxvel[i] += multiplier * 8 * fabs(rotx[i]);
217 if (rotx[i] > 0) rotxvel[i] -= multiplier * 4;
218 if (rotx[i] < 0) rotxvel[i] += multiplier * 4;
219 if (rotxvel[i] > 0) rotxvel[i] -= multiplier * 4;
220 if (rotxvel[i] < 0) rotxvel[i] += multiplier * 4;
221 if (fabs(rotx[i]) < multiplier * 4)
223 if (fabs(rotxvel[i]) < multiplier * 4)
226 rotx[i] += rotxvel[i] * multiplier * 4;
228 if (rotyvel[i] || roty[i]) {
229 if (roty[i] > 0) rotyvel[i] -= multiplier * 8 * fabs(roty[i]);
230 if (roty[i] < 0) rotyvel[i] += multiplier * 8 * fabs(roty[i]);
231 if (roty[i] > 0) rotyvel[i] -= multiplier * 4;
232 if (roty[i] < 0) rotyvel[i] += multiplier * 4;
233 if (rotyvel[i] > 0) rotyvel[i] -= multiplier * 4;
234 if (rotyvel[i] < 0) rotyvel[i] += multiplier * 4;
235 if (fabs(roty[i]) < multiplier * 4)
237 if (fabs(rotyvel[i]) < multiplier * 4)
240 roty[i] += rotyvel[i] * multiplier * 4;
243 glRotatef(roty[i] / 4, 1, 0, 0);
246 glRotatef(-rotx[i] / 4, 0, 0, 1);
259 if (/*detail==2&&*/environment == snowyenvironment) {
260 if (type[i] == treeleavestype) {
261 glRotatef((sin(windvar + position[i].x * .3) + .5) * 1.5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
263 if (type[i] == treetrunktype) {
264 glRotatef((sin(windvar + position[i].x * .3) + .5)*.5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
266 if (type[i] == bushtype) {
267 glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
270 if (/*detail==2&&*/environment == grassyenvironment) {
271 if (type[i] == treeleavestype) {
272 glRotatef((sin(windvar + position[i].x * .3) + .5) * 1.5 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
274 if (type[i] == treetrunktype) {
275 glRotatef((sin(windvar + position[i].x * .3) + .5)*.5 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
277 if (type[i] == bushtype) {
278 glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
281 if (/*detail==2&&*/environment == desertenvironment) {
282 if (type[i] == bushtype) {
283 glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
286 glRotatef(yaw[i], 0, 1, 0);
289 glColor4f((1 - shadowed[i]) / 2 + .5, (1 - shadowed[i]) / 2 + .5, (1 - shadowed[i]) / 2 + .5, distance);
292 glAlphaFunc(GL_GREATER, 0.5);
296 glAlphaFunc(GL_GREATER, 0.1);
298 if (type[i] != treetrunktype && type[i] != treeleavestype && type[i] != bushtype && type[i] != rocktype) {
299 glEnable(GL_CULL_FACE);
300 glAlphaFunc(GL_GREATER, 0.0001);
301 model[i].drawdifftex(boxtextureptr);
302 model[i].drawdecals(terrain.shadowtexture, terrain.bloodtexture, terrain.bloodtexture2, terrain.breaktexture);
304 if (type[i] == rocktype) {
305 glEnable(GL_CULL_FACE);
306 glAlphaFunc(GL_GREATER, 0.0001);
307 glColor4f((1 - shadowed[i]) / 2 + light.ambient[0], (1 - shadowed[i]) / 2 + light.ambient[1], (1 - shadowed[i]) / 2 + light.ambient[2], distance);
308 model[i].drawdifftex(rocktextureptr);
309 model[i].drawdecals(terrain.shadowtexture, terrain.bloodtexture, terrain.bloodtexture2, terrain.breaktexture);
311 if (type[i] == treeleavestype) {
312 glDisable(GL_CULL_FACE);
313 glDisable(GL_LIGHTING);
314 terrainlight = terrain.getLighting(position[i].x, position[i].z);
316 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance);
318 glAlphaFunc(GL_GREATER, 0.2);
323 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance / 3);
324 glAlphaFunc(GL_GREATER, 0);
326 model[i].drawdifftex(treetextureptr);
328 if (type[i] == bushtype) {
329 glDisable(GL_CULL_FACE);
330 glDisable(GL_LIGHTING);
331 terrainlight = terrain.getLighting(position[i].x, position[i].z);
333 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance);
335 glAlphaFunc(GL_GREATER, 0.2);
340 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance / 3);
341 glAlphaFunc(GL_GREATER, 0);
343 model[i].drawdifftex(bushtextureptr);
345 if (type[i] == treetrunktype) {
346 glEnable(GL_CULL_FACE);
347 terrainlight = terrain.getLighting(position[i].x, position[i].z);
348 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance);
349 model[i].drawdifftex(treetextureptr);
359 glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
360 for (i = 0; i < numobjects; i++) {
361 if (type[i] == treeleavestype || type[i] == bushtype) {
362 moved = DoRotation(model[i].boundingspherecenter, 0, yaw[i], 0);
363 if (frustum.SphereInFrustum(position[i].x + moved.x, position[i].y + moved.y, position[i].z + moved.z, model[i].boundingsphereradius)) {
364 hidden = distsqflat(&viewer, &position[i]) <= playerdist + 3;
368 if (1 == 1 || occluded[i] < 6) {
369 glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
371 glEnable(GL_LIGHTING);
373 glTranslatef(position[i].x, position[i].y, position[i].z);
374 if (type[i] == bushtype) {
375 messedwith[i] -= multiplier;
376 if (rotxvel[i] || rotx[i]) {
377 if (rotx[i] > 0) rotxvel[i] -= multiplier * 8 * fabs(rotx[i]);
378 if (rotx[i] < 0) rotxvel[i] += multiplier * 8 * fabs(rotx[i]);
379 if (rotx[i] > 0) rotxvel[i] -= multiplier * 4;
380 if (rotx[i] < 0) rotxvel[i] += multiplier * 4;
381 if (rotxvel[i] > 0) rotxvel[i] -= multiplier * 4;
382 if (rotxvel[i] < 0) rotxvel[i] += multiplier * 4;
383 if (fabs(rotx[i]) < multiplier * 4)
385 if (fabs(rotxvel[i]) < multiplier * 4)
388 rotx[i] += rotxvel[i] * multiplier * 4;
390 if (rotyvel[i] || roty[i]) {
391 if (roty[i] > 0) rotyvel[i] -= multiplier * 8 * fabs(roty[i]);
392 if (roty[i] < 0) rotyvel[i] += multiplier * 8 * fabs(roty[i]);
393 if (roty[i] > 0) rotyvel[i] -= multiplier * 4;
394 if (roty[i] < 0) rotyvel[i] += multiplier * 4;
395 if (rotyvel[i] > 0) rotyvel[i] -= multiplier * 4;
396 if (rotyvel[i] < 0) rotyvel[i] += multiplier * 4;
397 if (fabs(roty[i]) < multiplier * 4)
399 if (fabs(rotyvel[i]) < multiplier * 4)
402 roty[i] += rotyvel[i] * multiplier * 4;
405 glRotatef(roty[i], 1, 0, 0);
408 glRotatef(-rotx[i], 0, 0, 1);
419 if (type[i] == treetrunktype || type[i] == treeleavestype) {
420 messedwith[i] -= multiplier;
421 if (rotxvel[i] || rotx[i]) {
422 if (rotx[i] > 0) rotxvel[i] -= multiplier * 8 * fabs(rotx[i]);
423 if (rotx[i] < 0) rotxvel[i] += multiplier * 8 * fabs(rotx[i]);
424 if (rotx[i] > 0) rotxvel[i] -= multiplier * 4;
425 if (rotx[i] < 0) rotxvel[i] += multiplier * 4;
426 if (rotxvel[i] > 0) rotxvel[i] -= multiplier * 4;
427 if (rotxvel[i] < 0) rotxvel[i] += multiplier * 4;
428 if (fabs(rotx[i]) < multiplier * 4)
430 if (fabs(rotxvel[i]) < multiplier * 4)
433 rotx[i] += rotxvel[i] * multiplier * 4;
435 if (rotyvel[i] || roty[i]) {
436 if (roty[i] > 0) rotyvel[i] -= multiplier * 8 * fabs(roty[i]);
437 if (roty[i] < 0) rotyvel[i] += multiplier * 8 * fabs(roty[i]);
438 if (roty[i] > 0) rotyvel[i] -= multiplier * 4;
439 if (roty[i] < 0) rotyvel[i] += multiplier * 4;
440 if (rotyvel[i] > 0) rotyvel[i] -= multiplier * 4;
441 if (rotyvel[i] < 0) rotyvel[i] += multiplier * 4;
442 if (fabs(roty[i]) < multiplier * 4)
444 if (fabs(rotyvel[i]) < multiplier * 4)
447 roty[i] += rotyvel[i] * multiplier * 4;
450 glRotatef(roty[i] / 2, 1, 0, 0);
453 glRotatef(-rotx[i] / 2, 0, 0, 1);
464 if (environment == snowyenvironment) {
465 if (type[i] == treeleavestype) {
466 glRotatef((sin(windvar + position[i].x * .3) + .5) * 1.5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
468 if (type[i] == treetrunktype) {
469 glRotatef((sin(windvar + position[i].x * .3) + .5)*.5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
471 if (type[i] == bushtype) {
472 glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
475 if (environment == grassyenvironment) {
476 if (type[i] == treeleavestype) {
477 glRotatef((sin(windvar + position[i].x * .3) + .5) * 1.5 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
479 if (type[i] == treetrunktype) {
480 glRotatef((sin(windvar + position[i].x * .3) + .5)*.5 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
482 if (type[i] == bushtype) {
483 glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
486 glRotatef(yaw[i], 0, 1, 0);
487 glColor4f(1, 1, 1, distance);
488 if (type[i] == treeleavestype) {
489 glDisable(GL_CULL_FACE);
490 glDisable(GL_LIGHTING);
491 terrainlight = terrain.getLighting(position[i].x, position[i].z);
494 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, .3);
495 glAlphaFunc(GL_GREATER, 0);
496 glDisable(GL_ALPHA_TEST);
497 model[i].drawdifftex(treetextureptr);
499 if (type[i] == bushtype) {
500 glDisable(GL_CULL_FACE);
501 glDisable(GL_LIGHTING);
502 terrainlight = terrain.getLighting(position[i].x, position[i].z);
505 glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, .3);
506 glAlphaFunc(GL_GREATER, 0);
507 glDisable(GL_ALPHA_TEST);
508 model[i].drawdifftex(bushtextureptr);
517 if (environment == desertenvironment)
518 glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
519 glEnable(GL_ALPHA_TEST);
520 SetUpLight(&light, 0);
523 void Objects::DeleteObject(int which)
525 type[numobjects - 1] = 0;
526 yaw[numobjects - 1] = 0;
527 position[numobjects - 1] = 0;
528 scale[numobjects - 1] = 0;
529 friction[numobjects - 1] = 0;
534 void Objects::MakeObject(int atype, XYZ where, float ayaw, float ascale)
536 if ((atype != treeleavestype && atype != bushtype) || foliage == 1) {
537 scale[numobjects] = ascale;
538 if (atype == treeleavestype)
539 scale[numobjects] += fabs((float)(Random() % 100) / 900) * ascale;
541 onfire[numobjects] = 0;
542 flamedelay[numobjects] = 0;
543 type[numobjects] = atype;
545 if (atype == firetype)
546 onfire[numobjects] = 1;
548 position[numobjects] = where;
549 if (atype == bushtype)
550 position[numobjects].y = terrain.getHeight(position[numobjects].x, position[numobjects].z) - .3;
551 yaw[numobjects] = ayaw;
553 rotxvel[numobjects] = 0;
554 rotyvel[numobjects] = 0;
555 rotx[numobjects] = 0;
556 roty[numobjects] = 0;
558 if (atype == boxtype) model[numobjects].loaddecal((char *)":Data:Models:Box.solid", 0);
559 if (atype == cooltype) model[numobjects].loaddecal((char *)":Data:Models:Cool.solid", 0);
560 if (atype == walltype) model[numobjects].loaddecal((char *)":Data:Models:Wall.solid", 0);
561 if (atype == tunneltype) model[numobjects].loaddecal((char *)":Data:Models:Tunnel.solid", 0);
562 if (atype == chimneytype) model[numobjects].loaddecal((char *)":Data:Models:Chimney.solid", 0);
563 if (atype == spiketype) model[numobjects].load((char *)":Data:Models:Spike.solid", 0);
564 if (atype == weirdtype) model[numobjects].loaddecal((char *)":Data:Models:Weird.solid", 0);
565 if (atype == rocktype) model[numobjects].loaddecal((char *)":Data:Models:Rock.solid", 0);
566 if (atype == treetrunktype) model[numobjects].load((char *)":Data:Models:Treetrunk.solid", 0);
567 if (atype == treeleavestype) model[numobjects].load((char *)":Data:Models:Leaves.solid", 0);
568 if (atype == bushtype) model[numobjects].load((char *)":Data:Models:Bush.solid", 0);
570 if (atype == boxtype) friction[numobjects] = 1.5;
571 if (atype == cooltype) friction[numobjects] = 1.5;
572 if (atype == walltype) friction[numobjects] = 1.5;
573 if (atype == platformtype) friction[numobjects] = 1.5;
574 if (atype == tunneltype) friction[numobjects] = 1.5;
575 if (atype == chimneytype) friction[numobjects] = 1.5;
576 if (atype == rocktype) friction[numobjects] = .5;
577 if (atype == rocktype && ascale>.5) friction[numobjects] = 1.5;
578 if (atype == weirdtype) friction[numobjects] = 1.5;
579 if (atype == spiketype) friction[numobjects] = .4;
580 if (atype == treetrunktype) friction[numobjects] = .4;
581 if (atype == treeleavestype) friction[numobjects] = 0;
583 if (atype == platformtype) {
584 model[numobjects].loaddecal((char *)":Data:Models:Platform.solid", 0);
585 model[numobjects].Rotate(90, 0, 0);
588 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) {
589 model[numobjects].ScaleTexCoords(scale[numobjects] * 1.5);
591 if (type[numobjects] == rocktype) {
592 model[numobjects].ScaleTexCoords(scale[numobjects] * 3);
594 model[numobjects].flat = 1;
595 if (atype == treetrunktype || atype == treeleavestype || atype == rocktype) {
596 model[numobjects].flat = 0;
598 model[numobjects].Scale(.3 * scale[numobjects], .3 * scale[numobjects], .3 * scale[numobjects]);
599 model[numobjects].Rotate(90, 1, 1);
600 if (type[numobjects] == rocktype) {
601 model[numobjects].Rotate(ayaw * 5, 1, 1);
603 model[numobjects].CalculateNormals(1);
604 model[numobjects].ScaleNormals(-1, -1, -1);
606 if (atype == treetrunktype && position[numobjects].y < terrain.getHeight(position[numobjects].x, position[numobjects].z) + 1) {
608 terrain.MakeDecal(shadowdecalpermanent, position[numobjects], 2, .4, 0);
611 if (atype == bushtype && position[numobjects].y < terrain.getHeight(position[numobjects].x, position[numobjects].z) + 1) {
613 terrain.MakeDecal(shadowdecalpermanent, position[numobjects], 1, .4, 0);
616 if (atype != treeleavestype && atype != bushtype && atype != firetype)
617 terrain.AddObject(where + DoRotation(model[numobjects].boundingspherecenter, 0, ayaw, 0), model[numobjects].boundingsphereradius, numobjects);
623 void Objects::MakeObject(int atype, XYZ where, float ayaw, float apitch, float ascale)
625 if ((atype != treeleavestype && atype != bushtype) || foliage == 1) {
626 scale[numobjects] = ascale;
627 if (atype == treeleavestype)
628 scale[numobjects] += fabs((float)(Random() % 100) / 900) * ascale;
630 onfire[numobjects] = 0;
631 flamedelay[numobjects] = 0;
632 type[numobjects] = atype;
634 if (atype == firetype)
635 onfire[numobjects] = 1;
637 position[numobjects] = where;
638 if (atype == bushtype)
639 position[numobjects].y = terrain.getHeight(position[numobjects].x, position[numobjects].z) - .3;
640 /*if(atype==firetype){
641 if(position[numobjects].y<terrain.getHeight(position[numobjects].x,position[numobjects].z)-.3)
642 position[numobjects].y=terrain.getHeight(position[numobjects].x,position[numobjects].z)-.3;
644 yaw[numobjects] = ayaw;
645 pitch[numobjects] = apitch;
647 rotxvel[numobjects] = 0;
648 rotyvel[numobjects] = 0;
649 rotx[numobjects] = 0;
650 roty[numobjects] = 0;
652 if (atype == boxtype) model[numobjects].loaddecal((char *)":Data:Models:Box.solid", 0);
653 if (atype == cooltype) model[numobjects].loaddecal((char *)":Data:Models:Cool.solid", 0);
654 if (atype == walltype) model[numobjects].loaddecal((char *)":Data:Models:Wall.solid", 0);
655 if (atype == tunneltype) model[numobjects].loaddecal((char *)":Data:Models:Tunnel.solid", 0);
656 if (atype == chimneytype) model[numobjects].loaddecal((char *)":Data:Models:Chimney.solid", 0);
657 if (atype == spiketype) model[numobjects].load((char *)":Data:Models:Spike.solid", 0);
658 if (atype == weirdtype) model[numobjects].loaddecal((char *)":Data:Models:Weird.solid", 0);
659 if (atype == rocktype) model[numobjects].loaddecal((char *)":Data:Models:Rock.solid", 0);
660 if (atype == treetrunktype) model[numobjects].load((char *)":Data:Models:Treetrunk.solid", 0);
661 if (atype == treeleavestype) model[numobjects].load((char *)":Data:Models:Leaves.solid", 0);
662 if (atype == bushtype) model[numobjects].load((char *)":Data:Models:Bush.solid", 0);
664 if (atype == boxtype) friction[numobjects] = 1.5;
665 if (atype == cooltype) friction[numobjects] = 1.5;
666 if (atype == walltype) friction[numobjects] = 1.5;
667 if (atype == platformtype) friction[numobjects] = 1.5;
668 if (atype == tunneltype) friction[numobjects] = 1.5;
669 if (atype == chimneytype) friction[numobjects] = 1.5;
670 if (atype == rocktype) friction[numobjects] = .5;
671 if (atype == rocktype && ascale>.5) friction[numobjects] = 1.5;
672 if (atype == weirdtype) friction[numobjects] = 1.5;
673 if (atype == spiketype) friction[numobjects] = .4;
674 if (atype == treetrunktype) friction[numobjects] = .4;
675 if (atype == treeleavestype) friction[numobjects] = 0;
677 if (friction[numobjects] == 1.5 && fabs(apitch) > 5)
678 friction[numobjects] = .5;
680 if (atype == platformtype) {
681 model[numobjects].loaddecal((char *)":Data:Models:Platform.solid", 0);
682 model[numobjects].Rotate(90, 0, 0);
685 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) {
686 model[numobjects].ScaleTexCoords(scale[numobjects] * 1.5);
688 if (type[numobjects] == rocktype) {
689 model[numobjects].ScaleTexCoords(scale[numobjects] * 3);
691 model[numobjects].flat = 1;
692 if (atype == treetrunktype || atype == treeleavestype || atype == rocktype) {
693 model[numobjects].flat = 0;
695 model[numobjects].Scale(.3 * scale[numobjects], .3 * scale[numobjects], .3 * scale[numobjects]);
696 model[numobjects].Rotate(90, 1, 1);
697 model[numobjects].Rotate(apitch, 0, 0);
698 if (type[numobjects] == rocktype) {
699 model[numobjects].Rotate(ayaw * 5, 0, 0);
701 model[numobjects].CalculateNormals(1);
702 model[numobjects].ScaleNormals(-1, -1, -1);
704 if (atype == treetrunktype && position[numobjects].y < terrain.getHeight(position[numobjects].x, position[numobjects].z) + 1) {
706 terrain.MakeDecal(shadowdecalpermanent, position[numobjects], 2, .4, 0);
709 if (atype == bushtype && position[numobjects].y < terrain.getHeight(position[numobjects].x, position[numobjects].z) + 1) {
711 terrain.MakeDecal(shadowdecalpermanent, position[numobjects], 1, .4, 0);
714 if (atype != treeleavestype && atype != bushtype && atype != firetype)
715 terrain.AddObject(where + DoRotation(model[numobjects].boundingspherecenter, 0, ayaw, 0), model[numobjects].boundingsphereradius, numobjects);
721 void Objects::DoStuff()
724 for (int i = 0; i < numobjects; i++) {
725 /*if(type[i]==firetype){
726 Sprite::MakeSprite(weaponshinesprite, position[i],position[i]*0, 1,1,1, 5, 1);
729 if (type[i] == firetype)
732 if (type[i] == bushtype)
733 flamedelay[i] -= multiplier * 3;
734 if (type[i] == firetype)
735 flamedelay[i] -= multiplier * 3;
736 if (type[i] == treeleavestype)
737 flamedelay[i] -= multiplier * 4;
738 while (flamedelay[i] < 0 && onfire[i]) {
739 flamedelay[i] += .006;
740 if (type[i] == bushtype || type[i] == firetype) {
741 spawnpoint.x = ((float)(Random() % 100)) / 30 * scale[i];
742 spawnpoint.y = ((float)(Random() % 100) + 60) / 30 * scale[i];
744 spawnpoint = DoRotation(spawnpoint, 0, Random() % 360, 0);
745 spawnpoint += position[i];
746 Sprite::MakeSprite(flamesprite, spawnpoint, spawnpoint * 0, 1, 1, 1, (.6 + (float)abs(Random() % 100) / 200 - .25) * 5 * scale[i], 1);
748 if (type[i] == treeleavestype) {
749 spawnpoint.x = ((float)(Random() % 100)) / 80 * scale[i];
750 spawnpoint.y = ((float)(Random() % 100) + 80) / 12 * scale[i];
752 spawnpoint = DoRotation(spawnpoint, 0, Random() % 360, 0);
753 spawnpoint += position[i];
754 Sprite::MakeSprite(flamesprite, spawnpoint, spawnpoint * 0, 1, 1, 1, (.6 + (float)abs(Random() % 100) / 200 - .25) * 6, 1);
762 void Objects::DoShadows()
765 static XYZ testpoint, testpoint2, terrainpoint, lightloc, col;
766 lightloc = light.location;
770 Normalise(&lightloc);
774 for (i = 0; i < numobjects; i++) {
775 if (type[i] != treeleavestype && type[i] != treetrunktype && type[i] != bushtype && type[i] != firetype) {
776 for (j = 0; j < model[i].vertexNum; j++) {
777 terrainpoint = position[i] + DoRotation(model[i].vertex[j] + model[i].normals[j] * .1, 0, yaw[i], 0);
778 //terrainpoint.y+=model[i].boundingsphereradius;
780 patchx = terrainpoint.x / (terrain.size / subdivision * terrain.scale);
781 patchz = terrainpoint.z / (terrain.size / subdivision * terrain.scale);
782 if (patchx >= 0 && patchz >= 0 && patchx < subdivision && patchz < subdivision)
783 if (terrain.patchobjectnum[patchx][patchz])
784 for (k = 0; k < terrain.patchobjectnum[patchx][patchz]; k++) {
785 l = terrain.patchobjects[patchx][patchz][k];
786 if (type[l] != treetrunktype/*&&l!=i*/) {
787 testpoint = terrainpoint;
788 testpoint2 = terrainpoint + lightloc * 50 * (1 - shadowed[i]);
789 if (model[l].LineCheck(&testpoint, &testpoint2, &col, &position[l], &yaw[l]) != -1) {
790 shadowed[i] = 1 - (findDistance(&terrainpoint, &col) / 50);
794 if (shadowed[i] > 0) {
795 col = model[i].normals[j] - DoRotation(lightloc * shadowed[i], 0, -yaw[i], 0);
797 for (k = 0; k < model[i].TriangleNum; k++) {
798 if (model[i].Triangles[k].vertex[0] == j) {
800 model[i].vArray[l + 2] = col.x;
801 model[i].vArray[l + 3] = col.y;
802 model[i].vArray[l + 4] = col.z;
804 if (model[i].Triangles[k].vertex[1] == j) {
806 model[i].vArray[l + 10] = col.x;
807 model[i].vArray[l + 11] = col.y;
808 model[i].vArray[l + 12] = col.z;
810 if (model[i].Triangles[k].vertex[2] == j) {
812 model[i].vArray[l + 18] = col.x;
813 model[i].vArray[l + 19] = col.y;
814 model[i].vArray[l + 20] = col.z;
830 memset(position, 0, sizeof(position));
831 memset(type, 0, sizeof(type));
832 memset(yaw, 0, sizeof(yaw));
833 memset(pitch, 0, sizeof(pitch));
834 memset(rotx, 0, sizeof(rotx));
835 memset(rotxvel, 0, sizeof(rotxvel));
836 memset(roty, 0, sizeof(roty));
837 memset(rotyvel, 0, sizeof(rotyvel));
838 memset(possible, 0, sizeof(possible));
839 memset(model, 0, sizeof(model));
840 memset(displaymodel, 0, sizeof(displaymodel));
841 memset(friction, 0, sizeof(friction));
842 memset(scale, 0, sizeof(scale));
843 memset(messedwith, 0, sizeof(messedwith));
844 memset(checked, 0, sizeof(checked));
845 memset(shadowed, 0, sizeof(shadowed));
846 memset(occluded, 0, sizeof(occluded));
847 memset(onfire, 0, sizeof(onfire));
848 memset(flamedelay, 0, sizeof(flamedelay));
853 boxtextureptr.destroy();
854 treetextureptr.destroy();
855 bushtextureptr.destroy();
856 rocktextureptr.destroy();