aboutsummaryrefslogblamecommitdiff
path: root/src/GameInitDispose.cpp
blob: d94f6f6f59d0dcded57477ca4b0623bcaad413a5 (plain) (tree)




















                                                                         
 
                   
 
                   
                     
                 

                                   
                                    
                     
                             
                       

                     
                                
                           
                           
                               
                   
                     
               
                  
                       
                       
                       
                       
                               
                               
                                  
                              
                 
                       
                        
                   
                    
                  
                         

                      



                                                    
                                        

 
                             
 
                               

                                           
                                     

                             
                                         


                                                              






                                   
 



                                                  














                                                                  


                                      
                    

 
                                 
 
                                                          

                                     
 
                                     

































































                                                                             
 
                          







                                                                           
         
 

                                                            
                                                         
                                                          
                                                            
                                                         
                                                          
                                                             
                                                          

                                                           
                             
                                                                        
                                                                     
                                                                      
         
 
                                                              
                                                           
                                                            
                                                              
                                                           
                                                            
                                                           
                                                        
                                                         
                                                             
                                                          
                                                              
                                                             
                                                          
                                                           
                                                              
                                                                
                                                             
                                                             
                                                                
                                                             
                                                             
                                                               
                                                            
                                                            
                                                              
                                                           
                                                            
                                                            
                                                         
                                                          
                                                           
                                                        
                                                         
                                                             
                                                          
                                                           
                                                             
                                                          
                                                           
                                                             
                                                          
                                                          
                                                                
                                                             
                                                             
                                                                  
                                                               
                                                               
                                                            
                                                         
                                                         
                                                             
                                                          
                                                          
                                                               
                                                            
                                                            
                                                               
                                                            
                                                             
                                                          
                                                       
                                                           
                                                          
                                                       
                                                        
                                                                  
                                                               
                                                                
                                                                
                                                             
                                                             
                                                             
                                                          
                                                           
                                                          
                                                       
                                                        
                                                             
                                                          
                                                           
                                                           
                                                        
                                                         
                                                          
                                                       
                                                        

 
                         
 
                              
                             
                             

                                



                                                                   




























                                                                               
 
                                                            
                               
                                                                           

                                                                  

                                                          
                                                       




                                                          
                                                                  


                                                          

                                                                               


                                                          
                                                                  

                                                          
                                                               

                                                          
                                                                                  

                                                          
                                                                

                                                          
                                                             



                                                          
                                               
                 

         

































































































































































                                                                   

         
                                                
                             

                  
                                       

                              








                                                                    

         



                             
 
                                 
                                                                               
 

                                              

                                   















                                                                         


         
                            
                          
 












                                                                          


                                                           
                                                                   
                                                                        
                                                         

                                                            
                         
                                                                    
                 














                                                                                          








                                                                                         

                 








                                                                                        









                                                                                                 

















                                                                                   




                                                                   

         





























































                                                                              


                                   
                                                                          






                                                     
                                                                           






                                                     
                                                                             






                                                     
                                                                               






                                                     
                                                                               






                                                     
                                                                          






                                                     
                                                                               






                                                     
                                                                               






                                                     
                                                                          






                                                     
                                                                            






                                                     
 

                                                                                           






                                                                  
                                                                                             






                                                                
                                                                                           










                                                                  
                                                                                             










                                                                   
                                                                                          










                                                                   
                                                                                            










                                                                    
                                                                                           








                                                                  
                                                                                         








                                                                 
                                                                                             








                                                                   
                                                                               








                                                            
                                                                                   








                                                              
         
 





                             
 
                
 
                                    
 
                                    
 
                                    
 
                                    
 
                                   
 
                                   
 
                                    
 
                                    
 
                                    
 
                                  
 
                                  
 
                                   
 
                                     
 
                                     
 
                                      
 




                                               
 



                                               
 





                                                                 





                                                                 





                                                                 





                                                                   





                                                                    





                                                                    





                                                                       





                                                                       





                                                                 







                                           





                                              





                                                                  





                                                                  





                                                                  





                                                                    





                                                                     





                                                                      





                                                                        





                                                                        





                                                                  







                                           





                                              





                                                                    





                                                                    





                                                                    





                                                                      





                                                                       





                                                                       





                                                                          





                                                                          





                                                                    







                                           





                                             





                                           





                                                                    





                                                                    





                                                                    





                                                                      





                                                                       





                                                                       





                                                                          





                                                                          





                                                                    







                                           





                                             





                                            





                                                                    





                                                                    





                                                                    





                                                                      





                                                                       





                                                                        





                                                                          





                                                                          





                                                                    
                     





                                           





                                              





                                            





                                            





                                            





                                            





                                                              





                                                              





                                                              





                                                                





                                                                 





                                                                 





                                                                    





                                                                    





                                                              







                                          





                                             





                                           





                                                                    





                                                                    





                                                                    





                                                                      





                                                                       





                                                                       





                                                                          





                                                                          





                                                                    
                                 






                                                                                    









                                                                                                









                                                                                          









                                                                                            







                                                                                          










                                                                                            


















                                                                                    

         

                                   
 

                                                      
 

                                                           
               
                                                            
                                                          
                                                       
                                                       
                            


                                 
























                                                                                                              

         




                                    

                                                      




                                                               
                                                     

         
                                 
          
                                                  
                                        
         
                                                
                                      


                               
                                 
                            

 
                       
 
                                                                                
                               
                                      
                             
                              
                                                  

 
                                                 
 
                                    
                         
                                                                                         
                                   
                         
 
 
                          
 
                                 



                                                 

                                      
                                                                
 
// Game object setup and teardown
// Copyright (C) 2002  David Rosen
// Copyright (C) 2003  Ryan C. Gordon
// Copyright (C) 2003  Steven Fuller
// Copyright (C) 2003  Zachary Jack Slater
// Copyright (C) 2021  Nguyễn Gia Phong
//
// This file is part of Black Shades.
//
// Black Shades is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Black Shades is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Black Shades.  If not, see <https://www.gnu.org/licenses/>.

#include <AL/alc.h>

#include "config.h"
#include "Textures.h"
#include "Game.h"

extern unsigned int gSourceID[100];
extern unsigned int gSampleSet[100];
extern Camera camera;
extern Skeleton testskeleton;
extern Sprites sprites;
extern Decals decals;

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 resizeWindow(Game* game, int width, int height)
{
	game->screenwidth = width;
	game->screenheight = height;
	glViewport(0, 0, width, height);
}

Game* makeGame(Config config)
{
	auto game = new Game();
	game->screenwidth = config.width;
	game->screenheight = config.height;
	game->blurness = config.blur;
	blood = config.blood;

	game->musictoggle = config.music;

	game->usermousesensitivity = config.mouse_sensitivity;
	game->mousesensitivity = game->usermousesensitivity;
	forwardskey = GLFW_KEY_W;
	backwardskey = GLFW_KEY_S;
	leftkey = GLFW_KEY_A;
	rightkey = GLFW_KEY_D;
	aimkey = GLFW_KEY_Q;
	psychicaimkey = GLFW_KEY_E;
	psychickey = GLFW_KEY_Z;

	game->mainmenuness = config.menu;
	game->customlevels = config.custom_levels;
	game->debug = config.debug;

	if (!game->initialized) {
		// TODO: Read high score
		ifstream ipstream2 {"highscore.txt"};
		if (!ipstream2) {
			ofstream opstream("highscore.txt");
			opstream << (game->highscore = 0) << endl;
			opstream << (game->beatgame = 0) << endl;
			opstream.close();
		} else {
			ipstream2 >> game->highscore;
			ipstream2.ignore(256,'\n');
			ipstream2 >> game->beatgame;
			ipstream2.close();
		}

		game->disttest = true;
		game->cubetest = true;
	}
	return game;
}

void LoadSounds(bool musictoggle)
{
	// generate ten OpenAL sample sets and two sources
	alGenBuffers(37, gSampleSet);
	alGenSources(37, gSourceID);

	// load up some audio data...
	loadOgg((char*) ":Data:Sounds:underwater.ogg",
		gSampleSet[visionsound], gSourceID[visionsound]);
	loadOgg((char*) ":Data:Sounds:soulin.ogg",
		gSampleSet[soulinsound], gSourceID[soulinsound]);
	loadOgg((char*) ":Data:Sounds:soulout.ogg",
		gSampleSet[souloutsound], gSourceID[souloutsound]);
	loadOgg((char*) ":Data:Sounds:footstep1.ogg",
		gSampleSet[footstepsound], gSourceID[footstepsound]);
	loadOgg((char*) ":Data:Sounds:footstep2.ogg",
		gSampleSet[footstepsound+1], gSourceID[footstepsound+1]);
	loadOgg((char*) ":Data:Sounds:footstep3.ogg",
		gSampleSet[footstepsound+2], gSourceID[footstepsound+2]);
	loadOgg((char*) ":Data:Sounds:footstep4.ogg",
		gSampleSet[footstepsound+3], gSourceID[footstepsound+3]);
	loadOgg((char*) ":Data:Sounds:footstep5.ogg",
		gSampleSet[footstepsound+4], gSourceID[footstepsound+4]);
	loadOgg((char*) ":Data:Sounds:bodyland.ogg",
		gSampleSet[bodylandsound], gSourceID[bodylandsound]);
	loadOgg((char*) ":Data:Sounds:headland.ogg",
		gSampleSet[headlandsound], gSourceID[headlandsound]);
	loadOgg((char*) ":Data:Sounds:sniperrifle.ogg",
		gSampleSet[riflesound], gSourceID[riflesound]);
	loadOgg((char*) ":Data:Sounds:BodyHit.ogg",
		gSampleSet[bodyhitsound], gSourceID[bodyhitsound]);
	loadOgg((char*) ":Data:Sounds:WallHit.ogg",
		gSampleSet[wallhitsound], gSourceID[wallhitsound]);
	loadOgg((char*) ":Data:Sounds:machinegun.ogg",
		gSampleSet[machinegunsound], gSourceID[machinegunsound]);
	loadOgg((char*) ":Data:Sounds:Nearbullet.ogg",
		gSampleSet[nearbulletsound], gSourceID[nearbulletsound]);
	loadOgg((char*) ":Data:Sounds:riflewhack.ogg",
		gSampleSet[headwhacksound], gSourceID[headwhacksound]);
	loadOgg((char*) ":Data:Sounds:headshot.ogg",
		gSampleSet[headshotsound], gSourceID[headshotsound]);
	loadOgg((char*) ":Data:Sounds:reload.ogg",
		gSampleSet[reloadsound], gSourceID[reloadsound]);
	loadOgg((char*) ":Data:Sounds:click.ogg",
		gSampleSet[clicksound], gSourceID[clicksound]);
	loadOgg((char*) ":Data:Sounds:SW.ogg",
		gSampleSet[pistol1sound], gSourceID[pistol1sound]);
	loadOgg((char*) ":Data:Sounds:glock.ogg",
		gSampleSet[pistol2sound], gSourceID[pistol2sound]);
	loadOgg((char*) ":Data:Sounds:pinpull.ogg",
		gSampleSet[pinpullsound], gSourceID[pinpullsound]);
	loadOgg((char*) ":Data:Sounds:pinreplace.ogg",
		gSampleSet[pinreplacesound], gSourceID[pinreplacesound]);
	loadOgg((char*) ":Data:Sounds:handlerelease.ogg",
		gSampleSet[grenadethrowsound], gSourceID[grenadethrowsound]);
	loadOgg((char*) ":Data:Sounds:bounce.ogg",
		gSampleSet[bouncesound], gSourceID[bouncesound]);
	loadOgg((char*) ":Data:Sounds:bounce2.ogg",
		gSampleSet[bounce2sound], gSourceID[bounce2sound]);
	loadOgg((char*) ":Data:Sounds:explosion.ogg",
		gSampleSet[explosionsound], gSourceID[explosionsound]);
	loadOgg((char*) ":Data:Sounds:headland.ogg",
		gSampleSet[bodywhacksound], gSourceID[bodywhacksound]);
	loadOgg((char*) ":Data:Sounds:rain.ogg",
		gSampleSet[rainsound], gSourceID[rainsound]);
	loadOgg((char*) ":Data:Sounds:Lose.ogg",
		gSampleSet[losesound], gSourceID[losesound]);
	loadOgg((char*) ":Data:Sounds:Disguisekill.ogg",
		gSampleSet[disguisekillsound], gSourceID[disguisekillsound]);
	loadOgg((char*) ":Data:Sounds:knifeslash.ogg",
		gSampleSet[knifeslashsound], gSourceID[knifeslashsound]);
	loadOgg((char*) ":Data:Sounds:shotgun.ogg",
		gSampleSet[shotgunsound], gSourceID[shotgunsound]);

	if (musictoggle) {
		loadOgg((char*) ":Data:Sounds:mainmenusong.ogg",
			gSampleSet[mainmenusong], gSourceID[mainmenusong]);
		loadOgg((char*) ":Data:Sounds:shootsong.ogg",
			gSampleSet[shootsong], gSourceID[shootsong]);
		loadOgg((char*) ":Data:Sounds:zombiesong.ogg",
			gSampleSet[zombiesong], gSourceID[zombiesong]);
		loadOgg((char*) ":Data:Sounds:knifesong.ogg",
			gSampleSet[knifesong], gSourceID[knifesong]);
	}

	alListenerfv(AL_POSITION, {});
	alSourcefv(gSourceID[visionsound], AL_POSITION, {});
	alSourcei(gSourceID[visionsound], AL_LOOPING, 1);
	alSourcef(gSourceID[visionsound], AL_MIN_GAIN, 1);
	alSourcefv(gSourceID[soulinsound], AL_POSITION, {});
	alSourcei(gSourceID[soulinsound], AL_LOOPING, 0);
	alSourcef(gSourceID[soulinsound], AL_MIN_GAIN, 1);
	alSourcefv(gSourceID[souloutsound], AL_POSITION, {});
	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, {});
		alSourcei(gSourceID[footstepsound+i], AL_LOOPING, 0);
		alSourcef(gSourceID[footstepsound+i], AL_MIN_GAIN, 0);
	}

	alSourcefv(gSourceID[bodylandsound], AL_POSITION, {});
	alSourcei(gSourceID[bodylandsound], AL_LOOPING, 0);
	alSourcef(gSourceID[bodylandsound], AL_MIN_GAIN, 0);
	alSourcefv(gSourceID[headlandsound], AL_POSITION, {});
	alSourcei(gSourceID[headlandsound], AL_LOOPING, 0);
	alSourcef(gSourceID[headlandsound], AL_MIN_GAIN, 0);
	alSourcefv(gSourceID[riflesound], AL_POSITION, {});
	alSourcei(gSourceID[riflesound], AL_LOOPING, 0);
	alSourcef(gSourceID[riflesound], AL_MIN_GAIN, 0);
	alSourcefv(gSourceID[bodyhitsound], AL_POSITION, {});
	alSourcei(gSourceID[bodyhitsound], AL_LOOPING, 0);
	alSourcef(gSourceID[bodyhitsound], AL_MIN_GAIN, 0.1f);
	alSourcefv(gSourceID[wallhitsound], AL_POSITION, {});
	alSourcei(gSourceID[wallhitsound], AL_LOOPING, 0);
	alSourcef(gSourceID[wallhitsound], AL_MIN_GAIN, 0);
	alSourcef(gSourceID[wallhitsound], AL_MAX_GAIN, 0.6f);
	alSourcefv(gSourceID[machinegunsound], AL_POSITION, {});
	alSourcei(gSourceID[machinegunsound], AL_LOOPING, 0);
	alSourcef(gSourceID[machinegunsound], AL_MIN_GAIN,0);
	alSourcefv(gSourceID[nearbulletsound], AL_POSITION, {});
	alSourcei(gSourceID[nearbulletsound], AL_LOOPING, 0);
	alSourcef(gSourceID[nearbulletsound], AL_MIN_GAIN,0);
	alSourcefv(gSourceID[headwhacksound], AL_POSITION, {});
	alSourcei(gSourceID[headwhacksound], AL_LOOPING, 0);
	alSourcef(gSourceID[headwhacksound], AL_MIN_GAIN,0);
	alSourcefv(gSourceID[headshotsound], AL_POSITION, {});
	alSourcei(gSourceID[headshotsound], AL_LOOPING, 0);
	alSourcef(gSourceID[headshotsound], AL_MIN_GAIN, 0);
	alSourcefv(gSourceID[reloadsound], AL_POSITION, {});
	alSourcei(gSourceID[reloadsound], AL_LOOPING, 0);
	alSourcef(gSourceID[reloadsound], AL_MIN_GAIN, 0);
	alSourcefv(gSourceID[clicksound], AL_POSITION, {});
	alSourcei(gSourceID[clicksound], AL_LOOPING, 0);
	alSourcef(gSourceID[clicksound], AL_MIN_GAIN, 0);
	alSourcefv(gSourceID[pistol1sound], AL_POSITION, {});
	alSourcei(gSourceID[pistol1sound], AL_LOOPING, 0);
	alSourcef(gSourceID[pistol1sound], AL_MIN_GAIN, 0);
	alSourcefv(gSourceID[pistol2sound], AL_POSITION, {});
	alSourcei(gSourceID[pistol2sound], AL_LOOPING, 0);
	alSourcef(gSourceID[pistol2sound], AL_MIN_GAIN, 0);
	alSourcefv(gSourceID[pinpullsound], AL_POSITION, {});
	alSourcei(gSourceID[pinpullsound], AL_LOOPING, 0);
	alSourcef(gSourceID[pinpullsound], AL_MIN_GAIN,0);
	alSourcefv(gSourceID[pinreplacesound], AL_POSITION, {});
	alSourcei(gSourceID[pinreplacesound], AL_LOOPING, 0);
	alSourcef(gSourceID[pinreplacesound], AL_MIN_GAIN,0);
	alSourcefv(gSourceID[grenadethrowsound], AL_POSITION, {});
	alSourcei(gSourceID[grenadethrowsound], AL_LOOPING, 0);
	alSourcef(gSourceID[grenadethrowsound], AL_MIN_GAIN,0);
	alSourcefv(gSourceID[bouncesound], AL_POSITION, {});
	alSourcei(gSourceID[bouncesound], AL_LOOPING, 0);
	alSourcef(gSourceID[bouncesound], AL_MIN_GAIN,0);
	alSourcefv(gSourceID[bounce2sound], AL_POSITION, {});
	alSourcei(gSourceID[bounce2sound], AL_LOOPING, 0);
	alSourcef(gSourceID[bounce2sound], AL_MIN_GAIN,0);
	alSourcefv(gSourceID[explosionsound], AL_POSITION, {});
	alSourcei(gSourceID[explosionsound], AL_LOOPING, 0);
	alSourcef(gSourceID[explosionsound], AL_MIN_GAIN,0);
	alSourcefv(gSourceID[bodywhacksound], AL_POSITION, {});
	alSourcei(gSourceID[bodywhacksound], AL_LOOPING, 0);
	alSourcef(gSourceID[bodywhacksound], AL_MIN_GAIN, 0);
	alSourcefv(gSourceID[rainsound], AL_POSITION, {});
	alSourcei(gSourceID[rainsound], AL_LOOPING, 1);
	alSourcef(gSourceID[rainsound], AL_MIN_GAIN, 0.3f);
	alSourcefv(gSourceID[losesound], AL_POSITION, {});
	alSourcei(gSourceID[losesound], AL_LOOPING, 0);
	alSourcef(gSourceID[losesound], AL_MIN_GAIN, 1);
	alSourcefv(gSourceID[disguisekillsound], AL_POSITION, {});
	alSourcei(gSourceID[disguisekillsound], AL_LOOPING, 0);
	alSourcef(gSourceID[disguisekillsound], AL_MIN_GAIN, 1);
	alSourcefv(gSourceID[knifeslashsound], AL_POSITION, {});
	alSourcei(gSourceID[knifeslashsound], AL_LOOPING, 0);
	alSourcef(gSourceID[knifeslashsound], AL_MIN_GAIN,0);
	alSourcefv(gSourceID[shotgunsound], AL_POSITION, {});
	alSourcei(gSourceID[shotgunsound], AL_LOOPING, 0);
	alSourcef(gSourceID[shotgunsound], AL_MIN_GAIN, 0);
	alSourcefv(gSourceID[knifesong], AL_POSITION, {});
	alSourcei(gSourceID[knifesong], AL_LOOPING, 1);
	alSourcef(gSourceID[knifesong], AL_MIN_GAIN, 1);
	alSourcefv(gSourceID[mainmenusong], AL_POSITION, {});
	alSourcei(gSourceID[mainmenusong], AL_LOOPING, 1);
	alSourcef(gSourceID[mainmenusong], AL_MIN_GAIN, 1);
	alSourcefv(gSourceID[zombiesong], AL_POSITION, {});
	alSourcei(gSourceID[zombiesong], AL_LOOPING, 1);
	alSourcef(gSourceID[zombiesong], AL_MIN_GAIN, 1);
	alSourcefv(gSourceID[shootsong], AL_POSITION, {});
	alSourcei(gSourceID[shootsong], AL_LOOPING, 1);
	alSourcef(gSourceID[shootsong], AL_MIN_GAIN, 1);
}

void initGame(Game* game)
{
	//Set up rain and snow
	precipitationhorz=60;
	precipitationvert=40;
	precipitationdensity=25;

	//Setup camera
	camera.position = {block_spacing * (num_blocks + 1) / 2.0f,
		30.0f, block_spacing * (num_blocks + 1) / 2.0f};
	camera.oldposition = camera.position;

	// Bodyguard stats
	auto& bodyguard = game->person[0];
	bodyguard.playercoords = camera.position;
	bodyguard.oldplayercoords = bodyguard.playercoords;
	bodyguard.type = playertype;
	bodyguard.existing = 1;
	bodyguard.speedmult = 1.3f;

	for (int i = 0; i < 10; ++i)
		bodyguard.reloads[i] = 0;

	// Level setup
	game->killedinnocent = 0; // haven't shot any civilians yet...

	if (game->customlevels) {
		game->nummissions = 1; // default level in case of load failure
		game->type = randomshoot_type;
		game->possiblegun[0] = handgun1;
		game->possiblegun[1] = handgun2;
		game->possiblegun[2] = shotgun;
		game->numpossibleguns = 3;
		game->evilprobability = 6;
		bodyguard.whichgun = knife;
		bodyguard.reloads[bodyguard.whichgun] = 6;
		if (!game->gameinprogress)
			game->score = 0;
		game->timeremaining = 50;
		game->difficulty= 0.8f;

		ifstream ipstream {"Data/customlevels.txt"};
		if (ipstream) {
			ipstream.ignore(256,'\n');//ignore descriptive text
			ipstream >> game->nummissions;
			for (int j = 0; j <= game->mission; ++j) {
				ipstream.ignore(256,'\n');
				ipstream.ignore(256,'\n');
				ipstream >> game->type;
				ipstream.ignore(256,'\n');
				ipstream.ignore(256,'\n');
				ipstream >> environment;
				ipstream.ignore(256,'\n');
				ipstream.ignore(256,'\n');
				ipstream >> game->numpossibleguns;
				ipstream.ignore(256,'\n');
				ipstream.ignore(256,'\n');

				for (int i = 0; i < game->numpossibleguns; ++i)
					ipstream >> game->possiblegun[i];

				ipstream.ignore(256,'\n');
				ipstream.ignore(256,'\n');
				ipstream >> game->evilprobability;
				ipstream.ignore(256,'\n');
				ipstream.ignore(256,'\n');
				ipstream >> bodyguard.whichgun;
				ipstream.ignore(256,'\n');
				ipstream.ignore(256,'\n');
				ipstream >> bodyguard.reloads[bodyguard.whichgun];
				ipstream.ignore(256,'\n');
				ipstream.ignore(256,'\n');
				ipstream >> game->timeremaining;
				ipstream.ignore(256,'\n');
				ipstream.ignore(256,'\n');
				ipstream >> game->difficulty;
				ipstream.ignore(256,'\n');
			}
			ipstream.close();
		} else {
			game->customlevels = 0;
		}
	}

	if (!game->customlevels) {
		game->nummissions = 13;
		if (!game->gameinprogress)
			game->score = 0;

		switch (game->mission) {
		case 0:
			environment = sunny_environment;
			game->type = randomshoot_type;
			game->possiblegun[0] = handgun1;
			game->possiblegun[1] = handgun2;
			game->possiblegun[2] = shotgun;
			game->numpossibleguns = 3;
			game->evilprobability = 6;
			bodyguard.whichgun = assaultrifle;
			bodyguard.reloads[bodyguard.whichgun] = 6;
			game->timeremaining = 50;
			game->difficulty = 0.6f;
			break;
		case 1:
			environment = snowy_environment;
			game->type = randomshoot_type;
			game->possiblegun[0] = knife;
			game->possiblegun[1] = assaultrifle;
			game->numpossibleguns = 2;
			game->evilprobability = 5;
			bodyguard.whichgun = handgun2;
			bodyguard.reloads[bodyguard.whichgun] = 3;
			game->timeremaining = 40;
			game->difficulty = 0.6f;
			break;
		case 2:
			environment = foggy_environment;
			game->type = randomshoot_type;
			game->possiblegun[0] = sniperrifle;
			game->numpossibleguns = 1;
			game->evilprobability = 5;
			bodyguard.whichgun = sniperrifle;
			bodyguard.reloads[bodyguard.whichgun] = 4;
			game->timeremaining = 50;
			game->difficulty = 0.9f;
			break;
		case 3:
			environment = firey_environment;
			game->type = zombie_type;
			game->numpossibleguns = 0;
			game->evilprobability = 5;
			bodyguard.whichgun = shotgun;
			bodyguard.reloads[bodyguard.whichgun] = 5;
			game->timeremaining = 35;
			game->difficulty = 0.7f;
			break;
		case 4:
			environment = snowy_environment;
			game->type = randomshoot_type;
			game->possiblegun[0] = sniperrifle;
			game->possiblegun[1] = assaultrifle;
			game->numpossibleguns = 2;
			game->evilprobability = 5;
			bodyguard.whichgun = grenade;
			bodyguard.reloads[bodyguard.whichgun] = 20;
			game->timeremaining = 30;
			game->difficulty = 0.5f;
			break;
		case 5:
			environment = rainy_environment;
			game->type = randomshoot_type;
			game->possiblegun[0] = handgun1;
			game->possiblegun[1] = shotgun;
			game->possiblegun[2] = assaultrifle;
			game->numpossibleguns = 3;
			game->evilprobability = 6;
			bodyguard.whichgun = knife;
			bodyguard.reloads[bodyguard.whichgun] = 3;
			game->timeremaining = 40;
			game->difficulty = 0.8f;
			break;
		case 6:
			environment = night_environment;
			game->type = randomshoot_type;
			game->possiblegun[1] = handgun1;
			game->possiblegun[2] = handgun2;
			game->possiblegun[3] = shotgun;
			game->numpossibleguns = 3;
			game->evilprobability = 5;
			bodyguard.whichgun = handgun1;
			bodyguard.reloads[bodyguard.whichgun] = 4;
			game->timeremaining = 30;
			game->difficulty = 1.0f;
			break;
		case 7:
			environment = firey_environment;
			game->type = zombie_type;
			bodyguard.whichgun = assaultrifle;
			bodyguard.reloads[bodyguard.whichgun] = 5;
			game->timeremaining = 30;
			game->difficulty = 1.0f;
			break;
		case 8:
			environment = rainy_environment;
			game->type = randomshoot_type;
			game->possiblegun[0] = handgun1;
			game->possiblegun[1] = handgun2;
			game->possiblegun[2] = shotgun;
			game->possiblegun[3] = sniperrifle;
			game->possiblegun[4] = assaultrifle;
			game->numpossibleguns = 5;
			game->evilprobability = 5;
			bodyguard.whichgun = nogun;
			bodyguard.reloads[bodyguard.whichgun] = 3;
			game->timeremaining = 40;
			game->difficulty = 0.8f;
			break;
		case 9:
			environment = snowy_environment;
			game->type = randomshoot_type;
			game->possiblegun[0] = knife;
			game->possiblegun[1] = handgun1;
			game->possiblegun[2] = handgun2;
			game->possiblegun[3] = shotgun;
			game->possiblegun[4] = sniperrifle;
			game->possiblegun[5] = assaultrifle;
			game->numpossibleguns = 6;
			game->evilprobability = 4;
			bodyguard.whichgun = handgun1;
			bodyguard.reloads[bodyguard.whichgun] = 3;
			game->timeremaining = 90;
			game->difficulty = 1.0f;
			break;
		case 10:
			environment = night_environment;
			game->type = randomshoot_type;
			game->possiblegun[0] = sniperrifle;
			game->numpossibleguns = 1;
			game->evilprobability = 5;
			bodyguard.whichgun = sniperrifle;
			bodyguard.reloads[bodyguard.whichgun] = 4;
			game->timeremaining = 30;
			game->difficulty = 1.3f;
			break;
		case 11:
			environment = sunny_environment;
			game->type = randomshoot_type;
			game->possiblegun[0] = knife;
			game->possiblegun[1] = sniperrifle;
			game->numpossibleguns = 2;
			game->evilprobability = 4;
			bodyguard.whichgun = knife;
			game->timeremaining = 30;
			game->difficulty = 1.5f;
			break;
		case 12:
			environment = firey_environment;
			game->type = zombie_type;
			game->possiblegun[0] = knife;
			game->possiblegun[1] = sniperrifle;
			bodyguard.whichgun = handgun2;
			bodyguard.reloads[bodyguard.whichgun] = 10;
			game->timeremaining = 60;
			game->difficulty = 1.5f;
			break;
		}
	}

	//Setup fast radian to degree conversion
	rad2deg= 56.54866776;
	visions=0;

	//Setup bounding cylinder model
	float boundingscale=3;

	if (!game->initialized) {
		auto& point0 = game->boundingpoints[0];
		point0 = 0;
		point0.z = boundingscale;
		point0.y = 0;

		for (int i = 1; i < 8; ++i)
			game->boundingpoints[i] = DoRotation(point0,
					0, i * 360 / 7, 0);
	}

	game->civkills = 0;
	game->badkills = 0;
	game->goodkills = 0;
	game->enemystate = 2;

	if (!game->initialized) {
		soundscalefactor=soundscalefactordefault; //Setup sound falloff

		// Sounds
		LoadSounds(game->musictoggle);

		//Play correct song
		if (environment == rainy_environment)
			alSourcePlay(gSourceID[rainsound]);
		else
			alSourcePause(gSourceID[rainsound]);

		ALuint sound_source = gSourceID[game->whichsong];
		alSourceStop(sound_source);
		alSourcef(sound_source, AL_MIN_GAIN, 0);
		alSourcef(sound_source, AL_MAX_GAIN, 0);

		sound_source = gSourceID[game->whichsong = mainmenusong];
		alSourceStop(sound_source);
		alSourcef(sound_source, AL_PITCH, 1);
		alSourcePlay(sound_source);
		alSourcef(sound_source, AL_MIN_GAIN, 1);
		alSourcef(sound_source, AL_MAX_GAIN, 1);

	}

	// Setup random seed
	srand(time(NULL));

	// Setup block models
	if (!game->initialized) {
		game->blocks[0].load((char*) ":Data:Models:Block1.solid");
		game->blocks[1].load((char*) ":Data:Models:Block2.solid");
		game->blocks[2].load((char*) ":Data:Models:Block3.solid");
		game->blocks[3].load((char*) ":Data:Models:Block4.solid");
		for (auto&& block : game->blocks) {
			block.Rotate(90, 0, 0);
			block.Scale(0.8f, 0.8f, 0.8f);
			block.CalculateNormals();

			// Fix block radius
			auto& center = block.boundingspherecenter;
			center.x = center.y = center.z = 0;

			float radiusqr = 0.0;
			for (int x = 0; x < block.vertexNum; x++) {
				auto distance = findDistancefast(center,
					block.vertex[x]);
				if (distance > radiusqr)
					radiusqr = distance;
			}
			block.boundingsphereradius = sqrt(radiusqr);
		}

		game->sidewalkcollide.load((char*) ":Data:Models:Lowheightcollide.solid");
		game->sidewalkcollide.Rotate(90, 0, 0);
		game->sidewalkcollide.Scale(0.8f, 0.8f, 0.8f);
		game->sidewalkcollide.CalculateNormals();

		game->blockwalls[0].load((char*) ":Data:Models:Block1collide.solid");
		game->blockwalls[1].load((char*) ":Data:Models:Block2collide.solid");
		game->blockwalls[2].load((char*) ":Data:Models:Block3collide.solid");
		game->blockwalls[3].load((char*) ":Data:Models:Block4collide.solid");
		for (auto&& blockwall : game->blockwalls) {
			blockwall.Rotate(90, 0, 0);
			blockwall.Scale(0.8f, 0.75f, 0.8f);
			blockwall.CalculateNormals();
		}

		game->blockroofs[0].load((char*) ":Data:Models:Highblock1collide.solid");
		game->blockroofs[1].load((char*) ":Data:Models:Highblock2collide.solid");
		game->blockroofs[2].load((char*) ":Data:Models:Highblock3collide.solid");
		game->blockroofs[3].load((char*) ":Data:Models:Highblock4collide.solid");
		for (auto&& blockroof : game->blockroofs) {
			blockroof.Rotate(90, 0, 0);
			blockroof.Scale(0.8f, 0.8f, 0.8f);
			blockroof.CalculateNormals();
		}

		game->blockcollide[0].load((char*) ":Data:Models:block1complete.solid");
		game->blockcollide[1].load((char*) ":Data:Models:block2complete.solid");
		game->blockcollide[2].load((char*) ":Data:Models:block3complete.solid");
		game->blockcollide[3].load((char*) ":Data:Models:block4complete.solid");
		for (auto&& blockcollide : game->blockcollide) {
			blockcollide.Rotate(90, 0, 0);
			blockcollide.Scale(0.8f, 0.8f, 0.8f);
			blockcollide.CalculateNormals();
		}

		game->blocksimplecollide[0].load((char*) ":Data:Models:lowsimplecollide1.solid");
		game->blocksimplecollide[1].load((char*) ":Data:Models:lowsimplecollide2.solid");
		game->blocksimplecollide[2].load((char*) ":Data:Models:lowsimplecollide3.solid");
		game->blocksimplecollide[3].load((char*) ":Data:Models:lowsimplecollide4.solid");
		for (auto&& blocksimplecollide : game->blocksimplecollide) {
			blocksimplecollide.Rotate(90, 0, 0);
			blocksimplecollide.Scale(0.8f, 0.8f, 0.8f);
			blocksimplecollide.CalculateNormals();
		}

		game->blockocclude.load((char*) ":Data:Models:blockocclude.solid");
		game->blockocclude.Rotate(90, 0, 0);
		game->blockocclude.Scale(0.8f, 0.8f, 0.8f);
		game->blockocclude.CalculateNormals();

		game->blocksimple.load((char*) ":Data:Models:blocksimple.solid");
		game->blocksimple.Rotate(90, 0, 0);
		game->blocksimple.Scale(0.8f, 2.0f, 0.8f);
		game->blocksimple.CalculateNormals();

		game->street.load((char*) ":Data:Models:streetsubdivided2.solid");
		game->street.Rotate(90,0,0);
		game->street.Scale(0.01f, 0.01f, 0.01f);
		game->street.CalculateNormals();

		game->Bigstreet = game->street;
		game->Bigstreet.Scale(10000.0f, 10000.0f, 10000.0f);

		game->path.load((char*) ":Data:Models:path.solid");
		game->path.Rotate(90,0,0);
		game->path.Scale(0.8f, 0.8f, 0.8f);
		game->path.CalculateNormals();
	}

	auto& vip = game->person[game->numpeople = 1];
	vip.type = viptype;
	vip.whichgun = nogun;
	vip.aiming = 0;
	vip.killtarget = -1;
	vip.existing = 1;

	vip.playerrotation = 0;
	vip.whichcostume = vipcostume;
	vip.whichblockx = (bodyguard.playercoords.x + block_spacing / 2)
		/ block_spacing;
	vip.whichblocky = (bodyguard.playercoords.z + block_spacing / 2)
		/ block_spacing;
	vip.oldoldoldpathnum = vip.oldoldpathnum
		= vip.oldpathnum = vip.pathnum = -1;

	while (vip.pathnum < 0 || vip.pathnum == 1
	       || vip.pathnum >= game->path.vertexNum)
		vip.pathnum = Random() % game->path.vertexNum;

	vip.pathtarget.x = game->path.vertex[vip.pathnum].x;
	vip.pathtarget.z = game->path.vertex[vip.pathnum].z;
	vip.pathsize = 0.98f + abs(Random() % 20) / 400.0f;
	vip.pathtarget *= vip.pathsize;
	vip.pathtarget.x += vip.whichblockx * block_spacing;
	vip.pathtarget.z += vip.whichblocky * block_spacing;
	vip.oldplayercoords = vip.playercoords = vip.pathtarget;

	bodyguard.playercoords = vip.playercoords;
	bodyguard.playercoords.x += 1;
	bodyguard.playercoords.z += 1;
	bodyguard.oldplayercoords = bodyguard.playercoords;

	vip.skeleton.free = 0;
	vip.targetanimation = walkanim;
	vip.speed = 1;
	vip.existing = 0;
	vip.speedmult = (game->type == zombie_type) ? 0.8f : 1.0f;

	vip.health = 100;
	vip.playerrotation2 = 0; // 20
	vip.lastdistancevictim = 200000;

	if (vip.skeleton.broken)
		vip.skeleton.Load((char*) ":Data:Skeleton:Basic Figure");

	game->citypeoplenum[vip.whichblockx][vip.whichblocky]++;
	game->numpeople++;
	game->spawndelay = 0.1f;

	game->vipgoal = vip.playercoords
		+ DoRotation({10000000.0f, 0.0f, 0.0f}, 0, Random() % 360, 0);

	// Init city block rotations
	for (int i = 0; i < num_blocks; ++i)
		for (int j = 0; j < num_blocks; ++j) {
			game->cityrotation[i][j] = Random() % 4;
			game->citytype[i][j] = abs(Random()) % 4;
			game->citypeoplenum[i][j] = 0;
		}

	if (!game->initialized) {

		//Load player model

		skeletonmodels[0].load((char*) ":Data:Models:Head.solid");

		skeletonmodels[0].Rotate(90,0,0);

		skeletonmodels[0].Scale(.02,.02,.02);

		skeletonmodels[0].CalculateNormals();

		skeletonmodels[1].load((char*) ":Data:Models:Chest.solid");

		skeletonmodels[1].Rotate(90,0,0);

		skeletonmodels[1].Scale(.02,.02,.02);

		skeletonmodels[1].CalculateNormals();

		skeletonmodels[2].load((char*) ":Data:Models:Abdomen.solid");

		skeletonmodels[2].Rotate(90,0,0);

		skeletonmodels[2].Scale(.02,.02,.02);

		skeletonmodels[2].CalculateNormals();

		skeletonmodels[3].load((char*) ":Data:Models:Upper arm.solid");

		skeletonmodels[3].Rotate(90,0,0);

		skeletonmodels[3].Scale(.02,.02,.02);

		skeletonmodels[3].CalculateNormals();

		skeletonmodels[4].load((char*) ":Data:Models:Lower arm.solid");

		skeletonmodels[4].Rotate(90,0,0);

		skeletonmodels[4].Scale(.02,.02,.02);

		skeletonmodels[4].CalculateNormals();

		skeletonmodels[5].load((char*) ":Data:Models:Hand.solid");

		skeletonmodels[5].Rotate(90,0,0);

		skeletonmodels[5].Scale(.02,.02,.02);

		skeletonmodels[5].CalculateNormals();

		skeletonmodels[6].load((char*) ":Data:Models:Upper leg.solid");

		skeletonmodels[6].Rotate(90,0,0);

		skeletonmodels[6].Scale(.02,.02,.02);

		skeletonmodels[6].CalculateNormals();

		skeletonmodels[7].load((char*) ":Data:Models:Lower leg.solid");

		skeletonmodels[7].Rotate(90,0,0);

		skeletonmodels[7].Scale(.02,.02,.02);

		skeletonmodels[7].CalculateNormals();

		skeletonmodels[8].load((char*) ":Data:Models:Foot.solid");

		skeletonmodels[8].Rotate(90,0,0);

		skeletonmodels[8].Scale(.02,.02,.02);

		skeletonmodels[8].CalculateNormals();

		skeletonmodels[9].load((char*) ":Data:Models:Shades.solid");

		skeletonmodels[9].Rotate(90,0,0);

		skeletonmodels[9].Scale(.02,.02,.02);

		skeletonmodels[9].CalculateNormals();


		//Load gun models
		gunmodels[sniperriflemodel].load((char*) ":Data:Models:sniperrifle.solid");

		gunmodels[sniperriflemodel].Rotate(0,0,90);

		gunmodels[sniperriflemodel].Scale(.001,.001,.001);

		gunmodels[sniperriflemodel].CalculateNormals();

		gunmodels[assaultriflemodel].load((char*) ":Data:Models:assaultrifle.solid");

		gunmodels[assaultriflemodel].Rotate(0,0,90);

		gunmodels[assaultriflemodel].Scale(.01,.01,.01);

		gunmodels[assaultriflemodel].CalculateNormals();

		gunmodels[handgunbasemodel].load((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);

		gunmodels[handgunslidemodel].load((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((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((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);

		gunmodels[grenadebasemodel].load((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((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((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((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((char*) ":Data:Models:shotgun.solid");

		gunmodels[shotgunmodel].Rotate(0,0,90);

		gunmodels[shotgunmodel].Scale(.001,.001,.001);

		gunmodels[shotgunmodel].CalculateNormals();

		gunmodels[shotgunmodel].MultColor(.6);

	}

	//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 (game->type == zombie_type) {
		headcolor[0] = 223.0f / 255.0f;
		headcolor[1] = 243.0f / 255.0f;
		headcolor[2] = 197.0f / 255.0f;

		handcolor[0] = 223.0f / 255.0f;
		handcolor[1] = 243.0f / 255.0f;
		handcolor[2] = 197.0f / 255.0f;
	}

		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];

		//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
		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");

		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");

		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");

		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");

		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");

		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) {
		auto& person = game->person[i];
		if (i == 0)
			person.whichcostume = bodyguardcostume;
		else if (i > 1)
			person.whichcostume = casualcostumes
				+ abs(Random()) % numcasual;

		// person.firstlongdead = 0;
		person.dead = 0;
		person.health = 100;
		person.skeleton.free = 0;
		person.ammo = 0;
		person.velocity = 0;

		// Load skeleton structure
		if (!game->initialized)
			person.skeleton.Load((char*) ":Data:Skeleton:Basic Figure");
	}

	bodyguard.attackframe = -1;
	game->spawndelay = 0;

	fog.SetFog(fogcolorr, fogcolorg, fogcolorb, 0,
		game->viewdistance * 0.8f, 0.1f);

	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);

	// Load some textures
	if (!game->initialized) {
		game->personspritetextureptr = loadTexture((char*) ":Data:Textures:Personsprite.png");
		game->deadpersonspritetextureptr = loadTexture((char*) ":Data:Textures:DeadPersonsprite.png");
		game->scopetextureptr = loadTexture((char*) ":Data:Textures:Scope.png");
		game->flaretextureptr = loadTexture((char*) ":Data:Textures:Flare.png");

		sprites.flaretextureptr = loadTexture((char*) ":Data:Textures:HitFlash.png");
		sprites.muzzleflaretextureptr = loadTexture((char*) ":Data:Textures:MuzzleFlash.png");
		sprites.smoketextureptr = loadTexture((char*) ":Data:Textures:Smoke.png");
		sprites.bloodtextureptr = loadTexture((char*) ":Data:Textures:Blood.png");
		sprites.raintextureptr = loadTexture((char*) ":Data:Textures:rain.png");
		sprites.snowtextureptr = loadTexture((char*) ":Data:Textures:snow.png");

		decals.bulletholetextureptr = loadTexture((char*) ":Data:Textures:BulletHole.png");
		decals.cratertextureptr = loadTexture((char*) ":Data:Textures:Crater.png");
		decals.bloodtextureptr[0] = loadTexture((char*) ":Data:Textures:Blood:Blood1.png");
		decals.bloodtextureptr[1] = loadTexture((char*) ":Data:Textures:Blood:Blood2.png");
		decals.bloodtextureptr[2] = loadTexture((char*) ":Data:Textures:Blood:Blood3.png");
		decals.bloodtextureptr[3] = loadTexture((char*) ":Data:Textures:Blood:Blood4.png");
		decals.bloodtextureptr[4] = loadTexture((char*) ":Data:Textures:Blood:Blood5.png");
		decals.bloodtextureptr[5] = loadTexture((char*) ":Data:Textures:Blood:Blood6.png");
		decals.bloodtextureptr[6] = loadTexture((char*) ":Data:Textures:Blood:Blood7.png");
		decals.bloodtextureptr[7] = loadTexture((char*) ":Data:Textures:Blood:Blood8.png");
		decals.bloodtextureptr[8] = loadTexture((char*) ":Data:Textures:Blood:Blood9.png");
		decals.bloodtextureptr[9] = loadTexture((char*) ":Data:Textures:Blood:Blood10.png");
		decals.bloodtextureptr[10] = loadTexture((char*) ":Data:Textures:Blood:Blood11.png");
	}

	// Setup clip plane equation
	game->eqn[0] = 0;
	game->eqn[1] = 1;
	game->eqn[2] = 0;
	game->eqn[3] = 0;
	glClearColor(fogcolorr,fogcolorg,fogcolorb,1);

	// Draw city one frame to fix evil menu bug
	if (!game->initialized) {
		game->mainmenu = 2;
		game->flashamount = 1;
		game->flashr = game->flashg = game->flashb = 1;
		alSourcePlay(gSourceID[soulinsound]);
	}

	game->initialized = true;
	/*
	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;
	game->losedelay = 1;
}

void initGl(Game* game)
{
	game->text.FontTexture = loadTexture((char*) ":Data:Textures:Font.png");
	game->text.BuildFont();
	glAlphaFunc(GL_GREATER, 0.01);
	glDepthFunc(GL_LESS);
	glPolygonOffset(-8,0);
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}

GLvoid Game::ReSizeGLScene(float fov, float near)
{
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(fov,(GLfloat)screenwidth/(GLfloat)screenheight,near,viewdistance);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

void closeGame(Game* game)
{
	const GLuint textures[] {
		game->personspritetextureptr,
		game->deadpersonspritetextureptr,
		game->scopetextureptr,
		game->flaretextureptr,
	};
	glDeleteTextures(4, textures);
	alDeleteSources(100, gSourceID); // delete sound sources
}