summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/GameDraw.cpp8
-rw-r--r--src/GameInitDispose.cpp21
-rw-r--r--src/GameLoop.cpp8
-rw-r--r--src/GameTick.cpp234
-rw-r--r--src/Person.cpp5
-rw-r--r--src/Sprites.cpp34
-rw-r--r--src/Support.cpp8
-rw-r--r--src/Support.h4
-rw-r--r--src/main.zig20
-rw-r--r--src/misc.h4
10 files changed, 128 insertions, 218 deletions
diff --git a/src/GameDraw.cpp b/src/GameDraw.cpp
index e783559..a916d7e 100644
--- a/src/GameDraw.cpp
+++ b/src/GameDraw.cpp
@@ -20,7 +20,7 @@
 // along with Black Shades.  If not, see <https://www.gnu.org/licenses/>.
 
 #include "Game.h"
-#include "Support.h"
+#include "misc.h"
 
 extern int thirdperson;
 extern float multiplier;
@@ -619,9 +619,9 @@ void Game::DrawGLScene(void)
 			if (person[0].aiming && person[0].whichgun != grenade
 			    && thirdperson == 0)
 				camerashake = 0;
-			glTranslatef(Random() % 100 / 100.0f * camerashake,
-				Random() % 100 / 100.0f * camerashake,
-				Random() % 100 / 100.0f * camerashake);
+			glTranslatef(randInt(-99, 99) / 100.0f * camerashake,
+				randInt(-99, 99) / 100.0f * camerashake,
+				randInt(-99, 99) / 100.0f * camerashake);
 		}
 		camera.Apply();
 
diff --git a/src/GameInitDispose.cpp b/src/GameInitDispose.cpp
index 50b848e..b95768e 100644
--- a/src/GameInitDispose.cpp
+++ b/src/GameInitDispose.cpp
@@ -20,15 +20,13 @@
 // 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 <initializer_list>
 
 #include <AL/alc.h>
 #include <GL/glu.h>
 
 #include "Game.h"
-#include "Support.h"
+#include "misc.h"
 
 extern unsigned int gSourceID[37];
 extern unsigned int gSampleSet[37];
@@ -279,9 +277,6 @@ void initGame(Game* game)
 		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");
@@ -330,11 +325,11 @@ void initGame(Game* game)
 
 	while (vip.pathnum < 0 || vip.pathnum == 1
 	       || vip.pathnum >= game->path.vertexNum)
-		vip.pathnum = Random() % game->path.vertexNum;
+		vip.pathnum = randUint(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.pathsize = 0.98f + 0.04f * randFloat();
 	vip.pathtarget *= vip.pathsize;
 	vip.pathtarget.x += vip.whichblockx * block_spacing;
 	vip.pathtarget.z += vip.whichblocky * block_spacing;
@@ -359,13 +354,13 @@ void initGame(Game* game)
 	game->spawndelay = 0.1f;
 
 	game->vipgoal = vip.playercoords
-		+ DoRotation({10000000.0f, 0.0f, 0.0f}, 0, Random() % 360, 0);
+		+ DoRotation({10000000.0f, 0.0f, 0.0f}, 0, randUint(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->cityrotation[i][j] = randUint(4);
+			game->citytype[i][j] = randUint(4);
 			game->citypeoplenum[i][j] = 0;
 		}
 
@@ -971,7 +966,7 @@ void initGame(Game* game)
 			person.whichcostume = bodyguardcostume;
 		else if (i > 1)
 			person.whichcostume = casualcostumes
-				+ abs(Random()) % numcasual;
+				+ randUint(numcasual);
 
 		// person.firstlongdead = 0;
 		person.dead = 0;
diff --git a/src/GameLoop.cpp b/src/GameLoop.cpp
index 3364bc2..9aaff92 100644
--- a/src/GameLoop.cpp
+++ b/src/GameLoop.cpp
@@ -20,7 +20,7 @@
 // along with Black Shades.  If not, see <https://www.gnu.org/licenses/>.
 
 #include "Game.h"
-#include "Support.h"
+#include "misc.h"
 
 extern float multiplier;
 extern int thirdperson;
@@ -194,9 +194,9 @@ void handleKey(Game* game, int key, int action, int mods)
 					0, person.playerrotation, 0);
 				joint.velocity += person.velocity;
 				joint.velocity += facing * 50;
-				joint.velocity.x += abs(Random() % 20) - 10;
-				joint.velocity.y += abs(Random() % 20) - 10;
-				joint.velocity.z += abs(Random() % 20) - 10;
+				joint.velocity.x += randInt(-9, 9);
+				joint.velocity.y += randInt(-9, 9);
+				joint.velocity.z += randInt(-9, 9);
 			}
 		}
 	} else if (key == keymap.switch_weapon) {
diff --git a/src/GameTick.cpp b/src/GameTick.cpp
index 9630a1b..a848289 100644
--- a/src/GameTick.cpp
+++ b/src/GameTick.cpp
@@ -21,12 +21,11 @@
 //
 // 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 <algorithm>
-#include <fstream>
 
 #include "Game.h"
-#include "Support.h"
+#include "misc.h"
 
 extern float multiplier;
 extern int thirdperson;
@@ -374,8 +373,8 @@ XYZ Game::aimPlayer()
 			aimrot = 4.0f;
 			break;
 		case shotgun:
-			aimrot = Random() % 1000 / 500.0f - 1;
-			aimrot2 = Random() % 1000 / 500.0f + 2;
+			aimrot = randInt(-1000, 1000) / 500.0f - 1;
+			aimrot2 = randInt(-1000, 1000) / 500.0f + 2;
 			break;
 		case handgun1:
 		case handgun2:
@@ -423,10 +422,8 @@ XYZ Game::aimBot(int j)
 	aim -= person[j].playercoords
 		+ DoRotation(lefthandpos, 0, person[j].playerrotation, 0);
 	return DoRotation(
-		DoRotation(
-			DoRotation(aim, 0, -person[j].playerrotation, 0),
-			(abs(Random() % 2000) / 2000.0 - 0.5) * inaccuracy,
-			(abs(Random() % 2000) / 2000.0 - 0.5) * inaccuracy, 0),
+		DoRotation(DoRotation(aim, 0, -person[j].playerrotation, 0),
+			randFloat() * inaccuracy, randFloat() * inaccuracy, 0),
 		0, person[j].playerrotation, 0);
 }
 
@@ -715,8 +712,8 @@ void Game::Tick()
 	int blockspawnx = 0, blockspawny = 0;
 	do {
 		auto block = person[0].playercoords / block_spacing;
-		blockspawnx = block.x + 0.5f + Random() % 2;
-		blockspawny = block.z + 0.5f + Random() % 2;
+		blockspawnx = block.x + 0.5f + randInt(-1, 1);
+		blockspawny = block.z + 0.5f + randInt(-1, 1);
 
 		auto& people = citypeoplenum[blockspawnx][blockspawny];
 		if (people < max_people_block)
@@ -726,55 +723,34 @@ void Game::Tick()
 	spawndelay -= multiplier;
 	if(cyclenum<10){
 
-	if(spawndelay<0&&numpeople<max_people){
-
-		if(type==randomshoot_type){
-
-			if(abs(Random()%evilprobability)==0)person[numpeople].type=eviltype;
-
-			else person[numpeople].type=civiliantype;
-
-		}
-
-		if(type==zombie_type){
-
-			person[numpeople].type=zombietype;
-
-		}
+	if (spawndelay < 0 && numpeople < max_people) {
+		if (type == zombie_type)
+			person[numpeople].type = zombietype;
+		else if (randUint(evilprobability))
+			person[numpeople].type = civiliantype;
+		else
+			person[numpeople].type = eviltype;
 
 		if(person[numpeople].type!=civiliantype&&blockspawnx==person[1].whichblockx&&blockspawny==person[1].whichblocky){
-
 			while((citypeoplenum[blockspawnx][blockspawny]>=max_people_block&&cyclenum<10)||blockspawnx==0||(blockspawnx==person[1].whichblockx&&blockspawny==person[1].whichblocky)){
-
-				blockspawnx=((person[0].playercoords.x+block_spacing/2)/block_spacing)+Random()%2;
-
-				blockspawny=((person[0].playercoords.z+block_spacing/2)/block_spacing)+Random()%2;
-
+				blockspawnx = (person[0].playercoords.x + block_spacing / 2) / block_spacing + randInt(-1, 1);
+				blockspawny = (person[0].playercoords.z + block_spacing / 2) / block_spacing + randInt(-1, 1);
 				cyclenum++;
-
 			}
-
 		}
 
 		person[numpeople].playerrotation=0;
-
-		person[numpeople].whichcostume=casualcostumes+abs(Random())%numcasual;
-
+		person[numpeople].whichcostume = casualcostumes + randUint(numcasual);
 		person[numpeople].whichblockx=blockspawnx;
-
 		person[numpeople].whichblocky=blockspawny;
-
 		person[numpeople].pathnum=-1;
-
 		person[numpeople].oldpathnum=-1;
-
 		person[numpeople].oldoldpathnum=-1;
-
 		person[numpeople].oldoldoldpathnum=-1;
 
 		while(person[numpeople].pathnum<0||person[numpeople].pathnum>=path.vertexNum||person[numpeople].pathnum==1){
 
-			person[numpeople].pathnum=Random()%path.vertexNum;
+			person[numpeople].pathnum = randUint(path.vertexNum);
 
 		}
 
@@ -782,7 +758,7 @@ void Game::Tick()
 
 		person[numpeople].pathtarget.z=path.vertex[person[numpeople].pathnum].z;
 
-		person[numpeople].pathsize=.98+float(abs(Random()%20))/400;
+		person[numpeople].pathsize = 0.98f + 0.04f * randFloat();
 
 		person[numpeople].pathtarget*=person[numpeople].pathsize;
 
@@ -804,7 +780,7 @@ void Game::Tick()
 
 		person[numpeople].existing=0;
 
-		person[numpeople].speedmult=.8+float(abs(Random()%20))/50;
+		person[numpeople].speedmult = 0.8f + 0.4f * randFloat();
 
 		person[numpeople].health=100;
 
@@ -853,64 +829,40 @@ void Game::Tick()
 		}
 
 		if(cycle<max_people&&cyclenum<max_people){
-
-			if(type==randomshoot_type){
-
-				if(abs(Random()%evilprobability)==0)person[cycle].type=eviltype;
-
-				else person[cycle].type=civiliantype;
-
-			}
-
-			if(type==zombie_type){
-
-				person[cycle].type=zombietype;
-
-			}
+			if (type == zombie_type)
+				person[cycle].type = zombietype;
+			else if (randUint(evilprobability))
+				person[cycle].type = civiliantype;
+			else
+				person[cycle].type = eviltype;
 
 			if(person[cycle].type!=civiliantype&&blockspawnx==person[1].whichblockx&&blockspawny==person[1].whichblocky){
-
 				while((citypeoplenum[blockspawnx][blockspawny]>=max_people_block&&cyclenum<10)||blockspawnx==0||(blockspawnx==person[1].whichblockx&&blockspawny==person[1].whichblocky)){
-
-					blockspawnx=((person[0].playercoords.x+block_spacing/2)/block_spacing)+Random()%2;
-
-					blockspawny=((person[0].playercoords.z+block_spacing/2)/block_spacing)+Random()%2;
-
+					blockspawnx = (person[0].playercoords.x + block_spacing / 2) / block_spacing + randInt(-1, 1);
+					blockspawny = (person[0].playercoords.z + block_spacing / 2) / block_spacing + randInt(-1, 1);
 					cyclenum++;
-
 				}
-
 			}
 
 			person[cycle].playerrotation=0;
-
-			person[cycle].whichcostume=casualcostumes+abs(Random())%numcasual;
-
+			person[cycle].whichcostume = casualcostumes + randUint(numcasual);
 			citypeoplenum[person[cycle].whichblockx][person[cycle].whichblocky]--;
-
 			person[cycle].whichblockx=blockspawnx;
-
 			person[cycle].whichblocky=blockspawny;
-
 			person[cycle].pathnum=-1;
-
 			person[cycle].oldpathnum=-1;
-
 			person[cycle].oldoldpathnum=-1;
-
 			person[cycle].oldoldoldpathnum=-1;
 
 			while(person[cycle].pathnum<0||person[cycle].pathnum>=path.vertexNum||person[cycle].pathnum==1){
-
-				person[cycle].pathnum=Random()%path.vertexNum;
-
+				person[cycle].pathnum = randUint(path.vertexNum);
 			}
 
 			person[cycle].pathtarget.x=path.vertex[person[cycle].pathnum].x;
 
 			person[cycle].pathtarget.z=path.vertex[person[cycle].pathnum].z;
 
-			person[cycle].pathsize=.98+float(abs(Random()%20))/400;
+			person[cycle].pathsize= 0.98f + 0.04f * randFloat();
 
 			person[cycle].pathtarget*=person[cycle].pathsize;
 
@@ -932,7 +884,7 @@ void Game::Tick()
 
 			person[cycle].existing=0;
 
-			person[cycle].speedmult=.8+float(abs(Random()%20))/50;
+			person[cycle].speedmult = 0.8f + 0.4f * randFloat();
 
 			person[cycle].health=100;
 
@@ -1428,7 +1380,7 @@ void Game::Tick()
 									person[i].pathnum=-1;
 
 									if(person[i].whichgun==nogun){
-										person[i].whichgun=possiblegun[abs(Random()%numpossibleguns)];
+										person[i].whichgun=possiblegun[randUint(numpossibleguns)];
 										person[i].reloads[person[i].whichgun]=1;
 										if(person[i].whichgun==knife)person[i].speedmult=.8+.5*difficulty;
 									}
@@ -1670,9 +1622,9 @@ void Game::Tick()
 					joint.position += person[person[0].killtarget].playercoords;
 					joint.realoldposition = joint.position;
 					joint.velocity = person[person[0].killtarget].velocity;
-					joint.velocity.x += abs(Random() % 10) - 5;
-					joint.velocity.y += abs(Random() % 10) - 5;
-					joint.velocity.z += abs(Random() % 10) - 5;
+					joint.velocity.x += randInt(-4, 4);
+					joint.velocity.y += randInt(-4, 4);
+					joint.velocity.z += randInt(-4, 4);
 				}
 
 				if(person[0].whichgun!=knife){
@@ -1718,9 +1670,9 @@ void Game::Tick()
 					joint.realoldposition = joint.position;
 					joint.velocity = person[person[0].killtarget].velocity;
 
-					joint.velocity.x += abs(Random() % 10) - 5;
-					joint.velocity.y += abs(Random() % 10) - 5;
-					joint.velocity.z += abs(Random() % 10) - 5;
+					joint.velocity.x += randInt(-4, 4);
+					joint.velocity.y += randInt(-4, 4);
+					joint.velocity.z += randInt(-4, 4);
 				}
 
 				if(person[0].whichgun!=knife){
@@ -1758,9 +1710,9 @@ void Game::Tick()
 				joint.realoldposition = joint.position;
 				joint.velocity = person[0].velocity;
 				joint.velocity.y = -10;
-				joint.velocity.x += abs(Random() % 10) - 5;
-				joint.velocity.y += abs(Random() % 10) - 5;
-				joint.velocity.z += abs(Random() % 10) - 5;
+				joint.velocity.x += randInt(-4, 4);
+				joint.velocity.y += randInt(-4, 4);
+				joint.velocity.z += randInt(-4, 4);
 			}
 		}
 	}
@@ -1898,7 +1850,7 @@ void Game::Tick()
 					rot2 = crouch ? 3.0f : 5.0f;
 					break;
 				case assaultrifle:
-					rot = Random() % 100 / (crouch ? 60.0f : 50.0f);
+					rot = randInt(-100, 100) / (crouch ? 60.0f : 50.0f);
 					rot2 = crouch ? 1.5f : 2.3f;
 					break;
 				}
@@ -1930,7 +1882,6 @@ void Game::Tick()
 			XYZ end {start + aim * 1000};
 			int bulletstrength=1;
 			int firstpass=-1;
-			bool penetrate;
 
 			for(int m=0;m<bulletstrength;m++){
 
@@ -2119,17 +2070,12 @@ void Game::Tick()
 
 					}
 
-					//penetrate
-
-						penetrate=abs(Random()%2)==1;
-
-						if(numshots>1)penetrate=0;
-
-						if(penetrate){bulletstrength=2;
-
-						firstpass=whichhit;
-
-						end=start+aim*1000;}
+					bool penetrate = (numshots > 1) ? 0 : !randUint(3);
+					if (penetrate) {
+						bulletstrength = 2;
+						firstpass = whichhit;
+						end = start + aim * 1000;
+					}
 
 					if(person[j].whichgun==assaultrifle)person[whichhit].health-=20;
 
@@ -2201,9 +2147,9 @@ void Game::Tick()
 								joint.position += person[whichhit].playercoords;
 								joint.realoldposition = joint.position;
 								joint.velocity = person[whichhit].velocity;
-								joint.velocity.x += (abs(Random()%20) - 10) / 2.0f;
-								joint.velocity.y += (abs(Random()%20) - 10) / 2.0f;
-								joint.velocity.z += (abs(Random()%20) - 10) / 2.0f;
+								joint.velocity.x += randInt(-4, 4);
+								joint.velocity.y += randInt(-4, 4);
+								joint.velocity.z += randInt(-4, 4);
 							}
 						}
 
@@ -2263,35 +2209,23 @@ void Game::Tick()
 						for (int j = 0; j < max_joints; ++j) {
 
 							if(&person[whichhit].skeleton.joints[j]==hitstruct.joint1||&person[whichhit].skeleton.joints[j]==hitstruct.joint2){
-
 								if (j != abdomen && j != groin && j != neck) {
-
-									sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,person[whichhit].skeleton.joints[j].position, person[whichhit].skeleton.joints[j].velocity/3, 9);
-
-									sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,person[whichhit].skeleton.joints[j].position, DoRotation(person[whichhit].skeleton.joints[j].velocity/3,Random()%360,Random()%360,0)/5, 5);
-
-									sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,person[whichhit].skeleton.joints[j].position, DoRotation(person[whichhit].skeleton.joints[j].velocity/3,Random()%360,Random()%360,0)/5, 5);
-
-									sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,person[whichhit].skeleton.joints[j].position, DoRotation(person[whichhit].skeleton.joints[j].velocity/3,Random()%360,Random()%360,0)/5, 5);
-
-									sprites.MakeSprite(bloodspritedown, .8, 1, .2, .2,person[whichhit].skeleton.joints[j].position, DoRotation(person[whichhit].skeleton.joints[j].velocity/3,Random()%360,Random()%360,0)/5, 5);
-
+									sprites.MakeSprite(bloodspritedown, 0.8f, 1, 0.2f, 0.2f,
+										person[whichhit].skeleton.joints[j].position,
+										person[whichhit].skeleton.joints[j].velocity / 3, 9);
+									for (int tmp = 0; tmp < 4; ++tmp)
+										sprites.MakeSprite(bloodspritedown, 0.8f, 1, 0.2f, 0.2f,
+											person[whichhit].skeleton.joints[j].position,
+											DoRotation(person[whichhit].skeleton.joints[j].velocity / 3,
+												randUint(360), randUint(360), 0) / 5, 5);
 									person[whichhit].skeleton.DeleteJoint(j);
-
 									person[whichhit].skeleton.broken=1;
-
 									person[whichhit].health=-10000;
-
 									person[whichhit].skeleton.joints[j].existing=0;
-
 									if(person[whichhit].type==zombietype)score+=300;
-
 								}
-
 							}
-
 						}
-
 					}
 
 					XYZ velocity;
@@ -2650,47 +2584,27 @@ void Game::Tick()
 	}
 
 	//Snow
-
 	snowdelay-=multiplier;
-
 	while(snowdelay<0&&environment==snowy_environment){
-
 		snowdelay+=1/precipitationdensity*2;
-
 		velocity=0;
-
 		velocity.y=-5;
-
 		start=camera.position;
-
 		start.y+=precipitationvert;
-
-		start.x+=Random()%(int)precipitationhorz;
-
-		start.z+=Random()%(int)precipitationhorz;
-
+		start.x += randUint(precipitationhorz);
+		start.z += randUint(precipitationhorz);
 		sprites.MakeSprite(snowsprite, 1, 1, 1, 1, start, velocity, 1.01);
-
 	}
 
 	while(snowdelay<0&&environment==rainy_environment){
-
 		snowdelay+=1/precipitationdensity/4;
-
 		velocity=0;
-
 		velocity.y=-100;
-
 		start=camera.position;
-
 		start.y+=precipitationvert;
-
-		start.x+=Random()%(int)precipitationhorz*.5;
-
-		start.z+=Random()%(int)precipitationhorz*.5;
-
+		start.x += randUint(precipitationhorz) * 0.5f;
+		start.z += randUint(precipitationhorz) * 0.5f;
 		sprites.MakeSprite(rainsprite, .5, 1, 1, 1, start, velocity, 2.00);
-
 	}
 
 	//Grenade collision
@@ -2748,7 +2662,7 @@ void Game::Tick()
 							soundpos.y / v / soundscalefactor,
 							soundpos.z / v / soundscalefactor,
 						};
-						whichsound = bouncesound + abs(Random()%2);
+						whichsound = bouncesound + randUint(2);
 						alSourcefv(gSourceID[whichsound], AL_POSITION, gLoc);
 						alSourcePlay(gSourceID[whichsound]);
 					}
@@ -2792,7 +2706,7 @@ void Game::Tick()
 							soundpos.y / v / soundscalefactor,
 							soundpos.z / v / soundscalefactor,
 						};
-						whichsound = bouncesound + abs(Random()%2);
+						whichsound = bouncesound + randUint(2);
 						alSourcefv(gSourceID[whichsound], AL_POSITION, gLoc);
 						if (sprites.size[i] <= 1)
 							alSourcePlay(gSourceID[whichsound]);
@@ -2845,9 +2759,9 @@ void Game::Tick()
 											+ person[j].playercoords;
 
 										joint.velocity = person[j].velocity;
-										joint.velocity.x += abs(Random()%10)-5;
-										joint.velocity.y += abs(Random()%10)-5;
-										joint.velocity.z += abs(Random()%10)-5;
+										joint.velocity.x += randInt(-4, 4);
+										joint.velocity.y += randInt(-4, 4);
+										joint.velocity.z += randInt(-4, 4);
 									}
 
 									hitstruct.joint1->velocity += sprites.velocity[i];
@@ -2998,9 +2912,9 @@ void Game::Tick()
 							joint.realoldposition = joint.position;
 							joint.velocity = DoRotation(joint.velocity, 0, person[k].playerrotation, 0);
 							joint.velocity += person[k].velocity;
-							joint.velocity.x += abs(Random() % 20) - 10;
-							joint.velocity.y += abs(Random() % 20) - 10;
-							joint.velocity.z += abs(Random() % 20) - 10;
+							joint.velocity.x += randInt(-9, 9);
+							joint.velocity.y += randInt(-9, 9);
+							joint.velocity.z += randInt(-9, 9);
 						}}
 
 						person[k].longdead=1;
@@ -3015,7 +2929,7 @@ void Game::Tick()
 
 							// Sever stuff
 							if (findLengthfast(joint.velocity) > 1500
-							    && joint.existing && abs(Random() % 3) != 1) {
+							    && joint.existing && randUint(5)) {
 								sprites.MakeSprite(bloodspritedown, 0.8, 1, 0.2, 0.2, joint.position, joint.velocity / 3, 9);
 								person[k].skeleton.DeleteJoint(&joint
 									- person[k].skeleton.joints);
diff --git a/src/Person.cpp b/src/Person.cpp
index 888ea8f..dca3bbb 100644
--- a/src/Person.cpp
+++ b/src/Person.cpp
@@ -22,7 +22,6 @@
 #include <GLFW/glfw3.h>
 
 #include "Person.h"
-#include "Support.h"
 #include "config.h"
 #include "misc.h"
 
@@ -212,7 +211,7 @@ void Person::DoAnimations(int who)
 			|| targetanimation == walkanim)
 		    && (targetframe == 0 || targetframe == 8) && who == 0) {
 			auto soundsrc = playercoords - camera.position;
-			playSound(gSourceID[footstepsound + abs(Random()) % 5],
+			playSound(gSourceID[footstepsound + randUint(5)],
 				soundsrc.x, soundsrc.y, soundsrc.z);
 		}
 
@@ -574,7 +573,7 @@ void Person::DoAnimationslite(int who)
 		        || targetanimation == walkanim)
 		    && (targetframe == 0 || targetframe == 8)) {
 			auto soundsrc = playercoords - camera.position;
-			playSound(gSourceID[footstepsound + abs(Random()) % 5],
+			playSound(gSourceID[footstepsound + randUint(5)],
 				soundsrc.x, soundsrc.y, soundsrc.z);
 		}
 
diff --git a/src/Sprites.cpp b/src/Sprites.cpp
index fa43ae8..68a79dc 100644
--- a/src/Sprites.cpp
+++ b/src/Sprites.cpp
@@ -2,7 +2,7 @@
 #include "Fog.h"
 #include "Models.h"
 #include "Sprites.h"
-#include "Support.h"
+#include "misc.h"
 
 extern float multiplier;
 extern bool slomo;
@@ -21,30 +21,20 @@ extern float precipitationvert;
 extern float precipitationdensity;
 extern float snowdelay;
 
-int Sprites::MakeSprite(int atype, float abrightness, float acolor1, float acolor2, float acolor3, XYZ alocation, XYZ avelocity, float asize){
-	type[howmanysprites]=atype;
-	rotation[howmanysprites]=Random()%360;
-	brightness[howmanysprites]=abrightness;
-	color1[howmanysprites]=acolor1;
-	color2[howmanysprites]=acolor2;
-	color3[howmanysprites]=acolor3;
-	location[howmanysprites]=alocation;
-	oldlocation[howmanysprites]=alocation;
-	velocity[howmanysprites]=avelocity;
-	size[howmanysprites]=asize;
-	initialsize[howmanysprites]=asize;
-	initialbrightness[howmanysprites]=abrightness;
-	initialvelocity[howmanysprites]=avelocity;
-	alivetime[howmanysprites]=0;
-	owner[howmanysprites]=0;
-	if(howmanysprites<maxsprites){howmanysprites++;}
-
-	return 0;
+int Sprites::MakeSprite(int atype, float abrightness,
+	float acolor1, float acolor2, float acolor3,
+	XYZ alocation, XYZ avelocity, float asize)
+{
+	return MakeSprite(atype, abrightness, acolor1, acolor2, acolor3,
+		alocation, avelocity, asize, 0);
 }
 
-int Sprites::MakeSprite(int atype, float abrightness, float acolor1, float acolor2, float acolor3, XYZ alocation, XYZ avelocity, float asize, int aowner){
+int Sprites::MakeSprite(int atype, float abrightness,
+	float acolor1, float acolor2, float acolor3,
+	XYZ alocation, XYZ avelocity, float asize, int aowner)
+{
 	type[howmanysprites]=atype;
-	rotation[howmanysprites]=Random()%360;
+	rotation[howmanysprites] = randUint(360);
 	brightness[howmanysprites]=abrightness;
 	color1[howmanysprites]=acolor1;
 	color2[howmanysprites]=acolor2;
diff --git a/src/Support.cpp b/src/Support.cpp
deleted file mode 100644
index 2f24e94..0000000
--- a/src/Support.cpp
+++ /dev/null
@@ -1,8 +0,0 @@
-#include <stdlib.h>
-
-#include "Support.h"
-
-int Random()
-{
-	return (rand() % 65535) - 32767;
-}
diff --git a/src/Support.h b/src/Support.h
deleted file mode 100644
index a5683ec..0000000
--- a/src/Support.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#ifndef SUPPORT_H
-#define SUPPORT_H
-int Random();
-#endif
diff --git a/src/main.zig b/src/main.zig
index f6a2353..8cdfb6e 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -16,6 +16,7 @@
 // You should have received a copy of the GNU General Public License
 // along with Black Shades.  If not, see <https://www.gnu.org/licenses/>.
 
+const DefaultPrng = std.rand.DefaultPrng;
 const allocator = std.heap.c_allocator;
 const free = std.c.free;
 const std = @import("std");
@@ -33,6 +34,7 @@ const loadScores = misc.loadScores;
 const saveScores = misc.saveScores;
 
 var game: *c.Game = undefined;
+var prng: DefaultPrng = undefined;
 
 fn resizeWindow(window: gf.Window, width: c_int, height: c_int) void {
     c.resizeWindow(game, width, height);
@@ -52,6 +54,23 @@ fn click(window: gf.Window, button: gf.MouseButton,
     c.click(game, @enumToInt(button), @enumToInt(action), mods.toInt());
 }
 
+/// Return a floating point value evenly distributed in the range [0, 1).
+export fn randFloat() f32 {
+    return prng.random.float(f32);
+}
+
+/// Return a random integer i where at_least <= i <= at_most.
+/// The results of this function may be biased.
+export fn randInt(at_least: i32, at_most: i32) i32 {
+    return prng.random.intRangeAtMostBiased(i32, at_least, at_most);
+}
+
+/// Return a random integer i where 0 <= i < less_than.
+/// The results of this function may be biased.
+export fn randUint(less_than: u32) u32 {
+    return prng.random.uintLessThanBiased(u32, less_than);
+}
+
 pub fn main() !void {
     const loca = try Loca.init(allocator, .{});
     defer loca.deinit();
@@ -64,6 +83,7 @@ pub fn main() !void {
                                         "Black Shades", .{}, .{});
     try window.makeCurrent();
 
+    prng = DefaultPrng.init(@floatToInt(u64, try gf.getTime()));
     game = c.makeGame(@bitCast(c.Config, config),
                       @bitCast(c.Scores, try loadScores(loca.user_data))).?;
     defer saveScores(loca.user_data, @bitCast(Scores, c.getScores(game)))
diff --git a/src/misc.h b/src/misc.h
index 36880ff..a6b5e6b 100644
--- a/src/misc.h
+++ b/src/misc.h
@@ -3,6 +3,7 @@
 
 #include <stdbool.h>
 #include <stddef.h>
+#include <stdint.h>
 
 #include <AL/al.h>
 #include <GL/gl.h>
@@ -62,6 +63,9 @@ extern "C" {
 	ALuint loadSound(const char*);
 	GLuint loadTexture(const char*);
 	void playSound(ALuint source, ALfloat x, ALfloat y, ALfloat z);
+	float randFloat();
+	int32_t randInt(int32_t at_least, int32_t at_most);
+	uint32_t randUint(uint32_t less_than);
 #ifdef __cplusplus
 } // extern "C"
 #endif // __cplusplus