diff options
| author | Nguyễn Gia Phong <cnx@loang.net> | 2023-11-19 04:11:46 +0900 |
|---|---|---|
| committer | Nguyễn Gia Phong <cnx@loang.net> | 2023-11-19 04:11:46 +0900 |
| commit | db730f01951231196cac36630d043c7a3676d446 (patch) | |
| tree | f1f8cd2c2e2d8d24235a64fd5d9aa577ca73f4bc /src/GameTick.cpp | |
| parent | ae0810b2d4cdd31cd05f5746c6411da9d458eead (diff) | |
| download | blackshades-db730f01951231196cac36630d043c7a3676d446.tar.gz | |
Finish porting model handling to Zig
Diffstat (limited to 'src/GameTick.cpp')
| -rw-r--r-- | src/GameTick.cpp | 259 |
1 files changed, 84 insertions, 175 deletions
diff --git a/src/GameTick.cpp b/src/GameTick.cpp index 2bfdda6..75bcc9d 100644 --- a/src/GameTick.cpp +++ b/src/GameTick.cpp @@ -527,7 +527,7 @@ void checkPersonCollisions(Game* game, int k) move, city_rot, &collpoint); if (whichtri == -1) continue; - person.playercoords += rotate(game->blockwalls[city_type].normals[whichtri], 0, city_rot, 0); + person.playercoords += rotate(game->blockwalls[city_type].faces[whichtri][0].normal, 0, city_rot, 0); } } @@ -608,15 +608,11 @@ void spawnNpc(Game* game) default: break; } - npc.pathnum = -1; - while (npc.pathnum < 0 - || npc.pathnum == 1 - || npc.pathnum >= game->path.vertexNum) - npc.pathnum = randUint(game->path.vertexNum); npc.oldoldoldpathnum = npc.oldoldpathnum = npc.oldpathnum = -1; + npc.pathnum = randUint(8); - npc.pathtarget.x = game->path.vertex[npc.pathnum].x; - npc.pathtarget.z = game->path.vertex[npc.pathnum].z; + npc.pathtarget.x = DIRECTIONS[npc.pathnum].x; + npc.pathtarget.z = DIRECTIONS[npc.pathnum].z; npc.pathtarget *= npc.pathsize; npc.pathtarget.x += npc.whichblockx * block_spacing; npc.pathtarget.z += npc.whichblocky * block_spacing; @@ -1078,16 +1074,14 @@ void Game::Tick() && !person[i].running) { person[i].killtargetvisible = 0; 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; + for (unsigned char j = 0; j < 8; j++) { + person[i].pathtarget = DIRECTIONS[j]; 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 - && j != 1 && j != person[i].oldpathnum + && j != person[i].oldpathnum && j != person[i].oldoldpathnum && j != person[i].oldoldoldpathnum){ leastdistance = sqrlen(person[i].playercoords - person[i].pathtarget); @@ -1095,13 +1089,12 @@ void Game::Tick() } } - if (closesttarget >= 0 && closesttarget < path.vertexNum) { + if (closesttarget >= 0 && closesttarget < 8) { person[i].oldoldoldpathnum = person[i].oldoldpathnum; person[i].oldoldpathnum = person[i].oldpathnum; person[i].oldpathnum = person[i].pathnum; person[i].pathnum = closesttarget; - person[i].pathtarget.x = path.vertex[person[i].pathnum].x; - person[i].pathtarget.z = path.vertex[person[i].pathnum].z; + person[i].pathtarget = DIRECTIONS[closesttarget]; person[i].pathtarget *= person[i].pathsize; person[i].pathtarget.x += person[i].whichblockx*block_spacing; person[i].pathtarget.z += person[i].whichblocky*block_spacing; @@ -1141,17 +1134,14 @@ void Game::Tick() for (int l = beginx; l <= endx; l++) { for (int m = beginx; m <= endx; m++) { - for (int j = 0; j < path.vertexNum; j++){ - person[i].pathtarget.x = path.vertex[j].x; - person[i].pathtarget.y = path.vertex[j].y; - person[i].pathtarget.z = path.vertex[j].z; + for (unsigned char j = 0; j < 8; ++j) { + person[i].pathtarget = DIRECTIONS[j]; person[i].pathtarget*=person[i].pathsize; person[i].pathtarget.x+=l*block_spacing; person[i].pathtarget.z+=m*block_spacing; - if (j != 1 - && (sqrlen(person[i].playercoords - person[i].pathtarget) - < leastdistance) + 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)) && (segCrossModelTrans(person[i].playercoords, person[i].pathtarget, &blocksimple, @@ -1222,18 +1212,15 @@ void Game::Tick() person[i].lastdistancevictim=2000000; closesttarget=-1; - //Check best path - 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; + // Check best path + for (unsigned char j = 0; j < 8; ++j) { + person[i].pathtarget = DIRECTIONS[j]; 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 (j != 1 - && (sqrlen(person[i].playercoords - person[i].pathtarget) - < leastdistance) + if ((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, @@ -1262,17 +1249,14 @@ void Game::Tick() for(int m=beginx;m<=endx;m++){ if(l!=person[i].whichblockx||m!=person[i].whichblocky){ - for(int j=0;j<path.vertexNum;j++){ - person[i].pathtarget.x=path.vertex[j].x; - person[i].pathtarget.y=path.vertex[j].y; - person[i].pathtarget.z=path.vertex[j].z; + for (unsigned char j = 0; j < 8; ++j){ + person[i].pathtarget = DIRECTIONS[j]; person[i].pathtarget*=person[i].pathsize; person[i].pathtarget.x+=l*block_spacing; person[i].pathtarget.z+=m*block_spacing; - if (j != 1 - && (sqrlen(person[i].playercoords - person[i].pathtarget) - < leastdistance) + 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)) && (segCrossModelTrans(person[i].playercoords, person[i].pathtarget, &blocksimple, @@ -1576,13 +1560,7 @@ void Game::Tick() XYZ wallhit; XYZ start; - XYZ finalwallhit; int numshots; - XYZ hitnorm; - XYZ hitmove; - int hitpoly = 0; - float hitrotation = 0.0f; - Model* model = NULL; for (int j = 0; j < numpeople; j++) { if (j && person[j].type != eviltype) @@ -1733,17 +1711,11 @@ void Game::Tick() int firstpass=-1; for(int m=0;m<bulletstrength;m++){ - //People - whichhit=-1; - for(int i=0;i<numpeople;i++){ - if(i!=j&&i!=firstpass&&person[i].existing){ - temphitstruct=person[i].BulletCollideWithPlayer(i, start, end); - if(temphitstruct.collision){ distance = sqrlen(start - temphitstruct.hitlocation); if(distance<olddistance||whichhit==-1){ @@ -1756,124 +1728,89 @@ void Game::Tick() } } - // Blocks - wallhit = {}; - beginx=(person[j].playercoords.x+block_spacing/2)/block_spacing-3; - - if(beginx<0)beginx=0; - - beginz=(person[j].playercoords.z+block_spacing/2)/block_spacing-3; - - if(beginz<0)beginz=0; - - endx=(person[j].playercoords.x+block_spacing/2)/block_spacing+3; - - if(endx>num_blocks-1)endx=num_blocks-1; - - endz=(person[j].playercoords.z+block_spacing/2)/block_spacing+3; - - if(endz>num_blocks-1)endz=num_blocks-1; - - if(beginx<endx&&beginz<endz) - - finalwallhit = {}; - for(int i=beginx;i<=endx;i++) - for(int j=beginz;j<=endz;j++){ + // Terrain damage + XYZ hitNorm; + Model* model; + GLfloat hitRot; + whichtri = -1; + beginx = std::max(0, + (int) (person[j].playercoords.x + block_spacing / 2) / block_spacing - 3); + beginz = std::max(0, + (int) (person[j].playercoords.z + block_spacing / 2) / block_spacing - 3); + endx = std::min(num_blocks - 1, + (int) (person[j].playercoords.x + block_spacing / 2) / block_spacing + 3); + endz = std::min(num_blocks - 1, + (int) (person[j].playercoords.z + block_spacing / 2) / block_spacing + 3); + for (auto i = beginx; i <= endx; ++i) + for (auto j = beginz; j <= endz; ++j) { + model = blocks + citytype[i][j]; move = {(float) i * block_spacing, 0.0f, (float) j * block_spacing}; + hitRot = cityrotation[i][j] * 90; whichtri = segCrossModelTrans(start, end, - blocks + citytype[i][j], - move, cityrotation[i][j] * 90, - &wallhit); + model, move, hitRot, &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; + hitNorm = rotate(model->faces[whichtri][0].normal, + 0, hitRot, 0); + goto hit_terrain; } } - whichtri = segCrossModelTrans(start, end, &Bigstreet, - {camera.position.x, 0.0f, camera.position.z}, 0, - &wallhit); + model = &this->Bigstreet; + move = {camera.position.x, 0.0f, camera.position.z}; + hitRot = 0.0f; + whichtri = segCrossModelTrans(start, end, + model, move, hitRot, &wallhit); if (whichtri > -1) { - end.y-=.5; - end=wallhit; - finalwallhit=wallhit; - bulletstrength=2; - hitnorm = {0.0f, 1.0f, 0.0f}; - hitmove = {}; - hitrotation=0; - } - - if(m==0){ - - if(j==0&&slomo==2){ - alSourceStop(gSourceID[whichsong]); - - alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 0); - - alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 0); - - if(person[0].whichgun==knife)whichsong=knifesong; - - if(person[0].whichgun!=knife)whichsong=shootsong; - - if(type==zombie_type)whichsong=zombiesong; - - alSourcef(gSourceID[whichsong], AL_PITCH, 1); - - alSourcePlay(gSourceID[whichsong]); - - alSourcef(gSourceID[whichsong], AL_MIN_GAIN, 1); - - alSourcef(gSourceID[whichsong], AL_MAX_GAIN, 1); - - slomo=0; - - if(whichhit==-1)alSourcePlay(gSourceID[disguisekillsound]); - - flashamount=.5; - - flashr=1;flashg=1;flashb=1; - + hitNorm = {0.0f, 1.0f, 0.0f}; +hit_terrain: + whichhit = -1; + addDecal(&decals, BULLET_HOLE, wallhit, 0.7f, + hitNorm, whichtri, model, move, hitRot); + const auto& velocity = hitNorm * 3; + switch (person[j].whichgun) { + case sniperrifle: + sprites.MakeSprite(smokesprite, .4, 1, 1, 1, wallhit, velocity, 10); + sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, wallhit, velocity, 2); + break; + case shotgun: + sprites.MakeSprite(smokesprite, .4, 1, 1, 1, wallhit, velocity, 5); + sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, wallhit, velocity, .8); + break; + case assaultrifle: + case handgun1: + case handgun2: + sprites.MakeSprite(smokesprite, .4, 1, 1, 1, wallhit, velocity, 6); + sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, wallhit, velocity, 1); + break; } + auto soundpos = wallhit - camera.position; + playSound(gSourceID[wallhitsound], + soundpos.x, soundpos.y, soundpos.z); } - //Impact - - XYZ oldend {end}; - - //with person + if (m == 0 && j == 0 && slomo == 2){ + if (whichhit == -1) + alSourcePlay(gSourceID[disguisekillsound]); + alSourcef(gSourceID[whichsong], AL_PITCH, 1); + slomo = 0; + flashamount = 0.5f; + flashr = flashg = flashb = 1.0f; + } + // Impact with person if(whichhit!=-1&&whichhit!=firstpass){ - if(j==0)person[whichhit].dead=1; - if(whichhit==1){ - murderer=j; - } if(person[whichhit].health==100&&j==0){ - if(person[whichhit].type==civiliantype)civkills++; - if(person[whichhit].type==eviltype)goodkills++; - } if(person[whichhit].health==100&&j!=0){ - badkills++; - } bool penetrate = (numshots > 1) ? 0 : !randUint(3); @@ -2085,37 +2022,8 @@ void Game::Tick() playSound(hitsound, hitpos.x, hitpos.y, hitpos.z); } - // with wall - 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); - break; - case shotgun: - sprites.MakeSprite(smokesprite, .4, 1, 1, 1, finalwallhit, velocity, 5); - sprites.MakeSprite(muzzleflashsprite, 1, 1, 1, 1, finalwallhit, velocity, .8); - 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; - playSound(gSourceID[wallhitsound], - soundpos.x, soundpos.y, soundpos.z); - } - lastshot[0]=start; - lastshot[1]=oldend; + lastshot[1]=end; auto velocity = aim * 8; if(person[j].whichgun!=sniperrifle&&person[j].whichgun!=shotgun&&p==numshots-1)sprites.MakeSprite(smokesprite, .3, 1, 1, 1, start+aim*1.5, velocity, 3); @@ -2209,7 +2117,8 @@ void Game::Tick() if (whichtri != -1) { impact = true; - auto normalrotated = rotate(blocks[citytype[wherex][wherey]].normals[whichtri], 0, cityrotation[wherex][wherey] * 90, 0); + const auto& normalrotated = rotate(blocks[citytype[wherex][wherey]].faces[whichtri][0].normal, + 0, cityrotation[wherex][wherey] * 90, 0); if (sprites.size[i] > 1) addDecal(&decals, CRATER, wallhit, 9.0f, normalrotated, whichtri, |
