Merge branch 'gravityflipping' into 'next'

Gravity flip bugfixes & additions

Closes #378, #661, and #430

See merge request STJr/SRB2!1808
This commit is contained in:
Eidolon 2022-11-12 23:33:07 +00:00
commit 9a88c9ea47
13 changed files with 252 additions and 65 deletions

View file

@ -438,6 +438,7 @@ sectortypes
160 = "Special Stage Time/Spheres Parameters <deprecated>"; 160 = "Special Stage Time/Spheres Parameters <deprecated>";
176 = "Custom Global Gravity <deprecated>"; 176 = "Custom Global Gravity <deprecated>";
1280 = "Speed Pad"; 1280 = "Speed Pad";
1536 = "Flip Gravity on Jump";
4096 = "Star Post Activator"; 4096 = "Star Post Activator";
8192 = "Exit/Special Stage Pit/Return Flag"; 8192 = "Exit/Special Stage Pit/Return Flag";
12288 = "CTF Red Team Base"; 12288 = "CTF Red Team Base";
@ -496,6 +497,7 @@ gen_sectortypes
{ {
0 = "Normal"; 0 = "Normal";
1280 = "Speed Pad"; 1280 = "Speed Pad";
1536 = "Flip Gravity on Jump";
} }
fourth fourth
@ -576,6 +578,7 @@ linedeftypes
title = "Per-Sector Gravity"; title = "Per-Sector Gravity";
prefix = "(1)"; prefix = "(1)";
flags64text = "[6] Flip in reverse gravity"; flags64text = "[6] Flip in reverse gravity";
flags8192text = "[13] Reverse while inside";
} }
5 5
@ -2062,6 +2065,30 @@ linedeftypes
prefix = "(342)"; prefix = "(342)";
} }
343
{
title = "Gravity Check - Continuous";
flags2text = "[1] Check temporary reverse gravity";
flags64text = "[6] Check for reverse gravity";
prefix = "(343)";
}
344
{
title = "Gravity Check - Each Time";
flags2text = "[1] Check temporary reverse gravity";
flags64text = "[6] Check for reverse gravity";
prefix = "(344)";
}
345
{
title = "Gravity Check - Once";
flags2text = "[1] Check temporary reverse gravity";
flags64text = "[6] Check for reverse gravity";
prefix = "(345)";
}
399 399
{ {
title = "Level Load"; title = "Level Load";
@ -2315,6 +2342,7 @@ linedeftypes
title = "Enable/Disable Gravity Flip"; title = "Enable/Disable Gravity Flip";
prefix = "(433)"; prefix = "(433)";
flags8text = "[3] Set delay by backside sector"; flags8text = "[3] Set delay by backside sector";
flags32text = "[5] Invert current gravity";
flags64text = "[6] Return to normal"; flags64text = "[6] Return to normal";
} }

View file

@ -779,6 +779,21 @@ doom
title = "NiGHTS Mare - Once"; title = "NiGHTS Mare - Once";
prefix = "(342)"; prefix = "(342)";
} }
343
{
title = "Gravity Check - Continuous";
prefix = "(343)";
}
344
{
title = "Gravity Check - Each Time";
prefix = "(344)";
}
345
{
title = "Gravity Check - Once";
prefix = "(345)";
}
399 399
{ {
title = "Level Load"; title = "Level Load";
@ -3581,6 +3596,29 @@ udmf
} }
} }
343
{
title = "Gravity Check";
prefix = "(343)";
arg0
{
title = "Trigger type";
type = 11;
enum = "triggertype";
}
arg1
{
title = "Gravity";
type = 11;
enum
{
0 = "Normal gravity";
1 = "Reverse gravity";
2 = "Reverse gravity (no MF2_OBJECTFLIP)";
}
}
}
399 399
{ {
title = "Level Load"; title = "Level Load";
@ -3918,6 +3956,16 @@ udmf
2 = "Remove"; 2 = "Remove";
} }
} }
arg3
{
title = "Override gravity?";
type = 11;
enum
{
0 = "No";
1 = "Yes";
}
}
stringarg0 stringarg0
{ {
title = "Gravity value"; title = "Gravity value";
@ -4157,7 +4205,7 @@ udmf
prefix = "(433)"; prefix = "(433)";
arg0 arg0
{ {
title = "Gravity"; title = "Set gravity";
type = 11; type = 11;
enum enum
{ {
@ -4165,6 +4213,16 @@ udmf
1 = "Normal"; 1 = "Normal";
} }
} }
arg1
{
title = "Invert current gravity";
type = 11;
enum
{
0 = "No";
1 = "Yes";
}
}
} }
434 434

View file

@ -28,6 +28,7 @@ sectortypes
160 = "Special Stage Time/Spheres Parameters <deprecated>"; 160 = "Special Stage Time/Spheres Parameters <deprecated>";
176 = "Custom Global Gravity <deprecated>"; 176 = "Custom Global Gravity <deprecated>";
1280 = "Speed Pad"; 1280 = "Speed Pad";
1536 = "Flip Gravity on Jump";
4096 = "Star Post Activator"; 4096 = "Star Post Activator";
8192 = "Exit/Special Stage Pit/Return Flag"; 8192 = "Exit/Special Stage Pit/Return Flag";
12288 = "CTF Red Team Base"; 12288 = "CTF Red Team Base";
@ -84,6 +85,7 @@ gen_sectortypes
{ {
0 = "Normal"; 0 = "Normal";
1280 = "Speed Pad"; 1280 = "Speed Pad";
1536 = "Flip Gravity on Jump";
} }
fourth fourth

View file

@ -1301,6 +1301,17 @@ static int lib_pInQuicksand(lua_State *L)
return 1; return 1;
} }
static int lib_pInJumpFlipSector(lua_State *L)
{
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
//HUDSAFE
INLEVEL
if (!mo)
return LUA_ErrInvalid(L, "mobj_t");
lua_pushboolean(L, P_InJumpFlipSector(mo));
return 1;
}
static int lib_pSetObjectMomZ(lua_State *L) static int lib_pSetObjectMomZ(lua_State *L)
{ {
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
@ -4044,6 +4055,7 @@ static luaL_Reg lib[] = {
{"P_IsObjectOnGround",lib_pIsObjectOnGround}, {"P_IsObjectOnGround",lib_pIsObjectOnGround},
{"P_InSpaceSector",lib_pInSpaceSector}, {"P_InSpaceSector",lib_pInSpaceSector},
{"P_InQuicksand",lib_pInQuicksand}, {"P_InQuicksand",lib_pInQuicksand},
{"P_InJumpFlipSector",lib_pInJumpFlipSector},
{"P_SetObjectMomZ",lib_pSetObjectMomZ}, {"P_SetObjectMomZ",lib_pSetObjectMomZ},
{"P_PlayJingle",lib_pPlayJingle}, {"P_PlayJingle",lib_pPlayJingle},
{"P_PlayJingleMusic",lib_pPlayJingleMusic}, {"P_PlayJingleMusic",lib_pPlayJingleMusic},

View file

@ -3883,7 +3883,10 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings)
P_SetObjectMomZ(mo, ns, true); P_SetObjectMomZ(mo, ns, true);
} }
if (player->mo->eflags & MFE_VERTICALFLIP) if (player->mo->eflags & MFE_VERTICALFLIP)
{
mo->momz *= -1; mo->momz *= -1;
mo->flags2 |= MF2_OBJECTFLIP;
}
} }
player->losstime += 10*TICRATE; player->losstime += 10*TICRATE;
@ -4107,6 +4110,8 @@ void P_PlayerWeaponPanelOrAmmoBurst(player_t *player)
P_SetObjectMomZ(mo, 4*FRACUNIT, false); \ P_SetObjectMomZ(mo, 4*FRACUNIT, false); \
if (i & 1) \ if (i & 1) \
P_SetObjectMomZ(mo, 4*FRACUNIT, true); \ P_SetObjectMomZ(mo, 4*FRACUNIT, true); \
if (player->mo->eflags & MFE_VERTICALFLIP) \
mo->flags2 |= MF2_OBJECTFLIP; \
++i; \ ++i; \
} \ } \
else if (player->powers[power] > 0) \ else if (player->powers[power] > 0) \
@ -4126,6 +4131,8 @@ void P_PlayerWeaponPanelOrAmmoBurst(player_t *player)
P_SetObjectMomZ(mo, 3*FRACUNIT, false); \ P_SetObjectMomZ(mo, 3*FRACUNIT, false); \
if (i & 1) \ if (i & 1) \
P_SetObjectMomZ(mo, 3*FRACUNIT, true); \ P_SetObjectMomZ(mo, 3*FRACUNIT, true); \
if (player->mo->eflags & MFE_VERTICALFLIP) \
mo->flags2 |= MF2_OBJECTFLIP; \
player->powers[power] = 0; \ player->powers[power] = 0; \
++i; \ ++i; \
} }
@ -4266,7 +4273,10 @@ void P_PlayerEmeraldBurst(player_t *player, boolean toss)
P_SetObjectMomZ(mo, 3*FRACUNIT, false); P_SetObjectMomZ(mo, 3*FRACUNIT, false);
if (player->mo->eflags & MFE_VERTICALFLIP) if (player->mo->eflags & MFE_VERTICALFLIP)
{
mo->momz = -mo->momz; mo->momz = -mo->momz;
mo->flags2 |= MF2_OBJECTFLIP;
}
if (toss) if (toss)
player->tossdelay = 2*TICRATE; player->tossdelay = 2*TICRATE;
@ -4295,7 +4305,10 @@ void P_PlayerFlagBurst(player_t *player, boolean toss)
flag = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, type); flag = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, type);
if (player->mo->eflags & MFE_VERTICALFLIP) if (player->mo->eflags & MFE_VERTICALFLIP)
{
flag->z += player->mo->height - flag->height; flag->z += player->mo->height - flag->height;
flag->flags2 |= MF2_OBJECTFLIP;
}
if (toss) if (toss)
P_InstaThrust(flag, player->mo->angle, FixedMul(6*FRACUNIT, player->mo->scale)); P_InstaThrust(flag, player->mo->angle, FixedMul(6*FRACUNIT, player->mo->scale));

View file

@ -151,6 +151,7 @@ boolean P_IsObjectInGoop(mobj_t *mo);
boolean P_IsObjectOnGround(mobj_t *mo); boolean P_IsObjectOnGround(mobj_t *mo);
boolean P_InSpaceSector(mobj_t *mo); boolean P_InSpaceSector(mobj_t *mo);
boolean P_InQuicksand(mobj_t *mo); boolean P_InQuicksand(mobj_t *mo);
boolean P_InJumpFlipSector(mobj_t *mo);
boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff); boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff);
void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative); void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative);

View file

@ -2153,7 +2153,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
if (rover->fofflags & FOF_QUICKSAND) if (rover->fofflags & FOF_QUICKSAND)
{ {
if (thing->z < topheight && bottomheight < thingtop) if (!(thing->eflags & MFE_VERTICALFLIP) && thing->z < topheight && bottomheight < thingtop)
{ {
if (tmfloorz < thing->z) { if (tmfloorz < thing->z) {
tmfloorz = thing->z; tmfloorz = thing->z;
@ -2161,6 +2161,14 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y)
tmfloorslope = NULL; tmfloorslope = NULL;
} }
} }
else if (thing->eflags & MFE_VERTICALFLIP && thing->z < topheight && bottomheight < thingtop)
{
if (tmceilingz > thingtop) {
tmceilingz = thingtop;
tmceilingrover = rover;
tmceilingslope = NULL;
}
}
// Quicksand blocks never change heights otherwise. // Quicksand blocks never change heights otherwise.
continue; continue;
} }
@ -5119,8 +5127,8 @@ fixed_t P_CeilingzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height)
{ {
if (thingtop > bottomheight && topheight > z) if (thingtop > bottomheight && topheight > z)
{ {
if (ceilingz > z) if (ceilingz > thingtop)
ceilingz = z; ceilingz = thingtop;
} }
continue; continue;
} }

View file

@ -1432,7 +1432,7 @@ static void P_PlayerFlip(mobj_t *mo)
fixed_t P_GetMobjGravity(mobj_t *mo) fixed_t P_GetMobjGravity(mobj_t *mo)
{ {
fixed_t gravityadd = 0; fixed_t gravityadd = 0;
boolean no3dfloorgrav = true; // Custom gravity sector_t *gravsector = NULL; // Custom gravity
boolean goopgravity = false; boolean goopgravity = false;
boolean wasflip; boolean wasflip;
@ -1440,14 +1440,11 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
I_Assert(!P_MobjWasRemoved(mo)); I_Assert(!P_MobjWasRemoved(mo));
wasflip = (mo->eflags & MFE_VERTICALFLIP) != 0; wasflip = (mo->eflags & MFE_VERTICALFLIP) != 0;
mo->eflags &= ~MFE_VERTICALFLIP;
if (mo->type != MT_SPINFIRE)
mo->eflags &= ~MFE_VERTICALFLIP;
if (mo->subsector->sector->ffloors) // Check for 3D floor gravity too. if (mo->subsector->sector->ffloors) // Check for 3D floor gravity too.
{ {
ffloor_t *rover; ffloor_t *rover;
fixed_t gravfactor;
for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next) for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next)
{ {
@ -1457,27 +1454,24 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
if ((rover->fofflags & (FOF_SWIMMABLE|FOF_GOOWATER)) == (FOF_SWIMMABLE|FOF_GOOWATER)) if ((rover->fofflags & (FOF_SWIMMABLE|FOF_GOOWATER)) == (FOF_SWIMMABLE|FOF_GOOWATER))
goopgravity = true; goopgravity = true;
gravfactor = P_GetSectorGravityFactor(rover->master->frontsector); if (P_GetSectorGravityFactor(rover->master->frontsector) == FRACUNIT)
if (gravfactor == FRACUNIT)
continue; continue;
gravityadd = -FixedMul(gravity, gravfactor); gravsector = rover->master->frontsector;
if ((rover->master->frontsector->flags & MSF_GRAVITYFLIP) && gravityadd > 0)
mo->eflags |= MFE_VERTICALFLIP;
no3dfloorgrav = false;
break; break;
} }
} }
if (no3dfloorgrav) if (!gravsector) // If there is no 3D floor gravity, check sector's gravity
{ gravsector = mo->subsector->sector;
gravityadd = -FixedMul(gravity, P_GetSectorGravityFactor(mo->subsector->sector));
if ((mo->subsector->sector->flags & MSF_GRAVITYFLIP) && gravityadd > 0) gravityadd = -FixedMul(gravity, P_GetSectorGravityFactor(gravsector));
mo->eflags |= MFE_VERTICALFLIP;
if ((gravsector->flags & MSF_GRAVITYFLIP) && gravityadd > 0)
{
if (gravsector->specialflags & SSF_GRAVITYOVERRIDE)
mo->flags2 &= ~MF2_OBJECTFLIP;
mo->eflags |= MFE_VERTICALFLIP;
} }
// Less gravity underwater. // Less gravity underwater.
@ -1515,36 +1509,6 @@ fixed_t P_GetMobjGravity(mobj_t *mo)
{ {
switch (mo->type) switch (mo->type)
{ {
case MT_FLINGRING:
case MT_FLINGCOIN:
case MT_FLINGBLUESPHERE:
case MT_FLINGNIGHTSCHIP:
case MT_FLINGEMERALD:
case MT_BOUNCERING:
case MT_RAILRING:
case MT_INFINITYRING:
case MT_AUTOMATICRING:
case MT_EXPLOSIONRING:
case MT_SCATTERRING:
case MT_GRENADERING:
case MT_BOUNCEPICKUP:
case MT_RAILPICKUP:
case MT_AUTOPICKUP:
case MT_EXPLODEPICKUP:
case MT_SCATTERPICKUP:
case MT_GRENADEPICKUP:
case MT_REDFLAG:
case MT_BLUEFLAG:
if (mo->target)
{
// Flung items copy the gravity of their tosser.
if ((mo->target->eflags & MFE_VERTICALFLIP) && !(mo->eflags & MFE_VERTICALFLIP))
{
gravityadd = -gravityadd;
mo->eflags |= MFE_VERTICALFLIP;
}
}
break;
case MT_WATERDROP: case MT_WATERDROP:
case MT_CYBRAKDEMON: case MT_CYBRAKDEMON:
gravityadd >>= 1; gravityadd >>= 1;
@ -2193,15 +2157,20 @@ void P_AdjustMobjFloorZ_FFloors(mobj_t *mo, sector_t *sector, UINT8 motype)
case 2: // scenery does things differently for some reason case 2: // scenery does things differently for some reason
if (mo->z < topheight && bottomheight < thingtop) if (mo->z < topheight && bottomheight < thingtop)
{ {
mo->floorz = mo->z; if (!(mo->eflags & MFE_VERTICALFLIP))
mo->floorz = mo->z;
else if (mo->eflags & MFE_VERTICALFLIP)
mo->ceilingz = thingtop;
continue; continue;
} }
break; break;
default: default:
if (mo->z < topheight && bottomheight < thingtop) if (mo->z < topheight && bottomheight < thingtop)
{ {
if (mo->floorz < mo->z) if (!(mo->eflags & MFE_VERTICALFLIP) && mo->floorz < mo->z)
mo->floorz = mo->z; mo->floorz = mo->z;
else if (mo->eflags & MFE_VERTICALFLIP && mo->ceilingz > thingtop)
mo->ceilingz = thingtop;
} }
continue; // This is so you can jump/spring up through quicksand from below. continue; // This is so you can jump/spring up through quicksand from below.
} }

View file

@ -1727,6 +1727,10 @@ static void ParseTextmapSectorParameter(UINT32 i, const char *param, const char
sectors[i].specialflags |= SSF_FINISHLINE; sectors[i].specialflags |= SSF_FINISHLINE;
else if (fastcmp(param, "ropehang") && fastcmp("true", val)) else if (fastcmp(param, "ropehang") && fastcmp("true", val))
sectors[i].specialflags |= SSF_ROPEHANG; sectors[i].specialflags |= SSF_ROPEHANG;
else if (fastcmp(param, "jumpflip") && fastcmp("true", val))
sectors[i].specialflags |= SSF_JUMPFLIP;
else if (fastcmp(param, "gravityoverride") && fastcmp("true", val))
sectors[i].specialflags |= SSF_GRAVITYOVERRIDE;
else if (fastcmp(param, "friction")) else if (fastcmp(param, "friction"))
sectors[i].friction = FLOAT_TO_FIXED(atof(val)); sectors[i].friction = FLOAT_TO_FIXED(atof(val));
else if (fastcmp(param, "gravity")) else if (fastcmp(param, "gravity"))
@ -2580,6 +2584,10 @@ static void P_WriteTextmap(void)
fprintf(f, "finishline = true;\n"); fprintf(f, "finishline = true;\n");
if (wsectors[i].specialflags & SSF_ROPEHANG) if (wsectors[i].specialflags & SSF_ROPEHANG)
fprintf(f, "ropehang = true;\n"); fprintf(f, "ropehang = true;\n");
if (wsectors[i].specialflags & SSF_JUMPFLIP)
fprintf(f, "jumpflip = true;\n");
if (wsectors[i].specialflags & SSF_GRAVITYOVERRIDE)
fprintf(f, "gravityoverride = true;\n");
if (wsectors[i].friction != ORIG_FRICTION) if (wsectors[i].friction != ORIG_FRICTION)
fprintf(f, "friction = %f;\n", FIXED_TO_FLOAT(wsectors[i].friction)); fprintf(f, "friction = %f;\n", FIXED_TO_FLOAT(wsectors[i].friction));
if (wsectors[i].gravity != FRACUNIT) if (wsectors[i].gravity != FRACUNIT)
@ -4964,6 +4972,21 @@ static void P_ConvertBinaryLinedefTypes(void)
lines[i].args[2] = TMC_EQUAL; lines[i].args[2] = TMC_EQUAL;
lines[i].special = 340; lines[i].special = 340;
break; break;
case 343: //Gravity check - continuous
case 344: //Gravity check - each time
case 345: //Gravity check - once
if (lines[i].special == 345)
lines[i].args[0] = TMT_ONCE;
else if (lines[i].special == 344)
lines[i].args[0] = (lines[i].flags & ML_BOUNCY) ? TMT_EACHTIMEENTERANDEXIT : TMT_EACHTIMEENTER;
else
lines[i].args[0] = TMT_CONTINUOUS;
if (lines[i].flags & ML_BLOCKMONSTERS)
lines[i].args[1] = TMG_TEMPREVERSE;
else if (lines[i].flags & ML_NOCLIMB)
lines[i].args[1] = TMG_REVERSE;
lines[i].special = 343;
break;
case 400: //Set tagged sector's floor height/texture case 400: //Set tagged sector's floor height/texture
case 401: //Set tagged sector's ceiling height/texture case 401: //Set tagged sector's ceiling height/texture
lines[i].args[0] = tag; lines[i].args[0] = tag;
@ -5243,6 +5266,7 @@ static void P_ConvertBinaryLinedefTypes(void)
break; break;
case 433: //Enable/disable gravity flip case 433: //Enable/disable gravity flip
lines[i].args[0] = !!(lines[i].flags & ML_NOCLIMB); lines[i].args[0] = !!(lines[i].flags & ML_NOCLIMB);
lines[i].args[1] = !!(lines[i].flags & ML_SKEWTD);
break; break;
case 434: //Award power-up case 434: //Award power-up
if (sides[lines[i].sidenum[0]].text) if (sides[lines[i].sidenum[0]].text)
@ -6015,6 +6039,9 @@ static void P_ConvertBinarySectorTypes(void)
case 5: //Speed pad case 5: //Speed pad
sectors[i].specialflags |= SSF_SPEEDPAD; sectors[i].specialflags |= SSF_SPEEDPAD;
break; break;
case 6: //Gravity flip on jump (think VVVVVV)
sectors[i].specialflags |= SSF_JUMPFLIP;
break;
default: default:
break; break;
} }

View file

@ -1863,6 +1863,12 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
if (!P_CheckPlayerMare(triggerline)) if (!P_CheckPlayerMare(triggerline))
return false; return false;
break; break;
case 343: // gravity check
if (triggerline->args[1] == TMG_TEMPREVERSE && (!(actor->flags2 & MF2_OBJECTFLIP) != !(actor->player->powers[pw_gravityboots])))
return false;
if ((triggerline->args[1] == TMG_NORMAL) != !(actor->eflags & MFE_VERTICALFLIP))
return false;
break;
default: default:
break; break;
} }
@ -1900,7 +1906,8 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller
|| specialtype == 319 // Unlockable || specialtype == 319 // Unlockable
|| specialtype == 331 // Player skin || specialtype == 331 // Player skin
|| specialtype == 334 // Object dye || specialtype == 334 // Object dye
|| specialtype == 337) // Emerald check || specialtype == 337 // Emerald check
|| specialtype == 343) // Gravity check
&& triggerline->args[0] == TMT_ONCE) && triggerline->args[0] == TMT_ONCE)
triggerline->special = 0; triggerline->special = 0;
} }
@ -1950,7 +1957,8 @@ void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller)
|| lines[masterline].special == 319 // Unlockable trigger || lines[masterline].special == 319 // Unlockable trigger
|| lines[masterline].special == 331 // Player skin || lines[masterline].special == 331 // Player skin
|| lines[masterline].special == 334 // Object dye || lines[masterline].special == 334 // Object dye
|| lines[masterline].special == 337) // Emerald check || lines[masterline].special == 337 // Emerald check
|| lines[masterline].special == 343) // Gravity check
&& lines[masterline].args[0] > TMT_EACHTIMEMASK) && lines[masterline].args[0] > TMT_EACHTIMEMASK)
continue; continue;
@ -2774,7 +2782,9 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
break; break;
case 433: // Flip/flop gravity. Works on pushables, too! case 433: // Flip/flop gravity. Works on pushables, too!
if (line->args[0]) if (line->args[1])
mo->flags2 ^= MF2_OBJECTFLIP;
else if (line->args[0])
mo->flags2 &= ~MF2_OBJECTFLIP; mo->flags2 &= ~MF2_OBJECTFLIP;
else else
mo->flags2 |= MF2_OBJECTFLIP; mo->flags2 |= MF2_OBJECTFLIP;
@ -3827,6 +3837,9 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
sectors[secnum].flags |= MSF_GRAVITYFLIP; sectors[secnum].flags |= MSF_GRAVITYFLIP;
else if (line->args[2] == TMF_REMOVE) else if (line->args[2] == TMF_REMOVE)
sectors[secnum].flags &= ~MSF_GRAVITYFLIP; sectors[secnum].flags &= ~MSF_GRAVITYFLIP;
if (line->args[3])
sectors[secnum].specialflags |= SSF_GRAVITYOVERRIDE;
} }
} }
break; break;
@ -6307,6 +6320,9 @@ void P_SpawnSpecials(boolean fromnetsave)
else else
sectors[s].flags &= ~MSF_GRAVITYFLIP; sectors[s].flags &= ~MSF_GRAVITYFLIP;
if (lines[i].flags & ML_EFFECT6)
sectors[s].specialflags |= SSF_GRAVITYOVERRIDE;
CheckForReverseGravity |= (sectors[s].flags & MSF_GRAVITYFLIP); CheckForReverseGravity |= (sectors[s].flags & MSF_GRAVITYFLIP);
} }
break; break;
@ -6924,6 +6940,7 @@ void P_SpawnSpecials(boolean fromnetsave)
case 331: // Player skin case 331: // Player skin
case 334: // Object dye case 334: // Object dye
case 337: // Emerald check case 337: // Emerald check
case 343: // Gravity check
if (lines[i].args[0] > TMT_EACHTIMEMASK) if (lines[i].args[0] > TMT_EACHTIMEMASK)
P_AddEachTimeThinker(&lines[i], lines[i].args[0] == TMT_EACHTIMEENTERANDEXIT); P_AddEachTimeThinker(&lines[i], lines[i].args[0] == TMT_EACHTIMEENTERANDEXIT);
break; break;

View file

@ -254,6 +254,13 @@ typedef enum
TMC_GTE = 2, TMC_GTE = 2,
} textmapcomparison_t; } textmapcomparison_t;
typedef enum
{
TMG_NORMAL = 0,
TMG_REVERSE = 1,
TMG_TEMPREVERSE = 2,
} textmapgravity_t;
typedef enum typedef enum
{ {
TMNP_FASTEST = 0, TMNP_FASTEST = 0,

View file

@ -2494,6 +2494,41 @@ boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand
return false; // No sand here, Captain! return false; // No sand here, Captain!
} }
boolean P_InJumpFlipSector(mobj_t *mo) // Returns true if you are in a jumpflip sector
{
sector_t *sector = mo->subsector->sector;
fixed_t topheight, bottomheight;
if (sector->specialflags & SSF_JUMPFLIP)
return true;
if (sector->ffloors)
{
ffloor_t *rover;
for (rover = sector->ffloors; rover; rover = rover->next)
{
if (!(rover->fofflags & FOF_EXISTS))
continue;
if (!(rover->master->frontsector->specialflags & SSF_JUMPFLIP))
continue;
topheight = P_GetFFloorTopZAt (rover, mo->x, mo->y);
bottomheight = P_GetFFloorBottomZAt(rover, mo->x, mo->y);
if (mo->z + (mo->height/2) > topheight)
continue;
if (mo->z + (mo->height/2) < bottomheight)
continue;
return true;
}
}
return false; // No gravity jumping here, Captain Viridian!
}
static boolean P_PlayerCanBust(player_t *player, ffloor_t *rover) static boolean P_PlayerCanBust(player_t *player, ffloor_t *rover)
{ {
if (!(rover->fofflags & FOF_EXISTS)) if (!(rover->fofflags & FOF_EXISTS))
@ -2789,12 +2824,13 @@ static void P_CheckQuicksand(player_t *player)
fixed_t sinkspeed; fixed_t sinkspeed;
fixed_t topheight, bottomheight; fixed_t topheight, bottomheight;
if (!(player->mo->subsector->sector->ffloors && player->mo->momz <= 0)) if (!(player->mo->subsector->sector->ffloors && P_MobjFlip(player->mo)*player->mo->momz <= 0))
return; return;
for (rover = player->mo->subsector->sector->ffloors; rover; rover = rover->next) for (rover = player->mo->subsector->sector->ffloors; rover; rover = rover->next)
{ {
if (!(rover->fofflags & FOF_EXISTS)) continue; if (!(rover->fofflags & FOF_EXISTS))
continue;
if (!(rover->fofflags & FOF_QUICKSAND)) if (!(rover->fofflags & FOF_QUICKSAND))
continue; continue;
@ -4459,6 +4495,12 @@ void P_DoJump(player_t *player, boolean soundandstate)
if (player->charflags & SF_NOJUMPDAMAGE) if (player->charflags & SF_NOJUMPDAMAGE)
player->pflags &= ~PF_SPINNING; player->pflags &= ~PF_SPINNING;
if (P_InJumpFlipSector(player->mo)) // Flip gravity on jump?
{
player->mo->flags2 ^= MF2_OBJECTFLIP;
S_StartSound(player->mo, sfx_s3k73); // Play gravity flip sound
}
if (soundandstate) if (soundandstate)
{ {
if (!player->spectator) if (!player->spectator)
@ -7642,11 +7684,9 @@ void P_ElementalFire(player_t *player, boolean cropcircle)
else else
ground = player->mo->floorz; ground = player->mo->floorz;
if (cropcircle)
ground += P_MobjFlip(player->mo);
if (cropcircle) if (cropcircle)
{ {
ground += P_MobjFlip(player->mo);
#define numangles 8 #define numangles 8
#define limitangle (180/numangles) #define limitangle (180/numangles)
travelangle = player->mo->angle + P_RandomRange(-limitangle, limitangle)*ANG1; travelangle = player->mo->angle + P_RandomRange(-limitangle, limitangle)*ANG1;
@ -7659,7 +7699,8 @@ void P_ElementalFire(player_t *player, boolean cropcircle)
flame->fuse = TICRATE*7; // takes about an extra second to hit the ground flame->fuse = TICRATE*7; // takes about an extra second to hit the ground
flame->destscale = player->mo->scale; flame->destscale = player->mo->scale;
P_SetScale(flame, player->mo->scale); P_SetScale(flame, player->mo->scale);
flame->flags2 = (flame->flags2 & ~MF2_OBJECTFLIP)|(player->mo->flags2 & MF2_OBJECTFLIP); if (!(player->mo->flags2 & MF2_OBJECTFLIP) != !(player->powers[pw_gravityboots])) // take gravity boots into account
flame->flags2 |= MF2_OBJECTFLIP;
flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP);
P_InstaThrust(flame, flame->angle, FixedMul(3*FRACUNIT, flame->scale)); P_InstaThrust(flame, flame->angle, FixedMul(3*FRACUNIT, flame->scale));
P_SetObjectMomZ(flame, 3*FRACUNIT, false); P_SetObjectMomZ(flame, 3*FRACUNIT, false);
@ -7694,6 +7735,8 @@ void P_ElementalFire(player_t *player, boolean cropcircle)
flame->fuse = TICRATE*6; flame->fuse = TICRATE*6;
flame->destscale = player->mo->scale; flame->destscale = player->mo->scale;
P_SetScale(flame, player->mo->scale); P_SetScale(flame, player->mo->scale);
if (!(player->mo->flags2 & MF2_OBJECTFLIP) != !(player->powers[pw_gravityboots])) // take gravity boots into account
flame->flags2 |= MF2_OBJECTFLIP;
flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP); flame->eflags = (flame->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP);
if (!(gametyperules & GTR_FRIENDLY)) if (!(gametyperules & GTR_FRIENDLY))
{ {

View file

@ -355,6 +355,8 @@ typedef enum
SSF_ZOOMTUBEEND = 1<<16, SSF_ZOOMTUBEEND = 1<<16,
SSF_FINISHLINE = 1<<17, SSF_FINISHLINE = 1<<17,
SSF_ROPEHANG = 1<<18, SSF_ROPEHANG = 1<<18,
SSF_JUMPFLIP = 1<<19,
SSF_GRAVITYOVERRIDE = 1<<20, // combine with MSF_GRAVITYFLIP
} sectorspecialflags_t; } sectorspecialflags_t;
typedef enum typedef enum