diff --git a/src/d_clisrv.c b/src/d_clisrv.c index c0f81ba3..9ea9e842 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -506,6 +506,10 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i) rsp->skin = LONG(players[i].skin); // Just in case Lua does something like // modify these at runtime + // SRB2kart + rsp->kartspeed = (fixed_t)LONG(players[i].kartspeed); + rsp->kartweight = (fixed_t)LONG(players[i].kartweight); + // rsp->normalspeed = (fixed_t)LONG(players[i].normalspeed); rsp->runspeed = (fixed_t)LONG(players[i].runspeed); rsp->thrustfactor = players[i].thrustfactor; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 79ade64f..6ebe8f53 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -168,6 +168,10 @@ typedef struct INT32 skin; // Just in case Lua does something like // modify these at runtime + // SRB2kart + UINT8 kartspeed; + UINT8 kartweight; + // fixed_t normalspeed; fixed_t runspeed; UINT8 thrustfactor; diff --git a/src/d_main.c b/src/d_main.c index d114a843..6023b906 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -259,7 +259,7 @@ static void D_Display(void) { if (intertype == int_spec) // Special Stage wipedefindex = wipe_specinter_toblack; - else if (intertype != int_coop) // Multiplayer + else //if (intertype != int_coop) // Multiplayer wipedefindex = wipe_multinter_toblack; } @@ -642,7 +642,7 @@ void D_StartTitle(void) INT32 i; if (netgame) { - if (gametype == GT_COOP) + if (gametype == GT_RACE) // SRB2kart { G_SetGamestate(GS_WAITINGPLAYERS); // hack to prevent a command repeat @@ -687,7 +687,7 @@ void D_StartTitle(void) playerdeadview = false; displayplayer = consoleplayer = 0; //demosequence = -1; - gametype = GT_COOP; + gametype = GT_RACE; // SRB2kart paused = false; advancedemo = false; F_StartTitleScreen(); @@ -1244,9 +1244,9 @@ void D_SRB2Main(void) // user settings come before "+" parameters. if (dedicated) - COM_ImmedExecute(va("exec \"%s"PATHSEP"adedserv.cfg\"\n", srb2home)); + COM_ImmedExecute(va("exec \"%s"PATHSEP"kartserv.cfg\"\n", srb2home)); else - COM_ImmedExecute(va("exec \"%s"PATHSEP"autoexec.cfg\" -noerror\n", srb2home)); + COM_ImmedExecute(va("exec \"%s"PATHSEP"kartexec.cfg\" -noerror\n", srb2home)); if (!autostart) M_PushSpecialParameters(); // push all "+" parameters at the command buffer diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 50d06424..ab798549 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -351,7 +351,7 @@ static CV_PossibleValue_t timelimit_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NUL consvar_t cv_timelimit = {"timelimit", "0", CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t, TimeLimit_OnChange, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t numlaps_cons_t[] = {{0, "MIN"}, {50, "MAX"}, {0, NULL}}; -consvar_t cv_numlaps = {"numlaps", "4", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t, +consvar_t cv_numlaps = {"numlaps", "3", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t, NumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_usemapnumlaps = {"usemaplaps", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -386,9 +386,9 @@ consvar_t cv_mute = {"mute", "Off", CV_NETVAR|CV_CALL, CV_OnOff, Mute_OnChange, consvar_t cv_sleep = {"cpusleep", "-1", CV_SAVE, sleeping_cons_t, NULL, -1, NULL, NULL, 0, 0, NULL}; -INT16 gametype = GT_COOP; +INT16 gametype = GT_RACE; // SRB2kart boolean splitscreen = false; -boolean circuitmap = false; +boolean circuitmap = true; // SRB2kart INT32 adminplayer = -1; // ========================================================================= @@ -1017,8 +1017,8 @@ UINT8 CanChangeSkin(INT32 playernum) if (gametype == GT_COOP) return true; - // Can change skin during initial countdown. - if ((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE) + // Can change skin during initial countdown. // SRB2kart - Can always change skin in the level + if (gametype == GT_RACE || gametype == GT_COMPETITION) // if ((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE) return true; if (G_TagGametype()) @@ -2601,7 +2601,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) // Clear player score and rings if a spectator. if (players[playernum].spectator) { - players[playernum].score = 0; + //players[playernum].score = 0; // SRB2kart players[playernum].health = 1; if (players[playernum].mo) players[playernum].mo->health = 1; @@ -3453,7 +3453,7 @@ void D_GameTypeChanged(INT32 lastgametype) } else if (!multiplayer && !netgame) { - gametype = GT_COOP; + gametype = GT_RACE; // SRB2kart // These shouldn't matter anymore //CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); //CV_SetValue(&cv_itemrespawn, 0); diff --git a/src/d_player.h b/src/d_player.h index a3286828..06792418 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -247,6 +247,7 @@ typedef enum k_sounds, // Used this to avoid sounds being played every tic k_boosting, // Determines if you're currently shroom-boosting to change how drifting works + k_floorboost, // Prevents Mushroom sounds for a breif duration when triggered by a floor panel k_spinout, // Separate confirmation to prevent endless wipeout loops k_spinouttype, // Determines whether to thrust forward or not while spinning out; 0 = move forwards, 1 = stay still @@ -255,6 +256,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_lakitu, // > 0 = Lakitu fishing, < 0 = Lakitu lap counter (was "player->airtime") // NOTE: Check for ->lakitu, replace with this + k_offroad, // In Super Mario Kart, going offroad has lee-way of about 1 second before you start losing speed k_itemroulette, // Used for the roulette when deciding what item to give you (was "pw_kartitem") k_itemclose, // Used to animate the item window closing (was "pw_psychic") @@ -297,6 +299,7 @@ typedef enum k_tripleredshell, // 0x1 = 1 Red Shell orbiting, 0x2 = 2 Red Shells orbiting // 0x4 = 3 Red Shells orbiting, 0x8 = Triple Red Shell in inventory k_lightning, // 0x1 = Lightning in inventory + k_kitchensink, // 0x1 = Sink in inventory NUMKARTSTUFF } kartstufftype_t; @@ -381,6 +384,11 @@ typedef struct player_s fixed_t dashspeed; // dashing speed INT32 dashtime; // tics dashing, used for rev sound + // SRB2kart + UINT8 kartspeed; // Kart speed stat between 1 and 9 + UINT8 kartweight; // Kart weight stat between 1 and 9 + // + fixed_t normalspeed; // Normal ground fixed_t runspeed; // Speed you break into the run animation UINT8 thrustfactor; // Thrust = thrustfactor * acceleration diff --git a/src/dehacked.c b/src/dehacked.c index 9d4e56af..a55519e8 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -994,6 +994,8 @@ static const struct { {"CHRISTMAS",TOL_XMAS}, {"WINTER",TOL_XMAS}, + {"KART",TOL_KART}, // SRB2kart + {NULL, 0} }; diff --git a/src/doomdef.h b/src/doomdef.h index af7ed97b..06958eb8 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -220,8 +220,8 @@ extern FILE *logstream; // The maximum number of players, multiplayer/networking. // NOTE: it needs more than this to increase the number of players... -#define MAXPLAYERS 32 -#define MAXSKINS MAXPLAYERS +#define MAXPLAYERS 16 +#define MAXSKINS 32 #define PLAYERSMASK (MAXPLAYERS-1) #define MAXPLAYERNAME 21 @@ -325,7 +325,7 @@ typedef enum #define NEWTICRATERATIO 1 // try 4 for 140 fps :) #define NEWTICRATE (TICRATE*NEWTICRATERATIO) -#define RING_DIST 512*FRACUNIT // how close you need to be to a ring to attract it +#define RING_DIST 1280*FRACUNIT // how close you need to be to a ring to attract it #define PUSHACCEL (2*FRACUNIT) // Acceleration for MF2_SLIDEPUSH items. diff --git a/src/doomstat.h b/src/doomstat.h index 4fb391ec..8ac5e5ba 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -249,6 +249,9 @@ typedef struct // (This is not ifdeffed so the map header structure can stay identical, just in case.) UINT8 numCustomOptions; ///< Internal. For Lua custom value support. customoption_t *customopts; ///< Custom options. Allocated dynamically for space reasons. Be careful. + + // SRB2kart + boolean automap; ///< Displays a level's white map outline in modified games } mapheader_t; // level flags @@ -287,7 +290,8 @@ enum TypeOfLevel TOL_MARIO = 0x0200, ///< Mario TOL_NIGHTS = 0x0400, ///< NiGHTS TOL_ERZ3 = 0x0800, ///< ERZ3 - TOL_XMAS = 0x1000 ///< Christmas NiGHTS + TOL_XMAS = 0x1000, ///< Christmas NiGHTS + TOL_KART = 0x4000 ///< Kart 32768 }; // Gametypes diff --git a/src/g_game.c b/src/g_game.c index 6c71e7de..dd9c46b2 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -61,8 +61,9 @@ JoyType_t Joystick2; // 1024 bytes is plenty for a savegame #define SAVEGAMESIZE (1024) -char gamedatafilename[64] = "gamedata.dat"; -char timeattackfolder[64] = "main"; +// SRB2kart +char gamedatafilename[64] = "kartdata.dat"; +char timeattackfolder[64] = "kart"; char customversionstring[32] = "\0"; static void G_DoCompleted(void); @@ -189,7 +190,7 @@ boolean CheckForReverseGravity; // Powerup durations UINT16 invulntics = 20*TICRATE; UINT16 sneakertics = 20*TICRATE; -UINT16 flashingtics = 3*TICRATE; +UINT16 flashingtics = 3*TICRATE/2; // SRB2kart UINT16 tailsflytics = 8*TICRATE; UINT16 underwatertics = 30*TICRATE; UINT16 spacetimetics = 11*TICRATE + (TICRATE/2); @@ -446,7 +447,7 @@ consvar_t cv_firenaxis2 = {"joyaxis2_firenormal", "None", CV_SAVE, joyaxis_cons_ #endif -#if MAXPLAYERS > 32 +#if MAXPLAYERS > 16 #error "please update player_name table using the new value for MAXPLAYERS" #endif @@ -471,24 +472,8 @@ char player_names[MAXPLAYERS][MAXPLAYERNAME+1] = "Player 13", "Player 14", "Player 15", - "Player 16", - "Player 17", - "Player 18", - "Player 19", - "Player 20", - "Player 21", - "Player 22", - "Player 23", - "Player 24", - "Player 25", - "Player 26", - "Player 27", - "Player 28", - "Player 29", - "Player 30", - "Player 31", - "Player 32" -}; + "Player 16" +}; // SRB2kart - removed Players 17 through 32 INT16 rw_maximums[NUM_WEAPONS] = { @@ -1094,12 +1079,13 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics) // some people strafe left & right with mouse buttons // those people are weird + + /* // SRB2kart - these aren't used in kart if (PLAYER1INPUTDOWN(gc_straferight)) side += sidemove[speed]; if (PLAYER1INPUTDOWN(gc_strafeleft)) side -= sidemove[speed]; - /* // SRB2kart - these aren't used in kart if (PLAYER1INPUTDOWN(gc_driftleft)) cmd->buttons |= BT_WEAPONNEXT; // Next Weapon if (PLAYER1INPUTDOWN(gc_driftright)) @@ -1983,6 +1969,7 @@ void G_Ticker(boolean run) { UINT32 i; INT32 buf; + ticcmd_t *cmd; P_MapStart(); // do player reborns if needed @@ -2023,8 +2010,20 @@ void G_Ticker(boolean run) // read/write demo and check turbo cheat for (i = 0; i < MAXPLAYERS; i++) { + cmd = &players[i].cmd; + if (playeringame[i]) - G_CopyTiccmd(&players[i].cmd, &netcmds[buf][i], 1); + G_CopyTiccmd(cmd, &netcmds[buf][i], 1); + + // SRB2kart + // Save the dir the player is holding + // to allow items to be thrown forward or backward. + if (cmd->forwardmove > 0) + players[i].kartstuff[k_throwdir] = 1; + else if (cmd->forwardmove < 0) + players[i].kartstuff[k_throwdir] = -1; + else + players[i].kartstuff[k_throwdir] = 0; } // do main actions @@ -2146,6 +2145,10 @@ void G_PlayerReborn(INT32 player) INT32 continues; UINT8 charability; UINT8 charability2; + // SRB2kart + UINT8 kartspeed; + UINT8 kartweight; + // fixed_t normalspeed; fixed_t runspeed; UINT8 thrustfactor; @@ -2185,7 +2188,7 @@ void G_PlayerReborn(INT32 player) INT32 playerahead; INT32 starpostwp; INT32 lakitu; - + INT32 offroad; score = players[player].score; lives = players[player].lives; @@ -2208,6 +2211,10 @@ void G_PlayerReborn(INT32 player) skin = players[player].skin; charability = players[player].charability; charability2 = players[player].charability2; + // SRB2kart + kartspeed = players[player].kartspeed; + kartweight = players[player].kartweight; + // normalspeed = players[player].normalspeed; runspeed = players[player].runspeed; thrustfactor = players[player].thrustfactor; @@ -2238,6 +2245,7 @@ void G_PlayerReborn(INT32 player) playerahead = players[player].kartstuff[k_playerahead]; starpostwp = players[player].kartstuff[k_starpostwp]; lakitu = players[player].kartstuff[k_lakitu]; + offroad = players[player].kartstuff[k_offroad]; p = &players[player]; memset(p, 0, sizeof (*p)); @@ -2255,6 +2263,10 @@ void G_PlayerReborn(INT32 player) p->skin = skin; p->charability = charability; p->charability2 = charability2; + // SRB2kart + p->kartspeed = kartspeed; + p->kartweight = kartweight; + // p->normalspeed = normalspeed; p->runspeed = runspeed; p->thrustfactor = thrustfactor; @@ -2291,6 +2303,7 @@ void G_PlayerReborn(INT32 player) p->kartstuff[k_playerahead] = playerahead; p->kartstuff[k_starpostwp] = starpostwp; p->kartstuff[k_lakitu] = lakitu; + p->kartstuff[k_offroad] = offroad; // Don't do anything immediately p->pflags |= PF_USEDOWN; @@ -2646,7 +2659,7 @@ void G_DoReborn(INT32 playernum) // Do a wipe wipegamestate = -1; - if (player->starposttime) + if (player->starpostnum) // SRB2kart starpost = true; if (camera.chase) @@ -2691,7 +2704,7 @@ void G_DoReborn(INT32 playernum) // respawn at the start mobj_t *oldmo = NULL; - if (player->starposttime) + if (player->starpostnum) // SRB2kart starpost = true; // first dissasociate the corpse @@ -2832,7 +2845,7 @@ boolean G_TagGametype(void) INT16 G_TOLFlag(INT32 pgametype) { if (!multiplayer) return TOL_SP; - if (pgametype == GT_COOP) return TOL_COOP; + if (pgametype == GT_COOP) return TOL_RACE; // SRB2kart if (pgametype == GT_COMPETITION) return TOL_COMPETITION; if (pgametype == GT_RACE) return TOL_RACE; if (pgametype == GT_MATCH) return TOL_MATCH; @@ -3050,7 +3063,7 @@ static void G_DoWorldDone(void) { if (server) { - if (gametype == GT_COOP) + if (gametype == GT_RACE) // SRB2kart // don't reset player between maps D_MapChange(nextmap+1, gametype, ultimatemode, false, 0, false, false); else @@ -3683,6 +3696,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean { players[i].lives = cv_startinglives.value; players[i].continues = 0; + players[i].kartstuff[k_lakitu] = 0; // SRB2kart } else if (pultmode) { @@ -3693,6 +3707,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean { players[i].lives = 3; players[i].continues = 1; + players[i].kartstuff[k_lakitu] = 0; // SRB2kart } // The latter two should clear by themselves, but just in case @@ -4806,6 +4821,10 @@ void G_BeginRecording(void) WRITEUINT8(demo_p,player->actionspd>>FRACBITS); WRITEUINT8(demo_p,player->mindash>>FRACBITS); WRITEUINT8(demo_p,player->maxdash>>FRACBITS); + // SRB2kart + WRITEUINT8(demo_p,player->kartspeed>>FRACBITS); + WRITEUINT8(demo_p,player->kartweight>>FRACBITS); + // WRITEUINT8(demo_p,player->normalspeed>>FRACBITS); WRITEUINT8(demo_p,player->runspeed>>FRACBITS); WRITEUINT8(demo_p,player->thrustfactor); @@ -5041,7 +5060,7 @@ void G_DoPlayDemo(char *defdemoname) char skin[17],color[17],*n,*pdemoname; UINT8 version,subversion,charability,charability2,thrustfactor,accelstart,acceleration; UINT32 randseed; - fixed_t actionspd,mindash,maxdash,normalspeed,runspeed,jumpfactor; + fixed_t actionspd,mindash,maxdash,kartspeed,kartweight,normalspeed,runspeed,jumpfactor; char msg[1024]; skin[16] = '\0'; @@ -5182,6 +5201,10 @@ void G_DoPlayDemo(char *defdemoname) actionspd = (fixed_t)READUINT8(demo_p)<width/4); + y = 100 - (AutomapPic->height/4); + } + else + { + x = 312 - (AutomapPic->width/2); + y = 60; + } + + V_DrawSmallScaledPatch(x, y, 0, AutomapPic); + + // Player's tiny icons on the Automap. + if (lumpnum != -1 && (!modifiedgame || (modifiedgame && mapheaderinfo[gamemap-1].automap))) + { + for (i = 0; i < MAXPLAYERS; i++) + { + if (players[i].mo && !players[i].spectator) + { + // amnum xpos & ypos are the icon's speed around the HUD. + // The number being divided by is for how fast it moves. + // The higher the number, the slower it moves. + + // am xpos & ypos are the icon's starting position. Withouht + // it, they wouldn't 'spawn' on the top-right side of the HUD. + amnumxpos = (players[i].mo->x / 320) >> FRACBITS; + amnumypos = (-players[i].mo->y / 340) >> FRACBITS; + + amxpos = (x + amnumxpos) - (iconprefix[players[i].skin]->width/4); + amypos = (y + amnumypos) - (iconprefix[players[i].skin]->height/4); + + if (!players[i].skincolor) // 'default' color + { + V_DrawSmallScaledPatch(amxpos, amypos, 0, iconprefix[players[i].skin]); + } + else + { + UINT8 *colormap = translationtables[players[i].skin] - 256 + (players[i].skincolor<<8); + V_DrawSmallMappedPatch(amxpos, amypos, 0,iconprefix[players[i].skin], colormap); + } + } + } + } + if (!splitscreen && maptol & TOL_KART && !hu_showscores) + HU_DrawRaceRankings(); + } + */ + // + // draw chat string plus cursor if (chat_on) HU_DrawChat(); @@ -1272,9 +1345,18 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I if (circuitmap) { if (players[tab[i].num].exiting) - V_DrawRightAlignedString(x+240, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime))); + V_DrawRightAlignedString(x+240, y, V_YELLOWMAP, va("%d:%02d.%02d", + players[tab[i].num].realtime/(60*TICRATE), + players[tab[i].num].realtime/TICRATE % 60, + players[tab[i].num].realtime % TICRATE)); + //V_DrawRightAlignedString(x+240, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime))); else - V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count)); + V_DrawRightAlignedString(x+240, y, 0, va("(CP%02d) %d:%02d.%02d", + tab[i].count, + players[tab[i].num].starposttime/(60*TICRATE), + players[tab[i].num].starposttime/TICRATE % 60, + (int)((players[tab[i].num].starposttime % TICRATE) * (100.00f/TICRATE)))); + //V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count)); } else V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count))); diff --git a/src/info.c b/src/info.c index 8c51df09..984fb250 100644 --- a/src/info.c +++ b/src/info.c @@ -56,7 +56,8 @@ char sprnames[NUMSPRITES + 1][5] = "SRBJ","SRBK","SRBL","SRBM","SRBN","SRBO", //SRB2kart Sprites "SPRG","BSPR","RNDM","SPRK","KFRE","DRIF","DSMO","FAKE","DFAK","BANA", - "DBAN","GSHE","GSTR","DGSH","RSHE","RSTR","DRSH","BOMB","BLIG","LIGH" + "DBAN","GSHE","GSTR","DGSH","RSHE","RSTR","DRSH","BOMB","BLIG","LIGH", + "SINK","SITR","POKE" }; // Doesn't work with g++, needs actionf_p1 (don't modify this comment) @@ -2589,30 +2590,30 @@ state_t states[NUMSTATES] = {SPR_KFRE, FF_FULLBRIGHT|5, 2, {NULL}, 0, 0, S_KARTFIRE8}, // S_KARTFIRE7 {SPR_KFRE, FF_FULLBRIGHT|6, 2, {NULL}, 0, 0, S_NULL}, // S_KARTFIRE8 - {SPR_FAKE, 0, 3, {NULL}, 0, 0, S_FAKEITEM2}, // S_FAKEITEM1 - {SPR_FAKE, 1, 3, {NULL}, 0, 0, S_FAKEITEM3}, // S_FAKEITEM2 - {SPR_FAKE, 2, 3, {NULL}, 0, 0, S_FAKEITEM4}, // S_FAKEITEM3 - {SPR_FAKE, 3, 3, {NULL}, 0, 0, S_FAKEITEM5}, // S_FAKEITEM4 - {SPR_FAKE, 4, 3, {NULL}, 0, 0, S_FAKEITEM6}, // S_FAKEITEM5 - {SPR_FAKE, 5, 3, {NULL}, 0, 0, S_FAKEITEM7}, // S_FAKEITEM6 - {SPR_FAKE, 6, 3, {NULL}, 0, 0, S_FAKEITEM8}, // S_FAKEITEM7 - {SPR_FAKE, 7, 3, {NULL}, 0, 0, S_FAKEITEM9}, // S_FAKEITEM8 - {SPR_FAKE, 8, 3, {NULL}, 0, 0, S_FAKEITEM10}, // S_FAKEITEM9 - {SPR_FAKE, 9, 3, {NULL}, 0, 0, S_FAKEITEM11}, // S_FAKEITEM10 - {SPR_FAKE, 10, 3, {NULL}, 0, 0, S_FAKEITEM12}, // S_FAKEITEM11 - {SPR_FAKE, 11, 3, {NULL}, 0, 0, S_FAKEITEM13}, // S_FAKEITEM12 - {SPR_FAKE, 12, 3, {NULL}, 0, 0, S_FAKEITEM14}, // S_FAKEITEM13 - {SPR_FAKE, 13, 3, {NULL}, 0, 0, S_FAKEITEM15}, // S_FAKEITEM14 - {SPR_FAKE, 14, 3, {NULL}, 0, 0, S_FAKEITEM16}, // S_FAKEITEM15 - {SPR_FAKE, 15, 3, {NULL}, 0, 0, S_FAKEITEM17}, // S_FAKEITEM16 - {SPR_FAKE, 16, 3, {NULL}, 0, 0, S_FAKEITEM18}, // S_FAKEITEM17 - {SPR_FAKE, 17, 3, {NULL}, 0, 0, S_FAKEITEM19}, // S_FAKEITEM18 - {SPR_FAKE, 18, 3, {NULL}, 0, 0, S_FAKEITEM20}, // S_FAKEITEM19 - {SPR_FAKE, 19, 3, {NULL}, 0, 0, S_FAKEITEM21}, // S_FAKEITEM20 - {SPR_FAKE, 20, 3, {NULL}, 0, 0, S_FAKEITEM22}, // S_FAKEITEM21 - {SPR_FAKE, 21, 3, {NULL}, 0, 0, S_FAKEITEM23}, // S_FAKEITEM22 - {SPR_FAKE, 22, 3, {NULL}, 0, 0, S_FAKEITEM24}, // S_FAKEITEM23 - {SPR_FAKE, 23, 3, {NULL}, 0, 0, S_FAKEITEM1}, // S_FAKEITEM24 + {SPR_FITE, 0, 3, {NULL}, 0, 0, S_FAKEITEM2}, // S_FAKEITEM1 + {SPR_FITE, 1, 3, {NULL}, 0, 0, S_FAKEITEM3}, // S_FAKEITEM2 + {SPR_FITE, 2, 3, {NULL}, 0, 0, S_FAKEITEM4}, // S_FAKEITEM3 + {SPR_FITE, 3, 3, {NULL}, 0, 0, S_FAKEITEM5}, // S_FAKEITEM4 + {SPR_FITE, 4, 3, {NULL}, 0, 0, S_FAKEITEM6}, // S_FAKEITEM5 + {SPR_FITE, 5, 3, {NULL}, 0, 0, S_FAKEITEM7}, // S_FAKEITEM6 + {SPR_FITE, 6, 3, {NULL}, 0, 0, S_FAKEITEM8}, // S_FAKEITEM7 + {SPR_FITE, 7, 3, {NULL}, 0, 0, S_FAKEITEM9}, // S_FAKEITEM8 + {SPR_FITE, 8, 3, {NULL}, 0, 0, S_FAKEITEM10}, // S_FAKEITEM9 + {SPR_FITE, 9, 3, {NULL}, 0, 0, S_FAKEITEM11}, // S_FAKEITEM10 + {SPR_FITE, 10, 3, {NULL}, 0, 0, S_FAKEITEM12}, // S_FAKEITEM11 + {SPR_FITE, 11, 3, {NULL}, 0, 0, S_FAKEITEM13}, // S_FAKEITEM12 + {SPR_FITE, 12, 3, {NULL}, 0, 0, S_FAKEITEM14}, // S_FAKEITEM13 + {SPR_FITE, 13, 3, {NULL}, 0, 0, S_FAKEITEM15}, // S_FAKEITEM14 + {SPR_FITE, 14, 3, {NULL}, 0, 0, S_FAKEITEM16}, // S_FAKEITEM15 + {SPR_FITE, 15, 3, {NULL}, 0, 0, S_FAKEITEM17}, // S_FAKEITEM16 + {SPR_FITE, 16, 3, {NULL}, 0, 0, S_FAKEITEM18}, // S_FAKEITEM17 + {SPR_FITE, 17, 3, {NULL}, 0, 0, S_FAKEITEM19}, // S_FAKEITEM18 + {SPR_FITE, 18, 3, {NULL}, 0, 0, S_FAKEITEM20}, // S_FAKEITEM19 + {SPR_FITE, 19, 3, {NULL}, 0, 0, S_FAKEITEM21}, // S_FAKEITEM20 + {SPR_FITE, 20, 3, {NULL}, 0, 0, S_FAKEITEM22}, // S_FAKEITEM21 + {SPR_FITE, 21, 3, {NULL}, 0, 0, S_FAKEITEM23}, // S_FAKEITEM22 + {SPR_FITE, 22, 3, {NULL}, 0, 0, S_FAKEITEM24}, // S_FAKEITEM23 + {SPR_FITE, 23, 3, {NULL}, 0, 0, S_FAKEITEM1}, // S_FAKEITEM24 {SPR_DFAK, 0, 175, {NULL}, 0, 0, S_FAKEITEM1}, // S_DEADFAKEITEM {SPR_BANA, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BANANAITEM @@ -2642,15 +2643,15 @@ state_t states[NUMSTATES] = {SPR_GSHE, 5, 2, {A_SmokeTrailer}, MT_GREENTRAIL, 0, S_GREENITEM7}, // S_GREENITEM6 {SPR_GSHE, 6, 2, {A_SmokeTrailer}, MT_GREENTRAIL, 0, S_GREENITEM8}, // S_GREENITEM7 {SPR_GSHE, 7, 2, {A_SmokeTrailer}, MT_GREENTRAIL, 0, S_GREENITEM1}, // S_GREENITEM8 - {SPR_GSHE, 0, 1, {NULL}, 0, 0, S_GREENTRAIL2}, // S_GREENTRAIL1 - {SPR_GSHE, 1, 1, {NULL}, 0, 0, S_GREENTRAIL3}, // S_GREENTRAIL2 - {SPR_GSHE, 2, 1, {NULL}, 0, 0, S_GREENTRAIL4}, // S_GREENTRAIL3 - {SPR_GSHE, 3, 1, {NULL}, 0, 0, S_GREENTRAIL5}, // S_GREENTRAIL4 - {SPR_GSHE, 4, 1, {NULL}, 0, 0, S_GREENTRAIL6}, // S_GREENTRAIL5 - {SPR_GSHE, 5, 1, {NULL}, 0, 0, S_GREENTRAIL7}, // S_GREENTRAIL6 - {SPR_GSHE, 6, 1, {NULL}, 0, 0, S_GREENTRAIL8}, // S_GREENTRAIL7 - {SPR_GSHE, 7, 1, {NULL}, 0, 0, S_GREENTRAIL9}, // S_GREENTRAIL8 - {SPR_GSHE, 8, 1, {NULL}, 0, 0, S_NULL}, // S_GREENTRAIL9 + {SPR_GSTR, 0, 1, {NULL}, 0, 0, S_GREENTRAIL2}, // S_GREENTRAIL1 + {SPR_GSTR, 1, 1, {NULL}, 0, 0, S_GREENTRAIL3}, // S_GREENTRAIL2 + {SPR_GSTR, 2, 1, {NULL}, 0, 0, S_GREENTRAIL4}, // S_GREENTRAIL3 + {SPR_GSTR, 3, 1, {NULL}, 0, 0, S_GREENTRAIL5}, // S_GREENTRAIL4 + {SPR_GSTR, 4, 1, {NULL}, 0, 0, S_GREENTRAIL6}, // S_GREENTRAIL5 + {SPR_GSTR, 5, 1, {NULL}, 0, 0, S_GREENTRAIL7}, // S_GREENTRAIL6 + {SPR_GSTR, 6, 1, {NULL}, 0, 0, S_GREENTRAIL8}, // S_GREENTRAIL7 + {SPR_GSTR, 7, 1, {NULL}, 0, 0, S_GREENTRAIL9}, // S_GREENTRAIL8 + {SPR_GSTR, 8, 1, {NULL}, 0, 0, S_NULL}, // S_GREENTRAIL9 {SPR_DGSH, 0, 175, {NULL}, 0, 0, S_NULL}, // S_DEADGREEN {SPR_RSHE, 0, 2, {A_RotateSpikeBall}, 0, 0, S_TRIPLEREDSHIELD2}, // S_TRIPLEREDSHIELD1 @@ -2679,15 +2680,15 @@ state_t states[NUMSTATES] = {SPR_RSHE, 7, 2, {A_DualAction}, S_REDITEMCHASE, S_REDITEMTRAIL, S_REDITEM1}, // S_REDITEM8 {SPR_RSHE, 0, 2, {A_RedShellChase}, 0, 0, S_REDITEM2}, // S_REDITEMCHASE {SPR_RSHE, 1, 2, {A_SmokeTrailer}, MT_REDTRAIL, 0, S_REDITEM3}, // S_REDITEMTRAIL - {SPR_RSHE, 0, 1, {NULL}, 0, 0, S_REDTRAIL2}, // S_REDTRAIL1 - {SPR_RSHE, 1, 1, {NULL}, 0, 0, S_REDTRAIL3}, // S_REDTRAIL2 - {SPR_RSHE, 2, 1, {NULL}, 0, 0, S_REDTRAIL4}, // S_REDTRAIL3 - {SPR_RSHE, 3, 1, {NULL}, 0, 0, S_REDTRAIL5}, // S_REDTRAIL4 - {SPR_RSHE, 4, 1, {NULL}, 0, 0, S_REDTRAIL6}, // S_REDTRAIL5 - {SPR_RSHE, 5, 1, {NULL}, 0, 0, S_REDTRAIL7}, // S_REDTRAIL6 - {SPR_RSHE, 6, 1, {NULL}, 0, 0, S_REDTRAIL8}, // S_REDTRAIL7 - {SPR_RSHE, 7, 1, {NULL}, 0, 0, S_REDTRAIL9}, // S_REDTRAIL8 - {SPR_RSHE, 8, 1, {NULL}, 0, 0, S_NULL}, // S_REDTRAIL9 + {SPR_RSTR, 0, 1, {NULL}, 0, 0, S_REDTRAIL2}, // S_REDTRAIL1 + {SPR_RSTR, 1, 1, {NULL}, 0, 0, S_REDTRAIL3}, // S_REDTRAIL2 + {SPR_RSTR, 2, 1, {NULL}, 0, 0, S_REDTRAIL4}, // S_REDTRAIL3 + {SPR_RSTR, 3, 1, {NULL}, 0, 0, S_REDTRAIL5}, // S_REDTRAIL4 + {SPR_RSTR, 4, 1, {NULL}, 0, 0, S_REDTRAIL6}, // S_REDTRAIL5 + {SPR_RSTR, 5, 1, {NULL}, 0, 0, S_REDTRAIL7}, // S_REDTRAIL6 + {SPR_RSTR, 6, 1, {NULL}, 0, 0, S_REDTRAIL8}, // S_REDTRAIL7 + {SPR_RSTR, 7, 1, {NULL}, 0, 0, S_REDTRAIL9}, // S_REDTRAIL8 + {SPR_RSTR, 8, 1, {NULL}, 0, 0, S_NULL}, // S_REDTRAIL9 {SPR_DRSH, 0, 175, {NULL}, 0, 0, S_NULL}, // S_DEADRED {SPR_BOMB, 0, 1, {NULL}, 0, 0, S_BOMBSHIELD}, // S_BOMBSHIELD @@ -2706,6 +2707,20 @@ state_t states[NUMSTATES] = {SPR_LIGH, 0, 2, {NULL}, 0, 0, S_LIGHTNING4}, // S_LIGHTNING3 {SPR_LIGH, 0, 2, {NULL}, 0, 0, S_NULL}, // S_LIGHTNING4 + {SPR_SINK, 0, 4, {A_SmokeTrailer}, MT_SINKTRAIL, 0, S_SINK}, // S_SINK + {SPR_SITR, 0, 1, {NULL}, 0, 0, S_SINKTRAIL2}, // S_SINKTRAIL1 + {SPR_SITR, 1, 5, {NULL}, 0, 0, S_SINKTRAIL3}, // S_SINKTRAIL2 + {SPR_SITR, 2, 3, {NULL}, 0, 0, S_NULL}, // S_SINKTRAIL3 + + {SPR_POKE, 0, 2, {A_MoveAbsolute}, 0, 2, S_POKEY2}, // S_POKEY1 + {SPR_POKE, 1, 2, {A_MoveAbsolute}, 0, 2, S_POKEY3}, // S_POKEY2 + {SPR_POKE, 2, 2, {A_MoveAbsolute}, 0, 2, S_POKEY4}, // S_POKEY3 + {SPR_POKE, 3, 2, {A_MoveAbsolute}, 0, 2, S_POKEY1}, // S_POKEY4 + {SPR_POKE, 0, 2, {A_MoveAbsolute}, 180, 2, S_POKEY6}, // S_POKEY5 + {SPR_POKE, 1, 2, {A_MoveAbsolute}, 180, 2, S_POKEY7}, // S_POKEY6 + {SPR_POKE, 2, 2, {A_MoveAbsolute}, 180, 2, S_POKEY8}, // S_POKEY7 + {SPR_POKE, 3, 2, {A_MoveAbsolute}, 180, 2, S_POKEY5}, // S_POKEY8 + {SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_POKEYIDLE #ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK @@ -14881,6 +14896,141 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_SINK + -1, // doomednum + S_SINK, // spawnstate + 105, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + 256*FRACUNIT, // painstate + 100, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_shbrk, // deathsound + 0, // speed + 16*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 100, // mass + 1, // damage + sfx_bomb, // activesound + MF_BOUNCE|MF_FLOAT|MF_NOCLIPTHING|MF_MISSILE|MF_SHOOTABLE, // flags + S_NULL // raisestate + }, + + { // MT_SINKTRAIL + -1, // doomednum + S_SINKTRAIL1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 20*FRACUNIT, // radius + 16*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_POKEY + 2002, // doomednum + S_POKEY1, // spawnstate + 1000, // spawnhealth + S_POKEY1, // seestate + sfx_None, // seesound + 32, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 100, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 3, // speed + 21*FRACUNIT, // radius + 69*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SPECIAL|MF_SHOOTABLE, // flags + S_NULL // raisestate + }, + + { // MT_ENEMYFLIP + 2003, // doomednum + S_NULL, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 100, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 32*FRACUNIT, // radius + 64*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_SCENERY, // flags + S_NULL // raisestate + }, + + { // MT_WAYPOINT + 2001, // doomednum + S_NULL, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 100, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 1*FRACUNIT, // radius + 2*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY, // flags + S_NULL // raisestate + }, + #ifdef SEENAMES { // MT_NAMECHECK -1, // doomednum diff --git a/src/info.h b/src/info.h index 3ddd9d24..4af684e6 100644 --- a/src/info.h +++ b/src/info.h @@ -598,6 +598,11 @@ typedef enum sprite SPR_BOMB, // Bob-omb SPR_BLIG, // Blue Lightning SPR_LIGH, // Lightning + SPR_SINK, // Kitchen Sink + SPR_SITR, // Kitchen Sink Trail + + // Additional Kart Objects + SPR_POKE, // Lightning SPR_FIRSTFREESLOT, SPR_LASTFREESLOT = SPR_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1, @@ -3194,6 +3199,23 @@ typedef enum state S_LIGHTNING3, S_LIGHTNING4, + // The legend + S_SINK, + S_SINKTRAIL1, + S_SINKTRAIL2, + S_SINKTRAIL3, + + // Pokey + S_POKEY1, + S_POKEY2, + S_POKEY3, + S_POKEY4, + S_POKEY5, + S_POKEY6, + S_POKEY7, + S_POKEY8, + S_POKEYIDLE, + #ifdef SEENAMES S_NAMECHECK, #endif @@ -3764,6 +3786,13 @@ typedef enum mobj_type MT_BLUEEXPLOSION, MT_LIGHTNING, + MT_SINK, // Kitchen Sink Stuff + MT_SINKTRAIL, + + MT_POKEY, // Huh, thought this was a default asset for some reason, guess not. + MT_ENEMYFLIP, + MT_WAYPOINT, + #ifdef SEENAMES MT_NAMECHECK, #endif diff --git a/src/k_kart.c b/src/k_kart.c index bee2aaf2..71210a63 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -9,6 +9,7 @@ #include "g_game.h" #include "m_random.h" #include "p_local.h" +#include "p_slopes.h" #include "r_draw.h" #include "r_local.h" #include "s_sound.h" @@ -898,7 +899,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd) void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) { // This spawns the drift sparks when k_driftcharge hits 30. Its own AI handles life/death and color - if ((player->kartstuff[k_drift] == 1 || player->kartstuff[k_drift] == -1) + if ((player->kartstuff[k_drift] >= 1 || player->kartstuff[k_drift] <= -1) && player->kartstuff[k_driftcharge] == 30) P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_DRIFT)->target = player->mo; @@ -911,12 +912,18 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_spinouttimer]) player->kartstuff[k_spinouttimer]--; + if (player->kartstuff[k_spinout] == 0 && player->kartstuff[k_spinouttimer] == 0 && player->powers[pw_flashing] == flashingtics) + 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_startimer]) player->kartstuff[k_startimer]--; @@ -1026,23 +1033,26 @@ void K_PlayTauntSound(mobj_t *source) S_StartSound(source, sfx_taunt4); } -boolean K_SpinPlayer(player_t *player, mobj_t *source) +void K_SpinPlayer(player_t *player, mobj_t *source) { if (player->health <= 0) - return false; + return; if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || (player->kartstuff[k_spinouttimer] > 0 && player->kartstuff[k_spinout] > 0) || player->kartstuff[k_startimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_bootaketimer] > 0) - return false; + return; player->kartstuff[k_mushroomtimer] = 0; - if (player->kartstuff[k_spinouttype] == 0) + if (player->kartstuff[k_spinouttype] <= 0) { - player->kartstuff[k_spinouttimer] = 2*TICRATE; + if (player->kartstuff[k_spinouttype] == 0) + player->kartstuff[k_spinouttimer] = 2*TICRATE; + else + player->kartstuff[k_spinouttimer] = 3*TICRATE/2; if (player->speed < player->normalspeed/4) - P_InstaThrust(player->mo, player->mo->angle, player->normalspeed*FRACUNIT/4); + P_InstaThrust(player->mo, player->mo->angle, FixedMul(player->normalspeed/4, player->mo->scale)); S_StartSound(player->mo, sfx_slip); } @@ -1058,17 +1068,17 @@ boolean K_SpinPlayer(player_t *player, mobj_t *source) player->kartstuff[k_spinouttype] = 0; - return true; + return; } -boolean K_SquishPlayer(player_t *player, mobj_t *source) +void K_SquishPlayer(player_t *player, mobj_t *source) { if (player->health <= 0) - return false; + return; if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || player->kartstuff[k_startimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_bootaketimer] > 0) - return false; + return; player->kartstuff[k_mushroomtimer] = 0; @@ -1083,17 +1093,17 @@ boolean K_SquishPlayer(player_t *player, mobj_t *source) P_PlayRinglossSound(player->mo); - return true; + return; } -boolean K_ExplodePlayer(player_t *player, mobj_t *source) // A bit of a hack, we just throw the player up higher here and extend their spinout timer +void K_ExplodePlayer(player_t *player, mobj_t *source) // A bit of a hack, we just throw the player up higher here and extend their spinout timer { if (player->health <= 0) - return false; + return; if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || (player->kartstuff[k_spinouttimer] > 0 && player->kartstuff[k_spinout] > 0) || player->kartstuff[k_startimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_bootaketimer] > 0) - return false; + return; player->mo->momz = 18*FRACUNIT; player->mo->momx = player->mo->momy = 0; @@ -1113,7 +1123,7 @@ boolean K_ExplodePlayer(player_t *player, mobj_t *source) // A bit of a hack, we P_PlayRinglossSound(player->mo); - return true; + return; } void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit) @@ -1281,7 +1291,7 @@ void K_SpawnDriftTrail(player_t *player) ground -= FixedMul(mobjinfo[MT_MUSHROOMTRAIL].height, player->mo->scale); } #endif - if ((player->kartstuff[k_drift] == 1 || player->kartstuff[k_drift] == -1) && player->kartstuff[k_mushroomtimer] == 0) + if ((player->kartstuff[k_drift] >= 1 || player->kartstuff[k_drift] <= -1) && player->kartstuff[k_mushroomtimer] == 0) flame = P_SpawnMobj(newx, newy, ground, MT_DRIFTSMOKE); else flame = P_SpawnMobj(newx, newy, ground, MT_MUSHROOMTRAIL); @@ -1558,9 +1568,11 @@ static void K_DoBooSteal(player_t * player) void K_DoMushroom(player_t *player, boolean doPFlag) { - S_StartSound(player->mo, sfx_mush); + if (!player->kartstuff[k_floorboost] || player->kartstuff[k_floorboost] == 3) + S_StartSound(player->mo, sfx_mush); + player->kartstuff[k_mushroomtimer] = mushroomtime; - + if (doPFlag) player->pflags |= PF_ATTACKDOWN; @@ -1594,6 +1606,187 @@ void K_DoLightning(player_t *player, boolean bluelightning) player->kartstuff[k_sounds] = 70; } +void K_KartDrift(player_t *player, ticcmd_t *cmd, boolean onground) +{ + // Drifting is actually straffing + automatic turning. + // Holding the Jump button will enable drifting. + if (cmd->buttons & BT_DRIFTRIGHT) + player->kartstuff[k_turndir] = 1; + else if (cmd->buttons & BT_DRIFTLEFT) + player->kartstuff[k_turndir] = -1; + else + player->kartstuff[k_turndir] = 0; + + // Drift Release (Moved here so you can't "chain" drifts) + if ((player->kartstuff[k_drift] == 0) + // || (player->kartstuff[k_drift] >= 1 && player->kartstuff[k_turndir] != 1) || (player->kartstuff[k_drift] <= -1 && player->kartstuff[k_turndir] != -1)) + && player->kartstuff[k_driftcharge] < 30 + && onground) + { + player->kartstuff[k_drift] = 0; + player->kartstuff[k_driftcharge] = 0; + } + else if ((player->kartstuff[k_drift] == 0) + // || (player->kartstuff[k_drift] >= 1 && player->kartstuff[k_turndir] != 1) || (player->kartstuff[k_drift] <= -1 && player->kartstuff[k_turndir] != -1)) + && (player->kartstuff[k_driftcharge] >= 30 && player->kartstuff[k_driftcharge] < 60) + && onground) + { + player->powers[pw_sneakers] += 17; + S_StartSound(player->mo, sfx_mush); + player->kartstuff[k_drift] = 0; + player->kartstuff[k_driftcharge] = 0; + } + else if ((player->kartstuff[k_drift] == 0) + // || (player->kartstuff[k_drift] >= 1 && player->kartstuff[k_turndir] != 1) || (player->kartstuff[k_drift] <= -1 && player->kartstuff[k_turndir] != -1)) + && player->kartstuff[k_driftcharge] >= 60 + && onground) + { + player->powers[pw_sneakers] += 35; + S_StartSound(player->mo, sfx_mush); + player->kartstuff[k_drift] = 0; + player->kartstuff[k_driftcharge] = 0; + } + + // Drifting: left or right? + if (player->kartstuff[k_turndir] == 1 && player->speed > 10 && player->kartstuff[k_jmp] == 1 + && player->kartstuff[k_drift] < 3 && player->kartstuff[k_drift] > -1) // && player->kartstuff[k_drift] != 1) + player->kartstuff[k_drift] = 1; + else if (player->kartstuff[k_turndir] == -1 && player->speed > 10 && player->kartstuff[k_jmp] == 1 + && player->kartstuff[k_drift] > -3 && player->kartstuff[k_drift] < 1) // && player->kartstuff[k_drift] != -1) + player->kartstuff[k_drift] = -1; + else if (player->kartstuff[k_jmp] == 0) // || player->kartstuff[k_turndir] == 0) + player->kartstuff[k_drift] = 0; + + // Incease/decrease the drift value to continue drifting in that direction + if (player->kartstuff[k_spinouttimer] == 0 && player->kartstuff[k_jmp] == 1 && onground + && (player->kartstuff[k_drift] >= 1 || player->kartstuff[k_drift] <= -1)) + { + player->kartstuff[k_driftcharge]++; + + if (player->kartstuff[k_drift] >= 1) // Drifting to the Right + { + player->kartstuff[k_drift]++; + if (player->kartstuff[k_drift] > 3) + player->kartstuff[k_drift] = 3; + + // Left = +450 Right = -450 + // Player 1 + if (player == &players[consoleplayer]) + { + if (player->kartstuff[k_turndir] == -1) // Turning Left while Drifting Right + localangle -= 600*FRACUNIT; + else if (player->kartstuff[k_turndir] == 1) // Turning Right while Drifting Right + localangle -= 225*FRACUNIT; + else // No Direction while Drifting Right + localangle -= 450*FRACUNIT; + } + + // Player 2 + if (splitscreen && player == &players[secondarydisplayplayer]) + { + + } + } + else if (player->kartstuff[k_drift] <= -1) // Drifting to the Left + { + player->kartstuff[k_drift]--; + if (player->kartstuff[k_drift] < -3) + player->kartstuff[k_drift] = -3; + + // Left = +450 Right = -450 + // Player 1 + if (player == &players[consoleplayer]) + { + if (player->kartstuff[k_turndir] == 1) // Turning Right while Drifting Left + localangle += 600*FRACUNIT; + else if (player->kartstuff[k_turndir] == -1) // Turning Left while Drifting Left + localangle += 225*FRACUNIT; + else // No Direction while Drifting Left + localangle += 450*FRACUNIT; + } + + // Player 2 + if (splitscreen && player == &players[secondarydisplayplayer] && player->kartstuff[k_turndir] == 1) + localangle2 += (300+192)*FRACUNIT; + else if (splitscreen && player == &players[secondarydisplayplayer]) + localangle2 += (300)*FRACUNIT; + } + } + + // Stop drifting + if (player->kartstuff[k_spinouttimer] > 0 // banana peel + || player->speed < 10) // you're too slow! + { + player->kartstuff[k_drift] = 0; + player->kartstuff[k_driftcharge] = 0; + } +} + +UINT64 K_GetKartSpeed(player_t *player) +{ + UINT64 k_speed = 47*FRACUNIT + FRACUNIT/2; + + // Speed is a value between 48 and 52, incremented by halves + k_speed += player->kartspeed*FRACUNIT/2; + + return k_speed; +} + +UINT64 K_GetKartAccel(player_t *player) +{ + UINT64 k_accel = 45; + + // Acceleration is a given base, minus the speed value. + k_accel -= 3*player->kartspeed; + + return k_accel; +} + +fixed_t K_3dKartMovement(player_t *player, boolean onground) +{ + // If the player isn't on the ground, there is no change in speed + if (!onground) return 0; + + fixed_t accelmax = 2000; // AccelMax + fixed_t f_beater = 2*FRACUNIT - (0xE8<<(FRACBITS-8)); //1.10345f; // Friction Beater Friction = (0xE8 << (FRACBITS-8)) + fixed_t g_cc = 1*FRACUNIT; // Game CC + + fixed_t newspeed, oldspeed, finalspeed; + fixed_t boostpower = 1*FRACUNIT; + fixed_t p_speed = K_GetKartSpeed(player); + fixed_t p_accel = K_GetKartAccel(player); + + sector_t *nextsector = R_PointInSubsector(player->mo->x + player->mo->momx*2, player->mo->y + player->mo->momy*2)->sector; + + // Determine boostpower by checking every power. There's probably a cleaner way to do this, but eh whatever. + if (!(player->kartstuff[k_startimer] || player->kartstuff[k_bootaketimer] || player->powers[pw_sneakers] || + player->kartstuff[k_mushroomtimer] || player->kartstuff[k_growshrinktimer] > 1) && P_IsObjectOnGround(player->mo) && + nextsector->special & 256 && nextsector->special != 768 && (nextsector->special != 1024 || nextsector->special != 4864)) + boostpower = FixedMul(boostpower, FRACUNIT/4); // Off-road, unless you're ignoring off-road. + if (player->kartstuff[k_growshrinktimer] < -1) boostpower = FixedMul(boostpower, FRACUNIT/3); // Shrink + if (player->kartstuff[k_squishedtimer] > 0) boostpower = FixedMul(boostpower, FRACUNIT/2); // Squished + if (player->powers[pw_sneakers]) boostpower = FixedMul(boostpower, FRACUNIT+FRACUNIT/4); // Slide Boost + if (player->kartstuff[k_growshrinktimer] > 1) boostpower = FixedMul(boostpower, FRACUNIT+FRACUNIT/3); // Mega Mushroom + if (player->kartstuff[k_startimer]) boostpower = FixedMul(boostpower, FRACUNIT+FRACUNIT/2); // Star + if (player->kartstuff[k_mushroomtimer]) boostpower = FixedMul(boostpower, FRACUNIT+FRACUNIT/1); // Mushroom + + // Boostpower is applied to each stat individually, and NOT the calculation. + // Applying to the calculation fails due to friction never getting beaten, or getting overshot really far. + // It's easier this way. + // Similarly, the CC of the game is also multiplied directly. + // This assures a growth in speed without affecting acceleration curving. + p_speed = FixedMul(FixedMul(p_speed, boostpower), g_cc); + p_accel = FixedMul(FixedMul(p_accel, boostpower), g_cc); + accelmax = FixedMul(FixedMul(accelmax, boostpower), g_cc); + + // Now, the code that made Iceman's eyes rub erotically against a toaster. + oldspeed = FixedMul(FixedMul(P_AproxDistance(player->rmomx, player->rmomy), player->mo->scale), f_beater); + newspeed = FixedMul(FixedDiv(FixedMul(oldspeed, accelmax - p_accel) + FixedMul(p_speed, p_accel), accelmax), f_beater); + finalspeed = newspeed - oldspeed; + + return (fixed_t)finalspeed; +} + void K_MoveKartPlayer(player_t *player, ticcmd_t *cmd, boolean onground) { boolean ATTACK_IS_DOWN = ((cmd->buttons & BT_ATTACK) && !(player->pflags & PF_ATTACKDOWN)); @@ -1972,9 +2165,9 @@ void K_MoveKartPlayer(player_t *player, ticcmd_t *cmd, boolean onground) if (player->kartstuff[k_mushroomtimer] > 0 && player->kartstuff[k_boosting] == 0 && onground) { cmd->forwardmove = 1; - if (player->kartstuff[k_drift] == 1) + if (player->kartstuff[k_drift] >= 1) P_InstaThrust(player->mo, player->mo->angle+ANGLE_45, 55*FRACUNIT); - else if (player->kartstuff[k_drift] == -1) + else if (player->kartstuff[k_drift] <= -1) P_InstaThrust(player->mo, player->mo->angle-ANGLE_45, 55*FRACUNIT); else P_InstaThrust(player->mo, player->mo->angle, 55*FRACUNIT); @@ -2020,79 +2213,7 @@ void K_MoveKartPlayer(player_t *player, ticcmd_t *cmd, boolean onground) if (splitscreen && player == &players[secondarydisplayplayer]) CV_SetValue(&cv_cam2_dist, 190); - // DRRRRIIIIFFFFFFTTT!!!! - // Drifting is actually straffing + automatic turning. - // Holding the Jump button will enable drifting. - - // Instead of instantly straffing, you go from running - // straight to slowly turning left/right. - // 536870912 is the normal straffing angle, 90 degrees. - // 35791394 is the speed that's added from 0 to 90. - - // localangle is SRB2's turning code, not angle direction. - // Adding or subtracting by 300 is how much you can turn. - // The higher it is, the faster you turn. - - if (cmd->buttons & BT_DRIFTRIGHT) - player->kartstuff[k_turndir] = 1; - else if (cmd->buttons & BT_DRIFTLEFT) - player->kartstuff[k_turndir] = -1; - else - player->kartstuff[k_turndir] = 0; - - // Moved here so you can't "chain" drifts - // Drift Release - if (((player->kartstuff[k_drift] == 0) || (player->kartstuff[k_drift] == 1 && player->kartstuff[k_turndir] != 1) || (player->kartstuff[k_drift] == -1 && player->kartstuff[k_turndir] != -1)) - && player->kartstuff[k_driftcharge] < 30 - && onground) - { - player->kartstuff[k_drift] = 0; - player->kartstuff[k_driftcharge] = 0; - } - else if (((player->kartstuff[k_drift] == 0) || (player->kartstuff[k_drift] == 1 && player->kartstuff[k_turndir] != 1) || (player->kartstuff[k_drift] == -1 && player->kartstuff[k_turndir] != -1)) - && (player->kartstuff[k_driftcharge] >= 30 && player->kartstuff[k_driftcharge] < 60) - && onground) - { - player->powers[pw_sneakers] += 17; - S_StartSound(player->mo, sfx_mush); - player->kartstuff[k_drift] = 0; - player->kartstuff[k_driftcharge] = 0; - } - else if (((player->kartstuff[k_drift] == 0) || (player->kartstuff[k_drift] == 1 && player->kartstuff[k_turndir] != 1) || (player->kartstuff[k_drift] == -1 && player->kartstuff[k_turndir] != -1)) - && player->kartstuff[k_driftcharge] >= 60 - && onground) - { - player->powers[pw_sneakers] += 35; - S_StartSound(player->mo, sfx_mush); - player->kartstuff[k_drift] = 0; - player->kartstuff[k_driftcharge] = 0; - } - - if (player->kartstuff[k_turndir] == 1 && player->speed > 10 - && player->kartstuff[k_jmp] == 1 - && player->kartstuff[k_drift] != 1) - player->kartstuff[k_drift] = 1; - else if (player->kartstuff[k_turndir] == -1 && player->speed > 10 - && player->kartstuff[k_jmp] == 1 - && player->kartstuff[k_drift] != -1) - player->kartstuff[k_drift] = -1; - else if (player->kartstuff[k_jmp] == 0 || player->kartstuff[k_turndir] == 0) - player->kartstuff[k_drift] = 0; - - // If you press any strafe key while turning right, then drift right. - if (player->kartstuff[k_spinouttimer] == 0 - && player->kartstuff[k_jmp] == 1 && (player->kartstuff[k_drift] == 1 || player->kartstuff[k_drift] == -1) - && onground) //Right - { - player->kartstuff[k_driftcharge]++; - } - // Stop drifting - if (player->kartstuff[k_spinouttimer] > 0 // banana peel - || player->speed < 10) // you're too slow! - { - player->kartstuff[k_drift] = 0; - player->kartstuff[k_driftcharge] = 0; - } + K_KartDrift(player, cmd, onground); // Quick Turning // You can't turn your kart when you're not moving. @@ -2161,7 +2282,6 @@ void K_MoveKartPlayer(player_t *player, ticcmd_t *cmd, boolean onground) } } */ - player->kartstuff[k_boostcharge] = 0; // Play the stop light's sounds if ((leveltime == (TICRATE-4)*2) || (leveltime == (TICRATE-2)*3)) @@ -2175,7 +2295,7 @@ void K_MoveKartPlayer(player_t *player, ticcmd_t *cmd, boolean onground) player->kartstuff[k_boostcharge] = 0; // Increase your size while charging your engine. if (leveltime < 150) - player->mo->destscale = FRACUNIT*((100 + player->kartstuff[k_boostcharge])/100); + player->mo->destscale = FRACUNIT + (player->kartstuff[k_boostcharge]*655); // Determine the outcome of your charge. if (leveltime > 140 && player->kartstuff[k_boostcharge]) @@ -2187,7 +2307,10 @@ void K_MoveKartPlayer(player_t *player, ticcmd_t *cmd, boolean onground) } // You overcharged your engine? Those things are expensive!!! if (player->kartstuff[k_boostcharge] > 10) - player->kartstuff[k_boostcharge] = 40; + { + player->powers[pw_nocontrol] = 40; + S_StartSound(player->mo, sfx_slip); + } player->kartstuff[k_boostcharge] = 0; } @@ -2351,6 +2474,7 @@ static patch_t *kp_blueshell; static patch_t *kp_fireflower; static patch_t *kp_tripleredshell; static patch_t *kp_lightning; +static patch_t *kp_kitchensink; static patch_t *kp_itemused1; static patch_t *kp_itemused2; static patch_t *kp_itemused3; @@ -2447,6 +2571,7 @@ void K_LoadKartHUDGraphics(void) kp_fireflower = W_CachePatchName("K_ITFIRE", PU_HUDGFX); kp_tripleredshell = W_CachePatchName("K_ITTRED", PU_HUDGFX); kp_lightning = W_CachePatchName("K_ITLIGH", PU_HUDGFX); + kp_kitchensink = W_CachePatchName("K_ITSINK", PU_HUDGFX); // Item-used - Closing the item window after an item is used kp_itemused1 = W_CachePatchName("K_ITUSE1", PU_HUDGFX); @@ -2725,6 +2850,7 @@ static void K_drawKartRetroItem(void) if ((stplyr->kartstuff[k_bootaketimer] > 0 || stplyr->kartstuff[k_boostolentimer] > 0) && (leveltime & 2)) localpatch = kp_boosteal; else if (stplyr->kartstuff[k_boostolentimer] > 0 && !(leveltime & 2)) localpatch = kp_noitem; + else if (stplyr->kartstuff[k_kitchensink] == 1) localpatch = kp_kitchensink; else if (stplyr->kartstuff[k_lightning] == 1) localpatch = kp_lightning; else if (stplyr->kartstuff[k_tripleredshell] & 8) localpatch = kp_tripleredshell; else if (stplyr->kartstuff[k_fireflower] == 1) localpatch = kp_fireflower; @@ -3083,15 +3209,9 @@ void K_drawKartHUD(void) K_DrawKartPositionNum(stplyr->kartstuff[k_spinout]); //K_DrawKartPositionNum(stplyr->kartstuff[k_position]); - // Why is this here????? - /* + // Plays the music after the starting countdown. This is here since it checks every frame regularly. if (leveltime > 157 && leveltime < (TICRATE+1)*7) - { - if (!(mapmusic & 2048)) // TODO: Might not need this here - mapmusic = mapheaderinfo[gamemap-1].musicslot; - - S_ChangeMusic(mapmusic & 2047, true); - }*/ + S_ChangeMusicInternal(mapmusname, true); } //} diff --git a/src/k_kart.h b/src/k_kart.h index 5f822cd6..014eb581 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -16,11 +16,13 @@ UINT8 K_GetKartColorByName(const char *name); void K_RegisterKartStuff(void); void K_KartPlayerThink(player_t *player, ticcmd_t *cmd); -boolean K_SpinPlayer(player_t *player, mobj_t *source); -boolean K_SquishPlayer(player_t *player, mobj_t *source); -boolean K_ExplodePlayer(player_t *player, mobj_t *source); +void K_SpinPlayer(player_t *player, mobj_t *source); +void K_SquishPlayer(player_t *player, mobj_t *source); +void K_ExplodePlayer(player_t *player, mobj_t *source); void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit); void K_SpawnDriftTrail(player_t *player); +void K_DoMushroom(player_t *player, boolean doPFlag); +fixed_t K_3dKartMovement(player_t *player, boolean onground); void K_MoveKartPlayer(player_t *player, ticcmd_t *cmd, boolean onground); void K_LoadKartHUDGraphics(void); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index bd5605f2..29bcd736 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -144,6 +144,12 @@ static int player_get(lua_State *L) lua_pushfixed(L, plr->dashspeed); else if (fastcmp(field,"dashtime")) lua_pushinteger(L, plr->dashtime); + // SRB2kart + else if (fastcmp(field,"kartspeed")) + lua_pushfixed(L, plr->kartspeed); + else if (fastcmp(field,"kartweight")) + lua_pushfixed(L, plr->kartweight); + // else if (fastcmp(field,"normalspeed")) lua_pushfixed(L, plr->normalspeed); else if (fastcmp(field,"runspeed")) @@ -401,6 +407,12 @@ static int player_set(lua_State *L) plr->dashspeed = luaL_checkfixed(L, 3); else if (fastcmp(field,"dashtime")) plr->dashtime = (INT32)luaL_checkinteger(L, 3); + // SRB2kart + else if (fastcmp(field,"kartspeed")) + plr->kartspeed = (UINT8)luaL_checkfixed(L, 3); + else if (fastcmp(field,"kartweight")) + plr->kartweight = (UINT8)luaL_checkfixed(L, 3); + // else if (fastcmp(field,"normalspeed")) plr->normalspeed = luaL_checkfixed(L, 3); else if (fastcmp(field,"runspeed")) diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c index 28d5fed2..85e029e6 100644 --- a/src/lua_skinlib.c +++ b/src/lua_skinlib.c @@ -38,6 +38,10 @@ enum skin { skin_actionspd, skin_mindash, skin_maxdash, + // SRB2kart + skin_kartspeed, + skin_kartweight, + // skin_normalspeed, skin_runspeed, skin_thrustfactor, @@ -68,6 +72,10 @@ static const char *const skin_opt[] = { "actionspd", "mindash", "maxdash", + // SRB2kart + "kartspeed", + "kartweight", + // "normalspeed", "runspeed", "thrustfactor", @@ -155,6 +163,14 @@ static int skin_get(lua_State *L) case skin_maxdash: lua_pushfixed(L, skin->maxdash); break; + // SRB2kart + case skin_kartspeed: + lua_pushfixed(L, skin->kartspeed); + break; + case skin_kartweight: + lua_pushfixed(L, skin->kartweight); + break; + // case skin_normalspeed: lua_pushfixed(L, skin->normalspeed); break; diff --git a/src/m_menu.c b/src/m_menu.c index 2b623651..38c9acfe 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -376,6 +376,9 @@ consvar_t cv_chooseskin = {"chooseskin", DEFAULTSKIN, CV_HIDEN|CV_CALL, skins_co // When you add gametypes here, don't forget to update them in CV_AddValue! CV_PossibleValue_t gametype_cons_t[] = { + {GT_RACE, "Race"}, {GT_MATCH, "Match"}, + + /* // SRB2kart {GT_COOP, "Co-op"}, {GT_COMPETITION, "Competition"}, @@ -388,9 +391,10 @@ CV_PossibleValue_t gametype_cons_t[] = {GT_HIDEANDSEEK, "Hide and Seek"}, {GT_CTF, "CTF"}, + */ {0, NULL} }; -consvar_t cv_newgametype = {"newgametype", "Co-op", CV_HIDEN|CV_CALL, gametype_cons_t, Newgametype_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_newgametype = {"newgametype", "Race", CV_HIDEN|CV_CALL, gametype_cons_t, Newgametype_OnChange, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t serversort_cons_t[] = { {0,"Ping"}, @@ -1899,19 +1903,19 @@ static void Newgametype_OnChange(void) if(!mapheaderinfo[cv_nextmap.value-1]) P_AllocMapHeader((INT16)(cv_nextmap.value-1)); - if ((cv_newgametype.value == GT_COOP && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_COOP)) || - (cv_newgametype.value == GT_COMPETITION && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_COMPETITION)) || - (cv_newgametype.value == GT_RACE && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_RACE)) || - ((cv_newgametype.value == GT_MATCH || cv_newgametype.value == GT_TEAMMATCH) && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_MATCH)) || - ((cv_newgametype.value == GT_TAG || cv_newgametype.value == GT_HIDEANDSEEK) && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_TAG)) || - (cv_newgametype.value == GT_CTF && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_CTF))) + if ((cv_newgametype.value == GT_RACE && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_RACE)) || // SRB2kart + //(cv_newgametype.value == GT_COMPETITION && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_COMPETITION)) || + //(cv_newgametype.value == GT_RACE && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_RACE)) || + ((cv_newgametype.value == GT_MATCH || cv_newgametype.value == GT_TEAMMATCH) && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_MATCH))) // || + //((cv_newgametype.value == GT_TAG || cv_newgametype.value == GT_HIDEANDSEEK) && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_TAG)) || + //(cv_newgametype.value == GT_CTF && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_CTF))) { INT32 value = 0; switch (cv_newgametype.value) { case GT_COOP: - value = TOL_COOP; + value = TOL_RACE; // SRB2kart break; case GT_COMPETITION: value = TOL_COMPETITION; @@ -4264,7 +4268,7 @@ static void M_NewGame(void) fromlevelselect = false; startmap = spstage_start; - CV_SetValue(&cv_newgametype, GT_COOP); // Graue 09-08-2004 + CV_SetValue(&cv_newgametype, GT_RACE); // SRB2kart M_SetupChoosePlayer(0); } @@ -6213,6 +6217,15 @@ static void M_DrawServerMenu(void) } #endif + // SRB2kart + // A 70x70 image of the level's gametype + /* + if (mapheaderinfo[cv_nextmap.value-1].typeoflevel & TOL_KART) + V_DrawSmallScaledPatch(BASEVIDWIDTH/2,130,0,W_CachePatchName("KART", PU_STATIC)); + else + V_DrawSmallScaledPatch(BASEVIDWIDTH/2,130,0,W_CachePatchName("SONR", PU_STATIC)); + */ + // A 160x100 image of the level as entry MAPxxP lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value))); diff --git a/src/m_misc.h b/src/m_misc.h index fa1f3b33..f2a8bb54 100644 --- a/src/m_misc.h +++ b/src/m_misc.h @@ -38,7 +38,7 @@ void M_StopMovie(void); #elif defined (PSP) #define CONFIGFILENAME "srb2psp.cfg" #else -#define CONFIGFILENAME "config.cfg" +#define CONFIGFILENAME "kartconfig.cfg" #endif INT32 M_MapNumber(char first, char second); diff --git a/src/p_inter.c b/src/p_inter.c index 1c97302d..15d2e1f1 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1151,6 +1151,13 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) case MT_STARPOST: if (player->bot) return; + // SRB2kart - 150117 + if (player->exiting) //STOP MESSING UP MY STATS FASDFASDF + { + player->kartstuff[k_starpostwp] = player->kartstuff[k_waypoint]; + return; + } + // // In circuit, player must have touched all previous starposts if (circuitmap && special->health - player->starpostnum > 1) @@ -1173,7 +1180,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; // Already hit this post // Save the player's time and position. - player->starposttime = leveltime; + player->starposttime = player->realtime; //this makes race mode's timers work correctly whilst not affecting sp -x + if (((special->health - 1) + (numstarposts+1)*player->laps) < 256) // SIGSEGV prevention + player->checkpointtimes[(special->health - 1) + (numstarposts+1)*player->laps] = player->realtime; + //player->starposttime = leveltime; player->starpostx = toucher->x>>FRACBITS; player->starposty = toucher->y>>FRACBITS; player->starpostz = special->z>>FRACBITS; @@ -1181,6 +1191,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) player->starpostnum = special->health; P_ClearStarPost(special->health); + // SRB2kart + if (gametype == GT_RACE) + player->kartstuff[k_playerahead] = P_CheckPlayerAhead(player, (special->health - 1) + (numstarposts+1)*player->laps); + // Find all starposts in the level with this value. { thinker_t *th; @@ -1479,6 +1493,58 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) P_KillMobj(special, NULL, toucher); } +// SRB2kart +INT32 P_CheckPlayerAhead(player_t *player, INT32 tocheck) +{ + INT32 i, retvalue = 0, me = -1; + tic_t besttime = 0xffffffff; + + if (tocheck >= 256) + return 0; //Don't SIGSEGV. + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (player == &players[i]) //you're me! + { + me = i; + continue; + } + + if (!players[i].checkpointtimes[tocheck]) + continue; + + if (players[i].checkpointtimes[tocheck] >= besttime) + continue; + + besttime = players[i].checkpointtimes[tocheck]; + retvalue = i+1; + } + + if (!retvalue) + return 0; + + if (besttime >= player->realtime) // > sign is practically paranoia + { + if (!players[retvalue-1].kartstuff[k_playerahead] && me != -1 + && players[retvalue-1].laps == player->laps + && players[retvalue-1].starpostnum == player->starpostnum) + players[retvalue-1].kartstuff[k_playerahead] = 65536; + return 65536; //we're tied! + } + + //checkplayerahead does this too! + if (!players[retvalue-1].kartstuff[k_playerahead] && me != -1 + && players[retvalue-1].laps == player->laps + && players[retvalue-1].starpostnum == player->starpostnum) + players[retvalue-1].kartstuff[k_playerahead] = 257 + me; + + return retvalue; +} +// + /** Prints death messages relating to a dying or hit player. * * \param player Affected player. @@ -1956,14 +2022,60 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) if (inflictor && (inflictor->type == MT_SHELL || inflictor->type == MT_FIREBALL)) P_SetTarget(&target->tracer, inflictor); + // SRB2kart + // I wish I knew a better way to do this + if (target->target && target->target->player && target->target->player->mo) + { + if (target->type == MT_GREENSHIELD && target->target->player->kartstuff[k_greenshell] & 1) + target->target->player->kartstuff[k_greenshell] &= ~1; + else if (target->type == MT_REDSHIELD && target->target->player->kartstuff[k_redshell] & 1) + target->target->player->kartstuff[k_redshell] &= ~1; + else if (target->type == MT_BANANASHIELD && target->target->player->kartstuff[k_banana] & 1) + target->target->player->kartstuff[k_banana] &= ~1; + else if (target->type == MT_FAKESHIELD && target->target->player->kartstuff[k_fakeitem] & 1) + target->target->player->kartstuff[k_fakeitem] &= ~1; + else if (target->type == MT_BOMBSHIELD && target->target->player->kartstuff[k_bobomb] & 1) + target->target->player->kartstuff[k_bobomb] &= ~1; + else if (target->type == MT_TRIPLEGREENSHIELD1 && target->target->player->kartstuff[k_triplegreenshell] & 1) + target->target->player->kartstuff[k_triplegreenshell] &= ~1; + else if (target->type == MT_TRIPLEGREENSHIELD2 && target->target->player->kartstuff[k_triplegreenshell] & 2) + target->target->player->kartstuff[k_triplegreenshell] &= ~2; + else if (target->type == MT_TRIPLEGREENSHIELD3 && target->target->player->kartstuff[k_triplegreenshell] & 4) + target->target->player->kartstuff[k_triplegreenshell] &= ~4; + else if (target->type == MT_TRIPLEREDSHIELD1 && target->target->player->kartstuff[k_tripleredshell] & 1) + target->target->player->kartstuff[k_tripleredshell] &= ~1; + else if (target->type == MT_TRIPLEREDSHIELD2 && target->target->player->kartstuff[k_tripleredshell] & 2) + target->target->player->kartstuff[k_tripleredshell] &= ~2; + else if (target->type == MT_TRIPLEREDSHIELD3 && target->target->player->kartstuff[k_tripleredshell] & 4) + target->target->player->kartstuff[k_tripleredshell] &= ~4; + else if (target->type == MT_TRIPLEBANANASHIELD1 && target->target->player->kartstuff[k_triplebanana] & 1) + target->target->player->kartstuff[k_triplebanana] &= ~1; + else if (target->type == MT_TRIPLEBANANASHIELD2 && target->target->player->kartstuff[k_triplebanana] & 2) + target->target->player->kartstuff[k_triplebanana] &= ~2; + else if (target->type == MT_TRIPLEBANANASHIELD3 && target->target->player->kartstuff[k_triplebanana] & 4) + target->target->player->kartstuff[k_triplebanana] &= ~4; + } + // + if (!useNightsSS && G_IsSpecialStage(gamemap) && target->player && sstimer > 6) sstimer = 6; // Just let P_Ticker take care of the rest. if (target->flags & (MF_ENEMY|MF_BOSS)) target->momx = target->momy = target->momz = 0; - if (target->type != MT_PLAYER && !(target->flags & MF_MONITOR)) - target->flags |= MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT; // Don't drop Tails 03-08-2000 + // SRB2kart + if (target->type != MT_PLAYER && !(target->flags & MF_MONITOR) + && !(target->type == MT_GREENITEM || target->type == MT_GREENSHIELD + || target->type == MT_TRIPLEGREENSHIELD1 || target->type == MT_TRIPLEGREENSHIELD2 || target->type == MT_TRIPLEGREENSHIELD3 + || target->type == MT_REDITEM || target->type == MT_REDITEMDUD || target->type == MT_REDSHIELD + || target->type == MT_TRIPLEREDSHIELD1 || target->type == MT_TRIPLEREDSHIELD2 || target->type == MT_TRIPLEREDSHIELD3 + || target->type == MT_BANANAITEM || target->type == MT_BANANASHIELD + || target->type == MT_TRIPLEBANANASHIELD1 || target->type == MT_TRIPLEBANANASHIELD2 || target->type == MT_TRIPLEBANANASHIELD3 + || target->type == MT_FAKEITEM || target->type == MT_FAKESHIELD)) // kart dead items + target->flags |= MF_NOGRAVITY; // Don't drop Tails 03-08-2000 + else + target->flags &= ~MF_NOGRAVITY; // lose it if you for whatever reason have it, I'm looking at you shields + // if (target->flags2 & MF2_NIGHTSPULL) P_SetTarget(&target->tracer, NULL); @@ -2894,6 +3006,13 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da return false; } + // SRB2kart 011617 - Special Case for Pokey so it doesn't die. + if (target->type == MT_POKEY) + { + target->threshold = 1; + return false; + } + // Special case for Crawla Commander if (target->type == MT_CRAWLACOMMANDER) { diff --git a/src/p_local.h b/src/p_local.h index c8930aed..707b861c 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -387,6 +387,10 @@ void P_CheckPointLimit(void); void P_CheckSurvivors(void); boolean P_CheckRacers(void); +// SRB2kart +INT32 P_CheckPlayerAhead(player_t *player, INT32 tocheck); +// + void P_ClearStarPost(INT32 postnum); void P_ResetStarposts(void); diff --git a/src/p_map.c b/src/p_map.c index 79ae5ddf..b9ff1597 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -24,6 +24,7 @@ #include "r_sky.h" #include "s_sound.h" #include "w_wad.h" +#include "k_kart.h" // SRB2kart 011617 #include "r_splats.h" @@ -553,6 +554,537 @@ static boolean PIT_CheckThing(mobj_t *thing) } } + // SRB2kart 011617 - Colission code for kart items //{ + + if (tmthing->type == MT_GREENITEM || tmthing->type == MT_REDITEM || tmthing->type == MT_REDITEMDUD || + tmthing->type == MT_GREENSHIELD || tmthing->type == MT_REDSHIELD || + tmthing->type == MT_TRIPLEGREENSHIELD1 || tmthing->type == MT_TRIPLEGREENSHIELD2 || tmthing->type == MT_TRIPLEGREENSHIELD3 || + tmthing->type == MT_TRIPLEREDSHIELD1 || tmthing->type == MT_TRIPLEREDSHIELD2 || tmthing->type == MT_TRIPLEREDSHIELD3) + { + // see if it went over / under + if (tmthing->z > thing->z + thing->height) + return true; // overhead + if (tmthing->z + tmthing->height < thing->z) + return true; // underneath + + if (((tmthing->target == thing) || (tmthing->target == thing->target)) && (tmthing->threshold > 0 || (thing->type != MT_PLAYER && thing->threshold > 0))) + return true; + + if (tmthing->health <= 0 || thing->health <= 0) + return true; + + if (((tmthing->type == MT_TRIPLEGREENSHIELD1 || tmthing->type == MT_TRIPLEGREENSHIELD2 || tmthing->type == MT_TRIPLEGREENSHIELD3 + || tmthing->type == MT_TRIPLEREDSHIELD1 || tmthing->type == MT_TRIPLEREDSHIELD2 || tmthing->type == MT_TRIPLEREDSHIELD3) + && (thing->type == MT_TRIPLEGREENSHIELD1 || thing->type == MT_TRIPLEGREENSHIELD2 || thing->type == MT_TRIPLEGREENSHIELD3 + || thing->type == MT_TRIPLEREDSHIELD1 || thing->type == MT_TRIPLEREDSHIELD2 || thing->type == MT_TRIPLEREDSHIELD3)) + && (tmthing->target == thing->target)) // Don't hit each other if you have the same target + return true; + + if (thing->type == MT_PLAYER) + { + // Player Damage + P_DamageMobj(thing, tmthing, tmthing->target, 1); + + + // This Item Damage + if (tmthing->eflags & MFE_VERTICALFLIP) + tmthing->z -= tmthing->height; + else + tmthing->z += tmthing->height; + + S_StartSound(tmthing, tmthing->info->deathsound); + P_KillMobj(tmthing, thing, thing); + + P_SetObjectMomZ(tmthing, 8*FRACUNIT, false); + P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT); + } + else if (thing->type == MT_GREENITEM || thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD + || thing->type == MT_GREENSHIELD || thing->type == MT_REDSHIELD + || thing->type == MT_TRIPLEGREENSHIELD1 || thing->type == MT_TRIPLEGREENSHIELD2 || thing->type == MT_TRIPLEGREENSHIELD3 + || thing->type == MT_TRIPLEREDSHIELD1 || thing->type == MT_TRIPLEREDSHIELD2 || thing->type == MT_TRIPLEREDSHIELD3 + || thing->type == MT_BANANAITEM || thing->type == MT_BANANASHIELD + || thing->type == MT_TRIPLEBANANASHIELD1 || thing->type == MT_TRIPLEBANANASHIELD2 || thing->type == MT_TRIPLEBANANASHIELD3 + ) + { + // Other Item Damage + if (thing->eflags & MFE_VERTICALFLIP) + thing->z -= thing->height; + else + thing->z += thing->height; + + S_StartSound(thing, thing->info->deathsound); + P_KillMobj(thing, tmthing, tmthing); + + P_SetObjectMomZ(thing, 8*FRACUNIT, false); + P_InstaThrust(thing, R_PointToAngle2(tmthing->x, tmthing->y, thing->x, thing->y)+ANGLE_90, 16*FRACUNIT); + + + // This Item Damage + if (tmthing->eflags & MFE_VERTICALFLIP) + tmthing->z -= tmthing->height; + else + tmthing->z += tmthing->height; + + S_StartSound(tmthing, tmthing->info->deathsound); + P_KillMobj(tmthing, thing, thing); + + P_SetObjectMomZ(tmthing, 8*FRACUNIT, false); + P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT); + } + else if (thing->type == MT_FAKEITEM || thing->type == MT_FAKESHIELD) + { + if (tmthing->type == MT_GREENSHIELD || tmthing->type == MT_REDSHIELD + || tmthing->type == MT_TRIPLEGREENSHIELD1 || tmthing->type == MT_TRIPLEGREENSHIELD2 || tmthing->type == MT_TRIPLEGREENSHIELD3 + || tmthing->type == MT_TRIPLEREDSHIELD1 || tmthing->type == MT_TRIPLEREDSHIELD2 || tmthing->type == MT_TRIPLEREDSHIELD3) + { + // This Item Damage + if (tmthing->eflags & MFE_VERTICALFLIP) + tmthing->z -= tmthing->height; + else + tmthing->z += tmthing->height; + + S_StartSound(tmthing, tmthing->info->deathsound); + P_KillMobj(tmthing, thing, thing); + + P_SetObjectMomZ(tmthing, 8*FRACUNIT, false); + P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT); + } + + // Other Item Damage + if (thing->eflags & MFE_VERTICALFLIP) + thing->z -= thing->height; + else + thing->z += thing->height; + + S_StartSound(thing, thing->info->deathsound); + P_KillMobj(thing, tmthing, tmthing); + + P_SetObjectMomZ(thing, 8*FRACUNIT, false); + P_InstaThrust(thing, R_PointToAngle2(tmthing->x, tmthing->y, thing->x, thing->y)+ANGLE_90, 16*FRACUNIT); + } + else if (thing->type == MT_BOMBSHIELD || thing->type == MT_BOMBITEM) + { + // This Item Damage + if (tmthing->eflags & MFE_VERTICALFLIP) + tmthing->z -= tmthing->height; + else + tmthing->z += tmthing->height; + + S_StartSound(tmthing, tmthing->info->deathsound); + P_KillMobj(tmthing, thing, thing); + + P_SetObjectMomZ(tmthing, 8*FRACUNIT, false); + P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT); + + + // Bomb death + P_KillMobj(thing, tmthing, tmthing); + } + else if (thing->flags & MF_SPRING && (tmthing->type == MT_REDITEM || tmthing->type == MT_REDITEMDUD || tmthing->type == MT_GREENITEM)) + P_DoSpring(thing, tmthing); + + return true; + } + else if (tmthing->flags & MF_SPRING && (thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD || thing->type == MT_GREENITEM)) + { + // see if it went over / under + if (tmthing->z > thing->z + thing->height) + return true; // overhead + if (tmthing->z + tmthing->height < thing->z) + return true; // underneath + + if (thing->health <= 0) + return true; + + P_DoSpring(tmthing, thing); + + return true; + } + else if (tmthing->type == MT_SINK) + { + // see if it went over / under + if (tmthing->z > thing->z + thing->height) + return true; // overhead + if (tmthing->z + tmthing->height < thing->z) + return true; // underneath + + if (((tmthing->target == thing) || (tmthing->target == thing->target)) && (tmthing->threshold > 0 || (thing->type != MT_PLAYER && thing->threshold > 0))) + return true; + + if (thing->type == MT_PLAYER) + { + S_StartSound(NULL, sfx_cgot); //let all players hear it. + HU_SetCEchoFlags(0); + HU_SetCEchoDuration(5); + HU_DoCEcho(va("%s\\was hit by a kitchen sink.\\\\\\\\", player_names[thing->player-players])); + I_OutputMsg("%s was hit by a kitchen sink.\n", player_names[thing->player-players]); + P_DamageMobj(thing, tmthing, tmthing->target, 10000); + P_KillMobj(tmthing, thing, thing); + } + + return true; + } + else if (tmthing->type == MT_BOMBEXPLOSION) + { + // see if it went over / under + if (tmthing->z > thing->z + thing->height) + return true; // overhead + if (tmthing->z + tmthing->height < thing->z) + return true; // underneath + + if (!(thing->type == MT_PLAYER)) + return true; + + if (thing->type == MT_PLAYER) + { + K_SpinPlayer(thing->player, tmthing->target); + } + + return true; // This doesn't collide with anything, but we want it to effect the player anyway. + } + else if (tmthing->type == MT_BANANASHIELD || tmthing->type == MT_BANANAITEM + || tmthing->type == MT_TRIPLEBANANASHIELD1 || tmthing->type == MT_TRIPLEBANANASHIELD2 || tmthing->type == MT_TRIPLEBANANASHIELD3) + { + // see if it went over / under + if (tmthing->z > thing->z + thing->height) + return true; // overhead + if (tmthing->z + tmthing->height < thing->z) + return true; // underneath + + if (((tmthing->target == thing) || (tmthing->target == thing->target)) && (tmthing->threshold > 0 || (thing->type != MT_PLAYER && thing->threshold > 0))) + return true; + + if (tmthing->health <= 0 || thing->health <= 0) + return true; + + if (((tmthing->type == MT_BANANASHIELD || tmthing->type == MT_TRIPLEBANANASHIELD1 || tmthing->type == MT_TRIPLEBANANASHIELD2 || tmthing->type == MT_TRIPLEBANANASHIELD3) + && (thing->type == MT_BANANASHIELD || thing->type == MT_TRIPLEBANANASHIELD1 || thing->type == MT_TRIPLEBANANASHIELD2 || thing->type == MT_TRIPLEBANANASHIELD3)) + && (tmthing->target == thing->target)) // Don't hit each other if you have the same target + return true; + + if (thing->type == MT_PLAYER) + { + // Player Damage + K_SpinPlayer(thing->player, tmthing->target); + + // This Item Damage + if (tmthing->eflags & MFE_VERTICALFLIP) + tmthing->z -= tmthing->height; + else + tmthing->z += tmthing->height; + + S_StartSound(tmthing, tmthing->info->deathsound); + P_KillMobj(tmthing, thing, thing); + + P_SetObjectMomZ(tmthing, 8*FRACUNIT, false); + P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT); + } + else if (thing->type == MT_BANANASHIELD || thing->type == MT_BANANAITEM + || thing->type == MT_TRIPLEBANANASHIELD1 || thing->type == MT_TRIPLEBANANASHIELD2 || thing->type == MT_TRIPLEBANANASHIELD3 + || thing->type == MT_GREENITEM || thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD + || thing->type == MT_GREENSHIELD || thing->type == MT_TRIPLEGREENSHIELD1 || thing->type == MT_TRIPLEGREENSHIELD2 || thing->type == MT_TRIPLEGREENSHIELD3 + || thing->type == MT_REDSHIELD || thing->type == MT_TRIPLEREDSHIELD1 || thing->type == MT_TRIPLEREDSHIELD2 || thing->type == MT_TRIPLEREDSHIELD3) + { + // Other Item Damage + if (thing->eflags & MFE_VERTICALFLIP) + thing->z -= thing->height; + else + thing->z += thing->height; + + S_StartSound(thing, thing->info->deathsound); + P_KillMobj(thing, tmthing, tmthing); + + P_SetObjectMomZ(thing, 8*FRACUNIT, false); + P_InstaThrust(thing, R_PointToAngle2(tmthing->x, tmthing->y, thing->x, thing->y)+ANGLE_90, 16*FRACUNIT); + + // This Item Damage + if (tmthing->eflags & MFE_VERTICALFLIP) + tmthing->z -= tmthing->height; + else + tmthing->z += tmthing->height; + + S_StartSound(tmthing, tmthing->info->deathsound); + P_KillMobj(tmthing, thing, thing); + + P_SetObjectMomZ(tmthing, 8*FRACUNIT, false); + P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT); + } + else if (thing->type == MT_FAKEITEM || thing->type == MT_FAKESHIELD) + { + if (tmthing->type == MT_BANANASHIELD || tmthing->type == MT_TRIPLEBANANASHIELD1 || tmthing->type == MT_TRIPLEBANANASHIELD2 || tmthing->type == MT_TRIPLEBANANASHIELD3) + { + // This Item Damage + if (tmthing->eflags & MFE_VERTICALFLIP) + tmthing->z -= tmthing->height; + else + tmthing->z += tmthing->height; + + S_StartSound(tmthing, tmthing->info->deathsound); + P_KillMobj(tmthing, thing, thing); + + P_SetObjectMomZ(tmthing, 8*FRACUNIT, false); + P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT); + } + // Other Item Damage + if (thing->eflags & MFE_VERTICALFLIP) + thing->z -= thing->height; + else + thing->z += thing->height; + + S_StartSound(thing, thing->info->deathsound); + P_KillMobj(thing, tmthing, tmthing); + + P_SetObjectMomZ(thing, 8*FRACUNIT, false); + P_InstaThrust(thing, R_PointToAngle2(tmthing->x, tmthing->y, thing->x, thing->y)+ANGLE_90, 16*FRACUNIT); + } + + return true; + } + else if (tmthing->type == MT_FAKESHIELD || tmthing->type == MT_FAKEITEM) + { + // see if it went over / under + if (tmthing->z > thing->z + thing->height) + return true; // overhead + if (tmthing->z + tmthing->height < thing->z) + return true; // underneath + + if (((tmthing->target == thing) || (tmthing->target == thing->target)) && (tmthing->threshold > 0 || (thing->type != MT_PLAYER && thing->threshold > 0))) + return true; + + if (tmthing->health <= 0 || thing->health <= 0) + return true; + + if (thing->type == MT_GREENITEM // When these items collide with the fake item, just the fake item is destroyed + || thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD + || thing->type == MT_BOMBITEM + || thing->type == MT_BANANAITEM) + { + // This Item Damage + if (tmthing->eflags & MFE_VERTICALFLIP) + tmthing->z -= tmthing->height; + else + tmthing->z += tmthing->height; + + S_StartSound(tmthing, tmthing->info->deathsound); + P_KillMobj(tmthing, thing, thing); + + P_SetObjectMomZ(tmthing, 8*FRACUNIT, false); + P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT); + } + else if (thing->type == MT_GREENSHIELD || thing->type == MT_TRIPLEGREENSHIELD1 || thing->type == MT_TRIPLEGREENSHIELD2 || thing->type == MT_TRIPLEGREENSHIELD3 // When these items collide with the fake item, both of them are destroyed + || thing->type == MT_REDSHIELD || thing->type == MT_TRIPLEREDSHIELD1 || thing->type == MT_TRIPLEREDSHIELD2 || thing->type == MT_TRIPLEREDSHIELD3 + || thing->type == MT_BOMBSHIELD + || thing->type == MT_BANANASHIELD || thing->type == MT_TRIPLEBANANASHIELD1 || thing->type == MT_TRIPLEBANANASHIELD2 || thing->type == MT_TRIPLEBANANASHIELD3 + || thing->type == MT_FAKEITEM || thing->type == MT_FAKESHIELD) + { + // Other Item Damage + if (thing->eflags & MFE_VERTICALFLIP) + thing->z -= thing->height; + else + thing->z += thing->height; + + S_StartSound(thing, thing->info->deathsound); + P_KillMobj(thing, tmthing, tmthing); + + P_SetObjectMomZ(thing, 8*FRACUNIT, false); + P_InstaThrust(thing, R_PointToAngle2(tmthing->x, tmthing->y, thing->x, thing->y)+ANGLE_90, 16*FRACUNIT); + + // This Item Damage + if (tmthing->eflags & MFE_VERTICALFLIP) + tmthing->z -= tmthing->height; + else + tmthing->z += tmthing->height; + + S_StartSound(tmthing, tmthing->info->deathsound); + P_KillMobj(tmthing, thing, thing); + + P_SetObjectMomZ(tmthing, 8*FRACUNIT, false); + P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT); + } + else if (thing->type == MT_PLAYER) + { + // Player Damage + P_DamageMobj(thing, tmthing, tmthing->target, 1); + + // This Item Damage + if (tmthing->eflags & MFE_VERTICALFLIP) + tmthing->z -= tmthing->height; + else + tmthing->z += tmthing->height; + + S_StartSound(tmthing, tmthing->info->deathsound); + P_KillMobj(tmthing, thing, thing); + + P_SetObjectMomZ(tmthing, 8*FRACUNIT, false); + P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT); + } + + return true; + } + else if (tmthing->type == MT_BOMBSHIELD || tmthing->type == MT_BOMBITEM) + { + // see if it went over / under + if (tmthing->z > thing->z + thing->height) + return true; // overhead + if (tmthing->z + tmthing->height < thing->z) + return true; // underneath + + if (((tmthing->target == thing) || (tmthing->target == thing->target)) && (tmthing->threshold > 0 || (thing->type != MT_PLAYER && thing->threshold > 0))) + return true; + + if (tmthing->health <= 0 || thing->health <= 0) + return true; + + if (thing->type == MT_PLAYER) + { + P_KillMobj(tmthing, thing, thing); + } + else if (thing->type == MT_GREENITEM || thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD + || thing->type == MT_GREENSHIELD || thing->type == MT_TRIPLEGREENSHIELD1 || thing->type == MT_TRIPLEGREENSHIELD2 || thing->type == MT_TRIPLEGREENSHIELD3 + || thing->type == MT_REDSHIELD || thing->type == MT_TRIPLEREDSHIELD1 || thing->type == MT_TRIPLEREDSHIELD2 || thing->type == MT_TRIPLEREDSHIELD3) + { + P_KillMobj(tmthing, thing, thing); + + // Other Item Damage + if (thing->eflags & MFE_VERTICALFLIP) + thing->z -= thing->height; + else + thing->z += thing->height; + + S_StartSound(thing, thing->info->deathsound); + P_KillMobj(thing, tmthing, tmthing); + + P_SetObjectMomZ(thing, 8*FRACUNIT, false); + P_InstaThrust(thing, R_PointToAngle2(tmthing->x, tmthing->y, thing->x, thing->y)+ANGLE_90, 16*FRACUNIT); + } + + return true; + } + else if (tmthing->type == MT_PLAYER && + (thing->type == MT_GREENSHIELD || thing->type == MT_GREENITEM + || thing->type == MT_REDSHIELD || thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD + || thing->type == MT_TRIPLEGREENSHIELD1 || thing->type == MT_TRIPLEGREENSHIELD2 || thing->type == MT_TRIPLEGREENSHIELD3 + || thing->type == MT_TRIPLEREDSHIELD1 || thing->type == MT_TRIPLEREDSHIELD2 || thing->type == MT_TRIPLEREDSHIELD3 + || thing->type == MT_FAKESHIELD || thing->type == MT_FAKEITEM + || thing->type == MT_BANANASHIELD || thing->type == MT_BANANAITEM + || thing->type == MT_TRIPLEBANANASHIELD1 || thing->type == MT_TRIPLEBANANASHIELD2 || thing->type == MT_TRIPLEBANANASHIELD3 + || thing->type == MT_BOMBSHIELD || thing->type == MT_BOMBITEM + || thing->type == MT_BOMBEXPLOSION + || thing->type == MT_SINK + )) + { + // see if it went over / under + if (tmthing->z > thing->z + thing->height) + return true; // overhead + if (tmthing->z + tmthing->height < thing->z) + return true; // underneath + + if (thing->type == MT_GREENSHIELD || thing->type == MT_TRIPLEGREENSHIELD1 || thing->type == MT_TRIPLEGREENSHIELD2 || thing->type == MT_TRIPLEGREENSHIELD3 + || thing->type == MT_REDSHIELD || thing->type == MT_TRIPLEREDSHIELD1 || thing->type == MT_TRIPLEREDSHIELD2 || thing->type == MT_TRIPLEREDSHIELD3 + || thing->type == MT_GREENITEM || thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD + || thing->type == MT_FAKESHIELD || thing->type == MT_FAKEITEM) + { + if ((thing->target == tmthing) && (thing->threshold > 0)) + return true; + + if (tmthing->health <= 0 || thing->health <= 0) + return true; + + // Player Damage + P_DamageMobj(tmthing, thing, thing->target, 1); + + // Other Item Damage + if (thing->eflags & MFE_VERTICALFLIP) + thing->z -= thing->height; + else + thing->z += thing->height; + + S_StartSound(thing, thing->info->deathsound); + P_KillMobj(thing, tmthing, tmthing); + + P_SetObjectMomZ(thing, 8*FRACUNIT, false); + P_InstaThrust(thing, R_PointToAngle2(tmthing->x, tmthing->y, thing->x, thing->y)+ANGLE_90, 16*FRACUNIT); + } + else if (thing->type == MT_BANANASHIELD || thing->type == MT_BANANAITEM + || thing->type == MT_TRIPLEBANANASHIELD1 || thing->type == MT_TRIPLEBANANASHIELD2 || thing->type == MT_TRIPLEBANANASHIELD3) + { + if ((thing->target == tmthing) && (thing->threshold > 0)) + return true; + + if (tmthing->health <= 0 || thing->health <= 0) + return true; + + // Player Damage + K_SpinPlayer(tmthing->player, thing->target); + + // Other Item Damage + if (thing->eflags & MFE_VERTICALFLIP) + thing->z -= thing->height; + else + thing->z += thing->height; + + S_StartSound(thing, thing->info->deathsound); + P_KillMobj(thing, tmthing, tmthing); + + P_SetObjectMomZ(thing, 8*FRACUNIT, false); + P_InstaThrust(thing, R_PointToAngle2(tmthing->x, tmthing->y, thing->x, thing->y)+ANGLE_90, 16*FRACUNIT); + } + else if (thing->type == MT_BOMBSHIELD || thing->type == MT_BOMBITEM) + { + if ((thing->target == tmthing) && (thing->threshold > 0)) + return true; + + if (tmthing->health <= 0 || thing->health <= 0) + return true; + + P_KillMobj(thing, tmthing, tmthing); + } + else if (thing->type == MT_BOMBEXPLOSION) + { + // Player Damage + K_SpinPlayer(tmthing->player, thing->target); + + return true; + } + else if (thing->type == MT_SINK) + { + if ((thing->target == tmthing) && (thing->threshold > 0)) + return true; + + S_StartSound(NULL, sfx_cgot); //let all players hear it. + HU_SetCEchoFlags(0); + HU_SetCEchoDuration(5); + HU_DoCEcho(va("%s\\was hit by a kitchen sink.\\\\\\\\", player_names[tmthing->player-players])); + I_OutputMsg("%s was hit by a kitchen sink.\n", player_names[tmthing->player-players]); + P_DamageMobj(tmthing, thing, thing->target, 10000); + P_KillMobj(thing, tmthing, tmthing); + } + + return true; + } + + + if (thing->type == MT_POKEY) + { + // see if it went over / under + if (tmthing->z > thing->z + thing->height) + return true; // overhead + if (tmthing->z + tmthing->height < thing->z) + return true; // underneath + + if (tmthing->type == MT_ENEMYFLIP) + { + if (tmthing->angle) + P_SetMobjState(thing, S_POKEY5); + else + P_SetMobjState(thing, S_POKEY1); + } + if (tmthing->type == MT_PLAYER && !thing->threshold) + P_DamageMobj(tmthing, thing, thing->target, 1); + } + + //} + if ((thing->type == MT_SPRINGSHELL || thing->type == MT_YELLOWSHELL) && thing->health > 0 && (tmthing->player || (tmthing->flags & MF_PUSHABLE)) && tmthing->health > 0) { diff --git a/src/p_saveg.c b/src/p_saveg.c index aee50e61..0454232e 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -268,6 +268,10 @@ static void P_NetArchivePlayers(void) WRITEFIXED(save_p, players[i].actionspd); WRITEFIXED(save_p, players[i].mindash); WRITEFIXED(save_p, players[i].maxdash); + // SRB2kart + WRITEUINT8(save_p, players[i].kartspeed); + WRITEUINT8(save_p, players[i].kartweight); + // WRITEFIXED(save_p, players[i].normalspeed); WRITEFIXED(save_p, players[i].runspeed); WRITEUINT8(save_p, players[i].thrustfactor); @@ -434,6 +438,10 @@ static void P_NetUnArchivePlayers(void) players[i].actionspd = READFIXED(save_p); players[i].mindash = READFIXED(save_p); players[i].maxdash = READFIXED(save_p); + // SRB2kart + players[i].kartspeed = READUINT8(save_p); + players[i].kartweight = READUINT8(save_p); + // players[i].normalspeed = READFIXED(save_p); players[i].runspeed = READFIXED(save_p); players[i].thrustfactor = READUINT8(save_p); diff --git a/src/p_setup.c b/src/p_setup.c index b36bf0b8..bf229271 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2481,9 +2481,13 @@ boolean P_SetupLevel(boolean skipprecip) S_StopSounds(); S_ClearSfx(); - // As oddly named as this is, this handles music only. - // We should be fine starting it here. - S_Start(); + // SRB2kart 010217 + if (leveltime < 157) + S_StopMusic(); + if (leveltime > 157) + // As oddly named as this is, this handles music only. + // We should be fine starting it here. + S_Start(); // Let's fade to black here // But only if we didn't do the special stage wipe diff --git a/src/p_spec.c b/src/p_spec.c index 18378b84..2ec4d7b2 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -35,6 +35,8 @@ #include "m_cond.h" //unlock triggers #include "lua_hook.h" // LUAh_LinedefExecute +#include "k_kart.h" // SRB2kart + #ifdef HW3SOUND #include "hardware/hw3sound.h" #endif @@ -50,6 +52,9 @@ mobj_t *skyboxmo[2]; // Amount (dx, dy) vector linedef is shifted right to get scroll amount #define SCROLL_SHIFT 5 + +// This must be updated whenever we up the max flat size - quicker to assume rather than figuring out the sqrt of the specific flat's filesize. +#define MAXFLATSIZE (2048<mo, S_PLAY_FALL1); break; - case 6: // Super Sonic transformer - if (player->mo->health > 0 && !player->bot && (player->charflags & SF_SUPER) && !player->powers[pw_super] && ALL7EMERALDS(emeralds)) - P_DoSuperTransformation(player, true); + + case 6: // Super Sonic transformer // SRB2kart 190117- Replaced. This is now a Mushroom Boost Panel + if (!player->kartstuff[k_floorboost]) + player->kartstuff[k_floorboost] = 3; + else + player->kartstuff[k_floorboost] = 2; + K_DoMushroom(player, false); break; - case 7: // Make player spin - /* // SRB2kart - no. - if (!(player->pflags & PF_SPINNING) && P_IsObjectOnGround(player->mo) && (player->charability2 == CA2_SPINDASH)) + /* if (player->mo->health > 0 && !player->bot && (player->charflags & SF_SUPER) && !player->powers[pw_super] && ALL7EMERALDS(emeralds)) + P_DoSuperTransformation(player, true); + break; */ + + case 7: // Make player spin // SRB2kart 190117- Replaced. This is now an Oil Slick (Oddly ironic considering) + player->kartstuff[k_spinouttype] = -1; + K_SpinPlayer(player, NULL); + break; + + /* if (!(player->pflags & PF_SPINNING) && P_IsObjectOnGround(player->mo) && (player->charability2 == CA2_SPINDASH)) { player->pflags |= PF_SPINNING; P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); @@ -3861,8 +3877,8 @@ DoneSection2: if (abs(player->rmomx) < FixedMul(5*FRACUNIT, player->mo->scale) && abs(player->rmomy) < FixedMul(5*FRACUNIT, player->mo->scale)) P_InstaThrust(player->mo, player->mo->angle, FixedMul(10*FRACUNIT, player->mo->scale)); - }*/ - break; + } + break; */ case 8: // Zoom Tube Start { @@ -3924,11 +3940,15 @@ DoneSection2: P_SetTarget(&player->mo->tracer, waypoint); player->speed = speed; + player->pflags &= ~PF_SPINNING; // SRB2kart 200117 player->pflags |= PF_SPINNING; player->pflags &= ~PF_JUMPED; player->pflags &= ~PF_GLIDING; player->climbing = 0; + if (!(player->mo->state >= &states[S_KART_RUN1] && player->mo->state <= &states[S_KART_RUN2])) + P_SetPlayerMobjState(player->mo, S_KART_RUN1); + //if (!(player->mo->state >= &states[S_PLAY_ATK1] && player->mo->state <= &states[S_PLAY_ATK4])) // SRB2kart //{ // P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); @@ -3998,9 +4018,13 @@ DoneSection2: P_SetTarget(&player->mo->tracer, waypoint); player->speed = speed; + player->pflags &= ~PF_SPINNING; // SRB2kart 200117 player->pflags |= PF_SPINNING; player->pflags &= ~PF_JUMPED; + if (!(player->mo->state >= &states[S_KART_RUN1] && player->mo->state <= &states[S_KART_RUN2])) + P_SetPlayerMobjState(player->mo, S_KART_RUN1); + //if (!(player->mo->state >= &states[S_PLAY_ATK1] && player->mo->state <= &states[S_PLAY_ATK4])) // SRB2kart //{ // P_SetPlayerMobjState(player->mo, S_PLAY_ATK1); @@ -4010,6 +4034,10 @@ DoneSection2: break; case 10: // Finish Line + // SRB2kart - 150117 + if (gametype == GT_RACE && (player->starpostnum == numstarposts || player->exiting)) + player->kartstuff[k_starpostwp] = player->kartstuff[k_waypoint] = 0; + // if (gametype == GT_RACE && !player->exiting) { if (player->starpostnum == numstarposts) // Must have touched all the starposts @@ -4021,16 +4049,47 @@ DoneSection2: if (player->laps >= (UINT8)cv_numlaps.value) CONS_Printf(M_GetText("%s has finished the race.\n"), player_names[player-players]); + else if (player->laps == (UINT8)(cv_numlaps.value - 1)) + CONS_Printf("%s started the final lap\n", player_names[player-players]); else CONS_Printf(M_GetText("%s started lap %u\n"), player_names[player-players], (UINT32)player->laps+1); // Reset starposts (checkpoints) info - player->starpostangle = player->starposttime = player->starpostnum = 0; + // SRB2kart 200117 + player->starpostangle = player->starpostnum = 0; player->starpostx = player->starposty = player->starpostz = 0; + //except the time! + player->starposttime = player->realtime; + if (((numstarposts+1)*player->laps - 1) < 256) //SIGSEGV prevention + player->checkpointtimes[(numstarposts+1)*player->laps - 1] = player->realtime; + player->kartstuff[k_playerahead] = P_CheckPlayerAhead(player, (numstarposts+1)*player->laps - 1); + + if (P_IsLocalPlayer(player)) + { + if (player->laps < (UINT8)(cv_numlaps.value - 1)) + { + S_StartSound(NULL, sfx_mlap); + player->kartstuff[k_lakitu] = -64; + } + else if (player->laps == (UINT8)(cv_numlaps.value - 1)) + { + player->kartstuff[k_lakitu] = -64; + + if (!splitscreen || (splitscreen && !players[consoleplayer].exiting + && !players[secondarydisplayplayer].exiting)) + { + //player->powers[pw_sounds] = 1; + S_ChangeMusicInternal("finlap", false); + } + } + } + // + //player->starpostangle = player->starposttime = player->starpostnum = 0; + //player->starpostx = player->starposty = player->starpostz = 0; P_ResetStarposts(); // Play the starpost sound for 'consistency' - S_StartSound(player->mo, sfx_strpst); + // S_StartSound(player->mo, sfx_strpst); } else if (player->starpostnum) { @@ -4044,9 +4103,22 @@ DoneSection2: { if (P_IsLocalPlayer(player)) { - HU_SetCEchoFlags(0); - HU_SetCEchoDuration(5); - HU_DoCEcho("FINISHED!"); + // SRB2kart 200117 + if (!splitscreen) + { + if (player->kartstuff[k_position] == 1) + S_ChangeMusicInternal("karwin", true); + else if (player->kartstuff[k_position] == 2 || player->kartstuff[k_position] == 3) + S_ChangeMusicInternal("karok", true); + else if (player->kartstuff[k_position] >= 4) + S_ChangeMusicInternal("karlos", true); + } + else + S_ChangeMusicInternal("karwin", true); + // + //HU_SetCEchoFlags(0); + //HU_SetCEchoDuration(5); + //HU_DoCEcho("FINISHED!"); } P_DoPlayerExit(player); @@ -5485,37 +5557,31 @@ void P_SpawnSpecials(INT32 fromnetsave) secthinkers[secnum].thinkers[secthinkers[secnum].count++] = th; } - // Init line EFFECTs for (i = 0; i < numlines; i++) { - // set line specials to 0 here too, same reason as above - if (netgame || multiplayer) + if (lines[i].special != 7) // This is a hack. I can at least hope nobody wants to prevent flat alignment with arbitrary skin setups... { - // future: nonet flag? - } - else if ((lines[i].flags & ML_NETONLY) == ML_NETONLY) - { - lines[i].special = 0; - continue; - } - else - { - if (players[consoleplayer].charability == CA_THOK && (lines[i].flags & ML_NOSONIC)) + // set line specials to 0 here too, same reason as above + if (netgame || multiplayer) + { + // future: nonet flag? + } + else if ((lines[i].flags & ML_NETONLY) == ML_NETONLY) { lines[i].special = 0; continue; } - if (players[consoleplayer].charability == CA_FLY && (lines[i].flags & ML_NOTAILS)) + /*else -- commented out because irrelevant to kart { - lines[i].special = 0; - continue; - } - if (players[consoleplayer].charability == CA_GLIDEANDCLIMB && (lines[i].flags & ML_NOKNUX)) - { - lines[i].special = 0; - continue; - } + if ((players[consoleplayer].charability == CA_THOK && (lines[i].flags & ML_NOSONIC)) + || (players[consoleplayer].charability == CA_FLY && (lines[i].flags & ML_NOTAILS)) + || (players[consoleplayer].charability == CA_GLIDEANDCLIMB && (lines[i].flags & ML_NOKNUX))) + { + lines[i].special = 0; + continue; + } + }*/ } switch (lines[i].special) @@ -5559,50 +5625,55 @@ void P_SpawnSpecials(INT32 fromnetsave) I_Error("Failed to catch a disable linedef"); break; #endif - - case 7: // Flat alignment - if (lines[i].flags & ML_EFFECT4) // Align angle + case 7: // Flat alignment - redone by toast + if ((lines[i].flags & (ML_NOSONIC|ML_NOTAILS)) != (ML_NOSONIC|ML_NOTAILS)) // If you can do something... { - if (!(lines[i].flags & ML_EFFECT5)) // Align floor unless ALLTRIGGER flag is set + angle_t flatangle = InvAngle(R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y)); + fixed_t xoffs; + fixed_t yoffs; + + if (lines[i].flags & ML_NOKNUX) // Set offset through x and y texture offsets if NOKNUX flag is set { - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) - sectors[s].spawn_flrpic_angle = sectors[s].floorpic_angle = R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y); + xoffs = sides[lines[i].sidenum[0]].textureoffset; + yoffs = sides[lines[i].sidenum[0]].rowoffset; } - - if (!(lines[i].flags & ML_BOUNCY)) // Align ceiling unless BOUNCY flag is set + else // Otherwise, set calculated offsets such that line's v1 is the apparent origin { - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) - sectors[s].spawn_ceilpic_angle = sectors[s].ceilingpic_angle = R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y); + fixed_t cosinecomponent = FINECOSINE(flatangle>>ANGLETOFINESHIFT); + fixed_t sinecomponent = FINESINE(flatangle>>ANGLETOFINESHIFT); + xoffs = (-FixedMul(lines[i].v1->x, cosinecomponent) % MAXFLATSIZE) + (FixedMul(lines[i].v1->y, sinecomponent) % MAXFLATSIZE); // No danger of overflow thanks to the strategically placed modulo operations. + yoffs = (FixedMul(lines[i].v1->x, sinecomponent) % MAXFLATSIZE) + (FixedMul(lines[i].v1->y, cosinecomponent) % MAXFLATSIZE); // Ditto. } - } - else // Do offsets - { - if (!(lines[i].flags & ML_BLOCKMONSTERS)) // Align floor unless BLOCKMONSTERS flag is set + + for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) { - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + if (!(lines[i].flags & ML_NOSONIC)) // Modify floor flat alignment unless NOSONIC flag is set { - sectors[s].floor_xoffs += lines[i].dx; - sectors[s].floor_yoffs += lines[i].dy; + sectors[s].spawn_flrpic_angle = sectors[s].floorpic_angle = flatangle; + sectors[s].floor_xoffs += xoffs; + sectors[s].floor_yoffs += yoffs; // saved for netgames sectors[s].spawn_flr_xoffs = sectors[s].floor_xoffs; sectors[s].spawn_flr_yoffs = sectors[s].floor_yoffs; } - } - - if (!(lines[i].flags & ML_NOCLIMB)) // Align ceiling unless NOCLIMB flag is set - { - for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) + + if (!(lines[i].flags & ML_NOTAILS)) // Modify ceiling flat alignment unless NOTAILS flag is set { - sectors[s].ceiling_xoffs += lines[i].dx; - sectors[s].ceiling_yoffs += lines[i].dy; + sectors[s].spawn_ceilpic_angle = sectors[s].ceilingpic_angle = flatangle; + sectors[s].ceiling_xoffs += xoffs; + sectors[s].ceiling_yoffs += yoffs; // saved for netgames sectors[s].spawn_ceil_xoffs = sectors[s].ceiling_xoffs; sectors[s].spawn_ceil_yoffs = sectors[s].ceiling_yoffs; } } } + else // Otherwise, print a helpful warning. Can I do no less? + CONS_Alert(CONS_WARNING, + M_GetText("Flat alignment linedef (tag %d) doesn't have anything to do.\nConsider changing the linedef's flag configuration or removing it entirely.\n"), + lines[i].tag); break; - + case 8: // Sector Parameters for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;) { @@ -6976,7 +7047,9 @@ void T_Friction(friction_t *f) // apparently, all I had to do was comment out part of the next line and // friction works for all mobj's // (or at least MF_PUSHABLEs, which is all I care about anyway) - if (!(thing->flags & (MF_NOGRAVITY | MF_NOCLIP)) && thing->z == thing->floorz) + if ((!(thing->flags & (MF_NOGRAVITY | MF_NOCLIP)) && thing->z == thing->floorz) && (thing->player + && (thing->player->kartstuff[k_startimer] && thing->player->kartstuff[k_bootaketimer] + && thing->player->kartstuff[k_mushroomtimer] && thing->player->kartstuff[k_growshrinktimer] <= 0))) { if (f->roverfriction) { diff --git a/src/p_user.c b/src/p_user.c index 06f7ca80..59d529a2 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4571,9 +4571,9 @@ static void P_3dMovement(player_t *player) } else { - if (player->kartstuff[k_drift] == 1) + if (player->kartstuff[k_drift] >= 1) movepushangle = player->mo->angle+ANGLE_45; - else if (player->kartstuff[k_drift] == -1) + else if (player->kartstuff[k_drift] <= -1) movepushangle = player->mo->angle-ANGLE_45; else movepushangle = player->mo->angle; @@ -4715,7 +4715,11 @@ static void P_3dMovement(player_t *player) && cmd->forwardmove != 0 && !(player->pflags & PF_GLIDING || player->exiting || (P_PlayerInPain(player) && !onground))) { - movepushforward = cmd->forwardmove * (thrustfactor * acceleration); + //movepushforward = cmd->forwardmove * (thrustfactor * acceleration); + if (cmd->forwardmove > 0) + movepushforward = K_3dKartMovement(player, onground); + else + movepushforward = -(K_3dKartMovement(player, onground)); // allow very small movement while in air for gameplay if (!onground) @@ -4764,7 +4768,11 @@ static void P_3dMovement(player_t *player) // (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 = max(abs(cmd->sidemove), abs(cmd->forwardmove)) * (thrustfactor * acceleration); + if (max(abs(cmd->sidemove), abs(cmd->forwardmove)) > 0) + movepushforward = K_3dKartMovement(player, onground); + else + movepushforward = -(K_3dKartMovement(player, onground)); // allow very small movement while in air for gameplay if (!onground) @@ -4800,7 +4808,11 @@ static void P_3dMovement(player_t *player) } else if (cmd->sidemove && !(player->pflags & PF_GLIDING) && !player->exiting && !P_PlayerInPain(player)) { - movepushside = cmd->sidemove * (thrustfactor * acceleration); + //movepushside = cmd->sidemove * (thrustfactor * acceleration); + if (cmd->sidemove > 0) + movepushside = K_3dKartMovement(player, onground); + else + movepushside = -(K_3dKartMovement(player, onground)); if (!onground) { @@ -6664,10 +6676,12 @@ static void P_MovePlayer(player_t *player) // Drifting sound { // Start looping the sound now. - if (leveltime % 50 == 0 && ((player->kartstuff[k_drift] == 1 || player->kartstuff[k_drift] == -1) && onground)) + if (leveltime % 50 == 0 && onground + && ((player->kartstuff[k_drift] >= 1 && player->kartstuff[k_drift] <= 3) + || (player->kartstuff[k_drift] <= -1 && player->kartstuff[k_drift] >= -3))) S_StartSound(player->mo, sfx_mkdrft); // Leveltime being 50 might take a while at times. We'll start it up once, isntantly. - else if ((player->kartstuff[k_drift] == 1 || player->kartstuff[k_drift] == -1) && !S_SoundPlaying(player->mo, sfx_mkdrft) && onground) + else if ((player->kartstuff[k_drift] >= 1 || player->kartstuff[k_drift] <= -1) && !S_SoundPlaying(player->mo, sfx_mkdrft) && onground) S_StartSound(player->mo, sfx_mkdrft); // Ok, we'll stop now. else if ((player->kartstuff[k_drift] == 0) @@ -7906,11 +7920,13 @@ static void P_DeathThink(player_t *player) countdown2 = 1*TICRATE; skipstats = true; + /* // SRB2kart 010217 - Score doesn't need to be reset in Kart. for (i = 0; i < MAXPLAYERS; i++) { if (playeringame[i]) players[i].score = 0; } + */ //emeralds = 0; tokenbits = 0; @@ -9037,7 +9053,7 @@ void P_PlayerThink(player_t *player) // Make sure spectators always have a score and ring count of 0. if (player->spectator) { - player->score = 0; + //player->score = 0; player->mo->health = 1; player->health = 1; } @@ -9052,12 +9068,17 @@ void P_PlayerThink(player_t *player) if (player == &players[displayplayer]) playerdeadview = false; + // SRB2kart 010217 + if (gametype == GT_RACE && leveltime < 4*TICRATE) + player->powers[pw_nocontrol] = 2; + /* if ((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE) { - cmd->buttons &= BT_BRAKE; // Remove all buttons except BT_BRAKE // TODO: ? + cmd->buttons &= BT_BRAKE; // Remove all buttons except BT_BRAKE cmd->forwardmove = 0; cmd->sidemove = 0; } + */ // Synchronizes the "real" amount of time spent in the level. if (!player->exiting) diff --git a/src/r_main.c b/src/r_main.c index 97d6876e..1655a566 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -139,7 +139,7 @@ static void FlipCam2_OnChange(void); void SendWeaponPref(void); void SendWeaponPref2(void); -consvar_t cv_tailspickup = {"tailspickup", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_tailspickup = {"tailspickup", "Off", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_chasecam = {"chasecam", "On", CV_CALL, CV_OnOff, ChaseCam_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_chasecam2 = {"chasecam2", "On", CV_CALL, CV_OnOff, ChaseCam2_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_flipcam = {"flipcam", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam_OnChange, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/r_things.c b/src/r_things.c index 44883f2c..331ff726 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2279,6 +2279,11 @@ static void Sk_SetDefaultValue(skin_t *skin) skin->starttranscolor = 160; skin->prefcolor = SKINCOLOR_GREEN; + // SRB2kart + skin->kartspeed = 7; + skin->kartweight = 5; + // + skin->normalspeed = 36<runspeed = 28<thrustfactor = 5; @@ -2422,6 +2427,11 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum) player->mindash = skin->mindash; player->maxdash = skin->maxdash; + // SRB2kart + player->kartspeed = skin->kartspeed; + player->kartweight = skin->kartweight; + // + player->normalspeed = skin->normalspeed; player->runspeed = skin->runspeed; player->thrustfactor = skin->thrustfactor; @@ -2644,6 +2654,10 @@ void R_AddSkins(UINT16 wadnum) #undef GETSPEED #define GETINT(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value); + // SRB2kart + GETINT(kartspeed) + GETINT(kartweight) + // GETINT(thrustfactor) GETINT(accelstart) GETINT(acceleration) diff --git a/src/r_things.h b/src/r_things.h index 483db7e9..e634b527 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -86,6 +86,11 @@ typedef struct fixed_t mindash; fixed_t maxdash; + // SRB2kart + UINT8 kartspeed; // Normal ground + UINT8 kartweight; // Normal ground + // + fixed_t normalspeed; // Normal ground fixed_t runspeed; // Speed that you break into your run animation diff --git a/src/s_sound.c b/src/s_sound.c index 5a654649..e19f9265 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -1159,7 +1159,7 @@ void S_StartSoundName(void *mo, const char *soundname) /// ------------------------ #ifdef MUSICSLOT_COMPATIBILITY -const char *compat_special_music_slots[16] = +const char *compat_special_music_slots[21] = { "titles", // 1036 title screen "read_m", // 1037 intro @@ -1176,6 +1176,12 @@ const char *compat_special_music_slots[16] = "credit", // 1048 credits "racent", // 1049 Race Results "stjr", // 1050 Sonic Team Jr. Presents + // SRB2kart 040217 + "finlap", // 1051 Sonic Team Jr. Presents + "karwin", // 1052 Sonic Team Jr. Presents + "karok", // 1053 Sonic Team Jr. Presents + "karlos", // 1054 Sonic Team Jr. Presents + "mega", // 1055 Sonic Team Jr. Presents "" }; #endif diff --git a/src/s_sound.h b/src/s_sound.h index bcc7979a..1f308447 100644 --- a/src/s_sound.h +++ b/src/s_sound.h @@ -142,7 +142,7 @@ void S_StopSoundByNum(sfxenum_t sfxnum); #ifdef MUSICSLOT_COMPATIBILITY // For compatibility with code/scripts relying on older versions // This is a list of all the "special" slot names and their associated numbers -const char *compat_special_music_slots[16]; +const char *compat_special_music_slots[21]; #endif #endif diff --git a/src/win32/Makefile.cfg b/src/win32/Makefile.cfg index f309f7db..a064dc38 100644 --- a/src/win32/Makefile.cfg +++ b/src/win32/Makefile.cfg @@ -57,9 +57,9 @@ endif # name of the exefile ifdef SDL - EXENAME?=srb2win.exe + EXENAME?=srb2kart.exe else - EXENAME?=srb2dd.exe + EXENAME?=srb2kartdd.exe endif ifdef SDL diff --git a/src/win32/Srb2win.ico b/src/win32/Srb2win.ico index 700276fd..6e667b61 100644 Binary files a/src/win32/Srb2win.ico and b/src/win32/Srb2win.ico differ diff --git a/src/y_inter.c b/src/y_inter.c index e5ff97ed..74f6978f 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -114,6 +114,9 @@ typedef union patch_t *redflag; // int_ctf uses this struct too. INT32 numplayers; // Number of players being displayed char levelstring[40]; // holds levelnames up to 32 characters + // SRB2kart + int increase[MAXPLAYERS]; //how much did the score increase by? + int time[MAXPLAYERS]; //Tournament Time } match; struct @@ -151,10 +154,12 @@ static INT32 endtic = -1; intertype_t intertype = int_none; -static void Y_AwardCoopBonuses(void); -static void Y_AwardSpecialStageBonus(void); +//static void Y_AwardCoopBonuses(void); +//static void Y_AwardSpecialStageBonus(void); +static void Y_CalculateTournamentPoints(void); // SRB2kart + static void Y_CalculateCompetitionWinners(void); -static void Y_CalculateTimeRaceWinners(void); +//static void Y_CalculateTimeRaceWinners(void); static void Y_CalculateMatchWinners(void); static void Y_FollowIntermission(void); static void Y_UnloadData(void); @@ -199,34 +204,32 @@ void Y_IntermissionDrawer(void) else V_DrawPatchFill(bgtile); - if (intertype == int_coop) + // SRB2kart 290117 - compeltely replaced this block. + if (intertype == int_timeattack) { - INT32 bonusy; - - // draw score - V_DrawScaledPatch(hudinfo[HUD_SCORE].x, hudinfo[HUD_SCORE].y, V_SNAPTOLEFT, sboscore); - V_DrawTallNum(hudinfo[HUD_SCORENUM].x, hudinfo[HUD_SCORENUM].y, V_SNAPTOLEFT, data.coop.score); - // draw time V_DrawScaledPatch(hudinfo[HUD_TIME].x, hudinfo[HUD_TIME].y, V_SNAPTOLEFT, sbotime); - if (cv_timetic.value == 1) + if (cv_timetic.value) V_DrawTallNum(hudinfo[HUD_SECONDS].x, hudinfo[HUD_SECONDS].y, V_SNAPTOLEFT, data.coop.tics); else { - // we should show centiseconds on the intermission screen too, if the conditions are right. - if (modeattacking || cv_timetic.value == 2) - { - V_DrawPaddedTallNum(hudinfo[HUD_TICS].x, hudinfo[HUD_TICS].y, V_SNAPTOLEFT, - G_TicsToCentiseconds(data.coop.tics), 2); - V_DrawScaledPatch(hudinfo[HUD_TIMETICCOLON].x, hudinfo[HUD_TIMETICCOLON].y, V_SNAPTOLEFT, sboperiod); - } - - V_DrawPaddedTallNum(hudinfo[HUD_SECONDS].x, hudinfo[HUD_SECONDS].y, V_SNAPTOLEFT, - G_TicsToSeconds(data.coop.tics), 2); - V_DrawScaledPatch(hudinfo[HUD_TIMECOLON].x, hudinfo[HUD_TIMECOLON].y, V_SNAPTOLEFT, sbocolon); - V_DrawTallNum(hudinfo[HUD_MINUTES].x, hudinfo[HUD_MINUTES].y, V_SNAPTOLEFT, - G_TicsToMinutes(data.coop.tics, false)); + if (G_TicsToSeconds(data.coop.tics) < 10) + V_DrawTallNum(hudinfo[HUD_TICS].x, hudinfo[HUD_TICS].y, 0, 0); + V_DrawTallNum(hudinfo[HUD_SECONDS].x, hudinfo[HUD_SECONDS].y, 0, G_TicsToSeconds(data.coop.tics)); + V_DrawTallNum(hudinfo[HUD_MINUTES].x, hudinfo[HUD_MINUTES].y, 0, G_TicsToMinutes(data.coop.tics, false)); + V_DrawScaledPatch(hudinfo[HUD_TIMECOLON].x, hudinfo[HUD_TIMECOLON].y, 0, sbocolon); + V_DrawTallNum(hudinfo[HUD_TICS].x, hudinfo[HUD_TICS].y, 0, (int)((data.coop.tics%TICRATE) * (100.00f/TICRATE))); + V_DrawScaledPatch(hudinfo[HUD_TIMETICCOLON].x, hudinfo[HUD_TIMETICCOLON].y, 0, sbocolon); } + + /* // SRB2kart - pulled from old coop block, just in case we need it + // we should show centiseconds on the intermission screen too, if the conditions are right. + if (modeattacking || cv_timetic.value == 2) + { + V_DrawPaddedTallNum(hudinfo[HUD_TICS].x, hudinfo[HUD_TICS].y, V_SNAPTOLEFT, + G_TicsToCentiseconds(data.coop.tics), 2); + V_DrawScaledPatch(hudinfo[HUD_TIMETICCOLON].x, hudinfo[HUD_TIMETICCOLON].y, V_SNAPTOLEFT, sboperiod); + }*/ // draw the "got through act" lines and act number V_DrawLevelTitle(data.coop.passedx1, 49, 0, data.coop.passed1); @@ -235,114 +238,141 @@ void Y_IntermissionDrawer(void) if (mapheaderinfo[gamemap-1]->actnum) V_DrawScaledPatch(244, 57, 0, data.coop.ttlnum); - bonusy = 150; - // Total - V_DrawScaledPatch(152, bonusy, 0, data.coop.ptotal); - V_DrawTallNum(BASEVIDWIDTH - 68, bonusy + 1, 0, data.coop.total); - bonusy -= (3*SHORT(tallnum[0]->height)/2) + 1; + //if (gottimebonus && endtic != -1) + // V_DrawCenteredString(BASEVIDWIDTH/2, 172, V_YELLOWMAP, "TIME BONUS UNLOCKED!"); + + V_DrawString(70, 106, V_YELLOWMAP, "LAP 1"); + V_DrawString(70, 116, V_YELLOWMAP, "LAP 2"); + V_DrawString(70, 126, V_YELLOWMAP, "LAP 3"); - // Draw bonuses - for (i = 3; i >= 0; --i) { - if (data.coop.bonuses[i].display) - { - V_DrawScaledPatch(152, bonusy, 0, data.coop.bonuspatches[i]); - V_DrawTallNum(BASEVIDWIDTH - 68, bonusy + 1, 0, data.coop.bonuses[i].points); - } - bonusy -= (3*SHORT(tallnum[0]->height)/2) + 1; + INT32 laptime; + laptime = stplyr->checkpointtimes[(numstarposts+1) - 1]; + V_DrawRightAlignedString(250, 106, 0, va("%d:%02d.%02d", laptime/(60*TICRATE), laptime/TICRATE % 60, (int)((laptime%TICRATE) * (100.00f/TICRATE)))); + laptime = stplyr->checkpointtimes[((numstarposts+1)*2) - 1] - stplyr->checkpointtimes[(numstarposts+1) - 1]; + V_DrawRightAlignedString(250, 116, 0, va("%d:%02d.%02d", laptime/(60*TICRATE), laptime/TICRATE % 60, (int)((laptime%TICRATE) * (100.00f/TICRATE)))); + laptime = stplyr->realtime - stplyr->checkpointtimes[((numstarposts+1)*2) - 1]; + V_DrawRightAlignedString(250, 126, 0, va("%d:%02d.%02d", laptime/(60*TICRATE), laptime/TICRATE % 60, (int)((laptime%TICRATE) * (100.00f/TICRATE)))); } } - else if (intertype == int_spec) + else if (intertype == int_race) { - static tic_t animatetic = 0; - INT32 ttheight = 16; - INT32 xoffset1 = 0; // Line 1 x offset - INT32 xoffset2 = 0; // Line 2 x offset - INT32 xoffset3 = 0; // Line 3 x offset - UINT8 drawsection = 0; + INT32 i = 0, j = 0; + INT32 x = 4; + INT32 y = 48; + char name[MAXPLAYERNAME+1]; - // draw the header - if (intertic <= TICRATE) - animatetic = 0; - else if (!animatetic && data.spec.bonus.points == 0 && data.spec.passed3[0] != '\0') - animatetic = intertic; + boolean completed[MAXPLAYERS]; + memset(completed, 0, sizeof (completed)); - if (animatetic) + // draw the level name + V_DrawCenteredString(BASEVIDWIDTH/2, 20, 0, data.match.levelstring); + V_DrawFill(4, 42, 312, 1, 0); + + if (data.match.numplayers > 8) { - INT32 animatetimer = (intertic - animatetic); - if (animatetimer <= 8) - { - xoffset1 = -(animatetimer * 40); - xoffset2 = -((animatetimer-2) * 40); - if (xoffset2 > 0) xoffset2 = 0; - } - else if (animatetimer <= 19) - { - drawsection = 1; - xoffset1 = (16-animatetimer) * 40; - xoffset2 = (18-animatetimer) * 40; - xoffset3 = (20-animatetimer) * 40; - if (xoffset1 < 0) xoffset1 = 0; - if (xoffset2 < 0) xoffset2 = 0; - } - else - drawsection = 1; + V_DrawFill(160, 32, 1, 152, 0); + + V_DrawCenteredString(x+6+(BASEVIDWIDTH/2), 32, V_YELLOWMAP, "#"); + V_DrawString(x+36+(BASEVIDWIDTH/2), 32, V_YELLOWMAP, "NAME"); + + V_DrawRightAlignedString(x+110, 32, V_YELLOWMAP, "TIME"); + + V_DrawRightAlignedString(x+152, 32, V_YELLOWMAP, "SCORE"); } - if (drawsection == 1) + V_DrawCenteredString(x+6, 32, V_YELLOWMAP, "#"); + V_DrawString(x+36, 32, V_YELLOWMAP, "NAME"); + + if (data.match.numplayers > 8) { - ttheight = 16; - V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1); - ttheight += V_LevelNameHeight(data.spec.passed3) + 2; - V_DrawLevelTitle(data.spec.passedx3 + xoffset2, ttheight, 0, data.spec.passed3); - ttheight += V_LevelNameHeight(data.spec.passed4) + 2; - V_DrawLevelTitle(data.spec.passedx4 + xoffset3, ttheight, 0, data.spec.passed4); - } - else if (data.spec.passed1[0] != '\0') - { - ttheight = 24; - V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1); - ttheight += V_LevelNameHeight(data.spec.passed2) + 2; - V_DrawLevelTitle(data.spec.passedx2 + xoffset2, ttheight, 0, data.spec.passed2); + V_DrawRightAlignedString(x+(BASEVIDWIDTH/2)+110, 32, V_YELLOWMAP, "TIME"); } else { - ttheight = 24 + (V_LevelNameHeight(data.spec.passed2)/2) + 2; - V_DrawLevelTitle(data.spec.passedx2 + xoffset1, ttheight, 0, data.spec.passed2); + V_DrawRightAlignedString(x+(BASEVIDWIDTH/2)+62, 32, V_YELLOWMAP, "TIME"); } - // draw the emeralds - if (intertic & 1) + V_DrawRightAlignedString(x+(BASEVIDWIDTH/2)+152, 32, V_YELLOWMAP, "SCORE"); + + for (i = 0; i < data.match.numplayers; i++) { - INT32 emeraldx = 80; - for (i = 0; i < 7; ++i) + char strtime[10]; + + if (data.match.spectator[i]) + continue; + + V_DrawCenteredString(x+6, y, 0, va("%d", j+1)); + j++; //We skip spectators, but not their number. + + if (playeringame[data.match.num[i]]) { - if (emeralds & (1 << i)) - V_DrawScaledPatch(emeraldx, 74, 0, emeraldpics[i]); - emeraldx += 24; + if (data.match.color[i] == 0) + V_DrawSmallScaledPatch(x+16, y-4, 0,faceprefix[*data.match.character[i]]); + else + { + UINT8 *colormap = R_GetTranslationColormap(*data.match.character[i], *data.match.color[i], GTC_CACHE); + V_DrawSmallMappedPatch(x+16, y-4, 0,faceprefix[*data.match.character[i]], colormap); + } + + if (data.match.numplayers > 8) + { + strlcpy(name, data.match.name[i], 6); + } + else + STRBUFCPY(name, data.match.name[i]); + + V_DrawString(x+36, y, V_ALLOWLOWERCASE, name); + + snprintf(strtime, sizeof strtime, "%d", data.match.scores[i]-data.match.increase[i]); + + if (data.match.numplayers > 8) + { + V_DrawRightAlignedString(x+152, y, V_YELLOWMAP, strtime); + } + else + { + V_DrawRightAlignedString(x+152+BASEVIDWIDTH/2, y, V_YELLOWMAP, strtime); + } + + if (data.match.increase[i] > 9) + snprintf(strtime, sizeof strtime, "(+%02d)", data.match.increase[i]); + else + snprintf(strtime, sizeof strtime, "(+ %d)", data.match.increase[i]); + + if (data.match.numplayers <= 8) // Only draw this with less than 8 players, otherwise we won't be able to fit the times in + { + V_DrawString(x+84+BASEVIDWIDTH/2, y, 0, strtime); + } + + snprintf(strtime, sizeof strtime, "%i:%02i.%02i", G_TicsToMinutes(data.match.time[i], true), + G_TicsToSeconds(data.match.time[i]), G_TicsToCentiseconds(data.match.time[i])); + + strtime[sizeof strtime - 1] = '\0'; + + if (data.match.numplayers > 8) + { + V_DrawRightAlignedString(x+134, y, 0, strtime); + } + else + { + V_DrawRightAlignedString(x+80+BASEVIDWIDTH/2, y, 0, strtime); + } + + + completed[i] = true; } - } - V_DrawScaledPatch(152, 108, 0, data.spec.bonuspatch); - V_DrawTallNum(BASEVIDWIDTH - 68, 109, 0, data.spec.bonus.points); - V_DrawScaledPatch(152, 124, 0, data.spec.pscore); - V_DrawTallNum(BASEVIDWIDTH - 68, 125, 0, data.spec.score); + y += 16; - // Draw continues! - if (!multiplayer /* && (data.spec.continues & 0x80) */) // Always draw outside of netplay - { - UINT8 continues = data.spec.continues & 0x7F; - - V_DrawScaledPatch(152, 150, 0, data.spec.pcontinues); - for (i = 0; i < continues; ++i) + if (y > 160) { - if ((data.spec.continues & 0x80) && i == continues-1 && (endtic < 0 || intertic%20 < 10)) - break; - V_DrawContinueIcon(246 - (i*12), 162, 0, *data.spec.playerchar, *data.spec.playercolor); + y = 48; + x += BASEVIDWIDTH/2; } } } - else if (intertype == int_match || intertype == int_race) + else if (intertype == int_match) { INT32 j = 0; INT32 x = 4; @@ -671,6 +701,7 @@ void Y_Ticker(void) if (endtic != -1) return; // tally is done + /* // SRB2kart if (intertype == int_coop) // coop or single player, normal level { INT32 i; @@ -798,6 +829,39 @@ void Y_Ticker(void) --data.spec.gotlife; } } + */ + if (intertype == int_timeattack) + { + if (!intertic) + endtic = intertic + 10*TICRATE; // 10 second pause after end of tally + } + else if (intertype == int_race) + { + INT32 q=0,r=0; + + /* // SRB2kart - removed temporarily. + if (!intertic) { + if (!((music_playing == "karwin") // Mario Kart Win + || (music_playing == "karok") // Mario Kart Ok + || (music_playing == "karlos"))) // Mario Kart Lose + S_ChangeMusicInternal("racent", true); // Backup Plan + }*/ + + if (intertic < TICRATE || intertic % 8) + return; + + for (q = 0; q < data.match.numplayers; q++) + { + if (data.match.increase[q]) { + data.match.increase[q]--; + r++; + } + } + if (r) + S_StartSound(NULL, sfx_menu1); + else + endtic = intertic + 3*TICRATE; // 3 second pause after end of tally + } else if (intertype == int_match || intertype == int_ctf || intertype == int_teammatch) // match { if (!intertic) // first time only @@ -924,10 +988,16 @@ void Y_StartIntermission(void) { timer = 0; + /* if (G_IsSpecialStage(gamemap)) intertype = (maptol & TOL_NIGHTS) ? int_nightsspec : int_spec; else intertype = (maptol & TOL_NIGHTS) ? int_nights : int_coop; + */ + if (modeattacking) + intertype = int_timeattack; + else + intertype = int_race; } else { @@ -941,6 +1011,7 @@ void Y_StartIntermission(void) timer = 1; } + /* // SRB2kart if (gametype == GT_COOP) { // Nights intermission is single player only @@ -950,7 +1021,8 @@ void Y_StartIntermission(void) else intertype = int_coop; } - else if (gametype == GT_TEAMMATCH) + else */ + if (gametype == GT_TEAMMATCH) intertype = int_teammatch; else if (gametype == GT_MATCH || gametype == GT_TAG @@ -985,11 +1057,11 @@ void Y_StartIntermission(void) } // fall back into the coop intermission for now - intertype = int_coop; - case int_coop: // coop or single player, normal level + intertype = int_timeattack; + case int_timeattack: // coop or single player, normal level // SRB2kart 230117 - replaced int_coop { // award time and ring bonuses - Y_AwardCoopBonuses(); + // Y_AwardCoopBonuses(); // setup time data data.coop.tics = players[consoleplayer].realtime; @@ -1079,6 +1151,7 @@ void Y_StartIntermission(void) break; } + /* // SRB2kart 230117 - removed case int_nightsspec: if (modeattacking && stagefailed) { @@ -1144,7 +1217,7 @@ void Y_StartIntermission(void) data.spec.headx = 48; data.spec.nowsuper = NULL; } */ - +/* // Super form stuff (normally blank) data.spec.passed3[0] = '\0'; data.spec.passed4[0] = '\0'; @@ -1190,7 +1263,7 @@ void Y_StartIntermission(void) data.spec.passedx3 = (BASEVIDWIDTH - V_LevelNameWidth(data.spec.passed3))/2; data.spec.passedx4 = (BASEVIDWIDTH - V_LevelNameWidth(data.spec.passed4))/2; break; - } + }*/ case int_match: { @@ -1224,7 +1297,7 @@ void Y_StartIntermission(void) case int_race: // (time-only race) { // Calculate who won - Y_CalculateTimeRaceWinners(); + Y_CalculateTournamentPoints(); // set up the levelstring if (mapheaderinfo[prevmap]->actnum) @@ -1241,7 +1314,7 @@ void Y_StartIntermission(void) data.match.levelstring[sizeof data.match.levelstring - 1] = '\0'; // get RESULT header - data.match.result = W_CachePatchName("RESULT", PU_STATIC); + //data.match.result = W_CachePatchName("RESULT", PU_STATIC); bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); usetile = true; @@ -1360,6 +1433,7 @@ static void Y_CalculateMatchWinners(void) } } +/* // // Y_CalculateTimeRaceWinners // @@ -1403,6 +1477,7 @@ static void Y_CalculateTimeRaceWinners(void) data.match.numplayers++; } } +*/ // // Y_CalculateCompetitionWinners @@ -1665,7 +1740,7 @@ bonus_f bonuses_list[4][4] = { }; - +/* // SRB2kart 230117 - Replaced with Y_CalculateTournamentPoints // // Y_AwardCoopBonuses // @@ -1759,6 +1834,86 @@ static void Y_AwardSpecialStageBonus(void) } } } +*/ + +// +// Y_CalculateTournamentPoints +// +static void Y_CalculateTournamentPoints(void) +{ + INT32 i, j; + boolean completed[MAXPLAYERS]; + INT32 numplayersingame = 0; + INT32 zz1 = 0, zz2 = 0, zz3 = 0, zz4 = 0, zz5 = 0, zz6 = 0, zz7 = 0, zz8 = 0, + zz9 = 0, zz10 = 0, zz11 = 0, zz12 = 0, zz13 = 0, zz14 = 0, zz15 = 0, zz16 = 0; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i]) + numplayersingame++; + } + + zz1 = numplayersingame; zz2 = numplayersingame-1; zz3 = numplayersingame-2; zz4 = numplayersingame-3; + zz5 = numplayersingame-4; zz6 = numplayersingame-5; zz7 = numplayersingame-6; zz8 = numplayersingame-7; + zz9 = numplayersingame-8; zz10= numplayersingame-9; zz11= numplayersingame-10; zz12= numplayersingame-11; + zz13= numplayersingame-12; zz14= numplayersingame-13; zz15= numplayersingame-14; zz16= numplayersingame-15; + + if (zz1 < 0) zz1 = 0; if (zz2 < 0) zz2 = 0; if (zz3 < 0) zz3 = 0; if (zz4 < 0) zz4 = 0; + if (zz5 < 0) zz5 = 0; if (zz6 < 0) zz6 = 0; if (zz7 < 0) zz7 = 0; if (zz8 < 0) zz8 = 0; + if (zz9 < 0) zz9 = 0; if (zz10< 0) zz10= 0; if (zz11< 0) zz11= 0; if (zz12< 0) zz12= 0; + if (zz13< 0) zz13= 0; if (zz14< 0) zz14= 0; if (zz15< 0) zz15= 0; if (zz16< 0) zz16= 0; + + INT32 increase[MAXPLAYERS] = {zz1,zz2,zz3,zz4,zz5,zz6,zz7,zz8,zz9,zz10,zz11,zz12,zz13,zz14,zz15,zz16}; + + // Initialize variables + + for (j = 0; j < MAXPLAYERS; j++) + data.match.scores[j] = INT32_MAX; + + memset(data.match.time, 0, sizeof (data.match.time)); + memset(data.match.color, 0, sizeof (data.match.color)); + memset(data.match.character, 0, sizeof (data.match.character)); + memset(data.match.spectator, 0, sizeof (data.match.spectator)); + memset(data.match.increase, 0, sizeof (data.match.increase)); + memset(completed, 0, sizeof (completed)); + data.match.numplayers = 0; + i = j = 0; + + for (j = 0; j < MAXPLAYERS; j++) + { + if (!playeringame[j]) + continue; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i]) + continue; + + if (players[i].realtime <= data.match.scores[data.match.numplayers] && completed[i] == false) + { + data.match.time[data.match.numplayers] = players[i].realtime; + data.match.scores[data.match.numplayers] = players[i].realtime; + data.match.color[data.match.numplayers] = &players[i].skincolor; + data.match.character[data.match.numplayers] = &players[i].skin; + data.match.name[data.match.numplayers] = player_names[i]; + data.match.spectator[data.match.numplayers] = players[i].spectator; + data.match.num[data.match.numplayers] = i; + } + } + completed[data.match.num[data.match.numplayers]] = true; + if (!(players[data.match.num[data.match.numplayers]].pflags & PF_TIMEOVER + || players[data.match.num[data.match.numplayers]].spectator)) + data.match.increase[data.match.numplayers] = increase[data.match.numplayers]; + players[data.match.num[data.match.numplayers]].score += data.match.increase[data.match.numplayers]; + data.match.scores[data.match.numplayers] = players[data.match.num[data.match.numplayers]].score; + + //players[data.match.num[data.match.numplayers]].newfloorz = 0; + players[data.match.num[data.match.numplayers]].kartstuff[k_lakitu] = 0; + //players[data.match.num[data.match.numplayers]].airtime = 0; + + data.match.numplayers++; + } +} // ====== @@ -1853,6 +2008,7 @@ static void Y_UnloadData(void) switch (intertype) { + /* case int_coop: // unload the coop and single player patches UNLOAD(data.coop.ttlnum); @@ -1870,6 +2026,7 @@ static void Y_UnloadData(void) UNLOAD(data.spec.pscore); UNLOAD(data.spec.pcontinues); break; + */ case int_match: case int_race: UNLOAD(data.match.result); diff --git a/src/y_inter.h b/src/y_inter.h index 9fe95fcc..358debf7 100644 --- a/src/y_inter.h +++ b/src/y_inter.h @@ -20,15 +20,15 @@ void Y_EndGame(void); typedef enum { int_none, - int_coop, // Single Player/Cooperative - int_match, // Match - int_teammatch,// Team Match -// int_tag, // Tag - int_ctf, // CTF - int_spec, // Special Stage - int_nights, // NiGHTS into Dreams - int_nightsspec,// NiGHTS special stage - int_race, // Race + int_timeattack, // Time Attack + int_match, // Match + int_teammatch, // Team Match +// int_tag, // Tag + int_ctf, // CTF + int_spec, // Special Stage + int_nights, // NiGHTS into Dreams + int_nightsspec, // NiGHTS special stage + int_race, // Race int_classicrace, // Competition } intertype_t; extern intertype_t intertype;