Previous EXE: The Better Edition

- Improve balloon-based items. Much more distinguished differences
between the different ranks
- Reverted Feather strafing. You can now just... properly move in the
air, if you're using a Feather or a Bounce Pad.
- Bounce pads are now stronger while using speed items.
- Fixed the long standing bug about offroad & ziplines working when
you're on FOFs above them. This is a tricky subject, so please report
any issues you may come across related to this.
- Shells should no longer travel to Mars, nor will they  when using
bounce pads. They should now do a gentle hop.
- :WIP: new MP Player Setup screen, now shows character stats. Will
later feature the list of characters in a row of icons, and a backported
2.2 color selector with toast's permission
- Renamed "Match" to "Battle" :p
- Yet MORE minor cases where kartspeed & kartweight were being read as
fixed_t when they're freakin' UINT8's, people!
This commit is contained in:
TehRealSalt 2017-11-28 01:13:23 -05:00
parent 4288d6c668
commit 198685582f
9 changed files with 176 additions and 140 deletions

View File

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

View File

@ -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<<FRACBITS;
if (thrust > 72<<FRACBITS)
thrust = 72<<FRACBITS;
if (mo->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<<FRACBITS)
if (thrust < 4<<FRACBITS)
thrust = 4<<FRACBITS;
if (thrust > 8<<FRACBITS)
thrust = 8<<FRACBITS;
if (thrust > 32<<FRACBITS)
thrust = 32<<FRACBITS;
mo->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!

View File

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

View File

@ -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)<<FRACBITS, (my+62)<<FRACBITS, FRACUNIT, 0, statbg, NULL);
for (i = 0; i < numskins; i++)
{
if (i != setupm_fakeskin && R_SkinAvailable(skins[i].name) != -1)
{
speed = skins[i].kartspeed;
weight = skins[i].kartweight;
V_DrawFixedPatch(((mx+178) + ((speed-1)*8))<<FRACBITS, ((my+76) + ((weight-1)*8))<<FRACBITS, FRACUNIT, 0, statdot, NULL);
}
}
// anim the player in the box
if (--multi_tics <= 0)
@ -6534,25 +6552,34 @@ static void M_DrawSetupMultiPlayerMenu(void)
frame = 0; // Try to use standing frame
sprframe = &sprdef->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))<<FRACBITS,
(my+16+(PLBOXH*8)-12)<<FRACBITS,
V_DrawSciencePatch((mx+50+(PLBOXW*8/2))<<FRACBITS,
(my+74+(PLBOXH*8)-12)<<FRACBITS,
flags, patch,
skins[setupm_fakeskin].highresscale);
}
else
V_DrawScaledPatch(mx + 98 + (PLBOXW*8/2), my + 16 + (PLBOXH*8) - 12, flags, patch);
V_DrawScaledPatch(mx + 50 + (PLBOXW*8/2), my + 74 + (PLBOXH*8) - 12, flags, patch);
V_DrawFixedPatch(((mx+178) + ((speed-1)*8))<<FRACBITS, ((my+76) + ((weight-1)*8))<<FRACBITS, FRACUNIT, 0, statdot, NULL);
}
else
{
@ -6560,14 +6587,15 @@ static void M_DrawSetupMultiPlayerMenu(void)
if (skins[setupm_fakeskin].flags & SF_HIRES)
{
V_DrawFixedPatch((mx+98+(PLBOXW*8/2))<<FRACBITS,
(my+16+(PLBOXH*8)-12)<<FRACBITS,
V_DrawFixedPatch((mx+50+(PLBOXW*8/2))<<FRACBITS,
(my+74+(PLBOXH*8)-12)<<FRACBITS,
skins[setupm_fakeskin].highresscale,
flags, patch, colormap);
}
else
V_DrawMappedPatch(mx + 98 + (PLBOXW*8/2), my + 16 + (PLBOXH*8) - 12, flags, patch, colormap);
V_DrawMappedPatch(mx + 50 + (PLBOXW*8/2), my + 74 + (PLBOXH*8) - 12, flags, patch, colormap);
V_DrawFixedPatch(((mx+178) + ((speed-1)*8))<<FRACBITS, ((my+76) + ((weight-1)*8))<<FRACBITS, FRACUNIT, 0, statdot, colormap);
Z_Free(colormap);
}
}
@ -6591,12 +6619,12 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
break;
case KEY_LEFTARROW:
if (itemOn == 2) //player skin
if (itemOn == 1) //player skin
{
S_StartSound(NULL,sfx_menu1); // Tails
setupm_fakeskin--;
}
else if (itemOn == 1) // player color
else if (itemOn == 2) // player color
{
S_StartSound(NULL,sfx_menu1); // Tails
setupm_fakecolor--;
@ -6604,12 +6632,12 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
break;
case KEY_RIGHTARROW:
if (itemOn == 2) //player skin
if (itemOn == 1) //player skin
{
S_StartSound(NULL,sfx_menu1); // Tails
setupm_fakeskin++;
}
else if (itemOn == 1) // player color
else if (itemOn == 2) // player color
{
S_StartSound(NULL,sfx_menu1); // Tails
setupm_fakecolor++;

View File

@ -2037,33 +2037,6 @@ foundenemy:
P_RemoveThinker(&nobaddies->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
//

View File

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

View File

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

View File

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

View File

@ -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<<FRACBITS;
// Set the player speeds.