From 622e94797bb587a8a6feb99c8d3af3e0c2af99f4 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 25 Nov 2018 22:55:49 -0500 Subject: [PATCH 01/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] - 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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/81] 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 2635d1b8106506424cff6c1477838a01fbbcc7b8 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 27 Sep 2019 06:46:10 -0400 Subject: [PATCH 53/81] 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 54/81] 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 55/81] 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 56/81] 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 57/81] 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 58/81] 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 59/81] 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 60/81] 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 61/81] 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 62/81] 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 63/81] 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 64/81] 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 65/81] 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 66/81] 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 67/81] 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 68/81] 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 69/81] 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 70/81] 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 71/81] 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 72/81] 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 73/81] 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 74/81] 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 75/81] 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 76/81] 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 77/81] 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 78/81] 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 79/81] 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 80/81] 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 027dec67025481e19ec00cb43d8336ed25982672 Mon Sep 17 00:00:00 2001 From: wolfy852 Date: Sat, 5 Oct 2019 19:07:26 -0500 Subject: [PATCH 81/81] 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;