Merge remote-tracking branch 'origin/master' into frey

This commit is contained in:
AJ Martinez 2024-03-05 01:29:21 -07:00
commit 01bab662c5
36 changed files with 270 additions and 165 deletions

View file

@ -579,7 +579,7 @@ target_compile_definitions(SRB2SDL2 PRIVATE -DCMAKECONFIG)
# Misc. build options from Makefiles
if(SRB2_CONFIG_DEBUGMODE)
target_compile_definitions(SRB2SDL2 PRIVATE -DZDEBUG -DPARANOIA -DRANGECHECK -DPACKETDROP)
target_compile_definitions(SRB2SDL2 PRIVATE -DZDEBUG -DPARANOIA -DPACKETDROP)
endif()
if(SRB2_CONFIG_TESTERS)
target_compile_definitions(SRB2SDL2 PRIVATE -DTESTERS)

View file

@ -301,10 +301,7 @@ consvar_t cv_addons_search_case = Player("addons_search_case", "No").yes_no();
consvar_t cv_addons_search_type = Player("addons_search_type", "Anywhere").values({{0, "Start"}, {1, "Anywhere"}});
consvar_t cv_addons_showall = Player("addons_showall", "No").yes_no();
consvar_t cv_allowguests = Player("allowguests", "On").on_off();
void AltTitle_OnChange(void);
consvar_t cv_alttitle = Player("alttitle", "Off").flags(CV_NOSHOWHELP).on_off().onchange_noinit(AltTitle_OnChange);
consvar_t cv_alttitle = Player("alttitle", "Off").on_off();
consvar_t cv_alwaysgrabmouse = GraphicsDriver("alwaysgrabmouse", "Off").on_off();
consvar_t cv_apng_delay = Player("apng_speed", "1x").values({

View file

@ -5920,9 +5920,9 @@ static void Local_Maketic(INT32 realtics)
INT32 i;
I_OsPolling(); // I_Getevent
D_ProcessEvents(); // menu responder, cons responder,
// game responder calls HU_Responder, AM_Responder,
// and G_MapEventsToControls
D_ProcessEvents(true); // menu responder, cons responder,
// game responder calls HU_Responder, AM_Responder,
// and G_MapEventsToControls
if (!dedicated) rendergametic = gametic;

View file

@ -264,7 +264,7 @@ void HandleGamepadDeviceEvents(event_t *ev)
// D_ProcessEvents
// Send all the events of the given timestamp down the responder chain
//
void D_ProcessEvents(void)
void D_ProcessEvents(boolean callresponders)
{
event_t *ev;
int i;
@ -298,6 +298,9 @@ void D_ProcessEvents(void)
// update keys current state
G_MapEventsToControls(ev);
if (!callresponders)
continue; // eat
// Menu input
#ifdef HAVE_THREADS
I_lock_mutex(&k_menu_mutex);

View file

@ -50,7 +50,7 @@ void D_PostEvent(const event_t *ev);
void D_PostEvent_end(void); // delimiter for locking memory
#endif
void D_ProcessEvents(void);
void D_ProcessEvents(boolean callresponders);
const char *D_Home(void);

View file

@ -5195,19 +5195,6 @@ FUNCNORETURN static ATTRNORETURN void Command_Quit_f(void)
I_Quit();
}
void AltTitle_OnChange(void)
{
if (!cv_alttitle.value)
return; // it's fine.
if (!M_SecretUnlocked(SECRET_ALTTITLE, true))
{
CONS_Printf(M_GetText("You haven't earned this yet.\n"));
CV_StealthSetValue(&cv_alttitle, 0);
return;
}
}
void ItemFinder_OnChange(void)
{
if (!cv_itemfinder.value)

View file

@ -110,7 +110,7 @@ typedef enum {
} capsuletest_val_t;
extern consvar_t cv_capsuletest;
extern consvar_t cv_alttitle, cv_itemfinder;
extern consvar_t cv_itemfinder;
extern consvar_t cv_inttime, cv_advancemap;
extern consvar_t cv_overtime;
@ -255,7 +255,6 @@ boolean IsPlayerAdmin(INT32 playernum);
void SetAdminPlayer(INT32 playernum);
void ClearAdminPlayers(void);
void RemoveAdminPlayer(INT32 playernum);
void AltTitle_OnChange(void);
void ItemFinder_OnChange(void);
void D_SetPassword(const char *pw);

View file

@ -67,12 +67,10 @@ extern "C" {
#if !defined (NDEBUG)
#define PACKETDROP
#define PARANOIA
//#define RANGECHECK
#define ZDEBUG
#endif
// Uncheck this to compile debugging code
#define RANGECHECK
//#ifndef PARANOIA
//#define PARANOIA // do some tests that never fail but maybe
// turn this on by make etc.. DEBUGMODE = 1 or use the Debug profile in the VC++ projects

View file

@ -1145,13 +1145,8 @@ static void F_CacheTitleScreen(void)
case TTMODE_RINGRACERS:
{
if (!M_SecretUnlocked(SECRET_ALTTITLE, true))
{
CV_StealthSetValue(&cv_alttitle, 0);
}
kts_bumper = W_CachePatchName(
(cv_alttitle.value ? "KTSJUMPR1" : "KTSBUMPR1"),
(M_UseAlternateTitleScreen() ? "KTSJUMPR1" : "KTSBUMPR1"),
PU_PATCH_LOWPRIORITY);
kts_eggman = W_CachePatchName("KTSEGG01", PU_PATCH_LOWPRIORITY);
kts_tails = W_CachePatchName("KTSTAL01", PU_PATCH_LOWPRIORITY);

View file

@ -494,11 +494,6 @@ void F_RunWipe(UINT8 wipemode, UINT8 wipetype, boolean drawMenu, const char *col
WipeInAction = true;
wipe_scr = screens[0];
// FIXME: Wipes SUCK and drop input events for some reason, causing stuck gamepad inputs.
// It's better to ignore an intentional hold than to turn a tap into a phantom hold.
// (If you're removing this, remove the one after the inner loop too!)
G_ResetAllDeviceGameKeyDown();
// lastwipetic should either be 0 or the tic we last wiped
// on for fade-to-black
for (;;)
@ -558,6 +553,12 @@ void F_RunWipe(UINT8 wipemode, UINT8 wipetype, boolean drawMenu, const char *col
}
I_OsPolling();
// The event buffer is rather small so we need to
// process these events immediately, to make sure
// inputs don't get stuck (would happen a lot with
// some controllers that send a lot of analog
// events).
D_ProcessEvents(false);
I_UpdateNoBlit();
if (drawMenu && rendermode != render_none)
@ -586,11 +587,6 @@ void F_RunWipe(UINT8 wipemode, UINT8 wipetype, boolean drawMenu, const char *col
WipeInAction = false;
// FIXME: Wipes SUCK and drop input events for some reason, causing stuck gamepad inputs.
// It's better to ignore an intentional hold than to turn a tap into a phantom hold.
// (If you're removing this, remove the one before the inner loop too!)
G_ResetAllDeviceGameKeyDown();
if (fcolor)
{
Z_Free(fcolor);

View file

@ -3588,6 +3588,14 @@ void G_AddGhost(savebuffer_t *buffer, const char *defdemoname)
if ((flags & DF_GRANDPRIX))
p += 3;
// Skip unlockables
{
UINT32 unlockables = READUINT32(p);
p += std::min<UINT32>(unlockables, MAXUNLOCKABLES);
}
p++; // mapmusrng
if (*p == DEMOMARKER)
{
CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Replay is empty.\n"), defdemoname);
@ -3803,6 +3811,14 @@ staffbrief_t *G_GetStaffGhostBrief(UINT8 *buffer)
if ((flags & DF_GRANDPRIX))
p += 3;
// Skip unlockables
{
UINT32 unlockables = READUINT32(p);
p += std::min<UINT32>(unlockables, MAXUNLOCKABLES);
}
p++; // mapmusrng
// Assert first player is in and then read name
if (READUINT8(p) != 0)
goto fail;

View file

@ -1191,8 +1191,10 @@ void G_DoLoadLevelEx(boolean resetplayer, gamestate_t newstate)
}
// clear cmd building stuff
G_ResetAllDeviceGameKeyDown();
G_ResetAllDeviceResponding();
// We don't clear them anymore, so you can buffer inputs
// on map change / map restart.
//G_ResetAllDeviceGameKeyDown();
//G_ResetAllDeviceResponding();
// clear hud messages remains (usually from game startup)
CON_ClearHUD();

View file

@ -4740,10 +4740,11 @@ static void HWR_ProjectSprite(mobj_t *thing)
tr_y = FIXED_TO_FLOAT(interp.y);
// decide which patch to use for sprite relative to player
#ifdef RANGECHECK
if ((unsigned)thing->sprite >= numsprites)
I_Error("HWR_ProjectSprite: invalid sprite number %i ", thing->sprite);
#endif
{
CONS_Debug(DBG_RENDER, "HWR_ProjectSprite: invalid sprite number %i\n", thing->sprite);
return;
}
rot = thing->frame&FF_FRAMEMASK;
@ -5184,22 +5185,20 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
// decide which patch to use for sprite relative to player
if ((unsigned)thing->sprite >= numsprites)
#ifdef RANGECHECK
I_Error("HWR_ProjectPrecipitationSprite: invalid sprite number %i ",
{
CONS_Debug(DBG_RENDER, "HWR_ProjectPrecipitationSprite: invalid sprite number %i\n",
thing->sprite);
#else
return;
#endif
}
sprdef = &sprites[thing->sprite];
if ((size_t)(thing->frame&FF_FRAMEMASK) >= sprdef->numframes)
#ifdef RANGECHECK
I_Error("HWR_ProjectPrecipitationSprite: invalid sprite frame %i : %i for %s",
{
CONS_Debug(DBG_RENDER, "HWR_ProjectPrecipitationSprite: invalid sprite frame %i : %i for %s\n",
thing->sprite, thing->frame, sprnames[thing->sprite]);
#else
return;
#endif
}
sprframe = &sprdef->spriteframes[ thing->frame & FF_FRAMEMASK];

View file

@ -319,6 +319,15 @@ void HU_Init(void)
PR ("PRFN");
REG;
DIM ('0', 10);
DIG (2);
PR ("ROLNUM");
REG;
PR ("RO4NUM");
REG;
DIG (3);
ADIM (KART);

View file

@ -80,6 +80,8 @@ enum
X (NIGHTSNUM),
X (PINGNUM),
X (PROFNUM),
X (ROLNUM),
X (RO4NUM),
X (KART),
X (TIMER),

View file

@ -1023,7 +1023,7 @@ static void F_DrawCreditsTitleDrop(void)
0, -BASEVIDHEIGHT * (FRACUNIT / 2),
FRACUNIT, 0,
static_cast<patch_t *>(W_CachePatchName(
(cv_alttitle.value ? "KTSJUMPR1" : "KTSBUMPR1"),
(M_UseAlternateTitleScreen() ? "KTSJUMPR1" : "KTSBUMPR1"),
PU_CACHE
)),
nullptr

View file

@ -1371,6 +1371,7 @@ static void K_drawKartItem(void)
// Set to 'no item' just in case.
const UINT8 offset = ((r_splitscreen > 1) ? 1 : 0);
patch_t *localpatch[3] = { kp_nodraw, kp_nodraw, kp_nodraw };
UINT8 localamt[3] = {0, 0, 0};
patch_t *localbg = ((offset) ? kp_itembg[2] : kp_itembg[0]);
patch_t *localinv = ((offset) ? kp_invincibility[((leveltime % (6*3)) / 3) + 7] : kp_invincibility[(leveltime % (7*3)) / 3]);
INT32 fx = 0, fy = 0, fflags = 0; // final coords for hud and flags...
@ -1403,14 +1404,19 @@ static void K_drawKartItem(void)
{
case KITEM_INVINCIBILITY:
localpatch[i] = localinv;
localamt[i] = amt;
break;
case KITEM_ORBINAUT:
localpatch[i] = kp_orbinaut[(offset ? 4 : std::min(amt-1, 3))];
if (amt > 4)
localamt[i] = amt;
break;
default:
localpatch[i] = K_GetCachedItemPatch(item, offset);
if (item != KITEM_BALLHOG || amt != 5)
localamt[i] = amt;
break;
}
}
@ -1586,25 +1592,35 @@ static void K_drawKartItem(void)
V_SLIDEIN|fflags
);
V_DrawFixedPatch(
fx<<FRACBITS, (fy<<FRACBITS) + rouletteOffset + rouletteSpace,
FRACUNIT, V_HUDTRANS|V_SLIDEIN|fflags,
localpatch[0], (localcolor[0] ? R_GetTranslationColormap(colormode[0], localcolor[0], GTC_CACHE) : NULL)
);
V_DrawFixedPatch(
fx<<FRACBITS, (fy<<FRACBITS) + rouletteOffset - rouletteSpace,
FRACUNIT, V_HUDTRANS|V_SLIDEIN|fflags,
localpatch[2], (localcolor[2] ? R_GetTranslationColormap(colormode[2], localcolor[2], GTC_CACHE) : NULL)
);
auto draw_item = [&](fixed_t y, int i)
{
const UINT8 *colormap = (localcolor[i] ? R_GetTranslationColormap(colormode[i], localcolor[i], GTC_CACHE) : NULL);
V_DrawFixedPatch(
fx<<FRACBITS, (fy<<FRACBITS) + rouletteOffset + y,
FRACUNIT, V_HUDTRANS|V_SLIDEIN|fflags,
localpatch[i], colormap
);
if (localamt[i] > 1)
{
using srb2::Draw;
Draw(
fx + rouletteCrop.x + FixedToFloat(rouletteSpace/2),
fy + rouletteCrop.y + FixedToFloat(rouletteOffset + y + rouletteSpace) - (r_splitscreen > 1 ? 15 : 33))
.font(r_splitscreen > 1 ? Draw::Font::kRollingNum4P : Draw::Font::kRollingNum)
.align(Draw::Align::kCenter)
.flags(V_HUDTRANS|V_SLIDEIN|fflags)
.colormap(colormap)
.text("{}", localamt[i]);
}
};
draw_item(rouletteSpace, 0);
draw_item(-rouletteSpace, 2);
if (stplyr->itemRoulette.active == true)
{
// Draw the item underneath the box.
V_DrawFixedPatch(
fx<<FRACBITS, (fy<<FRACBITS) + rouletteOffset,
FRACUNIT, V_HUDTRANS|V_SLIDEIN|fflags,
localpatch[1], (localcolor[1] ? R_GetTranslationColormap(colormode[1], localcolor[1], GTC_CACHE) : NULL)
);
draw_item(0, 1);
V_ClearClipRect();
}
else
@ -1987,8 +2003,13 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT32 splitflags, U
}
}
workx -= V_ThinStringWidth(stickermedalinfo.targettext, splitflags);
V_DrawThinString(workx, worky, splitflags, stickermedalinfo.targettext);
using srb2::Draw;
Draw::TextElement text(stickermedalinfo.targettext);
text.flags(splitflags);
text.font(Draw::Font::kZVote);
workx -= text.width();
Draw(workx, worky).text(text);
}
workx -= (6 + (i*5));
@ -5953,11 +5974,19 @@ void K_drawKartHUD(void)
{
// Draw the timestamp
if (LUA_HudEnabled(hud_time))
K_drawKartTimestamp(stplyr->realtime,
TIME_X,
TIME_Y,
V_HUDTRANS|V_SLIDEIN|V_SNAPTOTOP|V_SNAPTORIGHT,
0);
{
bool ta = modeattacking && !demo.playback;
INT32 flags = V_HUDTRANS|V_SLIDEIN|V_SNAPTOTOP|V_SNAPTORIGHT;
K_drawKartTimestamp(stplyr->realtime, TIME_X, TIME_Y + (ta ? 2 : 0), flags, 0);
if (ta)
{
using srb2::Draw;
Draw(BASEVIDWIDTH - 19, 2)
.flags(flags | V_YELLOWMAP)
.align(Draw::Align::kRight)
.text("\xBE Restart");
}
}
islonesome = K_drawKartPositionFaces();
}
@ -5998,7 +6027,7 @@ void K_drawKartHUD(void)
if (demo.attract == DEMO_ATTRACT_TITLE) // Draw logo on title screen demos
{
INT32 x = BASEVIDWIDTH - 8, y = BASEVIDHEIGHT-8, snapflags = V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_SLIDEIN;
patch_t *pat = static_cast<patch_t*>(W_CachePatchName((cv_alttitle.value ? "MTSJUMPR1" : "MTSBUMPR1"), PU_CACHE));
patch_t *pat = static_cast<patch_t*>(W_CachePatchName((M_UseAlternateTitleScreen() ? "MTSJUMPR1" : "MTSBUMPR1"), PU_CACHE));
if (r_splitscreen == 3)
{

View file

@ -232,6 +232,8 @@ private:
case MT_BATTLEUFO_SPAWNER:
case MT_WAYPOINT:
case MT_BUBBLESHIELDTRAP:
case MT_GARDENTOP:
return {};
default:
@ -341,11 +343,36 @@ bool is_object_tracking_target(const mobj_t* mobj)
case MT_WAYPOINT:
return cv_kartdebugwaypoints.value;
case MT_BUBBLESHIELDTRAP:
return mobj->tracer && !P_MobjWasRemoved(mobj->tracer)
&& mobj->tracer->player && P_IsDisplayPlayer(mobj->tracer->player)
&& mobj->tracer->player == &players[displayplayers[R_GetViewNumber()]];
case MT_GARDENTOP:
return mobj->tracer && !P_MobjWasRemoved(mobj->tracer)
&& mobj->tracer->player && P_IsDisplayPlayer(mobj->tracer->player)
&& mobj->tracer->player == &players[displayplayers[R_GetViewNumber()]]
&& Obj_GardenTopPlayerNeedsHelp(mobj);
default:
return false;
}
}
bool can_object_be_offscreen(const mobj_t* mobj)
{
switch (mobj->type)
{
// You can see this, you fucking liar
case MT_GARDENTOP:
case MT_BUBBLESHIELDTRAP:
return false;
default:
return true;
}
}
Visibility is_object_visible(const mobj_t* mobj)
{
switch (mobj->type)
@ -381,7 +408,7 @@ void K_DrawTargetTracking(const TargetTracking& target)
const trackingResult_t& result = target.result;
int32_t timer = 0;
if (result.onScreen == false)
if (can_object_be_offscreen(target.mobj) && result.onScreen == false)
{
// Off-screen, draw alongside the borders of the screen.
// Probably the most complicated thing.
@ -578,7 +605,9 @@ void K_DrawTargetTracking(const TargetTracking& target)
.align(Draw::Align::kCenter);
};
switch (target.mobj->type) // debug
srb2::Draw::Font splitfont = (r_splitscreen > 1) ? Draw::Font::kThin : Draw::Font::kMenu;
switch (target.mobj->type)
{
case MT_BATTLEUFO_SPAWNER:
debug().text("BUFO ID: {}", Obj_BattleUFOSpawnerID(target.mobj));
@ -592,6 +621,21 @@ void K_DrawTargetTracking(const TargetTracking& target)
}
break;
case MT_BUBBLESHIELDTRAP:
Draw(FixedToFloat(result.x), FixedToFloat(result.y))
.flags(V_SPLITSCREEN)
.font(Draw::Font::kMenu)
.align(Draw::Align::kCenter)
.text(((leveltime/3)%2) ? "\xB3 " : " \xB2");
break;
case MT_GARDENTOP:
Draw(FixedToFloat(result.x), FixedToFloat(result.y))
.flags(V_SPLITSCREEN)
.font(splitfont)
.align(Draw::Align::kCenter)
.text("Try \xA7!");
default:
break;
}

View file

@ -7014,7 +7014,7 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
{
x = 8;
y = BASEVIDHEIGHT-16;
V_DrawGamemodeString(x, y - 33, 0, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_PLAGUE, GTC_MENUCACHE), cv_alttitle.string);
V_DrawGamemodeString(x, y - 33, 0, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_PLAGUE, GTC_MENUCACHE), M_UseAlternateTitleScreen() ? "On" : "Off");
K_drawButtonAnim(x, y, 0, kp_button_a[1], challengesmenu.ticker);
x += SHORT(kp_button_a[1][0]->width);
@ -8202,7 +8202,7 @@ void M_DrawWrongWarp(void)
titleoffset += titlewidth;
}
patch_t *bumper = W_CachePatchName((cv_alttitle.value ? "MTSJUMPR1" : "MTSBUMPR1"), PU_CACHE);
patch_t *bumper = W_CachePatchName((M_UseAlternateTitleScreen() ? "MTSJUMPR1" : "MTSBUMPR1"), PU_CACHE);
V_DrawScaledPatch(x-(SHORT(bumper->width)), (BASEVIDHEIGHT-8)-(SHORT(bumper->height)), 0, bumper);
}

View file

@ -27,6 +27,7 @@ void Obj_GardenTopThink(mobj_t *top);
void Obj_GardenTopSparkThink(mobj_t *spark);
void Obj_GardenTopArrowThink(mobj_t *arrow);
boolean Obj_GardenTopPlayerIsGrinding(const player_t *player);
boolean Obj_GardenTopPlayerNeedsHelp(const mobj_t *top);
/* Shrink */
void Obj_PohbeeThinker(mobj_t *pohbee);

View file

@ -3758,3 +3758,9 @@ const char *M_GetEmblemPatch(emblem_t *em, boolean big)
return pnamebuf;
}
boolean M_UseAlternateTitleScreen(void)
{
extern consvar_t cv_alttitle;
return cv_alttitle.value && M_SecretUnlocked(SECRET_ALTTITLE, true);
}

View file

@ -494,6 +494,8 @@ UINT16 M_EmblemMapNum(emblem_t *emblem);
#define M_Achieved(a) ((a) >= MAXCONDITIONSETS || gamedata->achieved[a])
boolean M_UseAlternateTitleScreen(void);
#ifdef __cplusplus
} // extern "C"
#endif

View file

@ -1027,11 +1027,13 @@ boolean M_ChallengesInputs(INT32 ch)
{
switch (unlockables[challengesmenu.currentunlock].type)
{
case SECRET_ALTTITLE:
case SECRET_ALTTITLE: {
extern consvar_t cv_alttitle;
CV_AddValue(&cv_alttitle, 1);
S_StartSound(NULL, sfx_s3kc3s);
M_SetMenuDelay(pid);
break;
}
default:
break;
}

View file

@ -19,6 +19,22 @@ menuitem_t OPTIONS_Server[] =
NULL, {.cvar = &cv_advertise}, 0, 0},
{IT_HEADER, "Players...", NULL,
NULL, {NULL}, 0, 0},
{IT_STRING | IT_CVAR, "Maximum Players", "How many players can play at once.",
NULL, {.cvar = &cv_maxplayers}, 0, 0},
{IT_STRING | IT_CVAR, "Maximum Connections", "How many players & spectators can connect to the server.",
NULL, {.cvar = &cv_maxconnections}, 0, 0},
{IT_STRING | IT_CVAR, "CPU Difficulty", "Bots can fill unused slots. How strong should they be?",
NULL, {.cvar = &cv_kartbot}, 0, 0},
{IT_STRING | IT_CVAR, "Use PWR.LV", "Set whether players should be rated on their performance.",
NULL, {.cvar = &cv_kartusepwrlv}, 0, 0},
{IT_HEADER, "Progression...", NULL,
NULL, {NULL}, 0, 0},
@ -32,15 +48,9 @@ menuitem_t OPTIONS_Server[] =
NULL, {.cvar = &cv_votetime}, 0, 0},
{IT_HEADER, "Joining...", NULL,
{IT_HEADER, "Permissions...", NULL,
NULL, {NULL}, 0, 0},
{IT_STRING | IT_CVAR, "Maximum Players", "How many players can play at once.",
NULL, {.cvar = &cv_maxplayers}, 0, 0},
{IT_STRING | IT_CVAR, "Maximum Connections", "How many players & spectators can connect to the server.",
NULL, {.cvar = &cv_maxconnections}, 0, 0},
{IT_STRING | IT_CVAR, "Allow Joining", "Sets whether players can connect to your server.",
NULL, {.cvar = &cv_allownewplayer}, 0, 0},
@ -60,8 +70,7 @@ menuitem_t OPTIONS_Server[] =
{IT_STRING | IT_CVAR, "Chat Spam Protection", "Prevents too many message from a single player.",
NULL, {.cvar = &cv_chatspamprotection}, 0, 0},
{IT_SPACE | IT_DYBIGSPACE, NULL, NULL,
{IT_HEADER, "Advanced...", NULL,
NULL, {NULL}, 0, 0},
{IT_STRING | IT_SUBMENU, "Advanced...", "Advanced options. Be careful when messing with these!",

View file

@ -747,7 +747,9 @@ void M_LevelSelected(INT16 add, boolean menuupdate)
SV_StartSinglePlayerServer(levellist.newgametype, levellist.netgame);
CV_StealthSet(&cv_kartbot, cv_dummymatchbots.string);
if (!levellist.netgame)
CV_StealthSet(&cv_kartbot, cv_dummymatchbots.string);
CV_StealthSet(&cv_kartencore, (cv_dummygpencore.value == 1) ? "On" : "Auto");
CV_StealthSet(&cv_kartspeed, (cv_dummykartspeed.value == KARTSPEED_NORMAL) ? "Auto" : cv_dummykartspeed.string);

View file

@ -47,6 +47,8 @@ enum {
#define top_waveangle(o) ((o)->movedir)
/* wavepause will take mobjinfo reactiontime automatically */
#define top_wavepause(o) ((o)->reactiontime)
#define top_helpme(o) ((o)->cusval)
#define top_lifetime(o) ((o)->cvmem)
#define spark_top(o) ((o)->target)
#define spark_angle(o) ((o)->movedir)
@ -133,6 +135,8 @@ init_top
top_float(top) = 0;
top_sound(top) = sfx_None;
top_waveangle(top) = 0;
top_helpme(top) = (mode == TOP_ANCHORED) ? 1 : 0;
top_lifetime(top) = 0;
}
static void
@ -191,6 +195,8 @@ spawn_grind_spark (mobj_t *top)
player = get_rider_player(rider);
}
top_helpme(top) = 0;
spark = P_SpawnMobjFromMobj(
top, x, y, 0, MT_DRIFTSPARK);
@ -432,6 +438,8 @@ anchor_top (mobj_t *top)
top->momy = 0;
top->momz = rider->momz;
top_lifetime(top)++;
/* The Z momentum can put the Top slightly ahead of the
player in that axis too. It looks cool if the Top
falls below you but not if it bounces up. */
@ -687,3 +695,11 @@ Obj_GardenTopPlayerIsGrinding (const player_t *player)
return top ? is_top_grinding(top) : false;
}
boolean
Obj_GardenTopPlayerNeedsHelp (const mobj_t *top)
{
if (top && top_mode(top) != TOP_ANCHORED)
return false;
return top ? (top_helpme(top) || top_lifetime(top) < 3*TICRATE) : false;
}

View file

@ -634,6 +634,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
P_SetTarget(&special->tracer, toucher);
toucher->flags |= MF_NOGRAVITY;
toucher->momz = (8*toucher->scale) * P_MobjFlip(toucher);
// Snap to the unfortunate player and quit moving laterally, or we can end up quite far away
special->momx = 0;
special->momy = 0;
special->x = toucher->x;
special->y = toucher->y;
special->z = toucher->z;
S_StartSound(toucher, sfx_s1b2);
return;
@ -3114,8 +3122,6 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
source->player->invincibilityextensions++;
source->player->invincibilitytimer += kinvextend;
// This has a scaling boost type now, don't let it get too crazy
source->player->invincibilitytimer = min(source->player->invincibilitytimer, 20*TICRATE);
if (P_IsDisplayPlayer(source->player))
S_StartSound(NULL, sfx_gsha7);

View file

@ -5359,6 +5359,12 @@ static boolean P_IsTrackerType(INT32 type)
case MT_WAYPOINT: // debug
return true;
case MT_BUBBLESHIELDTRAP: // Mash prompt
return true;
case MT_GARDENTOP: // Frey
return true;
default:
return false;
}

View file

@ -1427,15 +1427,11 @@ void T_PolyObjRotate(polyrotate_t *th)
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
if (!po)
#ifdef RANGECHECK
I_Error("T_PolyObjRotate: thinker has invalid id %d\n", th->polyObjNum);
#else
{
CONS_Debug(DBG_POLYOBJ, "T_PolyObjRotate: thinker with invalid id %d removed.\n", th->polyObjNum);
P_RemoveThinker(&th->thinker);
return;
}
#endif
// check for displacement due to override and reattach when possible
if (po->thinker == NULL)
@ -1508,15 +1504,11 @@ void T_PolyObjMove(polymove_t *th)
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
if (!po)
#ifdef RANGECHECK
I_Error("T_PolyObjMove: thinker has invalid id %d\n", th->polyObjNum);
#else
{
CONS_Debug(DBG_POLYOBJ, "T_PolyObjMove: thinker with invalid id %d removed.\n", th->polyObjNum);
P_RemoveThinker(&th->thinker);
return;
}
#endif
// check for displacement due to override and reattach when possible
if (po->thinker == NULL)
@ -1598,15 +1590,11 @@ void T_PolyObjWaypoint(polywaypoint_t *th)
fixed_t speed = th->speed;
if (!po)
#ifdef RANGECHECK
I_Error("T_PolyObjWaypoint: thinker has invalid id %d\n", th->polyObjNum);
#else
{
CONS_Debug(DBG_POLYOBJ, "T_PolyObjWaypoint: thinker with invalid id %d removed.", th->polyObjNum);
P_RemoveThinker(&th->thinker);
return;
}
#endif
// check for displacement due to override and reattach when possible
if (!po->thinker)
@ -1714,15 +1702,11 @@ void T_PolyDoorSlide(polyslidedoor_t *th)
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
if (!po)
#ifdef RANGECHECK
I_Error("T_PolyDoorSlide: thinker has invalid id %d\n", th->polyObjNum);
#else
{
CONS_Debug(DBG_POLYOBJ, "T_PolyDoorSlide: thinker with invalid id %d removed.\n", th->polyObjNum);
P_RemoveThinker(&th->thinker);
return;
}
#endif
// check for displacement due to override and reattach when possible
if (po->thinker == NULL)
@ -1819,15 +1803,11 @@ void T_PolyDoorSwing(polyswingdoor_t *th)
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
if (!po)
#ifdef RANGECHECK
I_Error("T_PolyDoorSwing: thinker has invalid id %d\n", th->polyObjNum);
#else
{
CONS_Debug(DBG_POLYOBJ, "T_PolyDoorSwing: thinker with invalid id %d removed.\n", th->polyObjNum);
P_RemoveThinker(&th->thinker);
return;
}
#endif
// check for displacement due to override and reattach when possible
if (po->thinker == NULL)
@ -1918,15 +1898,11 @@ void T_PolyObjDisplace(polydisplace_t *th)
fixed_t dx, dy;
if (!po)
#ifdef RANGECHECK
I_Error("T_PolyObjDisplace: thinker has invalid id %d\n", th->polyObjNum);
#else
{
CONS_Debug(DBG_POLYOBJ, "T_PolyObjDisplace: thinker with invalid id %d removed.\n", th->polyObjNum);
P_RemoveThinker(&th->thinker);
return;
}
#endif
// check for displacement due to override and reattach when possible
if (po->thinker == NULL)
@ -1958,15 +1934,11 @@ void T_PolyObjRotDisplace(polyrotdisplace_t *th)
fixed_t rotangle;
if (!po)
#ifdef RANGECHECK
I_Error("T_PolyObjRotDisplace: thinker has invalid id %d\n", th->polyObjNum);
#else
{
CONS_Debug(DBG_POLYOBJ, "T_PolyObjRotDisplace: thinker with invalid id %d removed.\n", th->polyObjNum);
P_RemoveThinker(&th->thinker);
return;
}
#endif
// check for displacement due to override and reattach when possible
if (po->thinker == NULL)
@ -2442,15 +2414,11 @@ void T_PolyObjFlag(polymove_t *th)
size_t i;
if (!po)
#ifdef RANGECHECK
I_Error("T_PolyObjFlag: thinker has invalid id %d\n", th->polyObjNum);
#else
{
CONS_Debug(DBG_POLYOBJ, "T_PolyObjFlag: thinker with invalid id %d removed.\n", th->polyObjNum);
P_RemoveThinker(&th->thinker);
return;
}
#endif
// check for displacement due to override and reattach when possible
if (po->thinker == NULL)
@ -2549,15 +2517,11 @@ void T_PolyObjFade(polyfade_t *th)
polyobj_t *po = Polyobj_GetForNum(th->polyObjNum);
if (!po)
#ifdef RANGECHECK
I_Error("T_PolyObjFade: thinker has invalid id %d\n", th->polyObjNum);
#else
{
CONS_Debug(DBG_POLYOBJ, "T_PolyObjFade: thinker with invalid id %d removed.\n", th->polyObjNum);
P_RemoveThinker(&th->thinker);
return;
}
#endif
// check for displacement due to override and reattach when possible
if (po->thinker == NULL)

View file

@ -469,10 +469,11 @@ static boolean P_CrossSubsector(size_t num, register los_t *los, register los_fu
seg_t *seg;
INT32 count;
#ifdef RANGECHECK
if (num >= numsubsectors)
I_Error("P_CrossSubsector: ss %s with numss = %s\n", sizeu1(num), sizeu2(numsubsectors));
#endif
{
CONS_Debug(DBG_RENDER, "P_CrossSubsector: ss %s with numss = %s\n", sizeu1(num), sizeu2(numsubsectors));
return true;
}
// haleyjd 02/23/06: this assignment should be after the above check
seg = segs + subsectors[num].firstline;

View file

@ -909,14 +909,12 @@ static void R_Subsector(size_t num)
ZoneScoped;
#ifdef RANGECHECK
if (num >= numsubsectors)
I_Error("R_Subsector: ss %s with numss = %s\n", sizeu1(num), sizeu2(numsubsectors));
#endif
// subsectors added at run-time
if (num >= numsubsectors)
{
CONS_Debug(DBG_RENDER, "R_Subsector: ss %s with numss = %s\n", sizeu1(num), sizeu2(numsubsectors));
return;
}
sub = &subsectors[num];
frontsector = sub->sector;

View file

@ -105,12 +105,10 @@ static void R_DrawColumnTemplate(drawcolumndata_t *dc)
return;
}
#ifdef RANGECHECK
if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height)
{
return;
}
#endif
if constexpr (Type & DrawColumnType::DC_LIGHTLIST)
{
@ -341,10 +339,8 @@ void R_DrawFogColumn(drawcolumndata_t *dc)
if (count < 0)
return;
#ifdef RANGECHECK
if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height)
return;
#endif
// Framebuffer destination address.
// Use ylookup LUT to avoid multiply with ScreenWidth.
@ -408,10 +404,8 @@ void R_DrawColumn_Flat(drawcolumndata_t *dc)
if (count < 0) // Zero length, column does not exceed a pixel.
return;
#ifdef RANGECHECK
if ((unsigned)dc->x >= (unsigned)vid.width || dc->yl < 0 || dc->yh >= vid.height)
return;
#endif
// Framebuffer destination address.
// Use ylookup LUT to avoid multiply with ScreenWidth.

View file

@ -1073,9 +1073,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
}
else if (vis->cut & SC_SHEAR)
{
#ifdef RANGECHECK
pwidth = patch->width;
#endif
// Vertically sheared sprite
for (dc.x = vis->x1; dc.x <= vis->x2; dc.x++, frac += vis->xiscale, dc.texturemid -= vis->shear.tan)
@ -1093,7 +1091,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
else
{
#ifdef RANGECHECK
#if 0
if (vis->x1test && vis->x2test)
{
INT32 x1test = vis->x1test;
@ -1112,7 +1110,7 @@ static void R_DrawVisSprite(vissprite_t *vis)
CONS_Printf("THE GAME WOULD HAVE CRASHED, %d (old) vs %d (new)\n", (x2test - x1test), (vis->x2 - vis->x1));
}
}
#endif // RANGECHECK
#endif
// Non-paper drawing loop
for (dc.x = vis->x1; dc.x <= vis->x2; dc.x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan)
@ -1191,10 +1189,11 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis)
{
texturecolumn = frac>>FRACBITS;
#ifdef RANGECHECK
if (texturecolumn < 0 || texturecolumn >= patch->width)
I_Error("R_DrawPrecipitationSpriteRange: bad texturecolumn");
#endif
{
CONS_Debug(DBG_RENDER, "R_DrawPrecipitationSpriteRange: bad texturecolumn\n");
break;
}
column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn]));
@ -1832,10 +1831,11 @@ static void R_ProjectSprite(mobj_t *thing)
sortscale = FixedDiv(projectiony[viewssnum], tz);
// decide which patch to use for sprite relative to player
#ifdef RANGECHECK
if ((size_t)(thing->sprite) >= numsprites)
I_Error("R_ProjectSprite: invalid sprite number %d ", thing->sprite);
#endif
{
CONS_Debug(DBG_RENDER, "R_ProjectSprite: invalid sprite number %d\n", thing->sprite);
return;
}
frame = thing->frame&FF_FRAMEMASK;
@ -2634,19 +2634,21 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
yscale = FixedDiv(projectiony[viewssnum], tz);
// decide which patch to use for sprite relative to player
#ifdef RANGECHECK
if ((unsigned)thing->sprite >= numsprites)
I_Error("R_ProjectPrecipitationSprite: invalid sprite number %d ",
{
CONS_Debug(DBG_RENDER, "R_ProjectPrecipitationSprite: invalid sprite number %d\n",
thing->sprite);
#endif
return;
}
sprdef = &sprites[thing->sprite];
#ifdef RANGECHECK
if ((UINT8)(thing->frame&FF_FRAMEMASK) >= sprdef->numframes)
I_Error("R_ProjectPrecipitationSprite: invalid sprite frame %d : %d for %s",
{
CONS_Debug(DBG_RENDER, "R_ProjectPrecipitationSprite: invalid sprite frame %d : %d for %s\n",
thing->sprite, thing->frame, sprnames[thing->sprite]);
#endif
return;
}
sprframe = &sprdef->spriteframes[thing->frame & FF_FRAMEMASK];

View file

@ -308,6 +308,12 @@ int Draw::font_to_fontno(Font font)
case Font::kMedium:
return MED_FONT;
case Font::kRollingNum:
return ROLNUM_FONT;
case Font::kRollingNum4P:
return RO4NUM_FONT;
}
return TINY_FONT;

View file

@ -41,6 +41,8 @@ public:
kThinTimer,
kMenu,
kMedium,
kRollingNum,
kRollingNum4P,
};
enum class Align

View file

@ -987,10 +987,8 @@ void V_DrawBlock(INT32 x, INT32 y, INT32 scrn, INT32 width, INT32 height, const
UINT8 *dest;
const UINT8 *deststop;
#ifdef RANGECHECK
if (x < 0 || x + width > vid.width || y < 0 || y + height > vid.height || (unsigned)scrn > 4)
I_Error("Bad V_DrawBlock");
#endif
dest = screens[scrn] + y*vid.width + x;
deststop = screens[scrn] + vid.rowbytes * vid.height;
@ -2342,6 +2340,12 @@ static void V_GetFontSpecification(int fontno, INT32 flags, fontspec_t *result)
case PINGF_FONT:
result->spacew = 3;
break;
case ROLNUM_FONT:
result->spacew = 17;
break;
case RO4NUM_FONT:
result->spacew = 9;
break;
}
switch (fontno)
@ -2373,6 +2377,12 @@ static void V_GetFontSpecification(int fontno, INT32 flags, fontspec_t *result)
case PINGF_FONT:
result->lfh = 10;
break;
case ROLNUM_FONT:
result->lfh = 33;
break;
case RO4NUM_FONT:
result->lfh = 15;
break;
}
switch (fontno)
@ -2432,6 +2442,8 @@ static void V_GetFontSpecification(int fontno, INT32 flags, fontspec_t *result)
break;
case OPPRF_FONT:
case PINGF_FONT:
case ROLNUM_FONT:
case RO4NUM_FONT:
if (result->chw)
result->dim_fn = FixedCharacterDim;
else