Merge branch 'master' into resync

This commit is contained in:
TehRealSalt 2018-11-01 20:39:50 -04:00
commit e758e0f8fd
22 changed files with 693 additions and 185 deletions

View file

@ -2930,7 +2930,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
if (otherp >= 0) \ if (otherp >= 0) \
{ \ { \
if (otherp != pnum) \ if (otherp != pnum) \
CONS_Printf("\x82%s\x80 left the game (Joined with \x82%s\x80)\n", player_names[otherp], player_names[pnum]); \ HU_AddChatText(va("\x82*%s left the game (Joined with %s)", player_names[otherp], player_names[pnum]), false); \
buf[0] = (UINT8)otherp; \ buf[0] = (UINT8)otherp; \
SendNetXCmd(XD_REMOVEPLAYER, &buf, 1); \ SendNetXCmd(XD_REMOVEPLAYER, &buf, 1); \
otherp = -1; \ otherp = -1; \

View file

@ -3234,6 +3234,8 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
players[playernum].playerstate = PST_REBORN; players[playernum].playerstate = PST_REBORN;
} }
players[playernum].pflags &= ~PF_WANTSTOJOIN;
//Now that we've done our error checking and killed the player //Now that we've done our error checking and killed the player
//if necessary, put the player on the correct team/status. //if necessary, put the player on the correct team/status.
if (G_TagGametype()) if (G_TagGametype())
@ -3315,8 +3317,6 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
else else
CONS_Printf(M_GetText("%s switched to the %c%s%c.\n"), player_names[playernum], '\x84', M_GetText("Blue Team"), '\x80'); CONS_Printf(M_GetText("%s switched to the %c%s%c.\n"), player_names[playernum], '\x84', M_GetText("Blue Team"), '\x80');
} }
else if (players[playernum].pflags & PF_WANTSTOJOIN)
players[playernum].pflags &= ~PF_WANTSTOJOIN;
else else
HU_AddChatText(va("\x82*%s became a spectator.", player_names[playernum]), false); HU_AddChatText(va("\x82*%s became a spectator.", player_names[playernum]), false);

View file

@ -280,6 +280,7 @@ typedef enum
k_throwdir, // Held dir of controls; 1 = forward, 0 = none, -1 = backward (was "player->heldDir") k_throwdir, // Held dir of controls; 1 = forward, 0 = none, -1 = backward (was "player->heldDir")
k_lapanimation, // Used to show the lap start wing logo animation k_lapanimation, // Used to show the lap start wing logo animation
k_laphand, // Lap hand gfx to use; 0 = none, 1 = :ok_hand:, 2 = :thumbs_up:, 3 = :thumps_down:
k_cardanimation, // Used to determine the position of some full-screen Battle Mode graphics k_cardanimation, // Used to determine the position of some full-screen Battle Mode graphics
k_voices, // Used to stop the player saying more voices than it should k_voices, // Used to stop the player saying more voices than it should
k_tauntvoices, // Used to specifically stop taunt voice spam k_tauntvoices, // Used to specifically stop taunt voice spam
@ -308,6 +309,7 @@ typedef enum
k_destboostcam, // Ditto k_destboostcam, // Ditto
k_timeovercam, // Camera timer for leaving behind or not k_timeovercam, // Camera timer for leaving behind or not
k_aizdriftstrat, // Let go of your drift while boosting? Helper for the SICK STRATZ you have just unlocked k_aizdriftstrat, // Let go of your drift while boosting? Helper for the SICK STRATZ you have just unlocked
k_brakedrift, // Helper for brake-drift spark spawning
k_itemroulette, // Used for the roulette when deciding what item to give you (was "pw_kartitem") k_itemroulette, // Used for the roulette when deciding what item to give you (was "pw_kartitem")
k_roulettetype, // Used for the roulette, for deciding type (currently only used for Battle, to give you better items from Karma items) k_roulettetype, // Used for the roulette, for deciding type (currently only used for Battle, to give you better items from Karma items)
@ -344,6 +346,7 @@ typedef enum
k_comebackpoints, // Number of times you've bombed or gave an item to someone; once it's 3 it gets set back to 0 and you're given a bumper k_comebackpoints, // Number of times you've bombed or gave an item to someone; once it's 3 it gets set back to 0 and you're given a bumper
k_comebackmode, // 0 = bomb, 1 = item k_comebackmode, // 0 = bomb, 1 = item
k_wanted, // Timer for determining WANTED status, lowers when hitting people, prevents the game turning into Camp Lazlo k_wanted, // Timer for determining WANTED status, lowers when hitting people, prevents the game turning into Camp Lazlo
k_yougotem, // "You Got Em" gfx when hitting someone as a karma player via a method that gets you back in the game instantly
NUMKARTSTUFF NUMKARTSTUFF
} kartstufftype_t; } kartstufftype_t;

View file

@ -6247,6 +6247,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_DRIFTSPARK_C1", "S_DRIFTSPARK_C1",
"S_DRIFTSPARK_C2", "S_DRIFTSPARK_C2",
// Brake drift sparks
"S_BRAKEDRIFT",
// Drift Smoke // Drift Smoke
"S_DRIFTDUST1", "S_DRIFTDUST1",
"S_DRIFTDUST2", "S_DRIFTDUST2",
@ -6758,6 +6761,36 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
"S_KARMAWHEEL", // Karma player wheels "S_KARMAWHEEL", // Karma player wheels
"S_BATTLEPOINT1A", // Battle point indicators
"S_BATTLEPOINT1B",
"S_BATTLEPOINT1C",
"S_BATTLEPOINT1D",
"S_BATTLEPOINT1E",
"S_BATTLEPOINT1F",
"S_BATTLEPOINT1G",
"S_BATTLEPOINT1H",
"S_BATTLEPOINT1I",
"S_BATTLEPOINT2A",
"S_BATTLEPOINT2B",
"S_BATTLEPOINT2C",
"S_BATTLEPOINT2D",
"S_BATTLEPOINT2E",
"S_BATTLEPOINT2F",
"S_BATTLEPOINT2G",
"S_BATTLEPOINT2H",
"S_BATTLEPOINT2I",
"S_BATTLEPOINT3A",
"S_BATTLEPOINT3B",
"S_BATTLEPOINT3C",
"S_BATTLEPOINT3D",
"S_BATTLEPOINT3E",
"S_BATTLEPOINT3F",
"S_BATTLEPOINT3G",
"S_BATTLEPOINT3H",
"S_BATTLEPOINT3I",
// Thunder shield use stuff; // Thunder shield use stuff;
"S_KSPARK1", // Sparkling Radius "S_KSPARK1", // Sparkling Radius
"S_KSPARK2", "S_KSPARK2",
@ -7393,6 +7426,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_INVULNFLASH", "MT_INVULNFLASH",
"MT_WIPEOUTTRAIL", "MT_WIPEOUTTRAIL",
"MT_DRIFTSPARK", "MT_DRIFTSPARK",
"MT_BRAKEDRIFT",
"MT_DRIFTDUST", "MT_DRIFTDUST",
"MT_ROCKETSNEAKER", // Rocket sneakers "MT_ROCKETSNEAKER", // Rocket sneakers
@ -7515,6 +7549,8 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s
"MT_KARMAHITBOX", "MT_KARMAHITBOX",
"MT_KARMAWHEEL", "MT_KARMAWHEEL",
"MT_BATTLEPOINT",
"MT_FZEROBOOM", "MT_FZEROBOOM",
// Midnight Channel stuff: // Midnight Channel stuff:
@ -7867,6 +7903,7 @@ static const char *const KARTSTUFF_LIST[] = {
"THROWDIR", "THROWDIR",
"LAPANIMATION", "LAPANIMATION",
"LAPHAND",
"CARDANIMATION", "CARDANIMATION",
"VOICES", "VOICES",
"TAUNTVOICES", "TAUNTVOICES",
@ -7895,6 +7932,7 @@ static const char *const KARTSTUFF_LIST[] = {
"DESTBOOSTCAM", "DESTBOOSTCAM",
"TIMEOVERCAM", "TIMEOVERCAM",
"AIZDRIFTSTRAT", "AIZDRIFTSTRAT",
"BRAKEDRIFT",
"ITEMROULETTE", "ITEMROULETTE",
"ROULETTETYPE", "ROULETTETYPE",
@ -7927,6 +7965,7 @@ static const char *const KARTSTUFF_LIST[] = {
"COMEBACKPOINTS", "COMEBACKPOINTS",
"COMEBACKMODE", "COMEBACKMODE",
"WANTED", "WANTED",
"YOUGOTEM",
}; };
static const char *const HUDITEMS_LIST[] = { static const char *const HUDITEMS_LIST[] = {

View file

@ -1328,6 +1328,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->header.numFrames; frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->header.numFrames;
buff = md2->model->glCommandBuffer; buff = md2->model->glCommandBuffer;
curr = &md2->model->frames[frame]; curr = &md2->model->frames[frame];
#if 0
if (cv_grmd2.value == 1 && tics <= durs) if (cv_grmd2.value == 1 && tics <= durs)
{ {
// frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation // frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation
@ -1348,6 +1349,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
} }
} }
} }
#endif
//Hurdler: it seems there is still a small problem with mobj angle //Hurdler: it seems there is still a small problem with mobj angle
p.x = FIXED_TO_FLOAT(spr->mobj->x); p.x = FIXED_TO_FLOAT(spr->mobj->x);

View file

@ -109,8 +109,8 @@ static patch_t *crosshair[HU_CROSSHAIRS]; // 3 precached crosshair graphics
// protos. // protos.
// ------- // -------
static void HU_DrawRankings(void); static void HU_DrawRankings(void);
static void HU_DrawCoopOverlay(void); //static void HU_DrawCoopOverlay(void);
static void HU_DrawNetplayCoopOverlay(void); //static void HU_DrawNetplayCoopOverlay(void);
//====================================================================== //======================================================================
// KEYBOARD LAYOUTS FOR ENTERING TEXT // KEYBOARD LAYOUTS FOR ENTERING TEXT
@ -2020,26 +2020,27 @@ UINT32 hu_demolap;
static void HU_DrawDemoInfo(void) static void HU_DrawDemoInfo(void)
{ {
V_DrawString(4, 188-16, V_YELLOWMAP, va(M_GetText("%s's replay"), player_names[0])); V_DrawCenteredString((BASEVIDWIDTH/2), BASEVIDHEIGHT-40, 0, M_GetText("Replay:"));
V_DrawCenteredString((BASEVIDWIDTH/2), BASEVIDHEIGHT-32, V_ALLOWLOWERCASE, player_names[0]);
if (modeattacking) if (modeattacking)
{ {
V_DrawString(4, 188-8, V_YELLOWMAP|V_MONOSPACE, "BEST TIME:"); V_DrawRightAlignedString((BASEVIDWIDTH/2)-4, BASEVIDHEIGHT-24, V_YELLOWMAP|V_MONOSPACE, "BEST TIME:");
if (hu_demotime != UINT32_MAX) if (hu_demotime != UINT32_MAX)
V_DrawRightAlignedString(120, 188-8, V_MONOSPACE, va("%i:%02i.%02i", V_DrawString((BASEVIDWIDTH/2)+4, BASEVIDHEIGHT-24, V_MONOSPACE, va("%i'%02i\"%02i",
G_TicsToMinutes(hu_demotime,true), G_TicsToMinutes(hu_demotime,true),
G_TicsToSeconds(hu_demotime), G_TicsToSeconds(hu_demotime),
G_TicsToCentiseconds(hu_demotime))); G_TicsToCentiseconds(hu_demotime)));
else else
V_DrawRightAlignedString(120, 188-8, V_MONOSPACE, "--:--.--"); V_DrawString((BASEVIDWIDTH/2)+4, BASEVIDHEIGHT-24, V_MONOSPACE, "--'--\"--");
V_DrawString(4, 188, V_YELLOWMAP|V_MONOSPACE, "BEST LAP:"); V_DrawRightAlignedString((BASEVIDWIDTH/2)-4, BASEVIDHEIGHT-16, V_YELLOWMAP|V_MONOSPACE, "BEST LAP:");
if (hu_demolap != UINT32_MAX) if (hu_demolap != UINT32_MAX)
V_DrawRightAlignedString(120, 188, V_MONOSPACE, va("%i:%02i.%02i", V_DrawString((BASEVIDWIDTH/2)+4, BASEVIDHEIGHT-16, V_MONOSPACE, va("%i'%02i\"%02i",
G_TicsToMinutes(hu_demolap,true), G_TicsToMinutes(hu_demolap,true),
G_TicsToSeconds(hu_demolap), G_TicsToSeconds(hu_demolap),
G_TicsToCentiseconds(hu_demolap))); G_TicsToCentiseconds(hu_demolap)));
else else
V_DrawRightAlignedString(120, 188, V_MONOSPACE, "--:--.--"); V_DrawString((BASEVIDWIDTH/2)+4, BASEVIDHEIGHT-16, V_MONOSPACE, "--'--\"--");
} }
} }
@ -2112,11 +2113,11 @@ void HU_Drawer(void)
if (LUA_HudEnabled(hud_rankings)) if (LUA_HudEnabled(hud_rankings))
#endif #endif
HU_DrawRankings(); HU_DrawRankings();
if (gametype == GT_COOP) //if (gametype == GT_COOP)
HU_DrawNetplayCoopOverlay(); //HU_DrawNetplayCoopOverlay();
} }
else //else
HU_DrawCoopOverlay(); //HU_DrawCoopOverlay();
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
LUAh_ScoresHUD(); LUAh_ScoresHUD();
#endif #endif
@ -2274,11 +2275,12 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
{ {
INT32 i, j, rightoffset = 240; INT32 i, j, rightoffset = 240;
const UINT8 *colormap; const UINT8 *colormap;
INT32 dupadjust = (vid.width/vid.dupx), duptweak = (dupadjust - BASEVIDWIDTH)/2;
//this function is designed for 9 or less score lines only //this function is designed for 9 or less score lines only
//I_Assert(scorelines <= 9); -- not today bitch, kart fixed it up //I_Assert(scorelines <= 9); -- not today bitch, kart fixed it up
V_DrawFill(1, 26, 318, 1, 0); // Draw a horizontal line because it looks nice! V_DrawFill(1-duptweak, 26, dupadjust-2, 1, 0); // Draw a horizontal line because it looks nice!
if (scorelines > 8) if (scorelines > 8)
{ {
V_DrawFill(160, 26, 1, 154, 0); // Draw a vertical line to separate the two sides. V_DrawFill(160, 26, 1, 154, 0); // Draw a vertical line to separate the two sides.
@ -2293,9 +2295,9 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
if (players[tab[i].num].spectator || !players[tab[i].num].mo) if (players[tab[i].num].spectator || !players[tab[i].num].mo)
continue; //ignore them. continue; //ignore them.
if (!splitscreen) // don't draw it on splitscreen, if (netgame) // don't draw it offline
{ {
if (!(tab[i].num == serverplayer)) if (tab[i].num != serverplayer)
HU_drawPing(x+ 253, y+2, playerpingtable[tab[i].num], false); HU_drawPing(x+ 253, y+2, playerpingtable[tab[i].num], false);
} }
@ -2562,16 +2564,17 @@ void HU_DrawEmeralds(INT32 x, INT32 y, INT32 pemeralds)
// //
static inline void HU_DrawSpectatorTicker(void) static inline void HU_DrawSpectatorTicker(void)
{ {
int i; INT32 i;
int length = 0, height = 174; INT32 length = 0, height = 174;
int totallength = 0, templength = 0; INT32 totallength = 0, templength = -8;
INT32 dupadjust = (vid.width/vid.dupx), duptweak = (dupadjust - BASEVIDWIDTH)/2;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].spectator) if (playeringame[i] && players[i].spectator)
totallength += (signed)strlen(player_names[i]) * 8 + 16; totallength += (signed)strlen(player_names[i]) * 8 + 16;
length -= (leveltime % (totallength + BASEVIDWIDTH)); length -= (leveltime % (totallength + dupadjust+8));
length += BASEVIDWIDTH; length += dupadjust;
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].spectator) if (playeringame[i] && players[i].spectator)
@ -2579,15 +2582,18 @@ static inline void HU_DrawSpectatorTicker(void)
char *pos; char *pos;
char initial[MAXPLAYERNAME+1]; char initial[MAXPLAYERNAME+1];
char current[MAXPLAYERNAME+1]; char current[MAXPLAYERNAME+1];
INT32 len;
len = ((signed)strlen(player_names[i]) * 8 + 16);
strcpy(initial, player_names[i]); strcpy(initial, player_names[i]);
pos = initial; pos = initial;
if (length >= -((signed)strlen(player_names[i]) * 8 + 16) && length <= BASEVIDWIDTH) if (length >= -len)
{ {
if (length < 0) if (length < -8)
{ {
UINT8 eatenchars = (UINT8)(abs(length) / 8 + 1); UINT8 eatenchars = (UINT8)(abs(length) / 8);
if (eatenchars <= strlen(initial)) if (eatenchars <= strlen(initial))
{ {
@ -2595,7 +2601,7 @@ static inline void HU_DrawSpectatorTicker(void)
// then compensate the drawing position. // then compensate the drawing position.
pos += eatenchars; pos += eatenchars;
strcpy(current, pos); strcpy(current, pos);
templength = length % 8 + 8; templength = ((length + 8) % 8);
} }
else else
{ {
@ -2609,10 +2615,11 @@ static inline void HU_DrawSpectatorTicker(void)
templength = length; templength = length;
} }
V_DrawString(templength, height + 8, V_TRANSLUCENT, current); V_DrawString(templength - duptweak, height, V_TRANSLUCENT|V_ALLOWLOWERCASE, current);
} }
length += (signed)strlen(player_names[i]) * 8 + 16; if ((length += len) >= dupadjust+8)
break;
} }
} }
@ -2627,6 +2634,8 @@ static void HU_DrawRankings(void)
boolean completed[MAXPLAYERS]; boolean completed[MAXPLAYERS];
UINT32 whiteplayer = MAXPLAYERS; UINT32 whiteplayer = MAXPLAYERS;
V_DrawFadeScreen(0xFF00, 16); // A little more readable, and prevents cheating the fades under other circumstances.
if (cons_menuhighlight.value) if (cons_menuhighlight.value)
hilicol = cons_menuhighlight.value; hilicol = cons_menuhighlight.value;
else if (modeattacking) else if (modeattacking)
@ -2636,9 +2645,9 @@ static void HU_DrawRankings(void)
// draw the current gametype in the lower right // draw the current gametype in the lower right
if (modeattacking) if (modeattacking)
V_DrawString(4, 188, hilicol, "Record Attack"); V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, "Record Attack");
else else
V_DrawString(4, 188, hilicol, gametype_cons_t[gametype].strvalue); V_DrawString(4, 188, hilicol|V_SNAPTOBOTTOM|V_SNAPTOLEFT, gametype_cons_t[gametype].strvalue);
if (G_GametypeHasTeams()) if (G_GametypeHasTeams())
{ {
@ -2733,9 +2742,6 @@ static void HU_DrawRankings(void)
numplayersingame++; numplayersingame++;
} }
if (netgame && numplayersingame <= 1)
K_drawKartFreePlay(leveltime);
for (j = 0; j < numplayersingame; j++) for (j = 0; j < numplayersingame; j++)
{ {
UINT8 lowestposition = MAXPLAYERS; UINT8 lowestposition = MAXPLAYERS;
@ -2783,11 +2789,11 @@ static void HU_DrawRankings(void)
HU_DrawDualTabRankings(32, 32, tab, scorelines, whiteplayer);*/ HU_DrawDualTabRankings(32, 32, tab, scorelines, whiteplayer);*/
// draw spectators in a ticker across the bottom // draw spectators in a ticker across the bottom
if (!splitscreen && G_GametypeHasSpectators()) if (netgame && G_GametypeHasSpectators())
HU_DrawSpectatorTicker(); HU_DrawSpectatorTicker();
} }
static void HU_DrawCoopOverlay(void) /*static void HU_DrawCoopOverlay(void)
{ {
if (token if (token
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
@ -2843,7 +2849,7 @@ static void HU_DrawNetplayCoopOverlay(void)
if (emeralds & (1 << i)) if (emeralds & (1 << i))
V_DrawScaledPatch(20 + (i * 20), 6, 0, emeraldpics[i]); V_DrawScaledPatch(20 + (i * 20), 6, 0, emeraldpics[i]);
} }
} }*/
// Interface to CECHO settings for the outside world, avoiding the // Interface to CECHO settings for the outside world, avoiding the

View file

@ -56,13 +56,13 @@ char sprnames[NUMSPRITES + 1][5] =
"SRBJ","SRBK","SRBL","SRBM","SRBN","SRBO", "SRBJ","SRBK","SRBL","SRBM","SRBN","SRBO",
//SRB2kart Sprites //SRB2kart Sprites
"SPRG","BSPR","RNDM","RPOP","SGNS","FAST","DSHR","BOST","BOSM","KFRE", "SPRG","BSPR","RNDM","RPOP","SGNS","FAST","DSHR","BOST","BOSM","KFRE",
"KINV","KINF","WIPD","DRIF","DUST","RSHE","FITM","BANA","ORBN","JAWZ", "KINV","KINF","WIPD","DRIF","BDRF","DUST","RSHE","FITM","BANA","ORBN",
"SSMN","KRBM","BHOG","BHBM","SPBM","THNS","SINK","SITR","KBLN","DEZL", "JAWZ","SSMN","KRBM","BHOG","BHBM","SPBM","THNS","SINK","SITR","KBLN",
"POKE","AUDI","DECO","DOOD","SNES","GBAS","SPRS","BUZB","CHOM","SACO", "DEZL","POKE","AUDI","DECO","DOOD","SNES","GBAS","SPRS","BUZB","CHOM",
"CRAB","SHAD","BRNG","BUMP","FLEN","CLAS","PSHW","ISTA","ISTB","ARRO", "SACO","CRAB","SHAD","BRNG","BUMP","FLEN","CLAS","PSHW","ISTA","ISTB",
"ITEM","ITMO","ITMI","ITMN","WANT","PBOM","RETI","AIDU","KSPK","LZI1", "ARRO","ITEM","ITMO","ITMI","ITMN","WANT","PBOM","HIT1","HIT2","HIT3",
"LZI2","KLIT","FZSM","FZBM","FPRT","SPTL","ENM1","GARU","MARR","REAP", "RETI","AIDU","KSPK","LZI1","LZI2","KLIT","FZSM","FZBM","FPRT","SPTL",
"JITB","CDMO","CDBU","VIEW" "ENM1","GARU","MARR","REAP","JITB","CDMO","CDBU","VIEW"
}; };
// Doesn't work with g++, needs actionf_p1 (don't modify this comment) // Doesn't work with g++, needs actionf_p1 (don't modify this comment)
@ -2561,6 +2561,8 @@ state_t states[NUMSTATES] =
{SPR_DRIF, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_DRIFTSPARK_C2}, // S_DRIFTSPARK_C1 {SPR_DRIF, FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_DRIFTSPARK_C2}, // S_DRIFTSPARK_C1
{SPR_DRIF, FF_FULLBRIGHT|FF_TRANS20, 1, {NULL}, 0, 0, S_DRIFTSPARK_A3}, // S_DRIFTSPARK_C2 (Loop back to A3) {SPR_DRIF, FF_FULLBRIGHT|FF_TRANS20, 1, {NULL}, 0, 0, S_DRIFTSPARK_A3}, // S_DRIFTSPARK_C2 (Loop back to A3)
{SPR_BDRF, FF_FULLBRIGHT|FF_PAPERSPRITE|FF_ANIMATE, -1, {NULL}, 5, 2, S_BRAKEDRIFT}, // S_BRAKEDRIFT
{SPR_DUST, 0, 3, {NULL}, 0, 0, S_DRIFTDUST2}, // S_DRIFTDUST1 {SPR_DUST, 0, 3, {NULL}, 0, 0, S_DRIFTDUST2}, // S_DRIFTDUST1
{SPR_DUST, 1, 3, {NULL}, 0, 0, S_DRIFTDUST3}, // S_DRIFTDUST2 {SPR_DUST, 1, 3, {NULL}, 0, 0, S_DRIFTDUST3}, // S_DRIFTDUST2
{SPR_DUST, FF_TRANS20|2, 3, {NULL}, 0, 0, S_DRIFTDUST4}, // S_DRIFTDUST3 {SPR_DUST, FF_TRANS20|2, 3, {NULL}, 0, 0, S_DRIFTDUST4}, // S_DRIFTDUST3
@ -3046,6 +3048,36 @@ state_t states[NUMSTATES] =
{SPR_PBOM, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KARMAWHEEL {SPR_PBOM, 0, -1, {NULL}, 0, 0, S_NULL}, // S_KARMAWHEEL
{SPR_HIT1, 0, 7, {NULL}, 0, 0, S_BATTLEPOINT1B}, // S_BATTLEPOINT1A
{SPR_HIT1, 2, 1, {NULL}, 0, 0, S_BATTLEPOINT1C}, // S_BATTLEPOINT1B
{SPR_HIT1, 4, 1, {NULL}, 0, 0, S_BATTLEPOINT1D}, // S_BATTLEPOINT1C
{SPR_HIT1, 3, 1, {NULL}, 0, 0, S_BATTLEPOINT1E}, // S_BATTLEPOINT1D
{SPR_HIT1, 2, 1, {NULL}, 0, 0, S_BATTLEPOINT1F}, // S_BATTLEPOINT1E
{SPR_HIT1, 1, 1, {NULL}, 0, 0, S_BATTLEPOINT1G}, // S_BATTLEPOINT1F
{SPR_HIT1, 2, TICRATE, {NULL}, 0, 0, S_BATTLEPOINT1H}, // S_BATTLEPOINT1G
{SPR_HIT1, 5, 1, {NULL}, 0, 0, S_BATTLEPOINT1I}, // S_BATTLEPOINT1H
{SPR_HIT1, 6, 1, {NULL}, 0, 0, S_NULL}, // S_BATTLEPOINT1I
{SPR_HIT2, 0, 7, {NULL}, 0, 0, S_BATTLEPOINT2B}, // S_BATTLEPOINT2A
{SPR_HIT2, 2, 1, {NULL}, 0, 0, S_BATTLEPOINT2C}, // S_BATTLEPOINT2B
{SPR_HIT2, 4, 1, {NULL}, 0, 0, S_BATTLEPOINT2D}, // S_BATTLEPOINT2C
{SPR_HIT2, 3, 1, {NULL}, 0, 0, S_BATTLEPOINT2E}, // S_BATTLEPOINT2D
{SPR_HIT2, 2, 1, {NULL}, 0, 0, S_BATTLEPOINT2F}, // S_BATTLEPOINT2E
{SPR_HIT2, 1, 1, {NULL}, 0, 0, S_BATTLEPOINT2G}, // S_BATTLEPOINT2F
{SPR_HIT2, 2, TICRATE, {NULL}, 0, 0, S_BATTLEPOINT2H}, // S_BATTLEPOINT2G
{SPR_HIT2, 5, 1, {NULL}, 0, 0, S_BATTLEPOINT2I}, // S_BATTLEPOINT2H
{SPR_HIT2, 6, 1, {NULL}, 0, 0, S_NULL}, // S_BATTLEPOINT2I
{SPR_HIT3, 0, 7, {NULL}, 0, 0, S_BATTLEPOINT3B}, // S_BATTLEPOINT3A
{SPR_HIT3, 2, 1, {NULL}, 0, 0, S_BATTLEPOINT3C}, // S_BATTLEPOINT3B
{SPR_HIT3, 4, 1, {NULL}, 0, 0, S_BATTLEPOINT3D}, // S_BATTLEPOINT3C
{SPR_HIT3, 3, 1, {NULL}, 0, 0, S_BATTLEPOINT3E}, // S_BATTLEPOINT3D
{SPR_HIT3, 2, 1, {NULL}, 0, 0, S_BATTLEPOINT3F}, // S_BATTLEPOINT3E
{SPR_HIT3, 1, 1, {NULL}, 0, 0, S_BATTLEPOINT3G}, // S_BATTLEPOINT3F
{SPR_HIT3, 2, TICRATE, {NULL}, 0, 0, S_BATTLEPOINT3H}, // S_BATTLEPOINT3G
{SPR_HIT3, 5, 1, {NULL}, 0, 0, S_BATTLEPOINT3I}, // S_BATTLEPOINT3H
{SPR_HIT3, 6, 1, {NULL}, 0, 0, S_NULL}, // S_BATTLEPOINT3I
// Oh no it's annoying lightning states....... // Oh no it's annoying lightning states.......
// Lightning Sparks (it's the ones we'll use for the radius) // Lightning Sparks (it's the ones we'll use for the radius)
{SPR_KSPK, FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_KSPARK2}, // S_KSPARK1 {SPR_KSPK, FF_FULLBRIGHT, 2, {A_LightningFollowPlayer}, 0, 0, S_KSPARK2}, // S_KSPARK1
@ -14873,6 +14905,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate S_NULL // raisestate
}, },
{ // MT_BRAKEDRIFT
-1, // doomednum
S_BRAKEDRIFT, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
8, // speed
8*FRACUNIT, // radius
8*FRACUNIT, // height
1, // display offset
100, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags
S_NULL // raisestate
},
{ // MT_DRIFTDUST { // MT_DRIFTDUST
-1, // doomednum -1, // doomednum
S_DRIFTDUST1, // spawnstate S_DRIFTDUST1, // spawnstate
@ -17276,6 +17335,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
S_NULL // raisestate S_NULL // raisestate
}, },
{ // MT_BATTLEPOINT
-1, // doomednum
S_INVISIBLE, // spawnstate
1000, // spawnhealth
S_NULL, // seestate
sfx_None, // seesound
8, // reactiontime
sfx_None, // attacksound
S_NULL, // painstate
0, // painchance
sfx_None, // painsound
S_NULL, // meleestate
S_NULL, // missilestate
S_NULL, // deathstate
S_NULL, // xdeathstate
sfx_None, // deathsound
8, // speed
8*FRACUNIT, // radius
8*FRACUNIT, // height
-1, // display offset
100, // mass
0, // damage
sfx_None, // activesound
MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_DONTENCOREMAP, // flags
S_NULL // raisestate
},
{ // MT_FZEROBOOM { // MT_FZEROBOOM
-1, // doomednum -1, // doomednum
S_INVISIBLE, // spawnstate S_INVISIBLE, // spawnstate

View file

@ -601,6 +601,7 @@ typedef enum sprite
SPR_KINF, // Invincibility flash SPR_KINF, // Invincibility flash
SPR_WIPD, // Wipeout dust trail SPR_WIPD, // Wipeout dust trail
SPR_DRIF, // Drift Sparks SPR_DRIF, // Drift Sparks
SPR_BDRF, // Brake drift sparks
SPR_DUST, // Drift Dust SPR_DUST, // Drift Dust
// Kart Items // Kart Items
@ -651,6 +652,11 @@ typedef enum sprite
SPR_WANT, SPR_WANT,
SPR_PBOM, // player bomb SPR_PBOM, // player bomb
SPR_HIT1, // battle points
SPR_HIT2, // battle points
SPR_HIT3, // battle points
SPR_RETI, // player reticule SPR_RETI, // player reticule
SPR_AIDU, SPR_AIDU,
@ -3109,6 +3115,9 @@ typedef enum state
S_DRIFTSPARK_C1, S_DRIFTSPARK_C1,
S_DRIFTSPARK_C2, S_DRIFTSPARK_C2,
// Brake drift sparks
S_BRAKEDRIFT,
// Drift Smoke // Drift Smoke
S_DRIFTDUST1, S_DRIFTDUST1,
S_DRIFTDUST2, S_DRIFTDUST2,
@ -3620,6 +3629,36 @@ typedef enum state
S_KARMAWHEEL, S_KARMAWHEEL,
S_BATTLEPOINT1A, // Battle point indicators
S_BATTLEPOINT1B,
S_BATTLEPOINT1C,
S_BATTLEPOINT1D,
S_BATTLEPOINT1E,
S_BATTLEPOINT1F,
S_BATTLEPOINT1G,
S_BATTLEPOINT1H,
S_BATTLEPOINT1I,
S_BATTLEPOINT2A,
S_BATTLEPOINT2B,
S_BATTLEPOINT2C,
S_BATTLEPOINT2D,
S_BATTLEPOINT2E,
S_BATTLEPOINT2F,
S_BATTLEPOINT2G,
S_BATTLEPOINT2H,
S_BATTLEPOINT2I,
S_BATTLEPOINT3A,
S_BATTLEPOINT3B,
S_BATTLEPOINT3C,
S_BATTLEPOINT3D,
S_BATTLEPOINT3E,
S_BATTLEPOINT3F,
S_BATTLEPOINT3G,
S_BATTLEPOINT3H,
S_BATTLEPOINT3I,
// Thunder shield use stuff; // Thunder shield use stuff;
S_KSPARK1, // Sparkling Radius S_KSPARK1, // Sparkling Radius
S_KSPARK2, S_KSPARK2,
@ -4272,6 +4311,7 @@ typedef enum mobj_type
MT_INVULNFLASH, MT_INVULNFLASH,
MT_WIPEOUTTRAIL, MT_WIPEOUTTRAIL,
MT_DRIFTSPARK, MT_DRIFTSPARK,
MT_BRAKEDRIFT,
MT_DRIFTDUST, MT_DRIFTDUST,
MT_ROCKETSNEAKER, MT_ROCKETSNEAKER,
@ -4394,6 +4434,8 @@ typedef enum mobj_type
MT_KARMAHITBOX, MT_KARMAHITBOX,
MT_KARMAWHEEL, MT_KARMAWHEEL,
MT_BATTLEPOINT,
MT_FZEROBOOM, MT_FZEROBOOM,
// Midnight Channel stuff: // Midnight Channel stuff:

View file

@ -487,22 +487,22 @@ static INT32 K_KartItemOddsRace[NUMKARTRESULTS][9] =
{ {
//P-Odds 0 1 2 3 4 5 6 7 8 //P-Odds 0 1 2 3 4 5 6 7 8
/*Sneaker*/ {20, 0, 0, 4, 6, 6, 0, 0, 0 }, // Sneaker /*Sneaker*/ {20, 0, 0, 4, 6, 6, 0, 0, 0 }, // Sneaker
/*Rocket Sneaker*/ { 0, 0, 0, 0, 0, 2, 5, 5, 0 }, // Rocket Sneaker /*Rocket Sneaker*/ { 0, 0, 0, 0, 0, 1, 3, 5, 3 }, // Rocket Sneaker
/*Invincibility*/ { 0, 0, 0, 0, 0, 1, 4, 6,16 }, // Invincibility /*Invincibility*/ { 0, 0, 0, 0, 0, 1, 4, 6,14 }, // Invincibility
/*Banana*/ { 0, 9, 4, 2, 1, 0, 0, 0, 0 }, // Banana /*Banana*/ { 0, 9, 4, 2, 1, 0, 0, 0, 0 }, // Banana
/*Eggman Monitor*/ { 0, 4, 3, 2, 0, 0, 0, 0, 0 }, // Eggman Monitor /*Eggman Monitor*/ { 0, 4, 3, 2, 0, 0, 0, 0, 0 }, // Eggman Monitor
/*Orbinaut*/ { 0, 6, 5, 3, 2, 0, 0, 0, 0 }, // Orbinaut /*Orbinaut*/ { 0, 6, 5, 3, 2, 0, 0, 0, 0 }, // Orbinaut
/*Jawz*/ { 0, 0, 3, 2, 1, 1, 0, 0, 0 }, // Jawz /*Jawz*/ { 0, 0, 3, 2, 1, 1, 0, 0, 0 }, // Jawz
/*Mine*/ { 0, 0, 1, 2, 1, 0, 0, 0, 0 }, // Mine /*Mine*/ { 0, 0, 2, 2, 1, 0, 0, 0, 0 }, // Mine
/*Ballhog*/ { 0, 0, 1, 2, 1, 0, 0, 0, 0 }, // Ballhog /*Ballhog*/ { 0, 0, 0, 2, 1, 0, 0, 0, 0 }, // Ballhog
/*Self-Propelled Bomb*/ { 0, 0, 1, 2, 3, 4, 2, 2, 0 }, // Self-Propelled Bomb /*Self-Propelled Bomb*/ { 0, 0, 1, 2, 3, 4, 2, 2, 0 }, // Self-Propelled Bomb
/*Grow*/ { 0, 0, 0, 0, 0, 1, 3, 5, 4 }, // Grow /*Grow*/ { 0, 0, 0, 0, 0, 1, 3, 5, 3 }, // Grow
/*Shrink*/ { 0, 0, 0, 0, 0, 0, 1, 2, 0 }, // Shrink /*Shrink*/ { 0, 0, 0, 0, 0, 0, 0, 2, 0 }, // Shrink
/*Thunder Shield*/ { 0, 1, 2, 0, 0, 0, 0, 0, 0 }, // Thunder Shield /*Thunder Shield*/ { 0, 1, 2, 0, 0, 0, 0, 0, 0 }, // Thunder Shield
/*Hyudoro*/ { 0, 0, 0, 0, 1, 2, 1, 0, 0 }, // Hyudoro /*Hyudoro*/ { 0, 0, 0, 0, 1, 2, 1, 0, 0 }, // Hyudoro
/*Pogo Spring*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Pogo Spring /*Pogo Spring*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Pogo Spring
/*Kitchen Sink*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Kitchen Sink /*Kitchen Sink*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }, // Kitchen Sink
/*Sneaker x3*/ { 0, 0, 0, 0, 3, 6, 6, 2, 0 }, // Sneaker x3 /*Sneaker x3*/ { 0, 0, 0, 0, 3, 7, 9, 2, 0 }, // Sneaker x3
/*Banana x3*/ { 0, 0, 1, 1, 0, 0, 0, 0, 0 }, // Banana x3 /*Banana x3*/ { 0, 0, 1, 1, 0, 0, 0, 0, 0 }, // Banana x3
/*Banana x10*/ { 0, 0, 0, 0, 1, 0, 0, 0, 0 }, // Banana x10 /*Banana x10*/ { 0, 0, 0, 0, 1, 0, 0, 0, 0 }, // Banana x10
/*Orbinaut x3*/ { 0, 0, 0, 1, 0, 0, 0, 0, 0 }, // Orbinaut x3 /*Orbinaut x3*/ { 0, 0, 0, 1, 0, 0, 0, 0, 0 }, // Orbinaut x3
@ -666,7 +666,7 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed)
break; break;
case KITEM_INVINCIBILITY: case KITEM_INVINCIBILITY:
POWERITEMODDS(newodds); POWERITEMODDS(newodds);
if ((!cv_invincibility.value) || (pinvin > 2)) newodds = 0; if ((!cv_invincibility.value) || (pinvin >= 2)) newodds = 0;
break; break;
case KITEM_BANANA: case KITEM_BANANA:
if (!cv_banana.value) newodds = 0; if (!cv_banana.value) newodds = 0;
@ -700,7 +700,7 @@ static INT32 K_KartGetItemOdds(UINT8 pos, SINT8 item, fixed_t mashed)
break; break;
case KITEM_GROW: case KITEM_GROW:
POWERITEMODDS(newodds); POWERITEMODDS(newodds);
if ((!cv_grow.value) || (pinvin > 2)) newodds = 0; if ((!cv_grow.value) || (pinvin >= 2)) newodds = 0;
break; break;
case KITEM_SHRINK: case KITEM_SHRINK:
POWERITEMODDS(newodds); POWERITEMODDS(newodds);
@ -1330,6 +1330,23 @@ static void K_SpawnDashDustRelease(player_t *player)
} }
} }
static void K_SpawnBrakeDriftSparks(player_t *player) // Be sure to update the mobj thinker case too!
{
mobj_t *sparks;
I_Assert(player != NULL);
I_Assert(player->mo != NULL);
I_Assert(!P_MobjWasRemoved(player->mo));
// Position & etc are handled in its thinker, and its spawned invisible.
// This avoids needing to dupe code if we don't need it.
sparks = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BRAKEDRIFT);
P_SetTarget(&sparks->target, player->mo);
P_SetScale(sparks, (sparks->destscale = player->mo->scale));
K_MatchGenericExtraFlags(sparks, player->mo);
sparks->flags2 |= MF2_DONTDRAW;
}
/** \brief Calculates the respawn timer and drop-boosting /** \brief Calculates the respawn timer and drop-boosting
\param player player object passed from K_KartPlayerThink \param player player object passed from K_KartPlayerThink
@ -1362,8 +1379,8 @@ void K_RespawnChecker(player_t *player)
fixed_t newx, newy, newz; fixed_t newx, newy, newz;
newangle = FixedAngle(((360/8)*i)*FRACUNIT); newangle = FixedAngle(((360/8)*i)*FRACUNIT);
newx = player->mo->x + P_ReturnThrustX(player->mo, newangle, 31*player->mo->scale); newx = player->mo->x + P_ReturnThrustX(player->mo, newangle, 31<<FRACBITS); // does NOT use scale, since this effect doesn't scale properly
newy = player->mo->y + P_ReturnThrustY(player->mo, newangle, 31*player->mo->scale); newy = player->mo->y + P_ReturnThrustY(player->mo, newangle, 31<<FRACBITS);
if (player->mo->eflags & MFE_VERTICALFLIP) if (player->mo->eflags & MFE_VERTICALFLIP)
newz = player->mo->z + player->mo->height; newz = player->mo->z + player->mo->height;
else else
@ -1383,11 +1400,19 @@ void K_RespawnChecker(player_t *player)
} }
else if (player->kartstuff[k_respawn] == 1) else if (player->kartstuff[k_respawn] == 1)
{ {
if (!P_IsObjectOnGround(player->mo)) if (player->kartstuff[k_growshrinktimer] < 0)
{
player->mo->scalespeed = mapheaderinfo[gamemap-1]->mobj_scale/TICRATE;
player->mo->destscale = 6*(mapheaderinfo[gamemap-1]->mobj_scale)/8;
if (cv_kartdebugshrink.value && !player->bot)
player->mo->destscale = 6*player->mo->destscale/8;
}
if (!P_IsObjectOnGround(player->mo) && !mapreset)
{ {
player->powers[pw_flashing] = 2; player->powers[pw_flashing] = 2;
// Sal: That's stupid and prone to accidental usage. // Sal: The old behavior was stupid and prone to accidental usage.
// Let's rip off Mania instead, and turn this into a Drop Dash! // Let's rip off Mania instead, and turn this into a Drop Dash!
if (cmd->buttons & BT_ACCELERATE) if (cmd->buttons & BT_ACCELERATE)
@ -1776,6 +1801,32 @@ void K_DoInstashield(player_t *player)
P_SetTarget(&layerb->target, player->mo); P_SetTarget(&layerb->target, player->mo);
} }
void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount)
{
statenum_t st;
mobj_t *pt;
if (!source || !source->mo)
return;
if (amount == 1)
st = S_BATTLEPOINT1A;
else if (amount == 2)
st = S_BATTLEPOINT2A;
else if (amount == 3)
st = S_BATTLEPOINT3A;
else
return; // NO STATE!
pt = P_SpawnMobj(source->mo->x, source->mo->y, source->mo->z, MT_BATTLEPOINT);
P_SetTarget(&pt->target, source->mo);
P_SetMobjState(pt, st);
if (victim && victim->skincolor)
pt->color = victim->skincolor;
else
pt->color = source->skincolor;
}
void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem) void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem)
{ {
UINT8 scoremultiply = 1; UINT8 scoremultiply = 1;
@ -1809,6 +1860,7 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem
if (source && source->player && player != source->player) if (source && source->player && player != source->player)
{ {
P_AddPlayerScore(source->player, scoremultiply); P_AddPlayerScore(source->player, scoremultiply);
K_SpawnBattlePoints(source->player, player, scoremultiply);
if (!trapitem) if (!trapitem)
{ {
source->player->kartstuff[k_wanted] -= wantedreduce; source->player->kartstuff[k_wanted] -= wantedreduce;
@ -1847,19 +1899,15 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem
player->kartstuff[k_spinouttype] = type; player->kartstuff[k_spinouttype] = type;
if (player->kartstuff[k_spinouttype] <= 0) if (player->kartstuff[k_spinouttype] <= 0) // type 0 is spinout, type 1 is wipeout
{ {
player->kartstuff[k_spinouttimer] = 3*TICRATE/2; // Banana Spinout
// At spinout, player speed is increased to 1/4 their regular speed, moving them forward // At spinout, player speed is increased to 1/4 their regular speed, moving them forward
if (player->speed < K_GetKartSpeed(player, true)/4) if (player->speed < K_GetKartSpeed(player, true)/4)
P_InstaThrust(player->mo, player->mo->angle, FixedMul(K_GetKartSpeed(player, true)/4, player->mo->scale)); P_InstaThrust(player->mo, player->mo->angle, FixedMul(K_GetKartSpeed(player, true)/4, player->mo->scale));
S_StartSound(player->mo, sfx_slip); S_StartSound(player->mo, sfx_slip);
} }
else
player->kartstuff[k_spinouttimer] = TICRATE+20; // Wipeout
player->kartstuff[k_spinouttimer] = (3*TICRATE/2)+2;
player->powers[pw_flashing] = K_GetKartFlashing(player); player->powers[pw_flashing] = K_GetKartFlashing(player);
if (player->mo->state != &states[S_KART_SPIN]) if (player->mo->state != &states[S_KART_SPIN])
@ -1903,6 +1951,7 @@ void K_SquishPlayer(player_t *player, mobj_t *source)
if (source && source->player && player != source->player) if (source && source->player && player != source->player)
{ {
P_AddPlayerScore(source->player, scoremultiply); P_AddPlayerScore(source->player, scoremultiply);
K_SpawnBattlePoints(source->player, player, scoremultiply);
source->player->kartstuff[k_wanted] -= wantedreduce; source->player->kartstuff[k_wanted] -= wantedreduce;
player->kartstuff[k_wanted] -= (wantedreduce/2); player->kartstuff[k_wanted] -= (wantedreduce/2);
} }
@ -1936,7 +1985,7 @@ void K_SquishPlayer(player_t *player, mobj_t *source)
K_CheckBumpers(); K_CheckBumpers();
} }
player->kartstuff[k_squishedtimer] = 2*TICRATE; player->kartstuff[k_squishedtimer] = TICRATE;
player->powers[pw_flashing] = K_GetKartFlashing(player); player->powers[pw_flashing] = K_GetKartFlashing(player);
@ -1992,6 +2041,7 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A b
if (source && source->player && player != source->player) if (source && source->player && player != source->player)
{ {
P_AddPlayerScore(source->player, scoremultiply); P_AddPlayerScore(source->player, scoremultiply);
K_SpawnBattlePoints(source->player, player, scoremultiply);
source->player->kartstuff[k_wanted] -= wantedreduce; source->player->kartstuff[k_wanted] -= wantedreduce;
player->kartstuff[k_wanted] -= (wantedreduce/2); player->kartstuff[k_wanted] -= (wantedreduce/2);
} }
@ -2032,7 +2082,7 @@ void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor) // A b
if (inflictor && inflictor->type == MT_SPBEXPLOSION && inflictor->extravalue1) if (inflictor && inflictor->type == MT_SPBEXPLOSION && inflictor->extravalue1)
{ {
player->kartstuff[k_spinouttimer] = (3*player->kartstuff[k_spinouttimer])/2; player->kartstuff[k_spinouttimer] = ((3*player->kartstuff[k_spinouttimer])/2)+1;
player->mo->momz *= 2; player->mo->momz *= 2;
} }
@ -3336,8 +3386,6 @@ void K_DropItems(player_t *player)
drop->destscale = (3*drop->destscale)/2;; drop->destscale = (3*drop->destscale)/2;;
drop->angle = player->mo->angle + ANGLE_90; drop->angle = player->mo->angle + ANGLE_90;
drop->momx = player->mo->momx>>1;
drop->momy = player->mo->momy>>1;
P_Thrust(drop, P_Thrust(drop,
FixedAngle(P_RandomFixed()*180) + player->mo->angle + ANGLE_90, FixedAngle(P_RandomFixed()*180) + player->mo->angle + ANGLE_90,
8*(mapheaderinfo[gamemap-1]->mobj_scale)); 8*(mapheaderinfo[gamemap-1]->mobj_scale));
@ -3628,7 +3676,7 @@ static void K_MoveHeldObjects(player_t *player)
#if 1 #if 1
{ {
angle_t input = player->mo->angle - cur->angle; angle_t input = player->frameangle - cur->angle;
boolean invert = (input > ANGLE_180); boolean invert = (input > ANGLE_180);
if (invert) if (invert)
input = InvAngle(input); input = InvAngle(input);
@ -3640,7 +3688,7 @@ static void K_MoveHeldObjects(player_t *player)
cur->angle = cur->angle + input; cur->angle = cur->angle + input;
} }
#else #else
cur->angle = player->mo->angle; cur->angle = player->frameangle;
#endif #endif
angoffset = ANGLE_90 + (ANGLE_180 * num); angoffset = ANGLE_90 + (ANGLE_180 * num);
@ -3877,9 +3925,15 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
fast->momx = 3*player->mo->momx/4; fast->momx = 3*player->mo->momx/4;
fast->momy = 3*player->mo->momy/4; fast->momy = 3*player->mo->momy/4;
fast->momz = 3*player->mo->momz/4; fast->momz = 3*player->mo->momz/4;
K_MatchGenericExtraFlags(fast, player->mo);
} }
if (player->kartstuff[k_eggmanexplode]) // You're gonna diiiiie if (player->playerstate == PST_DEAD || player->kartstuff[k_respawn] > 1) // Ensure these are set correctly here
{
player->mo->colorized = false;
player->mo->color = player->skincolor;
}
else if (player->kartstuff[k_eggmanexplode]) // You're gonna diiiiie
{ {
const INT32 flashtime = 4<<(player->kartstuff[k_eggmanexplode]/TICRATE); const INT32 flashtime = 4<<(player->kartstuff[k_eggmanexplode]/TICRATE);
if (player->kartstuff[k_eggmanexplode] == 1 || (player->kartstuff[k_eggmanexplode] % (flashtime/2) != 0)) if (player->kartstuff[k_eggmanexplode] == 1 || (player->kartstuff[k_eggmanexplode] % (flashtime/2) != 0))
@ -3956,6 +4010,18 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
player->kartstuff[k_timeovercam] = 0; player->kartstuff[k_timeovercam] = 0;
// Make ABSOLUTELY SURE that your flashing tics don't get set WHILE you're still in hit animations.
if (player->kartstuff[k_spinouttimer] != 0
|| player->kartstuff[k_wipeoutslow] != 0
|| player->kartstuff[k_squishedtimer] != 0)
{
player->powers[pw_flashing] = K_GetKartFlashing(player);
}
else if (player->powers[pw_flashing] == K_GetKartFlashing(player))
{
player->powers[pw_flashing]--;
}
if (player->kartstuff[k_spinouttimer]) if (player->kartstuff[k_spinouttimer])
{ {
if ((P_IsObjectOnGround(player->mo) || player->kartstuff[k_spinouttype] == 1) if ((P_IsObjectOnGround(player->mo) || player->kartstuff[k_spinouttype] == 1)
@ -3983,9 +4049,6 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
} }
} }
if (player->kartstuff[k_spinouttimer] == 0 && player->powers[pw_flashing] == K_GetKartFlashing(player))
player->powers[pw_flashing]--;
/*if (player->kartstuff[k_thunderanim]) /*if (player->kartstuff[k_thunderanim])
player->kartstuff[k_thunderanim]--;*/ player->kartstuff[k_thunderanim]--;*/
@ -4008,11 +4071,13 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
if (player->kartstuff[k_invincibilitytimer]) if (player->kartstuff[k_invincibilitytimer])
player->kartstuff[k_invincibilitytimer]--; player->kartstuff[k_invincibilitytimer]--;
if (!player->kartstuff[k_respawn])
{
if (player->kartstuff[k_growshrinktimer] > 0) if (player->kartstuff[k_growshrinktimer] > 0)
player->kartstuff[k_growshrinktimer]--; player->kartstuff[k_growshrinktimer]--;
if (player->kartstuff[k_growshrinktimer] < 0) if (player->kartstuff[k_growshrinktimer] < 0)
player->kartstuff[k_growshrinktimer]++; player->kartstuff[k_growshrinktimer]++;
}
if (player->kartstuff[k_growshrinktimer] == 1 || player->kartstuff[k_growshrinktimer] == -1) if (player->kartstuff[k_growshrinktimer] == 1 || player->kartstuff[k_growshrinktimer] == -1)
{ {
@ -4049,6 +4114,9 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
if (player->kartstuff[k_lapanimation]) if (player->kartstuff[k_lapanimation])
player->kartstuff[k_lapanimation]--; player->kartstuff[k_lapanimation]--;
if (player->kartstuff[k_yougotem])
player->kartstuff[k_yougotem]--;
if (G_BattleGametype() && (player->exiting || player->kartstuff[k_comebacktimer])) if (G_BattleGametype() && (player->exiting || player->kartstuff[k_comebacktimer]))
{ {
if (player->exiting) if (player->exiting)
@ -4436,7 +4504,8 @@ static void K_KartDrift(player_t *player, boolean onground)
if (player->kartstuff[k_spinouttimer] > 0 // banana peel if (player->kartstuff[k_spinouttimer] > 0 // banana peel
|| player->speed < FixedMul(10<<16, player->mo->scale)) // you're too slow! || player->speed < FixedMul(10<<16, player->mo->scale)) // you're too slow!
{ {
player->kartstuff[k_drift] = player->kartstuff[k_driftcharge] = player->kartstuff[k_aizdriftstrat] = 0; player->kartstuff[k_drift] = player->kartstuff[k_driftcharge] = 0;
player->kartstuff[k_aizdriftstrat] = player->kartstuff[k_brakedrift] = 0;
} }
if ((!player->kartstuff[k_sneakertimer]) if ((!player->kartstuff[k_sneakertimer])
@ -4450,6 +4519,18 @@ static void K_KartDrift(player_t *player, boolean onground)
} }
else if (player->kartstuff[k_aizdriftstrat] && !player->kartstuff[k_drift]) else if (player->kartstuff[k_aizdriftstrat] && !player->kartstuff[k_drift])
K_SpawnAIZDust(player); K_SpawnAIZDust(player);
if (player->kartstuff[k_drift]
&& ((player->cmd.buttons & BT_BRAKE)
|| !(player->cmd.buttons & BT_ACCELERATE))
&& P_IsObjectOnGround(player->mo))
{
if (!player->kartstuff[k_brakedrift])
K_SpawnBrakeDriftSparks(player);
player->kartstuff[k_brakedrift] = 1;
}
else
player->kartstuff[k_brakedrift] = 0;
} }
// //
// K_KartUpdatePosition // K_KartUpdatePosition
@ -4644,7 +4725,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
else if (cmd->buttons & BT_ATTACK) else if (cmd->buttons & BT_ATTACK)
player->pflags |= PF_ATTACKDOWN; player->pflags |= PF_ATTACKDOWN;
if (player && player->mo && player->mo->health > 0 && !player->spectator && !(player->exiting || mapreset) && player->kartstuff[k_spinouttimer] == 0) if (player && player->mo && player->mo->health > 0 && !player->spectator && !(player->exiting || mapreset)
&& player->kartstuff[k_spinouttimer] == 0 && player->kartstuff[k_squishedtimer] == 0 && player->kartstuff[k_respawn] == 0)
{ {
// First, the really specific, finicky items that function without the item being directly in your item slot. // First, the really specific, finicky items that function without the item being directly in your item slot.
// Karma item dropping // Karma item dropping
@ -5501,8 +5583,8 @@ static patch_t *kp_karmasticker;
static patch_t *kp_splitkarmabomb; static patch_t *kp_splitkarmabomb;
static patch_t *kp_timeoutsticker; static patch_t *kp_timeoutsticker;
static patch_t *kp_startcountdown[8]; static patch_t *kp_startcountdown[16];
static patch_t *kp_racefinish[2]; static patch_t *kp_racefinish[6];
static patch_t *kp_positionnum[NUMPOSNUMS][NUMPOSFRAMES]; static patch_t *kp_positionnum[NUMPOSNUMS][NUMPOSFRAMES];
static patch_t *kp_winnernum[NUMPOSFRAMES]; static patch_t *kp_winnernum[NUMPOSFRAMES];
@ -5559,6 +5641,9 @@ static patch_t *kp_lapanim_lap[7];
static patch_t *kp_lapanim_final[11]; static patch_t *kp_lapanim_final[11];
static patch_t *kp_lapanim_number[10][3]; static patch_t *kp_lapanim_number[10][3];
static patch_t *kp_lapanim_emblem; static patch_t *kp_lapanim_emblem;
static patch_t *kp_lapanim_hand[3];
static patch_t *kp_yougotem;
void K_LoadKartHUDGraphics(void) void K_LoadKartHUDGraphics(void)
{ {
@ -5589,9 +5674,25 @@ void K_LoadKartHUDGraphics(void)
kp_startcountdown[5] = W_CachePatchName("K_CNT2B", PU_HUDGFX); kp_startcountdown[5] = W_CachePatchName("K_CNT2B", PU_HUDGFX);
kp_startcountdown[6] = W_CachePatchName("K_CNT1B", PU_HUDGFX); kp_startcountdown[6] = W_CachePatchName("K_CNT1B", PU_HUDGFX);
kp_startcountdown[7] = W_CachePatchName("K_CNTGOB", PU_HUDGFX); kp_startcountdown[7] = W_CachePatchName("K_CNTGOB", PU_HUDGFX);
// Splitscreen
kp_startcountdown[8] = W_CachePatchName("K_SMC3A", PU_HUDGFX);
kp_startcountdown[9] = W_CachePatchName("K_SMC2A", PU_HUDGFX);
kp_startcountdown[10] = W_CachePatchName("K_SMC1A", PU_HUDGFX);
kp_startcountdown[11] = W_CachePatchName("K_SMCGOA", PU_HUDGFX);
kp_startcountdown[12] = W_CachePatchName("K_SMC3B", PU_HUDGFX);
kp_startcountdown[13] = W_CachePatchName("K_SMC2B", PU_HUDGFX);
kp_startcountdown[14] = W_CachePatchName("K_SMC1B", PU_HUDGFX);
kp_startcountdown[15] = W_CachePatchName("K_SMCGOB", PU_HUDGFX);
// Finish
kp_racefinish[0] = W_CachePatchName("K_FINA", PU_HUDGFX); kp_racefinish[0] = W_CachePatchName("K_FINA", PU_HUDGFX);
kp_racefinish[1] = W_CachePatchName("K_FINB", PU_HUDGFX); kp_racefinish[1] = W_CachePatchName("K_FINB", PU_HUDGFX);
// Splitscreen
kp_racefinish[2] = W_CachePatchName("K_SMFINA", PU_HUDGFX);
kp_racefinish[3] = W_CachePatchName("K_SMFINB", PU_HUDGFX);
// 2P splitscreen
kp_racefinish[4] = W_CachePatchName("K_2PFINA", PU_HUDGFX);
kp_racefinish[5] = W_CachePatchName("K_2PFINB", PU_HUDGFX);
// Position numbers // Position numbers
sprintf(buffer, "K_POSNxx"); sprintf(buffer, "K_POSNxx");
@ -5762,6 +5863,15 @@ void K_LoadKartHUDGraphics(void)
} }
kp_lapanim_emblem = (patch_t *) W_CachePatchName("K_LAPE00", PU_HUDGFX); kp_lapanim_emblem = (patch_t *) W_CachePatchName("K_LAPE00", PU_HUDGFX);
sprintf(buffer, "K_LAPH0x");
for (i = 0; i < 3; i++)
{
buffer[7] = '0'+(i+1);
kp_lapanim_hand[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX);
}
kp_yougotem = (patch_t *) W_CachePatchName("YOUGOTEM", PU_HUDGFX);
} }
// For the item toggle menu // For the item toggle menu
@ -6585,7 +6695,7 @@ static void K_drawKartWanted(void)
if (splitscreen) // Can't fit the poster on screen, sadly if (splitscreen) // Can't fit the poster on screen, sadly
{ {
if (K_IsPlayerWanted(stplyr) && leveltime % 10 > 3) if (K_IsPlayerWanted(stplyr) && leveltime % 10 > 3)
V_DrawRightAlignedString(WANT_X, WANT_Y, K_calcSplitFlags(V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS|V_REDMAP), "WANTED"); V_DrawRightAlignedString(WANT_X, WANT_Y, K_calcSplitFlags(V_SNAPTOBOTTOM|V_SNAPTORIGHT|V_HUDTRANS|V_ORANGEMAP), "WANTED");
return; return;
} }
@ -6924,10 +7034,9 @@ static void K_drawKartStartCountdown(void)
pnum++; pnum++;
if ((leveltime % (2*5)) / 5) // blink if ((leveltime % (2*5)) / 5) // blink
pnum += 4; pnum += 4;
if (splitscreen) // splitscreen
pnum += 8;
if (splitscreen)
V_DrawSmallScaledPatch(STCD_X - (SHORT(kp_startcountdown[pnum]->width)/4), STCD_Y - (SHORT(kp_startcountdown[pnum]->height)/4), splitflags, kp_startcountdown[pnum]);
else
V_DrawScaledPatch(STCD_X - (SHORT(kp_startcountdown[pnum]->width)/2), STCD_Y - (SHORT(kp_startcountdown[pnum]->height)/2), splitflags, kp_startcountdown[pnum]); V_DrawScaledPatch(STCD_X - (SHORT(kp_startcountdown[pnum]->width)/2), STCD_Y - (SHORT(kp_startcountdown[pnum]->height)/2), splitflags, kp_startcountdown[pnum]);
} }
@ -6941,12 +7050,14 @@ static void K_drawKartFinish(void)
if ((stplyr->kartstuff[k_cardanimation] % (2*5)) / 5) // blink if ((stplyr->kartstuff[k_cardanimation] % (2*5)) / 5) // blink
pnum = 1; pnum = 1;
if (splitscreen > 1) if (splitscreen > 1) // small splitscreen
{ pnum += 2;
V_DrawTinyScaledPatch(STCD_X - (SHORT(kp_racefinish[pnum]->width)/8), STCD_Y - (SHORT(kp_racefinish[pnum]->height)/8), splitflags, kp_racefinish[pnum]); else if (splitscreen == 1) // wide splitscreen
return; pnum += 4;
}
if (splitscreen > 1) // Stationary FIN
V_DrawScaledPatch(STCD_X - (SHORT(kp_racefinish[pnum]->width)/2), STCD_Y - (SHORT(kp_racefinish[pnum]->height)/2), splitflags, kp_racefinish[pnum]);
else // Scrolling FINISH
{ {
INT32 scaleshift = (FRACBITS - splitscreen); // FRACUNIT or FRACUNIT/2 INT32 scaleshift = (FRACBITS - splitscreen); // FRACUNIT or FRACUNIT/2
INT32 x = ((vid.width<<FRACBITS)/vid.dupx), xval = (SHORT(kp_racefinish[pnum]->width)<<scaleshift); INT32 x = ((vid.width<<FRACBITS)/vid.dupx), xval = (SHORT(kp_racefinish[pnum]->width)<<scaleshift);
@ -7013,7 +7124,7 @@ static void K_drawBattleFullscreen(void)
{ {
if (stplyr->kartstuff[k_position] == 1) if (stplyr->kartstuff[k_position] == 1)
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, splitflags, kp_battlewin, NULL); V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, splitflags, kp_battlewin, NULL);
else if (splitscreen < 2) else
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, splitflags, (K_IsPlayerLosing(stplyr) ? kp_battlelose : kp_battlecool), NULL); V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, scale, splitflags, (K_IsPlayerLosing(stplyr) ? kp_battlelose : kp_battlecool), NULL);
} }
else else
@ -7341,41 +7452,57 @@ static void K_drawLapStartAnim(void)
{ {
// This is an EVEN MORE insanely complicated animation. // This is an EVEN MORE insanely complicated animation.
const UINT8 progress = 80-stplyr->kartstuff[k_lapanimation]; const UINT8 progress = 80-stplyr->kartstuff[k_lapanimation];
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, stplyr->skincolor, 0);
V_DrawScaledPatch(BASEVIDWIDTH/2 + (32*max(0, stplyr->kartstuff[k_lapanimation]-76)), V_DrawFixedPatch((BASEVIDWIDTH/2 + (32*max(0, stplyr->kartstuff[k_lapanimation]-76)))*FRACUNIT,
64 - (32*max(0, progress-76)), (48 - (32*max(0, progress-76)))*FRACUNIT,
0, kp_lapanim_emblem); FRACUNIT, V_HUDTRANS,
kp_lapanim_emblem, colormap);
if (stplyr->kartstuff[k_laphand] >= 1 && stplyr->kartstuff[k_laphand] <= 3)
{
V_DrawFixedPatch((BASEVIDWIDTH/2 + (32*max(0, stplyr->kartstuff[k_lapanimation]-76)))*FRACUNIT,
(48 - (32*max(0, progress-76))
+ 4 - abs((leveltime % 8) - 4))*FRACUNIT,
FRACUNIT, V_HUDTRANS,
kp_lapanim_hand[stplyr->kartstuff[k_laphand]-1], NULL);
}
if (stplyr->laps == (UINT8)(cv_numlaps.value - 1)) if (stplyr->laps == (UINT8)(cv_numlaps.value - 1))
{ {
V_DrawScaledPatch(27 - (32*max(0, progress-76)), V_DrawFixedPatch((62 - (32*max(0, progress-76)))*FRACUNIT, // 27
40, (-6)*FRACUNIT, // 24
0, kp_lapanim_final[min(progress/2, 10)]); FRACUNIT, V_HUDTRANS,
kp_lapanim_final[min(progress/2, 10)], NULL);
if (progress/2-12 >= 0) if (progress/2-12 >= 0)
{ {
V_DrawScaledPatch(194 + (32*max(0, progress-76)), V_DrawFixedPatch((188 + (32*max(0, progress-76)))*FRACUNIT, // 194
40, (-6)*FRACUNIT, // 24
0, kp_lapanim_lap[min(progress/2-12, 6)]); FRACUNIT, V_HUDTRANS,
kp_lapanim_lap[min(progress/2-12, 6)], NULL);
} }
} }
else else
{ {
V_DrawScaledPatch(61 - (32*max(0, progress-76)), V_DrawFixedPatch((82 - (32*max(0, progress-76)))*FRACUNIT, // 61
40, (-6)*FRACUNIT, // 24
0, kp_lapanim_lap[min(progress/2, 6)]); FRACUNIT, V_HUDTRANS,
kp_lapanim_lap[min(progress/2, 6)], NULL);
if (progress/2-8 >= 0) if (progress/2-8 >= 0)
{ {
V_DrawScaledPatch(194 + (32*max(0, progress-76)), V_DrawFixedPatch((188 + (32*max(0, progress-76)))*FRACUNIT, // 194
40, (-6)*FRACUNIT, // 24
0, kp_lapanim_number[(((UINT32)stplyr->laps+1) / 10)][min(progress/2-8, 2)]); FRACUNIT, V_HUDTRANS,
kp_lapanim_number[(((UINT32)stplyr->laps+1) / 10)][min(progress/2-8, 2)], NULL);
if (progress/2-10 >= 0) if (progress/2-10 >= 0)
{ {
V_DrawScaledPatch(221 + (32*max(0, progress-76)), V_DrawFixedPatch((208 + (32*max(0, progress-76)))*FRACUNIT, // 221
40, (-6)*FRACUNIT, // 24
0, kp_lapanim_number[(((UINT32)stplyr->laps+1) % 10)][min(progress/2-10, 2)]); FRACUNIT, V_HUDTRANS,
kp_lapanim_number[(((UINT32)stplyr->laps+1) % 10)][min(progress/2-10, 2)], NULL);
} }
} }
} }
@ -7509,15 +7636,6 @@ void K_drawKartHUD(void)
|| ((splitscreen > 2 && stplyr == &players[fourthdisplayplayer]) && !camera4.chase)) || ((splitscreen > 2 && stplyr == &players[fourthdisplayplayer]) && !camera4.chase))
K_drawKartFirstPerson(); K_drawKartFirstPerson();
// Draw a white fade on level opening
if (leveltime < 15 && stplyr == &players[displayplayer])
{
if (leveltime <= 5)
V_DrawFill(0,0,BASEVIDWIDTH,BASEVIDHEIGHT,120); // Pure white on first few frames, to hide SRB2's awful level load artifacts
else
V_DrawFadeScreen(120, 15-leveltime); // Then gradually fade out from there
}
if (splitscreen == 2) // Player 4 in 3P is the minimap :p if (splitscreen == 2) // Player 4 in 3P is the minimap :p
K_drawKartMinimap(); K_drawKartMinimap();
@ -7626,6 +7744,9 @@ void K_drawKartHUD(void)
K_drawLapStartAnim(); K_drawLapStartAnim();
} }
if (G_BattleGametype() && !splitscreen && (stplyr->kartstuff[k_yougotem] % 2)) // * YOU GOT EM *
V_DrawScaledPatch(BASEVIDWIDTH/2 - (SHORT(kp_yougotem->width)/2), 32, V_HUDTRANS, kp_yougotem);
// Draw FREE PLAY. // Draw FREE PLAY.
if (isfreeplay && !stplyr->spectator && timeinmap > 113) if (isfreeplay && !stplyr->spectator && timeinmap > 113)
K_drawKartFreePlay(leveltime); K_drawKartFreePlay(leveltime);

View file

@ -27,6 +27,7 @@ void K_KartMoveAnimation(player_t *player);
void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); void K_KartPlayerThink(player_t *player, ticcmd_t *cmd);
void K_KartPlayerAfterThink(player_t *player); void K_KartPlayerAfterThink(player_t *player);
void K_DoInstashield(player_t *player); void K_DoInstashield(player_t *player);
void K_SpawnBattlePoints(player_t *source, player_t *victim, UINT8 amount);
void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem); void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, boolean trapitem);
void K_SquishPlayer(player_t *player, mobj_t *source); void K_SquishPlayer(player_t *player, mobj_t *source);
void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor); void K_ExplodePlayer(player_t *player, mobj_t *source, mobj_t *inflictor);

View file

@ -2109,6 +2109,20 @@ static int lib_kDoInstashield(lua_State *L)
return 0; return 0;
} }
static int lib_kSpawnBattlePoints(lua_State *L)
{
player_t *source = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
player_t *victim = *((player_t **)luaL_checkudata(L, 2, META_PLAYER));
UINT8 amount = (UINT8)luaL_checkinteger(L, 3);
NOHUD
if (!source)
return LUA_ErrInvalid(L, "player_t");
if (!victim)
return LUA_ErrInvalid(L, "player_t");
K_SpawnBattlePoints(source, victim, amount);
return 0;
}
static int lib_kSpinPlayer(lua_State *L) static int lib_kSpinPlayer(lua_State *L)
{ {
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@ -2500,6 +2514,7 @@ static luaL_Reg lib[] = {
{"K_KartBouncing",lib_kKartBouncing}, {"K_KartBouncing",lib_kKartBouncing},
{"K_MatchGenericExtraFlags",lib_kMatchGenericExtraFlags}, {"K_MatchGenericExtraFlags",lib_kMatchGenericExtraFlags},
{"K_DoInstashield",lib_kDoInstashield}, {"K_DoInstashield",lib_kDoInstashield},
{"K_SpawnBattlePoints",lib_kSpawnBattlePoints},
{"K_SpinPlayer",lib_kSpinPlayer}, {"K_SpinPlayer",lib_kSpinPlayer},
{"K_SquishPlayer",lib_kSquishPlayer}, {"K_SquishPlayer",lib_kSquishPlayer},
{"K_ExplodePlayer",lib_kExplodePlayer}, {"K_ExplodePlayer",lib_kExplodePlayer},

View file

@ -1241,7 +1241,8 @@ static menuitem_t OP_VideoOptionsMenu[] =
{IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 90}, {IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 90},
#ifdef HWRENDER #ifdef HWRENDER
{IT_SUBMENU|IT_STRING, NULL, "OpenGL Options...", &OP_OpenGLOptionsDef, 105}, {IT_STRING | IT_CVAR, NULL, "3D models", &cv_grmd2, 105},
{IT_SUBMENU|IT_STRING, NULL, "OpenGL Options...", &OP_OpenGLOptionsDef, 115},
#endif #endif
}; };
@ -1271,18 +1272,19 @@ static menuitem_t OP_VideoModeMenu[] =
#ifdef HWRENDER #ifdef HWRENDER
static menuitem_t OP_OpenGLOptionsMenu[] = static menuitem_t OP_OpenGLOptionsMenu[] =
{ {
{IT_STRING|IT_CVAR, NULL, "Field of View", &cv_grfov, 10}, {IT_SUBMENU|IT_STRING, NULL, "Fog...", &OP_OpenGLFogDef, 10},
{IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 20}, {IT_SUBMENU|IT_STRING, NULL, "Gamma...", &OP_OpenGLColorDef, 20},
{IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 30},
{IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode,40}, {IT_STRING|IT_CVAR, NULL, "Field of View", &cv_grfov, 35},
#ifdef _WINDOWS {IT_STRING|IT_CVAR, NULL, "Quality", &cv_scr_depth, 45},
{IT_STRING|IT_CVAR, NULL, "Texture Filter", &cv_grfiltermode, 55},
{IT_STRING|IT_CVAR, NULL, "Anisotropic", &cv_granisotropicmode, 65},
/*#ifdef _WINDOWS
{IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 50}, {IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 50},
#endif #endif
#ifdef ALAM_LIGHTING #ifdef ALAM_LIGHTING
{IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 70}, {IT_SUBMENU|IT_STRING, NULL, "Lighting...", &OP_OpenGLLightingDef, 70},
#endif #endif*/
{IT_SUBMENU|IT_STRING, NULL, "Fog...", &OP_OpenGLFogDef, 80},
{IT_SUBMENU|IT_STRING, NULL, "Gamma...", &OP_OpenGLColorDef, 90},
}; };
#ifdef ALAM_LIGHTING #ifdef ALAM_LIGHTING
@ -7819,6 +7821,8 @@ static void M_ConnectIP(INT32 choice)
return; return;
} }
M_ClearMenus(true);
COM_BufAddText(va("connect \"%s\"\n", setupm_ip)); COM_BufAddText(va("connect \"%s\"\n", setupm_ip));
// A little "please wait" message. // A little "please wait" message.
@ -7850,7 +7854,6 @@ static void M_HandleConnectIP(INT32 choice)
case KEY_ENTER: case KEY_ENTER:
S_StartSound(NULL,sfx_menu1); // Tails S_StartSound(NULL,sfx_menu1); // Tails
M_ClearMenus(true);
M_ConnectIP(1); M_ConnectIP(1);
break; break;

View file

@ -8435,6 +8435,7 @@ void A_SPBChase(mobj_t *actor)
//fast->momz = 3*actor->momz/4; //fast->momz = 3*actor->momz/4;
fast->color = SKINCOLOR_RED; fast->color = SKINCOLOR_RED;
fast->colorized = true; fast->colorized = true;
K_MatchGenericExtraFlags(fast, actor);
} }
return; return;

View file

@ -494,6 +494,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
else else
{ {
mobj_t *boom = P_SpawnMobj(special->target->x, special->target->y, special->target->z, MT_BOOMEXPLODE); mobj_t *boom = P_SpawnMobj(special->target->x, special->target->y, special->target->z, MT_BOOMEXPLODE);
UINT8 ptadd = (K_IsPlayerWanted(player) ? 2 : 1);
boom->scale = special->target->scale; boom->scale = special->target->scale;
boom->destscale = special->target->scale; boom->destscale = special->target->scale;
boom->momz = 5*FRACUNIT; boom->momz = 5*FRACUNIT;
@ -516,12 +518,17 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
} }
if (numingame <= 2) // If so, then an extra karma point so they are 100% certain to switch places; it's annoying to end matches with a bomb kill if (numingame <= 2) // If so, then an extra karma point so they are 100% certain to switch places; it's annoying to end matches with a bomb kill
special->target->player->kartstuff[k_comebackpoints]++; ptadd++;
} }
special->target->player->kartstuff[k_comebackpoints] += (K_IsPlayerWanted(player) ? 2 : 1); special->target->player->kartstuff[k_comebackpoints] += ptadd;
if (ptadd > 1)
special->target->player->kartstuff[k_yougotem] = 2*TICRATE;
if (special->target->player->kartstuff[k_comebackpoints] >= 2) if (special->target->player->kartstuff[k_comebackpoints] >= 2)
K_StealBumper(special->target->player, player, true); K_StealBumper(special->target->player, player, true);
special->target->player->kartstuff[k_comebacktimer] = comebacktime; special->target->player->kartstuff[k_comebacktimer] = comebacktime;
K_ExplodePlayer(player, special->target, special); K_ExplodePlayer(player, special->target, special);
@ -545,6 +552,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
else if (special->target->player->kartstuff[k_comebackmode] == 2 && P_CanPickupItem(player, 2)) else if (special->target->player->kartstuff[k_comebackmode] == 2 && P_CanPickupItem(player, 2))
{ {
mobj_t *poof = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE); mobj_t *poof = P_SpawnMobj(special->x, special->y, special->z, MT_EXPLODE);
UINT8 ptadd = 1; // No WANTED bonus for tricking
S_StartSound(poof, special->info->seesound); S_StartSound(poof, special->info->seesound);
if (player->kartstuff[k_bumper] == 1) // If you have only one bumper left, and see if it's a 1v1 if (player->kartstuff[k_bumper] == 1) // If you have only one bumper left, and see if it's a 1v1
@ -560,14 +569,18 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
} }
if (numingame <= 2) // If so, then an extra karma point so they are 100% certain to switch places; it's annoying to end matches with a fake kill if (numingame <= 2) // If so, then an extra karma point so they are 100% certain to switch places; it's annoying to end matches with a fake kill
special->target->player->kartstuff[k_comebackpoints]++; ptadd++;
} }
special->target->player->kartstuff[k_comebackmode] = 0; special->target->player->kartstuff[k_comebackmode] = 0;
special->target->player->kartstuff[k_comebackpoints]++; special->target->player->kartstuff[k_comebackpoints] += ptadd;
if (ptadd > 1)
special->target->player->kartstuff[k_yougotem] = 2*TICRATE;
if (special->target->player->kartstuff[k_comebackpoints] >= 2) if (special->target->player->kartstuff[k_comebackpoints] >= 2)
K_StealBumper(special->target->player, player, true); K_StealBumper(special->target->player, player, true);
special->target->player->kartstuff[k_comebacktimer] = comebacktime; special->target->player->kartstuff[k_comebacktimer] = comebacktime;
K_DropItems(player); //K_StripItems(player); K_DropItems(player); //K_StripItems(player);

View file

@ -665,8 +665,33 @@ static boolean PIT_CheckThing(mobj_t *thing)
// SRB2kart 011617 - Colission code for kart items //{ // SRB2kart 011617 - Colission code for kart items //{
// Push fakes out of other items
if (tmthing->type == MT_FAKEITEM && (thing->type == MT_RANDOMITEM || thing->type == MT_FAKEITEM))
{
// see if it went over / under
if (tmthing->z > thing->z + thing->height)
return true; // overhead
if (tmthing->z + tmthing->height < thing->z)
return true; // underneath
P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y), thing->radius/4);
return true;
}
else if (thing->type == MT_FAKEITEM && (tmthing->type == MT_RANDOMITEM || tmthing->type == MT_FAKEITEM))
{
// see if it went over / under
if (tmthing->z > thing->z + thing->height)
return true; // overhead
if (tmthing->z + tmthing->height < thing->z)
return true; // underneath
P_InstaThrust(thing, R_PointToAngle2(tmthing->x, tmthing->y, thing->x, thing->y), tmthing->radius/4);
return true;
}
if (tmthing->type == MT_RANDOMITEM) if (tmthing->type == MT_RANDOMITEM)
return true; return true;
if (tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ || tmthing->type == MT_JAWZ_DUD if (tmthing->type == MT_ORBINAUT || tmthing->type == MT_JAWZ || tmthing->type == MT_JAWZ_DUD
|| tmthing->type == MT_ORBINAUT_SHIELD || tmthing->type == MT_JAWZ_SHIELD) || tmthing->type == MT_ORBINAUT_SHIELD || tmthing->type == MT_JAWZ_SHIELD)
{ {
@ -1386,19 +1411,17 @@ static boolean PIT_CheckThing(mobj_t *thing)
// Make sure they aren't able to damage you ANYWHERE along the Z axis, you have to be TOUCHING the person. // Make sure they aren't able to damage you ANYWHERE along the Z axis, you have to be TOUCHING the person.
&& !(thing->z + thing->height < tmthing->z || thing->z > tmthing->z + tmthing->height)) && !(thing->z + thing->height < tmthing->z || thing->z > tmthing->z + tmthing->height))
{ {
// SRB2kart - Squish!
if (tmthing->scale > thing->scale + (FRACUNIT/8)) if (tmthing->scale > thing->scale + (FRACUNIT/8)) // SRB2kart - Handle squishes first!
K_SquishPlayer(thing->player, tmthing); K_SquishPlayer(thing->player, tmthing);
else if (thing->scale > tmthing->scale + (FRACUNIT/8)) else if (thing->scale > tmthing->scale + (FRACUNIT/8))
K_SquishPlayer(tmthing->player, thing); K_SquishPlayer(tmthing->player, thing);
else if (tmthing->player->kartstuff[k_invincibilitytimer] && !thing->player->kartstuff[k_invincibilitytimer]) // SRB2kart - Then invincibility!
// SRB2kart - Invincibility!
if (tmthing->player->kartstuff[k_invincibilitytimer] && !thing->player->kartstuff[k_invincibilitytimer])
P_DamageMobj(thing, tmthing, tmthing, 1); P_DamageMobj(thing, tmthing, tmthing, 1);
else if (thing->player->kartstuff[k_invincibilitytimer] && !tmthing->player->kartstuff[k_invincibilitytimer]) else if (thing->player->kartstuff[k_invincibilitytimer] && !tmthing->player->kartstuff[k_invincibilitytimer])
P_DamageMobj(tmthing, thing, thing, 1); P_DamageMobj(tmthing, thing, thing, 1);
if (G_BattleGametype() && (!G_GametypeHasTeams() || tmthing->player->ctfteam != thing->player->ctfteam)) /*if (G_BattleGametype() && (!G_GametypeHasTeams() || tmthing->player->ctfteam != thing->player->ctfteam))
{ {
if ((tmthing->player->powers[pw_invulnerability] || tmthing->player->powers[pw_super]) if ((tmthing->player->powers[pw_invulnerability] || tmthing->player->powers[pw_super])
&& !thing->player->powers[pw_super]) && !thing->player->powers[pw_super])
@ -1416,7 +1439,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
P_DamageMobj(thing, tmthing, tmthing, 1); P_DamageMobj(thing, tmthing, tmthing, 1);
else if ((thing->player->pflags & PF_TAGIT) && !(tmthing->player->pflags & PF_TAGIT)) else if ((thing->player->pflags & PF_TAGIT) && !(tmthing->player->pflags & PF_TAGIT))
P_DamageMobj(tmthing, thing, tmthing, 1); P_DamageMobj(tmthing, thing, tmthing, 1);
} }*/
} }
// Force solid players in hide and seek to avoid corner stacking. // Force solid players in hide and seek to avoid corner stacking.
@ -3784,6 +3807,7 @@ void P_BouncePlayerMove(mobj_t *mo)
S_StartSound(mo, sfx_s3k49); S_StartSound(mo, sfx_s3k49);
} }
mo->player->kartstuff[k_pogospring] = 0; // Cancel pogo spring effect so you aren't shoved forward back into the wall you just bounced off
P_PlayerHitBounceLine(bestslideline); P_PlayerHitBounceLine(bestslideline);
mo->eflags |= MFE_JUSTBOUNCEDWALL; mo->eflags |= MFE_JUSTBOUNCEDWALL;

View file

@ -6803,7 +6803,7 @@ void P_MobjThinker(mobj_t *mobj)
&& mobj->target->player->health && mobj->target->player->playerstate != PST_DEAD && mobj->target->player->health && mobj->target->player->playerstate != PST_DEAD
/*&& players[displayplayer].mo && !players[displayplayer].spectator*/) /*&& players[displayplayer].mo && !players[displayplayer].spectator*/)
{ {
fixed_t scale = mobj->target->scale; fixed_t scale = 4*mobj->target->scale;
mobj->color = mobj->target->color; mobj->color = mobj->target->color;
K_MatchGenericExtraFlags(mobj, mobj->target); K_MatchGenericExtraFlags(mobj, mobj->target);
@ -6834,10 +6834,10 @@ void P_MobjThinker(mobj_t *mobj)
if (!splitscreen) if (!splitscreen)
{ {
scale += FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayer].mo->x-mobj->target->x, scale = mobj->target->scale + FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayer].mo->x-mobj->target->x,
players[displayplayer].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale); players[displayplayer].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale);
if (scale > 16*FRACUNIT) if (scale > 16*mobj->target->scale)
scale = 16*FRACUNIT; scale = 16*mobj->target->scale;
} }
mobj->destscale = scale; mobj->destscale = scale;
@ -6998,7 +6998,7 @@ void P_MobjThinker(mobj_t *mobj)
&& mobj->target->player->health && mobj->target->player->playerstate != PST_DEAD && mobj->target->player->health && mobj->target->player->playerstate != PST_DEAD
&& players[displayplayer].mo && !players[displayplayer].spectator) && players[displayplayer].mo && !players[displayplayer].spectator)
{ {
fixed_t scale = mobj->target->scale; fixed_t scale = 4*mobj->target->scale;
if (!K_IsPlayerWanted(mobj->target->player)) if (!K_IsPlayerWanted(mobj->target->player))
{ {
@ -7028,10 +7028,13 @@ void P_MobjThinker(mobj_t *mobj)
} }
P_SetThingPosition(mobj); P_SetThingPosition(mobj);
scale += FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayer].mo->x-mobj->target->x, if (!splitscreen)
{
scale = mobj->target->scale + FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayer].mo->x-mobj->target->x,
players[displayplayer].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale); players[displayplayer].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale);
if (scale > 16*FRACUNIT) if (scale > 16*mobj->target->scale)
scale = 16*FRACUNIT; scale = 16*mobj->target->scale;
}
mobj->destscale = scale; mobj->destscale = scale;
} }
else if (mobj->health > 0) else if (mobj->health > 0)
@ -8153,6 +8156,7 @@ void P_MobjThinker(mobj_t *mobj)
} }
case MT_BANANA: case MT_BANANA:
case MT_FAKEITEM: case MT_FAKEITEM:
mobj->friction = ORIG_FRICTION/4;
if (mobj->momx || mobj->momy) if (mobj->momx || mobj->momy)
P_SpawnGhostMobj(mobj); P_SpawnGhostMobj(mobj);
if (mobj->z <= mobj->floorz && mobj->health > 1) if (mobj->z <= mobj->floorz && mobj->health > 1)
@ -8303,6 +8307,43 @@ void P_MobjThinker(mobj_t *mobj)
} }
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z); P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
break; break;
case MT_BRAKEDRIFT:
if ((!mobj->target || !mobj->target->health || !mobj->target->player || !P_IsObjectOnGround(mobj->target))
|| !mobj->target->player->kartstuff[k_drift] || !mobj->target->player->kartstuff[k_brakedrift]
|| !((mobj->target->player->cmd.buttons & BT_BRAKE)
|| !(mobj->target->player->cmd.buttons & BT_ACCELERATE))) // Letting go of accel functions about the same as brake-drifting
{
P_RemoveMobj(mobj);
return;
}
else
{
fixed_t newx, newy;
angle_t travelangle;
travelangle = mobj->target->angle - ((ANGLE_45/5)*mobj->target->player->kartstuff[k_drift]);
newx = mobj->target->x + P_ReturnThrustX(mobj->target, travelangle+ANGLE_180, 24*mobj->target->scale);
newy = mobj->target->y + P_ReturnThrustY(mobj->target, travelangle+ANGLE_180, 24*mobj->target->scale);
P_TeleportMove(mobj, newx, newy, mobj->target->z);
mobj->angle = travelangle - ((ANGLE_90/5)*mobj->target->player->kartstuff[k_drift]);
P_SetScale(mobj, (mobj->destscale = mobj->target->scale));
if (mobj->target->player->kartstuff[k_driftcharge] >= K_GetKartDriftSparkValue(mobj->target->player)*4)
mobj->color = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1)));
else if (mobj->target->player->kartstuff[k_driftcharge] >= K_GetKartDriftSparkValue(mobj->target->player)*2)
mobj->color = SKINCOLOR_KETCHUP;
else if (mobj->target->player->kartstuff[k_driftcharge] >= K_GetKartDriftSparkValue(mobj->target->player))
mobj->color = SKINCOLOR_SAPPHIRE;
else
mobj->color = SKINCOLOR_WHITE;
K_MatchGenericExtraFlags(mobj, mobj->target);
if (leveltime & 1)
mobj->flags2 |= MF2_DONTDRAW;
}
break;
case MT_PLAYERRETICULE: case MT_PLAYERRETICULE:
if (!mobj->target || !mobj->target->health) if (!mobj->target || !mobj->target->health)
{ {
@ -8312,10 +8353,7 @@ void P_MobjThinker(mobj_t *mobj)
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z); P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
break; break;
case MT_INSTASHIELDB: case MT_INSTASHIELDB:
if (leveltime & 1) mobj->flags2 ^= MF2_DONTDRAW;
mobj->flags2 |= MF2_DONTDRAW;
else
mobj->flags2 &= ~MF2_DONTDRAW;
/* FALLTHRU */ /* FALLTHRU */
case MT_INSTASHIELDA: case MT_INSTASHIELDA:
if (!mobj->target || !mobj->target->health || (mobj->target->player && !mobj->target->player->kartstuff[k_instashield])) if (!mobj->target || !mobj->target->health || (mobj->target->player && !mobj->target->player->kartstuff[k_instashield]))
@ -8325,6 +8363,28 @@ void P_MobjThinker(mobj_t *mobj)
} }
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z); P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z);
break; break;
case MT_BATTLEPOINT:
if (!mobj->target || P_MobjWasRemoved(mobj->target))
{
P_RemoveMobj(mobj);
return;
}
if (mobj->movefactor < 48*mobj->target->scale)
{
mobj->movefactor += (48*mobj->target->scale)/6;
if (mobj->movefactor > mobj->target->height)
mobj->movefactor = mobj->target->height;
}
else if (mobj->movefactor > 48*mobj->target->scale)
{
mobj->movefactor -= (48*mobj->target->scale)/6;
if (mobj->movefactor < mobj->target->height)
mobj->movefactor = mobj->target->height;
}
P_TeleportMove(mobj, mobj->target->x, mobj->target->y, mobj->target->z + (mobj->target->height/2) + mobj->movefactor);
break;
case MT_THUNDERSHIELD: case MT_THUNDERSHIELD:
{ {
fixed_t destx, desty; fixed_t destx, desty;
@ -8511,8 +8571,8 @@ void P_MobjThinker(mobj_t *mobj)
case MT_FZEROBOOM: // F-Zero explosion case MT_FZEROBOOM: // F-Zero explosion
if (!mobj->extravalue1) if (!mobj->extravalue1)
{ {
fixed_t mx = P_ReturnThrustX(NULL, mobj->angle, 32<<FRACBITS); fixed_t mx = P_ReturnThrustX(NULL, mobj->angle, 32*mobj->scale);
fixed_t my = P_ReturnThrustY(NULL, mobj->angle, 32<<FRACBITS); fixed_t my = P_ReturnThrustY(NULL, mobj->angle, 32*mobj->scale);
mobj_t *explosion = P_SpawnMobj(mobj->x + (2*mx), mobj->y + (2*my), mobj->z+(mobj->height/2), MT_THOK); mobj_t *explosion = P_SpawnMobj(mobj->x + (2*mx), mobj->y + (2*my), mobj->z+(mobj->height/2), MT_THOK);
P_SetMobjState(explosion, S_FZEROBOOM1); P_SetMobjState(explosion, S_FZEROBOOM1);

View file

@ -3219,7 +3219,7 @@ void P_SetupSignExit(player_t *player)
// SRB2Kart: Set sign spinning variables // SRB2Kart: Set sign spinning variables
thing->movefactor = thing->z; thing->movefactor = thing->z;
thing->z += (768<<FRACBITS) * P_MobjFlip(thing); thing->z += (768*thing->scale) * P_MobjFlip(thing);
thing->movecount = 1; thing->movecount = 1;
++numfound; ++numfound;
@ -3247,7 +3247,7 @@ void P_SetupSignExit(player_t *player)
// SRB2Kart: Set sign spinning variables // SRB2Kart: Set sign spinning variables
thing->movefactor = thing->z; thing->movefactor = thing->z;
thing->z += (768<<FRACBITS) * P_MobjFlip(thing); thing->z += (768*thing->scale) * P_MobjFlip(thing);
thing->movecount = 1; thing->movecount = 1;
++numfound; ++numfound;
@ -3259,7 +3259,7 @@ void P_SetupSignExit(player_t *player)
// SRB2Kart: FINALLY, add in an alternative if no place is found // SRB2Kart: FINALLY, add in an alternative if no place is found
if (player->mo) if (player->mo)
{ {
mobj_t *sign = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + (768<<FRACBITS), MT_SIGN); mobj_t *sign = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + (768*mapheaderinfo[gamemap-1]->mobj_scale), MT_SIGN);
P_SetTarget(&sign->target, player->mo); P_SetTarget(&sign->target, player->mo);
P_SetMobjState(sign, S_SIGN1); P_SetMobjState(sign, S_SIGN1);
@ -4196,7 +4196,34 @@ DoneSection2:
{ {
if (player->starpostcount >= numstarposts/2) // srb2kart: must have touched *enough* starposts (was originally "(player->starpostnum == numstarposts)") if (player->starpostcount >= numstarposts/2) // srb2kart: must have touched *enough* starposts (was originally "(player->starpostnum == numstarposts)")
{ {
UINT8 i;
UINT8 nump = 0;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
continue;
nump++;
}
player->laps++; player->laps++;
// Set up lap animation vars
if (nump > 1)
{
if (K_IsPlayerLosing(player))
player->kartstuff[k_laphand] = 3;
else
{
if (nump > 2 && player->kartstuff[k_position] == 1) // 1st place in 1v1 uses thumbs up
player->kartstuff[k_laphand] = 1;
else
player->kartstuff[k_laphand] = 2;
}
}
else
player->kartstuff[k_laphand] = 0; // No hands in FREE PLAY
player->kartstuff[k_lapanimation] = 80; player->kartstuff[k_lapanimation] = 80;
if (player->pflags & PF_NIGHTSMODE) if (player->pflags & PF_NIGHTSMODE)
@ -4237,15 +4264,7 @@ DoneSection2:
// Figure out how many are playing on the last lap, to prevent spectate griefing // Figure out how many are playing on the last lap, to prevent spectate griefing
if (!nospectategrief && player->laps >= (UINT8)(cv_numlaps.value - 1)) if (!nospectategrief && player->laps >= (UINT8)(cv_numlaps.value - 1))
{ nospectategrief = nump;
UINT8 i;
for (i = 0; i < MAXPLAYERS; i++)
{
if (!playeringame[i] || players[i].spectator)
continue;
nospectategrief++;
}
}
} }
else if (player->starpostnum) else if (player->starpostnum)
{ {

View file

@ -1217,6 +1217,8 @@ void P_RestoreMusic(player_t *player)
if (!P_IsLocalPlayer(player)) // Only applies to a local player if (!P_IsLocalPlayer(player)) // Only applies to a local player
return; return;
S_SpeedMusic(1.0f);
// Event - HERE COMES A NEW CHALLENGER // Event - HERE COMES A NEW CHALLENGER
if (mapreset) if (mapreset)
{ {
@ -1228,24 +1230,58 @@ void P_RestoreMusic(player_t *player)
if (P_EndingMusic(player)) if (P_EndingMusic(player))
return; return;
S_SpeedMusic(1.0f);
// Event - Level Start // Event - Level Start
if (leveltime < (starttime + (TICRATE/2))) if (leveltime < (starttime + (TICRATE/2)))
S_ChangeMusicInternal((encoremode ? "estart" : "kstart"), false); //S_StopMusic(); S_ChangeMusicInternal((encoremode ? "estart" : "kstart"), false); //S_StopMusic();
else // see also where time overs are handled - search for "lives = 2" in this file else // see also where time overs are handled - search for "lives = 2" in this file
{ {
INT32 wantedmus = 0; // 0 is level music, 1 is invincibility, 2 is grow
if (splitscreen)
{
INT32 bestlocaltimer = 1;
#define setbests(p) \
if (players[p].playerstate == PST_LIVE) \
{ \
if (players[p].kartstuff[k_growshrinktimer] > bestlocaltimer) \
{ wantedmus = 2; bestlocaltimer = players[p].kartstuff[k_growshrinktimer]; } \
else if (players[p].kartstuff[k_invincibilitytimer] > bestlocaltimer) \
{ wantedmus = 1; bestlocaltimer = players[p].kartstuff[k_invincibilitytimer]; } \
}
setbests(displayplayer);
setbests(secondarydisplayplayer);
if (splitscreen > 1)
setbests(thirddisplayplayer);
if (splitscreen > 2)
setbests(fourthdisplayplayer);
#undef setbests
}
else
{
if (player->playerstate == PST_LIVE)
{
if (player->kartstuff[k_growshrinktimer] > 1)
wantedmus = 2;
else if (player->kartstuff[k_invincibilitytimer] > 1)
wantedmus = 1;
}
}
// Item - Grow // Item - Grow
if (player->kartstuff[k_growshrinktimer] > 1 && player->playerstate == PST_LIVE) if (wantedmus == 2)
S_ChangeMusicInternal("kgrow", true); S_ChangeMusicInternal("kgrow", true);
// Item - Invincibility // Item - Invincibility
else if (player->kartstuff[k_invincibilitytimer] > 1 && player->playerstate == PST_LIVE) else if (wantedmus == 1)
S_ChangeMusicInternal("kinvnc", true); S_ChangeMusicInternal("kinvnc", true);
else else
{ {
#if 0
// Event - Final Lap // Event - Final Lap
// Still works for GME, but disabled for consistency
if (G_RaceGametype() && player->laps >= (UINT8)(cv_numlaps.value - 1)) if (G_RaceGametype() && player->laps >= (UINT8)(cv_numlaps.value - 1))
S_SpeedMusic(1.2f); S_SpeedMusic(1.2f);
#endif
S_ChangeMusic(mapmusname, mapmusflags, true); S_ChangeMusic(mapmusname, mapmusflags, true);
} }
} }
@ -6652,13 +6688,24 @@ static void P_MovePlayer(player_t *player)
if (player->mo->state != &states[S_KART_SQUISH]) if (player->mo->state != &states[S_KART_SQUISH])
P_SetPlayerMobjState(player->mo, S_KART_SQUISH); P_SetPlayerMobjState(player->mo, S_KART_SQUISH);
} }
else if (player->kartstuff[k_spinouttimer] > 0 || player->pflags & PF_SLIDING) else if (player->pflags & PF_SLIDING)
{ {
if (player->mo->state != &states[S_KART_SPIN]) if (player->mo->state != &states[S_KART_SPIN])
P_SetPlayerMobjState(player->mo, S_KART_SPIN); P_SetPlayerMobjState(player->mo, S_KART_SPIN);
player->frameangle -= ANGLE_22h; player->frameangle -= ANGLE_22h;
} }
else if (player->kartstuff[k_spinouttimer] > 0)
{
INT32 speed = max(1, min(8, player->kartstuff[k_spinouttimer]/8));
if (player->mo->state != &states[S_KART_SPIN])
P_SetPlayerMobjState(player->mo, S_KART_SPIN);
if (speed == 1 && abs(player->mo->angle - player->frameangle) < ANGLE_22h)
player->frameangle = player->mo->angle; // Face forward at the end of the animation
else
player->frameangle -= (ANGLE_11hh * speed);
}
else if (player->powers[pw_nocontrol] && player->pflags & PF_SKIDDOWN) else if (player->powers[pw_nocontrol] && player->pflags & PF_SKIDDOWN)
{ {
if (player->mo->state != &states[S_KART_SPIN]) if (player->mo->state != &states[S_KART_SPIN])
@ -7335,7 +7382,7 @@ static void P_DoZoomTube(player_t *player)
fixed_t dist; fixed_t dist;
boolean reverse; boolean reverse;
player->mo->height = P_GetPlayerSpinHeight(player); //player->mo->height = P_GetPlayerSpinHeight(player);
if (player->speed > 0) if (player->speed > 0)
reverse = false; reverse = false;
@ -7440,6 +7487,11 @@ static void P_DoZoomTube(player_t *player)
else if (player == &players[fourthdisplayplayer]) else if (player == &players[fourthdisplayplayer])
localangle4 = player->mo->angle; localangle4 = player->mo->angle;
} }
#if 0
if (player->mo->state != &states[S_KART_SPIN])
P_SetPlayerMobjState(player->mo, S_KART_SPIN);
player->frameangle -= ANGLE_22h;
#endif
} }
// //
@ -8254,6 +8306,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
if (mo->eflags & MFE_VERTICALFLIP) if (mo->eflags & MFE_VERTICALFLIP)
camheight += thiscam->height; camheight += thiscam->height;
if (splitscreen == 1)
camspeed = (3*camspeed)/4;
if (timeover) if (timeover)
angle = mo->angle + FixedAngle(camrotate*FRACUNIT); angle = mo->angle + FixedAngle(camrotate*FRACUNIT);
else if (leveltime < starttime) else if (leveltime < starttime)
@ -8555,8 +8610,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
if (timeover == 1) if (timeover == 1)
{ {
thiscam->momx = P_ReturnThrustX(NULL, mo->angle, 32<<FRACBITS); // Push forward thiscam->momx = P_ReturnThrustX(NULL, mo->angle, 32*mo->scale); // Push forward
thiscam->momy = P_ReturnThrustY(NULL, mo->angle, 32<<FRACBITS); thiscam->momy = P_ReturnThrustY(NULL, mo->angle, 32*mo->scale);
thiscam->momz = 0; thiscam->momz = 0;
} }
else if (player->exiting || timeover == 2) else if (player->exiting || timeover == 2)

View file

@ -531,6 +531,9 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
pitch = NORM_PITCH; pitch = NORM_PITCH;
priority = NORM_PRIORITY; priority = NORM_PRIORITY;
if (splitscreen && origin)
volume = FixedDiv(volume<<FRACBITS, FixedSqrt((splitscreen+1)<<FRACBITS))>>FRACBITS;
if (splitscreen && listenmobj2) // Copy the sound for the split player if (splitscreen && listenmobj2) // Copy the sound for the split player
{ {
// Check to see if it is audible, and if not, modify the params // Check to see if it is audible, and if not, modify the params
@ -1011,6 +1014,9 @@ void S_UpdateSounds(void)
pitch = NORM_PITCH; pitch = NORM_PITCH;
sep = NORM_SEP; sep = NORM_SEP;
if (splitscreen && c->origin)
volume = FixedDiv(volume<<FRACBITS, FixedSqrt((splitscreen+1)<<FRACBITS))>>FRACBITS;
// check non-local sounds for distance clipping // check non-local sounds for distance clipping
// or modify their params // or modify their params
if (c->origin && ((c->origin != players[consoleplayer].mo) if (c->origin && ((c->origin != players[consoleplayer].mo)
@ -1325,6 +1331,9 @@ INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *v
*vol = (15 * ((S_CLIPPING_DIST - approx_dist)>>FRACBITS)) / S_ATTENUATOR; *vol = (15 * ((S_CLIPPING_DIST - approx_dist)>>FRACBITS)) / S_ATTENUATOR;
} }
if (splitscreen)
*vol = FixedDiv((*vol)<<FRACBITS, FixedSqrt((splitscreen+1)<<FRACBITS))>>FRACBITS;
return (*vol > 0); return (*vol > 0);
} }

View file

@ -1903,13 +1903,13 @@ static void ST_overlayDrawer(void)
if(!P_IsLocalPlayer(stplyr)) if(!P_IsLocalPlayer(stplyr))
{ {
char name[MAXPLAYERNAME+1]; /*char name[MAXPLAYERNAME+1];
// shorten the name if its more than twelve characters. // shorten the name if its more than twelve characters.
strlcpy(name, player_names[stplyr-players], 13); strlcpy(name, player_names[stplyr-players], 13);*/
// Show name of player being displayed // Show name of player being displayed
V_DrawCenteredString((BASEVIDWIDTH/2), BASEVIDHEIGHT-40, 0, M_GetText("Viewpoint:")); V_DrawCenteredString((BASEVIDWIDTH/2), BASEVIDHEIGHT-40, 0, M_GetText("Viewpoint:"));
V_DrawCenteredString((BASEVIDWIDTH/2), BASEVIDHEIGHT-32, V_ALLOWLOWERCASE, name); V_DrawCenteredString((BASEVIDWIDTH/2), BASEVIDHEIGHT-32, V_ALLOWLOWERCASE, player_names[stplyr-players]);
} }
// This is where we draw all the fun cheese if you have the chasecam off! // This is where we draw all the fun cheese if you have the chasecam off!
@ -2065,4 +2065,13 @@ void ST_Drawer(void)
if (mapheaderinfo[gamemap-1]->typeoflevel & TOL_TV) // Very specific Midnight Channel stuff. if (mapheaderinfo[gamemap-1]->typeoflevel & TOL_TV) // Very specific Midnight Channel stuff.
ST_MayonakaStatic(); ST_MayonakaStatic();
} }
// Draw a white fade on level opening
if (leveltime < 15)
{
if (leveltime <= 5)
V_DrawFill(0,0,BASEVIDWIDTH,BASEVIDHEIGHT,120); // Pure white on first few frames, to hide SRB2's awful level load artifacts
else
V_DrawFadeScreen(120, 15-leveltime); // Then gradually fade out from there
}
} }

View file

@ -78,9 +78,9 @@ consvar_t cv_grcoronas = {"gr_coronas", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL,
consvar_t cv_grcoronasize = {"gr_coronasize", "1", CV_SAVE| CV_FLOAT, 0, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grcoronasize = {"gr_coronasize", "1", CV_SAVE| CV_FLOAT, 0, NULL, 0, NULL, NULL, 0, 0, NULL};
#endif #endif
static CV_PossibleValue_t CV_MD2[] = {{0, "Off"}, {1, "On"}, {2, "Old"}, {0, NULL}}; //static CV_PossibleValue_t CV_MD2[] = {{0, "Off"}, {1, "On"}, {2, "Old"}, {0, NULL}};
// console variables in development // console variables in development
consvar_t cv_grmd2 = {"gr_md2", "Off", CV_SAVE, CV_MD2, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_grmd2 = {"gr_md2", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
#endif #endif
const UINT8 gammatable[5][256] = const UINT8 gammatable[5][256] =

View file

@ -348,7 +348,7 @@ void Y_IntermissionDrawer(void)
V_DrawPatchFill(bgtile); V_DrawPatchFill(bgtile);
if (usebuffer) // Fade everything out if (usebuffer) // Fade everything out
V_DrawFadeScreen(0xFF00, 20); V_DrawFadeScreen(0xFF00, 22);
if (!splitscreen) if (!splitscreen)
whiteplayer = demoplayback ? displayplayer : consoleplayer; whiteplayer = demoplayback ? displayplayer : consoleplayer;