about summary refs log tree commit diff
path: root/src/GameTick.cpp
diff options
context:
space:
mode:
authorNguyễn Gia Phong <cnx@loang.net>2023-11-18 21:40:15 +0900
committerNguyễn Gia Phong <cnx@loang.net>2023-11-18 21:40:15 +0900
commitae0810b2d4cdd31cd05f5746c6411da9d458eead (patch)
treea827fbe10c12a4a4665b98144f32e767ba5a3553 /src/GameTick.cpp
parent371906f5fb958691a8bfce85c28eb4dfaf63559c (diff)
downloadblackshades-ae0810b2d4cdd31cd05f5746c6411da9d458eead.tar.gz
Convert model geometry to Zig
Diffstat (limited to 'src/GameTick.cpp')
-rw-r--r--src/GameTick.cpp296
1 files changed, 135 insertions, 161 deletions
diff --git a/src/GameTick.cpp b/src/GameTick.cpp
index b628637..2bfdda6 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-2022  Nguyễn Gia Phong
+// Copyright (C) 2021-2023  Nguyễn Gia Phong
 //
 // This file is part of Black Shades.
 //
@@ -497,8 +497,10 @@ void checkPersonCollisions(Game* game, int k)
 			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)
+			if (segCrossModelTrans(overpoint, underpoint,
+				&game->sidewalkcollide, move, city_rot,
+				&collpoint)
+			    == -1)
 				continue;
 
 			if (person.playercoords.y <= collpoint.y
@@ -516,19 +518,13 @@ void checkPersonCollisions(Game* game, int k)
 			// Wall collision
 			const auto city_type = game->citytype[i][j];
 			for (auto& bound : game->boundingpoints) {
-				const auto whichtri = game->blockwalls[city_type].LineCheck2(person.playercoords + bound,
-					person.playercoords + bound,
-					&collpoint, move, city_rot);
-				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].LineCheck2(person.playercoords + bound,
+				const auto whichtri = segCrossModelTrans(person.playercoords + bound,
 					person.playercoords + game->boundingpoints[pointnum],
-					&collpoint, move, city_rot);
+					game->blockwalls + city_type,
+					move, city_rot, &collpoint);
 				if (whichtri == -1)
 					continue;
 				person.playercoords += rotate(game->blockwalls[city_type].normals[whichtri], 0, city_rot, 0);
@@ -752,20 +748,21 @@ void bleed(Game* game, size_t i)
 		overpoint.y += 3000;
 		auto underpoint = person.skeleton.joints[abdomen].position;
 		underpoint.y -= 3000;
-		XYZ temp;
+		XYZ loc;
 		XYZ move {(float) x * block_spacing, 0.0f, (float) y * block_spacing, };
-		auto whichtri = game->sidewalkcollide.LineCheck2(overpoint,
-			underpoint, &temp, move, rot);
+		auto whichtri = segCrossModelTrans(overpoint, underpoint,
+			&game->sidewalkcollide, move, rot, &loc);
 
 		XYZ normish {0.0f, 1.0f, 0.0f};
 		if (whichtri >= 0) {
-			addDecal(&decals, BLOOD_POOL, temp, 12, normish,
+			addDecal(&decals, BLOOD_POOL, loc, 12, normish,
 				whichtri, &game->sidewalkcollide, move, rot);
 		} else {
-			temp = person.skeleton.joints[abdomen].position;
-			temp.y = -0.5f;
-			addDecal(&decals, BLOOD_POOL, temp, 12, normish,
-				0, &game->sidewalkcollide, {}, 0);
+			loc = person.skeleton.joints[abdomen].position;
+			loc.y = -0.5f;
+			move = {0.0f};
+			addDecal(&decals, BLOOD_POOL, loc, 12, normish,
+				0, &game->sidewalkcollide, move, 0);
 		}
 		person.firstlongdead = true;
 		return;
@@ -953,14 +950,15 @@ void renderLaser(Game* game)
 			};
 			XYZ tmp {};
 			auto& block = game->blocks[game->citytype[i][j]];
-			auto whichtri = block.LineCheck2(start, end,
-				&tmp, move, game->cityrotation[i][j]*90);
-			if (whichtri != -1)
+			if (segCrossModelTrans(start, end, &block,
+				move, game->cityrotation[i][j]*90, &tmp)
+			    > -1)
 				end = tmp;
 		}
-	XYZ tmp {camera.position.x, 0.0f, camera.position.z};
-	auto whichtri = game->Bigstreet.LineCheck2(start, end, &tmp, tmp, 0);
-	if (whichtri != -1)
+	XYZ tmp;
+	if (segCrossModelTrans(start, end, &game->Bigstreet,
+		{camera.position.x, 0.0f, camera.position.z}, 0, &tmp)
+	    > -1)
 		end = tmp;
 
 	// People
@@ -1151,10 +1149,17 @@ void Game::Tick()
 										person[i].pathtarget.x+=l*block_spacing;
 										person[i].pathtarget.z+=m*block_spacing;
 
-										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) {
+										if (j != 1
+										    && (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))
+										    && (segCrossModelTrans(person[i].playercoords, person[i].pathtarget, &blocksimple,
+											move, cityrotation[person[i].whichblockx][person[i].whichblocky], &blah)
+										        == -1)
+										    && (segCrossModelTrans(person[i].playercoords, person[i].pathtarget, &blocksimple,
+											move, cityrotation[l][m], &blah)
+										        == -1)) {
 											person[i].lastdistancevictim = sqrlen(person[i].pathtarget - person[person[i].killtarget].playercoords);
 											leastdistance = sqrlen(person[i].playercoords - person[i].pathtarget);
 											closesttarget=j;
@@ -1226,28 +1231,14 @@ void Game::Tick()
 							person[i].pathtarget.x+=person[i].whichblockx*block_spacing;
 							person[i].pathtarget.z+=person[i].whichblocky*block_spacing;
 
-							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;
-							}
-						}
-
-						leastdistance=2000000;
-						for(int j=0;j<path.vertexNum;j++){
-							person[i].pathtarget.x=path.vertex[j].x;
-							person[i].pathtarget.z=path.vertex[j].z;
-							person[i].pathtarget.y=path.vertex[j].y;
-							person[i].pathtarget*=person[i].pathsize;
-							person[i].pathtarget.x+=person[i].whichblockx*block_spacing;
-							person[i].pathtarget.z+=person[i].whichblocky*block_spacing;
-
-							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) {
+							if (j != 1
+							    && (sqrlen(person[i].playercoords - person[i].pathtarget)
+							        < leastdistance)
+							    && (sqrlen(person[i].pathtarget - person[person[i].killtarget].playercoords)
+							        < person[i].lastdistancevictim)
+							    && (segCrossModelTrans(person[i].playercoords, person[i].pathtarget, &blocksimple,
+								move, cityrotation[person[i].whichblockx][person[i].whichblocky], &blah)
+							        == -1)) {
 								leastdistance = sqrlen(person[i].playercoords - person[i].pathtarget);
 								person[i].lastdistancevictim = sqrlen(person[i].pathtarget - person[person[i].killtarget].playercoords);
 								closesttarget=j;
@@ -1279,10 +1270,17 @@ void Game::Tick()
 										person[i].pathtarget.x+=l*block_spacing;
 										person[i].pathtarget.z+=m*block_spacing;
 
-										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) {
+										if (j != 1
+										    && (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))
+										    && (segCrossModelTrans(person[i].playercoords, person[i].pathtarget, &blocksimple,
+											move, cityrotation[person[i].whichblockx][person[i].whichblocky], &blah)
+										        == -1)
+										    && (segCrossModelTrans(person[i].playercoords, person[i].pathtarget, &blocksimple,
+											move, cityrotation[l][m], &blah)
+										        == -1)) {
 											leastdistance = sqrlen(person[i].playercoords - person[i].pathtarget);
 											closesttarget=j;
 											finaltarget=person[i].pathtarget;
@@ -1315,29 +1313,27 @@ void Game::Tick()
 							person[i].killtargetvisible = 0;
 
 						if(person[i].killtargetvisible){
-							beginx=person[i].whichblockx-2;
-							if(beginx<0)beginx=0;
-							beginz=person[i].whichblocky-2;
-							if(beginz<0)beginz=0;
-							endx=person[i].whichblockx+2;
-							if(endx>num_blocks-1)endx=num_blocks-1;
-							endz=person[i].whichblocky+2;
-							if(endz>num_blocks-1)endz=num_blocks-1;
-
-							for(int l=beginx;l<=endx;l++){
-								for(int m=beginx;m<=endx;m++){
-									move.x=l*block_spacing;
-									move.z=m*block_spacing;
-									move.y=-3;
-									if(person[i].killtargetvisible){
-										if(blocksimple.LineCheck2(person[i].playercoords,person[person[i].killtarget].playercoords,&blah,move,cityrotation[l][m])!=-1)
-										{
-											person[i].killtargetvisible=0;
-										}
-									}
-								}
-							 }
-							}
+							beginx = std::max(0,
+								person[i].whichblockx - 2);
+							beginz = std::max(0,
+								person[i].whichblocky - 2);
+							endx = std::min(num_blocks - 1,
+								person[i].whichblockx + 2);
+							endz = std::min(num_blocks - 1,
+								person[i].whichblocky + 2);
+
+							for (auto l = beginx; l <= endx; ++l)
+								for (auto m = beginx; m <= endx; ++m)
+									if (person[i].killtargetvisible
+									    && (segCrossModelTrans(person[i].playercoords,
+										person[person[i].killtarget].playercoords,
+										&blocksimple,
+										{(float) l * block_spacing,
+										 -3.0f,
+										 (float) m * block_spacing},
+										cityrotation[l][m], &blah)
+									        > -1))
+										person[i].killtargetvisible = 0;
 
 							if(person[i].type==eviltype){
 								 if(!person[i].killtargetvisible&&person[i].targetanimation==idleanim){
@@ -1458,6 +1454,7 @@ void Game::Tick()
 									finaltarget=person[person[i].killtarget].playercoords;
 								 }
 							}
+						}
 
 						 if(person[i].killtargetvisible||realcheck)person[i].pathtarget=finaltarget;
 						if (realcheck)
@@ -1783,34 +1780,28 @@ void Game::Tick()
 				for(int i=beginx;i<=endx;i++)
 					for(int j=beginz;j<=endz;j++){
 						move = {(float) i * block_spacing, 0.0f, (float) j * block_spacing};
-						whichtri=blocks[citytype[i][j]].LineCheck2(start,end,&wallhit,move,cityrotation[i][j]*90);
-
-						if(whichtri!=-1){
-
-							whichhit=-1;
-
-							end=wallhit;
-
-							finalwallhit=wallhit;
-
-							hitnorm=rotate(blocks[citytype[i][j]].normals[whichtri],0,cityrotation[i][j]*90,0);
-
-							hitmove=move;
-
-							hitrotation=cityrotation[i][j]*90;
-
-							hitpoly=whichtri;
-
-							model=&blocks[citytype[i][j]];
-
-							if(j==0&&blocks[citytype[i][j]].normals[whichtri].y>.9)bulletstrength=2;
+						whichtri = segCrossModelTrans(start, end,
+							blocks + citytype[i][j],
+							move, cityrotation[i][j] * 90,
+							&wallhit);
+						if (whichtri > -1) {
+							whichhit = -1;
+							end = finalwallhit = wallhit;
+							hitnorm = rotate(blocks[citytype[i][j]].normals[whichtri],
+								0, cityrotation[i][j]*90, 0);
+							hitmove = move;
+							hitrotation = cityrotation[i][j]*90;
+							hitpoly = whichtri;
+							model = &blocks[citytype[i][j]];
+							if (j == 0
+							    && blocks[citytype[i][j]].normals[whichtri].y > 0.9)
+								bulletstrength = 2;
 						}
 					}
-				wallhit = {camera.position.x, 0.0f, camera.position.z};
-
-				whichtri=Bigstreet.LineCheck2(start,end,&wallhit,wallhit,0);
-
-				if(whichtri!=-1){
+				whichtri = segCrossModelTrans(start, end, &Bigstreet,
+					{camera.position.x, 0.0f, camera.position.z}, 0,
+					&wallhit);
+				if (whichtri > -1) {
 					end.y-=.5;
 					end=wallhit;
 					finalwallhit=wallhit;
@@ -2095,54 +2086,27 @@ void Game::Tick()
 				}
 
 				// with wall
-				if(oldend==finalwallhit){
-
-					addDecal(&decals, BULLET_HOLE, finalwallhit,.7,hitnorm, hitpoly, model, hitmove, hitrotation);
-
-					XYZ velocity;
-
-					velocity=aim*-4;
-
-					velocity=hitnorm*3;
-
-					if(person[j].whichgun==sniperrifle){
-
+				if (oldend == finalwallhit) {
+					addDecal(&decals, BULLET_HOLE, finalwallhit, 0.7f,
+						hitnorm, hitpoly, model, hitmove, hitrotation);
+					// FIXME: WTF?
+					XYZ velocity = aim * -4.0f;
+					velocity = hitnorm * 3;
+					switch (person[j].whichgun) {
+					case sniperrifle:
 						sprites.MakeSprite(smokesprite, .4, 1, 1, 1, finalwallhit, velocity, 10);
-
 						sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, finalwallhit, velocity, 2);
-
-					}
-
-					if(person[j].whichgun==shotgun){
-
+						break;
+					case shotgun:
 						sprites.MakeSprite(smokesprite, .4, 1, 1, 1, finalwallhit, velocity, 5);
-
 						sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, finalwallhit, velocity, .8);
-
-					}
-
-					if(person[j].whichgun==assaultrifle){
-
-						sprites.MakeSprite(smokesprite, .4, 1, 1, 1, finalwallhit, velocity, 6);
-
-						sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, finalwallhit, velocity, 1);
-
-					}
-
-					if(person[j].whichgun==handgun1){
-
-						sprites.MakeSprite(smokesprite, .4, 1, 1, 1, finalwallhit, velocity, 6);
-
-						sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, finalwallhit, velocity, 1);
-
-					}
-
-					if(person[j].whichgun==handgun2){
-
+						break;
+					case assaultrifle:
+					case handgun1:
+					case handgun2:
 						sprites.MakeSprite(smokesprite, .4, 1, 1, 1, finalwallhit, velocity, 6);
-
 						sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, finalwallhit, velocity, 1);
-
+						break;
 					}
 
 					auto soundpos = finalwallhit - camera.position;
@@ -2237,13 +2201,20 @@ void Game::Tick()
 			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};
-			whichtri=blocks[citytype[wherex][wherey]].LineCheck2(sprites.oldlocation[i],sprites.location[i],&wallhit,move,cityrotation[wherex][wherey]*90);
+			whichtri = segCrossModelTrans(sprites.oldlocation[i],
+				sprites.location[i],
+				blocks + citytype[wherex][wherey],
+				move, cityrotation[wherex][wherey] * 90,
+				&wallhit);
 
 			if (whichtri != -1) {
 				impact = true;
 				auto normalrotated = rotate(blocks[citytype[wherex][wherey]].normals[whichtri], 0, cityrotation[wherex][wherey] * 90, 0);
 				if (sprites.size[i] > 1)
-					addDecal(&decals, CRATER, wallhit, 9, normalrotated, whichtri, &blocks[citytype[wherex][wherey]], move, cityrotation[wherex][wherey] * 90);
+					addDecal(&decals, CRATER, wallhit, 9.0f,
+						normalrotated, whichtri,
+						&blocks[citytype[wherex][wherey]],
+						move, cityrotation[wherex][wherey] * 90);
 				sprites.location[i] = wallhit + normalrotated * 0.02f;
 				reflect(&sprites.velocity[i], normalrotated);
 				sprites.velocity[i] *= 0.3f;
@@ -2276,7 +2247,8 @@ void Game::Tick()
 						move = {};
 						sprites.location[i].y=-.5;
 						XYZ normish = {0.0f, 1.0f, 0.0f};
-						addDecal(&decals, CRATER, sprites.location[i],9,normish, 0, &blocks[citytype[wherex][wherey]], move, 0);
+						addDecal(&decals, CRATER, sprites.location[i], 9.0f,
+							normish, 0, blocks + citytype[wherex][wherey], move, 0);
 					}
 
 					auto soundpos = sprites.location[i] - camera.position;
@@ -2395,18 +2367,20 @@ void Game::Tick()
 			move = {(float) wherex * block_spacing, 0.0f, (float) wherey * block_spacing};
 
 			XYZ temp;
-			whichtri=sidewalkcollide.LineCheck2(overpoint,underpoint,&temp,move,cityrotation[wherex][wherey]*90);
-
+			whichtri = segCrossModelTrans(overpoint, underpoint,
+				&sidewalkcollide,
+				move, cityrotation[wherex][wherey] * 90, &temp);
 			XYZ normish = {0.0f, 1.0f, 0.0f};
-			if(whichtri>=0){
-				addDecal(&decals, CRATER, sprites.location[i],9,normish, 0, &sidewalkcollide, move, cityrotation[wherex][wherey]*90);
-			}
-
-			if(whichtri==-1){
-				temp=sprites.location[i];
-				temp.y=-.5;
-				move = {};
-				addDecal(&decals, CRATER, sprites.location[i],9,normish, 0, &sidewalkcollide, move, 0);
+			if (whichtri > -1) {
+				addDecal(&decals, CRATER, sprites.location[i], 9.0f,
+					normish, 0, &sidewalkcollide, move,
+					cityrotation[wherex][wherey]*90);
+			} else {
+				temp = sprites.location[i];
+				temp.y = -0.5f;
+				move = {0.0f};
+				addDecal(&decals, CRATER, sprites.location[i], 9.0f,
+					normish, 0, &sidewalkcollide, move, 0);
 			}
 
 			for(int k=0;k<numpeople;k++){