Merge branch 'master' of https://git.do.srb2.org/KartKrew/Kart into challenge-consarnit

This commit is contained in:
toaster 2023-12-26 15:45:00 +00:00
commit a1d198d317
39 changed files with 1133 additions and 556 deletions

View file

@ -134,7 +134,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
k_botsearch.c
k_grandprix.c
k_boss.c
k_hud.c
k_hud.cpp
k_hud_track.cpp
k_menufunc.c
k_menudraw.c

View file

@ -318,8 +318,12 @@ consvar_t cv_controlperkey = Player("controlperkey", "One").values({{1, "One"},
// actual general (maximum) sound & music volume, saved into the config
// Volume scale is 0-100 in new mixer. 100 is treated as -0dB or 100% gain. No more weirdness to work around SDL_mixer
// problems
consvar_t cv_digmusicvolume = Player("musicvolume", "80").min_max(0, 100);
consvar_t cv_soundvolume = Player("soundvolume", "80").min_max(0, 100);
void MasterVolume_OnChange(void);
void DigMusicVolume_OnChange(void);
void SoundVolume_OnChange(void);
consvar_t cv_mastervolume = Player("volume", "80").min_max(0, 100).onchange_noinit(MasterVolume_OnChange);
consvar_t cv_digmusicvolume = Player("musicvolume", "80").min_max(0, 100).onchange_noinit(DigMusicVolume_OnChange);
consvar_t cv_soundvolume = Player("soundvolume", "80").min_max(0, 100).onchange_noinit(SoundVolume_OnChange);
#ifdef HAVE_DISCORDRPC
void DRPC_UpdatePresence(void);
@ -402,10 +406,14 @@ extern CV_PossibleValue_t perfstats_cons_t[];
consvar_t cv_perfstats = Player("perfstats", "Off").dont_save().values(perfstats_cons_t);
// Window focus sound sytem toggles
void PlayMusicIfUnfocused_OnChange(void);
void PlaySoundIfUnfocused_OnChange(void);
consvar_t cv_playmusicifunfocused = Player("playmusicifunfocused", "No").yes_no().onchange_noinit(PlayMusicIfUnfocused_OnChange);
consvar_t cv_playsoundifunfocused = Player("playsoundsifunfocused", "No").yes_no().onchange_noinit(PlaySoundIfUnfocused_OnChange);
void BGAudio_OnChange(void);
void BGAudio_OnChange(void);
consvar_t cv_bgaudio = Player("bgaudio", "Nothing").onchange_noinit(BGAudio_OnChange).values({
{0, "Nothing"},
{1, "Music"},
{2, "Sounds"},
{3, "Music&Sounds"},
});
// Pause game upon window losing focus
consvar_t cv_pauseifunfocused = Player("pauseifunfocused", "Yes").yes_no();

View file

@ -61,9 +61,10 @@ typedef enum
#define TICCMD_LATENCYMASK 0xFF
// ticcmd flags
#define TICCMD_RECEIVED 1
#define TICCMD_TYPING 2/* chat window or console open */
#define TICCMD_KEYSTROKE 4/* chat character input */
#define TICCMD_RECEIVED (0x01) /* Actual tic recieved from client */
#define TICCMD_TYPING (0x02) /* chat window or console open */
#define TICCMD_KEYSTROKE (0x04) /* chat character input */
#define TICCMD_BOT (0x80) /* generated by bot, demos write bot variables */
#if defined(_MSC_VER)
#pragma pack(1)
@ -79,6 +80,12 @@ struct ticcmd_t
UINT16 buttons;
UINT8 latency; // Netgames: how many tics ago was this ticcmd generated from this player's end?
UINT8 flags;
struct
{
SINT8 turnconfirm;
SINT8 spindashconfirm;
SINT8 itemconfirm;
} bot;
} ATTRPACK;
#if defined(_MSC_VER)

View file

@ -139,8 +139,13 @@ demoghost *ghosts = NULL;
#define ZT_AIMING 0x0040
#define ZT_LATENCY 0x0080
#define ZT_FLAGS 0x0100
#define ZT_BOT 0x8000
// Ziptics are UINT16 now, go nuts
#define ZT_BOT_TURN 0x0001
#define ZT_BOT_SPINDASH 0x0002
#define ZT_BOT_ITEM 0x0004
#define DEMOMARKER 0x80 // demobuf.end
UINT8 demo_extradata[MAXPLAYERS];
@ -544,6 +549,18 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum)
if (ziptic & ZT_FLAGS)
oldcmd[playernum].flags = READUINT8(demobuf.p);
if (ziptic & ZT_BOT)
{
UINT16 botziptic = READUINT16(demobuf.p);
if (botziptic & ZT_BOT_TURN)
oldcmd[playernum].bot.turnconfirm = READSINT8(demobuf.p);
if (botziptic & ZT_BOT_SPINDASH)
oldcmd[playernum].bot.spindashconfirm = READSINT8(demobuf.p);
if (botziptic & ZT_BOT_ITEM)
oldcmd[playernum].bot.itemconfirm = READSINT8(demobuf.p);
}
G_CopyTiccmd(cmd, &oldcmd[playernum], 1);
if (!(demoflags & DF_GHOST) && *demobuf.p == DEMOMARKER)
@ -558,10 +575,12 @@ void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum)
{
UINT16 ziptic = 0;
UINT8 *ziptic_p;
(void)playernum;
//(void)playernum;
if (!demobuf.p)
return;
ziptic_p = demobuf.p; // the ziptic, written at the end of this function
demobuf.p += 2;
@ -621,8 +640,45 @@ void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum)
ziptic |= ZT_FLAGS;
}
if (cmd->flags & TICCMD_BOT)
{
ziptic |= ZT_BOT;
}
WRITEUINT16(ziptic_p, ziptic);
if (ziptic & ZT_BOT)
{
UINT16 botziptic = 0;
UINT8 *botziptic_p;
botziptic_p = demobuf.p; // the ziptic, written at the end of this function
demobuf.p += 2;
if (cmd->bot.turnconfirm != oldcmd[playernum].bot.turnconfirm)
{
WRITESINT8(demobuf.p, cmd->bot.turnconfirm);
oldcmd[playernum].bot.turnconfirm = cmd->bot.turnconfirm;
botziptic |= ZT_BOT_TURN;
}
if (cmd->bot.spindashconfirm != oldcmd[playernum].bot.spindashconfirm)
{
WRITESINT8(demobuf.p, cmd->bot.spindashconfirm);
oldcmd[playernum].bot.spindashconfirm = cmd->bot.spindashconfirm;
botziptic |= ZT_BOT_SPINDASH;
}
if (cmd->bot.itemconfirm != oldcmd[playernum].bot.itemconfirm)
{
WRITESINT8(demobuf.p, cmd->bot.itemconfirm);
oldcmd[playernum].bot.itemconfirm = cmd->bot.itemconfirm;
botziptic |= ZT_BOT_ITEM;
}
WRITEUINT16(botziptic_p, botziptic);
}
// attention here for the ticcmd size!
// latest demos with mouse aiming byte in ticcmd
if (!(demoflags & DF_GHOST) && ziptic_p > demobuf.end - 9)
@ -1243,6 +1299,16 @@ readghosttic:
g->p++;
if (ziptic & ZT_FLAGS)
g->p++;
if (ziptic & ZT_BOT)
{
UINT16 botziptic = READUINT16(g->p);
if (botziptic & ZT_BOT_TURN)
g->p++;
if (botziptic & ZT_BOT_SPINDASH)
g->p++;
if (botziptic & ZT_BOT_ITEM)
g->p++;
}
// Grab ghost data.
ziptic = READUINT8(g->p);

View file

@ -997,6 +997,11 @@ ticcmd_t *G_MoveTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n)
dest[i].buttons = (UINT16)SHORT(src[i].buttons);
dest[i].latency = src[i].latency;
dest[i].flags = src[i].flags;
if (dest[i].flags & TICCMD_BOT)
{
dest[i].bot.itemconfirm = src[i].bot.itemconfirm;
}
}
return dest;
}
@ -1754,13 +1759,15 @@ void G_Ticker(boolean run)
{
if (players[i].bot == true && grandprixinfo.gp == true && grandprixinfo.masterbots == false)
{
if (players[i].botvars.difficulty <= BOT_LEVEL_DECREASE)
const UINT8 bot_level_decrease = (grandprixinfo.gamespeed <= KARTSPEED_NORMAL) ? 3 : 2;
if (players[i].botvars.difficulty <= bot_level_decrease)
{
players[i].botvars.difficulty = 1;
}
else
{
players[i].botvars.difficulty -= BOT_LEVEL_DECREASE;
players[i].botvars.difficulty -= bot_level_decrease;
}
}
else

View file

@ -8699,7 +8699,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
MT_EMERALD, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
@ -24898,7 +24898,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
100, // mass
1, // damage
sfx_None, // activesound
MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_DONTENCOREMAP, // flags
MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_DONTENCOREMAP|MF_DONTPUNT, // flags
S_NULL // raisestate
},

View file

@ -331,11 +331,11 @@ void K_UpdateMatchRaceBots(void)
}
/*--------------------------------------------------
boolean K_PlayerUsesBotMovement(player_t *player)
boolean K_PlayerUsesBotMovement(const player_t *player)
See header file for description.
--------------------------------------------------*/
boolean K_PlayerUsesBotMovement(player_t *player)
boolean K_PlayerUsesBotMovement(const player_t *player)
{
if (K_PodiumSequence() == true)
return true;
@ -354,7 +354,7 @@ boolean K_PlayerUsesBotMovement(player_t *player)
See header file for description.
--------------------------------------------------*/
boolean K_BotCanTakeCut(player_t *player)
boolean K_BotCanTakeCut(const player_t *player)
{
if (
#if 1
@ -374,7 +374,7 @@ boolean K_BotCanTakeCut(player_t *player)
}
/*--------------------------------------------------
static fixed_t K_BotSpeedScaled(player_t *player, fixed_t speed)
static fixed_t K_BotSpeedScaled(const player_t *player, fixed_t speed)
What the bot "thinks" their speed is, for predictions.
Mainly to make bots brake earlier when on friction sectors.
@ -386,7 +386,7 @@ boolean K_BotCanTakeCut(player_t *player)
Return:-
The bot's speed value for calculations.
--------------------------------------------------*/
static fixed_t K_BotSpeedScaled(player_t *player, fixed_t speed)
static fixed_t K_BotSpeedScaled(const player_t *player, fixed_t speed)
{
fixed_t result = speed;
@ -441,11 +441,11 @@ static fixed_t K_BotSpeedScaled(player_t *player, fixed_t speed)
}
/*--------------------------------------------------
const botcontroller_t *K_GetBotController(mobj_t *mobj)
const botcontroller_t *K_GetBotController(const mobj_t *mobj)
See header file for description.
--------------------------------------------------*/
const botcontroller_t *K_GetBotController(mobj_t *mobj)
const botcontroller_t *K_GetBotController(const mobj_t *mobj)
{
botcontroller_t *ret = nullptr;
@ -495,11 +495,11 @@ const botcontroller_t *K_GetBotController(mobj_t *mobj)
fixed_t K_BotMapModifier(void)
{
constexpr INT32 complexity_scale = 10000;
constexpr INT32 modifier_max = FRACUNIT * 2;
constexpr fixed_t modifier_max = FRACUNIT * 2;
const fixed_t complexity_value = std::clamp<fixed_t>(
FixedDiv(K_GetTrackComplexity(), complexity_scale),
-modifier_max,
-FixedDiv(FRACUNIT, modifier_max),
modifier_max
);
@ -507,7 +507,7 @@ fixed_t K_BotMapModifier(void)
}
/*--------------------------------------------------
static UINT32 K_BotRubberbandDistance(player_t *player)
static UINT32 K_BotRubberbandDistance(const player_t *player)
Calculates the distance away from 1st place that the
bot should rubberband to.
@ -518,7 +518,7 @@ fixed_t K_BotMapModifier(void)
Return:-
Distance to add, as an integer.
--------------------------------------------------*/
static UINT32 K_BotRubberbandDistance(player_t *player)
static UINT32 K_BotRubberbandDistance(const player_t *player)
{
const UINT32 spacing = FixedDiv(640 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)) / FRACUNIT;
const UINT8 portpriority = player - players;
@ -560,28 +560,40 @@ static UINT32 K_BotRubberbandDistance(player_t *player)
}
/*--------------------------------------------------
fixed_t K_BotRubberband(player_t *player)
fixed_t K_BotRubberband(const player_t *player)
See header file for description.
--------------------------------------------------*/
fixed_t K_BotRubberband(player_t *player)
fixed_t K_BotRubberband(const player_t *player)
{
constexpr fixed_t rubberdeltabase = FRACUNIT / 4; // +/- x0.25
const fixed_t difficultyEase = ((player->botvars.difficulty - 1) * FRACUNIT) / (MAXBOTDIFFICULTY - 1);
// Lv. 1: x0.50 avg
// Lv. 9: x1.50 avg
const fixed_t difficultyEase = ((player->botvars.difficulty - 1) * FRACUNIT) / (DIFFICULTBOT - 1);
const fixed_t rubberavg = Easing_Linear(difficultyEase, FRACUNIT / 2, FRACUNIT * 3 / 2);
// Lv. 1: x0.65 avg
// Lv. MAX: x1.1 avg
const fixed_t rubberBase = Easing_OutSine(
difficultyEase,
FRACUNIT * 65 / 100,
FRACUNIT * 11 / 10
);
// Lv. 1: x0.35 min
// Lv. 9: x1.35 min
const fixed_t rubberdeltamin = FixedMul(rubberdeltabase, K_BotMapModifier());
const fixed_t rubbermin = std::max<fixed_t>(rubberavg - rubberdeltamin, FRACUNIT/3);
// +/- x0.25
const fixed_t rubberStretchiness = FixedMul(
FixedDiv(
FRACUNIT / 4,
K_GetKartGameSpeedScalar(gamespeed)
),
K_BotMapModifier()
);
// Lv. 1: x0.65 max
// Lv. 9: x1.65 max
const fixed_t rubberdeltamax = FixedMul(rubberdeltabase, K_BotMapModifier());
const fixed_t rubbermax = std::min<fixed_t>(rubberavg - rubberdeltamax, FRACUNIT*3);
// Lv. 1: x0.4 min
// Lv. MAX: x0.85 min
constexpr fixed_t rubberSlowMin = FRACUNIT / 2;
const fixed_t rubberSlow = std::max<fixed_t>( rubberBase - rubberStretchiness, rubberSlowMin );
// Lv. 1: x0.9 max
// Lv. MAX: x1.35 max
constexpr fixed_t rubberFastMax = FRACUNIT * 3 / 2;
const fixed_t rubberFast = std::min<fixed_t>( rubberBase + rubberStretchiness, rubberFastMax );
fixed_t rubberband = FRACUNIT >> 1;
player_t *firstplace = nullptr;
@ -628,7 +640,7 @@ fixed_t K_BotRubberband(player_t *player)
if (firstplace != nullptr)
{
const fixed_t spacing = FixedDiv(2560 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)) / FRACUNIT;
const UINT32 spacing = FixedDiv(10240 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed)) / FRACUNIT;
const UINT32 wanteddist = firstplace->distancetofinish + K_BotRubberbandDistance(player);
const INT32 distdiff = player->distancetofinish - wanteddist;
@ -644,7 +656,7 @@ fixed_t K_BotRubberband(player_t *player)
}
}
return Easing_Linear(rubberband, rubbermin, rubbermax);
return Easing_Linear(rubberband, rubberSlow, rubberFast);
}
/*--------------------------------------------------
@ -784,7 +796,7 @@ static fixed_t K_ScaleWPDistWithSlope(fixed_t disttonext, angle_t angletonext, c
}
/*--------------------------------------------------
static botprediction_t *K_CreateBotPrediction(player_t *player)
static botprediction_t *K_CreateBotPrediction(const player_t *player)
Calculates a point further along the track to attempt to drive towards.
@ -794,7 +806,7 @@ static fixed_t K_ScaleWPDistWithSlope(fixed_t disttonext, angle_t angletonext, c
Return:-
Bot prediction struct.
--------------------------------------------------*/
static botprediction_t *K_CreateBotPrediction(player_t *player)
static botprediction_t *K_CreateBotPrediction(const player_t *player)
{
const precise_t time = I_GetPreciseTime();
@ -915,7 +927,7 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
}
/*--------------------------------------------------
static UINT8 K_TrySpindash(player_t *player)
static UINT8 K_TrySpindash(const player_t *player, ticcmd_t *cmd)
Determines conditions where the bot should attempt to spindash.
@ -926,7 +938,7 @@ static botprediction_t *K_CreateBotPrediction(player_t *player)
0 to make the bot drive normally, 1 to e-brake, 2 to e-brake & charge spindash.
(TODO: make this an enum)
--------------------------------------------------*/
static UINT8 K_TrySpindash(player_t *player)
static UINT8 K_TrySpindash(const player_t *player, ticcmd_t *cmd)
{
const tic_t difficultyModifier = (TICRATE/6);
@ -939,7 +951,6 @@ static UINT8 K_TrySpindash(player_t *player)
if (player->spindashboost || player->tiregrease // You just released a spindash, you don't need to try again yet, jeez.
|| P_IsObjectOnGround(player->mo) == false) // Not in a state where we want 'em to spindash.
{
player->botvars.spindashconfirm = 0;
return 0;
}
@ -997,7 +1008,7 @@ static UINT8 K_TrySpindash(player_t *player)
anyCondition = true;\
if (player->botvars.spindashconfirm < BOTSPINDASHCONFIRM) \
{ \
player->botvars.spindashconfirm++; \
cmd->bot.spindashconfirm++; \
} \
}
@ -1039,7 +1050,7 @@ static UINT8 K_TrySpindash(player_t *player)
{
if (player->botvars.spindashconfirm > 0)
{
player->botvars.spindashconfirm--;
cmd->bot.spindashconfirm--;
}
}
}
@ -1049,7 +1060,7 @@ static UINT8 K_TrySpindash(player_t *player)
}
/*--------------------------------------------------
static boolean K_TryRingShooter(player_t *player)
static boolean K_TryRingShooter(const player_t *player)
Determines conditions where the bot should attempt to respawn.
@ -1059,7 +1070,7 @@ static UINT8 K_TrySpindash(player_t *player)
Return:-
true if we want to hold the respawn button, otherwise false.
--------------------------------------------------*/
static boolean K_TryRingShooter(player_t *player)
static boolean K_TryRingShooter(const player_t *player)
{
if (player->respawn.state != RESPAWNST_NONE)
{
@ -1079,15 +1090,11 @@ static boolean K_TryRingShooter(player_t *player)
return false;
}
// Our anti-grief system is already a perfect system
// for determining if we're not making progress, so
// lets reuse it for bot respawning!
P_IncrementGriefValue(player, &player->botvars.respawnconfirm, BOTRESPAWNCONFIRM);
return (player->botvars.respawnconfirm >= BOTRESPAWNCONFIRM);
return true;
}
/*--------------------------------------------------
static void K_DrawPredictionDebug(botprediction_t *predict, player_t *player)
static void K_DrawPredictionDebug(botprediction_t *predict, const player_t *player)
Draws objects to show where the viewpoint bot is trying to go.
@ -1098,7 +1105,7 @@ static boolean K_TryRingShooter(player_t *player)
Return:-
None
--------------------------------------------------*/
static void K_DrawPredictionDebug(botprediction_t *predict, player_t *player)
static void K_DrawPredictionDebug(botprediction_t *predict, const player_t *player)
{
mobj_t *debugMobj = nullptr;
angle_t sideAngle = ANGLE_MAX;
@ -1151,7 +1158,7 @@ static void K_DrawPredictionDebug(botprediction_t *predict, player_t *player)
}
/*--------------------------------------------------
static void K_BotTrick(player_t *player, ticcmd_t *cmd, const botcontroller_t *botController)
static void K_BotTrick(const player_t *player, ticcmd_t *cmd, const botcontroller_t *botController)
Determines inputs for trick panels.
@ -1163,7 +1170,7 @@ static void K_DrawPredictionDebug(botprediction_t *predict, player_t *player)
Return:-
None
--------------------------------------------------*/
static void K_BotTrick(player_t *player, ticcmd_t *cmd, const botcontroller_t *botController)
static void K_BotTrick(const player_t *player, ticcmd_t *cmd, const botcontroller_t *botController)
{
// Trick panel state -- do nothing until a controller line is found, in which case do a trick.
if (botController == nullptr)
@ -1192,7 +1199,7 @@ static void K_BotTrick(player_t *player, ticcmd_t *cmd, const botcontroller_t *b
}
/*--------------------------------------------------
static angle_t K_BotSmoothLanding(player_t *player, angle_t destangle)
static angle_t K_BotSmoothLanding(const player_t *player, angle_t destangle)
Calculates a new destination angle while in the air,
to be able to successfully smooth land.
@ -1204,7 +1211,7 @@ static void K_BotTrick(player_t *player, ticcmd_t *cmd, const botcontroller_t *b
Return:-
New destination angle.
--------------------------------------------------*/
static angle_t K_BotSmoothLanding(player_t *player, angle_t destangle)
static angle_t K_BotSmoothLanding(const player_t *player, angle_t destangle)
{
angle_t newAngle = destangle;
boolean air = !P_IsObjectOnGround(player->mo);
@ -1241,7 +1248,7 @@ static angle_t K_BotSmoothLanding(player_t *player, angle_t destangle)
}
/*--------------------------------------------------
static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t *predict)
static INT32 K_HandleBotTrack(const player_t *player, ticcmd_t *cmd, botprediction_t *predict)
Determines inputs for standard track driving.
@ -1253,7 +1260,7 @@ static angle_t K_BotSmoothLanding(player_t *player, angle_t destangle)
Return:-
New value for turn amount.
--------------------------------------------------*/
static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t *predict, angle_t destangle)
static INT32 K_HandleBotTrack(const player_t *player, ticcmd_t *cmd, botprediction_t *predict, angle_t destangle)
{
// Handle steering towards waypoints!
INT32 turnamt = 0;
@ -1265,7 +1272,7 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t *
destangle = K_BotSmoothLanding(player, destangle);
moveangle = player->mo->angle;
moveangle = player->mo->angle + K_GetUnderwaterTurnAdjust(player);
anglediff = AngleDeltaSigned(moveangle, destangle);
if (anglediff < 0)
@ -1341,7 +1348,7 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t *
}
/*--------------------------------------------------
static INT32 K_HandleBotReverse(player_t *player, ticcmd_t *cmd, botprediction_t *predict)
static INT32 K_HandleBotReverse(const player_t *player, ticcmd_t *cmd, botprediction_t *predict)
Determines inputs for reversing.
@ -1353,7 +1360,7 @@ static INT32 K_HandleBotTrack(player_t *player, ticcmd_t *cmd, botprediction_t *
Return:-
New value for turn amount.
--------------------------------------------------*/
static INT32 K_HandleBotReverse(player_t *player, ticcmd_t *cmd, botprediction_t *predict, angle_t destangle)
static INT32 K_HandleBotReverse(const player_t *player, ticcmd_t *cmd, botprediction_t *predict, angle_t destangle)
{
// Handle steering towards waypoints!
INT32 turnamt = 0;
@ -1398,7 +1405,7 @@ static INT32 K_HandleBotReverse(player_t *player, ticcmd_t *cmd, botprediction_t
destangle = K_BotSmoothLanding(player, destangle);
// Calculate turn direction first.
moveangle = player->mo->angle;
moveangle = player->mo->angle + K_GetUnderwaterTurnAdjust(player);
angle = (moveangle - destangle);
if (angle < ANGLE_180)
@ -1486,11 +1493,11 @@ static INT32 K_HandleBotReverse(player_t *player, ticcmd_t *cmd, botprediction_t
}
/*--------------------------------------------------
static void K_BotPodiumTurning(player_t *player, ticcmd_t *cmd)
static void K_BotPodiumTurning(const player_t *player, ticcmd_t *cmd)
Calculates bot turning for the podium cutscene.
--------------------------------------------------*/
static void K_BotPodiumTurning(player_t *player, ticcmd_t *cmd)
static void K_BotPodiumTurning(const player_t *player, ticcmd_t *cmd)
{
const angle_t destAngle = R_PointToAngle2(
player->mo->x, player->mo->y,
@ -1514,11 +1521,11 @@ static void K_BotPodiumTurning(player_t *player, ticcmd_t *cmd)
}
/*--------------------------------------------------
static void K_BuildBotPodiumTiccmd(player_t *player, ticcmd_t *cmd)
static void K_BuildBotPodiumTiccmd(const player_t *player, ticcmd_t *cmd)
Calculates all bot movement for the podium cutscene.
--------------------------------------------------*/
static void K_BuildBotPodiumTiccmd(player_t *player, ticcmd_t *cmd)
static void K_BuildBotPodiumTiccmd(const player_t *player, ticcmd_t *cmd)
{
if (player->currentwaypoint == nullptr)
{
@ -1543,11 +1550,11 @@ static void K_BuildBotPodiumTiccmd(player_t *player, ticcmd_t *cmd)
}
/*--------------------------------------------------
static void K_BuildBotTiccmdNormal(player_t *player, ticcmd_t *cmd)
static void K_BuildBotTiccmdNormal(const player_t *player, ticcmd_t *cmd)
Build ticcmd for bots with a style of BOT_STYLE_NORMAL
--------------------------------------------------*/
static void K_BuildBotTiccmdNormal(player_t *player, ticcmd_t *cmd)
static void K_BuildBotTiccmdNormal(const player_t *player, ticcmd_t *cmd)
{
precise_t t = 0;
@ -1597,7 +1604,7 @@ static void K_BuildBotTiccmdNormal(player_t *player, ticcmd_t *cmd)
return;
}
if (K_TryRingShooter(player) == true)
if (K_TryRingShooter(player) == true && player->botvars.respawnconfirm >= BOTRESPAWNCONFIRM)
{
// We want to respawn. Simply hold Y and stop here!
cmd->buttons |= (BT_RESPAWN | BT_EBRAKEMASK);
@ -1751,7 +1758,7 @@ static void K_BuildBotTiccmdNormal(player_t *player, ticcmd_t *cmd)
if (trySpindash == true)
{
// Spindashing
spindash = K_TrySpindash(player);
spindash = K_TrySpindash(player, cmd);
if (spindash > 0)
{
@ -1790,7 +1797,7 @@ static void K_BuildBotTiccmdNormal(player_t *player, ticcmd_t *cmd)
// Count up
if (player->botvars.turnconfirm < BOTTURNCONFIRM)
{
player->botvars.turnconfirm++;
cmd->bot.turnconfirm++;
}
}
else if (turnamt < 0)
@ -1798,7 +1805,7 @@ static void K_BuildBotTiccmdNormal(player_t *player, ticcmd_t *cmd)
// Count down
if (player->botvars.turnconfirm > -BOTTURNCONFIRM)
{
player->botvars.turnconfirm--;
cmd->bot.turnconfirm--;
}
}
else
@ -1806,11 +1813,11 @@ static void K_BuildBotTiccmdNormal(player_t *player, ticcmd_t *cmd)
// Back to neutral
if (player->botvars.turnconfirm < 0)
{
player->botvars.turnconfirm++;
cmd->bot.turnconfirm++;
}
else if (player->botvars.turnconfirm > 0)
{
player->botvars.turnconfirm--;
cmd->bot.turnconfirm--;
}
}
@ -1836,7 +1843,9 @@ static void K_BuildBotTiccmdNormal(player_t *player, ticcmd_t *cmd)
See header file for description.
--------------------------------------------------*/
void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
void K_BuildBotTiccmd(
player_t *player, // annoyingly NOT const because of LUA_HookTiccmd... grumble grumble
ticcmd_t *cmd)
{
// Remove any existing controls
memset(cmd, 0, sizeof(ticcmd_t));
@ -1855,9 +1864,12 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
// their own :)
if (LUA_HookTiccmd(player, cmd, HOOK(BotTiccmd)) == true)
{
cmd->flags |= TICCMD_BOT;
return;
}
cmd->flags |= TICCMD_BOT;
if (K_PodiumSequence() == true)
{
K_BuildBotPodiumTiccmd(player, cmd);
@ -1886,8 +1898,6 @@ void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd)
--------------------------------------------------*/
void K_UpdateBotGameplayVars(player_t *player)
{
player->botvars.rubberband = FRACUNIT;
if (gamestate != GS_LEVEL || !player->mo)
{
// Not in the level.
@ -1895,4 +1905,26 @@ void K_UpdateBotGameplayVars(player_t *player)
}
player->botvars.rubberband = K_UpdateRubberband(player);
player->botvars.turnconfirm += player->cmd.bot.turnconfirm;
if (player->spindashboost || player->tiregrease // You just released a spindash, you don't need to try again yet, jeez.
|| P_IsObjectOnGround(player->mo) == false) // Not in a state where we want 'em to spindash.
{
player->botvars.spindashconfirm = 0;
}
else
{
player->botvars.spindashconfirm += player->cmd.bot.spindashconfirm;
}
if (K_TryRingShooter(player) == true)
{
// Our anti-grief system is already a perfect system
// for determining if we're not making progress, so
// lets reuse it for bot respawning!
P_IncrementGriefValue(player, &player->botvars.respawnconfirm, BOTRESPAWNCONFIRM);
}
K_UpdateBotGameplayVarsItemUsage(player);
}

View file

@ -32,9 +32,6 @@ extern "C" {
// Level of a "difficult" bot. The max bot level was increased, but this keeps all of the same calculations.
#define DIFFICULTBOT (9)
// How much all bots reduce in difficulty when the match needs to be restarted.
#define BOT_LEVEL_DECREASE (2)
// How many tics in a row do you need to turn in this direction before we'll let you turn.
// Made it as small as possible without making it look like the bots are twitching constantly.
#define BOTTURNCONFIRM 4
@ -59,7 +56,7 @@ struct botprediction_t
/*--------------------------------------------------
boolean K_PlayerUsesBotMovement(player_t *player);
boolean K_PlayerUsesBotMovement(const player_t *player);
Tells if this player is being controlled via bot movement code (is a bot, or is exiting).
@ -70,11 +67,11 @@ struct botprediction_t
true if using bot movement code, otherwise false.
--------------------------------------------------*/
boolean K_PlayerUsesBotMovement(player_t *player);
boolean K_PlayerUsesBotMovement(const player_t *player);
/*--------------------------------------------------
boolean K_BotCanTakeCut(player_t *player);
boolean K_BotCanTakeCut(const player_t *player);
Tells if this bot is able to take shortcuts (currently unaffected by offroad,
or has certain items ready).
@ -86,11 +83,11 @@ boolean K_PlayerUsesBotMovement(player_t *player);
true if able to take shortcuts, otherwise false.
--------------------------------------------------*/
boolean K_BotCanTakeCut(player_t *player);
boolean K_BotCanTakeCut(const player_t *player);
/*--------------------------------------------------
const botcontroller_t *K_GetBotController(mobj_t *mobj);
const botcontroller_t *K_GetBotController(const mobj_t *mobj);
Retrieves the current bot controller values from
the player's current sector.
@ -102,7 +99,7 @@ boolean K_BotCanTakeCut(player_t *player);
Pointer to the sector's bot controller struct.
--------------------------------------------------*/
const botcontroller_t *K_GetBotController(mobj_t *mobj);
const botcontroller_t *K_GetBotController(const mobj_t *mobj);
/*--------------------------------------------------
@ -126,7 +123,7 @@ fixed_t K_BotMapModifier(void);
/*--------------------------------------------------
fixed_t K_BotRubberband(player_t *player);
fixed_t K_BotRubberband(const player_t *player);
Gives a multiplier for a bot's rubberbanding.
Meant to be used for acceleration and handling.
@ -138,7 +135,7 @@ fixed_t K_BotMapModifier(void);
A multiplier in fixed point scale.
--------------------------------------------------*/
fixed_t K_BotRubberband(player_t *player);
fixed_t K_BotRubberband(const player_t *player);
/*--------------------------------------------------
@ -262,7 +259,7 @@ UINT8 K_EggboxStealth(fixed_t x, fixed_t y);
true if avoiding this sector, false otherwise.
--------------------------------------------------*/
boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t y);
boolean K_BotHatesThisSector(const player_t *player, sector_t *sec, fixed_t x, fixed_t y);
/*--------------------------------------------------
@ -278,11 +275,11 @@ boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t
None
--------------------------------------------------*/
void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player);
void K_NudgePredictionTowardsObjects(botprediction_t *predict, const player_t *player);
/*--------------------------------------------------
INT32 K_PositionBully(player_t *player)
INT32 K_PositionBully(const player_t *player)
Calculates a turn value to reach a player that can be bullied.
@ -293,7 +290,7 @@ void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
INT32_MAX if couldn't find anything, otherwise a steering value.
--------------------------------------------------*/
INT32 K_PositionBully(player_t *player);
INT32 K_PositionBully(const player_t *player);
/*--------------------------------------------------
@ -313,6 +310,23 @@ INT32 K_PositionBully(player_t *player);
void K_BuildBotTiccmd(player_t *player, ticcmd_t *cmd);
/*--------------------------------------------------
void K_UpdateBotGameplayVarsItemUsage(player_t *player)
Updates gamestate affecting botvars, relating to
item usage. This must be called for both client
and server.
Input Arguments:-
player - Player to whom to update the botvars.
Return:-
N/A
--------------------------------------------------*/
void K_UpdateBotGameplayVarsItemUsage(player_t *player);
/*--------------------------------------------------
void K_UpdateBotGameplayVars(player_t *player);
@ -330,7 +344,7 @@ void K_UpdateBotGameplayVars(player_t *player);
/*--------------------------------------------------
void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt);
void K_BotItemUsage(const player_t *player, ticcmd_t *cmd, INT16 turnamt);
Item usage part of ticcmd generation.
@ -343,7 +357,7 @@ void K_UpdateBotGameplayVars(player_t *player);
None
--------------------------------------------------*/
void K_BotItemUsage(player_t *player, ticcmd_t *cmd, INT16 turnamt);
void K_BotItemUsage(const player_t *player, ticcmd_t *cmd, INT16 turnamt);
/*--------------------------------------------------

File diff suppressed because it is too large Load diff

View file

@ -117,7 +117,7 @@ UINT8 K_EggboxStealth(fixed_t x, fixed_t y)
}
/*--------------------------------------------------
static boolean K_BotHatesThisSectorsSpecial(player_t *player, sector_t *sec)
static boolean K_BotHatesThisSectorsSpecial(const player_t *player, sector_t *sec)
Tells us if a bot will play more careful around
this sector's special type.
@ -129,7 +129,7 @@ UINT8 K_EggboxStealth(fixed_t x, fixed_t y)
Return:-
true if avoiding this sector special, false otherwise.
--------------------------------------------------*/
static boolean K_BotHatesThisSectorsSpecial(player_t *player, sector_t *sec, const boolean flip)
static boolean K_BotHatesThisSectorsSpecial(const player_t *player, sector_t *sec, const boolean flip)
{
terrain_t *terrain = K_GetTerrainForFlatNum(flip ? sec->ceilingpic : sec->floorpic);
@ -162,11 +162,11 @@ static boolean K_BotHatesThisSectorsSpecial(player_t *player, sector_t *sec, con
}
/*--------------------------------------------------
boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t y)
boolean K_BotHatesThisSector(const player_t *player, sector_t *sec, fixed_t x, fixed_t y)
See header file for description.
--------------------------------------------------*/
boolean K_BotHatesThisSector(player_t *player, sector_t *sec, fixed_t x, fixed_t y)
boolean K_BotHatesThisSector(const player_t *player, sector_t *sec, fixed_t x, fixed_t y)
{
const boolean flip = (player->mo->eflags & MFE_VERTICALFLIP);
fixed_t highestfloor = INT32_MAX;
@ -664,11 +664,11 @@ static BlockItReturn_t K_FindObjectsForNudging(mobj_t *thing)
}
/*--------------------------------------------------
void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
void K_NudgePredictionTowardsObjects(botprediction_t *predict, const player_t *player)
See header file for description.
--------------------------------------------------*/
void K_NudgePredictionTowardsObjects(botprediction_t *predict, player_t *player)
void K_NudgePredictionTowardsObjects(botprediction_t *predict, const player_t *player)
{
const precise_t time = I_GetPreciseTime();
@ -948,11 +948,11 @@ static BlockItReturn_t K_FindPlayersToBully(mobj_t *thing)
}
/*--------------------------------------------------
INT32 K_PositionBully(player_t *player)
INT32 K_PositionBully(const player_t *player)
See header file for description.
--------------------------------------------------*/
INT32 K_PositionBully(player_t *player)
INT32 K_PositionBully(const player_t *player)
{
INT32 xl, xh, yl, yh, bx, by;

View file

@ -952,9 +952,11 @@ boolean K_InstaWhipCollide(mobj_t *shield, mobj_t *victim)
shield->extravalue1 = 1;
}
P_DamageMobj(victim, shield, attacker, 1, DMG_NORMAL);
K_AddHitLag(attacker, attackerHitlag, false);
shield->hitlag = attacker->hitlag;
if (P_DamageMobj(victim, shield, attacker, 1, DMG_NORMAL))
{
K_AddHitLag(attacker, attackerHitlag, false);
shield->hitlag = attacker->hitlag;
}
}
return false;
}

View file

@ -604,6 +604,7 @@ void K_IncreaseBotDifficulty(player_t *bot)
disruptDelta = abs(statusQuo - bot->position);
increase = (beatenDelta + winnerDelta + disruptDelta - 2) / 3;
increase++; // At least +1 level up.
if (increase <= 0)
{
// No increase...

View file

@ -9,6 +9,9 @@
/// \file k_hud.c
/// \brief HUD drawing functions exclusive to Kart
#include <algorithm>
#include <vector>
#include "k_hud.h"
#include "k_kart.h"
#include "k_battle.h"
@ -955,7 +958,7 @@ static patch_t *K_GetSmallStaticCachedItemPatch(kartitems_t item)
{
UINT8 offset;
item = K_ItemResultToType(item);
item = static_cast<kartitems_t>(K_ItemResultToType(item));
switch (item)
{
@ -1281,7 +1284,7 @@ void K_DrawMapThumbnail(fixed_t x, fixed_t y, fixed_t width, UINT32 flags, UINT1
}
else
{
PictureOfLevel = mapheaderinfo[map]->thumbnailPic;
PictureOfLevel = static_cast<patch_t*>(mapheaderinfo[map]->thumbnailPic);
}
K_DrawLikeMapThumbnail(x, y, width, flags, PictureOfLevel, colormap);
@ -1318,7 +1321,7 @@ static void K_drawKartItem(void)
INT32 itembar = 0;
INT32 maxl = 0; // itembar's normal highest value
const INT32 barlength = (offset ? 12 : 26);
UINT16 localcolor[3] = { stplyr->skincolor };
skincolornum_t localcolor[3] = { static_cast<skincolornum_t>(stplyr->skincolor) };
SINT8 colormode[3] = { TC_RAINBOW };
boolean flipamount = false; // Used for 3P/4P splitscreen to flip item amount stuff
@ -1346,7 +1349,7 @@ static void K_drawKartItem(void)
break;
case KITEM_ORBINAUT:
localpatch[i] = kp_orbinaut[(offset ? 4 : min(amt-1, 3))];
localpatch[i] = kp_orbinaut[(offset ? 4 : std::min(amt-1, 3))];
break;
default:
@ -1435,7 +1438,7 @@ static void K_drawKartItem(void)
break;
case KITEM_ORBINAUT:
localpatch[1] = kp_orbinaut[(offset ? 4 : min(stplyr->itemamount-1, 3))];
localpatch[1] = kp_orbinaut[(offset ? 4 : std::min(stplyr->itemamount-1, 3))];
break;
case KITEM_SPB:
@ -1464,7 +1467,7 @@ static void K_drawKartItem(void)
switch (stplyr->karthud[khud_itemblinkmode])
{
case 2:
localcolor[1] = K_RainbowColor(leveltime);
localcolor[1] = static_cast<skincolornum_t>(K_RainbowColor(leveltime));
break;
case 1:
localcolor[1] = SKINCOLOR_RED;
@ -1597,7 +1600,7 @@ static void K_drawKartItem(void)
if (itembar)
{
const INT32 fill = ((itembar*barlength)/maxl);
const INT32 length = min(barlength, fill);
const INT32 length = std::min(barlength, fill);
const INT32 height = (offset ? 1 : 2);
const INT32 x = (offset ? 17 : 11), y = (offset ? 27 : 35);
@ -1616,14 +1619,14 @@ static void K_drawKartItem(void)
// Quick Eggman numbers
if (stplyr->eggmanexplode > 1)
V_DrawScaledPatch(fx+17, fy+13-offset, V_HUDTRANS|V_SLIDEIN|fflags, kp_eggnum[min(5, G_TicsToSeconds(stplyr->eggmanexplode))]);
V_DrawScaledPatch(fx+17, fy+13-offset, V_HUDTRANS|V_SLIDEIN|fflags, kp_eggnum[std::min(5, G_TicsToSeconds(stplyr->eggmanexplode))]);
if (stplyr->itemtype == KITEM_FLAMESHIELD && stplyr->flamelength > 0)
{
INT32 numframes = FLAMESHIELD_MAX;
INT32 absolutemax = numframes;
INT32 flamemax = stplyr->flamelength;
INT32 flamemeter = min(stplyr->flamemeter, flamemax);
INT32 flamemeter = std::min(static_cast<INT32>(stplyr->flamemeter), flamemax);
INT32 bf = numframes - stplyr->flamelength;
INT32 ff = numframes - ((flamemeter * numframes) / absolutemax);
@ -1688,7 +1691,7 @@ static void K_drawKartSlotMachine(void)
INT32 vstretch = 0;
INT32 hstretch = 3;
INT32 splitbsx = 0, splitbsy = 0;
UINT16 localcolor[3] = { stplyr->skincolor };
skincolornum_t localcolor[3] = { static_cast<skincolornum_t>(stplyr->skincolor) };
SINT8 colormode[3] = { TC_RAINBOW };
fixed_t rouletteOffset = 0;
@ -1942,14 +1945,14 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT32 splitflags, U
if (gamedata->collected[(stickermedalinfo.emblems[i]-emblemlocations)])
{
V_DrawSmallMappedPatch(workx, worky, splitflags,
W_CachePatchName(M_GetEmblemPatch(stickermedalinfo.emblems[i], false), PU_CACHE),
static_cast<patch_t*>(W_CachePatchName(M_GetEmblemPatch(stickermedalinfo.emblems[i], false), PU_CACHE)),
R_GetTranslationColormap(TC_DEFAULT, M_GetEmblemColor(stickermedalinfo.emblems[i]), GTC_CACHE)
);
}
else
{
V_DrawSmallMappedPatch(workx, worky, splitflags,
W_CachePatchName("NEEDIT", PU_CACHE),
static_cast<patch_t*>(W_CachePatchName("NEEDIT", PU_CACHE)),
NULL
);
}
@ -1960,7 +1963,7 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT32 splitflags, U
if (modeattacking & ATTACKING_SPB && stplyr->SPBdistance > 0)
{
UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, stplyr->skincolor, GTC_CACHE);
UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, static_cast<skincolornum_t>(stplyr->skincolor), GTC_CACHE);
INT32 ybar = 180;
INT32 widthbar = 120, xbar = 160 - widthbar/2, currentx;
INT32 barflags = V_SNAPTOBOTTOM|V_SLIDEIN;
@ -2046,7 +2049,7 @@ void K_DrawKartPositionNumXY(
if (exit && num == 1)
{
// 1st place winner? You get rainbows!!
color = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_POSNUM_BEST1 + (counter % 6), GTC_CACHE);
color = R_GetTranslationColormap(TC_DEFAULT, static_cast<skincolornum_t>(SKINCOLOR_POSNUM_BEST1 + (counter % 6)), GTC_CACHE);
}
else if (exit || lastLap)
{
@ -2061,11 +2064,11 @@ void K_DrawKartPositionNumXY(
if (useRedNums == true)
{
color = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_POSNUM_LOSE1 + (counter % 3), GTC_CACHE);
color = R_GetTranslationColormap(TC_DEFAULT, static_cast<skincolornum_t>(SKINCOLOR_POSNUM_LOSE1 + (counter % 3)), GTC_CACHE);
}
else
{
color = R_GetTranslationColormap(TC_DEFAULT, SKINCOLOR_POSNUM_WIN1 + (counter % 3), GTC_CACHE);
color = R_GetTranslationColormap(TC_DEFAULT, static_cast<skincolornum_t>(SKINCOLOR_POSNUM_WIN1 + (counter % 3)), GTC_CACHE);
}
}
else
@ -2100,7 +2103,7 @@ static void K_DrawKartPositionNum(UINT8 num)
UINT8 splitIndex = (r_splitscreen > 0) ? 1 : 0;
fixed_t scale = FRACUNIT;
fixed_t fx = 0, fy = 0;
transnum_t trans = 0;
transnum_t trans = static_cast<transnum_t>(0);
INT32 fflags = 0;
if (stplyr->lives <= 0 && stplyr->playerstate == PST_DEAD)
@ -2110,7 +2113,7 @@ static void K_DrawKartPositionNum(UINT8 num)
if (leveltime < (starttime + NUMTRANSMAPS))
{
trans = (starttime + NUMTRANSMAPS) - leveltime;
trans = static_cast<transnum_t>((starttime + NUMTRANSMAPS) - leveltime);
}
if (trans >= NUMTRANSMAPS)
@ -2122,7 +2125,7 @@ static void K_DrawKartPositionNum(UINT8 num)
{
const UINT8 delay = (stplyr->exiting) ? POS_DELAY_TIME : stplyr->positiondelay;
const fixed_t add = (scale * 3) >> ((r_splitscreen == 1) ? 1 : 2);
scale += min((add * (delay * delay)) / (POS_DELAY_TIME * POS_DELAY_TIME), add);
scale += std::min((add * (delay * delay)) / (POS_DELAY_TIME * POS_DELAY_TIME), add);
}
// pain and suffering defined below
@ -2314,11 +2317,11 @@ static boolean K_drawKartPositionFaces(void)
else
workingskin = players[rankplayer[i]].skin;
colormap = R_GetTranslationColormap(workingskin, players[rankplayer[i]].mo->color, GTC_CACHE);
colormap = R_GetTranslationColormap(workingskin, static_cast<skincolornum_t>(players[rankplayer[i]].mo->color), GTC_CACHE);
if (players[rankplayer[i]].mo->colorized)
colormap = R_GetTranslationColormap(TC_RAINBOW, players[rankplayer[i]].mo->color, GTC_CACHE);
colormap = R_GetTranslationColormap(TC_RAINBOW, static_cast<skincolornum_t>(players[rankplayer[i]].mo->color), GTC_CACHE);
else
colormap = R_GetTranslationColormap(workingskin, players[rankplayer[i]].mo->color, GTC_CACHE);
colormap = R_GetTranslationColormap(workingskin, static_cast<skincolornum_t>(players[rankplayer[i]].mo->color), GTC_CACHE);
V_DrawMappedPatch(FACE_X + xoff, Y + yoff, V_HUDTRANS|V_SLIDEIN|V_SNAPTOLEFT|flipflag, faceprefix[workingskin][FACE_RANK], colormap);
@ -2341,7 +2344,7 @@ static boolean K_drawKartPositionFaces(void)
for (j = 0; j < 7; j++)
{
UINT32 emeraldFlag = (1 << j);
UINT16 emeraldColor = SKINCOLOR_CHAOSEMERALD1 + j;
skincolornum_t emeraldColor = static_cast<skincolornum_t>(SKINCOLOR_CHAOSEMERALD1 + j);
if (players[rankplayer[i]].emeralds & emeraldFlag)
{
@ -2417,7 +2420,7 @@ static void K_drawBossHealthBar(void)
;
else if (bossinfo.visualbarimpact)
{
INT32 mag = min((bossinfo.visualbarimpact/4) + 1, 8);
INT32 mag = std::min((bossinfo.visualbarimpact/4) + 1, 8u);
if (bossinfo.visualbarimpact & 1)
starty -= mag;
else
@ -2582,7 +2585,7 @@ static void K_drawKartEmeralds(void)
for (i = 0; i < 7; i++)
{
UINT32 emeraldFlag = (1 << i);
UINT16 emeraldColor = SKINCOLOR_CHAOSEMERALD1 + i;
skincolornum_t emeraldColor = static_cast<skincolornum_t>(SKINCOLOR_CHAOSEMERALD1 + i);
if (stplyr->emeralds & emeraldFlag)
{
@ -2676,7 +2679,7 @@ static void K_drawKartLaps(void)
{
// Laps
V_DrawScaledPatch(LAPS_X, LAPS_Y, V_HUDTRANS|V_SLIDEIN|splitflags, kp_lapsticker);
V_DrawTimerString(LAPS_X+33, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", min(stplyr->laps, numlaps), numlaps));
V_DrawTimerString(LAPS_X+33, LAPS_Y+3, V_HUDTRANS|V_SLIDEIN|splitflags, va("%d/%d", std::min(stplyr->laps, numlaps), numlaps));
}
}
@ -2790,7 +2793,7 @@ static void K_drawRingCounter(boolean gametypeinfoshown)
// Lives
if (uselives)
{
UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, stplyr->skincolor, GTC_CACHE);
UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, static_cast<skincolornum_t>(stplyr->skincolor), GTC_CACHE);
V_DrawMappedPatch(fr+21, fy-3, V_HUDTRANS|V_SLIDEIN|splitflags, faceprefix[stplyr->skin][FACE_MINIMAP], colormap);
if (stplyr->lives >= 0)
K_DrawLivesDigits(fr+34, fy, 4, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font);
@ -2839,7 +2842,7 @@ static void K_drawRingCounter(boolean gametypeinfoshown)
// Lives
if (uselives)
{
UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, stplyr->skincolor, GTC_CACHE);
UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, static_cast<skincolornum_t>(stplyr->skincolor), GTC_CACHE);
V_DrawMappedPatch(LAPS_X+46, fy-5, V_HUDTRANS|V_SLIDEIN|splitflags, faceprefix[stplyr->skin][FACE_RANK], colormap);
SINT8 livescount = 0;
if (stplyr->lives > 0)
@ -3017,9 +3020,9 @@ static void K_drawBlueSphereMeter(boolean gametypeinfoshown)
{
const UINT8 maxBars = 4;
const UINT8 segColors[] = {73, 64, 52, 54, 55, 35, 34, 33, 202, 180, 181, 182, 164, 165, 166, 153, 152};
const UINT8 sphere = max(min(stplyr->spheres, 40), 0);
const UINT8 sphere = std::clamp(static_cast<int>(stplyr->spheres), 0, 40);
UINT8 numBars = min((sphere / 10), maxBars);
UINT8 numBars = std::min((sphere / 10), +maxBars);
UINT8 colorIndex = (sphere * sizeof(segColors)) / (40 + 1);
INT32 fx, fy;
UINT8 i;
@ -3120,14 +3123,14 @@ static void K_drawBlueSphereMeter(boolean gametypeinfoshown)
if (r_splitscreen < 2)
{
V_DrawFill(fx, fy + 6, segLen, 3, segColors[max(colorIndex-1, 0)] | splitflags);
V_DrawFill(fx, fy + 7, segLen, 1, segColors[max(colorIndex-2, 0)] | splitflags);
V_DrawFill(fx, fy + 6, segLen, 3, segColors[std::max(colorIndex-1, 0)] | splitflags);
V_DrawFill(fx, fy + 7, segLen, 1, segColors[std::max(colorIndex-2, 0)] | splitflags);
V_DrawFill(fx, fy + 9, segLen, 3, segColors[colorIndex] | splitflags);
}
else
{
V_DrawFill(fx, fy + 5, segLen, 1, segColors[max(colorIndex-1, 0)] | splitflags);
V_DrawFill(fx, fy + 6, segLen, 1, segColors[max(colorIndex-2, 0)] | splitflags);
V_DrawFill(fx, fy + 5, segLen, 1, segColors[std::max(colorIndex-1, 0)] | splitflags);
V_DrawFill(fx, fy + 6, segLen, 1, segColors[std::max(colorIndex-2, 0)] | splitflags);
V_DrawFill(fx, fy + 7, segLen, 2, segColors[colorIndex] | splitflags);
}
@ -3137,7 +3140,7 @@ static void K_drawBlueSphereMeter(boolean gametypeinfoshown)
static void K_drawKartBumpersOrKarma(void)
{
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, stplyr->skincolor, GTC_CACHE);
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, static_cast<skincolornum_t>(stplyr->skincolor), GTC_CACHE);
INT32 splitflags = V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN;
if (r_splitscreen > 1)
@ -3401,7 +3404,7 @@ static void K_drawKartPlayerCheck(void)
if (result.onScreen == true)
{
colormap = R_GetTranslationColormap(TC_DEFAULT, checkplayer->mo->color, GTC_CACHE);
colormap = R_GetTranslationColormap(TC_DEFAULT, static_cast<skincolornum_t>(checkplayer->mo->color), GTC_CACHE);
V_DrawFixedPatch(result.x, y, FRACUNIT, V_HUDTRANS|V_SPLITSCREEN|splitflags, kp_check[pnum], colormap);
}
}
@ -3441,7 +3444,7 @@ static boolean K_ShowPlayerNametag(player_t *p)
static void K_DrawLocalTagForPlayer(fixed_t x, fixed_t y, player_t *p, UINT8 id)
{
UINT8 blink = ((leveltime / 7) & 1);
UINT8 *colormap = R_GetTranslationColormap(TC_RAINBOW, p->skincolor, GTC_CACHE);
UINT8 *colormap = R_GetTranslationColormap(TC_RAINBOW, static_cast<skincolornum_t>(p->skincolor), GTC_CACHE);
V_DrawFixedPatch(x, y, FRACUNIT, V_HUDTRANS|V_SPLITSCREEN, kp_localtag[id][blink], colormap);
}
@ -3551,9 +3554,9 @@ static void K_DrawWeakSpot(weakspotdraw_t *ws)
flashtime = WEAKSPOTANIMTIME - bossinfo.weakspots[ws->i].time;
if (flashtime & 1)
colormap = R_GetTranslationColormap(TC_ALLWHITE, 0, GTC_CACHE);
colormap = R_GetTranslationColormap(TC_ALLWHITE, SKINCOLOR_NONE, GTC_CACHE);
else
colormap = R_GetTranslationColormap(TC_RAINBOW, bossinfo.weakspots[ws->i].color, GTC_CACHE);
colormap = R_GetTranslationColormap(TC_RAINBOW, static_cast<skincolornum_t>(bossinfo.weakspots[ws->i].color), GTC_CACHE);
V_DrawFixedPatch(ws->x, ws->y, FRACUNIT, 0, kp_bossret[j], colormap);
@ -3915,27 +3918,47 @@ static void K_drawKartMinimapDot(fixed_t objx, fixed_t objy, INT32 hudx, INT32 h
V_DrawFill((amxpos + hudx) - (size / 2), (amypos + hudy) - (size / 2), size, size, flags | color);
}
static void K_drawKartMinimapWaypoint(waypoint_t *wp, INT32 hudx, INT32 hudy, INT32 flags)
static UINT8 K_RankMinimapWaypoint(waypoint_t *wp)
{
UINT8 pal = 0x95; // blue
UINT8 size = 3;
if (wp == stplyr->nextwaypoint)
{
pal = 0x70; // green
size = 6;
}
else if (K_GetWaypointIsShortcut(wp)) // shortcut
{
pal = 0x20; // pink
}
else if (!K_GetWaypointIsEnabled(wp)) // disabled
{
pal = 0x10; // gray
return 4;
}
else if (wp->numnextwaypoints == 0 || wp->numprevwaypoints == 0)
{
pal = 0x40; // yellow
return 3;
}
else if (!K_GetWaypointIsEnabled(wp)) // disabled
{
return 2;
}
else if (K_GetWaypointIsShortcut(wp)) // shortcut
{
return 1;
}
else
{
return 0;
}
}
static void K_drawKartMinimapWaypoint(waypoint_t *wp, UINT8 rank, INT32 hudx, INT32 hudy, INT32 flags)
{
static UINT8 colors[] =
{
0x95, // blue (0 - default)
0x20, // pink (1 - shortcut)
0x10, // gray (2 - disabled)
0x40, // yellow (3 - error)
0x70, // green (4 - player)
};
UINT8 pal = colors[rank]; // blue
UINT8 size = 3;
if (rank == 4)
{
size = 6;
}
if (!(flags & V_NOSCALESTART))
@ -4085,7 +4108,7 @@ static void K_drawKartMinimap(void)
const INT32 prevsplitflags = splitflags;
splitflags &= ~V_HUDTRANSHALF;
splitflags |= V_HUDTRANS;
colormap = R_GetTranslationColormap(TC_RAINBOW, K_RainbowColor(leveltime), GTC_CACHE);
colormap = R_GetTranslationColormap(TC_RAINBOW, static_cast<skincolornum_t>(K_RainbowColor(leveltime)), GTC_CACHE);
K_drawKartMinimapIcon(battleovertime.x, battleovertime.y, x, y, splitflags, kp_itemminimap, colormap);
splitflags = prevsplitflags;
}
@ -4108,9 +4131,9 @@ static void K_drawKartMinimap(void)
if (g->mo->color)
{
if (g->mo->colorized)
colormap = R_GetTranslationColormap(TC_RAINBOW, g->mo->color, GTC_CACHE);
colormap = R_GetTranslationColormap(TC_RAINBOW, static_cast<skincolornum_t>(g->mo->color), GTC_CACHE);
else
colormap = R_GetTranslationColormap(skin, g->mo->color, GTC_CACHE);
colormap = R_GetTranslationColormap(skin, static_cast<skincolornum_t>(g->mo->color), GTC_CACHE);
}
else
colormap = NULL;
@ -4168,7 +4191,7 @@ static void K_drawKartMinimap(void)
}
workingPic = kp_nocontestminimap;
colormap = R_GetTranslationColormap(TC_DEFAULT, mobj->color, GTC_CACHE);
colormap = R_GetTranslationColormap(TC_DEFAULT, static_cast<skincolornum_t>(mobj->color), GTC_CACHE);
mobj = mobj->tracer;
@ -4183,9 +4206,9 @@ static void K_drawKartMinimap(void)
if (mobj->color)
{
if (mobj->colorized)
colormap = R_GetTranslationColormap(TC_RAINBOW, mobj->color, GTC_CACHE);
colormap = R_GetTranslationColormap(TC_RAINBOW, static_cast<skincolornum_t>(mobj->color), GTC_CACHE);
else
colormap = R_GetTranslationColormap(skin, mobj->color, GTC_CACHE);
colormap = R_GetTranslationColormap(skin, static_cast<skincolornum_t>(mobj->color), GTC_CACHE);
}
else
colormap = NULL;
@ -4257,7 +4280,7 @@ static void K_drawKartMinimap(void)
#endif
if (mobj->color)
{
colormap = R_GetTranslationColormap(TC_RAINBOW, mobj->color, GTC_CACHE);
colormap = R_GetTranslationColormap(TC_RAINBOW, static_cast<skincolornum_t>(mobj->color), GTC_CACHE);
}
break;
@ -4275,7 +4298,7 @@ static void K_drawKartMinimap(void)
workingPic = kp_superflickyminimap;
if (Obj_SuperFlickyOwner(mobj)->color)
{
colormap = R_GetTranslationColormap(TC_RAINBOW, (Obj_SuperFlickyOwner(mobj)->color), GTC_CACHE);
colormap = R_GetTranslationColormap(TC_RAINBOW, static_cast<skincolornum_t>(Obj_SuperFlickyOwner(mobj)->color), GTC_CACHE);
}
break;
default:
@ -4319,7 +4342,7 @@ static void K_drawKartMinimap(void)
if (specialstageinfo.ufo->color)
{
colormap = R_GetTranslationColormap(TC_DEFAULT, specialstageinfo.ufo->color, GTC_CACHE);
colormap = R_GetTranslationColormap(TC_DEFAULT, static_cast<skincolornum_t>(specialstageinfo.ufo->color), GTC_CACHE);
}
}
@ -4346,7 +4369,7 @@ static void K_drawKartMinimap(void)
colormap = NULL;
if (bossinfo.weakspots[i].color)
colormap = R_GetTranslationColormap(TC_RAINBOW, bossinfo.weakspots[i].color, GTC_CACHE);
colormap = R_GetTranslationColormap(TC_RAINBOW, static_cast<skincolornum_t>(bossinfo.weakspots[i].color), GTC_CACHE);
interpx = R_InterpolateFixed(bossinfo.weakspots[i].spot->old_x, bossinfo.weakspots[i].spot->x);
interpy = R_InterpolateFixed(bossinfo.weakspots[i].spot->old_y, bossinfo.weakspots[i].spot->y);
@ -4381,7 +4404,7 @@ static void K_drawKartMinimap(void)
}
workingPic = kp_nocontestminimap;
colormap = R_GetTranslationColormap(TC_DEFAULT, mobj->color, GTC_CACHE);
colormap = R_GetTranslationColormap(TC_DEFAULT, static_cast<skincolornum_t>(mobj->color), GTC_CACHE);
mobj = mobj->tracer;
@ -4396,9 +4419,9 @@ static void K_drawKartMinimap(void)
if (mobj->color)
{
if (mobj->colorized)
colormap = R_GetTranslationColormap(TC_RAINBOW, mobj->color, GTC_CACHE);
colormap = R_GetTranslationColormap(TC_RAINBOW, static_cast<skincolornum_t>(mobj->color), GTC_CACHE);
else
colormap = R_GetTranslationColormap(skin, mobj->color, GTC_CACHE);
colormap = R_GetTranslationColormap(skin, static_cast<skincolornum_t>(mobj->color), GTC_CACHE);
}
else
colormap = NULL;
@ -4443,21 +4466,35 @@ static void K_drawKartMinimap(void)
if (doprogressionbar == false && cv_kartdebugwaypoints.value != 0)
{
struct MiniWaypoint
{
waypoint_t* waypoint;
UINT8 rank;
MiniWaypoint(waypoint_t* wp) : waypoint(wp), rank(K_RankMinimapWaypoint(wp)) {}
bool operator<(const MiniWaypoint& b) { return rank < b.rank; }
};
std::vector<MiniWaypoint> waypoints;
size_t idx;
waypoints.reserve(K_GetNumWaypoints());
for (idx = 0; idx < K_GetNumWaypoints(); ++idx)
{
waypoint_t *wp = K_GetWaypointFromIndex(idx);
I_Assert(wp != NULL);
K_drawKartMinimapWaypoint(wp, x, y, splitflags);
waypoints.push_back(wp);
}
if (stplyr->nextwaypoint != NULL)
std::sort(waypoints.begin(), waypoints.end());
for (MiniWaypoint& wp : waypoints)
{
// should be drawn on top of the others
K_drawKartMinimapWaypoint(stplyr->nextwaypoint, x, y, splitflags);
K_drawKartMinimapWaypoint(wp.waypoint, wp.rank, x, y, splitflags);
}
}
}
@ -4507,7 +4544,7 @@ static void K_drawKartFinish(boolean finish)
x = ((vid.width<<FRACBITS)/vid.dupx);
xval = (SHORT(kptodraw[pnum]->width)<<FRACBITS);
pwidth = max(xval, x);
pwidth = std::max(xval, x);
x = ((TICRATE - timer) * pwidth) / TICRATE;
ox = ((TICRATE - (timer - 1)) * pwidth) / TICRATE;
@ -4879,9 +4916,9 @@ static void K_drawKartFirstPerson(void)
if ((leveltime & 1) && (driftcolor != SKINCOLOR_NONE)) // drift sparks!
colmap = R_GetTranslationColormap(TC_RAINBOW, driftcolor, GTC_CACHE);
colmap = R_GetTranslationColormap(TC_RAINBOW, static_cast<skincolornum_t>(driftcolor), GTC_CACHE);
else if (stplyr->mo->colorized && stplyr->mo->color) // invincibility/grow/shrink!
colmap = R_GetTranslationColormap(TC_RAINBOW, stplyr->mo->color, GTC_CACHE);
colmap = R_GetTranslationColormap(TC_RAINBOW, static_cast<skincolornum_t>(stplyr->mo->color), GTC_CACHE);
}
V_DrawFixedPatch(x, y, scale, splitflags, kp_fpview[target], colmap);
@ -4970,7 +5007,7 @@ static void K_drawInput(void)
else
{
UINT8 *colormap;
colormap = R_GetTranslationColormap(TC_DEFAULT, stplyr->skincolor, GTC_CACHE);
colormap = R_GetTranslationColormap(TC_DEFAULT, static_cast<skincolornum_t>(stplyr->skincolor), GTC_CACHE);
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT, splitflags, kp_inputwheel[target], colormap);
}
}
@ -4985,7 +5022,7 @@ static void K_drawChallengerScreen(void)
19,20,19,20,19,20,19,20,19,20, // frame 20-21, 1 tic, 5 alternating: all text vibrates from impact
21,22,23,24 // frame 22-25, 1 tic: CHALLENGER turns gold
};
const UINT8 offset = min(52-1, (3*TICRATE)-mapreset);
const UINT8 offset = std::min(52-1u, (3*TICRATE)-mapreset);
V_DrawFadeScreen(0xFF00, 16); // Fade out
V_DrawScaledPatch(0, 0, 0, kp_challenger[anim[offset]]);
@ -5002,16 +5039,16 @@ static void K_drawLapStartAnim(void)
const tic_t leveltimeOld = leveltime - 1;
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, stplyr->skincolor, GTC_CACHE);
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, static_cast<skincolornum_t>(stplyr->skincolor), GTC_CACHE);
fixed_t interpx, interpy, newval, oldval;
newval = (BASEVIDWIDTH/2 + (32 * max(0, t - 76))) * FRACUNIT;
oldval = (BASEVIDWIDTH/2 + (32 * max(0, tOld - 76))) * FRACUNIT;
newval = (BASEVIDWIDTH/2 + (32 * std::max(0, t - 76))) * FRACUNIT;
oldval = (BASEVIDWIDTH/2 + (32 * std::max(0, tOld - 76))) * FRACUNIT;
interpx = R_InterpolateFixed(oldval, newval);
newval = (48 - (32 * max(0, progress - 76))) * FRACUNIT;
oldval = (48 - (32 * max(0, progressOld - 76))) * FRACUNIT;
newval = (48 - (32 * std::max(0, progress - 76))) * FRACUNIT;
oldval = (48 - (32 * std::max(0, progressOld - 76))) * FRACUNIT;
interpy = R_InterpolateFixed(oldval, newval);
V_DrawFixedPatch(
@ -5033,64 +5070,64 @@ static void K_drawLapStartAnim(void)
if (stplyr->latestlap == (UINT8)(numlaps))
{
newval = (62 - (32 * max(0, progress - 76))) * FRACUNIT;
oldval = (62 - (32 * max(0, progressOld - 76))) * FRACUNIT;
newval = (62 - (32 * std::max(0, progress - 76))) * FRACUNIT;
oldval = (62 - (32 * std::max(0, progressOld - 76))) * FRACUNIT;
interpx = R_InterpolateFixed(oldval, newval);
V_DrawFixedPatch(
interpx, // 27
30*FRACUNIT, // 24
FRACUNIT, V_SNAPTOTOP|V_HUDTRANS,
kp_lapanim_final[min(progress/2, 10)], NULL);
kp_lapanim_final[std::min(progress/2, 10)], NULL);
if (progress/2-12 >= 0)
{
newval = (188 + (32 * max(0, progress - 76))) * FRACUNIT;
oldval = (188 + (32 * max(0, progressOld - 76))) * FRACUNIT;
newval = (188 + (32 * std::max(0, progress - 76))) * FRACUNIT;
oldval = (188 + (32 * std::max(0, progressOld - 76))) * FRACUNIT;
interpx = R_InterpolateFixed(oldval, newval);
V_DrawFixedPatch(
interpx, // 194
30*FRACUNIT, // 24
FRACUNIT, V_SNAPTOTOP|V_HUDTRANS,
kp_lapanim_lap[min(progress/2-12, 6)], NULL);
kp_lapanim_lap[std::min(progress/2-12, 6)], NULL);
}
}
else
{
newval = (82 - (32 * max(0, progress - 76))) * FRACUNIT;
oldval = (82 - (32 * max(0, progressOld - 76))) * FRACUNIT;
newval = (82 - (32 * std::max(0, progress - 76))) * FRACUNIT;
oldval = (82 - (32 * std::max(0, progressOld - 76))) * FRACUNIT;
interpx = R_InterpolateFixed(oldval, newval);
V_DrawFixedPatch(
interpx, // 61
30*FRACUNIT, // 24
FRACUNIT, V_SNAPTOTOP|V_HUDTRANS,
kp_lapanim_lap[min(progress/2, 6)], NULL);
kp_lapanim_lap[std::min(progress/2, 6)], NULL);
if (progress/2-8 >= 0)
{
newval = (188 + (32 * max(0, progress - 76))) * FRACUNIT;
oldval = (188 + (32 * max(0, progressOld - 76))) * FRACUNIT;
newval = (188 + (32 * std::max(0, progress - 76))) * FRACUNIT;
oldval = (188 + (32 * std::max(0, progressOld - 76))) * FRACUNIT;
interpx = R_InterpolateFixed(oldval, newval);
V_DrawFixedPatch(
interpx, // 194
30*FRACUNIT, // 24
FRACUNIT, V_SNAPTOTOP|V_HUDTRANS,
kp_lapanim_number[(((UINT32)stplyr->latestlap) / 10)][min(progress/2-8, 2)], NULL);
kp_lapanim_number[(((UINT32)stplyr->latestlap) / 10)][std::min(progress/2-8, 2)], NULL);
if (progress/2-10 >= 0)
{
newval = (208 + (32 * max(0, progress - 76))) * FRACUNIT;
oldval = (208 + (32 * max(0, progressOld - 76))) * FRACUNIT;
newval = (208 + (32 * std::max(0, progress - 76))) * FRACUNIT;
oldval = (208 + (32 * std::max(0, progressOld - 76))) * FRACUNIT;
interpx = R_InterpolateFixed(oldval, newval);
V_DrawFixedPatch(
interpx, // 221
30*FRACUNIT, // 24
FRACUNIT, V_SNAPTOTOP|V_HUDTRANS,
kp_lapanim_number[(((UINT32)stplyr->latestlap) % 10)][min(progress/2-10, 2)], NULL);
kp_lapanim_number[(((UINT32)stplyr->latestlap) % 10)][std::min(progress/2-10, 2)], NULL);
}
}
}
@ -5223,7 +5260,7 @@ static void K_drawDistributionDebugger(void)
for (i = 0; i < rouletteData.itemListLen; i++)
{
const kartitems_t item = rouletteData.itemList[i];
const kartitems_t item = static_cast<kartitems_t>(rouletteData.itemList[i]);
UINT8 amount = 1;
if (y > (BASEVIDHEIGHT << FRACBITS) - space - pad)
@ -5503,7 +5540,7 @@ void K_drawKartHUD(void)
if (demo.title) // Draw title logo instead in demo.titles
{
INT32 x = BASEVIDWIDTH - 8, y = BASEVIDHEIGHT-8, snapflags = V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_SLIDEIN;
patch_t *pat = W_CachePatchName((cv_alttitle.value ? "MTSJUMPR1" : "MTSBUMPR1"), PU_CACHE);
patch_t *pat = static_cast<patch_t*>(W_CachePatchName((cv_alttitle.value ? "MTSJUMPR1" : "MTSBUMPR1"), PU_CACHE));
if (r_splitscreen == 3)
{
@ -5678,7 +5715,7 @@ void K_drawKartHUD(void)
{
if (skincolors[c].accessible)
{
UINT8 *cm = R_GetTranslationColormap(TC_RAINBOW, c, GTC_CACHE);
UINT8 *cm = R_GetTranslationColormap(TC_RAINBOW, static_cast<skincolornum_t>(c), GTC_CACHE);
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT>>1, 0, faceprefix[stplyr->skin][FACE_WANTED], cm);
x += 16;
@ -5704,12 +5741,12 @@ void K_DrawSticker(INT32 x, INT32 y, INT32 width, INT32 flags, boolean isSmall)
if (isSmall == true)
{
stickerEnd = W_CachePatchName("K_STIKE2", PU_CACHE);
stickerEnd = static_cast<patch_t*>(W_CachePatchName("K_STIKE2", PU_CACHE));
height = 6;
}
else
{
stickerEnd = W_CachePatchName("K_STIKEN", PU_CACHE);
stickerEnd = static_cast<patch_t*>(W_CachePatchName("K_STIKEN", PU_CACHE));
height = 11;
}

View file

@ -2830,7 +2830,7 @@ void K_MomentumToFacing(player_t *player)
player->mo->momy = FixedMul(player->mo->momy - player->cmomy, player->mo->friction) + player->cmomy;
}
boolean K_ApplyOffroad(player_t *player)
boolean K_ApplyOffroad(const player_t *player)
{
if (player->invincibilitytimer || player->hyudorotimer || player->sneakertimer)
return false;
@ -2839,7 +2839,7 @@ boolean K_ApplyOffroad(player_t *player)
return true;
}
boolean K_SlopeResistance(player_t *player)
boolean K_SlopeResistance(const player_t *player)
{
if (player->invincibilitytimer || player->sneakertimer || player->tiregrease || player->flamedash)
return true;
@ -2848,7 +2848,7 @@ boolean K_SlopeResistance(player_t *player)
return false;
}
tripwirepass_t K_TripwirePassConditions(player_t *player)
tripwirepass_t K_TripwirePassConditions(const player_t *player)
{
if (
player->invincibilitytimer ||
@ -2871,7 +2871,7 @@ tripwirepass_t K_TripwirePassConditions(player_t *player)
return TRIPWIRE_NONE;
}
boolean K_TripwirePass(player_t *player)
boolean K_TripwirePass(const player_t *player)
{
return (player->tripwirePass != TRIPWIRE_NONE);
}
@ -3156,7 +3156,7 @@ void K_SpawnWaterRunParticles(mobj_t *mobj)
}
}
boolean K_IsRidingFloatingTop(player_t *player)
boolean K_IsRidingFloatingTop(const player_t *player)
{
if (player->curshield != KSHIELD_TOP)
{
@ -3166,7 +3166,7 @@ boolean K_IsRidingFloatingTop(player_t *player)
return !Obj_GardenTopPlayerIsGrinding(player);
}
boolean K_IsHoldingDownTop(player_t *player)
boolean K_IsHoldingDownTop(const player_t *player)
{
if (player->curshield != KSHIELD_TOP)
{
@ -3181,7 +3181,7 @@ boolean K_IsHoldingDownTop(player_t *player)
return true;
}
mobj_t *K_GetGardenTop(player_t *player)
mobj_t *K_GetGardenTop(const player_t *player)
{
if (player->curshield != KSHIELD_TOP)
{
@ -3202,14 +3202,14 @@ static fixed_t K_FlameShieldDashVar(INT32 val)
return (3*FRACUNIT/4) + (((val * FRACUNIT) / TICRATE));
}
INT16 K_GetSpindashChargeTime(player_t *player)
INT16 K_GetSpindashChargeTime(const player_t *player)
{
// more charge time for higher speed
// Tails = 1.7s, Knuckles = 2.2s, Metal = 2.7s
return ((player->kartspeed + 8) * TICRATE) / 6;
}
fixed_t K_GetSpindashChargeSpeed(player_t *player)
fixed_t K_GetSpindashChargeSpeed(const player_t *player)
{
// more speed for higher weight & speed
// Tails = +16.94%, Fang = +34.94%, Mighty = +34.94%, Metal = +43.61%
@ -3406,7 +3406,7 @@ static void K_GetKartBoostPower(player_t *player)
player->numboosts = numboosts;
}
fixed_t K_GrowShrinkSpeedMul(player_t *player)
fixed_t K_GrowShrinkSpeedMul(const player_t *player)
{
fixed_t scaleDiff = player->mo->scale - mapobjectscale;
fixed_t playerScale = FixedDiv(player->mo->scale, mapobjectscale);
@ -3442,7 +3442,7 @@ fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed)
return finalspeed;
}
fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower, boolean dorubberband)
fixed_t K_GetKartSpeed(const player_t *player, boolean doboostpower, boolean dorubberband)
{
const boolean mobjValid = (player->mo != NULL && P_MobjWasRemoved(player->mo) == false);
const fixed_t physicsScale = mobjValid ? K_GrowShrinkSpeedMul(player) : FRACUNIT;
@ -3506,7 +3506,7 @@ fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower, boolean dorubberb
return finalspeed;
}
fixed_t K_GetKartAccel(player_t *player)
fixed_t K_GetKartAccel(const player_t *player)
{
fixed_t k_accel = 121;
UINT8 stat = (9 - player->kartspeed);
@ -3537,7 +3537,7 @@ fixed_t K_GetKartAccel(player_t *player)
return k_accel;
}
UINT16 K_GetKartFlashing(player_t *player)
UINT16 K_GetKartFlashing(const player_t *player)
{
UINT16 tics = flashingtics;
@ -3555,7 +3555,7 @@ UINT16 K_GetKartFlashing(player_t *player)
return tics;
}
boolean K_PlayerShrinkCheat(player_t *player)
boolean K_PlayerShrinkCheat(const player_t *player)
{
return (
(player->pflags & PF_SHRINKACTIVE)
@ -3583,20 +3583,20 @@ void K_UpdateShrinkCheat(player_t *player)
}
}
boolean K_KartKickstart(player_t *player)
boolean K_KartKickstart(const player_t *player)
{
return ((player->pflags & PF_KICKSTARTACCEL)
&& (!K_PlayerUsesBotMovement(player))
&& (player->kickstartaccel >= ACCEL_KICKSTART));
}
UINT16 K_GetKartButtons(player_t *player)
UINT16 K_GetKartButtons(const player_t *player)
{
return (player->cmd.buttons |
(K_KartKickstart(player) ? BT_ACCELERATE : 0));
}
SINT8 K_GetForwardMove(player_t *player)
SINT8 K_GetForwardMove(const player_t *player)
{
SINT8 forwardmove = player->cmd.forwardmove;
@ -3644,7 +3644,7 @@ SINT8 K_GetForwardMove(player_t *player)
return forwardmove;
}
fixed_t K_GetNewSpeed(player_t *player)
fixed_t K_GetNewSpeed(const player_t *player)
{
const fixed_t accelmax = 4000;
fixed_t p_speed = K_GetKartSpeed(player, true, true);
@ -3675,7 +3675,7 @@ fixed_t K_GetNewSpeed(player_t *player)
return finalspeed;
}
fixed_t K_3dKartMovement(player_t *player)
fixed_t K_3dKartMovement(const player_t *player)
{
fixed_t finalspeed = K_GetNewSpeed(player);
@ -8128,7 +8128,7 @@ static void K_UpdateTripwire(player_t *player)
}
}
boolean K_PressingEBrake(player_t *player)
boolean K_PressingEBrake(const player_t *player)
{
return ((K_GetKartButtons(player) & BT_EBRAKEMASK) == BT_EBRAKEMASK);
}
@ -9607,7 +9607,7 @@ void K_UpdateDistanceFromFinishLine(player_t *const player)
}
}
INT32 K_GetKartRingPower(player_t *player, boolean boosted)
INT32 K_GetKartRingPower(const player_t *player, boolean boosted)
{
fixed_t ringPower = ((9 - player->kartspeed) + (9 - player->kartweight)) * (FRACUNIT/2);
fixed_t basePower = ringPower;
@ -9657,7 +9657,7 @@ boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y)
// countersteer is how strong the controls are telling us we are turning
// turndir is the direction the controls are telling us to turn, -1 if turning right and 1 if turning left
static INT16 K_GetKartDriftValue(player_t *player, fixed_t countersteer)
static INT16 K_GetKartDriftValue(const player_t *player, fixed_t countersteer)
{
INT16 basedrift, driftadjust;
fixed_t driftweight = player->kartweight*14; // 12
@ -9733,7 +9733,7 @@ INT16 K_UpdateSteeringValue(INT16 inputSteering, INT16 destSteering)
return outputSteering;
}
static fixed_t K_GetUnderwaterStrafeMul(player_t *player)
static fixed_t K_GetUnderwaterStrafeMul(const player_t *player)
{
const fixed_t minSpeed = 11 * player->mo->scale;
fixed_t baseline = INT32_MAX;
@ -9743,7 +9743,7 @@ static fixed_t K_GetUnderwaterStrafeMul(player_t *player)
return max(0, FixedDiv(player->speed - minSpeed, baseline - minSpeed));
}
INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue)
INT16 K_GetKartTurnValue(const player_t *player, INT16 turnvalue)
{
fixed_t turnfixed = turnvalue * FRACUNIT;
@ -9877,7 +9877,7 @@ INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue)
return (turnfixed / FRACUNIT);
}
INT32 K_GetUnderwaterTurnAdjust(player_t *player)
INT32 K_GetUnderwaterTurnAdjust(const player_t *player)
{
if (player->mo->eflags & MFE_UNDERWATER)
{
@ -9893,12 +9893,12 @@ INT32 K_GetUnderwaterTurnAdjust(player_t *player)
return 0;
}
INT32 K_GetKartDriftSparkValue(player_t *player)
INT32 K_GetKartDriftSparkValue(const player_t *player)
{
return (26*4 + player->kartspeed*2 + (9 - player->kartweight))*8;
}
INT32 K_GetKartDriftSparkValueForStage(player_t *player, UINT8 stage)
INT32 K_GetKartDriftSparkValueForStage(const player_t *player, UINT8 stage)
{
fixed_t mul = FRACUNIT;
@ -10625,7 +10625,7 @@ static INT32 K_FlameShieldMax(player_t *player)
return min(FLAMESHIELD_MAX, (FLAMESHIELD_MAX / 16) + (disttofinish / distv)); // Ditto for this minimum, old value was 1/16
}
boolean K_PlayerEBrake(player_t *player)
boolean K_PlayerEBrake(const player_t *player)
{
if (player->respawn.state != RESPAWNST_NONE
&& (player->respawn.init == true || player->respawn.fromRingShooter == true))
@ -10656,7 +10656,7 @@ boolean K_PlayerEBrake(player_t *player)
return false;
}
boolean K_PlayerGuard(player_t *player)
boolean K_PlayerGuard(const player_t *player)
{
if (player->guardCooldown != 0)
{
@ -10697,7 +10697,7 @@ boolean K_PlayerGuard(player_t *player)
return false;
}
SINT8 K_Sliptiding(player_t *player)
SINT8 K_Sliptiding(const player_t *player)
{
/*
if (player->mo->eflags & MFE_UNDERWATER)
@ -11197,7 +11197,7 @@ static void K_AirFailsafe(player_t *player)
//
// K_PlayerBaseFriction
//
fixed_t K_PlayerBaseFriction(player_t *player, fixed_t original)
fixed_t K_PlayerBaseFriction(const player_t *player, fixed_t original)
{
const fixed_t factor = FixedMul(
FixedDiv(FRACUNIT - original, FRACUNIT - ORIG_FRICTION),
@ -11567,6 +11567,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
{
whip->flags2 |= MF2_AMBUSH;
}
player->botvars.itemconfirm = 0;
}
}
else if (!(player->instaWhipCharge >= INSTAWHIP_CHARGETIME && P_PlayerInPain(player))) // Allow reversal whip
@ -11599,7 +11601,10 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (player->eggmanexplode)
{
if (ATTACK_IS_DOWN && player->eggmanexplode <= 3*TICRATE && player->eggmanexplode > 1)
{
player->eggmanexplode = 1;
player->botvars.itemconfirm = 0;
}
}
// Eggman Monitor throwing
else if (player->itemflags & IF_EGGMANOUT)
@ -11610,6 +11615,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
K_PlayAttackTaunt(player->mo);
player->itemflags &= ~IF_EGGMANOUT;
K_UpdateHnextList(player, true);
player->botvars.itemconfirm = 0;
}
}
// Rocket Sneaker usage
@ -11623,6 +11629,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->rocketsneakertimer = 1;
else
player->rocketsneakertimer -= 3*TICRATE;
player->botvars.itemconfirm = 2*TICRATE;
}
}
else if (player->itemamount == 0)
@ -11639,6 +11646,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
K_DoSneaker(player, 1);
K_PlayBoostTaunt(player->mo);
player->itemamount--;
player->botvars.itemconfirm = 0;
}
break;
case KITEM_ROCKETSNEAKER:
@ -11672,6 +11680,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
P_SetTarget(&prev->hnext, mo);
prev = mo;
}
player->botvars.itemconfirm = 0;
}
break;
case KITEM_INVINCIBILITY:
@ -11680,6 +11689,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
K_DoInvincibility(player, 10 * TICRATE);
K_PlayPowerGloatSound(player->mo);
player->itemamount--;
player->botvars.itemconfirm = 0;
}
break;
case KITEM_BANANA:
@ -11711,6 +11721,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
P_SetTarget(&prev->hnext, mo);
prev = mo;
}
player->botvars.itemconfirm = 0;
}
else if (ATTACK_IS_DOWN && (player->itemflags & IF_ITEMOUT)) // Banana x3 thrown
{
@ -11718,6 +11729,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
K_PlayAttackTaunt(player->mo);
player->itemamount--;
K_UpdateHnextList(player, false);
player->botvars.itemconfirm = 0;
}
break;
case KITEM_EGGMAN:
@ -11739,6 +11751,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
P_SetTarget(&mo->target, player->mo);
P_SetTarget(&player->mo->hnext, mo);
}
player->botvars.itemconfirm = 0;
}
break;
case KITEM_ORBINAUT:
@ -11774,6 +11787,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
P_SetTarget(&prev->hnext, mo);
prev = mo;
}
player->botvars.itemconfirm = 0;
}
else if (ATTACK_IS_DOWN && (player->itemflags & IF_ITEMOUT)) // Orbinaut x3 thrown
{
@ -11781,6 +11795,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
K_PlayAttackTaunt(player->mo);
player->itemamount--;
K_UpdateHnextList(player, false);
player->botvars.itemconfirm = 0;
}
break;
case KITEM_JAWZ:
@ -11815,6 +11830,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
P_SetTarget(&prev->hnext, mo);
prev = mo;
}
player->botvars.itemconfirm = 0;
}
else if (ATTACK_IS_DOWN && HOLDING_ITEM && (player->itemflags & IF_ITEMOUT)) // Jawz thrown
{
@ -11822,6 +11838,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
K_PlayAttackTaunt(player->mo);
player->itemamount--;
K_UpdateHnextList(player, false);
player->botvars.itemconfirm = 0;
}
break;
case KITEM_MINE:
@ -11841,6 +11858,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
P_SetTarget(&mo->target, player->mo);
P_SetTarget(&player->mo->hnext, mo);
}
player->botvars.itemconfirm = 0;
}
else if (ATTACK_IS_DOWN && (player->itemflags & IF_ITEMOUT))
{
@ -11849,6 +11867,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->itemamount--;
player->itemflags &= ~IF_ITEMOUT;
K_UpdateHnextList(player, true);
player->botvars.itemconfirm = 0;
}
break;
case KITEM_LANDMINE:
@ -11857,6 +11876,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->itemamount--;
K_ThrowLandMine(player);
K_PlayAttackTaunt(player->mo);
player->botvars.itemconfirm = 0;
}
break;
case KITEM_DROPTARGET:
@ -11876,6 +11896,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
P_SetTarget(&mo->target, player->mo);
P_SetTarget(&player->mo->hnext, mo);
}
player->botvars.itemconfirm = 0;
}
else if (ATTACK_IS_DOWN && (player->itemflags & IF_ITEMOUT))
{
@ -11884,6 +11905,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->itemamount--;
player->itemflags &= ~IF_ITEMOUT;
K_UpdateHnextList(player, true);
player->botvars.itemconfirm = 0;
}
break;
case KITEM_BALLHOG:
@ -11966,6 +11988,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->ballhogcharge = 0;
player->itemflags &= ~IF_HOLDREADY;
player->botvars.itemconfirm = 0;
}
}
}
@ -11976,6 +11999,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->itemamount--;
K_ThrowKartItem(player, true, MT_SPB, 1, 0, 0);
K_PlayAttackTaunt(player->mo);
player->botvars.itemconfirm = 0;
}
break;
case KITEM_GROW:
@ -12011,6 +12035,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
S_StartSound(player->mo, sfx_kc5a);
player->itemamount--;
player->botvars.itemconfirm = 0;
}
break;
case KITEM_SHRINK:
@ -12019,6 +12044,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
K_DoShrink(player);
player->itemamount--;
K_PlayPowerGloatSound(player->mo);
player->botvars.itemconfirm = 0;
}
break;
case KITEM_LIGHTNINGSHIELD:
@ -12043,6 +12069,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
// ...:dumbestass:
player->itemamount--;
K_PlayAttackTaunt(player->mo);
player->botvars.itemconfirm = 0;
}
}
break;
@ -12050,6 +12077,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (player->curshield == KSHIELD_TOP && K_GetGardenTop(player) == NULL)
{
Obj_GardenTopDeploy(player->mo);
player->botvars.itemconfirm = 0;
}
else if (ATTACK_IS_DOWN && NO_HYUDORO)
{
@ -12085,6 +12113,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
K_PlayAttackTaunt(player->mo);
}
}
player->botvars.itemconfirm = 0;
}
break;
case KITEM_BUBBLESHIELD:
@ -12121,6 +12151,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->bubblecool = 0;
player->itemflags &= ~IF_HOLDREADY;
player->itemamount--;
player->botvars.itemconfirm = 0;
}
}
else
@ -12207,6 +12238,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
else
{
player->itemflags |= IF_HOLDREADY;
player->botvars.itemconfirm = 3*flamemax/4;
if (!(gametyperules & GTR_CLOSERPLAYERS) || leveltime % 6 == 0)
{
@ -12216,7 +12248,6 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (!player->flamemeter)
S_StopSoundByID(player->mo, sfx_fshld3);
}
}
if (player->flamelength > destlen)
@ -12240,6 +12271,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
//K_DoHyudoroSteal(player); // yes. yes they do.
Obj_HyudoroDeploy(player->mo);
K_PlayAttackTaunt(player->mo);
player->botvars.itemconfirm = 0;
}
break;
case KITEM_POGOSPRING:
@ -12249,6 +12281,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
//K_DoPogoSpring(player->mo, 32<<FRACBITS, 2);
P_SpawnMobjFromMobj(player->mo, 0, 0, 0, MT_POGOSPRING);
player->itemamount--;
player->botvars.itemconfirm = 0;
}
break;
case KITEM_SUPERRING:
@ -12256,6 +12289,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
{
K_AwardPlayerRings(player, 20, true);
player->itemamount--;
player->botvars.itemconfirm = 0;
}
break;
case KITEM_KITCHENSINK:
@ -12275,6 +12309,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
P_SetTarget(&mo->target, player->mo);
P_SetTarget(&player->mo->hnext, mo);
}
player->botvars.itemconfirm = 0;
}
else if (ATTACK_IS_DOWN && HOLDING_ITEM && (player->itemflags & IF_ITEMOUT)) // Sink thrown
{
@ -12283,6 +12318,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->itemamount--;
player->itemflags &= ~IF_ITEMOUT;
K_UpdateHnextList(player, true);
player->botvars.itemconfirm = 0;
}
break;
case KITEM_GACHABOM:
@ -12296,6 +12332,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
? 1 : 0xFF
);
K_UpdateHnextList(player, false);
player->botvars.itemconfirm = 0;
}
break;
case KITEM_SAD:
@ -12304,6 +12341,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
{
player->sadtimer = stealtime;
player->itemamount--;
player->botvars.itemconfirm = 0;
}
break;
default:

View file

@ -99,7 +99,7 @@ void K_SpawnBumpEffect(mobj_t *mo);
void K_KartMoveAnimation(player_t *player);
void K_KartPlayerHUDUpdate(player_t *player);
void K_KartResetPlayerColor(player_t *player);
boolean K_PressingEBrake(player_t *player);
boolean K_PressingEBrake(const player_t *player);
void K_KartPlayerThink(player_t *player, ticcmd_t *cmd);
void K_KartPlayerAfterThink(player_t *player);
angle_t K_MomentumAngleEx(const mobj_t *mo, const fixed_t threshold);
@ -151,15 +151,15 @@ void K_DropHnextList(player_t *player);
void K_RepairOrbitChain(mobj_t *orbit);
void K_CalculateBananaSlope(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z, fixed_t radius, fixed_t height, boolean flip, boolean player);
mobj_t *K_FindJawzTarget(mobj_t *actor, player_t *source, angle_t range);
INT32 K_GetKartRingPower(player_t *player, boolean boosted);
INT32 K_GetKartRingPower(const player_t *player, boolean boosted);
void K_UpdateDistanceFromFinishLine(player_t *const player);
boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y);
INT16 K_UpdateSteeringValue(INT16 inputSteering, INT16 destSteering);
INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue);
INT32 K_GetUnderwaterTurnAdjust(player_t *player);
INT32 K_GetKartDriftSparkValue(player_t *player);
INT16 K_GetKartTurnValue(const player_t *player, INT16 turnvalue);
INT32 K_GetUnderwaterTurnAdjust(const player_t *player);
INT32 K_GetKartDriftSparkValue(const player_t *player);
INT32 K_StairJankFlip(INT32 value);
INT32 K_GetKartDriftSparkValueForStage(player_t *player, UINT8 stage);
INT32 K_GetKartDriftSparkValueForStage(const player_t *player, UINT8 stage);
void K_SpawnDriftBoostExplosion(player_t *player, int stage);
void K_SpawnDriftElectricSparks(player_t *player, int color, boolean shockwave);
void K_KartUpdatePosition(player_t *player);
@ -175,37 +175,37 @@ void K_DropKitchenSink(player_t *player);
void K_StripItems(player_t *player);
void K_StripOther(player_t *player);
void K_MomentumToFacing(player_t *player);
boolean K_ApplyOffroad(player_t *player);
boolean K_SlopeResistance(player_t *player);
tripwirepass_t K_TripwirePassConditions(player_t *player);
boolean K_TripwirePass(player_t *player);
boolean K_ApplyOffroad(const player_t *player);
boolean K_SlopeResistance(const player_t *player);
tripwirepass_t K_TripwirePassConditions(const player_t *player);
boolean K_TripwirePass(const player_t *player);
boolean K_MovingHorizontally(mobj_t *mobj);
boolean K_WaterRun(mobj_t *mobj);
boolean K_WaterSkip(mobj_t *mobj);
void K_SpawnWaterRunParticles(mobj_t *mobj);
boolean K_IsRidingFloatingTop(player_t *player);
boolean K_IsHoldingDownTop(player_t *player);
mobj_t *K_GetGardenTop(player_t *player);
boolean K_IsRidingFloatingTop(const player_t *player);
boolean K_IsHoldingDownTop(const player_t *player);
mobj_t *K_GetGardenTop(const player_t *player);
void K_ApplyTripWire(player_t *player, tripwirestate_t state);
INT16 K_GetSpindashChargeTime(player_t *player);
fixed_t K_GetSpindashChargeSpeed(player_t *player);
fixed_t K_GrowShrinkSpeedMul(player_t *player);
INT16 K_GetSpindashChargeTime(const player_t *player);
fixed_t K_GetSpindashChargeSpeed(const player_t *player);
fixed_t K_GrowShrinkSpeedMul(const player_t *player);
fixed_t K_GetKartSpeedFromStat(UINT8 kartspeed);
fixed_t K_GetKartSpeed(player_t *player, boolean doboostpower, boolean dorubberbanding);
fixed_t K_GetKartAccel(player_t *player);
UINT16 K_GetKartFlashing(player_t *player);
boolean K_PlayerShrinkCheat(player_t *player);
fixed_t K_GetKartSpeed(const player_t *player, boolean doboostpower, boolean dorubberbanding);
fixed_t K_GetKartAccel(const player_t *player);
UINT16 K_GetKartFlashing(const player_t *player);
boolean K_PlayerShrinkCheat(const player_t *player);
void K_UpdateShrinkCheat(player_t *player);
boolean K_KartKickstart(player_t *player);
UINT16 K_GetKartButtons(player_t *player);
SINT8 K_GetForwardMove(player_t *player);
fixed_t K_GetNewSpeed(player_t *player);
fixed_t K_3dKartMovement(player_t *player);
boolean K_PlayerEBrake(player_t *player);
boolean K_PlayerGuard(player_t *player);
SINT8 K_Sliptiding(player_t *player);
boolean K_KartKickstart(const player_t *player);
UINT16 K_GetKartButtons(const player_t *player);
SINT8 K_GetForwardMove(const player_t *player);
fixed_t K_GetNewSpeed(const player_t *player);
fixed_t K_3dKartMovement(const player_t *player);
boolean K_PlayerEBrake(const player_t *player);
boolean K_PlayerGuard(const player_t *player);
SINT8 K_Sliptiding(const player_t *player);
boolean K_FastFallBounce(player_t *player);
fixed_t K_PlayerBaseFriction(player_t *player, fixed_t original);
fixed_t K_PlayerBaseFriction(const player_t *player, fixed_t original);
void K_AdjustPlayerFriction(player_t *player);
void K_MoveKartPlayer(player_t *player, boolean onground);
void K_CheckSpectateStatus(boolean considermapreset);

View file

@ -26,7 +26,7 @@ mobj_t *Obj_GardenTopDestroy(player_t *player);
void Obj_GardenTopThink(mobj_t *top);
void Obj_GardenTopSparkThink(mobj_t *spark);
void Obj_GardenTopArrowThink(mobj_t *arrow);
boolean Obj_GardenTopPlayerIsGrinding(player_t *player);
boolean Obj_GardenTopPlayerIsGrinding(const player_t *player);
/* Shrink */
void Obj_PohbeeThinker(mobj_t *pohbee);
@ -135,7 +135,7 @@ void Obj_ChargeExtraThink(mobj_t *extra);
/* Ring Shooter */
boolean Obj_RingShooterThinker(mobj_t *mo);
boolean Obj_PlayerRingShooterFreeze(player_t *const player);
boolean Obj_PlayerRingShooterFreeze(const player_t *player);
void Obj_RingShooterInput(player_t *player);
void Obj_PlayerUsedRingShooter(mobj_t *base, player_t *player);
void Obj_RingShooterDelete(mobj_t *mo);
@ -326,7 +326,7 @@ void Obj_BoxSideThink(mobj_t *mo);
void Obj_TryCrateInit(mobj_t *mo);
boolean Obj_TryCrateThink(mobj_t *mo);
void Obj_TryCrateTouch(mobj_t *special, mobj_t *toucher);
void Obj_TryCrateDamage(mobj_t *target, mobj_t *inflictor);
boolean Obj_TryCrateDamage(mobj_t *target, mobj_t *inflictor);
boolean Obj_SA2CrateIsMetal(mobj_t *mo);
/* Lavender Shrine Spears */

View file

@ -2474,12 +2474,14 @@ static INT32 K_CalculateTrackComplexity(void)
waypoint_t *const mid = (waypoint_t *)path.array[ i ].nodedata;
waypoint_t *const end = (waypoint_t *)path.array[ i + 1 ].nodedata;
const INT32 turn_id = K_GetWaypointID(mid);
// would it be better to just check mid?
if (K_GetWaypointIsSpawnpoint(start) == false
|| K_GetWaypointIsSpawnpoint(mid) == false
|| K_GetWaypointIsSpawnpoint(end) == false)
{
CONS_Debug(DBG_SETUP, "%s", fmt::format("TURN [{}]: skipped\n", i).c_str());
CONS_Debug(DBG_SETUP, "%s", fmt::format("TURN [{}]: skipped\n", turn_id).c_str());
continue;
}
@ -2618,18 +2620,20 @@ static INT32 K_CalculateTrackComplexity(void)
)
);
constexpr fixed_t minimum_drop = 45 * FRACUNIT; // If the delta is lower than this, it's probably just a slope.
constexpr fixed_t minimum_drop = 30 * FRACUNIT; // If the delta is lower than this, it's probably just a slope.
if (pitch_delta > minimum_drop)
{
// bonus complexity for drop-off / ramp
delta += FixedMul(pitch_delta, FRACUNIT + (pitch_delta - minimum_drop));
constexpr fixed_t drop_factor = 10 * FRACUNIT;
const fixed_t drop_off_mul = FRACUNIT + FixedDiv(pitch_delta - minimum_drop, drop_factor);
delta += FixedMul(pitch_delta, drop_off_mul);
}
delta = FixedMul(delta, FixedMul(FixedMul(dist_factor, radius_factor), wall_factor));
std::string msg = fmt::format(
"TURN [{}]: r: {:.2f}, d: {:.2f}, w: {:.2f}, r*d*w: {:.2f}, DELTA: {}\n",
i,
turn_id,
FixedToFloat(radius_factor),
FixedToFloat(dist_factor),
FixedToFloat(wall_factor),
@ -2771,8 +2775,7 @@ boolean K_SetupWaypointList(void)
finishline = firstwaypoint;
}
if (K_SetupCircuitLength() == 0
&& ((mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE) != LF_SECTIONRACE))
if (K_SetupCircuitLength() == 0)
{
CONS_Alert(CONS_ERROR, "Circuit track waypoints do not form a circuit.\n");
}

View file

@ -284,7 +284,7 @@ typedef enum {
#define GDMAX_RINGS 999999999
#define GDMAX_CHAOKEYS 9999
#define GDCONVERT_ROUNDSTOKEY 32
#define GDCONVERT_ROUNDSTOKEY 14
#define GDINIT_CHAOKEYS 3 // Start with 3 Chao Keys !!
#define GDINIT_PRISONSTOPRIZE 30 // 30 Prison Eggs to your [Wild Prize] !!

View file

@ -25,7 +25,7 @@ target_sources(SRB2SDL2 PRIVATE
options-profiles-edit-controls.c
options-server-1.c
options-server-advanced.c
options-sound.c
options-sound.cpp
options-video-1.c
options-video-gl.c
options-video-modes.c

View file

@ -1,66 +0,0 @@
/// \file menus/options-sound.c
/// \brief Sound Options
#include "../k_menu.h"
#include "../s_sound.h" // sounds consvars
#include "../g_game.h" // cv_chatnotifications
menuitem_t OPTIONS_Sound[] =
{
{IT_STRING | IT_CVAR, "SFX", "Enable or disable sound effect playback.",
NULL, {.cvar = &cv_gamesounds}, 0, 0},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, "SFX Volume", "Adjust the volume of sound effects.",
NULL, {.cvar = &cv_soundvolume}, 0, 0},
{IT_STRING | IT_CVAR, "Music", "Enable or disable music playback.",
NULL, {.cvar = &cv_gamedigimusic}, 0, 0},
{IT_STRING | IT_CVAR | IT_CV_SLIDER, "Music Volume", "Adjust the volume of music playback.",
NULL, {.cvar = &cv_digmusicvolume}, 0, 0},
{IT_SPACE | IT_NOTHING, NULL, NULL,
NULL, {NULL}, 0, 0},
{IT_STRING | IT_CVAR, "Reverse L/R Channels", "Reverse left & right channels for Stereo playback.",
NULL, {.cvar = &stereoreverse}, 0, 0},
{IT_SPACE | IT_NOTHING, NULL, NULL,
NULL, {NULL}, 0, 0},
{IT_STRING | IT_CVAR, "Chat Notifications", "Set when to play notification sounds when chat messages are received.",
NULL, {.cvar = &cv_chatnotifications}, 0, 0},
{IT_STRING | IT_CVAR, "Character Voices", "Set how often to play character voices in game.",
NULL, {.cvar = &cv_kartvoices}, 0, 0},
{IT_SPACE | IT_NOTHING, NULL, NULL,
NULL, {NULL}, 0, 0},
{IT_STRING | IT_CVAR, "Play Music While Unfocused", "Keeps playing music even if the game is not the active window.",
NULL, {.cvar = &cv_playmusicifunfocused}, 0, 0},
{IT_STRING | IT_CVAR, "Play SFX While Unfocused", "Keeps playing sound effects even if the game is not the active window.",
NULL, {.cvar = &cv_playsoundifunfocused}, 0, 0},
// @TODO: Sound test (there's currently no space on this menu, might be better to throw it in extras?)
};
menu_t OPTIONS_SoundDef = {
sizeof (OPTIONS_Sound) / sizeof (menuitem_t),
&OPTIONS_MainDef,
0,
OPTIONS_Sound,
48, 80,
SKINCOLOR_THUNDER, 0,
MBF_DRAWBGWHILEPLAYING,
NULL,
2, 5,
M_DrawGenericOptions,
M_DrawOptionsCogs,
M_OptionsTick,
NULL,
NULL,
NULL,
};

280
src/menus/options-sound.cpp Normal file
View file

@ -0,0 +1,280 @@
/// \file menus/options-sound.c
/// \brief Sound Options
#include <array>
#include <cstdlib>
#include "../v_draw.hpp"
#include "../doomstat.h"
#include "../console.h"
#include "../k_menu.h"
#include "../m_cond.h"
#include "../s_sound.h" // sounds consvars
#include "../g_game.h" // cv_chatnotifications
extern "C" consvar_t cv_mastervolume;
using srb2::Draw;
namespace
{
bool basic_options()
{
// M_GameTrulyStarted
return gamedata && gamestartchallenge < MAXUNLOCKABLES && !netgame && gamedata->gonerlevel <= GDGONER_PROFILE;
}
int flip_delay = 0;
struct Slider
{
enum Id
{
kMasterVolume,
kMusicVolume,
kSfxVolume,
kNumSliders
};
Slider(bool(*toggle)(bool), consvar_t& volume) : toggle_(toggle), volume_(volume) {}
bool(*toggle_)(bool);
consvar_t& volume_;
int shake_ = 0;
void draw(int x, int y, bool shaded, bool selected)
{
constexpr int kWidth = 111;
Draw h(320 - x - kWidth, y);
if (selected)
{
int ofs = skullAnimCounter / 5;
Draw arrows = h.font(Draw::Font::kConsole).align(Draw::Align::kLeft).flags(highlightflags);
arrows.x(-10 - ofs).text("\x1C");
arrows.x(kWidth + 2 + ofs).text("\x1D");
if (!basic_options())
{
h.xy(kWidth + 9, -3).small_button(Draw::Button::z, false);
}
}
h = h.y(1);
h.size(kWidth, 7).fill(31);
Draw s = shaded ? h.xy(1, 5).size(10, 1) : h.xy(1, 2).size(10, 4);
int color = toggle_(false) ? aquamap[0] : 15;
int n = volume_.value / 10;
for (int i = 0; i < n; ++i)
{
s.fill(color);
s = s.x(11);
}
s.width(volume_.value % 10).fill(color);
n = std::atoi(volume_.defaultvalue);
h.x(1 + shake_ + n + (n / 10)).size(1, 7).fill(35);
if (!toggle_(false))
{
h
.x(kWidth / 2)
.font(Draw::Font::kConsole)
.align(Draw::Align::kCenter)
.flags(V_40TRANS)
.text("S I L E N T");
}
}
void input(INT32 c)
{
if (c == -1 && &volume_ == &cv_mastervolume)
{
// Master volume does not necessarily change when
// music or sound volumes change separately. So
// cv_mastervolume could still have its default
// value, and M_ChangeCvarDirect would do
// nothing.
CV_Set(&cv_digmusicvolume, cv_mastervolume.defaultvalue);
CV_Set(&cv_soundvolume, cv_mastervolume.defaultvalue);
}
else
{
M_ChangeCvarDirect(c, &volume_);
}
shake_ = !shake_;
flip_delay = 2;
}
};
std::array<Slider, Slider::kNumSliders> sliders{{
{
[](bool toggle) -> bool
{
bool n = !S_MusicDisabled() || !S_SoundDisabled();
if (toggle)
{
n = !n;
CV_SetValue(&cv_gamedigimusic, n);
CV_SetValue(&cv_gamesounds, n);
}
return n;
},
cv_mastervolume,
},
{
[](bool toggle) -> bool
{
if (toggle)
{
CV_AddValue(&cv_gamedigimusic, 1);
}
return !S_MusicDisabled();
},
cv_digmusicvolume,
},
{
[](bool toggle) -> bool
{
if (toggle)
{
CV_AddValue(&cv_gamesounds, 1);
}
return !S_SoundDisabled();
},
cv_soundvolume,
},
}};
void slider_routine(INT32 c)
{
sliders.at(currentMenu->menuitems[itemOn].mvar2).input(c);
}
void restartaudio_routine(INT32)
{
COM_ImmedExecute("restartaudio");
}
void draw_routine()
{
int x = currentMenu->x - (menutransition.tics * 48);
int y = currentMenu->y;
M_DrawGenericOptions();
for (int i = 0; i < currentMenu->numitems; ++i)
{
const menuitem_t& it = currentMenu->menuitems[i];
if ((it.status & IT_TYPE) == IT_ARROWS)
{
sliders.at(it.mvar2).draw(
x,
y,
it.mvar2 == Slider::kMasterVolume,
i == itemOn
);
}
y += 8;
}
}
void tick_routine(void)
{
M_OptionsTick();
if (flip_delay && !--flip_delay)
{
for (Slider& slider : sliders)
{
slider.shake_ = 0;
}
}
}
boolean input_routine(INT32)
{
UINT8 pid = 0; // todo: Add ability for any splitscreen player to bring up the menu.
const menuitem_t& it = currentMenu->menuitems[itemOn];
if (M_MenuButtonPressed(pid, MBT_Z) && (it.status & IT_TYPE) == IT_ARROWS && !basic_options())
{
sliders.at(it.mvar2).toggle_(true);
return true;
}
return false;
}
}; // namespace
menuitem_t OPTIONS_Sound[] =
{
{IT_STRING | IT_ARROWS | IT_CV_SLIDER, "Volume", "Adjust the volume of game audio.",
NULL, {.routine = slider_routine}, 0, Slider::kMasterVolume},
{IT_STRING | IT_ARROWS | IT_CV_SLIDER, "SFX Volume", "Adjust the volume of sound effects.",
NULL, {.routine = slider_routine}, 0, Slider::kSfxVolume},
{IT_STRING | IT_ARROWS | IT_CV_SLIDER, "Music Volume", "Adjust the volume of music playback.",
NULL, {.routine = slider_routine}, 0, Slider::kMusicVolume},
{IT_SPACE | IT_NOTHING, NULL, NULL,
NULL, {NULL}, 0, 0},
{IT_STRING | IT_CVAR, "Chat Notifications", "Set when to play notification sounds when chat messages are received.",
NULL, {.cvar = &cv_chatnotifications}, 0, 0},
{IT_STRING | IT_CVAR, "Character Voices", "Set how often to play character voices in game.",
NULL, {.cvar = &cv_kartvoices}, 0, 0},
{IT_SPACE | IT_NOTHING, NULL, NULL,
NULL, {NULL}, 0, 0},
{IT_STRING | IT_CVAR, "Reverse L/R Channels", "Reverse left & right channels for Stereo playback.",
NULL, {.cvar = &stereoreverse}, 0, 0},
{IT_STRING | IT_CVAR, "Hear Tabbed-out", "Keep playing game audio when the window is out of focus (FOCUS LOST).",
NULL, {.cvar = &cv_bgaudio}, 0, 0},
{IT_SPACE | IT_NOTHING, NULL, NULL,
NULL, {NULL}, 0, 0},
{IT_STRING | IT_CALL, "\x85" "Restart Audio", "Reboot the game's audio system.",
NULL, {.routine = restartaudio_routine}, 0, 0},
};
menu_t OPTIONS_SoundDef = {
sizeof (OPTIONS_Sound) / sizeof (menuitem_t),
&OPTIONS_MainDef,
0,
OPTIONS_Sound,
48, 80,
SKINCOLOR_THUNDER, 0,
MBF_DRAWBGWHILEPLAYING,
NULL,
2, 5,
draw_routine,
M_DrawOptionsCogs,
tick_routine,
NULL,
NULL,
input_routine,
};

View file

@ -129,6 +129,7 @@ void Music_Init(void)
tune.song = "_title";
tune.priority = 100;
tune.resist = true;
tune.credit = true;
}
{
@ -183,6 +184,11 @@ void Music_Tick(void)
g_tunes.tick();
}
void Music_Flip(void)
{
g_tunes.flip();
}
void Music_Play(const char* id)
{
Tune* tune = g_tunes.find(id);

View file

@ -144,6 +144,11 @@ void Music_Init(void);
// Call this every tic to update the music.
void Music_Tick(void);
// Flips the internal state so music is reloaded next tick.
// This is required when disabling music during runtime so
// the music plays again when re-enabled.
void Music_Flip(void);
#ifdef __cplusplus
} // extern "C"

View file

@ -53,6 +53,8 @@ public:
return res.first->second;
}
void flip() { current_song_ = {}; }
void tick();
void pause_unpause() const;

View file

@ -197,11 +197,11 @@ struct Box : AnyBox
bool damage_valid(const Mobj* inflictor) const { return !fuse && Mobj::valid(inflictor); }
void damage(Mobj* inflictor)
bool damage(Mobj* inflictor)
{
if (!damage_valid(inflictor))
{
return;
return false;
}
inflictor->hitlag(3);
@ -230,6 +230,8 @@ struct Box : AnyBox
debris(inflictor);
update_nearby();
return true;
}
private:
@ -321,19 +323,19 @@ struct Crate : Box<SA2CrateConfig>
}
}
void damage(Toucher* inflictor)
bool damage(Toucher* inflictor)
{
if (!Box::damage_valid(inflictor))
{
return;
return false;
}
if (metal() && !inflictor->boosting())
{
return;
return false;
}
Box::damage(inflictor);
return Box::damage(inflictor);
}
};
@ -385,9 +387,11 @@ void Obj_TryCrateTouch(mobj_t* special, mobj_t* toucher)
static_cast<AnyBox*>(special)->visit([&](auto box) { box->touch(static_cast<Toucher*>(toucher)); });
}
void Obj_TryCrateDamage(mobj_t* target, mobj_t* inflictor)
boolean Obj_TryCrateDamage(mobj_t* target, mobj_t* inflictor)
{
static_cast<AnyBox*>(target)->visit([&](auto box) { box->damage(static_cast<Toucher*>(inflictor)); });
bool c = false;
static_cast<AnyBox*>(target)->visit([&](auto box) { c = box->damage(static_cast<Toucher*>(inflictor)); });
return c;
}
boolean Obj_SA2CrateIsMetal(mobj_t* mobj)

View file

@ -681,7 +681,7 @@ Obj_GardenTopArrowThink (mobj_t *arrow)
}
boolean
Obj_GardenTopPlayerIsGrinding (player_t *player)
Obj_GardenTopPlayerIsGrinding (const player_t *player)
{
mobj_t *top = K_GetGardenTop(player);

View file

@ -638,7 +638,7 @@ static void SpawnRingShooter(player_t *player)
rs_base_playerface(base) = (player - players);
}
static boolean AllowRingShooter(player_t *player)
static boolean AllowRingShooter(const player_t *player)
{
const fixed_t minSpeed = 6 * player->mo->scale;
@ -667,9 +667,9 @@ static boolean AllowRingShooter(player_t *player)
return false;
}
boolean Obj_PlayerRingShooterFreeze(player_t *const player)
boolean Obj_PlayerRingShooterFreeze(const player_t *player)
{
mobj_t *const base = player->ringShooter;
const mobj_t *base = player->ringShooter;
if (AllowRingShooter(player) == true
&& (player->cmd.buttons & BT_RESPAWN) == BT_RESPAWN

View file

@ -44,7 +44,21 @@ void Obj_SneakerPanelSetup(mobj_t *mobj, mapthing_t *mthing)
mobj->eflags |= MFE_VERTICALFLIP;
mobj->flags2 |= MF2_OBJECTFLIP;
}
P_TryMove(mobj, mobj->x, mobj->y, true, NULL); // sets standingslope
if (P_CheckPosition(mobj, mobj->x, mobj->y, NULL))
{
if (P_IsObjectFlipped(mobj))
{
if (tm.ceilingz <= mobj->z + mobj->height)
mobj->standingslope = tm.ceilingslope;
}
else
{
if (mobj->z <= tm.floorz)
mobj->standingslope = tm.floorslope;
}
}
Obj_SneakerPanelSpriteScale(mobj);
}

View file

@ -813,9 +813,13 @@ static UINT8 GetUFODamage(mobj_t *inflictor, UINT8 damageType)
break;
}
case MT_SPB:
case MT_SPBEXPLOSION:
{
if (inflictor->type != MT_SPBEXPLOSION || inflictor->threshold == KITEM_SPB)
{
targetdamaging |= UFOD_SPB;
}
// SPB deals triple damage.
targetdamaging |= UFOD_SPB;
ret = 30;
break;
}
@ -834,6 +838,14 @@ static UINT8 GetUFODamage(mobj_t *inflictor, UINT8 damageType)
ret = 10;
break;
}
case MT_GARDENTOP:
{
// Garden Top is not classified as a "field
// item" because the player can ride it. So
// an explicit case is necessary.
ret = 10;
break;
}
case MT_PLAYER:
{
// Players deal damage relative to how many sneakers they used.
@ -849,6 +861,11 @@ static UINT8 GetUFODamage(mobj_t *inflictor, UINT8 damageType)
}
default:
{
// General hazards cannot damage the UFO
if (P_IsKartFieldItem(inflictor->type) == false)
{
return 0;
}
break;
}
}

View file

@ -2883,8 +2883,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
case MT_SA2_CRATE:
case MT_ICECAPBLOCK:
Obj_TryCrateDamage(target, inflictor);
return true;
return Obj_TryCrateDamage(target, inflictor);
default:
break;

View file

@ -154,7 +154,7 @@ void P_DemoCameraMovement(camera_t *cam, UINT8 num);
boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcalled);
void P_ToggleDemoCamera(UINT8 viewnum);
boolean P_PlayerInPain(player_t *player);
boolean P_PlayerInPain(const player_t *player);
void P_ResetPlayer(player_t *player);
boolean P_PlayerCanDamage(player_t *player, mobj_t *thing);
@ -166,12 +166,12 @@ void P_SetPlayerAngle(player_t *player, angle_t angle);
void P_ForceLocalAngle(player_t *player, angle_t angle);
boolean P_PlayerFullbright(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_IsObjectInGoop(const mobj_t *mo);
boolean P_IsObjectOnGround(const mobj_t *mo);
boolean P_IsObjectOnGroundIn(const mobj_t *mo, const sector_t *sec);
boolean P_IsObjectOnRealGround(const mobj_t *mo, const sector_t *sec); // SRB2Kart
#define P_IsObjectFlipped(o) (((o)->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP)
boolean P_InQuicksand(mobj_t *mo);
boolean P_InQuicksand(const mobj_t *mo);
boolean P_PlayerHitFloor(player_t *player, boolean fromAir, angle_t oldPitch, angle_t oldRoll);
void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative);
@ -276,8 +276,8 @@ void P_PushableThinker(mobj_t *mobj);
void P_SceneryThinker(mobj_t *mobj);
fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect);
fixed_t P_MobjFloorZ(const mobj_t *mobj, const sector_t *sector, const sector_t *boundsec, fixed_t x, fixed_t y, const line_t *line, boolean lowest, boolean perfect);
fixed_t P_MobjCeilingZ(const mobj_t *mobj, const sector_t *sector, const sector_t *boundsec, fixed_t x, fixed_t y, const line_t *line, boolean lowest, boolean perfect);
#define P_GetFloorZ(mobj, sector, x, y, line) P_MobjFloorZ(mobj, sector, NULL, x, y, line, false, false)
#define P_GetCeilingZ(mobj, sector, x, y, line) P_MobjCeilingZ(mobj, sector, NULL, x, y, line, true, false)
#define P_GetFOFTopZ(mobj, sector, fof, x, y, line) P_MobjCeilingZ(mobj, sectors + fof->secnum, sector, x, y, line, false, false)

View file

@ -670,8 +670,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
{
UINT32 damagetype = (thing->info->mass & 0xFF);
if (P_DamageMobj(tm.thing, thing, thing, 1, damagetype) && (damagetype = (thing->info->mass>>8)))
S_StartSound(thing, damagetype);
P_DamageMobj(tm.thing, thing, thing, 1, damagetype);
if (P_MobjWasRemoved(tm.thing) || P_MobjWasRemoved(thing))
return BMIT_CONTINUE;
@ -690,8 +689,7 @@ static BlockItReturn_t PIT_CheckThing(mobj_t *thing)
{
UINT32 damagetype = (tm.thing->info->mass & 0xFF);
if (P_DamageMobj(thing, tm.thing, tm.thing, 1, damagetype) && (damagetype = (tm.thing->info->mass>>8)))
S_StartSound(tm.thing, damagetype);
P_DamageMobj(thing, tm.thing, tm.thing, 1, damagetype);
if (P_MobjWasRemoved(tm.thing) || P_MobjWasRemoved(thing))
return BMIT_CONTINUE;

View file

@ -633,7 +633,7 @@ boolean P_InsideANonSolidFFloor(mobj_t *mobj, ffloor_t *rover)
// Supply boundsec ONLY when checking for specials! It should be the "in-level" sector, and sector the control sector (if separate).
// If set, then this function will iterate through boundsec's linedefs to find the highest contact point on the slope. Non-special-checking
// usage will handle that later.
static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line, pslope_t *slope, boolean actuallylowest)
static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, const line_t *line, const pslope_t *slope, boolean actuallylowest)
{
// Alright, so we're sitting on a line that contains our slope sector, and need to figure out the highest point we're touching...
// The solution is simple! Get the line's vertices, and pull each one in along its line until it touches the object's bounding box
@ -731,7 +731,7 @@ static fixed_t HighestOnLine(fixed_t radius, fixed_t x, fixed_t y, line_t *line,
);
}
fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect)
fixed_t P_MobjFloorZ(const mobj_t *mobj, const sector_t *sector, const sector_t *boundsec, fixed_t x, fixed_t y, const line_t *line, boolean lowest, boolean perfect)
{
I_Assert(mobj != NULL);
I_Assert(sector != NULL);
@ -808,7 +808,7 @@ fixed_t P_MobjFloorZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t
return sector->floorheight;
}
fixed_t P_MobjCeilingZ(mobj_t *mobj, sector_t *sector, sector_t *boundsec, fixed_t x, fixed_t y, line_t *line, boolean lowest, boolean perfect)
fixed_t P_MobjCeilingZ(const mobj_t *mobj, const sector_t *sector, const sector_t *boundsec, fixed_t x, fixed_t y, const line_t *line, boolean lowest, boolean perfect)
{
I_Assert(mobj != NULL);
I_Assert(sector != NULL);

View file

@ -5710,8 +5710,8 @@ static void P_CheckMobj3DFloorAction(mobj_t *mo, sector_t *sec, boolean continuo
continue;
}
top = P_GetSpecialTopZ(mo, roversec, roversec);
bottom = P_GetSpecialBottomZ(mo, roversec, roversec);
top = P_GetSpecialTopZ(mo, roversec, sec);
bottom = P_GetSpecialBottomZ(mo, roversec, sec);
mid = bottom + ((top - bottom) / 2);
if (mo->z > top || mo->z + mo->height < bottom)

View file

@ -459,7 +459,7 @@ UINT8 P_FindHighestLap(void)
// Is player in pain??
// Checks for painstate and flashing, if both found return true
//
boolean P_PlayerInPain(player_t *player)
boolean P_PlayerInPain(const player_t *player)
{
if (player->spinouttimer || (player->tumbleBounces > 0) || (player->pflags & PF_FAULT) || player->icecube.frozen)
return true;
@ -831,7 +831,7 @@ void P_InvincGrowMusic(void)
// Returns true if the object is inside goop water.
// (Spectators and objects otherwise without gravity cannot have goop gravity!)
//
boolean P_IsObjectInGoop(mobj_t *mo)
boolean P_IsObjectInGoop(const mobj_t *mo)
{
if (mo->player && mo->player->spectator)
return false;
@ -849,7 +849,7 @@ boolean P_IsObjectInGoop(mobj_t *mo)
// on the ground. Takes reverse
// gravity and FOFs into account.
//
boolean P_IsObjectOnGround(mobj_t *mo)
boolean P_IsObjectOnGround(const mobj_t *mo)
{
if (P_IsObjectInGoop(mo))
{
@ -894,7 +894,7 @@ boolean P_IsObjectOnGround(mobj_t *mo)
// on the ground in a specific sector. Takes reverse
// gravity and FOFs into account.
//
boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec)
boolean P_IsObjectOnGroundIn(const mobj_t *mo, const sector_t *sec)
{
ffloor_t *rover;
@ -981,7 +981,7 @@ boolean P_IsObjectOnGroundIn(mobj_t *mo, sector_t *sec)
// 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)
boolean P_IsObjectOnRealGround(const mobj_t *mo, const sector_t *sec)
{
// Is the object in reverse gravity?
if (mo->eflags & MFE_VERTICALFLIP)
@ -1471,7 +1471,7 @@ boolean P_PlayerHitFloor(player_t *player, boolean fromAir, angle_t oldPitch, an
return clipmomz;
}
boolean P_InQuicksand(mobj_t *mo) // Returns true if you are in quicksand
boolean P_InQuicksand(const mobj_t *mo) // Returns true if you are in quicksand
{
sector_t *sector = mo->subsector->sector;
fixed_t topheight, bottomheight;

View file

@ -37,6 +37,8 @@
#include "v_video.h" // V_ThinStringWidth
#include "music.h"
extern consvar_t cv_mastervolume;
static boolean S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *vol, INT32 *sep, INT32 *pitch, sfxinfo_t *sfxinfo);
static void Command_Tunes_f(void);
@ -246,7 +248,7 @@ boolean S_SoundDisabled(void)
{
return (
sound_disabled ||
( window_notinfocus && ! cv_playsoundifunfocused.value )
( window_notinfocus && ! (cv_bgaudio.value & 2) )
);
}
@ -2166,7 +2168,7 @@ boolean S_MusicDisabled(void)
boolean S_MusicNotInFocus(void)
{
return (
( window_notinfocus && ! cv_playmusicifunfocused.value )
( window_notinfocus && ! (cv_bgaudio.value & 1) )
);
}
@ -2515,27 +2517,67 @@ void GameDigiMusic_OnChange(void)
{
digital_disabled = true;
I_UnloadSong();
Music_Flip();
}
}
void PlayMusicIfUnfocused_OnChange(void);
void PlayMusicIfUnfocused_OnChange(void)
void MasterVolume_OnChange(void);
void MasterVolume_OnChange(void)
{
INT32 adj = cv_mastervolume.value - max(cv_digmusicvolume.value, cv_soundvolume.value);
if (adj < 0)
{
INT32 under = min(cv_digmusicvolume.value, cv_soundvolume.value) + adj;
if (under < 0)
{
// Ensure balance between music/sound volume does
// not change at lower bound. (This is already
// guaranteed at upper bound.)
adj -= under;
CV_StealthSetValue(&cv_mastervolume, cv_mastervolume.value - under);
}
}
CV_SetValue(&cv_digmusicvolume, cv_digmusicvolume.value + adj);
CV_SetValue(&cv_soundvolume, cv_soundvolume.value + adj);
}
void DigMusicVolume_OnChange(void);
void DigMusicVolume_OnChange(void)
{
if (!cv_gamedigimusic.value)
{
CV_SetValue(&cv_gamedigimusic, 1);
}
CV_StealthSetValue(&cv_mastervolume, max(cv_digmusicvolume.value, cv_soundvolume.value));
}
void SoundVolume_OnChange(void);
void SoundVolume_OnChange(void)
{
if (!cv_gamesounds.value)
{
CV_SetValue(&cv_gamesounds, 1);
}
CV_StealthSetValue(&cv_mastervolume, max(cv_digmusicvolume.value, cv_soundvolume.value));
}
void BGAudio_OnChange(void);
void BGAudio_OnChange(void)
{
if (window_notinfocus)
{
if (cv_playmusicifunfocused.value)
if (cv_bgaudio.value & 1)
I_SetMusicVolume(0);
else
S_SetMusicVolume();
}
}
void PlaySoundIfUnfocused_OnChange(void);
void PlaySoundIfUnfocused_OnChange(void)
{
if (!cv_gamesounds.value)
return;
if (window_notinfocus && !cv_playsoundifunfocused.value)
if (window_notinfocus && !(cv_bgaudio.value & 2))
S_StopSounds();
}

View file

@ -41,8 +41,7 @@ extern consvar_t cv_numChannels;
extern consvar_t cv_gamedigimusic;
extern consvar_t cv_gamesounds;
extern consvar_t cv_playmusicifunfocused;
extern consvar_t cv_playsoundifunfocused;
extern consvar_t cv_bgaudio;
typedef enum
{

View file

@ -538,9 +538,9 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
{
// Tell game we lost focus, pause music
window_notinfocus = true;
if (!cv_playmusicifunfocused.value)
if (!(cv_bgaudio.value & 1))
I_SetMusicVolume(0);
if (!cv_playsoundifunfocused.value)
if (!(cv_bgaudio.value & 2))
S_StopSounds();
if (!disable_mouse)

View file

@ -56,7 +56,7 @@ void Chain::fill(UINT8 color) const
{
const auto _ = Clipper(*this);
V_DrawFill(x_, y_, width_, height_, color);
V_DrawFill(x_, y_, width_, height_, color|(flags_ & ~0xFF));
}
void Chain::string(const char* str, INT32 flags, Font font) const