TROR: Prototypical no-SE7 water submersion/emersion.

Submersion only happens when the upper sector has lotag 1 and its vertical
neighbor has lotag 2 (this can be useful to create non-submergible above-water
sectors).  Currently, only the player is handled.  On the implementation side,
the water handling code is split into P_Submerge() and P_Emerge() preparing the
"teleportation", and P_FinishWaterChange() for the finalization.

git-svn-id: https://svn.eduke32.com/eduke32@3072 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2012-10-14 20:41:17 +00:00
parent bc9a29b121
commit e921346dac
3 changed files with 161 additions and 102 deletions

View file

@ -1057,12 +1057,16 @@ BOLT:
} }
} }
static int32_t P_Submerge(int32_t j, int32_t p, DukePlayer_t *ps, int32_t sect, int32_t othersect);
static int32_t P_Emerge(int32_t j, int32_t p, DukePlayer_t *ps, int32_t sect, int32_t othersect);
static void P_FinishWaterChange(int32_t j, DukePlayer_t *ps, int32_t sectlotag, int32_t ow, int32_t newsectnum);
int32_t otherp; int32_t otherp;
ACTOR_STATIC void G_MovePlayers(void) ACTOR_STATIC void G_MovePlayers(void)
{ {
int32_t i = headspritestat[STAT_PLAYER]; int32_t i = headspritestat[STAT_PLAYER];
int32_t otherx;
while (i >= 0) while (i >= 0)
{ {
@ -1083,6 +1087,34 @@ ACTOR_STATIC void G_MovePlayers(void)
} }
else else
{ {
int32_t otherx;
#ifdef YAX_ENABLE
// TROR water submerge/emerge
const int32_t psect=s->sectnum, slotag=sector[psect].lotag;
if (slotag==ST_1_ABOVE_WATER || slotag==ST_2_UNDERWATER)
{
int32_t othersect = yax_getneighborsect(
s->x, s->y, psect, slotag==ST_1_ABOVE_WATER ? YAX_FLOOR : YAX_CEILING);
// If submerging, the lower sector MUST have lotag 2.
if (othersect >= 0 && (slotag==ST_2_UNDERWATER || sector[othersect].lotag==ST_2_UNDERWATER))
{
int32_t k = 0;
// Compare with G_MoveTransports().
p->on_warping_sector = 1;
if (slotag==ST_1_ABOVE_WATER)
k = P_Submerge(i, s->yvel, p, psect, othersect);
else
k = P_Emerge(i, s->yvel, p, psect, othersect);
if (k == 1)
P_FinishWaterChange(i, p, slotag, -1, othersect);
}
}
#endif
if (g_netServer || ud.multimode > 1) if (g_netServer || ud.multimode > 1)
otherp = P_FindOtherPlayer(s->yvel,&otherx); otherp = P_FindOtherPlayer(s->yvel,&otherx);
else else
@ -3107,18 +3139,108 @@ BOLT:
} }
} }
static int32_t P_Submerge(int32_t j, int32_t p, DukePlayer_t *ps, int32_t sect, int32_t othersect)
{
if (ps->on_ground &&
ps->pos.z >= sector[sect].floorz &&
(TEST_SYNC_KEY(g_player[p].sync->bits, SK_CROUCH) || ps->vel.z > 2048))
// if( onfloorz && sectlotag == 1 && ps->pos.z > (sector[sect].floorz-(6<<8)) )
{
if (screenpeek == p)
{
FX_StopAllSounds();
S_ClearSoundLocks();
}
if (sprite[ps->i].extra > 0)
A_PlaySound(DUKE_UNDERWATER, j);
ps->opos.z = ps->pos.z = sector[othersect].ceilingz;
// ps->vel.x = 4096-(krand()&8192);
// ps->vel.y = 4096-(krand()&8192);
if (TEST_SYNC_KEY(g_player[p].sync->bits, SK_CROUCH))
ps->vel.z += 512;
return 1;
}
return 0;
}
static int32_t P_Emerge(int32_t j, int32_t p, DukePlayer_t *ps, int32_t sect, int32_t othersect)
{
// r1449-:
if (ps->pos.z < (sector[sect].ceilingz+1080) && ps->vel.z == 0)
// r1450+, breaks submergible slime in bobsp2:
// if (onfloorz && sectlotag == 2 && ps->pos.z <= sector[sect].ceilingz /*&& ps->vel.z == 0*/)
{
// if( sprite[j].extra <= 0) break;
if (screenpeek == p)
{
FX_StopAllSounds();
S_ClearSoundLocks();
}
A_PlaySound(DUKE_GASP, j);
ps->opos.z = ps->pos.z = sector[othersect].floorz;
ps->vel.z = 0;
// ps->vel.z += 1024;
ps->jumping_toggle = 1;
ps->jumping_counter = 0;
return 1;
}
return 0;
}
static void P_FinishWaterChange(int32_t j, DukePlayer_t *ps, int32_t sectlotag, int32_t ow, int32_t newsectnum)
{
int32_t l;
vec3_t vect;
ps->bobposx = ps->opos.x = ps->pos.x;
ps->bobposy = ps->opos.y = ps->pos.y;
if (ow < 0 || sprite[ow].owner != ow)
ps->transporter_hold = -2;
ps->cursectnum = newsectnum;
changespritesect(j, newsectnum);
vect.x = ps->pos.x;
vect.y = ps->pos.y;
vect.z = ps->pos.z+PHEIGHT;
setsprite(ps->i, &vect);
P_UpdateScreenPal(ps);
if ((krand()&255) < 32)
A_Spawn(j, WATERSPLASH2);
if (sectlotag == ST_1_ABOVE_WATER)
for (l = 0; l < 9; l++)
{
int32_t q = A_Spawn(ps->i,WATERBUBBLE);
sprite[q].z += krand()&16383;
}
}
ACTOR_STATIC void G_MoveTransports(void) ACTOR_STATIC void G_MoveTransports(void)
{ {
int32_t warpspriteto; int32_t i = headspritestat[STAT_TRANSPORT], j, k;
int32_t i = headspritestat[STAT_TRANSPORT], j, k, l, sect, sectlotag, nexti, nextj;
int32_t ll,onfloorz,q;
while (i >= 0) while (i >= 0)
{ {
sect = SECT; const int32_t sect = SECT;
sectlotag = sector[sect].lotag; const int32_t sectlotag = sector[sect].lotag;
nexti = nextspritestat[i]; const int32_t nexti = nextspritestat[i];
int32_t onfloorz;
if (OW == i) if (OW == i)
{ {
@ -3126,14 +3248,14 @@ ACTOR_STATIC void G_MoveTransports(void)
continue; continue;
} }
onfloorz = T5; onfloorz = T5; // ONFLOORZ
if (T1 > 0) T1--; if (T1 > 0) T1--;
j = headspritesect[sect]; j = headspritesect[sect];
while (j >= 0) while (j >= 0)
{ {
nextj = nextspritesect[j]; const int32_t nextj = nextspritesect[j];
switch (sprite[j].statnum) switch (sprite[j].statnum)
{ {
@ -3212,82 +3334,20 @@ ACTOR_STATIC void G_MoveTransports(void)
} }
k = 0; k = 0;
if (onfloorz)
if (onfloorz && sectlotag == 1 && ps->on_ground &&
ps->pos.z >= sector[sect].floorz &&
(TEST_SYNC_KEY(g_player[p].sync->bits, SK_CROUCH) || ps->vel.z > 2048))
// if( onfloorz && sectlotag == 1 && ps->pos.z > (sector[sect].floorz-(6<<8)) )
{ {
k = 1; if (sectlotag==ST_1_ABOVE_WATER)
if (screenpeek == p) k = P_Submerge(j, p, ps, sect, sprite[OW].sectnum);
{ else if (sectlotag==ST_2_UNDERWATER)
FX_StopAllSounds(); k = P_Emerge(j, p, ps, sect, sprite[OW].sectnum);
S_ClearSoundLocks();
}
if (sprite[ps->i].extra > 0)
A_PlaySound(DUKE_UNDERWATER,j);
ps->opos.z = ps->pos.z =
sector[sprite[OW].sectnum].ceilingz;
/*
ps->vel.x = 4096-(krand()&8192);
ps->vel.y = 4096-(krand()&8192);
*/
if (TEST_SYNC_KEY(g_player[p].sync->bits, SK_CROUCH))
ps->vel.z += 512;
}
// r1449-:
if (onfloorz && sectlotag == 2 && ps->pos.z < (sector[sect].ceilingz+1080) && ps->vel.z == 0)
// r1450+, breaks submergible slime in bobsp2:
// if (onfloorz && sectlotag == 2 && ps->pos.z <= sector[sect].ceilingz /*&& ps->vel.z == 0*/)
{
k = 1;
// if( sprite[j].extra <= 0) break;
if (screenpeek == p)
{
FX_StopAllSounds();
S_ClearSoundLocks();
}
A_PlaySound(DUKE_GASP,j);
ps->opos.z = ps->pos.z =
sector[sprite[OW].sectnum].floorz;
ps->jumping_toggle = 1;
ps->jumping_counter = 0;
ps->vel.z = 0;
// ps->vel.z += 1024;
} }
if (k == 1) if (k == 1)
{ {
vec3_t vect; ps->pos.x += sprite[OW].x-SX;
ps->bobposx = ps->opos.x = ps->pos.x += sprite[OW].x-SX; ps->pos.y += sprite[OW].y-SY;
ps->bobposy = ps->opos.y = ps->pos.y += sprite[OW].y-SY;
if (sprite[OW].owner != OW) P_FinishWaterChange(j, ps, sectlotag, OW, sprite[OW].sectnum);
ps->transporter_hold = -2;
ps->cursectnum = sprite[OW].sectnum;
changespritesect(j,sprite[OW].sectnum);
vect.x = ps->pos.x;
vect.y = ps->pos.y;
vect.z = ps->pos.z+PHEIGHT;
setsprite(ps->i,&vect);
P_UpdateScreenPal(ps);
if ((krand()&255) < 32)
A_Spawn(j,WATERSPLASH2);
if (sectlotag == 1)
for (l = 0; l < 9; l++)
{
q = A_Spawn(ps->i,WATERBUBBLE);
sprite[q].z += krand()&16383;
}
} }
} }
break; break;
@ -3305,16 +3365,17 @@ ACTOR_STATIC void G_MoveTransports(void)
case STAT_MISC: case STAT_MISC:
case STAT_FALLER: case STAT_FALLER:
case STAT_DUMMYPLAYER: case STAT_DUMMYPLAYER:
{
ll = klabs(sprite[j].zvel); int32_t ll = klabs(sprite[j].zvel);
if (totalclock > actor[j].lasttransport) if (totalclock > actor[j].lasttransport)
{ {
warpspriteto = 0; int32_t warpspriteto = 0;
if (ll && sectlotag == 2 && sprite[j].z < (sector[sect].ceilingz+ll))
if (ll && sectlotag == ST_2_UNDERWATER && sprite[j].z < (sector[sect].ceilingz+ll))
warpspriteto = 1; warpspriteto = 1;
if (ll && sectlotag == 1 && sprite[j].z > (sector[sect].floorz-ll)) if (ll && sectlotag == ST_1_ABOVE_WATER && sprite[j].z > (sector[sect].floorz-ll))
warpspriteto = 1; warpspriteto = 1;
if (sectlotag == 0 && (onfloorz || klabs(sprite[j].z-SZ) < 4096)) if (sectlotag == 0 && (onfloorz || klabs(sprite[j].z-SZ) < 4096))
@ -3412,38 +3473,33 @@ ACTOR_STATIC void G_MoveTransports(void)
changespritesect(j,sprite[OW].sectnum); changespritesect(j,sprite[OW].sectnum);
} }
break; break;
case 1:
case ST_1_ABOVE_WATER:
case ST_2_UNDERWATER:
{
int32_t osect = sprite[OW].sectnum;
actor[j].lasttransport = totalclock + (TICSPERFRAME<<2); actor[j].lasttransport = totalclock + (TICSPERFRAME<<2);
sprite[j].x += (sprite[OW].x-SX); sprite[j].x += (sprite[OW].x-SX);
sprite[j].y += (sprite[OW].y-SY); sprite[j].y += (sprite[OW].y-SY);
sprite[j].z = sector[sprite[OW].sectnum].ceilingz; sprite[j].z = sectlotag==ST_1_ABOVE_WATER ?
sector[osect].ceilingz : sector[osect].floorz;
Bmemcpy(&actor[j].bposx, &sprite[j], sizeof(vec3_t)); Bmemcpy(&actor[j].bposx, &sprite[j], sizeof(vec3_t));
changespritesect(j,sprite[OW].sectnum); changespritesect(j, sprite[OW].sectnum);
break;
case 2:
actor[j].lasttransport = totalclock + (TICSPERFRAME<<2);
sprite[j].x += (sprite[OW].x-SX);
sprite[j].y += (sprite[OW].y-SY);
sprite[j].z = sector[sprite[OW].sectnum].floorz;
Bmemcpy(&actor[j].bposx, &sprite[j], sizeof(vec3_t));
changespritesect(j,sprite[OW].sectnum);
break; break;
} }
}
break; break;
} }
} }
break; break;
} }
} // switch (sprite[j].statnum)
JBOLT: JBOLT:
j = nextj; j = nextj;
} }

View file

@ -5409,7 +5409,7 @@ int32_t A_Spawn(int32_t j, int32_t pn)
} }
else OW = i; else OW = i;
T5 = sector[sect].floorz == SZ; T5 = (sector[sect].floorz == SZ); // ONFLOORZ
sp->cstat = 0; sp->cstat = 0;
changespritestat(i, STAT_TRANSPORT); changespritestat(i, STAT_TRANSPORT);
goto SPAWN_END; goto SPAWN_END;

View file

@ -392,7 +392,10 @@ enum {
// sector lotags // sector lotags
enum { enum {
// left: ST 1 and 2 ST_1_ABOVE_WATER = 1,
ST_2_UNDERWATER = 2,
ST_3 = 3,
// ^^^ maybe not complete substitution in code
ST_9_SLIDING_ST_DOOR = 9, ST_9_SLIDING_ST_DOOR = 9,
ST_15_WARP_ELEVATOR = 15, ST_15_WARP_ELEVATOR = 15,
ST_16_PLATFORM_DOWN = 16, ST_16_PLATFORM_DOWN = 16,