summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/GameDraw.cpp23
-rw-r--r--src/GameLoop.cpp6
-rw-r--r--src/GameTick.cpp155
-rw-r--r--src/Models.cpp2
-rw-r--r--src/Person.cpp4
-rw-r--r--src/Quaternions.cpp8
-rw-r--r--src/Quaternions.h3
-rw-r--r--src/Skeleton.cpp4
-rw-r--r--src/Sprites.cpp2
-rw-r--r--src/misc.zig5
10 files changed, 115 insertions, 97 deletions
diff --git a/src/GameDraw.cpp b/src/GameDraw.cpp
index 010fbc0..1fbbca2 100644
--- a/src/GameDraw.cpp
+++ b/src/GameDraw.cpp
@@ -508,7 +508,8 @@ void Game::DrawGLScene(void)
 					move.y=0;
 					move.x=i*block_spacing;
 					move.z=j*block_spacing;
-					if(findDistancefast(move,camera.position)<300000)drawn[i][j]=0;
+					if (sqrlen(move - camera.position) < 300000)
+						drawn[i][j] = 0;
 				}
 			}
 		}
@@ -553,8 +554,8 @@ void Game::DrawGLScene(void)
 				}else draw=0;
 				if(draw)
 				if(!cubeInFrustum(frustum, person[i].playercoords.x,person[i].playercoords.y,person[i].playercoords.z,5))draw=0;
-				if(draw)
-				if(findDistancefast(person[i].playercoords,camera.position)>1000000)draw=0;
+				if (draw && sqrlen(person[i].playercoords - camera.position) > 1000000)
+					draw = 0;
 				if(draw)
 				for(int j=beginx;j<=endx;j++){
 					for(int k=beginz;k<=endz;k++){
@@ -562,7 +563,7 @@ void Game::DrawGLScene(void)
 							move.y=0;
 							move.x=j*block_spacing;
 							move.z=k*block_spacing;
-							if(findDistancefast(move,camera.position)<100000){
+							if (sqrlen(move - camera.position) < 100000) {
 								whichtri=blockocclude.LineCheck2(camera.position,person[i].playercoords,&collpoint,move,0);
 								if(whichtri!=-1)draw=0;
 							}
@@ -583,8 +584,8 @@ void Game::DrawGLScene(void)
 			if(person[i].skeleton.free==1){
 				if(draw)
 				if(!person[i].skeleton.broken&&!cubeInFrustum(frustum, person[i].averageloc.x,person[i].averageloc.y,person[i].averageloc.z,5))draw=0;
-				if(draw)
-				if(findDistancefast(person[i].averageloc,camera.position)>1000000)draw=0;
+				if (draw && sqrlen(person[i].averageloc - camera.position) > 1000000)
+					draw = 0;
 				if(draw)
 				if(person[i].skeleton.joints[0].position.y<-2)draw=0;
 
@@ -594,7 +595,7 @@ void Game::DrawGLScene(void)
 							move.y=0;
 							move.x=j*block_spacing;
 							move.z=k*block_spacing;
-							if(findDistancefast(move,camera.position)<100000){
+							if (sqrlen(move - camera.position) < 100000) {
 								whichtri=blockocclude.LineCheck2(camera.position,person[i].averageloc,&collpoint,move,0);
 								if(whichtri!=-1)draw=0;
 							}
@@ -612,7 +613,10 @@ void Game::DrawGLScene(void)
 			}
 
 			if(draw&&person[i].existing==1){
-				if((findDistancefast(person[i].playercoords,camera.position)<100000+zoom*3000000&&person[i].skeleton.free<1)||(findDistancefast(person[i].averageloc,camera.position)<100000+zoom*3000000&&person[i].skeleton.free>=1)){
+				if ((sqrlen(person[i].playercoords - camera.position) < 100000 + zoom * 3000000
+				     && !person[i].skeleton.free)
+				    || (sqrlen(person[i].averageloc - camera.position) < 100000 + zoom * 3000000
+					&& person[i].skeleton.free)) {
 					glPushMatrix();
 						if(person[i].skeleton.free==0){
 							glTranslatef(person[i].playercoords.x,person[i].playercoords.y,person[i].playercoords.z);
@@ -666,7 +670,8 @@ void Game::DrawGLScene(void)
 			}
 			if(person[i].skeleton.free<1&&!draw)person[i].DoAnimationslite(i);
 			if(!person[i].existing)
-				if(!draw||findDistancefast(person[i].playercoords,camera.position)>10000){person[i].existing=1;}
+				if (!draw || sqrlen(person[i].playercoords - camera.position) > 10000)
+					person[i].existing = 1;
 		}
 		glDisable(GL_COLOR_MATERIAL);
 		glDisable(GL_BLEND);
diff --git a/src/GameLoop.cpp b/src/GameLoop.cpp
index f9eefcc..c3eefad 100644
--- a/src/GameLoop.cpp
+++ b/src/GameLoop.cpp
@@ -84,8 +84,7 @@ void handleKey(Game* game, int key, int action, int mods)
 			for (int i = 1; i < game->numpeople; ++i) {
 				auto& person = game->person[i];
 				if (!person.skeleton.free
-				    || findDistancefast(player.playercoords,
-				                        person.averageloc) > 200)
+				    || sqrlen(player.playercoords - person.averageloc) > 200)
 					continue;
 
 				auto soundpos = player.playercoords - camera.position;
@@ -179,8 +178,7 @@ void handleKey(Game* game, int key, int action, int mods)
 		for (int i = 1; i < game->numpeople; i++) {
 			auto& person = game->person[i];
 			if (person.skeleton.free == 1
-			    || findDistancefast(person.playercoords,
-						player.playercoords) > 1000)
+			    || sqrlen(person.playercoords - player.playercoords) > 1000)
 				continue;
 			person.skeleton.free = 1;
 			person.longdead = 1;
diff --git a/src/GameTick.cpp b/src/GameTick.cpp
index fc5305b..3f42796 100644
--- a/src/GameTick.cpp
+++ b/src/GameTick.cpp
@@ -202,8 +202,8 @@ void click(Game* game, int button, int action, int mods)
 			auto& person = game->person[i];
 			if (person.type == viptype || person.skeleton.free)
 				continue;
-			auto distance = findDistancefast(person.playercoords,
-				player.playercoords + flatfacing);
+			auto distance = sqrlen(player.playercoords + flatfacing
+				- person.playercoords);
 			if (distance > 12 + (weapon == knife) * 10)
 				continue;
 			if (closedistance == 0 || distance < closedistance) {
@@ -233,8 +233,8 @@ void click(Game* game, int button, int action, int mods)
 			auto& person = game->person[i];
 			if (person.skeleton.free || person.whichgun == nogun)
 				continue;
-			auto distance = findDistancefast(person.playercoords,
-				player.playercoords + flatfacing);
+			auto distance = sqrlen(player.playercoords + flatfacing
+				- person.playercoords);
 			if (distance > 12)
 				continue;
 			attacking = true;
@@ -711,9 +711,9 @@ void tackle(Game* game, XYZ flatfacing)
 	auto& player = game->person[0];
 	for (int i = 1; i < game->numpeople; ++i) {
 		auto& person = game->person[i];
-		if (person.skeleton.free > 0
-		    || findDistancefast(person.playercoords,
-		                        player.playercoords + flatfacing) > 22)
+		if (person.skeleton.free
+		    || sqrlen(player.playercoords + flatfacing
+		              - person.playercoords) > 22)
 			continue;
 
 		float gLoc[] {
@@ -858,7 +858,7 @@ void controlZombie(Game* game, size_t i)
 	if (zombie.type != zombietype)
 		return;
 	auto& vip = game->person[1];
-	if (findDistancefast(zombie.playercoords, vip.playercoords) > 20000
+	if (sqrlen(zombie.playercoords - vip.playercoords) > 20000
 	    || zombie.speedmult < 0.7f) {
 		zombie.killtarget = -1;
 		return;
@@ -968,12 +968,12 @@ void renderLaser(Game* game)
 	int whichhit = -1;
 	for (auto i = 1; i < game->numpeople; ++i) {
 		auto& person = game->person[i];
-		if (findDistancefast(coords, person.playercoords) > 20000)
+		if (sqrlen(coords -  person.playercoords) > 20000)
 			continue;
 		auto hit = person.BulletCollideWithPlayer(i, start, end);
 		if (!hit.collision)
 			continue;
-		auto distance = findDistancefast(start, hit.hitlocation);
+		auto distance = sqrlen(start - hit.hitlocation);
 		if (distance < olddistance || whichhit == -1) {
 			olddistance = distance;
 			whichhit = i;
@@ -1058,11 +1058,8 @@ void Game::Tick()
 				// Realcheck tells us
 				// a) we've got close to the end of our path or
 				// b) we're moving away from our target
-				auto moving_away
-					= findDistancefast(person[i].pathtarget,
-						person[i].playercoords)
-					> findDistancefast(person[i].pathtarget,
-						person[i].oldplayercoords);
+				auto moving_away = sqrlen(person[i].pathtarget - person[i].playercoords)
+					> sqrlen(person[i].pathtarget - person[i].oldplayercoords);
 				realcheck = (abs(person[i].playercoords.x
 						- person[i].pathtarget.x) < 1
 					&& abs(person[i].playercoords.z
@@ -1091,9 +1088,12 @@ void Game::Tick()
 							person[i].pathtarget.x += person[i].whichblockx*block_spacing;
 							person[i].pathtarget.z += person[i].whichblocky*block_spacing;
 
-							if(findDistancefast(person[i].playercoords,person[i].pathtarget)<leastdistance&&j!=1&&j!=person[i].oldpathnum&&j!=person[i].oldoldpathnum&&j!=person[i].oldoldoldpathnum){
-								leastdistance=findDistancefast(person[i].playercoords,person[i].pathtarget);
-								closesttarget=j;
+							if (sqrlen(person[i].playercoords - person[i].pathtarget) < leastdistance
+							    && j != 1 && j != person[i].oldpathnum
+							    && j != person[i].oldoldpathnum
+							    && j != person[i].oldoldoldpathnum){
+								leastdistance = sqrlen(person[i].playercoords - person[i].pathtarget);
+								closesttarget = j;
 							}
 						}
 
@@ -1151,9 +1151,12 @@ void Game::Tick()
 										person[i].pathtarget.x+=l*block_spacing;
 										person[i].pathtarget.z+=m*block_spacing;
 
-										if(findDistancefast(person[i].playercoords,person[i].pathtarget)<leastdistance&&findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords)>findDistancefast(person[i].playercoords,person[person[i].killtarget].playercoords)&&j!=1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[person[i].whichblockx][person[i].whichblocky])==-1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[l][m])==-1){
-											person[i].lastdistancevictim=findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords);
-											leastdistance=findDistancefast(person[i].playercoords,person[i].pathtarget);
+										if (sqrlen(person[i].playercoords - person[i].pathtarget) < leastdistance
+										    && sqrlen(person[i].pathtarget - person[person[i].killtarget].playercoords) > sqrlen(person[i].playercoords - person[person[i].killtarget].playercoords)
+										    && j != 1 && blocksimple.LineCheck2(person[i].playercoords, person[i].pathtarget, &blah, move, cityrotation[person[i].whichblockx][person[i].whichblocky]) == -1
+										    && blocksimple.LineCheck2(person[i].playercoords, person[i].pathtarget, &blah, move, cityrotation[l][m]) == -1) {
+											person[i].lastdistancevictim = sqrlen(person[i].pathtarget - person[person[i].killtarget].playercoords);
+											leastdistance - sqrlen(person[i].playercoords - person[i].pathtarget);
 											closesttarget=j;
 											finaltarget=person[i].pathtarget;
 											person[i].whichblockx=l;
@@ -1223,9 +1226,11 @@ void Game::Tick()
 							person[i].pathtarget.x+=person[i].whichblockx*block_spacing;
 							person[i].pathtarget.z+=person[i].whichblocky*block_spacing;
 
-							if(findDistancefast(person[i].playercoords,person[i].pathtarget)<leastdistance&&findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords)<person[i].lastdistancevictim&&j!=1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[person[i].whichblockx][person[i].whichblocky])==-1){
-								leastdistance=findDistancefast(person[i].playercoords,person[i].pathtarget);
-								person[i].lastdistancevictim=findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords);
+							if (sqrlen(person[i].playercoords - person[i].pathtarget) < leastdistance
+							    && sqrlen(person[i].pathtarget - person[person[i].killtarget].playercoords) < person[i].lastdistancevictim
+							    && j != 1 && blocksimple.LineCheck2(person[i].playercoords, person[i].pathtarget, &blah, move, cityrotation[person[i].whichblockx][person[i].whichblocky]) == -1) {
+								leastdistance = sqrlen(person[i].playercoords - person[i].pathtarget);
+								person[i].lastdistancevictim = sqrlen(person[i].pathtarget - person[person[i].killtarget].playercoords);
 								closesttarget=j;
 								finaltarget=person[i].pathtarget;
 							}
@@ -1240,9 +1245,11 @@ void Game::Tick()
 							person[i].pathtarget.x+=person[i].whichblockx*block_spacing;
 							person[i].pathtarget.z+=person[i].whichblocky*block_spacing;
 
-							if(findDistancefast(person[i].playercoords,person[i].pathtarget)<leastdistance&&findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords)<person[i].lastdistancevictim&&j!=1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[person[i].whichblockx][person[i].whichblocky])==-1){
-								leastdistance=findDistancefast(person[i].playercoords,person[i].pathtarget);
-								person[i].lastdistancevictim=findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords);
+							if (sqrlen(person[i].playercoords - person[i].pathtarget) < leastdistance
+							    && sqrlen(person[i].pathtarget - person[person[i].killtarget].playercoords) < person[i].lastdistancevictim
+							    && j != 1 && blocksimple.LineCheck2(person[i].playercoords, person[i].pathtarget, &blah, move, cityrotation[person[i].whichblockx][person[i].whichblocky]) == -1) {
+								leastdistance = sqrlen(person[i].playercoords - person[i].pathtarget);
+								person[i].lastdistancevictim = sqrlen(person[i].pathtarget - person[person[i].killtarget].playercoords);
 								closesttarget=j;
 								finaltarget=person[i].pathtarget;
 							}
@@ -1272,8 +1279,11 @@ void Game::Tick()
 										person[i].pathtarget.x+=l*block_spacing;
 										person[i].pathtarget.z+=m*block_spacing;
 
-										if(findDistancefast(person[i].playercoords,person[i].pathtarget)<leastdistance&&findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords)<findDistancefast(person[i].playercoords,person[person[i].killtarget].playercoords)&&j!=1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[l][m])==-1&&blocksimple.LineCheck2(person[i].playercoords,person[i].pathtarget,&blah,move,cityrotation[person[i].whichblockx][person[i].whichblocky])==-1){
-											leastdistance=findDistancefast(person[i].playercoords,person[i].pathtarget);
+										if (sqrlen(person[i].playercoords - person[i].pathtarget) < leastdistance
+										    && sqrlen(person[i].pathtarget - person[person[i].killtarget].playercoords) < sqrlen(person[i].playercoords - person[person[i].killtarget].playercoords)
+										    && j != 1 && blocksimple.LineCheck2(person[i].playercoords, person[i].pathtarget, &blah, move, cityrotation[l][m]) == -1
+										    && blocksimple.LineCheck2(person[i].playercoords, person[i].pathtarget, &blah, move, cityrotation[person[i].whichblockx][person[i].whichblocky]) == -1) {
+											leastdistance = sqrlen(person[i].playercoords - person[i].pathtarget);
 											closesttarget=j;
 											finaltarget=person[i].pathtarget;
 											person[i].whichblockx=l;
@@ -1297,7 +1307,9 @@ void Game::Tick()
 
 						if(person[person[i].killtarget].health<=0)person[i].killtargetvisible=0;
 
-						if(closesttarget!=-1&&findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)>30000)person[i].killtargetvisible=0;
+						if (closesttarget != -1
+						    && sqrlen(person[i].playercoords - person[person[i].killtarget].playercoords) > 30000)
+							person[i].killtargetvisible = 0;
 
 						if(person[i].killtarget==0&&visions==1)person[i].killtargetvisible=0;
 
@@ -1379,10 +1391,15 @@ void Game::Tick()
 										toofar=20000;
 									}
 
-									if(findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)>toofar)
+									if (sqrlen(person[i].playercoords - person[person[i].killtarget].playercoords) > toofar)
 										person[i].targetanimation=joganim;
 
-									if((findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)<=tooclose&&person[person[i].killtarget].skeleton.free==0)||(tooclose>200&&findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)<=200)||(tooclose<=200&&findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)<tooclose)){
+									if ((sqrlen(person[i].playercoords - person[person[i].killtarget].playercoords) <= tooclose
+									     && person[person[i].killtarget].skeleton.free == 0)
+									    || (tooclose > 200
+									        && sqrlen(person[i].playercoords - person[person[i].killtarget].playercoords) <= 200)
+									    || (tooclose <= 200
+									        && sqrlen(person[i].playercoords - person[person[i].killtarget].playercoords) < tooclose)) {
 										if(person[i].targetanimation!=idleanim){
 											person[i].targetanimation=idleanim;
 											person[i].targetframe=0;
@@ -1431,20 +1448,19 @@ void Game::Tick()
 
 									if(person[i].aiming==0)person[i].shotdelay=shotdelayamount/difficulty;
 
-									if(findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)>20||person[i].targetanimation!=idleanim)
-										person[i].targetanimation=zombiejoganim;
-
-									if(findDistancefast(person[i].playercoords, person[person[i].killtarget].playercoords)<=20){
+									if (sqrlen(person[i].playercoords - person[person[i].killtarget].playercoords) <= 20) {
 										murderer=i;
 										person[person[i].killtarget].health=0;
 										person[person[i].killtarget].eaten=i;
-									}
+									} else if (person[i].targetanimation != idleanim)
+										person[i].targetanimation = zombiejoganim;
 									finaltarget=person[person[i].killtarget].playercoords;
 								 }
 							}
 
 						 if(person[i].killtargetvisible||realcheck)person[i].pathtarget=finaltarget;
-						 if(realcheck)person[i].lastdistancevictim=findDistancefast(person[i].pathtarget,person[person[i].killtarget].playercoords);
+						if (realcheck)
+							person[i].lastdistancevictim = sqrlen(person[i].pathtarget - person[person[i].killtarget].playercoords);
 						}
 					}
 
@@ -1503,7 +1519,8 @@ void Game::Tick()
 			person[i].averageloc /= max_joints;
 			person[i].playercoords=person[i].averageloc;
 			if(person[i].longdead<multiplier/2&&person[i].longdead>0)person[i].DrawSkeleton(i);
-			if(findDistancefast(person[i].averageloc,person[i].oldaverageloc)<.2*multiplier)person[i].longdead-=multiplier/2;
+			if (sqrlen(person[i].averageloc - person[i].oldaverageloc) < 0.2 * multiplier)
+				person[i].longdead -= multiplier / 2;
 		}
 
 		if(person[i].skeleton.free==1&&person[i].longdead<=0&&person[i].health>0&&person[i].longdead!=-1){
@@ -1725,25 +1742,15 @@ void Game::Tick()
 						temphitstruct=person[i].BulletCollideWithPlayer(i, start, end);
 
 						if(temphitstruct.collision){
-
-							distance=findDistancefast(start,temphitstruct.hitlocation);
-
+							distance = sqrlen(start - temphitstruct.hitlocation);
 							if(distance<olddistance||whichhit==-1){
-
 								end=temphitstruct.hitlocation;
-
 								olddistance=distance;
-
 								hitstruct=temphitstruct;
-
 								whichhit=i;
-
 							}
-
 						}
-
 					}
-
 				}
 
 				// Blocks
@@ -1956,7 +1963,7 @@ void Game::Tick()
 						}
 
 						for (auto& joint : person[whichhit].skeleton.joints) {
-							auto distance = findDistancefast(joint.position, hitstruct.hitlocation);
+							auto distance = sqrlen(joint.position - hitstruct.hitlocation);
 							if (distance < 200) {
 								totalarea += 200 / distance;
 								joint.velocity += aim * 200 / distance / totalarea * 200;
@@ -1993,13 +2000,15 @@ void Game::Tick()
 						person[whichhit].skeleton.offset=1;
 
 						for (auto& joint : person[whichhit].skeleton.joints) {
-							auto distance = findDistancefast(DoRotation(joint.position, 0, person[whichhit].playerrotation, 0) + person[whichhit].playercoords, hitstruct.hitlocation);
+							auto distance = sqrlen(DoRotation(joint.position, 0, person[whichhit].playerrotation, 0)
+								+ person[whichhit].playercoords
+								- hitstruct.hitlocation);
 							if(distance < 200) {
 								totalarea += 200 / distance;
 								joint.offset += DoRotation(aim * 200 / distance / totalarea * 10,
 									0, -person[whichhit].playerrotation, 0);
 							}
-							if (findLengthfast(joint.offset) > 36)
+							if (sqrlen(joint.offset) > 36)
 								joint.offset = normalize(joint.offset) * 6;
 						}
 					}
@@ -2167,7 +2176,7 @@ void Game::Tick()
 				}
 
 				if (nearest.x
-				    && findDistancefast(nearest, camera.position) < 10
+				    && sqrlen(nearest - camera.position) < 10
 				    && (thirdperson == 2 || j != 0)) {
 					auto nearsound = nearest - camera.position;
 					playSound(gSourceID[nearbulletsound],
@@ -2217,7 +2226,7 @@ void Game::Tick()
 		}
 
 		bool impact = false;
-		if(findLengthfast(sprites.velocity[i])>0){
+		if (sqrlen(sprites.velocity[i]) > 0) {
 			int wherex = sprites.location[i].x / block_spacing + 0.5f;
 			int wherey = sprites.location[i].z / block_spacing + 0.5f;
 			move = {(float) wherex * block_spacing, 0.0f, (float) wherey * block_spacing};
@@ -2234,7 +2243,7 @@ void Game::Tick()
 
 				if (sprites.type[i] == grenadesprite && sprites.size[i] <= 1) {
 					auto soundpos = sprites.location[i] - camera.position;
-					auto v = findLengthfast(sprites.velocity[i]) * 0.2f;
+					auto v = sqrlen(sprites.velocity[i]) * 0.2f;
 					ALfloat gLoc[] {
 						soundpos.x / v / soundscalefactor,
 						soundpos.y / v / soundscalefactor,
@@ -2245,7 +2254,7 @@ void Game::Tick()
 					alSourcePlay(gSourceID[whichsound]);
 				}
 
-				if (findLengthfast(sprites.velocity[i]) <= 10)
+				if (sqrlen(sprites.velocity[i]) <= 10)
 					sprites.velocity[i] = {};
 			}
 
@@ -2264,7 +2273,7 @@ void Game::Tick()
 					}
 
 					auto soundpos = sprites.location[i] - camera.position;
-					auto v = findLengthfast(sprites.velocity[i]) * 0.2f;
+					auto v = sqrlen(sprites.velocity[i]) * 0.2f;
 					ALfloat gLoc[] {
 						soundpos.x / v / soundscalefactor,
 						soundpos.y / v / soundscalefactor,
@@ -2277,11 +2286,12 @@ void Game::Tick()
 
 				}
 
-				if (findLengthfast(sprites.velocity[i]) <= 10)
+				if (sqrlen(sprites.velocity[i]) <= 10)
 					sprites.velocity[i] = {};
 			}
 
-			if(sprites.type[i]==grenadesprite&&findLengthfast(sprites.velocity[i])>20){
+			if (sprites.type[i] == grenadesprite
+			    && sqrlen(sprites.velocity[i]) > 20) {
 				for (int j = 0; j < numpeople; ++j) {
 					if (j == 0 && sprites.brightness[i] > 0.9f || !person[j].existing)
 						continue;
@@ -2291,7 +2301,7 @@ void Game::Tick()
 					impact = true;
 					sprites.location[i] = hitstruct.hitlocation;
 					auto landpos = sprites.location[i] - camera.position;
-					auto v = findLengthfast(sprites.velocity[i]) * 0.2f;
+					auto v = sqrlen(sprites.velocity[i]) * 0.2f;
 					ALfloat gLoc[] {
 						landpos.x / v / soundscalefactor,
 						landpos.y / v / soundscalefactor,
@@ -2332,12 +2342,14 @@ void Game::Tick()
 						person[j].skeleton.offset=1;
 
 						for (auto& joint : person[j].skeleton.joints) {
-							auto distance = findDistancefast(DoRotation(joint.position, 0, person[j].playerrotation, 0) + person[j].playercoords, hitstruct.hitlocation);
+							auto distance = sqrlen(DoRotation(joint.position, 0, person[j].playerrotation, 0)
+								+ person[j].playercoords
+								- hitstruct.hitlocation);
 							if (distance < 200) {
 								totalarea += 200 / distance;
 								joint.offset += DoRotation(sprites.velocity[i] * 0.1 * 200 / distance / totalarea * 10, 0, -person[j].playerrotation, 0);
 							}
-							if (findLengthfast(joint.offset) > 9) {
+							if (sqrlen(joint.offset) > 9) {
 								joint.offset = normalize(joint.offset) * 3;
 							}
 						}
@@ -2391,9 +2403,12 @@ void Game::Tick()
 
 			for(int k=0;k<numpeople;k++){
 				if (!person[k].existing
-				    || person[k].longdead == -1 && person[k].skeleton.free
-				    || (findDistancefast(person[k].playercoords,sprites.location[i]) > 700 || person[k].skeleton.free)
-				       && (findDistancefast(person[k].averageloc,sprites.location[i]) > 700 || !person[k].skeleton.free))
+				    || (person[k].longdead == -1
+				        && person[k].skeleton.free)
+				    || ((sqrlen(person[k].playercoords - sprites.location[i]) > 700
+				         || person[k].skeleton.free)
+				        && (sqrlen(person[k].averageloc - sprites.location[i]) > 700
+				            || !person[k].skeleton.free)))
 					continue;
 				if(person[k].skeleton.free!=1){
 					if(person[k].type==civiliantype)civkills++;
@@ -2402,7 +2417,11 @@ void Game::Tick()
 					person[k].skeleton.free=1;
 					person[k].killtargetvisible=0;
 
-					if((findDistancefast(person[k].playercoords,sprites.location[i])<600&&person[k].skeleton.free<1)||(findDistancefast(person[k].averageloc,sprites.location[i])<600&&person[k].skeleton.free>=1)||person[k].type==playertype){
+					if ((sqrlen(person[k].playercoords - sprites.location[i]) < 600
+					     && person[k].skeleton.free < 1)
+					    || (sqrlen(person[k].averageloc - sprites.location[i]) < 600
+					        && person[k].skeleton.free >= 1)
+					    || person[k].type == playertype) {
 						person[k].health-=100;
 						person[k].bleeding=1;
 					}
@@ -2436,7 +2455,7 @@ void Game::Tick()
 						joint.velocity += relation * 300;
 
 					// Sever stuff
-					if (findLengthfast(joint.velocity) > 1500
+					if (sqrlen(joint.velocity) > 1500
 					    && 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
diff --git a/src/Models.cpp b/src/Models.cpp
index e706ebf..a414008 100644
--- a/src/Models.cpp
+++ b/src/Models.cpp
@@ -52,7 +52,7 @@ void Model::CalculateNormals()
 	boundingsphereradius = 0;
 	for (int i = 0; i < vertexNum; ++i)
 		boundingsphereradius = std::max(boundingsphereradius,
-			findDistancefast(boundingspherecenter, vertex[i]));
+			sqrlen(boundingspherecenter - vertex[i]));
 	boundingsphereradius = sqrt(boundingsphereradius);
 }
 
diff --git a/src/Person.cpp b/src/Person.cpp
index 452a8bd..292269a 100644
--- a/src/Person.cpp
+++ b/src/Person.cpp
@@ -60,7 +60,7 @@ HitStruct 	Person::BulletCollideWithPlayer(int who, XYZ start, XYZ end){
 	float distancemax = 0.0f;
 	for (auto& joint : skeleton.joints)
 		distancemax = std::max(distancemax,
-			findDistancefast(average, joint.position));
+			sqrlen(average - joint.position));
 	distancemax = sqrt(distancemax);
 
 	//Collide with player
@@ -932,7 +932,7 @@ int Person::DrawSkeleton(int who)
 				for (auto& joint : skeleton.joints) {
 					joint.oldposition = joint.position;
 					joint.position += joint.offset;
-					if (findLengthfast(joint.offset) >= multiplier * multiplier * 25) {
+					if (sqrlen(joint.offset) >= multiplier * multiplier * 25) {
 						normal = normalize(joint.offset);
 						skeleton.offset = 1;
 						joint.offset -= normal * multiplier * 5;
diff --git a/src/Quaternions.cpp b/src/Quaternions.cpp
index 9142da0..2de000b 100644
--- a/src/Quaternions.cpp
+++ b/src/Quaternions.cpp
@@ -107,14 +107,6 @@ float findDistance(XYZ point1, XYZ point2){
 	return sqrt((point1.x-point2.x)*(point1.x-point2.x)+(point1.y-point2.y)*(point1.y-point2.y)+(point1.z-point2.z)*(point1.z-point2.z));
 }
 
-float findLengthfast(XYZ point1){
-	return((point1.x)*(point1.x)+(point1.y)*(point1.y)+(point1.z)*(point1.z));
-}
-
-float findDistancefast(XYZ point1, XYZ point2){
-	return((point1.x-point2.x)*(point1.x-point2.x)+(point1.y-point2.y)*(point1.y-point2.y)+(point1.z-point2.z)*(point1.z-point2.z));
-}
-
 XYZ DoRotation(XYZ thePoint, float xang, float yang, float zang){
 	XYZ newpoint;
 	if(xang){
diff --git a/src/Quaternions.h b/src/Quaternions.h
index 16ff2d9..f1fbe6b 100644
--- a/src/Quaternions.h
+++ b/src/Quaternions.h
@@ -42,6 +42,7 @@ constexpr XYZ& operator/=(XYZ& u, float k) { return u = u / k; }
 extern "C" {
 #endif // __cplusplus
 	float dotProduct(struct XYZ, struct XYZ);
+	float sqrlen(struct XYZ);
 	struct XYZ crossProduct(struct XYZ, struct XYZ);
 	struct XYZ normalize(struct XYZ);
 	void reflect(struct XYZ*, struct XYZ);
@@ -53,8 +54,6 @@ extern "C" {
 	struct XYZ DoRotation(struct XYZ thePoint,
 		float xang, float yang, float zang);
 	float findDistance(struct XYZ point1, struct XYZ point2);
-	float findLengthfast(struct XYZ point1);
-	float findDistancefast(struct XYZ point1, struct XYZ point2);
 
 	void getFrustum(float (*)[4]);
 	int cubeInFrustum(float (*)[4], float, float, float, float);
diff --git a/src/Skeleton.cpp b/src/Skeleton.cpp
index 6925fb6..23892b8 100644
--- a/src/Skeleton.cpp
+++ b/src/Skeleton.cpp
@@ -159,8 +159,8 @@ void Skeleton::DoConstraints(Model *collide, XYZ *move, float rotation)
 						AL_SOURCE_STATE, &playing);
 
 				if (playing != AL_PLAYING
-				    && (findLengthfast(joints[i].velocity) > 2
-				        || findLengthfast(avgvelocity) > 2)) {
+				    && (sqrlen(joints[i].velocity) > 2
+				        || sqrlen(avgvelocity) > 2)) {
 					auto soundpos = pos - camera.position;
 					playSound(gSourceID[landsound],
 						soundpos.x, soundpos.y, soundpos.z);
diff --git a/src/Sprites.cpp b/src/Sprites.cpp
index e96577e..30737df 100644
--- a/src/Sprites.cpp
+++ b/src/Sprites.cpp
@@ -96,7 +96,7 @@ void Sprites::DoStuff()
 			brightness[i]=0;
 		}
 		if(type[i]==grenadesprite||type[i]==spoonsprite||type[i]==pinsprite){
-			if(findLengthfast(velocity[i])>0){
+			if (sqrlen(velocity[i]) > 0) {
 				velocity[i].y+=gravity*multiplier;
 				rotation[i]+=multiplier*2;
 			}
diff --git a/src/misc.zig b/src/misc.zig
index 0b1ad54..f2db3d1 100644
--- a/src/misc.zig
+++ b/src/misc.zig
@@ -387,6 +387,11 @@ fn dot(u: anytype, v: @TypeOf(u)) Child(@TypeOf(u)) {
     return @reduce(.Add, u * v);
 }
 
+export fn sqrlen(v: XYZ) f32 {
+    const u = @bitCast(@Vector(3, f32), v);
+    return dot(u, u);
+}
+
 fn norm(v: anytype) Child(@TypeOf(v)) {
     return @sqrt(dot(v, v));
 }