diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 9190853e..0d3b9141 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1319,7 +1319,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) else netbuffer->u.serverinfo.iszone = 0; - netbuffer->u.serverinfo.actnum = mapheaderinfo[gamemap-1]->actnum; + netbuffer->u.serverinfo.actnum = 0; //mapheaderinfo[gamemap-1]->actnum p = PutFileNeeded(); @@ -1636,15 +1636,16 @@ static void CL_LoadReceivedSavegame(void) if (P_LoadNetGame()) { - const INT32 actnum = mapheaderinfo[gamemap-1]->actnum; CONS_Printf(M_GetText("Map is now \"%s"), G_BuildMapName(gamemap)); - if (strcmp(mapheaderinfo[gamemap-1]->lvlttl, "")) + if (strlen(mapheaderinfo[gamemap-1]->lvlttl) > 0) { CONS_Printf(": %s", mapheaderinfo[gamemap-1]->lvlttl); - if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE)) + if (strlen(mapheaderinfo[gamemap-1]->zonttl) > 0) + CONS_Printf(" %s", mapheaderinfo[gamemap-1]->zonttl); + else if (!(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE)) CONS_Printf(M_GetText(" ZONE")); - if (actnum > 0) - CONS_Printf(" %2d", actnum); + if (strlen(mapheaderinfo[gamemap-1]->actnum) > 0) + CONS_Printf(" %s", mapheaderinfo[gamemap-1]->actnum); } CONS_Printf("\"\n"); } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 02c12fcd..2f2657d7 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -4523,10 +4523,20 @@ static void Command_Showmap_f(void) { if (gamestate == GS_LEVEL) { - if (mapheaderinfo[gamemap-1]->actnum) - CONS_Printf("%s (%d): %s %d\n", G_BuildMapName(gamemap), gamemap, mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->actnum); + if (strlen(mapheaderinfo[gamemap-1]->zonttl) > 0) + { + if (strlen(mapheaderinfo[gamemap-1]->actnum) > 0) + CONS_Printf("%s (%d): %s %s %s\n", G_BuildMapName(gamemap), gamemap, mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->zonttl, mapheaderinfo[gamemap-1]->actnum); + else + CONS_Printf("%s (%d): %s %s\n", G_BuildMapName(gamemap), gamemap, mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->zonttl); + } else - CONS_Printf("%s (%d): %s\n", G_BuildMapName(gamemap), gamemap, mapheaderinfo[gamemap-1]->lvlttl); + { + if (strlen(mapheaderinfo[gamemap-1]->actnum) > 0) + CONS_Printf("%s (%d): %s %s\n", G_BuildMapName(gamemap), gamemap, mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->actnum); + else + CONS_Printf("%s (%d): %s\n", G_BuildMapName(gamemap), gamemap, mapheaderinfo[gamemap-1]->lvlttl); + } } else CONS_Printf(M_GetText("You must be in a level to use this.\n")); diff --git a/src/d_player.h b/src/d_player.h index bd5004de..2ca419d9 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -261,6 +261,7 @@ typedef enum k_boostcharge, // Charge-up for boosting at the start of the race, or when Lakitu drops you k_jmp, // In Mario Kart, letting go of the jump button stops the drift k_offroad, // In Super Mario Kart, going offroad has lee-way of about 1 second before you start losing speed + k_brakestop, // Wait until you've made a complete stop for a few tics before letting brake go in reverse. 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) @@ -279,6 +280,7 @@ typedef enum k_spinouttimer, // Spin-out from a banana peel or oil slick (was "pw_bananacam") k_laserwisptimer, // The duration and relative angle of the laser k_justbumped, // Prevent players from endlessly bumping into each other + k_deathsentence, // 30 seconds to live... (Blue Shell murder timer (not actually 30 sec, I just couldn't help the FF reference :p)) k_poweritemtimer, // Battle mode, how long before you're allowed another power item (Star, Megashroom) k_comebacktimer, // Battle mode, how long before you become a bomb after death diff --git a/src/d_ticcmd.h b/src/d_ticcmd.h index 0a751148..afb052ce 100644 --- a/src/d_ticcmd.h +++ b/src/d_ticcmd.h @@ -25,18 +25,13 @@ typedef enum { BT_ACCELERATE = 1, // Accelerate - BT_DRIFT = 1<<2, // Drift (direction is cmd->angleturn) + BT_DRIFT = 1<<2, // Drift (direction is cmd->driftturn) BT_BRAKE = 1<<3, // Brake BT_ATTACK = 1<<4, // Use Item BT_FORWARD = 1<<5, // Aim Item Forward BT_BACKWARD = 1<<6, // Aim Item Backward - //BT_SPECTATE = 1<<7, // Toggle Spectate - // Want more button space? Help get rid of this hack :V - BT_DRIFTLEFT = 1<<7, // Drift left hack - BT_DRIFTRIGHT = 1<<8, // Drift right hack - - // free: 1<<9 to 1<<12 + // free: 1<<7 to 1<<12 // Lua garbage BT_CUSTOM1 = 1<<13, @@ -64,6 +59,7 @@ typedef struct INT16 angleturn; // <<16 for angle delta - saved as 1 byte into demos INT16 aiming; // vertical aiming, see G_BuildTicCmd UINT16 buttons; + INT16 driftturn; // SRB2Kart: Used for getting drift turn speed } ATTRPACK ticcmd_t; #if defined(_MSC_VER) diff --git a/src/dehacked.c b/src/dehacked.c index 70b6965e..772771ec 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1136,10 +1136,12 @@ static void readlevelheader(MYFILE *f, INT32 num) } else if (fastcmp(word, "ACT")) { - if (i >= 0 && i < 20) // 0 for no act number, TTL1 through TTL19 + /*if (i >= 0 && i < 20) // 0 for no act number, TTL1 through TTL19 mapheaderinfo[num-1]->actnum = (UINT8)i; else - deh_warning("Level header %d: invalid act number %d", num, i); + deh_warning("Level header %d: invalid act number %d", num, i);*/ + deh_strlcpy(mapheaderinfo[num-1]->actnum, word2, + sizeof(mapheaderinfo[num-1]->actnum), va("Level header %d: actnum", num)); } else if (fastcmp(word, "NEXTLEVEL")) { @@ -7306,9 +7308,13 @@ static const char *const MOBJEFLAG_LIST[] = { "JUSTSTEPPEDDOWN", // used for ramp sectors "VERTICALFLIP", // Vertically flip sprite/allow upside-down physics "GOOWATER", // Goo water - "\x01", // free: 1<<7 (name un-matchable) + "JUSTBOUNCEDWALL", // SRB2Kart: Mobj already bounced off a wall this tic "SPRUNG", // Mobj was already sprung this tic "APPLYPMOMZ", // Platform movement + "DRAWONLYFORP1", // SRB2Kart: Splitscreen sprite draw flags + "DRAWONLYFORP2", + "DRAWONLYFORP3", + "DRAWONLYFORP4", NULL }; @@ -7565,8 +7571,10 @@ static const char *const KARTSTUFF_LIST[] = { "BOOSTCHARGE", "JMP", "OFFROAD", + "BRAKESTOP", "ITEMROULETTE", + "ROULETTETYPE", "ITEMCLOSE", "MAGNETTIMER", @@ -7581,6 +7589,7 @@ static const char *const KARTSTUFF_LIST[] = { "SPINOUTTIMER", "LASERWISPTIMER", "JUSTBUMPED", + "DEATHSENTENCE", "POWERITEMTIMER", "COMEBACKTIMER", @@ -8030,9 +8039,6 @@ struct { {"BT_ATTACK",BT_ATTACK}, {"BT_FORWARD",BT_FORWARD}, {"BT_BACKWARD",BT_BACKWARD}, - //{"BT_SPECTATE",BT_SPECTATE}, - {"BT_DRIFTLEFT",BT_DRIFTLEFT}, - {"BT_DRIFTRIGHT",BT_DRIFTRIGHT}, {"BT_CUSTOM1",BT_CUSTOM1}, // Lua customizable {"BT_CUSTOM2",BT_CUSTOM2}, // Lua customizable {"BT_CUSTOM3",BT_CUSTOM3}, // Lua customizable diff --git a/src/doomstat.h b/src/doomstat.h index 41a3656f..ea5151b1 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -220,7 +220,7 @@ typedef struct char lvlttl[22]; ///< Level name without "Zone". (21 character limit instead of 32, 21 characters can display on screen max anyway) char subttl[33]; ///< Subtitle for level char zonttl[22]; ///< "ZONE" replacement name - UINT8 actnum; ///< Act number or 0 for none. + char actnum[3]; ///< SRB2Kart: Now a 2 character long string. UINT16 typeoflevel; ///< Combination of typeoflevel flags. INT16 nextlevel; ///< Map number of next level, or 1100-1102 to end. char musname[7]; ///< Music track to play. "" for no music. @@ -445,6 +445,10 @@ extern boolean franticitems; extern boolean mirrormode; extern boolean comeback; +extern tic_t lightningcooldown; +extern tic_t blueshellincoming; +extern UINT8 blueshellplayer; + extern boolean legitimateexit; extern boolean comebackshowninfo; extern tic_t curlap, bestlap; diff --git a/src/g_game.c b/src/g_game.c index 269d25f1..bbce2d3e 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -252,6 +252,11 @@ INT16 votelevels[4]; // Levels that were rolled by the host SINT8 votes[MAXPLAYERS]; // Each player's vote SINT8 pickedvote; // What vote the host rolls +// Server-sided variables +tic_t lightningcooldown; // Cooldown before any more lightning/blue shell is awarded +tic_t blueshellincoming; // Timer before blue shell hits, can switch targets at this point +UINT8 blueshellplayer; // Player num that used the last blue shell + // Client-sided variables (NEVER use in anything that needs to be synced with other players) boolean legitimateexit; // Did this client actually finish the match? boolean comebackshowninfo; // Have you already seen the "ATTACK OR PROTECT" message? @@ -1150,16 +1155,15 @@ angle_t localangle, localangle2, localangle3, localangle4; boolean camspin, camspin2, camspin3, camspin4; static fixed_t forwardmove[2] = {25<>16, 50<>16}; -static fixed_t sidemove[2] = {25<>16, 50<>16}; // faster! +static fixed_t sidemove[2] = {2<>16, 4<>16}; static fixed_t angleturn[3] = {400, 800, 200}; // + slow turn void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) { - boolean forcestrafe = false; INT32 laim, th, tspeed, forward, side, axis; //i const INT32 speed = 1; // these ones used for multiple conditions - boolean turnleft, turnright, invertmouse, mouseaiming, lookaxis, analog, analogjoystickmove, gamepadjoystickmove, kbl, rd; + boolean turnleft, turnright, invertmouse, mouseaiming, lookaxis, analogjoystickmove, gamepadjoystickmove, kbl, rd; player_t *player; camera_t *thiscam; angle_t lang; @@ -1231,7 +1235,6 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) lookaxis = cv_lookaxis2.value; analogjoystickmove = cv_usejoystick2.value && !Joystick2.bGamepadStyle; gamepadjoystickmove = cv_usejoystick2.value && Joystick2.bGamepadStyle; - analog = cv_analog2.value; break; case 3: mouseaiming = false; @@ -1239,7 +1242,6 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) lookaxis = cv_lookaxis3.value; analogjoystickmove = cv_usejoystick3.value && !Joystick3.bGamepadStyle; gamepadjoystickmove = cv_usejoystick3.value && Joystick3.bGamepadStyle; - analog = cv_analog3.value; break; case 4: mouseaiming = false; @@ -1247,7 +1249,6 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) lookaxis = cv_lookaxis4.value; analogjoystickmove = cv_usejoystick4.value && !Joystick4.bGamepadStyle; gamepadjoystickmove = cv_usejoystick4.value && Joystick4.bGamepadStyle; - analog = cv_analog4.value; break; case 1: default: @@ -1256,7 +1257,6 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) lookaxis = cv_lookaxis.value; analogjoystickmove = cv_usejoystick.value && !Joystick.bGamepadStyle; gamepadjoystickmove = cv_usejoystick.value && Joystick.bGamepadStyle; - analog = cv_analog.value; break; } @@ -1292,49 +1292,66 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) else tspeed = speed; + cmd->driftturn = 0; + // let movement keys cancel each other out - if (analog) // Analog + if (turnright && !(turnleft)) { - if (turnright) - cmd->angleturn = (INT16)(cmd->angleturn - angleturn[tspeed]); - if (turnleft) - cmd->angleturn = (INT16)(cmd->angleturn + angleturn[tspeed]); + cmd->angleturn = (INT16)(cmd->angleturn - angleturn[tspeed]); + cmd->driftturn = (INT16)(cmd->driftturn - angleturn[tspeed]); + } + else if (turnleft && !(turnright)) + { + cmd->angleturn = (INT16)(cmd->angleturn + angleturn[tspeed]); + cmd->driftturn = (INT16)(cmd->driftturn + angleturn[tspeed]); } - if (analog || twodlevel - || (player->mo && (player->mo->flags2 & MF2_TWOD)) - || (!demoplayback && (player->climbing - || (player->pflags & PF_NIGHTSMODE) - || (player->pflags & PF_SLIDING) - || (player->pflags & PF_FORCESTRAFE)))) // Analog - forcestrafe = true; + if (analogjoystickmove && axis != 0) + { + // JOYAXISRANGE should be 1023 (divide by 1024) + cmd->angleturn = (INT16)(cmd->angleturn - ((axis * angleturn[1]) >> 10)); // ANALOG! + cmd->driftturn = (INT16)(cmd->driftturn - ((axis * angleturn[1]) >> 10)); + } - if (forcestrafe) // Analog + // Specator mouse turning + if (player->spectator) + { + cmd->angleturn = (INT16)(cmd->angleturn - (mousex*(mirrormode ? -1 : 1)*8)); + cmd->driftturn = (INT16)(cmd->driftturn - (mousex*(mirrormode ? -1 : 1)*8)); + } + + // Bounce pad strafing + if (!demoplayback && ((player->pflags & PF_FORCESTRAFE) || (player->kartstuff[k_feather] & 2))) { if (turnright) - side += sidemove[speed]; + side += sidemove[1]; if (turnleft) - side -= sidemove[speed]; - + side -= sidemove[1]; if (analogjoystickmove && axis != 0) { // JOYAXISRANGE is supposed to be 1023 (divide by 1024) - side += ((axis * sidemove[1]) >> 10); + side += ((axis * sidemove[0]) >> 10); } } - else - { - if (turnright && !(turnleft)) - cmd->angleturn = (INT16)(cmd->angleturn - angleturn[tspeed]); - else if (turnleft && !(turnright)) - cmd->angleturn = (INT16)(cmd->angleturn + angleturn[tspeed]); - if (analogjoystickmove && axis != 0) - { - // JOYAXISRANGE should be 1023 (divide by 1024) - cmd->angleturn = (INT16)(cmd->angleturn - ((axis * angleturn[1]) >> 10)); // ANALOG! - } - } + //{ SRB2kart - Drift support + // limit turning to angleturn[1] to stop mouselook letting you look too fast + if (cmd->angleturn > angleturn[1]) + cmd->angleturn = angleturn[1]; + else if (cmd->angleturn < -angleturn[1]) + cmd->angleturn = -angleturn[1]; + + if (cmd->driftturn > angleturn[1]) + cmd->driftturn = angleturn[1]; + else if (cmd->driftturn < -angleturn[1]) + cmd->driftturn = -angleturn[1]; + + if (player->mo) + cmd->angleturn = K_GetKartTurnValue(player, cmd->angleturn); + + // SRB2kart - no additional angle if not moving + if ((player->mo && player->speed > 0) || (leveltime > 140 && cmd->buttons & BT_ACCELERATE && cmd->buttons & BT_BRAKE) || (player->spectator || objectplacing)) + lang += (cmd->angleturn<<16); if (player->spectator || objectplacing) // SRB2Kart: spectators need special controls { @@ -1392,7 +1409,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (InputDown(gc_fire, ssplayer) || (cv_usejoystick.value && axis > 0)) cmd->buttons |= BT_ATTACK; - // drift button + // drift with any button/key axis = JoyAxis(AXISDRIFT, ssplayer); if (InputDown(gc_drift, ssplayer) || (cv_usejoystick.value && axis > 0)) cmd->buttons |= BT_DRIFT; @@ -1405,6 +1422,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) if (InputDown(gc_custom3, ssplayer)) cmd->buttons |= BT_CUSTOM3; + // Reset camera if (InputDown(gc_camreset, ssplayer)) { if (thiscam->chase && !rd) @@ -1414,7 +1432,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) else rd = false; - // player aiming shit, ahhhh... + // spectator aiming shit, ahhhh... { INT32 player_invert = invertmouse ? -1 : 1; INT32 screen_invert = @@ -1463,15 +1481,13 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->aiming = G_ClipAimingPitch(&laim); } - if (player->spectator) - cmd->angleturn = (INT16)(cmd->angleturn - (mousex*(mirrormode ? -1 : 1)*8)); - mousex = mousey = mlooky = 0; if (forward > MAXPLMOVE) forward = MAXPLMOVE; else if (forward < -MAXPLMOVE) forward = -MAXPLMOVE; + if (side > MAXPLMOVE) side = MAXPLMOVE; else if (side < -MAXPLMOVE) @@ -1479,86 +1495,20 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // No additional acceleration when moving forward/backward and strafing simultaneously. // do this AFTER we cap to MAXPLMOVE so people can't find ways to cheese around this. - if (!forcestrafe && forward && side) + // SRB2Kart: We don't need this; we WANT bounce strafing to plain stack on top of normal movement. + /*if (!bouncestrafe && forward && side) { forward = FixedMul(forward, 3*FRACUNIT/4); side = FixedMul(side, 3*FRACUNIT/4); - } + }*/ - //Silly hack to make 2d mode *somewhat* playable with no chasecam. - if ((twodlevel || (player->mo && player->mo->flags2 & MF2_TWOD)) && !thiscam->chase) - { - INT32 temp = forward; - forward = side; - side = temp; - } - - if (cmd->buttons & BT_BRAKE && !forward) // Sal: If you're not accelerating, but going forward, then you should just lose your momentum. Request from Sev - { - cmd->forwardmove = (SINT8)(cmd->forwardmove / 2); - cmd->sidemove = (SINT8)(cmd->sidemove / 2); - } - else + if (forward || side) { cmd->forwardmove = (SINT8)(cmd->forwardmove + forward); - if (mirrormode) - cmd->sidemove = (SINT8)(cmd->sidemove - side); - else - cmd->sidemove = (SINT8)(cmd->sidemove + side); + cmd->sidemove = (SINT8)(cmd->sidemove + side); } - if (ssplayer == 2 && player->bot == 1) { - if (!player->powers[pw_tailsfly] && (cmd->forwardmove || cmd->sidemove || cmd->buttons)) - { - player->bot = 2; // A player-controlled bot. Returns to AI when it respawns. - //CV_SetValue(&cv_analog2, true); - } - else - { - G_CopyTiccmd(cmd, I_BaseTiccmd2(), 1); // empty, or external driver - B_BuildTiccmd(player, cmd); - } - } - - //{ SRB2kart - Drift support - axis = JoyAxis(AXISTURN, ssplayer); - if (mirrormode) - axis = -axis; - - // TODO: Remove this hack please :( - if (cmd->angleturn > 0) // Drifting to the left - cmd->buttons |= BT_DRIFTLEFT; - else - cmd->buttons &= ~BT_DRIFTLEFT; - - if (cmd->angleturn < 0) // Drifting to the right - cmd->buttons |= BT_DRIFTRIGHT; - else - cmd->buttons &= ~BT_DRIFTRIGHT; - //} - - if (analog) { - cmd->angleturn = (INT16)(thiscam->angle >> 16); - if (player->awayviewtics) - cmd->angleturn = (INT16)(player->awayviewmobj->angle >> 16); - } - else - { - // limit turning to angleturn[1] to stop mouselook letting you look too fast - if (cmd->angleturn > angleturn[1]) - cmd->angleturn = angleturn[1]; - else if (cmd->angleturn < -angleturn[1]) - cmd->angleturn = -angleturn[1]; - - if (player->mo) - cmd->angleturn = K_GetKartTurnValue(player, cmd->angleturn); - - // SRB2kart - no additional angle if not moving - if ((player->mo && player->speed > 0) || (leveltime > 140 && cmd->buttons & BT_ACCELERATE && cmd->buttons & BT_BRAKE) || (player->spectator || objectplacing)) - lang += (cmd->angleturn<<16); - - cmd->angleturn = (INT16)(lang >> 16); - } + cmd->angleturn = (INT16)(lang >> 16); if (!hu_stopped) { @@ -4149,10 +4099,10 @@ char *G_BuildMapTitle(INT32 mapnum) { size_t len = 1; const char *zonetext = NULL; - const INT32 actnum = mapheaderinfo[mapnum-1]->actnum; + const char *actnum = NULL; len += strlen(mapheaderinfo[mapnum-1]->lvlttl); - if (strcmp(mapheaderinfo[mapnum-1]->zonttl, "")) + if (strlen(mapheaderinfo[mapnum-1]->zonttl) > 0) { zonetext = M_GetText(mapheaderinfo[mapnum-1]->zonttl); len += strlen(zonetext) + 1; // ' ' + zonetext @@ -4162,14 +4112,17 @@ char *G_BuildMapTitle(INT32 mapnum) zonetext = M_GetText("ZONE"); len += strlen(zonetext) + 1; // ' ' + zonetext } - if (actnum > 0) - len += 1 + 11; // ' ' + INT32 + if (strlen(mapheaderinfo[mapnum-1]->actnum) > 0) + { + actnum = M_GetText(mapheaderinfo[mapnum-1]->actnum); + len += strlen(actnum) + 1; // ' ' + actnum + } title = Z_Malloc(len, PU_STATIC, NULL); sprintf(title, "%s", mapheaderinfo[mapnum-1]->lvlttl); if (zonetext) sprintf(title + strlen(title), " %s", zonetext); - if (actnum > 0) sprintf(title + strlen(title), " %d", actnum); + if (actnum) sprintf(title + strlen(title), " %s", actnum); } return title; @@ -4194,6 +4147,7 @@ char *G_BuildMapTitle(INT32 mapnum) #define ZT_ANGLE 0x04 #define ZT_BUTTONS 0x08 #define ZT_AIMING 0x10 +#define ZT_DRIFT 0x20 #define DEMOMARKER 0x80 // demoend static ticcmd_t oldcmd; @@ -4251,6 +4205,7 @@ ticcmd_t *G_MoveTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n) dest[i].angleturn = SHORT(src[i].angleturn); dest[i].aiming = (INT16)SHORT(src[i].aiming); dest[i].buttons = (UINT16)SHORT(src[i].buttons); + dest[i].driftturn = (INT16)SHORT(src[i].driftturn); } return dest; } @@ -4274,6 +4229,8 @@ void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum) oldcmd.buttons = (oldcmd.buttons & (BT_FORWARD|BT_BACKWARD)) | (READUINT16(demo_p) & ~(BT_FORWARD|BT_BACKWARD)); if (ziptic & ZT_AIMING) oldcmd.aiming = READINT16(demo_p); + if (ziptic & ZT_DRIFT) + oldcmd.driftturn = READINT16(demo_p); G_CopyTiccmd(cmd, &oldcmd, 1); @@ -4330,6 +4287,13 @@ void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum) ziptic |= ZT_AIMING; } + if (cmd->driftturn != oldcmd.driftturn) + { + WRITEINT16(demo_p,cmd->driftturn); + oldcmd.driftturn = cmd->driftturn; + ziptic |= ZT_DRIFT; + } + *ziptic_p = ziptic; // attention here for the ticcmd size! @@ -4702,6 +4666,8 @@ void G_GhostTicker(void) g->p += 2; if (ziptic & ZT_AIMING) g->p += 2; + if (ziptic & ZT_DRIFT) + g->p += 2; // Grab ghost data. ziptic = READUINT8(g->p); diff --git a/src/info.c b/src/info.c index 3c7e2894..7ab34df0 100644 --- a/src/info.c +++ b/src/info.c @@ -15242,7 +15242,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 100, // mass 1, // damage sfx_None, // activesound - MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY, // flags + MF_NOBLOCKMAP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING|MF_NOGRAVITY|MF_SCENERY, // flags S_NULL // raisestate }, diff --git a/src/k_kart.c b/src/k_kart.c index 5c75f2bd..2c485a1c 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -25,6 +25,9 @@ // franticitems is Frantic Mode items, bool // mirrormode is Mirror Mode (duh), bool // comeback is Battle Mode's karma comeback, also bool +// lightningcooldown is timer before anyone's allowed another lightning/blue shell +// blueshellincoming is the timer before k_deathsentence is cast on the player in 1st +// blueshellplayer is the last player who fired one //{ SRB2kart Color Code @@ -364,11 +367,11 @@ static INT32 K_KartItemOddsDistance_Retro[NUMKARTITEMS][9] = //P-Odds 0 1 2 3 4 5 6 7 8 /*Magnet*/ { 0, 1, 2, 0, 0, 0, 0, 0, 0 }, // Magnet /*Boo*/ { 0, 0, 2, 2, 1, 0, 0, 0, 0 }, // Boo - /*Mushroom*/ { 1, 0, 0, 3, 7, 5, 0, 0, 0 }, // Mushroom - /*Triple Mushroom*/ { 0, 0, 0, 0, 3, 8, 6, 4, 0 }, // Triple Mushroom - /*Mega Mushroom*/ { 0, 0, 0, 0, 0, 1, 1, 1, 2 }, // Mega Mushroom - /*Gold Mushroom*/ { 0, 0, 0, 0, 0, 2, 4, 3, 0 }, // Gold Mushroom - /*Star*/ { 0, 0, 0, 0, 0, 1, 6, 8,18 }, // Star + /*Mushroom*/ {20, 0, 0, 3, 7, 6, 0, 0, 0 }, // Mushroom + /*Triple Mushroom*/ { 0, 0, 0, 0, 3, 8, 7, 4, 0 }, // Triple Mushroom + /*Mega Mushroom*/ { 0, 0, 0, 0, 0, 0, 1, 1, 2 }, // Mega Mushroom + /*Gold Mushroom*/ { 0, 0, 0, 0, 0, 3, 5, 4, 0 }, // Gold Mushroom + /*Star*/ { 0, 0, 0, 0, 0, 1, 6, 9,18 }, // Star /*Triple Banana*/ { 0, 0, 1, 1, 0, 0, 0, 0, 0 }, // Triple Banana /*Fake Item*/ { 0, 4, 2, 1, 0, 0, 0, 0, 0 }, // Fake Item @@ -377,7 +380,7 @@ static INT32 K_KartItemOddsDistance_Retro[NUMKARTITEMS][9] = /*Red Shell*/ { 0, 0, 3, 2, 2, 1, 0, 0, 0 }, // Red Shell /*Triple Green Shell*/ { 0, 0, 0, 1, 1, 1, 0, 0, 0 }, // Triple Green Shell /*Bob-omb*/ { 0, 0, 1, 2, 1, 0, 0, 0, 0 }, // Bob-omb - /*Blue Shell*/ { 0, 0, 0, 0, 0, 1, 2, 0, 0 }, // Blue Shell + /*Blue Shell*/ { 0, 0, 1, 2, 4, 3, 1, 0, 0 }, // Blue Shell /*Fire Flower*/ { 0, 0, 1, 2, 1, 0, 0, 0, 0 }, // Fire Flower /*Triple Red Shell*/ { 0, 0, 0, 1, 1, 0, 0, 0, 0 }, // Triple Red Shell /*Lightning*/ { 0, 0, 0, 0, 0, 0, 1, 2, 0 }, // Lightning @@ -390,25 +393,25 @@ static INT32 K_KartItemOddsBalloons[NUMKARTITEMS][6] = //P-Odds 0 1 2 3 4 5 /*Magnet*/ { 0, 0, 0, 0, 0, 0 }, // Magnet /*Boo*/ { 0, 0, 1, 1, 0, 0 }, // Boo - /*Mushroom*/ { 0, 1, 2, 1, 0, 1 }, // Mushroom - /*Triple Mushroom*/ { 0, 0, 0, 0, 0, 0 }, // Triple Mushroom - /*Mega Mushroom*/ { 1, 2, 0, 0, 0, 1 }, // Mega Mushroom + /*Mushroom*/ { 3, 1, 2, 2, 0, 2 }, // Mushroom + /*Triple Mushroom*/ { 3, 0, 0, 0, 0, 2 }, // Triple Mushroom + /*Mega Mushroom*/ { 4, 2, 0, 0, 0, 2 }, // Mega Mushroom /*Gold Mushroom*/ { 0, 0, 0, 0, 0, 0 }, // Gold Mushroom - /*Star*/ { 1, 2, 0, 0, 0, 1 }, // Star + /*Star*/ { 4, 2, 1, 0, 0, 2 }, // Star - /*Triple Banana*/ { 0, 1, 1, 0, 0, 1 }, // Triple Banana - /*Fake Item*/ { 0, 0, 2, 1, 1, 0 }, // Fake Item - /*Banana*/ { 0, 0, 3, 1, 1, 0 }, // Banana - /*Green Shell*/ { 0, 0, 5, 3, 2, 0 }, // Green Shell - /*Red Shell*/ { 0, 3, 3, 0, 0, 1 }, // Red Shell - /*Triple Green Shell*/ { 0, 1, 1, 0, 0, 1 }, // Triple Green Shell - /*Bob-omb*/ { 0, 3, 3, 0, 0, 1 }, // Bob-omb + /*Triple Banana*/ { 0, 2, 2, 1, 1, 2 }, // Triple Banana + /*Fake Item*/ { 0, 0, 2, 2, 3, 0 }, // Fake Item + /*Banana*/ { 0, 0, 2, 3, 6, 0 }, // Banana + /*Green Shell*/ { 0, 0, 3, 5,10, 0 }, // Green Shell + /*Red Shell*/ { 3, 3, 2, 1, 0, 2 }, // Red Shell + /*Triple Green Shell*/ { 0, 3, 1, 1, 0, 2 }, // Triple Green Shell + /*Bob-omb*/ { 0, 3, 2, 1, 0, 2 }, // Bob-omb /*Blue Shell*/ { 0, 0, 0, 0, 0, 0 }, // Blue Shell - /*Fire Flower*/ { 0, 3, 3, 0, 0, 1 }, // Fire Flower - /*Triple Red Shell*/ { 1, 2, 0, 0, 0, 1 }, // Triple Red Shell + /*Fire Flower*/ { 0, 2, 1, 1, 0, 2 }, // Fire Flower + /*Triple Red Shell*/ { 3, 2, 0, 0, 0, 2 }, // Triple Red Shell /*Lightning*/ { 0, 0, 0, 0, 0, 0 }, // Lightning - /*Feather*/ { 0, 0, 1, 1, 0, 0 } // Feather + /*Feather*/ { 0, 0, 1, 2, 0, 0 } // Feather }; /** \brief Item Roulette for Kart @@ -473,6 +476,7 @@ static void K_KartGetItemResult(player_t *player, fixed_t getitem, boolean retro player->kartstuff[k_blueshell] = 1; else player->kartstuff[k_bobomb] |= 2; + lightningcooldown = 20*TICRATE; break; case 16: // Fire Flower - or - Deton (Blue Shell) if (retrokart) @@ -488,6 +492,7 @@ static void K_KartGetItemResult(player_t *player, fixed_t getitem, boolean retro break; case 18: // Lightning player->kartstuff[k_lightning] = 1; + lightningcooldown = 20*TICRATE; break; case 19: // Feather player->kartstuff[k_feather] |= 1; @@ -507,7 +512,7 @@ static void K_KartGetItemResult(player_t *player, fixed_t getitem, boolean retro \return void */ -static INT32 K_KartGetItemOdds(INT32 pos, INT32 itemnum) +static INT32 K_KartGetItemOdds(INT32 pos, INT32 itemnum, boolean mashed) { INT32 newodds; @@ -516,10 +521,15 @@ static INT32 K_KartGetItemOdds(INT32 pos, INT32 itemnum) else newodds = K_KartItemOddsDistance_Retro[itemnum-1][pos]; - if (franticitems && (itemnum == 1 || itemnum == 4 || itemnum == 5 || itemnum == 6 + if (itemnum == 1 || itemnum == 4 || itemnum == 5 || itemnum == 6 || itemnum == 7 || itemnum == 8 || itemnum == 12 || itemnum == 13 || itemnum == 14 || itemnum == 15 - || itemnum == 16 || itemnum == 17 || itemnum == 18)) - newodds *= 2; + || itemnum == 16 || itemnum == 17 || itemnum == 18) // Powerful items! + { + if (franticitems) + newodds *= 2; + if (mashed) + newodds /= 2; + } return newodds; } @@ -537,6 +547,10 @@ static void K_KartItemRouletteByDistance(player_t *player, ticcmd_t *cmd) INT32 chance = 0, numchoices = 0; INT32 distvar = (64*14); INT32 avgballoon = 0; + INT32 secondist = 0; + SINT8 first = -1; + SINT8 second = -1; + boolean mashed = false; // This makes the roulette cycle through items - if this is 0, you shouldn't be here. if (player->kartstuff[k_itemroulette]) @@ -553,8 +567,9 @@ static void K_KartItemRouletteByDistance(player_t *player, ticcmd_t *cmd) // If the roulette finishes or the player presses BT_ATTACK, stop the roulette and calculate the item. // I'm returning via the exact opposite, however, to forgo having another bracket embed. Same result either way, I think. // Finally, if you get past this check, now you can actually start calculating what item you get. - if (!(player->kartstuff[k_itemroulette] >= (TICRATE*3) - || ((cmd->buttons & BT_ATTACK) && player->kartstuff[k_itemroulette] >= roulettestop))) + if ((cmd->buttons & BT_ATTACK) && player->kartstuff[k_itemroulette] >= roulettestop) + mashed = true; // Mashing halves your chances for the good items + else if (!(player->kartstuff[k_itemroulette] >= (TICRATE*3))) return; if (cmd->buttons & BT_ATTACK) @@ -567,8 +582,9 @@ static void K_KartItemRouletteByDistance(player_t *player, ticcmd_t *cmd) // Gotta check how many players are active at this moment. for (i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i] && !players[i].spectator) - pingame++; + if (!playeringame[i] || players[i].spectator) + continue; + pingame++; if (players[i].exiting) pexiting++; if (players[i].kartstuff[k_balloon] > 0) @@ -580,15 +596,28 @@ static void K_KartItemRouletteByDistance(player_t *player, ticcmd_t *cmd) for (i = 0; i < MAXPLAYERS; i++) { - if (playeringame[i] && !players[i].spectator && players[i].mo - && players[i].kartstuff[k_position] < player->kartstuff[k_position]) - pdis += P_AproxDistance(P_AproxDistance(players[i].mo->x - player->mo->x, - players[i].mo->y - player->mo->y), - players[i].mo->z - player->mo->z) / mapheaderinfo[gamemap-1]->mobj_scale - * (pingame - players[i].kartstuff[k_position]) - / ((pingame - 1) * (pingame + 1) / 3); + if (playeringame[i] && !players[i].spectator && players[i].mo) + { + if (players[i].kartstuff[k_position] < player->kartstuff[k_position]) + pdis += P_AproxDistance(P_AproxDistance(players[i].mo->x - player->mo->x, + players[i].mo->y - player->mo->y), + players[i].mo->z - player->mo->z) / mapheaderinfo[gamemap-1]->mobj_scale + * (pingame - players[i].kartstuff[k_position]) + / ((pingame - 1) * (pingame + 1) / 3); + if (players[i].kartstuff[k_position] == 1 && first == -1) + first = i; + if (players[i].kartstuff[k_position] == 2 && second == -1) + second = i; + } } + if (first != -1 && second != -1 && !secondist) // calculate 2nd's distance from 1st, for blue shell + secondist = P_AproxDistance(P_AproxDistance(players[first].mo->x - players[second].mo->x, + players[first].mo->y - players[second].mo->y), + players[first].mo->z - players[second].mo->z) / mapheaderinfo[gamemap-1]->mobj_scale + * (pingame - 1) + / ((pingame - 1) * (pingame + 1) / 3); + player->kartstuff[k_itemclose] = 0; // Reset the item window closer. if (G_BattleGametype()) // Battle Mode @@ -607,7 +636,10 @@ static void K_KartItemRouletteByDistance(player_t *player, ticcmd_t *cmd) else { if (franticitems) // Frantic items make the distances between everyone artifically higher :P + { pdis = (15*pdis/14); + secondist = (15*pdis/14); + } if (pingame == 1) useodds = 0; // Record Attack, or just alone else if (pdis <= distvar * 0) useodds = 1; // (64*14) * 0 = 0 else if (pdis <= distvar * 1) useodds = 2; // (64*14) * 1 = 896 @@ -619,32 +651,35 @@ static void K_KartItemRouletteByDistance(player_t *player, ticcmd_t *cmd) else useodds = 8; } + //CONS_Printf("%d %d\n", secondist, distvar*2); + #define SETITEMRESULT(pos, itemnum) \ - for (chance = 0; chance < K_KartGetItemOdds(pos, itemnum); chance++) \ + for (chance = 0; chance < K_KartGetItemOdds(pos, itemnum, mashed); chance++) \ spawnchance[numchoices++] = itemnum // Check the game type to differentiate odds. //if (gametype == GT_RETRO) //{ - if (cv_magnet.value) SETITEMRESULT(useodds, 1); // Magnet - if (cv_boo.value) SETITEMRESULT(useodds, 2); // Boo - if (cv_mushroom.value || modeattacking) SETITEMRESULT(useodds, 3); // Mushroom - if (cv_triplemushroom.value) SETITEMRESULT(useodds, 4); // Triple Mushroom - if (cv_megashroom.value && !player->kartstuff[k_poweritemtimer]) SETITEMRESULT(useodds, 5); // Mega Mushroom - if (cv_goldshroom.value) SETITEMRESULT(useodds, 6); // Gold Mushroom - if (cv_star.value && !player->kartstuff[k_poweritemtimer]) SETITEMRESULT(useodds, 7); // Star - if (cv_triplebanana.value) SETITEMRESULT(useodds, 8); // Triple Banana - if (cv_fakeitem.value) SETITEMRESULT(useodds, 9); // Fake Item - if (cv_banana.value) SETITEMRESULT(useodds, 10); // Banana - if (cv_greenshell.value) SETITEMRESULT(useodds, 11); // Green Shell - if (cv_redshell.value) SETITEMRESULT(useodds, 12); // Red Shell - if (cv_triplegreenshell.value) SETITEMRESULT(useodds, 13); // Triple Green Shell - if (cv_bobomb.value) SETITEMRESULT(useodds, 14); // Bob-omb - if (cv_blueshell.value && pexiting == 0) SETITEMRESULT(useodds, 15); // Blue Shell - if (cv_fireflower.value) SETITEMRESULT(useodds, 16); // Fire Flower - if (cv_tripleredshell.value && pingame > 2) SETITEMRESULT(useodds, 17); // Triple Red Shell - if (cv_lightning.value && pingame > pexiting) SETITEMRESULT(useodds, 18); // Lightning - if (cv_feather.value) SETITEMRESULT(useodds, 19); // Feather + if (cv_magnet.value) SETITEMRESULT(useodds, 1); // Magnet + if (cv_boo.value) SETITEMRESULT(useodds, 2); // Boo + if (cv_mushroom.value || modeattacking) SETITEMRESULT(useodds, 3); // Mushroom + if (cv_triplemushroom.value) SETITEMRESULT(useodds, 4); // Triple Mushroom + if (cv_megashroom.value && !player->kartstuff[k_poweritemtimer]) SETITEMRESULT(useodds, 5); // Mega Mushroom + if (cv_goldshroom.value) SETITEMRESULT(useodds, 6); // Gold Mushroom + if (cv_star.value && !player->kartstuff[k_poweritemtimer]) SETITEMRESULT(useodds, 7); // Star + if (cv_triplebanana.value) SETITEMRESULT(useodds, 8); // Triple Banana + if (cv_fakeitem.value) SETITEMRESULT(useodds, 9); // Fake Item + if (cv_banana.value) SETITEMRESULT(useodds, 10); // Banana + if (cv_greenshell.value) SETITEMRESULT(useodds, 11); // Green Shell + if (cv_redshell.value) SETITEMRESULT(useodds, 12); // Red Shell + if (cv_triplegreenshell.value) SETITEMRESULT(useodds, 13); // Triple Green Shell + if (cv_bobomb.value) SETITEMRESULT(useodds, 14); // Bob-omb + if (cv_blueshell.value && pexiting == 0 + && (secondist > distvar*4) && !lightningcooldown) SETITEMRESULT(useodds, 15); // Blue Shell + if (cv_fireflower.value) SETITEMRESULT(useodds, 16); // Fire Flower + if (cv_tripleredshell.value) SETITEMRESULT(useodds, 17); // Triple Red Shell + if (cv_lightning.value && pingame > pexiting && !lightningcooldown) SETITEMRESULT(useodds, 18); // Lightning + if (cv_feather.value) SETITEMRESULT(useodds, 19); // Feather prandom = P_RandomKey(numchoices); @@ -691,6 +726,10 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) || (mobj2->player && mobj2->player->playerstate != PST_LIVE)) return; + if ((mobj1->player && mobj1->player->kartstuff[k_lakitu]) + || (mobj2->player && mobj2->player->kartstuff[k_lakitu])) + return; + // Don't bump if you've recently bumped if ((mobj1->player && mobj1->player->kartstuff[k_justbumped]) || (mobj2->player && mobj1->player->kartstuff[k_justbumped])) @@ -947,11 +986,11 @@ void K_KartMoveAnimation(player_t *player) // Standing frames - S_KART_STND1 S_KART_STND1_L S_KART_STND1_R if (player->speed == 0) { - if (cmd->buttons & BT_DRIFTRIGHT && !(player->mo->state >= &states[S_KART_STND1_R] && player->mo->state <= &states[S_KART_STND2_R])) + if (cmd->driftturn < 0 && !(player->mo->state >= &states[S_KART_STND1_R] && player->mo->state <= &states[S_KART_STND2_R])) P_SetPlayerMobjState(player->mo, S_KART_STND1_R); - else if (cmd->buttons & BT_DRIFTLEFT && !(player->mo->state >= &states[S_KART_STND1_L] && player->mo->state <= &states[S_KART_STND2_L])) + else if (cmd->driftturn > 0 && !(player->mo->state >= &states[S_KART_STND1_L] && player->mo->state <= &states[S_KART_STND2_L])) P_SetPlayerMobjState(player->mo, S_KART_STND1_L); - else if (!(cmd->buttons & BT_DRIFTRIGHT || cmd->buttons & BT_DRIFTLEFT) && !(player->mo->state >= &states[S_KART_STND1] && player->mo->state <= &states[S_KART_STND2])) + else if (cmd->driftturn == 0 && !(player->mo->state >= &states[S_KART_STND1] && player->mo->state <= &states[S_KART_STND2])) P_SetPlayerMobjState(player->mo, S_KART_STND1); } // Drifting Left - S_KART_DRIFT1_L @@ -969,228 +1008,25 @@ void K_KartMoveAnimation(player_t *player) // Run frames - S_KART_RUN1 S_KART_RUN1_L S_KART_RUN1_R else if (player->speed > FixedMul(player->runspeed, player->mo->scale)) { - if (cmd->buttons & BT_DRIFTRIGHT && !(player->mo->state >= &states[S_KART_RUN1_R] && player->mo->state <= &states[S_KART_RUN2_R])) + if (cmd->driftturn < 0 && !(player->mo->state >= &states[S_KART_RUN1_R] && player->mo->state <= &states[S_KART_RUN2_R])) P_SetPlayerMobjState(player->mo, S_KART_RUN1_R); - else if (cmd->buttons & BT_DRIFTLEFT && !(player->mo->state >= &states[S_KART_RUN1_L] && player->mo->state <= &states[S_KART_RUN2_L])) + else if (cmd->driftturn > 0 && !(player->mo->state >= &states[S_KART_RUN1_L] && player->mo->state <= &states[S_KART_RUN2_L])) P_SetPlayerMobjState(player->mo, S_KART_RUN1_L); - else if (!(cmd->buttons & BT_DRIFTRIGHT || cmd->buttons & BT_DRIFTLEFT) && !(player->mo->state >= &states[S_KART_RUN1] && player->mo->state <= &states[S_KART_RUN2])) + else if (cmd->driftturn == 0 && !(player->mo->state >= &states[S_KART_RUN1] && player->mo->state <= &states[S_KART_RUN2])) P_SetPlayerMobjState(player->mo, S_KART_RUN1); } // Walk frames - S_KART_WALK1 S_KART_WALK1_L S_KART_WALK1_R else if (player->speed <= FixedMul(player->runspeed, player->mo->scale)) { - if (cmd->buttons & BT_DRIFTRIGHT && !(player->mo->state >= &states[S_KART_WALK1_R] && player->mo->state <= &states[S_KART_WALK2_R])) + if (cmd->driftturn < 0 && !(player->mo->state >= &states[S_KART_WALK1_R] && player->mo->state <= &states[S_KART_WALK2_R])) P_SetPlayerMobjState(player->mo, S_KART_WALK1_R); - else if (cmd->buttons & BT_DRIFTLEFT && !(player->mo->state >= &states[S_KART_WALK1_L] && player->mo->state <= &states[S_KART_WALK2_L])) + else if (cmd->driftturn > 0 && !(player->mo->state >= &states[S_KART_WALK1_L] && player->mo->state <= &states[S_KART_WALK2_L])) P_SetPlayerMobjState(player->mo, S_KART_WALK1_L); - else if (!(cmd->buttons & BT_DRIFTRIGHT || cmd->buttons & BT_DRIFTLEFT) && !(player->mo->state >= &states[S_KART_WALK1] && player->mo->state <= &states[S_KART_WALK2])) + else if (cmd->driftturn == 0 && !(player->mo->state >= &states[S_KART_WALK1] && player->mo->state <= &states[S_KART_WALK2])) P_SetPlayerMobjState(player->mo, S_KART_WALK1); } } -/** \brief Decreases various kart timers and powers per frame. Called in P_PlayerThink in p_user.c - - \param player player object passed from P_PlayerThink - \param cmd control input from player - - \return void -*/ -void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) -{ - K_UpdateOffroad(player); - - // setting players to use the star colormap and spawning afterimages - if (player->kartstuff[k_startimer]) - { - mobj_t *ghost; - player->mo->colorized = true; - ghost = P_SpawnGhostMobj(player->mo); - ghost->fuse = 4; - ghost->frame |= FF_FULLBRIGHT; - } - else - { - player->mo->colorized = false; - } - - if (player->kartstuff[k_itemclose]) - player->kartstuff[k_itemclose]--; - - if (player->kartstuff[k_spinout]) - player->kartstuff[k_spinout]--; - - if (player->kartstuff[k_spinouttimer]) - player->kartstuff[k_spinouttimer]--; - else if (!comeback) - player->kartstuff[k_comebacktimer] = comebacktime; - else if (player->kartstuff[k_comebacktimer]) - { - player->kartstuff[k_comebacktimer]--; - if (player == &players[consoleplayer] && player->kartstuff[k_balloon] <= 0 && player->kartstuff[k_comebacktimer] <= 0) - comebackshowninfo = true; // client has already seen the message - } - - if (player->kartstuff[k_spinout] == 0 && player->kartstuff[k_spinouttimer] == 0 && player->powers[pw_flashing] == K_GetKartFlashing()) - player->powers[pw_flashing]--; - - if (player->kartstuff[k_magnettimer]) - player->kartstuff[k_magnettimer]--; - - if (player->kartstuff[k_mushroomtimer]) - player->kartstuff[k_mushroomtimer]--; - - if (player->kartstuff[k_floorboost]) - player->kartstuff[k_floorboost]--; - - if (player->kartstuff[k_driftboost]) - player->kartstuff[k_driftboost]--; - - if (player->kartstuff[k_startimer]) - player->kartstuff[k_startimer]--; - - if (player->kartstuff[k_growshrinktimer] > 0) - player->kartstuff[k_growshrinktimer]--; - - if (player->kartstuff[k_growshrinktimer] < 0) - player->kartstuff[k_growshrinktimer]++; - - if (player->kartstuff[k_growshrinktimer] == 1 || player->kartstuff[k_growshrinktimer] == -1) - { - player->mo->destscale = mapheaderinfo[gamemap-1]->mobj_scale; - P_RestoreMusic(player); - } - - if (player->kartstuff[k_bootaketimer] == 0 && player->kartstuff[k_boostolentimer] == 0 - && player->kartstuff[k_goldshroomtimer]) - player->kartstuff[k_goldshroomtimer]--; - - if (player->kartstuff[k_bootimer]) - player->kartstuff[k_bootimer]--; - - if (player->kartstuff[k_bootaketimer]) - player->kartstuff[k_bootaketimer]--; - - if (player->kartstuff[k_boostolentimer]) - player->kartstuff[k_boostolentimer]--; - - if (player->kartstuff[k_squishedtimer]) - player->kartstuff[k_squishedtimer]--; - - if (player->kartstuff[k_laserwisptimer]) - player->kartstuff[k_laserwisptimer]--; - - if (player->kartstuff[k_justbumped]) - player->kartstuff[k_justbumped]--; - - if (player->kartstuff[k_poweritemtimer]) - player->kartstuff[k_poweritemtimer]--; - - if (player->kartstuff[k_lapanimation]) - player->kartstuff[k_lapanimation]--; - - if (G_BattleGametype() && (player->exiting || player->kartstuff[k_comebacktimer])) - { - if (player->exiting) - { - if (player->exiting < 6*TICRATE) - player->kartstuff[k_cardanimation] += ((164-player->kartstuff[k_cardanimation])/8)+1; - } - else - { - if (player->kartstuff[k_comebacktimer] < 6*TICRATE) - player->kartstuff[k_cardanimation] -= ((164-player->kartstuff[k_cardanimation])/8)+1; - else if (player->kartstuff[k_comebacktimer] < 9*TICRATE) - player->kartstuff[k_cardanimation] += ((164-player->kartstuff[k_cardanimation])/8)+1; - } - - if (player->kartstuff[k_cardanimation] > 164) - player->kartstuff[k_cardanimation] = 164; - if (player->kartstuff[k_cardanimation] < 0) - player->kartstuff[k_cardanimation] = 0; - } - else - player->kartstuff[k_cardanimation] = 0; - - if (player->kartstuff[k_voices]) - player->kartstuff[k_voices]--; - - if (player->kartstuff[k_tauntvoices]) - player->kartstuff[k_tauntvoices]--; - - // ??? - /* - if (player->kartstuff[k_jmp] > 1 && onground) - { - S_StartSound(player->mo, sfx_spring); - P_DoJump(player, false); - player->mo->momz *= player->kartstuff[k_jmp]; - player->kartstuff[k_jmp] = 0; - } - */ - - if (player->kartstuff[k_comebacktimer]) - player->kartstuff[k_comebackmode] = 0; - - if (P_IsObjectOnGround(player->mo) && !(player->mo->momz) - && player->kartstuff[k_feather] & 2) - player->kartstuff[k_feather] &= ~2; - - if (cmd->buttons & BT_DRIFT) - player->kartstuff[k_jmp] = 1; - else - player->kartstuff[k_jmp] = 0; - - // Lakitu Checker - if (player->kartstuff[k_lakitu]) - K_LakituChecker(player); - - // Roulette Code - //K_KartItemRouletteByPosition(player, cmd); // Old, position-based - K_KartItemRouletteByDistance(player, cmd); // New, distance-based - - // Stopping of the horrible star SFX - if (player->mo->health <= 0 || player->mo->player->kartstuff[k_startimer] <= 0 - || player->mo->player->kartstuff[k_growshrinktimer] > 0) // If you don't have invincibility (or mega is active too) - { - if (S_SoundPlaying(player->mo, sfx_star)) // But the sound is playing - S_StopSoundByID(player->mo, sfx_star); // Stop it - } - - // And the same for the mega mushroom SFX - if (!(player->mo->health > 0 && player->mo->player->kartstuff[k_growshrinktimer] > 0)) // If you aren't big - { - if (S_SoundPlaying(player->mo, sfx_mega)) // But the sound is playing - S_StopSoundByID(player->mo, sfx_mega); // Stop it - } - - // AAAAAAND handle the SMK star alarm - if (player->mo->health > 0 && (player->mo->player->kartstuff[k_startimer] > 0 - || player->mo->player->kartstuff[k_growshrinktimer] > 0)) - { - if (leveltime % 13 == 0 && cv_kartstarsfx.value && !P_IsLocalPlayer(player)) - S_StartSound(player->mo, sfx_smkinv); - } - else if (S_SoundPlaying(player->mo, sfx_smkinv)) - S_StopSoundByID(player->mo, sfx_smkinv); - - // Plays the music after the starting countdown. - if (P_IsLocalPlayer(player) && leveltime == 158) - S_ChangeMusic(mapmusname, mapmusflags, true); -} - -void K_KartPlayerAfterThink(player_t *player) -{ - if (player->kartstuff[k_startimer]) - { - player->mo->frame |= FF_FULLBRIGHT; - } - else - { - if (!(player->mo->state->frame & FF_FULLBRIGHT)) - player->mo->frame &= ~FF_FULLBRIGHT; - } -} - static void K_PlayTauntSound(mobj_t *source) { if (source->player && source->player->kartstuff[k_tauntvoices]) // Prevents taunt sounds from playing every time the button is pressed @@ -1389,6 +1225,15 @@ fixed_t K_3dKartMovement(player_t *player, boolean onground, fixed_t forwardmove if (!onground) return 0; // If the player isn't on the ground, there is no change in speed + if (forwardmove <= 0 && player->kartstuff[k_brakestop] < 6) // Don't start reversing with brakes until you've made a stop first + { + if (player->speed < 8*FRACUNIT) + player->kartstuff[k_brakestop]++; + return 0; + } + else if (forwardmove > 0) + player->kartstuff[k_brakestop] = 0; + // ACCELCODE!!!1!11! oldspeed = R_PointToDist2(0, 0, player->rmomx, player->rmomy); // FixedMul(P_AproxDistance(player->rmomx, player->rmomy), player->mo->scale); newspeed = FixedDiv(FixedDiv(FixedMul(oldspeed, accelmax - p_accel) + FixedMul(p_speed, p_accel), accelmax), ORIG_FRICTION); @@ -1808,6 +1653,7 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t angle mobj_t *th; angle_t an; fixed_t x, y, z; + fixed_t finalspeed = speed; mobj_t *throwmo; //INT32 dir; @@ -1819,8 +1665,11 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t angle //else // dir = 1; - x = source->x + source->momx; - y = source->y + source->momy; + if (source->player && source->player->speed > K_GetKartSpeed(source->player, false)) + finalspeed = FixedMul(speed, FixedDiv(source->player->speed, K_GetKartSpeed(source->player, false))); + + x = source->x + source->momx + FixedMul(finalspeed, FINECOSINE(an>>ANGLETOFINESHIFT)); + y = source->y + source->momy + FixedMul(finalspeed, FINESINE(an>>ANGLETOFINESHIFT)); z = source->z; // spawn on the ground please if (P_MobjFlip(source) < 0) @@ -1862,11 +1711,11 @@ static mobj_t *K_SpawnKartMissile(mobj_t *source, mobjtype_t type, angle_t angle } th->angle = an; - th->momx = FixedMul(speed, FINECOSINE(an>>ANGLETOFINESHIFT)); - th->momy = FixedMul(speed, FINESINE(an>>ANGLETOFINESHIFT)); + th->momx = FixedMul(finalspeed, FINECOSINE(an>>ANGLETOFINESHIFT)); + th->momy = FixedMul(finalspeed, FINESINE(an>>ANGLETOFINESHIFT)); x = x + P_ReturnThrustX(source, an, source->radius + th->radius); - x = y + P_ReturnThrustY(source, an, source->radius + th->radius); + y = y + P_ReturnThrustY(source, an, source->radius + th->radius); throwmo = P_SpawnMobj(x, y, z, MT_FIREDITEM); throwmo->movecount = 1; throwmo->movedir = source->angle - an; @@ -2018,7 +1867,7 @@ static mobj_t *K_ThrowKartItem(player_t *player, boolean missile, mobjtype_t map else { // Shoot forward - mo = K_SpawnKartMissile(player->mo, mapthing, player->mo->angle, 0, PROJSPEED + player->speed); + mo = K_SpawnKartMissile(player->mo, mapthing, player->mo->angle, 0, PROJSPEED); } } } @@ -2285,7 +2134,7 @@ void K_DoMushroom(player_t *player, boolean doPFlag) K_PlayTauntSound(player->mo); } -static void K_DoLightning(player_t *player, boolean bluelightning) +static void K_DoLightning(player_t *player) { mobj_t *mo; thinker_t *think; @@ -2308,7 +2157,7 @@ static void K_DoLightning(player_t *player, boolean bluelightning) if (mo->player && !mo->player->spectator && mo->player->kartstuff[k_position] < player->kartstuff[k_position]) - P_DamageMobj(mo, player->mo, player->mo, bluelightning ? 65 : 64); + P_DamageMobj(mo, player->mo, player->mo, 64); else continue; } @@ -2316,6 +2165,21 @@ static void K_DoLightning(player_t *player, boolean bluelightning) K_PlayTauntSound(player->mo); } +static void K_DoBlueShell(player_t *victim, player_t *source) +{ + INT32 i; + S_StartSound(victim->mo, sfx_bkpoof); // Sound the BANG! + + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i]) + P_FlashPal(&players[i], PAL_NUKE, 10); + } + + if (victim->mo && !victim->spectator) + P_DamageMobj(victim->mo, source->mo, source->mo, 65); +} + void K_DoBouncePad(mobj_t *mo, fixed_t vertispeed) { if (mo->player && mo->player->spectator) @@ -2366,6 +2230,216 @@ void K_DoBouncePad(mobj_t *mo, fixed_t vertispeed) S_StartSound(mo, sfx_boing); } +/** \brief Decreases various kart timers and powers per frame. Called in P_PlayerThink in p_user.c + + \param player player object passed from P_PlayerThink + \param cmd control input from player + + \return void +*/ +void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) +{ + K_UpdateOffroad(player); + + // setting players to use the star colormap and spawning afterimages + if (player->kartstuff[k_startimer]) + { + mobj_t *ghost; + player->mo->colorized = true; + ghost = P_SpawnGhostMobj(player->mo); + ghost->fuse = 4; + ghost->frame |= FF_FULLBRIGHT; + } + else + { + player->mo->colorized = false; + } + + if (player->kartstuff[k_itemclose]) + player->kartstuff[k_itemclose]--; + + if (player->kartstuff[k_spinout]) + player->kartstuff[k_spinout]--; + + if (player->kartstuff[k_spinouttimer]) + player->kartstuff[k_spinouttimer]--; + else if (!comeback) + player->kartstuff[k_comebacktimer] = comebacktime; + else if (player->kartstuff[k_comebacktimer]) + { + player->kartstuff[k_comebacktimer]--; + if (player == &players[consoleplayer] && player->kartstuff[k_balloon] <= 0 && player->kartstuff[k_comebacktimer] <= 0) + comebackshowninfo = true; // client has already seen the message + } + + if (player->kartstuff[k_spinout] == 0 && player->kartstuff[k_spinouttimer] == 0 && player->powers[pw_flashing] == K_GetKartFlashing()) + player->powers[pw_flashing]--; + + if (player->kartstuff[k_magnettimer]) + player->kartstuff[k_magnettimer]--; + + if (player->kartstuff[k_mushroomtimer]) + player->kartstuff[k_mushroomtimer]--; + + if (player->kartstuff[k_floorboost]) + player->kartstuff[k_floorboost]--; + + if (player->kartstuff[k_driftboost]) + player->kartstuff[k_driftboost]--; + + if (player->kartstuff[k_startimer]) + player->kartstuff[k_startimer]--; + + if (player->kartstuff[k_growshrinktimer] > 0) + player->kartstuff[k_growshrinktimer]--; + + if (player->kartstuff[k_growshrinktimer] < 0) + player->kartstuff[k_growshrinktimer]++; + + if (player->kartstuff[k_growshrinktimer] == 1 || player->kartstuff[k_growshrinktimer] == -1) + { + player->mo->destscale = mapheaderinfo[gamemap-1]->mobj_scale; + P_RestoreMusic(player); + } + + if (player->kartstuff[k_bootaketimer] == 0 && player->kartstuff[k_boostolentimer] == 0 + && player->kartstuff[k_goldshroomtimer]) + player->kartstuff[k_goldshroomtimer]--; + + if (player->kartstuff[k_bootimer]) + player->kartstuff[k_bootimer]--; + + if (player->kartstuff[k_bootaketimer]) + player->kartstuff[k_bootaketimer]--; + + if (player->kartstuff[k_boostolentimer]) + player->kartstuff[k_boostolentimer]--; + + if (player->kartstuff[k_squishedtimer]) + player->kartstuff[k_squishedtimer]--; + + if (player->kartstuff[k_laserwisptimer]) + player->kartstuff[k_laserwisptimer]--; + + if (player->kartstuff[k_justbumped]) + player->kartstuff[k_justbumped]--; + + if (player->kartstuff[k_deathsentence]) + { + if (player->kartstuff[k_deathsentence] == 1) + K_DoBlueShell(player, &players[blueshellplayer]); + player->kartstuff[k_deathsentence]--; + } + + if (player->kartstuff[k_poweritemtimer]) + player->kartstuff[k_poweritemtimer]--; + + if (player->kartstuff[k_lapanimation]) + player->kartstuff[k_lapanimation]--; + + if (G_BattleGametype() && (player->exiting || player->kartstuff[k_comebacktimer])) + { + if (player->exiting) + { + if (player->exiting < 6*TICRATE) + player->kartstuff[k_cardanimation] += ((164-player->kartstuff[k_cardanimation])/8)+1; + } + else + { + if (player->kartstuff[k_comebacktimer] < 6*TICRATE) + player->kartstuff[k_cardanimation] -= ((164-player->kartstuff[k_cardanimation])/8)+1; + else if (player->kartstuff[k_comebacktimer] < 9*TICRATE) + player->kartstuff[k_cardanimation] += ((164-player->kartstuff[k_cardanimation])/8)+1; + } + + if (player->kartstuff[k_cardanimation] > 164) + player->kartstuff[k_cardanimation] = 164; + if (player->kartstuff[k_cardanimation] < 0) + player->kartstuff[k_cardanimation] = 0; + } + else + player->kartstuff[k_cardanimation] = 0; + + if (player->kartstuff[k_voices]) + player->kartstuff[k_voices]--; + + if (player->kartstuff[k_tauntvoices]) + player->kartstuff[k_tauntvoices]--; + + // ??? + /* + if (player->kartstuff[k_jmp] > 1 && onground) + { + S_StartSound(player->mo, sfx_spring); + P_DoJump(player, false); + player->mo->momz *= player->kartstuff[k_jmp]; + player->kartstuff[k_jmp] = 0; + } + */ + + if (player->kartstuff[k_comebacktimer]) + player->kartstuff[k_comebackmode] = 0; + + if (P_IsObjectOnGround(player->mo) && !(player->mo->momz) + && player->kartstuff[k_feather] & 2) + player->kartstuff[k_feather] &= ~2; + + if (cmd->buttons & BT_DRIFT) + player->kartstuff[k_jmp] = 1; + else + player->kartstuff[k_jmp] = 0; + + // Lakitu Checker + if (player->kartstuff[k_lakitu]) + K_LakituChecker(player); + + // Roulette Code + //K_KartItemRouletteByPosition(player, cmd); // Old, position-based + K_KartItemRouletteByDistance(player, cmd); // New, distance-based + + // Stopping of the horrible star SFX + if (player->mo->health <= 0 || player->mo->player->kartstuff[k_startimer] <= 0 + || player->mo->player->kartstuff[k_growshrinktimer] > 0) // If you don't have invincibility (or mega is active too) + { + if (S_SoundPlaying(player->mo, sfx_star)) // But the sound is playing + S_StopSoundByID(player->mo, sfx_star); // Stop it + } + + // And the same for the mega mushroom SFX + if (!(player->mo->health > 0 && player->mo->player->kartstuff[k_growshrinktimer] > 0)) // If you aren't big + { + if (S_SoundPlaying(player->mo, sfx_mega)) // But the sound is playing + S_StopSoundByID(player->mo, sfx_mega); // Stop it + } + + // AAAAAAND handle the SMK star alarm + if (player->mo->health > 0 && (player->mo->player->kartstuff[k_startimer] > 0 + || player->mo->player->kartstuff[k_growshrinktimer] > 0)) + { + if (leveltime % 13 == 0 && cv_kartstarsfx.value && !P_IsLocalPlayer(player)) + S_StartSound(player->mo, sfx_smkinv); + } + else if (S_SoundPlaying(player->mo, sfx_smkinv)) + S_StopSoundByID(player->mo, sfx_smkinv); + + // Plays the music after the starting countdown. + if (P_IsLocalPlayer(player) && leveltime == 158) + S_ChangeMusic(mapmusname, mapmusflags, true); +} + +void K_KartPlayerAfterThink(player_t *player) +{ + if (player->kartstuff[k_startimer]) + { + player->mo->frame |= FF_FULLBRIGHT; + } + else + { + if (!(player->mo->state->frame & FF_FULLBRIGHT)) + player->mo->frame &= ~FF_FULLBRIGHT; + } +} + // Returns false if this player being placed here causes them to collide with any other player // Used in g_game.c for match etc. respawning // This does not check along the z because the z is not correctly set for the spawnee at this point @@ -2452,7 +2526,7 @@ static void K_KartDrift(player_t *player, boolean onground) kartspeed = 1; // IF YOU CHANGE THESE: MAKE SURE YOU UPDATE THE SAME VALUES IN p_mobjc, "case MT_DRIFT:" - dsone = 26*4 + kartspeed*2 + (9 - player->kartweight); + dsone = (26*4 + kartspeed*2 + (9 - player->kartweight))*8; dstwo = dsone*2; // Drifting is actually straffing + automatic turning. @@ -2486,7 +2560,7 @@ static void K_KartDrift(player_t *player, boolean onground) } // Drifting: left or right? - if ((player->cmd.buttons & BT_DRIFTLEFT) && player->speed > FixedMul(10<<16, player->mo->scale) && player->kartstuff[k_jmp] == 1 + if ((player->cmd.driftturn > 0) && player->speed > FixedMul(10<<16, player->mo->scale) && player->kartstuff[k_jmp] == 1 && (player->kartstuff[k_drift] == 0 || player->kartstuff[k_driftend] == 1)) // && player->kartstuff[k_drift] != 1) { // Starting left drift @@ -2494,7 +2568,7 @@ static void K_KartDrift(player_t *player, boolean onground) player->kartstuff[k_driftend] = 0; player->kartstuff[k_driftcharge] = 0; } - else if ((player->cmd.buttons & BT_DRIFTRIGHT) && player->speed > FixedMul(10<<16, player->mo->scale) && player->kartstuff[k_jmp] == 1 + else if ((player->cmd.driftturn < 0) && player->speed > FixedMul(10<<16, player->mo->scale) && player->kartstuff[k_jmp] == 1 && (player->kartstuff[k_drift] == 0 || player->kartstuff[k_driftend] == 1)) // && player->kartstuff[k_drift] != -1) { // Starting right drift @@ -2523,7 +2597,7 @@ static void K_KartDrift(player_t *player, boolean onground) if (player->kartstuff[k_spinouttimer] == 0 && player->kartstuff[k_jmp] == 1 && onground && player->kartstuff[k_drift] != 0) { - fixed_t driftadditive = 3; + fixed_t driftadditive = 24; if (player->kartstuff[k_drift] >= 1) // Drifting to the left { @@ -2531,10 +2605,10 @@ static void K_KartDrift(player_t *player, boolean onground) if (player->kartstuff[k_drift] > 5) player->kartstuff[k_drift] = 5; - if (player->cmd.buttons & BT_DRIFTLEFT) // Inward - driftadditive++; - if (player->cmd.buttons & BT_DRIFTRIGHT) // Outward - driftadditive--; + if (player->cmd.driftturn > 0) // Inward + driftadditive += (player->cmd.driftturn/800)/8; + if (player->cmd.driftturn < 0) // Outward + driftadditive -= (player->cmd.driftturn/800)/8; } else if (player->kartstuff[k_drift] <= -1) // Drifting to the right { @@ -2542,10 +2616,10 @@ static void K_KartDrift(player_t *player, boolean onground) if (player->kartstuff[k_drift] < -5) player->kartstuff[k_drift] = -5; - if (player->cmd.buttons & BT_DRIFTRIGHT) // Inward - driftadditive++; - if (player->cmd.buttons & BT_DRIFTLEFT) // Outward - driftadditive--; + if (player->cmd.driftturn < 0) // Inward + driftadditive += (player->cmd.driftturn/800)/4; + if (player->cmd.driftturn > 0) // Outward + driftadditive -= (player->cmd.driftturn/800)/4; } // This spawns the drift sparks @@ -3160,14 +3234,46 @@ void K_MoveKartPlayer(player_t *player, boolean onground) // Thunder else if (ATTACK_IS_DOWN && !HOLDING_ITEM && player->kartstuff[k_lightning] == 1 && NO_BOO) { - K_DoLightning(player, false); + K_DoLightning(player); player->kartstuff[k_lightning] = 0; player->kartstuff[k_itemclose] = 10; } // Blue Shell else if (ATTACK_IS_DOWN && !HOLDING_ITEM && player->kartstuff[k_blueshell] == 1 && NO_BOO) { - K_DoLightning(player, true); + UINT8 i; + UINT8 bestrank = 0; + fixed_t dist = 0; + + //K_DoLightning(player, true); + + for (i = 0; i < MAXPLAYERS; i++) + { + fixed_t thisdist; + if (!playeringame[i] || players[i].spectator) + continue; + if (&players[i] == player) + continue; + if (!players[i].mo) + continue; + if (players[i].exiting) + continue; + thisdist = R_PointToDist2(player->mo->x, player->mo->y, players[i].mo->x, players[i].mo->y); + if (bestrank == 0 || players[i].kartstuff[k_position] < bestrank) + { + bestrank = players[i].kartstuff[k_position]; + dist = thisdist; + } + } + + if (dist == 0) + blueshellincoming = 6*TICRATE; // If you couldn't find anyone, just set an abritary timer + else + blueshellincoming = (tic_t)max(1, FixedDiv(dist, 64*FRACUNIT)/FRACUNIT); + + blueshellplayer = player-players; + player->pflags |= PF_ATTACKDOWN; + K_PlayTauntSound(player->mo); player->kartstuff[k_blueshell] = 0; player->kartstuff[k_itemclose] = 10; } @@ -3253,23 +3359,47 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (player->kartstuff[k_bootimer] > 0) { - if ((player == &players[displayplayer] && !splitscreen) - || (!(player == &players[displayplayer] && !splitscreen) - && (player->kartstuff[k_bootimer] < 1*TICRATE/2 || player->kartstuff[k_bootimer] > bootime-(1*TICRATE/2)))) + if (splitscreen) { if (leveltime & 1) player->mo->flags2 |= MF2_DONTDRAW; else player->mo->flags2 &= ~MF2_DONTDRAW; + + if (player->kartstuff[k_bootimer] >= (1*TICRATE/2) && player->kartstuff[k_bootimer] <= bootime-(1*TICRATE/2)) + { + if (player == &players[secondarydisplayplayer]) + player->mo->eflags |= MFE_DRAWONLYFORP2; + else if (player == &players[thirddisplayplayer] && splitscreen > 1) + player->mo->eflags |= MFE_DRAWONLYFORP3; + else if (player == &players[fourthdisplayplayer] && splitscreen > 2) + player->mo->eflags |= MFE_DRAWONLYFORP4; + else + player->mo->eflags |= MFE_DRAWONLYFORP1; + } + else + player->mo->eflags &= ~(MFE_DRAWONLYFORP1|MFE_DRAWONLYFORP2|MFE_DRAWONLYFORP3|MFE_DRAWONLYFORP4); } else - player->mo->flags2 |= MF2_DONTDRAW; + { + if (player == &players[displayplayer] + || (player != &players[displayplayer] && (player->kartstuff[k_bootimer] < (1*TICRATE/2) || player->kartstuff[k_bootimer] > bootime-(1*TICRATE/2)))) + { + if (leveltime & 1) + player->mo->flags2 |= MF2_DONTDRAW; + else + player->mo->flags2 &= ~MF2_DONTDRAW; + } + else + player->mo->flags2 |= MF2_DONTDRAW; + } player->powers[pw_flashing] = player->kartstuff[k_bootimer]; // We'll do this for now, let's people know about the invisible people through subtle hints } else if (player->kartstuff[k_bootimer] == 0) { player->mo->flags2 &= ~MF2_DONTDRAW; + player->mo->eflags &= ~(MFE_DRAWONLYFORP1|MFE_DRAWONLYFORP2|MFE_DRAWONLYFORP3|MFE_DRAWONLYFORP4); } if (G_BattleGametype() && player->kartstuff[k_balloon] <= 0) // dead in match? you da bomb @@ -3353,24 +3483,10 @@ void K_MoveKartPlayer(player_t *player, boolean onground) K_KartDrift(player, onground); - // Feather strafing - if (player->kartstuff[k_feather] & 2) - { - fixed_t strafe = 0; - fixed_t strength = FRACUNIT/32; - if (cmd->buttons & BT_DRIFTLEFT) - strafe--; - if (cmd->buttons & BT_DRIFTRIGHT) - strafe++; - strength += FixedDiv(player->speed, K_GetKartSpeed(player, true)); - P_Thrust(player->mo, player->mo->angle-ANGLE_90, strafe*strength); - } - // Quick Turning // You can't turn your kart when you're not moving. // So now it's time to burn some rubber! - if (player->speed < 2 && leveltime > 140 && cmd->buttons & BT_ACCELERATE && cmd->buttons & BT_BRAKE - && ((cmd->buttons & BT_DRIFTLEFT) || (cmd->buttons & BT_DRIFTRIGHT))) + if (player->speed < 2 && leveltime > 140 && cmd->buttons & BT_ACCELERATE && cmd->buttons & BT_BRAKE && cmd->driftturn != 0) { if (leveltime % 20 == 0) S_StartSound(player->mo, sfx_mkslid); @@ -3553,6 +3669,7 @@ static patch_t *kp_checkmega; static patch_t *kp_checkmegaw; static patch_t *kp_rankballoon; static patch_t *kp_ranknoballoons; +static patch_t *kp_bswarning[2]; /* static patch_t *kp_neonoitem; static patch_t *kp_electroshield; @@ -3721,6 +3838,10 @@ void K_LoadKartHUDGraphics(void) kp_rankballoon = W_CachePatchName("K_BLNICO", PU_HUDGFX); kp_ranknoballoons = W_CachePatchName("K_NOBLNS", PU_HUDGFX); + // Blue Shell warning + kp_bswarning[0] = W_CachePatchName("K_BSWRN1", PU_HUDGFX); + kp_bswarning[1] = W_CachePatchName("K_BSWRN2", PU_HUDGFX); + /* // Neo-Kart item windows kp_electroshield = W_CachePatchName("KNITELEC", PU_HUDGFX); @@ -3764,6 +3885,7 @@ INT32 FACE_X, FACE_Y; // Top-four Faces INT32 LAKI_X, LAKI_Y; // Lakitu INT32 CHEK_Y; // CHECK graphic INT32 MINI_X, MINI_Y; // Minimap +INT32 BSWR_X, BSWR_Y; // Blue Shell warning static void K_initKartHUD(void) { @@ -3831,6 +3953,9 @@ static void K_initKartHUD(void) // Minimap MINI_X = BASEVIDWIDTH - 50; // 270 MINI_Y = BASEVIDHEIGHT/2; // 100 + // Blue Shell warning + BSWR_X = BASEVIDWIDTH/2; // 270 + BSWR_Y = BASEVIDHEIGHT- 24; // 176 if (splitscreen) // Splitscreen { @@ -3843,6 +3968,8 @@ static void K_initKartHUD(void) MINI_Y = (BASEVIDHEIGHT/2); + BSWR_Y = (BASEVIDHEIGHT/2)-8; + if (splitscreen > 1) // 3P/4P Small Splitscreen { ITEM_X = 0; @@ -3856,6 +3983,8 @@ static void K_initKartHUD(void) MINI_X = (3*BASEVIDWIDTH/4); MINI_Y = (3*BASEVIDHEIGHT/4); + BSWR_X = BASEVIDWIDTH/4; + if (splitscreen > 2) // 4P-only { MINI_X = (BASEVIDWIDTH/2); @@ -4293,7 +4422,7 @@ static void K_DrawKartPositionNum(INT32 num) break; } } - else if (stplyr->laps+1 == cv_numlaps.value || stplyr->exiting) // Check for the final lap, or won + else if (stplyr->laps+1 >= cv_numlaps.value || stplyr->exiting) // Check for the final lap, or won { // Alternate frame every three frames switch (leveltime % 9) @@ -4561,6 +4690,23 @@ static void K_drawKartBalloonsOrKarma(void) } } +static void K_drawBlueShellWarning(void) +{ + patch_t *localpatch = kp_nodraw; + INT32 splitflags = K_calcSplitFlags(V_SNAPTOBOTTOM); + + if (!(stplyr->kartstuff[k_deathsentence] > 0 + || (blueshellincoming > 0 && blueshellincoming < 2*TICRATE && stplyr->kartstuff[k_position] == 1))) + return; + + if (leveltime % 8 > 3) + localpatch = kp_bswarning[1]; + else + localpatch = kp_bswarning[0]; + + V_DrawScaledPatch(BSWR_X, BSWR_Y, splitflags, localpatch); +} + fixed_t K_FindCheckX(fixed_t px, fixed_t py, angle_t ang, fixed_t mx, fixed_t my) { fixed_t dist, x; @@ -5130,6 +5276,9 @@ void K_drawKartHUD(void) // Draw the numerical position K_DrawKartPositionNum(stplyr->kartstuff[k_position]); } + + // You're about to DIEEEEE + K_drawBlueShellWarning(); } else if (G_BattleGametype()) // Battle-only { diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 771dd0af..c8ff4e28 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -1185,7 +1185,7 @@ static int mapheaderinfo_get(lua_State *L) else if (fastcmp(field,"zonttl")) lua_pushstring(L, header->zonttl); else if (fastcmp(field,"actnum")) - lua_pushinteger(L, header->actnum); + lua_pushstring(L, header->actnum); else if (fastcmp(field,"typeoflevel")) lua_pushinteger(L, header->typeoflevel); else if (fastcmp(field,"nextlevel")) diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 0d488fdb..1eed10b0 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -733,6 +733,8 @@ static int ticcmd_get(lua_State *L) lua_pushinteger(L, cmd->aiming); else if (fastcmp(field,"buttons")) lua_pushinteger(L, cmd->buttons); + else if (fastcmp(field,"driftturn")) + lua_pushinteger(L, cmd->driftturn); else return NOFIELD; @@ -759,6 +761,8 @@ static int ticcmd_set(lua_State *L) cmd->aiming = (INT16)luaL_checkinteger(L, 3); else if (fastcmp(field,"buttons")) cmd->buttons = (UINT16)luaL_checkinteger(L, 3); + else if (fastcmp(field,"driftturn")) + cmd->driftturn = (INT16)luaL_checkinteger(L, 3); else return NOFIELD; diff --git a/src/m_menu.c b/src/m_menu.c index c45e9aa5..87982310 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3371,17 +3371,17 @@ static void M_DrawPauseMenu(void) // Draw any and all emblems at the top. M_DrawMapEmblems(gamemap, 272, 28); - if (mapheaderinfo[gamemap-1]->zonttl) + if (strlen(mapheaderinfo[gamemap-1]->zonttl) > 0) { - if (mapheaderinfo[gamemap-1]->actnum != 0) - V_DrawString(40, 28, V_YELLOWMAP, va("%s %s %d", mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->zonttl, mapheaderinfo[gamemap-1]->actnum)); + if (strlen(mapheaderinfo[gamemap-1]->actnum) > 0) + V_DrawString(40, 28, V_YELLOWMAP, va("%s %s %s", mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->zonttl, mapheaderinfo[gamemap-1]->actnum)); else V_DrawString(40, 28, V_YELLOWMAP, va("%s %s", mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->zonttl)); } else { - if (mapheaderinfo[gamemap-1]->actnum != 0) - V_DrawString(40, 28, V_YELLOWMAP, va("%s %d", mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->actnum)); + if (strlen(mapheaderinfo[gamemap-1]->actnum) > 0) + V_DrawString(40, 28, V_YELLOWMAP, va("%s %s", mapheaderinfo[gamemap-1]->lvlttl, mapheaderinfo[gamemap-1]->actnum)); else V_DrawString(40, 28, V_YELLOWMAP, mapheaderinfo[gamemap-1]->lvlttl); } @@ -4896,7 +4896,7 @@ static void M_ReadSavegameInfo(UINT32 slot) else { strcpy(savegameinfo[slot].levelname, mapheaderinfo[(fake-1) & 8191]->lvlttl); - savegameinfo[slot].actnum = mapheaderinfo[(fake-1) & 8191]->actnum; + savegameinfo[slot].actnum = 0; //mapheaderinfo[(fake-1) & 8191]->actnum } #ifdef SAVEGAMES_OTHERVERSIONS @@ -5347,17 +5347,17 @@ static void M_DrawStatsMaps(int location) mnum = statsMapList[i]; M_DrawMapEmblems(mnum+1, 292, y); - if (mapheaderinfo[mnum]->zonttl) + if (strlen(mapheaderinfo[gamemap-1]->zonttl) > 0) { - if (mapheaderinfo[mnum]->actnum != 0) - V_DrawString(20, y, V_YELLOWMAP, va("%s %s %d", mapheaderinfo[mnum]->lvlttl, mapheaderinfo[mnum]->zonttl, mapheaderinfo[mnum]->actnum)); + if (strlen(mapheaderinfo[gamemap-1]->actnum) > 0) + V_DrawString(20, y, V_YELLOWMAP, va("%s %s %s", mapheaderinfo[mnum]->lvlttl, mapheaderinfo[mnum]->zonttl, mapheaderinfo[mnum]->actnum)); else V_DrawString(20, y, V_YELLOWMAP, va("%s %s", mapheaderinfo[mnum]->lvlttl, mapheaderinfo[mnum]->zonttl)); } else { - if (mapheaderinfo[mnum]->actnum != 0) - V_DrawString(20, y, V_YELLOWMAP, va("%s %d", mapheaderinfo[mnum]->lvlttl, mapheaderinfo[mnum]->actnum)); + if (strlen(mapheaderinfo[gamemap-1]->actnum) > 0) + V_DrawString(20, y, V_YELLOWMAP, va("%s %s", mapheaderinfo[mnum]->lvlttl, mapheaderinfo[mnum]->actnum)); else V_DrawString(20, y, V_YELLOWMAP, mapheaderinfo[mnum]->lvlttl); } diff --git a/src/m_misc.c b/src/m_misc.c index 573354f0..5727067c 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -679,9 +679,9 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png if (gamestate == GS_LEVEL && mapheaderinfo[gamemap-1]->lvlttl[0] != '\0') snprintf(lvlttltext, 48, "%s%s%s", mapheaderinfo[gamemap-1]->lvlttl, - (strlen(mapheaderinfo[gamemap-1]->zonttl) > 0) ? mapheaderinfo[gamemap-1]->zonttl : // SRB2kart + (strlen(mapheaderinfo[gamemap-1]->zonttl) > 0) ? va(" %s",mapheaderinfo[gamemap-1]->zonttl) : // SRB2kart ((mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE"), - (mapheaderinfo[gamemap-1]->actnum > 0) ? va(" %d",mapheaderinfo[gamemap-1]->actnum) : ""); + (strlen(mapheaderinfo[gamemap-1]->actnum) > 0) ? va(" %s",mapheaderinfo[gamemap-1]->actnum) : ""); else snprintf(lvlttltext, 48, "Unknown"); diff --git a/src/p_inter.c b/src/p_inter.c index d3587717..6099e585 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3127,8 +3127,10 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da player->kartstuff[k_mushroomtimer] = 0; // Thunder - if (damage == 64 && player != source->player) + if (damage == 64) { + if (player == source->player) + return false; // Don't flip out while super! if (!player->kartstuff[k_startimer] && player->kartstuff[k_growshrinktimer] <= 0) { @@ -3148,20 +3150,18 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_LIGHTNING); return true; } - else if (damage == 64 && player == source->player) - return false; // Blue Thunder - if (damage == 65 && player->kartstuff[k_position] == 1) + if (damage == 65) { + if (player == source->player) + return false; // Just need to do this now! Being thrown upwards is done by the explosion. P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BLUELIGHTNING); blueexplode = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_BLUEEXPLOSION); P_SetTarget(&blueexplode->target, source); return true; } - else if (damage == 65 && player->kartstuff[k_position] > 1) - return false; //} // Sudden-Death mode diff --git a/src/p_map.c b/src/p_map.c index 16a3838b..ece49f26 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -3886,6 +3886,12 @@ void P_BounceMove(mobj_t *mo) //INT32 hitcount; fixed_t mmomx = 0, mmomy = 0; + if (mo->eflags & MFE_JUSTBOUNCEDWALL) + { + P_SlideMove(mo, true); + return; + } + slidemo = mo; //hitcount = 0; @@ -4018,7 +4024,8 @@ bounceback: } } - P_HitBounceLine(bestslideline); // clip the moves + P_HitBounceLine(bestslideline); + mo->eflags |= MFE_JUSTBOUNCEDWALL; mo->momx = tmxmove; mo->momy = tmymove; diff --git a/src/p_mobj.c b/src/p_mobj.c index a77b97b7..bbf0848c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2891,6 +2891,12 @@ static void P_PlayerZMovement(mobj_t *mo) mo->momx = mo->momx/2; mo->momy = mo->momy/2; } + + if (mo->player->cmd.buttons & BT_BRAKE && !(mo->player->cmd.forwardmove)) // FURTHER slowdown if you're braking. + { + mo->momx = mo->momx/2; + mo->momy = mo->momy/2; + } } if (mo->health) @@ -6258,6 +6264,26 @@ void P_RunShadows(void) else mobj->flags2 &= ~MF2_DONTDRAW; + if (mobj->target->eflags & MFE_DRAWONLYFORP1) // groooooaann... + mobj->eflags |= MFE_DRAWONLYFORP1; + else + mobj->eflags &= ~MFE_DRAWONLYFORP1; + + if (mobj->target->eflags & MFE_DRAWONLYFORP2) + mobj->eflags |= MFE_DRAWONLYFORP2; + else + mobj->eflags &= ~MFE_DRAWONLYFORP2; + + if (mobj->target->eflags & MFE_DRAWONLYFORP3) + mobj->eflags |= MFE_DRAWONLYFORP3; + else + mobj->eflags &= ~MFE_DRAWONLYFORP3; + + if (mobj->target->eflags & MFE_DRAWONLYFORP4) + mobj->eflags |= MFE_DRAWONLYFORP4; + else + mobj->eflags &= ~MFE_DRAWONLYFORP4; + // First scale to the same radius P_SetScale(mobj, FixedDiv(mobj->target->radius, mobj->info->radius)); @@ -6407,7 +6433,7 @@ void P_MobjThinker(mobj_t *mobj) P_SetTarget(&mobj->tracer, NULL); mobj->flags2 &= ~MF2_PUSHED; - mobj->eflags &= ~MFE_SPRUNG; + mobj->eflags &= ~(MFE_SPRUNG|MFE_JUSTBOUNCEDWALL); tmfloorthing = tmhitthing = NULL; @@ -6559,7 +6585,7 @@ void P_MobjThinker(mobj_t *mobj) if (G_BattleGametype() && mobj->target->player->kartstuff[k_balloon] <= 0) kartspeed = 1; - dsone = 26*4 + kartspeed*2 + (9 - mobj->target->player->kartweight); + dsone = (26*4 + kartspeed*2 + (9 - mobj->target->player->kartweight))*8; dstwo = dsone*2; if (mobj->target->player->kartstuff[k_driftcharge] < dsone) @@ -6570,27 +6596,46 @@ void P_MobjThinker(mobj_t *mobj) if (mobj->target->player->kartstuff[k_bootimer] > 0) { - if ((mobj->target->player == &players[displayplayer] - || (splitscreen && mobj->target->player == &players[secondarydisplayplayer]) - || (splitscreen > 1 && mobj->target->player == &players[thirddisplayplayer]) - || (splitscreen > 2 && mobj->target->player == &players[fourthdisplayplayer])) - || (!(mobj->target->player == &players[displayplayer] - || (splitscreen && mobj->target->player == &players[secondarydisplayplayer]) - || (splitscreen > 1 && mobj->target->player == &players[thirddisplayplayer]) - || (splitscreen > 2 && mobj->target->player == &players[fourthdisplayplayer])) - && (mobj->target->player->kartstuff[k_bootimer] < 1*TICRATE/2 || mobj->target->player->kartstuff[k_bootimer] > bootime-(1*TICRATE/2)))) + if (splitscreen) { if (leveltime & 1) mobj->flags2 |= MF2_DONTDRAW; else mobj->flags2 &= ~MF2_DONTDRAW; + + if (mobj->target->player->kartstuff[k_bootimer] >= (1*TICRATE/2) && mobj->target->player->kartstuff[k_bootimer] <= bootime-(1*TICRATE/2)) + { + if (mobj->target->player == &players[secondarydisplayplayer]) + mobj->eflags |= MFE_DRAWONLYFORP2; + else if (mobj->target->player == &players[thirddisplayplayer] && splitscreen > 1) + mobj->eflags |= MFE_DRAWONLYFORP3; + else if (mobj->target->player == &players[fourthdisplayplayer] && splitscreen > 2) + mobj->eflags |= MFE_DRAWONLYFORP4; + else + mobj->eflags |= MFE_DRAWONLYFORP1; + } + else + mobj->eflags &= ~(MFE_DRAWONLYFORP1|MFE_DRAWONLYFORP2|MFE_DRAWONLYFORP3|MFE_DRAWONLYFORP4); } else - mobj->flags2 |= MF2_DONTDRAW; + { + if (mobj->target->player == &players[displayplayer] + || (mobj->target->player != &players[displayplayer] + && (mobj->target->player->kartstuff[k_bootimer] < (1*TICRATE/2) || mobj->target->player->kartstuff[k_bootimer] > bootime-(1*TICRATE/2)))) + { + if (leveltime & 1) + mobj->flags2 |= MF2_DONTDRAW; + else + mobj->flags2 &= ~MF2_DONTDRAW; + } + else + mobj->flags2 |= MF2_DONTDRAW; + } } else if (mobj->target->player->kartstuff[k_bootimer] == 0) { mobj->flags2 &= ~MF2_DONTDRAW; + mobj->eflags &= ~(MFE_DRAWONLYFORP1|MFE_DRAWONLYFORP2|MFE_DRAWONLYFORP3|MFE_DRAWONLYFORP4); } // Actor's distance from its Target, or Radius. @@ -6785,7 +6830,7 @@ void P_MobjThinker(mobj_t *mobj) } break; case MT_BATTLEBALLOON: - if (mobj->health > 0 && mobj->target && mobj->target->player && mobj->target->player->mo + if (mobj->health > 0 && mobj->target && mobj->target->player && mobj->target->player->health > 0 && !mobj->target->player->spectator) { fixed_t rad = 32*mobj->target->scale; @@ -6816,6 +6861,26 @@ void P_MobjThinker(mobj_t *mobj) offz = mobj->target->height / 5; } + if (mobj->target->eflags & MFE_DRAWONLYFORP1) // groooooaann... + mobj->eflags |= MFE_DRAWONLYFORP1; + else + mobj->eflags &= ~MFE_DRAWONLYFORP1; + + if (mobj->target->eflags & MFE_DRAWONLYFORP2) + mobj->eflags |= MFE_DRAWONLYFORP2; + else + mobj->eflags &= ~MFE_DRAWONLYFORP2; + + if (mobj->target->eflags & MFE_DRAWONLYFORP3) + mobj->eflags |= MFE_DRAWONLYFORP3; + else + mobj->eflags &= ~MFE_DRAWONLYFORP3; + + if (mobj->target->eflags & MFE_DRAWONLYFORP4) + mobj->eflags |= MFE_DRAWONLYFORP4; + else + mobj->eflags &= ~MFE_DRAWONLYFORP4; + if (mobj->target->flags2 & MF2_DONTDRAW) mobj->flags2 |= MF2_DONTDRAW; else @@ -6925,6 +6990,9 @@ void P_MobjThinker(mobj_t *mobj) else if (mobj->target->player->kartstuff[k_banana]) P_SetMobjState(mobj, S_PLAYERARROW_BANANA); else if (mobj->target->player->kartstuff[k_greenshell]) P_SetMobjState(mobj, S_PLAYERARROW_GREENSHELL); else if (mobj->target->player->kartstuff[k_mushroom]) P_SetMobjState(mobj, S_PLAYERARROW_MUSHROOM); + else if (mobj->target->player->kartstuff[k_mushroom] + && mobj->target->player->kartstuff[k_mushroomtimer] > 1 + && !(leveltime & 1)) P_SetMobjState(mobj, S_PLAYERARROW_EMPTY); // S_INVISIBLE else P_SetMobjState(mobj, S_PLAYERARROW); // S_INVISIBLE scale += FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayer].mo->x-mobj->target->x, @@ -9169,7 +9237,8 @@ void P_SpawnPrecipitation(void) subsector_t *precipsector = NULL; precipmobj_t *rainmo = NULL; - if (dedicated || !cv_precipdensity.value || curWeather == PRECIP_NONE) + if (dedicated || !cv_precipdensity.value || curWeather == PRECIP_NONE + || netgame) // SRB2Kart return; // Use the blockmap to narrow down our placing patterns diff --git a/src/p_mobj.h b/src/p_mobj.h index 3617ea40..919a3d58 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -233,11 +233,17 @@ typedef enum MFE_VERTICALFLIP = 1<<5, // Goo water MFE_GOOWATER = 1<<6, - // free: to and including 1<<7 + // SRB2Kart: The mobj just hit & bounced off a wall, this is cleared on next frame + MFE_JUSTBOUNCEDWALL = 1<<7, // Mobj was already sprung this tic MFE_SPRUNG = 1<<8, // Platform movement MFE_APPLYPMOMZ = 1<<9, + // SRB2Kart: Splitscreen sprite display; very wasteful but I couldn't think of another way to do it... + MFE_DRAWONLYFORP1 = 1<<10, + MFE_DRAWONLYFORP2 = 1<<11, + MFE_DRAWONLYFORP3 = 1<<12, + MFE_DRAWONLYFORP4 = 1<<13, // free: to and including 1<<15 } mobjeflag_t; diff --git a/src/p_saveg.c b/src/p_saveg.c index e1a9944a..0fc69ad3 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3248,11 +3248,16 @@ static void P_NetArchiveMisc(void) WRITEUINT32(save_p, hidetime); // SRB2kart + WRITEINT32(save_p, numgotboxes); + WRITEUINT8(save_p, gamespeed); WRITEUINT8(save_p, mirrormode); WRITEUINT8(save_p, franticitems); WRITEUINT8(save_p, comeback); - WRITEINT32(save_p, numgotboxes); // Probably shouldn't need nummapboxes + + WRITEUINT32(save_p, lightningcooldown); + WRITEUINT32(save_p, blueshellincoming); + WRITEUINT8(save_p, blueshellplayer); // Is it paused? if (paused) @@ -3340,11 +3345,16 @@ static inline boolean P_NetUnArchiveMisc(void) hidetime = READUINT32(save_p); // SRB2kart + numgotboxes = READINT32(save_p); + gamespeed = READUINT8(save_p); mirrormode = (boolean)READUINT8(save_p); franticitems = (boolean)READUINT8(save_p); comeback = (boolean)READUINT8(save_p); - numgotboxes = READINT32(save_p); + + lightningcooldown = READUINT32(save_p); + blueshellincoming = READUINT32(save_p); + blueshellplayer = READUINT8(save_p); // Is it paused? if (READUINT8(save_p) == 0x2f) diff --git a/src/p_setup.c b/src/p_setup.c index 3deabb76..bc29cc6c 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -179,8 +179,8 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) mapheaderinfo[num]->subttl[0] = '\0'; DEH_WriteUndoline("ZONETITLE", mapheaderinfo[num]->zonttl, UNDO_NONE); // SRB2kart mapheaderinfo[num]->zonttl[0] = '\0'; - DEH_WriteUndoline("ACT", va("%d", mapheaderinfo[num]->actnum), UNDO_NONE); - mapheaderinfo[num]->actnum = 0; + DEH_WriteUndoline("ACT", mapheaderinfo[num]->actnum, UNDO_NONE); // SRB2kart + mapheaderinfo[num]->actnum[0] = '\0'; DEH_WriteUndoline("TYPEOFLEVEL", va("%d", mapheaderinfo[num]->typeoflevel), UNDO_NONE); mapheaderinfo[num]->typeoflevel = 0; DEH_WriteUndoline("NEXTLEVEL", va("%d", mapheaderinfo[num]->nextlevel), UNDO_NONE); @@ -2674,19 +2674,19 @@ boolean P_SetupLevel(boolean skipprecip) } // Print "SPEEDING OFF TO [ZONE] [ACT 1]..." - if (rendermode != render_none) + /*if (rendermode != render_none) { // Don't include these in the fade! char tx[64]; V_DrawSmallString(1, 191, V_ALLOWLOWERCASE, M_GetText("Speeding off to...")); snprintf(tx, 63, "%s%s%s", mapheaderinfo[gamemap-1]->lvlttl, - (strlen(mapheaderinfo[gamemap-1]->zonttl) > 0) ? mapheaderinfo[gamemap-1]->zonttl : // SRB2kart + (strlen(mapheaderinfo[gamemap-1]->zonttl) > 0) ? va(" %s",mapheaderinfo[gamemap-1]->zonttl) : // SRB2kart ((mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE) ? "" : " ZONE"), - (mapheaderinfo[gamemap-1]->actnum > 0) ? va(", Act %d",mapheaderinfo[gamemap-1]->actnum) : ""); + (strlen(mapheaderinfo[gamemap-1]->actnum) > 0) ? va(", Act %s",mapheaderinfo[gamemap-1]->actnum) : ""); V_DrawSmallString(1, 195, V_ALLOWLOWERCASE, tx); I_UpdateNoVsync(); - } + }*/ #ifdef HAVE_BLUA LUA_InvalidateLevel(); @@ -3003,6 +3003,10 @@ boolean P_SetupLevel(boolean skipprecip) comeback = cv_kartcomeback.value; } + lightningcooldown = 0; + blueshellincoming = 0; + blueshellplayer = 0; + // clear special respawning que iquehead = iquetail = 0; @@ -3039,7 +3043,7 @@ boolean P_SetupLevel(boolean skipprecip) if (!(netgame || multiplayer || demoplayback || demorecording || metalrecording || modeattacking || players[consoleplayer].lives <= 0) && (!modifiedgame || savemoddata) && cursaveslot >= 0 && !ultimatemode && !(mapheaderinfo[gamemap-1]->menuflags & LF2_HIDEINMENU) - && (!G_IsSpecialStage(gamemap)) && gamemap != lastmapsaved && (mapheaderinfo[gamemap-1]->actnum < 2 || gamecomplete)) + && (!G_IsSpecialStage(gamemap)) && gamemap != lastmapsaved && (/*mapheaderinfo[gamemap-1]->actnum < 2 ||*/ gamecomplete)) G_SaveGame((UINT32)cursaveslot); if (savedata.lives > 0) diff --git a/src/p_spec.c b/src/p_spec.c index 18314c2e..7883a2ca 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4210,7 +4210,9 @@ DoneSection2: if (P_IsLocalPlayer(player)) { // SRB2kart 200117 - if (!splitscreen) + if (splitscreen) + S_ChangeMusicInternal("karwin", true); + else { if (player->kartstuff[k_position] == 1) S_ChangeMusicInternal("karwin", true); @@ -4219,8 +4221,6 @@ DoneSection2: else S_ChangeMusicInternal("karok", true); } - else - S_ChangeMusicInternal("karok", true); } if (player->kartstuff[k_position] == 1) diff --git a/src/p_tick.c b/src/p_tick.c index 84c36835..8235e8d5 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -677,6 +677,38 @@ void P_Ticker(boolean run) if (countdown2) countdown2--; + if (blueshellincoming && --blueshellincoming <= 0) + { + UINT8 best = 0; + SINT8 hurtthisguy = -1; + + blueshellincoming = 0; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator) + continue; + + if (!players[i].mo) + continue; + + if (players[i].exiting) + continue; + + if (best <= 0 || players[i].kartstuff[k_position] < best) + { + best = players[i].kartstuff[k_position]; + hurtthisguy = i; + } + } + + if (hurtthisguy != -1) + players[hurtthisguy].kartstuff[k_deathsentence] = TICRATE+1; + } + + if (lightningcooldown) + lightningcooldown--; + if (quake.time) { fixed_t ir = quake.intensity>>1; diff --git a/src/p_user.c b/src/p_user.c index 4666141c..6ef87bcd 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1165,7 +1165,22 @@ void P_RestoreMusic(player_t *player) S_SpeedMusic(1.0f); // SRB2kart - We have some different powers than vanilla, some of which tweak the music. - if (!player->exiting) + if (splitscreen != 0 && G_RaceGametype() + && (players[consoleplayer].exiting + || players[secondarydisplayplayer].exiting + || players[thirddisplayplayer].exiting + || players[fourthdisplayplayer].exiting)) + S_ChangeMusicInternal("karwin", true); + else if (splitscreen == 0 && G_RaceGametype() && player->exiting) + { + if (player->kartstuff[k_position] == 1) + S_ChangeMusicInternal("karwin", true); + else if (K_IsPlayerLosing(player)) + S_ChangeMusicInternal("karlos", true); + else + S_ChangeMusicInternal("karok", true); + } + else { // Item - Mega Mushroom if (player->kartstuff[k_growshrinktimer] > 1 && player->playerstate == PST_LIVE) @@ -1176,7 +1191,7 @@ void P_RestoreMusic(player_t *player) else if (leveltime > 157) { // Event - Final Lap - if (player->laps == (UINT8)(cv_numlaps.value - 1)) + if (G_RaceGametype() && player->laps >= (UINT8)(cv_numlaps.value - 1)) S_SpeedMusic(1.2f); S_ChangeMusic(mapmusname, mapmusflags, true); } @@ -4670,7 +4685,6 @@ static void P_3dMovement(player_t *player) angle_t movepushangle, movepushsideangle; // Analog //INT32 topspeed, acceleration, thrustfactor; fixed_t movepushforward = 0, movepushside = 0; - INT32 mforward = 0, mbackward = 0; angle_t dangle; // replaces old quadrants bits //boolean dangleflip = false; // SRB2kart - toaster //fixed_t normalspd = FixedMul(player->normalspeed, player->mo->scale); @@ -4758,12 +4772,6 @@ static void P_3dMovement(player_t *player) //dangleflip = true; } - // now use it to determine direction! - if (dangle <= ANGLE_45) // angles 0-45 or 315-360 - mforward = 1; // going forwards - else if (dangle >= ANGLE_135) // angles 135-225 - mbackward = 1; // going backwards - // anything else will leave both at 0, so no need to do anything else //{ SRB2kart 220217 - Toaster Code for misplaced thrust @@ -4789,104 +4797,13 @@ static void P_3dMovement(player_t *player) cmd->forwardmove = 0; // Do not let the player control movement if not onground. - onground = P_IsObjectOnGround(player->mo); - - // SRB2Kart: shhhhhhh don't question me, feather and speed bumps are supposed to control like you're on the ground :p - if (player->kartstuff[k_feather] & 2) - onground = true; + // SRB2Kart: feather and speed bumps are supposed to control like you're on the ground + onground = (P_IsObjectOnGround(player->mo) || (player->kartstuff[k_feather] & 2)); player->aiming = cmd->aiming<pflags & PF_SLIDING) - { - normalspd = FixedMul(36<mo->scale); - thrustfactor = 5; - acceleration = 96 + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * 40; - topspeed = normalspd; - } - else if (player->bot) - { // Bot steals player 1's stats - normalspd = FixedMul(players[consoleplayer].normalspeed, player->mo->scale); - thrustfactor = players[consoleplayer].thrustfactor; - acceleration = players[consoleplayer].accelstart + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * players[consoleplayer].acceleration; - - if (player->powers[pw_tailsfly]) - topspeed = normalspd/2; - else if (player->mo->eflags & (MFE_UNDERWATER|MFE_GOOWATER)) - { - topspeed = normalspd/2; - acceleration = 2*acceleration/3; - } - else - topspeed = normalspd; - } - else if (player->powers[pw_super] || player->powers[pw_sneakers] || player->kartstuff[k_startimer] || player->kartstuff[k_mushroomtimer]) - { - if (player->powers[pw_sneakers] && (player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_mushroomtimer] > 0 || player->kartstuff[k_startimer] > 0)) - thrustfactor = player->thrustfactor*3; - else - thrustfactor = player->thrustfactor*2; - acceleration = player->accelstart/2 + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration/2; - - - if (player->powers[pw_tailsfly]) - topspeed = normalspd; - else if (player->mo->eflags & (MFE_UNDERWATER|MFE_GOOWATER)) - { - topspeed = normalspd; - acceleration = 2*acceleration/3; - } - - if (cmd->forwardmove < 0) - topspeed = 5<<16; - else - topspeed = (normalspd * 3)/2; //> 60<<16 ? 60<<16 : normalspd * 2; - } - else - { - thrustfactor = player->thrustfactor; - acceleration = player->accelstart + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration; - - - if (player->powers[pw_tailsfly]) - topspeed = normalspd/2; - else if (player->mo->eflags & (MFE_UNDERWATER|MFE_GOOWATER)) - { - topspeed = normalspd/2; - acceleration = 2*acceleration/3; - } - if (cmd->forwardmove < 0) - topspeed = 5<<16; - else - topspeed = normalspd; - } - - // Better maneuverability while flying - //if(player->powers[pw_tailsfly]) - //{ - // thrustfactor = player->thrustfactor*2; - // acceleration = player->accelstart + (FixedDiv(player->speed, player->mo->scale)>>FRACBITS) * player->acceleration; - //} - - if (player->mo->movefactor != FRACUNIT) // Friction-scaled acceleration... - acceleration = FixedMul(acceleration<mo->movefactor)>>FRACBITS; - */ - // Forward movement - if (player->climbing) - { - if (cmd->forwardmove) - { - P_SetObjectMomZ(player->mo, FixedDiv(cmd->forwardmove*FRACUNIT, 10*FRACUNIT), false); - if (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])) - player->mo->momz *= 2; - } - } - else if (!analogmove - //&& cmd->forwardmove != 0 - && !(player->pflags & PF_GLIDING || player->exiting - || (P_PlayerInPain(player) && !onground))) + if (!(player->exiting || (P_PlayerInPain(player) && !onground))) { //movepushforward = cmd->forwardmove * (thrustfactor * acceleration); movepushforward = K_3dKartMovement(player, onground, cmd->forwardmove); @@ -4895,25 +4812,14 @@ static void P_3dMovement(player_t *player) if (!onground) movepushforward >>= 2; // proper air movement - // Allow a bit of movement while spinning - if (player->pflags & PF_SPINNING) - { - if ((mforward && cmd->forwardmove > 0) || (mbackward && cmd->forwardmove < 0)) - movepushforward = 0; - else if (!(player->pflags & PF_STARTDASH)) - movepushforward = FixedDiv(movepushforward, 16*FRACUNIT); - else - movepushforward = 0; - } - // don't need to account for scale here with kart accel code //movepushforward = FixedMul(movepushforward, player->mo->scale); if (player->mo->movefactor != FRACUNIT) // Friction-scaled acceleration... movepushforward = FixedMul(movepushforward, player->mo->movefactor); - //if (mforward && cmd->forwardmove < 0) // SRB2kart - braking isn't instant - // movepushforward /= 32; + if (cmd->buttons & BT_BRAKE && !cmd->forwardmove) // SRB2kart - braking isn't instant + movepushforward /= 64; #ifdef ESLOPE totalthrust.x += P_ReturnThrustX(player->mo, movepushangle, movepushforward); @@ -4926,91 +4832,14 @@ static void P_3dMovement(player_t *player) { K_MomentumToFacing(player); } + // Sideways movement - if (player->climbing) + if (cmd->sidemove != 0 && !(player->exiting || (P_PlayerInPain(player)))) { - if (player->powers[pw_super] && ALL7EMERALDS(player->powers[pw_emeralds])) - P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedMul(FixedDiv(cmd->sidemove*FRACUNIT, 5*FRACUNIT), player->mo->scale)); - else - P_InstaThrust(player->mo, player->mo->angle-ANGLE_90, FixedMul(FixedDiv(cmd->sidemove*FRACUNIT, 10*FRACUNIT), player->mo->scale)); - } - // Analog movement control - else if (analogmove) - { - if (!(player->pflags & PF_GLIDING || player->exiting || P_PlayerInPain(player))) - { - angle_t controldirection; - - // Calculate the angle at which the controls are pointing - // to figure out the proper mforward and mbackward. - // (Why was it so complicated before? ~Red) - controldirection = R_PointToAngle2(0, 0, cmd->forwardmove*FRACUNIT, -cmd->sidemove*FRACUNIT)+movepushangle; - - //movepushforward = max(abs(cmd->sidemove), abs(cmd->forwardmove)) * (thrustfactor * acceleration); - movepushforward = K_3dKartMovement(player, onground, max(abs(cmd->sidemove), abs(cmd->forwardmove))); - - // allow very small movement while in air for gameplay - if (!onground) - movepushforward >>= 2; // proper air movement - - // Allow a bit of movement while spinning - if (player->pflags & PF_SPINNING) - { - // Stupid little movement prohibitor hack - // that REALLY shouldn't belong in analog code. - if ((mforward && cmd->forwardmove > 0) || (mbackward && cmd->forwardmove < 0)) - movepushforward = 0; - else if (!(player->pflags & PF_STARTDASH)) - movepushforward = FixedDiv(movepushforward, 16*FRACUNIT); - else - movepushforward = 0; - } - - movepushsideangle = controldirection; - - // don't need to account for scale here with kart accel code - //movepushforward = FixedMul(movepushforward, player->mo->scale); - - //if (mforward && cmd->forwardmove < 0) // SRB2kart - braking isn't instant - // movepushforward /= 32; - -#ifdef ESLOPE - totalthrust.x += P_ReturnThrustX(player->mo, controldirection, movepushforward); - totalthrust.y += P_ReturnThrustY(player->mo, controldirection, movepushforward); -#else - P_Thrust(player->mo, controldirection, movepushforward); -#endif - } - } - else if (cmd->sidemove && !(player->pflags & PF_GLIDING) && !player->exiting && !P_PlayerInPain(player)) - { - //movepushside = cmd->sidemove * (thrustfactor * acceleration); if (cmd->sidemove > 0) - movepushside = K_3dKartMovement(player, onground, 50); + movepushside = (cmd->sidemove * FRACUNIT/128) + FixedDiv(player->speed, K_GetKartSpeed(player, true)); else - movepushside = -(K_3dKartMovement(player, onground, 50)); - - if (!onground) - { - movepushside >>= 2; - - // Reduce movepushslide even more if over "max" flight speed - if (player->powers[pw_tailsfly] && player->speed > K_GetKartSpeed(player, true)) //topspeed) - movepushside >>= 2; - } - - // Allow a bit of movement while spinning - if (player->pflags & PF_SPINNING) - { - if (!(player->pflags & PF_STARTDASH)) - movepushside = FixedDiv(movepushside,16*FRACUNIT); - else - movepushside = 0; - } - - // Finally move the player now that his speed/direction has been decided. - // don't need to account for scale here with kart accel code - //movepushside = FixedMul(movepushside, player->mo->scale); + movepushside = (cmd->sidemove * FRACUNIT/128) - FixedDiv(player->speed, K_GetKartSpeed(player, true)); #ifdef ESLOPE totalthrust.x += P_ReturnThrustX(player->mo, movepushsideangle, movepushside); @@ -6482,13 +6311,13 @@ void P_ElementalFireTrail(player_t *player) } } -static void P_SkidStuff(player_t *player) +/*static void P_SkidStuff(player_t *player) { fixed_t pmx = player->rmomx + player->cmomx; fixed_t pmy = player->rmomy + player->cmomy; // Knuckles glides into the dirt. - /* // SRB2kart - don't need + // SRB2kart - don't need if (player->pflags & PF_GLIDING && player->skidtime) { // Fell off a ledge... @@ -6526,7 +6355,7 @@ static void P_SkidStuff(player_t *player) } } // Skidding! - else*/if (onground && !(player->mo->eflags & MFE_GOOWATER) && !(player->pflags & (PF_JUMPED|PF_SPINNING|PF_SLIDING)) && !(player->charflags & SF_NOSKID)) + elseif (onground && !(player->mo->eflags & MFE_GOOWATER) && !(player->pflags & (PF_JUMPED|PF_SPINNING|PF_SLIDING)) && !(player->charflags & SF_NOSKID)) { if (player->skidtime) { @@ -6573,7 +6402,7 @@ static void P_SkidStuff(player_t *player) S_StopSound(player->mo); } } -} +}*/ // // P_MovePlayer @@ -6748,7 +6577,7 @@ static void P_MovePlayer(player_t *player) if (maptol & TOL_2D) runspd = FixedMul(runspd, 2*FRACUNIT/3); - P_SkidStuff(player); + //P_SkidStuff(player); ///////////////////////// // MOVEMENT ANIMATIONS // @@ -10129,3 +9958,4 @@ void P_PlayerAfterThink(player_t *player) K_KartPlayerAfterThink(player); } + diff --git a/src/r_bsp.c b/src/r_bsp.c index 10fac7a5..234d6ee0 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -855,7 +855,7 @@ static void R_AddPolyObjects(subsector_t *sub) drawseg_t *firstseg; -static void R_Subsector(size_t num) +static void R_Subsector(size_t num, UINT8 ssplayer) { INT32 count, floorlightlevel, ceilinglightlevel, light; seg_t *line; @@ -1213,7 +1213,7 @@ static void R_Subsector(size_t num) // Either you must pass the fake sector and handle validcount here, on the // real sector, or you must account for the lighting in some other way, // like passing it as an argument. - R_AddSprites(sub->sector, (floorlightlevel+ceilinglightlevel)/2); + R_AddSprites(sub->sector, (floorlightlevel+ceilinglightlevel)/2, ssplayer); firstseg = NULL; @@ -1419,7 +1419,7 @@ INT32 R_GetPlaneLight(sector_t *sector, fixed_t planeheight, boolean underside) // // killough 5/2/98: reformatted, removed tail recursion -void R_RenderBSPNode(INT32 bspnum) +void R_RenderBSPNode(INT32 bspnum, UINT8 ssplayer) { node_t *bsp; INT32 side; @@ -1430,7 +1430,7 @@ void R_RenderBSPNode(INT32 bspnum) // Decide which side the view point is on. side = R_PointOnSide(viewx, viewy, bsp); // Recursively divide front space. - R_RenderBSPNode(bsp->children[side]); + R_RenderBSPNode(bsp->children[side], ssplayer); // Possibly divide back space. @@ -1448,5 +1448,5 @@ void R_RenderBSPNode(INT32 bspnum) portalcullsector = NULL; } - R_Subsector(bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR); + R_Subsector(bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR, ssplayer); } diff --git a/src/r_bsp.h b/src/r_bsp.h index e871b5dd..db340221 100644 --- a/src/r_bsp.h +++ b/src/r_bsp.h @@ -37,7 +37,7 @@ extern INT32 doorclosed; void R_ClearClipSegs(void); void R_PortalClearClipSegs(INT32 start, INT32 end); void R_ClearDrawSegs(void); -void R_RenderBSPNode(INT32 bspnum); +void R_RenderBSPNode(INT32 bspnum, UINT8 ssplayer); void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2); #ifdef POLYOBJECTS diff --git a/src/r_main.c b/src/r_main.c index 82b2b6d5..c516b87a 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1335,6 +1335,18 @@ void R_RenderPlayerView(player_t *player) { portal_pair *portal; const boolean skybox = (skyboxmo[0] && cv_skybox.value); + UINT8 ssplayer; + + if (player == &players[secondarydisplayplayer] && splitscreen) + ssplayer = 2; + else if (player == &players[thirddisplayplayer] && splitscreen > 1) + ssplayer = 3; + else if (player == &players[fourthdisplayplayer] && splitscreen > 2) + ssplayer = 4; + else if (splitscreen) + ssplayer = 1; + else + ssplayer = 0; if (cv_homremoval.value && player == &players[displayplayer]) // if this is display player 1 { @@ -1371,7 +1383,7 @@ void R_RenderPlayerView(player_t *player) R_ClearVisibleFloorSplats(); #endif - R_RenderBSPNode((INT32)numnodes - 1); + R_RenderBSPNode((INT32)numnodes - 1, ssplayer); R_ClipSprites(); R_DrawPlanes(); #ifdef FLOORSPLATS @@ -1404,7 +1416,7 @@ void R_RenderPlayerView(player_t *player) mytotal = 0; ProfZeroTimer(); #endif - R_RenderBSPNode((INT32)numnodes - 1); + R_RenderBSPNode((INT32)numnodes - 1, ssplayer); R_ClipSprites(); #ifdef TIMING RDMSR(0x10, &mycount); @@ -1429,7 +1441,7 @@ void R_RenderPlayerView(player_t *player) validcount++; - R_RenderBSPNode((INT32)numnodes - 1); + R_RenderBSPNode((INT32)numnodes - 1, ssplayer); R_ClipSprites(); //R_DrawPlanes(); //R_DrawMasked(); diff --git a/src/r_things.c b/src/r_things.c index 541a7816..7309f452 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -29,6 +29,7 @@ #include "d_netfil.h" // blargh. for nameonly(). #include "m_cheat.h" // objectplace #include "k_kart.h" // SRB2kart +#include "p_local.h" // stplyr #ifdef HWRENDER #include "hardware/hw_md2.h" #endif @@ -1675,7 +1676,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) // R_AddSprites // During BSP traversal, this adds sprites by sector. // -void R_AddSprites(sector_t *sec, INT32 lightlevel) +void R_AddSprites(sector_t *sec, INT32 lightlevel, UINT8 ssplayer) { mobj_t *thing; precipmobj_t *precipthing; // Tails 08-25-2002 @@ -1718,6 +1719,25 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel) if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW) continue; + if (splitscreen) + { + if (thing->eflags & MFE_DRAWONLYFORP1) + if (ssplayer != 1) + continue; + + if (thing->eflags & MFE_DRAWONLYFORP2) + if (ssplayer != 2) + continue; + + if (thing->eflags & MFE_DRAWONLYFORP3 && splitscreen > 1) + if (ssplayer != 3) + continue; + + if (thing->eflags & MFE_DRAWONLYFORP4 && splitscreen > 2) + if (ssplayer != 4) + continue; + } + approx_dist = P_AproxDistance(viewx-thing->x, viewy-thing->y); if (approx_dist <= limit_dist) @@ -1728,8 +1748,31 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel) { // Draw everything in sector, no checks for (thing = sec->thinglist; thing; thing = thing->snext) - if (!(thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW)) - R_ProjectSprite(thing); + { + if (thing->sprite == SPR_NULL || thing->flags2 & MF2_DONTDRAW) + continue; + + if (splitscreen) + { + if (thing->eflags & MFE_DRAWONLYFORP1) + if (ssplayer != 1) + continue; + + if (thing->eflags & MFE_DRAWONLYFORP2) + if (ssplayer != 2) + continue; + + if (thing->eflags & MFE_DRAWONLYFORP3 && splitscreen > 1) + if (ssplayer != 3) + continue; + + if (thing->eflags & MFE_DRAWONLYFORP4 && splitscreen > 2) + if (ssplayer != 4) + continue; + } + + R_ProjectSprite(thing); + } } // Someone seriously wants infinite draw distance for precipitation? diff --git a/src/r_things.h b/src/r_things.h index 347f204f..c7d4989c 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -55,7 +55,7 @@ void R_DelSpriteDefs(UINT16 wadnum); #endif //SoM: 6/5/2000: Light sprites correctly! -void R_AddSprites(sector_t *sec, INT32 lightlevel); +void R_AddSprites(sector_t *sec, INT32 lightlevel, UINT8 ssplayer); void R_InitSprites(void); void R_ClearSprites(void); void R_ClipSprites(void); diff --git a/src/st_stuff.c b/src/st_stuff.c index 0e0e9749..33f7a275 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -77,7 +77,7 @@ static patch_t *race1; static patch_t *race2; static patch_t *race3; static patch_t *racego; -static patch_t *ttlnum; +//static patch_t *ttlnum; static patch_t *nightslink; static patch_t *count5; static patch_t *count4; @@ -753,7 +753,7 @@ static void ST_drawLevelTitle(void) char *lvlttl = mapheaderinfo[gamemap-1]->lvlttl; char *subttl = mapheaderinfo[gamemap-1]->subttl; char *zonttl = mapheaderinfo[gamemap-1]->zonttl; // SRB2kart - INT32 actnum = mapheaderinfo[gamemap-1]->actnum; + char *actnum = mapheaderinfo[gamemap-1]->actnum; INT32 lvlttlxpos; INT32 subttlxpos = BASEVIDWIDTH/2; INT32 ttlnumxpos; @@ -765,11 +765,8 @@ static void ST_drawLevelTitle(void) if (!(timeinmap > 2 && timeinmap-3 < 110)) return; - if (actnum > 0) - { - ttlnum = W_CachePatchName(va("TTL%.2d", actnum), PU_CACHE); - lvlttlxpos = ((BASEVIDWIDTH/2) - (V_LevelNameWidth(lvlttl)/2)) - SHORT(ttlnum->width); - } + if (strlen(actnum) > 0) + lvlttlxpos = ((BASEVIDWIDTH/2) - (V_LevelNameWidth(lvlttl)/2)) - V_LevelNameWidth(actnum); else lvlttlxpos = ((BASEVIDWIDTH/2) - (V_LevelNameWidth(lvlttl)/2)); @@ -801,8 +798,8 @@ static void ST_drawLevelTitle(void) default: zoney = 104; lvlttly = 80; break; } - if (actnum) - V_DrawScaledPatch(ttlnumxpos, zoney, 0, ttlnum); + if (strlen(actnum) > 0) + V_DrawLevelTitle(ttlnumxpos+12, zoney, 0, actnum); V_DrawLevelTitle(lvlttlxpos, lvlttly, 0, lvlttl); diff --git a/src/v_video.c b/src/v_video.c index 801a577f..ac0eed17 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1774,7 +1774,7 @@ void V_DrawLevelTitle(INT32 x, INT32 y, INT32 option, const char *string) c = toupper(c) - LT_FONTSTART; if (c < 0 || c >= LT_FONTSIZE || !lt_font[c]) { - cx += 16*dupx; + cx += 12*dupx; continue; } @@ -1805,7 +1805,7 @@ INT32 V_LevelNameWidth(const char *string) { c = toupper(string[i]) - LT_FONTSTART; if (c < 0 || c >= LT_FONTSIZE || !lt_font[c]) - w += 16; + w += 12; else w += SHORT(lt_font[c]->width); } diff --git a/src/y_inter.c b/src/y_inter.c index f18edafd..cd56b346 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -38,6 +38,7 @@ #include "m_random.h" // P_RandomKey #include "g_input.h" // PLAYER1INPUTDOWN +#include "k_kart.h" // colortranslations #ifdef HWRENDER #include "hardware/hw_main.h" @@ -197,6 +198,10 @@ static y_voteclient voteclient; static INT32 votetic; static INT32 voteendtic = -1; static patch_t *cursor = NULL; +static patch_t *cursor1 = NULL; +static patch_t *cursor2 = NULL; +static patch_t *cursor3 = NULL; +static patch_t *cursor4 = NULL; static patch_t *randomlvl = NULL; static void Y_UnloadVoteData(void); @@ -290,7 +295,7 @@ void Y_IntermissionDrawer(void) V_DrawLevelTitle(data.coop.passedx1, 49, 0, data.coop.passed1); V_DrawLevelTitle(data.coop.passedx2, 49+V_LevelNameHeight(data.coop.passed2)+2, 0, data.coop.passed2); - if (mapheaderinfo[gamemap-1]->actnum) + if (strlen(mapheaderinfo[prevmap]->actnum) > 0) V_DrawScaledPatch(244, 57, 0, data.coop.ttlnum); //if (gottimebonus && endtic != -1) @@ -1122,10 +1127,10 @@ void Y_StartIntermission(void) data.coop.ptotal = W_CachePatchName("YB_TOTAL", PU_STATIC); // get act number - if (mapheaderinfo[prevmap]->actnum) + /*if (mapheaderinfo[prevmap]->actnum) data.coop.ttlnum = W_CachePatchName(va("TTL%.2d", mapheaderinfo[prevmap]->actnum), PU_STATIC); - else + else*/ data.coop.ttlnum = W_CachePatchName("TTL01", PU_STATIC); // get background patches @@ -1154,24 +1159,24 @@ void Y_StartIntermission(void) if (strlen(skins[players[consoleplayer].skin].realname) > 13) { strcpy(data.coop.passed1, "YOU GOT"); - strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "THROUGH ACT" : "THROUGH THE ACT"); + strcpy(data.coop.passed2, (strlen(mapheaderinfo[prevmap]->actnum) > 0) ? "THROUGH ACT" : "THROUGH THE ACT"); } // long enough that "X GOT" won't fit so use "X PASSED THE ACT" else if (strlen(skins[players[consoleplayer].skin].realname) > 8) { strcpy(data.coop.passed1, skins[players[consoleplayer].skin].realname); - strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "PASSED ACT" : "PASSED THE ACT"); + strcpy(data.coop.passed2, (strlen(mapheaderinfo[prevmap]->actnum) > 0) ? "PASSED ACT" : "PASSED THE ACT"); } // length is okay for normal use else { snprintf(data.coop.passed1, sizeof data.coop.passed1, "%s GOT", skins[players[consoleplayer].skin].realname); - strcpy(data.coop.passed2, (mapheaderinfo[gamemap-1]->actnum) ? "THROUGH ACT" : "THROUGH THE ACT"); + strcpy(data.coop.passed2, (strlen(mapheaderinfo[prevmap]->actnum) > 0) ? "THROUGH ACT" : "THROUGH THE ACT"); } // set X positions - if (mapheaderinfo[gamemap-1]->actnum) + if (strlen(mapheaderinfo[prevmap]->actnum) > 0) { data.coop.passedx1 = 62 + (176 - V_LevelNameWidth(data.coop.passed1))/2; data.coop.passedx2 = 62 + (176 - V_LevelNameWidth(data.coop.passed2))/2; @@ -1312,12 +1317,12 @@ void Y_StartIntermission(void) Y_CalculateMatchWinners(); // set up the levelstring - if (mapheaderinfo[prevmap]->zonttl) + if (strlen(mapheaderinfo[prevmap]->zonttl) > 0) { - if (mapheaderinfo[prevmap]->actnum) + if (strlen(mapheaderinfo[prevmap]->actnum) > 0) snprintf(data.match.levelstring, sizeof data.match.levelstring, - "%.32s %.32s * %d *", + "%.32s %.32s * %s *", mapheaderinfo[prevmap]->lvlttl, mapheaderinfo[prevmap]->zonttl, mapheaderinfo[prevmap]->actnum); else snprintf(data.match.levelstring, @@ -1327,10 +1332,10 @@ void Y_StartIntermission(void) } else { - if (mapheaderinfo[prevmap]->actnum) + if (strlen(mapheaderinfo[prevmap]->actnum) > 0) snprintf(data.match.levelstring, sizeof data.match.levelstring, - "%.32s * %d *", + "%.32s * %s *", mapheaderinfo[prevmap]->lvlttl, mapheaderinfo[prevmap]->actnum); else snprintf(data.match.levelstring, @@ -1375,12 +1380,12 @@ void Y_StartIntermission(void) Y_CalculateTournamentPoints(); // set up the levelstring - if (mapheaderinfo[prevmap]->zonttl) + if (strlen(mapheaderinfo[prevmap]->zonttl) > 0) { - if (mapheaderinfo[prevmap]->actnum) + if (strlen(mapheaderinfo[prevmap]->actnum) > 0) snprintf(data.match.levelstring, sizeof data.match.levelstring, - "%.32s %.32s * %d *", + "%.32s %.32s * %s *", mapheaderinfo[prevmap]->lvlttl, mapheaderinfo[prevmap]->zonttl, mapheaderinfo[prevmap]->actnum); else snprintf(data.match.levelstring, @@ -1390,10 +1395,10 @@ void Y_StartIntermission(void) } else { - if (mapheaderinfo[prevmap]->actnum) + if (strlen(mapheaderinfo[prevmap]->actnum) > 0) snprintf(data.match.levelstring, sizeof data.match.levelstring, - "%.32s * %d *", + "%.32s * %s *", mapheaderinfo[prevmap]->lvlttl, mapheaderinfo[prevmap]->actnum); else snprintf(data.match.levelstring, @@ -1420,10 +1425,10 @@ void Y_StartIntermission(void) Y_CalculateMatchWinners(); // set up the levelstring - if (mapheaderinfo[prevmap]->actnum) + if (strlen(mapheaderinfo[prevmap]->actnum) > 0) snprintf(data.match.levelstring, sizeof data.match.levelstring, - "%.32s * %d *", + "%.32s * %s *", mapheaderinfo[prevmap]->lvlttl, mapheaderinfo[prevmap]->actnum); else snprintf(data.match.levelstring, @@ -1456,10 +1461,10 @@ void Y_StartIntermission(void) Y_CalculateCompetitionWinners(); // set up the levelstring - if (mapheaderinfo[prevmap]->actnum) + if (strlen(mapheaderinfo[prevmap]->actnum) > 0) snprintf(data.competition.levelstring, sizeof data.competition.levelstring, - "%.32s * %d *", + "%.32s * %s *", mapheaderinfo[prevmap]->lvlttl, mapheaderinfo[prevmap]->actnum); else snprintf(data.competition.levelstring, @@ -2201,33 +2206,53 @@ void Y_VoteDrawer(void) for (j = 0; j <= splitscreen; j++) // another loop for drawing the selection backgrounds in the right order, grumble grumble.. { INT32 handy = y; + UINT8 *colormap; + patch_t *thiscurs; if (voteclient.playerinfo[j].selection != i) continue; - switch (j) + if (splitscreen == 0) { - case 1: - color = 215; - break; - case 2: - color = 127; - break; - case 3: - color = 161; - break; - default: - color = 103; - break; + thiscurs = cursor; + color = colortranslations[players[consoleplayer].skincolor][7]; + colormap = NULL; + } + else + { + switch (j) + { + case 1: + thiscurs = cursor2; + color = colortranslations[players[secondarydisplayplayer].skincolor][7]; + colormap = R_GetTranslationColormap(-1, players[secondarydisplayplayer].skincolor, GTC_CACHE); + break; + case 2: + thiscurs = cursor3; + color = colortranslations[players[thirddisplayplayer].skincolor][7]; + colormap = R_GetTranslationColormap(-1, players[thirddisplayplayer].skincolor, GTC_CACHE); + break; + case 3: + thiscurs = cursor4; + color = colortranslations[players[fourthdisplayplayer].skincolor][7]; + colormap = R_GetTranslationColormap(-1, players[fourthdisplayplayer].skincolor, GTC_CACHE); + break; + default: + thiscurs = cursor1; + color = colortranslations[players[consoleplayer].skincolor][7]; + colormap = R_GetTranslationColormap(-1, players[consoleplayer].skincolor, GTC_CACHE); + break; + } } handy += 6*(3-splitscreen) + (13*j); - V_DrawScaledPatch(BASEVIDWIDTH-124, handy, V_SNAPTORIGHT, cursor); + V_DrawMappedPatch(BASEVIDWIDTH-124, handy, V_SNAPTORIGHT, thiscurs, colormap); if (votetic % 5 == 0) V_DrawFill(BASEVIDWIDTH-100-sizeadd, y-sizeadd, 80+(sizeadd*2), 50+(sizeadd*2), 120|V_SNAPTORIGHT); else V_DrawFill(BASEVIDWIDTH-100-sizeadd, y-sizeadd, 80+(sizeadd*2), 50+(sizeadd*2), color|V_SNAPTORIGHT); + sizeadd--; } @@ -2500,6 +2525,10 @@ void Y_StartVote(void) widebgpatch = W_CachePatchName("INTERSCW", PU_STATIC); bgpatch = W_CachePatchName("INTERSCR", PU_STATIC); cursor = W_CachePatchName("M_CURSOR", PU_STATIC); + cursor1 = W_CachePatchName("P1CURSOR", PU_STATIC); + cursor2 = W_CachePatchName("P2CURSOR", PU_STATIC); + cursor3 = W_CachePatchName("P3CURSOR", PU_STATIC); + cursor4 = W_CachePatchName("P4CURSOR", PU_STATIC); randomlvl = W_CachePatchName("RANDOMLV", PU_STATIC); timer = cv_votetime.value*TICRATE; @@ -2525,12 +2554,12 @@ void Y_StartVote(void) lumpnum_t lumpnum; // set up the str - if (mapheaderinfo[votelevels[i]]->zonttl) + if (strlen(mapheaderinfo[votelevels[i]]->zonttl) > 0) { - if (mapheaderinfo[votelevels[i]]->actnum) + if (strlen(mapheaderinfo[votelevels[i]]->actnum) > 0) snprintf(levelinfo[i].str, sizeof levelinfo[i].str, - "%.32s %.32s %d", + "%.32s %.32s %s", mapheaderinfo[votelevels[i]]->lvlttl, mapheaderinfo[votelevels[i]]->zonttl, mapheaderinfo[votelevels[i]]->actnum); else snprintf(levelinfo[i].str, @@ -2540,10 +2569,10 @@ void Y_StartVote(void) } else { - if (mapheaderinfo[votelevels[i]]->actnum) + if (strlen(mapheaderinfo[votelevels[i]]->actnum) > 0) snprintf(levelinfo[i].str, sizeof levelinfo[i].str, - "%.32s %d", + "%.32s %s", mapheaderinfo[votelevels[i]]->lvlttl, mapheaderinfo[votelevels[i]]->actnum); else snprintf(levelinfo[i].str, @@ -2582,6 +2611,10 @@ static void Y_UnloadVoteData(void) UNLOAD(widebgpatch); UNLOAD(bgpatch); UNLOAD(cursor); + UNLOAD(cursor1); + UNLOAD(cursor2); + UNLOAD(cursor3); + UNLOAD(cursor4); UNLOAD(randomlvl); UNLOAD(levelinfo[3].pic);