Merge public master into internal master

This commit is contained in:
Eidolon 2024-05-19 17:29:17 -05:00
commit 5864cf40c0
9 changed files with 106 additions and 36 deletions

View file

@ -46,6 +46,9 @@ Environment::Environment()
// Not that we're adding any modules to it, though. :p // Not that we're adding any modules to it, though. :p
global->active = true; global->active = true;
// Set a branch limit (same as ZDoom's instruction limit)
branchLimit = 2000000;
// Add the data & function pointers. // Add the data & function pointers.
// Starting with raw ACS0 codes. I'm using this classic-style // Starting with raw ACS0 codes. I'm using this classic-style
@ -405,3 +408,42 @@ ACSVM::Word Environment::callSpecImpl
P_ProcessSpecial(activator, spec, args, stringargs); P_ProcessSpecial(activator, spec, args, stringargs);
return 1; return 1;
} }
void Environment::printKill(ACSVM::Thread *thread, ACSVM::Word type, ACSVM::Word data)
{
std::string scriptName;
ACSVM::String *scriptNamePtr = (thread->script != nullptr) ? (thread->script->name.s) : nullptr;
if (scriptNamePtr && scriptNamePtr->len)
scriptName = std::string(scriptNamePtr->str);
else
scriptName = std::to_string((int)thread->script->name.i);
ACSVM::KillType killType = static_cast<ACSVM::KillType>(type);
if (killType == ACSVM::KillType::BranchLimit)
{
CONS_Alert(CONS_ERROR, "Terminated runaway script %s\n", scriptName.c_str());
return;
}
else if (killType == ACSVM::KillType::UnknownCode)
{
CONS_Alert(CONS_ERROR, "ACSVM ERROR: Unknown opcode %d in script %s\n", data, scriptName.c_str());
}
else if (killType == ACSVM::KillType::UnknownFunc)
{
CONS_Alert(CONS_ERROR, "ACSVM ERROR: Unknown function %d in script %s\n", data, scriptName.c_str());
}
else if (killType == ACSVM::KillType::OutOfBounds)
{
CONS_Alert(CONS_ERROR, "ACSVM ERROR: Jumped to out of bounds location %lu in script %s\n",
(thread->codePtr - thread->module->codeV.data() - 1), scriptName.c_str());
}
else
{
CONS_Alert(CONS_ERROR, "ACSVM ERROR: Kill %u:%d at %lu in script %s\n",
type, data, (thread->codePtr - thread->module->codeV.data() - 1), scriptName.c_str());
}
CONS_Printf("Script terminated.\n");
}

View file

@ -32,6 +32,8 @@ public:
virtual ACSVM::Thread *allocThread(); virtual ACSVM::Thread *allocThread();
virtual void printKill(ACSVM::Thread *thread, ACSVM::Word type, ACSVM::Word data);
protected: protected:
virtual void loadModule(ACSVM::Module *module); virtual void loadModule(ACSVM::Module *module);

View file

@ -6461,14 +6461,12 @@ void Command_Retry_f(void)
*/ */
static void Command_Isgamemodified_f(void) static void Command_Isgamemodified_f(void)
{ {
if (majormods) if (savemoddata)
CONS_Printf("The game has been modified with major addons, so you cannot play Record Attack.\n"); CONS_Printf("The game has been modified with an addon using its own save data.\n");
else if (savemoddata)
CONS_Printf("The game has been modified with an addon with its own save data, so you can play Record Attack and earn medals.\n");
else if (modifiedgame) else if (modifiedgame)
CONS_Printf("The game has been modified with only minor addons. You can play Record Attack, earn medals and unlock extras.\n"); CONS_Printf("The game has been modified, but is still using Ring Racers save data.\n");
else else
CONS_Printf("The game has not been modified. You can play Record Attack, earn medals and unlock extras.\n"); CONS_Printf("The game has not been modified.\n");
} }
#ifdef _DEBUG #ifdef _DEBUG

View file

@ -358,7 +358,7 @@ void G_ClearRecords(void)
// TODO: Technically, these should only remove time attack records here. // TODO: Technically, these should only remove time attack records here.
// But I'm out of juice for dev (+ literally, just finished some OJ). // But I'm out of juice for dev (+ literally, just finished some OJ).
// The stats need to be cleared in M_ClearStats, and I guess there's // The stats need to be cleared in M_ClearStats, and I guess there's
// no perfect place to wipe mapvisited because it's not actually part of // no perfect place to wipe mapvisited because it's not actually part of
// basegame progression... so here's fine for launch. ~toast 100424 // basegame progression... so here's fine for launch. ~toast 100424
unloaded_mapheader_t *unloadedmap, *nextunloadedmap = NULL; unloaded_mapheader_t *unloadedmap, *nextunloadedmap = NULL;
@ -652,7 +652,7 @@ static void G_UpdateRecordReplays(void)
} }
} }
// for consistency among messages: this modifies the game and removes savemoddata. // for consistency among messages: this marks the game as modified.
void G_SetGameModified(boolean silent, boolean major) void G_SetGameModified(boolean silent, boolean major)
{ {
if ((majormods && modifiedgame) || !mainwads || (refreshdirmenu & REFRESHDIR_GAMEDATA)) // new gamedata amnesty? if ((majormods && modifiedgame) || !mainwads || (refreshdirmenu & REFRESHDIR_GAMEDATA)) // new gamedata amnesty?
@ -666,9 +666,6 @@ void G_SetGameModified(boolean silent, boolean major)
//savemoddata = false; -- there is literally no reason to do this anymore. //savemoddata = false; -- there is literally no reason to do this anymore.
majormods = true; majormods = true;
if (!silent)
CONS_Alert(CONS_NOTICE, M_GetText("Game must be restarted to play Record Attack.\n"));
// If in record attack recording, cancel it. // If in record attack recording, cancel it.
if (modeattacking) if (modeattacking)
M_EndModeAttackRun(); M_EndModeAttackRun();

View file

@ -12617,7 +12617,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
// if a player picks up an item during the instawhip input safety window—the one that triggers // if a player picks up an item during the instawhip input safety window—the one that triggers
// after you burn to 0 rings—they can continue to hold the input, then charge a usable whip // after you burn to 0 rings—they can continue to hold the input, then charge a usable whip
// without stopping the roulette and acquiring an item, which cancels it. // without stopping the roulette and acquiring an item, which cancels it.
// //
// No ghosts use this technique, but your least favorite tournament player might. // No ghosts use this technique, but your least favorite tournament player might.
if (player->itemRoulette.active) if (player->itemRoulette.active)
{ {
@ -12857,9 +12857,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
} }
else if (ATTACK_IS_DOWN && (player->itemflags & IF_ITEMOUT)) // Banana x3 thrown else if (ATTACK_IS_DOWN && (player->itemflags & IF_ITEMOUT)) // Banana x3 thrown
{ {
player->itemamount--;
K_ThrowKartItem(player, false, MT_BANANA, -1, 0, 0); K_ThrowKartItem(player, false, MT_BANANA, -1, 0, 0);
K_PlayAttackTaunt(player->mo); K_PlayAttackTaunt(player->mo);
player->itemamount--;
K_UpdateHnextList(player, false); K_UpdateHnextList(player, false);
player->botvars.itemconfirm = 0; player->botvars.itemconfirm = 0;
} }
@ -12923,9 +12923,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
} }
else if (ATTACK_IS_DOWN && (player->itemflags & IF_ITEMOUT)) // Orbinaut x3 thrown else if (ATTACK_IS_DOWN && (player->itemflags & IF_ITEMOUT)) // Orbinaut x3 thrown
{ {
player->itemamount--;
K_ThrowKartItem(player, true, MT_ORBINAUT, 1, 0, 0); K_ThrowKartItem(player, true, MT_ORBINAUT, 1, 0, 0);
K_PlayAttackTaunt(player->mo); K_PlayAttackTaunt(player->mo);
player->itemamount--;
K_UpdateHnextList(player, false); K_UpdateHnextList(player, false);
player->botvars.itemconfirm = 0; player->botvars.itemconfirm = 0;
} }
@ -12966,9 +12966,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
} }
else if (ATTACK_IS_DOWN && HOLDING_ITEM && (player->itemflags & IF_ITEMOUT)) // Jawz thrown else if (ATTACK_IS_DOWN && HOLDING_ITEM && (player->itemflags & IF_ITEMOUT)) // Jawz thrown
{ {
player->itemamount--;
K_ThrowKartItem(player, true, MT_JAWZ, 1, 0, 0); K_ThrowKartItem(player, true, MT_JAWZ, 1, 0, 0);
K_PlayAttackTaunt(player->mo); K_PlayAttackTaunt(player->mo);
player->itemamount--;
K_UpdateHnextList(player, false); K_UpdateHnextList(player, false);
player->botvars.itemconfirm = 0; player->botvars.itemconfirm = 0;
} }
@ -12994,9 +12994,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
} }
else if (ATTACK_IS_DOWN && (player->itemflags & IF_ITEMOUT)) else if (ATTACK_IS_DOWN && (player->itemflags & IF_ITEMOUT))
{ {
player->itemamount--;
K_ThrowKartItem(player, false, MT_SSMINE, 1, 1, 0); K_ThrowKartItem(player, false, MT_SSMINE, 1, 1, 0);
K_PlayAttackTaunt(player->mo); K_PlayAttackTaunt(player->mo);
player->itemamount--;
player->itemflags &= ~IF_ITEMOUT; player->itemflags &= ~IF_ITEMOUT;
K_UpdateHnextList(player, true); K_UpdateHnextList(player, true);
player->botvars.itemconfirm = 0; player->botvars.itemconfirm = 0;
@ -13032,9 +13032,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
} }
else if (ATTACK_IS_DOWN && (player->itemflags & IF_ITEMOUT)) else if (ATTACK_IS_DOWN && (player->itemflags & IF_ITEMOUT))
{ {
player->itemamount--;
K_ThrowKartItem(player, (player->throwdir > 0), MT_DROPTARGET, -1, 0, 0); K_ThrowKartItem(player, (player->throwdir > 0), MT_DROPTARGET, -1, 0, 0);
K_PlayAttackTaunt(player->mo); K_PlayAttackTaunt(player->mo);
player->itemamount--;
player->itemflags &= ~IF_ITEMOUT; player->itemflags &= ~IF_ITEMOUT;
K_UpdateHnextList(player, true); K_UpdateHnextList(player, true);
player->botvars.itemconfirm = 0; player->botvars.itemconfirm = 0;
@ -13276,9 +13276,10 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (player->bubbleblowup > bubbletime*2) if (player->bubbleblowup > bubbletime*2)
{ {
player->itemamount--;
K_ThrowKartItem(player, (player->throwdir > 0), MT_BUBBLESHIELDTRAP, -1, 0, 0); K_ThrowKartItem(player, (player->throwdir > 0), MT_BUBBLESHIELDTRAP, -1, 0, 0);
if (player->throwdir == -1) if (player->throwdir == -1)
{ {
P_InstaThrust(player->mo, player->mo->angle, player->speed + (80 * mapobjectscale)); P_InstaThrust(player->mo, player->mo->angle, player->speed + (80 * mapobjectscale));
player->wavedashboost += TICRATE; player->wavedashboost += TICRATE;
player->wavedashpower = FRACUNIT; player->wavedashpower = FRACUNIT;
@ -13288,7 +13289,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->bubbleblowup = 0; player->bubbleblowup = 0;
player->bubblecool = 0; player->bubblecool = 0;
player->itemflags &= ~IF_HOLDREADY; player->itemflags &= ~IF_HOLDREADY;
player->itemamount--;
player->botvars.itemconfirm = 0; player->botvars.itemconfirm = 0;
} }
} }
@ -13362,7 +13362,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->mo, player->mo->angle, player->mo, player->mo->angle,
FixedMul((50*player->mo->scale), K_GetKartGameSpeedScalar(gamespeed)) FixedMul((50*player->mo->scale), K_GetKartGameSpeedScalar(gamespeed))
); );
player->wavedashboost += TICRATE; player->wavedashboost += TICRATE;
player->wavedashpower = FRACUNIT; player->wavedashpower = FRACUNIT;
player->fakeBoost = TICRATE/3; player->fakeBoost = TICRATE/3;
@ -13454,9 +13454,9 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
} }
else if (ATTACK_IS_DOWN && HOLDING_ITEM && (player->itemflags & IF_ITEMOUT)) // Sink thrown else if (ATTACK_IS_DOWN && HOLDING_ITEM && (player->itemflags & IF_ITEMOUT)) // Sink thrown
{ {
player->itemamount--;
K_ThrowKartItem(player, false, MT_SINK, 1, 2, 0); K_ThrowKartItem(player, false, MT_SINK, 1, 2, 0);
K_PlayAttackTaunt(player->mo); K_PlayAttackTaunt(player->mo);
player->itemamount--;
player->itemflags &= ~IF_ITEMOUT; player->itemflags &= ~IF_ITEMOUT;
K_UpdateHnextList(player, true); K_UpdateHnextList(player, true);
player->botvars.itemconfirm = 0; player->botvars.itemconfirm = 0;
@ -13465,11 +13465,11 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
case KITEM_GACHABOM: case KITEM_GACHABOM:
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO) if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO)
{ {
player->itemamount--;
K_SetItemOut(player); // need this to set itemscale K_SetItemOut(player); // need this to set itemscale
K_ThrowKartItem(player, true, MT_GACHABOM, 0, 0, 0); K_ThrowKartItem(player, true, MT_GACHABOM, 0, 0, 0);
K_UnsetItemOut(player); K_UnsetItemOut(player);
K_PlayAttackTaunt(player->mo); K_PlayAttackTaunt(player->mo);
player->itemamount--;
player->roundconditions.gachabom_miser = ( player->roundconditions.gachabom_miser = (
(player->roundconditions.gachabom_miser == 0) (player->roundconditions.gachabom_miser == 0)
? 1 : 0xFF ? 1 : 0xFF
@ -13596,7 +13596,13 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
// We'll never need to go above that. // We'll never need to go above that.
if (player->tricktime <= TRICKDELAY) if (player->tricktime <= TRICKDELAY)
{
// 2.3 - Prevent accidental fastfalls during trickdelay
if (!G_CompatLevel(0x000C))
player->pflags |= PF_NOFASTFALL;
player->tricktime++; player->tricktime++;
}
// debug shit // debug shit
//CONS_Printf("%d\n", player->mo->momz / mapobjectscale); //CONS_Printf("%d\n", player->mo->momz / mapobjectscale);
@ -13624,15 +13630,21 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
const angle_t angledelta = FixedAngle(36*FRACUNIT); const angle_t angledelta = FixedAngle(36*FRACUNIT);
angle_t baseangle = player->mo->angle + angledelta/2; angle_t baseangle = player->mo->angle + angledelta/2;
UINT16 buttons = player->cmd.buttons;
INT16 aimingcompare = abs(cmd->throwdir) - abs(cmd->turning); INT16 aimingcompare = abs(cmd->throwdir) - abs(cmd->turning);
// 2.2 - Pre-steering trickpanels // 2.2 - Pre-steering trickpanels
if (!G_CompatLevel(0x000A) && !K_PlayerUsesBotMovement(player)) if (!G_CompatLevel(0x000A) && !K_PlayerUsesBotMovement(player))
{ {
if (!(player->cmd.buttons & BT_ACCELERATE)) if (!(buttons & BT_ACCELERATE))
{ {
aimingcompare = 0; aimingcompare = 0;
} }
// 2.3 - also allow tricking with the Spindash button
else if (!G_CompatLevel(0x000C) && ((buttons & BT_SPINDASHMASK) == BT_SPINDASHMASK))
{
player->pflags |= PF_NOFASTFALL;
}
} }
// Uses cmd->turning over steering intentionally. // Uses cmd->turning over steering intentionally.
@ -13877,9 +13889,22 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
} }
else else
{ {
if ((player->pflags & PF_TRICKDELAY) && !(player->cmd.buttons & BT_ACCELERATE) && (player->tricktime >= TRICKDELAY)) if (G_CompatLevel(0x000C))
{ {
player->pflags &= ~PF_TRICKDELAY; if ((player->pflags & PF_TRICKDELAY) && !(player->cmd.buttons & BT_ACCELERATE) && (player->tricktime >= TRICKDELAY))
{
player->pflags &= ~PF_TRICKDELAY;
}
}
else
// 2.3 - Spindash to trick
{
// Ignore pre-existing Accel inputs if not pressing Spindash. Always ignore pre-existing Spindash inputs to prevent accidental tricking.
if ((player->pflags & PF_TRICKDELAY) && (!(player->cmd.buttons & BT_ACCELERATE) || (((player->cmd.buttons & BT_SPINDASHMASK) == BT_SPINDASHMASK) && (player->oldcmd.buttons & BT_SPINDASHMASK) != BT_SPINDASHMASK)) && (player->tricktime >= TRICKDELAY))
{
player->pflags &= ~PF_TRICKDELAY;
player->pflags |= PF_NOFASTFALL;
}
} }
} }

View file

@ -138,7 +138,7 @@ INT16 K_PowerLevelPlacementScore(player_t *player)
INT16 K_CalculatePowerLevelAvg(void) INT16 K_CalculatePowerLevelAvg(void)
{ {
fixed_t avg = 0; INT32 avg = 0;
UINT8 div = 0; UINT8 div = 0;
SINT8 t = PWRLV_DISABLED; SINT8 t = PWRLV_DISABLED;
UINT8 i; UINT8 i;
@ -166,7 +166,7 @@ INT16 K_CalculatePowerLevelAvg(void)
|| clientpowerlevels[i][t] == 0) // splitscreen player || clientpowerlevels[i][t] == 0) // splitscreen player
continue; continue;
avg += (clientpowerlevels[i][t] << FRACBITS); avg += clientpowerlevels[i][t];
div++; div++;
} }
@ -178,7 +178,7 @@ INT16 K_CalculatePowerLevelAvg(void)
avg /= div; avg /= div;
return (INT16)(avg >> FRACBITS); return (INT16)avg;
} }
void K_UpdatePowerLevels(player_t *player, UINT8 lap, boolean forfeit) void K_UpdatePowerLevels(player_t *player, UINT8 lap, boolean forfeit)

View file

@ -157,7 +157,7 @@ void M_AddonsRefresh(void)
else if (majormods && !prevmajormods) else if (majormods && !prevmajormods)
{ {
S_StartSound(NULL, sfx_s221); S_StartSound(NULL, sfx_s221);
message = va("%c%s\x80\nYou've loaded a gameplay-modifying addon.\n\nRecord Attack has been disabled, but you\ncan still play alone in local Multiplayer.\n\nIf you wish to play Record Attack mode, restart the game to disable loaded addons.\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname); message = va("%c%s\x80\nYou've loaded a gameplay-modifying addon.\nCheck the console log for more info.\n", ('\x80' + (highlightflags>>V_CHARCOLORSHIFT)), refreshdirname);
prevmajormods = majormods; prevmajormods = majormods;
} }

View file

@ -59,11 +59,12 @@ void Obj_InstaWhipThink (mobj_t *whip)
void Obj_SpawnInstaWhipRecharge(player_t *player, angle_t angleOffset) void Obj_SpawnInstaWhipRecharge(player_t *player, angle_t angleOffset)
{ {
mobj_t *x = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_INSTAWHIP_RECHARGE); mobj_t *x = P_SpawnMobjFromMobj(player->mo, 0, 0, player->mo->height / 2, MT_INSTAWHIP_RECHARGE);
// This was previously used to delay the visual, back when this was VFX for a cooldown // This was previously used to delay the visual, back when this was VFX for a cooldown
// instead of VFX for a charge. We want to instantly bail out of that state now. // instead of VFX for a charge. We want to instantly bail out of that state now.
x->tics = 1; x->tics = 1;
x->eflags &= ~MFE_VERTICALFLIP; // Fix the visual being misaligned.
x->renderflags |= RF_SLOPESPLAT | RF_NOSPLATBILLBOARD; x->renderflags |= RF_SLOPESPLAT | RF_NOSPLATBILLBOARD;
P_SetTarget(&recharge_target(x), player->mo); P_SetTarget(&recharge_target(x), player->mo);
@ -81,7 +82,8 @@ void Obj_InstaWhipRechargeThink(mobj_t *x)
} }
P_MoveOrigin(x, target->x, target->y, target->z + (target->height / 2)); P_MoveOrigin(x, target->x, target->y, target->z + (target->height / 2));
P_InstaScale(x, 2 * target->scale); if (x->scale != target->scale * 2)
P_InstaScale(x, target->scale * 2);
x->angle = target->angle + recharge_offset(x); x->angle = target->angle + recharge_offset(x);
// Flickers every other frame // Flickers every other frame
@ -91,6 +93,10 @@ void Obj_InstaWhipRechargeThink(mobj_t *x)
void Obj_SpawnInstaWhipReject(player_t *player) void Obj_SpawnInstaWhipReject(player_t *player)
{ {
mobj_t *x = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_INSTAWHIP_REJECT); mobj_t *x = P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_INSTAWHIP_REJECT);
x->eflags &= ~MFE_VERTICALFLIP;
// Fixes an issue with gravflip misplacing the object for the first tic.
if (player->mo->eflags & MFE_VERTICALFLIP)
P_SetOrigin(x, player->mo->x, player->mo->y, player->mo->z);
P_SetTarget(&recharge_target(x), player->mo); P_SetTarget(&recharge_target(x), player->mo);
} }

View file

@ -2220,7 +2220,7 @@ static INT16 P_FindClosestTurningForAngle(player_t *player, INT32 targetAngle, I
// Slightly frumpy binary search for the ideal turning input. // Slightly frumpy binary search for the ideal turning input.
// We do this instead of reversing K_GetKartTurnValue so that future handling changes are automatically accounted for. // We do this instead of reversing K_GetKartTurnValue so that future handling changes are automatically accounted for.
while (attempts++ < 20) // Practical calls of this function search maximum 10 times, this is solely for safety. while (attempts++ < 20) // Practical calls of this function search maximum 10 times, this is solely for safety.
{ {
// These need to be treated as signed, or situations where boundaries straddle 0 are a mess. // These need to be treated as signed, or situations where boundaries straddle 0 are a mess.
@ -2341,7 +2341,7 @@ static void P_UpdatePlayerAngle(player_t *player)
// Corrections via fake turn go through easing. // Corrections via fake turn go through easing.
// That means undoing them takes the same amount of time as doing them. // That means undoing them takes the same amount of time as doing them.
// This can lead to oscillating death spiral states on a multi-tic correction, as we swing past the target angle. // This can lead to oscillating death spiral states on a multi-tic correction, as we swing past the target angle.
// So before we go into death-spirals, if our predicton is _almost_ right... // So before we go into death-spirals, if our predicton is _almost_ right...
angle_t leniency_base; angle_t leniency_base;
if (G_CompatLevel(0x000A)) if (G_CompatLevel(0x000A))
{ {
@ -2450,7 +2450,7 @@ void P_MovePlayer(player_t *player)
////////////////////// //////////////////////
P_UpdatePlayerAngle(player); P_UpdatePlayerAngle(player);
ticruned++; ticruned++;
if (!(cmd->flags & TICCMD_RECEIVED)) if (!(cmd->flags & TICCMD_RECEIVED))
ticmiss++; ticmiss++;
@ -4255,7 +4255,7 @@ void P_PlayerThink(player_t *player)
} }
else if (cmd->buttons & BT_ACCELERATE) else if (cmd->buttons & BT_ACCELERATE)
{ {
if (!player->exiting && !(player->oldcmd.buttons & BT_ACCELERATE)) if (!player->exiting && !(player->oldcmd.buttons & BT_ACCELERATE) && ((cmd->buttons & BT_SPINDASHMASK) != BT_SPINDASHMASK) && player->trickpanel != TRICKSTATE_READY)
{ {
player->kickstartaccel = 0; player->kickstartaccel = 0;
} }
@ -4550,7 +4550,7 @@ void P_PlayerThink(player_t *player)
{ {
player->stairjank--; player->stairjank--;
} }
// Random skin / "ironman" // Random skin / "ironman"
{ {
UINT32 skinflags = (demo.playback) UINT32 skinflags = (demo.playback)