From cfead10cc2033d83c38fec57970e54889172f416 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 8 May 2020 00:03:51 +0200 Subject: [PATCH] - movetransports. --- source/games/duke/src/actors_d.cpp | 340 +++++++++++++++++++ source/games/duke/src/actors_r.cpp | 396 ++++++++++++++++++++++ source/games/duke/src/e_actors.cpp | 505 +---------------------------- source/games/duke/src/global.h | 6 + source/games/duke/src/player.h | 10 +- 5 files changed, 755 insertions(+), 502 deletions(-) diff --git a/source/games/duke/src/actors_d.cpp b/source/games/duke/src/actors_d.cpp index 42ad9dd00..f10b759d0 100644 --- a/source/games/duke/src/actors_d.cpp +++ b/source/games/duke/src/actors_d.cpp @@ -1865,5 +1865,345 @@ void moveweapons_d(void) } } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void movetransports_d(void) +{ + char warpspriteto; + short j, k, l, p, sect, sectlotag, nextj, nextk; + int ll, onfloorz, q, nexti; + + for (int i = headspritestat[STAT_TRANSPORT]; i >= 0; i = nexti) + { + sect = sprite[i].sectnum; + sectlotag = sector[sect].lotag; + + nexti = nextspritestat[i]; + + if (sprite[i].owner == i) + { + i = nexti; + continue; + } + + onfloorz = hittype[i].temp_data[4]; + + if (hittype[i].temp_data[0] > 0) hittype[i].temp_data[0]--; + + j = headspritesect[sect]; + while (j >= 0) + { + nextj = nextspritesect[j]; + + switch (sprite[j].statnum) + { + case STAT_PLAYER: // Player + + if (sprite[j].owner != -1) + { + p = sprite[j].yvel; + + ps[p].on_warping_sector = 1; + + if (ps[p].transporter_hold == 0 && ps[p].jumping_counter == 0) + { + if (ps[p].on_ground && sectlotag == 0 && onfloorz && ps[p].jetpack_on == 0) + { + if (sprite[i].pal == 0) + { + spawn(i, TRANSPORTERBEAM); + spritesound(TELEPORTER, i); + } + + for (k = connecthead; k >= 0; k = connectpoint2[k]) + if (ps[k].cursectnum == sprite[sprite[i].owner].sectnum) + { + ps[k].frag_ps = p; + sprite[ps[k].i].extra = 0; + } + + ps[p].q16ang = sprite[sprite[i].owner].ang << FRACBITS; + + if (sprite[sprite[i].owner].owner != sprite[i].owner) + { + hittype[i].temp_data[0] = 13; + hittype[sprite[i].owner].temp_data[0] = 13; + ps[p].transporter_hold = 13; + } + + ps[p].bobposx = ps[p].oposx = ps[p].posx = sprite[sprite[i].owner].x; + ps[p].bobposy = ps[p].oposy = ps[p].posy = sprite[sprite[i].owner].y; + ps[p].oposz = ps[p].posz = sprite[sprite[i].owner].z - PHEIGHT; + + changespritesect(j, sprite[sprite[i].owner].sectnum); + ps[p].cursectnum = sprite[j].sectnum; + + if (sprite[i].pal == 0) + { + k = spawn(sprite[i].owner, TRANSPORTERBEAM); + spritesound(TELEPORTER, k); + } + + break; + } + } + else if (!(sectlotag == 1 && ps[p].on_ground == 1)) break; + + if (onfloorz == 0 && abs(sprite[i].z - ps[p].posz) < 6144) + if ((ps[p].jetpack_on == 0) || (ps[p].jetpack_on && (PlayerInput(p, SK_JUMP))) || + (ps[p].jetpack_on && (PlayerInput(p, SK_CROUCH) ^ !!ps[p].crouch_toggle))) + { + ps[p].oposx = ps[p].posx += sprite[sprite[i].owner].x - sprite[i].x; + ps[p].oposy = ps[p].posy += sprite[sprite[i].owner].y - sprite[i].y; + + if (ps[p].jetpack_on && (PlayerInput(p, SK_JUMP) || ps[p].jetpack_on < 11)) + ps[p].posz = sprite[sprite[i].owner].z - 6144; + else ps[p].posz = sprite[sprite[i].owner].z + 6144; + ps[p].oposz = ps[p].posz; + + hittype[ps[p].i].bposx = ps[p].posx; + hittype[ps[p].i].bposy = ps[p].posy; + hittype[ps[p].i].bposz = ps[p].posz; + + changespritesect(j, sprite[sprite[i].owner].sectnum); + ps[p].cursectnum = sprite[sprite[i].owner].sectnum; + + break; + } + + k = 0; + + if (onfloorz && sectlotag == ST_1_ABOVE_WATER && ps[p].on_ground && ps[p].posz > (sector[sect].floorz - (16 << 8)) && (PlayerInput(p, SK_CROUCH) || ps[p].poszv > 2048)) + // if( onfloorz && sectlotag == 1 && ps[p].posz > (sector[sect].floorz-(6<<8)) ) + { + k = 1; + if (screenpeek == p) + { + FX_StopAllSounds(); + } + if (sprite[ps[p].i].extra > 0) + spritesound(DUKE_UNDERWATER, j); + ps[p].oposz = ps[p].posz = + sector[sprite[sprite[i].owner].sectnum].ceilingz + (7 << 8); + + ps[p].posxv = 4096 - (krand() & 8192); + ps[p].posyv = 4096 - (krand() & 8192); + + } + + if (onfloorz && sectlotag == ST_2_UNDERWATER && ps[p].posz < (sector[sect].ceilingz + (6 << 8))) + { + k = 1; + // if( sprite[j].extra <= 0) break; + if (screenpeek == p) + { + FX_StopAllSounds(); + } + spritesound(DUKE_GASP, j); + + ps[p].oposz = ps[p].posz = + sector[sprite[sprite[i].owner].sectnum].floorz - (7 << 8); + + ps[p].jumping_toggle = 1; + ps[p].jumping_counter = 0; + } + + if (k == 1) + { + ps[p].oposx = ps[p].posx += sprite[sprite[i].owner].x - sprite[i].x; + ps[p].oposy = ps[p].posy += sprite[sprite[i].owner].y - sprite[i].y; + + if (sprite[sprite[i].owner].owner != sprite[i].owner) + ps[p].transporter_hold = -2; + ps[p].cursectnum = sprite[sprite[i].owner].sectnum; + + changespritesect(j, sprite[sprite[i].owner].sectnum); + setsprite(ps[p].i, ps[p].posx, ps[p].posy, ps[p].posz + PHEIGHT); + + setpal(&ps[p]); + + if ((krand() & 255) < 32) + spawn(j, WATERSPLASH2); + + if (sectlotag == 1) + for (l = 0; l < 9; l++) + { + q = spawn(ps[p].i, WATERBUBBLE); + sprite[q].z += krand() & 16383; + } + } + } + break; + + case STAT_ACTOR: + switch (sprite[j].picnum) + { + case SHARK: + case COMMANDER: + case OCTABRAIN: + case GREENSLIME: + case GREENSLIME + 1: + case GREENSLIME + 2: + case GREENSLIME + 3: + case GREENSLIME + 4: + case GREENSLIME + 5: + case GREENSLIME + 6: + case GREENSLIME + 7: + if (sprite[j].extra > 0) + goto JBOLT; + } + case STAT_PROJECTILE: + case STAT_MISC: + case STAT_FALLER: + case STAT_DUMMYPLAYER: + + ll = abs(sprite[j].zvel); + + { + warpspriteto = 0; + if (ll && sectlotag == 2 && sprite[j].z < (sector[sect].ceilingz + ll)) + warpspriteto = 1; + + if (ll && sectlotag == 1 && sprite[j].z > (sector[sect].floorz - ll)) + warpspriteto = 1; + + if (sectlotag == 0 && (onfloorz || abs(sprite[j].z - sprite[i].z) < 4096)) + { + if (sprite[sprite[i].owner].owner != sprite[i].owner && onfloorz && hittype[i].temp_data[0] > 0 && sprite[j].statnum != 5) + { + hittype[i].temp_data[0]++; + goto BOLT; + } + warpspriteto = 1; + } + + if (warpspriteto) switch (sprite[j].picnum) + { + case TRANSPORTERSTAR: + case TRANSPORTERBEAM: + case TRIPBOMB: + case BULLETHOLE: + case WATERSPLASH2: + case BURNING: + case BURNING2: + case FIRE: + case FIRE2: + case TOILETWATER: + case LASERLINE: + goto JBOLT; + case PLAYERONWATER: + if (sectlotag == 2) + { + sprite[j].cstat &= 32767; + break; + } + default: + if (sprite[j].statnum == 5 && !(sectlotag == 1 || sectlotag == 2)) + break; + + case WATERBUBBLE: + // if( rnd(192) && sprite[j].picnum == WATERBUBBLE) + // break; + + if (sectlotag > 0) + { + k = spawn(j, WATERSPLASH2); + if (sectlotag == 1 && sprite[j].statnum == 4) + { + sprite[k].xvel = sprite[j].xvel >> 1; + sprite[k].ang = sprite[j].ang; + ssp(k, CLIPMASK0); + } + } + + switch (sectlotag) + { + case 0: + if (onfloorz) + { + if (sprite[j].statnum == 4 || (checkcursectnums(sect) == -1 && checkcursectnums(sprite[sprite[i].owner].sectnum) == -1)) + { + sprite[j].x += (sprite[sprite[i].owner].x - sprite[i].x); + sprite[j].y += (sprite[sprite[i].owner].y - sprite[i].y); + sprite[j].z -= sprite[i].z - sector[sprite[sprite[i].owner].sectnum].floorz; + sprite[j].ang = sprite[sprite[i].owner].ang; + + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + hittype[j].bposz = sprite[j].z; + + if (sprite[i].pal == 0) + { + k = spawn(i, TRANSPORTERBEAM); + spritesound(TELEPORTER, k); + + k = spawn(sprite[i].owner, TRANSPORTERBEAM); + spritesound(TELEPORTER, k); + } + + if (sprite[sprite[i].owner].owner != sprite[i].owner) + { + hittype[i].temp_data[0] = 13; + hittype[sprite[i].owner].temp_data[0] = 13; + } + + changespritesect(j, sprite[sprite[i].owner].sectnum); + } + } + else + { + sprite[j].x += (sprite[sprite[i].owner].x - sprite[i].x); + sprite[j].y += (sprite[sprite[i].owner].y - sprite[i].y); + sprite[j].z = sprite[sprite[i].owner].z + 4096; + + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + hittype[j].bposz = sprite[j].z; + + changespritesect(j, sprite[sprite[i].owner].sectnum); + } + break; + case 1: + sprite[j].x += (sprite[sprite[i].owner].x - sprite[i].x); + sprite[j].y += (sprite[sprite[i].owner].y - sprite[i].y); + sprite[j].z = sector[sprite[sprite[i].owner].sectnum].ceilingz + ll; + + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + hittype[j].bposz = sprite[j].z; + + changespritesect(j, sprite[sprite[i].owner].sectnum); + + break; + case 2: + sprite[j].x += (sprite[sprite[i].owner].x - sprite[i].x); + sprite[j].y += (sprite[sprite[i].owner].y - sprite[i].y); + sprite[j].z = sector[sprite[sprite[i].owner].sectnum].floorz - ll; + + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + hittype[j].bposz = sprite[j].z; + + changespritesect(j, sprite[sprite[i].owner].sectnum); + + break; + } + + break; + } + } + break; + + } + JBOLT: + j = nextj; + } + BOLT:; + } +} END_DUKE_NS diff --git a/source/games/duke/src/actors_r.cpp b/source/games/duke/src/actors_r.cpp index 242e512a1..aff5b3f12 100644 --- a/source/games/duke/src/actors_r.cpp +++ b/source/games/duke/src/actors_r.cpp @@ -1639,5 +1639,401 @@ void moveweapons_r(void) } } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +void movetransports_r(void) +{ + char warpdir, warpspriteto; + short i, j, k, p, sect, sectlotag, nexti, nextj; + long ll2, ll, onfloorz; + + i = headspritestat[STAT_TRANSPORT]; //Transporters + + while (i >= 0) + { + sect = sprite[i].sectnum; + sectlotag = sector[sect].lotag; + + nexti = nextspritestat[i]; + + auto& OW = sprite[i].owner; + auto PN = sprite[i].picnum; + if (OW == i) + { + i = nexti; + continue; + } + + onfloorz = hittype[i].temp_data[4]; + + if (hittype[i].temp_data[0] > 0) hittype[i].temp_data[0]--; + + j = headspritesect[sect]; + while (j >= 0) + { + nextj = nextspritesect[j]; + + switch (sprite[j].statnum) + { + case STAT_PLAYER: // Player + + if (sprite[j].owner != -1) + { + p = sprite[j].yvel; + + ps[p].on_warping_sector = 1; + + if (ps[p].transporter_hold == 0 && ps[p].jumping_counter == 0) + { + if (ps[p].on_ground && sectlotag == 0 && onfloorz && ps[p].jetpack_on == 0) + { + spawn(i, TRANSPORTERBEAM); + spritesound(TELEPORTER, i); + + for (k = connecthead; k >= 0; k = connectpoint2[k])// connectpoinhittype[i].temp_data[1][k]) + if (ps[k].cursectnum == sprite[OW].sectnum) + { + ps[k].frag_ps = p; + sprite[ps[k].i].extra = 0; + } + + ps[p].q16ang = sprite[OW].ang << FRACBITS; + + if (sprite[OW].owner != OW) + { + hittype[i].temp_data[0] = 13; + hittype[OW].temp_data[0] = 13; + ps[p].transporter_hold = 13; + } + + ps[p].bobposx = ps[p].oposx = ps[p].posx = sprite[OW].x; + ps[p].bobposy = ps[p].oposy = ps[p].posy = sprite[OW].y; + ps[p].oposz = ps[p].posz = sprite[OW].z - (PHEIGHT - (4 << 8)); + + changespritesect(j, sprite[OW].sectnum); + ps[p].cursectnum = sprite[j].sectnum; + + k = spawn(OW, TRANSPORTERBEAM); + spritesound(TELEPORTER, k); + + break; + } + } + else break; + + if (onfloorz == 0 && abs(sprite[i].z - ps[p].posz) < 6144) + if ((ps[p].jetpack_on == 0) || (ps[p].jetpack_on && PlayerInput(p, SK_JUMP)) || + (ps[p].jetpack_on && PlayerInput(p, SK_CROUCH))) + { + ps[p].oposx = ps[p].posx += sprite[OW].x - sprite[i].x; + ps[p].oposy = ps[p].posy += sprite[OW].y - sprite[i].y; + + if (ps[p].jetpack_on && (PlayerInput(p, SK_JUMP) || ps[p].jetpack_on < 11)) + ps[p].posz = sprite[OW].z - 6144; + else ps[p].posz = sprite[OW].z + 6144; + ps[p].oposz = ps[p].posz; + + changespritesect(j, sprite[OW].sectnum); + ps[p].cursectnum = sprite[OW].sectnum; + + break; + } + + k = 0; + + if (isRRRA()) + { + if (onfloorz && sectlotag == 160 && ps[p].posz > (sector[sect].floorz - (48 << 8))) + { + k = 2; + ps[p].oposz = ps[p].posz = + sector[sprite[OW].sectnum].ceilingz + (7 << 8); + } + + if (onfloorz && sectlotag == 161 && ps[p].posz < (sector[sect].ceilingz + (6 << 8))) + { + k = 2; + if (sprite[ps[p].i].extra <= 0) break; + ps[p].oposz = ps[p].posz = + sector[sprite[OW].sectnum].floorz - (49 << 8); + } + } + + if ((onfloorz && sectlotag == ST_1_ABOVE_WATER && ps[p].posz > (sector[sect].floorz - (6 << 8))) || + (onfloorz && sectlotag == ST_1_ABOVE_WATER && ps[p].OnMotorcycle)) + { + if (ps[p].OnBoat) break; + k = 1; + if (screenpeek == p) + { + FX_StopAllSounds(); + } + spritesound(DUKE_UNDERWATER, ps[p].i); + ps[p].oposz = ps[p].posz = + sector[sprite[OW].sectnum].ceilingz + (7 << 8); + if (ps[p].OnMotorcycle) + ps[p].moto_underwater = 1; + } + + if (onfloorz && sectlotag == ST_2_UNDERWATER && ps[p].posz < (sector[sect].ceilingz + (6 << 8))) + { + k = 1; + if (sprite[ps[p].i].extra <= 0) break; + if (screenpeek == p) + { + FX_StopAllSounds(); + } + spritesound(DUKE_GASP, ps[p].i); + + ps[p].oposz = ps[p].posz = + sector[sprite[OW].sectnum].floorz - (7 << 8); + } + + if (k == 1) + { + ps[p].oposx = ps[p].posx += sprite[OW].x - sprite[i].x; + ps[p].oposy = ps[p].posy += sprite[OW].y - sprite[i].y; + + if (sprite[OW].owner != OW) + ps[p].transporter_hold = -2; + ps[p].cursectnum = sprite[OW].sectnum; + + changespritesect(j, sprite[OW].sectnum); + + setpal(&ps[p]); + + if ((krand() & 255) < 32) + spawn(ps[p].i, WATERSPLASH2); + } + else if (isRRRA() && k == 2) + { + ps[p].oposx = ps[p].posx += sprite[OW].x - sprite[i].x; + ps[p].oposy = ps[p].posy += sprite[OW].y - sprite[i].y; + + if (sprite[OW].owner != OW) + ps[p].transporter_hold = -2; + ps[p].cursectnum = sprite[OW].sectnum; + + changespritesect(j, sprite[OW].sectnum); + } + } + break; + + case STAT_ACTOR: + if (PN == SHARK || + (isRRRA() && (PN == CHEERBOAT || PN == HULKBOAT || PN == MINIONBOAT || PN == UFO1_RRRA)) || + (!isRRRA() && (PN == UFO1_RR || PN == UFO2 || PN == UFO3 || PN == UFO4 || PN == UFO5))) goto JBOLT; + case STAT_PROJECTILE: + case STAT_MISC: + case STAT_DUMMYPLAYER: + + ll = abs(sprite[j].zvel); + if (isRRRA()) + { + if (sprite[j].zvel >= 0) + warpdir = 2; + else + warpdir = 1; + } + + { + warpspriteto = 0; + if (ll && sectlotag == ST_2_UNDERWATER && sprite[j].z < (sector[sect].ceilingz + ll)) + warpspriteto = 1; + + if (ll && sectlotag == ST_1_ABOVE_WATER && sprite[j].z > (sector[sect].floorz - ll)) + if (!isRRRA() || (sprite[j].picnum != CHEERBOAT && sprite[j].picnum != HULKBOAT && sprite[j].picnum != MINIONBOAT)) + warpspriteto = 1; + + if (isRRRA()) + { + if (ll && sectlotag == 161 && sprite[j].z < (sector[sect].ceilingz + ll) && warpdir == 1) + { + warpspriteto = 1; + ll2 = ll - abs(sprite[j].z - sector[sect].ceilingz); + } + else if (sectlotag == 161 && sprite[j].z < (sector[sect].ceilingz + 1000) && warpdir == 1) + { + warpspriteto = 1; + ll2 = 1; + } + if (ll && sectlotag == 160 && sprite[j].z > (sector[sect].floorz - ll) && warpdir == 2) + { + warpspriteto = 1; + ll2 = ll - abs(sector[sect].floorz - sprite[j].z); + } + else if (sectlotag == 160 && sprite[j].z > (sector[sect].floorz - 1000) && warpdir == 2) + { + warpspriteto = 1; + ll2 = 1; + } + } + + if (sectlotag == 0 && (onfloorz || abs(sprite[j].z - sprite[i].z) < 4096)) + { + if (sprite[OW].owner != OW && onfloorz && hittype[i].temp_data[0] > 0 && sprite[j].statnum != 5) + { + hittype[i].temp_data[0]++; + goto BOLT; + } + warpspriteto = 1; + } + + if (warpspriteto) switch (sprite[j].picnum) + { + case TRANSPORTERSTAR: + case TRANSPORTERBEAM: + case BULLETHOLE: + case WATERSPLASH2: + case BURNING: + case FIRE: + case MUD: + goto JBOLT; + case PLAYERONWATER: + if (sectlotag == ST_2_UNDERWATER) + { + sprite[j].cstat &= 32767; + break; + } + default: + if (sprite[j].statnum == 5 && !(sectlotag == ST_1_ABOVE_WATER || sectlotag == ST_2_UNDERWATER || (isRRRA() && (sectlotag == 160 || sectlotag == 161)))) + break; + + case WATERBUBBLE: + if (rnd(192) && sprite[j].picnum == WATERBUBBLE) + break; + + if (sectlotag > 0) + { + k = spawn(j, WATERSPLASH2); + if (sectlotag == 1 && sprite[j].statnum == 4) + { + sprite[k].xvel = sprite[j].xvel >> 1; + sprite[k].ang = sprite[j].ang; + ssp(k, CLIPMASK0); + } + } + + switch (sectlotag) + { + case ST_0_NO_EFFECT: + if (onfloorz) + { + if (checkcursectnums(sect) == -1 && checkcursectnums(sprite[OW].sectnum) == -1) + { + sprite[j].x += (sprite[OW].x - sprite[i].x); + sprite[j].y += (sprite[OW].y - sprite[i].y); + sprite[j].z -= sprite[i].z - sector[sprite[OW].sectnum].floorz; + sprite[j].ang = sprite[OW].ang; + + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + hittype[j].bposz = sprite[j].z; + + k = spawn(i, TRANSPORTERBEAM); + spritesound(TELEPORTER, k); + + k = spawn(OW, TRANSPORTERBEAM); + spritesound(TELEPORTER, k); + + if (sprite[OW].owner != OW) + { + hittype[i].temp_data[0] = 13; + hittype[OW].temp_data[0] = 13; + } + + changespritesect(j, sprite[OW].sectnum); + } + } + else + { + sprite[j].x += (sprite[OW].x - sprite[i].x); + sprite[j].y += (sprite[OW].y - sprite[i].y); + sprite[j].z = sprite[OW].z + 4096; + + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + hittype[j].bposz = sprite[j].z; + + changespritesect(j, sprite[OW].sectnum); + } + break; + case ST_1_ABOVE_WATER: + sprite[j].x += (sprite[OW].x - sprite[i].x); + sprite[j].y += (sprite[OW].y - sprite[i].y); + sprite[j].z = sector[sprite[OW].sectnum].ceilingz + ll; + + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + hittype[j].bposz = sprite[j].z; + + changespritesect(j, sprite[OW].sectnum); + + break; + case ST_2_UNDERWATER: + sprite[j].x += (sprite[OW].x - sprite[i].x); + sprite[j].y += (sprite[OW].y - sprite[i].y); + sprite[j].z = sector[sprite[OW].sectnum].floorz - ll; + + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + hittype[j].bposz = sprite[j].z; + + changespritesect(j, sprite[OW].sectnum); + + break; + + case 160: + if (!isRRRA()) break; + sprite[j].x += (sprite[OW].x - sprite[i].x); + sprite[j].y += (sprite[OW].y - sprite[i].y); + sprite[j].z = sector[sprite[OW].sectnum].ceilingz + ll2; + + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + hittype[j].bposz = sprite[j].z; + + changespritesect(j, sprite[OW].sectnum); + + movesprite(j, (sprite[j].xvel * sintable[(sprite[j].ang + 512) & 2047]) >> 14, + (sprite[j].xvel * sintable[sprite[j].ang & 2047]) >> 14, 0, CLIPMASK1); + + break; + case 161: + if (!isRRRA()) break; + sprite[j].x += (sprite[OW].x - sprite[i].x); + sprite[j].y += (sprite[OW].y - sprite[i].y); + sprite[j].z = sector[sprite[OW].sectnum].floorz - ll2; + + hittype[j].bposx = sprite[j].x; + hittype[j].bposy = sprite[j].y; + hittype[j].bposz = sprite[j].z; + + changespritesect(j, sprite[OW].sectnum); + + movesprite(j, (sprite[j].xvel * sintable[(sprite[j].ang + 512) & 2047]) >> 14, + (sprite[j].xvel * sintable[sprite[j].ang & 2047]) >> 14, 0, CLIPMASK1); + + break; + } + + break; + } + } + break; + + } + JBOLT: + j = nextj; + } + BOLT: + i = nexti; + } +} + END_DUKE_NS diff --git a/source/games/duke/src/e_actors.cpp b/source/games/duke/src/e_actors.cpp index 6c80e95b2..8525a620a 100644 --- a/source/games/duke/src/e_actors.cpp +++ b/source/games/duke/src/e_actors.cpp @@ -369,11 +369,6 @@ int A_IncurDamage(int const spriteNum) } - -static int P_Submerge(int, int, DukePlayer_t *, int, int); -static int P_Emerge(int, int, DukePlayer_t *, int, int); -static void P_FinishWaterChange(int, DukePlayer_t *, int, int, int); - static void Proj_BounceOffWall(spritetype *s, int j) { int k = getangle( @@ -382,500 +377,6 @@ static void Proj_BounceOffWall(spritetype *s, int j) s->ang = ((k<<1) - s->ang)&2047; } - - - - -static int P_Submerge(int const spriteNum, int const playerNum, DukePlayer_t * const pPlayer, int const sectNum, int const otherSect) -{ - if ((!RR && pPlayer->on_ground && pPlayer->pos.z > sector[sectNum].floorz - ZOFFSET2 - && (TEST_SYNC_KEY(g_player[playerNum].input->bits, SK_CROUCH) || pPlayer->vel.z > 2048)) - || (RR && pPlayer->pos.z > (sector[sectNum].floorz-(6<<8))) || pPlayer->OnMotorcycle) - // if( onfloorz && sectlotag == 1 && ps->pos.z > (sector[sect].floorz-(6<<8)) ) - { - if (pPlayer->OnBoat) return 0; - - if (screenpeek == playerNum) - { - FX_StopAllSounds(); - S_ClearSoundLocks(); - } - - if (RR || sprite[pPlayer->i].extra > 0) - A_PlaySound(DUKE_UNDERWATER, spriteNum); - - pPlayer->opos.z = pPlayer->pos.z = sector[otherSect].ceilingz + (7<<8); - - if (!RR) - { - pPlayer->vel.x = 4096-(krand2()&8192); - pPlayer->vel.y = 4096-(krand2()&8192); - } - - if (pPlayer->OnMotorcycle) - pPlayer->moto_underwater = 1; - - return 1; - } - - return 0; -} - -static int P_Emerge(int const spriteNum, int const playerNum, DukePlayer_t * const pPlayer, int const sectNum, int const otherSect) -{ - // r1449-: - if (pPlayer->pos.z < (sector[sectNum].ceilingz+(6<<8))) - // r1450+, breaks submergible slime in bobsp2: -// if (onfloorz && sectlotag == 2 && ps->pos.z <= sector[sect].ceilingz /*&& ps->vel.z == 0*/) - { - if (RR && sprite[pPlayer->i].extra <= 0) return 1; - if (screenpeek == playerNum) - { - FX_StopAllSounds(); - S_ClearSoundLocks(); - } - - A_PlaySound(DUKE_GASP, spriteNum); - - pPlayer->opos.z = pPlayer->pos.z = sector[otherSect].floorz - (7<<8); - //pPlayer->vel.z = 0; -// ps->vel.z += 1024; - - if (!RR) - { - pPlayer->jumping_toggle = 1; - pPlayer->jumping_counter = 0; - } - - return 1; - } - - return 0; -} - -static void P_FinishWaterChange(int const playerNum, DukePlayer_t * const pPlayer, int const sectLotag, int const spriteOwner, int const newSector) -{ - /*pPlayer->bobpos.x = */pPlayer->opos.x = pPlayer->pos.x; - /*pPlayer->bobpos.y = */pPlayer->opos.y = pPlayer->pos.y; - - if (spriteOwner < 0 || sprite[spriteOwner].owner != spriteOwner) - pPlayer->transporter_hold = -2; - - pPlayer->cursectnum = newSector; - changespritesect(playerNum, newSector); - - if (!RR) - { - vec3_t vect = pPlayer->pos; - vect.z += PHEIGHT; - setsprite(pPlayer->i, &vect); - } - - P_UpdateScreenPal(pPlayer); - - if ((krand2()&255) < 32) - A_Spawn(RR ? pPlayer->i : playerNum, TILE_WATERSPLASH2); - - if (!RR && sectLotag == ST_1_ABOVE_WATER) - { - for (bssize_t l = 0; l < 9; l++) - sprite[A_Spawn(pPlayer->i, TILE_WATERBUBBLE)].z += krand2() & 16383; - } -} - -// Check prevention of teleportation *when alive*. For example, commanders and -// octabrains would be transported by SE7 (both water and normal) only if dead. -static int A_CheckNonTeleporting(int const spriteNum) -{ - int const tileNum = sprite[spriteNum].picnum; - if (RRRA) - { - return !!(tileNum == TILE_SHARK || tileNum == TILE_CHEERBOAT || tileNum == TILE_HULKBOAT - || tileNum == TILE_MINIONBOAT || tileNum == TILE_UFO1); - } - else if (RR) - { - return !!(tileNum == TILE_SHARK || tileNum == TILE_UFO1 || tileNum == TILE_UFO2 - || tileNum == TILE_UFO3 || tileNum == TILE_UFO4 || tileNum == TILE_UFO5); - } - return !!(tileNum == TILE_SHARK || tileNum == TILE_COMMANDER || tileNum == TILE_OCTABRAIN - || (tileNum >= TILE_GREENSLIME && tileNum <= TILE_GREENSLIME + 7)); -} - -ACTOR_STATIC void G_MoveTransports(void) -{ - int spriteNum = headspritestat[STAT_TRANSPORT]; - - while (spriteNum >= 0) - { - int const nextSprite = nextspritestat[spriteNum]; - - if (OW(spriteNum) == spriteNum) - { - spriteNum = nextSprite; - continue; - } - - int const sectNum = SECT(spriteNum); - int const sectLotag = sector[sectNum].lotag; - int const onFloor = T5(spriteNum); // ONFLOORZ - - if (T1(spriteNum) > 0) - T1(spriteNum)--; - - int sectSprite = headspritesect[sectNum]; - while (sectSprite >= 0) - { - int const nextSectSprite = nextspritesect[sectSprite]; - - switch (sprite[sectSprite].statnum) - { - case STAT_PLAYER: - if (sprite[sectSprite].owner != -1) - { - int const playerNum = P_Get(sectSprite); - DukePlayer_t *const pPlayer = g_player[playerNum].ps; - - pPlayer->on_warping_sector = 1; - - if (pPlayer->transporter_hold == 0 && pPlayer->jumping_counter == 0) - { - if (pPlayer->on_ground && sectLotag == 0 && onFloor && pPlayer->jetpack_on == 0) - { - if (RR || sprite[spriteNum].pal == 0) - { - A_Spawn(spriteNum, TILE_TRANSPORTERBEAM); - A_PlaySound(TELEPORTER, spriteNum); - } - for (int TRAVERSE_CONNECT(otherPlayer)) - { - if (g_player[otherPlayer].ps->cursectnum == sprite[OW(spriteNum)].sectnum) - { - g_player[otherPlayer].ps->frag_ps = playerNum; - sprite[g_player[otherPlayer].ps->i].extra = 0; - } - } - - pPlayer->q16ang = fix16_from_int(sprite[OW(spriteNum)].ang); - - if (sprite[OW(spriteNum)].owner != OW(spriteNum)) - { - T1(spriteNum) = 13; - actor[OW(spriteNum)].t_data[0] = 13; - pPlayer->transporter_hold = 13; - } - - pPlayer->pos = *(vec3_t *)&sprite[OW(spriteNum)]; - pPlayer->pos.z -= PHEIGHT-(RR ? (4<<8) : 0); - pPlayer->opos = pPlayer->pos; - pPlayer->bobpos = *(vec2_t *)&pPlayer->pos; - - changespritesect(sectSprite, sprite[OW(spriteNum)].sectnum); - pPlayer->cursectnum = sprite[sectSprite].sectnum; - - if (RR || sprite[spriteNum].pal == 0) - { - int const newSprite = A_Spawn(OW(spriteNum), TILE_TRANSPORTERBEAM); - A_PlaySound(TELEPORTER, newSprite); - } - break; - } - } - else if (RR || !(sectLotag == ST_1_ABOVE_WATER && pPlayer->on_ground == 1)) - break; - - if (onFloor == 0 && klabs(SZ(spriteNum) - pPlayer->pos.z) < 6144) - if (!pPlayer->jetpack_on || TEST_SYNC_KEY(g_player[playerNum].input->bits, SK_JUMP) - || (TEST_SYNC_KEY(g_player[playerNum].input->bits, SK_CROUCH) ^ pPlayer->crouch_toggle)) - { - pPlayer->pos.x += sprite[OW(spriteNum)].x - SX(spriteNum); - pPlayer->pos.y += sprite[OW(spriteNum)].y - SY(spriteNum); - pPlayer->pos.z = (pPlayer->jetpack_on && (TEST_SYNC_KEY(g_player[playerNum].input->bits, SK_JUMP) - || pPlayer->jetpack_on < 11)) - ? sprite[OW(spriteNum)].z - 6144 - : sprite[OW(spriteNum)].z + 6144; - - if (!RR) - actor[pPlayer->i].bpos = pPlayer->pos; - pPlayer->opos = pPlayer->pos; - //pPlayer->bobpos = *(vec2_t *)&pPlayer->pos; - - changespritesect(sectSprite, sprite[OW(spriteNum)].sectnum); - pPlayer->cursectnum = sprite[OW(spriteNum)].sectnum; - - break; - } - - int doWater = 0; - - if (RRRA) - { - if (onFloor) - { - if (sectLotag == 160 && pPlayer->pos.z > (sector[sectNum].floorz-(48<<8))) - { - doWater = 2; - pPlayer->opos.z = pPlayer->pos.z = sector[sprite[OW(spriteNum)].sectnum].ceilingz+(7<<8); - } - else if (sectLotag == 161 && pPlayer->pos.z < (sector[sectNum].ceilingz+(6<<8)) && sprite[pPlayer->i].extra > 0) - { - doWater = 2; - pPlayer->opos.z = pPlayer->pos.z = sector[sprite[OW(spriteNum)].sectnum].floorz-(49<<8); - } - } - } - - if (onFloor) - { - if (sectLotag == ST_1_ABOVE_WATER) - doWater = P_Submerge(sectSprite, playerNum, pPlayer, sectNum, sprite[OW(spriteNum)].sectnum); - else if (sectLotag == ST_2_UNDERWATER) - doWater = P_Emerge(sectSprite, playerNum, pPlayer, sectNum, sprite[OW(spriteNum)].sectnum); - } - - if (doWater == 1) - { - pPlayer->pos.x += sprite[OW(spriteNum)].x - SX(spriteNum); - pPlayer->pos.y += sprite[OW(spriteNum)].y - SY(spriteNum); - - P_FinishWaterChange(sectSprite, pPlayer, sectLotag, OW(spriteNum), sprite[OW(spriteNum)].sectnum); - } - else if (doWater == 2) - { - pPlayer->pos.x += sprite[OW(spriteNum)].x - SX(spriteNum); - pPlayer->pos.y += sprite[OW(spriteNum)].y - SY(spriteNum); - pPlayer->opos.x = pPlayer->pos.x; - pPlayer->opos.y = pPlayer->pos.y; - - if (sprite[OW(spriteNum)].owner != OW(spriteNum)) - pPlayer->transporter_hold = -2; - - pPlayer->cursectnum = sprite[OW(spriteNum)].sectnum; - changespritesect(sectSprite, sprite[OW(spriteNum)].sectnum); - } - } - break; - - - ////////// Non-player teleportation ////////// - - case STAT_ACTOR: - if ((RR || sprite[sectSprite].extra > 0) && A_CheckNonTeleporting(sectSprite)) - goto JBOLT; - fallthrough__; - case STAT_PROJECTILE: - case STAT_MISC: - case STAT_FALLER: - case STAT_DUMMYPLAYER: - { - if (RR && sprite[sectSprite].statnum == STAT_FALLER) break; - //if ((totalclock & UINT8_MAX) != actor[sectSprite].lasttransport) - { - int const zvel = sprite[sectSprite].zvel; - int const absZvel = klabs(zvel); - int doWarp = 0; - int warpDir; - int absZdiff; - - if (zvel >= 0) - warpDir = 2; - else - warpDir = 1; - - if (absZvel != 0) - { - if (sectLotag == ST_2_UNDERWATER && sprite[sectSprite].z < (sector[sectNum].ceilingz + absZvel)) - doWarp = 1; - if (sectLotag == ST_1_ABOVE_WATER && sprite[sectSprite].z > (sector[sectNum].floorz - absZvel)) - if (!RRRA || (sprite[sectSprite].picnum != TILE_CHEERBOAT && sprite[sectSprite].picnum != TILE_HULKBOAT && sprite[sectSprite].picnum != TILE_MINIONBOAT)) - doWarp = 1; - } - - if (RRRA) - { - if (absZvel != 0 && sectLotag == 161 && sprite[sectSprite].z < (sector[sectNum].ceilingz + absZvel) && warpDir == 1) - { - doWarp = 1; - absZdiff = absZvel - klabs(sprite[sectSprite].z-sector[sectNum].ceilingz); - } - else if (sectLotag == 161 && sprite[sectSprite].z < (sector[sectNum].ceilingz + 1000) && warpDir == 1) - { - doWarp = 1; - absZdiff = 1; - } - if (absZvel != 0 && sectLotag == 160 && sprite[sectSprite].z > (sector[sectNum].floorz - absZvel) && warpDir == 2) - { - doWarp = 1; - absZdiff = absZvel - klabs(sector[sectNum].floorz-sprite[sectSprite].z); - } - else if (sectLotag == 160 && sprite[sectSprite].z > (sector[sectNum].floorz - 1000) && warpDir == 2) - { - doWarp = 1; - absZdiff = 1; - } - } - - if (sectLotag == 0 && (onFloor || klabs(sprite[sectSprite].z - SZ(spriteNum)) < 4096)) - { - if (sprite[OW(spriteNum)].owner != OW(spriteNum) && onFloor && T1(spriteNum) > 0 - && sprite[sectSprite].statnum != STAT_MISC) - { - T1(spriteNum)++; - goto next_sprite; - } - doWarp = 1; - } - - if (doWarp) - { - switch (DYNAMICTILEMAP(sprite[sectSprite].picnum)) - { - case TRIPBOMB__STATIC: - case BURNING2__STATIC: - case FIRE2__STATIC: - case TOILETWATER__STATIC: - case LASERLINE__STATIC: - if (RR) goto default_case; - fallthrough__; - case TRIPBOMBSPRITE__STATIC: - if (!RR && sprite[sectSprite].picnum == TILE_TRIPBOMBSPRITE) - goto default_case; - fallthrough__; - case TRANSPORTERSTAR__STATIC: - case TRANSPORTERBEAM__STATIC: - case BULLETHOLE__STATIC: - case WATERSPLASH2__STATIC: - case BURNING__STATIC: - case FIRE__STATIC: - case MUD__STATICRR: goto JBOLT; - case PLAYERONWATER__STATIC: - if (sectLotag == ST_2_UNDERWATER) - { - sprite[sectSprite].cstat &= 32767; - break; - } - fallthrough__; - default: -default_case: - if (sprite[sectSprite].statnum == STAT_MISC && !(sectLotag == ST_1_ABOVE_WATER || sectLotag == ST_2_UNDERWATER || (RRRA && (sectLotag == 160 || sectLotag == 161)))) - break; - fallthrough__; - case WATERBUBBLE__STATIC: - if (RR) - if( rnd(192) && sprite[sectSprite].picnum == TILE_WATERBUBBLE) - break; - - if (sectLotag > 0) - { - // Water SE7 teleportation. - int const osect = sprite[OW(spriteNum)].sectnum; - - Bassert(sectLotag == ST_1_ABOVE_WATER || sectLotag == ST_2_UNDERWATER || (RRRA && (sectLotag == 160 || sectLotag == 161))); - - int const newSprite = A_Spawn(sectSprite, TILE_WATERSPLASH2); - - if (sectLotag == ST_1_ABOVE_WATER && sprite[sectSprite].statnum == STAT_PROJECTILE) - { - sprite[newSprite].xvel = sprite[sectSprite].xvel >> 1; - sprite[newSprite].ang = sprite[sectSprite].ang; - A_SetSprite(newSprite, CLIPMASK0); - } - - actor[sectSprite].lasttransport = ((int32_t) totalclock & UINT8_MAX); - - if (sectLotag == ST_1_ABOVE_WATER || sectLotag == ST_2_UNDERWATER) - { - sprite[sectSprite].x += sprite[OW(spriteNum)].x - SX(spriteNum); - sprite[sectSprite].y += sprite[OW(spriteNum)].y - SY(spriteNum); - sprite[sectSprite].z = (sectLotag == ST_1_ABOVE_WATER) ? sector[osect].ceilingz+absZvel : sector[osect].floorz-absZvel; - - actor[sectSprite].bpos = *(vec3_t *)&sprite[sectSprite]; - - changespritesect(sectSprite, sprite[OW(spriteNum)].sectnum); - } - else - { - sprite[sectSprite].x += sprite[OW(spriteNum)].x - SX(spriteNum); - sprite[sectSprite].y += sprite[OW(spriteNum)].y - SY(spriteNum); - sprite[sectSprite].z = (sectLotag == 160) ? sector[osect].ceilingz+absZdiff : sector[osect].floorz-absZdiff; - - actor[sectSprite].bpos = *(vec3_t *)&sprite[sectSprite]; - - changespritesect(sectSprite, sprite[OW(spriteNum)].sectnum); - - vec3_t const vect = { - (sprite[sectSprite].xvel*sintable[(sprite[sectSprite].ang+512)&2047])>>14, - (sprite[sectSprite].xvel*sintable[sprite[sectSprite].ang])>>14, - 0 - }; - - A_MoveSprite(sectSprite, &vect, CLIPMASK1); - } - } - else if (Bassert(sectLotag == 0), 1) - { - // Non-water SE7 teleportation. - - if (onFloor) - { - if ((!RR && sprite[sectSprite].statnum == STAT_PROJECTILE) - || (G_CheckPlayerInSector(sectNum) == -1 - && G_CheckPlayerInSector(sprite[OW(spriteNum)].sectnum) == -1)) - { - sprite[sectSprite].x += (sprite[OW(spriteNum)].x - SX(spriteNum)); - sprite[sectSprite].y += (sprite[OW(spriteNum)].y - SY(spriteNum)); - sprite[sectSprite].z -= SZ(spriteNum) - sector[sprite[OW(spriteNum)].sectnum].floorz; - - sprite[sectSprite].ang = sprite[OW(spriteNum)].ang; - actor[sectSprite].bpos = *(vec3_t *)&sprite[sectSprite]; - - if (RR || sprite[spriteNum].pal == 0) - { - int newSprite = A_Spawn(spriteNum, TILE_TRANSPORTERBEAM); - A_PlaySound(TELEPORTER, newSprite); - - newSprite = A_Spawn(OW(spriteNum), TILE_TRANSPORTERBEAM); - A_PlaySound(TELEPORTER, newSprite); - } - - if (sprite[OW(spriteNum)].owner != OW(spriteNum)) - { - T1(spriteNum) = 13; - actor[OW(spriteNum)].t_data[0] = 13; - } - - changespritesect(sectSprite, sprite[OW(spriteNum)].sectnum); - } - } - else - { - sprite[sectSprite].x += (sprite[OW(spriteNum)].x - SX(spriteNum)); - sprite[sectSprite].y += (sprite[OW(spriteNum)].y - SY(spriteNum)); - sprite[sectSprite].z = sprite[OW(spriteNum)].z + 4096; - - actor[sectSprite].bpos = *(vec3_t *)&sprite[sectSprite]; - - changespritesect(sectSprite, sprite[OW(spriteNum)].sectnum); - } - } - - break; - } // switch (DYNAMICTILEMAP(sprite[j].picnum)) - } // if (doWarp) - } // if (totalclock > actor[j].lasttransport) - - break; - } // five cases - - } // switch (sprite[j].statnum) - JBOLT: - sectSprite = nextSectSprite; - } - next_sprite: - spriteNum = nextSprite; - } -} - static int A_FindLocator(int const tag, int const sectNum) { for (bssize_t SPRITES_OF(STAT_LOCATOR, spriteNum)) @@ -6953,6 +6454,7 @@ void movefta_d(void); void movefallers_d(); void movestandables_d(); void moveweapons_d(); +void movetransports_d(void); void movefta_r(void); void moveplayers(); @@ -6960,6 +6462,7 @@ void movefx(); void movefallers_r(); void movestandables_r(); void moveweapons_r(); +void movetransports_r(void); void G_MoveWorld_d(void) { @@ -6968,7 +6471,7 @@ void G_MoveWorld_d(void) movefta_d(); //ST 2 moveweapons_d(); //ST 4 - G_MoveTransports(); //ST 9 + movetransports_d(); //ST 9 moveplayers(); //ST 10 movefallers_d(); //ST 12 @@ -7002,7 +6505,7 @@ void G_MoveWorld_r(void) { movefta_r(); //ST 2 moveweapons_r(); //ST 4 - G_MoveTransports(); //ST 9 + movetransports_r(); //ST 9 } moveplayers(); //ST 10 diff --git a/source/games/duke/src/global.h b/source/games/duke/src/global.h index 1026eed38..731e22296 100644 --- a/source/games/duke/src/global.h +++ b/source/games/duke/src/global.h @@ -364,6 +364,12 @@ bool isIn(int value, int first, Args... args) #define pPick2(d, r) (isRR()? (r) : (d)) +inline bool PlayerInput(int pl, int bit) +{ + return TEST_SYNC_KEY(g_player[pl].input->bits, bit); +} + + END_DUKE_NS #endif diff --git a/source/games/duke/src/player.h b/source/games/duke/src/player.h index b04c741dc..0596e7a16 100644 --- a/source/games/duke/src/player.h +++ b/source/games/duke/src/player.h @@ -152,7 +152,13 @@ typedef struct player_struct { struct { int32_t posxv, posyv, poszv; }; }; vec3_t npos; - vec2_t bobpos, fric; + union + { + vec2_t bobpos; + struct { int32_t bobposx, bobposy; }; + }; + + vec2_t fric; fix16_t q16horiz, q16horizoff; fix16_t q16ang, oq16ang; @@ -272,9 +278,11 @@ typedef struct char vote, gotvote, playerreadyflag, playerquitflag, connected; char user_name[32]; char syncval[SYNCFIFOSIZ][MAXSYNCBYTES]; + } playerdata_t; #pragma pack(pop) + // KEEPINSYNC lunatic/con_lang.lua typedef struct {