// 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-2023 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 . #include #include #include "Game.h" #include "misc.h" extern unsigned int gSourceID[37]; extern unsigned int gSampleSet[37]; extern Camera camera; extern Skeleton testskeleton; extern Sprites sprites; extern Model skeletonmodels[10]; extern Model gunmodels[11]; extern Costume costume[10]; extern Animation animation[30]; extern bool 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 struct Key keymap; void resizeWindow(Game* game, int width, int height) { game->screenwidth = width; game->screenheight = height; glViewport(0, 0, width, height); } 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[munchsound] = loadSound("impact/munch.wav"); gSampleSet[rainsound] = loadSound("rain.ogg"); if (musictoggle) { gSampleSet[mainmenusong] = loadSound("music/menu.opus"); gSampleSet[assassinsong] = loadSound("music/assassin.opus"); gSampleSet[zombiesong] = loadSound("music/zombie.opus"); } 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[losesound] = loadSound("Lose.ogg"); gSampleSet[disguisekillsound] = loadSound("disguise-kill.ogg"); alGenSources(34, 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[munchsound], AL_BUFFER, gSampleSet[munchsound]); alSourcei(gSourceID[rainsound], AL_BUFFER, gSampleSet[rainsound]); alSourcei(gSourceID[rainsound], AL_LOOPING, 1); 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(3, gSourceID + 34); alSourcei(gSourceID[mainmenusong], AL_BUFFER, gSampleSet[mainmenusong]); alSourcei(gSourceID[mainmenusong], AL_LOOPING, 1); alSourcei(gSourceID[assassinsong], AL_BUFFER, gSampleSet[assassinsong]); alSourcei(gSourceID[assassinsong], AL_LOOPING, 1); alSourcei(gSourceID[zombiesong], AL_BUFFER, gSampleSet[zombiesong]); alSourcei(gSourceID[zombiesong], 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[mainmenusong], AL_POSITION, {}); alSourcefv(gSourceID[assassinsong], AL_POSITION, {}); alSourcefv(gSourceID[zombiesong], AL_POSITION, {}); } } void loadModels(Game* game) { game->blocks[0] = loadModel("blocks/0.off"); game->blocks[1] = loadModel("blocks/1.off"); game->blocks[2] = loadModel("blocks/2.off"); game->blocks[3] = loadModel("blocks/3.off"); game->sidewalkcollide = loadModel("collide/sidewalk.off"); game->blockwalls[0] = loadModel("collide/blocks/walls/0.off"); game->blockwalls[1] = loadModel("collide/blocks/walls/1.off"); game->blockwalls[2] = loadModel("collide/blocks/walls/2.off"); game->blockwalls[3] = loadModel("collide/blocks/walls/3.off"); game->blockroofs[0] = loadModel("collide/blocks/roofs/0.off"); game->blockroofs[1] = loadModel("collide/blocks/roofs/1.off"); game->blockroofs[2] = loadModel("collide/blocks/roofs/2.off"); game->blockroofs[3] = loadModel("collide/blocks/roofs/3.off"); game->blockcollide[0] = loadModel("collide/blocks/0.off"); game->blockcollide[1] = loadModel("collide/blocks/1.off"); game->blockcollide[2] = loadModel("collide/blocks/2.off"); game->blockcollide[3] = loadModel("collide/blocks/3.off"); game->blocksimplecollide[0] = loadModel("collide/blocks/simple/0.off"); game->blocksimplecollide[1] = loadModel("collide/blocks/simple/1.off"); game->blocksimplecollide[2] = loadModel("collide/blocks/simple/2.off"); game->blocksimplecollide[3] = loadModel("collide/blocks/simple/3.off"); game->blockocclude = loadModel("blocks/occlude.off"); game->blocksimple = loadModel("blocks/simple.off"); game->street = loadModel("streets/small.off"); game->Bigstreet = loadModel("streets/big.off"); skeletonmodels[0] = loadModel("skeleton/head.off"); skeletonmodels[1] = loadModel("skeleton/chest.off"); skeletonmodels[2] = loadModel("skeleton/abdomen.off"); skeletonmodels[3] = loadModel("skeleton/arm.off"); skeletonmodels[4] = loadModel("skeleton/forearm.off"); skeletonmodels[5] = loadModel("skeleton/hand.off"); skeletonmodels[6] = loadModel("skeleton/thigh.off"); skeletonmodels[7] = loadModel("skeleton/leg.off"); skeletonmodels[8] = loadModel("skeleton/foot.off"); skeletonmodels[9] = loadModel("skeleton/shades.off"); gunmodels[sniperriflemodel] = loadModel("guns/sniper-rifle.off"); gunmodels[assaultriflemodel] = loadModel("guns/assault-rifle.off"); gunmodels[handgunbasemodel] = loadModel("guns/handgun-big-base.off"); gunmodels[handgunslidemodel] = loadModel("guns/handgun-big-slide.off"); gunmodels[handgun2basemodel] = loadModel("guns/handgun-small-base.off"); gunmodels[handgun2slidemodel] = loadModel("guns/handgun-small-slide.off"); gunmodels[grenadebasemodel] = loadModel("grenade/base.off"); gunmodels[grenadepinmodel] = loadModel("grenade/pin.off"); gunmodels[grenadespoonmodel] = loadModel("grenade/spoon.off"); gunmodels[knifemodel] = loadModel("knife.off"); gunmodels[shotgunmodel] = loadModel("guns/shotgun.off"); } Game* makeGame(void *decals, Config config, Scores scores) { auto game = new Game(); game->decals = decals; loadModels(game); // FIXME: free models game->screenwidth = config.width; game->screenheight = config.height; blood = config.blood; game->musictoggle = config.music; game->mouse_sensitivity = config.mouse_sensitivity; keymap = config.key; game->levels = config.levels.ptr; game->nummissions = config.levels.len; game->debug = config.debug; game->highscore = scores.high_score; game->beatgame = scores.completed; setMenu(game, true); return game; } 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 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 = false; //Setup bounding cylinder model float boundingscale=3; if (!game->initialized) { auto& point0 = game->boundingpoints[0]; point0.x = point0.y = 0; point0.z = boundingscale; for (int i = 1; i < 8; ++i) game->boundingpoints[i] = rotate(point0, 0, i * 360 / 7, 0); } game->civkills = 0; game->badkills = 0; game->goodkills = 0; game->enemystate = 2; if (!game->initialized) { soundscalefactor = 10; loadSounds(game->musictoggle); if (game->musictoggle) alSourcePlay(gSourceID[game->whichsong = mainmenusong]); } auto& vip = game->person[game->numpeople = 1]; vip.type = viptype; vip.whichgun = nogun; vip.aiming = false; vip.killtarget = -1; vip.existing = true; 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 = -1; vip.pathnum = randUint(8); vip.pathtarget.x = DIRECTIONS[vip.pathnum].x; vip.pathtarget.z = DIRECTIONS[vip.pathnum].z; vip.pathsize = 0.98f + 0.04f * randFloat(); 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.x = vip.playercoords.x; bodyguard.playercoords.z = vip.playercoords.z; 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; // Init city block rotations for (int i = 0; i < num_blocks; ++i) for (int j = 0; j < num_blocks; ++j) { game->cityrotation[i][j] = randUint(4); game->citytype[i][j] = randUint(4); game->citypeoplenum[i][j] = 0; } //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 + randUint(numcasual); // person.firstlongdead = 0; person.dead = 0; person.health = 100; person.skeleton.free = 0; person.ammo = 0; person.velocity = {}; // Load skeleton structure person.skeleton.reload(); } bodyguard.attackframe = -1; game->spawndelay = 0; setFog(&fog, 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); glClearColor(fogcolorr,fogcolorg,fogcolorb,1); game->initialized = true; 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); glEnable(GL_BLEND); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); game->text.texture = loadTexture("font.qoi"); buildFont(&game->text); game->personspritetextureptr = loadTexture("sprites/person.qoi"); game->deadpersonspritetextureptr = loadTexture("sprites/person-dead.qoi"); game->scopetextureptr = loadTexture("scope.qoi"); game->flaretextureptr = loadTexture("flare.qoi"); sprites.flaretextureptr = loadTexture("sprites/flash-hit.qoi"); sprites.muzzleflaretextureptr = loadTexture("sprites/flash-muzzle.qoi"); sprites.smoketextureptr = loadTexture("sprites/smoke.qoi"); sprites.bloodtextureptr = loadTexture("sprites/blood.qoi"); sprites.raintextureptr = loadTexture("sprites/white.qoi"); sprites.snowtextureptr = loadTexture("sprites/snowflake.qoi"); } struct Scores getScores(Game* game) { return { .high_score = (size_t) game->highscore, .completed = game->beatgame, }; } void destroyModels(Game* game) { for (unsigned char i = 0; i < 4; ++i) { destroyModel(game->blocks + i); destroyModel(game->blockwalls + i); destroyModel(game->blockroofs + i); destroyModel(game->blockcollide + i); destroyModel(game->blocksimplecollide + i); } destroyModel(&game->sidewalkcollide); destroyModel(&game->blockocclude); destroyModel(&game->blocksimple); destroyModel(&game->street); destroyModel(&game->Bigstreet); for (unsigned char i = 0; i < 10; ++i) destroyModel(skeletonmodels + i); for (unsigned char i = 0; i < 11; ++i) destroyModel(gunmodels + i); } void closeGame(Game* game) { const GLuint textures[] { game->text.texture, game->personspritetextureptr, game->deadpersonspritetextureptr, game->scopetextureptr, game->flaretextureptr, }; glDeleteTextures(5, textures); alDeleteSources(34 + game->musictoggle * 3, gSourceID); alDeleteBuffers(34 + game->musictoggle * 3, gSampleSet); destroyModels(game); }