- movetransports.

This commit is contained in:
Christoph Oelckers 2020-05-08 00:03:51 +02:00
parent d396df057f
commit cfead10cc2
5 changed files with 755 additions and 502 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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
{