diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg index a2f56880be3c4647d3478b2b71625e923bdc374d..6bae1494f5f6ae140adc33b0a072cc70f754a25a 100644 --- a/extras/conf/SRB2-22.cfg +++ b/extras/conf/SRB2-22.cfg @@ -438,6 +438,7 @@ sectortypes 160 = "Special Stage Time/Spheres Parameters <deprecated>"; 176 = "Custom Global Gravity <deprecated>"; 1280 = "Speed Pad"; + 1536 = "Flip Gravity on Jump"; 4096 = "Star Post Activator"; 8192 = "Exit/Special Stage Pit/Return Flag"; 12288 = "CTF Red Team Base"; @@ -496,6 +497,7 @@ gen_sectortypes { 0 = "Normal"; 1280 = "Speed Pad"; + 1536 = "Flip Gravity on Jump"; } fourth @@ -576,6 +578,7 @@ linedeftypes title = "Per-Sector Gravity"; prefix = "(1)"; flags64text = "[6] Flip in reverse gravity"; + flags8192text = "[13] Reverse while inside"; } 5 @@ -2062,6 +2065,30 @@ linedeftypes 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 { title = "Level Load"; @@ -2315,6 +2342,7 @@ linedeftypes title = "Enable/Disable Gravity Flip"; prefix = "(433)"; flags8text = "[3] Set delay by backside sector"; + flags32text = "[5] Invert current gravity"; flags64text = "[6] Return to normal"; } diff --git a/extras/conf/udb/Includes/SRB222_linedefs.cfg b/extras/conf/udb/Includes/SRB222_linedefs.cfg index 1dec9ab88116330f9a1bc77b751d3f90dea8abbc..99c3056590dbc65135fc3c75c33b68267838674b 100644 --- a/extras/conf/udb/Includes/SRB222_linedefs.cfg +++ b/extras/conf/udb/Includes/SRB222_linedefs.cfg @@ -779,6 +779,21 @@ doom title = "NiGHTS Mare - Once"; 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 { 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 { title = "Level Load"; @@ -3918,6 +3956,16 @@ udmf 2 = "Remove"; } } + arg3 + { + title = "Override gravity?"; + type = 11; + enum + { + 0 = "No"; + 1 = "Yes"; + } + } stringarg0 { title = "Gravity value"; @@ -4157,7 +4205,7 @@ udmf prefix = "(433)"; arg0 { - title = "Gravity"; + title = "Set gravity"; type = 11; enum { @@ -4165,6 +4213,16 @@ udmf 1 = "Normal"; } } + arg1 + { + title = "Invert current gravity"; + type = 11; + enum + { + 0 = "No"; + 1 = "Yes"; + } + } } 434 diff --git a/extras/conf/udb/Includes/SRB222_sectors.cfg b/extras/conf/udb/Includes/SRB222_sectors.cfg index f9df297e76d06a3ed122156379066d3b38136c84..5b3ad4155c176b229eee741b9a1744121b68d4ae 100644 --- a/extras/conf/udb/Includes/SRB222_sectors.cfg +++ b/extras/conf/udb/Includes/SRB222_sectors.cfg @@ -28,6 +28,7 @@ sectortypes 160 = "Special Stage Time/Spheres Parameters <deprecated>"; 176 = "Custom Global Gravity <deprecated>"; 1280 = "Speed Pad"; + 1536 = "Flip Gravity on Jump"; 4096 = "Star Post Activator"; 8192 = "Exit/Special Stage Pit/Return Flag"; 12288 = "CTF Red Team Base"; @@ -84,6 +85,7 @@ gen_sectortypes { 0 = "Normal"; 1280 = "Speed Pad"; + 1536 = "Flip Gravity on Jump"; } fourth @@ -102,4 +104,4 @@ gen_sectortypes 45056 = "Rope Hang"; 49152 = "Intangible to the Camera"; } -} \ No newline at end of file +} diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 5af9669ca3ab14672da929a900fcb6c448386fec..29adb478abfffd58a5d564769382c6290c6acefd 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1301,6 +1301,17 @@ static int lib_pInQuicksand(lua_State *L) 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) { mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); @@ -4044,6 +4055,7 @@ static luaL_Reg lib[] = { {"P_IsObjectOnGround",lib_pIsObjectOnGround}, {"P_InSpaceSector",lib_pInSpaceSector}, {"P_InQuicksand",lib_pInQuicksand}, + {"P_InJumpFlipSector",lib_pInJumpFlipSector}, {"P_SetObjectMomZ",lib_pSetObjectMomZ}, {"P_PlayJingle",lib_pPlayJingle}, {"P_PlayJingleMusic",lib_pPlayJingleMusic}, diff --git a/src/p_inter.c b/src/p_inter.c index c230ce178ad5b388ca123cde1352e8771b80f8c5..dd3e0f9c27fc41657841c22e24d20391d9e94b74 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3883,7 +3883,10 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) P_SetObjectMomZ(mo, ns, true); } if (player->mo->eflags & MFE_VERTICALFLIP) + { mo->momz *= -1; + mo->flags2 |= MF2_OBJECTFLIP; + } } player->losstime += 10*TICRATE; @@ -4107,6 +4110,8 @@ void P_PlayerWeaponPanelOrAmmoBurst(player_t *player) P_SetObjectMomZ(mo, 4*FRACUNIT, false); \ if (i & 1) \ P_SetObjectMomZ(mo, 4*FRACUNIT, true); \ + if (player->mo->eflags & MFE_VERTICALFLIP) \ + mo->flags2 |= MF2_OBJECTFLIP; \ ++i; \ } \ else if (player->powers[power] > 0) \ @@ -4126,6 +4131,8 @@ void P_PlayerWeaponPanelOrAmmoBurst(player_t *player) P_SetObjectMomZ(mo, 3*FRACUNIT, false); \ if (i & 1) \ P_SetObjectMomZ(mo, 3*FRACUNIT, true); \ + if (player->mo->eflags & MFE_VERTICALFLIP) \ + mo->flags2 |= MF2_OBJECTFLIP; \ player->powers[power] = 0; \ ++i; \ } @@ -4266,7 +4273,10 @@ void P_PlayerEmeraldBurst(player_t *player, boolean toss) P_SetObjectMomZ(mo, 3*FRACUNIT, false); if (player->mo->eflags & MFE_VERTICALFLIP) + { mo->momz = -mo->momz; + mo->flags2 |= MF2_OBJECTFLIP; + } if (toss) 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); if (player->mo->eflags & MFE_VERTICALFLIP) + { flag->z += player->mo->height - flag->height; + flag->flags2 |= MF2_OBJECTFLIP; + } if (toss) P_InstaThrust(flag, player->mo->angle, FixedMul(6*FRACUNIT, player->mo->scale)); diff --git a/src/p_local.h b/src/p_local.h index 49af03f3666a29ec703beb7dc4a0ae8fa673b297..2b3020997da387a624efcf5e5c9d46ded7384930 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -151,6 +151,7 @@ boolean P_IsObjectInGoop(mobj_t *mo); boolean P_IsObjectOnGround(mobj_t *mo); boolean P_InSpaceSector(mobj_t *mo); boolean P_InQuicksand(mobj_t *mo); +boolean P_InJumpFlipSector(mobj_t *mo); boolean P_PlayerHitFloor(player_t *player, boolean dorollstuff); void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative); diff --git a/src/p_map.c b/src/p_map.c index 117d49ea491e05310d4c358f7708d8d2b9473d4c..275403e2e125ec1d04f4ccbdec1b0e4880d59728 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2153,7 +2153,7 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) 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) { tmfloorz = thing->z; @@ -2161,6 +2161,14 @@ boolean P_CheckPosition(mobj_t *thing, fixed_t x, fixed_t y) 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. 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 (ceilingz > z) - ceilingz = z; + if (ceilingz > thingtop) + ceilingz = thingtop; } continue; } diff --git a/src/p_mobj.c b/src/p_mobj.c index 965e8e57e5710ea5429fe23704a7693555794978..e658d192c6bb50452433c48653e46dc4d6575656 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1432,7 +1432,7 @@ static void P_PlayerFlip(mobj_t *mo) fixed_t P_GetMobjGravity(mobj_t *mo) { fixed_t gravityadd = 0; - boolean no3dfloorgrav = true; // Custom gravity + sector_t *gravsector = NULL; // Custom gravity boolean goopgravity = false; boolean wasflip; @@ -1440,14 +1440,11 @@ fixed_t P_GetMobjGravity(mobj_t *mo) I_Assert(!P_MobjWasRemoved(mo)); wasflip = (mo->eflags & MFE_VERTICALFLIP) != 0; - - if (mo->type != MT_SPINFIRE) - mo->eflags &= ~MFE_VERTICALFLIP; + mo->eflags &= ~MFE_VERTICALFLIP; if (mo->subsector->sector->ffloors) // Check for 3D floor gravity too. { ffloor_t *rover; - fixed_t gravfactor; 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)) goopgravity = true; - gravfactor = P_GetSectorGravityFactor(rover->master->frontsector); - - if (gravfactor == FRACUNIT) + if (P_GetSectorGravityFactor(rover->master->frontsector) == FRACUNIT) continue; - gravityadd = -FixedMul(gravity, gravfactor); - - if ((rover->master->frontsector->flags & MSF_GRAVITYFLIP) && gravityadd > 0) - mo->eflags |= MFE_VERTICALFLIP; - - no3dfloorgrav = false; + gravsector = rover->master->frontsector; break; } } - if (no3dfloorgrav) - { - gravityadd = -FixedMul(gravity, P_GetSectorGravityFactor(mo->subsector->sector)); + if (!gravsector) // If there is no 3D floor gravity, check sector's gravity + gravsector = mo->subsector->sector; - if ((mo->subsector->sector->flags & MSF_GRAVITYFLIP) && gravityadd > 0) - mo->eflags |= MFE_VERTICALFLIP; + gravityadd = -FixedMul(gravity, P_GetSectorGravityFactor(gravsector)); + + if ((gravsector->flags & MSF_GRAVITYFLIP) && gravityadd > 0) + { + if (gravsector->specialflags & SSF_GRAVITYOVERRIDE) + mo->flags2 &= ~MF2_OBJECTFLIP; + mo->eflags |= MFE_VERTICALFLIP; } // Less gravity underwater. @@ -1515,36 +1509,6 @@ fixed_t P_GetMobjGravity(mobj_t *mo) { 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_CYBRAKDEMON: 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 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; } break; default: if (mo->z < topheight && bottomheight < thingtop) { - if (mo->floorz < mo->z) + if (!(mo->eflags & MFE_VERTICALFLIP) && 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. } diff --git a/src/p_setup.c b/src/p_setup.c index ed8c5c2e9daa8cf3b308c36b9caebd72744c5c5a..deb308da22ea5bd45837f8848baba8e1c9e41d67 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -1727,6 +1727,10 @@ static void ParseTextmapSectorParameter(UINT32 i, const char *param, const char sectors[i].specialflags |= SSF_FINISHLINE; else if (fastcmp(param, "ropehang") && fastcmp("true", val)) 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")) sectors[i].friction = FLOAT_TO_FIXED(atof(val)); else if (fastcmp(param, "gravity")) @@ -2580,6 +2584,10 @@ static void P_WriteTextmap(void) fprintf(f, "finishline = true;\n"); if (wsectors[i].specialflags & SSF_ROPEHANG) 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) fprintf(f, "friction = %f;\n", FIXED_TO_FLOAT(wsectors[i].friction)); if (wsectors[i].gravity != FRACUNIT) @@ -4964,6 +4972,21 @@ static void P_ConvertBinaryLinedefTypes(void) lines[i].args[2] = TMC_EQUAL; lines[i].special = 340; 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 401: //Set tagged sector's ceiling height/texture lines[i].args[0] = tag; @@ -5243,6 +5266,7 @@ static void P_ConvertBinaryLinedefTypes(void) break; case 433: //Enable/disable gravity flip lines[i].args[0] = !!(lines[i].flags & ML_NOCLIMB); + lines[i].args[1] = !!(lines[i].flags & ML_SKEWTD); break; case 434: //Award power-up if (sides[lines[i].sidenum[0]].text) @@ -6015,6 +6039,9 @@ static void P_ConvertBinarySectorTypes(void) case 5: //Speed pad sectors[i].specialflags |= SSF_SPEEDPAD; break; + case 6: //Gravity flip on jump (think VVVVVV) + sectors[i].specialflags |= SSF_JUMPFLIP; + break; default: break; } diff --git a/src/p_spec.c b/src/p_spec.c index a1e2e3c5d2e81c326eb970a2e9f270ec32143b7d..82337d2f6b07aa5d664363a234695243601d2883 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -1863,6 +1863,12 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller if (!P_CheckPlayerMare(triggerline)) return false; 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: break; } @@ -1900,7 +1906,8 @@ boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller || specialtype == 319 // Unlockable || specialtype == 331 // Player skin || specialtype == 334 // Object dye - || specialtype == 337) // Emerald check + || specialtype == 337 // Emerald check + || specialtype == 343) // Gravity check && triggerline->args[0] == TMT_ONCE) 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 == 331 // Player skin || 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) continue; @@ -2774,7 +2782,9 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) break; 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; else 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; else if (line->args[2] == TMF_REMOVE) sectors[secnum].flags &= ~MSF_GRAVITYFLIP; + + if (line->args[3]) + sectors[secnum].specialflags |= SSF_GRAVITYOVERRIDE; } } break; @@ -6307,6 +6320,9 @@ void P_SpawnSpecials(boolean fromnetsave) else sectors[s].flags &= ~MSF_GRAVITYFLIP; + if (lines[i].flags & ML_EFFECT6) + sectors[s].specialflags |= SSF_GRAVITYOVERRIDE; + CheckForReverseGravity |= (sectors[s].flags & MSF_GRAVITYFLIP); } break; @@ -6924,6 +6940,7 @@ void P_SpawnSpecials(boolean fromnetsave) case 331: // Player skin case 334: // Object dye case 337: // Emerald check + case 343: // Gravity check if (lines[i].args[0] > TMT_EACHTIMEMASK) P_AddEachTimeThinker(&lines[i], lines[i].args[0] == TMT_EACHTIMEENTERANDEXIT); break; diff --git a/src/p_spec.h b/src/p_spec.h index 69c629c4783ad3680e13f25a79b75b053b9f4f07..cd97efa1a7486b5c0afb1b3ae0294fac69c1cb6b 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -254,6 +254,13 @@ typedef enum TMC_GTE = 2, } textmapcomparison_t; +typedef enum +{ + TMG_NORMAL = 0, + TMG_REVERSE = 1, + TMG_TEMPREVERSE = 2, +} textmapgravity_t; + typedef enum { TMNP_FASTEST = 0, diff --git a/src/p_user.c b/src/p_user.c index 87809255df9e3180eb86818e183caa1ebafa66b5..ed9da035cd4f640c00abbb2a2f045959b5f07797 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -2494,6 +2494,41 @@ boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand 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) { if (!(rover->fofflags & FOF_EXISTS)) @@ -2789,12 +2824,13 @@ static void P_CheckQuicksand(player_t *player) fixed_t sinkspeed; 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; 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)) continue; @@ -4459,6 +4495,12 @@ void P_DoJump(player_t *player, boolean soundandstate) if (player->charflags & SF_NOJUMPDAMAGE) 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 (!player->spectator) @@ -7642,11 +7684,9 @@ void P_ElementalFire(player_t *player, boolean cropcircle) else ground = player->mo->floorz; - if (cropcircle) - ground += P_MobjFlip(player->mo); - if (cropcircle) { + ground += P_MobjFlip(player->mo); #define numangles 8 #define limitangle (180/numangles) 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->destscale = 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); P_InstaThrust(flame, flame->angle, FixedMul(3*FRACUNIT, flame->scale)); P_SetObjectMomZ(flame, 3*FRACUNIT, false); @@ -7694,6 +7735,8 @@ void P_ElementalFire(player_t *player, boolean cropcircle) flame->fuse = TICRATE*6; flame->destscale = 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); if (!(gametyperules & GTR_FRIENDLY)) { diff --git a/src/r_defs.h b/src/r_defs.h index 6c9c91ab13125492652cc3ac3bb77bc4a5e671cc..dbede806e241819c11ece32009d2a724f9aa60e5 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -355,6 +355,8 @@ typedef enum SSF_ZOOMTUBEEND = 1<<16, SSF_FINISHLINE = 1<<17, SSF_ROPEHANG = 1<<18, + SSF_JUMPFLIP = 1<<19, + SSF_GRAVITYOVERRIDE = 1<<20, // combine with MSF_GRAVITYFLIP } sectorspecialflags_t; typedef enum