summary refs log tree commit diff
path: root/src/GameTick.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/GameTick.cpp')
-rw-r--r--src/GameTick.cpp276
1 files changed, 93 insertions, 183 deletions
diff --git a/src/GameTick.cpp b/src/GameTick.cpp
index fb98859..071993b 100644
--- a/src/GameTick.cpp
+++ b/src/GameTick.cpp
@@ -5,7 +5,7 @@
 // Copyright (C) 2003  Steven Fuller
 // Copyright (C) 2003  Zachary Jack Slater
 // Copyright (C) 2003  Toby Haynes
-// Copyright (C) 2021  Nguyễn Gia Phong
+// Copyright (C) 2021-2022  Nguyễn Gia Phong
 //
 // This file is part of Black Shades.
 //
@@ -465,6 +465,88 @@ void nextLevel(Game* game)
 	}
 }
 
+void checkPersonCollisions(Game* game, int k)
+{
+	auto& person = game->person[k];
+	person.oldplayercoords = person.playercoords;
+	person.DoStuff(k);
+	if (person.skeleton.free)
+		return;
+
+	person.onground = false;
+	auto overpoint = person.playercoords;
+	overpoint.y += 3000;
+	auto underpoint = person.playercoords;
+	underpoint.y -= 3000;
+
+	const int x = (person.playercoords.x + block_spacing / 2) / block_spacing;
+	const int z = (person.playercoords.z + block_spacing / 2) / block_spacing;
+	const int endx = std::min(num_blocks - 1, x + 1);
+	const int endz = std::min(num_blocks - 1, z + 1);
+	/* TODO: huh?
+	 * if(k!=0) {
+	 * 	beginx == person.whichblockx;
+	 * 	beginz == person.whichblocky;
+	 * 	endx == person.whichblockx;
+	 * 	endz == person.whichblocky;
+	 * }
+	 */
+
+	for (auto i = std::max(0, x); i <= endx; ++i)
+		for (auto j = std::max(0, z); j <= endz; ++j) {
+			// Ground collision
+			const auto city_rot = game->cityrotation[i][j] * 90;
+			const XYZ move = {(float) i * block_spacing,
+				0.0f, (float) j * block_spacing};
+			XYZ collpoint;
+			if (game->sidewalkcollide.LineCheck2(overpoint,
+					underpoint, &collpoint, move, city_rot) == -1)
+				continue;
+
+			if (person.playercoords.y <= collpoint.y
+			    && person.velocity.y <= 0) {
+				person.playercoords.y = collpoint.y;
+				person.onground = true;
+				Splat(game, k);
+			}
+
+			if (k != 0)
+				continue;
+			game->onblockx = i;
+			game->onblocky = j;
+
+			// Wall collision
+			float depth;
+			const auto city_type = game->citytype[i][j];
+			for (auto& bound : game->boundingpoints) {
+				const auto whichtri = game->blockwalls[city_type].LineCheck3(person.playercoords + bound,
+					person.playercoords + bound,
+					&collpoint, move, city_rot, &depth);
+				if (whichtri == -1)
+					continue;
+			}
+			for (auto& bound : game->boundingpoints) {
+				auto pointnum = k + 1;
+				if (pointnum > 3)
+					pointnum = 0;
+				const auto whichtri = game->blockwalls[city_type].LineCheck3(person.playercoords + bound,
+					person.playercoords + game->boundingpoints[pointnum],
+					&collpoint, move, city_rot, &depth);
+				if (whichtri == -1)
+					continue;
+				person.playercoords += DoRotation(game->blockwalls[city_type].normals[whichtri], 0, city_rot, 0);
+			}
+		}
+
+	if (person.playercoords.y <= 0) {
+		person.onground = true;
+		person.playercoords.y = 0;
+		Splat(game, k);
+		if (k == 0)
+			game->onblockx = game->onblocky = -1;
+	}
+}
+
 void Game::Tick()
 {
 	if (person[1].health <= 0 || person[0].health <= 0 || killedinnocent)
@@ -498,169 +580,14 @@ void Game::Tick()
 	flatfacing.y = 0;
 	Normalise(&flatfacing);
 
-	//Check collision with buildings
+	// Check collision with buildings
 	int beginx,endx;
 	int beginz,endz;
-	XYZ collpoint;
 	XYZ move;
 	int whichtri;
 	XYZ underpoint;
 	XYZ overpoint;
-	int pointnum;
-	float depth;
-	XYZ normalrotated;
-	bool inblock;
-
-	//Check people collisions
-	for(int k=0;k<numpeople;k++){
-		// SBF - backing up the old coordinates makes
-		// the most sense here.
-		person[k].oldplayercoords=person[k].playercoords;
-
-		person[k].DoStuff(k);
-
-		if(person[k].skeleton.free<1){
-
-		if(1==1){
-
-		person[k].onground=0;
-
-		overpoint=person[k].playercoords;
-
-		overpoint.y+=3000;
-
-		underpoint=person[k].playercoords;
-
-		underpoint.y-=3000;
-
-		beginx=(person[k].playercoords.x+block_spacing/2)/block_spacing;
-
-		if(beginx<0)beginx=0;
-
-		beginz=(person[k].playercoords.z+block_spacing/2)/block_spacing;
-
-		if(beginz<0)beginz=0;
-
-		endx=(person[k].playercoords.x+block_spacing/2)/block_spacing+1;
-
-		if(endx>num_blocks-1)endx=num_blocks-1;
-
-		endz=(person[k].playercoords.z+block_spacing/2)/block_spacing+1;
-
-		if(endz>num_blocks-1)endz=num_blocks-1;
-
-		/* TODO: huh?
-		 * if(k!=0) {
-		 * 	beginx == person[k].whichblockx;
-		 * 	beginz == person[k].whichblocky;
-		 * 	endx == person[k].whichblockx;
-		 * 	endz == person[k].whichblocky;
-		 * }
-		 */
-
-		if(beginx<=endx&&beginz<=endz)
-
-		for(int i=beginx;i<=endx;i++)
-
-			for(int j=beginz;j<=endz;j++){
-
-				inblock=0;
-
-				//Ground collision
-				move = {(float) i * block_spacing, 0.0f, (float) j * block_spacing};
-
-				whichtri=sidewalkcollide.LineCheck2(overpoint,underpoint,&collpoint,move,cityrotation[i][j]*90);
-
-				if(whichtri!=-1&&person[k].playercoords.y<=collpoint.y&&person[k].velocity.y<=0){
-					person[k].playercoords.y=collpoint.y;
-					person[k].onground=1;
-					Splat(this, k);
-				}
-
-				if(whichtri!=-1){
-
-					inblock=1;
-
-					if(k==0){onblockx=i;onblocky=j;}
-
-				}
-
-				//Wall collision
-
-				if(k==0){
-
-					if(inblock){
-
-						for(int l=0;l<8;l++){
-							move = {(float) i * block_spacing, 0.0f, (float) j * block_spacing};
-							whichtri=blockwalls[citytype[i][j]].LineCheck3(person[k].oldplayercoords+boundingpoints[l],person[k].playercoords+boundingpoints[l],&collpoint,move,cityrotation[i][j]*90,&depth);
-
-							if(whichtri!=-1){
-
-								normalrotated=DoRotation(blockwalls[citytype[i][j]].normals[whichtri],0,cityrotation[i][j]*90,0);
-
-								person[k].playercoords+=normalrotated*(-(dotproduct(normalrotated,person[k].playercoords-person[k].oldplayercoords))-depth);
-
-							}
-
-						}
-
-						for(int l=0;l<8;l++){
-
-							pointnum=k+1;
-
-							if(pointnum>3)pointnum=0;
-							move = {(float) i * block_spacing, 0.0f, (float) j * block_spacing};
-							whichtri=blockwalls[citytype[i][j]].LineCheck3(person[k].playercoords+boundingpoints[l],person[k].playercoords+boundingpoints[pointnum],&collpoint,move,cityrotation[i][j]*90,&depth);
-
-							if(whichtri!=-1){
-
-								normalrotated=DoRotation(blockwalls[citytype[i][j]].normals[whichtri],0,cityrotation[i][j]*90,0);
-
-								person[k].playercoords+=normalrotated;
-
-							}
-
-						}
-
-					}
-
-					//Roof collision
-
-					if(inblock&&person[k].playercoords.y>30){
-
-						if(!person[k].onground){
-							move = {(float) i * block_spacing, 0.0f, (float) j * block_spacing};
-							whichtri=blockroofs[citytype[i][j]].LineCheck2(overpoint,underpoint,&collpoint,move,cityrotation[i][j]*90);
-
-							if(whichtri!=-1&&person[k].playercoords.y<=collpoint.y&&person[k].velocity.y<=0){
-								person[k].playercoords.y=collpoint.y;
-								person[k].onground=1;
-								Splat(this, k);
-							}
-
-							if(whichtri!=-1)inblock=1;
-						}
-					}
-				}
-			}
-
-		if (person[k].playercoords.y <= 0) {
-			person[k].onground = 1;
-			person[k].playercoords.y = 0;
-			Splat(this, k);
-			if (k == 0)
-				onblockx = onblocky = -1;
-		}
-
-		// SBF - this is definately in the wrong spot!
-		//person[k].oldplayercoords=person[k].playercoords;
-
-		}
-
-		}
-
-	}
+	for (auto k = numpeople; k--; checkPersonCollisions(this, k));
 
 	// Camera
 	camera.oldposition = camera.position;
@@ -2516,46 +2443,29 @@ void Game::Tick()
 	}
 
 	//Grenade collision
-
 	int wherex, wherey, whichsound;
-
 	bool impact;
-
 	for(int i=0;i<sprites.howmanysprites;i++){
-
 		if(sprites.type[i]==grenadesprite||sprites.type[i]==spoonsprite||sprites.type[i]==pinsprite){
-
 			impact=0;
-
 			if(sprites.type[i]!=grenadesprite){
-
 				sprites.brightness[i]-=multiplier*.2;
-
 			}
 
 			if(findLengthfast(sprites.velocity[i])>0){
-
 				wherex=(sprites.location[i].x+block_spacing/2)/block_spacing;
-
 				wherey=(sprites.location[i].z+block_spacing/2)/block_spacing;
-
 				move = {(float) wherex * block_spacing, 0.0f, (float) wherey * block_spacing};
-
 				whichtri=blocks[citytype[wherex][wherey]].LineCheck2(sprites.oldlocation[i],sprites.location[i],&wallhit,move,cityrotation[wherex][wherey]*90);
 
-				if(whichtri!=-1){
-
-					impact=1;
-
-					normalrotated=DoRotation(blocks[citytype[wherex][wherey]].normals[whichtri],0,cityrotation[wherex][wherey]*90,0);
-
-					if(sprites.size[i]>1)decals.MakeDecal(crater, wallhit,9,normalrotated, whichtri, &blocks[citytype[wherex][wherey]], move, cityrotation[wherex][wherey]*90);
-
-					sprites.location[i]=wallhit+normalrotated*.02;
-
-					ReflectVector(&sprites.velocity[i],&normalrotated);
-
-					sprites.velocity[i]*=.3;
+				if (whichtri != -1) {
+					impact = 1;
+					auto normalrotated = DoRotation(blocks[citytype[wherex][wherey]].normals[whichtri], 0, cityrotation[wherex][wherey] * 90, 0);
+					if (sprites.size[i] > 1)
+						decals.MakeDecal(crater, wallhit, 9, normalrotated, whichtri, &blocks[citytype[wherex][wherey]], move, cityrotation[wherex][wherey] * 90);
+					sprites.location[i] = wallhit + normalrotated * 0.02f;
+					ReflectVector(&sprites.velocity[i], &normalrotated);
+					sprites.velocity[i] *= 0.3f;
 
 					if (sprites.type[i] == grenadesprite
 					    && sprites.size[i] <= 1) {