diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 7e1cfc38..dc844451 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -534,8 +534,8 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) // Just in case Lua does something like // modify these at runtime // SRB2kart - rsp->kartspeed = (fixed_t)LONG(players[i].kartspeed); - rsp->kartweight = (fixed_t)LONG(players[i].kartweight); + rsp->kartspeed = (UINT8)LONG(players[i].kartspeed); + rsp->kartweight = (UINT8)LONG(players[i].kartweight); // rsp->normalspeed = (fixed_t)LONG(players[i].normalspeed); rsp->runspeed = (fixed_t)LONG(players[i].runspeed); @@ -666,8 +666,8 @@ static void resynch_read_player(resynch_pak *rsp) players[i].skin = LONG(rsp->skin); // Just in case Lua does something like // modify these at runtime - players[i].kartspeed = (fixed_t)LONG(rsp->kartspeed); - players[i].kartweight = (fixed_t)LONG(rsp->kartweight); + players[i].kartspeed = (UINT8)LONG(rsp->kartspeed); + players[i].kartweight = (UINT8)LONG(rsp->kartweight); players[i].normalspeed = (fixed_t)LONG(rsp->normalspeed); players[i].runspeed = (fixed_t)LONG(rsp->runspeed); diff --git a/src/k_kart.c b/src/k_kart.c index 5e07e103..57e38bf8 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -721,26 +721,26 @@ static INT32 K_KartItemOddsDistance_Battle[NUMKARTITEMS][5] = { //P-Odds 0 1 2 3 4 /*Magnet*/ { 0, 0, 0, 0, 0 }, // Magnet - /*Boo*/ { 2, 2, 2, 1, 0 }, // Boo - /*Mushroom*/ { 2, 2, 2, 1, 0 }, // Mushroom + /*Boo*/ { 1, 2, 3, 1, 0 }, // Boo + /*Mushroom*/ { 3, 2, 3, 1, 0 }, // Mushroom /*Triple Mushroom*/ { 0, 0, 0, 0, 0 }, // Triple Mushroom - /*Mega Mushroom*/ { 2, 1, 0, 0, 0 }, // Mega Mushroom + /*Mega Mushroom*/ { 3, 1, 0, 0, 0 }, // Mega Mushroom /*Gold Mushroom*/ { 0, 0, 0, 0, 0 }, // Gold Mushroom - /*Star*/ { 2, 1, 0, 0, 0 }, // Star + /*Star*/ { 3, 1, 0, 0, 0 }, // Star - /*Triple Banana*/ { 1, 1, 1, 1, 0 }, // Triple Banana - /*Fake Item*/ { 0, 1, 2, 4, 6 }, // Fake Item - /*Banana*/ { 0, 1, 3, 4, 6 }, // Banana - /*Green Shell*/ { 0, 1, 3, 4, 6 }, // Green Shell - /*Red Shell*/ { 1, 2, 2, 1, 0 }, // Red Shell - /*Triple Green Shell*/ { 1, 2, 2, 1, 0 }, // Triple Green Shell - /*Bob-omb*/ { 3, 2, 1, 1, 0 }, // Bob-omb + /*Triple Banana*/ { 0, 2, 1, 1, 0 }, // Triple Banana + /*Fake Item*/ { 0, 0, 2, 5, 8 }, // Fake Item + /*Banana*/ { 0, 0, 3, 4, 5 }, // Banana + /*Green Shell*/ { 0, 0, 3, 4, 5 }, // Green Shell + /*Red Shell*/ { 0, 3, 1, 1, 0 }, // Red Shell + /*Triple Green Shell*/ { 0, 3, 1, 1, 0 }, // Triple Green Shell + /*Bob-omb*/ { 3, 2, 1, 0, 0 }, // Bob-omb /*Blue Shell*/ { 0, 0, 0, 0, 0 }, // Blue Shell - /*Fire Flower*/ { 3, 2, 1, 1, 0 }, // Fire Flower - /*Triple Red Shell*/ { 2, 1, 0, 0, 0 }, // Triple Red Shell + /*Fire Flower*/ { 3, 2, 1, 0, 0 }, // Fire Flower + /*Triple Red Shell*/ { 4, 1, 0, 0, 0 }, // Triple Red Shell /*Lightning*/ { 0, 0, 0, 0, 0 }, // Lightning - /*Feather*/ { 0, 1, 1, 1, 2 } // Feather + /*Feather*/ { 0, 1, 2, 2, 2 } // Feather }; /** \brief Item Roulette for Kart @@ -965,11 +965,11 @@ static void K_KartItemRouletteByPosition(player_t *player, ticcmd_t *cmd) //} -static INT32 K_KartGetItemOdds(INT32 pos, INT32 itemnum, boolean battle) +static INT32 K_KartGetItemOdds(INT32 pos, INT32 itemnum) { INT32 newodds; - if (battle) + if (gametype == GT_MATCH) newodds = K_KartItemOddsDistance_Battle[itemnum-1][pos]; else newodds = K_KartItemOddsDistance_Retro[itemnum-1][pos]; @@ -995,10 +995,6 @@ static void K_KartItemRouletteByDistance(player_t *player, ticcmd_t *cmd) INT32 chance = 0, numchoices = 0; INT32 distvar = (64*14); INT32 avgballoon = 0; - boolean battle = false; - - if (gametype == GT_MATCH) - battle = true; // This makes the roulette cycle through items - if this is 0, you shouldn't be here. if (player->kartstuff[k_itemroulette]) @@ -1030,10 +1026,7 @@ static void K_KartItemRouletteByDistance(player_t *player, ticcmd_t *cmd) for (i = 0; i < MAXPLAYERS; i++) { if (playeringame[i] && !players[i].spectator) - { pingame++; - continue; - } if (players[i].exiting) pexiting++; if (players[i].kartstuff[k_balloon] > 0) @@ -1055,12 +1048,6 @@ static void K_KartItemRouletteByDistance(player_t *player, ticcmd_t *cmd) player->kartstuff[k_itemclose] = 0; // Reset the item window closer. - if (cv_kartfrantic.value) // Stupid items - { - pdis = (13*pdis/12); // multiply... - pdis += distvar; // set everyone back another place... - } - if (gametype == GT_MATCH || gametype == GT_TEAMMATCH || gametype == GT_CTF) // Battle Mode { useodds = (player->kartstuff[k_balloon]-avgballoon)+2; // 0 is two balloons below average, 2 is average, 4 is two balloons above average @@ -1071,6 +1058,12 @@ static void K_KartItemRouletteByDistance(player_t *player, ticcmd_t *cmd) } else { + if (cv_kartfrantic.value) // Frantic items + { + pdis = (13*pdis/12); // make the distances between everyone artifically higher... + pdis += distvar; // and set everyone back another place! + } + if (pingame == 1) useodds = 0; // Record Attack, or just alone else if (pdis <= distvar * 0) useodds = 1; // (64*14) * 0 = 0 else if (pdis <= distvar * 1) useodds = 2; // (64*14) * 1 = 896 @@ -1083,7 +1076,7 @@ static void K_KartItemRouletteByDistance(player_t *player, ticcmd_t *cmd) } #define SETITEMRESULT(pos, itemnum) \ - for (chance = 0; chance < K_KartGetItemOdds(pos, itemnum, battle); chance++) \ + for (chance = 0; chance < K_KartGetItemOdds(pos, itemnum); chance++) \ spawnchance[numchoices++] = itemnum // Check the game type to differentiate odds. @@ -1239,18 +1232,25 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce) \return boolean */ -static boolean K_CheckOffroadCollide(mobj_t *mo) +static UINT8 K_CheckOffroadCollide(mobj_t *mo, sector_t *sec) { + UINT8 i; + sector_t *sec2; + I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); - if (P_IsObjectOnGround(mo) - && (GETSECSPECIAL(mo->subsector->sector->special, 1) == 2 - || GETSECSPECIAL(mo->subsector->sector->special, 1) == 3 - || GETSECSPECIAL(mo->subsector->sector->special, 1) == 4)) - return true; + sec2 = P_ThingOnSpecial3DFloor(mo); - return false; + for (i = 2; i < 5; i++) + { + if ((sec2 && GETSECSPECIAL(sec2->special, 1) == i) + || (P_IsObjectOnRealGround(mo, sec) + && GETSECSPECIAL(sec->special, 1) == i)) + return i; + } + + return 0; } /** \brief Updates the Player's offroad value once per frame @@ -1267,12 +1267,12 @@ static void K_UpdateOffroad(player_t *player) player->mo->x + player->mo->momx*2, player->mo->y + player->mo->momy*2)->sector; fixed_t offroadstrength = 0; - - if (GETSECSPECIAL(nextsector->special, 1) == 2) // Weak Offroad + + if (K_CheckOffroadCollide(player->mo, nextsector) == 2) // Weak Offroad offroadstrength = 1; - else if (GETSECSPECIAL(nextsector->special, 1) == 3) // Mid Offroad + else if (K_CheckOffroadCollide(player->mo, nextsector) == 3) // Mid Offroad offroadstrength = 2; - else if (GETSECSPECIAL(nextsector->special, 1) == 4) // Strong Offroad + else if (K_CheckOffroadCollide(player->mo, nextsector) == 4) // Strong Offroad offroadstrength = 3; // If you are offroad, a timer starts. Depending on your weight value, the timer increments differently. @@ -1280,8 +1280,9 @@ static void K_UpdateOffroad(player_t *player) // && nextsector->special != 1024 && nextsector->special != 4864) if (offroadstrength) { - if (K_CheckOffroadCollide(player->mo) && player->kartstuff[k_offroad] == 0) + if (K_CheckOffroadCollide(player->mo, player->mo->subsector->sector) && player->kartstuff[k_offroad] == 0) player->kartstuff[k_offroad] = 16; + if (player->kartstuff[k_offroad] > 0) { if (kartweight < 1) { kartweight = 1; } if (kartweight > 9) { kartweight = 9; } // Safety Net @@ -2611,16 +2612,20 @@ void K_DoBouncePad(mobj_t *mo, fixed_t vertispeed) thrust = 48< 72<player->kartstuff[k_mushroomtimer]) + thrust = FixedMul(thrust, 5*FRACUNIT/4); + else if (mo->player->kartstuff[k_startimer]) + thrust = FixedMul(thrust, 9*FRACUNIT/8); mo->momz = FixedMul(FINESINE(ANGLE_22h>>ANGLETOFINESHIFT), thrust); } else { thrust = P_AproxDistance(mo->momx,mo->momy); - if (thrust < 8< 8< 32<momz = FixedMul(FINESINE(ANGLE_11hh>>ANGLETOFINESHIFT), thrust); + mo->momz = FixedMul(FINESINE(ANGLE_22h>>ANGLETOFINESHIFT), thrust); } } else @@ -3587,18 +3592,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_KartDrift(player, onground); - if (player->kartstuff[k_feather] & 2) - { - fixed_t strafe = 0; - fixed_t strength = FRACUNIT/4; - if (cmd->buttons & BT_DRIFTLEFT) - strafe -= 1; - if (cmd->buttons & BT_DRIFTRIGHT) - strafe += 1; - strength += FixedDiv(player->speed, K_GetKartSpeed(player, true)); - P_Thrust(player->mo, player->mo->angle-ANGLE_90, strafe*strength); - } - // Quick Turning // You can't turn your kart when you're not moving. // So now it's time to burn some rubber! diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index a58892d3..4679c0c5 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -150,9 +150,9 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->dashtime); // SRB2kart else if (fastcmp(field,"kartspeed")) - lua_pushfixed(L, plr->kartspeed); + lua_pushinteger(L, plr->kartspeed); else if (fastcmp(field,"kartweight")) - lua_pushfixed(L, plr->kartweight); + lua_pushinteger(L, plr->kartweight); // else if (fastcmp(field,"normalspeed")) lua_pushfixed(L, plr->normalspeed); diff --git a/src/m_menu.c b/src/m_menu.c index 14110f2b..74d7f912 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -375,7 +375,7 @@ consvar_t cv_chooseskin = {"chooseskin", DEFAULTSKIN, CV_HIDEN|CV_CALL, skins_co // When you add gametypes here, don't forget to update them in CV_AddValue! CV_PossibleValue_t gametype_cons_t[] = { - {GT_RACE, "Race"}, {GT_MATCH, "Match"}, + {GT_RACE, "Race"}, {GT_MATCH, "Battle"}, /* // SRB2kart {GT_COOP, "Co-op"}, @@ -977,9 +977,9 @@ static menuitem_t MP_SplitServerMenu[] = static menuitem_t MP_PlayerSetupMenu[] = { - {IT_KEYHANDLER | IT_STRING, NULL, "Your name", M_HandleSetupMultiPlayer, 0}, - {IT_KEYHANDLER | IT_STRING, NULL, "Your color", M_HandleSetupMultiPlayer, 16}, - {IT_KEYHANDLER | IT_STRING, NULL, "Your player", M_HandleSetupMultiPlayer, 96}, // Tails 01-18-2001 + {IT_KEYHANDLER | IT_STRING, NULL, "Name", M_HandleSetupMultiPlayer, 0}, + {IT_KEYHANDLER | IT_STRING, NULL, "Character", M_HandleSetupMultiPlayer, 16}, // Tails 01-18-2001 + {IT_KEYHANDLER | IT_STRING, NULL, "Color", M_HandleSetupMultiPlayer, 152}, }; // ------------------------------------ @@ -1657,12 +1657,12 @@ menu_t MP_RoomDef = menu_t MP_SplitServerDef = MAPICONMENUSTYLE("M_MULTI", MP_SplitServerMenu, &MP_MainDef); menu_t MP_PlayerSetupDef = { - "M_SPLAYR", + NULL, //"M_SPLAYR" sizeof (MP_PlayerSetupMenu)/sizeof (menuitem_t), &MP_MainDef, MP_PlayerSetupMenu, M_DrawSetupMultiPlayerMenu, - 27, 40, + 32, 16, 0, M_QuitMultiPlayerMenu }; @@ -5637,11 +5637,11 @@ static void M_HandleStaffReplay(INT32 choice) { case KEY_DOWNARROW: M_NextOpt(); - S_StartSound(NULL, sfx_bewar1); + S_StartSound(NULL, sfx_menu1); break; case KEY_UPARROW: M_PrevOpt(); - S_StartSound(NULL, sfx_bewar1); + S_StartSound(NULL, sfx_menu1); break; case KEY_BACKSPACE: case KEY_ESCAPE: @@ -6483,8 +6483,13 @@ static void M_DrawSetupMultiPlayerMenu(void) INT32 mx, my, st, flags = 0; spritedef_t *sprdef; spriteframe_t *sprframe; + patch_t *statbg = W_CachePatchName("K_STATBG", PU_CACHE); + patch_t *statdot = W_CachePatchName("K_SDOT0", PU_CACHE); patch_t *patch; UINT8 frame; + UINT8 speed; + UINT8 weight; + UINT8 i; mx = MP_PlayerSetupDef.x; my = MP_PlayerSetupDef.y; @@ -6493,21 +6498,34 @@ static void M_DrawSetupMultiPlayerMenu(void) M_DrawGenericMenu(); // draw name string - M_DrawTextBox(mx + 90, my - 8, MAXPLAYERNAME, 1); - V_DrawString(mx + 98, my, V_ALLOWLOWERCASE, setupm_name); + M_DrawTextBox(mx + 40, my - 8, MAXPLAYERNAME, 1); + V_DrawString(mx + 56, my, V_ALLOWLOWERCASE, setupm_name); // draw skin string - V_DrawString(mx + 90, my + 96, + V_DrawString(mx + 88, my + 16, ((MP_PlayerSetupMenu[2].status & IT_TYPE) == IT_SPACE ? V_TRANSLUCENT : 0)|V_YELLOWMAP|V_ALLOWLOWERCASE, skins[setupm_fakeskin].realname); // draw the name of the color you have chosen // Just so people don't go thinking that "Default" is Green. - V_DrawString(208, 72, V_YELLOWMAP|V_ALLOWLOWERCASE, KartColor_Names[setupm_fakecolor]); // SRB2kart + V_DrawString(mx + 56, my + 152, V_YELLOWMAP|V_ALLOWLOWERCASE, KartColor_Names[setupm_fakecolor]); // SRB2kart // draw text cursor for name if (!itemOn && skullAnimCounter < 4) // blink cursor - V_DrawCharacter(mx + 98 + V_StringWidth(setupm_name, 0), my, '_',false); + V_DrawCharacter(mx + 56 + V_StringWidth(setupm_name, 0), my, '_',false); + + // SRB2Kart: draw the stat backer + V_DrawFixedPatch((mx+142)<spriteframes[frame]; - patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE); + patch = W_CachePatchNum(sprframe->lumppat[1], PU_CACHE); if (sprframe->flip & 1) // Only for first sprite flags |= V_FLIP; // This sprite is left/right flipped! // draw box around guy - M_DrawTextBox(mx + 90, my + 8, PLBOXW, PLBOXH); + M_DrawTextBox(mx + 42, my + 66, PLBOXW, PLBOXH); + + if (skullAnimCounter < 4) // SRB2Kart: we draw this dot later so that it's not covered if there's multiple skins with the same stats + statdot = W_CachePatchName("K_SDOT2", PU_CACHE); + else + statdot = W_CachePatchName("K_SDOT1", PU_CACHE); + + speed = skins[setupm_fakeskin].kartspeed; + weight = skins[setupm_fakeskin].kartweight; // draw player sprite if (!setupm_fakecolor) // should never happen but hey, who knows { if (skins[setupm_fakeskin].flags & SF_HIRES) { - V_DrawSciencePatch((mx+98+(PLBOXW*8/2))<thinker); } -// -// P_IsObjectOnRealGround -// -// Helper function for T_EachTimeThinker -// Like P_IsObjectOnGroundIn, except ONLY THE REAL GROUND IS CONSIDERED, NOT FOFS -// I'll consider whether to make this a more globally accessible function or whatever in future -// -- Monster Iestyn -// -static boolean P_IsObjectOnRealGround(mobj_t *mo, sector_t *sec) -{ - // Is the object in reverse gravity? - if (mo->eflags & MFE_VERTICALFLIP) - { - // Detect if the player is on the ceiling. - if (mo->z+mo->height >= P_GetSpecialTopZ(mo, sec, sec)) - return true; - } - // Nope! - else - { - // Detect if the player is on the floor. - if (mo->z <= P_GetSpecialBottomZ(mo, sec, sec)) - return true; - } - return false; -} - // // P_HavePlayersEnteredArea // diff --git a/src/p_local.h b/src/p_local.h index 8d27d69e..673aa4fc 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -135,6 +135,7 @@ boolean P_IsLocalPlayer(player_t *player); boolean P_IsObjectInGoop(mobj_t *mo); boolean P_IsObjectOnGround(mobj_t *mo); boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec); +boolean P_IsObjectOnRealGround(mobj_t *mo, sector_t *sec); // SRB2Kart boolean P_InSpaceSector(mobj_t *mo); boolean P_InQuicksand(mobj_t *mo); diff --git a/src/p_mobj.c b/src/p_mobj.c index 6a9890f9..4349bdcc 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7710,7 +7710,9 @@ void P_MobjThinker(mobj_t *mobj) } sec2 = P_ThingOnSpecial3DFloor(mobj); - if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1) || (P_IsObjectOnGround(mobj) && GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1)) + if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1) + || (P_IsObjectOnRealGround(mobj, mobj->subsector->sector) + && GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1)) K_DoBouncePad(mobj, 0); if (mobj->threshold > 0) @@ -7761,7 +7763,9 @@ void P_MobjThinker(mobj_t *mobj) P_InstaThrust(mobj, R_PointToAngle2(0, 0, mobj->momx, mobj->momy), topspeed); sec2 = P_ThingOnSpecial3DFloor(mobj); - if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1) || (P_IsObjectOnGround(mobj) && GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1)) + if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1) + || (P_IsObjectOnRealGround(mobj, mobj->subsector->sector) + && GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1)) K_DoBouncePad(mobj, 0); break; @@ -7775,7 +7779,9 @@ void P_MobjThinker(mobj_t *mobj) P_InstaThrust(mobj, mobj->angle, mobj->info->speed); sec2 = P_ThingOnSpecial3DFloor(mobj); - if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1) || (P_IsObjectOnGround(mobj) && GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1)) + if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1) + || (P_IsObjectOnRealGround(mobj, mobj->subsector->sector) + && GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1)) K_DoBouncePad(mobj, 0); if (mobj->threshold > 0) diff --git a/src/p_spec.c b/src/p_spec.c index 7d787eb9..0bc84765 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3729,18 +3729,17 @@ DoneSection2: switch (special) { case 1: // SRB2kart: bounce pad - if (!P_IsObjectOnGround(player->mo)) - break; + if (roversector || P_MobjReadyToTrigger(player->mo, sector)) + { + if (player->mo->eflags & MFE_SPRUNG) + break; - if (player->mo->eflags & MFE_SPRUNG) - break; - - if (player->speed < K_GetKartSpeed(player, true)/4) // Push forward to prevent getting stuck - P_InstaThrust(player->mo, player->mo->angle, FixedMul(K_GetKartSpeed(player, true)/4, player->mo->scale)); - - player->kartstuff[k_feather] |= 2; - K_DoBouncePad(player->mo, 0); + if (player->speed < K_GetKartSpeed(player, true)/4) // Push forward to prevent getting stuck + P_InstaThrust(player->mo, player->mo->angle, FixedMul(K_GetKartSpeed(player, true)/4, player->mo->scale)); + player->kartstuff[k_feather] |= 2; + K_DoBouncePad(player->mo, 0); + } break; case 2: // Wind/Current @@ -3942,20 +3941,22 @@ DoneSection2: break; case 6: // SRB2kart 190117 - Mushroom Boost Panel - if (!P_IsObjectOnGround(player->mo)) - break; - if (!player->kartstuff[k_floorboost]) - player->kartstuff[k_floorboost] = 3; - else - player->kartstuff[k_floorboost] = 2; - K_DoMushroom(player, false, false); + if (roversector || P_MobjReadyToTrigger(player->mo, sector)) + { + if (!player->kartstuff[k_floorboost]) + player->kartstuff[k_floorboost] = 3; + else + player->kartstuff[k_floorboost] = 2; + K_DoMushroom(player, false, false); + } break; case 7: // SRB2kart 190117 - Oil Slick - if (!P_IsObjectOnGround(player->mo)) - break; - player->kartstuff[k_spinouttype] = -1; - K_SpinPlayer(player, NULL); + if (roversector || P_MobjReadyToTrigger(player->mo, sector)) + { + player->kartstuff[k_spinouttype] = -1; + K_SpinPlayer(player, NULL); + } break; case 8: // Zoom Tube Start diff --git a/src/p_user.c b/src/p_user.c index 583a0547..f1383646 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1312,6 +1312,36 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec) return false; } +// +// P_IsObjectOnRealGround +// +// Helper function for T_EachTimeThinker +// Like P_IsObjectOnGroundIn, except ONLY THE REAL GROUND IS CONSIDERED, NOT FOFS +// I'll consider whether to make this a more globally accessible function or whatever in future +// -- Monster Iestyn +// +// Really simple, but personally I think it's also incredibly helpful. I think this is fine in p_user.c +// -- Sal + +boolean P_IsObjectOnRealGround(mobj_t *mo, sector_t *sec) +{ + // Is the object in reverse gravity? + if (mo->eflags & MFE_VERTICALFLIP) + { + // Detect if the player is on the ceiling. + if (mo->z+mo->height >= P_GetSpecialTopZ(mo, sec, sec)) + return true; + } + // Nope! + else + { + // Detect if the player is on the floor. + if (mo->z <= P_GetSpecialBottomZ(mo, sec, sec)) + return true; + } + return false; +} + // // P_SetObjectMomZ // @@ -4706,6 +4736,10 @@ static void P_3dMovement(player_t *player) // Do not let the player control movement if not onground. onground = P_IsObjectOnGround(player->mo); + // SRB2Kart: shhhhhhh don't question me, feather and speed bumps are supposed to control like you're on the ground :p + if (player->kartstuff[k_feather] & 2) + onground = true; + player->aiming = cmd->aiming<