aboutsummaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authoricculus <icculus@5198baeb-e213-0410-be47-fc2ff85ca46f>2003-01-02 21:06:00 +0000
committericculus <icculus@5198baeb-e213-0410-be47-fc2ff85ca46f>2003-01-02 21:06:00 +0000
commite17acec1c9bec3a26d97ca2873bb77bdcb48665e (patch)
tree26b14b6cedcb70df651c23dddbf0981970d0bd4d /Source
parent59ca62d601e30b5467f8ecd2cb7d517bc682fc12 (diff)
downloadblackshades-e17acec1c9bec3a26d97ca2873bb77bdcb48665e.tar.gz
Initial revision
git-svn-id: svn://svn.icculus.org/blackshades/trunk@2 5198baeb-e213-0410-be47-fc2ff85ca46f
Diffstat (limited to 'Source')
-rw-r--r--Source/AGL_DSp.cpp242
-rw-r--r--Source/AGL_DSp.h41
-rw-r--r--Source/Alerts.cpp93
-rw-r--r--Source/Alerts.h44
-rw-r--r--Source/Camera.cpp8
-rw-r--r--Source/Camera.h23
-rw-r--r--Source/Constants.h135
-rw-r--r--Source/Decals.cpp445
-rw-r--r--Source/Decals.h54
-rw-r--r--Source/Files.cpp173
-rw-r--r--Source/Files.h88
-rw-r--r--Source/Fog.cpp53
-rw-r--r--Source/Fog.h23
-rw-r--r--Source/Frustum.cpp153
-rw-r--r--Source/Frustum.h13
-rw-r--r--Source/Game.h210
-rw-r--r--Source/GameDraw.cpp1771
-rw-r--r--Source/GameInitDispose.cpp3846
-rw-r--r--Source/GameLoop.cpp371
-rw-r--r--Source/GameTick.cpp4923
-rw-r--r--Source/Globals.cpp90
-rw-r--r--Source/MacInput.cpp42
-rw-r--r--Source/MacInput.h101
-rw-r--r--Source/Main.cpp64
-rw-r--r--Source/Maths.cpp21
-rw-r--r--Source/Maths.h10
-rw-r--r--Source/Models.cpp339
-rw-r--r--Source/Models.h60
-rw-r--r--Source/Person.cpp1037
-rw-r--r--Source/Person.h149
-rw-r--r--Source/PhysicsMath.h1431
-rw-r--r--Source/Quaternions.cpp745
-rw-r--r--Source/Quaternions.h87
-rw-r--r--Source/Skeleton.cpp841
-rw-r--r--Source/Skeleton.h149
-rw-r--r--Source/Sprites.cpp499
-rw-r--r--Source/Sprites.h91
-rw-r--r--Source/TGALoader.cpp83
-rw-r--r--Source/TGALoader.h29
-rw-r--r--Source/Text.cpp92
-rw-r--r--Source/Text.h29
-rw-r--r--Source/Timer.cpp26
-rw-r--r--Source/Timer.h17
43 files changed, 18741 insertions, 0 deletions
diff --git a/Source/AGL_DSp.cpp b/Source/AGL_DSp.cpp
new file mode 100644
index 0000000..eace870
--- /dev/null
+++ b/Source/AGL_DSp.cpp
@@ -0,0 +1,242 @@
+/**> HEADER FILES <**/
+#include "AGL_DSp.h"
+#include "Alerts.h"
+
+
+/**> GLOBAL VARIABLES <**/
+DSpContextAttributes gDSpContextAttributes; // Global DrawSprocket context attributes
+DSpContextReference gDSpContext; // The global DrawSprocket context
+AGLContext gOpenGLContext; // The global OpenGL (AGL) context
+
+
+/********************> ToolboxInit() <*****/
+void ToolboxInit( void )
+{
+
+ MaxApplZone();
+
+ InitGraf( &qd.thePort );
+ InitFonts();
+ InitWindows();
+ InitMenus();
+ TEInit();
+ InitDialogs( 0L );
+ InitCursor();
+
+}
+
+/********************> HasAppearance() <*****/
+Boolean HasAppearance( void )
+{
+
+ OSErr error;
+ SInt32 response;
+ Boolean appearancePresent = false;
+ Boolean appearance101present = false;
+ Boolean appearance110present = false;
+ Boolean inCompatibilityMode = false;
+
+ error = Gestalt( gestaltAppearanceAttr, &response );
+
+ // If Gestalt returns no error and the bit in response represented by the constant
+ // gestaltAppearanceExists is set, proceed, otherwise exit with an error message.
+
+ if ( error == noErr && ( BitTst( &response, 31 - gestaltAppearanceExists ) ) )
+ {
+ // At least Version 1.0 is present. Set a flag.
+ appearancePresent = true;
+
+ // If the bit in response represented by the constant gestaltAppearanceCompatMode
+ // is set, system-wide Appearance is off. The result of this check will be
+ // relevant only where Versions 1.0 through 1.0.3 are present.
+ if( BitTst( &response, 31 - gestaltAppearanceCompatMode ) )
+ inCompatibilityMode = true;
+
+ // Call Gestalt again with the gestaltAppearanceVersion selector.
+ Gestalt( gestaltAppearanceVersion, &response );
+
+ // If the low order word in response is 0x0101, Version 1.0.1, 1.0.2, or 1.0.3 is
+ // present. If the low order word in response is 0x0110, Version 1.1 is available.
+ if( response == 0x00000101 )
+ appearance101present = true;
+ else if( response == 0x00000110 )
+ appearance110present = true;
+ }
+ /*else
+ {
+ StopAlert( kNoAppearanceAlert, nil );
+ ExitToShell();
+ }*/
+
+ // Register this app as an Appearance Client
+ //RegisterAppearanceClient();
+
+ return appearancePresent;
+
+}
+
+/********************> SetupScreen() <*****/
+CGrafPtr SetupScreen( int width, int height )
+{
+
+ OSStatus theError;
+ CGrafPtr theFrontBuffer;
+
+ // Start DrawSprocket
+ theError = DSpStartup();
+ if( theError )
+ FatalErrorAlert( kErr_DSpStartupFailed, theError );
+
+ // Set the Context Attributes
+ gDSpContextAttributes.displayWidth = width;
+ gDSpContextAttributes.displayHeight = height;
+ gDSpContextAttributes.colorNeeds = kDSpColorNeeds_Require;
+ gDSpContextAttributes.displayDepthMask = kDSpDepthMask_32;
+ gDSpContextAttributes.backBufferDepthMask = kDSpDepthMask_32;
+ gDSpContextAttributes.displayBestDepth = 32;
+ gDSpContextAttributes.backBufferBestDepth = 32;
+ gDSpContextAttributes.pageCount = 1;
+
+ // Find the best context for our attributes
+ theError = DSpFindBestContext( &gDSpContextAttributes, &gDSpContext );
+ if( theError != noErr )
+ FatalErrorAlert( kErr_DSpFindBestContextFailed, theError ); // This function is in my Alerts.cpp
+
+ // Reserve that context
+ theError = DSpContext_Reserve( gDSpContext, &gDSpContextAttributes );
+ if( theError != noErr )
+ FatalErrorAlert( kErr_DSpContext_ReserveFailed, theError );
+
+ // Fade out
+ theError = DSpContext_FadeGammaOut( NULL, NULL );
+ if( theError != noErr )
+ FatalErrorAlert( kErr_DSpFadeFailed, theError );
+
+ // Activate the context
+ theError = DSpContext_SetState( gDSpContext, kDSpContextState_Active );
+ if( theError != noErr )
+ {
+ // Fade back in the display before dying
+ theError = DSpContext_FadeGammaIn( NULL, NULL );
+
+ // Now do the fatal error alert
+ FatalErrorAlert( kErr_ActivateContextFailed, theError );
+ }
+
+ // Fade in
+ theError = DSpContext_FadeGammaIn( NULL, NULL );
+ if( theError != noErr )
+ FatalErrorAlert( kErr_DSpFadeFailed, theError );
+
+ // Create a window to draw in
+ CreateWindow( theFrontBuffer, width, height );
+
+ return theFrontBuffer;
+
+}
+
+/********************> CreateWindow() <*****/
+void CreateWindow( CGrafPtr &theFrontBuffer, int width, int height )
+{
+
+ Rect rect;
+ AuxWinHandle awh;
+ CTabHandle theColorTable;
+ OSErr error;
+ RGBColor backColor = { 0xFFFF, 0xFFFF, 0xFFFF };
+ RGBColor foreColor = { 0x0000, 0x0000, 0x0000 };
+
+ // Set the window rect
+ rect.top = rect.left = 0;
+ DSpContext_LocalToGlobal( gDSpContext, ( Point* )&rect );
+ rect.right = rect.left + width;
+ rect.bottom = rect.top + height;
+
+ // Create a new color window
+ theFrontBuffer = ( CGrafPtr )NewCWindow( NULL, &rect, "\p", 0, plainDBox, kMoveToFront, 0, 0 );
+
+ // set the content color of the window to black to avoid a white flash when the window appears.
+ if ( GetAuxWin( ( WindowPtr )theFrontBuffer, &awh ) )
+ {
+ theColorTable = ( **awh ).awCTable;
+ error = HandToHand( ( Handle* )&theColorTable );
+ if ( error )
+ DebugStr( "\pOut of memory!" );
+
+ ( **theColorTable ).ctTable[wContentColor].rgb.red = 0;
+ ( **theColorTable ).ctTable[wContentColor].rgb.green = 0;
+ ( **theColorTable ).ctTable[wContentColor].rgb.blue = 0;
+
+ CTabChanged( theColorTable );
+
+ // the color table will be disposed by the window manager when the window is disposed
+ SetWinColor( ( WindowPtr )theFrontBuffer, ( WCTabHandle )theColorTable );
+ }
+
+ // Show the window
+ ShowWindow( ( GrafPtr )theFrontBuffer );
+ SetPort( ( GrafPtr )theFrontBuffer );
+
+ // Set current pen colors
+ RGBForeColor( &foreColor );
+ RGBBackColor( &backColor );
+
+}
+
+/********************> ShutdownScreen() <*****/
+void ShutdownScreen( CGrafPtr theFrontBuffer )
+{
+
+ DSpContext_FadeGammaOut( NULL, NULL );
+ DisposeWindow( ( WindowPtr )theFrontBuffer );
+ DSpContext_SetState( gDSpContext, kDSpContextState_Inactive );
+ DSpContext_FadeGammaIn( NULL, NULL );
+ DSpContext_Release( gDSpContext );
+ DSpShutdown();
+
+}
+
+/********************> SetupAGL() <*****/
+AGLContext SetupAGL( AGLDrawable window )
+{
+ GLint attrib[] = { AGL_RGBA, AGL_DEPTH_SIZE, 24, AGL_DOUBLEBUFFER, AGL_NONE };
+ AGLPixelFormat format;
+ AGLContext context;
+ GLboolean ok;
+
+ // Choose an rgb pixel format
+ format = aglChoosePixelFormat( NULL, 0, attrib );
+ if ( format == NULL )
+ return NULL;
+
+ // Create an AGL context
+ context = aglCreateContext( format, NULL );
+ if ( context == NULL )
+ return NULL;
+
+ // Attach the window to the context
+ ok = aglSetDrawable( context, window );
+ if ( !ok )
+ return NULL;
+
+ // Make the context the current context
+ ok = aglSetCurrentContext( context );
+ if ( !ok )
+ return NULL;
+
+ // The pixel format is no longer needed so get rid of it
+ aglDestroyPixelFormat( format );
+
+ return context;
+
+}
+
+/********************> CleanupAGL() <*****/
+void CleanupAGL( AGLContext context )
+{
+
+ aglSetCurrentContext( NULL );
+ aglSetDrawable( context, NULL );
+ aglDestroyContext( context );
+
+}
diff --git a/Source/AGL_DSp.h b/Source/AGL_DSp.h
new file mode 100644
index 0000000..4c1d531
--- /dev/null
+++ b/Source/AGL_DSp.h
@@ -0,0 +1,41 @@
+#pragma once
+
+#ifndef _AGL_DSP_H_
+#define _AGL_DSP_H_
+
+
+/**> HEADER FILES <**/
+#include <stdlib.h> // ANSI C cross platform headers
+#include <stdio.h>
+#include <DrawSprocket.h> // DrawSprocket
+#include <agl.h> // Apple's OpenGL
+#include <glu.h> // Used for setting perspective and making objects
+#include <tk.h> // Used for loading images
+
+
+/**> CONSTANT DECLARATIONS <**/
+#define kMoveToFront kFirstWindowOfClass
+
+// Screen Dimensions
+#define SCREEN_WIDTH 640
+#define SCREEN_HEIGHT 480
+
+
+/**> GLOBAL VARIABLES <**/
+extern DSpContextAttributes gDSpContextAttributes; // Global DrawSprocket context attributes
+extern DSpContextReference gDSpContext; // The global DrawSprocket context
+extern AGLContext gOpenGLContext; // The global OpenGL (AGL) context
+ // Note: These are actually defined in AGL_DSp.cpp
+
+
+/**> FUNCTION PROTOTYPES <**/
+void ToolboxInit( void );
+Boolean HasAppearance( void );
+CGrafPtr SetupScreen( int width, int height );
+void CreateWindow( CGrafPtr &theFrontBuffer, int width, int height );
+void ShutdownScreen( CGrafPtr theFrontBuffer );
+AGLContext SetupAGL( AGLDrawable window );
+void CleanupAGL( AGLContext context );
+
+
+#endif \ No newline at end of file
diff --git a/Source/Alerts.cpp b/Source/Alerts.cpp
new file mode 100644
index 0000000..acfefae
--- /dev/null
+++ b/Source/Alerts.cpp
@@ -0,0 +1,93 @@
+/**> HEADER FILES <**/
+#include "Alerts.h"
+
+
+/********************> SelectResolution() <*****/
+int SelectResolution( void )
+{
+
+ DialogPtr dialog;
+ Boolean dialogDone = false;
+ short itemHit, itemType;
+ Handle okItem;
+ Handle resolutionItem;
+ Rect itemRect;
+ int selectionNum;
+
+ // Load the dialog
+ dialog = GetNewDialog( kResID_DLOG_SelectResolution, nil, kMoveToFront );
+
+ // Display the dialog
+ ShowWindow( dialog );
+ SetPort( dialog );
+
+ // Load dialog items
+ SetDialogDefaultItem( dialog, iOK );
+ SetDialogTracksCursor( dialog, true );
+ GetDialogItem( dialog, iOK, &itemType, &okItem, &itemRect );
+ GetDialogItem( dialog, iResolutionPopUp, &itemType, &resolutionItem, &itemRect );
+
+ // Set item values
+ SetControlValue( ( ControlHandle )resolutionItem, i640x480 );
+
+
+ while ( !dialogDone )
+ {
+
+ ModalDialog( nil, &itemHit );
+
+ switch( itemHit )
+ {
+ case iOK:
+ dialogDone = true;
+ // Get the item number selected int the popup
+ selectionNum = GetControlValue( ( ControlHandle )resolutionItem );
+ break;
+ case iResolutionPopUp:
+ // We don't actually need to do anything here
+ break;
+ }
+
+ }
+
+ DisposeDialog( dialog );
+
+ // Return the item selected in the popup menu
+ return selectionNum;
+}
+
+/********************> MessageAlert() <*****/
+void MessageAlert( unsigned char *theMessage )
+{
+
+ // Set parameter ^0 to our message (I could set up to three, but for simplicity's sake I won't)
+ ParamText( ( unsigned char * )theMessage, NULL, NULL, NULL );
+
+ // Do the Alert
+ NoteAlert( kResID_ALRT_MessageAlert, nil );
+
+}
+
+/********************> FatalErrorAlert() <*****/
+void FatalErrorAlert( UInt16 errorNum, OSErr osError )
+{
+
+ Str15 errNumStr;
+ Str255 mainMessage;
+
+ // Convert the OSErr to a string
+ NumToString( osError, errNumStr );
+
+ // Get the error description (inErrorDesc) from the STR# resource
+ GetIndString( mainMessage, kResID_STRn_ErrorStrings, errorNum );
+
+ // Set the parameters (^0 and ^1) in the ALRT to our error messages
+ ParamText( mainMessage, errNumStr, NULL, NULL );
+
+ // Do the alert (which now has our messages in it)
+ StopAlert( kResID_ALRT_ErrorAlert, NULL );
+
+ // Quit
+ exit( EXIT_SUCCESS );
+
+}
diff --git a/Source/Alerts.h b/Source/Alerts.h
new file mode 100644
index 0000000..5db7938
--- /dev/null
+++ b/Source/Alerts.h
@@ -0,0 +1,44 @@
+#ifndef _MYALERTS_H_
+#define _MYALERTS_H_
+
+
+/**> HEADER FILES <**/
+#include <string.h>
+#include <stdlib.h>
+
+
+/**> CONSTANT DECLARATIONS <**/
+#define kMoveToFront kFirstWindowOfClass
+// Alerts
+#define kResID_ALRT_MessageAlert 128
+#define kResID_ALRT_ErrorAlert 129
+// Dialogs
+#define kResID_DLOG_SelectResolution 130
+#define iOK 1
+#define iResolutionPopUp 2
+// Menus
+#define mResolution 128
+#define i640x480 1
+#define i800x600 2
+#define i1024x768 3
+// String resources
+#define kResID_STRn_ErrorStrings 128
+// Misc
+#define kInsignificantConstant7454955 0
+
+// Error numbers
+#define kErr_DSpFindBestContextFailed 1
+#define kErr_DSpContext_ReserveFailed 2
+#define kErr_ActivateContextFailed 3
+#define kErr_DSpStartupFailed 4
+#define kErr_DSpFadeFailed 5
+#define kErr_AGLContext_CreationFailed 6
+
+
+/**> FUNCTION PROTOTYPES <**/
+int SelectResolution( void );
+void MessageAlert( unsigned char *theMessage );
+void FatalErrorAlert( UInt16 errorNum, OSErr osError );
+
+
+#endif \ No newline at end of file
diff --git a/Source/Camera.cpp b/Source/Camera.cpp
new file mode 100644
index 0000000..e5633a9
--- /dev/null
+++ b/Source/Camera.cpp
@@ -0,0 +1,8 @@
+/**> HEADER FILES <**/
+#include "Camera.h"
+
+
+void Camera::Apply()
+{
+ glTranslatef(-position.x,-position.y,-position.z);
+} \ No newline at end of file
diff --git a/Source/Camera.h b/Source/Camera.h
new file mode 100644
index 0000000..7f1d437
--- /dev/null
+++ b/Source/Camera.h
@@ -0,0 +1,23 @@
+#ifndef _CAMERA_H_
+#define _CAMERA_H_
+
+
+/**> HEADER FILES <**/
+#include <gl.h>
+#include "Quaternions.h"
+
+class Camera
+{
+ public:
+ XYZ position;
+ XYZ oldposition;
+ XYZ targetoffset;
+
+ float rotation, rotation2;
+ float oldrotation, oldrotation2;
+ float oldoldrotation, oldoldrotation2;
+ float visrotation, visrotation2;
+ void Apply();
+};
+
+#endif \ No newline at end of file
diff --git a/Source/Constants.h b/Source/Constants.h
new file mode 100644
index 0000000..1d95ad4
--- /dev/null
+++ b/Source/Constants.h
@@ -0,0 +1,135 @@
+#ifndef _CONSTANTS_H_
+#define _CONSTANTS_H_
+
+#define max_joints 50
+#define max_frames 50
+#define max_muscles 100
+#define gravity -25
+
+#define bullethole 0
+#define crater 1
+#define bloodpool 2
+
+#define idleanim 0
+#define joganim 1
+#define pistolaimanim 2
+#define walkanim 3
+#define rifleholdanim 4
+#define rifleaimanim 5
+#define assaultrifleaimanim 6
+#define crouchanim 7
+#define headpainanim 8
+#define chestpainanim 9
+#define stomachpainanim 10
+#define rightarmpainanim 11
+#define leftarmpainanim 12
+#define rightlegpainanim 13
+#define leftlegpainanim 14
+#define riflehitanim 15
+#define grenadeaimanim 16
+#define grenadechargeanim 17
+#define grenadethrowanim 18
+#define zombieeatanim 19
+#define zombiejoganim 20
+#define zombiewalkanim 21
+#define getupfrontanim 22
+#define getupbackanim 23
+#define lyinganim 24
+#define diveanim 25
+#define throwanim 26
+#define thrownanim 27
+
+#define nogun 0
+#define sniperrifle 1
+#define assaultrifle 2
+#define handgun1 3
+#define handgun2 4
+#define grenade 5
+#define knife 6
+#define shotgun 7
+
+#define sniperriflemodel 0
+#define assaultriflemodel 1
+#define handgunbasemodel 2
+#define handgunslidemodel 3
+#define handgun2basemodel 4
+#define handgun2slidemodel 5
+#define grenadebasemodel 6
+#define grenadepinmodel 7
+#define grenadespoonmodel 8
+#define knifemodel 9
+#define shotgunmodel 10
+
+#define visionsound 0
+#define soulinsound 1
+#define souloutsound 2
+#define footstepsound 3
+#define bodylandsound 8
+#define headlandsound 9
+#define riflesound 10
+#define bodyhitsound 11
+#define wallhitsound 12
+#define machinegunsound 13
+#define nearbulletsound 14
+#define headwhacksound 15
+#define headshotsound 16
+#define reloadsound 17
+#define clicksound 18
+#define pistol1sound 19
+#define pistol2sound 20
+#define pinpullsound 21
+#define pinreplacesound 22
+#define grenadethrowsound 23
+#define bouncesound 24
+#define bounce2sound 25
+#define explosionsound 26
+#define bodywhacksound 27
+#define rainsound 28
+#define losesound 29
+#define disguisekillsound 30
+#define knifeslashsound 31
+#define shotgunsound 32
+#define mainmenusong 33
+#define shootsong 34
+#define knifesong 35
+#define zombiesong 36
+
+#define sunny_environment 0
+#define foggy_environment 1
+#define snowy_environment 2
+#define rainy_environment 3
+#define firey_environment 4
+#define night_environment 5
+
+#define randomshoot_type 0
+#define zombie_type 1
+#define soldiers_type 2
+#define snipers_type 3
+#define stabber_type 4
+
+#define shotdelayamount 3
+
+#define fleshtone1 240/255
+#define fleshtone2 183/255
+#define fleshtone3 132/255
+
+#define headmodel 0
+#define chestmodel 1
+#define abdomenmodel 2
+#define upperarmmodel 3
+#define lowerarmmodel 4
+#define handmodel 5
+#define upperlegmodel 6
+#define lowerlegmodel 7
+#define footmodel 8
+
+#define policecostume 0
+#define bodyguardcostume 1
+#define casualcostumes 2
+#define vipcostume 6
+
+#define numcasual 4
+
+#define soundscalefactordefault 10
+
+#endif \ No newline at end of file
diff --git a/Source/Decals.cpp b/Source/Decals.cpp
new file mode 100644
index 0000000..075f69b
--- /dev/null
+++ b/Source/Decals.cpp
@@ -0,0 +1,445 @@
+#include "Decals.h"
+
+extern double multiplier;
+extern bool slomo;
+extern Fog fog;
+extern bool blood;
+extern float fogcolorr;
+extern float fogcolorg;
+extern float fogcolorb;
+//Functions
+extern float sinefluct;
+extern int environment;
+extern Model gunmodels[10];
+extern Camera camera;
+extern float precipitationhorz;
+extern float precipitationvert;
+extern float precipitationdensity;
+extern float snowdelay;
+
+int Decals::MakeDecal(int atype, XYZ location, float size, XYZ normal, int poly, Model *model, XYZ move, float rotation){
+ int major=0;
+ float normalv[3];
+ XYZ right;
+ XYZ up;
+ XYZ nothing;
+ XYZ axis[3];
+ XYZ temp;
+
+ nothing=0;
+
+ axis[0].x=1;
+ axis[1].y=1;
+ axis[2].z=1;
+
+ normalv[0]=abs(normal.x);
+ normalv[1]=abs(normal.y);
+ normalv[2]=abs(normal.z);
+
+
+ if(normalv[1]>normalv[major])major=1;
+ if(normalv[2]>normalv[major])major=2;
+
+ if (normalv[0] == 1 || normalv[1] == 1 || normalv[2] == 1)
+ {
+ if ((major == 0 && normal.x > 0) || major == 1){
+ right=0;
+ right.z=-1;}
+ else if (major == 0){
+ right=0;
+ right.z=1;}
+ else {
+ right=0;
+ right.x=normal.z;}
+ }
+ else
+ CrossProduct(axis[major], normal, &right);
+
+ CrossProduct(normal, right, &up);
+ Normalise(&up);
+ Normalise(&right);
+
+ float count;
+ float count2;
+ float countinc=1/size;
+ if(countinc<.01)countinc=.01;
+ if(countinc>.2)countinc=.2;
+ float normaloffset=.02;
+ int good;
+
+ numpoints[howmanydecals]=0;
+ points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right - up) * (size/3) /*+ normal/100*/;
+ texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 0;
+ texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 0;
+ if((move.x==0&&move.z==0&&rotation==0)||
+ LineFacetd(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25, model->vertex[model->Triangles[poly].vertex[0]], model->vertex[model->Triangles[poly].vertex[1]], model->vertex[model->Triangles[poly].vertex[2]],normal,&temp)
+ )numpoints[howmanydecals]++;
+ else {
+ good=-1;
+ count=1-countinc;
+ while(good==-1&&count>-1){
+ texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 0;
+ texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2;
+ points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right - up*count) * (size/3);
+ count-=countinc;
+ good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
+ }
+ if(good!=-1)numpoints[howmanydecals]++;
+ good=-1;
+ count=1-countinc;
+ while(good==-1&&count>-1){
+ texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2;
+ texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 0;
+ points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right*count - up) * (size/3);
+ count-=countinc;
+ good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
+ }
+ if(good!=-1)numpoints[howmanydecals]++;
+ if(good==-1){
+ good=-1;
+ count2=1-countinc;
+ while(good==-1&&count2>-1){
+ count=1-countinc;
+ while(good==-1&&count>-1){
+ texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5-count2/2;
+ texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2;
+ points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right*count2 - up*count) * (size/3);
+ count-=countinc;
+ good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
+ }
+ count2-=countinc;
+ }
+ if(good!=-1)numpoints[howmanydecals]++;
+ }
+ }
+
+ points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right - up) * (size/3) /*+ normal/100*/;
+ texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 1;
+ texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 0;
+ if((move.x==0&&move.y==0&&move.z==0&&rotation==0)||
+ LineFacetd(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25, model->vertex[model->Triangles[poly].vertex[0]], model->vertex[model->Triangles[poly].vertex[1]], model->vertex[model->Triangles[poly].vertex[2]],normal,&temp)
+ )numpoints[howmanydecals]++;
+ else {
+ good=-1;
+ count=1-countinc;
+ while(good==-1&&count>-1){
+ texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2;
+ texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 0;
+ points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right*count - up) * (size/3);
+ count-=countinc;
+ good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
+ }
+ if(good!=-1)numpoints[howmanydecals]++;
+ good=-1;
+ count=1-countinc;
+ while(good==-1&&count>-1){
+ texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 1;
+ texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2;
+ points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right - up*count) * (size/3);
+ count-=countinc;
+ good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
+ }
+ if(good!=-1)numpoints[howmanydecals]++;
+ if(good==-1){
+ good=-1;
+ count2=1-countinc;
+ while(good==-1&&count2>-1){
+ count=1-countinc;
+ while(good==-1&&count>-1){
+ texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5+count2/2;
+ texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2;
+ points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right*count2 - up*count) * (size/3);
+ count-=countinc;
+ good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
+ }
+ count2-=countinc;
+ }
+ if(good!=-1)numpoints[howmanydecals]++;
+ }
+ }
+
+ points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right + up) * (size/3) /*+ normal/100*/;
+ texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 1;
+ texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 1;
+ if((move.x==0&&move.y==0&&move.z==0&&rotation==0)||
+ LineFacetd(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25, model->vertex[model->Triangles[poly].vertex[0]], model->vertex[model->Triangles[poly].vertex[1]], model->vertex[model->Triangles[poly].vertex[2]],normal,&temp)
+ )numpoints[howmanydecals]++;
+ else {
+ good=-1;
+ count=1-countinc;
+ while(good==-1&&count>-1){
+ texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 1;
+ texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2;
+ points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right + up*count) * (size/3);
+ count-=countinc;
+ good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
+ }
+ if(good!=-1)numpoints[howmanydecals]++;
+ good=-1;
+ count=1-countinc;
+ while(good==-1&&count>-1){
+ texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2;
+ texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 1;
+ points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right*count + up) * (size/3);
+ count-=countinc;
+ good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
+ }
+ if(good!=-1)numpoints[howmanydecals]++;
+ if(good==-1){
+ good=-1;
+ count2=1-countinc;
+ while(good==-1&&count2>-1){
+ count=1-countinc;
+ while(good==-1&&count>-1){
+ texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5+count2/2;
+ texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2;
+ points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing + right*count2 + up*count) * (size/3);
+ count-=countinc;
+ good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
+ }
+ count2-=countinc;
+ }
+ if(good!=-1)numpoints[howmanydecals]++;
+ }
+ }
+
+ points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right + up) * (size/3) /*+ normal/100*/;
+ texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 0;
+ texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 1;
+ if((move.x==0&&move.y==0&&move.z==0&&rotation==0)||
+ LineFacetd(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25, model->vertex[model->Triangles[poly].vertex[0]], model->vertex[model->Triangles[poly].vertex[1]], model->vertex[model->Triangles[poly].vertex[2]],normal,&temp)
+ )numpoints[howmanydecals]++;
+ else {
+ good=-1;
+ count=1-countinc;
+ while(good==-1&&count>-1){
+ texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5-count/2;
+ texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = 1;
+ points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right*count + up) * (size/3);
+ count-=countinc;
+ good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
+ }
+ if(good!=-1)numpoints[howmanydecals]++;
+ good=-1;
+ count=1-countinc;
+ while(good==-1&&count>-1){
+ texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = 0;
+ texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2;
+ points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right + up*count) * (size/3);
+ count-=countinc;
+ good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
+ }
+ if(good!=-1)numpoints[howmanydecals]++;
+ if(good==-1){
+ good=-1;
+ count2=1-countinc;
+ while(good==-1&&count2>-1){
+ count=1-countinc;
+ while(good==-1&&count>-1){
+ texcoordsx[howmanydecals*8+numpoints[howmanydecals]] = .5-count2/2;
+ texcoordsy[howmanydecals*8+numpoints[howmanydecals]] = .5+count/2;
+ points[howmanydecals*8+numpoints[howmanydecals]] = location + (nothing - right*count2 + up*count) * (size/3);
+ count-=countinc;
+ good=model->LineCheck2(points[howmanydecals*8+numpoints[howmanydecals]]+normal/25,points[howmanydecals*8+numpoints[howmanydecals]]-normal/25,&temp,move,rotation);
+ }
+ count2-=countinc;
+ }
+ if(good!=-1)numpoints[howmanydecals]++;
+ }
+ }
+ for(int i=0;i<numpoints[howmanydecals];i++){
+ points[howmanydecals*8+i] += normal*normaloffset;
+ }
+
+ type[howmanydecals]=atype;
+ alivetime[howmanydecals]=0;
+ if(howmanydecals<maxdecals){howmanydecals++;}
+}
+
+int Decals::DeleteDecal(int which){
+ if(which>=0){
+ numpoints[which]=numpoints[howmanydecals-1];
+ alivetime[which]=alivetime[howmanydecals-1];
+ type[which]=type[howmanydecals-1];
+ for(int i=0;i<numpoints[which];i++){
+ points[which*8+i] = points[howmanydecals*8-8+i];
+ texcoordsx[which*8+i] = texcoordsx[howmanydecals*8-8+i];
+ texcoordsy[which*8+i] = texcoordsy[howmanydecals*8-8+i];
+ }
+ if(howmanydecals>0){howmanydecals--;}
+ }
+}
+
+void Decals::LoadBulletHoleTexture(char *fileName)
+{
+ TGAImageRec *tempTexture;
+ GLuint type;
+
+ //Load Image
+ tempTexture = LoadTGA( fileName );
+ //Is it valid?
+ if(tempTexture){
+ //Alpha channel?
+ if ( tempTexture->bpp == 24 )
+ type = GL_RGB;
+ else
+ type = GL_RGBA;
+
+ glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
+
+ glGenTextures( 1, &bulletholetextureptr );
+ glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+
+ glBindTexture( GL_TEXTURE_2D, bulletholetextureptr);
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+
+ gluBuild2DMipmaps( GL_TEXTURE_2D, type, tempTexture->sizeX, tempTexture->sizeY, type, GL_UNSIGNED_BYTE, tempTexture->data );
+ free( tempTexture->data );
+ free( tempTexture );
+ }
+}
+
+void Decals::LoadBloodTexture(char *fileName, int which)
+{
+ TGAImageRec *tempTexture;
+ GLuint type;
+
+ //Load Image
+ tempTexture = LoadTGA( fileName );
+ //Is it valid?
+ if(tempTexture){
+ //Alpha channel?
+ if ( tempTexture->bpp == 24 )
+ type = GL_RGB;
+ else
+ type = GL_RGBA;
+
+ glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
+
+ glGenTextures( 1, &bloodtextureptr[which] );
+ glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+
+ glBindTexture( GL_TEXTURE_2D, bloodtextureptr[which]);
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+
+ gluBuild2DMipmaps( GL_TEXTURE_2D, type, tempTexture->sizeX, tempTexture->sizeY, type, GL_UNSIGNED_BYTE, tempTexture->data );
+ free( tempTexture->data );
+ free( tempTexture );
+ }
+}
+
+void Decals::LoadCraterTexture(char *fileName)
+{
+ TGAImageRec *tempTexture;
+ GLuint type;
+
+ //Load Image
+ tempTexture = LoadTGA( fileName );
+ //Is it valid?
+ if(tempTexture){
+ //Alpha channel?
+ if ( tempTexture->bpp == 24 )
+ type = GL_RGB;
+ else
+ type = GL_RGBA;
+
+ glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
+
+ glGenTextures( 1, &cratertextureptr );
+ glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+
+ glBindTexture( GL_TEXTURE_2D, cratertextureptr);
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+
+ gluBuild2DMipmaps( GL_TEXTURE_2D, type, tempTexture->sizeX, tempTexture->sizeY, type, GL_UNSIGNED_BYTE, tempTexture->data );
+ free( tempTexture->data );
+ free( tempTexture );
+ }
+}
+
+void Decals::DoStuff()
+{
+ for(int i=0;i<howmanydecals;i++){
+ alivetime[i]+=multiplier;
+ if(alivetime[i]>10&&(type[i]==bullethole||type[i]==crater))DeleteDecal(i);
+ if(alivetime[i]>20&&(type[i]==bloodpool))DeleteDecal(i);
+ }
+}
+
+void Decals::draw()
+{
+ glAlphaFunc(GL_GREATER, 0.01);
+
+ float bloodpoolspeed=1;
+
+ glDepthFunc(GL_LEQUAL);
+ glEnable(GL_BLEND);
+ glEnable(GL_CULL_FACE);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_LIGHTING);
+ glDepthMask(0);
+ glAlphaFunc(GL_GREATER, 0.01);
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_POLYGON_OFFSET_FILL);
+ for(int i=0;i<howmanydecals;i++){
+ if(type[i]==bullethole)glBindTexture(GL_TEXTURE_2D, bulletholetextureptr);
+ if(type[i]==crater)glBindTexture(GL_TEXTURE_2D, cratertextureptr);
+ if(type[i]!=bloodpool)glColor4f(1,1,1,10-alivetime[i]);
+
+ if(type[i]==bloodpool&&alivetime[i]<bloodpoolspeed*.2)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[0]);
+ if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.2&&alivetime[i]<bloodpoolspeed*.4)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[1]);
+ if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.4&&alivetime[i]<bloodpoolspeed*.6)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[2]);
+ if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.6&&alivetime[i]<bloodpoolspeed*.8)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[3]);
+ if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.8&&alivetime[i]<bloodpoolspeed*1)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[4]);
+ if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1&&alivetime[i]<bloodpoolspeed*1.2)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[5]);
+ if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.2&&alivetime[i]<bloodpoolspeed*1.4)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[6]);
+ if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.4&&alivetime[i]<bloodpoolspeed*1.6)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[7]);
+ if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.6&&alivetime[i]<bloodpoolspeed*1.8)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[8]);
+ if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.8&&alivetime[i]<bloodpoolspeed*2.0)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[9]);
+ if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*2.0)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[10]);
+ if(type[i]==bloodpool&&alivetime[i]<bloodpoolspeed*2.0)glColor4f(1,1,1,1.5-(alivetime[i]*5/bloodpoolspeed-(int)(alivetime[i]*5/bloodpoolspeed)));
+ if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*2.0)glColor4f(1,1,1,20-alivetime[i]);
+
+ glPushMatrix();
+ glBegin(GL_TRIANGLE_FAN);
+ for(int j=0;j<numpoints[i];j++){
+ glTexCoord2f(texcoordsx[i*8+j], texcoordsy[i*8+j]); glVertex3f(points[i*8+j].x,points[i*8+j].y,points[i*8+j].z);
+ }
+ glEnd();
+ glPopMatrix();
+
+ if(type[i]==bloodpool&&alivetime[i]<bloodpoolspeed*2.0){
+ if(type[i]==bloodpool&&alivetime[i]<bloodpoolspeed*.2)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[1]);
+ if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.2&&alivetime[i]<bloodpoolspeed*.4)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[2]);
+ if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.4&&alivetime[i]<bloodpoolspeed*.6)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[3]);
+ if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.6&&alivetime[i]<bloodpoolspeed*.8)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[4]);
+ if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*.8&&alivetime[i]<bloodpoolspeed*1)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[5]);
+ if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1&&alivetime[i]<bloodpoolspeed*1.2)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[6]);
+ if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.2&&alivetime[i]<bloodpoolspeed*1.4)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[7]);
+ if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.4&&alivetime[i]<bloodpoolspeed*1.6)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[8]);
+ if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.6&&alivetime[i]<bloodpoolspeed*1.8)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[9]);
+ if(type[i]==bloodpool&&alivetime[i]>=bloodpoolspeed*1.8&&alivetime[i]<bloodpoolspeed*2.0)glBindTexture(GL_TEXTURE_2D, bloodtextureptr[10]);
+ if(type[i]==bloodpool)glColor4f(1,1,1,alivetime[i]*5/bloodpoolspeed-(int)(alivetime[i]*5/bloodpoolspeed));
+
+ glPushMatrix();
+ glBegin(GL_TRIANGLE_FAN);
+ for(int j=0;j<numpoints[i];j++){
+ glTexCoord2f(texcoordsx[i*8+j], texcoordsy[i*8+j]); glVertex3f(points[i*8+j].x,points[i*8+j].y,points[i*8+j].z);
+ }
+ glEnd();
+ glPopMatrix();
+ }
+ }
+ glDepthMask(1);
+ glDisable(GL_TEXTURE_2D);
+ glColor4f(1,1,1,1);
+ glEnable(GL_CULL_FACE);
+ glDisable(GL_POLYGON_OFFSET_FILL);
+ glDepthFunc(GL_LEQUAL);
+}
+
diff --git a/Source/Decals.h b/Source/Decals.h
new file mode 100644
index 0000000..bfd0738
--- /dev/null
+++ b/Source/Decals.h
@@ -0,0 +1,54 @@
+#ifndef _DECALS_H_
+#define _DECALS_H_
+
+#include "Quaternions.h"
+#include <gl.h>
+#include <glu.h>
+#include "Files.h"
+#include "TGALoader.h"
+#include "Quaternions.h"
+#include "gl.h"
+#include "glut.h"
+#include "Camera.h"
+#include "Models.h"
+#include "Fog.h"
+//
+// Model Structures
+//
+
+#define maxdecals 120
+
+class Decals{
+ public:
+ GLuint bulletholetextureptr;
+ GLuint cratertextureptr;
+ GLuint bloodtextureptr[11];
+
+ int howmanydecals;
+
+ int type[maxdecals];
+
+ XYZ points[8*maxdecals];
+ int numpoints[maxdecals];
+ float texcoordsx[8*maxdecals];
+ float texcoordsy[8*maxdecals];
+ float alivetime[maxdecals];
+
+ void draw();
+
+ int DeleteDecal(int which);
+ int MakeDecal(int atype, XYZ location, float size, XYZ normal, int poly, Model *model, XYZ move, float rotation);
+
+ void DoStuff();
+ void LoadBulletHoleTexture(char *fileName);
+ void LoadCraterTexture(char *fileName);
+ void LoadBloodTexture(char *fileName, int which);
+
+ Decals() {
+ glDeleteTextures( 1, (const unsigned long *)bulletholetextureptr );
+ glDeleteTextures( 1, (const unsigned long *)cratertextureptr );
+ glDeleteTextures( 11, (const unsigned long *)bloodtextureptr );
+ };
+};
+
+#endif \ No newline at end of file
diff --git a/Source/Files.cpp b/Source/Files.cpp
new file mode 100644
index 0000000..dd55c52
--- /dev/null
+++ b/Source/Files.cpp
@@ -0,0 +1,173 @@
+#include "Files.h"
+
+short Files::OpenFile(Str255 Name)
+{
+ short volume;
+ char filename[33];
+ short tFile;
+ tFile=-1;
+ Point ptOrigin = { 0, 0 };
+ volume = 0;
+ sprintf (filename, "%s", Name);
+ SetVol( nil, volume );
+ CtoPstr( filename );
+ FSOpen( (Pstr) filename, volume,&tFile );
+ PtoCstr( (Pstr) filename );
+ sFile=tFile;
+ return( tFile );
+}
+
+short Files::OpenNewFile( SFReply *psfReply,
+ OSType osTypeCreator,
+ OSType osTypeType )
+{
+ sFile = 0;
+ OSErr osErr;
+
+ SetVol( nil, psfReply->vRefNum );
+ osErr = Create( psfReply->fName, psfReply->vRefNum, osTypeCreator, osTypeType );
+
+ if ( osErr == dupFNErr )
+ {
+ FSDelete( psfReply->fName, psfReply->vRefNum );
+ Create( psfReply->fName, psfReply->vRefNum, osTypeCreator, osTypeType );
+ }
+
+ FSOpen( psfReply->fName, psfReply->vRefNum, &sFile );
+
+ return( sFile );
+}
+
+
+short Files::PromptForSaveAS( short sPromptID,
+ short sNameID,
+ Str255 str255NamePrompt,
+ OSType osTypeCreator,
+ OSType osTypeType,
+ SFReply *psfReply )
+{
+ Str255 str255Prompt;
+ Str255 str255Name;
+ sFile = 0;
+ Point ptOrigin = { 0, 0 };
+
+ GetIndString( str255Prompt, FILE_STRINGS, sPromptID );
+
+ if ( !str255NamePrompt )
+ GetIndString( str255Name, FILE_STRINGS, sNameID );
+
+ else
+ memcpy( str255Name, str255NamePrompt, *str255NamePrompt + 1 );
+
+ SFPutFile( ptOrigin, str255Prompt, str255Name, nil, psfReply );
+
+ if ( psfReply->good )
+ {
+ sFile = OpenNewFile( psfReply, osTypeCreator, osTypeType );
+ }
+
+ return( sFile );
+}
+
+short Files::OpenSavedGame(Str255 Name)
+{
+ Point ptOrigin = { 0, 0 };
+ sSavedGameVolume = 0;
+ sprintf (szSavedGameName, "%s", Name);
+ SetVol( nil, sSavedGameVolume );
+ CtoPstr( szSavedGameName );
+ FSOpen( (Pstr) szSavedGameName, sSavedGameVolume,&sFile );
+ PtoCstr( (Pstr) szSavedGameName );
+ return( sFile );
+}
+
+short Files::OpenFileDialog()
+{
+ Point ptOrigin = { 0, 0 };
+ sFile = 0;
+ SFReply sfReply;
+ SFTypeList sfTypeList = { 'DMAP', '\p', '\p', '\p' };
+ SFGetFile( ptOrigin, "\p", nil, 1, sfTypeList, nil, &sfReply );
+
+ if ( sfReply.good )
+ {
+ PtoCstr( sfReply.fName );
+ strcpy( szSavedGameName, (Cstr) sfReply.fName );
+ }
+
+ if ( sfReply.good )
+ {
+ sSavedGameVolume = sfReply.vRefNum;
+ SetVol( nil, sSavedGameVolume );
+
+ CtoPstr( szSavedGameName );
+
+ FSOpen( (Pstr) szSavedGameName, sSavedGameVolume,&sFile );
+
+ PtoCstr( (Pstr) szSavedGameName );
+ }
+
+ return( sFile );
+}
+
+void Files::StartSave()
+{
+ int x,y;
+ SFReply sfReply;
+ sFile = 0;
+ long lSize;
+ long lLongSize = sizeof( long );
+
+ CtoPstr( szSavedGameName );
+
+ sFile = PromptForSaveAS( SAVE_GAME_STRING, 0, (Pstr)szSavedGameName,'DAVD', 'DMAP', &sfReply );
+
+ PtoCstr((Pstr) szSavedGameName );
+
+ if ( sFile )
+ {
+ sSavedGameVolume = sfReply.vRefNum;
+ PtoCstr( sfReply.fName );
+ strcpy( szSavedGameName, (Cstr)sfReply.fName );
+ }
+
+ else
+ {
+ sfReply.vRefNum = sSavedGameVolume;
+ strcpy( (Cstr) sfReply.fName, szSavedGameName );
+ CtoPstr( (Cstr)sfReply.fName );
+
+ sFile = OpenNewFile( &sfReply, 'GLF2', 'SKLT' );
+ }
+
+}
+
+void Files::EndSave()
+{
+ int x,y;
+ SFReply sfReply;
+ long lSize;
+ long lLongSize = sizeof( long );
+
+ if ( sFile )
+ FSClose( sFile );
+
+}
+
+void Files::StartLoad()
+{
+ Boolean bLoaded = false;
+ long lSize;
+ long lLongSize = sizeof( long );
+
+ int x,y,kl;
+ sFile=OpenFileDialog();
+
+}
+
+void Files::EndLoad()
+{
+
+ if (sFile)
+ FSClose( sFile );
+} \ No newline at end of file
diff --git a/Source/Files.h b/Source/Files.h
new file mode 100644
index 0000000..49572df
--- /dev/null
+++ b/Source/Files.h
@@ -0,0 +1,88 @@
+#ifndef _FILES_H_
+#define _FILES_H_
+
+#include <stdio.h>
+#include <stdlib.h> // Header File For Standard functions
+#include <stdio.h> // Header File For Standard Input/Output
+#include <string.h>
+#include <ctype.h>
+#include "gl.h" // Header File For The OpenGL32 Library
+#include "glu.h" // Header File For The GLu32 Library
+#include "tk.h" // Header File For The Glaux Library
+#include <Sound.h>
+#include <Resources.h>
+#include "AGL_DSp.h" // Header for OpenGL and DrawSprocket Functions
+#include "MacInput.h" // Header for Special Mac Input functions
+#include "Alerts.h" // Header for Dialogs and alerts for this application
+#include <cstdarg>
+#include <math.h>
+#include "glm.h"
+#include <TextUtils.h>
+#include <iostream.h>
+#include <fstream.h>
+
+#define FILE_STRINGS 130
+#define Pstr unsigned char *
+#define Cstr char *
+
+#define FILE_ERROR_ALERT 138
+#define OLD_SAVE_VERSION 139
+#define UNREADABLE_SCORES_ALERT 140
+
+#define SAVE_WARNING_ID 132
+#define PB_SAVE 1
+#define PB_CANCEL 2
+#define PB_DONT_SAVE 3
+
+#define FILE_ERROR_STRINGS 129
+#define FILE_ERROR_PREFIX 1
+#define FILE_ERROR_SUFFIX 2
+
+#define SAVE_WARNING_STRINGS 132
+
+#define FILE_STRINGS 130
+#define SAVE_GAME_STRING 1
+#define SAVE_SCORES_STRING 2
+#define SCORES_NAME_STRING 3
+#define SAVE_JOURNAL_STRING 4
+#define JOURNAL_NAME_STRING 5
+#define UNTITLED_STRING 6
+#define SAVE_FORM_STRING 7
+#define FORM_NAME_STRING 8
+
+#define REGISTRATION_FORM 136
+
+#define FILE_NAME_SIZE 32
+#define ERROR_LENGTH 80
+
+/**> Files Opening <**/
+class Files
+{
+ public:
+ char szSavedGameName[FILE_NAME_SIZE + 1];
+ short sSavedGameVolume;
+ SFReply sfReply;
+ Boolean bGameSaved;
+ short sFile;
+ long lSize;
+
+ short OpenFile(Str255 Name);
+ short PromptForSaveAS( short sPromptID,
+ short sNameID,
+ Str255 str255NamePrompt,
+ OSType osTypeCreator,
+ OSType osTypeType,
+ SFReply *psfReply );
+ short OpenNewFile( SFReply *psfReply, OSType osTypeCreator, OSType osTypeType );
+ short OpenSavedGame(Str255 Name);
+ short OpenFileDialog();
+ void LoadNamedMap(Str255 Name);
+ void LoadGame(Str255 Name, int animnum);
+ void LoadMap();
+ void StartSave();
+ void EndSave();
+ void StartLoad();
+ void EndLoad();
+};
+
+#endif \ No newline at end of file
diff --git a/Source/Fog.cpp b/Source/Fog.cpp
new file mode 100644
index 0000000..af30dfa
--- /dev/null
+++ b/Source/Fog.cpp
@@ -0,0 +1,53 @@
+/**> HEADER FILES <**/
+#include "Fog.h"
+
+void Fog::SetFog(float colorR, float colorG, float colorB, float fStart, float fEnd, float Density)
+{
+ fogColor[0]=colorR;
+ fogColor[1]=colorG;
+ fogColor[2]=colorB;
+ fogColor[3]=1;
+ fogStart=fStart;
+ fogEnd=fEnd;
+ fogDensity=Density;
+ fogMode=GL_LINEAR;
+
+ glFogi(GL_FOG_MODE,fogMode);
+ glFogfv(GL_FOG_COLOR,fogColor);
+ glFogf(GL_FOG_DENSITY,fogDensity);
+ glFogi(GL_FOG_HINT,GL_DONT_CARE);
+ glFogi(GL_FOG_START,fogStart);
+ glFogi(GL_FOG_END,fogEnd);
+
+ glEnable(GL_FOG);
+}
+
+void Fog::TempFog(float colorR, float colorG, float colorB)
+{
+ GLfloat tempfogColor[4];
+ tempfogColor[0]=colorR;
+ tempfogColor[1]=colorG;
+ tempfogColor[2]=colorB;
+ tempfogColor[3]=1;
+
+ glFogi(GL_FOG_MODE,fogMode);
+ glFogfv(GL_FOG_COLOR,tempfogColor);
+ glFogf(GL_FOG_DENSITY,fogDensity);
+ glFogi(GL_FOG_HINT,GL_DONT_CARE);
+ glFogi(GL_FOG_START,fogStart);
+ glFogi(GL_FOG_END,fogEnd);
+
+ glEnable(GL_FOG);
+}
+
+void Fog::ResetFog()
+{
+ glFogi(GL_FOG_MODE,fogMode);
+ glFogfv(GL_FOG_COLOR,fogColor);
+ glFogf(GL_FOG_DENSITY,fogDensity);
+ glFogi(GL_FOG_HINT,GL_DONT_CARE);
+ glFogi(GL_FOG_START,fogStart);
+ glFogi(GL_FOG_END,fogEnd);
+
+ glEnable(GL_FOG);
+} \ No newline at end of file
diff --git a/Source/Fog.h b/Source/Fog.h
new file mode 100644
index 0000000..be55da9
--- /dev/null
+++ b/Source/Fog.h
@@ -0,0 +1,23 @@
+#ifndef _FOG_H_
+#define _FOG_H_
+
+
+/**> HEADER FILES <**/
+#include <gl.h>
+#include "Quaternions.h"
+
+
+class Fog{
+ public:
+ GLfloat fogColor[4];
+ GLint fogMode;
+ GLfloat fogDensity;
+ GLfloat fogStart;
+ GLfloat fogEnd;
+
+ void SetFog(float colorR, float colorG, float colorB, float fStart, float fEnd, float fogDensity);
+ void TempFog(float colorR, float colorG, float colorB);
+ void ResetFog();
+};
+
+#endif \ No newline at end of file
diff --git a/Source/Frustum.cpp b/Source/Frustum.cpp
new file mode 100644
index 0000000..32639e7
--- /dev/null
+++ b/Source/Frustum.cpp
@@ -0,0 +1,153 @@
+#include "frustum.h"
+#include <math.h>
+#include "gl.h"
+
+void FRUSTUM::
+ GetFrustum() {
+ float projmatrix[16];
+ float mvmatrix[16];
+ float clip[16];
+ float t;
+
+ glGetFloatv(GL_PROJECTION_MATRIX, projmatrix);
+ glGetFloatv(GL_MODELVIEW_MATRIX, mvmatrix);
+
+ // Combine the matrices
+ clip[0] = mvmatrix[0] * projmatrix[0] + mvmatrix[1] * projmatrix[4] + mvmatrix[2] * projmatrix[8] + mvmatrix[3] * projmatrix[12];
+ clip[1] = mvmatrix[0] * projmatrix[1] + mvmatrix[1] * projmatrix[5] + mvmatrix[2] * projmatrix[9] + mvmatrix[3] * projmatrix[13];
+ clip[2] = mvmatrix[0] * projmatrix[2] + mvmatrix[1] * projmatrix[6] + mvmatrix[2] * projmatrix[10] + mvmatrix[3] * projmatrix[14];
+ clip[3] = mvmatrix[0] * projmatrix[3] + mvmatrix[1] * projmatrix[7] + mvmatrix[2] * projmatrix[11] + mvmatrix[3] * projmatrix[15];
+
+ clip[4] = mvmatrix[4] * projmatrix[0] + mvmatrix[5] * projmatrix[4] + mvmatrix[6] * projmatrix[8] + mvmatrix[7] * projmatrix[12];
+ clip[5] = mvmatrix[4] * projmatrix[1] + mvmatrix[5] * projmatrix[5] + mvmatrix[6] * projmatrix[9] + mvmatrix[7] * projmatrix[13];
+ clip[6] = mvmatrix[4] * projmatrix[2] + mvmatrix[5] * projmatrix[6] + mvmatrix[6] * projmatrix[10] + mvmatrix[7] * projmatrix[14];
+ clip[7] = mvmatrix[4] * projmatrix[3] + mvmatrix[5] * projmatrix[7] + mvmatrix[6] * projmatrix[11] + mvmatrix[7] * projmatrix[15];
+
+ clip[8] = mvmatrix[8] * projmatrix[0] + mvmatrix[9] * projmatrix[4] + mvmatrix[10] * projmatrix[8] + mvmatrix[11] * projmatrix[12];
+ clip[9] = mvmatrix[8] * projmatrix[1] + mvmatrix[9] * projmatrix[5] + mvmatrix[10] * projmatrix[9] + mvmatrix[11] * projmatrix[13];
+ clip[10] = mvmatrix[8] * projmatrix[2] + mvmatrix[9] * projmatrix[6] + mvmatrix[10] * projmatrix[10] + mvmatrix[11] * projmatrix[14];
+ clip[11] = mvmatrix[8] * projmatrix[3] + mvmatrix[9] * projmatrix[7] + mvmatrix[10] * projmatrix[11] + mvmatrix[11] * projmatrix[15];
+
+ clip[12] = mvmatrix[12] * projmatrix[0] + mvmatrix[13] * projmatrix[4] + mvmatrix[14] * projmatrix[8] + mvmatrix[15] * projmatrix[12];
+ clip[13] = mvmatrix[12] * projmatrix[1] + mvmatrix[13] * projmatrix[5] + mvmatrix[14] * projmatrix[9] + mvmatrix[15] * projmatrix[13];
+ clip[14] = mvmatrix[12] * projmatrix[2] + mvmatrix[13] * projmatrix[6] + mvmatrix[14] * projmatrix[10] + mvmatrix[15] * projmatrix[14];
+ clip[15] = mvmatrix[12] * projmatrix[3] + mvmatrix[13] * projmatrix[7] + mvmatrix[14] * projmatrix[11] + mvmatrix[15] * projmatrix[15];
+
+ // Right plane
+ frustum[0][0] = clip[3] - clip[0];
+ frustum[0][1] = clip[7] - clip[4];
+ frustum[0][2] = clip[11] - clip[8];
+ frustum[0][3] = clip[15] - clip[12];
+
+ // Left plane
+ frustum[1][0] = clip[3] + clip[0];
+ frustum[1][1] = clip[7] + clip[4];
+ frustum[1][2] = clip[11] + clip[8];
+ frustum[1][3] = clip[15] + clip[12];
+
+ // Bottom plane
+ frustum[2][0] = clip[3] + clip[1];
+ frustum[2][1] = clip[7] + clip[5];
+ frustum[2][2] = clip[11] + clip[9];
+ frustum[2][3] = clip[15] + clip[13];
+
+ // Top plane
+ frustum[3][0] = clip[3] - clip[1];
+ frustum[3][1] = clip[7] - clip[5];
+ frustum[3][2] = clip[11] - clip[9];
+ frustum[3][3] = clip[15] - clip[13];
+
+ // Far plane
+ frustum[4][0] = clip[3] - clip[2];
+ frustum[4][1] = clip[7] - clip[6];
+ frustum[4][2] = clip[11] - clip[10];
+ frustum[4][3] = clip[15] - clip[14];
+
+ // Near plane
+ frustum[5][0] = clip[3] + clip[2];
+ frustum[5][1] = clip[7] + clip[6];
+ frustum[5][2] = clip[11] + clip[10];
+ frustum[5][3] = clip[15] + clip[14];
+}
+
+int FRUSTUM::
+ CubeInFrustum(float x, float y, float z, float size) {
+ int c, c2;
+
+ for(int i=0; i<6; i++) {
+ c=0;
+ if(frustum[i][0] * (x-size) + frustum[i][1] * (y-size) + frustum[i][2] * (z-size) + frustum[i][3] > 0)
+ c++;
+ if(frustum[i][0] * (x+size) + frustum[i][1] * (y-size) + frustum[i][2] * (z-size) + frustum[i][3] > 0)
+ c++;
+ if(frustum[i][0] * (x-size) + frustum[i][1] * (y+size) + frustum[i][2] * (z-size) + frustum[i][3] > 0)
+ c++;
+ if(frustum[i][0] * (x+size) + frustum[i][1] * (y+size) + frustum[i][2] * (z-size) + frustum[i][3] > 0)
+ c++;
+ if(frustum[i][0] * (x-size) + frustum[i][1] * (y-size) + frustum[i][2] * (z+size) + frustum[i][3] > 0)
+ c++;
+ if(frustum[i][0] * (x+size) + frustum[i][1] * (y-size) + frustum[i][2] * (z+size) + frustum[i][3] > 0)
+ c++;
+ if(frustum[i][0] * (x-size) + frustum[i][1] * (y+size) + frustum[i][2] * (z+size) + frustum[i][3] > 0)
+ c++;
+ if(frustum[i][0] * (x+size) + frustum[i][1] * (y+size) + frustum[i][2] * (z+size) + frustum[i][3] > 0)
+ c++;
+ if(c==0)
+ return 0;
+ if(c==8)
+ c2++;
+ }
+ if(c2>=6)
+ return 2;
+ else
+ return 1;
+}
+
+int FRUSTUM::
+ CubeInFrustum(float x, float y, float z, float size, float height) {
+ int c, c2;
+
+ for(int i=0; i<6; i++) {
+ c=0;
+ if(frustum[i][0] * (x-size) + frustum[i][1] * (y-height) + frustum[i][2] * (z-size) + frustum[i][3] > 0)
+ c++;
+ if(frustum[i][0] * (x+size) + frustum[i][1] * (y-height) + frustum[i][2] * (z-size) + frustum[i][3] > 0)
+ c++;
+ if(frustum[i][0] * (x-size) + frustum[i][1] * (y+height) + frustum[i][2] * (z-size) + frustum[i][3] > 0)
+ c++;
+ if(frustum[i][0] * (x+size) + frustum[i][1] * (y+height) + frustum[i][2] * (z-size) + frustum[i][3] > 0)
+ c++;
+ if(frustum[i][0] * (x-size) + frustum[i][1] * (y-height) + frustum[i][2] * (z+size) + frustum[i][3] > 0)
+ c++;
+ if(frustum[i][0] * (x+size) + frustum[i][1] * (y-height) + frustum[i][2] * (z+size) + frustum[i][3] > 0)
+ c++;
+ if(frustum[i][0] * (x-size) + frustum[i][1] * (y+height) + frustum[i][2] * (z+size) + frustum[i][3] > 0)
+ c++;
+ if(frustum[i][0] * (x+size) + frustum[i][1] * (y+height) + frustum[i][2] * (z+size) + frustum[i][3] > 0)
+ c++;
+ if(c==0)
+ return 0;
+ if(c==8)
+ c2++;
+ }
+ if(c2>=6)
+ return 2;
+ else
+ return 1;
+}
+
+int FRUSTUM::
+ SphereInFrustum(float x, float y, float z, float radius) {
+ int c2;
+
+ for(int i=0; i<6; i++) {
+ if(frustum[i][0] * x + frustum[i][1] * y + frustum[i][2] * z + frustum[i][3] > -1*radius)
+ c2++;
+ else
+ return 0;
+ }
+ if(c2>=6)
+ return 2;
+ else
+ return 1;
+} \ No newline at end of file
diff --git a/Source/Frustum.h b/Source/Frustum.h
new file mode 100644
index 0000000..759e50a
--- /dev/null
+++ b/Source/Frustum.h
@@ -0,0 +1,13 @@
+#ifndef FRUSTUM_H
+#define FRUSTUM_H
+
+class FRUSTUM {
+ public:
+ float frustum[6][4];
+ void GetFrustum();
+ int CubeInFrustum(float, float, float, float);
+ int CubeInFrustum(float, float, float, float, float);
+ int SphereInFrustum(float, float, float, float);
+};
+
+#endif \ No newline at end of file
diff --git a/Source/Game.h b/Source/Game.h
new file mode 100644
index 0000000..7da52a0
--- /dev/null
+++ b/Source/Game.h
@@ -0,0 +1,210 @@
+#ifndef _GAME_H_
+#define _GAME_H_
+
+#include <gl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <gl.h>
+#include <glu.h>
+#include <tk.h>
+#include <Sound.h>
+#include <Resources.h>
+#include <cstdarg>
+#include <glm.h>
+#include <TextUtils.h>
+
+#include "AGL_DSp.h"
+#include "Timer.h"
+#include "MacInput.h"
+#include "Quaternions.h"
+#include "Camera.h"
+#include "Skeleton.h"
+#include "Files.h"
+#include "Models.h"
+#include "Text.h"
+#include "TGALoader.h"
+#include "alut.h"
+#include "Fog.h"
+#include "Frustum.h"
+#include "Sprites.h"
+#include "Person.h"
+#include "Decals.h"
+
+#define num_blocks 100
+#define block_spacing 360
+#define max_people 90
+#define max_people_block 20
+
+
+class Game
+{
+ public:
+ //Eventloop
+ Boolean gQuit;
+ float gamespeed;
+ double multiplier2,multiplier3,multiplier4,multiplier5,end,start,timetaken,framespersecond;
+ timer theTimer;
+ float sps;
+ int maxfps;
+ AGLContext gOpenGLContext;
+ CGrafPtr theScreen;
+
+ //Graphics
+ int screenwidth,screenheight;
+ float viewdistance;
+
+ //GL functions
+ GLvoid ReSizeGLScene(float fov, float near);
+ int DrawGLScene(GLvoid);
+ int InitGL(GLvoid);
+ void LoadingScreen(float percent);
+
+ //Game Functions
+ void HandleKeyDown( char theChar );
+ void DoEvent( EventRecord *event );
+ void EventLoop( void );
+ void Tick();
+ void Splat(int k);
+ void InitGame();
+ void Dispose();
+
+ //Mouse
+ Point mouseloc;
+ Point oldmouseloc;
+ float mouserotation,mouserotation2;
+ float oldmouserotation,oldmouserotation2;
+ float mousesensitivity;
+ float usermousesensitivity;
+
+ //keyboard
+
+ bool tabkeydown;
+
+ //Project Specific
+ int cityrotation[num_blocks][num_blocks];
+ int citytype[num_blocks][num_blocks];
+ int citypeoplenum[num_blocks][num_blocks];
+ bool drawn[num_blocks][num_blocks];
+ int onblockx,onblocky;
+ bool cubetest;
+ bool disttest;
+ bool oldbutton;
+
+ bool initialized;
+
+ float flashamount;
+ float flashr,flashg,flashb;
+
+ int enemystate;
+
+ int cycle;
+
+ bool whacked;
+
+ float losedelay;
+
+ XYZ bodycoords;
+
+ FRUSTUM frustum;
+ Model blocks[4];
+ Model blockwalls[4];
+ Model blockcollide[4];
+ Model blocksimplecollide[4];
+ Model blockroofs[4];
+ Model blockocclude;
+ Model sidewalkcollide;
+ Model street;
+ Model Bigstreet;
+ Model path;
+ Model blocksimple;
+ XYZ boundingpoints[8];
+ Files files;
+ Text text;
+ int goodkills;
+ int badkills;
+ int civkills;
+ int machinegunsoundloop;
+
+ bool lasersight;
+ bool debug;
+ bool vblsync;
+
+ bool blur;
+ bool blurness;
+
+ bool paused;
+
+ int mainmenu;
+
+ bool reloadtoggle;
+
+ bool aimtoggle;
+
+ Point olddrawmouse;
+
+ XYZ vipgoal;
+
+ XYZ aimer[2];
+
+ double eqn[4];
+
+ float oldrot,oldrot2;
+
+ XYZ lastshot[2];
+ bool zoom;
+ bool oldzoom;
+
+ int numpeople;
+ float spawndelay;
+
+ bool customlevels;
+
+ bool musictoggle;
+
+ float psychicpower;
+
+ int type;
+
+ bool slomokeydown;
+
+ int mouseoverbutton;
+ int oldmouseoverbutton;
+
+ Person person[max_people];
+
+ GLuint personspritetextureptr;
+ GLuint deadpersonspritetextureptr;
+ GLuint scopetextureptr;
+ GLuint flaretextureptr;
+
+ bool killedinnocent;
+ bool gameinprogress;
+ bool beatgame;
+ bool mainmenuness;
+ int murderer;
+ float timeremaining;
+ int whichsong;
+ int oldscore;
+ int highscore;
+ int score;
+ int mission;
+ int nummissions;
+ int numpossibleguns;
+ int possiblegun[6];
+ int evilprobability;
+ float difficulty;
+ bool azertykeyboard;
+ bool oldvisionkey;
+
+ ~Game() {
+ glDeleteTextures( 1, (const unsigned long *)personspritetextureptr );
+ glDeleteTextures( 1, (const unsigned long *)deadpersonspritetextureptr );
+ glDeleteTextures( 1, (const unsigned long *)scopetextureptr );
+ glDeleteTextures( 1, (const unsigned long *)flaretextureptr );
+ }
+
+};
+
+#endif \ No newline at end of file
diff --git a/Source/GameDraw.cpp b/Source/GameDraw.cpp
new file mode 100644
index 0000000..179eaf6
--- /dev/null
+++ b/Source/GameDraw.cpp
@@ -0,0 +1,1771 @@
+#include "Game.h"
+
+
+
+extern int thirdperson;
+
+extern double multiplier;
+
+extern int nocolors;
+
+extern int visions;
+
+extern unsigned int gSourceID[100];
+
+extern unsigned int gSampleSet[100];
+
+extern Camera camera;
+
+extern Sprites sprites;
+
+extern float camerashake;
+
+extern Fog fog;
+
+extern float fogcolorr;
+
+extern float fogcolorg;
+
+extern float fogcolorb;
+
+extern float sinefluct;
+
+extern float sinefluctprog;
+
+extern int environment;
+
+extern Decals decals;
+
+/*********************> DrawGLScene() <*****/
+
+int Game::DrawGLScene(GLvoid)
+
+{
+
+ //Main menu
+
+ if(mainmenu==1){
+
+ //Setup fast sine fluctuation
+
+ sinefluct=sin(sinefluctprog);
+
+ sinefluctprog+=multiplier*1.5;
+
+
+
+ glLoadIdentity();
+
+ glClearColor(0,0,0,1);
+
+ glDisable(GL_CLIP_PLANE0);
+
+ glDisable(GL_FOG);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+
+
+ //"Black Shades"
+
+ glDisable(GL_TEXTURE_2D);
+
+ glDisable(GL_DEPTH_TEST); // Disables Depth Testing
+
+ glDisable(GL_CULL_FACE);
+
+ glDisable(GL_LIGHTING);
+
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE);
+
+ glDepthMask(0);
+
+ glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
+
+ glPushMatrix(); // Store The Projection Matrix
+
+ glLoadIdentity(); // Reset The Projection Matrix
+
+ glOrtho(0,640,0,480,-100,100); // Set Up An Ortho Screen
+
+ glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
+
+ //Draw smoke
+
+ glPushMatrix(); // Store The Modelview Matrix
+
+ glLoadIdentity(); // Reset The Modelview Matrix
+
+ glTranslatef(60+sinefluct*40,335-sinefluct*9,0);
+
+ glScalef(500-sinefluct*80,70+sinefluct*18,1);
+
+ glTranslatef(.5,.5,0);
+
+ glScalef(.5,.5,1);
+
+ glRotatef(sinefluctprog*50,0,0,1);
+
+ glEnable(GL_TEXTURE_2D);
+
+ glBindTexture(GL_TEXTURE_2D, sprites.smoketextureptr);
+
+ glEnable(GL_BLEND);
+
+ glColor4f(1,1,1,.4+sinefluct/8);
+
+ glBegin(GL_TRIANGLES);
+
+ glTexCoord2f(1.0f, 1.0f); glVertex3f( 1, 1, 0.0f);
+
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
+
+ glTexCoord2f(1.0f, 0.0f); glVertex3f( 1,-1, 0.0f);
+
+ glTexCoord2f(0.0f, 0.0f); glVertex3f(-1,-1, 0.0f);
+
+ glTexCoord2f(1.0f, 0.0f); glVertex3f( 1, -1, 0.0f);
+
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
+
+ glEnd();
+
+ glPopMatrix();
+
+ glPushMatrix(); // Store The Modelview Matrix
+
+ glLoadIdentity(); // Reset The Modelview Matrix
+
+ glTranslatef(60+sinefluct*40,335-sinefluct*9,0);
+
+ glScalef(530-sinefluct*80,50+sinefluct*18,1);
+
+ glTranslatef(.5,.5,0);
+
+ glScalef(.5,.5,1);
+
+ glRotatef(-sinefluctprog*50,0,0,1);
+
+ glEnable(GL_TEXTURE_2D);
+
+ glBindTexture(GL_TEXTURE_2D, sprites.smoketextureptr);
+
+ glEnable(GL_BLEND);
+
+ glColor4f(1,1,1,.4-sinefluct/8);
+
+ glBegin(GL_TRIANGLES);
+
+ glTexCoord2f(1.0f, 1.0f); glVertex3f( 1, 1, 0.0f);
+
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
+
+ glTexCoord2f(1.0f, 0.0f); glVertex3f( 1,-1, 0.0f);
+
+ glTexCoord2f(0.0f, 0.0f); glVertex3f(-1,-1, 0.0f);
+
+ glTexCoord2f(1.0f, 0.0f); glVertex3f( 1, -1, 0.0f);
+
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
+
+ glEnd();
+
+ glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
+
+ glPopMatrix(); // Restore The Old Projection Matrix
+
+ glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
+
+ glPopMatrix(); // Restore The Old Projection Matrix
+
+ glDepthMask(1);
+
+
+
+ //Text
+
+
+
+ glEnable(GL_TEXTURE_2D);
+
+ glColor4f(0,0,0,1);
+
+ static char string[256]="";
+
+ sprintf (string, "Black Shades");
+
+ text.glPrint(100,175,string,1,2,640,480);
+
+
+
+ //"New Game"
+
+ glDisable(GL_TEXTURE_2D);
+
+ glDisable(GL_DEPTH_TEST); // Disables Depth Testing
+
+ glDisable(GL_CULL_FACE);
+
+ glDisable(GL_LIGHTING);
+
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE);
+
+ glDepthMask(0);
+
+ glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
+
+ glPushMatrix(); // Store The Projection Matrix
+
+ glLoadIdentity(); // Reset The Projection Matrix
+
+ glOrtho(0,640,0,480,-100,100); // Set Up An Ortho Screen
+
+ glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
+
+ //Draw smoke
+
+ glPushMatrix(); // Store The Modelview Matrix
+
+ glLoadIdentity(); // Reset The Modelview Matrix
+
+ glTranslatef(120-sinefluct*40,235+sinefluct*9,0);
+
+ glScalef(440+sinefluct*80,70-sinefluct*18,1);
+
+ glTranslatef(.5,.5,0);
+
+ glScalef(.5,.5,1);
+
+ glRotatef(sinefluctprog*50,0,0,1);
+
+ glEnable(GL_TEXTURE_2D);
+
+ if(mouseoverbutton!=1)glBindTexture(GL_TEXTURE_2D, sprites.smoketextureptr);
+
+ if(mouseoverbutton==1)glBindTexture(GL_TEXTURE_2D, flaretextureptr);
+
+ glEnable(GL_BLEND);
+
+ glColor4f(1,0,0,.5+sinefluct/6);
+
+ glBegin(GL_TRIANGLES);
+
+ glTexCoord2f(1.0f, 1.0f); glVertex3f( 1, 1, 0.0f);
+
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
+
+ glTexCoord2f(1.0f, 0.0f); glVertex3f( 1,-1, 0.0f);
+
+ glTexCoord2f(0.0f, 0.0f); glVertex3f(-1,-1, 0.0f);
+
+ glTexCoord2f(1.0f, 0.0f); glVertex3f( 1, -1, 0.0f);
+
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
+
+ glEnd();
+
+ glPopMatrix();
+
+ glPushMatrix(); // Store The Modelview Matrix
+
+ glLoadIdentity(); // Reset The Modelview Matrix
+
+ glTranslatef(120-sinefluct*40,235+sinefluct*9,0);
+
+ glScalef(460+sinefluct*80,50-sinefluct*18,1);
+
+ glTranslatef(.5,.5,0);
+
+ glScalef(.5,.5,1);
+
+ glRotatef(-sinefluctprog*50,0,0,1);
+
+ glEnable(GL_TEXTURE_2D);
+
+ if(mouseoverbutton!=1)glBindTexture(GL_TEXTURE_2D, sprites.smoketextureptr);
+
+ if(mouseoverbutton==1)glBindTexture(GL_TEXTURE_2D, flaretextureptr);
+
+ glEnable(GL_BLEND);
+
+ glColor4f(1,0,0,.5-sinefluct/6);
+
+ glBegin(GL_TRIANGLES);
+
+ glTexCoord2f(1.0f, 1.0f); glVertex3f( 1, 1, 0.0f);
+
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
+
+ glTexCoord2f(1.0f, 0.0f); glVertex3f( 1,-1, 0.0f);
+
+ glTexCoord2f(0.0f, 0.0f); glVertex3f(-1,-1, 0.0f);
+
+ glTexCoord2f(1.0f, 0.0f); glVertex3f( 1, -1, 0.0f);
+
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
+
+ glEnd();
+
+ glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
+
+ glPopMatrix(); // Restore The Old Projection Matrix
+
+ glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
+
+ glPopMatrix(); // Restore The Old Projection Matrix
+
+ glDepthMask(1);
+
+
+
+ //Text
+
+
+
+ glEnable(GL_TEXTURE_2D);
+
+ glColor4f(0,0,0,1);
+
+ if(!gameinprogress)sprintf (string, "New Game");
+
+ if(gameinprogress)sprintf (string, "Resume Game");
+
+ text.glPrint(190-gameinprogress*10,170,string,1,1.5,640,480);
+
+
+
+ //"Quit"
+
+ glDisable(GL_TEXTURE_2D);
+
+ glDisable(GL_DEPTH_TEST); // Disables Depth Testing
+
+ glDisable(GL_CULL_FACE);
+
+ glDisable(GL_LIGHTING);
+
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE);
+
+ glDepthMask(0);
+
+ glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
+
+ glPushMatrix(); // Store The Projection Matrix
+
+ glLoadIdentity(); // Reset The Projection Matrix
+
+ glOrtho(0,640,0,480,-100,100); // Set Up An Ortho Screen
+
+ glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
+
+ //Draw smoke
+
+ glPushMatrix(); // Store The Modelview Matrix
+
+ glLoadIdentity(); // Reset The Modelview Matrix
+
+ glTranslatef(120-sinefluct*40,112+sinefluct*9,0);
+
+ glScalef(440+sinefluct*80,70-sinefluct*18,1);
+
+ glTranslatef(.5,.5,0);
+
+ glScalef(.5,.5,1);
+
+ glRotatef(sinefluctprog*50,0,0,1);
+
+ glEnable(GL_TEXTURE_2D);
+
+ if(mouseoverbutton!=2)glBindTexture(GL_TEXTURE_2D, sprites.smoketextureptr);
+
+ if(mouseoverbutton==2)glBindTexture(GL_TEXTURE_2D, flaretextureptr);
+
+ glEnable(GL_BLEND);
+
+ glColor4f(1,0,0,.5+sinefluct/6);
+
+ glBegin(GL_TRIANGLES);
+
+ glTexCoord2f(1.0f, 1.0f); glVertex3f( 1, 1, 0.0f);
+
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
+
+ glTexCoord2f(1.0f, 0.0f); glVertex3f( 1,-1, 0.0f);
+
+ glTexCoord2f(0.0f, 0.0f); glVertex3f(-1,-1, 0.0f);
+
+ glTexCoord2f(1.0f, 0.0f); glVertex3f( 1, -1, 0.0f);
+
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
+
+ glEnd();
+
+ glPopMatrix();
+
+ glPushMatrix(); // Store The Modelview Matrix
+
+ glLoadIdentity(); // Reset The Modelview Matrix
+
+ glTranslatef(120-sinefluct*40,112+sinefluct*9,0);
+
+ glScalef(460+sinefluct*80,50-sinefluct*18,1);
+
+ glTranslatef(.5,.5,0);
+
+ glScalef(.5,.5,1);
+
+ glRotatef(-sinefluctprog*50,0,0,1);
+
+ glEnable(GL_TEXTURE_2D);
+
+ if(mouseoverbutton!=2)glBindTexture(GL_TEXTURE_2D, sprites.smoketextureptr);
+
+ if(mouseoverbutton==2)glBindTexture(GL_TEXTURE_2D, flaretextureptr);
+
+ glEnable(GL_BLEND);
+
+ glColor4f(1,0,0,.5-sinefluct/6);
+
+ glBegin(GL_TRIANGLES);
+
+ glTexCoord2f(1.0f, 1.0f); glVertex3f( 1, 1, 0.0f);
+
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
+
+ glTexCoord2f(1.0f, 0.0f); glVertex3f( 1,-1, 0.0f);
+
+ glTexCoord2f(0.0f, 0.0f); glVertex3f(-1,-1, 0.0f);
+
+ glTexCoord2f(1.0f, 0.0f); glVertex3f( 1, -1, 0.0f);
+
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(-1, 1, 0.0f);
+
+ glEnd();
+
+ glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
+
+ glPopMatrix(); // Restore The Old Projection Matrix
+
+ glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
+
+ glPopMatrix(); // Restore The Old Projection Matrix
+
+ glDepthMask(1);
+
+
+
+ //Text
+
+
+
+ glEnable(GL_TEXTURE_2D);
+
+ glColor4f(0,0,0,1);
+
+ if(!gameinprogress)sprintf (string, "Quit");
+
+ if(gameinprogress)sprintf (string, "End Game");
+
+ text.glPrint(197-gameinprogress*15,87,string,1,1.5,640,480);
+
+
+
+ //High score
+
+ glColor4f(.5+sinefluct/5,0,0,1);
+
+ if(!beatgame)sprintf (string, "High Score: %d", highscore);
+
+ if(beatgame)sprintf (string, "High Score: %d *COMPLETED* Please vote for Black Shades at iDevGames.com!", highscore);
+
+ text.glPrint(0,0,string,1,.8,640,480);
+
+
+
+ //Mandatory udg text
+
+ glColor4f(.3-sinefluct/20,.3-sinefluct/20,.3-sinefluct/20,1);
+
+ sprintf (string, "uDevGame 2002 Entry - Visit iDevGames.com for more games!", highscore);
+
+ text.glPrint(500,750,string,1,.6,640,480);
+
+
+
+
+
+ //Mouse (draw)
+
+ glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
+
+ glPushMatrix(); // Store The Projection Matrix
+
+ glLoadIdentity(); // Reset The Projection Matrix
+
+ glOrtho(0,screenwidth,0,screenheight,-100,100); // Set Up An Ortho Screen
+
+ glMatrixMode(GL_MODELVIEW);
+
+ glDisable(GL_TEXTURE_2D);
+
+ Point mouseloc;
+
+ GetMouse(&mouseloc);
+
+ mouseloc.v=screenheight-mouseloc.v;
+
+
+
+ glColor4f(.1,0,0,1);
+
+
+
+ float size=5;
+
+
+
+ glBegin(GL_TRIANGLES);
+
+ glVertex3f(mouseloc.h,mouseloc.v,0);
+
+ glVertex3f(mouseloc.h+2*size,mouseloc.v-2*size,0);
+
+ glVertex3f(mouseloc.h+.5*size,mouseloc.v-2*size,0);
+
+ glEnd();
+
+
+
+ glColor4f(1,0,0,1);
+
+
+
+ glBegin(GL_QUADS);
+
+ glVertex3f(olddrawmouse.h,olddrawmouse.v,0);
+
+ glVertex3f(mouseloc.h,mouseloc.v,0);
+
+ glVertex3f(mouseloc.h+2*size,mouseloc.v-2*size,0);
+
+ glVertex3f(olddrawmouse.h+2*size,olddrawmouse.v-2*size,0);
+
+
+
+ glVertex3f(olddrawmouse.h,olddrawmouse.v,0);
+
+ glVertex3f(mouseloc.h,mouseloc.v,0);
+
+ glVertex3f(mouseloc.h+.5*size,mouseloc.v-2*size,0);
+
+ glVertex3f(olddrawmouse.h+.5*size,olddrawmouse.v-2*size,0);
+
+
+
+ glVertex3f(olddrawmouse.h+2*size,olddrawmouse.v-2*size,0);
+
+ glVertex3f(mouseloc.h+2*size,mouseloc.v-2*size,0);
+
+ glVertex3f(mouseloc.h+.5*size,mouseloc.v-2*size,0);
+
+ glVertex3f(olddrawmouse.h+.5*size,olddrawmouse.v-2*size,0);
+
+ glEnd();
+
+ glPopMatrix();
+
+
+
+ olddrawmouse=mouseloc;
+
+
+
+ //Flash
+
+ if(flashamount>0){
+
+ if(flashamount>1)flashamount=1;
+
+ flashamount-=multiplier;
+
+ if(flashamount<0)flashamount=0;
+
+ glDisable(GL_DEPTH_TEST); // Disables Depth Testing
+
+ glDisable(GL_CULL_FACE);
+
+ glDisable(GL_LIGHTING);
+
+ glDepthMask(0);
+
+ glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
+
+ glPushMatrix(); // Store The Projection Matrix
+
+ glLoadIdentity(); // Reset The Projection Matrix
+
+ glOrtho(0,screenwidth,0,screenheight,-100,100); // Set Up An Ortho Screen
+
+ glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
+
+ glPushMatrix(); // Store The Modelview Matrix
+
+ glLoadIdentity(); // Reset The Modelview Matrix
+
+ glScalef(screenwidth,screenheight,1);
+
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+
+ glEnable(GL_BLEND);
+
+ glColor4f(flashr,flashg,flashb,flashamount);
+
+ glBegin(GL_QUADS);
+
+ glVertex3f(0, 0, 0.0f);
+
+ glVertex3f(256, 0, 0.0f);
+
+ glVertex3f(256, 256, 0.0f);
+
+ glVertex3f(0, 256, 0.0f);
+
+ glEnd();
+
+ glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
+
+ glPopMatrix(); // Restore The Old Projection Matrix
+
+ glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
+
+ glPopMatrix(); // Restore The Old Projection Matrix
+
+ glEnable(GL_DEPTH_TEST); // Enables Depth Testing
+
+ glEnable(GL_CULL_FACE);
+
+ glDisable(GL_BLEND);
+
+ glDepthMask(1);
+
+ }
+
+ }
+
+ //If in-game
+
+ if(mainmenu!=1){
+
+ //If flashing to fix menu bug, go back to menu after a frame
+
+ if(mainmenu==2)mainmenu=1;
+
+ glLoadIdentity();
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glDisable(GL_CLIP_PLANE0);
+
+ //Visions
+
+ sinefluct=sin(sinefluctprog);
+
+ sinefluctprog+=multiplier*3;
+
+ if(visions==0){
+
+ //environment light
+
+ if(environment==sunny_environment){
+
+ viewdistance=2000;
+
+ fogcolorr=.5;
+
+ fogcolorg=.5;
+
+ fogcolorb=.8;
+
+ fog.SetFog(fogcolorr,fogcolorg,fogcolorb,0,viewdistance*.8,.1);
+
+ }
+
+ if(environment==foggy_environment){
+
+ viewdistance=500;
+
+ fogcolorr=.5;
+
+ fogcolorg=.5;
+
+ fogcolorb=.5;
+
+ fog.SetFog(fogcolorr,fogcolorg,fogcolorb,0,viewdistance*.8,.2);
+
+ }
+
+ if(environment==night_environment){
+
+ viewdistance=500;
+
+ fogcolorr=.15;
+
+ fogcolorg=.15;
+
+ fogcolorb=.3;
+
+ fog.SetFog(fogcolorr,fogcolorg,fogcolorb,0,viewdistance*.8,.2);
+
+ }
+
+ if(environment==snowy_environment){
+
+ viewdistance=800;
+
+ fogcolorr=.5;
+
+ fogcolorg=.5;
+
+ fogcolorb=.5;
+
+ fog.SetFog(fogcolorr,fogcolorg,fogcolorb,0,viewdistance*.8,.2);
+
+ }
+
+ if(environment==rainy_environment){
+
+ viewdistance=700;
+
+ fogcolorr=.3;
+
+ fogcolorg=.3;
+
+ fogcolorb=.3;
+
+ fog.SetFog(fogcolorr,fogcolorg,fogcolorb,0,viewdistance*.8,.2);
+
+ }
+
+ if(environment==firey_environment){
+
+ viewdistance=600;
+
+ fogcolorr=.3;
+
+ fogcolorg=.1;
+
+ fogcolorb=0;
+
+ fog.SetFog(fogcolorr,fogcolorg,fogcolorb,0,viewdistance*.8,.2);
+
+ }
+
+ glClearColor(fogcolorr,fogcolorg,fogcolorb,1);
+
+
+
+ if(environment==sunny_environment){
+
+ GLfloat LightAmbient[]= { fogcolorr/4, fogcolorg/4, fogcolorb/4, 1.0f};
+
+ GLfloat LightDiffuse[]= { fogcolorr*1.6, fogcolorg*1.6, fogcolorr*1.6, 1.0f };
+
+ glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);
+
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
+
+ }
+
+ if(environment!=sunny_environment){
+
+ GLfloat LightAmbient[]= { fogcolorr*.8, fogcolorg*.8, fogcolorb*.8, 1.0f};
+
+ GLfloat LightDiffuse[]= { fogcolorr*.8, fogcolorg*.8, fogcolorr*.8, 1.0f };
+
+ glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);
+
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
+
+ }
+
+
+
+ glEnable(GL_LIGHT0);
+
+
+
+ //Change fov if zooming with scope
+
+ if(!zoom)ReSizeGLScene(90,.1);
+
+ if(zoom)ReSizeGLScene(10,.6);
+
+ nocolors=0;
+
+ }
+
+
+
+ if(visions==1){
+
+ //light
+
+ GLfloat LightAmbient[]= { 0, 0, 0, 1.0f};
+
+ GLfloat LightDiffuse[]= { .1+sinefluct/5, 0, 0, 1.0f };
+
+
+
+ glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);
+
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
+
+ glEnable(GL_LIGHT0);
+
+
+
+ fogcolorr=(sinefluct/4+.5);
+
+ fogcolorg=0;
+
+ fogcolorb=0;
+
+ fog.SetFog(fogcolorr,fogcolorg,fogcolorb,0,viewdistance*.8*.5*(sinefluct/4+.3),sinefluct/3+.7);
+
+ glClearColor(fogcolorr,fogcolorg,fogcolorb,1);
+
+ ReSizeGLScene(120-sinefluct*20,.3);
+
+ glRotatef(sinefluct*10,0,0,.1);
+
+ nocolors=1;
+
+ //Pitch higher if moving for effect
+
+ if(person[0].currentanimation==idleanim)alSourcef(gSourceID[visionsound], AL_PITCH, 1);
+
+ if(person[0].currentanimation!=idleanim)alSourcef(gSourceID[visionsound], AL_PITCH, 2);
+
+ }
+
+
+
+ //Camera
+
+ float bluramount=.1*blurness;
+
+ blur=1-blur;
+
+ //Set rotation/position
+
+ if(thirdperson)glTranslatef(camera.targetoffset.x,camera.targetoffset.y,camera.targetoffset.z);
+
+ if(thirdperson!=2&&(person[0].skeleton.free!=1||thirdperson!=0)){
+
+ glRotatef(camera.visrotation2+-bluramount/2+(float)blur*bluramount,1,0,0);
+
+ glRotatef(camera.visrotation+-bluramount/2+(float)blur*bluramount,0,1,0);
+
+ }
+
+ if(thirdperson==0&&person[0].skeleton.free==1){
+
+ glRotatef(person[0].skeleton.joints[(person[0].skeleton.jointlabels[head])].rotate3,0,1,0);
+
+ glRotatef(180-(person[0].skeleton.joints[(person[0].skeleton.jointlabels[head])].rotate2+90),0,0,1);
+
+ glRotatef(person[0].skeleton.joints[(person[0].skeleton.jointlabels[head])].rotate1+90,0,1,0);
+
+ }
+
+ if(thirdperson==2){
+
+ glRotatef(oldrot2+-bluramount/2+(float)blur*bluramount,1,0,0);
+
+ glRotatef(oldrot+-bluramount/2+(float)blur*bluramount,0,1,0);
+
+ }
+
+ //Shake camera if grenade explosion
+
+ if(camerashake>0){
+
+ if(!(person[0].aiming<1||person[0].whichgun==grenade||thirdperson)){
+
+ camerashake=0;
+
+ }
+
+ glTranslatef((float)(Random()%100)/100*camerashake,(float)(Random()%100)/100*camerashake,(float)(Random()%100)/100*camerashake);
+
+ }
+
+ camera.Apply();
+
+
+
+ glPushMatrix();
+
+ glClipPlane(GL_CLIP_PLANE0, eqn);
+
+ glDisable(GL_CLIP_PLANE0);
+
+ glPopMatrix();
+
+
+
+ frustum.GetFrustum();
+
+
+
+ GLfloat LightPosition[]= { -.5, 1, -.8, 0.0f };
+
+ glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);
+
+
+
+ glDisable(GL_TEXTURE_2D);
+
+ glEnable(GL_FOG);
+
+ glEnable(GL_COLOR_MATERIAL);
+
+ glEnable(GL_CULL_FACE);
+
+ glDepthMask(1);
+
+
+
+ //Draw street
+
+ glPushMatrix();
+
+ glDepthMask(0);
+
+ glDisable(GL_DEPTH_TEST);
+
+ glEnable(GL_LIGHTING);
+
+ glTranslatef(camera.position.x,0,camera.position.z);
+
+ glScalef(viewdistance*5/100,1,viewdistance*5/100);
+
+ if(visions==0)street.draw(.22,.22,.22);
+
+ if(visions==1)street.draw(0,0,0);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glDepthMask(1);
+
+ glPopMatrix();
+
+
+
+ if(visions==0)glEnable(GL_LIGHTING);
+
+ if(visions==1)glDisable(GL_LIGHTING);
+
+
+
+ //Draw blocks
+
+ glEnable(GL_BLEND);
+
+ XYZ move2;
+
+ XYZ move;
+
+ int beginx,endx;
+
+ int beginz,endz;
+
+ int beginoccludex,endoccludex;
+
+ int beginoccludez,endoccludez;
+
+ int distsquared;
+
+
+
+ //Only nearby blocks
+
+ beginx=(camera.position.x-viewdistance+block_spacing/2)/block_spacing-2;
+
+ if(beginx<0)beginx=0;
+
+ beginz=(camera.position.z-viewdistance+block_spacing/2)/block_spacing-2;
+
+ if(beginz<0)beginz=0;
+
+
+
+ endx=(camera.position.x+viewdistance+block_spacing/2)/block_spacing+2;
+
+ if(endx>num_blocks-1)endx=num_blocks-1;
+
+ endz=(camera.position.z+viewdistance+block_spacing/2)/block_spacing+2;
+
+ if(endz>num_blocks-1)endz=num_blocks-1;
+
+
+
+ bool draw;
+
+ int numfail;
+
+ int whichtri;
+
+ XYZ collpoint;
+
+
+
+ for(int i=beginx;i<=endx;i++){
+
+ for(int j=beginz;j<=endz;j++){
+
+ drawn[i][j]=1;
+
+ }
+
+ }
+
+
+
+ if(beginx<endx&&beginz<endz)
+
+ for(int i=beginx;i<=endx;i++){
+
+ for(int j=beginz;j<=endz;j++){
+
+ draw=1;
+
+ //Only draw if visible
+
+ distsquared=((i)*block_spacing-camera.position.x)*((i)*block_spacing-camera.position.x)+((j)*block_spacing-camera.position.z)*((j)*block_spacing-camera.position.z);
+
+ if(distsquared>(viewdistance*viewdistance+block_spacing*block_spacing ))draw=0;
+
+ if(draw&&citytype[i][j]!=3&&!frustum.CubeInFrustum((i)*block_spacing,0,(j)*block_spacing,block_spacing))draw=0;
+
+ if(draw&&citytype[i][j]!=3&&!frustum.SphereInFrustum(blocks[citytype[i][j]].boundingspherecenter.x+(i)*block_spacing,blocks[citytype[i][j]].boundingspherecenter.y,blocks[citytype[i][j]].boundingspherecenter.z+(j)*block_spacing,blocks[citytype[i][j]].boundingsphereradius))draw=0;
+
+ if(draw){
+
+ glPushMatrix();
+
+ glTranslatef(i*block_spacing,0,j*block_spacing);
+
+ glRotatef(cityrotation[i][j]*90,0,1,0);
+
+ blocks[citytype[i][j]].draw();
+
+ glPopMatrix();
+
+ }
+
+ if(!draw){
+
+ move.y=0;
+
+ move.x=i*block_spacing;
+
+ move.z=j*block_spacing;
+
+ if(findDistancefast(move,camera.position)<300000)drawn[i][j]=0;
+
+ }
+
+ }
+
+ }
+
+
+
+ //Decals
+
+ decals.draw();
+
+
+
+ //Occluding blocks
+
+ beginx=(camera.position.x+block_spacing/2)/block_spacing-2;
+
+ if(beginx<0)beginx=0;
+
+ beginz=(camera.position.z+block_spacing/2)/block_spacing-2;
+
+ if(beginz<0)beginz=0;
+
+
+
+ endx=(camera.position.x+block_spacing/2)/block_spacing+2;
+
+ if(endx>num_blocks-1)endx=num_blocks-1;
+
+ endz=(camera.position.z+block_spacing/2)/block_spacing+2;
+
+ if(endz>num_blocks-1)endz=num_blocks-1;
+
+
+
+ float M[16];
+
+ XYZ drawpoint;
+
+ float size=20;
+
+
+
+ //Draw people
+
+ if(visions==1)fog.SetFog(fogcolorr,fogcolorg,fogcolorb,0,viewdistance*.8*.5*(-sinefluct/4+.3),-sinefluct/3+.7);
+
+ glColor4f(1,1,1,1);
+
+ glEnable(GL_COLOR_MATERIAL);
+
+ glEnable(GL_BLEND);
+
+ for(int i=0;i<numpeople;i++){
+
+
+
+ draw=1;
+
+ if(person[i].skeleton.free<1){
+
+ if(person[i].whichblockx>=0&&person[i].whichblockx<num_blocks&&person[i].whichblocky>=0&&person[i].whichblocky<num_blocks){
+
+ if(!drawn[person[i].whichblockx][person[i].whichblocky])draw=0;
+
+ }else draw=0;
+
+ if(draw)
+
+ if(!frustum.CubeInFrustum(person[i].playercoords.x,person[i].playercoords.y,person[i].playercoords.z,5))draw=0;
+
+ if(draw)
+
+ if(findDistancefast(person[i].playercoords,camera.position)>1000000)draw=0;
+
+ if(draw)
+
+ for(int j=beginx;j<=endx;j++){
+
+ for(int k=beginz;k<=endz;k++){
+
+ if(draw){
+
+ move.y=0;
+
+ move.x=j*block_spacing;
+
+ move.z=k*block_spacing;
+
+ if(findDistancefast(move,camera.position)<100000){
+
+ whichtri=blockocclude.LineCheck2(camera.position,person[i].playercoords,&collpoint,move,0);
+
+ if(whichtri!=-1)draw=0;
+
+ }
+
+ }
+
+ }
+
+ }
+
+ if(draw){
+
+ move.y=0;
+
+ move.x=person[i].whichblockx*block_spacing;
+
+ move.z=person[i].whichblocky*block_spacing;
+
+ whichtri=blockocclude.LineCheck2(camera.position,person[i].playercoords,&collpoint,move,0);
+
+ if(whichtri!=-1)draw=0;
+
+ }
+
+ if(i==0)draw=1;
+
+ }
+
+ if(person[i].skeleton.free==1){
+
+ if(draw)
+
+ if(!person[i].skeleton.broken&&!frustum.CubeInFrustum(person[i].averageloc.x,person[i].averageloc.y,person[i].averageloc.z,5))draw=0;
+
+ if(draw)
+
+ if(findDistancefast(person[i].averageloc,camera.position)>1000000)draw=0;
+
+ if(draw)
+
+ if(person[i].skeleton.joints[0].position.y<-2)draw=0;
+
+ for(int j=beginx;j<=endx;j++){
+
+ for(int k=beginz;k<=endz;k++){
+
+ if(draw){
+
+ move.y=0;
+
+ move.x=j*block_spacing;
+
+ move.z=k*block_spacing;
+
+ if(findDistancefast(move,camera.position)<100000){
+
+ whichtri=blockocclude.LineCheck2(camera.position,person[i].averageloc,&collpoint,move,0);
+
+ if(whichtri!=-1)draw=0;
+
+ }
+
+ }
+
+ }
+
+ }
+
+ if(draw){
+
+ move.y=0;
+
+ move.x=person[i].whichblockx*block_spacing;
+
+ move.z=person[i].whichblocky*block_spacing;
+
+ whichtri=blockocclude.LineCheck2(camera.position,person[i].averageloc,&collpoint,move,0);
+
+ if(whichtri!=-1)draw=0;
+
+ }
+
+ if(i==0)draw=1;
+
+ }
+
+ if(draw&&person[i].existing==1){
+
+ if((findDistancefast(person[i].playercoords,camera.position)<100000+zoom*3000000&&person[i].skeleton.free<1)||(findDistancefast(person[i].averageloc,camera.position)<100000+zoom*3000000&&person[i].skeleton.free>=1)){
+
+ glPushMatrix();
+
+ if(person[i].skeleton.free==0){
+
+ glTranslatef(person[i].playercoords.x,person[i].playercoords.y,person[i].playercoords.z);
+
+ glRotatef(person[i].playerrotation,0,1,0);
+
+ if(i!=0||visions==0)person[i].DoAnimations(i);
+
+ if(i==0&&visions==1)person[i].DoAnimationslite(i);
+
+ }
+
+ if(visions==1)nocolors=1;
+
+ if(visions==1&&person[i].type==eviltype)nocolors=2;
+
+ if(visions==1&&person[i].type==viptype)nocolors=3;
+
+ if(!(visions==1&&i==0)&&!(zoom==1&&i==0))person[i].DrawSkeleton(i);
+
+ glPopMatrix();
+
+ }
+
+ else{
+
+ glPushMatrix();
+
+ if(person[i].skeleton.free<1)person[i].DoAnimationslite(i);
+
+ glColor4f(1,1,1,1);
+
+ glEnable(GL_BLEND);
+
+ glDisable(GL_CULL_FACE);
+
+ glEnable(GL_TEXTURE_2D);
+
+ glDisable(GL_LIGHTING);
+
+ glDepthMask(0);
+
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+
+ if(person[i].skeleton.free<1){
+
+ glBindTexture(GL_TEXTURE_2D, personspritetextureptr);
+
+ glTranslatef(person[i].playercoords.x,person[i].playercoords.y+size/2*.3,person[i].playercoords.z);
+
+ }
+
+ if(person[i].skeleton.free==1){
+
+ glBindTexture(GL_TEXTURE_2D, deadpersonspritetextureptr);
+
+ glTranslatef(person[i].averageloc.x,person[i].averageloc.y+size/2*.3,person[i].averageloc.z);
+
+ }
+
+ glGetFloatv(GL_MODELVIEW_MATRIX,M);
+
+ drawpoint.x=M[12];
+
+ drawpoint.y=M[13];
+
+ drawpoint.z=M[14];
+
+ glLoadIdentity();
+
+ glTranslatef(drawpoint.x, drawpoint.y, drawpoint.z);
+
+ glBegin(GL_TRIANGLES);
+
+ glTexCoord2f(1.0f, 1.0f); glVertex3f( .3f*size, .3f*size, 0.0f);
+
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(-.3f*size, .3f*size, 0.0f);
+
+ glTexCoord2f(1.0f, 0.0f); glVertex3f( .3f*size,-.3f*size, 0.0f);
+
+ glTexCoord2f(0.0f, 0.0f); glVertex3f(-.3f*size,-.3f*size, 0.0f);
+
+ glTexCoord2f(1.0f, 0.0f); glVertex3f( .3f*size, -.3f*size, 0.0f);
+
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(-.3f*size, .3f*size, 0.0f);
+
+ glEnd();
+
+ glPopMatrix();
+
+ glDepthMask(1);
+
+ glDisable(GL_TEXTURE_2D);
+
+ glEnable(GL_CULL_FACE);
+
+ if(visions!=1)glEnable(GL_LIGHTING);
+
+ }
+
+ }
+
+ if(person[i].skeleton.free<1&&!draw)person[i].DoAnimationslite(i);
+
+
+
+ if(!person[i].existing)
+
+ if(!draw||findDistancefast(person[i].playercoords,camera.position)>10000){person[i].existing=1;}
+
+ }
+
+ glDisable(GL_COLOR_MATERIAL);
+
+ glDisable(GL_BLEND);
+
+
+
+ //Attacker psychicness
+
+ for(int i=0;i<numpeople;i++){
+
+ if(person[i].killtarget>-1&&person[i].killtargetvisible&&person[i].skeleton.free==0&&person[person[i].killtarget].skeleton.free==0){
+
+ sprites.MakeSprite(bulletinstant, (shotdelayamount/difficulty-person[i].shotdelay)/shotdelayamount/difficulty/2, 1, person[i].shotdelay/shotdelayamount/difficulty, person[i].shotdelay/shotdelayamount/difficulty, DoRotation(person[i].skeleton.joints[person[i].skeleton.jointlabels[lefthand]].position,0,person[i].playerrotation,0)+person[i].playercoords, person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[abdomen]].position+person[person[i].killtarget].playercoords, person[i].shotdelay*2);
+
+ }
+
+ if(person[i].killtarget>-1&&person[i].killtargetvisible&&person[i].skeleton.free==0&&person[person[i].killtarget].skeleton.free!=0){
+
+ sprites.MakeSprite(bulletinstant, (shotdelayamount/difficulty-person[i].shotdelay)/shotdelayamount/difficulty/2, 1, person[i].shotdelay/shotdelayamount/difficulty, person[i].shotdelay/shotdelayamount/difficulty, DoRotation(person[i].skeleton.joints[person[i].skeleton.jointlabels[lefthand]].position,0,person[i].playerrotation,0)+person[i].playercoords, person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[abdomen]].position, person[i].shotdelay*2);
+
+ }
+
+ }
+
+
+
+ //Sprites
+
+ glEnable(GL_CLIP_PLANE0);
+
+ sprites.draw();
+
+
+
+ glDisable(GL_CLIP_PLANE0);
+
+
+
+ glDisable(GL_FOG);
+
+ //Zoom
+
+ glAlphaFunc(GL_GREATER, 0.01);
+
+
+
+ if(zoom){
+
+ glDisable(GL_DEPTH_TEST); // Disables Depth Testing
+
+ glDisable(GL_CULL_FACE);
+
+ glDisable(GL_LIGHTING);
+
+ glDepthMask(0);
+
+ glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
+
+ glPushMatrix(); // Store The Projection Matrix
+
+ glLoadIdentity(); // Reset The Projection Matrix
+
+ glOrtho(0,screenwidth,0,screenheight,-100,100); // Set Up An Ortho Screen
+
+ glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
+
+ glPushMatrix(); // Store The Modelview Matrix
+
+ glLoadIdentity(); // Reset The Modelview Matrix
+
+ glScalef(screenwidth,screenheight,1);
+
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+
+ glEnable(GL_BLEND);
+
+ glEnable(GL_TEXTURE_2D);
+
+ glColor4f(.5,.5,.5,1);
+
+ glBindTexture(GL_TEXTURE_2D, scopetextureptr);
+
+ glBegin(GL_QUADS);
+
+ glTexCoord2f(0,0);
+
+ glVertex3f(0, 0, 0.0f);
+
+ glTexCoord2f(1,0);
+
+ glVertex3f(1, 0, 0.0f);
+
+ glTexCoord2f(1,1);
+
+ glVertex3f(1, 1, 0.0f);
+
+ glTexCoord2f(0,1);
+
+ glVertex3f(0, 1, 0.0f);
+
+ glEnd();
+
+ glDisable(GL_TEXTURE_2D);
+
+ glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
+
+ glPopMatrix(); // Restore The Old Projection Matrix
+
+ glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
+
+ glPopMatrix(); // Restore The Old Projection Matrix
+
+ glEnable(GL_DEPTH_TEST); // Enables Depth Testing
+
+ glEnable(GL_CULL_FACE);
+
+ glDisable(GL_BLEND);
+
+ glDepthMask(1);
+
+ }
+
+
+
+ //Flash
+
+ if(flashamount>0){
+
+ if(flashamount>1)flashamount=1;
+
+ flashamount-=multiplier;
+
+ if(flashamount<0)flashamount=0;
+
+ glDisable(GL_DEPTH_TEST); // Disables Depth Testing
+
+ glDisable(GL_CULL_FACE);
+
+ glDisable(GL_LIGHTING);
+
+ glDepthMask(0);
+
+ glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
+
+ glPushMatrix(); // Store The Projection Matrix
+
+ glLoadIdentity(); // Reset The Projection Matrix
+
+ glOrtho(0,screenwidth,0,screenheight,-100,100); // Set Up An Ortho Screen
+
+ glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
+
+ glPushMatrix(); // Store The Modelview Matrix
+
+ glLoadIdentity(); // Reset The Modelview Matrix
+
+ glScalef(screenwidth,screenheight,1);
+
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+
+ glEnable(GL_BLEND);
+
+ glColor4f(flashr,flashg,flashb,flashamount);
+
+ glBegin(GL_QUADS);
+
+ glVertex3f(0, 0, 0.0f);
+
+ glVertex3f(256, 0, 0.0f);
+
+ glVertex3f(256, 256, 0.0f);
+
+ glVertex3f(0, 256, 0.0f);
+
+ glEnd();
+
+ glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
+
+ glPopMatrix(); // Restore The Old Projection Matrix
+
+ glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
+
+ glPopMatrix(); // Restore The Old Projection Matrix
+
+ glEnable(GL_DEPTH_TEST); // Enables Depth Testing
+
+ glEnable(GL_CULL_FACE);
+
+ glDisable(GL_BLEND);
+
+ glDepthMask(1);
+
+ }
+
+ if(person[0].skeleton.free>0&&thirdperson!=2){
+
+ glDisable(GL_DEPTH_TEST); // Disables Depth Testing
+
+ glDisable(GL_CULL_FACE);
+
+ glDisable(GL_LIGHTING);
+
+ glDepthMask(0);
+
+ glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
+
+ glPushMatrix(); // Store The Projection Matrix
+
+ glLoadIdentity(); // Reset The Projection Matrix
+
+ glOrtho(0,screenwidth,0,screenheight,-100,100); // Set Up An Ortho Screen
+
+ glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
+
+ glPushMatrix(); // Store The Modelview Matrix
+
+ glLoadIdentity(); // Reset The Modelview Matrix
+
+ glScalef(screenwidth,screenheight,1);
+
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+
+ glEnable(GL_BLEND);
+
+ glColor4f(0,0,0,1-person[0].longdead);
+
+ glBegin(GL_QUADS);
+
+ glVertex3f(0, 0, 0.0f);
+
+ glVertex3f(256, 0, 0.0f);
+
+ glVertex3f(256, 256, 0.0f);
+
+ glVertex3f(0, 256, 0.0f);
+
+ glEnd();
+
+ glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
+
+ glPopMatrix(); // Restore The Old Projection Matrix
+
+ glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
+
+ glPopMatrix(); // Restore The Old Projection Matrix
+
+ glEnable(GL_DEPTH_TEST); // Enables Depth Testing
+
+ glEnable(GL_CULL_FACE);
+
+ glDisable(GL_BLEND);
+
+ glDepthMask(1);
+
+ }
+
+
+
+ //Text
+
+ glEnable(GL_TEXTURE_2D);
+
+ glColor4f(1,1,1,1);
+
+ static char string[256]="";
+
+ if(!debug){
+
+ if(person[0].whichgun==nogun)sprintf (string, "UNARMED");
+
+ if(person[0].whichgun==knife)sprintf (string, "KNIFE");
+
+ if(person[0].whichgun==assaultrifle)sprintf (string, "ASSAULT RIFLE");
+
+ if(person[0].whichgun==shotgun)sprintf (string, "SHOTGUN");
+
+ if(person[0].whichgun==sniperrifle)sprintf (string, "SNIPER RIFLE");
+
+ if(person[0].whichgun==grenade)sprintf (string, "HAND GRENADE");
+
+ if(person[0].whichgun==handgun1)sprintf (string, "MAGNUM");
+
+ if(person[0].whichgun==handgun2)sprintf (string, "HANDGUN");
+
+ text.glPrint(10,90,string,1,.8,640,480);
+
+ if(person[0].whichgun!=nogun&&person[0].whichgun!=knife&&person[0].whichgun!=grenade){
+
+ glColor4f(0,1,0,1);
+
+ sprintf (string, "Magazines");
+
+ text.glPrint(10,30,string,0,.8,640,480);
+
+ glColor4f(1,1,1,1);
+
+ sprintf (string, "0%d",(int)person[0].reloads[person[0].whichgun]);
+
+ text.glPrint(10,10,string,1,1,640,480);
+
+ if(person[0].ammo>=0){
+
+ glColor4f(0,1,0,1);
+
+ sprintf (string, "Ammo");
+
+ text.glPrint(10,65,string,0,.8,640,480);
+
+ glColor4f(1,1,1,1);
+
+ if(person[0].ammo>=10)sprintf (string, "%d",(int)person[0].ammo);
+
+ if(person[0].ammo<10)sprintf (string, "0%d",(int)person[0].ammo);
+
+ text.glPrint(10,40,string,1,1,640,480);
+
+ }
+
+ }
+
+ if(person[0].whichgun==grenade){
+
+ sprintf (string, "Grenades Left: %d",(int)person[0].reloads[person[0].whichgun]+1);
+
+ text.glPrint(10,20,string,0,.8,640,480);
+
+ }
+
+ glColor4f(1,1,0,1);
+
+ sprintf (string, "Score");
+
+ text.glPrint(725,575,string,0,.8,640,480);
+
+ glColor4f(1,1,1,1);
+
+ sprintf (string, "%d", score);
+
+ text.glPrint(580,440,string,1,1,640,480);
+
+
+
+ glColor4f(1,1,0,1);
+
+ sprintf (string, "Time Remaining");
+
+ text.glPrint(50,575,string,0,.8,640,480);
+
+ glColor4f(1,1,1,1);
+
+ if((int)timeremaining%60>=10)sprintf (string, "%d:%d", (int)(timeremaining/60),(int)timeremaining%60);
+
+ if((int)timeremaining%60<10)sprintf (string, "%d:0%d", (int)(timeremaining/60),(int)timeremaining%60);
+
+ text.glPrint(72.5,440,string,1,1,640,480);
+
+ }
+
+
+
+ if(debug){
+
+ sprintf (string, "The framespersecond is %d out of maximum %d.",(int)framespersecond+1,maxfps);
+
+ text.glPrint(10,30,string,0,.8,screenwidth,screenheight);
+
+ if(enemystate==0)sprintf (string, "Enemies are in random assassination mode.");
+
+ if(enemystate==1)sprintf (string, "Enemies are in passive mode.");
+
+ if(enemystate==2)sprintf (string, "Enemies are in DIE!!!! mode.");
+
+ text.glPrint(10,20,string,0,.8,screenwidth,screenheight);
+
+ sprintf (string, "You have pointlessly shot or beaten %d unarmed civilians.",civkills);
+
+ text.glPrint(10,60,string,0,.8,screenwidth,screenheight);
+
+ sprintf (string, "You have incapacitated %d assassins.",goodkills);
+
+ text.glPrint(10,70,string,0,.8,screenwidth,screenheight);
+
+ sprintf (string, "You have allowed %d successful murders.",badkills);
+
+ text.glPrint(10,80,string,0,.8,screenwidth,screenheight);
+
+ }
+
+ sprintf (string, "");
+
+ text.glPrint(10,80,string,0,.8,screenwidth,screenheight);
+
+ }
+
+} \ No newline at end of file
diff --git a/Source/GameInitDispose.cpp b/Source/GameInitDispose.cpp
new file mode 100644
index 0000000..23880a1
--- /dev/null
+++ b/Source/GameInitDispose.cpp
@@ -0,0 +1,3846 @@
+#include "Game.h"
+
+#include "ctype.h"
+
+
+
+extern unsigned int gSourceID[100];
+
+extern unsigned int gSampleSet[100];
+
+extern Camera camera;
+
+extern Skeleton testskeleton;
+
+extern Sprites sprites;
+
+extern Decals decals;
+
+/*********************> InitGame()<*****/
+
+extern Model skeletonmodels[10];
+
+extern Model gunmodels[10];
+
+extern Costume costume[10];
+
+extern Animation animation[30];
+
+extern int visions;
+
+extern float rad2deg;
+
+extern Fog fog;
+
+extern bool blood;
+
+extern float fogcolorr;
+
+extern float fogcolorg;
+
+extern float fogcolorb;
+
+extern int environment;
+
+extern float precipitationhorz;
+
+extern float precipitationvert;
+
+extern float precipitationdensity;
+
+extern float soundscalefactor;
+
+extern int slomo;
+
+
+
+extern int forwardskey;
+
+extern int backwardskey;
+
+extern int leftkey;
+
+extern int rightkey;
+
+extern int aimkey;
+
+extern int psychicaimkey;
+
+extern int psychickey;
+
+
+
+void LoadSounds(bool musictoggle);
+
+void LoadSounds(bool musictoggle)
+
+{
+
+ EventRecord EventRec;
+
+ char *pBuffer1;
+
+ long lBuffer1Len;
+
+ ALenum formatBuffer1;
+
+ ALsizei freqBuffer1;
+
+ FSSpec sfFile;
+
+ Str255 sFileName;
+
+ short fRefNum;
+
+ SInt16 iNumSources, iNumSampleSets;
+
+ // EAX test
+
+ unsigned long ulEAXVal;
+
+ long lGlobalReverb;
+
+
+
+ // initialize OpenAL
+
+ alutInit(NULL, 0);
+
+
+
+
+
+ // load up some audio data...
+
+ // generate ten OpenAL sample sets and two sources
+
+ iNumSources = 37;
+
+ iNumSampleSets = 37;
+
+ alGenSources(iNumSources, &gSourceID[0]);
+
+ alGenBuffers(iNumSampleSets, &gSampleSet[0]);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:underwater.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[visionsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[visionsound], AL_BUFFER, gSampleSet[visionsound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:soulin.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[soulinsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[soulinsound], AL_BUFFER, gSampleSet[soulinsound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:soulout.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[souloutsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[souloutsound], AL_BUFFER, gSampleSet[souloutsound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:footstep1.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[footstepsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[footstepsound], AL_BUFFER, gSampleSet[footstepsound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:footstep2.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[footstepsound+1], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[footstepsound+1], AL_BUFFER, gSampleSet[footstepsound+1]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:footstep3.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[footstepsound+2], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[footstepsound+2], AL_BUFFER, gSampleSet[footstepsound+2]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:footstep4.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[footstepsound+3], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[footstepsound+3], AL_BUFFER, gSampleSet[footstepsound+3]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:footstep5.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[footstepsound+4], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[footstepsound+4], AL_BUFFER, gSampleSet[footstepsound+4]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:bodyland.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[bodylandsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[bodylandsound], AL_BUFFER, gSampleSet[bodylandsound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:headland.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[headlandsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[headlandsound], AL_BUFFER, gSampleSet[headlandsound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:sniperrifle.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[riflesound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[riflesound], AL_BUFFER, gSampleSet[riflesound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:BodyHit.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[bodyhitsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[bodyhitsound], AL_BUFFER, gSampleSet[bodyhitsound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:WallHit.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[wallhitsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[wallhitsound], AL_BUFFER, gSampleSet[wallhitsound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:machinegun.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[machinegunsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[machinegunsound], AL_BUFFER, gSampleSet[machinegunsound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:Nearbullet.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[nearbulletsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[nearbulletsound], AL_BUFFER, gSampleSet[nearbulletsound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:riflewhack.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[headwhacksound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[headwhacksound], AL_BUFFER, gSampleSet[headwhacksound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:headshot.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[headshotsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[headshotsound], AL_BUFFER, gSampleSet[headshotsound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:reload.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[reloadsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[reloadsound], AL_BUFFER, gSampleSet[reloadsound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:click.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[clicksound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[clicksound], AL_BUFFER, gSampleSet[clicksound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:SW.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[pistol1sound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[pistol1sound], AL_BUFFER, gSampleSet[pistol1sound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:glock.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[pistol2sound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[pistol2sound], AL_BUFFER, gSampleSet[pistol2sound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:pinpull.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[pinpullsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[pinpullsound], AL_BUFFER, gSampleSet[pinpullsound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:pinreplace.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[pinreplacesound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[pinreplacesound], AL_BUFFER, gSampleSet[pinreplacesound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:handlerelease.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[grenadethrowsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[grenadethrowsound], AL_BUFFER, gSampleSet[grenadethrowsound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:bounce.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[bouncesound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[bouncesound], AL_BUFFER, gSampleSet[bouncesound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:bounce2.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[bounce2sound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[bounce2sound], AL_BUFFER, gSampleSet[bounce2sound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:explosion.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[explosionsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[explosionsound], AL_BUFFER, gSampleSet[explosionsound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:headland.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[bodywhacksound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[bodywhacksound], AL_BUFFER, gSampleSet[bodywhacksound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:rain.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[rainsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[rainsound], AL_BUFFER, gSampleSet[rainsound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:Lose.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[losesound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[losesound], AL_BUFFER, gSampleSet[losesound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:Disguisekill.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[disguisekillsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[disguisekillsound], AL_BUFFER, gSampleSet[disguisekillsound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:knifeslash.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[knifeslashsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[knifeslashsound], AL_BUFFER, gSampleSet[knifeslashsound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:shotgun.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[shotgunsound], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[shotgunsound], AL_BUFFER, gSampleSet[shotgunsound]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ if(musictoggle){
+
+ alutLoadWAVFile((char *)":Data:Sounds:mainmenusong.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[mainmenusong], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[mainmenusong], AL_BUFFER, gSampleSet[mainmenusong]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:shootsong.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[shootsong], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[shootsong], AL_BUFFER, gSampleSet[shootsong]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:zombiesong.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[zombiesong], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[zombiesong], AL_BUFFER, gSampleSet[zombiesong]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+
+
+ alutLoadWAVFile((char *)":Data:Sounds:knifesong.wav",&formatBuffer1, (void **) &pBuffer1,(unsigned int *)&lBuffer1Len,&freqBuffer1);
+
+ alBufferData(gSampleSet[knifesong], formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ alSourcei(gSourceID[knifesong], AL_BUFFER, gSampleSet[knifesong]);
+
+ alutUnloadWAV(formatBuffer1, pBuffer1, lBuffer1Len, freqBuffer1);
+
+ }
+
+
+
+ float gLoc[3];
+
+
+
+ gLoc[0]=0;
+
+ gLoc[1]=0;
+
+ gLoc[2]=0;
+
+
+
+ alSourcefv(gSourceID[visionsound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[visionsound], AL_LOOPING, 1);
+
+ alSourcef(gSourceID[visionsound], AL_MIN_GAIN, 1);
+
+
+
+ alSourcefv(gSourceID[soulinsound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[soulinsound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[soulinsound], AL_MIN_GAIN, 1);
+
+
+
+ alSourcefv(gSourceID[souloutsound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[souloutsound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[souloutsound], AL_MIN_GAIN, 1);
+
+
+
+ for(int i=0;i<5;i++){
+
+ alSourcefv(gSourceID[footstepsound+i], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[footstepsound+i], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[footstepsound+i], AL_MIN_GAIN, 0);
+
+ }
+
+
+
+ alSourcefv(gSourceID[bodylandsound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[bodylandsound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[bodylandsound], AL_MIN_GAIN, 0);
+
+
+
+ alSourcefv(gSourceID[headlandsound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[headlandsound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[headlandsound], AL_MIN_GAIN, 0);
+
+
+
+ alSourcefv(gSourceID[riflesound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[riflesound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[riflesound], AL_MIN_GAIN, 0);
+
+
+
+ alSourcefv(gSourceID[bodyhitsound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[bodyhitsound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[bodyhitsound], AL_MIN_GAIN, .1);
+
+
+
+ alSourcefv(gSourceID[wallhitsound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[wallhitsound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[wallhitsound], AL_MIN_GAIN, 0);
+
+ alSourcef(gSourceID[wallhitsound], AL_MAX_GAIN, .6);
+
+
+
+ alSourcefv(gSourceID[machinegunsound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[machinegunsound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[machinegunsound], AL_MIN_GAIN,0);
+
+
+
+ alSourcefv(gSourceID[nearbulletsound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[nearbulletsound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[nearbulletsound], AL_MIN_GAIN,0);
+
+
+
+ alSourcefv(gSourceID[headwhacksound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[headwhacksound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[headwhacksound], AL_MIN_GAIN,0);
+
+
+
+ alSourcefv(gSourceID[headshotsound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[headshotsound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[headshotsound], AL_MIN_GAIN, 0);
+
+
+
+ alSourcefv(gSourceID[reloadsound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[reloadsound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[reloadsound], AL_MIN_GAIN, 0);
+
+
+
+ alSourcefv(gSourceID[clicksound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[clicksound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[clicksound], AL_MIN_GAIN, 0);
+
+
+
+ alSourcefv(gSourceID[pistol1sound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[pistol1sound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[pistol1sound], AL_MIN_GAIN, 0);
+
+
+
+ alSourcefv(gSourceID[pistol2sound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[pistol2sound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[pistol2sound], AL_MIN_GAIN, 0);
+
+
+
+ alSourcefv(gSourceID[pinpullsound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[pinpullsound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[pinpullsound], AL_MIN_GAIN,0);
+
+
+
+ alSourcefv(gSourceID[pinreplacesound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[pinreplacesound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[pinreplacesound], AL_MIN_GAIN,0);
+
+
+
+ alSourcefv(gSourceID[grenadethrowsound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[grenadethrowsound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[grenadethrowsound], AL_MIN_GAIN,0);
+
+
+
+ alSourcefv(gSourceID[bouncesound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[bouncesound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[bouncesound], AL_MIN_GAIN,0);
+
+
+
+ alSourcefv(gSourceID[bounce2sound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[bounce2sound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[bounce2sound], AL_MIN_GAIN,0);
+
+
+
+ alSourcefv(gSourceID[explosionsound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[explosionsound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[explosionsound], AL_MIN_GAIN,0);
+
+
+
+ alSourcefv(gSourceID[bodywhacksound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[bodywhacksound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[bodywhacksound], AL_MIN_GAIN, 0);
+
+
+
+ alSourcefv(gSourceID[rainsound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[rainsound], AL_LOOPING, 1);
+
+ alSourcef(gSourceID[rainsound], AL_MIN_GAIN, .3);
+
+
+
+ alSourcefv(gSourceID[losesound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[losesound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[losesound], AL_MIN_GAIN, 1);
+
+
+
+ alSourcefv(gSourceID[disguisekillsound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[disguisekillsound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[disguisekillsound], AL_MIN_GAIN, 1);
+
+
+
+ alSourcefv(gSourceID[knifeslashsound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[knifeslashsound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[knifeslashsound], AL_MIN_GAIN,0);
+
+
+
+ alSourcefv(gSourceID[shotgunsound], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[shotgunsound], AL_LOOPING, 0);
+
+ alSourcef(gSourceID[shotgunsound], AL_MIN_GAIN, 0);
+
+
+
+ alSourcefv(gSourceID[knifesong], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[knifesong], AL_LOOPING, 1);
+
+ alSourcef(gSourceID[knifesong], AL_MIN_GAIN, 1);
+
+
+
+ alSourcefv(gSourceID[mainmenusong], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[mainmenusong], AL_LOOPING, 1);
+
+ alSourcef(gSourceID[mainmenusong], AL_MIN_GAIN, 1);
+
+
+
+ alSourcefv(gSourceID[zombiesong], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[zombiesong], AL_LOOPING, 1);
+
+ alSourcef(gSourceID[zombiesong], AL_MIN_GAIN, 1);
+
+
+
+ alSourcefv(gSourceID[shootsong], AL_POSITION, gLoc);
+
+ alSourcei(gSourceID[shootsong], AL_LOOPING, 1);
+
+ alSourcef(gSourceID[shootsong], AL_MIN_GAIN, 1);
+
+
+
+
+
+}
+
+
+
+void Game::LoadingScreen(float percent)
+
+{
+
+ float size=1;
+
+ glLoadIdentity();
+
+ //Clear to black
+
+ glClearColor(0,0,0,1);
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+
+
+ //Background
+
+
+
+ glDisable(GL_TEXTURE_2D);
+
+ glDisable(GL_DEPTH_TEST); // Disables Depth Testing
+
+ glDisable(GL_CULL_FACE);
+
+ glDisable(GL_LIGHTING);
+
+ glDepthMask(0);
+
+ glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
+
+ glPushMatrix(); // Store The Projection Matrix
+
+ glLoadIdentity(); // Reset The Projection Matrix
+
+ glOrtho(0,640,0,480,-100,100); // Set Up An Ortho Screen
+
+ glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
+
+ glPushMatrix(); // Store The Modelview Matrix
+
+ for(int i=19;i>=0;i--){
+
+ glLoadIdentity(); // Reset The Modelview Matrix
+
+ glTranslatef(120-i*1,190-i*1,0);
+
+ glScalef(400+i*2,30+i*2,1);
+
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+
+ glEnable(GL_BLEND);
+
+ if(i)glColor4f(1-(float)i/20-percent/100,1-(float)i/20-percent/100,1-(float)i/20-percent/100,1);
+
+ if(!i)glColor4f(0,0,0,1);
+
+ glBegin(GL_QUADS);
+
+ glVertex3f(0, 0, 0.0f);
+
+ glVertex3f(1, 0, 0.0f);
+
+ glVertex3f(1, 1, 0.0f);
+
+ glVertex3f(0, 1, 0.0f);
+
+ glEnd();
+
+ }
+
+ glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
+
+ glPopMatrix(); // Restore The Old Projection Matrix
+
+ glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
+
+ glPopMatrix(); // Restore The Old Projection Matrix
+
+ glDisable(GL_BLEND);
+
+ glDepthMask(1);
+
+
+
+ //Progress
+
+
+
+ glDisable(GL_DEPTH_TEST); // Disables Depth Testing
+
+ glDisable(GL_CULL_FACE);
+
+ glDisable(GL_LIGHTING);
+
+ glDisable(GL_TEXTURE_2D);
+
+ glDepthMask(0);
+
+ glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
+
+ glPushMatrix(); // Store The Projection Matrix
+
+ glLoadIdentity(); // Reset The Projection Matrix
+
+ glOrtho(0,640,0,480,-100,100); // Set Up An Ortho Screen
+
+ glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
+
+ glPushMatrix(); // Store The Modelview Matrix
+
+ for(int i=19;i>=0;i--){
+
+ glLoadIdentity(); // Reset The Modelview Matrix
+
+ glTranslatef(120,190,0);
+
+ if(4*percent+i*2<400)glScalef(4*percent+i*2,30,1);
+
+ if(4*percent+i*2>=400)glScalef(400,30,1);
+
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+
+ glEnable(GL_BLEND);
+
+ glColor4f(1,0,0,.1);
+
+ glBegin(GL_QUADS);
+
+ glVertex3f(0, 0, 0.0f);
+
+ glVertex3f(1, 0, 0.0f);
+
+ glVertex3f(1, 1, 0.0f);
+
+ glVertex3f(0, 1, 0.0f);
+
+ glEnd();
+
+ }
+
+ glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
+
+ glPopMatrix(); // Restore The Old Projection Matrix
+
+ glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
+
+ glPopMatrix(); // Restore The Old Projection Matrix
+
+ glDisable(GL_BLEND);
+
+ glDepthMask(1);
+
+
+
+ //Text
+
+
+
+ glEnable(GL_TEXTURE_2D);
+
+ glColor4f(.6-.6*percent/100,0,0,1);
+
+ static char string[256]="";
+
+ sprintf (string, "LOADING...");
+
+ text.glPrint(280,195,string,1,1,640,480);
+
+
+
+
+
+ aglSwapBuffers( gOpenGLContext );
+
+}
+
+
+
+void LoadPersonSpriteTexture(char *fileName, GLuint *textureid);
+
+void LoadPersonSpriteTexture(char *fileName, GLuint *textureid)
+
+{
+
+ TGAImageRec *tempTexture;
+
+ GLuint type;
+
+
+
+ //Load Image
+
+ tempTexture = LoadTGA( fileName );
+
+ //Is it valid?
+
+ if(tempTexture){
+
+ //Alpha channel?
+
+ if ( tempTexture->bpp == 24 )
+
+ type = GL_RGB;
+
+ else
+
+ type = GL_RGBA;
+
+
+
+ glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
+
+
+
+ glGenTextures( 1, textureid );
+
+ glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+
+
+
+ glBindTexture( GL_TEXTURE_2D, *textureid);
+
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+
+
+
+ gluBuild2DMipmaps( GL_TEXTURE_2D, type, tempTexture->sizeX, tempTexture->sizeY, type, GL_UNSIGNED_BYTE, tempTexture->data );
+
+ free( tempTexture->data );
+
+ free( tempTexture );
+
+ }
+
+}
+
+
+
+void Game::InitGame()
+
+{
+
+ //Setup loading screen
+
+ float loadingscreenamount=0;
+
+ float loadingscreenamounttotal=200;
+
+ if(initialized)loadingscreenamounttotal=20;
+
+
+
+ if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+
+
+
+ //Set up rain and snow
+
+ precipitationhorz=60;
+
+ precipitationvert=40;
+
+ precipitationdensity=25;
+
+
+
+ //Bodyguard stats
+
+ person[0].playercoords=camera.position;
+
+ person[0].oldplayercoords=person[0].playercoords;
+
+ person[0].type=playertype;
+
+ person[0].existing=1;
+
+ for(int i=0;i<10;i++){
+
+ person[0].reloads[i]=0;
+
+ }
+
+
+
+ //Level setup
+
+ killedinnocent=0; //Haven't shot any civilians yet...
+
+
+
+ if(customlevels){ //Load custom levels
+
+ nummissions=1; //Default level in case of load failure
+
+ type=randomshoot_type;
+
+ possiblegun[0]=handgun1;
+
+ possiblegun[1]=handgun2;
+
+ possiblegun[2]=shotgun;
+
+ numpossibleguns=3;
+
+ evilprobability=6;
+
+ person[0].whichgun=knife;
+
+ person[0].reloads[person[0].whichgun]=6;
+
+ if(!gameinprogress)score=0;
+
+ timeremaining=50;
+
+ difficulty=.8;
+
+ ifstream ipstream(":Data:customlevels.txt");
+
+ if(!ipstream) {
+
+ customlevels=0;
+
+ }
+
+ if(ipstream){
+
+ ipstream.ignore(256,'\n');//ignore descriptive text
+
+ ipstream >> nummissions;
+
+ for(int j=0;j<mission+1;j++){
+
+ ipstream.ignore(256,'\n');
+
+ ipstream.ignore(256,'\n');
+
+ ipstream >> type;
+
+ ipstream.ignore(256,'\n');
+
+ ipstream.ignore(256,'\n');
+
+ ipstream >> environment;
+
+ ipstream.ignore(256,'\n');
+
+ ipstream.ignore(256,'\n');
+
+ ipstream >> numpossibleguns;
+
+ ipstream.ignore(256,'\n');
+
+ ipstream.ignore(256,'\n');
+
+ for(int i=0;i<numpossibleguns;i++){
+
+ ipstream >> possiblegun[i];
+
+ }
+
+ ipstream.ignore(256,'\n');
+
+ ipstream.ignore(256,'\n');
+
+ ipstream >> evilprobability;
+
+ ipstream.ignore(256,'\n');
+
+ ipstream.ignore(256,'\n');
+
+ ipstream >> person[0].whichgun;
+
+ ipstream.ignore(256,'\n');
+
+ ipstream.ignore(256,'\n');
+
+ ipstream >> person[0].reloads[person[0].whichgun];
+
+ ipstream.ignore(256,'\n');
+
+ ipstream.ignore(256,'\n');
+
+ ipstream >> timeremaining;
+
+ ipstream.ignore(256,'\n');
+
+ ipstream.ignore(256,'\n');
+
+ ipstream >> difficulty;
+
+ ipstream.ignore(256,'\n');
+
+ }
+
+ ipstream.close();
+
+ }
+
+ }
+
+
+
+ if(!customlevels){ //Setup hardcoded default levels
+
+ if(mission==0){
+
+ environment=sunny_environment;
+
+ type=randomshoot_type;
+
+ possiblegun[0]=handgun1;
+
+ possiblegun[1]=handgun2;
+
+ possiblegun[2]=shotgun;
+
+ numpossibleguns=3;
+
+ evilprobability=6;
+
+ person[0].whichgun=assaultrifle;
+
+ person[0].reloads[person[0].whichgun]=6;
+
+ if(!gameinprogress)score=0;
+
+ timeremaining=50;
+
+ difficulty=.6;
+
+ }
+
+ if(mission==1){
+
+ environment=snowy_environment;
+
+ type=randomshoot_type;
+
+ possiblegun[0]=knife;
+
+ possiblegun[1]=assaultrifle;
+
+ numpossibleguns=2;
+
+ evilprobability=5;
+
+ person[0].whichgun=handgun2;
+
+ person[0].reloads[person[0].whichgun]=3;
+
+ if(!gameinprogress)score=0;
+
+ timeremaining=40;
+
+ difficulty=.6;
+
+ }
+
+ if(mission==2){
+
+ environment=foggy_environment;
+
+ type=randomshoot_type;
+
+ possiblegun[0]=sniperrifle;
+
+ numpossibleguns=1;
+
+ evilprobability=5;
+
+ person[0].whichgun=sniperrifle;
+
+ person[0].reloads[person[0].whichgun]=4;
+
+ if(!gameinprogress)score=0;
+
+ timeremaining=50;
+
+ difficulty=0.9;
+
+ }
+
+ if(mission==3){
+
+ environment=firey_environment;
+
+ type=zombie_type;
+
+ numpossibleguns=0;
+
+ evilprobability=5;
+
+ person[0].whichgun=shotgun;
+
+ person[0].reloads[person[0].whichgun]=5;
+
+ if(!gameinprogress)score=0;
+
+ timeremaining=35;
+
+ difficulty=.7;
+
+ }
+
+ if(mission==4){
+
+ environment=snowy_environment;
+
+ type=randomshoot_type;
+
+ possiblegun[0]=sniperrifle;
+
+ possiblegun[1]=assaultrifle;
+
+ numpossibleguns=2;
+
+ evilprobability=5;
+
+ person[0].whichgun=grenade;
+
+ person[0].reloads[person[0].whichgun]=20;
+
+ if(!gameinprogress)score=0;
+
+ timeremaining=30;
+
+ difficulty=.5;
+
+ }
+
+ if(mission==5){
+
+ environment=rainy_environment;
+
+ type=randomshoot_type;
+
+ possiblegun[0]=handgun1;
+
+ possiblegun[1]=shotgun;
+
+ possiblegun[2]=assaultrifle;
+
+ numpossibleguns=3;
+
+ evilprobability=6;
+
+ person[0].whichgun=knife;
+
+ person[0].reloads[person[0].whichgun]=3;
+
+ if(!gameinprogress)score=0;
+
+ timeremaining=40;
+
+ difficulty=.8;
+
+ }
+
+ if(mission==6){
+
+ environment=night_environment;
+
+ type=randomshoot_type;
+
+ possiblegun[1]=handgun1;
+
+ possiblegun[2]=handgun2;
+
+ possiblegun[3]=shotgun;
+
+ numpossibleguns=3;
+
+ evilprobability=5;
+
+ person[0].whichgun=handgun1;
+
+ person[0].reloads[person[0].whichgun]=4;
+
+ if(!gameinprogress)score=0;
+
+ timeremaining=30;
+
+ difficulty=1;
+
+ }
+
+ if(mission==7){
+
+ environment=firey_environment;
+
+ type=zombie_type;
+
+ person[0].whichgun=assaultrifle;
+
+ person[0].reloads[person[0].whichgun]=5;
+
+ if(!gameinprogress)score=0;
+
+ timeremaining=30;
+
+ difficulty=1;
+
+ }
+
+ if(mission==8){
+
+ environment=rainy_environment;
+
+ type=randomshoot_type;
+
+ possiblegun[0]=handgun1;
+
+ possiblegun[1]=handgun2;
+
+ possiblegun[2]=shotgun;
+
+ possiblegun[3]=sniperrifle;
+
+ possiblegun[4]=assaultrifle;
+
+ numpossibleguns=5;
+
+ evilprobability=5;
+
+ person[0].whichgun=nogun;
+
+ person[0].reloads[person[0].whichgun]=3;
+
+ if(!gameinprogress)score=0;
+
+ timeremaining=40;
+
+ difficulty=.8;
+
+ }
+
+ if(mission==9){
+
+ environment=snowy_environment;
+
+ type=randomshoot_type;
+
+ possiblegun[0]=knife;
+
+ possiblegun[1]=handgun1;
+
+ possiblegun[2]=handgun2;
+
+ possiblegun[3]=shotgun;
+
+ possiblegun[4]=sniperrifle;
+
+ possiblegun[5]=assaultrifle;
+
+ numpossibleguns=6;
+
+ evilprobability=4;
+
+ person[0].whichgun=handgun1;
+
+ person[0].reloads[person[0].whichgun]=3;
+
+ if(!gameinprogress)score=0;
+
+ timeremaining=90;
+
+ difficulty=1;
+
+ }
+
+ if(mission==10){
+
+ environment=night_environment;
+
+ type=randomshoot_type;
+
+ possiblegun[0]=sniperrifle;
+
+ numpossibleguns=1;
+
+ evilprobability=5;
+
+ person[0].whichgun=sniperrifle;
+
+ person[0].reloads[person[0].whichgun]=4;
+
+ if(!gameinprogress)score=0;
+
+ timeremaining=30;
+
+ difficulty=1.3;
+
+ }
+
+ if(mission==11){
+
+ environment=sunny_environment;
+
+ type=randomshoot_type;
+
+ possiblegun[0]=knife;
+
+ possiblegun[1]=sniperrifle;
+
+ numpossibleguns=2;
+
+ evilprobability=4;
+
+ person[0].whichgun=knife;
+
+ if(!gameinprogress)score=0;
+
+ timeremaining=30;
+
+ difficulty=1.5;
+
+ }
+
+ if(mission==12){
+
+ environment=firey_environment;
+
+ type=zombie_type;
+
+ possiblegun[0]=knife;
+
+ possiblegun[1]=sniperrifle;
+
+ person[0].whichgun=handgun2;
+
+ person[0].reloads[person[0].whichgun]=10;
+
+ if(!gameinprogress)score=0;
+
+ timeremaining=60;
+
+ difficulty=1.5;
+
+ }
+
+
+
+ nummissions=13;
+
+ }
+
+
+
+ //Setup fast radian to degree conversion
+
+ rad2deg= 56.54866776;
+
+ visions=0;
+
+
+
+ //Setup bounding cylinder model
+
+ float boundingscale=3;
+
+
+
+ if(!initialized){
+
+ boundingpoints[0]=0;
+
+ boundingpoints[0].z=boundingscale;
+
+ boundingpoints[0].y=0;
+
+ for(int i=1;i<8;i++){
+
+ boundingpoints[i]=DoRotation(boundingpoints[0],0,i*360/7,0);
+
+ }
+
+ }
+
+ civkills=0;
+
+ badkills=0;
+
+ goodkills=0;
+
+ enemystate=2;
+
+
+
+ if(!initialized){
+
+ if(!azertykeyboard){
+
+ forwardskey=MAC_W_KEY;
+
+ backwardskey=MAC_S_KEY;
+
+ leftkey=MAC_A_KEY;
+
+ rightkey=MAC_D_KEY;
+
+ aimkey=MAC_Q_KEY;
+
+ psychicaimkey=MAC_E_KEY;
+
+ psychickey=MAC_Z_KEY;
+
+ }
+
+
+
+ if(azertykeyboard){
+
+ forwardskey=MAC_Z_KEY;
+
+ backwardskey=MAC_S_KEY;
+
+ leftkey=MAC_Q_KEY;
+
+ rightkey=MAC_D_KEY;
+
+ aimkey=MAC_A_KEY;
+
+ psychicaimkey=MAC_E_KEY;
+
+ psychickey=MAC_W_KEY;
+
+ }
+
+
+
+ soundscalefactor=soundscalefactordefault; //Setup sound falloff
+
+
+
+ gQuit=false;
+
+
+
+ //Sounds
+
+ LoadSounds(musictoggle);
+
+ //Play correct song
+
+ if(environment==rainy_environment)alSourcePlay(gSourceID[rainsound]);
+
+ if(environment!=rainy_environment)alSourcePause(gSourceID[rainsound]);
+
+ alSourceStop(gSourceID[whichsong]);
+
+ alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 0);
+
+ alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 0);
+
+ whichsong=mainmenusong;
+
+ alSourceStop(gSourceID[whichsong]);
+
+ alSourcef(gSourceID[whichsong], AL_PITCH, 1);
+
+ alSourcePlay(gSourceID[whichsong]);
+
+ alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1);
+
+ alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1);
+
+ }
+
+
+
+ loadingscreenamount+=5;
+
+ if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+
+
+
+ //Setup random seed
+
+ qd.randSeed = TickCount();
+
+ gamespeed=1;
+
+
+
+ //Setup camera
+
+ camera.position=0;
+
+ camera.position.x=num_blocks/2*block_spacing+block_spacing/2;
+
+ camera.position.z=num_blocks/2*block_spacing+block_spacing/2;
+
+ camera.position.y=30;
+
+ camera.oldposition=camera.position;
+
+ numpeople=1;
+
+
+
+ //Setup path to walk around blocks
+
+ path.load((unsigned char *)":Data:Models:path.solid");
+
+ path.Rotate(90,0,0);
+
+ path.Scale(.8,.8,.8);
+
+ path.CalculateNormals();
+
+
+
+ loadingscreenamount+=5;
+
+ if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+
+
+
+ person[0].speedmult=1.3;
+
+
+
+ //Add vip
+
+ person[numpeople].playerrotation=0;
+
+
+
+ person[numpeople].whichcostume=vipcostume;
+
+
+
+ person[numpeople].whichblockx=((person[0].playercoords.x+block_spacing/2)/block_spacing);
+
+ person[numpeople].whichblocky=((person[0].playercoords.x+block_spacing/2)/block_spacing);
+
+
+
+ person[numpeople].pathnum=-1;
+
+ person[numpeople].oldpathnum=-1;
+
+ person[numpeople].oldoldpathnum=-1;
+
+ person[numpeople].oldoldoldpathnum=-1;
+
+ while(person[numpeople].pathnum<0||person[numpeople].pathnum>=path.vertexNum||person[numpeople].pathnum==1){
+
+ person[numpeople].pathnum=Random()%path.vertexNum;
+
+ }
+
+ person[numpeople].pathtarget.x=path.vertex[person[numpeople].pathnum].x;
+
+ person[numpeople].pathtarget.z=path.vertex[person[numpeople].pathnum].z;
+
+ person[numpeople].pathsize=.98+float(abs(Random()%20))/400;
+
+ person[numpeople].pathtarget*=person[numpeople].pathsize;
+
+ person[numpeople].pathtarget.x+=person[numpeople].whichblockx*block_spacing;
+
+ person[numpeople].pathtarget.z+=person[numpeople].whichblocky*block_spacing;
+
+
+
+
+
+ person[numpeople].playercoords=person[numpeople].pathtarget;
+
+ person[numpeople].oldplayercoords=person[numpeople].playercoords;
+
+
+
+ person[0].playercoords=person[numpeople].playercoords;
+
+ person[0].playercoords.x+=1;
+
+ person[0].playercoords.z+=1;
+
+ person[0].oldplayercoords=person[0].playercoords;
+
+
+
+ person[numpeople].skeleton.free=0;
+
+
+
+ person[numpeople].targetanimation=walkanim;
+
+ person[numpeople].speed=1;
+
+ person[numpeople].existing=0;
+
+ person[numpeople].speedmult=1;
+
+ if(type==zombie_type)person[numpeople].speedmult=.8;
+
+ person[numpeople].health=100;
+
+ person[numpeople].playerrotation2=0;//20;
+
+
+
+ person[numpeople].lastdistancevictim=200000;
+
+
+
+ if(person[numpeople].skeleton.broken)person[numpeople].skeleton.Load((char *)":Data:Skeleton:Basic Figure");
+
+
+
+ person[numpeople].type=viptype;
+
+ person[numpeople].whichgun=nogun; person[numpeople].aiming=0; person[numpeople].killtarget=-1;
+
+ person[numpeople].existing=1;
+
+
+
+ citypeoplenum[person[numpeople].whichblockx][person[numpeople].whichblocky]++;
+
+ numpeople++;
+
+ spawndelay=.1;
+
+
+
+ XYZ vipdistance;
+
+ vipdistance=0;
+
+ vipdistance.x=10000000;
+
+ vipgoal=person[1].playercoords+DoRotation(vipdistance,0,Random()%360,0);
+
+
+
+ //Setup block models
+
+ if(!initialized){
+
+ blocks[0].load((unsigned char *)":Data:Models:Block1.solid");
+
+ blocks[0].Rotate(90,0,0);
+
+ blocks[0].Scale(.8,.8,.8);
+
+ blocks[0].CalculateNormals();
+
+
+
+ blocks[1].load((unsigned char *)":Data:Models:Block2.solid");
+
+ blocks[1].Rotate(90,0,0);
+
+ blocks[1].Scale(.8,.8,.8);
+
+ blocks[1].CalculateNormals();
+
+
+
+ loadingscreenamount+=5;
+
+ if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+
+
+
+ blocks[2].load((unsigned char *)":Data:Models:Block3.solid");
+
+ blocks[2].Rotate(90,0,0);
+
+ blocks[2].Scale(.8,.8,.8);
+
+ blocks[2].CalculateNormals();
+
+
+
+ blocks[3].load((unsigned char *)":Data:Models:Block4.solid");
+
+ blocks[3].Rotate(90,0,0);
+
+ blocks[3].Scale(.8,.8,.8);
+
+ blocks[3].CalculateNormals();
+
+
+
+ loadingscreenamount+=5;
+
+ if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+
+
+
+ sidewalkcollide.load((unsigned char *)":Data:Models:Lowheightcollide.solid");
+
+ sidewalkcollide.Rotate(90,0,0);
+
+ sidewalkcollide.Scale(.8,.8,.8);
+
+ sidewalkcollide.CalculateNormals();
+
+
+
+ blockwalls[0].load((unsigned char *)":Data:Models:Block1collide.solid");
+
+ blockwalls[0].Rotate(90,0,0);
+
+ blockwalls[0].Scale(.8,.75,.8);
+
+ blockwalls[0].CalculateNormals();
+
+
+
+ blockwalls[1].load((unsigned char *)":Data:Models:Block2collide.solid");
+
+ blockwalls[1].Rotate(90,0,0);
+
+ blockwalls[1].Scale(.8,.75,.8);
+
+ blockwalls[1].CalculateNormals();
+
+
+
+ blockwalls[2].load((unsigned char *)":Data:Models:Block3collide.solid");
+
+ blockwalls[2].Rotate(90,0,0);
+
+ blockwalls[2].Scale(.8,.75,.8);
+
+ blockwalls[2].CalculateNormals();
+
+
+
+ blockwalls[3].load((unsigned char *)":Data:Models:Block4collide.solid");
+
+ blockwalls[3].Rotate(90,0,0);
+
+ blockwalls[3].Scale(.8,.75,.8);
+
+ blockwalls[3].CalculateNormals();
+
+
+
+ loadingscreenamount+=5;
+
+ if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+
+
+
+ blockroofs[0].load((unsigned char *)":Data:Models:Highblock1collide.solid");
+
+ blockroofs[0].Rotate(90,0,0);
+
+ blockroofs[0].Scale(.8,.8,.8);
+
+ blockroofs[0].CalculateNormals();
+
+
+
+ blockroofs[1].load((unsigned char *)":Data:Models:Highblock2collide.solid");
+
+ blockroofs[1].Rotate(90,0,0);
+
+ blockroofs[1].Scale(.8,.8,.8);
+
+ blockroofs[1].CalculateNormals();
+
+
+
+ blockroofs[2].load((unsigned char *)":Data:Models:Highblock3collide.solid");
+
+ blockroofs[2].Rotate(90,0,0);
+
+ blockroofs[2].Scale(.8,.8,.8);
+
+ blockroofs[2].CalculateNormals();
+
+
+
+ blockroofs[3].load((unsigned char *)":Data:Models:Highblock4collide.solid");
+
+ blockroofs[3].Rotate(90,0,0);
+
+ blockroofs[3].Scale(.8,.8,.8);
+
+ blockroofs[3].CalculateNormals();
+
+
+
+ blockcollide[0].load((unsigned char *)":Data:Models:block1complete.solid");
+
+ blockcollide[0].Rotate(90,0,0);
+
+ blockcollide[0].Scale(.8,.8,.8);
+
+ blockcollide[0].CalculateNormals();
+
+
+
+ blockcollide[1].load((unsigned char *)":Data:Models:block2complete.solid");
+
+ blockcollide[1].Rotate(90,0,0);
+
+ blockcollide[1].Scale(.8,.8,.8);
+
+ blockcollide[1].CalculateNormals();
+
+
+
+ blockcollide[2].load((unsigned char *)":Data:Models:block3complete.solid");
+
+ blockcollide[2].Rotate(90,0,0);
+
+ blockcollide[2].Scale(.8,.8,.8);
+
+ blockcollide[2].CalculateNormals();
+
+
+
+ blockcollide[3].load((unsigned char *)":Data:Models:block4complete.solid");
+
+ blockcollide[3].Rotate(90,0,0);
+
+ blockcollide[3].Scale(.8,.8,.8);
+
+ blockcollide[3].CalculateNormals();
+
+
+
+ loadingscreenamount+=5;
+
+ if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+
+
+
+
+
+ blocksimplecollide[0].load((unsigned char *)":Data:Models:lowsimplecollide1.solid");
+
+ blocksimplecollide[0].Rotate(90,0,0);
+
+ blocksimplecollide[0].Scale(.8,.8,.8);
+
+ blocksimplecollide[0].CalculateNormals();
+
+
+
+ blocksimplecollide[1].load((unsigned char *)":Data:Models:lowsimplecollide2.solid");
+
+ blocksimplecollide[1].Rotate(90,0,0);
+
+ blocksimplecollide[1].Scale(.8,.8,.8);
+
+ blocksimplecollide[1].CalculateNormals();
+
+
+
+ blocksimplecollide[2].load((unsigned char *)":Data:Models:lowsimplecollide3.solid");
+
+ blocksimplecollide[2].Rotate(90,0,0);
+
+ blocksimplecollide[2].Scale(.8,.8,.8);
+
+ blocksimplecollide[2].CalculateNormals();
+
+
+
+ blocksimplecollide[3].load((unsigned char *)":Data:Models:lowsimplecollide4.solid");
+
+ blocksimplecollide[3].Rotate(90,0,0);
+
+ blocksimplecollide[3].Scale(.8,.8,.8);
+
+ blocksimplecollide[3].CalculateNormals();
+
+
+
+ loadingscreenamount+=5;
+
+ if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+
+
+
+ blockocclude.load((unsigned char *)":Data:Models:blockocclude.solid");
+
+ blockocclude.Rotate(90,0,0);
+
+ blockocclude.Scale(.8,.8,.8);
+
+ blockocclude.CalculateNormals();
+
+
+
+ blocksimple.load((unsigned char *)":Data:Models:blocksimple.solid");
+
+ blocksimple.Rotate(90,0,0);
+
+ blocksimple.Scale(.8,2,.8);
+
+ blocksimple.CalculateNormals();
+
+
+
+ street.load((unsigned char *)":Data:Models:streetsubdivided2.solid");
+
+ street.Rotate(90,0,0);
+
+ street.Scale(.01,.01,.01);
+
+ street.CalculateNormals();
+
+
+
+ Bigstreet=street;
+
+ Bigstreet.Scale(10000,10000,10000);
+
+
+
+ loadingscreenamount+=5;
+
+ if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+
+
+
+ path.load((unsigned char *)":Data:Models:path.solid");
+
+ path.Rotate(90,0,0);
+
+ path.Scale(.8,.8,.8);
+
+ path.CalculateNormals();
+
+
+
+ //Fix block radius
+
+ for(int i=0;i<4;i++){
+
+ blocks[i].boundingspherecenter.x=0;
+
+ blocks[i].boundingspherecenter.z=0;
+
+ blocks[i].boundingsphereradius=0;
+
+ for(int i=0;i<blocks[i].vertexNum;i++){
+
+ if(findDistancefast(blocks[i].boundingspherecenter,blocks[i].vertex[i])>blocks[i].boundingsphereradius)blocks[i].boundingsphereradius=findDistancefast(blocks[i].boundingspherecenter,blocks[i].vertex[i]);
+
+ }
+
+ blocks[i].boundingsphereradius=sqrt(blocks[i].boundingsphereradius);
+
+ }
+
+ }
+
+ mousesensitivity=1;
+
+
+
+ //init city block rotations
+
+ for(int i=0;i<num_blocks;i++){
+
+ for(int j=0;j<num_blocks;j++){
+
+ cityrotation[i][j]=Random()%4;
+
+ citytype[i][j]=Random()%4;
+
+ citypeoplenum[i][j]=0;
+
+ if(citytype[i][j]<0)citytype[i][j]=0;
+
+ if(citytype[i][j]>3)citytype[i][j]=3;
+
+ }
+
+ }
+
+
+
+ if(!initialized){
+
+ //Load player model
+
+ skeletonmodels[0].load((unsigned char *)":Data:Models:Head.solid");
+
+ skeletonmodels[0].Rotate(90,0,0);
+
+ skeletonmodels[0].Scale(.02,.02,.02);
+
+ skeletonmodels[0].CalculateNormals();
+
+
+
+ skeletonmodels[1].load((unsigned char *)":Data:Models:Chest.solid");
+
+ skeletonmodels[1].Rotate(90,0,0);
+
+ skeletonmodels[1].Scale(.02,.02,.02);
+
+ skeletonmodels[1].CalculateNormals();
+
+
+
+ skeletonmodels[2].load((unsigned char *)":Data:Models:Abdomen.solid");
+
+ skeletonmodels[2].Rotate(90,0,0);
+
+ skeletonmodels[2].Scale(.02,.02,.02);
+
+ skeletonmodels[2].CalculateNormals();
+
+
+
+ skeletonmodels[3].load((unsigned char *)":Data:Models:Upper arm.solid");
+
+ skeletonmodels[3].Rotate(90,0,0);
+
+ skeletonmodels[3].Scale(.02,.02,.02);
+
+ skeletonmodels[3].CalculateNormals();
+
+
+
+ skeletonmodels[4].load((unsigned char *)":Data:Models:Lower arm.solid");
+
+ skeletonmodels[4].Rotate(90,0,0);
+
+ skeletonmodels[4].Scale(.02,.02,.02);
+
+ skeletonmodels[4].CalculateNormals();
+
+
+
+ skeletonmodels[5].load((unsigned char *)":Data:Models:Hand.solid");
+
+ skeletonmodels[5].Rotate(90,0,0);
+
+ skeletonmodels[5].Scale(.02,.02,.02);
+
+ skeletonmodels[5].CalculateNormals();
+
+
+
+ skeletonmodels[6].load((unsigned char *)":Data:Models:Upper leg.solid");
+
+ skeletonmodels[6].Rotate(90,0,0);
+
+ skeletonmodels[6].Scale(.02,.02,.02);
+
+ skeletonmodels[6].CalculateNormals();
+
+
+
+ skeletonmodels[7].load((unsigned char *)":Data:Models:Lower leg.solid");
+
+ skeletonmodels[7].Rotate(90,0,0);
+
+ skeletonmodels[7].Scale(.02,.02,.02);
+
+ skeletonmodels[7].CalculateNormals();
+
+
+
+ skeletonmodels[8].load((unsigned char *)":Data:Models:Foot.solid");
+
+ skeletonmodels[8].Rotate(90,0,0);
+
+ skeletonmodels[8].Scale(.02,.02,.02);
+
+ skeletonmodels[8].CalculateNormals();
+
+
+
+ skeletonmodels[9].load((unsigned char *)":Data:Models:Shades.solid");
+
+ skeletonmodels[9].Rotate(90,0,0);
+
+ skeletonmodels[9].Scale(.02,.02,.02);
+
+ skeletonmodels[9].CalculateNormals();
+
+
+
+ //Load gun models
+
+ loadingscreenamount+=5;
+
+ if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+
+
+
+ gunmodels[sniperriflemodel].load((unsigned char *)":Data:Models:sniperrifle.solid");
+
+ gunmodels[sniperriflemodel].Rotate(0,0,90);
+
+ gunmodels[sniperriflemodel].Scale(.001,.001,.001);
+
+ gunmodels[sniperriflemodel].CalculateNormals();
+
+
+
+ gunmodels[assaultriflemodel].load((unsigned char *)":Data:Models:assaultrifle.solid");
+
+ gunmodels[assaultriflemodel].Rotate(0,0,90);
+
+ gunmodels[assaultriflemodel].Scale(.01,.01,.01);
+
+ gunmodels[assaultriflemodel].CalculateNormals();
+
+
+
+ gunmodels[handgunbasemodel].load((unsigned char *)":Data:Models:Handgunbase.solid");
+
+ gunmodels[handgunbasemodel].Rotate(0,0,90);
+
+ gunmodels[handgunbasemodel].Rotate(180,0,0);
+
+ gunmodels[handgunbasemodel].Scale(.014,.014,.014);
+
+ gunmodels[handgunbasemodel].CalculateNormals();
+
+ gunmodels[handgunbasemodel].MultColor(.6);
+
+ loadingscreenamount+=5;
+
+ if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+
+
+
+ gunmodels[handgunslidemodel].load((unsigned char *)":Data:Models:Handgunslide.solid");
+
+ gunmodels[handgunslidemodel].Rotate(0,0,90);
+
+ gunmodels[handgunslidemodel].Rotate(180,0,0);
+
+ gunmodels[handgunslidemodel].Scale(.014,.014,.014);
+
+ gunmodels[handgunslidemodel].CalculateNormals();
+
+ gunmodels[handgunslidemodel].MultColor(.6);
+
+
+
+ gunmodels[handgun2basemodel].load((unsigned char *)":Data:Models:glockbase.solid");
+
+ gunmodels[handgun2basemodel].Rotate(0,0,90);
+
+ gunmodels[handgun2basemodel].Rotate(180,0,0);
+
+ gunmodels[handgun2basemodel].Scale(.014,.014,.014);
+
+ gunmodels[handgun2basemodel].CalculateNormals();
+
+ gunmodels[handgun2basemodel].MultColor(.6);
+
+
+
+ gunmodels[handgun2slidemodel].load((unsigned char *)":Data:Models:glockslide.solid");
+
+ gunmodels[handgun2slidemodel].Rotate(0,0,90);
+
+ gunmodels[handgun2slidemodel].Rotate(180,0,0);
+
+ gunmodels[handgun2slidemodel].Scale(.014,.014,.014);
+
+ gunmodels[handgun2slidemodel].CalculateNormals();
+
+ gunmodels[handgun2slidemodel].MultColor(.6);
+
+ loadingscreenamount+=5;
+
+ if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+
+
+
+ gunmodels[grenadebasemodel].load((unsigned char *)":Data:Models:grenadebase.solid");
+
+ gunmodels[grenadebasemodel].Rotate(0,0,90);
+
+ gunmodels[grenadebasemodel].Rotate(180,0,0);
+
+ gunmodels[grenadebasemodel].Scale(.014,.014,.014);
+
+ gunmodels[grenadebasemodel].CalculateNormals();
+
+
+
+ gunmodels[grenadepinmodel].load((unsigned char *)":Data:Models:grenadepin.solid");
+
+ gunmodels[grenadepinmodel].Rotate(0,0,90);
+
+ gunmodels[grenadepinmodel].Rotate(180,0,0);
+
+ gunmodels[grenadepinmodel].Scale(.014,.014,.014);
+
+ gunmodels[grenadepinmodel].CalculateNormals();
+
+
+
+ gunmodels[grenadespoonmodel].load((unsigned char *)":Data:Models:grenadespoon.solid");
+
+ gunmodels[grenadespoonmodel].Rotate(0,0,90);
+
+ gunmodels[grenadespoonmodel].Rotate(180,0,0);
+
+ gunmodels[grenadespoonmodel].Scale(.014,.014,.014);
+
+ gunmodels[grenadespoonmodel].CalculateNormals();
+
+
+
+ gunmodels[knifemodel].load((unsigned char *)":Data:Models:Knife.solid");
+
+ gunmodels[knifemodel].Rotate(0,0,90);
+
+ gunmodels[knifemodel].Rotate(180,0,0);
+
+ gunmodels[knifemodel].Scale(.014,.014,.014);
+
+ gunmodels[knifemodel].CalculateNormals();
+
+
+
+ gunmodels[shotgunmodel].load((unsigned char *)":Data:Models:shotgun.solid");
+
+ gunmodels[shotgunmodel].Rotate(0,0,90);
+
+ gunmodels[shotgunmodel].Scale(.001,.001,.001);
+
+ gunmodels[shotgunmodel].CalculateNormals();
+
+ gunmodels[shotgunmodel].MultColor(.6);
+
+ }
+
+
+
+ loadingscreenamount+=5;
+
+ if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+
+
+
+ //Setup costumes
+
+ float headcolor[3];
+
+ float footcolor[3];
+
+ float handcolor[3];
+
+ float topcolor[3];
+
+ float bottomcolor[3];
+
+ //Police
+
+ headcolor[0]=(float)240/255;
+
+ headcolor[1]=(float)183/255;
+
+ headcolor[2]=(float)132/255;
+
+
+
+ footcolor[0]=(float)119/255;
+
+ footcolor[1]=(float)68/255;
+
+ footcolor[2]=(float)18/255;
+
+
+
+ handcolor[0]=(float)240/255;
+
+ handcolor[1]=(float)183/255;
+
+ handcolor[2]=(float)132/255;
+
+
+
+ topcolor[0]=(float)14/255;
+
+ topcolor[1]=(float)18/255;
+
+ topcolor[2]=(float)195/255;
+
+
+
+ bottomcolor[0]=(float)14/255;
+
+ bottomcolor[1]=(float)18/255;
+
+ bottomcolor[2]=(float)195/255;
+
+
+
+ //Greenish skin if zombies
+
+ if(type==zombie_type){
+
+ headcolor[0]=(float)223/255;
+
+ headcolor[1]=(float)243/255;
+
+ headcolor[2]=(float)197/255;
+
+
+
+ handcolor[0]=(float)223/255;
+
+ handcolor[1]=(float)243/255;
+
+ handcolor[2]=(float)197/255;
+
+ }
+
+
+
+ costume[policecostume].headcolor[0]=headcolor[0];
+
+ costume[policecostume].headcolor[1]=headcolor[1];
+
+ costume[policecostume].headcolor[2]=headcolor[2];
+
+
+
+ costume[policecostume].handcolor[0]=handcolor[0];
+
+ costume[policecostume].handcolor[1]=handcolor[1];
+
+ costume[policecostume].handcolor[2]=handcolor[2];
+
+
+
+ costume[policecostume].chestcolor[0]=topcolor[0];
+
+ costume[policecostume].chestcolor[1]=topcolor[1];
+
+ costume[policecostume].chestcolor[2]=topcolor[2];
+
+
+
+ costume[policecostume].abdomencolor[0]=topcolor[0];
+
+ costume[policecostume].abdomencolor[1]=topcolor[1];
+
+ costume[policecostume].abdomencolor[2]=topcolor[2];
+
+
+
+ costume[policecostume].upperarmcolor[0]=topcolor[0];
+
+ costume[policecostume].upperarmcolor[1]=topcolor[1];
+
+ costume[policecostume].upperarmcolor[2]=topcolor[2];
+
+
+
+ costume[policecostume].lowerarmcolor[0]=topcolor[0];
+
+ costume[policecostume].lowerarmcolor[1]=topcolor[1];
+
+ costume[policecostume].lowerarmcolor[2]=topcolor[2];
+
+
+
+ costume[policecostume].upperlegcolor[0]=bottomcolor[0];
+
+ costume[policecostume].upperlegcolor[1]=bottomcolor[1];
+
+ costume[policecostume].upperlegcolor[2]=bottomcolor[2];
+
+
+
+ costume[policecostume].lowerlegcolor[0]=bottomcolor[0];
+
+ costume[policecostume].lowerlegcolor[1]=bottomcolor[1];
+
+ costume[policecostume].lowerlegcolor[2]=bottomcolor[2];
+
+
+
+ costume[policecostume].footcolor[0]=footcolor[0];
+
+ costume[policecostume].footcolor[1]=footcolor[1];
+
+ costume[policecostume].footcolor[2]=footcolor[2];
+
+
+
+ //casual
+
+ topcolor[0]=(float)14/255;
+
+ topcolor[1]=(float)200/255;
+
+ topcolor[2]=(float)30/255;
+
+
+
+ bottomcolor[0]=(float)14/255;
+
+ bottomcolor[1]=(float)18/255;
+
+ bottomcolor[2]=(float)195/255;
+
+
+
+ costume[casualcostumes].headcolor[0]=headcolor[0];
+
+ costume[casualcostumes].headcolor[1]=headcolor[1];
+
+ costume[casualcostumes].headcolor[2]=headcolor[2];
+
+
+
+ costume[casualcostumes].handcolor[0]=handcolor[0];
+
+ costume[casualcostumes].handcolor[1]=handcolor[1];
+
+ costume[casualcostumes].handcolor[2]=handcolor[2];
+
+
+
+ costume[casualcostumes].chestcolor[0]=topcolor[0];
+
+ costume[casualcostumes].chestcolor[1]=topcolor[1];
+
+ costume[casualcostumes].chestcolor[2]=topcolor[2];
+
+
+
+ costume[casualcostumes].abdomencolor[0]=topcolor[0];
+
+ costume[casualcostumes].abdomencolor[1]=topcolor[1];
+
+ costume[casualcostumes].abdomencolor[2]=topcolor[2];
+
+
+
+ costume[casualcostumes].upperarmcolor[0]=topcolor[0];
+
+ costume[casualcostumes].upperarmcolor[1]=topcolor[1];
+
+ costume[casualcostumes].upperarmcolor[2]=topcolor[2];
+
+
+
+ costume[casualcostumes].lowerarmcolor[0]=handcolor[0];
+
+ costume[casualcostumes].lowerarmcolor[1]=handcolor[1];
+
+ costume[casualcostumes].lowerarmcolor[2]=handcolor[2];
+
+
+
+ costume[casualcostumes].upperlegcolor[0]=bottomcolor[0];
+
+ costume[casualcostumes].upperlegcolor[1]=bottomcolor[1];
+
+ costume[casualcostumes].upperlegcolor[2]=bottomcolor[2];
+
+
+
+ costume[casualcostumes].lowerlegcolor[0]=bottomcolor[0];
+
+ costume[casualcostumes].lowerlegcolor[1]=bottomcolor[1];
+
+ costume[casualcostumes].lowerlegcolor[2]=bottomcolor[2];
+
+
+
+ costume[casualcostumes].footcolor[0]=footcolor[0];
+
+ costume[casualcostumes].footcolor[1]=footcolor[1];
+
+ costume[casualcostumes].footcolor[2]=footcolor[2];
+
+
+
+ //casual 2
+
+ topcolor[0]=(float)140/255;
+
+ topcolor[1]=(float)55/255;
+
+ topcolor[2]=(float)4/255;
+
+
+
+ bottomcolor[0]=(float)14/255;
+
+ bottomcolor[1]=(float)18/255;
+
+ bottomcolor[2]=(float)135/255;
+
+
+
+ costume[casualcostumes+1].headcolor[0]=headcolor[0];
+
+ costume[casualcostumes+1].headcolor[1]=headcolor[1];
+
+ costume[casualcostumes+1].headcolor[2]=headcolor[2];
+
+
+
+ costume[casualcostumes+1].handcolor[0]=handcolor[0];
+
+ costume[casualcostumes+1].handcolor[1]=handcolor[1];
+
+ costume[casualcostumes+1].handcolor[2]=handcolor[2];
+
+
+
+ costume[casualcostumes+1].chestcolor[0]=topcolor[0];
+
+ costume[casualcostumes+1].chestcolor[1]=topcolor[1];
+
+ costume[casualcostumes+1].chestcolor[2]=topcolor[2];
+
+
+
+ costume[casualcostumes+1].abdomencolor[0]=topcolor[0];
+
+ costume[casualcostumes+1].abdomencolor[1]=topcolor[1];
+
+ costume[casualcostumes+1].abdomencolor[2]=topcolor[2];
+
+
+
+ costume[casualcostumes+1].upperarmcolor[0]=topcolor[0];
+
+ costume[casualcostumes+1].upperarmcolor[1]=topcolor[1];
+
+ costume[casualcostumes+1].upperarmcolor[2]=topcolor[2];
+
+
+
+ costume[casualcostumes+1].lowerarmcolor[0]=topcolor[0];
+
+ costume[casualcostumes+1].lowerarmcolor[1]=topcolor[1];
+
+ costume[casualcostumes+1].lowerarmcolor[2]=topcolor[2];
+
+
+
+ costume[casualcostumes+1].upperlegcolor[0]=bottomcolor[0];
+
+ costume[casualcostumes+1].upperlegcolor[1]=bottomcolor[1];
+
+ costume[casualcostumes+1].upperlegcolor[2]=bottomcolor[2];
+
+
+
+ costume[casualcostumes+1].lowerlegcolor[0]=bottomcolor[0];
+
+ costume[casualcostumes+1].lowerlegcolor[1]=bottomcolor[1];
+
+ costume[casualcostumes+1].lowerlegcolor[2]=bottomcolor[2];
+
+
+
+ costume[casualcostumes+1].footcolor[0]=footcolor[0];
+
+ costume[casualcostumes+1].footcolor[1]=footcolor[1];
+
+ costume[casualcostumes+1].footcolor[2]=footcolor[2];
+
+
+
+ //casual 3
+
+ topcolor[0]=(float)134/255;
+
+ topcolor[1]=(float)80/255;
+
+ topcolor[2]=(float)3/255;
+
+
+
+ bottomcolor[0]=(float)30/255;
+
+ bottomcolor[1]=(float)30/255;
+
+ bottomcolor[2]=(float)30/255;
+
+
+
+ footcolor[0]=(float)20/255;
+
+ footcolor[1]=(float)20/255;
+
+ footcolor[2]=(float)20/255;
+
+
+
+
+
+ costume[casualcostumes+2].headcolor[0]=headcolor[0];
+
+ costume[casualcostumes+2].headcolor[1]=headcolor[1];
+
+ costume[casualcostumes+2].headcolor[2]=headcolor[2];
+
+
+
+ costume[casualcostumes+2].handcolor[0]=handcolor[0];
+
+ costume[casualcostumes+2].handcolor[1]=handcolor[1];
+
+ costume[casualcostumes+2].handcolor[2]=handcolor[2];
+
+
+
+ costume[casualcostumes+2].chestcolor[0]=topcolor[0];
+
+ costume[casualcostumes+2].chestcolor[1]=topcolor[1];
+
+ costume[casualcostumes+2].chestcolor[2]=topcolor[2];
+
+
+
+ costume[casualcostumes+2].abdomencolor[0]=topcolor[0];
+
+ costume[casualcostumes+2].abdomencolor[1]=topcolor[1];
+
+ costume[casualcostumes+2].abdomencolor[2]=topcolor[2];
+
+
+
+ costume[casualcostumes+2].upperarmcolor[0]=topcolor[0];
+
+ costume[casualcostumes+2].upperarmcolor[1]=topcolor[1];
+
+ costume[casualcostumes+2].upperarmcolor[2]=topcolor[2];
+
+
+
+ costume[casualcostumes+2].lowerarmcolor[0]=topcolor[0];
+
+ costume[casualcostumes+2].lowerarmcolor[1]=topcolor[1];
+
+ costume[casualcostumes+2].lowerarmcolor[2]=topcolor[2];
+
+
+
+ costume[casualcostumes+2].upperlegcolor[0]=bottomcolor[0];
+
+ costume[casualcostumes+2].upperlegcolor[1]=bottomcolor[1];
+
+ costume[casualcostumes+2].upperlegcolor[2]=bottomcolor[2];
+
+
+
+ costume[casualcostumes+2].lowerlegcolor[0]=bottomcolor[0];
+
+ costume[casualcostumes+2].lowerlegcolor[1]=bottomcolor[1];
+
+ costume[casualcostumes+2].lowerlegcolor[2]=bottomcolor[2];
+
+
+
+ costume[casualcostumes+2].footcolor[0]=footcolor[0];
+
+ costume[casualcostumes+2].footcolor[1]=footcolor[1];
+
+ costume[casualcostumes+2].footcolor[2]=footcolor[2];
+
+
+
+ //casual 4
+
+ topcolor[0]=(float)228/255;
+
+ topcolor[1]=(float)220/255;
+
+ topcolor[2]=(float)0/255;
+
+
+
+ bottomcolor[0]=(float)20/255;
+
+ bottomcolor[1]=(float)20/255;
+
+ bottomcolor[2]=(float)20/255;
+
+
+
+ footcolor[0]=(float)119/255;
+
+ footcolor[1]=(float)68/255;
+
+ footcolor[2]=(float)18/255;
+
+
+
+ costume[casualcostumes+3].headcolor[0]=headcolor[0];
+
+ costume[casualcostumes+3].headcolor[1]=headcolor[1];
+
+ costume[casualcostumes+3].headcolor[2]=headcolor[2];
+
+
+
+ costume[casualcostumes+3].handcolor[0]=handcolor[0];
+
+ costume[casualcostumes+3].handcolor[1]=handcolor[1];
+
+ costume[casualcostumes+3].handcolor[2]=handcolor[2];
+
+
+
+ costume[casualcostumes+3].chestcolor[0]=topcolor[0];
+
+ costume[casualcostumes+3].chestcolor[1]=topcolor[1];
+
+ costume[casualcostumes+3].chestcolor[2]=topcolor[2];
+
+
+
+ costume[casualcostumes+3].abdomencolor[0]=topcolor[0];
+
+ costume[casualcostumes+3].abdomencolor[1]=topcolor[1];
+
+ costume[casualcostumes+3].abdomencolor[2]=topcolor[2];
+
+
+
+ costume[casualcostumes+3].upperarmcolor[0]=topcolor[0];
+
+ costume[casualcostumes+3].upperarmcolor[1]=topcolor[1];
+
+ costume[casualcostumes+3].upperarmcolor[2]=topcolor[2];
+
+
+
+ costume[casualcostumes+3].lowerarmcolor[0]=handcolor[0];
+
+ costume[casualcostumes+3].lowerarmcolor[1]=handcolor[1];
+
+ costume[casualcostumes+3].lowerarmcolor[2]=handcolor[2];
+
+
+
+ costume[casualcostumes+3].upperlegcolor[0]=bottomcolor[0];
+
+ costume[casualcostumes+3].upperlegcolor[1]=bottomcolor[1];
+
+ costume[casualcostumes+3].upperlegcolor[2]=bottomcolor[2];
+
+
+
+ costume[casualcostumes+3].lowerlegcolor[0]=bottomcolor[0];
+
+ costume[casualcostumes+3].lowerlegcolor[1]=bottomcolor[1];
+
+ costume[casualcostumes+3].lowerlegcolor[2]=bottomcolor[2];
+
+
+
+ costume[casualcostumes+3].footcolor[0]=footcolor[0];
+
+ costume[casualcostumes+3].footcolor[1]=footcolor[1];
+
+ costume[casualcostumes+3].footcolor[2]=footcolor[2];
+
+
+
+ if(!initialized){
+
+ //vip
+
+ topcolor[0]=(float)235/255;
+
+ topcolor[1]=(float)235/255;
+
+ topcolor[2]=(float)235/255;
+
+
+
+ bottomcolor[0]=(float)200/255;
+
+ bottomcolor[1]=(float)200/255;
+
+ bottomcolor[2]=(float)200/255;
+
+
+
+ footcolor[0]=(float)119/255;
+
+ footcolor[1]=(float)68/255;
+
+ footcolor[2]=(float)18/255;
+
+
+
+ headcolor[0]=(float)240/255;
+
+ headcolor[1]=(float)183/255;
+
+ headcolor[2]=(float)132/255;
+
+
+
+ footcolor[0]=(float)119/255;
+
+ footcolor[1]=(float)68/255;
+
+ footcolor[2]=(float)18/255;
+
+
+
+ handcolor[0]=(float)240/255;
+
+ handcolor[1]=(float)183/255;
+
+ handcolor[2]=(float)132/255;
+
+
+
+ costume[vipcostume].headcolor[0]=headcolor[0];
+
+ costume[vipcostume].headcolor[1]=headcolor[1];
+
+ costume[vipcostume].headcolor[2]=headcolor[2];
+
+
+
+ costume[vipcostume].handcolor[0]=handcolor[0];
+
+ costume[vipcostume].handcolor[1]=handcolor[1];
+
+ costume[vipcostume].handcolor[2]=handcolor[2];
+
+
+
+ costume[vipcostume].chestcolor[0]=topcolor[0];
+
+ costume[vipcostume].chestcolor[1]=topcolor[1];
+
+ costume[vipcostume].chestcolor[2]=topcolor[2];
+
+
+
+ costume[vipcostume].abdomencolor[0]=topcolor[0];
+
+ costume[vipcostume].abdomencolor[1]=topcolor[1];
+
+ costume[vipcostume].abdomencolor[2]=topcolor[2];
+
+
+
+ costume[vipcostume].upperarmcolor[0]=topcolor[0];
+
+ costume[vipcostume].upperarmcolor[1]=topcolor[1];
+
+ costume[vipcostume].upperarmcolor[2]=topcolor[2];
+
+
+
+ costume[vipcostume].lowerarmcolor[0]=topcolor[0];
+
+ costume[vipcostume].lowerarmcolor[1]=topcolor[1];
+
+ costume[vipcostume].lowerarmcolor[2]=topcolor[2];
+
+
+
+ costume[vipcostume].upperlegcolor[0]=bottomcolor[0];
+
+ costume[vipcostume].upperlegcolor[1]=bottomcolor[1];
+
+ costume[vipcostume].upperlegcolor[2]=bottomcolor[2];
+
+
+
+ costume[vipcostume].lowerlegcolor[0]=bottomcolor[0];
+
+ costume[vipcostume].lowerlegcolor[1]=bottomcolor[1];
+
+ costume[vipcostume].lowerlegcolor[2]=bottomcolor[2];
+
+
+
+ costume[vipcostume].footcolor[0]=footcolor[0];
+
+ costume[vipcostume].footcolor[1]=footcolor[1];
+
+ costume[vipcostume].footcolor[2]=footcolor[2];
+
+
+
+ //Bodyguard
+
+ topcolor[0]=(float)50/255;
+
+ topcolor[1]=(float)50/255;
+
+ topcolor[2]=(float)50/255;
+
+
+
+ bottomcolor[0]=(float)30/255;
+
+ bottomcolor[1]=(float)30/255;
+
+ bottomcolor[2]=(float)30/255;
+
+
+
+ footcolor[0]=(float)20/255;
+
+ footcolor[1]=(float)20/255;
+
+ footcolor[2]=(float)20/255;
+
+
+
+ costume[bodyguardcostume].headcolor[0]=headcolor[0];
+
+ costume[bodyguardcostume].headcolor[1]=headcolor[1];
+
+ costume[bodyguardcostume].headcolor[2]=headcolor[2];
+
+
+
+ costume[bodyguardcostume].handcolor[0]=handcolor[0];
+
+ costume[bodyguardcostume].handcolor[1]=handcolor[1];
+
+ costume[bodyguardcostume].handcolor[2]=handcolor[2];
+
+
+
+ costume[bodyguardcostume].chestcolor[0]=topcolor[0];
+
+ costume[bodyguardcostume].chestcolor[1]=topcolor[1];
+
+ costume[bodyguardcostume].chestcolor[2]=topcolor[2];
+
+
+
+ costume[bodyguardcostume].abdomencolor[0]=topcolor[0];
+
+ costume[bodyguardcostume].abdomencolor[1]=topcolor[1];
+
+ costume[bodyguardcostume].abdomencolor[2]=topcolor[2];
+
+
+
+ costume[bodyguardcostume].upperarmcolor[0]=topcolor[0];
+
+ costume[bodyguardcostume].upperarmcolor[1]=topcolor[1];
+
+ costume[bodyguardcostume].upperarmcolor[2]=topcolor[2];
+
+
+
+ costume[bodyguardcostume].lowerarmcolor[0]=topcolor[0];
+
+ costume[bodyguardcostume].lowerarmcolor[1]=topcolor[1];
+
+ costume[bodyguardcostume].lowerarmcolor[2]=topcolor[2];
+
+
+
+ costume[bodyguardcostume].upperlegcolor[0]=bottomcolor[0];
+
+ costume[bodyguardcostume].upperlegcolor[1]=bottomcolor[1];
+
+ costume[bodyguardcostume].upperlegcolor[2]=bottomcolor[2];
+
+
+
+ costume[bodyguardcostume].lowerlegcolor[0]=bottomcolor[0];
+
+ costume[bodyguardcostume].lowerlegcolor[1]=bottomcolor[1];
+
+ costume[bodyguardcostume].lowerlegcolor[2]=bottomcolor[2];
+
+
+
+ costume[bodyguardcostume].footcolor[0]=footcolor[0];
+
+ costume[bodyguardcostume].footcolor[1]=footcolor[1];
+
+ costume[bodyguardcostume].footcolor[2]=footcolor[2];
+
+
+
+ //Load animations
+
+ loadingscreenamount+=5;
+
+ if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+
+
+
+ testskeleton.Load((char *)":Data:Skeleton:Basic Figure");
+
+ animation[idleanim].Load((char *)":Data:Animations:Breathe");
+
+ animation[joganim].Load((char *)":Data:Animations:Run");
+
+ animation[pistolaimanim].Load((char *)":Data:Animations:PistolAim");
+
+ loadingscreenamount+=5;
+
+ if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+
+ animation[walkanim].Load((char *)":Data:Animations:Walk");
+
+ animation[rifleholdanim].Load((char *)":Data:Animations:Riflehold");
+
+ animation[rifleaimanim].Load((char *)":Data:Animations:Rifleaim");
+
+ animation[assaultrifleaimanim].Load((char *)":Data:Animations:AssaultRifleaim");
+
+ animation[crouchanim].Load((char *)":Data:Animations:Crouch");
+
+ loadingscreenamount+=5;
+
+ if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+
+ animation[headpainanim].Load((char *)":Data:Animations:Headshot");
+
+ animation[chestpainanim].Load((char *)":Data:Animations:Chestshot");
+
+ animation[stomachpainanim].Load((char *)":Data:Animations:Stomachshot");
+
+ animation[rightarmpainanim].Load((char *)":Data:Animations:Rightarmshot");
+
+ animation[leftarmpainanim].Load((char *)":Data:Animations:Leftarmshot");
+
+ loadingscreenamount+=5;
+
+ if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+
+ animation[rightlegpainanim].Load((char *)":Data:Animations:Rightlegshot");
+
+ animation[leftlegpainanim].Load((char *)":Data:Animations:Leftlegshot");
+
+ animation[riflehitanim].Load((char *)":Data:Animations:Riflehit");
+
+ animation[grenadeaimanim].Load((char *)":Data:Animations:grenadeaim");
+
+ animation[grenadechargeanim].Load((char *)":Data:Animations:grenadecharge");
+
+ loadingscreenamount+=5;
+
+ if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+
+ animation[grenadethrowanim].Load((char *)":Data:Animations:grenadethrow");
+
+ animation[zombieeatanim].Load((char *)":Data:Animations:Zombiemunch");
+
+ animation[zombiejoganim].Load((char *)":Data:Animations:ZombieRun");
+
+ animation[zombiewalkanim].Load((char *)":Data:Animations:Zombiewalk");
+
+ loadingscreenamount+=5;
+
+ if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+
+ animation[getupfrontanim].Load((char *)":Data:Animations:Getupfromfront");
+
+ animation[getupbackanim].Load((char *)":Data:Animations:Getupfromback",180);
+
+ animation[diveanim].Load((char *)":Data:Animations:Dive");
+
+ animation[throwanim].Load((char *)":Data:Animations:Aikidothrow");
+
+ animation[thrownanim].Load((char *)":Data:Animations:Aikidothrown");
+
+ }
+
+
+
+ //Setup people
+
+ for(int i=0;i<max_people;i++){
+
+ if(i==0){
+
+ person[i].whichcostume=bodyguardcostume;
+
+ }
+
+
+
+ if(i>1){
+
+ person[i].whichcostume=casualcostumes+abs(Random())%numcasual;
+
+ }
+
+ //person[i].firstlongdead=0;
+
+ person[i].dead=0;
+
+ person[i].health=100;
+
+ person[i].skeleton.free=0;
+
+ person[i].ammo=0;
+
+ person[i].velocity=0;
+
+ //Load skeleton structure
+
+ if(!initialized)person[i].skeleton.Load((char *)":Data:Skeleton:Basic Figure");
+
+
+
+ if(i%5==0){
+
+ loadingscreenamount+=5;
+
+ if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+
+ }
+
+ }
+
+
+
+ loadingscreenamount+=5;
+
+ if(!initialized)LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+
+
+
+ if(initialized)person[0].skeleton.Load((char *)":Data:Skeleton:Basic Figure");
+
+
+
+ person[0].attackframe=-1;
+
+
+
+ spawndelay=0;
+
+
+
+ fog.SetFog(fogcolorr,fogcolorg,fogcolorb,0,viewdistance*.8,.1);
+
+
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+
+
+
+
+ //light
+
+ GLfloat LightAmbient[]= { .3, .3, .3, 1.0f};
+
+ GLfloat LightDiffuse[]= { 1, 1, 1, 1.0f };
+
+
+
+ glLightfv(GL_LIGHT0, GL_AMBIENT, LightAmbient);
+
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, LightDiffuse);
+
+ glEnable(GL_LIGHT0);
+
+
+
+ loadingscreenamount+=5;
+
+
+
+ //Load some textures
+
+ if(!initialized){
+
+ LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+
+
+
+
+
+ LoadPersonSpriteTexture(":Data:Textures:Personsprite.tga",&personspritetextureptr);
+
+ LoadPersonSpriteTexture(":Data:Textures:DeadPersonsprite.tga",&deadpersonspritetextureptr);
+
+ LoadPersonSpriteTexture(":Data:Textures:Scope.tga",&scopetextureptr);
+
+ LoadPersonSpriteTexture(":Data:Textures:Flare.tga",&flaretextureptr);
+
+
+
+ sprites.LoadFlareTexture(":Data:Textures:HitFlash.tga");
+
+ sprites.LoadMuzzleFlareTexture(":Data:Textures:MuzzleFlash.tga");
+
+ sprites.LoadSmokeTexture(":Data:Textures:Smoke.tga");
+
+ sprites.LoadBloodTexture(":Data:Textures:Blood.tga");
+
+ sprites.LoadRainTexture(":Data:Textures:rain.tga");
+
+ sprites.LoadSnowTexture(":Data:Textures:snow.tga");
+
+ decals.LoadBulletHoleTexture(":Data:Textures:BulletHole.tga");
+
+ decals.LoadCraterTexture(":Data:Textures:Crater.tga");
+
+ decals.LoadBloodTexture(":Data:Textures:Blood:Blood1.tga",0);
+
+ decals.LoadBloodTexture(":Data:Textures:Blood:Blood2.tga",1);
+
+ decals.LoadBloodTexture(":Data:Textures:Blood:Blood3.tga",2);
+
+ decals.LoadBloodTexture(":Data:Textures:Blood:Blood4.tga",3);
+
+ decals.LoadBloodTexture(":Data:Textures:Blood:Blood5.tga",4);
+
+ decals.LoadBloodTexture(":Data:Textures:Blood:Blood6.tga",5);
+
+ decals.LoadBloodTexture(":Data:Textures:Blood:Blood7.tga",6);
+
+ decals.LoadBloodTexture(":Data:Textures:Blood:Blood8.tga",7);
+
+ decals.LoadBloodTexture(":Data:Textures:Blood:Blood9.tga",8);
+
+ decals.LoadBloodTexture(":Data:Textures:Blood:Blood10.tga",9);
+
+ decals.LoadBloodTexture(":Data:Textures:Blood:Blood11.tga",10);
+
+ }
+
+
+
+ //Setup clip plane equation
+
+ eqn[0]=0;
+
+ eqn[1]=1;
+
+ eqn[2]=0;
+
+ eqn[3]=0;
+
+
+
+ glClearColor(fogcolorr,fogcolorg,fogcolorb,1);
+
+
+
+ if(!initialized)InitMouse();
+
+
+
+ //Draw city one frame to fix evil menu bug
+
+ if(!initialized)mainmenu=2;
+
+
+
+ if(!initialized){
+
+ LoadingScreen(loadingscreenamount/loadingscreenamounttotal*100);
+
+ flashamount=1;
+
+ flashr=1;flashg=1;flashb=1;
+
+ alSourcePlay(gSourceID[soulinsound]);
+
+ }
+
+
+
+ initialized=1;
+
+
+
+ loadingscreenamount+=5;
+
+
+
+ //Sync to refresh rate
+
+ if(vblsync){
+
+ GLint swapInt = 1;
+
+ aglSetInteger(gOpenGLContext, AGL_SWAP_INTERVAL, &swapInt);
+
+ }
+
+ /*
+
+ for(int i=0;i<sprites.howmanysprites;i++){
+
+ sprites.DeleteSprite(0);
+
+ }
+
+
+
+ for(int i=0;i<decals.howmanydecals;i++){
+
+ decals.DeleteDecal(0);
+
+ }*/
+
+ decals.howmanydecals=0;
+
+ sprites.howmanysprites=0;
+
+
+
+ losedelay=1;
+
+
+
+ oldscore=score;
+
+}
+
+
+
+/*********************> InitGL() <*****/
+
+
+
+
+
+int Game::InitGL(GLvoid)
+
+{
+
+ //Config
+
+ if(!initialized){
+
+ //Default config in case config is not found
+
+ HideCursor();
+
+ screenwidth = 640;
+
+ screenheight = 480;
+
+ usermousesensitivity=.7;
+
+ debug=0;
+
+ vblsync=1;
+
+ blood = 1;
+
+ blurness = 0;
+
+ mainmenuness=1;
+
+ customlevels=0;
+
+ musictoggle=1;
+
+
+
+ //If no config, write one
+
+ ifstream ipstream("config.txt");
+
+ if(!ipstream) {
+
+ ofstream opstream("config.txt");
+
+ opstream << "Screenwidth:\n";
+
+ opstream << screenwidth;
+
+ opstream << "\nScreenheight:\n";
+
+ opstream << screenheight;
+
+ opstream << "\nMouse sensitivity:\n";
+
+ opstream << usermousesensitivity;
+
+ opstream << "\nShow fps and other info:\n";
+
+ opstream << debug;
+
+ opstream << "\nVBL sync:\n";
+
+ opstream << vblsync;
+
+ opstream << "\nBlood:\n";
+
+ opstream << blood;
+
+ opstream << "\nBlur:\n";
+
+ opstream << blurness;
+
+ opstream << "\nMain Menu:\n";
+
+ opstream << mainmenuness;
+
+ opstream << "\nCustom levels:\n";
+
+ opstream << customlevels;
+
+ opstream << "\nMusic:\n";
+
+ opstream << musictoggle;
+
+ opstream << "\azerty keyboard:\n";
+
+ opstream << azertykeyboard;
+
+ opstream.close();
+
+ }
+
+ //Read config
+
+ if(ipstream){
+
+ ipstream.ignore(256,'\n');
+
+ ipstream >> screenwidth;
+
+ ipstream.ignore(256,'\n');
+
+ ipstream.ignore(256,'\n');
+
+ ipstream >> screenheight;
+
+ ipstream.ignore(256,'\n');
+
+ ipstream.ignore(256,'\n');
+
+ ipstream >> usermousesensitivity;
+
+ ipstream.ignore(256,'\n');
+
+ ipstream.ignore(256,'\n');
+
+ ipstream >> debug;
+
+ ipstream.ignore(256,'\n');
+
+ ipstream.ignore(256,'\n');
+
+ ipstream >> vblsync;
+
+ ipstream.ignore(256,'\n');
+
+ ipstream.ignore(256,'\n');
+
+ ipstream >> blood;
+
+ ipstream.ignore(256,'\n');
+
+ ipstream.ignore(256,'\n');
+
+ ipstream >> blurness;
+
+ ipstream.ignore(256,'\n');
+
+ ipstream.ignore(256,'\n');
+
+ ipstream >> mainmenuness;
+
+ ipstream.ignore(256,'\n');
+
+ ipstream.ignore(256,'\n');
+
+ ipstream >> customlevels;
+
+ ipstream.ignore(256,'\n');
+
+ ipstream.ignore(256,'\n');
+
+ ipstream >> musictoggle;
+
+ ipstream.ignore(256,'\n');
+
+ ipstream.ignore(256,'\n');
+
+ ipstream >> azertykeyboard;
+
+ ipstream.close();
+
+ }
+
+
+
+ //Read high score
+
+ ifstream ipstream2(":Data:Highscore");
+
+ if(!ipstream2) {
+
+ highscore=0;
+
+ beatgame=0;
+
+ ofstream opstream(":Data:Highscore");
+
+ opstream << highscore;
+
+ opstream << "\n";
+
+ opstream << beatgame;
+
+ opstream.close();
+
+ }
+
+ if(ipstream2){
+
+ ipstream2 >> highscore;
+
+ ipstream.ignore(256,'\n');
+
+ ipstream2 >> beatgame;
+
+ ipstream2.close();
+
+ }
+
+
+
+ sps=40;
+
+ maxfps=90;
+
+
+
+ disttest=1;
+
+ cubetest=1;
+
+ }
+
+
+
+ //Setup screen
+
+ if(screenwidth<640||screenheight<480)
+
+ theScreen = SetupScreen( 640, 480 );
+
+ else
+
+ theScreen = SetupScreen( screenwidth, screenheight );
+
+
+
+ gOpenGLContext = SetupAGL( ( AGLDrawable )theScreen );
+
+ if ( !gOpenGLContext )
+
+ return;
+
+
+
+ text.LoadFontTexture(":Data:Textures:Font.tga");
+
+ text.BuildFont();
+
+ glAlphaFunc(GL_GREATER, 0.01);
+
+ glDepthFunc(GL_LESS);
+
+
+
+ glPolygonOffset(-8,0);
+
+ glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
+
+
+
+ return TRUE;
+
+}
+
+
+
+//***************> Dispose() <******/
+
+void Game::Dispose()
+
+{
+
+ CleanupAGL( gOpenGLContext );
+
+ ShutdownScreen( theScreen );
+
+ ShowCursor();
+
+
+
+ //Delete sound sources
+
+ alDeleteSources(100, gSourceID);
+
+
+
+}
+
+
+
+//***************> ResizeGLScene() <******/
+
+GLvoid Game::ReSizeGLScene(float fov, float near)
+
+{
+
+ if (screenheight==0)
+
+ {
+
+ screenheight=1;
+
+ }
+
+
+
+ glViewport(0,0,screenwidth,screenheight);
+
+
+
+ glMatrixMode(GL_PROJECTION);
+
+ glLoadIdentity();
+
+
+
+ gluPerspective(fov,(GLfloat)screenwidth/(GLfloat)screenheight,near,viewdistance);
+
+
+
+ glMatrixMode(GL_MODELVIEW);
+
+ glLoadIdentity();
+
+}
+
diff --git a/Source/GameLoop.cpp b/Source/GameLoop.cpp
new file mode 100644
index 0000000..6e222fd
--- /dev/null
+++ b/Source/GameLoop.cpp
@@ -0,0 +1,371 @@
+#include "Game.h"
+
+
+
+extern double multiplier;
+
+extern int visions;
+
+extern unsigned int gSourceID[100];
+
+extern unsigned int gSampleSet[100];
+
+extern Camera camera;
+
+extern float rad2deg;
+
+extern Fog fog;
+
+extern int environment;
+
+extern int slomo;
+
+/********************> HandleKeyDown() <*****/
+
+void Game::HandleKeyDown( char theChar )
+
+{
+
+ ALint tempInt;
+
+ XYZ facing;
+
+
+
+ if(!mainmenu){
+
+ switch( theChar )
+
+ {
+
+ case 'k':
+
+ if(debug)timeremaining=0;
+
+ break;
+
+
+
+ case 'b':
+
+ if(debug){
+
+ alSourcePlay(gSourceID[soulinsound]);
+
+ if(!slomo)slomo=1;
+
+ else slomo=0;}
+
+ if(slomo){
+
+ alSourcef(gSourceID[knifesong], AL_PITCH, (ALfloat)(.5));
+
+ alSourcef(gSourceID[shootsong], AL_PITCH, (ALfloat)(.5));
+
+ alSourcef(gSourceID[zombiesong], AL_PITCH, (ALfloat)(.5));
+
+ }
+
+ if(!slomo){
+
+ alSourcef(gSourceID[knifesong], AL_PITCH, (ALfloat)(1));
+
+ alSourcef(gSourceID[shootsong], AL_PITCH, (ALfloat)(1));
+
+ alSourcef(gSourceID[zombiesong], AL_PITCH, (ALfloat)(1));
+
+ }
+
+ break;
+
+ case 'B':
+
+ if(debug){
+
+ alSourcePlay(gSourceID[soulinsound]);
+
+ paused=1-paused;}
+
+ break;
+
+ case 'f':
+
+ if(debug){
+
+ alSourcePlay(gSourceID[souloutsound]);
+
+ //Facing
+
+ facing=0;
+
+ facing.z=-1;
+
+
+
+ facing=DoRotation(facing,-camera.rotation2,0,0);
+
+ facing=DoRotation(facing,0,0-camera.rotation,0);
+
+ for(int i=1;i<numpeople;i++){
+
+ if(person[i].skeleton.free!=1){
+
+ if(findDistancefast(person[i].playercoords,person[0].playercoords)<1000){
+
+ person[i].skeleton.free=1;
+
+ person[i].longdead=1;
+
+ for(int j=0;j<person[i].skeleton.num_joints;j++){
+
+ person[i].skeleton.joints[j].position=DoRotation(person[i].skeleton.joints[j].position,0,person[i].playerrotation,0);
+
+ person[i].skeleton.joints[j].position+=person[i].playercoords;
+
+ person[i].skeleton.joints[j].realoldposition=person[i].skeleton.joints[j].position;
+
+ person[i].skeleton.joints[j].velocity=DoRotation(person[i].skeleton.joints[j].velocity,0,person[i].playerrotation,0);
+
+ person[i].skeleton.joints[j].velocity+=person[i].velocity;
+
+ person[i].skeleton.joints[j].velocity+=facing*50;
+
+ person[i].skeleton.joints[j].velocity.x+=abs(Random()%20)-10;
+
+ person[i].skeleton.joints[j].velocity.y+=abs(Random()%20)-10;
+
+ person[i].skeleton.joints[j].velocity.z+=abs(Random()%20)-10;
+
+ }}}
+
+ }}
+
+ break;
+
+ case 'X':
+
+ if(debug){
+
+ if(person[0].grenphase==0){
+
+ person[0].ammo=-1;
+
+ person[0].whichgun++;
+
+ person[0].grenphase=0;
+
+ person[0].reloads[person[0].whichgun]=3;
+
+ if(person[0].whichgun>7)person[0].whichgun=0;
+
+ }}
+
+ break;
+
+ }
+
+ }
+
+}
+
+
+
+/********************> DoEvent() <*****/
+
+void Game::DoEvent( EventRecord *event )
+
+{
+
+
+
+ char theChar;
+
+
+
+ switch ( event->what )
+
+ {
+
+ case keyDown:
+
+ case autoKey:
+
+ theChar = event->message & charCodeMask; // Get the letter of the key pressed from the event message
+
+ HandleKeyDown( theChar ); // Only some key presses are handled here because it is slower and less responsive
+
+ break;
+
+ }
+
+
+
+
+
+}
+
+/********************> EventLoop() <*****/
+
+void Game::EventLoop( void )
+
+{
+
+ EventRecord event;
+
+ unsigned char theKeyMap[16];
+
+ int colaccuracy,i;
+
+ GLfloat oldmult;
+
+ gQuit = false;
+
+ while ( gQuit == false )
+
+ {
+
+ if ( GetNextEvent( everyEvent, &event ) )
+
+ DoEvent( &event );
+
+
+
+ start=TimerGetTime(&theTimer);
+
+
+
+ colaccuracy=sps/framespersecond+1;
+
+ if(colaccuracy>sps){colaccuracy=sps;}
+
+
+
+ oldmult=multiplier;
+
+ multiplier/=colaccuracy;
+
+ for(i=0;i<(int)(colaccuracy+.5);i++){
+
+ Tick();
+
+ }
+
+ multiplier=oldmult;
+
+
+
+ if ( DrawGLScene())
+
+ aglSwapBuffers( gOpenGLContext );
+
+ else
+
+ gQuit = true;
+
+ oldmult=multiplier;
+
+
+
+ end=TimerGetTime(&theTimer);
+
+ timetaken=end-start;
+
+ framespersecond=600000000/timetaken;
+
+ while(framespersecond>maxfps){
+
+ end=TimerGetTime(&theTimer);
+
+ timetaken=end-start;
+
+ framespersecond=600000000/timetaken;
+
+ }
+
+ multiplier5=multiplier4;
+
+ multiplier4=multiplier3;
+
+ multiplier3=multiplier2;
+
+ multiplier2=1/framespersecond;
+
+ multiplier=(multiplier2+multiplier3+multiplier4+multiplier5)/4;
+
+ if(multiplier>1)multiplier=1;
+
+ if(multiplier<.00001)multiplier=.00001;
+
+ if(visions==1&&mainmenu==0)multiplier/=3;
+
+ if(slomo)multiplier*=.2;
+
+ if(paused)multiplier=0;
+
+ GetKeys( ( unsigned long * )theKeyMap );
+
+ if ( IsKeyDown( theKeyMap, MAC_COMMAND_KEY )&&IsKeyDown( theKeyMap, MAC_Q_KEY )){
+
+ gQuit = true;
+
+ if(score>highscore){
+
+ highscore=score;
+
+ ofstream opstream(":Data:Highscore");
+
+ opstream << highscore;
+
+ opstream << "\n";
+
+ opstream << beatgame;
+
+ opstream.close();
+
+ }
+
+ }
+
+ if ( IsKeyDown( theKeyMap, MAC_ESCAPE_KEY )){
+
+ alSourcePause(gSourceID[rainsound]);
+
+
+
+ mainmenu=1;
+
+ alSourcePlay(gSourceID[souloutsound]);
+
+ flashamount=1;
+
+ flashr=1;flashg=1;flashb=1;
+
+ alSourceStop(gSourceID[visionsound]);
+
+ whichsong=mainmenusong;
+
+ alSourceStop(gSourceID[knifesong]);
+
+ alSourceStop(gSourceID[shootsong]);
+
+ alSourceStop(gSourceID[zombiesong]);
+
+ alSourceStop(gSourceID[mainmenusong]);
+
+ alSourcef(gSourceID[knifesong], AL_MIN_GAIN, 0);
+
+ alSourcef(gSourceID[shootsong], AL_MIN_GAIN, 0);
+
+ alSourcef(gSourceID[zombiesong], AL_MIN_GAIN, 0);
+
+ alSourcef(gSourceID[mainmenusong], AL_MIN_GAIN, 0);
+
+ alSourcePlay(gSourceID[whichsong]);
+
+ alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1);
+
+ }
+
+ }
+
+} \ No newline at end of file
diff --git a/Source/GameTick.cpp b/Source/GameTick.cpp
new file mode 100644
index 0000000..d21eeab
--- /dev/null
+++ b/Source/GameTick.cpp
@@ -0,0 +1,4923 @@
+#include "Game.h"
+
+
+
+extern double multiplier;
+
+extern int thirdperson;
+
+extern int visions;
+
+extern Sprites sprites;
+
+
+
+extern unsigned int gSourceID[100];
+
+extern unsigned int gSampleSet[100];
+
+extern Camera camera;
+
+extern float camerashake;
+
+extern Fog fog;
+
+extern int environment;
+
+extern float precipitationhorz;
+
+extern float precipitationvert;
+
+extern float snowdelay;
+
+extern float precipitationdensity;
+
+extern float soundscalefactor;
+
+extern int slomo;
+
+
+
+extern int forwardskey;
+
+extern int backwardskey;
+
+extern int leftkey;
+
+extern int rightkey;
+
+extern int aimkey;
+
+extern int psychicaimkey;
+
+extern int psychickey;
+
+
+
+extern Decals decals;
+
+/********************> Tick() <*****/
+
+#define maxfallvel 40
+
+
+
+void Game::Splat(int k){
+
+ if(k!=0||visions==0){
+
+ person[k].health=0;
+
+ person[k].DoAnimations(k);
+
+ person[k].skeleton.offset=0;
+
+ person[k].skeleton.free=1;
+
+ person[k].longdead=1;
+
+
+
+ person[k].bleeding=1;
+
+ person[k].bleeddelay=1;
+
+ person[k].bjoint1=&person[k].skeleton.joints[person[k].skeleton.jointlabels[head]];
+
+ person[k].bjoint2=&person[k].skeleton.joints[person[k].skeleton.jointlabels[neck]];
+
+
+
+ for(int j=0;j<person[k].skeleton.num_joints;j++){
+
+ person[k].skeleton.joints[j].position+=person[k].skeleton.joints[j].offset;
+
+ person[k].skeleton.joints[j].position=DoRotation(person[k].skeleton.joints[j].position,0,person[k].playerrotation,0);
+
+ person[k].skeleton.joints[j].position+=person[k].playercoords;
+
+ person[k].skeleton.joints[j].realoldposition=person[k].skeleton.joints[j].position;
+
+ person[k].skeleton.joints[j].velocity=0;
+
+ person[k].skeleton.joints[j].velocity.y+=person[k].velocity.y;
+
+ }
+
+
+
+ float gLoc[3];
+
+ gLoc[0]=person[k].skeleton.joints[person[k].skeleton.jointlabels[head]].position.x/soundscalefactor;
+
+ gLoc[1]=person[k].skeleton.joints[person[k].skeleton.jointlabels[head]].position.y/soundscalefactor;
+
+ gLoc[2]=person[k].skeleton.joints[person[k].skeleton.jointlabels[head]].position.z/soundscalefactor;
+
+ alSourcefv(gSourceID[headwhacksound], AL_POSITION, gLoc);
+
+ alSourcePlay(gSourceID[headwhacksound]);
+
+ }
+
+}
+
+
+
+void Game::Tick(){
+
+ if(mainmenu){
+
+
+
+ unsigned char theKeyMap[16];
+
+ GetKeys( ( unsigned long * )theKeyMap );
+
+
+
+ if(IsKeyDown(theKeyMap, MAC_SPACE_KEY)){
+
+ mainmenu=0;
+
+ }
+
+
+
+ GetMouse(&mouseloc);
+
+ float mousex=mouseloc.h;
+
+ float mousey=mouseloc.v;
+
+ mousex=(float)mouseloc.h*640/screenwidth;
+
+ mousey=480-(float)mouseloc.v*480/screenheight;
+
+
+
+ oldmouseoverbutton=mouseoverbutton;
+
+ mouseoverbutton=0;
+
+ if(mousex>120&&mousex<560&&mousey>235&&mousey<305){
+
+ mouseoverbutton=1;
+
+ }
+
+ if(mousex>120&&mousex<560&&mousey>112&&mousey<182){
+
+ mouseoverbutton=2;
+
+ }
+
+ if((Button()&&mouseoverbutton==1&&!gameinprogress&&!oldbutton)||!mainmenuness){
+
+ if(environment==rainy_environment)alSourcePlay(gSourceID[rainsound]);
+
+ if(environment!=rainy_environment)alSourcePause(gSourceID[rainsound]);
+
+ alSourceStop(gSourceID[whichsong]);
+
+ alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 0);
+
+ alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 0);
+
+ if(person[0].whichgun==knife)whichsong=knifesong;
+
+ if(person[0].whichgun!=knife)whichsong=shootsong;
+
+ if(type==zombie_type)whichsong=zombiesong;
+
+ alSourcef(gSourceID[whichsong], AL_PITCH, 1);
+
+ alSourcePlay(gSourceID[whichsong]);
+
+ alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1);
+
+ alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1);
+
+ flashamount=1;
+
+ flashr=1;flashg=1;flashb=1;
+
+ mainmenu=0;
+
+ alSourcePlay(gSourceID[soulinsound]);
+
+ mission=0;
+
+ InitGame();
+
+ gameinprogress=1;
+
+ }
+
+ if((Button()&&mouseoverbutton==1&&gameinprogress&&!oldbutton)||!mainmenuness){
+
+ flashamount=1;
+
+ flashr=1;flashg=1;flashb=1;
+
+ mainmenu=0;
+
+ MoveMouse(oldmouseloc.h,oldmouseloc.v,&mouseloc);
+
+ //if(!visions){
+
+ if(environment==rainy_environment)alSourcePlay(gSourceID[rainsound]);
+
+ if(environment!=rainy_environment)alSourcePause(gSourceID[rainsound]);
+
+ alSourceStop(gSourceID[whichsong]);
+
+ alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 0);
+
+ alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 0);
+
+ if(person[0].whichgun==knife)whichsong=knifesong;
+
+ if(person[0].whichgun!=knife)whichsong=shootsong;
+
+ if(type==zombie_type)whichsong=zombiesong;
+
+ alSourcePlay(gSourceID[whichsong]);
+
+ alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1);
+
+ alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1);
+
+ //}
+
+ alSourcePlay(gSourceID[soulinsound]);
+
+ if(visions)alSourcePlay(gSourceID[visionsound]);
+
+ }
+
+ if(Button()&&mouseoverbutton==2&&!gameinprogress&&!oldbutton){
+
+ flashamount=1;
+
+ flashr=1;flashg=0;flashb=0;
+
+ alSourcePlay(gSourceID[losesound]);
+
+ gQuit = true;
+
+ if(score>highscore){
+
+ highscore=score;
+
+ ofstream opstream(":Data:Highscore");
+
+ opstream << highscore;
+
+ opstream << "\n";
+
+ opstream << beatgame;
+
+ opstream.close();
+
+ }
+
+ }
+
+ if(Button()&&mouseoverbutton==2&&gameinprogress&&!oldbutton){
+
+ flashamount=1;
+
+ flashr=1;flashg=1;flashb=1;
+
+ alSourcePlay(gSourceID[losesound]);
+
+ gameinprogress=0;
+
+ if(score>highscore){
+
+ highscore=score;
+
+ ofstream opstream(":Data:Highscore");
+
+ opstream << highscore;
+
+ opstream << "\n";
+
+ opstream << beatgame;
+
+ opstream.close();
+
+ }
+
+ }
+
+
+
+ if(Button())oldbutton=1;
+
+ if(!Button())oldbutton=0;
+
+ }
+
+ if(!mainmenu){
+
+
+
+
+
+ XYZ facing;
+
+ XYZ flatfacing;
+
+ float speed=10;
+
+
+
+ if(person[1].health<=0||person[0].health<=0||killedinnocent){
+
+ losedelay-=multiplier/6;
+
+ }
+
+
+
+ if(person[1].health>0&&person[0].health>0&&!killedinnocent)timeremaining-=multiplier*25/40;
+
+ if(timeremaining<=0){
+
+ flashamount=1;
+
+ flashr=0;flashg=1;flashb=0;
+
+ mission++;
+
+ alSourcePlay(gSourceID[souloutsound]);
+
+ score+=100+(mission*50);
+
+ if(mission>=nummissions){
+
+ beatgame=1;
+
+ mainmenu=1;
+
+ gameinprogress=0;
+
+ alSourcePause(gSourceID[rainsound]);
+
+
+
+ alSourceStop(gSourceID[visionsound]);
+
+ alSourceStop(gSourceID[whichsong]);
+
+ alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 0);
+
+ alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 0);
+
+ whichsong=mainmenusong;
+
+ alSourceStop(gSourceID[whichsong]);
+
+ alSourcef(gSourceID[whichsong], AL_PITCH, 1);
+
+ alSourcePlay(gSourceID[whichsong]);
+
+ alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1);
+
+ alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1);
+
+ if(score>highscore){
+
+ highscore=score;
+
+ ofstream opstream(":Data:Highscore");
+
+ opstream << highscore;
+
+ opstream << "\n";
+
+ opstream << beatgame;
+
+ opstream.close();
+
+ }
+
+ }
+
+ if(!mainmenu){
+
+ InitGame();
+
+ if(environment==rainy_environment)alSourcePlay(gSourceID[rainsound]);
+
+ if(environment!=rainy_environment)alSourcePause(gSourceID[rainsound]);
+
+ alSourceStop(gSourceID[visionsound]);
+
+ alSourceStop(gSourceID[whichsong]);
+
+ if(person[0].whichgun==knife)whichsong=knifesong;
+
+ if(person[0].whichgun!=knife)whichsong=shootsong;
+
+ if(type==zombie_type)whichsong=zombiesong;
+
+ alSourcef(gSourceID[whichsong], AL_PITCH, 1);
+
+ alSourcePlay(gSourceID[whichsong]);
+
+ alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1);
+
+ alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1);
+
+ }
+
+ }
+
+ if(losedelay<=0){
+
+ flashamount=1;
+
+ flashr=0;flashg=0;flashb=0;
+
+ if(person[murderer].health>0)score=oldscore-200;
+
+ if(person[murderer].health<=0)score=oldscore-100;
+
+ InitGame();
+
+ alSourceStop(gSourceID[whichsong]);
+
+ if(person[0].whichgun==knife)whichsong=knifesong;
+
+ if(person[0].whichgun!=knife)whichsong=shootsong;
+
+ if(type==zombie_type)whichsong=zombiesong;
+
+ alSourcef(gSourceID[whichsong], AL_PITCH, 1);
+
+ alSourcePlay(gSourceID[whichsong]);
+
+ alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1);
+
+ alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1);
+
+ alSourcePlay(gSourceID[soulinsound]);
+
+ }
+
+
+
+ unsigned char theKeyMap[16];
+
+ GetKeys( ( unsigned long * )theKeyMap );
+
+
+
+ //Sprites
+
+ sprites.DoStuff();
+
+
+
+ //Decals
+
+ decals.DoStuff();
+
+
+
+ //Facing
+
+ facing=0;
+
+ facing.z=-1;
+
+
+
+ facing=DoRotation(facing,-camera.rotation2,0,0);
+
+ facing=DoRotation(facing,0,0-camera.rotation,0);
+
+
+
+ flatfacing=facing;
+
+ flatfacing.y=0;
+
+ Normalise(&flatfacing);
+
+
+
+ if(IsKeyDown(theKeyMap, psychickey)&&!oldvisionkey){
+
+ oldvisionkey=1;
+
+ visions++;
+
+ if(visions==2)visions=0;
+
+ if(visions==0){
+
+ float rad2deg=56.54866776;
+
+ flashamount=1;
+
+ flashr=1;flashg=1;flashb=1;
+
+
+
+ if(person[0].playercoords.x!=bodycoords.x||person[0].playercoords.z!=bodycoords.z){
+
+ XYZ towards;
+
+ towards=person[0].playercoords-bodycoords;
+
+ Normalise(&towards);
+
+ camera.rotation=-asin(0-towards.x);
+
+ camera.rotation*=360/6.28;
+
+ if(towards.z>0)camera.rotation=180-camera.rotation;
+
+ camera.visrotation=camera.rotation;
+
+ camera.oldrotation=camera.rotation;
+
+ camera.oldoldrotation=camera.rotation;
+
+ }
+
+
+
+ person[0].playercoords=bodycoords;
+
+ person[0].oldplayercoords=bodycoords;
+
+ person[0].velocity=0;
+
+ alSourcePlay(gSourceID[soulinsound]);
+
+ alSourceStop(gSourceID[visionsound]);
+
+ alSourcef(gSourceID[knifesong], AL_PITCH, (ALfloat)(1));
+
+ alSourcef(gSourceID[shootsong], AL_PITCH, (ALfloat)(1));
+
+ alSourcef(gSourceID[zombiesong], AL_PITCH, (ALfloat)(1));
+
+ }
+
+ if(visions==1){
+
+ alSourceStop(gSourceID[visionsound]);
+
+ flashamount=1;
+
+ flashr=1;flashg=0;flashb=0;
+
+ bodycoords=person[0].oldplayercoords;
+
+ alSourcePlay(gSourceID[souloutsound]);
+
+ alSourcef(gSourceID[knifesong], AL_PITCH, (ALfloat)(.5));
+
+ alSourcef(gSourceID[shootsong], AL_PITCH, (ALfloat)(.5));
+
+ alSourcef(gSourceID[zombiesong], AL_PITCH, (ALfloat)(.5));
+
+ alSourcePlay(gSourceID[visionsound]);
+
+ }
+
+ }
+
+ if(!IsKeyDown(theKeyMap, psychickey)){
+
+ oldvisionkey=0;
+
+ }
+
+
+
+ if(IsKeyDown(theKeyMap, MAC_TAB_KEY)&&!tabkeydown&&debug){
+
+ thirdperson++;
+
+ if(thirdperson>2)thirdperson=0;
+
+ tabkeydown=1;
+
+ }
+
+
+
+ if(!IsKeyDown(theKeyMap, MAC_TAB_KEY))
+
+ tabkeydown=0;
+
+
+
+ if(IsKeyDown(theKeyMap, aimkey)&&!aimtoggle){
+
+ person[0].aiming=1-person[0].aiming;
+
+ aimtoggle=1;
+
+ }
+
+
+
+ if(!IsKeyDown(theKeyMap, aimkey))
+
+ aimtoggle=0;
+
+
+
+ if(IsKeyDown(theKeyMap, MAC_R_KEY)&&!reloadtoggle){
+
+ if(person[0].reloads[person[0].whichgun]>0&&person[0].reloading<=0)person[0].ammo=-1;
+
+ reloadtoggle=1;
+
+ }
+
+
+
+ if(!IsKeyDown(theKeyMap, MAC_R_KEY))
+
+ reloadtoggle=0;
+
+
+
+ if(IsKeyDown(theKeyMap, psychicaimkey)&&!slomokeydown&&slomo==0){
+
+ alSourcePlay(gSourceID[souloutsound]);
+
+ slomo=2;
+
+ flashamount=.5;
+
+ flashr=1;flashg=0;flashb=0;
+
+ slomokeydown=1;
+
+ score-=20;
+
+ alSourcef(gSourceID[knifesong], AL_PITCH, (ALfloat)(.5));
+
+ alSourcef(gSourceID[shootsong], AL_PITCH, (ALfloat)(.5));
+
+ alSourcef(gSourceID[zombiesong], AL_PITCH, (ALfloat)(.5));
+
+ }
+
+
+
+ if(!IsKeyDown(theKeyMap, psychicaimkey))
+
+ slomokeydown=0;
+
+
+
+ //Mouse look
+
+
+
+ if((person[0].aimamount<=0&&person[0].targetanimation!=crouchanim)){
+
+ camera.rotation=camera.visrotation;
+
+ camera.rotation2=camera.visrotation2;
+
+ mousesensitivity=usermousesensitivity;
+
+ }
+
+ if(person[0].aimamount>=1&&zoom==0){
+
+ mousesensitivity=usermousesensitivity*.8;
+
+ }
+
+ if(slomo==2){
+
+ mousesensitivity*=.6;
+
+ }
+
+ GetMouse(&mouseloc);
+
+ if (mouseloc.h>600){MoveMouse(mouseloc.h-500,mouseloc.v,&mouseloc);}
+
+ if (mouseloc.h<100){MoveMouse(mouseloc.h+500,mouseloc.v,&mouseloc);}
+
+ GetMouse(&mouseloc);
+
+ if (mouseloc.v>400){MoveMouse(mouseloc.h,mouseloc.v-300,&mouseloc);}
+
+ if (mouseloc.v<100){MoveMouse(mouseloc.h,mouseloc.v+300,&mouseloc);}
+
+ GetMouse(&mouseloc);
+
+
+
+ oldmouserotation=(oldmouseloc.h/1.3888)*mousesensitivity;
+
+ oldmouserotation2=(oldmouseloc.v/1.3888)*mousesensitivity;
+
+ mouserotation=(mouseloc.h/1.3888)*mousesensitivity;
+
+ mouserotation2=(mouseloc.v/1.3888)*mousesensitivity;
+
+
+
+ if(abs(oldmouseloc.h-mouseloc.h)<400)camera.rotation+=mouserotation-oldmouserotation;
+
+ if(abs(oldmouseloc.v-mouseloc.v)<200)camera.rotation2+=mouserotation2-oldmouserotation2;
+
+ if(mouseloc.h-oldmouseloc.h>400)camera.rotation+=mouserotation-oldmouserotation-(500/1.3888*mousesensitivity);
+
+ if(mouseloc.h-oldmouseloc.h<-400)camera.rotation+=mouserotation-oldmouserotation+(500/1.3888*mousesensitivity);
+
+ if(mouseloc.v-oldmouseloc.v>200)camera.rotation2+=mouserotation2-oldmouserotation2-(300/1.3888*mousesensitivity);
+
+ if(mouseloc.v-oldmouseloc.v<-200)camera.rotation2+=mouserotation2-oldmouserotation2+(300/1.3888*mousesensitivity);
+
+
+
+ if(camera.rotation2>89){camera.rotation2=89;}
+
+ if(camera.rotation2<-89){camera.rotation2=-89;}
+
+
+
+ //Smooth
+
+ camera.rotation=(camera.oldoldrotation+((camera.rotation-camera.oldoldrotation)*.7+(camera.oldrotation-camera.oldoldrotation)*.3));
+
+ camera.rotation2=(camera.oldoldrotation2+((camera.rotation2-camera.oldoldrotation2)*.7+(camera.oldrotation2-camera.oldoldrotation2)*.3));
+
+
+
+ if(camera.visrotation<camera.rotation-7)camera.visrotation=camera.rotation-7;
+
+ if(camera.visrotation>camera.rotation+7)camera.visrotation=camera.rotation+7;
+
+ if(camera.visrotation2<camera.rotation2-15)camera.visrotation2=camera.rotation2-15;
+
+ if(camera.visrotation2>camera.rotation2+15)camera.visrotation2=camera.rotation2+15;
+
+
+
+ if(zoom||person[0].aimamount<=0||person[0].whichgun==nogun||visions||person[0].whichgun==grenade||person[0].whichgun==knife){
+
+ camera.visrotation=camera.rotation;
+
+ camera.visrotation2=camera.rotation2;
+
+ }
+
+ oldzoom=zoom;
+
+
+
+ camera.oldoldrotation=camera.oldrotation;
+
+ camera.oldoldrotation2=camera.oldrotation2;
+
+ camera.oldrotation=camera.rotation;
+
+ camera.oldrotation2=camera.rotation2;
+
+
+
+ //Check collision with buildings
+
+
+
+ int beginx,endx;
+
+ int beginz,endz;
+
+ int distsquared;
+
+ XYZ collpoint;
+
+ XYZ move;
+
+ float howmuchintersect;
+
+ int whichtri;
+
+ float olddist;
+
+ XYZ nothing;
+
+ XYZ underpoint;
+
+ XYZ overpoint;
+
+ int pointnum;
+
+ float depth;
+
+ XYZ normalrotated;
+
+ XYZ pointrotated;
+
+ bool inblock;
+
+
+
+
+
+ person[0].playerrotation=180-camera.rotation;
+
+
+
+ //Check people collisions
+
+ for(int k=0;k<numpeople;k++){
+
+ person[k].DoStuff(k);
+
+ if(person[k].skeleton.free<1){
+
+ if(1==1){
+
+ person[k].onground=0;
+
+ overpoint=person[k].playercoords;
+
+ overpoint.y+=3000;
+
+ underpoint=person[k].playercoords;
+
+ underpoint.y-=3000;
+
+
+
+ beginx=(person[k].playercoords.x+block_spacing/2)/block_spacing;
+
+ if(beginx<0)beginx=0;
+
+ beginz=(person[k].playercoords.z+block_spacing/2)/block_spacing;
+
+ if(beginz<0)beginz=0;
+
+
+
+ endx=(person[k].playercoords.x+block_spacing/2)/block_spacing+1;
+
+ if(endx>num_blocks-1)endx=num_blocks-1;
+
+ endz=(person[k].playercoords.z+block_spacing/2)/block_spacing+1;
+
+ if(endz>num_blocks-1)endz=num_blocks-1;
+
+
+
+ if(k!=0){
+
+ beginx==person[k].whichblockx;
+
+ beginz==person[k].whichblocky;
+
+ endx==person[k].whichblockx;
+
+ endz==person[k].whichblocky;
+
+ }
+
+
+
+ if(beginx<=endx&&beginz<=endz)
+
+ for(int i=beginx;i<=endx;i++)
+
+ for(int j=beginz;j<=endz;j++){
+
+ inblock=0;
+
+ //Ground collision
+
+ move=0;
+
+ move.x=i*block_spacing;
+
+ move.z=j*block_spacing;
+
+ whichtri=sidewalkcollide.LineCheck2(overpoint,underpoint,&collpoint,move,cityrotation[i][j]*90);
+
+ if(whichtri!=-1&&person[k].playercoords.y<=collpoint.y&&person[k].velocity.y<=0){
+
+ person[k].playercoords.y=collpoint.y;
+
+ person[k].onground=1;
+
+ if(person[k].velocity.y<-maxfallvel)Splat(k);
+
+ else person[k].velocity.y=0;
+
+ }
+
+ if(whichtri!=-1){
+
+ inblock=1;
+
+ if(k==0){onblockx=i;onblocky=j;}
+
+ }
+
+ //Wall collision
+
+ if(k==0){
+
+ if(inblock){
+
+ for(int l=0;l<8;l++){
+
+ move=0;
+
+ move.x=i*block_spacing;
+
+ move.z=j*block_spacing;
+
+ whichtri=blockwalls[citytype[i][j]].LineCheck3(person[k].oldplayercoords+boundingpoints[l],person[k].playercoords+boundingpoints[l],&collpoint,move,cityrotation[i][j]*90,&depth);
+
+ if(whichtri!=-1){
+
+ normalrotated=DoRotation(blockwalls[citytype[i][j]].normals[whichtri],0,cityrotation[i][j]*90,0);
+
+ person[k].playercoords+=normalrotated*(-(dotproduct(normalrotated,person[k].playercoords-person[k].oldplayercoords))-depth);
+
+ }
+
+ }
+
+ for(int l=0;l<8;l++){
+
+ pointnum=k+1;
+
+ if(pointnum>3)pointnum=0;
+
+ move=0;
+
+ move.x=i*block_spacing;
+
+ move.z=j*block_spacing;
+
+ whichtri=blockwalls[citytype[i][j]].LineCheck3(person[k].playercoords+boundingpoints[l],person[k].playercoords+boundingpoints[pointnum],&collpoint,move,cityrotation[i][j]*90,&depth);
+
+ if(whichtri!=-1){
+
+ normalrotated=DoRotation(blockwalls[citytype[i][j]].normals[whichtri],0,cityrotation[i][j]*90,0);
+
+ person[k].playercoords+=normalrotated;
+
+ }
+
+ }
+
+ }
+
+ //Roof collision
+
+ if(inblock&&person[k].playercoords.y>30){
+
+ if(!person[k].onground){
+
+ move=0;
+
+ move.x=i*block_spacing;
+
+ move.z=j*block_spacing;
+
+ whichtri=blockroofs[citytype[i][j]].LineCheck2(overpoint,underpoint,&collpoint,move,cityrotation[i][j]*90);
+
+ if(whichtri!=-1&&person[k].playercoords.y<=collpoint.y&&person[k].velocity.y<=0){
+
+ person[k].playercoords.y=collpoint.y;
+
+ person[k].onground=1;
+
+ if(person[k].velocity.y<-maxfallvel)Splat(k);
+
+ else person[k].velocity.y=0;
+
+ }
+
+ if(whichtri!=-1)inblock=1;
+
+ }
+
+ }
+
+ }
+
+ }
+
+ if(person[k].playercoords.y<=0){
+
+ person[k].onground=1;
+
+ person[k].playercoords.y=0;
+
+ if(person[k].velocity.y<-maxfallvel)Splat(k);
+
+ else person[k].velocity.y=0;
+
+ if(k==0)onblockx=-1;onblocky=-1;
+
+ }
+
+ person[k].oldplayercoords=person[k].playercoords;
+
+ }
+
+ }
+
+ }
+
+
+
+ if(IsKeyDown( theKeyMap, MAC_SPACE_KEY )){
+
+ if(visions==0&&person[0].targetanimation==joganim&&person[0].currentanimation==joganim&&person[0].backwardsanim==0&&person[0].playerrotation==person[0].playerlowrotation){
+
+ person[0].targetanimation=diveanim;
+
+ person[0].targetframe=0;
+
+ person[0].target=0;
+
+ person[0].aimamount=0;
+
+ }
+
+ }
+
+
+
+ //Camera
+
+ camera.oldposition=camera.position;
+
+ camera.targetoffset=0;
+
+ camera.targetoffset.z=-5;
+
+
+
+
+
+ //Spawn people
+
+ spawndelay-=multiplier;
+
+ int blockspawnx,blockspawny;
+
+ blockspawnx=0;
+
+ blockspawny=0;
+
+ int cyclenum;
+
+ cyclenum=0;
+
+ while((citypeoplenum[blockspawnx][blockspawny]>=max_people_block&&cyclenum<10)||blockspawnx==0){
+
+ blockspawnx=((person[0].playercoords.x+block_spacing/2)/block_spacing)+Random()%2;
+
+ blockspawny=((person[0].playercoords.z+block_spacing/2)/block_spacing)+Random()%2;
+
+ cyclenum++;
+
+ }
+
+ if(cyclenum<10){
+
+ if(spawndelay<0&&numpeople<max_people){
+
+ if(type==randomshoot_type){
+
+ if(abs(Random()%evilprobability)==0)person[numpeople].type=eviltype;
+
+ else person[numpeople].type=civiliantype;
+
+ }
+
+ if(type==zombie_type){
+
+ person[numpeople].type=zombietype;
+
+ }
+
+
+
+ if(person[numpeople].type!=civiliantype&&blockspawnx==person[1].whichblockx&&blockspawny==person[1].whichblocky){
+
+ while((citypeoplenum[blockspawnx][blockspawny]>=max_people_block&&cyclenum<10)||blockspawnx==0||(blockspawnx==person[1].whichblockx&&blockspawny==person[1].whichblocky)){
+
+ blockspawnx=((person[0].playercoords.x+block_spacing/2)/block_spacing)+Random()%2;
+
+ blockspawny=((person[0].playercoords.z+block_spacing/2)/block_spacing)+Random()%2;
+
+ cyclenum++;
+
+ }
+
+ }
+
+
+
+ person[numpeople].playerrotation=0;
+
+
+
+ person[numpeople].whichcostume=casualcostumes+abs(Random())%numcasual;
+
+
+
+ person[numpeople].whichblockx=blockspawnx;
+
+ person[numpeople].whichblocky=blockspawny;
+
+
+
+ person[numpeople].pathnum=-1;
+
+ person[numpeople].oldpathnum=-1;
+
+ person[numpeople].oldoldpathnum=-1;
+
+ person[numpeople].oldoldoldpathnum=-1;
+
+ while(person[numpeople].pathnum<0||person[numpeople].pathnum>=path.vertexNum||person[numpeople].pathnum==1){
+
+ person[numpeople].pathnum=Random()%path.vertexNum;
+
+ }
+
+ person[numpeople].pathtarget.x=path.vertex[person[numpeople].pathnum].x;
+
+ person[numpeople].pathtarget.z=path.vertex[person[numpeople].pathnum].z;
+
+ person[numpeople].pathsize=.98+float(abs(Random()%20))/400;
+
+ person[numpeople].pathtarget*=person[numpeople].pathsize;
+
+ person[numpeople].pathtarget.x+=person[numpeople].whichblockx*block_spacing;
+
+ person[numpeople].pathtarget.z+=person[numpeople].whichblocky*block_spacing;
+
+
+
+
+
+ person[numpeople].playercoords=person[numpeople].pathtarget;
+
+ person[numpeople].oldplayercoords=person[numpeople].playercoords;
+
+ person[numpeople].skeleton.free=0;
+
+
+
+ person[numpeople].targetanimation=walkanim;
+
+ if(person[numpeople].type==zombietype)person[numpeople].targetanimation=zombiewalkanim;
+
+ person[numpeople].speed=1;
+
+ person[numpeople].existing=0;
+
+ person[numpeople].speedmult=.8+float(abs(Random()%20))/50;
+
+ person[numpeople].health=100;
+
+ person[numpeople].maxhealth=100;
+
+ person[numpeople].playerrotation2=0;
+
+
+
+ person[numpeople].lastdistancevictim=200000;
+
+
+
+ if(person[numpeople].skeleton.broken)person[numpeople].skeleton.Load((char *)":Data:Skeleton:Basic Figure");
+
+
+
+ if(numpeople==1)person[numpeople].type=viptype;
+
+
+
+ person[numpeople].killtarget=-1;
+
+
+
+ if(person[numpeople].type==eviltype){person[numpeople].existing=1; person[numpeople].pathsize=1.04; person[numpeople].whichgun=nogun; person[numpeople].aiming=1; person[numpeople].killtarget=-1; person[numpeople].speedmult=1+.3*difficulty;}
+
+ if(person[numpeople].type==zombietype){person[numpeople].existing=1; person[numpeople].pathsize=1.04; person[numpeople].whichgun=nogun; person[numpeople].aiming=0; person[numpeople].killtarget=-1; person[numpeople].speedmult=0.7+.2*difficulty;}
+
+ else {person[numpeople].whichgun=nogun; person[numpeople].aiming=0; person[numpeople].killtarget=-1;}
+
+
+
+ if(person[numpeople].type==viptype){person[numpeople].existing=1;}
+
+
+
+
+
+ if(enemystate==2)person[numpeople].killtarget=1;
+
+
+
+ numpeople++;
+
+ citypeoplenum[blockspawnx][blockspawny]++;
+
+ spawndelay=.1;
+
+ }
+
+ if(spawndelay<0&&numpeople>=max_people){
+
+ if(cycle>=max_people)cycle=0;
+
+ cyclenum=0;
+
+ while(cyclenum<max_people&&(person[cycle].type==playertype||person[cycle].type==viptype||(abs(person[cycle].whichblockx-((person[0].playercoords.x+block_spacing/2)/block_spacing))<2&&abs(person[cycle].whichblocky-((person[0].playercoords.z+block_spacing/2)/block_spacing))<2))){
+
+ cycle++;
+
+ cyclenum++;
+
+ if(cycle>=max_people)cycle=0;
+
+ }
+
+ if(cycle<max_people&&cyclenum<max_people){
+
+ if(type==randomshoot_type){
+
+ if(abs(Random()%evilprobability)==0)person[cycle].type=eviltype;
+
+ else person[cycle].type=civiliantype;
+
+ }
+
+ if(type==zombie_type){
+
+ person[cycle].type=zombietype;
+
+ }
+
+ if(person[cycle].type!=civiliantype&&blockspawnx==person[1].whichblockx&&blockspawny==person[1].whichblocky){
+
+ while((citypeoplenum[blockspawnx][blockspawny]>=max_people_block&&cyclenum<10)||blockspawnx==0||(blockspawnx==person[1].whichblockx&&blockspawny==person[1].whichblocky)){
+
+ blockspawnx=((person[0].playercoords.x+block_spacing/2)/block_spacing)+Random()%2;
+
+ blockspawny=((person[0].playercoords.z+block_spacing/2)/block_spacing)+Random()%2;
+
+ cyclenum++;
+
+ }
+
+ }
+
+ person[cycle].playerrotation=0;
+
+
+
+ person[cycle].whichcostume=casualcostumes+abs(Random())%numcasual;
+
+
+
+ citypeoplenum[person[cycle].whichblockx][person[cycle].whichblocky]--;
+
+ person[cycle].whichblockx=blockspawnx;
+
+ person[cycle].whichblocky=blockspawny;
+
+
+
+ person[cycle].pathnum=-1;
+
+ person[cycle].oldpathnum=-1;
+
+ person[cycle].oldoldpathnum=-1;
+
+ person[cycle].oldoldoldpathnum=-1;
+
+ while(person[cycle].pathnum<0||person[cycle].pathnum>=path.vertexNum||person[cycle].pathnum==1){
+
+ person[cycle].pathnum=Random()%path.vertexNum;
+
+ }
+
+ person[cycle].pathtarget.x=path.vertex[person[cycle].pathnum].x;
+
+ person[cycle].pathtarget.z=path.vertex[person[cycle].pathnum].z;
+
+ person[cycle].pathsize=.98+float(abs(Random()%20))/400;
+
+ person[cycle].pathtarget*=person[cycle].pathsize;
+
+ person[cycle].pathtarget.x+=person[cycle].whichblockx*block_spacing;
+
+ person[cycle].pathtarget.z+=person[cycle].whichblocky*block_spacing;
+
+
+
+ person[cycle].playercoords=person[cycle].pathtarget;
+
+ person[cycle].oldplayercoords=person[cycle].playercoords;
+
+ person[cycle].skeleton.free=0;
+
+
+
+ person[cycle].targetanimation=walkanim;
+
+ if(person[cycle].type==zombietype)person[cycle].targetanimation=zombiewalkanim;
+
+ person[cycle].speed=1;
+
+ person[cycle].existing=0;
+
+ person[cycle].speedmult=.8+float(abs(Random()%20))/50;
+
+ person[cycle].health=100;
+
+ person[cycle].maxhealth=100;
+
+ person[cycle].playerrotation2=0;
+
+
+
+ if(person[cycle].skeleton.broken)person[cycle].skeleton.Load((char *)":Data:Skeleton:Basic Figure");
+
+
+
+ if(enemystate==1)person[cycle].killtarget=-1;
+
+
+
+ if(person[cycle].type==eviltype){person[cycle].existing=1; person[cycle].pathsize=1.04; person[cycle].whichgun=nogun; person[cycle].aiming=1; person[cycle].killtarget=-1; person[cycle].speedmult=1+.3*difficulty;}
+
+ if(person[cycle].type==zombietype){person[cycle].existing=1; person[cycle].pathsize=1.04; person[cycle].whichgun=nogun; person[cycle].aiming=0; person[cycle].killtarget=-1; person[cycle].speedmult=.7+.2*difficulty;}
+
+ else {person[cycle].whichgun=nogun; person[cycle].aiming=0; person[cycle].killtarget=-1;}
+
+
+
+ person[cycle].lastdistancevictim=200000;
+
+
+
+ if(enemystate==2)person[cycle].killtarget=1;
+
+
+
+ if(numpeople<max_people)numpeople++;
+
+ citypeoplenum[blockspawnx][blockspawny]++;
+
+ cycle++;
+
+
+
+ spawndelay=.1;
+
+ }
+
+ }}
+
+
+
+ XYZ towards;
+
+ XYZ finaltarget;
+
+ XYZ blah;
+
+ int closesttarget;
+
+ float leastdistance;
+
+
+
+
+
+ XYZ bleedloc;
+
+ XYZ vel;
+
+
+
+ float tooclose;
+
+ float toofar;
+
+
+
+ //People
+
+ for(int i=0;i<numpeople;i++){
+
+ if(person[i].health<0&&person[i].longdead<0&&person[i].firstlongdead==0){
+
+ if(person[i].type!=zombietype){
+
+ overpoint=person[i].skeleton.joints[person[i].skeleton.jointlabels[abdomen]].position;
+
+ overpoint.y+=3000;
+
+ underpoint=person[i].skeleton.joints[person[i].skeleton.jointlabels[abdomen]].position;
+
+ underpoint.y-=3000;
+
+ move=0;
+
+ move.x=person[i].whichblockx*block_spacing;
+
+ move.z=person[i].whichblocky*block_spacing;
+
+ XYZ temp;
+
+ whichtri=sidewalkcollide.LineCheck2(overpoint,underpoint,&temp,move,cityrotation[person[i].whichblockx][person[i].whichblocky]*90);
+
+ XYZ normish;
+
+ normish=0;
+
+ normish.y=1;
+
+ if(whichtri>=0){
+
+ decals.MakeDecal(bloodpool,temp,12,normish, whichtri, &sidewalkcollide, move, cityrotation[person[i].whichblockx][person[i].whichblocky]*90);
+
+ }
+
+ if(whichtri==-1){
+
+ temp=person[i].skeleton.joints[person[i].skeleton.jointlabels[abdomen]].position;
+
+ temp.y=-.5;
+
+ move=0;
+
+ decals.MakeDecal(bloodpool,temp,12,normish, 0, &sidewalkcollide, move, 0);
+
+ }
+
+ person[i].firstlongdead=1;
+
+ }
+
+ }
+
+ if(person[i].health<100&&person[i].type!=zombietype){
+
+ person[i].health-=multiplier*120;
+
+ }
+
+ if(person[i].health<100&&person[i].type==zombietype){
+
+ person[i].health+=multiplier*10;
+
+ if(person[i].health>person[i].maxhealth)person[i].health=person[i].maxhealth;
+
+ }
+
+ if(person[i].health<100&&person[i].type==zombietype&&person[i].skeleton.free==1){
+
+ person[i].health+=multiplier*10;
+
+ if(person[i].health>person[i].maxhealth)person[i].health=person[i].maxhealth;
+
+ }
+
+ if(person[i].health<40&&person[i].type==zombietype){
+
+ person[i].speedmult-=multiplier/20;
+
+ if(person[i].speedmult<.6){
+
+ person[i].speedmult=.6;
+
+ person[i].killtarget=-1;
+
+ }
+
+ }
+
+ if(person[i].health>=40&&person[i].type==zombietype){
+
+ person[i].speedmult+=multiplier/40;
+
+ if(person[i].speedmult>.7+difficulty*.2){
+
+ person[i].speedmult=.7+difficulty*.2;
+
+ person[i].killtarget=1;
+
+ }
+
+ }
+
+
+
+ if(person[i].maxhealth<100&&person[i].type==zombietype){
+
+ person[i].maxhealth+=multiplier*2;
+
+ if(person[i].maxhealth>100)person[i].maxhealth=100;
+
+ }
+
+ if(person[i].bleeding>0){
+
+ person[i].bleeding-=multiplier;
+
+ person[i].bleeddelay-=multiplier*10;
+
+ if(person[i].bleeddelay<=0){
+
+ person[i].bleeddelay=1;
+
+ if(person[i].skeleton.free==0){
+
+ bleedloc=DoRotation((person[i].bjoint1->position+person[i].bjoint2->position)/2,0,person[i].playerrotation,0)+person[i].playercoords;
+
+ }
+
+ if(person[i].skeleton.free>0){
+
+ bleedloc=(person[i].bjoint1->position+person[i].bjoint2->position)/2;
+
+ }
+
+ vel=0;
+
+ sprites.MakeSprite(bloodspritedown, .6, 1, .2, .2,bleedloc, vel, 3*person[i].bleeding);
+
+ }
+
+ }
+
+ if(person[i].skeleton.free==0){
+
+ //Gun
+
+ if(person[i].type==playertype||person[i].type==eviltype){
+
+ if(i==0){
+
+ if(person[i].whichgun==shotgun)person[i].recoil-=multiplier*4;
+
+ if(person[i].whichgun==sniperrifle)person[i].recoil-=multiplier*2;
+
+ if(person[i].whichgun==handgun1)person[i].recoil-=multiplier*5;
+
+ if(person[i].whichgun==handgun2)person[i].recoil-=multiplier*5;
+
+ if(person[i].whichgun==assaultrifle)person[i].recoil-=multiplier*10;
+
+ }
+
+ if(i!=0){
+
+ if(person[i].whichgun==shotgun)person[i].recoil-=multiplier*1;
+
+ if(person[i].whichgun==sniperrifle)person[i].recoil-=multiplier*1;
+
+ if(person[i].whichgun==handgun1)person[i].recoil-=multiplier*2;
+
+ if(person[i].whichgun==handgun2)person[i].recoil-=multiplier*2;
+
+ if(person[i].whichgun==assaultrifle)person[i].recoil-=multiplier*10;
+
+ }
+
+ if(person[i].recoil<0)person[i].recoil=0;
+
+ if(i==0){
+
+ if(zoom){
+
+ mousesensitivity=.05*usermousesensitivity;
+
+ if(person[i].targetanimation!=crouchanim||person[i].currentanimation!=crouchanim||person[i].aiming<1){
+
+ zoom=0;
+
+ }
+
+ if(visions==1)zoom=0;
+
+ }
+
+ if(person[i].currentanimation==crouchanim&&person[i].targetanimation==crouchanim&&person[i].aiming>=1&&person[i].whichgun==sniperrifle){
+
+ zoom=1;
+
+ if(zoom&&!oldzoom)camera.rotation2-=6;
+
+ }
+
+ if(!zoom)mousesensitivity=1*usermousesensitivity;
+
+ if(person[i].whichgun!=sniperrifle)zoom=0;
+
+ }
+
+ }
+
+ //Zombie eat
+
+ if(i>0&&person[person[i].killtarget].eaten==i&&person[i].targetanimation==zombieeatanim){
+
+ person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[head]].locked=1;
+
+ person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[rightshoulder]].locked=1;
+
+ for(int k=0;k<2;k++){
+
+ person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[head]].position=DoRotation(person[i].skeleton.joints[person[i].skeleton.jointlabels[righthand]].position,0,person[i].playerrotation,0)+person[i].playercoords;
+
+ person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[head]].velocity=0;
+
+ person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[rightshoulder]].position=DoRotation(person[i].skeleton.joints[person[i].skeleton.jointlabels[lefthand]].position,0,person[i].playerrotation,0)+person[i].playercoords;
+
+ person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[rightshoulder]].velocity=0;
+
+ person[person[i].killtarget].skeleton.DoConstraints();
+
+ person[person[i].killtarget].skeleton.DoConstraints(&blocksimplecollide[citytype[person[i].whichblockx][person[i].whichblocky]],&move,cityrotation[person[i].whichblockx][person[i].whichblocky]*90);
+
+ }
+
+ person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[head]].locked=0;
+
+ person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[rightshoulder]].locked=0;
+
+
+
+ person[person[i].killtarget].longdead=1;
+
+ }
+
+
+
+ if(i>0&&enemystate!=1&&person[i].type==zombietype&&person[i].speedmult>.7){
+
+ if(findDistancefast(person[i].playercoords,person[1].playercoords)<20000)person[i].killtarget=1;
+
+ else person[i].killtarget=-1;
+
+ }
+
+ if(i>0&&enemystate!=1&&person[i].type==zombietype&&person[i].speedmult<.7){
+
+ person[i].killtarget=-1;
+
+ }
+
+
+
+ bool realcheck;
+
+ //Pathfinding
+
+ if(i>0&&person[i].targetanimation!=getupfrontanim&&person[i].targetanimation!=thrownanim&&person[i].targetanimation!=getupbackanim&&person[i].currentanimation!=getupfrontanim&&person[i].currentanimation!=getupbackanim){
+
+ person[i].pathcheckdelay-=multiplier;
+
+ realcheck=(abs(person[i].playercoords.x-person[i].pathtarget.x)<1&&abs(person[i].playercoords.z-person[i].pathtarget.z)<1)||findDistancefast(person[i].playercoords,person[i].pathtarget)>findDistancefast(person[i].oldplayercoords,person[i].pathtarget);
+
+ if(person[i].targetanimation==idleanim&&person[i].killtargetvisible==0){
+
+ person[i].targetanimation=walkanim;
+
+ if(person[i].type==zombietype)person[i].targetanimation=zombiewalkanim;
+
+ realcheck=1;
+
+ }
+
+ if((realcheck||((person[i].killtarget>-1&&person[i].type!=civiliantype)&&person[i].pathcheckdelay<=0)||person[i].killtargetvisible)){
+
+ person[i].pathcheckdelay=1.2;
+
+ if((person[i].killtarget==-1||person[i].type==civiliantype)&&!person[i].running){
+
+ person[i].killtargetvisible=0;
+
+ leastdistance=2000000;
+
+ for(int j=0;j<path.vertexNum;j++){
+
+ person[i].pathtarget.x=path.vertex[j].x;
+
+ person[i].pathtarget.z=path.vertex[j].z;
+
+ person[i].pathtarget.y=path.vertex[j].y;
+
+ person[i].pathtarget*=person[i].pathsize;
+
+ person[i].pathtarget.x+=person[i].whichblockx*block_spacing;
+
+ person[i].pathtarget.z+=person[i].whichblocky*block_spacing;
+
+ if(findDistancefast(person[i].playercoords,person[i].pathtarget)<leastdistance&&j!=1&&j!=person[i].oldpathnum&&j!=person[i].oldoldpathnum&&j!=person[i].oldoldoldpathnum){
+
+ leastdistance=findDistancefast(person[i].playercoords,person[i].pathtarget);
+
+ closesttarget=j;
+
+ }
+
+ }
+
+ if(closesttarget>=0&&closesttarget<path.vertexNum){
+
+ person[i].oldoldoldpathnum=person[i].oldoldpathnum;
+
+ person[i].oldoldpathnum=person[i].oldpathnum;
+
+ person[i].oldpathnum=person[i].pathnum;
+
+ person[i].pathnum=closesttarget;
+
+ person[i].pathtarget.x=path.vertex[person[i].pathnum].x;
+
+ person[i].pathtarget.z=path.vertex[person[i].pathnum].z;
+
+ person[i].pathtarget*=person[i].pathsize;
+
+ person[i].pathtarget.x+=person[i].whichblockx*block_spacing;
+
+ person[i].pathtarget.z+=person[i].whichblocky*block_spacing;
+
+ }
+
+ }
+
+ if(person[i].running&&realcheck){
+
+ person[i].killtargetvisible=0;
+
+ person[i].targetanimation=joganim;
+
+ //Dead target?
+
+ if(person[person[i].killtarget].health<=0){
+
+ person[i].running=0;
+
+ }
+
+ person[i].killtarget=1;
+
+
+
+ //If pathfind
+
+ if(realcheck){
+
+ leastdistance=2000000;
+
+ person[i].lastdistancevictim=0;
+
+ closesttarget=-1;
+
+ //Check best path
+
+ closesttarget=person[i].pathnum;
+
+ //Check other blocks?
+
+ if((closesttarget==person[i].pathnum)){
+
+ beginx=person[i].whichblockx-2;
+
+ if(beginx<0)beginx=0;
+
+ beginz=person[i].whichblocky-2;
+
+ if(beginz<0)beginz=0;
+
+
+
+ endx=person[i].whichblockx+2;
+
+ if(endx>num_blocks-1)endx=num_blocks-1;
+
+ endz=person[i].whichblocky+2;
+
+ if(endz>num_blocks-1)endz=num_blocks-1;
+
+
+
+ leastdistance=2000000;
+
+ for(int l=beginx;l<=endx;l++){
+
+ for(int m=beginx;m<=endx;m++){
+
+ for(int j=0;j<path.vertexNum;j++){
+
+ person[i].pathtarget.x=path.vertex[j].x;
+
+ person[i].pathtarget.y=path.vertex[j].y;
+
+ person[i].pathtarget.z=path.vertex[j].z;
+
+ person[i].pathtarget*=person[i].pathsize;
+
+ person[i].pathtarget.x+=l*block_spacing;
+
+ person[i].pathtarget.z+=m*block_spacing;
+
+ if(findDistancefast(person[i].playercoords,person[i].pathtarget)<leastdistance&&findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords)>findDistancefast(person[i].playercoords,person[person[i].killtarget].playercoords)&&j!=1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[person[i].whichblockx][person[i].whichblocky])==-1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[l][m])==-1){
+
+ person[i].lastdistancevictim=findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords);
+
+ leastdistance=findDistancefast(person[i].playercoords,person[i].pathtarget);
+
+ closesttarget=j;
+
+ finaltarget=person[i].pathtarget;
+
+ person[i].whichblockx=l;
+
+ person[i].whichblocky=m;
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ if(closesttarget!=-1){
+
+ person[i].pathnum=closesttarget;
+
+ person[i].pathtarget=finaltarget;
+
+ }
+
+ }
+
+ }
+
+ //Assassin
+
+ if((person[i].killtarget>-1&&person[i].type!=civiliantype)&&!person[i].running){
+
+ //Dead target?
+
+ if(person[person[i].killtarget].health<=0&&person[i].type==eviltype){
+
+ person[i].playerrotation2=0;
+
+ person[i].whichgun=nogun;
+
+ person[i].targetanimation=walkanim;
+
+ person[i].lastdistancevictim=200000;
+
+ person[i].pathnum=-1;
+
+ enemystate=1;
+
+ person[i].killtarget=-1;
+
+ realcheck=1;
+
+ }
+
+ if(person[i].type==zombietype&&person[person[i].killtarget].health<=0){
+
+ if(person[person[i].killtarget].eaten!=i){
+
+ person[i].playerrotation2=0;
+
+ person[i].targetanimation=zombiewalkanim;
+
+ person[i].lastdistancevictim=200000;
+
+ person[i].pathnum=-1;
+
+ realcheck=1;
+
+ person[i].killtarget=-1;
+
+ }
+
+ if(person[person[i].killtarget].eaten==i&&person[i].targetanimation!=zombieeatanim){
+
+ person[i].targetanimation=zombieeatanim;
+
+ person[i].targetframe=0;
+
+ person[i].target=0;
+
+ }
+
+ enemystate=1;
+
+ }
+
+ if(person[person[i].killtarget].health>0){
+
+ if(person[person[i].killtarget].skeleton.free){
+
+ person[person[i].killtarget].playercoords=person[person[i].killtarget].averageloc;
+
+ }
+
+
+
+ //If pathfind
+
+ if(realcheck){
+
+ leastdistance=2000000;
+
+ person[i].lastdistancevictim=2000000;
+
+ closesttarget=-1;
+
+ //Check best path
+
+ for(int j=0;j<path.vertexNum;j++){
+
+ person[i].pathtarget.x=path.vertex[j].x;
+
+ person[i].pathtarget.z=path.vertex[j].z;
+
+ person[i].pathtarget.y=path.vertex[j].y;
+
+ person[i].pathtarget*=person[i].pathsize;
+
+ person[i].pathtarget.x+=person[i].whichblockx*block_spacing;
+
+ person[i].pathtarget.z+=person[i].whichblocky*block_spacing;
+
+ if(findDistancefast(person[i].playercoords,person[i].pathtarget)<leastdistance&&findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords)<person[i].lastdistancevictim&&j!=1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[person[i].whichblockx][person[i].whichblocky])==-1){
+
+ leastdistance=findDistancefast(person[i].playercoords,person[i].pathtarget);
+
+ person[i].lastdistancevictim=findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords);
+
+ closesttarget=j;
+
+ finaltarget=person[i].pathtarget;
+
+ }
+
+ }
+
+ leastdistance=2000000;
+
+ for(int j=0;j<path.vertexNum;j++){
+
+ person[i].pathtarget.x=path.vertex[j].x;
+
+ person[i].pathtarget.z=path.vertex[j].z;
+
+ person[i].pathtarget.y=path.vertex[j].y;
+
+ person[i].pathtarget*=person[i].pathsize;
+
+ person[i].pathtarget.x+=person[i].whichblockx*block_spacing;
+
+ person[i].pathtarget.z+=person[i].whichblocky*block_spacing;
+
+ if(findDistancefast(person[i].playercoords,person[i].pathtarget)<leastdistance&&findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords)<person[i].lastdistancevictim&&j!=1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[person[i].whichblockx][person[i].whichblocky])==-1){
+
+ leastdistance=findDistancefast(person[i].playercoords,person[i].pathtarget);
+
+ person[i].lastdistancevictim=findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords);
+
+ closesttarget=j;
+
+ finaltarget=person[i].pathtarget;
+
+ }
+
+ }
+
+ //Check other blocks?
+
+ if((closesttarget==person[i].pathnum)||closesttarget==-1){
+
+ beginx=person[i].whichblockx-2;
+
+ if(beginx<0)beginx=0;
+
+ beginz=person[i].whichblocky-2;
+
+ if(beginz<0)beginz=0;
+
+
+
+ endx=person[i].whichblockx+2;
+
+ if(endx>num_blocks-1)endx=num_blocks-1;
+
+ endz=person[i].whichblocky+2;
+
+ if(endz>num_blocks-1)endz=num_blocks-1;
+
+
+
+ leastdistance=2000000;
+
+ for(int l=beginx;l<=endx;l++){
+
+ for(int m=beginx;m<=endx;m++){
+
+ if(l!=person[i].whichblockx||m!=person[i].whichblocky){
+
+ for(int j=0;j<path.vertexNum;j++){
+
+ person[i].pathtarget.x=path.vertex[j].x;
+
+ person[i].pathtarget.y=path.vertex[j].y;
+
+ person[i].pathtarget.z=path.vertex[j].z;
+
+ person[i].pathtarget*=person[i].pathsize;
+
+ person[i].pathtarget.x+=l*block_spacing;
+
+ person[i].pathtarget.z+=m*block_spacing;
+
+ if(findDistancefast(person[i].playercoords,person[i].pathtarget)<leastdistance&&findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords)<findDistancefast(person[i].playercoords,person[person[i].killtarget].playercoords)&&j!=1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[l][m])==-1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[person[i].whichblockx][person[i].whichblocky])==-1){
+
+ leastdistance=findDistancefast(person[i].playercoords,person[i].pathtarget);
+
+ closesttarget=j;
+
+ finaltarget=person[i].pathtarget;
+
+ person[i].whichblockx=l;
+
+ person[i].whichblocky=m;
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ if(closesttarget!=-1){
+
+ person[i].onpath=1;
+
+ person[i].pathnum=closesttarget;
+
+ person[i].pathtarget=finaltarget;
+
+ }
+
+ }
+
+ //Check killtargetvisible
+
+ person[i].killtargetvisible=1;
+
+ if(person[person[i].killtarget].health<=0)person[i].killtargetvisible=0;
+
+ if(closesttarget!=-1&&findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)>30000)person[i].killtargetvisible=0;
+
+ if(person[i].killtarget==0&&visions==1)person[i].killtargetvisible=0;
+
+ if(person[i].killtargetvisible){
+
+ beginx=person[i].whichblockx-2;
+
+ if(beginx<0)beginx=0;
+
+ beginz=person[i].whichblocky-2;
+
+ if(beginz<0)beginz=0;
+
+
+
+ endx=person[i].whichblockx+2;
+
+ if(endx>num_blocks-1)endx=num_blocks-1;
+
+ endz=person[i].whichblocky+2;
+
+ if(endz>num_blocks-1)endz=num_blocks-1;
+
+
+
+ for(int l=beginx;l<=endx;l++){
+
+ for(int m=beginx;m<=endx;m++){
+
+ move.x=l*block_spacing;
+
+ move.z=m*block_spacing;
+
+ move.y=-3;
+
+ if(person[i].killtargetvisible){
+
+ if(blocksimple.LineCheck2(person[i].playercoords,person[person[i].killtarget].playercoords,&blah,move,cityrotation[l][m])!=-1)
+
+ {
+
+ person[i].killtargetvisible=0;
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ if(person[i].type==eviltype){
+
+ if(!person[i].killtargetvisible&&person[i].targetanimation==idleanim){
+
+ person[i].targetanimation=joganim;
+
+ }
+
+ if(!person[i].killtargetvisible){
+
+ person[i].aiming=0;
+
+ }
+
+ if(person[i].killtargetvisible){
+
+ person[i].onpath=0;
+
+ person[i].lastdistancevictim=200000;
+
+ person[i].pathnum=-1;
+
+ if(person[i].whichgun==nogun){
+
+ person[i].whichgun=possiblegun[abs(Random()%numpossibleguns)];
+
+ person[i].reloads[person[i].whichgun]=1;
+
+ if(person[i].whichgun==knife)person[i].speedmult=.8+.5*difficulty;
+
+ }
+
+ if(person[i].aiming==0)person[i].shotdelay=shotdelayamount/difficulty;
+
+ person[i].aiming=1;
+
+ if(person[i].reloading>0)person[i].aiming=0;
+
+ if(person[i].whichgun==handgun1||person[i].whichgun==handgun2)person[i].playerrotation2=-10;
+
+ if(person[i].whichgun==assaultrifle||person[i].whichgun==sniperrifle||person[i].whichgun==shotgun)person[i].playerrotation2=20;
+
+ tooclose=1300;
+
+ toofar=3000;
+
+ if(person[i].whichgun==shotgun){
+
+ tooclose=1400;
+
+ toofar=5000;
+
+ }
+
+ if(person[i].whichgun==assaultrifle){
+
+ tooclose=5000;
+
+ toofar=9000;
+
+ }
+
+ if(person[i].whichgun==sniperrifle){
+
+ tooclose=10000;
+
+ toofar=20000;
+
+ }
+
+ if(person[i].whichgun==knife){
+
+ tooclose=20;
+
+ toofar=20000;
+
+ }
+
+ if(findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)>toofar)
+
+ person[i].targetanimation=joganim;
+
+ if((findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)<=tooclose&&person[person[i].killtarget].skeleton.free==0)||(tooclose>200&&findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)<=200)||(tooclose<=200&&findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)<tooclose)){
+
+ if(person[i].targetanimation!=idleanim){
+
+ person[i].targetanimation=idleanim;
+
+ person[i].targetframe=0;
+
+ person[i].target=0;
+
+ }
+
+ if(person[i].whichgun==knife&&person[person[i].killtarget].health==100){
+
+ murderer=i;
+
+ person[i].attacktarget=0;
+
+ person[i].attackframe=0;
+
+ float gLoc[3];
+
+ gLoc[0]=(camera.position.x+((person[i].playercoords.x+flatfacing.x)-camera.position.x)/2)/soundscalefactor;
+
+ gLoc[1]=(camera.position.y+((person[i].playercoords.y+flatfacing.y)-camera.position.y)/2)/soundscalefactor;
+
+ gLoc[2]=(camera.position.z+((person[i].playercoords.z+flatfacing.z)-camera.position.z)/2)/soundscalefactor;
+
+ if(person[person[i].killtarget].type!=zombietype)
+
+ {
+
+ alSourcefv(gSourceID[knifeslashsound], AL_POSITION, gLoc);
+
+ alSourcePlay(gSourceID[knifeslashsound]);
+
+ person[person[i].killtarget].bjoint1=&person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[neck]];
+
+ person[person[i].killtarget].bjoint2=&person[person[i].killtarget].skeleton.joints[person[person[i].killtarget].skeleton.jointlabels[neck]];
+
+ person[person[i].killtarget].bleeding=1;
+
+ person[person[i].killtarget].bleeddelay=1;
+
+ person[person[i].killtarget].health-=20;
+
+ person[person[i].killtarget].targetanimation=chestpainanim;
+
+ person[person[i].killtarget].targetframe=0;
+
+ person[person[i].killtarget].target=0;
+
+ person[person[i].killtarget].longdead=1;
+
+ }
+
+ }
+
+ }
+
+ finaltarget=person[person[i].killtarget].playercoords;
+
+ }
+
+ }
+
+ if(person[i].type==zombietype&&person[person[i].killtarget].health>0){
+
+ if(!person[i].killtargetvisible&&person[i].targetanimation==idleanim){
+
+ person[i].targetanimation=zombiejoganim;
+
+ }
+
+ if(!person[i].killtargetvisible){
+
+ person[i].aiming=0;
+
+ }
+
+ if(person[i].killtargetvisible){
+
+ person[i].onpath=0;
+
+ person[i].lastdistancevictim=200000;
+
+ person[i].pathnum=-1;
+
+ if(person[i].aiming==0)person[i].shotdelay=shotdelayamount/difficulty;
+
+ if(findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)>20||person[i].targetanimation!=idleanim)
+
+ person[i].targetanimation=zombiejoganim;
+
+ if(findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)<=20){
+
+ murderer=i;
+
+ person[person[i].killtarget].health=0;
+
+ person[person[i].killtarget].eaten=i;
+
+ }
+
+ finaltarget=person[person[i].killtarget].playercoords;
+
+ }
+
+ }
+
+ if(person[i].killtargetvisible||realcheck)person[i].pathtarget=finaltarget;
+
+ if(realcheck)person[i].lastdistancevictim=findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords);
+
+ }
+
+ }
+
+
+
+ if(person[i].targetanimation!=zombieeatanim||person[i].type!=zombietype){
+
+ towards=person[i].playercoords-person[i].pathtarget;
+
+ Normalise(&towards);
+
+ person[i].playerrotation=asin(0-towards.x)*360/6.28;
+
+ if(towards.z>0)person[i].playerrotation=180-person[i].playerrotation;
+
+ }
+
+ }
+
+ }
+
+
+
+ person[i].whichblockx=((person[i].playercoords.x+block_spacing/2)/block_spacing);
+
+ person[i].whichblocky=((person[i].playercoords.z+block_spacing/2)/block_spacing);
+
+
+
+ if(!person[i].onground)person[i].velocity.y+=multiplier*gravity;
+
+ if(!person[i].onground&&(i!=0||visions!=1))person[i].playercoords+=person[i].velocity*multiplier;
+
+ //Death by bleeding/shock
+
+ if(person[i].health<=0){
+
+ person[i].skeleton.offset=0;
+
+ person[i].skeleton.free=1;
+
+ person[i].longdead=1;
+
+ for(int j=0;j<person[i].skeleton.num_joints;j++){
+
+ person[i].skeleton.joints[j].position+=person[i].skeleton.joints[j].offset;
+
+ person[i].skeleton.joints[j].position=DoRotation(person[i].skeleton.joints[j].position,0,person[i].playerrotation,0);
+
+ person[i].skeleton.joints[j].position+=person[i].playercoords;
+
+ person[i].skeleton.joints[j].realoldposition=person[i].skeleton.joints[j].position;
+
+ person[i].skeleton.joints[j].velocity=DoRotation(person[i].skeleton.joints[j].velocity,0,person[i].playerrotation,0);
+
+ person[i].skeleton.joints[j].velocity+=person[i].velocity;
+
+ person[i].skeleton.joints[j].velocity+=person[i].facing*4;
+
+ }
+
+ }
+
+ }
+
+ //Rag doll
+
+ if(person[i].skeleton.free==1&&person[i].longdead>0){
+
+ person[i].whichblockx=((person[i].skeleton.joints[0].position.x+block_spacing/2)/block_spacing);
+
+ person[i].whichblocky=((person[i].skeleton.joints[0].position.z+block_spacing/2)/block_spacing);
+
+ move=0;
+
+ move.x=person[i].whichblockx*block_spacing;
+
+ move.z=person[i].whichblocky*block_spacing;
+
+ person[i].skeleton.DoGravity();
+
+ if(person[i].averageloc.y<=50)person[i].skeleton.DoConstraints(&blocksimplecollide[citytype[person[i].whichblockx][person[i].whichblocky]],&move,cityrotation[person[i].whichblockx][person[i].whichblocky]*90);
+
+ if(person[i].averageloc.y>50)person[i].skeleton.DoConstraints(&blockcollide[citytype[person[i].whichblockx][person[i].whichblocky]],&move,cityrotation[person[i].whichblockx][person[i].whichblocky]*90);
+
+ person[i].oldaverageloc=person[i].averageloc;
+
+ person[i].averageloc=0;
+
+ for(int j=0;j<person[i].skeleton.num_joints;j++){
+
+ person[i].averageloc+=person[i].skeleton.joints[j].position;
+
+ }
+
+ person[i].averageloc/=person[i].skeleton.num_joints;
+
+ person[i].playercoords=person[i].averageloc;
+
+ if(person[i].longdead<multiplier/2&&person[i].longdead>0)person[i].DrawSkeleton(i);
+
+ if(findDistancefast(person[i].averageloc,person[i].oldaverageloc)<.2*multiplier)person[i].longdead-=multiplier/2;
+
+ }
+
+ if(person[i].skeleton.free==1&&person[i].longdead<=0&&person[i].health>0&&person[i].longdead!=-1){
+
+ person[i].longdead=1;
+
+ person[i].skeleton.free=0;
+
+ person[i].currentanimation=lyinganim;
+
+ person[i].target=0;
+
+ person[i].targetframe=0;
+
+ //Get up from front or back?
+
+ if(person[i].skeleton.forward.y>0)
+
+ person[i].targetanimation=getupfrontanim;
+
+ else
+
+ person[i].targetanimation=getupbackanim;
+
+ //Find playercoords
+
+ person[i].playercoords=person[i].averageloc;
+
+ for(int j=0;j<person[i].skeleton.num_joints;j++){
+
+ if(person[i].skeleton.joints[j].position.y>person[i].playercoords.y)person[i].playercoords.y=person[i].skeleton.joints[j].position.y;
+
+ }
+
+ //Find orientation
+
+ XYZ firsttop=person[i].skeleton.joints[person[i].skeleton.jointlabels[neck]].position-person[i].skeleton.joints[person[i].skeleton.jointlabels[groin]].position;
+
+ Normalise(&firsttop);
+
+ person[i].playerrotation=acos(0-firsttop.z);
+
+ person[i].playerrotation*=360/6.28;
+
+ if(0>firsttop.x)person[i].playerrotation=360-person[i].playerrotation;
+
+ person[i].playerrotation*=-1;
+
+ person[i].playervelocity=0;
+
+ if(person[i].targetanimation==getupfrontanim)person[i].playerrotation+=180;
+
+ for(int j=0;j<person[i].skeleton.num_joints;j++){
+
+ person[i].tempanimation.position[j][0]=person[i].skeleton.joints[j].position-person[i].playercoords;
+
+ person[i].tempanimation.position[j][0]=DoRotation(person[i].tempanimation.position[j][0],0,-person[i].playerrotation,0);
+
+ }
+
+ }
+
+ }
+
+
+
+ //Grenade
+
+ if(Button()&&person[0].whichgun==grenade&&person[0].ammo>0&&person[0].reloading<=0&&person[0].attackframe<0&&person[0].targetanimation!=crouchanim){
+
+ if(person[0].grenphase==0){
+
+ XYZ soundsource=DoRotation(person[0].skeleton.joints[person[0].skeleton.jointlabels[righthand]].position,0,person[0].playerrotation,0)+person[0].playercoords;
+
+ float gLoc[3];
+
+ gLoc[0]=soundsource.x/soundscalefactor;
+
+ gLoc[1]=soundsource.y/soundscalefactor;
+
+ gLoc[2]=soundsource.z/soundscalefactor;
+
+ alSourcefv(gSourceID[pinpullsound], AL_POSITION, gLoc);
+
+ alSourcePlay(gSourceID[pinpullsound]);
+
+ person[0].grenphase=1;
+
+ }
+
+ }
+
+ if((!Button())&&person[0].whichgun==grenade){
+
+ if(person[0].grenphase==1){
+
+ person[0].grenphase=0;
+
+ person[0].attackframe=0;
+
+ person[0].attacktarget=0;
+
+ person[0].killtarget=0;
+
+ }
+
+ }
+
+ if(person[0].targetanimation==crouchanim){
+
+ if(person[0].grenphase==1){
+
+ person[0].grenphase=0;
+
+ XYZ soundsource=DoRotation(person[0].skeleton.joints[person[0].skeleton.jointlabels[righthand]].position,0,person[0].playerrotation,0)+person[0].playercoords;
+
+ float gLoc[3];
+
+ gLoc[0]=soundsource.x/soundscalefactor;
+
+ gLoc[1]=soundsource.y/soundscalefactor;
+
+ gLoc[2]=soundsource.z/soundscalefactor;
+
+ alSourcefv(gSourceID[pinreplacesound], AL_POSITION, gLoc);
+
+ alSourcePlay(gSourceID[pinreplacesound]);
+
+ }
+
+ }
+
+
+
+ //Get gun
+
+ int temp;
+
+ int temp2;
+
+ bool switched=0;
+
+ if(Button()&&!oldbutton&&(person[0].aiming==0||person[0].whichgun==grenade||person[0].whichgun==nogun||person[0].whichgun==knife)&&person[0].currentanimation==crouchanim){
+
+ for(int i=0;i<max_people;i++){
+
+ if(!switched&&person[i].skeleton.free==1&&findDistancefast(person[0].playercoords,person[i].averageloc)<200){
+
+ float gLoc[3];
+
+ gLoc[0]=person[0].playercoords.x/soundscalefactor;
+
+ gLoc[1]=person[0].playercoords.y/soundscalefactor;
+
+ gLoc[2]=person[0].playercoords.z/soundscalefactor;
+
+
+
+ alSourcefv(gSourceID[clicksound], AL_POSITION, gLoc);
+
+ alSourcePlay(gSourceID[clicksound]);
+
+
+
+ temp=person[0].whichgun;
+
+ temp2=person[0].ammo;
+
+ person[0].whichgun=person[i].whichgun;
+
+ person[0].ammo=person[i].ammo;
+
+ person[i].whichgun=temp;
+
+ person[i].ammo=temp2;
+
+ person[0].aiming=1;
+
+ person[0].aimamount=0;
+
+
+
+ switched=1;
+
+ }
+
+ }
+
+ }
+
+
+
+ //Throw
+
+ if(Button()&&person[0].attackframe<0&&((person[0].whichgun==nogun||person[0].aiming==0)&&person[0].whichgun!=knife)&&person[0].currentanimation!=crouchanim&&person[0].targetanimation!=crouchanim&&person[0].targetanimation!=throwanim&&visions==0){
+
+ if(person[0].targetanimation==idleanim||person[0].targetanimation==walkanim){
+
+ bool attacking=0;
+
+ person[0].killtarget=-1;
+
+ float closedistance=-1;
+
+ for(int i=1;i<numpeople;i++){
+
+ if(person[i].skeleton.free<1&&(person[i].whichgun!=nogun)&&findDistancefast(person[i].playercoords,person[0].playercoords+flatfacing)<12){
+
+ attacking=1;
+
+ if(person[0].killtarget==-1||findDistancefast(person[i].playercoords,person[0].playercoords)<closedistance){
+
+ person[0].killtarget=i;
+
+ closedistance=findDistancefast(person[i].playercoords,person[0].playercoords);
+
+ }
+
+ }
+
+ }
+
+ if(attacking){
+
+ score+=150;
+
+ person[0].aiming=1;
+
+ person[0].whichgun=person[person[0].killtarget].whichgun;
+
+ person[0].ammo=person[person[0].killtarget].ammo;
+
+ person[person[0].killtarget].whichgun=nogun;
+
+ person[person[0].killtarget].killtarget=-1;
+
+ person[0].targetframe=0;
+
+ person[0].targetanimation=throwanim;
+
+ person[0].target=1;
+
+ person[0].speed=1;
+
+ person[person[0].killtarget].targetframe=0;
+
+ person[person[0].killtarget].targetanimation=thrownanim;
+
+ person[person[0].killtarget].target=1;
+
+ person[person[0].killtarget].playercoords=person[0].playercoords;
+
+ person[person[0].killtarget].playerrotation=person[0].playerrotation;
+
+ person[person[0].killtarget].speed=person[0].speed;
+
+ person[person[0].killtarget].speedmult=1;
+
+ }
+
+ }
+
+ }
+
+
+
+ //Gun whacking
+
+ if(Button()&&(person[0].aiming==0||person[0].ammo<=0||person[0].whichgun==nogun||person[0].whichgun==knife||person[0].targetanimation==joganim)&&person[0].currentanimation!=crouchanim&&person[0].targetanimation!=throwanim&&person[0].whichgun!=grenade&&person[0].targetanimation!=crouchanim&&visions==0){
+
+ if(person[0].attackframe==-1||person[person[0].killtarget].skeleton.free==1){
+
+ bool attacking=0;
+
+ person[0].killtarget=-1;
+
+ float closedistance=-1;
+
+ for(int i=1;i<numpeople;i++){
+
+ if(person[i].existing&&person[i].type!=viptype&&person[i].skeleton.free<1&&findDistancefast(person[i].playercoords,person[0].playercoords+flatfacing)<12+(person[0].whichgun==knife)*10){
+
+ if(person[0].killtarget==-1||findDistancefast(person[i].playercoords,person[0].playercoords)<closedistance){
+
+ attacking=1;
+
+ person[0].killtarget=i;
+
+ closedistance=findDistancefast(person[i].playercoords,person[0].playercoords);
+
+ }
+
+ }
+
+ }
+
+ if(attacking){
+
+ person[0].attacktarget=0;
+
+ person[0].attackframe=0;
+
+ }
+
+ whacked=0;
+
+ }
+
+ }
+
+
+
+ XYZ velocity;
+
+
+
+ if(person[0].attackframe>1||(person[0].attackframe>=0&&person[0].currentanimation==joganim)){
+
+ if(person[person[0].killtarget].skeleton.free<1&&person[0].killtarget!=0&&(person[0].aiming<1||person[0].whichgun==nogun||person[0].whichgun==knife||person[0].targetanimation==joganim)){
+
+ float gLoc[3];
+
+ gLoc[0]=(camera.position.x+((person[0].playercoords.x+flatfacing.x)-camera.position.x)/2)/soundscalefactor;
+
+ gLoc[1]=(camera.position.y+((person[0].playercoords.y+flatfacing.y)-camera.position.y)/2)/soundscalefactor;
+
+ gLoc[2]=(camera.position.z+((person[0].playercoords.z+flatfacing.z)-camera.position.z)/2)/soundscalefactor;
+
+ if(person[person[0].killtarget].type!=zombietype)
+
+ {
+
+ if(person[0].whichgun!=knife){
+
+ alSourcefv(gSourceID[headwhacksound], AL_POSITION, gLoc);
+
+ alSourcePlay(gSourceID[headwhacksound]);
+
+ }
+
+ if(person[0].whichgun==knife){
+
+ alSourcefv(gSourceID[knifeslashsound], AL_POSITION, gLoc);
+
+ alSourcePlay(gSourceID[knifeslashsound]);
+
+ person[person[0].killtarget].bjoint1=&person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[neck]];
+
+ person[person[0].killtarget].bjoint2=&person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[neck]];
+
+ person[person[0].killtarget].bleeding=1;
+
+ person[person[0].killtarget].bleeddelay=1;
+
+ person[0].bjoint1=&person[0].skeleton.joints[person[0].skeleton.jointlabels[righthand]];
+
+ person[0].bjoint2=&person[0].skeleton.joints[person[0].skeleton.jointlabels[righthand]];
+
+ person[0].bleeding=1;
+
+ person[0].bleeddelay=1;
+
+ velocity=DoRotation(flatfacing,0,70,0)*50+person[0].velocity*2;
+
+ velocity.y+=30;
+
+ sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,DoRotation(person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[neck]].position,0,person[person[0].killtarget].playerrotation,0)+person[person[0].killtarget].playercoords, velocity*.3, 2);
+
+ sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,DoRotation(person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[neck]].position,0,person[person[0].killtarget].playerrotation,0)+person[person[0].killtarget].playercoords, velocity*.2, 3);
+
+ sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,DoRotation(person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[neck]].position,0,person[person[0].killtarget].playerrotation,0)+person[person[0].killtarget].playercoords, velocity*.1, 4);
+
+ }
+
+ person[person[0].killtarget].health-=100;
+
+ person[person[0].killtarget].skeleton.free=1;
+
+ person[person[0].killtarget].longdead=1;
+
+ for(int j=0;j<person[person[0].killtarget].skeleton.num_joints;j++){
+
+ person[person[0].killtarget].skeleton.joints[j].position=DoRotation(person[person[0].killtarget].skeleton.joints[j].position,0,person[person[0].killtarget].playerrotation,0);
+
+ person[person[0].killtarget].skeleton.joints[j].position+=person[person[0].killtarget].playercoords;
+
+ person[person[0].killtarget].skeleton.joints[j].realoldposition=person[person[0].killtarget].skeleton.joints[j].position;
+
+ person[person[0].killtarget].skeleton.joints[j].velocity=person[person[0].killtarget].velocity;
+
+ person[person[0].killtarget].skeleton.joints[j].velocity.x+=abs(Random()%10)-5;
+
+ person[person[0].killtarget].skeleton.joints[j].velocity.y+=abs(Random()%10)-5;
+
+ person[person[0].killtarget].skeleton.joints[j].velocity.z+=abs(Random()%10)-5;
+
+ }
+
+ if(person[0].whichgun!=knife){
+
+ person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[head]].velocity+=DoRotation(flatfacing,0,40,0)*50;
+
+ person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[head]].velocity+=person[0].velocity*2;
+
+ }
+
+ }
+
+ else
+
+ {
+
+ if(whacked==0){
+
+ whacked=1;
+
+ if(person[0].whichgun!=knife){
+
+ alSourcefv(gSourceID[headwhacksound], AL_POSITION, gLoc);
+
+ alSourcePlay(gSourceID[headwhacksound]);
+
+ }
+
+ if(person[0].whichgun==knife){
+
+ alSourcefv(gSourceID[knifeslashsound], AL_POSITION, gLoc);
+
+ alSourcePlay(gSourceID[knifeslashsound]);
+
+ person[person[0].killtarget].bjoint1=&person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[neck]];
+
+ person[person[0].killtarget].bjoint2=&person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[neck]];
+
+ person[person[0].killtarget].bleeding=1;
+
+ person[person[0].killtarget].bleeddelay=1;
+
+ person[0].bjoint1=&person[0].skeleton.joints[person[0].skeleton.jointlabels[righthand]];
+
+ person[0].bjoint2=&person[0].skeleton.joints[person[0].skeleton.jointlabels[righthand]];
+
+ person[0].bleeding=1;
+
+ person[0].bleeddelay=1;
+
+ velocity=DoRotation(flatfacing,0,70,0)*50+person[0].velocity*2;
+
+ velocity.y+=30;
+
+ sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,DoRotation(person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[neck]].position,0,person[person[0].killtarget].playerrotation,0)+person[person[0].killtarget].playercoords, velocity*.3, 2);
+
+ sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,DoRotation(person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[neck]].position,0,person[person[0].killtarget].playerrotation,0)+person[person[0].killtarget].playercoords, velocity*.2, 3);
+
+ sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,DoRotation(person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[neck]].position,0,person[person[0].killtarget].playerrotation,0)+person[person[0].killtarget].playercoords, velocity*.1, 4);
+
+ }
+
+ person[person[0].killtarget].health-=200;
+
+ person[person[0].killtarget].maxhealth-=20;
+
+ person[person[0].killtarget].skeleton.free=1;
+
+ person[person[0].killtarget].longdead=1;
+
+ for(int j=0;j<person[person[0].killtarget].skeleton.num_joints;j++){
+
+ person[person[0].killtarget].skeleton.joints[j].position=DoRotation(person[person[0].killtarget].skeleton.joints[j].position,0,person[person[0].killtarget].playerrotation,0);
+
+ person[person[0].killtarget].skeleton.joints[j].position+=person[person[0].killtarget].playercoords;
+
+ person[person[0].killtarget].skeleton.joints[j].realoldposition=person[person[0].killtarget].skeleton.joints[j].position;
+
+ person[person[0].killtarget].skeleton.joints[j].velocity=person[person[0].killtarget].velocity;
+
+ person[person[0].killtarget].skeleton.joints[j].velocity.x+=abs(Random()%10)-5;
+
+ person[person[0].killtarget].skeleton.joints[j].velocity.y+=abs(Random()%10)-5;
+
+ person[person[0].killtarget].skeleton.joints[j].velocity.z+=abs(Random()%10)-5;
+
+ }
+
+ if(person[0].whichgun!=knife){
+
+ person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[head]].velocity+=DoRotation(flatfacing,0,40,0)*50;
+
+ person[person[0].killtarget].skeleton.joints[person[person[0].killtarget].skeleton.jointlabels[head]].velocity+=person[0].velocity*2;
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+
+
+ //Tackle
+
+ if(person[0].currentanimation==diveanim&&visions==0){
+
+ for(int i=1;i<numpeople;i++){
+
+ if(person[i].skeleton.free<1&&findDistancefast(person[i].playercoords,person[0].playercoords+flatfacing)<22){
+
+ float gLoc[3];
+
+ gLoc[0]=(camera.position.x+((person[0].playercoords.x+flatfacing.x)-camera.position.x)/2)/soundscalefactor;
+
+ gLoc[1]=(camera.position.y+((person[0].playercoords.y+flatfacing.y)-camera.position.y)/2)/soundscalefactor;
+
+ gLoc[2]=(camera.position.z+((person[0].playercoords.z+flatfacing.z)-camera.position.z)/2)/soundscalefactor;
+
+ alSourcefv(gSourceID[headwhacksound], AL_POSITION, gLoc);
+
+ alSourcePlay(gSourceID[headwhacksound]);
+
+ person[i].skeleton.free=1;
+
+ person[i].longdead=1;
+
+ for(int j=0;j<person[i].skeleton.num_joints;j++){
+
+ person[i].skeleton.joints[j].position=DoRotation(person[i].skeleton.joints[j].position,0,person[i].playerrotation,0);
+
+ person[i].skeleton.joints[j].position+=person[i].playercoords;
+
+ person[i].skeleton.joints[j].realoldposition=person[i].skeleton.joints[j].position;
+
+ person[i].skeleton.joints[j].velocity=person[0].velocity;
+
+ person[i].skeleton.joints[j].velocity.y=-10;
+
+ person[i].skeleton.joints[j].velocity.x+=abs(Random()%10)-5;
+
+ person[i].skeleton.joints[j].velocity.y+=abs(Random()%10)-5;
+
+ person[i].skeleton.joints[j].velocity.z+=abs(Random()%10)-5;
+
+ }
+
+ }
+
+ }
+
+ }
+
+
+
+ //Fire/wing
+
+ XYZ wallhit;
+
+ XYZ start;
+
+ XYZ finalwallhit;
+
+ bool firing;
+
+ float inaccuracy;
+
+ int numshots;
+
+ XYZ hitnorm;
+
+ XYZ hitmove;
+
+ int hitpoly=0;
+
+ float hitrotation;
+
+ Model *model;
+
+ for(int j=0;j<numpeople;j++){
+
+ if(person[j].type==playertype||person[j].type==eviltype){
+
+ firing=0;
+
+ if(person[j].ammo>0&&person[j].reloading<=0&&person[j].targetanimation!=joganim){
+
+ if(Button()&&!oldbutton&&j==0)firing=1;
+
+ if(j!=0)firing=0;
+
+ if(j!=0&&person[j].whichgun!=nogun&&person[j].whichgun!=knife&&person[j].killtargetvisible&&person[j].shotdelay<0)firing=1;
+
+ if(j!=0&&person[j].whichgun!=nogun&&person[j].whichgun!=knife&&person[j].killtargetvisible&&person[j].shotdelay>0)person[j].shotdelay-=multiplier*.9;
+
+ if(person[j].skeleton.free==1||person[j].targetanimation==getupfrontanim||person[j].targetanimation==getupbackanim)person[j].shotdelay=shotdelayamount/difficulty;
+
+ if(j!=0&&person[j].whichgun!=nogun&&person[j].whichgun!=knife&&person[j].killtargetvisible)person[j].aiming=1;
+
+ if(person[0].whichgun!=assaultrifle)oldbutton=1;
+
+ }
+
+ if(person[j].ammo==0&&person[j].reloads[person[j].whichgun]>0){
+
+ person[j].ammo=-1;
+
+ person[j].aiming=0;
+
+ firing=0;
+
+ }
+
+ if(person[0].ammo<=0&&Button()&&!oldbutton&&person[0].targetanimation!=joganim&&person[0].whichgun!=nogun&&person[0].whichgun!=knife&&person[0].whichgun!=grenade&&person[0].aiming){
+
+ oldbutton=1;
+
+ float gLoc[3];
+
+ gLoc[0]=person[0].playercoords.x/soundscalefactor;
+
+ gLoc[1]=person[0].playercoords.y/soundscalefactor;
+
+ gLoc[2]=person[0].playercoords.z/soundscalefactor;
+
+
+
+ alSourcefv(gSourceID[clicksound], AL_POSITION, gLoc);
+
+ alSourcePlay(gSourceID[clicksound]);
+
+ }
+
+ if(j==0&&visions==1&&firing){
+
+ firing=0;
+
+ alSourcePlay(gSourceID[soulinsound]);
+
+ }
+
+ if(person[j].aimamount<1)firing=0;
+
+ if(firing){
+
+ if(person[j].whichgun==handgun1||person[j].whichgun==handgun2)inaccuracy=8;
+
+ if(person[j].whichgun==assaultrifle)inaccuracy=6;
+
+ if(person[j].whichgun==sniperrifle)inaccuracy=2;
+
+ if(person[j].whichgun==shotgun)inaccuracy=6;
+
+ if(person[person[j].killtarget].skeleton.free==1)inaccuracy*=3;
+
+
+
+ person[j].shotdelay=shotdelayamount/difficulty;
+
+ if(person[j].aiming>=1&&person[j].recoil<=0){
+
+ //Firing
+
+ person[j].litup=1;
+
+ person[j].recoil=1;
+
+ XYZ end, aim, oldend;
+
+ HitStruct hitstruct,temphitstruct;
+
+ float olddistance;
+
+ float distance;
+
+ float totalarea;
+
+ int whichhit=-1;
+
+ if(person[j].whichgun==shotgun)numshots=7;
+
+ if(person[j].whichgun!=shotgun)numshots=1;
+
+ if(person[j].whichgun!=grenade)person[j].ammo--;
+
+ for(int p=0;p<numshots;p++){
+
+ if(!zoom||j!=0){
+
+ if(person[j].whichgun==assaultrifle)aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position-person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position,0,person[j].playerrotation-2.5,0);
+
+ if(person[j].whichgun==sniperrifle)aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position-person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position,0,person[j].playerrotation+4,0);
+
+ if(person[j].whichgun==shotgun)aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position-person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position,2+(float)(Random()%1000)/500,0,0);
+
+ if(person[j].whichgun==shotgun)aim=DoRotation(aim,0,person[j].playerrotation-1+(float)(Random()%1000)/500,0);
+
+ if(person[j].whichgun==handgun1&&!thirdperson&&j==0)aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position-(person[j].skeleton.joints[person[j].skeleton.jointlabels[head]].position*.65+person[j].skeleton.joints[person[j].skeleton.jointlabels[neck]].position*.35),0,person[j].playerrotation-.9,0);
+
+ if(person[j].whichgun==handgun1&&(thirdperson||j!=0))aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position-(person[j].skeleton.joints[person[j].skeleton.jointlabels[head]].position*.35+person[j].skeleton.joints[person[j].skeleton.jointlabels[neck]].position*.65),0,person[j].playerrotation-.9,0);
+
+ if(person[j].whichgun==handgun2&&!thirdperson&&j==0)aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position-(person[j].skeleton.joints[person[j].skeleton.jointlabels[head]].position*.65+person[j].skeleton.joints[person[j].skeleton.jointlabels[neck]].position*.35),0,person[j].playerrotation-.9,0);
+
+ if(person[j].whichgun==handgun2&&(thirdperson||j!=0))aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position-(person[j].skeleton.joints[person[j].skeleton.jointlabels[head]].position*.35+person[j].skeleton.joints[person[j].skeleton.jointlabels[neck]].position*.65),0,person[j].playerrotation-.9,0);
+
+ if(j!=0&&person[person[j].killtarget].skeleton.free==0)aim=(DoRotation(person[person[j].killtarget].skeleton.joints[person[person[j].killtarget].skeleton.jointlabels[abdomen]].position,0,person[person[j].killtarget].playerrotation,0)+person[person[j].killtarget].playercoords)-(DoRotation(person[j].skeleton.joints[person[j].skeleton.jointlabels[lefthand]].position,0,person[j].playerrotation,0)+person[j].playercoords);
+
+ if(j!=0&&person[person[j].killtarget].skeleton.free!=0)aim=person[person[j].killtarget].skeleton.joints[person[person[j].killtarget].skeleton.jointlabels[abdomen]].position-(DoRotation(person[j].skeleton.joints[person[j].skeleton.jointlabels[lefthand]].position,0,person[j].playerrotation,0)+person[j].playercoords);
+
+ if(j!=0)aim=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),(float)(abs(Random()%2000))/2000*inaccuracy-inaccuracy/2,(float)(abs(Random()%2000))/2000*inaccuracy-inaccuracy/2,0),0,person[j].playerrotation,0);
+
+ }
+
+ if(zoom&&j==0){
+
+ start=camera.position;
+
+ aim=facing;
+
+ }
+
+ Normalise(&aim);
+
+ if(person[j].whichgun==sniperrifle){
+
+ start=person[j].playercoords+DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position,0,person[j].playerrotation,0);
+
+ float gLoc[3];
+
+
+
+ start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*.35;
+
+
+
+ gLoc[0]=(camera.position.x+(start.x-camera.position.x)/4)/soundscalefactor;
+
+ gLoc[1]=(camera.position.y+(start.y-camera.position.y)/4)/soundscalefactor;
+
+ gLoc[2]=(camera.position.z+(start.z-camera.position.z)/4)/soundscalefactor;
+
+ alSourcefv(gSourceID[riflesound], AL_POSITION, gLoc);
+
+ alSourcePlay(gSourceID[riflesound]);
+
+ if(j==0){
+
+ if(person[j].currentanimation!=crouchanim)camera.rotation2-=7;
+
+ if(person[j].currentanimation==crouchanim)camera.rotation2-=3;
+
+ }
+
+ }
+
+ if(person[j].whichgun==shotgun){
+
+ start=person[j].playercoords+DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position,0,person[j].playerrotation,0);
+
+ float gLoc[3];
+
+
+
+ start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*.35;
+
+
+
+ if(p==numshots-1){
+
+ gLoc[0]=(camera.position.x+(start.x-camera.position.x)/4)/soundscalefactor;
+
+ gLoc[1]=(camera.position.y+(start.y-camera.position.y)/4)/soundscalefactor;
+
+ gLoc[2]=(camera.position.z+(start.z-camera.position.z)/4)/soundscalefactor;
+
+ alSourcefv(gSourceID[shotgunsound], AL_POSITION, gLoc);
+
+ alSourcePlay(gSourceID[shotgunsound]);
+
+ if(j==0){
+
+ if(person[j].currentanimation!=crouchanim)camera.rotation2-=7;
+
+ if(person[j].currentanimation==crouchanim)camera.rotation2-=3;
+
+ }
+
+ }
+
+ }
+
+ if(person[j].whichgun==handgun1){
+
+ start=person[j].playercoords+DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[rightwrist])].position,0,person[j].playerrotation,0);
+
+ start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*.55;
+
+
+
+ float gLoc[3];
+
+
+
+ gLoc[0]=(camera.position.x+(start.x-camera.position.x)/4)/soundscalefactor;
+
+ gLoc[1]=(camera.position.y+(start.y-camera.position.y)/4)/soundscalefactor;
+
+ gLoc[2]=(camera.position.z+(start.z-camera.position.z)/4)/soundscalefactor;
+
+ alSourcefv(gSourceID[pistol1sound], AL_POSITION, gLoc);
+
+ alSourcePlay(gSourceID[pistol1sound]);
+
+ if(j==0){
+
+ if(person[j].currentanimation!=crouchanim)camera.rotation2-=6;
+
+ if(person[j].currentanimation==crouchanim)camera.rotation2-=4;
+
+ }
+
+ }
+
+ if(person[j].whichgun==handgun2){
+
+ start=person[j].playercoords+DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[rightwrist])].position,0,person[j].playerrotation,0);
+
+ start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*.55;
+
+
+
+ float gLoc[3];
+
+
+
+ gLoc[0]=(camera.position.x+(start.x-camera.position.x)/4)/soundscalefactor;
+
+ gLoc[1]=(camera.position.y+(start.y-camera.position.y)/4)/soundscalefactor;
+
+ gLoc[2]=(camera.position.z+(start.z-camera.position.z)/4)/soundscalefactor;
+
+ alSourcefv(gSourceID[pistol2sound], AL_POSITION, gLoc);
+
+ alSourcePlay(gSourceID[pistol2sound]);
+
+ if(j==0){
+
+ if(person[j].currentanimation!=crouchanim)camera.rotation2-=5;
+
+ if(person[j].currentanimation==crouchanim)camera.rotation2-=3;
+
+ }
+
+ }
+
+ if(person[j].whichgun==assaultrifle){
+
+ start=person[j].playercoords+DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position,0,person[j].playerrotation,0);
+
+ start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*.25;
+
+
+
+ float gLoc[3];
+
+ gLoc[0]=(camera.position.x+(start.x-camera.position.x)/4)/soundscalefactor;
+
+ gLoc[1]=(camera.position.y+(start.y-camera.position.y)/4)/soundscalefactor;
+
+ gLoc[2]=(camera.position.z+(start.z-camera.position.z)/4)/soundscalefactor;
+
+ alSourcefv(gSourceID[machinegunsound], AL_POSITION, gLoc);
+
+ alSourcePlay(gSourceID[machinegunsound]);
+
+ if(j==0){
+
+ if(person[j].currentanimation!=crouchanim){
+
+ camera.rotation2-=2.3;
+
+ camera.rotation+=(float)(Random()%100)/50;
+
+ }
+
+ if(person[j].currentanimation==crouchanim){
+
+ camera.rotation2-=1.5;
+
+ camera.rotation+=(float)(Random()%100)/60;
+
+ }
+
+ }
+
+ }
+
+ end=start+aim*1000;
+
+ if(debug){
+
+ if(IsKeyDown(theKeyMap, MAC_G_KEY)&&j==0){
+
+ sprites.MakeSprite(grenadesprite, 1, 1, 1, 1, start, aim*200, 1.01);
+
+ }
+
+ }
+
+ if(!IsKeyDown(theKeyMap, MAC_G_KEY)||j!=0||!debug){
+
+ int bulletstrength=1;
+
+ int firstpass=-1;
+
+ bool penetrate;
+
+ for(int m=0;m<bulletstrength;m++){
+
+ //People
+
+ whichhit=-1;
+
+ for(int i=0;i<numpeople;i++){
+
+ if(i!=j&&i!=firstpass&&person[i].existing){
+
+ temphitstruct=person[i].BulletCollideWithPlayer(i, start, end);
+
+ if(temphitstruct.collision){
+
+ distance=findDistancefast(start,temphitstruct.hitlocation);
+
+ if(distance<olddistance||whichhit==-1){
+
+ end=temphitstruct.hitlocation;
+
+ olddistance=distance;
+
+ hitstruct=temphitstruct;
+
+ whichhit=i;
+
+ }
+
+ }
+
+ }
+
+ }
+
+ //Blocks
+
+ wallhit=0;
+
+ beginx=(person[j].playercoords.x+block_spacing/2)/block_spacing-3;
+
+ if(beginx<0)beginx=0;
+
+ beginz=(person[j].playercoords.z+block_spacing/2)/block_spacing-3;
+
+ if(beginz<0)beginz=0;
+
+
+
+ endx=(person[j].playercoords.x+block_spacing/2)/block_spacing+3;
+
+ if(endx>num_blocks-1)endx=num_blocks-1;
+
+ endz=(person[j].playercoords.z+block_spacing/2)/block_spacing+3;
+
+ if(endz>num_blocks-1)endz=num_blocks-1;
+
+
+
+ if(beginx<endx&&beginz<endz)
+
+ finalwallhit=0;
+
+ for(int i=beginx;i<=endx;i++)
+
+ for(int j=beginz;j<=endz;j++){
+
+ move=0;
+
+ move.x=i*block_spacing;
+
+ move.z=j*block_spacing;
+
+ whichtri=blocks[citytype[i][j]].LineCheck2(start,end,&wallhit,move,cityrotation[i][j]*90);
+
+ if(whichtri!=-1){
+
+ whichhit=-1;
+
+ end=wallhit;
+
+ finalwallhit=wallhit;
+
+ hitnorm=DoRotation(blocks[citytype[i][j]].normals[whichtri],0,cityrotation[i][j]*90,0);
+
+ hitmove=move;
+
+ hitrotation=cityrotation[i][j]*90;
+
+ hitpoly=whichtri;
+
+ model=&blocks[citytype[i][j]];
+
+ if(j==0&&blocks[citytype[i][j]].normals[whichtri].y>.9)bulletstrength=2;
+
+ }
+
+ }
+
+ wallhit=0;
+
+ wallhit.x=camera.position.x;
+
+ wallhit.z=camera.position.z;
+
+ whichtri=Bigstreet.LineCheck2(start,end,&wallhit,wallhit,0);
+
+ if(whichtri!=-1){
+
+ end.y-=.5;
+
+ end=wallhit;
+
+ finalwallhit=wallhit;
+
+ bulletstrength=2;
+
+ hitnorm=0;
+
+ hitnorm.y=1;
+
+ hitmove=0;
+
+ hitrotation=0;
+
+ }
+
+ if(m==0){
+
+ if(j==0&&slomo==2){
+
+ soundscalefactor=soundscalefactordefault;
+
+ alSourceStop(gSourceID[whichsong]);
+
+ alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 0);
+
+ alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 0);
+
+ if(person[0].whichgun==knife)whichsong=knifesong;
+
+ if(person[0].whichgun!=knife)whichsong=shootsong;
+
+ if(type==zombie_type)whichsong=zombiesong;
+
+ alSourcef(gSourceID[whichsong], AL_PITCH, 1);
+
+ alSourcePlay(gSourceID[whichsong]);
+
+ alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1);
+
+ alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1);
+
+ slomo=0;
+
+ if(whichhit==-1)alSourcePlay(gSourceID[disguisekillsound]);
+
+ flashamount=.5;
+
+ flashr=1;flashg=1;flashb=1;
+
+ }
+
+ }
+
+ //Impact
+
+ oldend=end;
+
+ //with person
+
+ if(whichhit!=-1&&whichhit!=firstpass){
+
+ if(j==0)person[whichhit].dead=1;
+
+ if(whichhit==1){
+
+ murderer=j;
+
+ }
+
+ if(person[whichhit].health==100&&j==0){
+
+ if(person[whichhit].type==civiliantype)civkills++;
+
+ if(person[whichhit].type==eviltype)goodkills++;
+
+ }
+
+ if(person[whichhit].health==100&&j!=0){
+
+ badkills++;
+
+ }
+
+ //penetrate
+
+ penetrate=abs(Random()%2)==1;
+
+ if(numshots>1)penetrate=0;
+
+ if(penetrate){bulletstrength=2;
+
+ firstpass=whichhit;
+
+ end=start+aim*1000;}
+
+ if(person[j].whichgun==assaultrifle)person[whichhit].health-=20;
+
+ if(person[j].whichgun==assaultrifle&&person[whichhit].type==zombietype)person[whichhit].health-=60;
+
+ if(person[j].whichgun==handgun1){
+
+ if(person[whichhit].type!=zombietype)person[whichhit].health-=100;
+
+ if(person[whichhit].type==zombietype)person[whichhit].health-=100;
+
+ person[whichhit].DoAnimations(whichhit);
+
+ }
+
+ if(person[j].whichgun==handgun2)person[whichhit].health-=20;
+
+ if(person[j].whichgun==handgun2&&person[whichhit].type==zombietype)person[whichhit].health-=60;
+
+ if(person[j].whichgun==sniperrifle&&m!=0)person[whichhit].health-=30;
+
+ if(person[j].whichgun==shotgun)person[whichhit].health-=60;
+
+ if(person[j].whichgun==sniperrifle&&m==0){
+
+ if(person[whichhit].type!=zombietype)person[whichhit].health-=100;
+
+ if(person[whichhit].type==zombietype)person[whichhit].health-=120;
+
+ person[whichhit].DoAnimations(whichhit);
+
+ }
+
+ if(hitstruct.joint1->modelnum==headmodel&&person[whichhit].type!=zombietype){
+
+ person[whichhit].health-=60;
+
+ }
+
+ if(person[whichhit].type==zombietype)person[whichhit].speedmult-=.05;
+
+ if(person[whichhit].type==zombietype)person[whichhit].maxhealth-=10;
+
+ if(whichhit==0){
+
+ bulletstrength=1;
+
+ person[0].health=100;
+
+ flashr=0;
+
+ flashg=0;
+
+ flashb=0;
+
+ flashamount=1;
+
+ float gLoc[3];
+
+ gLoc[0]=hitstruct.hitlocation.x/soundscalefactor;
+
+ gLoc[1]=hitstruct.hitlocation.y/soundscalefactor;
+
+ gLoc[2]=hitstruct.hitlocation.z/soundscalefactor;
+
+ alSourcefv(gSourceID[bodywhacksound], AL_POSITION, gLoc);
+
+ alSourcePlay(gSourceID[bodywhacksound]);
+
+ }
+
+ person[whichhit].longdead=1;
+
+
+
+ if(person[whichhit].health<=0){
+
+ person[whichhit].skeleton.offset=0;
+
+ if(person[whichhit].skeleton.free!=1){
+
+ person[whichhit].skeleton.free=1;
+
+ totalarea=0;
+
+ for(int j=0;j<person[whichhit].skeleton.num_joints;j++){
+
+ person[whichhit].skeleton.joints[j].position=DoRotation(person[whichhit].skeleton.joints[j].position,0,person[whichhit].playerrotation,0);
+
+ person[whichhit].skeleton.joints[j].position+=person[whichhit].playercoords;
+
+ person[whichhit].skeleton.joints[j].realoldposition=person[whichhit].skeleton.joints[j].position;
+
+ person[whichhit].skeleton.joints[j].velocity=person[whichhit].velocity;
+
+ person[whichhit].skeleton.joints[j].velocity.x+=(float)(abs(Random()%20)-10)/2;
+
+ person[whichhit].skeleton.joints[j].velocity.y+=(float)(abs(Random()%20)-10)/2;
+
+ person[whichhit].skeleton.joints[j].velocity.z+=(float)(abs(Random()%20)-10)/2;
+
+ }
+
+ }
+
+ for(int j=0;j<person[whichhit].skeleton.num_joints;j++){
+
+ if(findDistancefast(person[whichhit].skeleton.joints[j].position,hitstruct.hitlocation)<200){
+
+ totalarea+=(200/findDistancefast(person[whichhit].skeleton.joints[j].position,hitstruct.hitlocation));
+
+ }
+
+ }
+
+ for(int j=0;j<person[whichhit].skeleton.num_joints;j++){
+
+ if(findDistancefast(person[whichhit].skeleton.joints[j].position,hitstruct.hitlocation)<200){
+
+ person[whichhit].skeleton.joints[j].velocity+=aim*((200/findDistancefast(person[whichhit].skeleton.joints[j].position,hitstruct.hitlocation))/totalarea*200);
+
+ }
+
+ }
+
+ }
+
+ if(person[whichhit].health>0){
+
+ if(person[whichhit].killtargetvisible==0&&person[whichhit].type!=zombietype&&person[whichhit].currentanimation!=getupfrontanim&person[whichhit].currentanimation!=getupbackanim){
+
+ if(hitstruct.joint1->modelnum==headmodel)person[whichhit].targetanimation=headpainanim;
+
+ if(hitstruct.joint1->modelnum==chestmodel)person[whichhit].targetanimation=chestpainanim;
+
+ if(hitstruct.joint1->modelnum==abdomenmodel)person[whichhit].targetanimation=stomachpainanim;
+
+ if(hitstruct.joint1->label==rightelbow||hitstruct.joint1->label==rightshoulder||hitstruct.joint1->label==rightwrist||hitstruct.joint1->label==righthand)person[whichhit].targetanimation=rightarmpainanim;
+
+ if(hitstruct.joint1->label==leftelbow||hitstruct.joint1->label==leftshoulder||hitstruct.joint1->label==leftwrist||hitstruct.joint1->label==lefthand)person[whichhit].targetanimation=leftarmpainanim;
+
+ if(hitstruct.joint1->label==rightknee||hitstruct.joint1->label==righthip||hitstruct.joint1->label==rightankle||hitstruct.joint1->label==rightfoot)person[whichhit].targetanimation=rightlegpainanim;
+
+ if(hitstruct.joint1->label==leftknee||hitstruct.joint1->label==lefthip||hitstruct.joint1->label==leftankle||hitstruct.joint1->label==leftfoot)person[whichhit].targetanimation=leftlegpainanim;
+
+ person[whichhit].targetframe=0;
+
+ person[whichhit].target=0;
+
+ }
+
+ person[whichhit].skeleton.offset=1;
+
+ for(int j=0;j<person[whichhit].skeleton.num_joints;j++){
+
+ if(findDistancefast(DoRotation(person[whichhit].skeleton.joints[j].position,0,person[whichhit].playerrotation,0)+person[whichhit].playercoords,hitstruct.hitlocation)<200){
+
+ totalarea+=(200/findDistancefast(DoRotation(person[whichhit].skeleton.joints[j].position,0,person[whichhit].playerrotation,0)+person[whichhit].playercoords,hitstruct.hitlocation));
+
+ }
+
+ }
+
+ float offsetlength;
+
+ for(int j=0;j<person[whichhit].skeleton.num_joints;j++){
+
+ if(findDistancefast(DoRotation(person[whichhit].skeleton.joints[j].position,0,person[whichhit].playerrotation,0)+person[whichhit].playercoords,hitstruct.hitlocation)<200){
+
+ person[whichhit].skeleton.joints[j].offset+=DoRotation(aim*((200/findDistancefast(DoRotation(person[whichhit].skeleton.joints[j].position,0,person[whichhit].playerrotation,0)+person[whichhit].playercoords,hitstruct.hitlocation))/totalarea*10),0,-person[whichhit].playerrotation,0);
+
+ }
+
+ offsetlength=findLengthfast(person[whichhit].skeleton.joints[j].offset);
+
+ if(offsetlength>36){
+
+ Normalise(&person[whichhit].skeleton.joints[j].offset);
+
+ person[whichhit].skeleton.joints[j].offset*=6;
+
+ }
+
+ }
+
+ }
+
+ if(hitstruct.joint1->modelnum==headmodel&&person[whichhit].health<=0){
+
+ for(int j=0;j<person[whichhit].skeleton.num_joints;j++){
+
+ if(&person[whichhit].skeleton.joints[j]==hitstruct.joint1||&person[whichhit].skeleton.joints[j]==hitstruct.joint2){
+
+ if(j!=person[whichhit].skeleton.jointlabels[abdomen]&&j!=person[whichhit].skeleton.jointlabels[groin]&&j!=person[whichhit].skeleton.jointlabels[neck]){
+
+ sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,person[whichhit].skeleton.joints[j].position, person[whichhit].skeleton.joints[j].velocity/3, 9);
+
+ sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,person[whichhit].skeleton.joints[j].position, DoRotation(person[whichhit].skeleton.joints[j].velocity/3,Random()%360,Random()%360,0)/5, 5);
+
+ sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,person[whichhit].skeleton.joints[j].position, DoRotation(person[whichhit].skeleton.joints[j].velocity/3,Random()%360,Random()%360,0)/5, 5);
+
+ sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,person[whichhit].skeleton.joints[j].position, DoRotation(person[whichhit].skeleton.joints[j].velocity/3,Random()%360,Random()%360,0)/5, 5);
+
+ sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,person[whichhit].skeleton.joints[j].position, DoRotation(person[whichhit].skeleton.joints[j].velocity/3,Random()%360,Random()%360,0)/5, 5);
+
+ person[whichhit].skeleton.DeleteJoint(j);
+
+ person[whichhit].skeleton.broken=1;
+
+ person[whichhit].health=-10000;
+
+ person[whichhit].skeleton.joints[j].existing=0;
+
+ if(person[whichhit].type==zombietype)score+=300;
+
+ }
+
+ }
+
+ }
+
+ }
+
+
+
+ XYZ velocity;
+
+ velocity=aim*-8;
+
+ //blood
+
+ if(!hitstruct.joint1->modelnum==headmodel){
+
+ if(person[j].whichgun==sniperrifle)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*0, 5);
+
+ if(person[j].whichgun==sniperrifle&&penetrate)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*-3, 7);
+
+ if(person[j].whichgun==shotgun)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*0, 5);
+
+ if(person[j].whichgun==shotgun&&penetrate)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*-3, 7);
+
+ if(person[j].whichgun==assaultrifle)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*0, 3);
+
+ if(person[j].whichgun==assaultrifle&&penetrate)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*-3, 7);
+
+ if(person[j].whichgun==handgun1)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*0, 3);
+
+ if(person[j].whichgun==handgun1&&penetrate)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*-3, 4);
+
+ if(person[j].whichgun==handgun2)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*0, 3);
+
+ if(person[j].whichgun==handgun2&&penetrate)sprites.MakeSprite(bloodspritenoup, 1, 1, 0, 0, hitstruct.hitlocation, velocity*-3, 4);
+
+ }else{
+
+ sprites.MakeSprite(bloodspritenoup, 1, 1, .2, .2, hitstruct.hitlocation, velocity*0, 6);
+
+ sprites.MakeSprite(bloodspritenoup, 1, 1, .5, .5, hitstruct.hitlocation, velocity*-2, 7);
+
+ sprites.MakeSprite(bloodspritenoup, 1, 1, .2, .2, hitstruct.hitlocation, velocity*-3, 10);
+
+ }
+
+
+
+ person[whichhit].bjoint1=hitstruct.joint1;
+
+ person[whichhit].bjoint2=hitstruct.joint2;
+
+ person[whichhit].bleeding=1;
+
+ person[whichhit].bleeddelay=1;
+
+ float gLoc[3];
+
+ gLoc[0]=(camera.position.x+(hitstruct.hitlocation.x-camera.position.x)/4)/soundscalefactor;
+
+ gLoc[1]=(camera.position.y+(hitstruct.hitlocation.y-camera.position.y)/4)/soundscalefactor;
+
+ gLoc[2]=(camera.position.z+(hitstruct.hitlocation.z-camera.position.z)/4)/soundscalefactor;
+
+ if(!hitstruct.joint1->modelnum==headmodel){
+
+ if(!thirdperson)alSourcef(gSourceID[bodyhitsound], AL_MIN_GAIN, 1);
+
+ if(thirdperson)alSourcef(gSourceID[bodyhitsound], AL_MIN_GAIN, .1);
+
+ alSourcefv(gSourceID[bodyhitsound], AL_POSITION, gLoc);
+
+ alSourcePlay(gSourceID[bodyhitsound]);
+
+ }
+
+ if(hitstruct.joint1->modelnum==headmodel){
+
+ if(!thirdperson)alSourcef(gSourceID[headshotsound], AL_MIN_GAIN, 1);
+
+ if(thirdperson)alSourcef(gSourceID[headshotsound], AL_MIN_GAIN, .1);
+
+ alSourcefv(gSourceID[headshotsound], AL_POSITION, gLoc);
+
+ alSourcePlay(gSourceID[headshotsound]);
+
+ }
+
+ }//with wall
+
+ if(oldend==finalwallhit){
+
+ decals.MakeDecal(bullethole, finalwallhit,.7,hitnorm, hitpoly, model, hitmove, hitrotation);
+
+ XYZ velocity;
+
+ velocity=aim*-4;
+
+ velocity=hitnorm*3;
+
+ if(person[j].whichgun==sniperrifle){
+
+ sprites.MakeSprite(smokesprite, .4, 1, 1, 1, finalwallhit, velocity, 10);
+
+ sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, finalwallhit, velocity, 2);
+
+ }
+
+ if(person[j].whichgun==shotgun){
+
+ sprites.MakeSprite(smokesprite, .4, 1, 1, 1, finalwallhit, velocity, 5);
+
+ sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, finalwallhit, velocity, .8);
+
+ }
+
+ if(person[j].whichgun==assaultrifle){
+
+ sprites.MakeSprite(smokesprite, .4, 1, 1, 1, finalwallhit, velocity, 6);
+
+ sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, finalwallhit, velocity, 1);
+
+ }
+
+ if(person[j].whichgun==handgun1){
+
+ sprites.MakeSprite(smokesprite, .4, 1, 1, 1, finalwallhit, velocity, 6);
+
+ sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, finalwallhit, velocity, 1);
+
+ }
+
+ if(person[j].whichgun==handgun2){
+
+ sprites.MakeSprite(smokesprite, .4, 1, 1, 1, finalwallhit, velocity, 6);
+
+ sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, finalwallhit, velocity, 1);
+
+ }
+
+ float gLoc[3];
+
+ gLoc[0]=finalwallhit.x/soundscalefactor;
+
+ gLoc[1]=finalwallhit.y/soundscalefactor;
+
+ gLoc[2]=finalwallhit.z/soundscalefactor;
+
+ alSourcefv(gSourceID[wallhitsound], AL_POSITION, gLoc);
+
+ alSourcePlay(gSourceID[wallhitsound]);
+
+ }
+
+ lastshot[0]=start;
+
+ lastshot[1]=oldend;
+
+ velocity=aim*8;
+
+ if(person[j].whichgun!=sniperrifle&&person[j].whichgun!=shotgun&&p==numshots-1)sprites.MakeSprite(smokesprite, .3, 1, 1, 1, start+aim*1.5, velocity, 3);
+
+ if(person[j].whichgun==shotgun&&p==numshots-1)sprites.MakeSprite(smokesprite, .4, 1, 1, 1, start+aim*1.5, velocity, 5);
+
+ if(person[j].whichgun==sniperrifle&&!zoom)sprites.MakeSprite(smokesprite, .3, 1, 1, 1, start+aim*2.2, velocity, 4);
+
+ if(j!=0||zoom==0)sprites.MakeSprite(bullet, .07, 1, 1, .7, lastshot[0]+aim*1, lastshot[1], .2);
+
+ //Nearby bullet whoosh
+
+ long dot_ta,dot_tb;
+
+ XYZ *a,*b,*c,nearest;
+
+ a=&lastshot[0];
+
+ *a+=aim*1;
+
+ b=&lastshot[1];
+
+ c=&camera.position;
+
+ nearest=0;
+
+ dot_ta = (c->x - a->x)*(b->x - a->x) + (c->y - a->y)*(b->y - a->y) + (c->z - a->z)*(b->z - a->z);
+
+ dot_tb = (c->x - b->x)*(a->x - b->x) + (c->y - b->y)*(a->y - b->y) + (c->z - b->z)*(a->z - b->z);
+
+ if (!dot_ta <= 0&&!dot_tb <= 0){
+
+
+
+ nearest.x = a->x + ((b->x - a->x) * dot_ta)/(dot_ta + dot_tb);
+
+ nearest.y = a->y + ((b->y - a->y) * dot_ta)/(dot_ta +dot_tb);
+
+ nearest.z = a->z + ((b->z - a->z) * dot_ta)/(dot_ta +dot_tb);
+
+ }
+
+
+
+ if(nearest.x){
+
+ if(findDistancefast(nearest,camera.position)<10&&(thirdperson==2||j!=0)){
+
+ float gLoc[3];
+
+
+
+ gLoc[0]=(camera.position.x+(nearest.x-camera.position.x))/soundscalefactor;
+
+ gLoc[1]=(camera.position.y+(nearest.y-camera.position.y))/soundscalefactor;
+
+ gLoc[2]=(camera.position.z+(nearest.z-camera.position.z))/soundscalefactor;
+
+ alSourcefv(gSourceID[nearbulletsound], AL_POSITION, gLoc);
+
+ alSourcePlay(gSourceID[nearbulletsound]);
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+
+
+ if(!Button())oldbutton=0;
+
+
+
+ if(lasersight&&person[0].whichgun!=grenade){
+
+ for(int j=0;j<numpeople;j++){
+
+ if(person[j].type==playertype){
+
+ if(person[j].aiming>=1){
+
+ //Firing
+
+ XYZ end, aim, oldend;
+
+ HitStruct hitstruct,temphitstruct;
+
+ float olddistance;
+
+ float distance;
+
+ int whichhit=-1;
+
+ if(!zoom||j!=0){
+
+ if(person[j].whichgun==assaultrifle)aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position-person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position,0,person[j].playerrotation-2.5,0);
+
+ if(person[j].whichgun==sniperrifle)aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position-person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position,0,person[j].playerrotation+4,0);
+
+ if(person[j].whichgun==shotgun)aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position-person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position,0,person[j].playerrotation+4,0);
+
+ if(person[j].whichgun==handgun1&&!thirdperson&&j==0)aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position-(person[j].skeleton.joints[person[j].skeleton.jointlabels[head]].position*.65+person[j].skeleton.joints[person[j].skeleton.jointlabels[neck]].position*.35),0,person[j].playerrotation-.9,0);
+
+ if(person[j].whichgun==handgun1&&(thirdperson||j!=0))aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position-(person[j].skeleton.joints[person[j].skeleton.jointlabels[head]].position*.35+person[j].skeleton.joints[person[j].skeleton.jointlabels[neck]].position*.65),0,person[j].playerrotation-.9,0);
+
+ if(person[j].whichgun==handgun2&&!thirdperson&&j==0)aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position-(person[j].skeleton.joints[person[j].skeleton.jointlabels[head]].position*.65+person[j].skeleton.joints[person[j].skeleton.jointlabels[neck]].position*.35),0,person[j].playerrotation-.9,0);
+
+ if(person[j].whichgun==handgun2&&(thirdperson||j!=0))aim=DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[righthand])].position-(person[j].skeleton.joints[person[j].skeleton.jointlabels[head]].position*.35+person[j].skeleton.joints[person[j].skeleton.jointlabels[neck]].position*.65),0,person[j].playerrotation-.9,0);
+
+ }
+
+ if(zoom&&j==0){
+
+ start=camera.position;
+
+ aim=facing;
+
+ }
+
+ Normalise(&aim);
+
+ if(person[j].whichgun==sniperrifle){
+
+ start=person[j].playercoords+DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position,0,person[j].playerrotation,0);
+
+ start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*(0-.4);
+
+ }
+
+ if(person[j].whichgun==shotgun){
+
+ start=person[j].playercoords+DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position,0,person[j].playerrotation,0);
+
+ start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*(0-.4);
+
+ }
+
+ if(person[j].whichgun==handgun1){
+
+ start=person[j].playercoords+DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[rightwrist])].position,0,person[j].playerrotation,0);
+
+ start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*(.55-.4);
+
+ }
+
+ if(person[j].whichgun==handgun2){
+
+ start=person[j].playercoords+DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[rightwrist])].position,0,person[j].playerrotation,0);
+
+ start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*(.55-.4);
+
+ }
+
+ if(person[j].whichgun==assaultrifle){
+
+ start=person[j].playercoords+DoRotation(person[j].skeleton.joints[(person[j].skeleton.jointlabels[lefthand])].position,0,person[j].playerrotation,0);
+
+ start-=DoRotation(DoRotation(DoRotation(aim,0,-person[j].playerrotation,0),90,0,0),0,person[j].playerrotation,0)*(.25-.4);
+
+ }
+
+ end=start+aim*1000;
+
+ //Blocks
+
+ wallhit=0;
+
+ beginx=(person[j].playercoords.x+block_spacing/2)/block_spacing-2;
+
+ if(beginx<0)beginx=0;
+
+ beginz=(person[j].playercoords.z+block_spacing/2)/block_spacing-2;
+
+ if(beginz<0)beginz=0;
+
+
+
+ endx=(person[j].playercoords.x+block_spacing/2)/block_spacing+2;
+
+ if(endx>num_blocks-1)endx=num_blocks-1;
+
+ endz=(person[j].playercoords.z+block_spacing/2)/block_spacing+2;
+
+ if(endz>num_blocks-1)endz=num_blocks-1;
+
+
+
+ if(beginx<endx&&beginz<endz)
+
+ finalwallhit=0;
+
+ for(int i=beginx;i<=endx;i++)
+
+ for(int j=beginz;j<=endz;j++){
+
+ move=0;
+
+ move.x=i*block_spacing;
+
+ move.z=j*block_spacing;
+
+ whichtri=blocks[citytype[i][j]].LineCheck2(start,end,&wallhit,move,cityrotation[i][j]*90);
+
+ if(whichtri!=-1){
+
+ end=wallhit;
+
+ finalwallhit=wallhit;
+
+ }
+
+ }
+
+ wallhit=0;
+
+ wallhit.x=camera.position.x;
+
+ wallhit.z=camera.position.z;
+
+ whichtri=Bigstreet.LineCheck2(start,end,&wallhit,wallhit,0);
+
+ if(whichtri!=-1){
+
+ end=wallhit;
+
+ finalwallhit=wallhit;
+
+ }
+
+ //People
+
+ whichhit=-1;
+
+ for(int i=0;i<numpeople;i++){
+
+ if(i!=j&&findDistancefast(person[j].playercoords,person[i].playercoords)<20000){
+
+ temphitstruct=person[i].BulletCollideWithPlayer(i, start, end);
+
+ if(temphitstruct.collision){
+
+ distance=findDistancefast(start,temphitstruct.hitlocation);
+
+ if(distance<olddistance||whichhit==-1){
+
+ end=temphitstruct.hitlocation;
+
+ olddistance=distance;
+
+ hitstruct=temphitstruct;
+
+ whichhit=i;
+
+ }
+
+ }
+
+ }
+
+ }
+
+ aimer[0]=start;
+
+ aimer[1]=end;
+
+ sprites.MakeSprite(bulletinstant, .4, 1, 0, 0, aimer[0], aimer[1], .2);
+
+
+
+ }
+
+ }
+
+ }
+
+ }
+
+
+
+ //Snow
+
+ snowdelay-=multiplier;
+
+ while(snowdelay<0&&environment==snowy_environment){
+
+ snowdelay+=1/precipitationdensity*2;
+
+ velocity=0;
+
+ velocity.y=-5;
+
+ start=camera.position;
+
+ start.y+=precipitationvert;
+
+ start.x+=Random()%(int)precipitationhorz;
+
+ start.z+=Random()%(int)precipitationhorz;
+
+ sprites.MakeSprite(snowsprite, 1, 1, 1, 1, start, velocity, 1.01);
+
+ }
+
+ while(snowdelay<0&&environment==rainy_environment){
+
+ snowdelay+=1/precipitationdensity/4;
+
+ velocity=0;
+
+ velocity.y=-100;
+
+ start=camera.position;
+
+ start.y+=precipitationvert;
+
+ start.x+=Random()%(int)precipitationhorz*.5;
+
+ start.z+=Random()%(int)precipitationhorz*.5;
+
+ sprites.MakeSprite(rainsprite, .5, 1, 1, 1, start, velocity, 2.00);
+
+ }
+
+
+
+ //Grenade collision
+
+ int wherex,wherey,whichsound,severwhat;
+
+ bool impact;
+
+ for(int i=0;i<sprites.howmanysprites;i++){
+
+ if(sprites.type[i]==grenadesprite||sprites.type[i]==spoonsprite||sprites.type[i]==pinsprite){
+
+ impact=0;
+
+ if(sprites.type[i]!=grenadesprite){
+
+ sprites.brightness[i]-=multiplier*.2;
+
+ }
+
+
+
+ if(findLengthfast(sprites.velocity[i])>0){
+
+ wherex=(sprites.location[i].x+block_spacing/2)/block_spacing;
+
+ wherey=(sprites.location[i].z+block_spacing/2)/block_spacing;
+
+ move=0;
+
+ move.x=wherex*block_spacing;
+
+ move.z=wherey*block_spacing;
+
+ whichtri=blocks[citytype[wherex][wherey]].LineCheck2(sprites.oldlocation[i],sprites.location[i],&wallhit,move,cityrotation[wherex][wherey]*90);
+
+ if(whichtri!=-1){
+
+ impact=1;
+
+ normalrotated=DoRotation(blocks[citytype[wherex][wherey]].normals[whichtri],0,cityrotation[wherex][wherey]*90,0);
+
+ if(sprites.size[i]>1)decals.MakeDecal(crater, wallhit,9,normalrotated, whichtri, &blocks[citytype[wherex][wherey]], move, cityrotation[wherex][wherey]*90);
+
+ sprites.location[i]=wallhit+normalrotated*.02;
+
+ ReflectVector(&sprites.velocity[i],&normalrotated);
+
+ sprites.velocity[i]*=.3;
+
+ if(sprites.type[i]==grenadesprite){
+
+ float gLoc[3];
+
+ gLoc[0]=(((sprites.location[i].x)-camera.position.x)/findLengthfast(sprites.velocity[i])*5+camera.position.x)/soundscalefactor;
+
+ gLoc[1]=(((sprites.location[i].y)-camera.position.y)/findLengthfast(sprites.velocity[i])*5+camera.position.y)/soundscalefactor;
+
+ gLoc[2]=(((sprites.location[i].z)-camera.position.z)/findLengthfast(sprites.velocity[i])*5+camera.position.z)/soundscalefactor;
+
+ whichsound=abs(Random()%2);
+
+ alSourcefv(gSourceID[bouncesound+whichsound], AL_POSITION, gLoc);
+
+ if(sprites.size[i]<=1)alSourcePlay(gSourceID[bouncesound+whichsound]);
+
+ }
+
+ if(findLengthfast(sprites.velocity[i])<=10)sprites.velocity[i]=0;
+
+ }
+
+ if(sprites.location[i].y<0){
+
+ impact=1;
+
+ sprites.velocity[i].y*=-1;
+
+ sprites.velocity[i]*=.3;
+
+ sprites.location[i].y=0;
+
+ if(sprites.type[i]==grenadesprite){
+
+ if(sprites.size[i]>1){
+
+ move=0;
+
+ sprites.location[i].y=-.5;
+
+ XYZ normish;
+
+ normish=0;
+
+ normish.y=1;
+
+ decals.MakeDecal(crater, sprites.location[i],9,normish, 0, &blocks[citytype[wherex][wherey]], move, 0);
+
+ }
+
+ float gLoc[3];
+
+ gLoc[0]=(((sprites.location[i].x)-camera.position.x)/findLengthfast(sprites.velocity[i])*5+camera.position.x)/soundscalefactor;
+
+ gLoc[1]=(((sprites.location[i].y)-camera.position.y)/findLengthfast(sprites.velocity[i])*5+camera.position.y)/soundscalefactor;
+
+ gLoc[2]=(((sprites.location[i].z)-camera.position.z)/findLengthfast(sprites.velocity[i])*5+camera.position.z)/soundscalefactor;
+
+ whichsound=abs(Random()%2);
+
+ alSourcefv(gSourceID[bouncesound+whichsound], AL_POSITION, gLoc);
+
+ if(sprites.size[i]<=1)alSourcePlay(gSourceID[bouncesound+whichsound]);
+
+ }
+
+ if(findLengthfast(sprites.velocity[i])<=10)sprites.velocity[i]=0;
+
+ }
+
+ if(sprites.type[i]==grenadesprite&&findLengthfast(sprites.velocity[i])>20){
+
+ HitStruct hitstruct;
+
+ for(int j=0;j<numpeople;j++){
+
+ if((j!=0||sprites.brightness[i]<.9)&&person[j].existing){
+
+ hitstruct=person[j].BulletCollideWithPlayer(j, sprites.oldlocation[i], sprites.location[i]);
+
+ if(hitstruct.collision){
+
+ impact=1;
+
+ sprites.location[i]=hitstruct.hitlocation;
+
+ float gLoc[3];
+
+ gLoc[0]=(((sprites.location[i].x)-camera.position.x)/findLengthfast(sprites.velocity[i])*5+camera.position.x)/soundscalefactor;
+
+ gLoc[1]=(((sprites.location[i].y)-camera.position.y)/findLengthfast(sprites.velocity[i])*5+camera.position.y)/soundscalefactor;
+
+ gLoc[2]=(((sprites.location[i].z)-camera.position.z)/findLengthfast(sprites.velocity[i])*5+camera.position.z)/soundscalefactor;
+
+ if(person[j].skeleton.free<1){
+
+ if((hitstruct.joint1->label==head||hitstruct.joint2->label==head)&&person[j].type!=zombietype){
+
+ alSourcefv(gSourceID[headwhacksound], AL_POSITION, gLoc);
+
+ if(sprites.size[i]<=1)alSourcePlay(gSourceID[headwhacksound]);
+
+ person[j].skeleton.free=1;
+
+ person[j].longdead=1;
+
+ for(int k=0;k<person[j].skeleton.num_joints;k++){
+
+ person[j].skeleton.joints[k].position=DoRotation(person[j].skeleton.joints[k].position,0,person[j].playerrotation,0);
+
+ person[j].skeleton.joints[k].position+=person[j].playercoords;
+
+ person[j].skeleton.joints[k].realoldposition=person[j].skeleton.joints[k].position;
+
+ person[j].skeleton.joints[k].velocity=person[j].velocity;
+
+ person[j].skeleton.joints[k].velocity.x+=abs(Random()%10)-5;
+
+ person[j].skeleton.joints[k].velocity.y+=abs(Random()%10)-5;
+
+ person[j].skeleton.joints[k].velocity.z+=abs(Random()%10)-5;
+
+ }
+
+ hitstruct.joint1->velocity+=sprites.velocity[i];
+
+ hitstruct.joint2->velocity+=sprites.velocity[i];
+
+ if(person[j].type==civiliantype)civkills++;
+
+ if(person[j].type==eviltype)goodkills++;
+
+ }else{
+
+ float totalarea;
+
+ alSourcefv(gSourceID[bodywhacksound], AL_POSITION, gLoc);
+
+ if(sprites.size[i]<=1)alSourcePlay(gSourceID[bodywhacksound]);
+
+ person[j].skeleton.offset=1;
+
+ for(int k=0;k<person[j].skeleton.num_joints;k++){
+
+ if(findDistancefast(DoRotation(person[j].skeleton.joints[k].position,0,person[j].playerrotation,0)+person[j].playercoords,hitstruct.hitlocation)<200){
+
+ totalarea+=(200/findDistancefast(DoRotation(person[j].skeleton.joints[k].position,0,person[j].playerrotation,0)+person[j].playercoords,hitstruct.hitlocation));
+
+ }
+
+ }
+
+ float offsetlength;
+
+ for(int k=0;k<person[j].skeleton.num_joints;k++){
+
+ if(findDistancefast(DoRotation(person[j].skeleton.joints[k].position,0,person[j].playerrotation,0)+person[j].playercoords,hitstruct.hitlocation)<200){
+
+ person[j].skeleton.joints[k].offset+=DoRotation(sprites.velocity[i]*.1*((200/findDistancefast(DoRotation(person[j].skeleton.joints[k].position,0,person[j].playerrotation,0)+person[j].playercoords,hitstruct.hitlocation))/totalarea*10),0,-person[j].playerrotation,0);
+
+ }
+
+ offsetlength=findLengthfast(person[j].skeleton.joints[k].offset);
+
+ if(offsetlength>9){
+
+ Normalise(&person[j].skeleton.joints[k].offset);
+
+ person[j].skeleton.joints[k].offset*=3;
+
+ }
+
+ }
+
+ }}
+
+ sprites.velocity[i]*=-.3;
+
+ }
+
+ }
+
+ }
+
+ }
+
+ sprites.oldlocation[i]=sprites.location[i];
+
+ }
+
+ //Explode
+
+ if(sprites.type[i]==grenadesprite){
+
+ sprites.brightness[i]-=multiplier*.3;
+
+ if(sprites.brightness[i]<=0||(impact&&sprites.size[i]>1)){
+
+ sprites.brightness[i]=0;
+
+ sprites.MakeSprite(smokesprite, 1, 1, 1, 1, sprites.location[i], facing*0, 60);
+
+ sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, sprites.location[i], facing*0, 9);
+
+ float gLoc[3];
+
+ gLoc[0]=(((sprites.location[i].x)-camera.position.x)/3+camera.position.x)/soundscalefactor;
+
+ gLoc[1]=(((sprites.location[i].y)-camera.position.y)/3+camera.position.y)/soundscalefactor;
+
+ gLoc[2]=(((sprites.location[i].z)-camera.position.z)/3+camera.position.z)/soundscalefactor;
+
+ alSourcefv(gSourceID[explosionsound], AL_POSITION, gLoc);
+
+ alSourcePlay(gSourceID[explosionsound]);
+
+ XYZ relation;
+
+ camerashake=1-findDistance(person[0].playercoords,sprites.location[i])/200;
+
+ //if(!sprites.size[i]>1){
+
+ overpoint=sprites.location[i];
+
+ overpoint.y+=3000;
+
+ underpoint=sprites.location[i];
+
+ underpoint.y-=3000;
+
+ move=0;
+
+ wherex=(sprites.location[i].x+block_spacing/2)/block_spacing;
+
+ wherey=(sprites.location[i].z+block_spacing/2)/block_spacing;
+
+ move.x=wherex*block_spacing;
+
+ move.z=wherey*block_spacing;
+
+ XYZ temp;
+
+ whichtri=sidewalkcollide.LineCheck2(overpoint,underpoint,&temp,move,cityrotation[wherex][wherey]*90);
+
+ XYZ normish;
+
+ normish=0;
+
+ normish.y=1;
+
+ if(whichtri>=0){
+
+ decals.MakeDecal(crater, sprites.location[i],9,normish, 0, &sidewalkcollide, move, cityrotation[wherex][wherey]*90);
+
+ }
+
+ if(whichtri==-1){
+
+ temp=sprites.location[i];
+
+ temp.y=-.5;
+
+ move=0;
+
+ decals.MakeDecal(crater, sprites.location[i],9,normish, 0, &sidewalkcollide, move, 0);
+
+ }
+
+ //}
+
+ for(int k=0;k<numpeople;k++){
+
+ if(person[k].existing&&(person[k].longdead!=-1||person[k].skeleton.free<1)){
+
+ if((findDistancefast(person[k].playercoords,sprites.location[i])<700&&person[k].skeleton.free<1)||(findDistancefast(person[k].averageloc,sprites.location[i])<700&&person[k].skeleton.free>=1)){
+
+ if(person[k].skeleton.free!=1){
+
+ if(person[k].type==civiliantype)civkills++;
+
+ if(person[k].type==eviltype)goodkills++;
+
+ person[k].skeleton.free=1;
+
+ person[k].killtargetvisible=0;
+
+ if((findDistancefast(person[k].playercoords,sprites.location[i])<600&&person[k].skeleton.free<1)||(findDistancefast(person[k].averageloc,sprites.location[i])<600&&person[k].skeleton.free>=1)||person[k].type==playertype){
+
+ person[k].health-=100;
+
+ person[k].bleeding=1;
+
+ }
+
+ person[k].DoAnimations(k);
+
+ person[k].longdead=1;
+
+
+
+ person[k].bleeddelay=1;
+
+ person[k].bjoint1=&person[k].skeleton.joints[person[k].skeleton.jointlabels[head]];
+
+ person[k].bjoint2=&person[k].skeleton.joints[person[k].skeleton.jointlabels[neck]];
+
+
+
+
+
+ for(int j=0;j<person[k].skeleton.num_joints;j++){
+
+ person[k].skeleton.joints[j].position=DoRotation(person[k].skeleton.joints[j].position,0,person[k].playerrotation,0);
+
+ person[k].skeleton.joints[j].position+=person[k].playercoords;
+
+ person[k].skeleton.joints[j].realoldposition=person[k].skeleton.joints[j].position;
+
+ person[k].skeleton.joints[j].velocity=DoRotation(person[k].skeleton.joints[j].velocity,0,person[k].playerrotation,0);
+
+ person[k].skeleton.joints[j].velocity+=person[k].velocity;
+
+ person[k].skeleton.joints[j].velocity.x+=abs(Random()%20)-10;
+
+ person[k].skeleton.joints[j].velocity.y+=abs(Random()%20)-10;
+
+ person[k].skeleton.joints[j].velocity.z+=abs(Random()%20)-10;
+
+ }}
+
+ for(int j=0;j<person[k].skeleton.num_joints;j++){
+
+ relation=person[k].skeleton.joints[j].position-sprites.location[i];
+
+ Normalise(&relation);
+
+ if(findDistance(person[k].skeleton.joints[j].position,sprites.location[i])>1)person[k].skeleton.joints[j].velocity+=relation/findDistance(person[k].skeleton.joints[j].position,sprites.location[i])*300;
+
+ else person[k].skeleton.joints[j].velocity+=relation*300;
+
+ }
+
+ person[k].longdead=1;
+
+ for(int j=0;j<person[k].skeleton.num_joints;j++){
+
+ //Sever stuff
+
+ if(findLengthfast(person[k].skeleton.joints[j].velocity)>1500&&person[k].skeleton.joints[j].existing==1&&abs(Random()%3)!=1){
+
+ sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,person[k].skeleton.joints[j].position, person[k].skeleton.joints[j].velocity/3, 9);
+
+ person[k].skeleton.DeleteJoint(j);
+
+ person[k].skeleton.broken=2;
+
+ person[k].health=-10000;
+
+ person[k].skeleton.joints[j].existing=0;
+
+ }
+
+ }
+
+ }
+
+ }
+
+ }
+
+
+
+ }
+
+ }
+
+ }
+
+ }
+
+
+
+ //camera shake
+
+ camerashake-=multiplier;
+
+ if(camerashake<0)camerashake=0;
+
+
+
+ //camera position
+
+ XYZ average;
+
+ if(!zoom)average=person[0].skeleton.joints[(person[0].skeleton.jointlabels[head])].position*(person[0].aimamount/2+.5)+person[0].skeleton.joints[(person[0].skeleton.jointlabels[neck])].position*((1-person[0].aimamount)/2);
+
+ if(zoom)average=person[0].skeleton.joints[(person[0].skeleton.jointlabels[righthand])].position;
+
+
+
+ if(person[0].skeleton.free==0&&thirdperson!=2)camera.position=person[0].playercoords+DoRotation(average,0,person[0].playerrotation,0);
+
+ if(person[0].skeleton.free==1&&thirdperson!=2)camera.position=average;
+
+
+
+ //Restraints
+
+ if(camera.position.y<.1)camera.position.y=.1;
+
+
+
+ if(thirdperson!=2){
+
+ oldrot=camera.visrotation;
+
+ oldrot2=camera.visrotation2;
+
+ }
+
+
+
+ //Kill count
+
+ for(int i=0;i<numpeople;i++){
+
+ if(person[i].oldhealth>0&&person[i].health<=0){
+
+ if(i==1)alSourcePlay(gSourceID[losesound]);
+
+ if(person[i].type==civiliantype){
+
+ alSourcePlay(gSourceID[disguisekillsound]);
+
+ score-=300;
+
+ }
+
+ if(person[i].type==eviltype){
+
+ alSourcePlay(gSourceID[soulinsound]);
+
+ score+=75;
+
+ if(person[i].whichgun==knife)score+=50;
+
+ }
+
+ person[i].firstlongdead=0;
+
+ }
+
+ person[i].oldhealth=person[i].health;
+
+ }
+
+
+
+ if(slomo==2){
+
+ psychicpower-=multiplier*15;
+
+ if(psychicpower<0){
+
+ soundscalefactor=soundscalefactordefault;
+
+ alSourceStop(gSourceID[whichsong]);
+
+ alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 0);
+
+ alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 0);
+
+ if(person[0].whichgun==knife)whichsong=knifesong;
+
+ if(person[0].whichgun!=knife)whichsong=shootsong;
+
+ if(type==zombie_type)whichsong=zombiesong;
+
+ alSourcef(gSourceID[whichsong], AL_PITCH, 1);
+
+ alSourcePlay(gSourceID[whichsong]);
+
+ alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1);
+
+ alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1);
+
+ slomo=0;
+
+ alSourcePlay(gSourceID[soulinsound]);
+
+ psychicpower=0;
+
+ flashamount=.5;
+
+ flashr=1;flashg=1;flashb=1;
+
+ }
+
+ }
+
+ psychicpower+=multiplier*5;
+
+ if(psychicpower>10)psychicpower=10;
+
+
+
+ //3d sound
+
+ ALint tempInt;
+
+ float gLoc[3];
+
+ gLoc[0]=camera.position.x/soundscalefactor;
+
+ gLoc[1]=camera.position.y/soundscalefactor;
+
+ gLoc[2]=camera.position.z/soundscalefactor;
+
+ //Set listener position
+
+ alListenerfv(AL_POSITION, gLoc);
+
+
+
+ //Set orientation with forward and up vectors
+
+ XYZ upvector;
+
+ upvector=0;
+
+ upvector.z=-1;
+
+
+
+ upvector=DoRotation(upvector,-camera.rotation2+90,0,0);
+
+ upvector=DoRotation(upvector,0,0-camera.rotation,0);
+
+
+
+ float ori[6];
+
+ ori[0] = -facing.x;
+
+ ori[1] = facing.y;
+
+ ori[2] = facing.z;
+
+ ori[3] = -upvector.x;
+
+ ori[4] = upvector.y;
+
+ ori[5] = upvector.z;
+
+ alListenerfv(AL_ORIENTATION, ori);
+
+
+
+ if(person[0].currentanimation==throwanim||person[0].currentanimation==diveanim||paused){
+
+ MoveMouse(oldmouseloc.h,oldmouseloc.v,&mouseloc);
+
+ GetMouse(&mouseloc);
+
+ }
+
+ oldmouseloc=mouseloc;
+
+
+
+ if(score<0)score=0;
+
+ }
+
+} \ No newline at end of file
diff --git a/Source/Globals.cpp b/Source/Globals.cpp
new file mode 100644
index 0000000..c9b047c
--- /dev/null
+++ b/Source/Globals.cpp
@@ -0,0 +1,90 @@
+#include "Quaternions.h"
+#include "Constants.h"
+#include "Models.h"
+#include "Person.h"
+#include "Game.h"
+
+float sinefluct;
+float sinefluctprog;
+
+double multiplier=0;
+
+unsigned int gSourceID[100]; // hundred source IDs
+unsigned int gSampleSet[100]; // hundred sample set ID numbers
+
+float precipitationhorz;
+float precipitationvert;
+float precipitationdensity;
+
+int environment;
+
+float soundscalefactor;
+int slomo;
+
+Animation animation[30];
+Model skeletonmodels[10];
+Model gunmodels[11];
+Costume costume[10];
+Sprites sprites;
+Decals decals;
+int thirdperson;
+int nocolors;
+int visions;
+Camera camera;
+float rad2deg;
+Skeleton testskeleton;
+
+float snowdelay;
+
+float camerashake;
+
+Fog fog;
+
+int forwardskey;
+int backwardskey;
+int leftkey;
+int rightkey;
+int aimkey;
+int psychicaimkey;
+int psychickey;
+
+bool blood;
+
+float fogcolorr;
+float fogcolorg;
+float fogcolorb;
+
+float d;
+float a1,a2,a3;
+float total,denom,mu;
+XYZ pa1,pa2,pa3;
+
+float u0, u1, u2;
+float v0, v1, v2;
+float a, b;
+float max;
+int i, j;
+bool bInter;
+float pointv[3];
+float p1v[3];
+float p2v[3];
+float p3v[3];
+float normalv[3];
+
+XYZ vel;
+XYZ midp;
+XYZ newpoint1,newpoint2;
+
+float oldlength;
+float relaxlength;
+
+float friction;
+int numrepeats;
+float groundlevel;
+float offset;
+XYZ impact;
+XYZ overpoint;
+XYZ underpoint;
+int whichtri;
+XYZ normalrotated;
+bool groundish;
diff --git a/Source/MacInput.cpp b/Source/MacInput.cpp
new file mode 100644
index 0000000..a6afc8f
--- /dev/null
+++ b/Source/MacInput.cpp
@@ -0,0 +1,42 @@
+/**> HEADER FILES <**/
+#include "MacInput.h"
+
+/**> Mouse Stuff <**/
+CursorDevicePtr theCursor;
+
+/********************> IsKeyDown() <*****/
+Boolean IsKeyDown( unsigned char *keyMap, unsigned short theKey )
+{
+ long keyMapIndex;
+ Boolean isKeyDown;
+ short bitToCheck;
+
+ // Calculate the key map index
+ keyMapIndex = keyMap[theKey/8];
+
+ // Calculate the individual bit to check
+ bitToCheck = theKey%8;
+
+ // Check the status of the key
+ isKeyDown = ( keyMapIndex >> bitToCheck ) & 0x01;
+
+ // Return the status of the key
+ return isKeyDown;
+
+}
+
+void InitMouse()
+{
+ CursorDeviceNewDevice( &theCursor ); //Mouse
+}
+
+void MoveMouse(int xcoord, int ycoord, Point *mouseloc)
+{
+ CursorDeviceMoveTo( theCursor, xcoord, ycoord);
+ GetMouse(mouseloc);
+}
+
+void DisposeMouse()
+{
+ CursorDeviceDisposeDevice( theCursor );//Mouse
+} \ No newline at end of file
diff --git a/Source/MacInput.h b/Source/MacInput.h
new file mode 100644
index 0000000..04f5e42
--- /dev/null
+++ b/Source/MacInput.h
@@ -0,0 +1,101 @@
+#ifndef _MACINPUT_H_
+#define _MACINPUT_H_
+
+/**> HEADER FILES <**/
+#include <stdlib.h>
+#include <stdio.h>
+#include <CursorDevices.h> //Mouse
+
+/**> CONSTANT DECLARATIONS <**/
+// Mac Keyboard Codes
+#define MAC_1_KEY 0x12
+#define MAC_2_KEY 0x13
+#define MAC_3_KEY 0x14
+#define MAC_4_KEY 0x15
+#define MAC_5_KEY 0x17
+#define MAC_6_KEY 0x16
+#define MAC_7_KEY 0x1A
+#define MAC_8_KEY 0x1C
+#define MAC_9_KEY 0x19
+#define MAC_0_KEY 0x1D
+#define MAC_NUMPAD_1_KEY 0x53
+#define MAC_NUMPAD_2_KEY 0x54
+#define MAC_NUMPAD_3_KEY 0x55
+#define MAC_NUMPAD_4_KEY 0x56
+#define MAC_NUMPAD_5_KEY 0x57
+#define MAC_NUMPAD_6_KEY 0x58
+#define MAC_NUMPAD_7_KEY 0x59
+#define MAC_NUMPAD_8_KEY 0x5B
+#define MAC_NUMPAD_9_KEY 0x5C
+#define MAC_NUMPAD_0_KEY 0x52
+#define MAC_A_KEY 0x00
+#define MAC_B_KEY 0x0B
+#define MAC_C_KEY 0x08
+#define MAC_D_KEY 0x02
+#define MAC_E_KEY 0x0E
+#define MAC_F_KEY 0x03
+#define MAC_G_KEY 0x05
+#define MAC_H_KEY 0x04
+#define MAC_I_KEY 0x22
+#define MAC_J_KEY 0x26
+#define MAC_K_KEY 0x28
+#define MAC_L_KEY 0x25
+#define MAC_M_KEY 0x2E
+#define MAC_N_KEY 0x2D
+#define MAC_O_KEY 0x1F
+#define MAC_P_KEY 0x23
+#define MAC_Q_KEY 0x0C
+#define MAC_R_KEY 0x0F
+#define MAC_S_KEY 0x01
+#define MAC_T_KEY 0x11
+#define MAC_U_KEY 0x20
+#define MAC_V_KEY 0x09
+#define MAC_W_KEY 0x0D
+#define MAC_X_KEY 0x07
+#define MAC_Y_KEY 0x10
+#define MAC_Z_KEY 0x06
+#define MAC_F1_KEY 0x7A
+#define MAC_F2_KEY 0x78
+#define MAC_F3_KEY 0x63
+#define MAC_F4_KEY 0x76
+#define MAC_F5_KEY 0x60
+#define MAC_F6_KEY 0x61
+#define MAC_F7_KEY 0x62
+#define MAC_F8_KEY 0x64
+#define MAC_F9_KEY 0x65
+#define MAC_F10_KEY 0x6D
+#define MAC_F11_KEY 0x67
+#define MAC_F12_KEY 0x6F
+#define MAC_RETURN_KEY 0x24
+#define MAC_ENTER_KEY 0x4C
+#define MAC_TAB_KEY 0x30
+#define MAC_SPACE_KEY 0x31
+#define MAC_DELETE_KEY 0x33
+#define MAC_ESCAPE_KEY 0x35
+#define MAC_COMMAND_KEY 0x37
+#define MAC_SHIFT_KEY 0x38
+#define MAC_CAPS_LOCK_KEY 0x39
+#define MAC_OPTION_KEY 0x3A
+#define MAC_CONTROL_KEY 0x3B
+#define MAC_PAGE_UP_KEY 0x74
+#define MAC_PAGE_DOWN_KEY 0x79
+#define MAC_INSERT_KEY 0x72
+#define MAC_DEL_KEY 0x75
+#define MAC_HOME_KEY 0x73
+#define MAC_END_KEY 0x77
+#define MAC_LEFT_BRACKET_KEY 0x21
+#define MAC_RIGHT_BRACKET_KEY 0x1E
+#define MAC_ARROW_UP_KEY 0x7E
+#define MAC_ARROW_DOWN_KEY 0x7D
+#define MAC_ARROW_LEFT_KEY 0x7B
+#define MAC_ARROW_RIGHT_KEY 0x7C
+
+
+/**> FUNCTION PROTOTYPES <**/
+Boolean IsKeyDown( unsigned char *keyMap, unsigned short theKey );
+void InitMouse();
+void MoveMouse(int xcoord, int ycoord, Point *mouseloc);
+void RefreshMouse(Point *mouseloc);
+void DisposeMouse();
+
+#endif \ No newline at end of file
diff --git a/Source/Main.cpp b/Source/Main.cpp
new file mode 100644
index 0000000..3eb8803
--- /dev/null
+++ b/Source/Main.cpp
@@ -0,0 +1,64 @@
+/********************> Headers <*****/
+
+#include "Game.h"
+
+
+
+/********************> Globals <*****/
+
+
+
+Game game;
+
+
+
+/********************> main() <*****/
+
+void main( void )
+
+ {
+
+
+
+ ToolboxInit();
+
+
+
+ if ( HasAppearance() )
+
+ RegisterAppearanceClient();
+
+
+
+
+
+ game.InitGL();
+
+
+
+ game.InitGame();
+
+
+
+ game.EventLoop();
+
+
+
+ game.Dispose();
+
+
+
+ if ( HasAppearance() )
+
+ UnregisterAppearanceClient();
+
+
+
+ FlushEvents( everyEvent, 0 );
+
+ ExitToShell();
+
+
+
+}
+
diff --git a/Source/Maths.cpp b/Source/Maths.cpp
new file mode 100644
index 0000000..f8f2664
--- /dev/null
+++ b/Source/Maths.cpp
@@ -0,0 +1,21 @@
+/**> HEADER FILES <**/
+#include "Maths.h"
+
+double fast_sqrt (register double arg)
+{
+ // Can replace with slower return std::sqrt(arg);
+ register double result;
+
+ if (arg == 0.0) return 0.0;
+
+ asm {
+ frsqrte result,arg // Calculate Square root
+ }
+
+ // Newton Rhapson iterations.
+ result = result + 0.5 * result * (1.0 - arg * result * result);
+ result = result + 0.5 * result * (1.0 - arg * result * result);
+
+ return result * arg;
+}
+
diff --git a/Source/Maths.h b/Source/Maths.h
new file mode 100644
index 0000000..478fb7a
--- /dev/null
+++ b/Source/Maths.h
@@ -0,0 +1,10 @@
+#ifndef _MATHS_H_
+#define _MATHS_H_
+
+
+/**> HEADER FILES <**/
+#include <math.h>
+
+double fast_sqrt (register double arg);
+
+#endif \ No newline at end of file
diff --git a/Source/Models.cpp b/Source/Models.cpp
new file mode 100644
index 0000000..430f052
--- /dev/null
+++ b/Source/Models.cpp
@@ -0,0 +1,339 @@
+#include "Models.h"
+
+//Functions
+void Model::UpdateVertexArray(){
+ int i;
+ for(i=0;i<TriangleNum;i++){
+ vArray[i*27+0]=vertex[Triangles[i].vertex[0]].x;
+ vArray[i*27+1]=vertex[Triangles[i].vertex[0]].y;
+ vArray[i*27+2]=vertex[Triangles[i].vertex[0]].z;
+ vArray[i*27+3]=normals[i].x;
+ vArray[i*27+4]=normals[i].y;
+ vArray[i*27+5]=normals[i].z;
+ vArray[i*27+6]=Triangles[i].r;
+ vArray[i*27+7]=Triangles[i].g;
+ vArray[i*27+8]=Triangles[i].b;
+
+ vArray[i*27+9]=vertex[Triangles[i].vertex[1]].x;
+ vArray[i*27+10]=vertex[Triangles[i].vertex[1]].y;
+ vArray[i*27+11]=vertex[Triangles[i].vertex[1]].z;
+ vArray[i*27+12]=normals[i].x;
+ vArray[i*27+13]=normals[i].y;
+ vArray[i*27+14]=normals[i].z;
+ vArray[i*27+15]=Triangles[i].r;
+ vArray[i*27+16]=Triangles[i].g;
+ vArray[i*27+17]=Triangles[i].b;
+
+ vArray[i*27+18]=vertex[Triangles[i].vertex[2]].x;
+ vArray[i*27+19]=vertex[Triangles[i].vertex[2]].y;
+ vArray[i*27+20]=vertex[Triangles[i].vertex[2]].z;
+ vArray[i*27+21]=normals[i].x;
+ vArray[i*27+22]=normals[i].y;
+ vArray[i*27+23]=normals[i].z;
+ vArray[i*27+24]=Triangles[i].r;
+ vArray[i*27+25]=Triangles[i].g;
+ vArray[i*27+26]=Triangles[i].b;
+ }
+
+ XYZ average;
+ int howmany;
+ average=0;
+ howmany=0;
+ boundingboxmin=20000;
+ boundingboxmax=-20000;
+ for(int i=0;i<vertexNum;i++){
+ howmany++;
+ average=average+vertex[i];
+ if(vertex[i].x<boundingboxmin.x)boundingboxmin.x=vertex[i].x;
+ if(vertex[i].y<boundingboxmin.y)boundingboxmin.y=vertex[i].y;
+ if(vertex[i].z<boundingboxmin.z)boundingboxmin.z=vertex[i].z;
+ if(vertex[i].x>boundingboxmax.x)boundingboxmax.x=vertex[i].x;
+ if(vertex[i].y>boundingboxmax.y)boundingboxmax.y=vertex[i].y;
+ if(vertex[i].z>boundingboxmax.z)boundingboxmax.z=vertex[i].z;
+ }
+ average=average/howmany;
+ boundingspherecenter=average;
+ boundingsphereradius=0;
+ for(int i=0;i<vertexNum;i++){
+ if(findDistancefast(average,vertex[i])>boundingsphereradius)boundingsphereradius=findDistancefast(average,vertex[i]);
+ }
+ boundingsphereradius=fast_sqrt(boundingsphereradius);
+}
+
+bool Model::load(Str255 Name)
+{
+ short tfile;
+ long i,count,err;
+ Files file;
+
+ tfile=file.OpenFile(Name);
+ SetFPos(tfile,fsFromStart,0);
+
+ // read model settings
+
+ count=2;
+ err=FSRead(tfile,&count,&vertexNum);
+ count=2;
+ err=FSRead(tfile,&count,&TriangleNum);
+
+ // read the model data
+
+ count=(long)vertexNum*sizeof(XYZ);
+ err=FSRead(tfile,&count,&vertex);
+ count=(long)TriangleNum*sizeof(TexturedTriangle);
+ err=FSRead(tfile,&count,&Triangles);
+
+ FSClose(tfile);
+
+ UpdateVertexArray();
+
+ XYZ average;
+ int howmany;
+ average=0;
+ howmany=0;
+ for(int i=0;i<vertexNum;i++){
+ howmany++;
+ average=average+vertex[i];
+ }
+ average=average/howmany;
+ boundingspherecenter=average;
+ boundingsphereradius=0;
+ for(int i=0;i<vertexNum;i++){
+ if(findDistancefast(average,vertex[i])>boundingsphereradius)boundingsphereradius=findDistancefast(average,vertex[i]);
+ }
+ boundingsphereradius=fast_sqrt(boundingsphereradius);
+
+ return 1;
+}
+
+void Model::Scale(float xscale,float yscale,float zscale)
+{
+ int i;
+ for(i=0; i<vertexNum; i++){
+ vertex[i].x*=xscale;
+ vertex[i].y*=yscale;
+ vertex[i].z*=zscale;
+ }
+ UpdateVertexArray();
+}
+
+void Model::MultColor(float howmuch)
+{
+ int i;
+ for(i=0; i<TriangleNum; i++){
+ Triangles[i].r*=howmuch;
+ Triangles[i].g*=howmuch;
+ Triangles[i].b*=howmuch;
+ }
+ UpdateVertexArray();
+}
+
+void Model::ScaleNormals(float xscale,float yscale,float zscale)
+{
+ int i;
+ for(i=0; i<vertexNum; i++){
+ normals[i].x*=xscale;
+ normals[i].y*=yscale;
+ normals[i].z*=zscale;
+ }
+ UpdateVertexArray();
+}
+
+void Model::Translate(float xtrans,float ytrans,float ztrans)
+{
+ int i;
+ for(i=0; i<vertexNum; i++){
+ vertex[i].x+=xtrans;
+ vertex[i].y+=ytrans;
+ vertex[i].z+=ztrans;
+ }
+ UpdateVertexArray();
+}
+
+void Model::Rotate(float xang,float yang,float zang)
+{
+ int i;
+ for(i=0; i<vertexNum; i++){
+ vertex[i]=DoRotation(vertex[i],xang,yang,zang);
+ }
+ UpdateVertexArray();
+}
+
+
+void Model::CalculateNormals()
+{
+ int i,j;
+ for(i=0;i<TriangleNum;i++){
+ CrossProduct(vertex[Triangles[i].vertex[1]]-vertex[Triangles[i].vertex[0]],vertex[Triangles[i].vertex[2]]-vertex[Triangles[i].vertex[0]],&normals[i]);
+ Normalise(&normals[i]);
+ }
+ UpdateVertexArray();
+}
+
+extern int nocolors;
+void Model::draw()
+{
+ if(!nocolors){
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+ glVertexPointer(3, GL_FLOAT, 9*sizeof(GLfloat),&vArray[0]);
+ glNormalPointer(GL_FLOAT, 9*sizeof(GLfloat),&vArray[3]);
+ glColorPointer(3,GL_FLOAT, 9*sizeof(GLfloat),&vArray[6]);
+ glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3);
+ }
+ if(nocolors){
+ glColor4f(0,0,0,1);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+ glVertexPointer(3, GL_FLOAT, 9*sizeof(GLfloat),&vArray[0]);
+ glNormalPointer(GL_FLOAT, 9*sizeof(GLfloat),&vArray[3]);
+ glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3);
+ }
+}
+
+
+void Model::draw(float r, float g, float b)
+{
+ if(!nocolors)glColor4f(r,g,b,1);
+ if(nocolors==1)glColor4f(0,0,0,1);
+ if(nocolors==2)glColor4f(1,0,0,1);
+ if(nocolors==3)glColor4f(0,0,1,1);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+ glVertexPointer(3, GL_FLOAT, 9*sizeof(GLfloat),&vArray[0]);
+ glNormalPointer(GL_FLOAT, 9*sizeof(GLfloat),&vArray[3]);
+ glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3);
+}
+
+void Model::draw(float r, float g, float b, float o)
+{
+ if(!nocolors)glColor4f(r,g,b,o);
+ if(nocolors==1)glColor4f(0,0,0,1);
+ if(nocolors==2)glColor4f(1,0,0,1);
+ if(nocolors==3)glColor4f(1,1,1,1);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+ glVertexPointer(3, GL_FLOAT, 9*sizeof(GLfloat),&vArray[0]);
+ glNormalPointer(GL_FLOAT, 9*sizeof(GLfloat),&vArray[3]);
+ glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3);
+}
+
+void Model::draw(float r, float g, float b, float x, float y, float z)
+{
+ if(!nocolors)glColor4f(r,g,b,1);
+ if(nocolors==1)glColor4f(0,0,0,1);
+ if(nocolors==2)glColor4f(1,0,0,1);
+ if(nocolors==3)glColor4f(1,1,1,1);
+ glNormal3f(x,y,z);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_NORMAL_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+ glVertexPointer(3, GL_FLOAT, 9*sizeof(GLfloat),&vArray[0]);
+ glDrawArrays(GL_TRIANGLES, 0, TriangleNum*3);
+}
+
+
+int Model::LineCheck(XYZ p1,XYZ p2, XYZ *p)
+{
+ int j;
+ float distance;
+ float olddistance;
+ int intersecting;
+ int firstintersecting=-1;
+ XYZ point;
+ if(sphere_line_intersection(p1.x,p1.y,p1.z,
+ p2.x,p2.y,p2.z,
+ boundingspherecenter.x,boundingspherecenter.y,boundingspherecenter.z,
+ boundingsphereradius))
+ for (j=0;j<TriangleNum;j++){
+ intersecting=LineFacetd(p1,p2,vertex[Triangles[j].vertex[0]],vertex[Triangles[j].vertex[1]],vertex[Triangles[j].vertex[2]],normals[j],&point);
+ distance=(point.x-p1.x)*(point.x-p1.x)+(point.y-p1.y)*(point.y-p1.y)+(point.z-p1.z)*(point.z-p1.z);
+ if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j; *p=point;}
+ }
+ return firstintersecting;
+}
+
+int Model::LineCheck2(XYZ p1,XYZ p2, XYZ *p, XYZ move, float rotate)
+{
+ int j;
+ float distance;
+ float olddistance;
+ int intersecting;
+ int firstintersecting=-1;
+ XYZ point;
+ p1=p1-move;
+ p2=p2-move;
+ if(rotate)p1=DoRotation(p1,0,-rotate,0);
+ if(rotate)p2=DoRotation(p2,0,-rotate,0);
+ if(sphere_line_intersection(p1.x,p1.y,p1.z,
+ p2.x,p2.y,p2.z,
+ boundingspherecenter.x,boundingspherecenter.y,boundingspherecenter.z,
+ boundingsphereradius))
+ for (j=0;j<TriangleNum;j++){
+ intersecting=LineFacetd(p1,p2,vertex[Triangles[j].vertex[0]],vertex[Triangles[j].vertex[1]],vertex[Triangles[j].vertex[2]],normals[j],&point);
+ distance=(point.x-p1.x)*(point.x-p1.x)+(point.y-p1.y)*(point.y-p1.y)+(point.z-p1.z)*(point.z-p1.z);
+ if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j; *p=point;}
+ }
+
+ if(rotate)*p=DoRotation(*p,0,rotate,0);
+ *p=*p+move;
+ return firstintersecting;
+}
+
+int Model::LineCheck2(XYZ *p1,XYZ *p2, XYZ *p, XYZ *move, float *rotate)
+{
+ int j;
+ float distance;
+ float olddistance;
+ int intersecting;
+ int firstintersecting=-1;
+ XYZ point;
+ *p1=*p1-*move;
+ *p2=*p2-*move;
+ if(*rotate)*p1=DoRotation(*p1,0,-*rotate,0);
+ if(*rotate)*p2=DoRotation(*p2,0,-*rotate,0);
+ if(sphere_line_intersection(p1->x,p1->y,p1->z,
+ p2->x,p2->y,p2->z,
+ boundingspherecenter.x,boundingspherecenter.y,boundingspherecenter.z,
+ boundingsphereradius))
+ for (j=0;j<TriangleNum;j++){
+ intersecting=LineFacetd(p1,p2,&vertex[Triangles[j].vertex[0]],&vertex[Triangles[j].vertex[1]],&vertex[Triangles[j].vertex[2]],&normals[j],&point);
+ distance=(point.x-p1->x)*(point.x-p1->x)+(point.y-p1->y)*(point.y-p1->y)+(point.z-p1->z)*(point.z-p1->z);
+ if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j; *p=point;}
+ }
+
+ if(*rotate)*p=DoRotation(*p,0,*rotate,0);
+ *p=*p+*move;
+ return firstintersecting;
+}
+
+int Model::LineCheck3(XYZ p1,XYZ p2, XYZ *p, XYZ move, float rotate, float *d)
+{
+ int j;
+ float distance;
+ float olddistance;
+ int intersecting;
+ int firstintersecting=-1;
+ XYZ point;
+ p1=p1-move;
+ p2=p2-move;
+ p1=DoRotation(p1,0,-rotate,0);
+ p2=DoRotation(p2,0,-rotate,0);
+ if(sphere_line_intersection(p1.x,p1.y,p1.z,
+ p2.x,p2.y,p2.z,
+ boundingspherecenter.x,boundingspherecenter.y,boundingspherecenter.z,
+ boundingsphereradius))
+ for (j=0;j<TriangleNum;j++){
+ intersecting=LineFacetd(p1,p2,vertex[Triangles[j].vertex[0]],vertex[Triangles[j].vertex[1]],vertex[Triangles[j].vertex[2]],normals[j],&point);
+ distance=(point.x-p1.x)*(point.x-p1.x)+(point.y-p1.y)*(point.y-p1.y)+(point.z-p1.z)*(point.z-p1.z);
+ if((distance<olddistance||firstintersecting==-1)&&intersecting){olddistance=distance; firstintersecting=j; *p=point;}
+ }
+ *d=intersecting;
+ *p=DoRotation(*p,0,rotate,0);
+ *p=*p+move;
+ return firstintersecting;
+} \ No newline at end of file
diff --git a/Source/Models.h b/Source/Models.h
new file mode 100644
index 0000000..2cde5e7
--- /dev/null
+++ b/Source/Models.h
@@ -0,0 +1,60 @@
+#ifndef _MODELS_H_
+#define _MODELS_H_
+
+/**> Model Loading <**/
+//
+// Model Maximums
+//
+#include "Quaternions.h"
+#include <gl.h>
+#include <glu.h>
+#include "Files.h"
+#include "Constants.h"
+
+#define max_textured_triangle 400 // maximum number of texture-filled triangles in a model
+#define max_model_vertex max_textured_triangle*3 // maximum number of vertexs
+
+
+//
+// Model Structures
+//
+
+class TexturedTriangle{
+ public:
+ short vertex[3];
+ float r,g,b;
+};
+
+class Model{
+ public:
+ short vertexNum,TriangleNum;
+
+ XYZ vertex[max_model_vertex];
+ XYZ normals[max_textured_triangle];
+ TexturedTriangle Triangles[max_textured_triangle];
+ GLfloat vArray[max_textured_triangle*27];
+
+ XYZ boundingspherecenter;
+ float boundingsphereradius;
+ int LineCheck(XYZ p1,XYZ p2, XYZ *p);
+ int LineCheck2(XYZ p1,XYZ p2, XYZ *p,XYZ move,float rotate);
+ int LineCheck2(XYZ *p1,XYZ *p2, XYZ *p,XYZ *move,float *rotate);
+ int LineCheck3(XYZ p1,XYZ p2, XYZ *p,XYZ move,float rotate,float *d);
+
+ void UpdateVertexArray();
+ bool load(Str255 Name);
+ void Scale(float xscale,float yscale,float zscale);
+ void ScaleNormals(float xscale,float yscale,float zscale);
+ void Translate(float xtrans,float ytrans,float ztrans);
+ void CalculateNormals();
+ void draw();
+ void draw(float r,float g,float b);
+ void draw(float r,float g,float b, float o);
+ void draw(float r,float g,float b, float x, float y, float z);
+ void Rotate(float xang,float yang,float zang);
+ void MultColor(float howmuch);
+
+ XYZ boundingboxmin,boundingboxmax;
+};
+
+#endif \ No newline at end of file
diff --git a/Source/Person.cpp b/Source/Person.cpp
new file mode 100644
index 0000000..172c2d1
--- /dev/null
+++ b/Source/Person.cpp
@@ -0,0 +1,1037 @@
+/**> HEADER FILES <**/
+#include "Person.h"
+
+extern double multiplier;
+extern unsigned int gSourceID[100];
+extern unsigned int gSampleSet[100];
+extern Animation animation[30];
+extern int thirdperson;
+extern int visions;
+extern Camera camera;
+extern float rad2deg;
+extern Model gunmodels[10];
+extern Model skeletonmodels[10];
+extern Sprites sprites;
+extern float soundscalefactor;
+extern int slomo;
+
+extern int forwardskey;
+extern int backwardskey;
+extern int leftkey;
+extern int rightkey;
+extern int aimkey;
+extern int psychicaimkey;
+extern int psychickey;
+
+HitStruct Person::BulletCollideWithPlayer(int who, XYZ start, XYZ end){
+ float damage=20;
+ XYZ tempbulletloc[2];
+ XYZ collisionpoint;
+ XYZ sparkpos;
+ GLfloat M[16];
+ int collide;
+ float howfar;
+ XYZ average;
+ XYZ facing;
+ int howmany;
+ float distancemax;
+ HitStruct hitstruct;
+ hitstruct.collision=0;
+ //Make bounding sphere
+ average=0;
+ howmany=0;
+ for(int j=0;j<skeleton.num_joints;j++){
+ average.x=average.x+skeleton.joints[j].position.x;
+ average.y=average.y+skeleton.joints[j].position.y;
+ average.z=average.z+skeleton.joints[j].position.z;
+ howmany++;
+ }
+ average=average/howmany;
+ distancemax=0;
+ for(int j=0;j<skeleton.num_joints;j++){
+ if(findDistancefast(average,skeleton.joints[j].position)>distancemax){
+ distancemax=findDistancefast(average,skeleton.joints[j].position);
+ }
+ }
+ distancemax=fast_sqrt(distancemax);
+ //Collide with player
+ if(skeleton.free<1){
+ start=start-playercoords;
+ end=end-playercoords;
+ if(playerrotation)start=DoRotation(start,0,-playerrotation,0);
+ if(playerrotation)end=DoRotation(end,0,-playerrotation,0);
+ }
+ tempbulletloc[0]=start;
+ tempbulletloc[1]=end;
+ if(sphere_line_intersection(tempbulletloc[0].x,tempbulletloc[0].y,tempbulletloc[0].z,
+ tempbulletloc[1].x,tempbulletloc[1].y,tempbulletloc[1].z,
+ average.x, average.y, average.z, distancemax)){
+ for(int j=0;j<skeleton.num_joints;j++){
+ if(skeleton.joints[j].hasparent&&skeleton.joints[j].visible){
+ tempbulletloc[0]=start;
+ tempbulletloc[1]=end;
+ glPushMatrix();
+ glLoadIdentity();
+ glScalef(1,1/skeleton.joints[j].length,1);
+ glRotatef(skeleton.joints[j].rotate2-90,0,0,1);
+ glRotatef(skeleton.joints[j].rotate1-90,0,1,0);
+ glTranslatef( (-(skeleton.joints[j].position.x+skeleton.joints[j].parent->position.x)/2),
+ (-(skeleton.joints[j].position.y+skeleton.joints[j].parent->position.y)/2),
+ (-(skeleton.joints[j].position.z+skeleton.joints[j].parent->position.z)/2));
+ glTranslatef(tempbulletloc[0].x,tempbulletloc[0].y,tempbulletloc[0].z);
+ glGetFloatv(GL_MODELVIEW_MATRIX,M);
+ tempbulletloc[0].x=M[12];
+ tempbulletloc[0].y=M[13];
+ tempbulletloc[0].z=M[14];
+ glPopMatrix();
+ glPushMatrix();
+ glLoadIdentity();
+ glScalef(1,1/skeleton.joints[j].length,1);
+ glRotatef(skeleton.joints[j].rotate2-90,0,0,1);
+ glRotatef(skeleton.joints[j].rotate1-90,0,1,0);
+ glTranslatef( (-(skeleton.joints[j].position.x+skeleton.joints[j].parent->position.x)/2),
+ (-(skeleton.joints[j].position.y+skeleton.joints[j].parent->position.y)/2),
+ (-(skeleton.joints[j].position.z+skeleton.joints[j].parent->position.z)/2));
+ glTranslatef(tempbulletloc[1].x,tempbulletloc[1].y,tempbulletloc[1].z);
+ glGetFloatv(GL_MODELVIEW_MATRIX,M);
+ tempbulletloc[1].x=M[12];
+ tempbulletloc[1].y=M[13];
+ tempbulletloc[1].z=M[14];
+ glPopMatrix();
+ collide=skeletonmodels[skeleton.joints[j].modelnum].LineCheck(tempbulletloc[0],tempbulletloc[1],&collisionpoint);
+ if(collide!=-1)
+ {
+ glPushMatrix();
+ glLoadIdentity();
+ glTranslatef( (skeleton.joints[j].position.x+skeleton.joints[j].parent->position.x)/2,
+ (skeleton.joints[j].position.y+skeleton.joints[j].parent->position.y)/2,
+ (skeleton.joints[j].position.z+skeleton.joints[j].parent->position.z)/2);
+ glRotatef(-skeleton.joints[j].rotate1+90,0,1,0);
+ glRotatef(-skeleton.joints[j].rotate2+90,0,0,1);
+ glScalef(1,skeleton.joints[j].length,1);
+ glTranslatef(collisionpoint.x,collisionpoint.y,collisionpoint.z);
+ glGetFloatv(GL_MODELVIEW_MATRIX,M);
+ collisionpoint.x=M[12];
+ collisionpoint.y=M[13];
+ collisionpoint.z=M[14];
+ glPopMatrix();
+ hitstruct.collision=1;
+ hitstruct.hitlocation=collisionpoint;
+ hitstruct.joint1=&skeleton.joints[j];
+ hitstruct.joint2=skeleton.joints[j].parent;
+ }
+ }
+ }
+ for(int j=0;j<skeleton.num_muscles;j++){
+ if(skeleton.muscles[j].visible){
+ tempbulletloc[0]=start;
+ tempbulletloc[1]=end;
+ glPushMatrix();
+ glLoadIdentity();
+ glScalef(1,1/skeleton.muscles[j].length,1);
+ glRotatef(skeleton.muscles[j].rotate3,0,1,0);
+ glRotatef(skeleton.muscles[j].rotate2-90,0,0,1);
+ glRotatef(skeleton.muscles[j].rotate1-90,0,1,0);
+ glTranslatef( (-(skeleton.muscles[j].parent1->position.x+skeleton.muscles[j].parent2->position.x)/2),
+ (-(skeleton.muscles[j].parent1->position.y+skeleton.muscles[j].parent2->position.y)/2),
+ (-(skeleton.muscles[j].parent1->position.z+skeleton.muscles[j].parent2->position.z)/2));
+
+ glTranslatef(tempbulletloc[0].x,tempbulletloc[0].y,tempbulletloc[0].z);
+ glGetFloatv(GL_MODELVIEW_MATRIX,M);
+ tempbulletloc[0].x=M[12];
+ tempbulletloc[0].y=M[13];
+ tempbulletloc[0].z=M[14];
+ glPopMatrix();
+ glPushMatrix();
+ glLoadIdentity();
+ glScalef(1,1/skeleton.muscles[j].length,1);
+ glRotatef(skeleton.muscles[j].rotate3,0,1,0);
+ glRotatef(skeleton.muscles[j].rotate2-90,0,0,1);
+ glRotatef(skeleton.muscles[j].rotate1-90,0,1,0);
+
+ glTranslatef( (-(skeleton.muscles[j].parent1->position.x+skeleton.muscles[j].parent2->position.x)/2),
+ (-(skeleton.muscles[j].parent1->position.y+skeleton.muscles[j].parent2->position.y)/2),
+ (-(skeleton.muscles[j].parent1->position.z+skeleton.muscles[j].parent2->position.z)/2));
+ glTranslatef(tempbulletloc[1].x,tempbulletloc[1].y,tempbulletloc[1].z);
+ glGetFloatv(GL_MODELVIEW_MATRIX,M);
+ tempbulletloc[1].x=M[12];
+ tempbulletloc[1].y=M[13];
+ tempbulletloc[1].z=M[14];
+ glPopMatrix();
+ collide=skeletonmodels[skeleton.muscles[j].parent1->modelnum].LineCheck(tempbulletloc[0],tempbulletloc[1],&collisionpoint);
+ if(collide!=-1)
+ {
+ glPushMatrix();
+ glLoadIdentity();
+ glTranslatef( (skeleton.muscles[j].parent1->position.x+skeleton.muscles[j].parent2->position.x)/2,
+ (skeleton.muscles[j].parent1->position.y+skeleton.muscles[j].parent2->position.y)/2,
+ (skeleton.muscles[j].parent1->position.z+skeleton.muscles[j].parent2->position.z)/2);
+ glRotatef(-skeleton.muscles[j].rotate1+90,0,1,0);
+ glRotatef(-skeleton.muscles[j].rotate2+90,0,0,1);
+ glRotatef(-skeleton.muscles[j].rotate3,0,1,0);
+ glScalef(1,findDistance(skeleton.muscles[j].parent1->position,skeleton.muscles[j].parent2->position),1);
+ glTranslatef(collisionpoint.x,collisionpoint.y,collisionpoint.z);
+ glGetFloatv(GL_MODELVIEW_MATRIX,M);
+ collisionpoint.x=M[12];
+ collisionpoint.y=M[13];
+ collisionpoint.z=M[14];
+ glPopMatrix();
+ hitstruct.collision=1;
+ hitstruct.hitlocation=collisionpoint;
+ hitstruct.joint1=skeleton.muscles[j].parent1;
+ hitstruct.joint2=skeleton.muscles[j].parent2;
+ }
+ }
+ }
+ }
+ if(skeleton.free<1){
+ if(playerrotation)hitstruct.hitlocation=DoRotation(hitstruct.hitlocation,0,playerrotation,0);
+ hitstruct.hitlocation=hitstruct.hitlocation+playercoords;
+ }
+ return hitstruct;
+}
+
+extern float camerashake;
+extern int cycle;
+void Person::DoAnimations(int who){
+
+ if(target>1&&!skeleton.free){
+ //Footstep sounds
+ if(who==0&&slomo==0&&(targetanimation==joganim||targetanimation==walkanim)&&(targetframe==0||targetframe==8)&&visions==0&&(onground||abs(velocity.y)<1)){
+ int whichsound;
+ float gLoc[3];
+ gLoc[0]=playercoords.x/soundscalefactor;
+ gLoc[1]=playercoords.y/soundscalefactor;
+ gLoc[2]=playercoords.z/soundscalefactor;
+ whichsound=footstepsound+abs(Random())%5;
+ alSourcefv(gSourceID[whichsound], AL_POSITION, gLoc);
+ alSourcePlay(gSourceID[whichsound]);
+ }
+ if(targetanimation==zombieeatanim&&(targetframe==3)){
+ int whichsound;
+ float gLoc[3];
+ XYZ soundpoint=(DoRotation(skeleton.joints[skeleton.jointlabels[head]].position,0,playerrotation,0)+playercoords);
+ gLoc[0]=soundpoint.x/soundscalefactor;
+ gLoc[1]=soundpoint.y/soundscalefactor;
+ gLoc[2]=soundpoint.z/soundscalefactor;
+ alSourcefv(gSourceID[bodyhitsound], AL_POSITION, gLoc);
+ alSourcePlay(gSourceID[bodyhitsound]);
+ bleeding=1;
+ bleeddelay=1;
+ bjoint1=&skeleton.joints[skeleton.jointlabels[head]];
+ bjoint2=&skeleton.joints[skeleton.jointlabels[neck]];
+ }
+ targetframe=currentframe;
+ currentanimation=targetanimation;
+ if(!backwardsanim){targetframe++;
+ if(targetframe>animation[currentanimation].numframes-1)targetframe=0;}
+ if(backwardsanim){targetframe--;
+ if(targetframe<0)targetframe=animation[currentanimation].numframes-1;}
+ target=0;
+ if((currentanimation==getupfrontanim||currentanimation==getupbackanim)&&targetframe==0){
+ targetanimation=idleanim;
+ }
+ if(targetanimation==diveanim&&currentanimation==diveanim&&targetframe==0){
+ targetanimation=getupfrontanim;
+ float gLoc[3];
+ XYZ soundpoint=(DoRotation(skeleton.joints[skeleton.jointlabels[head]].position,0,playerrotation,0)+playercoords);
+ gLoc[0]=soundpoint.x/soundscalefactor;
+ gLoc[1]=soundpoint.y/soundscalefactor;
+ gLoc[2]=soundpoint.z/soundscalefactor;
+ alSourcefv(gSourceID[bodywhacksound], AL_POSITION, gLoc);
+ alSourcePlay(gSourceID[bodywhacksound]);
+ }
+ if(currentanimation==throwanim&&targetframe==0){
+ targetanimation=idleanim;
+ }
+ if(currentanimation==thrownanim&&targetframe==0){
+ skeleton.offset=0;
+ skeleton.free=1;
+ longdead=1;
+ for(int j=0;j<skeleton.num_joints;j++){
+ skeleton.joints[j].position+=skeleton.joints[j].offset;
+ skeleton.joints[j].position=DoRotation(skeleton.joints[j].position,0,playerrotation,0);
+ skeleton.joints[j].position+=playercoords;
+ skeleton.joints[j].realoldposition=skeleton.joints[j].position;
+ skeleton.joints[j].velocity=DoRotation(skeleton.joints[j].velocity,0,playerrotation,0);
+ }
+ }
+ }
+
+ if(!skeleton.free){
+ if(currentanimation!=lyinganim){
+ if(animation[targetanimation].speed[currentframe]>animation[currentanimation].speed[currentframe])
+ target+=multiplier*animation[targetanimation].speed[currentframe]*speed;
+ if(animation[targetanimation].speed[currentframe]<=animation[currentanimation].speed[currentframe])
+ target+=multiplier*animation[currentanimation].speed[currentframe]*speed;
+ }
+ if(currentanimation==lyinganim){
+ target+=multiplier*animation[targetanimation].speed[targetframe]*speed;
+ }
+ if(((currentanimation==crouchanim)&&(targetanimation!=crouchanim))||((currentanimation!=crouchanim)&&(targetanimation==crouchanim)))target+=multiplier*animation[crouchanim].speed[0]*2;
+ if(currentanimation==idleanim&&targetanimation==idleanim)target-=multiplier*animation[idleanim].speed[0]/2;
+
+ if(target>1)currentframe=targetframe;
+
+ for(int i=0;i<skeleton.num_joints;i++){
+ if(currentanimation!=lyinganim){
+ skeleton.joints[i].velocity=((animation[currentanimation].position[i][currentframe]*(1-target)+animation[targetanimation].position[i][targetframe]*(target))-(skeleton.joints[i].position))/multiplier;
+ skeleton.joints[i].position=animation[currentanimation].position[i][currentframe]*(1-target)+animation[targetanimation].position[i][targetframe]*(target);
+ if(skeleton.joints[i].hasparent&&skeleton.joints[i].visible)
+ {
+ skeleton.joints[i].rotate1=animation[currentanimation].rotate1[i][currentframe]*(1-target)+animation[targetanimation].rotate1[i][targetframe]*(target);
+ skeleton.joints[i].rotate2=animation[currentanimation].rotate2[i][currentframe]*(1-target)+animation[targetanimation].rotate2[i][targetframe]*(target);
+ skeleton.joints[i].rotate3=animation[currentanimation].rotate3[i][currentframe]*(1-target)+animation[targetanimation].rotate3[i][targetframe]*(target);
+ }
+ if(skeleton.muscles[i].visible)
+ {
+ skeleton.muscles[i].rotate1=animation[currentanimation].mrotate1[i][currentframe]*(1-target)+animation[targetanimation].mrotate1[i][targetframe]*(target);
+ skeleton.muscles[i].rotate2=animation[currentanimation].mrotate2[i][currentframe]*(1-target)+animation[targetanimation].mrotate2[i][targetframe]*(target);
+ skeleton.muscles[i].rotate3=animation[currentanimation].mrotate3[i][currentframe]*(1-target)+animation[targetanimation].mrotate3[i][targetframe]*(target);
+ }
+ }
+ if(currentanimation==lyinganim){
+ skeleton.joints[i].velocity=((tempanimation.position[i][0]*(1-target)+animation[targetanimation].position[i][targetframe]*(target))-(skeleton.joints[i].position))/multiplier;
+ skeleton.joints[i].position=tempanimation.position[i][0]*(1-target)+animation[targetanimation].position[i][targetframe]*(target);
+ }
+ }
+ }
+
+ //Look up+down
+ if(!skeleton.free&&(whichgun!=nogun||who==0)&&health==100&&currentanimation!=lyinganim&&currentanimation!=getupfrontanim&&currentanimation!=getupbackanim&&currentanimation!=diveanim&&targetanimation!=diveanim&&targetanimation!=throwanim&&targetanimation!=thrownanim){
+ XYZ facing;
+ XYZ facingdown;
+ XYZ facinghalf;
+ XYZ facingright;
+ int oldanimation=currentanimation;
+ if(who==0){
+ playerrotation2=camera.rotation2;
+ //Facing
+ facing=0;
+ facing.z=1;
+
+ facinghalf=DoRotation(facing,playerrotation2/2,0,0);
+ facinghalf=DoRotation(facinghalf,0,-7,0);
+ facing=DoRotation(facing,playerrotation2,0,0);
+ facingright=DoRotation(facing,0,-90,0);
+ facingdown=DoRotation(facing,90,0,0);
+ }
+ if(who!=0){
+ //Facing
+ facing=0;
+ facing.z=1;
+
+ facinghalf=DoRotation(facing,playerrotation2/2,0,0);
+ facinghalf=DoRotation(facinghalf,0,-7,0);
+ facing=DoRotation(facing,playerrotation2,0,0);
+ facingright=DoRotation(facing,0,-90,0);
+ facingdown=DoRotation(facing,90,0,0);
+ }
+ XYZ rotatearound;
+ XYZ oldpos;
+ if(whichgun==sniperrifle){
+ for(int i=0;i<skeleton.num_joints;i++){
+ if(skeleton.joints[i].label!=righthand&&skeleton.joints[i].label!=rightelbow&&skeleton.joints[i].label!=rightwrist&&skeleton.joints[i].label!=lefthand&&skeleton.joints[i].label!=leftelbow&&skeleton.joints[i].label!=leftwrist){
+ }else{
+ skeleton.joints[i].position=animation[rifleholdanim].position[i][0];
+ if(currentanimation==crouchanim||targetanimation==crouchanim)skeleton.joints[i].position-=(animation[idleanim].position[skeleton.jointlabels[neck]][0]-skeleton.joints[skeleton.jointlabels[neck]].position);
+ }
+ }
+ }
+ if(whichgun==shotgun){
+ for(int i=0;i<skeleton.num_joints;i++){
+ if(skeleton.joints[i].label!=righthand&&skeleton.joints[i].label!=rightelbow&&skeleton.joints[i].label!=rightwrist&&skeleton.joints[i].label!=lefthand&&skeleton.joints[i].label!=leftelbow&&skeleton.joints[i].label!=leftwrist){
+ }else{
+ skeleton.joints[i].position=animation[rifleholdanim].position[i][0];
+ if(currentanimation==crouchanim||targetanimation==crouchanim)skeleton.joints[i].position-=(animation[idleanim].position[skeleton.jointlabels[neck]][0]-skeleton.joints[skeleton.jointlabels[neck]].position);
+ }
+ }
+ }
+ if(whichgun==assaultrifle){
+ for(int i=0;i<skeleton.num_joints;i++){
+ if(skeleton.joints[i].label!=righthand&&skeleton.joints[i].label!=rightelbow&&skeleton.joints[i].label!=rightwrist&&skeleton.joints[i].label!=lefthand&&skeleton.joints[i].label!=leftelbow&&skeleton.joints[i].label!=leftwrist){
+ }else{
+ skeleton.joints[i].position=animation[rifleholdanim].position[i][0];
+ if(currentanimation==crouchanim||targetanimation==crouchanim)skeleton.joints[i].position-=(animation[idleanim].position[skeleton.jointlabels[neck]][0]-skeleton.joints[skeleton.jointlabels[neck]].position);
+ }
+ }
+ }
+ if((aiming||aimamount>0||whichgun==grenade)&&whichgun!=nogun){
+ if(aiming&&targetanimation!=joganim){
+ if(aimamount<1)aimamount+=multiplier*4;
+ if(aimamount>1)aimamount=1;
+ }
+ if(!aiming||targetanimation==joganim){
+ if(aimamount>0)aimamount-=multiplier*4;
+ if(aimamount<0)aimamount=0;
+ }
+ if(grenphase==1){
+ if(grenamount<1)grenamount+=multiplier*4;
+ if(grenamount>1)grenamount=1;
+ }
+ if(grenphase==0){
+ if(grenamount>0)grenamount-=multiplier*4;
+ if(grenamount<0)grenamount=0;
+ }
+ rotatearound=skeleton.joints[skeleton.jointlabels[neck]].position;
+ for(int i=0;i<skeleton.num_joints;i++){
+ if(skeleton.joints[i].label!=righthand&&skeleton.joints[i].label!=rightelbow&&skeleton.joints[i].label!=rightwrist&&skeleton.joints[i].label!=lefthand&&skeleton.joints[i].label!=leftelbow&&skeleton.joints[i].label!=leftwrist){
+ }else{
+ if(whichgun==sniperrifle){
+ oldpos=skeleton.joints[i].position;
+ skeleton.joints[i].position=animation[rifleaimanim].position[i][0];
+ if(currentanimation==crouchanim||targetanimation==crouchanim){
+ skeleton.joints[i].position-=(animation[idleanim].position[skeleton.jointlabels[neck]][0]-skeleton.joints[skeleton.jointlabels[neck]].position);
+ }
+ skeleton.joints[i].position+=facingright*0.1;
+ skeleton.joints[i].position=rotatearound+DoRotation(skeleton.joints[i].position-rotatearound,(playerrotation2/2-10)*aimamount,0,0);
+ skeleton.joints[i].position=skeleton.joints[i].position*(aimamount)+oldpos*(1-aimamount);
+ }
+ if(whichgun==shotgun){
+ oldpos=skeleton.joints[i].position;
+ skeleton.joints[i].position=animation[assaultrifleaimanim].position[i][0];
+ if(currentanimation==crouchanim||targetanimation==crouchanim)skeleton.joints[i].position-=(animation[idleanim].position[skeleton.jointlabels[neck]][0]-skeleton.joints[skeleton.jointlabels[neck]].position);
+ skeleton.joints[i].position=rotatearound+DoRotation(skeleton.joints[i].position-rotatearound,(playerrotation2/2)*aimamount,0,0);
+ if(currentanimation==crouchanim||targetanimation==crouchanim)skeleton.joints[i].position+=facingdown*.2;
+ else skeleton.joints[i].position-=facingdown*.02;
+ if(skeleton.joints[i].label==righthand)skeleton.joints[i].position=skeleton.joints[skeleton.jointlabels[lefthand]].position-facinghalf*2;
+ skeleton.joints[i].position=skeleton.joints[i].position*(aimamount)+oldpos*(1-aimamount);
+ }
+ if(whichgun==assaultrifle){
+ oldpos=skeleton.joints[i].position;
+ skeleton.joints[i].position=animation[assaultrifleaimanim].position[i][0];
+ if(currentanimation==crouchanim||targetanimation==crouchanim)skeleton.joints[i].position-=(animation[idleanim].position[skeleton.jointlabels[neck]][0]-skeleton.joints[skeleton.jointlabels[neck]].position);
+ skeleton.joints[i].position=rotatearound+DoRotation(skeleton.joints[i].position-rotatearound,(playerrotation2/2)*aimamount,0,0);
+ if(currentanimation==crouchanim||targetanimation==crouchanim)skeleton.joints[i].position+=facingdown*.2;
+ else skeleton.joints[i].position-=facingdown*.02;
+ if(skeleton.joints[i].label==righthand)skeleton.joints[i].position=skeleton.joints[skeleton.jointlabels[lefthand]].position-facinghalf*2;
+ skeleton.joints[i].position=skeleton.joints[i].position*(aimamount)+oldpos*(1-aimamount);
+ }
+ if(whichgun==handgun1){
+ oldpos=skeleton.joints[i].position;
+ skeleton.joints[i].position=animation[pistolaimanim].position[i][0];
+ if(currentanimation==crouchanim||targetanimation==crouchanim)skeleton.joints[i].position-=(animation[idleanim].position[skeleton.jointlabels[neck]][0]-skeleton.joints[skeleton.jointlabels[neck]].position);
+ skeleton.joints[i].position=rotatearound+DoRotation(skeleton.joints[i].position-rotatearound,(playerrotation2/2)*aimamount,0,0);
+ if(currentanimation==crouchanim||targetanimation==crouchanim){skeleton.joints[i].position+=facingright*.15;skeleton.joints[i].position+=facingdown*.3;}
+ else skeleton.joints[i].position-=facingdown*.1;
+ skeleton.joints[i].position=skeleton.joints[i].position*(aimamount)+oldpos*(1-aimamount);
+ }
+ if(whichgun==handgun2){
+ oldpos=skeleton.joints[i].position;
+ skeleton.joints[i].position=animation[pistolaimanim].position[i][0];
+ if(currentanimation==crouchanim||targetanimation==crouchanim)skeleton.joints[i].position-=(animation[idleanim].position[skeleton.jointlabels[neck]][0]-skeleton.joints[skeleton.jointlabels[neck]].position);
+ skeleton.joints[i].position=rotatearound+DoRotation(skeleton.joints[i].position-rotatearound,(playerrotation2/2)*aimamount,0,0);
+ if(currentanimation==crouchanim||targetanimation==crouchanim){skeleton.joints[i].position+=facingright*.15;skeleton.joints[i].position+=facingdown*.3;}
+ else skeleton.joints[i].position-=facingdown*.1;
+ skeleton.joints[i].position=skeleton.joints[i].position*(aimamount)+oldpos*(1-aimamount);
+ }
+ if(whichgun==grenade){
+ aimamount=1;
+ oldpos=skeleton.joints[i].position;
+ skeleton.joints[i].position=animation[grenadeaimanim].position[i][0];
+ if(currentanimation==crouchanim||targetanimation==crouchanim)skeleton.joints[i].position-=(animation[idleanim].position[skeleton.jointlabels[neck]][0]-skeleton.joints[skeleton.jointlabels[neck]].position);
+ skeleton.joints[i].position=skeleton.joints[i].position*(aimamount)+oldpos*(1-aimamount);
+ }
+ if(whichgun==grenade&&grenamount>0){
+ oldpos=skeleton.joints[i].position;
+ skeleton.joints[i].position=animation[grenadechargeanim].position[i][0];
+ if(currentanimation==crouchanim||targetanimation==crouchanim)skeleton.joints[i].position-=(animation[idleanim].position[skeleton.jointlabels[neck]][0]-skeleton.joints[skeleton.jointlabels[neck]].position);
+ skeleton.joints[i].position=skeleton.joints[i].position*(grenamount)+oldpos*(1-grenamount);
+ }
+ if(thirdperson||who!=0)skeleton.joints[i].position+=facingdown*.4;
+ if(currentanimation!=crouchanim)skeleton.joints[i].position-=facinghalf*recoil*.35;
+ if(currentanimation==crouchanim)skeleton.joints[i].position-=facinghalf*recoil*.1;
+ }
+ }
+ }
+ //Whack
+ if(attackframe>-1&&whichgun!=grenade){
+ for(int i=0;i<skeleton.num_joints;i++){
+ if(!skeleton.joints[i].lower){
+ if(attackframe==animation[riflehitanim].numframes)skeleton.joints[i].position=skeleton.joints[i].position*(attacktarget)+animation[riflehitanim].position[i][attackframe-1]*(1-attacktarget);
+ if(attackframe>0&&attackframe<animation[riflehitanim].numframes)skeleton.joints[i].position=animation[riflehitanim].position[i][attackframe-1]*(1-attacktarget)+animation[riflehitanim].position[i][attackframe]*(attacktarget);
+ if(attackframe==0)skeleton.joints[i].position=skeleton.joints[i].position*(1-attacktarget)+animation[riflehitanim].position[i][attackframe]*(attacktarget);
+ }
+ }
+ if(attackframe==0)attacktarget+=multiplier*animation[riflehitanim].speed[attackframe]*2;
+ if(attackframe>0)attacktarget+=multiplier*animation[riflehitanim].speed[attackframe-1]*2;
+ if(attacktarget>1){
+ attacktarget=0;
+ attackframe++;
+ if(attackframe>animation[riflehitanim].numframes)attackframe=-1;
+ }
+ }
+ //Throw grenade
+ if(attackframe>-1&&whichgun==grenade&&ammo>0){
+ for(int i=0;i<skeleton.num_joints;i++){
+ if(!skeleton.joints[i].lower){
+ if(attackframe==animation[grenadethrowanim].numframes)skeleton.joints[i].position=skeleton.joints[i].position*(attacktarget)+animation[grenadethrowanim].position[i][attackframe-1]*(1-attacktarget);
+ if(attackframe>0&&attackframe<animation[grenadethrowanim].numframes)skeleton.joints[i].position=animation[grenadethrowanim].position[i][attackframe-1]*(1-attacktarget)+animation[grenadethrowanim].position[i][attackframe]*(attacktarget);
+ if(attackframe==0)skeleton.joints[i].position=skeleton.joints[i].position*(1-attacktarget)+animation[grenadethrowanim].position[i][attackframe]*(attacktarget);
+ }
+ }
+ if(attackframe==0)attacktarget+=multiplier*animation[grenadethrowanim].speed[attackframe]*2;
+ if(attackframe>0)attacktarget+=multiplier*animation[grenadethrowanim].speed[attackframe-1]*2;
+ if(attacktarget>1){
+ attacktarget=0;
+ attackframe++;
+ if(attackframe>animation[grenadethrowanim].numframes){
+ attackframe=-1;
+ }
+ if(attackframe==animation[grenadethrowanim].numframes-1&&ammo>0){
+ ammo=-1;
+ sprites.MakeSprite(grenadesprite, 1, 1, 1, 1, DoRotation(skeleton.joints[skeleton.jointlabels[righthand]].position,0,playerrotation,0)+playercoords, DoRotation(facing,0,playerrotation,0)*30+velocity, 1);
+ sprites.MakeSprite(spoonsprite, 1, 1, 1, 1, DoRotation(skeleton.joints[skeleton.jointlabels[righthand]].position,0,playerrotation,0)+playercoords, DoRotation(facing,0,playerrotation,0)*10+velocity, 1);
+ sprites.MakeSprite(pinsprite, 1, 1, 1, 1, DoRotation(skeleton.joints[skeleton.jointlabels[lefthand]].position,0,playerrotation,0)+playercoords, facing*.1+velocity, 1);
+ XYZ soundsource=DoRotation(skeleton.joints[skeleton.jointlabels[righthand]].position,0,playerrotation,0)+playercoords;
+ float gLoc[3];
+ gLoc[0]=soundsource.x/soundscalefactor;
+ gLoc[1]=soundsource.y/soundscalefactor;
+ gLoc[2]=soundsource.z/soundscalefactor;
+ alSourcefv(gSourceID[grenadethrowsound], AL_POSITION, gLoc);
+ alSourcePlay(gSourceID[grenadethrowsound]);
+ }
+ }
+ }
+
+ rotatearound=skeleton.joints[skeleton.jointlabels[abdomen]].position;
+ if(who==0)
+ for(int i=0;i<skeleton.num_joints;i++){
+ if(skeleton.joints[i].lower==0)
+ skeleton.joints[i].position=rotatearound+DoRotation(skeleton.joints[i].position-rotatearound,playerrotation2/2,0,0);
+ }
+ if(who==0)
+ for(int i=0;i<skeleton.num_joints;i++){
+ if(skeleton.joints[i].lower==1&&skeleton.joints[i].label!=groin)
+ skeleton.joints[i].position=DoRotation(skeleton.joints[i].position,0,playerlowrotation-playerrotation,0);
+ }
+ //head facing
+ if(who==0){
+ rotatearound=skeleton.joints[skeleton.jointlabels[neck]].position;
+ skeleton.joints[skeleton.jointlabels[head]].position=rotatearound+DoRotation(skeleton.joints[skeleton.jointlabels[head]].position-rotatearound,playerrotation2/2,0,0);
+ }
+
+ skeleton.DoConstraints();
+
+ //Reload
+ if(whichgun!=nogun&&whichgun!=knife){
+ if(reloading>0){
+ aiming=0;
+ reloading-=multiplier;
+ }
+ if(ammo<0&&reloads[whichgun]>0&&reloading<=0){
+ if(whichgun!=grenade){
+ float gLoc[3];
+ ALint tempint;
+ gLoc[0]=playercoords.x/soundscalefactor;
+ gLoc[1]=playercoords.y/soundscalefactor;
+ gLoc[2]=playercoords.z/soundscalefactor;
+ alGetSourcei(gSourceID[reloadsound], AL_SOURCE_STATE, &tempint);
+ if (tempint != AL_PLAYING){
+ alSourcefv(gSourceID[reloadsound], AL_POSITION, gLoc);
+ alSourcePlay(gSourceID[reloadsound]);
+ }
+ }
+ reloading=3;
+ aiming=0;
+ if(whichgun==sniperrifle)ammo=5;
+ if(whichgun==assaultrifle)ammo=25;
+ if(whichgun==handgun1)ammo=12;
+ if(whichgun==handgun2)ammo=16;
+ if(whichgun==grenade){ammo=1; reloading=1;}
+ if(whichgun==shotgun)ammo=6;
+ reloads[whichgun]--;
+ }
+ if(reloads[whichgun]==0&&whichgun==grenade&&ammo<=0){
+ whichgun=nogun;
+ }
+ if(reloading<0){
+ reloading=0;
+ aiming=1;
+ }
+ }
+ }
+}
+
+void Person::DoAnimationslite(int who){
+
+ int oldanimation=currentanimation;
+ if(target>1&&!skeleton.free){
+ //Footstep sounds
+ if(who==0&&(targetanimation==joganim||targetanimation==walkanim)&&(targetframe==0||targetframe==8)&&visions==0&&(onground||abs(velocity.y)<1)){
+ int whichsound;
+ float gLoc[3];
+ gLoc[0]=playercoords.x/soundscalefactor;
+ gLoc[1]=playercoords.y/soundscalefactor;
+ gLoc[2]=playercoords.z/soundscalefactor;
+ whichsound=footstepsound+abs(Random())%5;
+ alSourcefv(gSourceID[whichsound], AL_POSITION, gLoc);
+ alSourcePlay(gSourceID[whichsound]);
+ }
+ if(targetanimation==zombieeatanim&&(targetframe==3)){
+ int whichsound;
+ float gLoc[3];
+ XYZ soundpoint=(DoRotation(skeleton.joints[skeleton.jointlabels[head]].position,0,playerrotation,0)+playercoords);
+ gLoc[0]=soundpoint.x/soundscalefactor;
+ gLoc[1]=soundpoint.y/soundscalefactor;
+ gLoc[2]=soundpoint.z/soundscalefactor;
+ alSourcefv(gSourceID[bodyhitsound], AL_POSITION, gLoc);
+ alSourcePlay(gSourceID[bodyhitsound]);
+ bleeding=1;
+ bleeddelay=1;
+ bjoint1=&skeleton.joints[skeleton.jointlabels[head]];
+ bjoint2=&skeleton.joints[skeleton.jointlabels[neck]];
+ }
+ targetframe=currentframe;
+ currentanimation=targetanimation;
+ if(!backwardsanim){targetframe++;
+ if(targetframe>animation[currentanimation].numframes-1)targetframe=0;}
+ if(backwardsanim){targetframe--;
+ if(targetframe<0)targetframe=animation[currentanimation].numframes-1;}
+ target=0;
+ if((currentanimation==getupfrontanim||currentanimation==getupbackanim)&&targetframe==0){
+ targetanimation=idleanim;
+ }
+ }
+
+ if(!skeleton.free){
+ if(currentanimation!=lyinganim){
+ if(animation[targetanimation].speed[currentframe]>animation[currentanimation].speed[currentframe])
+ target+=multiplier*animation[targetanimation].speed[currentframe]*speed;
+ if(animation[targetanimation].speed[currentframe]<=animation[currentanimation].speed[currentframe])
+ target+=multiplier*animation[currentanimation].speed[currentframe]*speed;
+ }
+ if(currentanimation==lyinganim){
+ target+=multiplier*animation[targetanimation].speed[targetframe]*speed;
+ }
+ if(((currentanimation==crouchanim)&&(targetanimation!=crouchanim))||((currentanimation!=crouchanim)&&(targetanimation==crouchanim)))target+=multiplier*animation[crouchanim].speed[0]*2;
+ if(currentanimation==idleanim&&targetanimation==idleanim)target-=multiplier*animation[idleanim].speed[0]/2;
+
+ if(target>1)currentframe=targetframe;
+ }
+}
+
+void Person::DoStuff(int who){
+ int moveanim;
+
+ if((targetanimation!=idleanim&&targetanimation!=crouchanim)||visions==1)playerlowrotation=playerrotation;
+ if(targetanimation!=crouchanim&&currentanimation!=crouchanim){
+ if(playerrotation>playerlowrotation+50){playerlowrotation=playerrotation-50; targetanimation=walkanim; targetframe=0; target=0;}
+ if(playerrotation<playerlowrotation-50){playerlowrotation=playerrotation+50; targetanimation=walkanim; targetframe=0; target=0;}
+ }
+ if(targetanimation==crouchanim||currentanimation==crouchanim){
+ if(playerrotation>playerlowrotation+70){playerrotation=playerlowrotation+70;}
+ if(playerrotation<playerlowrotation-70){playerrotation=playerlowrotation-70;}
+ }
+ if(who==0)camera.rotation=180-playerrotation;
+
+ if(who!=0&&visions==0){
+ if(targetanimation!=walkanim&&targetanimation!=zombiewalkanim)speed=1.0*speedmult;
+ if(targetanimation==walkanim||targetanimation==zombiewalkanim)speed=1.8*speedmult;
+ playerlowrotation=playerrotation;
+ }
+
+ //Do controls
+ if(who==0&&targetanimation!=diveanim&&targetanimation!=throwanim&&targetanimation!=thrownanim&&currentanimation!=diveanim&&currentanimation!=getupfrontanim){
+ backwardsanim=0;
+ if(visions==1)speed=40;
+ if(visions==0&&targetanimation==joganim)speed=2.2;
+ if(visions==0&&targetanimation!=joganim)speed=1.3;
+ if(visions==0&&targetanimation==walkanim)speed=2.5;
+ unsigned char theKeyMap[16];
+ GetKeys( ( unsigned long * )theKeyMap );
+
+ if(IsKeyDown( theKeyMap, MAC_SHIFT_KEY )||visions==1){
+ moveanim=joganim;
+ }else{
+ moveanim=walkanim;
+ }
+ if(IsKeyDown( theKeyMap, MAC_CONTROL_KEY )&&currentanimation==idleanim&&targetanimation==idleanim){
+ targetanimation=crouchanim;
+ target=0;
+ }
+ if(!IsKeyDown( theKeyMap, MAC_CONTROL_KEY )&&currentanimation==crouchanim&&targetanimation==crouchanim){
+ targetanimation=idleanim;
+ target=0;
+ }
+ if((onground||(who==0&&visions==1))&&currentanimation!=crouchanim){
+ if ( IsKeyDown( theKeyMap, forwardskey )&&!( IsKeyDown( theKeyMap, backwardskey ))){
+ if(targetanimation!=moveanim)targetframe=0;
+ targetanimation=moveanim;
+ }
+ if ( IsKeyDown( theKeyMap, rightkey )&&!( IsKeyDown( theKeyMap, leftkey ))){
+ if(targetanimation!=moveanim)targetframe=0;
+ targetanimation=moveanim;
+ playerlowrotation-=90;
+ if(IsKeyDown( theKeyMap, forwardskey ))playerlowrotation+=45;
+ if(IsKeyDown( theKeyMap, backwardskey ))playerlowrotation-=235;
+ }
+ if ( IsKeyDown( theKeyMap, leftkey )&&!( IsKeyDown( theKeyMap, rightkey ))){
+ if(targetanimation!=moveanim)targetframe=0;
+ targetanimation=moveanim;
+ playerlowrotation+=90;
+ if(IsKeyDown( theKeyMap, forwardskey ))playerlowrotation-=45;
+ if(IsKeyDown( theKeyMap, backwardskey ))playerlowrotation+=235;
+ }
+ if ( IsKeyDown( theKeyMap, backwardskey )){
+ if(targetanimation!=moveanim)targetframe=0;
+ targetanimation=moveanim;
+ backwardsanim=1;
+ }
+ }
+ //air control
+ if(!onground){
+ float oldplayerrotation=playerrotation;
+ if ( IsKeyDown( theKeyMap, forwardskey )&&!( IsKeyDown( theKeyMap, backwardskey ))){
+ facing=0;
+ facing.z=1;
+ facing=DoRotation(facing,0,playerrotation,0);
+ velocity=velocity+facing*multiplier*4;
+ }
+ if ( IsKeyDown( theKeyMap, rightkey )&&!( IsKeyDown( theKeyMap, leftkey ))){
+ playerrotation-=90;
+ if(IsKeyDown( theKeyMap, forwardskey ))playerrotation+=45;
+ if(IsKeyDown( theKeyMap, backwardskey ))playerrotation-=45;
+ facing=0;
+ facing.z=1;
+ facing=DoRotation(facing,0,playerrotation,0);
+ velocity=velocity+facing*multiplier*4;
+ }
+ if ( IsKeyDown( theKeyMap, leftkey )&&!( IsKeyDown( theKeyMap, rightkey ))){
+ playerrotation+=90;
+ if(IsKeyDown( theKeyMap, forwardskey ))playerrotation-=45;
+ if(IsKeyDown( theKeyMap, backwardskey ))playerrotation+=45;
+ facing=0;
+ facing.z=1;
+ facing=DoRotation(facing,0,playerrotation,0);
+ velocity=velocity+facing*multiplier*4;
+ }
+ if ( IsKeyDown( theKeyMap, backwardskey )&&!IsKeyDown( theKeyMap, forwardskey )&&!IsKeyDown( theKeyMap, leftkey )&&!IsKeyDown( theKeyMap, rightkey )){
+ playerrotation+=180;
+ facing=0;
+ facing.z=1;
+ facing=DoRotation(facing,0,playerrotation,0);
+ velocity=velocity+facing*multiplier*4;
+ }
+ playerrotation=oldplayerrotation;
+ }
+ if(!IsKeyDown( theKeyMap, forwardskey )&&!IsKeyDown( theKeyMap, leftkey )&&!IsKeyDown( theKeyMap, rightkey )&&!IsKeyDown( theKeyMap, backwardskey )&&(targetanimation==joganim||targetanimation==walkanim)){
+ if(!(targetanimation==walkanim&&(targetframe==0||targetframe==2))){
+ targetanimation=idleanim;
+ targetframe=0;
+ target=0;
+ }
+ }
+ }
+
+
+ facing=0;
+ facing.z=1;
+
+ facing=DoRotation(facing,0,playerlowrotation,0);
+ if(backwardsanim)facing*=-1;
+
+ if(onground){
+ velocity=0;
+ }
+ if(((currentanimation==joganim||currentanimation==zombiejoganim||currentanimation==diveanim)&&onground)||(who==0&&visions==1&&((currentanimation==joganim||currentanimation==walkanim||currentanimation==diveanim)||(currentanimation==zombiejoganim||currentanimation==zombiewalkanim)))){
+ playercoords+=facing*multiplier*15*speed;
+ velocity.x=facing.x*15*speed;
+ velocity.z=facing.z*15*speed;
+ }
+ if((currentanimation==walkanim||currentanimation==zombiewalkanim)&&onground&&(who!=0||visions==0)){
+ playercoords+=facing*multiplier*4*speed;
+ velocity.x=facing.x*4*speed;
+ velocity.z=facing.z*4*speed;
+ }
+}
+
+void Person::FindRotationGun(XYZ start, XYZ target)
+{
+ XYZ temppoint1,temppoint2,tempforward;
+ float distance;
+
+ temppoint1=start;
+ temppoint2=target;
+ distance=findDistance(temppoint1,temppoint2);
+ gunrotate2=asin((temppoint1.y-temppoint2.y)/distance)*rad2deg;
+ temppoint1.y=0;
+ temppoint2.y=0;
+ gunrotate1=acos((temppoint1.z-temppoint2.z)/findDistance(temppoint1,temppoint2))*rad2deg;
+ if(temppoint1.x>temppoint2.x)gunrotate1=360-gunrotate1;
+ tempforward=target-start;
+ tempforward=DoRotation(tempforward,-90,0,0);
+ tempforward=DoRotation(tempforward,0,gunrotate1-90,0);
+ tempforward=DoRotation(tempforward,0,0,gunrotate2-90);
+ tempforward.y=0;
+ Normalise(&tempforward);
+ gunrotate3=acos(0-tempforward.z)*rad2deg;
+ if(0>tempforward.x)gunrotate3=360-gunrotate3;
+}
+
+extern Model skeletonmodels[10];
+extern Costume costume[2];
+int Person::DrawSkeleton(int who){
+ GLfloat M[16];
+ //Guns
+ if(whichgun==sniperrifle){
+ FindRotationGun(skeleton.joints[skeleton.jointlabels[righthand]].position,skeleton.joints[skeleton.jointlabels[lefthand]].position);
+ glPushMatrix();
+ glTranslatef( skeleton.joints[skeleton.jointlabels[righthand]].position.x,
+ skeleton.joints[skeleton.jointlabels[righthand]].position.y,
+ skeleton.joints[skeleton.jointlabels[righthand]].position.z);
+ glRotatef(-gunrotate1+90,0,1,0);
+ glRotatef(-gunrotate2+90,0,0,1);
+ glRotatef(-gunrotate3,0,1,0);
+ gunmodels[sniperriflemodel].draw();
+ glPopMatrix();
+ }
+
+ if(whichgun==shotgun){
+ FindRotationGun(skeleton.joints[skeleton.jointlabels[righthand]].position,skeleton.joints[skeleton.jointlabels[lefthand]].position);
+ glPushMatrix();
+ glTranslatef( skeleton.joints[skeleton.jointlabels[righthand]].position.x,
+ skeleton.joints[skeleton.jointlabels[righthand]].position.y,
+ skeleton.joints[skeleton.jointlabels[righthand]].position.z);
+ glRotatef(2,1,0,0);
+ glRotatef(-gunrotate1+90+1,0,1,0);
+ glRotatef(-gunrotate2+90,0,0,1);
+ glRotatef(-gunrotate3,0,1,0);
+ glTranslatef(0,-.4,0);
+ gunmodels[shotgunmodel].draw();
+ glPopMatrix();
+ }
+
+ if(whichgun==assaultrifle){
+ FindRotationGun(skeleton.joints[skeleton.jointlabels[righthand]].position,skeleton.joints[skeleton.jointlabels[lefthand]].position);
+ glPushMatrix();
+ glTranslatef( skeleton.joints[skeleton.jointlabels[righthand]].position.x,
+ skeleton.joints[skeleton.jointlabels[righthand]].position.y,
+ skeleton.joints[skeleton.jointlabels[righthand]].position.z);
+ glRotatef(-gunrotate1+90,0,1,0);
+ glRotatef(-gunrotate2+90,0,0,1);
+ glRotatef(-gunrotate3,0,1,0);
+ gunmodels[assaultriflemodel].draw();
+ glPopMatrix();
+ }
+
+ if(whichgun==handgun1){
+ if(!thirdperson&&who==0)FindRotationGun(skeleton.joints[skeleton.jointlabels[righthand]].position,(skeleton.joints[skeleton.jointlabels[head]].position*.65+skeleton.joints[skeleton.jointlabels[neck]].position*.35));
+ if(thirdperson||who!=0)FindRotationGun(skeleton.joints[skeleton.jointlabels[righthand]].position,(skeleton.joints[skeleton.jointlabels[head]].position*.35+skeleton.joints[skeleton.jointlabels[neck]].position*.65));
+ glPushMatrix();
+ glTranslatef( skeleton.joints[skeleton.jointlabels[righthand]].position.x,
+ skeleton.joints[skeleton.jointlabels[righthand]].position.y,
+ skeleton.joints[skeleton.jointlabels[righthand]].position.z);
+ glRotatef(-gunrotate1+90-1.5,0,1,0);
+ glRotatef(-gunrotate2+90,0,0,1);
+ glRotatef(-gunrotate3,0,1,0);
+ glTranslatef(0,0,.15);
+ gunmodels[handgunbasemodel].draw();
+ glTranslatef(0,-recoil*.3,0);
+ gunmodels[handgunslidemodel].draw();
+ glPopMatrix();
+ }
+
+ if(whichgun==handgun2){
+ if(!thirdperson&&who==0)FindRotationGun(skeleton.joints[skeleton.jointlabels[righthand]].position,(skeleton.joints[skeleton.jointlabels[head]].position*.65+skeleton.joints[skeleton.jointlabels[neck]].position*.35));
+ if(thirdperson||who!=0)FindRotationGun(skeleton.joints[skeleton.jointlabels[righthand]].position,(skeleton.joints[skeleton.jointlabels[head]].position*.35+skeleton.joints[skeleton.jointlabels[neck]].position*.65));
+ glPushMatrix();
+ glTranslatef( skeleton.joints[skeleton.jointlabels[righthand]].position.x,
+ skeleton.joints[skeleton.jointlabels[righthand]].position.y,
+ skeleton.joints[skeleton.jointlabels[righthand]].position.z);
+ glRotatef(-gunrotate1+90-1.5,0,1,0);
+ glRotatef(-gunrotate2+90,0,0,1);
+ glRotatef(-gunrotate3,0,1,0);
+ glTranslatef(0,0,.15);
+ gunmodels[handgun2basemodel].draw();
+ glTranslatef(0,-recoil*.3,0);
+ gunmodels[handgun2slidemodel].draw();
+ glPopMatrix();
+ }
+
+ if(whichgun==grenade){
+ glPushMatrix();
+ glTranslatef( skeleton.joints[skeleton.jointlabels[righthand]].position.x,
+ skeleton.joints[skeleton.jointlabels[righthand]].position.y,
+ skeleton.joints[skeleton.jointlabels[righthand]].position.z);
+ glRotatef(-90,1,0,0);
+ glTranslatef(0,0,.05);
+ if(reloading<=0){
+ gunmodels[grenadebasemodel].draw();
+ if(grenphase==0)gunmodels[grenadepinmodel].draw();
+ glTranslatef(0,0,.005);
+ gunmodels[grenadespoonmodel].draw();
+ }
+ glPopMatrix();
+ }
+
+ if(whichgun==grenade){
+ glPushMatrix();
+ glTranslatef( skeleton.joints[skeleton.jointlabels[lefthand]].position.x,
+ skeleton.joints[skeleton.jointlabels[lefthand]].position.y,
+ skeleton.joints[skeleton.jointlabels[lefthand]].position.z);
+ glRotatef(-90,1,0,0);
+ glTranslatef(0,0,-.15);
+ if(reloading<=0){
+ if(grenphase==1)gunmodels[grenadepinmodel].draw();
+ }
+ glPopMatrix();
+ }
+ if(!litup){
+ glDisable(GL_LIGHT1);
+ }
+ if(litup){
+ GLfloat LightAmbient[]= { 0,0,0, 1.0f};
+ GLfloat LightDiffuse[]= { 1,1,1, 1.0f };
+ XYZ lightpoint;
+ lightpoint=skeleton.joints[skeleton.jointlabels[lefthand]].position;
+ GLfloat LightPosition[]= {lightpoint.x,lightpoint.y,lightpoint.z,0};
+ glLightfv(GL_LIGHT1, GL_POSITION, LightPosition);
+ glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);
+ glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);
+ glEnable(GL_LIGHT1);
+
+ litup=0;
+ }
+
+ //Find forward vectors
+ if(who==0||skeleton.free!=0||skeleton.offset!=0||whichgun!=nogun||currentanimation==lyinganim||((currentanimation==getupfrontanim||currentanimation==getupbackanim)&&targetanimation==idleanim)){
+ if(!(skeleton.free==1&&longdead<=0)){
+ if(skeleton.offset&&skeleton.free<1){
+ XYZ normal;
+ skeleton.offset=0;
+ for(int i=0;i<skeleton.num_joints;i++){
+ skeleton.joints[i].oldposition=skeleton.joints[i].position;
+ skeleton.joints[i].position+=skeleton.joints[i].offset;
+ if(findLengthfast(skeleton.joints[i].offset)<multiplier*multiplier*25)skeleton.joints[i].offset=0;
+ else{
+ normal=skeleton.joints[i].offset;
+ Normalise(&normal);
+ skeleton.offset=1;
+ skeleton.joints[i].offset-=normal*multiplier*5;
+ }
+ }
+ skeleton.DoConstraints();
+ }
+ CrossProduct(skeleton.joints[skeleton.forwardjoints[1]].position-skeleton.joints[skeleton.forwardjoints[0]].position,skeleton.joints[skeleton.forwardjoints[2]].position-skeleton.joints[skeleton.forwardjoints[0]].position,&skeleton.forward);
+ Normalise(&skeleton.forward);
+
+ CrossProduct(skeleton.joints[skeleton.lowforwardjoints[1]].position-skeleton.joints[skeleton.lowforwardjoints[0]].position,skeleton.joints[skeleton.lowforwardjoints[2]].position-skeleton.joints[skeleton.lowforwardjoints[0]].position,&skeleton.lowforward);
+ Normalise(&skeleton.lowforward);
+
+ //Special forwards
+ skeleton.specialforward[0]=skeleton.forward;
+
+ skeleton.specialforward[1]=skeleton.joints[skeleton.jointlabels[rightshoulder]].position+skeleton.joints[skeleton.jointlabels[rightwrist]].position;
+ skeleton.specialforward[1]=skeleton.joints[skeleton.jointlabels[rightelbow]].position-skeleton.specialforward[1]/2;
+ skeleton.specialforward[1]+=skeleton.forward*.2;
+ Normalise(&skeleton.specialforward[1]);
+ skeleton.specialforward[2]=skeleton.joints[skeleton.jointlabels[leftshoulder]].position+skeleton.joints[skeleton.jointlabels[leftwrist]].position;
+ skeleton.specialforward[2]=skeleton.joints[skeleton.jointlabels[leftelbow]].position-skeleton.specialforward[2]/2;
+ skeleton.specialforward[2]+=skeleton.forward*.2;
+ Normalise(&skeleton.specialforward[2]);
+
+ if(who==0&&aimamount>0&&health==100&&whichgun!=nogun){
+ //Facing
+ XYZ facing;
+ XYZ facingdown;
+ //Facing
+ facing=0;
+ facing.z=1;
+
+ facing=DoRotation(facing,camera.rotation2,0,0);
+ facingdown=DoRotation(facing,90,0,0);
+ skeleton.specialforward[1]=skeleton.specialforward[1]*(1-aimamount)+facingdown*aimamount;
+ skeleton.specialforward[2]=skeleton.specialforward[2]*(1-aimamount)+facingdown*aimamount;
+ }
+
+ skeleton.specialforward[3]=skeleton.joints[skeleton.jointlabels[righthip]].position+skeleton.joints[skeleton.jointlabels[rightankle]].position;
+ skeleton.specialforward[3]=skeleton.specialforward[3]/2-skeleton.joints[skeleton.jointlabels[rightknee]].position;
+ skeleton.specialforward[3]+=skeleton.lowforward*.2;
+ Normalise(&skeleton.specialforward[3]);
+ skeleton.specialforward[4]=skeleton.joints[skeleton.jointlabels[lefthip]].position+skeleton.joints[skeleton.jointlabels[leftankle]].position;
+ skeleton.specialforward[4]=skeleton.specialforward[4]/2-skeleton.joints[skeleton.jointlabels[leftknee]].position;
+ skeleton.specialforward[4]+=skeleton.lowforward*.2;
+ Normalise(&skeleton.specialforward[4]);
+
+ //Find joint rotations
+ for(int i=0;i<skeleton.num_joints;i++){
+ if(skeleton.joints[i].hasparent&&skeleton.joints[i].visible)
+ {
+ skeleton.FindRotationJoint(i);
+ }
+ }
+ for(int i=0;i<skeleton.num_muscles;i++){
+ if(skeleton.muscles[i].visible)
+ {
+ skeleton.FindRotationMuscle(i);
+ }
+ }}}
+ for(int i=0;i<skeleton.num_joints;i++){
+ if(skeleton.joints[i].hasparent&&skeleton.joints[i].visible)
+ {
+ glPushMatrix();
+ glTranslatef( (skeleton.joints[i].position.x+skeleton.joints[i].parent->position.x)/2,
+ (skeleton.joints[i].position.y+skeleton.joints[i].parent->position.y)/2,
+ (skeleton.joints[i].position.z+skeleton.joints[i].parent->position.z)/2);
+ glRotatef(-skeleton.joints[i].rotate1+90,0,1,0);
+ glRotatef(-skeleton.joints[i].rotate2+90,0,0,1);
+ glRotatef(-skeleton.joints[i].rotate3,0,1,0);
+ if(skeleton.joints[i].modelnum==0&&(who!=0||thirdperson))skeletonmodels[skeleton.joints[i].modelnum].draw(costume[whichcostume].headcolor[0],costume[whichcostume].headcolor[1],costume[whichcostume].headcolor[2]);
+ if(skeleton.joints[i].modelnum==0&&(who==0&&thirdperson))skeletonmodels[9].draw();
+ if(skeleton.joints[i].modelnum==1&&(who!=0||thirdperson))skeletonmodels[skeleton.joints[i].modelnum].draw(costume[whichcostume].chestcolor[0],costume[whichcostume].chestcolor[1],costume[whichcostume].chestcolor[2]);
+ if(skeleton.joints[i].modelnum==2)skeletonmodels[skeleton.joints[i].modelnum].draw(costume[whichcostume].abdomencolor[0],costume[whichcostume].abdomencolor[1],costume[whichcostume].abdomencolor[2]);
+ if(skeleton.joints[i].modelnum==3)skeletonmodels[skeleton.joints[i].modelnum].draw(costume[whichcostume].upperarmcolor[0],costume[whichcostume].upperarmcolor[1],costume[whichcostume].upperarmcolor[2]);
+ if(skeleton.joints[i].modelnum==4)skeletonmodels[skeleton.joints[i].modelnum].draw(costume[whichcostume].lowerarmcolor[0],costume[whichcostume].lowerarmcolor[1],costume[whichcostume].lowerarmcolor[2]);
+ if(skeleton.joints[i].modelnum==5)skeletonmodels[skeleton.joints[i].modelnum].draw(costume[whichcostume].handcolor[0],costume[whichcostume].handcolor[1],costume[whichcostume].handcolor[2]);
+ if(skeleton.joints[i].modelnum==6)skeletonmodels[skeleton.joints[i].modelnum].draw(costume[whichcostume].upperlegcolor[0],costume[whichcostume].upperlegcolor[1],costume[whichcostume].upperlegcolor[2]);
+ if(skeleton.joints[i].modelnum==7)skeletonmodels[skeleton.joints[i].modelnum].draw(costume[whichcostume].lowerlegcolor[0],costume[whichcostume].lowerlegcolor[1],costume[whichcostume].lowerlegcolor[2]);
+ if(skeleton.joints[i].modelnum==8)skeletonmodels[skeleton.joints[i].modelnum].draw(costume[whichcostume].footcolor[0],costume[whichcostume].footcolor[1],costume[whichcostume].footcolor[2]);
+ glPopMatrix();
+ }
+ }
+
+ for(int i=0;i<skeleton.num_muscles;i++){
+ if(skeleton.muscles[i].visible)
+ {
+ glPushMatrix();
+ glTranslatef( (skeleton.muscles[i].parent1->position.x+skeleton.muscles[i].parent2->position.x)/2,
+ (skeleton.muscles[i].parent1->position.y+skeleton.muscles[i].parent2->position.y)/2,
+ (skeleton.muscles[i].parent1->position.z+skeleton.muscles[i].parent2->position.z)/2);
+ glRotatef(-skeleton.muscles[i].rotate1+90,0,1,0);
+ glRotatef(-skeleton.muscles[i].rotate2+90,0,0,1);
+ glRotatef(-skeleton.muscles[i].rotate3,0,1,0);
+ if(skeleton.muscles[i].parent1->modelnum==0&&(who!=0||thirdperson))skeletonmodels[skeleton.muscles[i].parent1->modelnum].draw(costume[whichcostume].headcolor[0],costume[whichcostume].headcolor[1],costume[whichcostume].headcolor[2]);
+ if(skeleton.muscles[i].parent1->modelnum==0&&(who==0&&thirdperson))skeletonmodels[9].draw();
+ if(skeleton.muscles[i].parent1->modelnum==1&&(who!=0||thirdperson))skeletonmodels[skeleton.muscles[i].parent1->modelnum].draw(costume[whichcostume].chestcolor[0],costume[whichcostume].chestcolor[1],costume[whichcostume].chestcolor[2]);
+ if(skeleton.muscles[i].parent1->modelnum==2)skeletonmodels[skeleton.muscles[i].parent1->modelnum].draw(costume[whichcostume].abdomencolor[0],costume[whichcostume].abdomencolor[1],costume[whichcostume].abdomencolor[2]);
+ if(skeleton.muscles[i].parent1->modelnum==3)skeletonmodels[skeleton.muscles[i].parent1->modelnum].draw(costume[whichcostume].upperarmcolor[0],costume[whichcostume].upperarmcolor[1],costume[whichcostume].upperarmcolor[2]);
+ if(skeleton.muscles[i].parent1->modelnum==4)skeletonmodels[skeleton.muscles[i].parent1->modelnum].draw(costume[whichcostume].lowerarmcolor[0],costume[whichcostume].lowerarmcolor[1],costume[whichcostume].lowerarmcolor[2]);
+ if(skeleton.muscles[i].parent1->modelnum==5)skeletonmodels[skeleton.muscles[i].parent1->modelnum].draw(costume[whichcostume].handcolor[0],costume[whichcostume].handcolor[1],costume[whichcostume].handcolor[2]);
+ if(skeleton.muscles[i].parent1->modelnum==6)skeletonmodels[skeleton.muscles[i].parent1->modelnum].draw(costume[whichcostume].upperlegcolor[0],costume[whichcostume].upperlegcolor[1],costume[whichcostume].upperlegcolor[2]);
+ if(skeleton.muscles[i].parent1->modelnum==7)skeletonmodels[skeleton.muscles[i].parent1->modelnum].draw(costume[whichcostume].lowerlegcolor[0],costume[whichcostume].lowerlegcolor[1],costume[whichcostume].lowerlegcolor[2]);
+ if(skeleton.muscles[i].parent1->modelnum==8)skeletonmodels[skeleton.muscles[i].parent1->modelnum].draw(costume[whichcostume].footcolor[0],costume[whichcostume].footcolor[1],costume[whichcostume].footcolor[2]);
+
+ glPopMatrix();
+ }
+ }
+ if(whichgun==knife){
+ glPushMatrix();
+ glTranslatef( skeleton.joints[skeleton.jointlabels[righthand]].position.x,
+ skeleton.joints[skeleton.jointlabels[righthand]].position.y,
+ skeleton.joints[skeleton.jointlabels[righthand]].position.z);
+ glRotatef(-skeleton.joints[skeleton.jointlabels[righthand]].rotate1+90-1.5,0,1,0);
+ glRotatef(-skeleton.joints[skeleton.jointlabels[righthand]].rotate2+90,0,0,1);
+ glRotatef(-skeleton.joints[skeleton.jointlabels[righthand]].rotate3,0,1,0);
+ glTranslatef(0,-.2,0);
+ gunmodels[knifemodel].draw();
+ glPopMatrix();
+ }
+ if(skeleton.offset&&skeleton.free<1){
+ for(int i=0;i<skeleton.num_joints;i++){
+ skeleton.joints[i].position=skeleton.joints[i].oldposition;
+ }
+ }
+
+ glDisable(GL_LIGHT1);
+} \ No newline at end of file
diff --git a/Source/Person.h b/Source/Person.h
new file mode 100644
index 0000000..e4b0fa3
--- /dev/null
+++ b/Source/Person.h
@@ -0,0 +1,149 @@
+#ifndef _PERSON_H_
+#define _PERSON_H_
+
+/**> HEADER FILES <**/
+#include <gl.h>
+#include "Quaternions.h"
+#include "Constants.h"
+#include "alut.h"
+#include "skeleton.h"
+#include "models.h"
+#include "constants.h"
+#include "math.h"
+#include "camera.h"
+#include "sprites.h"
+
+#define playertype 0
+#define civiliantype 1
+#define eviltype 2
+#define viptype 3
+#define evilsnipertype 4
+#define evilassaultrifletype 5
+#define zombietype 6
+
+class HitStruct
+{
+ public:
+ Joint *joint1;
+ Joint *joint2;
+ XYZ hitlocation;
+ bool collision;
+};
+
+class Person
+{
+ public:
+ int eaten;
+ int currentframe;
+ int targetframe;
+ int currentanimation;
+ int targetanimation;
+ float target;
+ float playerhealth;
+ int modelnum;
+ XYZ oldplayercoords;
+ XYZ playercoords;
+ XYZ playervelocity;
+ float playerrotation;
+ float playerrotation2;
+ float playerlowrotation;
+ float pathcheckdelay;
+ bool onground;
+ bool backwardsanim;
+ XYZ facing;
+ XYZ velocity;
+ float shotdelay;
+ bool litup;
+
+ bool existing;
+
+ int type;
+
+ int whichcostume;
+
+ Skeleton skeleton;
+ Animation tempanimation;
+
+ bool freshshootkey;
+ bool freshkickkey;
+ int bufferattack;
+ int jump_key;
+ int left_key;
+ int right_key;
+ int duck_key;
+ int shoot_key;
+ int kick_key;
+ int block_key;
+
+ float speed;
+ bool aiming;
+ int grenphase;
+ float grenamount;
+ float aimamount;
+ float speedmult;
+ float pathsize;
+
+ int pathnum;
+ int oldpathnum;
+ int oldoldpathnum;
+ int oldoldoldpathnum;
+ XYZ pathtarget;
+ int whichblockx;
+ int whichblocky;
+
+ bool dead;
+
+ XYZ averageloc;
+ XYZ oldaverageloc;
+
+ float lastdistancevictim;
+
+ bool firstlongdead;
+ float longdead;
+
+ Joint *bjoint1,*bjoint2;
+ float bleeding;
+ float bleeddelay;
+
+ float attacktarget;
+ int attackframe;
+ int killtarget;
+ bool killtargetvisible;
+
+ float gunrotate1, gunrotate2, gunrotate3;
+ float recoil;
+ int whichgun;
+ float oldhealth;
+ float health;
+ float maxhealth;
+ float reloading;
+ int ammo;
+ int reloads[10];
+ bool running;
+ bool onpath;
+
+ void FindRotationGun(XYZ start, XYZ target);
+
+ int DrawSkeleton(int who);
+ void DoStuff(int who);
+ void DoAnimations(int who);
+ void DoAnimationslite(int who);
+ HitStruct BulletCollideWithPlayer(int who, XYZ start, XYZ end);
+};
+
+class Costume
+{
+ public:
+ float headcolor[3];
+ float handcolor[3];
+ float footcolor[3];
+ float upperarmcolor[3];
+ float lowerarmcolor[3];
+ float upperlegcolor[3];
+ float lowerlegcolor[3];
+ float abdomencolor[3];
+ float chestcolor[3];
+};
+
+
+#endif \ No newline at end of file
diff --git a/Source/PhysicsMath.h b/Source/PhysicsMath.h
new file mode 100644
index 0000000..d9073df
--- /dev/null
+++ b/Source/PhysicsMath.h
@@ -0,0 +1,1431 @@
+#ifndef _PHYSICSMATH_H_
+
+#define _PHYSICSMATH_H_
+
+
+
+#include <math.h>
+
+#include "Quaternions.h"
+
+
+
+//------------------------------------------------------------------------//
+
+// Misc. Constants
+
+//------------------------------------------------------------------------//
+
+
+
+float const pi = 3.14159265f;
+
+float const g = -32.174f; // acceleration due to gravity, ft/s^2
+
+float const rho = 0.0023769f; // desity of air at sea level, slugs/ft^3
+
+float const tol = 0.0000000001f; // float type tolerance
+
+
+
+
+
+//------------------------------------------------------------------------//
+
+// Misc. Functions
+
+//------------------------------------------------------------------------//
+
+inline float DegreesToRadians(float deg);
+
+inline float RadiansToDegrees(float rad);
+
+
+
+inline float DegreesToRadians(float deg)
+
+{
+
+ return deg * pi / 180.0f;
+
+}
+
+
+
+inline float RadiansToDegrees(float rad)
+
+{
+
+ return rad * 180.0f / pi;
+
+}
+
+
+
+//------------------------------------------------------------------------//
+
+// Vector Class and vector functions
+
+//------------------------------------------------------------------------//
+
+class Vector {
+
+public:
+
+ float x;
+
+ float y;
+
+ float z;
+
+
+
+ Vector(void);
+
+ Vector(float xi, float yi, float zi);
+
+
+
+ float Magnitude(void);
+
+ void Normalize(void);
+
+ void Reverse(void);
+
+
+
+ Vector& operator+=(Vector u); // vector addition
+
+ Vector& operator-=(Vector u); // vector subtraction
+
+ Vector& operator*=(float s); // scalar multiply
+
+ Vector& operator/=(float s); // scalar divide
+
+
+
+ Vector operator-(void);
+
+
+
+};
+
+
+
+inline Vector operator+(Vector u, Vector v);
+
+inline Vector operator-(Vector u, Vector v);
+
+inline Vector operator^(Vector u, Vector v);
+
+inline float operator*(Vector u, Vector v);
+
+inline Vector operator*(float s, Vector u);
+
+inline Vector operator*(Vector u, float s);
+
+inline Vector operator/(Vector u, float s);
+
+inline float TripleScalarProduct(Vector u, Vector v, Vector w);
+
+
+
+inline Vector::Vector(void)
+
+{
+
+ x = 0;
+
+ y = 0;
+
+ z = 0;
+
+}
+
+
+
+inline Vector::Vector(float xi, float yi, float zi)
+
+{
+
+ x = xi;
+
+ y = yi;
+
+ z = zi;
+
+}
+
+
+
+inline float Vector::Magnitude(void)
+
+{
+
+ return (float) fast_sqrt(x*x + y*y + z*z);
+
+}
+
+
+
+inline void Vector::Normalize(void)
+
+{
+
+ float m = (float) fast_sqrt(x*x + y*y + z*z);
+
+ if(m <= tol) m = 1;
+
+ x /= m;
+
+ y /= m;
+
+ z /= m;
+
+
+
+ if (fabs(x) < tol) x = 0.0f;
+
+ if (fabs(y) < tol) y = 0.0f;
+
+ if (fabs(z) < tol) z = 0.0f;
+
+}
+
+
+
+inline void Vector::Reverse(void)
+
+{
+
+ x = -x;
+
+ y = -y;
+
+ z = -z;
+
+}
+
+
+
+inline Vector& Vector::operator+=(Vector u)
+
+{
+
+ x += u.x;
+
+ y += u.y;
+
+ z += u.z;
+
+ return *this;
+
+}
+
+
+
+inline Vector& Vector::operator-=(Vector u)
+
+{
+
+ x -= u.x;
+
+ y -= u.y;
+
+ z -= u.z;
+
+ return *this;
+
+}
+
+
+
+inline Vector& Vector::operator*=(float s)
+
+{
+
+ x *= s;
+
+ y *= s;
+
+ z *= s;
+
+ return *this;
+
+}
+
+
+
+inline Vector& Vector::operator/=(float s)
+
+{
+
+ x /= s;
+
+ y /= s;
+
+ z /= s;
+
+ return *this;
+
+}
+
+
+
+inline Vector Vector::operator-(void)
+
+{
+
+ return Vector(-x, -y, -z);
+
+}
+
+
+
+
+
+inline Vector operator+(Vector u, Vector v)
+
+{
+
+ return Vector(u.x + v.x, u.y + v.y, u.z + v.z);
+
+}
+
+
+
+inline Vector operator-(Vector u, Vector v)
+
+{
+
+ return Vector(u.x - v.x, u.y - v.y, u.z - v.z);
+
+}
+
+
+
+// Vector cross product (u cross v)
+
+inline Vector operator^(Vector u, Vector v)
+
+{
+
+ return Vector( u.y*v.z - u.z*v.y,
+
+ -u.x*v.z + u.z*v.x,
+
+ u.x*v.y - u.y*v.x );
+
+}
+
+
+
+// Vector dot product
+
+inline float operator*(Vector u, Vector v)
+
+{
+
+ return (u.x*v.x + u.y*v.y + u.z*v.z);
+
+}
+
+
+
+inline Vector operator*(float s, Vector u)
+
+{
+
+ return Vector(u.x*s, u.y*s, u.z*s);
+
+}
+
+
+
+inline Vector operator*(Vector u, float s)
+
+{
+
+ return Vector(u.x*s, u.y*s, u.z*s);
+
+}
+
+
+
+inline Vector operator/(Vector u, float s)
+
+{
+
+ return Vector(u.x/s, u.y/s, u.z/s);
+
+}
+
+
+
+// triple scalar product (u dot (v cross w))
+
+inline float TripleScalarProduct(Vector u, Vector v, Vector w)
+
+{
+
+ return float( (u.x * (v.y*w.z - v.z*w.y)) +
+
+ (u.y * (-v.x*w.z + v.z*w.x)) +
+
+ (u.z * (v.x*w.y - v.y*w.x)) );
+
+ //return u*(v^w);
+
+
+
+}
+
+
+
+
+
+
+
+//------------------------------------------------------------------------//
+
+// Matrix Class and matrix functions
+
+//------------------------------------------------------------------------//
+
+
+
+class Matrix3x3 {
+
+public:
+
+ // elements eij: i -> row, j -> column
+
+ float e11, e12, e13, e21, e22, e23, e31, e32, e33;
+
+
+
+ Matrix3x3(void);
+
+ Matrix3x3( float r1c1, float r1c2, float r1c3,
+
+ float r2c1, float r2c2, float r2c3,
+
+ float r3c1, float r3c2, float r3c3 );
+
+
+
+ float det(void);
+
+ Matrix3x3 Transpose(void);
+
+ Matrix3x3 Inverse(void);
+
+
+
+ Matrix3x3& operator+=(Matrix3x3 m);
+
+ Matrix3x3& operator-=(Matrix3x3 m);
+
+ Matrix3x3& operator*=(float s);
+
+ Matrix3x3& operator/=(float s);
+
+};
+
+
+
+inline Matrix3x3 operator+(Matrix3x3 m1, Matrix3x3 m2);
+
+inline Matrix3x3 operator-(Matrix3x3 m1, Matrix3x3 m2);
+
+inline Matrix3x3 operator/(Matrix3x3 m, float s);
+
+inline Matrix3x3 operator*(Matrix3x3 m1, Matrix3x3 m2);
+
+inline Matrix3x3 operator*(Matrix3x3 m, float s);
+
+inline Matrix3x3 operator*(float s, Matrix3x3 m);
+
+inline Vector operator*(Matrix3x3 m, Vector u);
+
+inline Vector operator*(Vector u, Matrix3x3 m);
+
+
+
+
+
+
+
+
+
+
+
+inline Matrix3x3::Matrix3x3(void)
+
+{
+
+ e11 = 0;
+
+ e12 = 0;
+
+ e13 = 0;
+
+ e21 = 0;
+
+ e22 = 0;
+
+ e23 = 0;
+
+ e31 = 0;
+
+ e32 = 0;
+
+ e33 = 0;
+
+}
+
+
+
+inline Matrix3x3::Matrix3x3( float r1c1, float r1c2, float r1c3,
+
+ float r2c1, float r2c2, float r2c3,
+
+ float r3c1, float r3c2, float r3c3 )
+
+{
+
+ e11 = r1c1;
+
+ e12 = r1c2;
+
+ e13 = r1c3;
+
+ e21 = r2c1;
+
+ e22 = r2c2;
+
+ e23 = r2c3;
+
+ e31 = r3c1;
+
+ e32 = r3c2;
+
+ e33 = r3c3;
+
+}
+
+
+
+inline float Matrix3x3::det(void)
+
+{
+
+ return e11*e22*e33 -
+
+ e11*e32*e23 +
+
+ e21*e32*e13 -
+
+ e21*e12*e33 +
+
+ e31*e12*e23 -
+
+ e31*e22*e13;
+
+}
+
+
+
+inline Matrix3x3 Matrix3x3::Transpose(void)
+
+{
+
+ return Matrix3x3(e11,e21,e31,e12,e22,e32,e13,e23,e33);
+
+}
+
+
+
+inline Matrix3x3 Matrix3x3::Inverse(void)
+
+{
+
+ float d = e11*e22*e33 -
+
+ e11*e32*e23 +
+
+ e21*e32*e13 -
+
+ e21*e12*e33 +
+
+ e31*e12*e23 -
+
+ e31*e22*e13;
+
+
+
+ if (d == 0) d = 1;
+
+
+
+ return Matrix3x3( (e22*e33-e23*e32)/d,
+
+ -(e12*e33-e13*e32)/d,
+
+ (e12*e23-e13*e22)/d,
+
+ -(e21*e33-e23*e31)/d,
+
+ (e11*e33-e13*e31)/d,
+
+ -(e11*e23-e13*e21)/d,
+
+ (e21*e32-e22*e31)/d,
+
+ -(e11*e32-e12*e31)/d,
+
+ (e11*e22-e12*e21)/d );
+
+}
+
+
+
+inline Matrix3x3& Matrix3x3::operator+=(Matrix3x3 m)
+
+{
+
+ e11 += m.e11;
+
+ e12 += m.e12;
+
+ e13 += m.e13;
+
+ e21 += m.e21;
+
+ e22 += m.e22;
+
+ e23 += m.e23;
+
+ e31 += m.e31;
+
+ e32 += m.e32;
+
+ e33 += m.e33;
+
+ return *this;
+
+}
+
+
+
+inline Matrix3x3& Matrix3x3::operator-=(Matrix3x3 m)
+
+{
+
+ e11 -= m.e11;
+
+ e12 -= m.e12;
+
+ e13 -= m.e13;
+
+ e21 -= m.e21;
+
+ e22 -= m.e22;
+
+ e23 -= m.e23;
+
+ e31 -= m.e31;
+
+ e32 -= m.e32;
+
+ e33 -= m.e33;
+
+ return *this;
+
+}
+
+
+
+inline Matrix3x3& Matrix3x3::operator*=(float s)
+
+{
+
+ e11 *= s;
+
+ e12 *= s;
+
+ e13 *= s;
+
+ e21 *= s;
+
+ e22 *= s;
+
+ e23 *= s;
+
+ e31 *= s;
+
+ e32 *= s;
+
+ e33 *= s;
+
+ return *this;
+
+}
+
+
+
+inline Matrix3x3& Matrix3x3::operator/=(float s)
+
+{
+
+ e11 /= s;
+
+ e12 /= s;
+
+ e13 /= s;
+
+ e21 /= s;
+
+ e22 /= s;
+
+ e23 /= s;
+
+ e31 /= s;
+
+ e32 /= s;
+
+ e33 /= s;
+
+ return *this;
+
+}
+
+
+
+inline Matrix3x3 operator+(Matrix3x3 m1, Matrix3x3 m2)
+
+{
+
+ return Matrix3x3( m1.e11+m2.e11,
+
+ m1.e12+m2.e12,
+
+ m1.e13+m2.e13,
+
+ m1.e21+m2.e21,
+
+ m1.e22+m2.e22,
+
+ m1.e23+m2.e23,
+
+ m1.e31+m2.e31,
+
+ m1.e32+m2.e32,
+
+ m1.e33+m2.e33);
+
+}
+
+
+
+inline Matrix3x3 operator-(Matrix3x3 m1, Matrix3x3 m2)
+
+{
+
+ return Matrix3x3( m1.e11-m2.e11,
+
+ m1.e12-m2.e12,
+
+ m1.e13-m2.e13,
+
+ m1.e21-m2.e21,
+
+ m1.e22-m2.e22,
+
+ m1.e23-m2.e23,
+
+ m1.e31-m2.e31,
+
+ m1.e32-m2.e32,
+
+ m1.e33-m2.e33);
+
+}
+
+
+
+inline Matrix3x3 operator/(Matrix3x3 m, float s)
+
+{
+
+ return Matrix3x3( m.e11/s,
+
+ m.e12/s,
+
+ m.e13/s,
+
+ m.e21/s,
+
+ m.e22/s,
+
+ m.e23/s,
+
+ m.e31/s,
+
+ m.e32/s,
+
+ m.e33/s);
+
+}
+
+
+
+inline Matrix3x3 operator*(Matrix3x3 m1, Matrix3x3 m2)
+
+{
+
+ return Matrix3x3( m1.e11*m2.e11 + m1.e12*m2.e21 + m1.e13*m2.e31,
+
+ m1.e11*m2.e12 + m1.e12*m2.e22 + m1.e13*m2.e32,
+
+ m1.e11*m2.e13 + m1.e12*m2.e23 + m1.e13*m2.e33,
+
+ m1.e21*m2.e11 + m1.e22*m2.e21 + m1.e23*m2.e31,
+
+ m1.e21*m2.e12 + m1.e22*m2.e22 + m1.e23*m2.e32,
+
+ m1.e21*m2.e13 + m1.e22*m2.e23 + m1.e23*m2.e33,
+
+ m1.e31*m2.e11 + m1.e32*m2.e21 + m1.e33*m2.e31,
+
+ m1.e31*m2.e12 + m1.e32*m2.e22 + m1.e33*m2.e32,
+
+ m1.e31*m2.e13 + m1.e32*m2.e23 + m1.e33*m2.e33 );
+
+}
+
+
+
+inline Matrix3x3 operator*(Matrix3x3 m, float s)
+
+{
+
+ return Matrix3x3( m.e11*s,
+
+ m.e12*s,
+
+ m.e13*s,
+
+ m.e21*s,
+
+ m.e22*s,
+
+ m.e23*s,
+
+ m.e31*s,
+
+ m.e32*s,
+
+ m.e33*s);
+
+}
+
+
+
+inline Matrix3x3 operator*(float s, Matrix3x3 m)
+
+{
+
+ return Matrix3x3( m.e11*s,
+
+ m.e12*s,
+
+ m.e13*s,
+
+ m.e21*s,
+
+ m.e22*s,
+
+ m.e23*s,
+
+ m.e31*s,
+
+ m.e32*s,
+
+ m.e33*s);
+
+}
+
+
+
+inline Vector operator*(Matrix3x3 m, Vector u)
+
+{
+
+ return Vector( m.e11*u.x + m.e12*u.y + m.e13*u.z,
+
+ m.e21*u.x + m.e22*u.y + m.e23*u.z,
+
+ m.e31*u.x + m.e32*u.y + m.e33*u.z);
+
+}
+
+
+
+inline Vector operator*(Vector u, Matrix3x3 m)
+
+{
+
+ return Vector( u.x*m.e11 + u.y*m.e21 + u.z*m.e31,
+
+ u.x*m.e12 + u.y*m.e22 + u.z*m.e32,
+
+ u.x*m.e13 + u.y*m.e23 + u.z*m.e33);
+
+}
+
+
+
+//------------------------------------------------------------------------//
+
+// Quaternion Class and Quaternion functions
+
+//------------------------------------------------------------------------//
+
+
+
+class Quaternion {
+
+public:
+
+ float n; // number (scalar) part
+
+ Vector v; // vector part: v.x, v.y, v.z
+
+
+
+ Quaternion(void);
+
+ Quaternion(float e0, float e1, float e2, float e3);
+
+
+
+ float Magnitude(void);
+
+ Vector GetVector(void);
+
+ float GetScalar(void);
+
+ Quaternion operator+=(Quaternion q);
+
+ Quaternion operator-=(Quaternion q);
+
+ Quaternion operator*=(float s);
+
+ Quaternion operator/=(float s);
+
+ Quaternion operator~(void) const { return Quaternion(n, -v.x, -v.y, -v.z);}
+
+};
+
+
+
+inline Quaternion operator+(Quaternion q1, Quaternion q2);
+
+inline Quaternion operator-(Quaternion q1, Quaternion q2);
+
+inline Quaternion operator*(Quaternion q1, Quaternion q2);
+
+inline Quaternion operator*(Quaternion q, float s);
+
+inline Quaternion operator*(float s, Quaternion q);
+
+inline Quaternion operator*(Quaternion q, Vector v);
+
+inline Quaternion operator*(Vector v, Quaternion q);
+
+inline Quaternion operator/(Quaternion q, float s);
+
+inline float QGetAngle(Quaternion q);
+
+inline Vector QGetAxis(Quaternion q);
+
+inline Quaternion QRotate(Quaternion q1, Quaternion q2);
+
+inline Vector QVRotate(Quaternion q, Vector v);
+
+inline Quaternion MakeQFromEulerAngles(float x, float y, float z);
+
+inline Vector MakeEulerAnglesFromQ(Quaternion q);
+
+
+
+
+
+inline Quaternion::Quaternion(void)
+
+{
+
+ n = 0;
+
+ v.x = 0;
+
+ v.y = 0;
+
+ v.z = 0;
+
+}
+
+
+
+inline Quaternion::Quaternion(float e0, float e1, float e2, float e3)
+
+{
+
+ n = e0;
+
+ v.x = e1;
+
+ v.y = e2;
+
+ v.z = e3;
+
+}
+
+
+
+inline float Quaternion::Magnitude(void)
+
+{
+
+ return (float) fast_sqrt(n*n + v.x*v.x + v.y*v.y + v.z*v.z);
+
+}
+
+
+
+inline Vector Quaternion::GetVector(void)
+
+{
+
+ return Vector(v.x, v.y, v.z);
+
+}
+
+
+
+inline float Quaternion::GetScalar(void)
+
+{
+
+ return n;
+
+}
+
+
+
+inline Quaternion Quaternion::operator+=(Quaternion q)
+
+{
+
+ n += q.n;
+
+ v.x += q.v.x;
+
+ v.y += q.v.y;
+
+ v.z += q.v.z;
+
+ return *this;
+
+}
+
+
+
+inline Quaternion Quaternion::operator-=(Quaternion q)
+
+{
+
+ n -= q.n;
+
+ v.x -= q.v.x;
+
+ v.y -= q.v.y;
+
+ v.z -= q.v.z;
+
+ return *this;
+
+}
+
+
+
+inline Quaternion Quaternion::operator*=(float s)
+
+{
+
+ n *= s;
+
+ v.x *= s;
+
+ v.y *= s;
+
+ v.z *= s;
+
+ return *this;
+
+}
+
+
+
+inline Quaternion Quaternion::operator/=(float s)
+
+{
+
+ n /= s;
+
+ v.x /= s;
+
+ v.y /= s;
+
+ v.z /= s;
+
+ return *this;
+
+}
+
+
+
+/*inline Quaternion Quaternion::operator~()
+
+{
+
+ return Quaternion(n, -v.x, -v.y, -v.z);
+
+}*/
+
+
+
+inline Quaternion operator+(Quaternion q1, Quaternion q2)
+
+{
+
+ return Quaternion( q1.n + q2.n,
+
+ q1.v.x + q2.v.x,
+
+ q1.v.y + q2.v.y,
+
+ q1.v.z + q2.v.z);
+
+}
+
+
+
+inline Quaternion operator-(Quaternion q1, Quaternion q2)
+
+{
+
+ return Quaternion( q1.n - q2.n,
+
+ q1.v.x - q2.v.x,
+
+ q1.v.y - q2.v.y,
+
+ q1.v.z - q2.v.z);
+
+}
+
+
+
+inline Quaternion operator*(Quaternion q1, Quaternion q2)
+
+{
+
+ return Quaternion( q1.n*q2.n - q1.v.x*q2.v.x - q1.v.y*q2.v.y - q1.v.z*q2.v.z,
+
+ q1.n*q2.v.x + q1.v.x*q2.n + q1.v.y*q2.v.z - q1.v.z*q2.v.y,
+
+ q1.n*q2.v.y + q1.v.y*q2.n + q1.v.z*q2.v.x - q1.v.x*q2.v.z,
+
+ q1.n*q2.v.z + q1.v.z*q2.n + q1.v.x*q2.v.y - q1.v.y*q2.v.x);
+
+}
+
+
+
+inline Quaternion operator*(Quaternion q, float s)
+
+{
+
+ return Quaternion(q.n*s, q.v.x*s, q.v.y*s, q.v.z*s);
+
+}
+
+
+
+inline Quaternion operator*(float s, Quaternion q)
+
+{
+
+ return Quaternion(q.n*s, q.v.x*s, q.v.y*s, q.v.z*s);
+
+}
+
+
+
+inline Quaternion operator*(Quaternion q, Vector v)
+
+{
+
+ return Quaternion( -(q.v.x*v.x + q.v.y*v.y + q.v.z*v.z),
+
+ q.n*v.x + q.v.y*v.z - q.v.z*v.y,
+
+ q.n*v.y + q.v.z*v.x - q.v.x*v.z,
+
+ q.n*v.z + q.v.x*v.y - q.v.y*v.x);
+
+}
+
+
+
+inline Quaternion operator*(Vector v, Quaternion q)
+
+{
+
+ return Quaternion( -(q.v.x*v.x + q.v.y*v.y + q.v.z*v.z),
+
+ q.n*v.x + q.v.z*v.y - q.v.y*v.z,
+
+ q.n*v.y + q.v.x*v.z - q.v.z*v.x,
+
+ q.n*v.z + q.v.y*v.x - q.v.x*v.y);
+
+}
+
+
+
+inline Quaternion operator/(Quaternion q, float s)
+
+{
+
+ return Quaternion(q.n/s, q.v.x/s, q.v.y/s, q.v.z/s);
+
+}
+
+
+
+inline float QGetAngle(Quaternion q)
+
+{
+
+ return (float) (2*acos(q.n));
+
+}
+
+
+
+inline Vector QGetAxis(Quaternion q)
+
+{
+
+ Vector v;
+
+ float m;
+
+
+
+ v = q.GetVector();
+
+ m = v.Magnitude();
+
+
+
+ if (m <= tol)
+
+ return Vector();
+
+ else
+
+ return v/m;
+
+}
+
+
+
+inline Quaternion QRotate(Quaternion q1, Quaternion q2)
+
+{
+
+ return q1*q2*(~q1);
+
+}
+
+
+
+inline Vector QVRotate(Quaternion q, Vector v)
+
+{
+
+ Quaternion t;
+
+
+
+
+
+ t = q*v*(~q);
+
+
+
+ return t.GetVector();
+
+}
+
+
+
+inline Quaternion MakeQFromEulerAngles(float x, float y, float z)
+
+{
+
+ Quaternion q;
+
+ double roll = DegreesToRadians(x);
+
+ double pitch = DegreesToRadians(y);
+
+ double yaw = DegreesToRadians(z);
+
+
+
+ double cyaw, cpitch, croll, syaw, spitch, sroll;
+
+ double cyawcpitch, syawspitch, cyawspitch, syawcpitch;
+
+
+
+ cyaw = cos(0.5f * yaw);
+
+ cpitch = cos(0.5f * pitch);
+
+ croll = cos(0.5f * roll);
+
+ syaw = sin(0.5f * yaw);
+
+ spitch = sin(0.5f * pitch);
+
+ sroll = sin(0.5f * roll);
+
+
+
+ cyawcpitch = cyaw*cpitch;
+
+ syawspitch = syaw*spitch;
+
+ cyawspitch = cyaw*spitch;
+
+ syawcpitch = syaw*cpitch;
+
+
+
+ q.n = (float) (cyawcpitch * croll + syawspitch * sroll);
+
+ q.v.x = (float) (cyawcpitch * sroll - syawspitch * croll);
+
+ q.v.y = (float) (cyawspitch * croll + syawcpitch * sroll);
+
+ q.v.z = (float) (syawcpitch * croll - cyawspitch * sroll);
+
+
+
+ return q;
+
+}
+
+
+
+inline Vector MakeEulerAnglesFromQ(Quaternion q)
+
+{
+
+ double r11, r21, r31, r32, r33, r12, r13;
+
+ double q00, q11, q22, q33;
+
+ double tmp;
+
+ Vector u;
+
+
+
+ q00 = q.n * q.n;
+
+ q11 = q.v.x * q.v.x;
+
+ q22 = q.v.y * q.v.y;
+
+ q33 = q.v.z * q.v.z;
+
+
+
+ r11 = q00 + q11 - q22 - q33;
+
+ r21 = 2 * (q.v.x*q.v.y + q.n*q.v.z);
+
+ r31 = 2 * (q.v.x*q.v.z - q.n*q.v.y);
+
+ r32 = 2 * (q.v.y*q.v.z + q.n*q.v.x);
+
+ r33 = q00 - q11 - q22 + q33;
+
+
+
+ tmp = fabs(r31);
+
+ if(tmp > 0.999999)
+
+ {
+
+ r12 = 2 * (q.v.x*q.v.y - q.n*q.v.z);
+
+ r13 = 2 * (q.v.x*q.v.z + q.n*q.v.y);
+
+
+
+ u.x = RadiansToDegrees(0.0f); //roll
+
+ u.y = RadiansToDegrees((float) (-(pi/2) * r31/tmp)); // pitch
+
+ u.z = RadiansToDegrees((float) atan2(-r12, -r31*r13)); // yaw
+
+ return u;
+
+ }
+
+
+
+ u.x = RadiansToDegrees((float) atan2(r32, r33)); // roll
+
+ u.y = RadiansToDegrees((float) asin(-r31)); // pitch
+
+ u.z = RadiansToDegrees((float) atan2(r21, r11)); // yaw
+
+ return u;
+
+
+
+
+
+}
+
+
+
+
+
+
+
+
+
+
+
+#endif \ No newline at end of file
diff --git a/Source/Quaternions.cpp b/Source/Quaternions.cpp
new file mode 100644
index 0000000..b806ec0
--- /dev/null
+++ b/Source/Quaternions.cpp
@@ -0,0 +1,745 @@
+#include "Quaternions.h"
+
+// Functions
+quaternion Quat_Mult(quaternion q1, quaternion q2)
+{
+ quaternion QResult;
+ float a, b, c, d, e, f, g, h;
+ a = (q1.w + q1.x) * (q2.w + q2.x);
+ b = (q1.z - q1.y) * (q2.y - q2.z);
+ c = (q1.w - q1.x) * (q2.y + q2.z);
+ d = (q1.y + q1.z) * (q2.w - q2.x);
+ e = (q1.x + q1.z) * (q2.x + q2.y);
+ f = (q1.x - q1.z) * (q2.x - q2.y);
+ g = (q1.w + q1.y) * (q2.w - q2.z);
+ h = (q1.w - q1.y) * (q2.w + q2.z);
+ QResult.w = b + (-e - f + g + h) / 2;
+ QResult.x = a - (e + f + g + h) / 2;
+ QResult.y = c + (e - f + g - h) / 2;
+ QResult.z = d + (e - f - g + h) / 2;
+ return QResult;
+}
+
+XYZ XYZ::operator+(XYZ add){
+ XYZ ne;
+ ne=add;
+ ne.x+=x;
+ ne.y+=y;
+ ne.z+=z;
+ return ne;
+}
+
+XYZ XYZ::operator-(XYZ add){
+ XYZ ne;
+ ne=add;
+ ne.x=x-ne.x;
+ ne.y=y-ne.y;
+ ne.z=z-ne.z;
+ return ne;
+}
+
+XYZ XYZ::operator*(float add){
+ XYZ ne;
+ ne.x=x*add;
+ ne.y=y*add;
+ ne.z=z*add;
+ return ne;
+}
+
+XYZ XYZ::operator*(XYZ add){
+ XYZ ne;
+ ne.x=x*add.x;
+ ne.y=y*add.y;
+ ne.z=z*add.z;
+ return ne;
+}
+
+XYZ XYZ::operator/(float add){
+ XYZ ne;
+ ne.x=x/add;
+ ne.y=y/add;
+ ne.z=z/add;
+ return ne;
+}
+
+void XYZ::operator+=(XYZ add){
+ x+=add.x;
+ y+=add.y;
+ z+=add.z;
+}
+
+void XYZ::operator-=(XYZ add){
+ x=x-add.x;
+ y=y-add.y;
+ z=z-add.z;
+}
+
+void XYZ::operator*=(float add){
+ x=x*add;
+ y=y*add;
+ z=z*add;
+}
+
+void XYZ::operator*=(XYZ add){
+ x=x*add.x;
+ y=y*add.y;
+ z=z*add.z;
+}
+
+void XYZ::operator/=(float add){
+ x=x/add;
+ y=y/add;
+ z=z/add;
+}
+
+void XYZ::operator=(float add){
+ x=add;
+ y=add;
+ z=add;
+}
+
+void XYZ::vec(Vector add){
+ x=add.x;
+ y=add.y;
+ z=add.z;
+}
+
+bool XYZ::operator==(XYZ add){
+ if(x==add.x&&y==add.y&&z==add.z)return 1;
+ return 0;
+}
+
+quaternion To_Quat(Matrix_t m)
+{
+ // From Jason Shankel, (C) 2000.
+ quaternion Quat;
+
+ double Tr = m[0][0] + m[1][1] + m[2][2] + 1.0, fourD;
+ double q[4];
+
+ int i,j,k;
+ if (Tr >= 1.0)
+ {
+ fourD = 2.0*fast_sqrt(Tr);
+ q[3] = fourD/4.0;
+ q[0] = (m[2][1] - m[1][2]) / fourD;
+ q[1] = (m[0][2] - m[2][0]) / fourD;
+ q[2] = (m[1][0] - m[0][1]) / fourD;
+ }
+ else
+ {
+ if (m[0][0] > m[1][1])
+ {
+ i = 0;
+ }
+ else
+ {
+ i = 1;
+ }
+ if (m[2][2] > m[i][i])
+ {
+ i = 2;
+ }
+ j = (i+1)%3;
+ k = (j+1)%3;
+ fourD = 2.0*fast_sqrt(m[i][i] - m[j][j] - m[k][k] + 1.0);
+ q[i] = fourD / 4.0;
+ q[j] = (m[j][i] + m[i][j]) / fourD;
+ q[k] = (m[k][i] + m[i][k]) / fourD;
+ q[3] = (m[j][k] - m[k][j]) / fourD;
+ }
+
+ Quat.x = q[0];
+ Quat.y = q[1];
+ Quat.z = q[2];
+ Quat.w = q[3];
+ return Quat;
+}
+void Quat_2_Matrix(quaternion Quat, Matrix_t m)
+{
+ // From the GLVelocity site (http://glvelocity.gamedev.net)
+ float fW = Quat.w;
+ float fX = Quat.x;
+ float fY = Quat.y;
+ float fZ = Quat.z;
+ float fXX = fX * fX;
+ float fYY = fY * fY;
+ float fZZ = fZ * fZ;
+ m[0][0] = 1.0f - 2.0f * (fYY + fZZ);
+ m[1][0] = 2.0f * (fX * fY + fW * fZ);
+ m[2][0] = 2.0f * (fX * fZ - fW * fY);
+ m[3][0] = 0.0f;
+ m[0][1] = 2.0f * (fX * fY - fW * fZ);
+ m[1][1] = 1.0f - 2.0f * (fXX + fZZ);
+ m[2][1] = 2.0f * (fY * fZ + fW * fX);
+ m[3][1] = 0.0f;
+ m[0][2] = 2.0f * (fX * fZ + fW * fY);
+ m[1][2] = 2.0f * (fX * fZ - fW * fX);
+ m[2][2] = 1.0f - 2.0f * (fXX + fYY);
+ m[3][2] = 0.0f;
+ m[0][3] = 0.0f;
+ m[1][3] = 0.0f;
+ m[2][3] = 0.0f;
+ m[3][3] = 1.0f;
+}
+quaternion To_Quat(angle_axis Ang_Ax)
+{
+ // From the Quaternion Powers article on gamedev.net
+ quaternion Quat;
+
+ Quat.x = Ang_Ax.x * sin(Ang_Ax.angle / 2);
+ Quat.y = Ang_Ax.y * sin(Ang_Ax.angle / 2);
+ Quat.z = Ang_Ax.z * sin(Ang_Ax.angle / 2);
+ Quat.w = cos(Ang_Ax.angle / 2);
+ return Quat;
+}
+angle_axis Quat_2_AA(quaternion Quat)
+{
+ angle_axis Ang_Ax;
+ float scale, tw;
+ tw = (float)acos(Quat.w) * 2;
+ scale = (float)sin(tw / 2.0);
+ Ang_Ax.x = Quat.x / scale;
+ Ang_Ax.y = Quat.y / scale;
+ Ang_Ax.z = Quat.z / scale;
+
+ Ang_Ax.angle = 2.0 * acos(Quat.w)/(float)PI*180;
+ return Ang_Ax;
+}
+
+quaternion To_Quat(int In_Degrees, euler Euler)
+{
+ // From the gamasutra quaternion article
+ quaternion Quat;
+ float cr, cp, cy, sr, sp, sy, cpcy, spsy;
+ //If we are in Degree mode, convert to Radians
+ if (In_Degrees) {
+ Euler.x = Euler.x * (float)PI / 180;
+ Euler.y = Euler.y * (float)PI / 180;
+ Euler.z = Euler.z * (float)PI / 180;
+ }
+ //Calculate trig identities
+ //Formerly roll, pitch, yaw
+ cr = float(cos(Euler.x/2));
+ cp = float(cos(Euler.y/2));
+ cy = float(cos(Euler.z/2));
+ sr = float(sin(Euler.x/2));
+ sp = float(sin(Euler.y/2));
+ sy = float(sin(Euler.z/2));
+
+ cpcy = cp * cy;
+ spsy = sp * sy;
+ Quat.w = cr * cpcy + sr * spsy;
+ Quat.x = sr * cpcy - cr * spsy;
+ Quat.y = cr * sp * cy + sr * cp * sy;
+ Quat.z = cr * cp * sy - sr * sp * cy;
+
+ return Quat;
+}
+
+quaternion QNormalize(quaternion Quat)
+{
+ float norm;
+ norm = Quat.x * Quat.x +
+ Quat.y * Quat.y +
+ Quat.z * Quat.z +
+ Quat.w * Quat.w;
+ Quat.x = float(Quat.x / norm);
+ Quat.y = float(Quat.y / norm);
+ Quat.z = float(Quat.z / norm);
+ Quat.w = float(Quat.w / norm);
+ return Quat;
+}
+
+XYZ Quat2Vector(quaternion Quat)
+{
+ QNormalize(Quat);
+
+ float fW = Quat.w;
+ float fX = Quat.x;
+ float fY = Quat.y;
+ float fZ = Quat.z;
+
+ XYZ tempvec;
+
+ tempvec.x = 2.0f*(fX*fZ-fW*fY);
+ tempvec.y = 2.0f*(fY*fZ+fW*fX);
+ tempvec.z = 1.0f-2.0f*(fX*fX+fY*fY);
+
+ return tempvec;
+}
+
+void CrossProduct(XYZ P, XYZ Q, XYZ *V){
+ V->x = P.y * Q.z - P.z * Q.y;
+ V->y = P.z * Q.x - P.x * Q.z;
+ V->z = P.x * Q.y - P.y * Q.x;
+}
+
+void Normalise(XYZ *vectory) {
+ float d = fast_sqrt(vectory->x*vectory->x+vectory->y*vectory->y+vectory->z*vectory->z);
+ if(d==0){return;}
+ vectory->x /= d;
+ vectory->y /= d;
+ vectory->z /= d;
+}
+
+float fast_sqrt (register float arg)
+{
+ // Can replace with slower return std::sqrt(arg);
+ register float result;
+
+ if (arg == 0.0) return 0.0;
+
+ asm {
+ frsqrte result,arg // Calculate Square root
+ }
+
+ // Newton Rhapson iterations.
+ result = result + 0.5 * result * (1.0 - arg * result * result);
+ result = result + 0.5 * result * (1.0 - arg * result * result);
+
+ return result * arg;
+}
+
+float normaldotproduct(XYZ point1, XYZ point2){
+ GLfloat returnvalue;
+ Normalise(&point1);
+ Normalise(&point2);
+ returnvalue=(point1.x*point2.x+point1.y*point2.y+point1.z*point2.z);
+ return returnvalue;
+}
+
+extern float u0, u1, u2;
+extern float v0, v1, v2;
+extern float a, b;
+extern float max;
+extern int i, j;
+extern bool bInter;
+extern float pointv[3];
+extern float p1v[3];
+extern float p2v[3];
+extern float p3v[3];
+extern float normalv[3];
+
+bool PointInTriangle(Vector *p, Vector normal, float p11, float p12, float p13, float p21, float p22, float p23, float p31, float p32, float p33)
+{
+ bInter=0;
+
+ pointv[0]=p->x;
+ pointv[1]=p->y;
+ pointv[2]=p->z;
+
+
+ p1v[0]=p11;
+ p1v[1]=p12;
+ p1v[2]=p13;
+
+ p2v[0]=p21;
+ p2v[1]=p22;
+ p2v[2]=p23;
+
+ p3v[0]=p31;
+ p3v[1]=p32;
+ p3v[2]=p33;
+
+ normalv[0]=normal.x;
+ normalv[1]=normal.y;
+ normalv[2]=normal.z;
+
+#define ABS(X) (((X)<0.f)?-(X):(X) )
+#define MAX(A, B) (((A)<(B))?(B):(A))
+ max = MAX(MAX(ABS(normalv[0]), ABS(normalv[1])), ABS(normalv[2]));
+#undef MAX
+ if (max == ABS(normalv[0])) {i = 1; j = 2;} // y, z
+ if (max == ABS(normalv[1])) {i = 0; j = 2;} // x, z
+ if (max == ABS(normalv[2])) {i = 0; j = 1;} // x, y
+#undef ABS
+
+ u0 = pointv[i] - p1v[i];
+ v0 = pointv[j] - p1v[j];
+ u1 = p2v[i] - p1v[i];
+ v1 = p2v[j] - p1v[j];
+ u2 = p3v[i] - p1v[i];
+ v2 = p3v[j] - p1v[j];
+
+ if (u1 > -1.0e-05f && u1 < 1.0e-05f)// == 0.0f)
+ {
+ b = u0 / u2;
+ if (0.0f <= b && b <= 1.0f)
+ {
+ a = (v0 - b * v2) / v1;
+ if ((a >= 0.0f) && (( a + b ) <= 1.0f))
+ bInter = 1;
+ }
+ }
+ else
+ {
+ b = (v0 * u1 - u0 * v1) / (v2 * u1 - u2 * v1);
+ if (0.0f <= b && b <= 1.0f)
+ {
+ a = (u0 - b * u2) / u1;
+ if ((a >= 0.0f) && (( a + b ) <= 1.0f ))
+ bInter = 1;
+ }
+ }
+
+ return bInter;
+}
+
+bool LineFacet(Vector p1,Vector p2,Vector pa,Vector pb,Vector pc,Vector *p)
+{
+ float d;
+ float a1,a2,a3;
+ float total,denom,mu;
+ Vector n,pa1,pa2,pa3;
+
+ //Calculate the parameters for the plane
+ n.x = (pb.y - pa.y)*(pc.z - pa.z) - (pb.z - pa.z)*(pc.y - pa.y);
+ n.y = (pb.z - pa.z)*(pc.x - pa.x) - (pb.x - pa.x)*(pc.z - pa.z);
+ n.z = (pb.x - pa.x)*(pc.y - pa.y) - (pb.y - pa.y)*(pc.x - pa.x);
+ n.Normalize();
+ d = - n.x * pa.x - n.y * pa.y - n.z * pa.z;
+
+ //Calculate the position on the line that intersects the plane
+ denom = n.x * (p2.x - p1.x) + n.y * (p2.y - p1.y) + n.z * (p2.z - p1.z);
+ if (abs(denom) < 0.0000001) // Line and plane don't intersect
+ return 0;
+ mu = - (d + n.x * p1.x + n.y * p1.y + n.z * p1.z) / denom;
+ p->x = p1.x + mu * (p2.x - p1.x);
+ p->y = p1.y + mu * (p2.y - p1.y);
+ p->z = p1.z + mu * (p2.z - p1.z);
+ if (mu < 0 || mu > 1) // Intersection not along line segment
+ return 0;
+
+ if(!PointInTriangle( p, n, pa.x, pa.y, pa.z, pb.x, pb.y, pb.z, pc.x, pc.y, pc.z)){return 0;}
+
+ return 1;
+}
+
+bool PointInTriangle(XYZ *p, XYZ normal, XYZ *p1, XYZ *p2, XYZ *p3)
+{
+ bInter=0;
+
+ pointv[0]=p->x;
+ pointv[1]=p->y;
+ pointv[2]=p->z;
+
+
+ p1v[0]=p1->x;
+ p1v[1]=p1->y;
+ p1v[2]=p1->z;
+
+ p2v[0]=p2->x;
+ p2v[1]=p2->y;
+ p2v[2]=p2->z;
+
+ p3v[0]=p3->x;
+ p3v[1]=p3->y;
+ p3v[2]=p3->z;
+
+ normalv[0]=normal.x;
+ normalv[1]=normal.y;
+ normalv[2]=normal.z;
+
+#define ABS(X) (((X)<0.f)?-(X):(X) )
+#define MAX(A, B) (((A)<(B))?(B):(A))
+ max = MAX(MAX(ABS(normalv[0]), ABS(normalv[1])), ABS(normalv[2]));
+#undef MAX
+ if (max == ABS(normalv[0])) {i = 1; j = 2;} // y, z
+ if (max == ABS(normalv[1])) {i = 0; j = 2;} // x, z
+ if (max == ABS(normalv[2])) {i = 0; j = 1;} // x, y
+#undef ABS
+
+ u0 = pointv[i] - p1v[i];
+ v0 = pointv[j] - p1v[j];
+ u1 = p2v[i] - p1v[i];
+ v1 = p2v[j] - p1v[j];
+ u2 = p3v[i] - p1v[i];
+ v2 = p3v[j] - p1v[j];
+
+ if (u1 > -1.0e-05f && u1 < 1.0e-05f)// == 0.0f)
+ {
+ b = u0 / u2;
+ if (0.0f <= b && b <= 1.0f)
+ {
+ a = (v0 - b * v2) / v1;
+ if ((a >= 0.0f) && (( a + b ) <= 1.0f))
+ bInter = 1;
+ }
+ }
+ else
+ {
+ b = (v0 * u1 - u0 * v1) / (v2 * u1 - u2 * v1);
+ if (0.0f <= b && b <= 1.0f)
+ {
+ a = (u0 - b * u2) / u1;
+ if ((a >= 0.0f) && (( a + b ) <= 1.0f ))
+ bInter = 1;
+ }
+ }
+
+ return bInter;
+}
+
+bool LineFacet(XYZ p1,XYZ p2,XYZ pa,XYZ pb,XYZ pc,XYZ *p)
+{
+ float d;
+ float a1,a2,a3;
+ float total,denom,mu;
+ XYZ n,pa1,pa2,pa3;
+
+ //Calculate the parameters for the plane
+ n.x = (pb.y - pa.y)*(pc.z - pa.z) - (pb.z - pa.z)*(pc.y - pa.y);
+ n.y = (pb.z - pa.z)*(pc.x - pa.x) - (pb.x - pa.x)*(pc.z - pa.z);
+ n.z = (pb.x - pa.x)*(pc.y - pa.y) - (pb.y - pa.y)*(pc.x - pa.x);
+ Normalise(&n);
+ d = - n.x * pa.x - n.y * pa.y - n.z * pa.z;
+
+ //Calculate the position on the line that intersects the plane
+ denom = n.x * (p2.x - p1.x) + n.y * (p2.y - p1.y) + n.z * (p2.z - p1.z);
+ if (abs(denom) < 0.0000001) // Line and plane don't intersect
+ return 0;
+ mu = - (d + n.x * p1.x + n.y * p1.y + n.z * p1.z) / denom;
+ p->x = p1.x + mu * (p2.x - p1.x);
+ p->y = p1.y + mu * (p2.y - p1.y);
+ p->z = p1.z + mu * (p2.z - p1.z);
+ if (mu < 0 || mu > 1) // Intersection not along line segment
+ return 0;
+
+ if(!PointInTriangle( p, n, &pa, &pb, &pc)){return 0;}
+
+ return 1;
+}
+
+extern float d;
+extern float a1,a2,a3;
+extern float total,denom,mu;
+extern XYZ pa1,pa2,pa3,n;
+
+float LineFacetd(XYZ p1,XYZ p2,XYZ pa,XYZ pb,XYZ pc,XYZ *p)
+{
+
+ //Calculate the parameters for the plane
+ n.x = (pb.y - pa.y)*(pc.z - pa.z) - (pb.z - pa.z)*(pc.y - pa.y);
+ n.y = (pb.z - pa.z)*(pc.x - pa.x) - (pb.x - pa.x)*(pc.z - pa.z);
+ n.z = (pb.x - pa.x)*(pc.y - pa.y) - (pb.y - pa.y)*(pc.x - pa.x);
+ Normalise(&n);
+ d = - n.x * pa.x - n.y * pa.y - n.z * pa.z;
+
+ //Calculate the position on the line that intersects the plane
+ denom = n.x * (p2.x - p1.x) + n.y * (p2.y - p1.y) + n.z * (p2.z - p1.z);
+ if (abs(denom) < 0.0000001) // Line and plane don't intersect
+ return 0;
+ mu = - (d + n.x * p1.x + n.y * p1.y + n.z * p1.z) / denom;
+ p->x = p1.x + mu * (p2.x - p1.x);
+ p->y = p1.y + mu * (p2.y - p1.y);
+ p->z = p1.z + mu * (p2.z - p1.z);
+ if (mu < 0 || mu > 1) // Intersection not along line segment
+ return 0;
+
+ if(!PointInTriangle( p, n, &pa, &pb, &pc)){return 0;}
+
+ return 1;
+}
+
+float LineFacetd(XYZ p1,XYZ p2,XYZ pa,XYZ pb,XYZ pc, XYZ n, XYZ *p)
+{
+
+ //Calculate the parameters for the plane
+ d = - n.x * pa.x - n.y * pa.y - n.z * pa.z;
+
+ //Calculate the position on the line that intersects the plane
+ denom = n.x * (p2.x - p1.x) + n.y * (p2.y - p1.y) + n.z * (p2.z - p1.z);
+ if (abs(denom) < 0.0000001) // Line and plane don't intersect
+ return 0;
+ mu = - (d + n.x * p1.x + n.y * p1.y + n.z * p1.z) / denom;
+ p->x = p1.x + mu * (p2.x - p1.x);
+ p->y = p1.y + mu * (p2.y - p1.y);
+ p->z = p1.z + mu * (p2.z - p1.z);
+ if (mu < 0 || mu > 1) // Intersection not along line segment
+ return 0;
+
+ if(!PointInTriangle( p, n, &pa, &pb, &pc)){return 0;}
+ return 1;
+}
+
+float LineFacetd(XYZ *p1,XYZ *p2,XYZ *pa,XYZ *pb,XYZ *pc, XYZ *n, XYZ *p)
+{
+
+ //Calculate the parameters for the plane
+ d = - n->x * pa->x - n->y * pa->y - n->z * pa->z;
+
+ //Calculate the position on the line that intersects the plane
+ denom = n->x * (p2->x - p1->x) + n->y * (p2->y - p1->y) + n->z * (p2->z - p1->z);
+ if (abs(denom) < 0.0000001) // Line and plane don't intersect
+ return 0;
+ mu = - (d + n->x * p1->x + n->y * p1->y + n->z * p1->z) / denom;
+ p->x = p1->x + mu * (p2->x - p1->x);
+ p->y = p1->y + mu * (p2->y - p1->y);
+ p->z = p1->z + mu * (p2->z - p1->z);
+ if (mu < 0 || mu > 1) // Intersection not along line segment
+ return 0;
+
+ if(!PointInTriangle( p, *n, pa, pb, pc)){return 0;}
+ return 1;
+}
+
+void ReflectVector(XYZ *vel, XYZ *n)
+{
+ XYZ vn;
+ XYZ vt;
+ float dotprod;
+
+ dotprod=dotproduct(*n,*vel);
+ vn.x=n->x*dotprod;
+ vn.y=n->y*dotprod;
+ vn.z=n->z*dotprod;
+
+ vt.x=vel->x-vn.x;
+ vt.y=vel->y-vn.y;
+ vt.z=vel->z-vn.z;
+
+ vel->x = vt.x - vn.x;
+ vel->y = vt.y - vn.y;
+ vel->z = vt.z - vn.z;
+}
+
+float dotproduct(XYZ point1, XYZ point2){
+ GLfloat returnvalue;
+ returnvalue=(point1.x*point2.x+point1.y*point2.y+point1.z*point2.z);
+ return returnvalue;
+}
+
+float findDistance(XYZ point1, XYZ point2){
+ return(fast_sqrt((point1.x-point2.x)*(point1.x-point2.x)+(point1.y-point2.y)*(point1.y-point2.y)+(point1.z-point2.z)*(point1.z-point2.z)));
+}
+
+float findLength(XYZ point1){
+ return(fast_sqrt((point1.x)*(point1.x)+(point1.y)*(point1.y)+(point1.z)*(point1.z)));
+}
+
+
+float findLengthfast(XYZ point1){
+ return((point1.x)*(point1.x)+(point1.y)*(point1.y)+(point1.z)*(point1.z));
+}
+
+float findDistancefast(XYZ point1, XYZ point2){
+ return((point1.x-point2.x)*(point1.x-point2.x)+(point1.y-point2.y)*(point1.y-point2.y)+(point1.z-point2.z)*(point1.z-point2.z));
+}
+
+XYZ DoRotation(XYZ thePoint, float xang, float yang, float zang){
+ XYZ newpoint;
+ if(xang){
+ xang*=6.283185;
+ xang/=360;
+ }
+ if(yang){
+ yang*=6.283185;
+ yang/=360;
+ }
+ if(zang){
+ zang*=6.283185;
+ zang/=360;
+ }
+
+
+ if(yang){
+ newpoint.z=thePoint.z*cos(yang)-thePoint.x*sin(yang);
+ newpoint.x=thePoint.z*sin(yang)+thePoint.x*cos(yang);
+ thePoint.z=newpoint.z;
+ thePoint.x=newpoint.x;
+ }
+
+ if(zang){
+ newpoint.x=thePoint.x*cos(zang)-thePoint.y*sin(zang);
+ newpoint.y=thePoint.y*cos(zang)+thePoint.x*sin(zang);
+ thePoint.x=newpoint.x;
+ thePoint.y=newpoint.y;
+ }
+
+ if(xang){
+ newpoint.y=thePoint.y*cos(xang)-thePoint.z*sin(xang);
+ newpoint.z=thePoint.y*sin(xang)+thePoint.z*cos(xang);
+ thePoint.z=newpoint.z;
+ thePoint.y=newpoint.y;
+ }
+
+ return thePoint;
+}
+
+float square( float f ) { return (f*f) ;}
+
+bool sphere_line_intersection (
+ float x1, float y1 , float z1,
+ float x2, float y2 , float z2,
+ float x3, float y3 , float z3, float r )
+{
+
+ // x1,y1,z1 P1 coordinates (point of line)
+ // x2,y2,z2 P2 coordinates (point of line)
+ // x3,y3,z3, r P3 coordinates and radius (sphere)
+ // x,y,z intersection coordinates
+ //
+ // This function returns a pointer array which first index indicates
+ // the number of intersection point, followed by coordinate pairs.
+
+ float x , y , z;
+ float a, b, c, mu, i ;
+
+ if(x1>x3+r&&x2>x3+r)return(0);
+ if(x1<x3-r&&x2<x3-r)return(0);
+ if(y1>y3+r&&y2>y3+r)return(0);
+ if(y1<y3-r&&y2<y3-r)return(0);
+ if(z1>z3+r&&z2>z3+r)return(0);
+ if(z1<z3-r&&z2<z3-r)return(0);
+ a = square(x2 - x1) + square(y2 - y1) + square(z2 - z1);
+ b = 2* ( (x2 - x1)*(x1 - x3)
+ + (y2 - y1)*(y1 - y3)
+ + (z2 - z1)*(z1 - z3) ) ;
+ c = square(x3) + square(y3) +
+ square(z3) + square(x1) +
+ square(y1) + square(z1) -
+ 2* ( x3*x1 + y3*y1 + z3*z1 ) - square(r) ;
+ i = b * b - 4 * a * c ;
+
+ if ( i < 0.0 )
+ {
+ // no intersection
+ return(0);
+ }
+ if ( i >= 0.0 )
+ {
+ return(1);
+ }
+}
+
+XYZ DoRotationRadian(XYZ thePoint, float xang, float yang, float zang){
+ XYZ newpoint;
+ XYZ oldpoint;
+
+ oldpoint=thePoint;
+
+ if(yang!=0){
+ newpoint.z=oldpoint.z*cos(yang)-oldpoint.x*sin(yang);
+ newpoint.x=oldpoint.z*sin(yang)+oldpoint.x*cos(yang);
+ oldpoint.z=newpoint.z;
+ oldpoint.x=newpoint.x;
+ }
+
+ if(zang!=0){
+ newpoint.x=oldpoint.x*cos(zang)-oldpoint.y*sin(zang);
+ newpoint.y=oldpoint.y*cos(zang)+oldpoint.x*sin(zang);
+ oldpoint.x=newpoint.x;
+ oldpoint.y=newpoint.y;
+ }
+
+ if(xang!=0){
+ newpoint.y=oldpoint.y*cos(xang)-oldpoint.z*sin(xang);
+ newpoint.z=oldpoint.y*sin(xang)+oldpoint.z*cos(xang);
+ oldpoint.z=newpoint.z;
+ oldpoint.y=newpoint.y;
+ }
+
+ return oldpoint;
+
+} \ No newline at end of file
diff --git a/Source/Quaternions.h b/Source/Quaternions.h
new file mode 100644
index 0000000..bdc0642
--- /dev/null
+++ b/Source/Quaternions.h
@@ -0,0 +1,87 @@
+
+#ifndef _QUATERNIONS_H_
+#define _QUATERNIONS_H_
+
+#pragma mark -
+
+#include "Maths.h"
+#include <gl.h>
+#include "PhysicsMath.h"
+
+/**> Quaternion Structures <**/
+#define PI 3.14159265355555897932384626
+#define RADIANS 0
+#define DEGREES 1
+#define deg2rad .0174532925
+
+using namespace std;
+typedef float Matrix_t [4][4];
+struct euler
+{
+ float x, y, z;
+};
+struct angle_axis
+{
+ float x, y, z, angle;
+};
+struct quaternion
+{
+ float x, y, z, w;
+};
+
+class XYZ{
+ public:
+ float x;
+ float y;
+ float z;
+ XYZ operator+(XYZ add);
+ XYZ operator-(XYZ add);
+ XYZ operator*(float add);
+ XYZ operator*(XYZ add);
+ XYZ operator/(float add);
+ void operator+=(XYZ add);
+ void operator-=(XYZ add);
+ void operator*=(float add);
+ void operator*=(XYZ add);
+ void operator/=(float add);
+ void operator=(float add);
+ void vec(Vector add);
+ bool operator==(XYZ add);
+};
+
+/*********************> Quaternion Function definition <********/
+quaternion To_Quat(int Degree_Flag, euler Euler);
+quaternion To_Quat(angle_axis Ang_Ax);
+quaternion To_Quat(Matrix_t m);
+angle_axis Quat_2_AA(quaternion Quat);
+void Quat_2_Matrix(quaternion Quat, Matrix_t m);
+quaternion Normalize(quaternion Quat);
+quaternion Quat_Mult(quaternion q1, quaternion q2);
+quaternion QNormalize(quaternion Quat);
+XYZ Quat2Vector(quaternion Quat);
+
+void CrossProduct(XYZ P, XYZ Q, XYZ *V);
+void Normalise(XYZ *vectory);
+float normaldotproduct(XYZ point1, XYZ point2);
+float fast_sqrt (register float arg);
+bool PointInTriangle(XYZ *p, XYZ normal, XYZ *p1, XYZ *p2, XYZ *p3);
+bool LineFacet(XYZ p1,XYZ p2,XYZ pa,XYZ pb,XYZ pc,XYZ *p);
+float LineFacetd(XYZ p1,XYZ p2,XYZ pa,XYZ pb,XYZ pc,XYZ *p);
+float LineFacetd(XYZ p1,XYZ p2,XYZ pa,XYZ pb,XYZ pc,XYZ n, XYZ *p);
+float LineFacetd(XYZ *p1,XYZ *p2,XYZ *pa,XYZ *pb,XYZ *pc,XYZ *n, XYZ *p);
+bool PointInTriangle(Vector *p, Vector normal, float p11, float p12, float p13, float p21, float p22, float p23, float p31, float p32, float p33);
+bool LineFacet(Vector p1,Vector p2,Vector pa,Vector pb,Vector pc,Vector *p);
+void ReflectVector(XYZ *vel, XYZ *n);
+XYZ DoRotation(XYZ thePoint, float xang, float yang, float zang);
+XYZ DoRotationRadian(XYZ thePoint, float xang, float yang, float zang);
+float findDistance(XYZ point1, XYZ point2);
+float findLength(XYZ point1);
+float findLengthfast(XYZ point1);
+float findDistancefast(XYZ point1, XYZ point2);
+float dotproduct(XYZ point1, XYZ point2);
+bool sphere_line_intersection (
+ float x1, float y1 , float z1,
+ float x2, float y2 , float z2,
+ float x3, float y3 , float z3, float r );
+
+#endif \ No newline at end of file
diff --git a/Source/Skeleton.cpp b/Source/Skeleton.cpp
new file mode 100644
index 0000000..041d07a
--- /dev/null
+++ b/Source/Skeleton.cpp
@@ -0,0 +1,841 @@
+/**> HEADER FILES <**/
+#include "Skeleton.h"
+
+extern double multiplier;
+extern unsigned int gSourceID[100];
+extern unsigned int gSampleSet[100];
+extern int visions;
+extern float rad2deg;
+extern Camera camera;
+extern float soundscalefactor;
+
+extern XYZ vel;
+extern XYZ midp;
+extern XYZ newpoint1,newpoint2;
+
+extern float oldlength;
+extern float relaxlength;
+
+extern float friction;
+extern int numrepeats;
+extern float groundlevel;
+extern float offset;
+extern XYZ impact;
+extern XYZ overpoint;
+extern XYZ underpoint;
+extern int whichtri;
+extern XYZ normalrotated;
+extern bool groundish;
+
+
+void Joint::DoConstraint()
+{
+
+ if(hasparent){
+ //Find midpoint
+ midp=(position+parent->position)/2;
+ //Find vector from midpoint to second vector
+ vel=parent->position-midp;
+ //Change to unit vector
+ Normalise(&vel);
+ //Apply velocity change
+ velocity+=((midp-vel*length/2)-position);
+ parent->velocity+=((midp+vel*length/2)-parent->position);
+ //Move child point to within certain distance of parent point
+ if(!locked)position=midp-vel*length/2;
+ if(!parent->locked)parent->position=midp+vel*length/2;
+ }
+}
+
+void Muscle::DoConstraint(int broken)
+{
+ oldlength=length;
+ relaxlength=findDistance(parent1->position,parent2->position);
+
+ if(type==boneconnect)strength=1;
+ if(type==constraint)strength=0;
+
+ if(strength<0)strength=0;
+ if(strength>1)strength=1;
+
+ length-=(length-relaxlength)*(1-strength)*multiplier*multiplier*10000;
+ length-=(length-targetlength)*(strength)*multiplier*multiplier*10000;
+ if(strength==0)length=relaxlength;
+
+ if((relaxlength-length>0&&relaxlength-oldlength<0)||(relaxlength-length<0&&relaxlength-oldlength>0))length=relaxlength;
+
+ if(length<minlength)length=minlength;
+ if(length>maxlength&&!broken)length=maxlength;
+
+ //Find midpoint
+ midp=(parent1->position+parent2->position)/2;
+ //Find vector from midpoint to second vector
+ vel=parent2->position-midp;
+ //Change to unit vector
+ Normalise(&vel);
+ //Apply velocity change
+ newpoint1=midp-vel*length/2;
+ newpoint2=midp+vel*length/2;
+ parent1->velocity+=(newpoint1-parent1->position);
+ parent2->velocity+=(newpoint2-parent2->position);
+ //Move child point to within certain distance of parent point
+ if(!parent1->locked)parent1->position=newpoint1;
+ if(!parent2->locked)parent2->position=newpoint2;
+}
+
+void Skeleton::DoConstraints()
+{
+ numrepeats=3;
+
+ for(int j=0; j<numrepeats; j++){
+ for(int i=0; i<num_joints; i++){
+ joints[i].DoConstraint();
+ }
+ }
+}
+
+void Skeleton::DoConstraints(Model *collide, XYZ *move, float rotation)
+{
+ friction=20;
+ numrepeats=2;
+ groundlevel=0;
+
+ move->y+=.35;
+
+ for(int j=0; j<numrepeats; j++){
+ for(int i=0; i<num_joints; i++){
+ if(joints[i].existing||i==jointlabels[lefthand]||i==jointlabels[righthand]){
+ //Length constraints
+ joints[i].DoConstraint();
+ //Ground constraint
+ offset=0;
+ overpoint=joints[i].position;
+ overpoint.y+=10;
+ underpoint=joints[i].position;
+ underpoint.y-=offset;
+ whichtri=collide->LineCheck2(overpoint,underpoint,&impact,*move,rotation);
+ if(collide->normals[whichtri].y<=.8)whichtri=collide->LineCheck2(joints[i].realoldposition,joints[i].position,&impact,*move,rotation);
+ if(joints[i].position.y<=groundlevel+offset||whichtri!=-1){
+ if(whichtri==-1||(whichtri!=-1&&collide->normals[whichtri].y>.8)){
+ if(whichtri==-1)joints[i].position.y=groundlevel+offset;
+ if(whichtri!=-1){
+ joints[i].position=impact;
+ joints[i].position.y+=offset;
+ }
+ joints[i].velocity.y*=-.3;
+ joints[i].velocity.x*=.3;
+ joints[i].velocity.z*=.3;
+ }
+ offset=.2;
+ if(whichtri!=-1&&collide->normals[whichtri].y<=.8){
+ normalrotated=DoRotation(collide->normals[whichtri],0,rotation,0);
+ joints[i].position=impact+normalrotated*offset;
+ ReflectVector(&joints[i].velocity,&normalrotated);
+ joints[i].velocity*=.3;
+ }
+ if(broken<=1){
+ XYZ avgvelocity;
+ avgvelocity=0;
+ float gLoc[3];
+ ALint tempint;
+ for(int k=0; k<num_joints; k++){
+ avgvelocity+=joints[k].velocity;
+ }
+ avgvelocity/=num_joints;
+ if(joints[i].label==head&&(findLengthfast(joints[i].velocity)>2||findLengthfast(avgvelocity)>2)){
+ avgvelocity+=joints[i].velocity;
+ gLoc[0]=joints[i].position.x/soundscalefactor;
+ gLoc[1]=joints[i].position.y/soundscalefactor;
+ gLoc[2]=joints[i].position.z/soundscalefactor;
+ alGetSourcei(gSourceID[headlandsound], AL_SOURCE_STATE, &tempint);
+ if (tempint != AL_PLAYING){
+ alSourcef(gSourceID[headlandsound], AL_MIN_GAIN, ALfloat(findLengthfast(avgvelocity)*2/findDistancefast(joints[i].position,camera.position)*soundscalefactor*2));
+ alSourcef(gSourceID[headlandsound], AL_MAX_GAIN, ALfloat(findLengthfast(avgvelocity)*2/findDistancefast(joints[i].position,camera.position)*soundscalefactor*2));
+ alSourcefv(gSourceID[headlandsound], AL_POSITION, gLoc);
+ alSourcePlay(gSourceID[headlandsound]);}
+ }
+ avgvelocity=0;
+ for(int k=0; k<num_joints; k++){
+ avgvelocity+=joints[k].velocity;
+ }
+ avgvelocity/=num_joints;
+ if((joints[i].label==abdomen)&&(findLengthfast(joints[i].velocity)>2||findLengthfast(avgvelocity)>2)){
+ avgvelocity+=joints[i].velocity;
+ gLoc[0]=joints[i].position.x/soundscalefactor;
+ gLoc[1]=joints[i].position.y/soundscalefactor;
+ gLoc[2]=joints[i].position.z/soundscalefactor;
+ alGetSourcei(gSourceID[bodylandsound], AL_SOURCE_STATE, &tempint);
+ if (tempint != AL_PLAYING){
+ alSourcef(gSourceID[bodylandsound], AL_MIN_GAIN, ALfloat(findLengthfast(joints[i].velocity)*1/findDistancefast(joints[i].position,camera.position)*soundscalefactor*2));
+ alSourcef(gSourceID[bodylandsound], AL_MAX_GAIN, ALfloat(findLengthfast(joints[i].velocity)*1/findDistancefast(joints[i].position,camera.position)*soundscalefactor*2));
+ alSourcefv(gSourceID[bodylandsound], AL_POSITION, gLoc);
+ alSourcePlay(gSourceID[bodylandsound]);}
+ }
+ }
+ }}
+ }
+ if(num_muscles)
+ for(int i=0; i<num_muscles; i++){
+ //Length constraints
+ muscles[i].DoConstraint(broken);
+ }
+ }
+
+ for(int i=0; i<num_joints; i++){
+ joints[i].realoldposition=joints[i].position;
+ }
+
+ //Add velocity
+ for(int i=0; i<num_joints; i++){
+ if(joints[i].existing||i==jointlabels[lefthand]||i==jointlabels[righthand])joints[i].position=joints[i].position+joints[i].velocity*multiplier;
+ }
+}
+
+void Skeleton::DoGravity()
+{
+ for(int i=0; i<num_joints; i++){
+ joints[i].velocity.y+=gravity*multiplier;
+ }
+}
+
+void Skeleton::Draw(int muscleview)
+{
+ float jointcolor[4];
+
+ if(muscleview!=2){
+ jointcolor[0]=0;
+ jointcolor[1]=0;
+ jointcolor[2]=.5;
+ jointcolor[3]=1;
+ }
+
+ if(muscleview==2){
+ jointcolor[0]=0;
+ jointcolor[1]=0;
+ jointcolor[2]=0;
+ jointcolor[3]=.5;
+ }
+ //Calc motionblur-ness
+ for(int i=0; i<num_joints; i++){
+ joints[i].oldposition=joints[i].position;
+ joints[i].blurred=findDistance(joints[i].position,joints[i].oldposition)*100;
+ if(joints[i].blurred<1)joints[i].blurred=1;
+ }
+
+ //Do Motionblur
+ glDepthMask(0);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+ glBegin(GL_QUADS);
+ for(int i=0; i<num_joints; i++){
+ if(joints[i].hasparent){
+ glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].blurred);
+ glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
+ glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].parent->blurred);
+ glVertex3f(joints[i].parent->position.x,joints[i].parent->position.y,joints[i].parent->position.z);
+ glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].parent->blurred);
+ glVertex3f(joints[i].parent->oldposition.x,joints[i].parent->oldposition.y,joints[i].parent->oldposition.z);
+ glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].blurred);
+ glVertex3f(joints[i].oldposition.x,joints[i].oldposition.y,joints[i].oldposition.z);
+ }
+ }
+ for(int i=0; i<num_muscles; i++){
+ if(muscles[i].type==boneconnect){
+ glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
+ glVertex3f(muscles[i].parent1->position.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z);
+ glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
+ glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z);
+ glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
+ glVertex3f(muscles[i].parent2->oldposition.x,muscles[i].parent2->oldposition.y,muscles[i].parent2->oldposition.z);
+ glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent1->blurred);
+ glVertex3f(muscles[i].parent1->oldposition.x,muscles[i].parent1->oldposition.y,muscles[i].parent1->oldposition.z);
+ }
+ }
+ glEnd();
+
+ glBegin(GL_LINES);
+ for(int i=0; i<num_joints; i++){
+ if(joints[i].hasparent){
+ glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].blurred);
+ glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
+ glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/joints[i].parent->blurred);
+ glVertex3f(joints[i].parent->position.x,joints[i].parent->position.y,joints[i].parent->position.z);
+ }
+ }
+ for(int i=0; i<num_muscles; i++){
+ if(muscles[i].type==boneconnect){
+ glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent1->blurred);
+ glVertex3f(muscles[i].parent1->position.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z);
+ glColor4f(jointcolor[0],jointcolor[1],jointcolor[2],jointcolor[3]/muscles[i].parent2->blurred);
+ glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z);
+ }
+ }
+ glColor3f(.6,.6,0);
+ if(muscleview==1)
+ for(int i=0; i<num_muscles; i++){
+ if(muscles[i].type!=boneconnect){
+ glVertex3f(muscles[i].parent1->position.x,muscles[i].parent1->position.y,muscles[i].parent1->position.z);
+ glVertex3f(muscles[i].parent2->position.x,muscles[i].parent2->position.y,muscles[i].parent2->position.z);
+ }
+ }
+ glEnd();
+
+ if(muscleview!=2){
+ glPointSize(3);
+ glBegin(GL_POINTS);
+ for(int i=0; i<num_joints; i++){
+ if(i!=selected)glColor4f(0,0,.5,1);
+ if(i==selected)glColor4f(1,1,0,1);
+ if(joints[i].locked&&i!=selected)glColor4f(1,0,0,1);
+ glVertex3f(joints[i].position.x,joints[i].position.y,joints[i].position.z);
+ }
+ glEnd();
+ }
+
+ //Set old position to current position
+ if(muscleview==2)
+ for(int i=0; i<num_joints; i++){
+ joints[i].oldposition=joints[i].position;
+ }
+ glDepthMask(1);
+}
+
+void Skeleton::AddJoint(float x, float y, float z, int which)
+{
+ if(num_joints<max_joints-1){
+ joints[num_joints].velocity=0;
+ joints[num_joints].position.x=x;
+ joints[num_joints].position.y=y;
+ joints[num_joints].position.z=z;
+ joints[num_joints].locked=0;
+
+ if(which>=num_joints||which<0)joints[num_joints].hasparent=0;
+ if(which<num_joints&&which>=0){
+ joints[num_joints].parent=&joints[which];
+ joints[num_joints].hasparent=1;
+ joints[num_joints].length=findDistance(joints[num_joints].position,joints[num_joints].parent->position);
+ }
+ num_joints++;
+ }
+}
+
+void Skeleton::DeleteJoint(int whichjoint)
+{
+ if(whichjoint<num_joints&&whichjoint>=0){
+ for(int i=0;i<num_muscles;i++){
+ while(muscles[i].parent1==&joints[whichjoint]&&i<num_muscles)DeleteMuscle(i);
+ while(muscles[i].parent2==&joints[whichjoint]&&i<num_muscles)DeleteMuscle(i);
+ }
+ for(int i=0;i<num_joints;i++){
+ if(joints[i].parent==&joints[whichjoint])joints[i].hasparent=0;
+ }
+ joints[whichjoint].hasparent=0;
+ }
+}
+
+void Skeleton::DeleteMuscle(int whichmuscle)
+{
+ if(whichmuscle<num_muscles){
+ muscles[whichmuscle].minlength=muscles[num_muscles-1].minlength;
+ muscles[whichmuscle].maxlength=muscles[num_muscles-1].maxlength;
+ muscles[whichmuscle].strength=muscles[num_muscles-1].strength;
+ muscles[whichmuscle].parent1=muscles[num_muscles-1].parent1;
+ muscles[whichmuscle].parent2=muscles[num_muscles-1].parent2;
+ muscles[whichmuscle].length=muscles[num_muscles-1].length;
+ muscles[whichmuscle].visible=muscles[num_muscles-1].visible;
+ muscles[whichmuscle].type=muscles[num_muscles-1].type;
+ muscles[whichmuscle].targetlength=muscles[num_muscles-1].targetlength;
+
+ num_muscles--;
+ }
+}
+
+void Skeleton::SetJoint(float x, float y, float z, int which, int whichjoint)
+{
+ if(whichjoint<num_joints){
+ joints[whichjoint].velocity=0;
+ joints[whichjoint].position.x=x;
+ joints[whichjoint].position.y=y;
+ joints[whichjoint].position.z=z;
+
+ if(which>=num_joints||which<0)joints[whichjoint].hasparent=0;
+ if(which<num_joints&&which>=0){
+ joints[whichjoint].parent=&joints[which];
+ joints[whichjoint].hasparent=1;
+ joints[whichjoint].length=findDistance(joints[whichjoint].position,joints[whichjoint].parent->position);
+ }
+ }
+}
+
+void Skeleton::AddMuscle(int attach1,int attach2,float minlength,float maxlength,int type)
+{
+ if(num_muscles<max_muscles-1&&attach1<num_joints&&attach1>=0&attach2<num_joints&&attach2>=0&&attach1!=attach2){
+ muscles[num_muscles].parent1=&joints[attach1];
+ muscles[num_muscles].parent2=&joints[attach2];
+ muscles[num_muscles].length=findDistance(muscles[num_muscles].parent1->position,muscles[num_muscles].parent2->position);
+ muscles[num_muscles].targetlength=findDistance(muscles[num_muscles].parent1->position,muscles[num_muscles].parent2->position);
+ muscles[num_muscles].strength=.7;
+ muscles[num_muscles].type=type;
+ muscles[num_muscles].minlength=minlength;
+ muscles[num_muscles].maxlength=maxlength;
+
+ num_muscles++;
+ }
+}
+
+void Skeleton::MusclesSet()
+{
+ for(int i=0;i<num_muscles;i++){
+ muscles[i].length=findDistance(muscles[i].parent1->position,muscles[i].parent2->position);
+ }
+}
+
+void Skeleton::FindRotationJoint(int which)
+{
+ XYZ temppoint1,temppoint2,tempforward;
+ float distance;
+
+ temppoint1=joints[which].position;
+ temppoint2=joints[which].parent->position;
+ distance=findDistance(temppoint1,temppoint2);
+ joints[which].rotate2=asin((temppoint1.y-temppoint2.y)/distance)*rad2deg;
+ temppoint1.y=0;
+ temppoint2.y=0;
+ joints[which].rotate1=acos((temppoint1.z-temppoint2.z)/findDistance(temppoint1,temppoint2))*rad2deg;
+ if(temppoint1.x>temppoint2.x)joints[which].rotate1=360-joints[which].rotate1;
+ if(joints[which].label==head)tempforward=specialforward[0];
+ else if(joints[which].label==rightshoulder||joints[which].label==rightelbow||joints[which].label==rightwrist||joints[which].label==righthand)tempforward=specialforward[1];
+ else if(joints[which].label==leftshoulder||joints[which].label==leftelbow||joints[which].label==leftwrist||joints[which].label==lefthand)tempforward=specialforward[2];
+ else if(joints[which].label==righthip||joints[which].label==rightknee||joints[which].label==rightankle)tempforward=specialforward[3];
+ else if(joints[which].label==lefthip||joints[which].label==leftknee||joints[which].label==leftankle)tempforward=specialforward[4];
+ else if(!joints[which].lower)tempforward=forward;
+ else if(joints[which].lower)tempforward=lowforward;
+ tempforward=DoRotation(tempforward,0,joints[which].rotate1-90,0);
+ tempforward=DoRotation(tempforward,0,0,joints[which].rotate2-90);
+ tempforward.y=0;
+ Normalise(&tempforward);
+ joints[which].rotate3=acos(0-tempforward.z)*rad2deg;
+ if(0>tempforward.x)joints[which].rotate3=360-joints[which].rotate3;
+}
+
+void Skeleton::FindRotationMuscle(int which)
+{
+ XYZ temppoint1,temppoint2,tempforward;
+ float distance;
+
+ temppoint1=muscles[which].parent1->position;
+ temppoint2=muscles[which].parent2->position;
+ distance=findDistance(temppoint1,temppoint2);
+ muscles[which].rotate2=asin((temppoint1.y-temppoint2.y)/distance)*rad2deg;
+ temppoint1.y=0;
+ temppoint2.y=0;
+ muscles[which].rotate1=acos((temppoint1.z-temppoint2.z)/findDistance(temppoint1,temppoint2));
+ muscles[which].rotate1*=360/6.28;
+ if(temppoint1.x>temppoint2.x)muscles[which].rotate1=360-muscles[which].rotate1;
+ if(muscles[which].parent1->label==head)tempforward=specialforward[0];
+ else if(muscles[which].parent1->label==rightshoulder||muscles[which].parent1->label==rightelbow||muscles[which].parent1->label==rightwrist)tempforward=specialforward[1];
+ else if(muscles[which].parent1->label==leftshoulder||muscles[which].parent1->label==leftelbow||muscles[which].parent1->label==leftwrist)tempforward=specialforward[2];
+ else if(muscles[which].parent1->label==righthip||muscles[which].parent1->label==rightknee||muscles[which].parent1->label==rightankle)tempforward=specialforward[3];
+ else if(muscles[which].parent1->label==lefthip||muscles[which].parent1->label==leftknee||muscles[which].parent1->label==leftankle)tempforward=specialforward[4];
+ else if(!muscles[which].parent1->lower)tempforward=forward;
+ else if(muscles[which].parent1->lower)tempforward=lowforward;
+ tempforward=DoRotation(tempforward,0,muscles[which].rotate1-90,0);
+ tempforward=DoRotation(tempforward,0,0,muscles[which].rotate2-90);
+ tempforward.y=0;
+ Normalise(&tempforward);
+ muscles[which].rotate3=acos(0-tempforward.z)*rad2deg;
+ for(int i=0;i<num_joints;i++){
+ if(&joints[i]==muscles[which].parent1){
+ joints[i].rotate1=muscles[which].rotate1;
+ joints[i].rotate2=muscles[which].rotate2;
+ joints[i].rotate3=muscles[which].rotate3;
+ }
+ }
+ if(0>tempforward.x)muscles[which].rotate3=360-muscles[which].rotate3;
+}
+
+extern Skeleton testskeleton;
+
+void Animation::Load(char *fileName)
+{
+ float placeholder[3];
+ files.OpenFile((unsigned char*)fileName);
+ if(files.sFile){
+ files.lSize=sizeof(numframes);
+ FSRead( files.sFile, &files.lSize, &numframes);
+ for(int i=0;i<numframes;i++){
+ files.lSize=sizeof(XYZ);
+ for(int j=0;j<max_joints;j++){
+ FSRead( files.sFile, &files.lSize, &position[j][i]);
+ }
+ files.lSize=sizeof(float);
+ for(int j=0;j<max_joints;j++){
+ FSRead( files.sFile, &files.lSize, &twist[j][i]);
+ }
+ files.lSize=sizeof(bool);
+ for(int j=0;j<max_joints;j++){
+ FSRead( files.sFile, &files.lSize, &onground[j][i]);
+ }
+ files.lSize=sizeof(float);
+ FSRead( files.sFile, &files.lSize, &speed[i]);
+ files.lSize=sizeof(float);
+ FSRead( files.sFile, &files.lSize, &gunrotation[i]);
+ }
+ for(int i=0;i<numframes;i++){
+ files.lSize=sizeof(float);
+ for(int j=0;j<max_joints;j++){
+ FSRead( files.sFile, &files.lSize, &twist2[j][i]);
+ }
+ }
+ }
+ files.EndLoad();
+
+ for(int j=0;j<numframes;j++){
+ for(int i=0;i<testskeleton.num_joints;i++){
+ testskeleton.joints[i].position=position[i][j];
+ }
+ //Find forward vectors
+ CrossProduct(testskeleton.joints[testskeleton.forwardjoints[1]].position-testskeleton.joints[testskeleton.forwardjoints[0]].position,testskeleton.joints[testskeleton.forwardjoints[2]].position-testskeleton.joints[testskeleton.forwardjoints[0]].position,&testskeleton.forward);
+ Normalise(&testskeleton.forward);
+
+ CrossProduct(testskeleton.joints[testskeleton.lowforwardjoints[1]].position-testskeleton.joints[testskeleton.lowforwardjoints[0]].position,testskeleton.joints[testskeleton.lowforwardjoints[2]].position-testskeleton.joints[testskeleton.lowforwardjoints[0]].position,&testskeleton.lowforward);
+ Normalise(&testskeleton.lowforward);
+
+ //Special forwards
+ testskeleton.specialforward[0]=testskeleton.forward;
+
+ testskeleton.specialforward[1]=testskeleton.joints[testskeleton.jointlabels[rightshoulder]].position+testskeleton.joints[testskeleton.jointlabels[rightwrist]].position;
+ testskeleton.specialforward[1]=testskeleton.joints[testskeleton.jointlabels[rightelbow]].position-testskeleton.specialforward[1]/2;
+ testskeleton.specialforward[1]+=testskeleton.forward*.2;
+ Normalise(&testskeleton.specialforward[1]);
+ testskeleton.specialforward[2]=testskeleton.joints[testskeleton.jointlabels[leftshoulder]].position+testskeleton.joints[testskeleton.jointlabels[leftwrist]].position;
+ testskeleton.specialforward[2]=testskeleton.joints[testskeleton.jointlabels[leftelbow]].position-testskeleton.specialforward[2]/2;
+ testskeleton.specialforward[2]+=testskeleton.forward*.2;
+ Normalise(&testskeleton.specialforward[2]);
+
+ testskeleton.specialforward[3]=testskeleton.joints[testskeleton.jointlabels[righthip]].position+testskeleton.joints[testskeleton.jointlabels[rightankle]].position;
+ testskeleton.specialforward[3]=testskeleton.specialforward[3]/2-testskeleton.joints[testskeleton.jointlabels[rightknee]].position;
+ testskeleton.specialforward[3]+=testskeleton.lowforward*.2;
+ Normalise(&testskeleton.specialforward[3]);
+ testskeleton.specialforward[4]=testskeleton.joints[testskeleton.jointlabels[lefthip]].position+testskeleton.joints[testskeleton.jointlabels[leftankle]].position;
+ testskeleton.specialforward[4]=testskeleton.specialforward[4]/2-testskeleton.joints[testskeleton.jointlabels[leftknee]].position;
+ testskeleton.specialforward[4]+=testskeleton.lowforward*.2;
+ Normalise(&testskeleton.specialforward[4]);
+
+ //Find joint rotations
+ for(int i=0;i<testskeleton.num_joints;i++){
+ if(testskeleton.joints[i].hasparent&&testskeleton.joints[i].visible)
+ {
+ testskeleton.FindRotationJoint(i);
+ }
+ }
+ for(int i=0;i<testskeleton.num_muscles;i++){
+ if(testskeleton.muscles[i].visible)
+ {
+ testskeleton.FindRotationMuscle(i);
+ }
+ }
+ for(int i=0;i<testskeleton.num_muscles;i++){
+ if(testskeleton.muscles[i].visible)
+ {
+ mrotate1[i][j]=testskeleton.muscles[i].rotate1;
+ mrotate2[i][j]=testskeleton.muscles[i].rotate2;
+ mrotate3[i][j]=testskeleton.muscles[i].rotate3;
+ if(j!=0&&mrotate3[i][j]>mrotate3[i][j-1]+180)mrotate3[i][j]-=360;
+ if(j!=0&&mrotate3[i][j]<mrotate3[i][j-1]-180)mrotate3[i][j]+=360;
+ if(j!=0&&mrotate2[i][j]>mrotate2[i][j-1]+180)mrotate2[i][j]-=360;
+ if(j!=0&&mrotate2[i][j]<mrotate2[i][j-1]-180)mrotate2[i][j]+=360;
+ if(j!=0&&mrotate1[i][j]>mrotate1[i][j-1]+180)mrotate1[i][j]-=360;
+ if(j!=0&&mrotate1[i][j]<mrotate1[i][j-1]-180)mrotate1[i][j]+=360;
+ }
+ }
+ for(int i=0;i<testskeleton.num_joints;i++){
+ if(testskeleton.joints[i].hasparent&&testskeleton.joints[i].visible)
+ {
+ rotate1[i][j]=testskeleton.joints[i].rotate1;
+ rotate2[i][j]=testskeleton.joints[i].rotate2;
+ rotate3[i][j]=testskeleton.joints[i].rotate3;
+ if(j!=0&&rotate3[i][j]>rotate3[i][j-1]+180)rotate3[i][j]-=360;
+ if(j!=0&&rotate3[i][j]<rotate3[i][j-1]-180)rotate3[i][j]+=360;
+ if(j!=0&&rotate2[i][j]>rotate2[i][j-1]+180)rotate2[i][j]-=360;
+ if(j!=0&&rotate2[i][j]<rotate2[i][j-1]-180)rotate2[i][j]+=360;
+ if(j!=0&&rotate1[i][j]>rotate1[i][j-1]+180)rotate1[i][j]-=360;
+ if(j!=0&&rotate1[i][j]<rotate1[i][j-1]-180)rotate1[i][j]+=360;
+ }
+ }
+ }
+
+ for(int k=0;k<2;k++)
+ for(int j=0;j<numframes;j++){
+ for(int i=0;i<testskeleton.num_muscles;i++){
+ if(testskeleton.muscles[i].visible)
+ {
+ if(j!=0&&mrotate3[i][j]>mrotate3[i][j-1]+180)mrotate3[i][j]-=360;
+ if(j!=0&&mrotate3[i][j]<mrotate3[i][j-1]-180)mrotate3[i][j]+=360;
+ if(j!=0&&mrotate2[i][j]>mrotate2[i][j-1]+180)mrotate2[i][j]-=360;
+ if(j!=0&&mrotate2[i][j]<mrotate2[i][j-1]-180)mrotate2[i][j]+=360;
+ if(j!=0&&mrotate1[i][j]>mrotate1[i][j-1]+180)mrotate1[i][j]-=360;
+ if(j!=0&&mrotate1[i][j]<mrotate1[i][j-1]-180)mrotate1[i][j]+=360;
+
+ if(j==0&&mrotate3[i][j]>mrotate3[i][numframes-1]+180)mrotate3[i][j]-=360;
+ if(j==0&&mrotate3[i][j]<mrotate3[i][numframes-1]-180)mrotate3[i][j]+=360;
+ if(j==0&&mrotate2[i][j]>mrotate2[i][numframes-1]+180)mrotate2[i][j]-=360;
+ if(j==0&&mrotate2[i][j]<mrotate2[i][numframes-1]-180)mrotate2[i][j]+=360;
+ if(j==0&&mrotate1[i][j]>mrotate1[i][numframes-1]+180)mrotate1[i][j]-=360;
+ if(j==0&&mrotate1[i][j]<mrotate1[i][numframes-1]-180)mrotate1[i][j]+=360;
+ }
+ }
+ for(int i=0;i<testskeleton.num_joints;i++){
+ if(testskeleton.joints[i].hasparent&&testskeleton.joints[i].visible)
+ {
+ if(j!=0&&rotate3[i][j]>rotate3[i][j-1]+180)rotate3[i][j]-=360;
+ if(j!=0&&rotate3[i][j]<rotate3[i][j-1]-180)rotate3[i][j]+=360;
+ if(j!=0&&rotate2[i][j]>rotate2[i][j-1]+180)rotate2[i][j]-=360;
+ if(j!=0&&rotate2[i][j]<rotate2[i][j-1]-180)rotate2[i][j]+=360;
+ if(j!=0&&rotate1[i][j]>rotate1[i][j-1]+180)rotate1[i][j]-=360;
+ if(j!=0&&rotate1[i][j]<rotate1[i][j-1]-180)rotate1[i][j]+=360;
+
+ if(j==0&&rotate3[i][j]>rotate3[i][numframes-1]+180)rotate3[i][j]-=360;
+ if(j==0&&rotate3[i][j]<rotate3[i][numframes-1]-180)rotate3[i][j]+=360;
+ if(j==0&&rotate2[i][j]>rotate2[i][numframes-1]+180)rotate2[i][j]-=360;
+ if(j==0&&rotate2[i][j]<rotate2[i][numframes-1]-180)rotate2[i][j]+=360;
+ if(j==0&&rotate1[i][j]>rotate1[i][numframes-1]+180)rotate1[i][j]-=360;
+ if(j==0&&rotate1[i][j]<rotate1[i][numframes-1]-180)rotate1[i][j]+=360;
+ }
+ }
+ }
+}
+
+void Animation::Load(char *fileName, float rotate)
+{
+ float placeholder[3];
+ files.OpenFile((unsigned char*)fileName);
+ if(files.sFile){
+ files.lSize=sizeof(numframes);
+ FSRead( files.sFile, &files.lSize, &numframes);
+ for(int i=0;i<numframes;i++){
+ files.lSize=sizeof(XYZ);
+ for(int j=0;j<max_joints;j++){
+ FSRead( files.sFile, &files.lSize, &position[j][i]);
+ position[j][i]=DoRotation(position[j][i],0,rotate,0);
+ }
+ files.lSize=sizeof(float);
+ for(int j=0;j<max_joints;j++){
+ FSRead( files.sFile, &files.lSize, &twist[j][i]);
+ }
+ files.lSize=sizeof(bool);
+ for(int j=0;j<max_joints;j++){
+ FSRead( files.sFile, &files.lSize, &onground[j][i]);
+ }
+ files.lSize=sizeof(float);
+ FSRead( files.sFile, &files.lSize, &speed[i]);
+ files.lSize=sizeof(float);
+ FSRead( files.sFile, &files.lSize, &gunrotation[i]);
+ }
+ for(int i=0;i<numframes;i++){
+ files.lSize=sizeof(float);
+ for(int j=0;j<max_joints;j++){
+ FSRead( files.sFile, &files.lSize, &twist2[j][i]);
+ }
+ }
+ }
+ files.EndLoad();
+
+ for(int j=0;j<numframes;j++){
+ for(int i=0;i<testskeleton.num_joints;i++){
+ testskeleton.joints[i].position=position[i][j];
+ }
+ //Find forward vectors
+ CrossProduct(testskeleton.joints[testskeleton.forwardjoints[1]].position-testskeleton.joints[testskeleton.forwardjoints[0]].position,testskeleton.joints[testskeleton.forwardjoints[2]].position-testskeleton.joints[testskeleton.forwardjoints[0]].position,&testskeleton.forward);
+ Normalise(&testskeleton.forward);
+
+ CrossProduct(testskeleton.joints[testskeleton.lowforwardjoints[1]].position-testskeleton.joints[testskeleton.lowforwardjoints[0]].position,testskeleton.joints[testskeleton.lowforwardjoints[2]].position-testskeleton.joints[testskeleton.lowforwardjoints[0]].position,&testskeleton.lowforward);
+ Normalise(&testskeleton.lowforward);
+
+ //Special forwards
+ testskeleton.specialforward[0]=testskeleton.forward;
+
+ testskeleton.specialforward[1]=testskeleton.joints[testskeleton.jointlabels[rightshoulder]].position+testskeleton.joints[testskeleton.jointlabels[rightwrist]].position;
+ testskeleton.specialforward[1]=testskeleton.joints[testskeleton.jointlabels[rightelbow]].position-testskeleton.specialforward[1]/2;
+ testskeleton.specialforward[1]+=testskeleton.forward*.2;
+ Normalise(&testskeleton.specialforward[1]);
+ testskeleton.specialforward[2]=testskeleton.joints[testskeleton.jointlabels[leftshoulder]].position+testskeleton.joints[testskeleton.jointlabels[leftwrist]].position;
+ testskeleton.specialforward[2]=testskeleton.joints[testskeleton.jointlabels[leftelbow]].position-testskeleton.specialforward[2]/2;
+ testskeleton.specialforward[2]+=testskeleton.forward*.2;
+ Normalise(&testskeleton.specialforward[2]);
+
+ testskeleton.specialforward[3]=testskeleton.joints[testskeleton.jointlabels[righthip]].position+testskeleton.joints[testskeleton.jointlabels[rightankle]].position;
+ testskeleton.specialforward[3]=testskeleton.specialforward[3]/2-testskeleton.joints[testskeleton.jointlabels[rightknee]].position;
+ testskeleton.specialforward[3]+=testskeleton.lowforward*.2;
+ Normalise(&testskeleton.specialforward[3]);
+ testskeleton.specialforward[4]=testskeleton.joints[testskeleton.jointlabels[lefthip]].position+testskeleton.joints[testskeleton.jointlabels[leftankle]].position;
+ testskeleton.specialforward[4]=testskeleton.specialforward[4]/2-testskeleton.joints[testskeleton.jointlabels[leftknee]].position;
+ testskeleton.specialforward[4]+=testskeleton.lowforward*.2;
+ Normalise(&testskeleton.specialforward[4]);
+
+ //Find joint rotations
+ for(int i=0;i<testskeleton.num_joints;i++){
+ if(testskeleton.joints[i].hasparent&&testskeleton.joints[i].visible)
+ {
+ testskeleton.FindRotationJoint(i);
+ }
+ }
+ for(int i=0;i<testskeleton.num_muscles;i++){
+ if(testskeleton.muscles[i].visible)
+ {
+ testskeleton.FindRotationMuscle(i);
+ }
+ }
+ for(int i=0;i<testskeleton.num_muscles;i++){
+ if(testskeleton.muscles[i].visible)
+ {
+ mrotate1[i][j]=testskeleton.muscles[i].rotate1;
+ mrotate2[i][j]=testskeleton.muscles[i].rotate2;
+ mrotate3[i][j]=testskeleton.muscles[i].rotate3;
+ if(j!=0&&mrotate3[i][j]>mrotate3[i][j-1]+180)mrotate3[i][j]-=360;
+ if(j!=0&&mrotate3[i][j]<mrotate3[i][j-1]-180)mrotate3[i][j]+=360;
+ if(j!=0&&mrotate2[i][j]>mrotate2[i][j-1]+180)mrotate2[i][j]-=360;
+ if(j!=0&&mrotate2[i][j]<mrotate2[i][j-1]-180)mrotate2[i][j]+=360;
+ if(j!=0&&mrotate1[i][j]>mrotate1[i][j-1]+180)mrotate1[i][j]-=360;
+ if(j!=0&&mrotate1[i][j]<mrotate1[i][j-1]-180)mrotate1[i][j]+=360;
+ }
+ }
+ for(int i=0;i<testskeleton.num_joints;i++){
+ if(testskeleton.joints[i].hasparent&&testskeleton.joints[i].visible)
+ {
+ rotate1[i][j]=testskeleton.joints[i].rotate1;
+ rotate2[i][j]=testskeleton.joints[i].rotate2;
+ rotate3[i][j]=testskeleton.joints[i].rotate3;
+ if(j!=0&&rotate3[i][j]>rotate3[i][j-1]+180)rotate3[i][j]-=360;
+ if(j!=0&&rotate3[i][j]<rotate3[i][j-1]-180)rotate3[i][j]+=360;
+ if(j!=0&&rotate2[i][j]>rotate2[i][j-1]+180)rotate2[i][j]-=360;
+ if(j!=0&&rotate2[i][j]<rotate2[i][j-1]-180)rotate2[i][j]+=360;
+ if(j!=0&&rotate1[i][j]>rotate1[i][j-1]+180)rotate1[i][j]-=360;
+ if(j!=0&&rotate1[i][j]<rotate1[i][j-1]-180)rotate1[i][j]+=360;
+ }
+ }
+ }
+
+ for(int k=0;k<2;k++)
+ for(int j=0;j<numframes;j++){
+ for(int i=0;i<testskeleton.num_muscles;i++){
+ if(testskeleton.muscles[i].visible)
+ {
+ if(j!=0&&mrotate3[i][j]>mrotate3[i][j-1]+180)mrotate3[i][j]-=360;
+ if(j!=0&&mrotate3[i][j]<mrotate3[i][j-1]-180)mrotate3[i][j]+=360;
+ if(j!=0&&mrotate2[i][j]>mrotate2[i][j-1]+180)mrotate2[i][j]-=360;
+ if(j!=0&&mrotate2[i][j]<mrotate2[i][j-1]-180)mrotate2[i][j]+=360;
+ if(j!=0&&mrotate1[i][j]>mrotate1[i][j-1]+180)mrotate1[i][j]-=360;
+ if(j!=0&&mrotate1[i][j]<mrotate1[i][j-1]-180)mrotate1[i][j]+=360;
+
+ if(j==0&&mrotate3[i][j]>mrotate3[i][numframes-1]+180)mrotate3[i][j]-=360;
+ if(j==0&&mrotate3[i][j]<mrotate3[i][numframes-1]-180)mrotate3[i][j]+=360;
+ if(j==0&&mrotate2[i][j]>mrotate2[i][numframes-1]+180)mrotate2[i][j]-=360;
+ if(j==0&&mrotate2[i][j]<mrotate2[i][numframes-1]-180)mrotate2[i][j]+=360;
+ if(j==0&&mrotate1[i][j]>mrotate1[i][numframes-1]+180)mrotate1[i][j]-=360;
+ if(j==0&&mrotate1[i][j]<mrotate1[i][numframes-1]-180)mrotate1[i][j]+=360;
+ }
+ }
+ for(int i=0;i<testskeleton.num_joints;i++){
+ if(testskeleton.joints[i].hasparent&&testskeleton.joints[i].visible)
+ {
+ if(j!=0&&rotate3[i][j]>rotate3[i][j-1]+180)rotate3[i][j]-=360;
+ if(j!=0&&rotate3[i][j]<rotate3[i][j-1]-180)rotate3[i][j]+=360;
+ if(j!=0&&rotate2[i][j]>rotate2[i][j-1]+180)rotate2[i][j]-=360;
+ if(j!=0&&rotate2[i][j]<rotate2[i][j-1]-180)rotate2[i][j]+=360;
+ if(j!=0&&rotate1[i][j]>rotate1[i][j-1]+180)rotate1[i][j]-=360;
+ if(j!=0&&rotate1[i][j]<rotate1[i][j-1]-180)rotate1[i][j]+=360;
+
+ if(j==0&&rotate3[i][j]>rotate3[i][numframes-1]+180)rotate3[i][j]-=360;
+ if(j==0&&rotate3[i][j]<rotate3[i][numframes-1]-180)rotate3[i][j]+=360;
+ if(j==0&&rotate2[i][j]>rotate2[i][numframes-1]+180)rotate2[i][j]-=360;
+ if(j==0&&rotate2[i][j]<rotate2[i][numframes-1]-180)rotate2[i][j]+=360;
+ if(j==0&&rotate1[i][j]>rotate1[i][numframes-1]+180)rotate1[i][j]-=360;
+ if(j==0&&rotate1[i][j]<rotate1[i][numframes-1]-180)rotate1[i][j]+=360;
+ }
+ }
+ }
+}
+
+void Skeleton::Load(char *fileName)
+{
+ int parentID;
+ int what;
+ bool lock;
+ float placeholder[3];
+ files.OpenFile((unsigned char*)fileName);
+ if(files.sFile){
+ files.lSize=sizeof(num_joints);
+ FSRead( files.sFile, &files.lSize, &num_joints);
+ for(int i=0;i<num_joints;i++){
+ files.lSize=sizeof(XYZ);
+ FSRead( files.sFile, &files.lSize, &joints[i].position);
+ files.lSize=sizeof(float);
+ FSRead( files.sFile, &files.lSize, &joints[i].length);
+ files.lSize=sizeof(float);
+ FSRead( files.sFile, &files.lSize, &joints[i].mass);
+ files.lSize=sizeof(bool);
+ FSRead( files.sFile, &files.lSize, &joints[i].hasparent);
+ files.lSize=sizeof(bool);
+ FSRead( files.sFile, &files.lSize, &joints[i].locked);
+ files.lSize=sizeof(int);
+ FSRead( files.sFile, &files.lSize, &joints[i].modelnum);
+ files.lSize=sizeof(bool);
+ FSRead( files.sFile, &files.lSize, &joints[i].visible);
+ files.lSize=sizeof(bool);
+ FSRead( files.sFile, &files.lSize, &what);
+ files.lSize=sizeof(int);
+ FSRead( files.sFile, &files.lSize, &joints[i].label);
+ files.lSize=sizeof(int);
+ FSRead( files.sFile, &files.lSize, &joints[i].hasgun);
+ files.lSize=sizeof(bool);
+ FSRead( files.sFile, &files.lSize, &joints[i].lower);
+ files.lSize=sizeof(int);
+ FSRead( files.sFile, &files.lSize, &parentID);
+ if(joints[i].hasparent)joints[i].parent=&joints[parentID];
+ joints[i].velocity=0;
+ joints[i].oldposition=joints[i].position;
+ joints[i].existing=1;
+ }
+ files.lSize=sizeof(num_muscles);
+ FSRead( files.sFile, &files.lSize, &num_muscles);
+ for(int i=0;i<num_muscles;i++){
+ files.lSize=sizeof(float);
+ FSRead( files.sFile, &files.lSize, &muscles[i].length);
+ files.lSize=sizeof(float);
+ FSRead( files.sFile, &files.lSize, &muscles[i].targetlength);
+ files.lSize=sizeof(float);
+ FSRead( files.sFile, &files.lSize, &muscles[i].minlength);
+ files.lSize=sizeof(float);
+ FSRead( files.sFile, &files.lSize, &muscles[i].maxlength);
+ files.lSize=sizeof(float);
+ FSRead( files.sFile, &files.lSize, &muscles[i].strength);
+ files.lSize=sizeof(int);
+ FSRead( files.sFile, &files.lSize, &muscles[i].type);
+ files.lSize=sizeof(bool);
+ FSRead( files.sFile, &files.lSize, &muscles[i].visible);
+ files.lSize=sizeof(int);
+ FSRead( files.sFile, &files.lSize, &parentID);
+ muscles[i].parent1=&joints[parentID];
+ FSRead( files.sFile, &files.lSize, &parentID);
+ muscles[i].parent2=&joints[parentID];
+ }
+ files.lSize=sizeof(int);
+ for(int j=0;j<3;j++){
+ FSRead( files.sFile, &files.lSize, &forwardjoints[j]);
+ }
+ for(int j=0;j<3;j++){
+ FSRead( files.sFile, &files.lSize, &lowforwardjoints[j]);
+ }
+ }
+ files.EndLoad();
+
+ for(int i=0;i<num_joints;i++){
+ for(int j=0;j<num_joints;j++){
+ if(joints[i].label==j)jointlabels[j]=i;
+ }
+ }
+
+ broken=0;
+}
+
diff --git a/Source/Skeleton.h b/Source/Skeleton.h
new file mode 100644
index 0000000..e59228f
--- /dev/null
+++ b/Source/Skeleton.h
@@ -0,0 +1,149 @@
+#ifndef _SKELETON_H_
+#define _SKELETON_H_
+
+#define boneconnect 0
+#define constraint 1
+#define muscle 2
+
+//head, neck, left shoulder, left elbow, left wrist, left hand
+ //right shoulder, right elbow, right wrist, right hand,
+ //middle, left hip, right hip,groin
+ //left knee,left ankle, left foot, right knee, right ankle, right foort
+
+#define head 1
+#define neck 2
+#define leftshoulder 3
+#define leftelbow 4
+#define leftwrist 5
+#define lefthand 6
+#define rightshoulder 7
+#define rightelbow 8
+#define rightwrist 9
+#define righthand 10
+#define abdomen 11
+#define lefthip 12
+#define righthip 13
+#define groin 14
+#define leftknee 15
+#define leftankle 16
+#define leftfoot 17
+#define rightknee 18
+#define rightankle 19
+#define rightfoot 20
+
+/**> HEADER FILES <**/
+#include <gl.h>
+#include "Quaternions.h"
+#include "Constants.h"
+#include "alut.h"
+#include "Files.h"
+#include "Models.h"
+#include "Camera.h"
+
+class Joint
+{
+ public:
+ XYZ position;
+ XYZ oldposition;
+ XYZ realoldposition;
+ XYZ velocity;
+ XYZ offset;
+ float blurred;
+ float length;
+ float mass;
+ bool lower;
+ bool hasparent;
+ bool locked;
+ int modelnum;
+ bool visible;
+ bool existing;
+ Joint* parent;
+ int label;
+ int hasgun;
+ float rotate1,rotate2,rotate3;
+
+ void DoConstraint();
+};
+
+class Muscle
+{
+ public:
+ float length;
+ float targetlength;
+ Joint* parent1;
+ Joint* parent2;
+ float maxlength;
+ float minlength;
+ int type;
+ bool visible;
+ void DoConstraint(int broken);
+ float rotate1,rotate2,rotate3;
+
+ float strength;
+};
+
+class Animation
+{
+ public:
+ Files files;
+ int numframes;
+ bool canbeoverridden;
+ bool ismodified[max_joints][max_frames];
+ XYZ position[max_joints][max_frames];
+ float twist[max_joints][max_frames];
+ float twist2[max_joints][max_frames];
+ float speed[max_frames];
+ float gunrotation[max_frames];
+ bool onground[max_joints][max_frames];
+ XYZ forward[max_frames];
+ float rotate1[max_joints][max_frames],rotate2[max_joints][max_frames],rotate3[max_joints][max_frames];
+ float mrotate1[max_joints][max_frames],mrotate2[max_joints][max_frames],mrotate3[max_joints][max_frames];
+ void Load(char *fileName);
+ void Load(char *fileName,float rotate);
+};
+
+
+class Skeleton
+{
+ public:
+ int num_joints;
+ Joint joints[max_joints];
+ int jointlabels[max_joints];
+
+ int num_muscles;
+ Muscle muscles[max_muscles];
+
+ int selected;
+
+ int forwardjoints[3];
+ XYZ forward;
+
+ int lowforwardjoints[3];
+ XYZ lowforward;
+
+ int broken;
+ bool offset;
+
+ XYZ specialforward[5];
+
+ bool free;
+
+ Files files;
+
+ void DoConstraints();
+ void DoConstraints(Model *collide, XYZ *move, float rotation);
+ void DoGravity();
+ void DoBalance();
+ void MusclesSet();
+ void Draw(int muscleview);
+ void AddJoint(float x, float y, float z, int which);
+ void SetJoint(float x, float y, float z, int which, int whichjoint);
+ void DeleteJoint(int whichjoint);
+ void AddMuscle(int attach1,int attach2,float maxlength,float minlength,int type);
+ void DeleteMuscle(int whichmuscle);
+ void FindRotationJoint(int which);
+ void FindRotationMuscle(int which);
+ void Load(char *fileName);
+};
+
+#endif \ No newline at end of file
diff --git a/Source/Sprites.cpp b/Source/Sprites.cpp
new file mode 100644
index 0000000..f4cacda
--- /dev/null
+++ b/Source/Sprites.cpp
@@ -0,0 +1,499 @@
+#include "Sprites.h"
+
+extern double multiplier;
+extern bool slomo;
+extern Fog fog;
+extern bool blood;
+extern float fogcolorr;
+extern float fogcolorg;
+extern float fogcolorb;
+//Functions
+extern float sinefluct;
+extern int environment;
+extern Model gunmodels[10];
+extern Camera camera;
+extern float precipitationhorz;
+extern float precipitationvert;
+extern float precipitationdensity;
+extern float snowdelay;
+
+int Sprites::MakeSprite(int atype, float abrightness, float acolor1, float acolor2, float acolor3, XYZ alocation, XYZ avelocity, float asize){
+ type[howmanysprites]=atype;
+ rotation[howmanysprites]=Random()%360;
+ brightness[howmanysprites]=abrightness;
+ color1[howmanysprites]=acolor1;
+ color2[howmanysprites]=acolor2;
+ color3[howmanysprites]=acolor3;
+ location[howmanysprites]=alocation;
+ oldlocation[howmanysprites]=alocation;
+ velocity[howmanysprites]=avelocity;
+ size[howmanysprites]=asize;
+ initialsize[howmanysprites]=asize;
+ initialbrightness[howmanysprites]=abrightness;
+ initialvelocity[howmanysprites]=avelocity;
+ alivetime[howmanysprites]=0;
+ owner[howmanysprites]=0;
+ if(howmanysprites<maxsprites){howmanysprites++;}
+}
+
+int Sprites::MakeSprite(int atype, float abrightness, float acolor1, float acolor2, float acolor3, XYZ alocation, XYZ avelocity, float asize, int aowner){
+ type[howmanysprites]=atype;
+ rotation[howmanysprites]=Random()%360;
+ brightness[howmanysprites]=abrightness;
+ color1[howmanysprites]=acolor1;
+ color2[howmanysprites]=acolor2;
+ color3[howmanysprites]=acolor3;
+ location[howmanysprites]=alocation;
+ oldlocation[howmanysprites]=alocation;
+ velocity[howmanysprites]=avelocity;
+ size[howmanysprites]=asize;
+ initialsize[howmanysprites]=asize;
+ initialbrightness[howmanysprites]=abrightness;
+ initialvelocity[howmanysprites]=avelocity;
+ alivetime[howmanysprites]=0;
+ owner[howmanysprites]=aowner;
+ if(howmanysprites<maxsprites){howmanysprites++;}
+}
+
+int Sprites::DeleteSprite(int which){
+ if(which>=0){
+ location[which]=location[howmanysprites-1];
+ oldlocation[which]=oldlocation[howmanysprites-1];
+ velocity[which]=velocity[howmanysprites-1];
+ initialsize[which]=initialsize[howmanysprites-1];
+ size[which]=size[howmanysprites-1];
+ brightness[which]=brightness[howmanysprites-1];
+ initialbrightness[which]=initialbrightness[howmanysprites-1];
+ color1[which]=color1[howmanysprites-1];
+ color2[which]=color2[howmanysprites-1];
+ color3[which]=color3[howmanysprites-1];
+ alivetime[which]=alivetime[howmanysprites-1];
+ rotation[which]=rotation[howmanysprites-1];
+ type[which]=type[howmanysprites-1];
+ type[howmanysprites-1]=0;
+
+ if(howmanysprites>0){howmanysprites--;}
+ }
+}
+
+void Sprites::LoadFlareTexture(char *fileName)
+{
+ TGAImageRec *tempTexture;
+ GLuint type;
+
+ //Load Image
+ tempTexture = LoadTGA( fileName );
+ //Is it valid?
+ if(tempTexture){
+ //Alpha channel?
+ if ( tempTexture->bpp == 24 )
+ type = GL_RGB;
+ else
+ type = GL_RGBA;
+
+ glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
+
+ glGenTextures( 1, &flaretextureptr );
+ glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+
+ glBindTexture( GL_TEXTURE_2D, flaretextureptr);
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+
+ gluBuild2DMipmaps( GL_TEXTURE_2D, type, tempTexture->sizeX, tempTexture->sizeY, type, GL_UNSIGNED_BYTE, tempTexture->data );
+ free( tempTexture->data );
+ free( tempTexture );
+ }
+}
+
+void Sprites::LoadMuzzleFlareTexture(char *fileName)
+{
+ TGAImageRec *tempTexture;
+ GLuint type;
+
+ //Load Image
+ tempTexture = LoadTGA( fileName );
+ //Is it valid?
+ if(tempTexture){
+ //Alpha channel?
+ if ( tempTexture->bpp == 24 )
+ type = GL_RGB;
+ else
+ type = GL_RGBA;
+
+ glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
+
+ glGenTextures( 1, &muzzleflaretextureptr );
+ glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+
+ glBindTexture( GL_TEXTURE_2D, muzzleflaretextureptr);
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+
+ gluBuild2DMipmaps( GL_TEXTURE_2D, type, tempTexture->sizeX, tempTexture->sizeY, type, GL_UNSIGNED_BYTE, tempTexture->data );
+ free( tempTexture->data );
+ free( tempTexture );
+ }
+}
+
+void Sprites::LoadSmokeTexture(char *fileName)
+{
+ TGAImageRec *tempTexture;
+ GLuint type;
+
+ //Load Image
+ tempTexture = LoadTGA( fileName );
+ //Is it valid?
+ if(tempTexture){
+ //Alpha channel?
+ if ( tempTexture->bpp == 24 )
+ type = GL_RGB;
+ else
+ type = GL_RGBA;
+
+ glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
+
+ glGenTextures( 1, &smoketextureptr );
+ glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+
+ glBindTexture( GL_TEXTURE_2D, smoketextureptr);
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+
+ gluBuild2DMipmaps( GL_TEXTURE_2D, type, tempTexture->sizeX, tempTexture->sizeY, type, GL_UNSIGNED_BYTE, tempTexture->data );
+ free( tempTexture->data );
+ free( tempTexture );
+ }
+}
+
+void Sprites::LoadBloodTexture(char *fileName)
+{
+ TGAImageRec *tempTexture;
+ GLuint type;
+
+ //Load Image
+ tempTexture = LoadTGA( fileName );
+ //Is it valid?
+ if(tempTexture){
+ //Alpha channel?
+ if ( tempTexture->bpp == 24 )
+ type = GL_RGB;
+ else
+ type = GL_RGBA;
+
+ glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
+
+ glGenTextures( 1, &bloodtextureptr );
+ glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+
+ glBindTexture( GL_TEXTURE_2D, bloodtextureptr);
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+
+ gluBuild2DMipmaps( GL_TEXTURE_2D, type, tempTexture->sizeX, tempTexture->sizeY, type, GL_UNSIGNED_BYTE, tempTexture->data );
+ free( tempTexture->data );
+ free( tempTexture );
+ }
+}
+
+void Sprites::LoadRainTexture(char *fileName)
+{
+ TGAImageRec *tempTexture;
+ GLuint type;
+
+ //Load Image
+ tempTexture = LoadTGA( fileName );
+ //Is it valid?
+ if(tempTexture){
+ //Alpha channel?
+ if ( tempTexture->bpp == 24 )
+ type = GL_RGB;
+ else
+ type = GL_RGBA;
+
+ glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
+
+ glGenTextures( 1, &raintextureptr );
+ glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+
+ glBindTexture( GL_TEXTURE_2D, raintextureptr);
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+
+ gluBuild2DMipmaps( GL_TEXTURE_2D, type, tempTexture->sizeX, tempTexture->sizeY, type, GL_UNSIGNED_BYTE, tempTexture->data );
+ free( tempTexture->data );
+ free( tempTexture );
+ }
+}
+
+void Sprites::LoadSnowTexture(char *fileName)
+{
+ TGAImageRec *tempTexture;
+ GLuint type;
+
+ //Load Image
+ tempTexture = LoadTGA( fileName );
+ //Is it valid?
+ if(tempTexture){
+ //Alpha channel?
+ if ( tempTexture->bpp == 24 )
+ type = GL_RGB;
+ else
+ type = GL_RGBA;
+
+ glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
+
+ glGenTextures( 1, &snowtextureptr );
+ glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+
+ glBindTexture( GL_TEXTURE_2D, snowtextureptr);
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+
+ gluBuild2DMipmaps( GL_TEXTURE_2D, type, tempTexture->sizeX, tempTexture->sizeY, type, GL_UNSIGNED_BYTE, tempTexture->data );
+ free( tempTexture->data );
+ free( tempTexture );
+ }
+}
+
+void Sprites::LoadBulletTexture(char *fileName)
+{
+ TGAImageRec *tempTexture;
+ GLuint type;
+
+ //Load Image
+ tempTexture = LoadTGA( fileName );
+ //Is it valid?
+ if(tempTexture){
+ //Alpha channel?
+ if ( tempTexture->bpp == 24 )
+ type = GL_RGB;
+ else
+ type = GL_RGBA;
+
+ glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
+
+ glGenTextures( 1, &bullettextureptr );
+ glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+
+ glBindTexture( GL_TEXTURE_2D, bullettextureptr);
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+
+ gluBuild2DMipmaps( GL_TEXTURE_2D, type, tempTexture->sizeX, tempTexture->sizeY, type, GL_UNSIGNED_BYTE, tempTexture->data );
+ free( tempTexture->data );
+ free( tempTexture );
+ }
+}
+
+
+void Sprites::DoStuff()
+{
+ for(int i=0;i<howmanysprites;i++){
+ if(type[i]!=bullet&&type[i]!=bulletinstant&&type[i]!=grenadesprite&&type[i]!=pinsprite&&type[i]!=grenadesprite)oldlocation[i]=location[i];
+ if(type[i]==muzzleflashsprite)brightness[i]-=multiplier*10;
+ if(type[i]==flashsprite)brightness[i]-=multiplier*10;
+ if(type[i]==smokesprite||type[i]==smokespritenoup||type[i]==bloodspritedown||type[i]==particlesspritedown)brightness[i]-=multiplier*.5;
+ if(type[i]==bloodspritenoup)brightness[i]-=multiplier*.9;
+ if(type[i]==smokesprite)size[i]=initialsize[i]*abs(fast_sqrt(fast_sqrt(abs(initialbrightness[i]-brightness[i]))));//velocity[i].y+=multiplier*20;
+ if(type[i]==bloodspritenoup||type[i]==particlesspritedown)size[i]=initialsize[i]*(initialbrightness[i]-brightness[i]+.4)*(initialbrightness[i]-brightness[i]+.4);//velocity[i].y+=multiplier*20;
+ if(type[i]==bloodspritenoup||type[i]==particlesspritedown)velocity[i]=initialvelocity[i]*brightness[i];//velocity[i].y+=multiplier*20;
+ if(type[i]==bullet)brightness[i]-=multiplier;
+ if(type[i]==snowsprite)rotation[i]+=multiplier*50;
+ if(type[i]==smokesprite)rotation[i]+=multiplier*30;
+ if(type[i]==smokespritenoup)rotation[i]+=multiplier*30;
+ if(type[i]==bulletinstant){
+ brightness[i]=0;
+ }
+ if(type[i]==grenadesprite||type[i]==spoonsprite||type[i]==pinsprite){
+ if(findLengthfast(velocity[i])>0){
+ velocity[i].y+=gravity*multiplier;
+ rotation[i]+=multiplier*2;
+ }
+ }
+ if(type[i]==bloodspritedown||type[i]==particlesspritedown){
+ velocity[i].y+=gravity*multiplier;
+ }
+
+ if(type[i]!=bulletinstant&&type[i]!=bullet)location[i]=location[i]+velocity[i]*multiplier;
+
+ alivetime[i]+=multiplier;
+ if(brightness[i]<=0)DeleteSprite(i);
+ if(type[i]==snowsprite&&(location[i].y<-.1||environment!=snowy_environment))DeleteSprite(i);
+ if(type[i]==rainsprite&&(location[i].y<-.1||environment!=rainy_environment))DeleteSprite(i);
+
+ if(type[i]==snowsprite){
+ if(location[i].x<camera.position.x-precipitationhorz){location[i].x+=precipitationhorz*2;}
+ if(location[i].z<camera.position.z-precipitationhorz){location[i].z+=precipitationhorz*2;}
+ if(location[i].y<camera.position.y-precipitationvert){location[i].y+=precipitationvert*2;snowdelay+=1/precipitationdensity*2;}
+ if(location[i].x>camera.position.x+precipitationhorz){location[i].x-=precipitationhorz*2;}
+ if(location[i].z>camera.position.z+precipitationhorz){location[i].z-=precipitationhorz*2;}
+ if(location[i].y>camera.position.y+precipitationvert){location[i].y-=precipitationvert*2;}
+ }
+ if(type[i]==rainsprite){
+ if(location[i].x<camera.position.x-precipitationhorz*.5){location[i].x+=precipitationhorz;}
+ if(location[i].z<camera.position.z-precipitationhorz*.5){location[i].z+=precipitationhorz;}
+ if(location[i].y<camera.position.y-precipitationvert){location[i].y+=precipitationvert*2;snowdelay+=1/precipitationdensity/4;}
+ if(location[i].x>camera.position.x+precipitationhorz*.5){location[i].x-=precipitationhorz;}
+ if(location[i].z>camera.position.z+precipitationhorz*.5){location[i].z-=precipitationhorz;}
+ if(location[i].y>camera.position.y+precipitationvert){location[i].y-=precipitationvert*2;}
+ }
+ }
+}
+
+void Sprites::draw()
+{
+ float M[16];
+ XYZ begProj,endProj,avgProj,persp;
+ XYZ between;
+ float oolen,dx,dy;
+ float bulletsize;
+ XYZ point;
+ glAlphaFunc(GL_GREATER, 0.01);
+
+ //glEnable(GL_POLYGON_OFFSET_FILL);
+
+ glEnable(GL_BLEND);
+ glDisable(GL_CULL_FACE);
+ glEnable(GL_TEXTURE_2D);
+ glDisable(GL_LIGHTING);
+ glDepthMask(0);
+ glAlphaFunc(GL_GREATER, 0.01);
+ for(int i=0;i<howmanysprites;i++){
+ if(type[i]==muzzleflashsprite){fog.TempFog(0,0,0); glBindTexture(GL_TEXTURE_2D, muzzleflaretextureptr);glBlendFunc(GL_SRC_ALPHA,GL_ONE);}
+ if(type[i]==flashsprite){fog.TempFog(0,0,0); glBindTexture(GL_TEXTURE_2D, flaretextureptr);glBlendFunc(GL_SRC_ALPHA,GL_ONE);}
+ if(type[i]==smokesprite||type[i]==smokespritenoup){fog.ResetFog(); glBindTexture(GL_TEXTURE_2D, smoketextureptr);glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);}
+ if(type[i]==bloodspritedown||type[i]==bloodspritenoup){fog.ResetFog(); glBindTexture(GL_TEXTURE_2D, smoketextureptr);glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);}
+ if(type[i]==particlesspritedown){fog.ResetFog(); glBindTexture(GL_TEXTURE_2D, bloodtextureptr);glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);}
+ if(type[i]==snowsprite){fog.ResetFog(); glBindTexture(GL_TEXTURE_2D, snowtextureptr);glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);}
+ if(type[i]==rainsprite){fog.ResetFog(); glBindTexture(GL_TEXTURE_2D, raintextureptr);glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);}
+ if(type[i]==bullet||type[i]==bulletinstant){fog.ResetFog(); glBindTexture(GL_TEXTURE_2D, bullettextureptr);glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);}
+
+ glPushMatrix();
+ if(type[i]==muzzleflashsprite||type[i]==flashsprite||type[i]==smokesprite||type[i]==smokespritenoup||type[i]==snowsprite||type[i]==particlesspritedown||((type[i]==bloodspritenoup||type[i]==bloodspritedown)&&blood)){
+ glColor4f(color1[i]*fogcolorr*1.6,color2[i]*fogcolorg*1.6,color3[i]*fogcolorb*1.6,brightness[i]);
+ glTranslatef(location[i].x,location[i].y,location[i].z);
+ if(type[i]==snowsprite){
+ glTranslatef(sinefluct*rotation[i]/400,0,sinefluct*rotation[i]/400);
+ }
+ glGetFloatv(GL_MODELVIEW_MATRIX,M);
+ point.x=M[12];
+ point.y=M[13];
+ point.z=M[14];
+ glLoadIdentity();
+ glTranslatef(point.x, point.y, point.z);
+ glRotatef(rotation[i],0,0,1);
+
+ glBegin(GL_TRIANGLES);
+ glTexCoord2f(1.0f, 1.0f); glVertex3f( .3f*size[i], .3f*size[i], 0.0f);
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(-.3f*size[i], .3f*size[i], 0.0f);
+ glTexCoord2f(1.0f, 0.0f); glVertex3f( .3f*size[i],-.3f*size[i], 0.0f);
+ glTexCoord2f(0.0f, 0.0f); glVertex3f(-.3f*size[i],-.3f*size[i], 0.0f);
+ glTexCoord2f(1.0f, 0.0f); glVertex3f( .3f*size[i], -.3f*size[i], 0.0f);
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(-.3f*size[i], .3f*size[i], 0.0f);
+ glEnd();
+
+ }
+
+ if(type[i]==rainsprite){
+ glColor4f(color1[i]*fogcolorr*1.6,color2[i]*fogcolorg*1.6,color3[i]*fogcolorb*1.6,brightness[i]);
+ glTranslatef(location[i].x,location[i].y,location[i].z);
+ glGetFloatv(GL_MODELVIEW_MATRIX,M);
+ for( int i=0; i<3; i+=2 )
+ for( int j=0; j<3; j++ ) {
+ if ( i==j )
+ M[i*4+j] = 1.0;
+ else
+ M[i*4+j] = 0.0;
+ }
+
+
+
+ glLoadMatrixf(M);
+ glScalef(.2,abs(velocity[i].y)*multiplier,.2);
+ glBegin(GL_TRIANGLES);
+ glTexCoord2f(1.0f, 1.0f); glVertex3f( .3f*size[i], .3f*size[i], 0.0f);
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(-.3f*size[i], .3f*size[i], 0.0f);
+ glTexCoord2f(1.0f, 0.0f); glVertex3f( .3f*size[i],-.3f*size[i], 0.0f);
+ glTexCoord2f(0.0f, 0.0f); glVertex3f(-.3f*size[i],-.3f*size[i], 0.0f);
+ glTexCoord2f(1.0f, 0.0f); glVertex3f( .3f*size[i], -.3f*size[i], 0.0f);
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(-.3f*size[i], .3f*size[i], 0.0f);
+ glEnd();
+ }
+
+ if(type[i]==grenadesprite||type[i]==spoonsprite||type[i]==pinsprite){
+ glTranslatef(location[i].x,location[i].y+.2,location[i].z);
+ glDisable(GL_BLEND);
+ glEnable(GL_FOG);
+ glEnable(GL_CULL_FACE);
+ glDisable(GL_TEXTURE_2D);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_COLOR_MATERIAL);
+ glDepthMask(1);
+ glRotatef(rotation[i],1,.6,.3);
+
+ if(type[i]==grenadesprite)gunmodels[grenadebasemodel].draw();
+ if(type[i]==spoonsprite)gunmodels[grenadespoonmodel].draw();
+ if(type[i]==pinsprite)gunmodels[grenadepinmodel].draw();
+
+ glEnable(GL_BLEND);
+ glDisable(GL_FOG);
+ glDisable(GL_CULL_FACE);
+ glEnable(GL_TEXTURE_2D);
+ glDisable(GL_LIGHTING);
+ glDisable(GL_COLOR_MATERIAL);
+ glDepthMask(0);
+ }
+
+ if(type[i]==bullet||type[i]==bulletinstant){
+ bulletsize=size[i];
+ glPushMatrix();
+ begProj=location[i];
+ endProj=velocity[i];
+ glPushMatrix();
+ glTranslatef(begProj.x,begProj.y,begProj.z);
+ glGetFloatv(GL_MODELVIEW_MATRIX,M);
+ begProj.x=M[12];
+ begProj.y=M[13];
+ begProj.z=M[14];
+ glPopMatrix();
+ glPushMatrix();
+ glTranslatef(endProj.x,endProj.y,endProj.z);
+ glGetFloatv(GL_MODELVIEW_MATRIX,M);
+ endProj.x=M[12];
+ endProj.y=M[13];
+ endProj.z=M[14];
+ glPopMatrix();
+ avgProj=(endProj+begProj)/2;
+
+ dx = endProj.x - begProj.x;
+ dy = endProj.y - begProj.y;
+ oolen= 1/fast_sqrt(dx*dx+dy*dy)*0.5;
+ persp=0;
+ persp.x=-dy*oolen; persp.y=dx*oolen;
+
+ glColor4f(color1[i]*fogcolorr*1.6,color2[i]*fogcolorg*1.6,color3[i]*fogcolorb*1.6,brightness[i]);
+
+ glPushMatrix();
+ glLoadIdentity();
+ glBegin(GL_TRIANGLES);
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(endProj.x-persp.x*bulletsize/2, endProj.y-persp.y*bulletsize/2, endProj.z);
+ glTexCoord2f(1.0f, 0.0f); glVertex3f(begProj.x+persp.x*bulletsize/2, begProj.y+persp.y*bulletsize/2, begProj.z);
+ glTexCoord2f(0.0f, 0.0f); glVertex3f(begProj.x-persp.x*bulletsize/2, begProj.y-persp.y*bulletsize/2, begProj.z);
+ glTexCoord2f(1.0f, 0.0f); glVertex3f(begProj.x+persp.x*bulletsize/2, begProj.y+persp.y*bulletsize/2, begProj.z);
+ glTexCoord2f(0.0f, 1.0f); glVertex3f(endProj.x-persp.x*bulletsize/2, endProj.y-persp.y*bulletsize/2, endProj.z);
+ glTexCoord2f(1.0f, 1.0f); glVertex3f(endProj.x+persp.x*bulletsize/2, endProj.y+persp.y*bulletsize/2, endProj.z);
+ glEnd();
+ glPopMatrix();
+ glPopMatrix();
+ }
+ glPopMatrix();
+ }
+ fog.ResetFog();
+ glDepthMask(1);
+ glDisable(GL_TEXTURE_2D);
+ glEnable(GL_CULL_FACE);
+ //glDisable(GL_POLYGON_OFFSET_FILL);
+
+}
+
diff --git a/Source/Sprites.h b/Source/Sprites.h
new file mode 100644
index 0000000..49ceab5
--- /dev/null
+++ b/Source/Sprites.h
@@ -0,0 +1,91 @@
+#ifndef _SPRITE_H_
+#define _SPRITE_H_
+
+#include "Quaternions.h"
+#include <gl.h>
+#include <glu.h>
+#include "Files.h"
+#include "TGALoader.h"
+#include "Quaternions.h"
+#include "gl.h"
+#include "glut.h"
+#include "Camera.h"
+#include "Models.h"
+#include "Fog.h"
+//
+// Model Structures
+//
+
+#define maxsprites 2000
+
+#define muzzleflashsprite 1
+#define smokesprite 2
+#define smokespritenoup 3
+#define flashsprite 6
+#define grenadesprite 7
+#define pinsprite 8
+#define spoonsprite 9
+#define bloodspritedown 10
+#define bloodspritenoup 11
+#define particlesspritedown 12
+#define snowsprite 13
+#define rainsprite 14
+
+#define bullet 4
+#define bulletinstant 5
+
+class Sprites{
+ public:
+ GLuint flaretextureptr;
+ GLuint muzzleflaretextureptr;
+ GLuint smoketextureptr;
+ GLuint bullettextureptr;
+ GLuint bloodtextureptr;
+ GLuint raintextureptr;
+ GLuint snowtextureptr;
+
+ int howmanysprites;
+
+ XYZ location[maxsprites];
+ XYZ oldlocation[maxsprites];
+ XYZ velocity[maxsprites];
+ XYZ initialvelocity[maxsprites];
+ float size[maxsprites];
+ float initialsize[maxsprites];
+ float brightness[maxsprites];
+ float initialbrightness[maxsprites];
+ float color1[maxsprites];
+ float color2[maxsprites];
+ float color3[maxsprites];
+ float alivetime[maxsprites];
+ float rotation[maxsprites];
+ int type[maxsprites];
+ int owner[maxsprites];
+
+ void draw();
+
+ int DeleteSprite(int which);
+ int MakeSprite(int atype, float abrightness, float acolor1, float acolor2, float acolor3, XYZ alocation, XYZ avelocity, float asize);
+ int MakeSprite(int atype, float abrightness, float acolor1, float acolor2, float acolor3, XYZ alocation, XYZ avelocity, float asize, int aowner);
+
+ void DoStuff();
+ void LoadMuzzleFlareTexture(char *fileName);
+ void LoadFlareTexture(char *fileName);
+ void LoadSmokeTexture(char *fileName);
+ void LoadBulletTexture(char *fileName);
+ void LoadBloodTexture(char *fileName);
+ void LoadSnowTexture(char *fileName);
+ void LoadRainTexture(char *fileName);
+
+ ~Sprites() {
+ glDeleteTextures( 1, (const unsigned long *)muzzleflaretextureptr );
+ glDeleteTextures( 1, (const unsigned long *)flaretextureptr );
+ glDeleteTextures( 1, (const unsigned long *)bullettextureptr );
+ glDeleteTextures( 1, (const unsigned long *)smoketextureptr );
+ glDeleteTextures( 1, (const unsigned long *)bloodtextureptr );
+ glDeleteTextures( 1, (const unsigned long *)raintextureptr );
+ glDeleteTextures( 1, (const unsigned long *)snowtextureptr );
+ };
+};
+
+#endif \ No newline at end of file
diff --git a/Source/TGALoader.cpp b/Source/TGALoader.cpp
new file mode 100644
index 0000000..b3ec161
--- /dev/null
+++ b/Source/TGALoader.cpp
@@ -0,0 +1,83 @@
+/**> HEADER FILES <**/
+#include "TGALoader.h"
+
+
+/********************> LoadTGA() <*****/
+TGAImageRec* LoadTGA( char *filename )
+{
+ GLubyte TGAheader[12]={0,0,2,0,0,0,0,0,0,0,0,0}; // Uncompressed TGA Header
+ GLubyte TGAcompare[12]; // Used To Compare TGA Header
+ GLubyte header[6]; // First 6 Useful Bytes From The Header
+ GLuint bytesPerPixel; // Holds Number Of Bytes Per Pixel Used In The TGA File
+ GLuint imageSize; // Used To Store The Image Size When Setting Aside Ram
+ GLuint temp; // Temporary Variable
+ GLuint type = GL_RGBA; // Set The Default GL Mode To RBGA (32 BPP)
+ TGAImageRec *texture;
+ FILE *file;
+
+ // Open The TGA File
+ file = fopen( filename, "rb" );
+
+ if( ( file == NULL ) || // Does File Even Exist?
+ ( fread( TGAcompare, 1, sizeof( TGAcompare ), file ) != sizeof( TGAcompare ) ) || // Are There 12 Bytes To Read?
+ ( memcmp( TGAheader, TGAcompare, sizeof( TGAheader ) ) != 0 ) || // Does The Header Match What We Want?
+ ( fread( header, 1, sizeof( header ), file ) != sizeof( header ) ) )// If So Read Next 6 Header Bytes
+ {
+ // If anything failed then close the file and return false
+ fclose( file );
+ return NULL;
+ }
+
+ // Create a new RGBAImageRec
+ texture = ( TGAImageRec* )malloc( sizeof( TGAImageRec ) );
+
+ // Determine the TGA width (highbyte*256+lowbyte) and height (highbyte*256+lowbyte)
+ texture->sizeX = header[1] * 256 + header[0];
+ texture->sizeY = header[3] * 256 + header[2];
+
+ // Make sure the height, width, and bit depth are valid
+ if( ( texture->sizeX <= 0 ) || ( texture->sizeY <= 0 ) || ( ( header[4] != 24 ) && ( header[4] != 32 ) ) )
+ {
+ // If anything failed then close the file, free up memory for the image, and return NULL
+ fclose( file );
+ free( texture );
+ return NULL;
+ }
+
+ // Grab The TGA's Bits Per Pixel (24 or 32)
+ texture->bpp = header[4];
+ bytesPerPixel = texture->bpp/8; // Divide By 8 To Get The Bytes Per Pixel
+
+ // Calculate The Memory Required For The TGA Data
+ imageSize = texture->sizeX * texture->sizeY * bytesPerPixel;
+
+ // Reserve Memory To Hold The TGA Data
+ texture->data = ( GLubyte* )malloc( imageSize );
+
+ // Make sure the right amount of memory was allocated
+ if( ( texture->data == NULL ) || ( fread( texture->data, 1, imageSize, file ) != imageSize ) )
+ {
+ // Free up the image data if there was any
+ if( texture->data != NULL )
+ free( texture->data );
+
+ // If anything failed then close the file, free up memory for the image, and return NULL
+ fclose( file );
+ free( texture );
+ return NULL;
+ }
+
+ // Loop Through The Image Data
+ for( GLuint i = 0; i < int( imageSize ); i += bytesPerPixel )
+ {
+ // Swaps The 1st And 3rd Bytes ('R'ed and 'B'lue)
+ temp = texture->data[i]; // Temporarily Store The Value At Image Data 'i'
+ texture->data[i] = texture->data[i + 2]; // Set The 1st Byte To The Value Of The 3rd Byte
+ texture->data[i + 2] = temp; // Set The 3rd Byte To The Value In 'temp' (1st Byte Value)
+ }
+
+ // Close The File
+ fclose( file );
+
+ return texture;
+}
diff --git a/Source/TGALoader.h b/Source/TGALoader.h
new file mode 100644
index 0000000..a7b9d9a
--- /dev/null
+++ b/Source/TGALoader.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#ifndef _TGA_LOADER_H_
+#define _TGA_LOADER_H_
+
+
+/**> HEADER FILES <**/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "gl.h"
+
+
+/**> DATA STRUCTURES <**/
+typedef struct TGAImageRec
+{
+ GLubyte *data; // Image Data (Up To 32 Bits)
+ GLuint bpp; // Image Color Depth In Bits Per Pixel.
+ GLuint sizeX;
+ GLuint sizeY;
+} TGAImageRec;
+
+
+
+/**> FUNCTION PROTOTYPES <**/
+TGAImageRec* LoadTGA( char *filename );
+
+
+#endif
diff --git a/Source/Text.cpp b/Source/Text.cpp
new file mode 100644
index 0000000..2b64b4b
--- /dev/null
+++ b/Source/Text.cpp
@@ -0,0 +1,92 @@
+/**> HEADER FILES <**/
+#include "Text.h"
+
+void Text::LoadFontTexture(char *fileName)
+{
+ TGAImageRec *tempTexture;
+ GLuint type;
+
+ //Load Image
+ tempTexture = LoadTGA( fileName );
+ //Is it valid?
+ if(tempTexture){
+ //Alpha channel?
+ if ( tempTexture->bpp == 24 )
+ type = GL_RGB;
+ else
+ type = GL_RGBA;
+
+ glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
+
+ glGenTextures( 1, &FontTexture );
+ glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+
+ glBindTexture( GL_TEXTURE_2D, FontTexture);
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+
+ gluBuild2DMipmaps( GL_TEXTURE_2D, type, tempTexture->sizeX, tempTexture->sizeY, type, GL_UNSIGNED_BYTE, tempTexture->data );
+ free( tempTexture->data );
+ free( tempTexture );
+ }
+}
+
+void Text::BuildFont() // Build Our Font Display List
+{
+ float cx; // Holds Our X Character Coord
+ float cy; // Holds Our Y Character Coord
+ int loop;
+
+ base=glGenLists(256); // Creating 256 Display Lists
+ glBindTexture(GL_TEXTURE_2D, FontTexture); // Select Our Font Texture
+ for (loop=0; loop<256; loop++) // Loop Through All 256 Lists
+ {
+ cx=float(loop%16)/16.0f; // X Position Of Current Character
+ cy=float(loop/16)/16.0f; // Y Position Of Current Character
+
+ glNewList(base+loop,GL_COMPILE); // Start Building A List
+ glBegin(GL_QUADS); // Use A Quad For Each Character
+ glTexCoord2f(cx,1-cy-0.0625f+.001); // Texture Coord (Bottom Left)
+ glVertex2i(0,0); // Vertex Coord (Bottom Left)
+ glTexCoord2f(cx+0.0625f,1-cy-0.0625f+.001); // Texture Coord (Bottom Right)
+ glVertex2i(16,0); // Vertex Coord (Bottom Right)
+ glTexCoord2f(cx+0.0625f,1-cy-.001); // Texture Coord (Top Right)
+ glVertex2i(16,16); // Vertex Coord (Top Right)
+ glTexCoord2f(cx,1-cy-+.001); // Texture Coord (Top Left)
+ glVertex2i(0,16); // Vertex Coord (Top Left)
+ glEnd(); // Done Building Our Quad (Character)
+ glTranslated(10,0,0); // Move To The Right Of The Character
+ glEndList(); // Done Building The Display List
+ } // Loop Until All 256 Are Built
+}
+
+void Text::glPrint(GLint x, GLint y, char *string, int set, float size, float width, float height) // Where The Printing Happens
+{
+ if (set>1)
+ {
+ set=1;
+ }
+ glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+ glBindTexture(GL_TEXTURE_2D, FontTexture); // Select Our Font Texture
+ glDisable(GL_DEPTH_TEST); // Disables Depth Testing
+ glDisable(GL_LIGHTING);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
+ glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
+ glPushMatrix(); // Store The Projection Matrix
+ glLoadIdentity(); // Reset The Projection Matrix
+ glOrtho(0,width,0,height,-100,100); // Set Up An Ortho Screen
+ glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
+ glPushMatrix(); // Store The Modelview Matrix
+ glLoadIdentity();
+ glScalef(size,size,1); // Reset The Modelview Matrix
+ glTranslated(x,y,0); // Position The Text (0,0 - Bottom Left)
+ glListBase(base-32+(128*set)); // Choose The Font Set (0 or 1)
+ glCallLists(strlen(string),GL_BYTE,string); // Write The Text To The Screen
+ glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
+ glPopMatrix(); // Restore The Old Projection Matrix
+ glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
+ glPopMatrix(); // Restore The Old Projection Matrix
+ glEnable(GL_DEPTH_TEST); // Enables Depth Testing
+ glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
+}
diff --git a/Source/Text.h b/Source/Text.h
new file mode 100644
index 0000000..541dc03
--- /dev/null
+++ b/Source/Text.h
@@ -0,0 +1,29 @@
+#ifndef _TEXT_H_
+#define _TEXT_H_
+
+
+/**> HEADER FILES <**/
+#include "Quaternions.h"
+#include <gl.h>
+#include <glu.h>
+#include "Files.h"
+#include "Quaternions.h"
+#include "gl.h"
+#include "glut.h"
+#include "TGALoader.h"
+
+class Text{
+ public:
+ GLuint FontTexture;
+ GLuint base;
+
+ void LoadFontTexture(char *fileName);
+ void BuildFont();
+ void glPrint(GLint x, GLint y, char *string, int set, float size, float width, float height);
+
+ ~Text(){
+ glDeleteTextures( 1, (const unsigned long *)FontTexture );
+ }
+};
+
+#endif \ No newline at end of file
diff --git a/Source/Timer.cpp b/Source/Timer.cpp
new file mode 100644
index 0000000..5360e5f
--- /dev/null
+++ b/Source/Timer.cpp
@@ -0,0 +1,26 @@
+/**> HEADER FILES <**/
+#include "Timer.h"
+#include <string.h>
+
+/********************> Timer <*****/
+void TimerInit(timer* theTimer)
+{
+ UnsignedWide ms;
+
+ Microseconds(&ms);
+
+ memset(theTimer, 0, sizeof(timer));
+
+ theTimer->mm_timer_start = ms.lo;
+ theTimer->mm_timer_elapsed = theTimer->mm_timer_start;
+}
+
+float TimerGetTime(timer* theTimer)
+{
+ UnsignedWide ms;
+
+ Microseconds(&ms);
+
+
+ return( (float) (ms.lo - theTimer->mm_timer_start) * 1000.0f);
+}
diff --git a/Source/Timer.h b/Source/Timer.h
new file mode 100644
index 0000000..ce895bb
--- /dev/null
+++ b/Source/Timer.h
@@ -0,0 +1,17 @@
+#ifndef _TIMER_H_
+#define _TIMER_H_
+
+
+/**> HEADER FILES <**/
+class timer
+{
+ public:
+ unsigned long mm_timer_start;
+ unsigned long mm_timer_elapsed;
+};
+
+
+void TimerInit(timer* theTimer);
+float TimerGetTime(timer* theTimer);
+
+#endif \ No newline at end of file