From 622e94797bb587a8a6feb99c8d3af3e0c2af99f4 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 25 Nov 2018 22:55:49 -0500 Subject: [PATCH 001/163] 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 002/163] 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 003/163] 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 004/163] 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 005/163] 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 006/163] 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 007/163] 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 008/163] 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 009/163] 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 010/163] 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 011/163] 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 012/163] 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 013/163] 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 014/163] 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 015/163] 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 016/163] 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 017/163] 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 018/163] 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 019/163] 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 020/163] - 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 021/163] 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 022/163] 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 023/163] 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 024/163] 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 025/163] 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 026/163] 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 027/163] 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 028/163] 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 029/163] 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 030/163] 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 031/163] 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 0c6d27a319dd2eb6bbc9dc3eb53a818c5daf77e0 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 26 Apr 2019 14:14:25 -0400 Subject: [PATCH 032/163] Flush random map pool after all but 3 are played --- 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 ad25c8ce9..36b696fb4 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3428,7 +3428,7 @@ tryagain: void G_AddMapToBuffer(INT16 map) { - INT16 bufx, refreshnum = (TOLMaps(G_TOLFlag(gametype)) / 2) + 1; + INT16 bufx, refreshnum = max(0, TOLMaps(G_TOLFlag(gametype))-3); // Add the map to the buffer. for (bufx = NUMMAPS-1; bufx > 0; bufx--) From 927c5e008048855dc408217887749b2f41236ace Mon Sep 17 00:00:00 2001 From: Sryder Date: Tue, 7 May 2019 23:35:19 +0100 Subject: [PATCH 033/163] Use spin slope physics on all players Disable increased slope strength with more speed --- src/p_slopes.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index c6416b75a..6928e93e9 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -869,26 +869,22 @@ void P_ButteredSlope(mobj_t *mo) return; // Allow the player to stand still on slopes below a certain steepness } - thrust = FINESINE(mo->standingslope->zangle>>ANGLETOFINESHIFT) * 15 / 16 * (mo->eflags & MFE_VERTICALFLIP ? 1 : -1); + thrust = FINESINE(mo->standingslope->zangle>>ANGLETOFINESHIFT) * 4 / 5 * (mo->eflags & MFE_VERTICALFLIP ? 1 : -1); - if (mo->player && (mo->player->pflags & PF_SPINNING)) { - fixed_t mult = 0; + if (mo->player) { + fixed_t mult = FRACUNIT; if (mo->momx || mo->momy) { angle_t angle = R_PointToAngle2(0, 0, mo->momx, mo->momy) - mo->standingslope->xydirection; if (P_MobjFlip(mo) * mo->standingslope->zdelta < 0) angle ^= ANGLE_180; - mult = FINECOSINE(angle >> ANGLETOFINESHIFT); + mult = FRACUNIT + (FRACUNIT + FINECOSINE(angle>>ANGLETOFINESHIFT))*3/2; } - thrust = FixedMul(thrust, FRACUNIT*2/3 + mult/8); + thrust = FixedMul(thrust, mult); } - if (mo->momx || mo->momy) // Slightly increase thrust based on the object's speed - thrust = FixedMul(thrust, FRACUNIT+P_AproxDistance(mo->momx, mo->momy)/16); - // This makes it harder to zigzag up steep slopes, as well as allows greater top speed when rolling down - // Let's get the gravity strength for the object... thrust = FixedMul(thrust, abs(P_GetMobjGravity(mo))); From 682a8f68295b1b643c6e25f79108ff37b2e0c842 Mon Sep 17 00:00:00 2001 From: Sryder Date: Wed, 8 May 2019 20:49:47 +0100 Subject: [PATCH 034/163] Disable the speedcap on players. Don't calculate acceleration as ever being above top speed. --- src/k_kart.c | 11 +++++++---- src/p_user.c | 4 +++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index d9bc1f26d..18ef5ac90 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1636,7 +1636,7 @@ static void K_DrawDraftCombiring(player_t *player, player_t *victim, fixed_t cur curx += stepx; cury += stepy; curz += stepz; - + offset = abs(offset-1) % 3; n--; } @@ -2241,7 +2241,7 @@ static void K_GetKartBoostPower(player_t *player) { speedboost += (player->kartstuff[k_draftpower]) / 3; // + 0 to 33.3% top speed //accelboost += (FRACUNIT / 3); // + 33.3% acceleration - numboosts++; // (Drafting suffers no boost stack penalty!) + numboosts++; // (Drafting suffers no boost stack penalty!) } player->kartstuff[k_boostpower] = boostpower; @@ -2319,6 +2319,9 @@ fixed_t K_3dKartMovement(player_t *player, boolean onground, fixed_t forwardmove // ACCELCODE!!!1!11! oldspeed = R_PointToDist2(0, 0, player->rmomx, player->rmomy); // FixedMul(P_AproxDistance(player->rmomx, player->rmomy), player->mo->scale); + // Don't calculate the acceleration as ever being above top speed + if (oldspeed > p_speed) + oldspeed = p_speed; newspeed = FixedDiv(FixedDiv(FixedMul(oldspeed, accelmax - p_accel) + FixedMul(p_speed, p_accel), accelmax), ORIG_FRICTION); if (player->kartstuff[k_pogospring]) // Pogo Spring minimum/maximum thrust @@ -3413,7 +3416,7 @@ void K_SpawnDraftDust(mobj_t *mo) ang = mo->player->frameangle; - if (mo->player->kartstuff[k_drift] != 0) + if (mo->player->kartstuff[k_drift] != 0) { drifting = true; ang += (mo->player->kartstuff[k_drift] * ((ANGLE_270 + ANGLE_22h) / 5)); // -112.5 doesn't work. I fucking HATE SRB2 angles @@ -8382,7 +8385,7 @@ static void K_drawKartRingsAndLives(void) } else if (stplyr->kartstuff[k_rings] >= 20) // Maxed out ringmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_YELLOW, GTC_CACHE); - + if (netgame) V_DrawScaledPatch(LAPS_X, LAPS_Y-11, V_HUDTRANS|splitflags, kp_ringsticker[1]); diff --git a/src/p_user.c b/src/p_user.c index d4e6a03de..a331d56b7 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4184,6 +4184,7 @@ static void P_3dMovement(player_t *player) // If "no" to 2, normalize to topspeed, so we can't suddenly run faster than it of our own accord. // If "no" to 1, we're not reaching any limits yet, so ignore this entirely! // -Shadow Hog + /* newMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0); if (newMagnitude > K_GetKartSpeed(player, true)) //topspeed) { @@ -4207,6 +4208,7 @@ static void P_3dMovement(player_t *player) player->mo->momy = tempmomy + player->cmomy; } } + */ } // @@ -7352,7 +7354,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (P_CameraThinker(player, thiscam, resetcalled)) return true; - + if (thiscam == &camera[1]) // Camera 2 { num = 1; From 00ec2b5f16856e05dab479078ec2d71143ccde08 Mon Sep 17 00:00:00 2001 From: Sryder Date: Fri, 10 May 2019 20:21:21 +0100 Subject: [PATCH 035/163] Re-enable the speed cap Only in midair to prevent pogo jump acceleration to infinity. --- src/p_user.c | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/src/p_user.c b/src/p_user.c index a331d56b7..d25095f0c 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -4184,31 +4184,35 @@ static void P_3dMovement(player_t *player) // If "no" to 2, normalize to topspeed, so we can't suddenly run faster than it of our own accord. // If "no" to 1, we're not reaching any limits yet, so ignore this entirely! // -Shadow Hog - /* - newMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0); - if (newMagnitude > K_GetKartSpeed(player, true)) //topspeed) + // Only do this forced cap of speed when in midair, the kart acceleration code takes into account friction, and + // doesn't let you accelerate past top speed, so this is unnecessary on the ground, but in the air is needed to + // allow for being able to change direction on spring jumps without being accelerated into the void - Sryder + if (!P_IsObjectOnGround(player->mo)) { - fixed_t tempmomx, tempmomy; - if (oldMagnitude > K_GetKartSpeed(player, true)) + newMagnitude = R_PointToDist2(player->mo->momx - player->cmomx, player->mo->momy - player->cmomy, 0, 0); + if (newMagnitude > K_GetKartSpeed(player, true)) //topspeed) { - if (newMagnitude > oldMagnitude) + fixed_t tempmomx, tempmomy; + if (oldMagnitude > K_GetKartSpeed(player, true)) { - tempmomx = FixedMul(FixedDiv(player->mo->momx - player->cmomx, newMagnitude), oldMagnitude); - tempmomy = FixedMul(FixedDiv(player->mo->momy - player->cmomy, newMagnitude), oldMagnitude); + if (newMagnitude > oldMagnitude) + { + tempmomx = FixedMul(FixedDiv(player->mo->momx - player->cmomx, newMagnitude), oldMagnitude); + tempmomy = FixedMul(FixedDiv(player->mo->momy - player->cmomy, newMagnitude), oldMagnitude); + player->mo->momx = tempmomx + player->cmomx; + player->mo->momy = tempmomy + player->cmomy; + } + // else do nothing + } + else + { + tempmomx = FixedMul(FixedDiv(player->mo->momx - player->cmomx, newMagnitude), K_GetKartSpeed(player, true)); //topspeed) + tempmomy = FixedMul(FixedDiv(player->mo->momy - player->cmomy, newMagnitude), K_GetKartSpeed(player, true)); //topspeed) player->mo->momx = tempmomx + player->cmomx; player->mo->momy = tempmomy + player->cmomy; } - // else do nothing - } - else - { - tempmomx = FixedMul(FixedDiv(player->mo->momx - player->cmomx, newMagnitude), K_GetKartSpeed(player, true)); //topspeed) - tempmomy = FixedMul(FixedDiv(player->mo->momy - player->cmomy, newMagnitude), K_GetKartSpeed(player, true)); //topspeed) - player->mo->momx = tempmomx + player->cmomx; - player->mo->momy = tempmomy + player->cmomy; } } - */ } // From c0d2689ae4d5ee0c971bac2e6ff945c745c728d7 Mon Sep 17 00:00:00 2001 From: Sryder Date: Fri, 10 May 2019 21:25:45 +0100 Subject: [PATCH 036/163] Allow slope physics to apply on all but slight gradients. --- src/p_slopes.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/p_slopes.c b/src/p_slopes.c index 6928e93e9..b672be56e 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -862,9 +862,11 @@ void P_ButteredSlope(mobj_t *mo) return; // don't slide down slopes if you can't touch them or you're not affected by gravity if (mo->player) { - if (abs(mo->standingslope->zdelta) < FRACUNIT/4 && !(mo->player->pflags & PF_SPINNING)) + // Changed in kart to only not apply physics on very slight slopes (I think about 4 degree angles) + if (abs(mo->standingslope->zdelta) < FRACUNIT/21 && !(mo->player->pflags & PF_SPINNING)) return; // Don't slide on non-steep slopes unless spinning + // This only means you can be stopped on slopes that aren't steeper than 45 degrees if (abs(mo->standingslope->zdelta) < FRACUNIT/2 && !(mo->player->rmomx || mo->player->rmomy)) return; // Allow the player to stand still on slopes below a certain steepness } From dca1a05a7f70b536fb4b7f9e759b82f419f54fe7 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 26 May 2019 03:41:18 -0400 Subject: [PATCH 037/163] Gradient skincolors for MD2 blend textures --- src/hardware/hw_md2.c | 167 +++++++++++++++++++++++------------------- src/k_kart.c | 2 +- 2 files changed, 93 insertions(+), 76 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index d217f4094..cc69fad02 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -653,13 +653,12 @@ spritemd2found: // 0.2126 to red // 0.7152 to green // 0.0722 to blue -// (See this same define in k_kart.c!) +// (See this same define in hw_md2.c!) #define SETBRIGHTNESS(brightness,r,g,b) \ - brightness = (UINT8)(((1063*((UINT16)r)/5000) + (3576*((UINT16)g)/5000) + (361*((UINT16)b)/5000)) / 3) + brightness = (UINT8)(((1063*(UINT16)(r))/5000) + ((3576*(UINT16)(g))/5000) + ((361*(UINT16)(b))/5000)) static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, GLMipmap_t *grmip, INT32 skinnum, skincolors_t color) { - UINT8 i; UINT16 w = gpatch->width, h = gpatch->height; UINT32 size = w*h; RGBA_t *image, *blendimage, *cur, blendcolor; @@ -684,102 +683,120 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, image = gpatch->mipmap.grInfo.data; blendimage = blendgpatch->mipmap.grInfo.data; + blendcolor = V_GetColor(0); // initialize - // Average all of the translation's colors + while (size--) { - const UINT8 div = 6; - const UINT8 start = 4; - UINT32 r, g, b; + UINT16 brightness; - blendcolor = V_GetColor(colortranslations[color][start]); - r = (UINT32)(blendcolor.s.red*blendcolor.s.red); - g = (UINT32)(blendcolor.s.green*blendcolor.s.green); - b = (UINT32)(blendcolor.s.blue*blendcolor.s.blue); - - for (i = 1; i < div; i++) - { - RGBA_t nextcolor = V_GetColor(colortranslations[color][start+i]); - r += (UINT32)(nextcolor.s.red*nextcolor.s.red); - g += (UINT32)(nextcolor.s.green*nextcolor.s.green); - b += (UINT32)(nextcolor.s.blue*nextcolor.s.blue); - } - - blendcolor.s.red = (UINT8)(FixedSqrt((r/div)<>FRACBITS); - blendcolor.s.green = (UINT8)(FixedSqrt((g/div)<>FRACBITS); - blendcolor.s.blue = (UINT8)(FixedSqrt((b/div)<>FRACBITS); - } - - // rainbow support, could theoretically support boss ones too - if (skinnum == TC_RAINBOW) - { - while (size--) + // Don't bother with blending the pixel if the alpha of the blend pixel is 0 + if (skinnum == TC_RAINBOW) { if (image->s.alpha == 0 && blendimage->s.alpha == 0) { - // Don't bother with blending the pixel if the alpha of the blend pixel is 0 cur->rgba = image->rgba; + cur++; image++; blendimage++; + continue; } else { - UINT32 tempcolor; - UINT16 imagebright, blendbright, finalbright, colorbright; + UINT16 imagebright, blendbright; SETBRIGHTNESS(imagebright,image->s.red,image->s.green,image->s.blue); SETBRIGHTNESS(blendbright,blendimage->s.red,blendimage->s.green,blendimage->s.blue); // slightly dumb average between the blend image color and base image colour, usually one or the other will be fully opaque anyway - finalbright = (imagebright*(255-blendimage->s.alpha))/255 + (blendbright*blendimage->s.alpha)/255; - SETBRIGHTNESS(colorbright,blendcolor.s.red,blendcolor.s.green,blendcolor.s.blue); - - tempcolor = (finalbright*blendcolor.s.red)/colorbright; - tempcolor = min(255, tempcolor); - cur->s.red = (UINT8)tempcolor; - tempcolor = (finalbright*blendcolor.s.green)/colorbright; - tempcolor = min(255, tempcolor); - cur->s.green = (UINT8)tempcolor; - tempcolor = (finalbright*blendcolor.s.blue)/colorbright; - tempcolor = min(255, tempcolor); - cur->s.blue = (UINT8)tempcolor; - cur->s.alpha = image->s.alpha; + brightness = (imagebright*(255-blendimage->s.alpha))/255 + (blendbright*blendimage->s.alpha)/255; } - - cur++; image++; blendimage++; } - } - else - { - while (size--) + else { if (blendimage->s.alpha == 0) { - // Don't bother with blending the pixel if the alpha of the blend pixel is 0 cur->rgba = image->rgba; + cur++; image++; blendimage++; + continue; } else { - INT32 tempcolor; - INT16 tempmult, tempalpha; - tempalpha = -(abs(blendimage->s.red-127)-127)*2; - if (tempalpha > 255) - tempalpha = 255; - else if (tempalpha < 0) - tempalpha = 0; - - tempmult = (blendimage->s.red-127)*2; - if (tempmult > 255) - tempmult = 255; - else if (tempmult < 0) - tempmult = 0; - - tempcolor = (image->s.red*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.red)/255)) * blendimage->s.alpha)/255; - cur->s.red = (UINT8)tempcolor; - tempcolor = (image->s.green*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.green)/255)) * blendimage->s.alpha)/255; - cur->s.green = (UINT8)tempcolor; - tempcolor = (image->s.blue*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.blue)/255)) * blendimage->s.alpha)/255; - cur->s.blue = (UINT8)tempcolor; - cur->s.alpha = image->s.alpha; + SETBRIGHTNESS(brightness,blendimage->s.red,blendimage->s.green,blendimage->s.blue); } - - cur++; image++; blendimage++; } + + // Calculate a sort of "gradient" for the skincolor + // (Me splitting this into a function didn't work, so I had to ruin this entire function's groove...) + { + RGBA_t nextcolor; + UINT8 firsti, secondi, mul; + UINT32 r, g, b; + + firsti = ((UINT8)(255-brightness) / 16); + mul = ((UINT8)(255-brightness) % 16); + + blendcolor = V_GetColor(colortranslations[color][firsti]); + + if (mul > 0) // If it's 0, then we only need the first color. + { + secondi = firsti+1; + + if (secondi == 16) // blend to black + nextcolor = V_GetColor(31); + else + nextcolor = V_GetColor(colortranslations[color][secondi]); + + // Find difference between points + r = (UINT32)(nextcolor.s.red - blendcolor.s.red); + g = (UINT32)(nextcolor.s.green - blendcolor.s.green); + b = (UINT32)(nextcolor.s.blue - blendcolor.s.blue); + + // Find the gradient of the two points + r = ((mul * r) / 16); + g = ((mul * g) / 16); + b = ((mul * b) / 16); + + // Add gradient value to color + blendcolor.s.red += r; + blendcolor.s.green += g; + blendcolor.s.blue += b; + } + } + + if (skinnum == TC_RAINBOW) + { + // Directly set blendcolor + cur->s.red = blendcolor.s.red; + cur->s.green = blendcolor.s.green; + cur->s.blue = blendcolor.s.blue; + cur->s.alpha = image->s.alpha; + } + else + { + // Color strength depends on image alpha + INT32 tempcolor; + INT16 tempmult, tempalpha; + + tempalpha = -(abs(blendimage->s.red-127)-127)*2; + if (tempalpha > 255) + tempalpha = 255; + else if (tempalpha < 0) + tempalpha = 0; + + tempmult = (blendimage->s.red-127)*2; + if (tempmult > 255) + tempmult = 255; + else if (tempmult < 0) + tempmult = 0; + + tempcolor = (image->s.red*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.red)/255)) * blendimage->s.alpha)/255; + cur->s.red = (UINT8)tempcolor; + + tempcolor = (image->s.green*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.green)/255)) * blendimage->s.alpha)/255; + cur->s.green = (UINT8)tempcolor; + + tempcolor = (image->s.blue*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.blue)/255)) * blendimage->s.alpha)/255; + cur->s.blue = (UINT8)tempcolor; + cur->s.alpha = image->s.alpha; + } + + cur++; image++; blendimage++; } return; diff --git a/src/k_kart.c b/src/k_kart.c index 659c499db..5ec49b444 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -410,7 +410,7 @@ UINT8 colortranslations[MAXTRANSLATIONS][16] = { // 0.0722 to blue // (See this same define in hw_md2.c!) #define SETBRIGHTNESS(brightness,r,g,b) \ - brightness = (UINT8)(((1063*((UINT16)r)/5000) + (3576*((UINT16)g)/5000) + (361*((UINT16)b)/5000)) / 3) + brightness = (UINT8)(((1063*(UINT16)(r))/5000) + ((3576*(UINT16)(g))/5000) + ((361*(UINT16)(b))/5000)) /** \brief Generates the rainbow colourmaps that are used when a player has the invincibility power From 179bb2bd8b1fe801c1817734f3451657162f96d8 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 26 May 2019 06:22:14 -0400 Subject: [PATCH 038/163] Update colorize blending Didn't notice for a moment that it was back to 2.0-style rainbow blending -- this is horrible but it keeps the brightness of the textures in-tact --- src/hardware/hw_md2.c | 89 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 81 insertions(+), 8 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index cc69fad02..36d2a606f 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -728,15 +728,78 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, UINT8 firsti, secondi, mul; UINT32 r, g, b; - firsti = ((UINT8)(255-brightness) / 16); - mul = ((UINT8)(255-brightness) % 16); + // Rainbow needs to find the closest match to the textures themselves, instead of matching brightnesses to other colors. + // Ensue horrible mess. + if (skinnum == TC_RAINBOW) + { + UINT16 brightdif = 256; + UINT8 colorbrightnesses[16]; + INT32 compare, m, d; + UINT8 i; + + // Ignore pure white & pitch black + if (brightness > 246 || brightness < 7) + { + cur->rgba = image->rgba; + cur++; image++; blendimage++; + continue; + } + + firsti = 0; + mul = 0; + + for (i = 0; i < 16; i++) + { + RGBA_t tempc = V_GetColor(colortranslations[color][i]); + SETBRIGHTNESS(colorbrightnesses[i], tempc.s.red, tempc.s.green, tempc.s.blue); // store brightnesses for comparison + } + + for (i = 0; i < 16; i++) + { + if (brightness > colorbrightnesses[i]) // don't allow greater matches (because calculating a makeshift gradient for this is already a huge mess as is) + continue; + compare = abs((INT16)(colorbrightnesses[i]) - (INT16)(brightness)); + if (compare < brightdif) + { + brightdif = (UINT16)compare; + firsti = i; // best matching color that's equal brightness or darker + } + } + + secondi = firsti+1; // next color in line + if (secondi == 16) + { + m = (INT16)brightness; // - 0; + d = (INT16)colorbrightnesses[firsti]; // - 0; + } + else + { + m = (INT16)brightness - (INT16)colorbrightnesses[secondi]; + d = (INT16)colorbrightnesses[firsti] - (INT16)colorbrightnesses[secondi]; + } + + if (m >= d) + m = d-1; + + // calculate the "gradient" multiplier based on how close this color is to the one next in line + if (m <= 0 || d <= 0) + mul = 0; + else + mul = 15 - ((m * 16) / d); + } + else + { + // Thankfully, it's normally way more simple. + // Just convert brightness to a skincolor value, use remainder to find the gradient multipler + firsti = ((UINT8)(255-brightness) / 16); + secondi = firsti+1; + mul = ((UINT8)(255-brightness) % 16); + } blendcolor = V_GetColor(colortranslations[color][firsti]); if (mul > 0) // If it's 0, then we only need the first color. { - secondi = firsti+1; - if (secondi == 16) // blend to black nextcolor = V_GetColor(31); else @@ -761,10 +824,20 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, if (skinnum == TC_RAINBOW) { - // Directly set blendcolor - cur->s.red = blendcolor.s.red; - cur->s.green = blendcolor.s.green; - cur->s.blue = blendcolor.s.blue; + UINT32 tempcolor; + UINT16 colorbright = 127; // an arbitrary value now, since blendcolor is always changing + + tempcolor = (brightness * blendcolor.s.red) / colorbright; + tempcolor = min(255, tempcolor); + cur->s.red = (UINT8)tempcolor; + + tempcolor = (brightness * blendcolor.s.green) / colorbright; + tempcolor = min(255, tempcolor); + cur->s.green = (UINT8)tempcolor; + + tempcolor = (brightness * blendcolor.s.blue) / colorbright; + tempcolor = min(255, tempcolor); + cur->s.blue = (UINT8)tempcolor; cur->s.alpha = image->s.alpha; } else From ee60e6d76c326a22e57418708dacf0e49203a963 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 26 May 2019 07:44:40 -0400 Subject: [PATCH 039/163] Minor touchup to colorization code --- src/hardware/hw_md2.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 36d2a606f..02594eb70 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -738,7 +738,7 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, UINT8 i; // Ignore pure white & pitch black - if (brightness > 246 || brightness < 7) + if (brightness > 253 || brightness < 2) { cur->rgba = image->rgba; cur++; image++; blendimage++; @@ -825,7 +825,11 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, if (skinnum == TC_RAINBOW) { UINT32 tempcolor; - UINT16 colorbright = 127; // an arbitrary value now, since blendcolor is always changing + UINT16 colorbright; + + SETBRIGHTNESS(colorbright,blendcolor.s.red,blendcolor.s.green,blendcolor.s.blue); + if (colorbright == 0) + colorbright = 1; // no dividing by 0 please tempcolor = (brightness * blendcolor.s.red) / colorbright; tempcolor = min(255, tempcolor); From e1d73d0e3502bf7bb44f428b82b1c8bb689375ae Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 26 May 2019 15:20:16 -0400 Subject: [PATCH 040/163] Tiny optimization --- src/hardware/hw_md2.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 02594eb70..561daf058 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -798,7 +798,8 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, blendcolor = V_GetColor(colortranslations[color][firsti]); - if (mul > 0) // If it's 0, then we only need the first color. + if (mul > 0 // If it's 0, then we only need the first color. + && colortranslations[color][firsti] != colortranslations[color][secondi]) // Some colors have duplicate colors in a row, so let's just save the process { if (secondi == 16) // blend to black nextcolor = V_GetColor(31); From c6a0a41d1a614a9ece8ae38d7699abe186a4cfa8 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Tue, 28 May 2019 17:21:22 -0400 Subject: [PATCH 041/163] Model tilts - Add modeltilt variable, for more manual control of the model tilting. By default this just copies standingslope, but doesn't get cleared in the air. - Shadows & trailing bananas now tilt to match the ground they are on. - Rocket Sneakers & afterimages now tilt to match the player's current orientation. --- src/hardware/hw_md2.c | 8 +-- src/k_kart.c | 83 +++++++++++++++++++++++++++ src/p_map.c | 12 +++- src/p_mobj.c | 129 +++++++++++++++++++++++++++++++++++++----- src/p_mobj.h | 3 + src/p_saveg.c | 5 ++ src/p_slopes.c | 6 ++ src/p_user.c | 6 +- 8 files changed, 233 insertions(+), 19 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index 561daf058..b610d410c 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -1186,11 +1186,11 @@ void HWR_DrawMD2(gr_vissprite_t *spr) #ifdef USE_FTRANSFORM_ANGLEZ // Slope rotation from Kart p.anglez = 0.0f; - if (spr->mobj->standingslope) + if (spr->mobj->modeltilt) { - fixed_t tempz = spr->mobj->standingslope->normal.z; - fixed_t tempy = spr->mobj->standingslope->normal.y; - fixed_t tempx = spr->mobj->standingslope->normal.x; + fixed_t tempz = spr->mobj->modeltilt->normal.z; + fixed_t tempy = spr->mobj->modeltilt->normal.y; + fixed_t tempx = spr->mobj->modeltilt->normal.x; fixed_t tempangle = AngleFixed(R_PointToAngle2(0, 0, FixedSqrt(FixedMul(tempy, tempy) + FixedMul(tempz, tempz)), tempx)); p.anglez = FIXED_TO_FLOAT(tempangle); tempangle = -AngleFixed(R_PointToAngle2(0, 0, tempz, tempy)); diff --git a/src/k_kart.c b/src/k_kart.c index 5ec49b444..12c4f14e0 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4093,6 +4093,86 @@ static void K_MoveHeldObjects(player_t *player) if (R_PointToDist2(cur->x, cur->y, targx, targy) > 768*FRACUNIT) P_TeleportMove(cur, targx, targy, cur->z); +#ifdef ESLOPE + // We gotta do ALL of this... just so that bananas can tilt in OGL :V + if (P_IsObjectOnGround(cur)) + { + pslope_t *slope = NULL; + sector_t *sec = R_PointInSubsector(cur->x, cur->y)->sector; + boolean flip = (cur->eflags & MFE_VERTICALFLIP); + + if (flip) + { + if (sec->c_slope) + { + slope = sec->c_slope; + targz = P_GetZAt(sec->c_slope, cur->x, cur->y); + } + else + targz = sec->ceilingheight; + } + else + { + if (sec->f_slope) + { + slope = sec->f_slope; + targz = P_GetZAt(sec->f_slope, cur->x, cur->y); + } + else + targz = sec->floorheight; + } + + // Check FOFs for a better suited slope + if (sec->ffloors) + { + ffloor_t *rover; + + for (rover = sec->ffloors; rover; rover = rover->next) + { + fixed_t surface; + + if (!(rover->flags & FF_EXISTS)) + continue; + + if (!((rover->flags & FF_BLOCKOTHERS) || (rover->flags & FF_QUICKSAND)) || (rover->flags & FF_SWIMMABLE)) + continue; + + if (flip) + { + surface = *rover->bottomheight; + if (*rover->b_slope) + surface = P_GetZAt(*rover->b_slope, cur->x, cur->y); + + if (surface < targz && surface > (cur->z + cur->height)) + { + targz = surface; + if (*rover->b_slope) + slope = *rover->b_slope; + } + } + else + { + surface = *rover->topheight; + if (*rover->t_slope) + surface = P_GetZAt(*rover->t_slope, cur->x, cur->y); + + if (surface > targz && surface < cur->z) + { + targz = surface; + if (*rover->t_slope) + slope = *rover->t_slope; + } + } + } + } + + cur->standingslope = slope; +#ifdef HWRENDER + cur->modeltilt = cur->standingslope; +#endif + } +#endif + cur = cur->hnext; } } @@ -4182,6 +4262,9 @@ static void K_MoveHeldObjects(player_t *player) P_TeleportMove(cur, targx, targy, targz); K_FlipFromObject(cur, player->mo); // Update graviflip in real time thanks. +#ifdef HWRENDER + cur->modeltilt = player->mo->modeltilt; +#endif num = (num+1) % 2; cur = cur->hnext; } diff --git a/src/p_map.c b/src/p_map.c index 2c766349d..e7041afea 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2881,14 +2881,24 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) P_HandleSlopeLanding(thing, tmfloorslope); if (thing->momz <= 0) + { thing->standingslope = tmfloorslope; +#ifdef HWRENDER + thing->modeltilt = thing->standingslope; +#endif + } } else if (thing->z+thing->height >= tmceilingz && (thing->eflags & MFE_VERTICALFLIP)) { if (!startingonground && tmceilingslope) P_HandleSlopeLanding(thing, tmceilingslope); if (thing->momz >= 0) + { thing->standingslope = tmceilingslope; +#ifdef HWRENDER + thing->modeltilt = thing->standingslope; +#endif + } } } else // don't set standingslope if you're not going to clip against it @@ -4691,7 +4701,7 @@ fixed_t P_FloorzAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) if (!(rover->flags & FF_EXISTS)) continue; - if ((!(rover->flags & FF_SOLID || rover->flags & FF_QUICKSAND) || (rover->flags & FF_SWIMMABLE))) + if (!((rover->flags & FF_SOLID) || (rover->flags & FF_QUICKSAND)) || (rover->flags & FF_SWIMMABLE)) continue; topheight = *rover->topheight; diff --git a/src/p_mobj.c b/src/p_mobj.c index 1d0224590..dda3d045b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1816,6 +1816,9 @@ void P_XYMovement(mobj_t *mo) // Now compare the Zs of the different quantizations if (oldangle-newangle > ANG30 && oldangle-newangle < ANGLE_180) { // Allow for a bit of sticking - this value can be adjusted later mo->standingslope = oldslope; +#ifdef HWRENDER + mo->modeltilt = mo->standingslope; +#endif P_SlopeLaunch(mo); //CONS_Printf("launched off of slope - "); @@ -2389,6 +2392,9 @@ static boolean P_ZMovement(mobj_t *mo) if (((mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope) && (mo->type != MT_STEAM)) { mo->standingslope = (mo->eflags & MFE_VERTICALFLIP) ? tmceilingslope : tmfloorslope; +#ifdef HWRENDER + mo->modeltilt = mo->standingslope; +#endif P_ReverseQuantizeMomentumToSlope(&mom, mo->standingslope); } #endif @@ -6173,7 +6179,12 @@ void P_RunShadows(void) for (mobj = shadowcap; mobj; mobj = next) { - fixed_t floorz; + boolean flip; + fixed_t newz; + sector_t *sec; +#ifdef ESLOPE + pslope_t *slope = NULL; +#endif next = mobj->hnext; P_SetTarget(&mobj->hnext, NULL); @@ -6184,16 +6195,106 @@ void P_RunShadows(void) continue; // shouldn't you already be dead? } - if (mobj->target->player) - floorz = mobj->target->floorz; - else // FOR SOME REASON, plain floorz is not reliable for normal objects, only players?! - floorz = P_FloorzAtPos(mobj->target->x, mobj->target->y, mobj->target->z, mobj->target->height); - K_MatchGenericExtraFlags(mobj, mobj->target); + flip = (mobj->eflags & MFE_VERTICALFLIP); - if (((mobj->target->eflags & MFE_VERTICALFLIP) && mobj->target->z+mobj->target->height > mobj->target->ceilingz) - || (!(mobj->target->eflags & MFE_VERTICALFLIP) && mobj->target->z < floorz)) - mobj->flags2 |= MF2_DONTDRAW; + sec = R_PointInSubsector(mobj->target->x, mobj->target->y)->sector; + + if (flip) + { +#ifdef ESLOPE + if (sec->c_slope) + { + slope = sec->c_slope; + newz = P_GetZAt(sec->c_slope, mobj->target->x, mobj->target->y); + } + else +#endif + newz = sec->ceilingheight; + } + else + { +#ifdef ESLOPE + if (sec->f_slope) + { + slope = sec->f_slope; + newz = P_GetZAt(sec->f_slope, mobj->target->x, mobj->target->y); + } + else +#endif + newz = sec->floorheight; + } + + // Check FOFs for a better suited slope + if (sec->ffloors) + { + ffloor_t *rover; + + for (rover = sec->ffloors; rover; rover = rover->next) + { + fixed_t surface; + + if (!(rover->flags & FF_EXISTS)) + continue; + + if ((!(((rover->flags & FF_BLOCKPLAYER && mobj->target->player) + || (rover->flags & FF_BLOCKOTHERS && !mobj->target->player)) + || (rover->flags & FF_QUICKSAND)) + || (rover->flags & FF_SWIMMABLE))) + continue; + + if (flip) + { + surface = *rover->bottomheight; +#ifdef ESLOPE + if (*rover->b_slope) + surface = P_GetZAt(*rover->b_slope, mobj->target->x, mobj->target->y); +#endif + + if (surface < newz && surface > (mobj->target->z + mobj->target->height)) + { + newz = surface; +#ifdef ESLOPE + if (*rover->b_slope) + slope = *rover->b_slope; +#endif + } + } + else + { + surface = *rover->topheight; +#ifdef ESLOPE + if (*rover->t_slope) + surface = P_GetZAt(*rover->t_slope, mobj->target->x, mobj->target->y); +#endif + + if (surface > newz && surface < mobj->target->z) + { + newz = surface; +#ifdef ESLOPE + if (*rover->t_slope) + slope = *rover->t_slope; +#endif + } + } + } + } + + mobj->standingslope = slope; +#ifdef HWRENDER + mobj->modeltilt = mobj->standingslope; +#endif + + if (flip) + { + if ((mobj->target->z + mobj->target->height) > newz) + mobj->flags2 |= MF2_DONTDRAW; + } + else + { + if (mobj->target->z < newz) + mobj->flags2 |= MF2_DONTDRAW; + } // First scale to the same radius P_SetScale(mobj, FixedDiv(mobj->target->radius, mobj->info->radius)); @@ -6205,13 +6306,12 @@ void P_RunShadows(void) P_TeleportMove(mobj, dest->x, dest->y, mobj->target->z); - if (((mobj->eflags & MFE_VERTICALFLIP) && (mobj->ceilingz > mobj->z+mobj->height)) - || (!(mobj->eflags & MFE_VERTICALFLIP) && (floorz < mobj->z))) + if ((flip && newz > (mobj->z + mobj->height)) || (!flip && newz < mobj->z)) { INT32 i; fixed_t prevz; - mobj->z = (mobj->eflags & MFE_VERTICALFLIP ? mobj->ceilingz : floorz); + mobj->z = newz; for (i = 0; i < MAXFFLOORS; i++) { @@ -6223,7 +6323,7 @@ void P_RunShadows(void) // Check new position to see if you should still be on that ledge P_TeleportMove(mobj, dest->x, dest->y, mobj->z); - mobj->z = (mobj->eflags & MFE_VERTICALFLIP ? mobj->ceilingz : floorz); + mobj->z = newz; if (mobj->z == prevz) break; @@ -8132,6 +8232,9 @@ void P_MobjThinker(mobj_t *mobj) P_TeleportMove(mobj, mobj->target->x + P_ReturnThrustX(mobj, mobj->angle+ANGLE_180, mobj->target->radius), mobj->target->y + P_ReturnThrustY(mobj, mobj->angle+ANGLE_180, mobj->target->radius), mobj->target->z); P_SetScale(mobj, mobj->target->scale); +#ifdef HWRENDER + mobj->modeltilt = mobj->target->modeltilt; +#endif { player_t *p = NULL; diff --git a/src/p_mobj.h b/src/p_mobj.h index dfc8fc738..aec2ed951 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -370,6 +370,9 @@ typedef struct mobj_s #ifdef ESLOPE struct pslope_s *standingslope; // The slope that the object is standing on (shouldn't need synced in savegames, right?) +#ifdef HWRENDER + struct pslope_s *modeltilt; // Slope used for model tilting. Also is not synched, this is totally visual. +#endif #endif boolean colorized; // Whether the mobj uses the rainbow colormap diff --git a/src/p_saveg.c b/src/p_saveg.c index 7d2e9a307..a3b80633a 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2144,7 +2144,12 @@ static void LoadMobjThinker(actionf_p1 thinker) mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p); #ifdef ESLOPE if (diff2 & MD2_SLOPE) + { mobj->standingslope = P_SlopeById(READUINT16(save_p)); +#ifdef HWRENDER + mobj->modeltilt = mobj->standingslope; +#endif + } #endif if (diff2 & MD2_COLORIZED) mobj->colorized = READUINT8(save_p); diff --git a/src/p_slopes.c b/src/p_slopes.c index 76af7bfde..47e624da9 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -827,6 +827,9 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) if (P_MobjFlip(thing)*(thing->momz) < 0) { // falling, land on slope thing->momz = -P_MobjFlip(thing); thing->standingslope = slope; +#ifdef HWRENDER + thing->modeltilt = thing->standingslope; +#endif } return; } @@ -843,6 +846,9 @@ void P_HandleSlopeLanding(mobj_t *thing, pslope_t *slope) thing->momz = -P_MobjFlip(thing); thing->standingslope = slope; +#ifdef HWRENDER + thing->modeltilt = thing->standingslope; +#endif } } diff --git a/src/p_user.c b/src/p_user.c index 61d8f36f3..6802a9120 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1675,12 +1675,16 @@ mobj_t *P_SpawnGhostMobj(mobj_t *mobj) ghost->frame |= tr_trans50<fuse = ghost->info->damage; ghost->skin = mobj->skin; + ghost->standingslope = mobj->standingslope; +#ifdef HWRENDER + ghost->modeltilt = mobj->modeltilt; +#endif if (mobj->flags2 & MF2_OBJECTFLIP) ghost->flags |= MF2_OBJECTFLIP; if (!(mobj->flags & MF_DONTENCOREMAP)) - mobj->flags &= ~MF_DONTENCOREMAP; + ghost->flags &= ~MF_DONTENCOREMAP; return ghost; } From f3f0b5eddaf97e1621d84f3285bac297e5e31358 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 30 May 2019 03:07:31 -0400 Subject: [PATCH 042/163] Fix FOF shadows again --- src/p_mobj.c | 69 +++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 17 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index a58ff3387..67f540fde 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6264,7 +6264,8 @@ void P_RunShadows(void) for (rover = sec->ffloors; rover; rover = rover->next) { - fixed_t surface; + fixed_t top, bottom; + fixed_t d1, d2; if (!(rover->flags & FF_EXISTS)) continue; @@ -6275,17 +6276,41 @@ void P_RunShadows(void) || (rover->flags & FF_SWIMMABLE))) continue; +#ifdef ESLOPE + if (*rover->t_slope) + top = P_GetZAt(*rover->t_slope, mobj->target->x, mobj->target->y); + else +#endif + top = *rover->topheight; + +#ifdef ESLOPE + if (*rover->b_slope) + bottom = P_GetZAt(*rover->b_slope, mobj->target->x, mobj->target->y); + else +#endif + bottom = *rover->bottomheight; + if (flip) { - surface = *rover->bottomheight; -#ifdef ESLOPE - if (*rover->b_slope) - surface = P_GetZAt(*rover->b_slope, mobj->target->x, mobj->target->y); -#endif - - if (surface < newz && surface > (mobj->target->z + mobj->target->height)) + if (rover->flags & FF_QUICKSAND) { - newz = surface; + if (mobj->target->z < top && (mobj->target->z + mobj->target->height) > bottom) + { + if (newz > (mobj->target->z + mobj->target->height)) + { + newz = (mobj->target->z + mobj->target->height); + slope = NULL; + } + } + continue; + } + + d1 = (mobj->target->z + mobj->target->height) - (top + ((bottom - top)/2)); + d2 = mobj->target->z - (top + ((bottom - top)/2)); + + if (bottom < newz && abs(d1) < abs(d2)) + { + newz = bottom; #ifdef ESLOPE if (*rover->b_slope) slope = *rover->b_slope; @@ -6294,15 +6319,25 @@ void P_RunShadows(void) } else { - surface = *rover->topheight; -#ifdef ESLOPE - if (*rover->t_slope) - surface = P_GetZAt(*rover->t_slope, mobj->target->x, mobj->target->y); -#endif - - if (surface > newz && surface < mobj->target->z) + if (rover->flags & FF_QUICKSAND) { - newz = surface; + if (mobj->target->z < top && (mobj->target->z + mobj->target->height) > bottom) + { + if (newz < mobj->target->z) + { + newz = mobj->target->z; + slope = NULL; + } + } + continue; + } + + d1 = mobj->target->z - (bottom + ((top - bottom)/2)); + d2 = (mobj->target->z + mobj->target->height) - (bottom + ((top - bottom)/2)); + + if (top > newz && abs(d1) < abs(d2)) + { + newz = top; #ifdef ESLOPE if (*rover->t_slope) slope = *rover->t_slope; From 24feb8167195ab18bd556dea102a2ea8d582478d Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 31 May 2019 01:08:04 -0400 Subject: [PATCH 043/163] Improve shadow code yet again by testing highest value of slopes This makes it follow the sprites a bit better on slopes. Also split into a sub-function so that Banana doesn't need the duplicated code anymore. The accuracy can be further improved on by doing the calculation 3 extra times for every surface, for each corner of the hitbox -- it wouldn't be THAT much more expensive, but it would only make subtle differences on sector boundaries that we usually zoom past anyway, so I figured it wasn't worth it. (It'll be easy enough to do so if we decide that we want the uber-accuracy) --- src/k_kart.c | 77 +------------ src/p_local.h | 1 + src/p_mobj.c | 291 ++++++++++++++++++++++++++++---------------------- 3 files changed, 170 insertions(+), 199 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index b3c75a599..45c8652c8 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4527,82 +4527,11 @@ static void K_MoveHeldObjects(player_t *player) P_TeleportMove(cur, targx, targy, cur->z); #ifdef ESLOPE - // We gotta do ALL of this... just so that bananas can tilt in OGL :V if (P_IsObjectOnGround(cur)) { - pslope_t *slope = NULL; - sector_t *sec = R_PointInSubsector(cur->x, cur->y)->sector; - boolean flip = (cur->eflags & MFE_VERTICALFLIP); - - if (flip) - { - if (sec->c_slope) - { - slope = sec->c_slope; - targz = P_GetZAt(sec->c_slope, cur->x, cur->y); - } - else - targz = sec->ceilingheight; - } - else - { - if (sec->f_slope) - { - slope = sec->f_slope; - targz = P_GetZAt(sec->f_slope, cur->x, cur->y); - } - else - targz = sec->floorheight; - } - - // Check FOFs for a better suited slope - if (sec->ffloors) - { - ffloor_t *rover; - - for (rover = sec->ffloors; rover; rover = rover->next) - { - fixed_t surface; - - if (!(rover->flags & FF_EXISTS)) - continue; - - if (!((rover->flags & FF_BLOCKOTHERS) || (rover->flags & FF_QUICKSAND)) || (rover->flags & FF_SWIMMABLE)) - continue; - - if (flip) - { - surface = *rover->bottomheight; - if (*rover->b_slope) - surface = P_GetZAt(*rover->b_slope, cur->x, cur->y); - - if (surface < targz && surface > (cur->z + cur->height)) - { - targz = surface; - if (*rover->b_slope) - slope = *rover->b_slope; - } - } - else - { - surface = *rover->topheight; - if (*rover->t_slope) - surface = P_GetZAt(*rover->t_slope, cur->x, cur->y); - - if (surface > targz && surface < cur->z) - { - targz = surface; - if (*rover->t_slope) - slope = *rover->t_slope; - } - } - } - } - - cur->standingslope = slope; -#ifdef HWRENDER - cur->modeltilt = cur->standingslope; -#endif + // Slope values are set in the function, but we DON'T want to use its return value. + P_CalculateShadowFloor(cur, cur->x, cur->y, cur->z, + cur->radius, cur->height, (cur->eflags & MFE_VERTICALFLIP), false); } #endif diff --git a/src/p_local.h b/src/p_local.h index bc25affd4..d4da9fe29 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -227,6 +227,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state); boolean P_SetMobjState(mobj_t *mobj, statenum_t state); //void P_RunShields(void); void P_RunOverlays(void); +fixed_t P_CalculateShadowFloor(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z, fixed_t radius, fixed_t height, boolean flip, boolean player); void P_RunShadows(void); void P_MobjThinker(mobj_t *mobj); boolean P_RailThinker(mobj_t *mobj); diff --git a/src/p_mobj.c b/src/p_mobj.c index 67f540fde..c2a14cd45 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6205,6 +6205,170 @@ static void P_RemoveOverlay(mobj_t *thing) } } +// Simplified version of a code bit in P_MobjFloorZ +static fixed_t P_ShadowSlopeZ(pslope_t *slope, fixed_t x, fixed_t y, fixed_t radius, boolean ceiling) +{ + fixed_t testx, testy; + + if (slope->d.x < 0) + testx = radius; + else + testx = -radius; + + if (slope->d.y < 0) + testy = radius; + else + testy = -radius; + + if ((slope->zdelta > 0) ^ !!(ceiling)) + { + testx = -testx; + testy = -testy; + } + + testx += x; + testy += y; + + return P_GetZAt(slope, testx, testy); +} + +// Sets standingslope/modeltilt, returns z position for shadows; used also for stuff like bananas +// (I would've preferred to be able to return both the slope & z, but I'll take what I can get...) +fixed_t P_CalculateShadowFloor(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z, fixed_t radius, fixed_t height, boolean flip, boolean player) +{ + fixed_t newz; + sector_t *sec; +#ifdef ESLOPE + pslope_t *slope = NULL; +#endif + + sec = R_PointInSubsector(x, y)->sector; + + if (flip) + { +#ifdef ESLOPE + if (sec->c_slope) + { + slope = sec->c_slope; + newz = P_ShadowSlopeZ(slope, x, y, radius, true); + } + else +#endif + newz = sec->ceilingheight; + } + else + { +#ifdef ESLOPE + if (sec->f_slope) + { + slope = sec->f_slope; + newz = P_ShadowSlopeZ(slope, x, y, radius, false); + } + else +#endif + newz = sec->floorheight; + } + + // Check FOFs for a better suited slope + if (sec->ffloors) + { + ffloor_t *rover; + + for (rover = sec->ffloors; rover; rover = rover->next) + { + fixed_t top, bottom; + fixed_t d1, d2; + + if (!(rover->flags & FF_EXISTS)) + continue; + + if ((!(((rover->flags & FF_BLOCKPLAYER && player) + || (rover->flags & FF_BLOCKOTHERS && !player)) + || (rover->flags & FF_QUICKSAND)) + || (rover->flags & FF_SWIMMABLE))) + continue; + +#ifdef ESLOPE + if (*rover->t_slope) + top = P_ShadowSlopeZ(*rover->t_slope, x, y, radius, false); + else +#endif + top = *rover->topheight; + +#ifdef ESLOPE + if (*rover->b_slope) + bottom = P_ShadowSlopeZ(*rover->b_slope, x, y, radius, true); + else +#endif + bottom = *rover->bottomheight; + + if (flip) + { + if (rover->flags & FF_QUICKSAND) + { + if (z < top && (z + height) > bottom) + { + if (newz > (z + height)) + { + newz = (z + height); + slope = NULL; + } + } + continue; + } + + d1 = (z + height) - (top + ((bottom - top)/2)); + d2 = z - (top + ((bottom - top)/2)); + + if (bottom < newz && abs(d1) < abs(d2)) + { + newz = bottom; +#ifdef ESLOPE + if (*rover->b_slope) + slope = *rover->b_slope; +#endif + } + } + else + { + if (rover->flags & FF_QUICKSAND) + { + if (z < top && (z + height) > bottom) + { + if (newz < z) + { + newz = z; + slope = NULL; + } + } + continue; + } + + d1 = z - (bottom + ((top - bottom)/2)); + d2 = (z + height) - (bottom + ((top - bottom)/2)); + + if (top > newz && abs(d1) < abs(d2)) + { + newz = top; +#ifdef ESLOPE + if (*rover->t_slope) + slope = *rover->t_slope; +#endif + } + } + } + } + +#if 0 + mobj->standingslope = slope; +#endif +#ifdef HWRENDER + mobj->modeltilt = slope; +#endif + + return newz; +} + void P_RunShadows(void) { mobj_t *mobj, *next, *dest; @@ -6213,10 +6377,6 @@ void P_RunShadows(void) { boolean flip; fixed_t newz; - sector_t *sec; -#ifdef ESLOPE - pslope_t *slope = NULL; -#endif next = mobj->hnext; P_SetTarget(&mobj->hnext, NULL); @@ -6230,127 +6390,8 @@ void P_RunShadows(void) K_MatchGenericExtraFlags(mobj, mobj->target); flip = (mobj->eflags & MFE_VERTICALFLIP); - sec = R_PointInSubsector(mobj->target->x, mobj->target->y)->sector; - - if (flip) - { -#ifdef ESLOPE - if (sec->c_slope) - { - slope = sec->c_slope; - newz = P_GetZAt(sec->c_slope, mobj->target->x, mobj->target->y); - } - else -#endif - newz = sec->ceilingheight; - } - else - { -#ifdef ESLOPE - if (sec->f_slope) - { - slope = sec->f_slope; - newz = P_GetZAt(sec->f_slope, mobj->target->x, mobj->target->y); - } - else -#endif - newz = sec->floorheight; - } - - // Check FOFs for a better suited slope - if (sec->ffloors) - { - ffloor_t *rover; - - for (rover = sec->ffloors; rover; rover = rover->next) - { - fixed_t top, bottom; - fixed_t d1, d2; - - if (!(rover->flags & FF_EXISTS)) - continue; - - if ((!(((rover->flags & FF_BLOCKPLAYER && mobj->target->player) - || (rover->flags & FF_BLOCKOTHERS && !mobj->target->player)) - || (rover->flags & FF_QUICKSAND)) - || (rover->flags & FF_SWIMMABLE))) - continue; - -#ifdef ESLOPE - if (*rover->t_slope) - top = P_GetZAt(*rover->t_slope, mobj->target->x, mobj->target->y); - else -#endif - top = *rover->topheight; - -#ifdef ESLOPE - if (*rover->b_slope) - bottom = P_GetZAt(*rover->b_slope, mobj->target->x, mobj->target->y); - else -#endif - bottom = *rover->bottomheight; - - if (flip) - { - if (rover->flags & FF_QUICKSAND) - { - if (mobj->target->z < top && (mobj->target->z + mobj->target->height) > bottom) - { - if (newz > (mobj->target->z + mobj->target->height)) - { - newz = (mobj->target->z + mobj->target->height); - slope = NULL; - } - } - continue; - } - - d1 = (mobj->target->z + mobj->target->height) - (top + ((bottom - top)/2)); - d2 = mobj->target->z - (top + ((bottom - top)/2)); - - if (bottom < newz && abs(d1) < abs(d2)) - { - newz = bottom; -#ifdef ESLOPE - if (*rover->b_slope) - slope = *rover->b_slope; -#endif - } - } - else - { - if (rover->flags & FF_QUICKSAND) - { - if (mobj->target->z < top && (mobj->target->z + mobj->target->height) > bottom) - { - if (newz < mobj->target->z) - { - newz = mobj->target->z; - slope = NULL; - } - } - continue; - } - - d1 = mobj->target->z - (bottom + ((top - bottom)/2)); - d2 = (mobj->target->z + mobj->target->height) - (bottom + ((top - bottom)/2)); - - if (top > newz && abs(d1) < abs(d2)) - { - newz = top; -#ifdef ESLOPE - if (*rover->t_slope) - slope = *rover->t_slope; -#endif - } - } - } - } - - mobj->standingslope = slope; -#ifdef HWRENDER - mobj->modeltilt = mobj->standingslope; -#endif + newz = P_CalculateShadowFloor(mobj, mobj->target->x, mobj->target->y, mobj->target->z, + mobj->target->radius, mobj->target->height, flip, (mobj->target->player != NULL)); if (flip) { From de62209d966c1d952b6a3b78cd733dcb3354d1c0 Mon Sep 17 00:00:00 2001 From: Sryder Date: Fri, 5 Jul 2019 20:34:36 +0100 Subject: [PATCH 044/163] Orbinaut supports slopes, slows down naturally when above top speed. Still has it's speed reset lower when hitting a wall. Doesn't maintain slope speed increase. --- src/p_mobj.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 9919b2266..470615101 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1937,7 +1937,7 @@ void P_XYMovement(mobj_t *mo) #endif //{ SRB2kart stuff - if (mo->type == MT_ORBINAUT || mo->type == MT_JAWZ_DUD || mo->type == MT_JAWZ || mo->type == MT_BALLHOG || mo->type == MT_FLINGRING) //(mo->type == MT_JAWZ && !mo->tracer)) + if (mo->type == MT_JAWZ_DUD || mo->type == MT_JAWZ || mo->type == MT_BALLHOG || mo->type == MT_FLINGRING) //(mo->type == MT_JAWZ && !mo->tracer)) return; if (mo->player && (mo->player->kartstuff[k_spinouttimer] && !mo->player->kartstuff[k_wipeoutslow]) && mo->player->speed <= K_GetKartSpeed(mo->player, false)/2) @@ -7935,6 +7935,8 @@ void P_MobjThinker(mobj_t *mobj) else { fixed_t finalspeed = mobj->movefactor; + const fixed_t currentspeed = R_PointToDist2(0, 0, mobj->momx, mobj->momy); + fixed_t thrustamount = 0; mobj_t *ghost = P_SpawnGhostMobj(mobj); ghost->colorized = true; // already has color! @@ -7946,7 +7948,24 @@ void P_MobjThinker(mobj_t *mobj) finalspeed = FixedMul(finalspeed, FRACUNIT-FRACUNIT/4); } - P_InstaThrust(mobj, mobj->angle, finalspeed); + if (currentspeed >= finalspeed) + { + const fixed_t frictionsafety = (mobj->friction == 0) ? 1 : mobj->friction; + // Thrust as if you were at top speed, slow down naturally + thrustamount = FixedDiv(finalspeed, frictionsafety) - finalspeed; + } + else + { + const fixed_t frictionsafety = (mobj->friction == 0) ? 1 : mobj->friction; + const fixed_t beatfriction = FixedDiv(currentspeed, frictionsafety) - currentspeed; + // Thrust to immediately get to top speed + thrustamount = beatfriction + FixedDiv(finalspeed - currentspeed, frictionsafety); + } + + + P_Thrust(mobj, mobj->angle, thrustamount); + + if (grounded) { @@ -9439,7 +9458,8 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s || mobj->type == MT_BIGTUMBLEWEED || mobj->type == MT_LITTLETUMBLEWEED || mobj->type == MT_CANNONBALLDECOR - || mobj->type == MT_FALLINGROCK) { + || mobj->type == MT_FALLINGROCK + || mobj->type == MT_ORBINAUT) { P_TryMove(mobj, mobj->x, mobj->y, true); // Sets mo->standingslope correctly //if (mobj->standingslope) CONS_Printf("slope physics on mobj\n"); P_ButteredSlope(mobj); From 893d8cd211e80a0e828d02727b7407feeaa69acf Mon Sep 17 00:00:00 2001 From: Sryder Date: Fri, 5 Jul 2019 21:11:13 +0100 Subject: [PATCH 045/163] Support Jawz dud on slopes Don't let orbinaut accelerate infinitely when in the air. --- src/p_mobj.c | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 470615101..6af652028 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1937,7 +1937,7 @@ void P_XYMovement(mobj_t *mo) #endif //{ SRB2kart stuff - if (mo->type == MT_JAWZ_DUD || mo->type == MT_JAWZ || mo->type == MT_BALLHOG || mo->type == MT_FLINGRING) //(mo->type == MT_JAWZ && !mo->tracer)) + if (mo->type == MT_JAWZ || mo->type == MT_BALLHOG || mo->type == MT_FLINGRING) //(mo->type == MT_JAWZ && !mo->tracer)) return; if (mo->player && (mo->player->kartstuff[k_spinouttimer] && !mo->player->kartstuff[k_wipeoutslow]) && mo->player->speed <= K_GetKartSpeed(mo->player, false)/2) @@ -7937,9 +7937,16 @@ void P_MobjThinker(mobj_t *mobj) fixed_t finalspeed = mobj->movefactor; const fixed_t currentspeed = R_PointToDist2(0, 0, mobj->momx, mobj->momy); fixed_t thrustamount = 0; + fixed_t frictionsafety = (mobj->friction == 0) ? 1 : mobj->friction; mobj_t *ghost = P_SpawnGhostMobj(mobj); ghost->colorized = true; // already has color! + if (!grounded) + { + // No friction in the air + frictionsafety = FRACUNIT; + } + mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); if (mobj->health <= 5) { @@ -7950,23 +7957,19 @@ void P_MobjThinker(mobj_t *mobj) if (currentspeed >= finalspeed) { - const fixed_t frictionsafety = (mobj->friction == 0) ? 1 : mobj->friction; + // Thrust as if you were at top speed, slow down naturally thrustamount = FixedDiv(finalspeed, frictionsafety) - finalspeed; } else { - const fixed_t frictionsafety = (mobj->friction == 0) ? 1 : mobj->friction; const fixed_t beatfriction = FixedDiv(currentspeed, frictionsafety) - currentspeed; // Thrust to immediately get to top speed thrustamount = beatfriction + FixedDiv(finalspeed - currentspeed, frictionsafety); } - P_Thrust(mobj, mobj->angle, thrustamount); - - if (grounded) { sector_t *sec2 = P_ThingOnSpecial3DFloor(mobj); @@ -8061,6 +8064,9 @@ void P_MobjThinker(mobj_t *mobj) else { mobj_t *ghost = P_SpawnGhostMobj(mobj); + const fixed_t currentspeed = R_PointToDist2(0, 0, mobj->momx, mobj->momy); + fixed_t frictionsafety = (mobj->friction == 0) ? 1 : mobj->friction; + fixed_t thrustamount = 0; if (mobj->target && !P_MobjWasRemoved(mobj->target) && mobj->target->player) { @@ -8068,8 +8074,26 @@ void P_MobjThinker(mobj_t *mobj) ghost->colorized = true; } + if (!grounded) + { + // No friction in the air + frictionsafety = FRACUNIT; + } + + if (currentspeed >= mobj->movefactor) + { + // Thrust as if you were at top speed, slow down naturally + thrustamount = FixedDiv(mobj->movefactor, frictionsafety) - mobj->movefactor; + } + else + { + const fixed_t beatfriction = FixedDiv(currentspeed, frictionsafety) - currentspeed; + // Thrust to immediately get to top speed + thrustamount = beatfriction + FixedDiv(mobj->movefactor - currentspeed, frictionsafety); + } + mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); - P_InstaThrust(mobj, mobj->angle, mobj->movefactor); + P_Thrust(mobj, mobj->angle, thrustamount); if (grounded) { @@ -9459,7 +9483,8 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s || mobj->type == MT_LITTLETUMBLEWEED || mobj->type == MT_CANNONBALLDECOR || mobj->type == MT_FALLINGROCK - || mobj->type == MT_ORBINAUT) { + || mobj->type == MT_ORBINAUT + || mobj->type == MT_JAWZ_DUD) { P_TryMove(mobj, mobj->x, mobj->y, true); // Sets mo->standingslope correctly //if (mobj->standingslope) CONS_Printf("slope physics on mobj\n"); P_ButteredSlope(mobj); From d6ec65de5991e8a5fe59cc040c7617b3729b84c0 Mon Sep 17 00:00:00 2001 From: Sryder Date: Fri, 5 Jul 2019 23:29:31 +0100 Subject: [PATCH 046/163] Added some slope handling for regular jawz. Jawz as a result can absolutely behave differently, but it's mostly the case when in the range where it would slow down. Will need testing, seems like it can sometimes rocket past a player that's stationary, maybe that's not a bad thing? --- src/p_mobj.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 6af652028..c22d029cc 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1937,7 +1937,7 @@ void P_XYMovement(mobj_t *mo) #endif //{ SRB2kart stuff - if (mo->type == MT_JAWZ || mo->type == MT_BALLHOG || mo->type == MT_FLINGRING) //(mo->type == MT_JAWZ && !mo->tracer)) + if (mo->type == MT_BALLHOG || mo->type == MT_FLINGRING) //(mo->type == MT_JAWZ && !mo->tracer)) return; if (mo->player && (mo->player->kartstuff[k_spinouttimer] && !mo->player->kartstuff[k_wipeoutslow]) && mo->player->speed <= K_GetKartSpeed(mo->player, false)/2) @@ -7957,7 +7957,6 @@ void P_MobjThinker(mobj_t *mobj) if (currentspeed >= finalspeed) { - // Thrust as if you were at top speed, slow down naturally thrustamount = FixedDiv(finalspeed, frictionsafety) - finalspeed; } @@ -7993,6 +7992,9 @@ void P_MobjThinker(mobj_t *mobj) fixed_t topspeed = mobj->movefactor; fixed_t distbarrier = 512*mapobjectscale; fixed_t distaway; + const fixed_t currentspeed = R_PointToDist2(0, 0, mobj->momx, mobj->momy); + fixed_t thrustamount = 0; + fixed_t frictionsafety = (mobj->friction == 0) ? 1 : mobj->friction; mobj_t *ghost = P_SpawnGhostMobj(mobj); if (mobj->target && !P_MobjWasRemoved(mobj->target) && mobj->target->player) @@ -8008,6 +8010,12 @@ void P_MobjThinker(mobj_t *mobj) distbarrier = FixedMul(distbarrier, FRACUNIT + ((gamespeed-1) * (FRACUNIT/4))); + if (!P_IsObjectOnGround(mobj)) + { + // No friction in the air + frictionsafety = FRACUNIT; + } + if (G_RaceGametype() && mobj->tracer) { distaway = P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y); @@ -8021,17 +8029,21 @@ void P_MobjThinker(mobj_t *mobj) } } - if (G_BattleGametype()) + // Don't thrust at ALL if we're in the barrier range and above top speed, harsher slowdown + if ((currentspeed >= topspeed) && topspeed == mobj->movefactor) { - mobj->friction -= 1228; - if (mobj->friction > FRACUNIT) - mobj->friction = FRACUNIT; - if (mobj->friction < 0) - mobj->friction = 0; + // Thrust as if you were at top speed, slow down naturally + thrustamount = FixedDiv(topspeed, frictionsafety) - topspeed; + } + else + { + const fixed_t beatfriction = FixedDiv(currentspeed, frictionsafety) - currentspeed; + // Thrust to immediately get to top speed + thrustamount = beatfriction + FixedDiv(topspeed - currentspeed, frictionsafety); } mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); - P_InstaThrust(mobj, mobj->angle, topspeed); + P_Thrust(mobj, mobj->angle, thrustamount); if (mobj->tracer) mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->tracer->x, mobj->tracer->y); @@ -9484,7 +9496,7 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s || mobj->type == MT_CANNONBALLDECOR || mobj->type == MT_FALLINGROCK || mobj->type == MT_ORBINAUT - || mobj->type == MT_JAWZ_DUD) { + || mobj->type == MT_JAWZ || mobj->type == MT_JAWZ_DUD) { P_TryMove(mobj, mobj->x, mobj->y, true); // Sets mo->standingslope correctly //if (mobj->standingslope) CONS_Printf("slope physics on mobj\n"); P_ButteredSlope(mobj); From fbc5b9f8803d20f6ff5d9c583548fb5ae3998b8a Mon Sep 17 00:00:00 2001 From: Sryder Date: Sun, 7 Jul 2019 15:24:32 +0100 Subject: [PATCH 047/163] Added () for slight clarity --- 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 c22d029cc..f9bfc807b 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8030,7 +8030,7 @@ void P_MobjThinker(mobj_t *mobj) } // Don't thrust at ALL if we're in the barrier range and above top speed, harsher slowdown - if ((currentspeed >= topspeed) && topspeed == mobj->movefactor) + if ((currentspeed >= topspeed) && (topspeed == mobj->movefactor)) { // Thrust as if you were at top speed, slow down naturally thrustamount = FixedDiv(topspeed, frictionsafety) - topspeed; From d6382107d378892f4005977425d394a21ed3f7c4 Mon Sep 17 00:00:00 2001 From: Sryder Date: Sun, 7 Jul 2019 21:56:23 +0100 Subject: [PATCH 048/163] Hopefully better Jawz behaviour Moved the movement code for it out of the thinker and into A_JawzChase to have it all in a consistent place. --- src/p_enemy.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++-- src/p_mobj.c | 48 +-------------------------- 2 files changed, 90 insertions(+), 50 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index 7baca2adc..14eea8135 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8309,7 +8309,11 @@ void A_ItemPop(mobj_t *actor) void A_JawzChase(mobj_t *actor) { + const fixed_t currentspeed = R_PointToDist2(0, 0, actor->momx, actor->momy); player_t *player; + fixed_t thrustamount = 0; + fixed_t frictionsafety = (actor->friction == 0) ? 1 : actor->friction; + fixed_t topspeed = actor->movefactor; #ifdef HAVE_BLUA if (LUA_CallAction("A_JawzChase", actor)) return; @@ -8322,20 +8326,102 @@ void A_JawzChase(mobj_t *actor) if (actor->tracer->health) { + const angle_t targetangle = R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y); mobj_t *ret; + angle_t angledelta = actor->angle - targetangle; + boolean turnclockwise = true; + + if (G_RaceGametype()) + { + const fixed_t distbarrier = FixedMul(512*mapobjectscale, FRACUNIT + ((gamespeed-1) * (FRACUNIT/4))); + const fixed_t distaway = P_AproxDistance(actor->tracer->x - actor->x, actor->tracer->y - actor->y); + if (distaway < distbarrier) + { + if (actor->tracer->player) + { + fixed_t speeddifference = abs(topspeed - min(actor->tracer->player->speed, K_GetKartSpeed(actor->tracer->player, false))); + topspeed = topspeed - FixedMul(speeddifference, FRACUNIT-FixedDiv(distaway, distbarrier)); + } + } + } + + if (angledelta != 0) + { + angle_t MAX_JAWZ_TURN = ANGLE_90/15; // We can turn a maximum of 6 degrees per frame at regular max speed + // MAX_JAWZ_TURN gets stronger the slower the top speed of jawz + if (topspeed < actor->movefactor) + { + if (topspeed == 0) + { + MAX_JAWZ_TURN = ANGLE_180; + } + else + { + fixed_t anglemultiplier = FixedDiv(actor->movefactor, topspeed); + MAX_JAWZ_TURN += FixedAngle(FixedMul(AngleFixed(MAX_JAWZ_TURN), anglemultiplier)); + } + } + + if (angledelta > ANGLE_180) + { + angledelta = InvAngle(angledelta); + turnclockwise = false; + } + + if (angledelta > MAX_JAWZ_TURN) + { + angledelta = MAX_JAWZ_TURN; + } + + if (turnclockwise) + { + actor->angle -= angledelta; + } + else + { + actor->angle += angledelta; + } + } + + CONS_Printf("ad: %d\n", angledelta); ret = P_SpawnMobj(actor->tracer->x, actor->tracer->y, actor->tracer->z, MT_PLAYERRETICULE); P_SetTarget(&ret->target, actor->tracer); ret->frame |= ((leveltime % 10) / 2) + 5; ret->color = actor->cvmem; - - P_Thrust(actor, R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y), (7*actor->movefactor)/64); - return; } else P_SetTarget(&actor->tracer, NULL); } + if (!P_IsObjectOnGround(actor)) + { + // No friction in the air + frictionsafety = FRACUNIT; + } + + if (currentspeed >= topspeed) + { + // Thrust as if you were at top speed, slow down naturally + thrustamount = FixedDiv(topspeed, frictionsafety) - topspeed; + } + else + { + const fixed_t beatfriction = FixedDiv(currentspeed, frictionsafety) - currentspeed; + // Thrust to immediately get to top speed + thrustamount = beatfriction + FixedDiv(topspeed - currentspeed, frictionsafety); + } + + if (!actor->tracer) + { + actor->angle = R_PointToAngle2(0, 0, actor->momx, actor->momy); + } + + P_Thrust(actor, actor->angle, thrustamount); + + if ((actor->tracer != NULL) && (actor->tracer->health > 0)) + return; + if (actor->extravalue1) // Disable looking by setting this return; diff --git a/src/p_mobj.c b/src/p_mobj.c index f9bfc807b..aae777335 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -7989,12 +7989,6 @@ void P_MobjThinker(mobj_t *mobj) case MT_JAWZ: { sector_t *sec2; - fixed_t topspeed = mobj->movefactor; - fixed_t distbarrier = 512*mapobjectscale; - fixed_t distaway; - const fixed_t currentspeed = R_PointToDist2(0, 0, mobj->momx, mobj->momy); - fixed_t thrustamount = 0; - fixed_t frictionsafety = (mobj->friction == 0) ? 1 : mobj->friction; mobj_t *ghost = P_SpawnGhostMobj(mobj); if (mobj->target && !P_MobjWasRemoved(mobj->target) && mobj->target->player) @@ -8008,47 +8002,7 @@ void P_MobjThinker(mobj_t *mobj) if (leveltime % TICRATE == 0) S_StartSound(mobj, mobj->info->activesound); - distbarrier = FixedMul(distbarrier, FRACUNIT + ((gamespeed-1) * (FRACUNIT/4))); - - if (!P_IsObjectOnGround(mobj)) - { - // No friction in the air - frictionsafety = FRACUNIT; - } - - if (G_RaceGametype() && mobj->tracer) - { - distaway = P_AproxDistance(mobj->tracer->x - mobj->x, mobj->tracer->y - mobj->y); - if (distaway < distbarrier) - { - if (mobj->tracer->player) - { - fixed_t speeddifference = abs(topspeed - min(mobj->tracer->player->speed, K_GetKartSpeed(mobj->tracer->player, false))); - topspeed = topspeed - FixedMul(speeddifference, FRACUNIT-FixedDiv(distaway, distbarrier)); - } - } - } - - // Don't thrust at ALL if we're in the barrier range and above top speed, harsher slowdown - if ((currentspeed >= topspeed) && (topspeed == mobj->movefactor)) - { - // Thrust as if you were at top speed, slow down naturally - thrustamount = FixedDiv(topspeed, frictionsafety) - topspeed; - } - else - { - const fixed_t beatfriction = FixedDiv(currentspeed, frictionsafety) - currentspeed; - // Thrust to immediately get to top speed - thrustamount = beatfriction + FixedDiv(topspeed - currentspeed, frictionsafety); - } - - mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); - P_Thrust(mobj, mobj->angle, thrustamount); - - if (mobj->tracer) - mobj->angle = R_PointToAngle2(mobj->x, mobj->y, mobj->tracer->x, mobj->tracer->y); - else - mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); + // Movement handling has ALL been moved to A_JawzChase K_DriftDustHandling(mobj); From 407157496a56b97925dbf9034910da585643fd65 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Tue, 16 Jul 2019 16:03:31 -0400 Subject: [PATCH 049/163] Fix colors looking washed-out on models --- src/hardware/hw_md2.c | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c index b610d410c..21deed84b 100644 --- a/src/hardware/hw_md2.c +++ b/src/hardware/hw_md2.c @@ -849,27 +849,17 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch, { // Color strength depends on image alpha INT32 tempcolor; - INT16 tempmult, tempalpha; - tempalpha = -(abs(blendimage->s.red-127)-127)*2; - if (tempalpha > 255) - tempalpha = 255; - else if (tempalpha < 0) - tempalpha = 0; - - tempmult = (blendimage->s.red-127)*2; - if (tempmult > 255) - tempmult = 255; - else if (tempmult < 0) - tempmult = 0; - - tempcolor = (image->s.red*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.red)/255)) * blendimage->s.alpha)/255; + tempcolor = ((image->s.red * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.red * blendimage->s.alpha) / 255); + tempcolor = min(255, tempcolor); cur->s.red = (UINT8)tempcolor; - tempcolor = (image->s.green*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.green)/255)) * blendimage->s.alpha)/255; + tempcolor = ((image->s.green * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.green * blendimage->s.alpha) / 255); + tempcolor = min(255, tempcolor); cur->s.green = (UINT8)tempcolor; - tempcolor = (image->s.blue*(255-blendimage->s.alpha))/255 + ((tempmult + ((tempalpha*blendcolor.s.blue)/255)) * blendimage->s.alpha)/255; + tempcolor = ((image->s.blue * (255-blendimage->s.alpha)) / 255) + ((blendcolor.s.blue * blendimage->s.alpha) / 255); + tempcolor = min(255, tempcolor); cur->s.blue = (UINT8)tempcolor; cur->s.alpha = image->s.alpha; } From 94081f469e14d7ad600a8976a2d967349b21f293 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 4 Aug 2019 23:42:30 -0400 Subject: [PATCH 050/163] 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 051/163] 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 052/163] 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 053/163] 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 054/163] 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 055/163] 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 056/163] 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 0006ceac888346401948a5e5df1e0e62a34dd672 Mon Sep 17 00:00:00 2001 From: Sryder Date: Sun, 11 Aug 2019 18:37:18 +0100 Subject: [PATCH 057/163] Remove stray CONS_Printf --- src/p_enemy.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index bb8169a23..9569b2c4c 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -8395,8 +8395,6 @@ void A_JawzChase(mobj_t *actor) } } - CONS_Printf("ad: %d\n", angledelta); - ret = P_SpawnMobj(actor->tracer->x, actor->tracer->y, actor->tracer->z, MT_PLAYERRETICULE); P_SetTarget(&ret->target, actor->tracer); ret->frame |= ((leveltime % 10) / 2) + 5; From de8030bc2eabc50d7fd87d23d16c2e3fb7845967 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 11 Aug 2019 12:32:57 -0700 Subject: [PATCH 058/163] Toggle ping and FPS counters with HUD --- src/sdl/i_video.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index 42e0a917f..e5f1c23fc 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1377,11 +1377,14 @@ void I_FinishUpdate(void) if (I_SkipFrame()) return; - if (cv_ticrate.value) - SCR_DisplayTicRate(); + if (st_overlay) + { + if (cv_ticrate.value) + SCR_DisplayTicRate(); - if (cv_showping.value && netgame && consoleplayer != serverplayer) - SCR_DisplayLocalPing(); + if (cv_showping.value && netgame && consoleplayer != serverplayer) + SCR_DisplayLocalPing(); + } if (rendermode == render_soft && screens[0]) { From 63abd92a0e4171656d4c57c1713dc0a1f63f37c9 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 11 Aug 2019 12:35:06 -0700 Subject: [PATCH 059/163] Apply HUD translucency to ping and FPS counters --- src/screen.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/screen.c b/src/screen.c index 4cb8bac5d..96a78ae8e 100644 --- a/src/screen.c +++ b/src/screen.c @@ -427,13 +427,13 @@ void SCR_DisplayTicRate(void) ticcntcolor|V_NOSCALESTART, va("%02d/%02u", totaltics, TICRATE));*/ // draw "FPS" - V_DrawFixedPatch(306< servermaxping)) // only show 2 (warning) if our ping is at a bad level { INT32 dispy = cv_ticrate.value ? 160 : 181; - HU_drawPing(307, dispy, ping, V_SNAPTORIGHT | V_SNAPTOBOTTOM); + HU_drawPing(307, dispy, ping, V_SNAPTORIGHT | V_SNAPTOBOTTOM | V_HUDTRANS); } } From 780202668b0ff1f515fe0e8d6a2ae9f6707f602f Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 11 Aug 2019 15:35:38 -0400 Subject: [PATCH 060/163] 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 094c926fd095be6514bf160ee72d5d095930c606 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 11 Aug 2019 13:09:03 -0700 Subject: [PATCH 061/163] Apply hud translucency to FREE PLAY --- 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 c56c7c982..d0fef36a8 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -9560,7 +9560,7 @@ void K_drawKartFreePlay(UINT32 flashtime) return; V_DrawKartString((BASEVIDWIDTH - (LAPS_X+1)) - (12*9), // mirror the laps thingy - LAPS_Y+3, V_SNAPTOBOTTOM|V_SNAPTORIGHT, "FREE PLAY"); + LAPS_Y+3, V_HUDTRANS|V_SNAPTOBOTTOM|V_SNAPTORIGHT, "FREE PLAY"); } static void K_drawDistributionDebugger(void) From e0a177e612135de8c393f30a4858c12ee6233fa3 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Wed, 11 Sep 2019 23:33:33 -0400 Subject: [PATCH 062/163] Horizontal springs, bigger hitboxes, springs use the meatier Sonic 3 sound effect --- src/dehacked.c | 62 +++++---- src/info.c | 363 ++++++++++++++++++++++++++++++------------------- src/info.h | 77 ++++++----- src/k_kart.c | 11 -- 4 files changed, 303 insertions(+), 210 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index be45f3f0f..b8f2ecdec 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -5609,44 +5609,59 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_RBIRD2", "S_RBIRD3", - "S_YELLOWSPRING", + // Yellow Spring + "S_YELLOWSPRING1", "S_YELLOWSPRING2", "S_YELLOWSPRING3", "S_YELLOWSPRING4", - "S_YELLOWSPRING5", - "S_REDSPRING", + // Red Spring + "S_REDSPRING1", "S_REDSPRING2", "S_REDSPRING3", "S_REDSPRING4", - "S_REDSPRING5", - // Blue Springs - "S_BLUESPRING", + // Blue Spring + "S_BLUESPRING1", "S_BLUESPRING2", "S_BLUESPRING3", "S_BLUESPRING4", - "S_BLUESPRING5", // Yellow Diagonal Spring "S_YDIAG1", "S_YDIAG2", "S_YDIAG3", "S_YDIAG4", - "S_YDIAG5", - "S_YDIAG6", - "S_YDIAG7", - "S_YDIAG8", // Red Diagonal Spring "S_RDIAG1", "S_RDIAG2", "S_RDIAG3", "S_RDIAG4", - "S_RDIAG5", - "S_RDIAG6", - "S_RDIAG7", - "S_RDIAG8", + + // Blue Diagonal Spring + "S_BDIAG1", + "S_BDIAG2", + "S_BDIAG3", + "S_BDIAG4", + + // Yellow Horizontal Spring + "S_YHORIZ1", + "S_YHORIZ2", + "S_YHORIZ3", + "S_YHORIZ4", + + // Red Horizontal Spring + "S_RHORIZ1", + "S_RHORIZ2", + "S_RHORIZ3", + "S_RHORIZ4", + + // Blue Horizontal Spring + "S_BHORIZ1", + "S_BHORIZ2", + "S_BHORIZ3", + "S_BHORIZ4", // Rain "S_RAIN1", @@ -6281,16 +6296,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit // Invis-spring - this is used just for the sproing sound. "S_INVISSPRING", - // Blue Diagonal Spring - "S_BDIAG1", - "S_BDIAG2", - "S_BDIAG3", - "S_BDIAG4", - "S_BDIAG5", - "S_BDIAG6", - "S_BDIAG7", - "S_BDIAG8", - //{ Random Item Box "S_RANDOMITEM1", "S_RANDOMITEM2", @@ -7328,11 +7333,15 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s // Springs and others "MT_FAN", "MT_STEAM", // Steam riser - "MT_BLUESPRING", "MT_YELLOWSPRING", "MT_REDSPRING", + "MT_BLUESPRING", "MT_YELLOWDIAG", // Yellow Diagonal Spring "MT_REDDIAG", // Red Diagonal Spring + "MT_BLUEDIAG", // Blue Diagonal Spring + "MT_YELLOWHORIZ", // Yellow Horizontal Spring + "MT_REDHORIZ", // Red Horizontal Spring + "MT_BLUEHORIZ", // Blue Horizontal Spring // Interactive Objects "MT_BUBBLES", // Bubble source @@ -7716,7 +7725,6 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s // SRB2kart "MT_GRAYSPRING", "MT_INVISSPRING", - "MT_BLUEDIAG", "MT_RANDOMITEM", "MT_RANDOMITEMPOP", "MT_FLOATINGITEM", diff --git a/src/info.c b/src/info.c index 31f2f8348..c7a826372 100644 --- a/src/info.c +++ b/src/info.c @@ -43,33 +43,33 @@ char sprnames[NUMSPRITES + 1][5] = "DFLM","XMS1","XMS2","XMS3","BSZ1","BSZ2","BSZ3","BSZ4","BSZ5","BSZ6", "BSZ7","BSZ8","STLG","DBAL","RCRY","ARMA","ARMF","ARMB","WIND","MAGN", "ELEM","FORC","PITY","IVSP","SSPK","GOAL","BIRD","BUNY","MOUS","CHIC", - "COWZ","RBRD","SPRY","SPRR","SPRB","YSPR","RSPR","RAIN","SNO1","SPLH", - "SPLA","SMOK","BUBP","BUBO","BUBN","BUBM","POPP","TFOG","SEED","PRTL", - "SCOR","DRWN","TTAG","GFLG","RRNG","RNGB","RNGR","RNGI","RNGA","RNGE", - "RNGS","RNGG","PIKB","PIKR","PIKA","PIKE","PIKS","PIKG","TAUT","TGRE", - "TSCR","COIN","CPRK","GOOM","BGOM","FFWR","FBLL","SHLL","PUMA","HAMM", - "KOOP","BFLM","MAXE","MUS1","MUS2","TOAD","NDRN","SUPE","SUPZ","NDRL", - "NSPK","NBMP","HOOP","NSCR","NPRU","CAPS","SUPT","SPRK","BOM1","BOM2", - "BOM3","BOM4","ROIA","ROIB","ROIC","ROID","ROIE","ROIF","ROIG","ROIH", - "ROII","ROIJ","ROIK","ROIL","ROIM","ROIN","ROIO","ROIP","BBAL","GWLG", - "GWLR","SRBA","SRBB","SRBC","SRBD","SRBE","SRBF","SRBG","SRBH","SRBI", - "SRBJ","SRBK","SRBL","SRBM","SRBN","SRBO", + "COWZ","RBRD","SPVY","SPVR","SPVB","SPDY","SPDR","SPDB","SPHY","SPHR", + "SPHB","RAIN","SNO1","SPLH","SPLA","SMOK","BUBP","BUBO","BUBN","BUBM", + "POPP","TFOG","SEED","PRTL","SCOR","DRWN","TTAG","GFLG","RRNG","RNGB", + "RNGR","RNGI","RNGA","RNGE","RNGS","RNGG","PIKB","PIKR","PIKA","PIKE", + "PIKS","PIKG","TAUT","TGRE","TSCR","COIN","CPRK","GOOM","BGOM","FFWR", + "FBLL","SHLL","PUMA","HAMM","KOOP","BFLM","MAXE","MUS1","MUS2","TOAD", + "NDRN","SUPE","SUPZ","NDRL","NSPK","NBMP","HOOP","NSCR","NPRU","CAPS", + "SUPT","SPRK","BOM1","BOM2","BOM3","BOM4","ROIA","ROIB","ROIC","ROID", + "ROIE","ROIF","ROIG","ROIH","ROII","ROIJ","ROIK","ROIL","ROIM","ROIN", + "ROIO","ROIP","BBAL","GWLG","GWLR","SRBA","SRBB","SRBC","SRBD","SRBE", + "SRBF","SRBG","SRBH","SRBI","SRBJ","SRBK","SRBL","SRBM","SRBN","SRBO", //SRB2kart Sprites - "SPRG","BSPR","RNDM","RPOP","SGNS","FAST","DSHR","BOST","BOSM","KFRE", - "KINV","KINF","WIPD","DRIF","BDRF","DUST","RSHE","FITM","BANA","ORBN", - "JAWZ","SSMN","KRBM","BHOG","BHBM","SPBM","THNS","SINK","SITR","KBLN", - "DEZL","POKE","AUDI","DECO","DOOD","SNES","GBAS","SPRS","BUZB","CHOM", - "SACO","CRAB","SHAD","BRNG","BUMP","FLEN","CLAS","PSHW","ISTA","ISTB", - "ARRO","ITEM","ITMO","ITMI","ITMN","WANT","PBOM","HIT1","HIT2","HIT3", - "RETI","AIDU","KSPK","LZI1","LZI2","KLIT","FZSM","FZBM","FPRT","SBUS", - "MARB","FUFO","RUST","BLON","VAPE","HTZA","HTZB","SGVA","SGVB","SGVC", - "PGTR","PGF1","PGF2","PGF3","PGBH","DPLR","SPTL","ENM1","GARU","MARR", - "REAP","JITB","CDMO","CDBU","PINE","PPLR","DPPT","AATR","COCO","BDST", - "FROG","CBRA","HOLE","BBRA","EGFG","SMKP","MTYM","THWP","SNOB","ICEB", - "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", - "MXCL","RGSP","DRAF","XMS4","XMS5","VIEW" + "SPRG","RNDM","RPOP","SGNS","FAST","DSHR","BOST","BOSM","KFRE","KINV", + "KINF","WIPD","DRIF","BDRF","DUST","RSHE","FITM","BANA","ORBN","JAWZ", + "SSMN","KRBM","BHOG","BHBM","SPBM","THNS","SINK","SITR","KBLN","DEZL", + "POKE","AUDI","DECO","DOOD","SNES","GBAS","SPRS","BUZB","CHOM","SACO", + "CRAB","SHAD","BRNG","BUMP","FLEN","CLAS","PSHW","ISTA","ISTB","ARRO", + "ITEM","ITMO","ITMI","ITMN","WANT","PBOM","HIT1","HIT2","HIT3","RETI", + "AIDU","KSPK","LZI1","LZI2","KLIT","FZSM","FZBM","FPRT","SBUS","MARB", + "FUFO","RUST","BLON","VAPE","HTZA","HTZB","SGVA","SGVB","SGVC","PGTR", + "PGF1","PGF2","PGF3","PGBH","DPLR","SPTL","ENM1","GARU","MARR","REAP", + "JITB","CDMO","CDBU","PINE","PPLR","DPPT","AATR","COCO","BDST","FROG", + "CBRA","HOLE","BBRA","EGFG","SMKP","MTYM","THWP","SNOB","ICEB","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","MXCL", + "RGSP","DRAF","XMS4","XMS5","VIEW" }; // Doesn't work with g++, needs actionf_p1 (don't modify this comment) @@ -1795,45 +1795,58 @@ state_t states[NUMSTATES] = {SPR_RBRD, 1, 4, {A_Chase}, 0, 0, S_RBIRD2}, // S_RBIRD3 // Yellow Spring - {SPR_SPRY, 0, -1, {NULL}, 0, 0, S_NULL}, // S_YELLOWSPRING - {SPR_SPRY, 4, 4, {A_Pain}, 0, 0, S_YELLOWSPRING3}, // S_YELLOWSPRING2 - {SPR_SPRY, 3, 1, {NULL}, 0, 0, S_YELLOWSPRING4}, // S_YELLOWSPRING3 - {SPR_SPRY, 2, 1, {NULL}, 0, 0, S_YELLOWSPRING5}, // S_YELLOWSPRING4 - {SPR_SPRY, 1, 1, {NULL}, 0, 0, S_YELLOWSPRING}, // S_YELLOWSPRING5 + {SPR_SPVY, 0, -1, {NULL}, 0, 0, S_NULL}, // S_YELLOWSPRING1 + {SPR_SPVY, 1, 1, {A_Pain}, 0, 0, S_YELLOWSPRING3}, // S_YELLOWSPRING2 + {SPR_SPVY, 0, 1, {NULL}, 0, 0, S_YELLOWSPRING4}, // S_YELLOWSPRING3 + {SPR_SPVY, 2, 4, {NULL}, 0, 0, S_YELLOWSPRING1}, // S_YELLOWSPRING4 // Red Spring - {SPR_SPRR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_REDSPRING - {SPR_SPRR, 4, 4, {A_Pain}, 0, 0, S_REDSPRING3}, // S_REDSPRING2 - {SPR_SPRR, 3, 1, {NULL}, 0, 0, S_REDSPRING4}, // S_REDSPRING3 - {SPR_SPRR, 2, 1, {NULL}, 0, 0, S_REDSPRING5}, // S_REDSPRING4 - {SPR_SPRR, 1, 1, {NULL}, 0, 0, S_REDSPRING}, // S_REDSPRING5 + {SPR_SPVR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_REDSPRING1 + {SPR_SPVR, 1, 1, {A_Pain}, 0, 0, S_REDSPRING3}, // S_REDSPRING2 + {SPR_SPVR, 0, 1, {NULL}, 0, 0, S_REDSPRING4}, // S_REDSPRING3 + {SPR_SPVR, 2, 4, {NULL}, 0, 0, S_REDSPRING1}, // S_REDSPRING4 // Blue Spring - {SPR_SPRB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BLUESPRING - {SPR_SPRB, 4, 4, {A_Pain}, 0, 0, S_BLUESPRING3}, // S_BLUESPRING2 - {SPR_SPRB, 3, 1, {NULL}, 0, 0, S_BLUESPRING4}, // S_BLUESPRING3 - {SPR_SPRB, 2, 1, {NULL}, 0, 0, S_BLUESPRING5}, // S_BLUESPRING4 - {SPR_SPRB, 1, 1, {NULL}, 0, 0, S_BLUESPRING}, // S_BLUESPRING5 + {SPR_SPVB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BLUESPRING1 + {SPR_SPVB, 1, 1, {A_Pain}, 0, 0, S_BLUESPRING3}, // S_BLUESPRING2 + {SPR_SPVB, 0, 1, {NULL}, 0, 0, S_BLUESPRING4}, // S_BLUESPRING3 + {SPR_SPVB, 2, 4, {NULL}, 0, 0, S_BLUESPRING1}, // S_BLUESPRING4 // Yellow Diagonal Spring - {SPR_YSPR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_YDIAG1 - {SPR_YSPR, 1, 1, {A_Pain}, 0, 0, S_YDIAG3}, // S_YDIAG2 - {SPR_YSPR, 2, 1, {NULL}, 0, 0, S_YDIAG4}, // S_YDIAG3 - {SPR_YSPR, 3, 1, {NULL}, 0, 0, S_YDIAG5}, // S_YDIAG4 - {SPR_YSPR, 4, 1, {NULL}, 0, 0, S_YDIAG6}, // S_YDIAG5 - {SPR_YSPR, 3, 1, {NULL}, 0, 0, S_YDIAG7}, // S_YDIAG6 - {SPR_YSPR, 2, 1, {NULL}, 0, 0, S_YDIAG8}, // S_YDIAG7 - {SPR_YSPR, 1, 1, {NULL}, 0, 0, S_YDIAG1}, // S_YDIAG8 + {SPR_SPDY, 0, -1, {NULL}, 0, 0, S_NULL}, // S_YDIAG1 + {SPR_SPDY, 1, 1, {A_Pain}, 0, 0, S_YDIAG3}, // S_YDIAG2 + {SPR_SPDY, 0, 1, {NULL}, 0, 0, S_YDIAG4}, // S_YDIAG3 + {SPR_SPDY, 2, 4, {NULL}, 0, 0, S_YDIAG1}, // S_YDIAG4 // Red Diagonal Spring - {SPR_RSPR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_RDIAG1 - {SPR_RSPR, 1, 1, {A_Pain}, 0, 0, S_RDIAG3}, // S_RDIAG2 - {SPR_RSPR, 2, 1, {NULL}, 0, 0, S_RDIAG4}, // S_RDIAG3 - {SPR_RSPR, 3, 1, {NULL}, 0, 0, S_RDIAG5}, // S_RDIAG4 - {SPR_RSPR, 4, 1, {NULL}, 0, 0, S_RDIAG6}, // S_RDIAG5 - {SPR_RSPR, 3, 1, {NULL}, 0, 0, S_RDIAG7}, // S_RDIAG6 - {SPR_RSPR, 2, 1, {NULL}, 0, 0, S_RDIAG8}, // S_RDIAG7 - {SPR_RSPR, 1, 1, {NULL}, 0, 0, S_RDIAG1}, // S_RDIAG8 + {SPR_SPDR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_RDIAG1 + {SPR_SPDR, 1, 1, {A_Pain}, 0, 0, S_RDIAG3}, // S_RDIAG2 + {SPR_SPDR, 0, 1, {NULL}, 0, 0, S_RDIAG4}, // S_RDIAG3 + {SPR_SPDR, 2, 4, {NULL}, 0, 0, S_RDIAG1}, // S_RDIAG4 + + // Blue Diagonal Spring + {SPR_SPDB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BDIAG1 + {SPR_SPDB, 1, 1, {A_Pain}, 0, 0, S_BDIAG3}, // S_BDIAG2 + {SPR_SPDB, 0, 1, {NULL}, 0, 0, S_BDIAG4}, // S_BDIAG3 + {SPR_SPDB, 2, 4, {NULL}, 0, 0, S_BDIAG1}, // S_BDIAG4 + + // Yellow Horizontal Spring + {SPR_SPHY, 0, -1, {NULL}, 0, 0, S_NULL}, // S_YHORIZ1 + {SPR_SPHY, 1, 1, {A_Pain}, 0, 0, S_YHORIZ3}, // S_YHORIZ2 + {SPR_SPHY, 0, 1, {NULL}, 0, 0, S_YHORIZ4}, // S_YHORIZ3 + {SPR_SPHY, 2, 4, {NULL}, 0, 0, S_YHORIZ1}, // S_YHORIZ4 + + // Red Horizontal Spring + {SPR_SPHR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_RHORIZ1 + {SPR_SPHR, 1, 1, {A_Pain}, 0, 0, S_RHORIZ3}, // S_RHORIZ2 + {SPR_SPHR, 0, 1, {NULL}, 0, 0, S_RHORIZ4}, // S_RHORIZ3 + {SPR_SPHR, 2, 4, {NULL}, 0, 0, S_RHORIZ1}, // S_RHORIZ4 + + // Blue Horizontal Spring + {SPR_SPHB, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BHORIZ1 + {SPR_SPHB, 1, 1, {A_Pain}, 0, 0, S_BHORIZ3}, // S_BHORIZ2 + {SPR_SPHB, 0, 1, {NULL}, 0, 0, S_BHORIZ4}, // S_BHORIZ3 + {SPR_SPHB, 2, 4, {NULL}, 0, 0, S_BHORIZ1}, // S_BHORIZ4 // Rain {SPR_RAIN, FF_TRANS50, -1, {NULL}, 0, 0, S_NULL}, // S_RAIN1 @@ -2520,15 +2533,6 @@ state_t states[NUMSTATES] = {SPR_NULL, 0, 1, {A_Pain}, 0, 0, S_INVISIBLE}, // S_INVISSPRING - {SPR_BSPR, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BDIAG1 - {SPR_BSPR, 1, 1, {A_Pain}, 0, 0, S_BDIAG3}, // S_BDIAG2 - {SPR_BSPR, 2, 1, {NULL}, 0, 0, S_BDIAG4}, // S_BDIAG3 - {SPR_BSPR, 3, 1, {NULL}, 0, 0, S_BDIAG5}, // S_BDIAG4 - {SPR_BSPR, 4, 1, {NULL}, 0, 0, S_BDIAG6}, // S_BDIAG5 - {SPR_BSPR, 3, 1, {NULL}, 0, 0, S_BDIAG7}, // S_BDIAG6 - {SPR_BSPR, 2, 1, {NULL}, 0, 0, S_BDIAG8}, // S_BDIAG7 - {SPR_BSPR, 1, 1, {NULL}, 0, 0, S_BDIAG1}, // S_BDIAG8 - {SPR_RNDM, 0|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM2}, // S_RANDOMITEM1 {SPR_RNDM, 1|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM3}, // S_RANDOMITEM2 {SPR_RNDM, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM4}, // S_RANDOMITEM3 @@ -4237,7 +4241,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // attacksound S_NULL, // painstate 0, // painchance - sfx_spring, // painsound + sfx_s3kb1, // painsound S_NULL, // meleestate S_NULL, // missilestate S_XPLD1, // deathstate @@ -4264,7 +4268,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // attacksound S_NULL, // painstate 0, // painchance - sfx_spring, // painsound + sfx_s3kb1, // painsound S_NULL, // meleestate S_NULL, // missilestate S_XPLD1, // deathstate @@ -4681,7 +4685,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // display offset 0, // mass 0, // damage - sfx_spring, // activesound + sfx_s3kb1, // activesound MF_SPECIAL|MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOCLIPTHING, // flags S_EGGMOBILE2_POGO5 // raisestate }, @@ -6058,36 +6062,9 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_BLUESPRING - 552, // doomednum - S_BLUESPRING, // spawnstate - 1000, // spawnhealth - S_BLUESPRING2, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_spring, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 20*FRACUNIT, // radius - 16*FRACUNIT, // height - 0, // display offset - 14*FRACUNIT, // mass - 0, // damage - sfx_None, // activesound - MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags - S_BLUESPRING2 // raisestate - }, - { // MT_YELLOWSPRING 550, // doomednum - S_YELLOWSPRING, // spawnstate + S_YELLOWSPRING1,// spawnstate 1000, // spawnhealth S_YELLOWSPRING2,// seestate sfx_None, // seesound @@ -6095,15 +6072,15 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // attacksound S_NULL, // painstate 0, // painchance - sfx_spring, // painsound + sfx_s3kb1, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 20*FRACUNIT, // radius - 16*FRACUNIT, // height + 48*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset 26*FRACUNIT, // mass 0, // damage @@ -6114,7 +6091,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_REDSPRING 551, // doomednum - S_REDSPRING, // spawnstate + S_REDSPRING1, // spawnstate 1000, // spawnhealth S_REDSPRING2, // seestate sfx_None, // seesound @@ -6122,15 +6099,15 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // attacksound S_NULL, // painstate 0, // painchance - sfx_spring, // painsound + sfx_s3kb1, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 20*FRACUNIT, // radius - 16*FRACUNIT, // height + 48*FRACUNIT, // radius + 32*FRACUNIT, // height 0, // display offset 40*FRACUNIT, // mass 0, // damage @@ -6139,6 +6116,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_REDSPRING2 // raisestate }, + { // MT_BLUESPRING + 552, // doomednum + S_BLUESPRING1, // spawnstate + 1000, // spawnhealth + S_BLUESPRING2, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_s3kb1, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 48*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 14*FRACUNIT, // mass + 0, // damage + sfx_None, // activesound + MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags + S_BLUESPRING2 // raisestate + }, + { // MT_YELLOWDIAG 555, // doomednum S_YDIAG1, // spawnstate @@ -6149,15 +6153,15 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // attacksound S_NULL, // painstate 0, // painchance - sfx_spring, // painsound + sfx_s3kb1, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 16*FRACUNIT, // height + 48*FRACUNIT, // radius + 56*FRACUNIT, // height 0, // display offset 26*FRACUNIT, // mass 26*FRACUNIT, // damage @@ -6176,15 +6180,15 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // attacksound S_NULL, // painstate 0, // painchance - sfx_spring, // painsound + sfx_s3kb1, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed - 16*FRACUNIT, // radius - 16*FRACUNIT, // height + 48*FRACUNIT, // radius + 56*FRACUNIT, // height 0, // display offset 40*FRACUNIT, // mass 40*FRACUNIT, // damage @@ -6193,6 +6197,114 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_RDIAG2 // raisestate }, + { // MT_BLUEDIAG + 557, // doomednum + S_BDIAG1, // spawnstate + 1, // spawnhealth + S_BDIAG2, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_s3kb1, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 48*FRACUNIT, // radius + 56*FRACUNIT, // height + 0, // display offset + 14*FRACUNIT, // mass + 14*FRACUNIT, // damage + sfx_None, // activesound + MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags + S_BDIAG2 // raisestate + }, + + { // MT_YELLOWHORIZ + 558, // doomednum + S_YHORIZ1, // spawnstate + 1, // spawnhealth + S_YHORIZ2, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_s3kb1, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 48*FRACUNIT, // radius + 56*FRACUNIT, // height + 0, // display offset + 0, // mass + 36*FRACUNIT, // damage + sfx_None, // activesound + MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags + S_YHORIZ2 // raisestate + }, + + { // MT_REDHORIZ + 559, // doomednum + S_RHORIZ1, // spawnstate + 1, // spawnhealth + S_RHORIZ2, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_s3kb1, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 48*FRACUNIT, // radius + 56*FRACUNIT, // height + 0, // display offset + 0, // mass + 72*FRACUNIT, // damage + sfx_None, // activesound + MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags + S_RHORIZ2 // raisestate + }, + + { // MT_BLUEHORIZ + 560, // doomednum + S_BHORIZ1, // spawnstate + 1, // spawnhealth + S_BHORIZ2, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_s3kb1, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 48*FRACUNIT, // radius + 56*FRACUNIT, // height + 0, // display offset + 0, // mass + 18*FRACUNIT, // damage + sfx_None, // activesound + MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags + S_BHORIZ2 // raisestate + }, + { // MT_BUBBLES 500, // doomednum S_BUBBLES1, // spawnstate @@ -14811,7 +14923,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // attacksound S_NULL, // painstate 0, // painchance - sfx_spring, // painsound + sfx_s3kb1, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate @@ -14838,7 +14950,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // attacksound S_NULL, // painstate 0, // painchance - sfx_spring, // painsound + sfx_s3kb1, // painsound S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate @@ -14855,33 +14967,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_INVISSPRING // raisestate }, - { // MT_BLUEDIAG - 557, // doomednum - S_BDIAG1, // spawnstate - 1, // spawnhealth - S_BDIAG2, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_spring, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 16*FRACUNIT, // radius - 16*FRACUNIT, // height - 0, // display offset - 14*FRACUNIT, // mass - 14*FRACUNIT, // damage - sfx_None, // activesound - MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags - S_BDIAG2 // raisestate - }, - { // MT_RANDOMITEM 2000, // doomednum S_RANDOMITEM1, // spawnstate diff --git a/src/info.h b/src/info.h index e2a60e131..755b2f76b 100644 --- a/src/info.h +++ b/src/info.h @@ -459,11 +459,15 @@ typedef enum sprite SPR_RBRD, // Red Birdie in Bubble // Springs - SPR_SPRY, // yellow spring - SPR_SPRR, // red spring - SPR_SPRB, // Blue springs - SPR_YSPR, // Yellow Diagonal Spring - SPR_RSPR, // Red Diagonal Spring + SPR_SPVY, // Yellow Vertical Spring + SPR_SPVR, // Red Vertical Spring + SPR_SPVB, // Blue Vertical Spring + SPR_SPDY, // Yellow Diagonal Spring + SPR_SPDR, // Red Diagonal Spring + SPR_SPDB, // Blue Diagonal Spring + SPR_SPHY, // Yellow Horizontal Spring + SPR_SPHR, // Red Horizontal Spring + SPR_SPHB, // Blue Horizontal Spring // Environmental Effects SPR_RAIN, // Rain @@ -588,7 +592,6 @@ typedef enum sprite // Springs SPR_SPRG, // Gray Spring - SPR_BSPR, // Blue Diagonal Spring SPR_RNDM, // Random Item Box SPR_RPOP, // Random Item Box Pop @@ -2491,44 +2494,59 @@ typedef enum state S_RBIRD2, S_RBIRD3, - S_YELLOWSPRING, + // Yellow Spring + S_YELLOWSPRING1, S_YELLOWSPRING2, S_YELLOWSPRING3, S_YELLOWSPRING4, - S_YELLOWSPRING5, - S_REDSPRING, + // Red Spring + S_REDSPRING1, S_REDSPRING2, S_REDSPRING3, S_REDSPRING4, - S_REDSPRING5, - // Blue Springs - S_BLUESPRING, + // Blue Spring + S_BLUESPRING1, S_BLUESPRING2, S_BLUESPRING3, S_BLUESPRING4, - S_BLUESPRING5, // Yellow Diagonal Spring S_YDIAG1, S_YDIAG2, S_YDIAG3, S_YDIAG4, - S_YDIAG5, - S_YDIAG6, - S_YDIAG7, - S_YDIAG8, // Red Diagonal Spring S_RDIAG1, S_RDIAG2, S_RDIAG3, S_RDIAG4, - S_RDIAG5, - S_RDIAG6, - S_RDIAG7, - S_RDIAG8, + + // Blue Diagonal Spring + S_BDIAG1, + S_BDIAG2, + S_BDIAG3, + S_BDIAG4, + + // Yellow Horizontal Spring + S_YHORIZ1, + S_YHORIZ2, + S_YHORIZ3, + S_YHORIZ4, + + // Red Horizontal Spring + S_RHORIZ1, + S_RHORIZ2, + S_RHORIZ3, + S_RHORIZ4, + + // Blue Horizontal Spring + S_BHORIZ1, + S_BHORIZ2, + S_BHORIZ3, + S_BHORIZ4, // Rain S_RAIN1, @@ -3163,16 +3181,6 @@ typedef enum state // Invis-spring - this is used just for the sproing sound. S_INVISSPRING, - // Blue Diagonal Spring - S_BDIAG1, - S_BDIAG2, - S_BDIAG3, - S_BDIAG4, - S_BDIAG5, - S_BDIAG6, - S_BDIAG7, - S_BDIAG8, - //{ Random Item Box S_RANDOMITEM1, S_RANDOMITEM2, @@ -4242,11 +4250,15 @@ typedef enum mobj_type // Springs and others MT_FAN, MT_STEAM, // Steam riser - MT_BLUESPRING, MT_YELLOWSPRING, MT_REDSPRING, + MT_BLUESPRING, MT_YELLOWDIAG, // Yellow Diagonal Spring MT_REDDIAG, // Red Diagonal Spring + MT_BLUEDIAG, // Blue Diagonal Spring + MT_YELLOWHORIZ, // Yellow Horizontal Spring + MT_REDHORIZ, // Red Horizontal Spring + MT_BLUEHORIZ, // Blue Horizontal Spring // Interactive Objects MT_BUBBLES, // Bubble source @@ -4630,7 +4642,6 @@ typedef enum mobj_type // SRB2kart MT_GRAYSPRING, MT_INVISSPRING, - MT_BLUEDIAG, MT_RANDOMITEM, MT_RANDOMITEMPOP, MT_FLOATINGITEM, diff --git a/src/k_kart.c b/src/k_kart.c index c56c7c982..a2f0c5ac9 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5300,17 +5300,6 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) } } - // ??? - /* - if (player->kartstuff[k_jmp] > 1 && onground) - { - S_StartSound(player->mo, sfx_spring); - P_DoJump(player, false); - player->mo->momz *= player->kartstuff[k_jmp]; - player->kartstuff[k_jmp] = 0; - } - */ - if (player->kartstuff[k_comebacktimer]) player->kartstuff[k_comebackmode] = 0; From abfc1915c5460a7d846d04e905c449ea471c1d68 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 12 Sep 2019 00:10:06 -0400 Subject: [PATCH 063/163] Fixed horizontal springs having gravity --- src/info.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/info.c b/src/info.c index c7a826372..0a9c0cced 100644 --- a/src/info.c +++ b/src/info.c @@ -6247,7 +6247,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // mass 36*FRACUNIT, // damage sfx_None, // activesound - MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags + MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_YHORIZ2 // raisestate }, @@ -6274,7 +6274,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // mass 72*FRACUNIT, // damage sfx_None, // activesound - MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags + MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_RHORIZ2 // raisestate }, @@ -6301,7 +6301,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // mass 18*FRACUNIT, // damage sfx_None, // activesound - MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags + MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_BHORIZ2 // raisestate }, From 55caae6d1aee185e8c6b0259043e0967a20eb0c8 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 12 Sep 2019 00:31:51 -0400 Subject: [PATCH 064/163] Remove teleporting jank from springs, set angle when going directly against a horizontal/diagonal spring --- src/p_map.c | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index d99105005..d5b447cf3 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -113,12 +113,13 @@ boolean P_TeleportMove(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z) // MOVEMENT ITERATOR FUNCTIONS // ========================================================================= +//#define TELEPORTJANK + boolean P_DoSpring(mobj_t *spring, mobj_t *object) { //INT32 pflags; const fixed_t hscale = mapobjectscale + (mapobjectscale - object->scale); const fixed_t vscale = mapobjectscale + (object->scale - mapobjectscale); - fixed_t offx, offy; fixed_t vertispeed = spring->info->mass; fixed_t horizspeed = spring->info->damage; @@ -142,11 +143,13 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) object->eflags |= MFE_SPRUNG; // apply this flag asap! spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify +#ifdef TELEPORTJANK if (horizspeed && vertispeed) // Mimic SA { object->momx = object->momy = 0; P_TryMove(object, spring->x, spring->y, true); } +#endif if (spring->eflags & MFE_VERTICALFLIP) vertispeed *= -1; @@ -155,8 +158,11 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) object->z = spring->z + spring->height + 1; else if (vertispeed < 0) object->z = spring->z - object->height - 1; +#ifdef TELEPORTJANK else { + fixed_t offx, offy; + // Horizontal springs teleport you in FRONT of them. object->momx = object->momy = 0; @@ -178,6 +184,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) // Set position! P_TryMove(object, spring->x + offx, spring->y + offy, true); } +#endif if (vertispeed) object->momz = FixedMul(vertispeed,FixedSqrt(FixedMul(vscale, spring->scale))); @@ -208,20 +215,28 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) if (spring->flags & MF_ENEMY) // Spring shells P_SetTarget(&spring->target, object); - if (horizspeed && object->player->cmd.forwardmove == 0 && object->player->cmd.sidemove == 0) + if (horizspeed) { - object->angle = spring->angle; + const angle_t turnabout = ANGLE_90+ANGLE_45; + angle_t dangle = object->angle - spring->angle; + if (dangle > ANGLE_180) + dangle = InvAngle(dangle); - if (!demo.playback || P_AnalogMove(object->player)) + if (dangle > turnabout || (object->player->cmd.forwardmove == 0 && object->player->cmd.sidemove == 0)) { - if (object->player == &players[consoleplayer]) - localangle[0] = spring->angle; - else if (object->player == &players[displayplayers[1]]) - localangle[1] = spring->angle; - else if (object->player == &players[displayplayers[2]]) - localangle[2] = spring->angle; - else if (object->player == &players[displayplayers[3]]) - localangle[3] = spring->angle; + object->angle = spring->angle; + + if (!demo.playback || P_AnalogMove(object->player)) + { + if (object->player == &players[consoleplayer]) + localangle[0] = spring->angle; + else if (object->player == &players[displayplayers[1]]) + localangle[1] = spring->angle; + else if (object->player == &players[displayplayers[2]]) + localangle[2] = spring->angle; + else if (object->player == &players[displayplayers[3]]) + localangle[3] = spring->angle; + } } } From d4d03f907bbf299f591ec3cf13a78cc611c203fc Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 12 Sep 2019 00:32:47 -0400 Subject: [PATCH 065/163] Remove commented out code --- src/p_map.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index d5b447cf3..7487a7907 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -240,28 +240,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) } } - //pflags = object->player->pflags & (PF_JUMPED|PF_SPINNING|PF_THOKKED); // I still need these. P_ResetPlayer(object->player); - - /* // SRB2kart - Springs don't need to change player state in kart. - if (P_MobjFlip(object)*vertispeed > 0) - P_SetPlayerMobjState(object, S_PLAY_SPRING); - else if (P_MobjFlip(object)*vertispeed < 0) - P_SetPlayerMobjState(object, S_PLAY_FALL1); - else // horizontal spring - { - if (pflags & (PF_JUMPED|PF_SPINNING) && object->player->panim == PA_ROLL) - object->player->pflags = pflags; - else - P_SetPlayerMobjState(object, S_PLAY_RUN1); - } - - if (spring->info->painchance) - { - object->player->pflags |= PF_JUMPED; - P_SetPlayerMobjState(object, S_PLAY_ATK1); - } - */ } return true; } From d3f1b4f82c8adad79f450e267a6ac92702ee647a Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 12 Sep 2019 02:01:30 -0400 Subject: [PATCH 066/163] Greased horizontals --- src/d_player.h | 1 + src/dehacked.c | 3 ++- src/doomstat.h | 1 + src/g_game.c | 1 + src/info.c | 6 +++--- src/k_kart.c | 33 ++++++++++++++++++++++----------- src/p_map.c | 36 ++++++++++++++++++++++++------------ 7 files changed, 54 insertions(+), 27 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index d2ed296ce..aced985c8 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -327,6 +327,7 @@ typedef enum k_jawztargetdelay, // Delay for Jawz target switching, to make it less twitchy k_spectatewait, // How long have you been waiting as a spectator k_growcancel, // Hold the item button down to cancel Grow + k_tiregrease, // Reduced friction timer after hitting a horizontal spring NUMKARTSTUFF } kartstufftype_t; diff --git a/src/dehacked.c b/src/dehacked.c index b8f2ecdec..51eb820bb 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -8481,7 +8481,8 @@ static const char *const KARTSTUFF_LIST[] = { "GETSPARKS", "JAWZTARGETDELAY", "SPECTATEWAIT", - "GROWCANCEL" + "GROWCANCEL", + "TIREGREASE" }; #endif diff --git a/src/doomstat.h b/src/doomstat.h index 1f855da27..2299e8e87 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -435,6 +435,7 @@ extern INT32 sneakertime; extern INT32 itemtime; extern INT32 comebacktime; extern INT32 bumptime; +extern INT32 greasetics; extern INT32 wipeoutslowtime; extern INT32 wantedreduce; extern INT32 wantedfrequency; diff --git a/src/g_game.c b/src/g_game.c index e406e29d1..f4711592d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -216,6 +216,7 @@ INT32 sneakertime = TICRATE + (TICRATE/3); INT32 itemtime = 8*TICRATE; INT32 comebacktime = 10*TICRATE; INT32 bumptime = 6; +INT32 greasetics = 2*TICRATE; INT32 wipeoutslowtime = 20; INT32 wantedreduce = 5*TICRATE; INT32 wantedfrequency = 10*TICRATE; diff --git a/src/info.c b/src/info.c index 0a9c0cced..0579bf6d4 100644 --- a/src/info.c +++ b/src/info.c @@ -6245,7 +6245,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 56*FRACUNIT, // height 0, // display offset 0, // mass - 36*FRACUNIT, // damage + 40*FRACUNIT, // damage sfx_None, // activesound MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_YHORIZ2 // raisestate @@ -6272,7 +6272,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 56*FRACUNIT, // height 0, // display offset 0, // mass - 72*FRACUNIT, // damage + 80*FRACUNIT, // damage sfx_None, // activesound MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_RHORIZ2 // raisestate @@ -6299,7 +6299,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 56*FRACUNIT, // height 0, // display offset 0, // mass - 18*FRACUNIT, // damage + 20*FRACUNIT, // damage sfx_None, // activesound MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_BHORIZ2 // raisestate diff --git a/src/k_kart.c b/src/k_kart.c index a2f0c5ac9..79250d9fc 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5260,6 +5260,9 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) if (player->kartstuff[k_justbumped]) player->kartstuff[k_justbumped]--; + if (player->kartstuff[k_tiregrease]) + player->kartstuff[k_tiregrease]--; + // This doesn't go in HUD update because it has potential gameplay ramifications if (player->karthud[khud_itemblink] && player->karthud[khud_itemblink]-- <= 0) { @@ -6479,6 +6482,12 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (onground) { + fixed_t prevfriction = player->mo->friction; + + // Reduce friction after hitting a horizontal spring + if (player->kartstuff[k_tiregrease]) + player->mo->friction += ((FRACUNIT - prevfriction) / greasetics) * player->kartstuff[k_tiregrease]; + // Friction if (!player->kartstuff[k_offroad]) { @@ -6491,9 +6500,20 @@ void K_MoveKartPlayer(player_t *player, boolean onground) // Karma ice physics if (G_BattleGametype() && player->kartstuff[k_bumper] <= 0) - { player->mo->friction += 1228; + // Wipeout slowdown + if (player->kartstuff[k_spinouttimer] && player->kartstuff[k_wipeoutslow]) + { + if (player->kartstuff[k_offroad]) + player->mo->friction -= 4912; + if (player->kartstuff[k_wipeoutslow] == 1) + player->mo->friction -= 9824; + } + + // Friction was changed, so we must recalculate a bunch of stuff + if (player->mo->friction != prevfriction) + { if (player->mo->friction > FRACUNIT) player->mo->friction = FRACUNIT; if (player->mo->friction < 0) @@ -6504,20 +6524,11 @@ void K_MoveKartPlayer(player_t *player, boolean onground) if (player->mo->movefactor < FRACUNIT) player->mo->movefactor = 19*player->mo->movefactor - 18*FRACUNIT; else - player->mo->movefactor = FRACUNIT; //player->mo->movefactor = ((player->mo->friction - 0xDB34)*(0xA))/0x80; + player->mo->movefactor = FRACUNIT; if (player->mo->movefactor < 32) player->mo->movefactor = 32; } - - // Wipeout slowdown - if (player->kartstuff[k_spinouttimer] && player->kartstuff[k_wipeoutslow]) - { - if (player->kartstuff[k_offroad]) - player->mo->friction -= 4912; - if (player->kartstuff[k_wipeoutslow] == 1) - player->mo->friction -= 9824; - } } K_KartDrift(player, onground); diff --git a/src/p_map.c b/src/p_map.c index 7487a7907..fbee5abf0 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -158,7 +158,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) object->z = spring->z + spring->height + 1; else if (vertispeed < 0) object->z = spring->z - object->height - 1; -#ifdef TELEPORTJANK +//#ifdef TELEPORTJANK else { fixed_t offx, offy; @@ -184,26 +184,35 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) // Set position! P_TryMove(object, spring->x + offx, spring->y + offy, true); } -#endif +//#endif if (vertispeed) + { + // Vertical springs object->momz = FixedMul(vertispeed,FixedSqrt(FixedMul(vscale, spring->scale))); - if (horizspeed) - { - if (!object->player) - P_InstaThrustEvenIn2D(object, spring->angle, FixedMul(horizspeed,FixedSqrt(FixedMul(hscale, spring->scale)))); - else + // Diagonal springs + if (horizspeed) { - fixed_t finalSpeed = FixedDiv(horizspeed, hscale); - fixed_t pSpeed = object->player->speed; + if (!object->player) + P_InstaThrustEvenIn2D(object, spring->angle, FixedMul(horizspeed,FixedSqrt(FixedMul(hscale, spring->scale)))); + else + { + fixed_t finalSpeed = FixedDiv(horizspeed, hscale); + fixed_t pSpeed = object->player->speed; - if (pSpeed > finalSpeed) - finalSpeed = pSpeed; + if (pSpeed > finalSpeed) + finalSpeed = pSpeed; - P_InstaThrustEvenIn2D(object, spring->angle, FixedMul(finalSpeed,FixedSqrt(FixedMul(hscale, spring->scale)))); + P_InstaThrustEvenIn2D(object, spring->angle, FixedMul(finalSpeed,FixedSqrt(FixedMul(hscale, spring->scale)))); + } } } + else if (horizspeed) + { + // Horizontal springs + P_Thrust(object, spring->angle, FixedMul(FixedDiv(horizspeed, hscale), FixedSqrt(FixedMul(hscale, spring->scale)))); + } // Re-solidify spring->flags |= (spring->info->flags & (MF_SPECIAL|MF_SOLID)); @@ -238,6 +247,9 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) localangle[3] = spring->angle; } } + + if (!vertispeed) // Less friction when hitting horizontal springs + object->player->kartstuff[k_tiregrease] = greasetics; } P_ResetPlayer(object->player); From 56c9641488a19edc279c0fe439d482d08ff34aee Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 12 Sep 2019 02:18:07 -0400 Subject: [PATCH 067/163] Back to old thrusts --- src/info.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/info.c b/src/info.c index 0579bf6d4..0a9c0cced 100644 --- a/src/info.c +++ b/src/info.c @@ -6245,7 +6245,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 56*FRACUNIT, // height 0, // display offset 0, // mass - 40*FRACUNIT, // damage + 36*FRACUNIT, // damage sfx_None, // activesound MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_YHORIZ2 // raisestate @@ -6272,7 +6272,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 56*FRACUNIT, // height 0, // display offset 0, // mass - 80*FRACUNIT, // damage + 72*FRACUNIT, // damage sfx_None, // activesound MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_RHORIZ2 // raisestate @@ -6299,7 +6299,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 56*FRACUNIT, // height 0, // display offset 0, // mass - 20*FRACUNIT, // damage + 18*FRACUNIT, // damage sfx_None, // activesound MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_BHORIZ2 // raisestate From 97b09ba9c1a736efc92c02b761299001d329b603 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 12 Sep 2019 14:23:45 -0400 Subject: [PATCH 068/163] Grease part 2 --- src/g_game.c | 2 +- src/info.c | 6 +++--- src/p_map.c | 55 ++++++++++++++++++++-------------------------------- 3 files changed, 25 insertions(+), 38 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index f4711592d..e890627aa 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -216,7 +216,7 @@ INT32 sneakertime = TICRATE + (TICRATE/3); INT32 itemtime = 8*TICRATE; INT32 comebacktime = 10*TICRATE; INT32 bumptime = 6; -INT32 greasetics = 2*TICRATE; +INT32 greasetics = 3*TICRATE; INT32 wipeoutslowtime = 20; INT32 wantedreduce = 5*TICRATE; INT32 wantedfrequency = 10*TICRATE; diff --git a/src/info.c b/src/info.c index 0a9c0cced..9e949d24c 100644 --- a/src/info.c +++ b/src/info.c @@ -6245,7 +6245,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 56*FRACUNIT, // height 0, // display offset 0, // mass - 36*FRACUNIT, // damage + 18*FRACUNIT, // damage sfx_None, // activesound MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_YHORIZ2 // raisestate @@ -6272,7 +6272,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 56*FRACUNIT, // height 0, // display offset 0, // mass - 72*FRACUNIT, // damage + 36*FRACUNIT, // damage sfx_None, // activesound MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_RHORIZ2 // raisestate @@ -6299,7 +6299,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 56*FRACUNIT, // height 0, // display offset 0, // mass - 18*FRACUNIT, // damage + 9*FRACUNIT, // damage sfx_None, // activesound MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_BHORIZ2 // raisestate diff --git a/src/p_map.c b/src/p_map.c index fbee5abf0..eb9ff8cc8 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -158,60 +158,50 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) object->z = spring->z + spring->height + 1; else if (vertispeed < 0) object->z = spring->z - object->height - 1; -//#ifdef TELEPORTJANK else { fixed_t offx, offy; - // Horizontal springs teleport you in FRONT of them. - object->momx = object->momy = 0; - // Overestimate the distance to position you at - offx = P_ReturnThrustX(spring, spring->angle, (spring->radius + object->radius + 1) * 2); - offy = P_ReturnThrustY(spring, spring->angle, (spring->radius + object->radius + 1) * 2); - - // Make it square by clipping - if (offx > (spring->radius + object->radius + 1)) - offx = spring->radius + object->radius + 1; - else if (offx < -(spring->radius + object->radius + 1)) - offx = -(spring->radius + object->radius + 1); - - if (offy > (spring->radius + object->radius + 1)) - offy = spring->radius + object->radius + 1; - else if (offy < -(spring->radius + object->radius + 1)) - offy = -(spring->radius + object->radius + 1); + offx = P_ReturnThrustX(spring, spring->angle, spring->radius + object->radius + 1); + offy = P_ReturnThrustY(spring, spring->angle, spring->radius + object->radius + 1); // Set position! P_TryMove(object, spring->x + offx, spring->y + offy, true); } -//#endif if (vertispeed) { // Vertical springs - object->momz = FixedMul(vertispeed,FixedSqrt(FixedMul(vscale, spring->scale))); + object->momz = FixedMul(vertispeed, FixedSqrt(FixedMul(vscale, spring->scale))); // Diagonal springs if (horizspeed) { - if (!object->player) - P_InstaThrustEvenIn2D(object, spring->angle, FixedMul(horizspeed,FixedSqrt(FixedMul(hscale, spring->scale)))); - else + fixed_t finalSpeed = horizspeed; + + if (object->player) { - fixed_t finalSpeed = FixedDiv(horizspeed, hscale); - fixed_t pSpeed = object->player->speed; - - if (pSpeed > finalSpeed) - finalSpeed = pSpeed; - - P_InstaThrustEvenIn2D(object, spring->angle, FixedMul(finalSpeed,FixedSqrt(FixedMul(hscale, spring->scale)))); + if (object->player->speed > finalSpeed) + finalSpeed = object->player->speed; } + + P_InstaThrustEvenIn2D(object, spring->angle, FixedMul(finalSpeed, FixedSqrt(FixedMul(hscale, spring->scale)))); } } else if (horizspeed) { - // Horizontal springs - P_Thrust(object, spring->angle, FixedMul(FixedDiv(horizspeed, hscale), FixedSqrt(FixedMul(hscale, spring->scale)))); + fixed_t finalSpeed = horizspeed; + + if (object->player) + { + finalSpeed += object->player->speed; + // Less friction when hitting horizontal springs + object->player->kartstuff[k_tiregrease] = greasetics; + } + + // Add speed + P_Thrust(object, spring->angle, FixedMul(finalSpeed, FixedSqrt(FixedMul(hscale, spring->scale)))); } // Re-solidify @@ -247,9 +237,6 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) localangle[3] = spring->angle; } } - - if (!vertispeed) // Less friction when hitting horizontal springs - object->player->kartstuff[k_tiregrease] = greasetics; } P_ResetPlayer(object->player); From 40c8081a1ba2d19c7a26ae63cc698369fee42537 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 12 Sep 2019 19:26:00 -0400 Subject: [PATCH 069/163] Grease part 3 --- src/info.c | 6 ++-- src/p_map.c | 84 ++++++++++++++++++++++++++++++----------------------- 2 files changed, 50 insertions(+), 40 deletions(-) diff --git a/src/info.c b/src/info.c index 9e949d24c..a7fad9d76 100644 --- a/src/info.c +++ b/src/info.c @@ -6245,7 +6245,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 56*FRACUNIT, // height 0, // display offset 0, // mass - 18*FRACUNIT, // damage + 48*FRACUNIT, // damage sfx_None, // activesound MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_YHORIZ2 // raisestate @@ -6272,7 +6272,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 56*FRACUNIT, // height 0, // display offset 0, // mass - 36*FRACUNIT, // damage + 72*FRACUNIT, // damage sfx_None, // activesound MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_RHORIZ2 // raisestate @@ -6299,7 +6299,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 56*FRACUNIT, // height 0, // display offset 0, // mass - 9*FRACUNIT, // damage + 24*FRACUNIT, // damage sfx_None, // activesound MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_BHORIZ2 // raisestate diff --git a/src/p_map.c b/src/p_map.c index eb9ff8cc8..9610aa7fb 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -122,6 +122,8 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) const fixed_t vscale = mapobjectscale + (object->scale - mapobjectscale); fixed_t vertispeed = spring->info->mass; fixed_t horizspeed = spring->info->damage; + fixed_t savemomx = 0; + fixed_t savemomy = 0; if (object->eflags & MFE_SPRUNG) // Object was already sprung this tic return false; @@ -154,6 +156,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) if (spring->eflags & MFE_VERTICALFLIP) vertispeed *= -1; + // Vertical springs teleport you on TOP of them. if (vertispeed > 0) object->z = spring->z + spring->height + 1; else if (vertispeed < 0) @@ -162,11 +165,26 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) { fixed_t offx, offy; - // Overestimate the distance to position you at - offx = P_ReturnThrustX(spring, spring->angle, spring->radius + object->radius + 1); - offy = P_ReturnThrustY(spring, spring->angle, spring->radius + object->radius + 1); + // Horizontal springs teleport you in FRONT of them. + savemomx = object->momx; + savemomy = object->momy; + object->momx = object->momy = 0; + + // Overestimate the distance to position you at + offx = P_ReturnThrustX(spring, spring->angle, (spring->radius + object->radius + 1) * 2); + offy = P_ReturnThrustY(spring, spring->angle, (spring->radius + object->radius + 1) * 2); + + // Then clip it down to a square, so it matches the hitbox size. + if (offx > (spring->radius + object->radius + 1)) + offx = spring->radius + object->radius + 1; + else if (offx < -(spring->radius + object->radius + 1)) + offx = -(spring->radius + object->radius + 1); + + if (offy > (spring->radius + object->radius + 1)) + offy = spring->radius + object->radius + 1; + else if (offy < -(spring->radius + object->radius + 1)) + offy = -(spring->radius + object->radius + 1); - // Set position! P_TryMove(object, spring->x + offx, spring->y + offy, true); } @@ -181,27 +199,44 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) fixed_t finalSpeed = horizspeed; if (object->player) - { - if (object->player->speed > finalSpeed) - finalSpeed = object->player->speed; - } + finalSpeed = max(object->player->speed, finalSpeed); // Horizontal speed is a minimum P_InstaThrustEvenIn2D(object, spring->angle, FixedMul(finalSpeed, FixedSqrt(FixedMul(hscale, spring->scale)))); } } else if (horizspeed) { + angle_t reflect = spring->angle; fixed_t finalSpeed = horizspeed; + if (savemomx || savemomy) + { + angle_t momang, diff; + + momang = R_PointToAngle2(0, 0, savemomx, savemomy); + diff = (signed)(momang - spring->angle); + + reflect = (signed)(spring->angle - (diff*2)); + + if ((signed)reflect > (signed)(spring->angle + ANGLE_45)) + reflect = (spring->angle + ANGLE_45); + + if ((signed)reflect < (signed)(spring->angle - ANGLE_45)) + reflect = (spring->angle - ANGLE_45); + } + + // Scale to gamespeed + finalSpeed = FixedMul(finalSpeed, K_GetKartGameSpeedScalar(gamespeed)); + if (object->player) { - finalSpeed += object->player->speed; + // Horizontal speed is a minimum + finalSpeed = max(object->player->speed, finalSpeed); // Less friction when hitting horizontal springs - object->player->kartstuff[k_tiregrease] = greasetics; + object->player->kartstuff[k_tiregrease] = greasetics; //FixedMul(greasetics << FRACBITS, finalSpeed/72) >> FRACBITS } - // Add speed - P_Thrust(object, spring->angle, FixedMul(finalSpeed, FixedSqrt(FixedMul(hscale, spring->scale)))); + P_InstaThrustEvenIn2D(object, reflect, FixedMul(finalSpeed, FixedSqrt(FixedMul(hscale, spring->scale)))); } // Re-solidify @@ -214,31 +249,6 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) if (spring->flags & MF_ENEMY) // Spring shells P_SetTarget(&spring->target, object); - if (horizspeed) - { - const angle_t turnabout = ANGLE_90+ANGLE_45; - angle_t dangle = object->angle - spring->angle; - if (dangle > ANGLE_180) - dangle = InvAngle(dangle); - - if (dangle > turnabout || (object->player->cmd.forwardmove == 0 && object->player->cmd.sidemove == 0)) - { - object->angle = spring->angle; - - if (!demo.playback || P_AnalogMove(object->player)) - { - if (object->player == &players[consoleplayer]) - localangle[0] = spring->angle; - else if (object->player == &players[displayplayers[1]]) - localangle[1] = spring->angle; - else if (object->player == &players[displayplayers[2]]) - localangle[2] = spring->angle; - else if (object->player == &players[displayplayers[3]]) - localangle[3] = spring->angle; - } - } - } - P_ResetPlayer(object->player); } return true; From 0e35b65caaaebd5cd7a86f3a9c3a53d62b209990 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 14 Sep 2019 23:47:08 -0400 Subject: [PATCH 070/163] Spring Bullshit, part (?) Who knows how many times I've had to rewrite this part but it FINALLY works properly for everything... --- src/p_map.c | 58 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 9610aa7fb..b934fe8e7 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -189,40 +189,45 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) } if (vertispeed) - { - // Vertical springs object->momz = FixedMul(vertispeed, FixedSqrt(FixedMul(vscale, spring->scale))); - // Diagonal springs - if (horizspeed) - { - fixed_t finalSpeed = horizspeed; - - if (object->player) - finalSpeed = max(object->player->speed, finalSpeed); // Horizontal speed is a minimum - - P_InstaThrustEvenIn2D(object, spring->angle, FixedMul(finalSpeed, FixedSqrt(FixedMul(hscale, spring->scale)))); - } - } - else if (horizspeed) + if (horizspeed) { - angle_t reflect = spring->angle; + angle_t finalAngle = spring->angle; fixed_t finalSpeed = horizspeed; - if (savemomx || savemomy) + // Reflect your momentum angle against the surface of horizontal springs. + // This makes it a bit more interesting & unique than just being a speed boost in a pre-defined direction + if ((!vertispeed) && (savemomx || savemomy)) { - angle_t momang, diff; + angle_t momang; + INT32 angoffset; + boolean subtract = false; momang = R_PointToAngle2(0, 0, savemomx, savemomy); - diff = (signed)(momang - spring->angle); - reflect = (signed)(spring->angle - (diff*2)); + angoffset = momang; + angoffset -= spring->angle; // Subtract - if ((signed)reflect > (signed)(spring->angle + ANGLE_45)) - reflect = (spring->angle + ANGLE_45); + // Flip on wrong side + if ((angle_t)angoffset > ANGLE_180) + { + angoffset = InvAngle((angle_t)angoffset); + subtract = !subtract; + } - if ((signed)reflect < (signed)(spring->angle - ANGLE_45)) - reflect = (spring->angle - ANGLE_45); + // Fix going directly against the spring's angle sending you the wrong way + if ((spring->angle - momang) > ANGLE_90) + angoffset = ANGLE_180 - angoffset; + + angoffset /= 4; // Reduce amount so it feels more natural + + if (subtract) + angoffset = (signed)(spring->angle) - angoffset; + else + angoffset = (signed)(spring->angle) + angoffset; + + finalAngle = angoffset; } // Scale to gamespeed @@ -232,11 +237,13 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) { // Horizontal speed is a minimum finalSpeed = max(object->player->speed, finalSpeed); + // Less friction when hitting horizontal springs - object->player->kartstuff[k_tiregrease] = greasetics; //FixedMul(greasetics << FRACBITS, finalSpeed/72) >> FRACBITS + if (!vertispeed) + object->player->kartstuff[k_tiregrease] = greasetics; //FixedMul(greasetics << FRACBITS, finalSpeed/72) >> FRACBITS } - P_InstaThrustEvenIn2D(object, reflect, FixedMul(finalSpeed, FixedSqrt(FixedMul(hscale, spring->scale)))); + P_InstaThrustEvenIn2D(object, finalAngle, FixedMul(finalSpeed, FixedSqrt(FixedMul(hscale, spring->scale)))); } // Re-solidify @@ -251,6 +258,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) P_ResetPlayer(object->player); } + return true; } From 004bae45c5cd6e800eb0ea94c67bf9c158f9dc74 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 15 Sep 2019 00:27:28 -0400 Subject: [PATCH 071/163] Buff drift-steering during the grease period --- src/k_kart.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 0555504af..5f3b778fa 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5435,15 +5435,16 @@ static INT16 K_GetKartDriftValue(player_t *player, fixed_t countersteer) return 0; if (player->kartstuff[k_driftend] != 0) - { return -266*player->kartstuff[k_drift]; // Drift has ended and we are tweaking their angle back a bit - } //basedrift = 90*player->kartstuff[k_drift]; // 450 //basedrift = 93*player->kartstuff[k_drift] - driftweight*3*player->kartstuff[k_drift]/10; // 447 - 303 basedrift = 83*player->kartstuff[k_drift] - (driftweight - 14)*player->kartstuff[k_drift]/5; // 415 - 303 driftangle = abs((252 - driftweight)*player->kartstuff[k_drift]/5); + if (player->kartstuff[k_tiregrease] > 0) // Buff drift-steering while in greasemode + turnvalue += (turnvalue / greasetics) * player->kartstuff[k_tiregrease]; + return basedrift + FixedMul(driftangle, countersteer); } From 16bd11f53f90a993983b3e58ea421792e17bd24f Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 15 Sep 2019 00:32:58 -0400 Subject: [PATCH 072/163] Wrong var name --- 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 5f3b778fa..b3848837f 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5443,7 +5443,7 @@ static INT16 K_GetKartDriftValue(player_t *player, fixed_t countersteer) driftangle = abs((252 - driftweight)*player->kartstuff[k_drift]/5); if (player->kartstuff[k_tiregrease] > 0) // Buff drift-steering while in greasemode - turnvalue += (turnvalue / greasetics) * player->kartstuff[k_tiregrease]; + basedrift += (basedrift / greasetics) * player->kartstuff[k_tiregrease]; return basedrift + FixedMul(driftangle, countersteer); } From 57380711000e7c5836c2f9d93bab420c24108eef Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 15 Sep 2019 00:49:10 -0400 Subject: [PATCH 073/163] Horizontal/diagonal springs use all object's speed, instead of only players --- src/p_map.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index b934fe8e7..2aaa9df63 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -195,6 +195,12 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) { angle_t finalAngle = spring->angle; fixed_t finalSpeed = horizspeed; + fixed_t objectSpeed; + + if (object->player) + objectSpeed = object->player->speed; + else + objectSpeed = R_PointToDist2(0, 0, savemomx, savemomy); // Reflect your momentum angle against the surface of horizontal springs. // This makes it a bit more interesting & unique than just being a speed boost in a pre-defined direction @@ -220,7 +226,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) if ((spring->angle - momang) > ANGLE_90) angoffset = ANGLE_180 - angoffset; - angoffset /= 4; // Reduce amount so it feels more natural + angoffset /= 6; // Reduce amount so it feels more natural if (subtract) angoffset = (signed)(spring->angle) - angoffset; @@ -232,12 +238,11 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) // Scale to gamespeed finalSpeed = FixedMul(finalSpeed, K_GetKartGameSpeedScalar(gamespeed)); + // Horizontal speed is used as a minimum thrust, not a direct replacement + finalSpeed = max(objectSpeed, finalSpeed); if (object->player) { - // Horizontal speed is a minimum - finalSpeed = max(object->player->speed, finalSpeed); - // Less friction when hitting horizontal springs if (!vertispeed) object->player->kartstuff[k_tiregrease] = greasetics; //FixedMul(greasetics << FRACBITS, finalSpeed/72) >> FRACBITS From 26e34a1fa15849f2512beb083b39b0a374005f2e Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 16 Sep 2019 03:04:26 -0400 Subject: [PATCH 074/163] Use maps.pk3 --- assets/CMakeLists.txt | 2 +- src/config.h.in | 4 ++-- src/d_main.c | 14 +++++++++++--- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/assets/CMakeLists.txt b/assets/CMakeLists.txt index 89be796ad..e5cfa5ca2 100644 --- a/assets/CMakeLists.txt +++ b/assets/CMakeLists.txt @@ -17,7 +17,7 @@ set(SRB2_ASSET_HASHED gfx.pk3;\ textures.pk3;\ chars.pk3;\ -maps.wad;\ +maps.pk3;\ patch.pk3" CACHE STRING "Asset filenames to apply MD5 checks. No spaces between entries!" ) diff --git a/src/config.h.in b/src/config.h.in index 4bf84ff1d..964207e34 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -15,7 +15,7 @@ #define ASSET_HASH_GFX_PK3 "${SRB2_ASSET_gfx.pk3_HASH}" #define ASSET_HASH_TEXTURES_PK3 "${SRB2_ASSET_textures.pk3_HASH}" #define ASSET_HASH_CHARS_PK3 "${SRB2_ASSET_chars.pk3_HASH}" -#define ASSET_HASH_MAPS_WAD "${SRB2_ASSET_maps.wad_HASH}" +#define ASSET_HASH_MAPS_PK3 "${SRB2_ASSET_maps.pk3_HASH}" #ifdef USE_PATCH_FILE #define ASSET_HASH_PATCH_PK3 "${SRB2_ASSET_patch.pk3_HASH}" #endif @@ -36,7 +36,7 @@ #define ASSET_HASH_GFX_PK3 "00000000000000000000000000000000" #define ASSET_HASH_TEXTURES_PK3 "00000000000000000000000000000000" #define ASSET_HASH_CHARS_PK3 "00000000000000000000000000000000" -#define ASSET_HASH_MAPS_WAD "00000000000000000000000000000000" +#define ASSET_HASH_MAPS_PK3 "00000000000000000000000000000000" #ifdef USE_PATCH_FILE #define ASSET_HASH_PATCH_PK3 "00000000000000000000000000000000" #endif diff --git a/src/d_main.c b/src/d_main.c index 1404a5e61..5c8e34bde 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -896,11 +896,18 @@ static void IdentifyVersion(void) D_AddFile(va(pandf,srb2waddir,"gfx.pk3"), startupwadfiles); D_AddFile(va(pandf,srb2waddir,"textures.pk3"), startupwadfiles); D_AddFile(va(pandf,srb2waddir,"chars.pk3"), startupwadfiles); - D_AddFile(va(pandf,srb2waddir,"maps.wad"), startupwadfiles); // TODO: make this a pk3 too! + D_AddFile(va(pandf,srb2waddir,"maps.pk3"), startupwadfiles); #ifdef USE_PATCH_FILE D_AddFile(va(pandf,srb2waddir,"patch.pk3"), startupwadfiles); #endif +#if 0 + // TODO: pk3 doesn't support music replacement IIRC + // music barely benefits from the compression anyway + // would be nice for the folders, though + D_AddFile(va(pandf,srb2waddir,"sounds.pk3"), startupwadfiles); + D_AddFile(va(pandf,srb2waddir,"music.pk3"), startupwadfiles); +#else #if !defined (HAVE_SDL) || defined (HAVE_MIXER) #define MUSICTEST(str) \ {\ @@ -915,6 +922,7 @@ static void IdentifyVersion(void) MUSICTEST("music.wad") #undef MUSICTEST #endif +#endif } /* ======================================================================== */ @@ -1200,7 +1208,7 @@ void D_SRB2Main(void) mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_GFX_PK3); // gfx.pk3 mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_TEXTURES_PK3); // textures.pk3 mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_CHARS_PK3); // chars.pk3 - mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_MAPS_WAD); // maps.wad -- 4 - If you touch this, make sure to touch up the majormods stuff below. + mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_MAPS_PK3); // maps.pk3 -- 4 - If you touch this, make sure to touch up the majormods stuff below. #ifdef USE_PATCH_FILE mainwads++; W_VerifyFileMD5(mainwads, ASSET_HASH_PATCH_PK3); // patch.pk3 #endif @@ -1208,7 +1216,7 @@ void D_SRB2Main(void) mainwads++; // gfx.pk3 mainwads++; // textures.pk3 mainwads++; // chars.pk3 - mainwads++; // maps.wad + mainwads++; // maps.pk3 #ifdef USE_PATCH_FILE mainwads++; // patch.pk3 #endif From 22ccce6f24e84c897b4c68905bf58634bd276562 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 16 Sep 2019 20:47:13 -0400 Subject: [PATCH 075/163] Modify angle offset with your speed vs the spring's speed Blue springs will send you more at a reflected momentum angle, while red springs will send you more straight --- src/p_map.c | 75 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 33 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index 2aaa9df63..22c6755e7 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -202,45 +202,51 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) else objectSpeed = R_PointToDist2(0, 0, savemomx, savemomy); - // Reflect your momentum angle against the surface of horizontal springs. - // This makes it a bit more interesting & unique than just being a speed boost in a pre-defined direction - if ((!vertispeed) && (savemomx || savemomy)) + if (!vertispeed) { - angle_t momang; - INT32 angoffset; - boolean subtract = false; + // Scale to gamespeed + finalSpeed = FixedMul(finalSpeed, K_GetKartGameSpeedScalar(gamespeed)); - momang = R_PointToAngle2(0, 0, savemomx, savemomy); - - angoffset = momang; - angoffset -= spring->angle; // Subtract - - // Flip on wrong side - if ((angle_t)angoffset > ANGLE_180) + // Reflect your momentum angle against the surface of horizontal springs. + // This makes it a bit more interesting & unique than just being a speed boost in a pre-defined direction + if (savemomx || savemomy) { - angoffset = InvAngle((angle_t)angoffset); - subtract = !subtract; + angle_t momang; + INT32 angoffset; + boolean subtract = false; + + momang = R_PointToAngle2(0, 0, savemomx, savemomy); + + angoffset = momang; + angoffset -= spring->angle; // Subtract + + // Flip on wrong side + if ((angle_t)angoffset > ANGLE_180) + { + angoffset = InvAngle((angle_t)angoffset); + subtract = !subtract; + } + + // Fix going directly against the spring's angle sending you the wrong way + if ((spring->angle - momang) > ANGLE_90) + angoffset = ANGLE_180 - angoffset; + + // Offset is reduced to cap it (90 / 2 = max of 45 degrees) + angoffset /= 2; + + // Reduce further based on how slow your speed is compared to the spring's speed + if (finalSpeed > objectSpeed) + angoffset = FixedDiv(angoffset, FixedDiv(finalSpeed, objectSpeed)); + + if (subtract) + angoffset = (signed)(spring->angle) - angoffset; + else + angoffset = (signed)(spring->angle) + angoffset; + + finalAngle = angoffset; } - - // Fix going directly against the spring's angle sending you the wrong way - if ((spring->angle - momang) > ANGLE_90) - angoffset = ANGLE_180 - angoffset; - - angoffset /= 6; // Reduce amount so it feels more natural - - if (subtract) - angoffset = (signed)(spring->angle) - angoffset; - else - angoffset = (signed)(spring->angle) + angoffset; - - finalAngle = angoffset; } - // Scale to gamespeed - finalSpeed = FixedMul(finalSpeed, K_GetKartGameSpeedScalar(gamespeed)); - // Horizontal speed is used as a minimum thrust, not a direct replacement - finalSpeed = max(objectSpeed, finalSpeed); - if (object->player) { // Less friction when hitting horizontal springs @@ -248,6 +254,9 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) object->player->kartstuff[k_tiregrease] = greasetics; //FixedMul(greasetics << FRACBITS, finalSpeed/72) >> FRACBITS } + // Horizontal speed is used as a minimum thrust, not a direct replacement + finalSpeed = max(objectSpeed, finalSpeed); + P_InstaThrustEvenIn2D(object, finalAngle, FixedMul(finalSpeed, FixedSqrt(FixedMul(hscale, spring->scale)))); } From 5023abd279e1b745856f56288524b3cfaadca7f5 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Wed, 18 Sep 2019 02:26:14 -0400 Subject: [PATCH 076/163] Blue springs are Chaotix strong, grey springs are stronger & have diagonal/horizontal types, spring doomednums are reorganized --- src/dehacked.c | 33 ++++--- src/info.c | 237 ++++++++++++++++++++++++++++--------------------- src/info.h | 38 +++++--- 3 files changed, 182 insertions(+), 126 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 51eb820bb..616a81ee9 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -5627,6 +5627,12 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_BLUESPRING3", "S_BLUESPRING4", + // Grey Spring + "S_GREYSPRING1", + "S_GREYSPRING2", + "S_GREYSPRING3", + "S_GREYSPRING4", + // Yellow Diagonal Spring "S_YDIAG1", "S_YDIAG2", @@ -5645,6 +5651,12 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_BDIAG3", "S_BDIAG4", + // Grey Diagonal Spring + "S_GDIAG1", + "S_GDIAG2", + "S_GDIAG3", + "S_GDIAG4", + // Yellow Horizontal Spring "S_YHORIZ1", "S_YHORIZ2", @@ -5663,6 +5675,12 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_BHORIZ3", "S_BHORIZ4", + // Grey Horizontal Spring + "S_GHORIZ1", + "S_GHORIZ2", + "S_GHORIZ3", + "S_GHORIZ4", + // Rain "S_RAIN1", "S_RAINRETURN", @@ -6286,16 +6304,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_SRB1_GENREX1", "S_SRB1_GENREX2", - // Gray Springs - "S_GRAYSPRING", - "S_GRAYSPRING2", - "S_GRAYSPRING3", - "S_GRAYSPRING4", - "S_GRAYSPRING5", - - // Invis-spring - this is used just for the sproing sound. - "S_INVISSPRING", - //{ Random Item Box "S_RANDOMITEM1", "S_RANDOMITEM2", @@ -7336,12 +7344,15 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_YELLOWSPRING", "MT_REDSPRING", "MT_BLUESPRING", + "MT_GREYSPRING", "MT_YELLOWDIAG", // Yellow Diagonal Spring "MT_REDDIAG", // Red Diagonal Spring "MT_BLUEDIAG", // Blue Diagonal Spring + "MT_GREYDIAG", // Grey Diagonal Spring "MT_YELLOWHORIZ", // Yellow Horizontal Spring "MT_REDHORIZ", // Red Horizontal Spring "MT_BLUEHORIZ", // Blue Horizontal Spring + "MT_GREYHORIZ", // Grey Horizontal Spring // Interactive Objects "MT_BUBBLES", // Bubble source @@ -7723,8 +7734,6 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_SRB1_GENREX", // SRB2kart - "MT_GRAYSPRING", - "MT_INVISSPRING", "MT_RANDOMITEM", "MT_RANDOMITEMPOP", "MT_FLOATINGITEM", diff --git a/src/info.c b/src/info.c index a7fad9d76..274cee440 100644 --- a/src/info.c +++ b/src/info.c @@ -43,33 +43,34 @@ char sprnames[NUMSPRITES + 1][5] = "DFLM","XMS1","XMS2","XMS3","BSZ1","BSZ2","BSZ3","BSZ4","BSZ5","BSZ6", "BSZ7","BSZ8","STLG","DBAL","RCRY","ARMA","ARMF","ARMB","WIND","MAGN", "ELEM","FORC","PITY","IVSP","SSPK","GOAL","BIRD","BUNY","MOUS","CHIC", - "COWZ","RBRD","SPVY","SPVR","SPVB","SPDY","SPDR","SPDB","SPHY","SPHR", - "SPHB","RAIN","SNO1","SPLH","SPLA","SMOK","BUBP","BUBO","BUBN","BUBM", - "POPP","TFOG","SEED","PRTL","SCOR","DRWN","TTAG","GFLG","RRNG","RNGB", - "RNGR","RNGI","RNGA","RNGE","RNGS","RNGG","PIKB","PIKR","PIKA","PIKE", - "PIKS","PIKG","TAUT","TGRE","TSCR","COIN","CPRK","GOOM","BGOM","FFWR", - "FBLL","SHLL","PUMA","HAMM","KOOP","BFLM","MAXE","MUS1","MUS2","TOAD", - "NDRN","SUPE","SUPZ","NDRL","NSPK","NBMP","HOOP","NSCR","NPRU","CAPS", - "SUPT","SPRK","BOM1","BOM2","BOM3","BOM4","ROIA","ROIB","ROIC","ROID", - "ROIE","ROIF","ROIG","ROIH","ROII","ROIJ","ROIK","ROIL","ROIM","ROIN", - "ROIO","ROIP","BBAL","GWLG","GWLR","SRBA","SRBB","SRBC","SRBD","SRBE", - "SRBF","SRBG","SRBH","SRBI","SRBJ","SRBK","SRBL","SRBM","SRBN","SRBO", + "COWZ","RBRD","SPVY","SPVR","SPVB","SPVG","SPDY","SPDR","SPDB","SPDG", + "SPHY","SPHR","SPHB","SPHG","RAIN","SNO1","SPLH","SPLA","SMOK","BUBP", + "BUBO","BUBN","BUBM","POPP","TFOG","SEED","PRTL","SCOR","DRWN","TTAG", + "GFLG","RRNG","RNGB","RNGR","RNGI","RNGA","RNGE","RNGS","RNGG","PIKB", + "PIKR","PIKA","PIKE","PIKS","PIKG","TAUT","TGRE","TSCR","COIN","CPRK", + "GOOM","BGOM","FFWR","FBLL","SHLL","PUMA","HAMM","KOOP","BFLM","MAXE", + "MUS1","MUS2","TOAD","NDRN","SUPE","SUPZ","NDRL","NSPK","NBMP","HOOP", + "NSCR","NPRU","CAPS","SUPT","SPRK","BOM1","BOM2","BOM3","BOM4","ROIA", + "ROIB","ROIC","ROID","ROIE","ROIF","ROIG","ROIH","ROII","ROIJ","ROIK", + "ROIL","ROIM","ROIN","ROIO","ROIP","BBAL","GWLG","GWLR","SRBA","SRBB", + "SRBC","SRBD","SRBE","SRBF","SRBG","SRBH","SRBI","SRBJ","SRBK","SRBL", + "SRBM","SRBN","SRBO", //SRB2kart Sprites - "SPRG","RNDM","RPOP","SGNS","FAST","DSHR","BOST","BOSM","KFRE","KINV", - "KINF","WIPD","DRIF","BDRF","DUST","RSHE","FITM","BANA","ORBN","JAWZ", - "SSMN","KRBM","BHOG","BHBM","SPBM","THNS","SINK","SITR","KBLN","DEZL", - "POKE","AUDI","DECO","DOOD","SNES","GBAS","SPRS","BUZB","CHOM","SACO", - "CRAB","SHAD","BRNG","BUMP","FLEN","CLAS","PSHW","ISTA","ISTB","ARRO", - "ITEM","ITMO","ITMI","ITMN","WANT","PBOM","HIT1","HIT2","HIT3","RETI", - "AIDU","KSPK","LZI1","LZI2","KLIT","FZSM","FZBM","FPRT","SBUS","MARB", - "FUFO","RUST","BLON","VAPE","HTZA","HTZB","SGVA","SGVB","SGVC","PGTR", - "PGF1","PGF2","PGF3","PGBH","DPLR","SPTL","ENM1","GARU","MARR","REAP", - "JITB","CDMO","CDBU","PINE","PPLR","DPPT","AATR","COCO","BDST","FROG", - "CBRA","HOLE","BBRA","EGFG","SMKP","MTYM","THWP","SNOB","ICEB","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","MXCL", - "RGSP","DRAF","XMS4","XMS5","VIEW" + "RNDM","RPOP","SGNS","FAST","DSHR","BOST","BOSM","KFRE","KINV","KINF", + "WIPD","DRIF","BDRF","DUST","RSHE","FITM","BANA","ORBN","JAWZ","SSMN", + "KRBM","BHOG","BHBM","SPBM","THNS","SINK","SITR","KBLN","DEZL","POKE", + "AUDI","DECO","DOOD","SNES","GBAS","SPRS","BUZB","CHOM","SACO","CRAB", + "SHAD","BRNG","BUMP","FLEN","CLAS","PSHW","ISTA","ISTB","ARRO","ITEM", + "ITMO","ITMI","ITMN","WANT","PBOM","HIT1","HIT2","HIT3","RETI","AIDU", + "KSPK","LZI1","LZI2","KLIT","FZSM","FZBM","FPRT","SBUS","MARB","FUFO", + "RUST","BLON","VAPE","HTZA","HTZB","SGVA","SGVB","SGVC","PGTR","PGF1", + "PGF2","PGF3","PGBH","DPLR","SPTL","ENM1","GARU","MARR","REAP","JITB", + "CDMO","CDBU","PINE","PPLR","DPPT","AATR","COCO","BDST","FROG","CBRA", + "HOLE","BBRA","EGFG","SMKP","MTYM","THWP","SNOB","ICEB","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","MXCL","RGSP", + "DRAF","XMS4","XMS5","VIEW" }; // Doesn't work with g++, needs actionf_p1 (don't modify this comment) @@ -1812,6 +1813,12 @@ state_t states[NUMSTATES] = {SPR_SPVB, 0, 1, {NULL}, 0, 0, S_BLUESPRING4}, // S_BLUESPRING3 {SPR_SPVB, 2, 4, {NULL}, 0, 0, S_BLUESPRING1}, // S_BLUESPRING4 + // Grey Spring + {SPR_SPVG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_GREYSPRING1 + {SPR_SPVG, 1, 1, {A_Pain}, 0, 0, S_GREYSPRING3}, // S_GREYSPRING2 + {SPR_SPVG, 0, 1, {NULL}, 0, 0, S_GREYSPRING4}, // S_GREYSPRING3 + {SPR_SPVG, 2, 4, {NULL}, 0, 0, S_GREYSPRING1}, // S_GREYSPRING4 + // Yellow Diagonal Spring {SPR_SPDY, 0, -1, {NULL}, 0, 0, S_NULL}, // S_YDIAG1 {SPR_SPDY, 1, 1, {A_Pain}, 0, 0, S_YDIAG3}, // S_YDIAG2 @@ -1830,6 +1837,12 @@ state_t states[NUMSTATES] = {SPR_SPDB, 0, 1, {NULL}, 0, 0, S_BDIAG4}, // S_BDIAG3 {SPR_SPDB, 2, 4, {NULL}, 0, 0, S_BDIAG1}, // S_BDIAG4 + // Grey Diagonal Spring + {SPR_SPDG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_GDIAG1 + {SPR_SPDG, 1, 1, {A_Pain}, 0, 0, S_GDIAG3}, // S_GDIAG2 + {SPR_SPDG, 0, 1, {NULL}, 0, 0, S_GDIAG4}, // S_GDIAG3 + {SPR_SPDG, 2, 4, {NULL}, 0, 0, S_GDIAG1}, // S_GDIAG4 + // Yellow Horizontal Spring {SPR_SPHY, 0, -1, {NULL}, 0, 0, S_NULL}, // S_YHORIZ1 {SPR_SPHY, 1, 1, {A_Pain}, 0, 0, S_YHORIZ3}, // S_YHORIZ2 @@ -1848,6 +1861,12 @@ state_t states[NUMSTATES] = {SPR_SPHB, 0, 1, {NULL}, 0, 0, S_BHORIZ4}, // S_BHORIZ3 {SPR_SPHB, 2, 4, {NULL}, 0, 0, S_BHORIZ1}, // S_BHORIZ4 + // Grey Horizontal Spring + {SPR_SPHG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_GHORIZ1 + {SPR_SPHG, 1, 1, {A_Pain}, 0, 0, S_GHORIZ3}, // S_GHORIZ2 + {SPR_SPHG, 0, 1, {NULL}, 0, 0, S_GHORIZ4}, // S_GHORIZ3 + {SPR_SPHG, 2, 4, {NULL}, 0, 0, S_GHORIZ1}, // S_GHORIZ4 + // Rain {SPR_RAIN, FF_TRANS50, -1, {NULL}, 0, 0, S_NULL}, // S_RAIN1 {SPR_RAIN, FF_TRANS50, 1, {NULL}, 0, 0, S_RAIN1}, // S_RAINRETURN @@ -2525,14 +2544,6 @@ state_t states[NUMSTATES] = {SPR_SRBO, 0, 2, {A_BuzzFly}, 0, 0, S_SRB1_GENREX2}, // S_SRB1_GENREX2 // SRB2kart - {SPR_SPRG, 0, -1, {NULL}, 0, 0, S_NULL}, // S_GRAYSPRING - {SPR_SPRG, 4, 4, {A_Pain}, 0, 0, S_GRAYSPRING3}, // S_GRAYSPRING2 - {SPR_SPRG, 3, 1, {NULL}, 0, 0, S_GRAYSPRING4}, // S_GRAYSPRING3 - {SPR_SPRG, 2, 1, {NULL}, 0, 0, S_GRAYSPRING5}, // S_GRAYSPRING4 - {SPR_SPRG, 1, 1, {NULL}, 0, 0, S_GRAYSPRING}, // S_GRAYSPRING5 - - {SPR_NULL, 0, 1, {A_Pain}, 0, 0, S_INVISIBLE}, // S_INVISSPRING - {SPR_RNDM, 0|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM2}, // S_RANDOMITEM1 {SPR_RNDM, 1|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM3}, // S_RANDOMITEM2 {SPR_RNDM, 2|FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_RANDOMITEM4}, // S_RANDOMITEM3 @@ -6082,7 +6093,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 48*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset - 26*FRACUNIT, // mass + 25*FRACUNIT, // mass 0, // damage sfx_None, // activesound MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags @@ -6136,15 +6147,42 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 48*FRACUNIT, // radius 32*FRACUNIT, // height 0, // display offset - 14*FRACUNIT, // mass + 64*FRACUNIT, // mass 0, // damage sfx_None, // activesound MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags S_BLUESPRING2 // raisestate }, + { // MT_GREYSPRING + 553, // doomednum + S_GREYSPRING1, // spawnstate + 1000, // spawnhealth + S_GREYSPRING2, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_s3kb1, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 48*FRACUNIT, // radius + 32*FRACUNIT, // height + 0, // display offset + 15*FRACUNIT, // mass + 0, // damage + sfx_None, // activesound + MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags + S_GREYSPRING2 // raisestate + }, + { // MT_YELLOWDIAG - 555, // doomednum + 554, // doomednum S_YDIAG1, // spawnstate 1, // spawnhealth S_YDIAG2, // seestate @@ -6163,15 +6201,15 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 48*FRACUNIT, // radius 56*FRACUNIT, // height 0, // display offset - 26*FRACUNIT, // mass - 26*FRACUNIT, // damage + 25*FRACUNIT, // mass + 25*FRACUNIT, // damage sfx_None, // activesound MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags S_YDIAG2 // raisestate }, { // MT_REDDIAG - 556, // doomednum + 555, // doomednum S_RDIAG1, // spawnstate 1, // spawnhealth S_RDIAG2, // seestate @@ -6198,7 +6236,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, { // MT_BLUEDIAG - 557, // doomednum + 556, // doomednum S_BDIAG1, // spawnstate 1, // spawnhealth S_BDIAG2, // seestate @@ -6217,13 +6255,40 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 48*FRACUNIT, // radius 56*FRACUNIT, // height 0, // display offset - 14*FRACUNIT, // mass - 14*FRACUNIT, // damage + 64*FRACUNIT, // mass + 64*FRACUNIT, // damage sfx_None, // activesound MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags S_BDIAG2 // raisestate }, + { // MT_GREYDIAG + 557, // doomednum + S_GDIAG1, // spawnstate + 1, // spawnhealth + S_GDIAG2, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_s3kb1, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 48*FRACUNIT, // radius + 56*FRACUNIT, // height + 0, // display offset + 15*FRACUNIT, // mass + 15*FRACUNIT, // damage + sfx_None, // activesound + MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags + S_GDIAG2 // raisestate + }, + { // MT_YELLOWHORIZ 558, // doomednum S_YHORIZ1, // spawnstate @@ -6245,7 +6310,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 56*FRACUNIT, // height 0, // display offset 0, // mass - 48*FRACUNIT, // damage + 45*FRACUNIT, // damage sfx_None, // activesound MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_YHORIZ2 // raisestate @@ -6299,12 +6364,39 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 56*FRACUNIT, // height 0, // display offset 0, // mass - 24*FRACUNIT, // damage + 115*FRACUNIT, // damage sfx_None, // activesound MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags S_BHORIZ2 // raisestate }, + { // MT_GREYHORIZ + 561, // doomednum + S_GHORIZ1, // spawnstate + 1, // spawnhealth + S_GHORIZ2, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_s3kb1, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 48*FRACUNIT, // radius + 56*FRACUNIT, // height + 0, // display offset + 0, // mass + 27*FRACUNIT, // damage + sfx_None, // activesound + MF_SOLID|MF_SPRING|MF_NOGRAVITY|MF_DONTENCOREMAP, // flags + S_GHORIZ2 // raisestate + }, + { // MT_BUBBLES 500, // doomednum S_BUBBLES1, // spawnstate @@ -14912,61 +15004,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = }, // SRB2kart MT's - - { // MT_GRAYSPRING - 553, // doomednum - S_GRAYSPRING, // spawnstate - 100, // spawnhealth - S_GRAYSPRING2, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_s3kb1, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 20*FRACUNIT, // radius - 16*FRACUNIT, // height - 0, // display offset - 6*FRACUNIT, // mass - 0, // damage - sfx_None, // activesound - MF_SOLID|MF_SPRING|MF_DONTENCOREMAP, // flags - S_GRAYSPRING2 // raisestate - }, - - { // MT_INVISSPRING - 554, // doomednum - S_INVISIBLE, // spawnstate - 100, // spawnhealth - S_INVISSPRING, // seestate - sfx_None, // seesound - 8, // reactiontime - sfx_None, // attacksound - S_NULL, // painstate - 0, // painchance - sfx_s3kb1, // painsound - S_NULL, // meleestate - S_NULL, // missilestate - S_NULL, // deathstate - S_NULL, // xdeathstate - sfx_None, // deathsound - 0, // speed - 20*FRACUNIT, // radius - 16*FRACUNIT, // height - 0, // display offset - 6*FRACUNIT, // mass - 0, // damage - sfx_None, // activesound - MF_SOLID|MF_SPRING, // flags - S_INVISSPRING // raisestate - }, - { // MT_RANDOMITEM 2000, // doomednum S_RANDOMITEM1, // spawnstate diff --git a/src/info.h b/src/info.h index 755b2f76b..d4291f9d0 100644 --- a/src/info.h +++ b/src/info.h @@ -462,12 +462,15 @@ typedef enum sprite SPR_SPVY, // Yellow Vertical Spring SPR_SPVR, // Red Vertical Spring SPR_SPVB, // Blue Vertical Spring + SPR_SPVG, // Grey Vertical Spring SPR_SPDY, // Yellow Diagonal Spring SPR_SPDR, // Red Diagonal Spring SPR_SPDB, // Blue Diagonal Spring + SPR_SPDG, // Grey Diagonal Spring SPR_SPHY, // Yellow Horizontal Spring SPR_SPHR, // Red Horizontal Spring SPR_SPHB, // Blue Horizontal Spring + SPR_SPHG, // Grey Horizontal Spring // Environmental Effects SPR_RAIN, // Rain @@ -591,8 +594,6 @@ typedef enum sprite SPR_SRBO, // Springs - SPR_SPRG, // Gray Spring - SPR_RNDM, // Random Item Box SPR_RPOP, // Random Item Box Pop SPR_SGNS, // Signpost sparkle @@ -2512,6 +2513,12 @@ typedef enum state S_BLUESPRING3, S_BLUESPRING4, + // Grey Spring + S_GREYSPRING1, + S_GREYSPRING2, + S_GREYSPRING3, + S_GREYSPRING4, + // Yellow Diagonal Spring S_YDIAG1, S_YDIAG2, @@ -2530,6 +2537,12 @@ typedef enum state S_BDIAG3, S_BDIAG4, + // Grey Diagonal Spring + S_GDIAG1, + S_GDIAG2, + S_GDIAG3, + S_GDIAG4, + // Yellow Horizontal Spring S_YHORIZ1, S_YHORIZ2, @@ -2548,6 +2561,12 @@ typedef enum state S_BHORIZ3, S_BHORIZ4, + // Grey Horizontal Spring + S_GHORIZ1, + S_GHORIZ2, + S_GHORIZ3, + S_GHORIZ4, + // Rain S_RAIN1, S_RAINRETURN, @@ -3171,16 +3190,6 @@ typedef enum state S_SRB1_GENREX1, S_SRB1_GENREX2, - // Gray Springs - S_GRAYSPRING, - S_GRAYSPRING2, - S_GRAYSPRING3, - S_GRAYSPRING4, - S_GRAYSPRING5, - - // Invis-spring - this is used just for the sproing sound. - S_INVISSPRING, - //{ Random Item Box S_RANDOMITEM1, S_RANDOMITEM2, @@ -4253,12 +4262,15 @@ typedef enum mobj_type MT_YELLOWSPRING, MT_REDSPRING, MT_BLUESPRING, + MT_GREYSPRING, MT_YELLOWDIAG, // Yellow Diagonal Spring MT_REDDIAG, // Red Diagonal Spring MT_BLUEDIAG, // Blue Diagonal Spring + MT_GREYDIAG, // Grey Diagonal Spring MT_YELLOWHORIZ, // Yellow Horizontal Spring MT_REDHORIZ, // Red Horizontal Spring MT_BLUEHORIZ, // Blue Horizontal Spring + MT_GREYHORIZ, // Grey Horizontal Spring // Interactive Objects MT_BUBBLES, // Bubble source @@ -4640,8 +4652,6 @@ typedef enum mobj_type MT_SRB1_GENREX, // SRB2kart - MT_GRAYSPRING, - MT_INVISSPRING, MT_RANDOMITEM, MT_RANDOMITEMPOP, MT_FLOATINGITEM, From 47da5263131efee2923223586ce49f4651b9b841 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Wed, 18 Sep 2019 19:29:28 -0400 Subject: [PATCH 077/163] Use texture names instead of predesignated sky numbers --- src/dehacked.c | 13 +++++++------ src/doomstat.h | 2 +- src/lua_baselib.c | 6 +++--- src/lua_maplib.c | 4 ++-- src/m_cheat.c | 6 +++--- src/p_saveg.c | 10 +++++----- src/p_setup.c | 20 +++++++++++--------- src/p_setup.h | 2 +- src/p_spec.c | 2 +- src/r_data.c | 2 +- src/r_sky.c | 4 ++-- src/r_sky.h | 4 ++-- 12 files changed, 39 insertions(+), 36 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index be45f3f0f..e9e083814 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1230,8 +1230,9 @@ static void readlevelheader(MYFILE *f, INT32 num) } else if (fastcmp(word, "WEATHER")) mapheaderinfo[num-1]->weather = (UINT8)get_number(word2); - else if (fastcmp(word, "SKYNUM")) - mapheaderinfo[num-1]->skynum = (INT16)i; + else if (fastcmp(word, "SKYTEXTURE")) + deh_strlcpy(mapheaderinfo[num-1]->skytexture, word2, + sizeof(mapheaderinfo[num-1]->skytexture), va("Level header %d: sky texture", num)); else if (fastcmp(word, "INTERSCREEN")) strncpy(mapheaderinfo[num-1]->interscreen, word2, 8); else if (fastcmp(word, "PRECUTSCENENUM")) @@ -9903,11 +9904,11 @@ static inline int lib_getenum(lua_State *L) } else if (fastcmp(word,"globalweather")) { lua_pushinteger(L, globalweather); return 1; - } else if (fastcmp(word,"levelskynum")) { - lua_pushinteger(L, levelskynum); + } else if (fastcmp(word,"levelskytexture")) { + lua_pushstring(L, levelskytexture); return 1; - } else if (fastcmp(word,"globallevelskynum")) { - lua_pushinteger(L, globallevelskynum); + } else if (fastcmp(word,"globallevelskytexture")) { + lua_pushstring(L, globallevelskytexture); return 1; } else if (fastcmp(word,"mapmusname")) { lua_pushstring(L, mapmusname); diff --git a/src/doomstat.h b/src/doomstat.h index 1f855da27..8b71e2d86 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -227,7 +227,7 @@ typedef struct UINT32 muspos; ///< Music position to jump to. char forcecharacter[17]; ///< (SKINNAMESIZE+1) Skin to switch to or "" to disable. UINT8 weather; ///< 0 = sunny day, 1 = storm, 2 = snow, 3 = rain, 4 = blank, 5 = thunder w/o rain, 6 = rain w/o lightning, 7 = heat wave. - INT16 skynum; ///< Sky number to use. + char skytexture[9]; ///< Sky texture to use. INT16 skybox_scalex; ///< Skybox X axis scale. (0 = no movement, 1 = 1:1 movement, 16 = 16:1 slow movement, -4 = 1:4 fast movement, etc.) INT16 skybox_scaley; ///< Skybox Y axis scale. INT16 skybox_scalez; ///< Skybox Z axis scale. diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 38af4d2e9..7464743c3 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1405,15 +1405,15 @@ static int lib_pIsFlagAtBase(lua_State *L) static int lib_pSetupLevelSky(lua_State *L) { - INT32 skynum = (INT32)luaL_checkinteger(L, 1); + const char *skytexname = luaL_checkstring(L, 1); player_t *user = NULL; NOHUD if (!lua_isnone(L, 2) && lua_isuserdata(L, 2)) // if a player, setup sky for only the player, otherwise setup sky for all players user = *((player_t **)luaL_checkudata(L, 2, META_PLAYER)); if (!user) // global - P_SetupLevelSky(skynum, true); + P_SetupLevelSky(skytexname, true); else if (P_IsLocalPlayer(user)) - P_SetupLevelSky(skynum, false); + P_SetupLevelSky(skytexname, false); return 0; } diff --git a/src/lua_maplib.c b/src/lua_maplib.c index 19292b3d6..0522cb737 100644 --- a/src/lua_maplib.c +++ b/src/lua_maplib.c @@ -1487,8 +1487,8 @@ static int mapheaderinfo_get(lua_State *L) lua_pushstring(L, header->forcecharacter); else if (fastcmp(field,"weather")) lua_pushinteger(L, header->weather); - else if (fastcmp(field,"skynum")) - lua_pushinteger(L, header->skynum); + else if (fastcmp(field,"skytexture")) + lua_pushstring(L, header->skytexture); else if (fastcmp(field,"skybox_scalex")) lua_pushinteger(L, header->skybox_scalex); else if (fastcmp(field,"skybox_scaley")) diff --git a/src/m_cheat.c b/src/m_cheat.c index e7e877ada..c24a8014b 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -577,14 +577,14 @@ void Command_Skynum_f(void) if (COM_Argc() != 2) { - CONS_Printf(M_GetText("skynum : change the sky\n")); - CONS_Printf(M_GetText("Current sky is %d\n"), levelskynum); + CONS_Printf(M_GetText("skynum : change the sky\n")); + CONS_Printf(M_GetText("Current sky is %s\n"), levelskytexture); return; } CONS_Printf(M_GetText("Previewing sky %s...\n"), COM_Argv(1)); - P_SetupLevelSky(atoi(COM_Argv(1)), false); + P_SetupLevelSky(COM_Argv(1), false); } void Command_Weather_f(void) diff --git a/src/p_saveg.c b/src/p_saveg.c index 7d2e9a307..2e794e926 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3091,7 +3091,7 @@ static inline void P_NetArchiveSpecials(void) WRITEUINT32(save_p, 0xffffffff); // Sky number - WRITEINT32(save_p, globallevelskynum); + WRITESTRINGN(save_p, globallevelskytexture, 9); // Current global weather type WRITEUINT8(save_p, globalweather); @@ -3110,8 +3110,8 @@ static inline void P_NetArchiveSpecials(void) // static void P_NetUnArchiveSpecials(void) { + char skytex[9]; size_t i; - INT32 j; if (READUINT32(save_p) != ARCHIVEBLOCK_SPECIALS) I_Error("Bad $$$.sav at archive block Specials"); @@ -3124,9 +3124,9 @@ static void P_NetUnArchiveSpecials(void) itemrespawntime[iquehead++] = READINT32(save_p); } - j = READINT32(save_p); - if (j != globallevelskynum) - P_SetupLevelSky(j, true); + READSTRINGN(save_p, skytex, sizeof(skytex)); + if (strcmp(skytex, globallevelskytexture)) + P_SetupLevelSky(skytex, true); globalweather = READUINT8(save_p); diff --git a/src/p_setup.c b/src/p_setup.c index d1ef91705..b7a482ce9 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -207,8 +207,9 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) mapheaderinfo[num]->forcecharacter[0] = '\0'; DEH_WriteUndoline("WEATHER", va("%d", mapheaderinfo[num]->weather), UNDO_NONE); mapheaderinfo[num]->weather = 0; - DEH_WriteUndoline("SKYNUM", va("%d", mapheaderinfo[num]->skynum), UNDO_NONE); - mapheaderinfo[num]->skynum = 1; + DEH_WriteUndoline("SKYTEXTURE", va("%d", mapheaderinfo[num]->skytexture), UNDO_NONE); + snprintf(mapheaderinfo[num]->skytexture, 9, "SKY1"); + mapheaderinfo[num]->skytexture[8] = 0; DEH_WriteUndoline("SKYBOXSCALEX", va("%d", mapheaderinfo[num]->skybox_scalex), UNDO_NONE); mapheaderinfo[num]->skybox_scalex = 16; DEH_WriteUndoline("SKYBOXSCALEY", va("%d", mapheaderinfo[num]->skybox_scaley), UNDO_NONE); @@ -2255,17 +2256,18 @@ static inline boolean P_CheckLevel(lumpnum_t lumpnum) /** Sets up a sky texture to use for the level. * The sky texture is used instead of F_SKY1. */ -void P_SetupLevelSky(INT32 skynum, boolean global) +void P_SetupLevelSky(const char *skytexname, boolean global) { - char skytexname[12]; + char tex[9]; + strncpy(tex, skytexname, 9); + tex[8] = 0; - sprintf(skytexname, "SKY%d", skynum); - skytexture = R_TextureNumForName(skytexname); - levelskynum = skynum; + skytexture = R_TextureNumForName(tex); + strncpy(levelskytexture, tex, 9); // Global change if (global) - globallevelskynum = levelskynum; + strncpy(globallevelskytexture, tex, 9); // Don't go beyond for dedicated servers if (dedicated) @@ -2973,7 +2975,7 @@ boolean P_SetupLevel(boolean skipprecip) CON_SetupBackColormap(); // SRB2 determines the sky texture to be used depending on the map header. - P_SetupLevelSky(mapheaderinfo[gamemap-1]->skynum, true); + P_SetupLevelSky(mapheaderinfo[gamemap-1]->skytexture, true); P_MakeMapMD5(lastloadedmaplumpnum, &mapmd5); diff --git a/src/p_setup.h b/src/p_setup.h index c4a3aab9a..9abcfe5f6 100644 --- a/src/p_setup.h +++ b/src/p_setup.h @@ -54,7 +54,7 @@ INT32 P_CheckLevelFlat(const char *flatname); extern size_t nummapthings; extern mapthing_t *mapthings; -void P_SetupLevelSky(INT32 skynum, boolean global); +void P_SetupLevelSky(const char *skytexname, boolean global); #ifdef SCANTHINGS void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum); #endif diff --git a/src/p_spec.c b/src/p_spec.c index ec5de3224..daef60a09 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2802,7 +2802,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 423: // Change Sky if ((mo && mo->player && P_IsLocalPlayer(mo->player)) || (line->flags & ML_NOCLIMB)) - P_SetupLevelSky(sides[line->sidenum[0]].textureoffset>>FRACBITS, (line->flags & ML_NOCLIMB)); + P_SetupLevelSky(sides[line->sidenum[0]].text, (line->flags & ML_NOCLIMB)); break; case 424: // Change Weather diff --git a/src/r_data.c b/src/r_data.c index 7fb11855f..d710359d1 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -1631,7 +1631,7 @@ void R_PrecacheLevel(void) // Sky texture is always present. // Note that F_SKY1 is the name used to indicate a sky floor/ceiling as a flat, - // while the sky texture is stored like a wall texture, with a skynum dependent name. + // while the sky texture is stored like a wall texture, with a texture name set by the map. texturepresent[skytexture] = 1; texturememory = 0; diff --git a/src/r_sky.c b/src/r_sky.c index fe1630e90..1fe0fe0e6 100644 --- a/src/r_sky.c +++ b/src/r_sky.c @@ -47,8 +47,8 @@ fixed_t skyscale; /** \brief used for keeping track of the current sky */ -INT32 levelskynum; -INT32 globallevelskynum; +char levelskytexture[9]; +char globallevelskytexture[9]; /** \brief The R_SetupSkyDraw function diff --git a/src/r_sky.h b/src/r_sky.h index 86b615595..a41b24463 100644 --- a/src/r_sky.h +++ b/src/r_sky.h @@ -30,8 +30,8 @@ extern INT32 skytexture, skytexturemid; extern fixed_t skyscale; extern INT32 skyflatnum; -extern INT32 levelskynum; -extern INT32 globallevelskynum; +extern char levelskytexture[9]; +extern char globallevelskytexture[9]; // call after skytexture is set to adapt for old/new skies void R_SetupSkyDraw(void); From 20663affc0460a07629a51a282a22c359393e8b8 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Wed, 18 Sep 2019 19:46:59 -0400 Subject: [PATCH 078/163] Flip sky direction --- src/r_plane.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/r_plane.c b/src/r_plane.c index db5bfbda2..ec105bf75 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -734,7 +734,7 @@ void R_DrawPlanes(void) dc_x = x; dc_source = R_GetColumn(texturetranslation[skytexture], - angle); + -angle); // Negative because skies were being drawn horizontally flipped wallcolfunc(); } } From 9e17484c7f93521e6a17d34d88fc790f1c8e303e Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Wed, 18 Sep 2019 21:22:50 -0400 Subject: [PATCH 079/163] OGL flipped skies --- src/hardware/hw_main.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 0d024dc65..659af386d 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5922,13 +5922,15 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) static void HWR_DrawSkyBackground(void) { FOutVector v[4]; + texture_t *tex; angle_t angle; float dimensionmultiply; float aspectratio; float angleturn; + tex = textures[texturetranslation[skytexture]]; HWR_GetTexture(texturetranslation[skytexture]); - aspectratio = (float)vid.width/(float)vid.height; + aspectratio = (float)vid.width / (float)vid.height; //Hurdler: the sky is the only texture who need 4.0f instead of 1.0 // because it's called just after clearing the screen @@ -5952,22 +5954,22 @@ static void HWR_DrawSkyBackground(void) // software doesn't draw any further than 1024 for skies anyway, but this doesn't overlap properly // The only time this will probably be an issue is when a sky wider than 1024 is used as a sky AND a regular wall texture - angle = (dup_viewangle + gr_xtoviewangle[0]); - dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->width/256.0f); + angle = -(dup_viewangle + gr_xtoviewangle[0]); + dimensionmultiply = ((float)tex->width/256.0f); if (atransform.mirror) { angle = InvAngle(angle); - dimensionmultiply *= -1; + dimensionmultiply = -dimensionmultiply; } v[0].sow = v[3].sow = ((float) angle / ((ANGLE_90-1)*dimensionmultiply)); - v[2].sow = v[1].sow = (-1.0f/dimensionmultiply)+((float) angle / ((ANGLE_90-1)*dimensionmultiply)); + v[2].sow = v[1].sow = (1.0f/dimensionmultiply)+((float) angle / ((ANGLE_90-1)*dimensionmultiply)); // Y angle = aimingangle; - dimensionmultiply = ((float)textures[texturetranslation[skytexture]]->height/(128.0f*aspectratio)); + dimensionmultiply = ((float)tex->height/(128.0f*aspectratio)); if (splitscreen == 1) { From 54066cc9fcf8dec108f1664bf8a1f67d46dbb2c6 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 22 Sep 2019 22:44:15 -0400 Subject: [PATCH 080/163] 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 9d8cb5247a9dcaef214686b0333b01b954f621a0 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 23 Sep 2019 03:15:08 -0400 Subject: [PATCH 081/163] Special effects! Tire grease waves, colored stars --- src/d_player.h | 2 ++ src/dehacked.c | 7 ++++++- src/info.c | 55 ++++++++++++++++++++++++++++++++++++++------------ src/info.h | 4 ++++ src/k_kart.c | 23 +++++++++++++++++++++ src/p_map.c | 19 +++++++++++++++++ src/p_mobj.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 149 insertions(+), 14 deletions(-) diff --git a/src/d_player.h b/src/d_player.h index aced985c8..de6cbc46c 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -328,6 +328,8 @@ typedef enum k_spectatewait, // How long have you been waiting as a spectator k_growcancel, // Hold the item button down to cancel Grow k_tiregrease, // Reduced friction timer after hitting a horizontal spring + k_springstars, // Spawn stars around a player when they hit a spring + k_springcolor, // Color of spring stars NUMKARTSTUFF } kartstufftype_t; diff --git a/src/dehacked.c b/src/dehacked.c index 616a81ee9..0e7ddb7e5 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7212,6 +7212,8 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_DRAFTDUST4", "S_DRAFTDUST5", + "S_TIREGREASE", + #ifdef SEENAMES "S_NAMECHECK", #endif @@ -8004,6 +8006,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_KARMAFIREWORK", "MT_RINGSPARKS", "MT_DRAFTDUST", + "MT_TIREGREASE", #ifdef SEENAMES "MT_NAMECHECK", @@ -8491,7 +8494,9 @@ static const char *const KARTSTUFF_LIST[] = { "JAWZTARGETDELAY", "SPECTATEWAIT", "GROWCANCEL", - "TIREGREASE" + "TIREGREASE", + "SPRINGSTARS", + "SPRINGCOLOR" }; #endif diff --git a/src/info.c b/src/info.c index 274cee440..be32f3ebd 100644 --- a/src/info.c +++ b/src/info.c @@ -70,7 +70,7 @@ char sprnames[NUMSPRITES + 1][5] = "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","MXCL","RGSP", - "DRAF","XMS4","XMS5","VIEW" + "DRAF","GRES","XMS4","XMS5","VIEW" }; // Doesn't work with g++, needs actionf_p1 (don't modify this comment) @@ -3452,6 +3452,8 @@ state_t states[NUMSTATES] = {SPR_DRAF, 3, 1, {NULL}, 0, 0, S_DRAFTDUST5}, // S_DRAFTDUST4 {SPR_DRAF, 4, 1, {NULL}, 0, 0, S_NULL}, // S_DRAFTDUST5 + {SPR_GRES, FF_ANIMATE|FF_PAPERSPRITE, -1, {NULL}, 2, 4, S_NULL}, // S_TIREGREASE + #ifdef SEENAMES {SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK #endif @@ -6082,7 +6084,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + SKINCOLOR_YELLOW, // painchance sfx_s3kb1, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -6109,7 +6111,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + SKINCOLOR_SALMON, // painchance sfx_s3kb1, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -6136,7 +6138,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + SKINCOLOR_PASTEL, // painchance sfx_s3kb1, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -6163,7 +6165,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + SKINCOLOR_POPCORN, // painchance sfx_s3kb1, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -6190,7 +6192,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + SKINCOLOR_YELLOW, // painchance sfx_s3kb1, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -6217,7 +6219,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + SKINCOLOR_SALMON, // painchance sfx_s3kb1, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -6244,7 +6246,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + SKINCOLOR_PASTEL, // painchance sfx_s3kb1, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -6271,7 +6273,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + SKINCOLOR_POPCORN, // painchance sfx_s3kb1, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -6298,7 +6300,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + SKINCOLOR_YELLOW, // painchance sfx_s3kb1, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -6325,7 +6327,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + SKINCOLOR_SALMON, // painchance sfx_s3kb1, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -6352,7 +6354,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + SKINCOLOR_PASTEL, // painchance sfx_s3kb1, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -6379,7 +6381,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 8, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + SKINCOLOR_POPCORN, // painchance sfx_s3kb1, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -20271,6 +20273,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_TIREGREASE + -1, // doomednum + S_TIREGREASE, // 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<flags2 |= MF2_DONTDRAW; } + + if (player->kartstuff[k_springstars] && (leveltime & 1)) + { + fixed_t randx = P_RandomRange(-40, 40) * player->mo->scale; + fixed_t randy = P_RandomRange(-40, 40) * player->mo->scale; + fixed_t randz = P_RandomRange(0, player->mo->height >> FRACBITS) << FRACBITS; + mobj_t *star = P_SpawnMobj( + player->mo->x + randx, + player->mo->y + randy, + player->mo->z + randz, + MT_KARMAFIREWORK); + + star->color = player->kartstuff[k_springcolor]; + star->flags |= MF_NOGRAVITY; + star->momx = player->mo->momx / 2; + star->momy = player->mo->momy / 2; + star->momz = player->mo->momz / 2; + star->fuse = 12; + star->scale = player->mo->scale; + star->destscale = star->scale / 2; + + player->kartstuff[k_springstars]--; + } } if (player->playerstate == PST_DEAD || player->kartstuff[k_respawn] > 1) // Ensure these are set correctly here diff --git a/src/p_map.c b/src/p_map.c index 22c6755e7..fbf5b4b06 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -122,6 +122,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) const fixed_t vscale = mapobjectscale + (object->scale - mapobjectscale); fixed_t vertispeed = spring->info->mass; fixed_t horizspeed = spring->info->damage; + UINT8 starcolor = spring->info->painchance; fixed_t savemomx = 0; fixed_t savemomy = 0; @@ -251,7 +252,22 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) { // Less friction when hitting horizontal springs if (!vertispeed) + { + if (!object->player->kartstuff[k_tiregrease]) + { + UINT8 i; + for (i = 0; i < 2; i++) + { + mobj_t *grease; + grease = P_SpawnMobj(object->x, object->y, object->z, MT_TIREGREASE); + P_SetTarget(&grease->target, object); + grease->angle = R_PointToAngle2(0, 0, object->momx, object->momy); + grease->extravalue1 = i; + } + } + object->player->kartstuff[k_tiregrease] = greasetics; //FixedMul(greasetics << FRACBITS, finalSpeed/72) >> FRACBITS + } } // Horizontal speed is used as a minimum thrust, not a direct replacement @@ -271,6 +287,9 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) P_SetTarget(&spring->target, object); P_ResetPlayer(object->player); + + object->player->kartstuff[k_springstars] = max(vertispeed, horizspeed) / FRACUNIT / 2; + object->player->kartstuff[k_springcolor] = starcolor; } return true; diff --git a/src/p_mobj.c b/src/p_mobj.c index e8880f07b..2dda7cb4f 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8368,6 +8368,56 @@ void P_MobjThinker(mobj_t *mobj) z); } break; + case MT_TIREGREASE: + if (!mobj->target || P_MobjWasRemoved(mobj->target) || !mobj->target->player + || !mobj->target->player->kartstuff[k_tiregrease]) + { + P_RemoveMobj(mobj); + return; + } + + K_MatchGenericExtraFlags(mobj, mobj->target); + + { + const angle_t off = FixedAngle(40*FRACUNIT); + angle_t ang = mobj->target->angle; + fixed_t z; + UINT8 trans = (mobj->target->player->kartstuff[k_tiregrease] * (NUMTRANSMAPS+1)) / greasetics; + + if (trans > NUMTRANSMAPS) + trans = NUMTRANSMAPS; + + trans = NUMTRANSMAPS - trans; + + z = mobj->target->z; + if (mobj->eflags & MFE_VERTICALFLIP) + z += mobj->target->height; + + if (mobj->target->momx || mobj->target->momy) + ang = R_PointToAngle2(0, 0, mobj->target->momx, mobj->target->momy); + + if (mobj->extravalue1) + ang = (signed)(ang - off); + else + ang = (signed)(ang + off); + + P_TeleportMove(mobj, + mobj->target->x - FixedMul(mobj->target->radius, FINECOSINE(ang >> ANGLETOFINESHIFT)), + mobj->target->y - FixedMul(mobj->target->radius, FINESINE(ang >> ANGLETOFINESHIFT)), + z); + mobj->angle = ang; + + if (leveltime & 1) + mobj->flags2 |= MF2_DONTDRAW; + + if (trans >= NUMTRANSMAPS) + mobj->flags2 |= MF2_DONTDRAW; + else if (trans == 0) + mobj->frame = (mobj->frame & ~FF_TRANSMASK); + else + mobj->frame = (mobj->frame & ~FF_TRANSMASK)|(trans << FF_TRANSSHIFT); + } + break; case MT_THUNDERSHIELD: { fixed_t destx, desty; @@ -9070,6 +9120,9 @@ void P_MobjThinker(mobj_t *mobj) } break; case MT_KARMAFIREWORK: + if (mobj->flags & MF_NOGRAVITY) + break; + if (mobj->momz == 0) { P_RemoveMobj(mobj); From 594e1cb41a3d93c6cc563fb2f4699f1bda2aadb1 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 23 Sep 2019 03:48:50 -0400 Subject: [PATCH 082/163] rotate flag applies to all springs --- 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 2dda7cb4f..ecb92a06e 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12064,7 +12064,7 @@ ML_NOCLIMB : Direction not controllable { if (mthing->options & MTF_AMBUSH) { - if (i == MT_YELLOWDIAG || i == MT_REDDIAG) + if (mobj->flags & MF_SPRING) mobj->angle += ANGLE_22h; if (mobj->flags & MF_NIGHTSITEM) From bc7673f2dad8d434ac389725737ebe7e05527bd6 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 23 Sep 2019 06:29:30 -0400 Subject: [PATCH 083/163] Update Spring Shells, add color modulo check --- src/info.c | 8 ++++---- src/p_map.c | 3 ++- src/p_mobj.c | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/info.c b/src/info.c index be32f3ebd..cb478b3d8 100644 --- a/src/info.c +++ b/src/info.c @@ -4253,7 +4253,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 32, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + SKINCOLOR_TEA, // painchance sfx_s3kb1, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -4264,7 +4264,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // radius 40*FRACUNIT, // height 0, // display offset - 13*FRACUNIT, // mass + 15*FRACUNIT, // mass 0, // damage sfx_None, // activesound MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE, // flags @@ -4280,7 +4280,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 32, // reactiontime sfx_None, // attacksound S_NULL, // painstate - 0, // painchance + SKINCOLOR_YELLOW, // painchance sfx_s3kb1, // painsound S_NULL, // meleestate S_NULL, // missilestate @@ -4291,7 +4291,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 24*FRACUNIT, // radius 40*FRACUNIT, // height 0, // display offset - 26*FRACUNIT, // mass + 25*FRACUNIT, // mass 0, // damage sfx_None, // activesound MF_ENEMY|MF_SPECIAL|MF_SHOOTABLE, // flags diff --git a/src/p_map.c b/src/p_map.c index fbf5b4b06..36b5af70e 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -122,7 +122,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) const fixed_t vscale = mapobjectscale + (object->scale - mapobjectscale); fixed_t vertispeed = spring->info->mass; fixed_t horizspeed = spring->info->damage; - UINT8 starcolor = spring->info->painchance; + UINT8 starcolor = (spring->info->painchance % MAXTRANSLATIONS); fixed_t savemomx = 0; fixed_t savemomy = 0; @@ -1207,6 +1207,7 @@ static boolean PIT_CheckThing(mobj_t *thing) //else if (tmz > thzh - sprarea && tmz < thzh) // Don't damage people springing up / down return true; } + // missiles can hit other things if (tmthing->flags & MF_MISSILE || tmthing->type == MT_SHELL) { diff --git a/src/p_mobj.c b/src/p_mobj.c index ecb92a06e..de86bfb89 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12064,7 +12064,7 @@ ML_NOCLIMB : Direction not controllable { if (mthing->options & MTF_AMBUSH) { - if (mobj->flags & MF_SPRING) + if (mobj->flags & MF_SPRING && mobj->info->damage) mobj->angle += ANGLE_22h; if (mobj->flags & MF_NIGHTSITEM) From 932f8a1f618ee5c386714da9b13588db85e7f520 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Mon, 23 Sep 2019 07:03:00 -0400 Subject: [PATCH 084/163] 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 085/163] 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 086/163] 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 087/163] 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 088/163] 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 089/163] 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 090/163] 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 091/163] 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 092/163] 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 093/163] 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 094/163] 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 095/163] 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 7a6a2f248e54615b024c4e77365453862be72990 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Sep 2019 14:32:25 -0700 Subject: [PATCH 096/163] Remove trailing whitespace --- src/k_kart.c | 2 +- src/p_map.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index b1a28f683..670af73ff 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6539,7 +6539,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } // Friction was changed, so we must recalculate a bunch of stuff - if (player->mo->friction != prevfriction) + if (player->mo->friction != prevfriction) { if (player->mo->friction > FRACUNIT) player->mo->friction = FRACUNIT; diff --git a/src/p_map.c b/src/p_map.c index 36b5af70e..b9030fd00 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -219,7 +219,7 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object) momang = R_PointToAngle2(0, 0, savemomx, savemomy); angoffset = momang; - angoffset -= spring->angle; // Subtract + angoffset -= spring->angle; // Subtract // Flip on wrong side if ((angle_t)angoffset > ANGLE_180) From 1d59d8305d4b57a4527e7329732918c64fb38e26 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Sep 2019 14:39:23 -0700 Subject: [PATCH 097/163] Remove trailing whitespace --- src/d_main.c | 2 +- src/p_inter.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 5c8e34bde..8388c50cd 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -447,7 +447,7 @@ static void D_Display(void) { if (i > 0) // Splitscreen-specific { - switch (i) + switch (i) { case 1: if (splitscreen > 1) diff --git a/src/p_inter.c b/src/p_inter.c index de14b3db9..8cf9703d0 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3306,12 +3306,12 @@ void P_PlayerRingBurst(player_t *player, INT32 num_rings) // 20 is the ring cap in kart if (num_rings > 20) - num_rings = 20; + num_rings = 20; else if (num_rings <= 0) return; // Cap the maximum loss automatically to 2 in ring debt - if (player->kartstuff[k_rings] <= 0 && num_rings > 2) + if (player->kartstuff[k_rings] <= 0 && num_rings > 2) num_rings = 2; P_GivePlayerRings(player, -num_rings); From 971eed8d9726ca037f48ebca7d6c0909618549c5 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Sep 2019 16:35:41 -0700 Subject: [PATCH 098/163] abs is unnecessary on unsigned types --- 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 fce8b4ff6..fe8902257 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1623,7 +1623,7 @@ static void K_DrawDraftCombiring(player_t *player, player_t *victim, fixed_t cur cury + (P_RandomRange(-12,12)*mapobjectscale), curz + (P_RandomRange(24,48)*mapobjectscale), MT_SIGNSPARKLE); - P_SetMobjState(band, S_SIGNSPARK1 + (abs(leveltime+offset) % 11)); + P_SetMobjState(band, S_SIGNSPARK1 + ((leveltime+offset) % 11)); P_SetScale(band, (band->destscale = (3*player->mo->scale)/2)); band->color = colors[c]; band->colorized = true; From 739d602c84ca79cf972a76b07aed0830109a8055 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 26 Sep 2019 16:41:02 -0700 Subject: [PATCH 099/163] Addition unecessary as ruled out by if condition --- 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 fe8902257..2015cbf39 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1623,7 +1623,7 @@ static void K_DrawDraftCombiring(player_t *player, player_t *victim, fixed_t cur cury + (P_RandomRange(-12,12)*mapobjectscale), curz + (P_RandomRange(24,48)*mapobjectscale), MT_SIGNSPARKLE); - P_SetMobjState(band, S_SIGNSPARK1 + ((leveltime+offset) % 11)); + P_SetMobjState(band, S_SIGNSPARK1 + (leveltime % 11)); P_SetScale(band, (band->destscale = (3*player->mo->scale)/2)); band->color = colors[c]; band->colorized = true; From 92022be2542d824313854973b1849305367618bf Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 27 Sep 2019 06:28:26 -0400 Subject: [PATCH 100/163] Don't crash if you can't find a pwad or it's already loaded or etc --- src/d_main.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 5c8e34bde..a89fe4340 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1190,12 +1190,12 @@ void D_SRB2Main(void) M_InitCharacterTables(); // load wad, including the main wad file - CONS_Printf("W_InitMultipleFiles(): Adding IWAD and main PWADs.\n"); + CONS_Printf("W_InitMultipleFiles(): Adding main IWAD and PWADs.\n"); if (!W_InitMultipleFiles(startupwadfiles, false)) #ifdef _DEBUG - CONS_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n"); + CONS_Error("A main WAD file was not found or not valid.\nCheck the log to see which ones.\n"); #else - I_Error("A WAD file was not found or not valid.\nCheck the log to see which ones.\n"); + I_Error("A main WAD file was not found or not valid.\nCheck the log to see which ones.\n"); #endif D_CleanFile(startupwadfiles); @@ -1249,8 +1249,9 @@ void D_SRB2Main(void) } } + CONS_Printf("W_InitMultipleFiles(): Adding external PWADs.\n"); if (!W_InitMultipleFiles(startuppwads, true)) - CONS_Error("A PWAD file was not found or not valid.\nCheck the log to see which ones.\n"); + M_StartMessage(M_GetText("A PWAD file was not found or not valid.\nCheck log.txt to see which ones.\n\nPress ESC\n"), NULL, MM_NOTHING); D_CleanFile(startuppwads); // From 2635d1b8106506424cff6c1477838a01fbbcc7b8 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 27 Sep 2019 06:46:10 -0400 Subject: [PATCH 101/163] 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 102/163] 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 103/163] 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 104/163] 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 105/163] 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 106/163] 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 107/163] 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 108/163] 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 109/163] 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 110/163] 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 111/163] 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 112/163] 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 113/163] 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 114/163] 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 115/163] 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 116/163] 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 117/163] 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 118/163] 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 119/163] 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 120/163] 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 121/163] 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 122/163] 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 123/163] 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 124/163] 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 125/163] 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 126/163] 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 127/163] 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 128/163] Nevermind the FixedMul --- src/p_enemy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_enemy.c b/src/p_enemy.c index aadb27329..76f6b3159 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3637,7 +3637,7 @@ void A_AttractChase(mobj_t *actor) P_TeleportMove(actor, actor->target->x + FixedMul(dist, FINECOSINE(actor->angle >> ANGLETOFINESHIFT)), actor->target->y + FixedMul(dist, FINESINE(actor->angle >> ANGLETOFINESHIFT)), - actor->z + FixedMul(actor->target->scale, 24<z + actor->target->scale * 24 * P_MobjFlip(actor)); actor->angle += ANG30; actor->extravalue1++; From fa09c0420fe11049c22b6c803b8dd87f9aa3b18b Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 5 Oct 2019 13:15:36 -0700 Subject: [PATCH 129/163] Custom gamedata parameter --- src/g_game.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/g_game.c b/src/g_game.c index d5ed9af7d..15a22f493 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4082,6 +4082,11 @@ void G_LoadGameData(void) if (M_CheckParm("-resetdata")) return; // Don't load (essentially, reset). + if (M_CheckParm("-gamedata") && M_IsNextParm()) + { + strlcpy(gamedatafilename, M_GetNextParm(), sizeof gamedatafilename); + } + length = FIL_ReadFile(va(pandf, srb2home, gamedatafilename), &savebuffer); if (!length) // Aw, no game data. Their loss! return; From 027dec67025481e19ec00cb43d8336ed25982672 Mon Sep 17 00:00:00 2001 From: wolfy852 Date: Sat, 5 Oct 2019 19:07:26 -0500 Subject: [PATCH 130/163] Fix Ring Drain sectors for v2 rings --- src/p_spec.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index aa43583a4..93e88e2ce 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3637,10 +3637,9 @@ void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *rovers break; case 9: // Ring Drainer (Floor Touch) case 10: // Ring Drainer (No Floor Touch) - if (leveltime % (TICRATE/2) == 0 && player->mo->health > 1) + if (leveltime % (TICRATE/2) == 0 && player->kartstuff[k_rings] > 0) { - player->mo->health--; - player->health--; + player->kartstuff[k_rings]--; S_StartSound(player->mo, sfx_itemup); } break; From c963a49542607e5829c8cc2b0f7510d6fc7eb8fb Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 17 Oct 2019 23:43:06 -0400 Subject: [PATCH 131/163] Try fixing Auto causing desyncs - Move K_SetPowerLevelScrambles to G_DoCompleted - Fix wrong gamespeed being displayed in strings - Add defines for kartspeed values - Disable Easy scrambles again - Corrupt gamedata if pwrlv is in invalid range (gets corrected in-game, and doesn't really matter to anyone who knows what you're doing, but it'll stop at least the most basic script kiddie) Replay menu will still display wrong speed name, but it's fine in the replay itself. --- src/command.c | 10 +++++----- src/command.h | 4 ++++ src/d_main.c | 3 ++- src/d_netcmd.c | 10 ++++++---- src/g_game.c | 19 ++++++++++++++++-- src/g_game.h | 2 +- src/hu_stuff.c | 2 +- src/k_pwrlv.c | 54 ++++++++++++++++++++++++++++++++++++++++---------- src/m_menu.c | 4 ++-- src/p_saveg.c | 6 ++++++ src/p_setup.c | 8 ++++---- src/y_inter.c | 6 ++---- 12 files changed, 93 insertions(+), 35 deletions(-) diff --git a/src/command.c b/src/command.c index 664eb950c..625065120 100644 --- a/src/command.c +++ b/src/command.c @@ -68,12 +68,12 @@ CV_PossibleValue_t CV_YesNo[] = {{0, "No"}, {1, "Yes"}, {0, NULL}}; CV_PossibleValue_t CV_Unsigned[] = {{0, "MIN"}, {999999999, "MAX"}, {0, NULL}}; CV_PossibleValue_t CV_Natural[] = {{1, "MIN"}, {999999999, "MAX"}, {0, NULL}}; -//SRB2kart +// SRB2kart CV_PossibleValue_t kartspeed_cons_t[] = { - {-1, "Auto"}, - {0, "Easy"}, - {1, "Normal"}, - {2, "Hard"}, + {KARTSPEED_AUTO, "Auto"}, + {KARTSPEED_EASY, "Easy"}, + {KARTSPEED_NORMAL, "Normal"}, + {KARTSPEED_HARD, "Hard"}, {0, NULL} }; diff --git a/src/command.h b/src/command.h index 6b5d513ef..33d232bcb 100644 --- a/src/command.h +++ b/src/command.h @@ -131,6 +131,10 @@ extern CV_PossibleValue_t CV_Unsigned[]; extern CV_PossibleValue_t CV_Natural[]; // SRB2kart +#define KARTSPEED_AUTO -1 +#define KARTSPEED_EASY 0 +#define KARTSPEED_NORMAL 1 +#define KARTSPEED_HARD 2 extern CV_PossibleValue_t kartspeed_cons_t[]; extern consvar_t cv_execversion; diff --git a/src/d_main.c b/src/d_main.c index 597eea87c..dee752107 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -1536,10 +1536,11 @@ void D_SRB2Main(void) newskill = (INT16)kartspeed_cons_t[j].value; break; } + if (!kartspeed_cons_t[j].strvalue) // reached end of the list with no match { j = atoi(sskill); // assume they gave us a skill number, which is okay too - if (j >= 0 && j <= 2) + if (j >= KARTSPEED_EASY && j <= KARTSPEED_HARD) newskill = (INT16)j; } diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 51ec3b980..db0c00086 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -5779,7 +5779,7 @@ static void KartFrantic_OnChange(void) static void KartSpeed_OnChange(void) { - if (!M_SecretUnlocked(SECRET_HARDSPEED) && cv_kartspeed.value == 2) + if (!M_SecretUnlocked(SECRET_HARDSPEED) && cv_kartspeed.value == KARTSPEED_HARD) { CONS_Printf(M_GetText("You haven't earned this yet.\n")); CV_StealthSet(&cv_kartspeed, cv_kartspeed.defaultvalue); @@ -5788,13 +5788,15 @@ static void KartSpeed_OnChange(void) if (G_RaceGametype()) { - if ((UINT8)cv_kartspeed.value != gamespeed && gamestate == GS_LEVEL && leveltime > starttime) - CONS_Printf(M_GetText("Game speed will be changed to \"%s\" next round.\n"), cv_kartspeed.string); - else + if ((gamestate == GS_LEVEL && leveltime < starttime) && (cv_kartspeed.value != KARTSPEED_AUTO)) { CONS_Printf(M_GetText("Game speed has been changed to \"%s\".\n"), cv_kartspeed.string); gamespeed = (UINT8)cv_kartspeed.value; } + else if (cv_kartspeed.value != (signed)gamespeed) + { + CONS_Printf(M_GetText("Game speed will be changed to \"%s\" next round.\n"), cv_kartspeed.string); + } } } diff --git a/src/g_game.c b/src/g_game.c index d5ed9af7d..5a0960c36 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3687,6 +3687,7 @@ static void G_DoCompleted(void) { INT32 i, j = 0; boolean gottoken = false; + SINT8 powertype = PWRLV_DISABLED; tokenlist = 0; // Reset the list @@ -3825,13 +3826,23 @@ static void G_DoCompleted(void) nextmap = G_RandMap(G_TOLFlag(gametype), prevmap, false, 0, false, NULL); } - // We are committed to this map now. // We may as well allocate its header if it doesn't exist // (That is, if it's a real map) if (nextmap < NUMMAPS && !mapheaderinfo[nextmap]) P_AllocMapHeader(nextmap); + // Set up power level gametype scrambles + if (netgame && cv_kartusepwrlv.value) + { + if (G_RaceGametype()) + powertype = PWRLV_RACE; + else if (G_BattleGametype()) + powertype = PWRLV_BATTLE; + } + + K_SetPowerLevelScrambles(powertype); + demointermission: if (skipstats && !modeattacking) // Don't skip stats if we're in record attack @@ -4104,7 +4115,11 @@ void G_LoadGameData(void) matchesplayed = READUINT32(save_p); for (i = 0; i < PWRLV_NUMTYPES; i++) + { vspowerlevel[i] = READUINT16(save_p); + if (vspowerlevel[i] < PWRLVRECORD_MIN || vspowerlevel[i] > PWRLVRECORD_MAX) + goto datacorrupt; + } modded = READUINT8(save_p); @@ -6896,7 +6911,7 @@ void G_LoadDemoInfo(menudemo_t *pdemo) extrainfo_p = infobuffer + READUINT32(info_p); // Pared down version of CV_LoadNetVars to find the kart speed - pdemo->kartspeed = 1; // Default to normal speed + pdemo->kartspeed = KARTSPEED_NORMAL; // Default to normal speed count = READUINT16(info_p); while (count--) { diff --git a/src/g_game.h b/src/g_game.h index a69f91421..de482fe7f 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -80,7 +80,7 @@ typedef struct menudemo_s { UINT16 map; UINT8 addonstatus; // What do we need to do addon-wise to play this demo? UINT8 gametype; - UINT8 kartspeed; // Add OR DF_ENCORE for encore mode, idk + SINT8 kartspeed; // Add OR DF_ENCORE for encore mode, idk UINT8 numlaps; struct { diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 6126f7bec..1afa133b3 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -3017,7 +3017,7 @@ static void HU_DrawRankings(void) } V_DrawCenteredString(256, 8, 0, "GAME SPEED"); - V_DrawCenteredString(256, 16, hilicol, kartspeed_cons_t[gamespeed].strvalue); + V_DrawCenteredString(256, 16, hilicol, kartspeed_cons_t[1+gamespeed].strvalue); } // When you play, you quickly see your score because your name is displayed in white. diff --git a/src/k_pwrlv.c b/src/k_pwrlv.c index 257b8ad06..b1848f04b 100644 --- a/src/k_pwrlv.c +++ b/src/k_pwrlv.c @@ -83,7 +83,10 @@ INT16 K_CalculatePowerLevelAvg(void) UINT8 i; if (!netgame || !cv_kartusepwrlv.value) + { + CONS_Printf("Not in a netgame, or not using power levels -- no average.\n"); return 0; // No average. + } if (G_RaceGametype()) t = PWRLV_RACE; @@ -91,7 +94,10 @@ INT16 K_CalculatePowerLevelAvg(void) t = PWRLV_BATTLE; if (t == PWRLV_DISABLED) + { + CONS_Printf("Could not set a power level type -- no average.\n"); return 0; // Hmm?! + } for (i = 0; i < MAXPLAYERS; i++) { @@ -99,12 +105,15 @@ INT16 K_CalculatePowerLevelAvg(void) || clientpowerlevels[i][t] == 0) // splitscreen player continue; - avg += clientpowerlevels[i][t]; + avg += (clientpowerlevels[i][t] << FRACBITS); div++; } if (!div) + { + CONS_Printf("Found no players -- no average.\n"); return 0; // No average. + } avg /= div; @@ -120,19 +129,32 @@ void K_SetPowerLevelScrambles(SINT8 powertype) case PWRLV_RACE: if (cv_kartspeed.value == -1 || cv_kartencore.value == -1) { - UINT8 speed = atoi(cv_kartspeed.defaultvalue); + UINT8 speed = KARTSPEED_NORMAL; boolean encore = false; INT16 avg = 0, min = 0; - UINT8 i, t = 0; + UINT8 i, t = 1; avg = K_CalculatePowerLevelAvg(); for (i = 0; i < MAXPLAYERS; i++) { + if (!playeringame[i] || players[i].spectator + || clientpowerlevels[i][t] == 0) // splitscreen player + continue; + if (min == 0 || clientpowerlevels[i][0] < min) min = clientpowerlevels[i][0]; } + CONS_Printf("Min: %d, Avg: %d\n", min, avg); + + if (avg == 0 || min == 0) + { + CONS_Printf("No average/minimum, no scramblin'.\n"); + speedscramble = encorescramble = -1; + return; + } + if (min >= 7800) { if (avg >= 8200) @@ -161,6 +183,10 @@ void K_SetPowerLevelScrambles(SINT8 powertype) else t = 1; } +#if 1 + else + t = 1; +#else else if (min >= 1800) { if (avg >= 2200) @@ -170,35 +196,41 @@ void K_SetPowerLevelScrambles(SINT8 powertype) } else t = 0; +#endif + + CONS_Printf("Table position: %d\n", t); switch (t) { case 5: - speed = 2; + speed = KARTSPEED_HARD; encore = true; break; case 4: - speed = M_RandomChance((7<>1); + speed = P_RandomChance((7<>1); break; case 3: - speed = M_RandomChance((3<>2); + speed = P_RandomChance((3<>2); break; case 2: speed = 1; - encore = M_RandomChance(FRACUNIT>>3); + encore = P_RandomChance(FRACUNIT>>3); break; case 1: default: - speed = 1; + speed = KARTSPEED_NORMAL; encore = false; break; case 0: - speed = M_RandomChance((3<x+128, S_LINEY(i)+8, globalflags, va("(%s)", spd)); } diff --git a/src/p_saveg.c b/src/p_saveg.c index eb7d2900e..b81cc0f50 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -3290,6 +3290,9 @@ static void P_NetArchiveMisc(void) WRITEUINT8(save_p, franticitems); WRITEUINT8(save_p, comeback); + WRITESINT8(save_p, speedscramble); + WRITESINT8(save_p, encorescramble); + for (i = 0; i < 4; i++) WRITESINT8(save_p, battlewanted[i]); @@ -3410,6 +3413,9 @@ static inline boolean P_NetUnArchiveMisc(void) franticitems = (boolean)READUINT8(save_p); comeback = (boolean)READUINT8(save_p); + speedscramble = READSINT8(save_p); + encorescramble = READSINT8(save_p); + for (i = 0; i < 4; i++) battlewanted[i] = READSINT8(save_p); diff --git a/src/p_setup.c b/src/p_setup.c index 5ec0f97e6..5acc72746 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2388,18 +2388,18 @@ static void P_LevelInitStuff(void) // SRB2Kart: map load variables if (modeattacking) // Just play it safe and set everything { - gamespeed = 2; + gamespeed = KARTSPEED_HARD; franticitems = false; comeback = true; } else { if (G_BattleGametype()) - gamespeed = 0; + gamespeed = KARTSPEED_EASY; else { - if (cv_kartspeed.value == -1) - gamespeed = ((speedscramble == -1) ? atoi(cv_kartspeed.defaultvalue) : (UINT8)speedscramble); + if (cv_kartspeed.value == KARTSPEED_AUTO) + gamespeed = ((speedscramble == -1) ? KARTSPEED_NORMAL : (UINT8)speedscramble); else gamespeed = (UINT8)cv_kartspeed.value; } diff --git a/src/y_inter.c b/src/y_inter.c index c51ac1e3f..f5380d565 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -605,7 +605,7 @@ dotimer: V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2, hilicol, M_GetText("Teams will be scrambled next round!"));*/ if (speedscramble != -1 && speedscramble != gamespeed) V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT-24, hilicol|V_ALLOWLOWERCASE|V_SNAPTOBOTTOM, - va(M_GetText("Next race will be %s Speed!"), kartspeed_cons_t[speedscramble].strvalue)); + va(M_GetText("Next race will be %s Speed!"), kartspeed_cons_t[1+speedscramble].strvalue)); //} } @@ -1000,8 +1000,6 @@ void Y_StartIntermission(void) powertype = PWRLV_BATTLE; } - K_SetPowerLevelScrambles(powertype); - if (!multiplayer) { timer = 0; @@ -1078,7 +1076,7 @@ void Y_StartIntermission(void) break; } - if (powertype != -1) + if (powertype != PWRLV_DISABLED) K_UpdatePowerLevels(); //if (intertype == int_race || intertype == int_match) From 9777489bb83296a4fd6d0febc342b033013575e3 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 18 Oct 2019 19:09:10 -0400 Subject: [PATCH 132/163] debug prints --- src/k_pwrlv.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/k_pwrlv.c b/src/k_pwrlv.c index b1848f04b..94bdb13a4 100644 --- a/src/k_pwrlv.c +++ b/src/k_pwrlv.c @@ -84,7 +84,7 @@ INT16 K_CalculatePowerLevelAvg(void) if (!netgame || !cv_kartusepwrlv.value) { - CONS_Printf("Not in a netgame, or not using power levels -- no average.\n"); + CONS_Debug(DBG_GAMELOGIC, "Not in a netgame, or not using power levels -- no average.\n"); return 0; // No average. } @@ -95,7 +95,7 @@ INT16 K_CalculatePowerLevelAvg(void) if (t == PWRLV_DISABLED) { - CONS_Printf("Could not set a power level type -- no average.\n"); + CONS_Debug(DBG_GAMELOGIC, "Could not set a power level type -- no average.\n"); return 0; // Hmm?! } @@ -111,7 +111,7 @@ INT16 K_CalculatePowerLevelAvg(void) if (!div) { - CONS_Printf("Found no players -- no average.\n"); + CONS_Debug(DBG_GAMELOGIC, "Found no players -- no average.\n"); return 0; // No average. } @@ -146,11 +146,11 @@ void K_SetPowerLevelScrambles(SINT8 powertype) min = clientpowerlevels[i][0]; } - CONS_Printf("Min: %d, Avg: %d\n", min, avg); + CONS_Debug(DBG_GAMELOGIC, "Min: %d, Avg: %d\n", min, avg); if (avg == 0 || min == 0) { - CONS_Printf("No average/minimum, no scramblin'.\n"); + CONS_Debug(DBG_GAMELOGIC, "No average/minimum, no scramblin'.\n"); speedscramble = encorescramble = -1; return; } @@ -198,7 +198,7 @@ void K_SetPowerLevelScrambles(SINT8 powertype) t = 0; #endif - CONS_Printf("Table position: %d\n", t); + CONS_Debug(DBG_GAMELOGIC, "Table position: %d\n", t); switch (t) { @@ -228,8 +228,8 @@ void K_SetPowerLevelScrambles(SINT8 powertype) break; } - CONS_Printf("Rolled speed: %d\n", speed); - CONS_Printf("Rolled encore: %s\n", (encore ? "true" : "false")); + CONS_Debug(DBG_GAMELOGIC, "Rolled speed: %d\n", speed); + CONS_Debug(DBG_GAMELOGIC, "Rolled encore: %s\n", (encore ? "true" : "false")); if (cv_kartspeed.value == -1) speedscramble = speed; From fc862c999d2cd2511c1eb8da8e35c0bf8de37404 Mon Sep 17 00:00:00 2001 From: James Date: Sat, 19 Oct 2019 01:48:56 -0400 Subject: [PATCH 133/163] Bad parathesis --- src/d_clisrv.c | 1 + src/m_menu.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index d67f6b48e..1dacabd9f 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1241,6 +1241,7 @@ static inline void CL_DrawConnectionStatus(void) case CL_ASKDOWNLOADFILES: case CL_WAITDOWNLOADFILESRESPONSE: cltext = M_GetText("Waiting to download files..."); + break; default: cltext = M_GetText("Connecting to server..."); break; diff --git a/src/m_menu.c b/src/m_menu.c index e948b85f1..d5084dff2 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -5412,7 +5412,7 @@ static void DrawReplayHutReplayInfo(void) V_DrawThinString(x, y+9, V_SNAPTOTOP|V_ALLOWLOWERCASE, va("(%d laps)", demolist[dir_on[menudepthleft]].numlaps)); V_DrawString(x, y+20, V_SNAPTOTOP|V_ALLOWLOWERCASE, demolist[dir_on[menudepthleft]].gametype == GT_RACE ? - va("Race (%s speed)", kartspeed_cons_t[demolist[(dir_on[menudepthleft]].kartspeed & ~DF_ENCORE) + 1].strvalue) : + va("Race (%s speed)", kartspeed_cons_t[(demolist[dir_on[menudepthleft]].kartspeed & ~DF_ENCORE) + 1].strvalue) : "Battle Mode"); if (!demolist[dir_on[menudepthleft]].standings[0].ranking) From f9ea6833129ccf884ab2f0b3d9fb3d9d0e37d44f Mon Sep 17 00:00:00 2001 From: James Date: Tue, 22 Oct 2019 08:45:38 -0400 Subject: [PATCH 134/163] P_PlayerTouchingSectorSpecial turned into P_MobjTouchingSectorSpecial --- src/k_kart.c | 27 ++++++---------------- src/lua_baselib.c | 12 +++++----- src/p_floor.c | 2 +- src/p_inter.c | 2 +- src/p_map.c | 32 ++++++------------------- src/p_mobj.c | 26 +++++---------------- src/p_spec.c | 59 +++++++++++++++++++++++++---------------------- src/p_spec.h | 2 +- 8 files changed, 61 insertions(+), 101 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 230662d2a..6c268269d 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1533,20 +1533,16 @@ void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid) \return boolean */ -static UINT8 K_CheckOffroadCollide(mobj_t *mo, sector_t *sec) +static UINT8 K_CheckOffroadCollide(mobj_t *mo) { UINT8 i; - sector_t *sec2; I_Assert(mo != NULL); I_Assert(!P_MobjWasRemoved(mo)); - sec2 = P_ThingOnSpecial3DFloor(mo); - for (i = 2; i < 5; i++) { - if ((sec2 && GETSECSPECIAL(sec2->special, 1) == i) - || (P_IsObjectOnRealGround(mo, sec) && GETSECSPECIAL(sec->special, 1) == i)) + if (P_MobjTouchingSectorSpecial(mo, 1, i)) return i-1; } @@ -1561,25 +1557,16 @@ static UINT8 K_CheckOffroadCollide(mobj_t *mo, sector_t *sec) */ static void K_UpdateOffroad(player_t *player) { - fixed_t offroad; - sector_t *nextsector = R_PointInSubsector( - player->mo->x + player->mo->momx*2, player->mo->y + player->mo->momy*2)->sector; - UINT8 offroadstrength = K_CheckOffroadCollide(player->mo, nextsector); + fixed_t offroadstrength = (K_CheckOffroadCollide(player->mo) << FRACBITS); // If you are in offroad, a timer starts. if (offroadstrength) { - if (K_CheckOffroadCollide(player->mo, player->mo->subsector->sector) && player->kartstuff[k_offroad] == 0) - player->kartstuff[k_offroad] = TICRATE; + if (player->kartstuff[k_offroad] < offroadstrength) + player->kartstuff[k_offroad] += offroadstrength / TICRATE; - if (player->kartstuff[k_offroad] > 0) - { - offroad = (offroadstrength << FRACBITS) / TICRATE; - player->kartstuff[k_offroad] += offroad; - } - - if (player->kartstuff[k_offroad] > (offroadstrength << FRACBITS)) - player->kartstuff[k_offroad] = (offroadstrength << FRACBITS); + if (player->kartstuff[k_offroad] > offroadstrength) + player->kartstuff[k_offroad] = offroadstrength; } else player->kartstuff[k_offroad] = 0; diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 7464743c3..3d836dad2 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1313,15 +1313,15 @@ static int lib_pExplodeMissile(lua_State *L) return 0; } -static int lib_pPlayerTouchingSectorSpecial(lua_State *L) +static int lib_pMobjTouchingSectorSpecial(lua_State *L) { - player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER)); + mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); INT32 section = (INT32)luaL_checkinteger(L, 2); INT32 number = (INT32)luaL_checkinteger(L, 3); //HUDSAFE - if (!player) - return LUA_ErrInvalid(L, "player_t"); - LUA_PushUserdata(L, P_PlayerTouchingSectorSpecial(player, section, number), META_SECTOR); + if (!mo) + return LUA_ErrInvalid(L, "mobj_t"); + LUA_PushUserdata(L, P_MobjTouchingSectorSpecial(mo, section, number), META_SECTOR); return 1; } @@ -2736,7 +2736,7 @@ static luaL_Reg lib[] = { {"P_SetMobjStateNF",lib_pSetMobjStateNF}, {"P_DoSuperTransformation",lib_pDoSuperTransformation}, {"P_ExplodeMissile",lib_pExplodeMissile}, - {"P_PlayerTouchingSectorSpecial",lib_pPlayerTouchingSectorSpecial}, + {"P_MobjTouchingSectorSpecial",lib_pMobjTouchingSectorSpecial}, {"P_FindSpecialLineFromTag",lib_pFindSpecialLineFromTag}, {"P_SwitchWeather",lib_pSwitchWeather}, {"P_LinedefExecute",lib_pLinedefExecute}, diff --git a/src/p_floor.c b/src/p_floor.c index ccbfd6eae..a4e4f2747 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -2275,7 +2275,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime) continue; if (!(players[i].mo->subsector->sector == sec - || P_PlayerTouchingSectorSpecial(&players[i], 2, (GETSECSPECIAL(sec->special, 2))) == sec)) + || P_MobjTouchingSectorSpecial(players[i].mo, 2, (GETSECSPECIAL(sec->special, 2))) == sec)) continue; if (floortouch == true && P_IsObjectOnRealGround(players[i].mo, sec)) diff --git a/src/p_inter.c b/src/p_inter.c index 7a975951c..a1a44c998 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -925,7 +925,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) special->fuse = 1; special->flags2 |= MF2_JUSTATTACKED; - if (!P_PlayerTouchingSectorSpecial(player, 4, 2 + flagteam)) + if (!P_MobjTouchingSectorSpecial(player->mo, 4, 2 + flagteam)) { CONS_Printf(M_GetText("%s returned the %c%s%c to base.\n"), plname, flagcolor, flagtext, 0x80); diff --git a/src/p_map.c b/src/p_map.c index d4f2a94fa..22e624311 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2789,25 +2789,12 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) //All things are affected by their scale. fixed_t maxstep = FixedMul(MAXSTEPMOVE, mapobjectscale); - if (thing->player) - { - // If using type Section1:13, double the maxstep. - if (P_PlayerTouchingSectorSpecial(thing->player, 1, 13) - || GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 13) - maxstep <<= 1; - // If using type Section1:12, no maxstep. For ledges you don't want the player to climb! (see: Egg Zeppelin & SMK port walls) - else if (P_PlayerTouchingSectorSpecial(thing->player, 1, 12) - || GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 12) - maxstep = 0; - - // Don't 'step up' while springing, - // Only step up "if needed". - /* // SRB2kart - don't need - if (thing->state == &states[S_PLAY_SPRING] - && P_MobjFlip(thing)*thing->momz > FixedMul(FRACUNIT, thing->scale)) - maxstep = 0; - */ - } + // If using type Section1:13, double the maxstep. + if (P_MobjTouchingSectorSpecial(thing, 1, 13)) + maxstep <<= 1; + // If using type Section1:12, no maxstep. For short walls, like Egg Zeppelin + else if (P_MobjTouchingSectorSpecial(thing, 1, 12)) + maxstep = 0; if (thing->type == MT_SKIM) maxstep = 0; @@ -2830,12 +2817,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) return false; // mobj must lower itself to fit // Ramp test - if (maxstep > 0 && !( - thing->player && ( - P_PlayerTouchingSectorSpecial(thing->player, 1, 14) - || GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 14) - ) - ) + if ((maxstep > 0) && !(P_MobjTouchingSectorSpecial(thing, 1, 14))) { // If the floor difference is MAXSTEPMOVE or less, and the sector isn't Section1:14, ALWAYS // step down! Formerly required a Section1:13 sector for the full MAXSTEPMOVE, but no more. diff --git a/src/p_mobj.c b/src/p_mobj.c index f54eca41e..1fd846ff1 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8355,14 +8355,8 @@ void P_MobjThinker(mobj_t *mobj) P_Thrust(mobj, mobj->angle, thrustamount); - if (grounded) - { - sector_t *sec2 = P_ThingOnSpecial3DFloor(mobj); - if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1) - || (P_IsObjectOnRealGround(mobj, mobj->subsector->sector) - && GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1)) - K_DoPogoSpring(mobj, 0, 1); - } + if (P_MobjTouchingSectorSpecial(mobj, 3, 1)) + K_DoPogoSpring(mobj, 0, 1); if (mobj->threshold > 0) mobj->threshold--; @@ -8374,7 +8368,6 @@ void P_MobjThinker(mobj_t *mobj) } case MT_JAWZ: { - sector_t *sec2; mobj_t *ghost = P_SpawnGhostMobj(mobj); if (mobj->target && !P_MobjWasRemoved(mobj->target) && mobj->target->player) @@ -8392,10 +8385,7 @@ void P_MobjThinker(mobj_t *mobj) K_DriftDustHandling(mobj); - sec2 = P_ThingOnSpecial3DFloor(mobj); - if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1) - || (P_IsObjectOnRealGround(mobj, mobj->subsector->sector) - && GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1)) + if (P_MobjTouchingSectorSpecial(mobj, 3, 1)) K_DoPogoSpring(mobj, 0, 1); break; @@ -9602,13 +9592,9 @@ void P_MobjThinker(mobj_t *mobj) break; case MT_BLUEFLAG: case MT_REDFLAG: - { - sector_t *sec2; - sec2 = P_ThingOnSpecial3DFloor(mobj); - if ((sec2 && GETSECSPECIAL(sec2->special, 4) == 2) || (GETSECSPECIAL(mobj->subsector->sector->special, 4) == 2)) - mobj->fuse = 1; // Return to base. - break; - } + if (P_MobjTouchingSectorSpecial(mobj, 4, 2)) + mobj->fuse = 1; // Return to base. + break; case MT_CANNONBALL: #ifdef FLOORSPLATS R_AddFloorSplat(mobj->tracer->subsector, mobj->tracer, "TARGET", mobj->tracer->x, diff --git a/src/p_spec.c b/src/p_spec.c index 93e88e2ce..7786329ec 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3361,7 +3361,7 @@ boolean P_IsFlagAtBase(mobjtype_t flag) } // -// P_PlayerTouchingSectorSpecial +// P_MobjTouchingSectorSpecial // // Replaces the old player->specialsector. // This allows a player to touch more than @@ -3371,20 +3371,23 @@ boolean P_IsFlagAtBase(mobjtype_t flag) // the particular type that it finds. // Returns NULL if it doesn't find it. // -sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 number) +// Sal: There was absolutely no reason for +// this to be a player_t only function. +// +sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number) { msecnode_t *node; ffloor_t *rover; - if (!player->mo) + if (!mo) return NULL; // Check default case first - if (GETSECSPECIAL(player->mo->subsector->sector->special, section) == number) - return player->mo->subsector->sector; + if (GETSECSPECIAL(mo->subsector->sector->special, section) == number) + return mo->subsector->sector; // Hmm.. maybe there's a FOF that has it... - for (rover = player->mo->subsector->sector->ffloors; rover; rover = rover->next) + for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next) { fixed_t topheight, bottomheight; @@ -3394,37 +3397,38 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n if (!(rover->flags & FF_EXISTS)) continue; - topheight = P_GetSpecialTopZ(player->mo, sectors + rover->secnum, player->mo->subsector->sector); - bottomheight = P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, player->mo->subsector->sector); + topheight = P_GetSpecialTopZ(mo, sectors + rover->secnum, mo->subsector->sector); + bottomheight = P_GetSpecialBottomZ(mo, sectors + rover->secnum, mo->subsector->sector); // Check the 3D floor's type... - if (rover->flags & FF_BLOCKPLAYER) + if (((rover->flags & FF_BLOCKPLAYER) && mo->player) + || ((rover->flags & FF_BLOCKOTHERS) && !mo->player)) { // Thing must be on top of the floor to be affected... if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)) { - if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != topheight) + if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != topheight) continue; } else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)) { - if (!(player->mo->eflags & MFE_VERTICALFLIP) - || player->mo->z + player->mo->height != bottomheight) + if (!(mo->eflags & MFE_VERTICALFLIP) + || mo->z + mo->height != bottomheight) continue; } else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH) { - if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == bottomheight) - || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == topheight))) + if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == bottomheight) + || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == topheight))) continue; } } else { // Water and DEATH FOG!!! heh - if (player->mo->z > topheight || (player->mo->z + player->mo->height) < bottomheight) + if (mo->z > topheight || (mo->z + mo->height) < bottomheight) continue; } @@ -3432,13 +3436,13 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n return rover->master->frontsector; } - for (node = player->mo->touching_sectorlist; node; node = node->m_sectorlist_next) + for (node = mo->touching_sectorlist; node; node = node->m_sectorlist_next) { if (GETSECSPECIAL(node->m_sector->special, section) == number) { // This sector has the special we're looking for, but // are we allowed to touch it? - if (node->m_sector == player->mo->subsector->sector + if (node->m_sector == mo->subsector->sector || (node->m_sector->flags & SF_TRIGGERSPECIAL_TOUCH)) return node->m_sector; } @@ -3454,42 +3458,43 @@ sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 n if (!(rover->flags & FF_EXISTS)) continue; - topheight = P_GetSpecialTopZ(player->mo, sectors + rover->secnum, player->mo->subsector->sector); - bottomheight = P_GetSpecialBottomZ(player->mo, sectors + rover->secnum, player->mo->subsector->sector); + topheight = P_GetSpecialTopZ(mo, sectors + rover->secnum, mo->subsector->sector); + bottomheight = P_GetSpecialBottomZ(mo, sectors + rover->secnum, mo->subsector->sector); // Check the 3D floor's type... - if (rover->flags & FF_BLOCKPLAYER) + if (((rover->flags & FF_BLOCKPLAYER) && mo->player) + || ((rover->flags & FF_BLOCKOTHERS) && !mo->player)) { // Thing must be on top of the floor to be affected... if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING)) { - if ((player->mo->eflags & MFE_VERTICALFLIP) || player->mo->z != topheight) + if ((mo->eflags & MFE_VERTICALFLIP) || mo->z != topheight) continue; } else if ((rover->master->frontsector->flags & SF_FLIPSPECIAL_CEILING) && !(rover->master->frontsector->flags & SF_FLIPSPECIAL_FLOOR)) { - if (!(player->mo->eflags & MFE_VERTICALFLIP) - || player->mo->z + player->mo->height != bottomheight) + if (!(mo->eflags & MFE_VERTICALFLIP) + || mo->z + mo->height != bottomheight) continue; } else if (rover->master->frontsector->flags & SF_FLIPSPECIAL_BOTH) { - if (!((player->mo->eflags & MFE_VERTICALFLIP && player->mo->z + player->mo->height == bottomheight) - || (!(player->mo->eflags & MFE_VERTICALFLIP) && player->mo->z == topheight))) + if (!((mo->eflags & MFE_VERTICALFLIP && mo->z + mo->height == bottomheight) + || (!(mo->eflags & MFE_VERTICALFLIP) && mo->z == topheight))) continue; } } else { // Water and DEATH FOG!!! heh - if (player->mo->z > topheight || (player->mo->z + player->mo->height) < bottomheight) + if (mo->z > topheight || (mo->z + mo->height) < bottomheight) continue; } // This FOF has the special we're looking for, but are we allowed to touch it? - if (node->m_sector == player->mo->subsector->sector + if (node->m_sector == mo->subsector->sector || (rover->master->frontsector->flags & SF_TRIGGERSPECIAL_TOUCH)) return rover->master->frontsector; } diff --git a/src/p_spec.h b/src/p_spec.h index b604ac951..8431fcc75 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -37,7 +37,7 @@ void P_SpawnSpecials(INT32 fromnetsave); // every tic void P_UpdateSpecials(void); -sector_t *P_PlayerTouchingSectorSpecial(player_t *player, INT32 section, INT32 number); +sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number); void P_PlayerInSpecialSector(player_t *player); void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *roversector); From addb0d0a663380d3f484b94d169ab4ef2c25d3ce Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 25 Oct 2019 23:35:31 -0400 Subject: [PATCH 135/163] Fix time limit --- src/d_netcmd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index db0c00086..70dff2fcf 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -424,13 +424,13 @@ consvar_t cv_timetic = {"timerres", "Normal", CV_SAVE|CV_NOSHOWHELP, timetic_con static CV_PossibleValue_t pointlimit_cons_t[] = {{0, "MIN"}, {999999990, "MAX"}, {0, NULL}}; consvar_t cv_pointlimit = {"pointlimit", "0", CV_NETVAR|CV_CALL|CV_NOINIT, pointlimit_cons_t, PointLimit_OnChange, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t timelimit_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NULL}}; +static CV_PossibleValue_t timelimit_cons_t[] = {{0, "MIN"}, {1800, "MAX"}, {0, NULL}}; consvar_t cv_timelimit = {"timelimit", "0", CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t, TimeLimit_OnChange, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, NULL}}; +static CV_PossibleValue_t numlaps_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, NULL}}; consvar_t cv_numlaps = {"numlaps", "3", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t, NumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL}; -static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, "Map default"}, {0, NULL}}; +static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {99, "MAX"}, {0, "Map default"}, {0, NULL}}; consvar_t cv_basenumlaps = {"basenumlaps", "Map default", CV_NETVAR|CV_CALL|CV_CHEAT, basenumlaps_cons_t, BaseNumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_forceskin = {"forceskin", "Off", CV_NETVAR|CV_CALL|CV_CHEAT, Forceskin_cons_t, ForceSkin_OnChange, 0, NULL, NULL, 0, 0, NULL}; From 522959e762711247098764f784f92078f35b5485 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sat, 26 Oct 2019 23:11:19 -0400 Subject: [PATCH 136/163] Disable charging drift sparks in bounce pad state --- 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 230662d2a..8db2b0d81 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6609,7 +6609,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) } } - K_KartDrift(player, onground); + K_KartDrift(player, P_IsObjectOnGround(player->mo)); // Not using onground, since we don't want this affected by spring pads // Quick Turning // You can't turn your kart when you're not moving. From d52e7a652e61ff3b2412b876886061439ccc9e71 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 27 Oct 2019 09:03:35 -0400 Subject: [PATCH 137/163] Faster waterskipping --- src/p_map.c | 10 +++++++--- src/p_mobj.c | 25 ++++++++++--------------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/src/p_map.c b/src/p_map.c index d4f2a94fa..e9bc95712 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2787,18 +2787,22 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) if (!(thing->flags & MF_NOCLIP)) { //All things are affected by their scale. - fixed_t maxstep = FixedMul(MAXSTEPMOVE, mapobjectscale); + const fixed_t maxstepmove = FixedMul(MAXSTEPMOVE, mapobjectscale); + fixed_t maxstep = maxstepmove; if (thing->player) { + if (thing->player->kartstuff[k_waterskip]) + maxstep += maxstepmove; // Force some stepmove when waterskipping + // If using type Section1:13, double the maxstep. if (P_PlayerTouchingSectorSpecial(thing->player, 1, 13) || GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 13) - maxstep <<= 1; + maxstep += maxstepmove; // If using type Section1:12, no maxstep. For ledges you don't want the player to climb! (see: Egg Zeppelin & SMK port walls) else if (P_PlayerTouchingSectorSpecial(thing->player, 1, 12) || GETSECSPECIAL(R_PointInSubsector(x, y)->sector->special, 1) == 12) - maxstep = 0; + maxstep -= maxstepmove; // Don't 'step up' while springing, // Only step up "if needed". diff --git a/src/p_mobj.c b/src/p_mobj.c index f54eca41e..b220ff4e6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1268,6 +1268,8 @@ fixed_t P_GetMobjGravity(mobj_t *mo) P_PlayerFlip(mo); if (mo->player->kartstuff[k_pogospring]) gravityadd = (5*gravityadd)/2; + if (mo->player->kartstuff[k_waterskip]) + gravityadd = (4*gravityadd)/3; } else { @@ -3301,26 +3303,19 @@ void P_MobjCheckWater(mobj_t *mobj) // skipping stone! if (p && p->kartstuff[k_waterskip] < 2 && ((p->speed/3 > abs(mobj->momz)) // Going more forward than horizontal, so you can skip across the water. - || (p->speed > K_GetKartSpeed(p,false)/3 && p->kartstuff[k_waterskip])) // Already skipped once, so you can skip once more! + || (p->speed > 20*mapobjectscale && p->kartstuff[k_waterskip])) // Already skipped once, so you can skip once more! && ((!(mobj->eflags & MFE_VERTICALFLIP) && thingtop - mobj->momz > mobj->watertop) || ((mobj->eflags & MFE_VERTICALFLIP) && mobj->z - mobj->momz < mobj->waterbottom))) { - const fixed_t min = 6<momx = mobj->momx/2; - mobj->momy = mobj->momy/2; - mobj->momz = -mobj->momz/2; + mobj->momx = (4*mobj->momx)/5; + mobj->momy = (4*mobj->momy)/5; - if (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->momz < FixedMul(min, mobj->scale)) - mobj->momz = FixedMul(min, mobj->scale); - else if (mobj->eflags & MFE_VERTICALFLIP && mobj->momz > FixedMul(-min, mobj->scale)) - mobj->momz = FixedMul(-min, mobj->scale); - - /*if (!(mobj->eflags & MFE_VERTICALFLIP) && mobj->momz > FixedMul(max, mobj->scale)) - mobj->momz = FixedMul(max, mobj->scale); - else if (mobj->eflags & MFE_VERTICALFLIP && mobj->momz < FixedMul(-max, mobj->scale)) - mobj->momz = FixedMul(-max, mobj->scale);*/ + if (mobj->eflags & MFE_VERTICALFLIP) + mobj->momz = FixedMul(-hop, mobj->scale); + else + mobj->momz = FixedMul(hop, mobj->scale); p->kartstuff[k_waterskip]++; } From 7c0ca5bf7cdc62f7ff4892499e3638a8ae1664b0 Mon Sep 17 00:00:00 2001 From: James R Date: Sun, 27 Oct 2019 10:33:40 -0700 Subject: [PATCH 138/163] Move gamedata param to cover -resetdata --- src/g_game.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 15a22f493..ae47e633f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4079,14 +4079,14 @@ void G_LoadGameData(void) // Allow saving of gamedata beyond this point gamedataloaded = true; - if (M_CheckParm("-resetdata")) - return; // Don't load (essentially, reset). - if (M_CheckParm("-gamedata") && M_IsNextParm()) { strlcpy(gamedatafilename, M_GetNextParm(), sizeof gamedatafilename); } + if (M_CheckParm("-resetdata")) + return; // Don't load (essentially, reset). + length = FIL_ReadFile(va(pandf, srb2home, gamedatafilename), &savebuffer); if (!length) // Aw, no game data. Their loss! return; From b948f74b4f573dfc792961bb39151ca35f01e020 Mon Sep 17 00:00:00 2001 From: James R Date: Mon, 28 Oct 2019 00:04:30 -0700 Subject: [PATCH 139/163] Add overflow checks so we I_Error instead of death crash into oblivion You'd love to know how we even reached (size_t)-1. --- src/z_zone.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/z_zone.c b/src/z_zone.c index a3e13422f..2c0ddc295 100644 --- a/src/z_zone.c +++ b/src/z_zone.c @@ -210,7 +210,11 @@ void Z_Free(void *ptr) static void *xm(size_t size) { const size_t padedsize = size+sizeof (size_t); - void *p = malloc(padedsize); + void *p; + + if (padedsize < size)/* overflow check */ + I_Error("You are allocating memory too large!"); + p = malloc(padedsize); if (p == NULL) { @@ -254,6 +258,9 @@ void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) CONS_Debug(DBG_MEMORY, "Z_Malloc %s:%d\n", file, line); #endif + if (blocksize < size)/* overflow check */ + I_Error("You are allocating memory too large!"); + block = xm(sizeof *block); #ifdef HAVE_VALGRIND padsize += (1< Date: Fri, 8 Nov 2019 23:25:46 -0500 Subject: [PATCH 140/163] 3D signpost --- src/dehacked.c | 27 +++-------- src/info.c | 58 ++++++++++++++---------- src/info.h | 27 +++-------- src/p_enemy.c | 33 -------------- src/p_mobj.c | 118 +++++++++++++++++++++++++++++++++++++++---------- src/p_spec.c | 97 +++++++++++++++++++++++++++++++--------- 6 files changed, 213 insertions(+), 147 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 5f9249d89..7687803d3 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1774,7 +1774,6 @@ static actionpointer_t actionpointers[] = {{A_GrenadeRing}, "A_GRENADERING"}, // SRB2kart {{A_SetSolidSteam}, "A_SETSOLIDSTEAM"}, {{A_UnsetSolidSteam}, "A_UNSETSOLIDSTEAM"}, - {{A_SignPlayer}, "A_SIGNPLAYER"}, {{A_OverlayThink}, "A_OVERLAYTHINK"}, {{A_JetChase}, "A_JETCHASE"}, {{A_JetbThink}, "A_JETBTHINK"}, @@ -4887,27 +4886,10 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_BUBBLES2", // Level End Sign - "S_SIGN1", - "S_SIGN2", - "S_SIGN3", - "S_SIGN4", - "S_SIGN5", - "S_SIGN6", - "S_SIGN7", - "S_SIGN8", - "S_SIGN9", - "S_SIGN10", - "S_SIGN11", - "S_SIGN12", - "S_SIGN13", - "S_SIGN14", - "S_SIGN15", - "S_SIGN16", - "S_SIGN17", - "S_SIGN18", - "S_SIGN19", - "S_SIGN20", - "S_SIGN_END", + "S_SIGN_POLE", + "S_SIGN_BACK", + "S_SIGN_SIDE", + "S_SIGN_FACE", // Steam Riser "S_STEAM1", @@ -7363,6 +7345,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s // Interactive Objects "MT_BUBBLES", // Bubble source "MT_SIGN", // Level end sign + "MT_SIGN_PIECE", "MT_SPIKEBALL", // Spike Ball "MT_SPECIALSPIKEBALL", "MT_SPINFIRE", diff --git a/src/info.c b/src/info.c index 4f448cc00..7476a9344 100644 --- a/src/info.c +++ b/src/info.c @@ -193,7 +193,7 @@ state_t states[NUMSTATES] = {SPR_NULL, 0, 18, {NULL}, 0, 4, S_NULL}, // S_PLAY_ICON3 // Level end sign (uses player sprite) - {SPR_PLAY, 18, 1, {NULL}, 0, 24, S_PLAY_SIGN}, // S_PLAY_SIGN S + {SPR_PLAY, 18|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_PLAY_SIGN}, // S_PLAY_SIGN // Blue Crawla {SPR_POSS, 0, 5, {A_Look}, 0, 0, S_POSS_STND}, // S_POSS_STND @@ -1063,27 +1063,10 @@ state_t states[NUMSTATES] = {SPR_BUBL, 1, 8, {A_BubbleCheck}, 0, 0, S_BUBBLES1}, // S_BUBBLES2 // Level End Sign - {SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN2}, // S_SIGN1 - {SPR_SIGN, 1, 1, {NULL}, 0, 0, S_SIGN3}, // S_SIGN2 - {SPR_SIGN, 2, 1, {NULL}, 0, 0, S_SIGN4}, // S_SIGN3 - {SPR_SIGN, 3, 1, {NULL}, 0, 0, S_SIGN5}, // S_SIGN4 - {SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN6}, // S_SIGN5 - {SPR_SIGN, 1, 1, {NULL}, 0, 0, S_SIGN7}, // S_SIGN6 - {SPR_SIGN, 2, 1, {NULL}, 0, 0, S_SIGN8}, // S_SIGN7 - {SPR_SIGN, 4, 1, {NULL}, 0, 0, S_SIGN9}, // S_SIGN8 - {SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN10}, // S_SIGN9 - {SPR_SIGN, 1, 1, {NULL}, 0, 0, S_SIGN11}, // S_SIGN10 - {SPR_SIGN, 2, 1, {NULL}, 0, 0, S_SIGN12}, // S_SIGN11 - {SPR_SIGN, 5, 1, {NULL}, 0, 0, S_SIGN13}, // S_SIGN12 - {SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN14}, // S_SIGN13 - {SPR_SIGN, 1, 1, {NULL}, 0, 0, S_SIGN15}, // S_SIGN14 - {SPR_SIGN, 2, 1, {NULL}, 0, 0, S_SIGN16}, // S_SIGN15 - {SPR_SIGN, 6, 1, {NULL}, 0, 0, S_SIGN17}, // S_SIGN16 - {SPR_SIGN, 0, 1, {NULL}, 0, 0, S_SIGN18}, // S_SIGN17 - {SPR_SIGN, 1, 1, {NULL}, 0, 0, S_SIGN19}, // S_SIGN18 - {SPR_SIGN, 2, 1, {NULL}, 0, 0, S_SIGN20}, // S_SIGN19 - {SPR_SIGN, 7, 1, {NULL}, 0, 0, S_SIGN1}, // S_SIGN20 - {SPR_SIGN, 8, -1, {A_SignPlayer}, 0, 0, S_NULL}, // S_SIGN_END + {SPR_SIGN, 0, -1, {NULL}, 0, 0, S_SIGN_POLE}, // S_SIGN_POLE + {SPR_SIGN, 1|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_SIGN_BACK}, // S_SIGN_BACK + {SPR_SIGN, 2|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_SIGN_SIDE}, // S_SIGN_SIDE + {SPR_SIGN, 3|FF_PAPERSPRITE, -1, {NULL}, 0, 0, S_SIGN_FACE}, // S_SIGN_FACE // Steam Riser {SPR_STEM, 0, 2, {A_SetSolidSteam}, 0, 0, S_STEAM2}, // S_STEAM1 @@ -6434,7 +6417,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 501, // doomednum S_INVISIBLE, // spawnstate 1000, // spawnhealth - S_PLAY_SIGN, // seestate + S_NULL, // seestate sfx_s3kb8, // seesound 8, // reactiontime sfx_s3k7e, // attacksound @@ -6448,7 +6431,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // deathsound 8, // speed 8*FRACUNIT, // radius - 32*FRACUNIT, // height + 48*FRACUNIT, // height 0, // display offset 16, // mass 0, // damage @@ -6457,6 +6440,33 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, + { // MT_SIGN_PIECE + -1, // doomednum + S_INVISIBLE, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 8, // speed + 8*FRACUNIT, // radius + 48*FRACUNIT, // height + 0, // display offset + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_NOTHINK|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + { // MT_SPIKEBALL -1, // doomednum S_SPIKEBALL1, // spawnstate diff --git a/src/info.h b/src/info.h index 27488d916..f3450ff11 100644 --- a/src/info.h +++ b/src/info.h @@ -63,7 +63,6 @@ void A_ThrownRing(); // Sparkle trail for red ring void A_GrenadeRing(); // SRB2kart void A_SetSolidSteam(); void A_UnsetSolidSteam(); -void A_SignPlayer(); void A_OverlayThink(); void A_JetChase(); void A_JetbThink(); // Jetty-Syn Bomber Thinker @@ -1776,27 +1775,10 @@ typedef enum state S_BUBBLES2, // Level End Sign - S_SIGN1, - S_SIGN2, - S_SIGN3, - S_SIGN4, - S_SIGN5, - S_SIGN6, - S_SIGN7, - S_SIGN8, - S_SIGN9, - S_SIGN10, - S_SIGN11, - S_SIGN12, - S_SIGN13, - S_SIGN14, - S_SIGN15, - S_SIGN16, - S_SIGN17, - S_SIGN18, - S_SIGN19, - S_SIGN20, - S_SIGN_END, + S_SIGN_POLE, + S_SIGN_BACK, + S_SIGN_SIDE, + S_SIGN_FACE, // Steam Riser S_STEAM1, @@ -4284,6 +4266,7 @@ typedef enum mobj_type // Interactive Objects MT_BUBBLES, // Bubble source MT_SIGN, // Level end sign + MT_SIGN_PIECE, MT_SPIKEBALL, // Spike Ball MT_SPECIALSPIKEBALL, MT_SPINFIRE, diff --git a/src/p_enemy.c b/src/p_enemy.c index 76f6b3159..64a3ee12e 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -117,7 +117,6 @@ void A_ThrownRing(mobj_t *actor); void A_GrenadeRing(mobj_t *actor); void A_SetSolidSteam(mobj_t *actor); void A_UnsetSolidSteam(mobj_t *actor); -void A_SignPlayer(mobj_t *actor); void A_OverlayThink(mobj_t *actor); void A_JetChase(mobj_t *actor); void A_JetbThink(mobj_t *actor); @@ -4180,38 +4179,6 @@ void A_UnsetSolidSteam(mobj_t *actor) actor->flags |= MF_NOCLIP; } -// Function: A_SignPlayer -// -// Description: Changes the state of a level end sign to reflect the player that hit it. -// -// var1 = unused -// var2 = unused -// -void A_SignPlayer(mobj_t *actor) -{ - mobj_t *ov; -#ifdef HAVE_BLUA - if (LUA_CallAction("A_SignPlayer", actor)) - return; -#endif - if (!actor->target) - return; - - if (!actor->target->player) - return; - - // Set the sign to be an appropriate background color for this player's skincolor. - actor->color = KartColor_Opposite[actor->target->player->skincolor*2]; - actor->frame += KartColor_Opposite[actor->target->player->skincolor*2+1]; - - // spawn an overlay of the player's face. - ov = P_SpawnMobj(actor->x, actor->y, actor->z, MT_OVERLAY); - P_SetTarget(&ov->target, actor); - ov->color = actor->target->player->skincolor; - ov->skin = &skins[actor->target->player->skin]; - P_SetMobjState(ov, actor->info->seestate); // S_PLAY_SIGN -} - // Function: A_OverlayThink // // Description: Moves the overlay to the position of its target. diff --git a/src/p_mobj.c b/src/p_mobj.c index b220ff4e6..ffdbebf4a 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -1329,9 +1329,6 @@ fixed_t P_GetMobjGravity(mobj_t *mo) case MT_JAWZ_DUD: gravityadd = (5*gravityadd)/2; break; - case MT_SIGN: - gravityadd /= 8; - break; case MT_KARMAFIREWORK: gravityadd /= 3; break; @@ -8957,31 +8954,104 @@ void P_MobjThinker(mobj_t *mobj) } break; case MT_SIGN: // Kart's unique sign behavior - if (mobj->movecount) + if (mobj->movecount != 0) { - if (mobj->z <= mobj->movefactor) + mobj_t *cur = mobj->hnext; + SINT8 newskin = -1; + UINT8 newcolor = SKINCOLOR_NONE; + angle_t endangle = FixedAngle(mobj->extravalue1 << FRACBITS); + + if (mobj->movecount == 1) { - P_SetMobjState(mobj, S_SIGN_END); - if (mobj->info->attacksound) - S_StartSound(mobj, mobj->info->attacksound); - mobj->flags |= MF_NOGRAVITY; // ? - mobj->flags &= ~MF_NOCLIPHEIGHT; - mobj->z = mobj->movefactor; - mobj->movecount = 0; - } - else - { - P_SpawnMobj(mobj->x + (P_RandomRange(-48,48)*mobj->scale), - mobj->y + (P_RandomRange(-48,48)*mobj->scale), - mobj->z + (24*mobj->scale) + (P_RandomRange(-8,8)*mobj->scale), - MT_SIGNSPARKLE); - mobj->flags &= ~MF_NOGRAVITY; - if (abs(mobj->z - mobj->movefactor) <= (512*mobj->scale) && !mobj->cvmem) + if (mobj->z + mobj->momz <= mobj->movefactor) { - if (mobj->info->seesound) - S_StartSound(mobj, mobj->info->seesound); - mobj->cvmem = 1; + if (mobj->info->attacksound) + S_StartSound(mobj, mobj->info->attacksound); + + mobj->z = mobj->movefactor; + mobj->momz = 0; + mobj->movecount = 2; + + newskin = ((skin_t*)mobj->target->skin)-skins; + newcolor = mobj->target->player->skincolor; } + else + { + fixed_t g = (6*mobj->scale); + UINT16 ticstilimpact = abs(mobj->z - mobj->movefactor) / g; + + P_SpawnMobj( + mobj->x + FixedMul(48*mobj->scale, FINECOSINE(mobj->angle >> ANGLETOFINESHIFT)), + mobj->y + FixedMul(48*mobj->scale, FINESINE(mobj->angle >> ANGLETOFINESHIFT)), + mobj->z + ((24 + ((leveltime % 4) * 8)) * mobj->scale), + MT_SIGNSPARKLE + ); + + if (ticstilimpact == (3*TICRATE/2)) + { + if (mobj->info->seesound) + S_StartSound(mobj, mobj->info->seesound); + } + + mobj->angle += ANGLE_45; + mobj->momz = -g; + + if (mobj->angle == endangle + ANGLE_180) + { + if (ticstilimpact <= 8) + { + newskin = ((skin_t*)mobj->target->skin)-skins; + newcolor = mobj->target->player->skincolor; + } + else + { + newskin = leveltime % numskins; + newcolor = skins[newskin].prefcolor; + } + } + } + } + else if (mobj->movecount == 2) + { + if (mobj->angle != endangle) + mobj->angle += ANGLE_11hh; + } + + while (cur && !P_MobjWasRemoved(cur)) + { + fixed_t amt = cur->extravalue1 * mobj->scale; + angle_t dir = mobj->angle + (cur->extravalue2 * ANGLE_90); + fixed_t z = mobj->z + (23*mobj->scale); + + if (cur->state == &states[S_SIGN_FACE]) + { + if (newcolor != SKINCOLOR_NONE) + { + cur->color = KartColor_Opposite[newcolor*2]; + cur->frame = states[S_SIGN_FACE].frame + KartColor_Opposite[newcolor*2+1]; + } + } + else if (cur->state == &states[S_PLAY_SIGN]) + { + z += (5*mobj->scale); + amt += 1; + + if (newskin != -1) + cur->skin = &skins[newskin]; + + if (newcolor != SKINCOLOR_NONE) + cur->color = newcolor; + } + + P_TeleportMove( + cur, + mobj->x + FixedMul(amt, FINECOSINE(dir >> ANGLETOFINESHIFT)), + mobj->y + FixedMul(amt, FINESINE(dir >> ANGLETOFINESHIFT)), + z + ); + cur->angle = dir + ANGLE_90; + + cur = cur->hnext; } } break; diff --git a/src/p_spec.c b/src/p_spec.c index 93e88e2ce..0eb618c45 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3232,6 +3232,76 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) } } +static void P_SetupSignObject(mobj_t *sign, mobj_t *pmo) +{ + mobj_t *cur = sign, *prev = NULL; + + // Setup the sign itself + P_SetTarget(&sign->target, pmo); + P_SetMobjState(sign, S_SIGN_POLE); + + sign->movefactor = sign->z; + sign->z += (768*sign->scale) * P_MobjFlip(sign); + sign->movecount = 1; + sign->extravalue1 = AngleFixed(sign->angle) >> FRACBITS; + + // Setup the overlay pieces + // Front + cur->hnext = P_SpawnMobj(sign->x, sign->y, sign->z, MT_SIGN_PIECE); + P_SetTarget(&cur->hnext->target, sign); + P_SetMobjState(cur->hnext, S_SIGN_FACE); + cur->hnext->extravalue1 = 6; + cur->hnext->extravalue2 = 2; + + prev = cur; + cur = cur->hnext; + cur->hprev = prev; + + // Player icon + cur->hnext = P_SpawnMobj(sign->x, sign->y, sign->z, MT_SIGN_PIECE); + P_SetTarget(&cur->hnext->target, sign); + cur->hnext->skin = pmo->skin; + P_SetMobjState(cur->hnext, S_PLAY_SIGN); + cur->hnext->extravalue1 = 7; + cur->hnext->extravalue2 = 2; + + prev = cur; + cur = cur->hnext; + cur->hprev = prev; + + // Back + cur->hnext = P_SpawnMobj(sign->x, sign->y, sign->z, MT_SIGN_PIECE); + P_SetTarget(&cur->hnext->target, sign); + P_SetMobjState(cur->hnext, S_SIGN_BACK); + cur->hnext->extravalue1 = 6; + cur->hnext->extravalue2 = 0; + + prev = cur; + cur = cur->hnext; + cur->hprev = prev; + + // Sides + cur->hnext = P_SpawnMobj(sign->x, sign->y, sign->z, MT_SIGN_PIECE); + P_SetTarget(&cur->hnext->target, sign); + P_SetMobjState(cur->hnext, S_SIGN_SIDE); + cur->hnext->extravalue1 = 30; + cur->hnext->extravalue2 = 1; + + prev = cur; + cur = cur->hnext; + cur->hprev = prev; + + cur->hnext = P_SpawnMobj(sign->x, sign->y, sign->z, MT_SIGN_PIECE); + P_SetTarget(&cur->hnext->target, sign); + P_SetMobjState(cur->hnext, S_SIGN_SIDE); + cur->hnext->extravalue1 = 30; + cur->hnext->extravalue2 = 3; + + prev = cur; + cur = cur->hnext; + cur->hprev = prev; +} + // // P_SetupSignExit // @@ -3257,13 +3327,7 @@ void P_SetupSignExit(player_t *player) if (thing->state != &states[thing->info->spawnstate]) continue; - P_SetTarget(&thing->target, player->mo); - P_SetMobjState(thing, S_SIGN1); - - // SRB2Kart: Set sign spinning variables - thing->movefactor = thing->z; - thing->z += (768*thing->scale) * P_MobjFlip(thing); - thing->movecount = 1; + P_SetupSignObject(thing, player->mo); ++numfound; } @@ -3285,14 +3349,7 @@ void P_SetupSignExit(player_t *player) if (thing->state != &states[thing->info->spawnstate]) continue; - P_SetTarget(&thing->target, player->mo); - P_SetMobjState(thing, S_SIGN1); - - // SRB2Kart: Set sign spinning variables - thing->movefactor = thing->z; - thing->z += (768*thing->scale) * P_MobjFlip(thing); - thing->movecount = 1; - + P_SetupSignObject(thing, player->mo); ++numfound; } @@ -3300,14 +3357,10 @@ void P_SetupSignExit(player_t *player) return; // SRB2Kart: FINALLY, add in an alternative if no place is found - if (player->mo) + if (player->mo && !P_MobjWasRemoved(player->mo)) { - mobj_t *sign = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + (768*mapobjectscale), MT_SIGN); - - P_SetTarget(&sign->target, player->mo); - P_SetMobjState(sign, S_SIGN1); - sign->movefactor = player->mo->floorz; - sign->movecount = 1; + thing = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->floorz, MT_SIGN); + P_SetupSignObject(thing, player->mo); } } From bba8861d2f0c37defca40d2f5289869ddd23c15a Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Fri, 8 Nov 2019 23:33:59 -0500 Subject: [PATCH 141/163] Set angle for ties --- src/p_spec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p_spec.c b/src/p_spec.c index 0eb618c45..9f8bc6f4b 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3360,6 +3360,7 @@ void P_SetupSignExit(player_t *player) if (player->mo && !P_MobjWasRemoved(player->mo)) { thing = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->floorz, MT_SIGN); + thing->angle = player->mo->angle; P_SetupSignObject(thing, player->mo); } } From 80bb59031c4bbf360fd45b875f5c85728feae466 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Thu, 14 Nov 2019 04:26:41 -0500 Subject: [PATCH 142/163] Blizzard weather option + much more sane workflow for adding new precipitation options "precipprops" lets you create a new precipitation type by picking a mobj type to use, how many random states it has, and flags for effects such as thunder/lightning. Seesound on the mobj type sets an ambient sound (like rain drops) and mass sets the sound's frequency in tics. This could open up the possibility for SOC/Lua Weather options later. --- src/dehacked.c | 12 ++- src/doomstat.h | 35 +++++-- src/g_game.c | 15 ++- src/hardware/hw_main.c | 5 +- src/info.c | 74 ++++++++++---- src/info.h | 7 ++ src/p_floor.c | 1 + src/p_mobj.c | 224 ++++++++++++++++++++--------------------- src/p_mobj.h | 31 +++--- src/p_spec.c | 221 +++++++++------------------------------- src/p_spec.h | 2 +- src/p_tick.c | 10 -- src/r_things.c | 6 +- 13 files changed, 283 insertions(+), 360 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 5f9249d89..af1ee934e 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -5690,6 +5690,11 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_SNOW2", "S_SNOW3", + // Blizzard Snowball + "S_BLIZZARDSNOW1", + "S_BLIZZARDSNOW2", + "S_BLIZZARDSNOW3", + // Water Splish "S_SPLISH1", "S_SPLISH2", @@ -7589,6 +7594,7 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s // Environmental Effects "MT_RAIN", // Rain "MT_SNOWFLAKE", // Snowflake + "MT_BLIZZARDSNOW", // Blizzard Snowball "MT_SPLISH", // Water splish! "MT_SMOKE", "MT_SMALLBUBBLE", // small bubble @@ -8700,10 +8706,10 @@ struct { // Precipitation {"PRECIP_NONE",PRECIP_NONE}, - {"PRECIP_STORM",PRECIP_STORM}, - {"PRECIP_SNOW",PRECIP_SNOW}, {"PRECIP_RAIN",PRECIP_RAIN}, - {"PRECIP_BLANK",PRECIP_BLANK}, + {"PRECIP_SNOW",PRECIP_SNOW}, + {"PRECIP_BLIZZARD",PRECIP_BLIZZARD}, + {"PRECIP_STORM",PRECIP_STORM}, {"PRECIP_STORM_NORAIN",PRECIP_STORM_NORAIN}, {"PRECIP_STORM_NOSTRIKES",PRECIP_STORM_NOSTRIKES}, diff --git a/src/doomstat.h b/src/doomstat.h index 59e2bd5c4..cdc09cf86 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -41,18 +41,37 @@ extern UINT32 mapmusposition; extern INT16 maptol; extern UINT8 globalweather; -extern INT32 curWeather; +extern UINT8 curWeather; extern INT32 cursaveslot; extern INT16 lastmapsaved; extern boolean gamecomplete; -#define PRECIP_NONE 0 -#define PRECIP_STORM 1 -#define PRECIP_SNOW 2 -#define PRECIP_RAIN 3 -#define PRECIP_BLANK 4 -#define PRECIP_STORM_NORAIN 5 -#define PRECIP_STORM_NOSTRIKES 6 +typedef enum +{ + PRECIP_NONE = 0, + PRECIP_RAIN, + PRECIP_SNOW, + PRECIP_BLIZZARD, + PRECIP_STORM, + PRECIP_STORM_NORAIN, + PRECIP_STORM_NOSTRIKES, + MAXPRECIP +} preciptype_t; + +typedef enum +{ + PRECIPFX_THUNDER = 1, + PRECIPFX_LIGHTNING = 1<<1 +} precipeffect_t; + +typedef struct +{ + mobjtype_t type; + precipeffect_t effects; + UINT8 randomstates; +} precipprops_t; + +extern precipprops_t precipprops[MAXPRECIP]; // Set if homebrew PWAD stuff has been added. extern boolean modifiedgame; diff --git a/src/g_game.c b/src/g_game.c index d4d48f7c2..e15968b3e 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -83,8 +83,21 @@ UINT32 mapmusposition; // Position to jump to INT16 gamemap = 1; INT16 maptol; + UINT8 globalweather = 0; -INT32 curWeather = PRECIP_NONE; +UINT8 curWeather = PRECIP_NONE; + +precipprops_t precipprops[MAXPRECIP] = +{ + {MT_NULL, 0, 0}, // PRECIP_NONE + {MT_RAIN, 0, 0}, // PRECIP_RAIN + {MT_SNOWFLAKE, 0, 2}, // PRECIP_SNOW + {MT_BLIZZARDSNOW, 0, 2}, // PRECIP_BLIZZARD + {MT_RAIN, PRECIPFX_THUNDER|PRECIPFX_LIGHTNING, 0}, // PRECIP_STORM + {MT_NULL, PRECIPFX_THUNDER|PRECIPFX_LIGHTNING, 0}, // PRECIP_STORM_NORAIN + {MT_RAIN, PRECIPFX_THUNDER, 0} // PRECIP_STORM_NOSTRIKES +}; + INT32 cursaveslot = -1; // Auto-save 1p savegame slot INT16 lastmapsaved = 0; // Last map we auto-saved at boolean gamecomplete = false; diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 659af386d..31461283c 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5882,10 +5882,7 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing) // okay, we can't return now... this is a hack, but weather isn't networked, so it should be ok if (!(thing->precipflags & PCF_THUNK)) { - if (thing->precipflags & PCF_RAIN) - P_RainThinker(thing); - else - P_SnowThinker(thing); + P_PrecipThinker(thing); thing->precipflags |= PCF_THUNK; } diff --git a/src/info.c b/src/info.c index 4f448cc00..4542e6c3a 100644 --- a/src/info.c +++ b/src/info.c @@ -44,17 +44,17 @@ char sprnames[NUMSPRITES + 1][5] = "BSZ7","BSZ8","STLG","DBAL","RCRY","ARMA","ARMF","ARMB","WIND","MAGN", "ELEM","FORC","PITY","IVSP","SSPK","GOAL","BIRD","BUNY","MOUS","CHIC", "COWZ","RBRD","SPVY","SPVR","SPVB","SPVG","SPDY","SPDR","SPDB","SPDG", - "SPHY","SPHR","SPHB","SPHG","RAIN","SNO1","SPLH","SPLA","SMOK","BUBP", - "BUBO","BUBN","BUBM","POPP","TFOG","SEED","PRTL","SCOR","DRWN","TTAG", - "GFLG","RRNG","RNGB","RNGR","RNGI","RNGA","RNGE","RNGS","RNGG","PIKB", - "PIKR","PIKA","PIKE","PIKS","PIKG","TAUT","TGRE","TSCR","COIN","CPRK", - "GOOM","BGOM","FFWR","FBLL","SHLL","PUMA","HAMM","KOOP","BFLM","MAXE", - "MUS1","MUS2","TOAD","NDRN","SUPE","SUPZ","NDRL","NSPK","NBMP","HOOP", - "NSCR","NPRU","CAPS","SUPT","SPRK","BOM1","BOM2","BOM3","BOM4","ROIA", - "ROIB","ROIC","ROID","ROIE","ROIF","ROIG","ROIH","ROII","ROIJ","ROIK", - "ROIL","ROIM","ROIN","ROIO","ROIP","BBAL","GWLG","GWLR","SRBA","SRBB", - "SRBC","SRBD","SRBE","SRBF","SRBG","SRBH","SRBI","SRBJ","SRBK","SRBL", - "SRBM","SRBN","SRBO", + "SPHY","SPHR","SPHB","SPHG","RAIN","SNO1","SNO2","SPLH","SPLA","SMOK", + "BUBP","BUBO","BUBN","BUBM","POPP","TFOG","SEED","PRTL","SCOR","DRWN", + "TTAG","GFLG","RRNG","RNGB","RNGR","RNGI","RNGA","RNGE","RNGS","RNGG", + "PIKB","PIKR","PIKA","PIKE","PIKS","PIKG","TAUT","TGRE","TSCR","COIN", + "CPRK","GOOM","BGOM","FFWR","FBLL","SHLL","PUMA","HAMM","KOOP","BFLM", + "MAXE","MUS1","MUS2","TOAD","NDRN","SUPE","SUPZ","NDRL","NSPK","NBMP", + "HOOP","NSCR","NPRU","CAPS","SUPT","SPRK","BOM1","BOM2","BOM3","BOM4", + "ROIA","ROIB","ROIC","ROID","ROIE","ROIF","ROIG","ROIH","ROII","ROIJ", + "ROIK","ROIL","ROIM","ROIN","ROIO","ROIP","BBAL","GWLG","GWLR","SRBA", + "SRBB","SRBC","SRBD","SRBE","SRBF","SRBG","SRBH","SRBI","SRBJ","SRBK", + "SRBL","SRBM","SRBN","SRBO", //SRB2kart Sprites "RNDM","RPOP","SGNS","FAST","DSHR","BOST","BOSM","KFRE","KINV","KINF", "WIPD","DRIF","BDRF","DUST","RSHE","FITM","BANA","ORBN","JAWZ","SSMN", @@ -1869,13 +1869,18 @@ state_t states[NUMSTATES] = // Rain {SPR_RAIN, FF_TRANS50, -1, {NULL}, 0, 0, S_NULL}, // S_RAIN1 - {SPR_RAIN, FF_TRANS50, 1, {NULL}, 0, 0, S_RAIN1}, // S_RAINRETURN + {SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL}, // S_RAINRETURN // Snowflake {SPR_SNO1, 0, -1, {NULL}, 0, 0, S_NULL}, // S_SNOW1 {SPR_SNO1, 1, -1, {NULL}, 0, 0, S_NULL}, // S_SNOW2 {SPR_SNO1, 2, -1, {NULL}, 0, 0, S_NULL}, // S_SNOW3 + // Blizzard Snowball + {SPR_SNO2, 0, -1, {NULL}, 0, 0, S_NULL}, // S_BLIZZARDSNOW1 + {SPR_SNO2, 1, -1, {NULL}, 0, 0, S_NULL}, // S_BLIZZARDSNOW2 + {SPR_SNO2, 2, -1, {NULL}, 0, 0, S_NULL}, // S_BLIZZARDSNOW3 + // Water Splish {SPR_SPLH, FF_TRANS50 , 2, {NULL}, 0, 0, S_SPLISH2}, // S_SPLISH1 {SPR_SPLH, FF_TRANS50|1, 2, {NULL}, 0, 0, S_SPLISH3}, // S_SPLISH2 @@ -1888,9 +1893,9 @@ state_t states[NUMSTATES] = {SPR_SPLH, FF_TRANS50|8, 2, {NULL}, 0, 0, S_NULL}, // S_SPLISH9 // Water Splash - {SPR_SPLA, FF_TRANS50 , 3, {NULL}, 0, 0, S_SPLASH2}, // S_SPLASH1 - {SPR_SPLA, FF_TRANS70|1, 3, {NULL}, 0, 0, S_SPLASH3}, // S_SPLASH2 - {SPR_SPLA, FF_TRANS90|2, 3, {NULL}, 0, 0, S_RAINRETURN}, // S_SPLASH3 + {SPR_SPLA, FF_TRANS50 , 3, {NULL}, 0, 0, S_SPLASH2}, // S_SPLASH1 + {SPR_SPLA, FF_TRANS70|1, 3, {NULL}, 0, 0, S_SPLASH3}, // S_SPLASH2 + {SPR_SPLA, FF_TRANS90|2, 3, {NULL}, 0, 0, S_NULL}, // S_SPLASH3 // Smoke {SPR_SMOK, FF_TRANS50 , 4, {NULL}, 0, 0, S_SMOKE2}, // S_SMOKE1 @@ -11438,22 +11443,22 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_RAIN1, // spawnstate 1000, // spawnhealth S_NULL, // seestate - sfx_None, // seesound - 8, // reactiontime + sfx_rainin, // seesound + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_SPLASH1, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound -72*FRACUNIT, // speed -- -24*FRACUNIT originally, srb2kart x3 (nya) 1*FRACUNIT, // radius 8*FRACUNIT, // height 0, // display offset - 4, // mass + 80, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP, // flags @@ -11466,7 +11471,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound - 8, // reactiontime + 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance @@ -11480,7 +11485,34 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 4*FRACUNIT, // radius 4*FRACUNIT, // height 0, // display offset - 4, // mass + 0, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP, // flags + S_NULL // raisestate + }, + + { // MT_BLIZZARDSNOW + -1, // doomednum + S_BLIZZARDSNOW1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 0, // 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 + -24*FRACUNIT, // speed + 4*FRACUNIT, // radius + 4*FRACUNIT, // height + 0, // display offset + 0, // mass 0, // damage sfx_None, // activesound MF_NOBLOCKMAP, // flags diff --git a/src/info.h b/src/info.h index 27488d916..cb520252c 100644 --- a/src/info.h +++ b/src/info.h @@ -475,6 +475,7 @@ typedef enum sprite // Environmental Effects SPR_RAIN, // Rain SPR_SNO1, // Snowflake + SPR_SNO2, // Blizzard Snowball SPR_SPLH, // Water Splish SPR_SPLA, // Water Splash SPR_SMOK, @@ -2579,6 +2580,11 @@ typedef enum state S_SNOW2, S_SNOW3, + // Blizzard Snowball + S_BLIZZARDSNOW1, + S_BLIZZARDSNOW2, + S_BLIZZARDSNOW3, + // Water Splish S_SPLISH1, S_SPLISH2, @@ -4510,6 +4516,7 @@ typedef enum mobj_type // Environmental Effects MT_RAIN, // Rain MT_SNOWFLAKE, // Snowflake + MT_BLIZZARDSNOW, // Blizzard Snowball MT_SPLISH, // Water splish! MT_SMOKE, MT_SMALLBUBBLE, // small bubble diff --git a/src/p_floor.c b/src/p_floor.c index ccbfd6eae..666656958 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -1769,6 +1769,7 @@ static mobj_t *SearchMarioNode(msecnode_t *node) case MT_SUPERSPARK: case MT_RAIN: case MT_SNOWFLAKE: + case MT_BLIZZARDSNOW: case MT_SPLISH: case MT_SMOKE: case MT_SMALLBUBBLE: diff --git a/src/p_mobj.c b/src/p_mobj.c index b220ff4e6..87fb7a186 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3928,51 +3928,60 @@ void P_NullPrecipThinker(precipmobj_t *mobj) mobj->precipflags &= ~PCF_THUNK; } -void P_SnowThinker(precipmobj_t *mobj) +void P_PrecipThinker(precipmobj_t *mobj) { P_CycleStateAnimation((mobj_t *)mobj); - // adjust height - if ((mobj->z += mobj->momz) <= mobj->floorz) - mobj->z = mobj->ceilingz; -} - -void P_RainThinker(precipmobj_t *mobj) -{ - P_CycleStateAnimation((mobj_t *)mobj); - - if (mobj->state != &states[S_RAIN1]) + if (mobj->state == &states[S_RAINRETURN]) { - // cycle through states, - // calling action functions at transitions - if (mobj->tics <= 0) - return; - - if (--mobj->tics) - return; - - if (!P_SetPrecipMobjState(mobj, mobj->state->nextstate)) - return; - - if (mobj->state != &states[S_RAINRETURN]) - return; - + // Reset to ceiling! + P_SetPrecipMobjState(mobj, mobj->info->spawnstate); mobj->z = mobj->ceilingz; - P_SetPrecipMobjState(mobj, S_RAIN1); - - return; + mobj->momz = mobj->info->speed; + mobj->precipflags &= ~PCF_SPLASH; } + if (mobj->tics != -1) + { + if (mobj->tics) + { + mobj->tics--; + } + + if (mobj->tics == 0) + { + if ((mobj->precipflags & PCF_SPLASH) && (mobj->state->nextstate == S_NULL)) + { + // HACK: sprite changes are 1 tic late, so you would see splashes on the ceiling if not for this state. + // We need to use the settings from the previous state, since some of those are NOT 1 tic late. + INT32 frame = (mobj->frame & ~FF_FRAMEMASK); + P_SetPrecipMobjState(mobj, S_RAINRETURN); + mobj->frame = frame; + return; + } + else + { + if (!P_SetPrecipMobjState(mobj, mobj->state->nextstate)) + return; + } + } + } + + if (mobj->precipflags & PCF_SPLASH) + return; + // adjust height if ((mobj->z += mobj->momz) <= mobj->floorz) { - // no splashes on sky or bottomless pits - if (mobj->precipflags & PCF_PIT) + if ((mobj->info->deathstate == S_NULL) || (mobj->precipflags & PCF_PIT)) // no splashes on sky or bottomless pits + { mobj->z = mobj->ceilingz; + } else { + P_SetPrecipMobjState(mobj, mobj->info->deathstate); mobj->z = mobj->floorz; - P_SetPrecipMobjState(mobj, S_SPLASH1); + mobj->precipflags |= PCF_SPLASH; } } } @@ -6354,9 +6363,8 @@ fixed_t P_CalculateShadowFloor(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z, fi } } -#if 0 mobj->standingslope = slope; -#endif + #ifdef HWRENDER mobj->modeltilt = slope; #endif @@ -10754,17 +10762,21 @@ mobj_t *P_SpawnShadowMobj(mobj_t * caster) static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) { + const mobjinfo_t *info = &mobjinfo[type]; state_t *st; precipmobj_t *mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL); fixed_t starting_floorz; + mobj->type = type; + mobj->info = info; + mobj->x = x; mobj->y = y; - mobj->flags = mobjinfo[type].flags; + mobj->flags = info->flags; // do not set the state with P_SetMobjState, // because action routines can not be called yet - st = &states[mobjinfo[type].spawnstate]; + st = &states[info->spawnstate]; mobj->state = st; mobj->tics = st->tics; @@ -10787,7 +10799,7 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype mobj->subsector->sector->ceilingheight; mobj->z = z; - mobj->momz = mobjinfo[type].speed; + mobj->momz = info->speed; mobj->thinker.function.acp1 = (actionf_p1)P_NullPrecipThinker; P_AddThinker(&mobj->thinker); @@ -10804,21 +10816,6 @@ static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype return mobj; } -static inline precipmobj_t *P_SpawnRainMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) -{ - precipmobj_t *mo = P_SpawnPrecipMobj(x,y,z,type); - mo->precipflags |= PCF_RAIN; - //mo->thinker.function.acp1 = (actionf_p1)P_RainThinker; - return mo; -} - -static inline precipmobj_t *P_SpawnSnowMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) -{ - precipmobj_t *mo = P_SpawnPrecipMobj(x,y,z,type); - //mo->thinker.function.acp1 = (actionf_p1)P_SnowThinker; - return mo; -} - // // P_RemoveMobj // @@ -11007,8 +11004,8 @@ consvar_t cv_suddendeath = {"suddendeath", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHE void P_SpawnPrecipitation(void) { - INT32 i, mrand; - fixed_t basex, basey, x, y, height; + INT32 i, j, k; + fixed_t basex, basey, x, y, z, height; subsector_t *precipsector = NULL; precipmobj_t *rainmo = NULL; @@ -11021,8 +11018,9 @@ void P_SpawnPrecipitation(void) basex = bmaporgx + (i % bmapwidth) * MAPBLOCKSIZE; basey = bmaporgy + (i / bmapwidth) * MAPBLOCKSIZE; - //for (j = 0; j < cv_precipdensity.value; ++j) -- density is 1 for kart always { + UINT16 numparticles = 0; + x = basex + ((M_RandomKey(MAPBLOCKUNITS<<3)<>3); y = basey + ((M_RandomKey(MAPBLOCKUNITS<<3)<>3); @@ -11037,40 +11035,43 @@ void P_SpawnPrecipitation(void) if (precipsector->sector->ceilingpic != skyflatnum) continue; + height = abs(precipsector->sector->ceilingheight - precipsector->sector->floorheight); + // Exists, but is too small for reasonable precipitation. - if (!(precipsector->sector->floorheight <= precipsector->sector->ceilingheight - (32<sector->ceilingheight; + // Hack around a quirk of this entire system, where taller sectors look like they get less precipitation. + numparticles = 1 + (height / (MAPBLOCKUNITS<<4<sector->ceilingheight; + + for (j = 0; j < numparticles; j++) { - rainmo = P_SpawnSnowMobj(x, y, height, MT_SNOWFLAKE); - mrand = M_RandomByte(); - if (mrand < 64) - P_SetPrecipMobjState(rainmo, S_SNOW3); - else if (mrand < 144) - P_SetPrecipMobjState(rainmo, S_SNOW2); + rainmo = P_SpawnPrecipMobj(x, y, z, precipprops[curWeather].type); + + if (precipprops[curWeather].randomstates > 0) + { + UINT8 mrand = M_RandomByte(); + UINT8 threshold = UINT8_MAX / (precipprops[curWeather].randomstates + 1); + statenum_t st = mobjinfo[precipprops[curWeather].type].spawnstate; + + for (k = 0; k < precipprops[curWeather].randomstates; k++) + { + if (mrand < (threshold * (k+1))) + { + P_SetPrecipMobjState(rainmo, st+k+1); + break; + } + } + } + + // Randomly assign a height, now that floorz is set. + rainmo->z = M_RandomRange(rainmo->floorz>>FRACBITS, rainmo->ceilingz>>FRACBITS)<z = M_RandomRange(rainmo->floorz>>FRACBITS, rainmo->ceilingz>>FRACBITS)< 255) volume = 255; - if (sounds_rain && (!leveltime || leveltime % 80 == 1)) - S_StartSoundAtVolume(players[displayplayers[0]].mo, sfx_rainin, volume); + if (rainsfx != sfx_None && (!leveltime || leveltime % rainfreq == 1)) + S_StartSoundAtVolume(players[displayplayers[0]].mo, rainsfx, volume); if (!sounds_thunder) return; diff --git a/src/p_mobj.h b/src/p_mobj.h index aec2ed951..da3ba88e6 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -253,25 +253,23 @@ typedef enum // PRECIPITATION flags ?! ?! ?! // typedef enum { - // Don't draw. - PCF_INVISIBLE = 1, - // Above pit. - PCF_PIT = 2, - // Above FOF. - PCF_FOF = 4, - // Above MOVING FOF (this means we need to keep floorz up to date...) - PCF_MOVINGFOF = 8, - // Is rain. - PCF_RAIN = 16, - // Ran the thinker this tic. - PCF_THUNK = 32, + PCF_INVISIBLE = 1, // Don't draw. + PCF_PIT = 1<<1, // Above pit. + PCF_FOF = 1<<2, // Above FOF. + PCF_MOVINGFOF = 1<<3, // Above MOVING FOF (this means we need to keep floorz up to date...) + PCF_SPLASH = 1<<4, // Splashed on the ground, return to the ceiling after the animation's over + PCF_THUNK = 1<<5, // Ran the thinker this tic. } precipflag_t; + // Map Object definition. typedef struct mobj_s { // List: thinker links. thinker_t thinker; + mobjtype_t type; + const mobjinfo_t *info; // &mobjinfo[mobj->type] + // Info for drawing: position. fixed_t x, y, z; @@ -321,9 +319,6 @@ typedef struct mobj_s struct mobj_s *hnext; struct mobj_s *hprev; - mobjtype_t type; - const mobjinfo_t *info; // &mobjinfo[mobj->type] - INT32 health; // for player this is rings + 1 // Movement direction, movement generation (zig-zagging). @@ -392,6 +387,9 @@ typedef struct precipmobj_s // List: thinker links. thinker_t thinker; + mobjtype_t type; + const mobjinfo_t *info; // &mobjinfo[mobj->type] + // Info for drawing: position. fixed_t x, y, z; @@ -459,8 +457,7 @@ void P_SpawnParaloop(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 numb boolean P_BossTargetPlayer(mobj_t *actor, boolean closest); boolean P_SupermanLook4Players(mobj_t *actor); void P_DestroyRobots(void); -void P_SnowThinker(precipmobj_t *mobj); -void P_RainThinker(precipmobj_t *mobj); +void P_PrecipThinker(precipmobj_t *mobj); void P_NullPrecipThinker(precipmobj_t *mobj); void P_RemovePrecipMobj(precipmobj_t *mobj); void P_SetScale(mobj_t *mobj, fixed_t newscale); diff --git a/src/p_spec.c b/src/p_spec.c index 93e88e2ce..d92fb2f3b 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2003,57 +2003,28 @@ void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller) // // Switches the weather! // -void P_SwitchWeather(INT32 weathernum) +void P_SwitchWeather(UINT8 newWeather) { boolean purge = false; - INT32 swap = 0; + mobjtype_t swap = MT_NULL; - switch (weathernum) + if (precipprops[newWeather].type == MT_NULL) { - case PRECIP_NONE: // None - if (curWeather == PRECIP_NONE) - return; // Nothing to do. - purge = true; - break; - case PRECIP_STORM: // Storm - case PRECIP_STORM_NOSTRIKES: // Storm w/ no lightning - case PRECIP_RAIN: // Rain - if (curWeather == PRECIP_SNOW || curWeather == PRECIP_BLANK || curWeather == PRECIP_STORM_NORAIN) - swap = PRECIP_RAIN; - break; - case PRECIP_SNOW: // Snow - if (curWeather == PRECIP_SNOW) - return; // Nothing to do. - if (curWeather == PRECIP_RAIN || curWeather == PRECIP_STORM || curWeather == PRECIP_STORM_NOSTRIKES || curWeather == PRECIP_BLANK || curWeather == PRECIP_STORM_NORAIN) - swap = PRECIP_SNOW; // Need to delete the other precips. - break; - case PRECIP_STORM_NORAIN: // Storm w/o rain - if (curWeather == PRECIP_SNOW - || curWeather == PRECIP_STORM - || curWeather == PRECIP_STORM_NOSTRIKES - || curWeather == PRECIP_RAIN - || curWeather == PRECIP_BLANK) - swap = PRECIP_STORM_NORAIN; - else if (curWeather == PRECIP_STORM_NORAIN) - return; - break; - case PRECIP_BLANK: - if (curWeather == PRECIP_SNOW - || curWeather == PRECIP_STORM - || curWeather == PRECIP_STORM_NOSTRIKES - || curWeather == PRECIP_RAIN) - swap = PRECIP_BLANK; - else if (curWeather == PRECIP_STORM_NORAIN) - swap = PRECIP_BLANK; - else if (curWeather == PRECIP_BLANK) - return; - break; - default: - CONS_Debug(DBG_GAMELOGIC, "P_SwitchWeather: Unknown weather type %d.\n", weathernum); - break; + // New type is null, we want to purge the weather. + if (precipprops[curWeather].type == MT_NULL) + return; // Nothing to do. + purge = true; + } + else + { + if (precipprops[curWeather].type != MT_NULL) + { + // There are already existing weather particles to reuse. + swap = precipprops[newWeather].type; + } } - if (purge) + if (purge == true) { thinker_t *think; precipmobj_t *precipmobj; @@ -2068,136 +2039,53 @@ void P_SwitchWeather(INT32 weathernum) P_RemovePrecipMobj(precipmobj); } } - else if (swap && !((swap == PRECIP_BLANK && curWeather == PRECIP_STORM_NORAIN) || (swap == PRECIP_STORM_NORAIN && curWeather == PRECIP_BLANK))) // Rather than respawn all that crap, reuse it! + else if (swap != MT_NULL) // Rather than respawn all that crap, reuse it! { thinker_t *think; precipmobj_t *precipmobj; - state_t *st; + statenum_t st; for (think = thinkercap.next; think != &thinkercap; think = think->next) { if (think->function.acp1 != (actionf_p1)P_NullPrecipThinker) continue; // not a precipmobj thinker + precipmobj = (precipmobj_t *)think; - if (swap == PRECIP_RAIN) // Snow To Rain + precipmobj->flags = mobjinfo[swap].flags; + + st = mobjinfo[swap].spawnstate; + + if (precipprops[curWeather].randomstates > 0) { - precipmobj->flags = mobjinfo[MT_RAIN].flags; - st = &states[mobjinfo[MT_RAIN].spawnstate]; - precipmobj->state = st; - precipmobj->tics = st->tics; - precipmobj->sprite = st->sprite; - precipmobj->frame = st->frame; - precipmobj->momz = mobjinfo[MT_RAIN].speed; + UINT8 mrand = M_RandomByte(); + UINT8 threshold = UINT8_MAX / (precipprops[curWeather].randomstates + 1); + UINT8 i; - precipmobj->precipflags &= ~PCF_INVISIBLE; - - precipmobj->precipflags |= PCF_RAIN; - //think->function.acp1 = (actionf_p1)P_RainThinker; + for (i = 0; i < precipprops[curWeather].randomstates; i++) + { + if (mrand < (threshold * (i+1))) + { + st += i+1; + break; + } + } } - else if (swap == PRECIP_SNOW) // Rain To Snow - { - INT32 z; - precipmobj->flags = mobjinfo[MT_SNOWFLAKE].flags; - z = M_RandomByte(); + precipmobj->state = &states[st]; + precipmobj->tics = precipmobj->state->tics; + precipmobj->sprite = precipmobj->state->sprite; + precipmobj->frame = precipmobj->state->frame; - if (z < 64) - z = 2; - else if (z < 144) - z = 1; - else - z = 0; - - st = &states[mobjinfo[MT_SNOWFLAKE].spawnstate+z]; - precipmobj->state = st; - precipmobj->tics = st->tics; - precipmobj->sprite = st->sprite; - precipmobj->frame = st->frame; - precipmobj->momz = mobjinfo[MT_SNOWFLAKE].speed; - - precipmobj->precipflags &= ~(PCF_INVISIBLE|PCF_RAIN); - - //think->function.acp1 = (actionf_p1)P_SnowThinker; - } - else if (swap == PRECIP_BLANK || swap == PRECIP_STORM_NORAIN) // Remove precip, but keep it around for reuse. - { - //think->function.acp1 = (actionf_p1)P_NullPrecipThinker; - - precipmobj->precipflags |= PCF_INVISIBLE; - } + precipmobj->momz = mobjinfo[swap].speed; + precipmobj->precipflags &= ~PCF_INVISIBLE; } } - switch (weathernum) - { - case PRECIP_SNOW: // snow - curWeather = PRECIP_SNOW; + curWeather = newWeather; - if (!swap) - P_SpawnPrecipitation(); - - break; - case PRECIP_RAIN: // rain - { - boolean dontspawn = false; - - if (curWeather == PRECIP_RAIN || curWeather == PRECIP_STORM || curWeather == PRECIP_STORM_NOSTRIKES) - dontspawn = true; - - curWeather = PRECIP_RAIN; - - if (!dontspawn && !swap) - P_SpawnPrecipitation(); - - break; - } - case PRECIP_STORM: // storm - { - boolean dontspawn = false; - - if (curWeather == PRECIP_RAIN || curWeather == PRECIP_STORM || curWeather == PRECIP_STORM_NOSTRIKES) - dontspawn = true; - - curWeather = PRECIP_STORM; - - if (!dontspawn && !swap) - P_SpawnPrecipitation(); - - break; - } - case PRECIP_STORM_NOSTRIKES: // storm w/o lightning - { - boolean dontspawn = false; - - if (curWeather == PRECIP_RAIN || curWeather == PRECIP_STORM || curWeather == PRECIP_STORM_NOSTRIKES) - dontspawn = true; - - curWeather = PRECIP_STORM_NOSTRIKES; - - if (!dontspawn && !swap) - P_SpawnPrecipitation(); - - break; - } - case PRECIP_STORM_NORAIN: // storm w/o rain - curWeather = PRECIP_STORM_NORAIN; - - if (!swap) - P_SpawnPrecipitation(); - - break; - case PRECIP_BLANK: - curWeather = PRECIP_BLANK; - - if (!swap) - P_SpawnPrecipitation(); - - break; - default: - curWeather = PRECIP_NONE; - break; - } + if (swap == MT_NULL && precipprops[newWeather].type != MT_NULL) + P_SpawnPrecipitation(); } /** Gets an object. @@ -5672,25 +5560,10 @@ void P_InitSpecials(void) CheckForBustableBlocks = CheckForBouncySector = CheckForQuicksand = CheckForMarioBlocks = CheckForFloatBob = CheckForReverseGravity = false; - // Set curWeather - switch (mapheaderinfo[gamemap-1]->weather) - { - case PRECIP_SNOW: // snow - case PRECIP_RAIN: // rain - case PRECIP_STORM: // storm - case PRECIP_STORM_NORAIN: // storm w/o rain - case PRECIP_STORM_NOSTRIKES: // storm w/o lightning - curWeather = mapheaderinfo[gamemap-1]->weather; - break; - default: // blank/none - curWeather = PRECIP_NONE; - break; - } + // Set weather + curWeather = globalweather = mapheaderinfo[gamemap-1]->weather; - // Set globalweather - globalweather = mapheaderinfo[gamemap-1]->weather; - - P_InitTagLists(); // Create xref tables for tags + P_InitTagLists(); // Create xref tables for tags } /** After the map has loaded, scans for specials that spawn 3Dfloors and diff --git a/src/p_spec.h b/src/p_spec.h index b604ac951..1aca41155 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -59,7 +59,7 @@ INT32 P_FindMinSurroundingLight(sector_t *sector, INT32 max); void P_SetupSignExit(player_t *player); boolean P_IsFlagAtBase(mobjtype_t flag); -void P_SwitchWeather(INT32 weathernum); +void P_SwitchWeather(UINT8 newWeather); boolean P_RunTriggerLinedef(line_t *triggerline, mobj_t *actor, sector_t *caller); void P_LinedefExecute(INT16 tag, mobj_t *actor, sector_t *caller); diff --git a/src/p_tick.c b/src/p_tick.c index b285c35d0..9e4de8e33 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -58,8 +58,6 @@ void Command_Numthinkers_f(void) CONS_Printf(M_GetText("numthinkers <#>: Count number of thinkers\n")); CONS_Printf( "\t1: P_MobjThinker\n" - /*"\t2: P_RainThinker\n" - "\t3: P_SnowThinker\n"*/ "\t2: P_NullPrecipThinker\n" "\t3: T_Friction\n" "\t4: T_Pusher\n" @@ -75,14 +73,6 @@ void Command_Numthinkers_f(void) action = (actionf_p1)P_MobjThinker; CONS_Printf(M_GetText("Number of %s: "), "P_MobjThinker"); break; - /*case 2: - action = (actionf_p1)P_RainThinker; - CONS_Printf(M_GetText("Number of %s: "), "P_RainThinker"); - break; - case 3: - action = (actionf_p1)P_SnowThinker; - CONS_Printf(M_GetText("Number of %s: "), "P_SnowThinker"); - break;*/ case 2: action = (actionf_p1)P_NullPrecipThinker; CONS_Printf(M_GetText("Number of %s: "), "P_NullPrecipThinker"); diff --git a/src/r_things.c b/src/r_things.c index 1afbb125c..847f011ec 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -1639,14 +1639,10 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) // okay, we can't return now except for vertical clipping... this is a hack, but weather isn't networked, so it should be ok if (!(thing->precipflags & PCF_THUNK)) { - if (thing->precipflags & PCF_RAIN) - P_RainThinker(thing); - else - P_SnowThinker(thing); + P_PrecipThinker(thing); thing->precipflags |= PCF_THUNK; } - //SoM: 3/17/2000: Disregard sprites that are out of view.. gzt = thing->z + spritecachedinfo[lump].topoffset; gz = gzt - spritecachedinfo[lump].height; From 100a67f8f0c048585b5d45993429b68b33af4bc3 Mon Sep 17 00:00:00 2001 From: James Date: Sat, 16 Nov 2019 16:14:54 -0500 Subject: [PATCH 143/163] Prevent LF2_EXISTSHACK from ever getting removed --- src/p_setup.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/p_setup.c b/src/p_setup.c index 5acc72746..b51dabdd0 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -181,6 +181,8 @@ FUNCNORETURN static ATTRNORETURN void CorruptMapError(const char *msg) static void P_ClearSingleMapHeaderInfo(INT16 i) { const INT16 num = (INT16)(i-1); + INT32 exists = (mapheaderinfo[num]->menuflags & LF2_EXISTSHACK); + DEH_WriteUndoline("LEVELNAME", mapheaderinfo[num]->lvlttl, UNDO_NONE); mapheaderinfo[num]->lvlttl[0] = '\0'; DEH_WriteUndoline("SUBTITLE", mapheaderinfo[num]->subttl, UNDO_NONE); @@ -246,7 +248,7 @@ static void P_ClearSingleMapHeaderInfo(INT16 i) DEH_WriteUndoline("LEVELFLAGS", va("%d", mapheaderinfo[num]->levelflags), UNDO_NONE); mapheaderinfo[num]->levelflags = 0; DEH_WriteUndoline("MENUFLAGS", va("%d", mapheaderinfo[num]->menuflags), UNDO_NONE); - mapheaderinfo[num]->menuflags = (mainwads ? 0 : LF2_EXISTSHACK); // see p_setup.c - prevents replacing maps in addons with easier versions + mapheaderinfo[num]->menuflags = exists; // see p_setup.c - prevents replacing maps in addons with easier versions // TODO grades support for delfile (pfft yeah right) P_DeleteGrades(num); // SRB2Kart From 5f26312a0a390ccff6cf6bdca6135da2d52c37f4 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 22 Feb 2020 18:30:20 -0800 Subject: [PATCH 144/163] Drop frames as the host according to the lowest ping among clients --- src/d_clisrv.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 1dacabd9f..7851e1b62 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4960,6 +4960,28 @@ static void CL_SendClientCmd(void) size_t packetsize = 0; boolean mis = false; + int fastest; + int lag; + int i; + + fastest = 0; + + if (server) + { + for (i = 0; i < MAXPLAYERS; ++i) + { + if (playernode[i] > 0 && playeringame[i]) + { + lag = GetLag(playernode[i]); + if (! fastest || lag < fastest) + fastest = lag; + } + } + } + + if (fastest && ( gametic % fastest )) + return; + netbuffer->packettype = PT_CLIENTCMD; if (cl_packetmissed) From 56f6b058d039dfbd64c6fa5e3747342a2aa3bd5f Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 22 Feb 2020 18:33:31 -0800 Subject: [PATCH 145/163] Make host lag optional with "lagless", lag by default (lagless off) --- src/d_clisrv.c | 2 +- src/d_netcmd.c | 3 +++ src/d_netcmd.h | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 7851e1b62..1f5e1f1ae 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -4966,7 +4966,7 @@ static void CL_SendClientCmd(void) fastest = 0; - if (server) + if (server && ! cv_lagless.value) { for (i = 0; i < MAXPLAYERS; ++i) { diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 70dff2fcf..ede7558ad 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -447,6 +447,8 @@ consvar_t cv_jointimeout = {"jointimeout", "105", CV_CALL|CV_SAVE, nettimeout_co static CV_PossibleValue_t maxping_cons_t[] = {{0, "MIN"}, {1000, "MAX"}, {0, NULL}}; consvar_t cv_maxping = {"maxping", "800", CV_SAVE, maxping_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_lagless = {"lagless", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; + static CV_PossibleValue_t pingtimeout_cons_t[] = {{8, "MIN"}, {120, "MAX"}, {0, NULL}}; consvar_t cv_pingtimeout = {"pingtimeout", "10", CV_SAVE, pingtimeout_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -711,6 +713,7 @@ void D_RegisterServerCommands(void) CV_RegisterVar(&cv_skipmapcheck); CV_RegisterVar(&cv_sleep); CV_RegisterVar(&cv_maxping); + CV_RegisterVar(&cv_lagless); CV_RegisterVar(&cv_pingtimeout); CV_RegisterVar(&cv_showping); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index d1f28665c..7a11a809d 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -144,6 +144,7 @@ extern consvar_t cv_ringslinger, cv_soundtest; extern consvar_t cv_specialrings, cv_powerstones, cv_matchboxes, cv_competitionboxes; extern consvar_t cv_maxping; +extern consvar_t cv_lagless; extern consvar_t cv_pingtimeout; extern consvar_t cv_showping; From 6484a5cd93179581b4e07c52931adc9c52752c66 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 22 Feb 2020 18:38:36 -0800 Subject: [PATCH 146/163] Show LAGLESS on the scores if the host is being dishonest --- src/k_kart.c | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 230662d2a..2000c3765 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -7085,6 +7085,9 @@ static patch_t *kp_lapanim_hand[3]; static patch_t *kp_yougotem; static patch_t *kp_itemminimap; +static patch_t *kp_alagles[10]; +static patch_t *kp_blagles[6]; + void K_LoadKartHUDGraphics(void) { INT32 i, j; @@ -7385,6 +7388,20 @@ void K_LoadKartHUDGraphics(void) kp_yougotem = (patch_t *) W_CachePatchName("YOUGOTEM", PU_HUDGFX); kp_itemminimap = (patch_t *) W_CachePatchName("MMAPITEM", PU_HUDGFX); + + sprintf(buffer, "ALAGLESx"); + for (i = 0; i < 10; ++i) + { + buffer[7] = '0'+i; + kp_alagles[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + } + + sprintf(buffer, "BLAGLESx"); + for (i = 0; i < 6; ++i) + { + buffer[7] = '0'+i; + kp_blagles[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX); + } } // For the item toggle menu @@ -8357,9 +8374,11 @@ static boolean K_drawKartPositionFaces(void) // void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer, INT32 hilicol) { + static tic_t alagles_timer = 9; INT32 i, rightoffset = 240; const UINT8 *colormap; INT32 dupadjust = (vid.width/vid.dupx), duptweak = (dupadjust - BASEVIDWIDTH)/2; + int y2; //this function is designed for 9 or less score lines only //I_Assert(scorelines <= 9); -- not today bitch, kart fixed it up @@ -8385,10 +8404,34 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I STRBUFCPY(strtime, tab[i].name); + y2 = y; + + if (tab[i].num == 0 && cv_lagless.value) + { + y2 = ( y - 4 ); + + V_DrawScaledPatch(x + 20, y2, 0, kp_blagles[(leveltime / 3) % 6]); + // every 70 tics + if (( leveltime % 70 ) == 0) + { + alagles_timer = 9; + } + if (alagles_timer > 0) + { + V_DrawScaledPatch(x + 20, y2, 0, kp_alagles[alagles_timer]); + if (( leveltime % 2 ) == 0) + alagles_timer--; + } + else + V_DrawScaledPatch(x + 20, y2, 0, kp_alagles[0]); + + y2 += SHORT (kp_alagles[0]->height) + 1; + } + if (scorelines > 8) - V_DrawThinString(x + 20, y, ((tab[i].num == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE|V_6WIDTHSPACE, strtime); + V_DrawThinString(x + 20, y2, ((tab[i].num == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE|V_6WIDTHSPACE, strtime); else - V_DrawString(x + 20, y, ((tab[i].num == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE, strtime); + V_DrawString(x + 20, y2, ((tab[i].num == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE, strtime); if (players[tab[i].num].mo->color) { From 352d576979585e1f04b5d0b6d06a7b05cbc1305a Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 22 Feb 2020 19:08:03 -0800 Subject: [PATCH 147/163] Don't turn off lagless at map start; draw LAGLESS in intermission --- src/d_clisrv.c | 3 ++- src/d_clisrv.h | 2 ++ src/d_netcmd.c | 12 +++++++++++- src/g_game.c | 2 ++ src/k_kart.c | 2 +- src/y_inter.c | 36 ++++++++++++++++++++++++++++++++++-- 6 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 1f5e1f1ae..e520c8155 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -97,6 +97,7 @@ UINT16 pingmeasurecount = 1; UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone. UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values. tic_t servermaxping = 800; // server's max ping. Defaults to 800 +boolean server_lagless; SINT8 nodetoplayer[MAXNETNODES]; SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen) SINT8 nodetoplayer3[MAXNETNODES]; // say the numplayer for this node if any (splitscreen == 2) @@ -4966,7 +4967,7 @@ static void CL_SendClientCmd(void) fastest = 0; - if (server && ! cv_lagless.value) + if (server && ! server_lagless) { for (i = 0; i < MAXPLAYERS; ++i) { diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 0bd85b614..a33d06a2c 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -543,6 +543,8 @@ extern UINT32 realpingtable[MAXPLAYERS]; extern UINT32 playerpingtable[MAXPLAYERS]; extern tic_t servermaxping; +extern boolean server_lagless; + extern consvar_t #ifdef VANILLAJOINNEXTROUND cv_joinnextround, diff --git a/src/d_netcmd.c b/src/d_netcmd.c index ede7558ad..6b196d10d 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -93,6 +93,8 @@ static void TeamScramble_OnChange(void); static void NetTimeout_OnChange(void); static void JoinTimeout_OnChange(void); +static void Lagless_OnChange (void); + static void Ringslinger_OnChange(void); static void Gravity_OnChange(void); static void ForceSkin_OnChange(void); @@ -447,7 +449,7 @@ consvar_t cv_jointimeout = {"jointimeout", "105", CV_CALL|CV_SAVE, nettimeout_co static CV_PossibleValue_t maxping_cons_t[] = {{0, "MIN"}, {1000, "MAX"}, {0, NULL}}; consvar_t cv_maxping = {"maxping", "800", CV_SAVE, maxping_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_lagless = {"lagless", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_lagless = {"lagless", "Off", CV_SAVE|CV_NETVAR|CV_CALL, CV_OnOff, Lagless_OnChange, 0, NULL, NULL, 0, 0, NULL}; static CV_PossibleValue_t pingtimeout_cons_t[] = {{8, "MIN"}, {120, "MAX"}, {0, NULL}}; consvar_t cv_pingtimeout = {"pingtimeout", "10", CV_SAVE, pingtimeout_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -4772,6 +4774,14 @@ static void JoinTimeout_OnChange(void) jointimeout = (tic_t)cv_jointimeout.value; } +static void +Lagless_OnChange (void) +{ + /* don't back out of dishonesty, or go lagless after playing honestly */ + if (cv_lagless.value && gamestate == GS_LEVEL) + server_lagless = true; +} + UINT32 timelimitintics = 0; /** Deals with a timelimit change by printing the change to the console. diff --git a/src/g_game.c b/src/g_game.c index d4d48f7c2..af32050de 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1781,6 +1781,8 @@ void G_DoLoadLevel(boolean resetplayer) // clear hud messages remains (usually from game startup) CON_ClearHUD(); + + server_lagless = cv_lagless.value; } static INT32 pausedelay = 0; diff --git a/src/k_kart.c b/src/k_kart.c index 2000c3765..4016b7ced 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8406,7 +8406,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I y2 = y; - if (tab[i].num == 0 && cv_lagless.value) + if (tab[i].num == 0 && server_lagless) { y2 = ( y - 4 ); diff --git a/src/y_inter.c b/src/y_inter.c index f5380d565..ff168070c 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -435,6 +435,7 @@ void Y_IntermissionDrawer(void) INT32 y = 41, gutter = ((data.match.numplayers > NUMFORNEWCOLUMN) ? 0 : (BASEVIDWIDTH/2)); INT32 dupadjust = (vid.width/vid.dupx), duptweak = (dupadjust - BASEVIDWIDTH)/2; const char *timeheader; + int y2; if (data.match.rankingsmode) timeheader = "PWR.LV"; @@ -492,10 +493,41 @@ void Y_IntermissionDrawer(void) STRBUFCPY(strtime, data.match.name[i]); + y2 = y; + + if (data.match.num[i] == 0 && server_lagless) + { + static int alagles_timer = 0; + patch_t *alagles; + + y2 = ( y - 4 ); + + V_DrawScaledPatch(x + 36, y2, 0, W_CachePatchName(va("BLAGLES%d", (intertic / 3) % 6), PU_CACHE)); + // every 70 tics + if (( leveltime % 70 ) == 0) + { + alagles_timer = 9; + } + if (alagles_timer > 0) + { + alagles = W_CachePatchName(va("ALAGLES%d", alagles_timer), PU_CACHE); + V_DrawScaledPatch(x + 36, y2, 0, alagles); + if (( leveltime % 2 ) == 0) + alagles_timer--; + } + else + { + alagles = W_CachePatchName("ALAGLES0", PU_CACHE); + V_DrawScaledPatch(x + 36, y2, 0, alagles); + } + + y2 += SHORT (alagles->height) + 1; + } + if (data.match.numplayers > NUMFORNEWCOLUMN) - V_DrawThinString(x+36, y-1, ((data.match.num[i] == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE|V_6WIDTHSPACE, strtime); + V_DrawThinString(x+36, y2-1, ((data.match.num[i] == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE|V_6WIDTHSPACE, strtime); else - V_DrawString(x+36, y, ((data.match.num[i] == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE, strtime); + V_DrawString(x+36, y2, ((data.match.num[i] == whiteplayer) ? hilicol : 0)|V_ALLOWLOWERCASE, strtime); if (data.match.rankingsmode) { From a511d9358a81fb743a5b9b789c61d6f31c1b38c3 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 22 Feb 2020 19:38:36 -0800 Subject: [PATCH 148/163] Terrible code to show the ping counter for honest servers --- src/d_clisrv.c | 75 +++++++++++++++++++++++++++++++++-------------- src/sdl/i_video.c | 5 +++- 2 files changed, 57 insertions(+), 23 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index e520c8155..28a519694 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -97,6 +97,7 @@ UINT16 pingmeasurecount = 1; UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone. UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values. tic_t servermaxping = 800; // server's max ping. Defaults to 800 +static tic_t lowest_lag; boolean server_lagless; SINT8 nodetoplayer[MAXNETNODES]; SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen) @@ -4961,26 +4962,7 @@ static void CL_SendClientCmd(void) size_t packetsize = 0; boolean mis = false; - int fastest; - int lag; - int i; - - fastest = 0; - - if (server && ! server_lagless) - { - for (i = 0; i < MAXPLAYERS; ++i) - { - if (playernode[i] > 0 && playeringame[i]) - { - lag = GetLag(playernode[i]); - if (! fastest || lag < fastest) - fastest = lag; - } - } - } - - if (fastest && ( gametic % fastest )) + if (lowest_lag && ( gametic % lowest_lag )) return; netbuffer->packettype = PT_CLIENTCMD; @@ -5451,16 +5433,65 @@ static tic_t gametime = 0; static void UpdatePingTable(void) { + int fastest; + tic_t lag; + INT32 i; + if (server) { if (netgame && !(gametime % 35)) // update once per second. PingUpdate(); + + fastest = 0; + // update node latency values so we can take an average later. for (i = 0; i < MAXPLAYERS; i++) - if (playeringame[i]) - realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i])); + { + if (playeringame[i] && playernode[i] > 0) + { + if (! server_lagless && playernode[i] > 0) + { + lag = GetLag(playernode[i]); + realpingtable[i] += G_TicsToMilliseconds(lag); + + if (! fastest || lag < fastest) + fastest = lag; + } + else + realpingtable[i] += G_TicsToMilliseconds(GetLag(playernode[i])); + } + } pingmeasurecount++; + + if (server_lagless) + lowest_lag = 0; + else + { + lowest_lag = fastest; + + if (fastest) + lag = fastest; + else + lag = GetLag(0); + + lag = ( realpingtable[0] + G_TicsToMilliseconds(lag) ); + + switch (playerpernode[0]) + { + case 4: + realpingtable[nodetoplayer4[0]] = lag; + /*FALLTHRU*/ + case 3: + realpingtable[nodetoplayer3[0]] = lag; + /*FALLTHRU*/ + case 2: + realpingtable[nodetoplayer2[0]] = lag; + /*FALLTHRU*/ + case 1: + realpingtable[nodetoplayer[0]] = lag; + } + } } } diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index e5f1c23fc..c900417ab 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -1382,8 +1382,11 @@ void I_FinishUpdate(void) if (cv_ticrate.value) SCR_DisplayTicRate(); - if (cv_showping.value && netgame && consoleplayer != serverplayer) + if (cv_showping.value && netgame && + ( consoleplayer != serverplayer || ! server_lagless )) + { SCR_DisplayLocalPing(); + } } if (rendermode == render_soft && screens[0]) From 4f73e2666188df1d0b6b896cbe68f57152ff5b62 Mon Sep 17 00:00:00 2001 From: James R Date: Sat, 22 Feb 2020 19:44:16 -0800 Subject: [PATCH 149/163] Show server's ping on scores if not LAGLESS --- 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 4016b7ced..3c01f22ab 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8399,7 +8399,7 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I continue; //ignore them. if (netgame // don't draw it offline - && tab[i].num != serverplayer) + && ( tab[i].num != serverplayer || ! server_lagless )) HU_drawPing(x + ((i < 8) ? -17 : rightoffset + 11), y-4, playerpingtable[tab[i].num], 0); STRBUFCPY(strtime, tab[i].name); From a63157b937a347e60666bed1d1cde43838e2fc2f Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Tue, 25 Feb 2020 00:04:39 -0500 Subject: [PATCH 150/163] Flip facing direction --- src/p_spec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/p_spec.c b/src/p_spec.c index 9f8bc6f4b..2d8e355ed 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3251,7 +3251,7 @@ static void P_SetupSignObject(mobj_t *sign, mobj_t *pmo) P_SetTarget(&cur->hnext->target, sign); P_SetMobjState(cur->hnext, S_SIGN_FACE); cur->hnext->extravalue1 = 6; - cur->hnext->extravalue2 = 2; + cur->hnext->extravalue2 = 0; prev = cur; cur = cur->hnext; @@ -3263,7 +3263,7 @@ static void P_SetupSignObject(mobj_t *sign, mobj_t *pmo) cur->hnext->skin = pmo->skin; P_SetMobjState(cur->hnext, S_PLAY_SIGN); cur->hnext->extravalue1 = 7; - cur->hnext->extravalue2 = 2; + cur->hnext->extravalue2 = 0; prev = cur; cur = cur->hnext; @@ -3274,7 +3274,7 @@ static void P_SetupSignObject(mobj_t *sign, mobj_t *pmo) P_SetTarget(&cur->hnext->target, sign); P_SetMobjState(cur->hnext, S_SIGN_BACK); cur->hnext->extravalue1 = 6; - cur->hnext->extravalue2 = 0; + cur->hnext->extravalue2 = 2; prev = cur; cur = cur->hnext; From 6956e1d24ed96c3d8853e50d124fe450725094a6 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Sun, 1 Mar 2020 13:13:59 -0500 Subject: [PATCH 151/163] Store random states in mobjinfo instead of precipprops My reasoning is that it wouldn't make much sense to have a weather type that has snow, but doesn't randomize the sprite it uses, so we don't need to copy-paste the same "randomstates" for each weather type. --- src/doomstat.h | 1 - src/g_game.c | 14 +++++++------- src/info.c | 4 ++-- src/p_mobj.c | 12 +++++++----- src/p_spec.c | 7 ++++--- 5 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/doomstat.h b/src/doomstat.h index cdc09cf86..f4f7acfd0 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -68,7 +68,6 @@ typedef struct { mobjtype_t type; precipeffect_t effects; - UINT8 randomstates; } precipprops_t; extern precipprops_t precipprops[MAXPRECIP]; diff --git a/src/g_game.c b/src/g_game.c index e15968b3e..488f350a7 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -89,13 +89,13 @@ UINT8 curWeather = PRECIP_NONE; precipprops_t precipprops[MAXPRECIP] = { - {MT_NULL, 0, 0}, // PRECIP_NONE - {MT_RAIN, 0, 0}, // PRECIP_RAIN - {MT_SNOWFLAKE, 0, 2}, // PRECIP_SNOW - {MT_BLIZZARDSNOW, 0, 2}, // PRECIP_BLIZZARD - {MT_RAIN, PRECIPFX_THUNDER|PRECIPFX_LIGHTNING, 0}, // PRECIP_STORM - {MT_NULL, PRECIPFX_THUNDER|PRECIPFX_LIGHTNING, 0}, // PRECIP_STORM_NORAIN - {MT_RAIN, PRECIPFX_THUNDER, 0} // PRECIP_STORM_NOSTRIKES + {MT_NULL, 0}, // PRECIP_NONE + {MT_RAIN, 0}, // PRECIP_RAIN + {MT_SNOWFLAKE, 0}, // PRECIP_SNOW + {MT_BLIZZARDSNOW, 0}, // PRECIP_BLIZZARD + {MT_RAIN, PRECIPFX_THUNDER|PRECIPFX_LIGHTNING}, // PRECIP_STORM + {MT_NULL, PRECIPFX_THUNDER|PRECIPFX_LIGHTNING}, // PRECIP_STORM_NORAIN + {MT_RAIN, PRECIPFX_THUNDER} // PRECIP_STORM_NOSTRIKES }; INT32 cursaveslot = -1; // Auto-save 1p savegame slot diff --git a/src/info.c b/src/info.c index 4542e6c3a..018d354f5 100644 --- a/src/info.c +++ b/src/info.c @@ -11486,7 +11486,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 4*FRACUNIT, // height 0, // display offset 0, // mass - 0, // damage + 2, // damage sfx_None, // activesound MF_NOBLOCKMAP, // flags S_NULL // raisestate @@ -11513,7 +11513,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 4*FRACUNIT, // height 0, // display offset 0, // mass - 0, // damage + 2, // damage sfx_None, // activesound MF_NOBLOCKMAP, // flags S_NULL // raisestate diff --git a/src/p_mobj.c b/src/p_mobj.c index 87fb7a186..2f514f526 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11005,6 +11005,8 @@ consvar_t cv_suddendeath = {"suddendeath", "Off", CV_NETVAR|CV_CHEAT|CV_NOSHOWHE void P_SpawnPrecipitation(void) { INT32 i, j, k; + mobjtype_t type = precipprops[curWeather].type; + INT32 randomstates = mobjinfo[type].damage; fixed_t basex, basey, x, y, z, height; subsector_t *precipsector = NULL; precipmobj_t *rainmo = NULL; @@ -11049,15 +11051,15 @@ void P_SpawnPrecipitation(void) for (j = 0; j < numparticles; j++) { - rainmo = P_SpawnPrecipMobj(x, y, z, precipprops[curWeather].type); + rainmo = P_SpawnPrecipMobj(x, y, z, type); - if (precipprops[curWeather].randomstates > 0) + if (randomstates > 0 && randomstates < UINT8_MAX) { UINT8 mrand = M_RandomByte(); - UINT8 threshold = UINT8_MAX / (precipprops[curWeather].randomstates + 1); - statenum_t st = mobjinfo[precipprops[curWeather].type].spawnstate; + UINT8 threshold = UINT8_MAX / (randomstates + 1); + statenum_t st = mobjinfo[type].spawnstate; - for (k = 0; k < precipprops[curWeather].randomstates; k++) + for (k = 0; k < randomstates; k++) { if (mrand < (threshold * (k+1))) { diff --git a/src/p_spec.c b/src/p_spec.c index d92fb2f3b..1cca2cd5e 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2041,6 +2041,7 @@ void P_SwitchWeather(UINT8 newWeather) } else if (swap != MT_NULL) // Rather than respawn all that crap, reuse it! { + INT32 randomstates = mobjinfo[swap].damage; thinker_t *think; precipmobj_t *precipmobj; statenum_t st; @@ -2056,13 +2057,13 @@ void P_SwitchWeather(UINT8 newWeather) st = mobjinfo[swap].spawnstate; - if (precipprops[curWeather].randomstates > 0) + if (randomstates > 0 && randomstates < UINT8_MAX) { UINT8 mrand = M_RandomByte(); - UINT8 threshold = UINT8_MAX / (precipprops[curWeather].randomstates + 1); + UINT8 threshold = UINT8_MAX / (randomstates + 1); UINT8 i; - for (i = 0; i < precipprops[curWeather].randomstates; i++) + for (i = 0; i < randomstates; i++) { if (mrand < (threshold * (i+1))) { From 76e75d9756a9e07e66cdb17db84eeb6f76835948 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Sun, 1 Mar 2020 14:36:13 -0500 Subject: [PATCH 152/163] Fix offroad collision Adds an option to P_MobjTouchingSectorSpecial to only use non-FOF sectors' special if you're touching their floor/ceiling. --- src/k_kart.c | 2 +- src/lua_baselib.c | 3 ++- src/p_floor.c | 2 +- src/p_inter.c | 2 +- src/p_map.c | 6 ++--- src/p_mobj.c | 16 ++++--------- src/p_spec.c | 61 ++++++++++++++++++++++++++++++++++++++++------- src/p_spec.h | 2 +- 8 files changed, 66 insertions(+), 28 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 6c268269d..cb82dba93 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -1542,7 +1542,7 @@ static UINT8 K_CheckOffroadCollide(mobj_t *mo) for (i = 2; i < 5; i++) { - if (P_MobjTouchingSectorSpecial(mo, 1, i)) + if (P_MobjTouchingSectorSpecial(mo, 1, i, true)) return i-1; } diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 3d836dad2..bb7d1111b 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -1318,10 +1318,11 @@ static int lib_pMobjTouchingSectorSpecial(lua_State *L) mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); INT32 section = (INT32)luaL_checkinteger(L, 2); INT32 number = (INT32)luaL_checkinteger(L, 3); + boolean touchground = lua_optboolean(L, 4); //HUDSAFE if (!mo) return LUA_ErrInvalid(L, "mobj_t"); - LUA_PushUserdata(L, P_MobjTouchingSectorSpecial(mo, section, number), META_SECTOR); + LUA_PushUserdata(L, P_MobjTouchingSectorSpecial(mo, section, number, touchground), META_SECTOR); return 1; } diff --git a/src/p_floor.c b/src/p_floor.c index a4e4f2747..3621e0886 100644 --- a/src/p_floor.c +++ b/src/p_floor.c @@ -2275,7 +2275,7 @@ void T_EachTimeThinker(levelspecthink_t *eachtime) continue; if (!(players[i].mo->subsector->sector == sec - || P_MobjTouchingSectorSpecial(players[i].mo, 2, (GETSECSPECIAL(sec->special, 2))) == sec)) + || P_MobjTouchingSectorSpecial(players[i].mo, 2, (GETSECSPECIAL(sec->special, 2)), false) == sec)) continue; if (floortouch == true && P_IsObjectOnRealGround(players[i].mo, sec)) diff --git a/src/p_inter.c b/src/p_inter.c index a1a44c998..b81d3296d 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -925,7 +925,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck) special->fuse = 1; special->flags2 |= MF2_JUSTATTACKED; - if (!P_MobjTouchingSectorSpecial(player->mo, 4, 2 + flagteam)) + if (!P_MobjTouchingSectorSpecial(player->mo, 4, 2 + flagteam, false)) { CONS_Printf(M_GetText("%s returned the %c%s%c to base.\n"), plname, flagcolor, flagtext, 0x80); diff --git a/src/p_map.c b/src/p_map.c index 22e624311..19006fe49 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2790,10 +2790,10 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) fixed_t maxstep = FixedMul(MAXSTEPMOVE, mapobjectscale); // If using type Section1:13, double the maxstep. - if (P_MobjTouchingSectorSpecial(thing, 1, 13)) + if (P_MobjTouchingSectorSpecial(thing, 1, 13, false)) maxstep <<= 1; // If using type Section1:12, no maxstep. For short walls, like Egg Zeppelin - else if (P_MobjTouchingSectorSpecial(thing, 1, 12)) + else if (P_MobjTouchingSectorSpecial(thing, 1, 12, false)) maxstep = 0; if (thing->type == MT_SKIM) @@ -2817,7 +2817,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) return false; // mobj must lower itself to fit // Ramp test - if ((maxstep > 0) && !(P_MobjTouchingSectorSpecial(thing, 1, 14))) + if ((maxstep > 0) && !(P_MobjTouchingSectorSpecial(thing, 1, 14, false))) { // If the floor difference is MAXSTEPMOVE or less, and the sector isn't Section1:14, ALWAYS // step down! Formerly required a Section1:13 sector for the full MAXSTEPMOVE, but no more. diff --git a/src/p_mobj.c b/src/p_mobj.c index 1fd846ff1..2bb445e73 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -8355,7 +8355,7 @@ void P_MobjThinker(mobj_t *mobj) P_Thrust(mobj, mobj->angle, thrustamount); - if (P_MobjTouchingSectorSpecial(mobj, 3, 1)) + if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true)) K_DoPogoSpring(mobj, 0, 1); if (mobj->threshold > 0) @@ -8385,7 +8385,7 @@ void P_MobjThinker(mobj_t *mobj) K_DriftDustHandling(mobj); - if (P_MobjTouchingSectorSpecial(mobj, 3, 1)) + if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true)) K_DoPogoSpring(mobj, 0, 1); break; @@ -8437,14 +8437,8 @@ void P_MobjThinker(mobj_t *mobj) mobj->angle = R_PointToAngle2(0, 0, mobj->momx, mobj->momy); P_Thrust(mobj, mobj->angle, thrustamount); - if (grounded) - { - sector_t *sec2 = P_ThingOnSpecial3DFloor(mobj); - if ((sec2 && GETSECSPECIAL(sec2->special, 3) == 1) - || (P_IsObjectOnRealGround(mobj, mobj->subsector->sector) - && GETSECSPECIAL(mobj->subsector->sector->special, 3) == 1)) - K_DoPogoSpring(mobj, 0, 1); - } + if (P_MobjTouchingSectorSpecial(mobj, 3, 1, true)) + K_DoPogoSpring(mobj, 0, 1); if (mobj->threshold > 0) mobj->threshold--; @@ -9592,7 +9586,7 @@ void P_MobjThinker(mobj_t *mobj) break; case MT_BLUEFLAG: case MT_REDFLAG: - if (P_MobjTouchingSectorSpecial(mobj, 4, 2)) + if (P_MobjTouchingSectorSpecial(mobj, 4, 2, false)) mobj->fuse = 1; // Return to base. break; case MT_CANNONBALL: diff --git a/src/p_spec.c b/src/p_spec.c index 7786329ec..9ce9c9faf 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3371,11 +3371,12 @@ boolean P_IsFlagAtBase(mobjtype_t flag) // the particular type that it finds. // Returns NULL if it doesn't find it. // -// Sal: There was absolutely no reason for -// this to be a player_t only function. +// Sal: Couldn't see a reason for this to +// be a player_t only function. // -sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number) +sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number, boolean touchground) { + fixed_t topheight, bottomheight; msecnode_t *node; ffloor_t *rover; @@ -3384,13 +3385,34 @@ sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number) // Check default case first if (GETSECSPECIAL(mo->subsector->sector->special, section) == number) - return mo->subsector->sector; + { + if (touchground) + { + topheight = P_GetSpecialTopZ(mo, mo->subsector->sector, mo->subsector->sector); + bottomheight = P_GetSpecialBottomZ(mo, mo->subsector->sector, mo->subsector->sector); + + // Thing must be on top of the floor to be affected... + if (mo->subsector->sector->flags & SF_FLIPSPECIAL_FLOOR) + { + if (!(mo->eflags & MFE_VERTICALFLIP) && mo->z <= bottomheight) + return mo->subsector->sector; + } + + if (mo->subsector->sector->flags & SF_FLIPSPECIAL_CEILING) + { + if ((mo->eflags & MFE_VERTICALFLIP) && mo->z + mo->height >= topheight) + return mo->subsector->sector; + } + } + else + { + return mo->subsector->sector; + } + } // Hmm.. maybe there's a FOF that has it... for (rover = mo->subsector->sector->ffloors; rover; rover = rover->next) { - fixed_t topheight, bottomheight; - if (GETSECSPECIAL(rover->master->frontsector->special, section) != number) continue; @@ -3444,14 +3466,35 @@ sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number) // are we allowed to touch it? if (node->m_sector == mo->subsector->sector || (node->m_sector->flags & SF_TRIGGERSPECIAL_TOUCH)) - return node->m_sector; + { + if (touchground) + { + topheight = P_GetSpecialTopZ(mo, node->m_sector, node->m_sector); + bottomheight = P_GetSpecialBottomZ(mo, node->m_sector, node->m_sector); + + // Thing must be on top of the floor to be affected... + if (node->m_sector->flags & SF_FLIPSPECIAL_FLOOR) + { + if (!(mo->eflags & MFE_VERTICALFLIP) && mo->z <= bottomheight) + return node->m_sector; + } + + if (node->m_sector->flags & SF_FLIPSPECIAL_CEILING) + { + if ((mo->eflags & MFE_VERTICALFLIP) && mo->z + mo->height >= topheight) + return node->m_sector; + } + } + else + { + return node->m_sector; + } + } } // Hmm.. maybe there's a FOF that has it... for (rover = node->m_sector->ffloors; rover; rover = rover->next) { - fixed_t topheight, bottomheight; - if (GETSECSPECIAL(rover->master->frontsector->special, section) != number) continue; diff --git a/src/p_spec.h b/src/p_spec.h index 8431fcc75..eff7463ca 100644 --- a/src/p_spec.h +++ b/src/p_spec.h @@ -37,7 +37,7 @@ void P_SpawnSpecials(INT32 fromnetsave); // every tic void P_UpdateSpecials(void); -sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number); +sector_t *P_MobjTouchingSectorSpecial(mobj_t *mo, INT32 section, INT32 number, boolean touchground); void P_PlayerInSpecialSector(player_t *player); void P_ProcessSpecialSector(player_t *player, sector_t *sector, sector_t *roversector); From 0c1d0d8f5c74fb159a8935882375e481543c30c5 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Sun, 1 Mar 2020 14:56:16 -0500 Subject: [PATCH 153/163] Don't need abs here --- 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 2f514f526..1f2e5e3de 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11037,7 +11037,7 @@ void P_SpawnPrecipitation(void) if (precipsector->sector->ceilingpic != skyflatnum) continue; - height = abs(precipsector->sector->ceilingheight - precipsector->sector->floorheight); + height = precipsector->sector->ceilingheight - precipsector->sector->floorheight; // Exists, but is too small for reasonable precipitation. if (height < 64< Date: Sun, 1 Mar 2020 17:07:52 -0500 Subject: [PATCH 154/163] Remove our shadows --- src/k_kart.c | 164 ++++++++++++++++++++++++++++- src/p_local.h | 2 - src/p_mobj.c | 282 -------------------------------------------------- src/p_tick.c | 2 - 4 files changed, 162 insertions(+), 288 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index 230662d2a..e82f61413 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4345,6 +4345,167 @@ void K_RepairOrbitChain(mobj_t *orbit) } } +// Simplified version of a code bit in P_MobjFloorZ +static fixed_t K_BananaSlopeZ(pslope_t *slope, fixed_t x, fixed_t y, fixed_t radius, boolean ceiling) +{ + fixed_t testx, testy; + + if (slope->d.x < 0) + testx = radius; + else + testx = -radius; + + if (slope->d.y < 0) + testy = radius; + else + testy = -radius; + + if ((slope->zdelta > 0) ^ !!(ceiling)) + { + testx = -testx; + testy = -testy; + } + + testx += x; + testy += y; + + return P_GetZAt(slope, testx, testy); +} + +static void K_CalculateBananaSlope(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z, fixed_t radius, fixed_t height, boolean flip, boolean player) +{ + fixed_t newz; + sector_t *sec; +#ifdef ESLOPE + pslope_t *slope = NULL; +#endif + + sec = R_PointInSubsector(x, y)->sector; + + if (flip) + { +#ifdef ESLOPE + if (sec->c_slope) + { + slope = sec->c_slope; + newz = K_BananaSlopeZ(slope, x, y, radius, true); + } + else +#endif + newz = sec->ceilingheight; + } + else + { +#ifdef ESLOPE + if (sec->f_slope) + { + slope = sec->f_slope; + newz = K_BananaSlopeZ(slope, x, y, radius, false); + } + else +#endif + newz = sec->floorheight; + } + + // Check FOFs for a better suited slope + if (sec->ffloors) + { + ffloor_t *rover; + + for (rover = sec->ffloors; rover; rover = rover->next) + { + fixed_t top, bottom; + fixed_t d1, d2; + + if (!(rover->flags & FF_EXISTS)) + continue; + + if ((!(((rover->flags & FF_BLOCKPLAYER && player) + || (rover->flags & FF_BLOCKOTHERS && !player)) + || (rover->flags & FF_QUICKSAND)) + || (rover->flags & FF_SWIMMABLE))) + continue; + +#ifdef ESLOPE + if (*rover->t_slope) + top = K_BananaSlopeZ(*rover->t_slope, x, y, radius, false); + else +#endif + top = *rover->topheight; + +#ifdef ESLOPE + if (*rover->b_slope) + bottom = K_BananaSlopeZ(*rover->b_slope, x, y, radius, true); + else +#endif + bottom = *rover->bottomheight; + + if (flip) + { + if (rover->flags & FF_QUICKSAND) + { + if (z < top && (z + height) > bottom) + { + if (newz > (z + height)) + { + newz = (z + height); + slope = NULL; + } + } + continue; + } + + d1 = (z + height) - (top + ((bottom - top)/2)); + d2 = z - (top + ((bottom - top)/2)); + + if (bottom < newz && abs(d1) < abs(d2)) + { + newz = bottom; +#ifdef ESLOPE + if (*rover->b_slope) + slope = *rover->b_slope; +#endif + } + } + else + { + if (rover->flags & FF_QUICKSAND) + { + if (z < top && (z + height) > bottom) + { + if (newz < z) + { + newz = z; + slope = NULL; + } + } + continue; + } + + d1 = z - (bottom + ((top - bottom)/2)); + d2 = (z + height) - (bottom + ((top - bottom)/2)); + + if (top > newz && abs(d1) < abs(d2)) + { + newz = top; +#ifdef ESLOPE + if (*rover->t_slope) + slope = *rover->t_slope; +#endif + } + } + } + } + +#if 0 + mobj->standingslope = slope; +#endif + +#ifdef HWRENDER + mobj->modeltilt = slope; +#endif +} + // Move the hnext chain! static void K_MoveHeldObjects(player_t *player) { @@ -4532,8 +4693,7 @@ static void K_MoveHeldObjects(player_t *player) #ifdef ESLOPE if (P_IsObjectOnGround(cur)) { - // Slope values are set in the function, but we DON'T want to use its return value. - P_CalculateShadowFloor(cur, cur->x, cur->y, cur->z, + K_CalculateBananaSlope(cur, cur->x, cur->y, cur->z, cur->radius, cur->height, (cur->eflags & MFE_VERTICALFLIP), false); } #endif diff --git a/src/p_local.h b/src/p_local.h index 33f0026da..3ca171b24 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -228,8 +228,6 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state); boolean P_SetMobjState(mobj_t *mobj, statenum_t state); //void P_RunShields(void); void P_RunOverlays(void); -fixed_t P_CalculateShadowFloor(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z, fixed_t radius, fixed_t height, boolean flip, boolean player); -void P_RunShadows(void); void P_RunBattleOvertime(void); void P_MobjThinker(mobj_t *mobj); boolean P_RailThinker(mobj_t *mobj); diff --git a/src/p_mobj.c b/src/p_mobj.c index b220ff4e6..956d095f3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -47,7 +47,6 @@ consvar_t cv_splats = {"splats", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0 actioncache_t actioncachehead; static mobj_t *overlaycap = NULL; -static mobj_t *shadowcap = NULL; mobj_t *waypointcap = NULL; void P_InitCachedActions(void) @@ -6200,287 +6199,6 @@ static void P_RemoveOverlay(mobj_t *thing) } } -// Simplified version of a code bit in P_MobjFloorZ -static fixed_t P_ShadowSlopeZ(pslope_t *slope, fixed_t x, fixed_t y, fixed_t radius, boolean ceiling) -{ - fixed_t testx, testy; - - if (slope->d.x < 0) - testx = radius; - else - testx = -radius; - - if (slope->d.y < 0) - testy = radius; - else - testy = -radius; - - if ((slope->zdelta > 0) ^ !!(ceiling)) - { - testx = -testx; - testy = -testy; - } - - testx += x; - testy += y; - - return P_GetZAt(slope, testx, testy); -} - -// Sets standingslope/modeltilt, returns z position for shadows; used also for stuff like bananas -// (I would've preferred to be able to return both the slope & z, but I'll take what I can get...) -fixed_t P_CalculateShadowFloor(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z, fixed_t radius, fixed_t height, boolean flip, boolean player) -{ - fixed_t newz; - sector_t *sec; -#ifdef ESLOPE - pslope_t *slope = NULL; -#endif - - sec = R_PointInSubsector(x, y)->sector; - - if (flip) - { -#ifdef ESLOPE - if (sec->c_slope) - { - slope = sec->c_slope; - newz = P_ShadowSlopeZ(slope, x, y, radius, true); - } - else -#endif - newz = sec->ceilingheight; - } - else - { -#ifdef ESLOPE - if (sec->f_slope) - { - slope = sec->f_slope; - newz = P_ShadowSlopeZ(slope, x, y, radius, false); - } - else -#endif - newz = sec->floorheight; - } - - // Check FOFs for a better suited slope - if (sec->ffloors) - { - ffloor_t *rover; - - for (rover = sec->ffloors; rover; rover = rover->next) - { - fixed_t top, bottom; - fixed_t d1, d2; - - if (!(rover->flags & FF_EXISTS)) - continue; - - if ((!(((rover->flags & FF_BLOCKPLAYER && player) - || (rover->flags & FF_BLOCKOTHERS && !player)) - || (rover->flags & FF_QUICKSAND)) - || (rover->flags & FF_SWIMMABLE))) - continue; - -#ifdef ESLOPE - if (*rover->t_slope) - top = P_ShadowSlopeZ(*rover->t_slope, x, y, radius, false); - else -#endif - top = *rover->topheight; - -#ifdef ESLOPE - if (*rover->b_slope) - bottom = P_ShadowSlopeZ(*rover->b_slope, x, y, radius, true); - else -#endif - bottom = *rover->bottomheight; - - if (flip) - { - if (rover->flags & FF_QUICKSAND) - { - if (z < top && (z + height) > bottom) - { - if (newz > (z + height)) - { - newz = (z + height); - slope = NULL; - } - } - continue; - } - - d1 = (z + height) - (top + ((bottom - top)/2)); - d2 = z - (top + ((bottom - top)/2)); - - if (bottom < newz && abs(d1) < abs(d2)) - { - newz = bottom; -#ifdef ESLOPE - if (*rover->b_slope) - slope = *rover->b_slope; -#endif - } - } - else - { - if (rover->flags & FF_QUICKSAND) - { - if (z < top && (z + height) > bottom) - { - if (newz < z) - { - newz = z; - slope = NULL; - } - } - continue; - } - - d1 = z - (bottom + ((top - bottom)/2)); - d2 = (z + height) - (bottom + ((top - bottom)/2)); - - if (top > newz && abs(d1) < abs(d2)) - { - newz = top; -#ifdef ESLOPE - if (*rover->t_slope) - slope = *rover->t_slope; -#endif - } - } - } - } - -#if 0 - mobj->standingslope = slope; -#endif -#ifdef HWRENDER - mobj->modeltilt = slope; -#endif - - return newz; -} - -void P_RunShadows(void) -{ - mobj_t *mobj, *next, *dest; - - for (mobj = shadowcap; mobj; mobj = next) - { - boolean flip; - fixed_t newz; - - next = mobj->hnext; - P_SetTarget(&mobj->hnext, NULL); - - if (!mobj->target || P_MobjWasRemoved(mobj->target)) - { - mobj->flags2 |= MF2_DONTDRAW; - continue; // shouldn't you already be dead? - } - - K_MatchGenericExtraFlags(mobj, mobj->target); - flip = (mobj->eflags & MFE_VERTICALFLIP); - - newz = P_CalculateShadowFloor(mobj, mobj->target->x, mobj->target->y, mobj->target->z, - mobj->target->radius, mobj->target->height, flip, (mobj->target->player != NULL)); - - if (flip) - { - if ((mobj->target->z + mobj->target->height) > newz) - mobj->flags2 |= MF2_DONTDRAW; - } - else - { - if (mobj->target->z < newz) - mobj->flags2 |= MF2_DONTDRAW; - } - - // First scale to the same radius - P_SetScale(mobj, FixedDiv(mobj->target->radius, mobj->info->radius)); - - dest = mobj->target; - - if (dest->type == MT_THUNDERSHIELD) - dest = dest->target; - - P_TeleportMove(mobj, dest->x, dest->y, mobj->target->z); - - if ((flip && newz > (mobj->z + mobj->height)) || (!flip && newz < mobj->z)) - { - INT32 i; - fixed_t prevz; - - mobj->z = newz; - - for (i = 0; i < MAXFFLOORS; i++) - { - prevz = mobj->z; - - // Now scale again based on height difference - P_SetScale(mobj, FixedDiv(mobj->scale, max(FRACUNIT, ((mobj->target->z-mobj->z)/200)+FRACUNIT))); - - // Check new position to see if you should still be on that ledge - P_TeleportMove(mobj, dest->x, dest->y, mobj->z); - - mobj->z = newz; - - if (mobj->z == prevz) - break; - } - } - - if (mobj->target->type == MT_FLOATINGITEM) - P_SetScale(mobj, mobj->scale/3); - } - P_SetTarget(&shadowcap, NULL); -} - -// called whenever shadows think -// It must be done this way so that level changes don't break when the shadowcap can't be reset -static void P_AddShadow(mobj_t *thing) -{ - I_Assert(thing != NULL); - - if (shadowcap == NULL) - P_SetTarget(&shadowcap, thing); - else { - mobj_t *mo; - for (mo = shadowcap; mo && mo->hnext; mo = mo->hnext) - ; - - I_Assert(mo != NULL); - I_Assert(mo->hnext == NULL); - - P_SetTarget(&mo->hnext, thing); - } - P_SetTarget(&thing->hnext, NULL); -} - -// Called only when MT_SHADOW (or anything else in the shadowcap list) is removed. -// Keeps the hnext list from corrupting. -static void P_RemoveShadow(mobj_t *thing) -{ - mobj_t *mo; - if (shadowcap == thing) - { - P_SetTarget(&shadowcap, thing->hnext); - P_SetTarget(&thing->hnext, NULL); - return; - } - - for (mo = shadowcap; mo; mo = mo->hnext) - if (mo->hnext == thing) - { - P_SetTarget(&mo->hnext, thing->hnext); - P_SetTarget(&thing->hnext, NULL); - return; - } -} - // SAL'S KART BATTLE MODE OVERTIME HANDLER #define MAXPLANESPERSECTOR (MAXFFLOORS+1)*2 static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, fixed_t scale, mobjtype_t type, boolean ceiling) diff --git a/src/p_tick.c b/src/p_tick.c index b285c35d0..9c73f6946 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -658,8 +658,6 @@ void P_Ticker(boolean run) //P_RunShields(); P_RunOverlays(); - P_RunShadows(); - P_UpdateSpecials(); P_RespawnSpecials(); From 30d391b6b207471a4763e39f0c3e9c4e5831aa83 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Sun, 1 Mar 2020 17:35:49 -0500 Subject: [PATCH 155/163] FINISH removing the shadows... --- src/dehacked.c | 2 - src/info.c | 33 +---------- src/info.h | 4 -- src/lua_baselib.c | 11 ---- src/p_local.h | 2 - src/p_mobj.c | 146 ---------------------------------------------- 6 files changed, 1 insertion(+), 197 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 5f9249d89..4d72835bb 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7849,8 +7849,6 @@ static const char *const MOBJTYPE_LIST[] = { // array length left dynamic for s "MT_LAMPPOST", "MT_MOSSYTREE", - "MT_SHADOW", - "MT_BUMP", "MT_FLINGENERGY", diff --git a/src/info.c b/src/info.c index 4f448cc00..06ac8d9d4 100644 --- a/src/info.c +++ b/src/info.c @@ -60,7 +60,7 @@ char sprnames[NUMSPRITES + 1][5] = "WIPD","DRIF","BDRF","DUST","RSHE","FITM","BANA","ORBN","JAWZ","SSMN", "KRBM","BHOG","BHBM","SPBM","THNS","SINK","SITR","KBLN","DEZL","POKE", "AUDI","DECO","DOOD","SNES","GBAS","SPRS","BUZB","CHOM","SACO","CRAB", - "SHAD","BRNG","BUMP","FLEN","CLAS","PSHW","ISTA","ISTB","ARRO","ITEM", + "BRNG","BUMP","FLEN","CLAS","PSHW","ISTA","ISTB","ARRO","ITEM", "ITMO","ITMI","ITMN","WANT","PBOM","HIT1","HIT2","HIT3","RETI","AIDU", "KSPK","LZI1","LZI2","KLIT","FZSM","FZBM","FPRT","SBUS","MARB","FUFO", "RUST","BLON","VAPE","HTZA","HTZB","SGVA","SGVB","SGVC","PGTR","PGF1", @@ -2988,10 +2988,6 @@ state_t states[NUMSTATES] = {SPR_CRAB, 10, -1, {NULL}, 0, 0, S_NULL}, // S_LAMPPOST {SPR_CRAB, 11, -1, {NULL}, 0, 0, S_NULL}, // S_MOSSYTREE - // Fake Shadow - {SPR_SHAD, FF_TRANS50, -1, {NULL}, 0, 0, S_NULL}, // S_SHADOW - {SPR_SHAD, FF_FULLBRIGHT|FF_TRANS50|1, -1, {NULL}, 0, 0, S_NULL}, // S_WHITESHADOW - {SPR_BUMP, FF_FULLBRIGHT, 3, {NULL}, 0, 0, S_BUMP2}, // S_BUMP1 {SPR_BUMP, FF_FULLBRIGHT|1, 3, {NULL}, 0, 0, S_BUMP3}, // S_BUMP2 {SPR_BUMP, FF_FULLBRIGHT|2, 3, {NULL}, 0, 0, S_NULL}, // S_BUMP3 @@ -17251,33 +17247,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = S_NULL // raisestate }, - { // MT_SHADOW - -1, // doomednum - S_SHADOW, // 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 - 60*FRACUNIT, // speed - 50*FRACUNIT, // radius - 1*FRACUNIT, // height - -1, // display offset - 100, // mass - 0, // damage - sfx_None, // activesound - MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags - S_NULL // raisestate - }, - { // MT_BUMP -1, // doomednum S_BUMP1, // spawnstate diff --git a/src/info.h b/src/info.h index 27488d916..a3283217c 100644 --- a/src/info.h +++ b/src/info.h @@ -639,7 +639,6 @@ typedef enum sprite SPR_CHOM, // Sapphire Coast Chomper SPR_SACO, // Sapphire Coast Fauna SPR_CRAB, // Crystal Abyss mobs - SPR_SHAD, // TD shadows SPR_BRNG, // Chaotix Big Ring SPR_BUMP, // Player/shell bump @@ -3668,9 +3667,6 @@ typedef enum state S_LAMPPOST, S_MOSSYTREE, - S_SHADOW, - S_WHITESHADOW, - S_BUMP1, S_BUMP2, S_BUMP3, diff --git a/src/lua_baselib.c b/src/lua_baselib.c index 7464743c3..da0a60801 100644 --- a/src/lua_baselib.c +++ b/src/lua_baselib.c @@ -639,16 +639,6 @@ static int lib_pCheckSolidLava(lua_State *L) return 1; } -static int lib_pSpawnShadowMobj(lua_State *L) -{ - mobj_t *caster = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ)); - NOHUD - if (!caster) - return LUA_ErrInvalid(L, "mobj_t"); - P_SpawnShadowMobj(caster); - return 0; -} - // P_USER //////////// @@ -2672,7 +2662,6 @@ static luaL_Reg lib[] = { {"P_InsideANonSolidFFloor",lib_pInsideANonSolidFFloor}, {"P_CheckDeathPitCollide",lib_pCheckDeathPitCollide}, {"P_CheckSolidLava",lib_pCheckSolidLava}, - {"P_SpawnShadowMobj",lib_pSpawnShadowMobj}, // p_user {"P_GetPlayerHeight",lib_pGetPlayerHeight}, diff --git a/src/p_local.h b/src/p_local.h index 3ca171b24..1358bf195 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -216,8 +216,6 @@ void P_RespawnSpecials(void); mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type); -mobj_t *P_SpawnShadowMobj(mobj_t * caster); - void P_RecalcPrecipInSector(sector_t *sector); void P_PrecipitationEffects(void); diff --git a/src/p_mobj.c b/src/p_mobj.c index 956d095f3..774fe45bc 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6610,15 +6610,6 @@ void P_MobjThinker(mobj_t *mobj) P_AddOverlay(mobj); break; - case MT_SHADOW: - if (!mobj->target) - { - P_RemoveMobj(mobj); - return; - } - - P_AddShadow(mobj); - break; /*case MT_BLACKORB: case MT_WHITEORB: case MT_GREENORB: @@ -10298,29 +10289,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) break; } - switch (mobj->type) - { - case MT_PLAYER: - case MT_SMALLMACE: case MT_BIGMACE: - case MT_PUMA: case MT_BIGPUMA: - case MT_FALLINGROCK: - case MT_SMK_MOLE: case MT_SMK_THWOMP: - //case MT_RANDOMITEM: - case MT_FLOATINGITEM: - case MT_BATTLEBUMPER: - case MT_BANANA: case MT_BANANA_SHIELD: - //case MT_EGGMANITEM: case MT_EGGMANITEM_SHIELD: - case MT_ORBINAUT: case MT_ORBINAUT_SHIELD: - case MT_JAWZ: case MT_JAWZ_DUD: case MT_JAWZ_SHIELD: - case MT_SSMINE: case MT_SSMINE_SHIELD: - case MT_BALLHOG: case MT_SINK: - case MT_THUNDERSHIELD: case MT_ROCKETSNEAKER: - case MT_SPB: - P_SpawnShadowMobj(mobj); - default: - break; - } - if (!(mobj->flags & MF_NOTHINK)) P_AddThinker(&mobj->thinker); @@ -10356,120 +10324,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) return mobj; } -// -// P_SpawnShadowMobj -// warning: Do not send a shadow mobj as a caster into here, or try to spawn spawn shadows for shadows in P_SpawnMobj, we do not want recursive shadows -// -mobj_t *P_SpawnShadowMobj(mobj_t * caster) -{ - const mobjinfo_t *info = &mobjinfo[MT_SHADOW]; - state_t *st; - mobj_t *mobj = Z_Calloc(sizeof (*mobj), PU_LEVEL, NULL); - - // this is officially a mobj, declared as soon as possible. - mobj->thinker.function.acp1 = (actionf_p1)P_MobjThinker; - mobj->type = MT_SHADOW; - mobj->info = info; - - mobj->x = caster->x; - mobj->y = caster->y; - - mobj->radius = info->radius; - mobj->height = info->height; - mobj->flags = info->flags; - - mobj->health = info->spawnhealth; - - mobj->reactiontime = info->reactiontime; - - mobj->lastlook = -1; // stuff moved in P_enemy.P_LookForPlayer - - // do not set the state with P_SetMobjState, - // because action routines can not be called yet - if (caster->frame & FF_FULLBRIGHT) - st = &states[S_WHITESHADOW]; - else - st = &states[info->spawnstate]; - - mobj->state = st; - mobj->tics = st->tics; - mobj->sprite = st->sprite; - mobj->frame = st->frame; // FF_FRAMEMASK for frame, and other bits.. - P_SetupStateAnimation(mobj, st); - - mobj->friction = ORIG_FRICTION; - - mobj->movefactor = ORIG_FRICTION_FACTOR; - - // All mobjs are created at 100% scale. - mobj->scale = FRACUNIT; - mobj->destscale = mobj->scale; - mobj->scalespeed = FRACUNIT/12; - - if (mapobjectscale != FRACUNIT) //&& !(mobj->type == MT_BLACKEGGMAN) - { - mobj->destscale = mapobjectscale; - mobj->scalespeed = mapobjectscale/12; - } - - P_SetScale(mobj, mobj->destscale); - - // set subsector and/or block links - P_SetThingPosition(mobj); - I_Assert(mobj->subsector != NULL); - - // Make sure scale matches destscale immediately when spawned - P_SetScale(mobj, mobj->destscale); - - mobj->floorz = mobj->subsector->sector->floorheight; - mobj->ceilingz = mobj->subsector->sector->ceilingheight; - - // Tells MobjCheckWater that the water height was not set. - mobj->watertop = INT32_MAX; - - mobj->z = mobj->floorz; - - // defaults onground - if (mobj->z == mobj->floorz) - mobj->eflags |= MFE_ONGROUND; - - if (!(mobj->flags & MF_NOTHINK)) - P_AddThinker(&mobj->thinker); - - // Call action functions when the state is set - if (st->action.acp1 && (mobj->flags & MF_RUNSPAWNFUNC)) - { - if (levelloading) - { - // Cache actions in a linked list - // with function pointer, and - // var1 & var2, which will be executed - // when the level finishes loading. - P_AddCachedAction(mobj, mobj->info->spawnstate); - } - else - { - var1 = st->var1; - var2 = st->var2; -#ifdef HAVE_BLUA - astate = st; -#endif - st->action.acp1(mobj); - // DANGER! This is the ONLY way for P_SpawnMobj to return NULL! - // Avoid using MF_RUNSPAWNFUNC on mobjs whose spawn state expects target or tracer to already be set! - if (P_MobjWasRemoved(mobj)) - return NULL; - } - } - - if (CheckForReverseGravity && !(mobj->flags & MF_NOBLOCKMAP)) - P_CheckGravity(mobj, false); - - P_SetTarget(&mobj->target, caster); // set the shadow's caster as the target - - return mobj; -} - static precipmobj_t *P_SpawnPrecipMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) { state_t *st; From 7a3733d75c8c5404efbeef5d1f99693f9ea4b068 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Sun, 1 Mar 2020 17:37:10 -0500 Subject: [PATCH 156/163] More remenants --- src/dehacked.c | 3 --- src/p_mobj.c | 3 --- 2 files changed, 6 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index 4d72835bb..aa3080879 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -6779,9 +6779,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_LAMPPOST", "S_MOSSYTREE", - "S_SHADOW", - "S_WHITESHADOW", - "S_BUMP1", "S_BUMP2", "S_BUMP3", diff --git a/src/p_mobj.c b/src/p_mobj.c index 774fe45bc..7c0c3d882 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10448,9 +10448,6 @@ void P_RemoveMobj(mobj_t *mobj) if (mobj->type == MT_OVERLAY) P_RemoveOverlay(mobj); - if (mobj->type == MT_SHADOW) - P_RemoveShadow(mobj); - if (mobj->type == MT_SPB) spbplace = -1; From 834225c597e7fd9b5f5e0430a9f73010e41525e5 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Sun, 1 Mar 2020 17:50:58 -0500 Subject: [PATCH 157/163] One more... I swear it's the last... --- src/info.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/info.h b/src/info.h index a3283217c..2b0e8e07f 100644 --- a/src/info.h +++ b/src/info.h @@ -4766,8 +4766,6 @@ typedef enum mobj_type MT_LAMPPOST, MT_MOSSYTREE, - MT_SHADOW, - MT_BUMP, MT_FLINGENERGY, From 18637b9eb2052dd52c32d509268cf1512f4603e3 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Sun, 1 Mar 2020 22:12:50 -0500 Subject: [PATCH 158/163] 2.2 shadow port --- src/hardware/hw_main.c | 314 +++++++++------------------- src/k_kart.c | 1 + src/lua_mobjlib.c | 18 +- src/p_inter.c | 1 + src/p_mobj.c | 64 ++++++ src/p_mobj.h | 3 + src/r_main.c | 4 +- src/r_main.h | 2 +- src/r_things.c | 454 ++++++++++++++++++++++++++++++++++++----- src/r_things.h | 13 +- 10 files changed, 598 insertions(+), 276 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 659af386d..281812469 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -39,6 +39,7 @@ #include "../st_stuff.h" #include "../i_system.h" #include "../m_cheat.h" +#include "../r_things.h" // R_GetShadowZ #ifdef ESLOPE #include "../p_slopes.h" #endif @@ -4058,37 +4059,6 @@ static gr_vissprite_t *HWR_NewVisSprite(void) return HWR_GetVisSprite(gr_visspritecount++); } -// Finds a floor through which light does not pass. -static fixed_t HWR_OpaqueFloorAtPos(fixed_t x, fixed_t y, fixed_t z, fixed_t height) -{ - const sector_t *sec = R_PointInSubsector(x, y)->sector; - fixed_t floorz = sec->floorheight; - - if (sec->ffloors) - { - ffloor_t *rover; - fixed_t delta1, delta2; - const fixed_t thingtop = z + height; - - for (rover = sec->ffloors; rover; rover = rover->next) - { - if (!(rover->flags & FF_EXISTS) - || !(rover->flags & FF_RENDERPLANES) - || rover->flags & FF_TRANSLUCENT - || rover->flags & FF_FOG - || rover->flags & FF_INVERTPLANES) - continue; - - delta1 = z - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)); - delta2 = thingtop - (*rover->bottomheight + ((*rover->topheight - *rover->bottomheight)/2)); - if (*rover->topheight > floorz && abs(delta1) < abs(delta2)) - floorz = *rover->topheight; - } - } - - return floorz; -} - // // HWR_DoCulling // Hardware version of R_DoCulling @@ -4129,185 +4099,116 @@ static boolean HWR_DoCulling(line_t *cullheight, line_t *viewcullheight, float v return false; } -static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float this_scale) +static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale) { - FOutVector swallVerts[4]; + GLPatch_t *gpatch; + FOutVector shadowVerts[4]; FSurfaceInfo sSurf; - fixed_t floorheight, mobjfloor; - float offset = 0; + float fscale; float fx; float fy; float offset; + UINT8 lightlevel = 0; + extracolormap_t *colormap = NULL; + UINT8 i; - mobjfloor = HWR_OpaqueFloorAtPos( - spr->mobj->x, spr->mobj->y, - spr->mobj->z, spr->mobj->height); - if (cv_shadowoffs.value) + INT32 light; + fixed_t scalemul; + UINT16 alpha; + fixed_t floordiff; + fixed_t floorz; + fixed_t slopez; + pslope_t *floorslope; + + floorz = R_GetShadowZ(thing, &floorslope); + floordiff = abs(thing->z - floorz); + + alpha = floordiff / (4*FRACUNIT) + 75; + if (alpha >= 255) return; + alpha = 255 - alpha; + + if (thing->whiteshadow) { - angle_t shadowdir; - - // Set direction - if (splitscreen && stplyr == &players[displayplayers[1]]) - shadowdir = localangle[1] + FixedAngle(cv_cam2_rotate.value); - else if (splitscreen > 1 && stplyr == &players[displayplayers[2]]) - shadowdir = localangle[2] + FixedAngle(cv_cam3_rotate.value); - else if (splitscreen > 2 && stplyr == &players[displayplayers[3]]) - shadowdir = localangle[3] + FixedAngle(cv_cam4_rotate.value); - else - shadowdir = localangle[0] + FixedAngle(cv_cam_rotate.value); - - // Find floorheight - floorheight = HWR_OpaqueFloorAtPos( - spr->mobj->x + P_ReturnThrustX(spr->mobj, shadowdir, spr->mobj->z - mobjfloor), - spr->mobj->y + P_ReturnThrustY(spr->mobj, shadowdir, spr->mobj->z - mobjfloor), - spr->mobj->z, spr->mobj->height); - - // The shadow is falling ABOVE it's mobj? - // Don't draw it, then! - if (spr->mobj->z < floorheight) - return; - else - { - fixed_t floorz; - floorz = HWR_OpaqueFloorAtPos( - spr->mobj->x + P_ReturnThrustX(spr->mobj, shadowdir, spr->mobj->z - floorheight), - spr->mobj->y + P_ReturnThrustY(spr->mobj, shadowdir, spr->mobj->z - floorheight), - spr->mobj->z, spr->mobj->height); - // The shadow would be falling on a wall? Don't draw it, then. - // Would draw midair otherwise. - if (floorz < floorheight) - return; - } - - floorheight = FixedInt(spr->mobj->z - floorheight); - - offset = floorheight; + gpatch = (GLPatch_t *)W_CachePatchName("LSHADOW", PU_CACHE); + lightlevel = 255; } else - floorheight = FixedInt(spr->mobj->z - mobjfloor); + { + gpatch = (GLPatch_t *)W_CachePatchName("DSHADOW", PU_CACHE); + lightlevel = 0; + } + + if (!(gpatch && gpatch->mipmap.grInfo.format)) return; + HWR_GetPatch(gpatch); + + scalemul = FixedMul(FRACUNIT - floordiff/640, scale); + scalemul = FixedMul(scalemul, (thing->radius*2) / gpatch->height); + + fscale = FIXED_TO_FLOAT(scalemul); + fx = FIXED_TO_FLOAT(thing->x); + fy = FIXED_TO_FLOAT(thing->y); - // create the sprite billboard - // // 3--2 // | /| // |/ | // 0--1 - // x1/x2 were already scaled in HWR_ProjectSprite - // First match the normal sprite - swallVerts[0].x = swallVerts[3].x = spr->x1; - swallVerts[2].x = swallVerts[1].x = spr->x2; - swallVerts[0].z = swallVerts[3].z = spr->z1; - swallVerts[2].z = swallVerts[1].z = spr->z2; - - if (spr->mobj && fabsf(this_scale - 1.0f) > 1.0E-36f) - { - // Always a pixel above the floor, perfectly flat. - swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset * this_scale - (floorheight+3); - - // Now transform the TOP vertices along the floor in the direction of the camera - swallVerts[3].x = spr->x1 + ((gpatch->height * this_scale) + offset) * gr_viewcos; - swallVerts[2].x = spr->x2 + ((gpatch->height * this_scale) + offset) * gr_viewcos; - swallVerts[3].z = spr->z1 + ((gpatch->height * this_scale) + offset) * gr_viewsin; - swallVerts[2].z = spr->z2 + ((gpatch->height * this_scale) + offset) * gr_viewsin; - } + if (thing && fabsf(fscale - 1.0f) > 1.0E-36f) + offset = (gpatch->height/2) * fscale; else - { - // Always a pixel above the floor, perfectly flat. - swallVerts[0].y = swallVerts[1].y = swallVerts[2].y = swallVerts[3].y = spr->ty - gpatch->topoffset - (floorheight+3); + offset = (float)(gpatch->height/2); - // Now transform the TOP vertices along the floor in the direction of the camera - swallVerts[3].x = spr->x1 + (gpatch->height + offset) * gr_viewcos; - swallVerts[2].x = spr->x2 + (gpatch->height + offset) * gr_viewcos; - swallVerts[3].z = spr->z1 + (gpatch->height + offset) * gr_viewsin; - swallVerts[2].z = spr->z2 + (gpatch->height + offset) * gr_viewsin; + shadowVerts[2].x = shadowVerts[3].x = fx + offset; + shadowVerts[1].x = shadowVerts[0].x = fx - offset; + shadowVerts[1].z = shadowVerts[2].z = fy - offset; + shadowVerts[0].z = shadowVerts[3].z = fy + offset; + + for (i = 0; i < 4; i++) + { + float oldx = shadowVerts[i].x; + float oldy = shadowVerts[i].z; + shadowVerts[i].x = fx + ((oldx - fx) * gr_viewcos) - ((oldy - fy) * gr_viewsin); + shadowVerts[i].z = fy + ((oldx - fx) * gr_viewsin) + ((oldy - fy) * gr_viewcos); } - // We also need to move the bottom ones away when shadowoffs is on - if (cv_shadowoffs.value) + if (floorslope) { - swallVerts[0].x = spr->x1 + offset * gr_viewcos; - swallVerts[1].x = spr->x2 + offset * gr_viewcos; - swallVerts[0].z = spr->z1 + offset * gr_viewsin; - swallVerts[1].z = spr->z2 + offset * gr_viewsin; - } - - if (spr->flip) - { - swallVerts[0].sow = swallVerts[3].sow = gpatch->max_s; - swallVerts[2].sow = swallVerts[1].sow = 0; - } - else - { - swallVerts[0].sow = swallVerts[3].sow = 0; - swallVerts[2].sow = swallVerts[1].sow = gpatch->max_s; - } - - // flip the texture coords (look familiar?) - if (spr->vflip) - { - swallVerts[3].tow = swallVerts[2].tow = gpatch->max_t; - swallVerts[0].tow = swallVerts[1].tow = 0; - } - else - { - swallVerts[3].tow = swallVerts[2].tow = 0; - swallVerts[0].tow = swallVerts[1].tow = gpatch->max_t; - } - - sSurf.FlatColor.s.red = 0x00; - sSurf.FlatColor.s.blue = 0x00; - sSurf.FlatColor.s.green = 0x00; - - /*if (spr->mobj->frame & FF_TRANSMASK || spr->mobj->flags2 & MF2_SHADOW) - { - sector_t *sector = spr->mobj->subsector->sector; - UINT8 lightlevel = 255; - extracolormap_t *colormap = sector->extra_colormap; - - if (sector->numlights) + for (i = 0; i < 4; i++) { - INT32 light = R_GetPlaneLight(sector, spr->mobj->floorz, false); - - if (!(spr->mobj->frame & FF_FULLBRIGHT)) - { - lightlevel = *sector->lightlist[light].lightlevel; - if (spr->mobj->frame & FF_SEMIBRIGHT) - lightlevel = 128 + (lightlevel>>1); - } - - if (sector->lightlist[light].extra_colormap) - colormap = sector->lightlist[light].extra_colormap; + slopez = P_GetZAt(floorslope, FLOAT_TO_FIXED(shadowVerts[i].x), FLOAT_TO_FIXED(shadowVerts[i].z)); + shadowVerts[i].y = FIXED_TO_FLOAT(slopez) + 0.05f; } - else - { - lightlevel = sector->lightlevel; - - if (sector->extra_colormap) - colormap = sector->extra_colormap; - } - - if (colormap) - sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, colormap->rgba, colormap->fadergba, false, true); - else - sSurf.FlatColor.rgba = HWR_Lighting(lightlevel/2, NORMALFOG, FADEFOG, false, true); - }*/ - - // shadow is always half as translucent as the sprite itself - if (!cv_translucency.value) // use default translucency (main sprite won't have any translucency) - sSurf.FlatColor.s.alpha = 0x80; // default - else if (spr->mobj->flags2 & MF2_SHADOW) - sSurf.FlatColor.s.alpha = 0x20; - else if (spr->mobj->frame & FF_TRANSMASK) - { - HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &sSurf); - sSurf.FlatColor.s.alpha /= 2; //cut alpha in half! } else - sSurf.FlatColor.s.alpha = 0x80; // default - - if (sSurf.FlatColor.s.alpha > floorheight/4) { - sSurf.FlatColor.s.alpha = (UINT8)(sSurf.FlatColor.s.alpha - floorheight/4); - HWD.pfnDrawPolygon(&sSurf, swallVerts, 4, PF_Translucent|PF_Modulated|PF_Clip); + for (i = 0; i < 4; i++) + shadowVerts[i].y = FIXED_TO_FLOAT(floorz) + 0.05f; } + + shadowVerts[0].sow = shadowVerts[3].sow = 0; + shadowVerts[2].sow = shadowVerts[1].sow = gpatch->max_s; + + shadowVerts[3].tow = shadowVerts[2].tow = 0; + shadowVerts[0].tow = shadowVerts[1].tow = gpatch->max_t; + + if (thing->subsector->sector->numlights) + { + light = R_GetPlaneLight(thing->subsector->sector, floorz, false); // Always use the light at the top instead of whatever I was doing before + + if (thing->subsector->sector->lightlist[light].extra_colormap) + colormap = thing->subsector->sector->lightlist[light].extra_colormap; + } + else + { + if (thing->subsector->sector->extra_colormap) + colormap = thing->subsector->sector->extra_colormap; + } + + if (colormap) + sSurf.FlatColor.rgba = HWR_Lighting(lightlevel, colormap->rgba, colormap->fadergba, false, false); + else + sSurf.FlatColor.rgba = HWR_Lighting(lightlevel, NORMALFOG, FADEFOG, false, false); + + sSurf.FlatColor.s.alpha = alpha; + + HWD.pfnDrawPolygon(&sSurf, shadowVerts, 4, PF_Translucent|PF_Modulated|PF_Clip); } // This is expecting a pointer to an array containing 4 wallVerts for a sprite @@ -4384,22 +4285,6 @@ static void HWR_SplitSprite(gr_vissprite_t *spr) //Hurdler: 25/04/2000: now support colormap in hardware mode HWR_GetMappedPatch(gpatch, spr->colormap); - // Draw shadow BEFORE sprite - if (cv_shadow.value // Shadows enabled - && (spr->mobj->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow. - && !(spr->mobj->flags2 & MF2_DEBRIS) // Debris have no corona or shadow. -#ifdef ALAM_LIGHTING - && !(t_lspr[spr->mobj->sprite]->type // Things with dynamic lights have no shadow. - && (!spr->mobj->player || spr->mobj->player->powers[pw_super])) // Except for non-super players. -#endif - && (spr->mobj->z >= spr->mobj->floorz)) // Without this, your shadow shows on the floor, even after you die and fall through the ground. - { - //////////////////// - // SHADOW SPRITE! // - //////////////////// - HWR_DrawSpriteShadow(spr, gpatch, this_scale); - } - baseWallVerts[0].x = baseWallVerts[3].x = spr->x1; baseWallVerts[2].x = baseWallVerts[1].x = spr->x2; baseWallVerts[0].z = baseWallVerts[3].z = spr->z1; @@ -4802,22 +4687,6 @@ static void HWR_DrawSprite(gr_vissprite_t *spr) //Hurdler: 25/04/2000: now support colormap in hardware mode HWR_GetMappedPatch(gpatch, spr->colormap); - // Draw shadow BEFORE sprite - if (cv_shadow.value // Shadows enabled - && (spr->mobj->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow. - && !(spr->mobj->flags2 & MF2_DEBRIS) // Debris have no corona or shadow. -#ifdef ALAM_LIGHTING - && !(t_lspr[spr->mobj->sprite]->type // Things with dynamic lights have no shadow. - && (!spr->mobj->player || spr->mobj->player->powers[pw_super])) // Except for non-super players. -#endif - && (spr->mobj->z >= spr->mobj->floorz)) // Without this, your shadow shows on the floor, even after you die and fall through the ground. - { - //////////////////// - // SHADOW SPRITE! // - //////////////////// - HWR_DrawSpriteShadow(spr, gpatch, this_scale); - } - // if it has a dispoffset, push it a little towards the camera if (spr->dispoffset) { float co = -gr_viewcos*(0.05f*spr->dispoffset); @@ -5430,6 +5299,12 @@ static void HWR_DrawSprites(void) HWR_DrawPrecipitationSprite(spr); else #endif + { + if (spr->mobj && spr->mobj->shadowscale && cv_shadow.value) + { + HWR_DrawDropShadow(spr->mobj, spr->mobj->shadowscale); + } + if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY) { // 8/1/19: Only don't display player models if no default SPR_PLAY is found. @@ -5445,6 +5320,7 @@ static void HWR_DrawSprites(void) else HWR_DrawMD2(spr); } + } } } } diff --git a/src/k_kart.c b/src/k_kart.c index e82f61413..10e395d0e 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6212,6 +6212,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground) P_SetMobjState(ring, S_FASTRING1); ring->extravalue1 = 1; // Ring use animation timer ring->extravalue2 = 1; // Ring use animation flag + ring->shadowscale = 0; P_SetTarget(&ring->target, player->mo); // user player->kartstuff[k_rings]--; player->kartstuff[k_ringdelay] = 3; diff --git a/src/lua_mobjlib.c b/src/lua_mobjlib.c index dfb344e34..47efd729f 100644 --- a/src/lua_mobjlib.c +++ b/src/lua_mobjlib.c @@ -85,7 +85,9 @@ enum mobj_e { #ifdef ESLOPE mobj_standingslope, #endif - mobj_colorized + mobj_colorized, + mobj_shadowscale, + mobj_whiteshadow }; static const char *const mobj_opt[] = { @@ -149,6 +151,8 @@ static const char *const mobj_opt[] = { "standingslope", #endif "colorized", + "shadowscale", + "whiteshadow", NULL}; #define UNIMPLEMENTED luaL_error(L, LUA_QL("mobj_t") " field " LUA_QS " is not implemented for Lua and cannot be accessed.", mobj_opt[field]) @@ -360,6 +364,12 @@ static int mobj_get(lua_State *L) case mobj_colorized: lua_pushboolean(L, mo->colorized); break; + case mobj_shadowscale: + lua_pushfixed(L, mo->shadowscale); + break; + case mobj_whiteshadow: + lua_pushboolean(L, mo->whiteshadow); + break; default: // extra custom variables in Lua memory lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); @@ -677,6 +687,12 @@ static int mobj_set(lua_State *L) case mobj_colorized: mo->colorized = luaL_checkboolean(L, 3); break; + case mobj_shadowscale: + mo->shadowscale = luaL_checkfixed(L, 3); + break; + case mobj_whiteshadow: + mo->whiteshadow = luaL_checkboolean(L, 3); + break; default: lua_getfield(L, LUA_REGISTRYINDEX, LREG_EXTVARS); I_Assert(lua_istable(L, -1)); diff --git a/src/p_inter.c b/src/p_inter.c index 7a975951c..7fe9eeda3 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2157,6 +2157,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source) target->flags &= ~(MF_SHOOTABLE|MF_FLOAT|MF_SPECIAL); target->flags2 &= ~(MF2_SKULLFLY|MF2_NIGHTSPULL); target->health = 0; // This makes it easy to check if something's dead elsewhere. + target->shadowscale = 0; #ifdef HAVE_BLUA if (LUAh_MobjDeath(target, inflictor, source) || P_MobjWasRemoved(target)) diff --git a/src/p_mobj.c b/src/p_mobj.c index 7c0c3d882..2cbda8c33 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -3729,11 +3729,15 @@ static void P_PlayerMobjThinker(mobj_t *mobj) mobj->z += mobj->momz; P_SetThingPosition(mobj); P_CheckPosition(mobj, mobj->x, mobj->y); + mobj->floorz = tmfloorz; + mobj->ceilingz = tmceilingz; goto animonly; } else if (mobj->player->pflags & PF_MACESPIN && mobj->tracer) { P_CheckPosition(mobj, mobj->x, mobj->y); + mobj->floorz = tmfloorz; + mobj->ceilingz = tmceilingz; goto animonly; } @@ -9900,6 +9904,63 @@ void P_SceneryThinker(mobj_t *mobj) // GAME SPAWN FUNCTIONS // +static void P_DefaultMobjShadowScale(mobj_t *thing) +{ + thing->shadowscale = 0; + thing->whiteshadow = (thing->frame & FF_FULLBRIGHT); + + switch (thing->type) + { + case MT_PLAYER: + case MT_SMALLMACE: + case MT_BIGMACE: + case MT_PUMA: + case MT_BIGPUMA: + case MT_FALLINGROCK: + case MT_SMK_MOLE: + case MT_SMK_THWOMP: + case MT_BATTLEBUMPER: + case MT_BANANA: + case MT_ORBINAUT: + case MT_ORBINAUT_SHIELD: + case MT_JAWZ: + case MT_JAWZ_DUD: + case MT_JAWZ_SHIELD: + case MT_SSMINE: + case MT_SSMINE_SHIELD: + case MT_BALLHOG: + case MT_SINK: + case MT_THUNDERSHIELD: + case MT_ROCKETSNEAKER: + case MT_SPB: + thing->shadowscale = 3*FRACUNIT/2; + break; + case MT_BANANA_SHIELD: + thing->shadowscale = 12*FRACUNIT/5; + break; + case MT_RANDOMITEM: + thing->shadowscale = FRACUNIT/2; + thing->whiteshadow = false; + break; + case MT_EGGMANITEM: + thing->shadowscale = FRACUNIT; + thing->whiteshadow = false; + break; + case MT_EGGMANITEM_SHIELD: + thing->shadowscale = 3*FRACUNIT/2; + thing->whiteshadow = false; + break; + case MT_RING: + case MT_FLOATINGITEM: + thing->shadowscale = FRACUNIT/2; + break; + default: + if (thing->flags & (MF_ENEMY|MF_BOSS)) + thing->shadowscale = FRACUNIT; + break; + } +} + // // P_SpawnMobj // @@ -10000,6 +10061,9 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) mobj->colorized = false; + // Set shadowscale here, before spawn hook so that Lua can change it + P_DefaultMobjShadowScale(mobj); + #ifdef HAVE_BLUA // DANGER! This can cause P_SpawnMobj to return NULL! // Avoid using P_RemoveMobj on the newly created mobj in "MobjSpawn" Lua hooks! diff --git a/src/p_mobj.h b/src/p_mobj.h index aec2ed951..7b3d278f7 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -377,6 +377,9 @@ typedef struct mobj_s boolean colorized; // Whether the mobj uses the rainbow colormap + fixed_t shadowscale; // If this object casts a shadow, and the size relative to radius + boolean whiteshadow; // Use white shadow, set to true by default for fullbright objects + // WARNING: New fields must be added separately to savegame and Lua. } mobj_t; diff --git a/src/r_main.c b/src/r_main.c index 0d14bed73..a4fa9d463 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -168,8 +168,7 @@ consvar_t cv_flipcam2 = {"flipcam2", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, consvar_t cv_flipcam3 = {"flipcam3", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam3_OnChange, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_flipcam4 = {"flipcam4", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam4_OnChange, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_shadow = {"shadow", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; -consvar_t cv_shadowoffs = {"offsetshadows", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; +consvar_t cv_shadow = {"shadow", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_skybox = {"skybox", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_soniccd = {"soniccd", "Off", CV_NETVAR|CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; consvar_t cv_allowmlook = {"allowmlook", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL}; @@ -1505,7 +1504,6 @@ void R_RegisterEngineStuff(void) CV_RegisterVar(&cv_chasecam3); CV_RegisterVar(&cv_chasecam4); CV_RegisterVar(&cv_shadow); - CV_RegisterVar(&cv_shadowoffs); CV_RegisterVar(&cv_skybox); CV_RegisterVar(&cv_cam_dist); diff --git a/src/r_main.h b/src/r_main.h index 38a589682..879d4c6eb 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -76,7 +76,7 @@ extern consvar_t cv_showhud, cv_translucenthud; extern consvar_t cv_homremoval; extern consvar_t cv_chasecam, cv_chasecam2, cv_chasecam3, cv_chasecam4; extern consvar_t cv_flipcam, cv_flipcam2, cv_flipcam3, cv_flipcam4; -extern consvar_t cv_shadow, cv_shadowoffs; +extern consvar_t cv_shadow; extern consvar_t cv_translucency; extern consvar_t /*cv_precipdensity,*/ cv_drawdist, /*cv_drawdist_nights,*/ cv_drawdist_precip; extern consvar_t cv_fov; diff --git a/src/r_things.c b/src/r_things.c index 1afbb125c..b747d3493 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -802,9 +802,7 @@ static void R_DrawFlippedMaskedColumn(column_t *column, INT32 texheight) static void R_DrawVisSprite(vissprite_t *vis) { column_t *column; -#ifdef RANGECHECK INT32 texturecolumn; -#endif fixed_t frac; patch_t *patch = W_CacheLumpNum(vis->patch, PU_CACHE); fixed_t this_scale = vis->mobj->scale; @@ -920,6 +918,7 @@ static void R_DrawVisSprite(vissprite_t *vis) if (!(vis->scalestep)) { sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale); + sprtopscreen += vis->shear.tan * vis->shear.offset; dc_iscale = FixedDiv(FRACUNIT, vis->scale); } @@ -942,31 +941,50 @@ static void R_DrawVisSprite(vissprite_t *vis) vis->x2--; #endif - for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale) + // Split drawing loops for paper and non-paper to reduce conditional checks per sprite + if (vis->scalestep) { - if (vis->scalestep) // currently papersprites only + // Papersprite drawing loop + for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, spryscale += vis->scalestep) { -#ifndef RANGECHECK - if ((frac>>FRACBITS) < 0 || (frac>>FRACBITS) >= SHORT(patch->width)) // if this doesn't work i'm removing papersprites - break; -#endif + angle_t angle = ((vis->centerangle + xtoviewangle[dc_x]) >> ANGLETOFINESHIFT) & 0xFFF; + texturecolumn = (vis->paperoffset - FixedMul(FINETANGENT(angle), vis->paperdistance)) / this_scale; + + if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) + continue; + + if (vis->xiscale < 0) // Flipped sprite + texturecolumn = SHORT(patch->width) - 1 - texturecolumn; + sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale)); dc_iscale = (0xffffffffu / (unsigned)spryscale); - spryscale += vis->scalestep; - } -#ifdef RANGECHECK - texturecolumn = frac>>FRACBITS; - if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) - I_Error("R_DrawSpriteRange: bad texturecolumn"); - column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); + column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); + + if (vis->cut & SC_VFLIP) + R_DrawFlippedMaskedColumn(column, patch->height); + else + R_DrawMaskedColumn(column); + } + } + else + { + // Non-paper drawing loop + for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale, sprtopscreen += vis->shear.tan) + { +#ifdef RANGECHECK + texturecolumn = frac>>FRACBITS; + if (texturecolumn < 0 || texturecolumn >= SHORT(patch->width)) + I_Error("R_DrawSpriteRange: bad texturecolumn at %d from end", vis->x2 - dc_x); + column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[texturecolumn])); #else - column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS])); + column = (column_t *)((UINT8 *)patch + LONG(patch->columnofs[frac>>FRACBITS])); #endif - if (vis->cut & SC_VFLIP) - R_DrawFlippedMaskedColumn(column, patch->height); - else - R_DrawMaskedColumn(column); + if (vis->cut & SC_VFLIP) + R_DrawFlippedMaskedColumn(column, patch->height); + else + R_DrawMaskedColumn(column); + } } colfunc = basecolfunc; @@ -1138,6 +1156,278 @@ static void R_SplitSprite(vissprite_t *sprite) } } +// +// R_GetShadowZ(thing, shadowslope) +// Get the first visible floor below the object for shadows +// shadowslope is filled with the floor's slope, if provided +// +fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope) +{ + fixed_t z, floorz = INT32_MIN; + pslope_t *slope, *floorslope = NULL; + msecnode_t *node; + sector_t *sector; + ffloor_t *rover; + + for (node = thing->touching_sectorlist; node; node = node->m_sectorlist_next) + { + sector = node->m_sector; + + slope = (sector->heightsec != -1) ? NULL : sector->f_slope; + z = slope ? P_GetZAt(slope, thing->x, thing->y) : ( + (sector->heightsec != -1) ? sectors[sector->heightsec].floorheight : sector->floorheight + ); + + if (z < thing->z+thing->height/2 && z > floorz) + { + floorz = z; + floorslope = slope; + } + + if (sector->ffloors) + for (rover = sector->ffloors; rover; rover = rover->next) + { + if (!(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERPLANES) || (rover->alpha < 90 && !(rover->flags & FF_SWIMMABLE))) + continue; + + z = *rover->t_slope ? P_GetZAt(*rover->t_slope, thing->x, thing->y) : *rover->topheight; + if (z < thing->z+thing->height/2 && z > floorz) + { + floorz = z; + floorslope = *rover->t_slope; + } + } + } + + if (thing->floorz > floorz + (!floorslope ? 0 : FixedMul(abs(floorslope->zdelta), thing->radius*3/2))) + { + floorz = thing->floorz; + floorslope = NULL; + } + +#if 0 // Unfortunately, this drops CEZ2 down to sub-17 FPS on my i7. +//#ifdef POLYOBJECTS + // Check polyobjects and see if floorz needs to be altered, for rings only because they don't update floorz + if (thing->type == MT_RING) + { + INT32 xl, xh, yl, yh, bx, by; + + xl = (unsigned)(thing->x - thing->radius - bmaporgx)>>MAPBLOCKSHIFT; + xh = (unsigned)(thing->x + thing->radius - bmaporgx)>>MAPBLOCKSHIFT; + yl = (unsigned)(thing->y - thing->radius - bmaporgy)>>MAPBLOCKSHIFT; + yh = (unsigned)(thing->y + thing->radius - bmaporgy)>>MAPBLOCKSHIFT; + + BMBOUNDFIX(xl, xh, yl, yh); + + validcount++; + + for (by = yl; by <= yh; by++) + for (bx = xl; bx <= xh; bx++) + { + INT32 offset; + polymaplink_t *plink; // haleyjd 02/22/06 + + if (bx < 0 || by < 0 || bx >= bmapwidth || by >= bmapheight) + continue; + + offset = by*bmapwidth + bx; + + // haleyjd 02/22/06: consider polyobject lines + plink = polyblocklinks[offset]; + + while (plink) + { + polyobj_t *po = plink->po; + + if (po->validcount != validcount) // if polyobj hasn't been checked + { + po->validcount = validcount; + + if (!P_MobjInsidePolyobj(po, thing) || !(po->flags & POF_RENDERPLANES)) + { + plink = (polymaplink_t *)(plink->link.next); + continue; + } + + // We're inside it! Yess... + z = po->lines[0]->backsector->ceilingheight; + + if (z < thing->z+thing->height/2 && z > floorz) + { + floorz = z; + floorslope = NULL; + } + } + plink = (polymaplink_t *)(plink->link.next); + } + } + } +#endif + + if (shadowslope != NULL) + *shadowslope = floorslope; + + return floorz; +} + +static void R_ProjectDropShadow(mobj_t *thing, vissprite_t *vis, fixed_t scale, fixed_t tx, fixed_t tz) +{ + vissprite_t *shadow; + patch_t *patch; + fixed_t xscale, yscale, shadowxscale, shadowyscale, shadowskew, x1, x2; + INT32 light = 0; + fixed_t scalemul; UINT8 trans; + fixed_t floordiff; + fixed_t floorz; + pslope_t *floorslope; + + floorz = R_GetShadowZ(thing, &floorslope); + + if (abs(floorz-viewz)/tz > 4) return; // Prevent stretchy shadows and possible crashes + + floordiff = abs(thing->z - floorz); + + trans = floordiff / (100*FRACUNIT) + 3; + if (trans >= 9) return; + + scalemul = FixedMul(FRACUNIT - floordiff/640, scale); + + if (thing->whiteshadow) + patch = W_CachePatchName("LSHADOW", PU_CACHE); + else + patch = W_CachePatchName("DSHADOW", PU_CACHE); + + xscale = FixedDiv(projection, tz); + yscale = FixedDiv(projectiony, tz); + shadowxscale = FixedMul(thing->radius*2, scalemul); + shadowyscale = FixedMul(FixedMul(thing->radius*2, scalemul), FixedDiv(abs(floorz - viewz), tz)); + shadowyscale = min(shadowyscale, shadowxscale) / patch->height; + shadowxscale /= patch->width; + shadowskew = 0; + + if (floorslope) + { + // haha let's try some dumb stuff + fixed_t xslope, zslope; + angle_t sloperelang = (R_PointToAngle(thing->x, thing->y) - floorslope->xydirection) >> ANGLETOFINESHIFT; + + xslope = FixedMul(FINESINE(sloperelang), floorslope->zdelta); + zslope = FixedMul(FINECOSINE(sloperelang), floorslope->zdelta); + + //CONS_Printf("Shadow is sloped by %d %d\n", xslope, zslope); + + if (viewz < floorz) + shadowyscale += FixedMul(FixedMul(thing->radius*2 / patch->height, scalemul), zslope); + else + shadowyscale -= FixedMul(FixedMul(thing->radius*2 / patch->height, scalemul), zslope); + + shadowyscale = abs(shadowyscale); + + shadowskew = xslope; + } + + tx -= patch->width * shadowxscale/2; + x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; + if (x1 >= viewwidth) return; + + tx += patch->width * shadowxscale; + x2 = ((centerxfrac + FixedMul(tx,xscale))>>FRACBITS); x2--; + if (x2 < 0 || x2 <= x1) return; + + if (shadowyscale < FRACUNIT/patch->height) return; // fix some crashes? + + shadow = R_NewVisSprite(); + + if (thing->whiteshadow) + shadow->patch = W_CheckNumForName("LSHADOW"); + else + shadow->patch = W_CheckNumForName("DSHADOW"); + + shadow->heightsec = vis->heightsec; + + shadow->thingheight = FRACUNIT; + shadow->pz = floorz; + shadow->pzt = shadow->pz + shadow->thingheight; + + shadow->mobjflags = 0; + shadow->sortscale = vis->sortscale; + shadow->dispoffset = vis->dispoffset - 5; + shadow->gx = thing->x; + shadow->gy = thing->y; + shadow->gzt = shadow->pz + patch->height * shadowyscale / 2; + shadow->gz = shadow->gzt - patch->height * shadowyscale; + shadow->texturemid = FixedMul(thing->scale, FixedDiv(shadow->gzt - viewz, shadowyscale)); + if (thing->skin && ((skin_t *)thing->skin)->flags & SF_HIRES) + shadow->texturemid = FixedMul(shadow->texturemid, ((skin_t *)thing->skin)->highresscale); + shadow->scalestep = 0; + shadow->shear.tan = shadowskew; // repurposed variable + + shadow->mobj = thing; // Easy access! Tails 06-07-2002 + + shadow->x1 = x1 < 0 ? 0 : x1; + shadow->x2 = x2 >= viewwidth ? viewwidth-1 : x2; + + // PORTAL SEMI-CLIPPING + if (portalrender) + { + if (shadow->x1 < portalclipstart) + shadow->x1 = portalclipstart; + if (shadow->x2 >= portalclipend) + shadow->x2 = portalclipend-1; + } + + shadow->xscale = FixedMul(xscale, shadowxscale); //SoM: 4/17/2000 + shadow->scale = FixedMul(yscale, shadowyscale); + shadow->sector = vis->sector; + shadow->szt = (INT16)((centeryfrac - FixedMul(shadow->gzt - viewz, yscale))>>FRACBITS); + shadow->sz = (INT16)((centeryfrac - FixedMul(shadow->gz - viewz, yscale))>>FRACBITS); + shadow->cut = SC_ISSCALED|SC_SHADOW; //check this + + shadow->startfrac = 0; + //shadow->xiscale = 0x7ffffff0 / (shadow->xscale/2); + shadow->xiscale = (patch->width<x1 > x1) + shadow->startfrac += shadow->xiscale*(shadow->x1-x1); + + // reusing x1 variable + x1 += (x2-x1)/2; + shadow->shear.offset = shadow->x1-x1; + + if (thing->subsector->sector->numlights) + { + INT32 lightnum; +#ifdef ESLOPE // R_GetPlaneLight won't work on sloped lights! + light = thing->subsector->sector->numlights - 1; + + for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) { + fixed_t h = thing->subsector->sector->lightlist[lightnum].slope ? P_GetZAt(thing->subsector->sector->lightlist[lightnum].slope, thing->x, thing->y) + : thing->subsector->sector->lightlist[lightnum].height; + if (h <= shadow->gzt) { + light = lightnum - 1; + break; + } + } +#else + light = R_GetPlaneLight(thing->subsector->sector, shadow->gzt, false); +#endif + } + + if (thing->subsector->sector->numlights) + shadow->extra_colormap = thing->subsector->sector->lightlist[light].extra_colormap; + else + shadow->extra_colormap = thing->subsector->sector->extra_colormap; + + shadow->transmap = transtables + (trans<whiteshadow) + shadow->colormap = scalelight[LIGHTLEVELS - 1][0]; // full bright! + else + shadow->colormap = scalelight[0][0]; // full dark! + + objectsdrawn++; +} + // // R_ProjectSprite // Generates a vissprite for a thing @@ -1168,7 +1458,11 @@ static void R_ProjectSprite(mobj_t *thing) fixed_t iscale; fixed_t scalestep; // toast '16 fixed_t offset, offset2; - boolean papersprite = (thing->frame & FF_PAPERSPRITE); + + fixed_t basetx; // drop shadows + + boolean papersprite = !!(thing->frame & FF_PAPERSPRITE); + fixed_t paperoffset = 0, paperdistance = 0; angle_t centerangle = 0; //SoM: 3/17/2000 fixed_t gz, gzt; @@ -1176,8 +1470,6 @@ static void R_ProjectSprite(mobj_t *thing) INT32 light = 0; fixed_t this_scale = thing->scale; - fixed_t ang_scale = FRACUNIT; - // transform the origin point tr_x = thing->x - viewx; tr_y = thing->y - viewy; @@ -1188,15 +1480,15 @@ static void R_ProjectSprite(mobj_t *thing) tz = gxt-gyt; // thing is behind view plane? - if (!(papersprite) && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later + if (!papersprite && (tz < FixedMul(MINZ, this_scale))) // papersprite clipping is handled later return; gxt = -FixedMul(tr_x, viewsin); gyt = FixedMul(tr_y, viewcos); - tx = -(gyt + gxt); + basetx = tx = -(gyt + gxt); // too far off the side? - if (abs(tx) > tz<<2) + if (!papersprite && abs(tx) > tz<<2) // papersprite clipping is handled later return; // aspect ratio stuff @@ -1249,8 +1541,6 @@ static void R_ProjectSprite(mobj_t *thing) ang = R_PointToAngle (thing->x, thing->y) - thing->player->frameangle; else ang = R_PointToAngle (thing->x, thing->y) - thing->angle; - if (papersprite) - ang_scale = abs(FINESINE(ang>>ANGLETOFINESHIFT)); } if (sprframe->rotate == SRF_SINGLE) @@ -1288,27 +1578,12 @@ static void R_ProjectSprite(mobj_t *thing) else offset = -spritecachedinfo[lump].offset; offset = FixedMul(offset, this_scale); - tx += FixedMul(offset, ang_scale); - x1 = (centerxfrac + FixedMul (tx,xscale)) >>FRACBITS; - - // off the right side? - if (x1 > viewwidth) - return; - offset2 = FixedMul(spritecachedinfo[lump].width, this_scale); - tx += FixedMul(offset2, ang_scale); - x2 = ((centerxfrac + FixedMul (tx,xscale)) >> FRACBITS) - 1; - - // off the left side - if (x2 < 0) - return; if (papersprite) { - fixed_t yscale2, cosmul, sinmul, tz2; - - if (x2 <= x1) - return; + fixed_t xscale2, yscale2, cosmul, sinmul, tx2, tz2; + INT32 range; if (ang >= ANGLE_180) { @@ -1325,7 +1600,23 @@ static void R_ProjectSprite(mobj_t *thing) gyt = -FixedMul(tr_y, viewsin); tz = gxt-gyt; yscale = FixedDiv(projectiony, tz); - if (yscale < 64) return; // Fix some funky visuals + //if (yscale < 64) return; // Fix some funky visuals + + gxt = -FixedMul(tr_x, viewsin); + gyt = FixedMul(tr_y, viewcos); + tx = -(gyt + gxt); + xscale = FixedDiv(projection, tz); + x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; + + // Get paperoffset (offset) and paperoffset (distance) + paperoffset = -FixedMul(tr_x, cosmul) - FixedMul(tr_y, sinmul); + paperdistance = -FixedMul(tr_x, sinmul) + FixedMul(tr_y, cosmul); + if (paperdistance < 0) + { + paperoffset = -paperoffset; + paperdistance = -paperdistance; + } + centerangle = viewangle - thing->angle; tr_x += FixedMul(offset2, cosmul); tr_y += FixedMul(offset2, sinmul); @@ -1333,13 +1624,52 @@ static void R_ProjectSprite(mobj_t *thing) gyt = -FixedMul(tr_y, viewsin); tz2 = gxt-gyt; yscale2 = FixedDiv(projectiony, tz2); - if (yscale2 < 64) return; // ditto + //if (yscale2 < 64) return; // ditto + + gxt = -FixedMul(tr_x, viewsin); + gyt = FixedMul(tr_y, viewcos); + tx2 = -(gyt + gxt); + xscale2 = FixedDiv(projection, tz2); + x2 = ((centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS); if (max(tz, tz2) < FixedMul(MINZ, this_scale)) // non-papersprite clipping is handled earlier return; - scalestep = (yscale2 - yscale)/(x2 - x1); - scalestep = scalestep ? scalestep : 1; + // Needs partially clipped + if (tz < FixedMul(MINZ, this_scale)) + { + fixed_t div = FixedDiv(tz2-tz, FixedMul(MINZ, this_scale)-tz); + tx += FixedDiv(tx2-tx, div); + tz = FixedMul(MINZ, this_scale); + yscale = FixedDiv(projectiony, tz); + xscale = FixedDiv(projection, tz); + x1 = (centerxfrac + FixedMul(tx,xscale))>>FRACBITS; + } + else if (tz2 < FixedMul(MINZ, this_scale)) + { + fixed_t div = FixedDiv(tz-tz2, FixedMul(MINZ, this_scale)-tz2); + tx2 += FixedDiv(tx-tx2, div); + tz2 = FixedMul(MINZ, this_scale); + yscale2 = FixedDiv(projectiony, tz2); + xscale2 = FixedDiv(projection, tz2); + x2 = (centerxfrac + FixedMul(tx2,xscale2))>>FRACBITS; + } + + // off the right side? + if (x1 > viewwidth) + return; + + // off the left side + if (x2 < 0) + return; + + if ((range = x2 - x1) <= 0) + return; + + range++; // fencepost problem + + scalestep = ((yscale2 - yscale)/range) ?: 1; + xscale = FixedDiv(range<>FRACBITS; - xscale = FixedMul(xscale, ang_scale); + // off the right side? + if (x1 > viewwidth) + return; + + tx += offset2; + x2 = ((centerxfrac + FixedMul(tx,xscale))>>FRACBITS); x2--; + + // off the left side + if (x2 < 0) + return; + } // PORTAL SPRITE CLIPPING if (portalrender) @@ -1445,6 +1786,11 @@ static void R_ProjectSprite(mobj_t *thing) vis->pzt = vis->pz + vis->thingheight; vis->texturemid = vis->gzt - viewz; vis->scalestep = scalestep; + vis->paperoffset = paperoffset; + vis->paperdistance = paperdistance; + vis->centerangle = centerangle; + vis->shear.tan = 0; + vis->shear.offset = 0; vis->mobj = thing; // Easy access! Tails 06-07-2002 @@ -1537,6 +1883,9 @@ static void R_ProjectSprite(mobj_t *thing) if (thing->subsector->sector->numlights) R_SplitSprite(vis); + if (thing->shadowscale && cv_shadow.value) + R_ProjectDropShadow(thing, vis, thing->shadowscale, basetx, tz); + // Debug ++objectsdrawn; } @@ -1670,6 +2019,9 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing) vis->pzt = vis->pz + vis->thingheight; vis->texturemid = vis->gzt - viewz; vis->scalestep = 0; + vis->paperdistance = 0; + vis->shear.tan = 0; + vis->shear.offset = 0; vis->x1 = x1 < 0 ? 0 : x1; vis->x2 = x2 >= viewwidth ? viewwidth-1 : x2; diff --git a/src/r_things.h b/src/r_things.h index 4837b4aee..a50e0803d 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -50,6 +50,8 @@ void R_SortVisSprites(void); // (only sprites from namelist are added or replaced) void R_AddSpriteDefs(UINT16 wadnum); +fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope); + #ifdef DELFILE void R_DelSpriteDefs(UINT16 wadnum); #endif @@ -114,7 +116,8 @@ typedef enum SC_FULLBRIGHT = 1<<4, SC_SEMIBRIGHT = 1<<5, SC_VFLIP = 1<<6, - SC_ISSCALED = 1>>7, + SC_ISSCALED = 1<<7, + SC_SHADOW = 1<<8, // masks SC_CUTMASK = SC_TOP|SC_BOTTOM, SC_FLAGMASK = ~SC_CUTMASK @@ -139,8 +142,16 @@ typedef struct vissprite_s fixed_t startfrac; // horizontal position of x1 fixed_t scale, sortscale; // sortscale only differs from scale for flat sprites fixed_t scalestep; // only for flat sprites, 0 otherwise + fixed_t paperoffset, paperdistance; // for paper sprites, offset/dist relative to the angle fixed_t xiscale; // negative if flipped + angle_t centerangle; // for paper sprites + + struct { + fixed_t tan; // The amount to shear the sprite vertically per row + INT32 offset; // The center of the shearing location offset from x1 + } shear; + fixed_t texturemid; lumpnum_t patch; From ff190b7a880effc95059bb7cde8705c835cea6c4 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Tue, 3 Mar 2020 17:05:04 -0500 Subject: [PATCH 159/163] Fix unsigned/signed comparison --- src/p_mobj.c | 4 ++-- src/p_spec.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 1f2e5e3de..7533e8fc5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -11006,7 +11006,7 @@ void P_SpawnPrecipitation(void) { INT32 i, j, k; mobjtype_t type = precipprops[curWeather].type; - INT32 randomstates = mobjinfo[type].damage; + UINT8 randomstates = (UINT8)mobjinfo[type].damage; fixed_t basex, basey, x, y, z, height; subsector_t *precipsector = NULL; precipmobj_t *rainmo = NULL; @@ -11053,7 +11053,7 @@ void P_SpawnPrecipitation(void) { rainmo = P_SpawnPrecipMobj(x, y, z, type); - if (randomstates > 0 && randomstates < UINT8_MAX) + if (randomstates > 0) { UINT8 mrand = M_RandomByte(); UINT8 threshold = UINT8_MAX / (randomstates + 1); diff --git a/src/p_spec.c b/src/p_spec.c index 1cca2cd5e..953503f9d 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -2041,7 +2041,7 @@ void P_SwitchWeather(UINT8 newWeather) } else if (swap != MT_NULL) // Rather than respawn all that crap, reuse it! { - INT32 randomstates = mobjinfo[swap].damage; + UINT8 randomstates = (UINT8)mobjinfo[swap].damage; thinker_t *think; precipmobj_t *precipmobj; statenum_t st; @@ -2057,7 +2057,7 @@ void P_SwitchWeather(UINT8 newWeather) st = mobjinfo[swap].spawnstate; - if (randomstates > 0 && randomstates < UINT8_MAX) + if (randomstates > 0) { UINT8 mrand = M_RandomByte(); UINT8 threshold = UINT8_MAX / (randomstates + 1); From d459407866625e3c3d7fc102a5bcc330080a6a88 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Tue, 3 Mar 2020 17:22:13 -0500 Subject: [PATCH 160/163] Forgotten player check here --- src/p_map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p_map.c b/src/p_map.c index 4f39319a6..9e34e04d9 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -2790,7 +2790,7 @@ boolean P_TryMove(mobj_t *thing, fixed_t x, fixed_t y, boolean allowdropoff) const fixed_t maxstepmove = FixedMul(MAXSTEPMOVE, mapobjectscale); fixed_t maxstep = maxstepmove; - if (thing->player->kartstuff[k_waterskip]) + if (thing->player && thing->player->kartstuff[k_waterskip]) maxstep += maxstepmove; // Add some extra stepmove when waterskipping // If using type Section1:13, double the maxstep. From 11930b41bf704f68d7d6594e1a6e992603235d37 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 3 Mar 2020 20:11:03 -0800 Subject: [PATCH 161/163] Use tic_t --- 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 28a519694..308eb2616 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -5433,7 +5433,7 @@ static tic_t gametime = 0; static void UpdatePingTable(void) { - int fastest; + tic_t fastest; tic_t lag; INT32 i; From 76188e89fbd875b9c615f12932c60036278664b3 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Fri, 6 Mar 2020 12:54:54 -0500 Subject: [PATCH 162/163] Fullbright boosters We no longer have to maintain this standard manually. I actually suggest making booster sectors use the lightlevel of their surrounding sectors so that only the booster itself glows. (OGL support is commented out, since it conflicts with sal-lighting and should probably be done there) --- src/hardware/hw_main.c | 3 +++ src/r_bsp.c | 17 +++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index f2499bcf6..6ccaf1bc5 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -3564,6 +3564,9 @@ static void HWR_Subsector(size_t num) sub->sector->extra_colormap = gr_frontsector->extra_colormap; + //R_PlaneLightOverride(gr_frontsector, false, &floorlightlevel); + //R_PlaneLightOverride(gr_frontsector, true, &ceilinglightlevel); + // render floor ? #ifdef DOPLANES // yeah, easy backface cull! :) diff --git a/src/r_bsp.c b/src/r_bsp.c index 296cbbe87..a748af51c 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -57,6 +57,16 @@ static boolean R_NoEncore(sector_t *sector, boolean ceiling) return ((boolean)(sector->flags & SF_FLIPSPECIAL_FLOOR)); } +static void R_PlaneLightOverride(sector_t *sector, boolean ceiling, INT32 *lightlevel) +{ + if (GETSECSPECIAL(sector->special, 4) == 6) // Fullbright sneaker panels + { + if ((ceiling && (sector->flags & SF_FLIPSPECIAL_CEILING)) + || (!ceiling && (sector->flags & SF_FLIPSPECIAL_FLOOR))) + *lightlevel = 255; + } +} + // // R_ClearDrawSegs // @@ -895,6 +905,9 @@ static void R_Subsector(size_t num) sub->sector->extra_colormap = frontsector->extra_colormap; + R_PlaneLightOverride(frontsector, false, &floorlightlevel); + R_PlaneLightOverride(frontsector, true, &ceilinglightlevel); + if ((( #ifdef ESLOPE frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : @@ -923,8 +936,8 @@ static void R_Subsector(size_t num) || (frontsector->heightsec != -1 && sectors[frontsector->heightsec].floorpic == skyflatnum))) { - ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic, - ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle, + ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic, ceilinglightlevel, + frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle, ceilingcolormap, NULL #ifdef POLYOBJECTS_PLANES , NULL From 83c74af6968a3b80001391fb44e64d2993735f74 Mon Sep 17 00:00:00 2001 From: Sally Cochenour Date: Fri, 6 Mar 2020 12:56:12 -0500 Subject: [PATCH 163/163] Fix bad master merge --- src/p_mobj.c | 163 --------------------------------------------------- 1 file changed, 163 deletions(-) diff --git a/src/p_mobj.c b/src/p_mobj.c index 42bd714df..a532dddc5 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6209,169 +6209,6 @@ static void P_RemoveOverlay(mobj_t *thing) } } -// Simplified version of a code bit in P_MobjFloorZ -static fixed_t P_ShadowSlopeZ(pslope_t *slope, fixed_t x, fixed_t y, fixed_t radius, boolean ceiling) -{ - fixed_t testx, testy; - - if (slope->d.x < 0) - testx = radius; - else - testx = -radius; - - if (slope->d.y < 0) - testy = radius; - else - testy = -radius; - - if ((slope->zdelta > 0) ^ !!(ceiling)) - { - testx = -testx; - testy = -testy; - } - - testx += x; - testy += y; - - return P_GetZAt(slope, testx, testy); -} - -// Sets standingslope/modeltilt, returns z position for shadows; used also for stuff like bananas -// (I would've preferred to be able to return both the slope & z, but I'll take what I can get...) -fixed_t P_CalculateShadowFloor(mobj_t *mobj, fixed_t x, fixed_t y, fixed_t z, fixed_t radius, fixed_t height, boolean flip, boolean player) -{ - fixed_t newz; - sector_t *sec; -#ifdef ESLOPE - pslope_t *slope = NULL; -#endif - - sec = R_PointInSubsector(x, y)->sector; - - if (flip) - { -#ifdef ESLOPE - if (sec->c_slope) - { - slope = sec->c_slope; - newz = P_ShadowSlopeZ(slope, x, y, radius, true); - } - else -#endif - newz = sec->ceilingheight; - } - else - { -#ifdef ESLOPE - if (sec->f_slope) - { - slope = sec->f_slope; - newz = P_ShadowSlopeZ(slope, x, y, radius, false); - } - else -#endif - newz = sec->floorheight; - } - - // Check FOFs for a better suited slope - if (sec->ffloors) - { - ffloor_t *rover; - - for (rover = sec->ffloors; rover; rover = rover->next) - { - fixed_t top, bottom; - fixed_t d1, d2; - - if (!(rover->flags & FF_EXISTS)) - continue; - - if ((!(((rover->flags & FF_BLOCKPLAYER && player) - || (rover->flags & FF_BLOCKOTHERS && !player)) - || (rover->flags & FF_QUICKSAND)) - || (rover->flags & FF_SWIMMABLE))) - continue; - -#ifdef ESLOPE - if (*rover->t_slope) - top = P_ShadowSlopeZ(*rover->t_slope, x, y, radius, false); - else -#endif - top = *rover->topheight; - -#ifdef ESLOPE - if (*rover->b_slope) - bottom = P_ShadowSlopeZ(*rover->b_slope, x, y, radius, true); - else -#endif - bottom = *rover->bottomheight; - - if (flip) - { - if (rover->flags & FF_QUICKSAND) - { - if (z < top && (z + height) > bottom) - { - if (newz > (z + height)) - { - newz = (z + height); - slope = NULL; - } - } - continue; - } - - d1 = (z + height) - (top + ((bottom - top)/2)); - d2 = z - (top + ((bottom - top)/2)); - - if (bottom < newz && abs(d1) < abs(d2)) - { - newz = bottom; -#ifdef ESLOPE - if (*rover->b_slope) - slope = *rover->b_slope; -#endif - } - } - else - { - if (rover->flags & FF_QUICKSAND) - { - if (z < top && (z + height) > bottom) - { - if (newz < z) - { - newz = z; - slope = NULL; - } - } - continue; - } - - d1 = z - (bottom + ((top - bottom)/2)); - d2 = (z + height) - (bottom + ((top - bottom)/2)); - - if (top > newz && abs(d1) < abs(d2)) - { - newz = top; -#ifdef ESLOPE - if (*rover->t_slope) - slope = *rover->t_slope; -#endif - } - } - } - } - - mobj->standingslope = slope; - -#ifdef HWRENDER - mobj->modeltilt = slope; -#endif - - return newz; -} - // SAL'S KART BATTLE MODE OVERTIME HANDLER #define MAXPLANESPERSECTOR (MAXFFLOORS+1)*2 static void P_SpawnOvertimeParticles(fixed_t x, fixed_t y, fixed_t scale, mobjtype_t type, boolean ceiling)