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