mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-12-28 02:32:48 +00:00
Merge remote-tracking branch 'origin/master' into no-pick-me-up
This commit is contained in:
commit
d32b8036d5
28 changed files with 385 additions and 95 deletions
|
|
@ -73,6 +73,7 @@
|
|||
#include "k_bans.h"
|
||||
#include "k_director.h"
|
||||
#include "k_credits.h"
|
||||
#include "k_hud.h" // K_AddMessage
|
||||
|
||||
#ifdef SRB2_CONFIG_ENABLE_WEBM_MOVIES
|
||||
#include "m_avrecorder.h"
|
||||
|
|
@ -180,6 +181,8 @@ static void Command_Archivetest_f(void);
|
|||
|
||||
static void Command_KartGiveItem_f(void);
|
||||
|
||||
static void Command_DebugMessageFeed(void);
|
||||
|
||||
static void Command_Schedule_Add(void);
|
||||
static void Command_Schedule_Clear(void);
|
||||
static void Command_Schedule_List(void);
|
||||
|
|
@ -434,6 +437,8 @@ void D_RegisterServerCommands(void)
|
|||
COM_AddDebugCommand("give3", Command_KartGiveItem_f);
|
||||
COM_AddDebugCommand("give4", Command_KartGiveItem_f);
|
||||
|
||||
COM_AddDebugCommand("debugmessagefeed", Command_DebugMessageFeed);
|
||||
|
||||
COM_AddCommand("schedule_add", Command_Schedule_Add);
|
||||
COM_AddCommand("schedule_clear", Command_Schedule_Clear);
|
||||
COM_AddCommand("schedule_list", Command_Schedule_List);
|
||||
|
|
@ -559,6 +564,14 @@ void D_RegisterClientCommands(void)
|
|||
COM_AddDebugCommand("scale", Command_Scale_f);
|
||||
COM_AddDebugCommand("gravflip", Command_Gravflip_f);
|
||||
COM_AddDebugCommand("hurtme", Command_Hurtme_f);
|
||||
COM_AddDebugCommand("stumble", Command_Stumble_f);
|
||||
COM_AddDebugCommand("tumble", Command_Tumble_f);
|
||||
COM_AddDebugCommand("whumble", Command_Whumble_f);
|
||||
COM_AddDebugCommand("explode", Command_Explode_f);
|
||||
COM_AddDebugCommand("spinout", Command_Spinout_f);
|
||||
COM_AddDebugCommand("wipeout", Command_Wipeout_f);
|
||||
COM_AddDebugCommand("sting", Command_Sting_f);
|
||||
COM_AddDebugCommand("kill", Command_Kill_f);
|
||||
COM_AddDebugCommand("teleport", Command_Teleport_f);
|
||||
COM_AddDebugCommand("rteleport", Command_RTeleport_f);
|
||||
COM_AddDebugCommand("skynum", Command_Skynum_f);
|
||||
|
|
@ -5924,10 +5937,13 @@ static void Got_Cheat(const UINT8 **cp, INT32 playernum)
|
|||
|
||||
if (!P_MobjWasRemoved(player->mo))
|
||||
{
|
||||
P_DamageMobj(player->mo, NULL, NULL, damage, DMG_NORMAL);
|
||||
if (damage >= DMG_INSTAKILL)
|
||||
P_KillMobj(player->mo, NULL, NULL, (UINT8)damage);
|
||||
else
|
||||
P_DamageMobj(player->mo, NULL, NULL, 1, (UINT8)damage);
|
||||
}
|
||||
|
||||
CV_CheaterWarning(targetPlayer, va("%d damage to me", damage));
|
||||
CV_CheaterWarning(targetPlayer, va("damage (flags=%d) to me", damage));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -6358,6 +6374,11 @@ static void Command_Archivetest_f(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
static void Command_DebugMessageFeed(void)
|
||||
{
|
||||
K_AddMessage("Hello world! A = <a>, Right = <right>", true, false);
|
||||
}
|
||||
|
||||
/** Give yourself an, optional quantity or one of, an item.
|
||||
*/
|
||||
static void Command_KartGiveItem_f(void)
|
||||
|
|
|
|||
|
|
@ -2281,6 +2281,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
UINT8 lastsafecheatcheck;
|
||||
UINT16 bigwaypointgap;
|
||||
|
||||
INT16 duelscore;
|
||||
|
||||
roundconditions_t roundconditions;
|
||||
boolean saveroundconditions;
|
||||
|
||||
|
|
@ -2445,6 +2447,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
lastsafelap = 0;
|
||||
lastsafecheatcheck = 0;
|
||||
bigwaypointgap = 0;
|
||||
duelscore = 0;
|
||||
|
||||
tallyactive = false;
|
||||
|
||||
|
|
@ -2506,6 +2509,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
}
|
||||
|
||||
cangrabitems = players[player].cangrabitems;
|
||||
|
||||
duelscore = players[player].duelscore;
|
||||
}
|
||||
|
||||
spectatorReentry = (betweenmaps ? 0 : players[player].spectatorReentry);
|
||||
|
|
@ -2610,6 +2615,8 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
|
|||
p->gradingpointnum = gradingpointnum;
|
||||
p->totalring = totalring;
|
||||
|
||||
p->duelscore = duelscore;
|
||||
|
||||
for (i = 0; i < LAP__MAX; i++)
|
||||
{
|
||||
p->laptime[i] = laptime[i];
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ namespace fs = std::filesystem;
|
|||
#define GD_VERSION_MINOR (2)
|
||||
|
||||
#define GD_MINIMUM_SPRAYCANSV2 (2)
|
||||
#define GD_MINIMUM_TIMEATTACKV2 (2)
|
||||
|
||||
void srb2::save_ng_gamedata()
|
||||
{
|
||||
|
|
@ -214,7 +215,7 @@ void srb2::save_ng_gamedata()
|
|||
{
|
||||
newrecords.bestskin = String(skinref.unloaded->name);
|
||||
}
|
||||
else
|
||||
else if (skinref.id < numskins)
|
||||
{
|
||||
newrecords.bestskin = String(skins[skinref.id].name);
|
||||
}
|
||||
|
|
@ -614,10 +615,22 @@ void srb2::load_ng_gamedata()
|
|||
dummyrecord.mapvisited |= mappair.second.visited.encore ? MV_ENCORE : 0;
|
||||
dummyrecord.mapvisited |= mappair.second.visited.spbattack ? MV_SPBATTACK : 0;
|
||||
dummyrecord.mapvisited |= mappair.second.visited.mysticmelody ? MV_MYSTICMELODY : 0;
|
||||
dummyrecord.timeattack.time = mappair.second.stats.timeattack.besttime;
|
||||
dummyrecord.timeattack.lap = mappair.second.stats.timeattack.bestlap;
|
||||
dummyrecord.spbattack.time = mappair.second.stats.spbattack.besttime;
|
||||
dummyrecord.spbattack.lap = mappair.second.stats.spbattack.bestlap;
|
||||
|
||||
if (minorversion >= GD_MINIMUM_TIMEATTACKV2)
|
||||
{
|
||||
dummyrecord.timeattack.time = mappair.second.stats.timeattack.besttime;
|
||||
dummyrecord.timeattack.lap = mappair.second.stats.timeattack.bestlap;
|
||||
dummyrecord.spbattack.time = mappair.second.stats.spbattack.besttime;
|
||||
dummyrecord.spbattack.lap = mappair.second.stats.spbattack.bestlap;
|
||||
}
|
||||
else
|
||||
{
|
||||
converted = true;
|
||||
|
||||
dummyrecord.timeattack.time = dummyrecord.timeattack.lap = \
|
||||
dummyrecord.spbattack.time = dummyrecord.spbattack.lap = 0;
|
||||
}
|
||||
|
||||
dummyrecord.timeplayed = mappair.second.stats.time.total;
|
||||
dummyrecord.netgametimeplayed = mappair.second.stats.time.netgame;
|
||||
dummyrecord.modetimeplayed[GDGT_RACE] = mappair.second.stats.time.race;
|
||||
|
|
@ -655,7 +668,7 @@ void srb2::load_ng_gamedata()
|
|||
|
||||
mapheaderinfo[mapnum]->records = dummyrecord;
|
||||
}
|
||||
else if (dummyrecord.mapvisited & MV_BEATEN
|
||||
else if (dummyrecord.mapvisited & (MV_VISITED|MV_BEATEN)
|
||||
|| dummyrecord.timeattack.time != 0 || dummyrecord.timeattack.lap != 0
|
||||
|| dummyrecord.spbattack.time != 0 || dummyrecord.spbattack.lap != 0
|
||||
|| dummyrecord.spraycan != MCAN_INVALID)
|
||||
|
|
|
|||
|
|
@ -531,7 +531,7 @@ static void K_BotItemSneaker(const player_t *player, ticcmd_t *cmd)
|
|||
|| player->speedboost > (FRACUNIT/8) // Have another type of boost (tethering)
|
||||
|| player->botvars.itemconfirm > 4*TICRATE) // Held onto it for too long
|
||||
{
|
||||
if (player->sneakertimer == 0 && K_ItemButtonWasDown(player) == false)
|
||||
if (player->sneakertimer == 0 && player->weaksneakertimer == 0 && K_ItemButtonWasDown(player) == false)
|
||||
{
|
||||
cmd->buttons |= BT_ATTACK;
|
||||
//player->botvars.itemconfirm = 2*TICRATE;
|
||||
|
|
@ -567,7 +567,7 @@ static void K_BotItemRocketSneaker(const player_t *player, ticcmd_t *cmd)
|
|||
|
||||
if (player->botvars.itemconfirm > TICRATE)
|
||||
{
|
||||
if (player->sneakertimer == 0 && K_ItemButtonWasDown(player) == false)
|
||||
if (player->sneakertimer == 0 && player->weaksneakertimer == 0 && K_ItemButtonWasDown(player) == false)
|
||||
{
|
||||
cmd->buttons |= BT_ATTACK;
|
||||
//player->botvars.itemconfirm = 0;
|
||||
|
|
@ -1605,7 +1605,7 @@ static void K_BotItemIceCube(const player_t *player, ticcmd_t *cmd)
|
|||
return;
|
||||
}
|
||||
|
||||
if (player->sneakertimer)
|
||||
if (player->sneakertimer || player->weaksneakertimer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -269,7 +269,10 @@ static inline BlockItReturn_t PIT_SSMineSearch(mobj_t *thing)
|
|||
return BMIT_CONTINUE;
|
||||
}
|
||||
|
||||
if (thing == grenade->target && grenade->threshold != 0) // Don't blow up at your owner instantly.
|
||||
if (thing == grenade->target) // Don't blow up at your owner instantly.
|
||||
return BMIT_CONTINUE;
|
||||
|
||||
if (grenade->target->player && thing->player && G_SameTeam(grenade->target->player, thing->player))
|
||||
return BMIT_CONTINUE;
|
||||
|
||||
if (PIT_SSMineChecks(thing) == true)
|
||||
|
|
@ -388,6 +391,9 @@ boolean K_MineCollide(mobj_t *t1, mobj_t *t2)
|
|||
if (t2->player->flashing > 0 && t2->hitlag == 0)
|
||||
return true;
|
||||
|
||||
if (K_TryPickMeUp(t1, t2, false))
|
||||
return true;
|
||||
|
||||
// Bomb punting
|
||||
if ((t1->state >= &states[S_SSMINE1] && t1->state <= &states[S_SSMINE4])
|
||||
|| (t1->state >= &states[S_SSMINE_DEPLOY8] && t1->state <= &states[S_SSMINE_EXPLODE2]))
|
||||
|
|
@ -1139,6 +1145,11 @@ boolean K_PvPTouchDamage(mobj_t *t1, mobj_t *t2)
|
|||
if (P_MobjWasRemoved(t1) || P_MobjWasRemoved(t2) || !t1->player || !t2->player)
|
||||
return false;
|
||||
|
||||
if (G_SameTeam(t1->player, t2->player))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Clash instead of damage if both parties have any of these conditions
|
||||
auto canClash = [](mobj_t *t1, mobj_t *t2)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -3580,7 +3580,7 @@ static tic_t scorechangecooldown = 0;
|
|||
// but HUD hooks run at variable timing based on your actual framerate.
|
||||
static tic_t teams_lastleveltime = 0;
|
||||
|
||||
static void K_drawKartTeamScores(void)
|
||||
void K_drawKartTeamScores(boolean fromintermission, INT32 interoffset)
|
||||
{
|
||||
if (G_GametypeHasTeams() == false)
|
||||
{
|
||||
|
|
@ -3599,8 +3599,13 @@ static void K_drawKartTeamScores(void)
|
|||
INT32 basey = 0;
|
||||
INT32 flags = V_HUDTRANS|V_SLIDEIN;
|
||||
INT32 snapflags = V_SNAPTOTOP|V_SNAPTORIGHT;
|
||||
|
||||
if (use4p)
|
||||
snapflags = V_SNAPTOTOP;
|
||||
|
||||
if (fromintermission)
|
||||
use4p = true;
|
||||
|
||||
flags |= snapflags;
|
||||
|
||||
// bar stuff, relative to base
|
||||
|
|
@ -3644,6 +3649,13 @@ static void K_drawKartTeamScores(void)
|
|||
faceoff = 4;
|
||||
}
|
||||
|
||||
if (fromintermission)
|
||||
{
|
||||
snapflags = 0;
|
||||
flags = 0;
|
||||
basex += interoffset;
|
||||
}
|
||||
|
||||
UINT8 allies = stplyr->team;
|
||||
UINT8 enemies = (allies == TEAM_ORANGE) ? TEAM_BLUE : TEAM_ORANGE;
|
||||
|
||||
|
|
@ -3730,9 +3742,12 @@ static void K_drawKartTeamScores(void)
|
|||
}
|
||||
}
|
||||
|
||||
// replace scores with eased scores
|
||||
allyscore = easedallyscore;
|
||||
enemyscore = totalscore - allyscore;
|
||||
if (!fromintermission)
|
||||
{
|
||||
// replace scores with eased scores
|
||||
allyscore = easedallyscore;
|
||||
enemyscore = totalscore - allyscore;
|
||||
}
|
||||
}
|
||||
|
||||
teams_lastleveltime = leveltime;
|
||||
|
|
@ -3777,10 +3792,22 @@ static void K_drawKartTeamScores(void)
|
|||
}
|
||||
|
||||
// Draw at the top and bottom of the screen in 4P.
|
||||
boolean goagain = use4p;
|
||||
// Draw only at the bottom in intermission.
|
||||
boolean shouldsecondpass = use4p;
|
||||
boolean onsecondpass = fromintermission;
|
||||
|
||||
draw:
|
||||
|
||||
if (onsecondpass)
|
||||
{
|
||||
if (!fromintermission)
|
||||
{
|
||||
flags |= V_SNAPTOBOTTOM;
|
||||
flags &= ~V_SNAPTOTOP;
|
||||
}
|
||||
basey = 170;
|
||||
}
|
||||
|
||||
V_DrawScaledPatch(basex, basey, flags, kp_team_sticker[use4p]);
|
||||
V_DrawMappedPatch(basex, basey, flags, kp_team_underlay[use4p][0], enemycolor);
|
||||
V_DrawMappedPatch(basex, basey, flags, kp_team_underlay[use4p][1], allycolor);
|
||||
|
|
@ -3788,8 +3815,10 @@ static void K_drawKartTeamScores(void)
|
|||
if (!use4p)
|
||||
V_DrawScaledPatch(basex, basey, flags, kp_team_you);
|
||||
|
||||
if (V_GetHUDTranslucency(0) != 10)
|
||||
/*
|
||||
if (V_GetHUDTranslucency(0) != 10 || fromintermission)
|
||||
return;
|
||||
*/
|
||||
|
||||
V_DrawFill(basex+barx, basey+bary, enemywidth, barheight, enemyfill|flags);
|
||||
V_DrawFill(basex+barx+enemywidth, basey+bary, allywidth, barheight, allyfill|flags);
|
||||
|
|
@ -3847,12 +3876,9 @@ static void K_drawKartTeamScores(void)
|
|||
you.text("{:02}", youscore);
|
||||
}
|
||||
|
||||
if (goagain)
|
||||
if (shouldsecondpass && !onsecondpass)
|
||||
{
|
||||
goagain = false;
|
||||
flags |= V_SNAPTOBOTTOM;
|
||||
flags &= ~V_SNAPTOTOP;
|
||||
basey = 170;
|
||||
onsecondpass = true;
|
||||
goto draw;
|
||||
}
|
||||
|
||||
|
|
@ -7204,17 +7230,19 @@ static std::vector<messagestate_t> messagestates{MAXSPLITSCREENPLAYERS};
|
|||
|
||||
void K_AddMessage(const char *msg, boolean interrupt, boolean persist)
|
||||
{
|
||||
for (auto &state : messagestates)
|
||||
for (UINT8 i = 0; i <= r_splitscreen; i++)
|
||||
{
|
||||
if (interrupt)
|
||||
state.clear();
|
||||
messagestate_t *state = &messagestates[i];
|
||||
|
||||
std::string parsedmsg = srb2::Draw::TextElement().parse(msg).string();
|
||||
if (interrupt)
|
||||
state->clear();
|
||||
|
||||
std::string parsedmsg = srb2::Draw::TextElement().as(g_localplayers[i]).parse(msg).string();
|
||||
|
||||
if (persist)
|
||||
state.objective = parsedmsg;
|
||||
state->objective = parsedmsg;
|
||||
else
|
||||
state.add(parsedmsg);
|
||||
state->add(parsedmsg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -7612,10 +7640,7 @@ void K_drawKartHUD(void)
|
|||
}
|
||||
}
|
||||
|
||||
if (G_GametypeHasTeams() == true)
|
||||
{
|
||||
K_drawKartTeamScores();
|
||||
}
|
||||
K_drawKartTeamScores(false, 0);
|
||||
|
||||
if (K_InRaceDuel())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -165,6 +165,8 @@ position_t K_GetKartObjectPosToMinimapPos(fixed_t objx, fixed_t objy);
|
|||
|
||||
INT32 K_DrawGameControl(UINT16 x, UINT16 y, UINT8 player, const char *str, UINT8 alignment, UINT8 font, UINT32 flags);
|
||||
|
||||
void K_drawKartTeamScores(boolean fromintermission, INT32 interoffset);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -389,27 +389,12 @@ bool is_object_tracking_target(const mobj_t* mobj)
|
|||
return !(mobj->renderflags & (RF_TRANSMASK | RF_DONTDRAW)) && // the spraycan wasn't collected yet
|
||||
P_CheckSight(stplyr->mo, const_cast<mobj_t*>(mobj));
|
||||
|
||||
case MT_JAWZ:
|
||||
case MT_JAWZ_SHIELD:
|
||||
case MT_ORBINAUT:
|
||||
case MT_ORBINAUT_SHIELD:
|
||||
case MT_DROPTARGET:
|
||||
case MT_DROPTARGET_SHIELD:
|
||||
case MT_LANDMINE:
|
||||
case MT_BANANA:
|
||||
case MT_BANANA_SHIELD:
|
||||
case MT_GACHABOM:
|
||||
case MT_BUBBLESHIELDTRAP:
|
||||
case MT_EGGMANITEM:
|
||||
case MT_EGGMANITEM_SHIELD:
|
||||
if (cv_debugpickmeup.value)
|
||||
return false;
|
||||
return (mobj->target && !P_MobjWasRemoved(mobj->target) && (
|
||||
(mobj->target->player && stplyr == mobj->target->player)
|
||||
|| (mobj->target->player && G_SameTeam(stplyr, mobj->target->player))
|
||||
) && P_CheckSight(stplyr->mo, const_cast<mobj_t*>(mobj)));
|
||||
|
||||
default:
|
||||
if (K_IsPickMeUpItem(mobj->type))
|
||||
return (mobj->target && !P_MobjWasRemoved(mobj->target) && (
|
||||
(mobj->target->player && stplyr == mobj->target->player)
|
||||
|| (mobj->target->player && G_SameTeam(stplyr, mobj->target->player))
|
||||
) && P_CheckSight(stplyr->mo, const_cast<mobj_t*>(mobj)));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
48
src/k_kart.c
48
src/k_kart.c
|
|
@ -1102,6 +1102,12 @@ boolean K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2)
|
|||
disty = FixedMul(minBump, normalisedy);
|
||||
}
|
||||
|
||||
if (mobj1->player && mobj2->player && G_SameTeam(mobj1->player, mobj2->player))
|
||||
{
|
||||
distx /= 3;
|
||||
disty /= 3;
|
||||
}
|
||||
|
||||
if (mass2 > 0)
|
||||
{
|
||||
mobj1->momx = mobj1->momx - FixedMul(FixedDiv(2*mass2, mass1 + mass2), distx);
|
||||
|
|
@ -3071,7 +3077,8 @@ tripwirepass_t K_TripwirePassConditions(const player_t *player)
|
|||
{
|
||||
if (
|
||||
player->invincibilitytimer ||
|
||||
player->sneakertimer
|
||||
player->sneakertimer ||
|
||||
player->weaksneakertimer
|
||||
)
|
||||
return TRIPWIRE_BLASTER;
|
||||
|
||||
|
|
@ -4176,8 +4183,8 @@ void K_SpawnAmps(player_t *player, UINT8 amps, mobj_t *impact)
|
|||
if (amps == 0)
|
||||
return;
|
||||
|
||||
UINT32 itemdistance = max(0, min( FRACUNIT-1, K_GetItemRouletteDistance(player, D_NumPlayersInRace()))); // cap this to FRACUNIT-1, so it doesn't wrap when turning it into fixed_t
|
||||
fixed_t itemdistmult = FRACUNIT + max( 0, min( FRACUNIT, (itemdistance<<FRACBITS) / MAXAMPSCALINGDIST));
|
||||
UINT32 itemdistance = min(FRACUNIT-1, K_GetItemRouletteDistance(player, D_NumPlayersInRace())); // cap this to FRACUNIT-1, so it doesn't wrap when turning it into fixed_t
|
||||
fixed_t itemdistmult = FRACUNIT + min(FRACUNIT, (itemdistance<<FRACBITS) / MAXAMPSCALINGDIST);
|
||||
UINT16 scaledamps = min(amps, amps * (10 + (9-player->kartspeed) - (9-player->kartweight)) / 10);
|
||||
// Debug print for scaledamps calculation
|
||||
// CONS_Printf("K_SpawnAmps: player=%s, amps=%d, kartspeed=%d, kartweight=%d, itemdistance=%d, itemdistmult=%0.2f, statscaledamps=%d, distscaledamps=%d\n",
|
||||
|
|
@ -5460,7 +5467,7 @@ void K_DebtStingPlayer(player_t *player, mobj_t *source)
|
|||
{
|
||||
INT32 length = TICRATE;
|
||||
|
||||
if (source->player)
|
||||
if (source && !P_MobjWasRemoved(source) && source->player)
|
||||
{
|
||||
length += (4 * (source->player->kartweight - player->kartweight));
|
||||
}
|
||||
|
|
@ -7213,6 +7220,7 @@ static void K_FlameDashLeftoverSmoke(mobj_t *src)
|
|||
void K_DoSneaker(player_t *player, INT32 type)
|
||||
{
|
||||
|
||||
INT32 originaltype = type;
|
||||
fixed_t intendedboost = FRACUNIT/2;
|
||||
|
||||
// If you've already got an rocket sneaker type boost, panel sneakers will instead turn into rocket sneaker boosts
|
||||
|
|
@ -7317,16 +7325,27 @@ void K_DoSneaker(player_t *player, INT32 type)
|
|||
{
|
||||
case 0: // Panel sneaker
|
||||
player->panelsneakertimer = sneakertime;
|
||||
break;
|
||||
case 1: // Single item sneaker
|
||||
player->sneakertimer = sneakertime;
|
||||
break;
|
||||
case 2: // Rocket sneaker (aka. weaksneaker)
|
||||
player->weaksneakertimer = 3*sneakertime/4;
|
||||
break;
|
||||
}
|
||||
|
||||
// Give invincibility based on the ACTUAL boost type used, not the "promoted" boost type
|
||||
switch (originaltype)
|
||||
{
|
||||
case 0: // Panel sneaker
|
||||
if (player->overshield > 0) {
|
||||
player->overshield = min( player->overshield + TICRATE/3, max( TICRATE, player->overshield ));
|
||||
}
|
||||
break;
|
||||
case 1: // Single item sneaker
|
||||
player->sneakertimer = sneakertime;
|
||||
player->overshield = max( player->overshield, 25 );
|
||||
break;
|
||||
case 2: // Rocket sneaker (aka. weaksneaker)
|
||||
player->weaksneakertimer = 3*sneakertime/4;
|
||||
player->overshield = max( player->overshield, TICRATE/2 );
|
||||
break;
|
||||
}
|
||||
|
|
@ -9816,6 +9835,11 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
|
|||
player->invincibilitytimer--;
|
||||
if (player->invincibilitytimer && K_IsPlayerScamming(player))
|
||||
player->invincibilitytimer--;
|
||||
|
||||
// Extra tripwire leniency for the end of invincibility
|
||||
if (player->invincibilitytimer <= 0) {
|
||||
player->tripwireLeniency = max( player->tripwireLeniency, TICRATE );
|
||||
}
|
||||
}
|
||||
|
||||
// The precise ordering of start-of-level made me want to cut my head off,
|
||||
|
|
@ -15705,6 +15729,12 @@ void K_MakeObjectReappear(mobj_t *mo)
|
|||
|
||||
boolean K_PlayerCanUseItem(player_t *player)
|
||||
{
|
||||
if (player->icecube.frozen)
|
||||
return false;
|
||||
|
||||
if (player->turbine && (player->mo->flags & MF_NOCLIP))
|
||||
return false;
|
||||
|
||||
return (player->mo->health > 0 && !player->spectator && !P_PlayerInPain(player) && !mapreset && leveltime > introtime);
|
||||
}
|
||||
|
||||
|
|
@ -15854,6 +15884,8 @@ boolean K_IsPickMeUpItem(mobjtype_t type)
|
|||
case MT_EGGMANITEM:
|
||||
case MT_EGGMANITEM_SHIELD:
|
||||
case MT_BUBBLESHIELDTRAP:
|
||||
case MT_SSMINE:
|
||||
case MT_SSMINE_SHIELD:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
|
@ -15903,6 +15935,10 @@ static boolean K_PickUp(player_t *player, mobj_t *picked)
|
|||
case MT_SINK:
|
||||
type = KITEM_KITCHENSINK;
|
||||
break;
|
||||
case MT_SSMINE:
|
||||
case MT_SSMINE_SHIELD:
|
||||
type = KITEM_MINE;
|
||||
break;
|
||||
default:
|
||||
type = KITEM_SAD;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -3046,7 +3046,7 @@ fixed_t M_DrawCupWinData(INT32 rankx, INT32 ranky, cupheader_t *cup, UINT8 diffi
|
|||
patch_t *charPat = NULL;
|
||||
|
||||
if ((windata->best_skin.unloaded != NULL)
|
||||
|| (windata->best_skin.id > numskins))
|
||||
|| (windata->best_skin.id >= numskins))
|
||||
{
|
||||
colormap = NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ static struct podiumData_s
|
|||
boolean fastForward;
|
||||
|
||||
char header[64];
|
||||
char difficulty[64];
|
||||
|
||||
void Init(void);
|
||||
void NextLevel(void);
|
||||
|
|
@ -258,6 +259,27 @@ void podiumData_s::Init(void)
|
|||
);
|
||||
}
|
||||
|
||||
switch(grandprixinfo.gamespeed)
|
||||
{
|
||||
case KARTSPEED_EASY:
|
||||
snprintf(difficulty, sizeof difficulty, "Relaxed");
|
||||
break;
|
||||
case KARTSPEED_NORMAL:
|
||||
snprintf(difficulty, sizeof difficulty, "Intense");
|
||||
break;
|
||||
case KARTSPEED_HARD:
|
||||
snprintf(difficulty, sizeof difficulty, "Vicious");
|
||||
break;
|
||||
default:
|
||||
snprintf(difficulty, sizeof difficulty, "?");
|
||||
}
|
||||
|
||||
if (grandprixinfo.masterbots)
|
||||
snprintf(difficulty, sizeof difficulty, "Master");
|
||||
|
||||
if (cv_4thgear.value || cv_levelskull.value)
|
||||
snprintf(difficulty, sizeof difficulty, "Extra");
|
||||
|
||||
header[sizeof header - 1] = '\0';
|
||||
|
||||
displayLevels = 0;
|
||||
|
|
@ -504,6 +526,12 @@ void podiumData_s::Draw(void)
|
|||
.colormap(bestHuman->skin, static_cast<skincolornum_t>(bestHuman->skincolor))
|
||||
.patch(faceprefix[bestHuman->skin][FACE_WANTED]);
|
||||
|
||||
drawer_winner
|
||||
.xy(16, 28)
|
||||
.align(srb2::Draw::Align::kCenter)
|
||||
.font(srb2::Draw::Font::kMenu)
|
||||
.text(difficulty);
|
||||
|
||||
drawer_winner
|
||||
.xy(44, 31)
|
||||
.align(srb2::Draw::Align::kCenter)
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
#include "g_party.h"
|
||||
#include "g_input.h"
|
||||
#include "k_objects.h"
|
||||
#include "k_director.h"
|
||||
|
||||
boolean level_tally_t::UseBonuses(void)
|
||||
{
|
||||
|
|
@ -781,6 +782,24 @@ void level_tally_t::Tick(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (done == true)
|
||||
{
|
||||
if (directorWait < TALLY_DIRECTOR_TIME)
|
||||
{
|
||||
directorWait++;
|
||||
|
||||
if (directorWait == TALLY_DIRECTOR_TIME && G_IsPartyLocal(owner - players) == true)
|
||||
{
|
||||
// Finished tally, go to director while we wait for others to finish.
|
||||
K_ToggleDirector(G_PartyPosition(owner - players), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
directorWait = 0;
|
||||
}
|
||||
|
||||
if (transition < FRACUNIT)
|
||||
{
|
||||
if (transitionTime <= 0)
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ typedef enum
|
|||
TALLY_ST_GAMEOVER_DONE,
|
||||
} tally_state_e;
|
||||
|
||||
#define TALLY_DIRECTOR_TIME (4 * TICRATE)
|
||||
|
||||
struct level_tally_t
|
||||
{
|
||||
boolean active;
|
||||
|
|
@ -97,6 +99,7 @@ struct level_tally_t
|
|||
boolean showGrade;
|
||||
boolean done;
|
||||
boolean releasedFastForward;
|
||||
INT32 directorWait;
|
||||
|
||||
#ifdef __cplusplus
|
||||
boolean UseBonuses(void);
|
||||
|
|
|
|||
|
|
@ -2238,7 +2238,7 @@ static boolean Y_DetermineStageStrike(void)
|
|||
case int_score:
|
||||
{
|
||||
score_a = a->score;
|
||||
score_b = b->realtime;
|
||||
score_b = b->score;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -1124,6 +1124,14 @@ static int player_set(lua_State *L)
|
|||
plr->sneakertimer = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"numsneakers"))
|
||||
plr->numsneakers = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"panelsneakertimer"))
|
||||
plr->panelsneakertimer = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"numpanelsneakers"))
|
||||
plr->numpanelsneakers = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"weaksneakertimer"))
|
||||
plr->weaksneakertimer = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"numweaksneakers"))
|
||||
plr->numweaksneakers = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"floorboost"))
|
||||
plr->floorboost = luaL_checkinteger(L, 3);
|
||||
else if (fastcmp(field,"growshrinktimer"))
|
||||
|
|
|
|||
|
|
@ -115,13 +115,82 @@ void Command_Hurtme_f(void)
|
|||
|
||||
if (COM_Argc() < 2)
|
||||
{
|
||||
CONS_Printf(M_GetText("hurtme <damage>: Damage yourself by a specific amount\n"));
|
||||
CONS_Printf(M_GetText("hurtme <damage>: Damage yourself with specific flags\n"));
|
||||
CONS_Printf(M_GetText("Norm 0 Wipe 1 Expl 2 Tumb 3 Stng 4\n"));
|
||||
CONS_Printf(M_GetText("Krma 5 Volt 6 Stmb 7 Whmb 8\n"));
|
||||
CONS_Printf(M_GetText("Ikll 128 Dpit 129 Crsh 130 Spec 131 Time 132\n"));
|
||||
CONS_Printf(M_GetText("Wmbo 16 Stel 32 Hslf 64\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
D_Cheat(consoleplayer, CHEAT_HURT, atoi(COM_Argv(1)));
|
||||
}
|
||||
|
||||
void Command_Spinout_f(void)
|
||||
{
|
||||
REQUIRE_CHEATS;
|
||||
REQUIRE_INLEVEL;
|
||||
|
||||
D_Cheat(consoleplayer, CHEAT_HURT, DMG_NORMAL);
|
||||
}
|
||||
|
||||
void Command_Wipeout_f(void)
|
||||
{
|
||||
REQUIRE_CHEATS;
|
||||
REQUIRE_INLEVEL;
|
||||
|
||||
D_Cheat(consoleplayer, CHEAT_HURT, DMG_WIPEOUT);
|
||||
}
|
||||
|
||||
void Command_Explode_f(void)
|
||||
{
|
||||
REQUIRE_CHEATS;
|
||||
REQUIRE_INLEVEL;
|
||||
|
||||
D_Cheat(consoleplayer, CHEAT_HURT, DMG_EXPLODE);
|
||||
}
|
||||
|
||||
void Command_Sting_f(void)
|
||||
{
|
||||
REQUIRE_CHEATS;
|
||||
REQUIRE_INLEVEL;
|
||||
|
||||
D_Cheat(consoleplayer, CHEAT_HURT, DMG_STING);
|
||||
}
|
||||
|
||||
|
||||
void Command_Tumble_f(void)
|
||||
{
|
||||
REQUIRE_CHEATS;
|
||||
REQUIRE_INLEVEL;
|
||||
|
||||
D_Cheat(consoleplayer, CHEAT_HURT, DMG_TUMBLE);
|
||||
}
|
||||
|
||||
void Command_Stumble_f(void)
|
||||
{
|
||||
REQUIRE_CHEATS;
|
||||
REQUIRE_INLEVEL;
|
||||
|
||||
D_Cheat(consoleplayer, CHEAT_HURT, DMG_STUMBLE);
|
||||
}
|
||||
|
||||
void Command_Whumble_f(void)
|
||||
{
|
||||
REQUIRE_CHEATS;
|
||||
REQUIRE_INLEVEL;
|
||||
|
||||
D_Cheat(consoleplayer, CHEAT_HURT, DMG_WHUMBLE);
|
||||
}
|
||||
|
||||
void Command_Kill_f(void)
|
||||
{
|
||||
REQUIRE_CHEATS;
|
||||
REQUIRE_INLEVEL;
|
||||
|
||||
D_Cheat(consoleplayer, CHEAT_HURT, DMG_INSTAKILL);
|
||||
}
|
||||
|
||||
void Command_RTeleport_f(void)
|
||||
{
|
||||
float x = atof(COM_Argv(1));
|
||||
|
|
|
|||
|
|
@ -80,6 +80,16 @@ void Command_Devmode_f(void);
|
|||
void Command_Scale_f(void);
|
||||
void Command_Gravflip_f(void);
|
||||
void Command_Hurtme_f(void);
|
||||
|
||||
void Command_Stumble_f(void);
|
||||
void Command_Whumble_f(void);
|
||||
void Command_Tumble_f(void);
|
||||
void Command_Explode_f(void);
|
||||
void Command_Spinout_f(void);
|
||||
void Command_Wipeout_f(void);
|
||||
void Command_Sting_f(void);
|
||||
void Command_Kill_f(void);
|
||||
|
||||
void Command_Teleport_f(void);
|
||||
void Command_RTeleport_f(void);
|
||||
void Command_Skynum_f(void);
|
||||
|
|
|
|||
|
|
@ -499,7 +499,7 @@ struct CheckpointManager
|
|||
auto lines = tagged_lines(chk->linetag());
|
||||
if (lines.empty() && gametype != GT_TUTORIAL)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "Checkpoint thing %d, has linetag %d, but no lines found. Please ensure all checkpoints have associated lines.\n", chk->spawnpoint - mapthings, chk->linetag());
|
||||
CONS_Alert(CONS_WARNING, "Checkpoint thing %s, has linetag %d, but no lines found. Please ensure all checkpoints have associated lines.\n", sizeu1(chk->spawnpoint - mapthings), chk->linetag());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -510,7 +510,7 @@ struct CheckpointManager
|
|||
{
|
||||
if (gametype != GT_TUTORIAL)
|
||||
{
|
||||
CONS_Alert(CONS_WARNING, "Checkpoint thing %d, has no linetag. Please ensure all checkpoint things have a linetag.\n", chk->spawnpoint - mapthings);
|
||||
CONS_Alert(CONS_WARNING, "Checkpoint thing %s, has no linetag. Please ensure all checkpoint things have a linetag.\n", sizeu1(chk->spawnpoint - mapthings));
|
||||
}
|
||||
}
|
||||
list_.push_front(chk);
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include "../s_sound.h"
|
||||
#include "../r_main.h"
|
||||
#include "../m_random.h"
|
||||
#include "../k_hitlag.h"
|
||||
|
||||
|
||||
#define BULB_ZTHRUST 96*FRACUNIT
|
||||
|
|
@ -143,7 +144,6 @@ void Obj_PlayerCloudThink(player_t *player)
|
|||
if (player->cloud)
|
||||
{
|
||||
player->cloud--;
|
||||
P_InstaThrust(mo, 0, 0);
|
||||
mo->momz = 0;
|
||||
player->fastfall = 0;
|
||||
|
||||
|
|
@ -157,6 +157,7 @@ void Obj_PlayerCloudThink(player_t *player)
|
|||
player->cloudlaunch = TICRATE;
|
||||
|
||||
P_InstaThrust(mo, mo->cusval, mo->cvmem);
|
||||
K_AddHitLag(mo, 6, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1286,7 +1286,9 @@ static mobj_t *InitSpecialUFO(waypoint_t *start)
|
|||
// Set specialDamage as early as possible, for glass ball's sake
|
||||
if (grandprixinfo.gp && grandprixinfo.specialDamage)
|
||||
{
|
||||
ufo->health -= min(4*(UINT32)mobjinfo[MT_SPECIAL_UFO].spawnhealth/10, grandprixinfo.specialDamage/6);
|
||||
ufo->health -= min(2*(UINT32)mobjinfo[MT_SPECIAL_UFO].spawnhealth/10, grandprixinfo.specialDamage/12);
|
||||
// Use this if you want to spy on what the health ends up being:
|
||||
//CONS_Printf("the UFO weeps: %d hp\n", ufo->health );
|
||||
}
|
||||
|
||||
ufo_speed(ufo) = FixedMul(UFO_START_SPEED, K_GetKartGameSpeedScalar(gamespeed));
|
||||
|
|
|
|||
|
|
@ -237,7 +237,6 @@ void Obj_playerWPZTurbine(player_t *p)
|
|||
if (mode && !distreached)
|
||||
p->turbineangle = (INT32)R_PointToAngle2(t->x, t->y, pmo->x, pmo->y);
|
||||
|
||||
p->spinouttimer = TICRATE;
|
||||
pmo->pitch = 0;
|
||||
|
||||
// determine target x/y/z
|
||||
|
|
@ -344,7 +343,6 @@ void Obj_playerWPZTurbine(player_t *p)
|
|||
pmo->momy = (pmo->momy*17)/10;
|
||||
}
|
||||
|
||||
p->spinouttimer = 0;
|
||||
pmo->flags &= ~MF_NOCLIP;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
52
src/p_mobj.c
52
src/p_mobj.c
|
|
@ -5337,6 +5337,39 @@ boolean P_IsKartFieldItem(INT32 type)
|
|||
}
|
||||
}
|
||||
|
||||
// This item keeps track of its owner by the mobj target
|
||||
boolean P_IsRelinkItem(INT32 type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case MT_POGOSPRING:
|
||||
case MT_EGGMANITEM:
|
||||
case MT_EGGMANITEM_SHIELD:
|
||||
case MT_BANANA:
|
||||
case MT_BANANA_SHIELD:
|
||||
case MT_ORBINAUT:
|
||||
case MT_ORBINAUT_SHIELD:
|
||||
case MT_JAWZ:
|
||||
case MT_JAWZ_SHIELD:
|
||||
case MT_SSMINE:
|
||||
case MT_SSMINE_SHIELD:
|
||||
case MT_LANDMINE:
|
||||
case MT_DROPTARGET:
|
||||
case MT_DROPTARGET_SHIELD:
|
||||
case MT_BALLHOG:
|
||||
case MT_SPB:
|
||||
case MT_BUBBLESHIELDTRAP:
|
||||
case MT_GARDENTOP:
|
||||
case MT_HYUDORO_CENTER:
|
||||
case MT_SINK:
|
||||
case MT_GACHABOM:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
boolean K_IsMissileOrKartItem(mobj_t *mo)
|
||||
{
|
||||
if (mo->flags & MF_MISSILE)
|
||||
|
|
@ -5402,20 +5435,9 @@ static boolean P_IsTrackerType(INT32 type)
|
|||
case MT_GARDENTOP: // Frey
|
||||
return true;
|
||||
|
||||
case MT_JAWZ_SHIELD: // Pick-me-up
|
||||
case MT_ORBINAUT:
|
||||
case MT_ORBINAUT_SHIELD:
|
||||
case MT_DROPTARGET:
|
||||
case MT_DROPTARGET_SHIELD:
|
||||
case MT_LANDMINE:
|
||||
case MT_BANANA:
|
||||
case MT_BANANA_SHIELD:
|
||||
case MT_GACHABOM:
|
||||
case MT_EGGMANITEM:
|
||||
case MT_EGGMANITEM_SHIELD:
|
||||
return true;
|
||||
|
||||
default:
|
||||
if (K_IsPickMeUpItem(type))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -10355,7 +10377,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
I_Assert(mobj != NULL);
|
||||
I_Assert(!P_MobjWasRemoved(mobj));
|
||||
|
||||
if (P_IsKartItem(mobj->type) && mobj->target && !P_MobjWasRemoved(mobj->target))
|
||||
if (P_IsRelinkItem(mobj->type) && mobj->target && !P_MobjWasRemoved(mobj->target))
|
||||
{
|
||||
player_t *link = mobj->target->player;
|
||||
if (link && playeringame[link-players] && !link->spectator)
|
||||
|
|
@ -10366,7 +10388,7 @@ void P_MobjThinker(mobj_t *mobj)
|
|||
if (mobj->target && P_MobjWasRemoved(mobj->target))
|
||||
{
|
||||
P_SetTarget(&mobj->target, NULL);
|
||||
if (P_IsKartItem(mobj->type) && mobj->relinkplayer && mobj->relinkplayer <= MAXPLAYERS)
|
||||
if (P_IsRelinkItem(mobj->type) && mobj->relinkplayer && mobj->relinkplayer <= MAXPLAYERS)
|
||||
{
|
||||
player_t *relink = &players[mobj->relinkplayer-1];
|
||||
if (playeringame[relink-players] && !relink->spectator && relink->mo && !P_MobjWasRemoved(relink->mo))
|
||||
|
|
|
|||
|
|
@ -547,6 +547,7 @@ void P_AddCachedAction(mobj_t *mobj, INT32 statenum);
|
|||
|
||||
boolean P_IsKartItem(INT32 type);
|
||||
boolean P_IsKartFieldItem(INT32 type);
|
||||
boolean P_IsRelinkItem(INT32 type);
|
||||
boolean K_IsMissileOrKartItem(mobj_t *mo);
|
||||
boolean P_CanDeleteKartItem(INT32 type);
|
||||
|
||||
|
|
|
|||
|
|
@ -1198,6 +1198,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
|
|||
players[i].numsneakers = READUINT8(save->p);
|
||||
players[i].panelsneakertimer = READUINT16(save->p);
|
||||
players[i].numpanelsneakers = READUINT8(save->p);
|
||||
players[i].weaksneakertimer = READUINT16(save->p);
|
||||
players[i].numweaksneakers = READUINT8(save->p);
|
||||
players[i].floorboost = READUINT8(save->p);
|
||||
|
||||
|
|
|
|||
|
|
@ -8159,6 +8159,15 @@ static void P_InitGametype(void)
|
|||
#else
|
||||
strcpy(ver, VERSIONSTRING);
|
||||
#endif
|
||||
// Replace path separators with hyphens
|
||||
{
|
||||
char *p = ver;
|
||||
while ((p = strpbrk(p, "/\\")))
|
||||
{
|
||||
*p = '-';
|
||||
p++;
|
||||
}
|
||||
}
|
||||
sprintf(buf, "%s" PATHSEP "media" PATHSEP "replay" PATHSEP "online" PATHSEP "%s" PATHSEP "%d-%s",
|
||||
srb2home, ver, (int) (time(NULL)), G_BuildMapName(gamemap));
|
||||
|
||||
|
|
|
|||
22
src/p_user.c
22
src/p_user.c
|
|
@ -405,7 +405,7 @@ UINT8 P_FindHighestLap(void)
|
|||
//
|
||||
boolean P_PlayerInPain(const player_t *player)
|
||||
{
|
||||
if (player->spinouttimer || (player->tumbleBounces > 0) || (player->pflags & PF_FAULT) || player->icecube.frozen)
|
||||
if (player->spinouttimer || (player->tumbleBounces > 0) || (player->pflags & PF_FAULT))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
@ -2371,15 +2371,15 @@ static void P_UpdatePlayerAngle(player_t *player)
|
|||
// Don't force another turning tic, just give them the desired angle!
|
||||
#endif
|
||||
|
||||
if (!(player->cmd.buttons & BT_DRIFT) && (abs(player->drift) == 1) && ((player->cmd.turning > 0) == (player->drift > 0)) && player->handleboost > SLIPTIDEHANDLING)
|
||||
if (!(player->cmd.buttons & BT_DRIFT) && (abs(player->drift) == 1) && ((player->cmd.turning > 0) == (player->drift > 0)) && player->handleboost >= SLIPTIDEHANDLING)
|
||||
{
|
||||
// This drift release is eligible to start a sliptide. Don't do lag-compensation countersteer behavior that could destroy it!
|
||||
if (player->cmd.turning >= 0)
|
||||
if (player->cmd.turning > 0)
|
||||
{
|
||||
steeringLeft = max(steeringLeft, 1);
|
||||
steeringRight = max(steeringRight, steeringLeft);
|
||||
}
|
||||
else if (player->cmd.turning <= 0)
|
||||
else if (player->cmd.turning < 0)
|
||||
{
|
||||
steeringRight = min(steeringRight, -1);
|
||||
steeringLeft = min(steeringLeft, steeringRight);
|
||||
|
|
@ -2539,9 +2539,19 @@ void P_MovePlayer(player_t *player)
|
|||
player->glanceDir = 0;
|
||||
player->pflags &= ~PF_GAINAX;
|
||||
}
|
||||
else if ((player->pflags & PF_FAULT) || (player->spinouttimer > 0))
|
||||
else if ((player->pflags & PF_FAULT) || (player->spinouttimer > 0) || (player->turbine && (player->mo->flags & MF_NOCLIP)))
|
||||
{
|
||||
UINT16 speed = ((player->pflags & PF_FAULT) ? player->nocontrol : player->spinouttimer)/8;
|
||||
tic_t timer = 0;
|
||||
|
||||
if ((player->pflags & PF_FAULT))
|
||||
timer = player->nocontrol;
|
||||
else if (player->spinouttimer > 0)
|
||||
timer = player->spinouttimer;
|
||||
else if (player->turbine && (player->mo->flags & MF_NOCLIP))
|
||||
timer = TICRATE;
|
||||
|
||||
UINT16 speed = timer / 8;
|
||||
|
||||
if (speed > 8)
|
||||
speed = 8;
|
||||
else if (speed < 1)
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "z_zone.h"
|
||||
#include "k_profiles.h" // controls
|
||||
#include "p_local.h" // stplyr
|
||||
#include "r_fps.h" // R_GetViewNumber()
|
||||
|
||||
using srb2::Draw;
|
||||
using Chain = Draw::Chain;
|
||||
|
|
@ -176,17 +177,22 @@ Draw::TextElement& Draw::TextElement::parse(std::string_view raw)
|
|||
else if (auto it = translation.find(code); it != translation.end()) // This represents a gamecontrol, turn into Saturn button or generic button.
|
||||
{
|
||||
|
||||
UINT8 localplayer = 0;
|
||||
UINT8 indexedplayer = as_.value_or(stplyr - players);
|
||||
for (UINT8 i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
UINT8 localplayer = R_GetViewNumber();
|
||||
|
||||
if (as_.has_value())
|
||||
{
|
||||
if (g_localplayers[i] == indexedplayer)
|
||||
UINT8 indexedplayer = as_.value();
|
||||
for (UINT8 i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
localplayer = i;
|
||||
break;
|
||||
if (g_localplayers[i] == indexedplayer)
|
||||
{
|
||||
localplayer = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This isn't how v_video.cpp checks for buttons and I don't know why.
|
||||
if (cv_descriptiveinput[localplayer].value && ((it->second & 0xF0) != 0x80)) // Should we do game control translation?
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2020,6 +2020,9 @@ void Y_IntermissionDrawer(void)
|
|||
// Returns early if there's no players to draw
|
||||
Y_PlayerStandingsDrawer(&data, x);
|
||||
|
||||
if (sorttic == -1 || ((intertic - sorttic) < 8))
|
||||
K_drawKartTeamScores(true, x);
|
||||
|
||||
// Draw bottom (and top) pieces
|
||||
skiptallydrawer:
|
||||
if (!LUA_HudEnabled(hud_intermissionmessages))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue