diff options
Diffstat (limited to 'src/GameTick.cpp')
| -rw-r--r-- | src/GameTick.cpp | 296 |
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++){ |
