aboutsummaryrefslogblamecommitdiff
path: root/src/GameInitDispose.cpp
blob: 2928d5fe0cc921fb390608dd9b0327b7bb8ee160 (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 <fstream>

#include <time.h>

#include <AL/alc.h>
#include <GL/glu.h>

#include "Game.h"
#include "Support.h"

extern unsigned int gSourceID[37];
extern unsigned int gSampleSet[37];
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, Scores scores)
{
	auto game = new Game();
	game->screenwidth = config.width;
	game->screenheight = config.height;
	game->blurness = config.blur;
	blood = config.blood;

	game->musictoggle = config.music;

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

	game->levels = config.levels.ptr;
	game->nummissions = config.levels.len;
	game->debug = config.debug;

	game->highscore = scores.high_score;
	game->beatgame = scores.completed;
	game->disttest = true;
	game->cubetest = true;
	setMenu(game, true);
	return game;
}

void LoadSounds(bool musictoggle)
{
	gSampleSet[footstepsound + 0] = loadSound("footstep/0.ogg");
	gSampleSet[footstepsound + 1] = loadSound("footstep/1.ogg");
	gSampleSet[footstepsound + 2] = loadSound("footstep/2.ogg");
	gSampleSet[footstepsound + 3] = loadSound("footstep/3.ogg");
	gSampleSet[footstepsound + 4] = loadSound("footstep/4.ogg");
	gSampleSet[pinpullsound] = loadSound("grenade/pin-pull.flac");
	gSampleSet[pinreplacesound] = loadSound("grenade/pin-replace.flac");
	gSampleSet[clicksound] = loadSound("gun/empty-clip.wav");
	gSampleSet[shotgunsound] = loadSound("gun/fire/20-gauge-shotgun.wav");
	gSampleSet[pistol2sound] = loadSound("gun/fire/22-magnum-pistol.wav");
	gSampleSet[pistol1sound] = loadSound("gun/fire/9-mm-pistol.wav");
	gSampleSet[machinegunsound] = loadSound("gun/fire/ar-15-pistol.wav");
	gSampleSet[riflesound] = loadSound("gun/fire/ar-15-rifle.wav");
	gSampleSet[nearbulletsound] = loadSound("gun/near-bullet.wav");
	gSampleSet[reloadsound] = loadSound("gun/reload.wav");
	gSampleSet[bodylandsound] = loadSound("impact/body-fall.wav");
	gSampleSet[bodyhitsound] = loadSound("impact/body-hit.wav");
	gSampleSet[knifeslashsound] = loadSound("impact/knife-stab.wav");
	gSampleSet[wallhitsound] = loadSound("impact/wall-hit.wav");

	gSampleSet[visionsound] = loadSound("underwater.ogg");
	gSampleSet[soulinsound] = loadSound("soul-in.ogg");
	gSampleSet[souloutsound] = loadSound("soul-out.ogg");
	gSampleSet[headlandsound] = loadSound("headland.ogg");
	gSampleSet[headwhacksound] = loadSound("riflewhack.ogg");
	gSampleSet[headshotsound] = loadSound("headshot.ogg");
	gSampleSet[grenadethrowsound] = loadSound("handlerelease.ogg");
	gSampleSet[bouncesound] = loadSound("bounce.ogg");
	gSampleSet[bounce2sound] = loadSound("bounce2.ogg");
	gSampleSet[explosionsound] = loadSound("explosion.ogg");
	gSampleSet[headlandsound] = loadSound("headland.ogg");
	gSampleSet[rainsound] = loadSound("rain.ogg");
	gSampleSet[losesound] = loadSound("Lose.ogg");
	gSampleSet[disguisekillsound] = loadSound("disguise-kill.ogg");
	if (musictoggle) {
		gSampleSet[mainmenusong] = loadSound("mainmenusong.ogg");
		gSampleSet[shootsong] = loadSound("shootsong.ogg");
		gSampleSet[zombiesong] = loadSound("zombiesong.ogg");
		gSampleSet[knifesong] = loadSound("knifesong.ogg");
	}

	alGenSources(33, gSourceID);
	alSourcei(gSourceID[visionsound], AL_BUFFER, gSampleSet[visionsound]);
	alSourcei(gSourceID[soulinsound], AL_BUFFER, gSampleSet[soulinsound]);
	alSourcei(gSourceID[souloutsound], AL_BUFFER, gSampleSet[souloutsound]);
	alSourcei(gSourceID[footstepsound + 0], AL_BUFFER, gSampleSet[footstepsound + 0]);
	alSourcei(gSourceID[footstepsound + 1], AL_BUFFER, gSampleSet[footstepsound + 1]);
	alSourcei(gSourceID[footstepsound + 2], AL_BUFFER, gSampleSet[footstepsound + 2]);
	alSourcei(gSourceID[footstepsound + 3], AL_BUFFER, gSampleSet[footstepsound + 3]);
	alSourcei(gSourceID[footstepsound + 4], AL_BUFFER, gSampleSet[footstepsound + 4]);
	alSourcei(gSourceID[bodylandsound], AL_BUFFER, gSampleSet[bodylandsound]);
	alSourcei(gSourceID[headlandsound], AL_BUFFER, gSampleSet[headlandsound]);
	alSourcei(gSourceID[riflesound], AL_BUFFER, gSampleSet[riflesound]);
	alSourcei(gSourceID[bodyhitsound], AL_BUFFER, gSampleSet[bodyhitsound]);
	alSourcei(gSourceID[wallhitsound], AL_BUFFER, gSampleSet[wallhitsound]);
	alSourcei(gSourceID[machinegunsound], AL_BUFFER, gSampleSet[machinegunsound]);
	alSourcei(gSourceID[nearbulletsound], AL_BUFFER, gSampleSet[nearbulletsound]);
	alSourcei(gSourceID[headwhacksound], AL_BUFFER, gSampleSet[headwhacksound]);
	alSourcei(gSourceID[headshotsound], AL_BUFFER, gSampleSet[headshotsound]);
	alSourcei(gSourceID[reloadsound], AL_BUFFER, gSampleSet[reloadsound]);
	alSourcei(gSourceID[clicksound], AL_BUFFER, gSampleSet[clicksound]);
	alSourcei(gSourceID[pistol1sound], AL_BUFFER, gSampleSet[pistol1sound]);
	alSourcei(gSourceID[pistol2sound], AL_BUFFER, gSampleSet[pistol2sound]);
	alSourcei(gSourceID[pinpullsound], AL_BUFFER, gSampleSet[pinpullsound]);
	alSourcei(gSourceID[pinreplacesound], AL_BUFFER, gSampleSet[pinreplacesound]);
	alSourcei(gSourceID[grenadethrowsound], AL_BUFFER, gSampleSet[grenadethrowsound]);
	alSourcei(gSourceID[bouncesound], AL_BUFFER, gSampleSet[bouncesound]);
	alSourcei(gSourceID[bounce2sound], AL_BUFFER, gSampleSet[bounce2sound]);
	alSourcei(gSourceID[explosionsound], AL_BUFFER, gSampleSet[explosionsound]);
	alSourcei(gSourceID[bodywhacksound], AL_BUFFER, gSampleSet[bodywhacksound]);
	alSourcei(gSourceID[rainsound], AL_BUFFER, gSampleSet[rainsound]);
	alSourcei(gSourceID[losesound], AL_BUFFER, gSampleSet[losesound]);
	alSourcei(gSourceID[disguisekillsound], AL_BUFFER, gSampleSet[disguisekillsound]);
	alSourcei(gSourceID[knifeslashsound], AL_BUFFER, gSampleSet[knifeslashsound]);
	alSourcei(gSourceID[shotgunsound], AL_BUFFER, gSampleSet[shotgunsound]);
	if (musictoggle) {
		alGenSources(4, gSourceID + 33);
		alSourcei(gSourceID[mainmenusong], AL_BUFFER, gSampleSet[mainmenusong]);
		alSourcei(gSourceID[shootsong], AL_BUFFER, gSampleSet[shootsong]);
		alSourcei(gSourceID[zombiesong], AL_BUFFER, gSampleSet[zombiesong]);
		alSourcei(gSourceID[knifesong], AL_BUFFER, gSampleSet[knifesong]);

		alSourcei(gSourceID[knifesong], AL_LOOPING, 1);
		alSourcei(gSourceID[mainmenusong], AL_LOOPING, 1);
		alSourcei(gSourceID[zombiesong], AL_LOOPING, 1);
		alSourcei(gSourceID[shootsong], AL_LOOPING, 1);
	}

	alListenerfv(AL_POSITION, {});
	alSourcefv(gSourceID[visionsound], AL_POSITION, {});
	alSourcefv(gSourceID[soulinsound], AL_POSITION, {});
	alSourcefv(gSourceID[souloutsound], AL_POSITION, {});
	if (musictoggle) {
		alSourcefv(gSourceID[knifesong], AL_POSITION, {});
		alSourcefv(gSourceID[mainmenusong], AL_POSITION, {});
		alSourcefv(gSourceID[zombiesong], AL_POSITION, {});
		alSourcefv(gSourceID[shootsong], AL_POSITION, {});
	}
}

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->gameinprogress)
		game->score = 0;
	auto& level = game->levels[game->mission];
	environment = level.environment;
	game->type = (level.evil_weapons & 1 << nogun)
		? zombie_type : randomshoot_type;
	game->numpossibleguns = 0;
	for (auto weapon : { sniperrifle, assaultrifle, handgun1,
	                     handgun2, shotgun, grenade, knife })
		if (level.evil_weapons & 1 << weapon)
			game->possiblegun[game->numpossibleguns++] = weapon;
	game->evilprobability = level.evil_rarity;
	bodyguard.whichgun = level.guard_weapon;
	bodyguard.reloads[bodyguard.whichgun] = level.guard_reloads;
	game->timeremaining = level.time;
	game->difficulty = level.difficulty;

	//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 = 10;

		// 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("blocks/0.off");
		game->blocks[1].load("blocks/1.off");
		game->blocks[2].load("blocks/2.off");
		game->blocks[3].load("blocks/3.off");
		game->sidewalkcollide.load("collide/sidewalk.off");
		game->blockwalls[0].load("collide/blocks/walls/0.off");
		game->blockwalls[1].load("collide/blocks/walls/1.off");
		game->blockwalls[2].load("collide/blocks/walls/2.off");
		game->blockwalls[3].load("collide/blocks/walls/3.off");
		game->blockroofs[0].load("collide/blocks/roofs/0.off");
		game->blockroofs[1].load("collide/blocks/roofs/1.off");
		game->blockroofs[2].load("collide/blocks/roofs/2.off");
		game->blockroofs[3].load("collide/blocks/roofs/3.off");
		game->blockcollide[0].load("collide/blocks/0.off");
		game->blockcollide[1].load("collide/blocks/1.off");
		game->blockcollide[2].load("collide/blocks/2.off");
		game->blockcollide[3].load("collide/blocks/3.off");
		game->blocksimplecollide[0].load("collide/blocks/simple/0.off");
		game->blocksimplecollide[1].load("collide/blocks/simple/1.off");
		game->blocksimplecollide[2].load("collide/blocks/simple/2.off");
		game->blocksimplecollide[3].load("collide/blocks/simple/3.off");
		game->blockocclude.load("blocks/occlude.off");
		game->blocksimple.load("blocks/simple.off");
		game->street.load("streets/small.off");
		game->Bigstreet.load("streets/big.off");
		game->path.load("streets/path.off");
	}

	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;

	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 person model
		skeletonmodels[0].load("skeleton/head.off");
		skeletonmodels[1].load("skeleton/chest.off");
		skeletonmodels[2].load("skeleton/abdomen.off");
		skeletonmodels[3].load("skeleton/arm.off");
		skeletonmodels[4].load("skeleton/forearm.off");
		skeletonmodels[5].load("skeleton/hand.off");
		skeletonmodels[6].load("skeleton/thigh.off");
		skeletonmodels[7].load("skeleton/leg.off");
		skeletonmodels[8].load("skeleton/foot.off");
		skeletonmodels[9].load("skeleton/shades.off");

		// Load weapon models
		gunmodels[sniperriflemodel].load("guns/sniper-rifle.off");
		gunmodels[assaultriflemodel].load("guns/assault-rifle.off");
		gunmodels[handgunbasemodel].load("guns/handgun-big-base.off");
		gunmodels[handgunslidemodel].load("guns/handgun-big-slide.off");
		gunmodels[handgun2basemodel].load("guns/handgun-small-base.off");
		gunmodels[handgun2slidemodel].load("guns/handgun-small-slide.off");
		gunmodels[grenadebasemodel].load("grenade/base.off");
		gunmodels[grenadepinmodel].load("grenade/pin.off");
		gunmodels[grenadespoonmodel].load("grenade/spoon.off");
		gunmodels[knifemodel].load("knife.off");
		gunmodels[shotgunmodel].load("guns/shotgun.off");
	}

	//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.reload();
	animation[idleanim].load("breathe");
	animation[crouchanim].load("crouch");
	animation[walkanim].load("walk-human");
	animation[joganim].load("run-human");
	animation[diveanim].load("dive");
	animation[rifleholdanim].load("hold-rifle");
	animation[rifleaimanim].load("aim-sniper-rifle");
	animation[assaultrifleaimanim].load("aim-assault-rifle");
	animation[pistolaimanim].load("aim-pistol");
	animation[grenadeaimanim].load("aim-grenade");
	animation[grenadechargeanim].load("charge-grenade");
	animation[grenadethrowanim].load("throw-grenade");
	animation[throwanim].load("throw-aikido");
	animation[thrownanim].load("thrown-aikido");
	animation[headpainanim].load("shot-head");
	animation[chestpainanim].load("shot-chest");
	animation[stomachpainanim].load("shot-stomach");
	animation[rightarmpainanim].load("shot-arm-right");
	animation[leftarmpainanim].load("shot-arm-left");
	animation[rightlegpainanim].load("shot-leg-right");
	animation[leftlegpainanim].load("shot-leg-left");
	animation[riflehitanim].load("hit-rifle");
	animation[getupfrontanim].load("get-up-from-front");
	animation[getupbackanim].load("get-up-from-back");
	animation[zombieeatanim].load("munch");
	animation[zombiejoganim].load("run-zombie");
	animation[zombiewalkanim].load("walk-zombie");

	// 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
		person.skeleton.reload();
	}

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

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

	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)
{
	glAlphaFunc(GL_GREATER, 0.01);
	glDepthFunc(GL_LESS);
	glPolygonOffset(-8,0);
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

	game->text.FontTexture = loadTexture("font.png");
	game->text.BuildFont();
	game->personspritetextureptr = loadTexture("sprites/person.png");
	game->deadpersonspritetextureptr = loadTexture("sprites/person-dead.png");
	game->scopetextureptr = loadTexture("scope.png");
	game->flaretextureptr = loadTexture("flare.png");

	sprites.flaretextureptr = loadTexture("sprites/flash-hit.png");
	sprites.muzzleflaretextureptr = loadTexture("sprites/flash-muzzle.png");
	sprites.smoketextureptr = loadTexture("sprites/smoke.png");
	sprites.bloodtextureptr = loadTexture("sprites/blood.png");
	sprites.raintextureptr = loadTexture("sprites/white.png");
	sprites.snowtextureptr = loadTexture("sprites/white.png");

	decals.bulletholetextureptr = loadTexture("black.png");
	decals.cratertextureptr = loadTexture("black.png");
	decals.bloodtextureptr[0u] = loadTexture("blood/00.png");
	decals.bloodtextureptr[1u] = loadTexture("blood/01.png");
	decals.bloodtextureptr[2u] = loadTexture("blood/02.png");
	decals.bloodtextureptr[3u] = loadTexture("blood/03.png");
	decals.bloodtextureptr[4u] = loadTexture("blood/04.png");
	decals.bloodtextureptr[5u] = loadTexture("blood/05.png");
	decals.bloodtextureptr[6u] = loadTexture("blood/06.png");
	decals.bloodtextureptr[7u] = loadTexture("blood/07.png");
	decals.bloodtextureptr[8u] = loadTexture("blood/08.png");
	decals.bloodtextureptr[9u] = loadTexture("blood/09.png");
	decals.bloodtextureptr[10] = loadTexture("blood/10.png");
}

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

struct Scores getScores(Game* game)
{
	return {
		.high_score = (size_t) game->highscore,
		.completed = game->beatgame,
	};
}

void closeGame(Game* game)
{
	const GLuint textures[] {
		game->personspritetextureptr,
		game->deadpersonspritetextureptr,
		game->scopetextureptr,
		game->flaretextureptr,
	};
	glDeleteTextures(4, textures);
	alDeleteSources(33 + game->musictoggle * 4, gSourceID);
	alDeleteBuffers(33 + game->musictoggle * 4, gSampleSet);
}