From 622e94797bb587a8a6feb99c8d3af3e0c2af99f4 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 25 Nov 2018 22:55:49 -0500 Subject: [PATCH 01/91] basic start on VR --- src/doomstat.h | 1 + src/g_game.c | 11 +++++++++++ src/m_menu.c | 11 +++++++++++ 3 files changed, 23 insertions(+) diff --git a/src/doomstat.h b/src/doomstat.h index 34456b321..0ff47dce6 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -326,6 +326,7 @@ enum GameType // SRB2Kart extern tic_t totalplaytime; extern UINT32 matchesplayed; +extern UINT16 versusrecord[2]; extern UINT8 stagefailed; diff --git a/src/g_game.c b/src/g_game.c index e9309b807..cdb5d3717 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -169,6 +169,7 @@ INT32 sstimer; // Time allotted in the special stage tic_t totalplaytime; UINT32 matchesplayed; // SRB2Kart +UINT16 versusrecord[2]; // SRB2Kart: Online rankings boolean gamedataloaded = false; // Time attack data for levels @@ -3744,9 +3745,13 @@ void G_LoadGameData(void) // to new gamedata G_ClearRecords(); // main and nights records M_ClearSecrets(); // emblems, unlocks, maps visited, etc + totalplaytime = 0; // total play time (separate from all) matchesplayed = 0; // SRB2Kart: matches played & finished + for (i = 0; i < 2; i++) // SRB2Kart: online VR system + versusrecord[i] = 5000; + if (M_CheckParm("-nodata")) return; // Don't load. @@ -3777,6 +3782,9 @@ void G_LoadGameData(void) totalplaytime = READUINT32(save_p); matchesplayed = READUINT32(save_p); + for (i = 0; i < 2; i++) + versusrecord[i] = READUINT16(save_p); + modded = READUINT8(save_p); // Aha! Someone's been screwing with the save file! @@ -3925,6 +3933,9 @@ void G_SaveGameData(boolean force) WRITEUINT32(save_p, totalplaytime); WRITEUINT32(save_p, matchesplayed); + for (i = 0; i < 2; i++) + WRITEUINT16(save_p, versusrecord[i]); + btemp = (UINT8)(savemoddata || modifiedgame); WRITEUINT8(save_p, btemp); diff --git a/src/m_menu.c b/src/m_menu.c index 8e49b2155..2484cd9a3 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6319,9 +6319,16 @@ static void M_DrawLevelStats(void) G_TicsToHours(totalplaytime), G_TicsToMinutes(totalplaytime, false), G_TicsToSeconds(totalplaytime))); + V_DrawString(20, 42, highlightflags, "Total Matches:"); V_DrawRightAlignedString(BASEVIDWIDTH-16, 42, 0, va("%i played", matchesplayed)); + V_DrawString(20, 50, highlightflags, "Race Versus Record:"); + V_DrawRightAlignedString(BASEVIDWIDTH-16, 50, 0, va("%i", versusrecord[0])); + + V_DrawString(20, 58, highlightflags, "Battle Versus Record:"); + V_DrawRightAlignedString(BASEVIDWIDTH-16, 58, 0, va("%i", versusrecord[1])); + for (i = 0; i < NUMMAPS; i++) { if (!mapheaderinfo[i] || !(mapheaderinfo[i]->menuflags & LF2_RECORDATTACK)) @@ -8452,6 +8459,8 @@ static UINT8 erasecontext = 0; static void M_EraseDataResponse(INT32 ch) { + UINT8 i; + if (ch != 'y' && ch != KEY_ENTER) return; @@ -8463,6 +8472,8 @@ static void M_EraseDataResponse(INT32 ch) // SRB2Kart: This actually needs to be done FIRST, so that you don't immediately regain playtime/matches secrets totalplaytime = 0; matchesplayed = 0; + for (i = 0; i < 2; i++) + versusrecord[i] = 5000; F_StartIntro(); } if (erasecontext != 1) From dfa0522326202440304d29d1726c06719a2b2114 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 6 Dec 2018 13:46:38 -0500 Subject: [PATCH 02/91] Battle Mode overtime After the time limit is up, spawn a shrinking kill-field. This is one hefty initial commit! --- src/d_netcmd.c | 4 +- src/d_player.h | 1 + src/dehacked.c | 7 +++ src/doomstat.h | 11 ++++ src/g_game.c | 3 ++ src/info.c | 59 ++++++++++++++++++++- src/info.h | 8 +++ src/k_kart.c | 41 +++++++++++++- src/p_enemy.c | 4 +- src/p_inter.c | 99 ++++++++++++++++------------------ src/p_local.h | 1 + src/p_mobj.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++- src/p_saveg.c | 18 ++++++- src/p_setup.c | 4 ++ src/p_tick.c | 4 ++ 15 files changed, 343 insertions(+), 62 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f29798382..956990bd2 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -4326,9 +4326,9 @@ void D_GameTypeChanged(INT32 lastgametype) case GT_TEAMMATCH: if (!cv_timelimit.changed && !cv_pointlimit.changed) // user hasn't changed limits { - // default settings for match: no timelimit, no pointlimit + // default settings for match: 3 mins, no pointlimit CV_SetValue(&cv_pointlimit, 0); - CV_SetValue(&cv_timelimit, 0); + CV_SetValue(&cv_timelimit, 3); } if (!cv_itemrespawntime.changed) CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); // respawn normally diff --git a/src/d_player.h b/src/d_player.h index 1b1d4d0a2..ce5a92ab0 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -346,6 +346,7 @@ typedef enum k_comebackpoints, // Number of times you've bombed or gave an item to someone; once it's 3 it gets set back to 0 and you're given a bumper k_comebackmode, // 0 = bomb, 1 = item k_wanted, // Timer for determining WANTED status, lowers when hitting people, prevents the game turning into Camp Lazlo + k_killfield, // How long have you been in the kill field, stay in too long and lose a bumper k_yougotem, // "You Got Em" gfx when hitting someone as a karma player via a method that gets you back in the game instantly // v1.0.2 vars diff --git a/src/dehacked.c b/src/dehacked.c index 8cb704125..44c8163df 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7099,6 +7099,9 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_KARMAFIREWORK4", "S_KARMAFIREWORKTRAIL", + "S_OVERTIMEFOG", + "S_OVERTIMEORB", + #ifdef SEENAMES "S_NAMECHECK", #endif @@ -7886,6 +7889,9 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_KARMAFIREWORK", + "MT_OVERTIMEFOG", + "MT_OVERTIMEORB", + #ifdef SEENAMES "MT_NAMECHECK", #endif @@ -8278,6 +8284,7 @@ static const char *const KARTSTUFF_LIST[] = { "COMEBACKPOINTS", "COMEBACKMODE", "WANTED", + "KILLFIELD", "YOUGOTEM", "ITEMBLINK", diff --git a/src/doomstat.h b/src/doomstat.h index 69e2e7cd9..605cef5bb 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -471,6 +471,17 @@ extern INT16 votelevels[5][2]; extern SINT8 votes[MAXPLAYERS]; extern SINT8 pickedvote; +/** Battle overtime information + */ +typedef struct +{ + boolean enabled; ///< Has this been initalized yet? + UINT16 radius; ///< Radius of kill field + fixed_t x, y, z; ///< Position to center on (z is only used for visuals) +} battleovertime_t; + +extern battleovertime_t *battleovertime; + extern tic_t hidetime; extern UINT32 timesBeaten; // # of times the game has been beaten. diff --git a/src/g_game.c b/src/g_game.c index ac8e27a37..75e7440b8 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -260,6 +260,9 @@ INT16 votelevels[5][2]; // Levels that were rolled by the host SINT8 votes[MAXPLAYERS]; // Each player's vote SINT8 pickedvote; // What vote the host rolls +// Battle overtime system +battleovertime_t *battleovertime = {NULL}; + // Server-sided, synched variables SINT8 battlewanted[4]; // WANTED players in battle, worth x2 points tic_t wantedcalcdelay; // Time before it recalculates WANTED diff --git a/src/info.c b/src/info.c index 9851ee23b..863d5f8b5 100644 --- a/src/info.c +++ b/src/info.c @@ -69,7 +69,7 @@ char sprnames[NUMSPRITES + 1][5] = "CNDL","DOCH","DUCK","GTRE","CHES","CHIM","DRGN","LZMN","PGSS","ZTCH", "MKMA","MKMP","RTCH","BOWL","BOWH","BRRL","BRRR","HRSE","TOAH","BFRT", "OFRT","RFRT","PFRT","ASPK","HBST","HBSO","HBSF","WBLZ","WBLN","FWRK", - "XMS4","XMS5","VIEW" + "OTFG","XMS4","XMS5","VIEW" }; // Doesn't work with g++, needs actionf_p1 (don't modify this comment) @@ -3394,6 +3394,9 @@ state_t states[NUMSTATES] = {SPR_FWRK, 3|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_KARMAFIREWORK1}, // S_KARMAFIREWORK4 {SPR_FWRK, 4|FF_FULLBRIGHT, TICRATE, {NULL}, 0, 0, S_NULL}, // S_KARMAFIREWORKTRAIL + {SPR_OTFG, FF_FULLBRIGHT|FF_TRANS50, 8, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEFOG + {SPR_OTFG, 1|FF_FULLBRIGHT, 8, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEORB + #ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK #endif @@ -20052,6 +20055,60 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_OVERTIMEFOG + -1, // doomednum + S_OVERTIMEFOG, // 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 + 0, // speed + 8<mo->color = player->skincolor; } } + else if (player->kartstuff[k_killfield]) // You're gonna REALLY diiiiie + { + const INT32 flashtime = 4<<(4-(player->kartstuff[k_killfield]/TICRATE)); + if (player->kartstuff[k_killfield] == 1 || (player->kartstuff[k_killfield] % (flashtime/2) != 0)) + { + player->mo->colorized = false; + player->mo->color = player->skincolor; + } + else if (player->kartstuff[k_killfield] % flashtime == 0) + { + player->mo->colorized = true; + player->mo->color = SKINCOLOR_BYZANTIUM; + } + else + { + player->mo->colorized = true; + player->mo->color = SKINCOLOR_RUBY; + } + } else { player->mo->colorized = false; @@ -4370,8 +4389,28 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_tauntvoices]) player->kartstuff[k_tauntvoices]--; - if (G_BattleGametype() && player->kartstuff[k_bumper] > 0) + if (G_BattleGametype() && player->kartstuff[k_bumper] > 0 + && !player->kartstuff[k_spinouttimer] && !player->kartstuff[k_squishedtimer] + && !player->kartstuff[k_respawn] && !player->powers[pw_flashing]) + { player->kartstuff[k_wanted]++; + if (battleovertime->enabled) + { + if (P_AproxDistance(player->mo->x - battleovertime->x, player->mo->y - battleovertime->y) > (battleovertime->radius<kartstuff[k_killfield]++; + if (player->kartstuff[k_killfield] > 4*TICRATE) + { + K_SpinPlayer(player, NULL, 0, NULL, false); + //player->kartstuff[k_killfield] = 1; + } + } + else if (player->kartstuff[k_killfield] > 0) + player->kartstuff[k_killfield]--; + } + } + else if (player->kartstuff[k_killfield] > 0) + player->kartstuff[k_killfield]--; if (P_IsObjectOnGround(player->mo)) player->kartstuff[k_waterskip] = 0; diff --git a/src/p_enemy.c b/src/p_enemy.c index cc37c7747..a529c9b60 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8234,7 +8234,7 @@ void A_ItemPop(mobj_t *actor) remains->flags = actor->flags; // Transfer flags remains->flags2 = actor->flags2; // Transfer flags2 remains->fuse = actor->fuse; // Transfer respawn timer - remains->threshold = (actor->threshold == 69 ? 69 : 68); + remains->threshold = (actor->threshold == 70 ? 70 : (actor->threshold == 69 ? 69 : 68)); remains->skin = NULL; remains->spawnpoint = actor->spawnpoint; @@ -8248,7 +8248,7 @@ void A_ItemPop(mobj_t *actor) remains->flags2 &= ~MF2_AMBUSH; - if (G_BattleGametype() && actor->threshold != 69) + if (G_BattleGametype() && (actor->threshold != 69 && actor->threshold != 70)) numgotboxes++; P_RemoveMobj(actor); diff --git a/src/p_inter.c b/src/p_inter.c index fce8ccd56..4ef2f578f 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1755,7 +1755,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) */ void P_CheckTimeLimit(void) { - INT32 i, k; + INT32 i; if (!cv_timelimit.value) return; @@ -1791,66 +1791,62 @@ void P_CheckTimeLimit(void) } //Optional tie-breaker for Match/CTF - else*/ if (cv_overtime.value) + else*/ +#define TESTOVERTIMEINFREEPLAY + if (cv_overtime.value) { - INT32 playerarray[MAXPLAYERS]; - INT32 tempplayer = 0; - INT32 spectators = 0; - INT32 playercount = 0; - - //Figure out if we have enough participating players to care. +#ifndef TESTOVERTIMEINFREEPLAY + boolean foundone = false; // Overtime is used for closing off down to a specific item. for (i = 0; i < MAXPLAYERS; i++) { - if (players[i].exiting) - return; - if (playeringame[i] && players[i].spectator) - spectators++; - } - - if ((D_NumPlayers() - spectators) > 1) - { - // Play the starpost sfx after the first second of overtime. - if (gamestate == GS_LEVEL && (leveltime == (timelimitintics + TICRATE))) - S_StartSound(NULL, sfx_strpst); - - // Normal Match - if (!G_GametypeHasTeams()) + if (!playeringame[i] || players[i].spectator) + continue; + if (foundone) { - //Store the nodes of participating players in an array. - for (i = 0; i < MAXPLAYERS; i++) +#endif + // Initiate the kill zone + if (!battleovertime->enabled) { - if (playeringame[i] && !players[i].spectator) - { - playerarray[playercount] = i; - playercount++; - } - } + UINT8 b = 0; + thinker_t *th; + mobj_t *item = NULL; - //Sort 'em. - for (i = 1; i < playercount; i++) - { - for (k = i; k < playercount; k++) + // Find us an item box to center on. + for (th = thinkercap.next; th != &thinkercap; th = th->next) { - if (players[playerarray[i-1]].marescore < players[playerarray[k]].marescore) - { - tempplayer = playerarray[i-1]; - playerarray[i-1] = playerarray[k]; - playerarray[k] = tempplayer; - } - } - } + mobj_t *thismo; + if (th->function.acp1 != (actionf_p1)P_MobjThinker) + continue; + thismo = (mobj_t *)th; - //End the round if the top players aren't tied. - if (players[playerarray[0]].marescore == players[playerarray[1]].marescore) - return; + if (thismo->type != MT_RANDOMITEM) + continue; + if (thismo->threshold == 69) // Disappears + continue; + b++; + if (item == NULL || (b < nummapboxes && P_RandomChance(((nummapboxes-b)*FRACUNIT)/nummapboxes))) // This is to throw off the RNG some + item = thismo; + if (b >= nummapboxes) // end early if we've found them all already + break; + } + + if (item == NULL) // no item found?! + return; + + item->threshold = 70; // Set constant respawn + battleovertime->x = item->x; + battleovertime->y = item->y; + battleovertime->z = item->z; + battleovertime->radius = 4096; + battleovertime->enabled = true; + } + return; +#ifndef TESTOVERTIMEINFREEPLAY } else - { - //In team match and CTF, determining a tie is much simpler. =P - if (redscore == bluescore) - return; - } + foundone = true; } +#endif } for (i = 0; i < MAXPLAYERS; i++) @@ -1861,9 +1857,6 @@ void P_CheckTimeLimit(void) return; P_DoPlayerExit(&players[i]); } - - /*if (server) - SendNetXCmd(XD_EXITLEVEL, NULL, 0);*/ } /** Checks if a player's score is over the pointlimit and the round should end. diff --git a/src/p_local.h b/src/p_local.h index ddcfd75e8..b6dcd4d0b 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -233,6 +233,7 @@ boolean P_SetMobjState(mobj_t *mobj, statenum_t state); //void P_RunShields(void); void P_RunOverlays(void); void P_RunShadows(void); +void P_RunBattleOvertime(void); void P_MobjThinker(mobj_t *mobj); boolean P_RailThinker(mobj_t *mobj); void P_PushableThinker(mobj_t *mobj); diff --git a/src/p_mobj.c b/src/p_mobj.c index 40b107dcf..595ff1137 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6409,6 +6409,140 @@ static void P_RemoveShadow(mobj_t *thing) } } +// SAL'S KART BATTLE MODE OVERTIME HANDLER +#define MAXPLANESPERSECTOR (MAXFFLOORS+1)*2 +static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, mobjtype_t type, boolean ceiling) +{ + UINT8 i; + fixed_t flatz[MAXPLANESPERSECTOR]; + UINT8 numflats = 0; + mobj_t *mo; + subsector_t *ss = R_IsPointInSubsector(x, y); + sector_t *sec; + + if (!ss) + return; + sec = ss->sector; + + // convoluted stuff JUST to get all of the planes we need to draw orbs on :V + + if (sec->floorpic != skyflatnum) + { +#ifdef ESLOPE + flatz[numflats] = (sec->f_slope ? P_GetZAt(sec->f_slope, x, y) : sec->floorheight); +#else + flatz[numflats] = (sec->floorheight); +#endif + numflats++; + } + if (sec->ceilingpic != skyflatnum && ceiling) + { +#ifdef ESLOPE + flatz[numflats] = (sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : sec->ceilingheight) - mobjinfo[MT_THOK].height; +#else + flatz[numflats] = (sec->ceilingheight) - mobjinfo[MT_THOK].height; +#endif + numflats++; + } + + if (sec->ffloors) + { + ffloor_t *rover; + for (rover = sec->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_BLOCKPLAYER)) + continue; + if (*rover->toppic != skyflatnum) + { +#ifdef ESLOPE + flatz[numflats] = (*rover->t_slope ? P_GetZAt(*rover->t_slope, x, y) : *rover->topheight); +#else + flatz[numflats] = (*rover->topheight); +#endif + numflats++; + } + if (*rover->bottompic != skyflatnum && ceiling) + { +#ifdef ESLOPE + flatz[numflats] = (*rover->b_slope ? P_GetZAt(*rover->b_slope, x, y) : *rover->bottomheight) - mobjinfo[MT_THOK].height; +#else + flatz[numflats] = (*rover->bottomheight) - mobjinfo[MT_THOK].height; +#endif + numflats++; + } + } + } + + if (numflats <= 0) // no flats + return; + + for (i = 0; i < numflats; i++) + { + mo = P_SpawnMobj(x, y, flatz[i], type); + + // Lastly, if this can see the skybox mobj, then... we just wasted our time :V + if (skyboxmo[0] && !P_MobjWasRemoved(skyboxmo[0]) && P_CheckSight(skyboxmo[0], mo)) + { + P_RemoveMobj(mo); + continue; + } + + switch(type) + { + case MT_OVERTIMEFOG: + P_SetScale(mo, 2*mo->scale); + mo->destscale = 8*mo->scale; + mo->momz = P_RandomRange(1,8)*mo->scale; + break; + case MT_OVERTIMEORB: + P_SetScale(mo, 2*mo->scale); + mo->destscale = mo->scale/4; + if ((leveltime/2) & 1) + mo->frame++; + break; + default: + break; + } + } +} +#undef MAXPLANESPERSECTOR + +void P_RunBattleOvertime(void) +{ + UINT8 i, j; + + if (battleovertime->radius > 512) + battleovertime->radius--; + else + battleovertime->radius = 512; + + if (leveltime & 1) + { + for (i = 0; i < 16; i++) // 16 base orbs + { + angle_t ang = FixedAngle(((45*i) * (FRACUNIT>>1)) + ((leveltime % 360)<x + P_ReturnThrustX(NULL, ang, battleovertime->radius<y + P_ReturnThrustY(NULL, ang, battleovertime->radius<x + ((P_RandomRange(-64,64) * 128)<y + ((P_RandomRange(-64,64) * 128)<x, y-battleovertime->y) <= (battleovertime->radius<flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s P_RemoveMobj(mobj); // make sure they disappear return; case MT_RANDOMITEM: - if (G_BattleGametype()) + if (G_BattleGametype() && (mobj->threshold != 70)) { if (mobj->threshold != 69) + { + mobj->fuse = cv_itemrespawntime.value*TICRATE + 2; break; + } } else { @@ -9390,6 +9527,8 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s // Transfer flags2 (strongbox, objectflip) newmobj->flags2 = mobj->flags2 & ~MF2_DONTDRAW; + if (mobj->threshold == 70) + newmobj->threshold = 70; } P_RemoveMobj(mobj); // make sure they disappear return; diff --git a/src/p_saveg.c b/src/p_saveg.c index 02f774574..8306e64ad 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -961,8 +961,8 @@ typedef enum MD2_EXTVAL2 = 1<<6, MD2_HNEXT = 1<<7, MD2_HPREV = 1<<8, - MD2_COLORIZED = 1<<9, - MD2_WAYPOINTCAP = 1<<10 + MD2_COLORIZED = 1<<9, + MD2_WAYPOINTCAP = 1<<10 #ifdef ESLOPE , MD2_SLOPE = 1<<11 #endif @@ -3298,6 +3298,13 @@ static void P_NetArchiveMisc(void) for (i = 0; i < 4; i++) WRITESINT8(save_p, battlewanted[i]); + // battleovertime_t + WRITEUINT8(save_p, battleovertime->enabled); + WRITEUINT16(save_p, battleovertime->radius); + WRITEFIXED(save_p, battleovertime->x); + WRITEFIXED(save_p, battleovertime->y); + WRITEFIXED(save_p, battleovertime->z); + WRITEUINT32(save_p, wantedcalcdelay); WRITEUINT32(save_p, indirectitemcooldown); WRITEUINT32(save_p, mapreset); @@ -3405,6 +3412,13 @@ static inline boolean P_NetUnArchiveMisc(void) for (i = 0; i < 4; i++) battlewanted[i] = READSINT8(save_p); + // battleovertime_t + battleovertime->enabled = (boolean)READUINT8(save_p); + battleovertime->radius = READUINT16(save_p); + battleovertime->x = READFIXED(save_p); + battleovertime->y = READFIXED(save_p); + battleovertime->z = READFIXED(save_p); + wantedcalcdelay = READUINT32(save_p); indirectitemcooldown = READUINT32(save_p); mapreset = READUINT32(save_p); diff --git a/src/p_setup.c b/src/p_setup.c index 3bdb4d057..01b231116 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2373,6 +2373,10 @@ static void P_LevelInitStuff(void) for (i = 0; i < 4; i++) battlewanted[i] = -1; + + if (!battleovertime) + battleovertime = Z_Malloc(sizeof(battleovertime_t), PU_STATIC, NULL); + memset(battleovertime, 0, sizeof(battleovertime_t)); } // diff --git a/src/p_tick.c b/src/p_tick.c index b46b248bb..def074d60 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -621,6 +621,8 @@ void P_Ticker(boolean run) if (run) { P_RunThinkers(); + if (G_BattleGametype() && battleovertime->enabled) + P_RunBattleOvertime(); // Run any "after all the other thinkers" stuff for (i = 0; i < MAXPLAYERS; i++) @@ -760,6 +762,8 @@ void P_PreTicker(INT32 frames) } P_RunThinkers(); + if (G_BattleGametype() && battleovertime->enabled) + P_RunBattleOvertime(); // Run any "after all the other thinkers" stuff for (i = 0; i < MAXPLAYERS; i++) From 19ca7bf1347ee5015c5e092cc6c8c9c65dd447f8 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 6 Dec 2018 16:17:17 -0500 Subject: [PATCH 03/91] Show the central item on the minimap, and other minor aesthetic touches --- src/info.c | 10 +++--- src/k_kart.c | 89 +++++++++++++++++++++++++++++++++++++--------------- src/p_mobj.c | 28 ++++++++++++++--- 3 files changed, 93 insertions(+), 34 deletions(-) diff --git a/src/info.c b/src/info.c index 863d5f8b5..ae9696edc 100644 --- a/src/info.c +++ b/src/info.c @@ -3394,7 +3394,7 @@ state_t states[NUMSTATES] = {SPR_FWRK, 3|FF_FULLBRIGHT, 2, {NULL}, 0, 0, S_KARMAFIREWORK1}, // S_KARMAFIREWORK4 {SPR_FWRK, 4|FF_FULLBRIGHT, TICRATE, {NULL}, 0, 0, S_NULL}, // S_KARMAFIREWORKTRAIL - {SPR_OTFG, FF_FULLBRIGHT|FF_TRANS50, 8, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEFOG + {SPR_OTFG, FF_FULLBRIGHT|FF_TRANS50, TICRATE, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEFOG {SPR_OTFG, 1|FF_FULLBRIGHT, 8, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEORB #ifdef SEENAMES @@ -20072,8 +20072,8 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 8<skin) - skin = ((skin_t*)mo->skin)-skins; - maxx = maxy = INT32_MAX; minx = miny = INT32_MIN; minx = bsp->bbox[0][BOXLEFT]; @@ -7355,33 +7352,23 @@ static void K_drawKartMinimapHead(mobj_t *mo, INT32 x, INT32 y, INT32 flags, pat yscale = FixedDiv(AutomapPic->height, mapheight); zoom = FixedMul(min(xscale, yscale), FRACUNIT-FRACUNIT/20); - amnumxpos = (FixedMul(mo->x, zoom) - FixedMul(xoffset, zoom)); - amnumypos = -(FixedMul(mo->y, zoom) - FixedMul(yoffset, zoom)); + amnumxpos = (FixedMul(objx, zoom) - FixedMul(xoffset, zoom)); + amnumypos = -(FixedMul(objy, zoom) - FixedMul(yoffset, zoom)); if (encoremode) amnumxpos = -amnumxpos; - amxpos = amnumxpos + ((x + AutomapPic->width/2 - (facemmapprefix[skin]->width/2))<height/2 - (facemmapprefix[skin]->height/2))<width/2 - (icon->width/2))<height/2 - (icon->height/2))<width/2 + (facemmapprefix[skin]->width/2))<width/2 + (icon->width/2))<color) // 'default' color - V_DrawSciencePatch(amxpos, amypos, flags, facemmapprefix[skin], FRACUNIT); - else - { - UINT8 *colormap; - if (mo->colorized) - colormap = R_GetTranslationColormap(TC_RAINBOW, mo->color, GTC_CACHE); - else - colormap = R_GetTranslationColormap(skin, mo->color, GTC_CACHE); - V_DrawFixedPatch(amxpos, amypos, FRACUNIT, flags, facemmapprefix[skin], colormap); - } + V_DrawFixedPatch(amxpos, amypos, FRACUNIT, flags, icon, colormap); } static void K_drawKartMinimap(void) @@ -7392,6 +7379,8 @@ static void K_drawKartMinimap(void) INT32 x, y; INT32 minimaptrans, splitflags = (splitscreen ? 0 : V_SNAPTORIGHT); boolean dop1later = false; + UINT8 skin = 0; + UINT8 *colormap = NULL; // Draw the HUD only when playing in a level. // hu_stuff needs this, unlike st_stuff. @@ -7443,13 +7432,37 @@ static void K_drawKartMinimap(void) x -= SHORT(AutomapPic->leftoffset); y -= SHORT(AutomapPic->topoffset); + // Draw the super item in Battle + if (G_BattleGametype() && battleovertime->enabled) + { + const INT32 prevsplitflags = splitflags; + splitflags &= ~V_HUDTRANSHALF; + splitflags |= V_HUDTRANS; + colormap = R_GetTranslationColormap(TC_RAINBOW, (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1))), GTC_CACHE); + K_drawKartMinimapHead(battleovertime->x, battleovertime->y, x, y, splitflags, kp_itemminimap, colormap, AutomapPic); + splitflags = prevsplitflags; + } + // Player's tiny icons on the Automap. (drawn opposite direction so player 1 is drawn last in splitscreen) if (ghosts) { demoghost *g = ghosts; while (g) { - K_drawKartMinimapHead(g->mo, x, y, splitflags, AutomapPic); + if (g->mo->skin) + skin = ((skin_t*)g->mo->skin)-skins; + else + skin = 0; + if (g->mo->color) + { + if (g->mo->colorized) + colormap = R_GetTranslationColormap(TC_RAINBOW, g->mo->color, GTC_CACHE); + else + colormap = R_GetTranslationColormap(skin, g->mo->color, GTC_CACHE); + } + else + colormap = NULL; + K_drawKartMinimapHead(g->mo->x, g->mo->y, x, y, splitflags, facemmapprefix[skin], colormap, AutomapPic); g = g->next; } if (!stplyr->mo || stplyr->spectator) // do we need the latter..? @@ -7481,7 +7494,20 @@ static void K_drawKartMinimap(void) continue; } - K_drawKartMinimapHead(players[i].mo, x, y, splitflags, AutomapPic); + if (players[i].mo->skin) + skin = ((skin_t*)players[i].mo->skin)-skins; + else + skin = 0; + if (players[i].mo->color) + { + if (players[i].mo->colorized) + colormap = R_GetTranslationColormap(TC_RAINBOW, players[i].mo->color, GTC_CACHE); + else + colormap = R_GetTranslationColormap(skin, players[i].mo->color, GTC_CACHE); + } + else + colormap = NULL; + K_drawKartMinimapHead(players[i].mo->x, players[i].mo->y, x, y, splitflags, facemmapprefix[skin], colormap, AutomapPic); } } @@ -7490,7 +7516,20 @@ static void K_drawKartMinimap(void) splitflags &= ~V_HUDTRANSHALF; splitflags |= V_HUDTRANS; - K_drawKartMinimapHead(stplyr->mo, x, y, splitflags, AutomapPic); + if (stplyr->mo->skin) + skin = ((skin_t*)stplyr->mo->skin)-skins; + else + skin = 0; + if (stplyr->mo->color) + { + if (stplyr->mo->colorized) + colormap = R_GetTranslationColormap(TC_RAINBOW, stplyr->mo->color, GTC_CACHE); + else + colormap = R_GetTranslationColormap(skin, stplyr->mo->color, GTC_CACHE); + } + else + colormap = NULL; + K_drawKartMinimapHead(stplyr->mo->x, stplyr->mo->y, x, y, splitflags, facemmapprefix[skin], colormap, AutomapPic); } static void K_drawKartStartCountdown(void) diff --git a/src/p_mobj.c b/src/p_mobj.c index 595ff1137..7c2c8438d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6490,7 +6490,7 @@ static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, mobjtype_t type, bool switch(type) { case MT_OVERTIMEFOG: - P_SetScale(mo, 2*mo->scale); + P_SetScale(mo, 4*mo->scale); mo->destscale = 8*mo->scale; mo->momz = P_RandomRange(1,8)*mo->scale; break; @@ -6499,6 +6499,8 @@ static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, mobjtype_t type, bool mo->destscale = mo->scale/4; if ((leveltime/2) & 1) mo->frame++; + /*if (i == 0 && !((leveltime/2) % 3 == 0)) + S_StartSoundAtVolume(mo, sfx_s1b1, 64);*/ break; default: break; @@ -6511,6 +6513,9 @@ void P_RunBattleOvertime(void) { UINT8 i, j; + /*if (!S_IdPlaying(sfx_s3kd4l)) // global ambience + S_StartSound(NULL, sfx_s3kd4l);*/ + if (battleovertime->radius > 512) battleovertime->radius--; else @@ -6521,8 +6526,9 @@ void P_RunBattleOvertime(void) for (i = 0; i < 16; i++) // 16 base orbs { angle_t ang = FixedAngle(((45*i) * (FRACUNIT>>1)) + ((leveltime % 360)<x + P_ReturnThrustX(NULL, ang, battleovertime->radius<y + P_ReturnThrustY(NULL, ang, battleovertime->radius<radius - (2*mobjinfo[MT_OVERTIMEORB].radius))<x + P_ReturnThrustX(NULL, ang, dist); + fixed_t y = battleovertime->y + P_ReturnThrustY(NULL, ang, dist); P_SpawnOvertimeParticles(x, y, MT_OVERTIMEORB, true); } } @@ -6534,8 +6540,9 @@ void P_RunBattleOvertime(void) { fixed_t x = battleovertime->x + ((P_RandomRange(-64,64) * 128)<y + ((P_RandomRange(-64,64) * 128)<radius + (4*mobjinfo[MT_OVERTIMEFOG].radius))<x, y-battleovertime->y) <= (battleovertime->radius<x, y-battleovertime->y) < closestdist) continue; P_SpawnOvertimeParticles(x, y, MT_OVERTIMEFOG, false); break; @@ -9246,6 +9253,18 @@ void P_MobjThinker(mobj_t *mobj) trail->color = mobj->color; } break; + case MT_RANDOMITEM: + if (G_BattleGametype() && mobj->threshold == 70) + { + mobj->color = (1 + (leveltime % (MAXSKINCOLORS-1))); + mobj->colorized = true; + } + else + { + mobj->color = SKINCOLOR_NONE; + mobj->colorized = false; + } + break; //} case MT_TURRET: P_MobjCheckWater(mobj); @@ -9525,6 +9544,7 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s else newmobj = P_SpawnMobj(mobj->x, mobj->y, mobj->z, mobj->type); + P_SpawnMobj(newmobj->x, newmobj->y, newmobj->z, MT_EXPLODE); // poof into existance // Transfer flags2 (strongbox, objectflip) newmobj->flags2 = mobj->flags2 & ~MF2_DONTDRAW; if (mobj->threshold == 70) From 43af067415c229ddde7349924d9e0a170b7067b0 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 6 Dec 2018 18:13:40 -0500 Subject: [PATCH 04/91] Add a 5-second delay before the kill-field kicks in Until it's ready, the orbs are transparent and the minimap icon blinks. Also, tons more sounds. ALSO, Super Overtime mode. --- src/d_netcmd.c | 3 ++- src/doomstat.h | 4 ++-- src/k_kart.c | 17 ++++++++++------- src/p_inter.c | 4 +++- src/p_mobj.c | 28 ++++++++++++++++++++++------ src/p_saveg.c | 4 +++- src/sounds.c | 1 + src/sounds.h | 1 + 8 files changed, 44 insertions(+), 18 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 956990bd2..06f65bcaa 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -398,7 +398,8 @@ consvar_t cv_itemfinder = {"itemfinder", "Off", CV_CALL|CV_NOSHOWHELP, CV_OnOff, // Scoring type options consvar_t cv_match_scoring = {"matchscoring", "Normal", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, match_scoring_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_overtime = {"overtime", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t overtime_cons_t[] = {{0, "No"}, {1, "Yes"}, {2, "Super"}, {0, NULL}}; +consvar_t cv_overtime = {"overtime", "Yes", CV_NETVAR|CV_CHEAT, overtime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_rollingdemos = {"rollingdemos", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/doomstat.h b/src/doomstat.h index 605cef5bb..eb0af90f9 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -475,8 +475,8 @@ extern SINT8 pickedvote; */ typedef struct { - boolean enabled; ///< Has this been initalized yet? - UINT16 radius; ///< Radius of kill field + UINT8 enabled; ///< Has this been initalized yet? + UINT16 radius, minradius; ///< Radius of kill field fixed_t x, y, z; ///< Position to center on (z is only used for visuals) } battleovertime_t; diff --git a/src/k_kart.c b/src/k_kart.c index 5e6d07766..62bc99c45 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4394,7 +4394,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) && !player->kartstuff[k_respawn] && !player->powers[pw_flashing]) { player->kartstuff[k_wanted]++; - if (battleovertime->enabled) + if (battleovertime->enabled >= 5*TICRATE) { if (P_AproxDistance(player->mo->x - battleovertime->x, player->mo->y - battleovertime->y) > (battleovertime->radius<enabled) { - const INT32 prevsplitflags = splitflags; - splitflags &= ~V_HUDTRANSHALF; - splitflags |= V_HUDTRANS; - colormap = R_GetTranslationColormap(TC_RAINBOW, (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1))), GTC_CACHE); - K_drawKartMinimapHead(battleovertime->x, battleovertime->y, x, y, splitflags, kp_itemminimap, colormap, AutomapPic); - splitflags = prevsplitflags; + if (battleovertime->enabled >= 5*TICRATE || (battleovertime->enabled & 1)) + { + const INT32 prevsplitflags = splitflags; + splitflags &= ~V_HUDTRANSHALF; + splitflags |= V_HUDTRANS; + colormap = R_GetTranslationColormap(TC_RAINBOW, (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1))), GTC_CACHE); + K_drawKartMinimapHead(battleovertime->x, battleovertime->y, x, y, splitflags, kp_itemminimap, colormap, AutomapPic); + splitflags = prevsplitflags; + } } // Player's tiny icons on the Automap. (drawn opposite direction so player 1 is drawn last in splitscreen) diff --git a/src/p_inter.c b/src/p_inter.c index 4ef2f578f..b5615e4c8 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1838,7 +1838,9 @@ void P_CheckTimeLimit(void) battleovertime->y = item->y; battleovertime->z = item->z; battleovertime->radius = 4096; - battleovertime->enabled = true; + battleovertime->minradius = (cv_overtime.value == 2 ? 40 : 512); + battleovertime->enabled++; + S_StartSound(NULL, sfx_kc47); } return; #ifndef TESTOVERTIMEINFREEPLAY diff --git a/src/p_mobj.c b/src/p_mobj.c index 7c2c8438d..a79a3427d 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6499,6 +6499,8 @@ static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, mobjtype_t type, bool mo->destscale = mo->scale/4; if ((leveltime/2) & 1) mo->frame++; + if (battleovertime->enabled < 5*TICRATE) + mo->frame |= FF_TRANS50; /*if (i == 0 && !((leveltime/2) % 3 == 0)) S_StartSoundAtVolume(mo, sfx_s1b1, 64);*/ break; @@ -6513,13 +6515,21 @@ void P_RunBattleOvertime(void) { UINT8 i, j; - /*if (!S_IdPlaying(sfx_s3kd4l)) // global ambience - S_StartSound(NULL, sfx_s3kd4l);*/ - - if (battleovertime->radius > 512) - battleovertime->radius--; + if (battleovertime->enabled < 5*TICRATE) + { + battleovertime->enabled++; + if (battleovertime->enabled == TICRATE) + S_StartSound(NULL, sfx_bhurry); + if (battleovertime->enabled == 5*TICRATE) + S_StartSound(NULL, sfx_kc40); + } else - battleovertime->radius = 512; + { + if (battleovertime->radius > battleovertime->minradius) + battleovertime->radius--; + else + battleovertime->radius = battleovertime->minradius; + } if (leveltime & 1) { @@ -6533,6 +6543,12 @@ void P_RunBattleOvertime(void) } } + if (battleovertime->enabled < 5*TICRATE) + return; + + if (!S_IdPlaying(sfx_s3kd4s)) // global ambience + S_StartSoundAtVolume(NULL, sfx_s3kd4s, min(255, (4096-battleovertime->radius)/2)); + for (i = 0; i < 16; i++) { j = 0; diff --git a/src/p_saveg.c b/src/p_saveg.c index 8306e64ad..b70c7f83c 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3301,6 +3301,7 @@ static void P_NetArchiveMisc(void) // battleovertime_t WRITEUINT8(save_p, battleovertime->enabled); WRITEUINT16(save_p, battleovertime->radius); + WRITEUINT16(save_p, battleovertime->minradius); WRITEFIXED(save_p, battleovertime->x); WRITEFIXED(save_p, battleovertime->y); WRITEFIXED(save_p, battleovertime->z); @@ -3413,8 +3414,9 @@ static inline boolean P_NetUnArchiveMisc(void) battlewanted[i] = READSINT8(save_p); // battleovertime_t - battleovertime->enabled = (boolean)READUINT8(save_p); + battleovertime->enabled = READUINT8(save_p); battleovertime->radius = READUINT16(save_p); + battleovertime->minradius = READUINT16(save_p); battleovertime->x = READFIXED(save_p); battleovertime->y = READFIXED(save_p); battleovertime->z = READFIXED(save_p); diff --git a/src/sounds.c b/src/sounds.c index a3bc8bf41..4cad7e7c8 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -815,6 +815,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"chain", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Mementos Reaper {"mkuma", false, 96, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Trigger Happy Havoc Monokuma {"toada", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // Arid Sands Toad scream + {"bhurry", false, 255, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // v1.0.2 Battle overtime {"itfree", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR}, // :shitsfree: {"dbgsal", false, 255, 8, -1, NULL, 0, -1, -1, LUMPERROR}, // Debug notification diff --git a/src/sounds.h b/src/sounds.h index 4c341d49d..12e1fa43d 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -890,6 +890,7 @@ typedef enum sfx_chain, sfx_mkuma, sfx_toada, + sfx_bhurry, sfx_itfree, sfx_dbgsal, From 399cc44b93bdac928cfe3cb4ef5832d7a3515273 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 6 Dec 2018 18:16:13 -0500 Subject: [PATCH 05/91] Group k_killfield with the rest of the v1.0.2 vars --- src/d_player.h | 2 +- src/dehacked.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index ce5a92ab0..9ae46c6a8 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -346,12 +346,12 @@ typedef enum k_comebackpoints, // Number of times you've bombed or gave an item to someone; once it's 3 it gets set back to 0 and you're given a bumper k_comebackmode, // 0 = bomb, 1 = item k_wanted, // Timer for determining WANTED status, lowers when hitting people, prevents the game turning into Camp Lazlo - k_killfield, // How long have you been in the kill field, stay in too long and lose a bumper k_yougotem, // "You Got Em" gfx when hitting someone as a karma player via a method that gets you back in the game instantly // v1.0.2 vars k_itemblink, // Item flashing after roulette, prevents Hyudoro stealing AND serves as a mashing indicator k_itemblinkmode, // Type of flashing: 0 = white (normal), 1 = red (mashing), 2 = rainbow (enhanced items) + k_killfield, // How long have you been in the kill field, stay in too long and lose a bumper NUMKARTSTUFF } kartstufftype_t; diff --git a/src/dehacked.c b/src/dehacked.c index 44c8163df..1e4a9266a 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8284,11 +8284,11 @@ static const char *const KARTSTUFF_LIST[] = { "COMEBACKPOINTS", "COMEBACKMODE", "WANTED", - "KILLFIELD", "YOUGOTEM", "ITEMBLINK", - "ITEMBLINKMODE" + "ITEMBLINKMODE", + "KILLFIELD" }; static const char *const HUDITEMS_LIST[] = { From 312dd3f57f848920534f39c91d1d8e4a4f3152fe Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 7 Dec 2018 18:50:36 -0500 Subject: [PATCH 06/91] Ensure ALL boxes are respawned for overtime --- src/p_inter.c | 4 ++- src/p_local.h | 1 + src/p_mobj.c | 87 ++++++++++++++++++++++++++------------------------- 3 files changed, 49 insertions(+), 43 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index b5615e4c8..037a3566e 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1792,7 +1792,7 @@ void P_CheckTimeLimit(void) //Optional tie-breaker for Match/CTF else*/ -#define TESTOVERTIMEINFREEPLAY +//#define TESTOVERTIMEINFREEPLAY if (cv_overtime.value) { #ifndef TESTOVERTIMEINFREEPLAY @@ -1811,6 +1811,8 @@ void P_CheckTimeLimit(void) thinker_t *th; mobj_t *item = NULL; + P_RespawnBattleBoxes(); // FORCE THESE TO BE RESPAWNED FOR THIS!!!!!!! + // Find us an item box to center on. for (th = thinkercap.next; th != &thinkercap; th = th->next) { diff --git a/src/p_local.h b/src/p_local.h index b6dcd4d0b..4e06f3230 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -216,6 +216,7 @@ extern tic_t itemrespawntime[ITEMQUESIZE]; extern size_t iquehead, iquetail; extern consvar_t cv_gravity/*, cv_viewheight*/; +void P_RespawnBattleBoxes(void); void P_RespawnSpecials(void); mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type); diff --git a/src/p_mobj.c b/src/p_mobj.c index a79a3427d..5ae74d947 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -9544,10 +9544,7 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s if (G_BattleGametype() && (mobj->threshold != 70)) { if (mobj->threshold != 69) - { - mobj->fuse = cv_itemrespawntime.value*TICRATE + 2; break; - } } else { @@ -10900,6 +10897,50 @@ void P_PrecipitationEffects(void) } } +void P_RespawnBattleBoxes(void) +{ + thinker_t *th; + + if (!G_BattleGametype()) + return; + + for (th = thinkercap.next; th != &thinkercap; th = th->next) + { + mobj_t *box; + mobj_t *newmobj; + + if (th->function.acp1 != (actionf_p1)P_MobjThinker) // not a mobj + continue; + + box = (mobj_t *)th; + + if (box->type != MT_RANDOMITEM || box->threshold != 68 || box->fuse) // only popped items + continue; + + // Respawn from mapthing if you have one! + if (box->spawnpoint) + { + P_SpawnMapThing(box->spawnpoint); + newmobj = box->spawnpoint->mobj; // this is set to the new mobj in P_SpawnMapThing + P_SpawnMobj(box->spawnpoint->mobj->x, box->spawnpoint->mobj->y, box->spawnpoint->mobj->z, MT_EXPLODE); // poof into existance + } + else + { + newmobj = P_SpawnMobj(box->x, box->y, box->z, box->type); + P_SpawnMobj(newmobj->x, newmobj->y, newmobj->z, MT_EXPLODE); // poof into existance + } + + // Transfer flags2 (strongbox, objectflip) + newmobj->flags2 = box->flags2; + P_RemoveMobj(box); // make sure they disappear + numgotboxes--; // you've restored a box, remove it from the count + //continue; -- irrelevant? + } + + if (numgotboxes < 0) + numgotboxes = 0; +} + // // P_RespawnSpecials // @@ -10911,45 +10952,7 @@ void P_RespawnSpecials(void) mapthing_t *mthing = NULL; if (G_BattleGametype() && numgotboxes >= (4*nummapboxes/5)) // Battle Mode respawns all boxes in a different way - { - thinker_t *th; - - for (th = thinkercap.next; th != &thinkercap; th = th->next) - { - mobj_t *box; - mobj_t *newmobj; - - if (th->function.acp1 != (actionf_p1)P_MobjThinker) // not a mobj - continue; - - box = (mobj_t *)th; - - if (box->type != MT_RANDOMITEM || box->threshold != 68 || box->fuse) // only popped items - continue; - - // Respawn from mapthing if you have one! - if (box->spawnpoint) - { - P_SpawnMapThing(box->spawnpoint); - newmobj = box->spawnpoint->mobj; // this is set to the new mobj in P_SpawnMapThing - P_SpawnMobj(box->spawnpoint->mobj->x, box->spawnpoint->mobj->y, box->spawnpoint->mobj->z, MT_EXPLODE); // poof into existance - } - else - { - newmobj = P_SpawnMobj(box->x, box->y, box->z, box->type); - P_SpawnMobj(newmobj->x, newmobj->y, newmobj->z, MT_EXPLODE); // poof into existance - } - - // Transfer flags2 (strongbox, objectflip) - newmobj->flags2 = box->flags2; - P_RemoveMobj(box); // make sure they disappear - numgotboxes--; // you've restored a box, remove it from the count - //continue; -- irrelevant? - } - - if (numgotboxes < 0) - numgotboxes = 0; - } + P_RespawnBattleBoxes(); // only respawn items when cv_itemrespawn is on if (!cv_itemrespawn.value) From b27c70987929711d04acdef3ebc76ed2c5b57a9a Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 15 Dec 2018 19:14:30 -0500 Subject: [PATCH 07/91] a bunch of stuff I left uncommited --- src/d_netcmd.c | 4 +-- src/dehacked.c | 2 ++ src/doomdef.h | 2 +- src/doomstat.h | 4 +-- src/info.c | 34 +++++++++++++++++-- src/info.h | 2 ++ src/k_kart.c | 6 +++- src/p_inter.c | 13 ++++++-- src/p_mobj.c | 84 +++++++++++++++++++++++++++++++++++++---------- src/p_saveg.c | 8 ++--- src/sdl/i_video.c | 2 +- 11 files changed, 127 insertions(+), 34 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 06f65bcaa..9cf61bc5f 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -4327,9 +4327,9 @@ void D_GameTypeChanged(INT32 lastgametype) case GT_TEAMMATCH: if (!cv_timelimit.changed && !cv_pointlimit.changed) // user hasn't changed limits { - // default settings for match: 3 mins, no pointlimit + // default settings for match: 2 mins, no pointlimit CV_SetValue(&cv_pointlimit, 0); - CV_SetValue(&cv_timelimit, 3); + CV_SetValue(&cv_timelimit, 2); } if (!cv_itemrespawntime.changed) CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); // respawn normally diff --git a/src/dehacked.c b/src/dehacked.c index 1e4a9266a..46b90e8af 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7101,6 +7101,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_OVERTIMEFOG", "S_OVERTIMEORB", + "S_OVERTIMEBEAM", #ifdef SEENAMES "S_NAMECHECK", @@ -7891,6 +7892,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_OVERTIMEFOG", "MT_OVERTIMEORB", + "MT_OVERTIMEBEAM", #ifdef SEENAMES "MT_NAMECHECK", diff --git a/src/doomdef.h b/src/doomdef.h index a35f3291d..0791e07e9 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -140,7 +140,7 @@ extern FILE *logstream; #endif -//#define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable MD5 checking and stuff, all in one go. :3 +#define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable MD5 checking and stuff, all in one go. :3 #ifdef DEVELOP #define VERSION 0 // Game version #define SUBVERSION 0 // more precise version number diff --git a/src/doomstat.h b/src/doomstat.h index eb0af90f9..aa92e45ed 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -476,8 +476,8 @@ extern SINT8 pickedvote; typedef struct { UINT8 enabled; ///< Has this been initalized yet? - UINT16 radius, minradius; ///< Radius of kill field - fixed_t x, y, z; ///< Position to center on (z is only used for visuals) + fixed_t radius, minradius; ///< Radius of kill field + fixed_t x, y, z; ///< Position to center on } battleovertime_t; extern battleovertime_t *battleovertime; diff --git a/src/info.c b/src/info.c index ae9696edc..917e5ddec 100644 --- a/src/info.c +++ b/src/info.c @@ -3395,7 +3395,8 @@ state_t states[NUMSTATES] = {SPR_FWRK, 4|FF_FULLBRIGHT, TICRATE, {NULL}, 0, 0, S_NULL}, // S_KARMAFIREWORKTRAIL {SPR_OTFG, FF_FULLBRIGHT|FF_TRANS50, TICRATE, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEFOG - {SPR_OTFG, 1|FF_FULLBRIGHT, 8, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEORB + {SPR_OTFG, 1|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEORB + {SPR_OTFG, 3|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEBEAM #ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK @@ -20072,7 +20073,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16<type == MT_RANDOMITEM) + return 10<type) { case MT_PLAYER: @@ -4396,7 +4400,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) player->kartstuff[k_wanted]++; if (battleovertime->enabled >= 5*TICRATE) { - if (P_AproxDistance(player->mo->x - battleovertime->x, player->mo->y - battleovertime->y) > (battleovertime->radius<mo->x - battleovertime->x, player->mo->y - battleovertime->y) > battleovertime->radius) { player->kartstuff[k_killfield]++; if (player->kartstuff[k_killfield] > 4*TICRATE) diff --git a/src/p_inter.c b/src/p_inter.c index 037a3566e..6e4b6f0e9 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -373,7 +373,14 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; case MT_RANDOMITEM: // SRB2kart if (!P_CanPickupItem(player, 1)) + { + if (G_BattleGametype() && special->threshold == 70 && special->health) + { + K_KartBouncing(toucher, special, false, false); + special->extravalue1 = 6; + } return; + } if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0) { @@ -1792,7 +1799,7 @@ void P_CheckTimeLimit(void) //Optional tie-breaker for Match/CTF else*/ -//#define TESTOVERTIMEINFREEPLAY +#define TESTOVERTIMEINFREEPLAY if (cv_overtime.value) { #ifndef TESTOVERTIMEINFREEPLAY @@ -1839,8 +1846,8 @@ void P_CheckTimeLimit(void) battleovertime->x = item->x; battleovertime->y = item->y; battleovertime->z = item->z; - battleovertime->radius = 4096; - battleovertime->minradius = (cv_overtime.value == 2 ? 40 : 512); + battleovertime->radius = 4096*mapheaderinfo[gamemap-1]->mobj_scale; + battleovertime->minradius = (cv_overtime.value == 2 ? 40 : 512)*mapheaderinfo[gamemap-1]->mobj_scale; battleovertime->enabled++; S_StartSound(NULL, sfx_kc47); } diff --git a/src/p_mobj.c b/src/p_mobj.c index 5ae74d947..a37c26d78 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6417,6 +6417,7 @@ static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, mobjtype_t type, bool fixed_t flatz[MAXPLANESPERSECTOR]; UINT8 numflats = 0; mobj_t *mo; + fixed_t scale = mapheaderinfo[gamemap-1]->mobj_scale; subsector_t *ss = R_IsPointInSubsector(x, y); sector_t *sec; @@ -6424,6 +6425,18 @@ static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, mobjtype_t type, bool return; sec = ss->sector; + switch(type) + { + case MT_OVERTIMEFOG: + scale *= 4; + break; + case MT_OVERTIMEORB: + scale += battleovertime->radius/1024; + break; + default: + break; + } + // convoluted stuff JUST to get all of the planes we need to draw orbs on :V if (sec->floorpic != skyflatnum) @@ -6438,9 +6451,9 @@ static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, mobjtype_t type, bool if (sec->ceilingpic != skyflatnum && ceiling) { #ifdef ESLOPE - flatz[numflats] = (sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : sec->ceilingheight) - mobjinfo[MT_THOK].height; + flatz[numflats] = (sec->c_slope ? P_GetZAt(sec->c_slope, x, y) : sec->ceilingheight) - FixedMul(mobjinfo[type].height, scale); #else - flatz[numflats] = (sec->ceilingheight) - mobjinfo[MT_THOK].height; + flatz[numflats] = (sec->ceilingheight) - FixedMul(mobjinfo[type].height, scale); #endif numflats++; } @@ -6464,9 +6477,9 @@ static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, mobjtype_t type, bool if (*rover->bottompic != skyflatnum && ceiling) { #ifdef ESLOPE - flatz[numflats] = (*rover->b_slope ? P_GetZAt(*rover->b_slope, x, y) : *rover->bottomheight) - mobjinfo[MT_THOK].height; + flatz[numflats] = (*rover->b_slope ? P_GetZAt(*rover->b_slope, x, y) : *rover->bottomheight) - FixedMul(mobjinfo[type].height, scale); #else - flatz[numflats] = (*rover->bottomheight) - mobjinfo[MT_THOK].height; + flatz[numflats] = (*rover->bottomheight) - FixedMul(mobjinfo[type].height, scale); #endif numflats++; } @@ -6487,20 +6500,20 @@ static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, mobjtype_t type, bool continue; } + P_SetScale(mo, scale); + switch(type) { case MT_OVERTIMEFOG: - P_SetScale(mo, 4*mo->scale); mo->destscale = 8*mo->scale; mo->momz = P_RandomRange(1,8)*mo->scale; break; case MT_OVERTIMEORB: - P_SetScale(mo, 2*mo->scale); mo->destscale = mo->scale/4; if ((leveltime/2) & 1) mo->frame++; if (battleovertime->enabled < 5*TICRATE) - mo->frame |= FF_TRANS50; + mo->flags2 |= MF2_SHADOW; /*if (i == 0 && !((leveltime/2) % 3 == 0)) S_StartSoundAtVolume(mo, sfx_s1b1, 64);*/ break; @@ -6514,6 +6527,7 @@ static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, mobjtype_t type, bool void P_RunBattleOvertime(void) { UINT8 i, j; + UINT16 orbs = 16; if (battleovertime->enabled < 5*TICRATE) { @@ -6526,28 +6540,45 @@ void P_RunBattleOvertime(void) else { if (battleovertime->radius > battleovertime->minradius) - battleovertime->radius--; + battleovertime->radius -= mapheaderinfo[gamemap-1]->mobj_scale; else battleovertime->radius = battleovertime->minradius; } if (leveltime & 1) { - for (i = 0; i < 16; i++) // 16 base orbs + UINT8 transparency = tr_trans50; + + if (!splitscreen && players[displayplayer].mo) { - angle_t ang = FixedAngle(((45*i) * (FRACUNIT>>1)) + ((leveltime % 360)<radius - (2*mobjinfo[MT_OVERTIMEORB].radius))<x + P_ReturnThrustX(NULL, ang, dist); - fixed_t y = battleovertime->y + P_ReturnThrustY(NULL, ang, dist); - P_SpawnOvertimeParticles(x, y, MT_OVERTIMEORB, true); + INT32 dist = P_AproxDistance(battleovertime->x-players[displayplayer].mo->x, battleovertime->y-players[displayplayer].mo->y); + transparency = max(0, NUMTRANSMAPS - ((256 + (dist>>FRACBITS)) / 256)); } + + if (transparency < NUMTRANSMAPS) + { + mobj_t *beam = P_SpawnMobj(battleovertime->x, battleovertime->y, battleovertime->z + (mobjinfo[MT_RANDOMITEM].height/2), MT_OVERTIMEBEAM); + P_SetScale(beam, beam->scale*2); + if (transparency > 0) + beam->frame |= transparency<radius, 16*mapheaderinfo[gamemap-1]->mobj_scale)>>FRACBITS); + for (i = 0; i < orbs; i++) + { + angle_t ang = FixedAngle(((360/orbs) * i * (FRACUNIT>>1)) + (((leveltime*2) % 360)<x + P_ReturnThrustX(NULL, ang, battleovertime->radius); + fixed_t y = battleovertime->y + P_ReturnThrustY(NULL, ang, battleovertime->radius); + P_SpawnOvertimeParticles(x, y, MT_OVERTIMEORB, true); } if (battleovertime->enabled < 5*TICRATE) return; if (!S_IdPlaying(sfx_s3kd4s)) // global ambience - S_StartSoundAtVolume(NULL, sfx_s3kd4s, min(255, (4096-battleovertime->radius)/2)); + S_StartSoundAtVolume(NULL, sfx_s3kd4s, min(255, ((4096*mapheaderinfo[gamemap-1]->mobj_scale) - battleovertime->radius)>>FRACBITS / 2)); for (i = 0; i < 16; i++) { @@ -6556,7 +6587,7 @@ void P_RunBattleOvertime(void) { fixed_t x = battleovertime->x + ((P_RandomRange(-64,64) * 128)<y + ((P_RandomRange(-64,64) * 128)<radius + (4*mobjinfo[MT_OVERTIMEFOG].radius))<radius + (8*mobjinfo[MT_OVERTIMEFOG].radius); j++; if (P_AproxDistance(x-battleovertime->x, y-battleovertime->y) < closestdist) continue; @@ -7172,7 +7203,7 @@ void P_MobjThinker(mobj_t *mobj) mobj->x = mobj->target->x; mobj->y = mobj->target->y; - if (!splitscreen) + if (!splitscreen && players[displayplayer].mo) { scale = mobj->target->scale + FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayer].mo->x-mobj->target->x, players[displayplayer].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale); @@ -9274,6 +9305,25 @@ void P_MobjThinker(mobj_t *mobj) { mobj->color = (1 + (leveltime % (MAXSKINCOLORS-1))); mobj->colorized = true; + if (mobj->extravalue1) + mobj->extravalue1--; + else if (battleovertime->enabled) + { + fixed_t dist = P_AproxDistance(P_AproxDistance(battleovertime->x-mobj->x, battleovertime->y-mobj->y), battleovertime->z-mobj->z); + if (dist > mobj->scale) + { + angle_t hang = R_PointToAngle2(mobj->x, mobj->y, battleovertime->x, battleovertime->y); + angle_t vang = R_PointToAngle2(mobj->z, 0, battleovertime->z, dist); + mobj->momx += FixedMul(FixedMul(mobj->scale, FINECOSINE(hang>>ANGLETOFINESHIFT)), FINECOSINE(vang>>ANGLETOFINESHIFT)); + mobj->momy += FixedMul(FixedMul(mobj->scale, FINESINE(hang>>ANGLETOFINESHIFT)), FINECOSINE(vang>>ANGLETOFINESHIFT)); + mobj->momz += FixedMul(mobj->scale, FINESINE(vang>>ANGLETOFINESHIFT)); + } + else + { + mobj->momx = mobj->momy = mobj->momz = 0; + P_TeleportMove(mobj, battleovertime->x, battleovertime->y, battleovertime->z); + } + } } else { diff --git a/src/p_saveg.c b/src/p_saveg.c index b70c7f83c..f23179280 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3300,8 +3300,8 @@ static void P_NetArchiveMisc(void) // battleovertime_t WRITEUINT8(save_p, battleovertime->enabled); - WRITEUINT16(save_p, battleovertime->radius); - WRITEUINT16(save_p, battleovertime->minradius); + WRITEFIXED(save_p, battleovertime->radius); + WRITEFIXED(save_p, battleovertime->minradius); WRITEFIXED(save_p, battleovertime->x); WRITEFIXED(save_p, battleovertime->y); WRITEFIXED(save_p, battleovertime->z); @@ -3415,8 +3415,8 @@ static inline boolean P_NetUnArchiveMisc(void) // battleovertime_t battleovertime->enabled = READUINT8(save_p); - battleovertime->radius = READUINT16(save_p); - battleovertime->minradius = READUINT16(save_p); + battleovertime->radius = READFIXED(save_p); + battleovertime->minradius = READFIXED(save_p); battleovertime->x = READFIXED(save_p); battleovertime->y = READFIXED(save_p); battleovertime->z = READFIXED(save_p); diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 78dfc820c..8bbd60e89 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1370,7 +1370,7 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) #endif // Create a window - window = SDL_CreateWindow("SRB2Kart "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + window = SDL_CreateWindow("FortniteKart "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, realwidth, realheight, flags); if (window == NULL) From 8391dd520ab9b9eb686140004559b586e31c5dbb Mon Sep 17 00:00:00 2001 From: SeventhSentinel Date: Wed, 2 Jan 2019 14:08:00 -0500 Subject: [PATCH 08/91] Add item spinning, turn into papersprites, spawn more orbs Also tried to fix a memory issue I only get from Sev's compiles by removing the need to free memory for this... but didn't fix anything :/ --- src/doomstat.h | 8 ++---- src/g_game.c | 2 +- src/info.c | 2 +- src/k_kart.c | 14 ++++------ src/p_inter.c | 31 ++++++++++---------- src/p_mobj.c | 76 +++++++++++++++++++++----------------------------- src/p_saveg.c | 24 ++++++++-------- src/p_setup.c | 4 +-- src/p_tick.c | 4 +-- 9 files changed, 71 insertions(+), 94 deletions(-) diff --git a/src/doomstat.h b/src/doomstat.h index aa92e45ed..2c810dcfe 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -473,14 +473,12 @@ extern SINT8 pickedvote; /** Battle overtime information */ -typedef struct +extern struct battleovertime { - UINT8 enabled; ///< Has this been initalized yet? + UINT16 enabled; ///< Has this been initalized yet? fixed_t radius, minradius; ///< Radius of kill field fixed_t x, y, z; ///< Position to center on -} battleovertime_t; - -extern battleovertime_t *battleovertime; +} battleovertime; extern tic_t hidetime; diff --git a/src/g_game.c b/src/g_game.c index 75e7440b8..42652a4de 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -261,7 +261,7 @@ SINT8 votes[MAXPLAYERS]; // Each player's vote SINT8 pickedvote; // What vote the host rolls // Battle overtime system -battleovertime_t *battleovertime = {NULL}; +struct battleovertime battleovertime; // Server-sided, synched variables SINT8 battlewanted[4]; // WANTED players in battle, worth x2 points diff --git a/src/info.c b/src/info.c index 917e5ddec..50e10ba6b 100644 --- a/src/info.c +++ b/src/info.c @@ -3395,7 +3395,7 @@ state_t states[NUMSTATES] = {SPR_FWRK, 4|FF_FULLBRIGHT, TICRATE, {NULL}, 0, 0, S_NULL}, // S_KARMAFIREWORKTRAIL {SPR_OTFG, FF_FULLBRIGHT|FF_TRANS50, TICRATE, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEFOG - {SPR_OTFG, 1|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEORB + {SPR_OTFG, 1|FF_FULLBRIGHT|FF_TRANS30|FF_PAPERSPRITE, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEORB {SPR_OTFG, 3|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEBEAM #ifdef SEENAMES diff --git a/src/k_kart.c b/src/k_kart.c index 87a655436..7dfddcb8a 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1033,10 +1033,6 @@ static fixed_t K_GetMobjWeight(mobj_t *mobj, mobj_t *against) { fixed_t weight = 5<type == MT_RANDOMITEM) - return 10<type) { case MT_PLAYER: @@ -4398,9 +4394,9 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) && !player->kartstuff[k_respawn] && !player->powers[pw_flashing]) { player->kartstuff[k_wanted]++; - if (battleovertime->enabled >= 5*TICRATE) + if (battleovertime.enabled >= 5*TICRATE) { - if (P_AproxDistance(player->mo->x - battleovertime->x, player->mo->y - battleovertime->y) > battleovertime->radius) + if (P_AproxDistance(player->mo->x - battleovertime.x, player->mo->y - battleovertime.y) > battleovertime.radius) { player->kartstuff[k_killfield]++; if (player->kartstuff[k_killfield] > 4*TICRATE) @@ -7437,15 +7433,15 @@ static void K_drawKartMinimap(void) y -= SHORT(AutomapPic->topoffset); // Draw the super item in Battle - if (G_BattleGametype() && battleovertime->enabled) + if (G_BattleGametype() && battleovertime.enabled) { - if (battleovertime->enabled >= 5*TICRATE || (battleovertime->enabled & 1)) + if (battleovertime.enabled >= 5*TICRATE || (battleovertime.enabled & 1)) { const INT32 prevsplitflags = splitflags; splitflags &= ~V_HUDTRANSHALF; splitflags |= V_HUDTRANS; colormap = R_GetTranslationColormap(TC_RAINBOW, (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1))), GTC_CACHE); - K_drawKartMinimapHead(battleovertime->x, battleovertime->y, x, y, splitflags, kp_itemminimap, colormap, AutomapPic); + K_drawKartMinimapHead(battleovertime.x, battleovertime.y, x, y, splitflags, kp_itemminimap, colormap, AutomapPic); splitflags = prevsplitflags; } } diff --git a/src/p_inter.c b/src/p_inter.c index 6e4b6f0e9..f6eb9db65 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -373,14 +373,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) return; case MT_RANDOMITEM: // SRB2kart if (!P_CanPickupItem(player, 1)) - { - if (G_BattleGametype() && special->threshold == 70 && special->health) - { - K_KartBouncing(toucher, special, false, false); - special->extravalue1 = 6; - } return; - } if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0) { @@ -1752,6 +1745,9 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } } +// Easily make it so that overtime works offline +#define TESTOVERTIMEINFREEPLAY + /** Checks if the level timer is over the timelimit and the round should end, * unless you are in overtime. In which case leveltime may stretch out beyond * timelimitintics and overtime's status will be checked here each tick. @@ -1796,10 +1792,9 @@ void P_CheckTimeLimit(void) } } } + else*/ //Optional tie-breaker for Match/CTF - else*/ -#define TESTOVERTIMEINFREEPLAY if (cv_overtime.value) { #ifndef TESTOVERTIMEINFREEPLAY @@ -1812,9 +1807,9 @@ void P_CheckTimeLimit(void) { #endif // Initiate the kill zone - if (!battleovertime->enabled) + if (!battleovertime.enabled) { - UINT8 b = 0; + INT32 b = 0; thinker_t *th; mobj_t *item = NULL; @@ -1843,12 +1838,12 @@ void P_CheckTimeLimit(void) return; item->threshold = 70; // Set constant respawn - battleovertime->x = item->x; - battleovertime->y = item->y; - battleovertime->z = item->z; - battleovertime->radius = 4096*mapheaderinfo[gamemap-1]->mobj_scale; - battleovertime->minradius = (cv_overtime.value == 2 ? 40 : 512)*mapheaderinfo[gamemap-1]->mobj_scale; - battleovertime->enabled++; + battleovertime.x = item->x; + battleovertime.y = item->y; + battleovertime.z = item->z; + battleovertime.radius = 4096*mapheaderinfo[gamemap-1]->mobj_scale; + battleovertime.minradius = (cv_overtime.value == 2 ? 40 : 512)*mapheaderinfo[gamemap-1]->mobj_scale; + battleovertime.enabled = 1; S_StartSound(NULL, sfx_kc47); } return; @@ -1870,6 +1865,8 @@ void P_CheckTimeLimit(void) } } +#undef TESTOVERTIMEINFREEPLAY + /** Checks if a player's score is over the pointlimit and the round should end. * Verify that the value of ::cv_pointlimit is greater than zero before * calling this function. diff --git a/src/p_mobj.c b/src/p_mobj.c index a37c26d78..1279ec7a8 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6431,7 +6431,7 @@ static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, mobjtype_t type, bool scale *= 4; break; case MT_OVERTIMEORB: - scale += battleovertime->radius/1024; + scale += battleovertime.radius/1024; break; default: break; @@ -6509,13 +6509,12 @@ static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, mobjtype_t type, bool mo->momz = P_RandomRange(1,8)*mo->scale; break; case MT_OVERTIMEORB: - mo->destscale = mo->scale/4; + //mo->destscale = mo->scale/4; if ((leveltime/2) & 1) mo->frame++; - if (battleovertime->enabled < 5*TICRATE) + if (battleovertime.enabled < 5*TICRATE) mo->flags2 |= MF2_SHADOW; - /*if (i == 0 && !((leveltime/2) % 3 == 0)) - S_StartSoundAtVolume(mo, sfx_s1b1, 64);*/ + mo->angle = R_PointToAngle2(mo->x, mo->y, battleovertime.x, battleovertime.y) + ANGLE_90; break; default: break; @@ -6527,22 +6526,22 @@ static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, mobjtype_t type, bool void P_RunBattleOvertime(void) { UINT8 i, j; - UINT16 orbs = 16; + UINT16 orbs = 32; - if (battleovertime->enabled < 5*TICRATE) + if (battleovertime.enabled < 5*TICRATE) { - battleovertime->enabled++; - if (battleovertime->enabled == TICRATE) + battleovertime.enabled++; + if (battleovertime.enabled == TICRATE) S_StartSound(NULL, sfx_bhurry); - if (battleovertime->enabled == 5*TICRATE) + if (battleovertime.enabled == 5*TICRATE) S_StartSound(NULL, sfx_kc40); } else { - if (battleovertime->radius > battleovertime->minradius) - battleovertime->radius -= mapheaderinfo[gamemap-1]->mobj_scale; + if (battleovertime.radius > battleovertime.minradius) + battleovertime.radius -= mapheaderinfo[gamemap-1]->mobj_scale; else - battleovertime->radius = battleovertime->minradius; + battleovertime.radius = battleovertime.minradius; } if (leveltime & 1) @@ -6551,45 +6550,45 @@ void P_RunBattleOvertime(void) if (!splitscreen && players[displayplayer].mo) { - INT32 dist = P_AproxDistance(battleovertime->x-players[displayplayer].mo->x, battleovertime->y-players[displayplayer].mo->y); + INT32 dist = P_AproxDistance(battleovertime.x-players[displayplayer].mo->x, battleovertime.y-players[displayplayer].mo->y); transparency = max(0, NUMTRANSMAPS - ((256 + (dist>>FRACBITS)) / 256)); } if (transparency < NUMTRANSMAPS) { - mobj_t *beam = P_SpawnMobj(battleovertime->x, battleovertime->y, battleovertime->z + (mobjinfo[MT_RANDOMITEM].height/2), MT_OVERTIMEBEAM); + mobj_t *beam = P_SpawnMobj(battleovertime.x, battleovertime.y, battleovertime.z + (mobjinfo[MT_RANDOMITEM].height/2), MT_OVERTIMEBEAM); P_SetScale(beam, beam->scale*2); if (transparency > 0) beam->frame |= transparency<radius, 16*mapheaderinfo[gamemap-1]->mobj_scale)>>FRACBITS); + // 32 orbs at the normal minimum size of 512 + orbs = max(4, FixedDiv(battleovertime.radius, 16*mapheaderinfo[gamemap-1]->mobj_scale)>>FRACBITS); for (i = 0; i < orbs; i++) { angle_t ang = FixedAngle(((360/orbs) * i * (FRACUNIT>>1)) + (((leveltime*2) % 360)<x + P_ReturnThrustX(NULL, ang, battleovertime->radius); - fixed_t y = battleovertime->y + P_ReturnThrustY(NULL, ang, battleovertime->radius); + fixed_t x = battleovertime.x + P_ReturnThrustX(NULL, ang, battleovertime.radius); + fixed_t y = battleovertime.y + P_ReturnThrustY(NULL, ang, battleovertime.radius); P_SpawnOvertimeParticles(x, y, MT_OVERTIMEORB, true); } - if (battleovertime->enabled < 5*TICRATE) + if (battleovertime.enabled < 5*TICRATE) return; - if (!S_IdPlaying(sfx_s3kd4s)) // global ambience - S_StartSoundAtVolume(NULL, sfx_s3kd4s, min(255, ((4096*mapheaderinfo[gamemap-1]->mobj_scale) - battleovertime->radius)>>FRACBITS / 2)); + /*if (!S_IdPlaying(sfx_s3kd4s)) // global ambience + S_StartSoundAtVolume(NULL, sfx_s3kd4s, min(255, ((4096*mapheaderinfo[gamemap-1]->mobj_scale) - battleovertime.radius)>>FRACBITS / 2));*/ for (i = 0; i < 16; i++) { j = 0; while (j < 32) // max attempts { - fixed_t x = battleovertime->x + ((P_RandomRange(-64,64) * 128)<y + ((P_RandomRange(-64,64) * 128)<radius + (8*mobjinfo[MT_OVERTIMEFOG].radius); + fixed_t x = battleovertime.x + ((P_RandomRange(-64,64) * 128)<x, y-battleovertime->y) < closestdist) + if (P_AproxDistance(x-battleovertime.x, y-battleovertime.y) < closestdist) continue; P_SpawnOvertimeParticles(x, y, MT_OVERTIMEFOG, false); break; @@ -9303,26 +9302,15 @@ void P_MobjThinker(mobj_t *mobj) case MT_RANDOMITEM: if (G_BattleGametype() && mobj->threshold == 70) { - mobj->color = (1 + (leveltime % (MAXSKINCOLORS-1))); + mobj->color = (UINT8)(1 + (leveltime % (MAXSKINCOLORS-1))); mobj->colorized = true; - if (mobj->extravalue1) - mobj->extravalue1--; - else if (battleovertime->enabled) + + if (battleovertime.enabled) { - fixed_t dist = P_AproxDistance(P_AproxDistance(battleovertime->x-mobj->x, battleovertime->y-mobj->y), battleovertime->z-mobj->z); - if (dist > mobj->scale) - { - angle_t hang = R_PointToAngle2(mobj->x, mobj->y, battleovertime->x, battleovertime->y); - angle_t vang = R_PointToAngle2(mobj->z, 0, battleovertime->z, dist); - mobj->momx += FixedMul(FixedMul(mobj->scale, FINECOSINE(hang>>ANGLETOFINESHIFT)), FINECOSINE(vang>>ANGLETOFINESHIFT)); - mobj->momy += FixedMul(FixedMul(mobj->scale, FINESINE(hang>>ANGLETOFINESHIFT)), FINECOSINE(vang>>ANGLETOFINESHIFT)); - mobj->momz += FixedMul(mobj->scale, FINESINE(vang>>ANGLETOFINESHIFT)); - } - else - { - mobj->momx = mobj->momy = mobj->momz = 0; - P_TeleportMove(mobj, battleovertime->x, battleovertime->y, battleovertime->z); - } + fixed_t dist = min((4096*mapheaderinfo[gamemap-1]->mobj_scale - battleovertime.radius) / 2, 512*mapheaderinfo[gamemap-1]->mobj_scale); + angle_t ang = FixedAngle((leveltime % 360) << FRACBITS); + P_TeleportMove(mobj, battleovertime.x + P_ReturnThrustX(NULL, ang, dist), + battleovertime.y + P_ReturnThrustY(NULL, ang, dist), battleovertime.z); } } else diff --git a/src/p_saveg.c b/src/p_saveg.c index f23179280..5d4b88f84 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3299,12 +3299,12 @@ static void P_NetArchiveMisc(void) WRITESINT8(save_p, battlewanted[i]); // battleovertime_t - WRITEUINT8(save_p, battleovertime->enabled); - WRITEFIXED(save_p, battleovertime->radius); - WRITEFIXED(save_p, battleovertime->minradius); - WRITEFIXED(save_p, battleovertime->x); - WRITEFIXED(save_p, battleovertime->y); - WRITEFIXED(save_p, battleovertime->z); + WRITEUINT16(save_p, battleovertime.enabled); + WRITEFIXED(save_p, battleovertime.radius); + WRITEFIXED(save_p, battleovertime.minradius); + WRITEFIXED(save_p, battleovertime.x); + WRITEFIXED(save_p, battleovertime.y); + WRITEFIXED(save_p, battleovertime.z); WRITEUINT32(save_p, wantedcalcdelay); WRITEUINT32(save_p, indirectitemcooldown); @@ -3414,12 +3414,12 @@ static inline boolean P_NetUnArchiveMisc(void) battlewanted[i] = READSINT8(save_p); // battleovertime_t - battleovertime->enabled = READUINT8(save_p); - battleovertime->radius = READFIXED(save_p); - battleovertime->minradius = READFIXED(save_p); - battleovertime->x = READFIXED(save_p); - battleovertime->y = READFIXED(save_p); - battleovertime->z = READFIXED(save_p); + battleovertime.enabled = READUINT16(save_p); + battleovertime.radius = READFIXED(save_p); + battleovertime.minradius = READFIXED(save_p); + battleovertime.x = READFIXED(save_p); + battleovertime.y = READFIXED(save_p); + battleovertime.z = READFIXED(save_p); wantedcalcdelay = READUINT32(save_p); indirectitemcooldown = READUINT32(save_p); diff --git a/src/p_setup.c b/src/p_setup.c index 01b231116..4bfb0ff88 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2374,9 +2374,7 @@ static void P_LevelInitStuff(void) for (i = 0; i < 4; i++) battlewanted[i] = -1; - if (!battleovertime) - battleovertime = Z_Malloc(sizeof(battleovertime_t), PU_STATIC, NULL); - memset(battleovertime, 0, sizeof(battleovertime_t)); + memset(&battleovertime, 0, sizeof(struct battleovertime)); } // diff --git a/src/p_tick.c b/src/p_tick.c index def074d60..90b1835b6 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -621,7 +621,7 @@ void P_Ticker(boolean run) if (run) { P_RunThinkers(); - if (G_BattleGametype() && battleovertime->enabled) + if (G_BattleGametype() && battleovertime.enabled) P_RunBattleOvertime(); // Run any "after all the other thinkers" stuff @@ -762,7 +762,7 @@ void P_PreTicker(INT32 frames) } P_RunThinkers(); - if (G_BattleGametype() && battleovertime->enabled) + if (G_BattleGametype() && battleovertime.enabled) P_RunBattleOvertime(); // Run any "after all the other thinkers" stuff From 7790a6110c12c1a16a561908265add61858770ed Mon Sep 17 00:00:00 2001 From: SeventhSentinel Date: Wed, 2 Jan 2019 16:22:49 -0500 Subject: [PATCH 09/91] Minor issues --- src/p_mobj.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index cc5ba2379..887e3e171 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6525,7 +6525,7 @@ static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, mobjtype_t type, bool void P_RunBattleOvertime(void) { - UINT8 i, j; + UINT16 i, j; UINT16 orbs = 32; if (battleovertime.enabled < 5*TICRATE) @@ -6567,7 +6567,7 @@ void P_RunBattleOvertime(void) orbs = max(4, FixedDiv(battleovertime.radius, 16*mapheaderinfo[gamemap-1]->mobj_scale)>>FRACBITS); for (i = 0; i < orbs; i++) { - angle_t ang = FixedAngle(((360/orbs) * i * (FRACUNIT>>1)) + (((leveltime*2) % 360)< Date: Wed, 2 Jan 2019 19:32:23 -0500 Subject: [PATCH 10/91] New visual Will be replaced later regardless, but ah well --- src/info.c | 6 +++--- src/p_mobj.c | 20 ++++++++++++-------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/info.c b/src/info.c index 030e4c3ff..080148264 100644 --- a/src/info.c +++ b/src/info.c @@ -3395,8 +3395,8 @@ state_t states[NUMSTATES] = {SPR_FWRK, 4|FF_FULLBRIGHT, TICRATE, {NULL}, 0, 0, S_NULL}, // S_KARMAFIREWORKTRAIL {SPR_OTFG, FF_FULLBRIGHT|FF_TRANS50, TICRATE, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEFOG - {SPR_OTFG, 1|FF_FULLBRIGHT|FF_TRANS30|FF_PAPERSPRITE, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEORB - {SPR_OTFG, 3|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEBEAM + {SPR_OTFG, 2|FF_FULLBRIGHT|FF_PAPERSPRITE, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEORB + {SPR_OTFG, 1|FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_NULL}, // S_OVERTIMEBEAM #ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK @@ -20101,7 +20101,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 0, // speed 16<destscale = mo->scale/4; - if ((leveltime/2) & 1) - mo->frame++; + mo->frame += ((leveltime/4) % 8); if (battleovertime.enabled < 5*TICRATE) mo->flags2 |= MF2_SHADOW; mo->angle = R_PointToAngle2(mo->x, mo->y, battleovertime.x, battleovertime.y) + ANGLE_90; @@ -6526,7 +6525,7 @@ static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, mobjtype_t type, bool void P_RunBattleOvertime(void) { UINT16 i, j; - UINT16 orbs = 32; + UINT16 orbs = 16; if (battleovertime.enabled < 5*TICRATE) { @@ -6563,13 +6562,14 @@ void P_RunBattleOvertime(void) } } - // 32 orbs at the normal minimum size of 512 - orbs = max(4, FixedDiv(battleovertime.radius, 16*mapheaderinfo[gamemap-1]->mobj_scale)>>FRACBITS); + // 16 orbs at the normal minimum size of 512 + orbs = max(4, FixedDiv(battleovertime.radius, 32*mapheaderinfo[gamemap-1]->mobj_scale)>>FRACBITS); for (i = 0; i < orbs; i++) { - angle_t ang = FixedAngle(((((i+1) * 360) / orbs) + ((leveltime % 360) * 2))<mobj_scale + battleovertime.radius/1024; + fixed_t x = battleovertime.x + P_ReturnThrustX(NULL, ang, battleovertime.radius - FixedMul(mobjinfo[MT_OVERTIMEORB].radius, scale)); + fixed_t y = battleovertime.y + P_ReturnThrustY(NULL, ang, battleovertime.radius - FixedMul(mobjinfo[MT_OVERTIMEORB].radius, scale)); P_SpawnOvertimeParticles(x, y, MT_OVERTIMEORB, true); } @@ -9293,10 +9293,14 @@ void P_MobjThinker(mobj_t *mobj) if (battleovertime.enabled) { + mobj_t *ghost; fixed_t dist = min((4096*mapheaderinfo[gamemap-1]->mobj_scale - battleovertime.radius) / 2, 512*mapheaderinfo[gamemap-1]->mobj_scale); angle_t ang = FixedAngle((leveltime % 360) << FRACBITS); P_TeleportMove(mobj, battleovertime.x + P_ReturnThrustX(NULL, ang, dist), battleovertime.y + P_ReturnThrustY(NULL, ang, dist), battleovertime.z); + ghost = P_SpawnGhostMobj(mobj); + ghost->fuse = 4; + ghost->frame |= FF_FULLBRIGHT; } } else From ea9fc3c5a1bbd0c0ce086aa96f0fef6453bc5053 Mon Sep 17 00:00:00 2001 From: SeventhSentinel Date: Wed, 2 Jan 2019 19:37:01 -0500 Subject: [PATCH 11/91] Comment these out again --- src/doomdef.h | 2 +- src/p_inter.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 0791e07e9..a35f3291d 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -140,7 +140,7 @@ extern FILE *logstream; #endif -#define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable MD5 checking and stuff, all in one go. :3 +//#define DEVELOP // Disable this for release builds to remove excessive cheat commands and enable MD5 checking and stuff, all in one go. :3 #ifdef DEVELOP #define VERSION 0 // Game version #define SUBVERSION 0 // more precise version number diff --git a/src/p_inter.c b/src/p_inter.c index f6eb9db65..5902063f3 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1746,7 +1746,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } // Easily make it so that overtime works offline -#define TESTOVERTIMEINFREEPLAY +//#define TESTOVERTIMEINFREEPLAY /** Checks if the level timer is over the timelimit and the round should end, * unless you are in overtime. In which case leveltime may stretch out beyond From 02425bade6f60b2625304429d56127b4027c263b Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Tue, 8 Jan 2019 18:26:16 -0500 Subject: [PATCH 12/91] Double time for overtime to kick in, make barrier always completely visible --- src/k_kart.c | 4 ++-- src/p_mobj.c | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 077f1861c..a156f2a57 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4403,7 +4403,7 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) && !player->kartstuff[k_respawn] && !player->powers[pw_flashing]) { player->kartstuff[k_wanted]++; - if (battleovertime.enabled >= 5*TICRATE) + if (battleovertime.enabled >= 10*TICRATE) { if (P_AproxDistance(player->mo->x - battleovertime.x, player->mo->y - battleovertime.y) > battleovertime.radius) { @@ -7444,7 +7444,7 @@ static void K_drawKartMinimap(void) // Draw the super item in Battle if (G_BattleGametype() && battleovertime.enabled) { - if (battleovertime.enabled >= 5*TICRATE || (battleovertime.enabled & 1)) + if (battleovertime.enabled >= 10*TICRATE || (battleovertime.enabled & 1)) { const INT32 prevsplitflags = splitflags; splitflags &= ~V_HUDTRANSHALF; diff --git a/src/p_mobj.c b/src/p_mobj.c index 436339d2d..8c65d128a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6511,8 +6511,8 @@ static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, mobjtype_t type, bool case MT_OVERTIMEORB: //mo->destscale = mo->scale/4; mo->frame += ((leveltime/4) % 8); - if (battleovertime.enabled < 5*TICRATE) - mo->flags2 |= MF2_SHADOW; + /*if (battleovertime.enabled < 10*TICRATE) + mo->flags2 |= MF2_SHADOW;*/ mo->angle = R_PointToAngle2(mo->x, mo->y, battleovertime.x, battleovertime.y) + ANGLE_90; break; default: @@ -6527,12 +6527,12 @@ void P_RunBattleOvertime(void) UINT16 i, j; UINT16 orbs = 16; - if (battleovertime.enabled < 5*TICRATE) + if (battleovertime.enabled < 10*TICRATE) { battleovertime.enabled++; if (battleovertime.enabled == TICRATE) S_StartSound(NULL, sfx_bhurry); - if (battleovertime.enabled == 5*TICRATE) + if (battleovertime.enabled == 10*TICRATE) S_StartSound(NULL, sfx_kc40); } else @@ -6573,7 +6573,7 @@ void P_RunBattleOvertime(void) P_SpawnOvertimeParticles(x, y, MT_OVERTIMEORB, true); } - if (battleovertime.enabled < 5*TICRATE) + if (battleovertime.enabled < 10*TICRATE) return; /*if (!S_IdPlaying(sfx_s3kd4s)) // global ambience From c6c13bda6481362f84e95f149a658938d0b90ebe Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Tue, 8 Jan 2019 18:36:02 -0500 Subject: [PATCH 13/91] Use mapobjectscale --- src/p_inter.c | 4 ++-- src/p_mobj.c | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 0142981f8..3c0e3f927 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1841,8 +1841,8 @@ void P_CheckTimeLimit(void) battleovertime.x = item->x; battleovertime.y = item->y; battleovertime.z = item->z; - battleovertime.radius = 4096*mapheaderinfo[gamemap-1]->mobj_scale; - battleovertime.minradius = (cv_overtime.value == 2 ? 40 : 512)*mapheaderinfo[gamemap-1]->mobj_scale; + battleovertime.radius = 4096*mapobjectscale; + battleovertime.minradius = (cv_overtime.value == 2 ? 40 : 512) * mapobjectscale; battleovertime.enabled = 1; S_StartSound(NULL, sfx_kc47); } diff --git a/src/p_mobj.c b/src/p_mobj.c index 8c65d128a..afe4274b6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6417,7 +6417,7 @@ static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, mobjtype_t type, bool fixed_t flatz[MAXPLANESPERSECTOR]; UINT8 numflats = 0; mobj_t *mo; - fixed_t scale = mapheaderinfo[gamemap-1]->mobj_scale; + fixed_t scale = mapobjectscale; subsector_t *ss = R_IsPointInSubsector(x, y); sector_t *sec; @@ -6538,7 +6538,7 @@ void P_RunBattleOvertime(void) else { if (battleovertime.radius > battleovertime.minradius) - battleovertime.radius -= mapheaderinfo[gamemap-1]->mobj_scale; + battleovertime.radius -= mapobjectscale; else battleovertime.radius = battleovertime.minradius; } @@ -6563,11 +6563,11 @@ void P_RunBattleOvertime(void) } // 16 orbs at the normal minimum size of 512 - orbs = max(4, FixedDiv(battleovertime.radius, 32*mapheaderinfo[gamemap-1]->mobj_scale)>>FRACBITS); + orbs = max(4, FixedDiv(battleovertime.radius, 32*mapobjectscale)>>FRACBITS); for (i = 0; i < orbs; i++) { angle_t ang = FixedAngle(((((i+1) * 360) / orbs) - ((leveltime/2) % 360))<mobj_scale + battleovertime.radius/1024; + fixed_t scale = mapobjectscale + battleovertime.radius/1024; fixed_t x = battleovertime.x + P_ReturnThrustX(NULL, ang, battleovertime.radius - FixedMul(mobjinfo[MT_OVERTIMEORB].radius, scale)); fixed_t y = battleovertime.y + P_ReturnThrustY(NULL, ang, battleovertime.radius - FixedMul(mobjinfo[MT_OVERTIMEORB].radius, scale)); P_SpawnOvertimeParticles(x, y, MT_OVERTIMEORB, true); @@ -6577,7 +6577,7 @@ void P_RunBattleOvertime(void) return; /*if (!S_IdPlaying(sfx_s3kd4s)) // global ambience - S_StartSoundAtVolume(NULL, sfx_s3kd4s, min(255, ((4096*mapheaderinfo[gamemap-1]->mobj_scale) - battleovertime.radius)>>FRACBITS / 2));*/ + S_StartSoundAtVolume(NULL, sfx_s3kd4s, min(255, ((4096*mapobjectscale) - battleovertime.radius)>>FRACBITS / 2));*/ for (i = 0; i < 16; i++) { @@ -9294,7 +9294,7 @@ void P_MobjThinker(mobj_t *mobj) if (battleovertime.enabled) { mobj_t *ghost; - fixed_t dist = min((4096*mapheaderinfo[gamemap-1]->mobj_scale - battleovertime.radius) / 2, 512*mapheaderinfo[gamemap-1]->mobj_scale); + fixed_t dist = min((4096*mapobjectscale - battleovertime.radius) / 2, 512*mapobjectscale); angle_t ang = FixedAngle((leveltime % 360) << FRACBITS); P_TeleportMove(mobj, battleovertime.x + P_ReturnThrustX(NULL, ang, dist), battleovertime.y + P_ReturnThrustY(NULL, ang, dist), battleovertime.z); From 450e693c655ef7a2ce11c2ba0ccab8cd4986a376 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Tue, 8 Jan 2019 20:36:42 -0500 Subject: [PATCH 14/91] Extra improvements - The rainbow item now spawns in the middle before slowly expanding in radius. This keeps it anti-campy, but doesn't make it a pain in the ass to grab if it's being constantly picked up like intended. - Entirely remove the potential for holes in the barrier sprites - Flip particles that are attached to ceilings - More throughly check to make sure particles don't spawn in the skybox --- src/p_mobj.c | 90 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 61 insertions(+), 29 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index afe4274b6..ec20ad0df 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6411,13 +6411,13 @@ static void P_RemoveShadow(mobj_t *thing) // SAL'S KART BATTLE MODE OVERTIME HANDLER #define MAXPLANESPERSECTOR (MAXFFLOORS+1)*2 -static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, mobjtype_t type, boolean ceiling) +static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, fixed_t scale, mobjtype_t type, boolean ceiling) { UINT8 i; fixed_t flatz[MAXPLANESPERSECTOR]; + boolean flip[MAXPLANESPERSECTOR]; UINT8 numflats = 0; mobj_t *mo; - fixed_t scale = mapobjectscale; subsector_t *ss = R_IsPointInSubsector(x, y); sector_t *sec; @@ -6425,20 +6425,11 @@ static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, mobjtype_t type, bool return; sec = ss->sector; - switch(type) - { - case MT_OVERTIMEFOG: - scale *= 4; - break; - case MT_OVERTIMEORB: - scale += battleovertime.radius/1024; - break; - default: - break; - } - // convoluted stuff JUST to get all of the planes we need to draw orbs on :V + for (i = 0; i < MAXPLANESPERSECTOR; i++) + flip[i] = false; + if (sec->floorpic != skyflatnum) { #ifdef ESLOPE @@ -6455,6 +6446,7 @@ static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, mobjtype_t type, bool #else flatz[numflats] = (sec->ceilingheight) - FixedMul(mobjinfo[type].height, scale); #endif + flip[numflats] = true; numflats++; } @@ -6481,6 +6473,7 @@ static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, mobjtype_t type, bool #else flatz[numflats] = (*rover->bottomheight) - FixedMul(mobjinfo[type].height, scale); #endif + flip[numflats] = true; numflats++; } } @@ -6494,14 +6487,37 @@ static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, mobjtype_t type, bool mo = P_SpawnMobj(x, y, flatz[i], type); // Lastly, if this can see the skybox mobj, then... we just wasted our time :V - if (skyboxmo[0] && !P_MobjWasRemoved(skyboxmo[0]) && P_CheckSight(skyboxmo[0], mo)) + if (skyboxmo[0] && !P_MobjWasRemoved(skyboxmo[0])) { - P_RemoveMobj(mo); - continue; + const fixed_t sbz = skyboxmo[0]->z; + fixed_t checkz = sec->floorheight; + + while (checkz < sec->ceilingheight) + { + P_TeleportMove(skyboxmo[0], skyboxmo[0]->x, skyboxmo[0]->y, checkz); + if (P_CheckSight(skyboxmo[0], mo)) + { + P_RemoveMobj(mo); + break; + } + else + checkz += 32*mapobjectscale; + } + + P_TeleportMove(skyboxmo[0], skyboxmo[0]->x, skyboxmo[0]->y, sbz); + + if (P_MobjWasRemoved(mo)) + continue; } P_SetScale(mo, scale); + if (flip[i]) + { + mo->flags2 |= MF2_OBJECTFLIP; + mo->eflags |= MFE_VERTICALFLIP; + } + switch(type) { case MT_OVERTIMEFOG: @@ -6525,7 +6541,6 @@ static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, mobjtype_t type, bool void P_RunBattleOvertime(void) { UINT16 i, j; - UINT16 orbs = 16; if (battleovertime.enabled < 10*TICRATE) { @@ -6563,14 +6578,21 @@ void P_RunBattleOvertime(void) } // 16 orbs at the normal minimum size of 512 - orbs = max(4, FixedDiv(battleovertime.radius, 32*mapobjectscale)>>FRACBITS); - for (i = 0; i < orbs; i++) { - angle_t ang = FixedAngle(((((i+1) * 360) / orbs) - ((leveltime/2) % 360))<subsector->sector->floorheight) + z = mobj->subsector->sector->floorheight;*/ + + if (mobj->extravalue1 < 512) + mobj->extravalue1++; + dist = mobj->extravalue1 * mapobjectscale; + P_TeleportMove(mobj, battleovertime.x + P_ReturnThrustX(NULL, ang, dist), - battleovertime.y + P_ReturnThrustY(NULL, ang, dist), battleovertime.z); + battleovertime.y + P_ReturnThrustY(NULL, ang, dist), z); + ghost = P_SpawnGhostMobj(mobj); ghost->fuse = 4; ghost->frame |= FF_FULLBRIGHT; From 3246ca6b33e8562df46bb54cc12b115fb7b172b5 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Wed, 16 Jan 2019 14:49:42 -0500 Subject: [PATCH 15/91] More finished power level broken, can't finish --- src/d_clisrv.c | 117 +++++++++++++++++++++++--------------- src/d_clisrv.h | 1 + src/d_netcmd.c | 50 +++++++++++++++++ src/d_netcmd.h | 6 +- src/doomstat.h | 5 +- src/g_game.c | 12 ++-- src/k_kart.c | 111 +++++++++++++++++++++++++++++++++++- src/k_kart.h | 2 + src/m_menu.c | 24 ++++---- src/p_inter.c | 63 ++++++++++----------- src/p_saveg.c | 10 +++- src/p_setup.c | 5 +- src/p_spec.c | 4 -- src/y_inter.c | 149 ++++++++++++++++++++++++++++++++++++++++++------- 14 files changed, 428 insertions(+), 131 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 3dc641cdd..9c79d8ef6 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1461,7 +1461,7 @@ static void SV_SendPlayerInfo(INT32 node) */ static boolean SV_SendServerConfig(INT32 node) { - INT32 i; + INT32 i, j; UINT8 *p, *op; boolean waspacketsent; @@ -1485,9 +1485,15 @@ static boolean SV_SendServerConfig(INT32 node) memset(netbuffer->u.servercfg.adminplayers, -1, sizeof(netbuffer->u.servercfg.adminplayers)); + for (i = 0; i < MAXPLAYERS; i++) + for (j = 0; j < 2; j++) + netbuffer->u.servercfg.powerlevels[i][j] = 0; // Not sure if memset works on something like this + for (i = 0; i < MAXPLAYERS; i++) { netbuffer->u.servercfg.adminplayers[i] = (SINT8)adminplayers[i]; + for (j = 0; j < 2; j++) + netbuffer->u.servercfg.powerlevels[i][j] = clientpowerlevels[i][j]; if (!playeringame[i]) continue; @@ -2163,6 +2169,7 @@ static void CL_ConnectToServer(boolean viams) wipegamestate = GS_WAITINGPLAYERS; ClearAdminPlayers(); + ClearClientPowerLevels(); pnumnodes = 1; oldtic = I_GetTime() - 1; #ifndef NONET @@ -2971,6 +2978,21 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) break; } + // SRB2Kart: kicks count as forfeit + switch (kickreason) + { + case KR_KICK: + case KR_BAN: + case KR_LEAVE: + // Intentional removals should be hit with a true forfeit. + K_PlayerForfeit(pnum, true); + break; + default: + // Otherwise, give remaining players the point compensation, but doesn't penalize who left. + K_PlayerForfeit(pnum, false); + break; + } + if (playernode[pnum] == playernode[consoleplayer]) { #ifdef DUMPCONSISTENCY @@ -3145,6 +3167,7 @@ void SV_ResetServer(void) playernode[i] = UINT8_MAX; sprintf(player_names[i], "Player %d", i + 1); adminplayers[i] = -1; // Populate the entire adminplayers array with -1. + ClearClientPowerLevels(); } mynode = 0; @@ -3220,6 +3243,7 @@ void D_QuitNetGame(void) D_CloseConnection(); ClearAdminPlayers(); + ClearClientPowerLevels(); DEBFILE("===========================================================================\n" " Log finish\n" @@ -3247,8 +3271,7 @@ static inline void SV_AddNode(INT32 node) // Xcmd XD_ADDPLAYER static void Got_AddPlayer(UINT8 **p, INT32 playernum) { - INT16 node, newplayernum; - UINT8 splitscreenplayer = 0; + UINT8 node, newplayernum, splitscreenplayer; if (playernum != serverplayer && !IsPlayerAdmin(playernum)) { @@ -3265,11 +3288,12 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) return; } - node = READUINT8(*p); - newplayernum = READUINT8(*p); - splitscreenplayer = newplayernum/MAXPLAYERS; - newplayernum %= MAXPLAYERS; + node = (UINT8)READUINT8(*p); + newplayernum = (UINT8)READUINT8(*p); + splitscreenplayer = (UINT8)READUINT8(*p); + CONS_Printf("addplayer: %d %d %d\n", node, newplayernum, splitscreenplayer); + // Clear player before joining, lest some things get set incorrectly CL_ClearPlayer(newplayernum); @@ -3282,28 +3306,8 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) if (node == mynode) { playernode[newplayernum] = 0; // for information only - if (splitscreenplayer) - { - if (splitscreenplayer == 1) - { - secondarydisplayplayer = newplayernum; - DEBFILE("spawning my brother\n"); - if (botingame) - players[newplayernum].bot = 1; - // Same goes for player 2 when relevant - } - else if (splitscreenplayer == 2) - { - thirddisplayplayer = newplayernum; - DEBFILE("spawning my sister\n"); - } - else if (splitscreenplayer == 3) - { - fourthdisplayplayer = newplayernum; - DEBFILE("spawning my trusty pet dog\n"); - } - } - else + + if (splitscreenplayer == 0) { consoleplayer = newplayernum; displayplayer = newplayernum; @@ -3312,6 +3316,25 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) fourthdisplayplayer = newplayernum; DEBFILE("spawning me\n"); } + else if (splitscreenplayer == 1) + { + secondarydisplayplayer = newplayernum; + DEBFILE("spawning my brother\n"); + if (botingame) + players[newplayernum].bot = 1; + // Same goes for player 2 when relevant + } + else if (splitscreenplayer == 2) + { + thirddisplayplayer = newplayernum; + DEBFILE("spawning my sister\n"); + } + else if (splitscreenplayer == 3) + { + fourthdisplayplayer = newplayernum; + DEBFILE("spawning my trusty pet dog\n"); + } + D_SendPlayerConfig(); addedtogame = true; } @@ -3365,8 +3388,9 @@ static void Got_RemovePlayer(UINT8 **p, INT32 playernum) static boolean SV_AddWaitingPlayers(void) { INT32 node, n, newplayer = false; - XBOXSTATIC UINT8 buf[2]; UINT8 newplayernum = 0; + static UINT8 buf[3]; + static UINT8 *buf_p = buf; // What is the reason for this? Why can't newplayernum always be 0? // Sal: Because the dedicated player is stupidly forced into players[0]..... @@ -3385,8 +3409,10 @@ static boolean SV_AddWaitingPlayers(void) for (; newplayernum < MAXPLAYERS; newplayernum++) { for (n = 0; n < MAXNETNODES; n++) - if (nodetoplayer[n] == newplayernum || nodetoplayer2[n] == newplayernum - || nodetoplayer3[n] == newplayernum || nodetoplayer4[n] == newplayernum) + if (nodetoplayer[n] == newplayernum + || nodetoplayer2[n] == newplayernum + || nodetoplayer3[n] == newplayernum + || nodetoplayer4[n] == newplayernum) break; if (n == MAXNETNODES) break; @@ -3398,28 +3424,23 @@ static boolean SV_AddWaitingPlayers(void) playernode[newplayernum] = (UINT8)node; - buf[0] = (UINT8)node; - buf[1] = newplayernum; + WRITEUINT8(buf_p, (UINT8)node); + WRITEUINT8(buf_p, newplayernum); + if (playerpernode[node] < 1) nodetoplayer[node] = newplayernum; else if (playerpernode[node] < 2) - { nodetoplayer2[node] = newplayernum; - buf[1] += MAXPLAYERS; - } else if (playerpernode[node] < 3) - { nodetoplayer3[node] = newplayernum; - buf[1] += MAXPLAYERS*2; - } - else - { + else if (playerpernode[node] < 4) nodetoplayer4[node] = newplayernum; - buf[1] += MAXPLAYERS*3; - } + + WRITEUINT8(buf_p, playerpernode[node]); // splitscreen num + playerpernode[node]++; - SendNetXCmd(XD_ADDPLAYER, &buf, 2); + SendNetXCmd(XD_ADDPLAYER, buf, buf_p - buf); DEBFILE(va("Server added player %d node %d\n", newplayernum, node)); // use the next free slot (we can't put playeringame[newplayernum] = true here) @@ -3775,7 +3796,7 @@ static void HandlePacketFromAwayNode(SINT8 node) case PT_SERVERCFG: // Positive response of client join request { - INT32 j; + INT32 j, k; UINT8 *scp; if (server && serverrunning && node != servernode) @@ -3795,7 +3816,11 @@ static void HandlePacketFromAwayNode(SINT8 node) I_Error("Bad gametype in cliserv!"); modifiedgame = netbuffer->u.servercfg.modifiedgame; for (j = 0; j < MAXPLAYERS; j++) + { adminplayers[j] = netbuffer->u.servercfg.adminplayers[j]; + for (k = 0; k < 2; k++) + clientpowerlevels[j][k] = netbuffer->u.servercfg.powerlevels[j][k]; + } memcpy(server_context, netbuffer->u.servercfg.server_context, 8); } diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 5cf72bbc7..1c85144eb 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -328,6 +328,7 @@ typedef struct UINT8 gametype; UINT8 modifiedgame; SINT8 adminplayers[MAXPLAYERS]; // Needs to be signed + UINT16 powerlevels[MAXPLAYERS][2]; // SRB2kart: player power levels char server_context[8]; // Unique context id, generated at server startup. diff --git a/src/d_netcmd.c b/src/d_netcmd.c index e15ed9aac..4f42a6bef 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -61,6 +61,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum); static void Got_WeaponPref(UINT8 **cp, INT32 playernum); +static void Got_PowerLevel(UINT8 **cp, INT32 playernum); static void Got_Mapcmd(UINT8 **cp, INT32 playernum); static void Got_ExitLevelcmd(UINT8 **cp, INT32 playernum); static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum); @@ -455,6 +456,7 @@ boolean deferencoremode = false; UINT8 splitscreen = 0; boolean circuitmap = true; // SRB2kart INT32 adminplayers[MAXPLAYERS]; +UINT16 clientpowerlevels[MAXPLAYERS][2]; /// \warning Keep this up-to-date if you add/remove/rename net text commands const char *netxcmdnames[MAXNETXCMD - 1] = @@ -483,6 +485,8 @@ const char *netxcmdnames[MAXNETXCMD - 1] = "SETUPVOTE", "MODIFYVOTE", "PICKVOTE", + "REMOVEPLAYER", + "POWERLEVEL", #ifdef HAVE_BLUA "LUACMD", "LUAVAR" @@ -502,6 +506,7 @@ void D_RegisterServerCommands(void) { RegisterNetXCmd(XD_NAMEANDCOLOR, Got_NameAndColor); RegisterNetXCmd(XD_WEAPONPREF, Got_WeaponPref); + RegisterNetXCmd(XD_POWERLEVEL, Got_PowerLevel); RegisterNetXCmd(XD_MAP, Got_Mapcmd); RegisterNetXCmd(XD_EXITLEVEL, Got_ExitLevelcmd); RegisterNetXCmd(XD_ADDFILE, Got_Addfilecmd); @@ -1864,6 +1869,16 @@ static void Got_WeaponPref(UINT8 **cp,INT32 playernum) players[playernum].pflags |= PF_ANALOGMODE; } +static void Got_PowerLevel(UINT8 **cp,INT32 playernum) +{ + UINT16 race = (UINT16)READUINT16(*cp); + UINT16 battle = (UINT16)READUINT16(*cp); + + clientpowerlevels[playernum][0] = min(9999, race); + clientpowerlevels[playernum][1] = min(9999, battle); + CONS_Printf("set player %d to power %d\n", playernum, race); +} + void D_SendPlayerConfig(void) { SendNameAndColor(); @@ -1880,6 +1895,31 @@ void D_SendPlayerConfig(void) SendWeaponPref3(); if (splitscreen > 2) SendWeaponPref4(); + + { + UINT8 buf[4]; + UINT8 *buf_p = buf; + + WRITEUINT16(buf_p, vspowerlevel[0]); + WRITEUINT16(buf_p, vspowerlevel[1]); + + SendNetXCmd(XD_POWERLEVEL, buf, 4); + } + + if (splitscreen) + { + UINT8 buf[4]; + UINT8 *buf_p = buf; + + WRITEUINT16(buf_p, 0); + WRITEUINT16(buf_p, 0); + + SendNetXCmd2(XD_POWERLEVEL, buf, 4); + if (splitscreen > 1) + SendNetXCmd3(XD_POWERLEVEL, buf, 4); + if (splitscreen > 2) + SendNetXCmd4(XD_POWERLEVEL, buf, 4); + } } // Only works for displayplayer, sorry! @@ -3373,6 +3413,8 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) if (K_IsPlayerWanted(&players[playernum])) K_CalculateBattleWanted(); } + K_PlayerForfeit(playernum, true); + players[playernum].health = 1; if (players[playernum].mo) players[playernum].mo->health = 1; @@ -3521,6 +3563,14 @@ static void Got_Login(UINT8 **cp, INT32 playernum) #endif } +void ClearClientPowerLevels(void) +{ + INT32 i, j; + for (i = 0; i < MAXPLAYERS; i++) + for (j = 0; j < 2; j++) + clientpowerlevels[i][j] = 0; +} + boolean IsPlayerAdmin(INT32 playernum) { INT32 i; diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 7927aea00..22fc80da2 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -176,9 +176,10 @@ typedef enum XD_MODIFYVOTE, // 23 XD_PICKVOTE, // 24 XD_REMOVEPLAYER,// 25 + XD_POWERLEVEL, // 26 #ifdef HAVE_BLUA - XD_LUACMD, // 26 - XD_LUAVAR, // 27 + XD_LUACMD, // 27 + XD_LUAVAR, // 28 #endif MAXNETXCMD } netxcmd_t; @@ -237,6 +238,7 @@ void D_SetupVote(void); void D_ModifyClientVote(SINT8 voted, UINT8 splitplayer); void D_PickVote(void); void ObjectPlace_OnChange(void); +void ClearClientPowerLevels(void); boolean IsPlayerAdmin(INT32 playernum); void SetAdminPlayer(INT32 playernum); void ClearAdminPlayers(void); diff --git a/src/doomstat.h b/src/doomstat.h index 5831d4f47..4826e94fd 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -332,7 +332,7 @@ enum GameType // SRB2Kart extern tic_t totalplaytime; extern UINT32 matchesplayed; -extern UINT16 versusrecord[2]; +extern UINT16 vspowerlevel[2]; extern UINT8 stagefailed; @@ -467,7 +467,7 @@ extern SINT8 battlewanted[4]; extern tic_t wantedcalcdelay; extern tic_t indirectitemcooldown; extern tic_t mapreset; -extern UINT8 nospectategrief; +extern INT16 nospectategrief[MAXPLAYERS]; extern boolean thwompsactive; extern SINT8 spbplace; @@ -547,6 +547,7 @@ extern consvar_t cv_maxping; extern ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS]; extern INT32 serverplayer; extern INT32 adminplayers[MAXPLAYERS]; +extern UINT16 clientpowerlevels[MAXPLAYERS][2]; /// \note put these in d_clisrv outright? diff --git a/src/g_game.c b/src/g_game.c index 8292004a6..ec085914d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -169,7 +169,7 @@ INT32 sstimer; // Time allotted in the special stage tic_t totalplaytime; UINT32 matchesplayed; // SRB2Kart -UINT16 versusrecord[2]; // SRB2Kart: Online rankings +UINT16 vspowerlevel[2]; // SRB2Kart: Online rankings for each gametype boolean gamedataloaded = false; // Time attack data for levels @@ -267,7 +267,7 @@ SINT8 battlewanted[4]; // WANTED players in battle, worth x2 points tic_t wantedcalcdelay; // Time before it recalculates WANTED tic_t indirectitemcooldown; // Cooldown before any more Shrink, SPB, or any other item that works indirectly is awarded tic_t mapreset; // Map reset delay when enough players have joined an empty game -UINT8 nospectategrief; // How many players need to be in-game to eliminate last; for preventing spectate griefing +INT16 nospectategrief[MAXPLAYERS]; // Which players spec-scummed, and their power level before scumming. boolean thwompsactive; // Thwomps activate on lap 2 SINT8 spbplace; // SPB exists, give the person behind better items @@ -3782,8 +3782,8 @@ void G_LoadGameData(void) totalplaytime = 0; // total play time (separate from all) matchesplayed = 0; // SRB2Kart: matches played & finished - for (i = 0; i < 2; i++) // SRB2Kart: online VR system - versusrecord[i] = 5000; + for (i = 0; i < 2; i++) // SRB2Kart: online rank system + vspowerlevel[i] = 5000; if (M_CheckParm("-nodata")) return; // Don't load. @@ -3816,7 +3816,7 @@ void G_LoadGameData(void) matchesplayed = READUINT32(save_p); for (i = 0; i < 2; i++) - versusrecord[i] = READUINT16(save_p); + vspowerlevel[i] = READUINT16(save_p); modded = READUINT8(save_p); @@ -3967,7 +3967,7 @@ void G_SaveGameData(boolean force) WRITEUINT32(save_p, matchesplayed); for (i = 0; i < 2; i++) - WRITEUINT16(save_p, versusrecord[i]); + WRITEUINT16(save_p, vspowerlevel[i]); btemp = (UINT8)(savemoddata || modifiedgame); WRITEUINT8(save_p, btemp); diff --git a/src/k_kart.c b/src/k_kart.c index 476bff462..fdfdc4933 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -31,7 +31,7 @@ // battlewanted is an array of the WANTED player nums, -1 for no player in that slot // indirectitemcooldown is timer before anyone's allowed another Shrink/SPB // mapreset is set when enough players fill an empty server -// nospectategrief is the players in-game needed to eliminate the person in last +// nospectategrief is a list of griefers' power levels //{ SRB2kart Color Code @@ -5741,6 +5741,115 @@ void K_CheckBumpers(void) P_DoPlayerExit(&players[i]); } +// Adapted from this: http://wiki.tockdom.com/wiki/Player_Rating +INT16 K_CalculatePowerLevelInc(INT16 diff) +{ + INT16 control[10] = {0,0,0,1,8,50,125,125,125,125}; + fixed_t increment = 0; + fixed_t x; + UINT8 j; + +#define MAXDIFF 9998 + if (diff > MAXDIFF) + diff = MAXDIFF; + if (diff < -MAXDIFF) + diff = -MAXDIFF; +#undef MAXDIFF + + x = ((diff-2)<= (2<= (1<> FRACBITS); +} + +void K_PlayerForfeit(UINT8 playernum, boolean nopointloss) +{ + INT32 powertype = -1; + UINT16 yourpower = 5000; + UINT16 theirpower = 5000; + INT16 diff = 0; // Loser PWR.LV - Winner PWR.LV + INT16 inc = 0; + UINT8 i; + + // power level is netgames only + if (!netgame) + return; + + // 20 sec into the match counts as a forfeit -- automatic loss against every other player in the match. + if (gamestate != GS_LEVEL || leveltime <= starttime+(20*TICRATE)) + return; + + if (G_RaceGametype()) + powertype = 0; + else if (G_BattleGametype()) + powertype = 1; + + if (powertype == -1) // Not using power levels + return; + + if (clientpowerlevels[playernum][powertype] == 0) // splitscreen guests don't record power level changes + return; + yourpower = clientpowerlevels[playernum][powertype]; + + // Set up the point compensation. + nospectategrief[playernum] = yourpower; + + if (nopointloss) // This is set for stuff like sync-outs, which shouldn't be so harsh on the victim! + return; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (i == playernum) + continue; + + theirpower = 5000; + if (clientpowerlevels[i][powertype] != 0) // No power level acts as 5000 (used for splitscreen guests) + theirpower = clientpowerlevels[i][powertype]; + + diff = yourpower - theirpower; + inc -= K_CalculatePowerLevelInc(diff); + } + + if (inc == 0) // No change. + return; + + if (yourpower + inc > 9999) // I mean... we're subtracting... but y'know how it is :V + inc -= ((yourpower + inc) - 9999); + if (yourpower + inc < 1) + inc -= ((yourpower + inc) - 1); + + clientpowerlevels[playernum][powertype] += inc; + + if (playernum == consoleplayer) + { + vspowerlevel[powertype] = clientpowerlevels[playernum][powertype]; + if (M_UpdateUnlockablesAndExtraEmblems(true)) + S_StartSound(NULL, sfx_ncitem); + G_SaveGameData(true); // save your punishment! + } +} + void K_CheckSpectateStatus(void) { UINT8 respawnlist[MAXPLAYERS]; diff --git a/src/k_kart.h b/src/k_kart.h index 3f7120913..ce5203675 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -63,6 +63,8 @@ fixed_t K_3dKartMovement(player_t *player, boolean onground, fixed_t forwardmove void K_MoveKartPlayer(player_t *player, boolean onground); void K_CalculateBattleWanted(void); void K_CheckBumpers(void); +INT16 K_CalculatePowerLevelInc(INT16 diff); +void K_PlayerForfeit(UINT8 playernum, boolean nopointloss); void K_CheckSpectateStatus(void); const char *K_GetItemPatch(UINT8 item, boolean tiny); diff --git a/src/m_menu.c b/src/m_menu.c index a8c5ad486..bcbc6cb78 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6252,7 +6252,7 @@ static void M_Statistics(INT32 choice) static void M_DrawStatsMaps(int location) { - INT32 y = 80, i = -1; + INT32 y = 88, i = -1; INT16 mnum; extraemblem_t *exemblem; boolean dotopname = true, dobottomarrow = (location < statsMax); @@ -6365,11 +6365,9 @@ static void M_DrawLevelStats(void) V_DrawString(20, 42, highlightflags, "Total Matches:"); V_DrawRightAlignedString(BASEVIDWIDTH-16, 42, 0, va("%i played", matchesplayed)); - V_DrawString(20, 50, highlightflags, "Race Versus Record:"); - V_DrawRightAlignedString(BASEVIDWIDTH-16, 50, 0, va("%i", versusrecord[0])); - - V_DrawString(20, 58, highlightflags, "Battle Versus Record:"); - V_DrawRightAlignedString(BASEVIDWIDTH-16, 58, 0, va("%i", versusrecord[1])); + V_DrawString(20, 52, highlightflags, "Online Power Level:"); + V_DrawRightAlignedString(BASEVIDWIDTH-16, 52, 0, va("Race: %i", vspowerlevel[0])); + V_DrawRightAlignedString(BASEVIDWIDTH-16, 60, 0, va("Battle: %i", vspowerlevel[1])); for (i = 0; i < NUMMAPS; i++) { @@ -6385,18 +6383,18 @@ static void M_DrawLevelStats(void) besttime += mainrecords[i]->time; } - V_DrawString(20, 62, highlightflags, "Combined time records:"); + V_DrawString(20, 70, highlightflags, "Combined time records:"); sprintf(beststr, "%i:%02i:%02i.%02i", G_TicsToHours(besttime), G_TicsToMinutes(besttime, false), G_TicsToSeconds(besttime), G_TicsToCentiseconds(besttime)); - V_DrawRightAlignedString(BASEVIDWIDTH-16, 62, (mapsunfinished ? warningflags : 0), beststr); + V_DrawRightAlignedString(BASEVIDWIDTH-16, 70, (mapsunfinished ? warningflags : 0), beststr); if (mapsunfinished) - V_DrawRightAlignedString(BASEVIDWIDTH-16, 70, warningflags, va("(%d unfinished)", mapsunfinished)); + V_DrawRightAlignedString(BASEVIDWIDTH-16, 78, warningflags, va("(%d unfinished)", mapsunfinished)); else - V_DrawRightAlignedString(BASEVIDWIDTH-16, 70, recommendedflags, "(complete)"); + V_DrawRightAlignedString(BASEVIDWIDTH-16, 78, recommendedflags, "(complete)"); - V_DrawString(32, 70, 0, va("x %d/%d", M_CountEmblems(), numemblems+numextraemblems)); - V_DrawSmallScaledPatch(20, 70, 0, W_CachePatchName("GOTITA", PU_STATIC)); + V_DrawString(32, 78, V_ALLOWLOWERCASE, va("x %d/%d", M_CountEmblems(), numemblems+numextraemblems)); + V_DrawSmallScaledPatch(20, 78, 0, W_CachePatchName("GOTITA", PU_STATIC)); M_DrawStatsMaps(statsLocation); } @@ -8515,7 +8513,7 @@ static void M_EraseDataResponse(INT32 ch) totalplaytime = 0; matchesplayed = 0; for (i = 0; i < 2; i++) - versusrecord[i] = 5000; + vspowerlevel[i] = 5000; F_StartIntro(); } if (erasecontext != 1) diff --git a/src/p_inter.c b/src/p_inter.c index dd27858fc..a4f1fe84b 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2010,7 +2010,8 @@ void P_CheckPointLimit(void) // Checks whether or not to end a race netgame. boolean P_CheckRacers(void) { - INT32 i, j, numplayersingame = 0; + INT32 i, j, numplayersingame = 0, numexiting = 0; + boolean griefed = false; // Check if all the players in the race have finished. If so, end the level. for (i = 0; i < MAXPLAYERS; i++) @@ -2027,57 +2028,53 @@ boolean P_CheckRacers(void) return true; } - if (cv_karteliminatelast.value) + for (j = 0; j < MAXPLAYERS; j++) { - for (j = 0; j < MAXPLAYERS; j++) + if (nospectategrief[j] != -1) // prevent spectate griefing + griefed = true; + if (!playeringame[j] || players[j].spectator) + continue; + numplayersingame++; + if (players[j].exiting) + numexiting++; + } + + if (cv_karteliminatelast.value && numplayersingame > 1 && !griefed) + { + // check if we just got unlucky and there was only one guy who was a problem + for (j = i+1; j < MAXPLAYERS; j++) { - if (!playeringame[j] || players[j].spectator) + if (!playeringame[j] || players[j].spectator || players[j].exiting || !players[j].lives) continue; - numplayersingame++; + break; } - if (numplayersingame > 1 && nospectategrief > 0 && numplayersingame >= nospectategrief) // prevent spectate griefing + if (j == MAXPLAYERS) // finish anyways, force a time over { - // check if we just got unlucky and there was only one guy who was a problem - for (j = i+1; j < MAXPLAYERS; j++) - { - if (!playeringame[j] || players[j].spectator || players[j].exiting || !players[j].lives) - continue; - - break; - } - - if (j == MAXPLAYERS) // finish anyways, force a time over - { - P_DoTimeOver(&players[i]); - countdown = countdown2 = 0; - return true; - } + P_DoTimeOver(&players[i]); + countdown = countdown2 = 0; + return true; } } if (!countdown) // Check to see if the winners have finished, to set countdown. { - UINT8 numingame = 0, numexiting = 0; UINT8 winningpos = 1; - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator) - continue; - numingame++; - if (players[i].exiting) - numexiting++; - } - - winningpos = max(1, numingame/2); - if (numingame % 2) // any remainder? + winningpos = max(1, numplayersingame/2); + if (numplayersingame % 2) // any remainder? winningpos++; if (numexiting >= winningpos) countdown = (((netgame || multiplayer) ? cv_countdowntime.value : 30)*TICRATE) + 1; // 30 seconds to finish, get going! } + if (numplayersingame < 2) // reset nospectategrief in free play + { + for (j = 0; j < MAXPLAYERS; j++) + nospectategrief[j] = -1; + } + return false; } diff --git a/src/p_saveg.c b/src/p_saveg.c index 975a4a5d2..075b2ccb2 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3314,7 +3314,10 @@ static void P_NetArchiveMisc(void) WRITEUINT32(save_p, wantedcalcdelay); WRITEUINT32(save_p, indirectitemcooldown); WRITEUINT32(save_p, mapreset); - WRITEUINT8(save_p, nospectategrief); + + for (i = 0; i < MAXPLAYERS; i++) + WRITEINT16(save_p, nospectategrief[i]); + WRITEUINT8(save_p, thwompsactive); WRITESINT8(save_p, spbplace); @@ -3422,7 +3425,10 @@ static inline boolean P_NetUnArchiveMisc(void) wantedcalcdelay = READUINT32(save_p); indirectitemcooldown = READUINT32(save_p); mapreset = READUINT32(save_p); - nospectategrief = READUINT8(save_p); + + for (i = 0; i < MAXPLAYERS; i++) + nospectategrief[i] = READINT16(save_p); + thwompsactive = (boolean)READUINT8(save_p); spbplace = READSINT8(save_p); diff --git a/src/p_setup.c b/src/p_setup.c index 49b22184e..d1c0b1092 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -3242,7 +3242,10 @@ boolean P_SetupLevel(boolean skipprecip) wantedcalcdelay = wantedfrequency*2; indirectitemcooldown = 0; mapreset = 0; - nospectategrief = 0; + + for (i = 0; i < MAXPLAYERS; i++) + nospectategrief[i] = -1; + thwompsactive = false; spbplace = -1; diff --git a/src/p_spec.c b/src/p_spec.c index ca4967ce3..a11cc5c44 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -4278,10 +4278,6 @@ DoneSection2: // Play the starpost sound for 'consistency' // S_StartSound(player->mo, sfx_strpst); - // Figure out how many are playing on the last lap, to prevent spectate griefing - if (!nospectategrief && player->laps >= (UINT8)(cv_numlaps.value - 1)) - nospectategrief = nump; - thwompsactive = true; // Lap 2 effects } else if (player->starpostnum) diff --git a/src/y_inter.c b/src/y_inter.c index 021519e3b..8000fd2b1 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -89,7 +89,7 @@ typedef union INT32 numplayers; // Number of players being displayed char levelstring[64]; // holds levelnames up to 64 characters // SRB2kart - UINT8 increase[MAXPLAYERS]; // how much did the score increase by? + INT16 increase[MAXPLAYERS]; // how much did the score increase by? UINT8 jitter[MAXPLAYERS]; // wiggle UINT32 val[MAXPLAYERS]; // Gametype-specific value UINT8 pos[MAXPLAYERS]; // player positions. used for ties @@ -109,6 +109,7 @@ static boolean usetile; boolean usebuffer = false; static boolean useinterpic; static INT32 timer; +static INT32 powertype = 0; static INT32 intertic; static INT32 endtic = -1; @@ -192,11 +193,16 @@ static void Y_CompareBattle(INT32 i) static void Y_CompareRank(INT32 i) { - UINT8 increase = ((data.match.increase[i] == UINT8_MAX) ? 0 : data.match.increase[i]); - if (!(data.match.val[data.match.numplayers] == UINT32_MAX || (players[i].score - increase) > data.match.val[data.match.numplayers])) + INT16 increase = ((data.match.increase[i] == INT16_MIN) ? 0 : data.match.increase[i]); + UINT32 score = (powertype != -1 ? clientpowerlevels[i][powertype] : players[i].score); + + if (!(data.match.val[data.match.numplayers] == UINT32_MAX)) return; - data.match.val[data.match.numplayers] = (players[i].score - increase); + if (powertype == -1 && (players[i].score - increase) > data.match.val[data.match.numplayers]) + return; + + data.match.val[data.match.numplayers] = (score - increase); data.match.num[data.match.numplayers] = i; } @@ -204,7 +210,7 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32)) { INT32 i, j; boolean completed[MAXPLAYERS]; - INT32 numplayersingame = 0; + INT32 numplayersingame = 0, numgriefers = 0; // Initialize variables if (rankingsmode > 1) @@ -256,14 +262,17 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32)) { data.match.val[i] = UINT32_MAX; + if (nospectategrief[i] != -1) + numgriefers++; + if (!playeringame[i] || players[i].spectator) { - data.match.increase[i] = UINT8_MAX; + data.match.increase[i] = INT16_MIN; continue; } if (!rankingsmode) - data.match.increase[i] = UINT8_MAX; + data.match.increase[i] = INT16_MIN; numplayersingame++; } @@ -275,8 +284,6 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32)) for (j = 0; j < numplayersingame; j++) { - INT32 nump = ((G_RaceGametype() && nospectategrief > 0) ? nospectategrief : numplayersingame); - for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i] || players[i].spectator || completed[i]) @@ -298,14 +305,98 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32)) else data.match.pos[data.match.numplayers] = data.match.numplayers+1; - if (!rankingsmode && !(players[i].pflags & PF_TIMEOVER) && (data.match.pos[data.match.numplayers] < nump)) + if ((!rankingsmode && powertype == -1) // Single player rankings (grand prix). Online rank is handled below. + && !(players[i].pflags & PF_TIMEOVER) && (data.match.pos[data.match.numplayers] < (numplayersingame + numgriefers))) { - data.match.increase[i] = nump - data.match.pos[data.match.numplayers]; + data.match.increase[i] = (numplayersingame + numgriefers) - data.match.pos[data.match.numplayers]; players[i].score += data.match.increase[i]; } data.match.numplayers++; } + + // Compare every single player against each other for power level increases. + // Every player you won against gives you more points, and vice versa. + // The amount of points won per match-up depends on the difference between the loser's power and the winner's power. + // See K_CalculatePowerLevelInc for more info. + // (I'm bad at understanding this code, so I had no idea how to incorporate it with the above loop properly.) + + if (!rankingsmode && powertype != -1) + { + for (i = 0; i < data.match.numplayers; i++) + { + UINT16 yourpower = 5000; + UINT16 theirpower = 5000; + INT16 diff = 0; // Loser PWR.LV - Winner PWR.LV + INT16 inc = 0; // Total pt increment + + if (clientpowerlevels[i][powertype] == 0) // splitscreen guests don't record power level changes + continue; + yourpower = clientpowerlevels[i][powertype]; + + for (j = 0; j < data.match.numplayers; j++) + { + if (i == j || data.match.pos[i] == data.match.pos[j]) // Tie -- neither get any points for this match up. + continue; + + theirpower = 5000; + if (clientpowerlevels[j][powertype] != 0) // No power level acts as 5000 (used for splitscreen guests) + theirpower = clientpowerlevels[j][powertype]; + + if (data.match.pos[i] > data.match.pos[j]) // This player won! + { + diff = theirpower - yourpower; + inc += K_CalculatePowerLevelInc(diff); + } + else if (data.match.pos[i] < data.match.pos[j]) // This player lost... + { + diff = yourpower - theirpower; + inc -= K_CalculatePowerLevelInc(diff); + } + } + + if (numgriefers != 0) // Automatic win against quitters. + { + for (j = 0; j < MAXPLAYERS; j++) + { + if (nospectategrief[j] == -1) // Empty slot + continue; + + if (i == j) // Yourself?? + continue; + + theirpower = 5000; + if (nospectategrief[j] != 0) // No power level acts as 5000 (used for splitscreen guests) + theirpower = nospectategrief[j]; + + diff = theirpower - yourpower; + inc += K_CalculatePowerLevelInc(diff); + } + } + + if (inc == 0) + { + data.match.increase[i] = INT16_MIN; + continue; + } + + if (yourpower + inc > 9999) + inc -= ((yourpower + inc) - 9999); + if (yourpower + inc < 1) + inc -= ((yourpower + inc) - 1); + + data.match.increase[i] = inc; + clientpowerlevels[i][powertype] += data.match.increase[i]; + + if (i == consoleplayer) + { + vspowerlevel[powertype] = clientpowerlevels[i][powertype]; + if (M_UpdateUnlockablesAndExtraEmblems(true)) + S_StartSound(NULL, sfx_ncitem); + G_SaveGameData(true); + } + } + } } // @@ -421,7 +512,7 @@ void Y_IntermissionDrawer(void) const char *timeheader; if (data.match.rankingsmode) - timeheader = "RANK"; + timeheader = "PWR.LV"; else timeheader = (intertype == int_race ? "TIME" : "SCORE"); @@ -487,18 +578,23 @@ void Y_IntermissionDrawer(void) if (data.match.rankingsmode) { - if (data.match.increase[data.match.num[i]] != UINT8_MAX) + if (!clientpowerlevels[i][powertype]) // No power level (splitscreen guests) + STRBUFCPY(strtime, "----"); + else { - if (data.match.increase[data.match.num[i]] > 9) - snprintf(strtime, sizeof strtime, "(+%02d)", data.match.increase[data.match.num[i]]); - else - snprintf(strtime, sizeof strtime, "(+ %d)", data.match.increase[data.match.num[i]]); + if (data.match.increase[data.match.num[i]] != INT16_MIN) + { + if (data.match.increase[data.match.num[i]] > 9) + snprintf(strtime, sizeof strtime, "(+%02d)", data.match.increase[data.match.num[i]]); + else + snprintf(strtime, sizeof strtime, "(+ %d)", data.match.increase[data.match.num[i]]); - V_DrawRightAlignedString(x+120+gutter, y, 0, strtime); + V_DrawRightAlignedString(x+118+gutter, y, 0, strtime); + } + + snprintf(strtime, sizeof strtime, "%d", data.match.val[i]); } - snprintf(strtime, sizeof strtime, "%d", data.match.val[i]); - V_DrawRightAlignedString(x+152+gutter, y, 0, strtime); } else @@ -617,7 +713,7 @@ void Y_Ticker(void) { if (data.match.num[q] == MAXPLAYERS || !data.match.increase[data.match.num[q]] - || data.match.increase[data.match.num[q]] == UINT8_MAX) + || data.match.increase[data.match.num[q]] == INT16_MIN) continue; r++; @@ -737,6 +833,17 @@ void Y_StartIntermission(void) I_Error("endtic is dirty"); #endif + // set player Power Level type + powertype = -1; + + if (netgame) + { + if (G_RaceGametype()) + powertype = 0; + else if (G_BattleGametype()) + powertype = 1; + } + if (!multiplayer) { timer = 0; From a5f23091cc2ebc6984d5e769a9b95245c404913d Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Wed, 16 Jan 2019 16:13:34 -0500 Subject: [PATCH 16/91] Fix buffer overwrite & increment --- src/d_clisrv.c | 5 +++-- src/y_inter.c | 12 ++++++++++-- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 9c79d8ef6..24ec5137e 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3389,8 +3389,6 @@ static boolean SV_AddWaitingPlayers(void) { INT32 node, n, newplayer = false; UINT8 newplayernum = 0; - static UINT8 buf[3]; - static UINT8 *buf_p = buf; // What is the reason for this? Why can't newplayernum always be 0? // Sal: Because the dedicated player is stupidly forced into players[0]..... @@ -3402,6 +3400,9 @@ static boolean SV_AddWaitingPlayers(void) // splitscreen can allow 2+ players in one node for (; nodewaiting[node] > 0; nodewaiting[node]--) { + UINT8 buf[3]; + UINT8 *buf_p = buf; + newplayer = true; // search for a free playernum diff --git a/src/y_inter.c b/src/y_inter.c index 8000fd2b1..3cca4f7fc 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -718,8 +718,16 @@ void Y_Ticker(void) r++; data.match.jitter[data.match.num[q]] = 1; - if (--data.match.increase[data.match.num[q]]) - kaching = false; + if (data.match.increase[data.match.num[q]] > 0) + { + if (--data.match.increase[data.match.num[q]]) + kaching = false; + } + else if (data.match.increase[data.match.num[q]] < 0) + { + if (++data.match.increase[data.match.num[q]]) + kaching = false; + } } if (r) From 88af2ff3bc67ed9a82f01330de2cb0c252d9ed8e Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 17 Jan 2019 01:28:11 -0500 Subject: [PATCH 17/91] Use val instead of pos? Let's see if this fixes it... --- src/g_game.c | 2 +- src/y_inter.c | 19 ++++++++++++++++--- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 0c9f7c911..b63af6c51 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -64,7 +64,7 @@ JoyType_t Joystick4; #define SAVEGAMESIZE (1024) // SRB2kart -char gamedatafilename[64] = "kartdata.dat"; +char gamedatafilename[64] = "vr.dat"; char timeattackfolder[64] = "kart"; char customversionstring[32] = "\0"; diff --git a/src/y_inter.c b/src/y_inter.c index 53be9893c..b617db274 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -336,22 +336,35 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32)) for (j = 0; j < numplayersingame; j++) { + boolean won = false; + if (i == j) // Same person continue; - if (data.match.pos[i] == data.match.pos[j]) // Tie -- neither get any points for this match up. + if (data.match.val[i] == data.match.val[j]) // Tie -- neither get any points for this match up. continue; theirpower = 5000; if (clientpowerlevels[j][powertype] != 0) // No power level acts as 5000 (used for splitscreen guests) theirpower = clientpowerlevels[j][powertype]; - if (data.match.pos[i] < data.match.pos[j]) // This player won! + if (G_RaceGametype()) + { + if (data.match.val[i] < data.match.val[j]) + won = true; + } + else + { + if (data.match.val[i] > data.match.val[j]) + won = true; + } + + if (won) // This player won! { diff = theirpower - yourpower; inc += K_CalculatePowerLevelInc(diff); } - else if (data.match.pos[i] > data.match.pos[j]) // This player lost... + else // This player lost... { diff = yourpower - theirpower; inc -= K_CalculatePowerLevelInc(diff); From a55fb0729d3f869a909f13da4e0406f04704b6aa Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 17 Jan 2019 22:39:26 -0500 Subject: [PATCH 18/91] Improvements to power level updating & forfeit handling --- src/k_kart.c | 14 +++- src/y_inter.c | 198 +++++++++++++++++++++++++++++++------------------- 2 files changed, 135 insertions(+), 77 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index f1542e958..7ea2fd0b0 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5783,8 +5783,9 @@ INT16 K_CalculatePowerLevelInc(INT16 diff) return (INT16)(increment >> FRACBITS); } -void K_PlayerForfeit(UINT8 playernum, boolean nopointloss) +void K_PlayerForfeit(UINT8 playernum, boolean pointloss) { + UINT8 p = 0; INT32 powertype = -1; UINT16 yourpower = 5000; UINT16 theirpower = 5000; @@ -5800,6 +5801,15 @@ void K_PlayerForfeit(UINT8 playernum, boolean nopointloss) if (gamestate != GS_LEVEL || leveltime <= starttime+(20*TICRATE)) return; + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] && !players[i].spectator) + p++; + } + + if (p < 2) // no players + return; + if (G_RaceGametype()) powertype = 0; else if (G_BattleGametype()) @@ -5815,7 +5825,7 @@ void K_PlayerForfeit(UINT8 playernum, boolean nopointloss) // Set up the point compensation. nospectategrief[playernum] = yourpower; - if (nopointloss) // This is set for stuff like sync-outs, which shouldn't be so harsh on the victim! + if (!pointloss) // This is set for stuff like sync-outs, which shouldn't be so harsh on the victim! return; for (i = 0; i < MAXPLAYERS; i++) diff --git a/src/y_inter.c b/src/y_inter.c index b617db274..0bbb04b14 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -196,10 +196,7 @@ static void Y_CompareRank(INT32 i) INT16 increase = ((data.match.increase[i] == INT16_MIN) ? 0 : data.match.increase[i]); UINT32 score = (powertype != -1 ? clientpowerlevels[i][powertype] : players[i].score); - if (!(data.match.val[data.match.numplayers] == UINT32_MAX)) - return; - - if (powertype == -1 && (players[i].score - increase) > data.match.val[data.match.numplayers]) + if (!(data.match.val[data.match.numplayers] == UINT32_MAX || (score - increase) > data.match.val[data.match.numplayers])) return; data.match.val[data.match.numplayers] = (score - increase); @@ -314,103 +311,151 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32)) data.match.numplayers++; } +} + +static void Y_UpdatePowerLevels(void) +{ + INT32 i, j; + INT32 numplayersingame = 0, numgriefers = 0; + INT16 increment[MAXPLAYERS]; // Compare every single player against each other for power level increases. // Every player you won against gives you more points, and vice versa. // The amount of points won per match-up depends on the difference between the loser's power and the winner's power. // See K_CalculatePowerLevelInc for more info. - // (I'm bad at understanding this code, so I had no idea how to incorporate it with the above loop properly.) - if (!rankingsmode && powertype != -1) + for (i = 0; i < MAXPLAYERS; i++) { - for (i = 0; i < numplayersingame; i++) + increment[i] = 0; + + if (nospectategrief[i] != -1) + numgriefers++; + + if (!playeringame[i] || players[i].spectator) + continue; + + numplayersingame++; + } + + for (i = 0; i < numplayersingame; i++) + { + UINT16 yourpower = 5000; + UINT16 theirpower = 5000; + INT16 diff = 0; // Loser PWR.LV - Winner PWR.LV + INT16 inc = 0; // Total pt increment + UINT8 ipnum = data.match.num[i]; + UINT8 jpnum; + + CONS_Printf("Power Level Gain for player %d:\n", ipnum); + + if (clientpowerlevels[ipnum][powertype] == 0) // splitscreen guests don't record power level changes + continue; + yourpower = clientpowerlevels[ipnum][powertype]; + + CONS_Printf("Player %d's PWR.LV: %d\n", ipnum, yourpower); + + for (j = 0; j < numplayersingame; j++) { - UINT16 yourpower = 5000; - UINT16 theirpower = 5000; - INT16 diff = 0; // Loser PWR.LV - Winner PWR.LV - INT16 inc = 0; // Total pt increment + boolean won = false; - if (clientpowerlevels[i][powertype] == 0) // splitscreen guests don't record power level changes + jpnum = data.match.num[j]; + + if (i == j || ipnum == jpnum) // Same person continue; - yourpower = clientpowerlevels[i][powertype]; - for (j = 0; j < numplayersingame; j++) + CONS_Printf("Player %d VS Player %d:\n", ipnum, jpnum); + + if (data.match.val[i] == data.match.val[j]) // Tie -- neither get any points for this match up. { - boolean won = false; + CONS_Printf("TIE, no change.\n"); + continue; + } - if (i == j) // Same person + theirpower = 5000; + if (clientpowerlevels[jpnum][powertype] != 0) // No power level acts as 5000 (used for splitscreen guests) + theirpower = clientpowerlevels[jpnum][powertype]; + CONS_Printf("Player %d's PWR.LV: %d\n", jpnum, theirpower); + + if (G_RaceGametype()) + { + if (data.match.val[i] < data.match.val[j]) + won = true; + } + else + { + if (data.match.val[i] > data.match.val[j]) + won = true; + } + + if (won) // This player won! + { + diff = theirpower - yourpower; + inc += K_CalculatePowerLevelInc(diff); + CONS_Printf("WON! Diff is %d, total increment is %d\n", diff, inc); + } + else // This player lost... + { + diff = yourpower - theirpower; + inc -= K_CalculatePowerLevelInc(diff); + CONS_Printf("LOST... Diff is %d, total increment is %d\n", diff, inc); + } + } + + if (numgriefers != 0) // Automatic win against quitters. + { + for (jpnum = 0; jpnum < MAXPLAYERS; jpnum++) + { + if (nospectategrief[jpnum] == -1) // Empty slot continue; - if (data.match.val[i] == data.match.val[j]) // Tie -- neither get any points for this match up. + if (ipnum == jpnum) // Same person continue; + CONS_Printf("Player %d VS Player %d (griefer):\n", ipnum, jpnum); + theirpower = 5000; - if (clientpowerlevels[j][powertype] != 0) // No power level acts as 5000 (used for splitscreen guests) - theirpower = clientpowerlevels[j][powertype]; + if (nospectategrief[jpnum] != 0) // No power level acts as 5000 (used for splitscreen guests) + theirpower = nospectategrief[jpnum]; + CONS_Printf("Player %d's PWR.LV: %d\n", jpnum, theirpower); - if (G_RaceGametype()) - { - if (data.match.val[i] < data.match.val[j]) - won = true; - } - else - { - if (data.match.val[i] > data.match.val[j]) - won = true; - } - - if (won) // This player won! - { - diff = theirpower - yourpower; - inc += K_CalculatePowerLevelInc(diff); - } - else // This player lost... - { - diff = yourpower - theirpower; - inc -= K_CalculatePowerLevelInc(diff); - } + diff = theirpower - yourpower; + inc += K_CalculatePowerLevelInc(diff); + CONS_Printf("AUTO-WON! Diff is %d, total increment is %d\n", diff, inc); } + } - if (numgriefers != 0) // Automatic win against quitters. - { - for (j = 0; j < MAXPLAYERS; j++) - { - if (nospectategrief[j] == -1) // Empty slot - continue; + if (inc == 0) + { + data.match.increase[ipnum] = INT16_MIN; + CONS_Printf("Total Result: No increment, no change.\n"); + continue; + } - if (i == j) // Yourself?? - continue; + if (yourpower + inc > 9999) + inc -= ((yourpower + inc) - 9999); + if (yourpower + inc < 1) + inc -= ((yourpower + inc) - 1); - theirpower = 5000; - if (nospectategrief[j] != 0) // No power level acts as 5000 (used for splitscreen guests) - theirpower = nospectategrief[j]; + CONS_Printf("Total Result: Increment of %d.\n", inc); + increment[ipnum] = inc; + } - diff = theirpower - yourpower; - inc += K_CalculatePowerLevelInc(diff); - } - } + CONS_Printf("Setting final power levels...\n", inc); + for (i = 0; i < MAXPLAYERS; i++) + { + if (increment[i] == 0) + continue; - if (inc == 0) - { - data.match.increase[i] = INT16_MIN; - continue; - } + data.match.increase[i] = increment[i]; + clientpowerlevels[i][powertype] += data.match.increase[i]; - if (yourpower + inc > 9999) - inc -= ((yourpower + inc) - 9999); - if (yourpower + inc < 1) - inc -= ((yourpower + inc) - 1); - - data.match.increase[i] = inc; - clientpowerlevels[i][powertype] += data.match.increase[i]; - - if (i == consoleplayer) - { - vspowerlevel[powertype] = clientpowerlevels[i][powertype]; - if (M_UpdateUnlockablesAndExtraEmblems(true)) - S_StartSound(NULL, sfx_ncitem); - G_SaveGameData(true); - } + if (i == consoleplayer) + { + CONS_Printf("Player %d is you! Saving...\n", i); + vspowerlevel[powertype] = clientpowerlevels[i][powertype]; + if (M_UpdateUnlockablesAndExtraEmblems(true)) + S_StartSound(NULL, sfx_ncitem); + G_SaveGameData(true); } } } @@ -939,6 +984,9 @@ void Y_StartIntermission(void) break; } + if (powertype != -1) + Y_UpdatePowerLevels(); + //if (intertype == int_race || intertype == int_match) { //bgtile = W_CachePatchName("SRB2BACK", PU_STATIC); From 0c3e36ddf009dde6687d6b1d5911365b31c74e3f Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 18 Jan 2019 00:49:40 -0500 Subject: [PATCH 19/91] bad print --- src/y_inter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/y_inter.c b/src/y_inter.c index 0bbb04b14..a8ada4b2e 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -440,7 +440,7 @@ static void Y_UpdatePowerLevels(void) increment[ipnum] = inc; } - CONS_Printf("Setting final power levels...\n", inc); + CONS_Printf("Setting final power levels...\n"); for (i = 0; i < MAXPLAYERS; i++) { if (increment[i] == 0) From 3545b80459883f83502116b0cfc12735168b5e4e Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 21 Jan 2019 09:43:39 -0500 Subject: [PATCH 20/91] - Power level condition type (for emblems later) - Spectator forfeit doesn't kick in if you just joined the server --- src/d_netcmd.c | 1 + src/dehacked.c | 15 ++++++++++++++- src/k_kart.c | 8 ++++++-- src/m_cond.c | 2 ++ src/m_cond.h | 45 +++++++++++++++++++++++---------------------- src/m_menu.c | 2 ++ 6 files changed, 48 insertions(+), 25 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index ce9bcbf3a..6e75d3eb1 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -3413,6 +3413,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum) if (K_IsPlayerWanted(&players[playernum])) K_CalculateBattleWanted(); } + K_PlayerForfeit(playernum, true); players[playernum].health = 1; diff --git a/src/dehacked.c b/src/dehacked.c index 49b274d3f..b18abc34d 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2530,6 +2530,19 @@ static void readcondition(UINT8 set, UINT32 id, char *word2) ty = UC_PLAYTIME + offset; re = atoi(params[1]); } + else if ((offset=0) || fastcmp(params[0], "POWERLEVEL")) + { + PARAMCHECK(2); + ty = UC_POWERLEVEL; + re = atoi(params[1]); + x1 = atoi(params[2]); + + if (x1 < 0 || x1 > 1) + { + deh_warning("Power level type %d out of range (0 - 1)", x1); + return; + } + } else if ((offset=0) || fastcmp(params[0], "GAMECLEAR") || (++offset && fastcmp(params[0], "ALLEMERALDS"))) //|| (++offset && fastcmp(params[0], "ULTIMATECLEAR"))) @@ -2582,7 +2595,7 @@ static void readcondition(UINT8 set, UINT32 id, char *word2) if (x1 < 0 || x1 >= NUMMAPS) { - deh_warning("Level number %d out of range (1 - %d)", re, NUMMAPS); + deh_warning("Level number %d out of range (1 - %d)", x1, NUMMAPS); return; } } diff --git a/src/k_kart.c b/src/k_kart.c index 7ea2fd0b0..d13cd047e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5793,10 +5793,14 @@ void K_PlayerForfeit(UINT8 playernum, boolean pointloss) INT16 inc = 0; UINT8 i; - // power level is netgames only + // power level & spectating is netgames only if (!netgame) return; + // Hey, I just got here! + if (players[playernum].jointime <= 1) + return; + // 20 sec into the match counts as a forfeit -- automatic loss against every other player in the match. if (gamestate != GS_LEVEL || leveltime <= starttime+(20*TICRATE)) return; @@ -5815,7 +5819,7 @@ void K_PlayerForfeit(UINT8 playernum, boolean pointloss) else if (G_BattleGametype()) powertype = 1; - if (powertype == -1) // Not using power levels + if (powertype == -1) // Not using power levels? return; if (clientpowerlevels[playernum][powertype] == 0) // splitscreen guests don't record power level changes diff --git a/src/m_cond.c b/src/m_cond.c index 35eccd1c4..3158074fc 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -289,6 +289,8 @@ UINT8 M_CheckCondition(condition_t *cn) return (totalplaytime >= (unsigned)cn->requirement); case UC_MATCHESPLAYED: // Requires any level completed >= x times return (matchesplayed >= (unsigned)cn->requirement); + case UC_POWERLEVEL: // Requires power level >= x on a certain gametype + return (vspowerlevel[cn->extrainfo1] >= (unsigned)cn->requirement); case UC_GAMECLEAR: // Requires game beaten >= x times return (timesBeaten >= (unsigned)cn->requirement); case UC_ALLEMERALDS: // Requires game beaten with all 7 emeralds >= x times diff --git a/src/m_cond.h b/src/m_cond.h index 07e4480d1..4d3fe7248 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -22,28 +22,29 @@ typedef enum { UC_PLAYTIME, // PLAYTIME [tics] UC_MATCHESPLAYED, // SRB2Kart: MATCHESPLAYED [x played] - UC_GAMECLEAR, // GAMECLEAR - UC_ALLEMERALDS, // ALLEMERALDS - //UC_ULTIMATECLEAR, // ULTIMATECLEAR - //UC_OVERALLSCORE, // OVERALLSCORE [score to beat] - UC_OVERALLTIME, // OVERALLTIME [time to beat, tics] - //UC_OVERALLRINGS, // OVERALLRINGS [rings to beat] - UC_MAPVISITED, // MAPVISITED [map number] - UC_MAPBEATEN, // MAPBEATEN [map number] - UC_MAPALLEMERALDS, // MAPALLEMERALDS [map number] - //UC_MAPULTIMATE, // MAPULTIMATE [map number] - //UC_MAPPERFECT, // MAPPERFECT [map number] - //UC_MAPSCORE, // MAPSCORE [map number] [score to beat] - UC_MAPTIME, // MAPTIME [map number] [time to beat, tics] - //UC_MAPRINGS, // MAPRINGS [map number] [rings to beat] - //UC_NIGHTSSCORE, // NIGHTSSCORE [map number] [score to beat] - //UC_NIGHTSTIME, // NIGHTSTIME [map number] [time to beat, tics] - //UC_NIGHTSGRADE, // NIGHTSGRADE [map number] [grade] - UC_TRIGGER, // TRIGGER [trigger number] - UC_TOTALEMBLEMS, // TOTALEMBLEMS [number of emblems] - UC_EMBLEM, // EMBLEM [emblem number] - UC_EXTRAEMBLEM, // EXTRAEMBLEM [extra emblem number] - UC_CONDITIONSET, // CONDITIONSET [condition set number] + UC_POWERLEVEL, // SRB2Kart: POWERLEVEL [power level to reach] [gametype, "0" for race, "1" for battle] + UC_GAMECLEAR, // GAMECLEAR + UC_ALLEMERALDS, // ALLEMERALDS + //UC_ULTIMATECLEAR, // ULTIMATECLEAR + //UC_OVERALLSCORE, // OVERALLSCORE [score to beat] + UC_OVERALLTIME, // OVERALLTIME [time to beat, tics] + UC_OVERALLRINGS, // OVERALLRINGS [rings to beat] + UC_MAPVISITED, // MAPVISITED [map number] + UC_MAPBEATEN, // MAPBEATEN [map number] + UC_MAPALLEMERALDS, // MAPALLEMERALDS [map number] + //UC_MAPULTIMATE, // MAPULTIMATE [map number] + //UC_MAPPERFECT, // MAPPERFECT [map number] + //UC_MAPSCORE, // MAPSCORE [map number] [score to beat] + UC_MAPTIME, // MAPTIME [map number] [time to beat, tics] + //UC_MAPRINGS, // MAPRINGS [map number] [rings to beat] + //UC_NIGHTSSCORE, // NIGHTSSCORE [map number] [score to beat] + //UC_NIGHTSTIME, // NIGHTSTIME [map number] [time to beat, tics] + //UC_NIGHTSGRADE, // NIGHTSGRADE [map number] [grade] + UC_TRIGGER, // TRIGGER [trigger number] + UC_TOTALEMBLEMS, // TOTALEMBLEMS [number of emblems] + UC_EMBLEM, // EMBLEM [emblem number] + UC_EXTRAEMBLEM, // EXTRAEMBLEM [extra emblem number] + UC_CONDITIONSET, // CONDITIONSET [condition set number] } conditiontype_t; // Condition Set information diff --git a/src/m_menu.c b/src/m_menu.c index 900ff4f56..d28f44d20 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5170,6 +5170,8 @@ static char *M_GetConditionString(condition_t cond) G_TicsToSeconds(cond.requirement)); case UC_MATCHESPLAYED: return va("Play %d matches", cond.requirement); + case UC_POWERLEVEL: + return va("Reach power level %d in %s", cond.requirement, (cond.extrainfo1 == 1 ? "Battle" : "Race")); case UC_GAMECLEAR: if (cond.requirement > 1) return va("Beat game %d times", cond.requirement); From 12e41dfb002bb1209449d1130544e0f237b81915 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 11 Mar 2019 14:05:53 -0400 Subject: [PATCH 21/91] I *can't stand* waiting an entire minute minimum every time I need to test the tiniest thing -- time limit is now in seconds --- src/d_netcmd.c | 10 +++++----- src/p_inter.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 69f9fe5f7..18e105ea9 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -4363,8 +4363,8 @@ static void TimeLimit_OnChange(void) if (cv_timelimit.value != 0) { - CONS_Printf(M_GetText("Levels will end after %d minute%s.\n"),cv_timelimit.value,cv_timelimit.value == 1 ? "" : "s"); // Graue 11-17-2003 - timelimitintics = cv_timelimit.value * 60 * TICRATE; + CONS_Printf(M_GetText("Levels will end after %d second%s.\n"),cv_timelimit.value,cv_timelimit.value == 1 ? "" : "s"); // Graue 11-17-2003 + timelimitintics = cv_timelimit.value * TICRATE; //add hidetime for tag too! if (G_TagGametype()) @@ -4406,8 +4406,8 @@ void D_GameTypeChanged(INT32 lastgametype) if (!cv_timelimit.changed && !cv_pointlimit.changed) // user hasn't changed limits { // default settings for match: 2 mins, no pointlimit - CV_SetValue(&cv_pointlimit, 0); - CV_SetValue(&cv_timelimit, 2); + CV_SetValue(&cv_pointlimit, 0); + CV_SetValue(&cv_timelimit, 120); } if (!cv_itemrespawntime.changed) CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue); // respawn normally @@ -4713,7 +4713,7 @@ static void Hidetime_OnChange(void) //uh oh, gotta change timelimitintics now too if (G_TagGametype()) - timelimitintics = (cv_timelimit.value * 60 * TICRATE) + (hidetime * TICRATE); + timelimitintics = (cv_timelimit.value * TICRATE) + (hidetime * TICRATE); } static void Command_Showmap_f(void) diff --git a/src/p_inter.c b/src/p_inter.c index dce2021ac..9c49ccd4e 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1753,7 +1753,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } // Easily make it so that overtime works offline -//#define TESTOVERTIMEINFREEPLAY +#define TESTOVERTIMEINFREEPLAY /** Checks if the level timer is over the timelimit and the round should end, * unless you are in overtime. In which case leveltime may stretch out beyond From 47df41aa86e13128733150a33396ee3652a99c67 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Tue, 12 Mar 2019 01:24:43 -0400 Subject: [PATCH 22/91] Dither barrier --- src/p_mobj.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 801f6cf2a..10ac6817c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6533,6 +6533,7 @@ static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, fixed_t scale, mobjty /*if (battleovertime.enabled < 10*TICRATE) mo->flags2 |= MF2_SHADOW;*/ mo->angle = R_PointToAngle2(mo->x, mo->y, battleovertime.x, battleovertime.y) + ANGLE_90; + mo->z += P_RandomRange(0,48) * mo->scale; break; default: break; @@ -6583,7 +6584,7 @@ void P_RunBattleOvertime(void) // 16 orbs at the normal minimum size of 512 { const fixed_t pi = (22< Date: Fri, 19 Apr 2019 20:50:50 -0400 Subject: [PATCH 23/91] Update spawn positions in Race to use power levels --- src/g_game.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 57bc1829e..cd388b8bd 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2839,11 +2839,16 @@ mapthing_t *G_FindRaceStart(INT32 playernum) { UINT8 i; UINT8 pos = 0; + boolean usepowerlvl = false; // SRB2Kart: figure out player spawn pos from points if (!playeringame[playernum] || players[playernum].spectator) return playerstarts[0]; // go to first spot if you're a spectator + // Setup power level type + if (netgame) + usepowerlvl = true; + for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i] || players[i].spectator) @@ -2864,8 +2869,17 @@ mapthing_t *G_FindRaceStart(INT32 playernum) continue; if (j == i) continue; - if (players[j].score == players[i].score) - num++; + + if (usepowerlvl) + { + if (clientpowerlevels[j][0] == clientpowerlevels[i][0]) + num++; + } + else + { + if (players[j].score == players[i].score) + num++; + } } if (num > 1) // found dupes @@ -2873,8 +2887,21 @@ mapthing_t *G_FindRaceStart(INT32 playernum) } else { - if (players[i].score > players[playernum].score || i < playernum) + if (i < playernum) pos++; + else + { + if (usepowerlvl) + { + if (clientpowerlevels[i][0] > clientpowerlevels[playernum][0]) + pos++; + } + else + { + if (players[i].score > players[playernum].score) + pos++; + } + } } } From b669069098628b79aebc608e773a009f2710985b Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 19 Apr 2019 20:58:34 -0400 Subject: [PATCH 24/91] This doesn't exist --- src/m_cond.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/m_cond.h b/src/m_cond.h index 4d3fe7248..c6362ec5d 100644 --- a/src/m_cond.h +++ b/src/m_cond.h @@ -28,7 +28,7 @@ typedef enum //UC_ULTIMATECLEAR, // ULTIMATECLEAR //UC_OVERALLSCORE, // OVERALLSCORE [score to beat] UC_OVERALLTIME, // OVERALLTIME [time to beat, tics] - UC_OVERALLRINGS, // OVERALLRINGS [rings to beat] + //UC_OVERALLRINGS, // OVERALLRINGS [rings to beat] UC_MAPVISITED, // MAPVISITED [map number] UC_MAPBEATEN, // MAPBEATEN [map number] UC_MAPALLEMERALDS, // MAPALLEMERALDS [map number] From 8f3efa75987ec7bd46b21e190c27869850343531 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Tue, 23 Apr 2019 00:56:28 -0400 Subject: [PATCH 25/91] Remove 10 points at a time for power levels --- src/y_inter.c | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index a0f6ad16c..bd78e7f4e 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -786,15 +786,40 @@ void Y_Ticker(void) r++; data.match.jitter[data.match.num[q]] = 1; - if (data.match.increase[data.match.num[q]] > 0) + + if (powertype != -1) { - if (--data.match.increase[data.match.num[q]]) - kaching = false; + // Power Levels + if (abs(data.match.increase[data.match.num[q]]) < 10) + { + // Not a lot of point increase left, just set to 0 instantly + data.match.increase[data.match.num[q]] = 0; + } + else + { + SINT8 remove = 0; // default (should not happen) + + if (data.match.increase[data.match.num[q]] < 0) + remove = -10; + else if (data.match.increase[data.match.num[q]] > 0) + remove = 10; + + // Remove 10 points at a time + data.match.increase[data.match.num[q]] -= remove; + + // Still not zero, no kaching yet + if (data.match.increase[data.match.num[q]] != 0) + kaching = false; + } } - else if (data.match.increase[data.match.num[q]] < 0) + else { - if (++data.match.increase[data.match.num[q]]) - kaching = false; + // Basic bitch points + if (data.match.increase[data.match.num[q]]) + { + if (--data.match.increase[data.match.num[q]]) + kaching = false; + } } } From da7437947a9966df3bb6c670a7a5c701349462ca Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Tue, 23 Apr 2019 00:56:50 -0400 Subject: [PATCH 26/91] Display ---- on the right player --- src/y_inter.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/y_inter.c b/src/y_inter.c index bd78e7f4e..ff99b7ff4 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -635,7 +635,7 @@ void Y_IntermissionDrawer(void) if (data.match.rankingsmode) { - if (!clientpowerlevels[i][powertype]) // No power level (splitscreen guests) + if (!clientpowerlevels[data.match.num[i]][powertype]) // No power level (splitscreen guests) STRBUFCPY(strtime, "----"); else { From 6f6bc3333fa502a31faf2a4e28f690d891debb2a Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Tue, 23 Apr 2019 01:10:16 -0400 Subject: [PATCH 27/91] Put behind cvar --- src/d_netcmd.c | 1 + src/d_netcmd.h | 2 +- src/g_game.c | 9 ++------- src/k_kart.c | 7 ++++++- src/m_menu.c | 3 +-- src/y_inter.c | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 49dfae28f..46a57b340 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -369,6 +369,7 @@ static CV_PossibleValue_t kartvoices_cons_t[] = {{0, "Never"}, {1, "Tasteful"}, consvar_t cv_kartvoices = {"kartvoices", "Tasteful", CV_SAVE, kartvoices_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_karteliminatelast = {"karteliminatelast", "Yes", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOSHOWHELP, CV_YesNo, KartEliminateLast_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_kartusepwrlv = {"kartusepwrlv", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t kartdebugitem_cons_t[] = {{-1, "MIN"}, {NUMKARTITEMS-1, "MAX"}, {0, NULL}}; consvar_t cv_kartdebugitem = {"kartdebugitem", "0", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugitem_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/d_netcmd.h b/src/d_netcmd.h index efd314701..aa5f08b2b 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -120,8 +120,8 @@ extern consvar_t cv_kartencore; extern consvar_t cv_kartvoterulechanges; extern consvar_t cv_kartspeedometer; extern consvar_t cv_kartvoices; - extern consvar_t cv_karteliminatelast; +extern consvar_t cv_kartusepwrlv; extern consvar_t cv_votetime; diff --git a/src/g_game.c b/src/g_game.c index cd388b8bd..169933084 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2839,16 +2839,11 @@ mapthing_t *G_FindRaceStart(INT32 playernum) { UINT8 i; UINT8 pos = 0; - boolean usepowerlvl = false; // SRB2Kart: figure out player spawn pos from points if (!playeringame[playernum] || players[playernum].spectator) return playerstarts[0]; // go to first spot if you're a spectator - // Setup power level type - if (netgame) - usepowerlvl = true; - for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i] || players[i].spectator) @@ -2870,7 +2865,7 @@ mapthing_t *G_FindRaceStart(INT32 playernum) if (j == i) continue; - if (usepowerlvl) + if (netgame && cv_kartusepwrlv.value) { if (clientpowerlevels[j][0] == clientpowerlevels[i][0]) num++; @@ -2891,7 +2886,7 @@ mapthing_t *G_FindRaceStart(INT32 playernum) pos++; else { - if (usepowerlvl) + if (netgame && cv_kartusepwrlv.value) { if (clientpowerlevels[i][0] > clientpowerlevels[playernum][0]) pos++; diff --git a/src/k_kart.c b/src/k_kart.c index 2ec21d0f1..d07afda66 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -544,6 +544,7 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_kartspeedometer); CV_RegisterVar(&cv_kartvoices); CV_RegisterVar(&cv_karteliminatelast); + CV_RegisterVar(&cv_kartusepwrlv); CV_RegisterVar(&cv_votetime); CV_RegisterVar(&cv_kartdebugitem); @@ -6122,6 +6123,10 @@ void K_PlayerForfeit(UINT8 playernum, boolean pointloss) if (!netgame) return; + // This server isn't using power levels anyway! + if (!cv_kartusepwrlv.value) + return; + // Hey, I just got here! if (players[playernum].jointime <= 1) return; @@ -6144,7 +6149,7 @@ void K_PlayerForfeit(UINT8 playernum, boolean pointloss) else if (G_BattleGametype()) powertype = 1; - if (powertype == -1) // Not using power levels? + if (powertype == -1) // No power type?! return; if (clientpowerlevels[playernum][powertype] == 0) // splitscreen guests don't record power level changes diff --git a/src/m_menu.c b/src/m_menu.c index d3541ebde..1d11a2805 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -1445,8 +1445,7 @@ static menuitem_t OP_GameOptionsMenu[] = {IT_STRING | IT_CVAR, NULL, "Starting Bumpers", &cv_kartbumpers, 110}, {IT_STRING | IT_CVAR, NULL, "Karma Comeback", &cv_kartcomeback, 120}, - {IT_STRING | IT_CVAR, NULL, "Force Character", &cv_forceskin, 140}, - {IT_STRING | IT_CVAR, NULL, "Restrict Character Changes", &cv_restrictskinchange, 150}, + {IT_STRING | IT_CVAR, NULL, "Track Power Levels", &cv_kartusepwrlv, 140}, }; static menuitem_t OP_ServerOptionsMenu[] = diff --git a/src/y_inter.c b/src/y_inter.c index ff99b7ff4..42a5b0921 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -937,7 +937,7 @@ void Y_StartIntermission(void) // set player Power Level type powertype = -1; - if (netgame) + if (netgame && cv_kartusepwrlv.value) { if (G_RaceGametype()) powertype = 0; From 5abe25d0a552d05b79489df29e914760758b56b1 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Wed, 24 Apr 2019 01:47:43 -0400 Subject: [PATCH 28/91] Speed/Encore scrambles based on power level Did not test yet --- src/g_game.c | 39 ++++++++++++++++-------- src/k_kart.c | 33 +++++++++++++++++++++ src/k_kart.h | 1 + src/y_inter.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 140 insertions(+), 15 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 169933084..95b4c4b8d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -273,6 +273,10 @@ INT16 nospectategrief[MAXPLAYERS]; // Which players spec-scummed, and their powe boolean thwompsactive; // Thwomps activate on lap 2 SINT8 spbplace; // SPB exists, give the person behind better items +// Scrambles +SINT8 speedscramble; +SINT8 encorescramble; + // Client-sided, unsynched variables (NEVER use in anything that needs to be synced with other players) boolean legitimateexit; // Did this client actually finish the match? boolean comebackshowninfo; // Have you already seen the "ATTACK OR PROTECT" message? @@ -3194,9 +3198,10 @@ boolean G_BattleGametype(void) // INT16 G_SometimesGetDifferentGametype(void) { - boolean encorepossible = (M_SecretUnlocked(SECRET_ENCORE) && G_RaceGametype()); + boolean encorepossible = ((M_SecretUnlocked(SECRET_ENCORE) || encorescramble == 1) && G_RaceGametype()); - if (!cv_kartvoterulechanges.value) // never + if (!cv_kartvoterulechanges.value // never + && encorescramble != 1) // destroying the code for this one instance return gametype; if (randmapbuffer[NUMMAPS] > 0 && (encorepossible || cv_kartvoterulechanges.value != 3)) @@ -3204,18 +3209,23 @@ INT16 G_SometimesGetDifferentGametype(void) randmapbuffer[NUMMAPS]--; if (encorepossible) { - switch (cv_kartvoterulechanges.value) + if (encorescramble >= 0) + encorepossible = (boolean)encorescramble; + else { - case 3: // always - randmapbuffer[NUMMAPS] = 0; // gotta prep this in case it isn't already set - break; - case 2: // frequent - encorepossible = M_RandomChance(FRACUNIT>>1); - break; - case 1: // sometimes - default: - encorepossible = M_RandomChance(FRACUNIT>>2); - break; + switch (cv_kartvoterulechanges.value) + { + case 3: // always + randmapbuffer[NUMMAPS] = 0; // gotta prep this in case it isn't already set + break; + case 2: // frequent + encorepossible = M_RandomChance(FRACUNIT>>1); + break; + case 1: // sometimes + default: + encorepossible = M_RandomChance(FRACUNIT>>2); + break; + } } if (encorepossible != (boolean)cv_kartencore.value) return (gametype|0x80); @@ -3223,6 +3233,9 @@ INT16 G_SometimesGetDifferentGametype(void) return gametype; } + if (!cv_kartvoterulechanges.value) // never (again) + return gametype; + switch (cv_kartvoterulechanges.value) // okay, we're having a gametype change! when's the next one, luv? { case 3: // always diff --git a/src/k_kart.c b/src/k_kart.c index d07afda66..8ff2db66d 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6109,6 +6109,39 @@ INT16 K_CalculatePowerLevelInc(INT16 diff) return (INT16)(increment >> FRACBITS); } +INT16 K_CalculatePowerLevelAvg(void) +{ + fixed_t avg = 0; + UINT8 div = 0; + SINT8 t = -1; + UINT8 i; + + if (!netgame || !cv_kartusepwrlv.value) + return 0; // No average. + + if (G_RaceGametype()) + t = 0; + else if (G_BattleGametype()) + t = 1; + + if (t == -1) + return 0; // Hmm?! + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator + || clientpowerlevels[i][t] == 0) + continue; + + avg += clientpowerlevels[i][t]; + div++; + } + + avg /= div; + + return (INT16)(avg >> FRACBITS); +} + void K_PlayerForfeit(UINT8 playernum, boolean pointloss) { UINT8 p = 0; diff --git a/src/k_kart.h b/src/k_kart.h index 0844abc5a..396ebdc55 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -66,6 +66,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground); void K_CalculateBattleWanted(void); void K_CheckBumpers(void); INT16 K_CalculatePowerLevelInc(INT16 diff); +INT16 K_CalculatePowerLevelAvg(void); void K_PlayerForfeit(UINT8 playernum, boolean nopointloss); void K_CheckSpectateStatus(void); diff --git a/src/y_inter.c b/src/y_inter.c index 42a5b0921..67c4b797b 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -710,8 +710,14 @@ dotimer: } // Make it obvious that scrambling is happening next round. - if (cv_scrambleonchange.value && cv_teamscramble.value && (intertic/TICRATE % 2 == 0)) - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, hilicol, M_GetText("Teams will be scrambled next round!")); + if ((intertic/TICRATE) & 1) + { + /*if (cv_scrambleonchange.value && cv_teamscramble.value) + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, hilicol, M_GetText("Teams will be scrambled next round!"));*/ + if (speedscramble != -1) + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-12, hilicol|V_ALLOWLOWERCASE|V_SNAPTOBOTTOM, + M_GetText("The next race will be %s Speed!", (speedscramble == 2 ? "Hard" : "Normal"))); + } } // @@ -943,6 +949,78 @@ void Y_StartIntermission(void) powertype = 0; else if (G_BattleGametype()) powertype = 1; + + // Race scrambles + if ((intertype == int_race) && (cv_speedscramble.value || cv_encorescramble.value)) + { + boolean hardmode = false; + boolean encore = false; + INT16 avg = 0, min = 0; + UINT8 i, t = 0; + + avg = K_CalculatePowerLevelAvg(); + + for (i = 0; i < MAXPLAYERS; i++) + { + if (min == 0 || clientpowerlevels[i][0] < min) + min = clientpowerlevels[i][0]; + } + + if (min >= 4000) + { + if (avg >= 5000) + t = 3; + else + t = 2; + } + else if (min >= 2500) + { + if (avg >= 3000) + t = 2; + else + t = 1; + } + else if (min >= 500) + { + if (avg >= 2000) + t = 1; + else + t = 0; + } + else + t = 0; + + switch (t) + { + case 3: + hardmode = true; + encore = M_RandomChance(FRACUNIT>>1); + break; + case 2: + hardmode = M_RandomChance((7<>2); + break; + case 1: + hardmode = M_RandomChance((3< Date: Fri, 26 Apr 2019 13:34:30 -0400 Subject: [PATCH 29/91] finished scrambles --- src/d_netcmd.c | 3 + src/d_netcmd.h | 2 + src/doomstat.h | 3 + src/g_game.c | 6 +- src/k_kart.c | 5 ++ src/p_setup.c | 9 ++- src/y_inter.c | 149 ++++++++++++++++++++++++++----------------------- 7 files changed, 103 insertions(+), 74 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 46a57b340..2606311af 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -369,7 +369,10 @@ static CV_PossibleValue_t kartvoices_cons_t[] = {{0, "Never"}, {1, "Tasteful"}, consvar_t cv_kartvoices = {"kartvoices", "Tasteful", CV_SAVE, kartvoices_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_karteliminatelast = {"karteliminatelast", "Yes", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOSHOWHELP, CV_YesNo, KartEliminateLast_OnChange, 0, NULL, NULL, 0, 0, NULL}; + consvar_t cv_kartusepwrlv = {"kartusepwrlv", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_speedscramble = {"kartscramblespeed", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_encorescramble = {"kartscrambleencore", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t kartdebugitem_cons_t[] = {{-1, "MIN"}, {NUMKARTITEMS-1, "MAX"}, {0, NULL}}; consvar_t cv_kartdebugitem = {"kartdebugitem", "0", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugitem_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; diff --git a/src/d_netcmd.h b/src/d_netcmd.h index aa5f08b2b..24bc0a31b 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -122,6 +122,8 @@ extern consvar_t cv_kartspeedometer; extern consvar_t cv_kartvoices; extern consvar_t cv_karteliminatelast; extern consvar_t cv_kartusepwrlv; +extern consvar_t cv_speedscramble; +extern consvar_t cv_encorescramble; extern consvar_t cv_votetime; diff --git a/src/doomstat.h b/src/doomstat.h index 139660cc9..43cadcda5 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -474,6 +474,9 @@ extern INT16 nospectategrief[MAXPLAYERS]; extern boolean thwompsactive; extern SINT8 spbplace; +extern SINT8 speedscramble; +extern SINT8 encorescramble; + extern boolean legitimateexit; extern boolean comebackshowninfo; extern tic_t curlap, bestlap; diff --git a/src/g_game.c b/src/g_game.c index 95b4c4b8d..39d7f2957 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -274,8 +274,8 @@ boolean thwompsactive; // Thwomps activate on lap 2 SINT8 spbplace; // SPB exists, give the person behind better items // Scrambles -SINT8 speedscramble; -SINT8 encorescramble; +SINT8 speedscramble = -1; +SINT8 encorescramble = -1; // Client-sided, unsynched variables (NEVER use in anything that needs to be synced with other players) boolean legitimateexit; // Did this client actually finish the match? @@ -3210,7 +3210,7 @@ INT16 G_SometimesGetDifferentGametype(void) if (encorepossible) { if (encorescramble >= 0) - encorepossible = (boolean)encorescramble; + encorepossible = (boolean)encorescramble; // FORCE to what was scrambled on intermission else { switch (cv_kartvoterulechanges.value) diff --git a/src/k_kart.c b/src/k_kart.c index 8ff2db66d..742c3417a 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -545,6 +545,8 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_kartvoices); CV_RegisterVar(&cv_karteliminatelast); CV_RegisterVar(&cv_kartusepwrlv); + CV_RegisterVar(&cv_speedscramble); + CV_RegisterVar(&cv_encorescramble); CV_RegisterVar(&cv_votetime); CV_RegisterVar(&cv_kartdebugitem); @@ -6137,6 +6139,9 @@ INT16 K_CalculatePowerLevelAvg(void) div++; } + if (!div) + return 0; // No average. + avg /= div; return (INT16)(avg >> FRACBITS); diff --git a/src/p_setup.c b/src/p_setup.c index 9e8cd3c08..5c42b437a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2370,13 +2370,20 @@ static void P_LevelInitStuff(void) if (G_BattleGametype()) gamespeed = 0; else - gamespeed = (UINT8)cv_kartspeed.value; + { + if (cv_speedscramble.value && speedscramble != -1) + gamespeed = (UINT8)speedscramble; + else + gamespeed = (UINT8)cv_kartspeed.value; + } franticitems = (boolean)cv_kartfrantic.value; comeback = (boolean)cv_kartcomeback.value; } for (i = 0; i < 4; i++) battlewanted[i] = -1; + + speedscramble = encorescramble = -1; } // diff --git a/src/y_inter.c b/src/y_inter.c index 67c4b797b..19189e0c3 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -705,7 +705,7 @@ dotimer: if (timer) { INT32 tickdown = (timer+1)/TICRATE; - V_DrawCenteredString(BASEVIDWIDTH/2, 188, hilicol, + V_DrawCenteredString(BASEVIDWIDTH/2, 188, hilicol|V_SNAPTOBOTTOM, va("%s starts in %d", cv_advancemap.string, tickdown)); } @@ -714,9 +714,9 @@ dotimer: { /*if (cv_scrambleonchange.value && cv_teamscramble.value) V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, hilicol, M_GetText("Teams will be scrambled next round!"));*/ - if (speedscramble != -1) - V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-12, hilicol|V_ALLOWLOWERCASE|V_SNAPTOBOTTOM, - M_GetText("The next race will be %s Speed!", (speedscramble == 2 ? "Hard" : "Normal"))); + if (speedscramble != -1 && speedscramble != gamespeed) + V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24, hilicol|V_ALLOWLOWERCASE|V_SNAPTOBOTTOM, + va(M_GetText("Next race will be %s Speed!"), kartspeed_cons_t[speedscramble].strvalue)); } } @@ -949,78 +949,87 @@ void Y_StartIntermission(void) powertype = 0; else if (G_BattleGametype()) powertype = 1; + } - // Race scrambles - if ((intertype == int_race) && (cv_speedscramble.value || cv_encorescramble.value)) + // Race scrambles + if (powertype == 0 && (cv_speedscramble.value || cv_encorescramble.value)) + { + boolean hardmode = false; + boolean encore = false; + INT16 avg = 0, min = 0; + UINT8 i, t = 0; + + avg = K_CalculatePowerLevelAvg(); + + for (i = 0; i < MAXPLAYERS; i++) { - boolean hardmode = false; - boolean encore = false; - INT16 avg = 0, min = 0; - UINT8 i, t = 0; + if (min == 0 || clientpowerlevels[i][0] < min) + min = clientpowerlevels[i][0]; + } - avg = K_CalculatePowerLevelAvg(); - - for (i = 0; i < MAXPLAYERS; i++) - { - if (min == 0 || clientpowerlevels[i][0] < min) - min = clientpowerlevels[i][0]; - } - - if (min >= 4000) - { - if (avg >= 5000) - t = 3; - else - t = 2; - } - else if (min >= 2500) - { - if (avg >= 3000) - t = 2; - else - t = 1; - } - else if (min >= 500) - { - if (avg >= 2000) - t = 1; - else - t = 0; - } + if (min >= 6000) + { + if (avg >= 8000) + t = 4; + else + t = 3; + } + else if (min >= 4000) + { + if (avg >= 5000) + t = 3; + else + t = 2; + } + else if (min >= 2500) + { + if (avg >= 3000) + t = 2; + else + t = 1; + } + else if (min >= 500) + { + if (avg >= 2000) + t = 1; else t = 0; - - switch (t) - { - case 3: - hardmode = true; - encore = M_RandomChance(FRACUNIT>>1); - break; - case 2: - hardmode = M_RandomChance((7<>2); - break; - case 1: - hardmode = M_RandomChance((3<>1); + break; + case 2: + hardmode = M_RandomChance((7<>2); + break; + case 1: + hardmode = M_RandomChance((3< Date: Fri, 26 Apr 2019 13:40:14 -0400 Subject: [PATCH 30/91] no flash --- src/y_inter.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index 19189e0c3..8b9d7e2ca 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -709,15 +709,15 @@ dotimer: va("%s starts in %d", cv_advancemap.string, tickdown)); } - // Make it obvious that scrambling is happening next round. - if ((intertic/TICRATE) & 1) - { + // Make it obvious that scrambling is happening next round. (OR NOT I GUESS.) + //if ((intertic/TICRATE) & 1) + //{ /*if (cv_scrambleonchange.value && cv_teamscramble.value) V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, hilicol, M_GetText("Teams will be scrambled next round!"));*/ if (speedscramble != -1 && speedscramble != gamespeed) V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24, hilicol|V_ALLOWLOWERCASE|V_SNAPTOBOTTOM, va(M_GetText("Next race will be %s Speed!"), kartspeed_cons_t[speedscramble].strvalue)); - } + //} } // From ed093e0856199addf8585c934c1ab7c8eed50368 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 26 Apr 2019 14:07:48 -0400 Subject: [PATCH 31/91] Display on server browser --- src/d_clisrv.c | 5 +++++ src/d_clisrv.h | 1 + src/k_kart.c | 2 +- src/m_menu.c | 34 ++++++++++++++++++++-------------- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 7727ba8a9..2d9606839 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1435,6 +1435,11 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) p = PutFileNeeded(); + if (cv_kartusepwrlv.value) + netbuffer->u.serverinfo.avgpwrlv = K_CalculatePowerLevelAvg(); + else + netbuffer->u.serverinfo.avgpwrlv = -1; + HSendPacket(node, false, 0, p - ((UINT8 *)&netbuffer->u)); } diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 3241b25e7..4ce6581a0 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -399,6 +399,7 @@ typedef struct UINT8 actnum; UINT8 iszone; UINT8 fileneeded[MAXFILENEEDED]; // is filled with writexxx (byteptr.h) + INT16 avgpwrlv; // Kart avg power level } ATTRPACK serverinfo_pak; typedef struct diff --git a/src/k_kart.c b/src/k_kart.c index 742c3417a..00692acde 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6132,7 +6132,7 @@ INT16 K_CalculatePowerLevelAvg(void) for (i = 0; i < MAXPLAYERS; i++) { if (!playeringame[i] || players[i].spectator - || clientpowerlevels[i][t] == 0) + || clientpowerlevels[i][t] == 0) // splitscreen player continue; avg += clientpowerlevels[i][t]; diff --git a/src/m_menu.c b/src/m_menu.c index 1d11a2805..723a5f7fd 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7288,6 +7288,7 @@ static void M_DrawConnectMenu(void) UINT16 i, j; const char *gt = "Unknown"; const char *spd = ""; + const char *pwr = "----"; INT32 numPages = (serverlistcount+(SERVERS_PER_PAGE-1))/SERVERS_PER_PAGE; for (i = FIRSTSERVERLINE; i < min(localservercount, SERVERS_PER_PAGE)+FIRSTSERVERLINE; i++) @@ -7322,36 +7323,41 @@ static void M_DrawConnectMenu(void) V_DrawString(currentMenu->x, S_LINEY(i), globalflags, serverlist[slindex].info.servername); - // Don't use color flags intentionally, the global yellow color will auto override the text color code - if (serverlist[slindex].info.modifiedgame) - V_DrawSmallString(currentMenu->x+202, S_LINEY(i)+8, globalflags, "\x85" "Mod"); - if (serverlist[slindex].info.cheatsenabled) - V_DrawSmallString(currentMenu->x+222, S_LINEY(i)+8, globalflags, "\x83" "Cheats"); + if (serverlist[slindex].info.kartvars & SV_PASSWORD) + V_DrawFixedPatch((currentMenu->x - 9) << FRACBITS, (S_LINEY(i)) << FRACBITS, FRACUNIT, globalflags & (~V_ALLOWLOWERCASE), W_CachePatchName("SERVLOCK", PU_CACHE), NULL); V_DrawSmallString(currentMenu->x, S_LINEY(i)+8, globalflags, va("Ping: %u", (UINT32)LONG(serverlist[slindex].info.time))); + V_DrawSmallString(currentMenu->x+44,S_LINEY(i)+8, globalflags, + va("Players: %02d/%02d", serverlist[slindex].info.numberofplayer, serverlist[slindex].info.maxplayer)); + gt = "Unknown"; for (j = 0; gametype_cons_t[j].strvalue; j++) { if (gametype_cons_t[j].value == serverlist[slindex].info.gametype) gt = gametype_cons_t[j].strvalue; } - - V_DrawSmallString(currentMenu->x+46,S_LINEY(i)+8, globalflags, - va("Players: %02d/%02d", serverlist[slindex].info.numberofplayer, serverlist[slindex].info.maxplayer)); - - V_DrawSmallString(currentMenu->x+112, S_LINEY(i)+8, globalflags, gt); + V_DrawSmallString(currentMenu->x+108, S_LINEY(i)+8, globalflags, gt); if (serverlist[slindex].info.gametype == GT_RACE) { spd = kartspeed_cons_t[serverlist[slindex].info.kartvars & SV_SPEEDMASK].strvalue; - - V_DrawSmallString(currentMenu->x+132, S_LINEY(i)+8, globalflags, va("(%s Speed)", spd)); + V_DrawSmallString(currentMenu->x+128, S_LINEY(i)+8, globalflags, va("(%s)", spd)); } - if (serverlist[slindex].info.kartvars & SV_PASSWORD) - V_DrawFixedPatch((currentMenu->x - 9) << FRACBITS, (S_LINEY(i)) << FRACBITS, FRACUNIT, globalflags & (~V_ALLOWLOWERCASE), W_CachePatchName("SERVLOCK", PU_CACHE), NULL); + pwr = "----"; + if (serverlist[slindex].info.avgpwrlv == -1) + pwr = "Off"; + else if (serverlist[slindex].info.avgpwrlv > 0) + pwr = va("%04d", serverlist[slindex].info.avgpwrlv); + V_DrawSmallString(currentMenu->x+171, S_LINEY(i)+8, globalflags, va("Power Level: %s", pwr)); + + // Don't use color flags intentionally, the global yellow color will auto override the text color code + if (serverlist[slindex].info.modifiedgame) + V_DrawSmallString(currentMenu->x+245, S_LINEY(i)+8, globalflags, "\x85" "Mod"); + if (serverlist[slindex].info.cheatsenabled) + V_DrawSmallString(currentMenu->x+265, S_LINEY(i)+8, globalflags, "\x83" "Cheats"); MP_ConnectMenu[i+FIRSTSERVERLINE].status = IT_STRING | IT_CALL; } From 94081f469e14d7ad600a8976a2d967349b21f293 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 4 Aug 2019 23:42:30 -0400 Subject: [PATCH 32/91] Genesis wipe stuff Very unoptimized, lags in anything besides 320x200 --- src/f_wipe.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++-- src/r_data.c | 3 +- src/r_data.h | 1 + 3 files changed, 89 insertions(+), 5 deletions(-) diff --git a/src/f_wipe.c b/src/f_wipe.c index 3c8713d18..842161a62 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -12,12 +12,19 @@ /// \file f_wipe.c /// \brief SRB2 2.1 custom fade mask "wipe" behavior. +#define GENESIS_WIPE // Sal: experimental Genesis-style colorful wipes + #include "f_finale.h" #include "i_video.h" #include "v_video.h" +#ifdef GENESIS_WIPE +#include "r_data.h" // NearestColor +#else #include "r_draw.h" // transtable #include "p_pspr.h" // tr_transxxx +#endif + #include "w_wad.h" #include "z_zone.h" @@ -89,6 +96,7 @@ INT32 lastwipetic = 0; static UINT8 *wipe_scr_start; //screen 3 static UINT8 *wipe_scr_end; //screen 4 static UINT8 *wipe_scr; //screen 0 (main drawing) +static UINT8 pallen; static fixed_t paldiv; /** Create fademask_t from lump @@ -211,7 +219,12 @@ static void F_DoWipe(fademask_t *fademask) const UINT8 *e_base = e; // mask data, end - UINT8 *transtbl; +#ifdef GENESIS_WIPE + UINT8 i; + RGBA_t wcolor, *ecolor; +#else + UINT8 *transtbl; +#endif const UINT8 *mask = fademask->mask; const UINT8 *maskend = mask + fademask->size; @@ -259,7 +272,7 @@ static void F_DoWipe(fademask_t *fademask) relativepos += vid.width; } } - else if (*mask == 10) + else if (*mask == pallen) { // shortcut - memcpy target to work while (draw_linestogo--) @@ -270,6 +283,70 @@ static void F_DoWipe(fademask_t *fademask) } else { +#ifdef GENESIS_WIPE + // DRAWING LOOP + while (draw_linestogo--) + { + w = w_base + relativepos; + s = s_base + relativepos; + e = e_base + relativepos; + draw_rowstogo = draw_rowend - draw_rowstart; + + ecolor = &pLocalPalette[*e]; + + while (draw_rowstogo--) + { + memcpy(&wcolor, &pLocalPalette[*s++], sizeof(RGBA_t)); + + // GENESIS WIPE: + // Change red until it reaches the intended value + // Then green, then blue. + + for (i = 0; i < *mask; i++) + { + if (abs(wcolor.s.red - ecolor->s.red) > 34) + { + if (wcolor.s.red < ecolor->s.red) + wcolor.s.red += 34; + else + wcolor.s.red -= 34; + } + else + { + wcolor.s.red = ecolor->s.red; + + if (abs(wcolor.s.green - ecolor->s.green) > 34) + { + if (wcolor.s.green < ecolor->s.green) + wcolor.s.green += 34; + else + wcolor.s.green -= 34; + } + else + { + wcolor.s.green = ecolor->s.green; + + if (abs(wcolor.s.blue - ecolor->s.blue) > 34) + { + if (wcolor.s.blue < ecolor->s.blue) + wcolor.s.blue += 34; + else + wcolor.s.blue -= 34; + + } + else + wcolor.s.blue = ecolor->s.blue; + } + } + } + + *w++ = NearestColor(wcolor.s.red, wcolor.s.green, wcolor.s.blue); + } + + relativepos += vid.width; + } + // END DRAWING LOOP +#else // pointer to transtable that this mask would use transtbl = transtables + ((9 - *mask)<= fademask->width) @@ -347,7 +425,13 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu) UINT8 wipeframe = 0; fademask_t *fmask; - paldiv = FixedDiv(257< Date: Wed, 7 Aug 2019 02:21:04 -0400 Subject: [PATCH 33/91] Uses pre-defined colormap lumps now Works much faster now. I'd like to clean up this code some though --- src/d_main.c | 4 +- src/f_finale.c | 8 +-- src/f_finale.h | 2 +- src/f_wipe.c | 141 +++++++++++++++++++------------------------------ src/p_setup.c | 6 +-- 5 files changed, 65 insertions(+), 96 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 1404a5e61..a6bd48e0e 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -325,7 +325,7 @@ static void D_Display(void) F_WipeStartScreen(); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); F_WipeEndScreen(); - F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK); + F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK, "FADEMAP0", false); } if (gamestate != GS_LEVEL && rendermode != render_none) @@ -556,7 +556,7 @@ static void D_Display(void) if (rendermode != render_none) { F_WipeEndScreen(); - F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK); + F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK, "FADEMAP0", true); } } diff --git a/src/f_finale.c b/src/f_finale.c index 9a4be070c..d45a9cfa9 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -220,7 +220,7 @@ void F_StartIntro(void) F_WipeStartScreen(); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); F_WipeEndScreen(); - F_RunWipe(wipedefs[wipe_level_final], false); + F_RunWipe(wipedefs[wipe_level_final], false, "FADEMAP0", false); } if (introtoplay) @@ -306,7 +306,7 @@ void F_IntroDrawer(void) F_WipeStartScreen(); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); F_WipeEndScreen(); - F_RunWipe(99,true); + F_RunWipe(99, true, "FADEMAP0", false); } // Stay on black for a bit. =) @@ -1420,7 +1420,7 @@ void F_CutsceneDrawer(void) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, cutscenes[cutnum]->scene[scenenum].fadecolor); F_WipeEndScreen(); - F_RunWipe(cutscenes[cutnum]->scene[scenenum].fadeinid, true); + F_RunWipe(cutscenes[cutnum]->scene[scenenum].fadeinid, true, NULL, false); F_WipeStartScreen(); } @@ -1440,7 +1440,7 @@ void F_CutsceneDrawer(void) if (dofadenow && rendermode != render_none) { F_WipeEndScreen(); - F_RunWipe(cutscenes[cutnum]->scene[scenenum].fadeoutid, true); + F_RunWipe(cutscenes[cutnum]->scene[scenenum].fadeoutid, true, NULL, false); } V_DrawString(textxpos, textypos, 0, cutscene_disptext); diff --git a/src/f_finale.h b/src/f_finale.h index 45166e03d..a6fccf888 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -74,7 +74,7 @@ extern INT32 lastwipetic; void F_WipeStartScreen(void); void F_WipeEndScreen(void); -void F_RunWipe(UINT8 wipetype, boolean drawMenu); +void F_RunWipe(UINT8 wipetype, boolean drawMenu, const char *colormap, boolean reverse); enum { diff --git a/src/f_wipe.c b/src/f_wipe.c index 842161a62..0abef4ca7 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -18,12 +18,9 @@ #include "i_video.h" #include "v_video.h" -#ifdef GENESIS_WIPE #include "r_data.h" // NearestColor -#else #include "r_draw.h" // transtable #include "p_pspr.h" // tr_transxxx -#endif #include "w_wad.h" #include "z_zone.h" @@ -93,6 +90,9 @@ boolean WipeInAction = false; INT32 lastwipetic = 0; #ifndef NOWIPE + +#define GENLEN 31 + static UINT8 *wipe_scr_start; //screen 3 static UINT8 *wipe_scr_end; //screen 4 static UINT8 *wipe_scr; //screen 0 (main drawing) @@ -189,7 +189,7 @@ static fademask_t *F_GetFadeMask(UINT8 masknum, UINT8 scrnnum) { * * \param fademask pixels to change */ -static void F_DoWipe(fademask_t *fademask) +static void F_DoWipe(fademask_t *fademask, lighttable_t *fadecolormap, boolean reverse) { // Software mask wipe -- optimized; though it might not look like it! // Okay, to save you wondering *how* this is more optimized than the simpler @@ -207,6 +207,10 @@ static void F_DoWipe(fademask_t *fademask) // look a little messy; sorry!) but it simultaneously runs at twice the speed. // In addition, we precalculate all the X and Y positions that we need to draw // from and to, so it uses a little extra memory, but again, helps it run faster. + // --- + // Sal: I kinda destroyed some of this code by introducing Genesis-style fades. + // A colormap can be provided in F_RunWipe, which the white/black values will be + // remapped to the appropriate entry in the fade colormap. { // wipe screen, start, end UINT8 *w = wipe_scr; @@ -219,12 +223,7 @@ static void F_DoWipe(fademask_t *fademask) const UINT8 *e_base = e; // mask data, end -#ifdef GENESIS_WIPE - UINT8 i; - RGBA_t wcolor, *ecolor; -#else - UINT8 *transtbl; -#endif + UINT8 *transtbl; const UINT8 *mask = fademask->mask; const UINT8 *maskend = mask + fademask->size; @@ -255,6 +254,8 @@ static void F_DoWipe(fademask_t *fademask) maskx = masky = 0; do { + UINT8 m = *mask; + draw_rowstart = scrxpos[maskx]; draw_rowend = scrxpos[maskx + 1]; draw_linestart = scrypos[masky]; @@ -263,27 +264,32 @@ static void F_DoWipe(fademask_t *fademask) relativepos = (draw_linestart * vid.width) + draw_rowstart; draw_linestogo = draw_lineend - draw_linestart; - if (*mask == 0) + if (reverse) + m = ((pallen-1) - m); + + if (m == 0) { // shortcut - memcpy source to work while (draw_linestogo--) { - M_Memcpy(w_base+relativepos, s_base+relativepos, draw_rowend-draw_rowstart); + M_Memcpy(w_base+relativepos, (reverse ? e_base : s_base)+relativepos, draw_rowend-draw_rowstart); relativepos += vid.width; } } - else if (*mask == pallen) + else if (m >= (pallen-1)) { // shortcut - memcpy target to work while (draw_linestogo--) { - M_Memcpy(w_base+relativepos, e_base+relativepos, draw_rowend-draw_rowstart); + M_Memcpy(w_base+relativepos, (reverse ? s_base : e_base)+relativepos, draw_rowend-draw_rowstart); relativepos += vid.width; } } else { -#ifdef GENESIS_WIPE + // pointer to transtable that this mask would use + transtbl = transtables + ((9 - m)<s.red) > 34) - { - if (wcolor.s.red < ecolor->s.red) - wcolor.s.red += 34; - else - wcolor.s.red -= 34; - } + if (reverse) + *w++ = fadecolormap[ ( m << 8 ) + *e++ ]; else - { - wcolor.s.red = ecolor->s.red; - - if (abs(wcolor.s.green - ecolor->s.green) > 34) - { - if (wcolor.s.green < ecolor->s.green) - wcolor.s.green += 34; - else - wcolor.s.green -= 34; - } - else - { - wcolor.s.green = ecolor->s.green; - - if (abs(wcolor.s.blue - ecolor->s.blue) > 34) - { - if (wcolor.s.blue < ecolor->s.blue) - wcolor.s.blue += 34; - else - wcolor.s.blue -= 34; - - } - else - wcolor.s.blue = ecolor->s.blue; - } - } + *w++ = fadecolormap[ ( m << 8 ) + *s++ ]; } - - *w++ = NearestColor(wcolor.s.red, wcolor.s.green, wcolor.s.blue); + else + *w++ = transtbl[ ( *e++ << 8 ) + *s++ ]; } relativepos += vid.width; } // END DRAWING LOOP -#else - // pointer to transtable that this mask would use - transtbl = transtables + ((9 - *mask)<= fademask->width) @@ -415,23 +364,36 @@ void F_WipeEndScreen(void) /** After setting up the screens you want to wipe, * calling this will do a 'typical' wipe. */ -void F_RunWipe(UINT8 wipetype, boolean drawMenu) +void F_RunWipe(UINT8 wipetype, boolean drawMenu, const char *colormap, boolean reverse) { #ifdef NOWIPE (void)wipetype; (void)drawMenu; + (void)colormap; + (void)reverse; #else tic_t nowtime; UINT8 wipeframe = 0; fademask_t *fmask; -#ifndef GENESIS_WIPE - pallen = 21; // 21 steps -#else - pallen = 10; // 10 steps -#endif + lumpnum_t clump; + lighttable_t *fcolor = NULL; - paldiv = FixedDiv(257< Date: Thu, 8 Aug 2019 01:43:50 -0400 Subject: [PATCH 34/91] Set new fades, fixed crash upon using non-colormapped fade --- src/f_wipe.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/f_wipe.c b/src/f_wipe.c index 0abef4ca7..a1107e16f 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -51,26 +51,26 @@ UINT8 wipedefs[NUMWIPEDEFS] = { 99, // wipe_credits_intermediate (0) 0, // wipe_level_toblack - UINT8_MAX, // wipe_intermission_toblack + 0, // wipe_intermission_toblack 0, // wipe_voting_toblack, - UINT8_MAX, // wipe_continuing_toblack - 3, // wipe_titlescreen_toblack + 0, // wipe_continuing_toblack + 0, // wipe_titlescreen_toblack 0, // wipe_timeattack_toblack 99, // wipe_credits_toblack 0, // wipe_evaluation_toblack 0, // wipe_gameend_toblack UINT8_MAX, // wipe_intro_toblack (hardcoded) - UINT8_MAX, // wipe_cutscene_toblack (hardcoded) + 99, // wipe_cutscene_toblack (hardcoded) - UINT8_MAX, // wipe_specinter_toblack - UINT8_MAX, // wipe_multinter_toblack - 99, // wipe_speclevel_towhite + 0, // wipe_specinter_toblack + 0, // wipe_multinter_toblack + 0, // wipe_speclevel_towhite - 3, // wipe_level_final + UINT8_MAX, // wipe_level_final 0, // wipe_intermission_final 0, // wipe_voting_final 0, // wipe_continuing_final - 3, // wipe_titlescreen_final + 0, // wipe_titlescreen_final 0, // wipe_timeattack_final 99, // wipe_credits_final 0, // wipe_evaluation_final @@ -376,10 +376,11 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu, const char *colormap, boolean r UINT8 wipeframe = 0; fademask_t *fmask; - lumpnum_t clump; + lumpnum_t clump = LUMPERROR; lighttable_t *fcolor = NULL; - clump = W_GetNumForName(colormap); + if (colormap != NULL) + clump = W_GetNumForName(colormap); if (clump != LUMPERROR && wipetype != UINT8_MAX) { From aad0dbd076890afd1e7877268efab8020ee0dd39 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 10 Aug 2019 00:54:16 -0400 Subject: [PATCH 35/91] Encore invert fade --- src/d_main.c | 7 ---- src/dehacked.c | 32 ++++----------- src/f_finale.h | 12 ++---- src/f_wipe.c | 9 +---- src/p_setup.c | 63 ++++++++++++++++++------------ src/st_stuff.c | 11 ++---- src/v_video.c | 103 ++++++++++++++++++++++++++++++++++++++++++------- src/v_video.h | 3 +- 8 files changed, 147 insertions(+), 93 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index a6bd48e0e..53d32f412 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -308,13 +308,6 @@ static void D_Display(void) wipedefindex = gamestate; // wipe_xxx_toblack if (gamestate == GS_TITLESCREEN && wipegamestate != GS_INTRO) wipedefindex = wipe_timeattack_toblack; - else if (gamestate == GS_INTERMISSION) - { - if (intertype == int_spec) // Special Stage - wipedefindex = wipe_specinter_toblack; - else //if (intertype != int_coop) // Multiplayer - wipedefindex = wipe_multinter_toblack; - } if (rendermode != render_none) { diff --git a/src/dehacked.c b/src/dehacked.c index be45f3f0f..62d99bfe1 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -3256,29 +3256,13 @@ static void readwipes(MYFILE *f) else if (fastcmp(pword, "FINAL")) wipeoffset = wipe_intermission_final; } - else if (fastncmp(word, "SPECINTER_", 10)) - { - pword = word + 10; - if (fastcmp(pword, "TOBLACK")) - wipeoffset = wipe_specinter_toblack; - else if (fastcmp(pword, "FINAL")) - wipeoffset = wipe_specinter_final; - } else if (fastncmp(word, "VOTING_", 7)) { pword = word + 7; if (fastcmp(pword, "TOBLACK")) - wipeoffset = wipe_specinter_toblack; + wipeoffset = wipe_voting_toblack; else if (fastcmp(pword, "FINAL")) - wipeoffset = wipe_specinter_final; - } - else if (fastncmp(word, "MULTINTER_", 10)) - { - pword = word + 10; - if (fastcmp(pword, "TOBLACK")) - wipeoffset = wipe_multinter_toblack; - else if (fastcmp(pword, "FINAL")) - wipeoffset = wipe_multinter_final; + wipeoffset = wipe_voting_final; } else if (fastncmp(word, "CONTINUING_", 11)) { @@ -3330,11 +3314,11 @@ static void readwipes(MYFILE *f) else if (fastcmp(pword, "FINAL")) wipeoffset = wipe_gameend_final; } - else if (fastncmp(word, "SPECLEVEL_", 10)) + else if (fastncmp(word, "ENCORE_", 7)) { - pword = word + 10; - if (fastcmp(pword, "TOWHITE")) - wipeoffset = wipe_speclevel_towhite; + pword = word + 7; + if (fastcmp(pword, "TOINVERT")) + wipeoffset = wipe_encore_toinvert; } if (wipeoffset < 0) @@ -3344,10 +3328,10 @@ static void readwipes(MYFILE *f) } if (value == UINT8_MAX - && (wipeoffset <= wipe_level_toblack || wipeoffset >= wipe_speclevel_towhite)) + && (wipeoffset <= wipe_level_toblack || wipeoffset >= wipe_encore_toinvert)) { // Cannot disable non-toblack wipes - // (or the level toblack wipe, or the special towhite wipe) + // (or the level toblack wipe, or the special encore wipe) deh_warning("Wipes: can't disable wipe of type '%s'", word); continue; } diff --git a/src/f_finale.h b/src/f_finale.h index a6fccf888..b7a7f3c76 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -80,6 +80,7 @@ enum { wipe_credits_intermediate, // makes a good 0 I guess. + // Gamestate wipes wipe_level_toblack, wipe_intermission_toblack, wipe_voting_toblack, @@ -92,11 +93,10 @@ enum wipe_intro_toblack, wipe_cutscene_toblack, - // custom intermissions - wipe_specinter_toblack, - wipe_multinter_toblack, - wipe_speclevel_towhite, + // Specialized wipes + wipe_encore_toinvert, + // "From black" wipes wipe_level_final, wipe_intermission_final, wipe_voting_final, @@ -109,10 +109,6 @@ enum wipe_intro_final, wipe_cutscene_final, - // custom intermissions - wipe_specinter_final, - wipe_multinter_final, - NUMWIPEDEFS, WIPEFINALSHIFT = wipe_level_final - wipe_level_toblack }; diff --git a/src/f_wipe.c b/src/f_wipe.c index a1107e16f..c7f0f8e04 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -62,9 +62,7 @@ UINT8 wipedefs[NUMWIPEDEFS] = { UINT8_MAX, // wipe_intro_toblack (hardcoded) 99, // wipe_cutscene_toblack (hardcoded) - 0, // wipe_specinter_toblack - 0, // wipe_multinter_toblack - 0, // wipe_speclevel_towhite + 72, // wipe_encore_toinvert UINT8_MAX, // wipe_level_final 0, // wipe_intermission_final @@ -76,10 +74,7 @@ UINT8 wipedefs[NUMWIPEDEFS] = { 0, // wipe_evaluation_final 0, // wipe_gameend_final 99, // wipe_intro_final (hardcoded) - 99, // wipe_cutscene_final (hardcoded) - - 0, // wipe_specinter_final - 0 // wipe_multinter_final + 99 // wipe_cutscene_final (hardcoded) }; //-------------------------------------------------------------------------- diff --git a/src/p_setup.c b/src/p_setup.c index 0edd899c6..1952404c9 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2778,7 +2778,7 @@ boolean P_SetupLevel(boolean skipprecip) // use gamemap to get map number. // 99% of the things already did, so. // Map header should always be in place at this point - INT32 i, loadprecip = 1, ranspecialwipe = 0; + INT32 i, loadprecip = 1; INT32 loademblems = 1; INT32 fromnetsave = 0; boolean loadedbm = false; @@ -2857,36 +2857,50 @@ boolean P_SetupLevel(boolean skipprecip) S_StartSound(NULL, sfx_ruby1); + // Fade to an inverted screen, with a circle fade... F_WipeStartScreen(); - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 209); + V_EncoreInvertScreen(); F_WipeEndScreen(); - F_RunWipe(wipedefs[wipe_speclevel_towhite], false, NULL, false); + F_RunWipe(wipedefs[wipe_encore_toinvert], false, NULL, false); + + // Hold on invert for extra effect. + // (This define might be useful for other areas of code? Not sure) +#define WAIT(timetowait) \ + locstarttime = nowtime = lastwipetic; \ + endtime = locstarttime + timetowait; \ + while (nowtime < endtime) \ + { \ + while (!((nowtime = I_GetTime()) - lastwipetic)) \ + I_Sleep(); \ + lastwipetic = nowtime; \ + if (moviemode) \ + M_SaveFrame(); \ + NetKeepAlive(); \ + } \ + + WAIT((3*TICRATE)/2); + S_StartSound(NULL, sfx_ruby2); + + // Then fade to a white screen F_WipeStartScreen(); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0); - F_WipeEndScreen(); - F_RunWipe(wipedefs[wipe_level_final], false, "FADEMAP1", false); - locstarttime = nowtime = lastwipetic; - endtime = locstarttime + (3*TICRATE)/2; + F_RunWipe(wipedefs[wipe_level_toblack], false, "FADEMAP1", false); - // Hold on white for extra effect. - while (nowtime < endtime) - { - // wait loop - while (!((nowtime = I_GetTime()) - lastwipetic)) - I_Sleep(); - lastwipetic = nowtime; - if (moviemode) // make sure we save frames for the white hold too - M_SaveFrame(); + // THEN fade to a black screen. + F_WipeStartScreen(); - // Keep the network alive - NetKeepAlive(); - } + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); + F_WipeEndScreen(); - ranspecialwipe = 1; + F_RunWipe(wipedefs[wipe_level_toblack], false, "FADEMAP0", false); + + // Wait a bit longer. + WAIT((3*TICRATE)/4); } // Make sure all sounds are stopped before Z_FreeTags. @@ -2897,17 +2911,18 @@ boolean P_SetupLevel(boolean skipprecip) // We should be fine starting it here. S_Start(); - levelfadecol = (encoremode && !ranspecialwipe ? 209 : 0); + levelfadecol = (encoremode ? 0 : 31); // Let's fade to white here // But only if we didn't do the encore startup wipe - if (rendermode != render_none && !ranspecialwipe && !demo.rewinding) + if (rendermode != render_none && !demo.rewinding) { F_WipeStartScreen(); - V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); + V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); F_WipeEndScreen(); - F_RunWipe(wipedefs[(encoremode ? wipe_level_final : wipe_level_toblack)], false, "FADEMAP1", false); // Fading to white + + F_RunWipe(wipedefs[wipe_level_toblack], false, ((levelfadecol == 0) ? "FADEMAP1" : "FADEMAP0"), false); } // Reset the palette now all fades have been done diff --git a/src/st_stuff.c b/src/st_stuff.c index e59846aed..caed81f3e 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -2134,12 +2134,7 @@ void ST_Drawer(void) ST_MayonakaStatic(); } - // Draw a white fade on level opening - if (timeinmap < 15) - { - if (timeinmap <= 5) - V_DrawFill(0,0,BASEVIDWIDTH,BASEVIDHEIGHT,0); // Pure white on first few frames, to hide SRB2's awful level load artifacts - else - V_DrawFadeScreen(0, 15-timeinmap); // Then gradually fade out from there - } + // Draw a fade on level opening + if (timeinmap < 16) + V_DrawCustomFadeScreen(((levelfadecol == 0) ? "FADEMAP1" : "FADEMAP0"), 32-(timeinmap*2)); // Then gradually fade out from there } diff --git a/src/v_video.c b/src/v_video.c index 1b1d03baa..297eae9c4 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1287,28 +1287,75 @@ void V_DrawVhsEffect(boolean rewind) void V_DrawFadeScreen(UINT16 color, UINT8 strength) { #ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none) - { - HWR_FadeScreenMenuBack(color, strength); - return; - } + if (rendermode != render_soft && rendermode != render_none) + { + HWR_FadeScreenMenuBack(color, strength); + return; + } #endif - { - const UINT8 *fadetable = + { + const UINT8 *fadetable = (color > 0xFFF0) // Grab a specific colormap palette? ? R_GetTranslationColormap(color | 0xFFFF0000, strength, GTC_CACHE) : ((color & 0xFF00) // Color is not palette index? ? ((UINT8 *)colormaps + strength*256) // Do COLORMAP fade. : ((UINT8 *)transtables + ((9-strength)< Date: Sat, 10 Aug 2019 01:59:23 -0400 Subject: [PATCH 36/91] Encore wiggle --- src/d_main.c | 4 ++-- src/f_finale.c | 8 ++++---- src/f_finale.h | 2 +- src/f_wipe.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- src/p_setup.c | 8 ++++---- 5 files changed, 60 insertions(+), 12 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 53d32f412..1295722d0 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -318,7 +318,7 @@ static void D_Display(void) F_WipeStartScreen(); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); F_WipeEndScreen(); - F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK, "FADEMAP0", false); + F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK, "FADEMAP0", false, false); } if (gamestate != GS_LEVEL && rendermode != render_none) @@ -549,7 +549,7 @@ static void D_Display(void) if (rendermode != render_none) { F_WipeEndScreen(); - F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK, "FADEMAP0", true); + F_RunWipe(wipedefs[wipedefindex], gamestate != GS_TIMEATTACK, "FADEMAP0", true, false); } } diff --git a/src/f_finale.c b/src/f_finale.c index d45a9cfa9..7ea2e08a7 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -220,7 +220,7 @@ void F_StartIntro(void) F_WipeStartScreen(); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); F_WipeEndScreen(); - F_RunWipe(wipedefs[wipe_level_final], false, "FADEMAP0", false); + F_RunWipe(wipedefs[wipe_level_final], false, "FADEMAP0", false, false); } if (introtoplay) @@ -306,7 +306,7 @@ void F_IntroDrawer(void) F_WipeStartScreen(); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); F_WipeEndScreen(); - F_RunWipe(99, true, "FADEMAP0", false); + F_RunWipe(99, true, "FADEMAP0", false, false); } // Stay on black for a bit. =) @@ -1420,7 +1420,7 @@ void F_CutsceneDrawer(void) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, cutscenes[cutnum]->scene[scenenum].fadecolor); F_WipeEndScreen(); - F_RunWipe(cutscenes[cutnum]->scene[scenenum].fadeinid, true, NULL, false); + F_RunWipe(cutscenes[cutnum]->scene[scenenum].fadeinid, true, NULL, false, false); F_WipeStartScreen(); } @@ -1440,7 +1440,7 @@ void F_CutsceneDrawer(void) if (dofadenow && rendermode != render_none) { F_WipeEndScreen(); - F_RunWipe(cutscenes[cutnum]->scene[scenenum].fadeoutid, true, NULL, false); + F_RunWipe(cutscenes[cutnum]->scene[scenenum].fadeoutid, true, NULL, false, false); } V_DrawString(textxpos, textypos, 0, cutscene_disptext); diff --git a/src/f_finale.h b/src/f_finale.h index b7a7f3c76..d2231b8d0 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -74,7 +74,7 @@ extern INT32 lastwipetic; void F_WipeStartScreen(void); void F_WipeEndScreen(void); -void F_RunWipe(UINT8 wipetype, boolean drawMenu, const char *colormap, boolean reverse); +void F_RunWipe(UINT8 wipetype, boolean drawMenu, const char *colormap, boolean reverse, boolean encorewiggle); enum { diff --git a/src/f_wipe.c b/src/f_wipe.c index c7f0f8e04..e6d961c4d 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -356,10 +356,55 @@ void F_WipeEndScreen(void) #endif } +/** Wiggle post processor for encore wipes + */ +static void F_DoEncoreWiggle(UINT8 time) +{ + UINT8 *tmpscr = wipe_scr_start; + UINT8 *srcscr = wipe_scr; + angle_t disStart = (time * 128) & FINEMASK; + INT32 y, sine, newpix, scanline; + + for (y = 0; y < vid.height; y++) + { + sine = (FINESINE(disStart) * (time*12))>>FRACBITS; + scanline = y / vid.dupy; + if (scanline & 1) + sine = -sine; + newpix = abs(sine); + + if (sine < 0) + { + M_Memcpy(&tmpscr[(y*vid.width)+newpix], &srcscr[(y*vid.width)], vid.width-newpix); + + // Cleanup edge + while (newpix) + { + tmpscr[(y*vid.width)+newpix] = srcscr[(y*vid.width)]; + newpix--; + } + } + else + { + M_Memcpy(&tmpscr[(y*vid.width)], &srcscr[(y*vid.width) + sine], vid.width-newpix); + + // Cleanup edge + while (newpix) + { + tmpscr[(y*vid.width) + vid.width - newpix] = srcscr[(y*vid.width) + (vid.width-1)]; + newpix--; + } + } + + disStart += (time*8); //the offset into the displacement map, increment each game loop + disStart &= FINEMASK; //clip it to FINEMASK + } +} + /** After setting up the screens you want to wipe, * calling this will do a 'typical' wipe. */ -void F_RunWipe(UINT8 wipetype, boolean drawMenu, const char *colormap, boolean reverse) +void F_RunWipe(UINT8 wipetype, boolean drawMenu, const char *colormap, boolean reverse, boolean encorewiggle) { #ifdef NOWIPE (void)wipetype; @@ -415,6 +460,9 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu, const char *colormap, boolean r else #endif F_DoWipe(fmask, fcolor, reverse); + if (encorewiggle) + F_DoEncoreWiggle(wipeframe); + I_OsPolling(); I_UpdateNoBlit(); diff --git a/src/p_setup.c b/src/p_setup.c index 1952404c9..e40602039 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2863,7 +2863,7 @@ boolean P_SetupLevel(boolean skipprecip) V_EncoreInvertScreen(); F_WipeEndScreen(); - F_RunWipe(wipedefs[wipe_encore_toinvert], false, NULL, false); + F_RunWipe(wipedefs[wipe_encore_toinvert], false, NULL, false, false); // Hold on invert for extra effect. // (This define might be useful for other areas of code? Not sure) @@ -2889,7 +2889,7 @@ boolean P_SetupLevel(boolean skipprecip) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0); F_WipeEndScreen(); - F_RunWipe(wipedefs[wipe_level_toblack], false, "FADEMAP1", false); + F_RunWipe(99, false, "FADEMAP1", false, true); // wiggle the screen during this! // THEN fade to a black screen. F_WipeStartScreen(); @@ -2897,7 +2897,7 @@ boolean P_SetupLevel(boolean skipprecip) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); F_WipeEndScreen(); - F_RunWipe(wipedefs[wipe_level_toblack], false, "FADEMAP0", false); + F_RunWipe(wipedefs[wipe_level_toblack], false, "FADEMAP0", false, false); // Wait a bit longer. WAIT((3*TICRATE)/4); @@ -2922,7 +2922,7 @@ boolean P_SetupLevel(boolean skipprecip) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol); F_WipeEndScreen(); - F_RunWipe(wipedefs[wipe_level_toblack], false, ((levelfadecol == 0) ? "FADEMAP1" : "FADEMAP0"), false); + F_RunWipe(wipedefs[wipe_level_toblack], false, ((levelfadecol == 0) ? "FADEMAP1" : "FADEMAP0"), false, false); } // Reset the palette now all fades have been done From 71f35c7f5b7cea1fbc86d8699eb52088bde02735 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 10 Aug 2019 02:07:18 -0400 Subject: [PATCH 37/91] Add encore_towhite --- src/dehacked.c | 2 ++ src/f_finale.h | 1 + src/f_wipe.c | 1 + src/p_setup.c | 2 +- 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/dehacked.c b/src/dehacked.c index 62d99bfe1..a1330343b 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -3319,6 +3319,8 @@ static void readwipes(MYFILE *f) pword = word + 7; if (fastcmp(pword, "TOINVERT")) wipeoffset = wipe_encore_toinvert; + else if (fastcmp(pword, "TOWHITE")) + wipeoffset = wipe_encore_towhite; } if (wipeoffset < 0) diff --git a/src/f_finale.h b/src/f_finale.h index d2231b8d0..d1efa6ce2 100644 --- a/src/f_finale.h +++ b/src/f_finale.h @@ -95,6 +95,7 @@ enum // Specialized wipes wipe_encore_toinvert, + wipe_encore_towhite, // "From black" wipes wipe_level_final, diff --git a/src/f_wipe.c b/src/f_wipe.c index e6d961c4d..c4064eec5 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -63,6 +63,7 @@ UINT8 wipedefs[NUMWIPEDEFS] = { 99, // wipe_cutscene_toblack (hardcoded) 72, // wipe_encore_toinvert + 99, // wipe_encore_towhite UINT8_MAX, // wipe_level_final 0, // wipe_intermission_final diff --git a/src/p_setup.c b/src/p_setup.c index e40602039..4452dfe4c 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2889,7 +2889,7 @@ boolean P_SetupLevel(boolean skipprecip) V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 0); F_WipeEndScreen(); - F_RunWipe(99, false, "FADEMAP1", false, true); // wiggle the screen during this! + F_RunWipe(wipedefs[wipe_encore_towhite], false, "FADEMAP1", false, true); // wiggle the screen during this! // THEN fade to a black screen. F_WipeStartScreen(); From 978c4f7e24bfdb326fa77c461cd7cf2dd16dc4b1 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 10 Aug 2019 09:50:42 -0400 Subject: [PATCH 38/91] Minor fixes --- src/f_finale.c | 2 +- src/f_wipe.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/f_finale.c b/src/f_finale.c index 7ea2e08a7..c620c3ffd 100644 --- a/src/f_finale.c +++ b/src/f_finale.c @@ -220,7 +220,7 @@ void F_StartIntro(void) F_WipeStartScreen(); V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); F_WipeEndScreen(); - F_RunWipe(wipedefs[wipe_level_final], false, "FADEMAP0", false, false); + F_RunWipe(wipedefs[wipe_intro_toblack], false, "FADEMAP0", false, false); } if (introtoplay) diff --git a/src/f_wipe.c b/src/f_wipe.c index c4064eec5..c50afcd21 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -412,6 +412,7 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu, const char *colormap, boolean r (void)drawMenu; (void)colormap; (void)reverse; + (void)encorewiggle; #else tic_t nowtime; UINT8 wipeframe = 0; @@ -462,7 +463,7 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu, const char *colormap, boolean r #endif F_DoWipe(fmask, fcolor, reverse); if (encorewiggle) - F_DoEncoreWiggle(wipeframe); + F_DoEncoreWiggle(wipeframe); // Can't think of a better way to run this on fades, unfortunately. I_OsPolling(); I_UpdateNoBlit(); From 780202668b0ff1f515fe0e8d6a2ae9f6707f602f Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 11 Aug 2019 15:35:38 -0400 Subject: [PATCH 39/91] Only run Encore wiggle in software --- src/f_wipe.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/f_wipe.c b/src/f_wipe.c index c50afcd21..319d2b2f4 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -462,8 +462,12 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu, const char *colormap, boolean r else #endif F_DoWipe(fmask, fcolor, reverse); + +#ifndef HWRENDER if (encorewiggle) F_DoEncoreWiggle(wipeframe); // Can't think of a better way to run this on fades, unfortunately. +#endif + I_OsPolling(); I_UpdateNoBlit(); From 54066cc9fcf8dec108f1664bf8a1f67d46dbb2c6 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 22 Sep 2019 22:44:15 -0400 Subject: [PATCH 40/91] compile --- src/k_kart.c | 10 ++++++---- src/p_mobj.c | 6 +++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index ea64da8ea..dcd3c1c83 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8964,8 +8964,10 @@ static void K_drawKartMinimap(void) // hu_stuff needs this, unlike st_stuff. if (gamestate != GS_LEVEL) return; - - if (stplyr != &players[displayplayer]) + + // Only draw for the first player + // Maybe move this somewhere else where this won't be a concern? + if (stplyr != &players[displayplayers[0]]) return; lumpnum = W_CheckNumForName(va("%sR", G_BuildMapName(gamemap))); @@ -9066,7 +9068,7 @@ static void K_drawKartMinimap(void) if (!players[i].mo || players[i].spectator) continue; - if (i != displayplayer || splitscreen) + if (i != displayplayers[0] || splitscreen) { if (G_BattleGametype() && players[i].kartstuff[k_bumper] <= 0) continue; @@ -9080,7 +9082,7 @@ static void K_drawKartMinimap(void) } } - if (i == displayplayer || i == secondarydisplayplayer || i == thirddisplayplayer || i == fourthdisplayplayer) + if (i == displayplayers[0] || i == displayplayers[1] || i == displayplayers[2] || i == displayplayers[3]) { // Draw display players on top of everything else localplayers[numlocalplayers] = i; diff --git a/src/p_mobj.c b/src/p_mobj.c index f98de3003..16f27142e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6464,9 +6464,9 @@ void P_RunBattleOvertime(void) { UINT8 transparency = tr_trans50; - if (!splitscreen && players[displayplayer].mo) + if (!splitscreen && players[displayplayers[0]].mo) { - INT32 dist = P_AproxDistance(battleovertime.x-players[displayplayer].mo->x, battleovertime.y-players[displayplayer].mo->y); + INT32 dist = P_AproxDistance(battleovertime.x-players[displayplayers[0]].mo->x, battleovertime.y-players[displayplayers[0]].mo->y); transparency = max(0, NUMTRANSMAPS - ((256 + (dist>>FRACBITS)) / 256)); } @@ -7131,7 +7131,7 @@ void P_MobjThinker(mobj_t *mobj) mobj->x = mobj->target->x; mobj->y = mobj->target->y; - if (!splitscreen && players[displayplayer].mo) + if (!splitscreen && players[displayplayers[0]].mo) { scale = mobj->target->scale + FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayers[0]].mo->x-mobj->target->x, players[displayplayers[0]].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale); From 932f8a1f618ee5c386714da9b13588db85e7f520 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 23 Sep 2019 07:03:00 -0400 Subject: [PATCH 41/91] Update demos to save power levels --- src/doomdef.h | 3 - src/g_game.c | 346 ++++++-------------------------------------------- src/p_tick.c | 45 ++----- 3 files changed, 51 insertions(+), 343 deletions(-) diff --git a/src/doomdef.h b/src/doomdef.h index 4d3934773..ba3810858 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -158,9 +158,6 @@ extern FILE *logstream; // AND appveyor.yml, for the build bots! #endif -// Maintain compatibility with 1.0.x record attack replays? -#define DEMO_COMPAT_100 - // Does this version require an added patch file? // Comment or uncomment this as necessary. //#define USE_PATCH_FILE diff --git a/src/g_game.c b/src/g_game.c index 12b3a23b3..3c5cb33f6 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4776,7 +4776,7 @@ char *G_BuildMapTitle(INT32 mapnum) // DEMO RECORDING // -#define DEMOVERSION 0x0002 +#define DEMOVERSION 0x0003 #define DEMOHEADER "\xF0" "KartReplay" "\x0F" #define DF_GHOST 0x01 // This demo contains ghost data too! @@ -4787,12 +4787,6 @@ char *G_BuildMapTitle(INT32 mapnum) #define DF_ENCORE 0x40 #define DF_MULTIPLAYER 0x80 // This demo was recorded in multiplayer mode! -#ifdef DEMO_COMPAT_100 -#define DF_FILELIST 0x08 // This demo contains an extra files list -#define DF_GAMETYPEMASK 0x30 -#define DF_GAMESHIFT 4 -#endif - #define DEMO_SPECTATOR 0x40 // For demos @@ -5651,16 +5645,9 @@ void G_ConsGhostTic(INT32 playernum) else ghostext[playernum].desyncframes = 0; - if ( -#ifdef DEMO_COMPAT_100 - demo.version != 0x0001 && -#endif - ( - players[playernum].kartstuff[k_itemtype] != ghostext[playernum].kartitem || - players[playernum].kartstuff[k_itemamount] != ghostext[playernum].kartamount || - players[playernum].kartstuff[k_bumper] != ghostext[playernum].kartbumpers - ) - ) + if (players[playernum].kartstuff[k_itemtype] != ghostext[playernum].kartitem + || players[playernum].kartstuff[k_itemamount] != ghostext[playernum].kartamount + || players[playernum].kartstuff[k_bumper] != ghostext[playernum].kartbumpers) { if (demosynced) CONS_Alert(CONS_WARNING, M_GetText("Demo playback has desynced!\n")); @@ -5688,10 +5675,6 @@ void G_GhostTicker(void) // Skip normal demo data. UINT8 ziptic = READUINT8(g->p); -#ifdef DEMO_COMPAT_100 - if (g->version != 0x0001) - { -#endif while (ziptic != DW_END) // Get rid of extradata stuff { if (ziptic == 0) // Only support player 0 info for now @@ -5715,9 +5698,6 @@ void G_GhostTicker(void) } ziptic = READUINT8(g->p); // Back to actual ziptic stuff -#ifdef DEMO_COMPAT_100 - } -#endif if (ziptic & ZT_FWD) g->p++; @@ -5737,18 +5717,12 @@ void G_GhostTicker(void) // Grab ghost data. ziptic = READUINT8(g->p); -#ifdef DEMO_COMPAT_100 - if (g->version != 0x0001) - { -#endif if (ziptic == 0xFF) goto skippedghosttic; // Didn't write ghost info this frame else if (ziptic != 0) I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this ziptic = READUINT8(g->p); -#ifdef DEMO_COMPAT_100 - } -#endif + if (ziptic & GZT_XYZ) { g->oldmo.x = READFIXED(g->p); @@ -5889,15 +5863,8 @@ void G_GhostTicker(void) g->p += 12; // kartitem, kartamount, kartbumpers } -#ifdef DEMO_COMPAT_100 - if (g->version != 0x0001) - { -#endif if (READUINT8(g->p) != 0xFF) // Make sure there isn't other ghost data here. I_Error("Ghost is not a record attack ghost"); //@TODO lmao don't blow up like this -#ifdef DEMO_COMPAT_100 - } -#endif skippedghosttic: // Tick ghost colors (Super and Mario Invincibility flashing) @@ -6407,20 +6374,15 @@ void G_BeginRecording(void) switch ((demoflags & DF_ATTACKMASK)>>DF_ATTACKSHIFT) { - case ATTACKING_NONE: // 0 - break; - case ATTACKING_RECORD: // 1 - demotime_p = demo_p; - WRITEUINT32(demo_p,UINT32_MAX); // time - WRITEUINT32(demo_p,UINT32_MAX); // lap - break; - /*case ATTACKING_NIGHTS: // 2 - demotime_p = demo_p; - WRITEUINT32(demo_p,UINT32_MAX); // time - WRITEUINT32(demo_p,0); // score - break;*/ - default: // 3 - break; + case ATTACKING_NONE: // 0 + break; + case ATTACKING_RECORD: // 1 + demotime_p = demo_p; + WRITEUINT32(demo_p,UINT32_MAX); // time + WRITEUINT32(demo_p,UINT32_MAX); // lap + break; + default: // 3 + break; } WRITEUINT32(demo_p,P_GetInitSeed()); @@ -6460,6 +6422,9 @@ void G_BeginRecording(void) // Score, since Kart uses this to determine where you start on the map WRITEUINT32(demo_p, player->score); + // Power Levels + WRITEUINT16(demo_p, clientpowerlevels[p][G_BattleGametype() ? 1 : 0]); + // Kart speed and weight WRITEUINT8(demo_p, skins[player->skin].kartspeed); WRITEUINT8(demo_p, skins[player->skin].kartweight); @@ -6558,18 +6523,13 @@ void G_SetDemoTime(UINT32 ptime, UINT32 plap) { if (!demo.recording || !demotime_p) return; + if (demoflags & DF_RECORDATTACK) { WRITEUINT32(demotime_p, ptime); WRITEUINT32(demotime_p, plap); demotime_p = NULL; } - /*else if (demoflags & DF_NIGHTSATTACK) - { - WRITEUINT32(demotime_p, ptime); - WRITEUINT32(demotime_p, pscore); - demotime_p = NULL; - }*/ } static void G_LoadDemoExtraFiles(UINT8 **pp) @@ -6812,13 +6772,6 @@ UINT8 G_CmpDemoTime(char *oldname, char *newname) case DEMOVERSION: // latest always supported p += 64; // full demo title break; -#ifdef DEMO_COMPAT_100 - case 0x0001: - // Old replays gotta go :] - CONS_Alert(CONS_NOTICE, M_GetText("File '%s' outdated version. It will be overwritten. Nyeheheh.\n"), oldname); - Z_Free(buffer); - return UINT8_MAX; -#endif // too old, cannot support. default: CONS_Alert(CONS_NOTICE, M_GetText("File '%s' invalid format. It will be overwritten.\n"), oldname); @@ -6910,12 +6863,6 @@ void G_LoadDemoInfo(menudemo_t *pdemo) info_p += 64; break; -#ifdef DEMO_COMPAT_100 - case 0x0001: - pdemo->type = MD_OUTDATED; - sprintf(pdemo->title, "Legacy Replay"); - break; -#endif // too old, cannot support. default: CONS_Alert(CONS_ERROR, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemo->filepath); @@ -6950,16 +6897,6 @@ void G_LoadDemoInfo(menudemo_t *pdemo) Z_Free(infobuffer); return; } -#ifdef DEMO_COMPAT_100 - else if (pdemoversion == 0x0001) - { - CONS_Alert(CONS_ERROR, M_GetText("%s is a legacy multiplayer replay and cannot be played.\n"), pdemo->filepath); - pdemo->type = MD_INVALID; - sprintf(pdemo->title, "INVALID REPLAY"); - Z_Free(infobuffer); - return; - } -#endif pdemo->gametype = READUINT8(info_p); @@ -7160,10 +7097,6 @@ void G_DoPlayDemo(char *defdemoname) demo_p += 64; break; -#ifdef DEMO_COMPAT_100 - case 0x0001: - break; -#endif // too old, cannot support. default: snprintf(msg, 1024, M_GetText("%s is an incompatible replay format and cannot be played.\n"), pdemoname); @@ -7192,24 +7125,6 @@ void G_DoPlayDemo(char *defdemoname) demo_p += 16; // mapmd5 demoflags = READUINT8(demo_p); -#ifdef DEMO_COMPAT_100 - if (demo.version == 0x0001) - { - if (demoflags & DF_MULTIPLAYER) - { - snprintf(msg, 1024, M_GetText("%s is an alpha multiplayer replay and cannot be played.\n"), pdemoname); - CONS_Alert(CONS_ERROR, "%s", msg); - M_StartMessage(msg, NULL, MM_NOTHING); - Z_Free(pdemoname); - Z_Free(demobuffer); - demo.playback = false; - demo.title = false; - return; - } - } - else - { -#endif gametype = READUINT8(demo_p); if (demo.title) // Titledemos should always play and ought to always be compatible with whatever wadlist is running. @@ -7267,9 +7182,6 @@ void G_DoPlayDemo(char *defdemoname) return; } } -#ifdef DEMO_COMPAT_100 - } -#endif modeattacking = (demoflags & DF_ATTACKMASK)>>DF_ATTACKSHIFT; multiplayer = !!(demoflags & DF_MULTIPLAYER); @@ -7297,110 +7209,8 @@ void G_DoPlayDemo(char *defdemoname) // Random seed randseed = READUINT32(demo_p); -#ifdef DEMO_COMPAT_100 - if (demo.version != 0x0001) -#endif demo_p += 4; // Extrainfo location -#ifdef DEMO_COMPAT_100 - if (demo.version == 0x0001) - { - // Player name - M_Memcpy(player_names[0],demo_p,16); - demo_p += 16; - - // Skin - M_Memcpy(skin,demo_p,16); - demo_p += 16; - - // Color - M_Memcpy(color,demo_p,16); - demo_p += 16; - - demo_p += 5; // Backwards compat - some stats - // SRB2kart - kartspeed[0] = READUINT8(demo_p); - kartweight[0] = READUINT8(demo_p); - // - demo_p += 9; // Backwards compat - more stats - - // Skin not loaded? - if (!SetPlayerSkin(0, skin)) - { - snprintf(msg, 1024, M_GetText("%s features a character that is not currently loaded.\n"), pdemoname); - CONS_Alert(CONS_ERROR, "%s", msg); - M_StartMessage(msg, NULL, MM_NOTHING); - Z_Free(pdemoname); - Z_Free(demobuffer); - demo.playback = false; - demo.title = false; - return; - } - - // ...*map* not loaded? - if (!gamemap || (gamemap > NUMMAPS) || !mapheaderinfo[gamemap-1] || !(mapheaderinfo[gamemap-1]->menuflags & LF2_EXISTSHACK)) - { - snprintf(msg, 1024, M_GetText("%s features a course that is not currently loaded.\n"), pdemoname); - CONS_Alert(CONS_ERROR, "%s", msg); - M_StartMessage(msg, NULL, MM_NOTHING); - Z_Free(pdemoname); - Z_Free(demobuffer); - demo.playback = false; - demo.title = false; - return; - } - - // Set color - for (i = 0; i < MAXSKINCOLORS; i++) - if (!stricmp(KartColor_Names[i],color)) // SRB2kart - { - players[0].skincolor = i; - break; - } - - // net var data - CV_LoadNetVars(&demo_p); - - // Sigh ... it's an empty demo. - if (*demo_p == DEMOMARKER) - { - snprintf(msg, 1024, M_GetText("%s contains no data to be played.\n"), pdemoname); - CONS_Alert(CONS_ERROR, "%s", msg); - M_StartMessage(msg, NULL, MM_NOTHING); - Z_Free(pdemoname); - Z_Free(demobuffer); - demo.playback = false; - demo.title = false; - return; - } - - Z_Free(pdemoname); - - memset(&oldcmd,0,sizeof(oldcmd)); - memset(&oldghost,0,sizeof(oldghost)); - memset(&ghostext,0,sizeof(ghostext)); - - CONS_Alert(CONS_WARNING, M_GetText("Demo version does not match game version. Desyncs may occur.\n")); - - // console warning messages -#if defined(SKIPERRORS) && !defined(DEVELOP) - demosynced = (!skiperrors); -#else - demosynced = true; -#endif - - // didn't start recording right away. - demo.deferstart = false; - - consoleplayer = 0; - memset(displayplayers, 0, sizeof(displayplayers)); - memset(playeringame, 0, sizeof(playeringame)); - playeringame[0] = true; - - goto post_compat; - } -#endif - // net var data CV_LoadNetVars(&demo_p); @@ -7514,6 +7324,9 @@ void G_DoPlayDemo(char *defdemoname) // Score, since Kart uses this to determine where you start on the map players[p].score = READUINT32(demo_p); + // Power Levels + clientpowerlevels[p][G_BattleGametype() ? 1 : 0] = READUINT16(demo_p); + // Kart stats, temporarily kartspeed[p] = READUINT8(demo_p); kartweight[p] = READUINT8(demo_p); @@ -7538,10 +7351,6 @@ void G_DoPlayDemo(char *defdemoname) R_ExecuteSetViewSize(); -#ifdef DEMO_COMPAT_100 -post_compat: -#endif - P_SetRandSeed(randseed); G_InitNew(demoflags & DF_ENCORE, G_BuildMapName(gamemap), true, true); // Doesn't matter whether you reset or not here, given changes to resetplayer. @@ -7632,10 +7441,6 @@ void G_AddGhost(char *defdemoname) case DEMOVERSION: // latest always supported p += 64; // title break; -#ifdef DEMO_COMPAT_100 - case 0x0001: - break; -#endif // too old, cannot support. default: CONS_Alert(CONS_NOTICE, M_GetText("Ghost %s: Demo version incompatible.\n"), pdemoname); @@ -7676,15 +7481,9 @@ void G_AddGhost(char *defdemoname) return; } -#ifdef DEMO_COMPAT_100 - if (ghostversion != 0x0001) -#endif - p++; // gametype + p++; // gametype + G_SkipDemoExtraFiles(&p); // Don't wanna modify the file list for ghosts. -#ifdef DEMO_COMPAT_100 - if (ghostversion != 0x0001) -#endif - G_SkipDemoExtraFiles(&p); // Don't wanna modify the file list for ghosts. switch ((flags & DF_ATTACKMASK)>>DF_ATTACKSHIFT) { case ATTACKING_NONE: // 0 @@ -7700,41 +7499,6 @@ void G_AddGhost(char *defdemoname) } p += 4; // random seed - -#ifdef DEMO_COMPAT_100 - if (ghostversion == 0x0001) - { - // Player name (TODO: Display this somehow if it doesn't match cv_playername!) - M_Memcpy(name, p,16); - p += 16; - - // Skin - M_Memcpy(skin, p,16); - p += 16; - - // Color - M_Memcpy(color, p,16); - p += 16; - - // Ghosts do not have a player structure to put this in. - p++; // charability - p++; // charability2 - p++; // actionspd - p++; // mindash - p++; // maxdash - // SRB2kart - p++; // kartspeed - p++; // kartweight - // - p++; // normalspeed - p++; // runspeed - p++; // thrustfactor - p++; // accelstart - p++; // acceleration - p += 4; // jumpfactor - } - else -#endif p += 4; // Extra data location reference // net var data @@ -7754,10 +7518,6 @@ void G_AddGhost(char *defdemoname) return; } -#ifdef DEMO_COMPAT_100 - if (ghostversion != 0x0001) - { -#endif if (READUINT8(p) != 0) { CONS_Alert(CONS_NOTICE, M_GetText("Failed to add ghost %s: Invalid player slot.\n"), pdemoname); @@ -7779,6 +7539,7 @@ void G_AddGhost(char *defdemoname) p += 16; p += 4; // score + p += 2; // powerlevel kartspeed = READUINT8(p); kartweight = READUINT8(p); @@ -7790,9 +7551,6 @@ void G_AddGhost(char *defdemoname) Z_Free(buffer); return; } -#ifdef DEMO_COMPAT_100 - } -#endif for (i = 0; i < numskins; i++) if (!stricmp(skins[i].name,skin)) @@ -7892,18 +7650,13 @@ void G_UpdateStaffGhostName(lumpnum_t l) ghostversion = READUINT16(p); switch(ghostversion) { - case DEMOVERSION: // latest always supported - p += 64; // full demo title - break; + case DEMOVERSION: // latest always supported + p += 64; // full demo title + break; -#ifdef DEMO_COMPAT_100 - case 0x0001: - break; -#endif - - // too old, cannot support. - default: - goto fail; + // too old, cannot support. + default: + goto fail; } p += 16; // demo checksum @@ -7923,43 +7676,22 @@ void G_UpdateStaffGhostName(lumpnum_t l) goto fail; // we don't NEED to do it here, but whatever } -#ifdef DEMO_COMPAT_100 - if (ghostversion != 0x0001) -#endif p++; // Gametype -#ifdef DEMO_COMPAT_100 - if (ghostversion != 0x0001) -#endif G_SkipDemoExtraFiles(&p); switch ((flags & DF_ATTACKMASK)>>DF_ATTACKSHIFT) { - case ATTACKING_NONE: // 0 - break; - case ATTACKING_RECORD: // 1 - p += 8; // demo time, lap - break; - /*case ATTACKING_NIGHTS: // 2 - p += 8; // demo time left, score - break;*/ - default: // 3 - break; + case ATTACKING_NONE: // 0 + break; + case ATTACKING_RECORD: // 1 + p += 8; // demo time, lap + break; + default: // 3 + break; } p += 4; // random seed - - -#ifdef DEMO_COMPAT_100 - if (ghostversion == 0x0001) - { - // Player name - M_Memcpy(dummystaffname, p,16); - dummystaffname[16] = '\0'; - goto fail; // Not really a failure but whatever - } -#endif - p += 4; // Extrainfo location marker // Ehhhh don't need ghostversion here (?) so I'll reuse the var here @@ -8044,10 +7776,6 @@ void G_DoPlayMetal(void) { case DEMOVERSION: // latest always supported break; -#ifdef DEMO_COMPAT_100 - case 0x0001: - I_Error("You need to implement demo compat here, doofus! %s:%d", __FILE__, __LINE__); -#endif // too old, cannot support. default: CONS_Alert(CONS_WARNING, M_GetText("Failed to load bot recording for this map, format version incompatible.\n")); diff --git a/src/p_tick.c b/src/p_tick.c index 2502c7213..8312afe81 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -617,33 +617,21 @@ void P_Ticker(boolean run) } if (demo.playback) { + G_ReadDemoExtraData(); + for (i = 0; i < MAXPLAYERS; i++) + if (playeringame[i]) + { + //@TODO all this throwdir stuff shouldn't be here! But it's added to maintain 1.0.4 compat for now... + // Remove for 1.1! + if (players[i].cmd.buttons & BT_FORWARD) + players[i].kartstuff[k_throwdir] = 1; + else if (players[i].cmd.buttons & BT_BACKWARD) + players[i].kartstuff[k_throwdir] = -1; + else + players[i].kartstuff[k_throwdir] = 0; -#ifdef DEMO_COMPAT_100 - if (demo.version == 0x0001) - { - G_ReadDemoTiccmd(&players[consoleplayer].cmd, 0); - } - else - { -#endif - G_ReadDemoExtraData(); - for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i]) - { - //@TODO all this throwdir stuff shouldn't be here! But it's added to maintain 1.0.4 compat for now... - // Remove for 1.1! - if (players[i].cmd.buttons & BT_FORWARD) - players[i].kartstuff[k_throwdir] = 1; - else if (players[i].cmd.buttons & BT_BACKWARD) - players[i].kartstuff[k_throwdir] = -1; - else - players[i].kartstuff[k_throwdir] = 0; - - G_ReadDemoTiccmd(&players[i].cmd, i); - } -#ifdef DEMO_COMPAT_100 - } -#endif + G_ReadDemoTiccmd(&players[i].cmd, i); + } } for (i = 0; i < MAXPLAYERS; i++) @@ -759,11 +747,6 @@ void P_Ticker(boolean run) } else if (demo.playback) // Use Ghost data for consistency checks. { -#ifdef DEMO_COMPAT_100 - if (demo.version == 0x0001) - G_ConsGhostTic(0); - else -#endif G_ConsAllGhostTics(); } From 9e587f4d0d4a09a27ac6c748e2e872f881149eea Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 23 Sep 2019 07:26:36 -0400 Subject: [PATCH 42/91] Put prints behind CONS_Debug --- src/d_clisrv.c | 2 +- src/d_netcmd.c | 3 ++- src/y_inter.c | 28 ++++++++++++++-------------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 9e1f46e5a..a4e5e4968 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3478,7 +3478,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) newplayernum = (UINT8)READUINT8(*p); splitscreenplayer = (UINT8)READUINT8(*p); - CONS_Printf("addplayer: %d %d %d\n", node, newplayernum, splitscreenplayer); + CONS_Debug(DBG_NETPLAY, "addplayer: %d %d %d\n", node, newplayernum, splitscreenplayer); // Clear player before joining, lest some things get set incorrectly CL_ClearPlayer(newplayernum); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 37d91a765..3569bca24 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1938,7 +1938,8 @@ static void Got_PowerLevel(UINT8 **cp,INT32 playernum) clientpowerlevels[playernum][0] = min(9999, race); clientpowerlevels[playernum][1] = min(9999, battle); - CONS_Printf("set player %d to power %d\n", playernum, race); + + CONS_Debug(DBG_GAMELOGIC, "set player %d to power %d\n", playernum, race); } void D_SendPlayerConfig(void) diff --git a/src/y_inter.c b/src/y_inter.c index 5558de011..7dc97559b 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -356,13 +356,13 @@ static void Y_UpdatePowerLevels(void) UINT8 ipnum = data.match.num[i]; UINT8 jpnum; - CONS_Printf("Power Level Gain for player %d:\n", ipnum); + CONS_Debug(DBG_GAMELOGIC, "Power Level Gain for player %d:\n", ipnum); if (clientpowerlevels[ipnum][powertype] == 0) // splitscreen guests don't record power level changes continue; yourpower = clientpowerlevels[ipnum][powertype]; - CONS_Printf("Player %d's PWR.LV: %d\n", ipnum, yourpower); + CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", ipnum, yourpower); for (j = 0; j < numplayersingame; j++) { @@ -373,18 +373,18 @@ static void Y_UpdatePowerLevels(void) if (i == j || ipnum == jpnum) // Same person continue; - CONS_Printf("Player %d VS Player %d:\n", ipnum, jpnum); + CONS_Debug(DBG_GAMELOGIC, "Player %d VS Player %d:\n", ipnum, jpnum); if (data.match.val[i] == data.match.val[j]) // Tie -- neither get any points for this match up. { - CONS_Printf("TIE, no change.\n"); + CONS_Debug(DBG_GAMELOGIC, "TIE, no change.\n"); continue; } theirpower = 5000; if (clientpowerlevels[jpnum][powertype] != 0) // No power level acts as 5000 (used for splitscreen guests) theirpower = clientpowerlevels[jpnum][powertype]; - CONS_Printf("Player %d's PWR.LV: %d\n", jpnum, theirpower); + CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", jpnum, theirpower); if (G_RaceGametype()) { @@ -401,13 +401,13 @@ static void Y_UpdatePowerLevels(void) { diff = theirpower - yourpower; inc += K_CalculatePowerLevelInc(diff); - CONS_Printf("WON! Diff is %d, total increment is %d\n", diff, inc); + CONS_Debug(DBG_GAMELOGIC, "WON! Diff is %d, total increment is %d\n", diff, inc); } else // This player lost... { diff = yourpower - theirpower; inc -= K_CalculatePowerLevelInc(diff); - CONS_Printf("LOST... Diff is %d, total increment is %d\n", diff, inc); + CONS_Debug(DBG_GAMELOGIC, "LOST... Diff is %d, total increment is %d\n", diff, inc); } } @@ -421,23 +421,23 @@ static void Y_UpdatePowerLevels(void) if (ipnum == jpnum) // Same person continue; - CONS_Printf("Player %d VS Player %d (griefer):\n", ipnum, jpnum); + CONS_Debug(DBG_GAMELOGIC, "Player %d VS Player %d (griefer):\n", ipnum, jpnum); theirpower = 5000; if (nospectategrief[jpnum] != 0) // No power level acts as 5000 (used for splitscreen guests) theirpower = nospectategrief[jpnum]; - CONS_Printf("Player %d's PWR.LV: %d\n", jpnum, theirpower); + CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", jpnum, theirpower); diff = theirpower - yourpower; inc += K_CalculatePowerLevelInc(diff); - CONS_Printf("AUTO-WON! Diff is %d, total increment is %d\n", diff, inc); + CONS_Debug(DBG_GAMELOGIC, "AUTO-WON! Diff is %d, total increment is %d\n", diff, inc); } } if (inc == 0) { data.match.increase[ipnum] = INT16_MIN; - CONS_Printf("Total Result: No increment, no change.\n"); + CONS_Debug(DBG_GAMELOGIC, "Total Result: No increment, no change.\n"); continue; } @@ -446,11 +446,11 @@ static void Y_UpdatePowerLevels(void) if (yourpower + inc < 1) inc -= ((yourpower + inc) - 1); - CONS_Printf("Total Result: Increment of %d.\n", inc); + CONS_Debug(DBG_GAMELOGIC, "Total Result: Increment of %d.\n", inc); increment[ipnum] = inc; } - CONS_Printf("Setting final power levels...\n"); + CONS_Debug(DBG_GAMELOGIC, "Setting final power levels...\n"); for (i = 0; i < MAXPLAYERS; i++) { if (increment[i] == 0) @@ -461,7 +461,7 @@ static void Y_UpdatePowerLevels(void) if (i == consoleplayer) { - CONS_Printf("Player %d is you! Saving...\n", i); + CONS_Debug(DBG_GAMELOGIC, "Player %d is you! Saving...\n", i); vspowerlevel[powertype] = clientpowerlevels[i][powertype]; if (M_UpdateUnlockablesAndExtraEmblems(true)) S_StartSound(NULL, sfx_ncitem); From 38bb44e732e31813a3625b1fe10ebabbaae78637 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 23 Sep 2019 08:26:42 -0400 Subject: [PATCH 43/91] Separate into k_pwrlv.c, add defines to reduce amount of magic numbers --- src/Makefile | 1 + src/d_clisrv.c | 7 +- src/d_netcmd.c | 14 +- src/d_netcmd.h | 1 - src/doomstat.h | 6 - src/g_game.c | 15 +- src/k_kart.c | 169 +--------------------- src/k_kart.h | 3 - src/k_pwrlv.c | 289 +++++++++++++++++++++++++++++++++++++ src/k_pwrlv.h | 31 ++++ src/m_cond.c | 1 + src/m_menu.c | 5 +- src/p_inter.c | 1 + src/p_saveg.c | 3 + src/p_setup.c | 1 + src/y_inter.c | 378 ++++++++++++++++++++----------------------------- 16 files changed, 494 insertions(+), 431 deletions(-) create mode 100644 src/k_pwrlv.c create mode 100644 src/k_pwrlv.h diff --git a/src/Makefile b/src/Makefile index f4a77aedd..9c6bb0be4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -489,6 +489,7 @@ OBJS:=$(i_main_o) \ $(OBJDIR)/y_inter.o \ $(OBJDIR)/st_stuff.o \ $(OBJDIR)/k_kart.o \ + $(OBJDIR)/k_pwrlv.o \ $(OBJDIR)/m_aatree.o \ $(OBJDIR)/m_anigif.o \ $(OBJDIR)/m_argv.o \ diff --git a/src/d_clisrv.c b/src/d_clisrv.c index a4e5e4968..d0de5f3f8 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -47,6 +47,7 @@ #include "lua_script.h" #include "lua_hook.h" #include "k_kart.h" +#include "k_pwrlv.h" #ifdef CLIENT_LOADINGSCREEN // cl loading screen @@ -2317,7 +2318,7 @@ static void CL_ConnectToServer(boolean viams) wipegamestate = GS_WAITINGPLAYERS; ClearAdminPlayers(); - ClearClientPowerLevels(); + K_ClearClientPowerLevels(); pnumnodes = 1; oldtic = I_GetTime() - 1; #ifndef NONET @@ -3351,7 +3352,7 @@ void SV_ResetServer(void) playernode[i] = UINT8_MAX; sprintf(player_names[i], "Player %d", i + 1); adminplayers[i] = -1; // Populate the entire adminplayers array with -1. - ClearClientPowerLevels(); + K_ClearClientPowerLevels(); } mynode = 0; @@ -3427,7 +3428,7 @@ void D_QuitNetGame(void) D_CloseConnection(); ClearAdminPlayers(); - ClearClientPowerLevels(); + K_ClearClientPowerLevels(); DEBFILE("===========================================================================\n" " Log finish\n" diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 3569bca24..ffeb049fd 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -47,6 +47,7 @@ #include "m_cond.h" #include "m_anigif.h" #include "k_kart.h" // SRB2kart +#include "k_pwrlv.h" #include "y_inter.h" #ifdef NETGAME_DEVMODE @@ -475,7 +476,6 @@ boolean deferencoremode = false; UINT8 splitscreen = 0; boolean circuitmap = true; // SRB2kart INT32 adminplayers[MAXPLAYERS]; -UINT16 clientpowerlevels[MAXPLAYERS][2]; /// \warning Keep this up-to-date if you add/remove/rename net text commands const char *netxcmdnames[MAXNETXCMD - 1] = @@ -1936,8 +1936,8 @@ static void Got_PowerLevel(UINT8 **cp,INT32 playernum) UINT16 race = (UINT16)READUINT16(*cp); UINT16 battle = (UINT16)READUINT16(*cp); - clientpowerlevels[playernum][0] = min(9999, race); - clientpowerlevels[playernum][1] = min(9999, battle); + clientpowerlevels[playernum][PWRLV_RACE] = min(PWRLVRECORD_MAX, race); + clientpowerlevels[playernum][PWRLV_BATTLE] = min(PWRLVRECORD_MAX, battle); CONS_Debug(DBG_GAMELOGIC, "set player %d to power %d\n", playernum, race); } @@ -3845,14 +3845,6 @@ static void Got_Login(UINT8 **cp, INT32 playernum) #endif } -void ClearClientPowerLevels(void) -{ - INT32 i, j; - for (i = 0; i < MAXPLAYERS; i++) - for (j = 0; j < 2; j++) - clientpowerlevels[i][j] = 0; -} - boolean IsPlayerAdmin(INT32 playernum) { INT32 i; diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 0b88d2bc8..7d81f1164 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -242,7 +242,6 @@ void D_SetupVote(void); void D_ModifyClientVote(SINT8 voted, UINT8 splitplayer); void D_PickVote(void); void ObjectPlace_OnChange(void); -void ClearClientPowerLevels(void); boolean IsPlayerAdmin(INT32 playernum); void SetAdminPlayer(INT32 playernum); void ClearAdminPlayers(void); diff --git a/src/doomstat.h b/src/doomstat.h index af4abecf9..4f410aa53 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -339,7 +339,6 @@ extern const char *Gametype_Names[NUMGAMETYPES]; extern tic_t totalplaytime; extern UINT32 matchesplayed; -extern UINT16 vspowerlevel[2]; extern UINT8 stagefailed; @@ -475,13 +474,9 @@ extern tic_t wantedcalcdelay; extern tic_t indirectitemcooldown; extern tic_t hyubgone; extern tic_t mapreset; -extern INT16 nospectategrief[MAXPLAYERS]; extern boolean thwompsactive; extern SINT8 spbplace; -extern SINT8 speedscramble; -extern SINT8 encorescramble; - extern boolean legitimateexit; extern boolean comebackshowninfo; extern tic_t curlap, bestlap; @@ -556,7 +551,6 @@ extern consvar_t cv_maxping; extern ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS]; extern INT32 serverplayer; extern INT32 adminplayers[MAXPLAYERS]; -extern UINT16 clientpowerlevels[MAXPLAYERS][2]; /// \note put these in d_clisrv outright? diff --git a/src/g_game.c b/src/g_game.c index b07b764ec..4275e1356 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -48,6 +48,7 @@ #include "m_cond.h" // condition sets #include "md5.h" // demo checksums #include "k_kart.h" // SRB2kart +#include "k_pwrlv.h" gameaction_t gameaction; gamestate_t gamestate = GS_NULL; @@ -168,7 +169,6 @@ INT32 sstimer; // Time allotted in the special stage tic_t totalplaytime; UINT32 matchesplayed; // SRB2Kart -UINT16 vspowerlevel[2]; // SRB2Kart: Online rankings for each gametype boolean gamedataloaded = false; // Time attack data for levels @@ -267,14 +267,9 @@ tic_t wantedcalcdelay; // Time before it recalculates WANTED tic_t indirectitemcooldown; // Cooldown before any more Shrink, SPB, or any other item that works indirectly is awarded tic_t hyubgone; // Cooldown before hyudoro is allowed to be rerolled tic_t mapreset; // Map reset delay when enough players have joined an empty game -INT16 nospectategrief[MAXPLAYERS]; // Which players spec-scummed, and their power level before scumming. boolean thwompsactive; // Thwomps activate on lap 2 SINT8 spbplace; // SPB exists, give the person behind better items -// Scrambles -SINT8 speedscramble = -1; -SINT8 encorescramble = -1; - // Client-sided, unsynched variables (NEVER use in anything that needs to be synced with other players) boolean legitimateexit; // Did this client actually finish the match? boolean comebackshowninfo; // Have you already seen the "ATTACK OR PROTECT" message? @@ -4085,8 +4080,8 @@ void G_LoadGameData(void) totalplaytime = 0; // total play time (separate from all) matchesplayed = 0; // SRB2Kart: matches played & finished - for (i = 0; i < 2; i++) // SRB2Kart: online rank system - vspowerlevel[i] = 1000; + for (i = 0; i < PWRLV_NUMTYPES; i++) // SRB2Kart: online rank system + vspowerlevel[i] = PWRLVRECORD_START; if (M_CheckParm("-nodata")) return; // Don't load. @@ -6429,7 +6424,7 @@ void G_BeginRecording(void) WRITEUINT32(demo_p, player->score); // Power Levels - WRITEUINT16(demo_p, clientpowerlevels[p][G_BattleGametype() ? 1 : 0]); + WRITEUINT16(demo_p, clientpowerlevels[p][G_BattleGametype() ? PWRLV_BATTLE : PWRLV_RACE]); // Kart speed and weight WRITEUINT8(demo_p, skins[player->skin].kartspeed); @@ -7331,7 +7326,7 @@ void G_DoPlayDemo(char *defdemoname) players[p].score = READUINT32(demo_p); // Power Levels - clientpowerlevels[p][G_BattleGametype() ? 1 : 0] = READUINT16(demo_p); + clientpowerlevels[p][G_BattleGametype() ? PWRLV_BATTLE : PWRLV_RACE] = READUINT16(demo_p); // Kart stats, temporarily kartspeed[p] = READUINT8(demo_p); diff --git a/src/k_kart.c b/src/k_kart.c index e1a611d8a..969be4443 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4,6 +4,8 @@ /// \brief SRB2kart general. /// All of the SRB2kart-unique stuff. +#include "k_kart.h" +#include "k_pwrlv.h" #include "doomdef.h" #include "hu_stuff.h" #include "g_game.h" @@ -18,7 +20,6 @@ #include "z_zone.h" #include "m_misc.h" #include "m_cond.h" -#include "k_kart.h" #include "f_finale.h" #include "lua_hud.h" // For Lua hud checks #include "lua_hook.h" // For MobjDamage and ShouldDamage @@ -31,8 +32,6 @@ // battlewanted is an array of the WANTED player nums, -1 for no player in that slot // indirectitemcooldown is timer before anyone's allowed another Shrink/SPB // mapreset is set when enough players fill an empty server -// nospectategrief is the players in-game needed to eliminate the person in last - //{ SRB2kart Color Code @@ -6820,170 +6819,6 @@ void K_CheckBumpers(void) P_DoPlayerExit(&players[i]); } -// Adapted from this: http://wiki.tockdom.com/wiki/Player_Rating -INT16 K_CalculatePowerLevelInc(INT16 diff) -{ - INT16 control[10] = {0,0,0,1,8,50,125,125,125,125}; - fixed_t increment = 0; - fixed_t x; - UINT8 j; - -#define MAXDIFF 9998 - if (diff > MAXDIFF) - diff = MAXDIFF; - if (diff < -MAXDIFF) - diff = -MAXDIFF; -#undef MAXDIFF - - x = ((diff-2)<= (2<= (1<> FRACBITS); -} - -INT16 K_CalculatePowerLevelAvg(void) -{ - fixed_t avg = 0; - UINT8 div = 0; - SINT8 t = -1; - UINT8 i; - - if (!netgame || !cv_kartusepwrlv.value) - return 0; // No average. - - if (G_RaceGametype()) - t = 0; - else if (G_BattleGametype()) - t = 1; - - if (t == -1) - return 0; // Hmm?! - - for (i = 0; i < MAXPLAYERS; i++) - { - if (!playeringame[i] || players[i].spectator - || clientpowerlevels[i][t] == 0) // splitscreen player - continue; - - avg += clientpowerlevels[i][t]; - div++; - } - - if (!div) - return 0; // No average. - - avg /= div; - - return (INT16)(avg >> FRACBITS); -} - -void K_PlayerForfeit(UINT8 playernum, boolean pointloss) -{ - UINT8 p = 0; - INT32 powertype = -1; - UINT16 yourpower = 5000; - UINT16 theirpower = 5000; - INT16 diff = 0; // Loser PWR.LV - Winner PWR.LV - INT16 inc = 0; - UINT8 i; - - // power level & spectating is netgames only - if (!netgame) - return; - - // This server isn't using power levels anyway! - if (!cv_kartusepwrlv.value) - return; - - // Hey, I just got here! - if (players[playernum].jointime <= 1) - return; - - // 20 sec into the match counts as a forfeit -- automatic loss against every other player in the match. - if (gamestate != GS_LEVEL || leveltime <= starttime+(20*TICRATE)) - return; - - for (i = 0; i < MAXPLAYERS; i++) - { - if (playeringame[i] && !players[i].spectator) - p++; - } - - if (p < 2) // no players - return; - - if (G_RaceGametype()) - powertype = 0; - else if (G_BattleGametype()) - powertype = 1; - - if (powertype == -1) // No power type?! - return; - - if (clientpowerlevels[playernum][powertype] == 0) // splitscreen guests don't record power level changes - return; - yourpower = clientpowerlevels[playernum][powertype]; - - // Set up the point compensation. - nospectategrief[playernum] = yourpower; - - if (!pointloss) // This is set for stuff like sync-outs, which shouldn't be so harsh on the victim! - return; - - for (i = 0; i < MAXPLAYERS; i++) - { - if (i == playernum) - continue; - - theirpower = 5000; - if (clientpowerlevels[i][powertype] != 0) // No power level acts as 5000 (used for splitscreen guests) - theirpower = clientpowerlevels[i][powertype]; - - diff = yourpower - theirpower; - inc -= K_CalculatePowerLevelInc(diff); - } - - if (inc == 0) // No change. - return; - - if (yourpower + inc > 9999) // I mean... we're subtracting... but y'know how it is :V - inc -= ((yourpower + inc) - 9999); - if (yourpower + inc < 1) - inc -= ((yourpower + inc) - 1); - - clientpowerlevels[playernum][powertype] += inc; - - if (playernum == consoleplayer) - { - vspowerlevel[powertype] = clientpowerlevels[playernum][powertype]; - if (M_UpdateUnlockablesAndExtraEmblems(true)) - S_StartSound(NULL, sfx_ncitem); - G_SaveGameData(true); // save your punishment! - } -} - - void K_CheckSpectateStatus(void) { UINT8 respawnlist[MAXPLAYERS]; diff --git a/src/k_kart.h b/src/k_kart.h index 4b9a442d1..b91e8c8a1 100644 --- a/src/k_kart.h +++ b/src/k_kart.h @@ -68,9 +68,6 @@ fixed_t K_3dKartMovement(player_t *player, boolean onground, fixed_t forwardmove void K_MoveKartPlayer(player_t *player, boolean onground); void K_CalculateBattleWanted(void); void K_CheckBumpers(void); -INT16 K_CalculatePowerLevelInc(INT16 diff); -INT16 K_CalculatePowerLevelAvg(void); -void K_PlayerForfeit(UINT8 playernum, boolean nopointloss); void K_CheckSpectateStatus(void); // sound stuff for lua diff --git a/src/k_pwrlv.c b/src/k_pwrlv.c new file mode 100644 index 000000000..31a4bd314 --- /dev/null +++ b/src/k_pwrlv.c @@ -0,0 +1,289 @@ +/// \file k_pwrlv.c +/// \brief SRB2Kart Power Levels + +#include "k_pwrlv.h" +#include "d_netcmd.h" +#include "g_game.h" +#include "s_sound.h" +#include "m_random.h" +#include "m_cond.h" // M_UpdateUnlockablesAndExtraEmblems +#include "p_tick.h" // leveltime + +// Online rankings for the main gametypes. +// This array is saved to the gamedata. +UINT16 vspowerlevel[PWRLV_NUMTYPES]; + +// Client-sided calculations done for Power Levels. +// This is done so that clients will never be able to hack someone else's score over the server. +UINT16 clientpowerlevels[MAXPLAYERS][PWRLV_NUMTYPES]; + +// Which players spec-scummed, and their power level before scumming. +// On race finish, everyone is considered to have "won" against these people. +INT16 nospectategrief[MAXPLAYERS]; + +// Game setting scrambles based on server Power Level +SINT8 speedscramble = -1; +SINT8 encorescramble = -1; + +void K_ClearClientPowerLevels(void) +{ + UINT8 i, j; + for (i = 0; i < MAXPLAYERS; i++) + for (j = 0; j < PWRLV_NUMTYPES; j++) + clientpowerlevels[i][j] = 0; +} + +// Adapted from this: http://wiki.tockdom.com/wiki/Player_Rating +INT16 K_CalculatePowerLevelInc(INT16 diff) +{ + INT16 control[10] = {0,0,0,1,8,50,125,125,125,125}; + fixed_t increment = 0; + fixed_t x; + UINT8 j; + +#define MAXDIFF (PWRLVRECORD_MAX - 1) + if (diff > MAXDIFF) + diff = MAXDIFF; + if (diff < -MAXDIFF) + diff = -MAXDIFF; +#undef MAXDIFF + + x = ((diff-2)<= (2<= (1<> FRACBITS); +} + +INT16 K_CalculatePowerLevelAvg(void) +{ + fixed_t avg = 0; + UINT8 div = 0; + SINT8 t = PWRLV_DISABLED; + UINT8 i; + + if (!netgame || !cv_kartusepwrlv.value) + return 0; // No average. + + if (G_RaceGametype()) + t = PWRLV_RACE; + else if (G_BattleGametype()) + t = PWRLV_BATTLE; + + if (t == PWRLV_DISABLED) + return 0; // Hmm?! + + for (i = 0; i < MAXPLAYERS; i++) + { + if (!playeringame[i] || players[i].spectator + || clientpowerlevels[i][t] == 0) // splitscreen player + continue; + + avg += clientpowerlevels[i][t]; + div++; + } + + if (!div) + return 0; // No average. + + avg /= div; + + return (INT16)(avg >> FRACBITS); +} + +// -- K_UpdatePowerLevels could not be moved here due to usage of y_data, unfortunately. -- + +void K_SetPowerLevelScrambles(SINT8 powertype) +{ + switch (powertype) + { + case PWRLV_RACE: + if (cv_speedscramble.value || cv_encorescramble.value) + { + boolean hardmode = false; + boolean encore = false; + INT16 avg = 0, min = 0; + UINT8 i, t = 0; + + avg = K_CalculatePowerLevelAvg(); + + for (i = 0; i < MAXPLAYERS; i++) + { + if (min == 0 || clientpowerlevels[i][0] < min) + min = clientpowerlevels[i][0]; + } + + if (min >= 6000) + { + if (avg >= 8000) + t = 4; + else + t = 3; + } + else if (min >= 4000) + { + if (avg >= 5000) + t = 3; + else + t = 2; + } + else if (min >= 2500) + { + if (avg >= 3000) + t = 2; + else + t = 1; + } + else if (min >= 500) + { + if (avg >= 2000) + t = 1; + else + t = 0; + } + else + t = 0; + + switch (t) + { + case 4: + hardmode = encore = true; + break; + case 3: + hardmode = true; + encore = M_RandomChance(FRACUNIT>>1); + break; + case 2: + hardmode = M_RandomChance((7<>2); + break; + case 1: + hardmode = M_RandomChance((3< PWRLVRECORD_MAX) // I mean... we're subtracting... but y'know how it is :V + inc -= ((yourpower + inc) - PWRLVRECORD_MAX); + if (yourpower + inc < PWRLVRECORD_MIN) + inc -= ((yourpower + inc) - PWRLVRECORD_MIN); + + clientpowerlevels[playernum][powertype] += inc; + + if (playernum == consoleplayer) + { + vspowerlevel[powertype] = clientpowerlevels[playernum][powertype]; + if (M_UpdateUnlockablesAndExtraEmblems(true)) + S_StartSound(NULL, sfx_ncitem); + G_SaveGameData(true); // save your punishment! + } +} diff --git a/src/k_pwrlv.h b/src/k_pwrlv.h new file mode 100644 index 000000000..dfa300114 --- /dev/null +++ b/src/k_pwrlv.h @@ -0,0 +1,31 @@ +#ifndef __K_PWRLV__ +#define __K_PWRLV__ + +#include "doomtype.h" +#include "doomdef.h" + +#define PWRLV_DISABLED -1 +#define PWRLV_RACE 0 +#define PWRLV_BATTLE 1 +#define PWRLV_NUMTYPES 2 + +#define PWRLVRECORD_START 1000 +#define PWRLVRECORD_DEF 5000 +#define PWRLVRECORD_MIN 1 +#define PWRLVRECORD_MAX 9999 + +extern SINT8 speedscramble; +extern SINT8 encorescramble; + +extern UINT16 vspowerlevel[PWRLV_NUMTYPES]; +extern UINT16 clientpowerlevels[MAXPLAYERS][PWRLV_NUMTYPES]; +extern INT16 nospectategrief[MAXPLAYERS]; + +void K_ClearClientPowerLevels(void); +INT16 K_CalculatePowerLevelInc(INT16 diff); +INT16 K_CalculatePowerLevelAvg(void); +//void K_UpdatePowerLevels(void); +void K_SetPowerLevelScrambles(SINT8 powertype); +void K_PlayerForfeit(UINT8 playernum, boolean nopointloss); + +#endif diff --git a/src/m_cond.c b/src/m_cond.c index 6335d9f08..b56882c90 100644 --- a/src/m_cond.c +++ b/src/m_cond.c @@ -21,6 +21,7 @@ #include "r_things.h" // numskins //#include "r_draw.h" // R_GetColorByName #include "k_kart.h" // K_GetKartColorByName +#include "k_pwrlv.h" // Map triggers for linedef executors // 32 triggers, one bit each diff --git a/src/m_menu.c b/src/m_menu.c index 216eaab29..0dd9822c5 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -57,6 +57,7 @@ #include "st_stuff.h" #include "i_sound.h" #include "k_kart.h" // SRB2kart +#include "k_pwrlv.h" #include "d_player.h" // KITEM_ constants #include "i_joy.h" // for joystick menu controls @@ -9608,8 +9609,8 @@ static void M_EraseDataResponse(INT32 ch) // SRB2Kart: This actually needs to be done FIRST, so that you don't immediately regain playtime/matches secrets totalplaytime = 0; matchesplayed = 0; - for (i = 0; i < 2; i++) - vspowerlevel[i] = 1000; + for (i = 0; i < PWRLV_NUMTYPES; i++) + vspowerlevel[i] = PWRLVRECORD_START; F_StartIntro(); } if (erasecontext != 1) diff --git a/src/p_inter.c b/src/p_inter.c index b4d5c51dc..64bd573f1 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -27,6 +27,7 @@ #include "m_misc.h" #include "v_video.h" // video flags for CEchos #include "k_kart.h" // SRB2kart +#include "k_pwrlv.h" // CTF player names #define CTFTEAMCODE(pl) pl->ctfteam ? (pl->ctfteam == 1 ? "\x85" : "\x84") : "" diff --git a/src/p_saveg.c b/src/p_saveg.c index da625e867..c86758058 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -34,6 +34,9 @@ #include "p_slopes.h" #endif +// SRB2Kart +#include "k_pwrlv.h" + savedata_t savedata; UINT8 *save_p; diff --git a/src/p_setup.c b/src/p_setup.c index d61406054..b19093d9a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -84,6 +84,7 @@ // SRB2Kart #include "k_kart.h" +#include "k_pwrlv.h" // // Map MD5, calculated on level load. diff --git a/src/y_inter.c b/src/y_inter.c index 7dc97559b..4e130620b 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -39,6 +39,7 @@ #include "m_random.h" // M_RandomKey #include "g_input.h" // PLAYER1INPUTDOWN #include "k_kart.h" // colortranslations +#include "k_pwrlv.h" #include "console.h" // cons_menuhighlight #include "lua_hook.h" // IntermissionThinker hook @@ -323,153 +324,6 @@ static void Y_CalculateMatchData(UINT8 rankingsmode, void (*comparison)(INT32)) } } -static void Y_UpdatePowerLevels(void) -{ - INT32 i, j; - INT32 numplayersingame = 0, numgriefers = 0; - INT16 increment[MAXPLAYERS]; - - // Compare every single player against each other for power level increases. - // Every player you won against gives you more points, and vice versa. - // The amount of points won per match-up depends on the difference between the loser's power and the winner's power. - // See K_CalculatePowerLevelInc for more info. - - for (i = 0; i < MAXPLAYERS; i++) - { - increment[i] = 0; - - if (nospectategrief[i] != -1) - numgriefers++; - - if (!playeringame[i] || players[i].spectator) - continue; - - numplayersingame++; - } - - for (i = 0; i < numplayersingame; i++) - { - UINT16 yourpower = 5000; - UINT16 theirpower = 5000; - INT16 diff = 0; // Loser PWR.LV - Winner PWR.LV - INT16 inc = 0; // Total pt increment - UINT8 ipnum = data.match.num[i]; - UINT8 jpnum; - - CONS_Debug(DBG_GAMELOGIC, "Power Level Gain for player %d:\n", ipnum); - - if (clientpowerlevels[ipnum][powertype] == 0) // splitscreen guests don't record power level changes - continue; - yourpower = clientpowerlevels[ipnum][powertype]; - - CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", ipnum, yourpower); - - for (j = 0; j < numplayersingame; j++) - { - boolean won = false; - - jpnum = data.match.num[j]; - - if (i == j || ipnum == jpnum) // Same person - continue; - - CONS_Debug(DBG_GAMELOGIC, "Player %d VS Player %d:\n", ipnum, jpnum); - - if (data.match.val[i] == data.match.val[j]) // Tie -- neither get any points for this match up. - { - CONS_Debug(DBG_GAMELOGIC, "TIE, no change.\n"); - continue; - } - - theirpower = 5000; - if (clientpowerlevels[jpnum][powertype] != 0) // No power level acts as 5000 (used for splitscreen guests) - theirpower = clientpowerlevels[jpnum][powertype]; - CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", jpnum, theirpower); - - if (G_RaceGametype()) - { - if (data.match.val[i] < data.match.val[j]) - won = true; - } - else - { - if (data.match.val[i] > data.match.val[j]) - won = true; - } - - if (won) // This player won! - { - diff = theirpower - yourpower; - inc += K_CalculatePowerLevelInc(diff); - CONS_Debug(DBG_GAMELOGIC, "WON! Diff is %d, total increment is %d\n", diff, inc); - } - else // This player lost... - { - diff = yourpower - theirpower; - inc -= K_CalculatePowerLevelInc(diff); - CONS_Debug(DBG_GAMELOGIC, "LOST... Diff is %d, total increment is %d\n", diff, inc); - } - } - - if (numgriefers != 0) // Automatic win against quitters. - { - for (jpnum = 0; jpnum < MAXPLAYERS; jpnum++) - { - if (nospectategrief[jpnum] == -1) // Empty slot - continue; - - if (ipnum == jpnum) // Same person - continue; - - CONS_Debug(DBG_GAMELOGIC, "Player %d VS Player %d (griefer):\n", ipnum, jpnum); - - theirpower = 5000; - if (nospectategrief[jpnum] != 0) // No power level acts as 5000 (used for splitscreen guests) - theirpower = nospectategrief[jpnum]; - CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", jpnum, theirpower); - - diff = theirpower - yourpower; - inc += K_CalculatePowerLevelInc(diff); - CONS_Debug(DBG_GAMELOGIC, "AUTO-WON! Diff is %d, total increment is %d\n", diff, inc); - } - } - - if (inc == 0) - { - data.match.increase[ipnum] = INT16_MIN; - CONS_Debug(DBG_GAMELOGIC, "Total Result: No increment, no change.\n"); - continue; - } - - if (yourpower + inc > 9999) - inc -= ((yourpower + inc) - 9999); - if (yourpower + inc < 1) - inc -= ((yourpower + inc) - 1); - - CONS_Debug(DBG_GAMELOGIC, "Total Result: Increment of %d.\n", inc); - increment[ipnum] = inc; - } - - CONS_Debug(DBG_GAMELOGIC, "Setting final power levels...\n"); - for (i = 0; i < MAXPLAYERS; i++) - { - if (increment[i] == 0) - continue; - - data.match.increase[i] = increment[i]; - clientpowerlevels[i][powertype] += data.match.increase[i]; - - if (i == consoleplayer) - { - CONS_Debug(DBG_GAMELOGIC, "Player %d is you! Saving...\n", i); - vspowerlevel[powertype] = clientpowerlevels[i][powertype]; - if (M_UpdateUnlockablesAndExtraEmblems(true)) - S_StartSound(NULL, sfx_ncitem); - G_SaveGameData(true); - } - } -} - // // Y_IntermissionDrawer // @@ -974,6 +828,153 @@ static void Y_UpdateRecordReplays(void) CV_AddValue(&cv_nextmap, -1); } +static void K_UpdatePowerLevels(void) +{ + INT32 i, j; + INT32 numplayersingame = 0, numgriefers = 0; + INT16 increment[MAXPLAYERS]; + + // Compare every single player against each other for power level increases. + // Every player you won against gives you more points, and vice versa. + // The amount of points won per match-up depends on the difference between the loser's power and the winner's power. + // See K_CalculatePowerLevelInc for more info. + + for (i = 0; i < MAXPLAYERS; i++) + { + increment[i] = 0; + + if (nospectategrief[i] != -1) + numgriefers++; + + if (!playeringame[i] || players[i].spectator) + continue; + + numplayersingame++; + } + + for (i = 0; i < numplayersingame; i++) + { + UINT16 yourpower = PWRLVRECORD_DEF; + UINT16 theirpower = PWRLVRECORD_DEF; + INT16 diff = 0; // Loser PWR.LV - Winner PWR.LV + INT16 inc = 0; // Total pt increment + UINT8 ipnum = data.match.num[i]; + UINT8 jpnum; + + CONS_Debug(DBG_GAMELOGIC, "Power Level Gain for player %d:\n", ipnum); + + if (clientpowerlevels[ipnum][powertype] == 0) // splitscreen guests don't record power level changes + continue; + yourpower = clientpowerlevels[ipnum][powertype]; + + CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", ipnum, yourpower); + + for (j = 0; j < numplayersingame; j++) + { + boolean won = false; + + jpnum = data.match.num[j]; + + if (i == j || ipnum == jpnum) // Same person + continue; + + CONS_Debug(DBG_GAMELOGIC, "Player %d VS Player %d:\n", ipnum, jpnum); + + if (data.match.val[i] == data.match.val[j]) // Tie -- neither get any points for this match up. + { + CONS_Debug(DBG_GAMELOGIC, "TIE, no change.\n"); + continue; + } + + theirpower = PWRLVRECORD_DEF; + if (clientpowerlevels[jpnum][powertype] != 0) // No power level acts as 5000 (used for splitscreen guests) + theirpower = clientpowerlevels[jpnum][powertype]; + CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", jpnum, theirpower); + + if (G_RaceGametype()) + { + if (data.match.val[i] < data.match.val[j]) + won = true; + } + else + { + if (data.match.val[i] > data.match.val[j]) + won = true; + } + + if (won) // This player won! + { + diff = theirpower - yourpower; + inc += K_CalculatePowerLevelInc(diff); + CONS_Debug(DBG_GAMELOGIC, "WON! Diff is %d, total increment is %d\n", diff, inc); + } + else // This player lost... + { + diff = yourpower - theirpower; + inc -= K_CalculatePowerLevelInc(diff); + CONS_Debug(DBG_GAMELOGIC, "LOST... Diff is %d, total increment is %d\n", diff, inc); + } + } + + if (numgriefers != 0) // Automatic win against quitters. + { + for (jpnum = 0; jpnum < MAXPLAYERS; jpnum++) + { + if (nospectategrief[jpnum] == -1) // Empty slot + continue; + + if (ipnum == jpnum) // Same person + continue; + + CONS_Debug(DBG_GAMELOGIC, "Player %d VS Player %d (griefer):\n", ipnum, jpnum); + + theirpower = PWRLVRECORD_DEF; + if (nospectategrief[jpnum] != 0) // No power level acts as 5000 (used for splitscreen guests) + theirpower = nospectategrief[jpnum]; + CONS_Debug(DBG_GAMELOGIC, "Player %d's PWR.LV: %d\n", jpnum, theirpower); + + diff = theirpower - yourpower; + inc += K_CalculatePowerLevelInc(diff); + CONS_Debug(DBG_GAMELOGIC, "AUTO-WON! Diff is %d, total increment is %d\n", diff, inc); + } + } + + if (inc == 0) + { + data.match.increase[ipnum] = INT16_MIN; + CONS_Debug(DBG_GAMELOGIC, "Total Result: No increment, no change.\n"); + continue; + } + + if (yourpower + inc > PWRLVRECORD_MAX) + inc -= ((yourpower + inc) - PWRLVRECORD_MAX); + if (yourpower + inc < PWRLVRECORD_MIN) + inc -= ((yourpower + inc) - PWRLVRECORD_MIN); + + CONS_Debug(DBG_GAMELOGIC, "Total Result: Increment of %d.\n", inc); + increment[ipnum] = inc; + } + + CONS_Debug(DBG_GAMELOGIC, "Setting final power levels...\n"); + for (i = 0; i < MAXPLAYERS; i++) + { + if (increment[i] == 0) + continue; + + data.match.increase[i] = increment[i]; + clientpowerlevels[i][powertype] += data.match.increase[i]; + + if (i == consoleplayer) + { + CONS_Debug(DBG_GAMELOGIC, "Player %d is you! Saving...\n", i); + vspowerlevel[powertype] = clientpowerlevels[i][powertype]; + if (M_UpdateUnlockablesAndExtraEmblems(true)) + S_StartSound(NULL, sfx_ncitem); + G_SaveGameData(true); + } + } +} + // // Y_StartIntermission // @@ -999,86 +1000,7 @@ void Y_StartIntermission(void) powertype = 1; } - // Race scrambles - if (powertype == 0 && (cv_speedscramble.value || cv_encorescramble.value)) - { - boolean hardmode = false; - boolean encore = false; - INT16 avg = 0, min = 0; - UINT8 i, t = 0; - - avg = K_CalculatePowerLevelAvg(); - - for (i = 0; i < MAXPLAYERS; i++) - { - if (min == 0 || clientpowerlevels[i][0] < min) - min = clientpowerlevels[i][0]; - } - - if (min >= 6000) - { - if (avg >= 8000) - t = 4; - else - t = 3; - } - else if (min >= 4000) - { - if (avg >= 5000) - t = 3; - else - t = 2; - } - else if (min >= 2500) - { - if (avg >= 3000) - t = 2; - else - t = 1; - } - else if (min >= 500) - { - if (avg >= 2000) - t = 1; - else - t = 0; - } - else - t = 0; - - switch (t) - { - case 4: - hardmode = encore = true; - break; - case 3: - hardmode = true; - encore = M_RandomChance(FRACUNIT>>1); - break; - case 2: - hardmode = M_RandomChance((7<>2); - break; - case 1: - hardmode = M_RandomChance((3< Date: Mon, 23 Sep 2019 08:31:36 -0400 Subject: [PATCH 44/91] Remove a few more magic numbers --- src/d_clisrv.c | 6 +++--- src/d_netcmd.c | 4 ++-- src/g_game.c | 8 ++++---- src/m_menu.c | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index d0de5f3f8..6df5a03d9 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1525,13 +1525,13 @@ static boolean SV_SendServerConfig(INT32 node) memset(netbuffer->u.servercfg.adminplayers, -1, sizeof(netbuffer->u.servercfg.adminplayers)); for (i = 0; i < MAXPLAYERS; i++) - for (j = 0; j < 2; j++) + for (j = 0; j < PWRLV_NUMTYPES; j++) netbuffer->u.servercfg.powerlevels[i][j] = 0; // Not sure if memset works on something like this for (i = 0; i < MAXPLAYERS; i++) { netbuffer->u.servercfg.adminplayers[i] = (SINT8)adminplayers[i]; - for (j = 0; j < 2; j++) + for (j = 0; j < PWRLV_NUMTYPES; j++) netbuffer->u.servercfg.powerlevels[i][j] = clientpowerlevels[i][j]; if (!playeringame[i]) @@ -4131,7 +4131,7 @@ static void HandlePacketFromAwayNode(SINT8 node) for (j = 0; j < MAXPLAYERS; j++) { adminplayers[j] = netbuffer->u.servercfg.adminplayers[j]; - for (k = 0; k < 2; k++) + for (k = 0; k < PWRLV_NUMTYPES; k++) clientpowerlevels[j][k] = netbuffer->u.servercfg.powerlevels[j][k]; } memcpy(server_context, netbuffer->u.servercfg.server_context, 8); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index ffeb049fd..752e4b919 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1963,8 +1963,8 @@ void D_SendPlayerConfig(void) UINT8 buf[4]; UINT8 *buf_p = buf; - WRITEUINT16(buf_p, vspowerlevel[0]); - WRITEUINT16(buf_p, vspowerlevel[1]); + WRITEUINT16(buf_p, vspowerlevel[PWRLV_RACE]); + WRITEUINT16(buf_p, vspowerlevel[PWRLV_BATTLE]); SendNetXCmd(XD_POWERLEVEL, buf, 4); } diff --git a/src/g_game.c b/src/g_game.c index 4275e1356..fb0654c8e 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3049,7 +3049,7 @@ mapthing_t *G_FindRaceStart(INT32 playernum) if (netgame && cv_kartusepwrlv.value) { - if (clientpowerlevels[j][0] == clientpowerlevels[i][0]) + if (clientpowerlevels[j][PWRLV_RACE] == clientpowerlevels[i][PWRLV_RACE]) num++; } else @@ -3070,7 +3070,7 @@ mapthing_t *G_FindRaceStart(INT32 playernum) { if (netgame && cv_kartusepwrlv.value) { - if (clientpowerlevels[i][0] > clientpowerlevels[playernum][0]) + if (clientpowerlevels[i][PWRLV_RACE] > clientpowerlevels[playernum][PWRLV_RACE]) pos++; } else @@ -4113,7 +4113,7 @@ void G_LoadGameData(void) totalplaytime = READUINT32(save_p); matchesplayed = READUINT32(save_p); - for (i = 0; i < 2; i++) + for (i = 0; i < PWRLV_NUMTYPES; i++) vspowerlevel[i] = READUINT16(save_p); modded = READUINT8(save_p); @@ -4261,7 +4261,7 @@ void G_SaveGameData(boolean force) WRITEUINT32(save_p, totalplaytime); WRITEUINT32(save_p, matchesplayed); - for (i = 0; i < 2; i++) + for (i = 0; i < PWRLV_NUMTYPES; i++) WRITEUINT16(save_p, vspowerlevel[i]); btemp = (UINT8)(savemoddata); // what used to be here was profoundly dunderheaded diff --git a/src/m_menu.c b/src/m_menu.c index 0dd9822c5..362c7ea5c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7410,8 +7410,8 @@ static void M_DrawLevelStats(void) V_DrawRightAlignedString(BASEVIDWIDTH-16, 42, 0, va("%i played", matchesplayed)); V_DrawString(20, 52, highlightflags, "Online Power Level:"); - V_DrawRightAlignedString(BASEVIDWIDTH-16, 52, 0, va("Race: %i", vspowerlevel[0])); - V_DrawRightAlignedString(BASEVIDWIDTH-16, 60, 0, va("Battle: %i", vspowerlevel[1])); + V_DrawRightAlignedString(BASEVIDWIDTH-16, 52, 0, va("Race: %i", vspowerlevel[PWRLV_RACE])); + V_DrawRightAlignedString(BASEVIDWIDTH-16, 60, 0, va("Battle: %i", vspowerlevel[PWRLV_BATTLE])); for (i = 0; i < NUMMAPS; i++) { From a46036e489f55b6840674265df75a65801f82bd6 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 23 Sep 2019 08:50:59 -0400 Subject: [PATCH 45/91] Last few magic numbers I could find --- src/d_clisrv.h | 2 +- src/dehacked.c | 4 ++-- src/m_menu.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 87147aeb8..013ccca01 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -325,7 +325,7 @@ typedef struct UINT8 gametype; UINT8 modifiedgame; SINT8 adminplayers[MAXPLAYERS]; // Needs to be signed - UINT16 powerlevels[MAXPLAYERS][2]; // SRB2kart: player power levels + UINT16 powerlevels[MAXPLAYERS][PWRLV_NUMTYPES]; // SRB2kart: player power levels char server_context[8]; // Unique context id, generated at server startup. diff --git a/src/dehacked.c b/src/dehacked.c index 383183a0f..b8f292a69 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -2559,9 +2559,9 @@ static void readcondition(UINT8 set, UINT32 id, char *word2) re = atoi(params[1]); x1 = atoi(params[2]); - if (x1 < 0 || x1 > 1) + if (x1 < 0 || x1 >= PWRLV_NUMTYPES) { - deh_warning("Power level type %d out of range (0 - 1)", x1); + deh_warning("Power level type %d out of range (0 - %d)", x1, PWRLV_NUMTYPES-1); return; } } diff --git a/src/m_menu.c b/src/m_menu.c index 362c7ea5c..9f4c3cda5 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -6211,7 +6211,7 @@ static char *M_GetConditionString(condition_t cond) case UC_MATCHESPLAYED: return va("Play %d matches", cond.requirement); case UC_POWERLEVEL: - return va("Reach power level %d in %s", cond.requirement, (cond.extrainfo1 == 1 ? "Battle" : "Race")); + return va("Reach power level %d in %s", cond.requirement, (cond.extrainfo1 == PWRLV_BATTLE ? "Battle" : "Race")); case UC_GAMECLEAR: if (cond.requirement > 1) return va("Beat game %d times", cond.requirement); From 53848bd5faf2a8bfcf194af93c9294fc75cf1250 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 23 Sep 2019 08:51:49 -0400 Subject: [PATCH 46/91] commit throwdir fix I did a bunch of other demo-related cleanup in this branch so I'm throwing it in here too --- src/g_game.c | 14 -------------- src/p_tick.c | 11 ----------- src/p_user.c | 3 --- 3 files changed, 28 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index fb0654c8e..cf2378d09 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2368,21 +2368,7 @@ void G_Ticker(boolean run) if (playeringame[i]) { - //@TODO all this throwdir stuff shouldn't be here! But it stays for now to maintain 1.0.4 compat... - // Remove for 1.1! - - // SRB2kart - // Save the dir the player is holding - // to allow items to be thrown forward or backward. - if (cmd->buttons & BT_FORWARD) - players[i].kartstuff[k_throwdir] = 1; - else if (cmd->buttons & BT_BACKWARD) - players[i].kartstuff[k_throwdir] = -1; - else - players[i].kartstuff[k_throwdir] = 0; - G_CopyTiccmd(cmd, &netcmds[buf][i], 1); - // Use the leveltime sent in the player's ticcmd to determine control lag cmd->latency = modeattacking ? 0 : min(((leveltime & 0xFF) - cmd->latency) & 0xFF, MAXPREDICTTICS-1); //@TODO add a cvar to allow setting this max } diff --git a/src/p_tick.c b/src/p_tick.c index 8312afe81..02a532bc1 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -620,18 +620,7 @@ void P_Ticker(boolean run) G_ReadDemoExtraData(); for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i]) - { - //@TODO all this throwdir stuff shouldn't be here! But it's added to maintain 1.0.4 compat for now... - // Remove for 1.1! - if (players[i].cmd.buttons & BT_FORWARD) - players[i].kartstuff[k_throwdir] = 1; - else if (players[i].cmd.buttons & BT_BACKWARD) - players[i].kartstuff[k_throwdir] = -1; - else - players[i].kartstuff[k_throwdir] = 0; - G_ReadDemoTiccmd(&players[i].cmd, i); - } } for (i = 0; i < MAXPLAYERS; i++) diff --git a/src/p_user.c b/src/p_user.c index 8932a49c8..d5d7dc6fd 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8136,8 +8136,6 @@ void P_PlayerThink(player_t *player) cmd = &player->cmd; - //@TODO This fixes a one-tic latency on direction handling, AND makes behavior consistent while paused, but is not BC with 1.0.4. Do this for 1.1! -#if 0 // SRB2kart // Save the dir the player is holding // to allow items to be thrown forward or backward. @@ -8147,7 +8145,6 @@ void P_PlayerThink(player_t *player) player->kartstuff[k_throwdir] = -1; else player->kartstuff[k_throwdir] = 0; -#endif // Add some extra randomization. if (cmd->forwardmove) From 8dc946e6bbdfc934fdd9c55ee69b7a33aaac4f3c Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 23 Sep 2019 09:02:23 -0400 Subject: [PATCH 47/91] Yup, 1 more batch of magic numbers --- src/y_inter.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/y_inter.c b/src/y_inter.c index 4e130620b..c51ac1e3f 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -111,7 +111,7 @@ static boolean usetile; boolean usebuffer = false; static boolean useinterpic; static INT32 timer; -static INT32 powertype = 0; +static INT32 powertype = PWRLV_DISABLED; static INT32 intertic; static INT32 endtic = -1; @@ -990,14 +990,14 @@ void Y_StartIntermission(void) #endif // set player Power Level type - powertype = -1; + powertype = PWRLV_DISABLED; if (netgame && cv_kartusepwrlv.value) { if (G_RaceGametype()) - powertype = 0; + powertype = PWRLV_RACE; else if (G_BattleGametype()) - powertype = 1; + powertype = PWRLV_BATTLE; } K_SetPowerLevelScrambles(powertype); From e502a74a3fb3957ee0c8fbd2b339d482bff45ac4 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 23 Sep 2019 20:19:57 -0400 Subject: [PATCH 48/91] Use memset --- src/d_clisrv.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 6df5a03d9..ffc5b5772 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1523,10 +1523,7 @@ static boolean SV_SendServerConfig(INT32 node) memset(netbuffer->u.servercfg.playercolor, 0xFF, sizeof(netbuffer->u.servercfg.playercolor)); memset(netbuffer->u.servercfg.adminplayers, -1, sizeof(netbuffer->u.servercfg.adminplayers)); - - for (i = 0; i < MAXPLAYERS; i++) - for (j = 0; j < PWRLV_NUMTYPES; j++) - netbuffer->u.servercfg.powerlevels[i][j] = 0; // Not sure if memset works on something like this + memset(netbuffer->u.servercfg.powerlevels, 0, sizeof(netbuffer->u.servercfg.powerlevels)); for (i = 0; i < MAXPLAYERS; i++) { From 45fd60a4ab69bae271c803eb6cdefac06dd996a1 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 23 Sep 2019 20:26:47 -0400 Subject: [PATCH 49/91] Master Server scary --- src/d_clisrv.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 013ccca01..ab0c3ef82 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -388,6 +388,9 @@ typedef struct UINT8 actnum; UINT8 iszone; UINT8 fileneeded[MAXFILENEEDED]; // is filled with writexxx (byteptr.h) + // Anything beyond this point won't be read by the normal SRB2 Master Server display. + // The MS uses a simple unpack, so the size of the packet above shouldn't be changed, either. + // As long as those two conditions are met, we can add as much information as we want to the end. INT16 avgpwrlv; // Kart avg power level } ATTRPACK serverinfo_pak; From f75392109da44eb386f93269aba1d0b9a22c2703 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 23 Sep 2019 21:28:45 -0400 Subject: [PATCH 50/91] Forgotten include --- src/d_clisrv.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/d_clisrv.h b/src/d_clisrv.h index ab0c3ef82..0bd85b614 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -18,6 +18,7 @@ #include "d_netcmd.h" #include "tables.h" #include "d_player.h" +#include "k_pwrlv.h" // PWRLV_NUMTYPES #include "md5.h" From 7cfcb2f61a243946ffbe8c7ca08c9b2f0ad0e51d Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Tue, 24 Sep 2019 02:00:27 -0400 Subject: [PATCH 51/91] Don't select items in the air or with the Ambush flag for overtime --- src/p_inter.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/p_inter.c b/src/p_inter.c index 2029e6a48..022432af9 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1857,15 +1857,24 @@ void P_CheckTimeLimit(void) continue; if (thismo->threshold == 69) // Disappears continue; + b++; + + // Only select items that are on the ground, ignore ones in the air. Ambush flag inverts this rule. + if ((!P_IsObjectOnGround(thismo)) != (thismo->flags2 & MF2_AMBUSH)) + continue; + if (item == NULL || (b < nummapboxes && P_RandomChance(((nummapboxes-b)*FRACUNIT)/nummapboxes))) // This is to throw off the RNG some item = thismo; if (b >= nummapboxes) // end early if we've found them all already break; } - if (item == NULL) // no item found?! + if (item == NULL) // no item found, could happen if every item is in the air or has ambush flag, or the map has none + { + CONS_Alert(CONS_WARNING, "No usuable items for Battle overtime!\n"); return; + } item->threshold = 70; // Set constant respawn battleovertime.x = item->x; From 60b0df0330c9ecbcf7b9972a9ca036ad563e2e93 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Tue, 24 Sep 2019 02:01:27 -0400 Subject: [PATCH 52/91] Did not mean to commit this eons ago... :V --- src/sdl/i_video.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 824c67bf4..42e0a917f 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1678,7 +1678,7 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) #endif // Create a window - window = SDL_CreateWindow("FortniteKart "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + window = SDL_CreateWindow("SRB2Kart "VERSIONSTRING, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, realwidth, realheight, flags); if (window == NULL) From 1d59d8305d4b57a4527e7329732918c64fb38e26 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Sep 2019 14:39:23 -0700 Subject: [PATCH 53/91] Remove trailing whitespace --- src/d_main.c | 2 +- src/p_inter.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 5c8e34bde..8388c50cd 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -447,7 +447,7 @@ static void D_Display(void) { if (i > 0) // Splitscreen-specific { - switch (i) + switch (i) { case 1: if (splitscreen > 1) diff --git a/src/p_inter.c b/src/p_inter.c index de14b3db9..8cf9703d0 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3306,12 +3306,12 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) // 20 is the ring cap in kart if (num_rings > 20) - num_rings = 20; + num_rings = 20; else if (num_rings <= 0) return; // Cap the maximum loss automatically to 2 in ring debt - if (player->kartstuff[k_rings] <= 0 && num_rings > 2) + if (player->kartstuff[k_rings] <= 0 && num_rings > 2) num_rings = 2; P_GivePlayerRings(player, -num_rings); From 92022be2542d824313854973b1849305367618bf Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 27 Sep 2019 06:28:26 -0400 Subject: [PATCH 54/91] Don't crash if you can't find a pwad or it's already loaded or etc --- src/d_main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 5c8e34bde..a89fe4340 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1190,12 +1190,12 @@ void D_SRB2Main(void) M_InitCharacterTables(); // load wad, including the main wad file - CONS_Printf("W_InitMultipleFiles(): Adding IWAD and main PWADs.\n"); + CONS_Printf("W_InitMultipleFiles(): Adding main IWAD and PWADs.\n"); if (!W_InitMultipleFiles(startupwadfiles, false)) #ifdef _DEBUG - CONS_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n"); + CONS_Error("A main WAD file was not found or not valid.\nCheck the log to see which ones.\n"); #else - I_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n"); + I_Error("A main WAD file was not found or not valid.\nCheck the log to see which ones.\n"); #endif D_CleanFile(startupwadfiles); @@ -1249,8 +1249,9 @@ void D_SRB2Main(void) } } + CONS_Printf("W_InitMultipleFiles(): Adding external PWADs.\n"); if (!W_InitMultipleFiles(startuppwads, true)) - CONS_Error("A PWAD file was not found or not valid.\nCheck the log to see which ones.\n"); + M_StartMessage(M_GetText("A PWAD file was not found or not valid.\nCheck log.txt to see which ones.\n\nPress ESC\n"), NULL, MM_NOTHING); D_CleanFile(startuppwads); // From 2635d1b8106506424cff6c1477838a01fbbcc7b8 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 27 Sep 2019 06:46:10 -0400 Subject: [PATCH 55/91] Fix SPB target not being merged --- src/k_kart.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 348c5a824..3b6e80aeb 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -9142,7 +9142,9 @@ static void K_drawKartMinimap(void) colormap = NULL; K_drawKartMinimapIcon(players[i].mo->x, players[i].mo->y, x, y, splitflags, facemmapprefix[skin], colormap, AutomapPic); - if (K_IsPlayerWanted(&players[i])) + // Target reticule + if ((G_RaceGametype() && players[i].kartstuff[k_position] == spbplace) + || (G_BattleGametype() && K_IsPlayerWanted(&players[i]))) K_drawKartMinimapIcon(players[i].mo->x, players[i].mo->y, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic); } } @@ -9171,8 +9173,11 @@ static void K_drawKartMinimap(void) else colormap = NULL; - K_drawKartMinimapIcon(players[localplayers[i]].mo->x, players[localplayers[i]].mo->y, x, y, splitflags, facemmapprefix[skin], colormap, AutomapPic); - if (K_IsPlayerWanted(&players[localplayers[i]])) + K_drawKartMinimapIcon(players[localplayers[i]].mo->x, players[localplayers[i]].mo->y, x, y, splitflags, facemmapprefix[skin], colormap, AutomapPic); + + // Target reticule + if ((G_RaceGametype() && players[localplayers[i]].kartstuff[k_position] == spbplace) + || (G_BattleGametype() && K_IsPlayerWanted(&players[localplayers[i]]))) K_drawKartMinimapIcon(players[localplayers[i]].mo->x, players[localplayers[i]].mo->y, x, y, splitflags, kp_wantedreticle, NULL, AutomapPic); } } From 6a1e49a91c79ed118b1497d23bb387e2cbb901fd Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 27 Sep 2019 14:34:17 -0400 Subject: [PATCH 56/91] Fixed some instances that weren't writing TRANSPARENTPIXEL --- src/m_anigif.c | 2 +- src/r_data.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/m_anigif.c b/src/m_anigif.c index 4e68819bc..4dfc77cb3 100644 --- a/src/m_anigif.c +++ b/src/m_anigif.c @@ -422,7 +422,7 @@ static void GIF_headwrite(void) WRITEUINT16(p, rheight); // colors, aspect, etc - WRITEUINT8(p, 0xF7); + WRITEUINT8(p, 0xFF); // TRANSPARENTPIXEL WRITEUINT8(p, 0x00); WRITEUINT8(p, 0x00); diff --git a/src/r_data.c b/src/r_data.c index d710359d1..6aebf5a4a 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -267,7 +267,7 @@ static UINT8 *R_GenerateTexture(size_t texnum) texturememory += blocksize; block = Z_Malloc(blocksize+1, PU_STATIC, &texturecache[texnum]); - memset(block, 0xF7, blocksize+1); // Transparency hack + memset(block, 0xFF, blocksize+1); // TRANSPARENTPIXEL // columns lookup table colofs = (UINT32 *)(void *)block; From d907158b120941a5bd4c1c5843dfd4ccb5e8be66 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 27 Sep 2019 15:12:55 -0400 Subject: [PATCH 57/91] Revert this --- src/g_game.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index cf2378d09..ac7987291 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -67,7 +67,7 @@ JoyType_t Joystick4; #define SAVEGAMESIZE (1024) // SRB2kart -char gamedatafilename[64] = "vr.dat"; +char gamedatafilename[64] = "kartdata.dat"; char timeattackfolder[64] = "kart"; char customversionstring[32] = "\0"; From 9a9a1c13742cbd4ac9feb75ee2bad2d79e30194e Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 27 Sep 2019 15:31:57 -0400 Subject: [PATCH 58/91] This shouldn't be merged --- src/p_inter.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/p_inter.c b/src/p_inter.c index 022432af9..e5b4cb029 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -1776,7 +1776,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) } // Easily make it so that overtime works offline -#define TESTOVERTIMEINFREEPLAY +//#define TESTOVERTIMEINFREEPLAY /** Checks if the level timer is over the timelimit and the round should end, * unless you are in overtime. In which case leveltime may stretch out beyond @@ -1904,8 +1904,6 @@ void P_CheckTimeLimit(void) } } -#undef TESTOVERTIMEINFREEPLAY - /** Checks if a player's score is over the pointlimit and the round should end. * Verify that the value of ::cv_pointlimit is greater than zero before * calling this function. From 8cbdc999f4dac7dfc687b2ccd40e5e4138fa80b6 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 27 Sep 2019 19:19:04 -0700 Subject: [PATCH 59/91] Block playing by yourself in TESTERS build with le funni message SV_SpawnServer is called in instances other than joining a server or watching a replay. How convenient, huh? --- src/d_clisrv.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 4d61194c4..024194155 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3623,6 +3623,11 @@ boolean Playing(void) boolean SV_SpawnServer(void) { +#ifdef TESTERS + /* Just don't let the testers play. Easy. */ + I_Error("What do you think you're doing?"); + return 0; +#else if (demo.playback) G_StopDemo(); // reset engine parameter if (metalplayback) @@ -3649,6 +3654,7 @@ boolean SV_SpawnServer(void) } return SV_AddWaitingPlayers(); +#endif } void SV_StopServer(void) From 246280045cb1291d3bf1f2bb043e87388c6787b8 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 27 Sep 2019 19:20:55 -0700 Subject: [PATCH 60/91] Fix crash in TESTERS build if you try to record demo anyway --- src/sdl/i_system.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index d24bd5ade..76fdab684 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -3177,11 +3177,14 @@ void I_Error(const char *error, ...) #endif G_SaveGameData(false); // Tails 12-08-2002 + /* Prevent segmentation fault if testers go to Record Attack... */ +#ifndef TESTERS // Shutdown. Here might be other errors. if (demo.recording) G_CheckDemoStatus(); if (metalrecording) G_StopMetalRecording(); +#endif D_QuitNetGame(); I_ShutdownMusic(); From 03b3d61fd1d37993d23451d6337f1ac1855ee787 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 27 Sep 2019 19:21:18 -0700 Subject: [PATCH 61/91] Add TESTERS build flag to Makefile --- src/Makefile | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Makefile b/src/Makefile index f4a77aedd..3d997eacb 100644 --- a/src/Makefile +++ b/src/Makefile @@ -60,6 +60,7 @@ # Compile with GCC 4.6x version, add 'GCC46=1' # Compile a profile version, add 'PROFILEMODE=1' # Compile a debug version, add 'DEBUGMODE=1' +# Compile for the testers group (they don't get to play unless we're watching *wink*), add 'TESTERS=1' # Compile with extra warnings, add 'WARNINGMODE=1' # Compile without NASM's tmap.nas, add 'NOASM=1' # Compile without 3D hardware support, add 'NOHW=1' @@ -434,6 +435,10 @@ else endif CFLAGS+=-g $(OPTS) $(ARCHOPTS) $(WINDRESFLAGS) +ifdef TESTERS + OPTS+=-DTESTERS +endif + ifdef YASM ifdef STABS NASMOPTS?= -g stabs From b64dccd498d1bc4a977672b64e8d37194793b3fa Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 27 Sep 2019 19:56:18 -0700 Subject: [PATCH 62/91] Hide Record Attack in TESTERS build --- src/m_menu.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/m_menu.c b/src/m_menu.c index 166b115d6..ab13fdd8d 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -474,9 +474,14 @@ static menuitem_t MainMenu[] = { {IT_SUBMENU|IT_STRING, NULL, "Extras", &SR_MainDef, 76}, //{IT_CALL |IT_STRING, NULL, "1 Player", M_SinglePlayerMenu, 84}, +#ifdef TESTERS + {IT_GRAYEDOUT, NULL, "Time Attack", NULL, 84}, +#else {IT_CALL |IT_STRING, NULL, "Time Attack", M_TimeAttack, 84}, +#endif {IT_SUBMENU|IT_STRING, NULL, "Multiplayer", &MP_MainDef, 92}, {IT_CALL |IT_STRING, NULL, "Options", M_Options, 100}, + /* I don't think is useful at all... */ {IT_CALL |IT_STRING, NULL, "Addons", M_Addons, 108}, {IT_CALL |IT_STRING, NULL, "Quit Game", M_QuitSRB2, 116}, }; @@ -3029,7 +3034,11 @@ void M_StartControlPanel(void) //MainMenu[secrets].status = (M_AnySecretUnlocked()) ? (IT_STRING | IT_CALL) : (IT_DISABLED); currentMenu = &MainDef; +#ifdef TESTERS + itemOn = multiplr; +#else itemOn = singleplr; +#endif } else if (modeattacking) { @@ -4092,6 +4101,14 @@ static void M_DrawCenteredMenu(void) W_CachePatchName(currentMenu->menuitems[i].patch,PU_CACHE), graymap); y += LINEHEIGHT; break; + case IT_TRANSTEXT: + if (currentMenu->menuitems[i].alphaKey) + y = currentMenu->y+currentMenu->menuitems[i].alphaKey; + /* FALLTHRU */ + case IT_TRANSTEXT2: + V_DrawCenteredString(x, y, V_TRANSLUCENT, currentMenu->menuitems[i].text); + y += SMALLLINEHEIGHT; + break; } } From 7a201ea993d355f6b448548c4f1987bec50bccc7 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 27 Sep 2019 19:56:41 -0700 Subject: [PATCH 63/91] Hide Unlockables --- src/m_menu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/m_menu.c b/src/m_menu.c index ab13fdd8d..c971654fb 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -732,7 +732,9 @@ static menuitem_t SR_PandorasBox[] = // Sky Room Custom Unlocks static menuitem_t SR_MainMenu[] = { +#ifndef TESTERS {IT_STRING|IT_SUBMENU, NULL, "Unlockables", &SR_UnlockChecklistDef, 100}, +#endif {IT_CALL|IT_STRING|IT_CALL_NOTMODIFIED, NULL, "Statistics", M_Statistics, 108}, {IT_CALL|IT_STRING, NULL, "Replay Hut", M_ReplayHut, 116}, {IT_DISABLED, NULL, "", NULL, 0}, // Custom1 From 5ceff36ac1445b64bd16224acb3ce30e3ccdc024 Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 27 Sep 2019 19:58:55 -0700 Subject: [PATCH 64/91] Hide Multiplayer hosting options and Offline Mode --- src/m_menu.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/m_menu.c b/src/m_menu.c index c971654fb..ec5161cc6 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -89,6 +89,10 @@ int snprintf(char *str, size_t n, const char *fmt, ...); #define SLIDER_WIDTH (8*SLIDER_RANGE+6) #define SERVERS_PER_PAGE 11 +#if defined (NONET) || defined (TESTERS) +#define NOMENUHOST +#endif + typedef enum { QUITMSG = 0, @@ -968,12 +972,16 @@ static menuitem_t MP_MainMenu[] = {IT_STRING|IT_KEYHANDLER,NULL, "Player setup...", M_SetupMultiHandler,18}, {IT_HEADER, NULL, "Host a game", NULL, 100-24}, -#ifndef NONET +#ifndef NOMENUHOST {IT_STRING|IT_CALL, NULL, "Internet/LAN...", M_StartServerMenu, 110-24}, #else {IT_GRAYEDOUT, NULL, "Internet/LAN...", NULL, 110-24}, #endif +#ifdef TESTERS + {IT_GRAYEDOUT, NULL, "Offline...", NULL, 118-24}, +#else {IT_STRING|IT_CALL, NULL, "Offline...", M_StartOfflineServerMenu, 118-24}, +#endif {IT_HEADER, NULL, "Join a game", NULL, 132-24}, #ifndef NONET @@ -8830,7 +8838,7 @@ static void M_DrawMPMainMenu(void) // use generic drawer for cursor, items and title M_DrawGenericMenu(); -#ifndef NONET +#ifndef NOMENUHOST #if MAXPLAYERS != 16 Update the maxplayers label... #endif @@ -8838,10 +8846,12 @@ Update the maxplayers label... ((itemOn == 4) ? highlightflags : 0), "(2-16 players)"); #endif +#ifndef TESTERS V_DrawRightAlignedString(BASEVIDWIDTH-x, y+MP_MainMenu[5].alphaKey, ((itemOn == 5) ? highlightflags : 0), "(2-4 players)" ); +#endif #ifndef NONET y += MP_MainMenu[8].alphaKey; From e5b6ebaa4ede0c507872d5b1865d9f8786b1481c Mon Sep 17 00:00:00 2001 From: James R Date: Fri, 27 Sep 2019 20:00:46 -0700 Subject: [PATCH 65/91] Disable unused functions in TESTERS build --- src/m_menu.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/m_menu.c b/src/m_menu.c index ec5161cc6..3cab1e76c 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -245,14 +245,18 @@ static menu_t SP_TimeAttackDef, SP_ReplayDef, SP_GuestReplayDef, SP_GhostDef; // Multiplayer #ifndef NONET +#ifndef TESTERS static void M_StartServerMenu(INT32 choice); +#endif static void M_ConnectMenu(INT32 choice); static void M_ConnectMenuModChecks(INT32 choice); static void M_Refresh(INT32 choice); static void M_Connect(INT32 choice); static void M_ChooseRoom(INT32 choice); #endif +#ifndef TESTERS static void M_StartOfflineServerMenu(INT32 choice); +#endif static void M_StartServer(INT32 choice); static void M_SetupMultiPlayer(INT32 choice); static void M_SetupMultiPlayer2(INT32 choice); @@ -8801,6 +8805,7 @@ static void M_MapChange(INT32 choice) M_SetupNextMenu(&MISC_ChangeLevelDef); } +#ifndef TESTERS static void M_StartOfflineServerMenu(INT32 choice) { (void)choice; @@ -8808,8 +8813,10 @@ static void M_StartOfflineServerMenu(INT32 choice) M_PrepareLevelSelect(); M_SetupNextMenu(&MP_OfflineServerDef); } +#endif #ifndef NONET +#ifndef TESTERS static void M_StartServerMenu(INT32 choice) { (void)choice; @@ -8819,6 +8826,7 @@ static void M_StartServerMenu(INT32 choice) M_SetupNextMenu(&MP_ServerDef); } +#endif // ============== // CONNECT VIA IP From 7321a95a659c5497b18e47c0ec94525c82bd2801 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 28 Sep 2019 15:14:52 -0400 Subject: [PATCH 66/91] Ring respawn timer is based on lap count (proportional to 3 laps) --- src/p_mobj.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/p_mobj.c b/src/p_mobj.c index 05975f8df..56afd25fd 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11021,8 +11021,16 @@ void P_RespawnSpecials(void) if (pcount == 1) // No respawn when alone return; else if (pcount > 1) + { time = (180 - (pcount * 10))*TICRATE; + // If the map is longer or shorter than 3 laps, then adjust ring respawn to account for this. + // 5 lap courses would have more retreaded ground, while 2 lap courses would have less. + if ((mapheaderinfo[gamemap-1]->numlaps != 3) + && !(mapheaderinfo[gamemap-1]->levelflags & LF_SECTIONRACE)) + time = (time * 3) / mapheaderinfo[gamemap-1]->numlaps; + } + // only respawn items when cv_itemrespawn is on //if (!cv_itemrespawn.value) // TODO: remove this cvar //return; From 8fa5ada23d836f529248a069a6aaba88f8a70773 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 28 Sep 2019 15:16:08 -0400 Subject: [PATCH 67/91] Allow ring usage during Shrink --- src/k_kart.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_kart.c b/src/k_kart.c index 821f764d1..f603a0fa4 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5953,7 +5953,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) && NO_HYUDORO && !(HOLDING_ITEM || player->kartstuff[k_itemamount] || player->kartstuff[k_itemroulette] - || player->kartstuff[k_growshrinktimer] // Being disabled during Shrink was unintended but people seemed to be okay with it sooo... + || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_rocketsneakertimer] || player->kartstuff[k_eggmanexplode])) player->kartstuff[k_userings] = 1; From 7c40a1c07bf106d0024bec36cc70dc10335254ec Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 28 Sep 2019 15:18:01 -0400 Subject: [PATCH 68/91] Make sure it doesn't divide by 0 --- src/p_mobj.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 56afd25fd..3694fc919 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11028,7 +11028,7 @@ void P_RespawnSpecials(void) // 5 lap courses would have more retreaded ground, while 2 lap courses would have less. if ((mapheaderinfo[gamemap-1]->numlaps != 3) && !(mapheaderinfo[gamemap-1]->levelflags & LF_SECTIONRACE)) - time = (time * 3) / mapheaderinfo[gamemap-1]->numlaps; + time = (time * 3) / max(1, mapheaderinfo[gamemap-1]->numlaps); } // only respawn items when cv_itemrespawn is on From 217f61897fa3d6cad4b76ace3c7da5330933315d Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Wed, 2 Oct 2019 11:47:56 -0400 Subject: [PATCH 69/91] K_PlayerForfeit on I_Quit (I believe these are the only i_systems that matter?) --- src/djgppdos/i_system.c | 7 +++++++ src/sdl/i_system.c | 6 ++++++ src/sdl12/i_system.c | 6 ++++++ 3 files changed, 19 insertions(+) diff --git a/src/djgppdos/i_system.c b/src/djgppdos/i_system.c index bc3c8b2bc..b5785bb36 100644 --- a/src/djgppdos/i_system.c +++ b/src/djgppdos/i_system.c @@ -59,6 +59,8 @@ #include "../z_zone.h" #include "../g_input.h" +#include "../k_pwrlv.h" + #include "../console.h" #ifdef __GNUG__ @@ -618,6 +620,11 @@ void I_Quit (void) #ifndef NONET D_SaveBan(); // save the ban list #endif + + // Make sure you lose points for ALT-F4 + if (Playing()) + K_PlayerForfeit(consoleplayer, true); + G_SaveGameData(); // Tails 12-08-2002 if (demorecording) G_CheckDemoStatus(); diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index d24bd5ade..8695bd1fc 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -165,6 +165,7 @@ static char returnWadPath[256]; #include "../d_net.h" #include "../g_game.h" #include "../filesrch.h" +#include "../k_pwrlv.h" #include "endtxt.h" #include "sdlmain.h" @@ -3056,6 +3057,11 @@ void I_Quit(void) #ifndef NONET D_SaveBan(); // save the ban list #endif + + // Make sure you lose points for ALT-F4 + if (Playing()) + K_PlayerForfeit(consoleplayer, true); + G_SaveGameData(false); // Tails 12-08-2002 //added:16-02-98: when recording a demo, should exit using 'q' key, // but sometimes we forget and use 'F10'.. so save here too. diff --git a/src/sdl12/i_system.c b/src/sdl12/i_system.c index 62256f3a5..14d183748 100644 --- a/src/sdl12/i_system.c +++ b/src/sdl12/i_system.c @@ -233,6 +233,7 @@ static char returnWadPath[256]; #include "../d_net.h" #include "../g_game.h" #include "../filesrch.h" +#include "../k_pwrlv.h" #include "endtxt.h" #include "sdlmain.h" @@ -2977,6 +2978,11 @@ void I_Quit(void) #ifndef NONET D_SaveBan(); // save the ban list #endif + + // Make sure you lose points for ALT-F4 + if (Playing()) + K_PlayerForfeit(consoleplayer, true); + G_SaveGameData(); // Tails 12-08-2002 //added:16-02-98: when recording a demo, should exit using 'q' key, // but sometimes we forget and use 'F10'.. so save here too. From 7433becd7a44eb1cf492dbeb9d727c6eaa316305 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Wed, 2 Oct 2019 12:07:37 -0400 Subject: [PATCH 70/91] Move map loaded failure error from the deleted backwards compat code --- src/g_game.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/g_game.c b/src/g_game.c index ac7987291..2fbd106d5 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4914,7 +4914,6 @@ void G_ReadDemoExtraData(void) kartspeed = READUINT8(demo_p); kartweight = READUINT8(demo_p); - if (stricmp(skins[players[p].skin].name, name) != 0) FindClosestSkinForStats(p, kartspeed, kartweight); @@ -7198,6 +7197,19 @@ void G_DoPlayDemo(char *defdemoname) randseed = READUINT32(demo_p); demo_p += 4; // Extrainfo location + // ...*map* not loaded? + if (!gamemap || (gamemap > NUMMAPS) || !mapheaderinfo[gamemap-1] || !(mapheaderinfo[gamemap-1]->menuflags & LF2_EXISTSHACK)) + { + snprintf(msg, 1024, M_GetText("%s features a course that is not currently loaded.\n"), pdemoname); + CONS_Alert(CONS_ERROR, "%s", msg); + M_StartMessage(msg, NULL, MM_NOTHING); + Z_Free(pdemoname); + Z_Free(demobuffer); + demo.playback = false; + demo.title = false; + return; + } + // net var data CV_LoadNetVars(&demo_p); From 1b0ba7768c2a80c03e794ec50e79039c31e5f380 Mon Sep 17 00:00:00 2001 From: James R Date: Wed, 2 Oct 2019 13:57:14 -0700 Subject: [PATCH 71/91] False instead of 0, a little clearer --- src/d_clisrv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 024194155..3c7712c5a 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -3626,7 +3626,7 @@ boolean SV_SpawnServer(void) #ifdef TESTERS /* Just don't let the testers play. Easy. */ I_Error("What do you think you're doing?"); - return 0; + return false; #else if (demo.playback) G_StopDemo(); // reset engine parameter From 7f6d825809c561cc3bf73f887299742eff747d2f Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 3 Oct 2019 01:10:10 -0400 Subject: [PATCH 72/91] Remove unused GENESIS_WIPE define --- src/f_wipe.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/f_wipe.c b/src/f_wipe.c index 319d2b2f4..12887acf5 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -12,8 +12,6 @@ /// \file f_wipe.c /// \brief SRB2 2.1 custom fade mask "wipe" behavior. -#define GENESIS_WIPE // Sal: experimental Genesis-style colorful wipes - #include "f_finale.h" #include "i_video.h" #include "v_video.h" From a5ea6a97998d5b306df8eb9bd2a93e227354ac0b Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 3 Oct 2019 01:48:16 -0400 Subject: [PATCH 73/91] Merge speed/encore scrambles into the normal cvars as an "auto" option --- src/command.c | 12 ++++++++---- src/d_clisrv.c | 2 +- src/d_netcmd.c | 9 ++++----- src/d_netcmd.h | 2 -- src/g_game.c | 2 +- src/k_kart.c | 2 -- src/k_pwrlv.c | 6 +++--- src/p_setup.c | 4 ++-- 8 files changed, 19 insertions(+), 20 deletions(-) diff --git a/src/command.c b/src/command.c index 6d9c86d3e..664eb950c 100644 --- a/src/command.c +++ b/src/command.c @@ -70,8 +70,12 @@ CV_PossibleValue_t CV_Natural[] = {{1, "MIN"}, {999999999, "MAX"}, {0, NULL}}; //SRB2kart CV_PossibleValue_t kartspeed_cons_t[] = { - {0, "Easy"}, {1, "Normal"}, {2, "Hard"}, - {0, NULL}}; + {-1, "Auto"}, + {0, "Easy"}, + {1, "Normal"}, + {2, "Hard"}, + {0, NULL} +}; // Filter consvars by EXECVERSION // First implementation is 2 (1.0.2), so earlier configs default at 1 (1.0.0) @@ -1769,7 +1773,7 @@ void CV_AddValue(consvar_t *var, INT32 increment) { newvalue = var->value + 1; if (newvalue > maxspeed) - newvalue = 0; + newvalue = -1; var->value = newvalue; var->string = var->PossibleValue[var->value].strvalue; var->func(); @@ -1778,7 +1782,7 @@ void CV_AddValue(consvar_t *var, INT32 increment) else if (increment < 0) // Going down! { newvalue = var->value - 1; - if (newvalue < 0) + if (newvalue < -1) newvalue = maxspeed; var->value = newvalue; var->string = var->PossibleValue[var->value].strvalue; diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 523c92778..d67f6b48e 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1351,7 +1351,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled(); netbuffer->u.serverinfo.kartvars = (UINT8) ( - (cv_kartspeed.value & SV_SPEEDMASK) | + (gamespeed & SV_SPEEDMASK) | (dedicated ? SV_DEDICATED : 0) | (D_IsJoinPasswordOn() ? SV_PASSWORD : 0) ); diff --git a/src/d_netcmd.c b/src/d_netcmd.c index a5085864e..29a09fb06 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -360,12 +360,13 @@ consvar_t cv_kartminimap = {"kartminimap", "4", CV_SAVE, kartminimap_cons_t, NUL consvar_t cv_kartcheck = {"kartcheck", "Yes", CV_SAVE, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t kartinvinsfx_cons_t[] = {{0, "Music"}, {1, "SFX"}, {0, NULL}}; consvar_t cv_kartinvinsfx = {"kartinvinsfx", "SFX", CV_SAVE, kartinvinsfx_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_kartspeed = {"kartspeed", "Normal", CV_NETVAR|CV_CALL|CV_NOINIT, kartspeed_cons_t, KartSpeed_OnChange, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_kartspeed = {"kartspeed", "Auto", CV_NETVAR|CV_CALL|CV_NOINIT, kartspeed_cons_t, KartSpeed_OnChange, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t kartbumpers_cons_t[] = {{1, "MIN"}, {12, "MAX"}, {0, NULL}}; consvar_t cv_kartbumpers = {"kartbumpers", "3", CV_NETVAR|CV_CHEAT, kartbumpers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartfrantic = {"kartfrantic", "Off", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOINIT, CV_OnOff, KartFrantic_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartcomeback = {"kartcomeback", "On", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOINIT, CV_OnOff, KartComeback_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_kartencore = {"kartencore", "Off", CV_NETVAR|CV_CALL|CV_NOINIT, CV_OnOff, KartEncore_OnChange, 0, NULL, NULL, 0, 0, NULL}; +static CV_PossibleValue_t kartencore_cons_t[] = {{-1, "Auto"}, {0, "Off"}, {1, "On"}, {0, NULL}}; +consvar_t cv_kartencore = {"kartencore", "Auto", CV_NETVAR|CV_CALL|CV_NOINIT, kartencore_cons_t, KartEncore_OnChange, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t kartvoterulechanges_cons_t[] = {{0, "Never"}, {1, "Sometimes"}, {2, "Frequent"}, {3, "Always"}, {0, NULL}}; consvar_t cv_kartvoterulechanges = {"kartvoterulechanges", "Frequent", CV_NETVAR, kartvoterulechanges_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t kartspeedometer_cons_t[] = {{0, "Off"}, {1, "Percentage"}, {2, "Kilometers"}, {3, "Miles"}, {4, "Fracunits"}, {0, NULL}}; @@ -376,8 +377,6 @@ consvar_t cv_kartvoices = {"kartvoices", "Tasteful", CV_SAVE, kartvoices_cons_t, consvar_t cv_karteliminatelast = {"karteliminatelast", "Yes", CV_NETVAR|CV_CHEAT|CV_CALL|CV_NOSHOWHELP, CV_YesNo, KartEliminateLast_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_kartusepwrlv = {"kartusepwrlv", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_speedscramble = {"kartscramblespeed", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_encorescramble = {"kartscrambleencore", "Yes", CV_NETVAR|CV_CHEAT, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t kartdebugitem_cons_t[] = {{-1, "MIN"}, {NUMKARTITEMS-1, "MAX"}, {0, NULL}}; consvar_t cv_kartdebugitem = {"kartdebugitem", "0", CV_NETVAR|CV_CHEAT|CV_NOSHOWHELP, kartdebugitem_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -5783,7 +5782,7 @@ static void KartSpeed_OnChange(void) if (!M_SecretUnlocked(SECRET_HARDSPEED) && cv_kartspeed.value == 2) { CONS_Printf(M_GetText("You haven't earned this yet.\n")); - CV_StealthSetValue(&cv_kartspeed, 1); + CV_StealthSetValue(&cv_kartspeed, cv_kartspeed.defaultvalue); return; } diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 7d81f1164..d1f28665c 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -122,8 +122,6 @@ extern consvar_t cv_kartspeedometer; extern consvar_t cv_kartvoices; extern consvar_t cv_karteliminatelast; extern consvar_t cv_kartusepwrlv; -extern consvar_t cv_speedscramble; -extern consvar_t cv_encorescramble; extern consvar_t cv_votetime; diff --git a/src/g_game.c b/src/g_game.c index 4459abe52..642f62bc1 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3408,7 +3408,7 @@ INT16 G_SometimesGetDifferentGametype(void) randmapbuffer[NUMMAPS]--; if (encorepossible) { - if (encorescramble >= 0) + if (encorescramble != -1) encorepossible = (boolean)encorescramble; // FORCE to what was scrambled on intermission else { diff --git a/src/k_kart.c b/src/k_kart.c index 83b48c4a9..230662d2a 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -580,8 +580,6 @@ void K_RegisterKartStuff(void) CV_RegisterVar(&cv_kartvoices); CV_RegisterVar(&cv_karteliminatelast); CV_RegisterVar(&cv_kartusepwrlv); - CV_RegisterVar(&cv_speedscramble); - CV_RegisterVar(&cv_encorescramble); CV_RegisterVar(&cv_votetime); CV_RegisterVar(&cv_kartdebugitem); diff --git a/src/k_pwrlv.c b/src/k_pwrlv.c index 31a4bd314..c1096d4a3 100644 --- a/src/k_pwrlv.c +++ b/src/k_pwrlv.c @@ -118,7 +118,7 @@ void K_SetPowerLevelScrambles(SINT8 powertype) switch (powertype) { case PWRLV_RACE: - if (cv_speedscramble.value || cv_encorescramble.value) + if (cv_kartspeed.value == -1 || cv_kartencore.value == -1) { boolean hardmode = false; boolean encore = false; @@ -187,12 +187,12 @@ void K_SetPowerLevelScrambles(SINT8 powertype) break; } - if (cv_speedscramble.value) + if (cv_kartspeed.value == -1) speedscramble = (hardmode ? 2 : 1); else speedscramble = -1; - if (cv_encorescramble.value) + if (cv_kartencore.value == -1) encorescramble = (encore ? 1 : 0); else encorescramble = -1; diff --git a/src/p_setup.c b/src/p_setup.c index 3498c443b..7ffe84d0a 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2398,8 +2398,8 @@ static void P_LevelInitStuff(void) gamespeed = 0; else { - if (cv_speedscramble.value && speedscramble != -1) - gamespeed = (UINT8)speedscramble; + if (cv_kartspeed.value == -1) + gamespeed = ((speedscramble == -1) ? cv_kartspeed.defaultvalue : (UINT8)speedscramble); else gamespeed = (UINT8)cv_kartspeed.value; } From 12829743ae1b99737bfcfc03f1850c0954fcd540 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 3 Oct 2019 01:54:52 -0400 Subject: [PATCH 74/91] Add easy scrambles to the list now that easy is playable --- src/k_pwrlv.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/k_pwrlv.c b/src/k_pwrlv.c index c1096d4a3..e43348362 100644 --- a/src/k_pwrlv.c +++ b/src/k_pwrlv.c @@ -120,7 +120,7 @@ void K_SetPowerLevelScrambles(SINT8 powertype) case PWRLV_RACE: if (cv_kartspeed.value == -1 || cv_kartencore.value == -1) { - boolean hardmode = false; + UINT8 speed = cv_kartspeed.defaultvalue; boolean encore = false; INT16 avg = 0, min = 0; UINT8 i, t = 0; @@ -167,28 +167,29 @@ void K_SetPowerLevelScrambles(SINT8 powertype) switch (t) { case 4: - hardmode = encore = true; + speed = 2; + encore = true; break; case 3: - hardmode = true; + speed = M_RandomChance((7<>1); break; case 2: - hardmode = M_RandomChance((7<>2); break; - case 1: - hardmode = M_RandomChance((3< Date: Thu, 3 Oct 2019 10:16:10 -0400 Subject: [PATCH 75/91] atoi --- src/d_netcmd.c | 2 +- src/k_pwrlv.c | 2 +- src/p_setup.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 29a09fb06..e5a7109a9 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -5782,7 +5782,7 @@ static void KartSpeed_OnChange(void) if (!M_SecretUnlocked(SECRET_HARDSPEED) && cv_kartspeed.value == 2) { CONS_Printf(M_GetText("You haven't earned this yet.\n")); - CV_StealthSetValue(&cv_kartspeed, cv_kartspeed.defaultvalue); + CV_StealthSet(&cv_kartspeed, cv_kartspeed.defaultvalue); return; } diff --git a/src/k_pwrlv.c b/src/k_pwrlv.c index e43348362..2f0d3f2e1 100644 --- a/src/k_pwrlv.c +++ b/src/k_pwrlv.c @@ -120,7 +120,7 @@ void K_SetPowerLevelScrambles(SINT8 powertype) case PWRLV_RACE: if (cv_kartspeed.value == -1 || cv_kartencore.value == -1) { - UINT8 speed = cv_kartspeed.defaultvalue; + UINT8 speed = atoi(cv_kartspeed.defaultvalue); boolean encore = false; INT16 avg = 0, min = 0; UINT8 i, t = 0; diff --git a/src/p_setup.c b/src/p_setup.c index 7ffe84d0a..5ec0f97e6 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2399,7 +2399,7 @@ static void P_LevelInitStuff(void) else { if (cv_kartspeed.value == -1) - gamespeed = ((speedscramble == -1) ? cv_kartspeed.defaultvalue : (UINT8)speedscramble); + gamespeed = ((speedscramble == -1) ? atoi(cv_kartspeed.defaultvalue) : (UINT8)speedscramble); else gamespeed = (UINT8)cv_kartspeed.value; } From 37009ac9b040fb1340d44e8a24fb38e605c8eade Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 3 Oct 2019 10:31:34 -0400 Subject: [PATCH 76/91] A few stashed fixes that didn't make it to the branches somehow --- src/f_wipe.c | 8 +++++--- src/info.c | 7 ------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/src/f_wipe.c b/src/f_wipe.c index 12887acf5..8d73c1fe7 100644 --- a/src/f_wipe.c +++ b/src/f_wipe.c @@ -461,11 +461,13 @@ void F_RunWipe(UINT8 wipetype, boolean drawMenu, const char *colormap, boolean r #endif F_DoWipe(fmask, fcolor, reverse); -#ifndef HWRENDER if (encorewiggle) - F_DoEncoreWiggle(wipeframe); // Can't think of a better way to run this on fades, unfortunately. + { +#ifdef HWRENDER + if (rendermode != render_opengl) #endif - + F_DoEncoreWiggle(wipeframe); + } I_OsPolling(); I_UpdateNoBlit(); diff --git a/src/info.c b/src/info.c index c960ebff6..4f448cc00 100644 --- a/src/info.c +++ b/src/info.c @@ -20382,13 +20382,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // damage sfx_None, // activesound MF_NOBLOCKMAP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags - 8< Date: Thu, 3 Oct 2019 11:22:58 -0400 Subject: [PATCH 77/91] Fix a few messups due to the merged cvars --- src/d_main.c | 2 +- src/d_netcmd.c | 10 +++++----- src/g_game.c | 6 +++--- src/hu_stuff.c | 2 +- src/m_menu.c | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 05a9fa603..597eea87c 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1559,7 +1559,7 @@ void D_SRB2Main(void) else if (!dedicated && M_MapLocked(pstartmap)) I_Error("You need to unlock this level before you can warp to it!\n"); else - D_MapChange(pstartmap, gametype, (boolean)cv_kartencore.value, true, 0, false, false); + D_MapChange(pstartmap, gametype, (cv_kartencore.value == 1), true, 0, false, false); } } else if (M_CheckParm("-skipintro")) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index e5a7109a9..51ec3b980 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2395,7 +2395,7 @@ void D_SetupVote(void) UINT8 secondgt = G_SometimesGetDifferentGametype(); INT16 votebuffer[3] = {-1,-1,-1}; - if (cv_kartencore.value && G_RaceGametype()) + if ((cv_kartencore.value == 1) && G_RaceGametype()) WRITEUINT8(p, (gametype|0x80)); else WRITEUINT8(p, gametype); @@ -2566,7 +2566,7 @@ static void Command_Map_f(void) // new encoremode value // use cvar by default - newencoremode = (boolean)cv_kartencore.value; + newencoremode = (cv_kartencore.value == 1); if (COM_CheckParm("-encore")) { @@ -5802,10 +5802,10 @@ static void KartEncore_OnChange(void) { if (G_RaceGametype()) { - if ((boolean)cv_kartencore.value != encoremode && gamestate == GS_LEVEL /*&& leveltime > starttime*/) - CONS_Printf(M_GetText("Encore Mode will be turned %s next round.\n"), cv_kartencore.value ? M_GetText("on") : M_GetText("off")); + if ((cv_kartencore.value == 1) != encoremode && gamestate == GS_LEVEL /*&& leveltime > starttime*/) + CONS_Printf(M_GetText("Encore Mode will be set to %s next round.\n"), cv_kartencore.string); else - CONS_Printf(M_GetText("Encore Mode has been turned %s.\n"), cv_kartencore.value ? M_GetText("on") : M_GetText("off")); + CONS_Printf(M_GetText("Encore Mode has been set to %s.\n"), cv_kartencore.string); } } diff --git a/src/g_game.c b/src/g_game.c index 642f62bc1..d5ed9af7d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2340,7 +2340,7 @@ void G_Ticker(boolean run) G_DoReborn(consoleplayer);*/ - D_MapChange(gamemap, gametype, cv_kartencore.value, true, 1, false, false); + D_MapChange(gamemap, gametype, (cv_kartencore.value == 1), true, 1, false, false); } for (i = 0; i < MAXPLAYERS; i++) @@ -3426,7 +3426,7 @@ INT16 G_SometimesGetDifferentGametype(void) break; } } - if (encorepossible != (boolean)cv_kartencore.value) + if (encorepossible != (cv_kartencore.value == 1)) return (gametype|0x80); } return gametype; @@ -3903,7 +3903,7 @@ void G_NextLevel(void) } forceresetplayers = false; - deferencoremode = (boolean)cv_kartencore.value; + deferencoremode = (cv_kartencore.value == 1); } gameaction = ga_worlddone; diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 38324dbd9..dc8ca0dd2 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -3017,7 +3017,7 @@ static void HU_DrawRankings(void) } V_DrawCenteredString(256, 8, 0, "GAME SPEED"); - V_DrawCenteredString(256, 16, hilicol, cv_kartspeed.string); + V_DrawCenteredString(256, 16, hilicol, kartspeed_cons_t[gamespeed].string); } // When you play, you quickly see your score because your name is displayed in white. diff --git a/src/m_menu.c b/src/m_menu.c index 4a3102925..d0d818db6 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -8644,11 +8644,11 @@ static void M_StartServer(INT32 choice) paused = false; SV_StartSinglePlayerServer(); multiplayer = true; // yeah, SV_StartSinglePlayerServer clobbers this... - D_MapChange(cv_nextmap.value, cv_newgametype.value, (boolean)cv_kartencore.value, 1, 1, false, false); + D_MapChange(cv_nextmap.value, cv_newgametype.value, (cv_kartencore.value == 1), 1, 1, false, false); } else { - D_MapChange(cv_nextmap.value, cv_newgametype.value, (boolean)cv_kartencore.value, 1, 1, false, false); + D_MapChange(cv_nextmap.value, cv_newgametype.value, (cv_kartencore.value == 1), 1, 1, false, false); COM_BufAddText("dummyconsvar 1\n"); } @@ -8685,7 +8685,7 @@ static void M_DrawLevelSelectOnly(boolean leftfade, boolean rightfade) V_DrawFill(x-1, y-1, w+2, i+2, trans); // variable reuse... - if (!cv_kartencore.value || gamestate == GS_TIMEATTACK || cv_newgametype.value != GT_RACE) + if ((cv_kartencore.value != 1) || gamestate == GS_TIMEATTACK || cv_newgametype.value != GT_RACE) V_DrawSmallScaledPatch(x, y, 0, PictureOfLevel); else { From bcd142c2a0f3d117df2338b5d6de1093887f7cb1 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 3 Oct 2019 11:36:35 -0400 Subject: [PATCH 78/91] Start at 5000, rebalance scrambles --- src/k_pwrlv.c | 33 ++++++++++++++++++++++----------- src/k_pwrlv.h | 2 +- 2 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/k_pwrlv.c b/src/k_pwrlv.c index 2f0d3f2e1..257b8ad06 100644 --- a/src/k_pwrlv.c +++ b/src/k_pwrlv.c @@ -133,30 +133,37 @@ void K_SetPowerLevelScrambles(SINT8 powertype) min = clientpowerlevels[i][0]; } - if (min >= 6000) + if (min >= 7800) { - if (avg >= 8000) + if (avg >= 8200) + t = 5; + else + t = 4; + } + else if (min >= 6800) + { + if (avg >= 7200) t = 4; else t = 3; } - else if (min >= 4000) + else if (min >= 5800) { - if (avg >= 5000) + if (avg >= 6200) t = 3; else t = 2; } - else if (min >= 2500) + else if (min >= 3800) { - if (avg >= 3000) + if (avg >= 4200) t = 2; else t = 1; } - else if (min >= 500) + else if (min >= 1800) { - if (avg >= 2000) + if (avg >= 2200) t = 1; else t = 0; @@ -166,18 +173,22 @@ void K_SetPowerLevelScrambles(SINT8 powertype) switch (t) { - case 4: + case 5: speed = 2; encore = true; break; - case 3: + case 4: speed = M_RandomChance((7<>1); break; - case 2: + case 3: speed = M_RandomChance((3<>2); break; + case 2: + speed = 1; + encore = M_RandomChance(FRACUNIT>>3); + break; case 1: default: speed = 1; encore = false; diff --git a/src/k_pwrlv.h b/src/k_pwrlv.h index dfa300114..1dae566ed 100644 --- a/src/k_pwrlv.h +++ b/src/k_pwrlv.h @@ -9,7 +9,7 @@ #define PWRLV_BATTLE 1 #define PWRLV_NUMTYPES 2 -#define PWRLVRECORD_START 1000 +#define PWRLVRECORD_START 5000 //1000 #define PWRLVRECORD_DEF 5000 #define PWRLVRECORD_MIN 1 #define PWRLVRECORD_MAX 9999 From 706c6be627ba8147088ae05ce9a62046c779ed1f Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 3 Oct 2019 11:37:58 -0400 Subject: [PATCH 79/91] Wrong var name --- src/hu_stuff.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hu_stuff.c b/src/hu_stuff.c index dc8ca0dd2..6126f7bec 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -3017,7 +3017,7 @@ static void HU_DrawRankings(void) } V_DrawCenteredString(256, 8, 0, "GAME SPEED"); - V_DrawCenteredString(256, 16, hilicol, kartspeed_cons_t[gamespeed].string); + V_DrawCenteredString(256, 16, hilicol, kartspeed_cons_t[gamespeed].strvalue); } // When you play, you quickly see your score because your name is displayed in white. From 03ec42da6da6b334901b5a3b3dd8b350b460c102 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 3 Oct 2019 11:46:00 -0400 Subject: [PATCH 80/91] Back to 1000 --- src/k_pwrlv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/k_pwrlv.h b/src/k_pwrlv.h index 1dae566ed..05fbf1c8a 100644 --- a/src/k_pwrlv.h +++ b/src/k_pwrlv.h @@ -9,7 +9,7 @@ #define PWRLV_BATTLE 1 #define PWRLV_NUMTYPES 2 -#define PWRLVRECORD_START 5000 //1000 +#define PWRLVRECORD_START 1000 // 5000? #define PWRLVRECORD_DEF 5000 #define PWRLVRECORD_MIN 1 #define PWRLVRECORD_MAX 9999 From f1e5f64e66f4c9809bf825909e68b03ad065c0a6 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 5 Oct 2019 12:38:44 -0700 Subject: [PATCH 81/91] Use K_MatchGenericExtraFlags for reverse gravity rings Also corrected a mistaken usage of scale. --- src/p_enemy.c | 22 ++++++++-------------- src/p_mobj.c | 17 ++++++----------- 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 3c59c40f5..aadb27329 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3558,8 +3558,6 @@ void A_BubbleCheck(mobj_t *actor) // void A_AttractChase(mobj_t *actor) { - fixed_t z; - #ifdef HAVE_BLUA if (LUA_CallAction("A_AttractChase", actor)) return; @@ -3603,12 +3601,11 @@ void A_AttractChase(mobj_t *actor) { fixed_t offz = FixedMul(80*actor->target->scale, FINESINE(FixedAngle((90 - (9 * abs(10 - actor->extravalue1))) << FRACBITS) >> ANGLETOFINESHIFT)); //P_SetScale(actor, (actor->destscale = actor->target->scale)); - z = actor->target->z; - if (( actor->eflags & MFE_VERTICALFLIP )) - z -= actor->height + offz; - else - z += actor->target->height + offz; - P_TeleportMove(actor, actor->target->x, actor->target->y, z); + actor->z = actor->target->z; + K_MatchGenericExtraFlags(actor, actor->target); + P_TeleportMove(actor, actor->target->x, actor->target->y, + actor->z + + ( actor->target->height + offz )* P_MobjFlip(actor)); actor->extravalue1++; } } @@ -3635,15 +3632,12 @@ void A_AttractChase(mobj_t *actor) fixed_t dist = (actor->target->radius/4) * (16 - actor->extravalue1); P_SetScale(actor, (actor->destscale = actor->target->scale - ((actor->target->scale/14) * actor->extravalue1))); - z = actor->target->z; - if (( actor->eflags & MFE_VERTICALFLIP )) - z += actor->target->height - actor->height - 24 * actor->target->scale; - else - z += 24 * actor->target->scale; + actor->z = actor->target->z; + K_MatchGenericExtraFlags(actor, actor->target); P_TeleportMove(actor, actor->target->x + FixedMul(dist, FINECOSINE(actor->angle >> ANGLETOFINESHIFT)), actor->target->y + FixedMul(dist, FINESINE(actor->angle >> ANGLETOFINESHIFT)), - z); + actor->z + FixedMul(actor->target->scale, 24<angle += ANG30; actor->extravalue1++; diff --git a/src/p_mobj.c b/src/p_mobj.c index b1d862718..f54eca41e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8744,18 +8744,13 @@ void P_MobjThinker(mobj_t *mobj) return; } + mobj->z = mobj->target->z; + K_MatchGenericExtraFlags(mobj, mobj->target); - { - fixed_t z; - z = mobj->target->z; - if (( mobj->eflags & MFE_VERTICALFLIP )) - z -= mobj->height; - else - z += mobj->target->height; - P_TeleportMove(mobj, mobj->target->x + FINECOSINE(mobj->angle >> ANGLETOFINESHIFT), - mobj->target->y + FINESINE(mobj->angle >> ANGLETOFINESHIFT), - z); - } + + P_TeleportMove(mobj, mobj->target->x + FINECOSINE(mobj->angle >> ANGLETOFINESHIFT), + mobj->target->y + FINESINE(mobj->angle >> ANGLETOFINESHIFT), + mobj->z + mobj->target->height * P_MobjFlip(mobj)); break; case MT_TIREGREASE: if (!mobj->target || P_MobjWasRemoved(mobj->target) || !mobj->target->player From 675c896417a0c2f5b67c01dddd20a63b0a01c718 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 5 Oct 2019 12:46:24 -0700 Subject: [PATCH 82/91] Nevermind the FixedMul --- src/p_enemy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index aadb27329..76f6b3159 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3637,7 +3637,7 @@ void A_AttractChase(mobj_t *actor) P_TeleportMove(actor, actor->target->x + FixedMul(dist, FINECOSINE(actor->angle >> ANGLETOFINESHIFT)), actor->target->y + FixedMul(dist, FINESINE(actor->angle >> ANGLETOFINESHIFT)), - actor->z + FixedMul(actor->target->scale, 24<z + actor->target->scale * 24 * P_MobjFlip(actor)); actor->angle += ANG30; actor->extravalue1++; From fa09c0420fe11049c22b6c803b8dd87f9aa3b18b Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 5 Oct 2019 13:15:36 -0700 Subject: [PATCH 83/91] Custom gamedata parameter --- src/g_game.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index d5ed9af7d..15a22f493 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4082,6 +4082,11 @@ void G_LoadGameData(void) if (M_CheckParm("-resetdata")) return; // Don't load (essentially, reset). + if (M_CheckParm("-gamedata") && M_IsNextParm()) + { + strlcpy(gamedatafilename, M_GetNextParm(), sizeof gamedatafilename); + } + length = FIL_ReadFile(va(pandf, srb2home, gamedatafilename), &savebuffer); if (!length) // Aw, no game data. Their loss! return; From 027dec67025481e19ec00cb43d8336ed25982672 Mon Sep 17 00:00:00 2001 From: wolfy852 Date: Sat, 5 Oct 2019 19:07:26 -0500 Subject: [PATCH 84/91] Fix Ring Drain sectors for v2 rings --- src/p_spec.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index aa43583a4..93e88e2ce 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3637,10 +3637,9 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers break; case 9: // Ring Drainer (Floor Touch) case 10: // Ring Drainer (No Floor Touch) - if (leveltime % (TICRATE/2) == 0 && player->mo->health > 1) + if (leveltime % (TICRATE/2) == 0 && player->kartstuff[k_rings] > 0) { - player->mo->health--; - player->health--; + player->kartstuff[k_rings]--; S_StartSound(player->mo, sfx_itemup); } break; From c963a49542607e5829c8cc2b0f7510d6fc7eb8fb Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 17 Oct 2019 23:43:06 -0400 Subject: [PATCH 85/91] Try fixing Auto causing desyncs - Move K_SetPowerLevelScrambles to G_DoCompleted - Fix wrong gamespeed being displayed in strings - Add defines for kartspeed values - Disable Easy scrambles again - Corrupt gamedata if pwrlv is in invalid range (gets corrected in-game, and doesn't really matter to anyone who knows what you're doing, but it'll stop at least the most basic script kiddie) Replay menu will still display wrong speed name, but it's fine in the replay itself. --- src/command.c | 10 +++++----- src/command.h | 4 ++++ src/d_main.c | 3 ++- src/d_netcmd.c | 10 ++++++---- src/g_game.c | 19 ++++++++++++++++-- src/g_game.h | 2 +- src/hu_stuff.c | 2 +- src/k_pwrlv.c | 54 ++++++++++++++++++++++++++++++++++++++++---------- src/m_menu.c | 4 ++-- src/p_saveg.c | 6 ++++++ src/p_setup.c | 8 ++++---- src/y_inter.c | 6 ++---- 12 files changed, 93 insertions(+), 35 deletions(-) diff --git a/src/command.c b/src/command.c index 664eb950c..625065120 100644 --- a/src/command.c +++ b/src/command.c @@ -68,12 +68,12 @@ CV_PossibleValue_t CV_YesNo[] = {{0, "No"}, {1, "Yes"}, {0, NULL}}; CV_PossibleValue_t CV_Unsigned[] = {{0, "MIN"}, {999999999, "MAX"}, {0, NULL}}; CV_PossibleValue_t CV_Natural[] = {{1, "MIN"}, {999999999, "MAX"}, {0, NULL}}; -//SRB2kart +// SRB2kart CV_PossibleValue_t kartspeed_cons_t[] = { - {-1, "Auto"}, - {0, "Easy"}, - {1, "Normal"}, - {2, "Hard"}, + {KARTSPEED_AUTO, "Auto"}, + {KARTSPEED_EASY, "Easy"}, + {KARTSPEED_NORMAL, "Normal"}, + {KARTSPEED_HARD, "Hard"}, {0, NULL} }; diff --git a/src/command.h b/src/command.h index 6b5d513ef..33d232bcb 100644 --- a/src/command.h +++ b/src/command.h @@ -131,6 +131,10 @@ extern CV_PossibleValue_t CV_Unsigned[]; extern CV_PossibleValue_t CV_Natural[]; // SRB2kart +#define KARTSPEED_AUTO -1 +#define KARTSPEED_EASY 0 +#define KARTSPEED_NORMAL 1 +#define KARTSPEED_HARD 2 extern CV_PossibleValue_t kartspeed_cons_t[]; extern consvar_t cv_execversion; diff --git a/src/d_main.c b/src/d_main.c index 597eea87c..dee752107 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1536,10 +1536,11 @@ void D_SRB2Main(void) newskill = (INT16)kartspeed_cons_t[j].value; break; } + if (!kartspeed_cons_t[j].strvalue) // reached end of the list with no match { j = atoi(sskill); // assume they gave us a skill number, which is okay too - if (j >= 0 && j <= 2) + if (j >= KARTSPEED_EASY && j <= KARTSPEED_HARD) newskill = (INT16)j; } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 51ec3b980..db0c00086 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -5779,7 +5779,7 @@ static void KartFrantic_OnChange(void) static void KartSpeed_OnChange(void) { - if (!M_SecretUnlocked(SECRET_HARDSPEED) && cv_kartspeed.value == 2) + if (!M_SecretUnlocked(SECRET_HARDSPEED) && cv_kartspeed.value == KARTSPEED_HARD) { CONS_Printf(M_GetText("You haven't earned this yet.\n")); CV_StealthSet(&cv_kartspeed, cv_kartspeed.defaultvalue); @@ -5788,13 +5788,15 @@ static void KartSpeed_OnChange(void) if (G_RaceGametype()) { - if ((UINT8)cv_kartspeed.value != gamespeed && gamestate == GS_LEVEL && leveltime > starttime) - CONS_Printf(M_GetText("Game speed will be changed to \"%s\" next round.\n"), cv_kartspeed.string); - else + if ((gamestate == GS_LEVEL && leveltime < starttime) && (cv_kartspeed.value != KARTSPEED_AUTO)) { CONS_Printf(M_GetText("Game speed has been changed to \"%s\".\n"), cv_kartspeed.string); gamespeed = (UINT8)cv_kartspeed.value; } + else if (cv_kartspeed.value != (signed)gamespeed) + { + CONS_Printf(M_GetText("Game speed will be changed to \"%s\" next round.\n"), cv_kartspeed.string); + } } } diff --git a/src/g_game.c b/src/g_game.c index d5ed9af7d..5a0960c36 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3687,6 +3687,7 @@ static void G_DoCompleted(void) { INT32 i, j = 0; boolean gottoken = false; + SINT8 powertype = PWRLV_DISABLED; tokenlist = 0; // Reset the list @@ -3825,13 +3826,23 @@ static void G_DoCompleted(void) nextmap = G_RandMap(G_TOLFlag(gametype), prevmap, false, 0, false, NULL); } - // We are committed to this map now. // We may as well allocate its header if it doesn't exist // (That is, if it's a real map) if (nextmap < NUMMAPS && !mapheaderinfo[nextmap]) P_AllocMapHeader(nextmap); + // Set up power level gametype scrambles + if (netgame && cv_kartusepwrlv.value) + { + if (G_RaceGametype()) + powertype = PWRLV_RACE; + else if (G_BattleGametype()) + powertype = PWRLV_BATTLE; + } + + K_SetPowerLevelScrambles(powertype); + demointermission: if (skipstats && !modeattacking) // Don't skip stats if we're in record attack @@ -4104,7 +4115,11 @@ void G_LoadGameData(void) matchesplayed = READUINT32(save_p); for (i = 0; i < PWRLV_NUMTYPES; i++) + { vspowerlevel[i] = READUINT16(save_p); + if (vspowerlevel[i] < PWRLVRECORD_MIN || vspowerlevel[i] > PWRLVRECORD_MAX) + goto datacorrupt; + } modded = READUINT8(save_p); @@ -6896,7 +6911,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo) extrainfo_p = infobuffer + READUINT32(info_p); // Pared down version of CV_LoadNetVars to find the kart speed - pdemo->kartspeed = 1; // Default to normal speed + pdemo->kartspeed = KARTSPEED_NORMAL; // Default to normal speed count = READUINT16(info_p); while (count--) { diff --git a/src/g_game.h b/src/g_game.h index a69f91421..de482fe7f 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -80,7 +80,7 @@ typedef struct menudemo_s { UINT16 map; UINT8 addonstatus; // What do we need to do addon-wise to play this demo? UINT8 gametype; - UINT8 kartspeed; // Add OR DF_ENCORE for encore mode, idk + SINT8 kartspeed; // Add OR DF_ENCORE for encore mode, idk UINT8 numlaps; struct { diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 6126f7bec..1afa133b3 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -3017,7 +3017,7 @@ static void HU_DrawRankings(void) } V_DrawCenteredString(256, 8, 0, "GAME SPEED"); - V_DrawCenteredString(256, 16, hilicol, kartspeed_cons_t[gamespeed].strvalue); + V_DrawCenteredString(256, 16, hilicol, kartspeed_cons_t[1+gamespeed].strvalue); } // When you play, you quickly see your score because your name is displayed in white. diff --git a/src/k_pwrlv.c b/src/k_pwrlv.c index 257b8ad06..b1848f04b 100644 --- a/src/k_pwrlv.c +++ b/src/k_pwrlv.c @@ -83,7 +83,10 @@ INT16 K_CalculatePowerLevelAvg(void) UINT8 i; if (!netgame || !cv_kartusepwrlv.value) + { + CONS_Printf("Not in a netgame, or not using power levels -- no average.\n"); return 0; // No average. + } if (G_RaceGametype()) t = PWRLV_RACE; @@ -91,7 +94,10 @@ INT16 K_CalculatePowerLevelAvg(void) t = PWRLV_BATTLE; if (t == PWRLV_DISABLED) + { + CONS_Printf("Could not set a power level type -- no average.\n"); return 0; // Hmm?! + } for (i = 0; i < MAXPLAYERS; i++) { @@ -99,12 +105,15 @@ INT16 K_CalculatePowerLevelAvg(void) || clientpowerlevels[i][t] == 0) // splitscreen player continue; - avg += clientpowerlevels[i][t]; + avg += (clientpowerlevels[i][t] << FRACBITS); div++; } if (!div) + { + CONS_Printf("Found no players -- no average.\n"); return 0; // No average. + } avg /= div; @@ -120,19 +129,32 @@ void K_SetPowerLevelScrambles(SINT8 powertype) case PWRLV_RACE: if (cv_kartspeed.value == -1 || cv_kartencore.value == -1) { - UINT8 speed = atoi(cv_kartspeed.defaultvalue); + UINT8 speed = KARTSPEED_NORMAL; boolean encore = false; INT16 avg = 0, min = 0; - UINT8 i, t = 0; + UINT8 i, t = 1; avg = K_CalculatePowerLevelAvg(); for (i = 0; i < MAXPLAYERS; i++) { + if (!playeringame[i] || players[i].spectator + || clientpowerlevels[i][t] == 0) // splitscreen player + continue; + if (min == 0 || clientpowerlevels[i][0] < min) min = clientpowerlevels[i][0]; } + CONS_Printf("Min: %d, Avg: %d\n", min, avg); + + if (avg == 0 || min == 0) + { + CONS_Printf("No average/minimum, no scramblin'.\n"); + speedscramble = encorescramble = -1; + return; + } + if (min >= 7800) { if (avg >= 8200) @@ -161,6 +183,10 @@ void K_SetPowerLevelScrambles(SINT8 powertype) else t = 1; } +#if 1 + else + t = 1; +#else else if (min >= 1800) { if (avg >= 2200) @@ -170,35 +196,41 @@ void K_SetPowerLevelScrambles(SINT8 powertype) } else t = 0; +#endif + + CONS_Printf("Table position: %d\n", t); switch (t) { case 5: - speed = 2; + speed = KARTSPEED_HARD; encore = true; break; case 4: - speed = M_RandomChance((7<>1); + speed = P_RandomChance((7<>1); break; case 3: - speed = M_RandomChance((3<>2); + speed = P_RandomChance((3<>2); break; case 2: speed = 1; - encore = M_RandomChance(FRACUNIT>>3); + encore = P_RandomChance(FRACUNIT>>3); break; case 1: default: - speed = 1; + speed = KARTSPEED_NORMAL; encore = false; break; case 0: - speed = M_RandomChance((3<x+128, S_LINEY(i)+8, globalflags, va("(%s)", spd)); } diff --git a/src/p_saveg.c b/src/p_saveg.c index eb7d2900e..b81cc0f50 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3290,6 +3290,9 @@ static void P_NetArchiveMisc(void) WRITEUINT8(save_p, franticitems); WRITEUINT8(save_p, comeback); + WRITESINT8(save_p, speedscramble); + WRITESINT8(save_p, encorescramble); + for (i = 0; i < 4; i++) WRITESINT8(save_p, battlewanted[i]); @@ -3410,6 +3413,9 @@ static inline boolean P_NetUnArchiveMisc(void) franticitems = (boolean)READUINT8(save_p); comeback = (boolean)READUINT8(save_p); + speedscramble = READSINT8(save_p); + encorescramble = READSINT8(save_p); + for (i = 0; i < 4; i++) battlewanted[i] = READSINT8(save_p); diff --git a/src/p_setup.c b/src/p_setup.c index 5ec0f97e6..5acc72746 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2388,18 +2388,18 @@ static void P_LevelInitStuff(void) // SRB2Kart: map load variables if (modeattacking) // Just play it safe and set everything { - gamespeed = 2; + gamespeed = KARTSPEED_HARD; franticitems = false; comeback = true; } else { if (G_BattleGametype()) - gamespeed = 0; + gamespeed = KARTSPEED_EASY; else { - if (cv_kartspeed.value == -1) - gamespeed = ((speedscramble == -1) ? atoi(cv_kartspeed.defaultvalue) : (UINT8)speedscramble); + if (cv_kartspeed.value == KARTSPEED_AUTO) + gamespeed = ((speedscramble == -1) ? KARTSPEED_NORMAL : (UINT8)speedscramble); else gamespeed = (UINT8)cv_kartspeed.value; } diff --git a/src/y_inter.c b/src/y_inter.c index c51ac1e3f..f5380d565 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -605,7 +605,7 @@ dotimer: V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, hilicol, M_GetText("Teams will be scrambled next round!"));*/ if (speedscramble != -1 && speedscramble != gamespeed) V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24, hilicol|V_ALLOWLOWERCASE|V_SNAPTOBOTTOM, - va(M_GetText("Next race will be %s Speed!"), kartspeed_cons_t[speedscramble].strvalue)); + va(M_GetText("Next race will be %s Speed!"), kartspeed_cons_t[1+speedscramble].strvalue)); //} } @@ -1000,8 +1000,6 @@ void Y_StartIntermission(void) powertype = PWRLV_BATTLE; } - K_SetPowerLevelScrambles(powertype); - if (!multiplayer) { timer = 0; @@ -1078,7 +1076,7 @@ void Y_StartIntermission(void) break; } - if (powertype != -1) + if (powertype != PWRLV_DISABLED) K_UpdatePowerLevels(); //if (intertype == int_race || intertype == int_match) From 9777489bb83296a4fd6d0febc342b033013575e3 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 18 Oct 2019 19:09:10 -0400 Subject: [PATCH 86/91] debug prints --- src/k_pwrlv.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/k_pwrlv.c b/src/k_pwrlv.c index b1848f04b..94bdb13a4 100644 --- a/src/k_pwrlv.c +++ b/src/k_pwrlv.c @@ -84,7 +84,7 @@ INT16 K_CalculatePowerLevelAvg(void) if (!netgame || !cv_kartusepwrlv.value) { - CONS_Printf("Not in a netgame, or not using power levels -- no average.\n"); + CONS_Debug(DBG_GAMELOGIC, "Not in a netgame, or not using power levels -- no average.\n"); return 0; // No average. } @@ -95,7 +95,7 @@ INT16 K_CalculatePowerLevelAvg(void) if (t == PWRLV_DISABLED) { - CONS_Printf("Could not set a power level type -- no average.\n"); + CONS_Debug(DBG_GAMELOGIC, "Could not set a power level type -- no average.\n"); return 0; // Hmm?! } @@ -111,7 +111,7 @@ INT16 K_CalculatePowerLevelAvg(void) if (!div) { - CONS_Printf("Found no players -- no average.\n"); + CONS_Debug(DBG_GAMELOGIC, "Found no players -- no average.\n"); return 0; // No average. } @@ -146,11 +146,11 @@ void K_SetPowerLevelScrambles(SINT8 powertype) min = clientpowerlevels[i][0]; } - CONS_Printf("Min: %d, Avg: %d\n", min, avg); + CONS_Debug(DBG_GAMELOGIC, "Min: %d, Avg: %d\n", min, avg); if (avg == 0 || min == 0) { - CONS_Printf("No average/minimum, no scramblin'.\n"); + CONS_Debug(DBG_GAMELOGIC, "No average/minimum, no scramblin'.\n"); speedscramble = encorescramble = -1; return; } @@ -198,7 +198,7 @@ void K_SetPowerLevelScrambles(SINT8 powertype) t = 0; #endif - CONS_Printf("Table position: %d\n", t); + CONS_Debug(DBG_GAMELOGIC, "Table position: %d\n", t); switch (t) { @@ -228,8 +228,8 @@ void K_SetPowerLevelScrambles(SINT8 powertype) break; } - CONS_Printf("Rolled speed: %d\n", speed); - CONS_Printf("Rolled encore: %s\n", (encore ? "true" : "false")); + CONS_Debug(DBG_GAMELOGIC, "Rolled speed: %d\n", speed); + CONS_Debug(DBG_GAMELOGIC, "Rolled encore: %s\n", (encore ? "true" : "false")); if (cv_kartspeed.value == -1) speedscramble = speed; From fc862c999d2cd2511c1eb8da8e35c0bf8de37404 Mon Sep 17 00:00:00 2001 From: James Date: Sat, 19 Oct 2019 01:48:56 -0400 Subject: [PATCH 87/91] Bad parathesis --- src/d_clisrv.c | 1 + src/m_menu.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index d67f6b48e..1dacabd9f 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1241,6 +1241,7 @@ static inline void CL_DrawConnectionStatus(void) case CL_ASKDOWNLOADFILES: case CL_WAITDOWNLOADFILESRESPONSE: cltext = M_GetText("Waiting to download files..."); + break; default: cltext = M_GetText("Connecting to server..."); break; diff --git a/src/m_menu.c b/src/m_menu.c index e948b85f1..d5084dff2 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5412,7 +5412,7 @@ static void DrawReplayHutReplayInfo(void) V_DrawThinString(x, y+9, V_SNAPTOTOP|V_ALLOWLOWERCASE, va("(%d laps)", demolist[dir_on[menudepthleft]].numlaps)); V_DrawString(x, y+20, V_SNAPTOTOP|V_ALLOWLOWERCASE, demolist[dir_on[menudepthleft]].gametype == GT_RACE ? - va("Race (%s speed)", kartspeed_cons_t[demolist[(dir_on[menudepthleft]].kartspeed & ~DF_ENCORE) + 1].strvalue) : + va("Race (%s speed)", kartspeed_cons_t[(demolist[dir_on[menudepthleft]].kartspeed & ~DF_ENCORE) + 1].strvalue) : "Battle Mode"); if (!demolist[dir_on[menudepthleft]].standings[0].ranking) From addb0d0a663380d3f484b94d169ab4ef2c25d3ce Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 25 Oct 2019 23:35:31 -0400 Subject: [PATCH 88/91] Fix time limit --- src/d_netcmd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index db0c00086..70dff2fcf 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -424,13 +424,13 @@ consvar_t cv_timetic = {"timerres", "Normal", CV_SAVE|CV_NOSHOWHELP, timetic_con static CV_PossibleValue_t pointlimit_cons_t[] = {{0, "MIN"}, {999999990, "MAX"}, {0, NULL}}; consvar_t cv_pointlimit = {"pointlimit", "0", CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t, PointLimit_OnChange, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t timelimit_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}}; +static CV_PossibleValue_t timelimit_cons_t[] = {{0, "MIN"}, {1800, "MAX"}, {0, NULL}}; 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[] = {{1, "MIN"}, {50, "MAX"}, {0, NULL}}; +static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, NULL}}; consvar_t cv_numlaps = {"numlaps", "3", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t, NumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, "Map default"}, {0, NULL}}; +static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, "Map default"}, {0, NULL}}; consvar_t cv_basenumlaps = {"basenumlaps", "Map default", CV_NETVAR|CV_CALL|CV_CHEAT, basenumlaps_cons_t, BaseNumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_forceskin = {"forceskin", "Off", CV_NETVAR|CV_CALL|CV_CHEAT, Forceskin_cons_t, ForceSkin_OnChange, 0, NULL, NULL, 0, 0, NULL}; From d52e7a652e61ff3b2412b876886061439ccc9e71 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 27 Oct 2019 09:03:35 -0400 Subject: [PATCH 89/91] Faster waterskipping --- src/p_map.c | 10 +++++++--- src/p_mobj.c | 25 ++++++++++--------------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index d4f2a94fa..e9bc95712 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2787,18 +2787,22 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) if (!(thing->flags & MF_NOCLIP)) { //All things are affected by their scale. - fixed_t maxstep = FixedMul(MAXSTEPMOVE, mapobjectscale); + const fixed_t maxstepmove = FixedMul(MAXSTEPMOVE, mapobjectscale); + fixed_t maxstep = maxstepmove; if (thing->player) { + if (thing->player->kartstuff[k_waterskip]) + maxstep += maxstepmove; // Force some stepmove when waterskipping + // If using type Section1:13, double the maxstep. if (P_PlayerTouchingSectorSpecial(thing->player, 1, 13) || GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 13) - maxstep <<= 1; + maxstep += maxstepmove; // If using type Section1:12, no maxstep. For ledges you don't want the player to climb! (see: Egg Zeppelin & SMK port walls) else if (P_PlayerTouchingSectorSpecial(thing->player, 1, 12) || GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 12) - maxstep = 0; + maxstep -= maxstepmove; // Don't 'step up' while springing, // Only step up "if needed". diff --git a/src/p_mobj.c b/src/p_mobj.c index f54eca41e..b220ff4e6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1268,6 +1268,8 @@ fixed_t P_GetMobjGravity(mobj_t *mo) P_PlayerFlip(mo); if (mo->player->kartstuff[k_pogospring]) gravityadd = (5*gravityadd)/2; + if (mo->player->kartstuff[k_waterskip]) + gravityadd = (4*gravityadd)/3; } else { @@ -3301,26 +3303,19 @@ void P_MobjCheckWater(mobj_t *mobj) // skipping stone! if (p && p->kartstuff[k_waterskip] < 2 && ((p->speed/3 > abs(mobj->momz)) // Going more forward than horizontal, so you can skip across the water. - || (p->speed > K_GetKartSpeed(p,false)/3 && p->kartstuff[k_waterskip])) // Already skipped once, so you can skip once more! + || (p->speed > 20*mapobjectscale && p->kartstuff[k_waterskip])) // Already skipped once, so you can skip once more! && ((!(mobj->eflags & MFE_VERTICALFLIP) && thingtop - mobj->momz > mobj->watertop) || ((mobj->eflags & MFE_VERTICALFLIP) && mobj->z - mobj->momz < mobj->waterbottom))) { - const fixed_t min = 6<momx = mobj->momx/2; - mobj->momy = mobj->momy/2; - mobj->momz = -mobj->momz/2; + mobj->momx = (4*mobj->momx)/5; + mobj->momy = (4*mobj->momy)/5; - if (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->momz < FixedMul(min, mobj->scale)) - mobj->momz = FixedMul(min, mobj->scale); - else if (mobj->eflags & MFE_VERTICALFLIP && mobj->momz > FixedMul(-min, mobj->scale)) - mobj->momz = FixedMul(-min, mobj->scale); - - /*if (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->momz > FixedMul(max, mobj->scale)) - mobj->momz = FixedMul(max, mobj->scale); - else if (mobj->eflags & MFE_VERTICALFLIP && mobj->momz < FixedMul(-max, mobj->scale)) - mobj->momz = FixedMul(-max, mobj->scale);*/ + if (mobj->eflags & MFE_VERTICALFLIP) + mobj->momz = FixedMul(-hop, mobj->scale); + else + mobj->momz = FixedMul(hop, mobj->scale); p->kartstuff[k_waterskip]++; } From 7c0ca5bf7cdc62f7ff4892499e3638a8ae1664b0 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 27 Oct 2019 10:33:40 -0700 Subject: [PATCH 90/91] Move gamedata param to cover -resetdata --- src/g_game.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 15a22f493..ae47e633f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4079,14 +4079,14 @@ void G_LoadGameData(void) // Allow saving of gamedata beyond this point gamedataloaded = true; - if (M_CheckParm("-resetdata")) - return; // Don't load (essentially, reset). - if (M_CheckParm("-gamedata") && M_IsNextParm()) { strlcpy(gamedatafilename, M_GetNextParm(), sizeof gamedatafilename); } + if (M_CheckParm("-resetdata")) + return; // Don't load (essentially, reset). + length = FIL_ReadFile(va(pandf, srb2home, gamedatafilename), &savebuffer); if (!length) // Aw, no game data. Their loss! return; From b948f74b4f573dfc792961bb39151ca35f01e020 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 28 Oct 2019 00:04:30 -0700 Subject: [PATCH 91/91] Add overflow checks so we I_Error instead of death crash into oblivion You'd love to know how we even reached (size_t)-1. --- src/z_zone.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/z_zone.c b/src/z_zone.c index a3e13422f..2c0ddc295 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -210,7 +210,11 @@ void Z_Free(void *ptr) static void *xm(size_t size) { const size_t padedsize = size+sizeof (size_t); - void *p = malloc(padedsize); + void *p; + + if (padedsize < size)/* overflow check */ + I_Error("You are allocating memory too large!"); + p = malloc(padedsize); if (p == NULL) { @@ -254,6 +258,9 @@ void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) CONS_Debug(DBG_MEMORY, "Z_Malloc %s:%d\n", file, line); #endif + if (blocksize < size)/* overflow check */ + I_Error("You are allocating memory too large!"); + block = xm(sizeof *block); #ifdef HAVE_VALGRIND padsize += (1<