This is a doozy...

HUD:
* Miniaturised Spheres and Emeralds HUD for 3P/4P.
* Repair 3P minimap.
* Move accessibility icons in 3P/4P to next to the lap/bumper sticker (currently only kickstartaccel exists)
* Change language on menu retry to be more generalised.
* Adjust HUD code structuring a bit.

MECHANICAL:
* Now correctly set number of bumpers in Break the Capsules to 1 (from 3).
* The above required reworking K_SpawnBattleCapsules into K_BattleInit, which is a good staging ground to handle more battle-specific setup in future.
* Do not spawn Emeralds or Sphereboxes in Break the Capsules.
* If everyone is WANTED... nobody is.
* Try to handle exceptions to timelimits a little more thoroughly (still not perfect).
* Disable pointlimits in bosses.
This commit is contained in:
toaster 2022-03-05 22:31:43 +00:00
parent 9ac9abbb6e
commit bf43784d22
9 changed files with 350 additions and 180 deletions

View file

@ -54,6 +54,7 @@
// SRB2Kart
#include "s_sound.h" // song credits
#include "k_kart.h"
#include "k_boss.h"
#include "k_color.h"
#include "k_hud.h"
#include "r_fps.h"
@ -2365,13 +2366,13 @@ static void HU_DrawRankings(void)
else
V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, gametype_cons_t[gametype].strvalue);
if (gametyperules & (GTR_TIMELIMIT|GTR_POINTLIMIT))
if ((gametyperules & (GTR_TIMELIMIT|GTR_POINTLIMIT)) && !bossinfo.boss)
{
if ((gametyperules & GTR_TIMELIMIT) && cv_timelimit.value && timelimitintics > 0)
{
UINT32 timeval = (timelimitintics + starttime + 1 - leveltime);
if (timeval > timelimitintics+1)
timeval = timelimitintics;
timeval = timelimitintics+1;
timeval /= TICRATE;
if (leveltime <= (timelimitintics + starttime))

View file

@ -42,7 +42,17 @@ INT32 K_StartingBumperCount(void)
boolean K_IsPlayerWanted(player_t *player)
{
return (player->position == 1);
UINT8 i = 0, nump = 0, numfirst = 0;
for (; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
continue;
nump++;
if (players[i].position > 1)
continue;
numfirst++;
}
return ((numfirst < nump) && !player->spectator && (player->position == 1));
}
void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount)
@ -307,6 +317,8 @@ void K_RunPaperItemSpawners(void)
const boolean overtime = (battleovertime.enabled >= 10*TICRATE);
tic_t interval = 8*TICRATE;
const boolean canmakeemeralds = true; //(!(battlecapsules || bossinfo.boss));
UINT32 emeraldsSpawned = 0;
UINT32 firstUnspawnedEmerald = 0;
@ -316,6 +328,12 @@ void K_RunPaperItemSpawners(void)
UINT8 pcount = 0;
INT16 i;
if (battlecapsules || bossinfo.boss)
{
// Gametype uses paper items, but this specific expression doesn't
return;
}
if (leveltime < starttime)
{
// Round hasn't started yet!
@ -369,14 +387,17 @@ void K_RunPaperItemSpawners(void)
}
}
for (i = 0; i < 7; i++)
if (canmakeemeralds)
{
UINT32 emeraldFlag = (1 << i);
if (!(emeraldsSpawned & emeraldFlag))
for (i = 0; i < 7; i++)
{
firstUnspawnedEmerald = emeraldFlag;
break;
UINT32 emeraldFlag = (1 << i);
if (!(emeraldsSpawned & emeraldFlag))
{
firstUnspawnedEmerald = emeraldFlag;
break;
}
}
}
@ -396,11 +417,14 @@ void K_RunPaperItemSpawners(void)
0, 0
);
K_SpawnSphereBox(
battleovertime.x, battleovertime.y, battleovertime.z + (128 * mapobjectscale * flip),
FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip,
10
);
if (gametyperules & GTR_SPHERES)
{
K_SpawnSphereBox(
battleovertime.x, battleovertime.y, battleovertime.z + (128 * mapobjectscale * flip),
FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip,
10
);
}
}
}
else
@ -442,15 +466,18 @@ void K_RunPaperItemSpawners(void)
return;
}
for (i = 0; i < 7; i++)
if (canmakeemeralds)
{
UINT32 emeraldFlag = (1 << i);
if (!(emeraldsSpawned & emeraldFlag))
for (i = 0; i < 7; i++)
{
firstUnspawnedEmerald = emeraldFlag;
starti = -1;
break;
UINT32 emeraldFlag = (1 << i);
if (!(emeraldsSpawned & emeraldFlag))
{
firstUnspawnedEmerald = emeraldFlag;
starti = -1;
break;
}
}
}
@ -485,12 +512,15 @@ void K_RunPaperItemSpawners(void)
}
else
{
drop = K_SpawnSphereBox(
spotList[r]->x, spotList[r]->y, spotList[r]->z + (128 * mapobjectscale * flip),
FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip,
10
);
K_FlipFromObject(drop, spotList[r]);
if (gametyperules & GTR_SPHERES)
{
drop = K_SpawnSphereBox(
spotList[r]->x, spotList[r]->y, spotList[r]->z + (128 * mapobjectscale * flip),
FixedAngle(P_RandomRange(0, 359) * FRACUNIT), flip,
10
);
K_FlipFromObject(drop, spotList[r]);
}
drop = K_CreatePaperItem(
spotList[r]->x, spotList[r]->y, spotList[r]->z + (128 * mapobjectscale * flip),
@ -703,44 +733,79 @@ void K_SetupMovingCapsule(mapthing_t *mt, mobj_t *mobj)
}
}
void K_SpawnBattleCapsules(void)
void K_SpawnPlayerBattleBumpers(player_t *p)
{
if (!p->mo || p->bumpers <= 0)
return;
{
INT32 i;
angle_t diff = FixedAngle(360*FRACUNIT/p->bumpers);
angle_t newangle = p->mo->angle;
mobj_t *bump;
for (i = 0; i < p->bumpers; i++)
{
bump = P_SpawnMobjFromMobj(p->mo,
P_ReturnThrustX(p->mo, newangle + ANGLE_180, 64*FRACUNIT),
P_ReturnThrustY(p->mo, newangle + ANGLE_180, 64*FRACUNIT),
0, MT_BATTLEBUMPER);
bump->threshold = i;
P_SetTarget(&bump->target, p->mo);
bump->angle = newangle;
bump->color = p->mo->color;
if (p->mo->renderflags & RF_DONTDRAW)
bump->renderflags |= RF_DONTDRAW;
else
bump->renderflags &= ~RF_DONTDRAW;
newangle += diff;
}
}
}
void K_BattleInit(void)
{
mapthing_t *mt;
size_t i;
if (battlecapsules)
return;
if (bossinfo.boss)
return;
if (!(gametyperules & GTR_CAPSULES))
return;
if (modeattacking != ATTACKING_CAPSULES)
if ((gametyperules & GTR_CAPSULES) && !battlecapsules && !bossinfo.boss)
{
UINT8 n = 0;
mapthing_t *mt;
if (modeattacking != ATTACKING_CAPSULES)
{
UINT8 n = 0;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
continue;
n++;
}
if (n > 1)
goto aftercapsules;
}
mt = mapthings;
for (i = 0; i < nummapthings; i++, mt++)
{
if (mt->type == mobjinfo[MT_BATTLECAPSULE].doomednum)
P_SpawnMapThing(mt);
}
battlecapsules = true;
}
aftercapsules:
if (gametyperules & GTR_BUMPERS)
{
INT32 maxbumpers = K_StartingBumperCount();
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && !players[i].spectator)
n++;
if (players[i].exiting)
return;
if (n > 1)
break;
if (!playeringame[i] || players[i].spectator)
continue;
players[i].bumpers = maxbumpers;
K_SpawnPlayerBattleBumpers(players+i);
}
if (n > 1)
return;
}
mt = mapthings;
for (i = 0; i < nummapthings; i++, mt++)
{
if (mt->type == mobjinfo[MT_BATTLECAPSULE].doomednum)
P_SpawnMapThing(mt);
}
battlecapsules = true;
}

View file

@ -28,6 +28,7 @@ UINT8 K_NumEmeralds(player_t *player);
void K_RunPaperItemSpawners(void);
void K_RunBattleOvertime(void);
void K_SetupMovingCapsule(mapthing_t *mt, mobj_t *mobj);
void K_SpawnBattleCapsules(void);
void K_SpawnPlayerBattleBumpers(player_t *p);
void K_BattleInit(void);
#endif

View file

@ -55,6 +55,7 @@ static patch_t *kp_capsulesticker;
static patch_t *kp_capsulestickerwide;
static patch_t *kp_karmasticker;
static patch_t *kp_spheresticker;
static patch_t *kp_splitspheresticker;
static patch_t *kp_splitkarmabomb;
static patch_t *kp_timeoutsticker;
@ -192,6 +193,7 @@ void K_LoadKartHUDGraphics(void)
kp_capsulestickerwide = W_CachePatchName("K_STCAPW", PU_HUDGFX);
kp_karmasticker = W_CachePatchName("K_STKARM", PU_HUDGFX);
kp_spheresticker = W_CachePatchName("K_STBSMT", PU_HUDGFX);
kp_splitspheresticker = W_CachePatchName("K_SPBSMT", PU_HUDGFX);
kp_splitkarmabomb = W_CachePatchName("K_SPTKRM", PU_HUDGFX);
kp_timeoutsticker = W_CachePatchName("K_STTOUT", PU_HUDGFX);
@ -1456,17 +1458,34 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UI
// TIME_Y = 6; // 6
tic_t worktime;
boolean dontdraw = false;
INT32 splitflags = 0;
if (!mode)
{
splitflags = V_HUDTRANS|V_SLIDEIN|V_SNAPTOTOP|V_SNAPTORIGHT|V_SPLITSCREEN;
if (cv_timelimit.value && timelimitintics > 0 && !bossinfo.boss) // TODO
#ifndef TESTOVERTIMEINFREEPLAY
if (battlecapsules) // capsules override any time limit settings
;
else
#endif
if (bossinfo.boss == true)
;
else if (timelimitintics > 0 && (gametyperules & GTR_TIMELIMIT)) // TODO
{
if (drawtime >= timelimitintics)
{
if (((drawtime-timelimitintics)/TICRATE) & 1)
{
dontdraw = true;
}
drawtime = 0;
}
else
{
drawtime = timelimitintics - drawtime;
}
}
}
@ -1478,6 +1497,8 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UI
if (mode && !drawtime)
V_DrawKartString(TX, TY+3, splitflags, va("--'--\"--"));
else if (dontdraw) // overtime flash
;
else if (worktime < 100) // 99:99:99 only
{
// zero minute
@ -1581,13 +1602,13 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UI
goto bademblem;
}
V_DrawRightAlignedString(workx, worky, splitflags, targettext);
V_DrawRightAlignedString(workx, worky, splitflags|V_6WIDTHSPACE, targettext);
workx -= 67;
V_DrawSmallScaledPatch(workx + 4, worky, splitflags, W_CachePatchName("NEEDIT", PU_CACHE));
break;
bademblem:
bademblem:
emblem = M_GetLevelEmblems(-1);
}
@ -2020,22 +2041,49 @@ static void K_drawBossHealthBar(void)
static void K_drawKartEmeralds(void)
{
static const INT32 emeraldOffsets[7][2] = {
{34, 0},
{25, 8},
{43, 8},
{16, 0},
{52, 0},
{7, 8},
{61, 8}
static const INT32 emeraldOffsets[7][3] = {
{34, 0, 15},
{25, 8, 11},
{43, 8, 19},
{16, 0, 7},
{52, 0, 23},
{ 7, 8, 3},
{61, 8, 27}
};
const INT32 startx = BASEVIDWIDTH - 77 - 8;
const INT32 starty = BASEVIDHEIGHT - 29 - 8;
INT32 splitflags = V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_SPLITSCREEN;
INT32 startx = BASEVIDWIDTH - 77;
INT32 starty = BASEVIDHEIGHT - 29;
INT32 i = 0, xindex = 0;
INT32 i;
{
if (r_splitscreen)
{
starty = (starty/2) - 8;
}
starty -= 8;
V_DrawScaledPatch(startx, starty, V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT, kp_rankemeraldback);
if (r_splitscreen < 2)
{
startx -= 8;
V_DrawScaledPatch(startx, starty, V_HUDTRANS|splitflags, kp_rankemeraldback);
}
else
{
xindex = 2;
starty -= 15;
if (stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]]) // If we are P1 or P3...
{
startx = LAPS_X;
splitflags = V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_SPLITSCREEN;
}
else // else, that means we're P2 or P4.
{
startx = LAPS2_X + 1;
splitflags = V_SNAPTORIGHT|V_SNAPTOBOTTOM|V_SPLITSCREEN;
}
}
}
for (i = 0; i < 7; i++)
{
@ -2054,16 +2102,16 @@ static void K_drawKartEmeralds(void)
colormap = R_GetTranslationColormap(TC_DEFAULT, emeraldColor, GTC_CACHE);
V_DrawMappedPatch(
startx + emeraldOffsets[i][0], starty + emeraldOffsets[i][1],
V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT,
startx + emeraldOffsets[i][xindex], starty + emeraldOffsets[i][1],
V_HUDTRANS|splitflags,
kp_rankemerald, colormap
);
if (whiteFlash == true)
{
V_DrawScaledPatch(
startx + emeraldOffsets[i][0], starty + emeraldOffsets[i][1],
V_HUDTRANSHALF|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTORIGHT,
startx + emeraldOffsets[i][xindex], starty + emeraldOffsets[i][1],
V_HUDTRANSHALF|splitflags,
kp_rankemeraldflash
);
}
@ -2328,7 +2376,8 @@ static void K_drawKartLapsAndRings(void)
{
UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, stplyr->skincolor, GTC_CACHE);
V_DrawMappedPatch(fr+21, fy-13, V_HUDTRANS|V_SLIDEIN|splitflags, faceprefix[stplyr->skin][FACE_MINIMAP], colormap);
V_DrawScaledPatch(fr+34, fy-10, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[(stplyr->lives % 10)]); // make sure this doesn't overflow
if (stplyr->lives >= 0)
V_DrawScaledPatch(fr+34, fy-10, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[PINGNUM_FONT].font[(stplyr->lives % 10)]); // make sure this doesn't overflow OR underflow
}
}
else
@ -2366,7 +2415,8 @@ static void K_drawKartLapsAndRings(void)
{
UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, stplyr->skincolor, GTC_CACHE);
V_DrawMappedPatch(LAPS_X+46, LAPS_Y-16, V_HUDTRANS|V_SLIDEIN|splitflags, faceprefix[stplyr->skin][FACE_RANK], colormap);
V_DrawScaledPatch(LAPS_X+63, LAPS_Y-11, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(stplyr->lives % 10)]); // make sure this doesn't overflow
if (stplyr->lives >= 0)
V_DrawScaledPatch(LAPS_X+63, LAPS_Y-11, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[(stplyr->lives % 10)]); // make sure this doesn't overflow OR underflow
}
}
}
@ -2388,7 +2438,8 @@ static void K_drawKartAccessibilityIcons(INT32 fx)
}
else
{
fy += 4;
fx = LAPS_X+43;
fy = LAPS_Y;
if (!(stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]])) // If we are not P1 or P3...
{
splitflags ^= (V_SNAPTOLEFT|V_SNAPTORIGHT);
@ -2492,25 +2543,81 @@ static void K_drawBlueSphereMeter(void)
UINT8 numBars = min((sphere / 10), maxBars);
UINT8 colorIndex = (sphere * sizeof(segColors)) / (40 + 1);
INT32 x = LAPS_X + 25;
INT32 fx, fy;
UINT8 i;
INT32 splitflags = V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN;
INT32 flipflag = 0;
INT32 xstep = 15;
V_DrawScaledPatch(LAPS_X, LAPS_Y - 22, V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN, kp_spheresticker);
// pain and suffering defined below
if (r_splitscreen < 2) // don't change shit for THIS splitscreen.
{
fx = LAPS_X;
fy = LAPS_Y-22;
V_DrawScaledPatch(fx, fy, splitflags|flipflag, kp_spheresticker);
}
else
{
xstep = 8;
if (stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]]) // If we are P1 or P3...
{
fx = LAPS_X-2;
fy = LAPS_Y;
}
else // else, that means we're P2 or P4.
{
fx = LAPS2_X+(SHORT(kp_splitspheresticker->width) - 10);
fy = LAPS2_Y;
splitflags ^= V_SNAPTOLEFT|V_SNAPTORIGHT;
flipflag = V_FLIP; // make the string right aligned and other shit
xstep = -xstep;
}
fy -= 16;
V_DrawScaledPatch(fx, fy, splitflags|flipflag, kp_splitspheresticker);
}
if (r_splitscreen < 2)
{
fx += 25;
}
else
{
fx += (flipflag) ? -18 : 13;
}
for (i = 0; i <= numBars; i++)
{
UINT8 segLen = 10;
UINT8 segLen = (r_splitscreen < 2) ? 10 : 5;
if (i == numBars)
{
segLen = (sphere % 10);
if (r_splitscreen < 2)
;
else
{
segLen = (segLen+1)/2; // offset so nonzero spheres shows up IMMEDIATELY
if (!segLen)
break;
if (flipflag)
fx += (5-segLen);
}
}
V_DrawFill(x, LAPS_Y - 16, segLen, 3, segColors[max(colorIndex-1, 0)] | V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN);
V_DrawFill(x, LAPS_Y - 15, segLen, 1, segColors[max(colorIndex-2, 0)] | V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN);
V_DrawFill(x, LAPS_Y - 13, segLen, 3, segColors[colorIndex] | V_HUDTRANS|V_SLIDEIN|V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_SPLITSCREEN);
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 + 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 + 7, segLen, 2, segColors[colorIndex] | splitflags);
}
x += 15;
fx += xstep;
}
}
@ -2536,13 +2643,13 @@ static void K_drawKartBumpersOrKarma(void)
{
fx = LAPS_X;
fy = LAPS_Y;
splitflags = V_SNAPTOLEFT|((stplyr == &players[displayplayers[2]]) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P3 to the bottom.
splitflags = V_SNAPTOLEFT|V_SNAPTOBOTTOM|V_SPLITSCREEN;
}
else // else, that means we're P2 or P4.
{
fx = LAPS2_X;
fy = LAPS2_Y;
splitflags = V_SNAPTORIGHT|((stplyr == &players[displayplayers[3]]) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P4 to the bottom
splitflags = V_SNAPTORIGHT|V_SNAPTOBOTTOM|V_SPLITSCREEN;
flipflag = V_FLIP; // make the string right aligned and other shit
}
}
@ -3316,7 +3423,8 @@ static void K_drawKartMinimap(void)
patch_t *AutomapPic;
INT32 i = 0;
INT32 x, y;
INT32 minimaptrans, splitflags = (r_splitscreen == 3 ? 0 : (V_SLIDEIN|V_SNAPTORIGHT)); // flags should only be 0 when it's centered (4p split)
INT32 minimaptrans = cv_kartminimap.value;
INT32 splitflags = 0;
UINT8 skin = 0;
UINT8 *colormap = NULL;
SINT8 localplayers[4];
@ -3342,20 +3450,26 @@ static void K_drawKartMinimap(void)
else
return; // no pic, just get outta here
x = MINI_X - (AutomapPic->width/2);
y = MINI_Y - (AutomapPic->height/2);
if (r_splitscreen < 2) // 1/2P right aligned
{
splitflags = (V_SLIDEIN|V_SNAPTORIGHT);
}
else if (r_splitscreen == 3) // 4P centered
{
const tic_t length = TICRATE/2;
if (!lt_exitticker)
return;
minimaptrans = cv_kartminimap.value;
if (lt_exitticker < length)
minimaptrans = (((INT32)lt_exitticker)*minimaptrans)/((INT32)length);
if (!minimaptrans)
return;
}
// 3P lives in the middle of the bottom right player and shouldn't fade in OR slide
if (!minimaptrans)
return;
x = MINI_X - (AutomapPic->width/2);
y = MINI_Y - (AutomapPic->height/2);
minimaptrans = ((10-minimaptrans)<<FF_TRANSSHIFT);
splitflags |= minimaptrans;
@ -3365,7 +3479,6 @@ static void K_drawKartMinimap(void)
else
V_DrawScaledPatch(x, y, splitflags, AutomapPic);
if (r_splitscreen != 2)
{
splitflags &= ~minimaptrans;
splitflags |= V_HUDTRANSHALF;
@ -3515,8 +3628,10 @@ static void K_drawKartMinimap(void)
}
// draw our local players here, opaque.
splitflags &= ~V_HUDTRANSHALF;
splitflags |= V_HUDTRANS;
{
splitflags &= ~V_HUDTRANSHALF;
splitflags |= V_HUDTRANS;
}
// ...but first, any boss targets.
if (bossinfo.boss)
@ -4571,7 +4686,7 @@ static void K_DrawWaypointDebugger(void)
void K_drawKartHUD(void)
{
boolean isfreeplay = false;
boolean islonesome = false;
boolean battlefullscreen = false;
boolean freecam = demo.freecam; //disable some hud elements w/ freecam
UINT8 i;
@ -4645,12 +4760,7 @@ void K_drawKartHUD(void)
if (LUA_HudEnabled(hud_time))
K_drawKartTimestamp(stplyr->realtime, TIME_X, TIME_Y, gamemap, 0);
if (!modeattacking)
{
// The top-four faces on the left
//if (LUA_HudEnabled(hud_minirankings))
isfreeplay = K_drawKartPositionFaces();
}
islonesome = K_drawKartPositionFaces();
}
if (!stplyr->spectator && !demo.freecam) // Bottom of the screen elements, don't need in spectate mode
@ -4669,48 +4779,65 @@ void K_drawKartHUD(void)
V_DrawTinyScaledPatch(x-54, y, snapflags|V_SLIDEIN, W_CachePatchName("TTKBANNR", PU_CACHE));
V_DrawTinyScaledPatch(x-54, y+25, snapflags|V_SLIDEIN, W_CachePatchName("TTKART", PU_CACHE));
}
else if (gametype == GT_RACE) // Race-only elements
else
{
// Draw the lap counter
if (LUA_HudEnabled(hud_gametypeinfo))
K_drawKartLapsAndRings();
if (isfreeplay)
;
else if (!modeattacking)
if (LUA_HudEnabled(hud_position))
{
// Draw the numerical position
if (LUA_HudEnabled(hud_position))
K_DrawKartPositionNum(stplyr->position);
if (bossinfo.boss)
{
K_drawBossHealthBar();
}
else if (gametype == GT_RACE) // Race-only elements (not currently gametyperuleable)
{
if (!islonesome)
{
// Draw the numerical position
K_DrawKartPositionNum(stplyr->position);
}
}
else if (gametype == GT_BATTLE) // Battle-only (ditto)
{
if (!freecam && !battlecapsules)
{
K_drawKartEmeralds();
}
}
}
else //if (!(demo.playback && hu_showscores))
if (LUA_HudEnabled(hud_gametypeinfo))
{
if (gametyperules & GTR_CIRCUIT)
{
K_drawKartLapsAndRings();
}
else if (gametyperules & GTR_BUMPERS)
{
K_drawKartBumpersOrKarma();
}
}
// Draw the speedometer and/or accessibility icons
if (cv_kartspeedometer.value && !r_splitscreen && (LUA_HudEnabled(hud_speedometer)))
{
K_drawKartSpeedometer();
}
else
{
K_drawKartAccessibilityIcons(0);
}
if (gametyperules & GTR_SPHERES)
{
K_drawBlueSphereMeter();
}
if (modeattacking && !bossinfo.boss)
{
// Draw the input UI
if (LUA_HudEnabled(hud_position))
K_drawInput();
}
}
else if (gametype == GT_BATTLE) // Battle-only
{
// Draw the hits left!
if (LUA_HudEnabled(hud_gametypeinfo))
K_drawKartBumpersOrKarma();
}
// Draw the speedometer and/or accessibility icons
if (cv_kartspeedometer.value && !r_splitscreen && (LUA_HudEnabled(hud_speedometer)))
{
K_drawKartSpeedometer();
}
else
{
K_drawKartAccessibilityIcons((r_splitscreen > 1) ? 0 : 8);
}
if (gametyperules & GTR_SPHERES)
{
K_drawBlueSphereMeter();
}
}
// Draw the countdowns after everything else.
@ -4746,18 +4873,6 @@ void K_drawKartHUD(void)
if (stplyr->karthud[khud_trickcool])
K_drawTrickCool();
if (gametype == GT_BATTLE)
{
if (bossinfo.boss)
{
K_drawBossHealthBar();
}
else if (!freecam)
{
K_drawKartEmeralds();
}
}
if (modeattacking || freecam) // everything after here is MP and debug only
return;
@ -4765,7 +4880,7 @@ void K_drawKartHUD(void)
V_DrawScaledPatch(BASEVIDWIDTH/2 - (SHORT(kp_yougotem->width)/2), 32, V_HUDTRANS, kp_yougotem);
// Draw FREE PLAY.
if (isfreeplay && !bossinfo.boss && !stplyr->spectator)
if (islonesome && !modeattacking && !bossinfo.boss && !stplyr->spectator)
{
if (LUA_HudEnabled(hud_freeplay))
K_drawKartFreePlay();

View file

@ -103,7 +103,7 @@ void K_TimerInit(void)
starttime = (introtime + (3*TICRATE)) + ((2*TICRATE) + (numbulbs * bulbtime)); // Start countdown time, + buffer time
// NOW you can try to spawn in the Battle capsules, if there's not enough players for a match
K_SpawnBattleCapsules();
K_BattleInit();
//CONS_Printf("numbulbs set to %d (%d players, %d spectators) on tic %d\n", numbulbs, numPlayers, numspec, leveltime);
}

View file

@ -6369,7 +6369,7 @@ static void M_RetryResponse(INT32 ch)
static void M_Retry(INT32 choice)
{
(void)choice;
M_StartMessage(va("Start this %s over?\n\n(Press 'Y' to confirm)\n", (bossinfo.boss == true) ? "boss" : "race"),M_RetryResponse,MM_YESNO);
M_StartMessage(va("Start this %s over?\n\n(Press 'Y' to confirm)\n", (gametyperules & GTR_CIRCUIT) ? "race" : "battle"),M_RetryResponse,MM_YESNO);
}
static void M_SelectableClearMenus(INT32 choice)

View file

@ -634,10 +634,10 @@ void P_CheckTimeLimit(void)
if (!(gametyperules & GTR_TIMELIMIT))
return;
if (leveltime < (timelimitintics + starttime))
if (bossinfo.boss == true)
return;
if (bossinfo.boss == true)
if (leveltime < (timelimitintics + starttime))
return;
if (gameaction == ga_completed)
@ -736,6 +736,9 @@ void P_CheckPointLimit(void)
if (!(gametyperules & GTR_POINTLIMIT))
return;
if (bossinfo.boss == true)
return;
// pointlimit is nonzero, check if it's been reached by this player
if (G_GametypeHasTeams())
{

View file

@ -10935,29 +10935,14 @@ void P_SpawnPlayer(INT32 playernum)
{
if ((leveltime < starttime) || (pcount <= 1)) // Start of the map?
{
// Reset those bumpers!
p->bumpers = K_StartingBumperCount();
}
if (p->bumpers)
{
angle_t diff = FixedAngle(360*FRACUNIT/p->bumpers);
angle_t newangle = mobj->angle;
fixed_t newx = mobj->x + P_ReturnThrustX(mobj, newangle + ANGLE_180, 64*FRACUNIT);
fixed_t newy = mobj->y + P_ReturnThrustY(mobj, newangle + ANGLE_180, 64*FRACUNIT);
mobj_t *mo;
for (i = 0; i < p->bumpers; i++)
if (leveltime > 2) // Reset those bumpers!
{
mo = P_SpawnMobj(newx, newy, mobj->z, MT_BATTLEBUMPER);
mo->threshold = i;
P_SetTarget(&mo->target, mobj);
mo->angle = (diff * (i-1));
mo->color = mobj->color;
if (mobj->renderflags & RF_DONTDRAW)
mo->renderflags |= RF_DONTDRAW;
else
mo->renderflags &= ~RF_DONTDRAW;
p->bumpers = K_StartingBumperCount();
K_SpawnPlayerBattleBumpers(p);
}
else // temp, will get overwritten in K_BattleInit
{
p->bumpers = 1;
}
}
}

View file

@ -86,7 +86,7 @@
// SRB2Kart
#include "k_kart.h"
#include "k_race.h"
#include "k_battle.h" // K_SpawnBattleCapsules
#include "k_battle.h" // K_BattleInit
#include "k_pwrlv.h"
#include "k_waypoint.h"
#include "k_bot.h"