]> git.jsancho.org Git - lugaru.git/commitdiff
Cleaned up Objects handling
authorCôme Chilliet <come@chilliet.eu>
Wed, 14 Dec 2016 18:40:07 +0000 (01:40 +0700)
committerCôme Chilliet <come@chilliet.eu>
Thu, 15 Dec 2016 10:54:03 +0000 (17:54 +0700)
Checkcollide in Object is unused.
Game::checkcollide is used instead, it should be cleaned and moved to
Object class.

21 files changed:
CMakeLists.txt
Source/Animation/Skeleton.cpp
Source/Animation/Skeleton.hpp
Source/Devtools/ConsoleCmds.cpp
Source/Environment/Terrain.cpp
Source/Game.hpp
Source/GameDraw.cpp
Source/GameInitDispose.cpp
Source/GameTick.cpp
Source/Globals.cpp
Source/Graphic/Sprite.cpp
Source/Graphic/Sprite.hpp
Source/Objects/Object.cpp [new file with mode: 0644]
Source/Objects/Object.hpp [new file with mode: 0644]
Source/Objects/Objects.cpp [deleted file]
Source/Objects/Objects.hpp [deleted file]
Source/Objects/Person.cpp
Source/Objects/Weapons.cpp
Source/Thirdparty/optionparser.h
Source/Utils/binio.h
Source/win-res/resource.hpp

index 1c55e5798acd19bf4242b055d7136b49f2802a4c..58693544d74f30c8adbee32b5c52f9d9787ed53b 100644 (file)
@@ -66,7 +66,7 @@ set(LUGARU_SRCS
     ${SRCDIR}/Math/Frustum.cpp
     ${SRCDIR}/Math/Quaternions.cpp
     ${SRCDIR}/Menu/Menu.cpp
-    ${SRCDIR}/Objects/Objects.cpp
+    ${SRCDIR}/Objects/Object.cpp
     ${SRCDIR}/Objects/Person.cpp
     ${SRCDIR}/Objects/Weapons.cpp
     ${SRCDIR}/User/Account.cpp
@@ -110,7 +110,7 @@ set(LUGARU_H
     ${SRCDIR}/Math/Quaternions.hpp
     ${SRCDIR}/Math/Random.hpp
     ${SRCDIR}/Menu/Menu.hpp
-    ${SRCDIR}/Objects/Objects.hpp
+    ${SRCDIR}/Objects/Object.hpp
     ${SRCDIR}/Objects/Person.hpp
     ${SRCDIR}/Objects/Weapons.hpp
     ${SRCDIR}/Thirdparty/optionparser.h
index c7565984fddbc7cd4f983e134e63a4f0848b0ffb..31f98860c8528fc05f82caad26144bda85a3e9e3 100644 (file)
@@ -28,7 +28,6 @@ along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
 extern float multiplier;
 extern float gravity;
 extern Terrain terrain;
-extern Objects objects;
 extern int environment;
 extern float camerashake;
 extern bool freeze;
@@ -134,7 +133,7 @@ float Skeleton::DoConstraints(XYZ *coords, float *scale)
         whichpatchz = coords->z / (terrain.size / subdivision * terrain.scale);
 
         terrainlight = *coords;
-        objects.SphereCheckPossible(&terrainlight, 1);
+        Object::SphereCheckPossible(&terrainlight, 1);
 
         //Add velocity
         for (i = 0; i < joints.size(); i++) {
@@ -276,7 +275,7 @@ float Skeleton::DoConstraints(XYZ *coords, float *scale)
                             // FIXME: this crashes because k is not initialized!
                             // to reproduce, type 'wolfie' in console and play a while
                             // I'll just comment it out for now
-                            //objects.model[k].MakeDecal(breakdecal, DoRotation(temp - objects.position[k], 0, -objects.yaw[k], 0), .4, .5, Random() % 360);
+                            //Object::objects[k]->model.MakeDecal(breakdecal, DoRotation(temp - Object::objects[k]->position, 0, -Object::objects[k]->yaw, 0), .4, .5, Random() % 360);
                             Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, 1, 1, 1, 4, .2);
                             breaking = false;
                             camerashake += .6;
@@ -327,12 +326,12 @@ float Skeleton::DoConstraints(XYZ *coords, float *scale)
                 if (terrain.patchobjectnum[whichpatchx][whichpatchz])
                     for (m = 0; m < terrain.patchobjectnum[whichpatchx][whichpatchz]; m++) {
                         k = terrain.patchobjects[whichpatchx][whichpatchz][m];
-                        if (k < objects.numobjects && k >= 0)
-                            if (objects.possible[k]) {
-                                friction = objects.friction[k];
+                        if (k < Object::objects.size() && k >= 0)
+                            if (Object::objects[k]->possible) {
+                                friction = Object::objects[k]->friction;
                                 XYZ start = joints[i].realoldposition;
                                 XYZ end = joints[i].position * (*scale) + *coords;
-                                whichhit = objects.model[k].LineCheckPossible(&start, &end, &temp, &objects.position[k], &objects.yaw[k]);
+                                whichhit = Object::objects[k]->model.LineCheckPossible(&start, &end, &temp, &Object::objects[k]->position, &Object::objects[k]->yaw);
                                 if (whichhit != -1) {
                                     if (joints[i].label == groin && !joints[i].locked && joints[i].delay <= 0) {
                                         joints[i].locked = 1;
@@ -351,7 +350,7 @@ float Skeleton::DoConstraints(XYZ *coords, float *scale)
                                         }
                                     }
 
-                                    terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1;
+                                    terrainnormal = DoRotation(Object::objects[k]->model.facenormals[whichhit], 0, Object::objects[k]->yaw, 0) * -1;
                                     if (terrainnormal.y > .8)
                                         freefall = 0;
                                     bounceness = terrainnormal * findLength(&joints[i].velocity) * (abs(normaldotproduct(joints[i].velocity, terrainnormal)));
@@ -361,7 +360,7 @@ float Skeleton::DoConstraints(XYZ *coords, float *scale)
                                     }
                                     if (tutoriallevel != 1 || id == 0)
                                         if (findLengthfast(&bounceness) > 4000 && breaking) {
-                                            objects.model[k].MakeDecal(breakdecal, DoRotation(temp - objects.position[k], 0, -objects.yaw[k], 0), .4, .5, Random() % 360);
+                                            Object::objects[k]->model.MakeDecal(breakdecal, DoRotation(temp - Object::objects[k]->position, 0, -Object::objects[k]->yaw, 0), .4, .5, Random() % 360);
                                             Sprite::MakeSprite(cloudsprite, joints[i].position * (*scale) + *coords, joints[i].velocity * .06, 1, 1, 1, 4, .2);
                                             breaking = false;
                                             camerashake += .6;
@@ -370,11 +369,11 @@ float Skeleton::DoConstraints(XYZ *coords, float *scale)
 
                                             addEnvSound(*coords, 64);
                                         }
-                                    if (objects.type[k] == treetrunktype) {
-                                        objects.rotx[k] += joints[i].velocity.x * multiplier * .4;
-                                        objects.roty[k] += joints[i].velocity.z * multiplier * .4;
-                                        objects.rotx[k + 1] += joints[i].velocity.x * multiplier * .4;
-                                        objects.roty[k + 1] += joints[i].velocity.z * multiplier * .4;
+                                    if (Object::objects[k]->type == treetrunktype) {
+                                        Object::objects[k]->rotx += joints[i].velocity.x * multiplier * .4;
+                                        Object::objects[k]->roty += joints[i].velocity.z * multiplier * .4;
+                                        Object::objects[k + 1]->rotx += joints[i].velocity.x * multiplier * .4;
+                                        Object::objects[k + 1]->roty += joints[i].velocity.z * multiplier * .4;
                                     }
                                     if (!joints[i].locked)
                                         damage += findLengthfast(&bounceness) / 2500;
@@ -413,12 +412,12 @@ float Skeleton::DoConstraints(XYZ *coords, float *scale)
         if (terrain.patchobjectnum[whichpatchx][whichpatchz])
             for (m = 0; m < terrain.patchobjectnum[whichpatchx][whichpatchz]; m++) {
                 k = terrain.patchobjects[whichpatchx][whichpatchz][m];
-                if (objects.possible[k]) {
+                if (Object::objects[k]->possible) {
                     for (i = 0; i < 26; i++) {
                         //Make this less stupid
                         XYZ start = joints[jointlabels[whichjointstartarray[i]]].position * (*scale) + *coords;
                         XYZ end = joints[jointlabels[whichjointendarray[i]]].position * (*scale) + *coords;
-                        whichhit = objects.model[k].LineCheckSlidePossible(&start, &end, &temp, &objects.position[k], &objects.yaw[k]);
+                        whichhit = Object::objects[k]->model.LineCheckSlidePossible(&start, &end, &temp, &Object::objects[k]->position, &Object::objects[k]->yaw);
                         if (whichhit != -1) {
                             joints[jointlabels[whichjointendarray[i]]].position = (end - *coords) / (*scale);
                             for (unsigned j = 0; j < muscles.size(); j++) {
index 668506276af1d9771f510b5f5b2c083c77b2141c..bbf91edd07f9fdbd53edc5be65fcf1d2ff83ddc7 100644 (file)
@@ -28,7 +28,7 @@ along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
 #include "Graphic/Models.hpp"
 #include "Graphic/Sprite.hpp"
 #include "Math/Quaternions.hpp"
-#include "Objects/Objects.hpp"
+#include "Objects/Object.hpp"
 #include "Utils/binio.h"
 
 const int max_joints = 50;
index 6b30e3f038d6ae08b0d162bb3c73263ab3cd31c6..baa1463893dae10c5dbab20b068de2002900c766 100644 (file)
@@ -52,7 +52,6 @@ extern float slomofreq;
 extern int tutoriallevel;
 extern int hostile;
 extern int maptype;
-extern Objects objects;
 extern int slomo;
 extern float slomodelay;
 extern bool skyboxtexture;
@@ -210,11 +209,11 @@ void ch_save(const char *args)
 
     fpackf(tfile, "Bi", environment);
 
-    fpackf(tfile, "Bi", objects.numobjects);
+    fpackf(tfile, "Bi", Object::objects.size());
 
-    for (int k = 0; k < objects.numobjects; k++)
-        fpackf(tfile, "Bi Bf Bf Bf Bf Bf Bf", objects.type[k], objects.yaw[k], objects.pitch[k],
-               objects.position[k].x, objects.position[k].y, objects.position[k].z, objects.scale[k]);
+    for (int k = 0; k < Object::objects.size(); k++)
+        fpackf(tfile, "Bi Bf Bf Bf Bf Bf Bf", Object::objects[k]->type, Object::objects[k]->yaw, Object::objects[k]->pitch,
+               Object::objects[k]->position.x, Object::objects[k]->position.y, Object::objects[k]->position.z, Object::objects[k]->scale);
 
     fpackf(tfile, "Bi", Hotspot::hotspots.size());
     for (unsigned i = 0; i < Hotspot::hotspots.size(); i++) {
@@ -717,7 +716,7 @@ void ch_skytint(const char *args)
     SetUpLighting();
 
     terrain.DoShadows();
-    objects.DoShadows();
+    Object::DoShadows();
 }
 
 void ch_skylight(const char *args)
@@ -727,7 +726,7 @@ void ch_skylight(const char *args)
     SetUpLighting();
 
     terrain.DoShadows();
-    objects.DoShadows();
+    Object::DoShadows();
 }
 
 void ch_skybox(const char *args)
@@ -737,5 +736,5 @@ void ch_skybox(const char *args)
     SetUpLighting();
 
     terrain.DoShadows();
-    objects.DoShadows();
+    Object::DoShadows();
 }
index 164dce38fd6a02739d221c4e5282204584d6283a..77ae539fb4af977cfc335c76630e63dea60df39e 100644 (file)
@@ -21,7 +21,7 @@ along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
 #include "Environment/Terrain.hpp"
 
 #include "Game.hpp"
-#include "Objects/Objects.hpp"
+#include "Objects/Object.hpp"
 #include "Utils/Folders.hpp"
 
 extern XYZ viewer;
@@ -37,7 +37,6 @@ extern int detail;
 extern bool decals;
 extern float blurness;
 extern float targetblurness;
-extern Objects objects;
 extern bool visibleloading;
 extern bool skyboxtexture;
 extern int tutoriallevel;
@@ -1387,10 +1386,10 @@ void Terrain::DoShadows()
             if (patchobjectnum[patchx][patchz]) {
                 for (k = 0; k < patchobjectnum[patchx][patchz]; k++) {
                     l = patchobjects[patchx][patchz][k];
-                    if (objects.type[l] != treetrunktype) {
+                    if (Object::objects[l]->type != treetrunktype) {
                         testpoint = terrainpoint;
                         testpoint2 = terrainpoint + lightloc * 50 * (1 - shadowed);
-                        if (objects.model[l].LineCheck(&testpoint, &testpoint2, &col, &objects.position[l], &objects.yaw[l]) != -1) {
+                        if (Object::objects[l]->model.LineCheck(&testpoint, &testpoint2, &col, &Object::objects[l]->position, &Object::objects[l]->yaw) != -1) {
                             shadowed = 1 - (findDistance(&terrainpoint, &col) / 50);
                         }
                     }
index 48294146d3a45476ac3eba286aa4fb06fd687e5c..32f094d9cddfaae6fbe41e342b4bb67a62b3b25b 100644 (file)
@@ -32,7 +32,7 @@ along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
 #include "Graphic/Stereo.hpp"
 #include "Graphic/Text.hpp"
 #include "Graphic/Texture.hpp"
-#include "Objects/Objects.hpp"
+#include "Objects/Object.hpp"
 #include "Objects/Person.hpp"
 #include "Objects/Weapons.hpp"
 #include "Thirdparty/optionparser.h"
@@ -152,6 +152,7 @@ void SetUpLighting();
 GLvoid ReSizeGLScene(float fov, float near);
 int checkcollide(XYZ startpoint, XYZ endpoint);
 int checkcollide(XYZ startpoint, XYZ endpoint, int what);
+int checkcollide(XYZ startpoint, XYZ endpoint, float minx, float miny, float minz, float maxx, float maxy, float maxz, int what);
 
 void fireSound(int sound = fireendsound);
 
index 8f33c0cbe8338fdd448b2535fff063a8204cf602..fa7da1ccfa1fb8dd7ba17aa51cea38abbee05885 100644 (file)
@@ -39,7 +39,6 @@ extern float screenwidth, screenheight;
 extern int kTextureSize;
 extern FRUSTUM frustum;
 extern Light light;
-extern Objects objects;
 extern int detail;
 extern float usermousesensitivity;
 extern float camerashake;
@@ -300,7 +299,7 @@ int Game::DrawGLScene(StereoSide side)
         glTranslatef(-viewer.x, -viewer.y, -viewer.z);
         frustum.GetFrustum();
 
-        //make shadow decals on terrain and objects
+        //make shadow decals on terrain and Object::objects
         static XYZ point;
         static float size, opacity, rotation;
         rotation = 0;
@@ -318,14 +317,14 @@ int Game::DrawGLScene(StereoSide side)
                             terrain.MakeDecal(shadowdecal, point, size, opacity, rotation);
                             for (l = 0; l < terrain.patchobjectnum[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz]; l++) {
                                 int j = terrain.patchobjects[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz][l];
-                                if (objects.position[j].y < Person::players[k]->coords.y || objects.type[j] == tunneltype || objects.type[j] == weirdtype) {
-                                    point = DoRotation(DoRotation(Person::players[k]->skeleton.joints[i].position, 0, Person::players[k]->yaw, 0) * Person::players[k]->scale + Person::players[k]->coords - objects.position[j], 0, -objects.yaw[j], 0);
+                                if (Object::objects[j]->position.y < Person::players[k]->coords.y || Object::objects[j]->type == tunneltype || Object::objects[j]->type == weirdtype) {
+                                    point = DoRotation(DoRotation(Person::players[k]->skeleton.joints[i].position, 0, Person::players[k]->yaw, 0) * Person::players[k]->scale + Person::players[k]->coords - Object::objects[j]->position, 0, -Object::objects[j]->yaw, 0);
                                     size = .4f;
                                     opacity = .4f;
                                     if (k != 0 && tutoriallevel == 1) {
                                         opacity = .2 + .2 * sin(smoketex * 6 + i);
                                     }
-                                    objects.model[j].MakeDecal(shadowdecal, &point, &size, &opacity, &rotation);
+                                    Object::objects[j]->model.MakeDecal(shadowdecal, &point, &size, &opacity, &rotation);
                                 }
                             }
                         }
@@ -346,17 +345,17 @@ int Game::DrawGLScene(StereoSide side)
                             terrain.MakeDecal(shadowdecal, point, size, opacity * .7, rotation);
                             for (l = 0; l < terrain.patchobjectnum[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz]; l++) {
                                 int j = terrain.patchobjects[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz][l];
-                                if (objects.position[j].y < Person::players[k]->coords.y || objects.type[j] == tunneltype || objects.type[j] == weirdtype) {
+                                if (Object::objects[j]->position.y < Person::players[k]->coords.y || Object::objects[j]->type == tunneltype || Object::objects[j]->type == weirdtype) {
                                     if (Person::players[k]->skeleton.free)
-                                        point = DoRotation(Person::players[k]->skeleton.joints[i].position * Person::players[k]->scale + Person::players[k]->coords - objects.position[j], 0, -objects.yaw[j], 0);
+                                        point = DoRotation(Person::players[k]->skeleton.joints[i].position * Person::players[k]->scale + Person::players[k]->coords - Object::objects[j]->position, 0, -Object::objects[j]->yaw, 0);
                                     else
-                                        point = DoRotation(DoRotation(Person::players[k]->skeleton.joints[i].position, 0, Person::players[k]->yaw, 0) * Person::players[k]->scale + Person::players[k]->coords - objects.position[j], 0, -objects.yaw[j], 0);
+                                        point = DoRotation(DoRotation(Person::players[k]->skeleton.joints[i].position, 0, Person::players[k]->yaw, 0) * Person::players[k]->scale + Person::players[k]->coords - Object::objects[j]->position, 0, -Object::objects[j]->yaw, 0);
                                     size = .4f;
                                     opacity = .4f;
                                     if (k != 0 && tutoriallevel == 1) {
                                         opacity = .2 + .2 * sin(smoketex * 6 + i);
                                     }
-                                    objects.model[j].MakeDecal(shadowdecal, &point, &size, &opacity, &rotation);
+                                    Object::objects[j]->model.MakeDecal(shadowdecal, &point, &size, &opacity, &rotation);
                                 }
                             }
                         }
@@ -370,10 +369,10 @@ int Game::DrawGLScene(StereoSide side)
                     terrain.MakeDecal(shadowdecal, point, size, opacity * .7, rotation);
                     for (l = 0; l < terrain.patchobjectnum[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz]; l++) {
                         int j = terrain.patchobjects[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz][l];
-                        point = DoRotation(Person::players[k]->coords - objects.position[j], 0, -objects.yaw[j], 0);
+                        point = DoRotation(Person::players[k]->coords - Object::objects[j]->position, 0, -Object::objects[j]->yaw, 0);
                         size = .7;
                         opacity = .4f;
-                        objects.model[j].MakeDecal(shadowdecal, &point, &size, &opacity, &rotation);
+                        Object::objects[j]->model.MakeDecal(shadowdecal, &point, &size, &opacity, &rotation);
                     }
                 }
         }
@@ -445,7 +444,7 @@ int Game::DrawGLScene(StereoSide side)
         glPushMatrix();
         glCullFace(GL_BACK);
         glEnable(GL_TEXTURE_2D);
-        objects.Draw();
+        Object::Draw();
         glPopMatrix();
 
         //draw hawk
@@ -1374,15 +1373,15 @@ int Game::DrawGLScene(StereoSide side)
             glPopMatrix();
             glRotatef(Person::players[0]->lookyaw * -1 + 180, 0, 0, 1);
             glTranslatef(-(center.x / terrain.scale / 256 * -2 + 1), (center.z / terrain.scale / 256 * -2 + 1), 0);
-            for (int i = 0; i < objects.numobjects; i++) {
-                if (objects.type[i] == treetrunktype) {
-                    distcheck = distsq(&Person::players[0]->coords, &objects.position[i]);
+            for (int i = 0; i < Object::objects.size(); i++) {
+                if (Object::objects[i]->type == treetrunktype) {
+                    distcheck = distsq(&Person::players[0]->coords, &Object::objects[i]->position);
                     if (distcheck < mapviewdist) {
                         Mapcircletexture.bind();
                         glColor4f(0, .3, 0, opac * (1 - distcheck / mapviewdist));
                         glPushMatrix();
-                        glTranslatef(objects.position[i].x / terrain.scale / 256 * -2 + 1, objects.position[i].z / terrain.scale / 256 * 2 - 1, 0);
-                        glRotatef(objects.yaw[i], 0, 0, 1);
+                        glTranslatef(Object::objects[i]->position.x / terrain.scale / 256 * -2 + 1, Object::objects[i]->position.z / terrain.scale / 256 * 2 - 1, 0);
+                        glRotatef(Object::objects[i]->yaw, 0, 0, 1);
                         glScalef(.003, .003, .003);
                         glBegin(GL_QUADS);
                         glTexCoord2f(0, 0);
@@ -1397,15 +1396,15 @@ int Game::DrawGLScene(StereoSide side)
                         glPopMatrix();
                     }
                 }
-                if (objects.type[i] == boxtype) {
-                    distcheck = distsq(&Person::players[0]->coords, &objects.position[i]);
+                if (Object::objects[i]->type == boxtype) {
+                    distcheck = distsq(&Person::players[0]->coords, &Object::objects[i]->position);
                     if (distcheck < mapviewdist) {
                         Mapboxtexture.bind();
                         glColor4f(.4, .4, .4, opac * (1 - distcheck / mapviewdist));
                         glPushMatrix();
-                        glTranslatef(objects.position[i].x / terrain.scale / 256 * -2 + 1, objects.position[i].z / terrain.scale / 256 * 2 - 1, 0);
-                        glRotatef(objects.yaw[i], 0, 0, 1);
-                        glScalef(.01 * objects.scale[i], .01 * objects.scale[i], .01 * objects.scale[i]);
+                        glTranslatef(Object::objects[i]->position.x / terrain.scale / 256 * -2 + 1, Object::objects[i]->position.z / terrain.scale / 256 * 2 - 1, 0);
+                        glRotatef(Object::objects[i]->yaw, 0, 0, 1);
+                        glScalef(.01 * Object::objects[i]->scale, .01 * Object::objects[i]->scale, .01 * Object::objects[i]->scale);
                         glBegin(GL_QUADS);
                         glTexCoord2f(0, 0);
                         glVertex3f(-1, -1, 0.0f);
index a8d3ce82c93ceda305dbce7d70100694c00b1a6d..38815d9ee56206ef427bde0020460026dcae30da 100644 (file)
@@ -38,7 +38,6 @@ extern int kTextureSize;
 extern float texdetail;
 extern float realtexdetail;
 extern float volume;
-extern Objects objects;
 extern int detail;
 extern bool cellophane;
 extern GLubyte bloodText[512 * 512 * 3];
index 34b22e0df8a88f8df8739e619839afd5620f228c..68010da4ee70514eede346cd5cbcdd984d90be60 100644 (file)
@@ -68,7 +68,6 @@ extern float screenwidth, screenheight;
 extern float gravity;
 extern int detail;
 extern float texdetail;
-extern Objects objects;
 extern int slomo;
 extern float slomodelay;
 extern bool floatjump;
@@ -318,8 +317,8 @@ static int findClosestObject()
     int closest = -1;
     float closestdist = std::numeric_limits<float>::max();
 
-    for (int i = 0; i < objects.numobjects; i++) {
-        float distance = distsq(&objects.position[i], &Person::players[0]->coords);
+    for (int i = 0; i < Object::objects.size(); i++) {
+        float distance = distsq(&Object::objects[i]->position, &Person::players[0]->coords);
         if (distance < closestdist) {
             closestdist = distance;
             closest = i;
@@ -431,19 +430,19 @@ int Game::checkcollide(XYZ startpoint, XYZ endpoint)
     maxy = max(startpoint.y, endpoint.y) + 1;
     maxz = max(startpoint.z, endpoint.z) + 1;
 
-    for (int i = 0; i < objects.numobjects; i++) {
-        if (     objects.position[i].x > minx - objects.model[i].boundingsphereradius &&
-                 objects.position[i].x < maxx + objects.model[i].boundingsphereradius &&
-                 objects.position[i].y > miny - objects.model[i].boundingsphereradius &&
-                 objects.position[i].y < maxy + objects.model[i].boundingsphereradius &&
-                 objects.position[i].z > minz - objects.model[i].boundingsphereradius &&
-                 objects.position[i].z < maxz + objects.model[i].boundingsphereradius) {
-            if (     objects.type[i] != treeleavestype &&
-                     objects.type[i] != bushtype &&
-                     objects.type[i] != firetype) {
+    for (int i = 0; i < Object::objects.size(); i++) {
+        if (     Object::objects[i]->position.x > minx - Object::objects[i]->model.boundingsphereradius &&
+                 Object::objects[i]->position.x < maxx + Object::objects[i]->model.boundingsphereradius &&
+                 Object::objects[i]->position.y > miny - Object::objects[i]->model.boundingsphereradius &&
+                 Object::objects[i]->position.y < maxy + Object::objects[i]->model.boundingsphereradius &&
+                 Object::objects[i]->position.z > minz - Object::objects[i]->model.boundingsphereradius &&
+                 Object::objects[i]->position.z < maxz + Object::objects[i]->model.boundingsphereradius) {
+            if (     Object::objects[i]->type != treeleavestype &&
+                     Object::objects[i]->type != bushtype &&
+                     Object::objects[i]->type != firetype) {
                 colviewer = startpoint;
                 coltarget = endpoint;
-                if (objects.model[i].LineCheck(&colviewer, &coltarget, &colpoint, &objects.position[i], &objects.yaw[i]) != -1)
+                if (Object::objects[i]->model.LineCheck(&colviewer, &coltarget, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw) != -1)
                     return i;
             }
         }
@@ -466,19 +465,19 @@ int Game::checkcollide(XYZ startpoint, XYZ endpoint, int what)
     maxz = max(startpoint.z, endpoint.z) + 1;
 
     if (what != 1000) {
-        if (     objects.position[what].x > minx - objects.model[what].boundingsphereradius &&
-                 objects.position[what].x < maxx + objects.model[what].boundingsphereradius &&
-                 objects.position[what].y > miny - objects.model[what].boundingsphereradius &&
-                 objects.position[what].y < maxy + objects.model[what].boundingsphereradius &&
-                 objects.position[what].z > minz - objects.model[what].boundingsphereradius &&
-                 objects.position[what].z < maxz + objects.model[what].boundingsphereradius) {
-            if (     objects.type[what] != treeleavestype &&
-                     objects.type[what] != bushtype &&
-                     objects.type[what] != firetype) {
+        if (     Object::objects[what]->position.x > minx - Object::objects[what]->model.boundingsphereradius &&
+                 Object::objects[what]->position.x < maxx + Object::objects[what]->model.boundingsphereradius &&
+                 Object::objects[what]->position.y > miny - Object::objects[what]->model.boundingsphereradius &&
+                 Object::objects[what]->position.y < maxy + Object::objects[what]->model.boundingsphereradius &&
+                 Object::objects[what]->position.z > minz - Object::objects[what]->model.boundingsphereradius &&
+                 Object::objects[what]->position.z < maxz + Object::objects[what]->model.boundingsphereradius) {
+            if (     Object::objects[what]->type != treeleavestype &&
+                     Object::objects[what]->type != bushtype &&
+                     Object::objects[what]->type != firetype) {
                 colviewer = startpoint;
                 coltarget = endpoint;
                 //FIXME: i/what
-                if (objects.model[what].LineCheck(&colviewer, &coltarget, &colpoint, &objects.position[what], &objects.yaw[what]) != -1)
+                if (Object::objects[what]->model.LineCheck(&colviewer, &coltarget, &colpoint, &Object::objects[what]->position, &Object::objects[what]->yaw) != -1)
                     return i;
             }
         }
@@ -513,10 +512,10 @@ void Setenvironment(int which)
         if (ambientsound)
             emit_stream_np(stream_wind);
 
-        objects.treetextureptr.load("Textures/SnowTree.png", 0);
-        objects.bushtextureptr.load("Textures/BushSnow.png", 0);
-        objects.rocktextureptr.load("Textures/BoulderSnow.jpg", 1);
-        objects.boxtextureptr.load("Textures/SnowBox.jpg", 1);
+        Object::treetextureptr.load("Textures/SnowTree.png", 0);
+        Object::bushtextureptr.load("Textures/BushSnow.png", 0);
+        Object::rocktextureptr.load("Textures/BoulderSnow.jpg", 1);
+        Object::boxtextureptr.load("Textures/SnowBox.jpg", 1);
 
         footstepsound = footstepsn1;
         footstepsound2 = footstepsn2;
@@ -544,10 +543,10 @@ void Setenvironment(int which)
     } else if (environment == desertenvironment) {
         windvector = 0;
         windvector.z = 2;
-        objects.treetextureptr.load("Textures/DesertTree.png", 0);
-        objects.bushtextureptr.load("Textures/BushDesert.png", 0);
-        objects.rocktextureptr.load("Textures/BoulderDesert.jpg", 1);
-        objects.boxtextureptr.load("Textures/DesertBox.jpg", 1);
+        Object::treetextureptr.load("Textures/DesertTree.png", 0);
+        Object::bushtextureptr.load("Textures/BushDesert.png", 0);
+        Object::rocktextureptr.load("Textures/BoulderDesert.jpg", 1);
+        Object::boxtextureptr.load("Textures/DesertBox.jpg", 1);
 
 
         if (ambientsound)
@@ -579,10 +578,10 @@ void Setenvironment(int which)
     } else if (environment == grassyenvironment) {
         windvector = 0;
         windvector.z = 2;
-        objects.treetextureptr.load("Textures/Tree.png", 0);
-        objects.bushtextureptr.load("Textures/Bush.png", 0);
-        objects.rocktextureptr.load("Textures/Boulder.jpg", 1);
-        objects.boxtextureptr.load("Textures/GrassBox.jpg", 1);
+        Object::treetextureptr.load("Textures/Tree.png", 0);
+        Object::bushtextureptr.load("Textures/Bush.png", 0);
+        Object::rocktextureptr.load("Textures/Boulder.jpg", 1);
+        Object::boxtextureptr.load("Textures/GrassBox.jpg", 1);
 
         if (ambientsound)
             emit_stream_np(stream_wind, 100.);
@@ -737,19 +736,12 @@ void Game::Loadlevel(const std::string& name)
     if (!stealthloading) {
         terrain.numdecals = 0;
         Sprite::deleteSprites();
-        for (int i = 0; i < objects.numobjects; i++)
-            objects.model[i].numdecals = 0;
-
-        int j = objects.numobjects;
-        for (int i = 0; i < j; i++) {
-            objects.DeleteObject(0);
-            if (visibleloading)
-                LoadingScreen();
-        }
 
-        for (int i = 0; i < subdivision; i++)
-            for (int j = 0; j < subdivision; j++)
+        for (int i = 0; i < subdivision; i++) {
+            for (int j = 0; j < subdivision; j++) {
                 terrain.patchobjectnum[i][j] = 0;
+            }
+        }
         if (visibleloading)
             LoadingScreen();
     }
@@ -844,12 +836,7 @@ void Game::Loadlevel(const std::string& name)
 
     funpackf(tfile, "Bi", &environment);
 
-    funpackf(tfile, "Bi", &objects.numobjects);
-    for (int i = 0; i < objects.numobjects; i++) {
-        funpackf(tfile, "Bi Bf Bf Bf Bf Bf Bf", &objects.type[i], &objects.yaw[i], &objects.pitch[i], &objects.position[i].x, &objects.position[i].y, &objects.position[i].z, &objects.scale[i]);
-        if (objects.type[i] == treeleavestype)
-            objects.scale[i] = objects.scale[i - 1];
-    }
+    Object::LoadObjectsFromFile(tfile, stealthloading);
 
     if (mapvers >= 7) {
         int numhotspots;
@@ -877,24 +864,12 @@ void Game::Loadlevel(const std::string& name)
         LoadingScreen();
 
     if (!stealthloading) {
-        objects.center = 0;
-        for (int i = 0; i < objects.numobjects; i++)
-            objects.center += objects.position[i];
-        objects.center /= objects.numobjects;
-
+        Object::ComputeCenter();
 
         if (visibleloading)
             LoadingScreen();
 
-        float maxdistance = 0;
-        float tempdist;
-        for (int i = 0; i < objects.numobjects; i++) {
-            tempdist = distsq(&objects.center, &objects.position[i]);
-            if (tempdist > maxdistance) {
-                maxdistance = tempdist;
-            }
-        }
-        objects.radius = fast_sqrt(maxdistance);
+        Object::ComputeRadius();
     }
 
     if (visibleloading)
@@ -937,18 +912,11 @@ void Game::Loadlevel(const std::string& name)
     oldenvironment = environment;
 
     if (!stealthloading) {
-        int j = objects.numobjects;
-        objects.numobjects = 0;
-        for (int i = 0; i < j; i++) {
-            objects.MakeObject(objects.type[i], objects.position[i], objects.yaw[i], objects.pitch[i], objects.scale[i]);
-            if (visibleloading)
-                LoadingScreen();
-        }
-
+        Object::AddObjectsToTerrain();
         terrain.DoShadows();
         if (visibleloading)
             LoadingScreen();
-        objects.DoShadows();
+        Object::DoShadows();
         if (visibleloading)
             LoadingScreen();
     }
@@ -1681,9 +1649,9 @@ void doDevKeys()
 
         /* Grow tree leaves?? */
         if (Input::isKeyPressed(SDL_SCANCODE_Y)) {
-            for (int i = 0; i < objects.numobjects; i++) {
-                if (objects.type[i] == treeleavestype) {
-                    objects.scale[i] *= .9;
+            for (int i = 0; i < Object::objects.size(); i++) {
+                if (Object::objects[i]->type == treeleavestype) {
+                    Object::objects[i]->scale *= .9;
                 }
             }
         }
@@ -2024,12 +1992,13 @@ void doDevKeys()
 
         if (Input::isKeyPressed(SDL_SCANCODE_DELETE) && Input::isKeyDown(SDL_SCANCODE_LCTRL)) {
             int closest = findClosestObject();
-            if (closest >= 0)
-                objects.position[closest].y -= 500;
+            if (closest >= 0) {
+                Object::objects[closest]->position.y -= 500;
+            }
         }
 
         if (Input::isKeyPressed(SDL_SCANCODE_M) && Input::isKeyDown(SDL_SCANCODE_LSHIFT)) {
-            if (objects.numobjects < max_objects - 1) {
+            if (Object::objects.size() < max_objects - 1) {
                 XYZ scenecoords;
                 scenecoords.x = Person::players[0]->coords.x;
                 scenecoords.z = Person::players[0]->coords.z;
@@ -2046,9 +2015,9 @@ void doDevKeys()
                 if (temprotat2 < 0)
                     temprotat2 = Random() % 360;
 
-                objects.MakeObject(editortype, scenecoords, (int)temprotat - ((int)temprotat) % 30, (int)temprotat2, editorsize);
+                Object::MakeObject(editortype, scenecoords, (int)temprotat - ((int)temprotat) % 30, (int)temprotat2, editorsize);
                 if (editortype == treetrunktype)
-                    objects.MakeObject(treeleavestype, scenecoords, Random() % 360 * (temprotat2 < 2) + (int)editoryaw - ((int)editoryaw) % 30, editorpitch, editorsize);
+                    Object::MakeObject(treeleavestype, scenecoords, Random() % 360 * (temprotat2 < 2) + (int)editoryaw - ((int)editoryaw) % 30, editorpitch, editorsize);
             }
         }
 
@@ -2193,11 +2162,13 @@ void doDevKeys()
             if (pathpointselected >= numpathpoints)
                 pathpointselected = -1;
         }
+
         if (Input::isKeyPressed(SDL_SCANCODE_COMMA) && !Input::isKeyDown(SDL_SCANCODE_LSHIFT)) {
             pathpointselected--;
             if (pathpointselected <= -2)
                 pathpointselected = numpathpoints - 1;
         }
+
         if (Input::isKeyPressed(SDL_SCANCODE_COMMA) && Input::isKeyDown(SDL_SCANCODE_LSHIFT)) {
             if (pathpointselected != -1) {
                 numpathpoints--;
@@ -2265,6 +2236,7 @@ void doDevKeys()
         if (Input::isKeyPressed(SDL_SCANCODE_RIGHT) && Input::isKeyDown(SDL_SCANCODE_LSHIFT) && Input::isKeyDown(SDL_SCANCODE_LCTRL)) {
             mapradius += multiplier * 10;
         }
+
         if (Input::isKeyDown(SDL_SCANCODE_UP) && Input::isKeyDown(SDL_SCANCODE_LCTRL)) {
             editorpitch += multiplier * 100;
         }
@@ -2274,10 +2246,12 @@ void doDevKeys()
             if (editorpitch < -.01)
                 editorpitch = -.01;
         }
-        if (Input::isKeyPressed(SDL_SCANCODE_DELETE) && objects.numobjects && Input::isKeyDown(SDL_SCANCODE_LSHIFT)) {
+
+        if (Input::isKeyPressed(SDL_SCANCODE_DELETE) && Object::objects.size() && Input::isKeyDown(SDL_SCANCODE_LSHIFT)) {
             int closest = findClosestObject();
-            if (closest >= 0)
-                objects.DeleteObject(closest);
+            if (closest >= 0) {
+                Object::DeleteObject(closest);
+            }
         }
     }
 }
@@ -2444,9 +2418,9 @@ void doAerialAcrobatics()
 
             for (int l = 0; l < terrain.patchobjectnum[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz]; l++) {
                 int i = terrain.patchobjects[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz][l];
-                if (objects.type[i] != rocktype ||
-                        objects.scale[i] > .5 && Person::players[k]->aitype == playercontrolled ||
-                        objects.position[i].y > Person::players[k]->coords.y) {
+                if (Object::objects[i]->type != rocktype ||
+                        Object::objects[i]->scale > .5 && Person::players[k]->aitype == playercontrolled ||
+                        Object::objects[i]->position.y > Person::players[k]->coords.y) {
                     lowpoint = Person::players[k]->coords;
                     if (Person::players[k]->animTarget != jumpupanim &&
                             Person::players[k]->animTarget != jumpdownanim &&
@@ -2457,7 +2431,7 @@ void doAerialAcrobatics()
                     if (     Person::players[k]->coords.y < terrain.getHeight(Person::players[k]->coords.x, Person::players[k]->coords.z) &&
                              Person::players[k]->coords.y > terrain.getHeight(Person::players[k]->coords.x, Person::players[k]->coords.z) - .1)
                         Person::players[k]->coords.y = terrain.getHeight(Person::players[k]->coords.x, Person::players[k]->coords.z);
-                    if (Person::players[k]->SphereCheck(&lowpoint, 1.3, &colpoint, &objects.position[i], &objects.yaw[i], &objects.model[i]) != -1) {
+                    if (Person::players[k]->SphereCheck(&lowpoint, 1.3, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw, &Object::objects[i]->model) != -1) {
                         flatfacing = lowpoint - Person::players[k]->coords;
                         Person::players[k]->coords = lowpoint;
                         Person::players[k]->coords.y -= 1.3;
@@ -2473,14 +2447,14 @@ void doAerialAcrobatics()
                                 Person::players[k]->jumpkeydown) {
                             lowpointtarget = lowpoint + DoRotation(Person::players[k]->facing, 0, -90, 0) * 1.5;
                             XYZ tempcoords1 = lowpoint;
-                            whichhit = objects.model[i].LineCheck(&lowpoint, &lowpointtarget, &colpoint, &objects.position[i], &objects.yaw[i]);
-                            if (whichhit != -1 && fabs(objects.model[i].facenormals[whichhit].y) < .3) {
+                            whichhit = Object::objects[i]->model.LineCheck(&lowpoint, &lowpointtarget, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw);
+                            if (whichhit != -1 && fabs(Object::objects[i]->model.facenormals[whichhit].y) < .3) {
                                 Person::players[k]->setAnimation(walljumpleftanim);
                                 emit_sound_at(movewhooshsound, Person::players[k]->coords);
                                 if (k == 0)
                                     pause_sound(whooshsound);
 
-                                lowpointtarget = DoRotation(objects.model[i].facenormals[whichhit], 0, objects.yaw[i], 0);
+                                lowpointtarget = DoRotation(Object::objects[i]->model.facenormals[whichhit], 0, Object::objects[i]->yaw, 0);
                                 Person::players[k]->yaw = -asin(0 - lowpointtarget.x) * 180 / M_PI;
                                 if (lowpointtarget.z < 0)
                                     Person::players[k]->yaw = 180 - Person::players[k]->yaw;
@@ -2491,14 +2465,14 @@ void doAerialAcrobatics()
                             } else {
                                 lowpoint = tempcoords1;
                                 lowpointtarget = lowpoint + DoRotation(Person::players[k]->facing, 0, 90, 0) * 1.5;
-                                whichhit = objects.model[i].LineCheck(&lowpoint, &lowpointtarget, &colpoint, &objects.position[i], &objects.yaw[i]);
-                                if (whichhit != -1 && fabs(objects.model[i].facenormals[whichhit].y) < .3) {
+                                whichhit = Object::objects[i]->model.LineCheck(&lowpoint, &lowpointtarget, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw);
+                                if (whichhit != -1 && fabs(Object::objects[i]->model.facenormals[whichhit].y) < .3) {
                                     Person::players[k]->setAnimation(walljumprightanim);
                                     emit_sound_at(movewhooshsound, Person::players[k]->coords);
                                     if (k == 0)
                                         pause_sound(whooshsound);
 
-                                    lowpointtarget = DoRotation(objects.model[i].facenormals[whichhit], 0, objects.yaw[i], 0);
+                                    lowpointtarget = DoRotation(Object::objects[i]->model.facenormals[whichhit], 0, Object::objects[i]->yaw, 0);
                                     Person::players[k]->yaw = -asin(0 - lowpointtarget.x) * 180 / M_PI;
                                     if (lowpointtarget.z < 0)
                                         Person::players[k]->yaw = 180 - Person::players[k]->yaw;
@@ -2509,14 +2483,14 @@ void doAerialAcrobatics()
                                 } else {
                                     lowpoint = tempcoords1;
                                     lowpointtarget = lowpoint + Person::players[k]->facing * 2;
-                                    whichhit = objects.model[i].LineCheck(&lowpoint, &lowpointtarget, &colpoint, &objects.position[i], &objects.yaw[i]);
-                                    if (whichhit != -1 && fabs(objects.model[i].facenormals[whichhit].y) < .3) {
+                                    whichhit = Object::objects[i]->model.LineCheck(&lowpoint, &lowpointtarget, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw);
+                                    if (whichhit != -1 && fabs(Object::objects[i]->model.facenormals[whichhit].y) < .3) {
                                         Person::players[k]->setAnimation(walljumpbackanim);
                                         emit_sound_at(movewhooshsound, Person::players[k]->coords);
                                         if (k == 0)
                                             pause_sound(whooshsound);
 
-                                        lowpointtarget = DoRotation(objects.model[i].facenormals[whichhit], 0, objects.yaw[i], 0);
+                                        lowpointtarget = DoRotation(Object::objects[i]->model.facenormals[whichhit], 0, Object::objects[i]->yaw, 0);
                                         Person::players[k]->yaw = -asin(0 - lowpointtarget.x) * 180 / M_PI;
                                         if (lowpointtarget.z < 0)
                                             Person::players[k]->yaw = 180 - Person::players[k]->yaw;
@@ -2527,14 +2501,14 @@ void doAerialAcrobatics()
                                     } else {
                                         lowpoint = tempcoords1;
                                         lowpointtarget = lowpoint - Person::players[k]->facing * 2;
-                                        whichhit = objects.model[i].LineCheck(&lowpoint, &lowpointtarget, &colpoint, &objects.position[i], &objects.yaw[i]);
-                                        if (whichhit != -1 && fabs(objects.model[i].facenormals[whichhit].y) < .3) {
+                                        whichhit = Object::objects[i]->model.LineCheck(&lowpoint, &lowpointtarget, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw);
+                                        if (whichhit != -1 && fabs(Object::objects[i]->model.facenormals[whichhit].y) < .3) {
                                             Person::players[k]->setAnimation(walljumpfrontanim);
                                             emit_sound_at(movewhooshsound, Person::players[k]->coords);
                                             if (k == 0)
                                                 pause_sound(whooshsound);
 
-                                            lowpointtarget = DoRotation(objects.model[i].facenormals[whichhit], 0, objects.yaw[i], 0);
+                                            lowpointtarget = DoRotation(Object::objects[i]->model.facenormals[whichhit], 0, Object::objects[i]->yaw, 0);
                                             Person::players[k]->yaw = -asin(0 - lowpointtarget.x) * 180 / M_PI;
                                             if (lowpointtarget.z < 0)
                                                 Person::players[k]->yaw = 180 - Person::players[k]->yaw;
@@ -2549,11 +2523,11 @@ void doAerialAcrobatics()
                             }
                         }
                     }
-                } else if (objects.type[i] == rocktype) {
+                } else if (Object::objects[i]->type == rocktype) {
                     lowpoint2 = Person::players[k]->coords;
                     lowpoint = Person::players[k]->coords;
                     lowpoint.y += 2;
-                    if (objects.model[i].LineCheck(&lowpoint, &lowpoint2, &colpoint, &objects.position[i], &objects.yaw[i]) != -1) {
+                    if (Object::objects[i]->model.LineCheck(&lowpoint, &lowpoint2, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw) != -1) {
                         Person::players[k]->coords = colpoint;
                         Person::players[k]->collide = 1;
                         tempcollide = 1;
@@ -2596,8 +2570,8 @@ void doAerialAcrobatics()
                     int i = terrain.patchobjects[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz][l];
                     lowpoint = Person::players[k]->coords;
                     lowpoint.y += 1.35;
-                    if (objects.type[i] != rocktype)
-                        if (Person::players[k]->SphereCheck(&lowpoint, 1.33, &colpoint, &objects.position[i], &objects.yaw[i], &objects.model[i]) != -1) {
+                    if (Object::objects[i]->type != rocktype)
+                        if (Person::players[k]->SphereCheck(&lowpoint, 1.33, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw, &Object::objects[i]->model) != -1) {
                             if (Person::players[k]->animTarget != jumpupanim &&
                                     Person::players[k]->animTarget != jumpdownanim &&
                                     Person::players[k]->onterrain)
@@ -2613,14 +2587,14 @@ void doAerialAcrobatics()
                                      Person::players[k]->animTarget == jumpupanim ||
                                      Person::players[k]->animTarget == jumpdownanim)) {
                                 lowpoint = Person::players[k]->coords;
-                                objects.model[i].SphereCheckPossible(&lowpoint, 1.5, &objects.position[i], &objects.yaw[i]);
+                                Object::objects[i]->model.SphereCheckPossible(&lowpoint, 1.5, &Object::objects[i]->position, &Object::objects[i]->yaw);
                                 lowpoint = Person::players[k]->coords;
                                 lowpoint.y += .05;
                                 facing = 0;
                                 facing.z = -1;
                                 facing = DoRotation(facing, 0, Person::players[k]->targetyaw + 180, 0);
                                 lowpointtarget = lowpoint + facing * 1.4;
-                                whichhit = objects.model[i].LineCheckPossible(&lowpoint, &lowpointtarget, &colpoint, &objects.position[i], &objects.yaw[i]);
+                                whichhit = Object::objects[i]->model.LineCheckPossible(&lowpoint, &lowpointtarget, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw);
                                 if (whichhit != -1) {
                                     lowpoint = Person::players[k]->coords;
                                     lowpoint.y += .1;
@@ -2649,27 +2623,27 @@ void doAerialAcrobatics()
                                     lowpointtarget6.y += 45 / 13;
                                     lowpointtarget6 += facing * .6;
                                     lowpointtarget7.y += 90 / 13;
-                                    whichhit = objects.model[i].LineCheckPossible(&lowpoint, &lowpointtarget, &colpoint, &objects.position[i], &objects.yaw[i]);
-                                    if (objects.friction[i] > .5)
+                                    whichhit = Object::objects[i]->model.LineCheckPossible(&lowpoint, &lowpointtarget, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw);
+                                    if (Object::objects[i]->friction > .5)
                                         if (whichhit != -1) {
                                             if (whichhit != -1 && Person::players[k]->animTarget != jumpupanim && Person::players[k]->animTarget != jumpdownanim)
                                                 Person::players[k]->collided = 1;
                                             if (checkcollide(lowpoint7, lowpointtarget7) == -1)
                                                 if (checkcollide(lowpoint6, lowpointtarget6) == -1)
-                                                    if (     objects.model[i].LineCheckPossible(&lowpoint2, &lowpointtarget2,
-                                                             &colpoint, &objects.position[i], &objects.yaw[i]) != -1 &&
-                                                             objects.model[i].LineCheckPossible(&lowpoint3, &lowpointtarget3,
-                                                                     &colpoint, &objects.position[i], &objects.yaw[i]) != -1 &&
-                                                             objects.model[i].LineCheckPossible(&lowpoint4, &lowpointtarget4,
-                                                                     &colpoint, &objects.position[i], &objects.yaw[i]) != -1 &&
-                                                             objects.model[i].LineCheckPossible(&lowpoint5, &lowpointtarget5,
-                                                                     &colpoint, &objects.position[i], &objects.yaw[i]) != -1)
+                                                    if (     Object::objects[i]->model.LineCheckPossible(&lowpoint2, &lowpointtarget2,
+                                                             &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw) != -1 &&
+                                                             Object::objects[i]->model.LineCheckPossible(&lowpoint3, &lowpointtarget3,
+                                                                     &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw) != -1 &&
+                                                             Object::objects[i]->model.LineCheckPossible(&lowpoint4, &lowpointtarget4,
+                                                                     &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw) != -1 &&
+                                                             Object::objects[i]->model.LineCheckPossible(&lowpoint5, &lowpointtarget5,
+                                                                     &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw) != -1)
                                                         for (int j = 0; j < 45; j++) {
                                                             lowpoint = Person::players[k]->coords;
                                                             lowpoint.y += (float)j / 13;
                                                             lowpointtarget = lowpoint + facing * 1.4;
-                                                            if (objects.model[i].LineCheckPossible(&lowpoint, &lowpointtarget,
-                                                                                                   &colpoint2, &objects.position[i], &objects.yaw[i]) == -1) {
+                                                            if (Object::objects[i]->model.LineCheckPossible(&lowpoint, &lowpointtarget,
+                                                                                                   &colpoint2, &Object::objects[i]->position, &Object::objects[i]->yaw) == -1) {
                                                                 if (j <= 6 || j <= 25 && Person::players[k]->animTarget == jumpdownanim)
                                                                     break;
                                                                 if (Person::players[k]->animTarget == jumpupanim || Person::players[k]->animTarget == jumpdownanim) {
@@ -2677,7 +2651,7 @@ void doAerialAcrobatics()
                                                                     lowpoint.y += (float)j / 13;
                                                                     lowpointtarget = lowpoint + facing * 1.3;
                                                                     flatfacing = Person::players[k]->coords;
-                                                                    Person::players[k]->coords = colpoint - DoRotation(objects.model[i].facenormals[whichhit], 0, objects.yaw[k], 0) * .01;
+                                                                    Person::players[k]->coords = colpoint - DoRotation(Object::objects[i]->model.facenormals[whichhit], 0, Object::objects[k]->yaw, 0) * .01;
                                                                     Person::players[k]->coords.y = lowpointtarget.y - .07;
                                                                     Person::players[k]->currentoffset = (flatfacing - Person::players[k]->coords) / Person::players[k]->scale;
 
@@ -2688,7 +2662,7 @@ void doAerialAcrobatics()
                                                                         }
                                                                         emit_sound_at(jumpsound, Person::players[k]->coords, 128.);
 
-                                                                        lowpointtarget = DoRotation(objects.model[i].facenormals[whichhit], 0, objects.yaw[i], 0);
+                                                                        lowpointtarget = DoRotation(Object::objects[i]->model.facenormals[whichhit], 0, Object::objects[i]->yaw, 0);
                                                                         Person::players[k]->yaw = -asin(0 - lowpointtarget.x) * 180 / M_PI;
                                                                         if (lowpointtarget.z < 0)
                                                                             Person::players[k]->yaw = 180 - Person::players[k]->yaw;
@@ -3163,13 +3137,13 @@ void doAttacks()
                                                             terrain.decalalivetime[j] < 2)
                                                         terrain.DeleteDecal(j);
                                                 }
-                                                for (int l = 0; l < objects.numobjects; l++) {
-                                                    if (objects.model[l].type == decalstype)
-                                                        for (int j = 0; j < objects.model[l].numdecals; j++) {
-                                                            if ((objects.model[l].decaltype[j] == blooddecal ||
-                                                                    objects.model[l].decaltype[j] == blooddecalslow) &&
-                                                                    objects.model[l].decalalivetime[j] < 2)
-                                                                objects.model[l].DeleteDecal(j);
+                                                for (int l = 0; l < Object::objects.size(); l++) {
+                                                    if (Object::objects[l]->model.type == decalstype)
+                                                        for (int j = 0; j < Object::objects[l]->model.numdecals; j++) {
+                                                            if ((Object::objects[l]->model.decaltype[j] == blooddecal ||
+                                                                    Object::objects[l]->model.decaltype[j] == blooddecalslow) &&
+                                                                    Object::objects[l]->model.decalalivetime[j] < 2)
+                                                                Object::objects[l]->model.DeleteDecal(j);
                                                         }
                                                 }
                                             }
@@ -3189,13 +3163,13 @@ void doAttacks()
                                                             terrain.DeleteDecal(j);
                                                         }
                                                     }
-                                                    for (int l = 0; l < objects.numobjects; l++) {
-                                                        if (objects.model[l].type == decalstype)
-                                                            for (int j = 0; j < objects.model[l].numdecals; j++) {
-                                                                if ((objects.model[l].decaltype[j] == blooddecal ||
-                                                                        objects.model[l].decaltype[j] == blooddecalslow) &&
-                                                                        objects.model[l].decalalivetime[j] < 2) {
-                                                                    objects.model[l].DeleteDecal(j);
+                                                    for (int l = 0; l < Object::objects.size(); l++) {
+                                                        if (Object::objects[l]->model.type == decalstype)
+                                                            for (int j = 0; j < Object::objects[l]->model.numdecals; j++) {
+                                                                if ((Object::objects[l]->model.decaltype[j] == blooddecal ||
+                                                                        Object::objects[l]->model.decaltype[j] == blooddecalslow) &&
+                                                                        Object::objects[l]->model.decalalivetime[j] < 2) {
+                                                                    Object::objects[l]->model.DeleteDecal(j);
                                                                 }
                                                             }
                                                     }
@@ -5083,17 +5057,17 @@ void Game::Tick()
                     Person::players[i]->avoidsomething = 0;
 
                     //avoid flaming things
-                    for (int j = 0; j < objects.numobjects; j++)
-                        if (objects.onfire[j])
-                            if (distsq(&Person::players[i]->coords, &objects.position[j]) < sq(objects.scale[j]) * 200)
-                                if (     distsq(&Person::players[i]->coords, &objects.position[j]) <
+                    for (int j = 0; j < Object::objects.size(); j++)
+                        if (Object::objects[j]->onfire)
+                            if (distsq(&Person::players[i]->coords, &Object::objects[j]->position) < sq(Object::objects[j]->scale) * 200)
+                                if (     distsq(&Person::players[i]->coords, &Object::objects[j]->position) <
                                          distsq(&Person::players[i]->coords, &Person::players[0]->coords)) {
                                     Person::players[i]->collided = 0;
                                     Person::players[i]->avoidcollided = 1;
                                     if (Person::players[i]->avoidsomething == 0 ||
-                                            distsq(&Person::players[i]->coords, &objects.position[j]) <
+                                            distsq(&Person::players[i]->coords, &Object::objects[j]->position) <
                                             distsq(&Person::players[i]->coords, &Person::players[i]->avoidwhere)) {
-                                        Person::players[i]->avoidwhere = objects.position[j];
+                                        Person::players[i]->avoidwhere = Object::objects[j]->position;
                                         Person::players[i]->avoidsomething = 1;
                                     }
                                 }
@@ -5875,7 +5849,7 @@ void Game::Tick()
             }
 
             //do stuff
-            objects.DoStuff();
+            Object::DoStuff();
 
             for (int j = numenvsounds - 1; j >= 0; j--) {
                 envsoundlife[j] -= multiplier;
@@ -6387,20 +6361,20 @@ void Game::TickOnceAfter()
             viewer = cameraloc - facing * cameradist;
             colviewer = viewer;
             coltarget = cameraloc;
-            objects.SphereCheckPossible(&colviewer, findDistance(&colviewer, &coltarget));
+            Object::SphereCheckPossible(&colviewer, findDistance(&colviewer, &coltarget));
             if (terrain.patchobjectnum[Person::players[0]->whichpatchx][Person::players[0]->whichpatchz])
                 for (int j = 0; j < terrain.patchobjectnum[Person::players[0]->whichpatchx][Person::players[0]->whichpatchz]; j++) {
                     int i = terrain.patchobjects[Person::players[0]->whichpatchx][Person::players[0]->whichpatchz][j];
                     colviewer = viewer;
                     coltarget = cameraloc;
-                    if (objects.model[i].LineCheckPossible(&colviewer, &coltarget, &col, &objects.position[i], &objects.yaw[i]) != -1)
+                    if (Object::objects[i]->model.LineCheckPossible(&colviewer, &coltarget, &col, &Object::objects[i]->position, &Object::objects[i]->yaw) != -1)
                         viewer = col;
                 }
             if (terrain.patchobjectnum[Person::players[0]->whichpatchx][Person::players[0]->whichpatchz])
                 for (int j = 0; j < terrain.patchobjectnum[Person::players[0]->whichpatchx][Person::players[0]->whichpatchz]; j++) {
                     int i = terrain.patchobjects[Person::players[0]->whichpatchx][Person::players[0]->whichpatchz][j];
                     colviewer = viewer;
-                    if (objects.model[i].SphereCheck(&colviewer, .15, &col, &objects.position[i], &objects.yaw[i]) != -1) {
+                    if (Object::objects[i]->model.SphereCheck(&colviewer, .15, &col, &Object::objects[i]->position, &Object::objects[i]->yaw) != -1) {
                         viewer = colviewer;
                     }
                 }
index 485b60768276156927ceb2da53ed5d804a1f2d8d..074a78faf647a340c1eb825d4d61e8b5a38e2036 100644 (file)
@@ -65,7 +65,6 @@ FRUSTUM frustum;
 float texdetail = 0;
 float realtexdetail = 0;
 float playerdist = 0;
-Objects objects;
 int slomo = 0;
 float slomodelay = 0;
 GLubyte bloodText[512 * 512 * 3] = {0};
index 8cd5c7fdead2763feaf923fced6a5ab11c2df507..3f582f95f9b2e724b72a96b8d5eeea75293c7d62 100644 (file)
@@ -32,7 +32,6 @@ extern Light light;
 extern float multiplier;
 extern float gravity;
 extern Terrain terrain;
-extern Objects objects;
 extern int detail;
 extern XYZ viewerfacing;
 extern int bloodtoggle;
@@ -358,9 +357,9 @@ void Sprite::Draw()
                                 start = sprites[i]->oldposition;
                                 end = sprites[i]->position;
                                 if (!spritehit)
-                                    if (objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]) != -1) {
+                                    if (Object::objects[k]->model.LineCheck(&start, &end, &colpoint, &Object::objects[k]->position, &Object::objects[k]->yaw) != -1) {
                                         if (detail == 2 || (detail == 1 && abs(Random() % 4) == 0) || (detail == 0 && abs(Random() % 8) == 0))
-                                            objects.model[k].MakeDecal(blooddecalfast, DoRotation(colpoint - objects.position[k], 0, -objects.yaw[k], 0), sprites[i]->size * 1.6, .5, Random() % 360);
+                                            Object::objects[k]->model.MakeDecal(blooddecalfast, DoRotation(colpoint - Object::objects[k]->position, 0, -Object::objects[k]->yaw, 0), sprites[i]->size * 1.6, .5, Random() % 360);
                                         DeleteSprite(i);
                                         spritehit = 1;
                                     }
index 01e68a3fd4f76df86f6c72adc554bad484d9a274..66debe7dfbfc0a9f3c44aebf10b644390aa135db 100644 (file)
@@ -27,7 +27,7 @@ along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
 #include "Graphic/Texture.hpp"
 #include "Math/Frustum.hpp"
 #include "Math/Quaternions.hpp"
-#include "Objects/Objects.hpp"
+#include "Objects/Object.hpp"
 #include "Utils/ImageIO.hpp"
 
 #include <vector>
diff --git a/Source/Objects/Object.cpp b/Source/Objects/Object.cpp
new file mode 100644 (file)
index 0000000..12c96e5
--- /dev/null
@@ -0,0 +1,846 @@
+/*
+Copyright (C) 2003, 2010 - Wolfire Games
+Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file)
+
+This file is part of Lugaru.
+
+Lugaru is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+Lugaru is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "Objects/Object.hpp"
+
+extern XYZ viewer;
+extern float viewdistance;
+extern float fadestart;
+extern int environment;
+extern float texscale;
+extern Light light;
+extern float multiplier;
+extern float gravity;
+extern FRUSTUM frustum;
+extern Terrain terrain;
+extern bool foliage;
+extern int detail;
+extern float blurness;
+extern float windvar;
+extern float playerdist;
+extern bool skyboxtexture;
+
+std::vector<std::unique_ptr<Object>> Object::objects;
+XYZ Object::center;
+float Object::radius = 0;
+Texture Object::boxtextureptr;
+Texture Object::treetextureptr;
+Texture Object::bushtextureptr;
+Texture Object::rocktextureptr;
+
+//Functions
+
+Object::Object() :
+    position(),
+    type(0),
+    yaw(0),
+    pitch(0),
+    rotx(0),
+    rotxvel(0),
+    roty(0),
+    rotyvel(0),
+    possible(false),
+    model(),
+    displaymodel(),
+    friction(0),
+    scale(0),
+    messedwith(0),
+    checked(0),
+    shadowed(0),
+    occluded(0),
+    onfire(false),
+    flamedelay(0)
+{
+}
+
+Object::Object(int _type, XYZ _position, float _yaw, float _pitch, float _scale) : Object()
+{
+    scale = _scale;
+    type = _type;
+    position = _position;
+    yaw = _yaw;
+    pitch = _pitch;
+
+    switch(type) {
+        case boxtype:
+            model.loaddecal("Models/Box.solid", 0);
+            friction = 1.5;
+            break;
+        case cooltype:
+            model.loaddecal("Models/Cool.solid", 0);
+            friction = 1.5;
+            break;
+        case walltype:
+            model.loaddecal("Models/Wall.solid", 0);
+            friction = 1.5;
+            break;
+        case tunneltype:
+            model.loaddecal("Models/Tunnel.solid", 0);
+            friction = 1.5;
+            break;
+        case chimneytype:
+            model.loaddecal("Models/Chimney.solid", 0);
+            friction = 1.5;
+            break;
+        case spiketype:
+            model.load("Models/Spike.solid", 0);
+            friction = .4;
+            break;
+        case weirdtype:
+            model.loaddecal("Models/Weird.solid", 0);
+            friction = 1.5;
+            break;
+        case rocktype:
+            model.loaddecal("Models/Rock.solid", 0);
+            if (scale > .5) {
+                friction = 1.5;
+            } else {
+                friction = .5;
+            }
+            break;
+        case treetrunktype:
+            model.load("Models/TreeTrunk.solid", 0);
+            friction = .4;
+            break;
+        case treeleavestype:
+            scale += fabs((float)(Random() % 100) / 900) * scale;
+            model.load("Models/Leaves.solid", 0);
+            friction = 0;
+            break;
+        case bushtype:
+            position.y = terrain.getHeight(position.x, position.z) - .3;
+            model.load("Models/Bush.solid", 0);
+            break;
+        case platformtype:
+            model.loaddecal("Models/Platform.solid", 0);
+            model.Rotate(90, 0, 0);
+            friction = 1.5;
+            break;
+        case firetype:
+            onfire = true;
+            break;
+    }
+
+    if (friction == 1.5 && fabs(pitch) > 5) {
+        friction = .5;
+    }
+
+    if (type == boxtype || type == cooltype || type == spiketype || type == weirdtype || type == walltype || type == chimneytype || type == tunneltype || type == platformtype) {
+        model.ScaleTexCoords(scale * 1.5);
+    }
+    if (type == rocktype) {
+        model.ScaleTexCoords(scale * 3);
+    }
+    model.flat = 1;
+    if (type == treetrunktype || type == treeleavestype || type == rocktype) {
+        model.flat = 0;
+    }
+    model.Scale(.3 * scale, .3 * scale, .3 * scale);
+    model.Rotate(90, 1, 1);
+    model.Rotate(pitch, 0, 0);
+    if (type == rocktype) {
+        model.Rotate(yaw * 5, 0, 0);
+    }
+    model.CalculateNormals(1);
+    model.ScaleNormals(-1, -1, -1);
+}
+
+void Object::handleFire()
+{
+    if (type == firetype) {
+        onfire = 1;
+    }
+    if (onfire) {
+        XYZ spawnpoint;
+        if ((type == bushtype) || (type == firetype)) {
+            flamedelay -= multiplier * 3;
+        } else if (type == treeleavestype) {
+            flamedelay -= multiplier * 4;
+        }
+        while ((flamedelay < 0) && onfire) {
+            flamedelay += .006;
+            if ((type == bushtype) || (type == firetype)) {
+                spawnpoint.x = ((float)(Random() % 100)) / 30 * scale;
+                spawnpoint.y = ((float)(Random() % 100) + 60) / 30 * scale;
+                spawnpoint.z = 0;
+                spawnpoint = DoRotation(spawnpoint, 0, Random() % 360, 0);
+                spawnpoint += position;
+                Sprite::MakeSprite(flamesprite, spawnpoint, spawnpoint * 0, 1, 1, 1, (.6 + (float)abs(Random() % 100) / 200 - .25) * 5 * scale, 1);
+            } else if (type == treeleavestype) {
+                spawnpoint.x = ((float)(Random() % 100)) / 80 * scale;
+                spawnpoint.y = ((float)(Random() % 100) + 80) / 12 * scale;
+                spawnpoint.z = 0;
+                spawnpoint = DoRotation(spawnpoint, 0, Random() % 360, 0);
+                spawnpoint += position;
+                Sprite::MakeSprite(flamesprite, spawnpoint, spawnpoint * 0, 1, 1, 1, (.6 + (float)abs(Random() % 100) / 200 - .25) * 6, 1);
+            }
+        }
+    }
+}
+
+void Object::doShadows(XYZ lightloc)
+{
+    XYZ testpoint, testpoint2, terrainpoint, col;
+    int patchx, patchz;
+    if (type != treeleavestype && type != treetrunktype && type != bushtype && type != firetype) {
+        for (int j = 0; j < model.vertexNum; j++) {
+            terrainpoint = position + DoRotation(model.vertex[j] + model.normals[j] * .1, 0, yaw, 0);
+            shadowed = 0;
+            patchx = terrainpoint.x / (terrain.size / subdivision * terrain.scale);
+            patchz = terrainpoint.z / (terrain.size / subdivision * terrain.scale);
+            if (patchx >= 0 && patchz >= 0 && patchx < subdivision && patchz < subdivision) {
+                if (terrain.patchobjectnum[patchx][patchz]) {
+                    for (int k = 0; k < terrain.patchobjectnum[patchx][patchz]; k++) {
+                        int l = terrain.patchobjects[patchx][patchz][k];
+                        if (objects[l]->type != treetrunktype) {
+                            testpoint = terrainpoint;
+                            testpoint2 = terrainpoint + lightloc * 50 * (1 - shadowed);
+                            if (objects[l]->model.LineCheck(&testpoint, &testpoint2, &col, &objects[l]->position, &objects[l]->yaw) != -1) {
+                                shadowed = 1 - (findDistance(&terrainpoint, &col) / 50);
+                            }
+                        }
+                    }
+                }
+            }
+            if (shadowed > 0) {
+                col = model.normals[j] - DoRotation(lightloc * shadowed, 0, -yaw, 0);
+                Normalise(&col);
+                for (int k = 0; k < model.TriangleNum; k++) {
+                    if (model.Triangles[k].vertex[0] == j) {
+                        int l = k * 24;
+                        model.vArray[l + 2] = col.x;
+                        model.vArray[l + 3] = col.y;
+                        model.vArray[l + 4] = col.z;
+                    }
+                    if (model.Triangles[k].vertex[1] == j) {
+                        int l = k * 24;
+                        model.vArray[l + 10] = col.x;
+                        model.vArray[l + 11] = col.y;
+                        model.vArray[l + 12] = col.z;
+                    }
+                    if (model.Triangles[k].vertex[2] == j) {
+                        int l = k * 24;
+                        model.vArray[l + 18] = col.x;
+                        model.vArray[l + 19] = col.y;
+                        model.vArray[l + 20] = col.z;
+                    }
+                }
+            }
+        }
+    }
+    shadowed = 0;
+}
+
+void Object::draw()
+{
+    static float distance;
+    static XYZ moved, terrainlight;
+    bool hidden;
+    if (type == firetype) {
+        return;
+    }
+    moved = DoRotation(model.boundingspherecenter, 0, yaw, 0);
+    if (type == tunneltype || frustum.SphereInFrustum(position.x + moved.x, position.y + moved.y, position.z + moved.z, model.boundingsphereradius)) {
+        distance = distsq(&viewer, &position);
+        distance *= 1.2;
+        hidden = !(distsqflat(&viewer, &position) > playerdist + 3 || (type != bushtype && type != treeleavestype));
+        if (!hidden) {
+
+            if (detail == 2 && distance > viewdistance * viewdistance / 4 && environment == desertenvironment)
+                glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, blurness );
+            else
+                glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
+            distance = (viewdistance * viewdistance - (distance - (viewdistance * viewdistance * fadestart)) * (1 / (1 - fadestart))) / viewdistance / viewdistance;
+            if (distance > 1)
+                distance = 1;
+            if (distance > 0) {
+
+                if (occluded < 6) {
+                    glMatrixMode(GL_MODELVIEW);
+                    glPushMatrix();
+                    if (!model.color)
+                        glEnable(GL_LIGHTING);
+                    else
+                        glDisable(GL_LIGHTING);
+                    glDepthMask(1);
+                    glTranslatef(position.x, position.y, position.z);
+                    if (type == bushtype) {
+                        messedwith -= multiplier;
+                        if (rotxvel || rotx) {
+                            if (rotx > 0) rotxvel -= multiplier * 8 * fabs(rotx);
+                            if (rotx < 0) rotxvel += multiplier * 8 * fabs(rotx);
+                            if (rotx > 0) rotxvel -= multiplier * 4;
+                            if (rotx < 0) rotxvel += multiplier * 4;
+                            if (rotxvel > 0) rotxvel -= multiplier * 4;
+                            if (rotxvel < 0) rotxvel += multiplier * 4;
+                            if (fabs(rotx) < multiplier * 4)
+                                rotx = 0;
+                            if (fabs(rotxvel) < multiplier * 4)
+                                rotxvel = 0;
+
+                            rotx += rotxvel * multiplier * 4;
+                        }
+                        if (rotyvel || roty) {
+                            if (roty > 0) rotyvel -= multiplier * 8 * fabs(roty);
+                            if (roty < 0) rotyvel += multiplier * 8 * fabs(roty);
+                            if (roty > 0) rotyvel -= multiplier * 4;
+                            if (roty < 0) rotyvel += multiplier * 4;
+                            if (rotyvel > 0) rotyvel -= multiplier * 4;
+                            if (rotyvel < 0) rotyvel += multiplier * 4;
+                            if (fabs(roty) < multiplier * 4)
+                                roty = 0;
+                            if (fabs(rotyvel) < multiplier * 4)
+                                rotyvel = 0;
+
+                            roty += rotyvel * multiplier * 4;
+                        }
+                        if (roty) {
+                            glRotatef(roty, 1, 0, 0);
+                        }
+                        if (rotx) {
+                            glRotatef(-rotx, 0, 0, 1);
+                        }
+                        if (rotx > 10)
+                            rotx = 10;
+                        if (rotx < -10)
+                            rotx = -10;
+                        if (roty > 10)
+                            roty = 10;
+                        if (roty < -10)
+                            roty = -10;
+                    }
+                    if (type == treetrunktype || type == treeleavestype) {
+                        if (type == treetrunktype || environment == desertenvironment) {
+                            messedwith -= multiplier;
+                            if (rotxvel || rotx) {
+                                if (rotx > 0) rotxvel -= multiplier * 8 * fabs(rotx);
+                                if (rotx < 0) rotxvel += multiplier * 8 * fabs(rotx);
+                                if (rotx > 0) rotxvel -= multiplier * 4;
+                                if (rotx < 0) rotxvel += multiplier * 4;
+                                if (rotxvel > 0) rotxvel -= multiplier * 4;
+                                if (rotxvel < 0) rotxvel += multiplier * 4;
+                                if (fabs(rotx) < multiplier * 4)
+                                    rotx = 0;
+                                if (fabs(rotxvel) < multiplier * 4)
+                                    rotxvel = 0;
+
+                                rotx += rotxvel * multiplier * 4;
+                            }
+                            if (rotyvel || roty) {
+                                if (roty > 0) rotyvel -= multiplier * 8 * fabs(roty);
+                                if (roty < 0) rotyvel += multiplier * 8 * fabs(roty);
+                                if (roty > 0) rotyvel -= multiplier * 4;
+                                if (roty < 0) rotyvel += multiplier * 4;
+                                if (rotyvel > 0) rotyvel -= multiplier * 4;
+                                if (rotyvel < 0) rotyvel += multiplier * 4;
+                                if (fabs(roty) < multiplier * 4)
+                                    roty = 0;
+                                if (fabs(rotyvel) < multiplier * 4)
+                                    rotyvel = 0;
+
+                                roty += rotyvel * multiplier * 4;
+                            }
+                            if (roty) {
+                                glRotatef(roty / 6, 1, 0, 0);
+                            }
+                            if (rotx) {
+                                glRotatef(-rotx / 6, 0, 0, 1);
+                            }
+                            if (rotx > 10)
+                                rotx = 10;
+                            if (rotx < -10)
+                                rotx = -10;
+                            if (roty > 10)
+                                roty = 10;
+                            if (roty < -10)
+                                roty = -10;
+                        } else {
+                            messedwith -= multiplier;
+                            if (rotxvel || rotx) {
+                                if (rotx > 0) rotxvel -= multiplier * 8 * fabs(rotx);
+                                if (rotx < 0) rotxvel += multiplier * 8 * fabs(rotx);
+                                if (rotx > 0) rotxvel -= multiplier * 4;
+                                if (rotx < 0) rotxvel += multiplier * 4;
+                                if (rotxvel > 0) rotxvel -= multiplier * 4;
+                                if (rotxvel < 0) rotxvel += multiplier * 4;
+                                if (fabs(rotx) < multiplier * 4)
+                                    rotx = 0;
+                                if (fabs(rotxvel) < multiplier * 4)
+                                    rotxvel = 0;
+
+                                rotx += rotxvel * multiplier * 4;
+                            }
+                            if (rotyvel || roty) {
+                                if (roty > 0) rotyvel -= multiplier * 8 * fabs(roty);
+                                if (roty < 0) rotyvel += multiplier * 8 * fabs(roty);
+                                if (roty > 0) rotyvel -= multiplier * 4;
+                                if (roty < 0) rotyvel += multiplier * 4;
+                                if (rotyvel > 0) rotyvel -= multiplier * 4;
+                                if (rotyvel < 0) rotyvel += multiplier * 4;
+                                if (fabs(roty) < multiplier * 4)
+                                    roty = 0;
+                                if (fabs(rotyvel) < multiplier * 4)
+                                    rotyvel = 0;
+
+                                roty += rotyvel * multiplier * 4;
+                            }
+                            if (roty) {
+                                glRotatef(roty / 4, 1, 0, 0);
+                            }
+                            if (rotx) {
+                                glRotatef(-rotx / 4, 0, 0, 1);
+                            }
+                            if (rotx > 10)
+                                rotx = 10;
+                            if (rotx < -10)
+                                rotx = -10;
+                            if (roty > 10)
+                                roty = 10;
+                            if (roty < -10)
+                                roty = -10;
+                        }
+
+                    }
+                    if (/*detail==2&&*/environment == snowyenvironment) {
+                        if (type == treeleavestype) {
+                            glRotatef((sin(windvar + position.x * .3) + .5) * 1.5 * (sin(windvar * 2 + position.x * .3) + 1) / 2, 1, 0, 0);
+                        }
+                        if (type == treetrunktype) {
+                            glRotatef((sin(windvar + position.x * .3) + .5)*.5 * (sin(windvar * 2 + position.x * .3) + 1) / 2, 1, 0, 0);
+                        }
+                        if (type == bushtype) {
+                            glRotatef((sin(windvar + position.x * .3) + .5) * 4 * (sin(windvar * 2 + position.x * .3) + 1) / 2, 1, 0, 0);
+                        }
+                    }
+                    if (/*detail==2&&*/environment == grassyenvironment) {
+                        if (type == treeleavestype) {
+                            glRotatef((sin(windvar + position.x * .3) + .5) * 1.5 * .5 * (sin(windvar * 2 + position.x * .3) + 1) / 2, 1, 0, 0);
+                        }
+                        if (type == treetrunktype) {
+                            glRotatef((sin(windvar + position.x * .3) + .5)*.5 * .5 * (sin(windvar * 2 + position.x * .3) + 1) / 2, 1, 0, 0);
+                        }
+                        if (type == bushtype) {
+                            glRotatef((sin(windvar + position.x * .3) + .5) * 4 * .5 * (sin(windvar * 2 + position.x * .3) + 1) / 2, 1, 0, 0);
+                        }
+                    }
+                    if (/*detail==2&&*/environment == desertenvironment) {
+                        if (type == bushtype) {
+                            glRotatef((sin(windvar + position.x * .3) + .5) * 4 * .5 * (sin(windvar * 2 + position.x * .3) + 1) / 2, 1, 0, 0);
+                        }
+                    }
+                    glRotatef(yaw, 0, 1, 0);
+                    if (distance > 1)
+                        distance = 1;
+                    glColor4f((1 - shadowed) / 2 + .5, (1 - shadowed) / 2 + .5, (1 - shadowed) / 2 + .5, distance);
+                    if (distance >= 1) {
+                        glDisable(GL_BLEND);
+                        glAlphaFunc(GL_GREATER, 0.5);
+                    }
+                    if (distance < 1) {
+                        glEnable(GL_BLEND);
+                        glAlphaFunc(GL_GREATER, 0.1);
+                    }
+                    if (type != treetrunktype && type != treeleavestype && type != bushtype && type != rocktype) {
+                        glEnable(GL_CULL_FACE);
+                        glAlphaFunc(GL_GREATER, 0.0001);
+                        model.drawdifftex(boxtextureptr);
+                        model.drawdecals(terrain.shadowtexture, terrain.bloodtexture, terrain.bloodtexture2, terrain.breaktexture);
+                    }
+                    if (type == rocktype) {
+                        glEnable(GL_CULL_FACE);
+                        glAlphaFunc(GL_GREATER, 0.0001);
+                        glColor4f((1 - shadowed) / 2 + light.ambient[0], (1 - shadowed) / 2 + light.ambient[1], (1 - shadowed) / 2 + light.ambient[2], distance);
+                        model.drawdifftex(rocktextureptr);
+                        model.drawdecals(terrain.shadowtexture, terrain.bloodtexture, terrain.bloodtexture2, terrain.breaktexture);
+                    }
+                    if (type == treeleavestype) {
+                        glDisable(GL_CULL_FACE);
+                        glDisable(GL_LIGHTING);
+                        terrainlight = terrain.getLighting(position.x, position.z);
+                        if (!hidden) {
+                            glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance);
+                            if (distance < 1)
+                                glAlphaFunc(GL_GREATER, 0.2);
+                        }
+                        if (hidden) {
+                            glDepthMask(0);
+                            glEnable(GL_BLEND);
+                            glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance / 3);
+                            glAlphaFunc(GL_GREATER, 0);
+                        }
+                        model.drawdifftex(treetextureptr);
+                    }
+                    if (type == bushtype) {
+                        glDisable(GL_CULL_FACE);
+                        glDisable(GL_LIGHTING);
+                        terrainlight = terrain.getLighting(position.x, position.z);
+                        if (!hidden) {
+                            glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance);
+                            if (distance < 1)
+                                glAlphaFunc(GL_GREATER, 0.2);
+                        }
+                        if (hidden) {
+                            glDepthMask(0);
+                            glEnable(GL_BLEND);
+                            glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance / 3);
+                            glAlphaFunc(GL_GREATER, 0);
+                        }
+                        model.drawdifftex(bushtextureptr);
+                    }
+                    if (type == treetrunktype) {
+                        glEnable(GL_CULL_FACE);
+                        terrainlight = terrain.getLighting(position.x, position.z);
+                        glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance);
+                        model.drawdifftex(treetextureptr);
+                    }
+                    glPopMatrix();
+                }
+            }
+        }
+    }
+}
+
+void Object::drawSecondPass()
+{
+    static float distance;
+    static XYZ moved, terrainlight;
+    bool hidden;
+    if (type != treeleavestype && type != bushtype) {
+        return;
+    }
+    moved = DoRotation(model.boundingspherecenter, 0, yaw, 0);
+    if (frustum.SphereInFrustum(position.x + moved.x, position.y + moved.y, position.z + moved.z, model.boundingsphereradius)) {
+        hidden = distsqflat(&viewer, &position) <= playerdist + 3;
+        if (hidden) {
+            distance = 1;
+            glMatrixMode(GL_MODELVIEW);
+            glPushMatrix();
+            glEnable(GL_LIGHTING);
+            glDepthMask(1);
+            glTranslatef(position.x, position.y, position.z);
+            if (type == bushtype) {
+                messedwith -= multiplier;
+                if (rotxvel || rotx) {
+                    if (rotx > 0) rotxvel -= multiplier * 8 * fabs(rotx);
+                    if (rotx < 0) rotxvel += multiplier * 8 * fabs(rotx);
+                    if (rotx > 0) rotxvel -= multiplier * 4;
+                    if (rotx < 0) rotxvel += multiplier * 4;
+                    if (rotxvel > 0) rotxvel -= multiplier * 4;
+                    if (rotxvel < 0) rotxvel += multiplier * 4;
+                    if (fabs(rotx) < multiplier * 4)
+                        rotx = 0;
+                    if (fabs(rotxvel) < multiplier * 4)
+                        rotxvel = 0;
+
+                    rotx += rotxvel * multiplier * 4;
+                }
+                if (rotyvel || roty) {
+                    if (roty > 0) rotyvel -= multiplier * 8 * fabs(roty);
+                    if (roty < 0) rotyvel += multiplier * 8 * fabs(roty);
+                    if (roty > 0) rotyvel -= multiplier * 4;
+                    if (roty < 0) rotyvel += multiplier * 4;
+                    if (rotyvel > 0) rotyvel -= multiplier * 4;
+                    if (rotyvel < 0) rotyvel += multiplier * 4;
+                    if (fabs(roty) < multiplier * 4)
+                        roty = 0;
+                    if (fabs(rotyvel) < multiplier * 4)
+                        rotyvel = 0;
+
+                    roty += rotyvel * multiplier * 4;
+                }
+                if (roty) {
+                    glRotatef(roty, 1, 0, 0);
+                }
+                if (rotx) {
+                    glRotatef(-rotx, 0, 0, 1);
+                }
+                if (rotx > 10)
+                    rotx = 10;
+                if (rotx < -10)
+                    rotx = -10;
+                if (roty > 10)
+                    roty = 10;
+                if (roty < -10)
+                    roty = -10;
+            }
+            if (type == treetrunktype || type == treeleavestype) {
+                messedwith -= multiplier;
+                if (rotxvel || rotx) {
+                    if (rotx > 0) rotxvel -= multiplier * 8 * fabs(rotx);
+                    if (rotx < 0) rotxvel += multiplier * 8 * fabs(rotx);
+                    if (rotx > 0) rotxvel -= multiplier * 4;
+                    if (rotx < 0) rotxvel += multiplier * 4;
+                    if (rotxvel > 0) rotxvel -= multiplier * 4;
+                    if (rotxvel < 0) rotxvel += multiplier * 4;
+                    if (fabs(rotx) < multiplier * 4)
+                        rotx = 0;
+                    if (fabs(rotxvel) < multiplier * 4)
+                        rotxvel = 0;
+
+                    rotx += rotxvel * multiplier * 4;
+                }
+                if (rotyvel || roty) {
+                    if (roty > 0) rotyvel -= multiplier * 8 * fabs(roty);
+                    if (roty < 0) rotyvel += multiplier * 8 * fabs(roty);
+                    if (roty > 0) rotyvel -= multiplier * 4;
+                    if (roty < 0) rotyvel += multiplier * 4;
+                    if (rotyvel > 0) rotyvel -= multiplier * 4;
+                    if (rotyvel < 0) rotyvel += multiplier * 4;
+                    if (fabs(roty) < multiplier * 4)
+                        roty = 0;
+                    if (fabs(rotyvel) < multiplier * 4)
+                        rotyvel = 0;
+
+                    roty += rotyvel * multiplier * 4;
+                }
+                if (roty) {
+                    glRotatef(roty / 2, 1, 0, 0);
+                }
+                if (rotx) {
+                    glRotatef(-rotx / 2, 0, 0, 1);
+                }
+                if (rotx > 10)
+                    rotx = 10;
+                if (rotx < -10)
+                    rotx = -10;
+                if (roty > 10)
+                    roty = 10;
+                if (roty < -10)
+                    roty = -10;
+            }
+            if (environment == snowyenvironment) {
+                if (type == treeleavestype) {
+                    glRotatef((sin(windvar + position.x * .3) + .5) * 1.5 * (sin(windvar * 2 + position.x * .3) + 1) / 2, 1, 0, 0);
+                }
+                if (type == treetrunktype) {
+                    glRotatef((sin(windvar + position.x * .3) + .5)*.5 * (sin(windvar * 2 + position.x * .3) + 1) / 2, 1, 0, 0);
+                }
+                if (type == bushtype) {
+                    glRotatef((sin(windvar + position.x * .3) + .5) * 4 * (sin(windvar * 2 + position.x * .3) + 1) / 2, 1, 0, 0);
+                }
+            }
+            if (environment == grassyenvironment) {
+                if (type == treeleavestype) {
+                    glRotatef((sin(windvar + position.x * .3) + .5) * 1.5 * .5 * (sin(windvar * 2 + position.x * .3) + 1) / 2, 1, 0, 0);
+                }
+                if (type == treetrunktype) {
+                    glRotatef((sin(windvar + position.x * .3) + .5)*.5 * .5 * (sin(windvar * 2 + position.x * .3) + 1) / 2, 1, 0, 0);
+                }
+                if (type == bushtype) {
+                    glRotatef((sin(windvar + position.x * .3) + .5) * 4 * .5 * (sin(windvar * 2 + position.x * .3) + 1) / 2, 1, 0, 0);
+                }
+            }
+            glRotatef(yaw, 0, 1, 0);
+            glColor4f(1, 1, 1, distance);
+            if (type == treeleavestype) {
+                glDisable(GL_CULL_FACE);
+                glDisable(GL_LIGHTING);
+                terrainlight = terrain.getLighting(position.x, position.z);
+                glDepthMask(0);
+                glEnable(GL_BLEND);
+                glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, .3);
+                glAlphaFunc(GL_GREATER, 0);
+                glDisable(GL_ALPHA_TEST);
+                model.drawdifftex(treetextureptr);
+            }
+            if (type == bushtype) {
+                glDisable(GL_CULL_FACE);
+                glDisable(GL_LIGHTING);
+                terrainlight = terrain.getLighting(position.x, position.z);
+                glDepthMask(0);
+                glEnable(GL_BLEND);
+                glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, .3);
+                glAlphaFunc(GL_GREATER, 0);
+                glDisable(GL_ALPHA_TEST);
+                model.drawdifftex(bushtextureptr);
+            }
+            glPopMatrix();
+        }
+    }
+}
+
+void Object::ComputeCenter()
+{
+    center = 0;
+    for (unsigned i = 0; i < objects.size(); i++) {
+        center += objects[i]->position;
+    }
+    center /= objects.size();
+}
+
+void Object::ComputeRadius()
+{
+    float maxdistance = 0;
+    float tempdist;
+    for (int i = 0; i < objects.size(); i++) {
+        tempdist = distsq(&center, &objects[i]->position);
+        if (tempdist > maxdistance) {
+            maxdistance = tempdist;
+        }
+    }
+    radius = fast_sqrt(maxdistance);
+}
+
+void Object::LoadObjectsFromFile(FILE* tfile, bool skip)
+{
+    int numobjects;
+    int type;
+    XYZ position;
+    float yaw, pitch, scale, lastscale;
+    funpackf(tfile, "Bi", &numobjects);
+    if (!skip) {
+        objects.clear();
+    }
+    for (int i = 0; i < numobjects; i++) {
+        funpackf(tfile, "Bi Bf Bf Bf Bf Bf Bf", &type, &yaw, &pitch, &position.x, &position.y, &position.z, &scale);
+        if (!skip) {
+            if (type == treeleavestype) {
+                scale = lastscale;
+            }
+            objects.emplace_back(new Object(type, position, yaw, pitch, scale));
+            lastscale = scale;
+        }
+    }
+}
+
+void Object::addToTerrain(unsigned id)
+{
+    if ((type != treeleavestype) && (type != bushtype) && (type != firetype)) {
+        terrain.AddObject(position + DoRotation(model.boundingspherecenter, 0, yaw, 0), model.boundingsphereradius, id);
+    }
+
+    if (detail == 2) {
+        if ((type == treetrunktype) && (position.y < (terrain.getHeight(position.x, position.z) + 1))) {
+            terrain.MakeDecal(shadowdecalpermanent, position, 2, .4, 0);
+        }
+
+        if ((type == bushtype) && (position.y < (terrain.getHeight(position.x, position.z) + 1))) {
+            terrain.MakeDecal(shadowdecalpermanent, position, 1, .4, 0);
+        }
+    }
+}
+
+void Object::AddObjectsToTerrain()
+{
+    for (unsigned i = 0; i < objects.size(); i++) {
+        objects[i]->addToTerrain(i);
+    }
+}
+
+bool Object::Checkcollide(XYZ startpoint, XYZ endpoint, int which)
+{
+    static XYZ colpoint, colviewer, coltarget;
+    static int i;
+
+    startpoint.y += .1;
+    endpoint.y += .1;
+    startpoint.y -= .1;
+    endpoint.y -= .1;
+
+    for (i = 0; i < objects.size(); i++) {
+        if (objects[i]->type != treeleavestype && objects[i]->type != treetrunktype && objects[i]->type != bushtype && objects[i]->type != firetype && i != which) {
+            colviewer = startpoint;
+            coltarget = endpoint;
+            if (objects[i]->model.LineCheck(&colviewer, &coltarget, &colpoint, &objects[i]->position, &objects[i]->yaw) != -1)
+                return 1;
+        }
+    }
+
+    return 0;
+}
+
+void Object::SphereCheckPossible(XYZ *p1, float radius)
+{
+    int whichpatchx = p1->x / (terrain.size / subdivision * terrain.scale);
+    int whichpatchz = p1->z / (terrain.size / subdivision * terrain.scale);
+
+    if (whichpatchx >= 0 && whichpatchz >= 0 && whichpatchx < subdivision && whichpatchz < subdivision) {
+        if (terrain.patchobjectnum[whichpatchx][whichpatchz] > 0 && terrain.patchobjectnum[whichpatchx][whichpatchz] < 500) {
+            for (int j = 0; j < terrain.patchobjectnum[whichpatchx][whichpatchz]; j++) {
+                int i = terrain.patchobjects[whichpatchx][whichpatchz][j];
+                objects[i]->possible = false;
+                if (objects[i]->model.SphereCheckPossible(p1, radius, &objects[i]->position, &objects[i]->yaw) != -1) {
+                    objects[i]->possible = true;
+                }
+            }
+        }
+    }
+}
+
+void Object::Draw()
+{
+    for (unsigned i = 0; i < objects.size(); i++) {
+        objects[i]->draw();
+    }
+
+    glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
+    for (unsigned i = 0; i < objects.size(); i++) {
+        objects[i]->drawSecondPass();
+    }
+    if (environment == desertenvironment) {
+        glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
+    }
+    glEnable(GL_ALPHA_TEST);
+    SetUpLight(&light, 0);
+}
+
+void Object::DeleteObject(int which)
+{
+    objects.erase(objects.begin() + which);
+}
+
+void Object::MakeObject(int atype, XYZ where, float ayaw, float apitch, float ascale)
+{
+    if ((atype != treeleavestype && atype != bushtype) || foliage == 1) {
+        unsigned nextid = objects.size();
+        cout << "Adding object " << nextid << endl;
+        objects.emplace_back(new Object(atype, where, ayaw, apitch, ascale));
+        objects.back()->addToTerrain(nextid);
+    }
+}
+
+void Object::DoStuff()
+{
+    for (unsigned i = 0; i < objects.size(); i++) {
+        objects[i]->handleFire();
+    }
+}
+
+void Object::DoShadows()
+{
+    XYZ lightloc;
+    lightloc = light.location;
+    if (!skyboxtexture)
+        lightloc = 0;
+    lightloc.y += 10;
+    Normalise(&lightloc);
+
+    for (unsigned i = 0; i < objects.size(); i++) {
+        objects[i]->doShadows(lightloc);
+    }
+}
+
+//~ Object::~Objects()
+//~ {
+    //~ boxtextureptr.destroy();
+    //~ treetextureptr.destroy();
+    //~ bushtextureptr.destroy();
+    //~ rocktextureptr.destroy();
+//~ }
diff --git a/Source/Objects/Object.hpp b/Source/Objects/Object.hpp
new file mode 100644 (file)
index 0000000..c1e02cc
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+Copyright (C) 2003, 2010 - Wolfire Games
+Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file)
+
+This file is part of Lugaru.
+
+Lugaru is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+Lugaru is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _OBJECTS_HPP_
+#define _OBJECTS_HPP_
+
+#include "Environment/Lights.hpp"
+#include "Environment/Terrain.hpp"
+#include "Graphic/gamegl.hpp"
+#include "Graphic/Models.hpp"
+#include "Graphic/Sprite.hpp"
+#include "Graphic/Texture.hpp"
+#include "Math/Frustum.hpp"
+#include "Math/Quaternions.hpp"
+#include "Utils/ImageIO.hpp"
+
+#include <memory>
+#include <vector>
+//
+// Model Structures
+//
+
+#define max_objects 300
+
+#define boxtype 0
+#define weirdtype 1
+#define spiketype 2
+#define treetrunktype 3
+#define treeleavestype 4
+#define bushtype 5
+#define rocktype 6
+#define walltype 7
+#define chimneytype 8
+#define platformtype 9
+#define tunneltype 11
+#define cooltype 12
+#define firetype 13
+
+
+class Object
+{
+public:
+    static std::vector<std::unique_ptr<Object>> objects;
+    static XYZ center;
+    static float radius;
+    static Texture boxtextureptr;
+    static Texture treetextureptr;
+    static Texture bushtextureptr;
+    static Texture rocktextureptr;
+
+    XYZ position;
+    int type;
+    float yaw;
+    float pitch;
+    float rotx;
+    float rotxvel;
+    float roty;
+    float rotyvel;
+    bool possible;
+    Model model;
+    Model displaymodel;
+    float friction;
+    float scale;
+    float messedwith;
+    float checked;
+    float shadowed;
+    float occluded;
+    bool onfire;
+    float flamedelay;
+
+    Object();
+    Object(int _type, XYZ _position, float _yaw, float _pitch, float _scale);
+
+    static void ComputeCenter();
+    static void ComputeRadius();
+    static bool Checkcollide(XYZ startpoint, XYZ endpoint, int which);
+    static void AddObjectsToTerrain();
+    static void LoadObjectsFromFile(FILE* tfile, bool skip);
+    static void SphereCheckPossible(XYZ *p1, float radius);
+    static void DeleteObject(int which);
+    static void MakeObject(int atype, XYZ where, float ayaw, float apitch, float ascale);
+    static void Draw();
+    static void DoShadows();
+    static void DoStuff();
+
+private:
+    void handleFire();
+    void doShadows(XYZ lightloc);
+    void draw();
+    void drawSecondPass();
+    void addToTerrain(unsigned id);
+};
+
+#endif
+
diff --git a/Source/Objects/Objects.cpp b/Source/Objects/Objects.cpp
deleted file mode 100644 (file)
index c123342..0000000
+++ /dev/null
@@ -1,753 +0,0 @@
-/*
-Copyright (C) 2003, 2010 - Wolfire Games
-Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file)
-
-This file is part of Lugaru.
-
-Lugaru is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-Lugaru is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "Objects/Objects.hpp"
-
-extern XYZ viewer;
-extern float viewdistance;
-extern float fadestart;
-extern int environment;
-extern float texscale;
-extern Light light;
-extern float multiplier;
-extern float gravity;
-extern FRUSTUM frustum;
-extern Terrain terrain;
-extern bool foliage;
-extern int detail;
-extern float blurness;
-extern float windvar;
-extern float playerdist;
-extern bool skyboxtexture;
-
-//Functions
-
-bool Objects::checkcollide(XYZ startpoint, XYZ endpoint, int which)
-{
-    static XYZ colpoint, colviewer, coltarget;
-    static int i;
-
-    startpoint.y += .1;
-    endpoint.y += .1;
-    startpoint.y -= .1;
-    endpoint.y -= .1;
-
-    for (i = 0; i < numobjects; i++) {
-        if (type[i] != treeleavestype && type[i] != treetrunktype && type[i] != bushtype && type[i] != firetype && i != which) {
-            colviewer = startpoint;
-            coltarget = endpoint;
-            if (model[i].LineCheck(&colviewer, &coltarget, &colpoint, &position[i], &yaw[i]) != -1)
-                return 1;
-        }
-    }
-
-    return 0;
-}
-
-void Objects::SphereCheckPossible(XYZ *p1, float radius)
-{
-    static int i, j;
-    static int whichpatchx;
-    static int whichpatchz;
-
-    whichpatchx = p1->x / (terrain.size / subdivision * terrain.scale);
-    whichpatchz = p1->z / (terrain.size / subdivision * terrain.scale);
-
-    if (whichpatchx >= 0 && whichpatchz >= 0 && whichpatchx < subdivision && whichpatchz < subdivision)
-        if (terrain.patchobjectnum[whichpatchx][whichpatchz] > 0 && terrain.patchobjectnum[whichpatchx][whichpatchz] < 500)
-            for (j = 0; j < terrain.patchobjectnum[whichpatchx][whichpatchz]; j++) {
-                i = terrain.patchobjects[whichpatchx][whichpatchz][j];
-                possible[i] = 0;
-                if (model[i].SphereCheckPossible(p1, radius, &position[i], &yaw[i]) != -1) {
-                    possible[i] = 1;
-                }
-            }
-}
-
-void Objects::Draw()
-{
-    static float distance;
-    static int i;
-    static XYZ moved, terrainlight;
-    bool hidden;
-
-    for (i = 0; i < numobjects; i++) {
-        if (type[i] != firetype) {
-            moved = DoRotation(model[i].boundingspherecenter, 0, yaw[i], 0);
-            if (type[i] == tunneltype || frustum.SphereInFrustum(position[i].x + moved.x, position[i].y + moved.y, position[i].z + moved.z, model[i].boundingsphereradius)) {
-                distance = distsq(&viewer, &position[i]);
-                distance *= 1.2;
-                hidden = !(distsqflat(&viewer, &position[i]) > playerdist + 3 || (type[i] != bushtype && type[i] != treeleavestype));
-                if (!hidden) {
-
-                    if (detail == 2 && distance > viewdistance * viewdistance / 4 && environment == desertenvironment)
-                        glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, blurness );
-                    else
-                        glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
-                    distance = (viewdistance * viewdistance - (distance - (viewdistance * viewdistance * fadestart)) * (1 / (1 - fadestart))) / viewdistance / viewdistance;
-                    if (distance > 1)
-                        distance = 1;
-                    if (distance > 0) {
-
-                        if (occluded[i] < 6) {
-                            glMatrixMode(GL_MODELVIEW);
-                            glPushMatrix();
-                            if (!model[i].color)
-                                glEnable(GL_LIGHTING);
-                            else
-                                glDisable(GL_LIGHTING);
-                            glDepthMask(1);
-                            glTranslatef(position[i].x, position[i].y, position[i].z);
-                            if (type[i] == bushtype) {
-                                messedwith[i] -= multiplier;
-                                if (rotxvel[i] || rotx[i]) {
-                                    if (rotx[i] > 0) rotxvel[i] -= multiplier * 8 * fabs(rotx[i]);
-                                    if (rotx[i] < 0) rotxvel[i] += multiplier * 8 * fabs(rotx[i]);
-                                    if (rotx[i] > 0) rotxvel[i] -= multiplier * 4;
-                                    if (rotx[i] < 0) rotxvel[i] += multiplier * 4;
-                                    if (rotxvel[i] > 0) rotxvel[i] -= multiplier * 4;
-                                    if (rotxvel[i] < 0) rotxvel[i] += multiplier * 4;
-                                    if (fabs(rotx[i]) < multiplier * 4)
-                                        rotx[i] = 0;
-                                    if (fabs(rotxvel[i]) < multiplier * 4)
-                                        rotxvel[i] = 0;
-
-                                    rotx[i] += rotxvel[i] * multiplier * 4;
-                                }
-                                if (rotyvel[i] || roty[i]) {
-                                    if (roty[i] > 0) rotyvel[i] -= multiplier * 8 * fabs(roty[i]);
-                                    if (roty[i] < 0) rotyvel[i] += multiplier * 8 * fabs(roty[i]);
-                                    if (roty[i] > 0) rotyvel[i] -= multiplier * 4;
-                                    if (roty[i] < 0) rotyvel[i] += multiplier * 4;
-                                    if (rotyvel[i] > 0) rotyvel[i] -= multiplier * 4;
-                                    if (rotyvel[i] < 0) rotyvel[i] += multiplier * 4;
-                                    if (fabs(roty[i]) < multiplier * 4)
-                                        roty[i] = 0;
-                                    if (fabs(rotyvel[i]) < multiplier * 4)
-                                        rotyvel[i] = 0;
-
-                                    roty[i] += rotyvel[i] * multiplier * 4;
-                                }
-                                if (roty[i]) {
-                                    glRotatef(roty[i], 1, 0, 0);
-                                }
-                                if (rotx[i]) {
-                                    glRotatef(-rotx[i], 0, 0, 1);
-                                }
-                                if (rotx[i] > 10)
-                                    rotx[i] = 10;
-                                if (rotx[i] < -10)
-                                    rotx[i] = -10;
-                                if (roty[i] > 10)
-                                    roty[i] = 10;
-                                if (roty[i] < -10)
-                                    roty[i] = -10;
-                            }
-                            if (type[i] == treetrunktype || type[i] == treeleavestype) {
-                                if (type[i] == treetrunktype || environment == desertenvironment) {
-                                    messedwith[i] -= multiplier;
-                                    if (rotxvel[i] || rotx[i]) {
-                                        if (rotx[i] > 0) rotxvel[i] -= multiplier * 8 * fabs(rotx[i]);
-                                        if (rotx[i] < 0) rotxvel[i] += multiplier * 8 * fabs(rotx[i]);
-                                        if (rotx[i] > 0) rotxvel[i] -= multiplier * 4;
-                                        if (rotx[i] < 0) rotxvel[i] += multiplier * 4;
-                                        if (rotxvel[i] > 0) rotxvel[i] -= multiplier * 4;
-                                        if (rotxvel[i] < 0) rotxvel[i] += multiplier * 4;
-                                        if (fabs(rotx[i]) < multiplier * 4)
-                                            rotx[i] = 0;
-                                        if (fabs(rotxvel[i]) < multiplier * 4)
-                                            rotxvel[i] = 0;
-
-                                        rotx[i] += rotxvel[i] * multiplier * 4;
-                                    }
-                                    if (rotyvel[i] || roty[i]) {
-                                        if (roty[i] > 0) rotyvel[i] -= multiplier * 8 * fabs(roty[i]);
-                                        if (roty[i] < 0) rotyvel[i] += multiplier * 8 * fabs(roty[i]);
-                                        if (roty[i] > 0) rotyvel[i] -= multiplier * 4;
-                                        if (roty[i] < 0) rotyvel[i] += multiplier * 4;
-                                        if (rotyvel[i] > 0) rotyvel[i] -= multiplier * 4;
-                                        if (rotyvel[i] < 0) rotyvel[i] += multiplier * 4;
-                                        if (fabs(roty[i]) < multiplier * 4)
-                                            roty[i] = 0;
-                                        if (fabs(rotyvel[i]) < multiplier * 4)
-                                            rotyvel[i] = 0;
-
-                                        roty[i] += rotyvel[i] * multiplier * 4;
-                                    }
-                                    if (roty[i]) {
-                                        glRotatef(roty[i] / 6, 1, 0, 0);
-                                    }
-                                    if (rotx[i]) {
-                                        glRotatef(-rotx[i] / 6, 0, 0, 1);
-                                    }
-                                    if (rotx[i] > 10)
-                                        rotx[i] = 10;
-                                    if (rotx[i] < -10)
-                                        rotx[i] = -10;
-                                    if (roty[i] > 10)
-                                        roty[i] = 10;
-                                    if (roty[i] < -10)
-                                        roty[i] = -10;
-                                } else {
-                                    messedwith[i] -= multiplier;
-                                    if (rotxvel[i] || rotx[i]) {
-                                        if (rotx[i] > 0) rotxvel[i] -= multiplier * 8 * fabs(rotx[i]);
-                                        if (rotx[i] < 0) rotxvel[i] += multiplier * 8 * fabs(rotx[i]);
-                                        if (rotx[i] > 0) rotxvel[i] -= multiplier * 4;
-                                        if (rotx[i] < 0) rotxvel[i] += multiplier * 4;
-                                        if (rotxvel[i] > 0) rotxvel[i] -= multiplier * 4;
-                                        if (rotxvel[i] < 0) rotxvel[i] += multiplier * 4;
-                                        if (fabs(rotx[i]) < multiplier * 4)
-                                            rotx[i] = 0;
-                                        if (fabs(rotxvel[i]) < multiplier * 4)
-                                            rotxvel[i] = 0;
-
-                                        rotx[i] += rotxvel[i] * multiplier * 4;
-                                    }
-                                    if (rotyvel[i] || roty[i]) {
-                                        if (roty[i] > 0) rotyvel[i] -= multiplier * 8 * fabs(roty[i]);
-                                        if (roty[i] < 0) rotyvel[i] += multiplier * 8 * fabs(roty[i]);
-                                        if (roty[i] > 0) rotyvel[i] -= multiplier * 4;
-                                        if (roty[i] < 0) rotyvel[i] += multiplier * 4;
-                                        if (rotyvel[i] > 0) rotyvel[i] -= multiplier * 4;
-                                        if (rotyvel[i] < 0) rotyvel[i] += multiplier * 4;
-                                        if (fabs(roty[i]) < multiplier * 4)
-                                            roty[i] = 0;
-                                        if (fabs(rotyvel[i]) < multiplier * 4)
-                                            rotyvel[i] = 0;
-
-                                        roty[i] += rotyvel[i] * multiplier * 4;
-                                    }
-                                    if (roty[i]) {
-                                        glRotatef(roty[i] / 4, 1, 0, 0);
-                                    }
-                                    if (rotx[i]) {
-                                        glRotatef(-rotx[i] / 4, 0, 0, 1);
-                                    }
-                                    if (rotx[i] > 10)
-                                        rotx[i] = 10;
-                                    if (rotx[i] < -10)
-                                        rotx[i] = -10;
-                                    if (roty[i] > 10)
-                                        roty[i] = 10;
-                                    if (roty[i] < -10)
-                                        roty[i] = -10;
-                                }
-
-                            }
-                            if (/*detail==2&&*/environment == snowyenvironment) {
-                                if (type[i] == treeleavestype) {
-                                    glRotatef((sin(windvar + position[i].x * .3) + .5) * 1.5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
-                                }
-                                if (type[i] == treetrunktype) {
-                                    glRotatef((sin(windvar + position[i].x * .3) + .5)*.5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
-                                }
-                                if (type[i] == bushtype) {
-                                    glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
-                                }
-                            }
-                            if (/*detail==2&&*/environment == grassyenvironment) {
-                                if (type[i] == treeleavestype) {
-                                    glRotatef((sin(windvar + position[i].x * .3) + .5) * 1.5 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
-                                }
-                                if (type[i] == treetrunktype) {
-                                    glRotatef((sin(windvar + position[i].x * .3) + .5)*.5 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
-                                }
-                                if (type[i] == bushtype) {
-                                    glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
-                                }
-                            }
-                            if (/*detail==2&&*/environment == desertenvironment) {
-                                if (type[i] == bushtype) {
-                                    glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
-                                }
-                            }
-                            glRotatef(yaw[i], 0, 1, 0);
-                            if (distance > 1)
-                                distance = 1;
-                            glColor4f((1 - shadowed[i]) / 2 + .5, (1 - shadowed[i]) / 2 + .5, (1 - shadowed[i]) / 2 + .5, distance);
-                            if (distance >= 1) {
-                                glDisable(GL_BLEND);
-                                glAlphaFunc(GL_GREATER, 0.5);
-                            }
-                            if (distance < 1) {
-                                glEnable(GL_BLEND);
-                                glAlphaFunc(GL_GREATER, 0.1);
-                            }
-                            if (type[i] != treetrunktype && type[i] != treeleavestype && type[i] != bushtype && type[i] != rocktype) {
-                                glEnable(GL_CULL_FACE);
-                                glAlphaFunc(GL_GREATER, 0.0001);
-                                model[i].drawdifftex(boxtextureptr);
-                                model[i].drawdecals(terrain.shadowtexture, terrain.bloodtexture, terrain.bloodtexture2, terrain.breaktexture);
-                            }
-                            if (type[i] == rocktype) {
-                                glEnable(GL_CULL_FACE);
-                                glAlphaFunc(GL_GREATER, 0.0001);
-                                glColor4f((1 - shadowed[i]) / 2 + light.ambient[0], (1 - shadowed[i]) / 2 + light.ambient[1], (1 - shadowed[i]) / 2 + light.ambient[2], distance);
-                                model[i].drawdifftex(rocktextureptr);
-                                model[i].drawdecals(terrain.shadowtexture, terrain.bloodtexture, terrain.bloodtexture2, terrain.breaktexture);
-                            }
-                            if (type[i] == treeleavestype) {
-                                glDisable(GL_CULL_FACE);
-                                glDisable(GL_LIGHTING);
-                                terrainlight = terrain.getLighting(position[i].x, position[i].z);
-                                if (!hidden) {
-                                    glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance);
-                                    if (distance < 1)
-                                        glAlphaFunc(GL_GREATER, 0.2);
-                                }
-                                if (hidden) {
-                                    glDepthMask(0);
-                                    glEnable(GL_BLEND);
-                                    glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance / 3);
-                                    glAlphaFunc(GL_GREATER, 0);
-                                }
-                                model[i].drawdifftex(treetextureptr);
-                            }
-                            if (type[i] == bushtype) {
-                                glDisable(GL_CULL_FACE);
-                                glDisable(GL_LIGHTING);
-                                terrainlight = terrain.getLighting(position[i].x, position[i].z);
-                                if (!hidden) {
-                                    glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance);
-                                    if (distance < 1)
-                                        glAlphaFunc(GL_GREATER, 0.2);
-                                }
-                                if (hidden) {
-                                    glDepthMask(0);
-                                    glEnable(GL_BLEND);
-                                    glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance / 3);
-                                    glAlphaFunc(GL_GREATER, 0);
-                                }
-                                model[i].drawdifftex(bushtextureptr);
-                            }
-                            if (type[i] == treetrunktype) {
-                                glEnable(GL_CULL_FACE);
-                                terrainlight = terrain.getLighting(position[i].x, position[i].z);
-                                glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, distance);
-                                model[i].drawdifftex(treetextureptr);
-                            }
-                            glPopMatrix();
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
-    for (i = 0; i < numobjects; i++) {
-        if (type[i] == treeleavestype || type[i] == bushtype) {
-            moved = DoRotation(model[i].boundingspherecenter, 0, yaw[i], 0);
-            if (frustum.SphereInFrustum(position[i].x + moved.x, position[i].y + moved.y, position[i].z + moved.z, model[i].boundingsphereradius)) {
-                hidden = distsqflat(&viewer, &position[i]) <= playerdist + 3;
-                if (hidden) {
-                    distance = 1;
-                    glMatrixMode(GL_MODELVIEW);
-                    glPushMatrix();
-                    glEnable(GL_LIGHTING);
-                    glDepthMask(1);
-                    glTranslatef(position[i].x, position[i].y, position[i].z);
-                    if (type[i] == bushtype) {
-                        messedwith[i] -= multiplier;
-                        if (rotxvel[i] || rotx[i]) {
-                            if (rotx[i] > 0) rotxvel[i] -= multiplier * 8 * fabs(rotx[i]);
-                            if (rotx[i] < 0) rotxvel[i] += multiplier * 8 * fabs(rotx[i]);
-                            if (rotx[i] > 0) rotxvel[i] -= multiplier * 4;
-                            if (rotx[i] < 0) rotxvel[i] += multiplier * 4;
-                            if (rotxvel[i] > 0) rotxvel[i] -= multiplier * 4;
-                            if (rotxvel[i] < 0) rotxvel[i] += multiplier * 4;
-                            if (fabs(rotx[i]) < multiplier * 4)
-                                rotx[i] = 0;
-                            if (fabs(rotxvel[i]) < multiplier * 4)
-                                rotxvel[i] = 0;
-
-                            rotx[i] += rotxvel[i] * multiplier * 4;
-                        }
-                        if (rotyvel[i] || roty[i]) {
-                            if (roty[i] > 0) rotyvel[i] -= multiplier * 8 * fabs(roty[i]);
-                            if (roty[i] < 0) rotyvel[i] += multiplier * 8 * fabs(roty[i]);
-                            if (roty[i] > 0) rotyvel[i] -= multiplier * 4;
-                            if (roty[i] < 0) rotyvel[i] += multiplier * 4;
-                            if (rotyvel[i] > 0) rotyvel[i] -= multiplier * 4;
-                            if (rotyvel[i] < 0) rotyvel[i] += multiplier * 4;
-                            if (fabs(roty[i]) < multiplier * 4)
-                                roty[i] = 0;
-                            if (fabs(rotyvel[i]) < multiplier * 4)
-                                rotyvel[i] = 0;
-
-                            roty[i] += rotyvel[i] * multiplier * 4;
-                        }
-                        if (roty[i]) {
-                            glRotatef(roty[i], 1, 0, 0);
-                        }
-                        if (rotx[i]) {
-                            glRotatef(-rotx[i], 0, 0, 1);
-                        }
-                        if (rotx[i] > 10)
-                            rotx[i] = 10;
-                        if (rotx[i] < -10)
-                            rotx[i] = -10;
-                        if (roty[i] > 10)
-                            roty[i] = 10;
-                        if (roty[i] < -10)
-                            roty[i] = -10;
-                    }
-                    if (type[i] == treetrunktype || type[i] == treeleavestype) {
-                        messedwith[i] -= multiplier;
-                        if (rotxvel[i] || rotx[i]) {
-                            if (rotx[i] > 0) rotxvel[i] -= multiplier * 8 * fabs(rotx[i]);
-                            if (rotx[i] < 0) rotxvel[i] += multiplier * 8 * fabs(rotx[i]);
-                            if (rotx[i] > 0) rotxvel[i] -= multiplier * 4;
-                            if (rotx[i] < 0) rotxvel[i] += multiplier * 4;
-                            if (rotxvel[i] > 0) rotxvel[i] -= multiplier * 4;
-                            if (rotxvel[i] < 0) rotxvel[i] += multiplier * 4;
-                            if (fabs(rotx[i]) < multiplier * 4)
-                                rotx[i] = 0;
-                            if (fabs(rotxvel[i]) < multiplier * 4)
-                                rotxvel[i] = 0;
-
-                            rotx[i] += rotxvel[i] * multiplier * 4;
-                        }
-                        if (rotyvel[i] || roty[i]) {
-                            if (roty[i] > 0) rotyvel[i] -= multiplier * 8 * fabs(roty[i]);
-                            if (roty[i] < 0) rotyvel[i] += multiplier * 8 * fabs(roty[i]);
-                            if (roty[i] > 0) rotyvel[i] -= multiplier * 4;
-                            if (roty[i] < 0) rotyvel[i] += multiplier * 4;
-                            if (rotyvel[i] > 0) rotyvel[i] -= multiplier * 4;
-                            if (rotyvel[i] < 0) rotyvel[i] += multiplier * 4;
-                            if (fabs(roty[i]) < multiplier * 4)
-                                roty[i] = 0;
-                            if (fabs(rotyvel[i]) < multiplier * 4)
-                                rotyvel[i] = 0;
-
-                            roty[i] += rotyvel[i] * multiplier * 4;
-                        }
-                        if (roty[i]) {
-                            glRotatef(roty[i] / 2, 1, 0, 0);
-                        }
-                        if (rotx[i]) {
-                            glRotatef(-rotx[i] / 2, 0, 0, 1);
-                        }
-                        if (rotx[i] > 10)
-                            rotx[i] = 10;
-                        if (rotx[i] < -10)
-                            rotx[i] = -10;
-                        if (roty[i] > 10)
-                            roty[i] = 10;
-                        if (roty[i] < -10)
-                            roty[i] = -10;
-                    }
-                    if (environment == snowyenvironment) {
-                        if (type[i] == treeleavestype) {
-                            glRotatef((sin(windvar + position[i].x * .3) + .5) * 1.5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
-                        }
-                        if (type[i] == treetrunktype) {
-                            glRotatef((sin(windvar + position[i].x * .3) + .5)*.5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
-                        }
-                        if (type[i] == bushtype) {
-                            glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
-                        }
-                    }
-                    if (environment == grassyenvironment) {
-                        if (type[i] == treeleavestype) {
-                            glRotatef((sin(windvar + position[i].x * .3) + .5) * 1.5 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
-                        }
-                        if (type[i] == treetrunktype) {
-                            glRotatef((sin(windvar + position[i].x * .3) + .5)*.5 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
-                        }
-                        if (type[i] == bushtype) {
-                            glRotatef((sin(windvar + position[i].x * .3) + .5) * 4 * .5 * (sin(windvar * 2 + position[i].x * .3) + 1) / 2, 1, 0, 0);
-                        }
-                    }
-                    glRotatef(yaw[i], 0, 1, 0);
-                    glColor4f(1, 1, 1, distance);
-                    if (type[i] == treeleavestype) {
-                        glDisable(GL_CULL_FACE);
-                        glDisable(GL_LIGHTING);
-                        terrainlight = terrain.getLighting(position[i].x, position[i].z);
-                        glDepthMask(0);
-                        glEnable(GL_BLEND);
-                        glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, .3);
-                        glAlphaFunc(GL_GREATER, 0);
-                        glDisable(GL_ALPHA_TEST);
-                        model[i].drawdifftex(treetextureptr);
-                    }
-                    if (type[i] == bushtype) {
-                        glDisable(GL_CULL_FACE);
-                        glDisable(GL_LIGHTING);
-                        terrainlight = terrain.getLighting(position[i].x, position[i].z);
-                        glDepthMask(0);
-                        glEnable(GL_BLEND);
-                        glColor4f(terrainlight.x, terrainlight.y, terrainlight.z, .3);
-                        glAlphaFunc(GL_GREATER, 0);
-                        glDisable(GL_ALPHA_TEST);
-                        model[i].drawdifftex(bushtextureptr);
-                    }
-                    glPopMatrix();
-                }
-            }
-        }
-    }
-    if (environment == desertenvironment)
-        glTexEnvf( GL_TEXTURE_FILTER_CONTROL_EXT, GL_TEXTURE_LOD_BIAS_EXT, 0 );
-    glEnable(GL_ALPHA_TEST);
-    SetUpLight(&light, 0);
-}
-
-void Objects::DeleteObject(int which)
-{
-    type[numobjects - 1] = 0;
-    yaw[numobjects - 1] = 0;
-    position[numobjects - 1] = 0;
-    scale[numobjects - 1] = 0;
-    friction[numobjects - 1] = 0;
-
-    numobjects--;
-}
-
-void Objects::MakeObject(int atype, XYZ where, float ayaw, float apitch, float ascale)
-{
-    if ((atype != treeleavestype && atype != bushtype) || foliage == 1) {
-        scale[numobjects] = ascale;
-        if (atype == treeleavestype)
-            scale[numobjects] += fabs((float)(Random() % 100) / 900) * ascale;
-
-        onfire[numobjects] = 0;
-        flamedelay[numobjects] = 0;
-        type[numobjects] = atype;
-
-        if (atype == firetype)
-            onfire[numobjects] = 1;
-
-        position[numobjects] = where;
-        if (atype == bushtype)
-            position[numobjects].y = terrain.getHeight(position[numobjects].x, position[numobjects].z) - .3;
-        yaw[numobjects] = ayaw;
-        pitch[numobjects] = apitch;
-
-        rotxvel[numobjects] = 0;
-        rotyvel[numobjects] = 0;
-        rotx[numobjects] = 0;
-        roty[numobjects] = 0;
-
-        if (atype == boxtype)           model[numobjects].loaddecal("Models/Box.solid", 0);
-        if (atype == cooltype)          model[numobjects].loaddecal("Models/Cool.solid", 0);
-        if (atype == walltype)          model[numobjects].loaddecal("Models/Wall.solid", 0);
-        if (atype == tunneltype)        model[numobjects].loaddecal("Models/Tunnel.solid", 0);
-        if (atype == chimneytype)       model[numobjects].loaddecal("Models/Chimney.solid", 0);
-        if (atype == spiketype)         model[numobjects].load("Models/Spike.solid", 0);
-        if (atype == weirdtype)         model[numobjects].loaddecal("Models/Weird.solid", 0);
-        if (atype == rocktype)          model[numobjects].loaddecal("Models/Rock.solid", 0);
-        if (atype == treetrunktype)     model[numobjects].load("Models/TreeTrunk.solid", 0);
-        if (atype == treeleavestype)    model[numobjects].load("Models/Leaves.solid", 0);
-        if (atype == bushtype)          model[numobjects].load("Models/Bush.solid", 0);
-
-        if (atype == boxtype)           friction[numobjects] = 1.5;
-        if (atype == cooltype)          friction[numobjects] = 1.5;
-        if (atype == walltype)          friction[numobjects] = 1.5;
-        if (atype == platformtype)      friction[numobjects] = 1.5;
-        if (atype == tunneltype)        friction[numobjects] = 1.5;
-        if (atype == chimneytype)       friction[numobjects] = 1.5;
-        if (atype == rocktype)          friction[numobjects] = .5;
-        if (atype == rocktype && ascale>.5) friction[numobjects] = 1.5;
-        if (atype == weirdtype)         friction[numobjects] = 1.5;
-        if (atype == spiketype)         friction[numobjects] = .4;
-        if (atype == treetrunktype)     friction[numobjects] = .4;
-        if (atype == treeleavestype)    friction[numobjects] = 0;
-
-        if (friction[numobjects] == 1.5 && fabs(apitch) > 5)
-            friction[numobjects] = .5;
-
-        if (atype == platformtype) {
-            model[numobjects].loaddecal("Models/Platform.solid", 0);
-            model[numobjects].Rotate(90, 0, 0);
-        }
-
-        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) {
-            model[numobjects].ScaleTexCoords(scale[numobjects] * 1.5);
-        }
-        if (type[numobjects] == rocktype) {
-            model[numobjects].ScaleTexCoords(scale[numobjects] * 3);
-        }
-        model[numobjects].flat = 1;
-        if (atype == treetrunktype || atype == treeleavestype || atype == rocktype) {
-            model[numobjects].flat = 0;
-        }
-        model[numobjects].Scale(.3 * scale[numobjects], .3 * scale[numobjects], .3 * scale[numobjects]);
-        model[numobjects].Rotate(90, 1, 1);
-        model[numobjects].Rotate(apitch, 0, 0);
-        if (type[numobjects] == rocktype) {
-            model[numobjects].Rotate(ayaw * 5, 0, 0);
-        }
-        model[numobjects].CalculateNormals(1);
-        model[numobjects].ScaleNormals(-1, -1, -1);
-
-        if (detail == 2) {
-            if (atype == treetrunktype && position[numobjects].y < terrain.getHeight(position[numobjects].x, position[numobjects].z) + 1) {
-                terrain.MakeDecal(shadowdecalpermanent, position[numobjects], 2, .4, 0);
-            }
-
-            if (atype == bushtype && position[numobjects].y < terrain.getHeight(position[numobjects].x, position[numobjects].z) + 1) {
-                terrain.MakeDecal(shadowdecalpermanent, position[numobjects], 1, .4, 0);
-            }
-        }
-
-        if (atype != treeleavestype && atype != bushtype && atype != firetype) {
-            terrain.AddObject(where + DoRotation(model[numobjects].boundingspherecenter, 0, ayaw, 0), model[numobjects].boundingsphereradius, numobjects);
-        }
-
-        numobjects++;
-    }
-}
-
-void Objects::DoStuff()
-{
-    XYZ spawnpoint;
-    for (int i = 0; i < numobjects; i++) {
-        if (type[i] == firetype)
-            onfire[i] = 1;
-        if (onfire[i]) {
-            if (type[i] == bushtype)
-                flamedelay[i] -= multiplier * 3;
-            if (type[i] == firetype)
-                flamedelay[i] -= multiplier * 3;
-            if (type[i] == treeleavestype)
-                flamedelay[i] -= multiplier * 4;
-            while (flamedelay[i] < 0 && onfire[i]) {
-                flamedelay[i] += .006;
-                if (type[i] == bushtype || type[i] == firetype) {
-                    spawnpoint.x = ((float)(Random() % 100)) / 30 * scale[i];
-                    spawnpoint.y = ((float)(Random() % 100) + 60) / 30 * scale[i];
-                    spawnpoint.z = 0;
-                    spawnpoint = DoRotation(spawnpoint, 0, Random() % 360, 0);
-                    spawnpoint += position[i];
-                    Sprite::MakeSprite(flamesprite, spawnpoint, spawnpoint * 0, 1, 1, 1, (.6 + (float)abs(Random() % 100) / 200 - .25) * 5 * scale[i], 1);
-                }
-                if (type[i] == treeleavestype) {
-                    spawnpoint.x = ((float)(Random() % 100)) / 80 * scale[i];
-                    spawnpoint.y = ((float)(Random() % 100) + 80) / 12 * scale[i];
-                    spawnpoint.z = 0;
-                    spawnpoint = DoRotation(spawnpoint, 0, Random() % 360, 0);
-                    spawnpoint += position[i];
-                    Sprite::MakeSprite(flamesprite, spawnpoint, spawnpoint * 0, 1, 1, 1, (.6 + (float)abs(Random() % 100) / 200 - .25) * 6, 1);
-                }
-            }
-
-        }
-    }
-}
-
-void Objects::DoShadows()
-{
-    int i, j, k, l;
-    static XYZ testpoint, testpoint2, terrainpoint, lightloc, col;
-    lightloc = light.location;
-    if (!skyboxtexture)
-        lightloc = 0;
-    lightloc.y += 10;
-    Normalise(&lightloc);
-    int patchx, patchz;
-
-    if (numobjects > 0)
-        for (i = 0; i < numobjects; i++) {
-            if (type[i] != treeleavestype && type[i] != treetrunktype && type[i] != bushtype && type[i] != firetype) {
-                for (j = 0; j < model[i].vertexNum; j++) {
-                    terrainpoint = position[i] + DoRotation(model[i].vertex[j] + model[i].normals[j] * .1, 0, yaw[i], 0);
-                    //terrainpoint.y+=model[i].boundingsphereradius;
-                    shadowed[i] = 0;
-                    patchx = terrainpoint.x / (terrain.size / subdivision * terrain.scale);
-                    patchz = terrainpoint.z / (terrain.size / subdivision * terrain.scale);
-                    if (patchx >= 0 && patchz >= 0 && patchx < subdivision && patchz < subdivision)
-                        if (terrain.patchobjectnum[patchx][patchz])
-                            for (k = 0; k < terrain.patchobjectnum[patchx][patchz]; k++) {
-                                l = terrain.patchobjects[patchx][patchz][k];
-                                if (type[l] != treetrunktype/*&&l!=i*/) {
-                                    testpoint = terrainpoint;
-                                    testpoint2 = terrainpoint + lightloc * 50 * (1 - shadowed[i]);
-                                    if (model[l].LineCheck(&testpoint, &testpoint2, &col, &position[l], &yaw[l]) != -1) {
-                                        shadowed[i] = 1 - (findDistance(&terrainpoint, &col) / 50);
-                                    }
-                                }
-                            }
-                    if (shadowed[i] > 0) {
-                        col = model[i].normals[j] - DoRotation(lightloc * shadowed[i], 0, -yaw[i], 0);
-                        Normalise(&col);
-                        for (k = 0; k < model[i].TriangleNum; k++) {
-                            if (model[i].Triangles[k].vertex[0] == j) {
-                                l = k * 24;
-                                model[i].vArray[l + 2] = col.x;
-                                model[i].vArray[l + 3] = col.y;
-                                model[i].vArray[l + 4] = col.z;
-                            }
-                            if (model[i].Triangles[k].vertex[1] == j) {
-                                l = k * 24;
-                                model[i].vArray[l + 10] = col.x;
-                                model[i].vArray[l + 11] = col.y;
-                                model[i].vArray[l + 12] = col.z;
-                            }
-                            if (model[i].Triangles[k].vertex[2] == j) {
-                                l = k * 24;
-                                model[i].vArray[l + 18] = col.x;
-                                model[i].vArray[l + 19] = col.y;
-                                model[i].vArray[l + 20] = col.z;
-                            }
-                        }
-                    }
-                }
-            }
-            shadowed[i] = 0;
-        }
-}
-
-Objects::Objects()
-{
-    center = 0;
-    radius = 0;
-    numobjects = 0;
-
-    memset(position, 0, sizeof(position));
-    memset(type, 0, sizeof(type));
-    memset(yaw, 0, sizeof(yaw));
-    memset(pitch, 0, sizeof(pitch));
-    memset(rotx, 0, sizeof(rotx));
-    memset(rotxvel, 0, sizeof(rotxvel));
-    memset(roty, 0, sizeof(roty));
-    memset(rotyvel, 0, sizeof(rotyvel));
-    memset(possible, 0, sizeof(possible));
-    memset(model, 0, sizeof(model));
-    memset(displaymodel, 0, sizeof(displaymodel));
-    memset(friction, 0, sizeof(friction));
-    memset(scale, 0, sizeof(scale));
-    memset(messedwith, 0, sizeof(messedwith));
-    memset(checked, 0, sizeof(checked));
-    memset(shadowed, 0, sizeof(shadowed));
-    memset(occluded, 0, sizeof(occluded));
-    memset(onfire, 0, sizeof(onfire));
-    memset(flamedelay, 0, sizeof(flamedelay));
-}
-
-Objects::~Objects()
-{
-    boxtextureptr.destroy();
-    treetextureptr.destroy();
-    bushtextureptr.destroy();
-    rocktextureptr.destroy();
-}
diff --git a/Source/Objects/Objects.hpp b/Source/Objects/Objects.hpp
deleted file mode 100644 (file)
index 40c10bd..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
-Copyright (C) 2003, 2010 - Wolfire Games
-Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file)
-
-This file is part of Lugaru.
-
-Lugaru is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
-
-Lugaru is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _OBJECTS_HPP_
-#define _OBJECTS_HPP_
-
-#include "Environment/Lights.hpp"
-#include "Environment/Terrain.hpp"
-#include "Graphic/gamegl.hpp"
-#include "Graphic/Models.hpp"
-#include "Graphic/Sprite.hpp"
-#include "Graphic/Texture.hpp"
-#include "Math/Frustum.hpp"
-#include "Math/Quaternions.hpp"
-#include "Utils/ImageIO.hpp"
-
-#include <vector>
-//
-// Model Structures
-//
-
-#define max_objects 300
-
-#define boxtype 0
-#define weirdtype 1
-#define spiketype 2
-#define treetrunktype 3
-#define treeleavestype 4
-#define bushtype 5
-#define rocktype 6
-#define walltype 7
-#define chimneytype 8
-#define platformtype 9
-#define tunneltype 11
-#define cooltype 12
-#define firetype 13
-
-
-class Objects
-{
-public:
-    XYZ center;
-    float radius;
-    XYZ position[max_objects];
-    int type[max_objects];
-    float yaw[max_objects];
-    float pitch[max_objects];
-    float rotx[max_objects];
-    float rotxvel[max_objects];
-    float roty[max_objects];
-    float rotyvel[max_objects];
-    int numobjects;
-    bool possible[max_objects];
-    Model model[max_objects];
-    Model displaymodel[max_objects];
-    float friction[max_objects];
-    float scale[max_objects];
-    float messedwith[max_objects];
-    float checked[max_objects];
-    Texture boxtextureptr;
-    Texture treetextureptr;
-    Texture bushtextureptr;
-    Texture rocktextureptr;
-    float shadowed[max_objects];
-    float occluded[max_objects];
-    bool checkcollide(XYZ startpoint, XYZ endpoint, int which);
-    bool onfire[max_objects];
-    float flamedelay[max_objects];
-
-    void SphereCheckPossible(XYZ *p1, float radius);
-    void DeleteObject(int which);
-    void MakeObject(int atype, XYZ where, float ayaw, float apitch, float ascale);
-    void Draw();
-    void DoShadows();
-    void DoStuff();
-
-    Objects();
-    ~Objects();
-};
-
-#endif
-
index 8bd82698909fede4bdd2b22ccee6bb71b74e2bb8..c1b35e443d365d693e56f1cef87daf03d1ee3891 100644 (file)
@@ -44,7 +44,6 @@ extern float realtexdetail;
 extern GLubyte bloodText[512 * 512 * 3];
 extern GLubyte wolfbloodText[512 * 512 * 3];
 extern int bloodtoggle;
-extern Objects objects;
 extern bool autoslomo;
 extern float camerashake;
 extern float woozy;
@@ -1794,7 +1793,7 @@ void Person::RagDoll(bool checkcollision)
                     i = terrain.patchobjects[whichpatchx][whichpatchz][l];
                     lowpoint = coords;
                     lowpoint.y += 1;
-                    if (SphereCheck(&lowpoint, 3, &colpoint, &objects.position[i], &objects.yaw[i], &objects.model[i]) != -1) {
+                    if (SphereCheck(&lowpoint, 3, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw, &Object::objects[i]->model) != -1) {
                         coords.x = lowpoint.x;
                         coords.z = lowpoint.z;
                     }
@@ -4833,11 +4832,11 @@ void Person::DoStuff()
         if (bloodtoggle && !bled)
             for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
                 int j = terrain.patchobjects[whichpatchx][whichpatchz][l];
-                XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
+                XYZ point = DoRotation(headpoint - Object::objects[j]->position, 0, -Object::objects[j]->yaw, 0);
                 float size = .8;
                 float opacity = .6;
                 float yaw = 0;
-                objects.model[j].MakeDecal(blooddecalslow, &point, &size, &opacity, &yaw);
+                Object::objects[j]->model.MakeDecal(blooddecalslow, &point, &size, &opacity, &yaw);
             }
         bled = 1;
     }
@@ -5043,11 +5042,11 @@ void Person::DoStuff()
                     if (bloodtoggle && !bled)
                         for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
                             int j = terrain.patchobjects[whichpatchx][whichpatchz][l];
-                            XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
+                            XYZ point = DoRotation(headpoint - Object::objects[j]->position, 0, -Object::objects[j]->yaw, 0);
                             float size = .2 * 1.2;
                             float opacity = .6;
                             float yaw = 0;
-                            objects.model[j].MakeDecal(blooddecal, &point, &size, &opacity, &yaw);
+                            Object::objects[j]->model.MakeDecal(blooddecal, &point, &size, &opacity, &yaw);
                         }
                     bled = 1;
                 }
@@ -5062,11 +5061,11 @@ void Person::DoStuff()
                     if (bloodtoggle && !bled)
                         for (l = 0; l < terrain.patchobjectnum[whichpatchx][whichpatchz]; l++) {
                             int j = terrain.patchobjects[whichpatchx][whichpatchz][l];
-                            XYZ point = DoRotation(headpoint - objects.position[j], 0, -objects.yaw[j], 0);
+                            XYZ point = DoRotation(headpoint - Object::objects[j]->position, 0, -Object::objects[j]->yaw, 0);
                             float size = .8;
                             float opacity = .6;
                             float yaw = 0;
-                            objects.model[j].MakeDecal(blooddecalslow, &point, &size, &opacity, &yaw);
+                            Object::objects[j]->model.MakeDecal(blooddecalslow, &point, &size, &opacity, &yaw);
                         }
                     bled = 1;
                 }
@@ -5083,11 +5082,11 @@ void Person::DoStuff()
                 canrecover = 0;
             if (velocity.y < -30)
                 canrecover = 0;
-            for (i = 0; i < objects.numobjects; i++) {
-                if (objects.type[i] != treeleavestype && objects.type[i] != bushtype && objects.type[i] != firetype) {
+            for (i = 0; i < Object::objects.size(); i++) {
+                if (Object::objects[i]->type != treeleavestype && Object::objects[i]->type != bushtype && Object::objects[i]->type != firetype) {
                     colviewer = startpoint;
                     coltarget = endpoint;
-                    if (objects.model[i].LineCheck(&colviewer, &coltarget, &colpoint, &objects.position[i], &objects.yaw[i]) != -1)
+                    if (Object::objects[i]->model.LineCheck(&colviewer, &coltarget, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw) != -1)
                         canrecover = 0;
                 }
             }
@@ -5275,36 +5274,36 @@ void Person::DoStuff()
 
     if (aitype != passivetype || skeleton.free == 1)
         if (findLengthfast(&velocity) > .1)
-            for (i = 0; i < objects.numobjects; i++) {
-                if (objects.type[i] == firetype)
-                    if (distsqflat(&coords, &objects.position[i]) < objects.scale[i]*objects.scale[i] * 12 && distsq(&coords, &objects.position[i]) < objects.scale[i]*objects.scale[i] * 49) {
+            for (i = 0; i < Object::objects.size(); i++) {
+                if (Object::objects[i]->type == firetype)
+                    if (distsqflat(&coords, &Object::objects[i]->position) < Object::objects[i]->scale*Object::objects[i]->scale * 12 && distsq(&coords, &Object::objects[i]->position) < Object::objects[i]->scale*Object::objects[i]->scale * 49) {
                         if (onfire) {
-                            if (!objects.onfire[i]) {
-                                emit_sound_at(firestartsound, objects.position[i]);
+                            if (!Object::objects[i]->onfire) {
+                                emit_sound_at(firestartsound, Object::objects[i]->position);
                             }
-                            objects.onfire[i] = 1;
+                            Object::objects[i]->onfire = 1;
                         }
                         if (!onfire) {
-                            if (objects.onfire[i]) {
+                            if (Object::objects[i]->onfire) {
                                 CatchFire();
                             }
                         }
                     }
-                if (objects.type[i] == bushtype)
-                    if (distsqflat(&coords, &objects.position[i]) < objects.scale[i]*objects.scale[i] * 12 && distsq(&coords, &objects.position[i]) < objects.scale[i]*objects.scale[i] * 49) {
+                if (Object::objects[i]->type == bushtype)
+                    if (distsqflat(&coords, &Object::objects[i]->position) < Object::objects[i]->scale*Object::objects[i]->scale * 12 && distsq(&coords, &Object::objects[i]->position) < Object::objects[i]->scale*Object::objects[i]->scale * 49) {
                         if (onfire) {
-                            if (!objects.onfire[i]) {
-                                emit_sound_at(firestartsound, objects.position[i]);
+                            if (!Object::objects[i]->onfire) {
+                                emit_sound_at(firestartsound, Object::objects[i]->position);
                             }
-                            objects.onfire[i] = 1;
+                            Object::objects[i]->onfire = 1;
                         }
 
                         if (!onfire) {
-                            if (objects.onfire[i]) {
+                            if (Object::objects[i]->onfire) {
                                 CatchFire();
                             }
                         }
-                        if (objects.messedwith[i] <= 0) {
+                        if (Object::objects[i]->messedwith <= 0) {
                             XYZ tempvel;
                             XYZ pos;
 
@@ -5349,22 +5348,22 @@ void Person::DoStuff()
                                         Sprite::setLastSpriteSpecial(2);
                                     }
                         }
-                        objects.rotx[i] += velocity.x * multiplier * 6;
-                        objects.roty[i] += velocity.z * multiplier * 6;
-                        objects.messedwith[i] = .5;
+                        Object::objects[i]->rotx += velocity.x * multiplier * 6;
+                        Object::objects[i]->roty += velocity.z * multiplier * 6;
+                        Object::objects[i]->messedwith = .5;
                     }
                 XYZ tempcoord;
-                if (objects.type[i] == treeleavestype && environment != desertenvironment) {
-                    if (objects.pitch[i] == 0)
+                if (Object::objects[i]->type == treeleavestype && environment != desertenvironment) {
+                    if (Object::objects[i]->pitch == 0)
                         tempcoord = coords;
                     else {
-                        tempcoord = coords - objects.position[i];
-                        tempcoord = DoRotation(tempcoord, 0, -objects.yaw[i], 0);
-                        tempcoord = DoRotation(tempcoord, -objects.pitch[i], 0, 0);
-                        tempcoord += objects.position[i];
+                        tempcoord = coords - Object::objects[i]->position;
+                        tempcoord = DoRotation(tempcoord, 0, -Object::objects[i]->yaw, 0);
+                        tempcoord = DoRotation(tempcoord, -Object::objects[i]->pitch, 0, 0);
+                        tempcoord += Object::objects[i]->position;
                     }
-                    if (distsqflat(&tempcoord, &objects.position[i]) < objects.scale[i]*objects.scale[i] * 8 && distsq(&tempcoord, &objects.position[i]) < objects.scale[i]*objects.scale[i] * 300 && tempcoord.y > objects.position[i].y + 3 * objects.scale[i]) {
-                        if (objects.messedwith[i] <= 0) {
+                    if (distsqflat(&tempcoord, &Object::objects[i]->position) < Object::objects[i]->scale*Object::objects[i]->scale * 8 && distsq(&tempcoord, &Object::objects[i]->position) < Object::objects[i]->scale*Object::objects[i]->scale * 300 && tempcoord.y > Object::objects[i]->position.y + 3 * Object::objects[i]->scale) {
+                        if (Object::objects[i]->messedwith <= 0) {
                             XYZ tempvel;
                             XYZ pos;
 
@@ -5411,7 +5410,7 @@ void Person::DoStuff()
                                         Sprite::setLastSpriteSpecial(2);
                                     }
                         }
-                        objects.messedwith[i] = .5;
+                        Object::objects[i]->messedwith = .5;
                     }
                 }
             }
index a6a1786736897d38e198661869c2fe09fa9d148d..127c014cb41702bd2c10df4790514184369711e9 100644 (file)
@@ -42,7 +42,6 @@ extern bool cellophane;
 extern float texdetail;
 extern GLubyte bloodText[512 * 512 * 3];
 extern int bloodtoggle;
-extern Objects objects;
 extern bool autoslomo;
 extern float camerashake;
 extern float woozy;
@@ -158,16 +157,16 @@ void Weapon::DoStuff(int i)
         whichpatchx = position.x / (terrain.size / subdivision * terrain.scale);
         whichpatchz = position.z / (terrain.size / subdivision * terrain.scale);
         if (whichpatchx > 0 && whichpatchz > 0 && whichpatchx < subdivision && whichpatchz < subdivision) {
-            if (terrain.patchobjectnum[whichpatchx][whichpatchz]) { // if there are objects where the weapon is
+            if (terrain.patchobjectnum[whichpatchx][whichpatchz]) { // if there are Object::objects where the weapon is
                 for (int j = 0; j < terrain.patchobjectnum[whichpatchx][whichpatchz]; j++) { // check for collision
                     int k = terrain.patchobjects[whichpatchx][whichpatchz][j];
                     start = oldtippoint;
                     end = tippoint;
-                    whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
+                    whichhit = Object::objects[k]->model.LineCheck(&start, &end, &colpoint, &Object::objects[k]->position, &Object::objects[k]->yaw);
                     if (whichhit != -1) {
-                        if (objects.type[k] == treetrunktype) {
-                            objects.model[k].MakeDecal(breakdecal, DoRotation(colpoint - objects.position[k], 0, -objects.yaw[k], 0), .1, 1, Random() % 360);
-                            normalrot = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0);
+                        if (Object::objects[k]->type == treetrunktype) {
+                            Object::objects[k]->model.MakeDecal(breakdecal, DoRotation(colpoint - Object::objects[k]->position, 0, -Object::objects[k]->yaw, 0), .1, 1, Random() % 360);
+                            normalrot = DoRotation(Object::objects[k]->model.facenormals[whichhit], 0, Object::objects[k]->yaw, 0);
                             velocity = 0;
                             if (type == knife)
                                 position = colpoint - normalrot * .1;
@@ -416,7 +415,7 @@ void Weapon::DoStuff(int i)
                             if (type == staff) {
                                 start = tippoint - (position - tippoint) / 5;
                                 end = position + (position - tippoint) / 30;
-                                whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
+                                whichhit = Object::objects[k]->model.LineCheck(&start, &end, &colpoint, &Object::objects[k]->position, &Object::objects[k]->yaw);
                                 if (whichhit != -1) {
                                     XYZ diff;
                                     diff = (colpoint - position);
@@ -431,7 +430,7 @@ void Weapon::DoStuff(int i)
                             } else {
                                 start = position - (tippoint - position) / 5;
                                 end = tippoint + (tippoint - position) / 30;
-                                whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
+                                whichhit = Object::objects[k]->model.LineCheck(&start, &end, &colpoint, &Object::objects[k]->position, &Object::objects[k]->yaw);
                                 if (whichhit != -1) {
                                     XYZ diff;
                                     diff = (colpoint - tippoint);
@@ -448,11 +447,11 @@ void Weapon::DoStuff(int i)
 
                         start = oldposition;
                         end = position;
-                        whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
+                        whichhit = Object::objects[k]->model.LineCheck(&start, &end, &colpoint, &Object::objects[k]->position, &Object::objects[k]->yaw);
                         if (whichhit != -1) {
                             hitsomething = 1;
                             position = colpoint;
-                            terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1;
+                            terrainnormal = DoRotation(Object::objects[k]->model.facenormals[whichhit], 0, Object::objects[k]->yaw, 0) * -1;
                             ReflectVector(&velocity, &terrainnormal);
                             position += terrainnormal * .002;
 
@@ -478,11 +477,11 @@ void Weapon::DoStuff(int i)
                         }
                         start = oldtippoint;
                         end = tippoint;
-                        whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
+                        whichhit = Object::objects[k]->model.LineCheck(&start, &end, &colpoint, &Object::objects[k]->position, &Object::objects[k]->yaw);
                         if (whichhit != -1) {
                             hitsomething = 1;
                             tippoint = colpoint;
-                            terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1;
+                            terrainnormal = DoRotation(Object::objects[k]->model.facenormals[whichhit], 0, Object::objects[k]->yaw, 0) * -1;
                             ReflectVector(&tipvelocity, &terrainnormal);
                             tippoint += terrainnormal * .002;
 
@@ -507,7 +506,7 @@ void Weapon::DoStuff(int i)
                             }
                         }
 
-                        if ((objects.type[k] != boxtype && objects.type[k] != platformtype && objects.type[k] != walltype && objects.type[k] != weirdtype) || objects.pitch[k] != 0)
+                        if ((Object::objects[k]->type != boxtype && Object::objects[k]->type != platformtype && Object::objects[k]->type != walltype && Object::objects[k]->type != weirdtype) || Object::objects[k]->pitch != 0)
                             for (int m = 0; m < 2; m++) {
                                 mid = (position * (21 + (float)m * 10) + tippoint * (19 - (float)m * 10)) / 40;
                                 oldmid2 = mid;
@@ -515,11 +514,11 @@ void Weapon::DoStuff(int i)
 
                                 start = oldmid;
                                 end = mid;
-                                whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
+                                whichhit = Object::objects[k]->model.LineCheck(&start, &end, &colpoint, &Object::objects[k]->position, &Object::objects[k]->yaw);
                                 if (whichhit != -1) {
                                     hitsomething = 1;
                                     mid = colpoint;
-                                    terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1;
+                                    terrainnormal = DoRotation(Object::objects[k]->model.facenormals[whichhit], 0, Object::objects[k]->yaw, 0) * -1;
                                     ReflectVector(&velocity, &terrainnormal);
 
                                     bounceness = terrainnormal * findLength(&velocity) * (abs(normaldotproduct(velocity, terrainnormal)));
@@ -550,11 +549,11 @@ void Weapon::DoStuff(int i)
 
                                 start = oldmid;
                                 end = mid;
-                                whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
+                                whichhit = Object::objects[k]->model.LineCheck(&start, &end, &colpoint, &Object::objects[k]->position, &Object::objects[k]->yaw);
                                 if (whichhit != -1) {
                                     hitsomething = 1;
                                     mid = colpoint;
-                                    terrainnormal = DoRotation(objects.model[k].facenormals[whichhit], 0, objects.yaw[k], 0) * -1;
+                                    terrainnormal = DoRotation(Object::objects[k]->model.facenormals[whichhit], 0, Object::objects[k]->yaw, 0) * -1;
                                     ReflectVector(&tipvelocity, &terrainnormal);
 
                                     bounceness = terrainnormal * findLength(&tipvelocity) * (abs(normaldotproduct(tipvelocity, terrainnormal)));
@@ -582,14 +581,14 @@ void Weapon::DoStuff(int i)
                         else {
                             start = position;
                             end = tippoint;
-                            whichhit = objects.model[k].LineCheck(&start, &end, &colpoint, &objects.position[k], &objects.yaw[k]);
+                            whichhit = Object::objects[k]->model.LineCheck(&start, &end, &colpoint, &Object::objects[k]->position, &Object::objects[k]->yaw);
                             if (whichhit != -1) {
                                 hitsomething = 1;
                                 closestdistance = -1;
                                 closestswordpoint = colpoint; //(position+tippoint)/2;
-                                point[0] = DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[0]], 0, objects.yaw[k], 0) + objects.position[k];
-                                point[1] = DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[1]], 0, objects.yaw[k], 0) + objects.position[k];
-                                point[2] = DoRotation(objects.model[k].vertex[objects.model[k].Triangles[whichhit].vertex[2]], 0, objects.yaw[k], 0) + objects.position[k];
+                                point[0] = DoRotation(Object::objects[k]->model.vertex[Object::objects[k]->model.Triangles[whichhit].vertex[0]], 0, Object::objects[k]->yaw, 0) + Object::objects[k]->position;
+                                point[1] = DoRotation(Object::objects[k]->model.vertex[Object::objects[k]->model.Triangles[whichhit].vertex[1]], 0, Object::objects[k]->yaw, 0) + Object::objects[k]->position;
+                                point[2] = DoRotation(Object::objects[k]->model.vertex[Object::objects[k]->model.Triangles[whichhit].vertex[2]], 0, Object::objects[k]->yaw, 0) + Object::objects[k]->position;
                                 if (DistancePointLine(&closestswordpoint, &point[0], &point[1], &distance, &colpoint )) {
                                     if (distance < closestdistance || closestdistance == -1) {
                                         closestpoint = colpoint;
index 2e178ce01bba269aa76a19d367af06466f590cb6..c40d65c94f5f1885ffd74acade9c631427b9c9ef 100644 (file)
@@ -1100,7 +1100,7 @@ public:
    *            Note, that once the argument vector has been reordered, the @c gnu flag will have
    *            no further effect on this argument vector. So it is enough to pass @c gnu==true when
    *            creating Stats.
-   * @param usage Array of Descriptor objects that describe the options to support. The last entry
+   * @param usage Array of Descriptor Object::objects that describe the options to support. The last entry
    *              of this array must have 0 in all fields.
    * @param argc The number of elements from @c argv that are to be parsed. If you pass -1, the number
    *             will be determined automatically. In that case the @c argv list must end with a NULL
@@ -1137,10 +1137,10 @@ public:
    *               -1 (or not pass @c bufmax at all) which tells parse() that the buffer is
    *               "large enough".
    * @attention
-   * Remember that @c options and @c buffer store Option @e objects, not pointers. Therefore it
+   * Remember that @c options and @c buffer store Option @e Object::objects, not pointers. Therefore it
    * is not possible for the same object to be in both arrays. For those options that are found in
-   * both @c buffer[] and @c options[] the respective objects are independent copies. And only the
-   * objects in @c options[] are properly linked via Option::next() and Option::prev().
+   * both @c buffer[] and @c options[] the respective Object::objects are independent copies. And only the
+   * Object::objects in @c options[] are properly linked via Option::next() and Option::prev().
    * You can iterate over @c buffer[] to
    * process all options in the order they appear in the argument vector, but if you want access to
    * the other Options with the same Descriptor::index, then you @e must access the linked list via
@@ -1172,7 +1172,7 @@ public:
   }
 
   /**
-   * @brief Returns the number of valid Option objects in @c buffer[].
+   * @brief Returns the number of valid Option Object::objects in @c buffer[].
    *
    * @note
    * @li The returned value always reflects the number of Options in the buffer[] array used for
@@ -2724,8 +2724,8 @@ struct PrintUsageImplementation
  * @par Notes:
  * @li the @c write() method of a class that is to be passed as a temporary
  *     as @c MyWriter() is in the example, must be a @c const method, because
- *     temporary objects are passed as const reference. This only applies to
- *     temporary objects that are created and destroyed in the same statement.
+ *     temporary Object::objects are passed as const reference. This only applies to
+ *     temporary Object::objects that are created and destroyed in the same statement.
  *     If you create an object like @c writer in the example, this restriction
  *     does not apply.
  * @li a functor like @c MyWriteFunctor in the example must be passed as a pointer.
index dddb214e6330289d202d45bf0806e0d9ac34f303..a566125b6d4a36022dd84396aef87b10c936ff77 100644 (file)
@@ -35,10 +35,10 @@ extern "C" {
     an optional byte-order marker (defaults to H, "host-native"),
     and a  data-type specifier.
     * when unpacking, each variable argument is a pointer to the
-    appropriate number of objects of the appropriate type.
+    appropriate number of Object::objects of the appropriate type.
     * when packing, each variable argument is an object of the
     appropriate type if the count is omitted, or a pointer to the
-    appropriate number of objects of the appropriate type if the
+    appropriate number of Object::objects of the appropriate type if the
     count is specified.
     * the buffer supplied to pack/unpack must be of sufficient length
     to hold all the data, or the behavior is unspecified.
index 3583ba615a6b80cfb0618066535570ef9762f877..4a3e2537ec82db57697d5664a3e7e3b18912c0a5 100644 (file)
@@ -24,8 +24,8 @@ along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
 //
 #define IDI_LUGARU                      104
 
-// Next default values for new objects
-// 
+// Next default values for new Object::objects
+//
 #ifdef APSTUDIO_INVOKED
 #ifndef APSTUDIO_READONLY_SYMBOLS
 #define _APS_NEXT_RESOURCE_VALUE        105