diff options
-rw-r--r-- | src/GameTick.cpp | 276 |
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) { |